11 KiB
Raw Blame History

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-backendwater-frontendWhen 实施按计划推进,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 的高风险操作。