docs(specs): add new spec documents

This commit is contained in:
tangweijie 2026-05-18 17:38:12 +08:00
parent 226816c6bf
commit f2babf5353
3 changed files with 1155 additions and 0 deletions

View File

@ -0,0 +1,866 @@
# REV-005 财务后台发票管理前端设计
**Feature**: `002-rev005-invoice-flow`
**Date**: 2026-05-12
**Audience**: 财务经办、财务主管、客服协同、系统管理员
**Purpose**: 在既有 REV-005 发票业务流正式工件基础上,补充面向财务人员的前端页面、菜单层级、字段组织、状态模型与跳转关系设计,作为 `water-frontend` 页面实现的直接输入。
---
## 1. 设计目标
本设计聚焦 `SYS-002 > REV-005 发票管理` 后台前端,服务对象为财务人员,遵循以下目标:
1. 采用现有仓库已验证的前端页面模板,不引入新的页面组织范式。
2. 以财务批量处理为主、单笔处理为辅,保证高频操作路径最短。
3. 以缴费记录作为发票开具主数据源,以客户汇总作为大客户辅助视图,账单维度仅作为特殊补充能力。
4. 将红冲、作废、异常从普通查询中独立出来,形成可追踪、可授权、可审计的任务池页面。
5. 让财务人员进入页面后优先看到金额、状态、号码与失败原因,降低筛选和定位成本。
---
## 2. 设计范围
本轮仅覆盖 `REV-005` 财务后台前端,不扩展到:
- `CS-004` 客户侧电子发票服务
- `WECHAT-004` 微网厅电子发票服务
- `SYS-008` 发票服务子系统自身后台
- 发票物理打印页面
- 复杂自由拆票规则配置页面
本设计作为 `REV-005` 前端实现补充,不替代既有 `spec.md``plan.md``tasks.md``contracts/``data-model.md` 的正式业务口径。
---
## 3. 用户与职责边界
### 3.1 目标用户
- **财务经办**:待开票记录筛选、批量开票、查看结果
- **财务主管**:红冲、作废、大额合并开票、异常处理
- **客服协同**:只读查询、查看发票状态、查看开票信息
- **系统管理员**:全量权限、配置联调与问题核查
### 3.2 高风险动作
以下动作必须单独授权,不能仅因拥有列表查看权限而自动获得:
- 客户汇总合并开票
- 红冲处理
- 作废处理
- 异常改派
- 账单维度补充开票
- 大额批量开票
- 人工强制重试
---
## 4. 页面模板选型
### 4.1 主模板
采用 `water-frontend` 既有 **标准列表查询页** 模板,参考:
- `src/views/infra/config/index.vue`
- `src/views/settings/config/invoiceTaxRate/index.vue`
适用于以下页面:
- 发票开具
- 发票查询
- 红冲处理
- 作废处理
- 异常处理
### 4.2 辅模板
- **详情展示页**:发票详情页
- **弹窗表单页**:开票信息维护、批量开票确认、红冲原因、作废原因、异常日志
### 4.3 不采用的模式
本轮不采用新的“首页工作台”或“多栏组合工作台”模式,避免偏离现有模板体系。
---
## 5. 菜单层级设计
### 5.1 菜单树
- **一级菜单**:营收业务
- **二级菜单**:发票管理
- **三级菜单**
1. 发票开具
2. 发票查询
3. 红冲处理
4. 作废处理
5. 异常处理
### 5.2 菜单命名原则
- 名称面向财务人员理解,不使用技术化名称。
- 菜单名称直接对应主要任务,不采用“管理中心”“作业平台”等泛化命名。
- 红冲、作废、异常分别独立,不与“发票查询”混合。
---
## 6. 总体交互原则
1. 财务主入口固定为 **发票开具**
2. 发票开具默认展示 **缴费记录视图**,并在页内切换到 **客户汇总视图**
3. 发票查询作为历史结果与后续处理入口页。
4. 红冲、作废、异常均按“任务池”组织,优先突出待处理量和失败原因。
5. 所有高风险动作都需要二次确认。
6. 所有列表页均支持批量操作、导出与列配置。
---
## 7. 数据源口径
### 7.1 主数据源:缴费记录待开票
适用于:
- 居民用户电子普票
- 中小客户单笔开票
- 后台财务批量开票
- 特殊开账缴费后的开票
页面表现:
- 发票开具页默认视图
- 一笔缴费记录是一个待开票对象
- 支持同一客户多笔缴费记录批量开票
### 7.2 辅助数据源:客户汇总待开票
适用于:
- 大客户
- 政企客户
- 需要合并开票的集团户
- 专票场景
页面表现:
- 仅在发票开具页内切换视图
- 先看客户聚合,再展开客户下的待开票缴费记录
### 7.3 备用数据源:账单维度待开票
仅用于极特殊场景,不作为常规菜单或默认视图:
- 预付费特殊口径
- 协议先票后款
- 历史遗留修复
页面表现:
- 不提供独立菜单
- 仅通过特殊权限入口进入
---
## 8. 页面设计
## 8.1 发票开具页
### 页面定位
财务主作业页,用于待开票记录筛选、批量开票、单笔开票、查看开票信息。
### 页面结构
1. **查询区**
- 缴费日期范围
- 缴费单号
- 客户编号
- 客户名称
- 用户类型
- 开票状态
- 发票类型
- 营业网点 / 水司
- 收费渠道
- 是否大客户
- 特殊开账标识
2. **统计条区**
- 待开票笔数
- 待开票金额
- 今日新增待开票
- 大客户待开票金额
3. **工具栏区**
- 查询
- 重置
- 批量开票
- 批量校验
- 导出
- 切换视图(缴费记录 / 客户汇总)
4. **表格区**
- 默认:缴费记录待开票表
- 切换:客户汇总待开票表
### 缴费记录视图字段
- 选择框
- 缴费日期
- 缴费单号
- 客户编号
- 客户名称
- 户号
- 水表号
- 账期
- 缴费金额
- 可开票金额
- 费用类型
- 发票类型
- 开票抬头
- 税号
- 开票状态
- 特殊开账标识
- 收费渠道
- 收费员
- 操作
### 客户汇总视图字段
- 选择框
- 客户编号
- 客户名称
- 客户类型
- 税号
- 未开票笔数
- 未开票金额
- 默认发票类型
- 默认开票信息完整度
- 最近开票日期
- 操作(展开明细 / 合并开票)
### 行内动作
- 查看明细
- 查看开票信息
- 单笔开票
### 批量动作
- 批量开票
- 批量校验
- 批量导出
### 页面内视图切换要求
- 默认进入缴费记录视图
- 切换至客户汇总视图时,保留已输入的共用筛选条件
- 客户汇总视图下的开票动作仍落到缴费记录级别明细校验
---
## 8.2 发票查询页
### 页面定位
历史发票归档、结果核验与后续处理入口页。
### 页面结构
1. **查询区**
- 开票日期范围
- 发票号码
- 发票代码
- 客户名称
- 客户编号
- 发票类型
- 发票状态
- 推送状态
- 红冲状态
- 作废状态
- 开票人
2. **工具栏区**
- 查询
- 重置
- 导出
- 批量下载
- 批量重推送
- 批量打印(后续可选)
3. **表格区**
- 发票主记录列表
### 表格字段
- 发票号码
- 发票代码
- 客户名称
- 税号
- 开票日期
- 发票金额
- 关联缴费笔数
- 发票状态
- 推送状态
- 下载状态
- 红冲状态
- 作废状态
- 开票人
- 操作
### 行内动作
- 详情
- 下载
- 重推送
- 发起红冲
- 发起作废
---
## 8.3 红冲处理页
### 页面定位
红字发票任务池,用于对已开具发票进行冲销处理。
### 页面结构
1. **查询区**
- 红冲申请日期
- 原发票号码
- 客户名称
- 红冲状态
- 退款状态
- 申请人
2. **工具栏区**
- 查询
- 重置
- 批量提交红冲
- 批量重试
- 导出
3. **表格区**
- 待红冲 / 红冲中 / 红冲成功 / 红冲失败
### 表格字段
- 原发票号码
- 原发票代码
- 客户名称
- 红冲申请时间
- 红冲原因
- 关联退款金额
- 红冲状态
- 失败原因
- 申请人
- 审核人
- 操作
### 行内动作
- 查看原发票
- 查看退款关联
- 提交红冲
- 重试
- 查看失败原因
---
## 8.4 作废处理页
### 页面定位
作废任务池,用于对满足条件的发票进行作废。
### 页面结构
1. **查询区**
- 作废申请日期
- 发票号码
- 客户名称
- 作废状态
- 申请人
2. **工具栏区**
- 查询
- 重置
- 批量作废
- 批量重试
- 导出
3. **表格区**
- 待作废 / 作废中 / 作废成功 / 作废失败
### 表格字段
- 发票号码
- 客户名称
- 作废申请时间
- 作废原因
- 发票金额
- 作废状态
- 失败原因
- 申请人
- 操作
### 行内动作
- 查看发票详情
- 提交作废
- 重试
- 查看失败原因
---
## 8.5 异常处理页
### 页面定位
集中处理开票失败、回执异常、推送异常、下载异常与对账异常的任务池页面。
### 页面结构
1. **查询区**
- 异常日期
- 异常类型
- 业务单号
- 客户名称
- 当前状态
- 是否已重试
- 异常节点
2. **工具栏区**
- 查询
- 重置
- 批量重试
- 批量改派
- 导出
3. **表格区**
- 开票失败
- 回执异常
- 下载异常
- 推送异常
- 对账异常
### 表格字段
- 异常类型
- 业务单号
- 客户名称
- 发票号码
- 金额
- 异常节点
- 异常原因
- 重试次数
- 最新处理时间
- 当前状态
- 操作
### 行内动作
- 查看详情
- 重试
- 查看日志
- 改派处理
- 标记人工处理完成
---
## 8.6 发票详情页
### 页面定位
作为独立只读详情页,承载完整发票业务轨迹,不使用普通小弹窗替代。
### 页面结构
1. 基本信息区
2. 关联缴费记录区
3. 开票与推送轨迹区
4. 红冲 / 作废 / 异常日志区
### 推荐字段分组
#### 基本信息
- 发票代码
- 发票号码
- 发票类型
- 发票金额
- 开票日期
- 发票状态
- 开票人
#### 开票对象
- 客户编号
- 客户名称
- 发票抬头
- 纳税人识别号
- 地址电话
- 开户行
- 银行账号
- 邮箱
- 手机号
#### 关联业务
- 关联缴费笔数
- 关联缴费单号列表
- 账期范围
- 费用类型
- 特殊开账标识
#### 处理轨迹
- 推送状态
- 下载状态
- 红冲状态
- 作废状态
- 外部回执号
- 最近处理时间
- 失败原因
- 重试次数
---
## 9. 弹窗设计边界
### 9.1 开票信息弹窗
用于查看 / 维护:
- 发票抬头
- 税号
- 地址电话
- 开户行
- 银行账号
- 邮箱
- 手机号
- 发票类型
### 9.2 批量开票确认弹窗
用于确认:
- 本次勾选笔数
- 本次开票总金额
- 发票类型
- 抬头归属
- 校验通过/失败摘要
### 9.3 红冲原因弹窗
用于录入:
- 红冲原因
- 退款说明
- 备注
- 附件说明(后续可扩展)
### 9.4 作废原因弹窗
用于录入:
- 作废原因
- 备注
### 9.5 异常日志弹窗
用于快速查看:
- 异常节点
- 原始错误信息
- 外部回执
- 重试记录
- 最新处理结果
---
## 10. 页面跳转关系
### 10.1 主链路:批量开票
`发票开具页`
→ 勾选缴费记录
`批量开票确认弹窗`
→ 提交开票
→ 成功后可跳转 `发票查询页`
### 10.2 大客户链路:客户汇总合并开票
`发票开具页`
→ 切换到客户汇总视图
→ 选择客户
→ 展开明细 / 进入客户待开票记录
`批量开票确认弹窗`
→ 提交开票
`发票查询页`
### 10.3 后处理链路:红冲 / 作废
`发票查询页`
→ 发起红冲 / 发起作废
→ 跳转 `红冲处理页` / `作废处理页`
→ 原票详情查看 / 填原因 / 提交处理
→ 结果回写 `发票查询页`
### 10.4 补救链路:异常处理
`异常处理页`
→ 查看失败原因
→ 重试 / 改派 / 人工处理
→ 回到对应业务页复核
---
## 11. 权限模型建议
### 11.1 菜单权限
- 发票开具
- 发票查询
- 红冲处理
- 作废处理
- 异常处理
### 11.2 按钮权限
#### 发票开具页
- 查询
- 导出
- 查看明细
- 查看开票信息
- 单笔开票
- 批量开票
- 批量校验
#### 发票查询页
- 查询
- 导出
- 详情
- 下载
- 重推送
- 发起红冲
- 发起作废
#### 红冲处理页
- 查询
- 导出
- 提交红冲
- 批量红冲
- 重试
- 查看失败原因
#### 作废处理页
- 查询
- 导出
- 提交作废
- 批量作废
- 重试
#### 异常处理页
- 查询
- 导出
- 重试
- 改派
- 查看日志
- 标记人工完成
### 11.3 特殊动作权限
以下权限建议独立控制:
- 客户汇总合并开票
- 红冲
- 作废
- 异常改派
- 账单维度补充开票
- 大额批量开票
- 人工强制重试
---
## 12. 状态模型建议
## 12.1 开票状态(发票开具页主状态)
- 待开票
- 校验失败
- 开票中
- 开票成功
- 开票失败
## 12.2 发票生命周期状态(发票查询页主展示)
- 已开具
- 已推送
- 部分推送失败
- 红冲中
- 已红冲
- 作废中
- 已作废
- 状态异常
## 12.3 异常类型(异常处理页)
- 开票失败
- 回执异常
- 推送异常
- 下载异常
- 红冲失败
- 作废失败
- 对账异常
## 12.4 展示原则
- 开票状态、推送状态、红冲状态、作废状态分别展示,不合并成单一总状态。
- 列表页状态标签必须能直接支持财务筛选,不要求用户进入详情后再判断。
---
## 13. 字段优先级建议
### 13.1 A 级(默认必须可见)
- 客户名称
- 缴费单号 / 发票号码
- 金额
- 状态
- 发票类型
- 日期
- 失败原因 / 异常状态
- 操作
### 13.2 B 级(默认展示,可折叠)
- 客户编号
- 税号
- 收费渠道
- 营业网点
- 特殊开账标识
- 开票人
- 推送状态
### 13.3 C 级(列配置按需打开)
- 水表号
- 户号
- 账期
- 商品税收分类编码
- 下载状态
- 最近重试时间
- 外部回执号
- 供应商名称
---
## 14. 字段语义分组建议
### 14.1 业务来源组
- 缴费单号
- 账单号
- 客户编号
- 客户名称
- 户号
- 水表号
- 账期
- 特殊开账标识
- 收费渠道
- 营业网点
### 14.2 开票主体组
- 发票抬头
- 纳税人识别号
- 地址电话
- 开户行
- 银行账号
- 邮箱
- 手机号
- 发票类型
### 14.3 金额税务组
- 缴费金额
- 可开票金额
- 发票金额
- 税率
- 税额
- 不含税金额
- 商品税收分类编码
- 费用类型
### 14.4 状态轨迹组
- 开票状态
- 推送状态
- 下载状态
- 红冲状态
- 作废状态
- 异常类型
- 失败原因
- 最近处理时间
- 重试次数
### 14.5 审计留痕组
- 开票人
- 开票时间
- 申请人
- 审核人
- 操作时间
- 外部发票号码
- 外部回执号
- 处理备注
---
## 15. 财务视角下的最终方案
`REV-005` 前端采用“**标准列表入口 + 五个三级菜单页**”的财务后台模型:
- `发票开具`:主作业页,默认缴费记录视图,可切客户汇总视图
- `发票查询`:历史结果页与后处理入口页
- `红冲处理`:红字发票任务池
- `作废处理`:作废任务池
- `异常处理`:失败和异常集中处理池
整体原则如下:
1. 批量处理优先于单笔处理。
2. 缴费记录优先于客户汇总,客户汇总优先于账单补充。
3. 高风险动作单独授权。
4. 状态拆分展示,避免财务误判。
5. 详情页承载全量轨迹,弹窗只承接局部动作。
---
## 16. 与既有正式工件的关系
本文件补充的是 **前端财务页面与导航设计**,应与以下正式工件一起使用:
- `specs/002-rev005-invoice-flow/spec.md`
- `specs/002-rev005-invoice-flow/plan.md`
- `specs/002-rev005-invoice-flow/tasks.md`
- `specs/002-rev005-invoice-flow/data-model.md`
- `specs/002-rev005-invoice-flow/contracts/if-rev-008-invoice-application.md`
- `specs/002-rev005-invoice-flow/contracts/if-rev-009-invoice-query.md`
若后续进入 `water-frontend` 实现阶段,本文件可直接作为:
- 路由与菜单拆分输入
- 页面目录结构输入
- 查询区与列表字段输入
- 权限点拆分输入
- 页面模板选型输入
---
## 17. 未纳入本轮的事项
以下内容明确不在本轮设计范围内:
- 客户侧电子发票入口页面设计
- 微信端电子发票入口页面设计
- 供应商税控配置页面
- 发票打印模板设计
- 发票审批流页面
- 发票统计分析看板
后续若扩展 `CS-004``WECHAT-004``SYS-008`,应分别建立独立设计补充,不在本文件中混合扩展。

