164 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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` 的高风险操作。