# 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` - **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**: 1. **Given** 某个使用 `ExcelUtils.write(...)` 的导出接口,**When** 用户触发下载,**Then** 响应 `Content-Type` 为 xlsx 对应值,文件名以后缀 `.xlsx` 下载。 2. **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**: 1. **Given** 用户在红冲记录页点击导出,**When** 请求发往后端导出接口,**Then** 浏览器下载后端生成的 Excel 文件,不再生成 `.csv` Blob。 2. **Given** 用户在银行托收、托收明细、银行代扣、实时收费页面点击导出,**When** 各页面调用对应后端接口,**Then** 下载文件由后端生成,文件内容以查询条件为准,而不是仅以当前页 `list.value` 为准。 --- ### User Story 3 - 前后端并行可交付 (Priority: P2) 作为项目执行人员,我希望本次改动能拆成后端 lane 与前端 lane 并行推进,并通过 worktree/分支隔离,便于先完成后端统一能力,再接线前端页面并做联调验证。 **Why this priority**: 本次涉及两个代码仓,若不提前明确并行边界与依赖顺序,容易造成前端等待后端、或后端改动无法快速联调。 **Independent Test**: 审阅者只查看规格与后续计划,即可明确 backend lane、frontend lane 各自修改范围、依赖顺序与最小验证要求。 **Acceptance Scenarios**: 1. **Given** 需要同时修改 `water-backend` 和 `water-frontend`,**When** 实施按计划推进,**Then** 两个 lane 的修改边界清晰,且能在同一 feature 闭环下联调。 2. **Given** 某个前端页面缺少现成导出接口,**When** 盘点后确认缺口,**Then** 仅补齐该页面所需最小后端导出接口,不扩大到无关页面。 --- ### Edge Cases - 若后端 `ExcelUtils` 已统一为 `.xlsx`,但某些 controller 仍手工写死 `.xls` 文件名,则实施时必须一并盘点并修正受影响接口,避免公共工具与业务文件名口径冲突。 - 若某个前端页面尚无对应后端导出接口,则前端不能继续保留本地 CSV 兜底;必须在计划中明确“先补接口,再接前端”。 - 若前端查询条件包含日期区间、分页或详情上下文,导出请求必须复用页面实际查询条件,而不是重新拼装一套口径不一致的参数。 - 若后端返回流式文件下载,前端下载封装必须按文件流处理,不得再次包装为本地 CSV Blob。 - 若文件名包含中文、空格或特殊字符,后端响应头与前端下载链路必须保持统一编码策略,避免下载后文件名乱码。 ## Requirements *(mandatory)* ### Functional Requirements - **FR-001**: 后端公共导出工具 MUST 将 Excel 下载响应头统一为 `.xlsx` 语义,包括标准 xlsx `Content-Type`。 - **FR-002**: 后端公共导出工具 MUST 保证下载文件名以后缀 `.xlsx` 返回,避免继续暴露 `.xls` 与实际文件格式不一致的问题。 - **FR-003**: 本次前端 MUST 替换以下页面的本地 CSV 导出实现: - `src/views/operatingCharges/redReversalRecord/index.vue` - `src/views/collection/bankCollection/index.vue` - `src/views/collection/bankCollection/detail.vue` - `src/views/collection/bankWithholding/index.vue` - `src/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` 的高风险操作。