View File

@ -0,0 +1,125 @@
# Feature Specification: [FEATURE NAME]
**Feature Branch**: `[###-feature-name]`
**Created**: [DATE]
**Status**: Draft
**Input**: User description: "$ARGUMENTS"
## Document Scope & Sources *(mandatory)*
- **Target documents**: [List the exact files intended to be updated]
- **Primary source of truth**: [List the authoritative main docs]
- **Reference sources**: [List allowed Archive/guides/supporting docs]
- **Scope decision**: [State whether this request is in scope, needs confirmation, or is out of scope]
## Repository Scope *(mandatory)*
- **Target repos**:
- `water-docs`: [Required / Not Required]
- `water-backend`: [Required / Not Required]
- `water-frontend`: [Required / Not Required]
- **Expected delivery type**: [Document closure / Code evidence alignment / Backend implementation / Frontend implementation / Mixed]
- **Out of scope for this round**: [List anything explicitly excluded]
## Code Baseline *(mandatory for brownfield work)*
- **Backend baseline**: [commit SHA / branch / N/A]
- **Frontend baseline**: [commit SHA / branch / N/A]
- **Baseline capture rule**: [How the implementation evidence will be tied back to a specific code version]
## Evidence Scope *(mandatory)*
- **Document evidence required**: [Which formal docs or specs must be updated]
- **Backend evidence required**: [Controllers / services / tests / compile / N/A]
- **Frontend evidence required**: [Pages / routes / build / smoke / N/A]
- **Verification artifacts required**: [baseline.md / docs-validation.md / backend-validation.md / frontend-validation.md / final-verdict.md]
## User Scenarios & Testing *(mandatory)*
<!--
For this repository, user stories should describe independently reviewable
document-maintenance, implementation, or verification outcomes.
-->
### User Story 1 - [Brief Title] (Priority: P1)
[Describe the primary independently reviewable outcome in plain language]
**Why this priority**: [Explain the value and why it has this priority level]
**Independent Test**: [Describe how this can be reviewed independently]
**Acceptance Scenarios**:
1. **Given** [initial state], **When** [action], **Then** [expected outcome]
2. **Given** [initial state], **When** [action], **Then** [expected outcome]
---
### User Story 2 - [Brief Title] (Priority: P2)
[Describe this user journey in plain language]
**Why this priority**: [Explain the value and why it has this priority level]
**Independent Test**: [Describe how this can be tested independently]
**Acceptance Scenarios**:
1. **Given** [initial state], **When** [action], **Then** [expected outcome]
---
### User Story 3 - [Brief Title] (Priority: P3)
[Describe this user journey in plain language]
**Why this priority**: [Explain the value and why it has this priority level]
**Independent Test**: [Describe how this can be tested independently]
**Acceptance Scenarios**:
1. **Given** [initial state], **When** [action], **Then** [expected outcome]
---
### Edge Cases
- What happens when the formal document conclusion and the current code evidence do not align?
- What happens when a requested change is only supported by Archive history but not by current main docs?
- How does the workflow handle broken relative links, unstable anchors, or Mermaid syntax regressions introduced by edits?
- What happens when the backend and frontend are on different commits and the feature must still produce a single verdict?
## Requirements *(mandatory)*
### Functional Requirements
- **FR-001**: Specification MUST identify the exact target documents that will be changed.
- **FR-002**: Specification MUST identify the main source-of-truth documents that govern the change.
- **FR-003**: Specification MUST identify which repositories are in scope and which are explicitly out of scope for the round.
- **FR-004**: Specification MUST record backend/frontend code baselines or explicitly mark them N/A.
- **FR-005**: System MUST preserve the single-source-of-truth model and MUST NOT assume creation of new parallel formal documents unless explicitly approved.
- **FR-006**: Specification MUST list the validation actions needed after the change, including file validation and any required link or Mermaid checks.
- **FR-007**: Specification MUST state whether management ledgers need updates in `01_Project_Progress.md` and `03_Task_Checklist.md`.
- **FR-008**: Specification MUST capture cross-document consistency impacts when terminology, numbering, diagrams, references, or interface contracts may change.
- **FR-009**: Specification MUST define what evidence artifacts are required before the feature can be marked complete.
### Key Entities *(include if feature involves data)*
- **Target Document**: A Markdown file that will be modified as part of the request.
- **Source of Truth Document**: A main document or governance document that constrains allowed conclusions.
- **Reference Source**: Archive or guide material used only for verification, traceability, or scope judgment.
- **Code Baseline**: A backend or frontend commit reference used to anchor brownfield implementation evidence.
- **Evidence Artifact**: A document under `specs/` or `evidence/` that records validation, code proof, or the final verdict.
- **Ledger Update**: A required change to project progress or task checklist records after important modifications.
## Success Criteria *(mandatory)*
### Measurable Outcomes
- **SC-001**: Every target document and in-scope repository is explicitly named before implementation begins.
- **SC-002**: Every completed change can be traced to at least one source-of-truth or approved reference source.
- **SC-003**: Required validation and evidence actions are explicitly listed and can be executed without ambiguity.
- **SC-004**: Reviewers can determine from the spec alone whether ledger updates, code-baseline capture, and cross-document sync are required.
- **SC-005**: The feature can produce a final verdict without relying on unstated assumptions about backend or frontend implementation status.

View File

@ -0,0 +1,164 @@
# 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` 的高风险操作。