11 KiB
Feature Specification: Excel 导出 xlsx 统一化与前端 CSV 替换
Feature Branch: 012-xlsx-export-unification
Created: 2026-05-15
Status: Draft
Input: User description: "前端也是 两个分任务一起工作" / "按这个方案做"
Document Scope & Sources (mandatory)
- Target repositories:
../water-backend/../water-frontend/
- Primary source of truth:
../water-backend/sw-framework/sw-spring-boot-starter-excel/src/main/java/cn/com/emsoft/sw/framework/excel/core/util/ExcelUtils.java../water-frontend/src/views/operatingCharges/redReversalRecord/index.vue../water-frontend/src/views/collection/bankCollection/index.vue../water-frontend/src/views/collection/bankCollection/detail.vue../water-frontend/src/views/collection/bankWithholding/index.vue../water-frontend/src/views/collection/realTimeBilling/index.vue../water-frontend/src/utils/download.ts
- Reference sources:
../water-backend/AGENTS.md../water-frontend/AGENTS.md../water-docs/AGENTS.md
- Code baselines:
- backend SHA:
82b2a4bb2 - frontend SHA:
156fe74e
- backend SHA:
- Scope decision: In scope。本次工作聚焦两个并行子任务:一是后端统一 Excel 下载为标准
.xlsx响应;二是前端将已确认的 5 个本地 CSV 导出页面改为调用后端真实导出接口。除为打通这 5 个页面所必需的最小接口补齐外,不扩展到其他页面重构或下载体系重写。
User Scenarios & Testing (mandatory)
User Story 1 - 后端统一 xlsx 下载口径 (Priority: P1)
作为系统维护人员,我希望后端公共 Excel 导出能力统一返回标准 .xlsx 文件及对应响应头,这样 Excel 客户端和浏览器不会再遇到“扩展名与文件格式不一致”的识别风险。
Why this priority: 公共 ExcelUtils 是后端导出统一入口,优先统一这里可以一次性消除全站 Excel 导出头信息不规范的问题。
Independent Test: 任选一个现有后端导出接口下载文件,审阅者无需阅读实现即可确认响应头与文件名后缀均为 .xlsx 语义,且文件可被 Excel 正常打开。
Acceptance Scenarios:
- Given 某个使用
ExcelUtils.write(...)的导出接口,When 用户触发下载,Then 响应Content-Type为 xlsx 对应值,文件名以后缀.xlsx下载。 - Given 系统中其他依赖
ExcelUtils.write(...)的导出接口,When 它们继续使用公共导出工具,Then 无需各自复制下载头逻辑即可继承统一的 xlsx 行为。
User Story 2 - 前端页面不再本地拼 CSV (Priority: P1)
作为业务用户,我希望“红冲记录、银行托收、托收明细、银行代扣、实时收费”这些页面的导出直接下载后端生成的 Excel 文件,而不是前端本地把当前列表拼成 CSV。
Why this priority: 这些页面当前导出逻辑与系统其他 Excel 导出路径不一致,且只导出前端内存数据,存在格式、口径和分页数据缺失风险。
Independent Test: 审阅者在这 5 个页面逐一点击导出,无需查看代码即可确认浏览器下载的是后端返回的 Excel 文件,而不是前端即时生成的 .csv 文件。
Acceptance Scenarios:
- Given 用户在红冲记录页点击导出,When 请求发往后端导出接口,Then 浏览器下载后端生成的 Excel 文件,不再生成
.csvBlob。 - Given 用户在银行托收、托收明细、银行代扣、实时收费页面点击导出,When 各页面调用对应后端接口,Then 下载文件由后端生成,文件内容以查询条件为准,而不是仅以当前页
list.value为准。
User Story 3 - 前后端并行可交付 (Priority: P2)
作为项目执行人员,我希望本次改动能拆成后端 lane 与前端 lane 并行推进,并通过 worktree/分支隔离,便于先完成后端统一能力,再接线前端页面并做联调验证。
Why this priority: 本次涉及两个代码仓,若不提前明确并行边界与依赖顺序,容易造成前端等待后端、或后端改动无法快速联调。
Independent Test: 审阅者只查看规格与后续计划,即可明确 backend lane、frontend lane 各自修改范围、依赖顺序与最小验证要求。
Acceptance Scenarios:
- Given 需要同时修改
water-backend和water-frontend,When 实施按计划推进,Then 两个 lane 的修改边界清晰,且能在同一 feature 闭环下联调。 - Given 某个前端页面缺少现成导出接口,When 盘点后确认缺口,Then 仅补齐该页面所需最小后端导出接口,不扩大到无关页面。
Edge Cases
- 若后端
ExcelUtils已统一为.xlsx,但某些 controller 仍手工写死.xls文件名,则实施时必须一并盘点并修正受影响接口,避免公共工具与业务文件名口径冲突。 - 若某个前端页面尚无对应后端导出接口,则前端不能继续保留本地 CSV 兜底;必须在计划中明确“先补接口,再接前端”。
- 若前端查询条件包含日期区间、分页或详情上下文,导出请求必须复用页面实际查询条件,而不是重新拼装一套口径不一致的参数。
- 若后端返回流式文件下载,前端下载封装必须按文件流处理,不得再次包装为本地 CSV Blob。
- 若文件名包含中文、空格或特殊字符,后端响应头与前端下载链路必须保持统一编码策略,避免下载后文件名乱码。
Requirements (mandatory)
Functional Requirements
- FR-001: 后端公共导出工具 MUST 将 Excel 下载响应头统一为
.xlsx语义,包括标准 xlsxContent-Type。 - FR-002: 后端公共导出工具 MUST 保证下载文件名以后缀
.xlsx返回,避免继续暴露.xls与实际文件格式不一致的问题。 - FR-003: 本次前端 MUST 替换以下页面的本地 CSV 导出实现:
src/views/operatingCharges/redReversalRecord/index.vuesrc/views/collection/bankCollection/index.vuesrc/views/collection/bankCollection/detail.vuesrc/views/collection/bankWithholding/index.vuesrc/views/collection/realTimeBilling/index.vue
- FR-004: 以上 5 个页面 MUST 通过后端真实导出接口下载文件,不得继续使用
headers.join(',')、new Blob(... text/csv ...)、.csv文件名等本地 CSV 方案。 - FR-005: 前端导出请求 MUST 复用页面当前查询条件或上下文参数,确保导出数据口径与页面筛选条件一致。
- FR-006: 实施前 MUST 盘点上述 5 个页面各自是否已有后端导出接口;若缺失,则仅补齐该页面所需最小后端导出接口。
- FR-007: 若某页面已有后端导出接口,前端 MUST 优先复用现有接口,不得新增平行接口。
- FR-008: 前端共享下载逻辑 MAY 继续复用现有下载工具,但最终下载对象 MUST 是后端返回的文件流,而不是前端自行生成的 CSV Blob。
- FR-009: 本次实施 MUST 采用前后端并行子任务组织:backend lane 聚焦公共导出工具与必要接口补齐,frontend lane 聚焦 5 个页面接线与移除 CSV 逻辑。
- FR-010: 本次实施 MUST 在 worktree/分支隔离下完成,避免直接在
develop上混改。 - FR-011: 后端下载文件名与响应头中可编码的文件名部分 MUST 做统一编码处理,避免中文文件名在浏览器或跨端下载场景中出现乱码。
- FR-012: 验证 MUST 至少覆盖后端最小编译/导出验证、前端最小构建或类型验证,以及 5 个页面的关键导出 smoke。
- FR-013: 本次工作 MUST 保持最小闭环,不顺带重构无关下载工具、无关页面或导出权限体系。
Key Entities (include if feature involves data)
- 公共 Excel 导出工具: 后端
ExcelUtils.write(...),是后端导出响应头与输出流写入的统一入口。 - 页面导出实现: 前端页面中
handleExport一类导出逻辑,负责把页面查询条件映射到后端导出接口。 - 导出接口: 后端提供的下载型 HTTP 接口,负责根据查询条件生成 Excel 文件流。
- 导出查询条件: 页面当前筛选条件、详情页上下文参数或批次号等,用于保证导出口径一致。
- CSV 本地导出逻辑: 前端通过数组拼接、
Blob(text/csv)和.csv文件名直接下载的旧方案,需被移除。
Assumptions
EasyExcel.write(...)当前写出的实际文件格式可按.xlsx标准响应来承载,本次无需替换 Excel 写入库。- 这 5 个页面当前仍处于本地假数据 / 本地 CSV 导出阶段,属于前端临时实现,需要切换到正式后端接口模式。
- 可能并非 5 个页面都已具备现成后端导出接口,因此计划阶段需要先完成接口盘点,再决定哪些接口复用、哪些最小补齐。
- 本次以
develop为基线派生独立 worktree/分支进行实现,最终通过正常合并流程进入develop。
Clarifications
Session 2026-05-15
- Q: 发现多个前端页面使用本地 CSV 导出时,期望改成哪种方式? → A: 改成调用后端真实 Excel 导出接口。
- Q: 后端同步修改应做到哪个层级? → A: 统一修改公共
ExcelUtils为.xlsx。 - Q: 前端与后端是顺序推进还是并行分任务推进? → A: 采用前后端两个分任务一起工作。
- Q: 执行组织方式希望怎样落地? → A: 先建立 worktree,并以分任务方式并行推进前后端修改。
Success Criteria (mandatory)
Measurable Outcomes
- SC-001: 任一使用
ExcelUtils.write(...)的后端导出接口下载后,文件后缀为.xlsx,响应头为 xlsx 标准 MIME。 - SC-002: 上述 5 个前端页面代码中不再出现
text/csv、.csv下载文件名、手工csvContent拼接逻辑。 - SC-003: 5 个页面点击导出时,网络面板可观察到真实后端导出请求,而不是仅在浏览器端生成 Blob 后本地下载。
- SC-004: 若存在缺失导出接口,计划与实现结果中可明确指出哪些页面复用了现有接口、哪些页面补齐了最小后端接口。
- SC-005: 前后端两个 lane 的修改范围可分别审查,且在同一 feature 闭环下完成联调验证。
- SC-006: 含中文的导出文件名在浏览器下载后不出现乱码。
Proposed Execution Lanes
Backend lane
- 基于
develop派生独立 worktree/分支。 - 修改公共
ExcelUtils,统一.xlsx响应。 - 盘点 5 个页面所需后端导出接口,复用已有接口并补齐必要缺口。
- 完成最小编译与导出接口验证。
Frontend lane
- 基于
develop派生独立 worktree/分支,或在同一 feature 下使用单独前端 worktree。 - 删除 5 个页面的本地 CSV 导出逻辑。
- 新增/调整对应 API 调用,改为下载后端返回文件流。
- 完成最小构建/类型检查与关键页面导出 smoke。
Out of Scope
- 其余未列入的前端页面导出改造。
- 对全站下载工具、权限系统或路由结构做额外重构。
- 新增与
.xlsx统一无关的报表格式、模板样式或导出内容字段调整。 - 绕过分支审查流程直接修改
develop的高风险操作。