diff --git a/.gitignore b/.gitignore index 1f74b29..5e5c15d 100644 --- a/.gitignore +++ b/.gitignore @@ -42,3 +42,4 @@ build/ .env* temp_mermaid_* .codex +.omx/ diff --git a/AGENTS.md b/AGENTS.md index 2967ee1..ce3a5b4 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -36,6 +36,55 @@ - frontend lane 只改 `water-frontend` - verify lane 负责样本、日志、验收结论和基线固定 +## specs/ 与 docs/design/ 生命周期 + +本仓库维护两套文档体系,有明确的「一次性 ↔ 持续维护」分工。 + +### specs/ — 过程工件(建设期蓝图,建成后封存) + +`specs/<编号>-/` 是 feature 建设阶段的工作台,每个目录包含: + +- `spec.md`:功能规格(一次性,建成后不维护) +- `plan.md`:实施计划(一次性) +- `tasks.md`:任务拆分(一次性) +- `research.md`:调研记录(一次性) +- `verification.md`:验收记录(建成后封存) +- `data-model.md`:建设期数据模型草稿。建成后正式维护口已移交 `docs/design/03_Technical_Design/01_Database_Design.md` +- `contracts/`:建设期接口契约草稿。建成后正式维护口已移交 `docs/design/03_Technical_Design/03_Interface_Design.md` + +**规则**: +- `spec.md` / `plan.md` / `tasks.md` / `research.md` / `verification.md` 在 feature 建设期间活跃编辑,建成后封存不再修改。 +- `data-model.md` 和 `contracts/` 是临时草稿,feature 建成后数据模型和接口的唯一真源是 `docs/design/` 下的主文档。 +- 禁止在两个体系里并行维护同一份数据模型或接口定义。 +- 禁止创建同一个 feature 的多个 spec 目录(如 `003` 和 `006` 都是 REV-006),发现重复必须合并。 + +### docs/design/ — 正式交付文档(唯一真源,持续维护) + +`docs/design/` 是正式交付的「建成物」描述,所有模块的最终定义收敛在此: + +- `02_Detailed_Design/12_REV_Detailed.md`:REV 模块的功能描述唯一真源 +- `03_Technical_Design/01_Database_Design.md`:表结构的唯一真源 +- `03_Technical_Design/03_Interface_Design.md`:接口定义的唯一真源 + +**规则**:feature 建成后,所有后续维护、修订、查阅原则上以 `docs/design/` 为准,`specs/` 只作为历史追溯参考。 + +### docs/evidence/ — 验证证据(按模块组织) + +证据文件按模块分子目录存放: + +- `docs/evidence/rev004-accounting/` +- `docs/evidence/rev005-invoice/` +- `docs/evidence/rev006-reminder/` +- `docs/evidence/rev007-statistics/` + +禁止在 `docs/evidence/` 根目录平铺散文件。新证据必须归入对应模块子目录。 + +### docs/guides/ — 系统级指南 + +`docs/guides/` 只保留系统级指南(如 Speckit 工作流、系统能力地图、后端现状等)。模块专项操作指南归入 `docs/evidence/<模块>/`。 + +--- + 本文件用于指导通用代码代理(包括 Codex 类代理)在本仓库中的工作方式。 ## 项目定位 @@ -55,18 +104,19 @@ ```text / -├── docs/design/00_Management/ # 项目管理、进度跟踪、交付规范、编写指南 -├── docs/design/01_Overview/ # 总体设计:系统概述、系统架构、概要设计、系统图谱 -├── docs/design/02_Detailed_Design/ # 详细设计:主详设、模块设计、CA 安装设计 -├── docs/design/03_Technical_Design/ # 技术专项:数据库、表结构、接口、安全、部署、加密 -├── docs/design/04_Appendix/ # 附录与归档资料 -├── .claude/ # Claude Code 相关配置 -├── .omc/ # 项目记忆与代理状态 -├── .zed/ # Zed 项目配置 -├── assets/ # 图片、模板等静态资源 -├── docs/ # 研究资料、映射文档、使用指南 -├── scripts/ # 文档处理与导出脚本 -└── infra/ # 辅助基础设施 +├── specs/ # 过程工件:feature 建设期蓝图,建成后封存 +├── docs/design/00_Management/ # 项目管理、进度跟踪、交付规范、编写指南 +├── docs/design/01_Overview/ # 总体设计:系统概述、系统架构、概要设计、系统图谱 +├── docs/design/02_Detailed_Design/ # 详细设计:主详设、模块设计(功能描述唯一真源) +├── docs/design/03_Technical_Design/ # 技术专项:数据库、接口、安全、部署(表结构/接口定义唯一真源) +├── docs/design/04_Appendix/ # 附录与归档资料 +├── docs/evidence/ # 验证证据(按模块分子目录) +├── docs/guides/ # 系统级指南 +├── .claude/ # Claude Code 相关配置 +├── .codex/ # Codex 相关配置 +├── assets/ # 图片、模板等静态资源 +├── scripts/ # 文档处理与导出脚本 +└── infra/ # 辅助基础设施 ``` ## 当前文档组织原则 @@ -82,7 +132,7 @@ - `docs/design/03_Technical_Design/04_Security_Design.md`:安全设计主文档 - `docs/design/03_Technical_Design/05_Deployment_Design.md`:部署设计主文档 -如果已有主文档可以承载内容,**优先编辑现有文件,而不是新增“新-xxx”“最终版”“修订版”之类文件**。 +如果已有主文档可以承载内容,**优先编辑现有文件,而不是新增"新-xxx""最终版""修订版"之类文件**。 ### Archive 仅作归档 @@ -124,7 +174,7 @@ - 风格要求专业、克制、可交付,避免口语化和宣传化表述 - 不写与当前项目无关的泛化模板内容 -### 以“对齐现状”为第一原则 +### 以"对齐现状"为第一原则 所有修改必须优先对齐以下事实来源: @@ -146,7 +196,7 @@ ### 不要过度发挥 - 不要凭空补充不存在的子系统、模块、接口、表 -- 不要为了“显得完整”加入大量无依据的实现细节 +- 不要为了"显得完整"加入大量无依据的实现细节 - 不要默认加入大段代码示例、部署脚本、DDL、伪代码,除非用户明确要求 - 不要创建多余术语体系;优先沿用仓库现有命名 @@ -168,7 +218,7 @@ **福建水务营收系统** -除引用原始资料外,不要混用“营业收费系统”“数智营收管理系统”“客户服务平台”等作为正式系统名称。 +除引用原始资料外,不要混用"营业收费系统""数智营收管理系统""客户服务平台"等作为正式系统名称。 ### 数据库口径 @@ -186,7 +236,7 @@ ### 图表规范 - 所有正式图表优先使用 Mermaid -- 图表必须与正文一致,不能“图一套、文一套” +- 图表必须与正文一致,不能"图一套、文一套" - Mermaid 节点命名尽量避免容易导致解析异常的写法 - 调整图表时,同时检查导出可用性和可读性 @@ -302,7 +352,7 @@ npm run marksman:server - 擅自扩展需求的产品经理 - 无依据发明实现细节的方案生成器 -- 动辄新建文件的“版本制造机” +- 动辄新建文件的"版本制造机" ## 最终目标 diff --git a/docs/design/00_Management/01_Project_Progress.md b/docs/design/00_Management/01_Project_Progress.md index 42ca61d..4cf0bb6 100644 --- a/docs/design/00_Management/01_Project_Progress.md +++ b/docs/design/00_Management/01_Project_Progress.md @@ -118,6 +118,15 @@ | 2026-03-26 | 方案二整体部署方案独立成文 | 1)新增 `docs/design/03_Technical_Design/08_Integrated_Deployment_Design_PlanB.md`,将已采纳 PostgreSQL 16 方案二后的整体部署方案独立成文;2)结合当前前后端分层部署形态,补齐应用、数据库、中间件、静态存储的一体化部署结构;3)新增软件拓扑图、网络拓扑图、主机角色划分、资源配置建议、网络需求和端口访问建议;4)在 `07_PostgreSQL16_DR_Resource_Application.md` 增加独立文档引用说明,在技术专项目录增加入口。 | 用户明确要求不要仅在 `07` 文档内保留方案二内容,而是需要形成独立文件,并作为已采纳数据库方案后的整体部署方案提交评审。 | 正面影响,数据库资源申请专题与整体部署方案实现职责分离;后续甲方可分别评审“数据库容灾资源申请”和“系统整体部署方案”,减少口径混杂并提升部署审批的可读性。 | | 2026-04-02 | 方案二整体部署文档按网络图口径对齐 | 1)将 `docs/design/03_Technical_Design/08_Integrated_Deployment_Design_PlanB.md` 的网络分区口径统一为“办公区 / 公网区域 / 互联网区DMZ / 内网区”;2)将 `Nginx` 入口、业务应用节点、`SFTP/FTP` 文件交换服务器的部署区域说明统一调整为与评审图一致;3)同步修正网络拓扑图、访问链路、带宽/端口、资源角色及结论段落中的命名与边界表述。 | 用户提供最新部署图,要求正式文档向图片口径靠拢,消除 `内网 Nginx`、应用区/DMZ、办公区等描述不一致问题。 | 正面影响,整体部署方案的图文一致性显著提升,便于甲方按统一网络边界和主机分区口径开展安全评审与资源审批。 | +| 2026-04-03 | REV-004 全量账务领域设计骨架落地 | 1)新增 `docs/evidence/rev004-accounting/REV004_FULL_ACCOUNTING_DOMAIN_DESIGN.md`,将“完整承载旧系统账务业务”的目标建模路线落为单一设计底稿;2)统一旧系统账务对象、目标分层、正式业务实体、关系图、目标表设计骨架、迁移与兼容策略、逐步细化计划;3)明确该文档作为后续正式主文档回写前的统一骨架,不与现有 `REV-004` 一期 spec 冲突。 | 用户提出当前目标不是“一期最小闭环”,而是“新系统完整承载旧系统账务业务”,需要先搭建设计骨架再逐步细化并统一口径。 | 正面影响,后续关于账务实体、台账迁移、查询兼容、审批流和数据库设计的讨论有了统一底稿,可显著降低“继续沿用一期口径”和“直接机械平移旧表”之间的反复摇摆。 | +| 2026-04-03 | REV-004 详设正式回写首批收口(RWB-01) | 1)按 `RWB-01` 规则生成正式详设快照 `docs/design/04_Appendix/Archive/08_Formal_Doc_Snapshots/RWB-01/2026-04-03-RWB-01-12_REV_Detailed.md`,基线对应 docs 仓 commit `9d2ecf1`;2)重写 `docs/design/02_Detailed_Design/12_REV_Detailed.md` 的 `REV-004 账务处理` 章节,改为“当前正式边界 + 全量目标边界”双层写法,并纳入全量账务对象、审批分层、迁移承接和现状/目标边界;3)保持 `IF-REV-007` 当前统一入口事实,不将目标态误写为已全部落地实现。 | 用户同意从回写准备进入 `RWB-01`,要求先把 `12_REV_Detailed.md` 中 `REV-004` 正式详设改写为可承接全量账务领域的正式入口。 | 正面影响,`REV-004` 正式详设已从“一期五类场景”提升为“可承接全量账务对象的正式入口”,为后续数据库设计、接口设计与迁移专题回写建立了稳定锚点,同时保留了现状/目标分层表达,降低将目标态误判为当前实现的风险。 | +| 2026-04-03 | REV-004 数据库专项正式回写首批收口(RWB-02) | 1)按 `RWB-02` 规则生成数据库专项快照 `docs/design/04_Appendix/Archive/08_Formal_Doc_Snapshots/RWB-02/2026-04-03-RWB-02-01_Database_Design.md`,基线对应 docs 仓 commit `9d2ecf1`;2)更新 `docs/design/03_Technical_Design/01_Database_Design.md` 中 `SYS-002 开账、收费与票据表`、`biz_operat_log*`、历史台账迁移口径、索引关注点与归档补充,将 `REV-004` 从“一期不新增细表”扩展为“统一骨架 + 目标对象 + 查询投影 / 历史映射”的数据库专项口径;3)正式命名 `AccountingWorkflowRef` 与 `AccountingLegacyMapping` 为目标数据库承接对象,但仍保持“待补字段关注点”写法,不误写成已落地真实表。 | 用户同意进入 `RWB-02` 正式回写,要求先把数据库专项调整为能够承接全量账务领域的正式数据库设计入口。 | 正面影响,数据库专项已从“只描述现有骨架表”提升为“同时约束统一骨架、目标对象、历史映射和查询投影”的正式口径,为后续接口设计回写和实现落表讨论建立了稳定边界,同时避免把目标对象误判为已全部物理落地。 | +| 2026-04-03 | REV-004 接口专项正式回写首批收口(RWB-03) | 1)按 `RWB-03` 规则生成接口专项快照 `docs/design/04_Appendix/Archive/08_Formal_Doc_Snapshots/RWB-03/2026-04-03-RWB-03-03_Interface_Design.md`,基线对应 docs 仓 commit `9d2ecf1`;2)更新 `docs/design/03_Technical_Design/03_Interface_Design.md` 中 `IF-REV-007`、其请求/响应参数、数据对象与表口径、历史查询与迁移校验接口口径、实现状态说明,将 `REV-004` 从“一期五类场景统一入口”扩展为“当前统一入口 + 全量账务对象承接边界 + 历史查询分层”的正式接口口径;3)保持专属接口仍为后续方向,不误写成当前 backend 已完整落地能力。 | 用户同意进入 `RWB-03` 正式回写,要求先把接口专项调整为能够承接全量账务领域的正式接口设计入口。 | 正面影响,接口专项已从“一期统一处理接口说明”提升为“统一入口、对象承接边界、历史查询出口、实现状态分层”并存的正式口径,为后续总体设计回写和实现拆接口讨论建立了稳定约束,同时避免把目标专属接口误判为当前既成事实。 | +| 2026-04-03 | REV-004 总体摘要正式回写收口(RWB-04) | 1)按 `RWB-04` 规则生成总体摘要快照 `docs/design/04_Appendix/Archive/08_Formal_Doc_Snapshots/RWB-04/2026-04-03-RWB-04-03_Summary_Design.md`,基线对应 docs 仓 commit `9d2ecf1`;2)更新 `docs/design/01_Overview/03_Summary_Design.md` 中总体接口定义、营收业务系统外部接口、营收核心模块群概述、模块列表与 `REV-004` 模块摘要,使 REV-004 从“一期五类处理摘要”收敛为“当前统一入口 + 全量账务对象目标边界”的概要口径;3)继续保留当前已落地事实与目标设计边界分层表达,不将专属接口或独立对象实现写成已全部落地。 | 用户同意进入 `RWB-04`,要求完成 REV-004 全量账务领域在总体摘要层的正式收口。 | 正面影响,概要、详设、数据库、接口四层文档现已围绕 REV-004 形成一致口径;后续再讨论实现拆分、迁移验收与对象落表时,可直接基于统一的正式文档体系推进,显著降低跨层级表述不一致风险。 | +| 2026-04-03 | REV-004 实现分发清单与 Agent 交接模板落地 | 1)新增 `docs/evidence/rev004-accounting/REV004_IMPLEMENTATION_HANDOFF.md`,将 REV-004 全量账务领域的后端、前端、联调任务拆分为可直接分发的实现清单;2)同步整理对象范围、统一入口约束、历史只读/映射层边界、建议任务包与给其他 Agent 的提示模板;3)保持该文档定位为实现交接指南,不替代正式设计真源。 | 用户需要一份可直接分发给前后端实现 Agent 的功能清单和对应需求,用于后续协作执行。 | 正面影响,后续多 Agent 协作不再需要重复从正式文档中人工提炼任务;实现范围、分工边界与交接提示可直接复用,降低理解偏差和重复沟通成本。 | +| 2026-04-07 | REV-004 前端实现正式 handoff 落地 | 1)新增 `docs/evidence/rev004-accounting/REV004_FRONTEND_IMPLEMENTATION_HANDOFF.md`,将已批准的 REV-004 前端实现方案转为正式交接文档;2)明确本轮仅覆盖管理后台,不纳入微网厅/客户端实现;3)补齐四张正式执行表:页面清单、路由清单、通用组件清单、lane ownership 清单,并固化 `../water-frontend` 目录下的 `omx team` 执行边界。 | 用户要求把已达成共识的 REV-004 前端实现计划转为正式 handoff Markdown,并细化为可直接执行的正式表格。 | 正面影响,前端实现协作从“计划草案”升级为“执行交接文档”;后续在 `water-frontend` 中可直接按页面清单、路由清单、组件清单和 lane ownership 推进,降低前端实现阶段的范围漂移和分工冲突。 | +| 2026-04-07 | REV-004 前端 team prompts 落地 | 1)新增 `docs/evidence/rev004-accounting/REV004_FRONTEND_OMX_TEAM_PROMPTS.md`,将 leader 启动提示与 Lane A~F 执行 prompt 固化为可直接用于 `../water-frontend` 的 `omx team` 文本;2)保持本轮范围仅覆盖管理后台,不纳入微网厅/客户端实现;3)同步固化启动顺序、lane 职责边界与最终统一输出要求。 | 用户要求直接生成可在前端目录执行的 `omx team` prompts,用于下一步正式启动多 lane 实现。 | 正面影响,前端执行已从“交接文档阶段”进入“可直接开干的 prompt 阶段”;leader 与各 lane 不再需要临时编写任务说明,可直接按固定文本启动团队执行,降低启动成本与分工歧义。 | +| 2026-04-07 | REV-004 前端 team prompts 落地 | 1)新增 `docs/evidence/rev004-accounting/REV004_FRONTEND_TEAM_PROMPTS.md`,将 leader 启动提示与 Lane A~F 执行 prompt 固化为可直接用于 `../water-frontend` 的 `omx team` 文本;2)保持本轮范围仅覆盖管理后台,不纳入微网厅/客户端实现;3)同步固化启动顺序、lane 职责边界与最终统一输出要求。 | 用户要求直接生成可在前端目录执行的 `omx team` prompts,用于下一步正式启动多 lane 实现。 | 正面影响,前端执行已从“交接文档阶段”进入“可直接开干的 prompt 阶段”;leader 与各 lane 不再需要临时编写任务说明,可直接按固定文本启动团队执行,降低启动成本与分工歧义。 | | 2026-03-18 | REV-005 统计模板补齐 | 1)在 `specs/002-rev005-invoice-flow/verification.md` 为 `T055`、`T060`、`T061`、`T062`、`T063` 新增可直接填写的样本记录模板;2)将 SC-001 ~ SC-004 的建议统计口径细化为表格字段与待补说明,避免后续只剩抽象待办;3)保持“模板已补齐但实际统计结果仍待联调/测试环境补录”的真实状态,不虚构样本结果。 | 用户继续推进 REV-005,希望把剩余统计类待办进一步收敛成可执行模板,便于后续直接补录真实样本而不是重新设计统计格式。 | 正面影响,REV-005 当前已具备统一的统计与日志抽样记录模板;后续补 `T055`、`T060 ~ T063` 时可直接按模板填充真实环境数据,减少再次整理验证文档结构的成本。 | | 2026-03-18 | REV-005 verify 执行入口补齐 | 1)在 `specs/002-rev005-invoice-flow/verification.md` 补齐 `/business/invoice/apply`、`/query`、`/query/compensate`、`/write-back`、`/customer/query`、`/customer/download`、`/customer/push`、`/invalidate`、`/red-ink` 的最小请求模板;2)继续补齐 `T055`、`T060 ~ T063` 的执行命令草稿与样本采集顺序,明确仅作为测试/联调环境占位模板,真实地址、鉴权信息、业务主键与统计结果均待后续替换和回填;3)同步 `03_Task_Checklist.md`,将 verify 阶段推进到“替换真实环境参数即可执行”的状态。 | 用户继续推进 REV-005,希望不要停留在抽象验证建议,而是把剩余 verify 工作推进到可直接执行、可直接补样本的程度。 | 正面影响,REV-005 当前已具备统一的验证入口、请求模板、命令草稿与采样顺序;后续在测试或联调环境中可直接替换参数发起请求并回填 `T055`、`T060 ~ T063` 的真实结果,减少重复梳理接口和命令的成本。 | @@ -137,8 +146,8 @@ | 2026-03-16 | REV-005 后台发票申请与校验闭环(US1) | 1)在 `backend/sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/controller/admin/invoice/InvoiceController.java` 增加后台发票申请入口;2)在 `service/invoice/InvoiceServiceImpl.java` 实现客户、客户开票信息、账单与税率校验,确保仅已收费未开票账单允许申请;3)补齐 `applicationNo` 或 `custId + chargeIds` 幂等控制、申请单号生成与申请记录落库;4)执行 `mvn -f backend/sw-business/pom.xml -pl sw-business-server -am -DskipTests compile` 最小编译验证并通过。 | 用户要求继续推进 REV-005 implement,优先完成后台发票申请、开票校验与 US1 收尾,不中断当前实现链路。 | 正面影响,REV-005 已形成“后台申请入口 + 关键校验 + 幂等受理 + 最小编译验证”闭环,后续可在此基础上继续推进 SYS-008 调用、开票结果回写、账单状态联动与电子发票推送下载能力。 | | 2026-03-12 | OMX 任务路由样例落地 | 1)新增 `docs/design/00_Management/17_OMX_Task_Routing_Examples.md`,给出 `REV-004`、`REV-003` 与正式文档修订三类任务的 leader / explorer / executor / verifier 分工模板;2)补充各 lane 的提示词模板、推荐执行顺序与不建议的并行方式;3)更新 `00_Management/README.md` 收录该文档入口。 | 用户希望在治理层之外,再拿到针对当前项目可以直接复用的多 Agent 分工模板,而不是只看抽象原则。 | 正面影响,OMX 从“有规则”变成“可直接照着分工执行”;后续在 `REV-004`、`REV-003` 等闭环中可直接套用 lane 拆分,减少 leader 临时编排成本。 | | 2026-03-12 | OMX 多 Agent 治理层落地 | 1)在根 `AGENTS.md` 中新增 OMX 多 Agent 协作补充,明确分层 AGENTS、任务路由矩阵、写冲突规则、范围控制基线与 worktree/tmux 约定;2)新增 `backend/AGENTS.md`,固化 backend 开发边界、最小实现策略与 BPM 接入规则;3)新增 `docs/design/04_Appendix/Archive/AGENTS.md`,明确 Archive 默认只读与来源回写规则;4)新增 `docs/design/00_Management/16_OMX_Multi_Agent_Guide.md`,统一 leader / writer / executor / verifier 分工与协作拓扑;5)更新 `00_Management/README.md` 收录新指南入口。 | 用户明确准备采用 `oh-my-codex` 进行多 Agent 开发,需要对现有 AGENTS 体系做分层化和路由化改造,避免现有规则在 Team Mode 下失效。 | 正面影响,当前项目从“单 agent 规则完备”提升为“多 agent 可控协作”;后续接入 OMX 时,目录级职责、写权限边界、范围基线与会话约定已经成型,可显著降低并发改稿和多 worker 写冲突风险。 | -| 2026-03-12 | REV-004 一期执行手册与 worktree/tmux 启动脚本落地 | 1)新增 `docs/guides/REV004_ACCOUNTING_EXECUTION_PLAYBOOK.md`,将 `REV-004` 一期的范围、现状差距、最小改动方案、任务拆解、Codex Prompt 与验收清单固化为可执行手册;2)新增 `scripts/start-backend-codex-session.sh`,支持在 `backend/` 上创建或复用 worktree,并拉起 `tmux + codex` 三窗口开发会话;3)更新 `scripts/README.md` 记录脚本用途。 | 用户要求不仅给建议,还要把“如何规划执行、如何进入 worktree、如何在 tmux 场景下协作”落成可直接使用的资产。 | 正面影响,开发启动动作从“口头建议”变为“可复制执行”;后续围绕 `REV-004/REV-003/REV-008` 的闭环开发可直接复用该脚本和手册,降低 worktree、tmux、Codex 协作的起步成本与操作偏差。 | -| 2026-03-13 | REV-004 一期范围正式文档收敛(US1) | 1)更新 `docs/design/02_Detailed_Design/12_REV_Detailed.md`,将 REV-004 一期范围收敛为水量调整、金额调整、退款、冲正、坏账申请五类场景,并明确共性能力优先顺序、排除项与审批边界;2)重写 `docs/guides/REV004_ACCOUNTING_EXECUTION_PLAYBOOK.md`,将其从 backend 执行导向收敛为正式文档修订执行手册;3)同步 `docs/design/01_Overview/03_Summary_Design.md` 与 `specs/001-rev004-accounting/contracts/rev004-traceability-matrix.md` 的范围摘要与追溯说明;4)执行目标文档 `make validate-file` 与 `make check-links` 校验并通过。 | 用户要求在 implement 阶段先完成 REV-004 一期正式文档范围收敛,不把 backend 代码实现写成本轮已完成内容。 | 正面影响,REV-004 一期边界、验收入口与追溯关系已在正式文档体系内闭环,后续 US2/US3 可直接在稳定范围上继续对齐接口、数据库与台账,不再受早期执行手册偏代码导向表述干扰。 | +| 2026-03-12 | REV-004 一期执行手册与 worktree/tmux 启动脚本落地 | 1)新增 `docs/evidence/rev004-accounting/REV004_ACCOUNTING_EXECUTION_PLAYBOOK.md`,将 `REV-004` 一期的范围、现状差距、最小改动方案、任务拆解、Codex Prompt 与验收清单固化为可执行手册;2)新增 `scripts/start-backend-codex-session.sh`,支持在 `backend/` 上创建或复用 worktree,并拉起 `tmux + codex` 三窗口开发会话;3)更新 `scripts/README.md` 记录脚本用途。 | 用户要求不仅给建议,还要把“如何规划执行、如何进入 worktree、如何在 tmux 场景下协作”落成可直接使用的资产。 | 正面影响,开发启动动作从“口头建议”变为“可复制执行”;后续围绕 `REV-004/REV-003/REV-008` 的闭环开发可直接复用该脚本和手册,降低 worktree、tmux、Codex 协作的起步成本与操作偏差。 | +| 2026-03-13 | REV-004 一期范围正式文档收敛(US1) | 1)更新 `docs/design/02_Detailed_Design/12_REV_Detailed.md`,将 REV-004 一期范围收敛为水量调整、金额调整、退款、冲正、坏账申请五类场景,并明确共性能力优先顺序、排除项与审批边界;2)重写 `docs/evidence/rev004-accounting/REV004_ACCOUNTING_EXECUTION_PLAYBOOK.md`,将其从 backend 执行导向收敛为正式文档修订执行手册;3)同步 `docs/design/01_Overview/03_Summary_Design.md` 与 `specs/001-rev004-accounting/contracts/rev004-traceability-matrix.md` 的范围摘要与追溯说明;4)执行目标文档 `make validate-file` 与 `make check-links` 校验并通过。 | 用户要求在 implement 阶段先完成 REV-004 一期正式文档范围收敛,不把 backend 代码实现写成本轮已完成内容。 | 正面影响,REV-004 一期边界、验收入口与追溯关系已在正式文档体系内闭环,后续 US2/US3 可直接在稳定范围上继续对齐接口、数据库与台账,不再受早期执行手册偏代码导向表述干扰。 | | 2026-03-18 | 完成全仓旧模块编号残留审计 | 1)新增 `docs/design/00_Management/18_Old_Module_Number_Audit.md`,对 `docs/design`、`docs/guides`、`specs` 中的 `METER-004`、`INST-004`、`INST-005` 及相关旧模块语义进行全仓审计;2)将命中项分为“必须修”“可保留历史描述”“Archive 原始资料”“合法保留的接口编号/子能力表达”四类;3)更新 `docs/design/00_Management/README.md` 收录审计清单入口。 | 用户要求执行全仓旧编号残留审计,明确哪些需要继续修、哪些应作为历史资料保留。 | 正面影响,后续旧编号治理从“按检索临时判断”转为“按清单分类处理”;正式文档、管理台账与 Archive 的处理边界更加清晰。 | | 2026-03-18 | 旧模块编号残留收口与追溯链接修正 | 1)更新 `docs/design/02_Detailed_Design/03_CA_Esignature_Supplement.md`,将文档定位从旧 `INST-004` 修正为 `INST-002 工程管理` 下的“合同签署与电子签章能力”专项补充;2)修正 `docs/design/02_Detailed_Design/02_Module_Traceability_Index.md` 中 `INST-002`、`INST-003` 的章节锚点,确保跳转与当前三段式模块结构一致;3)复核 `docs/design/01_Overview/03_Summary_Design.md` 的主口径章节,确认残留 `IF-METER-004`、`IF-INST-004/005` 均为接口编号而非旧模块编号。 | 用户要求继续收口“旧编号视为错误”的相关正式文档,并区分必须修项与可保留历史描述。 | 正面影响,正式文档层的模块编号、追溯入口与专项补充挂接关系进一步统一,评审和检索时不会再因旧 `INST-004/005` 模块语义误跳转。 | | 2026-03-18 | 基于整体架构图补齐模块清单并对齐详细设计承接关系 | 1)新增 `docs/design/01_Overview/05_Module_Inventory.md`,将整体架构图中的分层、子系统、模块与当前详设承接关系整理为统一清单;2)更新 `docs/design/01_Overview/README.md` 与 `docs/design/02_Detailed_Design/README.md`,明确该清单作为模块枚举与承接核对入口;3)更新 `docs/design/02_Detailed_Design/01_Detailed_Design.md` 与 `docs/design/02_Detailed_Design/02_Module_Traceability_Index.md`,补充架构图模块清单与当前详设之间的映射说明,明确 `WECHAT-*`、`MOBILE-*`、`WORK-*` 等模块当前按业务域正文或协同能力承接。 | 用户要求根据 `output/preview/福建水务营收系统整体架构图.html` 形成模块清单,并以此为基线对齐 `02_Detailed_Design` 目录。 | 正面影响,架构图中的模块枚举与详细设计现状之间建立了稳定映射,后续评审时可直接判断“哪些模块已有正文、哪些是协同承接、哪些仍停留在架构层列示”,减少按图追文时的歧义。 | @@ -331,7 +340,7 @@ ### 2026-03-18 更新 -- 完成 `REV-006` Speckit feature `006-reminder-event-design` 的 implement 阶段文档收口,统一 `12_REV_Detailed.md`、`03_Interface_Design.md` 与治理台账口径。 +- 完成 `REV-006` Speckit feature `003-rev006-reminder-event-design` 的 implement 阶段文档收口,统一 `12_REV_Detailed.md`、`03_Interface_Design.md` 与治理台账口径。 - `REV-006` 正式业务接口编号确定为 `IF-REV-013`,不再复用 `IF-REV-009`;催缴结果状态统一为 `PENDING`、`SUCCESS`、`FAIL`、`MANUAL_VERIFIED` 四态。 - 明确旧“催缴记录 / 停水记录 / 预存短信记录”按历史只读口径承接,不新增同名在线主表;停复水在本轮仅保留联动边界、处置引用和追溯关系。 - 启动并完成 `REV-007` Speckit feature `004-rev007-revenue-statistics-design` 的 `specify -> plan -> tasks` 工件链,形成统计主题、维度、指标、`IF-REV-010` 与数据库承接口径的正式设计基线。 @@ -344,7 +353,7 @@ ### 2026-03-19 更新 -- 完成 `REV-006` 当前轮次治理文档二次对齐:在 `15_SYS002_Requirement_Breakdown.md` 明确 `SYS002-REQ-011` 继续维持“未见实现”判断,并补记 `specs/006-reminder-event-design/` 工件基线与后续研发切入建议。 +- 完成 `REV-006` 当前轮次治理文档二次对齐:在 `15_SYS002_Requirement_Breakdown.md` 明确 `SYS002-REQ-011` 继续维持“未见实现”判断,并补记 `specs/003-rev006-reminder-event-design/` 工件基线与后续研发切入建议。 - 同步回写 `03_Task_Checklist.md` 与本进度文档,补充本轮 implement 阶段的治理动作、验证动作与台账一致性说明,避免将文档收口误写为 backend 已实现。 ### 2026-03-24 更新 diff --git a/docs/design/00_Management/03_Task_Checklist.md b/docs/design/00_Management/03_Task_Checklist.md index 00ef94b..51870ff 100644 --- a/docs/design/00_Management/03_Task_Checklist.md +++ b/docs/design/00_Management/03_Task_Checklist.md @@ -196,7 +196,7 @@ ### 📋 REV-004 执行资产落地 - [x] **完成 REV-004 一期执行手册与启动脚本落地** ✅ (2026-03-12) - - [x] 新增 `docs/guides/REV004_ACCOUNTING_EXECUTION_PLAYBOOK.md`,固化范围、最小改动方案、任务拆解与验收清单 ✅ + - [x] 新增 `docs/evidence/rev004-accounting/REV004_ACCOUNTING_EXECUTION_PLAYBOOK.md`,固化范围、最小改动方案、任务拆解与验收清单 ✅ - [x] 新增 `scripts/start-backend-codex-session.sh`,支持 backend worktree + tmux + Codex 启动 ✅ - [x] 在 `scripts/README.md` 登记启动脚本用途 ✅ - [x] 在 `01_Project_Progress.md` 记录本次执行资产落地 ✅ @@ -571,7 +571,7 @@ - [x] 更新 `docs/design/03_Technical_Design/01_Database_Design.md`,明确历史只读保留策略、最小查询字段与处置引用边界 ✅ - [x] 更新 `docs/design/00_Management/15_SYS002_Requirement_Breakdown.md`、`01_Project_Progress.md` 与本任务清单,完成 implement 阶段治理回写 ✅ - [x] **完成 REV-006 implement 阶段治理文档二次对齐** ✅ (2026-03-19) - - [x] 在 `15_SYS002_Requirement_Breakdown.md` 明确 `SYS002-REQ-011` 继续维持“未见实现”,并补记 `specs/006-reminder-event-design/` 工件基线 ✅ + - [x] 在 `15_SYS002_Requirement_Breakdown.md` 明确 `SYS002-REQ-011` 继续维持“未见实现”,并补记 `specs/003-rev006-reminder-event-design/` 工件基线 ✅ - [x] 在 `01_Project_Progress.md` 更正 REV-006 feature 编号与本轮治理回写记录,避免误导为 backend 已实现 ✅ - [x] 在治理任务建议中补充 `make validate-file`、`make check-links`、`make validate-mermaid` 与台账同步动作 ✅ diff --git a/docs/design/00_Management/15_SYS002_Requirement_Breakdown.md b/docs/design/00_Management/15_SYS002_Requirement_Breakdown.md index 08cc9ba..da56e56 100644 --- a/docs/design/00_Management/15_SYS002_Requirement_Breakdown.md +++ b/docs/design/00_Management/15_SYS002_Requirement_Breakdown.md @@ -130,7 +130,7 @@ | `REV-003` 营业收费 | 部分实现 | 建议围绕“柜台班结”“红冲历史查询”等缺口拆小 feature | | `REV-004` 账务处理 | 已实现 | 以规则收口、二期扩展或历史台账映射为主 | | `REV-005` 发票与税务处理 | 已实现 | 以验收归档和细粒度对象补证为主 | -| `REV-006` 催缴与通知 | 未见实现 | 已完成 Speckit `specify -> plan -> tasks` 工件并形成 `specs/006-reminder-event-design/` 基线;当前进入 `implement` 阶段文档收口与台账同步,backend 仍未见明确催缴/通知业务实现骨架。 | +| `REV-006` 催缴与通知 | 未见实现 | 已完成 Speckit `specify -> plan -> tasks` 工件并形成 `specs/003-rev006-reminder-event-design/` 基线;当前进入 `implement` 阶段文档收口与台账同步,backend 仍未见明确催缴/通知业务实现骨架。 | | `REV-007` 统计分析 | 未见实现 | 已完成 Speckit `specify -> plan -> tasks`,当前进入 `implement` 阶段的正式文档收口与治理同步。 | | `REV-008` 代收与银行业务 | 已实现 | 以跨系统口径收口和扩展台账补证为主 | | `REV-009` 业务参数配置 | 已实现 | 以参数边界收口和治理能力补充为主 | @@ -152,7 +152,7 @@ | `REV-003` | 是 | `rev003-redflush-history-query` | 中 | 聚焦红冲历史查询与台账承接 | | `REV-004` | 否 | `rev004-adjustment-followup` | 中 | 仅在补二期或精细对象时使用 | | `REV-005` | 否 | `rev005-detail-reconciliation` | 中 | 仅在补发票细表/批次缺口时使用 | -| `REV-006` | 是 | `rev006-reminder-event-design` | 最高 | 已完成 `spec/plan/research/data-model/contracts/quickstart/tasks` 工件链,当前重点为按 `IF-REV-013` 四态口径推进正式文档 implement 收口并形成后续研发切入点。 | +| `REV-006` | 是 | `rev003-rev006-reminder-event-design` | 最高 | 已完成 `spec/plan/research/data-model/contracts/quickstart/tasks` 工件链,当前重点为按 `IF-REV-013` 四态口径推进正式文档 implement 收口并形成后续研发切入点。 | | `REV-006` | 是 | `rev006-notice-result-writeback` | 高 | 可作为 `REV-006` 拆分子 feature | | `REV-007` | 是 | `rev007-revenue-statistics-design` | 高 | 已启动并完成第一轮设计工件,当前建议继续收口正式文档并形成后续研发切入点 | | `REV-007` | 是 | `rev007-channel-analysis-query` | 中 | 适合作为统计分析子 feature | @@ -233,13 +233,13 @@ - 标题:`SYS-002:补齐催缴事件与通知协同设计` - 对应需求:`SYS002-REQ-011` -- feature:`rev006-reminder-event-design`(治理映射名:`sys002-reminder-event-design`) +- feature:`rev003-rev006-reminder-event-design`(治理映射名:`sys002-reminder-event-design`) - 优先级:`高` - 当前实现状态:`未见实现` - Story 描述: - 目标:补齐欠费催缴对象生成、通知触发、通知结果回写与催缴追踪闭环。 - 事实来源:`12_REV_Detailed.md` 中 REV-006、`03_Interface_Design.md` 中 `IF-EXT-008`。 - - 当前判断:当前代码检索范围内未见明确的催缴、通知、消息协同控制器或服务骨架;但本轮已完成 `specs/006-reminder-event-design/` 工件链,并在正式文档中统一 `IF-REV-013`、四态状态集、历史只读查询口径和停复水联动边界。 + - 当前判断:当前代码检索范围内未见明确的催缴、通知、消息协同控制器或服务骨架;但本轮已完成 `specs/003-rev006-reminder-event-design/` 工件链,并在正式文档中统一 `IF-REV-013`、四态状态集、历史只读查询口径和停复水联动边界。 - 验收要点:明确催缴触发时机、催缴对象筛选条件、通知方式、回写字段、四态状态语义与失败重试机制。 - 推荐 Task: - `T-011-01` 对齐催缴业务场景、触发条件与对象筛选规则 diff --git a/docs/design/01_Overview/03_Summary_Design.md b/docs/design/01_Overview/03_Summary_Design.md index 369c6c4..9f60d4f 100644 --- a/docs/design/01_Overview/03_Summary_Design.md +++ b/docs/design/01_Overview/03_Summary_Design.md @@ -878,6 +878,7 @@ graph TB | IF-REV-004 | 抄表数据提交接口 | 提交人工或远传抄表数据并触发校验 | 手机抄表APP/集抄系统 | HTTPS REST | 抄表任务ID、水表ID、读数、图片证据、GPS位置 | 上传结果、校验状态、异常标记 | | IF-REV-005 | 账单生成接口 | 根据抄表结果、水价模板和费用组成生成账单 | 开账任务/批量任务 | HTTPS REST | 抄表批次、账期、客户范围、应收日期 | 账单结果、失败清单、生成汇总 | | IF-REV-006 | 缴费处理接口 | 创建收费记录并核销账单 | 柜台/线上渠道 | HTTPS REST | 客户ID、账单ID列表、支付方式、实收金额 | 收费结果、核销状态、交易流水 | +| IF-REV-007 | 账务处理接口 | 当前统一承接账务调整、退款/冲正、坏账申请及全量账务对象通用处理申请 | 柜台/管理后台/协同任务 | HTTPS REST | 账单ID、对象类型、处理类型、原因、审批边界、原交易号 | 处理结果、审批状态、账单回写状态、结果对象编号 | | IF-REV-008 | 发票申请接口 | 发起电子发票申请并接收票据状态回写 | 柜台/客户渠道 | HTTPS REST | 客户ID、账单ID列表、开票抬头、税号、邮箱 | 发票申请结果、票据状态、下载地址 | | IF-REV-011 | 银行代收协同接口 | 发起代扣、回盘、对账、结算协同 | 银行代收模块/SYS-009 | HTTPS REST / 文件交换 | 批次号、渠道编码、账期、账单明细 | 批次状态、回盘结果、对账差异、结算结果 | | IF-REV-012 | 业务参数配置接口 | 查询和维护价格模板、优惠方案、业务参数配置 | 管理后台/参数管理端 | HTTPS REST | 参数分类、模板编码、站点范围 | 参数明细、模板信息、更新结果 | @@ -1749,7 +1750,7 @@ graph TD - **客户资料管理**:客户档案建立、信息维护、分组管理 - **抄表开账**:抄表数据录入、复核确认、自动开账 - **营业收费**:柜台收费、移动收费、在线缴费 -- **账务处理**:一期先聚焦水量调整、金额调整、退款、冲正、坏账申请,统一经 `IF-REV-007` 承接,并按共性能力先统一、场景能力再分批推进 +- **账务处理**:当前仍由 `IF-REV-007` 统一承接账务处理入口,统一覆盖账单修正、退款/冲正、坏账申请,并向预存退款、红冲、价差调整、违约金减免、分账调整、退款账、跨周期水量等全量账务对象边界扩展 - **发票管理**:发票开具、查询、重开、作废 - **催缴管理**:欠费统计、催缴通知、停水管理 - **统计分析**:多维度数据统计和报表分析 @@ -1805,6 +1806,7 @@ graph TD | IF-REV-004 | 抄表数据提交接口 | 提交人工或远传抄表数据并触发校验 | 手机抄表APP/集抄系统 | HTTPS REST | 抄表任务ID、水表ID、读数、图片证据、GPS位置 | 上传结果、校验状态、异常标记 | | IF-REV-005 | 账单生成接口 | 根据抄表结果、水价模板和费用组成生成账单 | 开账任务/批量任务 | HTTPS REST | 抄表批次、账期、客户范围、应收日期 | 账单结果、失败清单、生成汇总 | | IF-REV-006 | 缴费处理接口 | 创建收费记录并核销账单 | 柜台/线上渠道 | HTTPS REST | 客户ID、账单ID列表、支付方式、实收金额 | 收费结果、核销状态、交易流水 | +| IF-REV-007 | 账务处理接口 | 当前统一承接账务调整、退款/冲正、坏账申请及全量账务对象通用处理申请 | 柜台/管理后台/协同任务 | HTTPS REST | 账单ID、对象类型、处理类型、原因、审批边界、原交易号 | 处理结果、审批状态、账单回写状态、结果对象编号 | | IF-REV-008 | 发票申请接口 | 发起电子发票申请并接收票据状态回写 | 柜台/客户渠道 | HTTPS REST | 客户ID、账单ID列表、开票抬头、税号、邮箱 | 发票申请结果、票据状态、下载地址 | | IF-REV-011 | 银行代收协同接口 | 发起代扣、回盘、对账、结算协同 | 银行代收模块/SYS-009 | HTTPS REST / 文件交换 | 批次号、渠道编码、账期、账单明细 | 批次状态、回盘结果、对账差异、结算结果 | | IF-REV-012 | 业务参数配置接口 | 查询和维护价格模板、优惠方案、业务参数配置 | 管理后台/参数管理端 | HTTPS REST | 参数分类、模板编码、站点范围 | 参数明细、模板信息、更新结果 | @@ -1975,7 +1977,7 @@ graph TB | REV-001 | 客户资料管理 | 客户档案管理、客户分组、信息变更 | 自行开发 | | REV-002 | 抄表开账 | 抄表录入、复核开账、异常处理 | 自行开发 | | REV-003 | 营业收费 | 柜台收费、移动收费、在线缴费 | 自行开发 | -| REV-004 | 账务处理 | 账务调整、退款处理、坏账管理 | 自行开发 | +| REV-004 | 账务处理 | 统一账务处理、退款/冲正、红冲/价差/分账/坏账及历史账务承接 | 自行开发 | | REV-005 | 发票管理 | 发票开具、查询管理、电子发票 | 自行开发 | | REV-006 | 催缴管理 | 欠费催缴、短信通知、停水管理 | 自行开发 | | REV-007 | 统计分析 | 多维度数据统计和报表分析功能 | 自行开发 | @@ -2334,14 +2336,14 @@ flowchart TD **功能概述:** -  负责处理各类复杂的账务调整、退款、坏账等业务,确保账务的准确性和合规性。 +  负责统一承接营收核心链路中的账务处理能力。当前正式口径仍以 `IF-REV-007` 作为统一入口,承接账单修正、退款/冲正、坏账申请等处理;目标设计边界进一步覆盖预存退款、红冲、已销调整、价差调整、违约金减免、分账调整、退款账结果与跨周期水量等全量账务对象,并保持当前事实与目标设计分层表达。 **核心功能:** -- **未销账调整**: 对未支付账单进行调整。 -- **分账调整**: 将一笔总账单拆分为多笔子账单。 -- **预付款退款**: 处理客户预付款的退还流程。 -- **呆坏账处理**: 对长期无法收回的欠款进行核销。 +- **统一账务处理入口**: 通过 `IF-REV-007` 统一受理账务对象处理申请,返回处理结果、审批边界与账单回写状态。 +- **账务对象承接**: 在概要层承接预存退款、红冲、已销调整、价差调整、违约金减免、分账调整、坏账等对象族语义。 +- **结果与追溯**: 保留退款账结果、跨周期水量、历史账务查询、审批留痕与原单据追溯边界。 +- **分层边界控制**: 当前已落地能力继续保留统一入口事实;专属接口、独立对象实现和 BPM 细节作为后续方向,不在概要层误写成既成事实。 #### REV-005: 发票管理 diff --git a/docs/design/02_Detailed_Design/12_REV_Detailed.md b/docs/design/02_Detailed_Design/12_REV_Detailed.md index 0b120f2..3ca491a 100644 --- a/docs/design/02_Detailed_Design/12_REV_Detailed.md +++ b/docs/design/02_Detailed_Design/12_REV_Detailed.md @@ -294,74 +294,93 @@ flowchart TD ### 功能说明 -REV-004 一期仅覆盖水量调整、金额调整、退款、冲正、坏账申请五类场景,统一挂靠 `IF-REV-007` 作为账务处理入口,目标是在既有正式文档体系内先收敛范围、承接口径、留痕要求与审批边界。 +REV-004 当前正式口径仍以统一账务处理能力为核心,继续由 `IF-REV-007` 承接当前在线处理入口,统一处理账单承接、原交易校验、处理结果表达、操作留痕与审批边界。当前正式实现边界仍以营业账主明细、支付交易校验、操作日志与价格/方案重算支撑为基础,不将尚未落地为独立物理表族的对象误写成已实现事实。 -本阶段按“共性能力先统一、场景能力再分批”组织:先统一账单承接、原交易校验、结果表达、操作留痕与审批边界,再分别展开五类场景。违约金减免、分账调整、价差调整、跨周期水量、预存退款细表等内容仅作为旧系统迁移语义或后续扩展参考,不作为一期新增独立范围。 +在全量目标设计下,REV-004 不再只覆盖一期五类场景,而是统一承接全量账务对象族:`PrepaidRefund`、`RedinkRecord`、`WrittenoffAdjust`、`PriceDiffAdjust`、`LateFeeReduce`、`BadDebtRecord`、`SplitAdjust`、特殊开账 / 特账承接方式、`RefundBill`、`CrossCycleWaterRecord`。其中,特账按特殊开账类型挂接 `Charge` / `ChargeDetail` 主模型承接,`RefundBill` 作为退款处理结果对象保留,`CrossCycleWaterRecord` 作为账单重算和阶梯累计支撑对象保留;IC 卡账务当前仍按历史只读 + 映射层承接,不纳入在线主写范围。 ### 业务流程 ```mermaid flowchart TD - A[发起账务调整申请] --> B[校验账单状态与权限] - B --> C{是否通过} - C -->|否| D[驳回并记录原因] - C -->|是| E[执行重算或退款冲正] - E --> F[更新账单与明细状态] - F --> G[写入操作日志与审批留痕] - G --> H[返回处理结果] + A[提交账务处理或账务对象申请] --> B[校验账单、原交易、权限与来源依据] + B --> C{是否需要审批} + C -->|是| D[进入审批留痕与待审状态] + D --> E{审批是否通过} + E -->|否| F[驳回并记录原因] + E -->|是| G[执行重算、退款、红冲、核销修正或结果生成] + C -->|否| G + G --> H[回写账单、结果对象与关联状态] + H --> I[记录操作日志、审批引用与历史映射] + I --> J[返回处理结果] ``` ### 关键规则 -1. 一期场景严格限定为水量调整、金额调整、退款、冲正、坏账申请,不扩展到其他接口族或独立账务台账重构。 -2. 所有场景均以 `biz_charge` / `biz_charge_detail` 为主承接对象,并通过 `biz_operat_log` / `biz_operat_log_detail` 记录处理依据、前后变化和责任归属。 -3. 退款、冲正必须联动 `bk_transaction`、`bk_transaction_callback`、`bk_transaction_exception` 等原支付流水及渠道状态校验,不允许仅依据账单状态直接处理。 -4. 接口结果统一返回 `resultStatus`、`writeBackStatus`,其中 `resultStatus` 表示处理结论,`writeBackStatus` 表示账单状态回写结论,两者不得混用。 -5. 审批相关内容一期仅保留 `approvalRequired`、`PENDING_APPROVAL` 与审批边界说明,不展开完整 BPM 流程、节点、流转规则或审批回写实现细节。 -6. 对于当前未见明确独立实体表的特账、跨周期水量、退款账等对象,文档以“业务处理场景”表述,不强行落为已实现表。 +1. 当前正式边界仍以 `IF-REV-007` 统一承接在线账务处理入口;目标设计边界扩展为覆盖全量账务对象族,但不把未来专属接口和独立表族误写成当前全部已落地事实。 +2. 所有在线处理场景均以 `biz_charge` / `biz_charge_detail` 为统一账单承接骨架,并通过 `biz_operat_log` / `biz_operat_log_detail` 记录处理依据、前后变化、附件和责任归属;独立业务对象在详设层保留为正式业务语义,不再简单压平为单一“金额调整”子类型。 +3. 退款、红冲、冲正及其他资金回退相关场景,必须联动 `bk_transaction`、`bk_transaction_callback`、`bk_transaction_exception` 等原支付流水和渠道状态校验,不允许仅依据账单状态直接处理。 +4. 接口结果至少统一表达 `resultStatus`、`writeBackStatus`;涉及审批的场景还应明确 `approvalRequired`、`approvalStatus` 等边界,但当前正式文档仍不展开完整 BPM 节点、流转规则和引擎实现细节。 +5. 审批承接按对象分层:`PrepaidRefund`、`BadDebtRecord` 倾向独立审批流对象;`WrittenoffAdjust`、`PriceDiffAdjust`、`LateFeeReduce`、`SplitAdjust`、`RedinkRecord` 当前先保留审批能力位或可升级边界;`RefundBill`、`CrossCycleWaterRecord` 不单独承接审批流。 +6. 特账不是单独的在线主写账务实体,而是特殊开账类型;应通过开账来源类型、费用类型、原因编码和留痕信息挂接在 `Charge` / `ChargeDetail` 主模型中承接。 +7. 旧系统账务对象必须按“统一骨架、独立业务实体、查询投影、历史映射”四类分层承接;实时收费、对账日志等查询类对象不强行回写为在线主写对象,IC 卡账务保持历史只读 + 映射层口径。 +8. 所有账务处理场景都必须保留与原单据、原账单、原交易、审批痕迹和经办留痕的追溯关系,避免迁移后出现对账、审计和责任链断裂。 ### 核心数据 -- `biz_charge`、`biz_charge_detail`:账务调整的核心对象,承接调整前后账单主明细状态。 -- `bk_transaction`、`bk_transaction_callback`、`bk_transaction_exception`:退款、冲正场景的原交易校验与异常追溯对象。 -- 价格调整/优惠相关表:用于重算账单或差额追溯。 -- `biz_operat_log`、`biz_operat_log_detail`:操作与变更留痕,记录字段差异、处理说明、附件依据与责任归属。 +- **当前统一骨架对象**:`biz_charge`、`biz_charge_detail`,承接账务处理前后账单主明细状态和费用结果。 +- **当前交易校验对象**:`bk_transaction`、`bk_transaction_callback`、`bk_transaction_exception`,承接退款、红冲、冲正等资金相关场景的原交易核验与异常追溯。 +- **当前/目标留痕对象**:`biz_operat_log`、`biz_operat_log_detail`,记录字段差异、处理说明、附件依据、责任人和操作时间。 +- **目标正式业务对象**:`PrepaidRefund`、`RedinkRecord`、`WrittenoffAdjust`、`PriceDiffAdjust`、`LateFeeReduce`、`BadDebtRecord`、`SplitAdjust`、`RefundBill`、`CrossCycleWaterRecord`;其中特账按特殊开账类型挂接 `Charge` / `ChargeDetail` 承接。 +- **目标审批引用对象**:`AccountingWorkflowRef`,用于统一承接 `approvalRequired`、`approvalStatus`、旧 `TaskId` / `StepId` / `FlowRemark` 与后续审批引用。 +- **目标历史映射对象**:`AccountingLegacyMapping`,用于保留旧单据标识、旧账单标识、迁移批次、承接方式和历史追溯关系。 ### 主要场景 -| 场景 | 说明 | 控制要点 | -|---|---|---| -| 水量调整 | 更正异常水量 | 需复核原因、附件和原抄表依据 | -| 金额调整 | 更正账单金额 | 需记录依据、差异金额和审批边界 | -| 退款 | 退回客户支付资金或预存款 | 需校验原交易、退款余额与幂等性 | -| 冲正 | 修正误收/误核销记录 | 需关联原交易与账单状态 | -| 坏账申请 | 对长期欠费进行分类处理 | 需结合账龄、客户状态与审批边界 | +| 场景对象 | 场景说明 | 当前正式边界 | 控制要点 | +|---|---|---|---| +| `PrepaidRefund` | 预存退款申请与处理 | 当前仍通过统一账务处理能力承接 | 校验原支付、退款余额、审批边界和退款结果回写 | +| `RedinkRecord` | 红冲 / 冲正记录 | 当前保留统一处理入口与历史查询能力 | 必须关联原交易、原收费记录和红冲原因 | +| `WrittenoffAdjust` | 已收费后修正 | 当前按统一调账场景承接 | 保留原账单、调整原因和前后差异 | +| `PriceDiffAdjust` | 调价差额重算 | 当前以重算与差额修正场景表达 | 保留原价格口径、新价格口径和生效时间 | +| `LateFeeReduce` | 违约金减免 | 当前以滞纳金修正场景表达 | 支持减免原因、减免金额和审批边界 | +| `BadDebtRecord` | 呆坏账申请与生效 | 当前为统一账务处理中的独立场景 | 保留账龄、客户状态、审批结果和核销状态 | +| `SplitAdjust` | 分账调整 | 当前作为费用组成重分摊场景表达 | 支持按水量 / 按费用组成等分摊策略 | +| 特殊开账 / 特账 | 特殊开账形成的收费结果 | 当前挂接开账主模型,不单列独立表族 | 保留特殊来源类型、费用类型、原因编码与留痕 | +| `RefundBill` | 退款处理结果对象 | 当前不单独作为在线提交入口 | 关联退款申请、支付退款结果与账单状态 | +| `CrossCycleWaterRecord` | 跨周期水量支撑对象 | 当前作为重算和阶梯累计支撑语义 | 保留跨期水量、累计逻辑和关联场景来源 | ### 迁移补充(旧系统承接) -| 旧账务对象 | 当前承接方式 | 迁移口径 | -|---|---|---| -| 预存退款 / 预存退款详情 | 作为账务处理场景承接 | 保留申请单、原支付引用、退款结果与审批留痕 | -| 已销调整汇总 / 明细 | 作为已收费后修正场景承接 | 保留原账单、调整原因、前后差异、处理结果 | -| 价差调整汇总 / 明细 | 作为重算与差额修正场景承接 | 保留原价格口径、新价格口径、差额和生效时间 | -| 分账调整汇总 / 明细 | 作为费用组成重分摊场景承接 | 保留原分摊结果、调整后结果、责任人和审批链 | -| 账单-违约金减免 | 作为滞纳金修正场景承接 | 保留减免原因、减免金额、审批结果和生效时间 | -| 账单-呆坏账 | 作为坏账申请与生效场景承接 | 保留账龄、申请原因、审批结果、核销状态 | +| 旧账务对象 | 目标分层 | 当前承接方式 | 迁移口径 | +|---|---|---|---| +| 预存退款 / 预存退款详情 | `L2` 独立业务层 | 在线主模型 + 独立业务语义 | 保留申请单、原支付引用、退款结果、审批留痕 | +| 已销调整汇总 / 明细 | `L2` 独立业务层 | 在线主模型 + 场景承接 | 保留原账单、调整原因、前后差异、处理结果 | +| 价差调整汇总 / 明细 | `L2` 独立业务层 | 在线主模型 + 重算差额场景 | 保留原价格口径、新价格口径、差额和生效时间 | +| 分账调整汇总 / 明细 | `L2` 独立业务层 | 在线主模型 + 费用重分摊场景 | 保留原分摊结果、调整后结果、策略类型和责任链 | +| 账单-违约金减免 | `L2` 独立业务层 | 在线主模型 + 减免场景 | 保留减免原因、减免金额、审批结果和生效时间 | +| 账单-呆坏账 | `L2` 独立业务层 | 在线主模型 + 坏账申请场景 | 保留账龄、申请原因、审批结果、核销状态 | +| 特账 / 特殊开账 | `L2` 独立业务层(挂主开账模型) | 开账主模型扩展承接 | 保留特殊来源、费用类型、原因编码和关联账单 | +| 退款账 | `L2` 独立业务层(结果对象) | 退款结果对象承接 | 保留退款申请、退款结果、账单/支付关联 | +| 跨周期水量 | `L2` 基础支撑对象 | 重算与阶梯累计支撑对象 | 保留跨期水量、账单重算来源和累计口径 | +| 实时收费汇总 / 日志 / 明细、对账日志 | `L3` 查询投影层 | `projection-only` | 保留历史查询、报表和对账出口,不强接在线主写 | +| IC 卡账务表族 | `L4` 历史映射层 | `history-readonly + mapping-only` | 保留历史只读查询、旧主键映射和迁移追溯 | -1. P0 阶段不要求为每一类旧账务台账都新增独立实体表,但必须在业务对象和历史查询层形成可追溯闭环。 +1. 正式详设层不要求把每一类旧账务对象都立即落为已实现独立物理表,但必须先明确其在目标模型中的层级、角色和承接方式。 2. 旧系统精细台账迁移后至少保留:原单据标识、原账单标识、处理类型、处理原因、处理前后金额/水量、申请/审批/生效时间、经办人与附件依据。 3. 与支付、发票、渠道回调强关联的处理场景,必须保留与原交易、原发票、原收费记录的关联关系,避免后续对账和审计断链。 ### 接口映射 -- `IF-REV-007`:账务调整、退款、冲正、坏账等处理入口。 -- `IF-REV-006`:与收费核销状态联动,确保调账后账单状态一致。 +- `IF-REV-007`:当前正式统一账务处理入口,继续承接调账、退款、冲正、坏账等在线处理场景。 +- `IF-REV-006`:与收费核销状态联动,确保调账后账单状态、核销状态和结果回写一致。 +- 查询类对象后续可按“业务对象查询接口”和“历史只读 / 投影查询接口”分层拆分,但当前正式文档暂不新增专属接口编号。 +- 特殊开账 / 特账继续挂接 `IF-REV-005` 与开账主模型边界承接,不在本节单独定义新的在线处理入口。 ### 落地边界 -- **已落地**:营业账主明细、操作日志、价格/方案相关重算支撑。 -- **部分落地**:精细化账务对象更多表现为流程与场景,并未在 backend 中全部体现为独立表族。 -- **文档先行**:特账、退款账、跨周期水量等对象保留业务语义,不宣称为已实现独立表。 +- **已落地**:营业账主明细、支付交易校验、操作日志、价格/方案相关重算支撑,已构成当前统一账务处理骨架。 +- **部分落地**:精细化账务对象目前更多表现为处理场景、查询口径和留痕规则,尚未在 backend 中全部体现为独立表族或专属接口。 +- **目标设计**:后续将按正式业务对象、审批引用、历史映射和查询投影逐步回写数据库设计、接口设计和总体设计;IC 卡账务继续固定为历史只读 + 映射层,不纳入在线主写范围。 diff --git a/docs/design/03_Technical_Design/01_Database_Design.md b/docs/design/03_Technical_Design/01_Database_Design.md index 84ff12a..683f4ad 100644 --- a/docs/design/03_Technical_Design/01_Database_Design.md +++ b/docs/design/03_Technical_Design/01_Database_Design.md @@ -1078,14 +1078,18 @@ retrieval_priority: P0 | 字段名 | 说明 | | :--- | :--- | | `id` | 主键 | -| `code` | 账单编号 | +| `code` | 账单编号 / 账务主单编号 | | `cust_id` | 客户 ID | | `record_id` | 抄表记录或开账来源 ID | | `bill_period` | 账单期间 | | `total_amount` | 账单总金额 | -| `charge_status` | 收费状态 | +| `charge_status` | 收费状态 / 账务处理结果状态关注字段 | | `due_date` | 应缴日期 | +> 当前真实表事实:`biz_charge` 仍是当前 backend 已落地的营业账主表。 +> +> `RWB-02` 目标承接口径:除继续承接 REV-002 开账结果外,`biz_charge` 同时作为 REV-004 全量账务领域的统一骨架主对象,负责承接账单主状态、账务处理主结果、来源单据引用、账单结果回写和查询主入口;对尚未独立落表的目标业务对象,本节仅定义“承接边界 / 待补字段组 / 历史映射要求”,不误写为已存在独立物理表。 + ### biz_charge_detail (营业账明细表) | 字段名 | 说明 | | :--- | :--- | @@ -1096,6 +1100,10 @@ retrieval_priority: P0 | `unit_price` | 单价 | | `detail_amount` | 明细金额 | +> 当前真实表事实:`biz_charge_detail` 仍是当前 backend 已落地的营业账明细表。 +> +> `RWB-02` 目标承接口径:`biz_charge_detail` 除继续承接账单费用明细外,还应承接价差调整、违约金减免、分账调整、特殊开账 / 特账等费用差异结果的明细表达;当前数据库专项只冻结“由明细层承接差异结果”的方向,不在本轮直接展开独立实体表 DDL。 + #### REV-002 账单生成承接口径 | 对象 | 正式口径 | 承接说明 | @@ -1112,8 +1120,23 @@ retrieval_priority: P0 > 当前 backend 证据:`ChargeServiceImpl.generateSingleChargeWithCache` 成功路径已执行 `chargeMapper.insert(charge)`、`chargeDetailService.insertChargeDetail(detail)` 与 `updateReadingDataCheckState(readingDataId, 1)`,说明现有实现已能把按 `readingDataIds` 复核/开账的结果落入 `biz_charge`、`biz_charge_detail`。 > > 当前承接缺口:接口层返回仍为成功条数字符串,失败阻断主要依赖日志与布尔值,且仅支持 `ACTUAL_USAGE` 结算方式;`biz_charge` / `biz_charge_detail` 的主明细结果、失败对象范围和结构化原因尚未提升为正式 `IF-REV-005` 契约返回。 -> -> REV-004 承接口径:水量调整、金额调整、退款、冲正、坏账申请统一以 `biz_charge`、`biz_charge_detail` 作为账单主明细承接对象;当前数据库主文档不新增独立账务细表来承接一期场景。 + +#### REV-004 全量账务数据库承接口径 + +| 目标对象 | 当前数据库口径 | 目标承接方式 | 当前写法约束 | +| :--- | :--- | :--- | :--- | +| `PrepaidRefund` | 当前作为统一账务处理场景 | `biz_charge` / `biz_charge_detail` + 留痕 + 目标结果对象 | 当前不宣称已存在独立退款主表 | +| `RedinkRecord` | 当前以账务处理场景 + 历史查询表达 | 账单结果 + 原交易校验 + 历史只读查询 | 当前不宣称已落地独立红冲表族 | +| `WrittenoffAdjust` | 当前作为已收费后修正场景 | 统一骨架 + 差异结果 + 留痕 | 当前不下沉独立 DDL | +| `PriceDiffAdjust` | 当前作为重算差额场景 | 统一骨架 + 价格规则来源 + 明细差异表达 | 当前先冻结承接方向 | +| `LateFeeReduce` | 当前作为滞纳金修正场景 | 统一骨架 + 费用组成差异 + 审批留痕 | 当前先写待补字段关注点 | +| `BadDebtRecord` | 当前作为坏账申请场景 | 统一骨架 + 审批引用 + 历史追溯 | 当前不误写为已存在坏账主表 | +| `SplitAdjust` | 当前作为费用重分摊场景 | 统一骨架 + 明细差异 + 策略类型字段组 | 当前只冻结设计方向 | +| 特殊开账 / 特账 | 当前由开账同模型承接 | `biz_charge` / `biz_charge_detail` 同模型承接 | 不新增平行“特账表” | +| `RefundBill` | 当前作为退款结果语义 | 退款结果对象 + 历史映射 / 查询出口 | 当前不作为独立提交表宣称已落地 | +| `CrossCycleWaterRecord` | 当前作为重算支撑语义 | 账单重算基础数据对象 + 查询支撑 | 当前不写成强流程主表 | +| `AccountingWorkflowRef` | 当前数据库主文档未单独命名 | 目标审批引用对象 | 当前仅建立数据库承接边界和待补字段关注点 | +| `AccountingLegacyMapping` | 当前数据库主文档未单独命名 | 目标历史映射对象 | 当前仅建立历史映射承接边界和待补字段关注点 | ### biz_collection / biz_withholding (托收与代扣主表) | 表名 | 关键字段 | 说明 | @@ -1121,17 +1144,18 @@ retrieval_priority: P0 | `biz_collection` | `code`, `cust_id`, `charge_id`, `collection_status` | 托收主表 | | `biz_withholding` | `code`, `cust_id`, `charge_id`, `withholding_status` | 代扣主表 | -### biz_invoice / biz_invoice_taxrate (发票主表与税率表) +### biz_invoice / biz_invoice_record / biz_invoice_taxrate(开票配置表 / 发票记录表 / 税率表) | 表名 | 关键字段 | 说明 | | :--- | :--- | :--- | -| `biz_invoice` | `code`, `cust_id`, `charge_id`, `invoice_status`, `invoice_amount` | 发票主表,统一承接申请单号、账单关联、受理号、开票结果与电子票地址等核心状态 | +| `biz_invoice` | `supplier`, `limit`, `auto_invoice`, `invoice_type`, `status` | 开票配置表(供应商、限额、自动开票开关)| +| `biz_invoice_record` | `application_no`, `cust_id`, `invoice_status`, `invoice_amount` | 发票申请/记录主表,统一承接申请单号、账单关联、受理号、开票结果与电子票地址等核心状态 | | `biz_invoice_taxrate` | `tax_code`, `tax_name`, `tax_rate`, `status` | 税率基础配置 | #### REV-005 发票承接口径 | 对象 | 已有字段 | 待补字段 | 仅快照/历史只读字段 | | :--- | :--- | :--- | :--- | -| `biz_invoice` 发票申请/结果主对象 | `code`、`cust_id`、`charge_id`、`invoice_status`、`invoice_amount` | `application_no`、`sys_request_no`、`invoice_type`、`invoice_title`、`tax_no`、`email`、`mobile`、`source_channel`、`fail_reason`、`invoice_code`、`invoice_number`、`file_url`、`last_try_time`、`next_try_time`、`try_count`、`push_status`、`charge_ids_snapshot`、`charge_bind_status`、作废原因/备注、红冲原因/备注、原票/红票关联标识、作废/红冲申请来源、补偿查询/结果回写上下文 | 旧开票批次号、旧配置版本号、旧平台扩展回执 | +| `biz_invoice_record` 发票申请/结果主对象 | `code`、`cust_id`、`charge_id`、`invoice_status`、`invoice_amount` | `application_no`、`sys_request_no`、`invoice_type`、`invoice_title`、`tax_no`、`email`、`mobile`、`source_channel`、`fail_reason`、`invoice_code`、`invoice_number`、`file_url`、`last_try_time`、`next_try_time`、`try_count`、`push_status`、`charge_ids_snapshot`、`charge_bind_status`、作废原因/备注、红冲原因/备注、原票/红票关联标识、作废/红冲申请来源、补偿查询/结果回写上下文 | 旧开票批次号、旧配置版本号、旧平台扩展回执 | | `biz_cust_invoice` 客户开票信息 | `cust_id`、`invoice_title`、`tax_no`、`email`、`mobile` | 企业/个人抬头类型、默认推送方式等扩展属性按后续实现补齐 | 旧抬头版本、历史修改快照 | | `biz_invoice_taxrate` 税率配置 | `tax_code`、`tax_name`、`tax_rate`、`status` | 税率生效区间、适用票种范围等扩展控制字段 | 旧税率版本快照 | | 账单-发票关系快照 | 当前主模型通过 `biz_invoice` 与 `biz_charge*` 关联承接 | `charge_ids_snapshot`、账单集合来源、客户侧身份匹配结果、操作留痕标识 | 旧营业账开票关系表、旧发票明细表 | @@ -1142,9 +1166,11 @@ retrieval_priority: P0 | `biz_operat_log` | `biz_type`, `biz_id`, `operate_user`, `operate_time` | 业务操作主日志 | | `biz_operat_log_detail` | `log_id`, `field_name`, `before_value`, `after_value` | 字段级变更留痕 | -> REV-004 留痕口径:`biz_operat_log*` 统一承接账务处理的一期留痕,至少覆盖处理类型、目标账单、原交易引用、处理前后差异、原因说明、附件依据与操作人。 +> REV-004 留痕口径:`biz_operat_log*` 继续作为当前正式留痕主入口,但承接范围从“一期账务处理留痕”扩展为“全量账务操作留痕 + 审批痕迹 + 原单据关联 + 历史追溯”。 > -> 边界说明:旧数据字典中的“跨周期水量、特账、红冲、已销调整、呆坏账、实时收费日志”等对象,在当前 backend 范围内未全部识别到独立实体表,数据库专项中统一按业务处理场景描述,不误写为已明确落地的真实表。 +> 数据库关注点:至少覆盖处理类型、目标账单、原交易引用、处理前后差异、原因说明、附件依据、审批状态、审批引用、操作人和操作时间。 +> +> 边界说明:旧数据字典中的“跨周期水量、特账、红冲、已销调整、呆坏账、实时收费日志”等对象,在当前 backend 范围内未全部识别到独立实体表;数据库专项中统一按“在线骨架承接 / 历史只读保留 / 映射对象追溯”三层口径描述,不误写为已明确落地的真实表。 ### 旧系统历史台账迁移与只读查询口径 @@ -1153,22 +1179,32 @@ retrieval_priority: P0 | 旧对象/旧菜单 | 当前主口径 | 承接方式 | 数据策略 | | :--- | :--- | :--- | :--- | | 开账记录、特殊开账 | `biz_charge`、`biz_charge_detail`、`biz_operat_log*` | 统一纳入营业账主表与明细表,特殊开账按来源类型、业务类型、依据说明留痕,不单设平行“特殊开账表” | 在线保留 | +| 预存退款、已销调整、价差调整、分账调整、违约金减免、呆坏账新发生业务 | `biz_charge*` + 留痕骨架 + 目标对象语义 | 新发生业务优先走统一骨架承接,数据库文档保留目标对象命名和待补字段组,但不误写为已全部落地物理表 | 在线保留 | | 柜台收费、实时收费、代收代扣 | `biz_collection`、`biz_withholding`、`bk_transaction*`、`bk_withholding_*` | 统一纳入收费主模型与渠道交易模型,柜台班结/实时收费日志按交易结果和操作留痕归并 | 在线保留 | -| 发票申请、开票结果、票据税率 | `biz_invoice`、`biz_invoice_taxrate`、`biz_cust_invoice` | 统一纳入发票主表、税率表和客户开票信息,不为旧“营业账开票表”机械复制新在线表 | 在线保留 | +| 发票申请、开票结果、票据税率 | `biz_invoice_record`(业务记录)、`biz_invoice`(开票配置)、`biz_invoice_taxrate`、`biz_cust_invoice` | 统一纳入发票主表、税率表和客户开票信息,不为旧“营业账开票表”机械复制新在线表 | 在线保留 | | 微网厅业务字段、页面配置、微信参数 | `biz_business_types`、`biz_business_datas`、`biz_page_settings*`、`biz_parameter_settings`、`sys_wechat_app_settings` | 统一归并为业务类型、页面配置和渠道参数模型 | 在线保留 | | 办理附件、电子档案 | `biz_content`、`biz_content_attach` | 当前新增与迁移后新增资料统一按资料主表与附件表承接 | 在线保留 | -#### 历史只读保留范围 +#### 查询投影 / 历史映射保留范围 | 历史对象 | 当前正式口径 | 保留策略 | 查询要求 | | :--- | :--- | :--- | :--- | -| 红冲记录、红冲原因、红冲前后账务快照 | 账单状态 + 账务处理场景 + 操作留痕 | 保留历史只读,不强制拆为新主库独立实体表 | 至少支持原单号、红冲单号、金额、原因、经办人、时间查询 | -| 预存退款、已销调整、价差调整、分账调整、违约金减免、呆坏账明细 | `REV-004` 账务处理业务场景 | 旧细粒度台账以历史只读方式保留;新发生业务由流程与日志承接 | 至少支持汇总、明细、状态、审批结果和关联账单查询 | +| 红冲记录、红冲原因、红冲前后账务快照 | 账单状态 + 账务处理场景 + 操作留痕 | 保留历史只读,不强制拆为新主库独立实体表;后续可作为 `RedinkRecord` 查询投影出口 | 至少支持原单号、红冲单号、金额、原因、经办人、时间查询 | +| 预存退款、已销调整、价差调整、分账调整、违约金减免、呆坏账明细 | `REV-004` 账务处理业务场景 | 旧细粒度台账以历史只读方式保留;新发生业务由统一骨架、目标对象语义和留痕承接 | 至少支持汇总、明细、状态、审批结果和关联账单查询 | +| 退款账结果、跨周期水量、疑难重笔账 | 结果对象 / 基础支撑对象 / 历史问题单据 | 保留为查询投影或历史只读出口,不强行落为在线主写对象 | 至少支持结果状态、来源单据、时间、关联账单查询 | | 柜台结账、打印记录、补打记录 | 收费结果 + 打印/操作留痕 | 旧查询菜单作为历史只读能力保留,不单独建设新结账台账表 | 至少支持班次、营业所、柜员、打印类型、结账状态查询 | | 发票明细、营业账开票关系、开票配置快照 | 发票主模型 + 历史关系快照 | 旧细表和配置快照按历史只读保留;新在线模型只保留开票必需主数据 | 至少支持发票号、账单号、开票批次、配置版本和结果状态查询 | | 催缴记录、停水记录、预存短信记录 | 催缴/停复水/消息联动业务场景 | 旧记录菜单按历史只读保留,与 `IF-REV-013` 的任务结果、通知链路和工单处置引用分层承接,不新增同名在线主表 | 至少支持客户、账期、催缴方式、执行结果、发送对象、发送时间、关联账单、处置引用查询 | +| IC 卡账务表族 | 当前冻结为历史只读 + 映射层 | 保留 `history-readonly + mapping-only`,不进入在线主写数据库口径 | 至少支持卡号、客户、金额、时间、旧单据标识查询 | | 水表检定、领用、出库、退库、报废单据 | `METER-003` 生命周期场景 | 当前在线主表承接水表状态,旧单据与检定证书按历史只读保留 | 至少支持表号、仓库、单据类型、检定结论、证书编号查询 | +#### 目标引用对象与待补字段关注点 + +| 目标对象 | 当前数据库状态 | 待补字段关注点 | 说明 | +| :--- | :--- | :--- | :--- | +| `AccountingWorkflowRef` | 当前主文档未单列真实表 | `accounting_case_id`、`workflow_type`、`approval_required`、`approval_status`、`legacy_task_id`、`legacy_step_id`、`legacy_flow_remark` | 当前只建立数据库专题锚点,不宣称已存在真实表 | +| `AccountingLegacyMapping` | 当前主文档未单列真实表 | `legacy_object_type`、`legacy_object_id`、`new_object_type`、`new_object_id`、`mapping_mode`、`migration_batch_no`、`trace_status` | 当前只建立历史映射承接边界,不宣称已存在真实表 | + #### 迁移验收最低对账口径 | 对账主题 | 最低核对维度 | 主口径来源 | 验收要求 | @@ -1177,13 +1213,14 @@ retrieval_priority: P0 | 缴费记录 | 收费笔数、实收金额、渠道、核销状态 | `biz_collection`、`bk_transaction*` | 支持按渠道、日期、营业所汇总比对 | | 发票记录 | 开票笔数、金额、状态、票据类型 | `biz_invoice*` + 历史开票关系 | 支持按发票状态、开票日期比对 | | 红冲与账务调整 | 调整笔数、调整金额、处理结果 | 账务处理结果 + 历史台账 | 支持汇总与单据级差异定位 | +| 退款与坏账结果 | 结果笔数、结果金额、审批状态、关联账单 | 统一骨架结果 + 历史只读台账 | 支持按对象类型、状态、账期、时间定位 | | 催缴与停复水 | 通知笔数、执行结果、停复水状态 | `IF-REV-013` 任务结果 + 历史记录 | 支持按账期、客户、执行状态、处置引用比对 | | 电子档案 | 附件数、附件类型、关联业务单数 | `biz_content_attach` + 历史档案目录 | 支持按业务类型、上传时间、来源系统比对 | #### 设计约束 - 不以“旧菜单一项对应一张新表”为原则,优先复用当前已确认的 `biz_*`、`bk_*` 在线主模型。 -- 对 backend 当前未识别到独立实体表的旧细粒度台账,仅写为“历史只读查询对象”,不误写为“已存在新在线表”。 +- 对 backend 当前未识别到独立实体表的旧细粒度台账,仅写为“历史只读查询对象”或“目标对象 / 待补字段关注点”,不误写为“已存在新在线表”。 - 历史只读对象必须保留原系统关键标识(原单号、原客户号、原批次号或原附件标识)以支撑迁移验收与问题追溯。 - 涉及历史附件、影像、高拍仪资料时,正式数据库设计只约束“资料元数据 + 文件引用”口径,不在本轮臆造新的文件表族。 - `REV-006` 的正式结果状态按 `PENDING`、`SUCCESS`、`FAIL`、`MANUAL_VERIFIED` 四态统一,数据库设计仅约束查询与追溯口径,不反推为已存在独立催缴结果主表。 @@ -1536,7 +1573,7 @@ retrieval_priority: P0 | start_time | timestamp(6) | Y | | 开始时间 | | end_time | timestamp(6) | Y | | 结束时间 | | work_duration | int4 | Y | 0 | 工作时长(分钟) | -| work_status | int2 | N | 0 | 工单状态:0-待处理,1-处理中,2-已完成 | +| work_status | int2 | N | 0 | 工单状态:0-未处理(工单创建,待审核/待处理),1-已审核(审核通过/无需审批,待完成),2-已完成(处理成功且已回写完成),3-已撤销(工单已撤销) | | work_result | varchar(500) | Y | | 工作结果 | | completion_photos | text | Y | | 完成照片 | | customer_signature | varchar(500) | Y | | 客户签名 | @@ -1991,6 +2028,16 @@ CREATE INDEX idx_bk_withholding_batch_date ON bk_withholding_batch(batch_date, b CREATE INDEX idx_bk_reconcile_batch_bill_date ON bk_reconcile_batch(bill_date, reconcile_status); ``` +> `RWB-02` 索引关注点:在保持上述现有真实索引口径不变的前提下,后续应重点关注以下账务查询路径: +> +> - 账务主单 / 账单结果查询:`cust_id + bill_period`、`charge_status + due_date`、`code + tenant_id` +> - 账务明细差异查询:`charge_id + cost_component_code`,必要时补“差异类型 / 结果类型”类字段索引 +> - 原单据 / 原交易追溯:`biz_order_no`、`trade_no`、原单号 / 原申请单号 / 原结果单号 +> - 审批引用查询:后续若引入 `AccountingWorkflowRef`,应优先关注 `accounting_case_id`、`approval_status`、`workflow_type` +> - 历史映射查询:后续若引入 `AccountingLegacyMapping`,应优先关注 `legacy_object_type + legacy_object_id`、`new_object_type + new_object_id`、`migration_batch_no` +> +> 当前数据库文档仅冻结索引关注点,不在本轮直接新增未落地表的 SQL 索引语句。 + ## 分区表设计 ### 日志表分区策略 @@ -2020,6 +2067,12 @@ CREATE TABLE biz_price_adjustment_history_y2024 PARTITION OF biz_price_adjustmen FOR VALUES FROM ('2024-01-01') TO ('2025-01-01'); ``` +> `RWB-02` 历史数据关注点:对 REV-004 全量账务领域,后续应把“历史只读台账、查询投影、映射关系”与“在线主写骨架”分开管理。 +> +> - 历史只读对象:红冲记录、旧退款账、旧分账调整、旧价差调整、IC 卡账务等按历史查询保留,不并入在线主写分区策略 +> - 查询投影对象:实时收费、对账日志、结果投影可按时间或账期做轻量分区/归档优化 +> - 映射对象:若后续引入 `AccountingLegacyMapping`,优先按迁移批次号和时间做归档/检索设计 + ## 查询优化建议 ### 多租户查询优化 @@ -2058,6 +2111,12 @@ SELECT * FROM dept_tree; - **归档周期**: 每月执行一次归档作业 - **存储方式**: 使用列式存储优化查询性能 +### REV-004 历史账务归档补充 +- **在线骨架对象**:`biz_charge`、`biz_charge_detail`、`biz_operat_log*` 保留当前在线口径,优先服务当前账务处理、审计与查询。 +- **历史只读对象**:旧红冲、旧退款账、旧价差调整、旧分账调整、IC 卡账务等优先走历史只读归档,不反向要求在线主表一比一复刻。 +- **查询投影对象**:实时收费、对账日志、账务结果投影可按账期或时间做归档分层,确保老数据查询不拖累在线主写。 +- **映射对象**:后续若落地 `AccountingLegacyMapping`,应按迁移批次、对象类型、时间维度设计归档与抽检策略。 + ### 历史数据处理 ```sql -- 创建归档表 diff --git a/docs/design/03_Technical_Design/03_Interface_Design.md b/docs/design/03_Technical_Design/03_Interface_Design.md index 45d9790..9f8eeba 100644 --- a/docs/design/03_Technical_Design/03_Interface_Design.md +++ b/docs/design/03_Technical_Design/03_Interface_Design.md @@ -442,14 +442,16 @@ retrieval_priority: P0 | 归属模块 | REV-004 | | 请求方式 | POST | | 请求路径 | `/admin-api/revenue/accounting/adjust` | -| 功能描述 | 发起水量调整、金额调整、退款、冲正、坏账申请五类账务处理,并统一返回处理结果、审批边界与账单回写状态 | +| 功能描述 | 当前继续作为 REV-004 统一账务处理入口,统一承接账单修正、退款/冲正、坏账申请以及全量账务对象的通用处理申请,并返回处理结果、审批边界与账单回写状态 | | 核心表 | `biz_charge`、`biz_charge_detail`、`biz_operat_log`、`bk_transaction*` | 边界约束: -- 一期仅覆盖 `USAGE`、`AMOUNT`、`REFUND`、`REVERSE`、`BAD_DEBT` 五类 `adjustType`。 -- 退款、冲正必须提供 `sourceTradeNo` 并完成原交易校验;其他场景不得误用支付流水替代业务依据。 -- 审批相关内容仅保留 `approvalRequired`、`PENDING_APPROVAL` 与边界说明,不展开 BPM 节点与审批回写实现细节。 -- `resultStatus` 与 `writeBackStatus` 必须分离表达,前者表示处理结论,后者表示账单状态回写结论。 +- 当前正式事实仍以 `IF-REV-007` 为统一入口,不直接新增一整套新的正式专属接口编号族。 +- 当前统一入口需能够覆盖 `PrepaidRefund`、`RedinkRecord`、`WrittenoffAdjust`、`PriceDiffAdjust`、`LateFeeReduce`、`BadDebtRecord`、`SplitAdjust`、特殊开账 / 特账、`RefundBill`、`CrossCycleWaterRecord` 的统一提交或统一受理边界;其中结果对象和基础支撑对象可仅保留受理/查询语义。 +- 退款、红冲、冲正等资金回退相关场景必须提供 `sourceTradeNo` 并完成原交易校验;其他场景不得误用支付流水替代业务依据。 +- 审批相关内容当前仍仅保留 `approvalRequired`、`approvalStatus` 与边界说明,不展开 BPM 节点、审批回写 API 与流程引擎实现细节。 +- `resultStatus` 与 `writeBackStatus` 必须分离表达,前者表示处理结论,后者表示账单状态回写结论;后续若拆专属接口,也不得破坏该双状态语义。 +- 专属接口方向当前只允许写成“后续建议拆分方向”,不得误写为当前 backend 已完整落地能力。 ### IF-REV-008 发票申请接口 @@ -833,12 +835,15 @@ retrieval_priority: P0 | 字段 | 类型 | 必填 | 说明 | 主要来源/去向 | |------|------|------|------|---------------| | chargeId | Long | 是 | 目标账单 ID | `biz_charge.id` | -| adjustType | String | 是 | 调整类型:`USAGE`、`AMOUNT`、`REFUND`、`REVERSE`、`BAD_DEBT` | 业务类型 | +| objectType | String | 是 | 账务对象类型:`PREPAID_REFUND`、`REDINK_RECORD`、`WRITTENOFF_ADJUST`、`PRICE_DIFF_ADJUST`、`LATE_FEE_REDUCE`、`BAD_DEBT_RECORD`、`SPLIT_ADJUST`、`SPECIAL_BILLING`、`REFUND_BILL`、`CROSS_CYCLE_WATER` | 统一对象语义 | +| adjustType | String | 否 | 当前统一入口处理类型:`USAGE`、`AMOUNT`、`REFUND`、`REVERSE`、`BAD_DEBT` 等 | 业务类型 / 兼容字段 | | adjustAmount | Decimal | 否 | 调整金额 | `biz_charge_detail` / 业务计算 | | adjustUsage | Decimal | 否 | 调整水量 | 业务计算 | -| sourceTradeNo | String | 否 | 原交易流水号,退款/冲正场景使用 | `bk_transaction.trade_no` | +| sourceTradeNo | String | 否 | 原交易流水号,退款/红冲/冲正场景使用 | `bk_transaction.trade_no` | +| relatedBizNo | String | 否 | 原业务单号/结果单号/关联单号 | 历史追溯 / 业务流水 | | reasonCode | String | 是 | 调整原因编码 | 业务字典 | -| remark | String | 否 | 调整说明 | `biz_operat_log.remark` | +| approvalRequired | Boolean | 否 | 是否触发审批能力位 | 审批边界判断 | +| remark | String | 否 | 处理说明 | `biz_operat_log.remark` | | attachmentList | Array | 否 | 依据附件 | 附件系统 | | operatorId | Long | 是 | 操作人 ID | 操作上下文 | @@ -846,13 +851,22 @@ retrieval_priority: P0 | 字段 | 类型 | 说明 | 主要来源 | |------|------|------|----------| -| adjustmentNo | String | 调整业务编号 | 业务流水 | +| adjustmentNo | String | 调整业务编号 / 统一处理流水号 | 业务流水 | | chargeId | Long | 目标账单 ID | `biz_charge.id` | -| resultStatus | String | 处理状态:`SUCCESS`、`PENDING_APPROVAL`、`FAIL` | 业务状态 | +| objectType | String | 实际承接的账务对象类型 | 业务状态 | +| resultStatus | String | 处理状态:`SUCCESS`、`PENDING_APPROVAL`、`FAIL`、`PARTIAL_SUCCESS` 等 | 业务状态 | | writeBackStatus | String | 账单回写状态 | 业务状态 | | approvalRequired | Boolean | 是否进入审批 | 流程判断 | +| approvalStatus | String | 审批状态:`PENDING_APPROVAL`、`APPROVED`、`REJECTED` 等 | 审批边界 | +| resultObjectNo | String | 结果对象编号/结果单号 | 业务流水 / 结果对象 | | msg | String | 处理说明 | 返回消息 | +> 参数口径补充: +> +> - `objectType` 用于统一表达全量账务对象语义;当前若 backend 尚未完整开放所有对象类型,可按“已开放对象 + 后续扩展对象”分批实现,但正式接口文档已固定该统一表达方向。 +> - `adjustType` 当前保留作为统一入口兼容字段,后续若拆专属接口,可逐步从“处理类型”过渡到“对象类型 + 结果语义”表达。 +> - `approvalRequired`、`approvalStatus` 仅用于承接审批能力位和审批状态边界,不代表当前已落地完整 BPM API。 + ### IF-REV-008 发票申请接口 #### 请求参数 @@ -1543,6 +1557,7 @@ sequenceDiagram | 客户与账户 | `biz_cust`、`biz_account`、`biz_cust_contact` | 用于客户查询、账户绑定、资料维护 | | 客户扩展关系 | `biz_cust_meter`、`biz_cust_invoice`、`biz_cust_app_binds`、`biz_cust_collection_rel`、`biz_cust_withholding_rel` | 用于客户关联对象查询与服务协同 | | 抄表与开账 | `biz_meter_book`、`biz_meter_read`、`biz_reading_data`、`biz_last_reading`、`biz_charge`、`biz_charge_detail` | 用于抄表任务、账单生成、费用明细查询 | +| 账务处理与结果对象 | `biz_charge`、`biz_charge_detail`、`biz_operat_log`、`bk_transaction*`、目标对象 `AccountingWorkflowRef`、`AccountingLegacyMapping` | 用于 REV-004 统一处理入口、审批边界、结果对象表达与历史追溯 | | 价格与参数 | `biz_price_*`、`biz_cost_component`、`biz_parameter_settings`、`biz_page_settings*` | 用于价格模板、业务参数、页面配置 | | 收费与票据 | `biz_collection`、`biz_withholding`、`biz_invoice`、`biz_invoice_taxrate` | 用于收费、代扣、发票申请与回写 | | 办理与资料 | `biz_process*`、`biz_business_datas`、`biz_content*` | 用于业务办理与进度跟踪 | @@ -1552,7 +1567,8 @@ sequenceDiagram 1. 不再使用旧稿中的 `customer_*`、`water_*`、`billing_*`、`thirdpay_*`、`service_*` 作为 SYS-002 正式接口数据口径。 2. 若历史资料中仍存在旧命名,仅作为来源参考,不作为正式交付口径。 -3. 对 backend 中尚未明确存在独立实体表的对象,例如部分精细账务台账、红冲明细、价差调整明细等,本文仅描述为业务处理场景,不强写为既有独立接口对象。 +3. 对 backend 中尚未明确存在独立实体表的对象,例如部分精细账务台账、红冲明细、价差调整明细等,本文可正式命名其“接口对象语义”,但不误写为当前已完整落地的独立专属接口。 +4. `AccountingWorkflowRef`、`AccountingLegacyMapping` 当前属于目标接口对象 / 目标数据对象命名,用于表达审批引用和历史映射边界,不表示已存在独立对外接口编号。 ## 跨系统报文映射表 @@ -1731,16 +1747,30 @@ sequenceDiagram - 历史查询接口一律只读,不承担迁移修正、补写或状态变更职责。 - 不为迁移场景发明新的独立接口编号体系,统一挂靠既有 `IF-REV-*`、`IF-CS-*`、`IF-METER-*` 接口族扩展查询能力。 -- 对 backend 当前未识别到独立实体表的旧细粒度对象,仅要求接口返回“历史摘要 + 原始标识 + 状态映射”,不强行承诺独立在线业务对象。 +- 全量账务对象的查询出口按“两层口径”组织:一类为业务对象查询出口,一类为历史只读 / 投影查询出口。 +- 对 backend 当前未识别到独立实体表的旧细粒度对象,接口至少返回“对象语义 + 历史摘要 + 原始标识 + 状态映射”,不强行承诺独立在线业务对象。 - 迁移验收接口必须同时支持“汇总对账”和“明细追溯”两类能力,避免只能看总数、无法定位差异。 +### 全量账务对象查询出口分层 + +| 对象类型 | 当前挂靠接口 | 查询层级 | 最低返回要求 | 说明 | +|---------|--------------|----------|--------------|------| +| `PrepaidRefund`、`WrittenoffAdjust`、`PriceDiffAdjust`、`LateFeeReduce`、`BadDebtRecord`、`SplitAdjust` | `IF-REV-007` | 业务对象查询出口 | 对象类型、业务编号、关联账单、金额/水量差异、状态、审批状态、处理时间 | 当前继续挂统一入口查询语义,后续可拆专属查询接口 | +| `RedinkRecord` | `IF-REV-007` | 业务对象查询出口 + 历史只读出口 | 红冲单号、原单号、金额、原因、审批状态、处理时间 | 当前由统一入口和历史查询共同承接 | +| 特殊开账 / 特账 | `IF-REV-005`、`IF-CS-002` | 账单结果 / 历史账单查询出口 | 来源类型、费用类型、账单号、账期、金额、状态 | 继续挂开账主模型与历史账单查询 | +| `RefundBill` | `IF-REV-007`、`IF-CS-002` | 结果对象查询出口 | 结果单号、退款申请号、支付结果、关联账单、状态 | 当前不单列提交接口,但应保留查询出口 | +| `CrossCycleWaterRecord` | `IF-REV-007`、`IF-CS-002` | 基础支撑 / 历史查询出口 | 来源账单、跨期水量、账期范围、累计口径、关联场景 | 当前不作为强流程提交接口,仅保留查询语义 | +| 实时收费、对账日志、柜台结账 | `IF-CS-002`、`IF-REV-011` | 历史只读 / 投影查询出口 | 原流水号、渠道、金额、时间、柜员/营业所、状态 | 查询类对象不转为在线主写接口 | +| IC 卡账务表族 | 历史查询扩展接口 | 历史只读 / 映射查询出口 | 卡号、客户号、金额、时间、旧单据标识、映射状态 | 当前仅保留历史只读 + 映射层查询 | + ### 最小历史查询保留集 | 查询主题 | 挂靠接口族 | 主要数据来源 | 最低返回要求 | 说明 | |---------|------------|--------------|--------------|------| | 历史账单、特殊开账 | `IF-CS-002`、`IF-REV-005` | `biz_charge*` + 历史账单来源 | 原账单号、新账单号、客户号、账期、金额、状态、来源类型 | 支撑账单迁移核查与客户侧历史查询 | | 缴费记录、柜台结账、实时收费 | `IF-CS-002`、`IF-REV-006`、`IF-REV-011` | `biz_collection`、`bk_transaction*` + 历史收费记录 | 原流水号、渠道、实收金额、收费时间、柜员/营业所、核销状态 | 支撑渠道对账、柜面核查和历史收据核对 | -| 红冲与账务调整 | `IF-REV-007` | 操作留痕、流程结果 + 历史调整台账 | 调整类型、关联原单号、调整金额、原因、审批状态、处理时间 | 支撑预存退款、已销调整、价差调整、分账调整、呆坏账查询 | +| 红冲与账务调整 | `IF-REV-007` | 操作留痕、流程结果 + 历史调整台账 | 对象类型、关联原单号、调整金额、原因、审批状态、处理时间 | 支撑预存退款、已销调整、价差调整、分账调整、呆坏账查询 | +| 退款结果与跨周期支撑对象 | `IF-REV-007`、`IF-CS-002` | 统一结果对象 + 历史只读台账 | 结果单号、来源单号、关联账单、结果状态、时间 | 支撑退款账、跨周期水量、疑难账追溯 | | 发票与开票关系 | `IF-REV-008`、`IF-CS-004` | `biz_invoice*` + 历史开票关系快照 | 发票号、申请单号、关联账单、票据状态、票据类型、文件地址 | 支撑发票结果核查与历史补打定位 | | 催缴、停复水、预存短信 | `IF-REV-013`、`IF-METER-002` | 通知结果、流程工单 + 历史催缴记录 | 客户号、账期、催缴方式、消息状态、停复水状态、执行人、执行时间、处置引用 | 支撑催缴处置闭环核查 | | 业务进度与电子档案 | `IF-CS-006` | `biz_process*`、`biz_content*` + 历史附件目录 | 业务单号、节点状态、处理轨迹、附件数量、附件元数据 | 支撑微网厅与柜台办理进度、电子档案查询 | @@ -1753,6 +1783,7 @@ sequenceDiagram |---------|--------------|--------------|----------| | 开账迁移核对 | `IF-REV-005`、`IF-CS-002` | 账期、营业所、客户类型、账单状态 | 同时提供汇总金额/笔数与可追溯明细清单 | | 收费迁移核对 | `IF-REV-006`、`IF-REV-011`、`IF-CS-002` | 日期、渠道、营业所、收费状态 | 同时提供实收金额、流水数量和异常流水列表 | +| 账务对象迁移核对 | `IF-REV-007` | 对象类型、状态、审批状态、账期、时间 | 同时提供对象汇总、结果状态和单据级明细定位 | | 发票迁移核对 | `IF-REV-008`、`IF-CS-004` | 开票日期、票据类型、开票状态 | 同时提供开票汇总、失败原因和票据明细定位 | | 催缴与停复水核对 | `IF-REV-013`、`IF-METER-002` | 账期、催缴方式、执行状态、处理人 | 同时提供任务统计、执行明细与处置引用 | | 业务办理与档案核对 | `IF-CS-006` | 业务类型、流程状态、附件类型、创建时间 | 同时提供流程轨迹、附件元数据和缺失标记 | @@ -1761,9 +1792,10 @@ sequenceDiagram ### 接口约束补充 - 历史查询结果应优先返回原系统标识与新系统标识的映射关系,例如原单号、原批次号、原附件标识、当前业务单号。 -- 明细查询接口应支持按客户号、证件号、手机号、表号、账期、营业所、渠道、业务单号等组合检索,满足迁移验收定位需求。 +- 明细查询接口应支持按客户号、证件号、手机号、表号、账期、营业所、渠道、业务单号、对象类型等组合检索,满足迁移验收定位需求。 - 若历史附件不直接由当前业务服务托管,接口至少返回附件元数据、来源系统、文件引用地址和可访问状态。 - 历史查询接口的导出能力属于查询扩展能力,不应与在线交易接口共用“状态变更”动作。 +- 当前若尚未拆出专属账务对象查询接口,应在统一入口或查询扩展接口中保留 `objectType` 维度,避免后续迁移验收无法区分对象类别。 ## 实现状态说明 @@ -1775,6 +1807,7 @@ sequenceDiagram - 客户与账户查询、维护接口 - 抄表任务与抄表数据接口 - 账单生成与收费核销接口 +- `IF-REV-007` 作为当前统一账务处理入口的正式接口位置 - 银行代收、代扣、交易回调、对账、结算接口 - 发票申请与票据状态回写接口的业务侧支撑 - 客户渠道的账户绑定、查询、缴费、业务办理进度接口 @@ -1783,7 +1816,8 @@ sequenceDiagram 以下接口域已有主线支撑,但部分细粒度对象仍需结合后续实现继续核实: -- 账务调整、退款、坏账、冲正类精细接口 +- `IF-REV-007` 对全量账务对象的完整对象化表达 +- 账务调整、退款、坏账、冲正、红冲、价差调整、分账调整、违约金减免等精细对象查询能力 - 催缴管理中针对不同通知策略和停复水联动的细分接口 - 发票补开等扩展票据后处理接口 @@ -1791,6 +1825,8 @@ sequenceDiagram 以下内容可保留设计说明,但当前不应直接表述为已完全落地: +- 后续专属账务对象接口方向(例如预存退款、红冲、价差调整、分账调整等专属接口) +- `AccountingWorkflowRef`、`AccountingLegacyMapping` 等目标对象在接口层的独立实现形态 - 历史数据字典中大量细粒度账务台账接口 - 未在 backend 当前扫描范围内明确识别到的独立业务对象接口 - 特定银行或地方平台的专有报文细节 diff --git a/docs/research/migration/01_Document_Structure_Migration_Plan.md b/docs/design/04_Appendix/Archive/06_Migration_Plans/01_Document_Structure_Migration_Plan.md similarity index 100% rename from docs/research/migration/01_Document_Structure_Migration_Plan.md rename to docs/design/04_Appendix/Archive/06_Migration_Plans/01_Document_Structure_Migration_Plan.md diff --git a/docs/design/04_Appendix/Archive/08_Formal_Doc_Snapshots/RWB-01/2026-04-03-RWB-01-12_REV_Detailed.md b/docs/design/04_Appendix/Archive/08_Formal_Doc_Snapshots/RWB-01/2026-04-03-RWB-01-12_REV_Detailed.md new file mode 100644 index 0000000..0b120f2 --- /dev/null +++ b/docs/design/04_Appendix/Archive/08_Formal_Doc_Snapshots/RWB-01/2026-04-03-RWB-01-12_REV_Detailed.md @@ -0,0 +1,721 @@ +--- +doc_id: DT-12-REV +doc_role: module_body +authority: secondary +scope: 详细设计-营收业务 +source_of_truth: false +last_reviewed: 2026-03-11 +retrieval_priority: P1 +--- + +# 福建水务营收系统详细设计-营收业务模块正文 + +## 章节导航(精简) + +- [文档定位](#sec-position) +- [营收业务详细设计正文](#sec-content) + - [营收模块统一约束](#sec-rev-rules) + - [接口与数据追溯矩阵](#sec-rev-trace) + - [REV-001 客户资料管理](#mod-rev-001) + - [REV-002 抄表开账](#mod-rev-002) + - [REV-003 营业收费](#mod-rev-003) + - [REV-004 账务处理](#mod-rev-004) + - [REV-005 发票与税务处理](#mod-rev-005) + - [REV-006 催缴与通知](#mod-rev-006) + - [REV-007 统计分析](#mod-rev-007) + - [REV-008 代收与银行业务](#mod-rev-008) + - [REV-009 业务参数配置](#mod-rev-009) + + + +## 文档定位 + +本文档为 `01_Detailed_Design.md` 中“营收业务详细设计”章节的模块正文拆分稿,便于按模块独立维护。正式交付口径以主详设为准。 + + + +# 营收业务详细设计 + + + +## 营收模块统一约束 + +1. `SYS-002` 负责营收主流程,发票、支付结算、消息触达分别通过 `SYS-008`、`SYS-009`、`SYS-010` 协同完成,外部系统仅回写结果状态。 +2. 账单、收费、发票、代扣等关键状态变更必须通过业务流程驱动,不允许绕过业务校验直接改写主业务对象。 +3. 幂等控制遵循接口主键约束:支付以业务订单号为主,发票以申请单号或账单组合为主,代扣以批次号为主,消息以业务事件号为主。 +4. 账务调整、发票申请、催缴触达、银行批次下发等关键动作必须写入操作留痕,满足审计与问题追踪要求。 +5. 数据口径统一采用 `biz_*` 与 `bk_*` 命名体系,历史命名仅用于追溯,不作为本章节正式设计口径。 + + + +## 接口与数据追溯矩阵 + +> 说明:详细字段与报文以 `../03_Technical_Design/03_Interface_Design.md` 为准,数据库字段口径以 `../03_Technical_Design/01_Database_Design.md` 为准。 + +| REV 模块 | 关键接口 | 核心数据域(摘要) | 主要协同对象 | +|---|---|---|---| +| REV-001 客户资料管理 | `IF-REV-001` | `biz_cust`、`biz_account`、`biz_cust_*` | 客户服务模块、报装模块 | +| REV-002 抄表开账 | `IF-REV-004`、`IF-REV-005` | `biz_meter_book`、`biz_meter_read`、`biz_reading_*`、`biz_charge*` | 抄表APP、物联网集抄 | +| REV-003 营业收费 | `IF-REV-006` | `biz_charge*`、`biz_collection`、`bk_transaction*` | `SYS-009` | +| REV-004 账务处理 | `IF-REV-007` | `biz_charge*`、`biz_operat_log*` | 财务与营业人员 | +| REV-005 发票与税务处理 | `IF-REV-008` | `biz_invoice*`、`biz_cust_invoice` | `SYS-008` | +| REV-006 催缴与通知 | `IF-REV-013` | `biz_charge*`、催缴结果留痕 | `SYS-010` | +| REV-007 统计分析 | `IF-REV-010` | 客户、抄表、收费、渠道聚合对象 | 统计分析端 | +| REV-008 代收与银行业务 | `IF-REV-011` | `bk_withholding_*`、`bk_reconcile_*`、`bk_settlement_*` | `SYS-009`、银行 | +| REV-009 业务参数配置 | `IF-REV-012` | `biz_parameter_settings`、`biz_page_settings*`、`biz_price_*` | 统一平台、营收模块 | + + + +## REV-001 客户资料管理 + +### 功能说明 + +负责客户主档、账户主档、联系人、客户分组、客户与水表关系、客户开票信息、客户渠道绑定及托收/代扣关系维护,是抄表、收费、发票、代扣等后续业务的主数据基础。 + +### 关键设计 + +1. 客户建档覆盖立户、变更、更名、过户、销户、报停等全生命周期处理。 +2. 客户资料支持按客户类型、用水性质、片区、集团客户、重点客户等维度管理。 +3. 客户与水表、开票主体、托收/代扣签约关系按关联表维护,避免在主表中堆叠多类属性。 +4. 客户编号、集收标记、计划用水方案等规则类数据由统一配置与客户关系表共同支撑。 + +### 核心数据 + +- `biz_cust`:客户主档。 +- `biz_account`:客户账户与账户状态。 +- `biz_cust_contact`:联系人及联系方式。 +- `biz_cust_group`:客户分组。 +- `biz_cust_meter`:客户与水表绑定关系。 +- `biz_cust_invoice`:客户开票信息。 +- `biz_cust_app_binds`:渠道绑定关系。 +- `biz_cust_collection_rel`:客户托收关系。 +- `biz_cust_withholding_rel`:客户代扣关系。 +- `biz_cust_water_use_scheme`、`biz_cust_water_scheme_rel`:客户计划用水方案关系。 +- `biz_cust_no_rule`:客户编号规则。 +- `biz_cust_hub_marks`:集收号/集收标记关系。 + +### 迁移补充(旧系统承接) + +#### 定额共享 + +- 旧系统在“客户资料”下提供定额主客户、子客户绑定与共享清单管理能力。 +- 当前正式设计不新增并行主模型,统一归入客户与计划用水方案关系对象承接。 +- 迁移时必须至少保留主客户、子客户、绑定状态、生效时间、解除时间、备注与操作留痕,确保共享清单可查询、可解绑、可追溯。 + +#### 定额核定 + +- 旧系统支持对已建立共享关系的客户执行定额核定、撤销核定和共享清单联查。 +- 当前建议以客户关系对象和计划用水方案关系为主承接核定结果,不额外发明独立账务主表。 +- 核定结果迁移后应支持按客户、站点、核定状态、核定时间查询,并保留核定依据、操作人和变更留痕。 + +#### 批量修改 + +- 旧系统已形成“手工修改 + 模板导入修改”的双模式客户资料维护能力。 +- 当前正式设计应将其视为客户主数据治理能力的一部分,而不是临时导入工具。 +- 迁移时需明确三类口径:可批量修改字段范围、导入模板校验规则、批量修改审计留痕;历史批量修改结果至少需保留任务来源、修改字段、执行结果和失败原因。 + +### 接口映射 + +- `IF-REV-001`:客户档案、账户状态、联系人与水表绑定关系查询。 +- `IF-CS-001`、`IF-CS-002`:客户服务侧账户绑定与信息查询场景复用客户域数据。 + +### 落地边界 + +- **已落地**:客户主档、账户、联系人、分组、绑定、开票、托收/代扣关系。 +- **部分落地**:客户扩展关系、集收与规则类对象已见明确关系表,但具体业务场景仍需结合流程进一步细化。 +- **文档先行**:主副卡、部分复杂客户关系对象在当前 backend 中未见完全独立表族,文档中仅保留业务对象表述。 + + + +## REV-002 抄表开账 + +### 功能说明 + +负责抄表计划、册本管理、抄表录入、抄表状态跟踪、异常复核、计费计算与账单生成,是营收核心处理链路的起点。 + +### 业务流程 + +```mermaid +flowchart TD + A[制定抄表计划] --> B[生成抄表册本] + B --> C[分配抄表任务] + C --> D[人工/远传/自报抄表] + D --> E[数据校验] + E --> F{是否异常} + F -->|是| G[异常复核处理] + F -->|否| H[生成开账数据] + G --> H + H --> I[按价格模板与费用组成计费] + I --> J[生成营业账与明细] + J --> K[账单审核确认] + K --> L[进入收费/催缴/开票] +``` + +### 关键规则 + +1. 抄表数据同时校验本次读数、上次读数、用量波动和抄表状态,只有通过校验或完成异常复核的数据才能进入开账。 +2. 异常抄表支持估抄、补抄、重录、人工复核;异常处理的目标是形成可继续开账或明确阻断的统一结论,而不是绕开开账规则单独落账。 +3. `IF-REV-005` 的正式边界是“抄表校验完成后的账单生成”,不负责收费核销、发票开具、催缴执行和统计分析。 +4. 开账计费按价格归属、价格模板、费用组成、阶梯规则、计划用水方案综合计算;价格配置缺失、费用组成不完整或规则冲突时,必须阻断生成并返回失败原因。 +5. 账单生成结果统一由 `biz_charge` 与 `biz_charge_detail` 承接:主表表达客户、账期、应收日期、账单总金额和主状态,明细表表达费用组成、用量、单价和明细金额。 +6. 特殊开账、无码客户开账、罚款类开账等非标准来源,仍纳入同一营业账主明细模型承接,通过来源类型、业务类型、依据说明和操作留痕区分,不单独扩展平行账表。 +7. 审核通过后的营业账方可进入收费、催缴和发票流程;后续链路只能消费已生成账单结果,不反向改变本接口的生成边界。 +8. 远传抄表数据可由 `SYS-006` / IoT 能力提供采集支撑,但账单生成仍归属 SYS-002。 + +### 开账触发与结果表达 + +- 触发前提:正式口径下可按抄表批次、指定客户范围或指定抄表任务范围组织生成;当前 backend 已落地的入口为按 `readingDataIds` 批量复核并开账,对应 `ChargeController.generateCheckChargeBatch`、`ChargeServiceImpl.generateCheckChargeBatch` 与 `ReadingDataServiceImpl.batchReCheckReadingData`。 +- 规则来源:价格归属决定客户适用的价格口径;价格模板、阶梯规则、费用组成和计划用水方案共同决定营业账主表金额与明细拆分方式。 +- 当前承接证据:`ChargeServiceImpl.generateSingleChargeWithCache` 成功路径会写入 `biz_charge` 主表、循环写入 `biz_charge_detail` 明细,并回写抄表数据开账状态,说明现有实现已具备“按抄表数据 ID 生成营业账主明细”的 backend 基础。 +- 结果表达:正式 `IF-REV-005` 应返回成功清单、失败清单、生成汇总及主明细级结果;当前 backend 返回仍为“本次复核成功X条 / 本次开账成功Y条”的字符串拼接,尚未形成结构化成功/失败结果对象。 +- 阻断与限制:价格模板不存在、费用调整配置缺失、结算方式非 `ACTUAL_USAGE` 等场景当前会直接阻断单条生成;其中固定水量、按人口数、最低消费等非实际水量结算方式仍未纳入当前实现。 +- 下游边界:`REV-002` 只负责生成营业账结果并交由后续审核/收费链路消费,不在本章节扩展收费核销、发票申请或催缴执行细节。 + +### 核心数据 + +- `biz_meter_book`:册本与抄表计划。 +- `biz_meter_read`:抄表任务状态/执行状态。 +- `biz_reading_data`:抄表数据。 +- `biz_last_reading`:上次抄表结果。 +- `biz_reading_logs`:抄表日志与过程留痕。 +- `biz_meter`:计量水表主档引用。 +- `biz_charge`:营业账主表。 +- `biz_charge_detail`:营业账明细。 +- `biz_price_category`:价格归属。 +- `biz_price_template`:价格模板。 +- `biz_price_adjustment_snap`:调价快照。 +- `biz_price_tier_adjustment`:阶梯规则。 +- `biz_cost_component`:费用组成。 +- `biz_water_use_scheme`、`biz_water_use_scheme_tier`:计划用水方案与阶梯。 + +### 迁移补充(旧系统承接) + +#### 特殊开账 + +- 旧系统支持在非标准客户、无码客户或罚款类场景下直接开账。 +- 新系统仍以 `biz_charge`、`biz_charge_detail` 作为开账结果承载对象,不建议额外平行建设“特殊开账账表”。 +- 迁移与新建场景均需保留特殊开账来源、业务类型、经办人、依据说明、打印状态与后续收费关联,避免与普通抄表开账混淆。 + +#### 开账记录迁移 + +- 旧系统“开账记录”是历史查询与账务核对的核心入口,必须纳入迁移最小保留集。 +- 迁移后的开账记录应至少支持按站点、账务年月、册本、客户、抄表员、欠费状态查询,并支持统计水量、总金额及费用构成。 +- 对已收费、已作废、销户拆表、特殊开账等旧状态,不要求照搬旧表结构,但必须保留可对照的新状态映射关系。 + +### 接口映射 + +- `IF-REV-004`:抄表数据提交与异常标记。 +- `IF-REV-005`:账单生成与开账结果返回。 +- `IF-METER-004`:远传抄表数据接收后进入开账流程。 + +### 落地边界 + +- **已落地**:册本、抄表数据、上次抄表、抄表日志、营业账主明细、价格模板与阶梯规则。 +- **部分落地**:部分异常场景对象可能仍通过状态字段和日志表承载,而非全部拆成独立业务表。 +- **文档先行**:个别精细稽查、轨迹、下载同步对象当前未在本轮映射中确认为独立表。 + + + +## REV-003 营业收费 + +### 功能说明 + +支持柜台收费、预存款/余额抵扣、线上缴费回写、柜面扫码、营业网点收费及收费凭证管理,统一承接营收账单的核销处理。 + +### 业务流程 + +```mermaid +flowchart TD + A[查询客户及待缴账单] --> B[选择账单与核销方式] + B --> C[选择支付渠道] + C --> D{支付方式} + D -->|柜台现金/POS/扫码| E[现场收费] + D -->|微信/支付宝/聚合支付| F[渠道下单] + D -->|预存款/余额抵扣| G[账户余额核销] + E --> H[更新营业账状态] + F --> I[等待异步回调确认] + G --> H + I --> H + H --> J[生成收费记录与凭证] + J --> K[进入发票/对账流程] +``` + +### 关键规则 + +1. 一次缴费可对应多个账单或账单明细的组合核销。 +2. 收费记录必须保留渠道、流水号、网点、操作员、终端信息。 +3. 线上支付必须以回调或查询确认结果为准,不得以发起状态直接记账。 +4. 支付能力由 `SYS-009` 提供,SYS-002 负责账单核销与业务状态回写。 +5. 当前实现侧已确认 `PayCeb` 的欠费查询、缴费处理基础闭环可用,但代理收费对账仍为预留能力;正式文档不得将实时收费对账写成已闭环能力。 + +### 核心数据 + +- `biz_charge`、`biz_charge_detail`:待缴与已缴账单主明细。 +- `biz_collection`:托收/代收主表。 +- `biz_withholding`:代扣/托收主表。 +- `bk_transaction`:渠道交易流水。 +- `bk_transaction_callback`:支付回调记录。 +- `bk_transaction_exception`:支付异常记录。 + +### 迁移补充(旧系统承接) + +#### 柜台结账 + +- 旧系统将“柜台收费”和“柜台结账”拆分为两个菜单,结账阶段包含未结/已结查询、结账红冲、追加抄表和打印动作。 +- 当前设计可继续采用统一收费核销模型,但必须补出“收费记录 → 班结结果 → 打印/红冲/查询”的业务闭环,避免柜面日终处理缺口。 +- 迁移时需保留结账时间、结账人、网点、收费汇总口径和结账后红冲痕迹,保证财务对账与审计连续。 + +#### 账单打印服务 + +- 旧系统存在账单打印、补打、打印次数控制与打印记录查询能力。 +- 新系统不要求单独建立打印主模块,但必须明确打印模板、补打权限、打印状态与打印留痕的承接关系。 +- 对历史账单迁移,应允许基于账单主明细和打印配置恢复打印视图,避免割接后只能查账不能补打。 + +#### 红冲记录 + +- 旧系统支持红冲记录查询、导出与明细展开,是收费差错追溯的重要入口。 +- 当前设计可将红冲视为收费核销后的修正场景,不强制要求独立实体表,但必须提供历史只读查询口径。 +- 红冲迁移最小保留信息应包括原收费记录、红冲时间、红冲金额、原因、经办人、关联账单和后续账务状态。 + +### 接口映射 + +- `IF-REV-006`:创建收费记录、执行账单核销并回写状态。 +- `IF-CS-003`、`IF-CS-007`:客户渠道与柜面扫码支付场景复用收费核销链路。 + +### 落地边界 + +- **已落地**:营业账主明细、交易流水、回调、异常、托收/代扣主对象。 +- **部分落地**:柜台班结、部分收费汇总类对象可能通过业务流程与报表实现,不一定存在独立表。 +- **文档先行**:部分红冲、实时收费汇总类台账暂不表述为已确认独立实体表。 + + + +## REV-004 账务处理 + +### 功能说明 + +REV-004 一期仅覆盖水量调整、金额调整、退款、冲正、坏账申请五类场景,统一挂靠 `IF-REV-007` 作为账务处理入口,目标是在既有正式文档体系内先收敛范围、承接口径、留痕要求与审批边界。 + +本阶段按“共性能力先统一、场景能力再分批”组织:先统一账单承接、原交易校验、结果表达、操作留痕与审批边界,再分别展开五类场景。违约金减免、分账调整、价差调整、跨周期水量、预存退款细表等内容仅作为旧系统迁移语义或后续扩展参考,不作为一期新增独立范围。 + +### 业务流程 + +```mermaid +flowchart TD + A[发起账务调整申请] --> B[校验账单状态与权限] + B --> C{是否通过} + C -->|否| D[驳回并记录原因] + C -->|是| E[执行重算或退款冲正] + E --> F[更新账单与明细状态] + F --> G[写入操作日志与审批留痕] + G --> H[返回处理结果] +``` + +### 关键规则 + +1. 一期场景严格限定为水量调整、金额调整、退款、冲正、坏账申请,不扩展到其他接口族或独立账务台账重构。 +2. 所有场景均以 `biz_charge` / `biz_charge_detail` 为主承接对象,并通过 `biz_operat_log` / `biz_operat_log_detail` 记录处理依据、前后变化和责任归属。 +3. 退款、冲正必须联动 `bk_transaction`、`bk_transaction_callback`、`bk_transaction_exception` 等原支付流水及渠道状态校验,不允许仅依据账单状态直接处理。 +4. 接口结果统一返回 `resultStatus`、`writeBackStatus`,其中 `resultStatus` 表示处理结论,`writeBackStatus` 表示账单状态回写结论,两者不得混用。 +5. 审批相关内容一期仅保留 `approvalRequired`、`PENDING_APPROVAL` 与审批边界说明,不展开完整 BPM 流程、节点、流转规则或审批回写实现细节。 +6. 对于当前未见明确独立实体表的特账、跨周期水量、退款账等对象,文档以“业务处理场景”表述,不强行落为已实现表。 + +### 核心数据 + +- `biz_charge`、`biz_charge_detail`:账务调整的核心对象,承接调整前后账单主明细状态。 +- `bk_transaction`、`bk_transaction_callback`、`bk_transaction_exception`:退款、冲正场景的原交易校验与异常追溯对象。 +- 价格调整/优惠相关表:用于重算账单或差额追溯。 +- `biz_operat_log`、`biz_operat_log_detail`:操作与变更留痕,记录字段差异、处理说明、附件依据与责任归属。 + +### 主要场景 + +| 场景 | 说明 | 控制要点 | +|---|---|---| +| 水量调整 | 更正异常水量 | 需复核原因、附件和原抄表依据 | +| 金额调整 | 更正账单金额 | 需记录依据、差异金额和审批边界 | +| 退款 | 退回客户支付资金或预存款 | 需校验原交易、退款余额与幂等性 | +| 冲正 | 修正误收/误核销记录 | 需关联原交易与账单状态 | +| 坏账申请 | 对长期欠费进行分类处理 | 需结合账龄、客户状态与审批边界 | + +### 迁移补充(旧系统承接) + +| 旧账务对象 | 当前承接方式 | 迁移口径 | +|---|---|---| +| 预存退款 / 预存退款详情 | 作为账务处理场景承接 | 保留申请单、原支付引用、退款结果与审批留痕 | +| 已销调整汇总 / 明细 | 作为已收费后修正场景承接 | 保留原账单、调整原因、前后差异、处理结果 | +| 价差调整汇总 / 明细 | 作为重算与差额修正场景承接 | 保留原价格口径、新价格口径、差额和生效时间 | +| 分账调整汇总 / 明细 | 作为费用组成重分摊场景承接 | 保留原分摊结果、调整后结果、责任人和审批链 | +| 账单-违约金减免 | 作为滞纳金修正场景承接 | 保留减免原因、减免金额、审批结果和生效时间 | +| 账单-呆坏账 | 作为坏账申请与生效场景承接 | 保留账龄、申请原因、审批结果、核销状态 | + +1. P0 阶段不要求为每一类旧账务台账都新增独立实体表,但必须在业务对象和历史查询层形成可追溯闭环。 +2. 旧系统精细台账迁移后至少保留:原单据标识、原账单标识、处理类型、处理原因、处理前后金额/水量、申请/审批/生效时间、经办人与附件依据。 +3. 与支付、发票、渠道回调强关联的处理场景,必须保留与原交易、原发票、原收费记录的关联关系,避免后续对账和审计断链。 + +### 接口映射 + +- `IF-REV-007`:账务调整、退款、冲正、坏账等处理入口。 +- `IF-REV-006`:与收费核销状态联动,确保调账后账单状态一致。 + +### 落地边界 + +- **已落地**:营业账主明细、操作日志、价格/方案相关重算支撑。 +- **部分落地**:精细化账务对象更多表现为流程与场景,并未在 backend 中全部体现为独立表族。 +- **文档先行**:特账、退款账、跨周期水量等对象保留业务语义,不宣称为已实现独立表。 + + + +## REV-005 发票与税务处理 + +### 功能说明 + +负责发票业务闭环的业务接入与状态落账,覆盖后台发票申请、开票校验、`SYS-008` 异步协同、查询兜底、结果回写、账单关联、客户侧已开票电子发票查询/下载/推送,以及后台作废与红冲处理。 + +### 业务流程 + +```mermaid +flowchart TD + A[后台提交发票申请] --> B[校验账单、客户开票信息、税率与限额] + B --> C{是否满足开票条件} + C -->|否| D[返回不可开票原因] + C -->|是| E[生成申请单号并写入SUBMITTED] + E --> F[调用SYS-008发起异步开票] + F --> G[记录受理号并转为PENDING] + G --> H[系统轮询或后台查询兜底] + H --> I{开票结果} + I -->|成功| J[回写SUCCESS并更新账单-发票关联] + I -->|失败| K[回写FAIL并记录失败原因] + J --> L[客户侧查询/下载/推送电子发票] +``` + +### 状态说明 + +- `SUBMITTED`:后台申请已受理,已完成本地校验并生成申请单。 +- `PENDING`:已提交 `SYS-008`,等待异步结果或查询补偿结果。 +- `SUCCESS`:已取得有效发票代码、号码或电子票地址,且账单关联已完成更新。 +- `FAIL`:开票失败,需保留失败原因、最近查询结果与后续人工核查依据。 +- `INVALID`:发票已作废,作为后续能力预留状态。 +- `RED_INK`:发票已红冲,作为后续能力预留状态。 + +### 关键规则 + +1. 一期采用“后台申请开票 + 客户侧查询下载推送”的入口模式,客户侧不直接发起开票申请。 +2. 发票申请以客户信息、已收费未开票账单、税率配置和开票限额为基础;原始单账单不支持直接任意部分金额开票。 +3. 个人与企业开票均通过客户开票信息与税率表完成合法性校验;如需多张发票,沿用拆账/分账后的账单分别开票口径。 +4. `SYS-008` 采用“异步申请 + 查询兜底”模式,成功状态不得被后续失败查询结果覆盖。 +5. 电子发票仅在 `SUCCESS` 且存在票据文件地址时允许客户侧下载或推送。 +6. 发票作废、红冲仍由 `SYS-008` 统一承接税控侧处理,`SYS-002` 负责后台触发入口、状态校验、查询补偿、结果落账与日志留痕;当前轮次按二期范围补齐 backend 实现入口。 + +### 后台申请入口与校验补充 + +- 后台支持营业收费员、财务人员按单笔或批量已收费账单发起开票申请。 +- 申请时至少校验:账单收费状态、开票状态、客户开票信息完整性、票种适配性、开票限额、账单集合是否属于同一客户。 +- 企业抬头场景重点校验纳税人识别号;电子发票场景重点校验邮箱/手机号;不满足条件时直接返回不可开票原因。 +- 申请成功后生成申请单号并进入 `SUBMITTED/PENDING` 状态流转,失败校验场景不进入外部协同。 +- 幂等控制以 `applicationNo` 或 `custId + chargeIds` 为主,避免相同账单组合重复申请。 + +### SYS-008 异步协同与查询补偿 + +- 本地申请校验通过后,`SYS-002` 先写入 `biz_invoice` 申请记录,再向 `SYS-008` 发起异步开票请求,并记录 `sysRequestNo` 作为后续查询与回写的协同主键。 +- `SYS-008` 返回“已受理”后,发票状态转为 `PENDING`;若仅完成本地受理但尚未拿到受理号,则保留 `SUBMITTED` 并进入待补偿查询状态。 +- 查询补偿采用“回写优先、主动查询兜底”原则:`IF-EXT-007` 回写为首选结果来源,后台人工查询与系统定时补偿查询共用同一结果落账逻辑。 +- 系统补偿查询至少保留最近查询时间、下次计划查询时间、累计查询次数、最近一次返回结果摘要与异常原因,便于问题追踪和人工核查。 +- 后台按申请单号或受理号触发查询时,应同步刷新查询上下文;查询仍未取得终态时,仅更新补偿上下文,不得伪造成功或失败结论。 + +### 终态保护与异常核查 + +- `SUCCESS` 属于正常开票闭环终态,一旦已取得有效发票代码、发票号码或电子票据地址,后续失败查询结果不得覆盖成功状态。 +- `FAIL` 仅在 `SYS-008` 明确返回失败结论或多次补偿查询确认失败时写入,并同步保留失败原因、最近查询结果与人工核查依据。 +- 当后台人工查询、系统补偿查询与外部回写结果不一致时,应以最新有效外部凭据为准,并记录差异说明,不允许直接覆盖既有成功票据关键信息。 +- 每次提交协同、主动查询、状态变更和异常分支均应写入操作留痕,确保能够追溯责任人、触发来源、状态前后值与异常说明。 + +### 结果回写、账单关联与客户侧消费 + +- `IF-EXT-007` 回写成功结果时,除更新 `biz_invoice.invoice_status`、`invoice_code`、`invoice_number`、`file_url` 外,还应同步刷新账单快照、账单关联状态与推送状态初值。 +- 账单关联以 `biz_invoice.charge_id` + `charge_ids_snapshot` 记录本次开票覆盖账单集合,并同步把对应 `biz_charge.invoice_state` 更新为“开票完成”,保留失败原因与开票时间,便于账单明细、收费记录和客户侧结果统一展示。 +- 客户侧查询仅允许按本人 `custId` 访问已存在的发票记录;可通过 `invoiceId`、`applicationNo` 或 `sysRequestNo` 定位,但都必须命中同一客户名下记录。 +- 客户侧下载与推送前必须校验发票状态为 `SUCCESS` 且 `fileUrl` 非空;不满足条件时仅返回不可下载/推送原因,不得伪造文件地址。 +- 推送动作应记录推送渠道、目标邮箱/手机号与结果状态;成功后更新 `pushStatus=PUSHED`,失败则写入 `FAIL` 并保留失败原因供人工处理。 + +### 核心数据 + +- `biz_invoice`:发票主记录。 +- `biz_invoice_taxrate`:税率配置。 +- `biz_cust_invoice`:客户开票信息。 + +### 迁移补充(旧系统承接) + +- 旧系统数据字典中存在“发票明细表、营业账开票表、开票配置表”等更细粒度对象。 +- 当前正式设计已明确主承接对象为 `biz_invoice`、`biz_invoice_taxrate`、`biz_cust_invoice`,但迁移时不能忽略旧开票明细和账单关联关系。 +- P0 阶段建议先补三类迁移口径:账单与发票的关联关系、发票申请与结果回写记录、开票配置与税率的有效期;未确认已落地的细表对象仍按“历史只读或辅助映射”处理。 + +### 接口映射 + +- `IF-REV-008`:后台发票申请接口,负责单笔/批量申请、幂等控制与受理号生成。 +- `IF-REV-009`:发票结果查询接口,负责后台按申请单号/受理号查询以及系统补偿查询。 +- `IF-CS-004`:客户侧电子发票消费接口,负责已开票结果查看、下载、推送。 +- `IF-EXT-007`:发票结果回写协同接口(由发票服务侧回传)。 + +### 落地边界 + +- **已落地**:发票主记录、税率配置、客户开票信息,以及一期正常开票闭环所需的后台申请、查询兜底、结果回写、账单关联与客户侧电子发票消费能力。 +- **部分落地**:发票修改、开票过程留痕在后端中已有相关对象,但整套发票明细/批次类对象尚未全部确认。 +- **二期补齐**:发票作废、红冲及其查询补偿仍由 `SYS-008` 统一承接,但当前轮次补齐后台触发入口、状态流转、结果回写与日志留痕,不再仅停留于文档预留。 +- **文档先行**:发票明细、营业账开票关系等对象仍按设计能力描述,不表述为本轮已确认独立表。 + + + +## REV-006 催缴与通知 + +### 功能说明 + +针对欠费账单按账龄、金额、客户类别等规则生成催缴任务,通过短信、微信、站内通知等方式触达客户,并回写催缴结果;本模块同时定义催缴与停复水/工单处置之间的联动边界与追溯关系,但不展开停复水内部处置流程。 + +### 业务流程 + +```mermaid +flowchart TD + A[生成欠费客户清单] --> B[按策略分组催缴任务] + B --> C[触发IF-REV-013生成催缴任务] + C --> D[调用IF-EXT-008协同SYS-010] + D --> E[接收发送结果回写] + E --> F[更新催缴状态与后续策略] + F --> G[按联动边界挂接停复水/工单处置] +``` + +### 关键规则 + +1. 催缴策略以营业账状态、欠费金额、账龄分布、客户类别和渠道偏好为基础,支持按策略编码进行任务分组与频控。 +2. 自动催缴与人工催缴可并行;自动任务用于常规批量催缴,人工任务用于补发、核查或例外处置。 +3. `SYS-002` 负责催缴对象筛选、任务生成、业务事件编号、结果承接与历史查询;`SYS-010` 负责短信、微信公众号、站内信等触达执行与结果回传。 +4. `REV-006` 正式结果状态固定为 `PENDING`、`SUCCESS`、`FAIL`、`MANUAL_VERIFIED` 四态,其中 `MANUAL_VERIFIED` 仅用于外部结果未定或需人工核查补记的场景。 +5. 停复水在本模块中仅定义联动触发条件、处置引用与追溯关系,不展开停复水内部审批、派工或现场执行流程。 +6. 当前后端中部分催缴汇总、停水明细对象未确认独立落表,文档中保持保守描述,不误写为已确认在线主表。 + +#### 催缴对象筛选、排除与频控边界 + +- `IF-REV-013` 任务生成前必须完成候选筛选,筛选最小维度为:欠费状态、欠费金额、账龄分组、客户类别、渠道偏好和策略编码。 +- 候选对象必须以有效欠费账单为前提;以下场景不得进入正式催缴任务:已收费核销、已作废、已进入不允许催缴的处置流程、策略规则未命中。 +- 触发类型按 `triggerType` 区分自动与人工;自动用于批量触发,人工用于补发、核查和例外补记,不改变正式接口编号与状态语义。 +- 频控以“同客户/同策略/同渠道/同账期窗口”为最小拦截单元;命中频控时允许部分阻断,并返回被跳过对象及原因摘要。 + +### 核心数据 + +- `biz_charge`、`biz_charge_detail`:催缴对象来源。 +- 催缴结果与通知日志:通过业务状态与消息结果联动留痕。 + +#### 催缴对象与规则摘要 + +- `Reminder Candidate`:由欠费账单、客户类别、账龄分组、欠费金额、联系方式集合和命中策略编码组成,是催缴任务的输入对象。 +- `Reminder Strategy`:定义账龄规则、金额规则、客户类别规则、渠道优先级、重复触达拦截窗口和是否触发后续处置关注。 +- `Reminder Task`:一次正式催缴执行单元,至少包含 `taskNo`、`eventNo`、`strategyCode`、`channelType`、`triggerType`、`status` 和关联账单信息;正式业务接口编号固定为 `IF-REV-013`。 +- `Reminder Result`:承接 `IF-EXT-008` 回传结果后由业务侧映射的正式四态结果,最少记录 `status`、`lastCallbackTime`、`failReason` 与回传摘要。 +- `Disposal Link`:用于记录催缴结果与停水、复水、工单或人工跟进之间的关联引用,只承担追溯职责,不替代下游业务对象。 + +#### 四态与人工核查边界 + +- `PENDING`:已生成任务并完成外部受理或等待外部终态回传,尚未形成业务终态。 +- `SUCCESS`:外部触达结果明确成功,且业务侧已完成结果承接。 +- `FAIL`:外部返回明确失败或业务判定失败,必须记录失败原因。 +- `MANUAL_VERIFIED`:仅用于外部结果长期未定、人工核查补记或例外核销说明场景;必须留存核查说明与核查人。 +- 人工核查是状态收口手段,不得用于绕过候选筛选、排除条件或频控约束。 + +### 迁移补充(旧系统承接) + +#### 催缴记录 + +- 旧系统支持催缴记录查询、导出和明细展开,记录中包含推送内容、号码、方式、结果等信息。 +- 新系统可继续以消息协同结果和账单状态联动承接,但必须明确催缴记录查询口径,而不能仅保留“已发送/未发送”状态。 +- 历史查询最少保留客户号、账期、催缴方式、发送对象、发送时间、执行结果、关联账单、关联处置引用等字段,并兼容四态结果或其历史映射值。 +- 历史催缴记录按只读口径承接,作为查询与追溯来源,不反推为已确认在线主表。 + +#### 停水记录 + +- 停水记录不是孤立账务对象,应由催缴结果、业务处置和现场执行工单共同形成闭环。 +- 迁移后需支持按客户、站点、停水原因、停水时间、复水状态查询,并能追溯到对应欠费账单和工单执行结果。 +- 正式设计只定义“何时建立联动、如何保存处置引用、如何追溯关联结果”,不在 `REV-006` 中展开停复水内部流程设计。 +- 停复水关联以 `Disposal Link` 的处置引用承接,最少包含任务号、处置类型、处置引用号和建联时间。 + +#### 预存短信 + +- 旧系统对预存款余额不足客户提供短信推送和发送记录查询。 +- 新系统建议将其纳入催缴与通知统一策略,不再单建平行模型,但必须保留触发条件、发送内容、发送结果和补发记录。 +- 该类记录与催缴记录一样,按历史只读口径承接,不表述为新增同名在线主表。 + +### 接口映射 + +- `IF-REV-013`:催缴任务生成、任务查询与结果承接接口,负责业务侧任务生成、四态状态维护和历史查询挂接。 +- `IF-EXT-008`:消息协同结果回写接口(由 `SYS-010` 协同)。 + +### 落地边界 + +- **已落地**:以营业账为基础的欠费识别前提数据、催缴对象来源字段和消息协同边界约束。 +- **部分落地**:催缴登记汇总、停水汇总等对象暂未在 backend 中确认独立表,当前以业务事件、操作留痕和历史查询口径承接。 +- **文档先行**:复杂催缴台账、停复水统计和人工核查界面仅作为业务场景保留,不表述为 backend 已完成能力。 + + + +## REV-007 统计分析 + +### 功能说明 + +提供营收、抄表、收费、欠费、渠道、客户等多维度统计查询能力,为经营分析、业务监管和迁移核查提供统一的数据口径支撑;本模块以经营查询为主,不扩展到预测分析、专题大屏或独立 BI 平台实现。 + +### 关键设计 + +1. 统计查询按“主题 + 维度 + 指标”三层口径组织,避免仅以报表名称堆砌需求。 +2. 主题范围至少包括营收汇总、收费与实收统计、欠费规模与账龄统计、客户结构统计、渠道交易统计、抄表完成率统计以及营收相关业务概览类摘要。 +3. 查询维度至少包括时间区间、账期、营业所/片区、客户类别、渠道、客户/账户、状态等,并支持必要的分组汇总。 +4. 指标口径需明确区分应收金额、实收金额、欠费余额、账单数、客户数、交易笔数、渠道占比、抄表完成率等相近但不等价的统计概念。 +5. 导出与查询结果受数据权限控制;导出属于查询扩展能力,但不在本轮展开具体导出实现细节。 +6. 重点查询可按聚合视图、汇总口径或预聚合结果承接,但不将未确认存在的统计表、专题分析表或离线数仓对象写成已实现事实。 + +### 核心数据 + +- 客户维度:`biz_cust`、`biz_account`。 +- 抄表维度:`biz_meter_book`、`biz_reading_data`、`biz_last_reading`。 +- 账务与收费维度:`biz_charge`、`biz_charge_detail`。 +- 收费与交易维度:`biz_collection`、`bk_transaction`。 +- 渠道维度:`bk_transaction`、`bk_payment_channel`。 +- 组织与权限维度:`system_dept`、数据权限控制结果。 + +#### 统计主题与口径摘要 + +- `Statistics Theme`:按经营主题组织查询,至少覆盖营收、收费、欠费、客户、渠道、抄表完成率和必要的业务概览。 +- `Statistics Dimension`:按时间、账期、营业所/片区、客户类别、渠道、客户/账户、状态等条件筛选或分组。 +- `Statistics Indicator`:至少明确应收金额、实收金额、欠费余额、账单数、客户数、交易笔数、渠道占比、完成率等指标含义和单位。 +- `Aggregation Source`:统计结果以现有在线主数据聚合、视图或汇总口径承接,不反推为已存在独立统计表族。 + +### 接口映射 + +- `IF-REV-010`:营收、收费、欠费、渠道、客户等统计查询接口,承接主题查询、维度筛选、指标汇总和权限/导出边界。 + +### 落地边界 + +- **已落地**:主要统计源数据在客户、抄表、账单、收费、交易和渠道等领域均已具备,足以支撑经营统计口径设计。 +- **部分落地**:部分统计结果可能依赖聚合视图、汇总查询或报表层实现,当前未见明确的 backend 统计控制器或独立统计模型入口。 +- **文档先行**:预测类、专题分析类深度模型、BI 大屏和独立数仓能力暂不写成后端已实现能力。 + + + +## REV-008 代收与银行业务 + +### 功能说明 + +支持银行代收、银行代扣、实时收费、夜间批量扣款、对账与结算处理,是 SYS-002 面向 `SYS-009` 支付与银行结算能力的业务承接模块。 + +### 业务流程 + +```mermaid +flowchart TD + A[生成代扣批次] --> B[校验签约与待扣账单] + B --> C[调用IF-REV-011下发批次] + C --> D[SYS-009对接银行处理] + D --> E[回写扣款结果] + E --> F[执行对账与差异识别] + F --> G{差异是否已处理} + G -->|否| H[进入人工补偿] + G -->|是| I[确认结算并更新状态] +``` + +### 关键规则 + +1. 渠道、路由、接口配置、签约、交易、回调、异常、对账、结算形成完整银行业务链条。 +2. 实时收费场景由渠道交易流水驱动账单核销,批量代扣场景由签约关系与批次处理驱动。 +3. 对账结果区分一致、长款、短款、失败待处理等状态,支持差异追踪与人工补偿。 +4. 国密报文、批量文件、标准 API 等技术细节由 `SYS-009` 承载,SYS-002 保留业务规则与状态协同。 +5. 当前 backend 已确认 `BankWithholding` 六条银行入口(客户状态查询、送盘、送盘状态查询、取消送盘、回盘、回盘状态查询)已形成最小实现态闭环;`BankCollection` 平行链路、对账与结算协同仍以“部分实现或文档先行”表述,不得统一写成已闭环能力。 +6. 银行代扣文件传输配置按“默认规则 + 银行通道覆盖 + 租户覆盖 + 租户-银行通道覆盖”建模,命中优先级固定为 `TENANT_CHANNEL > TENANT > CHANNEL > DEFAULT`。 +7. 目录字段至少区分 `send/back/reconcile/archive/localTemp` 五类阶段;上层覆盖未完整定义时按字段级回退,不允许生成空路径。 +8. 路径模板仅允许 `{tenantId}`、`{companyId}`、`{channelCode}`、`{yyyyMMdd}`、`{yyyyMM}`、`{batchNo}`、`{fileName}` 七个固定变量;命中未声明变量或缺少变量取值时立即阻断文件动作。 +9. `BankWithholding` 在送盘创建时固化 `sendProtocol/sendDir/sendFilePath` 与 `backProtocol/backDir`,配置切换仅影响新发起文件动作,已落库批次继续沿用原解析结果。 + +### 核心数据 + +- `bk_payment_channel`:支付渠道。 +- `bk_channel_api_config`:渠道接口配置。 +- `bk_channel_route_rule`:渠道路由规则。 +- `bk_withholding_agreement`:代扣签约。 +- `bk_withholding_batch`、`bk_withholding_item`:代扣批次与明细。 +- `bk_reconcile_batch`、`bk_reconcile_diff`:对账批次与差异。 +- `bk_settlement_batch`:结算批次。 +- `bk_transaction`、`bk_transaction_callback`、`bk_transaction_exception`:交易、回调、异常。 +- `biz_collection`、`biz_withholding`:代收/代扣业务主对象。 + +#### 文件传输配置与审计补充 + +- 环境默认规则通过 Spring profile + Nacos 承接,不在仓库样例中写入真实密码、私钥或证书。 +- `bk_channel_api_config` 使用专用 `apiType=FILE_TRANSFER_CONFIG` 承接文件传输覆盖配置,`extParams` 记录作用域、业务类型、协议、连接引用和五类目录字段。 +- `bk_withholding_batch` 固化送盘/回盘目录与协议,`bk_reconcile_batch` 固化对账阶段最终 `protocol/dir/filePath/fileName`,用于审计与问题回放。 + +### 迁移补充(旧系统承接) + +#### 银行托收 + +- 旧系统“银行托收”菜单重点承接托收送盘、托收信息查询和托收结果回看。 +- 当前设计已形成 `biz_collection` + `bk_*` 渠道模型,迁移时应补出“旧托收菜单 → 托收批次/交易/回盘结果”的映射,而不是按旧菜单名平移建模。 +- 旧托收历史记录应至少保留送盘批次、客户范围、送盘结果、回盘结果和账单核销结果。 + +#### 实时收费查询与对账 + +- 旧系统“实时收费”更偏运营查询和渠道对账入口,不只是支付成功回写。 +- 当前建议以 `bk_transaction*` 作为主承接对象,并补充按结算日期、银行/渠道、收费结果、差异状态查询和导出能力说明。 +- 对旧“实时收费汇总/日志/明细”对象,P0 阶段先按历史只读查询口径保留,不误写为当前已落地的独立主模型。 + +#### 当前实现对齐说明 + +- `PayCeb` 路径已具备欠费查询、缴费处理、流水唯一性校验和交易日志留痕,可作为实时收费基础闭环的实现证据。 +- `BankWithholding` 路径已具备签约、解约、客户状态查询、送盘、送盘状态查询、取消送盘、回盘、回盘状态查询及对应交易留痕的实现证据,可作为代扣最小实现态闭环依据。 +- `BankCollection` 路径当前仍仅能确认签约、解约与协议/交易日志处理具备实现证据。 +- 对账、结算、真实银行文件解析、SFTP/文件通道联调和运行态样本补证当前仍未闭环,正式文档应继续保留为后续完善项。 + +### 接口映射 + +- `IF-REV-011`:代扣批次、对账与结算协同入口。 +- `IF-EXT-001`:银行代扣批次下发与回盘协同。 +- `IF-EXT-003`:银行实时收费查询、缴费与结果确认协同。 + +### 落地边界 + +- **已落地**:渠道、路由、交易、回调、异常、代扣/托收签约、解约,以及 `BankWithholding` 的客户状态查询、送盘、送盘状态查询、取消送盘、回盘、回盘状态查询和对应日志留痕等主对象已具备明确实现证据。 +- **部分落地**:`BankCollection` 批次、明细、送盘、回盘、状态查询、差异台账和后台资源管理入口已具备对象或骨架,但不等同于银行协同闭环全部完成;`BankWithholding` 的真实文件解析、异常补偿和运行态联调证据仍待补齐。 +- **文档先行**:夜间批量代扣调度、完整对账处理、结算确认、扩展银行台账等内容不得在当前阶段写成已完成能力。 + + + +## REV-009 业务参数配置 + +### 功能说明 + +负责营收域的价格参数、客户编号规则、页面配置、打印与渠道相关业务参数配置,为客户、开账、收费、发票、催缴等模块提供统一配置支撑。 + +### 关键设计 + +1. 业务参数按租户、单位、片区、业务类别分层管理。 +2. 价格体系、客户编号规则、页面字段配置、打印与通知参数统一归口维护。 +3. 配置变更应具备版本化、操作留痕与生效范围控制。 + +### 核心数据 + +- `biz_parameter_settings`:业务参数配置。 +- `biz_page_settings`、`biz_page_settings_detail`:页面配置。 +- `biz_price_category`、`biz_price_template`、`biz_template_dept_rel`:价格归属与模板站点关系。 +- `biz_cust_no_rule`:客户编号规则。 + - `sys_wechat_app_settings`:微信/微网厅基础配置。 + +### 迁移补充(旧系统承接) + +- 旧系统后台存在“页面配置、业务字段、微信参数、打印维护”等运营配置入口。 +- 当前建议统一按业务参数、页面配置、渠道参数与打印参数归口承接,不新增“微客服后台配置”并行主文档。 +- 迁移时需明确三类配置映射:客户/业务办理字段展示与校验规则、微信/微网厅基础参数、打印模板与补打策略;未确认已实现的高级灰度能力继续按“文档先行”处理。 + +### 接口映射 + +- `IF-REV-012`:查询与维护价格模板、业务参数、页面参数配置。 +- `IF-UP-004`:统一平台参数字典能力协同,为营收域参数提供基础字典支撑。 + +### 落地边界 + +- **已落地**:业务参数、页面配置、价格归属与模板站点关系、客户编号规则等核心配置对象。 +- **部分落地**:部分打印模板、通知策略等参数由统一平台或外部渠道参数共同承载,营收域仅保留业务侧映射。 +- **文档先行**:参数灰度发布、多版本并行生效等高级治理能力当前仅保留设计语义,不宣称为独立实现模块。 diff --git a/docs/design/04_Appendix/Archive/08_Formal_Doc_Snapshots/RWB-02/2026-04-03-RWB-02-01_Database_Design.md b/docs/design/04_Appendix/Archive/08_Formal_Doc_Snapshots/RWB-02/2026-04-03-RWB-02-01_Database_Design.md new file mode 100644 index 0000000..84ff12a --- /dev/null +++ b/docs/design/04_Appendix/Archive/08_Formal_Doc_Snapshots/RWB-02/2026-04-03-RWB-02-01_Database_Design.md @@ -0,0 +1,2082 @@ +--- +doc_id: TC-01-DB +doc_role: master_document +authority: primary +scope: 数据库设计 +source_of_truth: true +last_reviewed: 2026-03-12 +retrieval_priority: P0 +--- + +# 福建水务营收系统数据库设计说明书 + +## 章节导航(精简) + +- [前言](#sec-preface) +- [外部设计](#sec-external-design) +- [数据库设计说明](#sec-database-design-note) +- [表结构设计](#sec-table-design) +- [METER/INST 专题表边界](#sec-meter-inst-topic) +- [移动端表设计优化说明](#sec-mobile-table-optimization) +- [视图的设计](#sec-view-design) +- [索引设计与性能优化](#sec-index-performance) +- [安全保密设计](#sec-security-design) + +| 文件状态: | 文档密级: | 公开 | +| :--- | :--- | :--- | +| 【 】草稿 | | | +| 【 】修改稿 | | | +| 【√】正式发布 | | | +| | **当前版本:** | **V1.6** | +| | **作者:** | **唐伟杰** | +| | **完成日期:** | **2025-08-01** | + +## 版本历史 + +| **日期** | **版本号** | **作者** | **备注** | +| :--- | :--- | :--- | :--- | +| 2025-07-17 | V1.0 | 唐伟杰 | 初稿 | +| 2025-07-17 | V1.1 | 唐伟杰 | 根据用户要求,严格对齐SQL文件,确保所有表和字段的完整性。 | +| 2025-08-01 | V1.2 | 唐伟杰 | 1. 根据详细设计说明书调整目录结构,按6个子系统重新组织表结构。
2. 补充移动端表设计优化说明,明确移动端与Web端表复用策略。
3. 新增5个移动端特有表的详细设计,符合表设计优化原则。 | +| 2025-08-01 | V1.3 | 唐伟杰 | 数据库系统变更:将OpenGauss替换为达梦数据库 8.0+,作为主力国产数据库方案。 | +| 2025-08-01 | V1.4 | 唐伟杰 | 单点登录采用OAuth2.0协议:新增OAuth2.0相关数据表设计,包括客户端信息表、访问令牌表、刷新令牌表、授权码表。 | +| 2026-03-12 | V1.6 | 唐伟杰 | 补充旧系统历史台账迁移与只读查询口径,明确在线主模型承接范围、历史最小保留集与迁移验收对账基线。 | + + +# 前言 +本文档详细描述了福建水务营收系统的数据库设计,包括总体架构、E-R图、数据表结构、字段定义和索引策略。旨在为开发和运维人员提供清晰的数据结构参考。 + + +# 外部设计 + +- **数据库系统**: 主力采用国产数据库 **达梦数据库 8.0+**。系统设计上兼容 **MySQL 8.x** 或 **MariaDB 10.x**。 +- **数据库工具**: 使用 Navicat, DBeaver, DataGrip 等主流数据库管理工具。 +- **约定**: + - **表名**: 全部小写,单词间使用下划线 `_` 分隔。业务表以 `biz_` 开头,系统管理表以 `system_` 开头。 + - **字段名**: 全部小写,单词间使用下划线 `_` 分隔(如 `user_id`),与当前数据库主文档及主表命名口径保持一致。 + - **主键**: 统一命名为 `id`,类型为 `bigint`,自增。 + - **通用字段**: 所有表必须包含 `id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id` 字段。 + - **字符集**: 统一使用 `utf8mb4` 字符集。 + + +# 数据库设计说明 +数据库设计遵循第三范式(3NF),并采用基于`tenant_id`字段隔离的SaaS多租户架构。 + + +# 表结构设计 + +## 数据表总体概览 + +> 说明:本次重点对齐 `SYS-002` 相关数据库口径。`SYS-002` 的核心表命名已统一收敛为 `biz_*` 与 `bk_*`,并已清理旧稿中分散的历史表模型。对于旧数据字典中仍未在 backend 识别到独立实体表的对象,本文以“业务对象/处理场景”描述,不强行拆分为真实表。 + +| 模块 | 表前缀 | 主要功能 | 当前口径 | +| :--- | :--- | :--- | :--- | +| 系统公共 | `system_` | 用户、角色、权限、部门、租户、字典、日志、OAuth2 等统一平台能力 | 保持现稿 | +| SYS-002 基础配置与价格体系 | `biz_community`, `biz_company_*`, `biz_meter_*`, `biz_price_*`, `biz_template_*` | 小区、水司账户、水表参数、价格体系、调价快照、优惠方案、模板关系等 | 已按真实表对齐 | +| SYS-002 客户主数据与账户关系 | `biz_cust*`, `biz_account` | 客户主档、联系人、客户组、水表绑定、开票信息、托收/代扣关系、编号规则等 | 已按真实表对齐 | +| SYS-002 抄表开账与账单 | `biz_meter`, `biz_meter_book`, `biz_meter_read`, `biz_reading_*`, `biz_charge*` | 抄表册本、抄表状态、读数留痕、开账主单与明细 | 已按真实表对齐 | +| SYS-002 收费票据与操作留痕 | `biz_collection`, `biz_withholding`, `biz_invoice*`, `biz_operat_log*` | 收费、托收/代扣、发票、操作留痕与审计支撑 | 已按真实表对齐 | +| SYS-002 业务办理与资料 | `biz_process*`, `biz_business_*`, `biz_content*` | 业务办理流程、流转、装表资料、附件与扩展数据 | 已按真实表对齐 | +| SYS-002 银行代收与结算 | `bk_*` | 渠道路由、交易回调、代扣签约、批次、对账、结算 | 已按真实表对齐 | +| SYS-003 手机抄表 APP | `mobile_*` | 移动作业缓存、登录日志、离线任务与现场上报 | 保持现稿 | +| METER/INST 专题表 | `biz_meter_*`、`installation_*`、历史 `water_meter_*` | 表务专题与报装签章专题扩展 | 已纳入专题边界(见 `METER/INST 专题表边界`) | + +## 系统公共表 (system_*) +(基于 `sw_system_publcli.sql`) + +
+点击展开/折叠系统表详情 + +### system_dept (部门表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | nextval() | 部门id | +| name | varchar(30) | Y | | 部门名称 | +| parent_id | int8 | N | 0 | 父部门id | +| sort | int4 | N | 0 | 显示顺序 | +| leader_user_id | int8 | Y | | 负责人 | +| phone | varchar(11) | Y | | 联系电话 | +| email | varchar(50) | Y | | 邮箱 | +| type | varchar(10) | Y | | 部门类型 | +| code | varchar(50) | Y | | 部门代码 | +| status | int2 | N | | 部门状态(0正常 1停用) | +| creator | varchar(64) | Y | | 创建者 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| updater | varchar(64) | Y | | 更新者 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| deleted | int2 | N | 0 | 是否删除 | +| tenant_id | int8 | N | 0 | 租户编号 | +| longitude | numeric(10,7) | Y | | 经度 | +| latitude | numeric(10,7) | Y | | 纬度 | +| remark | varchar(500) | Y | | 备注 | + +### system_dict_data (字典数据表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | | 字典编码 | +| sort | int4 | N | 0 | 字典排序 | +| label | varchar(100) | Y | | 字典标签 | +| value | varchar(100) | Y | | 字典键值 | +| dict_type | varchar(100) | Y | | 字典类型 | +| status | int2 | N | 0 | 状态(0正常 1停用) | +| color_type | varchar(100) | Y | | 颜色类型 | +| css_class | varchar(100) | Y | | css 样式 | +| remark | varchar(500) | Y | | 备注 | +| creator | varchar(64) | Y | | 创建者 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| updater | varchar(64) | Y | | 更新者 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| deleted | int2 | N | 0 | 是否删除 | + +### system_dict_type (字典类型表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | | 字典主键 | +| name | varchar(100) | Y | | 字典名称 | +| type | varchar(100) | Y | | 字典类型 | +| status | int2 | N | 0 | 状态(0正常 1停用) | +| remark | varchar(500) | Y | | 备注 | +| creator | varchar(64) | Y | | 创建者 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| updater | varchar(64) | Y | | 更新者 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| deleted | int2 | N | 0 | 是否删除 | +| deleted_time | timestamp(6) | Y | | 删除时间 | + +### system_login_log (系统访问记录) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | | 访问ID | +| log_type | int8 | N | | 日志类型 | +| trace_id | varchar(64) | Y | | 链路追踪编号 | +| user_id | int8 | N | 0 | 用户编号 | +| user_type | int2 | N | 0 | 用户类型 | +| username | varchar(50) | Y | | 用户账号 | +| result | int2 | N | | 登陆结果 | +| user_ip | varchar(50) | N | | 用户 IP | +| user_agent | varchar(512) | N | | 浏览器 UA | +| creator | varchar(64) | Y | | 创建者 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| updater | varchar(64) | Y | | 更新者 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| deleted | int2 | N | 0 | 是否删除 | +| tenant_id | int8 | N | 0 | 租户编号 | + +### system_mail_account (邮箱账号表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | | 主键 | +| mail | varchar(255) | N | | 邮箱 | +| username | varchar(255) | N | | 用户名 | +| password | varchar(255) | N | | 密码 | +| host | varchar(255) | N | | SMTP 服务器域名 | +| port | int4 | N | | SMTP 服务器端口 | +| ssl_enable | bool | N | false | 是否开启 SSL | +| starttls_enable | bool | N | false | 是否开启 STARTTLS | +| creator | varchar(64) | Y | | 创建者 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| updater | varchar(64) | Y | | 更新者 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| deleted | int2 | N | 0 | 是否删除 | + +### system_mail_log (邮件日志表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | | 编号 | +| user_id | int8 | Y | | 用户编号 | +| user_type | int2 | Y | | 用户类型 | +| to_mail | varchar(255) | N | | 接收邮箱地址 | +| account_id | int8 | N | | 邮箱账号编号 | +| from_mail | varchar(255) | N | | 发送邮箱地址 | +| template_id | int8 | N | | 模板编号 | +| template_code | varchar(63) | N | | 模板编码 | +| template_nickname | varchar(255) | Y | | 模版发送人名称 | +| template_title | varchar(255) | N | | 邮件标题 | +| template_content | varchar(10240) | N | | 邮件内容 | +| template_params | varchar(255) | N | | 邮件参数 | +| send_status | int2 | N | 0 | 发送状态 | +| send_time | timestamp(6) | Y | | 发送时间 | +| send_message_id | varchar(255) | Y | | 发送返回的消息 ID | +| send_exception | varchar(4096) | Y | | 发送异常 | +| creator | varchar(64) | Y | | 创建者 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| updater | varchar(64) | Y | | 更新者 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| deleted | int2 | N | 0 | 是否删除 | + +### system_mail_template (邮件模版表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | | 编号 | +| name | varchar(63) | N | | 模板名称 | +| code | varchar(63) | N | | 模板编码 | +| account_id | int8 | N | | 发送的邮箱账号编号 | +| nickname | varchar(255) | Y | | 发送人名称 | +| title | varchar(255) | N | | 模板标题 | +| content | varchar(10240) | N | | 模板内容 | +| params | varchar(255) | N | | 参数数组 | +| status | int2 | N | | 开启状态 | +| remark | varchar(255) | Y | | 备注 | +| creator | varchar(64) | Y | | 创建者 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| updater | varchar(64) | Y | | 更新者 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| deleted | int2 | N | 0 | 是否删除 | + +### system_users (用户表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | | 用户ID | +| username | varchar(30) | N | | 用户账号 | +| password | varchar(100) | N | | 密码 | +| nickname | varchar(30) | N | | 用户昵称 | +| remark | varchar(500) | Y | | 备注 | +| dept_id | int8 | Y | | 部门ID | +| post_ids | varchar(255) | Y | | 岗位编号数组 | +| email | varchar(50) | Y | | 用户邮箱 | +| mobile | varchar(11) | Y | | 手机号码 | +| sex | int2 | Y | | 用户性别 | +| avatar | varchar(512) | Y | | 头像地址 | +| status | int2 | N | | 帐号状态(0正常 1停用) | +| login_ip | varchar(50) | Y | | 最后登录IP | +| login_date | timestamp(6) | Y | | 最后登录时间 | +| creator | varchar(64) | Y | | 创建者 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| updater | varchar(64) | Y | | 更新者 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| deleted | int2 | N | 0 | 是否删除 | +| tenant_id | int8 | N | 0 | 租户编号 | + +### system_role (角色信息表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | | 角色ID | +| name | varchar(30) | N | | 角色名称 | +| code | varchar(100) | N | | 角色权限字符串 | +| sort | int4 | N | | 显示顺序 | +| data_scope | int2 | N | 1 | 数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限) | +| data_scope_dept_ids | varchar(500) | N | | 数据范围(指定部门数组) | +| status | int2 | N | | 角色状态(0正常 1停用) | +| type | int2 | N | | 角色类型 | +| remark | varchar(500) | Y | | 备注 | +| creator | varchar(64) | Y | | 创建者 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| updater | varchar(64) | Y | | 更新者 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| deleted | int2 | N | 0 | 是否删除 | +| tenant_id | int8 | N | 0 | 租户编号 | + +### system_menu (菜单权限表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | | 菜单ID | +| name | varchar(50) | N | | 菜单名称 | +| permission | varchar(100) | N | | 权限标识 | +| type | int2 | N | | 菜单类型 | +| sort | int4 | N | 0 | 显示顺序 | +| parent_id | int8 | N | 0 | 父菜单ID | +| path | varchar(200) | Y | | 路由地址 | +| icon | varchar(100) | Y | | 菜单图标 | +| component | varchar(255) | Y | | 组件路径 | +| component_name | varchar(255) | Y | | 组件名 | +| status | int2 | N | | 菜单状态 | +| visible | bool | N | true | 是否可见 | +| keep_alive | bool | N | true | 是否缓存 | +| always_show | bool | N | true | 是否总是显示 | +| creator | varchar(64) | Y | | 创建者 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| updater | varchar(64) | Y | | 更新者 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| deleted | int2 | N | 0 | 是否删除 | + +### system_tenant (租户表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | | 租户编号 | +| name | varchar(30) | N | | 租户名 | +| contact_user_id | int8 | Y | | 联系人的用户编号 | +| contact_name | varchar(30) | N | | 联系人 | +| contact_mobile | varchar(500) | Y | | 联系手机 | +| status | int2 | N | | 租户状态(0正常 1停用) | +| website | varchar(256) | Y | | 绑定域名 | +| package_id | int8 | N | | 租户套餐编号 | +| expire_time | timestamp(6) | N | | 过期时间 | +| account_count | int4 | N | | 账号数量 | +| creator | varchar(64) | Y | | 创建者 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| updater | varchar(64) | Y | | 更新者 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| deleted | int2 | N | 0 | 是否删除 | + +### system_user_session (用户会话表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | nextval() | 会话ID | +| user_id | int8 | N | | 用户ID | +| session_id | varchar(100) | N | | 会话标识 | +| token | varchar(500) | N | | 访问令牌 | +| refresh_token | varchar(500) | Y | | 刷新令牌 | +| login_ip | varchar(50) | N | | 登录IP | +| login_location | varchar(100) | Y | | 登录地点 | +| user_agent | varchar(500) | Y | | 用户代理 | +| session_timeout | int4 | N | 1800 | 会话超时时间(秒) | +| last_access_time | timestamp(6) | N | pg_systimestamp() | 最后访问时间 | +| is_active | int2 | N | 1 | 是否活跃:0-否,1-是 | +| logout_time | timestamp(6) | Y | | 登出时间 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| deleted | int2 | N | 0 | 是否删除 | +| tenant_id | int8 | N | 0 | 租户编号 | + +### system_user_role (用户角色关联表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | nextval() | 主键 | +| user_id | int8 | N | | 用户ID | +| role_id | int8 | N | | 角色ID | +| creator | varchar(64) | Y | | 创建者 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| updater | varchar(64) | Y | | 更新者 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| deleted | int2 | N | 0 | 是否删除 | +| tenant_id | int8 | N | 0 | 租户编号 | + +### system_role_menu (角色菜单关联表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | nextval() | 主键 | +| role_id | int8 | N | | 角色ID | +| menu_id | int8 | N | | 菜单ID | +| creator | varchar(64) | Y | | 创建者 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| updater | varchar(64) | Y | | 更新者 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| deleted | int2 | N | 0 | 是否删除 | +| tenant_id | int8 | N | 0 | 租户编号 | + +
+ +## 子系统1: 统一平台数据表 + +统一平台主要负责系统基础功能,包括用户管理、权限管理、部门管理等。这些表主要为system_*系列,已在上一节详细描述。 + +### OAuth2.0单点登录相关表 + +为支持OAuth2.0协议的单点登录功能,系统新增以下OAuth2.0相关数据表: + +
+点击展开/折叠OAuth2.0表详情 + +### system_oauth2_client (OAuth2客户端表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | | 编号 | +| client_id | varchar(255) | N | | 客户端编号 | +| secret | varchar(255) | N | | 客户端密钥 | +| name | varchar(255) | N | | 应用名 | +| logo | varchar(255) | N | | 应用图标 | +| description | varchar(255) | Y | | 应用描述 | +| status | int2 | N | | 状态 | +| access_token_validity_seconds | int4 | N | | 访问令牌的有效期 | +| refresh_token_validity_seconds | int4 | N | | 刷新令牌的有效期 | +| redirect_uris | varchar(255) | N | | 可重定向的 URI 地址 | +| authorized_grant_types | varchar(255) | N | | 授权类型 | +| scopes | varchar(255) | Y | | 授权范围 | +| auto_approve_scopes | varchar(255) | Y | | 自动通过的授权范围 | +| authorities | varchar(255) | Y | | 权限 | +| resource_ids | varchar(255) | Y | | 资源 | +| additional_information | varchar(4096) | Y | | 附加信息 | +| creator | varchar(64) | Y | | 创建者 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| updater | varchar(64) | Y | | 更新者 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| deleted | int2 | N | 0 | 是否删除 | + +### system_oauth2_access_token (OAuth2访问令牌表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | | 编号 | +| user_id | int8 | N | | 用户编号 | +| user_type | int2 | N | | 用户类型 | +| user_info | varchar(512) | N | | 用户信息 | +| access_token | varchar(255) | N | | 访问令牌 | +| refresh_token | varchar(32) | N | | 刷新令牌 | +| client_id | varchar(255) | N | | 客户端编号 | +| scopes | varchar(255) | Y | | 授权范围 | +| expires_time | timestamp(6) | N | | 过期时间 | +| creator | varchar(64) | Y | | 创建者 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| updater | varchar(64) | Y | | 更新者 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| deleted | int2 | N | 0 | 是否删除 | +| tenant_id | int8 | N | 0 | 租户编号 | + +### system_oauth2_refresh_token (OAuth2刷新令牌表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | | 编号 | +| user_id | int8 | N | | 用户编号 | +| refresh_token | varchar(32) | N | | 刷新令牌 | +| user_type | int2 | N | | 用户类型 | +| client_id | varchar(255) | N | | 客户端编号 | +| scopes | varchar(255) | Y | | 授权范围 | +| expires_time | timestamp(6) | N | | 过期时间 | +| creator | varchar(64) | Y | | 创建者 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| updater | varchar(64) | Y | | 更新者 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| deleted | int2 | N | 0 | 是否删除 | +| tenant_id | int8 | N | 0 | 租户编号 | + +### system_oauth2_code (OAuth2授权码表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | | 编号 | +| user_id | int8 | N | | 用户编号 | +| user_type | int2 | N | | 用户类型 | +| code | varchar(32) | N | | 授权码 | +| client_id | varchar(255) | N | | 客户端编号 | +| scopes | varchar(255) | Y | | 授权范围 | +| expires_time | timestamp(6) | N | | 过期时间 | +| redirect_uri | varchar(255) | Y | | 可重定向的 URI 地址 | +| state | varchar(255) | Y | | 状态 | +| creator | varchar(64) | Y | | 创建者 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| updater | varchar(64) | Y | | 更新者 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| deleted | int2 | N | 0 | 是否删除 | +| tenant_id | int8 | N | 0 | 租户编号 | + +### system_oauth2_approve (OAuth2批准表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | | 编号 | +| user_id | int8 | N | | 用户编号 | +| user_type | int2 | N | | 用户类型 | +| client_id | varchar(255) | N | | 客户端编号 | +| scope | varchar(255) | Y | | 授权范围 | +| approved | bool | N | false | 是否接受 | +| expires_time | timestamp(6) | N | | 过期时间 | +| creator | varchar(64) | Y | | 创建者 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| updater | varchar(64) | Y | | 更新者 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| deleted | int2 | N | 0 | 是否删除 | +| tenant_id | int8 | N | 0 | 租户编号 | + +
+ +## 子系统2: 营收系统数据表 + +营收系统是核心业务系统,包括客户管理、抄表管理、账务管理、发票管理等核心业务功能。 + +
+点击展开/折叠营收系统表详情 + +### biz_community (所属小区表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | nextval() | 主键 | +| name | varchar(200) | N | | 小区名称 | +| code | varchar(100) | N | | 小区代码 | +| address | varchar(500) | Y | | 小区地址 | +| contact_number | varchar(100) | Y | | 联系号码 | +| dept_code | varchar(50) | N | | 部门代码,关联系统部门表 | +| parent_id | int8 | Y | | 父级小区id,支持小区层级管理 | +| ancestor_list | varchar(1000) | Y | | 祖级列表,格式:1,2,3表示祖级小区id列表 | +| sort | int4 | N | 0 | 排序 | +| remark | varchar(500) | Y | | 备注 | +| status | int2 | N | 0 | 状态:0-否,1-是 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| creator | varchar(100) | Y | | 创建人id | +| updater | varchar(100) | Y | | 更新人id | +| deleted | int2 | N | 0 | 是否删除 | +| tenant_id | int8 | N | 0 | 租户id | + +### system_user_form_config (用户表单字段配置表-标准) + +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | nextval() | 主键ID | +| obj_id | int8 | Y | | 对象ID(用户id/角色id等) | +| config_type | int2 | N | | 配置类型:1-个人配置,2-角色配置 | +| code | varchar(100) | N | | 表格标识/模版号(与菜单或功能标识关联) | +| column_key | varchar(100) | N | | 列字段标识 | +| column_title | varchar(100) | Y | | 自定义列标题 | +| column_width | int4 | Y | | 列宽度 | +| is_visible | int2 | N | 0 | 是否显示:0-显示,1-隐藏 | +| is_printable | int2 | N | 0 | 是否可打印:0-是,1-否 | +| sort_order | int4 | N | 0 | 排序序号 | +| creator | varchar(64) | Y | | 创建人 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| updater | varchar(64) | Y | | 更新人 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| deleted | int2 | N | 0 | 是否删除 | +| tenant_id | int8 | N | 0 | 租户编号 | + +### biz_company_account (水司账户表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | nextval() | 主键 | +| account_name | varchar(200) | N | | 账户名称 | +| account_address | varchar(500) | Y | | 账户地址 | +| bank_name | varchar(200) | N | | 开户行名称 | +| bank_code | varchar(100) | N | | 开户行代码 | +| bank_account | varchar(100) | N | | 开户行账户 | +| remark | varchar(500) | Y | | 备注 | +| status | int2 | N | 0 | 状态:0-否,1-是 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| creator | varchar(100) | Y | | 创建人id | +| updater | varchar(100) | Y | | 更新人id | +| deleted | int2 | N | 0 | 是否删除 | +| tenant_id | int8 | N | 0 | 租户id | + +### biz_cost_component (费用组成表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | nextval() | 主键 | +| name | varchar(100) | Y | | 费用名称 | +| code | varchar(100) | N | | 费用代码 | +| penalty_coefficient | numeric(10,4) | Y | | 违约金系数,违约金计算系数,默认为0表示不收取违约金 | +| zero_usage_calculation | int2 | N | 0 | 零用量是否计算,0-不计算,1-计算 | +| sort | int4 | N | 0 | 排序 | +| remark | varchar(500) | Y | | 备注 | +| status | int2 | N | 0 | 状态:0-否,1-是 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| creator | varchar(100) | Y | | 创建人id | +| updater | varchar(100) | Y | | 更新人id | +| deleted | int2 | N | 0 | 是否删除 | +| tenant_id | int8 | N | 0 | 租户id | + +### biz_dept_account_rel (部门和水司账户关系表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | nextval() | 主键 | +| dept_code | varchar(50) | N | | 部门代码,关联系统部门表 | +| account_id | int8 | N | | 水司账户id,关联水司账户表 | +| remark | varchar(500) | Y | | 备注 | +| status | int2 | N | 0 | 状态:0-否,1-是 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| creator | varchar(100) | Y | | 创建人id | +| updater | varchar(100) | Y | | 更新人id | +| deleted | int2 | N | 0 | 是否删除 | +| tenant_id | int8 | N | 0 | 租户id | + +### biz_meter_caliber (水表口径表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | nextval() | 主键 | +| name | varchar(100) | Y | | 口径名称 | +| code | varchar(100) | N | | 口径代码 | +| value | numeric(10,2) | Y | | 口径值(单位:毫米) | +| check_period | int4 | Y | | 强检周期(单位:年) | +| replace_period | int4 | Y | | 定换周期(单位:年) | +| high_coefficient | numeric(10,4) | Y | | 量高系数,抄表量高提醒系数 | +| low_coefficient | numeric(10,4) | Y | | 量低系数,抄表量低提醒系数 | +| remark | varchar(500) | Y | | 备注 | +| status | int2 | N | 0 | 状态:0-否,1-是 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| creator | varchar(100) | Y | | 创建人id | +| updater | varchar(100) | Y | | 更新人id | +| deleted | int2 | N | 0 | 是否删除 | +| tenant_id | int8 | N | 0 | 租户id | + +### biz_meter_maker (水表厂家表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | nextval() | 主键 | +| name | varchar(100) | Y | | 厂家名称 | +| code | varchar(100) | N | | 厂家代码 | +| recharge_type | varchar(10) | Y | | 充值类型 | +| address | varchar(500) | Y | | 地址 | +| contact | varchar(100) | Y | | 联系人 | +| contact_number | varchar(100) | Y | | 联系号码 | +| remark | varchar(500) | Y | | 备注 | +| status | int2 | N | 0 | 状态:0-否,1-是 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| creator | varchar(100) | Y | | 创建人id | +| updater | varchar(100) | Y | | 更新人id | +| deleted | int2 | N | 0 | 是否删除 | +| tenant_id | int8 | N | 0 | 租户id | + +### biz_meter_model (水表型号表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | nextval() | 主键 | +| maker_code | varchar(100) | N | | 厂家代码,关联水表厂家表 | +| name | varchar(100) | Y | | 型号名称 | +| code | varchar(100) | N | | 型号代码 | +| caliber_range | varchar(200) | Y | | 口径范围,如:DN15-DN200 | +| remark | varchar(500) | Y | | 备注 | +| status | int2 | N | 0 | 状态:0-否,1-是 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| creator | varchar(100) | Y | | 创建人id | +| updater | varchar(100) | Y | | 更新人id | +| deleted | int2 | N | 0 | 是否删除 | +| tenant_id | int8 | N | 0 | 租户id | + +### biz_meter_range (水表量程表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | nextval() | 主键 | +| name | varchar(100) | Y | | 量程名称 | +| code | varchar(100) | N | | 量程代码 | +| value | numeric(15,3) | Y | | 量程值 | +| remark | varchar(500) | Y | | 备注 | +| status | int2 | N | 0 | 状态:0-否,1-是 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| creator | varchar(100) | Y | | 创建人id | +| updater | varchar(100) | Y | | 更新人id | +| deleted | int2 | N | 0 | 是否删除 | +| tenant_id | int8 | N | 0 | 租户id | + +### biz_price_category (水价归属表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | nextval() | 主键 | +| name | varchar(100) | Y | | 归属名称 | +| code | varchar(100) | N | | 归属代码 | +| parent_id | int8 | Y | | 父级归属id | +| ancestor_list | varchar(1000) | Y | | 祖级列表,格式:1,2,3表示祖级归属id列表 | +| sort | int4 | N | 0 | 排序 | +| remark | varchar(500) | Y | | 备注 | +| status | int2 | N | 0 | 状态:0-否,1-是 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| creator | varchar(100) | Y | | 创建人id | +| updater | varchar(100) | Y | | 更新人id | +| deleted | int2 | N | 0 | 是否删除 | +| tenant_id | int8 | N | 0 | 租户id | + +### biz_price_adjustment_history (水价调整历史表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | nextval() | 主键 | +| adjustment_id | int8 | N | | 调整id,关联水价调整表 | +| before_value | numeric(15,4) | Y | | 调整前价格 | +| after_value | numeric(15,4) | Y | | 调整后价格 | +| adjustment_reason | varchar(500) | Y | | 调整原因 | +| effective_date | timestamp(6) | Y | | 生效日期 | +| remark | varchar(500) | Y | | 备注 | +| status | int2 | N | 0 | 状态:0-否,1-是 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| creator | varchar(100) | Y | | 创建人id | +| updater | varchar(100) | Y | | 更新人id | +| deleted | int2 | N | 0 | 是否删除 | +| tenant_id | int8 | N | 0 | 租户id | + +### biz_price_cost_adjustment (价格成本调整表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | nextval() | 主键 | +| cost_component_code | varchar(100) | N | | 费用组成代码,关联费用组成表 | +| price_category_code | varchar(100) | N | | 价格归属代码,关联价格归属表 | +| price_value | numeric(15,4) | Y | | 价格值 | +| effective_date | timestamp(6) | Y | | 生效日期 | +| expire_date | timestamp(6) | Y | | 失效日期 | +| remark | varchar(500) | Y | | 备注 | +| status | int2 | N | 0 | 状态:0-否,1-是 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| creator | varchar(100) | Y | | 创建人id | +| updater | varchar(100) | Y | | 更新人id | +| deleted | int2 | N | 0 | 是否删除 | +| tenant_id | int8 | N | 0 | 租户id | + +### biz_price_dept_rel (价格部门关系表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | nextval() | 主键 | +| price_category_code | varchar(100) | N | | 价格归属代码,关联价格归属表 | +| dept_code | varchar(50) | N | | 部门代码,关联系统部门表 | +| remark | varchar(500) | Y | | 备注 | +| status | int2 | N | 0 | 状态:0-否,1-是 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| creator | varchar(100) | Y | | 创建人id | +| updater | varchar(100) | Y | | 更新人id | +| deleted | int2 | N | 0 | 是否删除 | +| tenant_id | int8 | N | 0 | 租户id | + +### biz_price_discount_cost (价格折扣成本表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | nextval() | 主键 | +| scheme_id | int8 | N | | 折扣方案id,关联价格折扣方案表 | +| cost_component_code | varchar(100) | N | | 费用组成代码,关联费用组成表 | +| discount_rate | numeric(10,4) | Y | | 折扣率,0-1之间的小数 | +| remark | varchar(500) | Y | | 备注 | +| status | int2 | N | 0 | 状态:0-否,1-是 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| creator | varchar(100) | Y | | 创建人id | +| updater | varchar(100) | Y | | 更新人id | +| deleted | int2 | N | 0 | 是否删除 | +| tenant_id | int8 | N | 0 | 租户id | + +### biz_price_discount_scheme (价格折扣方案表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | nextval() | 主键 | +| name | varchar(100) | Y | | 方案名称 | +| code | varchar(100) | N | | 方案代码 | +| price_category_code | varchar(100) | N | | 价格归属代码,关联价格归属表 | +| discount_type | varchar(20) | Y | | 折扣类型,如:百分比、固定金额等 | +| effective_date | timestamp(6) | Y | | 生效日期 | +| expire_date | timestamp(6) | Y | | 失效日期 | +| remark | varchar(500) | Y | | 备注 | +| status | int2 | N | 0 | 状态:0-否,1-是 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| creator | varchar(100) | Y | | 创建人id | +| updater | varchar(100) | Y | | 更新人id | +| deleted | int2 | N | 0 | 是否删除 | +| tenant_id | int8 | N | 0 | 租户id | + +### biz_price_discount_tier (价格折扣阶梯表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | nextval() | 主键 | +| scheme_id | int8 | N | | 折扣方案id,关联价格折扣方案表 | +| tier_level | int4 | Y | | 阶梯级别 | +| start_value | numeric(15,3) | Y | | 起始值 | +| end_value | numeric(15,3) | Y | | 结束值 | +| discount_rate | numeric(10,4) | Y | | 折扣率 | +| remark | varchar(500) | Y | | 备注 | +| status | int2 | N | 0 | 状态:0-否,1-是 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| creator | varchar(100) | Y | | 创建人id | +| updater | varchar(100) | Y | | 更新人id | +| deleted | int2 | N | 0 | 是否删除 | +| tenant_id | int8 | N | 0 | 租户id | + +### biz_price_tier_adjustment (价格阶梯调整表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | nextval() | 主键 | +| cost_component_code | varchar(100) | N | | 费用组成代码,关联费用组成表 | +| price_category_code | varchar(100) | N | | 价格归属代码,关联价格归属表 | +| tier_level | int4 | Y | | 阶梯级别 | +| start_value | numeric(15,3) | Y | | 起始值 | +| end_value | numeric(15,3) | Y | | 结束值 | +| price_value | numeric(15,4) | Y | | 价格值 | +| effective_date | timestamp(6) | Y | | 生效日期 | +| expire_date | timestamp(6) | Y | | 失效日期 | +| remark | varchar(500) | Y | | 备注 | +| status | int2 | N | 0 | 状态:0-否,1-是 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| creator | varchar(100) | Y | | 创建人id | +| updater | varchar(100) | Y | | 更新人id | +| deleted | int2 | N | 0 | 是否删除 | +| tenant_id | int8 | N | 0 | 租户id | + +### biz_price_adjustment_snap (水价调整快照表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | nextval() | 主键 | +| code | int4 | N | | 快照编号/版本号,1->2->3递增 | +| effective_date | timestamp(6) | N | | 生效日期 | +| expiry_date | timestamp(6) | Y | | 失效日期,为空表示长期有效 | +| adjuster | varchar(100) | Y | | 调价人 | +| remark | varchar(500) | Y | | 备注 | +| status | int2 | N | 0 | 状态:0-否,1-是 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间/调价时间 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| creator | varchar(100) | Y | | 创建人id | +| updater | varchar(100) | Y | | 更新人id | +| deleted | int2 | N | 0 | 是否删除 | +| tenant_id | int8 | N | 0 | 租户id | + +### biz_price_template (水价调整模版表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | nextval() | 主键 | +| name | varchar(100) | Y | | 用水性质名称 | +| code | varchar(100) | N | | 模版代码/简号 | +| price_category_code | varchar(100) | N | | 水价归属代码,关联价格归属表 | +| adjustment_snap_code | varchar(100) | N | | 调价快照code,关联水价调整快照表 | +| meter_start | int4 | Y | | 起开量 | +| sort | int4 | N | 0 | 排序 | +| remark | varchar(500) | Y | | 备注 | +| status | int2 | N | 0 | 状态:0-否,1-是 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| creator | varchar(100) | Y | | 创建人id | +| updater | varchar(100) | Y | | 更新人id | +| deleted | int2 | N | 0 | 是否删除 | +| tenant_id | int8 | N | 0 | 租户id | + +### biz_template_dept_rel (模版部门关系表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | nextval() | 主键 | +| dept_code | varchar(50) | N | | 部门代码,关联系统部门表 | +| template_code | varchar(100) | N | | 水价调整模版代码 | +| adjustment_snap_code | varchar(100) | N | | 调价快照code | +| is_default | int2 | N | 0 | 是否默认:0-否,1-是 | +| remark | varchar(500) | Y | | 备注 | +| status | int2 | N | 0 | 状态:0-否,1-是 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| creator | varchar(100) | Y | | 创建人id | +| updater | varchar(100) | Y | | 更新人id | +| deleted | int2 | N | 0 | 是否删除 | +| tenant_id | int8 | N | 0 | 租户id | + +### biz_price_tier_adjustment (水价阶梯调整表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | nextval() | 主键 | +| cost_adjustment_id | int8 | N | | 水价费用调整id | +| cost_component_code | varchar(100) | N | | 费用组成代码 | +| tier_level | int4 | N | 0 | 阶梯级别,如1、2、3等 | +| start_volume | numeric(15,3) | Y | | 开始水量,单位:立方米 | +| end_volume | numeric(15,3) | Y | | 结束水量,为空表示无上限 | +| price | numeric(10,4) | N | | 价格,单位:元/立方米或元 | +| volume_coefficient | numeric(10,4) | N | 1 | 水量系数,用于特殊计算场景 | +| sort | int4 | N | 0 | 排序 | +| remark | varchar(500) | Y | | 备注 | +| status | int2 | N | 0 | 状态:0-否,1-是 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| creator | varchar(100) | Y | | 创建人id | +| updater | varchar(100) | Y | | 更新人id | +| deleted | int2 | N | 0 | 是否删除 | +| tenant_id | int8 | N | 0 | 租户id | + +### biz_price_discount_scheme (水价优惠方案表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | nextval() | 主键 | +| scheme_name | varchar(200) | N | | 方案名称,如:居民用户优惠方案2024 | +| scheme_code | varchar(100) | N | | 方案代码 | +| template_code | varchar(100) | N | | 水价模版代码 | +| discount_type | int4 | N | | 优惠方式:1-按水量,2-按比例 | +| effective_date | date | N | | 生效日期 | +| expiry_date | date | Y | | 失效日期,为空表示长期有效 | +| scheme_description | varchar(1000) | Y | | 方案描述 | +| sort | int4 | N | 0 | 排序 | +| remark | varchar(500) | Y | | 备注 | +| status | int2 | N | 0 | 状态:0-否,1-是 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| creator | varchar(100) | Y | | 创建人id | +| updater | varchar(100) | Y | | 更新人id | +| deleted | int2 | N | 0 | 是否删除 | +| tenant_id | int8 | N | 0 | 租户id | + +### biz_price_discount_tier (水价优惠阶梯表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | nextval() | 主键 | +| scheme_id | int8 | N | | 优惠方案id | +| tier_level | int4 | N | 0 | 阶梯级别,如1、2、3等 | +| start_volume | numeric(15,3) | Y | | 开始水量,单位:立方米 | +| end_volume | numeric(15,3) | Y | | 结束水量,为空表示无上限 | +| include_in_tier | int2 | N | 1 | 是否计入阶梯:0-不计入,1-计入 | +| sort | int4 | N | 0 | 排序 | +| remark | varchar(500) | Y | | 备注 | +| status | int2 | N | 0 | 状态:0-否,1-是 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| creator | varchar(100) | Y | | 创建人id | +| updater | varchar(100) | Y | | 更新人id | +| deleted | int2 | N | 0 | 是否删除 | +| tenant_id | int8 | N | 0 | 租户id | + +### biz_price_discount_cost (水价优惠费用表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | nextval() | 主键 | +| tier_id | int8 | N | | 优惠阶梯id | +| cost_component_code | varchar(100) | N | | 费用组成代码 | +| discount_price | numeric(10,4) | N | | 优惠价格,单位:元/立方米或元 | +| sort | int4 | N | 0 | 排序 | +| remark | varchar(500) | Y | | 备注 | +| status | int2 | N | 0 | 状态:0-否,1-是 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| creator | varchar(100) | Y | | 创建人id | +| updater | varchar(100) | Y | | 更新人id | +| deleted | int2 | N | 0 | 是否删除 | +| tenant_id | int8 | N | 0 | 租户id | + +## SYS-002 客户与账户关系表 (`biz_cust*` / `biz_account`) + +> 说明:以下内容按 `sql/lhc_数据库设计.md`、`docs/guides/BACKEND_TABLE_MAPPING.md` 与当前 backend 真实表名进行整编,字段以“数据库专项设计阶段需重点关注的核心字段”为主,不再延续旧稿中的 `customer_*` 系列表命名。 + +### biz_cust (客户主档表) +| 字段名 | 说明 | +| :--- | :--- | +| `id` | 主键 | +| `code` | 客户编号 | +| `name` | 客户名称 | +| `cust_type` | 客户类型 | +| `id_type` / `id_no` | 证件类型 / 证件号码 | +| `mobile` / `address` | 联系电话 / 地址 | +| `dept_code` | 所属营业部门 | +| `status` | 客户状态 | +| `tenant_id` | 租户编号 | + +### biz_account (客户账户表) +| 字段名 | 说明 | +| :--- | :--- | +| `id` | 主键 | +| `code` | 账户编号 | +| `cust_id` | 客户主档 ID | +| `balance` | 账户余额 | +| `arrears_amount` | 欠费金额 | +| `account_status` | 账户状态 | +| `tenant_id` | 租户编号 | + +### biz_cust_contact (客户联系人表) +| 字段名 | 说明 | +| :--- | :--- | +| `id` | 主键 | +| `cust_id` | 客户主档 ID | +| `name` | 联系人姓名 | +| `mobile` | 联系电话 | +| `contact_type` | 联系人类型 | +| `is_default` | 是否默认联系人 | + +### biz_cust_group (客户分组表) +| 字段名 | 说明 | +| :--- | :--- | +| `id` | 主键 | +| `code` | 分组编码 | +| `name` | 分组名称 | +| `parent_id` | 上级分组 | +| `status` | 状态 | + +### biz_cust_meter (客户与水表关系表) +| 字段名 | 说明 | +| :--- | :--- | +| `id` | 主键 | +| `cust_id` | 客户主档 ID | +| `meter_id` | 水表主档 ID | +| `bind_type` | 绑定类型 | +| `is_main` | 是否主表 | +| `status` | 关系状态 | + +### biz_cust_invoice (客户开票信息表) +| 字段名 | 说明 | +| :--- | :--- | +| `id` | 主键 | +| `cust_id` | 客户主档 ID | +| `invoice_title` | 开票抬头 | +| `tax_no` | 纳税人识别号 | +| `email` | 发票接收邮箱 | +| `mobile` | 联系手机号 | + +### biz_cust_app_binds (客户应用绑定表) +| 字段名 | 说明 | +| :--- | :--- | +| `id` | 主键 | +| `cust_id` | 客户主档 ID | +| `app_type` | 应用类型 | +| `app_user_id` | 外部应用用户标识 | +| `status` | 绑定状态 | + +### biz_cust_collection_rel / biz_cust_withholding_rel (托收/代扣关系表) +| 表名 | 关键字段 | 说明 | +| :--- | :--- | :--- | +| `biz_cust_collection_rel` | `cust_id`, `collection_id`, `status` | 客户与托收关系 | +| `biz_cust_withholding_rel` | `cust_id`, `withholding_id`, `status` | 客户与代扣关系 | + +### biz_cust_water_use_scheme / biz_cust_water_scheme_rel (用水方案关系表) +| 表名 | 关键字段 | 说明 | +| :--- | :--- | :--- | +| `biz_cust_water_use_scheme` | `cust_id`, `scheme_code`, `effective_date` | 客户用水方案 | +| `biz_cust_water_scheme_rel` | `cust_id`, `template_code`, `status` | 客户与价格模板关系 | + +### biz_cust_no_rule / biz_cust_hub_marks (客户编号与集抄标识表) +| 表名 | 关键字段 | 说明 | +| :--- | :--- | :--- | +| `biz_cust_no_rule` | `rule_code`, `prefix`, `dept_code`, `status` | 客户编号规则 | +| `biz_cust_hub_marks` | `cust_id`, `hub_code`, `mark_type` | 集抄/枢纽标识 | + +## SYS-002 抄表、水表与价格支撑表 (`biz_meter*` / `biz_reading_*` / `biz_price_*`) + +### biz_meter (水表主档表) +| 字段名 | 说明 | +| :--- | :--- | +| `id` | 主键 | +| `code` | 水表编号 | +| `meter_no` | 出厂表号 | +| `maker_code` / `model_code` | 厂家 / 型号 | +| `caliber_code` / `range_code` | 口径 / 量程 | +| `install_address` | 安装地址 | +| `meter_status` | 水表状态 | +| `tenant_id` | 租户编号 | + +### biz_meter_book (抄表册本表) +| 字段名 | 说明 | +| :--- | :--- | +| `id` | 主键 | +| `code` | 册本编号 | +| `name` | 册本名称 | +| `dept_code` | 所属部门 | +| `reader_user` | 抄表员 | +| `reading_cycle` | 抄表周期 | +| `status` | 册本状态 | + +### biz_meter_read (抄表任务/状态表) +| 字段名 | 说明 | +| :--- | :--- | +| `id` | 主键 | +| `book_id` | 册本 ID | +| `cust_id` | 客户 ID | +| `meter_id` | 水表 ID | +| `read_period` | 抄表期间 | +| `read_status` | 抄表状态 | +| `read_type` | 抄表方式 | + +### biz_reading_data (抄表数据表) +| 字段名 | 说明 | +| :--- | :--- | +| `id` | 主键 | +| `meter_read_id` | 抄表任务 ID | +| `last_reading` | 上次读数 | +| `current_reading` | 本次读数 | +| `water_usage` | 用水量 | +| `read_time` | 抄见时间 | +| `photo_url` | 抄表照片 | + +### biz_last_reading / biz_reading_logs (上次读数与抄表日志) +| 表名 | 关键字段 | 说明 | +| :--- | :--- | :--- | +| `biz_last_reading` | `meter_id`, `last_reading`, `last_read_time` | 水表最近有效读数 | +| `biz_reading_logs` | `meter_id`, `operate_type`, `operator`, `operate_time` | 抄表处理留痕 | + +### 价格与模板支撑表 +| 表名 | 关键字段 | 说明 | +| :--- | :--- | :--- | +| `biz_price_category` | `code`, `name`, `parent_id` | 水价归属 | +| `biz_price_template` | `code`, `price_category_code`, `adjustment_snap_code` | 水价模板 | +| `biz_price_adjustment_snap` | `code`, `effective_date`, `expiry_date` | 调价快照 | +| `biz_price_cost_adjustment` | `price_category_code`, `cost_component_code`, `price_value` | 费用调价 | +| `biz_price_tier_adjustment` | `cost_component_code`, `tier_level`, `start_volume`, `end_volume`, `price` | 阶梯价格 | +| `biz_cost_component` | `code`, `name`, `penalty_coefficient` | 费用组成 | +| `biz_water_use_scheme` | `code`, `name`, `status` | 用水方案 | +| `biz_water_use_scheme_tier` | `scheme_code`, `tier_level`, `start_volume`, `end_volume` | 用水阶梯 | +| `biz_exceed_water_use_scheme` | `scheme_code`, `exceed_type`, `price_rule` | 超计划规则 | + +## SYS-002 开账、收费与票据表 (`biz_charge*` / `biz_collection` / `biz_withholding` / `biz_invoice*`) + +### biz_charge (营业账主表) +| 字段名 | 说明 | +| :--- | :--- | +| `id` | 主键 | +| `code` | 账单编号 | +| `cust_id` | 客户 ID | +| `record_id` | 抄表记录或开账来源 ID | +| `bill_period` | 账单期间 | +| `total_amount` | 账单总金额 | +| `charge_status` | 收费状态 | +| `due_date` | 应缴日期 | + +### biz_charge_detail (营业账明细表) +| 字段名 | 说明 | +| :--- | :--- | +| `id` | 主键 | +| `charge_id` | 营业账主表 ID | +| `cost_component_code` | 费用组成代码 | +| `usage_amount` | 用量 | +| `unit_price` | 单价 | +| `detail_amount` | 明细金额 | + +#### REV-002 账单生成承接口径 + +| 对象 | 正式口径 | 承接说明 | +| :--- | :--- | :--- | +| `biz_charge` | 账单生成主结果对象 | 统一表达客户、账期、抄表/开账来源、账单总金额、收费状态与应缴日期,不单独发明新的在线账单主模型 | +| `biz_charge_detail` | 账单生成明细对象 | 统一表达费用组成、用量、单价、明细金额,与主表通过 `charge_id` 建立主明细关系 | +| `biz_price_category`、`biz_price_template`、`biz_price_adjustment_snap`、`biz_price_tier_adjustment` | 计费规则来源对象 | 用于表达价格归属、基础价格、调价快照与阶梯规则来源,支撑账单金额计算与追溯 | +| `biz_cost_component` | 费用组成定义对象 | 用于表达水费、污水费、附加费、罚款类费用等明细分类,不将费用组成直接硬编码到主表 | +| `biz_water_use_scheme`、`biz_water_use_scheme_tier`、`biz_exceed_water_use_scheme` | 计划用水与超计划规则对象 | 用于承接计划用水、超计划与阶梯类扩展规则,不额外发明平行的特殊开账规则表 | +| 历史开账记录、特殊开账 | 历史只读 / 同模型承接对象 | 统一纳入 `biz_charge`、`biz_charge_detail` 与操作留痕承接,通过来源类型、业务类型、依据说明区分,不单设“特殊开账表” | + +> REV-002 承接口径:账单生成结果统一由 `biz_charge`、`biz_charge_detail` 承接,关键规则来源继续由 `biz_price_*`、`biz_cost_component` 与计划用水相关对象提供;当价格模板、费用组成或规则关系不完整时,应按“阻断生成”口径处理。 +> +> 当前 backend 证据:`ChargeServiceImpl.generateSingleChargeWithCache` 成功路径已执行 `chargeMapper.insert(charge)`、`chargeDetailService.insertChargeDetail(detail)` 与 `updateReadingDataCheckState(readingDataId, 1)`,说明现有实现已能把按 `readingDataIds` 复核/开账的结果落入 `biz_charge`、`biz_charge_detail`。 +> +> 当前承接缺口:接口层返回仍为成功条数字符串,失败阻断主要依赖日志与布尔值,且仅支持 `ACTUAL_USAGE` 结算方式;`biz_charge` / `biz_charge_detail` 的主明细结果、失败对象范围和结构化原因尚未提升为正式 `IF-REV-005` 契约返回。 +> +> REV-004 承接口径:水量调整、金额调整、退款、冲正、坏账申请统一以 `biz_charge`、`biz_charge_detail` 作为账单主明细承接对象;当前数据库主文档不新增独立账务细表来承接一期场景。 + +### biz_collection / biz_withholding (托收与代扣主表) +| 表名 | 关键字段 | 说明 | +| :--- | :--- | :--- | +| `biz_collection` | `code`, `cust_id`, `charge_id`, `collection_status` | 托收主表 | +| `biz_withholding` | `code`, `cust_id`, `charge_id`, `withholding_status` | 代扣主表 | + +### biz_invoice / biz_invoice_taxrate (发票主表与税率表) +| 表名 | 关键字段 | 说明 | +| :--- | :--- | :--- | +| `biz_invoice` | `code`, `cust_id`, `charge_id`, `invoice_status`, `invoice_amount` | 发票主表,统一承接申请单号、账单关联、受理号、开票结果与电子票地址等核心状态 | +| `biz_invoice_taxrate` | `tax_code`, `tax_name`, `tax_rate`, `status` | 税率基础配置 | + +#### REV-005 发票承接口径 + +| 对象 | 已有字段 | 待补字段 | 仅快照/历史只读字段 | +| :--- | :--- | :--- | :--- | +| `biz_invoice` 发票申请/结果主对象 | `code`、`cust_id`、`charge_id`、`invoice_status`、`invoice_amount` | `application_no`、`sys_request_no`、`invoice_type`、`invoice_title`、`tax_no`、`email`、`mobile`、`source_channel`、`fail_reason`、`invoice_code`、`invoice_number`、`file_url`、`last_try_time`、`next_try_time`、`try_count`、`push_status`、`charge_ids_snapshot`、`charge_bind_status`、作废原因/备注、红冲原因/备注、原票/红票关联标识、作废/红冲申请来源、补偿查询/结果回写上下文 | 旧开票批次号、旧配置版本号、旧平台扩展回执 | +| `biz_cust_invoice` 客户开票信息 | `cust_id`、`invoice_title`、`tax_no`、`email`、`mobile` | 企业/个人抬头类型、默认推送方式等扩展属性按后续实现补齐 | 旧抬头版本、历史修改快照 | +| `biz_invoice_taxrate` 税率配置 | `tax_code`、`tax_name`、`tax_rate`、`status` | 税率生效区间、适用票种范围等扩展控制字段 | 旧税率版本快照 | +| 账单-发票关系快照 | 当前主模型通过 `biz_invoice` 与 `biz_charge*` 关联承接 | `charge_ids_snapshot`、账单集合来源、客户侧身份匹配结果、操作留痕标识 | 旧营业账开票关系表、旧发票明细表 | + +### biz_operat_log / biz_operat_log_detail (操作留痕表) +| 表名 | 关键字段 | 说明 | +| :--- | :--- | :--- | +| `biz_operat_log` | `biz_type`, `biz_id`, `operate_user`, `operate_time` | 业务操作主日志 | +| `biz_operat_log_detail` | `log_id`, `field_name`, `before_value`, `after_value` | 字段级变更留痕 | + +> REV-004 留痕口径:`biz_operat_log*` 统一承接账务处理的一期留痕,至少覆盖处理类型、目标账单、原交易引用、处理前后差异、原因说明、附件依据与操作人。 +> +> 边界说明:旧数据字典中的“跨周期水量、特账、红冲、已销调整、呆坏账、实时收费日志”等对象,在当前 backend 范围内未全部识别到独立实体表,数据库专项中统一按业务处理场景描述,不误写为已明确落地的真实表。 + +### 旧系统历史台账迁移与只读查询口径 + +#### 在线主模型承接范围 + +| 旧对象/旧菜单 | 当前主口径 | 承接方式 | 数据策略 | +| :--- | :--- | :--- | :--- | +| 开账记录、特殊开账 | `biz_charge`、`biz_charge_detail`、`biz_operat_log*` | 统一纳入营业账主表与明细表,特殊开账按来源类型、业务类型、依据说明留痕,不单设平行“特殊开账表” | 在线保留 | +| 柜台收费、实时收费、代收代扣 | `biz_collection`、`biz_withholding`、`bk_transaction*`、`bk_withholding_*` | 统一纳入收费主模型与渠道交易模型,柜台班结/实时收费日志按交易结果和操作留痕归并 | 在线保留 | +| 发票申请、开票结果、票据税率 | `biz_invoice`、`biz_invoice_taxrate`、`biz_cust_invoice` | 统一纳入发票主表、税率表和客户开票信息,不为旧“营业账开票表”机械复制新在线表 | 在线保留 | +| 微网厅业务字段、页面配置、微信参数 | `biz_business_types`、`biz_business_datas`、`biz_page_settings*`、`biz_parameter_settings`、`sys_wechat_app_settings` | 统一归并为业务类型、页面配置和渠道参数模型 | 在线保留 | +| 办理附件、电子档案 | `biz_content`、`biz_content_attach` | 当前新增与迁移后新增资料统一按资料主表与附件表承接 | 在线保留 | + +#### 历史只读保留范围 + +| 历史对象 | 当前正式口径 | 保留策略 | 查询要求 | +| :--- | :--- | :--- | :--- | +| 红冲记录、红冲原因、红冲前后账务快照 | 账单状态 + 账务处理场景 + 操作留痕 | 保留历史只读,不强制拆为新主库独立实体表 | 至少支持原单号、红冲单号、金额、原因、经办人、时间查询 | +| 预存退款、已销调整、价差调整、分账调整、违约金减免、呆坏账明细 | `REV-004` 账务处理业务场景 | 旧细粒度台账以历史只读方式保留;新发生业务由流程与日志承接 | 至少支持汇总、明细、状态、审批结果和关联账单查询 | +| 柜台结账、打印记录、补打记录 | 收费结果 + 打印/操作留痕 | 旧查询菜单作为历史只读能力保留,不单独建设新结账台账表 | 至少支持班次、营业所、柜员、打印类型、结账状态查询 | +| 发票明细、营业账开票关系、开票配置快照 | 发票主模型 + 历史关系快照 | 旧细表和配置快照按历史只读保留;新在线模型只保留开票必需主数据 | 至少支持发票号、账单号、开票批次、配置版本和结果状态查询 | +| 催缴记录、停水记录、预存短信记录 | 催缴/停复水/消息联动业务场景 | 旧记录菜单按历史只读保留,与 `IF-REV-013` 的任务结果、通知链路和工单处置引用分层承接,不新增同名在线主表 | 至少支持客户、账期、催缴方式、执行结果、发送对象、发送时间、关联账单、处置引用查询 | +| 水表检定、领用、出库、退库、报废单据 | `METER-003` 生命周期场景 | 当前在线主表承接水表状态,旧单据与检定证书按历史只读保留 | 至少支持表号、仓库、单据类型、检定结论、证书编号查询 | + +#### 迁移验收最低对账口径 + +| 对账主题 | 最低核对维度 | 主口径来源 | 验收要求 | +| :--- | :--- | :--- | :--- | +| 开账记录 | 客户数、账单数、账期、应收金额 | `biz_charge`、`biz_charge_detail` + 历史账单来源 | 支持按账期、营业所、客户类型汇总比对 | +| 缴费记录 | 收费笔数、实收金额、渠道、核销状态 | `biz_collection`、`bk_transaction*` | 支持按渠道、日期、营业所汇总比对 | +| 发票记录 | 开票笔数、金额、状态、票据类型 | `biz_invoice*` + 历史开票关系 | 支持按发票状态、开票日期比对 | +| 红冲与账务调整 | 调整笔数、调整金额、处理结果 | 账务处理结果 + 历史台账 | 支持汇总与单据级差异定位 | +| 催缴与停复水 | 通知笔数、执行结果、停复水状态 | `IF-REV-013` 任务结果 + 历史记录 | 支持按账期、客户、执行状态、处置引用比对 | +| 电子档案 | 附件数、附件类型、关联业务单数 | `biz_content_attach` + 历史档案目录 | 支持按业务类型、上传时间、来源系统比对 | + +#### 设计约束 + +- 不以“旧菜单一项对应一张新表”为原则,优先复用当前已确认的 `biz_*`、`bk_*` 在线主模型。 +- 对 backend 当前未识别到独立实体表的旧细粒度台账,仅写为“历史只读查询对象”,不误写为“已存在新在线表”。 +- 历史只读对象必须保留原系统关键标识(原单号、原客户号、原批次号或原附件标识)以支撑迁移验收与问题追溯。 +- 涉及历史附件、影像、高拍仪资料时,正式数据库设计只约束“资料元数据 + 文件引用”口径,不在本轮臆造新的文件表族。 +- `REV-006` 的正式结果状态按 `PENDING`、`SUCCESS`、`FAIL`、`MANUAL_VERIFIED` 四态统一,数据库设计仅约束查询与追溯口径,不反推为已存在独立催缴结果主表。 +- 停复水、复水和工单处置在本轮仅保留“关联引用 + 状态摘要 + 建链时间”三类追溯字段要求,不展开下游业务表设计。 + +## SYS-002 业务办理与资料表 (`biz_process*` / `biz_business_*` / `biz_content*`) + +| 表名 | 关键字段 | 说明 | +| :--- | :--- | :--- | +| `biz_process` | `code`, `biz_type_code`, `cust_id`, `process_status` | 业务办理流程主表 | +| `biz_process_transfer` | `process_id`, `from_user`, `to_user`, `transfer_time` | 流转/转办记录 | +| `biz_process_cust_contact` | `process_id`, `contact_name`, `mobile` | 办理过程联系人信息 | +| `biz_process_meter_install` | `process_id`, `meter_id`, `install_addr` | 装表安装信息 | +| `biz_process_invoice_modifys` | `process_id`, `invoice_id`, `modify_type` | 发票变更记录 | +| `biz_business_types` | `code`, `name`, `status` | 业务类型定义 | +| `biz_business_datas` | `biz_id`, `data_key`, `data_value` | 业务扩展数据 | +| `biz_content` | `biz_id`, `content_type`, `content_title` | 办理资料主表 | +| `biz_content_attach` | `content_id`, `file_name`, `file_url` | 办理附件表 | + +## SYS-002 银行代收与结算表 (`bk_*`) + +| 表名 | 关键字段 | 说明 | +| :--- | :--- | :--- | +| `bk_payment_channel` | `channel_code`, `channel_name`, `channel_type`, `status` | 支付渠道主表 | +| `bk_channel_api_config` | `channel_code`, `api_type`, `endpoint`, `crypto_type` | 渠道接口配置 | +| `bk_channel_route_rule` | `channel_code`, `route_type`, `priority`, `status` | 渠道路由规则 | +| `bk_channel_statistics` | `channel_code`, `stat_date`, `success_count`, `success_amount` | 渠道统计 | +| `bk_transaction` | `trade_no`, `biz_order_no`, `channel_code`, `trade_amount`, `trade_status` | 渠道交易流水 | +| `bk_transaction_callback` | `trade_no`, `callback_time`, `callback_status`, `raw_message` | 回调留痕 | +| `bk_transaction_exception` | `trade_no`, `exception_code`, `exception_desc`, `handle_status` | 异常处理 | + +> REV-004 原交易校验口径:退款、冲正场景统一依赖 `bk_transaction*` 校验原交易存在性、状态、回调结果与异常处理状态,数据库专项不再为一期新增平行退款交易表。 +| `bk_withholding_agreement` | `agreement_no`, `cust_id`, `channel_code`, `sign_status` | 代扣签约 | +| `bk_withholding_batch` | `batch_no`, `channel_code`, `batch_date`, `batch_status` | 代扣批次 | +| `bk_withholding_item` | `batch_id`, `cust_id`, `charge_id`, `item_status` | 代扣明细 | +| `bk_reconcile_batch` | `batch_no`, `channel_code`, `bill_date`, `reconcile_status` | 对账批次 | +| `bk_reconcile_diff` | `batch_id`, `trade_no`, `diff_type`, `diff_amount` | 对账差异 | +| `bk_settlement_batch` | `batch_no`, `channel_code`, `settlement_date`, `settlement_status` | 结算批次 | + +> 当前实现边界说明:`bk_*` 表族已形成较完整的对象承接口径,且签约、解约、交易流水与后台资源管理具备明确实现证据;但送盘、回盘、对账、结算等业务编排仍缺少完整闭环与统一迁移证据,数据库专项不得据此倒推出“银行协同已全部落地”。 + +
+ + +## METER/INST 专题表边界 + +本章节用于收敛 `SYS-002` 主表之外、但在详细设计与附录中反复出现的表务与报装签章专题表口径,避免“主文档未覆盖、分文档各写一套”。 + +### METER 专题(表务管理) + +#### 实现态(当前主库口径) + +| 表名 | 角色定位 | 说明 | +| :--- | :--- | :--- | +| `biz_meter` | 水表主档 | 水表基础信息、状态、型号、口径、量程等主数据入口 | +| `biz_meter_read` / `biz_reading_data` / `biz_last_reading` | 抄表与读数 | 支撑抄表任务、读数提交、最新读数维护 | +| `biz_meter_log` | 表务留痕 | 记录换表、移表、校表、维修等过程动作 | +| `biz_meter_in_out` / `biz_meter_in_out_rel` | 库存与出入库 | 支撑领用、退库、报废及批次追踪 | +| `biz_process` / `biz_process_transfer` | 工单协同 | 与业务办理流程共享工单流转和处理状态 | + +#### 历史命名映射(存量资料口径) + +| 历史命名(存量) | 当前主口径(建议对齐) | 说明 | +| :--- | :--- | :--- | +| `water_meter_workorder` | `biz_meter_log` + `biz_process*` | 旧稿“工单”能力在主文档统一并入表务日志与流程流转模型 | +| `water_meter_stock` / `water_meter_inventory` | `biz_meter_in_out` + `biz_meter_in_out_rel` | 旧稿库存/出入库能力按 `biz_meter_*` 专题表收敛 | +| `water_meter_archive` | `biz_meter` + `biz_last_reading` | 旧稿档案口径统一并入水表主档与读数状态模型 | + +> 说明:`water_meter_*` 仅用于历史资料追溯,不作为当前正式交付主口径。 + +### INST 专题(报装与签章) + +#### 实现态(当前主库口径) + +| 表名 | 角色定位 | 说明 | +| :--- | :--- | :--- | +| `biz_process` / `biz_process_transfer` | 报装流程主线 | 报装申请受理、节点流转、办理状态 | +| `biz_process_meter_install` | 装表落地信息 | 记录安装位置、装表结果等现场信息 | +| `biz_business_datas` | 业务扩展数据 | 踏勘、方案、审批扩展字段 | +| `biz_content` / `biz_content_attach` | 资料与附件 | 报装材料、验收资料、影像与附件管理 | + +#### 设计态(专项扩展口径) + +| 表名 | 角色定位 | 说明 | +| :--- | :--- | :--- | +| `installation_contract` | 报装合同主表 | 合同主数据、合同状态、文件地址 | +| `installation_signature` | 签章记录表 | 签署方、签章任务、签署状态与时间 | +| `installation_evidence` | 电子存证表 | 存证凭证、哈希、存证状态 | +| `installation_ca_config` | CA 配置表 | 泛微 CA 对接配置参数 | +| `installation_signature_template` | 签章模板表 | 签章模板与签署位置配置 | +| `installation_application` | 报装申请映射 | 与报装申请主线对象的关联映射(设计态) | + +> 边界说明:`installation_*` 来源于报装签章专项设计与附录,当前在数据库主文档按“专题扩展”纳管。若实施库落地结构与本表不一致,以实施库与主详设联合评审结果为准。 + +## 子系统5: 客户服务数据表(复用 SYS-002 主数据) + +客户服务模块本身不再单独维护旧稿中分散的平行表模型,而是以 `SYS-002` 主数据和交易表为主,按场景复用客户、账单、支付、发票与业务办理数据。 + +
+点击展开/折叠客户服务系统表详情 + +### 客户服务主要复用表 + +| 场景 | 复用表 | 说明 | +| :--- | :--- | :--- | +| 账户绑定管理 | `biz_cust`, `biz_cust_app_binds`, `biz_account` | 支撑账户绑定、默认客户切换与账号关联 | +| 信息查询服务 | `biz_cust`, `biz_cust_meter`, `biz_meter`, `biz_charge`, `biz_charge_detail` | 支撑客户档案、表计信息、账单与费用查询 | +| 在线缴费服务 | `biz_charge`, `biz_collection`, `biz_withholding`, `bk_transaction`, `bk_transaction_callback` | 支撑缴费下单、支付回写与异步回调 | +| 电子发票服务 | `biz_invoice`, `biz_invoice_taxrate`, `biz_cust_invoice` | 支撑发票申请、税率匹配与抬头信息 | +| 业务办理服务 | `biz_process`, `biz_process_transfer`, `biz_business_datas`, `biz_content_attach` | 支撑业务申请、进度查询与附件资料 | + +> 说明:客户服务模块与 `SYS-008`、`SYS-009`、`SYS-010` 的协同在数据库层主要表现为复用 `SYS-002` 主业务表并接收外部服务回写结果,不再单列一套平行客户服务数据库模型。 + +
+ +## 子系统6: 手机抄表APP数据表 + +手机抄表APP为抄表员和外勤人员提供移动作业工具,支持离线操作,提升现场工作效率。 + +
+点击展开/折叠手机抄表APP表详情 + +### 移动端表 (mobile_*) + +### mobile_user_session (移动端用户会话表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | nextval() | 主键 | +| user_id | int8 | N | | 用户ID | +| device_id | varchar(100) | N | | 设备ID | +| device_type | varchar(20) | N | | 设备类型:Android、iOS | +| app_version | varchar(20) | Y | | 应用版本 | +| login_type | varchar(20) | N | | 登录类型:在线、离线 | +| session_token | varchar(500) | N | | 会话令牌 | +| login_time | timestamp(6) | N | pg_systimestamp() | 登录时间 | +| last_active_time | timestamp(6) | Y | | 最后活跃时间 | +| logout_time | timestamp(6) | Y | | 登出时间 | +| session_duration | int4 | Y | 0 | 会话时长(分钟) | +| login_ip | varchar(50) | Y | | 登录IP | +| login_location | varchar(100) | Y | | 登录位置 | +| network_type | varchar(20) | Y | | 网络类型:WiFi、4G、5G | +| session_status | int2 | N | 1 | 会话状态:0-已结束,1-活跃 | +| sync_status | int2 | N | 0 | 同步状态:0-未同步,1-已同步 | +| last_sync_time | timestamp(6) | Y | | 最后同步时间 | +| remark | varchar(500) | Y | | 备注 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| creator | varchar(100) | Y | | 创建人id | +| updater | varchar(100) | Y | | 更新人id | +| deleted | int2 | N | 0 | 是否删除 | +| tenant_id | int8 | N | 0 | 租户id | + +### mobile_user_cache (移动端用户缓存表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | nextval() | 主键 | +| user_id | int8 | N | | 用户ID | +| device_id | varchar(100) | N | | 设备ID | +| cache_key | varchar(200) | N | | 缓存键 | +| cache_value | text | Y | | 缓存值 | +| cache_type | varchar(20) | N | | 缓存类型:用户信息、权限、配置、数据 | +| cache_size | int4 | Y | 0 | 缓存大小(字节) | +| expire_time | timestamp(6) | Y | | 过期时间 | +| access_count | int4 | Y | 0 | 访问次数 | +| last_access_time | timestamp(6) | Y | | 最后访问时间 | +| cache_status | int2 | N | 1 | 缓存状态:0-已过期,1-有效 | +| remark | varchar(500) | Y | | 备注 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| creator | varchar(100) | Y | | 创建人id | +| updater | varchar(100) | Y | | 更新人id | +| deleted | int2 | N | 0 | 是否删除 | +| tenant_id | int8 | N | 0 | 租户id | + +### mobile_login_log (移动端登录日志表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | nextval() | 主键 | +| user_id | int8 | N | | 用户ID | +| username | varchar(50) | N | | 用户名 | +| device_id | varchar(100) | N | | 设备ID | +| device_type | varchar(20) | N | | 设备类型:Android、iOS | +| device_model | varchar(100) | Y | | 设备型号 | +| app_version | varchar(20) | Y | | 应用版本 | +| login_type | varchar(20) | N | | 登录类型:在线、离线 | +| login_time | timestamp(6) | N | pg_systimestamp() | 登录时间 | +| login_result | int2 | N | | 登录结果:0-成功,1-失败 | +| login_ip | varchar(50) | Y | | 登录IP | +| login_location | varchar(100) | Y | | 登录位置 | +| network_type | varchar(20) | Y | | 网络类型:WiFi、4G、5G | +| failure_reason | varchar(200) | Y | | 失败原因 | +| user_agent | varchar(500) | Y | | 用户代理 | +| screen_resolution | varchar(20) | Y | | 屏幕分辨率 | +| operating_system | varchar(50) | Y | | 操作系统 | +| remark | varchar(500) | Y | | 备注 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| creator | varchar(100) | Y | | 创建人id | +| updater | varchar(100) | Y | | 更新人id | +| deleted | int2 | N | 0 | 是否删除 | +| tenant_id | int8 | N | 0 | 租户id | + +### mobile_reading_task (移动端抄表任务表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | nextval() | 主键 | +| task_no | varchar(32) | N | | 任务编号 | +| book_id | int8 | N | | 册本ID | +| reader_id | int8 | N | | 抄表员ID | +| task_date | date | N | | 任务日期 | +| total_meters | int4 | Y | 0 | 总表数 | +| completed_meters | int4 | Y | 0 | 已完成表数 | +| task_status | int2 | N | 0 | 任务状态:0-待开始,1-进行中,2-已完成 | +| download_time | timestamp(6) | Y | | 下载时间 | +| upload_time | timestamp(6) | Y | | 上传时间 | +| sync_status | int2 | N | 0 | 同步状态:0-未同步,1-已同步 | +| completion_rate | numeric(5,2) | Y | 0 | 完成率 | +| start_time | timestamp(6) | Y | | 开始时间 | +| end_time | timestamp(6) | Y | | 结束时间 | +| work_duration | int4 | Y | 0 | 工作时长(分钟) | +| exception_count | int4 | Y | 0 | 异常数量 | +| photo_count | int4 | Y | 0 | 照片数量 | +| remark | varchar(500) | Y | | 备注 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| creator | varchar(100) | Y | | 创建人id | +| updater | varchar(100) | Y | | 更新人id | +| deleted | int2 | N | 0 | 是否删除 | +| tenant_id | int8 | N | 0 | 租户id | + +### mobile_reading_record (移动端抄表记录表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | nextval() | 主键 | +| task_id | int8 | N | | 任务ID | +| customer_id | int8 | N | | 客户ID | +| meter_id | int8 | N | | 水表ID | +| reading_value | numeric(15,3) | Y | 0 | 抄表读数 | +| reading_time | timestamp(6) | N | pg_systimestamp() | 抄表时间 | +| reading_type | varchar(20) | N | | 抄表类型:正常、异常、估读 | +| exception_code | varchar(10) | Y | | 异常代码 | +| exception_description | varchar(500) | Y | | 异常描述 | +| photo_path | varchar(500) | Y | | 照片路径 | +| gps_longitude | numeric(10,6) | Y | | GPS经度 | +| gps_latitude | numeric(10,6) | Y | | GPS纬度 | +| location_accuracy | numeric(8,2) | Y | | 位置精度 | +| reading_method | varchar(20) | Y | | 抄表方式:手工、扫码、拍照识别 | +| sync_status | int2 | N | 0 | 同步状态:0-未同步,1-已同步 | +| sync_time | timestamp(6) | Y | | 同步时间 | +| network_type | varchar(20) | Y | | 网络类型:WiFi、4G、5G、离线 | +| device_id | varchar(100) | Y | | 设备ID | +| remark | varchar(500) | Y | | 备注 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| creator | varchar(100) | Y | | 创建人id | +| updater | varchar(100) | Y | | 更新人id | +| deleted | int2 | N | 0 | 是否删除 | +| tenant_id | int8 | N | 0 | 租户id | + +### mobile_task_progress (移动端任务进度表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | nextval() | 主键 | +| task_id | int8 | N | | 任务ID | +| user_id | int8 | N | | 用户ID | +| progress_time | timestamp(6) | N | pg_systimestamp() | 进度时间 | +| completed_count | int4 | Y | 0 | 已完成数量 | +| total_count | int4 | Y | 0 | 总数量 | +| completion_rate | numeric(5,2) | Y | 0 | 完成率 | +| current_location | varchar(200) | Y | | 当前位置 | +| working_status | varchar(20) | Y | | 工作状态:工作中、休息中、结束 | +| progress_description | varchar(500) | Y | | 进度描述 | +| device_id | varchar(100) | Y | | 设备ID | +| battery_level | int4 | Y | 0 | 电池电量 | +| network_status | varchar(20) | Y | | 网络状态:在线、离线 | +| remark | varchar(500) | Y | | 备注 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| creator | varchar(100) | Y | | 创建人id | +| updater | varchar(100) | Y | | 更新人id | +| deleted | int2 | N | 0 | 是否删除 | +| tenant_id | int8 | N | 0 | 租户id | + +### mobile_data_cache (移动端数据缓存表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | nextval() | 主键 | +| user_id | int8 | N | | 用户ID | +| device_id | varchar(100) | N | | 设备ID | +| data_type | varchar(20) | N | | 数据类型:抄表、收费、工单 | +| data_key | varchar(200) | N | | 数据键 | +| data_value | text | Y | | 数据值 | +| data_size | int4 | Y | 0 | 数据大小(字节) | +| cache_time | timestamp(6) | N | pg_systimestamp() | 缓存时间 | +| sync_status | int2 | N | 0 | 同步状态:0-未同步,1-已同步,2-同步失败 | +| sync_time | timestamp(6) | Y | | 同步时间 | +| sync_error | varchar(500) | Y | | 同步错误 | +| retry_count | int4 | Y | 0 | 重试次数 | +| priority | int4 | Y | 0 | 优先级 | +| expire_time | timestamp(6) | Y | | 过期时间 | +| remark | varchar(500) | Y | | 备注 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| creator | varchar(100) | Y | | 创建人id | +| updater | varchar(100) | Y | | 更新人id | +| deleted | int2 | N | 0 | 是否删除 | +| tenant_id | int8 | N | 0 | 租户id | + +### mobile_problem_report (移动端问题上报表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | nextval() | 主键 | +| report_no | varchar(32) | N | | 上报编号 | +| reporter_id | int8 | N | | 上报人ID | +| problem_type | varchar(20) | N | | 问题类型:水表故障、管道漏水、水质问题 | +| problem_description | text | N | | 问题描述 | +| problem_location | varchar(200) | Y | | 问题位置 | +| gps_longitude | numeric(10,6) | Y | | GPS经度 | +| gps_latitude | numeric(10,6) | Y | | GPS纬度 | +| urgency_level | varchar(20) | N | | 紧急程度:普通、紧急、特急 | +| report_time | timestamp(6) | N | pg_systimestamp() | 上报时间 | +| problem_photos | text | Y | | 问题照片 | +| problem_status | int2 | N | 0 | 问题状态:0-待处理,1-处理中,2-已处理 | +| handler | varchar(100) | Y | | 处理人 | +| handle_time | timestamp(6) | Y | | 处理时间 | +| handle_result | varchar(500) | Y | | 处理结果 | +| customer_id | int8 | Y | | 客户ID | +| meter_id | int8 | Y | | 水表ID | +| device_id | varchar(100) | Y | | 设备ID | +| remark | varchar(500) | Y | | 备注 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| creator | varchar(100) | Y | | 创建人id | +| updater | varchar(100) | Y | | 更新人id | +| deleted | int2 | N | 0 | 是否删除 | +| tenant_id | int8 | N | 0 | 租户id | + +### mobile_work_order (移动端工单表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | int8 | N | nextval() | 主键 | +| work_order_no | varchar(32) | N | | 工单编号 | +| problem_report_id | int8 | Y | | 问题上报ID | +| work_order_type | varchar(20) | N | | 工单类型:维修、更换、检查 | +| assigned_user | varchar(100) | Y | | 指派人员 | +| assignment_time | timestamp(6) | Y | | 指派时间 | +| work_description | text | Y | | 工作描述 | +| work_location | varchar(200) | Y | | 工作位置 | +| scheduled_time | timestamp(6) | Y | | 预约时间 | +| start_time | timestamp(6) | Y | | 开始时间 | +| end_time | timestamp(6) | Y | | 结束时间 | +| work_duration | int4 | Y | 0 | 工作时长(分钟) | +| work_status | int2 | N | 0 | 工单状态:0-待处理,1-处理中,2-已完成 | +| work_result | varchar(500) | Y | | 工作结果 | +| completion_photos | text | Y | | 完成照片 | +| customer_signature | varchar(500) | Y | | 客户签名 | +| satisfaction_rating | int2 | Y | | 满意度评分:1-5分 | +| device_id | varchar(100) | Y | | 设备ID | +| sync_status | int2 | N | 0 | 同步状态:0-未同步,1-已同步 | +| sync_time | timestamp(6) | Y | | 同步时间 | +| remark | varchar(500) | Y | | 备注 | +| create_time | timestamp(6) | N | pg_systimestamp() | 创建时间 | +| update_time | timestamp(6) | N | pg_systimestamp() | 更新时间 | +| creator | varchar(100) | Y | | 创建人id | +| updater | varchar(100) | Y | | 更新人id | +| deleted | int2 | N | 0 | 是否删除 | +| tenant_id | int8 | N | 0 | 租户id | + +### 移动端特有表(优化后) + +根据移动端表设计优化原则,以下为移动端特有的5个表: + +### mobile_user_cache (移动端用户缓存表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | bigint | N | AUTO_INCREMENT | 主键 | +| user_id | bigint | N | | 用户ID,关联system_users.id | +| device_id | varchar(100) | N | | 设备唯一标识 | +| cache_data | longtext | Y | | 缓存数据(JSON格式) | +| cache_type | varchar(50) | N | | 缓存类型:user_info、task_data、config_data | +| expire_time | datetime | Y | | 过期时间 | +| version | int | N | 1 | 版本号,用于数据同步 | +| create_time | datetime | N | CURRENT_TIMESTAMP | 创建时间 | +| update_time | datetime | N | CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP | 更新时间 | +| creator | varchar(64) | Y | | 创建者 | +| updater | varchar(64) | Y | | 更新者 | +| deleted | tinyint | N | 0 | 是否删除:0-未删除,1-已删除 | +| tenant_id | bigint | N | 0 | 租户ID | + +### mobile_search_history (移动端搜索历史表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | bigint | N | AUTO_INCREMENT | 主键 | +| user_id | bigint | N | | 用户ID,关联system_users.id | +| search_keyword | varchar(200) | N | | 搜索关键词 | +| search_type | varchar(50) | N | | 搜索类型:customer、meter、address | +| search_result_count | int | N | 0 | 搜索结果数量 | +| search_time | datetime | N | CURRENT_TIMESTAMP | 搜索时间 | +| device_id | varchar(100) | Y | | 设备ID | +| create_time | datetime | N | CURRENT_TIMESTAMP | 创建时间 | +| update_time | datetime | N | CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP | 更新时间 | +| creator | varchar(64) | Y | | 创建者 | +| updater | varchar(64) | Y | | 更新者 | +| deleted | tinyint | N | 0 | 是否删除:0-未删除,1-已删除 | +| tenant_id | bigint | N | 0 | 租户ID | + +### mobile_task_sync (移动端任务同步表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | bigint | N | AUTO_INCREMENT | 主键 | +| user_id | bigint | N | | 用户ID,关联system_users.id | +| task_id | bigint | N | | 任务ID,关联biz_meter_book.id | +| sync_status | varchar(20) | N | pending | 同步状态:pending、syncing、completed、failed | +| sync_type | varchar(20) | N | | 同步类型:download、upload | +| data_size | int | N | 0 | 数据大小(字节) | +| sync_progress | decimal(5,2) | N | 0.00 | 同步进度(百分比) | +| error_message | text | Y | | 错误信息 | +| last_sync_time | datetime | Y | | 最后同步时间 | +| retry_count | int | N | 0 | 重试次数 | +| device_id | varchar(100) | Y | | 设备ID | +| create_time | datetime | N | CURRENT_TIMESTAMP | 创建时间 | +| update_time | datetime | N | CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP | 更新时间 | +| creator | varchar(64) | Y | | 创建者 | +| updater | varchar(64) | Y | | 更新者 | +| deleted | tinyint | N | 0 | 是否删除:0-未删除,1-已删除 | +| tenant_id | bigint | N | 0 | 租户ID | + +### mobile_work_attachment (移动端工单附件表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | bigint | N | AUTO_INCREMENT | 主键 | +| work_order_id | bigint | N | | 工单ID,关联biz_process.id 或 biz_content.id | +| attachment_type | varchar(20) | N | | 附件类型:image、video、document | +| attachment_name | varchar(200) | N | | 附件名称 | +| attachment_path | varchar(500) | N | | 附件存储路径 | +| attachment_size | bigint | N | 0 | 附件大小(字节) | +| mime_type | varchar(100) | Y | | MIME类型 | +| upload_status | varchar(20) | N | pending | 上传状态:pending、uploading、completed、failed | +| upload_progress | decimal(5,2) | N | 0.00 | 上传进度(百分比) | +| gps_longitude | decimal(10,6) | Y | | GPS经度 | +| gps_latitude | decimal(10,6) | Y | | GPS纬度 | +| capture_time | datetime | Y | | 拍摄/录制时间 | +| device_id | varchar(100) | Y | | 设备ID | +| create_time | datetime | N | CURRENT_TIMESTAMP | 创建时间 | +| update_time | datetime | N | CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP | 更新时间 | +| creator | varchar(64) | Y | | 创建者 | +| updater | varchar(64) | Y | | 更新者 | +| deleted | tinyint | N | 0 | 是否删除:0-未删除,1-已删除 | +| tenant_id | bigint | N | 0 | 租户ID | + +### mobile_app_config (移动端应用配置表) +| 字段名 | 类型 | 是否可空 | 默认值 | 注释 | +| :--- | :--- | :--- | :--- | :--- | +| id | bigint | N | AUTO_INCREMENT | 主键 | +| user_id | bigint | N | | 用户ID,关联system_users.id | +| config_key | varchar(100) | N | | 配置项键名 | +| config_value | text | Y | | 配置项值 | +| config_type | varchar(50) | N | | 配置类型:system、user、app | +| config_description | varchar(500) | Y | | 配置描述 | +| is_active | tinyint | N | 1 | 是否启用:0-禁用,1-启用 | +| device_id | varchar(100) | Y | | 设备ID | +| create_time | datetime | N | CURRENT_TIMESTAMP | 创建时间 | +| update_time | datetime | N | CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP | 更新时间 | +| creator | varchar(64) | Y | | 创建者 | +| updater | varchar(64) | Y | | 更新者 | +| deleted | tinyint | N | 0 | 是否删除:0-未删除,1-已删除 | +| tenant_id | bigint | N | 0 | 租户ID | + +
+ + +# 移动端表设计优化说明 + +## 设计原则 + +根据系统架构设计原则,移动端优先使用Web端已有的数据表,避免重复建表,确保数据一致性和降低维护成本。 + +## 表复用策略 + +### 复用Web端表(10个) +移动端直接复用以下Web端已有表: + +| 表名 | 用途说明 | 备注 | +|------|----------|------| +| `system_users` | 用户基本信息表 | 复用Web端用户管理 | +| `system_login_log` | 登录日志表 | 扩展设备类型字段记录移动端登录 | +| `biz_cust` | 客户主档表 | 复用 Web 端客户档案 | +| `biz_meter` | 水表主档表 | 复用 Web 端水表档案 | +| `biz_meter_book` | 抄表册本表 | 复用 Web 端抄表任务 | +| `biz_reading_data` | 抄表数据表 | 复用 Web 端抄表数据 | +| `biz_meter_read` | 抄表任务/状态表 | 复用 Web 端抄表过程状态 | +| `biz_process` | 业务办理流程表 | 复用 Web 端现场业务工单/办理数据 | +| `biz_content_attach` | 办理附件表 | 复用 Web 端附件资料 | +| `biz_account` | 客户账户表 | 复用 Web 端账务信息 | + +### 移动端特有表(5个) +仅保留移动端特有的功能表: + +| 表名 | 用途说明 | 特有原因 | +|------|----------|----------| +| `mobile_user_cache` | 移动端用户缓存表 | 用于离线缓存,移动端特有需求 | +| `mobile_search_history` | 移动端搜索历史表 | 移动端搜索记录管理 | +| `mobile_task_sync` | 移动端任务同步表 | 离线任务管理,移动端特有 | +| `mobile_work_attachment` | 移动端工单附件表 | 现场附件管理,移动端特有 | +| `mobile_app_config` | 移动端应用配置表 | 个性化设置,移动端特有 | + +## 优化效果 + +1. **减少冗余**:避免了15+个重复表的创建 +2. **提升一致性**:移动端和Web端共享核心业务数据 +3. **降低维护成本**:统一的数据模型减少维护复杂度 +4. **符合架构原则**:遵循DRY(Don't Repeat Yourself)原则 + +## 数据同步策略 + +- **实时同步**:共用表自然保证数据一致性 +- **离线缓存**:移动端特有表支持离线操作 +- **冲突处理**:通过时间戳和版本控制处理数据冲突 + + +# 视图的设计 + +## 数据库ER图设计 + +### 系统核心表关系图 +```mermaid +erDiagram + system_tenant ||--o{ system_users : "租户关系" + system_users ||--o{ system_user_role : "用户角色" + system_role ||--o{ system_user_role : "角色用户" + system_role ||--o{ system_role_menu : "角色权限" + system_menu ||--o{ system_role_menu : "菜单权限" + system_dept ||--o{ system_users : "部门用户" + + system_tenant { + int8 id PK + varchar name + varchar contact_name + varchar contact_mobile + int2 status + timestamp expire_time + } + + system_users { + int8 id PK + varchar username + varchar nickname + varchar password + int8 dept_id FK + int8 tenant_id FK + int2 status + } + + system_role { + int8 id PK + varchar name + varchar code + int2 data_scope + int8 tenant_id FK + } + + system_dept { + int8 id PK + varchar name + int8 parent_id + varchar code + int8 tenant_id FK + } +``` + +### 业务核心表关系图 +```mermaid +erDiagram + BIZ_CUST ||--|| BIZ_ACCOUNT : 对应账户 + BIZ_CUST ||--o{ BIZ_CUST_CONTACT : 联系人 + BIZ_CUST ||--o{ BIZ_CUST_METER : 绑定水表 + BIZ_METER ||--o{ BIZ_CUST_METER : 被绑定 + BIZ_METER_BOOK ||--o{ BIZ_METER_READ : 生成任务 + BIZ_METER_READ ||--o{ BIZ_READING_DATA : 采集读数 + BIZ_METER ||--o{ BIZ_LAST_READING : 最新读数 + BIZ_READING_DATA ||--o{ BIZ_CHARGE : 触发开账 + BIZ_CHARGE ||--o{ BIZ_CHARGE_DETAIL : 明细拆分 + BIZ_CHARGE ||--o{ BIZ_INVOICE : 开票关联 + BIZ_CHARGE ||--o{ BK_TRANSACTION : 支付核销 + BIZ_PRICE_CATEGORY ||--o{ BIZ_PRICE_TEMPLATE : 模板归属 + BIZ_PRICE_TEMPLATE ||--o{ BIZ_WATER_USE_SCHEME : 计费方案 + BIZ_PRICE_CATEGORY ||--o{ BIZ_PRICE_COST_ADJUSTMENT : 费用调整 + BIZ_PRICE_COST_ADJUSTMENT ||--o{ BIZ_PRICE_TIER_ADJUSTMENT : 阶梯规则 + BK_WITHHOLDING_BATCH ||--o{ BK_WITHHOLDING_ITEM : 批次明细 + BK_RECONCILE_BATCH ||--o{ BK_RECONCILE_DIFF : 对账差异 + + BIZ_CUST { + int8 id PK + varchar code + varchar name + varchar cust_type + varchar mobile + int8 tenant_id FK + } + + BIZ_ACCOUNT { + int8 id PK + varchar code + int8 cust_id FK + numeric balance + numeric arrears_amount + } + + BIZ_METER { + int8 id PK + varchar code + varchar meter_no + varchar maker_code + varchar model_code + } + + BIZ_CHARGE { + int8 id PK + varchar code + int8 cust_id FK + varchar bill_period + numeric total_amount + int2 charge_status + } + + BK_TRANSACTION { + int8 id PK + varchar trade_no + varchar biz_order_no + varchar channel_code + numeric trade_amount + int2 trade_status + } +``` + +## 业务视图设计 + +为简化复杂查询和报表统计,设计以下视图: + +### v_price_info (价格信息视图) +综合展示价格体系信息,包含价格归属、费用组成、调整历史等。 +```sql +CREATE VIEW v_price_info AS +SELECT + pc.id as category_id, + pc.name as category_name, + pc.code as category_code, + cc.name as cost_name, + cc.code as cost_code, + pca.price_value, + pca.effective_date, + pca.expire_date +FROM biz_price_category pc +LEFT JOIN biz_price_cost_adjustment pca ON pc.code = pca.price_category_code +LEFT JOIN biz_cost_component cc ON pca.cost_component_code = cc.code +WHERE pc.deleted = 0 AND pca.deleted = 0 AND cc.deleted = 0; +``` + +### v_meter_info (水表信息视图) +整合水表主档、厂家、型号、口径等基础信息,服务于册本分配、现场抄表和档案查询。 +```sql +CREATE VIEW v_meter_info AS +SELECT + m.id AS meter_id, + m.code AS meter_code, + m.meter_no, + m.maker_code, + maker.name AS maker_name, + m.model_code, + model.name AS model_name, + m.caliber_code, + caliber.name AS caliber_name, + caliber.value AS caliber_value, + m.range_code, + range_cfg.name AS range_name, + m.install_address, + m.meter_status +FROM biz_meter m +LEFT JOIN biz_meter_maker maker ON m.maker_code = maker.code AND maker.deleted = 0 +LEFT JOIN biz_meter_model model ON m.model_code = model.code AND model.deleted = 0 +LEFT JOIN biz_meter_caliber caliber ON m.caliber_code = caliber.code AND caliber.deleted = 0 +LEFT JOIN biz_meter_range range_cfg ON m.range_code = range_cfg.code AND range_cfg.deleted = 0 +WHERE m.deleted = 0; +``` + +### v_dept_hierarchy (部门层级视图) +展示完整的组织架构层级关系。 +```sql +CREATE VIEW v_dept_hierarchy AS +WITH RECURSIVE dept_tree AS ( + SELECT id, name, code, parent_id, 0 as level, name as path + FROM system_dept + WHERE parent_id = 0 AND deleted = 0 + + UNION ALL + + SELECT d.id, d.name, d.code, d.parent_id, dt.level + 1, + CONCAT(dt.path, ' > ', d.name) + FROM system_dept d + INNER JOIN dept_tree dt ON d.parent_id = dt.id + WHERE d.deleted = 0 +) +SELECT * FROM dept_tree; +``` + +## 统计分析视图 + +### v_tenant_summary (租户汇总视图) +按租户维度统计各类数据。 +```sql +CREATE VIEW v_tenant_summary AS +SELECT + t.id as tenant_id, + t.name as tenant_name, + COUNT(DISTINCT u.id) as user_count, + COUNT(DISTINCT d.id) as dept_count, + COUNT(DISTINCT c.id) as community_count +FROM system_tenant t +LEFT JOIN system_users u ON t.id = u.tenant_id AND u.deleted = 0 +LEFT JOIN system_dept d ON t.id = d.tenant_id AND d.deleted = 0 +LEFT JOIN biz_community c ON t.id = c.tenant_id AND c.deleted = 0 +WHERE t.deleted = 0 +GROUP BY t.id, t.name; +``` + +### REV-007 统计承接口径 + +#### 设计定位 + +- `REV-007` 以在线业务主数据聚合、视图或汇总口径支撑经营统计查询,不在本轮确认独立统计仓库、离线批处理表或专题分析表族。 +- 统计结果必须能够追溯到现有客户、账单、收费、交易、抄表和组织维度数据来源。 +- 当前数据库主文档仅约束“统计查询如何承接”,不反推 backend 已存在专门统计模块或已固化全部统计视图。 + +#### 最小统计主题承接口径 + +| 统计主题 | 主数据来源 | 最低维度要求 | 最低指标要求 | 承接方式 | +| :--- | :--- | :--- | :--- | :--- | +| 营收汇总 | `biz_charge`、`biz_charge_detail` | 时间、账期、营业所、客户类别 | 应收金额、账单数、用水量 | 在线聚合 / 汇总口径 | +| 收费与实收统计 | `biz_collection`、`bk_transaction` | 时间、渠道、营业所、收费状态 | 实收金额、收费笔数、成功率 | 在线聚合 / 汇总口径 | +| 欠费规模与账龄统计 | `biz_charge`、`biz_charge_detail` | 账期、账龄、客户类别、区域 | 欠费余额、欠费户数、账龄分布 | 在线聚合 / 汇总口径 | +| 客户结构统计 | `biz_cust`、`biz_account` | 客户类别、区域、状态 | 客户数、账户数、活跃状态分布 | 在线聚合 / 视图口径 | +| 渠道交易统计 | `bk_transaction`、`bk_payment_channel` | 渠道、日期、结果状态 | 交易笔数、交易金额、渠道占比 | 在线聚合 / 汇总口径 | +| 抄表完成率统计 | `biz_meter_book`、`biz_reading_data`、`biz_last_reading` | 抄表周期、册本、片区、人员 | 应抄户数、已抄户数、完成率 | 在线聚合 / 汇总口径 | + +#### 设计约束 + +- 统计查询可以由视图、临时汇总结果或聚合 SQL 承接,但未确认存在的 `stat_*`、`report_*` 或专题报表表不得写成正式已实现对象。 +- 若某类统计仅在历史资料中出现而当前主文档未形成正式口径,应先作为后续专题保留项,不直接扩写为当前正式范围。 +- 涉及历史迁移核查的统计比对时,历史来源只承担补充核对职责,不替代在线主数据统计结果。 +- 导出能力属于查询扩展能力,数据库设计不单独为导出动作臆造新的物理表。 + + +# 索引设计与性能优化 + +## 核心索引设计 + +### 系统表索引 +```sql +-- 用户表核心索引 +CREATE INDEX idx_system_users_username ON system_users(username); +CREATE INDEX idx_system_users_dept_tenant ON system_users(dept_id, tenant_id); +CREATE INDEX idx_system_users_status_tenant ON system_users(status, tenant_id); + +-- 部门表索引 +CREATE INDEX idx_system_dept_parent_tenant ON system_dept(parent_id, tenant_id); +CREATE INDEX idx_system_dept_code ON system_dept(code); + +-- 角色权限索引 +CREATE INDEX idx_system_user_role_user_tenant ON system_user_role(user_id, tenant_id); +CREATE INDEX idx_system_role_menu_role_id ON system_role_menu(role_id); + +-- 日志表索引(支持时间范围查询) +CREATE INDEX idx_system_login_log_user_time ON system_login_log(user_id, create_time); +CREATE INDEX idx_system_login_log_ip_time ON system_login_log(user_ip, create_time); +``` + +### 业务表索引 +```sql +-- 客户主数据索引 +CREATE INDEX idx_biz_cust_code ON biz_cust(code); +CREATE INDEX idx_biz_cust_mobile ON biz_cust(mobile); +CREATE INDEX idx_biz_account_cust_status ON biz_account(cust_id, account_status); + +-- 水表与抄表索引 +CREATE INDEX idx_biz_meter_code ON biz_meter(code); +CREATE INDEX idx_biz_meter_book_dept_status ON biz_meter_book(dept_code, status); +CREATE INDEX idx_biz_meter_read_book_period ON biz_meter_read(book_id, read_period); +CREATE INDEX idx_biz_reading_data_read_time ON biz_reading_data(meter_read_id, read_time); + +-- 开账收费索引 +CREATE INDEX idx_biz_charge_cust_period ON biz_charge(cust_id, bill_period); +CREATE INDEX idx_biz_charge_status_due ON biz_charge(charge_status, due_date); +CREATE INDEX idx_biz_charge_detail_charge_cost ON biz_charge_detail(charge_id, cost_component_code); + +-- 价格体系索引 +CREATE INDEX idx_biz_price_category_code ON biz_price_category(code); +CREATE INDEX idx_biz_price_template_category ON biz_price_template(price_category_code, adjustment_snap_code); +CREATE INDEX idx_biz_price_cost_adj_category_cost ON biz_price_cost_adjustment(price_category_code, cost_component_code); +CREATE INDEX idx_biz_price_tier_adj_cost_tier ON biz_price_tier_adjustment(cost_component_code, tier_level); + +-- 银行代收与对账索引 +CREATE INDEX idx_bk_transaction_trade_no ON bk_transaction(trade_no); +CREATE INDEX idx_bk_transaction_biz_order ON bk_transaction(biz_order_no, trade_status); +CREATE INDEX idx_bk_withholding_batch_date ON bk_withholding_batch(batch_date, batch_status); +CREATE INDEX idx_bk_reconcile_batch_bill_date ON bk_reconcile_batch(bill_date, reconcile_status); +``` + +## 分区表设计 + +### 日志表分区策略 +```sql +-- 登录日志按月分区 +CREATE TABLE system_login_log_partition ( + LIKE system_login_log INCLUDING ALL +) PARTITION BY RANGE (create_time); + +-- 创建月度分区 +CREATE TABLE system_login_log_y2024m01 PARTITION OF system_login_log_partition + FOR VALUES FROM ('2024-01-01') TO ('2024-02-01'); + +CREATE TABLE system_login_log_y2024m02 PARTITION OF system_login_log_partition + FOR VALUES FROM ('2024-02-01') TO ('2024-03-01'); +``` + +### 历史数据分区策略 +```sql +-- 价格调整历史按年分区 +CREATE TABLE biz_price_adjustment_history_partition ( + LIKE biz_price_adjustment_history INCLUDING ALL +) PARTITION BY RANGE (create_time); + +-- 按年度分区 +CREATE TABLE biz_price_adjustment_history_y2024 PARTITION OF biz_price_adjustment_history_partition + FOR VALUES FROM ('2024-01-01') TO ('2025-01-01'); +``` + +## 查询优化建议 + +### 多租户查询优化 +```sql +-- 建议查询模式:始终带上租户ID +SELECT * FROM system_users +WHERE tenant_id = ? AND status = 0 AND dept_id = ?; + +-- 使用覆盖索引减少回表 +CREATE INDEX idx_system_users_cover ON system_users(tenant_id, status, dept_id) +INCLUDE (username, nickname, email); +``` + +### 层级查询优化 +```sql +-- 使用递归CTE查询部门层级 +WITH RECURSIVE dept_tree AS ( + SELECT id, name, parent_id, 1 as level + FROM system_dept + WHERE id = ? AND tenant_id = ? + + UNION ALL + + SELECT d.id, d.name, d.parent_id, dt.level + 1 + FROM system_dept d + INNER JOIN dept_tree dt ON d.parent_id = dt.id + WHERE d.tenant_id = ? AND dt.level < 10 -- 防止无限递归 +) +SELECT * FROM dept_tree; +``` + +## 数据归档策略 + +### 日志数据归档 +- **保留策略**: 在线保留3个月,历史数据转移到归档表 +- **归档周期**: 每月执行一次归档作业 +- **存储方式**: 使用列式存储优化查询性能 + +### 历史数据处理 +```sql +-- 创建归档表 +CREATE TABLE system_login_log_archive ( + LIKE system_login_log INCLUDING ALL +); + +-- 归档脚本示例 +INSERT INTO system_login_log_archive +SELECT * FROM system_login_log +WHERE create_time < CURRENT_DATE - INTERVAL '3 months'; + +DELETE FROM system_login_log +WHERE create_time < CURRENT_DATE - INTERVAL '3 months'; +``` + + +# 安全保密设计 +- **用户认证**: 所有数据库连接均需通过应用层的身份认证,禁止数据库密码在配置文件中明文存储。 +- **权限控制**: 数据库用户权限遵循最小权限原则。应用层根据用户角色(RBAC)动态构建SQL,并通过行级安全(RLS)策略限制数据访问范围。 +- **数据加密**: 对数据库中的密码、密钥等敏感信息,采用BCrypt或SM3等算法进行加密存储。 +- **审计日志**: 启用数据库审计功能,记录所有DDL和DML操作,特别是对敏感数据的访问和修改。 diff --git a/docs/design/04_Appendix/Archive/08_Formal_Doc_Snapshots/RWB-03/2026-04-03-RWB-03-03_Interface_Design.md b/docs/design/04_Appendix/Archive/08_Formal_Doc_Snapshots/RWB-03/2026-04-03-RWB-03-03_Interface_Design.md new file mode 100644 index 0000000..45d9790 --- /dev/null +++ b/docs/design/04_Appendix/Archive/08_Formal_Doc_Snapshots/RWB-03/2026-04-03-RWB-03-03_Interface_Design.md @@ -0,0 +1,1808 @@ +--- +doc_id: TC-03-INTERFACE +doc_role: master_document +authority: primary +scope: 接口设计 +source_of_truth: true +last_reviewed: 2026-03-12 +retrieval_priority: P0 +--- + +# 福建水务营收系统接口设计文档 + +## 文档信息 +| 项目信息 | 详情 | +|---------|------| +| **项目名称** | 福建水务营收系统 | +| **文档类型** | 接口设计文档 | +| **技术框架** | Spring Cloud Alibaba + RuoYi-Vue-Pro + yudao-ui-admin-vue3 | +| **文档版本** | v1.0 | +| **编写日期** | 2026-03-11 | +| **文档状态** | ✅ 已完成(按版本迭代) | + +## 章节导航(精简) +- [接口设计范围](#sec-scope) +- [设计原则与统一约束](#sec-principles) +- [SYS-002 接口视图](#sec-rev-interface-view) +- [外部接口设计](#sec-external-interface) +- [内部接口设计](#sec-internal-interface) +- [数据对象与表口径](#sec-data-object) +- [接口安全与异常处理](#sec-security-exception) +- [历史查询与迁移校验接口口径](#sec-migration-readonly) +- [实现状态说明](#sec-status) + + +## 接口设计范围 + +本文档用于描述福建水务营收系统的接口边界、调用方式、核心接口清单以及与外围子系统的协同关系,重点统一 `SYS-002` 营收业务系统的接口口径。 + +本次接口整编遵循以下事实来源: + +- `docs/design/02_Detailed_Design/01_Detailed_Design.md` +- `docs/design/03_Technical_Design/01_Database_Design.md` +- `docs/guides/BACKEND_CURRENT_STATUS.md` +- `docs/guides/BACKEND_TABLE_MAPPING.md` +- `output/preview/福建水务营收系统整体架构图.html` + +> 说明:本文档优先描述正式设计边界与业务接口职责,不将 backend 中尚未明确识别的内部实现细节误写为既有接口事实。对于历史资料中存在、但当前 backend 未完全确认的接口对象,统一按“文档先行”处理。 + + +## 设计原则与统一约束 + +### 接口设计原则 + +- **统一编号**:接口编号统一采用 `IF-UP-*`、`IF-REV-*`、`IF-CS-*`、`IF-METER-*`、`IF-INST-*`、`IF-EXT-*` 规则。 +- **统一边界**:`SYS-002` 负责营收业务主流程,发票、支付结算、消息触达分别通过 `SYS-008`、`SYS-009`、`SYS-010` 协同完成。 +- **统一数据口径**:接口数据对象优先对齐真实 `biz_*` 与 `bk_*` 表,不再沿用旧稿中的 `customer_*`、`billing_*`、`thirdpay_*`、`service_*` 等历史命名。 +- **统一协议风格**:内部管理接口以 HTTPS REST 为主,跨系统集成根据场景采用 REST、文件交换、消息队列等方式。 +- **统一安全机制**:内部接口采用统一认证鉴权,外部接口按渠道要求实施签名、回调校验、白名单和审计留痕。 + +### 通用响应格式 + +内部 REST 接口统一采用如下响应模型: + +```json +{ + "code": 0, + "data": {}, + "msg": "success" +} +``` + +分页响应统一采用: + +```json +{ + "code": 0, + "data": { + "list": [], + "total": 0, + "pageNo": 1, + "pageSize": 10 + }, + "msg": "success" +} +``` + + +## SYS-002 接口视图 + +### 模块分组 + +#### 营收核心模块群 + +| 模块编号 | 模块名称 | 接口职责定位 | +|---------|----------|-------------| +| REV-001 | 客户资料管理 | 客户、账户、联系人、水表绑定等主数据查询与维护 | +| REV-002 | 抄表开账 | 抄表任务、抄表数据、校验、开账触发 | +| REV-003 | 营业收费 | 收费受理、账单核销、柜台与渠道收款状态回写 | +| REV-004 | 账务处理 | 调整、退款、冲正、坏账等账务处理申请与结果回写 | +| REV-005 | 发票管理 | 发票申请、开票结果回写、票据状态查询 | +| REV-006 | 催缴管理 | 催缴名单生成、催缴任务下发、通知结果回写 | +| REV-007 | 统计分析 | 营收、抄表、收费、客户、渠道统计查询 | +| REV-008 | 代收业务 | 银行代收、代扣、送盘、回盘、对账、结算协同 | +| REV-009 | 业务参数配置 | 水价、费用组成、业务参数、页面参数等配置接口 | + +#### 客户服务模块群 + +| 模块编号 | 模块名称 | 接口职责定位 | +|---------|----------|-------------| +| CS-001 | 账户绑定管理 | 客户绑定、解绑、默认客户切换 | +| CS-002 | 信息查询服务 | 账单、欠费、用水、缴费、停水公告等查询 | +| CS-003 | 在线缴费服务 | 创建线上支付订单、支付状态查询 | +| CS-004 | 电子发票服务 | 发票申请、发票列表、下载与推送 | +| CS-005 | 营业网点服务 | 网点查询、预约、导航、业务事项查询 | +| CS-006 | 业务办理服务 | 更名、过户、低保、换表、自主抄表等线上办理 | +| CS-007 | 柜面扫码支付 | 柜台二维码收款、订单生成、支付结果回写 | + +### 跨系统协同边界 + +| 协同子系统 | 协同内容 | SYS-002 职责 | 对方职责 | +|-----------|----------|--------------|----------| +| SYS-008 发票服务 | 发票开具、作废、红冲、票据查询 | 提供业务上下文、账单信息、客户开票信息,接收结果回写 | 承接税控与电子发票能力 | +| SYS-009 支付与银行结算 | 微信/支付宝支付、银行实时收费、代扣、对账、结算 | 发起订单、接收支付结果、维护账单核销状态 | 承接支付渠道、交易流水、回调、对账与结算 | +| SYS-010 消息服务 | 催缴通知、缴费结果通知、办理进度通知 | 生成待通知业务事件与目标用户 | 承接短信、微信公众号、站内信等触达能力 | + + +## 外部接口设计 + +## 外部接口分类 + +| 接口分类 | 主要对接方 | 典型协议 | 说明 | +|---------|------------|----------|------| +| 银行代收/代扣接口 | 银行、银联、托收平台 | 文件交换 / HTTPS REST | 主要服务 REV-008 | +| 聚合支付接口 | 微信支付、支付宝等 | HTTPS REST + 回调 | 主要服务 REV-003、CS-003、CS-007 | +| 发票协同接口 | 税控/电子发票平台 | HTTPS REST | 主要服务 REV-005、CS-004 | +| 消息通知接口 | 短信平台、消息网关 | HTTPS REST / MQ | 主要服务 REV-006、CS-006 | +| 物联网集抄接口 | 集抄平台、IoT 平台 | HTTPS REST / MQ | 主要服务 REV-002 | + +### IF-EXT-001 银行代扣批次下发接口 + +| 项目 | 说明 | +|------|------| +| 接口编号 | IF-EXT-001 | +| 接口名称 | 银行代扣批次下发接口 | +| 归属模块 | REV-008 | +| 调用方向 | SYS-002 → SYS-009 / 银行渠道 | +| 接口方式 | 文件交换或 HTTPS REST | +| 业务说明 | 按账期生成待代扣账单批次,交由银行渠道执行代扣 | +| 核心数据支撑 | `biz_withholding`、`bk_withholding_batch`、`bk_withholding_item` | + +关键报文信息包括:客户号、签约号、扣款金额、账期、渠道编码、批次号等。 + +边界约束: +- 当前正式设计包含代扣送盘、回盘与对账的目标边界;其中 `BankWithholding` 已具备送盘、送盘状态查询、取消送盘等六条银行入口的最小实现态闭环证据。 +- 正式文档可将 `BankWithholding` 六条银行入口写为“已实现”,但需同时注明真实银行文件解析、SFTP/文件通道联调与运行态样本仍待补证。 +- 涉及批量文件交互时,正式口径保留 `HTTP/REST/SFTP` 与文件命名、批次号约束,不下沉到特定银行私有报文字段。 +- 运行时文件传输配置统一由解析器输出 `protocol/resolvedDir/resolvedPath/fileName/sourceScope`;优先级固定为 `TENANT_CHANNEL > TENANT > CHANNEL > DEFAULT`,高优先级仅覆盖部分字段时按字段级回退。 +- 命中协议缺少 `host/port/username/credentialRef`、阶段目录为空或模板变量非法时,接口必须立即返回配置错误,不得回退到错误租户或错误通道。 + +### IF-EXT-002 银行代扣回盘接收接口 + +| 项目 | 说明 | +|------|------| +| 接口编号 | IF-EXT-002 | +| 接口名称 | 银行代扣回盘接收接口 | +| 归属模块 | REV-008 | +| 调用方向 | 银行渠道 / SYS-009 → SYS-002 | +| 接口方式 | 文件交换或 HTTPS REST | +| 业务说明 | 接收代扣成功、失败、退票等结果并回写业务状态 | +| 核心数据支撑 | `bk_withholding_batch`、`bk_withholding_item`、`bk_transaction`、`bk_transaction_exception` | + +边界约束: +- 回盘处理、回盘状态查询、差异核对和结算确认属于同一能力簇;其中 `BankWithholding` 的回盘与回盘状态查询已具备最小实现态闭环证据,但完整差异核对、异常补偿和结算确认仍属后续完善项。 +- 当前正式文档允许保留回盘文件名、批次号、回盘日期、结果状态等正式字段约束,但不得把未落地的真实文件解析、异常补偿和结算闭环写成既成事实。 + +### IF-EXT-003 银行实时收费接口 + +| 项目 | 说明 | +|------|------| +| 接口编号 | IF-EXT-003 | +| 接口名称 | 银行实时收费接口 | +| 归属模块 | REV-003 / REV-008 | +| 调用方向 | 银行渠道 / SYS-009 ↔ SYS-002 | +| 接口方式 | HTTPS REST | +| 业务说明 | 支撑柜台、网银、手机银行实时查询应收并完成缴费 | +| 核心数据支撑 | `biz_charge`、`biz_charge_detail`、`bk_transaction`、`bk_transaction_callback` | + +边界约束: +- 当前 backend 已确认欠费查询与缴费处理具备实现证据,可作为正式文档中的已落地基础能力。 +- 代理收费对账、汇总对账和当日未对账红冲等扩展能力当前仍未形成完整实现闭环,正式文档须标注为后续完善项。 + +### 银行签约、状态查询与批次控制扩展接口 + +| 接口动作 | 推荐归属 | 当前代码路径 | 当前状态 | 正式口径 | +|---------|----------|-------------|----------|----------| +| 代扣签约 | REV-008 / SYS-009 | `BankWithholdingController#signing` | 已实现 | 可作为正式接口能力写入 | +| 代扣解约 | REV-008 / SYS-009 | `BankWithholdingController#termination` | 已实现 | 可作为正式接口能力写入 | +| 托收签约 | REV-008 / SYS-009 | `BankCollectionController#signing` | 已实现 | 可作为正式接口能力写入 | +| 托收解约 | REV-008 / SYS-009 | `BankCollectionController#termination` | 已实现 | 可作为正式接口能力写入 | +| 客户状态查询 | REV-008 / SYS-009 | `BankWithholdingController#customerCheck` / `BankCollectionController#customerCheck` | 代扣已实现;托收部分实现 | 代扣可作为正式接口能力写入;托收仅保留正式契约边界与结果状态 | +| 送盘 | REV-008 / SYS-009 | `BankWithholdingController#sendDisc` / `BankCollectionController#sendDisc` | 代扣已实现;托收部分实现 | 代扣可作为正式接口能力写入;托收仅保留正式契约边界与批次发送语义 | +| 送盘状态查询 | REV-008 / SYS-009 | `BankWithholdingController#sendDiscCheck` / `BankCollectionController#sendDiscCheck` | 代扣已实现;托收部分实现 | 代扣可作为正式接口能力写入;托收仅保留正式契约边界与批次状态语义 | +| 取消送盘 | REV-008 / SYS-009 | `BankWithholdingController#cancelDisc` / `BankCollectionController#cancelDisc` | 代扣已实现;托收部分实现 | 代扣可作为正式接口能力写入;托收仅保留正式契约边界与可取消条件 | +| 回盘 | REV-008 / SYS-009 | `BankWithholdingController#backDisc` / `BankCollectionController#backDisc` | 代扣已实现;托收部分实现 | 代扣可作为正式接口能力写入;托收仅保留正式契约边界与回盘处理语义 | +| 回盘状态查询 | REV-008 / SYS-009 | `BankWithholdingController#backDiscCheck` / `BankCollectionController#backDiscCheck` | 代扣已实现;托收部分实现 | 代扣可作为正式接口能力写入;托收仅保留正式契约边界与回盘状态语义 | + +### IF-EXT-004 聚合支付下单接口 + +| 项目 | 说明 | +|------|------| +| 接口编号 | IF-EXT-004 | +| 接口名称 | 聚合支付下单接口 | +| 归属模块 | REV-003 / CS-003 / CS-007 | +| 调用方向 | SYS-002 → SYS-009 | +| 接口方式 | HTTPS REST | +| 业务说明 | 创建微信、支付宝等支付订单,返回二维码、收银参数或支付跳转信息 | +| 核心数据支撑 | `biz_charge`、`biz_collection`、`bk_transaction` | + +### IF-EXT-005 聚合支付结果回调接口 + +| 项目 | 说明 | +|------|------| +| 接口编号 | IF-EXT-005 | +| 接口名称 | 聚合支付结果回调接口 | +| 归属模块 | REV-003 / CS-003 / CS-007 | +| 调用方向 | SYS-009 → SYS-002 | +| 接口方式 | HTTPS REST + 签名校验 | +| 业务说明 | 接收支付成功、失败、关闭、退款等异步事件,并更新收费状态 | +| 核心数据支撑 | `bk_transaction_callback`、`biz_collection`、`biz_charge` | + +### IF-EXT-006 发票开具协同接口 + +| 项目 | 说明 | +|------|------| +| 接口编号 | IF-EXT-006 | +| 接口名称 | 发票开具协同接口 | +| 归属模块 | REV-005 / CS-004 | +| 调用方向 | SYS-002 → SYS-008 | +| 接口方式 | HTTPS REST | +| 业务说明 | 传递账单、客户、抬头、税率等信息,由 SYS-008 承接开票 | +| 核心数据支撑 | `biz_invoice`、`biz_invoice_taxrate`、`biz_cust_invoice` | + +### IF-EXT-007 发票结果回写接口 + +| 项目 | 说明 | +|------|------| +| 接口编号 | IF-EXT-007 | +| 接口名称 | 发票结果回写接口 | +| 归属模块 | REV-005 / CS-004 | +| 调用方向 | SYS-008 → SYS-002 | +| 接口方式 | HTTPS REST | +| 业务说明 | 回写开票状态、票据编号、下载地址、作废/红冲结果 | +| 核心数据支撑 | `biz_invoice`、`biz_process_invoice_modifys` | + +### IF-EXT-008 消息触达接口 + +| 项目 | 说明 | +|------|------| +| 接口编号 | IF-EXT-008 | +| 接口名称 | 消息触达接口 | +| 归属模块 | REV-006 / CS-006 | +| 调用方向 | SYS-002 → SYS-010 | +| 接口方式 | HTTPS REST 或 MQ | +| 业务说明 | 承接催缴通知、办理进度通知、缴费结果通知等消息事件,返回受理结果并回传执行结果 | +| 核心数据支撑 | `biz_charge`、`biz_process`、`biz_operat_log` | + +边界约束: +- `IF-EXT-008` 只负责渠道触达执行与回执回传,不负责催缴候选对象筛选、任务生成或业务状态主控。 +- `SYS-010` 回传的渠道执行结果需由 `SYS-002` 映射为 `PENDING`、`SUCCESS`、`FAIL`、`MANUAL_VERIFIED` 四态业务状态。 +- 当仅返回受理成功但未返回终态时,`SYS-002` 维持 `PENDING`;若长期无终态且人工核查确认,可转 `MANUAL_VERIFIED`。 +- 消息模板、供应商协议和重试细节由 `SYS-010` 管理,不在 `IF-EXT-008` 展开实现细节。 + +### IF-EXT-009 集抄数据接入接口 + +| 项目 | 说明 | +|------|------| +| 接口编号 | IF-EXT-009 | +| 接口名称 | 集抄数据接入接口 | +| 归属模块 | REV-002 | +| 调用方向 | IoT 平台 / 集抄平台 → SYS-002 | +| 接口方式 | HTTPS REST / MQ | +| 业务说明 | 接收远传读数、设备状态、异常告警,触发抄表校验与开账准备 | +| 核心数据支撑 | `biz_meter_read`、`biz_reading_data`、`biz_last_reading` | + + +## 内部接口设计 + +## SYS-002 内部接口清单 + +### REV 接口清单 + +| 接口编号 | 接口名称 | 归属模块 | 主要用途 | 主要数据对象 | +|---------|----------|----------|----------|-------------| +| IF-REV-001 | 客户信息查询接口 | REV-001 | 查询客户档案、联系人、账户、水表绑定关系 | `biz_cust`、`biz_account`、`biz_cust_contact`、`biz_cust_meter` | +| IF-REV-002 | 客户主数据维护接口 | REV-001 | 新增、变更客户档案及开票/托收/代扣关系 | `biz_cust`、`biz_cust_invoice`、`biz_cust_collection_rel`、`biz_cust_withholding_rel` | +| IF-REV-003 | 抄表任务下发接口 | REV-002 | 按册本、片区、抄表周期生成抄表任务 | `biz_meter_book`、`biz_meter_read` | +| IF-REV-004 | 抄表数据提交接口 | REV-002 | 提交抄表数据、图片、异常标记并触发校验 | `biz_reading_data`、`biz_reading_logs`、`biz_last_reading` | +| IF-REV-005 | 账单生成接口 | REV-002 | 根据抄表结果、价格模板和费用组成生成账单 | `biz_charge`、`biz_charge_detail`、`biz_price_template`、`biz_cost_component` | +| IF-REV-006 | 缴费处理接口 | REV-003 | 创建收费记录、核销账单、回写收款结果 | `biz_collection`、`biz_charge`、`bk_transaction` | +| IF-REV-007 | 账务调整接口 | REV-004 | 发起金额调整、退款、冲正、坏账等业务处理 | `biz_charge`、`biz_charge_detail`、`biz_operat_log` | +| IF-REV-008 | 发票申请接口 | REV-005 | 后台发起单笔/批量开票申请并生成受理主键 | `biz_invoice`、`biz_invoice_taxrate`、`biz_cust_invoice` | +| IF-REV-009 | 发票结果查询接口 | REV-005 | 按申请单号/受理号查询开票结果并执行补偿查询 | `biz_invoice`、`biz_operat_log` | +| IF-REV-013 | 催缴任务生成与结果承接接口 | REV-006 | 生成催缴任务、查询任务结果并承接四态状态回写 | `biz_charge`、`biz_operat_log`、历史催缴查询口径 | +| IF-REV-010 | 统计查询接口 | REV-007 | 查询营收、收费、欠费、渠道、客户统计结果 | 聚合视图 / 统计结果集 | +| IF-REV-011 | 银行代收协同接口 | REV-008 | 发起代扣、回盘、对账、结算协同 | `biz_withholding`、`bk_reconcile_batch`、`bk_settlement_batch` | +| IF-REV-012 | 业务参数配置接口 | REV-009 | 查询和维护价格模板、优惠方案、业务参数配置 | `biz_parameter_settings`、`biz_price_*`、`biz_page_settings*` | + +### CS 接口清单 + +| 接口编号 | 接口名称 | 归属模块 | 主要用途 | 主要数据对象 | +|---------|----------|----------|----------|-------------| +| IF-CS-001 | 账户绑定接口 | CS-001 | 绑定、解绑、切换默认客户 | `biz_cust_app_binds`、`biz_cust` | +| IF-CS-002 | 历史账单查询接口 | CS-002 | 查询账单、欠费、用水历史、缴费记录 | `biz_charge`、`biz_charge_detail`、`biz_reading_data` | +| IF-CS-003 | 在线支付下单接口 | CS-003 | 创建微信/支付宝线上支付订单 | `biz_charge`、`biz_collection`、`bk_transaction` | +| IF-CS-004 | 电子发票消费接口 | CS-004 | 查询、下载、推送本人已开具电子发票 | `biz_invoice`、`biz_cust_invoice` | +| IF-CS-005 | 网点与业务办理接口 | CS-005 | 查询营业网点、预约信息、可办事项 | `biz_outlets`、`biz_business_types` | +| IF-CS-006 | 业务办理进度接口 | CS-006 | 提交业务申请、查询办理进度与附件 | `biz_process`、`biz_process_transfer`、`biz_content_attach` | +| IF-CS-007 | 柜面扫码支付接口 | CS-007 | 创建柜面扫码支付订单并回写结果 | `biz_collection`、`bk_transaction`、`biz_charge` | + +### UP 接口清单 + +| 接口编号 | 接口名称 | 归属模块 | 主要用途 | 主要数据对象 | +|---------|----------|----------|----------|-------------| +| IF-UP-001 | 用户登录接口 | UP-001 | 用户登录并获取访问令牌 | `system_users`、`system_oauth2_access_token`、`system_login_log` | +| IF-UP-002 | 用户信息接口 | UP-001 | 查询当前登录用户上下文信息 | `system_users`、`system_dept` | +| IF-UP-003 | 权限校验接口 | UP-002 | 校验菜单、按钮、数据权限 | `system_role`、`system_role_menu`、`system_user_role` | +| IF-UP-004 | 参数字典接口 | UP-003 | 查询字典、参数、配置项 | `system_dict_type`、`system_dict_data`、`biz_parameter_settings` | + +### METER 接口清单 + +| 接口编号 | 接口名称 | 归属模块 | 主要用途 | 主要数据对象 | +|---------|----------|----------|----------|-------------| +| IF-METER-001 | 水表档案查询接口 | METER-001 | 查询水表档案、状态与生命周期信息 | `biz_meter`、`biz_meter_model`、`biz_meter_caliber`、`biz_meter_range` | +| IF-METER-002 | 表务工单处理接口 | METER-003 | 提交换表、移表、校表、维修等工单处理结果 | `biz_meter_log`、`biz_process`、`biz_process_transfer` | +| IF-METER-003 | 库存出入库接口 | METER-002 | 处理领用、退库、报废等库存动作 | `biz_meter_in_out`、`biz_meter_in_out_rel` | +| IF-METER-004 | 集抄数据接收接口 | METER-003 | 接收远传抄表、异常告警并同步状态 | `biz_reading_data`、`biz_meter_read`、`biz_last_reading` | + +### INST 接口清单 + +| 接口编号 | 接口名称 | 归属模块 | 主要用途 | 主要数据对象 | +|---------|----------|----------|----------|-------------| +| IF-INST-001 | 报装申请提交接口 | INST-001 | 提交报装申请、附件与基础资料 | `biz_process`、`biz_content`、`biz_content_attach` | +| IF-INST-002 | 踏勘结果回填接口 | INST-001 | 回填现场踏勘、方案与审核结果 | `biz_process_transfer`、`biz_business_datas` | +| IF-INST-003 | 合同签署发起接口 | INST-002 | 发起电子签章任务并传输合同信息 | `installation_contract`、`installation_signature` | +| IF-INST-004 | 签章回执接口 | INST-002 | 回写签章结果、时间戳和存证信息 | `installation_signature`、`installation_evidence` | +| IF-INST-005 | 报装归档接口 | INST-003 | 归档申请、合同、验收与签章回执资料 | `biz_content_attach`、`installation_evidence` | + +## 关键内部接口说明 + +### IF-UP-001 用户登录接口 + +| 项目 | 说明 | +|------|------| +| 接口编号 | IF-UP-001 | +| 归属模块 | UP-001 | +| 请求方式 | POST | +| 请求路径 | `/admin-api/system/auth/login` | +| 功能描述 | 统一认证入口,签发访问令牌并输出用户上下文 | +| 核心表 | `system_users`、`system_oauth2_access_token`、`system_login_log` | + +### IF-REV-001 客户信息查询接口 + +| 项目 | 说明 | +|------|------| +| 接口编号 | IF-REV-001 | +| 归属模块 | REV-001 | +| 请求方式 | GET | +| 请求路径 | `/admin-api/revenue/customer/{id}` | +| 功能描述 | 查询客户主档、账户状态、联系人、水表绑定及开票资料 | +| 核心表 | `biz_cust`、`biz_account`、`biz_cust_contact`、`biz_cust_meter`、`biz_cust_invoice` | + +响应结果以客户主档为中心,组合返回账户余额、欠费金额、联系人列表、水表列表与开票资料摘要。 + +### IF-REV-004 抄表数据提交接口 + +| 项目 | 说明 | +|------|------| +| 接口编号 | IF-REV-004 | +| 归属模块 | REV-002 | +| 请求方式 | POST | +| 请求路径 | `/admin-api/revenue/reading-data/create` | +| 功能描述 | 接收人工或远传抄表数据,执行校验、估抄判断、异常标记 | +| 核心表 | `biz_meter_read`、`biz_reading_data`、`biz_last_reading`、`biz_reading_logs` | + +典型请求体: + +```json +{ + "meterReadId": 1001, + "meterId": 2001, + "readTime": "2026-03-11 09:30:00", + "currentReading": 156.32, + "readType": "MANUAL", + "photoList": [ + "file-001", + "file-002" + ], + "gps": "119.2965,26.0745", + "remark": "现场抄表正常" +} +``` + +### IF-REV-005 账单生成接口 + +| 项目 | 说明 | +|------|------| +| 接口编号 | IF-REV-005 | +| 归属模块 | REV-002 | +| 请求方式 | POST | +| 请求路径 | `/admin-api/revenue/charge/generate` | +| 功能描述 | 基于抄表结果、水价模板、阶梯规则、费用组成生成账单,并返回成功清单、失败清单与生成汇总 | +| 核心表 | `biz_charge`、`biz_charge_detail`、`biz_price_template`、`biz_price_tier_adjustment`、`biz_cost_component` | + +边界约束: +- 本接口只负责抄表校验完成后的账单生成,不直接承接收费核销、发票申请、催缴执行或统计汇总。 +- 正式请求范围可按抄表批次、客户集合或抄表任务集合组织;当前 backend 已实现入口为 `/business/charge/charge-batch` 与 `/business/charge/check-charge-batch`,请求体仅接受 `readingDataIds`。 +- 价格模板、费用组成、阶梯规则、计划用水方案等任一关键规则缺失时,应阻断生成并返回失败原因,而不是生成不完整账单。 +- 特殊开账、无码客户开账、罚款类开账等非标准来源仍沿用同一 `biz_charge` / `biz_charge_detail` 承接口径,不单设平行在线账表。 +- 当前实现仅支持 `SettleTypeEnum.ACTUAL_USAGE`;固定水量、按人口数、最低消费等结算方式暂未纳入现有开账链路。 + +当前 backend 证据与契约缺口: +- `ChargeServiceImpl.generateCheckChargeBatch` 已支持“批量复核 + 批量开账”,并通过 `generateSingleChargeWithCache` 写入 `biz_charge`、`biz_charge_detail`,说明主明细承接路径已存在。 +- 返回值当前为 `CommonResult`,仅表达“本次复核成功X条 / 本次开账成功Y条”,尚未提供正式契约要求的成功清单、失败清单、生成汇总和主明细结果对象。 +- 单条失败当前主要以 `log.warn` + `false` 跳过处理,尚未形成可直接对外返回的结构化阻断码、失败原因集合与对象范围。 + +### IF-REV-006 缴费处理接口 + +| 项目 | 说明 | +|------|------| +| 接口编号 | IF-REV-006 | +| 归属模块 | REV-003 | +| 请求方式 | POST | +| 请求路径 | `/admin-api/revenue/collection/create` | +| 功能描述 | 处理柜台收费、预存抵扣、渠道收款确认与账单核销 | +| 核心表 | `biz_collection`、`biz_charge`、`bk_transaction` | + +### IF-REV-007 账务调整接口 + +| 项目 | 说明 | +|------|------| +| 接口编号 | IF-REV-007 | +| 归属模块 | REV-004 | +| 请求方式 | POST | +| 请求路径 | `/admin-api/revenue/accounting/adjust` | +| 功能描述 | 发起水量调整、金额调整、退款、冲正、坏账申请五类账务处理,并统一返回处理结果、审批边界与账单回写状态 | +| 核心表 | `biz_charge`、`biz_charge_detail`、`biz_operat_log`、`bk_transaction*` | + +边界约束: +- 一期仅覆盖 `USAGE`、`AMOUNT`、`REFUND`、`REVERSE`、`BAD_DEBT` 五类 `adjustType`。 +- 退款、冲正必须提供 `sourceTradeNo` 并完成原交易校验;其他场景不得误用支付流水替代业务依据。 +- 审批相关内容仅保留 `approvalRequired`、`PENDING_APPROVAL` 与边界说明,不展开 BPM 节点与审批回写实现细节。 +- `resultStatus` 与 `writeBackStatus` 必须分离表达,前者表示处理结论,后者表示账单状态回写结论。 + +### IF-REV-008 发票申请接口 + +| 项目 | 说明 | +|------|------| +| 接口编号 | IF-REV-008 | +| 归属模块 | REV-005 | +| 请求方式 | POST | +| 请求路径 | `/business/invoice/apply` | +| 功能描述 | 后台对已收费未开票账单发起单笔/批量开票申请,并在同一管理域内受理作废/红冲后处理入口 | +| 核心表 | `biz_invoice`、`biz_invoice_taxrate`、`biz_cust_invoice` | + +边界约束: +- 一期仅支持后台营业收费员/财务人员发起申请,客户侧不直接调用本接口。 +- 发票开具、作废、红冲能力均由 `SYS-008` 统一承接税控侧处理,`SYS-002` 负责业务单据归集、申请发起、后台作废/红冲触发、查询补偿与结果落账。 +- 后台发票后处理沿同一管理域补充 `/business/invoice/invalidate` 与 `/business/invoice/red-ink` 两个入口,分别承接作废与红冲动作;处理结果继续通过 `IF-REV-009` 或 `IF-EXT-007` 统一收口。 +- 原始单账单不支持直接任意部分金额开票;如需多张发票,应基于拆账/分账后的账单集合申请。 + +### IF-REV-009 发票结果查询接口 + +| 项目 | 说明 | +|------|------| +| 接口编号 | IF-REV-009 | +| 归属模块 | REV-005 | +| 请求方式 | POST | +| 请求路径 | `/business/invoice/query`(补偿查询:`/business/invoice/query/compensate`) | +| 功能描述 | 后台按申请单号/受理号查询开票、作废或红冲结果,并支持系统补偿查询兜底 | +| 核心表 | `biz_invoice`、`biz_operat_log` | + +### IF-REV-013 催缴任务生成与结果承接接口 + +| 项目 | 说明 | +|------|------| +| 接口编号 | IF-REV-013 | +| 归属模块 | REV-006 | +| 请求方式 | POST | +| 请求路径 | `/admin-api/revenue/reminder/task`(查询:`/admin-api/revenue/reminder/task/query`,人工核查:`/admin-api/revenue/reminder/task/manual-verify`) | +| 功能描述 | 基于欠费账单、催缴策略和渠道偏好生成催缴任务,查询任务状态,并承接业务侧四态结果与处置引用 | +| 核心表 | `biz_charge`、`biz_charge_detail`、`biz_operat_log`、历史催缴查询口径 | + +边界约束: +- `IF-REV-013` 是 `REV-006` 的正式业务接口编号,不再复用 `IF-REV-009`。 +- `SYS-002` 负责催缴对象筛选、任务生成、业务事件号维护、四态状态承接和历史查询;`SYS-010` 只负责触达执行与结果回传。 +- 接口状态固定为 `PENDING`、`SUCCESS`、`FAIL`、`MANUAL_VERIFIED` 四态,不在本轮扩展“已阅读”“已补发”等细粒度业务状态。 +- 停复水仅作为联动边界与处置引用承接项,不在本接口中展开停复水内部流程。 + +### IF-REV-010 统计查询接口 + +| 项目 | 说明 | +|------|------| +| 接口编号 | IF-REV-010 | +| 归属模块 | REV-007 | +| 请求方式 | POST | +| 请求路径 | `/admin-api/revenue/statistics/query`(导出:`/admin-api/revenue/statistics/export`) | +| 功能描述 | 面向营收经营分析场景查询统计主题、维度汇总和指标结果,并在权限范围内支持导出 | +| 核心表 | `biz_charge`、`biz_charge_detail`、`biz_collection`、`bk_transaction`、`biz_cust`、`biz_account`、`biz_meter_book`、`biz_reading_data` | + +边界约束: +- `IF-REV-010` 只承接经营统计查询,不扩展到预测分析、BI 专题大屏或独立数仓查询。 +- 统计口径按“主题 + 维度 + 指标”组织,避免仅以报表名称表达接口范围。 +- 导出属于查询扩展能力,必须受数据权限和导出权限控制。 +- 没有明确实现证据的独立统计表、专题分析表或离线汇总表不得写成既成事实。 + +### IF-REV-011 银行代收协同接口 + +| 项目 | 说明 | +|------|------| +| 接口编号 | IF-REV-011 | +| 归属模块 | REV-008 | +| 请求方式 | POST | +| 请求路径 | `/admin-api/revenue/bank/withholding/batch` | +| 功能描述 | 创建代扣批次、发起对账、接收结算回写 | +| 核心表 | `biz_withholding`、`bk_withholding_batch`、`bk_reconcile_batch`、`bk_settlement_batch` | + +边界约束: +- `IF-REV-011` 在当前阶段主要承接正式业务协同边界,不等同于送盘、回盘、对账、结算全部已闭环。 +- 已确认的后台管理入口可证明批次、差异、结算台账对象存在,但不能替代银行 app 协同接口的完成度判断。 + +### IF-REV-012 业务参数配置接口 + +| 项目 | 说明 | +|------|------| +| 接口编号 | IF-REV-012 | +| 归属模块 | REV-009 | +| 请求方式 | GET / POST | +| 请求路径 | `/admin-api/revenue/parameter/config` | +| 功能描述 | 查询与维护价格模板、业务参数、页面参数与规则配置 | +| 核心表 | `biz_parameter_settings`、`biz_price_*`、`biz_page_settings*` | + +### IF-CS-001 账户绑定接口 + +| 项目 | 说明 | +|------|------| +| 接口编号 | IF-CS-001 | +| 归属模块 | CS-001 | +| 请求方式 | POST | +| 请求路径 | `/app-api/customer/account/bind` | +| 功能描述 | 绑定、解绑、切换默认客户账户,并校验渠道身份与客户关系 | +| 核心表 | `biz_cust_app_binds`、`biz_cust`、`biz_account` | + +### IF-CS-002 历史账单查询接口 + +| 项目 | 说明 | +|------|------| +| 接口编号 | IF-CS-002 | +| 归属模块 | CS-002 | +| 请求方式 | GET | +| 请求路径 | `/app-api/customer/bill/history` | +| 功能描述 | 查询账单、欠费、缴费、用水历史及发票摘要 | +| 核心表 | `biz_charge`、`biz_charge_detail`、`biz_reading_data`、`biz_invoice` | + +### IF-CS-003 在线支付下单接口 + +| 项目 | 说明 | +|------|------| +| 接口编号 | IF-CS-003 | +| 归属模块 | CS-003 | +| 请求方式 | POST | +| 请求路径 | `/app-api/customer/payment/order` | +| 功能描述 | 面向微网厅、微信、支付宝等客户渠道创建支付订单 | +| 核心表 | `biz_charge`、`biz_collection`、`bk_transaction` | + +边界约束: +- 支付通道、支付回调、对账流水由 `SYS-009` 负责。 +- `SYS-002` 负责校验待缴账单、生成业务订单、更新核销结果。 + +### IF-CS-004 电子发票消费接口 + +| 项目 | 说明 | +|------|------| +| 接口编号 | IF-CS-004 | +| 归属模块 | CS-004 | +| 请求方式 | POST | +| 请求路径 | `/business/invoice/customer/query`、`/business/invoice/customer/download`、`/business/invoice/customer/push` | +| 功能描述 | 面向客户渠道查询、下载、推送本人已开具电子发票 | +| 核心表 | `biz_invoice`、`biz_cust_invoice`、`biz_invoice_taxrate` | + +边界约束: +- 一期客户侧仅消费已形成 `SUCCESS` 终态且具备票据地址的电子发票结果,不直接发起开票申请。 +- 发票作废、红冲仍由 `SYS-008` 统一承接税控侧处理;`IF-CS-004` 仅消费当前仍可展示、下载、推送的有效电子发票结果,不开放客户侧直接发起作废或红冲。 + +### IF-CS-006 业务办理进度接口 + +| 项目 | 说明 | +|------|------| +| 接口编号 | IF-CS-006 | +| 归属模块 | CS-006 | +| 请求方式 | GET / POST | +| 请求路径 | `/app-api/customer/process` | +| 功能描述 | 提交业务办理申请、查询办理进度、补充附件资料 | +| 核心表 | `biz_process`、`biz_process_transfer`、`biz_business_datas`、`biz_content_attach` | + +### IF-CS-007 柜面扫码支付接口 + +| 项目 | 说明 | +|------|------| +| 接口编号 | IF-CS-007 | +| 归属模块 | CS-007 | +| 请求方式 | POST | +| 请求路径 | `/admin-api/counter/scan-pay/create` | +| 功能描述 | 柜台生成扫码订单,接收支付结果并回写收费状态 | +| 核心表 | `biz_collection`、`bk_transaction`、`biz_charge` | + +### IF-METER-001 水表档案查询接口 + +| 项目 | 说明 | +|------|------| +| 接口编号 | IF-METER-001 | +| 归属模块 | METER-001 | +| 请求方式 | GET | +| 请求路径 | `/admin-api/meter/archive/{id}` | +| 功能描述 | 查询水表档案、状态、参数与生命周期信息 | +| 核心表 | `biz_meter`、`biz_meter_model`、`biz_meter_caliber`、`biz_meter_range` | + +### IF-METER-002 表务工单处理接口 + +| 项目 | 说明 | +|------|------| +| 接口编号 | IF-METER-002 | +| 归属模块 | METER-003 | +| 请求方式 | POST | +| 请求路径 | `/admin-api/meter/work-order/handle` | +| 功能描述 | 提交换表、移表、校表、维修等工单处理结果并回写设备状态 | +| 核心表 | `biz_meter_log`、`biz_process`、`biz_process_transfer` | + +### IF-METER-003 库存出入库接口 + +| 项目 | 说明 | +|------|------| +| 接口编号 | IF-METER-003 | +| 归属模块 | METER-002 | +| 请求方式 | POST | +| 请求路径 | `/admin-api/meter/stock/in-out` | +| 功能描述 | 处理领用、退库、报废等库存动作并更新生命周期状态 | +| 核心表 | `biz_meter_in_out`、`biz_meter_in_out_rel`、`biz_meter` | + +### IF-METER-004 集抄数据接收接口 + +| 项目 | 说明 | +|------|------| +| 接口编号 | IF-METER-004 | +| 归属模块 | METER-003 | +| 请求方式 | POST | +| 请求路径 | `/admin-api/meter/iot/reading/receive` | +| 功能描述 | 接收远传抄表、设备状态和异常告警并同步读数状态 | +| 核心表 | `biz_reading_data`、`biz_meter_read`、`biz_last_reading` | + +### IF-INST-001 报装申请提交接口 + +| 项目 | 说明 | +|------|------| +| 接口编号 | IF-INST-001 | +| 归属模块 | INST-001 | +| 请求方式 | POST | +| 请求路径 | `/admin-api/installation/apply/create` | +| 功能描述 | 提交报装申请、基础资料与附件,并创建流程实例 | +| 核心表 | `biz_process`、`biz_content`、`biz_content_attach` | + +### IF-INST-002 踏勘结果回填接口 + +| 项目 | 说明 | +|------|------| +| 接口编号 | IF-INST-002 | +| 归属模块 | INST-001 | +| 请求方式 | POST | +| 请求路径 | `/admin-api/installation/survey/result` | +| 功能描述 | 回填现场踏勘结果、方案版本和审核结论 | +| 核心表 | `biz_process_transfer`、`biz_business_datas` | + +### IF-INST-003 合同签署发起接口 + +| 项目 | 说明 | +|------|------| +| 接口编号 | IF-INST-003 | +| 归属模块 | INST-002 | +| 请求方式 | POST | +| 请求路径 | `/admin-api/installation/contract/sign/initiate` | +| 功能描述 | 发起报装合同签署流程,并与 CA 系统协同处理签章、时间戳和存证 | +| 核心表 | `installation_contract`、`installation_signature`、`installation_evidence` | + +### IF-INST-004 签章回执接口 + +| 项目 | 说明 | +|------|------| +| 接口编号 | IF-INST-004 | +| 归属模块 | INST-002 | +| 请求方式 | POST | +| 请求路径 | `/admin-api/installation/contract/sign/callback` | +| 功能描述 | 回写签章结果、时间戳、存证回执与签章文件地址 | +| 核心表 | `installation_signature`、`installation_evidence` | + +### IF-INST-005 报装归档接口 + +| 项目 | 说明 | +|------|------| +| 接口编号 | IF-INST-005 | +| 归属模块 | INST-003 | +| 请求方式 | POST | +| 请求路径 | `/admin-api/installation/archive/submit` | +| 功能描述 | 归档申请资料、验收附件、合同文件与签章回执 | +| 核心表 | `biz_content_attach`、`installation_evidence`、`biz_process` | + +## 字段级请求与响应定义 + +> 说明:以下字段级定义服务于接口设计说明,重点体现业务含义、来源对象与跨系统协同所需关键字段,不等同于数据库表的完整字段清单。 + +### IF-REV-001 客户信息查询接口 + +#### 请求参数 + +| 字段 | 类型 | 必填 | 说明 | 主要来源 | +|------|------|------|------|----------| +| id | Long | 否 | 客户主键 ID,与 `code` 二选一 | `biz_cust.id` | +| code | String | 否 | 客户编号,与 `id` 二选一 | `biz_cust.code` | +| mobile | String | 否 | 客户手机号,支持模糊校验查询 | `biz_cust.mobile` / `biz_cust_contact.mobile` | +| queryType | String | 否 | 查询类型:`base`、`account`、`meter`、`invoice`、`all` | 查询控制参数 | + +#### 响应参数 + +| 字段 | 类型 | 说明 | 主要来源 | +|------|------|------|----------| +| id | Long | 客户主键 ID | `biz_cust.id` | +| code | String | 客户编号 | `biz_cust.code` | +| name | String | 客户名称 | `biz_cust.name` | +| custType | String | 客户类型 | `biz_cust.cust_type` | +| mobile | String | 主要联系电话 | `biz_cust.mobile` | +| address | String | 客户地址 | `biz_cust.address` | +| accountInfo | Object | 账户信息对象 | `biz_account` | +| accountInfo.balance | Decimal | 账户余额 | `biz_account.balance` | +| accountInfo.arrearsAmount | Decimal | 欠费金额 | `biz_account.arrears_amount` | +| accountInfo.status | String | 账户状态 | `biz_account.status` | +| contactList | Array | 联系人列表 | `biz_cust_contact` | +| meterList | Array | 绑定水表列表 | `biz_cust_meter`、`biz_meter` | +| invoiceInfo | Object | 开票信息摘要 | `biz_cust_invoice` | + +### IF-REV-004 抄表数据提交接口 + +#### 请求参数 + +| 字段 | 类型 | 必填 | 说明 | 主要来源/去向 | +|------|------|------|------|---------------| +| meterReadId | Long | 是 | 抄表任务 ID | `biz_meter_read.id` | +| meterId | Long | 是 | 水表 ID | `biz_meter.id` | +| readTime | Datetime | 是 | 抄表时间 | `biz_reading_data.read_time` | +| currentReading | Decimal | 是 | 本次读数 | `biz_reading_data.current_reading` | +| readType | String | 是 | 抄表方式:`MANUAL`、`IOT`、`IMPORT` | `biz_reading_data.read_type` | +| usageAmount | Decimal | 否 | 本次用量,可由系统自动计算 | `biz_reading_data.usage_amount` | +| photoList | Array | 否 | 表盘照片或现场图片文件标识 | 附件系统 / 文件服务 | +| gps | String | 否 | 现场坐标 | 扩展信息 | +| remark | String | 否 | 异常说明或现场备注 | `biz_reading_logs.remark` | +| abnormalFlag | Boolean | 否 | 是否标记异常 | 过程状态 | + +#### 响应参数 + +| 字段 | 类型 | 说明 | 主要来源 | +|------|------|------|----------| +| readingId | Long | 抄表数据主键 | `biz_reading_data.id` | +| meterReadId | Long | 抄表任务 ID | `biz_meter_read.id` | +| validateStatus | String | 校验状态:`PASS`、`WARN`、`REJECT` | 校验结果 | +| abnormalFlag | Boolean | 是否识别为异常 | 过程判断 | +| nextAction | String | 后续动作:`BILLING`、`RECHECK`、`MANUAL_REVIEW` | 流程控制 | +| msg | String | 处理说明 | 返回消息 | + +### IF-REV-005 账单生成接口 + +#### 请求参数 + +| 字段 | 类型 | 必填 | 说明 | 主要来源/去向 | +|------|------|------|------|---------------| +| billPeriod | String | 是 | 账期,如 `2026-03` | 开账批次参数 | +| readingBatchNo | String | 否 | 抄表批次号 | 抄表批次 | +| customerIds | Array | 否 | 指定客户范围 | `biz_cust.id` | +| meterReadIds | Array | 否 | 指定抄表任务范围 | `biz_meter_read.id` | +| dueDate | Date | 是 | 应收截止日期 | `biz_charge.due_date` | +| operatorId | Long | 否 | 发起操作人 | 操作上下文 | + +#### 响应参数 + +| 字段 | 类型 | 说明 | 主要来源 | +|------|------|------|----------| +| generateCount | Integer | 成功生成账单数量 | 汇总信息 | +| successList | Array | 成功明细列表 | `biz_charge` | +| successList[].chargeId | Long | 账单主键 | `biz_charge.id` | +| successList[].chargeCode | String | 账单编号 | `biz_charge.code` | +| successList[].custId | Long | 客户 ID | `biz_charge.cust_id` | +| successList[].totalAmount | Decimal | 账单总金额 | `biz_charge.total_amount` | +| failureList | Array | 失败明细列表 | 处理结果 | +| failureList[].reason | String | 失败原因 | 异常信息 | + +### IF-REV-006 缴费处理接口 + +#### 请求参数 + +| 字段 | 类型 | 必填 | 说明 | 主要来源/去向 | +|------|------|------|------|---------------| +| custId | Long | 是 | 客户 ID | `biz_charge.cust_id` | +| chargeIds | Array | 是 | 待核销账单 ID 列表 | `biz_charge.id` | +| paymentChannel | String | 是 | 支付渠道:`CASH`、`WECHAT`、`ALIPAY`、`BANK`、`PREPAY` | 渠道参数 | +| paymentAmount | Decimal | 是 | 本次支付金额 | `biz_collection.amount` | +| actualAmount | Decimal | 否 | 实收金额,柜台收费场景使用 | 柜台收费扩展 | +| tradeNo | String | 否 | 外部交易流水号 | `bk_transaction.trade_no` | +| outletCode | String | 否 | 柜台或网点编号 | `biz_outlets.code` | +| remark | String | 否 | 收费备注 | `biz_collection.remark` | + +#### 响应参数 + +| 字段 | 类型 | 说明 | 主要来源 | +|------|------|------|----------| +| collectionId | Long | 收费记录 ID | `biz_collection.id` | +| collectionCode | String | 收费业务编号 | `biz_collection.code` | +| writeOffStatus | String | 核销状态:`SUCCESS`、`PARTIAL`、`PENDING` | 业务状态 | +| paidAmount | Decimal | 已支付金额 | 汇总结果 | +| remainAmount | Decimal | 剩余待支付金额 | 汇总结果 | +| tradeNo | String | 渠道交易流水号 | `bk_transaction.trade_no` | +| invoiceAvailable | Boolean | 是否可发起开票 | 业务判断 | + +### IF-REV-007 账务调整接口 + +#### 请求参数 + +| 字段 | 类型 | 必填 | 说明 | 主要来源/去向 | +|------|------|------|------|---------------| +| chargeId | Long | 是 | 目标账单 ID | `biz_charge.id` | +| adjustType | String | 是 | 调整类型:`USAGE`、`AMOUNT`、`REFUND`、`REVERSE`、`BAD_DEBT` | 业务类型 | +| adjustAmount | Decimal | 否 | 调整金额 | `biz_charge_detail` / 业务计算 | +| adjustUsage | Decimal | 否 | 调整水量 | 业务计算 | +| sourceTradeNo | String | 否 | 原交易流水号,退款/冲正场景使用 | `bk_transaction.trade_no` | +| reasonCode | String | 是 | 调整原因编码 | 业务字典 | +| remark | String | 否 | 调整说明 | `biz_operat_log.remark` | +| attachmentList | Array | 否 | 依据附件 | 附件系统 | +| operatorId | Long | 是 | 操作人 ID | 操作上下文 | + +#### 响应参数 + +| 字段 | 类型 | 说明 | 主要来源 | +|------|------|------|----------| +| adjustmentNo | String | 调整业务编号 | 业务流水 | +| chargeId | Long | 目标账单 ID | `biz_charge.id` | +| resultStatus | String | 处理状态:`SUCCESS`、`PENDING_APPROVAL`、`FAIL` | 业务状态 | +| writeBackStatus | String | 账单回写状态 | 业务状态 | +| approvalRequired | Boolean | 是否进入审批 | 流程判断 | +| msg | String | 处理说明 | 返回消息 | + +### IF-REV-008 发票申请接口 + +#### 请求参数 + +| 字段 | 类型 | 必填 | 说明 | 主要来源/去向 | +|------|------|------|------|---------------| +| applicationNo | String | 否 | 发票申请单号 | 服务端生成,作为幂等主键之一 | +| custId | Long | 是 | 客户 ID | `biz_invoice.cust_id` | +| chargeIds | Array | 是 | 开票关联账单 ID 列表 | 业务单据关联 | +| invoiceType | String | 是 | 发票类型:`ELECTRONIC`、`PAPER` | `biz_invoice.invoice_type` | +| invoiceTitle | String | 是 | 发票抬头 | `biz_cust_invoice.invoice_title` | +| taxNo | String | 否 | 税号 | `biz_cust_invoice.tax_no` | +| email | String | 否 | 电子发票接收邮箱 | `biz_cust_invoice.email` | +| mobile | String | 否 | 接收手机号 | `biz_cust_invoice.mobile` | +| sourceChannel | String | 是 | 来源渠道:`COUNTER`、`FINANCE_BACKOFFICE` | 业务来源 | +| remark | String | 否 | 申请备注 | 操作留痕 | + +#### 响应参数 + +| 字段 | 类型 | 说明 | 主要来源 | +|------|------|------|----------| +| invoiceId | Long | 发票申请记录 ID | `biz_invoice.id` | +| applicationNo | String | 发票申请单号 | `biz_invoice.application_no` | +| invoiceStatus | String | 状态:`SUBMITTED`、`PENDING`、`REJECTED` | `biz_invoice.invoice_status` | +| sysRequestNo | String | 发往 `SYS-008` 的受理号 | 协同流水 | +| msg | String | 处理说明 | 返回消息 | + +#### 申请校验与幂等约束 + +- 所有关联账单必须满足“已收费、未开票、未作废”。 +- 一期不支持原始单账单直接任意部分金额开票;如需多张发票,必须基于拆账/分账后的账单集合发起申请。 +- 企业抬头场景应校验 `taxNo` 完整性;电子发票场景优先校验 `email` 或 `mobile` 至少一项可用。 +- 幂等键优先使用 `applicationNo`,未传入时按 `custId + chargeIds` 组合控制重复申请。 +- 申请成功后必须创建查询补偿上下文,不依赖回调作为唯一结果来源。 + +#### 后台作废请求参数(`/business/invoice/invalidate`) + +| 字段 | 类型 | 必填 | 说明 | 主要来源/去向 | +|------|------|------|------|---------------| +| invoiceId | Long | 是 | 发票记录 ID | `biz_invoice.id` | +| invalidReason | String | 是 | 作废原因 | `biz_invoice.invalid_reason` | +| invalidRemark | String | 否 | 作废备注 | `biz_invoice.invalid_remark` | +| originalInvoiceCode | String | 否 | 原发票代码;传入时必须与当前发票记录一致 | `biz_invoice.original_invoice_code` | +| originalInvoiceNumber | String | 否 | 原发票号码;传入时必须与当前发票记录一致 | `biz_invoice.original_invoice_number` | + +#### 后台红冲请求参数(`/business/invoice/red-ink`) + +| 字段 | 类型 | 必填 | 说明 | 主要来源/去向 | +|------|------|------|------|---------------| +| invoiceId | Long | 是 | 发票记录 ID | `biz_invoice.id` | +| redInkReason | String | 是 | 红冲原因 | `biz_invoice.red_ink_reason` | +| redInkRemark | String | 否 | 红冲备注 | `biz_invoice.red_ink_remark` | +| originalInvoiceCode | String | 否 | 原发票代码;传入时必须与当前发票记录一致 | `biz_invoice.original_invoice_code` | +| originalInvoiceNumber | String | 否 | 原发票号码;传入时必须与当前发票记录一致 | `biz_invoice.original_invoice_number` | + +#### 后台作废/红冲处理约束 + +- 作废与红冲仅允许对当前 `invoiceStatus=SUCCESS` 的记录发起;已进入 `INVALID` 或 `RED_INK` 的记录必须拒绝重复处理。 +- 后台提交作废或红冲后,应同步写入原因、备注、原票引用与触发来源,当前实现的触发来源分别为 `ADMIN_INVALIDATE`、`ADMIN_RED_INK`。 +- 作废与红冲的即时返回仅表示后台已受理本次后处理动作;最终状态仍通过 `IF-REV-009` 查询补偿或 `IF-EXT-007` 回写统一收口。 +- 后处理动作必须保留操作日志,记录触发人、目标状态、原因、备注与原发票代码/号码。 + +### IF-REV-009 发票结果查询接口 + +#### 请求参数 + +| 字段 | 类型 | 必填 | 说明 | 主要来源/去向 | +|------|------|------|------|---------------| +| applicationNo | String | 否 | 发票申请单号,与 `sysRequestNo` 二选一 | `biz_invoice.application_no` | +| sysRequestNo | String | 否 | `SYS-008` 受理号,与 `applicationNo` 二选一 | `biz_invoice.sys_request_no` | +| querySource | String | 是 | 查询来源:`MANUAL`、`AUTO_COMPENSATE`、`CALLBACK_VERIFY` | 查询触发上下文 | + +#### 响应参数 + +| 字段 | 类型 | 说明 | 主要来源 | +|------|------|------|----------| +| invoiceId | Long | 发票主记录 ID | `biz_invoice.id` | +| applicationNo | String | 发票申请单号 | `biz_invoice.application_no` | +| sysRequestNo | String | `SYS-008` 受理号 | `biz_invoice.sys_request_no` | +| invoiceStatus | String | 状态:`SUBMITTED`、`PENDING`、`SUCCESS`、`FAIL`、`INVALID`、`RED_INK` | `biz_invoice.invoice_status` | +| invoiceCode | String | 发票代码 | `biz_invoice.invoice_code` | +| invoiceNumber | String | 发票号码 | `biz_invoice.invoice_number` | +| fileUrl | String | 电子发票文件地址 | `biz_invoice.file_url` | +| failReason | String | 失败原因 | `biz_invoice.fail_reason` | +| pushStatus | String | 电子发票推送状态 | `biz_invoice.push_status` | +| lastQueryTime | DateTime | 最近一次查询时间 | `biz_invoice.last_try_time` | +| tryCount | Integer | 累计查询次数 | `biz_invoice.try_count` | +| latestResult | String | 最近一次查询结果摘要 | `biz_invoice.latest_result` | +| latestError | String | 最近一次查询异常说明 | `biz_invoice.latest_error` | +| msg | String | 处理说明 | 返回消息 | + +#### 查询补偿与状态流转约束 + +- 查询入口同时服务于后台人工查询与系统补偿查询,两类触发必须复用同一状态落账规则。 +- 当 `querySource=AUTO_COMPENSATE` 时,接口语义表示由系统补偿任务触发一次兜底查询,并刷新最近查询时间、下次计划时间与累计次数。 +- 查询结果若确认开票成功,应回写票号、票据地址与账单-发票关联状态;若仍处理中,仅维持 `PENDING` 并更新补偿上下文。 +- 对已发起作废或红冲的记录,查询结果应允许把终态更新为 `INVALID` 或 `RED_INK`,并同步刷新 `latestResult`、`latestError`、账单关联状态与后处理上下文。 +- 已进入 `SUCCESS` 的正常开票终态不得被后续失败查询结果覆盖;若外部返回异常,应记录到操作留痕并保留人工核查入口。 + +### IF-REV-013 催缴任务生成与结果承接接口 + +#### 请求参数 + +| 字段 | 类型 | 必填 | 说明 | 主要来源/去向 | +|------|------|------|------|---------------| +| taskNo | String | 否 | 催缴任务号;查询/人工核查时必填 | 任务主键 | +| custId | Long | 是 | 客户标识 | `biz_charge.cust_id` | +| chargeIds | Array | 是 | 欠费账单集合 | `biz_charge.id` | +| billPeriod | String | 是 | 账期 | `biz_charge.bill_period` | +| arrearsAmount | Decimal | 是 | 欠费金额汇总 | 欠费汇总结果 | +| strategyCode | String | 是 | 命中的催缴策略编码 | 策略规则 | +| channelType | String | 是 | 触达渠道:短信/微信公众号/站内信等 | 任务分组结果 | +| triggerType | String | 是 | 触发方式:`AUTO` / `MANUAL` | 任务触发上下文 | +| eventNo | String | 否 | 业务事件号;生成后返回,回写承接时作为关联键 | 协同事件主键 | +| relatedDisposalRef | String | 否 | 关联停复水或工单引用 | 联动追溯信息 | +| manualVerifyNote | String | 否 | 人工核查说明;仅人工核查时填写 | 核查留痕 | + +#### 响应参数 + +| 字段 | 类型 | 说明 | 主要来源 | +|------|------|------|----------| +| taskNo | String | 催缴任务号 | 任务主键 | +| interfaceCode | String | 固定返回 `IF-REV-013` | 接口常量 | +| eventNo | String | 业务事件号 | 协同主键 | +| status | String | 状态:`PENDING`、`SUCCESS`、`FAIL`、`MANUAL_VERIFIED` | 任务状态 | +| resultTime | DateTime | 最近结果时间 | 结果回写时间 | +| failureReason | String | 失败原因 | 失败回写 | +| resultChannel | String | 实际触达渠道 | 协同结果 | +| relatedDisposalRef | String | 关联停复水或工单引用 | 联动追溯 | +| msg | String | 处理说明 | 返回消息 | + +#### 任务生成与状态承接约束 + +- 任务生成前必须完成欠费账单、客户类别、联系方式和策略命中校验;至少存在一个可用触达渠道。 +- 相同业务事件与同一接收对象在去重窗口内不得重复生成等效任务;若为人工补发,应显式记录 `triggerType=MANUAL`。 +- `PENDING` 表示已生成任务并发起协同,等待 `SYS-010` 回写或人工核查;`SUCCESS`、`FAIL` 由协同结果或明确失败确认触发。 +- 当外部结果长期未定、历史回执不足或人工核查已确认结果时,可将任务补记为 `MANUAL_VERIFIED`,并保留核查人和核查说明。 +- 接口返回的 `relatedDisposalRef` 仅用于追溯停复水、复水或工单处置引用,不表示本接口承担下游流程控制。 + +#### 失败阻断与人工核查约束 + +- 候选账单不满足欠费前提、策略编码无效或触达信息缺失时,应阻断任务生成并返回明确原因,不得写入伪成功状态。 +- 频控规则命中时允许部分阻断,必须返回被跳过对象与原因摘要,避免“全成功”误判。 +- 渠道协同超时或仅返回受理结果时,不直接判定 `FAIL`,保持 `PENDING` 并等待回执或进入人工核查流程。 +- 人工核查补记必须校验 `taskNo` 存在且 `manualVerifyNote` 非空;不满足条件时应拒绝补记并返回校验错误。 +- 人工核查仅用于状态收口,不替代 `SYS-010` 的渠道执行职责,也不扩展停复水/工单内部流程控制。 + +### IF-REV-010 统计查询接口 + +#### 请求参数 + +| 字段 | 类型 | 必填 | 说明 | 主要来源/去向 | +|------|------|------|------|---------------| +| themeCode | String | 是 | 统计主题编码 | 查询主题 | +| dateFrom | Date | 是 | 开始日期 | 时间维度 | +| dateTo | Date | 是 | 结束日期 | 时间维度 | +| billPeriod | String | 否 | 账期 | `biz_charge.bill_period` | +| deptId | Long | 否 | 营业所/部门 | `system_dept.id` | +| regionCode | String | 否 | 片区/区域编码 | 区域维度 | +| customerCategory | String | 否 | 客户类别 | 客户标签/分类 | +| channelCode | String | 否 | 收费/交易渠道 | `bk_payment_channel.channel_code` | +| accountId | Long | 否 | 账户标识 | `biz_account.id` | +| custId | Long | 否 | 客户标识 | `biz_cust.id` | +| statusSet | Array | 否 | 状态集合 | 账单/收费/抄表等状态筛选 | +| groupBy | Array | 否 | 分组维度集合 | 结果分组 | +| exportFlag | Boolean | 否 | 是否导出 | 导出控制 | + +#### 响应参数 + +| 字段 | 类型 | 说明 | 主要来源 | +|------|------|------|----------| +| themeCode | String | 统计主题编码 | 查询主题 | +| themeName | String | 统计主题名称 | 主题定义 | +| dimensionSummary | Object | 查询维度摘要 | 查询条件 | +| indicatorList | Array | 指标结果集合 | 聚合结果 | +| indicatorList[].indicatorCode | String | 指标编码 | 指标定义 | +| indicatorList[].indicatorName | String | 指标名称 | 指标定义 | +| indicatorList[].indicatorValue | Decimal/String | 指标值 | 聚合结果 | +| indicatorList[].unit | String | 指标单位 | 指标定义 | +| groupRows | Array | 分组结果集合 | 维度分组结果 | +| exportAllowed | Boolean | 是否允许导出 | 权限结果 | +| msg | String | 处理说明 | 返回消息 | + +#### 查询主题与口径约束 + +- 本接口至少支持营收汇总、收费与实收、欠费规模与账龄、客户结构、渠道交易、抄表完成率等主题查询。 +- 应收金额、实收金额、欠费余额、账单数、客户数、交易笔数、渠道占比、完成率等指标必须按业务含义区分,不得混写。 +- 当查询涉及历史只读口径时,历史数据仅作为补充来源或迁移核查辅助,不替代在线主数据统计结果。 +- 权限边界必须同时作用于在线查询和导出动作;不允许越过现有数据权限返回全量统计结果。 + +### IF-REV-011 银行代收协同接口 + +#### 请求参数 + +| 字段 | 类型 | 必填 | 说明 | 主要来源/去向 | +|------|------|------|------|---------------| +| batchNo | String | 是 | 代扣批次号 | `bk_withholding_batch.batch_no` | +| businessType | String | 是 | 业务类型:`WITHHOLDING`、`RECONCILE`、`SETTLEMENT` | 协同类型 | +| channelCode | String | 是 | 渠道编码 | `bk_payment_channel.channel_code` | +| billPeriod | String | 否 | 账期 | 批处理参数 | +| itemList | Array | 否 | 批次明细列表 | `bk_withholding_item` | +| itemList[].custId | Long | 是 | 客户 ID | `bk_withholding_item.cust_id` | +| itemList[].chargeId | Long | 是 | 账单 ID | `bk_withholding_item.charge_id` | +| itemList[].amount | Decimal | 是 | 扣款金额 | 业务金额 | + +#### 响应参数 + +| 字段 | 类型 | 说明 | 主要来源 | +|------|------|------|----------| +| batchNo | String | 批次号 | `bk_withholding_batch.batch_no` | +| batchStatus | String | 批次状态:`CREATED`、`SENT`、`RETURNED`、`RECONCILED`、`SETTLED` | 批次状态 | +| successCount | Integer | 成功处理条数 | 汇总结果 | +| failCount | Integer | 失败条数 | 汇总结果 | +| reconcileStatus | String | 对账状态 | `bk_reconcile_batch.status` | +| settlementStatus | String | 结算状态 | `bk_settlement_batch.status` | +| diffList | Array | 差异清单摘要 | `bk_reconcile_diff` | + +### IF-REV-012 业务参数配置接口 + +#### 请求参数 + +| 字段 | 类型 | 必填 | 说明 | 主要来源/去向 | +|------|------|------|------|---------------| +| action | String | 是 | 动作:`QUERY`、`CREATE`、`UPDATE` | 配置动作 | +| configType | String | 是 | 配置类型:`PRICE`、`RULE`、`PAGE`、`NOTICE` | `biz_parameter_settings.config_type` | +| configCode | String | 否 | 配置编码 | `biz_parameter_settings.config_code` | +| configValue | String | 否 | 配置值或 JSON 内容 | `biz_parameter_settings.config_value` | +| deptId | Long | 否 | 生效单位 | 作用域参数 | +| effectiveDate | Date | 否 | 生效日期 | 生效控制 | +| operatorId | Long | 否 | 操作人 ID | 操作上下文 | + +#### 响应参数 + +| 字段 | 类型 | 说明 | 主要来源 | +|------|------|------|----------| +| configId | Long | 配置主键 | `biz_parameter_settings.id` | +| configCode | String | 配置编码 | `biz_parameter_settings.config_code` | +| configVersion | String | 配置版本 | 版本信息 | +| effectScope | String | 生效范围 | 作用域结果 | +| effectStatus | String | 生效状态:`DRAFT`、`ACTIVE`、`EXPIRED` | 业务状态 | +| msg | String | 处理说明 | 返回消息 | + +### IF-CS-001 账户绑定接口 + +#### 请求参数 + +| 字段 | 类型 | 必填 | 说明 | 主要来源/去向 | +|------|------|------|------|---------------| +| action | String | 是 | 动作:`BIND`、`UNBIND`、`SET_DEFAULT` | 绑定动作 | +| channelType | String | 是 | 渠道类型:`WECHAT`、`ALIPAY`、`MINIAPP` | 渠道上下文 | +| channelUserId | String | 是 | 渠道用户标识,如 OpenId | 渠道上下文 | +| custId | Long | 是 | 客户 ID | `biz_cust.id` | +| accountId | Long | 否 | 账户 ID | `biz_account.id` | +| verifyCode | String | 否 | 验证码或身份校验码 | 安全校验 | +| defaultFlag | Boolean | 否 | 是否设为默认账户 | `biz_cust_app_binds.is_default` | + +#### 响应参数 + +| 字段 | 类型 | 说明 | 主要来源 | +|------|------|------|----------| +| bindId | Long | 绑定关系 ID | `biz_cust_app_binds.id` | +| bindStatus | String | 绑定状态:`BOUND`、`UNBOUND` | 业务状态 | +| defaultFlag | Boolean | 是否默认账户 | `biz_cust_app_binds.is_default` | +| custSummary | Object | 客户摘要信息 | `biz_cust` | +| msg | String | 处理说明 | 返回消息 | + +### IF-CS-002 历史账单查询接口 + +#### 请求参数 + +| 字段 | 类型 | 必填 | 说明 | 主要来源/去向 | +|------|------|------|------|---------------| +| custId | Long | 是 | 客户 ID | 客户上下文 | +| queryType | String | 是 | 查询类型:`BILL`、`PAYMENT`、`USAGE`、`ARREARS`、`INVOICE` | 查询控制 | +| billPeriod | String | 否 | 账期,如 `2026-03` | `biz_charge.bill_period` | +| chargeStatus | String | 否 | 账单状态筛选 | `biz_charge.status` | +| pageNo | Integer | 否 | 页码 | 分页参数 | +| pageSize | Integer | 否 | 每页数量 | 分页参数 | + +#### 响应参数 + +| 字段 | 类型 | 说明 | 主要来源 | +|------|------|------|----------| +| total | Integer | 总记录数 | 分页结果 | +| list | Array | 查询结果列表 | 聚合结果 | +| list[].chargeId | Long | 账单 ID | `biz_charge.id` | +| list[].billPeriod | String | 账期 | `biz_charge.bill_period` | +| list[].usageAmount | Decimal | 用量 | `biz_reading_data.usage_amount` | +| list[].payStatus | String | 缴费状态 | 业务状态 | +| list[].invoiceStatus | String | 开票状态 | `biz_invoice.invoice_status` | + +### IF-CS-004 电子发票消费接口 + +#### 查询/下载请求参数 + +| 字段 | 类型 | 必填 | 说明 | 主要来源/去向 | +|------|------|------|------|---------------| +| custId | Long | 是 | 客户 ID | `biz_invoice.cust_id` | +| invoiceId | Long | 否 | 发票记录 ID,三选一优先键 | `biz_invoice.id` | +| applicationNo | String | 否 | 发票申请单号 | `biz_invoice.application_no` | +| sysRequestNo | String | 否 | `SYS-008` 受理号 | `biz_invoice.sys_request_no` | + +#### 推送请求参数 + +| 字段 | 类型 | 必填 | 说明 | 主要来源/去向 | +|------|------|------|------|---------------| +| custId | Long | 是 | 客户 ID | `biz_invoice.cust_id` | +| invoiceId | Long | 是 | 发票记录 ID | `biz_invoice.id` | +| applicationNo | String | 否 | 发票申请单号 | `biz_invoice.application_no` | +| pushChannel | String | 是 | 推送方式:`EMAIL`、`SMS` | 推送动作 | +| pushEmail | String | 否 | 推送邮箱,`EMAIL` 时优先使用 | 目标地址 | +| pushMobile | String | 否 | 推送手机号,`SMS` 时优先使用 | 目标地址 | + +#### 响应参数 + +| 字段 | 类型 | 说明 | 主要来源 | +|------|------|------|----------| +| invoiceId | Long | 发票记录 ID | `biz_invoice.id` | +| applicationNo | String | 发票申请单号 | `biz_invoice.application_no` | +| invoiceStatus | String | 当前状态 | `biz_invoice.invoice_status` | +| invoiceCode | String | 发票代码 | `biz_invoice.invoice_code` | +| invoiceNumber | String | 发票号码 | `biz_invoice.invoice_number` | +| fileUrl | String | 发票下载地址 | `biz_invoice.file_url` | +| pushStatus | String | 推送状态:`NONE`、`PUSHED`、`FAIL` | `biz_invoice.push_status` | +| chargeBindStatus | String | 账单关联状态:`UNBOUND`、`BOUND` | `biz_invoice.charge_bind_status` | +| msg | String | 处理说明 | 返回消息 | + +#### 客户侧消费约束 + +- 客户侧仅允许访问本人 `custId` 名下发票记录,`invoiceId`、`applicationNo`、`sysRequestNo` 任一定位成功后仍需再次校验客户归属。 +- 下载与推送前必须校验 `invoiceStatus=SUCCESS` 且 `fileUrl` 非空;已作废、已红冲或缺少电子票地址的记录一律返回不可消费原因。 +- 推送成功后回写 `pushStatus=PUSHED`;失败则更新为 `FAIL` 并记录失败原因。 +- 客户侧只消费已形成有效电子票结果的记录,不暴露后台作废、红冲入口,也不直接展示后处理请求参数。 + +### IF-CS-003 在线支付下单接口 + +#### 请求参数 + +| 字段 | 类型 | 必填 | 说明 | 主要来源/去向 | +|------|------|------|------|---------------| +| custId | Long | 是 | 客户 ID | 客户上下文 | +| chargeIds | Array | 是 | 待支付账单 ID 列表 | `biz_charge.id` | +| paymentChannel | String | 是 | 支付渠道:`WECHAT`、`ALIPAY` | 渠道参数 | +| paymentAmount | Decimal | 是 | 支付金额 | `bk_transaction.trade_amount` | +| openId | String | 否 | 微信渠道用户标识 | 微信场景 | +| returnUrl | String | 否 | 前端完成跳转地址 | 前端场景 | +| notifyUrl | String | 否 | 支付结果通知地址 | 回调地址 | + +#### 响应参数 + +| 字段 | 类型 | 说明 | 主要来源 | +|------|------|------|----------| +| bizOrderNo | String | SYS-002 业务订单号 | `biz_collection.code` / 业务单号 | +| tradeNo | String | 渠道交易流水号 | `bk_transaction.trade_no` | +| orderStatus | String | 订单状态:`INIT`、`PAYING`、`SUCCESS`、`FAIL` | 交易状态 | +| payUrl | String | 支付链接或二维码地址 | 渠道返回 | +| prepayInfo | Object | 预支付参数对象 | 渠道返回 | +| expireTime | Datetime | 订单失效时间 | 交易参数 | + +### IF-CS-006 业务办理进度接口 + +#### 请求参数 + +| 字段 | 类型 | 必填 | 说明 | 主要来源/去向 | +|------|------|------|------|---------------| +| processId | Long | 否 | 办理流程 ID,查询场景使用 | `biz_process.id` | +| businessTypeCode | String | 否 | 业务类型编码,如更名、过户、低保、换表 | `biz_business_types.code` | +| custId | Long | 否 | 客户 ID | 客户上下文 | +| applyData | Object | 否 | 业务申请主体数据 | `biz_business_datas` | +| attachmentList | Array | 否 | 附件文件标识列表 | `biz_content_attach` | +| action | String | 否 | 动作:`CREATE`、`QUERY`、`SUPPLEMENT` | 流程动作 | + +#### 响应参数 + +| 字段 | 类型 | 说明 | 主要来源 | +|------|------|------|----------| +| processId | Long | 办理流程 ID | `biz_process.id` | +| processCode | String | 流程编号 | `biz_process.code` | +| processStatus | String | 当前状态:`INIT`、`ACCEPTED`、`PROCESSING`、`DONE`、`REJECTED` | `biz_process.status` | +| currentNode | String | 当前办理节点 | 流程状态 | +| transferList | Array | 流转轨迹 | `biz_process_transfer` | +| attachmentRequired | Boolean | 是否需要补件 | 业务判断 | +| msg | String | 办理说明 | 返回消息 | + +### IF-CS-007 柜面扫码支付接口 + +#### 请求参数 + +| 字段 | 类型 | 必填 | 说明 | 主要来源/去向 | +|------|------|------|------|---------------| +| counterCode | String | 是 | 柜台编号 | 柜面终端 | +| chargeIds | Array | 是 | 待支付账单 ID 列表 | `biz_charge.id` | +| paymentChannel | String | 是 | 支付渠道:`WECHAT`、`ALIPAY` | 渠道参数 | +| orderAmount | Decimal | 是 | 订单金额 | `bk_transaction.trade_amount` | +| operatorId | Long | 是 | 柜台操作员 ID | 操作上下文 | +| scene | String | 否 | 场景标识,默认 `COUNTER_SCAN_PAY` | 场景参数 | + +#### 响应参数 + +| 字段 | 类型 | 说明 | 主要来源 | +|------|------|------|----------| +| bizOrderNo | String | 柜面业务订单号 | `biz_collection.code` | +| tradeNo | String | 渠道交易流水号 | `bk_transaction.trade_no` | +| qrCode | String | 柜面展示二维码内容 | 渠道返回 | +| orderStatus | String | 当前订单状态:`INIT`、`PAYING`、`SUCCESS`、`FAIL` | 交易状态 | +| writeBackStatus | String | 营收状态回写结果 | 业务状态 | +| msg | String | 处理说明 | 返回消息 | + +### IF-METER-001 水表档案查询接口 + +#### 请求参数 + +| 字段 | 类型 | 必填 | 说明 | 主要来源 | +|------|------|------|------|----------| +| id | Long | 否 | 水表主键 ID,与 `code` 二选一 | `biz_meter.id` | +| code | String | 否 | 水表编号,与 `id` 二选一 | `biz_meter.code` | +| queryType | String | 否 | 查询类型:`base`、`status`、`lifeCycle`、`all` | 查询控制参数 | + +#### 响应参数 + +| 字段 | 类型 | 说明 | 主要来源 | +|------|------|------|----------| +| id | Long | 水表主键 ID | `biz_meter.id` | +| code | String | 水表编号 | `biz_meter.code` | +| meterStatus | String | 水表状态 | `biz_meter.status` | +| modelCode | String | 型号编码 | `biz_meter.model_code` | +| caliberCode | String | 口径编码 | `biz_meter.caliber_code` | +| rangeCode | String | 量程编码 | `biz_meter.range_code` | +| installAddress | String | 安装地址 | `biz_meter.install_address` | +| lastReading | Decimal | 最近有效读数 | `biz_last_reading.last_reading` | + +### IF-METER-003 库存出入库接口 + +#### 请求参数 + +| 字段 | 类型 | 必填 | 说明 | 主要来源/去向 | +|------|------|------|------|---------------| +| action | String | 是 | 动作:`IN`、`OUT`、`RETURN`、`SCRAP` | 库存动作 | +| batchNo | String | 是 | 批次号 | `biz_meter_in_out.batch_no` | +| warehouseCode | String | 否 | 仓库编码 | 仓储参数 | +| meterIds | Array | 是 | 水表 ID 列表 | `biz_meter.id` | +| remark | String | 否 | 出入库说明 | `biz_meter_in_out.remark` | +| operatorId | Long | 是 | 操作人 ID | 操作上下文 | + +#### 响应参数 + +| 字段 | 类型 | 说明 | 主要来源 | +|------|------|------|----------| +| inOutId | Long | 出入库主记录 ID | `biz_meter_in_out.id` | +| batchNo | String | 批次号 | `biz_meter_in_out.batch_no` | +| actionStatus | String | 处理状态:`SUCCESS`、`PARTIAL`、`FAIL` | 业务状态 | +| successCount | Integer | 成功处理数量 | 汇总结果 | +| failCount | Integer | 失败数量 | 汇总结果 | +| msg | String | 处理说明 | 返回消息 | + +### IF-METER-004 集抄数据接收接口 + +#### 请求参数 + +| 字段 | 类型 | 必填 | 说明 | 主要来源/去向 | +|------|------|------|------|---------------| +| meterCode | String | 是 | 水表编号 | `biz_meter.code` | +| readTime | Datetime | 是 | 采集时间 | `biz_reading_data.read_time` | +| currentReading | Decimal | 是 | 当前读数 | `biz_reading_data.current_reading` | +| deviceStatus | String | 否 | 设备状态:`ONLINE`、`OFFLINE`、`ALARM` | 设备状态 | +| alarmList | Array | 否 | 告警编码列表 | 告警结果 | +| fileSerialNo | String | 否 | 上送批次或文件序列号 | 幂等辅助键 | +| sourceSystem | String | 是 | 来源系统:`IOT`、`MDC` | 来源标识 | + +#### 响应参数 + +| 字段 | 类型 | 说明 | 主要来源 | +|------|------|------|----------| +| readingId | Long | 读数记录 ID | `biz_reading_data.id` | +| meterReadId | Long | 对应抄表任务 ID | `biz_meter_read.id` | +| acceptStatus | String | 接收状态:`SUCCESS`、`WARN`、`REJECT` | 处理状态 | +| abnormalFlag | Boolean | 是否异常 | 过程判断 | +| nextAction | String | 后续动作:`BILLING`、`RECHECK`、`MANUAL_REVIEW` | 流程控制 | +| msg | String | 处理说明 | 返回消息 | + +### IF-INST-001 报装申请提交接口 + +#### 请求参数 + +| 字段 | 类型 | 必填 | 说明 | 主要来源/去向 | +|------|------|------|------|---------------| +| applyType | String | 是 | 报装类型:`NEW`、`REBUILD`、`ONE_METER_ONE_HOME` | 业务类型 | +| applicantName | String | 是 | 申请人姓名 | 申请资料 | +| mobile | String | 是 | 联系手机号 | 申请资料 | +| address | String | 是 | 申请地址 | 申请资料 | +| waterUseType | String | 是 | 用水性质 | 业务字典 | +| sourceChannel | String | 是 | 来源渠道:`COUNTER`、`MINIAPP`、`GOV` | 来源标识 | +| attachmentList | Array | 否 | 申请附件列表 | `biz_content_attach` | + +#### 响应参数 + +| 字段 | 类型 | 说明 | 主要来源 | +|------|------|------|----------| +| processId | Long | 流程实例 ID | `biz_process.id` | +| processCode | String | 报装流程编号 | `biz_process.code` | +| processStatus | String | 当前状态:`INIT`、`ACCEPTED`、`SURVEYING` | `biz_process.process_status` | +| acceptStatus | String | 受理结果 | 业务状态 | +| msg | String | 处理说明 | 返回消息 | + +### IF-INST-002 踏勘结果回填接口 + +#### 请求参数 + +| 字段 | 类型 | 必填 | 说明 | 主要来源/去向 | +|------|------|------|------|---------------| +| processId | Long | 是 | 报装流程 ID | `biz_process.id` | +| schemeVersion | String | 是 | 方案版本号 | `biz_business_datas` | +| surveyResult | String | 是 | 踏勘结论 | `biz_business_datas` | +| estimateAmount | Decimal | 否 | 预估费用 | `biz_business_datas` | +| attachmentList | Array | 否 | 现场照片与方案附件 | `biz_content_attach` | +| auditResult | String | 否 | 审核结果:`PASS`、`REJECT` | 审核结果 | + +#### 响应参数 + +| 字段 | 类型 | 说明 | 主要来源 | +|------|------|------|----------| +| transferId | Long | 流转记录 ID | `biz_process_transfer.id` | +| processStatus | String | 当前流程状态 | `biz_process.process_status` | +| nextNode | String | 下一节点 | 流程控制 | +| msg | String | 处理说明 | 返回消息 | + +### IF-INST-004 签章回执接口 + +#### 请求参数 + +| 字段 | 类型 | 必填 | 说明 | 主要来源/去向 | +|------|------|------|------|---------------| +| contractId | Long | 是 | 合同 ID | `installation_contract.id` | +| requestNo | String | 是 | 签章请求号 | 协同流水 | +| signStatus | String | 是 | 签章状态:`SUCCESS`、`FAIL`、`CANCEL` | `installation_signature.signature_status` | +| signerId | String | 否 | 签署人标识 | `installation_signature.signer_id` | +| signatureTime | Datetime | 否 | 签章时间 | `installation_signature.signature_time` | +| evidenceNo | String | 否 | 存证编号 | `installation_evidence.evidence_no` | +| fileUrl | String | 否 | 已签文件地址 | 结果回写 | +| hashValue | String | 否 | 存证哈希 | `installation_evidence.hash_value` | +| resultMsg | String | 否 | 结果说明 | 返回消息 | + +#### 响应参数 + +| 字段 | 类型 | 说明 | 主要来源 | +|------|------|------|----------| +| signatureId | Long | 签章记录 ID | `installation_signature.id` | +| evidenceId | Long | 存证记录 ID | `installation_evidence.id` | +| writeBackStatus | String | 回写状态:`SUCCESS`、`IGNORE_REPEAT`、`FAIL` | 业务状态 | +| msg | String | 处理说明 | 返回消息 | + +### IF-INST-005 报装归档接口 + +#### 请求参数 + +| 字段 | 类型 | 必填 | 说明 | 主要来源/去向 | +|------|------|------|------|---------------| +| processId | Long | 是 | 报装流程 ID | `biz_process.id` | +| archiveType | String | 是 | 归档类型:`APPLY`、`ACCEPT`、`CHECK`、`CONTRACT`、`FINISH` | 归档分类 | +| attachmentList | Array | 是 | 归档附件列表 | `biz_content_attach` | +| contractId | Long | 否 | 合同 ID | `installation_contract.id` | +| evidenceId | Long | 否 | 存证记录 ID | `installation_evidence.id` | +| operatorId | Long | 否 | 归档操作人 | 操作上下文 | + +#### 响应参数 + +| 字段 | 类型 | 说明 | 主要来源 | +|------|------|------|----------| +| archiveBatchNo | String | 归档批次号 | 业务流水 | +| archiveStatus | String | 归档状态:`SUCCESS`、`PARTIAL`、`FAIL` | 业务状态 | +| archiveCount | Integer | 已归档文件数量 | 汇总结果 | +| msg | String | 处理说明 | 返回消息 | + +## 关键接口时序图 + +> 说明:以下时序图用于说明 SYS-002 与客户渠道、外部协同子系统之间的交互边界,重点体现业务校验、协同调用、结果回写与状态更新链路。 + +### 1. 在线支付下单与回调时序 + +```mermaid +sequenceDiagram + autonumber + participant Client as 客户渠道 + participant SYS002 as SYS-002营收系统 + participant SYS009 as SYS-009支付结算 + participant Channel as 支付渠道 + + Client->>SYS002: 提交缴费下单请求(IF-CS-003) + SYS002->>SYS002: 校验客户、账单状态与应付金额 + SYS002->>SYS002: 生成业务订单与收费记录草稿 + SYS002->>SYS009: 发起支付下单协同(IF-EXT-004) + SYS009->>Channel: 调用微信/支付宝统一下单 + Channel-->>SYS009: 返回tradeNo、payUrl/prepayInfo + SYS009-->>SYS002: 返回交易流水与支付参数 + SYS002-->>Client: 返回bizOrderNo、payUrl、expireTime + + Channel-->>SYS009: 异步支付结果通知 + SYS009->>SYS009: 校验签名与交易状态 + SYS009->>SYS002: 回写支付结果(IF-EXT-005) + SYS002->>SYS002: 幂等校验并更新biz_collection/biz_charge + SYS002-->>Client: 查询订单时返回最新支付状态 +``` + +### 2. 电子发票申请、查询补偿与回写时序 + +```mermaid +sequenceDiagram + autonumber + participant Counter as 柜台或客户渠道 + participant SYS002 as SYS-002营收系统 + participant SYS008 as SYS-008发票服务 + participant Tax as 税控/开票平台 + participant Job as 查询补偿任务 + + Counter->>SYS002: 提交发票申请(IF-REV-008/IF-CS-004) + SYS002->>SYS002: 校验客户、账单、开票抬头与金额 + SYS002->>SYS002: 生成发票申请记录biz_invoice(SUBMITTED) + SYS002->>SYS008: 发起开票协同(IF-EXT-006) + SYS008->>Tax: 调用税控或电子发票平台 + Tax-->>SYS008: 返回受理结果/票号/文件地址 + SYS008-->>SYS002: 返回受理号或异步结果 + SYS002->>SYS002: 记录sysRequestNo并更新为PENDING + alt 发票服务主动回写 + SYS008-->>SYS002: 回写开票结果(IF-EXT-007) + SYS002->>SYS002: 更新biz_invoice状态、票据地址与账单关联 + else 未收到终态结果 + Job->>SYS002: 触发补偿查询(IF-REV-009) + SYS002->>SYS008: 按申请单号/受理号查询结果 + SYS008-->>SYS002: 返回处理中/成功/失败 + SYS002->>SYS002: 刷新查询上下文并按终态规则落账 + end + SYS002-->>Counter: 返回申请结果或供后续查询 +``` + +### 3. 银行代扣批次与回盘时序 + +```mermaid +sequenceDiagram + autonumber + participant BatchJob as 代扣批处理任务 + participant SYS002 as SYS-002营收系统 + participant SYS009 as SYS-009支付结算 + participant Bank as 银行渠道 + + BatchJob->>SYS002: 发起代扣批次处理(IF-REV-011) + SYS002->>SYS002: 汇总代扣客户、账单与协议关系 + SYS002->>SYS002: 生成bk_withholding_batch/bk_withholding_item + SYS002->>SYS002: 解析 send/back/reconcile 目录并固化协议、目录、文件路径 + SYS002->>SYS009: 下发银行代扣批次(IF-EXT-001) + SYS009->>Bank: 发送代扣文件或报文 + Bank-->>SYS009: 返回受理结果 + SYS009-->>SYS002: 回写批次发送状态 + + Bank-->>SYS009: 回盘文件/结果通知(IF-EXT-002) + SYS009->>SYS009: 解析成功、失败、异常明细 + SYS009->>SYS002: 回写代扣结果、差异与结算状态 + SYS002->>SYS002: 更新biz_withholding、账单核销、对账结算状态 + SYS002-->>BatchJob: 返回批次处理汇总结果 +``` + +### 4. 催缴通知下发与结果回写时序 + +```mermaid +sequenceDiagram + autonumber + participant Job as 催缴任务 + participant SYS002 as SYS-002营收系统 + participant SYS010 as SYS-010消息服务 + participant User as 客户 + + Job->>SYS002: 触发催缴任务(IF-REV-013) + SYS002->>SYS002: 按欠费账单、渠道偏好生成催缴名单 + SYS002->>SYS010: 提交通知下发请求(IF-EXT-008) + SYS010->>User: 发送短信/公众号/APP消息 + User-->>SYS010: 触达回执或阅读反馈 + SYS010-->>SYS002: 回写发送结果与触达状态 + SYS002->>SYS002: 更新催缴记录、四态状态与后续策略 + SYS002-->>Job: 返回催缴任务执行结果 +``` + + +## 数据对象与表口径 + +### SYS-002 接口核心数据对象 + +| 数据域 | 代表表 | 接口说明 | +|--------|--------|----------| +| 客户与账户 | `biz_cust`、`biz_account`、`biz_cust_contact` | 用于客户查询、账户绑定、资料维护 | +| 客户扩展关系 | `biz_cust_meter`、`biz_cust_invoice`、`biz_cust_app_binds`、`biz_cust_collection_rel`、`biz_cust_withholding_rel` | 用于客户关联对象查询与服务协同 | +| 抄表与开账 | `biz_meter_book`、`biz_meter_read`、`biz_reading_data`、`biz_last_reading`、`biz_charge`、`biz_charge_detail` | 用于抄表任务、账单生成、费用明细查询 | +| 价格与参数 | `biz_price_*`、`biz_cost_component`、`biz_parameter_settings`、`biz_page_settings*` | 用于价格模板、业务参数、页面配置 | +| 收费与票据 | `biz_collection`、`biz_withholding`、`biz_invoice`、`biz_invoice_taxrate` | 用于收费、代扣、发票申请与回写 | +| 办理与资料 | `biz_process*`、`biz_business_datas`、`biz_content*` | 用于业务办理与进度跟踪 | +| 银行代收与结算 | `bk_transaction*`、`bk_withholding_*`、`bk_reconcile_*`、`bk_settlement_batch` | 用于支付流水、批次、回调、对账和结算 | + +### 口径约束说明 + +1. 不再使用旧稿中的 `customer_*`、`water_*`、`billing_*`、`thirdpay_*`、`service_*` 作为 SYS-002 正式接口数据口径。 +2. 若历史资料中仍存在旧命名,仅作为来源参考,不作为正式交付口径。 +3. 对 backend 中尚未明确存在独立实体表的对象,例如部分精细账务台账、红冲明细、价差调整明细等,本文仅描述为业务处理场景,不强写为既有独立接口对象。 + +## 跨系统报文映射表 + +> 说明:以下映射表用于说明 SYS-002 与 `SYS-008`、`SYS-009`、`SYS-010` 之间的关键报文字段对应关系,重点体现业务主键、状态字段、金额字段与结果回写字段,不展开各外部平台私有扩展字段。 + +### 1. SYS-002 ↔ SYS-009 支付下单与结果回写映射 + +| 协同场景 | SYS-002 字段 | SYS-009/渠道字段 | 说明 | 主要来源 | +|---------|--------------|------------------|------|----------| +| 支付下单 | `bizOrderNo` | `businessOrderNo` | SYS-002 业务订单号,作为支付协同主键 | `biz_collection.code` | +| 支付下单 | `chargeIds[]` | `orderItems[].sourceId` | 待缴账单明细标识 | `biz_charge.id` | +| 支付下单 | `custId` | `buyer.customerId` | 客户标识 | `biz_charge.cust_id` / `biz_cust.id` | +| 支付下单 | `paymentAmount` | `tradeAmount` | 交易总金额 | `bk_transaction.trade_amount` | +| 支付下单 | `paymentChannel` | `channelCode` | 支付渠道编码 | 渠道参数 / `bk_payment_channel.channel_code` | +| 支付下单 | `notifyUrl` | `notifyUrl` | 支付结果异步通知地址 | 协同参数 | +| 下单返回 | `tradeNo` | `tradeNo` | 渠道交易流水号 | `bk_transaction.trade_no` | +| 下单返回 | `payUrl`/`prepayInfo` | `payUrl`/`payParams` | 二维码链接或预支付参数 | 渠道返回 | +| 结果回写 | `orderStatus` | `tradeStatus` | 交易状态映射:`INIT/PAYING/SUCCESS/FAIL` | `bk_transaction.status` | +| 结果回写 | `paidAmount` | `successAmount` | 实际支付成功金额 | `biz_collection.amount` / 渠道结果 | +| 结果回写 | `callbackTime` | `notifyTime` | 回调时间 | `bk_transaction_callback.create_time` | +| 结果回写 | `writeOffStatus` | `writeBackStatus` | SYS-002 核销处理结果 | 业务状态 | + +### 2. SYS-002 ↔ SYS-008 发票申请与结果回写映射 + +| 协同场景 | SYS-002 字段 | SYS-008 字段 | 说明 | 主要来源 | +|---------|--------------|--------------|------|----------| +| 发票申请 | `invoiceCode` | `requestNo` | 发票申请单号 / 协同请求号 | `biz_invoice.code` | +| 发票申请 | `custId` | `customerId` | 客户标识 | `biz_invoice.cust_id` | +| 发票申请 | `chargeIds[]` | `billList[].sourceBillId` | 开票关联账单标识 | 业务单据关联 | +| 发票申请 | `invoiceTitle` | `buyerName` | 购方名称 / 抬头 | `biz_cust_invoice.invoice_title` | +| 发票申请 | `taxNo` | `buyerTaxNo` | 购方税号 | `biz_cust_invoice.tax_no` | +| 发票申请 | `invoiceType` | `invoiceType` | 电子/纸质发票类型 | `biz_invoice.invoice_type` | +| 发票申请 | `taxRateCode` | `taxRateCode` | 税率编码 | `biz_invoice_taxrate.tax_code` | +| 发票申请 | `email` / `mobile` | `receiver.email` / `receiver.mobile` | 票据接收信息 | `biz_cust_invoice.email` / `biz_cust_invoice.mobile` | +| 结果回写 | `invoiceStatus` | `invoiceStatus` | 开票状态:受理中、成功、失败、作废、红冲等 | `biz_invoice.invoice_status` | +| 结果回写 | `invoiceNo` | `invoiceNo` | 发票号码 | 开票结果 | +| 结果回写 | `fileUrl` | `fileUrl` | 发票文件下载地址 | 回写结果 | +| 结果回写 | `msg` | `resultMsg` | 结果说明 | 返回消息 | + +### 3. SYS-002 ↔ SYS-009 银行代扣、对账、结算映射 + +| 协同场景 | SYS-002 字段 | SYS-009/银行字段 | 说明 | 主要来源 | +|---------|--------------|------------------|------|----------| +| 批次下发 | `batchNo` | `batchNo` | 代扣批次号 | `bk_withholding_batch.batch_no` | +| 批次下发 | `businessType` | `businessType` | 代扣/对账/结算类型 | 协同参数 | +| 批次下发 | `channelCode` | `channelCode` | 渠道编码 | `bk_payment_channel.channel_code` | +| 批次下发 | `protocol` | `protocol` | `SFTP/FTP` 传输协议 | 统一解析结果 | +| 批次下发 | `sendDir` / `sendFilePath` | `sendDir` / `sendFilePath` | 送盘目录与文件路径 | `bk_withholding_batch` | +| 批次下发 | `billPeriod` | `billPeriod` | 账期 | 批处理参数 | +| 批次明细 | `itemList[].custId` | `itemList[].customerId` | 客户标识 | `bk_withholding_item.cust_id` | +| 批次明细 | `itemList[].chargeId` | `itemList[].sourceBillId` | 账单标识 | `bk_withholding_item.charge_id` | +| 批次明细 | `itemList[].amount` | `itemList[].withholdingAmount` | 代扣金额 | 业务金额 | +| 回盘回写 | `batchStatus` | `batchStatus` | 批次状态:已发送、已回盘等 | `bk_withholding_batch.status` | +| 回盘回写 | `backProtocol` / `backDir` / `backFilePath` | `backProtocol` / `backDir` / `backFilePath` | 回盘阶段最终解析结果 | `bk_withholding_batch` | +| 回盘回写 | `successCount` / `failCount` | `successCount` / `failCount` | 成功失败数量汇总 | 汇总结果 | +| 对账回写 | `protocol` / `dir` / `filePath` | `protocol` / `dir` / `filePath` | 对账文件最终解析结果 | `bk_reconcile_batch` | +| 对账回写 | `reconcileStatus` | `reconcileStatus` | 对账状态 | `bk_reconcile_batch.status` | +| 对账回写 | `diffList[]` | `diffList[]` | 差异明细摘要 | `bk_reconcile_diff` | +| 结算回写 | `settlementStatus` | `settlementStatus` | 结算状态 | `bk_settlement_batch.status` | + +### 4. SYS-002 ↔ SYS-010 催缴与业务通知映射 + +| 协同场景 | SYS-002 字段 | SYS-010 字段 | 说明 | 主要来源 | +|---------|--------------|--------------|------|----------| +| 催缴通知 | `messageBizNo` | `eventNo` | 消息事件编号 | 业务事件编号 | +| 催缴通知 | `custId` | `receiver.customerId` | 接收客户标识 | `biz_charge.cust_id` / `biz_process.cust_id` | +| 催缴通知 | `mobile` | `receiver.mobile` | 接收手机号 | 客户联系方式 | +| 催缴通知 | `templateCode` | `templateCode` | 消息模板编码 | 模板参数 | +| 催缴通知 | `arrearsAmount` | `payload.arrearsAmount` | 欠费金额 | `biz_charge.total_amount` / 汇总结果 | +| 催缴通知 | `billPeriod` | `payload.billPeriod` | 账期 | `biz_charge.bill_period` | +| 催缴通知 | `strategyCode` | `payload.strategyCode` | 命中的催缴策略编码 | 任务分组结果 | +| 催缴通知 | `triggerType` | `payload.triggerType` | 自动/人工触发方式 | 任务触发上下文 | +| 办理进度通知 | `processCode` | `payload.processCode` | 业务办理单号 | `biz_process.code` | +| 办理进度通知 | `processStatus` | `payload.processStatus` | 办理状态 | `biz_process.status` | +| 发送结果回写 | `status` | `sendStatus` | 渠道回执由 `SYS-002` 统一映射为 `PENDING/SUCCESS/FAIL/MANUAL_VERIFIED` 四态 | 消息结果 | +| 发送结果回写 | `reachStatus` | `reachStatus` | 触达/阅读状态 | 渠道回执 | +| 发送结果回写 | `sendTime` | `sendTime` | 发送时间 | 消息结果 | +| 发送结果回写 | `msg` | `resultMsg` | 结果说明 | 返回消息 | + + +## 接口安全与异常处理 + +### 认证与鉴权 + +- 管理后台接口:统一采用登录态 + 权限控制 + 数据权限。 +- 客户渠道接口:采用账户绑定态、手机号/验证码、OAuth 或渠道令牌机制。 +- 外部协同接口:按渠道要求使用 API Key、时间戳、数字签名、证书或国密算法。 + +### 安全控制要求 + +- 全部接口统一走 HTTPS。 +- 外部回调接口必须执行签名校验、重复通知幂等处理与来源校验。 +- 关键交易类接口需记录业务流水、渠道流水和操作日志。 +- 敏感字段如证件号、手机号、银行账号按制度要求脱敏展示。 + +### 错误码分层建议 + +| 错误码段 | 说明 | +|---------|------| +| 0 | 成功 | +| 400~499 | 请求参数、权限、资源不存在等通用错误 | +| 1_002_001_xxx | 客户主数据类错误 | +| 1_002_002_xxx | 抄表开账类错误 | +| 1_002_003_xxx | 收费与核销类错误 | +| 1_002_004_xxx | 账务处理类错误 | +| 1_002_005_xxx | 发票协同类错误 | +| 1_002_006_xxx | 银行代收与结算类错误 | +| 1_002_007_xxx | 客户渠道与业务办理类错误 | +| 1_002_008_xxx | 消息通知与触达类错误 | + +### 典型错误码建议 + +| 错误码 | 适用接口/场景 | 说明 | 处理建议 | +|-------|---------------|------|----------| +| `1_002_001_001` | IF-REV-001 / IF-REV-002 | 客户不存在或已停用 | 返回客户状态并阻断后续处理 | +| `1_002_001_002` | IF-CS-001 | 账户绑定关系不存在 | 引导重新绑定客户 | +| `1_002_002_001` | IF-REV-004 | 抄表任务不存在或已关闭 | 禁止提交抄表数据 | +| `1_002_002_002` | IF-REV-004 | 本次读数小于上次读数且未通过异常审批 | 标记异常并进入复核 | +| `1_002_002_003` | IF-REV-005 | 价格模板或费用组成缺失 | 阻断账单生成并提示补齐配置 | +| `1_002_003_001` | IF-REV-006 / IF-CS-003 / IF-CS-007 | 账单已核销或不允许重复支付 | 返回当前账单支付状态 | +| `1_002_003_002` | IF-REV-006 | 支付金额与待核销金额不一致 | 阻断核销并返回差额 | +| `1_002_003_003` | IF-EXT-005 | 支付回调签名校验失败 | 记录异常回调并拒绝入账 | +| `1_002_004_001` | IF-REV-007 | 账务调整目标状态不允许变更 | 返回当前账务状态 | +| `1_002_005_001` | IF-REV-008 / IF-CS-004 | 发票申请单据不满足开票条件 | 返回不可开票原因 | +| `1_002_005_002` | IF-EXT-007 | 发票结果回写状态非法或重复 | 按请求号执行幂等回写 | +| `1_002_006_001` | IF-REV-011 / IF-EXT-001 | 代扣批次不存在或已发送 | 禁止重复下发批次 | +| `1_002_006_002` | IF-EXT-002 | 银行回盘文件格式非法或批次号不匹配 | 记录异常并进入人工核查 | +| `1_002_006_003` | IF-REV-011 | 对账差异未处理,禁止结算确认 | 需先完成差异处置 | +| `1_002_007_001` | IF-CS-006 | 业务办理单不存在 | 返回空结果并提示核对单号 | +| `1_002_007_002` | IF-CS-006 | 当前节点不允许补件或重复提交 | 返回当前流程节点状态 | +| `1_002_008_001` | IF-REV-013 / IF-EXT-008 | 消息模板不存在或目标联系方式缺失 | 记录失败原因并允许后续补发 | +| `1_002_008_002` | IF-EXT-008 | 消息通道调用超时 | 标记待重试,不直接判定业务失败 | +| `1_002_008_003` | IF-REV-013 | 人工核查补记缺少核查说明或关联任务不存在 | 拒绝补记并提示补齐核查上下文 | + +### 幂等与状态冲突控制 + +#### 幂等键建议 + +| 场景 | 接口 | 建议幂等键 | 幂等判定说明 | +|------|------|------------|--------------| +| 支付下单 | IF-CS-003 / IF-CS-007 | `bizOrderNo` 或 `custId + chargeIds + paymentChannel` | 相同业务订单仅允许创建一次有效支付单 | +| 支付回调 | IF-EXT-005 | `tradeNo + tradeStatus + notifyTime` | 同一交易成功回调只允许入账一次 | +| 发票申请 | IF-REV-008 / IF-CS-004 | `invoiceCode` 或 `custId + chargeIds` | 相同账单组合避免重复申请开票 | +| 发票结果回写 | IF-EXT-007 | `requestNo + invoiceStatus` | 相同发票状态重复回写仅更新回执日志 | +| 银行批次下发 | IF-REV-011 / IF-EXT-001 | `batchNo` | 同一代扣批次禁止重复发送 | +| 银行回盘接收 | IF-EXT-002 | `batchNo + fileSerialNo` | 同一回盘文件只处理一次 | +| 催缴通知 | IF-REV-013 / IF-EXT-008 | `messageBizNo + templateCode + receiver` | 同一业务事件与同一接收方避免重复发送 | +| 业务补件 | IF-CS-006 | `processId + action + attachmentDigest` | 相同补件内容重复提交仅保留一次 | + +#### 状态冲突处理原则 + +| 场景 | 冲突条件 | 处理原则 | +|------|----------|----------| +| 支付核销 | 账单已完成核销后再次支付 | 拒绝重复核销,返回现有 `writeOffStatus` | +| 支付回调 | 先收到失败回调,后收到成功回调 | 以最终成功状态为准,但全过程保留回调日志 | +| 发票申请 | 单据已开票成功后再次申请 | 拒绝重复申请,返回既有发票信息 | +| 发票回写 | 已成功开票后收到失败回写 | 不覆盖成功状态,转入异常核查 | +| 银行代扣 | 批次已发送后再次下发 | 拒绝重复发送,保留原批次状态 | +| 对账结算 | 差异未消除即发起结算 | 禁止结算,提示先处理差异明细 | +| 催缴通知 | 同一账期、同一模板短时间内重复催缴 | 按通知频控策略拦截重复下发 | +| 业务办理 | 流程已办结后再次补件 | 拒绝补件,返回当前流程终态 | + +### 异常处理要求 + +- 参数校验失败:直接返回明确字段错误信息。 +- 外部渠道超时:记录重试状态,不直接覆盖业务成功状态。 +- 重复回调:按业务流水执行幂等控制。 +- 账务状态冲突:返回当前账单状态与冲突原因,禁止重复核销。 +- 外部结果晚到:允许按幂等键补写回执,但不得回退已确认成功状态。 +- 人工兜底场景:支付异常、银行回盘异常、发票状态冲突等需保留人工复核入口与操作日志。 + + +## 历史查询与迁移校验接口口径 + +### 设计原则 + +- 历史查询接口一律只读,不承担迁移修正、补写或状态变更职责。 +- 不为迁移场景发明新的独立接口编号体系,统一挂靠既有 `IF-REV-*`、`IF-CS-*`、`IF-METER-*` 接口族扩展查询能力。 +- 对 backend 当前未识别到独立实体表的旧细粒度对象,仅要求接口返回“历史摘要 + 原始标识 + 状态映射”,不强行承诺独立在线业务对象。 +- 迁移验收接口必须同时支持“汇总对账”和“明细追溯”两类能力,避免只能看总数、无法定位差异。 + +### 最小历史查询保留集 + +| 查询主题 | 挂靠接口族 | 主要数据来源 | 最低返回要求 | 说明 | +|---------|------------|--------------|--------------|------| +| 历史账单、特殊开账 | `IF-CS-002`、`IF-REV-005` | `biz_charge*` + 历史账单来源 | 原账单号、新账单号、客户号、账期、金额、状态、来源类型 | 支撑账单迁移核查与客户侧历史查询 | +| 缴费记录、柜台结账、实时收费 | `IF-CS-002`、`IF-REV-006`、`IF-REV-011` | `biz_collection`、`bk_transaction*` + 历史收费记录 | 原流水号、渠道、实收金额、收费时间、柜员/营业所、核销状态 | 支撑渠道对账、柜面核查和历史收据核对 | +| 红冲与账务调整 | `IF-REV-007` | 操作留痕、流程结果 + 历史调整台账 | 调整类型、关联原单号、调整金额、原因、审批状态、处理时间 | 支撑预存退款、已销调整、价差调整、分账调整、呆坏账查询 | +| 发票与开票关系 | `IF-REV-008`、`IF-CS-004` | `biz_invoice*` + 历史开票关系快照 | 发票号、申请单号、关联账单、票据状态、票据类型、文件地址 | 支撑发票结果核查与历史补打定位 | +| 催缴、停复水、预存短信 | `IF-REV-013`、`IF-METER-002` | 通知结果、流程工单 + 历史催缴记录 | 客户号、账期、催缴方式、消息状态、停复水状态、执行人、执行时间、处置引用 | 支撑催缴处置闭环核查 | +| 业务进度与电子档案 | `IF-CS-006` | `biz_process*`、`biz_content*` + 历史附件目录 | 业务单号、节点状态、处理轨迹、附件数量、附件元数据 | 支撑微网厅与柜台办理进度、电子档案查询 | +| 水表生命周期、检定与库存流转 | `IF-METER-001`、`IF-METER-003` | `biz_meter*` + 历史仓储/检定单据 | 表号、当前状态、单据类型、仓库、检定结论、证书编号、时间 | 支撑表务迁移核查与历史作业追溯 | +| 页面参数、业务字段、微信配置 | `IF-REV-012`、`IF-CS-006` | `biz_parameter_settings`、`biz_page_settings*`、`sys_wechat_app_settings` | 参数编码、原值、新值、启用状态、生效时间、适用渠道 | 支撑微网厅后台配置迁移核查 | + +### 迁移验收对账接口要求 + +| 验收场景 | 推荐挂靠接口 | 最低查询维度 | 输出要求 | +|---------|--------------|--------------|----------| +| 开账迁移核对 | `IF-REV-005`、`IF-CS-002` | 账期、营业所、客户类型、账单状态 | 同时提供汇总金额/笔数与可追溯明细清单 | +| 收费迁移核对 | `IF-REV-006`、`IF-REV-011`、`IF-CS-002` | 日期、渠道、营业所、收费状态 | 同时提供实收金额、流水数量和异常流水列表 | +| 发票迁移核对 | `IF-REV-008`、`IF-CS-004` | 开票日期、票据类型、开票状态 | 同时提供开票汇总、失败原因和票据明细定位 | +| 催缴与停复水核对 | `IF-REV-013`、`IF-METER-002` | 账期、催缴方式、执行状态、处理人 | 同时提供任务统计、执行明细与处置引用 | +| 业务办理与档案核对 | `IF-CS-006` | 业务类型、流程状态、附件类型、创建时间 | 同时提供流程轨迹、附件元数据和缺失标记 | +| 表务仓储与检定核对 | `IF-METER-001`、`IF-METER-003` | 仓库、单据类型、水表状态、检定结论 | 同时提供数量汇总和单据级追溯信息 | + +### 接口约束补充 + +- 历史查询结果应优先返回原系统标识与新系统标识的映射关系,例如原单号、原批次号、原附件标识、当前业务单号。 +- 明细查询接口应支持按客户号、证件号、手机号、表号、账期、营业所、渠道、业务单号等组合检索,满足迁移验收定位需求。 +- 若历史附件不直接由当前业务服务托管,接口至少返回附件元数据、来源系统、文件引用地址和可访问状态。 +- 历史查询接口的导出能力属于查询扩展能力,不应与在线交易接口共用“状态变更”动作。 + + +## 实现状态说明 + +### 已落地 + +结合 `backend` 当前已确认模块与真实表,可明确支撑以下接口域: + +- 客户与账户查询、维护接口 +- 抄表任务与抄表数据接口 +- 账单生成与收费核销接口 +- 银行代收、代扣、交易回调、对账、结算接口 +- 发票申请与票据状态回写接口的业务侧支撑 +- 客户渠道的账户绑定、查询、缴费、业务办理进度接口 + +### 部分落地 + +以下接口域已有主线支撑,但部分细粒度对象仍需结合后续实现继续核实: + +- 账务调整、退款、坏账、冲正类精细接口 +- 催缴管理中针对不同通知策略和停复水联动的细分接口 +- 发票补开等扩展票据后处理接口 + +### 文档先行 + +以下内容可保留设计说明,但当前不应直接表述为已完全落地: + +- 历史数据字典中大量细粒度账务台账接口 +- 未在 backend 当前扫描范围内明确识别到的独立业务对象接口 +- 特定银行或地方平台的专有报文细节 +- 历史查询与迁移校验接口在实施时所依赖的只读库、归档库或映射表物理形态 + +--- + +### 版本迭代维护说明 + +当前主文档已覆盖 `UP / REV / CS / METER / INST / EXT` 六类接口域的统一编号、清单、关键接口与字段级定义。后续版本迭代按以下顺序增量维护: + +1. 先更新接口清单与归属模块,再补充字段级请求/响应结构; +2. 涉及跨系统协同时,同步维护 `SYS-008`、`SYS-009`、`SYS-010` 报文映射; +3. 涉及异常策略变化时,同步更新错误码与幂等规则; +4. 完成后同步校验 `02_Detailed_Design/01_Detailed_Design.md` 与本主文档的一致性。 diff --git a/docs/design/04_Appendix/Archive/08_Formal_Doc_Snapshots/RWB-04/2026-04-03-RWB-04-03_Summary_Design.md b/docs/design/04_Appendix/Archive/08_Formal_Doc_Snapshots/RWB-04/2026-04-03-RWB-04-03_Summary_Design.md new file mode 100644 index 0000000..369c6c4 --- /dev/null +++ b/docs/design/04_Appendix/Archive/08_Formal_Doc_Snapshots/RWB-04/2026-04-03-RWB-04-03_Summary_Design.md @@ -0,0 +1,4231 @@ +--- +doc_id: HL-03-SUMMARY +doc_role: master_document +authority: primary +scope: 概要设计 +source_of_truth: true +last_reviewed: 2026-03-12 +retrieval_priority: P0 +--- + +# 福建水务营收系统概要设计说明书 + +## 章节导航(精简) + +- [前言](#sec-preface) +- [系统总体设计](#sec-overall-design) +- [子系统设计(SYS-001~SYS-010)](#sec-subsystems) + - [SYS-001 统一平台](#sec-sys-001) + - [SYS-002 营收业务系统](#sec-sys-002) + - [SYS-003 手机抄表APP](#sec-sys-003) + - [SYS-004 微网厅系统](#sec-sys-004) + - [SYS-005 工单管理系统](#sec-sys-005) + - [SYS-006 表务管理系统](#sec-sys-006) + - [SYS-007 报装业务系统](#sec-sys-007) + - [SYS-008 发票服务子系统](#sec-sys-008) + - [SYS-009 支付与银行结算子系统](#sec-sys-009) + - [SYS-010 消息服务子系统](#sec-sys-010) +- [非功能性需求设计](#sec-nfr) + +| 文件状态: | 文档密级: | 公开 | +| :--- | :--- | :--- | +| 【√】草稿 | | | +| 【】修改稿 | | | +| 【】正式发布 | | | +| | **当前版本:** | **V1.7** | +| | **作者:** | **唐伟杰** | +| | **完成日期:** | **2025-08-18** | + +## 版本历史 + +| 日期 | 版本号 | 作者 | 备注 | +| :--- | :--- | :--- | :--- | +| 2025-07-01 | V1.0 | 唐伟杰 | 初版 | +| 2025-07-17 | V1.1 | 唐伟杰 | 1. 同步详细设计中的模块,补充缺失模块。
2. 调整子系统划分与编号,确保逻辑清晰、编号连续。
3. 重构表务、报装、客户服务子系统,优化模块设计。
4. 统一概要设计与详细设计的结构,提升一致性。 | +| 2025-08-01 | V1.2 | 唐伟杰 | 完善 APP相关的模块设计 | +| 2025-08-01 | V1.3 | 唐伟杰 | 数据库系统变更:将OpenGauss替换为达梦数据库 8.0+,更新所有相关架构图和技术描述。 | +| 2025-08-01 | V1.4 | 唐伟杰 | 单点登录采用OAuth2.0+CAS协议:更新单点登录模块描述,强调基于OAuth2.0+CAS协议实现。 | +| 2025-08-18 | V1.5 | 唐伟杰 | 架构调整:将营收业务系统中的工单、表务、报装剥离为独立子系统(SYS-005/006/007),更新目录、功能范围、子系统列表、关系图与接口定义;保留客户服务模块在营收业务系统中的作用。 | +| 2025-08-18 | V1.6 | 唐伟杰 | 合并第三方支付能力至SYS-009"支付与银行结算子系统",统一消息服务重编号为SYS-010;更新总体目标、功能范围、接口定义、子系统列表与相关架构图。 | +| 2026-03-12 | V1.7 | 唐伟杰 | 对照 `Archive/03_Design_Docs/营业收费管理系统-概要设计说明书20250912.md` 完成来源对齐:补充历史来源说明与引用路径,确认系统拆分、基础服务定位、外部集成与非功能约束已同步;保留当前正式系统名称、模块编号与接口编号标准,不沿用历史别名编码作为正式口径。 | + + + +# 前言 + +## 编写目的 + +  本文档是《福建水务营收系统详细设计说明书》的前导文档,旨在从总体架构和概要设计的角度对系统进行全面的技术规划和设计。 + +**主要目的:** + +1. **总体架构规划**:从系统整体角度进行技术架构规划,为详细设计提供宏观指导 +2. **技术方案论证**:确定系统的技术选型、架构模式和实现策略 +3. **设计标准制定**:建立统一的技术标准、开发规范和质量要求 +4. **风险评估分析**:识别技术风险、制定应对策略 +5. **资源需求评估**:确定系统开发、部署所需的技术资源和基础设施 + +**预期读者:** + +- 系统架构师和技术负责人 +- 项目经理和技术管理人员 +- 详细设计和开发团队 +- 测试团队和运维团队 +- 甲方技术评审团队 + +## 背景 + +  福建水务营收系统是为满足福建省水投数字科技有限公司客户服务管理领域的业务需求而建设的信息化系统。系统以客户为核心和基础,实现客户全生命周期管理。 + +**建设背景:** + +  福建水投集团注册资本46亿元,在全省40多个县市区投资重大水利项目超过450亿元,拥有全级次子公司超过67家,职工人数超3500人。当前,集团正紧紧抓住城乡供水一体化建设的机遇,需要构建以客户为中心的数字化服务体系。 + +## 术语与缩略语 + +| **术语、缩写** | **解释** | +|---|---| +| SaaS | Software as a Service,软件即服务 | +| RBAC | Role-Based Access Control,基于角色的访问控制 | +| JWT | JSON Web Token,基于JSON的Web令牌 | +| OAuth2 | 开放授权标准 | +| RESTful | Representational State Transfer,表现层状态转化 | +| OpenAPI | 开放应用程序接口规范 | +| DDL | Data Definition Language,数据定义语言 | +| DML | Data Manipulation Language,数据操作语言 | +| IoT | Internet of Things,物联网 | +| CAS | Central Authentication Service,中央认证服务 | +| DevOps | Development和Operations的组合词,开发运维一体化 | +| 业务参数 | 业务参数配置 | +| 站点 | 用于划分用户所属管辖区域,站点可以进行多级管理 | +| 册本 | 又称抄表本或抄表簿,根据抄表线路规划,按排相邻的一些水表给某一个抄表员进行抄表 | +| 用户编号 | 为签定了供用水合同的正式用户分配的唯一识别号 | +| 售水量 | 抄收水量+查处水量±调整水量 | +| 当期应收水费 | 当期售水量乘以不同类别的水价(到户价)所得的金额 | +| 水表抄见率 | (当期应抄用户数-当期估表用户数)/当期应抄用户数×100% | + +## 参考资料 + +- GB/T 8556-2007 信息技术软件生存周期过程 +- GB/T 9385-2008 计算机软件需求规格说明规范 +- GB/T 8567-2006 计算机软件文档编制规范 +- 《RuoYi-Vue-Pro技术架构文档》 +- 《Spring Cloud微服务架构设计指南》 +- 《福建水务营收系统需求规格说明书》 +- `../04_Appendix/Archive/03_Design_Docs/营业收费管理系统-概要设计说明书20250912.md` + +## 历史来源对齐说明 + +本主文档已对齐 `../04_Appendix/Archive/03_Design_Docs/营业收费管理系统-概要设计说明书20250912.md` 中对当前正式设计仍有效的内容,主要包括: + +- 子系统拆分口径:`SYS-001 ~ SYS-010` 的职责边界、基础服务分层与跨系统协同关系。 +- 业务范围口径:营收、微网厅、工单、表务、报装、发票、支付结算、消息等范围定义。 +- 架构与集成口径:外部支付、银行、税控、消息、摄像表 AI 等外部协同边界。 +- 非功能口径:达梦数据库 8.0+、物理部署、可靠性、安全与扩展性方向。 + +以下内容仅保留在 Archive 中作为历史来源,不直接作为当前正式主文档口径: + +- 历史系统名称“营业收费管理系统”等旧标题写法。 +- 历史别名编码,如 `UP-SSO`、`REV-CUSTOM`、`WECHAT-*`。 +- 历史接口编号体系,如 `IF-S-*`、`IF-C-*`。 + +当前正式口径继续统一采用: + +- 系统名称:`福建水务营收系统` +- 模块编号:`UP-001`、`REV-001`、`CS-001`、`METER-001`、`INST-001` +- 接口编号:`IF-UP-*`、`IF-REV-*`、`IF-CS-*`、`IF-METER-*`、`IF-INST-*`、`IF-EXT-*` + + + +# 系统总体设计 + +## 任务概述 + +### 系统总体目标 + +  福建水务营收系统采用分层解耦与子系统化建设,形成"业务服务层 + 基础服务层"的整体架构: + +- 业务服务层:SYS-001 统一平台、SYS-002 营收业务系统、SYS-003 手机抄表APP、SYS-004 微网厅系统、SYS-005 工单管理系统、SYS-006 表务管理系统、SYS-007 报装业务系统 + +- 基础服务层:SYS-008 发票服务子系统(统一开票)、SYS-009 支付与银行结算子系统(统一聚合支付/退款/渠道适配/第三方支付平台/银行实时收费、代扣/托收签解约、批次与对账契约、加解密与支付回调,夜间批量代扣/完整对账结算按后续完善项管理)、SYS-010 消息服务子系统(统一短信/邮件/站内信/模板消息/微信通知/数科系统对接)、注册/配置中心、任务调度等基础服务 + +  通过系统的建设,实现福建省水投数字科技有限公司客户服务管理领域的业务流程梳理再造、组织架构的优化、管理制度的建设、绩效考核标准的建设。构建以客户为中心的一体化服务体系,将客户的所有信息进行有机的关联,方便企业对营收信息进行综合分析和管理,为客户提供更多、更便捷、更主动的个性化服务,提高客户服务的质量和客户满意度。 + +**系统整体架构特点:** + +- **统一平台**:提供单点登录、统一认证(SSO/OAuth2+CAS)、审计与监控、权限、组织、参数、多租户、字典等基础能力 +- **营收业务系统**:围绕客户、抄表、收费、账务、催缴、统计等核心营收流程,保留"客户服务模块群"对外服务能力,提供多租户的业务参数配置 +- **手机抄表APP**:移动化现场作业,支持离线;现场问题上报与工单接收由工单系统统一承载 +- **微网厅系统**:面向公众的自助服务门户,支持绑定、查询、缴费、发票查看、业务办理 +- **工单管理系统**:统一工单中心与流程引擎,打通营收/表务/报装/微网厅/APP的全场景工单 +- **表务管理系统**:设备档案、表务全生命周期管理 +- **报装业务系统**:覆盖报装申请、踏勘、施工、验收、通水与档案归档的端到端流程,支持调用泛微进行合同签订,电子签章,支持各租户自定义报装流程和表单定义 +- **发票服务子系统**(基础服务):统一开票网关与供应商适配(现优先对接航天,预留博思),回执与存证 +- **支付与银行对接子系统**(基础服务):统一支付/退款、银行实时收费、代扣/托收签解约、送盘/回盘/对账契约、加解密签名与第三方支付平台(微信、支付宝);夜间批量代扣和完整结算闭环按后续完善项管理 +- **消息服务子系统**(基础服务):统一短信/邮件/站内信/模板消息,下行推送与到达回执,供各业务子系统调用(如营收业务系统催缴),微信信息通知,对接数科已建系统通知(OA、智水擎,水投数科 app) + +### 功能范围 + +  本系统功能涵盖水务企业完整的营收业务流程,包括客户资料管理、抄表开账、营业收费、账务处理、催缴管理、发票管理(经SYS-008)、表务管理、报装业务、客户服务、工单管理,以及支付与银行结算(经SYS-009)等;还包含查询统计与报表打印功能。 + +#### SYS-001 统一平台 + +- 单点登录、统一认证(SSO/OAuth2+CAS)、审计与监控、权限、组织、参数、多租户、字典等基础能力 + +#### SYS-002 营收业务系统 + +- 营收核心:客户资料、抄表开账、营业收费、账务处理、催缴管理、统计分析、代收业务、多租户业务参数配置 +- 客户服务:账户绑定、信息查询、在线缴费(经SYS-009)、柜面扫码支付(经SYS-009)、电子发票(经SYS-008)、营业网点、业务办理 + +#### SYS-003 手机抄表APP + +- 移动作业:登录、首页搜索、采集任务、现场抄表、调用外部AI识别服务 +- 现场上报/工单接收:问题上报、工单接收与回填(经SYS-005) +- 数据同步与个人管理:任务下载/数据上传(离线支持)、个人信息与设置 + +#### SYS-004 微网厅系统 + +- 账户绑定、账单/用水查询、在线缴费(经SYS-009)、电子发票查看(经SYS-008)、营业网点、业务办理 + +#### SYS-005 工单管理系统 + +- 统一工单中心、流程引擎、监控预警、绩效统计,打通营收/表务/报装/微网厅/APP + +#### SYS-006 表务管理系统 + +- 设备档案、表务全生命周期管理 + +#### SYS-007 报装业务系统 + +- 报装流程(申请/踏勘/施工/验收/通水)、支持调用泛微进行合同签订,电子签章、各租户自定义报装流程和表单定义、工程管理(进度/资源/质量/安全)、档案管理(资料归档/留痕) + +#### SYS-008 发票服务子系统(基础服务) + +- 统一开票/作废与红冲/查询、供应商适配(航天优先、预留博思)、回执处理与存证 + +#### SYS-009 支付与银行结算子系统(基础服务) + +- 聚合支付/退款、渠道适配(微信/支付宝/银联聚合等)、第三方支付平台(微信、支付宝)、支付结果通知、银行代扣(送盘/回盘)、支持夜间进行批量代扣、对账文件处理、加解密/签名 +- 当前实现侧已确认聚合支付基础能力、银行欠费查询/缴费、`BankWithholding` 六条银行入口(客户状态查询、送盘、送盘状态查询、取消送盘、回盘、回盘状态查询)、代扣/托收签约解约和后台资源管理具备证据;其中 `BankCollection` 平行链路、夜间批量代扣、完整对账与结算仍按部分实现或后续完善项管理 + +#### SYS-010 消息服务子系统(基础服务) + +- 统一短信/邮件/站内信/模板消息,下行推送与到达回执,供各业务子系统调用(如营收业务系统催缴) +- 微信信息通知,对接数科已建系统通知(OA、智水擎,水投数科 app) +- 邮件服务:邮件通知发送(经SYS-010) + +### 系统涉众与用户特点 + +**系统涉众**: + +  本系统主要涉及用户为各水务公司与系统相关的业务参与者、福建省水投数字科技有限公司研发运维团队。 + +**用户特点**: + +- **公司领导**:对信息化在企业生产经营管理活动中的积极作用有深刻认识,并具有前瞻视角。 + +- **公司管理层**:有丰富的企业管理经验,有良好的业务管理类系统使用经验。 + +- **系统管理人员**:具有本科以上教育背景,计算机操作熟练,具有良好的软件系统维护经验,主要维护系统的后台权限管理、人员管理、部门管理等功能。 + +- **操作人员**:部分用户已经使用过其他厂商提供的水务营收系统,部分用户对软件系统使用经验不足。 + +## 设计概述 + +### 总体约束 + +**技术约束**: + +- 采用现代化微服务架构,支持大规模并发访问 +- 支持多租户模式,满足集团化管理需求 +- 实现移动化办公,提高工作效率 +- 集成物联网技术,支持智能水表远程抄表 +- 适配国产化环境,确保系统安全可控 + +**性能约束**: + +- 系统并发用户数不低于200个 +- 移动设备同时登录系统的并发用户数不少于50个 +- 系统响应时间不超过3秒 +- 支持100万客户的业务量 +- 系统可用性达到99.5%以上 + +**安全约束**: + +- 系统满足国家信息安全等级保护要求 +- 支持数据加密存储和传输 +- 实现细粒度的权限控制 +- 提供完整的审计日志功能 + +### 系统依赖外部接口 + +  本系统需要与以下外部系统进行接口集成: + +| 接口类型 | 接口名称 | 功能描述 | 接口协议 | +|---------|---------|----------|----------| +| 金融支付 | 银行代扣接口 | 银行托收代扣缴费 | HTTPS | +| 金融支付 | 微信支付接口 | 微信在线支付 | HTTPS | +| 金融支付 | 支付宝支付接口 | 支付宝在线支付 | HTTPS | +| 通信服务 | 短信平台接口 | 短信通知发送 | HTTPS | +| 通信服务 | 邮件服务接口 | 邮件通知发送 | HTTPS/SMTP | +| 通信服务 | 微信模板消息接口 | 微信模板消息下发 | HTTPS | +| 物联网 | 集抄系统接口 | 智能水表数据采集 | TCP/HTTPS | +| 税务服务 | 电子发票接口 | 第三方发票开具 | HTTPS | +| 认证服务 | 身份认证接口 | 第三方身份验证 | HTTPS | +| 认证服务 | CAS单点登录 | 第三方身份验证 | HTTPS | +| 认证服务 | OAuth2.0单点登录 | 第三方身份验证 | HTTPS | +| 外部系统 | CA电子签章 | CA签发/验章/存证 | HTTPS | +| 外部系统 | 邮件服务 | 邮件服务 | HTTPS | +| 外部系统 | 摄像表AI接口 | 表AI识别服务 | HTTPS | + +### 设计方案概述 + +**架构设计方案**: + +  系统采用现代化的多层分布式架构,基于微服务设计思想,实现松耦合、高内聚的系统架构。整体架构分为表现层、网关层、业务服务层、基础服务层和数据层五个层次。 + +**技术选型方案**: + +- **后端技术栈**:Java 17+、Spring Boot 3.1+、Spring Cloud Gateway、MyBatis-Plus +- **前端技术栈**:Vue 3、Element Plus、TypeScript +- **数据库**:达梦数据库 8.0+(主从架构) +- **缓存**:Redis 6.0+(集群模式) +- **消息队列**:RabbitMQ 3.9+ +- **文件存储**:MinIO(分布式文件存储) +- **容器化**:基于Docker的容器化部署,使用Docker Compose进行容器编排,使用Kubernetes进行容器编排和调度。 +- **DevOps**:使用Jenkins进行自动化构建、部署和测试,使用Gitea进行代码管 + +**部署方案**: + +  采用容器化部署架构,支持多环境部署(开发、测试、生产),提供自动化部署脚本,支持弹性扩缩容。 + +## 系统架构设计 + +### 系统的逻辑架构设计 + +  系统采用现代化的多层分布式架构,基于微服务设计思想,实现松耦合、高内聚的系统架构。 + +#### 整体架构图 + +```mermaid +graph TB + %% 表现层 + subgraph "表现层" + ADMIN[Web管理端] + H5[微网厅H5] + APP[手机抄表APP] + end + + %% 网关层 + subgraph "网关层" + GATEWAY[API网关] + SSO[统一认证/SSO] + end + + %% 业务服务层 + subgraph "业务服务层" + UP[SYS-001 统一平台] + REV[SYS-002 营收业务系统] + WO[SYS-005 工单管理系统] + METER[SYS-006 表务管理系统] + INST[SYS-007 报装业务系统] + end + + %% 基础服务层 + subgraph "基础服务层" + INV[SYS-008 发票服务] + PAY[SYS-009 支付与银行结算] + MSG[SYS-010 消息服务] + MQ[RabbitMQ 消息队列] + FILE[MinIO 文件存储] + REDIS[Redis 缓存] + MON[监控/日志] + CONFIG[注册/配置中心] + SCHED[任务调度] + end + + %% 数据层 + subgraph "数据层" + DM[(达梦数据库集群)] + CACHE[(Redis集群)] + STORE[(MinIO集群)] + end + + %% 外部系统 + subgraph "外部系统" + EXT_CA[CA电子签章] + EXT_BANK[银行] + EXT_PSP[支付渠道 微信/支付宝/银联聚合] + EXT_INV[发票供应商 航天/博思] + EXT_SMS[短信平台] + EXT_MAIL[邮件服务] + EXT_IOT[集抄系统] + end + + %% 连接关系 + ADMIN --> GATEWAY + H5 --> GATEWAY + APP --> GATEWAY + GATEWAY --> SSO + GATEWAY --> UP + GATEWAY --> REV + GATEWAY --> WO + GATEWAY --> METER + GATEWAY --> INST + + REV --> INV + REV --> PAY + REV --> MQ + REV -.-> MSG + REV --> FILE + REV --> REDIS + + INST -.-> EXT_CA + + INV -.-> EXT_INV + MSG -.-> EXT_SMS + MSG -.-> EXT_MAIL + PAY -.-> EXT_BANK + PAY -.-> EXT_PSP + + %% 数据层连接 + UP --> CACHE + REV --> DM + WO --> DM + METER --> DM + INST --> DM + FILE --> STORE +``` + +#### 层级说明 + +**表现层(Presentation Layer)** + +- 负责用户交互和界面展示 +- 包含多种客户端形态:Web端、微网厅(微信、支付宝) +- 采用前后端分离架构,提高开发效率和用户体验 + +**网关层(Gateway Layer)** + +- 统一入口,负责请求路由和负载均衡 +- 集中处理认证授权、限流熔断、监控日志 +- 提供API版本管理和接口文档生成 + +**业务服务层(Business Service Layer)** + +- 核心业务逻辑处理层,包含七个子系统: + - **SYS-001 统一平台**:提供单点登录、统一认证(SSO/OAuth2+CAS)、审计与监控、权限、组织、参数、多租户、字典等基础能力 + - **SYS-002 营收业务系统**:营收核心与客户服务模块群 + - **SYS-003 手机抄表APP**:移动端现场作业、调用外部摄像表AI识别服务与数据同步 + - **SYS-004 微网厅系统**:面向客户的线上服务门户 + - **SYS-005 工单管理系统**:统一工单中心与流程引擎 + - **SYS-006 表务管理系统**:设备档案、表务全生命周期管理 + - **SYS-007 报装业务系统**:报装全流程与工程管理、合同签订与电子签章 +- 按业务域划分微服务,实现高内聚低耦合 +- 支持独立部署、扩缩容和技术栈选择 + +**基础服务层(Infrastructure Service Layer)** + +- 提供通用的技术服务能力 +- 包含权限、工作流、消息、文件、发票服务(统一开票能力)、银行对接服务(代扣/夜间批量代扣/对账/加解密)、第三方支付服务(聚合支付/退款)、消息服务(统一短信/邮件/站内信/模板消息)、注册/配置中心、任务调度等基础服务 +- 为业务服务提供统一的技术支撑 + +**数据层(Data Layer)** + +- 数据持久化和缓存层 +- 支持读写分离、分库分表、数据备份 +- 提供高性能、高可用的数据服务 + +**外部系统(External Systems)** + +- CA电子签章:用于报装资料签署、验章与存证(当前归属 `INST-002` 工程管理) +- 银行:托收代扣、回盘与对账(经SYS-009) +- 支付渠道:微信/支付宝/银联聚合等(经SYS-009) +- 发票供应商:航天/博思等税控平台(经SYS-008) +- 短信平台:通知与催缴短信发送(经SYS-010) +- 集抄系统:智能水表数据采集(远传/集中器) +- 邮件服务:邮件通知发送(经SYS-010) +- **摄像表AI系统(外部)**:基于计算机视觉的水表读数自动识别服务,通过API接口为手机抄表APP提供图像识别能力 + +### 系统数据流向图 + +```mermaid +flowchart TB + %% 分层横向排布,垂直贯通,允许直连线穿越模块 + subgraph L1["数据采集层"] + direction LR + A1[手机抄表APP/SYS-003] + A2[智能水表] + A3[管理后台/SYS-001] + A4[微网厅/SYS-004] + A5[外部系统] + end + + subgraph L2["接入层"] + direction LR + GW[API网关] + AUTH[统一平台SSO/SYS-001] + CLEAN[数据清洗] + MQ[消息队列] + CACHE_TMP[临时缓存] + end + + subgraph L3["业务层"] + direction LR + REV[营收系统/SYS-002] + WO[工单系统/SYS-005] + METER[表务系统/SYS-006] + INST[报装系统/SYS-007] + INV[发票服务/SYS-008] + PAY[支付与结算/SYS-009] + MSG[消息服务/SYS-010] + end + + subgraph L4["存储层"] + direction LR + DM_MASTER[达梦主库] + DM_SLAVE[达梦从库] + REDIS[Redis缓存] + MINIO[MinIO对象存储] + BACKUP[备份库] + end + + subgraph L5["数据服务层"] + direction LR + QRY[查询服务] + RPT[报表服务] + API[接口服务] + PUSH[推送服务] + end + + subgraph L6["展现层"] + direction LR + F1[管理后台] + F2[统计大屏] + F3[移动端] + F4[微网厅] + F5[第三方系统] + end + + %% 连接(精简且保持层间垂直分层,线可穿越模块) + A1 --> GW + A2 --> GW + A3 --> GW + A4 --> GW + A5 --> GW + + %% 相邻层连线:采集层 → 接入层 已在上方;以下为 接入层 → 业务层 + GW --> REV + GW --> WO + GW --> METER + GW --> INST + + MQ --> REV + MQ --> WO + MQ --> METER + MQ --> INST + + REV --> DM_MASTER + WO --> DM_MASTER + METER --> DM_MASTER + INST --> DM_MASTER + INV --> MINIO + MSG --> REDIS + %% 存储层内部链路省略,保持仅向下一层输出 + + DM_MASTER --> QRY + DM_MASTER --> RPT + DM_MASTER --> API + REDIS --> API + MINIO --> API + MSG --> PUSH + QRY --> F1 + RPT --> F2 + API --> F1 + API --> F3 + API --> F4 + API --> F5 + PUSH --> F3 + PUSH --> F4 +``` + +### 系统的物理架构设计 + +  系统采用分布式部署架构,通过多个服务器集群实现高可用和高性能,支持 DevOps 持续交付。 + +#### 物理部署图 + +```mermaid +graph TB + subgraph "DMZ区域" + subgraph "负载均衡集群" + LB1[Nginx 主
8核16G] + LB2[Nginx 备
8核16G] + WAF[Web应用防火墙] + end + end + + subgraph "应用服务区" + subgraph "Web服务集群" + WEB1[Web服务器1
8核32G] + WEB2[Web服务器2
8核32G] + end + + subgraph "应用服务集群" + APP1[应用服务器1
16核64G] + APP2[应用服务器2
16核64G] + end + + subgraph "中间件集群" + MQ1[消息队列1
8核16G] + MQ2[消息队列2
8核16G] + end + end + + subgraph "数据服务区" + subgraph "数据库集群" + DB1[达梦数据库主库
32核128G] + DB2[达梦数据库从库
32核128G] + DB3[达梦数据库备库
32核128G] + end + + subgraph "缓存集群" + REDIS1[Redis主节点
16核32G] + REDIS2[Redis从节点
16核32G] + REDIS3[Redis哨兵
8核16G] + end + + subgraph "文件存储集群" + FILE1[MinIO节点1
8核32G 10TB] + FILE2[MinIO节点2
8核32G 10TB] + FILE3[MinIO节点3
8核32G 10TB] + end + end + + subgraph "管理服务区" + MONITOR[监控服务器
Prometheus + Grafana
8核16G] + BACKUP[备份服务器
8核32G 20TB] + JUMP[跳板服务器
4核8G] + LOG[日志服务器
ELK Stack
16核32G] + end + + +``` + +#### 网络连接 + +```mermaid +graph TB + + Internet[互联网] -.->|HTTPS| DMZ[DMZ区域] + DMZ -.->|HTTP/RPC| APP[应用服务区] + APP -.->|数据访问| DATA[数据服务区] + MGMT[管理服务区] -.->|监控管理| APP + MGMT -.->|监控管理| DATA +``` + +#### 硬件配置规格 + +**DMZ区域配置** + +| 设备类型 | 配置规格 | 数量 | 主要作用 | +|---------|---------|------|----------| +| 负载均衡器 | 8核16G,双网卡 | 2台 | 负载均衡、高可用 | +| Web应用防火墙 | 硬件WAF设备 | 1台 | 安全防护 | + +**应用服务区配置** + +| 设备类型 | 配置规格 | 数量 | 主要作用 | +|---------|---------|------|----------| +| Web服务器 | 8核32G,1TB SSD | 2台 | 前端应用部署 | +| 应用服务器 | 32核128G,2TB SSD | 3台 | 后端服务部署 | +| 消息队列服务器 | 8核16G,1TB SSD | 2台 | 异步消息处理 | + +**数据服务区配置** + +| 设备类型 | 配置规格 | 数量 | 主要作用 | +|---------|---------|------|----------| +| 数据库服务器 | 32核128G,10TB SSD | 3台 | 主从备数据库 | +| 缓存服务器 | 16核32G,1TB SSD | 3台 | Redis集群 | +| 文件存储服务器 | 8核32G,10TB HDD | 3台 | 分布式文件存储 | + +**管理服务区配置** + +| 设备类型 | 配置规格 | 数量 | 主要作用 | +|---------|---------|------|----------| +| 监控服务器 | 8核16G,1TB SSD | 1台 | 系统监控 | +| 备份服务器 | 8核32G,20TB HDD | 1台 | 数据备份 | +| 跳板服务器 | 4核8G,500GB SSD | 1台 | 运维管理 | +| 日志服务器 | 16核32G,5TB SSD | 1台 | 日志收集分析 | + +#### 达梦数据库分布式架构 + +  系统采用达梦数据库分布式架构,支持高性能、高可用、高扩展性的数据存储服务。 + +```mermaid +graph TB + subgraph "达梦数据库分布式架构" + subgraph "协调节点" + CN1[协调节点1
Coordinator Node] + CN2[协调节点2
Coordinator Node] + end + + subgraph "数据节点组1" + DN1_1[数据节点1-主
Datanode Primary] + DN1_2[数据节点1-备
Datanode Standby] + DN1_1 -.->|主备同步| DN1_2 + end + + subgraph "数据节点组2" + DN2_1[数据节点2-主
Datanode Primary] + DN2_2[数据节点2-备
Datanode Standby] + DN2_1 -.->|主备同步| DN2_2 + end + + subgraph "GTM节点" + GTM[全局事务管理器
GTM Master] + GTM_S[GTM备节点
GTM Standby] + GTM -.->|备份| GTM_S + end + end + + %% 分布式架构调用关系 + CN1 -.->|分片路由
查询协调| DN1_1 + CN1 -.->|分片路由
查询协调| DN2_1 + CN2 -.->|分片路由
查询协调| DN1_1 + CN2 -.->|分片路由
查询协调| DN2_1 + CN1 -.->|事务管理
全局一致性| GTM + CN2 -.->|事务管理
全局一致性| GTM +``` + +#### 容器化部署架构 + +  系统采用基于Docker的容器化部署,使用Docker Compose进行容器编排,使用Kubernetes进行容器编排和调度,支持DevOps持续交付。 + +```mermaid +graph TB + subgraph "容器化部署架构" + subgraph "前端服务层" + WEB_CONTAINER[前端容器
Nginx + Vue3] + end + + subgraph "后端服务层" + APP_CONTAINER[后端容器
Spring Boot] + end + + subgraph "数据存储层" + DB_CONTAINER[数据库容器
达梦数据库] + CACHE_CONTAINER[缓存容器
Redis] + FILE_CONTAINER[文件存储容器
MinIO] + end + + subgraph "监控服务层" + MONITOR_CONTAINER[监控容器
Prometheus + Grafana] + LOG_CONTAINER[日志容器
ELK Stack] + end + end + + %% 容器服务调用关系 + WEB_CONTAINER -.->|API请求
静态资源| APP_CONTAINER + APP_CONTAINER -.->|数据操作| DB_CONTAINER + APP_CONTAINER -.->|缓存访问| CACHE_CONTAINER + APP_CONTAINER -.->|文件存储| FILE_CONTAINER + APP_CONTAINER -.->|监控数据| MONITOR_CONTAINER + APP_CONTAINER -.->|日志数据| LOG_CONTAINER +``` + +## 子系统定义 + +### 子系统列表 + +| 子系统编号 | 子系统名称(标识) | 功能描述 | 开发方式 | +|---|---|---|---| +| SYS-001 | 统一平台 | 单点登录、统一认证(SSO/OAuth2+CAS)、审计与监控、权限、组织、参数、多租户、字典等基础能力 | 自行开发 | +| SYS-002 | 营收业务系统 | 客户管理、抄表开账、营业收费、账务处理、发票管理、催缴管理、统计分析、代收业务、客户服务、业务参数配置 | 自行开发 | +| SYS-003 | 手机抄表APP | 移动端抄表、调用外部AI识别服务、现场作业、数据同步、离线支持 | 自行开发 | +| SYS-004 | 微网厅系统 | 微信公众号平台、账户绑定、在线缴费、信息查询、业务办理、网点服务 | 自行开发 | +| SYS-005 | 工单管理系统 | 统一工单中心、工单流程引擎、监控预警、绩效统计 | 自行开发 | +| SYS-006 | 表务管理系统 | 设备档案、表务全生命周期管理 | 自行开发 | +| SYS-007 | 报装业务系统 | 报装流程管理、合同签订与电子签章、工程管理、档案管理 | 自行开发 | +| SYS-008 | 发票服务子系统 | 统一开票网关、供应商适配器(优先对接航天)、回执处理与存证 | 自行开发 | +| SYS-009 | 支付与银行结算子系统 | 聚合支付/退款、渠道适配(微信/支付宝/银联)、支付通知、银行实时收费、代扣/托收签解约、送盘/回盘/对账契约、加解密签名;夜间批量代扣与完整结算闭环按后续完善项管理 | 自行开发 | +| SYS-010 | 消息服务子系统 | 短信/邮件/站内信模板与发送、回执查询、批量推送 | 自行开发 | + +### 子系统间关系 + +#### 子系统调用关系图 + +```mermaid +--- +title: 子系统调用关系图 +--- +graph TB + %%{ + run: { + "flowchart": { + + "curve": "basis" + } + "sequence": { + "curve": "basis" + } + + } + }%% + + UP[ 【SYS-001 统一平台】
单点登录
统一认证SSO/OAuth2+CAS
审计监控
权限、组织
参数、多租户
字典管理] + REV_CORE[【SYS-002 营收业务子系统-营收核心模块群】
客户管理
抄表开账
营业收费
账务处理
发票催缴
统计代收
业务参数配置] + CS_MOD[【SYS-002 营收业务子系统-客户服务模块群】
账户绑定管理
信息查询服务
在线缴费服务
业务办理服务] + + + + APP[【SYS-003 手机抄表APP】
移动抄表
调用外部AI服务
现场作业
数据同步
离线支持] + + WECHAT[【SYS-004 微网厅子系统】
账户绑定管理
信息查询服务
在线缴费服务
业务办理服务] + + WO_CENTER[【SYS-005 工单管理子系统】
统一工单中心
创建/派发/处理/验收
监控预警] + + + METER_SYS[【SYS-006 表务管理子系统】
设备档案
表务全生命周期管理] + + + INSTALL_SYS[【SYS-007 报装业务子系统】
报装流程
合同签订与电子签章
工程管理
档案管理] + + PAY_SYS[【SYS-009 支付与银行结算子系统】
聚合支付/退款/回调
渠道适配/代扣/对账/加解密] + + INVOICE_SYS[【SYS-008 发票服务子系统】
统一开票网关
供应商适配器
回执/存证] + + + + + MSG_SYS[【SYS-010 消息服务子系统】
统一短信/邮件/推送
模板与回执] + + + %% 统一平台权限管理 + UP -.->|用户认证/权限| REV_CORE + UP -.->|用户认证/权限| CS_MOD + UP -.->|用户认证/权限| APP + UP -.->|用户认证/权限| WECHAT + UP -.->|用户认证/权限| WO_CENTER + UP -.->|用户认证/权限| METER_SYS + UP -.->|用户认证/权限| INSTALL_SYS + + %% 系统间协作 + REV_CORE -.->|库存状态/换表结果| METER_SYS + REV_CORE -.->|支付/退款/代扣/对账| PAY_SYS + REV_CORE -.->|立户/工程结果| INSTALL_SYS + REV_CORE -.->|开票申请/作废/红冲| INVOICE_SYS + REV_CORE -.->|业务异常/流程触发| WO_CENTER + CS_MOD -.->|客户申请/服务工单| WO_CENTER + + WO_CENTER -.->|换表派发| METER_SYS + WO_CENTER -.->|报装派发| INSTALL_SYS + WO_CENTER -.->|处理结果回填| REV_CORE + WO_CENTER -.->|结果通知| CS_MOD + + %% 手机APP与营收业务系统协作关系 + APP -.->|抄表数据/收费数据| REV_CORE + APP -.->|现场工单/问题上报| WO_CENTER + WO_CENTER -.->|工单派发/任务分配| APP + REV_CORE -.->|抄表任务/客户信息| APP + + %% 微网厅与营收业务系统协作关系 + WECHAT -.->|账单查询/在线缴费| REV_CORE + WECHAT -.->|业务申请/服务工单| WO_CENTER + REV_CORE -.->|账单信息/缴费状态| WECHAT + INVOICE_SYS -.->|电子发票链接/推送| WECHAT + MSG_SYS -.->|短信/邮件/推送| WECHAT + REV_CORE -.->|推送| MSG_SYS + WO_CENTER -.->|推送| MSG_SYS + CS_MOD -.->|推送| MSG_SYS + METER_SYS -.->|推送| MSG_SYS + INSTALL_SYS -.->|推送| MSG_SYS + INVOICE_SYS -.->|推送| MSG_SYS + PAY_SYS -.->|推送| MSG_SYS + + WO_CENTER -.->|办理进度/结果通知| WECHAT + + %% 样式定义 + classDef coreSystem fill:#e3f2fd,stroke:#1976d2,stroke-width:4px,color:#000 + classDef mobileSystem fill:#e8f5e8,stroke:#388e3c,stroke-width:3px,color:#000 + classDef wechatSystem fill:#f3e5f5,stroke:#9c27b0,stroke-width:3px,color:#000 + classDef platform fill:#fff3e0,stroke:#f57c00,stroke-width:2px + + class REV_CORE,CS_MOD coreSystem + class APP mobileSystem + class WECHAT wechatSystem + class UP platform + class WO_CENTER,METER_SYS,INSTALL_SYS coreSystem +``` + +#### 主要接口定义 + +**统一平台对外接口** + +| 接口编号 | 接口名称 | 功能描述 | 调用方 | 接口协议 | 输入参数 | 输出结果 | +|---|---|---|---|---|---|---| +| IF-UP-001 | OAuth2认证接口 | 基于OAuth2.0的统一认证服务 | 所有子系统 | HTTP/REST | 客户端凭证、授权类型、作用域 | 访问令牌、刷新令牌、过期时间 | +| IF-UP-002 | 组织架构接口 | 获取部门和员工组织信息 | 营收/工单/表务系统 | HTTP/REST | 组织ID、查询层级、用户权限 | 组织树结构、员工信息、权限范围 | +| IF-UP-003 | 权限验证接口 | 验证用户操作权限和资源访问 | 所有子系统 | HTTP/REST | 用户Token、操作资源、权限类型 | 验证结果、权限详情、有效期限 | +| IF-UP-004 | 数据字典接口 | 提供系统基础数据字典服务 | 所有子系统 | HTTP/REST | 字典类型、字典编码、租户ID | 字典数据、层级关系、多语言支持 | +| IF-UP-005 | 多租户管理接口 | 多租户数据隔离和权限管理 | 所有子系统 | HTTP/REST | 租户ID、操作类型、数据范围 | 租户配置、数据权限、隔离策略 | + +**营收业务系统对外接口** + +| 接口编号 | 接口名称 | 功能描述 | 调用方 | 接口协议 | 输入参数 | 输出结果 | +|---|---|---|---|---|---|---| +| IF-REV-001 | 客户信息查询接口 | 查询客户档案、账户状态、联系人与水表绑定关系 | 柜台/客户渠道/工单 | HTTPS REST | 客户ID、客户编号、手机号、查询类型 | 客户档案、账户信息、联系人列表、水表绑定关系 | +| IF-REV-004 | 抄表数据提交接口 | 提交人工或远传抄表数据并触发校验 | 手机抄表APP/集抄系统 | HTTPS REST | 抄表任务ID、水表ID、读数、图片证据、GPS位置 | 上传结果、校验状态、异常标记 | +| IF-REV-005 | 账单生成接口 | 根据抄表结果、水价模板和费用组成生成账单 | 开账任务/批量任务 | HTTPS REST | 抄表批次、账期、客户范围、应收日期 | 账单结果、失败清单、生成汇总 | +| IF-REV-006 | 缴费处理接口 | 创建收费记录并核销账单 | 柜台/线上渠道 | HTTPS REST | 客户ID、账单ID列表、支付方式、实收金额 | 收费结果、核销状态、交易流水 | +| IF-REV-008 | 发票申请接口 | 发起电子发票申请并接收票据状态回写 | 柜台/客户渠道 | HTTPS REST | 客户ID、账单ID列表、开票抬头、税号、邮箱 | 发票申请结果、票据状态、下载地址 | +| IF-REV-011 | 银行代收协同接口 | 发起代扣、回盘、对账、结算协同 | 银行代收模块/SYS-009 | HTTPS REST / 文件交换 | 批次号、渠道编码、账期、账单明细 | 批次状态、回盘结果、对账差异、结算结果 | +| IF-REV-012 | 业务参数配置接口 | 查询和维护价格模板、优惠方案、业务参数配置 | 管理后台/参数管理端 | HTTPS REST | 参数分类、模板编码、站点范围 | 参数明细、模板信息、更新结果 | +| IF-CS-001 | 账户绑定接口 | 绑定、解绑、切换默认客户 | 微信/支付宝/微网厅 | HTTPS REST | 渠道用户标识、客户编号、身份校验信息 | 绑定结果、默认客户信息、绑定关系 | +| IF-CS-002 | 历史账单查询接口 | 查询账单、欠费、用水历史、缴费记录 | 客户端 | HTTPS REST | 客户ID、账期范围、查询类型 | 账单列表、欠费金额、用水趋势、缴费记录 | +| IF-CS-003 | 在线支付下单接口 | 创建微信/支付宝线上支付订单 | 客户端 | HTTPS REST | 客户ID、账单ID列表、支付渠道、支付金额 | 订单号、支付二维码/预支付信息、订单状态 | +| IF-CS-004 | 发票申请接口 | 提交电子发票申请、查询发票状态 | 客户端 | HTTPS REST | 缴费订单号、发票抬头、邮箱/手机号 | 发票状态、发票链接、申请结果 | +| IF-CS-005 | 网点与业务办理接口 | 查询营业网点、预约信息、可办事项 | 客户端 | HTTPS REST | 行政区划、关键字、业务类型 | 网点列表、营业时间、可办业务、预约信息 | +| IF-CS-006 | 业务办理进度接口 | 提交业务申请、查询办理进度与附件 | 客户端 | HTTPS REST | 申请类型、客户资料、附件清单、申请单号 | 受理结果、流程状态、进度轨迹、补件要求 | +| IF-CS-007 | 柜面扫码支付接口 | 创建柜面扫码支付订单并回写结果 | 柜台终端/营业前台 | HTTPS REST | 柜台编号、账单ID列表、订单金额、支付渠道 | 订单号、支付状态、回写结果 | + +**手机抄表APP对外接口** + +| 接口编号 | 接口名称 | 功能描述 | 调用方 | 接口协议 | 输入参数 | 输出结果 | +|---|---|---|---|---|---|---| +| IF-MOBILE-001 | 任务下载接口 | 下载抄表任务与客户信息 | 手机抄表APP | HTTP/REST | 抄表员ID、任务日期范围 | 任务列表、客户信息、水表信息 | +| IF-MOBILE-002 | 抄表数据上传接口 | 上传抄表数据与现场图片 | 手机抄表APP | HTTP/REST | 抄表记录、现场图片、GPS位置 | 上传状态、数据校验结果 | +| IF-MOBILE-003 | 工单接收接口 | 接收工单任务 | 工单管理系统 | HTTP/REST | 工单ID、工单类型、派发信息 | 接收确认、预计处理时间 | +| IF-MOBILE-004 | 工单回填接口 | 回填处理结果与附件 | 手机抄表APP | HTTP/REST | 工单ID、处理结果、现场图片 | 回填状态、审核结果 | +| IF-MOBILE-005 | 离线同步接口 | 离线数据同步 | 手机抄表APP | HTTP/REST | 离线数据包、时间戳 | 同步状态、冲突处理结果 | + +**微网厅系统对外接口** + +| 接口编号 | 接口名称 | 功能描述 | 调用方 | 接口协议 | 输入参数 | 输出结果 | +|---|---|---|---|---|---|---| +| IF-WECHAT-001 | 微信授权登录接口 | 通过微信OAuth2.0实现用户授权登录 | 微网厅系统 | HTTP/REST | 微信授权码、AppID、AppSecret | 用户OpenID、访问令牌、用户基本信息 | +| IF-WECHAT-002 | 微信支付接口 | 调用微信支付完成在线缴费 | 微网厅系统 | HTTP/REST | 订单信息、支付金额、用户OpenID | 预支付交易会话标识、支付结果 | +| IF-WECHAT-005 | 客户信息查询接口 | 查询绑定客户的基本信息 | 微网厅系统 | HTTP/REST | 客户编号/手机号/OpenID | 客户详细信息、绑定状态 | +| IF-WECHAT-006 | 账单信息查询接口 | 查询客户账单和欠费信息 | 微网厅系统 | HTTP/REST | 客户编号、查询月份范围 | 账单明细、欠费金额、阶梯用量 | +| IF-WECHAT-007 | 缴费处理接口 | 处理微信端发起的缴费业务 | 微网厅系统 | HTTP/REST | 客户编号、缴费金额、支付方式 | 缴费订单号、支付状态、发票信息 | +| IF-WECHAT-008 | 业务申请提交接口 | 提交报装、过户等业务申请 | 微网厅系统 | HTTP/REST | 申请类型、客户资料、申请材料 | 申请单号、预审结果、处理时限 | +| IF-WECHAT-009 | 电子发票申请接口 | 申请开具电子发票 | 微网厅系统 | HTTP/REST | 缴费订单号、发票抬头信息 | 电子发票PDF、发票代码和号码 | +| IF-WECHAT-011 | 账户绑定验证接口 | 验证客户身份并绑定微信账户 | 微网厅系统 | HTTP/REST | 客户编号、身份证号、手机号码 | 绑定验证结果、绑定关系ID | + +**工单管理系统对外接口** + +| 接口编号 | 接口名称 | 功能描述 | 调用方 | 接口协议 | 输入参数 | 输出结果 | +|---|---|---|---|---|---|---| +| IF-WO-001 | 工单创建接口 | 创建各类业务工单 | 营收/表务/报装/微网厅/APP | HTTP/REST | 工单类型、客户信息、问题描述、紧急程度 | 工单编号、预计处理时间、派发状态 | +| IF-WO-002 | 工单派发接口 | 向处理人/APP派发任务 | 工单管理系统 | HTTP/REST | 工单ID、处理人员、预期完成时间 | 派发结果、接收确认状态 | +| IF-WO-003 | 工单回填接口 | 回填处理结果与附件 | APP/各业务系统 | HTTP/REST | 工单ID、处理结果、现场图片、完成时间 | 回填状态、审核结果、客户满意度 | +| IF-WO-004 | 工单查询接口 | 查询工单状态和处理轨迹 | 各业务系统/客户端 | HTTP/REST | 工单编号/客户编号、查询条件 | 工单状态、处理进度、历史轨迹 | + +**表务管理系统对外接口** + +| 接口编号 | 接口名称 | 功能描述 | 调用方 | 接口协议 | 输入参数 | 输出结果 | +|---|---|---|---|---|---|---| +| IF-METER-001 | 库存查询接口 | 查询仓库库存状态和预警信息 | 工单/营收/报装系统 | HTTP/REST | 仓库编号、水表型号、库存状态 | 库存明细、预警状态、可用数量 | +| IF-METER-002 | 领用出库接口 | 支持换表/施工水表领用出库 | 工单管理系统 | HTTP/REST | 领用单号、水表型号、领用数量、领用人 | 出库状态、库存余量、领用凭证 | +| IF-METER-003 | 档案查询接口 | 查询水表设备档案信息 | 营收/工单/报装系统 | HTTP/REST | 水表编号、客户编号、查询类型 | 设备档案、安装历史、维修记录 | + +**报装业务系统对外接口(SYS-007)** + +| 接口编号 | 接口名称 | 功能描述 | 调用方 | 接口协议 | 输入参数 | 输出结果 | +|---|---|---|---|---|---|---| +| IF-INST-001 | 报装申请接口 | 提交报装申请信息与材料 | 微网厅/营收系统 | HTTP/REST | 申请人信息、用水地址、申请材料、联系方式 | 申请单号、预审结果、处理时限 | +| IF-INST-002 | 踏勘派工接口 | 现场踏勘任务派发 | 工单管理系统 | HTTP/REST | 报装单号、踏勘要求、预约时间 | 派工结果、踏勘人员、预计完成时间 | +| IF-INST-003 | 签章接口 | 调用CA系统进行电子签章 | CA电子签章系统 | HTTP/REST | 合同文档、签章类型、签章方信息 | 签章状态、签章文档、存证信息 | +| IF-INST-004 | 签章回执接口 | 接收CA系统签章完成回执 | CA电子签章系统 | HTTP/REST | 签章任务ID、签章结果、时间戳 | 接收确认、存档状态 | +| IF-INST-006 | 验收通水接口 | 验收合格并开通供水 | 营收业务系统 | HTTP/REST | 报装单号、验收结果、水表信息 | 开户结果、客户编号、通水状态 | + +**发票服务子系统对外接口** + +| 接口编号 | 接口名称 | 功能描述 | 调用方 | 接口协议 | 输入参数 | 输出结果 | +|---|---|---|---|---|---|---| +| IF-INV-001 | 统一开票接口 | 统一受理电子发票开具请求 | 营收业务系统/微网厅 | HTTP/REST | 开票信息、购买方信息、商品明细、税额 | 发票申请ID、开票状态、预计完成时间 | +| IF-INV-002 | 作废红冲接口 | 发票作废和红字发票处理 | 营收业务系统 | HTTP/REST | 原发票号码、作废/红冲原因、操作类型 | 处理结果、新发票信息、作废状态 | +| IF-INV-003 | 发票查询接口 | 查询发票状态和下载链接 | 营收系统/微网厅/客户端 | HTTP/REST | 发票代码、发票号码、查询类型 | 发票状态、PDF下载链接、发票详情 | +| IF-INV-004 | 回执推送接口 | 接收供应商发票处理回执 | 航天信息/博思等供应商 | HTTP/REST | 回执ID、处理结果、发票文件、时间戳 | 接收确认、存储状态、通知结果 | + +**支付与银行结算子系统对外接口(SYS-009)** + +| 接口编号 | 接口名称 | 功能描述 | 调用方 | 接口协议 | 输入参数 | 输出结果 | +|---|---|---|---|---|---|---| +| IF-PAY-001 | 统一支付下单接口 | 统一处理各渠道支付下单请求 | 营收系统/微网厅 | HTTP/REST | 订单信息、支付方式、支付金额、用户标识 | 预支付订单号、支付参数、二维码 | +| IF-PAY-002 | 统一关单接口 | 订单关闭和撤销处理 | 营收系统/微网厅 | HTTP/REST | 订单号、关闭原因、操作类型 | 关单状态、退款信息、处理结果 | +| IF-PAY-003 | 统一退款接口 | 原路退款和部分退款处理 | 营收系统/微网厅 | HTTP/REST | 原订单号、退款金额、退款原因 | 退款单号、退款状态、预计到账时间 | +| IF-PAY-004 | 支付回调接口 | 接收渠道支付结果回调 | 微信/支付宝/银联 | HTTP/REST | 回调数据、签名、时间戳 | 处理确认、业务更新状态 | +| IF-PAY-005 | 批量代扣送盘接口 | 银行批量代扣文件发送 | 营收业务系统 | HTTP/REST/SFTP | 代扣清单、客户签约信息、扣款金额 | 送盘状态、批次号、预计处理时间 | +| IF-PAY-006 | 批量代扣回盘接口 | 银行代扣结果回盘处理 | 银行系统 | HTTP/REST/SFTP | 回盘文件、处理结果、失败原因 | 解析结果、状态更新、异常处理 | +| IF-PAY-007 | 批量对账文件接口 | 银行对账文件处理分析 | 银行系统/营收系统 | HTTP/REST/SFTP | 对账文件、对账日期、差异规则 | 对账结果、差异明细、调整建议 | + +**消息服务子系统对外接口(SYS-010)** + +| 接口编号 | 接口名称 | 功能描述 | 调用方 | 接口协议 | 输入参数 | 输出结果 | +|---|---|---|---|---|---|---| +| IF-MSG-001 | 短信发送接口 | 发送短信通知消息 | 营收/微网厅/工单系统 | HTTP/REST | 手机号、消息内容、模板ID、发送时间 | 发送状态、消息ID、预计到达时间 | +| IF-MSG-002 | 邮件发送接口 | 发送邮件通知消息 | 营收/工单/报装系统 | HTTP/REST | 邮箱地址、邮件主题、邮件内容、附件 | 发送状态、邮件ID、送达确认 | +| IF-MSG-003 | 站内信接口 | 发送系统站内消息 | 各业务系统 | HTTP/REST | 用户ID、消息标题、消息内容、消息类型 | 发送结果、消息状态、已读状态 | +| IF-MSG-005 | 外部系统对接接口 | 对接OA/智水擎等外部系统 | OA系统/智水擎/水投数科APP | HTTP/REST | 系统标识、消息类型、接收用户、消息内容 | 对接状态、消息分发结果 | + + + + +# 子系统1设计: 统一平台 + +## 任务概述 + +  统一平台是整个福建水务营收系统的基础支撑平台,负责为所有子系统提供统一的用户认证、权限管理、组织管理等基础服务。 + +**设计目标:** + +- 实现单点登录,用户一次认证即可访问所有授权的子系统 +- 提供统一的用户和权限管理,确保系统安全性 +- 支持多租户模式,满足集团化管理需求 +- 提供系统监控和运维支撑功能 + +**功能范围:** + +- **单点登录**:提供统一的登录入口,支持多种认证方式 +- **用户管理**:管理系统用户的基本信息、状态和权限 +- **角色管理**:定义和管理系统角色,实现基于角色的权限控制 +- **权限管理**:细粒度的功能权限和数据权限控制 +- **组织管理**:管理企业的部门结构和人员归属 +- **租户管理**:支持多租户模式,实现数据隔离和个性化配置 +- **系统监控**:实时监控系统运行状态和用户在线情况 + +## 设计概述 + +### 总体约束 + +**技术约束:** + +- 基于Spring Security + OAuth2.0+CAS协议实现认证授权 +- 采用JWT令牌实现无状态认证 +- 支持Redis分布式会话存储 +- 遵循RBAC权限控制模型 + +**性能约束:** + +- 用户认证响应时间≤1秒 +- 权限验证响应时间≤500ms +- 支持并发用户数≥200个 +- 系统可用性≥99.5% + +**安全约束:** + +- 支持密码复杂度策略 +- 提供登录安全控制(失败锁定、验证码等) +- 敏感数据加密存储 +- 完整的操作审计日志 + +### 子系统外部接口 + +**接口设计说明:** + +  统一平台为整个系统提供基础认证、权限、组织、字典等服务能力,采用OAuth2.0+CAS统一认证机制,支持多租户数据隔离和权限管理,为各业务子系统提供标准化的基础服务接口。 + +| 接口编号 | 接口名称 | 功能描述 | 调用方 | 接口协议 | 输入参数 | 输出结果 | +|---|---|---|---|---|---|---| +| IF-UP-001 | 用户认证接口 | 用户登录认证和JWT令牌生成 | 所有业务子系统 | HTTP/REST | 用户名、密码、机构编号、验证码 | JWT令牌、用户信息、权限范围 | +| IF-UP-002 | 权限验证接口 | 验证用户访问资源权限 | 所有业务子系统 | HTTP/REST | JWT令牌、资源URL、操作类型 | 权限验证结果、资源访问权限 | +| IF-UP-003 | 用户信息接口 | 获取用户基本信息 | 营收/工单/表务系统 | HTTP/REST | 用户ID、查询范围 | 用户详细信息、角色权限 | +| IF-UP-004 | 组织架构接口 | 获取部门和员工组织信息 | 营收/工单/表务系统 | HTTP/REST | 部门ID、查询层级 | 部门信息、员工列表、权限范围 | +| IF-UP-005 | 实时通知接口 | 推送系统通知消息 | 所有业务子系统 | WebSocket | 消息内容、接收用户、消息类型 | 推送结果、送达状态 | + +### 设计方案概述 + +**架构设计:** + +  统一平台采用基于Spring Boot的微服务架构,使用Spring Security + OAuth2.0+CAS协议实现认证授权,Redis存储会话和缓存数据,支持水平扩展。 + +**技术选型:** + +- **认证授权**:Spring Security + OAuth2.0 + CAS协议 + JWT +- **缓存存储**:Redis 6.0+(分布式缓存) +- **数据库**:达梦数据库 8.0+ +- **消息队列**:RabbitMQ(异步通知) +- **监控日志**:Prometheus + Grafana + ELK + +## 子系统架构设计 + +  统一平台采用分层架构设计,从下至上分为数据层、业务层、服务层和应用层,确保系统的可维护性和可扩展性。 + +```mermaid +graph TB + subgraph "统一平台架构" + subgraph "应用层" + A1[Web管理界面] + A2[移动端界面] + A3[API网关] + end + + subgraph "服务层" + B1[认证服务] + B2[权限服务] + B3[用户服务] + B4[组织服务] + B5[监控服务] + end + + subgraph "业务层" + C1[登录业务] + C2[权限业务] + C3[用户管理业务] + C4[组织管理业务] + C5[系统监控业务] + end + + subgraph "数据层" + D1[(用户数据库)] + D2[(权限数据库)] + D3[(日志数据库)] + D4[Redis缓存] + end + end + + A1 --> B1 + A2 --> B1 + A3 --> B2 + B1 --> C1 + B2 --> C2 + B3 --> C3 + B4 --> C4 + B5 --> C5 + C1 --> D1 + C2 --> D2 + C3 --> D1 + C4 --> D1 + C5 --> D3 + C1 --> D4 + C2 --> D4 +``` + +## 模块定义 + +### 模块列表 + +| 模块编号 | 模块名称(标识) | 功能描述 | 开发方式 | +|---|---|---|---| +| UP-001 | 单点登录模块 | 用户认证、授权管理、多种登录方式支持 | 自行开发 | +| UP-002 | 系统管理模块 | 用户、角色、部门、菜单等基础数据管理 | 自行开发 | +| UP-003 | 权限控制模块 | RBAC权限模型、菜单权限、数据权限 | 自行开发 | +| UP-004 | 租户管理模块 | 多租户数据隔离、租户配置管理 | 自行开发 | +| UP-005 | 系统监控模块 | 在线用户监控、系统性能监控、操作日志 | 自行开发 | + +### 模块间关系 + +**权限管理功能群:** + +  权限管理功能群是统一平台的核心,实现了完整的RBAC权限控制模型。 + +```mermaid +graph TB + subgraph "权限管理功能群" + A[UP-002 系统管理模块-用户管理功能] + B[UP-003 系统管理模块-角色管理功能] + C[UP-003 系统管理模块-菜单管理功能] + D[UP-004 系统管理模块-部门管理功能] + E[UP-005 权限控制模块-权限控制功能] + end + + A -->|用户角色关联| B + B -->|角色权限关联| C + A -->|用户部门关联| D + E -->|权限验证| A + E -->|权限验证| B + E -->|权限验证| C + + A -.->|数据权限| D + B -.->|功能权限| C +``` + +**功能群说明:** + +- 用户管理模块负责用户基本信息维护 +- 角色管理模块定义系统角色和权限 +- 菜单管理模块配置系统功能菜单 +- 部门管理模块维护组织架构 +- 权限控制模块实现统一的权限验证 + +**系统监控功能群:** + +  系统监控功能群提供对整个系统运行状态的监控和管理。 + +```mermaid +graph TB + subgraph "系统监控功能群" + F[在线用户监控] + G[系统性能监控] + H[操作日志管理] + I[系统配置管理] + end + + F -->|用户行为| H + G -->|性能数据| H + I -->|配置变更| H + + F -.->|实时监控| G + H -.->|日志分析| G +``` + +### 模块描述 + +#### UP-001: 单点登录 + +**功能描述:** + +  单点登录模块基于OAuth2.0+CAS协议实现,提供统一的用户认证入口,支持多种登录方式和安全策略。该模块是整个系统安全的第一道防线,确保只有合法用户才能访问系统。 + +**主要功能:** + +1. **用户名密码登录**:传统的用户名密码认证方式 +2. **手机号短信登录**:基于短信验证码的快速登录 +3. **第三方登录**:支持微信、支付宝等第三方平台登录 +4. **OAuth2.0单点登录**:基于OAuth2.0+CAS协议,一次登录,多系统访问 +5. **自动登录**:支持"记住我"功能 +6. **安全控制**:密码策略、登录限制、验证码等 + +**技术实现:** + +- 基于JWT令牌的无状态认证 +- Redis存储用户会话信息 +- Spring Security实现安全控制 +- 支持多种加密算法 + +#### UP-002: 系统管理 + +**功能描述:** + +  系统管理模块提供系统基础数据的维护功能,包括用户、角色、部门、菜单等核心数据的管理。 + +**主要功能:** + +1. **用户管理**:用户信息的增删改查、状态管理、权限分配 +2. **角色管理**:角色定义、权限分配、角色用户关联 +3. **部门管理**:组织架构的维护、层级关系管理 +4. **菜单管理**:系统菜单的配置、权限关联 +5. **字典管理**:系统字典数据的维护 +6. **参数管理**:系统参数的配置和管理 + +**业务规则:** + +- 用户名全局唯一 +- 手机号不能重复 +- 超级管理员不能被删除 +- 部门删除前需要先移除下属用户 + +#### UP-003: 权限控制 + +**功能描述:** + +  权限控制模块基于"主库+租户库"的多数据库架构,实现RBAC(基于角色的访问控制)模型的权限管理。通过统一的权限控制中心与租户独立的权限数据相结合,提供细粒度的功能权限和数据权限控制,同时支持跨租户用户授权的复杂场景。 + +**多库权限架构设计:** + +```mermaid +graph TB + subgraph "主库(Master Database)" + MP[统一平台权限] + MT[租户管理权限] + MU[跨租户用户关系] + MA[全局审计日志] + end + + subgraph "租户库A(Tenant-A Database)" + TA_U[用户表 system_user] + TA_R[角色表 system_role] + TA_UR[用户角色关系 system_user_role] + TA_RM[角色菜单权限 system_role_menu] + TA_D[部门表 system_dept] + end + + subgraph "租户库B(Tenant-B Database)" + TB_U[用户表 system_user] + TB_R[角色表 system_role] + TB_UR[用户角色关系 system_user_role] + TB_RM[角色菜单权限 system_role_menu] + TB_D[部门表 system_dept] + end + + subgraph "权限控制引擎" + PE[权限验证引擎] + PC[权限缓存层] + PR[权限路由器] + end + + MP -.->|统一平台管理| PE + MT -.->|租户权限元数据| PE + MU -.->|跨租户关系| PE + + PE -->|权限路由| PR + PR -->|租户A权限| TA_U + PR -->|租户B权限| TB_U + + PE --> PC + PC -.->|缓存同步| TA_R + PC -.->|缓存同步| TB_R +``` + +**主要功能:** + +1. **多库权限统一管理** + - **主库权限管理**:统一平台功能权限、租户管理权限、系统级别权限 + - **租户库权限管理**:每个租户独立的用户、角色、权限数据 + - **权限数据路由**:根据用户所属租户动态路由到对应的租户数据库 + - **跨库权限验证**:支持跨租户用户的权限验证与切换 + +2. **RBAC权限模型实现** + - **功能权限控制**:基于菜单和按钮的功能权限控制 + - **数据权限控制**:基于组织架构的数据权限隔离 + - **角色继承体系**:支持角色间的权限继承关系 + - **动态权限分配**:支持运行时动态调整用户权限 + +3. **多租户权限隔离** + - **租户级别隔离**:每个租户的权限数据完全物理隔离 + - **用户多租户授权**:用户可在多个租户中拥有不同角色和权限 + - **权限继承与覆盖**:支持从上级租户继承权限并允许覆盖 + - **租户间权限依赖**:处理母子公司间的权限依赖关系 + +4. **接口权限验证** + - **API接口级别权限验证**:每个接口请求都进行权限校验 + - **租户上下文识别**:自动识别当前用户的租户上下文 + - **动态数据源切换**:根据权限验证结果切换到正确的租户数据库 + - **权限异常处理**:统一的权限异常处理和降级策略 + +5. **权限缓存管理** + - **多级缓存策略**:主库+租户库的分层缓存 + - **权限数据实时更新**:权限变更时的缓存实时同步 + - **缓存预热机制**:系统启动时预加载热点权限数据 + - **缓存失效策略**:精确的缓存失效和更新机制 + +**多库数据模型:** + +**主库权限数据结构:** + +**1. 租户与用户关系表(tenant_user_relation)** +- **表功能**:管理跨租户用户授权关系,记录用户在不同租户中的授权状态 +- **核心字段**: + - 主键标识:唯一标识每条授权关系 + - 租户标识:指向被授权的目标租户 + - 用户标识:指向被授权的用户 + - 授权类型:区分所有者(owner)、成员(member)、访客(guest)三种类型 + - 授权人标识:记录执行授权操作的管理员 + - 授权时间:记录授权建立的时间戳 + - 过期时间:设置授权的有效期限,支持临时访问 + - 状态标识:标记授权关系是否有效,支持动态启用/禁用 + +**2. 全局权限配置表(global_permission)** +- **表功能**:维护系统级别的权限定义,为各租户提供统一的权限基准 +- **核心字段**: + - 主键标识:唯一标识每个权限配置 + - 权限代码:系统内唯一的权限标识符,如"USER_MANAGE"、"BILL_QUERY" + - 权限名称:面向用户的权限描述,支持多语言 + - 权限类型:区分菜单权限(menu)、按钮权限(button)、接口权限(api) + - 父权限标识:构建权限树形结构,支持权限继承 + - 排序序号:控制权限在界面上的显示顺序 + - 状态标识:标记权限是否启用,支持权限的动态管理 + +**租户库权限数据结构:** + +**1. 用户基础信息表(system_user)** +- **表功能**:存储租户内部的用户基础信息和账户状态 +- **核心字段**: + - 主键标识:租户内用户的唯一标识 + - 用户账号:登录用户名,在租户内保持唯一性 + - 密码哈希:加密存储的用户密码 + - 用户昵称:显示名称,提升用户体验 + - 部门标识:关联用户所属的组织部门 + - 电子邮箱:用户联系邮箱,支持邮件通知 + - 手机号码:用户联系电话,支持短信验证 + - 用户性别:基础个人信息 + - 账户状态:标记用户是否启用、锁定等状态 + - 租户编号:明确用户所属的租户,支持数据隔离 + +**2. 角色定义表(system_role)** +- **表功能**:定义租户内的角色体系,实现权限的集中管理 +- **核心字段**: + - 主键标识:租户内角色的唯一标识 + - 角色名称:角色的显示名称,如"水务管理员"、"收费员" + - 角色代码:系统内部的角色标识符,用于权限验证 + - 显示顺序:控制角色在选择列表中的排序 + - 数据范围:定义角色的数据访问范围(全部、本部门、仅本人等) + - 角色状态:标记角色是否启用 + - 角色类型:区分系统内置角色和自定义角色 + - 租户编号:明确角色所属的租户 + +**3. 用户角色关联表(system_user_role)** +- **表功能**:建立用户与角色的多对多关联关系 +- **核心字段**: + - 主键标识:唯一标识每个用户-角色关联关系 + - 用户标识:关联到具体的用户记录 + - 角色标识:关联到具体的角色记录 + - 租户编号:确保关联关系在正确的租户范围内 + +**4. 角色菜单权限关联表(system_role_menu)** +- **表功能**:定义角色具体拥有的菜单和功能权限 +- **核心字段**: + - 主键标识:唯一标识每个角色-菜单权限关联 + - 角色标识:关联到具体的角色记录 + - 菜单标识:关联到具体的菜单或功能权限 + - 租户编号:确保权限配置在正确的租户范围内 + +**权限验证流程:** + +```mermaid +flowchart TD + A[用户请求] --> B{用户已登录?} + B -->|否| C[跳转登录页面] + B -->|是| D[解析JWT令牌] + + D --> E[获取当前租户上下文] + E --> F{是否跨租户操作?} + + F -->|否| G[连接当前租户数据库] + F -->|是| H[验证跨租户授权关系] + + H --> I{授权关系有效?} + I -->|否| J[权限拒绝] + I -->|是| K[切换目标租户上下文] + + G --> L[查询用户权限] + K --> L + + L --> M[权限缓存查询] + M --> N{缓存命中?} + + N -->|是| O[返回缓存权限] + N -->|否| P[数据库查询权限] + + P --> Q[更新权限缓存] + Q --> O + O --> R[权限验证] + + R --> S{权限验证通过?} + S -->|是| T[允许访问] + S -->|否| J + + T --> U[记录访问日志] + J --> V[记录拒绝日志] +``` + +**技术实现:** + +1. **权限验证引擎** + - Spring Security + 自定义权限验证器 + - 多数据源动态切换(基于租户上下文) + - 权限注解式控制(@PreAuthorize) + - 权限表达式引擎(SpEL) + +2. **多库数据访问** + - MyBatis-Plus多数据源配置 + - 动态数据源路由器(基于租户ID) + - 数据源连接池优化 + - 读写分离支持 + +3. **权限缓存策略** + - Redis分布式缓存 + - 权限数据分层缓存(全局+租户) + - 缓存键命名规范(tenant:{tenant_id}:user:{user_id}:permissions) + - 权限变更事件驱动缓存更新 + +4. **跨租户权限处理** + - 租户上下文传递(ThreadLocal + RequestFilter) + - 跨租户权限验证链 + - 租户切换权限检查 + - 权限降级和异常处理 + +**核心业务规则:** + +1. **权限验证优先级**:主库权限 > 租户库权限 > 默认权限 +2. **跨租户访问控制**:需要显式授权,禁止越权访问 +3. **权限缓存TTL**:用户权限缓存30分钟,角色权限缓存2小时 +4. **数据权限范围**:支持全部、本部门、本部门及子部门、仅本人 +5. **权限继承规则**:子租户可继承父租户的基础权限,但可以覆盖 + +#### UP-004: 租户管理 + +**功能描述:** + +  租户管理模块基于"主库+租户库"的多数据库架构,提供完整的多租户架构支持,实现租户间物理级别的数据隔离、配置管理,以及跨租户用户授权等高级功能。该模块是实现集团化管理的核心基础设施。 + +**多库租户架构设计:** + +```mermaid +graph TB + subgraph "主库(Master Database)" + MT[租户基础信息 sys_tenant] + MTC[租户配置参数 sys_tenant_config] + MTD[租户数据库映射 sys_tenant_database] + MTU[跨租户用户关系 tenant_user_relation] + MTA[全局审计日志 sys_audit_log] + end + + subgraph "租户库A(福州水务)" + TA_USER[租户用户 tenant_user] + TA_DEPT[组织架构 tenant_department] + TA_CONFIG[业务配置 tenant_business_config] + TA_BIZ[业务数据表群] + end + + subgraph "租户库B(厦门水务)" + TB_USER[租户用户 tenant_user] + TB_DEPT[组织架构 tenant_department] + TB_CONFIG[业务配置 tenant_business_config] + TB_BIZ[业务数据表群] + end + + subgraph "租户管理引擎" + TME[租户管理引擎] + TR[租户路由器] + TCC[跨库事务协调器] + TDM[数据库动态管理器] + end + + MT -.->|租户信息管理| TME + MTC -.->|配置参数管理| TME + MTD -.->|数据库映射| TME + MTU -.->|跨租户授权| TME + + TME --> TR + TR -->|路由A| TA_USER + TR -->|路由B| TB_USER + + TME --> TCC + TCC -.->|分布式事务| TA_BIZ + TCC -.->|分布式事务| TB_BIZ + + TME --> TDM + TDM -.->|动态管理| TA_CONFIG + TDM -.->|动态管理| TB_CONFIG +``` + +**主要功能:** + +1. **租户基础管理** + - 租户创建、编辑、删除 + - 租户状态管理(启用、禁用、过期) + - 租户基本信息维护 + - 租户层级结构管理(支持母公司-子公司模式) + +2. **多库数据隔离管理** + - **主库租户管理**:在主库中统一管理所有租户的基础信息、层级关系、配置参数 + - **租户专属数据库**:为每个租户创建独立的数据库实例,实现物理级别的数据隔离 + - **跨库关系管理**:在主库中维护跨租户用户授权关系和全局配置信息 + - **租户级别缓存隔离**:基于租户标识的分布式缓存命名空间隔离 + - **文件存储隔离**:租户专属的文件存储目录和访问控制 + +3. **跨租户用户授权机制** + - **用户多租户绑定**:支持一个用户绑定多个租户 + - **租户间用户授权**:租户管理员可以将其他租户的用户授权到本租户 + - **权限继承与隔离**:用户在不同租户下可拥有不同的角色和权限 + - **租户切换**:用户可在已授权的多个租户间自由切换 + +4. **租户配置管理** + - 租户级别的业务参数配置 + - 租户专属的菜单和功能配置 + - 租户品牌定制(Logo、主题色等) + - 租户级别的集成配置 + +**跨租户用户授权业务流程:** + +```mermaid +graph TD + A[租户A管理员] --> B{选择授权用户} + B --> C[搜索其他租户用户] + C --> D[选择租户B的用户X] + D --> E[配置在租户A中的角色] + E --> H[设置数据权限范围] + H --> I[建立用户X在租户A的权限关系] + I --> J[用户X可访问租户A系统] + J --> K[用户X可在租户A/B间切换] + + M[用户X登录] --> N{选择租户} + N --> O[租户A - 角色A权限] + N --> P[租户B - 角色B权限] +``` + +**多库租户管理数据模型:** + +**主库租户管理数据结构:** + +**1. 租户基础信息表(sys_tenant)** +- **表功能**:统一管理所有租户的基础信息和层级关系 +- **核心字段**: + - 主键标识:全系统唯一的租户标识符 + - 租户编码:业务层面的租户唯一编码,格式规范化 + - 租户名称:面向用户的租户显示名称 + - 父租户标识:支持母子公司层级结构 + - 租户类型:区分集团总部、分公司、子公司等类型 + - 联系信息:租户联系人、电话、邮箱等 + - 数据库配置:租户专属数据库的连接配置信息 + - 状态标识:租户启用、禁用、过期等状态 + - 创建信息:创建时间、创建人等审计信息 + +**2. 租户配置参数表(sys_tenant_config)** +- **表功能**:管理租户级别的业务参数和系统配置 +- **核心字段**: + - 主键标识:配置项的唯一标识 + - 租户标识:关联的租户信息 + - 配置分类:区分业务参数、系统配置、集成配置等 + - 配置键名:配置项的标识符 + - 配置值:具体的配置内容,支持JSON格式 + - 配置描述:配置项的说明信息 + - 是否加密:敏感配置的加密标识 + - 生效状态:配置是否启用 + +**3. 租户数据库映射表(sys_tenant_database)** +- **表功能**:管理租户与数据库实例的映射关系 +- **核心字段**: + - 主键标识:映射关系的唯一标识 + - 租户标识:关联的租户信息 + - 数据库标识:租户专属数据库的标识符 + - 连接配置:数据库连接字符串和参数 + - 读写配置:支持读写分离的配置信息 + - 容量配置:数据库容量限制和监控阈值 + - 备份配置:备份策略和恢复配置 + - 状态信息:数据库运行状态和健康检查 + +**租户库业务数据结构:** + +**1. 租户用户信息表(tenant_user)** +- **表功能**:存储租户内部的用户信息和组织关系 +- **核心字段**: + - 主键标识:租户内用户的唯一标识 + - 全局用户标识:关联主库中的用户信息 + - 用户编号:租户内部的用户编号 + - 部门标识:用户所属的组织部门 + - 职位信息:用户在租户内的职位和级别 + - 入职信息:用户在租户的入职时间和状态 + - 权限范围:用户在租户内的数据访问范围 + - 业务角色:用户在业务流程中的角色定位 + +**2. 租户组织架构表(tenant_department)** +- **表功能**:管理租户内部的组织架构和部门层级 +- **核心字段**: + - 主键标识:部门的唯一标识 + - 部门编码:租户内部的部门编码 + - 部门名称:部门的显示名称 + - 父部门标识:构建部门层级结构 + - 部门层级:部门在组织架构中的层级深度 + - 负责人信息:部门负责人和联系方式 + - 业务范围:部门负责的业务领域 + - 状态信息:部门的启用状态和变更历史 + +**3. 租户业务配置表(tenant_business_config)** +- **表功能**:管理租户特定的业务参数和流程配置 +- **核心字段**: + - 主键标识:配置项的唯一标识 + - 业务模块:配置所属的业务模块 + - 配置类型:区分费率、流程、规则等配置类型 + - 配置内容:具体的业务配置参数 + - 生效范围:配置的适用范围和条件 + - 生效时间:配置的生效和失效时间 + - 审核信息:配置变更的审核记录 + +**跨租户授权核心规则:** + +1. **授权主体规则** + - 只有租户管理员或超级管理员可以进行跨租户用户授权 + - 被授权用户必须是已存在的系统用户 + - 授权操作需要记录完整的审计日志 + +2. **权限隔离规则** + - 用户在不同租户下的权限完全独立 + - 租户A的管理员无法查看用户在租户B的权限信息 + - 跨租户数据访问严格按照数据权限控制 + +3. **会话管理规则** + - 用户登录后默认进入主租户(第一个绑定的租户) + - 租户切换需要重新进行权限验证 + - 同一用户在不同租户的会话信息独立存储 + +4. **授权生命周期规则** + - 支持设置授权有效期 + - 到期自动失效,需要重新申请 + - 支持授权撤销,立即生效 + +**多库架构技术实现:** + +**1. 主库租户管理引擎** +- **租户信息统一管理**:主库集中管理所有租户的基础信息、配置参数、层级关系 +- **数据库实例管理**:动态创建、配置和管理租户专属数据库实例 +- **跨库事务协调**:分布式事务管理器确保跨租户操作的数据一致性 +- **租户路由器**:根据用户上下文自动路由到正确的租户数据库 + +**2. 租户数据库动态管理** +- **数据库实例创建**:基于模板自动为新租户创建独立数据库实例 +- **Schema同步管理**:统一的数据库结构版本管理和升级机制 +- **连接池管理**:每个租户数据库的独立连接池配置和监控 +- **数据迁移工具**:支持租户数据的导入、导出和迁移功能 + +**3. 多租户会话管理** +- **租户上下文传递**:ThreadLocal + Request Header的租户标识传递机制 +- **会话状态隔离**:Redis分布式缓存的租户命名空间隔离 +- **权限缓存分层**:主库权限 + 租户权限的两级缓存策略 +- **切换状态同步**:租户切换时的权限重载和会话状态更新 + +**4. 跨租户授权协调** +- **授权关系存储**:主库统一存储和管理所有跨租户授权关系 +- **权限验证引擎**:跨库权限验证和数据访问控制 +- **授权流程引擎**:支持复杂的多级审批和自动化授权流程 +- **审计日志统一**:所有跨租户操作的统一审计和监控 + +**多库架构业务规则:** + +**1. 租户管理规则** +- 租户编码全局唯一,格式:水务公司简称+年份+3位流水号 +- 每个租户必须拥有独立的数据库实例,不允许共享 +- 租户创建时自动生成标准的数据库Schema结构 +- 租户删除前必须先完成数据备份和迁移确认 + +**2. 数据隔离规则** +- 租户数据库之间严格物理隔离,禁止直接跨库访问 +- 跨租户数据访问必须通过主库的授权关系验证 +- 租户数据库连接池独立配置,避免资源争用 +- 敏感数据在租户库中加密存储,密钥独立管理 + +**3. 用户授权规则** +- 用户在单个租户下最多可拥有5个角色 +- 跨租户授权操作需要双方租户管理员审批 +- 一个用户最多可以绑定10个租户 +- 用户在不同租户下的身份信息完全独立 +- 跨租户授权关系统一在主库中管理和审计 + +**4. 事务协调规则** +- 涉及多个租户的操作必须使用分布式事务 +- 单租户内的操作在租户库内保证ACID特性 +- 跨库操作失败时自动回滚所有相关变更 +- 重要业务操作需要在主库记录操作日志 + +**5. 性能管理规则** +- 每个租户数据库设置容量上限和性能监控 +- 大租户可配置读写分离和分库分表策略 +- 租户切换操作限制频率,防止系统资源滥用 +- 定期清理过期的授权关系和会话数据 + +#### UP-005: 系统监控 + +**功能描述:** + +  系统监控模块提供全面的系统运行状态监控、性能指标收集和运维管理功能。 + +**主要功能:** + +1. **在线用户监控**:实时监控在线用户数量、用户行为、异常登录 +2. **系统性能监控**:CPU、内存、磁盘、网络等系统资源监控 +3. **操作日志管理**:用户操作日志记录、查询、分析 +4. **告警管理**:系统异常告警、性能阈值告警 + +**技术实现:** + +- Micrometer + Prometheus监控指标收集 +- ELK Stack日志分析 +- Redis存储实时监控数据 +- WebSocket实时推送监控信息 + + + +# 子系统2设计: 营收业务系统 + +## 任务概述 + +  营收业务系统是整个福建水务营收系统的核心业务系统,负责处理从客户管理到账务处理的完整营收业务流程,整合了原营收系统、表务系统、报装系统、客户服务、微网厅等所有核心业务功能。 + +**设计目标:** + +- 实现统一的营收业务管理,涵盖水务企业全业务场景 +- 提供完整的客户服务体验,从线下到线上的全渠道服务 +- 支持表务全生命周期管理,确保设备资产的有效管控 +- 实现报装业务流程标准化,提高服务效率和客户满意度 + +**功能范围:** + +  营收业务系统包含两大核心模块群,实现水务企业营收业务闭环: + +#### 营收核心模块群 + +- **客户资料管理**:客户档案建立、信息维护、分组管理 +- **抄表开账**:抄表数据录入、复核确认、自动开账 +- **营业收费**:柜台收费、移动收费、在线缴费 +- **账务处理**:一期先聚焦水量调整、金额调整、退款、冲正、坏账申请,统一经 `IF-REV-007` 承接,并按共性能力先统一、场景能力再分批推进 +- **发票管理**:发票开具、查询、重开、作废 +- **催缴管理**:欠费统计、催缴通知、停水管理 +- **统计分析**:多维度数据统计和报表分析 +- **代收业务**:银行代扣、聚合支付等代收渠道 +- **业务配置**:业务参数配置 + +#### 客户服务模块群 + +- **账户绑定管理**:微信/支付宝账户绑定和管理 +- **信息查询服务**:账单查询、用水历史、缴费记录等 +- **在线缴费服务**:多渠道在线缴费服务 +- **电子发票服务**:电子发票开具、查询、推送 +- **营业网点服务**:网点查询、地图导航、预约服务 +- **业务办理服务**:各类业务在线申请和办理 + +**核心业务流程:** +  客户建档 → 抄表录入 → 复核开账 → 营业收费 → 账务处理 → 发票管理 → 催缴管理 + +## 设计概述 + +### 总体约束 + +**技术约束:** + +- 基于Spring Boot微服务架构实现 +- 采用事务处理确保数据一致性 +- 支持分布式锁处理并发访问 +- 遵循水务行业财务规范 + +**性能约束:** + +- 支持10万+客户的业务处理 +- 抄表开账处理能力≥5000户/小时 +- 收费交易响应时间≤2秒 +- 报表生成时间≤30秒 + +**安全约束:** + +- 财务数据加密存储 +- 关键操作需要审批流程 +- 完整的操作审计日志 +- 支付接口安全认证 + +### 子系统外部接口 + +**接口设计说明:** + +  营收业务系统作为核心业务平台,整合客户管理、账务处理、抄表计费、工单管理、报装业务等完整业务流程。系统提供标准化的RESTful接口,支持多租户业务配置,确保水务营收业务的高效运营和数据一致性。 + +| 接口编号 | 接口名称 | 功能描述 | 调用方 | 接口协议 | 输入参数 | 输出结果 | +|---|---|---|---|---|---|---| +| IF-REV-001 | 客户信息查询接口 | 查询客户档案、账户状态、联系人与水表绑定关系 | 柜台/客户渠道/工单 | HTTPS REST | 客户ID、客户编号、手机号、查询类型 | 客户档案、账户信息、联系人列表、水表绑定关系 | +| IF-REV-004 | 抄表数据提交接口 | 提交人工或远传抄表数据并触发校验 | 手机抄表APP/集抄系统 | HTTPS REST | 抄表任务ID、水表ID、读数、图片证据、GPS位置 | 上传结果、校验状态、异常标记 | +| IF-REV-005 | 账单生成接口 | 根据抄表结果、水价模板和费用组成生成账单 | 开账任务/批量任务 | HTTPS REST | 抄表批次、账期、客户范围、应收日期 | 账单结果、失败清单、生成汇总 | +| IF-REV-006 | 缴费处理接口 | 创建收费记录并核销账单 | 柜台/线上渠道 | HTTPS REST | 客户ID、账单ID列表、支付方式、实收金额 | 收费结果、核销状态、交易流水 | +| IF-REV-008 | 发票申请接口 | 发起电子发票申请并接收票据状态回写 | 柜台/客户渠道 | HTTPS REST | 客户ID、账单ID列表、开票抬头、税号、邮箱 | 发票申请结果、票据状态、下载地址 | +| IF-REV-011 | 银行代收协同接口 | 发起代扣、回盘、对账、结算协同 | 银行代收模块/SYS-009 | HTTPS REST / 文件交换 | 批次号、渠道编码、账期、账单明细 | 批次状态、回盘结果、对账差异、结算结果 | +| IF-REV-012 | 业务参数配置接口 | 查询和维护价格模板、优惠方案、业务参数配置 | 管理后台/参数管理端 | HTTPS REST | 参数分类、模板编码、站点范围 | 参数明细、模板信息、更新结果 | +| IF-CS-001 | 账户绑定接口 | 绑定、解绑、切换默认客户 | 微信/支付宝/微网厅 | HTTPS REST | 渠道用户标识、客户编号、身份校验信息 | 绑定结果、默认客户信息、绑定关系 | +| IF-CS-002 | 历史账单查询接口 | 查询账单、欠费、用水历史、缴费记录 | 客户端 | HTTPS REST | 客户ID、账期范围、查询类型 | 账单列表、欠费金额、用水趋势、缴费记录 | +| IF-CS-003 | 在线支付下单接口 | 创建微信/支付宝线上支付订单 | 客户端 | HTTPS REST | 客户ID、账单ID列表、支付渠道、支付金额 | 订单号、支付二维码/预支付信息、订单状态 | +| IF-CS-004 | 发票申请接口 | 提交电子发票申请、查询发票状态 | 客户端 | HTTPS REST | 缴费订单号、发票抬头、邮箱/手机号 | 发票状态、发票链接、申请结果 | +| IF-CS-005 | 网点与业务办理接口 | 查询营业网点、预约信息、可办事项 | 客户端 | HTTPS REST | 行政区划、关键字、业务类型 | 网点列表、营业时间、可办业务、预约信息 | +| IF-CS-006 | 业务办理进度接口 | 提交业务申请、查询办理进度与附件 | 客户端 | HTTPS REST | 申请类型、客户资料、附件清单、申请单号 | 受理结果、流程状态、进度轨迹、补件要求 | +| IF-CS-007 | 柜面扫码支付接口 | 创建柜面扫码支付订单并回写结果 | 柜台终端/营业前台 | HTTPS REST | 柜台编号、账单ID列表、订单金额、支付渠道 | 订单号、支付状态、回写结果 | + +### 设计方案概述 + +**架构设计:** + +  营收系统采用领域驱动设计(DDD),按业务领域划分为客户域、抄表域、收费域、账务域等,每个域独立部署,通过事件驱动实现域间协作。 + +**技术选型:** + +- **业务框架**:Spring Boot + MyBatis-Plus +- **工作流引擎**:Flowable(处理业务审批流程) +- **分布式事务**:Seata(确保数据一致性) +- **消息队列**:RabbitMQ(异步处理和事件通知) +- **缓存策略**:Redis(热点数据缓存) + +## 子系统架构设计 + +  营收系统采用DDD领域驱动设计,按业务领域进行模块划分,实现高内聚低耦合的架构设计。系统核心分为**营收核心模块群**和**客户服务模块群**两大业务板块。 + +```mermaid +graph TB + subgraph "营收系统整体架构" + subgraph "应用层 - Application Layer" + A1[Web管理界面
管理端] + A2[移动收费界面
收费端] + A3[API接口层
接口网关] + end + + subgraph "业务服务层 - Business Service Layer" + subgraph " 营收核心模块群 REV-001~009" + subgraph "核心业务流程" + B1[REV-001
客户管理服务
客户基础] + B2[REV-002
抄表开账服务
业务源头] + B3[REV-003
营业收费服务
收入核心] + B4[REV-004
账务处理服务
财务核心] + end + + subgraph "辅助业务支撑" + B5[REV-005
发票管理服务
票据管理] + B6[REV-006
催缴管理服务
收益保障] + B7[REV-007
统计分析服务
决策支持] + B8[REV-008
代收业务服务
渠道扩展] + B9[REV-009
业务参数配置
基础配置] + end + end + + %% 工单管理模块群已独立为SYS-005 + end + + subgraph "领域层 - Domain Layer" + subgraph "营收核心业务领域" + C1[客户领域
Customer Domain
] + C2[抄表领域
Meter Reading Domain
] + C3[收费领域
Billing Domain
] + C4[账务领域
Accounting Domain
] + C5[发票领域
Invoice Domain
] + end + + subgraph "工单管理业务领域" + C6[工单统一领域
WorkOrder Domain
] + C61[工单流程引擎
Workflow Engine
] + C62[工单状态管理
Status Management
] + C63[工单智能监控
Monitor & Alert
🔔] + end + end + + subgraph "基础设施层 - Infrastructure Layer" + D1[(达梦数据库集群
DM Database Cluster
核心存储)] + D2[Redis分布式缓存
Distributed Cache
高速缓存] + D3[MinIO文件存储
Distributed File Storage
文件管理] + D4[RabbitMQ消息队列
Message Queue
异步通信] + D5[支付与结算服务(SYS-009)
Payment & Settlement
聚合支付/代扣/对账] + D6[Flowable工作流引擎
Workflow Engine
流程引擎] + end + + subgraph "外部系统集成" + E1[手机抄表APP
移动端] + E2[微网厅系统
线上服务] + E3[表务系统
设备管理] + end + end + + %% 应用层到业务服务层连接 + A1 --> B1 + A1 --> B9 + A2 --> B3 + A3 --> B8 + A3 --> B9 + + %% 营收核心模块群内部业务流程 + B1 -->|客户数据| B2 + B2 -->|账单数据| B3 + B3 -->|收费数据| B4 + B4 -->|财务数据| B5 + B1 -.->|客户信息| B6 + B3 -.->|收费统计| B7 + B8 -.->|代收数据| B3 + + %% 工单管理模块群已独立为SYS-005 + + %% 业务服务层到领域层映射 + B1 --> C1 + B2 --> C2 + B3 --> C3 + B4 --> C4 + B5 --> C5 + B6 --> C1 + B7 --> C3 + B8 --> C3 + + %% 工单领域移至SYS-005 + + %% 领域层到基础设施层 + C1 --> D1 + C2 --> D1 + C3 --> D1 + C4 --> D1 + C5 --> D3 + C6 --> D4 + C61 --> D6 + C62 --> D2 + C63 --> D4 + B8 --> D5 + + %% 外部系统集成(工单流转由SYS-005承担) + + %% 样式定义 + classDef coreModuleGroup fill:#e3f2fd,stroke:#1976d2,stroke-width:4px,color:#000 + classDef workorderModuleGroup fill:#fce4ec,stroke:#c2185b,stroke-width:4px,color:#000 + classDef coreModule fill:#e1f5fe,stroke:#0277bd,stroke-width:2px + classDef workorderModule fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px + classDef coreDomain fill:#e8f5e8,stroke:#388e3c,stroke-width:2px + classDef workorderDomain fill:#fff3e0,stroke:#f57c00,stroke-width:2px + classDef infrastructure fill:#f3e5f5,stroke:#9c27b0,stroke-width:2px + classDef external fill:#e0f2f1,stroke:#00695c,stroke-width:2px + + %% 应用样式 + class B1,B2,B3,B4,B5,B6,B7,B8,B9 coreModule + class B9,B91,B92,B93,B94 workorderModule + class C1,C2,C3,C4,C5 coreDomain + class C6,C61,C62,C63 workorderDomain + class D1,D2,D3,D4,D5,D6 infrastructure + class E1,E2,E3 external +``` + +## 模块定义 + +### 模块列表 + +  营收系统的模块按业务性质分为两大模块群: + +#### 营收核心模块群 + +  营收核心业务模块,实现从客户管理到收费账务的完整业务链条,并通过 SYS-008 发票服务、SYS-009 支付与银行结算、SYS-010 消息服务形成跨子系统协同闭环: + +| 模块编号 | 模块名称(标识) | 功能描述 | 开发方式 | +|---|---|---|---| +| REV-001 | 客户资料管理 | 客户档案管理、客户分组、信息变更 | 自行开发 | +| REV-002 | 抄表开账 | 抄表录入、复核开账、异常处理 | 自行开发 | +| REV-003 | 营业收费 | 柜台收费、移动收费、在线缴费 | 自行开发 | +| REV-004 | 账务处理 | 账务调整、退款处理、坏账管理 | 自行开发 | +| REV-005 | 发票管理 | 发票开具、查询管理、电子发票 | 自行开发 | +| REV-006 | 催缴管理 | 欠费催缴、短信通知、停水管理 | 自行开发 | +| REV-007 | 统计分析 | 多维度数据统计和报表分析功能 | 自行开发 | +| REV-008 | 代收业务 | 集成银行渠道与聚合支付等代收方式 | 自行开发 | +| REV-009 | 业务参数配置 | 业务参数配置、参数管理 | 自行开发 | + +#### 客户服务模块群 + +  为外部渠道(微网厅、第三方平台)和内部渠道(客服前台)提供服务接入能力: + +- 账户绑定管理、信息查询服务、在线缴费服务、电子发票服务、营业网点服务、业务办理服务、柜面扫码支付 + +| 模块编号 | 模块名称(标识) | 功能描述 | 开发方式 | +|---|---|---|---| +| CS-001 | 账户绑定管理 | 微信/支付宝账户绑定与解绑、多账户管理 | 自行开发 | +| CS-002 | 信息查询服务 | 账单查询、用水历史、缴费记录、停水公告 | 自行开发 | +| CS-003 | 在线缴费服务 | 快捷缴费、充值、代缴、结果查询(经SYS-009) | 自行开发 | +| CS-004 | 电子发票服务 | 发票查看、推送、下载(经SYS-008) | 自行开发 | +| CS-005 | 营业网点服务 | 网点查询、地图导航、预约(可选) | 自行开发 | +| CS-006 | 业务办理服务 | 联系方式/开票方式变更、更名过户、低保、换表、自主抄表等 | 自行开发 | +| CS-007 | 柜面扫码支付 | 柜台二维码收款、票据关联、结果回传(经SYS-009) | 自行开发 | + +### 模块间关系 + +  营收系统的两大模块群既相对独立又紧密协作,形成完整的业务生态系统。 + +#### 营收核心模块群关系 + +  营收核心业务群实现了从客户管理到账务处理的完整营收业务流程: + +```mermaid +graph TD + subgraph "营收核心业务流程" + A[REV-001
客户资料管理
] --> B[REV-002
抄表开账
] + B --> C[REV-003
营业收费
] + C --> D[REV-004
账务处理
] + D --> E[REV-005
发票管理
] + + subgraph "辅助业务流程" + F[REV-006
催缴管理
] + G[REV-007
统计分析
] + H[REV-008
代收业务
] + I[REV-009
业务参数配置
] + end + end + + %% 主流程依赖关系 + A -.->|客户信息| C + A -.->|客户信息| E + A -.->|客户信息| F + B -.->|账单信息| D + B -.->|欠费信息| F + C -.->|收费记录| E + C -.->|收费数据| G + D -.->|账务数据| G + H -.->|代收记录| C + I -.->|水价/参数| B + I -.->|打印/税率/参数| E + I -.->|收费参数| C + + %% 样式 + classDef coreFlow fill:#e3f2fd,stroke:#1976d2,stroke-width:2px + classDef supportFlow fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px + + class A,B,C,D,E coreFlow + class F,G,H,I supportFlow +``` + +#### 客户服务模块群关系 + +  客户服务模块群为对外提供服务的核心入口,构建以客户为中心的一体化服务体系: + +```mermaid +graph TD + subgraph "客户服务核心流程" + A[CS-001
账户绑定管理
] --> B[CS-002
信息查询服务
] + B --> C[CS-003
在线缴费服务
] + C --> D[CS-004
电子发票服务
] + + subgraph "辅助服务模块" + E[CS-005
营业网点服务
] + F[CS-006
业务办理服务
] + G[CS-007
柜面扫码支付
] + end + end + + %% 服务调用关系 + A -.->|绑定验证| F + B -.->|查询支撑| C + B -.->|查询支撑| D + B -.->|查询支撑| F + C -.->|支付回调| D + G -.->|线下支付| D + E -.->|网点导航| F + F -.->|办理结果| B + + %% 外部系统依赖 + C -.->|支付处理| SYS009[SYS-009
支付系统] + D -.->|发票开具| SYS008[SYS-008
发票系统] + G -.->|扫码支付| SYS009 + F -.->|工单流转| SYS005[SYS-005
工单系统] + + %% 样式 + classDef coreService fill:#e8f5e8,stroke:#4caf50,stroke-width:2px + classDef supportService fill:#fff3e0,stroke:#ff9800,stroke-width:2px + classDef externalSys fill:#f3e5f5,stroke:#9c27b0,stroke-width:2px + + class A,B,C,D coreService + class E,F,G supportService + class SYS008,SYS009,SYS005 externalSys +``` + +**服务流程说明:** + +- **账户绑定**:客户通过微信/支付宝绑定水表账户,建立服务关系 +- **信息查询**:基于绑定关系,提供账单、用水历史、缴费记录等查询服务 +- **在线缴费**:支持快捷缴费、充值、代缴等多种缴费方式 +- **电子发票**:缴费完成后自动开具电子发票,支持查看下载 +- **业务办理**:提供各类业务在线申请,如更名过户、换表申请等 +- **营业网点**:提供网点查询、地图导航、预约服务等 +- **柜面扫码**:线下柜台扫码支付,与线上服务形成闭环 + +#### 模块群间协作关系 + +  两大模块群通过标准化接口进行协作,实现业务闭环: + +```mermaid +graph TB + subgraph "营收核心模块群" + CORE[REV-001~009
客户/抄表/收费/账务/发票/催缴/统计/代收/参数] + end + + subgraph "客户服务模块群" + CS[CS-001~007
账户绑定/查询/在线缴费/电子发票/网点/办理/柜面扫码] + end + + subgraph "工单管理系统" + WO[SYS-005
统一工单中心] + end + + CORE <-->|标准API| CS + CORE -.->|业务异常/流程触发| WO + CS -.->|客户申请/服务工单| WO + + classDef coreGroup fill:#e1f5fe,stroke:#0277bd,stroke-width:3px + classDef csGroup fill:#e8f5e8,stroke:#388e3c,stroke-width:3px + classDef workorderGroup fill:#f3e5f5,stroke:#7b1fa2,stroke-width:3px + + class CORE coreGroup + class CS csGroup + class WO workorderGroup +``` + +### 模块描述 + +#### REV-001: 客户资料管理 + +**功能概述:** + +  客户资料管理模块是营收系统的基础,负责维护所有用水客户的基本信息和档案资料。 + +**核心功能:** + +1. **客户档案管理** + - 新客户建档 + - 客户信息修改 + - 客户状态管理(正常、停用、注销) + - 客户变更历史记录 + +2. **客户分组管理** + - 按区域分组 + - 按用水性质分组 + - 按客户类型分组 + - 自定义分组 + +3. **客户查询服务** + - 多条件组合查询 + - 模糊查询支持 + - 高级筛选功能 + +**子功能扩展:** + +- 客户分组:客户分组管理、分组内客户管理 +- 集收管理:集收号管理、集收号内客户管理 +- 立户建档:手工建档、批量立户 +- 定额管理:定额共享(主/子客户)、定额核定 +- 批量修改:手工修改、模板导入修改 +- 客户业务办理:换表、加抄、更名、过户、低保、调价、停用/启用、注销/恢复 +- 电子档案:高拍仪/附件采集与档案管理 + +**业务规则:** + +- 客户编号系统自动生成,格式:部门代码+年份+6位流水号 +- 身份证号码必须通过实名认证 +- 客户状态变更需要审批流程 +- 存在未结清账务的客户不允许注销 + +#### REV-002: 抄表开账 + +**功能概述:** + +  抄表开账模块实现了从抄表数据录入到自动生成账单的完整业务流程。 + +**核心功能:** + +1. **抄表数据录入** + - 手工抄表录入 + - PDA抄表导入 + - 远传抄表自动采集 + - Excel批量导入 + +2. **抄表数据复核** + - 数据有效性验证 + - 异常用水量检测 + - 人工复核确认 + - 批量复核处理 + +3. **自动开账处理** + - 水量计算 + - 费用计算 + - 账单生成 + - 开账确认 + +**子功能扩展:** + +- 册本信息:册本查询、册本详情 +- 册本调整:新卡入册、册内序号调整、册本间调整 +- 抄表录入:按册本/按抄表员、导入抄表数据 +- 复核开账:复核开账查询/汇总、复核与开账 +- 开账记录:历史查询与导出 + +**业务流程图:** + +```mermaid +flowchart TD + A[开始抄表] --> B{选择抄表方式} + B -->|手工抄表| C[手工录入抄表数据] + B -->|PDA抄表| D[PDA现场抄表] + B -->|远传抄表| E[自动采集抄表数据] + B -->|批量导入| F[Excel批量导入] + + C --> G[系统数据验证] + D --> H[PDA数据上传] + E --> I[远传数据同步] + F --> J[批量数据校验] + + H --> G + I --> G + J --> G + + G --> K{数据是否有效?} + K -->|否| L[数据修正] + L --> G + K -->|是| M[抄表数据复核] + + M --> N{复核是否通过?} + N -->|否| O[标记异常数据] + O --> P[人工处理异常] + P --> M + N -->|是| Q[计算用水量] + + Q --> R[计算水费金额] + R --> S[生成账单] + S --> T[开账确认] + T --> U[结束] +``` + +**业务规则:** + +- 抄表状态:正常、故障、估读、拒抄、空房等 +- 用水量计算:本期读数 - 上期读数 +- 异常判断:超过历史平均值2倍为量高,低于0.5倍为量低 +- 复核规则:抄表人员不能复核自己录入的数据 + +#### REV-003: 营业收费 + +**功能概述:** + +  营业收费模块提供完整的收费业务流程管理,支持多种收费方式和支付渠道。 + +**核心功能:** + +1. **柜台收费** + - 实时收费处理 + - 多种支付方式 + - 收费凭证打印 + - 柜台结账管理 + +2. **在线缴费** + - 微信支付接入 + - 支付宝支付接入 + - 银行卡支付 + - 代扣代缴服务 + +3. **批量收费** + - 批量缴费处理 + - 预付款管理 + - 托收业务 + - 自动扣费 + +**子功能扩展:** + +- 特殊开账:特殊情形直接开账及查询导出 +- 柜台结账:结账、红冲、打印凭证 +- 红冲记录:红冲查询与导出 + +**业务流程图:** + +```mermaid +flowchart TD + A[客户缴费] --> B{选择缴费方式} + B -->|柜台缴费| C[到营业厅缴费] + B -->|在线缴费| D[选择在线支付] + B -->|银行代扣| E[银行自动扣费] + + C --> F[查询客户账单] + D --> G[微信/支付宝支付] + E --> H[银行代扣处理] + + F --> I{账单是否正确?} + I -->|否| J[账单调整] + J --> F + I -->|是| K[选择支付方式] + + K --> L{支付方式} + L -->|现金| M[现金收费] + L -->|POS机| N[刷卡收费] + L -->|扫码| O[扫码支付] + + G --> P[渠道支付确认] + H --> Q[银行扣费确认] + M --> R[收费确认] + N --> R + O --> R + P --> R + Q --> R + + R --> S[更新账单状态] + S --> T[生成收费凭证] + T --> U{需要发票?} + U -->|是| V[开具发票] + U -->|否| W[完成收费] + V --> W + W --> X[结束] +``` + +**业务规则:** + +1. 收费员每日下班前必须进行"柜台结账" +2. 结账前,收错的账款可以执行"红冲"操作 +3. 支持现金、POS机、微信、支付宝等多种支付方式 +4. 在线支付需要实时确认支付结果 +5. 银行代扣需要客户事先签约授权 + +#### REV-004: 账务处理 + +**功能概述:** + +  负责处理各类复杂的账务调整、退款、坏账等业务,确保账务的准确性和合规性。 + +**核心功能:** + +- **未销账调整**: 对未支付账单进行调整。 +- **分账调整**: 将一笔总账单拆分为多笔子账单。 +- **预付款退款**: 处理客户预付款的退还流程。 +- **呆坏账处理**: 对长期无法收回的欠款进行核销。 + +#### REV-005: 发票管理 + +**功能概述:** + +  提供全面的发票管理功能,支持电子发票和纸质发票的开具、查询、作废等操作。 + +**核心功能:** + +- **发票开具**: 根据缴费记录为客户开具发票。 +- **发票查询与管理**: 查询发票历史,处理红冲、作废等请求。 +- **电子发票集成**: 对接第三方电子发票平台,实现自动开具和推送。 + +**实现说明:** + +- 本模块通过调用`SYS-008 发票服务子系统`的"统一开票接口/作废红冲接口/发票查询接口"实现具体的开票与回执处理,营收系统不直接对接供应商。 + +#### REV-006: 催缴管理 + +**功能概述:** + +  对逾期未缴费的客户进行有效的催缴管理,提高水费回收率。 + +**核心功能:** + +- **欠费分析**: 统计和分析欠费客户数据。 +- **催缴通知**: 通过短信、电话、通知单等多种方式进行催缴。 +- **停复水管理**: 对恶意欠费用户执行停水,缴清后进行复水操作。 + +#### REV-007: 统计分析 + +**功能概述:** + +  提供多维度的数据统计和报表分析功能,为管理决策提供数据支持。 + +**核心功能:** + +- **售水统计**: 按日、月、年统计售水量、售水收入等。 +- **收费统计**: 统计不同收费渠道、方式的收费情况。 +- **欠费分析**: 多维度分析欠费构成和趋势。 +- **自定义报表**: 提供灵活的报表自定义工具。 +- **报表查询**: 业务分类报表树、统计条件与结果导出。 +- **欠费查询**: 按账期/金额等条件查询客户欠费。 +- **缴费记录**: 缴费记录检索与导出。 + +#### REV-008: 代收业务 + +**功能概述:** + +  集成银行渠道与聚合支付等代收方式,方便客户缴费。 + +**核心功能:** + +- **银行代扣**: 与银行签订协议,实现自动批量扣费。 +- **聚合支付**: 集成微信、支付宝等支付网关。 +- **对账管理**: 定期与各渠道进行账务核对。 +- **实时收费**: 渠道实时缴费处理(对接SYS-009)。 +- **银行托收**: 托收文件处理与状态跟踪(对接SYS-009)。 + +#### REV-009: 业务参数配置 + +**功能概述:** + +  集中管理与营收业务相关的参数与基础资料,提升配置一致性与运营效率。 + +**核心功能:** + +- 水表参数:水表厂家、型号、口径、量程 +- 地址参数:营业站点、所属小区 +- 价格体系:水价归属、费用组成、水价调整、调价历史、优惠方案、用水方案 +- 基本配置:打印维护、自定义列、日志管理、水司账户、发票税率、银行信息、抄表状态、词语信息、参数配置 + +### 客户服务模块群描述 + +#### CS-001: 账户绑定管理 + +**功能概述:** + +  账户绑定管理模块是客户服务体系的入口,负责处理客户与第三方平台账户的绑定关系管理,为后续的信息查询、在线缴费等服务奠定基础。 + +**核心功能:** + +1. **账户绑定流程** + - 微信/支付宝授权登录 + - 客户编号/户名/手机号搜索验证 + - 账户信息确认与绑定 + - 绑定状态维护与管理 + +2. **多账户管理** + - 支持一个用户绑定多个水务账户 + - 主账户设置与切换 + - 账户别名设置 + - 绑定账户列表管理 + +3. **解绑与重绑** + - 账户解绑流程 + - 解绑权限控制 + - 重新绑定验证 + - 解绑日志记录 + +**技术实现:** +- 基于OAuth2.0协议实现第三方授权 +- Redis缓存绑定关系提升查询性能 +- 数据加密存储保护客户隐私 + +#### CS-002: 信息查询服务 + +**功能概述:** + +  信息查询服务模块为客户提供全方位的信息查询功能,包括账单查询、用水历史、缴费记录等,是客户服务的核心模块之一。 + +**核心功能:** + +1. **账单查询服务** + - 当前账单查询 + - 历史账单查询 + - 账单详情展示 + - 欠费账单提醒 + +2. **用水信息查询** + - 用水量历史统计 + - 用水趋势分析 + - 抄表记录查询 + - 异常用水提醒 + +3. **缴费信息查询** + - 缴费记录查询 + - 缴费方式统计 + - 发票信息查询 + - 退费记录查询 + +4. **公告信息服务** + - 停水公告查看 + - 水价调整通知 + - 服务公告推送 + - 用水指南 + +**技术实现:** +- 分页查询优化大数据量处理 +- 数据缓存策略提升响应速度 +- 接口聚合减少客户端调用 + +#### CS-003: 在线缴费服务 + +**功能概述:** + +  在线缴费服务模块提供便捷的线上缴费功能,支持多种支付方式,与SYS-009支付系统深度集成,确保支付的安全性和可靠性。 + +**核心功能:** + +1. **快捷缴费** + - 一键缴费当前账单 + - 批量缴费多个账单 + - 预设金额快速充值 + - 自动扣费设置 + +2. **多样化缴费方式** + - 微信支付 + - 支付宝支付 + - 银联在线支付 + - 银行代扣缴费 + +3. **代缴服务** + - 代他人缴费 + - 批量代缴管理 + - 代缴权限控制 + - 代缴记录跟踪 + +4. **缴费管理** + - 缴费结果查询 + - 缴费凭证生成 + - 退费申请处理 + - 缴费异常处理 + +**技术实现:** +- 与SYS-009支付系统标准化对接 +- 订单状态实时同步机制 +- 支付安全策略与风控 + +#### CS-004: 电子发票服务 + +**功能概述:** + +  电子发票服务模块与SYS-008发票系统集成,为客户提供电子发票的查看、下载、推送等服务,满足客户对发票的个性化需求。 + +**核心功能:** + +1. **发票查看服务** + - 发票列表查询 + - 发票详情展示 + - 发票状态跟踪 + - 发票验真服务 + +2. **发票推送服务** + - 邮箱推送发票 + - 微信推送发票 + - 短信通知发票 + - 实时推送状态 + +3. **发票下载服务** + - PDF格式下载 + - 批量打包下载 + - 二维码扫描下载 + - 下载记录管理 + +4. **发票管理** + - 开票信息维护 + - 发票抬头管理 + - 特殊发票申请 + - 发票重开申请 + +**技术实现:** +- 与SYS-008发票系统API对接 +- 文件流处理与下载优化 +- 发票防伪与验真机制 + +#### CS-005: 营业网点服务 + +**功能概述:** + +  营业网点服务模块为客户提供营业网点相关的信息服务,包括网点查询、地图导航、预约服务等,提升客户线下服务体验。 + +**核心功能:** + +1. **网点信息查询** + - 就近网点查询 + - 网点详细信息 + - 营业时间查询 + - 服务项目介绍 + +2. **地图导航服务** + - 地图位置展示 + - 导航路线规划 + - 距离时间计算 + - 交通方式推荐 + +3. **网点预约服务** + - 业务预约申请 + - 预约时间管理 + - 预约状态跟踪 + - 预约取消重约 + +4. **网点评价反馈** + - 服务评价提交 + - 意见建议反馈 + - 投诉建议处理 + - 满意度调查 + +**技术实现:** +- 地理位置服务集成 +- 地图API调用优化 +- 预约队列管理机制 + +#### CS-006: 业务办理服务 + +**功能概述:** + +  业务办理服务模块为客户提供各类水务业务的在线申请和办理功能,与SYS-005工单系统协作实现业务流程的数字化处理。 + +**核心功能:** + +1. **基础业务办理** + - 联系方式变更 + - 开票信息变更 + - 用水性质变更 + - 账户信息修改 + +2. **高级业务办理** + - 更名过户申请 + - 水表换表申请 + - 低保减免申请 + - 自主抄表申请 + +3. **办理流程管理** + - 申请表单填写 + - 附件资料上传 + - 申请进度跟踪 + - 办理结果通知 + +4. **业务咨询服务** + - 办理条件查询 + - 办理流程指导 + - 所需材料清单 + - 在线客服咨询 + +**技术实现:** +- 与SYS-005工单系统流程集成 +- 动态表单引擎支持 +- 文件上传与存储管理 + +#### CS-007: 柜面扫码支付 + +**功能概述:** + +  柜面扫码支付模块为营业厅提供便捷的扫码收款功能,与SYS-009支付系统集成,实现线下支付的数字化处理。 + +**核心功能:** + +1. **扫码支付流程** + - 收费二维码生成 + - 扫码支付处理 + - 支付结果确认 + - 票据关联打印 + +2. **收款管理** + - 收款金额确认 + - 收款方式选择 + - 收款状态跟踪 + - 收款异常处理 + +3. **票据关联** + - 缴费凭证生成 + - 发票自动开具 + - 收据打印输出 + - 票据存档管理 + +4. **结果回传** + - 支付状态同步 + - 账务数据回传 + - 营业员确认 + - 客户通知发送 + +**技术实现:** +- 与SYS-009支付系统深度集成 +- 二维码动态生成与管理 +- POS机硬件设备对接 + + + +# 子系统3设计: 手机抄表APP + +## 任务概述 + +  手机抄表APP为抄表员、外勤人员提供移动作业工具,支持离线操作,通过调用外部摄像表AI系统实现抄表读数自动识别,提升现场工作效率。 + +**设计目标:** + +- 实现移动化抄表作业,提高工作效率 +- 支持离线作业,确保在无网络环境下正常工作 +- 构建完整的工单闭环处理流程 +- 提供直观友好的移动端用户体验 + +**功能范围:** + +- **登录认证**:机构编号、用户名密码认证、自动登录 +- **首页搜索**:多维度搜索、最近搜索记录、抄表任务 +- **采集任务管理**:任务列表管理、批量下载、单户采集 +- **现场上报**:问题上报(由SYS-005工单系统统一受理与派发) +- **个人设置**:个人信息管理、系统设置维护 + +**核心业务流程:** +  任务下载 → 现场抄表 → 问题上报 → 工单处理 → 数据上传 → 结果同步 + +## 设计概述 + +### 总体约束 + +**技术约束:** + +- 基于Spring Boot微服务架构 +- 采用条码/二维码技术进行水表标识 +- 支持RFID技术的水表管理 +- 遵循水表行业标准和规范 + +**性能约束:** + +- 支持100万+水表档案管理 +- 库存操作响应时间≤1秒 +- 支持并发库存操作≥50个 +- 盘点效率≥1000个/小时 + +**安全约束:** + +- 水表资产数据加密存储 +- 关键操作审批流程 +- 完整的操作审计日志 +- 防止水表资产丢失 + +### 子系统外部接口 + +**接口设计说明:** + +  手机抄表APP系统作为移动端现场作业工具,需要与营收业务系统、工单管理系统保持数据同步。所有接口均采用HTTP/REST协议,支持离线缓存和在线同步模式,确保现场作业的连续性和数据一致性。 + +| 接口编号 | 接口名称 | 功能描述 | 调用方 | 接口协议 | 输入参数 | 输出结果 | +|---|---|---|---|---|---|---| +| IF-MOBILE-001 | 任务下载接口 | 下载抄表任务与客户信息 | 手机抄表APP | HTTP/REST | 抄表员ID、任务日期范围 | 任务列表、客户信息、水表信息 | +| IF-MOBILE-002 | 抄表数据上传接口 | 上传抄表数据与现场图片 | 手机抄表APP | HTTP/REST | 抄表记录、现场图片、GPS位置 | 上传状态、数据校验结果 | +| IF-MOBILE-003 | 工单接收接口 | 接收工单任务 | 工单管理系统 | HTTP/REST | 工单ID、工单类型、派发信息 | 接收确认、预计处理时间 | +| IF-MOBILE-004 | 工单回填接口 | 回填处理结果与附件 | 手机抄表APP | HTTP/REST | 工单ID、处理结果、现场图片 | 回填状态、审核结果 | +| IF-MOBILE-005 | 离线同步接口 | 离线数据同步 | 手机抄表APP | HTTP/REST | 离线数据包、时间戳 | 同步状态、冲突处理结果 | + +### 设计方案概述 + +**架构设计:** + +  端云协同架构,APP端提供离线能力(本地缓存与任务包),在线时通过增量同步接口与服务端完成任务下载、数据上传与工单回填,确保弱网环境可用。 + +**关键技术:** + +- 本地缓存与数据加密存储、断点续传 +- 条码/二维码识别,拍照取证 +- 任务包增量同步与冲突处理 + +## 子系统架构设计 + +  手机抄表APP采用原生移动应用架构,支持Android平台部署。系统采用端云协同模式,APP端具备强大的离线工作能力,通过本地存储任务数据和抄表记录,支持弱网环境下的连续作业。 + + +```mermaid +graph TB + subgraph "手机抄表APP" + Login[登录认证] + Home[首页/搜索] + Task[采集任务] + Report[现场上报] + Sync[数据同步] + Settings[个人与设置] + end + + subgraph "服务端" + AUTH[统一平台] + REV[营收业务系统] + WO[工单管理系统] + end + + Login --> AUTH + Home --> REV + Task --> REV + Report --> WO + Sync <--> REV + WO -.-> Task +``` + +## 模块定义 + +### 模块列表 + +| 模块编号 | 模块名称(标识) | 功能描述 | 开发方式 | +|---|---|---|---| +| MOBILE-001 | 登录认证 | 机构编号、用户名/密码、自动登录、令牌管理 | 自行开发 | +| MOBILE-002 | 首页搜索 | 多维度搜索、最近记录、任务快捷入口 | 自行开发 | +| MOBILE-003 | 采集任务管理 | 任务列表、批量下载、单户采集、调用外部AI识别、读数校验 | 自行开发 | +| MOBILE-004 | 现场上报 | 问题上报、拍照取证、定位信息、异常标记 | 自行开发 | +| MOBILE-005 | 个人与设置 | 个人资料、偏好设置、缓存管理、安全退出 | 自行开发 | +| MOBILE-006 | 数据同步 | 任务包增量同步、离线数据包上传、冲突处理 | 自行开发 | + + +### 模块间关系 + +```mermaid +graph TD + subgraph "手机抄表APP模块关系" + A[MOBILE-001
登录认证] + B[MOBILE-002
首页搜索] + C[MOBILE-003
采集任务管理] + D[MOBILE-004
现场上报] + E[MOBILE-005
个人与设置] + F[MOBILE-006
数据同步] + end + + subgraph "外部系统" + AI[摄像表AI系统
(外部服务)] + end + + A -->|认证通过| C + B -->|搜索定位| C + C -.->|API调用| AI + AI -.->|识别结果| C + C -->|任务数据| F + D -->|上报数据| F + E -.->|配置同步| F + F -->|数据上传| UP[统一平台] + F -->|任务下载| CS[营收业务系统] + + %% 样式定义 + classDef coreModule fill:#e3f2fd,stroke:#1976d2,stroke-width:2px + classDef syncModule fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px + classDef externalModule fill:#fff3e0,stroke:#e65100,stroke-width:2px,stroke-dasharray: 5 5 + + class A,B,C,D coreModule + class E,F syncModule + class AI externalModule +``` + +### 模块描述 + +#### MOBILE-001: 登录认证 + +- 机构编号+用户名/密码登录 +- 自动登录选项 +- 登录问题客服支持 + +#### MOBILE-002: 首页搜索 + +- 户号/户名/地址/钢印号/手机号搜索 +- 最近搜索记录展示 +- 抄表任务列表 +- 搜索结果实时展示 + +#### MOBILE-003: 采集任务管理 + +- 任务列表与批量下载 +- 单户采集详情页 +- 定位/NFC/扫码三种采集方式 +- 上一户/下一户导航 + +#### MOBILE-004: 现场上报 + +- 换表工单处理 +- 复水工单确认 +- 稽查任务管理 +- 问题上报功能 +- 图片/视频附件上传 + +#### MOBILE-005: 个人与设置 + +- 个人信息查看与修改 +- 密码修改与退出登录 +- 日志上传与清理缓存 +- 异常水量预警设置 +- 数据库备份 + +#### MOBILE-006: 数据同步 + +- 增量任务同步 +- 离线包上传 +- 断点续传 +- 冲突解决 + + + + + +# 子系统4设计: 微网厅系统 + +## 任务概述 + +  微网厅系统(SYS-004)基于微信公众号平台开发,为客户提供便民的自助服务平台。系统支持账户绑定、账单查询、在线缴费、电子发票、营业网点查询和各类业务办理等功能。通过微信生态为用户提供7×24小时不间断的自助服务,显著提升客户服务体验。 + +## 设计概述 + +### 总体约束 + +**技术约束**: + +- 基于微信公众号开发框架 +- 遵循微信开发规范和接口限制 +- 采用响应式设计,适配不同移动设备 +- 支持微信支付集成 + +**安全约束**: + +- 严格的用户身份验证机制 +- 敏感数据加密传输和存储 +- 符合微信平台安全规范 +- 防范常见Web安全威胁 + +**业务约束**: + +- 必须与营收业务系统实时数据同步 +- 支持多账户绑定管理 +- 提供完整的业务流程闭环 + +### 子系统外部接口 + +**接口设计说明:** + +  微网厅系统基于微信公众号平台,为用户提供便捷的水务服务。系统与微信平台、营收业务系统、发票服务、支付系统等多个外部系统进行集成,支持账户绑定、在线查询、移动缴费、电子发票、业务申请等全流程服务。 + +| 接口编号 | 接口名称 | 功能描述 | 调用方 | 接口协议 | 输入参数 | 输出结果 | +|---|---|---|---|---|---|---| +| IF-WECHAT-001 | 微信授权登录接口 | 通过微信OAuth2.0实现用户授权登录 | 微网厅系统 | HTTP/REST | 微信授权码、AppID、AppSecret | 用户OpenID、访问令牌、用户基本信息 | +| IF-WECHAT-002 | 微信支付接口 | 调用微信支付完成在线缴费 | 微网厅系统 | HTTP/REST | 订单信息、支付金额、用户OpenID | 预支付交易会话标识、支付结果 | +| IF-WECHAT-003 | 微信模板消息接口 | 推送缴费成功、账单提醒等消息 | 消息服务系统 | HTTP/REST | 模板ID、用户OpenID、消息数据 | 消息推送状态、消息ID | +| IF-WECHAT-004 | 微信JS-SDK接口 | 调用微信JS-SDK实现前端功能 | 微网厅前端 | HTTP/REST | 页面URL、时间戳、随机字符串 | JS-SDK配置信息、签名 | +| IF-WECHAT-005 | 客户信息查询接口 | 查询绑定客户的基本信息 | 微网厅系统 | HTTP/REST | 客户编号/手机号/OpenID | 客户详细信息、绑定状态 | +| IF-WECHAT-006 | 账单信息查询接口 | 查询客户账单和欠费信息 | 微网厅系统 | HTTP/REST | 客户编号、查询月份范围 | 账单明细、欠费金额、阶梯用量 | +| IF-WECHAT-007 | 缴费处理接口 | 处理微信端发起的缴费业务 | 微网厅系统 | HTTP/REST | 客户编号、缴费金额、支付方式 | 缴费订单号、支付状态、发票信息 | +| IF-WECHAT-008 | 业务申请提交接口 | 提交报装、过户等业务申请 | 微网厅系统 | HTTP/REST | 申请类型、客户资料、申请材料 | 申请单号、预审结果、处理时限 | +| IF-WECHAT-009 | 电子发票申请接口 | 申请开具电子发票 | 微网厅系统 | HTTP/REST | 缴费订单号、发票抬头信息 | 电子发票PDF、发票代码和号码 | +| IF-WECHAT-010 | 营业网点查询接口 | 查询就近营业网点信息 | 微网厅系统 | HTTP/REST | 地理位置坐标、搜索半径 | 网点列表、营业时间、联系方式 | +| IF-WECHAT-011 | 账户绑定验证接口 | 验证客户身份并绑定微信账户 | 微网厅系统 | HTTP/REST | 客户编号、身份证号、手机号码 | 绑定验证结果、绑定关系ID | +| IF-WECHAT-012 | 用水历史查询接口 | 查询客户用水历史记录 | 微网厅系统 | HTTP/REST | 客户编号、查询时间段 | 用水量明细、趋势分析数据 | + +### 设计方案概述 + +  采用微信公众号H5页面开发模式,前端使用响应式Web技术,后端基于Spring Boot微服务架构。通过微信OAuth2.0实现用户授权,通过唯一标识实现账户绑定,确保数据安全和用户体验。 + +## 子系统架构设计 + + +  微网厅系统基于微信公众号生态,采用前后端分离架构。前端采用Vue.js框架开发响应式H5页面,适配微信浏览器环境;后端采用Spring Boot微服务架构,通过API Gateway统一接口管理。 + + +```mermaid +graph TB + subgraph "微信平台" + WeChat[微信公众号] + WeMsg[微信消息] + end + + subgraph "微网厅系统" + Frontend[前端H5页面] + Backend[后端服务] + Cache[缓存层] + end + + subgraph "营收业务系统" + Customer[客户管理] + Billing[账务处理] + Payment[收费管理] + Service[客户服务] + end + + WeChat --> Frontend + Frontend --> Backend + Backend --> Cache + Backend --> Customer + Backend --> Billing + Backend --> Payment + Backend --> Service + Backend -.->|支付调用| PAY_SYS[支付与结算(SYS-009)] + Backend --> WeMsg +``` + +## 模块定义 + +### 模块列表 + +| 模块编号 | 模块名称 | 功能描述 | 开发方式 | +|---------|----------|----------|------------| +| WECHAT-001 | 账户绑定管理 | 微信授权、账户绑定与解绑、多账户管理 | 自行开发 | +| WECHAT-002 | 信息查询服务 | 账单查询、用水历史、缴费记录、停水公告 | 自行开发 | +| WECHAT-003 | 在线缴费服务 | 快捷缴费、充值服务、多种支付方式 | 自行开发 | +| WECHAT-004 | 电子发票服务 | 发票查看、发票推送、电子发票管理 | 自行开发 | +| WECHAT-005 | 营业网点服务 | 网点查询、地图导航、距离计算 | 自行开发 | +| WECHAT-006 | 业务办理服务 | 联系方式变更、开票方式变更、更名业务、过户业务、一户多人口申请、水价变更、低保申请、换表申请、自主抄表 | 自行开发 | +| WECHAT-007 | 账户流水 | 账户历史缴费流水查询与导出 | 自行开发 | +| WECHAT-008 | 账号与机构管理 | 切换机构、添加/解绑客户、设置默认客户、客户详情 | 自行开发 | + +### 模块间关系 + +```mermaid +graph TD + subgraph "微网厅系统模块关系" + A[WECHAT-001
账户绑定管理] + B[WECHAT-002
信息查询服务] + C[WECHAT-003
在线缴费服务] + D[WECHAT-004
电子发票服务] + E[WECHAT-005
营业网点服务] + F[WECHAT-006
业务办理服务] + G[WECHAT-007
账户流水] + H[WECHAT-008
账号与机构管理] + end + + A -->|身份验证| B + A -->|授权支付| C + A -->|授权开票| D + A -->|位置服务| E + A -->|业务授权| F + A -->|流水授权| G + A -->|账号管理| H + + B -.->|查询后开票| D + C -.->|支付后开票| D + F -.->|业务查询| B + F -.->|业务缴费| C + + %% 样式定义 + classDef coreService fill:#e3f2fd,stroke:#1976d2,stroke-width:2px + classDef supportService fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px + classDef bindingModule fill:#fff3e0,stroke:#f57c00,stroke-width:2px + + class A bindingModule + class B,C,D,F coreService + class E,G,H supportService +``` + +### 模块描述 + +#### WECHAT-001: 账户绑定管理 + +- 微信授权与快捷登录 +- 手机号自动绑定 +- 客户编号手工绑定 +- 多客户绑定管理 +- 默认客户设置 + +#### WECHAT-002: 信息查询服务 + +- 首页基本信息展示 +- 客户详细信息查看 +- 历史账单查询(近12个月) +- 用水分析曲线图 +- 客户切换功能 + +#### WECHAT-003: 在线缴费服务 + +- 快捷缴费功能 +- 充值缴费服务 +- 微信支付集成 +- 缴费确认页面 +- 缴费结果通知 + +#### WECHAT-004: 电子发票服务 + +- 电子发票查看 +- 发票邮箱推送 +- 发票图片保存 +- 发票开具申请 + +#### WECHAT-005: 营业网点服务 + +- 营业网点列表展示 +- 地图模式展示 +- 距离排序显示 +- 网点详细信息 + +#### WECHAT-006: 业务办理服务 + +- 联系方式变更 +- 开票方式变更 +- 更名业务 +- 过户业务 +- 一户多人口申请 +- 水价变更 +- 低保申请 +- 换表申请 +- 自主抄表 +- 附件上传(最多9张) +- 业务进度查询 + +#### WECHAT-007: 账户流水 + +- 历史缴费流水查询 +- 缴费汇总情况 +- 流水详细信息展示 + +#### WECHAT-008: 账号与机构管理 + +- 用水机构切换 +- 添加绑定客户 +- 解除绑定客户 +- 设置默认客户 +- 查看客户详情 + +**业务办理流程**: + +```mermaid +flowchart TD + Start([用户发起业务申请]) --> Select[选择业务类型] + Select --> Fill[填写申请信息] + Fill --> Upload[上传相关材料] + Upload --> Submit[提交申请] + Submit --> Review[系统审核] + Review --> Approve{审核结果} + Approve -->|通过| Process[业务处理] + Approve -->|退回| Modify[修改申请] + Modify --> Submit + Process --> Complete[办理完成] + Complete --> Notify[结果通知] + Notify --> End([结束]) +``` + + + +# 子系统5设计: 工单管理系统 + +## 任务概述 + +  工单管理系统(SYS-005)负责全业务工单统一受理、创建、派发、处理、验收与归档,覆盖营收、表务、报装、客户服务等场景,提供统一流程引擎与监控预警能力。 + +## 设计概述 + +### 总体约束 + +- 流程统一:所有工单遵循统一的生命周期与态状态机 +- 实时可观测:状态监控、超时预警、绩效统计 +- 可扩展:支持新增工单类型与流程编排 + +### 子系统外部接口 + +  工单管理系统作为统一的工单处理平台,接收来自营收、表务、报装、微网厅、APP等各业务系统的工单需求,实现工单全生命周期管理。系统提供标准化的工单接口,支持多种工单类型的创建、派发、处理、跟踪全流程管理。 + +| 接口编号 | 接口名称 | 功能描述 | 调用方 | 接口协议 | 输入参数 | 输出结果 | +|---|---|---|---|---|---|---| +| IF-WO-001 | 工单创建接口 | 创建各类业务工单 | 营收/表务/报装/微网厅/APP | HTTP/REST | 工单类型、客户信息、问题描述、紧急程度 | 工单编号、预计处理时间、派发状态 | +| IF-WO-002 | 工单派发接口 | 向处理人/APP派发任务 | 工单管理系统 | HTTP/REST | 工单ID、处理人员、预期完成时间 | 派发结果、接收确认状态 | +| IF-WO-003 | 工单回填接口 | 回填处理结果与附件 | APP/各业务系统 | HTTP/REST | 工单ID、处理结果、现场图片、完成时间 | 回填状态、审核结果、客户满意度 | +| IF-WO-004 | 工单查询接口 | 查询工单状态和处理轨迹 | 各业务系统/客户端 | HTTP/REST | 工单编号/客户编号、查询条件 | 工单状态、处理进度、历史轨迹 | +| IF-WO-005 | 工单统计接口 | 工单处理绩效统计分析 | 管理后台 | HTTP/REST | 统计维度、时间范围、部门筛选 | 统计报表、效率分析、排名数据 | +| IF-WO-006 | 工单预警接口 | 超时工单监控预警 | 监控系统 | HTTP/REST | 预警规则、时间阈值 | 预警工单列表、通知配置 | + +### 设计方案概述 + +  架构采用"工单中心 + 流程编排 + 监控预警 + 绩效统计"的分层设计,提供统一API网关对接各业务系统,并通过可配置流程实现多类型工单的快速上线。 + +## 子系统架构设计 + +  工单管理系统采用微服务分层架构,通过统一工单中心集中管理各类业务工单,配置化流程引擎支持不同工单类型的个性化流转,实时监控预警确保服务质量,绩效统计提供数据分析支撑。 + + +```mermaid +graph TB + subgraph "工单管理系统" + WO_CENTER[统一工单中心] + FLOW[流程引擎] + MON[监控预警] + STAT[绩效统计] + end + + subgraph "协作系统" + REV[营收业务系统] + METER[表务管理系统] + INSTALL[报装业务系统] + APP[手机抄表APP] + WECHAT[微网厅] + end + + REV -.->|业务异常/申请| WO_CENTER + METER -.->|换表申请| WO_CENTER + INSTALL -.->|报装派单| WO_CENTER + WECHAT -.->|客户服务申请| WO_CENTER + APP -.->|问题上报/结果回填| WO_CENTER + + WO_CENTER -.-> FLOW + WO_CENTER -.-> MON + WO_CENTER -.-> STAT + WO_CENTER -.->|派发任务| APP +``` + +## 模块定义 + +### 模块列表 + +| 模块编号 | 模块名称 | 功能描述 | 开发方式 | +|---|---|---|---| +| WORK-001 | 工单中心 | 统一受理、路由、分派、跟踪 | 自行开发 | +| WORK-002 | 流程引擎 | 节点编排、条件路由、并行网关 | 自行开发 | +| WORK-003 | 监控预警 | 超时/积压/异常预警、看板 | 自行开发 | +| WORK-004 | 绩效统计 | 人员/环节时长、SLA达成率 | 自行开发 | + +### 模块间关系 + +```mermaid +graph TD + subgraph "工单管理系统模块关系" + A[WORK-001
工单中心] + B[WORK-002
流程引擎] + C[WORK-003
监控预警] + D[WORK-004
绩效统计] + end + + A -->|流程调度| B + A -->|状态监控| C + A -->|数据统计| D + B -.->|流程状态| C + C -.->|监控数据| D + + %% 样式定义 + classDef coreModule fill:#e3f2fd,stroke:#1976d2,stroke-width:2px + classDef processModule fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px + classDef monitorModule fill:#fff3e0,stroke:#f57c00,stroke-width:2px + + class A coreModule + class B processModule + class C,D monitorModule +``` + +### 模块描述 + +#### WORK-001: 工单中心 + +- 统一工单入口与受理管理 +- 工单分类与优先级策略配置 +- 智能路由与自动分派机制 +- 工单全生命周期状态跟踪 + +#### WORK-002: 流程引擎 + +- 可视化流程编排与配置 +- 条件路由与并行互斥网关 +- 子流程支持与流程嵌套 +- 回退重审与流程回滚机制 + +#### WORK-003: 监控预警 + +- 实时工单状态看板展示 +- 超时积压智能预警 +- 异常工单自动拦截识别 +- 多渠道预警通知推送 + +#### WORK-004: 绩效统计 + +- 处理人员时长统计分析 +- 各环节效率达成率统计 +- SLA达成率考核指标 +- 绩效报表自动生成导出 + + + +# 子系统6设计: 表务管理系统 + +## 任务概述 + +  表务管理系统(SYS-006)聚焦设备档案和表务全生命周期管理,面向换表等业务提供资源保障。 + +## 设计概述 + +### 总体约束 + +- 数据规范化:设备参数标准化,避免冗余与不一致 +- 状态可追溯:设备全生命周期状态流转与变更留痕 +- 库存实时性:库存数据实时同步,支持多仓库管理 + +### 子系统外部接口 + +  表务管理系统负责水表资产的全生命周期管理,包括基础参数配置、仓库库存管理、设备档案管理。系统与工单管理、营收业务等系统协作,支持水表领用、更换、维修、报废等全流程作业,确保水表资产的准确管理和有效利用。 + +| 接口编号 | 接口名称 | 功能描述 | 调用方 | 接口协议 | 输入参数 | 输出结果 | +|---|---|---|---|---|---|---| +| IF-METER-001 | 库存查询接口 | 查询仓库库存状态和预警信息 | 工单/营收/报装系统 | HTTP/REST | 仓库编号、水表型号、库存状态 | 库存明细、预警状态、可用数量 | +| IF-METER-002 | 领用出库接口 | 支持换表/施工水表领用出库 | 工单管理系统 | HTTP/REST | 领用单号、水表型号、领用数量、领用人 | 出库状态、库存余量、领用凭证 | +| IF-METER-003 | 档案查询接口 | 查询水表设备档案信息 | 营收/工单/报装系统 | HTTP/REST | 水表编号、客户编号、查询类型 | 设备档案、安装历史、维修记录 | +| IF-METER-004 | 集抄数据接收接口 | 接收远传抄表、异常告警并同步状态 | 物联网平台 | HTTP/REST | 设备标识、采集时间、读数值、告警信息 | 接收结果、校验状态、异常标记 | +| IF-METER-005 | 资产调拨接口 | 仓库间水表调拨转移 | 表务管理系统 | HTTP/REST | 调出仓库、调入仓库、调拨清单 | 调拨状态、库存变更结果 | +| IF-METER-006 | 盘点核实接口 | 定期盘点和库存核实 | 表务管理系统 | HTTP/REST | 盘点计划、盘点范围、盘点人员 | 盘点结果、差异分析、调整建议 | + +### 设计方案概述 + +  以"基础参数-仓库库存-设备档案"三层模型实现资产全生命周期管理;通过与工单系统联动完成领用/回填闭环,支持库存预警与追溯。 + +## 子系统架构设计 + +  表务管理系统采用分层数据架构,通过基础参数管理建立水表标准规范,通过仓库库存管理实现设备资源调配,通过设备档案管理实现全生命周期跟踪。系统与工单管理系统深度集成,形成"需求-领用-安装-回收"的完整闭环。 +  周转率、维修频次等统计分析 + +```mermaid +graph TB + subgraph "表务管理系统" + BASE[基础参数] + WH[仓库与库存] + DOC[设备档案] + end + + WO[工单系统] -.->|领用/回填| WH + REV[营收系统] -.->|档案/库存状态| DOC +``` + +## 模块定义 + +### 模块列表 + +| 模块编号 | 模块名称 | 功能描述 | 开发方式 | +|---|---|---|---| +| METER-001 | 表务基础管理 | 厂家/型号/口径/量程等基础参数 | 自行开发 | +| METER-002 | 仓库与库存管理 | 入库/出库/盘点/调拨/预警 | 自行开发 | +| METER-003 | 设备档案管理 | 档案建档/状态管理/追溯 | 自行开发 | + +### 模块间关系 + +```mermaid +graph TD + subgraph "表务管理系统模块关系" + A[METER-001
表务基础管理] + B[METER-002
仓库与库存管理] + C[METER-003
设备档案管理] + end + + A -->|基础参数| B + B -->|库存状态| C + C -.->|规格验证| A + + %% 样式定义 + classDef baseModule fill:#e3f2fd,stroke:#1976d2,stroke-width:2px + classDef warehouseModule fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px + classDef docModule fill:#fff3e0,stroke:#f57c00,stroke-width:2px + + class A baseModule + class B warehouseModule + class C docModule +``` + +### 模块描述 + +#### METER-001: 表务基础管理 + +- 厂家型号口径量程等基础参数标准化 +- 检定周期与技术规范管理 +- 设备分类与属性字典维护 +- 基础参数验证与规范校验 + +#### METER-002: 仓库与库存管理 + +- 入库出库盘点调拨全流程管理 +- 库存预警与安全库存监控 +- 与工单系统联动领用回填 +- 多仓库统一管理与库存同步 + +#### METER-003: 设备档案管理 + +- 唯一设备电子档案建立 +- 设备全生命周期状态流转 +- 批次管理与质检记录追溯 +- 档案查询与历史轨迹记录 + + + +# 子系统7设计: 报装业务系统 + +## 任务概述 + +  报装业务系统(SYS-007)覆盖从申请、踏勘、设计、施工到验收通水的全流程,支持调用泛微进行合同签订和电子签章,并与工单系统协作完成现场派工与过程留痕。 + +## 设计概述 + +### 设计方案概述 + +- 采用阶段性里程碑管控(申请-踏勘-施工-验收-通水),以工单驱动现场作业,形成资料全流程留痕与竣工归档。 +- 资料签章对接:与外部CA电子签章系统对接,完成报装申请材料、施工/验收文书的签署、验章与存证,签章回执异步回传。 + +### 子系统外部接口 + +  报装业务系统负责新用户报装全流程管理,从申请受理到通水验收的全生命周期业务处理。系统与微网厅、营收系统、工单管理、表务管理、CA电子签章等外部系统协作,实现报装业务的规范化、数字化管理和全流程追溯。 + +| 接口编号 | 接口名称 | 功能描述 | 调用方 | 接口协议 | 输入参数 | 输出结果 | +|---|---|---|---|---|---|---| +| IF-INST-001 | 报装申请接口 | 提交报装申请信息与材料 | 微网厅/营收系统 | HTTP/REST | 申请人信息、用水地址、申请材料、联系方式 | 申请单号、预审结果、处理时限 | +| IF-INST-002 | 踏勘派工接口 | 现场踏勘任务派发 | 工单管理系统 | HTTP/REST | 报装单号、踏勘要求、预约时间 | 派工结果、踏勘人员、预计完成时间 | +| IF-INST-003 | 签章接口 | 调用CA系统进行电子签章 | CA电子签章系统 | HTTP/REST | 合同文档、签章类型、签章方信息 | 签章状态、签章文档、存证信息 | +| IF-INST-004 | 签章回执接口 | 接收CA系统签章完成回执 | CA电子签章系统 | HTTP/REST | 签章任务ID、签章结果、时间戳 | 接收确认、存档状态 | +| IF-INST-005 | 报装归档接口 | 归档申请、合同、验收与签章回执资料 | 报装系统 | HTTP/REST | 报装单号、资料清单、签章回执、验收文档 | 归档状态、档案编号、存储位置 | +| IF-INST-006 | 验收通水接口 | 验收合格并开通供水 | 营收业务系统 | HTTP/REST | 报装单号、验收结果、水表信息 | 开户结果、客户编号、通水状态 | +| IF-INST-007 | 档案归档接口 | 竣工档案归档管理 | 档案管理系统 | HTTP/REST | 报装单号、竣工资料、验收文档 | 归档状态、档案编号、存储位置 | + +### 子系统架构设计 + +  报装业务系统采用阶段式流程架构,将复杂的报装业务分解为申请受理、现场踏勘、施工管理、验收通水四个核心阶段,每个阶段具有明确的输入输出和验收标准。系统与CA电子签章系统深度集成,实现合同文档的电子化签署和存证。 + + +```mermaid +graph TB + subgraph "报装业务系统" + APPLY[申请受理] + SURVEY[现场踏勘] + BUILD[施工管理] + ACCEPT[验收通水] + ARCH[资料归档] + end + + WECHAT[微网厅] -.->|报装申请| APPLY + APPLY -.-> SURVEY -.-> BUILD -.-> ACCEPT -.-> ARCH + INST_WO[工单系统] -.->|派工/回填| SURVEY + INST_WO -.->|派工/回填| BUILD + CA[CA电子签章] + ARCH -.->|签章/验章/存证| CA +``` + +## 模块定义 + +### 模块列表 + +| 模块编号 | 模块名称 | 功能描述 | 开发方式 | +|---|---|---|---| +| INST-001 | 报装流程管理 | 端到端阶段流转,里程碑控制 | 自行开发 | +| INST-002 | 工程管理 | 进度/资源/质量/安全管理 | 自行开发 | +| INST-003 | 档案管理 | 资料归档、过程留痕、竣工档案 | 自行开发 | + +### 模块间关系 + +```mermaid +graph TD + subgraph "报装业务系统模块关系" + A[INST-001
报装流程管理] + B[INST-002
工程管理] + C[INST-003
档案管理] + end + + A -->|流程驱动| B + B -->|工程资料| C + C -.->|档案反馈| A + + %% 样式定义 + classDef flowModule fill:#e3f2fd,stroke:#1976d2,stroke-width:2px + classDef projectModule fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px + classDef archiveModule fill:#fff3e0,stroke:#f57c00,stroke-width:2px + + class A flowModule + class B projectModule + class C archiveModule +``` + +### 模块描述 + +#### INST-001: 报装流程管理 + +**功能概述:** + +  报装流程管理模块负责端到端的报装业务流程控制,涵盖从申请受理到资料归档的完整生命周期管理。 + +**核心功能:** + +1. **申请受理** + - 申请类型识别(单位/个人、新建户表/总表/旧城改造) + - 工程信息录入(工程名称、地址、经办人信息) + - 资料上传管理(身份证、营业执照、房产证等) + - 工程编号自动生成 + - 申请暂存与提交控制 + +2. **踏勘管理** + - 现场勘查任务分派 + - 勘查结果录入(用水性质、水表口径、数量、预算总价) + - 用户信息批量录入 + - 设计图纸管理 + - 勘查意见与审核 + +3. **审批流转** + - 多级审批流程控制 + - 审批意见记录 + - 流程回退机制 + - 审批状态跟踪 + +4. **合同与缴费** + - OA系统合同审批对接 + - 分批缴费支持 + - 收据打印管理 + - 合同签订确认 + +#### INST-002: 工程管理 + +**功能概述:** + +  工程管理模块负责报装工程的施工全过程管理,包括派工、安装、验收等关键环节的控制与监督。 + +**核心功能:** + +1. **工程派工** + - 施工部门选择与派遣 + - 派工任务生成 + - 施工人员分配 + - 与SYS-005工单系统协作 + +2. **工程安装** + - 仓库领表管理(与表务系统对接) + - 现场安装信息录入 + - 水表信息关联(条形码、钢印号、厂家、型号) + - 施工过程记录(施工负责人、时间、描述) + - 安装质量控制 + +3. **工程验收** + - 联合竣工验收管理 + - 验收人员分配(抄表员、工程部门) + - 验收结果录入(合格/不合格) + - 验收情况详细记录 + - 表号等关键信息确认 + +4. **进度监控** + - 工程进度实时跟踪 + - 关键节点里程碑控制 + - 延期预警与通知 + - 施工安全管理 + +#### INST-003: 档案管理 + +**功能概述:** + +  档案管理模块负责报装业务全过程的资料归档、电子签章和竣工档案管理,确保业务合规性和可追溯性。 + +**核心功能:** + +1. **资料归档** + - 报装申请资料电子化存储 + - 踏勘设计图纸归档 + - 施工安装记录归档 + - 验收文档归档 + - 合同资料归档 + +2. **电子签章** + - CA电子签章系统对接 + - 申请材料电子签署 + - 施工验收文书签章 + - 签章验证与存证 + - 签章回执异步处理 + +3. **竣工档案** + - 竣工资料整理 + - 档案完整性检查 + - 移交确认管理 + - 与营收系统立户对接 + - 档案查询与检索 + +4. **材料审核** + - 报装材料核对 + - 资料完整性验证 + - 审核意见记录 + - 补充资料管理 + + + +# 子系统8设计: 发票服务子系统 + +## 任务概述 + +  发票服务子系统(SYS-008)定位为"基础服务层"的统一开票能力中心,通过统一开票网关与供应商适配器屏蔽不同厂商差异,当前优先对接"航天信息",预留"博思"等供应商接入能力。 + +## 设计概述 + +### 总体约束 + +- 统一入口:提供统一的开票、作废/红冲、查询能力 +- 供应商无关:采用适配器模式屏蔽供应商差异 +- 合规可靠:签章/存证、回执落库、审计留痕 + +### 设计方案概述 + +- 架构采用"统一开票网关 + 供应商适配器 + 回执处理/存证"的三层模型;对上通过REST接口供营收业务与微网厅调用,对下通过供应商SDK/HTTP对接航天(现阶段)与其他供应商。 + +### 子系统外部接口 + +  发票服务子系统作为基础服务层的统一开票能力中心,为上游业务系统提供标准化的发票服务。系统采用适配器模式,支持多供应商接入,当前优先对接航天信息,预留博思等其他供应商接入能力,确保发票业务的合规性和可扩展性。 + +| 接口编号 | 接口名称 | 功能描述 | 调用方 | 接口协议 | 输入参数 | 输出结果 | +|---|---|---|---|---|---|---| +| IF-INV-001 | 统一开票接口 | 统一受理电子发票开具请求 | 营收业务系统/微网厅 | HTTP/REST | 开票信息、购买方信息、商品明细、税额 | 发票申请ID、开票状态、预计完成时间 | +| IF-INV-002 | 作废红冲接口 | 发票作废和红字发票处理 | 营收业务系统 | HTTP/REST | 原发票号码、作废/红冲原因、操作类型 | 处理结果、新发票信息、作废状态 | +| IF-INV-003 | 发票查询接口 | 查询发票状态和下载链接 | 营收系统/微网厅/客户端 | HTTP/REST | 发票代码、发票号码、查询类型 | 发票状态、PDF下载链接、发票详情 | +| IF-INV-004 | 回执推送接口 | 接收供应商发票处理回执 | 航天信息/博思等供应商 | HTTP/REST | 回执ID、处理结果、发票文件、时间戳 | 接收确认、存储状态、通知结果 | +| IF-INV-005 | 供应商切换接口 | 供应商服务切换和负载均衡 | 发票服务网关 | HTTP/REST | 供应商标识、切换原因、备用方案 | 切换状态、新供应商信息、影响评估 | +| IF-INV-006 | 存证签章接口 | 发票电子存证和数字签章 | 存证签章模块 | HTTP/REST | 发票文件、签章类型、存证要求 | 存证凭证、签章状态、法律效力确认 | + +## 子系统架构设计 + +  发票服务子系统采用统一网关和适配器模式架构,通过统一开票网关屏蔽不同供应商的接口差异,供应商适配器实现具体厂商的协议转换,回执处理模块确保业务闭环,存证签章模块保障发票的法律效力。 + +```mermaid +graph TB + subgraph "发票服务子系统" + GW[统一开票网关] + ADP[供应商适配器] + RCPT[回执处理] + EVID[存证与签章] + end + + subgraph "上游系统" + REV[营收业务系统] + WECHAT[微网厅] + end + + subgraph "供应商" + HT[航天信息] + BOS[博思/预留] + end + + REV -.->|INV-001/002/003| GW + WECHAT -.->|发票查询/下载| GW + GW --> ADP --> HT + ADP -.-> BOS + HT -.-> RCPT --> EVID +``` + +## 模块定义 + +### 模块列表 + +| 模块编号 | 模块名称 | 功能描述 | 开发方式 | +|---|---|---|---| +| INV-001 | 统一开票网关 | 统一鉴权、参数校验、基础路由 | 自行开发 | +| INV-002 | 供应商适配器 | 航天/博思等供应商协议适配、签名加验签 | 自行开发 | +| INV-003 | 回执处理 | 回执解析、状态机、失败重试、告警通知 | 自行开发 | +| INV-004 | 存证与签章 | 发票PDF/JSON存证、签章与链接生成、合规审计 | 自行开发 | + +### 模块间关系 + +```mermaid +graph TD + subgraph "发票服务子系统模块关系" + A[INV-001
统一开票网关] + B[INV-002
供应商适配器] + C[INV-003
回执处理] + D[INV-004
存证与签章] + end + + A -->|请求路由| B + B -->|供应商回调| C + C -->|状态更新| D + C -.->|状态回馈| A + + %% 样式定义 + classDef gatewayModule fill:#e3f2fd,stroke:#1976d2,stroke-width:2px + classDef adapterModule fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px + classDef processModule fill:#fff3e0,stroke:#f57c00,stroke-width:2px + + class A gatewayModule + class B adapterModule + class C,D processModule +``` + +### 模块描述 + +#### INV-001: 统一开票网关 + +- 统一入口鉴权与参数校验 +- 开票请求幂等控制 +- 基础路由与负载分发 +- 供应商简单选择 + +#### INV-002: 供应商适配器 + +- 航天信息SDK/HTTP对接 +- 字段映射与签名验签 +- 错误码标准化转换 +- 博思等供应商扩展预留 + +#### INV-003: 回执处理 + +- 开票状态回填处理 +- 失败重试(指数退避策略) +- 超时监控与告警 +- 微网厅消息联动通知 + +#### INV-004: 存证与签章 + +- 发票PDF存储管理 +- 票根JSON数据保存 +- 数字签章与下载链接 +- 审计日志与合规留痕 + + + +# 子系统9设计: 支付与银行结算子系统 + +## 任务概述 + +  支付与银行结算子系统(SYS-009)统一承载聚合支付/退款、渠道适配(微信/支付宝/银联聚合)、支付回调验签入账,以及银行实时收费、代扣/托收签约解约、送盘/回盘/对账契约与安全加解密/签名,向上对营收/微网厅等系统提供标准化支付与结算能力。夜间批量代扣、完整回盘状态补偿、对账差异处理与结算确认当前仍按后续完善项管理。 + +## 设计概述 + +### 总体约束 + +- 多渠道聚合:统一接入微信/支付宝/银联聚合 +- 统一结算:统一维护批次、回盘、对账和差异语义,完整结算闭环按后续完善项推进 +- 安全合规:签名/验签、加解密、回调防重放、幂等 +- 高可用:基础重试补偿机制 + +### 设计方案概述 + +- 采用"统一支付与结算网关 + 渠道/银行适配器 + 回调处理 + 对账处理 + 加解密/签名"的分层;对上REST接口,对下渠道SDK/HTTP与银行HTTP/SFTP对接。 + +### 子系统外部接口(SYS-009) + +  支付与银行结算子系统作为统一的支付能力中心,为上游业务系统提供聚合支付、银行实时收费、代扣/托收签解约、退款处理、对账管理等支付结算服务。以下接口表表达的是正式设计目标边界,其中聚合支付、实时收费查询/缴费、代扣/托收签解约已具备较明确实现证据;`BankWithholding` 六条银行入口已形成最小实现态闭环,托收平行链路、对账和完整结算闭环仍按部分实现或后续完善项管理。 + +| 接口编号 | 接口名称 | 功能描述 | 调用方 | 接口协议 | 输入参数 | 输出结果 | +|---|---|---|---|---|---|---| +| IF-PAY-001 | 统一支付下单接口 | 统一处理各渠道支付下单请求 | 营收系统/微网厅 | HTTP/REST | 订单信息、支付方式、支付金额、用户标识 | 预支付订单号、支付参数、二维码 | +| IF-PAY-002 | 统一关单接口 | 订单关闭和撤销处理 | 营收系统/微网厅 | HTTP/REST | 订单号、关闭原因、操作类型 | 关单状态、退款信息、处理结果 | +| IF-PAY-003 | 统一退款接口 | 原路退款和部分退款处理 | 营收系统/微网厅 | HTTP/REST | 原订单号、退款金额、退款原因 | 退款单号、退款状态、预计到账时间 | +| IF-PAY-004 | 支付回调接口 | 接收渠道支付结果回调 | 微信/支付宝/银联 | HTTP/REST | 回调数据、签名、时间戳 | 处理确认、业务更新状态 | +| IF-PAY-005 | 批量代扣送盘接口 | 银行批量代扣文件发送 | 营收业务系统 | HTTP/REST/SFTP | 代扣清单、客户签约信息、扣款金额 | 送盘状态、批次号、预计处理时间(`BankWithholding` 已具备最小实现态闭环;真实文件通道联调仍待补证) | +| IF-PAY-006 | 批量代扣回盘接口 | 银行代扣结果回盘处理 | 银行系统 | HTTP/REST/SFTP | 回盘文件、处理结果、失败原因 | 解析结果、状态更新、异常处理(`BankWithholding` 已具备最小实现态闭环;真实文件解析与异常补偿仍待补证) | +| IF-PAY-007 | 批量对账文件接口 | 银行对账文件处理分析 | 银行系统/营收系统 | HTTP/REST/SFTP | 对账文件、对账日期、差异规则 | 对账结果、差异明细、调整建议(当前仍按部分实现或后续完善项管理) | +| IF-PAY-008 | 加解密签名接口 | 支付数据安全处理 | 内部模块调用 | HTTP/REST | 待处理数据、加密类型、签名算法 | 处理结果、安全凭证、验证状态 | + +## 子系统架构设计 + +  支付与银行结算子系统采用统一网关和多适配器架构,通过统一支付网关提供标准化支付接口,渠道适配器处理不同支付渠道的协议差异,银行适配器实现批量代扣和对账功能,回调处理确保支付结果的及时处理,加解密模块保障交易安全。 + +```mermaid +graph TB + subgraph "支付与银行结算子系统" + GW[统一支付与结算网关] + ADP_CH[渠道适配器] + ADP_BANK[银行适配器] + CB[回调处理] + RECON[对账处理] + CRYPTO[加解密/签名] + end + + subgraph "上游系统" + REV[营收业务系统] + WECHAT[微网厅] + end + + subgraph "外部机构" + WX[微信] + ALI[支付宝] + UPG[银联聚合] + BANK[银行] + end + + REV -.->|PAY-001/002/003/005/006/007| GW + WECHAT -.->|下单/查询| GW + GW --> ADP_CH --> WX + ADP_CH --> ALI + ADP_CH --> UPG + GW --> ADP_BANK --> BANK + WX -.-> CB + ALI -.-> CB + UPG -.-> CB + ADP_BANK -.-> RECON + GW -.-> CRYPTO +``` + +## 模块定义 + +### 模块列表 + +| 模块编号 | 模块名称 | 功能描述 | 开发方式 | +|---|---|---|---| +| PAY-001 | 统一支付与结算网关 | 鉴权、参数校验、幂等、基础路由 | 自行开发 | +| PAY-002 | 渠道适配器 | 渠道参数映射、签名/验签、错误码转换 | 自行开发 | +| PAY-003 | 银行适配器 | 协议/文件规范适配、编码转换、SFTP/HTTP | 自行开发 | +| PAY-004 | 回调处理 | 回调验签、订单入账、补偿重试 | 自行开发 | +| PAY-005 | 批量对账处理 | 对账接收/解析、差错处理、账务回填、报告 | 自行开发 | +| PAY-006 | 加解密/签名 | SM2/SM4/3DES等算法、密钥管理 | 自行开发 | + +### 模块间关系 + +```mermaid +graph TD + subgraph "支付与银行结算子系统模块关系" + A[PAY-001
统一支付与结算网关] + B[PAY-002
渠道适配器] + C[PAY-003
银行适配器] + D[PAY-004
回调处理] + E[PAY-005
批量对账处理] + F[PAY-006
加解密/签名] + end + + A -->|渠道路由| B + A -->|银行对接| C + B -->|支付回调| D + C -->|对账数据| E + A -->|安全加密| F + + B -.->|状态反馈| A + C -.->|状态反馈| A + D -.->|结果通知| A + E -.->|对账结果| A + F -.->|密钥服务| A + + %% 样式定义 + classDef gatewayModule fill:#e3f2fd,stroke:#1976d2,stroke-width:2px + classDef adapterModule fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px + classDef processModule fill:#fff3e0,stroke:#f57c00,stroke-width:2px + classDef securityModule fill:#e8f5e8,stroke:#388e3c,stroke-width:2px + + class A gatewayModule + class B,C adapterModule + class D,E processModule + class F securityModule +``` + +### 模块描述 + +#### PAY-001: 统一支付/代扣网关 + +- 统一入口鉴权与字段校验 +- 基础保护机制 +- 幂等键与重放攻击保护 +- 简单路由与流量分发 + +#### PAY-002: 渠道适配器 + +- 微信/支付宝/银联参数适配 +- 签名规范统一处理 +- 错误码标准化转换 +- 渠道响应格式统一 + +#### PAY-003: 银行适配器 + +- 银行与第三方支付协议对接 +- 签名验签与编码转换(GBK/UTF-8) +- SFTP/HTTP文件交互处理 +- 错误码映射与异常处理 + +#### PAY-004: 回调处理 + +- 支付回调验签确认 +- 订单状态同步对齐 +- 失败重试与异常告警 +- 回调幂等与去重处理 + +#### PAY-005: 对账处理 + +- 银行对账文件定时拉取解析 +- 差异识别与异常记录 +- 冲正/补记建议生成 +- 对账报告与追踪链路告警 +- 当前阶段按目标能力保留正式设计口径,不直接表述为已形成完整闭环 + +#### PAY-006: 加解密/签名 + +- 国密/商密算法支持 +- 密钥管理与定期轮换 +- 数据安全传输保障 + + + +# 子系统10设计: 消息服务子系统 + +## 任务概述 + +  消息服务子系统(SYS-010)负责统一消息推送、接收与处理,为各业务子系统提供消息通知服务。 + +**设计目标:** + +- 实现消息的统一推送与接收 +- 支持多种消息格式和推送方式 +- 确保消息的及时性和可靠性 + +**功能范围:** + +- **消息推送**:根据业务需求,向不同用户发送消息通知 +- **消息接收**:接收来自各业务系统的消息请求 +- **消息处理**:处理消息通知,生成响应结果 + +## 设计概述 + +### 总体约束 + +**技术约束:** + +- 基于消息队列技术实现消息的异步处理 +- 支持多种消息格式(如JSON、XML等) +- 实现消息的可靠传输和幂等处理 + +**性能约束:** + +- 支持高并发消息处理 +- 消息处理响应时间≤1秒 +- 消息队列容量≥100万条 + +**安全约束:** + +- 消息加密存储 +- 消息传输安全 +- 消息处理日志记录 + +### 子系统外部接口 + +  消息服务子系统作为统一的消息通知中心,为各业务系统提供多渠道消息推送能力。系统支持短信、邮件、站内信等多种消息渠道,与外部系统(OA、智水擎、水投数科APP)对接,实现消息的统一管理和分发。 + +| 接口编号 | 接口名称 | 功能描述 | 调用方 | 接口协议 | 输入参数 | 输出结果 | +|---|---|---|---|---|---|---| +| IF-MSG-001 | 短信发送接口 | 发送短信通知消息 | 营收/微网厅/工单系统 | HTTP/REST | 手机号、消息内容、模板ID、发送时间 | 发送状态、消息ID、预计到达时间 | +| IF-MSG-002 | 邮件发送接口 | 发送邮件通知消息 | 营收/工单/报装系统 | HTTP/REST | 邮箱地址、邮件主题、邮件内容、附件 | 发送状态、邮件ID、送达确认 | +| IF-MSG-003 | 站内信接口 | 发送系统站内消息 | 各业务系统 | HTTP/REST | 用户ID、消息标题、消息内容、消息类型 | 发送结果、消息状态、已读状态 | +| IF-MSG-004 | 微信消息推送接口 | 发送微信模板消息 | 微网厅系统 | HTTP/REST | 用户OpenID、模板ID、模板数据 | 推送状态、消息ID、送达状态 | +| IF-MSG-005 | 外部系统对接接口 | 对接OA/智水擎等外部系统 | OA系统/智水擎/水投数科APP | HTTP/REST | 系统标识、消息类型、接收用户、消息内容 | 对接状态、消息分发结果 | +| IF-MSG-006 | 固定模板管理接口 | 管理消息固定模板 | 系统管理员 | HTTP/REST | 模板类型、模板内容、适用场景 | 模板ID、保存状态、生效时间 | + +### 设计方案概述 + +**架构设计:** + +  消息服务子系统采用消息队列技术实现消息的异步处理。通过RabbitMQ实现消息的可靠传输和幂等处理。 + +**技术选型:** + +- **消息队列**:RabbitMQ +- **消息格式**:JSON +- **消息加密**:AES-256 +- **消息传输**:HTTPS + +## 子系统架构设计 + +  消息服务子系统采用消息中心架构模式,通过统一消息网关接收各业务系统的消息发送请求,通过渠道适配器实现不同消息渠道的协议转换,固定模板管理确保消息内容的规范性,外部系统对接实现与OA、智水擎等系统的消息互通。 + +```mermaid +graph TB + subgraph "消息服务子系统" + PUB[消息推送] + SUB[消息接收] + MQ[RabbitMQ] + end + + PUB --> MQ + SUB --> MQ +``` + +## 模块定义 + +### 模块列表 + +| 模块编号 | 模块名称 | 功能描述 | 开发方式 | +|---|---|---|---| +| MSG-001 | 消息网关模块 | 统一接入、鉴权、路由、幂等控制 | 自行开发 | +| MSG-002 | 短信服务模块 | 短信发送、回执处理、失败重试、供应商适配 | 自行开发 | +| MSG-003 | 邮件服务模块 | 邮件发送、附件管理、批量发送、回执处理 | 自行开发 | +| MSG-004 | 站内信模块 | 站内信管理、用户消息推送、已读状态跟踪 | 自行开发 | +| MSG-005 | 微信通知模块 | 微信模板消息、公众号推送通知 | 自行开发 | +| MSG-006 | 模板管理模块 | 消息模板管理、固定模板维护 | 自行开发 | +| MSG-007 | 外部系统适配模块 | 对接OA、智水擎、水投数科app等数科系统 | 自行开发 | + +### 模块间关系 + +```mermaid +graph TD + subgraph "消息服务子系统模块关系" + A[MSG-001
消息网关模块] + B[MSG-002
短信服务模块] + C[MSG-003
邮件服务模块] + D[MSG-004
站内信模块] + E[MSG-005
微信通知模块] + F[MSG-006
模板管理模块] + G[MSG-007
外部系统适配模块] + end + + %% 核心流程 + A -->|短信路由| B + A -->|邮件路由| C + A -->|站内信路由| D + A -->|微信路由| E + A -->|外部系统路由| G + + %% 模板服务 + F -->|短信模板| B + F -->|邮件模板| C + F -->|站内信模板| D + F -->|微信模板| E + F -->|外部模板| G + + %% 回执反馈 + B -.->|短信回执| A + C -.->|邮件回执| A + D -.->|已读状态| A + E -.->|微信回执| A + G -.->|外部回执| A + + %% 样式定义 + classDef gatewayModule fill:#e3f2fd,stroke:#1976d2,stroke-width:3px + classDef channelModule fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px + classDef templateModule fill:#fff3e0,stroke:#f57c00,stroke-width:2px + classDef externalModule fill:#e8f5e8,stroke:#388e3c,stroke-width:2px + + class A gatewayModule + class B,C,D,E channelModule + class F templateModule + class G externalModule +``` + +### 模块描述 + +#### MSG-001: 消息网关模块 + +- 统一消息接入与鉴权 +- 简单路由与负载均衡 +- 基础保护机制 +- 幂等控制与防重复发送 + +#### MSG-002: 短信服务模块 + +- 短信发送与供应商适配 +- 回执状态处理与确认 +- 失败重试与补偿机制 +- 短信固定内容管理 + +#### MSG-003: 邮件服务模块 + +- 邮件发送与附件管理 +- 批量邮件处理能力 +- 回执跟踪与状态确认 +- SMTP服务器配置管理 + +#### MSG-004: 站内信模块 + +- 站内消息推送管理 +- 用户消息中心维护 +- 已读/未读状态跟踪 +- 消息分类与过滤 + +#### MSG-005: 微信通知模块 + +- 微信模板消息发送 +- 公众号推送通知 +- 微信API接口对接 +- 推送结果状态回执 + +#### MSG-006: 模板管理模块 + +- 消息模板统一管理 +- 固定模板内容维护 +- 模板版本控制 +- 多渠道模板适配 + +#### MSG-007: 外部系统适配模块 + +- OA系统消息对接 +- 智水擎系统通知集成 +- 水投数科app消息推送 +- 外部API接口适配 + + + +# 非功能性需求的设计 + +## 性能的考虑 + +**设计目标:** + +- 系统响应时间:≤3秒(95%的请求) +- 并发用户数:≥200个在线用户 +- 数据库查询:≤1秒(单表查询) +- 批量处理:≥1000条/分钟 + +**设计措施:** + +1. **数据库优化** + - 采用达梦数据库主从架构,读写分离 + - 对核心业务表建立合适索引 + - 大表分区存储,历史数据归档 + - 连接池配置优化 + +2. **缓存策略** + - Redis缓存热点数据 + - 应用级缓存配置信息 + - CDN加速静态资源 + - 浏览器缓存优化 + +3. **应用优化** + - 异步处理非核心业务 + - 批量操作优化 + - SQL语句优化 + - 业务逻辑优化 + +## 兼容性的考虑 + +**浏览器兼容性:** + +- Chrome 80+(推荐) +- Firefox 75+ +- Safari 13+ +- Edge 80+ + +**数据库兼容性:** + +- 主要支持:达梦数据库 8.0+ +- 备选方案:PostgreSQL 12+ +- 预留接口:MySQL 8.0+ + +**操作系统兼容性:** + +- 服务器:Linux CentOS 7.6+/Ubuntu 18.04+ +- 客户端:Windows 10+/macOS 10.15+ + +## 安全的考虑 + +**身份认证:** + +- 基于OAuth2.0+CAS协议的单点登录 +- 基于JWT的无状态认证 +- 支持多因子认证(MFA) +- OAuth2+CAS第三方登录集成 +- 密码复杂度策略 + +**权限控制:** + +- RBAC角色权限模型 +- 细粒度功能权限控制 +- 数据权限隔离 +- 多租户数据隔离 + +**数据安全:** + +- 敏感数据加密存储 +- 数据传输HTTPS加密 +- 数据库连接加密 +- 定期数据备份 + +**系统安全:** + +- SQL注入防护 +- XSS攻击防护 +- CSRF攻击防护 +- 接口访问频率限制 + +## 可移植性的考虑 + +**平台无关性:** + +- 基于Java 17+,支持跨平台部署 +- 容器化部署,支持Docker/Kubernetes +- 数据库抽象层,支持多种数据库 +- 配置外部化,环境隔离 + +**云平台适配:** + +- 支持阿里云、腾讯云、华为云部署 +- 适配云原生架构 +- 支持弹性扩缩容 +- 云存储服务集成 + +## 关键技术特性 + +### 响应式设计 + +- **移动端适配**:完美适配各种移动设备 +- **触屏优化**:优化的触屏交互体验 +- **加载优化**:快速的页面加载速度 +- **离线支持**:基础功能离线可用 + +### 安全保障 + +- **数据加密**:敏感数据传输加密 +- **身份验证**:多重身份验证机制 +- **支付安全**:完善的支付安全策略 +- **隐私保护**:严格的用户隐私保护 + +## 集成与测试的考虑 + +**集成策略:** + +- 采用自底向上的集成方式 +- 先完成基础服务开发测试 +- 再进行业务服务集成 +- 最后进行端到端集成测试 + +**测试策略:** + +- 单元测试:代码覆盖率≥80% +- 集成测试:覆盖主要业务流程 +- 性能测试:验证性能指标 +- 安全测试:安全漏洞扫描 + +## 可扩展性的考虑 + +**架构扩展:** + +- 微服务架构支持水平扩展 +- 数据库分库分表支持 +- 缓存集群扩展 +- 负载均衡扩展 + +**功能扩展:** + +- 插件化架构设计 +- 开放API接口 +- 工作流引擎支持 +- 配置化业务规则 + +## 可靠性的考虑 + +**高可用设计:** + +- 应用服务集群部署 +- 数据库主从备份 +- 负载均衡器冗余 +- 自动故障切换 + +**容错机制:** + +- 服务降级策略 +- 熔断器模式 +- 重试机制 +- 异常处理策略 + +**数据备份:** + +- 数据库实时备份 +- 定期全量备份 +- 增量备份策略 +- 异地备份存储 + +## 可维护性的考虑 + +**代码质量:** + +- 统一编码规范 +- 代码审查制度 +- 自动化测试 +- 持续集成/持续部署 + +**运维友好:** + +- 完善的部署文档 +- 运维监控dashboard +- 日志集中管理 +- 性能监控告警 + +**文档管理:** + +- API文档自动生成 +- 系统架构文档 +- 运维操作手册 +- 故障处理手册 diff --git a/docs/evidence/bugfix/counter-settle-unsettled-filter-bugfix-2026-06-09.md b/docs/evidence/bugfix/counter-settle-unsettled-filter-bugfix-2026-06-09.md new file mode 100644 index 0000000..58328d1 --- /dev/null +++ b/docs/evidence/bugfix/counter-settle-unsettled-filter-bugfix-2026-06-09.md @@ -0,0 +1,137 @@ +# 柜台结清列表过滤字段对齐修复验证记录 + +日期:2026-06-09 + +## 问题现象 + +`GET /admin-api/business/charge/counter-settle/unsettled-page` 前端传入 `custCode`、`chargeWay` 后,待结清分页结果未按客户编号和收费方式过滤。 + +追加核对 `charge` 系列前端接口口径后,又发现: + +- 前端 `CounterUnsettledPageReqVO` 还声明了 `deptId`,后端待结清请求对象未接收,服务层未按站点过滤。 +- 前端已结清列表传入 `settleNo`,后端 `CounterSettledPageReqVO` 未接收,`SettleRecordMapper#selectSettledPage` 未按结清单号过滤。 + +示例参数: + +```text +pageNo=1&pageSize=10&custCode=15980151657&cashierId=&chargeWay= +``` + +## 根因 + +- 后端 `CounterUnsettledPageReqVO` 仅定义了 `cashierId`,未定义 `deptId`、`custCode`、`chargeWay`,Spring MVC 绑定查询参数时会忽略这些字段。 +- `CounterSettleApplicationServiceImpl#queryUnsettledItems` 只按收费员查询待结清支付主单,未继续应用客户编号、收费方式、营业站点过滤。 +- 后端 `CounterSettledPageReqVO` 未定义 `settleNo`,已结清 Mapper 查询条件也未包含 `settle_no`。 + +## 修复范围 + +仓库:`../water-backend` + +分支:`develop` + +修复前基线:`86203127e` + +修改文件: + +- `sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/controller/admin/charge/vo/CounterUnsettledPageReqVO.java` +- `sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/controller/admin/charge/vo/CounterSettledPageReqVO.java` +- `sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/dal/mysql/settlerecord/SettleRecordMapper.java` +- `sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/service/countersettle/CounterSettleApplicationServiceImpl.java` +- `sw-business/sw-business-server/src/test/java/cn/com/emsoft/sw/business/service/countersettle/CounterSettleApplicationServiceImplTest.java` +- `sw-business/sw-business-server/src/test/java/cn/com/emsoft/sw/business/integration/countersettle/CounterSettleIntegrationTest.java` + +## 修复内容 + +- `CounterUnsettledPageReqVO` 新增 `deptId`、`custCode`、`chargeWay` 查询字段。 +- 待结清列表在按收费员取得候选支付主单后,继续按 `custCode` 精确匹配、按 `chargeWay` 精确匹配、按账单 `deptId` 精确匹配。 +- 待结清导出复用同一查询逻辑,因此同步支持相同过滤条件。 +- `CounterSettledPageReqVO` 新增 `settleNo` 查询字段。 +- `SettleRecordMapper#selectSettledPage` 新增 `settleNo` 精确过滤,已结清导出复用同一查询逻辑。 +- 增加服务层单测覆盖 `custCode + chargeWay + deptId` 过滤、`settleNo` 参数传递和 Mapper 源码契约。 +- 增加接口集成测试断言,覆盖未结账匹配、不匹配客户编号、不匹配收费方式、不匹配站点,以及已结账匹配/不匹配结清单号;该集成测试受 `REV004_IT_DB_URL` 环境变量控制。 + +## 验证命令与结果 + +### RED 验证 + +```bash +cd /Volumes/Dpan/github/water-workspace/water-backend +mvn -pl sw-business/sw-business-server -Dtest=CounterSettleApplicationServiceImplTest#getUnsettledPage_shouldFilterByCustCodeAndChargeWay test +``` + +结果:失败,符合预期。 + +- 失败点:`CounterUnsettledPageReqVO` 缺少 `setCustCode(String)`、`setChargeWay(int)`。 +- 说明:证明后端请求对象没有承接过滤参数。 + +```bash +cd /Volumes/Dpan/github/water-workspace/water-backend +mvn -pl sw-business/sw-business-server -Dtest=CounterSettleApplicationServiceImplTest#getSettledPage_shouldUseMapperPagedResult+getUnsettledPage_shouldFilterByCustCodeChargeWayAndDeptId test +``` + +结果:失败,符合预期。 + +- 失败点:`CounterSettledPageReqVO` 缺少 `setSettleNo(String)` / `getSettleNo()`,`CounterUnsettledPageReqVO` 缺少 `setDeptId(long)`。 +- 说明:证明后端请求对象未完整对齐前端 `charge` 系列列表筛选字段。 + +### 服务层回归 + +```bash +cd /Volumes/Dpan/github/water-workspace/water-backend +mvn -pl sw-business/sw-business-server -Dtest=CounterSettleApplicationServiceImplTest#getUnsettledPage_shouldFilterByCustCodeAndChargeWay test +``` + +结果:通过。 + +- Surefire 汇总:`Tests run: 1, Failures: 0, Errors: 0, Skipped: 0` +- Maven 结果:`BUILD SUCCESS` + +```bash +cd /Volumes/Dpan/github/water-workspace/water-backend +mvn -pl sw-business/sw-business-server -Dtest=CounterSettleApplicationServiceImplTest#getSettledPage_shouldUseMapperPagedResult+getUnsettledPage_shouldFilterByCustCodeChargeWayAndDeptId test +``` + +结果:通过。 + +- Surefire 汇总:`Tests run: 2, Failures: 0, Errors: 0, Skipped: 0` +- Maven 结果:`BUILD SUCCESS` + +### 相关服务单测 + +```bash +cd /Volumes/Dpan/github/water-workspace/water-backend +mvn -pl sw-business/sw-business-server -Dtest=CounterSettleApplicationServiceImplTest test +``` + +结果:通过。 + +- Surefire 汇总:`Tests run: 22, Failures: 0, Errors: 0, Skipped: 0` +- Maven 结果:`BUILD SUCCESS` + +### 编译验证 + +```bash +cd /Volumes/Dpan/github/water-workspace/water-backend +mvn -pl sw-business/sw-business-server -DskipTests compile +``` + +结果:通过。 + +- Maven 结果:`BUILD SUCCESS` + +### 接口集成测试 + +```bash +cd /Volumes/Dpan/github/water-workspace/water-backend +mvn -pl sw-business/sw-business-server -Dtest=CounterSettleIntegrationTest#counterSettleApis_shouldSupportUnsettledConfirmSettledAndDetails test +``` + +结果:未执行,不作为通过项。 + +- Surefire 汇总:`Tests run: 1, Failures: 0, Errors: 0, Skipped: 1` +- 原因:`CounterSettleIntegrationTest` 标注 `@EnabledIfEnvironmentVariable(named = "REV004_IT_DB_URL", matches = ".+")`,当前环境未提供该变量。 + +## 备注 + +- 本次验证期间存在既有 Maven model warning、Mockito dynamic-agent warning、`MockBean` deprecation warning,未导致编译或已执行单测失败。 +- `cashierId` 为空时仍沿用既有逻辑:优先使用当前登录用户 ID 作为收费员过滤值。 diff --git a/docs/evidence/bugfix/frontend/frontend-expect-cli-test-framework-2026-06-08.md b/docs/evidence/bugfix/frontend/frontend-expect-cli-test-framework-2026-06-08.md new file mode 100644 index 0000000..d4569e6 --- /dev/null +++ b/docs/evidence/bugfix/frontend/frontend-expect-cli-test-framework-2026-06-08.md @@ -0,0 +1,354 @@ +# 前端 Expect CLI 测试框架接入记录 + +日期:2026-06-08 + +## 范围 + +本记录对应 `water-frontend` 仓库新增 `expect-cli` 浏览器测试框架入口,用于在现有 Playwright 与 `node:test` 测试之外,提供 agent 驱动的浏览器测试能力。 + +## 前端基线 + +- 仓库:`water-frontend` +- 工作目录:`/Volumes/Dpan/github/water-workspace/water-frontend` +- 分支:`develop` +- 基础提交:`35fb598c9059b0ea933de533892a0473512ad662` +- 状态:测试框架接入已在工作区实现,尚未提交 + +## 实现内容 + +- 新增开发依赖:`expect-cli@^0.1.3` +- 新增脚本: + - `pnpm test:expect` + - `pnpm test:expect:smoke` + - `pnpm test:expect:watch` + - `pnpm test:expect:acceptance` +- 新增 runner:`tools/expect/run-expect.mjs` + - 默认目标地址为 `http://localhost:18080` + - 支持 `EXPECT_BASE_URL` 覆盖目标地址 + - 本地服务不可达时自动启动 `pnpm dev` + - 复用已有本地服务时不接管其生命周期 + - 支持 `--no-dev-server` 禁止自动启动 +- 新增验收场景库:`tests/expect/revenue-bugfix-clear-scope/scenarios.json` + - 覆盖 `#78`、`#39`、`#50`、`#53`、`#58/#59`、`#69/#76` 和基础回归。 + - 场景来源为 `docs/superpowers/plans/2026-06-08-revenue-bugfix-clear-scope-acceptance-test.md`。 + - 使用环境占位符表达测试账号、客户和业务数据,不在前端仓硬编码 live 数据。 +- 新增验收场景加载模块:`tools/expect/acceptance-scenarios.mjs` + - 验收指令默认使用严格黑盒规约:正式验收计划为 oracle,不以源码、路由、store、API 封装或既有自动化测试作为通过依据。 + - 通过标准固定为 `PASS / FAIL / BLOCKED`,缺数据、缺权限或业务状态不足时必须标记 `BLOCKED`。 +- 新增验收数据预检: + - `acceptance` 运行前检查场景所需环境变量。 + - 缺少测试账号、客户或业务记录时直接输出 `BLOCKED` 并以退出码 `2` 结束,不启动浏览器,不使用占位符继续测试。 +- 新增 runner/场景单元测试: + - `tests/expect/revenueBugfixAcceptanceScenarios.test.mjs` + - `tests/expect/runExpectRunnerArgs.test.mjs` +- 新增使用说明:`tests/expect/README.md` + +## 验证命令 + +```bash +cd /Volumes/Dpan/github/water-workspace/water-frontend +node --check tools/expect/run-expect.mjs +node --check tools/expect/acceptance-scenarios.mjs +node tools/expect/run-expect.mjs --help +pnpm exec expect tui --help +node -e "const pkg=require('./package.json'); console.log(pkg.scripts['test:expect']); console.log(pkg.scripts['test:expect:smoke']); console.log(pkg.scripts['test:expect:watch']); console.log(pkg.devDependencies['expect-cli'])" +node --test tests/expect/revenueBugfixAcceptanceScenarios.test.mjs tests/expect/runExpectRunnerArgs.test.mjs +pnpm test:expect:acceptance -- --list +pnpm test:expect:acceptance -- rev-bugfix-39-counter-prepay-settlement +``` + +## 验证结果 + +- runner 语法检查:通过。 +- 验收场景加载模块语法检查:通过。 +- runner 帮助输出:通过,显示 `test:expect`、`test:expect:smoke`、`test:expect:watch` 用法及 `EXPECT_BASE_URL` 等环境变量。 +- `expect-cli` 本地可执行性:通过,`pnpm exec expect tui --help` 成功输出 CLI 参数说明。 +- `package.json` 脚本解析:通过,`test:expect`、`test:expect:smoke`、`test:expect:watch`、`test:expect:acceptance` 均指向 `tools/expect/run-expect.mjs`,开发依赖版本为 `^0.1.3`。 +- 验收场景单元测试:通过,8 项通过、0 项失败。 +- 验收场景列表命令:通过,列出 7 个场景及各自 requiredData。 +- 严格数据预检:通过。执行 `pnpm test:expect:acceptance -- rev-bugfix-39-counter-prepay-settlement` 时,由于未提供 `EXPECT_TEST_CASHIER_A_USERNAME` 和 `EXPECT_TEST_CUSTOMER_C4`,命令输出 `BLOCKED` 并以退出码 `2` 结束,未启动浏览器。 +- `typecheck/vue-tsc`:按用户要求未继续执行,后续本项不作为该接入任务的默认验证。 +- 浏览器实际 smoke:未执行。本次完成框架接入、验收场景库和 CLI 可用性验证;真实业务验收需要测试环境提供 C1-C5、收费员 A/B、审批账号、水价模板、未结账/已结账记录等数据后运行。 + +## 使用入口 + +```bash +pnpm test:expect +pnpm test:expect:smoke +pnpm test:expect:watch -- -m "test the flow you changed" +pnpm test:expect:acceptance -- --list +pnpm test:expect:acceptance -- rev-bugfix-53-prepaid-deduction +pnpm test:expect:acceptance -- all +EXPECT_BASE_URL=http://localhost:18081 pnpm test:expect +``` + +## 重新测试记录:2026-06-08 严格验收重跑 + +### 触发背景 + +前端工作区新增了红冲记录页面的时间范围默认时间处理: + +- `src/views/operatingCharges/redReversalRecord/index.vue` +- `tests/revenue-bugs/revenueBugfixClearScope.contract.test.mjs` + +### 执行命令 + +```bash +cd /Volumes/Dpan/github/water-workspace/water-frontend +pnpm test:expect:acceptance -- all +pnpm test:expect:acceptance -- rev-bugfix-58-59-red-reversal-record +node --test tests/revenue-bugs/revenueBugfixClearScope.contract.test.mjs +node --test tests/expect/revenueBugfixAcceptanceScenarios.test.mjs tests/expect/runExpectRunnerArgs.test.mjs +``` + +### 结果 + +- 严格全量验收:`BLOCKED`。当前 shell 未提供 `EXPECT_TEST_*` 测试账号、客户和业务记录数据,runner 未启动浏览器,未使用占位符继续测试。 +- `#58/#59` 红冲记录严格验收:`BLOCKED`。缺少: + - `EXPECT_TEST_CASHIER_A_USERNAME` + - `EXPECT_TEST_SETTLED_COUNTER_RECORD` +- 代码契约验证:通过,`tests/revenue-bugs/revenueBugfixClearScope.contract.test.mjs` 共 5 项通过、0 项失败。 +- Expect 场景/runner 单元测试:通过,8 项通过、0 项失败。 +- `typecheck/vue-tsc`:未执行。 + +### 结论 + +本次只确认了红冲记录代码契约和 Expect 严格验收框架本身仍可用。正式黑盒业务验收未通过也未失败,状态为 `BLOCKED`,需要提供测试账号、客户和已结账可红冲记录后重新执行。 + +## 收费与账务闭环场景库接入:2026-06-08 + +### 范围 + +基于 `/Volumes/Dpan/github/water-workspace/docs` 中收费、结账、预存抵扣业务资料,以及 `../water-docs/specs/001-rev004-accounting/` 中账务处理一期口径,新增前端 `expect-cli` 可执行场景 suite: + +- `tests/expect/revenue-accounting-closures/scenarios.json` +- `tests/expect/revenue-accounting-closures/README.md` + +### 场景 + +初版纳入 12 条场景: + +- P0 小闭环: + - `revenue-charge-normal-payment` + - `revenue-charge-no-arrears-topup` + - `revenue-charge-prepay-zero-confirm` + - `revenue-charge-prepay-partial-deduction` + - `revenue-charge-prepay-full-deduction` +- P0 跨页面大闭环: + - `closure-charge-to-settlement` + - `closure-prepay-charge-to-settlement` + - `closure-settlement-to-red-reversal-record` +- P1 账务处理小闭环: + - `accounting-unsold-split-submit` + - `accounting-unsold-bad-debt-submit` + - `accounting-unsold-price-diff-submit` + - `accounting-unsold-penalty-remission-submit` + +### 工具调整 + +- `tools/expect/acceptance-scenarios.mjs` 支持多 suite 加载。 +- 场景引用支持: + - `revenue-accounting-closures:all` + - `revenue-accounting-closures:` + - 全局唯一场景可直接使用 `` +- `requiredData` 扩展到账务和收费闭环数据键,例如 `customerArrears`、`customerNoArrears`、`unsoldBillCustomer` 等。 + +### 验证命令 + +```bash +cd /Volumes/Dpan/github/water-workspace/water-frontend +node --test tests/expect/revenueAccountingClosureScenarios.test.mjs tests/expect/revenueBugfixAcceptanceScenarios.test.mjs tests/expect/runExpectRunnerArgs.test.mjs +node --check tools/expect/acceptance-scenarios.mjs +node --check tools/expect/run-expect.mjs +pnpm test:expect:acceptance -- --list +pnpm test:expect:acceptance -- revenue-accounting-closures:closure-charge-to-settlement +``` + +### 结果 + +- 多 suite 场景加载、schema、requiredData 映射、prompt 生成测试:通过,15 项通过、0 项失败。 +- runner 语法检查:通过。 +- 场景列表命令:通过,可列出 bugfix suite 和 `revenue-accounting-closures` suite。 +- 严格业务执行:`pnpm test:expect:acceptance -- revenue-accounting-closures:closure-charge-to-settlement` 返回 `BLOCKED`,缺少 `EXPECT_TEST_CASHIER_A_USERNAME` 与 `EXPECT_TEST_CUSTOMER_ARREARS`,未启动浏览器,不作为失败或通过。 +- `typecheck/vue-tsc`:未执行。 + +## 验证记录:2026-06-08 收费与账务闭环 suite + +### 执行命令 + +```bash +cd /Volumes/Dpan/github/water-workspace/water-frontend +node --check tools/expect/acceptance-scenarios.mjs +node --check tools/expect/run-expect.mjs +node --test tests/expect/revenueAccountingClosureScenarios.test.mjs tests/expect/revenueBugfixAcceptanceScenarios.test.mjs tests/expect/runExpectRunnerArgs.test.mjs +node --test tests/revenue-bugs/revenueBugfixClearScope.contract.test.mjs +pnpm test:expect:acceptance -- --list +pnpm test:expect:acceptance -- revenue-accounting-closures:all +pnpm test:expect:acceptance -- revenue-accounting-closures:closure-charge-to-settlement +``` + +### 结果 + +- runner 语法检查:通过。 +- Expect 场景/runner 单元测试:通过,15 项通过、0 项失败。 +- 营收缺陷代码契约测试:通过,5 项通过、0 项失败。 +- 场景列表:通过,列出 `revenue-bugfix-clear-scope` 与 `revenue-accounting-closures` 两个 suite。 +- `revenue-accounting-closures:all`:`BLOCKED`。缺少收费员、欠费客户、无欠费客户、预存余额客户、已结账红冲记录、管理员和未销账单客户等测试数据。 +- `revenue-accounting-closures:closure-charge-to-settlement`:`BLOCKED`。缺少: + - `EXPECT_TEST_CASHIER_A_USERNAME` + - `EXPECT_TEST_CUSTOMER_ARREARS` +- 浏览器黑盒业务执行:未启动。阻塞发生在 requiredData 预检阶段,符合严格验收规则。 +- `typecheck/vue-tsc`:未执行。 + +## 验证记录:2026-06-08 Expect runner 与页面 smoke 重跑 + +### 触发背景 + +前端工作区继续调整了 Expect runner 可执行性,并对红冲记录页的红冲时间范围默认时间进行了补充: + +- `tools/expect/run-expect.mjs` +- `tests/expect/runExpectRunnerArgs.test.mjs` +- `src/views/operatingCharges/redReversalRecord/index.vue` +- `tests/revenue-bugs/revenueBugfixClearScope.contract.test.mjs` + +### 工具调整 + +- `tools/expect/run-expect.mjs` 改为优先调用本地 `node_modules/.bin/expect`,避免 `pnpm exec expect` 在当前工作区触发隐式 `pnpm install`。 +- runner 增加 `EXPECT_BIN` 覆盖入口,便于特殊环境指定 Expect 可执行文件。 +- runner 过滤 npm/pnpm 转发参数中的独立 `--` 分隔符,修复 `pnpm test:expect:acceptance -- ` 被 Expect 识别为多余位置参数的问题。 + +### 执行命令 + +```bash +cd /Volumes/Dpan/github/water-workspace/water-frontend +node --test tests/expect/runExpectRunnerArgs.test.mjs +node --test tests/expect/revenueBugfixAcceptanceScenarios.test.mjs tests/expect/revenueAccountingClosureScenarios.test.mjs +node --test tests/revenue-bugs/revenueBugfixClearScope.contract.test.mjs +corepack pnpm@9.15.9 test:expect:acceptance -- --list +source /tmp/revenue-acceptance-env.sh +corepack pnpm@9.15.9 test:expect:acceptance -- rev-bugfix-50-cashier-filter --target unstaged --timeout 120000 --verbose +./node_modules/.bin/eslint tools/expect/run-expect.mjs tests/expect/runExpectRunnerArgs.test.mjs tests/revenue-bugs/revenueBugfixClearScope.contract.test.mjs src/views/operatingCharges/redReversalRecord/index.vue +corepack pnpm@9.15.9 ts:check +NODE_OPTIONS=--max-old-space-size=16384 corepack pnpm@9.15.9 ts:check +corepack pnpm@9.15.9 build:dev +``` + +### 结果 + +- runner 单元测试:通过,5 项通过、0 项失败。 +- Expect 场景加载测试:通过,12 项通过、0 项失败。 +- 营收缺陷代码契约测试:通过,5 项通过、0 项失败。 +- 场景列表命令:通过。需使用 `corepack pnpm@9.15.9`;当前 shell 的全局 `pnpm@11.5.1` 会在脚本执行前尝试清理并重装 `node_modules`,无 TTY 时退出。 +- `rev-bugfix-50-cashier-filter` 严格黑盒验收:`BLOCKED`。requiredData 环境变量已提供,但 Expect 启动 Codex ACP 后返回 `401 Unauthorized`,提示当前 Codex agent 未认证或 API key 无效;未进入浏览器业务步骤,不可判定 `PASS` 或 `FAIL`。 +- 页面 smoke(Playwright fallback):通过登录默认租户 `福建水投集团`、用户 `admin` 后访问真实菜单路由: + - `/operatingCharges/counterCheckout`:页面标题为 `营业收费管理系统 - 柜台结账`,未出现 404,无 failed network request;截图在 `water-frontend/test-results/counter-checkout-smoke.png`。 + - `/operatingCharges/redReversalRecord`:页面标题为 `营业收费管理系统 - 红冲记录`,查询区显示 `红冲时间`,表格显示柜台红冲记录字段,无 failed network request;截图在 `water-frontend/test-results/red-reversal-record-smoke.png`。 +- 页面 smoke 备注:运行时存在既有 Vue/router warning,包括未解析菜单组件 `system/userformconfig/index`、`pay/demo/transfer/index`,以及 `inject() can only be used inside setup()` 等;未在本次范围内修复。 +- focused ESLint:通过。 +- `ts:check`:失败。默认堆内存运行先 OOM;增大到 16G 后完成但暴露 repo-wide 既有 TypeScript 错误,涉及 mall statistics、BPM designer、pay views、system views、settings 等大量非本次修改文件。本结果不作为本次改动通过项。 +- `build:dev`:通过,输出 `Build successful. Please see dist directory`。构建期间仍有既有 Vite CJS deprecation warning、SVG symbolId warning、Rollup PURE annotation warning。 + +### 结论 + +Expect runner 的本地执行入口和 pnpm 参数转发问题已修复并由单元测试覆盖。`rev-bugfix-50-cashier-filter` 严格黑盒验收当前阻塞于 Codex ACP 认证,状态为 `BLOCKED`;页面级 fallback smoke 只证明页面可登录访问和基础渲染,不替代正式黑盒业务验收。 + +## 修复记录:2026-06-08 Expect runner 完整收敛 + +### 触发背景 + +上一轮验证后仍有三个仓库内可控问题: + +- 当前 shell 的全局 `pnpm@11.5.1` 与 `node_modules/.modules.yaml` 中的 `pnpm@9.15.9` 布局不一致,未 pin 时会触发脚本前置安装/清理风险。 +- runner 自动启动 dev server 时仍通过 `pnpm dev`,在 pnpm 版本不一致时可能复现同类问题。 +- `tests/expect` 场景中存在 `/operating-charges/...` 旧路由元数据,而当前真实菜单路由为 `/operatingCharges/...`。 +- Expect 调用 Codex ACP 认证失败时输出原始栈,不够符合严格验收的 `BLOCKED` 语义。 + +### 实现内容 + +- `package.json` 新增 `packageManager: pnpm@9.15.9`。 +- `tools/expect/run-expect.mjs`: + - dev server 启动改为直接调用本地 `node_modules/vite/bin/vite.js --mode dev`。 + - 保留 `EXPECT_DEV_SERVER_BIN` 用于特殊环境覆盖。 + - 捕获 Expect 输出并识别 Codex ACP `401 Unauthorized` / `AcpProviderUnauthenticatedError`,转为清晰 `BLOCKED` 输出和退出码 `2`。 +- `tests/expect/revenue-bugfix-clear-scope/scenarios.json`: + - 为 bugfix 场景补充真实页面路由元数据。 +- `tests/expect/revenue-accounting-closures/scenarios.json`: + - 将收费、结账、红冲场景的旧路由更新为 `/operatingCharges/counterCharging`、`/operatingCharges/counterCheckout`、`/operatingCharges/redReversalRecord`。 +- `tests/expect/runExpectRunnerArgs.test.mjs`、`tests/expect/revenueBugfixAcceptanceScenarios.test.mjs`、`tests/expect/revenueAccountingClosureScenarios.test.mjs` 补充回归测试覆盖上述行为。 + +### 执行命令 + +```bash +cd /Volumes/Dpan/github/water-workspace/water-frontend +node --test tests/expect/runExpectRunnerArgs.test.mjs +node --test tests/expect/revenueBugfixAcceptanceScenarios.test.mjs tests/expect/revenueAccountingClosureScenarios.test.mjs +node --test tests/expect/runExpectRunnerArgs.test.mjs tests/expect/revenueBugfixAcceptanceScenarios.test.mjs tests/expect/revenueAccountingClosureScenarios.test.mjs +node --test tests/revenue-bugs/revenueBugfixClearScope.contract.test.mjs +./node_modules/.bin/eslint tools/expect/run-expect.mjs tools/expect/acceptance-scenarios.mjs tests/expect/runExpectRunnerArgs.test.mjs tests/expect/revenueBugfixAcceptanceScenarios.test.mjs tests/expect/revenueAccountingClosureScenarios.test.mjs tests/revenue-bugs/revenueBugfixClearScope.contract.test.mjs src/views/operatingCharges/redReversalRecord/index.vue +pnpm test:expect:acceptance -- --list +pnpm test:expect:acceptance -- revenue-accounting-closures:closure-charge-to-settlement +source /tmp/revenue-acceptance-env.sh +pnpm test:expect:acceptance -- rev-bugfix-50-cashier-filter --target unstaged --timeout 120000 --verbose +pnpm build:dev +``` + +### 结果 + +- runner 单测:通过,9 项通过、0 项失败。 +- Expect 场景测试:通过,14 项通过、0 项失败。 +- 合并执行 Expect runner/场景测试:通过,23 项通过、0 项失败。 +- 营收缺陷契约测试:通过,5 项通过、0 项失败。 +- focused ESLint:通过。 +- `pnpm test:expect:acceptance -- --list`:通过,可在 plain `pnpm` 下列出两个 suite 的场景。 +- `pnpm test:expect:acceptance -- revenue-accounting-closures:closure-charge-to-settlement`:按 requiredData 预检返回 `BLOCKED`,缺少 `EXPECT_TEST_CASHIER_A_USERNAME` 与 `EXPECT_TEST_CUSTOMER_ARREARS`,退出码 `2`。 +- `pnpm test:expect:acceptance -- rev-bugfix-50-cashier-filter --target unstaged --timeout 120000 --verbose`:requiredData 已提供,但 Codex ACP 认证失败,runner 输出清晰 `BLOCKED: Codex ACP authentication failed before browser acceptance steps ran...`,退出码 `2`,未再输出原始 ACP 栈。 +- `pnpm build:dev`:通过,输出 `Build successful. Please see dist directory`。构建期间仍存在既有 Vite CJS deprecation warning、SVG symbolId warning、Rollup PURE annotation warning。 + +### 结论 + +本次已将仓库内可控问题收敛:pnpm 版本、runner 启动路径、场景路由元数据、Codex ACP 认证失败语义均已有自动化测试覆盖。严格黑盒业务验收仍取决于外部 Codex ACP 认证状态;认证未完成时应按 `BLOCKED` 处理,不应判定业务 `PASS` 或 `FAIL`。 + +## 本地 Playwright smoke 入口:2026-06-08 无 ACP 场景 + +### 触发背景 + +用户本机没有 Codex ACP 认证,`pnpm test:expect:acceptance -- rev-bugfix-50-cashier-filter` 只能得到 `BLOCKED`,无法进入浏览器业务步骤。为保证前端页面链路仍可在本地验证,本次新增不依赖 ACP 的 Playwright smoke runner。 + +### 实现内容 + +- `package.json` 新增 `test:revenue:smoke`,执行 `node tools/revenue/run-local-smoke.mjs`。 +- `tools/revenue/run-local-smoke.mjs`: + - 默认读取 `/tmp/revenue-acceptance-env.sh`,支持 `REVENUE_SMOKE_ENV_FILE` 覆盖。 + - 使用 `EXPECT_BASE_URL`、`EXPECT_TEST_ADMIN_USERNAME`、`EXPECT_TEST_ADMIN_PASSWORD` 等本机环境变量登录本地前端代理 `/admin-api/system/auth/login`。 + - 自动复用或启动本地 Vite dev server。 + - 访问 `/operatingCharges/counterCheckout` 与 `/operatingCharges/redReversalRecord`,检查页面标题/关键文案、登录状态、not-found 状态,并输出截图。 + - 对登录不可达、认证被拒等数据/环境问题输出 `BLOCKED`,退出码 `2`。 + - 修复两个 runner 稳定性问题:`SmokeBlockedError` TDZ、业务流水号包含 `404` 时误判为 404 页。 +- `tests/revenue-bugs/revenueLocalSmokeRunner.test.mjs` 覆盖 env 解析、默认配置、页面清单、BLOCKED 输出、404 误判和超时 helper。 + +### 执行命令 + +```bash +cd /Volumes/Dpan/github/water-workspace/water-frontend +node --test tests/revenue-bugs/revenueLocalSmokeRunner.test.mjs +pnpm test:revenue:smoke +node --test tests/revenue-bugs/revenueLocalSmokeRunner.test.mjs tests/revenue-bugs/revenueBugfixClearScope.contract.test.mjs +node --test tests/expect/runExpectRunnerArgs.test.mjs tests/expect/revenueBugfixAcceptanceScenarios.test.mjs tests/expect/revenueAccountingClosureScenarios.test.mjs +pnpm exec eslint tools/revenue/run-local-smoke.mjs tests/revenue-bugs/revenueLocalSmokeRunner.test.mjs +pnpm build:dev +``` + +### 结果 + +- 本地 smoke runner 单测:通过,9 项通过、0 项失败。 +- 本地页面 smoke:通过。 + - `/operatingCharges/counterCheckout`:登录用户 `admin`,页面显示 `未结账`、`已结账`、`收费员`;截图为 `water-frontend/test-results/counter-checkout-local-smoke.png`。 + - `/operatingCharges/redReversalRecord`:页面显示 `红冲记录`、`红冲时间`、`收费员`;截图为 `water-frontend/test-results/red-reversal-record-local-smoke.png`。 +- 营收缺陷契约测试 + 本地 runner 单测:通过,14 项通过、0 项失败。 +- Expect runner/场景测试:通过,23 项通过、0 项失败。 +- focused ESLint:通过。 +- `pnpm build:dev`:通过,输出 `Build successful. Please see dist directory`。构建期间仍存在既有 Vite CJS deprecation warning、SVG symbolId warning、Rollup PURE annotation warning。 + +### 结论 + +本地前端页面链路现在可以通过 `pnpm test:revenue:smoke` 在无 ACP 的机器上执行。该入口证明登录、动态菜单路由、页面基础渲染和截图可用;它不替代 `expect-cli` 严格黑盒验收,也不验证 #50 收费员 A/B 业务数据筛选结果。严格业务验收仍需 ACP、其他可用 agent,或人工按正式验收计划执行。 diff --git a/docs/evidence/bugfix/frontend/frontend-form-create-native-tag-guard-2026-06-05.md b/docs/evidence/bugfix/frontend/frontend-form-create-native-tag-guard-2026-06-05.md new file mode 100644 index 0000000..2dde4df --- /dev/null +++ b/docs/evidence/bugfix/frontend/frontend-form-create-native-tag-guard-2026-06-05.md @@ -0,0 +1,28 @@ +# Frontend Form Create Native Tag Guard Evidence + +- Date: 2026-06-05 +- Repository: `water-frontend` +- Branch: `develop` +- Scope: production/dev-mode build warning where Element Plus `ElSelect` dropdown renders `ElScrollbar tag="ul"` and Vue resolves it as `
    `. + +## Root Cause + +Vue `resolveDynamicComponent('ul')` checks the app component registry before falling back to a native tag. A global component alias such as `Ul` can therefore shadow the native `ul` tag. Element Plus `ElScrollbar` uses dynamic tag rendering internally, so a polluted global registry causes its dropdown list to render as a component and emit: + +`Extraneous non-props attributes (...) were passed to component but could not be automatically inherited because component renders fragment or text root nodes.` + +## Frontend Change + +- Added `src/plugins/formCreate/nativeTagComponentGuard.ts`. +- Invoked the guard after `formCreate` and `FcDesigner` installation in `src/plugins/formCreate/index.ts`. +- The guard removes global component aliases matching native HTML/SVG tags after third-party plugin registration, preventing dynamic native tags such as `ul` from resolving to global Vue components. + +## Verification + +- `node --test tests/layout/nativeTagComponentGuard.test.mjs`: passed, 2 tests. +- `node --max-old-space-size=8192 ./node_modules/vite/bin/vite.js build --mode dev`: passed, generated `dist`. +- `node --max-old-space-size=8192 ./node_modules/vue-tsc/bin/vue-tsc.js --noEmit`: failed on existing repository-wide type errors outside this change scope, including mall statistics, BPM designer, pay pages, settings pages, and casing mismatch under `settings/waterMeter/range`. + +## Notes + +- The first `pnpm run` verification attempt triggered pnpm dependency-state auto-install in a non-TTY environment. `node_modules` was restored with `CI=true pnpm install --ignore-scripts`, and verification was continued by invoking local binaries directly. diff --git a/docs/evidence/bugfix/frontend/frontend-payment-method-account-address-required-2026-06-09.md b/docs/evidence/bugfix/frontend/frontend-payment-method-account-address-required-2026-06-09.md new file mode 100644 index 0000000..a3640bd --- /dev/null +++ b/docs/evidence/bugfix/frontend/frontend-payment-method-account-address-required-2026-06-09.md @@ -0,0 +1,56 @@ +# 客户缴费方式开户地址前端必填校验修复验证记录 + +日期:2026-06-09 + +## 问题现象 + +客户资料页面修改缴费方式时,前端代扣/托收表单展示了“开户地址”字段,但未做必填校验;提交到后端后,后端在保存代扣或托收资料时返回“开户地址不能为空”。 + +## 结论 + +本问题应由前端补齐校验。原因是后端代扣、托收资料保存对象均将 `accountAddress` 定义为必填字段,客户缴费方式修改链路会复用这两个保存对象。 + +## 修复范围 + +仓库:`../water-frontend` + +基线:`35aa0fbb` + +修改文件: + +- `src/views/custData/custInfo/components/PayMethodForm.vue` +- `src/views/custData/custCreate/components/WithHold.vue` +- `src/views/custData/custInfo/components/PayMethodForm.contract.test.mjs` + +## 修复内容 + +- 客户详情“缴费方式”弹窗: + - 托收资料 `collectionFormRules` 增加 `accountAddress` 必填。 + - 代扣资料 `withHoldingFormRules` 增加 `accountAddress` 必填。 +- 新户建档代扣弹窗: + - `formRules` 增加 `accountAddress` 必填。 +- 补充 node:test 契约测试,锁定上述规则。 + +## 验证命令与结果 + +```bash +cd /Volumes/Dpan/github/water-workspace/water-frontend +node --test src/views/custData/custInfo/components/PayMethodForm.contract.test.mjs +``` + +结果:通过。 + +- `tests 2` +- `pass 2` +- `fail 0` + +```bash +cd /Volumes/Dpan/github/water-workspace/water-frontend +git diff --check -- src/views/custData/custInfo/components/PayMethodForm.vue src/views/custData/custCreate/components/WithHold.vue src/views/custData/custInfo/components/PayMethodForm.contract.test.mjs +``` + +结果:通过,无空白错误。 + +## 备注 + +当前前端仓库存在其他未提交的 expect 相关改动,本次未触碰。 diff --git a/docs/evidence/bugfix/frontend/revenue-bugfix-clear-scope-frontend-2026-06-08.md b/docs/evidence/bugfix/frontend/revenue-bugfix-clear-scope-frontend-2026-06-08.md new file mode 100644 index 0000000..9a7c017 --- /dev/null +++ b/docs/evidence/bugfix/frontend/revenue-bugfix-clear-scope-frontend-2026-06-08.md @@ -0,0 +1,51 @@ +# 营收明确缺陷第一批前端修复验证记录 + +日期:2026-06-08 + +## 范围 + +本记录对应 `docs/superpowers/plans/2026-06-08-revenue-bugfix-clear-scope.md` 中前端 Task 5 至 Task 8: + +- `#69/#76` 未销分账、呆坏账、价差、违约金减免提交后状态提示 +- `#78` 水价调整失败后重试闭环 +- `#58/#59` 柜台红冲记录页面接口与查询语义 +- `#39/#53` 柜台结账预存充值行展示、柜台收费预存抵扣为 0 的确认保护 + +## 前端基线 + +- 仓库:`water-frontend` +- Worktree:`/Volumes/Dpan/github/water-workspace/worktrees/frontend-revenue-bugfix-clear-scope` +- 分支:`frontend-revenue-bugfix-clear-scope` +- 基础提交:`2a13e63e941e0a990f025844979847b3196effa9` +- 状态:前端修复已在 worktree 中实现,尚未提交 + +## 验证命令 + +```bash +cd /Volumes/Dpan/github/water-workspace/worktrees/frontend-revenue-bugfix-clear-scope +node --test tests/revenue-bugs/revenueBugfixClearScope.contract.test.mjs +pnpm dev --host 0.0.0.0 +``` + +## 验证结果 + +- 前端合约测试:通过,5 项通过、0 项失败。 +- Playwright 登录 smoke:通过。使用默认租户 `福建水投集团`、用户 `admin` 登录到 `http://localhost:18080/home/index`。 +- Playwright 页面 smoke: + - `/operatingCharges/redReversalRecord`:页面可打开,查询区和表格已显示 `收费员`、`红冲时间`、`红冲金额`、`红冲原因` 等柜台红冲语义字段。 + - `/operatingCharges/counterCheckout`:页面可打开,未结账表中空收费单号显示为 `--`。 + - `/operatingCharges/counterCharging`:页面可打开。使用现有客户 `20260512111` 验证“预存抵扣金额为 0”确认弹窗出现,且未调用 `/business/charge/update`,未提交收费。 + - `/accountProcess/unsoldAdjustment`:页面可打开。 + - `/settings/price/priceTemplate`:页面可打开,显示 `开始调价`。 +- 后端接口口径核对: + - 远端接口 `/admin-api/business/charge/counter-settle/red-flush-record-page` 返回业务 `code=404`,提示 `请求地址不存在:admin-api/business/charge/counter-settle/red-flush-record-page`。 + - 本地后端 worktree `backend-revenue-bugfix-clear-scope` 的 `ChargeController` 当前也未提供 `/counter-settle/red-flush-record-page` 和 `/counter-settle/red-flush-record-export`,与前端 Task 7 口径未闭合。 + - 预存抵扣后端兜底校验闭合:`ChargeServiceImpl` 校验抵扣金额非负且不超过应收金额,`AccountService.decreaseDeposit()` 校验账户预存余额不足并抛错。 +- `typecheck`:未执行完成。按用户要求停止并不再执行 typecheck。 +- `build`:未执行。 + +## 备注 + +依赖安装采用 `pnpm install`。安装过程中 pnpm 11 提示 `@carbon/icons` 构建脚本未批准;该临时配置改动未纳入本次业务修复。 + +Playwright 运行时按需安装了 Chromium 单浏览器。截图保存在前端 worktree 的 `test-results/` 目录下。 diff --git a/docs/evidence/bugfix/frontend/yw-business-flows-expect-cases-2026-06-09.md b/docs/evidence/bugfix/frontend/yw-business-flows-expect-cases-2026-06-09.md new file mode 100644 index 0000000..d0a05e9 --- /dev/null +++ b/docs/evidence/bugfix/frontend/yw-business-flows-expect-cases-2026-06-09.md @@ -0,0 +1,115 @@ +# YW 业务流程 Expect 验收用例编制记录(2026-06-09) + +## 背景 + +根据用户在 2026-06-09 提供的 5 条业务测试用例,前端仓新增 Expect 黑盒验收场景 suite: + +- `yw-business-flows:yw-01`:手工建档 +- `yw-business-flows:yw-02`:册本调整 +- `yw-business-flows:yw-03`:抄表录入 +- `yw-business-flows:yw-04`:复核开账 +- `yw-business-flows:yw-05`:柜台收费 + +前端实现位置: + +- `../water-frontend/tests/expect/yw-business-flows/scenarios.json` +- `../water-frontend/tests/expect/ywBusinessFlowsScenarios.test.mjs` +- `../water-frontend/tools/expect/acceptance-scenarios.mjs` +- `../water-frontend/tests/expect/README.md` + +## 执行入口 + +```bash +pnpm test:expect:acceptance -- yw-business-flows:all +pnpm test:expect:acceptance -- yw-business-flows:yw-01 +pnpm test:expect:acceptance -- yw-05 +``` + +## 测试数据要求 + +新增场景使用以下测试数据环境变量: + +- `EXPECT_TEST_NEW_CUSTOMER_ARCHIVE` +- `EXPECT_TEST_AVAILABLE_METER` +- `EXPECT_TEST_INVOICE_PROFILE` +- `EXPECT_TEST_ARCHIVED_CUSTOMER` +- `EXPECT_TEST_TARGET_METER_BOOK` +- `EXPECT_TEST_METER_READ_CUSTOMER` +- `EXPECT_TEST_METER_READING_VALUE` +- `EXPECT_TEST_REVIEWABLE_METER_READ_RECORD` +- `EXPECT_TEST_BILLABLE_METER_READ_RECORD` +- `EXPECT_TEST_CHARGED_CUSTOMER` + +并复用: + +- `EXPECT_TEST_ADMIN_USERNAME` +- `EXPECT_TEST_CASHIER_A_USERNAME` + +缺少上述数据时,runner 必须在启动浏览器前返回 `BLOCKED`,不得使用占位符或编造业务记录继续执行。 + +## 验证结果 + +已执行目录契约与 runner 数据门禁验证: + +```bash +node --test tests/expect/ywBusinessFlowsScenarios.test.mjs +``` + +结果:`pass 6 / fail 0`。 + +```bash +pnpm test:expect:acceptance -- --list +``` + +结果:命令退出码 `0`,`yw-business-flows:yw-01` 至 `yw-business-flows:yw-05` 均已列出。 + +```bash +pnpm test:expect:acceptance -- yw-05 --no-dev-server +``` + +结果:命令退出码 `2`,按预期返回: + +- `BLOCKED: missing required acceptance test data for yw-05.` +- 缺少 `EXPECT_TEST_CASHIER_A_USERNAME` +- 缺少 `EXPECT_TEST_CHARGED_CUSTOMER` + +```bash +pnpm test:expect:acceptance -- yw-business-flows:all --no-dev-server +``` + +结果:命令退出码 `2`,按预期返回 `BLOCKED`,缺少全部 5 条 YW 用例所需的账号、客户、册本、水表、抄表、复核开账与柜台收费测试数据。 + +```bash +node --test tests/expect/*.test.mjs +``` + +结果:`pass 30 / fail 0`。 + +### 真实浏览器验收尝试(2026-06-09 12:00 CST) + +```bash +pnpm test:expect:acceptance -- yw-business-flows:all --no-dev-server --timeout 1800000 +``` + +结果:命令退出码 `1`,未形成 `PASS` 业务验收结论。 + +- 已启动真实浏览器并进入 `yw-business-flows:yw-01` 手工建档场景。 +- 浏览器侧可见记录显示已登录并访问 `http://localhost:18080/custData/custCreate`。 +- 运行过程中产生的主要证据: + - `/tmp/expect-artifacts/playwright/page@8c120c0eebb660ecda33437a218d685a.webm` + - `/tmp/expect-artifacts/playwright-results/result-*.json` + - `.expect/logs.md` +- ACP rollout 日志显示:用例在 `yw-01` 内部反复处理 Element Plus 下拉选择器,后续浏览器 transport 关闭。 +- Expect 最终报错: + - `ACP stream inactivity timeout` + - `Streaming failed: Agent produced no output for 180s.` +- 本次运行未进入 `yw-02` 至 `yw-05` 的业务执行阶段。 +- 本次运行中测试数据环境变量虽然已设置,但部分值存在乱码;agent 曾使用自行构造的可读测试数据继续填写。按黑盒验收规则,这不能作为有效 `PASS` 证据。 + +本次真实浏览器验收结论:`BLOCKED` / `FAIL-RUNNER`。阻断原因为 Expect ACP/browser transport 超时,且测试数据可读性不足;业务功能本身尚不能据此判定通过或失败。 + +## 当前结论 + +测试用例已编制为可执行 Expect 黑盒验收场景,目录加载、提示词生成和数据缺失拦截均通过。 + +截至本记录,真实浏览器业务验收已尝试执行,但未形成有效业务通过结论;当前阻断点为测试数据可读性不足与 Expect ACP/browser transport 超时。真实业务场景结论当前仍为 `BLOCKED`,不是 `PASS`。 diff --git a/docs/evidence/bugfix/meter-reading-billing-p0-guard-2026-06-20.md b/docs/evidence/bugfix/meter-reading-billing-p0-guard-2026-06-20.md new file mode 100644 index 0000000..488562a --- /dev/null +++ b/docs/evidence/bugfix/meter-reading-billing-p0-guard-2026-06-20.md @@ -0,0 +1,71 @@ +# 抄表开账 P0 保护修复验证记录 + +- 时间:2026-06-20 15:56:43 +0800 +- 仓库:water-backend +- 分支:develop +- 范围:普通开账前置状态校验、取消开账账单状态保护 + +## 修复内容 + +1. `ChargeServiceImpl.validateReadingDataBeforeBilling` + - 普通批量开账新增前置条件:抄表记录必须为 `CheckStateEnum.REVIEWED`。 + - 已开账或已有营业账记录仍优先返回重复开账错误。 + +2. `ChargeServiceImpl.cancelChargeByReadingDataIds` + - 空入参、无关联营业账时直接返回。 + - 关联营业账存在 `PayStateEnum.PAID` 时禁止取消开账。 + - 关联营业账存在 `PayStateEnum.SETTLED` 时禁止取消开账。 + - 禁止场景下不删除营业账明细和营业账主记录。 + +## 红灯验证 + +新增测试后、修复实现前执行: + +```bash +mvn -pl sw-business/sw-business-server -am -Dtest=ChargeServiceBillingValidationTest -Dsurefire.failIfNoSpecifiedTests=false test +``` + +结果: + +- `cancelChargeByReadingDataIds_shouldRejectPaidCharge` 失败:当前实现未抛异常。 +- `generateChargeBatch_shouldRejectMeterRecordedReadingDataWithoutReview` 失败:当前实现未在校验阶段拦截未复核记录。 + +## 绿灯验证 + +修复后执行: + +```bash +mvn -pl sw-business/sw-business-server -am -Dtest=ChargeServiceBillingValidationTest -Dsurefire.failIfNoSpecifiedTests=false test +``` + +结果: + +- Tests run: 7 +- Failures: 0 +- Errors: 0 +- Skipped: 0 +- BUILD SUCCESS + +补充执行: + +```bash +mvn -pl sw-business/sw-business-server -am -Dtest=ReadingDataServiceImplCheckValidationTest,ChargeServiceBillingValidationTest -Dsurefire.failIfNoSpecifiedTests=false test +``` + +结果: + +- Tests run: 8 +- Failures: 0 +- Errors: 0 +- Skipped: 0 +- BUILD SUCCESS + +编译验证: + +```bash +mvn -pl sw-business/sw-business-server -am -DskipTests compile +``` + +结果: + +- BUILD SUCCESS diff --git a/docs/evidence/bugfix/meter-reading-generate-cycle-bugfix-2026-06-20.md b/docs/evidence/bugfix/meter-reading-generate-cycle-bugfix-2026-06-20.md new file mode 100644 index 0000000..c25c2d0 --- /dev/null +++ b/docs/evidence/bugfix/meter-reading-generate-cycle-bugfix-2026-06-20.md @@ -0,0 +1,92 @@ +# 抄表记录定时生成重复数据修复证据 + +## 背景 + +用户反馈:册本配置为“每月抄”,但每天定时器都会生成可修改、可抄表的抄表记录;同一客户同一账期中一条记录开账结账后,其余记录无法继续开账。 + +## 根因 + +后端存在两个抄表生成入口: + +- `ReadingDataGenerateData`:调用 `ReadingDataService.generateReadingDataForAllBooks()`。 +- `meterReadingGenerateJob`:原先直接在 Job 内组装并插入 `biz_reading_data`、`biz_last_reading`,绕过服务层去重和周期判断。 + +原 `meterReadingGenerateJob` 的实现只查询 `status = 0` 的册本,没有使用 `nextReadDate` 控制当前抄表周期,也没有按 `custId + billMonth` 做重复生成保护,因此定时任务每日执行时可能持续插入同客户同账期抄表记录。 + +开账链路通过同客户同账期有效账单校验防止重复开账,因此同月多条抄表记录中,第一条开账后,其余记录会被“本月已开账/已缴费”规则拦截。 + +## 修复内容 + +1. 将 `meterReadingGenerateJob` 精简为统一委托 `ReadingDataService.generateReadingDataForAllBooks()`,删除 Job 内旧的直接插入抄表数据逻辑。 +2. 在 `ReadingDataServiceImpl.generateReadingDataForAllBooks()` 中,当册本 `nextReadDate` 判定为非当前周期时直接跳过该册本,不再生成“非当前周期”的抄表数据。 +3. 新增回归测试: + - `MeterReadingGenerateJobTest`:验证 `meterReadingGenerateJob` 委托服务层统一入口。 + - `ReadingDataServiceImplGenerateTest`:验证非当前周期册本不会查询客户、不会插入抄表数据。 + +## 验证 + +执行命令: + +```bash +mvn -pl sw-business/sw-business-server -am -Dtest=MeterReadingGenerateJobTest,ReadingDataServiceImplGenerateTest -Dsurefire.failIfNoSpecifiedTests=false test +``` + +验证结果: + +- `Tests run: 2, Failures: 0, Errors: 0, Skipped: 0` +- Reactor 构建结果:`BUILD SUCCESS` +- 验证时间:2026-06-20 15:09:01 +08:00 + +## 影响范围 + +- 后端模块:`sw-business-server` +- 涉及链路:抄表记录定时生成、抄表数据批量生成 +- 不涉及:开账互斥规则、账单生成规则、收费结账逻辑 + +## 追加修复:抄表模块逻辑审查问题 + +### 背景 + +在完成重复生成修复后,继续审查抄表录入模块,发现仍存在若干会放大重复数据、筛选错误或账期误判的逻辑风险。 + +### 修复内容 + +1. `ReadingDataServiceImpl.generateReadingDataForAllBooks()` 增加 JVM 内串行保护,降低两个 XXL-JOB 入口或重复触发在同一应用实例内并发生成同客户同账期抄表记录的风险。 +2. `ReadingDataMapper.selectByCustIdAndBillMonth()`、`selectByCustMeterIdAndBillMonth()` 和 `LastReadingMapper.selectByCustIdAndBillMonth()` 改为 `selectList + order by id desc + limit 1`,避免历史重复数据导致 `selectOne` 抛 `TooManyResultsException`。 +3. `ReadingDataServiceImpl.filterCustMeterIdsByConditions()` 将 `meterStatus` 纳入“水表筛选条件”判断,修复只按水表状态筛选时条件被跳过的问题。 +4. Excel 导入抄表账期改为优先按导入行的 `readDate` 推导账期;未传抄表日期时继续回退当前年月,避免跨月导入误查当前月记录。 + +### 回归测试 + +新增或补充以下测试: + +- `ReadingDataMapperTest` +- `LastReadingMapperTest` +- `ReadingDataServiceImplFilterTest` +- `ReadingDataServiceImplImportTest` +- `ReadingDataServiceImplGenerateTest` + +### 验证 + +执行命令: + +```bash +mvn -pl sw-business/sw-business-server -am -Dtest=ReadingDataServiceImplGenerateTest,ReadingDataMapperTest,LastReadingMapperTest,ReadingDataServiceImplFilterTest,ReadingDataServiceImplImportTest -Dsurefire.failIfNoSpecifiedTests=false test +``` + +验证结果: + +- `Tests run: 9, Failures: 0, Errors: 0, Skipped: 0` +- Reactor 构建结果:`BUILD SUCCESS` +- 验证时间:2026-06-20 15:27:12 +08:00 + +编译验证命令: + +```bash +mvn -pl sw-business/sw-business-server -am -DskipTests compile +``` + +验证结果: + +- Reactor 构建结果:`BUILD SUCCESS` +- 验证时间:2026-06-20 15:27:41 +08:00 diff --git a/docs/evidence/bugfix/revenue-bugfix-clear-scope-2026-06-08.md b/docs/evidence/bugfix/revenue-bugfix-clear-scope-2026-06-08.md new file mode 100644 index 0000000..cb8bbd2 --- /dev/null +++ b/docs/evidence/bugfix/revenue-bugfix-clear-scope-2026-06-08.md @@ -0,0 +1,178 @@ +# 营收明确缺陷第一批修复验证记录 + +日期:2026-06-08 + +## 修复范围 + +- #78 水价调整失败后重试闭环 +- #39 柜台预存缴费进入结账 +- #50 柜台结账收费员筛选 +- #53 预存抵扣校验 +- #58/#59 柜台红冲记录查询 +- #69/#76 待审批账务调整文案 + +## 后端基线 + +- 仓库:water-backend +- Worktree:backend-revenue-bugfix-clear-scope +- 提交:`ba136759b1925789cb0adc18105d00d6928add59` + +## 前端基线 + +- 仓库:water-frontend +- Worktree:frontend-revenue-bugfix-clear-scope +- 提交:`5f7ad7754473541483b26efa324419eb7a5d1a3b` + +## 验证命令与结果 + +### 后端 targeted tests + +```bash +cd /Volumes/Dpan/github/water-workspace/worktrees/backend-revenue-bugfix-clear-scope +mvn -pl sw-business/sw-business-server -Dtest=PriceTemplateServiceImplTest,PriceTemplateAdjustmentLockRedisDAOTest,CounterSettleApplicationServiceImplTest,ChargeServiceImplCounterPrepayTest test +``` + +结果:通过。 + +- Surefire 汇总:`Tests run: 26, Failures: 0, Errors: 0, Skipped: 0` +- Maven 结果:`BUILD SUCCESS` +- 备注:执行期间存在既有 Maven model warning、Mockito dynamic-agent warning;`PriceTemplateServiceImplTest` 中有一段业务代码捕获后记录的 NPE 栈日志,但测试结果为 0 failures / 0 errors。 + +### 后端 compile + +```bash +cd /Volumes/Dpan/github/water-workspace/worktrees/backend-revenue-bugfix-clear-scope +mvn -pl sw-business/sw-business-server -DskipTests compile +``` + +结果:通过。 + +- Maven 结果:`BUILD SUCCESS` + +### 前端 contract test + +```bash +cd /Volumes/Dpan/github/water-workspace/worktrees/frontend-revenue-bugfix-clear-scope +node --test tests/revenue-bugs/revenueBugfixClearScope.contract.test.mjs +``` + +结果:通过。 + +- Node test 汇总:`tests 5`, `pass 5`, `fail 0` + +### 前端 settings contract regression + +```bash +cd /Volumes/Dpan/github/water-workspace/worktrees/frontend-revenue-bugfix-clear-scope +node --test tests/settings/priceTemplateAdjustmentErrorHandling.test.mjs +``` + +结果:通过。 + +- Node test 汇总:`tests 3`, `pass 3`, `fail 0` + +### 前端 type check + +```bash +pnpm ts:check +``` + +结果:未完成,不作为通过项。 + +- 首次执行长时间无诊断输出后以 `[ELIFECYCLE] Command failed.` 退出。 +- 随后按用户明确指令停止继续运行 `vue-tsc` / `pnpm ts:check`。 +- 已终止残留 `vue-tsc` 进程。 + +### 前端 build + +```bash +cd /Volumes/Dpan/github/water-workspace/worktrees/frontend-revenue-bugfix-clear-scope +pnpm build:dev +``` + +结果:通过。 + +- 输出:`Build successful. Please see dist directory` +- 备注:构建期间存在既有 Vite CJS deprecation warning、SVG icon symbolId warning、Rollup PURE annotation warning。 + +## 备注 + +- 前端 worktree 中存在未跟踪 `test-results/*.png` 截图产物,本次未提交。 +- 本轮未处理 #70 和 #9。#70 需抓包确认提交字段;#9 需产品确认抄表状态规则。 + +## Jenkins 构建修复补充记录(2026-06-09) + +### 问题定位 + +- Jenkins `sw-system-cloud-dev-pipeline` 在 `sw-business-server` 编译阶段报出 `*DORef` 缺失、Lombok getter/setter/log 缺失以及 `CounterSettleApplicationServiceImpl.isChargePaymentRecord(...)` 重复定义。 +- 本地复现确认:`PrestorageBpmCallbackService` 已存在 `@Slf4j`,`log` 缺失不是独立代码问题,而是编译异常导致注解处理未完成后的级联报错。 +- 修复 `CounterSettleApplicationServiceImpl` 中重复的 `isChargePaymentRecord(PaymentRecordDO)` 后,`target/generated-sources/annotations` 重新生成 `*DORef.java`,Lombok 相关报错消失。 +- 同一提交引入的 `Collection::stream` 代码缺少 `java.util.Collection` 导入,补齐后编译闭环通过。 + +### 后端修复范围 + +- 仓库:`../water-backend` +- 分支:`develop` +- 基线:`8e42a5123` +- 修改文件:`sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/service/countersettle/CounterSettleApplicationServiceImpl.java` + +### 验证命令与结果 + +```bash +cd /Volumes/Dpan/github/water-workspace/water-backend +mvn -pl sw-business/sw-business-server -am -DskipTests compile +``` + +结果:通过。 + +- Maven 结果:`BUILD SUCCESS` +- 说明:用于确认注解处理恢复,`*DORef` 生成文件重新出现。 + +```bash +cd /Volumes/Dpan/github/water-workspace/water-backend +mvn clean package -DskipTests -T 1C -pl sw-dependencies,sw-framework,sw-gateway,sw-server,sw-module-system,sw-module-infra,sw-module-bpm,sw-module-pay,sw-module-report,sw-business,sw-business-bank,sw-module-member -am +``` + +结果:通过。 + +- Maven 结果:`BUILD SUCCESS` +- 耗时:`01:13 min (Wall Clock)` +- 备注:执行期间仍存在既有 Maven model warning、MapStruct unmapped target warning、Mockito `MockBean` deprecation warning;均未导致构建失败。 + +## Jenkins 构建修复收敛记录(2026-06-09 10:35) + +### 修复收敛结论 + +- 已确认 `8e42a5123 fix: configure sw-common annotation processors` 不是本次 Jenkins 编译失败的根因修复。 +- 已将 `sw-framework/sw-common/pom.xml` 恢复到 `8e42a5123` 之前的注解处理器版本配置,避免保留错误方向的 POM 改动。 +- 最终保留的真实修复为: + - 删除 `CounterSettleApplicationServiceImpl` 中重复定义的 `isChargePaymentRecord(PaymentRecordDO)`。 + - 补齐同文件中 `Collection::stream` 所需的 `java.util.Collection` import。 + +### 后端最终修复范围 + +- 仓库:`../water-backend` +- 分支:`develop` +- 修复前基线:`8e42a5123` +- 后端修复提交:`86203127eeb27fcb1ff8228a89a77eb3a3325c57` +- 修改文件: + - `sw-framework/sw-common/pom.xml` + - `sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/service/countersettle/CounterSettleApplicationServiceImpl.java` + +### 最终验证命令与结果 + +```bash +cd /Volumes/Dpan/github/water-workspace/water-backend +mvn clean package -DskipTests -T 1C -pl sw-dependencies,sw-framework,sw-gateway,sw-server,sw-module-system,sw-module-infra,sw-module-bpm,sw-module-pay,sw-module-report,sw-business,sw-business-bank,sw-module-member -am +``` + +结果:通过。 + +- Maven 结果:`BUILD SUCCESS` +- 耗时:`01:15 min (Wall Clock)` +- 完成时间:`2026-06-09T10:35:31+08:00` +- 关键模块结果: + - `sw-common`: `SUCCESS` + - `sw-business-server`: `SUCCESS` + - `sw-server`: `SUCCESS` +- 备注:验证命令使用 `-DskipTests`,本次结论覆盖编译与打包;测试执行被跳过。 diff --git a/docs/evidence/rev004-accounting/2026-06-10-prestore-test-results.md b/docs/evidence/rev004-accounting/2026-06-10-prestore-test-results.md new file mode 100644 index 0000000..f43adcc --- /dev/null +++ b/docs/evidence/rev004-accounting/2026-06-10-prestore-test-results.md @@ -0,0 +1,59 @@ +# 预存余额功能 — 测试与部署结果 + +> 2026-06-10 | 预存余额 P0-1~P1-2 功能测试验证 + +## 后端编译 + +| 项目 | 结果 | +|------|------| +| `mvn compile -pl sw-business/sw-business-server -am -o` | PASS | +| `mvn package -pl sw-business/sw-business-server -am -o -DskipTests` | PASS (147MB jar) | + +## 后端单元测试 + +| 测试类 | 状态 | 备注 | +|--------|------|------| +| ChargeServiceCounterPaymentTest (7 tests) | 7/7 PASS | 修复了 AccountLogContext + CustBillTypeService mock | +| 其他已有单元测试 (300+ tests) | 全部 PASS | 仅 2 个已有失败 (CustServiceImplCustomerPageTest, PaymentRecordServiceImplTest) 非本次引入 | + +## 新增测试代码 + +| 文件 | 类型 | 编译 | +|------|------|------| +| `test/.../CounterChargeFullChainIntegrationTest.java` (新增方法) | 集成测试 | PASS | +| `test/resources/sql/prestore/01_counter_topup_log_seed.sql` | SQL 种子 | N/A | + +> 集成测试需要 PostgreSQL 环境运行 (`REV004_IT_DB_URL` 等环境变量)。代码已通过编译验证,实际执行待部署环境就绪。 + +## 前端 + +| 项目 | 结果 | +|------|------| +| TypeScript 类型检查 (`tsc --noEmit`) | 新文件无新增错误 | +| dist 构建 | dist/ 已存在 | +| E2E 测试代码 (2 文件) | 已创建,待后端运行后执行 | + +### 新增 E2E 测试 + +| 文件 | 覆盖 | +|------|------| +| `tests/e2e/prestore/counterTopup.e2e.spec.ts` | counterTopup充值流程, 欠费拒绝, counterPreview余额查询 | +| `tests/e2e/prestore/prestorageAdjustBpm.e2e.spec.ts` | 预存调整列表, BPM创建, 详情查询 | + +## 部署就绪项 + +| 产物 | 路径 | +|------|------| +| 后端 JAR | `sw-business/sw-business-server/target/sw-business-server.jar` | +| 前端 dist | `water-frontend/dist/` | +| DDL (PG) | `sql/rev005/REV006_account_log_ddl.sql` | +| DDL (MySQL) | `sql/rev005/REV006_account_log_ddl_mysql.sql` | +| DDL (MySQL) | `sql/rev005/REV006_cust_bill_type_ddl_mysql.sql` | + +## 待执行项 + +1. 部署 PostgreSQL 并执行 DDL +2. 启动后端 (`java -jar sw-business-server.jar --spring.profiles.active=local`) +3. 启动前端 (`pnpm dev`) +4. 运行 Browser 手动冒烟 (按 plan Task 7 清单) +5. 运行 Playwright E2E 测试 (`npx playwright test tests/e2e/prestore/`) diff --git a/docs/evidence/rev004-accounting/REV004_ACCOUNTING_ADJUST_API_DELTA.md b/docs/evidence/rev004-accounting/REV004_ACCOUNTING_ADJUST_API_DELTA.md new file mode 100644 index 0000000..1eecaec --- /dev/null +++ b/docs/evidence/rev004-accounting/REV004_ACCOUNTING_ADJUST_API_DELTA.md @@ -0,0 +1,301 @@ +# REV004 本次新增/增强接口清单 + +## 文档目的 +整理本次 REV004 在后端新增的接口,以及对已有接口的增强点,方便前端联调、测试验收和后续文档沉淀。 + +--- + +## 一、结论概览 + +### 1. 本次真正新增的接口 +本次**真正新增的 HTTP 路由共 4 个**,均为**分账专属接口**: + +1. `POST /admin-api/business/split-adjust/submit` +2. `GET /admin-api/business/split-adjust/page` +3. `GET /admin-api/business/split-adjust/detail` +4. `GET /admin-api/business/split-adjust/result` + +### 2. 本次增强的已有接口 +已有的 `/admin-api/business/accounting-adjust/*` 路由中,本次主要增强了: +- 未销分账提交能力 +- 未销违约金减免提交/批量提交能力 +- 调整详情/分页/日志/流程查询返回字段 +- late-fee formal-table 查询兜底能力 + +--- + +## 二、本次新增接口 + +## 2.1 分账专属提交 +- **方法**:`POST` +- **路径**:`/admin-api/business/split-adjust/submit` +- **作用**:发起分账申请 +- **说明**:与旧的 `accounting-adjust/unsold-split-submit` 相比,这是更明确的分账专属入口 + +### 典型用途 +- 前端分账弹窗直接调用 +- 后续独立分账页或分账台账页调用 + +--- + +## 2.2 分账专属分页 +- **方法**:`GET` +- **路径**:`/admin-api/business/split-adjust/page` +- **作用**:分页查询分账单列表 + +### 典型用途 +- 分账专属列表页 +- 分账查询台账 +- 分账历史记录页 + +--- + +## 2.3 分账专属详情 +- **方法**:`GET` +- **路径**:`/admin-api/business/split-adjust/detail` +- **作用**:查询分账详情 + +### 入参 +- `splitAdjustNo`:分账单号 +- `adjustmentNo`:兼容旧口径的调整单号 + +### 说明 +优先面向新的分账编号口径,同时兼容旧的 `adjustmentNo` 查询方式。 + +--- + +## 2.4 分账执行结果 +- **方法**:`GET` +- **路径**:`/admin-api/business/split-adjust/result` +- **作用**:查询分账执行结果 + +### 入参 +- `splitAdjustNo` +- `adjustmentNo` + +### 典型用途 +- 提交后查看执行状态 +- 审批通过后查看分账结果明细 +- 前端结果弹窗/详情页展示 + +--- + +## 三、本次增强的已有接口 + +## 3.1 未销分账提交 +- **方法**:`POST` +- **路径**:`/admin-api/business/accounting-adjust/unsold-split-submit` + +### 本次增强点 +新增支持: +- `splitItems` + +### 说明 +原先是未销调整页里的分账动作入口,本次增强后可承载更稳定的拆分明细提交语义。 + +--- + +## 3.2 未销违约金减免提交 +- **方法**:`POST` +- **路径**:`/admin-api/business/accounting-adjust/unsold-late-fee-reduce-submit` + +### 本次增强点 +新增支持: +- `applicant` +- `contactMobile` + +### 说明 +用于补齐前端页面上申请人、联系电话等基础申请信息。 + +--- + +## 3.3 未销违约金减免批量提交 +- **方法**:`POST` +- **路径**:`/admin-api/business/accounting-adjust/unsold-late-fee-reduce-batch-submit` + +### 本次增强点 + +#### 外层批量字段 +新增支持: +- `applyReason` +- `remark` +- `applicant` +- `contactMobile` +- `attachmentRefs` +- `lateFeeType` + +#### item 明细字段 +新增支持: +- `startDate` +- `endDate` + +### 说明 +该接口本次补齐了“按金额 / 按日期”两种减免模式所需字段,尤其适用于: +- 批量违约金减免 +- 按日期区间计算减免 +- 提交时保留申请人与联系电话信息 + +--- + +## 3.4 调整详情接口 +- **方法**:`GET` +- **路径**:`/admin-api/business/accounting-adjust/get` + +### 本次增强点 +返回字段增强,且对于 `LATE_FEE_REDUCE`: +- 当仅依赖 operat_log 无法完整聚合时 +- 可回退到 formal-table: + - `biz_latefee_reduce` + - `biz_latefee_reduce_detail` +- 继续组装详情返回 + +### 作用 +保证违约金减免在 formal-table 路线下,详情页仍可稳定展示。 + +--- + +## 3.5 调整分页接口 +- **方法**:`GET` +- **路径**:`/admin-api/business/accounting-adjust/page` + +### 本次增强点 +返回字段增强,便于前端稳定展示状态、原因标签、违约金减免展示字段等。 + +--- + +## 3.6 日志相关接口 +### 典型路径 +- `GET /admin-api/business/accounting-adjust/log-page` +- `GET /admin-api/business/accounting-adjust/log-detail` +- `GET /admin-api/business/accounting-adjust/log-process` +- `GET /admin-api/business/accounting-adjust/log-attachments` + +### 本次增强点 +返回字段增强,支持: +- 更完整的调整状态展示 +- 附件、申请信息、原因标签等展示 +- 对 formal-table / 新标准层字段的兼容展示 + +--- + +## 3.7 预存流程/附件接口 +### 典型路径 +- `GET /admin-api/business/accounting-adjust/prestorage-process` +- `GET /admin-api/business/accounting-adjust/prestorage-attachments` + +### 本次增强点 +返回字段增强,与统一标准层读模型保持一致。 + +--- + +## 四、本次重点新增/增强字段 + +## 4.1 提交类入参字段 + +### 分账相关 +- `splitItems` + +### 违约金减免相关 +- `applicant` +- `contactMobile` +- `lateFeeType` +- `startDate` +- `endDate` + +--- + +## 4.2 查询类返回字段 +本次新增/增强的典型返回字段包括: + +- `runtimeStatus` +- `reasonCodeLabel` +- `lateFeeType` +- `applicant` +- `contactMobile` +- `startDate` +- `endDate` +- `splitExecution` + +### 说明 +其中: +- `runtimeStatus`:统一状态展示口径 +- `reasonCodeLabel`:原因编码对应的人类可读标签 +- `splitExecution`:分账执行摘要/明细 +- `lateFeeType/startDate/endDate`:支撑违约金减免按日期模式展示 + +--- + +## 五、推荐给前端的理解方式 + +## 5.1 新接口 +前端如果做**分账专属页面 / 台账 / 结果页**,建议优先使用: + +- `POST /business/split-adjust/submit` +- `GET /business/split-adjust/page` +- `GET /business/split-adjust/detail` +- `GET /business/split-adjust/result` + +--- + +## 5.2 旧接口增强 +前端如果仍基于原有 `accounting-adjust` 页面编排,则本次应重点关注: + +- `unsold-split-submit`:支持 `splitItems` +- `unsold-late-fee-reduce-submit`:支持 `applicant/contactMobile` +- `unsold-late-fee-reduce-batch-submit`:支持 `lateFeeType/startDate/endDate` 等字段 +- `page/get/log/process/detail` 等查询接口:返回字段增强 + +--- + +## 六、联调建议 + +## 6.1 分账 +### 建议优先联调 +1. `POST /business/split-adjust/submit` +2. `GET /business/split-adjust/detail` +3. `GET /business/split-adjust/result` + +### 适用场景 +- 分账弹窗提交 +- 分账详情页 +- 分账结果回显 + +--- + +## 6.2 违约金减免 +### 建议重点联调 +1. `POST /business/accounting-adjust/unsold-late-fee-reduce-submit` +2. `POST /business/accounting-adjust/unsold-late-fee-reduce-batch-submit` +3. `GET /business/accounting-adjust/get` +4. `GET /business/accounting-adjust/log-process` + +### 建议重点验证 +- `lateFeeType=1`(按金额) +- `lateFeeType=2`(按日期) +- 是否能正确展示 `applicant/contactMobile/startDate/endDate` +- 审批后详情页是否仍能查到 formal-table 路径数据 + +--- + +## 七、当前边界说明 + +## 7.1 已覆盖 +- 分账专属接口新增 +- 未销违约金减免按日期模式关键字段补齐 +- late-fee formal-table 闭环 +- 查询接口的部分标准层字段增强 + +## 7.2 未完全覆盖 +- 其他对象类型(如坏账 / 核销 / 价差)尚未全部走 formal-table 同等级闭环 +- 全量旧页面并未全部迁移到新接口 +- 旧接口仍保留兼容口径 + +--- + +## 八、建议结论 + +如果前端是做: +- **分账专属页面**:优先接 `/business/split-adjust/*` +- **原未销调整页中的分账/违约金减免弹窗**:继续使用 `/business/accounting-adjust/*`,但需按本次新增字段补齐请求/展示 + +--- diff --git a/docs/evidence/rev004-accounting/REV004_ACCOUNTING_ADJUST_FRONTEND_DEBUG_DATA.md b/docs/evidence/rev004-accounting/REV004_ACCOUNTING_ADJUST_FRONTEND_DEBUG_DATA.md new file mode 100644 index 0000000..83f0677 --- /dev/null +++ b/docs/evidence/rev004-accounting/REV004_ACCOUNTING_ADJUST_FRONTEND_DEBUG_DATA.md @@ -0,0 +1,276 @@ +# REV004 前端联调测试数据说明 + +## 目的 +为 REV004 本次新增/增强的接口提供一套**可直接用于前端联调**的测试数据,重点覆盖: +- 分账专属接口 +- 未销违约金减免(成功 / 待审批) +- `accounting-adjust` 兼容查询链路 + +对应后端脚本: +- `water-backend/sql/rev004/REV004_accounting_adjust_frontend_debug_seed.sql` + +--- + +## 一、数据设计原则 + +本次联调数据重点保证: +1. **客户 / 账户 / 营业账** 有真实关联 +2. **分账主表 / 明细表 / 子账单** 有真实关联 +3. **违约金减免主表 / 明细表 / 营业账 / 营业账明细** 有真实关联 +4. **operat_log / operat_log_detail** 能支撑旧查询接口联调 +5. 成功态、待审批态同时具备,方便前端测状态切换与展示分支 + +--- + +## 二、可直接使用的样例数据 + +## 2.1 分账成功样例 + +### 关键标识 +- `splitAdjustNo = REV004-SPLIT-API-001` +- `adjustmentNo = REV004-SPLIT-API-001` +- `sourceChargeId = 920101` +- `customerCode = REV004_FE_SPLIT_CUST` + +### 数据关系 +- 源账单:`920101` +- 分账主单:`920301` +- 分账明细: + - `920311` + - `920312` + - `920313` +- 子账单: + - `920102` + - `920103` + - `920104` + +### 业务语义 +- 原账单水量:`9.000` +- 分成 3 笔 +- 每笔水量:`3.000` +- 每笔金额:`60.00` +- 状态:**审批通过 + 执行成功** + +### 适合联调的接口 +- `GET /admin-api/business/split-adjust/page` +- `GET /admin-api/business/split-adjust/detail?splitAdjustNo=REV004-SPLIT-API-001` +- `GET /admin-api/business/split-adjust/result?splitAdjustNo=REV004-SPLIT-API-001` +- `GET /admin-api/business/accounting-adjust/get?adjustmentNo=REV004-SPLIT-API-001` + +--- + +## 2.2 违约金减免成功样例 + +### 关键标识 +- `adjustmentNo = REV004-LATEFEE-API-001` +- `chargeId = 920105` +- `customerCode = REV004_FE_LATE_CUST` + +### 数据关系 +- 客户:`920002` +- 营业账:`920105` +- 营业账明细:`9201001` +- 违约金减免主单:`920401` +- 违约金减免明细:`920411` +- request log:`920511` +- approve log:`920512` + +### 业务语义 +- 违约金减免类型:`2`(按日期) +- 起算日期:`2026-04-01` +- 截止日期:`2026-04-30` +- 理论调整前违约金:`18.00` +- 减免金额:`6.00` +- 调整后违约金:`12.00` +- 状态:**审批通过 + 执行成功** + +### 适合联调的接口 +- `GET /admin-api/business/accounting-adjust/get?adjustmentNo=REV004-LATEFEE-API-001` +- `GET /admin-api/business/accounting-adjust/logs?adjustmentNo=REV004-LATEFEE-API-001` +- `GET /admin-api/business/accounting-adjust/log-detail?adjustmentNo=REV004-LATEFEE-API-001` +- `GET /admin-api/business/accounting-adjust/log-process?adjustmentNo=REV004-LATEFEE-API-001` + +--- + +## 2.3 违约金减免待审批样例 + +### 关键标识 +- `adjustmentNo = REV004-LATEFEE-API-002` +- `chargeId = 920106` +- `customerCode = REV004_FE_PENDING_CUST` + +### 数据关系 +- 客户:`920003` +- 营业账:`920106` +- 营业账明细:`9201002` +- 违约金减免主单:`920402` +- 违约金减免明细:`920412` +- request log:`920521` + +### 业务语义 +- 违约金减免类型:`1`(按金额) +- 减免金额:`5.00` +- 状态:**待审批** + +### 适合联调的接口 +- `GET /admin-api/business/accounting-adjust/get?adjustmentNo=REV004-LATEFEE-API-002` +- `GET /admin-api/business/accounting-adjust/page` +- `GET /admin-api/business/accounting-adjust/log-page` + +--- + +## 三、接口调试建议 + +## 3.1 分账专属接口 + +### 分页 +```http +GET /admin-api/business/split-adjust/page?pageNo=1&pageSize=10 +``` + +### 详情 +```http +GET /admin-api/business/split-adjust/detail?splitAdjustNo=REV004-SPLIT-API-001 +``` + +### 执行结果 +```http +GET /admin-api/business/split-adjust/result?splitAdjustNo=REV004-SPLIT-API-001 +``` + +--- + +## 3.2 账务调整兼容查询接口 + +### 调整详情 +```http +GET /admin-api/business/accounting-adjust/get?adjustmentNo=REV004-LATEFEE-API-001 +GET /admin-api/business/accounting-adjust/get?adjustmentNo=REV004-LATEFEE-API-002 +GET /admin-api/business/accounting-adjust/get?adjustmentNo=REV004-SPLIT-API-001 +``` + +### 调整分页 +```http +GET /admin-api/business/accounting-adjust/page?pageNo=1&pageSize=20 +``` + +### 调整日志 +```http +GET /admin-api/business/accounting-adjust/logs?adjustmentNo=REV004-LATEFEE-API-001 +``` + +--- + +## 3.3 未销兼容查询 + +### 查询分账源客户 +```http +GET /admin-api/business/accounting-adjust/unsold-page?pageNo=1&pageSize=20&code=REV004_FE_SPLIT_CUST +``` + +### 查询违约金客户 +```http +GET /admin-api/business/accounting-adjust/unsold-page?pageNo=1&pageSize=20&code=REV004_FE_LATE_CUST +``` + +### 查询待审批违约金客户 +```http +GET /admin-api/business/accounting-adjust/unsold-page?pageNo=1&pageSize=20&code=REV004_FE_PENDING_CUST +``` + +--- + +## 四、如果前端要直接提交流程 + +## 4.1 可用于新发起分账的源账单 +- `sourceChargeId = 920101` + +### 对应源账单条件 +- 水量:`9.000` +- 适合拆成 3 笔,每笔 `3.000` + +### 示例请求 +```json +{ + "sourceChargeId": 920101, + "applicant": "前端调试员", + "contactMobile": "13900009999", + "reasonCode": "1", + "remark": "前端直接调试新分账", + "attachmentRefs": ["split-fe-debug-1"], + "splitItems": [ + { "seqNo": 1, "splitWater": 3.000 }, + { "seqNo": 2, "splitWater": 3.000 }, + { "seqNo": 3, "splitWater": 3.000 } + ] +} +``` + +--- + +## 4.2 可用于新发起违约金减免的源账单 + +### 成功样例源账单 +- `chargeId = 920105` + +### 待审批样例源账单 +- `chargeId = 920106` + +### 注意 +这两笔账单都补了: +- `biz_charge.late_fee_begin_date` +- `biz_charge_detail` +- `biz_charge_detail.cost_component_code = 101` + +而 `biz_cost_component.code = 101` 在测试库里已有: +- `penalty_coefficient = 0.0010` + +因此可以支撑 `lateFeeType=2` 的按日期计算调试。 + +### 示例请求(按日期) +```json +{ + "lateFeeType": "2", + "applicant": "前端调试员", + "contactMobile": "13800009999", + "applyReason": "1", + "remark": "前端直接调试按日期减免", + "attachmentRefs": ["latefee-fe-debug-1"], + "items": [ + { + "chargeId": 920105, + "startDate": "2026-04-01", + "endDate": "2026-04-30" + } + ] +} +``` + +--- + +## 五、执行方式 + +如需把这套联调数据写入测试库,可执行: + +```bash +PGPASSWORD='Em@123456' \ +psql -h 192.168.10.130 -p 5436 -U sw_system -d sw_system \ + -v ON_ERROR_STOP=1 \ + -f /Volumes/Dpan/github/water-workspace/water-backend/sql/rev004/REV004_accounting_adjust_frontend_debug_seed.sql +``` + +--- + +## 六、当前结论 + +这套数据已经覆盖了前端最常见的三类场景: +1. **分账成功态** +2. **违约金减免成功态** +3. **违约金减免待审批态** + +同时兼顾: +- 新增分账专属接口 +- 旧 `accounting-adjust` 兼容查询接口 +- 申请态 / 审批态 / 执行态的展示联调 + +--- diff --git a/docs/guides/REV004_ACCOUNTING_EXECUTION_PLAYBOOK.md b/docs/evidence/rev004-accounting/REV004_ACCOUNTING_EXECUTION_PLAYBOOK.md similarity index 100% rename from docs/guides/REV004_ACCOUNTING_EXECUTION_PLAYBOOK.md rename to docs/evidence/rev004-accounting/REV004_ACCOUNTING_EXECUTION_PLAYBOOK.md diff --git a/docs/evidence/rev004-accounting/REV004_CURRENT_TRUTH_MATRIX.md b/docs/evidence/rev004-accounting/REV004_CURRENT_TRUTH_MATRIX.md new file mode 100644 index 0000000..6eda2da --- /dev/null +++ b/docs/evidence/rev004-accounting/REV004_CURRENT_TRUTH_MATRIX.md @@ -0,0 +1,90 @@ +# REV004 当前主线真值矩阵 + +## 主线基线 +- backend:`sw-system-cloud/develop @ 9462f3a12728b83bfe31e0b74c526f4256f5b361` +- docs:`fujian_water_biz_doc/main @ b5efa3b2480b1a0b8a00b728ac434f833787b6b4` +- 生成时间:`2026-04-17 15:00 +08:00` + +## 一、对象总览 + +| 对象 | objectType / 专属域 | formal-table 状态 | 主表 / 明细表 | 主接口状态 | strict formal-first 状态 | +|---|---|---|---|---|---| +| 预存调整 | prestorage | 已独立 | `biz_prestorage_adjust` / `biz_prestorage_adjust_detail` | 已接线 | 部分完成 | +| 坏账调整 | `BAD_DEBT_RECORD` | 已独立 | `biz_bad_debt_adjust` / `biz_bad_debt_adjust_detail` | 已接线 | 主链路完成 | +| 已销调整/核销 | `WRITTENOFF_ADJUST` | 已独立 | `biz_writtenoff_adjust` / `biz_writtenoff_adjust_detail` | 已接线 | 主链路完成 | +| 违约金减免 | `LATE_FEE_REDUCE` | 已独立 | `biz_latefee_reduce` / `biz_latefee_reduce_detail` | 已接线 | 主链路完成 | +| 分账调整 | `SPLIT_ADJUST` | 已独立 | `biz_split_adjust` / `biz_split_adjust_detail` | 已接线 | 专属接口完成 | +| 价差调整 | `PRICE_DIFF_ADJUST` | 未独立 | 无 | 兼容接口 | 未完成 | +| 红冲记录 | `REDINK_RECORD` | 未独立 | 无 | 兼容接口 | 未完成 | + +## 二、已独立对象明细 + +### 1. 预存调整(退款 / 转账) +- DDL:`sql/rev004/REV004_prestorage_formal_tables_deploy.sql` +- 表:`biz_prestorage_adjust`、`biz_prestorage_adjust_detail` +- 接口: + - `POST /admin-api/business/accounting-adjust/prestorage-submit` + - `POST /admin-api/business/accounting-adjust/prestorage-revoke` + - `GET /admin-api/business/accounting-adjust/prestorage-process` + - `GET /admin-api/business/accounting-adjust/prestorage-attachments` + - `GET /admin-api/business/accounting-adjust/prestorage-page` + - `GET /admin-api/business/accounting-adjust/prestorage-detail` +- 当前判断: + - submit / revoke / page / detail 已是 formal-table 主链路 + - `process / attachments` 仍保留 legacy / unified fallback + +### 2. 坏账调整 +- DDL:`sql/rev004/REV004_bad_debt_formal_tables_deploy.sql` +- 表:`biz_bad_debt_adjust`、`biz_bad_debt_adjust_detail` +- 接线口径:统一 `accounting-adjust` submit / approve / reject / page / detail +- 当前判断:主链路已 formal-first + +### 3. 已销调整 / 核销 +- DDL:`sql/rev004/REV004_writtenoff_formal_tables_deploy.sql` +- 表:`biz_writtenoff_adjust`、`biz_writtenoff_adjust_detail` +- 接口: + - `POST /admin-api/business/accounting-adjust/sold-submit` + - `POST /admin-api/business/accounting-adjust/approve` + - `POST /admin-api/business/accounting-adjust/reject` + - `GET /admin-api/business/accounting-adjust/get` + - `GET /admin-api/business/accounting-adjust/page` +- 当前判断:主链路已 formal-first,且已补事务边界 / fail-fast + +### 4. 违约金减免 +- DDL:`sql/rev004/REV004_latefee_formal_tables_deploy.sql` +- 表:`biz_latefee_reduce`、`biz_latefee_reduce_detail` +- 接口: + - `POST /admin-api/business/accounting-adjust/unsold-late-fee-reduce-submit` + - `POST /admin-api/business/accounting-adjust/unsold-late-fee-reduce-batch-submit` +- 当前判断:formal-table 主链路已建立 + +### 5. 分账调整 +- 表:`biz_split_adjust`、`biz_split_adjust_detail` +- 专属接口: + - `POST /business/split-adjust/submit` + - `GET /business/split-adjust/page` + - `GET /business/split-adjust/detail` + - `GET /business/split-adjust/result` +- 当前判断:已独立为专属对象域 +- 备注:`sql/rev004/` 目录下当前未看到单独 split deploy 脚本,说明库结构来源可能更早或另有维护路径 + +## 三、未独立对象 + +### 1. 价差调整 `PRICE_DIFF_ADJUST` +- 当前仍主要走兼容接口 / 统一日志骨架 +- 尚未见独立 `biz_price_diff_adjust` / `detail` 正式主从表 + +### 2. 红冲记录 `REDINK_RECORD` +- 当前未见独立 formal-table 主线 +- 仍属于兼容口径对象 + +## 四、当前最适合的后续优先级 +1. `PRICE_DIFF_ADJUST` formal-table +2. prestorage `process / attachments` strict formal-first 收口 +3. 统一补一版“对象 → 表 → 接口 → 真值口径”对外联调说明 + +## 五、证据锚点 +- backend 已合入:PR #77,merge sha=`9462f3a12728b83bfe31e0b74c526f4256f5b361` +- docs 已合入:merge sha=`b5efa3b2480b1a0b8a00b728ac434f833787b6b4` +- writtenoff fresh smoke evidence:`docs/evidence/rev004-writtenoff-formal-table-dev-db-apply-2026-04-17.md` +- formal-table 状态矩阵:`docs/guides/REV004_FORMAL_TABLE_STATUS_MATRIX.md` diff --git a/docs/guides/REV004_DICT_BINDING_MATRIX.md b/docs/evidence/rev004-accounting/REV004_DICT_BINDING_MATRIX.md similarity index 100% rename from docs/guides/REV004_DICT_BINDING_MATRIX.md rename to docs/evidence/rev004-accounting/REV004_DICT_BINDING_MATRIX.md diff --git a/docs/guides/REV004_FORMAL_TABLE_STATUS_MATRIX.md b/docs/evidence/rev004-accounting/REV004_FORMAL_TABLE_STATUS_MATRIX.md similarity index 100% rename from docs/guides/REV004_FORMAL_TABLE_STATUS_MATRIX.md rename to docs/evidence/rev004-accounting/REV004_FORMAL_TABLE_STATUS_MATRIX.md diff --git a/docs/evidence/rev004-accounting/REV004_FRONTEND_IMPLEMENTATION_HANDOFF.md b/docs/evidence/rev004-accounting/REV004_FRONTEND_IMPLEMENTATION_HANDOFF.md new file mode 100644 index 0000000..0e7189d --- /dev/null +++ b/docs/evidence/rev004-accounting/REV004_FRONTEND_IMPLEMENTATION_HANDOFF.md @@ -0,0 +1,299 @@ +# REV-004 前端实现交接清单 + +## 1. 文档定位 + +本文用于将 `REV-004` 前端实现方案转为可直接分发给前端实现 Agent 的正式 handoff 文档。 + +当前定位: +- 仅覆盖 **管理后台** +- 不覆盖微网厅 / 客户端实现 +- 用于后续在 `../water-frontend` 目录通过 `omx team` / `$team` 推进实现 + +## 2. 当前统一口径 + +### 2.1 已确认范围 + +本轮前端实现只覆盖: + +- REV-004 管理后台统一入口页 +- REV-004 核心对象业务页 +- REV-004 扩展对象业务页 +- REV-004 历史核查 / 对账页 +- 审批状态 / 结果展示通用组件 +- 前后端联调与口径校验 + +### 2.2 明确不纳入本轮范围 + +以下内容不属于本轮前端实现: + +- 微网厅页面实现 +- 客户端交易页实现 +- 客户端审批页实现 +- 客户端对象化菜单管理能力 +- 完整 BPM 流程前端实现 + +### 2.3 风格与实现原则 + +本轮采用折中策略: + +- 核心操作路径尽量像旧系统 +- 页面组织以当前前端风格为主 +- 延续当前 **菜单级独立页面 + 查询区 + 表格区 + Dialog/Drawer 办理** 范式 +- 但 REV-004 必须比当前更对象化、更清晰 +- 不重做成完全不同的一套前端范式 + +## 3. 页面分层方案 + +### 3.1 统一入口层 + +统一入口页只负责: + +- 对象导航 +- 待办汇总 +- 常用入口 +- 状态聚合 + +约束: +- **不承载主办理表单** +- **不承载复杂对象编辑** + +### 3.2 对象业务页层 + +#### 第一档独立菜单页(冻结清单) + +- 预存退款 +- 红冲记录 +- 已销调整 +- 坏账 + +#### 第二档共享扩展页 / 共享查询骨架(冻结清单) + +- 价差调整 +- 违约金减免 +- 分账调整 +- 特账 / 特殊开账 + +默认规则: +- 除第一档对象外,其余对象本轮不得新增顶层菜单 + +### 3.3 历史与核查层 + +- 退款账结果查询 +- 跨周期水量查询 +- 历史账务台账 / 迁移核查页 +- 对账与差异定位页 + +## 4. 页面粒度要求 + +页面按以下粒度组织: + +- **列表页**:查询、筛选、导出、批量操作 +- **办理弹窗 / 抽屉**:新增、调整、撤销、审批动作 +- **详情页 / 详情抽屉**:单据详情、留痕、审批状态、附件 +- **结果页 / 查询页**:退款账、跨周期水量、历史台账、迁移核查 + +## 5. 通用组件要求 + +建议统一复用 / 补齐以下组件: + +- `AccountingObjectHeader` +- `AccountingStatusPanel` +- `AccountingResultSummary` +- `AccountingApprovalBadge` +- `AccountingAttachmentPanel` +- `AccountingDiffTable` + +基础模板继续沿用: + +- `ContentWrap` +- 查询表单(`el-form`) +- 结果表格(`EnhancedTable` / `el-table`) +- `Dialog` / `Drawer` + +## 6. 最小交付件 + +执行前或执行中,至少需要形成以下 4 类交付件: + +### 6.1 页面清单 +字段最小结构: +- 页面名称 +- 页面类型 +- 对应对象 +- 当前状态(现有 / 复用 / 待新增) + +### 6.2 路由清单 +字段最小结构: +- 路由路径 +- 页面归属 +- 菜单归属 +- 是否顶层菜单 + +### 6.3 通用组件清单 +字段最小结构: +- 组件名 +- 用途 +- 复用页面 +- 是否新建 + +### 6.4 lane ownership 清单 +字段最小结构: +- lane 名称 +- 负责目录与页面 +- 负责组件 +- 前置依赖 + +## 7. 四张正式执行表 + +### 7.1 页面清单(冻结版) + +| 页面名称 | 页面类型 | 对应对象/用途 | 当前状态 | 目录/文件建议 | 说明 | +|---|---|---|---|---|---| +| REV-004 统一工作台 | 工作台页 | 统一入口、对象导航、待办汇总 | 待新增 | `src/views/accountProcess/index.vue` | 只做导航/聚合,不承载主办理表单 | +| 预存退款页 | 列表页 + 办理弹窗 + 详情 | `PrepaidRefund` | 现有(需口径收敛) | `src/views/accountProcess/prestorageAdjustment/index.vue` / `detail.vue` | 当前名称偏“预存调整”,需向预存退款对象口径收敛 | +| 红冲记录页 | 列表页 + 详情 | `RedinkRecord` | 现有 | `src/views/operatingCharges/redReversalRecord/index.vue` | 保留旧系统熟悉路径 | +| 已销调整页 | 列表页 + 办理弹窗 | `WrittenoffAdjust` | 现有 | `src/views/accountProcess/soldAdjustment/index.vue` | 作为第一档独立菜单页保留 | +| 坏账页 | 列表页 + 办理弹窗 | `BadDebtRecord` | 可复用 | `src/views/accountProcess/unsoldAdjustment/index.vue` + `components/BadDebtAdjustmentForm.vue` | 建议从未销调整页骨架中拆出独立坏账页 | +| 价差调整扩展页 | 共享扩展页 + 办理弹窗 | `PriceDiffAdjust` | 可复用 | `src/views/accountProcess/unsoldAdjustment/index.vue` + `components/PriceAdjustmentForm.vue` | 第二档共享扩展对象 | +| 违约金减免扩展页 | 共享扩展页 + 办理弹窗 | `LateFeeReduce` | 可复用 | `src/views/accountProcess/unsoldAdjustment/index.vue` + `components/PenaltyRemissionForm.vue` | 第二档共享扩展对象 | +| 分账调整扩展页 | 共享扩展页 + 办理弹窗 | `SplitAdjust` | 可复用 | `src/views/accountProcess/unsoldAdjustment/index.vue` + `components/SplitAdjustmentForm.vue` | 第二档共享扩展对象 | +| 特账 / 特殊开账页 | 列表页 / 查询页 | `SPECIAL_BILLING` | 现有(需边界重写) | `src/views/operatingCharges/specialAccountOpening/index.vue` | 保留“特殊开账”旧路径,但以当前前端组织为主 | +| 退款账结果查询页 | 结果页 / 查询页 | `RefundBill` | 待新增 | 建议 `src/views/accountProcess/refundBill/index.vue` | 只做查询与结果消费,不做主办理入口 | +| 跨周期水量查询页 | 查询页 | `CrossCycleWaterRecord` | 待新增 | 建议 `src/views/accountProcess/crossCycleWater/index.vue` | 只做查询/核查,不做强流程办理页 | +| 历史账务核查页 | 核查页 | 历史账务迁移核查 | 待新增 | 建议 `src/views/accountProcess/historyAudit/index.vue` | 用于现有/历史/目标口径差异定位 | +| 对账与差异定位页 | 核查页 | 结果差异、单据级定位 | 待新增 | 建议 `src/views/accountProcess/reconcileDiff/index.vue` | 偏联调与验收,不做业务办理 | + +### 7.2 路由清单(建议版) + +| 路由路径 | 页面归属 | 菜单归属 | 是否顶层菜单 | 当前状态 | 说明 | +|---|---|---|---|---|---| +| `/account-process` | REV-004 统一工作台 | 账务处理 | 否 | 待新增 | 工作台入口,聚合导航 | +| `/account-process/prestorage-adjustment` | 预存退款页 | 账务处理 | 是 | 现有 | 建议保留现有路径或做别名兼容 | +| `/operating-charges/red-reversal-record` | 红冲记录页 | 营业收费/账务处理 | 是 | 现有 | 可保留原有菜单认知 | +| `/account-process/sold-adjustment` | 已销调整页 | 账务处理 | 是 | 现有 | 第一档冻结对象 | +| `/account-process/bad-debt` | 坏账页 | 账务处理 | 是 | 待新增 | 从未销调整骨架中拆出 | +| `/account-process/adjustment-extension/price-diff` | 价差调整扩展页 | 账务处理扩展 | 否 | 待新增 | 第二档共享扩展对象 | +| `/account-process/adjustment-extension/late-fee-reduce` | 违约金减免扩展页 | 账务处理扩展 | 否 | 待新增 | 第二档共享扩展对象 | +| `/account-process/adjustment-extension/split-adjust` | 分账调整扩展页 | 账务处理扩展 | 否 | 待新增 | 第二档共享扩展对象 | +| `/operating-charges/special-account-opening` | 特账 / 特殊开账页 | 营业收费 | 否 | 现有 | 以特殊开账旧路径承接 | +| `/account-process/refund-bill` | 退款账结果查询页 | 历史与核查 | 否 | 待新增 | 结果对象查询出口 | +| `/account-process/cross-cycle-water` | 跨周期水量查询页 | 历史与核查 | 否 | 待新增 | 基础支撑对象查询出口 | +| `/account-process/history-audit` | 历史账务核查页 | 历史与核查 | 否 | 待新增 | 迁移核查主入口 | +| `/account-process/reconcile-diff` | 对账与差异定位页 | 历史与核查 | 否 | 待新增 | 联调/验收差异定位 | + +### 7.3 通用组件清单(冻结版) + +| 组件名 | 用途 | 复用页面 | 当前状态 | 说明 | +|---|---|---|---|---| +| `AccountingObjectHeader` | 对象标题、对象摘要、入口动作 | 统一工作台、对象列表页、详情页 | 待新增 | 统一对象头部表达 | +| `AccountingStatusPanel` | 结果状态 / 回写状态 / 业务状态面板 | 核心对象页、扩展对象页、核查页 | 待新增 | 状态统一展示 | +| `AccountingResultSummary` | 金额/水量/笔数汇总 | 列表页、核查页 | 待新增 | 可复用 `el-descriptions` 风格 | +| `AccountingApprovalBadge` | 审批状态 Tag / 摘要 | 对象列表页、详情页 | 待新增 | 不展开完整 BPM,只展示边界 | +| `AccountingAttachmentPanel` | 附件、留痕、资料展示 | 详情页、核查页 | 待新增 | 统一附件区 | +| `AccountingDiffTable` | 金额/水量前后差异表 | 已销调整、价差调整、分账调整、核查页 | 待新增 | 差异定位核心组件 | +| `AdjustmentForm` | 预存调整/退款办理弹窗 | `prestorageAdjustment` | 现有 | 可复用并收敛命名 | +| `SoldAdjustmentForm` | 已销调整办理弹窗 | `soldAdjustment` | 现有 | 可直接复用 | +| `BadDebtAdjustmentForm` | 坏账办理弹窗 | `unsoldAdjustment` / 坏账页 | 现有(待抽出) | 建议抽离到坏账页目录 | +| `PenaltyRemissionForm` | 违约金减免办理弹窗 | 扩展对象页 | 现有(可复用) | 第二档共享组件 | +| `PriceAdjustmentForm` | 价差调整办理弹窗 | 扩展对象页 | 现有(可复用) | 第二档共享组件 | +| `SplitAdjustmentForm` | 分账调整办理弹窗 | 扩展对象页 | 现有(可复用) | 第二档共享组件 | + +### 7.4 lane ownership 清单(冻结版) + +| lane | 负责目录与页面 | 负责组件 | 前置依赖 | 说明 | +|---|---|---|---|---| +| Lane A | `src/views/accountProcess/index.vue`(若新建) | 导航卡片、入口汇总组件 | 无 | 统一入口只做导航/聚合 | +| Lane B | `src/views/accountProcess/prestorageAdjustment/*`、`src/views/operatingCharges/redReversalRecord/*`、`src/views/accountProcess/soldAdjustment/*`、坏账页目录 | 预存退款、红冲、已销、坏账相关组件 | 接口对象命名冻结 | 第一档独立菜单对象 | +| Lane C | 价差调整、违约金减免、分账调整、特账相关目录(待新增或共享) | `PriceAdjustmentForm`、`PenaltyRemissionForm`、`SplitAdjustmentForm`、扩展页头部组件 | Lane B 对象模式稳定 | 第二档共享扩展对象 | +| Lane D | `src/views/accountProcess/refundBill/*`、`src/views/accountProcess/crossCycleWater/*`、`src/views/accountProcess/historyAudit/*`、`src/views/accountProcess/reconcileDiff/*`(建议) | `AccountingResultSummary`、`AccountingDiffTable`、核查类组合组件 | 接口查询口径稳定 | 历史与核查层 | +| Lane E | 通用组件目录(建议 `src/components/accounting/*`) | `AccountingStatusPanel`、`AccountingApprovalBadge`、`AccountingAttachmentPanel` | 状态枚举初版冻结 | 通用状态/审批/附件组件 | +| Lane F | 联调与验证脚本/样例/映射文档 | 接口映射、枚举校验、验收样例 | A/B/C/D/E 页面骨架形成 | 贯穿联调与验收 | + +## 8. `omx team` 执行建议 + +### 8.1 执行目录 + +在以下目录执行: + +- `../water-frontend` + +### 8.2 并行顺序 + +- `Lane A / B / D / E` 可先并行 +- `Lane C` 在 `Lane B` 的对象模式稳定后进入 +- `Lane F` 最后贯穿联调与验收 + +### 8.3 执行前提 + +执行前必须明确: + +- 先冻结 **IA(信息架构)**:页面分层、菜单分组、导航关系 +- 后冻结 **DTO / 状态细节** +- 联调阶段允许通过 `Lane F` 对接口字段、审批状态、结果枚举做受控收敛 +- 不允许反向推翻已冻结的页面分层 + +## 9. 任务包建议 + +### Agent A:统一入口页 +负责: +- 统一工作台页 +- 导航聚合 +- 待办与快捷入口 + +### Agent B:核心对象页 +负责: +- 预存退款 +- 红冲记录 +- 已销调整 +- 坏账 + +### Agent C:扩展对象页 +负责: +- 价差调整 +- 违约金减免 +- 分账调整 +- 特账 / 特殊开账 + +### Agent D:历史核查 / 对账页 +负责: +- 退款账结果查询 +- 跨周期水量查询 +- 历史账务核查页 +- 差异定位页 + +### Agent E:审批状态 / 结果组件 +负责: +- 审批状态展示 +- 结果状态展示 +- 留痕 / 附件通用区 + +### Agent F:联调与口径校验 +负责: +- 接口口径映射 +- 枚举统一 +- 页面与接口返回一致性校验 +- 验收样例整理 + +## 10. 验证要求 + +执行前 / 执行中至少检查: + +1. 是否明确区分: + - 当前已有页面 + - 可复用页面 + - 待新增页面 +2. 是否明确区分: + - 第一档独立菜单对象 + - 第二档共享扩展对象 +3. 统一入口是否只做导航 / 汇总,不承担主办理表单 +4. 是否把目标态误写成当前已实现页面 +5. `omx team` lane ownership 是否清晰,不会并行踩文件 + +## 11. 需求依据 + +- `.omx/plans/2026-04-07-rev004-frontend-implementation-plan.md` +- `.omx/specs/deep-interview-rev004-frontend-modules.md` +- `docs/design/02_Detailed_Design/12_REV_Detailed.md` +- `docs/design/03_Technical_Design/01_Database_Design.md` +- `docs/design/03_Technical_Design/03_Interface_Design.md` +- `docs/design/01_Overview/03_Summary_Design.md` +- `docs/guides/REV004_FULL_ACCOUNTING_DOMAIN_DESIGN.md` diff --git a/docs/evidence/rev004-accounting/REV004_FRONTEND_OMX_TEAM_PROMPTS.md b/docs/evidence/rev004-accounting/REV004_FRONTEND_OMX_TEAM_PROMPTS.md new file mode 100644 index 0000000..3d07d3a --- /dev/null +++ b/docs/evidence/rev004-accounting/REV004_FRONTEND_OMX_TEAM_PROMPTS.md @@ -0,0 +1,363 @@ +# REV-004 前端 OMX Team 执行提示词 + +## 1. 使用说明 + +本文用于在 `../water-frontend` 目录直接启动 `omx team` / `$team` 时,作为 leader 与各 lane 的执行提示词模板。 + +适用范围: +- **仅管理后台** +- 不包含微网厅 / 客户端实现 +- 需求依据以正式文档与 handoff 为准,不以旧手册直接替代正式设计 + +执行前固定输入依据: +- `docs/guides/REV004_FRONTEND_IMPLEMENTATION_HANDOFF.md` +- `.omx/plans/2026-04-07-rev004-frontend-implementation-plan.md` +- `.omx/specs/deep-interview-rev004-frontend-modules.md` +- `docs/design/02_Detailed_Design/12_REV_Detailed.md` +- `docs/design/03_Technical_Design/01_Database_Design.md` +- `docs/design/03_Technical_Design/03_Interface_Design.md` +- `docs/design/01_Overview/03_Summary_Design.md` + +--- + +## 2. Leader 启动 Prompt + +```text +任务:REV-004 管理后台前端实现 + +工作目录:../water-frontend + +本轮范围: +1. 统一入口页 +2. 核心对象页(预存退款、红冲记录、已销调整、坏账) +3. 扩展对象页(价差调整、违约金减免、分账调整、特账/特殊开账) +4. 历史核查 / 对账页(退款账结果、跨周期水量、历史账务核查、差异定位) +5. 审批状态 / 结果展示组件 +6. 联调与口径校验 + +严格约束: +- 仅做管理后台,不做微网厅 / 客户端 +- 保持当前前端范式:菜单级独立页面 + 查询区 + 表格区 + Dialog/Drawer 办理 +- 核心操作路径尽量像旧系统,但页面组织以当前前端风格为主 +- 统一入口页只做导航 / 聚合 / 快捷入口,不承载主办理表单 +- 第一档独立菜单对象冻结为:预存退款、红冲记录、已销调整、坏账 +- 第二档共享扩展对象冻结为:价差调整、违约金减免、分账调整、特账/特殊开账 +- 除第一档对象外,其余对象本轮不得新增顶层菜单 +- 不得把目标态写成当前已落地事实 + +交付件要求: +1. 页面清单 +2. 路由清单 +3. 通用组件清单 +4. lane ownership 清单 +5. 实际代码变更 +6. 验证结果 + +执行前提: +- 先冻结 IA(页面分层、菜单分组、导航关系) +- 后冻结 DTO / 状态细节 +- 联调阶段允许收敛接口字段、审批状态、结果枚举,但不能反向推翻页面分层 + +请按以下 lanes 组织执行: +- Lane A:统一入口页 / 导航聚合 +- Lane B:核心对象页 +- Lane C:扩展对象页 +- Lane D:历史核查 / 对账页 +- Lane E:审批状态 / 结果组件 +- Lane F:联调与口径校验 + +建议并行关系: +- A / B / D / E 先并行 +- C 在 B 的对象模式稳定后进入 +- F 最后贯穿联调与验收 + +最终输出: +- 各 lane 变更摘要 +- 冲突与整合说明 +- 验证结论 +``` + +--- + +## 3. Lane A Prompt:统一入口页 / 导航聚合 + +```text +你负责 REV-004 前端 Lane A:统一入口页 / 导航聚合。 + +工作范围: +- `src/views/accountProcess/index.vue`(若新建) +- 导航卡片组件 +- 入口汇总组件 + +目标: +- 建立 REV-004 管理后台统一工作台页 +- 仅负责对象导航、待办汇总、快捷入口、状态聚合 +- 不承载主办理表单 + +页面要求: +- 延续现有 ContentWrap / 查询区 / 信息卡片 / 表格摘要 风格 +- 页面中明确分出: + - 核心对象入口 + - 扩展对象入口 + - 历史核查入口 + - 审批/结果摘要入口 +- 支持跳转到各对象页,不把功能都堆在一个页面内 + +约束: +- 不要实现对象办理弹窗 +- 不要侵入 Lane B/C/D/E 的具体页面逻辑 +- 允许先用 mock/占位入口,但必须标清待接页面 + +交付: +1. 统一入口页代码 +2. 导航卡片/入口组件 +3. 页面清单与路由占位建议 +4. 需要 Lane B/C/D/E 配合的接口点 +``` + +--- + +## 4. Lane B Prompt:核心对象页 + +```text +你负责 REV-004 前端 Lane B:核心对象页。 + +冻结范围: +- 预存退款 +- 红冲记录 +- 已销调整 +- 坏账 + +优先目录: +- `src/views/accountProcess/prestorageAdjustment/*` +- `src/views/operatingCharges/redReversalRecord/*` +- `src/views/accountProcess/soldAdjustment/*` +- 坏账页目录(待新增,建议从 `unsoldAdjustment` 骨架拆出) + +目标: +- 将第一档核心对象做成独立菜单页 / 独立对象页 +- 页面模式保持现有后台风格:查询 + 表格 + 办理弹窗/详情 +- 统一对象页表达:状态、审批状态、附件、留痕、关联账单 + +重点要求: +- `prestorageAdjustment` 要向 `PrepaidRefund` 对象语义收敛 +- `redReversalRecord` 保留旧系统熟悉路径,但前端结构按现有项目规范组织 +- `soldAdjustment` 作为 `WrittenoffAdjust` 主页保留 +- 坏账页需明确从 `unsoldAdjustment` 中拆分,不要继续混在一个泛页面里 + +约束: +- 只处理第一档独立对象 +- 不扩展第二档对象 +- 不更改统一入口职责 + +交付: +1. 各对象页结构与代码调整 +2. 各页复用/新增组件清单 +3. 坏账页新建建议与落地文件路径 +4. 与 Lane E 的组件依赖点 +``` + +--- + +## 5. Lane C Prompt:扩展对象页 + +```text +你负责 REV-004 前端 Lane C:扩展对象页。 + +冻结范围: +- 价差调整 +- 违约金减免 +- 分账调整 +- 特账 / 特殊开账 + +建议依附: +- `src/views/accountProcess/unsoldAdjustment/*` +- `src/views/operatingCharges/specialAccountOpening/*` +- 或共享“账务调整扩展页”目录 + +目标: +- 将第二档对象做成共享扩展页或共享查询骨架 +- 不新增顶层菜单 +- 复用现有弹窗: + - `PriceAdjustmentForm` + - `PenaltyRemissionForm` + - `SplitAdjustmentForm` + +重点要求: +- 页面要体现对象差异,但不要每个对象都做成完整独立模块 +- 特账 / 特殊开账保留旧路径,但界面边界要按当前前端组织重写 +- 共享页要能通过对象类型切换,不回退成完全混杂页 + +约束: +- 本 lane 不得把第二档对象升为顶层菜单 +- 本 lane 不负责历史核查页 +- 统一状态 / 审批展示优先复用 Lane E 组件 + +交付: +1. 共享扩展页方案与代码 +2. 对象切换策略 +3. 复用组件点 +4. 与 Lane B 的边界说明 +``` + +--- + +## 6. Lane D Prompt:历史核查 / 对账页 + +```text +你负责 REV-004 前端 Lane D:历史核查 / 对账页。 + +范围: +- 退款账结果查询页 +- 跨周期水量查询页 +- 历史账务核查页 +- 对账与差异定位页 + +建议目录: +- `src/views/accountProcess/refundBill/*` +- `src/views/accountProcess/crossCycleWater/*` +- `src/views/accountProcess/historyAudit/*` +- `src/views/accountProcess/reconcileDiff/*` + +目标: +- 建立 REV-004 历史与核查层页面 +- 页面以查询、汇总、差异定位为主 +- 不做主办理动作 + +重点要求: +- 支持“现有 / 历史 / 目标”口径差异定位 +- 支持对象类型、状态、审批状态、账期、时间、关联账单等查询维度 +- 页面风格延续后台列表查询页 + 汇总区 + 详情抽屉模式 + +约束: +- 不要把这类页面做成办理页 +- 不要侵入第一档/第二档对象主办理逻辑 +- 与 Lane F 协作时,优先暴露差异定位能力 + +交付: +1. 历史与核查层页面代码 +2. 查询字段清单 +3. 差异定位展示方案 +4. 对 Lane F 的验收支撑点 +``` + +--- + +## 7. Lane E Prompt:审批状态 / 结果组件 + +```text +你负责 REV-004 前端 Lane E:审批状态 / 结果展示组件。 + +范围: +- 通用状态组件 +- 审批 Badge +- 结果摘要组件 +- 留痕 / 附件区组件 + +建议目录: +- `src/components/accounting/*` + +目标: +- 统一各对象页的状态表达 +- 统一审批状态展示 +- 统一结果摘要、附件、留痕表达 + +最小组件: +- `AccountingStatusPanel` +- `AccountingApprovalBadge` +- `AccountingResultSummary` +- `AccountingAttachmentPanel` +- `AccountingDiffTable` +- (可选)`AccountingObjectHeader` + +约束: +- 仅展示审批边界,不展开完整 BPM 流程前端 +- 组件要能被 Lane A/B/C/D 复用 +- 不直接绑定某个具体对象页逻辑 + +交付: +1. 通用组件代码 +2. 组件 props 约定 +3. 复用方式说明 +4. 与各 lane 的接入示例 +``` + +--- + +## 8. Lane F Prompt:联调与口径校验 + +```text +你负责 REV-004 前端 Lane F:联调与口径校验。 + +范围: +- 接口映射 +- 枚举值对齐 +- 页面与返回结构一致性校验 +- 验收样例整理 + +目标: +- 保证前端实现与正式文档口径一致 +- 检查 objectType、状态、审批状态、结果状态等枚举是否统一 +- 检查各对象页和核查页是否把“目标态”误写成“已实现事实” + +重点检查: +- 第一档对象页与第二档扩展页边界是否被破坏 +- 统一入口是否被做成主办理页 +- 历史核查页是否误入办理逻辑 +- 页面清单 / 路由清单 / 组件清单 / lane ownership 清单是否完整 + +交付: +1. 接口映射表 +2. 枚举值校验表 +3. 页面一致性检查结果 +4. 验收样例与问题清单 +``` + +--- + +## 9. 推荐启动顺序 + +建议在 `../water-frontend` 中按以下顺序启动: + +1. Leader 先下发统一任务说明 +2. 并行启动: + - Lane A + - Lane B + - Lane D + - Lane E +3. Lane B 稳定后启动 Lane C +4. 最后启动 Lane F 贯穿联调与验收 + +--- + +## 10. Leader 启动提示(可直接复制) + +```text +请在 ../water-frontend 中执行 REV-004 管理后台前端实现。 + +唯一需求依据: +- docs/guides/REV004_FRONTEND_IMPLEMENTATION_HANDOFF.md +- .omx/plans/2026-04-07-rev004-frontend-implementation-plan.md +- .omx/specs/deep-interview-rev004-frontend-modules.md +- REV-004 四层正式文档 + +范围限定: +- 仅管理后台 +- 不做微网厅 / 客户端 +- 不做完整 BPM 前端 + +执行原则: +- 保持当前前端范式 +- 核心操作路径尽量像旧系统 +- 统一入口只做导航 / 聚合 +- 第一档对象独立菜单冻结,第二档对象不得升顶层菜单 +- 先冻结 IA,再收敛 DTO / 状态细节 + +请按 Lane A-F 分工推进,并在最后统一输出: +1. 页面清单 +2. 路由清单 +3. 通用组件清单 +4. lane ownership 清单 +5. 代码变更摘要 +6. 联调问题清单 +``` diff --git a/docs/evidence/rev004-accounting/REV004_FRONTEND_OPEN_API_DEVELOPMENT_STANDARD.md b/docs/evidence/rev004-accounting/REV004_FRONTEND_OPEN_API_DEVELOPMENT_STANDARD.md new file mode 100644 index 0000000..ff89051 --- /dev/null +++ b/docs/evidence/rev004-accounting/REV004_FRONTEND_OPEN_API_DEVELOPMENT_STANDARD.md @@ -0,0 +1,149 @@ +# REV004 前后端开放接口开发规范(/business 域) + +## 1. 文档目的 +本规范用于统一 `water-backend` 对 `water-frontend` 的开放接口风格,作为后续新增、改造、评审和验收的共同标准。 + +## 2. 适用范围 +- 后端:`sw-business/sw-business-server/src/main/java/.../controller/admin/**` +- 前端:`water-frontend/src/api/**`、`water-frontend/src/views/**` +- 重点域:`/business/**` + +## 3. 现状基线(截至 2026-04-23) +### 3.1 导出接口现状 +- `/business` 导出映射约 **73** 个 + - `/export-excel`:**58**(主流) + - `/export`:**7**(次主流) + - 其他:`/export-details`、`/export-check`、`/export-failed` 等 +- 导出实现主流为: + - `ExcelUtils.write(...)` + - `ExcelUtils.writeWithTemplate(...)` +- 前端导出主流为: + - `request.download(...)` + - 失败数据回传导出:`request.postDownload(...)` + +### 3.2 当前特例(需治理) +`/business/accounting-adjust` 下存在 CSV 特例: +- `GET /business/accounting-adjust/log-export` +- `GET /business/accounting-adjust/prestorage-export` + +上述接口使用手写 `writeCsv(...)`,与整体 Excel 导出主流不一致。 + +--- + +## 4. 对前端开放接口统一标准(V1) + +### 4.1 路由命名标准 +| 场景 | 标准路由 | 说明 | +|---|---|---| +| 分页查询 | `GET /page` | 返回 `PageResult` | +| 详情 | `GET /get` | 单条详情 | +| 新增 | `POST /create` | 创建资源 | +| 更新 | `PUT /update` | 更新资源 | +| 删除 | `DELETE /delete` | 单条删除 | +| 导出(推荐) | `GET /export-excel` | 统一导出命名 | +| 导出(兼容) | `GET /export` | 历史接口保留过渡 | +| 失败数据导出 | `POST /export-failed` | 适配前端失败列表回传 | + +> 要求:新增接口优先 `export-excel`;历史 `export` 可保留,逐步迁移。 + +### 4.2 返回体标准 +| 类型 | 标准 | +|---|---| +| 普通接口 | `CommonResult` | +| 分页接口 | `CommonResult>`(字段固定 `list`、`total`) | +| 导出接口 | 二进制流(不包 `CommonResult`) | + +### 4.3 权限与审计标准 +- 导出接口权限统一:`@PreAuthorize("@ss.hasPermission('business::export')")` +- 导出接口必须标注:`@ApiAccessLog(operateType = EXPORT)` + +### 4.4 参数与校验标准 +- Query 分页参数统一 `*PageReqVO` +- 使用 `@Valid` / `@Validated` 触发参数校验 +- 必填、范围、格式使用 jakarta validation 注解 +- 日期区间优先显式双端字段;如需兼容前端 range 参数,可在 Controller 层做兼容解析 + +### 4.5 错误处理标准 +- Controller 层禁止直抛 `IllegalArgumentException` +- 统一使用 `ServiceException + ErrorCode` +- 统一由 `GlobalExceptionHandler` 转换为 `CommonResult` 响应 +- 错误信息需可读、可定位、可回溯 + +### 4.6 导出实现标准 +- 默认导出:`ExcelUtils.write(...)` +- 模板导出:`ExcelUtils.writeWithTemplate(...)` / `ExcelUtils.writeTemplate(...)` +- 禁止新增手写 CSV 导出实现 + +### 4.7 前端对接标准 +- 常规:`request.get/post/put/delete` +- 导出:`request.download` +- 失败导出:`request.postDownload` +- JSON 响应按 `code===200` 判成功(导出接口除外) + +--- + +## 5. 开发与评审检查清单(必须执行) + +### 5.1 新增接口检查 +- [ ] 路由命名符合标准 +- [ ] 权限点符合 `business::` +- [ ] 参数 VO 有校验注解 +- [ ] 响应类型为 `CommonResult` 或导出流 +- [ ] 无 `IllegalArgumentException` 直抛 + +### 5.2 导出接口检查 +- [ ] 使用 `GET /export-excel`(新接口) +- [ ] 使用 `ExcelUtils.*` 导出 +- [ ] 标注 `@ApiAccessLog(operateType = EXPORT)` +- [ ] 具备 `...:export` 权限 +- [ ] 前端 `request.download` 可直接对接 + +### 5.3 联调检查 +- [ ] 同筛选条件下“分页结果”和“导出结果”口径一致 +- [ ] 导出文件可正常打开,列头与业务语义一致 +- [ ] 异常场景返回结构可被前端统一处理 + +--- + +## 6. 账务调整模块专项治理要求 + +### 6.1 现状 +- `log-export` / `prestorage-export` 仍为 CSV 特例 + +### 6.2 治理目标 +- 与 `/business` 主流导出对齐为 Excel 导出 +- 保证前端调用方式不变或最小变更 + +### 6.3 推荐迁移策略 +1. 保留旧路由(兼容) +2. 新增/切换到 Excel 实现(`ExcelUtils`) +3. 增加 `@ApiAccessLog(EXPORT)` +4. 回归通过后,再评估是否下线 CSV 旧实现 + +--- + +## 7. 发布门禁(DoD) +- [ ] 编译通过 +- [ ] 导出接口静态扫描通过(权限、审计、实现方式) +- [ ] 前后端 smoke 联调通过(至少 3 个页面) +- [ ] 变更说明写入对应 feature 文档或 evidence + +--- + +## 8. 附:可直接执行的中文命令示例 + +```bash +# 1)进入后端仓库 +cd /Volumes/Dpan/github/water-workspace/water-backend + +# 2)扫描 /business 导出接口分布 +rg -n "@GetMapping\(\"/export|@PostMapping\(\"/export|writeCsv\(|ExcelUtils\.write" sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/controller/admin -S + +# 3)扫描是否存在 Controller 直抛 IllegalArgumentException +rg -n "throw new IllegalArgumentException" sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/controller/admin -S + +# 4)进入前端仓库检查下载对接 +cd /Volumes/Dpan/github/water-workspace/water-frontend +rg -n "request\.download\(|request\.postDownload\(" src/api -S +``` + diff --git a/docs/evidence/rev004-accounting/REV004_FRONTEND_QA_DEBUG_NOTICE.md b/docs/evidence/rev004-accounting/REV004_FRONTEND_QA_DEBUG_NOTICE.md new file mode 100644 index 0000000..eb9e356 --- /dev/null +++ b/docs/evidence/rev004-accounting/REV004_FRONTEND_QA_DEBUG_NOTICE.md @@ -0,0 +1,94 @@ +# REV004 联调通知(短版) + +各位前端 / 测试同学,REV004 本轮后端能力已合入 `develop`,现在可以开始联调: + +--- + +## 一、本轮已可联调 + +### 1. 分账专属接口 +- `POST /admin-api/business/split-adjust/submit` +- `GET /admin-api/business/split-adjust/page` +- `GET /admin-api/business/split-adjust/detail` +- `GET /admin-api/business/split-adjust/result` + +### 2. 违约金减免 +- 支持按金额 / 按日期 +- 支持申请人、联系电话、申请原因、附件 +- formal-table 闭环已打通 + +### 3. 预存转账 +已补齐并可回显: +- `targetCustName` +- `targetCustAddress` +- `applicant` +- `contactMobile` +- `remainingAmount` + +--- + +## 二、可直接用的联调样例 + +### 分账成功 +- `splitAdjustNo = REV004-SPLIT-API-001` +- `adjustmentNo = REV004-SPLIT-API-001` + +### 违约金减免成功 +- `adjustmentNo = REV004-LATEFEE-API-001` + +### 违约金减免待审批 +- `adjustmentNo = REV004-LATEFEE-API-002` + +--- + +## 三、测试环境 + +- `application-dev` 指向测试库已补齐相关表结构 +- real-db canary 已通过 + +--- + +## 四、重点建议验证 + +1. 分账提交 → 详情 → 结果回显 +2. 违约金减免按金额 / 按日期两种模式 +3. 预存转账提交后分页/详情回显是否完整 +4. 日志/附件/流程查询是否一致 + +--- + +## 五、当前边界 + +### 已覆盖 +- 分账专属接口 +- 违约金减免 formal-table +- 预存转账关键字段回显 + +### 未完全覆盖 +- 预存 formal-table 还没单独建 +- 坏账 / 核销 / 价差还没全部走 formal-table 路线 + +--- + +## 六、反馈方式 + +如果发现问题,请直接带: +- 接口路径 +- 请求参数 +- 返回报文 +- 对应 `adjustmentNo / splitAdjustNo` + +这样后端可以直接定位。 + +--- + +## 七、当前 develop 版本 + +当前 develop 已包含: +- PR #73:late-fee formal-table 闭环 +- PR #74:预存转账字段留痕与查询回显 + +最新 develop merge commit: +- `0d1e6d1d92fab7b59afc1f046ab08527691e9811` + +--- diff --git a/docs/evidence/rev004-accounting/REV004_FULL_ACCOUNTING_DOMAIN_DESIGN.md b/docs/evidence/rev004-accounting/REV004_FULL_ACCOUNTING_DOMAIN_DESIGN.md new file mode 100644 index 0000000..d371b99 --- /dev/null +++ b/docs/evidence/rev004-accounting/REV004_FULL_ACCOUNTING_DOMAIN_DESIGN.md @@ -0,0 +1,1741 @@ +# REV-004 全量账务领域设计骨架 + +## 1. 文档定位 + +本文档用于在现有 `REV-004` 一期设计基础上,补充一份面向“完整承载旧系统账务业务”的全量账务领域设计骨架,作为后续分批细化、正式文档回写、数据迁移设计和 backend 实施拆解的统一底稿。 + +本文件不是新的正式主文档替代稿,而是: + +- 对旧系统账务建模方式的结构化承接草案 +- 对新系统账务领域目标对象的统一设计骨架 +- 对“统一核心模型 + 独立业务实体 + 查询投影 + 历史映射”路线的落地说明 + +## 2. 设计目标 + +本设计面向以下目标: + +1. 完整承载旧系统账务相关业务,而不是仅覆盖一期最小闭环。 +2. 避免机械平移旧系统全部物理表结构,控制新系统领域复杂度。 +3. 在统一账务核心骨架下,为强业务场景保留正式业务实体。 +4. 保留旧系统台账查询、审批追溯、统计核对和历史迁移能力。 +5. 为后续正式主文档、数据库设计、接口设计和 backend 实施提供统一口径。 + +## 2.1 当前冻结范围 + +本轮冻结后的设计范围固定如下: + +1. 覆盖**旧系统账务相关全部业务对象**,不再局限于 `REV-004` 一期五类场景。 +2. 同时纳入以下 4 类设计内容: + - 领域对象与目标表设计 + - 接口承接设计 + - 审批 / BPM 承接设计 + - 历史迁移与查询兼容设计 +3. 当前首要产物固定为 `docs/guides/REV004_FULL_ACCOUNTING_DOMAIN_DESIGN.md`,作为全量账务领域设计的统一工作底稿。 +4. 后续允许按本底稿分批回写正式主文档,但当前阶段不直接把本稿视为正式交付主稿。 + +## 2.2 当前非目标 + +本轮明确不直接纳入以下内容: + +1. backend 实现代码 +2. 数据库建表 SQL / migration 脚本 +3. 历史迁移执行脚本 +4. 在正式目录旁保留 `*_old.md`、`*_v1.md` 等平行正式稿 +5. 复制一整套旧版正式文档目录作为运行中的第二真源 + +## 3. 来源与对齐基线 + +### 3.1 正式来源 + +- `docs/design/02_Detailed_Design/12_REV_Detailed.md` +- `docs/design/03_Technical_Design/01_Database_Design.md` +- `docs/design/03_Technical_Design/03_Interface_Design.md` +- `docs/design/01_Overview/03_Summary_Design.md` + +### 3.2 历史与核对来源 + +- `docs/design/04_Appendix/Archive/05_Data_Dictionary/营收数据字典.md` +- `docs/guides/REV004_LEGACY_FINANCE_MIGRATION_PLAN_V0.md` +- `docs/guides/BACKEND_TABLE_MAPPING.md` + +> 约束说明:以上历史来源仅用于**读取、核对、抽取和追溯**,不作为本轮直接修改目标;尤其 `Archive/05_Data_Dictionary/营收数据字典.md` 只读不改。 + +### 3.3 当前统一判断 + +1. 旧系统账务建模是典型的“场景台账型”模型。 +2. 新系统若要完整承载旧业务,不适合只保留一期统一主模型。 +3. 新系统也不应机械复制旧系统全部账务表族作为主写模型。 +4. 更合理的路线是: + - 统一核心账务骨架 + - 独立业务实体承接强场景 + - 查询投影承接旧菜单和旧报表 + - 历史映射承接旧主键和迁移追溯 + +### 3.4 真源边界与职责切分 + +当前真源边界固定如下: + +| 文档层 | 当前职责 | +|---|---| +| `specs/001-rev004-accounting/` | 继续约束 `REV-004` 一期最小闭环,不被本底稿覆盖或替代 | +| `specs/008-rev004-legacy-finance-migration/` | 继续约束旧账务迁移映射方法、缺失判定、迁移矩阵与批次策略 | +| `docs/guides/REV004_FULL_ACCOUNTING_DOMAIN_DESIGN.md` | 当前阶段唯一全量账务领域设计工作底稿 | +| `docs/design/*` 正式主文档 | 最终正式交付真源;仅在达到冻结条件后按批次回写 | + +### 3.5 正式回写与旧版保留规则 + +后续若启动正式主文档回写,必须遵守: + +1. 正式主文档回写前,旧版仅通过以下两种方式保留: + - Git 历史 + - `Archive/` 快照 +2. 不在正式目录中制造平行旧版文件。 +3. 每次正式回写前必须先冻结: + - 统一术语 + - 对象清单 + - 关系图 + - 回写范围 +4. 每次正式回写必须有明确的快照记录: + - 原文件路径 + - 快照日期 + - 快照归档路径 + - 对应回写批次号 + +## 4. 术语与口径统一 + +### 4.1 当前统一术语 + +| 术语 | 当前统一口径 | +|---|---| +| 账务处理 | 新系统中的控制骨架与统一处理能力总称 | +| 账务主单 | 一次账务处理申请/受理/执行过程的统一骨架对象 | +| 账务明细 | 账务主单影响的账单、流水、金额、水量等对象明细 | +| 业务实体 | 在业务上具备独立生命周期、审批、查询入口或强语义边界的对象 | +| 查询投影 | 面向旧菜单、旧报表、运营统计的查询/聚合对象 | +| 历史映射 | 旧系统表主键、单号、流程号与新系统对象的映射关系 | + +### 4.2 本文采用的分层术语 + +| 分层 | 说明 | +|---|---| +| `L1 核心抽象层` | 统一账务处理主单、明细、流程引用、留痕、期间、映射等骨架对象 | +| `L2 独立业务层` | 必须保留独立业务语义的正式账务实体 | +| `L3 查询投影层` | 面向历史查询、统计分析、旧菜单兼容的投影对象 | +| `L4 历史映射层` | 承接旧主键、旧单号、旧流程号和迁移批次追溯 | + +### 4.3 本文固定术语替换规则 + +为避免后续继续漂移,本文固定以下规则: + +1. “全量账务领域设计”默认指向**旧系统账务全部业务对象的目标态设计**。 +2. “一期口径”默认仅指 `specs/001-rev004-accounting/` 中的 `REV-004` 一期边界。 +3. “迁移设计”默认指 `specs/008-rev004-legacy-finance-migration/` 中的迁移方法、映射与缺失分析,不替代目标领域模型。 +4. “正式业务实体”指在新系统中保留独立业务语义、生命周期或查询入口的对象,不等同于旧表一比一平移。 +5. “查询投影”指服务旧菜单、旧报表、统计核查的只读或聚合承接对象,不作为新业务主写模型。 + +## 5. 旧系统账务建模特征 + +根据历史数据字典,旧系统账务域具备以下特征: + +1. 账务对象以业务场景为中心拆分,而非统一领域模型。 +2. 大量场景采用“汇总表 + 明细表”成对建模。 +3. 普遍嵌入流程字段: + - `TaskId` + - `StepId` + - `FlowRemark` +4. 普遍嵌入处理字段: + - `ProcType` + - `ProcPerson` + - `ProcDate` + - `ProcRemark` +5. 普遍围绕既有账单/流水修正: + - `FeeId` + - `NewFeeId` + - `AccountLogId` + - `TargetAccountLogId` +6. 普遍保留账务周期: + - `BillMonth` + +因此,旧系统账务模型本质上是: + +> 面向菜单和审批流的场景台账体系,而不是统一账务中心模型。 + +## 6. 目标建模总原则 + +### 6.1 必须坚持的原则 + +1. 不机械平移旧系统全部物理表结构作为新系统主写模型。 +2. 不把所有旧场景都压缩到一个通用表中导致语义丢失。 +3. 不让兼容层反客为主,直接成为新业务主写模型。 +4. 对强生命周期、强审批、强查询入口、强差异结构场景保留独立业务实体。 +5. 对旧系统高频查询和报表口径,必须提供查询投影承接。 +6. 对历史数据迁移,必须保留主键、单号、流程号级别的映射关系。 + +### 6.2 设计路线 + +新系统全量账务领域采用以下路线: + +```text +统一核心账务骨架 + + 独立业务实体 + + 查询投影对象 + + 历史映射对象 +``` + +## 7. 领域分层设计 + +### 7.1 L1 核心抽象层 + +建议保留以下统一骨架对象: + +| 对象 | 作用 | +|---|---| +| `AccountingCase` | 统一账务处理主单骨架,承接申请、状态、审批、结果 | +| `AccountingCaseDetail` | 统一账务处理明细骨架,承接受影响账单/流水/差异 | +| `AccountingWorkflowRef` | 统一审批流引用与流程状态 | +| `AccountingOperationLog` | 统一账务操作留痕 | +| `AccountingLegacyMapping` | 统一历史映射关系 | +| `BillingPeriod` | 统一账务年月与期间控制对象 | +| `AccountingProcTypeDict` | 统一处理方式字典 | + +### 7.2 L2 独立业务层 + +建议保留以下正式业务实体: + +| 对象 | 是否建议独立 | 说明 | +|---|---|---| +| `PrepaidRefund` / `PrepaidRefundDetail` | 是 | 预存退款生命周期独立 | +| `RedinkRecord` / `RedinkRecordDetail` | 是 | 红冲是强审计、强查询对象 | +| `WrittenoffAdjust` / `WrittenoffAdjustDetail` | 是 | 已销调整与普通金额调整不同 | +| `PriceDiffAdjust` / `PriceDiffAdjustDetail` | 是 | 涉及调价号、阶梯、累计量 | +| `LateFeeReduce` / `LateFeeReduceDetail` | 是 | 违约金减免具备独立业务语义 | +| `BadDebtRecord` / `BadDebtRecordDetail` | 是 | 坏账是财务强对象 | +| `SplitAdjust` / `SplitAdjustDetail` | 是 | 分账结构差异大 | +| `SpecialBillingType`(挂接 `Charge` / `ChargeDetail`) | 否,优先不独立 | 特账更符合特殊开账产生的特殊账单/收费类型 | +| `RefundBill` | 是 | 退款账是结果型正式对象 | +| `CrossCycleWaterRecord` | 是 | 跨周期水量是独立基础数据对象,不是强流程型业务单 | + +### 7.3 L3 查询投影层 + +建议保留以下查询/统计对象: + +| 对象 | 说明 | +|---|---| +| `RealtimeCollectionBatch` | 实时收费汇总 | +| `RealtimeCollectionLog` | 实时收费日志 | +| `RealtimeCollectionLogDetail` | 实时收费明细 | +| `PaymentCheckLog` | 对账日志 | +| `CollectionSummaryView` | 收费汇总/收费小计/收费明细投影 | +| `DifficultDuplicateBillView` | 疑难重笔账投影 | + +### 7.4 L4 历史映射层 + +建议统一保留: + +| 对象 | 说明 | +|---|---| +| `AccountingLegacyMapping` | 映射旧表、旧主键、旧父级主键、旧单号、旧流程号与新对象 | + +### 7.5 旧账务对象全量分层矩阵 + +下表用于把旧系统账务对象统一归入 `L1/L2/L3/L4`,作为后续对象设计、接口承接、审批承接和迁移承接的共同基础。 + +| 旧对象 | 旧表/表族 | 目标分层 | 当前建议归类 | 归层依据 | +|---|---|---|---|---| +| 营业账 | 账务信息域 / 营业账 | `L1` | 核心抽象对象 | 所有账务处理的核心账单承接对象 | +| 营业账明细 | 账务信息域 / 营业账明细 | `L1` | 核心抽象对象 | 账务明细与费用项承接对象 | +| 账务年月 | 系统相关 / 账务年月表 | `L1` | 核心抽象对象 | 账务期间控制与账期闭环基础对象 | +| 账务处理方式 | 字典 / `ProcType` | `L1` | 核心抽象对象 | 多个账务场景共享处理动作语义 | +| 预存退款 | `PM_ACCOUNT_RECORDS` | `L2` | 独立业务实体 | 生命周期、审批、处理方式、账户流水引用独立 | +| 预存退款详情 | `PM_ACCOUNT_RECORD_DETAILS` | `L2` | 独立业务实体明细 | 直接承接受影响客户、金额、流水、账期 | +| 已销调整汇总 | `PM_PAYMENT_RECORDS` | `L2` | 独立业务实体 | 已收费后修正语义独立 | +| 已销调整明细 | `PM_PAYMENT_RECORD_DETAILS` | `L2` | 独立业务实体明细 | 原账单/新账单/原流水/目标流水关系强 | +| 价差调整汇总 | `PM_PRICE_RECORDS` | `L2` | 独立业务实体 | 调价号、阶梯、累计量等规则独立 | +| 价差调整明细 | `PM_PRICE_RECORD_DETAILS` | `L2` | 独立业务实体明细 | 前后金额、滞纳金、账单差额变化独立 | +| 账单-违约金减免汇总 | `PM_LATEFEE_RECORDS` | `L2` | 独立业务实体 | 减免类型、起止时间、审批独立 | +| 账单-违约金减免详情 | `PM_LATEFEE_RECORD_DETAILS` | `L2` | 独立业务实体明细 | 调整前后违约金差异独立 | +| 账单-呆坏账汇总 | 呆坏账汇总表 | `L2` | 独立业务实体 | 财务处置与审批语义独立 | +| 账单-呆坏账详情 | 呆坏账详情表 | `L2` | 独立业务实体明细 | 坏账账龄、状态、核销差异明细独立 | +| 红冲表 | `PM_REDINK_ENTRYS` | `L2` | 独立业务实体 | 柜面核账、审计、历史追溯高频入口 | +| 红冲明细 | 红冲相关明细 | `L2` | 独立业务实体明细 | 红冲影响的收费/账单/金额明细需独立承接 | +| 分账调整汇总 | 分账调整汇总 | `L2` | 独立业务实体 | 分摊规则与目标对象结构差异大 | +| 分账调整明细 | 分账调整明细 | `L2` | 独立业务实体明细 | 目标账单/目标客户/金额分摊强绑定 | +| 特账 | 特账 | `L1` | 主模型扩展类型 | 更符合特殊开账产生的特殊账单/收费类型 | +| 特账明细 | 特账明细 | `L1` | 主模型扩展明细 | 通过账单主明细 + 类型/来源字段承接 | +| 退款账 | 退款账 | `L2` | 独立业务实体 | 结果型账务对象,不只是退款动作日志 | +| 跨周期水量 | 跨周期水量 | `L2` | 独立基础数据对象 | 服务跨账期计费、阶梯累计和账单重算 | +| 阶梯累计量 | 阶梯累计量 | `L2` | 独立业务实体或基础规则对象 | 影响阶梯计费和账务重算逻辑 | +| 实时收费汇总表 | `PM_REALTIME_SUBTOTALS` | `L3` | 查询投影对象 | 汇总查询、对账核查和渠道台账 | +| 实时收费日志表 | `PM_REALTIMES` | `L3` | 查询投影对象 | 渠道交易与实时收费日志 | +| 实时收费日志明细表 | `PM_REALTIMES_DETAILS` | `L3` | 查询投影对象 | 账单级交易明细查询 | +| 对账日志 | `PM_PAYMENT_LOGS` | `L3` | 查询投影对象 | 对账过程和结果日志更适合只读承接 | +| 收费汇总 | 收费汇总 | `L3` | 查询投影对象 | 统计聚合与柜面核查口径 | +| 收费小计 | 收费小计 | `L3` | 查询投影对象 | 班结、阶段汇总、日终核查口径 | +| 收费明细 | 收费明细 | `L3` | 查询投影对象 | 更适合由收费/交易对象投影形成 | +| 疑难重笔账 | 疑难重笔账 / 汇总 | `L3` | 查询投影对象 | 偏核查治理而非在线主业务 | +| IC 卡充退表 | IC 卡账务表族 | `L3`(旧系统已确认存在) | 历史只读查询对象 | 旧系统正式存在;当前新系统按历史只读 + 映射层承接 | +| IC 卡充退账明细 | IC 卡账务表族 | `L3`(旧系统已确认存在) | 历史只读查询对象 | 旧系统正式存在;当前新系统按历史只读 + 映射层承接 | +| IC 卡结余记录 | IC 卡账务表族 | `L3`(旧系统已确认存在) | 查询投影对象 | 旧系统正式存在,当前更偏查询和历史核对 | +| IC 卡操作日志 | IC 卡账务表族 | `L3`(旧系统已确认存在) | 查询投影对象 | 旧系统正式存在,当前更偏日志与审计核查 | +| 旧主键/旧单号/旧流程号映射 | 所有旧账务对象 | `L4` | 历史映射对象 | 服务历史迁移、追溯和新旧标识映射 | + +### 7.6 当前冻结的分层判断规则 + +为避免后续对象继续漂移,分层判断暂时冻结为以下规则: + +1. 满足以下任一条件的对象,优先判为 `L2 独立业务层`: + - 生命周期独立 + - 审批流独立 + - 历史查询入口独立 + - 明细结构明显异于通用账务明细 +2. 满足以下任一条件的对象,优先判为 `L3 查询投影层`: + - 以查询、汇总、对账、统计、核查为主 + - 不适合作为新系统主写模型 + - 适合从 `Charge`、`Transaction`、日志对象投影生成 +3. 仅承接新旧标识映射、迁移批次和追溯关系的对象,固定归 `L4`。 +4. `L1` 只保留跨场景共用骨架,不吸收具备强独立语义的业务对象。 +5. 当旧对象本质是账单来源类型、收费类型或开账类型时,优先挂接到既有主模型扩展字段,不单独提升为 `L2` 正式业务实体。 + +## 8. 正式业务实体清单 + +### 8.1 建议正式保留的核心业务实体 + +| 实体 | 旧系统来源 | 独立原因 | 承接重点 | +|---|---|---|---| +| `PrepaidRefund` | `PM_ACCOUNT_RECORDS*` | 预存退款申请、处理、退款方式和账户流水引用独立 | 原流水、目标流水、退款金额、退款类型 | +| `RedinkRecord` | `PM_REDINK_ENTRYS` | 红冲是柜面核账和审计的高频入口 | 红冲单号、原收费、红冲金额、红冲原因 | +| `WrittenoffAdjust` | `PM_PAYMENT_RECORDS*` | 已销调整涉及已收金额、抵扣、滞纳金、原/新账单 | 原账单、新账单、原流水、处理方式 | +| `PriceDiffAdjust` | `PM_PRICE_RECORDS*` | 价差调整涉及价格体系差异与重算规则 | 调价号、价格口径、累计量、前后金额差异 | +| `LateFeeReduce` | `PM_LATEFEE_RECORDS*` | 违约金减免业务边界清晰 | 减免类型、起止时间、前后违约金 | +| `BadDebtRecord` | `呆坏账表族` | 财务处置和审批语义独立 | 坏账原因、坏账类型、账龄、核销状态 | +| `SplitAdjust` | `分账调整表族` | 分摊结构差异显著 | 原账单、目标账单、分摊金额、规则 | +| `SpecialBillingType`(挂接 `Charge` / `ChargeDetail`) | `特账表族` | 更接近特殊开账形成的特殊账单/收费类型 | 来源类型、业务类型、特账类型、状态、关联账单 | +| `RefundBill` | `退款账` | 结果型账务对象 | 退款形成后的正式账务结果 | +| `CrossCycleWaterRecord` | `跨周期水量` | 账务重算与阶梯累计支撑对象 | 周期跨度、客户、账单影响范围 | + +### 8.2 正式业务实体与统一骨架关系 + +```mermaid +flowchart LR + classDef core fill:#eef2ff,stroke:#4f46e5,color:#312e81,stroke-width:1.2px; + classDef biz fill:#eff6ff,stroke:#2563eb,color:#1e3a8a,stroke-width:1.2px; + classDef base fill:#ecfdf5,stroke:#059669,color:#14532d,stroke-width:1.2px; + classDef query fill:#f5f3ff,stroke:#7c3aed,color:#4c1d95,stroke-width:1.2px; + classDef support fill:#fff7ed,stroke:#ea580c,color:#7c2d12,stroke-width:1.2px; + + subgraph CORE[统一骨架层] + AC[AccountingCase]:::core + ACD[AccountingCaseDetail]:::core + AWF[AccountingWorkflowRef]:::core + ALOG[AccountingOperationLog]:::core + AMAP[AccountingLegacyMapping]:::support + PERIOD[BillingPeriod]:::support + end + + subgraph BASE[基础业务对象] + CHARGE[Charge]:::base + CDETAIL[ChargeDetail]:::base + TRANS[Transaction]:::base + ALOGSRC[AccountLog]:::base + CUST[Customer]:::base + end + + subgraph BIZ[正式业务实体] + PR[PrepaidRefund]:::biz + RED[RedinkRecord]:::biz + WA[WrittenoffAdjust]:::biz + PDA[PriceDiffAdjust]:::biz + LFR[LateFeeReduce]:::biz + BDR[BadDebtRecord]:::biz + SA[SplitAdjust]:::biz + RB[RefundBill]:::biz + CCW[CrossCycleWaterRecord]:::biz + end + + subgraph QUERY[查询投影对象] + RTCB[RealtimeCollectionBatch]:::query + RTCL[RealtimeCollectionLog]:::query + PCL[PaymentCheckLog]:::query + end + + AC --> ACD + AC --> AWF + AC --> ALOG + AC --> PERIOD + AC --> AMAP + + PR --> AC + RED --> AC + WA --> AC + PDA --> AC + LFR --> AC + BDR --> AC + SA --> AC + RB --> AC + CCW --> AC + + ACD --> CHARGE + ACD --> CDETAIL + ACD --> TRANS + ACD --> ALOGSRC + AC --> CUST + + RTCB --> TRANS + RTCL --> TRANS + PCL --> TRANS +``` + +### 8.3 正式业务实体详细骨架 + +下表用于定义每个正式业务实体的最小业务结构,作为后续数据库表设计与接口设计的共同基础。 + +#### 8.3.1 `PrepaidRefund` / `PrepaidRefundDetail` + +| 项目 | 设计建议 | +|---|---| +| 主表角色 | 预存退款申请主单,承接申请、审批、退款状态与统一账务主单关联 | +| 明细表角色 | 记录受影响客户、退款金额、原账户流水、目标流水、处理方式与账期 | +| 主表关键字段组 | 单号:`refund_no`;申请:`applicant_id/name/mobile`;业务:`refund_type`、`apply_reason_code`、`remark`;流程:`approval_task_id`、`approval_step_id`、`approval_remark`;统一骨架:`accounting_case_id` | +| 明细表关键字段组 | 对象:`cust_id/cust_code`;金额:`refund_amount`、`surplus_deposit`、`uncheck_amount`;流水:`source_account_log_id`、`target_account_log_id`;处理:`proc_type`、`proc_person`、`proc_time`、`proc_remark`;期间:`bill_month` | +| 主外键关系 | 主表 `id` -> 明细表 `refund_id`;主表 `accounting_case_id` -> `biz_accounting_case.id` | +| 核心状态字段 | `refund_status`:`DRAFT/SUBMITTED/PENDING_APPROVAL/APPROVED/REFUNDING/SUCCESS/FAIL/CANCELLED` | +| 主要依赖对象 | `AccountingCase`、`AccountLog`、`Customer`、必要时关联 `Transaction` | + +#### 8.3.2 `RedinkRecord` / `RedinkRecordDetail` + +| 项目 | 设计建议 | +|---|---| +| 主表角色 | 红冲主对象,承接红冲申请、红冲结果、经办人与汇总金额 | +| 明细表角色 | 记录原收费、原账单、红冲金额、红冲原因、影响范围 | +| 主表关键字段组 | 单号:`redink_no`;柜面:`org_id`、`cashier_id`;操作:`redink_user_id`、`redink_time`;金额:`redink_amount_total`、`redink_count`;统一骨架:`accounting_case_id` | +| 明细表关键字段组 | 原对象:`source_charge_id`、`source_collection_id`、`source_transaction_id`;金额:`redink_amount`;原因:`reason_code/reason_text`;追溯:`source_bill_no`、`source_trade_no` | +| 主外键关系 | 主表 `id` -> 明细表 `redink_record_id`;主表 `accounting_case_id` -> `biz_accounting_case.id` | +| 核心状态字段 | `redink_status`:`SUBMITTED/PENDING_APPROVAL/APPROVED/SUCCESS/FAIL/CANCELLED` | +| 主要依赖对象 | `AccountingCase`、`Charge`、`Transaction`、`Collection` | + +#### 8.3.3 `WrittenoffAdjust` / `WrittenoffAdjustDetail` + +| 项目 | 设计建议 | +|---|---| +| 主表角色 | 已销调整主单,承接已收费后账单修正 | +| 明细表角色 | 记录原账单、新账单、原流水、目标流水、实收/抵扣/滞纳金差异 | +| 主表关键字段组 | 单号:`writtenoff_adjust_no`;申请:`applicant_id/name/mobile`;业务:`apply_reason_code`、`remark`;流程:`approval_*`;统一骨架:`accounting_case_id` | +| 明细表关键字段组 | 账单:`source_charge_id`、`target_charge_id`;金额:`bill_amount_before/after`、`actual_amount_before/after`、`deduction_amount_before/after`、`late_fee_before/after`;流水:`source_account_log_id`、`target_account_log_id`;处理:`proc_type` | +| 主外键关系 | 主表 `id` -> 明细表 `writtenoff_adjust_id`;主表 `accounting_case_id` -> `biz_accounting_case.id` | +| 核心状态字段 | `adjust_status`:`SUBMITTED/PENDING_APPROVAL/APPROVED/PROCESSING/SUCCESS/FAIL` | +| 主要依赖对象 | `AccountingCase`、`Charge`、`ChargeDetail`、`AccountLog`、必要时 `Transaction` | + +#### 8.3.4 `PriceDiffAdjust` / `PriceDiffAdjustDetail` + +| 项目 | 设计建议 | +|---|---| +| 主表角色 | 价差调整主单,承接价格体系变化带来的账务修正 | +| 明细表角色 | 记录调价前后账单金额、滞纳金、是否阶梯、是否影响累计量 | +| 主表关键字段组 | 单号:`price_diff_no`;价格:`price_list_id`、`price_code`、`is_ladder`、`is_change_total`;申请/流程字段;统一骨架:`accounting_case_id` | +| 明细表关键字段组 | 账单:`charge_id`、`new_charge_id`;金额:`bill_amount_before/after`、`extended_amount_before/after`、`late_fee_before/after`;客户:`cust_id/cust_code`;期间:`bill_month` | +| 主外键关系 | 主表 `id` -> 明细表 `price_diff_adjust_id`;主表 `accounting_case_id` -> `biz_accounting_case.id` | +| 核心状态字段 | `price_diff_status`:`SUBMITTED/PENDING_APPROVAL/APPROVED/PROCESSING/SUCCESS/FAIL` | +| 主要依赖对象 | `AccountingCase`、`Charge`、`PriceTemplate/PriceCategory`、必要时 `CrossCycleWaterRecord`、`LadderAccumulate` | + +#### 8.3.5 `LateFeeReduce` / `LateFeeReduceDetail` + +| 项目 | 设计建议 | +|---|---| +| 主表角色 | 违约金减免主单 | +| 明细表角色 | 记录减免对象、起止时间、原违约金、减免金额、调整后违约金 | +| 主表关键字段组 | 单号:`latefee_reduce_no`;申请:`applicant_*`;业务:`late_fee_type`、`apply_reason_code`、`remark`;流程:`approval_*`;统一骨架:`accounting_case_id` | +| 明细表关键字段组 | 对象:`charge_id`、`cust_id`;期间:`bill_month`、`start_date`、`end_date`;金额:`late_fee_before`、`reduce_amount`、`late_fee_after`;处理:`proc_type/proc_person/proc_time` | +| 主外键关系 | 主表 `id` -> 明细表 `latefee_reduce_id`;主表 `accounting_case_id` -> `biz_accounting_case.id` | +| 核心状态字段 | `reduce_status`:`SUBMITTED/PENDING_APPROVAL/APPROVED/SUCCESS/FAIL` | +| 主要依赖对象 | `AccountingCase`、`Charge` | + +#### 8.3.6 `BadDebtRecord` / `BadDebtRecordDetail` + +| 项目 | 设计建议 | +|---|---| +| 主表角色 | 呆坏账申请/认定/核销主单 | +| 明细表角色 | 记录账龄、账单、客户状态、核销状态、处理结果 | +| 主表关键字段组 | 单号:`bad_debt_no`;业务:`bad_debt_type`、`reason_code`、`remark`;申请与流程字段;统一骨架:`accounting_case_id` | +| 明细表关键字段组 | 对象:`charge_id`、`cust_id`;账龄:`aging_days/aging_bucket`;状态:`charge_status_before/after`、`writeoff_status`;金额:`receivable_amount`、`late_fee_amount` | +| 主外键关系 | 主表 `id` -> 明细表 `bad_debt_record_id`;主表 `accounting_case_id` -> `biz_accounting_case.id` | +| 核心状态字段 | `bad_debt_status`:`SUBMITTED/PENDING_APPROVAL/APPROVED/EFFECTIVE/WRITTEN_OFF/REJECTED/CANCELLED` | +| 主要依赖对象 | `AccountingCase`、`Charge`、`Customer` | + +#### 8.3.7 `SplitAdjust` / `SplitAdjustDetail` + +| 项目 | 设计建议 | +|---|---| +| 主表角色 | 分账调整主单,承接分摊或目标账单重分配 | +| 明细表角色 | 记录原账单、目标账单、分摊规则、金额和目标客户 | +| 主表关键字段组 | 单号:`split_adjust_no`;业务:`split_rule_type`、`reason_code`、`remark`;流程字段;统一骨架:`accounting_case_id` | +| 明细表关键字段组 | 原对象:`source_charge_id`;目标对象:`target_charge_id`、`target_cust_id`;金额:`split_amount`;规则:`split_ratio/split_basis`;处理:`proc_type` | +| 主外键关系 | 主表 `id` -> 明细表 `split_adjust_id`;主表 `accounting_case_id` -> `biz_accounting_case.id` | +| 核心状态字段 | `split_status`:`SUBMITTED/PENDING_APPROVAL/APPROVED/PROCESSING/SUCCESS/FAIL` | +| 主要依赖对象 | `AccountingCase`、`Charge`、`Customer` | + +#### 8.3.8 特殊开账 / 特账承接方式(挂接 `Charge` / `ChargeDetail`) + +| 项目 | 设计建议 | +|---|---| +| 承接角色 | 不建议单独建正式主表;优先作为 `Charge` / `ChargeDetail` 的扩展类型承接 | +| 核心语义 | 特账更符合“特殊开账场景下形成的特殊账单/收费类型” | +| 关键字段组 | `source_type = SPECIAL_BILLING`、`fee_type = SPECIAL`、`special_bill_type`、`reason_code`、`remark`、`operator_id` | +| 明细承接 | 通过 `ChargeDetail` 继续承接金额、水量、费用组成、状态差异 | +| 主外键关系 | 不新增独立主外键;挂接在 `biz_charge` / `biz_charge_detail` 上 | +| 核心状态字段 | 继承 `Charge` / `ChargeDetail` 主状态;必要时补特殊来源状态枚举 | +| 主要依赖对象 | `Charge`、`ChargeDetail`、`Customer`、`OperationLog` | + +#### 8.3.9 `RefundBill` + +| 项目 | 设计建议 | +|---|---| +| 主表角色 | 退款形成后的正式账务结果对象 | +| 是否建议独立明细表 | 可后续根据业务量判断,当前可先不单独建 detail | +| 关键字段组 | 单号:`refund_bill_no`;来源:`source_refund_id/source_trade_no/source_charge_id`;金额:`refund_amount`;状态:`refund_bill_status`;结果:`effective_time`、`settlement_flag` | +| 主外键关系 | `accounting_case_id` -> `biz_accounting_case.id`;必要时关联 `PrepaidRefund` 或 `Transaction` | +| 核心状态字段 | `CREATED/EFFECTIVE/CANCELLED/SETTLED` | +| 主要依赖对象 | `AccountingCase`、`Transaction`、`Charge` | + +#### 8.3.10 `CrossCycleWaterRecord` + +| 项目 | 设计建议 | +|---|---| +| 主表角色 | 跨周期水量基础数据对象 / 账单重算支撑对象 | +| 是否建议独立明细表 | 暂可不拆,后续如存在多段分配规则再拆 detail | +| 关键字段组 | 单号:`cross_cycle_water_no`;对象:`cust_id`、`meter_id`、`charge_id`;期间:`source_bill_month`、`target_bill_month`;数量:`water_volume`;原因:`reason_code` | +| 主外键关系 | 可关联 `Charge`、`MeterRead/ReadingData`、必要时关联 `AccountingCase` | +| 核心状态字段 | `CALCULATED/APPLIED/ROLLED_BACK`(表示计算与应用状态,不表示独立审批流状态) | +| 主要依赖对象 | `Charge`、`ChargeDetail`、`ReadingData`、`BillingPeriod`、必要时 `PriceDiffAdjust` / `LadderAccumulate` | + +## 9. 目标表设计骨架 + +### 9.1 L1 核心骨架表 + +| 目标表 | 角色 | 说明 | +|---|---|---| +| `biz_accounting_case` | 主单骨架表 | 统一账务处理主单 | +| `biz_accounting_case_detail` | 明细骨架表 | 统一账务处理明细 | +| `biz_accounting_workflow_ref` | 审批引用表 | 统一审批流引用 | +| `biz_accounting_legacy_mapping` | 历史映射表 | 旧对象映射 | +| `biz_billing_period` | 账务期间表 | 统一账务年月、期间控制 | +| `biz_accounting_proc_type` | 处理方式字典 | 承接旧 `ProcType` 及新枚举扩展 | + +### 9.2 L2 独立业务表 + +| 目标表 | 是否建议明细表 | 对应旧系统表 | +|---|---|---| +| `biz_prepaid_refund` | 是 | `PM_ACCOUNT_RECORDS` | +| `biz_prepaid_refund_detail` | 是 | `PM_ACCOUNT_RECORD_DETAILS` | +| `biz_redink_record` | 是 | `PM_REDINK_ENTRYS` + 关联明细 | +| `biz_redink_record_detail` | 是 | 红冲相关明细 | +| `biz_writtenoff_adjust` | 是 | `PM_PAYMENT_RECORDS` | +| `biz_writtenoff_adjust_detail` | 是 | `PM_PAYMENT_RECORD_DETAILS` | +| `biz_price_diff_adjust` | 是 | `PM_PRICE_RECORDS` | +| `biz_price_diff_adjust_detail` | 是 | `PM_PRICE_RECORD_DETAILS` | +| `biz_latefee_reduce` | 是 | `PM_LATEFEE_RECORDS` | +| `biz_latefee_reduce_detail` | 是 | `PM_LATEFEE_RECORD_DETAILS` | +| `biz_bad_debt_record` | 是 | 账单-呆坏账表族 | +| `biz_bad_debt_record_detail` | 是 | 账单-呆坏账表族 | +| `biz_split_adjust` | 是 | 分账调整汇总 | +| `biz_split_adjust_detail` | 是 | 分账调整明细 | +| 特账 / 特账明细 | 否 | 优先由 `biz_charge` / `biz_charge_detail` + 类型字段承接 | +| `biz_refund_bill` | 视情况 | 退款账 | +| `biz_cross_cycle_water_record` | 视情况 | 跨周期水量 | + +### 9.3 L3 查询投影表/视图 + +| 目标对象 | 建议类型 | 说明 | +|---|---|---| +| `vw_collection_summary` | 视图/物化视图 | 收费汇总、小计、明细 | +| `vw_realtime_collection_batch` | 视图/投影表 | 实时收费汇总 | +| `vw_realtime_collection_log` | 视图/投影表 | 实时收费日志 | +| `vw_payment_check_log` | 视图/投影表 | 对账日志 | +| `vw_difficult_duplicate_bill` | 视图 | 疑难重笔账 | + +## 10. 核心状态机骨架 + +### 10.1 统一账务主单状态 + +建议统一状态: + +```text +DRAFT +-> SUBMITTED +-> PENDING_APPROVAL +-> APPROVED / REJECTED +-> PROCESSING +-> SUCCESS / FAIL / CANCELLED +``` + +### 10.2 业务实体扩展状态 + +独立业务对象可在统一状态之上保留扩展状态,例如: + +- `PrepaidRefund` + - 待审核 + - 待退款 + - 部分退款 + - 退款完成 + - 退款失败 +- `BadDebtRecord` + - 待申请 + - 待审批 + - 已认定 + - 已核销 + - 已撤销 +- `RedinkRecord` + - 已受理 + - 已红冲 + - 红冲失败 + +## 11. 旧系统到新系统的映射策略 + +### 11.1 映射原则 + +1. 旧主键必须保留映射。 +2. 旧汇总表与明细表关系必须可追溯。 +3. 旧单号、旧流程号、旧审批号必须可回查。 +4. 新系统正式业务实体与统一骨架必须同时建立映射。 + +### 11.1A 迁移承接方式枚举 + +本设计冻结以下 4 类迁移承接方式: + +| 承接方式 | 含义 | +|---|---| +| `online-main` | 进入新系统统一核心模型或独立业务实体,参与在线业务处理 | +| `projection-only` | 不做在线主写,仅形成查询投影或聚合对象 | +| `history-readonly` | 只保留历史查询、比对和审计追溯能力 | +| `mapping-only` | 仅保留新旧标识映射,不提供独立在线处理或查询入口 | + +### 11.2 建议映射字段 + +`biz_accounting_legacy_mapping` 至少包含: + +| 字段 | 说明 | +|---|---| +| `legacy_table` | 原表名 | +| `legacy_id` | 原主键 | +| `legacy_parent_id` | 原父级主键 | +| `legacy_no` | 原业务单号 | +| `legacy_task_id` | 原流程任务号 | +| `new_case_id` | 新账务主单 ID | +| `new_case_detail_id` | 新账务明细 ID | +| `new_biz_object_type` | 新业务对象类型 | +| `new_biz_object_id` | 新业务对象 ID | +| `tenant_id` | 租户 | +| `migration_batch_no` | 迁移批次号 | + +### 11.3 旧对象迁移承接矩阵(冻结版) + +| 旧对象 | 目标承接方式 | 新系统承接对象 | 说明 | +|---|---|---|---| +| 营业账 | `online-main` | `Charge` / `AccountingCase` | 继续作为账务处理核心依附对象 | +| 营业账明细 | `online-main` | `ChargeDetail` / `AccountingCaseDetail` | 继续承接费用项级差异 | +| 预存退款 | `online-main` | `PrepaidRefund` + `AccountingCase` | 独立业务实体 + 统一骨架双承接 | +| 预存退款详情 | `online-main` | `PrepaidRefundDetail` + `AccountingCaseDetail` | 保留退款金额、流水与账期差异 | +| 已销调整汇总 | `online-main` | `WrittenoffAdjust` + `AccountingCase` | 独立业务实体承接 | +| 已销调整明细 | `online-main` | `WrittenoffAdjustDetail` + `AccountingCaseDetail` | 保留原/新账单与流水关系 | +| 价差调整汇总 | `online-main` | `PriceDiffAdjust` + `AccountingCase` | 保留调价号与规则边界 | +| 价差调整明细 | `online-main` | `PriceDiffAdjustDetail` + `AccountingCaseDetail` | 保留金额与滞纳金前后差异 | +| 账单-违约金减免汇总 | `online-main` | `LateFeeReduce` + `AccountingCase` | 作为正式业务实体保留 | +| 账单-违约金减免详情 | `online-main` | `LateFeeReduceDetail` + `AccountingCaseDetail` | 保留违约金前后差异与期间 | +| 账单-呆坏账汇总 | `online-main` | `BadDebtRecord` + `AccountingCase` | 保留坏账申请/认定/核销路径 | +| 账单-呆坏账详情 | `online-main` | `BadDebtRecordDetail` + `AccountingCaseDetail` | 保留账龄和状态差异 | +| 红冲表 | `online-main` | `RedinkRecord` + `AccountingCase` | 作为独立高频对象保留 | +| 红冲明细 | `online-main` | `RedinkRecordDetail` + `AccountingCaseDetail` | 记录红冲影响范围与金额 | +| 分账调整汇总 | `online-main` | `SplitAdjust` + `AccountingCase` | 分账规则独立保留 | +| 分账调整明细 | `online-main` | `SplitAdjustDetail` + `AccountingCaseDetail` | 保留分摊目标与金额 | +| 特账 | `online-main` | `Charge` / `ChargeDetail` + 类型字段 | 作为特殊开账产生的特殊账单/收费类型承接 | +| 特账明细 | `online-main` | `ChargeDetail` + 类型字段 | 不单独建主表,保留明细级差异与查询口径 | +| 退款账 | `online-main` | `RefundBill` + `AccountingCase` | 作为结果型正式对象承接 | +| 跨周期水量 | `online-main` | `CrossCycleWaterRecord` | 作为独立基础数据对象保留,不视为独立流程型业务单 | +| 阶梯累计量 | `online-main` 或 `projection-only` | 规则/累计量对象(待细化) | 后续需判断是正式对象还是规则支撑对象 | +| 实时收费汇总表 | `projection-only` | `RealtimeCollectionBatch` | 主要服务查询和对账 | +| 实时收费日志表 | `projection-only` | `RealtimeCollectionLog` | 主要服务渠道日志查询 | +| 实时收费日志明细表 | `projection-only` | `RealtimeCollectionLogDetail` | 主要服务账单级交易查询 | +| 对账日志 | `projection-only` | `PaymentCheckLog` | 保留对账过程查询 | +| 收费汇总 / 收费小计 / 收费明细 | `projection-only` | `CollectionSummaryView` | 通过收费/交易对象聚合形成 | +| 疑难重笔账 | `history-readonly` | `DifficultDuplicateBillView` | 先保留核查与追溯语义 | +| IC 卡账务表族 | `history-readonly`(旧系统已确认存在) | IC 卡兼容查询对象 | 旧系统正式存在;当前固定为历史只读 + 映射层承接 | +| 旧主键 / 单号 / 流程号映射 | `mapping-only` | `AccountingLegacyMapping` | 用于追溯、迁移校验和批次核对 | + +### 11.4 映射记录最小约束 + +每条迁移映射至少应明确: + +1. 原对象名称与原表名 +2. 原主键和原业务键 +3. 当前目标承接方式 +4. 当前目标对象 +5. 是否保留历史只读查询 +6. 是否需要状态映射 +7. 是否需要新旧标识映射 +8. 迁移批次号 +9. 证据来源(Archive / backend / 正式文档 / guides) + +## 12. 查询兼容策略 + +### 12.1 兼容目标 + +为旧业务菜单、历史台账、财务核查和报表导出提供以下兼容能力: + +1. 仍能按旧场景查询: + - 预存退款 + - 已销调整 + - 价差调整 + - 违约金减免 + - 呆坏账 + - 红冲 +2. 仍能按客户、账期、站点、处理方式、状态、审批结果检索。 +3. 仍能按汇总/明细双层视角导出。 + +### 12.2 兼容方式 + +建议采用: + +- 独立业务实体承接在线主写 +- 视图/投影表承接旧查询口径 +- 映射表承接旧主键追溯 + +### 12.3 历史只读边界 + +以下对象当前冻结为“历史只读或兼容查询优先”,不直接作为新系统主写模型: + +| 对象 | 当前边界 | 说明 | +|---|---|---| +| 疑难重笔账 | 历史只读 | 主要服务核查与比对 | +| 对账日志 | 查询投影优先 | 不建议单独作为在线主写业务对象 | +| 实时收费汇总/日志/明细 | 查询投影优先 | 主要服务渠道查询、差异核对和日志追溯 | +| 收费汇总/收费小计/收费明细 | 查询投影优先 | 主要服务统计和柜面核查 | +| IC 卡账务表族 | 历史只读(旧系统已确认存在) | 旧系统已有完整建模;当前固定为历史只读 + 映射层承接 | + +### 12.4 查询兼容出口设计 + +建议对旧系统高频查询口径提供统一查询出口: + +| 查询主题 | 建议出口 | 说明 | +|---|---|---| +| 预存退款查询 | `PrepaidRefund` + 明细查询接口/视图 | 同时支持主单和明细 | +| 已销调整查询 | `WrittenoffAdjust` + 明细查询接口/视图 | 支持原账单与新账单差异定位 | +| 价差调整查询 | `PriceDiffAdjust` + 明细查询接口/视图 | 支持按调价号、账期、客户查询 | +| 违约金减免查询 | `LateFeeReduce` + 明细查询接口/视图 | 支持按减免类型和账期查询 | +| 呆坏账查询 | `BadDebtRecord` + 明细查询接口/视图 | 支持账龄、状态、审批结果查询 | +| 红冲查询 | `RedinkRecord` + 明细查询接口/视图 | 支持原单号、红冲金额、经办人、时间查询 | +| 实时收费与对账查询 | `RealtimeCollection*` / `PaymentCheckLog` | 作为渠道与对账投影出口 | + +### 12.5 查询兼容规则 + +1. 旧查询口径优先通过独立业务实体或查询投影承接,不直接回退为“查旧表”。 +2. 历史只读对象必须至少支持: + - 原单号 + - 客户 + - 账期 + - 状态 + - 金额/水量摘要 + - 经办人 + - 时间 +3. 兼容查询接口不得承担状态变更职责。 +4. 兼容查询结果中必须能追溯到: + - 新对象 ID + - 旧对象标识 + - 迁移批次号(如适用) + +### 12.6 迁移批次设计骨架 + +建议迁移实施仍按以下批次组织: + +| 批次 | 范围 | 目标 | +|---|---|---| +| Batch 1 | 营业账、营业账明细、期间、账户流水主关系 | 锁定主键和核心关系 | +| Batch 2 | 收费结果、交易流水、实时收费与对账日志 | 锁定收费与交易追溯链 | +| Batch 3 | 账务处理主对象:退款、红冲、已销调整、价差调整、违约金减免、坏账、分账、特账 | 锁定全量账务业务承接对象 | +| Batch 4 | 退款账、跨周期水量、阶梯累计量及其他基础或结果对象 | 锁定补充账务基础对象 | +| Batch 5 | 历史只读对象、兼容视图、查询出口与校验报表 | 锁定旧菜单和历史核查口径 | + +### 12.7 接口承接设计原则 + +全量账务对象的接口承接采用以下原则: + +1. **统一入口优先承接共性动作** + 当前统一账务处理入口仍以 `IF-REV-007` 为基础骨架,优先承接共性的提交、校验、结果表达和留痕逻辑。 +2. **强独立业务对象允许拆专属接口族** + 对生命周期、审批、查询入口明显独立的对象,可在后续阶段拆出专属接口,而不是永久挤在 `IF-REV-007` 下。 +3. **查询投影对象只走只读接口** + 汇总、日志、对账、历史只读对象不得承担状态变更职责。 +4. **外部协同继续经既有专题系统承接** + 支付退款、银行对账、发票作废/红冲等,不在账务领域内部重复造一套外部接口体系。 + +### 12.8 接口承接分层矩阵 + +| 对象 | 当前统一承接入口 | 后续建议专属接口 | 查询接口策略 | 外部协同关系 | +|---|---|---|---|---| +| `PrepaidRefund` | `IF-REV-007` 提交退款类场景 | 建议后续拆 `IF-REV-014` 预存退款申请/处理接口 | 独立查询接口或查询视图 | 支付退款结果仍需联动 `bk_transaction*` | +| `RedinkRecord` | 当前可先挂 `IF-REV-007` 修正场景 | 建议后续拆 `IF-REV-015` 红冲处理接口 | 必须独立查询接口 | 与收费、结账、退款链协同 | +| `WrittenoffAdjust` | `IF-REV-007` | 可保留在统一入口内 | 独立查询接口或视图 | 必要时联动原交易和收费结果 | +| `PriceDiffAdjust` | `IF-REV-007` | 建议后续拆 `IF-REV-016` 价差调整接口 | 独立查询接口或视图 | 关联价格体系与账单重算 | +| `LateFeeReduce` | `IF-REV-007` | 视实施复杂度决定是否拆专属接口 | 独立查询接口或视图 | 无强外部协同,主要内部审批/账单联动 | +| `BadDebtRecord` | `IF-REV-007` | 建议后续拆 `IF-REV-017` 坏账申请/认定接口 | 独立查询接口或视图 | 无强外部协同,主要内部审批/核销联动 | +| `SplitAdjust` | `IF-REV-007` 或与账单调整同入口 | 建议后续拆 `IF-REV-018` 分账调整接口 | 独立查询接口或视图 | 主要内部账单分摊,不依赖外部系统 | +| 特账(特殊开账类型) | 不走 `IF-REV-007`;优先挂 `IF-REV-005` / 开账主模型扩展 | 不建议单独拆特账处理接口 | 历史查询与账单查询兼容出口即可 | 与收费、打印、发票链联动 | +| `RefundBill` | 不建议直接提交;由退款处理结果派生 | 可后续拆只读结果接口 | 建议独立查询接口 | 结果对象需联动支付退款结果与账单状态 | +| `CrossCycleWaterRecord` | 不建议作为用户直接提交接口 | 作为账单重算/计费内部对象,不拆前台业务接口 | 仅内部查询或管理查询 | 与账单生成、价差调整、阶梯累计联动 | +| `RealtimeCollectionBatch/Log/Detail` | 不走 `IF-REV-007` | 无需拆账务处理接口 | 只读查询接口 | 与支付、银行、柜台收费链联动 | +| `PaymentCheckLog` | 不走 `IF-REV-007` | 无需拆账务处理接口 | 只读查询接口 | 与银行对账、支付协同接口联动 | +| IC 卡账务表族 | 当前不纳入在线主写接口 | 暂不定义 | 历史只读查询 | 当前仅按历史只读 + 映射层承接 | + +### 12.9 统一入口与专属入口边界 + +#### 继续保留在 `IF-REV-007` 的对象 + +以下对象在当前阶段继续由 `IF-REV-007` 承接更合理: + +- `WrittenoffAdjust` +- `LateFeeReduce` +- `PrepaidRefund`(在未拆专属接口前) +- `BadDebtRecord`(在未拆专属接口前) + +原因: +- 已有正式接口骨架 +- 与当前 `REV-004` 正式主文档一致 +- 有利于先稳定共性输入、结果表达和留痕规则 + +#### 建议后续拆专属接口的对象 + +以下对象更适合后续拆专属接口: + +- `PrepaidRefund` +- `RedinkRecord` +- `PriceDiffAdjust` +- `BadDebtRecord` +- `SplitAdjust` + +原因: +- 生命周期更独立 +- 查询入口更独立 +- 输入输出结构已开始明显偏离统一账务调整接口 + +### 12.10 查询接口口径 + +建议后续统一采用两类查询接口: + +1. **业务对象查询接口** + 面向: + - 预存退款 + - 已销调整 + - 价差调整 + - 违约金减免 + - 呆坏账 + - 红冲 + - 分账调整 + - 退款账 + +2. **历史只读 / 投影查询接口** + 面向: + - 收费汇总/小计/明细 + - 实时收费汇总/日志/明细 + - 对账日志 + - IC 卡账务表族 + - 疑难重笔账 + +### 12.11 与当前正式接口文档的关系 + +当前正式接口文档 `docs/design/03_Technical_Design/03_Interface_Design.md` 的约束仍然成立: + +1. `IF-REV-007` 仍是当前正式账务处理统一入口。 +2. 发票作废/红冲仍由 `REV-005` / `SYS-008` 体系承接,不在本节重复定义税控协同接口。 +3. 支付退款、银行交易、回调、对账仍以 `bk_transaction*`、`SYS-009` 和外部支付/银行接口体系为准。 +4. 本节仅定义**全量账务领域未来的接口承接方向**,不把专属接口直接写成当前已落地事实。 + +### 12.12 审批 / BPM 承接原则 + +全量账务领域的审批 / BPM 承接采用以下原则: + +1. **当前正式口径继续有效** + 当前正式文档中,`IF-REV-007` 仍只保留: + - `approvalRequired` + - `PENDING_APPROVAL` + 等能力位与边界说明。 +2. **全量设计允许引入分层审批承接模型** + 不再把所有对象一概压缩成“只保留能力位”,而是按对象语义区分审批承接方式。 +3. **旧审批流字段优先保留为可追溯字段** + 旧系统中的: + - `TaskId` + - `StepId` + - `FlowRemark` + 先统一承接到审批引用 / 历史追溯对象中。 +4. **不是所有对象都需要独立 BPM** + 强流程型对象可独立审批;基础数据对象和查询投影对象不强接 BPM。 + +### 12.13 审批承接分层矩阵 + +| 对象 | 审批承接方式 | 当前判断 | 说明 | +|---|---|---|---| +| `PrepaidRefund` | 独立审批流对象 | 建议独立审批流 | 旧系统存在申请、查询、作废语义,生命周期独立 | +| `RedinkRecord` | 审批能力位对象 | 当前保留能力位,后续可升级 | 红冲业务强独立,但是否独立 BPM 仍可后续决策 | +| `WrittenoffAdjust` | 审批能力位对象 | 当前保留能力位 | 已销调整可先沿用统一审批边界 | +| `PriceDiffAdjust` | 审批能力位或独立审批流对象 | 倾向审批能力位 + 后续可升级 | 价差调整规则复杂,但不必立即拆完整 BPM | +| `LateFeeReduce` | 审批能力位对象 | 当前保留能力位 | 旧系统有审批语义,先统一承接到能力位 | +| `BadDebtRecord` | 独立审批流对象 | 建议独立审批流 | 坏账申请天然是财务审批对象 | +| `SplitAdjust` | 审批能力位对象 | 当前保留能力位 | 分账规则复杂,但可先保留统一审批位 | +| 特账(特殊开账类型) | 不单独承接审批流 | 由主模型来源类型和留痕承接 | 特账更像特殊开账类型,不单独抽流程 | +| `RefundBill` | 不单独承接审批流 | 结果对象 | 审批由退款申请/处理对象带出 | +| `CrossCycleWaterRecord` | 不单独承接审批流 | 基础数据对象 | 若需审批,由关联业务场景带出,不自行承接 | +| `RealtimeCollection*` | 无审批流 | 查询/投影对象 | 只读对象,不承接流程 | +| `PaymentCheckLog` | 无审批流 | 查询/投影对象 | 只读对象,不承接流程 | +| IC 卡账务表族 | 无在线审批流 | 当前历史只读 + 映射承接 | 不在当前在线承接范围内 | + +### 12.14 统一审批引用对象设计 + +建议统一通过 `AccountingWorkflowRef` 承接审批相关引用,至少保留: + +| 字段 | 说明 | +|---|---| +| `accountingCaseId` | 关联账务主单 | +| `workflowType` | 审批类型 / 流程模板类型 | +| `approvalRequired` | 是否需要审批 | +| `approvalStatus` | `PENDING_APPROVAL`、`APPROVED`、`REJECTED` 等 | +| `legacyTaskId` | 旧 `TaskId` | +| `legacyStepId` | 旧 `StepId` | +| `legacyFlowRemark` | 旧 `FlowRemark` | +| `currentTaskId` | 新流程任务 ID(若后续接入) | +| `currentStepKey` | 新流程节点标识(若后续接入) | +| `approvalComment` | 当前审批意见 | +| `approvedBy` | 审批人 | +| `approvedAt` | 审批时间 | + +### 12.15 审批冻结规则 + +当前冻结以下规则: + +1. 在正式主文档未回写前,不把全量账务领域中的审批模型写成“当前已落地 BPM 事实”。 +2. 当前 guides 底稿允许写: + - 哪些对象需要独立审批流 + - 哪些对象只保留审批能力位 + - 哪些对象仅保留历史审批痕迹 +3. 旧审批流字段必须保留历史追溯能力,不能在迁移设计中直接丢弃。 +4. 后续正式回写时,审批承接需分两个层级写法: + - 当前实现边界 + - 目标设计边界 + +## 13. 与当前正式文档的关系 + +### 13.1 当前已对齐项 + +- `REV-004` 是账务处理域的正式模块编号 +- `IF-REV-007` 是统一账务处理入口 +- `biz_charge*`、`bk_transaction*`、`biz_operat_log*` 是当前正式主文档已经确认的承接对象 + +### 13.2 当前需要后续回写的正式文档 + +后续若该骨架进一步确认,应分批回写: + +1. `docs/design/02_Detailed_Design/12_REV_Detailed.md` +2. `docs/design/03_Technical_Design/01_Database_Design.md` +3. `docs/design/03_Technical_Design/03_Interface_Design.md` +4. `docs/design/01_Overview/03_Summary_Design.md` + +### 13.3 正式回写冻结门禁 + +任一正式主文档启动回写前,至少同时满足以下冻结门禁: + +1. **术语冻结**:账务主对象、审批术语、迁移术语、查询兼容术语已在本底稿中统一,不再存在同义并列写法。 +2. **对象清单冻结**:本批次涉及的业务对象、历史对象、投影对象已明确归层,不存在“是否保留/是否独立”的悬置项。 +3. **关系图冻结**:本批次涉及对象与 `Charge`、`ChargeDetail`、`Transaction`、`AccountingWorkflowRef`、`AccountingLegacyMapping` 的关系已稳定。 +4. **回写范围冻结**:明确本批次只改哪些正式文档、哪些章节、哪些表格、哪些图,不跨批次扩散。 +5. **现状/目标边界冻结**:已明确哪些内容属于“当前正式事实”,哪些内容属于“目标设计口径”,避免把 guides 目标态直接写成现状。 +6. **校验清单冻结**:已明确本批次最小校验动作、校验顺序、台账更新条件。 + +若任一门禁未满足,则允许继续在 `docs/guides/REV004_FULL_ACCOUNTING_DOMAIN_DESIGN.md` 底稿迭代,但不得直接改正式主文档。 + +### 13.4 正式回写批次与顺序 + +建议正式回写严格按以下顺序推进: + +| 批次号 | 目标文档 | 回写重点 | 启动前冻结重点 | 最小校验动作 | +|---|---|---|---|---| +| `RWB-01` | `docs/design/02_Detailed_Design/12_REV_Detailed.md` | 对象边界、场景职责、审批边界、关系骨架 | 对象清单、关系图、状态机 | `make validate-file FILE=docs/design/02_Detailed_Design/12_REV_Detailed.md` | +| `RWB-02` | `docs/design/03_Technical_Design/01_Database_Design.md` | 主表/明细表、索引关注点、历史映射字段、查询投影结构 | 实体字段骨架、表关系、迁移承接方式 | `make validate-file FILE=docs/design/03_Technical_Design/01_Database_Design.md` | +| `RWB-03` | `docs/design/03_Technical_Design/03_Interface_Design.md` | 统一入口 / 专属入口 / 查询接口口径 | 接口承接矩阵、查询出口、现状/目标边界 | `make validate-file FILE=docs/design/03_Technical_Design/03_Interface_Design.md` | +| `RWB-04` | `docs/design/01_Overview/03_Summary_Design.md` | 领域摘要、模块职责、总体口径收敛 | 前三批回写已稳定 | `make validate-file FILE=docs/design/01_Overview/03_Summary_Design.md` | + +冻结顺序必须遵守: + +- 先详设,再数据库,再接口,再总体摘要 +- 上一批未完成校验和基线登记前,不启动下一批 +- 总体摘要只做收敛摘要,不反向引入尚未在详设/数据库/接口文档落地的新事实 + +### 13.5 Archive 快照清单与命名规则 + +正式回写前必须先做 Archive 快照,且快照只用于留档,不作为并行真源。每批至少登记以下信息: + +| 字段 | 说明 | +|---|---| +| `batchNo` | 回写批次号,如 `RWB-01` | +| `sourceFile` | 被回写的正式文档原路径 | +| `snapshotDate` | 快照日期,格式 `YYYY-MM-DD` | +| `sourceCommit` | 回写前 docs 仓基线 commit | +| `snapshotArchivePath` | 快照归档路径 | +| `scopeSummary` | 本批次回写范围摘要 | +| `validatedBy` | 执行校验的责任人/执行方式 | +| `validationResult` | 校验结果摘要 | + +快照命名建议采用: + +`--.md` + +例如: + +- `2026-04-03-RWB-01-12_REV_Detailed.md` +- `2026-04-03-RWB-02-01_Database_Design.md` + +冻结规则: + +1. 快照放入 `Archive/` 下按批次建立的快照目录,不在正式目录旁生成 `*_old.md`、`*_bak.md`、`*_v1.md`。 +2. 同一正式文档若二次回写,必须重新生成新快照,不覆盖旧快照。 +3. 快照记录必须能反查到回写前基线 commit 和对应 guides 章节。 + +### 13.6 基线记录规则 + +每批正式回写必须固定基线,至少包括: + +1. **docs 仓基线**:当前 `water-docs` commit SHA。 +2. **关联实现基线**:若本批次引用了 backend / frontend 已落地实现口径,则同步记录: + - `../water-backend/` commit SHA + - `../water-frontend/` commit SHA +3. **验证日期**:本批次完成校验的日期。 +4. **证据入口**:本批次所引用的 spec / guide / Archive 证据清单。 + +基线记录原则: + +- guides 底稿迭代阶段可以不写入 `Project_Progress`; +- 只有当正式回写批次完成冻结、完成快照、完成最小校验后,才在 `docs/design/00_Management/01_Project_Progress.md` 记正式里程碑; +- 若回写过程中发现对象边界再次变化,应回退到 guides 底稿继续收敛,而不是直接在正式文档中边改边定。 + +### 13.7 单批回写执行模板 + +建议每次正式回写都按以下模板执行: + +1. 确认本批次 `batchNo`、目标文档、回写范围。 +2. 检查 13.3 冻结门禁是否全部满足。 +3. 记录 docs / backend / frontend 基线 commit(若适用)。 +4. 生成 Archive 快照并登记快照路径。 +5. 根据 guides 底稿定向回写正式文档,不跨批次顺手扩写。 +6. 按既定顺序执行最小校验: + - 目标正式文档 `make validate-file` + - `docs/guides/REV004_FULL_ACCOUNTING_DOMAIN_DESIGN.md` 复核 + - 若涉及跨文档锚点/引用变更,再补充 `make check-links` 或小范围链接检查 +7. 校验通过后,更新 `Project_Progress` 里程碑或相应治理台账。 +8. 在批次总结中记录:变更摘要、剩余未回写项、下一批前置条件。 + +### 13.8 `RWB-01` 回写准备:`12_REV_Detailed.md` 范围拆解 + +`RWB-01` 当前只做**详设层回写准备**,目标是先把 `docs/design/02_Detailed_Design/12_REV_Detailed.md` 中 `REV-004 账务处理` 章节的回写范围拆清楚,不在本步骤直接改正式详设正文。 + +#### 13.8.1 本批次锁定的目标章节 + +`RWB-01` 只允许触达 `12_REV_Detailed.md` 中以下小节: + +| 目标章节 | 当前状态 | `RWB-01` 准备动作 | +|---|---|---| +| `## REV-004 账务处理` | 一期最小闭环口径 | 保持模块编号不变,仅准备章节内容扩展方案 | +| `### 功能说明` | 仅覆盖五类一期场景 | 准备扩展为“当前正式边界 + 全量目标对象边界”双层写法 | +| `### 业务流程` | 当前为统一流程图 | 评估是否保留统一流程图并增加分层说明,当前不拆多张场景流程图 | +| `### 关键规则` | 一期规则为主 | 准备补充全量对象承接、审批边界、查询兼容边界 | +| `### 核心数据` | 以 `biz_charge*` / `bk_transaction*` / `biz_operat_log*` 为主 | 准备补充正式业务实体骨架、审批引用、历史映射承接 | +| `### 主要场景` | 仅五类场景 | 准备扩展为全量账务正式场景清单 | +| `### 迁移补充(旧系统承接)` | 旧对象承接矩阵较粗 | 准备替换为更完整的分层承接口径 | +| `### 接口映射` | 维持 `IF-REV-007` / `IF-REV-006` | 准备补充“当前统一入口 + 后续专属入口趋势”说明 | +| `### 落地边界` | 一期实现边界 | 准备改为“当前已落地 / 部分落地 / 目标设计”三层边界 | + +#### 13.8.2 本批次明确纳入范围 + +`RWB-01` 进入正式回写时,准备纳入以下内容: + +1. **对象边界改写**:将 `REV-004` 从“一期五类场景”改写为“当前正式边界仍以统一处理为主、目标设计覆盖全量账务对象”。 +2. **场景清单扩写**:把以下对象纳入详设层正式场景说明: + - `PrepaidRefund` + - `RedinkRecord` + - `WrittenoffAdjust` + - `PriceDiffAdjust` + - `LateFeeReduce` + - `BadDebtRecord` + - `SplitAdjust` + - 特殊开账 / 特账承接方式 + - `RefundBill` + - `CrossCycleWaterRecord` +3. **审批边界写法收敛**:把“审批能力位”和“独立审批流对象”的区分补入详设,但仍不把目标 BPM 写成当前已实现事实。 +4. **迁移承接写法收敛**:把旧对象归层(`L1/L2/L3/L4`)和承接方式(在线主模型 / projection-only / history-readonly / mapping-only)翻译成详设可读语言。 +5. **现状/目标双层表达**:每个关键小节都要同时说明: + - 当前正式实现边界 + - 目标全量设计边界 + +#### 13.8.3 本批次明确排除范围 + +`RWB-01` 不纳入以下动作: + +1. 不修改 `REV-001`、`REV-002`、`REV-003`、`REV-005`、`REV-008` 等其他模块章节。 +2. 不在 `12_REV_Detailed.md` 中直接展开数据库字段级设计;字段级细化留给 `RWB-02`。 +3. 不在本批次新增正式接口编号、接口协议细节、入参出参结构;接口细化留给 `RWB-03`。 +4. 不把目标独立业务实体直接宣称为 backend 已落地物理表。 +5. 不展开完整 BPM 节点流转、审批表结构、流程引擎实现细节。 + +#### 13.8.4 guides 到 `12_REV_Detailed.md` 的回写映射 + +| guides 来源章节 | `12_REV_Detailed.md` 目标小节 | 回写目标 | +|---|---|---| +| `8.1`、`8.2`、`8.3` | `### 功能说明`、`### 主要场景`、`### 核心数据` | 把正式业务实体清单翻译成详设层业务边界与对象说明 | +| `10.1`、`10.2` | `### 关键规则` | 把统一状态机和扩展状态翻译成详设规则表述 | +| `11.1A`、`11.3`、`12.6` | `### 迁移补充(旧系统承接)` | 把迁移承接矩阵翻译成旧系统对象承接说明 | +| `12.7` ~ `12.11` | `### 接口映射`、`### 落地边界` | 保留当前统一入口事实,并增加未来接口拆分趋势说明 | +| `12.12` ~ `12.15` | `### 功能说明`、`### 关键规则`、`### 落地边界` | 明确审批能力位 / 独立审批流 / 历史痕迹三类边界 | +| `13.3` ~ `13.7` | `RWB-01` 执行准备,不直接写入详设正文 | 用于约束批次执行,不直接转抄到正式文档 | + +#### 13.8.5 `RWB-01` 正式改写前的最小准备清单 + +在真正开始改 `12_REV_Detailed.md` 前,至少先完成以下准备: + +1. 为 `REV-004` 章节生成本批次 Archive 快照。 +2. 固定本次回写基线 commit。 +3. 先起草 `REV-004` 小节的新旧对照提纲: + - 保留段 + - 改写段 + - 新增段 + - 暂缓段 +4. 明确当前章节中哪些表述必须保留“一期已落地”措辞,哪些内容可以新增“目标设计”措辞。 +5. 完成后只执行 `12_REV_Detailed.md` 单文件校验,不顺带修改其他正式主文档。 + +#### 13.8.6 `RWB-01` 回写后的验收点 + +`RWB-01` 真正落地时,应至少满足以下验收点: + +1. `REV-004` 章节不再只停留在一期五类场景。 +2. 全量账务核心对象已在详设层可见,但未越级写入字段级数据库设计。 +3. 当前实现边界与目标设计边界可以明确区分。 +4. `IF-REV-007` 当前统一入口事实仍保留,没有被误写成“已完全拆专属接口”。 +5. 审批/BPM 仍保持保守写法,没有把未来流程设计误写成当前事实。 + +#### 13.8.7 `REV-004` 小节新旧对照提纲 + +为后续正式改写 `12_REV_Detailed.md`,当前先冻结以下“保留 / 改写 / 新增 / 暂缓”提纲: + +##### 一、保留段 + +以下内容应保留,但允许做措辞收敛: + +| 当前小节 | 保留原因 | 保留方式 | +|---|---|---| +| `## REV-004 账务处理` 标题与模块编号 | 已是正式模块编号,不应改动 | 原位保留 | +| `### 业务流程` 的统一处理主线 | 统一申请、校验、执行、回写、留痕主线仍成立 | 保留现有统一流程图,再补充“适用于全量对象统一处理主线”的文字说明 | +| `### 关键规则` 中“以账单/交易/日志为统一承接骨架” | 属于当前正式口径核心 | 保留并扩展,不推翻 | +| `### 接口映射` 中 `IF-REV-007`、`IF-REV-006` 的当前事实 | 当前正式接口事实已成立 | 原事实保留,再增加目标趋势说明 | +| `### 落地边界` 中“已落地 / 部分落地 / 文档先行”的写法方向 | 适合承接现状/目标双层表达 | 保留三层写法,但重写对象内容 | + +##### 二、改写段 + +以下内容应整体改写,不再沿用现有一期限定表述: + +| 当前小节 | 当前问题 | 改写方向 | +|---|---|---| +| `### 功能说明` | 只描述一期五类场景,范围过窄 | 改为“当前正式统一处理边界 + 全量目标对象边界”双层说明 | +| `### 关键规则` 第 1 条 | 明确限定一期五类场景 | 改为“当前以统一处理入口承接,目标覆盖全量账务对象” | +| `### 关键规则` 第 6 条 | 将特账、跨周期水量、退款账统一按“未见独立表”处理,口径过粗 | 改为按对象分别说明:特账挂主开账模型、跨周期水量为基础数据对象、退款账为结果对象 | +| `### 核心数据` | 只列出骨架表,缺少正式业务实体层 | 改为“统一骨架 + 独立业务实体 + 审批引用 + 历史映射”四层表述 | +| `### 主要场景` | 仅五类场景,无法承接全量账务 | 改写为全量正式场景矩阵 | +| `### 迁移补充(旧系统承接)` | 仅列少量对象且承接粒度粗 | 改写为按对象分层承接与迁移方式说明 | + +##### 三、新增段 + +以下内容建议在现有小节内部新增,不额外新增新的顶级章节: + +| 归属小节 | 建议新增内容 | 目的 | +|---|---|---| +| `### 功能说明` | “当前正式边界 / 目标设计边界”双段说明 | 避免把目标态误写成现状 | +| `### 关键规则` | 审批承接分层规则 | 把审批能力位 / 独立审批流 / 历史痕迹区分清楚 | +| `### 核心数据` | `AccountingWorkflowRef`、`AccountingLegacyMapping` | 把审批引用和历史映射纳入详设语义层 | +| `### 主要场景` | 全量对象清单表 | 让 `REV-004` 可见完整账务对象族 | +| `### 迁移补充(旧系统承接)` | `L1/L2/L3/L4` 分层说明 + 承接方式枚举 | 和 guides 的迁移策略对齐 | +| `### 接口映射` | “继续保留统一入口”与“后续专属接口趋势”双段说明 | 为 `RWB-03` 接口回写留接口 | +| `### 落地边界` | “当前已落地 / 部分落地 / 目标设计”三段清单 | 保留保守口径并表达目标态 | + +##### 四、暂缓段 + +以下内容当前明确暂缓到后续批次,不在 `RWB-01` 写入正式详设: + +| 暂缓主题 | 暂缓原因 | 预计批次 | +|---|---|---| +| 主表/明细表字段级设计 | 属于数据库设计层,不属于详设层首批回写 | `RWB-02` | +| 独立接口编号、接口协议、报文结构 | 属于接口设计层 | `RWB-03` | +| BPM 节点流转、审批表结构、引擎实现 | 当前只冻结承接边界,不展开实现 | 后续 BPM 专题 / 非 `RWB-01` | +| IC 卡账务在线承接设计 | 当前已冻结为历史只读 + 映射层 | 暂不进入正式在线详设 | +| 报表口径与查询视图细节 | 属于查询/数据库联合专题 | `RWB-02` 或后续专题 | + +##### 五、正式改写时的段落重组建议 + +`REV-004` 正式改写时,建议采用以下段落重组顺序: + +1. `### 功能说明`:先写当前正式边界,再写目标全量边界。 +2. `### 业务流程`:保留统一流程图,补充“适配全量对象”的说明。 +3. `### 关键规则`:按统一骨架、交易校验、结果表达、审批边界、对象承接边界重排。 +4. `### 核心数据`:从“骨架对象”扩展到“骨架 + 独立业务实体 + 审批引用 + 映射对象”。 +5. `### 主要场景`:改成正式业务对象矩阵。 +6. `### 迁移补充(旧系统承接)`:改成旧对象分层承接矩阵。 +7. `### 接口映射`:保留当前统一入口事实,并提示后续接口拆分方向。 +8. `### 落地边界`:明确当前已落地、部分落地、目标设计三层。 + +### 13.9 `RWB-02` 回写准备:`01_Database_Design.md` 范围拆解 + +`RWB-02` 当前只做**数据库专项回写准备**,目标是先把 `docs/design/03_Technical_Design/01_Database_Design.md` 中与账务领域相关的回写范围拆清楚,不在本步骤直接改正式数据库正文。 + +#### 13.9.1 本批次锁定的目标章节 + +`RWB-02` 只允许优先触达 `01_Database_Design.md` 中以下章节: + +| 目标章节 | 当前状态 | `RWB-02` 准备动作 | +|---|---|---| +| `## SYS-002 开账、收费与票据表` | 已形成 `biz_charge*` / `biz_invoice*` / `biz_operat_log*` 统一口径 | 准备扩展为“统一骨架 + 独立业务实体 + 历史映射/查询投影”双层数据库口径 | +| `### biz_charge (营业账主表)` | 当前偏开账/账单主结果对象 | 准备补充其作为全量账务统一骨架主表的承接边界 | +| `### biz_charge_detail (营业账明细表)` | 当前偏开账明细表达 | 准备补充其对特账、价差、违约金等费用差异承接边界 | +| `### biz_operat_log / biz_operat_log_detail` | 当前为一期留痕口径 | 准备升级为全量账务留痕主承接对象说明 | +| `### 旧系统历史台账迁移与只读查询口径` | 当前已区分在线保留 / 历史只读 | 准备补全 `L2/L3/L4` 分层和承接方式枚举 | +| `### 业务表索引` | 当前以现有骨架表索引为主 | 准备补充全量账务查询与映射字段索引关注点 | +| `### 历史数据分区策略` / `### 数据归档策略` | 当前偏通用策略 | 准备补充账务历史映射和查询投影的归档边界说明 | + +#### 13.9.2 本批次明确纳入范围 + +`RWB-02` 进入正式回写时,准备纳入以下内容: + +1. **统一骨架增强**:明确 `biz_charge`、`biz_charge_detail` 不仅承接开账结果,也作为全量账务统一骨架主表/明细表。 +2. **正式业务实体承接矩阵**:把 `PrepaidRefund`、`RedinkRecord`、`WrittenoffAdjust`、`PriceDiffAdjust`、`LateFeeReduce`、`BadDebtRecord`、`SplitAdjust`、特殊开账 / 特账、`RefundBill`、`CrossCycleWaterRecord` 映射到数据库专项的承接方式。 +3. **审批引用 / 历史映射承接**:为 `AccountingWorkflowRef`、`AccountingLegacyMapping` 增加数据库专项承接口径,至少落到“目标对象 / 待补字段 / 历史映射字段”层。 +4. **历史只读 / 查询投影收敛**:把实时收费、对账日志、IC 卡账务等对象按 `projection-only`、`history-readonly`、`mapping-only` 分类写清。 +5. **索引与查询关注点**:补充按账务主单、原单据、审批状态、旧单据映射、账单结果查询的索引关注点,但不在本批次展开完整 DDL。 + +#### 13.9.3 本批次明确排除范围 + +`RWB-02` 不纳入以下动作: + +1. 不在正式数据库文档中直接新增完整建表 SQL、DDL 草案或迁移脚本。 +2. 不为所有目标业务对象立刻宣称“已存在独立物理表”;可采用“目标对象 / 待补字段 / 历史只读”写法。 +3. 不展开接口协议、接口编号、请求响应结构;该部分留给 `RWB-03`。 +4. 不展开 BPM 引擎表结构、流程节点表、审批流引擎实现。 +5. 不修改无关专题(如移动端、METER/INST 专题)现有章节。 + +#### 13.9.4 guides 到 `01_Database_Design.md` 的回写映射 + +| guides 来源章节 | `01_Database_Design.md` 目标小节 | 回写目标 | +|---|---|---| +| `8.1`、`8.2`、`8.3` | `### biz_charge`、`### biz_charge_detail`、`### 旧系统历史台账迁移与只读查询口径` | 把正式业务实体清单翻译成数据库专项承接矩阵 | +| `9.1`、`9.2`、`9.3` | `### biz_charge`、`### biz_charge_detail`、历史只读/投影章节 | 把目标表设计骨架翻译成主表/明细表/投影/映射数据库说明 | +| `10.1`、`10.2` | `### biz_charge`、`### biz_operat_log*` 说明段 | 把状态机要求转化为状态字段、结果字段、审批字段关注点 | +| `11.1A`、`11.3`、`12.1`~`12.6` | `### 旧系统历史台账迁移与只读查询口径` | 对齐迁移承接方式、查询兼容出口和批次设计骨架 | +| `12.12`~`12.15` | `### biz_operat_log*`、目标审批引用对象说明 | 补审批引用对象的数据库承接边界 | +| `13.3`~`13.7` | `RWB-02` 执行准备,不直接写入数据库正文 | 用于约束回写顺序、快照、基线与验证 | + +#### 13.9.5 `RWB-02` 正式改写前的最小准备清单 + +在真正开始改 `01_Database_Design.md` 前,至少先完成以下准备: + +1. 为 `01_Database_Design.md` 生成本批次 Archive 快照。 +2. 固定本次回写基线 commit。 +3. 起草数据库专项的新旧对照提纲: + - 保留段 + - 改写段 + - 新增段 + - 暂缓段 +4. 明确哪些内容只能写成“目标承接口径 / 待补字段”,不能写成“已存在真实表结构”。 +5. 完成后只执行 `01_Database_Design.md` 单文件校验,不顺带改接口设计和总体设计。 + +#### 13.9.6 `RWB-02` 回写后的验收点 + +`RWB-02` 真正落地时,应至少满足以下验收点: + +1. 数据库专项不再只停留在“一期 REV-004 不新增独立细表”的被动描述。 +2. 全量账务对象已在数据库专项中有明确承接方式:在线骨架、目标对象、查询投影或历史映射。 +3. `biz_charge`、`biz_charge_detail`、`biz_operat_log*` 的账务承接边界得到加强,但未误写为所有对象都已物理落表。 +4. `AccountingWorkflowRef`、`AccountingLegacyMapping` 至少在数据库专项中被正式命名并建立承接边界。 +5. 历史只读、查询投影、IC 卡账务等对象的数据库边界表达清楚,不与在线主写口径混淆。 + +#### 13.9.7 `01_Database_Design.md` 新旧对照提纲 + +为后续正式改写 `01_Database_Design.md`,当前先冻结以下“保留 / 改写 / 新增 / 暂缓”提纲: + +##### 一、保留段 + +以下内容应保留,但允许做措辞收敛: + +| 当前小节 | 保留原因 | 保留方式 | +|---|---|---| +| `## SYS-002 开账、收费与票据表` | 已是正式数据库专题入口 | 原位保留,扩展其账务领域职责 | +| `### biz_charge`、`### biz_charge_detail` 现有真实表说明 | 已与当前 backend / 正式文档对齐 | 保留真实表事实,再增加目标承接口径 | +| `### biz_operat_log / biz_operat_log_detail` 留痕口径 | 仍是当前正式留痕主入口 | 保留并扩展为全量账务留痕骨架 | +| `### 旧系统历史台账迁移与只读查询口径` 的章节位置 | 已经是迁移承接的正式入口 | 原位保留,改写内部矩阵和边界 | +| `### 业务表索引` 中现有索引写法 | 已反映当前真实表事实 | 保留现状索引,再补充目标关注点 | + +##### 二、改写段 + +以下内容应整体改写或增强: + +| 当前小节 | 当前问题 | 改写方向 | +|---|---|---| +| `> REV-004 承接口径` | 仍停留在“一期不新增独立细表” | 改为“当前统一骨架 + 全量目标对象承接矩阵” | +| `### biz_charge` / `### biz_charge_detail` 的说明 | 偏开账/账单生成语义 | 增强为全量账务统一骨架语义 | +| `### biz_operat_log*` 边界说明 | 仅覆盖一期留痕 | 改为覆盖全量账务操作留痕、审批留痕、原单据关联 | +| `### 旧系统历史台账迁移与只读查询口径` | 对象粒度仍较粗 | 改为按对象 + 分层 + 承接方式说明 | +| `### 业务表索引` | 缺少旧单据映射、审批状态、结果对象查询关注点 | 增补索引关注点说明 | + +##### 三、新增段 + +以下内容建议在现有章节中新增,不单独新增新的数据库专题大章: + +| 归属小节 | 建议新增内容 | 目的 | +|---|---|---| +| `### biz_charge` / `### biz_charge_detail` | 目标承接字段组说明 | 对齐主表/明细表如何承接全量账务对象 | +| `### biz_operat_log*` | 全量账务留痕字段关注点 | 明确处理类型、原交易引用、审批痕迹、附件依据 | +| 迁移与只读查询章节 | `AccountingLegacyMapping` | 正式命名历史映射承接对象 | +| 迁移与只读查询章节 | `AccountingWorkflowRef` 的数据库关注点 | 为审批引用对象留数据库专题锚点 | +| 索引与归档章节 | 账务查询投影 / 历史映射索引和归档关注点 | 让后续 DDL 与报表承接有明确方向 | + +##### 四、暂缓段 + +以下内容当前明确暂缓到后续批次或实现阶段,不在 `RWB-02` 写入正式数据库文档: + +| 暂缓主题 | 暂缓原因 | 预计批次 | +|---|---|---| +| 完整独立实体表 DDL | 当前只冻结承接边界和待补字段,不直接下沉为实现脚本 | 后续实现 / 专项 DDL | +| 专属接口入参出参与表字段一一映射 | 属于接口专题 | `RWB-03` | +| BPM 引擎表 / 节点表 / 流转表 | 当前不展开完整审批实现 | 后续 BPM 专题 | +| IC 卡账务在线主写表设计 | 当前冻结为历史只读 + 映射层 | 暂不进入在线数据库设计 | +| 报表视图最终字段清单 | 需要结合统计/查询专题再收敛 | `RWB-04` 或后续专题 | + +##### 五、正式改写时的段落重组建议 + +`01_Database_Design.md` 正式改写时,建议采用以下重组顺序: + +1. 先保留 `SYS-002 开账、收费与票据表` 的现状真实表事实。 +2. 在 `biz_charge` / `biz_charge_detail` 下补充“统一骨架承接边界”。 +3. 在 `biz_operat_log*` 下补充“全量账务留痕和审批痕迹关注点”。 +4. 重写“旧系统历史台账迁移与只读查询口径”为对象分层矩阵。 +5. 在索引、归档、历史数据策略处补充账务映射和查询投影关注点。 + +### 13.10 `RWB-03` 回写准备:`03_Interface_Design.md` 范围拆解 + +`RWB-03` 当前只做**接口专项回写准备**,目标是先把 `docs/design/03_Technical_Design/03_Interface_Design.md` 中与账务领域相关的回写范围拆清楚,不在本步骤直接改正式接口正文。 + +#### 13.10.1 本批次锁定的目标章节 + +`RWB-03` 只允许优先触达 `03_Interface_Design.md` 中以下章节: + +| 目标章节 | 当前状态 | `RWB-03` 准备动作 | +|---|---|---| +| `### IF-REV-007 账务调整接口` | 当前仍是一期五类场景统一入口 | 准备扩展为“当前统一入口事实 + 全量对象承接边界”双层接口写法 | +| `### IF-REV-007 请求/响应参数` | 当前参数偏一期通用处理 | 准备补充全量对象通用字段、审批边界字段、结果对象区分字段 | +| `## 历史查询与迁移校验接口口径` | 当前已形成历史查询原则 | 准备补充全量账务对象查询出口、历史只读 / 投影查询口径 | +| `## 数据对象与表口径` | 当前偏现有骨架表 | 准备补充目标对象、审批引用对象、历史映射对象的接口层命名边界 | +| `## 实现状态说明` | 当前已落地 / 部分落地 / 文档先行 | 准备同步收敛“当前统一入口已落地、专属接口为后续目标” | +| `### IF-CS-002 历史账单查询接口`(必要时) | 当前偏账单/费用历史查询 | 仅在需要时补充与全量账务历史查询的边界关系,不改其主职责 | + +#### 13.10.2 本批次明确纳入范围 + +`RWB-03` 进入正式回写时,准备纳入以下内容: + +1. **统一入口边界增强**:保留 `IF-REV-007` 当前正式统一入口事实,同时明确其当前承接全量账务对象的统一入口地位。 +2. **对象承接矩阵接口化**:把 `PrepaidRefund`、`RedinkRecord`、`WrittenoffAdjust`、`PriceDiffAdjust`、`LateFeeReduce`、`BadDebtRecord`、`SplitAdjust`、特殊开账 / 特账、`RefundBill`、`CrossCycleWaterRecord` 映射到接口承接方式。 +3. **当前统一入口 / 后续专属接口双层写法**:数据库和详设已经回写的对象,在接口文档中要明确: + - 当前是否继续挂 `IF-REV-007` + - 后续是否建议拆专属接口 +4. **查询接口分层**:把“业务对象查询接口”和“历史只读 / 投影查询接口”分层口径正式写入接口专项。 +5. **审批能力位边界**:把 `approvalRequired`、`approvalStatus`、审批引用语义纳入接口边界,但不展开 BPM 流程实现。 + +#### 13.10.3 本批次明确排除范围 + +`RWB-03` 不纳入以下动作: + +1. 不直接新增一整套新的正式接口编号族,除非文档明确写成“后续建议编号 / 后续拆分方向”。 +2. 不展开完整 BPM API、审批节点流转 API、流程引擎接口。 +3. 不展开数据库字段级设计;该部分已由 `RWB-02` 承接。 +4. 不修改与账务无关的 `CS`、`METER`、`INST` 主接口章节。 +5. 不把目标专属接口误写成当前 backend 已完整提供的既成事实。 + +#### 13.10.4 guides 到 `03_Interface_Design.md` 的回写映射 + +| guides 来源章节 | `03_Interface_Design.md` 目标小节 | 回写目标 | +|---|---|---| +| `8.1`、`8.2`、`8.3` | `### IF-REV-007`、`## 数据对象与表口径` | 把正式业务实体清单翻译成接口承接边界 | +| `10.1`、`10.2` | `### IF-REV-007 响应参数`、状态约束说明 | 把统一状态机与扩展状态翻译成接口结果状态语义 | +| `12.7`~`12.11` | `### IF-REV-007`、历史查询章节、实现状态说明 | 对齐统一入口、专属入口趋势和查询接口分层 | +| `12.12`~`12.15` | `### IF-REV-007 请求/响应参数`、约束说明 | 对齐审批能力位、审批状态与接口边界 | +| `13.3`~`13.7` | `RWB-03` 执行准备,不直接写入接口正文 | 用于约束快照、基线、验证和回写顺序 | + +#### 13.10.5 `RWB-03` 正式改写前的最小准备清单 + +在真正开始改 `03_Interface_Design.md` 前,至少先完成以下准备: + +1. 为 `03_Interface_Design.md` 生成本批次 Archive 快照。 +2. 固定本次回写基线 commit。 +3. 起草接口专项的新旧对照提纲: + - 保留段 + - 改写段 + - 新增段 + - 暂缓段 +4. 明确哪些内容可以写成“当前统一入口事实”,哪些内容只能写成“后续专属接口方向”。 +5. 完成后只执行 `03_Interface_Design.md` 单文件校验,不顺带改总体设计。 + +#### 13.10.6 `RWB-03` 回写后的验收点 + +`RWB-03` 真正落地时,应至少满足以下验收点: + +1. `IF-REV-007` 不再只对应一期五类场景,而是能表达全量账务对象的统一入口边界。 +2. 当前统一入口事实与后续专属接口方向可以清楚区分。 +3. 历史查询与迁移校验接口口径已能覆盖全量账务对象的查询出口。 +4. 审批能力位、审批状态和结果状态语义已在接口文档中形成统一口径。 +5. 未把目标专属接口误写成当前 backend 已完整落地能力。 + +#### 13.10.7 `03_Interface_Design.md` 新旧对照提纲 + +为后续正式改写 `03_Interface_Design.md`,当前先冻结以下“保留 / 改写 / 新增 / 暂缓”提纲: + +##### 一、保留段 + +以下内容应保留,但允许做措辞收敛: + +| 当前小节 | 保留原因 | 保留方式 | +|---|---|---| +| `### IF-REV-007 账务调整接口` 的接口编号 | 已是当前正式接口编号 | 原位保留,不随意改号 | +| `IF-REV-007` 当前统一入口事实 | 已与详设/数据库正式文档对齐 | 保留事实,再扩展对象边界 | +| `## 历史查询与迁移校验接口口径` 章节位置 | 已是查询承接的正式入口 | 原位保留,增强全量账务查询出口 | +| `## 实现状态说明` 中“已落地 / 部分落地 / 文档先行”结构 | 适合承接现状/目标分层表达 | 保留结构,重写账务对象内容 | + +##### 二、改写段 + +以下内容应整体改写或增强: + +| 当前小节 | 当前问题 | 改写方向 | +|---|---|---| +| `### IF-REV-007 账务调整接口` 功能描述 | 仍限定在一期五类场景 | 改为“当前统一入口 + 全量账务对象承接边界” | +| `### IF-REV-007` 请求/响应参数 | 参数仍偏一期通用处理 | 增强为支持对象类型、审批边界、结果状态表达 | +| `## 数据对象与表口径` | 对目标对象、审批引用、映射对象命名不足 | 增补全量对象接口层命名边界 | +| `## 历史查询与迁移校验接口口径` | 还未显式覆盖全量账务对象查询分层 | 增强为业务对象查询 + 历史只读 / 投影查询双层口径 | +| `## 实现状态说明` | 尚未体现统一入口与专属接口的双层状态 | 改为“当前统一入口已落地 / 专属接口为后续方向” | + +##### 三、新增段 + +以下内容建议在现有章节中新增,不单独新开一套正式接口大章: + +| 归属小节 | 建议新增内容 | 目的 | +|---|---|---| +| `### IF-REV-007` | 对象承接矩阵 | 明确哪些对象当前挂统一入口 | +| `### IF-REV-007 请求/响应参数` | `objectType`、`approvalStatus`、`resultStatus` 等语义说明 | 强化全量对象的统一表达能力 | +| 历史查询章节 | 全量账务对象查询出口分层表 | 明确业务对象查询与历史只读查询的边界 | +| 实现状态章节 | “后续专属接口方向”说明 | 为后续接口拆分留正式口径 | + +##### 四、暂缓段 + +以下内容当前明确暂缓到后续批次或实现阶段,不在 `RWB-03` 写入正式接口文档: + +| 暂缓主题 | 暂缓原因 | 预计批次 | +|---|---|---| +| 全套专属接口编号正式发布 | 当前仍以统一入口为正式事实 | 后续接口专题 | +| BPM API / 审批流 API | 当前只冻结审批能力位边界 | 后续 BPM 专题 | +| 与目标数据库字段的一一映射表 | 会使接口文档过度下沉到数据库层 | 后续实现 / 补充专题 | +| IC 卡账务在线接口 | 当前冻结为历史只读 + 映射层 | 暂不进入在线接口设计 | +| 查询报表的最终导出字段清单 | 需结合统计/查询专题进一步收敛 | `RWB-04` 或后续专题 | + +##### 五、正式改写时的段落重组建议 + +`03_Interface_Design.md` 正式改写时,建议采用以下重组顺序: + +1. 先保留 `IF-REV-007` 当前统一入口的正式事实。 +2. 在接口说明中扩展全量对象承接边界。 +3. 在请求/响应参数中补充对象类型、审批边界、结果状态语义。 +4. 重写历史查询与迁移校验章节,使其覆盖全量账务对象查询出口。 +5. 在实现状态说明中明确“当前已落地 / 后续专属接口方向”。 + +### 13.11 `RWB-04` 回写准备:`03_Summary_Design.md` 范围拆解 + +`RWB-04` 当前只做**总体摘要回写准备**,目标是先把 `docs/design/01_Overview/03_Summary_Design.md` 中与 REV-004 账务领域相关的摘要口径拆清楚,不在本步骤之外扩写超过概要层。 + +#### 13.11.1 本批次锁定的目标章节 + +`RWB-04` 只允许优先触达以下章节: + +| 目标章节 | 当前状态 | `RWB-04` 准备动作 | +|---|---|---| +| `主要接口定义`(总体接口表) | 缺少 `IF-REV-007` | 补入统一账务处理入口摘要定义 | +| `子系统2设计: 营收业务系统 -> 子系统外部接口` | 缺少 `IF-REV-007` | 同步补入 REV-004 对外接口摘要口径 | +| `营收核心模块群` 概述 | 仍保留“一期先聚焦”旧摘要 | 改为“当前统一入口 + 全量对象目标边界”双层摘要 | +| `营收核心模块群` 模块列表 | `REV-004` 描述过窄 | 扩展为全量账务对象承接摘要 | +| `#### REV-004: 账务处理` | 仅写未销账调整/分账/预付款退款/呆坏账 | 改为概要层的对象族 + 承接边界描述 | + +#### 13.11.2 本批次明确纳入范围 + +`RWB-04` 进入正式回写时,准备纳入以下内容: + +1. 在概要层明确 `IF-REV-007` 当前仍是 REV-004 正式统一入口。 +2. 将 `REV-004` 的摘要从“一期五类处理”提升为“当前统一入口 + 全量账务对象目标边界”。 +3. 在概要层列出核心对象族,但不下沉到数据库字段、接口参数、BPM 节点细节。 +4. 同步收敛“当前已落地 / 目标设计 / 历史只读”的高层边界。 + +#### 13.11.3 本批次明确排除范围 + +`RWB-04` 不纳入以下动作: + +1. 不在概要设计中重复详设/数据库/接口的字段级细节。 +2. 不新增专门的账务关系图或复杂流程图,除非为消除明显口径冲突所必需。 +3. 不把目标对象写成已全部实现的既成事实。 +4. 不修改与 REV-004 无关的子系统摘要章节。 + +#### 13.11.4 guides 到 `03_Summary_Design.md` 的回写映射 + +| guides 来源章节 | `03_Summary_Design.md` 目标小节 | 回写目标 | +|---|---|---| +| `8.1`、`8.2`、`8.3` | 营收核心模块群概述、`REV-004` 模块描述 | 把正式业务实体清单翻译成概要层对象族摘要 | +| `12.7`~`12.11` | 主要接口定义、营收业务系统子系统外部接口 | 把统一入口与查询分层趋势翻译成概要层接口摘要 | +| `12.12`~`12.15` | `REV-004` 模块描述 | 把审批能力位/审批边界翻译成概要层约束说明 | +| `13.3`~`13.7` | `RWB-04` 执行准备,不直接写入概要正文 | 用于约束快照、基线和验证 | + +#### 13.11.5 `RWB-04` 正式改写前的最小准备清单 + +在真正开始改 `03_Summary_Design.md` 前,至少先完成以下准备: + +1. 为 `03_Summary_Design.md` 生成本批次 Archive 快照。 +2. 固定本次回写基线 commit。 +3. 明确概要层只写模块职责、接口摘要、实现边界,不越级展开。 +4. 完成后执行 `03_Summary_Design.md` 单文件校验,并复核与前三批正式文档口径一致。 + +## 14. 逐步细化计划 + +建议按以下顺序继续细化: + +### 第一步:对象定版 + +完成以下事项: + +- 确认正式业务实体清单 +- 确认哪些对象保留汇总/明细双表 +- 确认哪些对象只保留查询投影 + +### 第二步:字段骨架定版 + +逐对象补齐: + +- 主键 +- 单号 +- 状态 +- 原对象引用 +- 审批字段 +- 金额/水量前后差异字段 +- 查询索引字段 + +### 第三步:关系与状态机定版 + +逐对象明确: + +- 与 `Charge` / `ChargeDetail` / `Transaction` / `AccountLog` 的关系 +- 与统一骨架的关系 +- 与审批流的关系 +- 状态机 + +### 第四步:迁移方案定版 + +逐对象明确: + +- 旧表映射 +- 历史迁移规则 +- 兼容查询规则 +- 报表承接方式 + +### 第五步:正式文档回写 + +将已定版内容分批同步到: + +- 详细设计 +- 数据库设计 +- 接口设计 +- 总体设计摘要 + +执行顺序固定为: + +1. 先完成 `RWB-01` 详设回写,稳定对象边界与审批边界。 +2. 再完成 `RWB-02` 数据库回写,落主表/明细表/映射字段骨架。 +3. 再完成 `RWB-03` 接口回写,收敛统一入口、专属入口与查询接口。 +4. 最后完成 `RWB-04` 总体摘要回写,只做总览收敛。 + +每一批回写都必须按以下顺序校验: + +1. 回写前确认冻结门禁、批次号、目标章节与 Archive 快照。 +2. 回写后先执行目标文档 `make validate-file`。 +3. 再复核 `docs/guides/REV004_FULL_ACCOUNTING_DOMAIN_DESIGN.md` 与正式文档是否一致。 +4. 如改动了跨文档引用或标题锚点,再执行小范围链接检查。 +5. 校验通过后再更新 `Project_Progress` 或相关治理台账。 + +## 15. 当前待确认问题 + +以下问题按当前证据收敛为两类:已可冻结结论 / 仍待确认问题。 + +### 15.1 已可冻结结论 + +#### 15.1.1 红冲 + +- **结论**:`红冲` 继续作为**独立正式业务对象**保留。 +- **依据**: + - 操作手册明确存在独立菜单 `【营业收费】-【红冲记录】`,并支持查询、导出和详情展开。 + - `12_REV_Detailed.md` 明确红冲记录是收费差错追溯的重要入口。 +- **当前冻结判断**: + - 红冲作为独立业务对象保留。 + - 红冲查询能力必须独立保留。 + - 是否需要**单独审批流**,当前仍保留为待确认;本轮仅冻结“红冲不是普通附属字段,而是独立场景对象”。 + +#### 15.1.2 分账调整 + +- **结论**:`分账调整` 继续作为**独立正式业务对象**保留,并且**明确存在多个分摊策略**。 +- **依据**: + - 操作手册明确在 `未销调整 > 分账` 中支持: + - 按水量分账 + - 按费用组成分账 + - `12_REV_Detailed.md` 已把分账调整视为“费用组成重分摊场景”承接。 +- **当前冻结判断**: + - 分账调整必须保留独立业务语义。 + - 分账调整后续应补**规则表或规则字段组**,因为至少已存在两类分摊策略,不宜只靠单一通用明细字段兜底。 + +#### 15.1.3 违约金减免 + +- **结论**:`违约金减免` 继续作为**独立正式业务对象**保留。 +- **依据**: + - 操作手册明确存在独立能力,并支持: + - 按金额 + - 按日期 + - 批量处理 + - 数据字典中存在 `PM_LATEFEE_RECORDS` / `PM_LATEFEE_RECORD_DETAILS`。 +- **当前冻结判断**: + - 违约金减免不应再退化为普通金额调整子类型。 + - 其主单/明细结构保留合理。 + +#### 15.1.4 价差调整 + +- **结论**:`价差调整` 继续作为**独立正式业务对象**保留。 +- **依据**: + - 操作手册明确支持: + - 调价号 + - 用水性质 + - 阶梯计费勾选 + - 数据字典存在 `PM_PRICE_RECORDS` / `PM_PRICE_RECORD_DETAILS` + - `12_REV_Detailed.md` 已把价差调整作为“重算与差额修正场景”承接。 +- **当前冻结判断**: + - 价差调整必须保留独立业务语义。 + - 其与价格体系、阶梯计费和累计量关系应在后续字段设计中继续展开。 + +#### 15.1.5 呆坏账调整 + +- **结论**:`呆坏账` 继续作为**独立正式业务对象**保留。 +- **依据**: + - 操作手册明确至少区分: + - 呆账 + - 坏账 + - 纠纷账 + - 且可恢复性不同。 + - 数据字典中有独立表族;`12_REV_Detailed.md` 已按坏账申请与生效场景承接。 +- **当前冻结判断**: + - `BadDebtRecord` 必须保留独立主单与明细承接。 + - `呆账/坏账/纠纷账` 至少应作为类型枚举保留。 + +#### 15.1.6 已销调整 / 预存调整 / 账务日志 + +- **结论**:三者在旧系统中都属于账务处理主模块下的正式子模块,应在新系统设计中保留独立业务语义或独立查询入口。 +- **依据**: + - 操作手册账务处理章节明确把: + - 未销调整 + - 已销调整 + - 预存调整 + - 账务日志 + 作为正式功能子模块描述。 +- **当前冻结判断**: + - `已销调整` 继续保留为正式业务实体。 + - `预存调整` 至少需要在后续继续明确它与 `PrepaidRefund`、账户调整、余额迁移之间的边界。 + - `账务日志` 继续作为统一查询/审计出口保留。 + +### 15.2 仍待确认问题 + +#### 15.1.7 特账 + +- **结论**:`特账` 更符合“**特殊开账产生的特殊账单 / 收费类型**”,不建议直接定义为独立 `L2` 账务处理实体。 +- **依据**: + - 操作手册和需求文档明确存在 `特殊开账`,并说明其主要针对罚款类型、可直接开账、可直接收费。 + - 数据字典中 `FeeType` 明确包含 `3 = 特账`,说明它更接近账单/收费类型,而不是独立申请单。 + - 当前正式文档 `12_REV_Detailed.md`、`01_Database_Design.md` 已倾向于把特殊开账统一挂到 `biz_charge` / `biz_charge_detail` 承接。 +- **当前冻结判断**: + - 特账优先由 `Charge` / `ChargeDetail` 主模型承接。 + - 应通过 `sourceType`、`feeType`、`specialBillType`、`reasonCode` 等字段区分。 + - 不建议当前先独立建设 `SpecialAccountRecord` / `SpecialAccountRecordDetail`。 + +#### 15.2.2 退款账 + +- **当前状态**:已可冻结为**结果型正式账务对象**。 +- **原因**: + - 数据字典存在 `AT_REFUNDS`,并出现 `RefundId`、`RefundNumber`、`RefundPrice` 等字段,说明旧系统存在正式退款结果对象,而不是只有退款动作。 + - 旧需求文档同时出现: + - 账务退款 + - 预付款退款 + - 多缴退款 / 错误缴费退款等退款语义 + 说明退款在旧系统中不是单一按钮,而是一组正式业务场景。 + - `specs/008` 中 `AT_REFUNDS` 被映射为旧对象 `退款账`,并被视为弱映射/当前缺口之一。 +- **当前冻结判断**: + - `退款账` 与 `PrepaidRefund` 不是同一概念。 + - `PrepaidRefund` 更偏退款申请/处理流程对象。 + - `RefundBill` 应作为退款处理完成后形成的**正式账务结果对象**保留。 + - `RefundBill` 至少应承接: + - 原账单 / 原收费 / 原交易关系 + - 退款金额 + - 退款状态 + - 退款时间 + - 退款人员 + - 退款单号 / 退款流水号 +- **后续待细化点**: + - 哪几类退款场景共用同一 `RefundBill` + - 是否需要独立明细表 + - 与 `Transaction`、`Charge`、收费明细中退费记录的关系如何建模 + +#### 15.2.3 跨周期水量 + +- **当前状态**:已可冻结为**独立基础数据对象**。 +- **原因**: + - 数据字典将其放在“账务信息”层,而不是“收费、账务处理”动作层。 + - 字段包含 `PriceCode`、`PriceItemId`、`LevelType`、`LevelIndex`、`StartWater`、`EndWater`、`UsedWater`、`LeftWater`、`IsSystemComputed`,更符合跨账期计费、阶梯累计和账单重算支撑对象特征。 + - 当前正式文档虽然未把它认定为已实现独立表,但也未否定其业务语义,只是避免误写为现成在线实体。 +- **当前冻结判断**: + - `CrossCycleWaterRecord` 应保留为独立基础数据对象。 + - 它不是强流程型业务单,不宜按退款/红冲/坏账那种申请单模式建模。 + - 若后续涉及审批,应由关联业务场景(如价差调整、未销调整)带出,而不是由跨周期水量对象自身承接审批流。 + +#### 15.2.4 IC 卡账务 + +- **当前状态**:旧系统正式存在,当前按**历史只读 + 映射层**承接。 +- **原因**: + - 操作手册未检索到 `IC卡` 相关账务入口,因此无法证明它仍是当前营收主操作流程的一部分。 + - 数据字典存在 `IC卡充退表`、`IC卡充退账明细表`、`IC卡结余记录`、`IC卡操作日志`。 + - Archive `数据库设计.md` 还给出了 `IC卡表-biz_smartcard`、`IC卡充退表-biz_smartcard_log`、`IC卡充退帐明细表-biz_smartcard_log_detail`、`IC卡结余记录-biz_smartcard_odd_log`、`IC卡操作日志-biz_smartcard_operate_log` 的完整建模说明。 + - `BACKEND_TABLE_MAPPING.md` 当前将其列为旧系统账务中的明显缺口之一。 +- **当前冻结判断**: + - IC 卡账务在旧系统中属于正式对象族。 + - 当前新系统设计不将其纳入在线主写模型。 + - 当前统一按**历史只读查询 + 新旧标识映射**承接。 + - 后续如业务范围发生变化,再单独评估是否升级为独立子域。 + +## 16. 本文档当前状态说明 + +本文档当前完成的是: + +- 目标建模路线定版 +- 分层结构定版 +- 正式业务实体清单定版 +- 关系图骨架定版 +- 目标表设计骨架定版 +- 后续逐步细化路径定版 + +本文档当前尚未完成的是: + +- 每个实体字段级完整设计 +- 数据库物理字段逐列定义 +- 完整接口合同拆分 +- 完整迁移 SQL/脚本设计 +- backend 代码实现方案 diff --git a/docs/evidence/rev004-accounting/REV004_IMPLEMENTATION_HANDOFF.md b/docs/evidence/rev004-accounting/REV004_IMPLEMENTATION_HANDOFF.md new file mode 100644 index 0000000..8e03129 --- /dev/null +++ b/docs/evidence/rev004-accounting/REV004_IMPLEMENTATION_HANDOFF.md @@ -0,0 +1,563 @@ +# REV-004 全量账务实现分发清单 + +## 1. 文档目的 + +本文用于将 `REV-004` 全量账务领域的当前正式口径,整理为可直接分发给前后端实现 Agent 的任务清单、需求边界与协作约束,避免后续实现阶段再次回到“一期最小闭环”或“旧表整表平移”的摇摆状态。 + +## 2. 当前统一口径 + +### 2.1 当前正式事实 + +- 当前正式统一入口:`IF-REV-007` +- `REV-004` 已在概要、详设、数据库、接口四层正式文档中完成首轮收口 +- 当前正式表达仍采用: + - 当前事实 + - 目标设计 + - 历史只读 / 映射层 + 三层分离口径 + +### 2.2 当前目标对象范围 + +当前全量账务对象范围包括: + +- `PrepaidRefund` +- `RedinkRecord` +- `WrittenoffAdjust` +- `PriceDiffAdjust` +- `LateFeeReduce` +- `BadDebtRecord` +- `SplitAdjust` +- 特殊开账 / 特账 +- `RefundBill` +- `CrossCycleWaterRecord` + +### 2.3 当前设计约束 + +1. 不得把目标设计写成当前已全部实现事实。 +2. 当前统一入口仍是 `IF-REV-007`,不能在未明确批准前直接改成多套正式专属接口编号。 +3. 旧系统对象必须分层承接: + - 在线统一骨架 + - 独立业务对象 + - 查询投影对象 + - 历史只读 / 映射对象 +4. Archive 原始资料为证据来源,不作为当前实现修改目标。 + +--- + +## 3. 分发给后端 Agent 的功能清单 + +### BE-01 统一账务处理入口扩展 + +**目标** +扩展 `IF-REV-007`,使其从一期五类场景提升为可承接全量账务对象的统一入口。 + +**需求** +后端统一入口需支持以下对象类型: + +- `PREPAID_REFUND` +- `REDINK_RECORD` +- `WRITTENOFF_ADJUST` +- `PRICE_DIFF_ADJUST` +- `LATE_FEE_REDUCE` +- `BAD_DEBT_RECORD` +- `SPLIT_ADJUST` +- `SPECIAL_BILLING` +- `REFUND_BILL` +- `CROSS_CYCLE_WATER` + +**最小输入要求** + +- `chargeId` +- `objectType` +- `adjustType`(兼容保留) +- `adjustAmount` +- `adjustUsage` +- `sourceTradeNo` +- `relatedBizNo` +- `reasonCode` +- `approvalRequired` +- `remark` +- `attachmentList` +- `operatorId` + +**最小输出要求** + +- `adjustmentNo` +- `chargeId` +- `objectType` +- `resultStatus` +- `writeBackStatus` +- `approvalRequired` +- `approvalStatus` +- `resultObjectNo` +- `msg` + +**验收重点** + +- `IF-REV-007` 仍是当前统一入口 +- 不要求一次性拆专属接口 +- `objectType` 成为统一对象表达核心字段 + +--- + +### BE-02 账务对象服务层分派机制 + +**目标** +建立 `objectType -> handler/service` 分派机制。 + +**需求** +至少按对象族拆分内部处理逻辑: + +- 预存退款处理 +- 红冲处理 +- 已销调整处理 +- 价差调整处理 +- 违约金减免处理 +- 坏账处理 +- 分账调整处理 +- 特账 / 特殊开账处理 +- 退款结果对象处理 +- 跨周期水量支撑处理 + +**验收重点** + +- 外部继续统一入口 +- 内部分派清晰 +- 不再把所有对象混成单一“金额调整”逻辑块 + +--- + +### BE-03 审批边界承接 + +**目标** +统一承接审批能力位,而不是直接落完整 BPM。 + +**需求** +至少保留: + +- `approvalRequired` +- `approvalStatus` +- `legacyTaskId` +- `legacyStepId` +- `legacyFlowRemark` + +**当前对象分层要求** + +- 倾向独立审批流对象: + - `PrepaidRefund` + - `BadDebtRecord` +- 当前先保留审批能力位: + - `WrittenoffAdjust` + - `PriceDiffAdjust` + - `LateFeeReduce` + - `SplitAdjust` + - `RedinkRecord` +- 不单独审批: + - `RefundBill` + - `CrossCycleWaterRecord` + +**验收重点** + +- 承接审批语义即可 +- 本轮不要求直接接完整 BPM 引擎 + +--- + +### BE-04 统一留痕能力增强 + +**目标** +强化 `biz_operat_log` / `biz_operat_log_detail` 的账务承接能力。 + +**需求** +至少留痕: + +- 对象类型 +- 目标账单 +- 原交易引用 +- 原业务单号 +- 原因说明 +- 金额/水量前后差异 +- 审批状态 +- 操作人 +- 操作时间 +- 附件依据 + +**验收重点** + +- 各账务对象都能统一追溯 +- 能支撑历史查询和迁移核查 + +--- + +### BE-05 数据库统一骨架承接 + +**目标** +继续以 `biz_charge` / `biz_charge_detail` 为统一骨架,不盲目整表平移。 + +**需求** +后端实现需遵循: + +- 新发生业务优先挂统一骨架 +- 不强制每个对象立刻单独建表 +- 对目标对象允许先通过: + - 统一骨架 + - 目标字段组 + - 历史映射 + 进行承接 + +**特别要求** +需重点考虑后续承接的目标对象: + +- `AccountingWorkflowRef` +- `AccountingLegacyMapping` + +--- + +### BE-06 历史只读 / 映射层查询承接 + +**目标** +旧系统细粒度台账不能丢,需要有后端查询承接。 + +**至少保留查询能力的对象** + +- 红冲记录 +- 预存退款历史 +- 已销调整历史 +- 价差调整历史 +- 分账调整历史 +- 违约金减免历史 +- 坏账历史 +- 退款账结果 +- 跨周期水量 +- 实时收费日志 +- 对账日志 +- IC 卡账务 + +**验收重点** + +- 不要求这些对象都转成在线主写表 +- 但必须可查、可追溯、可迁移验收 + +--- + +### BE-07 统一查询出口能力 + +**目标** +准备两类查询能力: + +#### 第一类:业务对象查询 + +面向: + +- `PrepaidRefund` +- `RedinkRecord` +- `WrittenoffAdjust` +- `PriceDiffAdjust` +- `LateFeeReduce` +- `BadDebtRecord` +- `SplitAdjust` +- `RefundBill` + +#### 第二类:历史只读 / 投影查询 + +面向: + +- 实时收费 +- 对账日志 +- 柜台结账 +- IC 卡账务 +- 历史账务台账 + +**验收重点** + +- 至少按 `objectType` 可区分 +- 支持汇总对账 + 明细追溯 + +--- + +## 4. 分发给前端 Agent 的功能清单 + +### FE-01 统一账务处理入口页面改造 + +**目标** +前端继续使用统一账务处理入口,但支持全量对象类型。 + +**需求** +至少支持: + +- 对象类型选择 / 识别 +- 按对象动态显示字段 +- 审批状态展示 +- 处理结果展示 +- 账单回写状态展示 + +**最低对象类型支持** + +- 预存退款 +- 红冲 +- 已销调整 +- 价差调整 +- 违约金减免 +- 坏账 +- 分账调整 +- 特账 +- 退款账结果查询 +- 跨周期水量查询 + +--- + +### FE-02 对象查询页 / 结果页分层 + +**目标** +查询页按两层口径组织。 + +#### 业务对象查询页 +至少展示: + +- 单号 +- 对象类型 +- 关联账单 +- 状态 +- 审批状态 +- 金额 / 水量差异 +- 时间 + +#### 历史只读查询页 +至少展示: + +- 原单号 +- 旧系统标识 +- 来源时间 +- 映射状态 +- 查询摘要 + +**验收重点** + +- 不把历史只读查询和在线处理页混成一个页面 + +--- + +### FE-03 审批状态展示 + +**目标** +统一展示审批边界,但不假设 BPM 已完整落地。 + +**需求** +至少展示: + +- 是否需要审批 +- 当前审批状态 +- 审批意见摘要(如有) +- 历史流程引用摘要(如有) + +--- + +### FE-04 统一结果表达 + +**目标** +在 REV-004 页面中统一表达处理结果。 + +**至少统一展示** + +- `resultStatus` +- `writeBackStatus` +- `approvalStatus` +- `resultObjectNo` +- `msg` + +**验收重点** + +- 不再只显示“成功 / 失败” +- 要能区分: + - 处理成功 + - 待审批 + - 回写失败 + - 部分成功 + +--- + +### FE-05 历史迁移核查页 / 对账页 + +**目标** +给迁移验收和历史比对保留前端展示入口。 + +**建议查询维度** + +- 客户号 +- 手机号 +- 表号 +- 账期 +- 营业所 +- 渠道 +- 业务单号 +- `objectType` +- 状态 +- 时间范围 + +**验收重点** + +- 能看汇总 +- 能点进明细 +- 能定位单据级差异 + +--- + +## 5. 联调 / 共同实现清单 + +### JOINT-01 枚举与字段统一 + +前后端统一: + +- `objectType` +- `adjustType` +- `resultStatus` +- `writeBackStatus` +- `approvalStatus` + +### JOINT-02 当前事实与目标设计分层 + +必须明确: + +- 哪些对象当前只是在统一入口下承接 +- 哪些对象只是目标设计命名 +- 哪些对象当前只支持查询,不支持在线提交 + +### JOINT-03 历史查询口径统一 + +统一以下查询口径: + +- 业务对象查询 +- 历史只读查询 +- 投影查询 +- 映射查询 + +### JOINT-04 迁移验收维度统一 + +统一核查维度: + +- 对象类型 +- 状态 +- 审批状态 +- 原单号 / 新单号 +- 金额 / 水量 +- 时间 +- 关联账单 + +--- + +## 6. 建议拆给其他 Agent 的任务包 + +### Agent A:后端统一入口改造 + +负责: + +- `IF-REV-007` 输入输出扩展 +- `objectType` 承接 +- 统一 handler 分派机制 + +### Agent B:后端账务查询与历史兼容 + +负责: + +- 业务对象查询出口 +- 历史只读 / 投影查询出口 +- 映射层查询支撑 + +### Agent C:后端审批 / 留痕承接 + +负责: + +- `approvalRequired` +- `approvalStatus` +- 操作留痕增强 +- 历史流程字段承接 + +### Agent D:前端统一账务处理页面 + +负责: + +- 统一入口页面改造 +- 对象差异化表单展示 +- 统一结果展示 + +### Agent E:前端账务查询与迁移核查页面 + +负责: + +- 业务对象查询页 +- 历史只读查询页 +- 差异定位展示 + +### Agent F:联调与口径校验 + +负责: + +- 枚举值统一 +- 字段命名统一 +- 页面与接口回包一致性校验 +- 历史查询与迁移验收口径校验 + +--- + +## 7. 最小交付顺序建议 + +1. 后端统一入口改造 +2. 后端查询出口改造 +3. 前端统一入口页面改造 +4. 前端查询页改造 +5. 审批 / 留痕补强 +6. 迁移验收 / 历史核查联调 + +--- + +## 8. 给其他 Agent 的任务提示模板 + +```text +任务背景 +当前正在推进 REV-004 全量账务领域实现,对应正式文档已完成四层回写:详设、数据库、接口、概要。当前正式统一入口为 IF-REV-007,目标是在不破坏当前统一入口事实的前提下,承接全量账务对象。 + +实现约束 +1. 不要把目标设计写成当前已完全实现事实 +2. 当前统一入口仍是 IF-REV-007 +3. 全量对象包括: + - PrepaidRefund + - RedinkRecord + - WrittenoffAdjust + - PriceDiffAdjust + - LateFeeReduce + - BadDebtRecord + - SplitAdjust + - 特殊开账 / 特账 + - RefundBill + - CrossCycleWaterRecord +4. 历史对象需区分: + - 在线统一骨架 + - 独立业务对象 + - 查询投影 + - 历史只读 / 映射层 + +请完成 +- 你负责的子任务:[填写 Agent A/B/C/D/E/F 的任务] +- 输出: + 1. 变更清单 + 2. 实现口径说明 + 3. 风险点 + 4. 与正式文档是否一致 + +文档依据 +- docs/design/02_Detailed_Design/12_REV_Detailed.md +- docs/design/03_Technical_Design/01_Database_Design.md +- docs/design/03_Technical_Design/03_Interface_Design.md +- docs/design/01_Overview/03_Summary_Design.md +- docs/guides/REV004_FULL_ACCOUNTING_DOMAIN_DESIGN.md +``` + +--- + +## 9. 参考文档 + +- `docs/design/02_Detailed_Design/12_REV_Detailed.md` +- `docs/design/03_Technical_Design/01_Database_Design.md` +- `docs/design/03_Technical_Design/03_Interface_Design.md` +- `docs/design/01_Overview/03_Summary_Design.md` +- `docs/guides/REV004_FULL_ACCOUNTING_DOMAIN_DESIGN.md` diff --git a/docs/guides/REV004_LEGACY_FINANCE_MIGRATION_PLAN_V0.md b/docs/evidence/rev004-accounting/REV004_LEGACY_FINANCE_MIGRATION_PLAN_V0.md similarity index 100% rename from docs/guides/REV004_LEGACY_FINANCE_MIGRATION_PLAN_V0.md rename to docs/evidence/rev004-accounting/REV004_LEGACY_FINANCE_MIGRATION_PLAN_V0.md diff --git a/docs/evidence/rev004-accounting/REV004_PREPAID_REFUND_TRANSFER_EVIDENCE_MATRIX.md b/docs/evidence/rev004-accounting/REV004_PREPAID_REFUND_TRANSFER_EVIDENCE_MATRIX.md new file mode 100644 index 0000000..d4f07f3 --- /dev/null +++ b/docs/evidence/rev004-accounting/REV004_PREPAID_REFUND_TRANSFER_EVIDENCE_MATRIX.md @@ -0,0 +1,137 @@ +# REV004 预存退款/转账原系统证据与待确认规则对照表 + +## 文档目的 +用于区分: +1. **原系统操作文档中已有直接证据**的规则/UI 形态 +2. **当前仅来自法规口径、业务访谈或实现推断**,尚需产品/财务/制度确认的规则 + +避免把“原系统已证明”和“待确认业务规则”混写。 + +--- + +## 一、证据来源 + +主要依据: +- `docs/design/04_Appendix/Archive/02_Manuals/营收系统_用户操作手册.md` +- `docs/design/04_Appendix/Archive/04_Original_Attachments/营收系统_用户操作手册.md` + +关键章节: +- `12.3 预存调整` +- `3.3.4 客户欠费缴费` + +关键截图: +- `营收系统_用户操作手册_images/media/image486.png` + +--- + +## 二、原系统可直接证明的内容 + +| 主题 | 结论 | 证据类型 | 说明 | +|---|---|---|---| +| 预存调整功能存在 | 是 | 菜单/章节 | 原系统存在【账务处理】-【预存调整】模块 | +| 预存调整支持“新增” | 是 | 操作文案 | 文档明确说明点击“新增”后可添加预存调整 | +| 新增时必须输入系统存在的户号 | 是 | 操作文案 | 文档明确写“户号必须是系统中存在的户号” | +| 新增时先选客户,再自动带出客户信息 | 是 | 截图 | 从新增弹窗可见客户编号、客户名称、客户地址、用水性质、预存金额、未到账金额为联动展示结构 | +| 预存调整分为“预存退款/预存转账”两类 | 是 | 截图 | 新增弹窗存在两个 tab:`预存退款`、`预存转账` | +| 预存退款页需要录入申请信息 | 是 | 截图 | 可见字段:退款金额、剩余金额、申请人、联系电话、申请原因、备注、上传 | +| 客户详情会同时展示预存与欠费统计 | 是 | 文案 | 文档明确写客户详情界面会展示预存、欠费笔数、欠费金额、应缴金额 | +| 预存与欠费在操作视图中有关联 | 是 | 文案/UI | 从客户详情汇总展示与预存调整入口形态可推断前台操作上是联动感知的 | + +--- + +## 三、当前只能视为“待确认”的规则 + +以下规则**未在原系统操作手册中找到直接证据**,当前不能写成“原系统已确认规则”: + +| 规则 | 当前状态 | 说明 | +|---|---|---| +| 用户对预存余额享有所有权 | 待确认 | 属于法规/制度表达,非原系统操作文案 | +| 退款必须原路返还 | 待确认 | 原系统手册未见“原路返还”明确表述 | +| 退款不收手续费 | 待确认 | 原系统手册未见 | +| 退款前必须先抵扣欠费 | 待确认 | 原系统手册未见明确账务顺序 | +| 预存抵扣顺序:违约金 → 水费本金 → 其他费用 | 待确认 | 这是强财务规则,原手册未给出 | +| 同主体、同区域、同公司才能转账 | 待确认 | 原手册仅证明“有预存转账”,未证明限制条件 | +| 有预存则不产生坏账 | 待确认 | 属于业务推断,非原系统直接表述 | +| 销户退款必须先清欠费再退款 | 待确认 | 原手册未见直接条文 | +| 已核销坏账与预存退款完全独立核算 | 待确认 | 原系统操作手册未给出 | + +--- + +## 四、对当前 REV004 实现/设计的建议口径 + +### 4.1 可直接作为“原系统一致”的内容 +可以写成: + +1. 原系统存在**预存调整**模块 +2. 预存调整包含: + - 预存退款 + - 预存转账 +3. 新增预存调整时,先选择客户/户号,再自动带出: + - 客户名称 + - 客户地址 + - 用水性质 + - 预存金额 + - 未到账金额 +4. 退款页需要申请信息: + - 申请人 + - 联系电话 + - 申请原因 + - 备注 + - 附件 + +### 4.2 只能作为“待制度确认”的内容 +建议写成: + +> 以下规则依据法规理解、业务访谈或拟实现口径提出,尚未从原系统操作文档中找到直接证据,需产品/财务/制度进一步确认: + +- 原路返还 +- 不收手续费 +- 抵扣顺序 +- 转账主体/区域限制 +- 清欠前置规则 +- 预存与坏账/核销的强约束关系 + +--- + +## 五、建议给产品/财务确认的问题清单 + +1. 预存退款是否必须**原路返还**? +2. 预存退款是否允许**线下转账**或人工指定退款账户? +3. 预存退款是否存在**手续费**或其他财务限制? +4. 有欠费时,是否必须**先抵扣后退款**? +5. 如需抵扣,抵扣顺序是否为: + - 违约金 + - 水费本金 + - 其他费用 +6. 预存转账是否仅允许: + - 同主体 + - 同区域 + - 同公司 +7. 销户退款是否必须先完成: + - 销户 + - 清欠 + - 无冻结/无争议 +8. 坏账/核销状态下,预存是否仍可退/可转? + +--- + +## 六、当前结论 + +### 已有原系统证据的部分 +- 功能存在 +- UI 形态存在 +- 关键字段存在 +- 客户选择后信息自动带出这一交互形态基本成立 + +### 尚未有原系统直接证据的部分 +- 财务清算规则 +- 原路退款规则 +- 抵扣优先级 +- 转账限制边界 +- 与坏账/核销的强约束关系 + +因此,当前最稳妥的做法是: +- **UI 与字段设计**可参考原系统直接推进 +- **资金与账务规则**必须单独走确认流程 + +--- diff --git a/docs/evidence/rev004-accounting/rev004-accounting-adjust-first-batch-dev-entry-2026-04-15.md b/docs/evidence/rev004-accounting/rev004-accounting-adjust-first-batch-dev-entry-2026-04-15.md new file mode 100644 index 0000000..2a5892c --- /dev/null +++ b/docs/evidence/rev004-accounting/rev004-accounting-adjust-first-batch-dev-entry-2026-04-15.md @@ -0,0 +1,22 @@ +# REV004 账务调整统一化改造 — 第一批开发入口(2026-04-15) + +## 说明 +基于已完成的 P0 标准层工件,本轮已进一步拆出第一批可执行开发任务单,作为后续真正进入代码实现的入口。 + +## 第一批试点对象 +- `late-fee reduce`(违约金减免) + +## 第一批任务单 +- `.omx/plans/first-batch-dev-tasklist-rev004-accounting-adjust-unification.md` + +## 核心内容 +1. 最小标准层 helper 落地 +2. late-fee reduce 字典统一 +3. late-fee reduce 状态映射冻结 +4. formal-table 申请态写入 +5. date-mode 最小执行闭环 +6. page/log-page 摘要字段补齐 +7. 测试闭环建立 + +## 用途 +该任务单用于把“标准层规划”正式推进到“试点对象实现”。 diff --git a/docs/evidence/rev004-accounting/rev004-accounting-adjust-standard-layer-bootstrap-2026-04-15.md b/docs/evidence/rev004-accounting/rev004-accounting-adjust-standard-layer-bootstrap-2026-04-15.md new file mode 100644 index 0000000..f45351f --- /dev/null +++ b/docs/evidence/rev004-accounting/rev004-accounting-adjust-standard-layer-bootstrap-2026-04-15.md @@ -0,0 +1,23 @@ +# REV004 账务调整统一化改造 — P0 标准层启动证据(2026-04-15) + +## 已完成 +本轮已将统一化改造的 P0 标准层拆分成独立工件,供后续直接执行: +- `.omx/plans/standard-layer/rev004-accounting-adjust-semantic-map.md` +- `.omx/plans/standard-layer/rev004-accounting-adjust-dict-and-status-strategy.md` +- `.omx/plans/standard-layer/rev004-accounting-adjust-readmodel-matrix.md` +- `.omx/plans/standard-layer/rev004-accounting-adjust-canonical-semantic-layer.md` +- `.omx/plans/standard-layer/rev004-accounting-adjust-test-matrix.md` +- `.omx/plans/p0-tasklist-rev004-accounting-adjust-unification-standard-layer.md` + +## 收口原则 +- REV004 当前接口模型为主真值 +- legacy 仅作映射与迁移参考 +- 不强制前端改字段名 +- 先做标准层,再做多对象 runtime 与迁移 + +## 本轮用途 +这些工件用于: +1. 统一字段语义 +2. 统一字典与状态口径 +3. 统一读模型输出 +4. 为 runtime 正式落库和历史迁移提供统一语义层 diff --git a/docs/evidence/rev004-accounting-adjust-standard-layer-code-bootstrap-2026-04-15.md b/docs/evidence/rev004-accounting/rev004-accounting-adjust-standard-layer-code-bootstrap-2026-04-15.md similarity index 100% rename from docs/evidence/rev004-accounting-adjust-standard-layer-code-bootstrap-2026-04-15.md rename to docs/evidence/rev004-accounting/rev004-accounting-adjust-standard-layer-code-bootstrap-2026-04-15.md diff --git a/docs/evidence/rev004-accounting/rev004-accountlog-action-wiring-notes-2026-04-13.md b/docs/evidence/rev004-accounting/rev004-accountlog-action-wiring-notes-2026-04-13.md new file mode 100644 index 0000000..bc70734 --- /dev/null +++ b/docs/evidence/rev004-accounting/rev004-accountlog-action-wiring-notes-2026-04-13.md @@ -0,0 +1,47 @@ +# REV004 accountLog 操作链接线说明(2026-04-13) + +## 结论 +当前 `accountLog` 的 4 条操作链在后端契约层已具备接线条件,不需要继续补新的稳定字段;前端主要做提交映射即可。 + +## 1. 查看流程 `log-process` +- 前端来源:`handleProcess(row)` +- 后端接口:`GET /business/accounting-adjust/log-process` +- 后端入参:`adjustmentNo` +- 当前行数据可用字段:`row.adjustmentNo` +- 接线结论:可直接接 + +## 2. 查看附件 `log-attachments` +- 前端来源:`handleAttachment(row)` +- 后端接口:`GET /business/accounting-adjust/log-attachments` +- 后端入参:`adjustmentNo` +- 当前行数据可用字段:`row.adjustmentNo` +- 接线结论:可直接接 + +## 3. 转退款 `log-refund` +- 前端来源:`RefundForm` +- 后端接口:`POST /business/accounting-adjust/log-refund` +- 后端请求对象:`AccountingAdjustSecondaryActionReqVO` +- 推荐映射: + - `adjustmentNo = row.adjustmentNo` + - `reason = form.remark` + - `collectionMethod = form.collectionMethod` + - `refundUser = form.refundUser` + - `attachmentRefs` = 前端上传结果(如有) +- 说明:前端 `refundAmount` 当前仅用于展示,不是后端必填字段 +- 接线结论:可接,主要是前端提交映射 + +## 4. 转预存 `log-prestorage` +- 前端来源:`TransferPrestoreForm` +- 后端接口:`POST /business/accounting-adjust/log-prestorage` +- 后端请求对象:`AccountingAdjustSecondaryActionReqVO` +- 推荐映射: + - `adjustmentNo = row.adjustmentNo` + - `targetCustCode = form.targetCustCode` + - `reason = form.remark` + - `attachmentRefs` = 前端上传结果(如有) +- 说明:前端 `transferAmount` 当前仅用于展示,不是后端必填字段 +- 接线结论:可接,主要是前端提交映射 + +## 补充说明 +- 本轮后端新增的 `accountLog.custId` 已可支撑前端客户编号点击后稳定跳客户详情。 +- `sold` 当前列表/弹窗展示字段已基本满足,不建议继续为展示字段扩充后端响应。 diff --git a/docs/evidence/rev004-accounting/rev004-accountprocess-dict-ui-consistency-summary-2026-04-13.md b/docs/evidence/rev004-accounting/rev004-accountprocess-dict-ui-consistency-summary-2026-04-13.md new file mode 100644 index 0000000..1e93864 --- /dev/null +++ b/docs/evidence/rev004-accounting/rev004-accountprocess-dict-ui-consistency-summary-2026-04-13.md @@ -0,0 +1,148 @@ +# REV004 / accountProcess 字典 label 与 UI 文案一致性摘要(2026-04-13) + +## 1. 目的 +本摘要用于收敛 `accountProcess` 当前涉及的状态/标签类字段,确认: +- 代码侧字典 type 是否已统一 +- 正式文档口径是否与代码一致 +- 是否仍存在旧快照 / 旧产出中的历史口径残留 + +--- + +## 2. 当前已确认一致的口径 + +### A. 工单状态 `work_status` +代码侧: +- `DictTypeConstants.WORK_STATUS = "work_status"` +- 口径:`0-未处理 / 1-已审核 / 2-已完成 / 3-已撤销` + +正式 SQL seed: +- `../water-docs/sql/rev004_account_adjust_dict_seed.sql` +- 已定义: + - `0 -> 未处理` + - `1 -> 已审核` + - `2 -> 已完成` + - `3 -> 已撤销` + +正式数据库设计文档: +- `../water-docs/docs/design/03_Technical_Design/01_Database_Design.md` +- 当前已同步为四态: + - `0-未处理(工单创建,待审核/待处理)` + - `1-已审核(审核通过/无需审批,待完成)` + - `2-已完成(处理成功且已回写完成)` + - `3-已撤销(工单已撤销)` + +结论: +- **代码 / seed SQL / 正式设计文档:已一致** + +### B. REV004 账务调整核心状态字典 +已确认存在统一 type: +- `account_adjust_object_type` +- `account_adjust_result_status` +- `account_adjust_approval_status` +- `account_adjust_writeback_status` + +代码侧使用: +- `AccountingAdjustLogProcessServiceImpl` +- `AccountingAdjustSoldProcessServiceImpl` +中均已通过 `DictFrameworkUtils.parseDictDataLabel(...)` 或统一映射读取 label + +正式 SQL seed: +- `../water-docs/sql/rev004_account_adjust_dict_seed.sql` +- 已定义: + - objectType:如 `PREPAID_REFUND / REDINK_RECORD / BAD_DEBT_RECORD / WRITTENOFF_ADJUST / PRICE_DIFF_ADJUST / LATE_FEE_REDUCE / SPLIT_ADJUST` + - resultStatus:`SUCCESS / PENDING_APPROVAL / FAIL` + - approvalStatus:`NOT_REQUIRED / PENDING_APPROVAL / APPROVED / REJECTED` + - writeBackStatus:`UPDATED / PENDING / SKIPPED` + +结论: +- **REV004 核心状态字典类型与值域已成套收口** + +### C. 收费方式 `charge_method` +代码侧: +- `DictTypeConstants.CHARGE_METHOD = "charge_method"` +- 已在 `AccountingAdjustSoldProcessServiceImpl` 中作为列表展示 label 来源 + +正式文档: +- `../water-docs/sql/lhc_数据库设计.md` +- `../water-docs/docs/design/04_Appendix/Archive/03_Design_Docs/数据库设计.md` +中可见 `charge_method` 语义为收费途径/收费方式 + +结论: +- **当前 sold 查询页“收费方式”展示依赖路径明确,代码口径稳定** + +--- + +## 3. 当前已确认的“动态原因字典”绑定口径 +参考: +- `../water-docs/docs/guides/REV004_DICT_BINDING_MATRIX.md` + +当前已明确: +- `PREPAID_REFUND -> deposit_reason` +- `REDINK_RECORD -> redink_reason` +- `BAD_DEBT_RECORD -> knotty_reason` +- `WRITTENOFF_ADJUST -> payment_reason`(过渡复用) +- `PRICE_DIFF_ADJUST -> price_reason` +- `LATE_FEE_REDUCE -> late_fee_reason` +- `SPLIT_ADJUST -> separate_reason` + +结论: +- **前端原因下拉不应绑定一个统一 reason 字典,而应按 objectType 动态切换** + +--- + +## 4. 当前仍存在的不一致 / 残留风险 + +### A. 历史快照文档仍残留旧三态 `work_status` +在旧归档快照中,仍能看到: +- `../water-docs/docs/design/04_Appendix/Archive/08_Formal_Doc_Snapshots/RWB-02/2026-04-03-RWB-02-01_Database_Design.md` +- 其中 `work_status` 仍写作:`0-待处理 / 1-处理中 / 2-已完成` + +这与当前正式口径不一致。 + +结论: +- **历史快照存在旧口径残留,但不应再作为当前真值来源** + +### B. output 产物也有旧口径残留 +例如: +- `../water-docs/output/01_Database_Design_processed.md` +中仍可见旧三态 `work_status` + +结论: +- **产出型文件存在滞后,需要明确“正式设计文档 + REV004 seed + 代码”为真值源** + +### C. UI 文案一致性尚未逐页核验 +虽然字典 type / 值域已统一,但还没有逐页确认: +- 页面上显示的是字典 label 还是代码 fallback 值 +- 页面文案是否与字典 label 完全一致 +- 历史页面是否仍在用旧文案(例如“处理中”) + +结论: +- **字典结构已较稳定,但 UI 最终展示一致性仍需前端/UAT 联合核验** + +--- + +## 5. 当前建议真值源优先级 +建议按以下优先级使用: +1. **后端代码中的 DictTypeConstants + Service 映射逻辑** +2. **`rev004_account_adjust_dict_seed.sql`** +3. **正式技术设计文档 `01_Database_Design.md`** +4. 历史快照 / output 产物(仅供追溯,不作为当前真值) + +--- + +## 6. 对前端 / UAT 的建议 +1. `work_status` 统一按四态使用: + - 0 未处理 + - 1 已审核 + - 2 已完成 + - 3 已撤销 +2. `objectType / resultStatus / approvalStatus / writeBackStatus` 使用 REV004 新字典,不再依赖旧业务大类字段硬编码。 +3. “原因”下拉必须按 `objectType` 动态切换,不要做单字典通配。 +4. 若页面仍显示“处理中”等旧文案,应优先视为前端展示遗留,而不是后端当前真值。 + +--- + +## 7. 当前结论 +- **核心字典 type 与值域已基本收口** +- **正式文档与 seed SQL 已与代码当前口径对齐** +- **残留风险主要在旧快照/旧输出文件与前端展示层,而不在当前后端主实现** diff --git a/docs/evidence/rev004-accounting/rev004-accountprocess-final-review-summary-2026-04-13.md b/docs/evidence/rev004-accounting/rev004-accountprocess-final-review-summary-2026-04-13.md new file mode 100644 index 0000000..7254e35 --- /dev/null +++ b/docs/evidence/rev004-accounting/rev004-accountprocess-final-review-summary-2026-04-13.md @@ -0,0 +1,257 @@ +# REV004 / accountProcess 最终评审摘要(2026-04-13) + +## 1. 评审目的 +本摘要用于对外汇报 `REV004 / accountProcess` 当前后端交付状态,统一回答以下问题: +- 这一块后端接口是否已形成可联调的稳定口径? +- 关键页面/弹窗对应的接口是否已经落地? +- 真实数据库条件下,主链路是否已经被证明可运行? +- 当前仍有哪些剩余风险与建议后续动作? + +--- + +## 2. 结论摘要 +### 结论 +`REV004 / accountProcess` 当前已经达到: +- **接口口径已基本收口** +- **页面/弹窗映射已梳理清楚** +- **主链路已完成真实数据库验证** +- **可进入联调 / 评审 / 阶段性验收** + +### 当前结论边界 +这里的“通过”是指: +- 后端接口已存在并按当前代码口径稳定返回 +- 关键提交流程、撤销流程、日志二次动作、主要查询面均有真实库证据 +- 不代表已经完成 UI 层面的最终视觉/交互验收 +- 不代表所有页面文案、字典 label、边角筛选条件都已逐项核验 + +--- + +## 3. 当前已沉淀产物 +### A. 集成测试累计证据 +- `docs/evidence/rev004-accountprocess-integration-testing-bootstrap-2026-04-13.md` + +### B. 接口真值矩阵 +- `docs/evidence/rev004-accountprocess-interface-truth-matrix-2026-04-13.md` + +### C. 页面元素勾稽矩阵 +- `docs/evidence/rev004-accountprocess-ui-element-matrix-2026-04-13.md` +- `docs/evidence/rev004-accountprocess-dict-ui-consistency-summary-2026-04-13.md` +- `docs/evidence/rev004-accountprocess-page-label-audit-2026-04-13.md` +- `docs/evidence/rev004-accountprocess-ui-orchestration-checklist-2026-04-13.md` + +### D. 真实库集成测试代码 +- `sw-business-server/src/test/java/.../integration/rev004/accountprocess/Rev004AccountProcessCanaryQueryIntegrationTest.java` + +--- + +## 4. 范围说明 +本轮范围仅覆盖: +- `REV004/accountProcess` + +具体包括四类页面/域: +- 预存调整(prestorage) +- 已销调整(sold) +- 未销调整(unsold) +- 账务日志(accountLog / log) + +本轮明确不扩散到: +- accountProcess 之外的其它业务模块 +- 全项目通用测试框架治理 +- UI 自动化或前端渲染层验证 + +--- + +## 5. 环境口径 +### 测试策略 +- **数据库:真实 PostgreSQL** +- **数据库外依赖:替身化 / MockBean** + +### 已明确替身边界 +例如: +- `TransactionApi` +- `ApiErrorLogCommonApi` +- `DictDataCommonApi` +- `OperateLogCommonApi` +- `RedissonClient` + +### 当前价值 +这意味着: +- 账务状态变化、operat_log 留痕、查询回看等核心真值来自真实数据库 +- 外部交易/缓存/公共 RPC 不会干扰主链路验证 + +--- + +## 6. 最新验证结果 +### 最新 surefire 结果 +- `Rev004AccountProcessCanaryQueryIntegrationTest` + - **21 tests / 0 fail / 0 skip** +- `Rev004AccountProcessIntegrationFixtureAssetsTest` + - **1 pass** +- `Rev004AccountProcessLiveDbReadinessTest` + - **1 pass** + +### 最新整体验证结果 +- `Rev004AccountProcess*` + - **总计 23 tests / 0 fail / 0 skip** + +这代表当前仓库内,至少在真实数据库 + 外部依赖替身化前提下,主链路验证是通过的。 + +--- + +## 7. 主链路覆盖概览 +### 7.1 prestorage +已验证: +- `prestorage-page` +- `prestorage-stat` +- `prestorage-detail` +- `prestorage-submit` +- `prestorage-revoke` +- `prestorage-process` +- `prestorage-attachments` +- 提交后 page/stat/detail/process/attachments 联动回看 + +已证明能力: +- 预存退款提交成功 +- 余额真实回写 +- 记录可回看 +- 撤销后余额可恢复 + +### 7.2 sold +已验证: +- `sold-page` +- `sold-stat` +- `sold-submit` +- `sold-batch-revoke` +- 提交后 page/stat 能反映撤销能力 + +已证明能力: +- 已销调整申请可成功落日志 +- 状态为 `PENDING_APPROVAL` +- 批量撤销以 `chargeIds[]` 可执行 + +### 7.3 unsold +已验证: +- `unsold-page` +- `unsold-stat` +- `unsold-adjust-submit` +- `unsold-split-submit` +- `unsold-late-fee-reduce-submit` +- `unsold-price-diff-submit` +- `unsold-bad-debt-submit` +- 调整后 page/stat 可回看金额变化 + +已证明能力: +- 五类未销动作 happy path 都可跑通 +- 查询面能反映初始数据与提交后的更新结果 + +### 7.4 log / accountLog +已验证: +- `log-page` +- `log-stat` +- `log-detail` +- `log-process` +- `log-attachments` +- `log-refund` +- `log-prestorage` +- `log-revoke` +- 日志页 page/stat/detail/process/attachments 联动回看 + +已证明能力: +- 日志链路是当前最完整的一组闭环 +- 支持二次动作(退款/转预存/撤销) +- 可查看流程摘要与附件引用 + +--- + +## 8. 页面 / 弹窗映射结论 +### 已收口 +目前页面与后端接口映射已经可明确回答: +- 哪个页面查哪个 `page/stat/detail` +- 哪个弹窗调哪个 `submit/revoke/process/attachments` +- 哪些动作依赖 `adjustmentNo` +- 哪些动作依赖 `chargeId/chargeIds` + +### 特别提醒 +- **已销批量撤销**:当前后端口径是 `chargeIds[]`,不是 `adjustmentNo[]` +- **日志页二次动作**:当前统一以 `adjustmentNo` 为主键 +- **已销查询页** 本身不返回 `adjustmentNo`,若前端要保留申请单号,应使用提交返回值或转到日志视角查看 + +--- + +## 9. 接口字段口径结论 +### 前端建议优先读取 +对于动作提交类接口,前端建议主读: +- `adjustmentNo` +- `resultStatus` +- `approvalStatus` +- `writeBackStatus` +- `msg` + +### 兼容字段 +- `status` +- `message` + +这些保留给旧调用方或兼容逻辑,不建议新页面作为主读来源。 + +### 预存工单状态口径 +- `0 = 未处理` +- `1 = 已审核` +- `2 = 已完成` +- `3 = 已撤销` + +### 页面状态与工单状态不要混用 +- `prestorage-page.workOrderStatus` 是预存工单状态 +- `log-page.statusCode/status` 是日志页状态投影 +- 两者不是同一套语义 + +--- + +## 10. 当前最可信的证据类型 +从强到弱排序: +1. **真实数据库 + MockMvc canary 测试** +2. **Controller / ReqVO / RespVO / Service 代码口径** +3. **矩阵文档归纳** + +因此当前对外说法应以: +- 已跑通真实库的场景 = 强证据 +- 仅代码里存在但未单独断言的字段 = 次强证据 + +--- + +## 11. 剩余风险 / 空白 +### 仍未完全补齐 +1. 字典 type / 值域已基本收口,剩余是页面文案逐页核对 +2. 前端弹窗 A/B/C 切换路径尚未做 UI 编排级验证 +3. 边角筛选条件并未全部逐项做真实库穷尽验证 + +### 风险等级判断 +- **主功能联调风险:中低** +- **页面展示细节风险:中** +- **最终 UI 验收风险:中** + +--- + +## 12. 对外建议说法 +建议对前端 / 产品 / 评审会的说法: + +> `REV004/accountProcess` 后端接口已基本收口,四条主链(prestorage / sold / unsold / log)均已有真实数据库验证证据; +> 当前可进入稳定联调和阶段性验收。 +> 剩余工作主要集中在页面文案/字典展示的一致性核验,以及更贴近前端的 UI 编排级验证。 + +--- + +## 13. 建议下一步 +按优先级建议: +1. 做页面文案 / 字典 label 的逐页验收核对 +2. 已提供 UI 编排级验收清单,若需要再补自动化/UI录屏级验证 +3. 评审会可直接使用本摘要 + 两份矩阵文档 + 集成测试证据 + 字典一致性摘要 + 页面文案核对表 + UI 编排验收清单 + +--- + +## 14. 关联文档 +- `docs/evidence/rev004-accountprocess-integration-testing-bootstrap-2026-04-13.md` +- `docs/evidence/rev004-accountprocess-interface-truth-matrix-2026-04-13.md` +- `docs/evidence/rev004-accountprocess-ui-element-matrix-2026-04-13.md` +- `docs/evidence/rev004-accountprocess-dict-ui-consistency-summary-2026-04-13.md` +- `docs/evidence/rev004-accountprocess-page-label-audit-2026-04-13.md` +- `docs/evidence/rev004-accountprocess-ui-orchestration-checklist-2026-04-13.md` diff --git a/docs/evidence/rev004-accounting/rev004-accountprocess-gap-remediation-2026-04-13.md b/docs/evidence/rev004-accounting/rev004-accountprocess-gap-remediation-2026-04-13.md new file mode 100644 index 0000000..ec0e47d --- /dev/null +++ b/docs/evidence/rev004-accounting/rev004-accountprocess-gap-remediation-2026-04-13.md @@ -0,0 +1,124 @@ +# REV004 accountProcess gap remediation — 2026-04-13 验证记录 + +## 本轮改动 +- accountProcess 查询 ReqVO 补前端原型 range 参数兼容: + - `sold`: `accountMonth` / `collectionTime` + - `log`: `accountMonth` / `createTime` / `handleTime` / `paymentDate` + - `unsold`: `accountMonth` + - `prestorage`: `acceptTime` +- 查询 Controller 增加 query-normalize,兼容多值 query param 传入 +- `accountLog` 状态筛选补兼容值:`1=正常`、`2=已撤销` + +## 验证结果 +### 1. 主代码编译 +命令: +```bash +cd sw-business/sw-business-server && mvn -q -DskipTests compile +``` +结果:通过。 + +### 2. 变更相关测试(手动定向执行) +由于模块内存在与本次改动无关的存量 testCompile 问题(`ChargeService` / `ChargeDO` 相关旧测试编译失败),本轮对变更相关测试采用定向手动编译 + JUnit Console 执行。 + +执行类: +- `AccountingAdjustActionControllerTest` +- `AccountingAdjustRouteSmokeTest` +- `AccountingAdjustLogProcessServiceImplTest` +- `AccountingAdjustPrestorageProcessServiceImplTest` +- `AccountingAdjustSoldQueryProcessServiceImplTest` +- `AccountingAdjustUnsoldProcessServiceImplTest` + +结果: +- 34 tests found +- 34 tests started +- 34 tests successful +- 0 tests failed + +关键覆盖点: +- accountProcess 路由 smoke 正常 +- query range 参数兼容归一化正常 +- `accountLog` 的 `status=2` 已撤销兼容筛选正常 +- `prestorage adjustmentNo` 闭环仍保持通过 +- `sold` 查询过滤与 `unsold` / `prestorage` 主流程回归通过 + +### 3. 说明 +直接执行: +```bash +cd sw-business/sw-business-server && mvn -Dtest='...' test +``` +仍会被仓库内历史遗留的 testCompile 问题阻断;该问题与本轮 accountProcess 修复无直接关系。 + + +## 4. `sold.isHistory` 语义收口(追加) +### 语义定义 +- `isHistory=false`:查询当前已收记录(`payState=PAID`),保留调整/批量撤销能力 +- `isHistory=true`:查询历史已结记录(`payState=SETTLED`),按只读口径返回,不开放调整/批量撤销 + +### 追加验证 +命令: +- `cd sw-business/sw-business-server && mvn -q -DskipTests compile` +- 手动定向执行:`AccountingAdjustRouteSmokeTest` + `AccountingAdjustSoldQueryProcessServiceImplTest` + +结果: +- 6 tests found +- 6 tests started +- 6 tests successful +- 0 tests failed + + +## 5. 完整相关回归(追加) +在 `sold.isHistory` 收口后,再次对本轮相关 6 个 accountProcess 测试类做完整定向回归。 + +执行类: +- `AccountingAdjustActionControllerTest` +- `AccountingAdjustRouteSmokeTest` +- `AccountingAdjustLogProcessServiceImplTest` +- `AccountingAdjustPrestorageProcessServiceImplTest` +- `AccountingAdjustSoldQueryProcessServiceImplTest` +- `AccountingAdjustUnsoldProcessServiceImplTest` + +结果: +- 35 tests found +- 35 tests started +- 35 tests successful +- 0 tests failed + + +## 6. sold / accountLog 展示字段复核(追加) +### 复核结论 +- `sold`:当前前端列表/弹窗所需展示字段已基本满足,暂不需要额外补展示字段 +- `accountLog`:补 `custId`,用于前端客户编号点击后稳定跳转客户详情 + +### 追加验证 +- `mvn -q -DskipTests compile` 通过 +- 手动定向执行:`AccountingAdjustRouteSmokeTest` + `AccountingAdjustLogProcessServiceImplTest` +- 结果:5 tests found / 5 tests successful / 0 failed + + +## 7. accountLog `custId` 补齐后的回归(追加) +### 变更目的 +- 补 `accountLog` 列表/详情响应中的 `custId` +- 支撑前端客户编号点击后稳定跳客户详情 + +### 追加验证 +- 手动定向编译:`AccountingAdjustRouteSmokeTest`、`AccountingAdjustLogProcessServiceImplTest`、`AccountingAdjustSoldQueryProcessServiceImplTest` +- JUnit Console 执行结果:9 tests found / 9 tests successful / 0 failed + + +## 8. work_status 字典与正式文档同步(追加) +### 本轮结果 +- 已在 `../water-docs/sql/rev004_account_adjust_dict_seed.sql` 中补充 `work_status` 字典 type/data(幂等) +- 已将 `../water-docs/docs/design/03_Technical_Design/01_Database_Design.md` 中的 `work_status` 口径同步为代码四态:`0-未处理 / 1-已审核 / 2-已完成 / 3-已撤销` +- 本轮仍无业务表 schema 变更,仅涉及字典 seed 与正式文档同步 + + +### 业务解释补充 +- `0 未处理`:工单创建,待审核/待处理 +- `1 已审核`:审核通过(或无需审批),待完成 +- `2 已完成`:处理成功且已回写完成 +- `3 已撤销`:工单已撤销 +- 说明:`钱到账`、`带红冲操作` 更偏业务侧解释;当前代码稳定判定仍以 `approvalStatus / resultStatus / writeBackStatus / revokeOfAdjustmentNo` 为准。 + +### 剩余风险 +- 当前 seed SQL 采用幂等补缺策略,不会纠正**环境中已存在但口径错误**的 `work_status` 数据;若某环境已落旧三态字典,仍需后续补一条存量纠偏 SQL 或人工核查。 +- Archive/历史快照与 processed/output 产物可能仍保留旧三态,它们属于历史资料/派生产物,不作为当前正式口径。 diff --git a/docs/evidence/rev004-accounting/rev004-accountprocess-integration-testing-bootstrap-2026-04-13.md b/docs/evidence/rev004-accounting/rev004-accountprocess-integration-testing-bootstrap-2026-04-13.md new file mode 100644 index 0000000..84499ad --- /dev/null +++ b/docs/evidence/rev004-accounting/rev004-accountprocess-integration-testing-bootstrap-2026-04-13.md @@ -0,0 +1,574 @@ +# REV004 accountProcess 集成测试方案 bootstrap(2026-04-13) + +## 本轮已落地 bootstrap +- 新增 `AbstractRev004AccountProcessIntegrationTest`:定义真实数据库 + 外部依赖默认替身化的测试基类 +- 新增 `Rev004AccountProcessLiveDbReadinessTest`:在提供 `REV004_IT_DB_*` 环境变量时,检查真实数据库所需表是否可见 +- 新增 `Rev004AccountProcessIntegrationFixtureAssetsTest`:校验 fixture 资源文件存在 +- 新增 `src/test/resources/sql/rev004/accountprocess/*.sql`:为 prestorage/sold/unsold/accountLog 预留 fixture 分层入口 + +## 当前价值 +- 把“真实数据库 + 外部依赖替身化”的执行边界固化到测试骨架 +- 把场景矩阵的 fixture 入口落到仓库,便于后续继续实现 query/action/close-loop 场景 +- 在未提供真实数据库环境变量时,不强行执行 live DB readiness 测试 + +## 下一步建议 +1. 补 `prestorage` 第 1 条全闭环场景 +2. 补 `sold` 的 `isHistory` + submit/撤销场景 +3. 补 `accountLog` 的 refund/prestorage 二次动作场景 + + +## Canary 补充 +- 新增 `Rev004AccountProcessCanaryQueryIntegrationTest`:在提供 `REV004_IT_DB_*` 环境变量时,真正启动 Spring + MockMvc,打通 `prestorage-page` 只读 query 作为最小 canary。 +- 当前 fixture 仍是 bootstrap 占位,因此该 canary 的目标是“验活骨架”,不是验证完整业务数据闭环。 + + +## Fresh verification +- 执行:`mvn -Dtest='Rev004AccountProcessIntegrationFixtureAssetsTest,Rev004AccountProcessLiveDbReadinessTest,Rev004AccountProcessCanaryQueryIntegrationTest' test` +- 结果:BUILD SUCCESS +- 细项: + - Fixture assets: 1 pass + - Live DB readiness: 1 skipped(未提供 `REV004_IT_DB_*` 环境变量时跳过) + - Canary query: 1 skipped(未提供 `REV004_IT_DB_*` 环境变量时跳过) + + +## Real DB canary verification +- 执行环境:使用 `application-local.yaml` 中 PostgreSQL 连接参数,以 `REV004_IT_DB_*` 环境变量注入 +- 执行:`mvn -Dtest='Rev004AccountProcessIntegrationFixtureAssetsTest,Rev004AccountProcessLiveDbReadinessTest,Rev004AccountProcessCanaryQueryIntegrationTest' test` +- 结果:BUILD SUCCESS +- 明细: + - Fixture assets: 1 pass + - Live DB readiness: 1 pass + - Canary query (`/admin-api/business/accounting-adjust/prestorage-page`): 1 pass +- 说明:当前 canary 证明了真实数据库 + Spring context + MockMvc + route wiring 可启动并返回成功包装;但 fixture 仍是最小占位,尚未证明完整业务数据闭环。 + + +## Real DB full bootstrap verification +- 执行环境:使用 `application-local.yaml` 中 PostgreSQL 连接参数,经 `REV004_IT_DB_*` 环境变量注入 +- 执行:`mvn -Dtest='Rev004AccountProcessIntegrationFixtureAssetsTest,Rev004AccountProcessLiveDbReadinessTest,Rev004AccountProcessCanaryQueryIntegrationTest' test` +- 结果:BUILD SUCCESS +- 明细: + - Fixture assets: 1 pass + - Live DB readiness: 1 pass + - Canary query (`/admin-api/business/accounting-adjust/prestorage-page`): 1 pass +- 说明:当前已经从“资产存在”推进到“真实数据库 + Spring context + MockMvc + canary query 验活成功”。 +- 剩余缺口:fixture 仍是最小占位,尚未验证完整业务数据闭环。 + + +## First real close-loop scenario +- 场景:`prestorage-submit` 预存退款 +- 测试文件:`Rev004AccountProcessCanaryQueryIntegrationTest` +- 使用真实数据库中的独立测试数据(`REV004_IT_SRC` / `biz_account.id=900001`) +- 断言: + - `POST /admin-api/business/accounting-adjust/prestorage-submit` 返回成功包装 + - 账户余额由 `100.00` 变为 `90.00` + - `biz_operat_log` 写入 1 条 `旧预存调整` 日志 + - `biz_operat_log_detail` 中存在与返回 `adjustmentNo` 对应的明细记录 +- 执行:`REV004_IT_DB_URL=... REV004_IT_DB_USERNAME=... REV004_IT_DB_PASSWORD=... mvn -Dtest='Rev004AccountProcessCanaryQueryIntegrationTest' test` +- 结果:BUILD SUCCESS(2 tests / 0 fail / 0 skip) + + +## Sold close-loop scenario +- 场景:`sold-submit` 已销调整申请 +- 测试文件:`Rev004AccountProcessCanaryQueryIntegrationTest` +- 使用真实数据库中的独立测试营业账数据(`biz_charge.id=900002`,`pay_state=1`) +- 断言: + - `POST /admin-api/business/accounting-adjust/sold-submit` 返回成功包装 + - 返回 `resultStatus = PENDING_APPROVAL` + - `biz_operat_log` 写入 1 条 `旧账务兼容动作` 日志 + - `biz_operat_log_detail` 中存在与返回 `adjustmentNo` 对应的明细记录 +- 结果:与 prestorage canary 一起执行,`Rev004AccountProcessCanaryQueryIntegrationTest` 当前为 3 tests / 0 fail / 0 skip + + +## AccountLog close-loop scenario +- 场景:`log-prestorage` 二次动作 +- 测试文件:`Rev004AccountProcessCanaryQueryIntegrationTest` +- 使用真实数据库中的独立源记录(`adjustmentNo=REV004-LOG-900003`,`biz_charge.id=900003`)与目标账户(`REV004_IT_TGT` / `biz_account.id=900004`) +- 断言: + - `POST /admin-api/business/accounting-adjust/log-prestorage` 返回成功包装 + - 源营业账 `pay_state` 被清为 `0`(未收) + - 目标账户余额增加到 `20.00` + - `biz_operat_log` 写入 1 条 `旧账务兼容动作` 日志 + - `biz_operat_log_detail` 中存在与返回 `adjustmentNo` 对应的明细记录 +- 结果:与 prestorage/sold 场景一起执行时,`Rev004AccountProcessCanaryQueryIntegrationTest` 当前为 4 tests / 0 fail / 0 skip + + +## AccountLog process query scenario +- 场景:`log-process` 读取已有调整记录流程摘要 +- 测试文件:`Rev004AccountProcessCanaryQueryIntegrationTest` +- 使用真实数据库中的独立源记录(`adjustmentNo=REV004-LOG-900003`) +- 断言: + - `GET /admin-api/business/accounting-adjust/log-process` 返回成功包装 + - `processState = UPDATED` + - `resultStatus = SUCCESS` + +## Current canary suite status +- `Rev004AccountProcessCanaryQueryIntegrationTest` 当前为 5 tests / 0 fail / 0 skip +- 已覆盖:query canary、prestorage-submit、sold-submit、log-prestorage、log-process + +## 2026-04-13 最新推进:accountLog refund 闭环补齐 +- 新增 `TransactionApi` 的 `@MockBean` 注入到 `AbstractRev004AccountProcessIntegrationTest`,确保真实数据库之外的交易后续流水依赖保持替身化。 +- 更新 `40_accountlog_seed.sql`:为 `REV004-LOG-900003` 补入 `originalTranSeq=T-900003`、`originalSysTranSeq=SYS-900003`,使 `log-refund` 路径具备真实可执行前置数据。 +- 新增 canary 闭环用例:`logRefund_shouldClearChargePaymentAndWriteFollowupLog` + +### 新增闭环断言 +- `POST /admin-api/business/accounting-adjust/log-refund` +- 返回:`resultStatus=SUCCESS`、`objectType=PREPAID_REFUND`、`writeBackStatus=UPDATED` +- 数据库断言: + - `biz_charge.id=900003` 的 `pay_state` 从已收改为 `0` + - `biz_operat_log` 中新增 1 条 `账务调整` 日志,`operat_content` 含返回的 `adjustmentNo` + - `biz_operat_log_detail` 中存在 `bankTranSeq=RF-900003` +- 替身断言:`TransactionApi.createFollowupTransaction(...)` 被调用 + +### 本次真实库验证 +- 执行 1:`REV004_IT_DB_URL=... REV004_IT_DB_USERNAME=... REV004_IT_DB_PASSWORD=... mvn -Dtest='Rev004AccountProcessCanaryQueryIntegrationTest' test` +- 结果 1:BUILD SUCCESS + - `Rev004AccountProcessCanaryQueryIntegrationTest`: 7 tests / 0 fail / 0 skip +- 执行 2:`REV004_IT_DB_URL=... REV004_IT_DB_USERNAME=... REV004_IT_DB_PASSWORD=... mvn -Dtest='Rev004AccountProcess*' test` +- 结果 2:BUILD SUCCESS + - `Rev004AccountProcessLiveDbReadinessTest`: 1 pass + - `Rev004AccountProcessIntegrationFixtureAssetsTest`: 1 pass + - `Rev004AccountProcessCanaryQueryIntegrationTest`: 7 pass + - 总计:9 tests / 0 fail / 0 skip + +### 当前 canary 套件真实覆盖 +- `prestorage-page_shouldReturnSuccessEnvelope` +- `prestorageSubmit_shouldChangeBalanceAndWriteOperatLog` +- `soldSubmit_shouldWritePendingOperatLog` +- `logPrestorage_shouldClearChargePaymentAndIncreaseTargetDeposit` +- `logProcess_shouldReturnUpdatedProcessSummary` +- `logAttachments_shouldReturnUnresolvedAttachmentRef` +- `logRefund_shouldClearChargePaymentAndWriteFollowupLog` + +### 仍待继续 +- `unsold` 五类 happy path 真实库闭环 +- `revoke/log-revoke/sold-batch-revoke` 的真实库撤销链验证 +- 更高一层的“提交 -> 查询页回看 -> detail/process/attachments 全链联动”场景编排 + +## 2026-04-13 继续推进:撤销链真实库闭环补齐 +- 新增真实库撤销链 canary: + - `prestorageRevoke_shouldRestoreBalanceAndWriteRevokeLog` + - `soldBatchRevoke_shouldWriteRevokeLogForPendingSyntheticRecord` + - `logRevoke_shouldRestoreChargePaymentAndRollbackTransferredDeposit` +- 为支持旧兼容动作撤销,本轮同时修正 `AccountingAdjustProcessServiceImpl.findSyntheticSnapshot(...)`: + - 改为按 `adjustmentNo` 直接回查 operat_log / operat_log_detail + - 避免旧预存调整 / 旧日志转预存 场景在撤销时误落入 unified snapshot 分支 + +### 新增闭环断言 +1. `prestorage-revoke` +- 先发起 `prestorage-submit` +- 再调用 `POST /admin-api/business/accounting-adjust/prestorage-revoke` +- 断言: + - 返回 `actionType=REVOKE` + - `biz_account.id=900001.deposit` 从 `90.00` 恢复到 `100.00` + - 存在 `revokeOfAdjustmentNo=<原adjustmentNo>` 明细 + +2. `sold-batch-revoke` +- 先发起 `sold-submit` +- 再调用 `POST /admin-api/business/accounting-adjust/sold-batch-revoke` +- 断言: + - `successCount=1` + - 存在 `revokeOfAdjustmentNo=<原adjustmentNo>` 明细 + +3. `log-revoke` +- 先发起 `log-prestorage` +- 再调用 `POST /admin-api/business/accounting-adjust/log-revoke` +- 断言: + - 返回 `actionType=REVOKE` + - `biz_charge.id=900003.pay_state` 恢复为 `1` + - `charge_method` 恢复为 `2` + - `charge_way` 恢复为 `6` + - `biz_account.id=900004.deposit` 从 `20.00` 回退到 `0.00` + - 存在 `revokeOfAdjustmentNo=<原adjustmentNo>` 明细 + +### 本次真实库验证 +- 执行 1:`REV004_IT_DB_URL=... REV004_IT_DB_USERNAME=... REV004_IT_DB_PASSWORD=... mvn -Dtest='Rev004AccountProcessCanaryQueryIntegrationTest' test` +- 结果 1:BUILD SUCCESS + - `Rev004AccountProcessCanaryQueryIntegrationTest`: 10 tests / 0 fail / 0 skip +- 执行 2:`REV004_IT_DB_URL=... REV004_IT_DB_USERNAME=... REV004_IT_DB_PASSWORD=... mvn -Dtest='Rev004AccountProcess*' test` +- 结果 2:BUILD SUCCESS + - `Rev004AccountProcessLiveDbReadinessTest`: 1 pass + - `Rev004AccountProcessIntegrationFixtureAssetsTest`: 1 pass + - `Rev004AccountProcessCanaryQueryIntegrationTest`: 10 pass + - 总计:12 tests / 0 fail / 0 skip + +### 当前 canary 套件真实覆盖(10 条) +- `prestoragePage_shouldReturnSuccessEnvelope` +- `prestorageSubmit_shouldChangeBalanceAndWriteOperatLog` +- `prestorageRevoke_shouldRestoreBalanceAndWriteRevokeLog` +- `soldSubmit_shouldWritePendingOperatLog` +- `soldBatchRevoke_shouldWriteRevokeLogForPendingSyntheticRecord` +- `logPrestorage_shouldClearChargePaymentAndIncreaseTargetDeposit` + +## 2026-06-05 sw-business-server 启动循环修复验证 + +### 问题现象 +- 环境:`root@192.168.10.130`,容器 `sw-business-server` +- 现象:容器反复重启,Docker healthcheck 一度显示 healthy,但应用日志持续出现 `Application run failed` +- 关键异常: + - `Error creating bean with name 'prestorageAdjustBpmApiImpl'` + - `Error creating bean with name 'prestorageBpmCallbackService'` + - `BeanCurrentlyInCreationException: Error creating bean with name 'custServiceImpl'` + - `custServiceImpl` 已以 raw version 注入 `chargeServiceImpl`、`waterUseSchemeServiceImpl`、`exceedWaterUseSchemeServiceImpl`、`custWaterSchemeRelServiceImpl`,随后又被 AOP 包装,Spring 拒绝混用 raw bean 与 proxy bean + +### 修复策略 +- 保留既有 `spring.main.allow-circular-references=true` 配置;该配置只能允许普通循环依赖,不能解决 raw bean 被代理包装后的不一致问题。 +- 对异常中明确点名的 4 个 `CustService` 注入点增加 `@Lazy`: + - `ChargeServiceImpl.custService` + - `WaterUseSchemeServiceImpl.custService` + - `ExceedWaterUseSchemeServiceImpl.custService` + - `CustWaterSchemeRelServiceImpl.custService` +- 新增回归测试 `CustServiceCircularDependencyContractTest`,约束上述 4 个注入点必须使用 lazy proxy。 + +### 本次验证 +- RED 验证: + - 命令:`mvn -pl sw-business/sw-business-server -am -Dtest=CustServiceCircularDependencyContractTest -Dsurefire.failIfNoSpecifiedTests=false test` + - 结果:测试按预期失败,失败点为 `ChargeServiceImpl.custService must be @Lazy` +- GREEN 验证: + - 命令:`mvn -pl sw-business/sw-business-server -am -Dtest=CustServiceCircularDependencyContractTest -Dsurefire.failIfNoSpecifiedTests=false test` + - 结果:BUILD SUCCESS,`1 tests / 0 failures / 0 errors / 0 skipped` +- 打包验证: + - 命令:`mvn -pl sw-business/sw-business-server -am -DskipTests package` + - 结果:BUILD SUCCESS,生成 `sw-business/sw-business-server/target/sw-business-server.jar` +- 远端部署验证: + - 上传 jar 到 `/projects/sw-cloud/sw-business-server/target/sw-business-server.jar` + - 远端执行:`cd /projects/sw-cloud && docker compose build sw-business-server && docker compose up -d sw-business-server` + - 结果:镜像 `sw-cloud-sw-business-server` 重建成功,容器 `sw-business-server` 重新创建并启动 +- 远端运行验证: + - 日志出现:`Tomcat started on port 48090`、`nacos registry, DEFAULT_GROUP business-server 192.168.10.130:48090 register finished`、`Started BusinessApplication in 42.77 seconds` + - 最近启动日志未再出现 `Application run failed`、`BeanCurrentlyInCreationException`、`Error creating bean with name` + - HTTP 验证:`curl http://127.0.0.1:48090/actuator/health` 返回 `{"status":"UP"}`,HTTP 200 + +### 遗留风险 +- `docker-compose.yml` 中 `sw-business-server` healthcheck 当前检查 `http://localhost:48080`,而业务应用实际监听 `48090`;该 healthcheck 会把其他服务返回的 HTTP 200 / 404 JSON 误判为业务健康。建议后续改为 `http://localhost:48090/actuator/health`。 +- 当前修复是最小断环修复;长期更优方向是拆分 `CustServiceImpl` 的查询能力与写能力,减少跨业务 service 之间的双向依赖。 +- `logRevoke_shouldRestoreChargePaymentAndRollbackTransferredDeposit` +- `logProcess_shouldReturnUpdatedProcessSummary` +- `logAttachments_shouldReturnUnresolvedAttachmentRef` +- `logRefund_shouldClearChargePaymentAndWriteFollowupLog` + +## 2026-04-13 继续推进:unsold 五类真实库 happy path 补齐 +- 新增 `30_unsold_seed.sql` 真实库 fixture: + - `biz_cust.id=900005 / code=REV004_IT_UNSOLD` + - `biz_charge.id=900005 / pay_state=0 / bill_amount=120.00 / extended_amount=120.00 / late_fee=30.00` +- 扩展 `00_reset.sql`,纳入 `900005 / REV004_IT_UNSOLD` 清理范围 +- 新增 5 条真实库 canary: + - `unsoldAdjustSubmit_shouldUpdateAmountsAndWriteOperatLog` + - `unsoldSplitSubmit_shouldCreatePendingApprovalRecord` + - `unsoldLateFeeReduceSubmit_shouldCreatePendingApprovalRecord` + - `unsoldPriceDiffSubmit_shouldCreatePendingApprovalRecord` + - `unsoldBadDebtSubmit_shouldCreatePendingApprovalRecord` + +### 新增闭环断言 +1. `unsold-adjust-submit` +- 返回 `SUCCESS` +- `biz_charge.id=900005.extended_amount` 更新为 `88.88` +- `bill_amount` 更新为 `80.00` +- `biz_operat_log.operat_content` 含返回 `adjustmentNo` + +2. `unsold-split-submit` +- 返回 `PENDING_APPROVAL` +- `objectType=SPLIT_ADJUST` +- `biz_operat_log.operat_content` 含返回 `adjustmentNo` + +3. `unsold-late-fee-reduce-submit` +- 返回 `PENDING_APPROVAL` +- `objectType=LATE_FEE_REDUCE` +- `biz_operat_log.operat_content` 含返回 `adjustmentNo` + +4. `unsold-price-diff-submit` +- 返回 `PENDING_APPROVAL` +- `objectType=PRICE_DIFF_ADJUST` +- `biz_operat_log.operat_content` 含返回 `adjustmentNo` + +5. `unsold-bad-debt-submit` +- 返回 `PENDING_APPROVAL` +- `objectType=BAD_DEBT_RECORD` +- `biz_operat_log.operat_content` 含返回 `adjustmentNo` + +### 本次真实库验证 +- 执行 1:`REV004_IT_DB_URL=... REV004_IT_DB_USERNAME=... REV004_IT_DB_PASSWORD=... mvn -Dtest='Rev004AccountProcessCanaryQueryIntegrationTest' test` +- 结果 1:BUILD SUCCESS + - `Rev004AccountProcessCanaryQueryIntegrationTest`: 15 tests / 0 fail / 0 skip +- 执行 2:`REV004_IT_DB_URL=... REV004_IT_DB_USERNAME=... REV004_IT_DB_PASSWORD=... mvn -Dtest='Rev004AccountProcess*' test` +- 结果 2:BUILD SUCCESS + - `Rev004AccountProcessLiveDbReadinessTest`: 1 pass + - `Rev004AccountProcessIntegrationFixtureAssetsTest`: 1 pass + - `Rev004AccountProcessCanaryQueryIntegrationTest`: 15 pass + - 总计:17 tests / 0 fail / 0 skip + +### 当前 canary 套件真实覆盖(15 条) +- `prestoragePage_shouldReturnSuccessEnvelope` +- `prestorageSubmit_shouldChangeBalanceAndWriteOperatLog` +- `prestorageRevoke_shouldRestoreBalanceAndWriteRevokeLog` +- `soldSubmit_shouldWritePendingOperatLog` +- `soldBatchRevoke_shouldWriteRevokeLogForPendingSyntheticRecord` +- `unsoldAdjustSubmit_shouldUpdateAmountsAndWriteOperatLog` +- `unsoldSplitSubmit_shouldCreatePendingApprovalRecord` +- `unsoldLateFeeReduceSubmit_shouldCreatePendingApprovalRecord` +- `unsoldPriceDiffSubmit_shouldCreatePendingApprovalRecord` +- `unsoldBadDebtSubmit_shouldCreatePendingApprovalRecord` +- `logPrestorage_shouldClearChargePaymentAndIncreaseTargetDeposit` +- `logRevoke_shouldRestoreChargePaymentAndRollbackTransferredDeposit` +- `logProcess_shouldReturnUpdatedProcessSummary` +- `logAttachments_shouldReturnUnresolvedAttachmentRef` +- `logRefund_shouldClearChargePaymentAndWriteFollowupLog` + +### 剩余待补 +- 更高一层的“提交 -> page/stat/detail/process/attachments 联动回看”场景编排 +- 若要进一步贴近前端验收,可再补一轮按弹窗功能分组的端到端查询/动作串联用例 + +## 2026-04-13 继续推进:提交后联动回看场景补齐 +- 新增 3 条更贴近前端验收的联动回看 canary: + - `prestorageSubmit_thenPageStatAndDetailShouldExposeNewRecord` + - `soldSubmit_thenSoldPageAndStatShouldExposePendingRevokeCapability` + - `logSeed_thenPageStatDetailProcessAndAttachmentsShouldStayConsistent` + +### 新增联动断言 +1. `prestorage` 提交后联动回看 +- 提交 `prestorage-submit` +- 再查: + - `prestorage-page` + - `prestorage-stat` + - `prestorage-detail` +- 断言: + - page 能看到新 `adjustmentNo` + - stat 的 `totalCount=1 / refundCount=1` + - detail 返回 `resultStatus=SUCCESS / writeBackStatus=UPDATED` + +2. `sold` 提交后联动回看 +- 提交 `sold-submit` +- 再查: + - `sold-page` + - `sold-stat` +- 断言: + - page 仍能看到 `biz_charge.id=900002` + - `canBatchRevoke=true` + - stat 的 `totalCount=1 / totalActualAmount=80.00` + +3. `log` 全链回看 +- 基于 `40_accountlog_seed.sql` 中的 `REV004-LOG-900003` +- 依次验证: + - `log-page` + - `log-stat` + - `log-detail` + - `log-process` + - `log-attachments` +- 断言: + - page 可见 `adjustmentNo=REV004-LOG-900003` + - stat `completedCount=1` + - detail 包含 `originalTranSeq=T-900003` 与 `attachmentRefs[0]=mock-ref-1` + - process `processState=UPDATED` + - attachments 可返回 `mock-ref-1` + +### 本次真实库验证 +- 执行 1:`REV004_IT_DB_URL=... REV004_IT_DB_USERNAME=... REV004_IT_DB_PASSWORD=... mvn -Dtest='Rev004AccountProcessCanaryQueryIntegrationTest' test` +- 结果 1:BUILD SUCCESS + - `Rev004AccountProcessCanaryQueryIntegrationTest`: 18 tests / 0 fail / 0 skip +- 执行 2:`REV004_IT_DB_URL=... REV004_IT_DB_USERNAME=... REV004_IT_DB_PASSWORD=... mvn -Dtest='Rev004AccountProcess*' test` +- 结果 2:BUILD SUCCESS + - `Rev004AccountProcessLiveDbReadinessTest`: 1 pass + - `Rev004AccountProcessIntegrationFixtureAssetsTest`: 1 pass + - `Rev004AccountProcessCanaryQueryIntegrationTest`: 18 pass + - 总计:20 tests / 0 fail / 0 skip + +### 当前真实库 canary 覆盖(18 条) +- `prestoragePage_shouldReturnSuccessEnvelope` +- `prestorageSubmit_shouldChangeBalanceAndWriteOperatLog` +- `prestorageRevoke_shouldRestoreBalanceAndWriteRevokeLog` +- `prestorageSubmit_thenPageStatAndDetailShouldExposeNewRecord` +- `soldSubmit_shouldWritePendingOperatLog` +- `soldBatchRevoke_shouldWriteRevokeLogForPendingSyntheticRecord` +- `soldSubmit_thenSoldPageAndStatShouldExposePendingRevokeCapability` +- `unsoldAdjustSubmit_shouldUpdateAmountsAndWriteOperatLog` +- `unsoldSplitSubmit_shouldCreatePendingApprovalRecord` +- `unsoldLateFeeReduceSubmit_shouldCreatePendingApprovalRecord` +- `unsoldPriceDiffSubmit_shouldCreatePendingApprovalRecord` +- `unsoldBadDebtSubmit_shouldCreatePendingApprovalRecord` +- `logPrestorage_shouldClearChargePaymentAndIncreaseTargetDeposit` +- `logRevoke_shouldRestoreChargePaymentAndRollbackTransferredDeposit` +- `logSeed_thenPageStatDetailProcessAndAttachmentsShouldStayConsistent` +- `logProcess_shouldReturnUpdatedProcessSummary` +- `logAttachments_shouldReturnUnresolvedAttachmentRef` +- `logRefund_shouldClearChargePaymentAndWriteFollowupLog` + +### 当前剩余缺口 +- 若要进一步逼近前端验收,可继续补“弹窗 A/B/C 对应多接口切换”的编排式测试摘要 +- 以及基于接口返回字段做一版更面向页面的 contract/assertion matrix + +## 2026-04-13 继续推进:unsold 查询面真实库回看补齐 +- 新增 2 条真实库查询联动 canary: + - `unsoldSeed_thenPageAndStatShouldExposeChargeSnapshot` + - `unsoldAdjustSubmit_thenPageAndStatShouldReflectUpdatedAmounts` + +### 新增断言 +1. `unsold` 初始查询面 +- `GET /admin-api/business/accounting-adjust/unsold-page` +- `GET /admin-api/business/accounting-adjust/unsold-stat` +- 断言: + - `biz_charge.id=900005` 可见 + - `totalAmount=120.00` + - `billAmount=120.00` + - `penaltyAmount=30.00` + - `canAdjust/canSplit/canLateFeeReduce/canPriceDiffAdjust/canBadDebtAdjust=true` + - stat:`sumWaterVolume=5.000 / sumTotalAmount=120.00 / sumBillAmount=120.00 / sumPenaltyAmount=30.00` + +2. `unsold-adjust-submit` 后查询面回看 +- 先提交 `unsold-adjust-submit` +- 再查 `unsold-page / unsold-stat` +- 断言: + - page 中 `totalAmount=88.88` + - page 中 `billAmount=80.00` + - stat 中 `sumTotalAmount=88.88` + - stat 中 `sumBillAmount=80.00` + +### 本次真实库验证 +- 执行 1:`REV004_IT_DB_URL=... REV004_IT_DB_USERNAME=... REV004_IT_DB_PASSWORD=... mvn -Dtest='Rev004AccountProcessCanaryQueryIntegrationTest' test` +- 结果 1:BUILD SUCCESS + - `Rev004AccountProcessCanaryQueryIntegrationTest`: 20 tests / 0 fail / 0 skip +- 执行 2:`REV004_IT_DB_URL=... REV004_IT_DB_USERNAME=... REV004_IT_DB_PASSWORD=... mvn -Dtest='Rev004AccountProcess*' test` +- 结果 2:BUILD SUCCESS + - `Rev004AccountProcessLiveDbReadinessTest`: 1 pass + - `Rev004AccountProcessIntegrationFixtureAssetsTest`: 1 pass + - `Rev004AccountProcessCanaryQueryIntegrationTest`: 20 pass + - 总计:22 tests / 0 fail / 0 skip + +### 影响 +- `prestorage / sold / unsold / log` 四条主查询面现在都至少有一组真实库回看证据 +- 剩余未补重点从“主链查询缺口”收敛为“预存页流程/附件链路 + 字典/UI文案展示一致性” + +## 2026-04-13 继续推进:prestorage process / attachments 真实库补齐 +- 新增 canary:`prestorageSubmit_thenProcessAndAttachmentsShouldExposeReturnedAdjustmentNo` +- 在 `prestorage-submit` 场景中附带 `attachmentRefs=[pre-proof-2, pre-proof-3]` +- 提交后继续验证: + - `GET /admin-api/business/accounting-adjust/prestorage-process` + - `GET /admin-api/business/accounting-adjust/prestorage-attachments` + +### 新增断言 +- process: + - `adjustmentNo` 与提交返回一致 + - `resultStatus=SUCCESS` + - `approvalStatus=NOT_REQUIRED` + - `writeBackStatus=UPDATED` + - `processState=UPDATED` + - `stages[0].message` 存在 +- attachments: + - 返回两条附件引用 + - `ref=pre-proof-2 / pre-proof-3` + - `resolved=false` + +### 本次真实库验证 +- `Rev004AccountProcessCanaryQueryIntegrationTest`: **21 tests / 0 fail / 0 skip** +- `Rev004AccountProcess*`: **总计 23 tests / 0 fail / 0 skip** + +### 影响 +- `prestorage` 查询/提交流程/撤销/流程查看/附件查看 这一组链路现在都已有真实库证据 +- 剩余缺口进一步收敛到:字典 label / UI 文案一致性、边角筛选条件穷尽、UI 编排级验证 + +## 2026-06-05 远端启动修复后真实 HTTP/BPM 闭环验证 + +### 环境 +- 后端:`192.168.10.130`,`sw-business-server` 端口 `48090`,gateway 端口 `48080` +- 前端代理:本地 Vite `http://127.0.0.1:18080/admin-api` -> gateway +- 数据库:`192.168.10.130:5436/sw_system` +- 测试数据:`00_reset.sql` + `01_dict_seed.sql` + `10_prestorage_seed.sql` + +### 启动与健康检查 +- `sw-business-server` 重新构建部署后日志出现 `Started BusinessApplication` +- `curl http://192.168.10.130:48090/actuator/health` 返回 `{"status":"UP"}` +- `curl http://192.168.10.130:48080/actuator/health` 返回 `{"status":"UP"}` + +### 真实接口链路 +1. 登录 +- `POST /admin-api/system/auth/login` +- `tenant-id: 1` +- 返回 `code=0`,获得 `accessToken` + +2. 预存退款:保存 -> BPM 审批 -> 自动执行 -> 查询回看 +- `POST /admin-api/business/accounting-adjust/prestorage-save` +- 请求核心字段: + - `custCode=REV004_IT_SRC` + - `refundAmount=10.00` + - `applicant=接口闭环测试人` + - `attachmentRefs=[real-api-proof-1]` +- 保存返回: + - `adjustmentNo=REV004-PRF-900001-20260605101623` + - `resultStatus=PENDING_APPROVAL` + - `approvalStatus=PENDING_APPROVAL` + - `writeBackStatus=PENDING` + - `resultObjectNo=8d8af605-6084-11f1-8df9-5ad978d7f8ab` +- BPM 待办: + - `GET /admin-api/bpm/task/list-by-process-instance-id?processInstanceId=8d8af605-6084-11f1-8df9-5ad978d7f8ab` + - taskId=`8da3600e-6084-11f1-8df9-5ad978d7f8ab` +- 审批: + - `PUT /admin-api/bpm/task/approve` + - 返回 `code=0,data=true` +- 回看: + - `GET /admin-api/business/accounting-adjust/prestorage-process` + - `resultStatus=SUCCESS` + - `approvalStatus=APPROVED` + - `writeBackStatus=UPDATED` + - `processState=UPDATED` + - `latestMessage=BPM审批通过后自动执行预存退款` +- DB 断言: + - `biz_account(900001).deposit=90.00` + - `biz_prestorage_adjust.business_status=COMPLETED` + - `biz_prestorage_payment_relation` 写入 `payment_record_id=159` + +3. 预存转账:保存 -> BPM 审批 -> 自动执行 -> 查询回看 +- `POST /admin-api/business/accounting-adjust/prestorage-save` +- 请求核心字段: + - `custCode=REV004_IT_SRC` + - `targetCustCode=REV004_IT_TGT` + - `transferAmount=30.00` + - `applicant=接口闭环转账人` + - `attachmentRefs=[real-api-transfer-proof]` +- 保存返回: + - `adjustmentNo=REV004-PTR-900001-20260605102121` + - `resultStatus=PENDING_APPROVAL` + - `approvalStatus=PENDING_APPROVAL` + - `writeBackStatus=PENDING` + - `resultObjectNo=3e231762-6085-11f1-8df9-5ad978d7f8ab` +- BPM 审批: + - taskId=`3e2401cb-6085-11f1-8df9-5ad978d7f8ab` + - `PUT /admin-api/bpm/task/approve` 返回 `code=0,data=true` +- 回看: + - `GET /admin-api/business/accounting-adjust/prestorage-process` + - `resultStatus=SUCCESS` + - `approvalStatus=APPROVED` + - `writeBackStatus=UPDATED` + - `latestMessage=BPM审批通过后自动执行预存转账` + - `prestorage-page` 中 `workOrderStatus=2 / adjustmentType=2 / targetCustCode=REV004_IT_TGT / remainingAmount=60.00` +- DB 断言: + - `biz_account(900001).deposit=60.00` + - `biz_account(900004).deposit=30.00` + +### 本次联调发现并处理的问题 +- 首次 BPM 审批退款失败,`/admin-api/bpm/task/approve` 返回 `code=500` +- 服务端根因: + - `ERROR: relation "biz_prestorage_payment_relation_seq" does not exist` + - 表 DDL 使用 `BIGSERIAL`,实际 sequence 为 `biz_prestorage_payment_relation_id_seq` + - Java 实体 `PrestoragePaymentRelationDO` 原标注 `@KeySequence("biz_prestorage_payment_relation_seq")` +- 临时环境修复: + - 远端库补齐兼容 sequence:`biz_prestorage_payment_relation_seq` +- 代码修复: + - `PrestoragePaymentRelationDO` 改为 `@KeySequence("biz_prestorage_payment_relation_id_seq")` + - 新增 `PrestoragePaymentRelationSequenceContractTest` 锁定注解与 DDL sequence 名一致 + +### 本次本地验证 +- `mvn -pl sw-business/sw-business-server -am -DskipTests compile` + - 结果:BUILD SUCCESS +- `javap` 反射核验: + - `PrestoragePaymentRelationDO` 当前产物中的 `@KeySequence` 为 `biz_prestorage_payment_relation_id_seq` +- 受既有测试编译问题影响,单测命令 `mvn -pl sw-business/sw-business-server -Dtest=PrestoragePaymentRelationSequenceContractTest test` 未能进入目标测试: + - 阻塞点:`MeterInOutServiceImplTest` 引用缺失的 `METER_IN_MODEL_CALIBER_MISMATCH` 与 `METER_IMPORT_MODEL_CALIBER_MISMATCH_MSG` + +### 2026-06-05 本地 targeted contract test 复核 +- 命令: + - `mvn -pl sw-business/sw-business-server -am -Dtest=CustServiceCircularDependencyContractTest,PrestoragePaymentRelationSequenceContractTest -Dsurefire.failIfNoSpecifiedTests=false test` +- 结果: + - `BUILD SUCCESS` + - `CustServiceCircularDependencyContractTest`: 1 tests / 0 failures / 0 errors / 0 skipped + - `PrestoragePaymentRelationSequenceContractTest`: 1 tests / 0 failures / 0 errors / 0 skipped +- 说明: + - `-Dsurefire.failIfNoSpecifiedTests=false` 用于 reactor 前置模块无匹配 `-Dtest` 用例时继续执行到 `sw-business-server` + - 本次复核覆盖四处 `CustService` 懒加载注入 contract 与 `biz_prestorage_payment_relation_id_seq` 注解 contract diff --git a/docs/evidence/rev004-accounting/rev004-accountprocess-interface-truth-matrix-2026-04-13.md b/docs/evidence/rev004-accounting/rev004-accountprocess-interface-truth-matrix-2026-04-13.md new file mode 100644 index 0000000..dbeb1ee --- /dev/null +++ b/docs/evidence/rev004-accounting/rev004-accountprocess-interface-truth-matrix-2026-04-13.md @@ -0,0 +1,315 @@ +# REV004 / accountProcess 接口真值矩阵(2026-04-13) + +## 目的 +给前端/联调/验收一个“当前代码真实口径”矩阵: +- 哪个页面/弹窗对应哪些接口 +- 每个接口当前稳定返回哪些关键字段 +- 哪些字段已经被真实库测试覆盖 +- 哪些地方仍然是页面编排层面的剩余缺口 + +> 口径来源:`water-backend` 当前控制器 + Req/RespVO + 已落地真实库 canary。 + +--- + +## 一、页面 / 弹窗 -> 接口映射 + +### 1. 预存调整页 +#### 查询区 +- `GET /admin-api/business/accounting-adjust/prestorage-page` +- `GET /admin-api/business/accounting-adjust/prestorage-stat` +- `GET /admin-api/business/accounting-adjust/prestorage-detail?id={id}` + +#### 动作区 +- `POST /admin-api/business/accounting-adjust/prestorage-submit` +- `POST /admin-api/business/accounting-adjust/prestorage-revoke` +- `GET /admin-api/business/accounting-adjust/prestorage-process?adjustmentNo=...` +- `GET /admin-api/business/accounting-adjust/prestorage-attachments?adjustmentNo=...` + +#### 维护区 +- `POST /prestorage-customer-update` +- `POST /prestorage-meter-update` +- `POST /prestorage-billing-update` +- `POST /prestorage-discount-update` +- `POST /prestorage-cost-component-update` + +### 2. 已销调整页 +#### 查询区 +- `GET /admin-api/business/accounting-adjust/sold-page` +- `GET /admin-api/business/accounting-adjust/sold-stat` + +#### 动作区 +- `POST /admin-api/business/accounting-adjust/sold-submit` +- `POST /admin-api/business/accounting-adjust/sold-batch-revoke` + +### 3. 未销调整页 +#### 查询区 +- `GET /admin-api/business/accounting-adjust/unsold-page` +- `GET /admin-api/business/accounting-adjust/unsold-stat` + +#### 动作区(按弹窗切换) +- 调整:`POST /unsold-adjust-submit` +- 分账:`POST /unsold-split-submit` +- 违约金减免:`POST /unsold-late-fee-reduce-submit` +- 价差调整:`POST /unsold-price-diff-submit` +- 呆坏账:`POST /unsold-bad-debt-submit` + +#### 批量区 +- `POST /unsold-adjust-batch-submit` +- `POST /unsold-split-batch-submit` +- `POST /unsold-late-fee-reduce-batch-submit` +- `POST /unsold-price-diff-batch-submit` +- `POST /unsold-bad-debt-batch-submit` + +### 4. 账务日志页 +#### 查询区 +- `GET /admin-api/business/accounting-adjust/log-page` +- `GET /admin-api/business/accounting-adjust/log-stat` +- `GET /admin-api/business/accounting-adjust/log-detail?adjustmentNo=...` + +#### 二次动作弹窗 +- 转退款:`POST /admin-api/business/accounting-adjust/log-refund` +- 转预存:`POST /admin-api/business/accounting-adjust/log-prestorage` +- 撤销:`POST /admin-api/business/accounting-adjust/log-revoke` + +#### 辅助弹窗 +- `GET /admin-api/business/accounting-adjust/log-process?adjustmentNo=...` +- `GET /admin-api/business/accounting-adjust/log-attachments?adjustmentNo=...` + +--- + +## 二、关键返回字段真值 + +### A. 通用动作返回 `AccountingAdjustRespVO` +适用: +- `prestorage-submit` +- `sold-submit` +- `unsold-*submit` +- `log-refund` +- `log-prestorage` + +当前稳定字段: +- `adjustmentNo`:主联调键 +- `objectType`:对象类型;未销调整 AMOUNT/USAGE 场景可能为空,其他场景一般有值 +- `resultStatus`:推荐前端主读字段 +- `approvalStatus` +- `writeBackStatus` +- `approvalRequired` +- `resultObjectNo` +- `msg` +- `status`:兼容旧字段 +- `message`:兼容旧字段 + +前端推荐: +- **优先读** `resultStatus / approvalStatus / writeBackStatus / msg` +- `status / message` 仅做兼容保底 + +### B. 撤销 / 审批动作返回 `AccountingAdjustActionRespVO` +适用: +- `prestorage-revoke` +- `log-revoke` + +当前稳定字段: +- `adjustmentNo` +- `objectType` +- `actionType`(当前撤销返回 `REVOKE`) +- `approvalStatus` +- `resultStatus` +- `writeBackStatus` +- `message` +- `actionTime` + +### C. 预存分页 `AccountingAdjustPrestoragePageRespVO` +关键字段: +- `id` +- `adjustmentNo` +- `custId` +- `workOrderStatus` +- `adjustmentType` +- `custCode / custName / custAddress` +- `targetCustCode` +- `adjustAmount / preBalance / postBalance` +- `adjustReason / remark` +- `createTime / creatorName` +- `canRevoke / canViewAttachment` + +补充: +- `prestorage-detail` 在上面基础上增加: + - `objectType` + - `resultStatus` + - `approvalStatus` + - `writeBackStatus` + - `processInstanceId` + - `attachmentRefs` + +### D. 已销分页 `AccountingAdjustSoldPageRespVO` +关键字段: +- `id` +- `custId` +- `accountMonth` +- `custCode / custName / custAddress` +- `waterNature` +- `billedWaterVolume` +- `actualAmount` +- `billedAmount` +- `penaltyAmount` +- `collectionMethod` +- `collector` +- `collectionDate` +- `canAdjust` +- `canBatchRevoke` + +注意: +- 已销查询页**不是调整日志页**,所以这里没有 `adjustmentNo` +- `sold-submit` 提交后,前端若要看申请单号,应跳到 `log-*` 维度或使用提交返回值保存的 `adjustmentNo` + +### E. 未销分页 `AccountingAdjustUnsoldPageRespVO` +关键字段: +- `id` +- `custId` +- `custCode / custName / custAddress` +- `waterType` +- `accountMonth` +- `waterVolume` +- `totalAmount / billAmount / penaltyAmount` +- `waterFee / sewageFee / garbageFee / resourcesFee / overPlanFee / seasonalSupplement` +- `canAdjust / canSplit / canLateFeeReduce / canPriceDiffAdjust / canBadDebtAdjust` + +### F. 日志分页 `AccountingAdjustLogPageRespVO` +关键字段: +- `id` +- `adjustmentNo` +- `accountMonth` +- `custId / custCode / custName / custAddress` +- `accountTypeCode / accountType` +- `processMethodCode / processMethod` +- `amount` +- `description` +- `registrant / handler` +- `handleTime / createTime` +- `statusCode / status` +- `targetCustCode` +- `originalPrestore / newPrestore` +- `originalBill / newBill` +- `originalWaterVolume / newWaterVolume` +- `originalPenalty / newPenalty` +- `billChange / waterVolumeChange / penaltyChange` +- `canRevoke / canRefund / canPrestore` + +### G. 日志详情 `AccountingAdjustLogDetailRespVO` +在日志分页基础上增加: +- `objectType` +- `resultStatus` +- `approvalStatus` +- `writeBackStatus` +- `originalTranSeq` +- `originalSysTranSeq` +- `attachmentRefs` +- `details[]` + +### H. 流程 / 附件 +#### `AccountingAdjustProcessRespVO` +关键字段: +- `adjustmentNo` +- `objectType` +- `adjustType` +- `chargeId` +- `actionAmount` +- `resultStatus` +- `approvalStatus` +- `writeBackStatus` +- `taskId` +- `processState` +- `latestMessage` +- `latestOperationTime` +- `stages[]` + +#### `AccountingAdjustAttachmentRespVO` +关键字段: +- `adjustmentNo` +- `ref` +- `resolved` +- `id / name / link / size / extension` +- `message` + +--- + +## 三、当前已经被真实库测试证明的字段/链路 + +### 已证明 +#### 预存 +- `prestorage-submit` 返回 `adjustmentNo/resultStatus/writeBackStatus` +- `prestorage-page` 可见新记录 +- `prestorage-stat` 可统计到 `refundCount` +- `prestorage-detail` 可按 `id` 回看 `resultStatus/writeBackStatus` +- `prestorage-revoke` 可回滚余额并生成撤销日志 + +#### 已销 +- `sold-submit` 返回 `adjustmentNo/resultStatus=PENDING_APPROVAL` +- `sold-page` 可见原账单,且 `canBatchRevoke=true` +- `sold-stat` 可统计 `totalCount / totalActualAmount` +- `sold-batch-revoke` 可按营业账 ID 执行撤销 + +#### 未销 +- 五类 submit 均已跑通真实库 happy path: + - adjust + - split + - late-fee-reduce + - price-diff + - bad-debt +- 动作返回值与 operat_log 写入已被验证 + +#### 日志 +- `log-page / log-stat / log-detail / log-process / log-attachments` 已形成一组真实库联动回看 +- `log-refund`、`log-prestorage`、`log-revoke` 已打通闭环 +- `log-detail` 中 `originalTranSeq / attachmentRefs` 已被验证 + +--- + +## 四、前端使用建议(当前真值口径) + +### 1. 提交后立即展示 +提交类动作完成后,前端应优先使用提交响应里的: +- `adjustmentNo` +- `resultStatus` +- `approvalStatus` +- `writeBackStatus` +- `msg` + +### 2. 页面列表回看 +- 预存页:查 `prestorage-page` +- 已销页:查 `sold-page` +- 未销页:查 `unsold-page` +- 若要看“申请/动作留痕”,查 `log-page` + +### 3. 二次动作弹窗 +- 日志页弹窗(退款/转预存/撤销)都应以 `adjustmentNo` 作为主键 +- 已销批量撤销当前以 `chargeIds[]` 为入参,不是 `adjustmentNo[]` + +### 4. 状态口径 +- 预存页 `workOrderStatus`:0未处理 / 1已审核 / 2已完成 / 3已撤销 +- 通用动作结果: + - `resultStatus` + - `approvalStatus` + - `writeBackStatus` +- 日志页状态: + - `statusCode/status` 为页面状态投影,不等于 `workOrderStatus` + +--- + +## 五、剩余缺口 +1. 还没有做“前端弹窗 A/B/C 切换路径”的 UI 级编排,只做到了接口级真实库链路。 +2. 还没有把所有字段做成“页面元素 -> 字段 -> 接口 -> 证据”的逐项勾稽表。 +3. 若后续要做最终验收,建议再补一版: + - 弹窗功能分组矩阵 + - 字段级 contract/assertion matrix + +--- + +## 六、证据索引 +- 集成测试 bootstrap 与累计验证: + - `docs/evidence/rev004-accountprocess-integration-testing-bootstrap-2026-04-13.md` +- 代码位置: + - `sw-business-server/src/main/java/.../accountProcess/*Controller.java` + - `sw-business-server/src/main/java/.../accountProcess/vo/*ReqVO.java` + - `sw-business-server/src/main/java/.../accountProcess/vo/*RespVO.java` + - `sw-business-server/src/test/java/.../integration/rev004/accountprocess/Rev004AccountProcessCanaryQueryIntegrationTest.java` diff --git a/docs/evidence/rev004-accounting/rev004-accountprocess-page-label-audit-2026-04-13.md b/docs/evidence/rev004-accounting/rev004-accountprocess-page-label-audit-2026-04-13.md new file mode 100644 index 0000000..bc7d78a --- /dev/null +++ b/docs/evidence/rev004-accounting/rev004-accountprocess-page-label-audit-2026-04-13.md @@ -0,0 +1,104 @@ +# REV004 / accountProcess 页面文案与字典 label 核对表(2026-04-13) + +## 1. 目的 +本表站在前端/UAT 视角,回答: +- 页面上显示的文案/标签,当前应从哪个字段读取? +- 该字段是原始编码、字典 label,还是代码 fallback 值? +- 当前是否已具备稳定真值来源? + +> 说明:本表是“字段/label 来源核对”,不是视觉稿验收。 + +--- + +## 2. 预存调整页 +| 页面展示项 | 建议展示来源 | 类型 | 当前真值来源 | 状态 | +|---|---|---|---|---| +| 工单状态 | `workOrderStatus` -> `work_status` label | 字典 label | `DictTypeConstants.WORK_STATUS` + 正式设计文档 + seed SQL | 已确认 | +| 调整类型 | `adjustmentType` | 业务枚举/旧口径 | 代码已有字段,但 label 映射未单列文档 | 待前端确认展示文案 | +| 客户编号/名称/地址 | `custCode/custName/custAddress` | 直接值 | DB 真值 | 已确认 | +| 调整余额/期初/期末余额 | `adjustAmount/preBalance/postBalance` | 直接值 | DB 真值 | 已确认 | +| 是否可撤销 | `canRevoke` | 布尔能力 | Service 推导 | 已确认 | +| 是否可查看附件 | `canViewAttachment` | 布尔能力 | Service 推导 | 已确认 | +| 提交成功提示 | `msg` | 文本 | Action 返回 | 已确认 | +| 详情结果状态 | `resultStatus` | 字典 label 候选 | 当前后端主要返回 code;前端如需文案应绑 `account_adjust_result_status` | 已确认 | +| 详情审批状态 | `approvalStatus` | 字典 label 候选 | 绑 `account_adjust_approval_status` | 已确认 | +| 详情回写状态 | `writeBackStatus` | 字典 label 候选 | 绑 `account_adjust_writeback_status` | 已确认 | + +### 预存页当前结论 +- 工单状态四态已稳定:`0未处理 / 1已审核 / 2已完成 / 3已撤销` +- 详情三状态字段推荐前端统一走 REV004 新字典做 label 显示 +- `prestorage-process / prestorage-attachments` 已有真实库证据,页面已具备展示基础 + +--- + +## 3. 已销调整页 +| 页面展示项 | 建议展示来源 | 类型 | 当前真值来源 | 状态 | +|---|---|---|---|---| +| 用水性质 | `waterNature` | 当前为模板名/编码映射 | `PriceTemplate` 名称映射 | 已确认 | +| 收费方式 | `collectionMethod` | 字典 label | `charge_method` | 已确认 | +| 收费员 | `collector` | 直接值 | DB 字段 | 已确认 | +| 是否可调整 | `canAdjust` | 布尔能力 | Service 推导 | 已确认 | +| 是否可批量撤销 | `canBatchRevoke` | 布尔能力 | Service 推导 | 已确认 | +| 提交结果状态 | `resultStatus` | 字典 label 候选 | `account_adjust_result_status` | 已确认 | +| 提交审批状态 | `approvalStatus` | 字典 label 候选 | `account_adjust_approval_status` | 已确认 | + +### 已销页当前结论 +- 收费方式文案应以后端经 `charge_method` 解析后的 `collectionMethod` 为准 +- 已销提交后的审批态展示建议直接使用返回 code + 新字典映射 label +- 批量撤销按钮能力应以后端 `canBatchRevoke` 和 `chargeIds[]` 入参约束为准 + +--- + +## 4. 未销调整页 +| 页面展示项 | 建议展示来源 | 类型 | 当前真值来源 | 状态 | +|---|---|---|---|---| +| 用水性质 | `waterType` | 当前为模板编码 | 代码直接回 `priceTemplateCode` | 待前端决定是否需要 label 化 | +| 合计金额/账单金额/违约金 | `totalAmount/billAmount/penaltyAmount` | 直接值 | DB 真值 | 已确认 | +| 五类按钮显隐 | `canAdjust/canSplit/canLateFeeReduce/canPriceDiffAdjust/canBadDebtAdjust` | 布尔能力 | Service 推导 | 已确认 | +| 调整原因 | `applyReason -> 动态 reason 字典` | 字典 label | 见 REV004_DICT_BINDING_MATRIX | 已确认 | +| 分账原因 | `applyReason -> separate_reason` | 字典 label | 见 REV004_DICT_BINDING_MATRIX | 已确认 | +| 违约金减免原因 | `applyReason -> late_fee_reason` | 字典 label | 见 REV004_DICT_BINDING_MATRIX | 已确认 | +| 价差调整原因 | `applyReason -> price_reason` | 字典 label | 见 REV004_DICT_BINDING_MATRIX | 已确认 | +| 呆坏账原因 | `applyReason -> knotty_reason` | 字典 label | 见 REV004_DICT_BINDING_MATRIX | 已确认 | + +### 未销页当前结论 +- 五类弹窗的“原因”不能共用一个字典,应按 objectType/弹窗类型动态切换 +- `waterType` 当前更像编码字段,如果前端要展示“中文用水性质”,需要确认是否再做模板名映射 + +--- + +## 5. 账务日志页 +| 页面展示项 | 建议展示来源 | 类型 | 当前真值来源 | 状态 | +|---|---|---|---|---| +| 账务类型 | `accountType` | 字典 label | `account_adjust_object_type` | 已确认 | +| 处理方式 | `processMethod` | 代码映射 label | Service 内 legacy 映射 | 已确认 | +| 页面状态 | `status/statusCode` | 字典/兼容投影 | success/pending/rejected 由 Service 投影 | 已确认 | +| 目标户号 | `targetCustCode` | 直接值 | 日志明细/业务上下文 | 已确认 | +| 原/新预存、账单、水量、违约金 | 对应 original/new 字段 | 直接值 | DB + log detail 推导 | 已确认 | +| 是否可撤销/退款/预转存 | `canRevoke/canRefund/canPrestore` | 布尔能力 | Service 推导 | 已确认 | +| 结果状态 | `resultStatus` | 字典 label 候选 | `account_adjust_result_status` | 已确认 | +| 审批状态 | `approvalStatus` | 字典 label 候选 | `account_adjust_approval_status` | 已确认 | +| 回写状态 | `writeBackStatus` | 字典 label 候选 | `account_adjust_writeback_status` | 已确认 | +| 附件状态 | `resolved/message` | 直接值 | Attachment 解析逻辑 | 已确认 | + +### 日志页当前结论 +- `accountType` 与 `resultStatus/approvalStatus/writeBackStatus` 已有稳定字典来源 +- `processMethod` 目前是代码映射,不完全等于字典 label,需要前端按当前返回文案展示,不建议自行二次翻译 +- 日志页是当前最适合承接“状态展示 / 二次动作 / 留痕回看”的页面 + +--- + +## 6. 当前仍需前端/UAT逐页确认的点 +1. 未销页 `waterType` 是否需要从编码升级为可读 label。 +2. 预存页 `adjustmentType` 的页面中文文案是否已有既定口径。 +3. 日志页 `processMethod/status` 是否与现有页面视觉稿/原型文案完全一致。 +4. 历史页面或旧截图中若还出现“处理中”这类旧三态文案,应以后端新四态口径为准重新校对。 + +--- + +## 7. 结论 +- 当前**状态字典与核心文案来源已经收口**,后端没有明显“真值不清”的问题。 +- 剩余问题主要不在后端结构,而在: + - 页面展示是否直接使用后端返回文案 + - 前端是否仍残留旧页面文案/旧字典绑定 + - 某些编码字段是否还需要做前端可读化处理 diff --git a/docs/evidence/rev004-accounting/rev004-accountprocess-real-wiring-cleanup-2026-06-05.md b/docs/evidence/rev004-accounting/rev004-accountprocess-real-wiring-cleanup-2026-06-05.md new file mode 100644 index 0000000..fe919c0 --- /dev/null +++ b/docs/evidence/rev004-accounting/rev004-accountprocess-real-wiring-cleanup-2026-06-05.md @@ -0,0 +1,63 @@ +# REV004 accountProcess Real Wiring Cleanup Evidence (2026-06-05) + +## Scope + +- Frontend repository: `/Volumes/Dpan/github/water-workspace/water-frontend` +- Pages/components: + - `src/views/accountProcess/accountLog/index.vue` + - `src/views/accountProcess/accountLog/components/RefundForm.vue` + - `src/views/accountProcess/accountLog/components/TransferPrestoreForm.vue` + - `src/views/accountProcess/soldAdjustment/index.vue` + - `src/views/accountProcess/unsoldAdjustment/components/UnsoldAdjustmentForm.vue` + - `src/views/accountProcess/unsoldAdjustment/components/PriceAdjustmentForm.vue` +- API: + - `src/api/accountProcess/accountLog/index.ts` + +## Interface Basis + +- `GET /business/accounting-adjust/log-page` +- `GET /business/accounting-adjust/log-stat` +- `GET /business/accounting-adjust/log-process` +- `GET /business/accounting-adjust/log-attachments` +- `GET /business/accounting-adjust/log-export` +- `POST /business/accounting-adjust/log-refund` +- `POST /business/accounting-adjust/log-prestorage` +- `POST /business/accounting-adjust/log-revoke` + +Basis documents: + +- `docs/evidence/rev004-accountlog-action-wiring-notes-2026-04-13.md` +- `docs/evidence/rev004-accountprocess-interface-truth-matrix-2026-04-13.md` + +## Verification + +| Command | Result | +| --- | --- | +| `node --test tests/rev004/accountProcessRealWiring.test.mjs` | PASS (7/7) | +| `node --test tests/rev006/unsoldAdjustmentSubmitPayload.test.mjs tests/rev006/soldAdjustmentSubmit.test.mjs tests/rev006/badDebtBatchSubmitContext.test.mjs` | PASS (29/29) | +| `pnpm build:dev` | PASS | + +## Commits + +``` +5d00f526 test(accountprocess): cover remaining mock wiring gaps +e001f9c0 feat(accountprocess): add account log action APIs +b133fcc5 feat(accountprocess): wire account log refund action +bf763907 feat(accountprocess): wire account log prestore action +a48bb23c feat(accountprocess): wire account log page actions +012fba78 fix(accountprocess): use customer id in sold detail navigation +ebc7bfc3 fix(accountprocess): remove unsold adjustment demo defaults +7b10e414 fix(accountprocess): remove hardcoded price adjustment selectors +``` + +## Result + +- Account log secondary actions no longer show success without a backend call. +- Account log export, process, attachments, and revoke actions call formal account log APIs. +- Account log and sold adjustment customer links use the selected row `custId`. +- Unsold adjustment no longer seeds `111` / `11.1` / `0.9` demo values. +- Price adjustment no longer exposes hardcoded `112` / `测试2` options. + +## Remaining Follow-up + +- `src/views/accountProcess/index.vue` remains a static REV-004 workspace/handoff dashboard backed by `rev004.data.ts`; this is not converted to a live dashboard in this cleanup. diff --git a/docs/evidence/rev004-accounting/rev004-accountprocess-split-adjust-brief-2026-04-14.md b/docs/evidence/rev004-accounting/rev004-accountprocess-split-adjust-brief-2026-04-14.md new file mode 100644 index 0000000..77e4407 --- /dev/null +++ b/docs/evidence/rev004-accounting/rev004-accountprocess-split-adjust-brief-2026-04-14.md @@ -0,0 +1,85 @@ +# REV004 / 分账短版说明(给产品 / 前端)(2026-04-14) + +## 一句话结论 +**分账** 不是退款,也不是减免。 +它的业务含义是: +> 把一笔原账单按规则拆成多笔可独立处理的结果,便于分别收费、分别开票、分别承担。 + +当前 REV004 后端已经支持: +- **发起分账申请** +- **进入待审批** +- **被日志/查询/审批状态承接** + +当前还不支持: +- **审批通过后真正执行拆账,生成多张目标账单** + +--- + +## 当前可以怎么理解 +### 业务上 +老系统分账支持两种方式: +1. **按水量分账** +2. **按费用组成分账** + +它适用于: +- 客户需要开多张发票 +- 客户不能一次缴清 +- 一张账单需要按规则拆给多个结果对象 + +### 后端当前落地到哪里 +当前后端实现的是: +- `SPLIT_ADJUST` 分账申请 +- 提交后状态:`PENDING_APPROVAL` +- 可以查询、留痕、审批承接 + +但还没有做到: +- 真的把一张原账单拆成多张目标账单 +- 真的生成拆分明细 +- 真的进入收费/开票承接执行态 + +--- + +## 为什么还没做到执行态 +因为“真正分账执行”不是普通字段修改,而是一个独立正式业务对象级能力,至少涉及: +- 原账单与目标账单关系 +- 分摊规则 +- 分摊明细 +- 审批通过后的执行流程 +- 执行失败回滚 +- 与收费/开票的后续承接 + +所以当前先落的是: +> **申请态 / 受理态** + +而不是: +> **执行态 / 拆账落地态** + +--- + +## 现在前端该怎么处理 +### 当前前端可以做的 +- 把“分账”当成一种**待审批业务申请**来用 +- 提交后展示: + - `adjustmentNo` + - `resultStatus = PENDING_APPROVAL` + - `approvalStatus = PENDING_APPROVAL` + - `writeBackStatus = PENDING` +- 在日志/列表中查看这笔申请的留痕与状态 + +### 当前前端不要假设的 +- 不要假设提交分账后会立刻生成多张新账单 +- 不要假设已经存在完整的“分账结果明细页”可直接读取目标账单集合 + +--- + +## 如果后续要继续做 +建议后续按这个顺序推进: +1. 明确业务真值:分账结果到底是“多张子账单”为主,还是“多笔待收费结果”为主 +2. 明确数据模型:`SplitAdjust / SplitAdjustDetail` +3. 明确审批后执行:真正拆账、重算、留痕、回看 +4. 再补前端执行态页面 + +--- + +## 当前最适合对外的话术 +> 当前 REV004 已支持“分账申请”的统一受理、审批与查询回看,但尚未落到“审批通过后真正拆账生成多张子账单”的执行态。若后续要继续建设,需要按独立正式业务对象方式展开,而不是把它当成普通账单字段修改处理。 diff --git a/docs/evidence/rev004-accounting/rev004-accountprocess-split-adjust-gap-summary-2026-04-14.md b/docs/evidence/rev004-accounting/rev004-accountprocess-split-adjust-gap-summary-2026-04-14.md new file mode 100644 index 0000000..e457609 --- /dev/null +++ b/docs/evidence/rev004-accounting/rev004-accountprocess-split-adjust-gap-summary-2026-04-14.md @@ -0,0 +1,195 @@ +# REV004 / 分账为什么还没做到执行态(2026-04-14) + +## 1. 目的 +本摘要用于解释: + +为什么当前 `REV004/accountProcess` 后端已经支持 `SPLIT_ADJUST` 分账申请, +但还没有做到“审批通过后真正把一张原账单拆成多张目标账单”的执行态能力。 + +--- + +## 2. 当前结论 +### 结论一句话 +当前后端实现的是: +- **分账申请态** + +尚未实现的是: +- **分账执行态** + +也就是: +- 现在可以提交分账申请、进入待审批、被日志与查询承接; +- 但还没有真正生成多张目标账单、分摊明细和后续收费/开票承接结果。 + +--- + +## 3. 代码证据 +### 3.1 当前入口 +当前分账在 `accountProcess` 中的入口是: +- `POST /admin-api/business/accounting-adjust/unsold-split-submit` + +对应代码: +- `AccountingAdjustProcessServiceImpl.createUnsoldSplit(...)` + +其行为是把分账提交统一转成: +- `objectType = SPLIT_ADJUST` +- `adjustType = SPLIT` + +然后交给统一账务处理入口: +- `chargeService.adjustAccounting(...)` + +### 3.2 当前真正处理逻辑 +在 `ChargeServiceImpl.handleSplitAdjust(...)` 中,当前逻辑只有: +- `approvalRequired = true` +- `resultStatus = PENDING_APPROVAL` +- `approvalStatus = PENDING_APPROVAL` +- `writeBackStatus = PENDING` +- `message = 账单拆分申请已提交,待审批` +- `needUpdate = false` + +这说明: +1. 只受理申请; +2. 不改原账单; +3. 不生成目标账单; +4. 不生成拆分明细; +5. 不进入真正执行态。 + +### 3.3 当前校验逻辑 +当前只做了最小申请校验: +- 仅未收费账单允许发起分账申请 +- `splitCount >= 2` +- `splitCount <= 12` +- 必须填写原因编码 +- 必须填写调整原因 + +这也进一步说明: +- 当前实现重心是“能不能发起分账申请” +- 不是“如何执行真正的分账结果落地” + +--- + +## 4. 业务复杂度为什么高 +真正的分账执行态,不是普通字段修改,而是**结构性重分摊**。 + +### 4.1 文档中的两类策略 +老系统与文档明确支持: +- **按水量分账** +- **按费用组成分账** + +### 4.2 按水量分账需要解决的问题 +- 原账单总水量拆成多笔 +- 拆分水量之和必须等于原水量 +- 拆分后重新按水价重算金额 +- 可能影响违约金、阶梯、费用明细 + +### 4.3 按费用组成分账需要解决的问题 +- 原账单费用项按规则拆分 +- 拆分后金额总额必须与原账单一致 +- 目标账单 / 目标客户 / 金额分摊关系需要明确 +- 费用项粒度如何绑定目标结果也需要独立明细结构 + +### 4.4 执行态至少需要的能力 +若真正落地执行态,后端至少需要: +- 原账单与目标账单关系模型 +- 分摊规则模型 +- 分摊明细模型 +- 审批通过后的执行流程 +- 执行失败回滚 +- 与收费/开票/日志/查询的后续承接 + +因此,这不是“小补丁”能力,而是**独立正式业务对象级别**的建设。 + +--- + +## 5. 文档证据 +### 5.1 需求与手册口径 +文档明确说明: +- 分账是“由一笔账单分成两笔独立账单信息” +- 可按“按水量”“按费用组成”进行分账调整 +- 适用于: + - 客户开多张发票 + - 不能一次缴清等场景 + +这说明业务真值更接近: +- **账单拆分 + 分摊结果重建** + +不是单纯加一条审批记录。 + +### 5.2 REV004 正式对象口径 +`REV004_FULL_ACCOUNTING_DOMAIN_DESIGN.md` 中已将: +- `SplitAdjust` +- `SplitAdjustDetail` + +视为独立正式业务对象,并建议存在: +- `split_adjust_no` +- `split_rule_type` +- `source_charge_id` +- `target_charge_id` +- `target_cust_id` +- `split_amount` +- `split_ratio / split_basis` + +这表明: +- 正式执行态设计方向已经明确; +- 但当前代码还没有真正落成这套模型。 + +### 5.3 文档中的关键冻结判断 +文档还明确给出: +- 当前先冻结设计方向 +- 分账调整后续应补规则表或规则字段组 + +这意味着: +- “申请态先落、执行态后补”是有设计背景的, +- 不是单纯遗漏开发。 + +--- + +## 6. 当前这轮 REV004 的实现目标 +从当前整体 accountProcess 收口策略看,这轮优先解决的是: +- 统一提交入口 +- 统一状态表达 +- 审批边界 +- 日志留痕 +- 查询回看 + +也就是先做到: +- 用户能发起 +- 系统能记录 +- 前端能查看 +- 审批流能承接 + +因此分账也被纳入了这套统一账务调整框架,先实现: +- **申请态可用** + +而没有直接推进到: +- **执行态拆账** + +--- + +## 7. 最终判断 +### 当前已经做到 +- `SPLIT_ADJUST` 已进入统一账务调整对象体系 +- 可提交申请 +- 返回 `PENDING_APPROVAL` +- 可被日志/查询/审批状态承接 + +### 当前还没做到 +- 审批通过后真正生成多张目标账单 +- 原账单与目标账单的主从关系落库 +- 按水量/按费用组成的拆分明细落库 +- 执行态后的收费/开票联动承接 + +### 最准确的一句话 +> 当前 REV004 后端已经实现“分账申请态”,但由于真正的分账执行态涉及分摊规则、目标账单生成、拆分明细、重算与后续收费/开票承接,属于独立正式对象级能力,因此尚未在 `accountProcess` 这一层落地。 + +--- + +## 8. 建议下一步 +如果后续要继续推进“分账执行态”,建议按顺序展开: +1. 先明确业务真值: + - 结果对象到底是多张子账单、还是多笔待收费结果、还是两者同时存在 +2. 再明确数据模型: + - `SplitAdjust` / `SplitAdjustDetail` 主表、明细表、规则字段组 +3. 再明确执行流程: + - 审批通过 -> 拆账执行 -> 重算 -> 留痕 -> 查询回看 +4. 最后补前端: + - 按水量 / 按费用组成 两种弹窗的真实执行态交互 diff --git a/docs/evidence/rev004-accounting/rev004-accountprocess-ui-element-matrix-2026-04-13.md b/docs/evidence/rev004-accounting/rev004-accountprocess-ui-element-matrix-2026-04-13.md new file mode 100644 index 0000000..5fa199c --- /dev/null +++ b/docs/evidence/rev004-accounting/rev004-accountprocess-ui-element-matrix-2026-04-13.md @@ -0,0 +1,250 @@ +# REV004 / accountProcess 页面元素勾稽矩阵(2026-04-13) + +## 目的 +把 `accountProcess` 当前后端真实口径进一步整理成: + +**页面元素 / 弹窗能力 -> 字段 -> 接口 -> 当前证据状态** + +便于: +- 前端逐项对表 +- UAT 做验收勾稽 +- 后端明确哪些已被真实库证实,哪些仍属于页面编排层缺口 + +> 本表基于当前 `water-backend` 代码、Req/RespVO、已落地真实库 canary 测试结果整理。 + +--- + +## 证据状态说明 +- **已真实库验证**:已有真实 PostgreSQL + Spring + MockMvc canary 覆盖 +- **已代码确认**:可从当前 Controller/RespVO/Service 明确确认,但尚未单独做真实库断言 +- **待补证据**:当前还缺更细粒度验证或 UI 编排验证 + +--- + +## 一、预存调整页 + +### A. 列表区 +| 页面元素 | 后端字段 | 接口 | 当前状态 | 说明 | +|---|---|---|---|---| +| 列表记录主键 | `id` | `GET /prestorage-page` | 已真实库验证 | 提交后可回查 detail | +| 调整单号 | `adjustmentNo` | `GET /prestorage-page` | 已真实库验证 | 提交后 page 可见 | +| 客户ID | `custId` | `GET /prestorage-page` | 已代码确认 | Response VO 已定义 | +| 工单状态 | `workOrderStatus` | `GET /prestorage-page` | 已真实库验证 | 已验证提交后为 `2=已完成` | +| 调整类型 | `adjustmentType` | `GET /prestorage-page` | 已代码确认 | page/detail 都有 | +| 客户编号 | `custCode` | `GET /prestorage-page` | 已真实库验证 | `REV004_IT_SRC` 已验证 | +| 目标户号 | `targetCustCode` | `GET /prestorage-page` | 已代码确认 | 转账/转预存场景使用 | +| 客户名称 | `custName` | `GET /prestorage-page` | 已代码确认 | | +| 客户地址 | `custAddress` | `GET /prestorage-page` | 已代码确认 | | +| 调整余额 | `adjustAmount` | `GET /prestorage-page` | 已代码确认 | | +| 期初余额 | `preBalance` | `GET /prestorage-page` | 已代码确认 | | +| 期末余额 | `postBalance` | `GET /prestorage-page` | 已代码确认 | | +| 调整原因 | `adjustReason` | `GET /prestorage-page` | 已代码确认 | | +| 备注 | `remark` | `GET /prestorage-page` | 已代码确认 | | +| 登记时间 | `createTime` | `GET /prestorage-page` | 已代码确认 | | +| 登记人员 | `creatorName` | `GET /prestorage-page` | 已代码确认 | | +| 是否可撤销 | `canRevoke` | `GET /prestorage-page` | 已代码确认 | 撤销能力由状态推导 | +| 是否可查看附件 | `canViewAttachment` | `GET /prestorage-page` | 已代码确认 | | + +### B. 统计区 +| 页面元素 | 后端字段 | 接口 | 当前状态 | 说明 | +|---|---|---|---|---| +| 总条数 | `totalCount` | `GET /prestorage-stat` | 已真实库验证 | | +| 调整余额合计 | `totalAdjustAmount` | `GET /prestorage-stat` | 已代码确认 | | +| 期初余额合计 | `totalPreBalance` | `GET /prestorage-stat` | 已代码确认 | | +| 期末余额合计 | `totalPostBalance` | `GET /prestorage-stat` | 已代码确认 | | +| 预存转账数量 | `transferCount` | `GET /prestorage-stat` | 已真实库验证 | 已验证退款场景下为 0 | +| 预存退款数量 | `refundCount` | `GET /prestorage-stat` | 已真实库验证 | 已验证退款场景下为 1 | + +### C. 提交弹窗 +| 页面元素 | 入参/出参字段 | 接口 | 当前状态 | 说明 | +|---|---|---|---|---| +| 源客户编号 | `custCode` | `POST /prestorage-submit` | 已真实库验证 | | +| 目标户号 | `targetCustCode` | `POST /prestorage-submit` | 已真实库验证 | 转账场景可用;退款场景未单独验证 | +| 退款金额 | `refundAmount` | `POST /prestorage-submit` | 已真实库验证 | | +| 转账金额 | `transferAmount` | `POST /prestorage-submit` | 已代码确认 | 未单独真实库验证 | +| 原因 | `applyReason` | `POST /prestorage-submit` | 已真实库验证 | | +| 备注 | `remark` | `POST /prestorage-submit` | 已真实库验证 | | +| 附件引用 | `attachmentRefs` | `POST /prestorage-submit` | 已代码确认 | 未单独真实库验证 | +| 调整单号回显 | `adjustmentNo` | `POST /prestorage-submit` 返回 | 已真实库验证 | | +| 结果状态 | `resultStatus` | `POST /prestorage-submit` 返回 | 已真实库验证 | `SUCCESS` | +| 回写状态 | `writeBackStatus` | `POST /prestorage-submit` 返回 | 已真实库验证 | `UPDATED` | +| 提示文案 | `msg/message` | `POST /prestorage-submit` 返回 | 已代码确认 | | + +### D. 详情 / 附件 / 流程 / 撤销 +| 页面元素 | 后端字段 | 接口 | 当前状态 | 说明 | +|---|---|---|---|---| +| 详情对象类型 | `objectType` | `GET /prestorage-detail` | 已代码确认 | | +| 详情结果状态 | `resultStatus` | `GET /prestorage-detail` | 已真实库验证 | | +| 详情审批状态 | `approvalStatus` | `GET /prestorage-detail` | 已代码确认 | | +| 详情回写状态 | `writeBackStatus` | `GET /prestorage-detail` | 已真实库验证 | | +| 流程任务ID | `processInstanceId` | `GET /prestorage-detail` | 已代码确认 | | +| 附件引用 | `attachmentRefs` | `GET /prestorage-detail` | 已代码确认 | | +| 查看流程 | `processState/stages[]` | `GET /prestorage-process` | 已代码确认 | 预存页流程接口存在,未单独真实库验证 | +| 查看附件 | `ref/resolved/...` | `GET /prestorage-attachments` | 已代码确认 | 预存页附件接口存在,未单独真实库验证 | +| 撤销动作 | `actionType/resultStatus/writeBackStatus` | `POST /prestorage-revoke` | 已真实库验证 | 余额恢复已验证 | + +--- + +## 二、已销调整页 + +### A. 列表区 +| 页面元素 | 后端字段 | 接口 | 当前状态 | 说明 | +|---|---|---|---|---| +| 账单ID | `id` | `GET /sold-page` | 已真实库验证 | | +| 客户ID | `custId` | `GET /sold-page` | 已代码确认 | | +| 账务年月 | `accountMonth` | `GET /sold-page` | 已代码确认 | | +| 客户编号 | `custCode` | `GET /sold-page` | 已真实库验证 | | +| 客户名称 | `custName` | `GET /sold-page` | 已代码确认 | | +| 客户地址 | `custAddress` | `GET /sold-page` | 已代码确认 | | +| 用水性质 | `waterNature` | `GET /sold-page` | 已代码确认 | | +| 开账水量 | `billedWaterVolume` | `GET /sold-page` | 已代码确认 | | +| 实收金额 | `actualAmount` | `GET /sold-page` | 已真实库验证 | stat 已验证 80.00 | +| 开账金额 | `billedAmount` | `GET /sold-page` | 已代码确认 | | +| 违约金 | `penaltyAmount` | `GET /sold-page` | 已代码确认 | | +| 收费方式 | `collectionMethod` | `GET /sold-page` | 已代码确认 | | +| 收费员 | `collector` | `GET /sold-page` | 已代码确认 | | +| 收费日期 | `collectionDate` | `GET /sold-page` | 已代码确认 | | +| 是否可调整 | `canAdjust` | `GET /sold-page` | 已代码确认 | | +| 是否可批量撤销 | `canBatchRevoke` | `GET /sold-page` | 已真实库验证 | 提交后仍可撤销 | + +### B. 统计区 +| 页面元素 | 后端字段 | 接口 | 当前状态 | 说明 | +|---|---|---|---|---| +| 总条数 | `totalCount` | `GET /sold-stat` | 已真实库验证 | | +| 开账水量合计 | `totalBilledWaterVolume` | `GET /sold-stat` | 已代码确认 | | +| 实收金额合计 | `totalActualAmount` | `GET /sold-stat` | 已真实库验证 | 80.00 | +| 开账金额合计 | `totalBilledAmount` | `GET /sold-stat` | 已代码确认 | | +| 违约金合计 | `totalPenaltyAmount` | `GET /sold-stat` | 已代码确认 | | + +### C. 提交 / 批量撤销 +| 页面元素 | 入参/出参字段 | 接口 | 当前状态 | 说明 | +|---|---|---|---|---| +| 营业账ID | `chargeId` | `POST /sold-submit` | 已真实库验证 | | +| 原因 | `applyReason` | `POST /sold-submit` | 已真实库验证 | | +| 是否红冲发票 | `redInvoice` | `POST /sold-submit` | 已代码确认 | | +| 备注 | `remark` | `POST /sold-submit` | 已真实库验证 | | +| 附件引用 | `attachmentRefs` | `POST /sold-submit` | 已代码确认 | | +| 调整单号 | `adjustmentNo` | `POST /sold-submit` 返回 | 已真实库验证 | | +| 结果状态 | `resultStatus` | `POST /sold-submit` 返回 | 已真实库验证 | `PENDING_APPROVAL` | +| 审批状态 | `approvalStatus` | `POST /sold-submit` 返回 | 已真实库验证 | `PENDING_APPROVAL` | +| 批量撤销入参 | `chargeIds[]` | `POST /sold-batch-revoke` | 已真实库验证 | 不是 `adjustmentNo[]` | +| 批量撤销结果 | `successCount/failCount/items[]` | `POST /sold-batch-revoke` | 已真实库验证 | | + +--- + +## 三、未销调整页 + +### A. 列表区 +| 页面元素 | 后端字段 | 接口 | 当前状态 | 说明 | +|---|---|---|---|---| +| 账单ID | `id` | `GET /unsold-page` | 已代码确认 | | +| 客户ID | `custId` | `GET /unsold-page` | 已代码确认 | | +| 客户编号 | `custCode` | `GET /unsold-page` | 已代码确认 | | +| 客户名称 | `custName` | `GET /unsold-page` | 已代码确认 | | +| 客户地址 | `custAddress` | `GET /unsold-page` | 已代码确认 | | +| 用水性质 | `waterType` | `GET /unsold-page` | 已代码确认 | | +| 账务年月 | `accountMonth` | `GET /unsold-page` | 已代码确认 | | +| 用水量 | `waterVolume` | `GET /unsold-page` | 已代码确认 | | +| 合计金额 | `totalAmount` | `GET /unsold-page` | 已代码确认 | | +| 账单金额 | `billAmount` | `GET /unsold-page` | 已代码确认 | | +| 违约金 | `penaltyAmount` | `GET /unsold-page` | 已代码确认 | | +| 用水费/污水/垃圾/资源税/超定额/季节性 | 对应费用字段 | `GET /unsold-page` | 已代码确认 | | +| 是否可调整 | `canAdjust` | `GET /unsold-page` | 已代码确认 | | +| 是否可分账 | `canSplit` | `GET /unsold-page` | 已代码确认 | | +| 是否可违约金减免 | `canLateFeeReduce` | `GET /unsold-page` | 已代码确认 | | +| 是否可价差调整 | `canPriceDiffAdjust` | `GET /unsold-page` | 已代码确认 | | +| 是否可呆坏账调整 | `canBadDebtAdjust` | `GET /unsold-page` | 已代码确认 | | + +### B. 统计区 +| 页面元素 | 后端字段 | 接口 | 当前状态 | 说明 | +|---|---|---|---|---| +| 用水量合计 | `sumWaterVolume` | `GET /unsold-stat` | 已代码确认 | | +| 合计金额 | `sumTotalAmount` | `GET /unsold-stat` | 已代码确认 | | +| 账单金额 | `sumBillAmount` | `GET /unsold-stat` | 已代码确认 | | +| 违约金 | `sumPenaltyAmount` | `GET /unsold-stat` | 已代码确认 | | +| 费用组成合计 | `sumWaterFee/...` | `GET /unsold-stat` | 已代码确认 | | + +### C. 五类弹窗动作 +| 弹窗 | 关键入参 | 返回口径 | 当前状态 | 说明 | +|---|---|---|---|---| +| 调整 | `chargeId/applyReason/remark/targetBillWater/targetExtendedAmount/targetBillAmount` | `adjustmentNo/resultStatus/writeBackStatus` | 已真实库验证 | AMOUNT happy path 已验证 | +| 分账 | `chargeId/applyReason/remark/splitCount` | `adjustmentNo/objectType/resultStatus=PENDING_APPROVAL` | 已真实库验证 | | +| 违约金减免 | `chargeId/applyReason/remark/lateFeeReduceAmount` | `adjustmentNo/objectType/resultStatus=PENDING_APPROVAL` | 已真实库验证 | | +| 价差调整 | `chargeId/applyReason/remark/priceDiffAmount` | `adjustmentNo/objectType/resultStatus=PENDING_APPROVAL` | 已真实库验证 | | +| 呆坏账 | `chargeId/applyReason/remark/badDebtAmount` | `adjustmentNo/objectType=result BAD_DEBT_RECORD / PENDING_APPROVAL` | 已真实库验证 | | + +--- + +## 四、账务日志页 + +### A. 列表区 +| 页面元素 | 后端字段 | 接口 | 当前状态 | 说明 | +|---|---|---|---|---| +| 日志ID | `id` | `GET /log-page` | 已代码确认 | | +| 调整单号 | `adjustmentNo` | `GET /log-page` | 已真实库验证 | | +| 账务年月 | `accountMonth` | `GET /log-page` | 已代码确认 | | +| 客户ID/编号/名称/地址 | `custId/custCode/custName/custAddress` | `GET /log-page` | 部分已真实库验证 | `custCode` 已验证 | +| 账务类型 | `accountTypeCode/accountType` | `GET /log-page` | 已代码确认 | | +| 处理方式 | `processMethodCode/processMethod` | `GET /log-page` | 已代码确认 | | +| 金额 | `amount` | `GET /log-page` | 已代码确认 | | +| 描述 | `description` | `GET /log-page` | 已代码确认 | | +| 登记人/处理人 | `registrant/handler` | `GET /log-page` | 已代码确认 | | +| 处理时间/创建时间 | `handleTime/createTime` | `GET /log-page` | 已代码确认 | | +| 页面状态 | `statusCode/status` | `GET /log-page` | 已真实库验证 | `SUCCESS` 场景已验证 | +| 目标户号 | `targetCustCode` | `GET /log-page` | 已代码确认 | | +| 原/新预存 | `originalPrestore/newPrestore` | `GET /log-page` | 已代码确认 | | +| 原/新账单 | `originalBill/newBill` | `GET /log-page` | 已代码确认 | | +| 原/新水量 | `originalWaterVolume/newWaterVolume` | `GET /log-page` | 已代码确认 | | +| 原/新违约金 | `originalPenalty/newPenalty` | `GET /log-page` | 已代码确认 | | +| 变化量 | `billChange/waterVolumeChange/penaltyChange` | `GET /log-page` | 已代码确认 | | +| 是否可撤销/退款/转预存 | `canRevoke/canRefund/canPrestore` | `GET /log-page` | 已代码确认 | | + +### B. 统计区 +| 页面元素 | 后端字段 | 接口 | 当前状态 | 说明 | +|---|---|---|---|---| +| 总条数 | `totalCount` | `GET /log-stat` | 已真实库验证 | | +| 调整金额 | `totalAmount` | `GET /log-stat` | 已代码确认 | | +| 调整水量 | `totalWaterVolume` | `GET /log-stat` | 已代码确认 | | +| 已完成数量 | `completedCount` | `GET /log-stat` | 已真实库验证 | | +| 未完成数量 | `pendingCount` | `GET /log-stat` | 已真实库验证 | sold 提交后场景已间接证明 pending | +| 已撤销数量 | `cancelledCount` | `GET /log-stat` | 已代码确认 | | + +### C. 详情 / 流程 / 附件 +| 页面元素 | 后端字段 | 接口 | 当前状态 | 说明 | +|---|---|---|---|---| +| 详情调整单号 | `adjustmentNo` | `GET /log-detail` | 已真实库验证 | | +| 对象类型 | `objectType` | `GET /log-detail` | 已代码确认 | | +| 结果状态 | `resultStatus` | `GET /log-detail` | 已真实库验证 | | +| 审批状态 | `approvalStatus` | `GET /log-detail` | 已代码确认 | | +| 回写状态 | `writeBackStatus` | `GET /log-detail` | 已代码确认 | | +| 原交易流水号 | `originalTranSeq` | `GET /log-detail` | 已真实库验证 | | +| 原系统流水号 | `originalSysTranSeq` | `GET /log-detail` | 已代码确认 | | +| 附件引用 | `attachmentRefs[]` | `GET /log-detail` | 已真实库验证 | | +| 详情明细 | `details[]` | `GET /log-detail` | 已代码确认 | | +| 流程状态 | `processState` | `GET /log-process` | 已真实库验证 | | +| 流程阶段 | `stages[]` | `GET /log-process` | 已代码确认 | | +| 附件原始引用 | `ref` | `GET /log-attachments` | 已真实库验证 | | +| 附件解析状态 | `resolved` | `GET /log-attachments` | 已真实库验证 | | +| 附件元数据 | `id/name/link/size/extension` | `GET /log-attachments` | 已代码确认 | 当前 mock-ref 未解析为真实附件 | + +### D. 日志页二次动作弹窗 +| 弹窗 | 关键入参 | 返回口径 | 当前状态 | 说明 | +|---|---|---|---|---| +| 转退款 | `adjustmentNo/reasonCode/reason` | `adjustmentNo/objectType/resultStatus/writeBackStatus` | 已真实库验证 | 且 bank 后续流水已验证 | +| 转预存 | `adjustmentNo/targetCustCode/reason` | `adjustmentNo/resultStatus` | 已真实库验证 | 目标余额变化已验证 | +| 撤销 | `adjustmentNo/comment` | `actionType/resultStatus/writeBackStatus` | 已真实库验证 | 回滚账单状态/余额已验证 | + +--- + +## 五、当前最适合前端/UAT对表的使用方式 +1. **动作成功后的即时展示**:直接用 `AccountingAdjustRespVO / AccountingAdjustActionRespVO` +2. **页面列表展示**:按页面查各自 `*-page / *-stat` +3. **动作留痕与二次操作**:统一以 `log-*` 视角看 `adjustmentNo` +4. **已销批量撤销特别注意**:当前后端口径是 `chargeIds[]`,不是 `adjustmentNo[]` + +--- + +## 六、仍待补的更细证据 +- `unsold-page / unsold-stat` 的真实库回看断言还未单独补 +- 预存页 `attachments/process` 还未像 log 页一样做完整真实库链路断言 +- 页面元素到字典标签展示(例如名称 label 是否完全满足 UI 文案)还缺单独验收 diff --git a/docs/evidence/rev004-accounting/rev004-accountprocess-ui-orchestration-checklist-2026-04-13.md b/docs/evidence/rev004-accounting/rev004-accountprocess-ui-orchestration-checklist-2026-04-13.md new file mode 100644 index 0000000..afa188c --- /dev/null +++ b/docs/evidence/rev004-accounting/rev004-accountprocess-ui-orchestration-checklist-2026-04-13.md @@ -0,0 +1,222 @@ +# REV004 / accountProcess UI 编排级验收清单(2026-04-13) + +## 1. 目的 +本清单面向前端 / UAT / 联调验收人员,回答: +- 某个页面有哪些核心弹窗/动作入口 +- 提交后应该回看哪些区域/接口 +- 当前这些链路是否已有后端真实库证据支撑 + +> 本清单不替代自动化测试,而是给人工联调 / 验收一份“按页面操作”的顺序脚本。 + +--- + +## 2. 使用说明 +每条清单包含: +- **入口**:从哪个页面/按钮进入 +- **动作**:调哪个后端接口 +- **回看**:操作成功后应检查哪些页面区域 +- **后端证据状态**:当前是否已有真实库证据 + +状态说明: +- **已真实库覆盖**:已有后端集成测试证明主链可运行 +- **已代码确认**:后端接口与字段存在,但尚未专门做该页面编排级回看 + +--- + +## 3. 预存调整页 + +### 场景 P1:预存退款提交 -> 列表/统计/详情回看 +- 入口:预存调整页“预存退款”弹窗 +- 动作接口:`POST /prestorage-submit` +- 提交后应回看: + - 列表:`GET /prestorage-page` + - 统计:`GET /prestorage-stat` + - 详情:`GET /prestorage-detail?id=...` +- 应确认: + - 新 `adjustmentNo` 出现在列表中 + - 工单状态为“已完成” + - `refundCount` 增加 + - detail 中 `resultStatus=SUCCESS` +- 后端证据状态:**已真实库覆盖** + +### 场景 P2:预存退款提交 -> 流程/附件回看 +- 入口:预存调整页提交成功后,点“查看流程 / 查看附件” +- 动作接口: + - `GET /prestorage-process?adjustmentNo=...` + - `GET /prestorage-attachments?adjustmentNo=...` +- 应确认: + - process 可返回 `processState=UPDATED` + - attachments 返回提交时带入的附件引用 +- 后端证据状态:**已真实库覆盖** + +### 场景 P3:预存记录撤销 -> 列表/余额回退 +- 入口:预存调整页列表“撤销”按钮 +- 动作接口:`POST /prestorage-revoke` +- 回看: + - 列表撤销状态 + - 账户余额恢复 + - 关联撤销日志 +- 后端证据状态:**已真实库覆盖** + +### 场景 P4:预存转账提交 +- 入口:预存调整页“预存转账”弹窗 +- 动作接口:`POST /prestorage-submit`(传 `targetCustCode + transferAmount`) +- 回看: + - 列表记录 + - 目标户号 + - 期初/期末余额变化 +- 后端证据状态:**已代码确认 / 部分真实库覆盖** +- 说明:转账字段链路存在,但当前主证据仍以退款场景为主 + +--- + +## 4. 已销调整页 + +### 场景 S1:已销调整提交 -> 已销列表/统计回看 +- 入口:已销调整页“提交”弹窗 +- 动作接口:`POST /sold-submit` +- 回看: + - `GET /sold-page` + - `GET /sold-stat` +- 应确认: + - 原账单仍可见 + - `canBatchRevoke=true` + - 统计金额仍符合账单真值 +- 后端证据状态:**已真实库覆盖** + +### 场景 S2:已销调整提交 -> 日志页留痕回看 +- 入口:已销调整提交成功后,使用返回的 `adjustmentNo` 在日志页查询 +- 动作接口: + - `GET /log-detail?adjustmentNo=...` + - `GET /log-process?adjustmentNo=...` +- 应确认: + - 日志详情存在 + - 状态为待审批 +- 后端证据状态:**已代码确认 / 部分真实库覆盖** +- 说明:已销提交本身和日志链主字段已证实,但“提交后页面跳日志”的 UI 编排尚未专门做一条端到端脚本 + +### 场景 S3:已销批量撤销 +- 入口:已销调整页列表批量勾选 -> “批量撤销” +- 动作接口:`POST /sold-batch-revoke` +- 入参特点:`chargeIds[]` +- 回看: + - 列表可撤销状态变化 + - 撤销日志存在 +- 后端证据状态:**已真实库覆盖** + +--- + +## 5. 未销调整页 + +### 场景 U1:未销调整(金额/水量)提交 -> 列表/统计回看 +- 入口:未销调整页“调整”弹窗 +- 动作接口:`POST /unsold-adjust-submit` +- 回看: + - `GET /unsold-page` + - `GET /unsold-stat` +- 应确认: + - `totalAmount/billAmount` 更新 + - 统计金额同步变化 +- 后端证据状态:**已真实库覆盖** + +### 场景 U2:未销分账提交 +- 入口:未销调整页“分账”弹窗 +- 动作接口:`POST /unsold-split-submit` +- 回看: + - 提交结果为待审批 + - 如页面有日志联动入口,可再看日志留痕 +- 后端证据状态:**已真实库覆盖(动作)** + +### 场景 U3:未销违约金减免提交 +- 入口:未销调整页“违约金减免”弹窗 +- 动作接口:`POST /unsold-late-fee-reduce-submit` +- 回看:提交结果状态 / 待审批标识 +- 后端证据状态:**已真实库覆盖(动作)** + +### 场景 U4:未销价差调整提交 +- 入口:未销调整页“价差调整”弹窗 +- 动作接口:`POST /unsold-price-diff-submit` +- 回看:提交结果状态 / 待审批标识 +- 后端证据状态:**已真实库覆盖(动作)** + +### 场景 U5:未销呆坏账提交 +- 入口:未销调整页“呆坏账调整”弹窗 +- 动作接口:`POST /unsold-bad-debt-submit` +- 回看:提交结果状态 / 待审批标识 +- 后端证据状态:**已真实库覆盖(动作)** + +### 场景 U6:未销查询页初始态 +- 入口:未销调整页默认查询 +- 动作接口: + - `GET /unsold-page` + - `GET /unsold-stat` +- 应确认: + - 初始未销账单金额与违约金展示正确 + - 五类按钮能力显隐正确 +- 后端证据状态:**已真实库覆盖** + +--- + +## 6. 账务日志页 + +### 场景 L1:日志页默认查询 -> page/stat/detail 联动 +- 入口:账务日志页查询 +- 动作接口: + - `GET /log-page` + - `GET /log-stat` + - `GET /log-detail?adjustmentNo=...` +- 应确认: + - 列表、统计、详情三处状态一致 +- 后端证据状态:**已真实库覆盖** + +### 场景 L2:日志页查看流程 / 附件 +- 入口:日志页“查看流程 / 查看附件” +- 动作接口: + - `GET /log-process?adjustmentNo=...` + - `GET /log-attachments?adjustmentNo=...` +- 应确认: + - process 返回阶段与状态摘要 + - attachments 返回引用及解析状态 +- 后端证据状态:**已真实库覆盖** + +### 场景 L3:日志页转退款 +- 入口:日志页“转退款”弹窗 +- 动作接口:`POST /log-refund` +- 回看: + - 日志状态变化 + - 账单收费状态变化 + - bank follow-up 留痕 +- 后端证据状态:**已真实库覆盖** + +### 场景 L4:日志页转预存 +- 入口:日志页“转预存”弹窗 +- 动作接口:`POST /log-prestorage` +- 回看: + - 日志状态变化 + - 目标账户余额变化 + - 可继续查看 process / attachments +- 后端证据状态:**已真实库覆盖** + +### 场景 L5:日志页撤销 +- 入口:日志页“撤销”按钮 +- 动作接口:`POST /log-revoke` +- 回看: + - 原账单支付状态恢复 + - 目标预存余额回退 + - 日志中出现撤销链记录 +- 后端证据状态:**已真实库覆盖** + +--- + +## 7. 当前对前端/UAT最重要的提醒 +1. 已销批量撤销使用 `chargeIds[]`,不要误用 `adjustmentNo[]`。 +2. 日志页所有二次动作统一以 `adjustmentNo` 作为主键。 +3. 未销页五类弹窗“原因”应动态切字典,不要共用一个原因下拉。 +4. 若页面仍显示旧三态文案(如“处理中”),应以后端当前四态真值为准重新对齐。 + +--- + +## 8. 当前仍未通过本清单覆盖的点 +1. 纯 UI 级交互(禁用态、二次确认提示、按钮联动)尚未自动化验证。 +2. 边角筛选条件还未做完整穷尽。 +3. 某些编码字段是否需要前端额外 label 化(如 `waterType`)仍需页面确认。 diff --git a/docs/evidence/rev004-bad-debt-formal-table-dev-db-apply-2026-04-17.md b/docs/evidence/rev004-accounting/rev004-bad-debt-formal-table-dev-db-apply-2026-04-17.md similarity index 100% rename from docs/evidence/rev004-bad-debt-formal-table-dev-db-apply-2026-04-17.md rename to docs/evidence/rev004-accounting/rev004-bad-debt-formal-table-dev-db-apply-2026-04-17.md diff --git a/docs/evidence/rev004-accounting/rev004-latefee-batch-contract-formalization-implementation-2026-04-14.md b/docs/evidence/rev004-accounting/rev004-latefee-batch-contract-formalization-implementation-2026-04-14.md new file mode 100644 index 0000000..f6fc3db --- /dev/null +++ b/docs/evidence/rev004-accounting/rev004-latefee-batch-contract-formalization-implementation-2026-04-14.md @@ -0,0 +1,156 @@ +# REV004 未销违约金减免批量契约补齐实施记录(2026-04-14) + +## 目标 +补齐 `unsold-late-fee-reduce-batch-submit` 的批量 outer 契约,使其能够承接前端页面公共表单字段,并把字段真实透传到后端执行主链,而不是只停留在 controller VO。 + +## 本次实现 +### 1. 批量 outer 契约补齐 +文件: +- `sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/controller/admin/accountingadjust/accountProcess/vo/AccountingAdjustUnsoldLateFeeReduceBatchSubmitReqVO.java` +- `sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/controller/admin/accountingadjust/accountProcess/vo/AccountingAdjustUnsoldLateFeeReduceBatchItemReqVO.java` + +新增 outer 字段: +- `lateFeeType` +- `applicant` +- `contactMobile` +- `applyReason` +- `remark` +- `attachmentRefs` + +明细 item 独立为专用 VO: +- `chargeId` +- `adjustmentNo` +- `applyReason`(兼容旧逐项提交) +- `remark`(兼容旧逐项提交) +- `attachmentRefs`(兼容旧逐项提交) +- `lateFeeReduceAmount` +- `startDate` +- `endDate` + +### 2. 共享 batch 主链承接 outer 字段 +文件: +- `.../AccountingAdjustBatchSubmitReqVO.java` +- `.../AccountingAdjustActionController.java` +- `.../AccountingAdjustProcessServiceImpl.java` + +处理方式: +- controller 先把 late-fee batch outer 字段规范化映射到 generic batch DTO +- process 主链在 `executeBatchSubmit` 中统一执行 outer -> item 合并 +- 统一 batch 主链承接字段: + - `reasonCode` + - `reason` + - `applicant` + - `contactMobile` + - `attachmentRefs` + - `lateFeeType` + +这避免了“专用 VO 上有字段,但 generic batch 主链吃不到”的伪完成。 + +### 3. amount / date 模式校验补齐 +文件: +- `.../AccountingAdjustProcessServiceImpl.java` +- `.../AccountingAdjustReqVO.java` +- `.../ChargeServiceImpl.java` + +规则: +- `lateFeeType=1`(按金额) + - 要求 `lateFeeReduceAmount > 0` + - 不允许同时传 `startDate/endDate` +- `lateFeeType=2`(按日期) + - 要求 `startDate/endDate` 同时存在,且 `endDate >= startDate` + - 不允许同时传 `lateFeeReduceAmount` +- 未显式传 `lateFeeType` 时: + - 若存在日期字段,推导为 `2` + - 否则默认 `1` + +### 4. 执行日志落地字段补齐 +文件: +- `.../AccountingAdjustReqVO.java` +- `.../ChargeServiceImpl.java` + +新增写入 operat log detail 的字段: +- `lateFeeType` +- `applicant` +- `contactMobile` +- `startDate` +- `endDate` + +## 验证结果 +### 编译 +命令: +```bash +mvn -pl sw-business/sw-business-server -DskipTests compile +``` +结果:**PASS** + +### 定向单测 +命令: +```bash +mvn -pl sw-business/sw-business-server \ + -Dtest=AccountingAdjustActionControllerTest#batchCreateUnsoldLateFeeReduce_shouldReturnWrappedSuccess,AccountingAdjustProcessServiceImplTest#createUnsoldLateFeeReduce_shouldPassDateModeFieldsToUnifiedChargeService+createUnsoldLateFeeReduce_shouldRejectMixedAmountAndDateMode+batchCreateUnsoldLateFeeReduce_shouldMergeBatchOuterFieldsIntoItems \ + test +``` +结果:**PASS(4 tests, 0 fail, 0 error)** + +### 真实 DB 定向集成 +命令: +```bash +REV004_IT_DB_URL=jdbc:postgresql://192.168.10.130:5436/sw_system \ +REV004_IT_DB_USERNAME=sw_system \ +REV004_IT_DB_PASSWORD='Em@123456' \ +mvn -pl sw-business/sw-business-server \ + -Dtest=Rev004AccountProcessCanaryQueryIntegrationTest#unsoldLateFeeReduceBatchSubmit_shouldAcceptOuterFieldsAndDateModeContract \ + test +``` +结果:**PASS(1 test, 0 fail, 0 error)** + +集成验证确认: +- batch outer 字段可提交 +- `lateFeeType=2` date-mode 契约可进入主链 +- operat log detail 中可看到: + - `lateFeeType=2` + - `applicant` + - `contactMobile` + - `startDate` + - `endDate` + - `attachmentRefs` + +## 当前边界与剩余风险 +1. **本轮重点是“提交契约 + 主链承接 + 日志落地”**。 +2. `lateFeeType=2` 的“按日期执行态/审批回写态”尚未展开为完整金额计算逻辑;当前已确保申请态与提交链路可用。 +3. 由于仓库当前还存在其他在制改动,本轮只做了定向验证,没有把整个相关测试类全部拉绿。 + +## 结论 +本轮已完成 REV004 未销违约金减免批量提交接口的主契约补齐,并把前端页面公共字段正式落到共享 batch 主链与日志记录中;可以支撑前端继续联调“按金额/按日期”两种提交形态。 + +## 追加收口(读模型展示字段) +### 本轮补齐 +- `AccountingAdjustDetailRespVO` 新增: + - `lateFeeType` + - `applicant` + - `contactMobile` + - `startDate` + - `endDate` +- `AccountingAdjustLogDetailRespVO` 新增同名字段 +- `AccountingAdjustProcessRespVO` 新增: + - `reasonCode` + - `attachmentRefs` + - `lateFeeType` + - `applicant` + - `contactMobile` + - `startDate` + - `endDate` + +### 读取链路 +- `AccountingAdjustQueryServiceImpl`:从 operat log detail 读取 late-fee 扩展字段并映射到 detail response +- `AccountingAdjustLogProcessServiceImpl`:从 request/action log detail 读取 late-fee 扩展字段并映射到 log-detail response +- `AccountingAdjustProcessServiceImpl#getProcess`:从 unified snapshot 读取并投影到 process response + +### 追加验证 +#### 定向读模型单测 +```bash +mvn -pl sw-business/sw-business-server \ + -Dtest=AccountingAdjustQueryServiceImplTest,AccountingAdjustLogProcessServiceImplTest,AccountingAdjustProcessServiceImplTest#getProcess_shouldExposeLateFeeDisplayFieldsFromUnifiedSnapshot \ + test +``` +结果:**PASS(7 tests, 0 fail, 0 error)** diff --git a/docs/evidence/rev004-accounting/rev004-latefee-daily-rule-confirmation-2026-04-15.md b/docs/evidence/rev004-accounting/rev004-latefee-daily-rule-confirmation-2026-04-15.md new file mode 100644 index 0000000..a22d842 --- /dev/null +++ b/docs/evidence/rev004-accounting/rev004-latefee-daily-rule-confirmation-2026-04-15.md @@ -0,0 +1,84 @@ +# REV004 违约金规则确认(2026-04-15) + +## 结论 +当前后续实现应以以下业务规则作为真值: + +> **违约金 = 欠缴水费金额 × 0.1‰ × 逾期天数** + +该规则意味着: +- **按日计收**,不是按月滚动 +- 计算基数是**欠缴水费金额** +- **不含违约金本身** +- **不得利滚利** + +## 业务前提 +违约金产生需满足: +1. 逾期未缴 +2. 经供水单位通知后仍未缴 + +## 对 REV004 的实现影响 +### 1. 计算模型 +后续 `late-fee reduce` 的设计与实现,应以“按日计收”模型展开,而不是“按月滚动”模型。 + +### 2. date-mode 减免理解 +`lateFeeType=2`(按日期)应理解为: +- 对指定日期区间内对应的逾期天数区间做减免 +- 先计算该区间理论应收违约金 +- 再形成: + - `lateFeeBefore` + - `reduceAmount` + - `lateFeeAfter` + +### 3. 需要补齐/确认的系统要素 +除现有: +- `lateFeeBeginDate` +- `lateFee` +- `penaltyCoefficient` + +还应确认或补齐: +- 欠缴本金 +- 通知状态 / 通知时间 +- 逾期起算日 +- 逾期天数 +- 上限规则(如部分地区 30%) +- 60 日后续处置边界 + +## 与当前仓库现状的关系 +### 当前已确认存在的模型字段 +- `ChargeDO.lateFeeBeginDate` +- `ChargeDO.lateFee` +- `CostComponentDO.penaltyCoefficient` + +### 当前未确认存在的现成实现 +仓库中尚未确认存在: +- 明确的“按日计收违约金”统一计算器 +- 明确的“按日期区间重算违约金”统一服务 + +因此,当前应将该规则视为: +- **业务规则真值输入** +- 后续需要据此补正式实现 + +## 使用建议 +后续 PRD / 设计稿 / 代码实现,不建议再使用“按月滚动”表述;应统一表述为: + +> **按日计收、按区间减免、按期累计结果** + + +## 追加确认(2026-04-15) +### 系数来源模型 +已进一步确认: +- 逐项重算违约金时,系数来源为 `CostComponentDO.penaltyCoefficient`。 +- 取数链路为:`ChargeDetailDO.costComponentCode -> CostComponentDO.code -> penaltyCoefficient`。 + +### 参与计算范围 +- 所有未缴费用项都参与。 +- 不收违约金的费用项,不做额外白名单过滤,而是通过 `penaltyCoefficient = 0` 自然贡献 0。 + +### 汇总口径 +- 每个费用项先单独计算违约金; +- 每项先四舍五入到分; +- 最后再求和。 + +### 当前仓库状态 +- 已确认存在上述模型链路; +- 但尚未发现现成“逐项按日期重算违约金”的统一实现。 diff --git a/docs/evidence/rev004-latefee-formal-table-db-blocker-2026-04-15.md b/docs/evidence/rev004-accounting/rev004-latefee-formal-table-db-blocker-2026-04-15.md similarity index 100% rename from docs/evidence/rev004-latefee-formal-table-db-blocker-2026-04-15.md rename to docs/evidence/rev004-accounting/rev004-latefee-formal-table-db-blocker-2026-04-15.md diff --git a/docs/evidence/rev004-accounting/rev004-latefee-formal-table-deploy-sql-2026-04-15.md b/docs/evidence/rev004-accounting/rev004-latefee-formal-table-deploy-sql-2026-04-15.md new file mode 100644 index 0000000..9c77473 --- /dev/null +++ b/docs/evidence/rev004-accounting/rev004-latefee-formal-table-deploy-sql-2026-04-15.md @@ -0,0 +1,27 @@ +# REV004 late-fee formal table 部署 SQL 说明(2026-04-15) + +## 新增脚本 +- `sql/rev004/REV004_latefee_formal_tables_deploy.sql` + +## 作用 +为 late-fee reduce 的新 formal table 提供单独部署脚本,覆盖: +- `biz_latefee_reduce` +- `biz_latefee_reduce_detail` +- 对应 sequence +- 主键 / 唯一索引 / 常用索引 +- 明细表外键 + +## 适用场景 +1. 测试库 / 联调库先补表 +2. 为真实 DB canary 排除“缺表”阻塞 +3. 为后续 formal-table 路线提供独立部署入口 + +## 注意事项 +- 当前脚本按 PostgreSQL / 测试环境风格编写 +- 若正式环境不是 PostgreSQL,需先做方言适配 +- 此脚本只覆盖 late-fee 两张表,不包含坏账 / 核销 / 价差等对象 + +## 建议使用顺序 +1. 先在目标库执行 `REV004_latefee_formal_tables_deploy.sql` +2. 再重跑 late-fee date-mode canary +3. 若通过,再考虑推广 formal-table 到其他对象 diff --git a/docs/evidence/rev004-latefee-formal-table-dev-db-apply-2026-04-15.md b/docs/evidence/rev004-accounting/rev004-latefee-formal-table-dev-db-apply-2026-04-15.md similarity index 100% rename from docs/evidence/rev004-latefee-formal-table-dev-db-apply-2026-04-15.md rename to docs/evidence/rev004-accounting/rev004-latefee-formal-table-dev-db-apply-2026-04-15.md diff --git a/docs/evidence/rev004-accounting/rev004-latefee-legacy-structure-gap-summary-2026-04-14.md b/docs/evidence/rev004-accounting/rev004-latefee-legacy-structure-gap-summary-2026-04-14.md new file mode 100644 index 0000000..dd195e5 --- /dev/null +++ b/docs/evidence/rev004-accounting/rev004-latefee-legacy-structure-gap-summary-2026-04-14.md @@ -0,0 +1,122 @@ +# REV004 违约金减免:现结构与老字典差异摘要(2026-04-14) + +## 结论 +当前 REV004 违约金减免结构已经对齐老字典/老表结构的核心骨架: +- `LateFeeType` 仍保持 `1=按金额 / 2=按日期` +- 已承接申请人、联系电话、备注 +- 已承接 `StartDate/EndDate` +- 已承接账单维度 `chargeId(FeeId)` + +但当前更偏**申请契约 + 日志/读模型承接**,并未完整复刻老系统执行态表模型。 + +## 老字典/老表结构证据 +### 主表 `PM_LATEFEE_RECORDS` +来源:`营收数据字典.md:3117-3126` +- `Applicant` +- `Mobile` +- `ApplyType` +- `LateFeeType` +- `State` +- `Remark` +- `TaskId` +- `StepId` +- `FlowRemark` +- `BusinessType` + +### 明细表 `PM_LATEFEE_RECORD_DETAILS` +来源:`营收数据字典.md:3143-3158` +- `CustId/CustCode/CustName/CustAddress` +- `BillMonth` +- `LateFee` +- `ReduceMoney` +- `NewLateFee` +- `StartDate` +- `EndDate` +- `ProcType/ProcPerson/ProcDate/ProcRemark` +- `State` +- `FeeId` + +### 老字典枚举 +来源:`营收数据字典.md:5683-5697` +- `LateFeeReason`: `1=用户协商`, `2=其它` +- `LateFeeType`: `1=按金额`, `2=按日期` + +## 当前结构证据 +### DDL 草案 +来源:`sql/rev004/REV004_accounting_adjustments_ddl.sql:289-403` +- 主表 `biz_latefee_reduce` + - `applicant_name` + - `applicant_mobile` + - `late_fee_type` + - `apply_reason_code` + - `remark` + - `approval_status` + - `reduce_status` +- 明细表 `biz_latefee_reduce_detail` + - `charge_id` + - `cust_id/cust_code/cust_name/cust_address` + - `bill_month` + - `start_date/end_date` + - `late_fee_before` + - `reduce_amount` + - `late_fee_after` + - `proc_type/proc_person/proc_time/proc_remark` + +### 当前批量提交契约 +来源: +- `AccountingAdjustUnsoldLateFeeReduceBatchSubmitReqVO` +- `AccountingAdjustUnsoldLateFeeReduceBatchItemReqVO` + +当前 outer: +- `lateFeeType` +- `applicant` +- `contactMobile` +- `applyReason` +- `remark` +- `attachmentRefs` +- `items` + +当前 item: +- `chargeId` +- `adjustmentNo` +- `lateFeeReduceAmount` +- `startDate` +- `endDate` +- 兼容项:`applyReason/remark/attachmentRefs` + +## 已对齐项 +1. `LateFeeType` 语义已对齐老字典 +2. `Applicant/Mobile` 已有对应字段 +3. `Remark` 已有对应字段 +4. `StartDate/EndDate` 已有对应字段 +5. `FeeId -> chargeId` 已有明确对应 +6. `ReduceMoney -> lateFeeReduceAmount/reduce_amount` 语义已对齐 +7. detail / log-detail / process 已可读出 late-fee 扩展字段 + +## 未完全落地项 +1. **ApplyType / LateFeeReason 字典口径未完全统一** + - 老字典:`1=用户协商, 2=其它` + - 当前前端历史口径曾使用不同原因值 +2. **State 未按老系统单字段口径落地** + - 当前主要使用 `approvalStatus/resultStatus/writeBackStatus` +3. **按日期模式仍偏申请态** + - 还未形成完整审批执行/计算回写 +4. **执行结果落表未完整 runtime 化** + - DDL 草案已具备 `late_fee_before/reduce_amount/late_fee_after` + - 但当前核心还是契约 + 日志承接 +5. **处理过程字段未完整 runtime 落地** + - `ProcType/ProcPerson/ProcDate/ProcRemark` +6. **老流程字段未完整复刻** + - `StepId/FlowRemark/BusinessType` + +## 优先级建议 +### P0 +- 统一 `applyReason` 与 `LateFeeReason` 口径 +- 给出老 `State` 与当前审批/回写状态映射表 + +### P1 +- 补齐 `lateFeeType=2` 按日期模式执行态 +- 审批通过后把结果正式落到 `biz_latefee_reduce / biz_latefee_reduce_detail` + +### P2 +- 再决定是否需要复刻 `StepId/FlowRemark/BusinessType/applicant_id` diff --git a/docs/evidence/rev004-accounting/rev004-prestorage-bpm-db-apply-2026-04-24.md b/docs/evidence/rev004-accounting/rev004-prestorage-bpm-db-apply-2026-04-24.md new file mode 100644 index 0000000..c834fc2 --- /dev/null +++ b/docs/evidence/rev004-accounting/rev004-prestorage-bpm-db-apply-2026-04-24.md @@ -0,0 +1,119 @@ +# REV004 prestorage BPM 字段已应用到 application-dev 测试库(2026-04-24) + +## 目标库 +依据: +- `sw-business/sw-business-server/src/main/resources/application-dev.yaml` + +解析结果: +- Host:`192.168.10.130` +- Port:`5436` +- DB:`sw_system` +- User:`sw_system` + +## 本次目的 +在既有 `biz_prestorage_adjust` / `biz_prestorage_adjust_detail` formal-table 基础上,补齐“保存即提审 / BPM 回写”所需的主表字段与索引。 + +## 实际执行 +执行增量 DDL: +- `ALTER TABLE biz_prestorage_adjust ADD COLUMN IF NOT EXISTS ...` +- 新增索引: + - `idx_biz_prestorage_adjust_process_instance` + - `idx_biz_prestorage_adjust_business_status` + - `idx_biz_prestorage_adjust_business_key` + +同步更新本地脚本: +- `sql/rev004/REV004_prestorage_formal_tables_deploy.sql` + +## 已补字段 +- `business_status` +- `approval_result` +- `approval_comment` +- `execution_status` +- `execution_message` +- `approved_at` +- `rejected_at` +- `cancelled_at` +- `rolled_back_at` +- `process_instance_id` +- `process_definition_key` +- `business_key` +- `current_task_id` +- `current_task_name` + +## 回读校验 +### 字段回读 +已确认上述 14 个字段均已存在于: +- `public.biz_prestorage_adjust` + +### 索引回读 +已确认以下索引存在: +- `idx_biz_prestorage_adjust_process_instance` +- `idx_biz_prestorage_adjust_business_status` +- `idx_biz_prestorage_adjust_business_key` + +## DB smoke +在测试库中开启事务,插入一条带 BPM 字段的 `biz_prestorage_adjust` 记录并回读,随后回滚。 + +验证结果: +- 插入成功 +- `business_status=IN_APPROVAL` +- `approval_status=PROCESSING` +- `execution_status=PENDING` +- `process_instance_id=PI-SMOKE-001` +- `current_task_name=预存调整审批` +- 回滚后 `left_count=0` + +结果:**PASS** + +## 当前结论 +`application-dev` 指向的测试库已经具备 REV004 prestorage BPM 接线所需的数据库字段基础,可以继续进行: +1. 保存即发起 BPM +2. 审批回写业务状态 +3. 审批中改类型重启流程 +4. 审批中撤销终止流程 + +## 当前仍未覆盖 +1. 真实 BPM 流程定义 `prestorage_adjust` 是否已在环境中部署,尚未验证; +2. 真实业务服务 + 真实 BPM 流程实例联调尚未完成; +3. 本次仅完成数据库结构到位与最小 smoke。 + +## 补充复核(2026-04-24 11:05 +08:00) +### 1. 部署脚本幂等重放 +再次执行: +```bash +PGPASSWORD='Em@123456' \ +psql -h 192.168.10.130 -p 5436 -U sw_system -d sw_system \ + -v ON_ERROR_STOP=1 \ + -f sql/rev004/REV004_prestorage_formal_tables_deploy.sql +``` + +结果:**PASS** + +关键现象: +- 已存在 sequence / table / index 均以 `already exists, skipping` 跳过; +- 已存在 BPM 字段均以 `column ... already exists, skipping` 跳过; +- 脚本可重复执行,不会因本次增量字段而破坏既有库结构。 + +### 2. 相关模块回归测试 +执行: +```bash +mvn -pl sw-business/sw-business-server,sw-module-bpm/sw-module-bpm-server -am \ + -Dtest=AccountingAdjustProcessServiceImplTest,PrestorageBpmBridgeServiceTest,PrestorageBpmCallbackServiceTest,BpmPrestorageAdjustStatusListenerTest \ + -Dsurefire.failIfNoSpecifiedTests=false test +``` + +结果:**BUILD SUCCESS** + +测试汇总: +- `AccountingAdjustProcessServiceImplTest`:27 通过 +- `PrestorageBpmBridgeServiceTest`:2 通过 +- `PrestorageBpmCallbackServiceTest`:3 通过 +- `BpmPrestorageAdjustStatusListenerTest`:1 通过 +- 合计:**32/32 通过** + +## 最新结论 +截至 2026-04-24 11:05 +08:00: +1. 测试库 BPM 字段已补齐; +2. 部署脚本可幂等重放; +3. 预存 BPM 相关业务/BPM 单测已通过; +4. 仍待真实 BPM 流程定义与真实流程实例联调验证。 diff --git a/docs/evidence/rev004-accounting/rev004-prestorage-bpm-deployed-integration-check-2026-04-24.md b/docs/evidence/rev004-accounting/rev004-prestorage-bpm-deployed-integration-check-2026-04-24.md new file mode 100644 index 0000000..7e8b048 --- /dev/null +++ b/docs/evidence/rev004-accounting/rev004-prestorage-bpm-deployed-integration-check-2026-04-24.md @@ -0,0 +1,70 @@ +# REV004 prestorage BPM 部署后集成检查(2026-04-24) + +## 环境 +- 主机:`root@192.168.10.130` +- 数据库:`jdbc:postgresql://192.168.10.130:5436/sw_system` +- 参考配置: + - `sw-business/sw-business-server/src/main/resources/application-dev.yaml` + - `sw-gateway/src/main/resources/application-dev.yaml` + +## 检查目标 +验证部署后的 REV004 预存调整 BPM 接口是否可通过网关/业务服务完成真实 HTTP 集成测试。 + +## 运行态探测 +### 容器状态 +- `sw-gateway`: Up +- `sw-module-bpm`: Up +- `sw-business-server`: `Up (health: starting)`,且 `RestartCount=7` + +### 端口 +- 网关:`48080` +- 业务服务映射:`48081 -> container 48090` + +## HTTP 实测 +### 1. 网关健康 +`GET http://127.0.0.1:48080/actuator/health` +- 返回:`{"status":"UP"}` +- 结果:PASS + +### 2. 网关预存接口 +`GET /admin-api/business/accounting-adjust/prestorage-page` +- 未登录:`401 账号未登录` +- 使用 `Authorization: emsoft1` 仍返回 `401` +- 结论:网关侧不支持直接使用 business 服务的 mock token 调测 + +### 3. 业务服务预存接口 +`GET http://127.0.0.1:48081/admin-api/business/accounting-adjust/prestorage-page?pageNo=1&pageSize=1` +- `Authorization: emsoft1, tenant-id:0`:返回 `500 系统异常` +- `Authorization: emsoft1, tenant-id:1`:返回 `404 请求地址不存在` + +## 日志根因 +`docker logs sw-business-server` 明确显示: +- Spring 启动失败点:`Error creating bean with name 'accountingAdjustActionController': Injection of resource dependencies failed` +- 最终失败原因: + - `A component required a bean of type 'cn.com.emsoft.sw.module.bpm.api.task.BpmProcessInstanceApi' that could not be found.` + +## 结论 +当前 **不是接口联调数据问题**,而是 **部署后的 business 服务启动失败 / controller 未成功装配**,因此无法继续完成真实接口集成测试。 + +## 影响判断 +本次预存 BPM 变更不仅修改了 business 模块,也修改了 BPM 相关模块: +- `sw-module-bpm-api/.../BpmProcessInstanceApi.java` +- `sw-module-bpm-api/.../dto/BpmProcessInstanceCancelReqDTO.java` +- `sw-module-bpm-server/.../BpmProcessInstanceApiImpl.java` +- `sw-module-bpm-server/.../RpcConfiguration.java` +- `sw-module-bpm-server/.../BpmPrestorageAdjustStatusListener.java` + +因此若仅更新 `sw-business-server`,或 `sw-module-bpm` 未按同版本一并部署,就会出现当前缺少 `BpmProcessInstanceApi` Bean 的启动失败。 + +## 建议下一步 +1. 同版本重新部署: + - `sw-business-server` + - `sw-module-bpm` +2. 部署后先验证: + - `sw-business-server` 健康状态变为 healthy / restart count 停止增长 + - 业务服务日志不再出现 `BpmProcessInstanceApi` 缺失 +3. 然后再执行预存 BPM 真实 HTTP 集成测试: + - save 即提审 + - page/detail/process 查询 + - revoke + - BPM 审批回写链路 diff --git a/docs/evidence/rev004-prestorage-formal-table-dev-db-apply-2026-04-16.md b/docs/evidence/rev004-accounting/rev004-prestorage-formal-table-dev-db-apply-2026-04-16.md similarity index 100% rename from docs/evidence/rev004-prestorage-formal-table-dev-db-apply-2026-04-16.md rename to docs/evidence/rev004-accounting/rev004-prestorage-formal-table-dev-db-apply-2026-04-16.md diff --git a/docs/evidence/rev004-accounting/rev004-prestorage-strict-formal-first-2026-04-17.md b/docs/evidence/rev004-accounting/rev004-prestorage-strict-formal-first-2026-04-17.md new file mode 100644 index 0000000..440cc4a --- /dev/null +++ b/docs/evidence/rev004-accounting/rev004-prestorage-strict-formal-first-2026-04-17.md @@ -0,0 +1,94 @@ +# REV004 prestorage process/attachments strict formal-first(2026-04-17) + +## 目标 +收口: +- `GET /admin-api/business/accounting-adjust/prestorage-process` +- `GET /admin-api/business/accounting-adjust/prestorage-attachments` + +使其优先读取 prestorage formal-table,而不是继续主要依赖 legacy/unified fallback。 + +## 代码变更 +核心变更位于: +- `AccountingAdjustProcessServiceImpl` +- `AccountingAdjustProcessServiceImplTest` + +策略: +1. `getProcess(adjustmentNo)` 先尝试 `PrestorageFormalizationService.getView(adjustmentNo)` +2. 命中 formal view 时,直接组装 `AccountingAdjustProcessRespVO` +3. `getAttachments(adjustmentNo)` 先尝试读取 formal `attachmentRefs` +4. 仅在 formal 不存在时才回退到 synthetic / unified 口径 + +## 验证 +### compile +```bash +mvn -pl sw-business/sw-business-server -DskipTests compile +``` +结果:**PASS** + +### targeted tests +```bash +mvn -pl sw-business/sw-business-server -Dtest=AccountingAdjustProcessServiceImplTest,AccountingAdjustPrestorageProcessServiceImplTest test +``` +结果:**PASS** +- Tests run: 23 +- Failures: 0 +- Errors: 0 + +## fresh jar smoke(port 48098) +### health +- `GET /actuator/health` -> `{"status":"UP"}` + +### smoke 数据 +手工 seed: +- `adjustmentNo = REV004-PTR-993001-SEED` +- formal main:`biz_prestorage_adjust` +- formal detail:`biz_prestorage_adjust_detail` +- attachment refs:`101,proof-raw` + +### process +调用: +- `GET /admin-api/business/accounting-adjust/prestorage-process?adjustmentNo=REV004-PTR-993001-SEED` + +结果:**PASS** +返回关键字段: +- `objectType = LEGACY_PRESTORAGE_TRANSFER` +- `adjustType = TRANSFER` +- `actionAmount = 20.0` +- `resultStatus = SUCCESS` +- `approvalStatus = NOT_REQUIRED` +- `writeBackStatus = UPDATED` +- `attachmentRefs = ["101", "proof-raw"]` +- `applicant = 王五` +- `contactMobile = 13700000000` +- `latestMessage = 预存转账成功,目标户号=C-993002` + +说明:process 已命中 formal main,而不是再走 unified detail 兜底。 + +### attachments +调用: +- `GET /admin-api/business/accounting-adjust/prestorage-attachments?adjustmentNo=REV004-PTR-993001-SEED` + +结果:**PASS** +返回: +- ref=`101` -> 数值 ID 解析,当前附件实体不存在,返回 `resolved=false, message=附件不存在` +- ref=`proof-raw` -> 非数值引用,返回 `resolved=false, message=附件引用不是数值ID,保留原始引用` + +说明:attachments 已优先读取 formal `attachmentRefs`,并保留现有解析策略。 + +## 清理 +已删除: +- `biz_prestorage_adjust / detail` seed 数据 + +回读结果: +- `prestorage_main_left=0` +- `prestorage_detail_left=0` + +运行态: +- `48098` 已停止 + +## 当前结论 +本轮 prestorage 剩余查询缺口已完成 strict formal-first 收口: +1. `prestorage-process` 优先命中 formal +2. `prestorage-attachments` 优先命中 formal attachment refs +3. formal 缺失时仍可继续 fallback +4. 主链路 schema / 写路径无变更 diff --git a/docs/evidence/rev004-accounting/rev004-prestorage-submit-dev-call-2026-04-23.md b/docs/evidence/rev004-accounting/rev004-prestorage-submit-dev-call-2026-04-23.md new file mode 100644 index 0000000..be02e75 --- /dev/null +++ b/docs/evidence/rev004-accounting/rev004-prestorage-submit-dev-call-2026-04-23.md @@ -0,0 +1,119 @@ +# REV004 预存调整 prestorage-submit 开发环境调用记录(2026-04-23) + +- 验证日期:2026-04-23 +- 后端仓基线:`21714d64822268d8dcb7cd1296656b4c19ff95fa` +- 前端仓基线:`d2698e1f5d107422f64928086d89d4b803cd12ae` +- 目标环境:`root@192.168.10.130` +- 服务端口:`sw-gateway -> 127.0.0.1:48080`,`sw-business-server -> 127.0.0.1:48090` +- 配置依据: + - `water-backend/sw-gateway/src/main/resources/application-dev.yaml` + - `water-backend/sw-business/sw-business-server/src/main/resources/application-dev.yaml` +- 鉴权方式:开发环境 `sw.security.mock-enable=true`,使用 `Authorization: Bearer emsoft1` + `tenant-id: 1` + +## 1. 实际调用 payload + +```json +{ + "applicant": "李四", + "applyReason": "充值错误", + "attachmentRefs": [], + "contactMobile": "19928382738", + "custCode": "26041011111", + "refundAmount": 2, + "remark": "ssa" +} +``` + +## 2. 实际调用命令 + +### 2.1 直连 business + +```bash +curl -X POST 'http://127.0.0.1:48090/admin-api/business/accounting-adjust/prestorage-submit' \ + -H 'Authorization: Bearer emsoft1' \ + -H 'tenant-id: 1' \ + -H 'Content-Type: application/json' \ + --data '{"applicant":"李四","applyReason":"充值错误","attachmentRefs":[],"contactMobile":"19928382738","custCode":"26041011111","refundAmount":2,"remark":"ssa"}' +``` + +### 2.2 走 gateway + +```bash +curl -X POST 'http://127.0.0.1:48080/admin-api/business/accounting-adjust/prestorage-submit' \ + -H 'Authorization: Bearer emsoft1' \ + -H 'tenant-id: 1' \ + -H 'Content-Type: application/json' \ + --data '{"applicant":"李四","applyReason":"充值错误","attachmentRefs":[],"contactMobile":"19928382738","custCode":"26041011111","refundAmount":2,"remark":"ssa"}' +``` + +## 3. 调用结果 + +直连 business 与走 gateway 返回一致: + +```json +{"code":500,"data":null,"msg":"系统异常"} +``` + +## 4. 后端日志根因 + +`sw-business-server` 日志显示真实异常为: + +```text +java.lang.IllegalArgumentException: 账户预存余额不足 +at cn.com.emsoft.sw.business.service.accountingadjust.accountProcess.AccountingAdjustProcessServiceImpl.createPrestorageAction(AccountingAdjustProcessServiceImpl.java:213) +``` + +对应代码位置: + +- `water-backend/sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/service/accountingadjust/accountProcess/AccountingAdjustProcessServiceImpl.java` + +关键逻辑: + +- 读取客户与账户 +- 将 `deposit == null` 视为 `0` +- 校验 `deposit < refundAmount` 时抛出 `IllegalArgumentException("账户预存余额不足")` + +## 5. 数据库核验 + +开发库(`sw_system`)中当前客户与账户数据: + +```sql +select id, code, name, population, address, status, tenant_id +from biz_cust +where deleted = 0 and code = '26041011111'; + +select id, cust_id, deposit, uncheck_money, overdraft, status, deleted, tenant_id +from biz_account +where cust_id = 67 and deleted = 0; +``` + +结果: + +```text +biz_cust: +67 | 26041011111 | liao | 3 | 11 | 0 | 1 + +biz_account: +65 | 67 | null | null | 0.0000 | 0 | 0 | 1 +``` + +结论:当前测试客户 `26041011111` 的 `biz_account.deposit` 为空,业务侧按 `0` 处理,因此退款金额 `2` 会命中“账户预存余额不足”。 + +## 6. 结论 + +本次 `prestorage-submit` 调用链路本身可达,鉴权可用,接口也已命中后端业务逻辑。 +失败原因不是网关/路由/权限,而是当前测试数据不满足退款校验条件: + +- 客户存在 +- 账户存在 +- 账户预存余额为空(按 0 处理) +- `refundAmount = 2`,因此提交失败 + +## 7. 后续建议 + +二选一: + +1. 修正该测试客户的 `biz_account.deposit`,使其大于等于 `2` +2. 改用当前开发库中预存余额充足的客户进行 `prestorage-submit` 联调 + +附带观察:当前前端收到的是泛化后的 `系统异常`,而非后端真实业务提示 `账户预存余额不足`。如果需要提升联调效率,可后续评估是否将该类参数/业务校验异常以明确业务消息返回前端。 diff --git a/docs/evidence/rev004-accounting/rev004-price-diff-formal-table-dev-db-apply-2026-04-17.md b/docs/evidence/rev004-accounting/rev004-price-diff-formal-table-dev-db-apply-2026-04-17.md new file mode 100644 index 0000000..783a5ef --- /dev/null +++ b/docs/evidence/rev004-accounting/rev004-price-diff-formal-table-dev-db-apply-2026-04-17.md @@ -0,0 +1,135 @@ +# REV004 price-diff formal-table 已应用到 application-dev 测试库(2026-04-17) + +## 目标库 +依据: +- `sw-business/sw-business-server/src/main/resources/application-dev.yaml` + +解析结果: +- Host:`192.168.10.130` +- Port:`5436` +- DB:`sw_system` +- User:`sw_system` + +## 已执行脚本 +- `sql/rev004/REV004_price_diff_formal_tables_deploy.sql` + +## DDL 执行结果 +结果:**PASS** + +已确认存在: +- `biz_price_diff_adjust` +- `biz_price_diff_adjust_detail` +- `biz_price_diff_adjust_seq` +- `biz_price_diff_adjust_detail_seq` + +已确认幂等重放通过: +- second apply 输出 `already exists, skipping` +- 无重复约束/重复索引异常 + +## 代码验证 +### compile +```bash +mvn -pl sw-business/sw-business-server -DskipTests compile +``` +结果:**PASS** + +说明: +- 先顺手修复 develop 基线 compile blocker: + - `CustApiImpl.java` 去掉 `updateCustPriceTemplateCode` 上多余 `@Override` + - `CustServiceImpl.java` 去掉 `dept.getCode()` 调用 +- 之后串行重跑 compile 成功 +- 曾出现一次 `NoSuchFileException ... target/generated-sources/...`,确认为 compile 与 test 并行访问同一 `target/` 目录导致的竞态,不属于业务代码错误 + +### targeted tests +```bash +mvn -pl sw-business/sw-business-server -Dtest=AccountingAdjustActionServiceImplTest,AccountingAdjustProcessServiceImplTest,AccountingAdjustQueryServiceImplTest,PriceDiffFormalizationServiceTest test +``` +结果:**PASS** +- Tests run: 43 +- Failures: 0 +- Errors: 0 + +## HTTP smoke(fresh jar, port 48095) +### health +- `GET /actuator/health` -> `{"status":"UP"}` + +### submit +- `unsold-price-diff-submit` on charge `992205` -> `REV004-992205-20260417153413` +- `unsold-price-diff-submit` on charge `992206` -> `REV004-992206-20260417153414` +- 返回统一为: + - `objectType = PRICE_DIFF_ADJUST` + - `approvalStatus = PENDING_APPROVAL` + - `resultStatus = PENDING_APPROVAL` + - `writeBackStatus = PENDING` + +### get / page +- `GET /admin-api/business/accounting-adjust/get?adjustmentNo=REV004-992205-20260417153413` + - 可返回 formal detail: + - `priceDiffAmount=15.50` + - `billAmountBefore=100.00` + - `billAmountAfter=115.50` + - `extendedAmountBefore=100.00` + - `extendedAmountAfter=115.50` +- `GET /admin-api/business/accounting-adjust/page?...objectType=PRICE_DIFF_ADJUST` + - 可返回 2 条 fresh smoke formal-first 记录 + - `reasonCodeLabel` 已能解析为字典文本(如 `用户协商` / `定价错误`) + +### approve / reject +- approve:`/admin-api/business/accounting-adjust/approve` + - 返回 `APPROVED / SUCCESS / UPDATED` +- reject:`/admin-api/business/accounting-adjust/reject` + - 返回 `REJECTED / FAIL / SKIPPED` + +## DB 回读 +`biz_price_diff_adjust`: +- `REV004-992205-20260417153413 -> APPROVED | UPDATED | SUCCESS` +- `REV004-992206-20260417153414 -> REJECTED | SKIPPED | FAIL` + +`biz_price_diff_adjust_detail`: +- approve 明细:`SUCCESS | APPROVE_EXECUTE | approve price diff smoke` +- reject 明细:`REJECTED | REJECT | reject price diff smoke` +- approve 样例金额前后值: + - `bill_amount_before=100.00 -> bill_amount_after=115.50` + - `extended_amount_before=100.00 -> extended_amount_after=115.50` + +`biz_charge`: +- `992205 -> bill_amount=115.5000, extended_amount=115.5000, original_money=115.5000` +- `992206 -> bill_amount=80.0000, extended_amount=80.0000, original_money=80.0000` + +## 测试数据清理 +smoke 完成后已删除: +- `biz_operat_log / detail`(identify_value = `992205`, `992206`) +- `biz_price_diff_adjust / detail` +- `biz_charge`(`992205`, `992206`) +- `biz_cust`(`REV004_PD_SMOKE_A`, `REV004_PD_SMOKE_B`) + +回读结果: +- `pricediff_main_left=0` +- `pricediff_detail_left=0` +- `operat_log_left=0` +- `charge_left=0` +- `cust_left=0` + +## 运行态清理 +用于 fresh-jar HTTP smoke 的临时实例: +- port `48095` + +已停止,当前无残留 LISTEN 进程。 + +## 当前结论 +本轮 price-diff formal-table 已达到: +1. DDL 可落库且可幂等重放; +2. unsold price-diff submit 能落 pending formal main/detail; +3. approve/reject 会同步 formal 状态; +4. detail/page 对 `PRICE_DIFF_ADJUST` 已能返回 formal-first 结果; +5. 账单回写与当前 `applyPriceDiffWriteBack(...)` 口径一致; +6. fresh smoke / cleanup 证据完整。 + +## 当前仍需收口 +- 这批尚未提交 commit / PR; +- 如果后续要更贴近原系统 `PM_PRICE_RECORDS / DETAILS` 语义,可继续补: + - `PriceListId` + - `PriceCode` + - `IsLadder` + - `NewFeeId` + - 更细颗粒的 old/new late fee 与账单差额字段来源收口。 diff --git a/docs/evidence/rev004-accounting/rev004-redink-formal-table-dev-db-apply-2026-04-17.md b/docs/evidence/rev004-accounting/rev004-redink-formal-table-dev-db-apply-2026-04-17.md new file mode 100644 index 0000000..bd4737c --- /dev/null +++ b/docs/evidence/rev004-accounting/rev004-redink-formal-table-dev-db-apply-2026-04-17.md @@ -0,0 +1,212 @@ +# REV004 redink formal-table 已应用到 application-dev 测试库(2026-04-17) + +## 目标库 +依据: +- `sw-business/sw-business-server/src/main/resources/application-dev.yaml` + +解析结果: +- Host:`192.168.10.130` +- Port:`5436` +- DB:`sw_system` +- User:`sw_system` + +## 已执行脚本 +- `sql/rev004/REV004_redink_formal_tables_deploy.sql` + +## DDL 执行结果 +结果:**PASS** + +已确认存在: +- `biz_redink_record` +- `biz_redink_record_detail` +- `biz_redink_record_seq` +- `biz_redink_record_detail_seq` + +已确认幂等重放通过: +- second apply 输出 existing/skip 结果 +- 本轮顺手把 sequence 创建方式从 `CREATE SEQUENCE IF NOT EXISTS` 收口为显式 `pg_class` 检查,规避 replay 时 sequence 级重复键异常 + +## 代码验证 +### compile +```bash +mvn -pl sw-business/sw-business-server -DskipTests compile +``` +结果:**PASS** + +### targeted tests +```bash +mvn -pl sw-business/sw-business-server -Dtest=ChargeServiceAccountingAdjustTest,AccountingAdjustQueryServiceImplTest,RedinkFormalizationServiceTest test +``` +结果:**PASS** +- Tests run: 34 +- Failures: 0 +- Errors: 0 + +## fresh query smoke(fresh jar, port 48096) +### health +- `GET /actuator/health` -> `{"status":"UP"}` + +### smoke 方式说明 +REDINK_RECORD 当前依赖原交易定位 / bank follow-up 逻辑;本轮先采用: +1. application-dev 手工 seed 一条 redink formal 主表/明细表记录; +2. fresh jar 验证 `get/page` 是否已 formal-first 命中; +3. 不在本轮直接伪造 live bank follow-up 交易。 + +### seed 记录 +- `adjustmentNo = REV004-RI-992305-SEED` +- `chargeId = 992305` +- formal 主表状态: + - `approvalStatus = NOT_REQUIRED` + - `executeStatus = UPDATED` + - `resultStatus = SUCCESS` +- bank follow-up 样例:`BK-992305` + +### get / page +- `GET /admin-api/business/accounting-adjust/get?adjustmentNo=REV004-RI-992305-SEED` + - 返回: + - `objectType = REDINK_RECORD` + - `resultStatus = SUCCESS` + - `approvalStatus = NOT_REQUIRED` + - `writeBackStatus = UPDATED` + - `originalTranSeq = T-992305` + - `originalSysTranSeq = SYS-992305` + - detail 中包含: + - `bankTranSeq` + - `redinkAmount` + - `payStateBefore` + - `payStateAfter` +- `GET /admin-api/business/accounting-adjust/page?...objectType=REDINK_RECORD` + - 返回 1 条 formal-first 记录 + - `reasonCodeLabel` 已能解析为字典文本(如 `收费错误`) + +## 当前结论 +本轮 redink formal-table 已达到: +1. DDL 可落库且可幂等重放; +2. 结果型 formal-table 主从表已建模; +3. query detail/page 对 `REDINK_RECORD` 已能返回 formal-first; +4. compile / targeted tests 通过; +5. fresh jar query smoke 已验证 formal-first 查询链路可用。 + +## 当前仍未完全覆盖 +- 尚未完成“真实 redink 执行成功后自动落 formal 结果”的 live HTTP smoke; +- 原因是当前红冲依赖原交易与 bank follow-up 外部链路,需要在下一轮补真实可复现数据后再做完整 execute smoke。 + +## 测试数据清理 +已删除: +- `biz_redink_record / detail` +- `biz_charge` +- `biz_cust` + +回读结果: +- `redink_main_left=0` +- `redink_detail_left=0` +- `charge_left=0` +- `cust_left=0` + +## 运行态清理 +用于 fresh-jar query smoke 的临时实例: +- port `48096` + +已停止,当前无残留 LISTEN 进程。 + +## live execute smoke 阻塞证据(2026-04-17 16:50 +08:00) +本轮额外尝试了真实 redink 执行链路: +- fresh jar:`48097` +- 请求:`POST /admin-api/business/charge/accounting-adjust` +- `objectType = REDINK_RECORD` +- `chargeId = 992306` +- `originalTranSeq = T-REDINK-NOPE` + +接口响应: +```json +{"code":500,"data":null,"msg":"系统异常"} +``` + +从应用日志定位到的精确异常: +- `FeignException$ServiceUnavailable: [503]` +- `Load balancer does not contain an instance for the service business-bank-server` +- 失败位置:`TransactionApi#getTransactionByTranSeq(...)` + +结论: +- 当前 live execute smoke 未能完成的直接原因是 **外部依赖 `business-bank-server` 在当前环境无可用实例**; +- 这不是 redink formal-table 本身的 DDL / 查询接线问题。 + +因此本批已完成: +- compile +- targeted tests +- DDL apply / replay +- fresh query smoke + +但“真实 redink 执行成功后自动落 formal”的端到端 smoke 仍需在 `business-bank-server` 可用时补跑。 + + +## live execute smoke 成功补证(2026-04-17 17:51 +08:00) +在本轮额外启动本地 `business-bank-server`(dev profile, port `48092`)并向测试库预置原交易后,重新完成了 REDINK_RECORD 的真实端到端执行 smoke。 + +### 前置 +- 本地启动 `business-bank-server`,并成功注册到 Nacos dev:`business-bank-server 192.168.9.109:48092 register finished` +- 向 `bk_transaction` seed 原交易: + - `tran_seq = T-REDINK-NOPE` + - `sys_tran_seq = SYS-REDINK-NOPE` + - `tran_type = PAY` + - `status = SUCCESS` + - `contract_no = 992306` + - `amount = 12000` +- 准备已收费营业账:`chargeId = 992306` + +### execute 请求 +`POST /admin-api/business/charge/accounting-adjust` +```json +{ + "chargeId": 992306, + "objectType": "REDINK_RECORD", + "reasonCode": "1", + "reason": "redink execute smoke", + "originalTranSeq": "T-REDINK-NOPE" +} +``` + +### execute 响应 +结果:**PASS** + +返回: +- `adjustmentNo = REV004-992306-20260417175109` +- `objectType = REDINK_RECORD` +- `resultStatus = SUCCESS` +- `approvalStatus = NOT_REQUIRED` +- `writeBackStatus = UPDATED` +- `message = 冲正处理成功,bank流水号=RV9923062026041717511073C805` + +### DB 回读 +`biz_redink_record`: +- `adjustment_no = REV004-992306-20260417175109` +- `approval_status = NOT_REQUIRED` +- `execute_status = UPDATED` +- `result_status = SUCCESS` +- `bank_tran_seq = RV9923062026041717511073C805` +- `original_tran_seq = T-REDINK-NOPE` + +`biz_redink_record_detail`: +- `detail_status = SUCCESS` +- `proc_type = EXECUTE` +- `pay_state_before = 1` +- `pay_state_after = 0` +- `redink_amount = 120.00` + +`biz_charge`: +- `pay_state = 0` +- 支付信息已清空为红冲后的未收费态 + +`bk_transaction`: +- 原交易 `T-REDINK-NOPE` 状态变为 `REVERSED` +- 新增 follow-up: + - `tran_seq = RV9923062026041717511073C805` + - `tran_type = PAY_INVALID` + - `status = SUCCESS` + - `original_tran_seq = T-REDINK-NOPE` + +### 查询回读 +- `GET /admin-api/business/accounting-adjust/get?adjustmentNo=REV004-992306-20260417175109` -> formal-first 返回成功 +- `GET /admin-api/business/accounting-adjust/page?...objectType=REDINK_RECORD` -> formal-first 返回成功 + +说明:至此,REDINK_RECORD 已补齐“真实执行 -> 自动落 formal -> formal-first 查询”的完整闭环证据。 diff --git a/docs/evidence/rev004-accounting/rev004-split-adjust-current-state-comparison-summary-2026-04-14.md b/docs/evidence/rev004-accounting/rev004-split-adjust-current-state-comparison-summary-2026-04-14.md new file mode 100644 index 0000000..f88d959 --- /dev/null +++ b/docs/evidence/rev004-accounting/rev004-split-adjust-current-state-comparison-summary-2026-04-14.md @@ -0,0 +1,224 @@ +# REV004 / 分账现状对照摘要(2026-04-14) + +## 1. 目的 +本摘要用于把 **旧设计**、**老数据字典**、**当前代码状态** 三者放在一起,对“分账(SplitAdjust)”给出一页式结论,回答: +- 旧系统/旧设计里的分账到底是什么 +- 当前 REV004 设计里把它定位成什么 +- 当前后端代码做到哪一步了 +- 三者之间的差距到底在哪里 + +--- + +## 2. 一句话结论 +> **旧系统里的分账是“真正的账单拆分/重分摊业务对象”,有汇总表、明细表和拆分后的结果对象;当前 REV004 设计也把它定义为独立正式对象,但当前后端代码只落到了“分账申请态”,还没有落到“审批通过后真正拆账生成子账单”的执行态。** + +--- + +## 3. 旧设计口径(12_REV_Detailed.md) +来源: +- `../water-docs/docs/design/02_Detailed_Design/12_REV_Detailed.md` + +### 旧设计里怎么定义分账 +文档明确把: +- `SplitAdjust` +列为: +- **目标正式业务对象** +- 并且属于: + - **L2 独立业务层** + +### 旧设计里的关键语义 +文档明确写到: +- `SplitAdjust | 分账调整 | 当前作为费用组成重分摊场景表达 | 支持按水量 / 按费用组成等分摊策略` + +并在迁移补充里写到: +- **分账调整汇总 / 明细** +- 承接方式: + - 在线主模型 + 费用重分摊场景 +- 需要保留: + - 原分摊结果 + - 调整后结果 + - 策略类型 + - 责任链 + +### 从旧设计可得的结论 +旧设计的分账不是普通字段修改,也不是一条审批备注,而是: +- 有独立业务语义 +- 有汇总/明细层 +- 有原结果与新结果的前后对照 +- 有策略与责任链 + +--- + +## 4. 老数据字典口径(营收数据字典.md) +来源: +- `../water-docs/docs/design/04_Appendix/Archive/05_Data_Dictionary/营收数据字典.md` + +### 老系统真实表结构 +#### 4.1 汇总表 +- `PM_SEPARATE_RECORDS` + +关键字段: +- `Applicant` +- `Mobile` +- `ApplyType` +- `SeparateType` +- `State` +- `Remark` +- `TaskId` +- `StepId` +- `FlowRemark` +- `BusinessType` + +#### 4.2 明细表 +- `PM_SEPARATE_RECORD_DETAILS` + +关键字段: +- `SeparateRecordId` +- `CustId / CustCode / CustName / CustAddress` +- `FeeId` +- `NewFeeId` +- `BillMonth` +- `BillWater / NewBillWater` +- `LateFee / NewLateFee` +- `BillAmount / NewBillAmount` +- `ExtendedAmount / NewExtendedAmount` +- `ItemStr` +- `ProcType / ProcPerson / ProcDate / ProcRemark` +- `State` + +### 从老数据字典可得的结论 +老系统里的分账已经明显是**执行态对象**,因为它不只是有申请信息,还已经有: +- 原费用对象:`FeeId` +- 新产生对象:`NewFeeId` +- 原水量 / 分账水量 +- 原金额 / 新金额 +- 原滞纳金 / 新滞纳金 +- 费用组成 + +也就是说,老系统分账不是“申请单”,而是: +> **有申请、有明细、有拆后结果对象的完整业务表族。** + +--- + +## 5. 当前代码状态 +来源: +- `sw-business/sw-business-server/src/main/java/.../AccountingAdjustProcessServiceImpl.java` +- `sw-business/sw-business-server/src/main/java/.../ChargeServiceImpl.java` + +### 当前入口 +当前分账提交入口: +- `POST /admin-api/business/accounting-adjust/unsold-split-submit` + +调用路径: +- `AccountingAdjustProcessServiceImpl.createUnsoldSplit(...)` +- 转成统一账务调整: + - `objectType = SPLIT_ADJUST` + - `adjustType = SPLIT` +- 进入 `chargeService.adjustAccounting(...)` + +### 当前真正处理逻辑 +在 `ChargeServiceImpl.handleSplitAdjust(...)` 中,只做了: +- `approvalRequired = true` +- `resultStatus = PENDING_APPROVAL` +- `approvalStatus = PENDING_APPROVAL` +- `writeBackStatus = PENDING` +- `message = 账单拆分申请已提交,待审批` +- `needUpdate = false` + +### 当前校验逻辑 +只校验: +- 原账单必须未收费 +- `splitCount >= 2` +- `splitCount <= 12` +- 必须填写原因编码 +- 必须填写调整原因 + +### 从当前代码可得的结论 +当前代码实现的是: +- **分账申请态** + +没有做到: +- 生成分账主表/明细表 +- 生成目标账单 +- 回填新账单 ID +- 原账单失效/已拆分标记 +- 执行态回看 + +--- + +## 6. 三者对照 + +| 对照维度 | 旧设计 | 老数据字典 | 当前代码 | +|---|---|---|---| +| 是否独立对象 | 是,`SplitAdjust` | 是,汇总表+明细表 | 语义上是,代码上仍挂统一入口 | +| 是否支持按水量 / 按费用组成 | 是 | 是(`SeparateType`) | 申请态支持对象类型,但未落执行规则 | +| 是否有汇总表 | 有方向 | 有真实表 | 当前没有真实表落地 | +| 是否有明细表 | 有方向 | 有真实表 | 当前没有真实表落地 | +| 是否有“原对象 -> 新对象”关系 | 有方向 | 有(`FeeId -> NewFeeId`) | 没有 | +| 是否有拆前拆后水量/金额 | 有方向 | 有 | 没有执行态数据 | +| 是否只到审批申请 | 否 | 否 | 是 | +| 是否真正生成子账单 | 应该要 | 已有新费用ID表达 | 当前未实现 | + +--- + +## 7. 当前最大的差距 +最核心的差距不是“少几个字段”,而是: + +### 旧系统 / 旧设计的分账 +是: +- **完整业务对象** +- **有结果承接** +- **有拆后对象** + +### 当前 REV004 代码的分账 +只是: +- **申请态入口** +- **待审批状态表达** +- **统一日志/查询承接** + +所以差距本质上是: +> **从“受理态”到“执行态”的整层能力还没有落。** + +--- + +## 8. 为什么会停在这里 +结合三者判断,原因可以归纳成: +1. 当前这轮 REV004 后端优先目标是统一入口、状态、日志、查询,不是重建所有独立执行对象。 +2. 真正分账执行涉及: + - 分摊规则 + - 主表/明细表 + - 目标账单生成 + - 守恒校验 + - 收费/开票承接 +3. 因此当前才先落成: + - `SPLIT_ADJUST` 申请态 + +而没有一步到位落成: +- `SplitAdjust` 执行态。 + +--- + +## 9. 最终判断 +### 业务真值 +分账本质上是: +- **账单拆分 / 重分摊** +- 不是退款 +- 不是减免 +- 也不只是审批单 + +### 当前状态 +当前 REV004: +- 已经把“分账”纳入正式对象语义 +- 但后端实现仍停在申请态 + +### 最适合对外讲的一句话 +> 旧系统与旧设计里的分账本来就是“有汇总、有明细、有拆后结果对象”的正式业务对象;当前 REV004 后端只先落了统一申请与审批承接,没有把真正的拆账执行态一起落出来,所以它现在更像“分账申请”,还不是“已执行的分账对象”。 + +--- + +## 10. 建议下一步 +若要继续推进分账执行态,建议: +1. 以老表结构 + 旧设计为真值来源,先冻结最小执行态模型 +2. 先做按水量分账 MVP +3. 再扩按费用组成分账 +4. 最后补前端执行态页面与回看能力 diff --git a/docs/evidence/rev004-accounting/rev004-split-adjust-execution-design-draft-2026-04-14.md b/docs/evidence/rev004-accounting/rev004-split-adjust-execution-design-draft-2026-04-14.md new file mode 100644 index 0000000..f051bc8 --- /dev/null +++ b/docs/evidence/rev004-accounting/rev004-split-adjust-execution-design-draft-2026-04-14.md @@ -0,0 +1,246 @@ +# REV004 / 分账执行态后端设计草案(2026-04-14) + +## 1. 目标 +在当前“分账申请态”基础上,补齐“审批通过后真正执行拆账”的后端能力,使系统可以: +- 将一笔原始未收费账单拆成多笔目标账单 +- 支持两类分账策略: + - 按水量分账 + - 按费用组成分账 +- 保证金额/水量守恒、状态可追踪、失败可回滚 +- 被后续收费、开票、日志、查询完整承接 + +--- + +## 2. 当前现状 +### 已有 +- 统一对象类型:`SPLIT_ADJUST` +- 统一提交入口:`unsold-split-submit` +- 当前结果:`PENDING_APPROVAL` +- 已有原因、审批、日志、查询承接能力 + +### 缺失 +- 审批通过后的执行器 +- 分账主表/明细表落库 +- 目标账单生成 +- 原账单与目标账单关系链 +- 按水量/按费用组成的规则明细 +- 执行态查询回看 + +--- + +## 3. 设计原则 +1. **先审批、后执行**:分账执行必须挂在审批通过之后,不在申请提交时直接拆账。 +2. **守恒原则**: + - 按水量分账:子账单水量之和 = 原账单水量 + - 按费用组成分账:子账单金额之和 = 原账单金额 +3. **原账单可追溯**:必须保留原账单与所有目标账单关系。 +4. **执行幂等**:同一分账单不得重复执行。 +5. **失败可回滚**:执行中任一步失败,必须整体回滚。 +6. **查询可回看**:日志页/分账页必须能看到申请、审批、执行结果、目标账单明细。 + +--- + +## 4. 结果对象建议 +### 最终业务真值 +建议以: +- **多张目标子账单** +为正式业务真值; +- “多笔待收费结果”只是前台呈现视角。 + +### 原因 +- 文档原始语义就是“由一笔账单分成两笔独立账单信息” +- 后续还要支持分别收费、分别开票、分别承担 +- 若没有目标账单实体,后续业务承接会变得模糊 + +--- + +## 5. 数据模型草案 + +### 5.1 主表:`biz_split_adjust` +建议字段: +- `id` +- `split_adjust_no`:分账单号 +- `source_charge_id`:原账单 ID +- `split_rule_type`:分账规则类型(`BY_WATER` / `BY_COMPONENT`) +- `reason_code` +- `remark` +- `approval_status` +- `execute_status`:`PENDING / PROCESSING / SUCCESS / FAIL` +- `execute_message` +- `executed_at` +- `accounting_case_id`(如继续挂统一骨架) +- 通用审计字段 + +### 5.2 明细表:`biz_split_adjust_detail` +建议字段: +- `id` +- `split_adjust_id` +- `seq_no` +- `target_cust_id` / `target_cust_code`(若允许拆给不同客户) +- `target_charge_id`(执行后生成) +- `split_basis`:拆分依据描述 +- `split_ratio` +- `split_water` +- `split_amount` +- `component_code`(按费用组成分账时必填) +- `component_amount` +- `status` +- 通用审计字段 + +### 5.3 与现有 `biz_charge` 的关系 +- 原账单:`source_charge_id` +- 子账单:执行后在 `biz_charge` 新增多条记录 +- 子账单增加来源追踪字段(建议二选一): + - `source_charge_id` + - 或 `split_adjust_id` + +建议至少有一个能让后续查询直接知道: +> 这张账单是由哪次分账生成的。 + +--- + +## 6. 执行流程草案 + +### Phase 1:申请提交 +接口:`POST /unsold-split-submit` +- 校验未收费、`splitCount`、原因等 +- 保存申请主单/明细草稿(如果前端已能提供拆分明细) +- 状态置为 `PENDING_APPROVAL` + +> 若当前前端还没有真正提交拆分明细,只是申请头信息,则需在后续补充“审批前明细维护”或“审批时确认明细”能力。 + +### Phase 2:审批通过 +触发点:审批系统回调/人工审批通过 +- 校验该分账单仍未执行 +- 锁定原账单 +- 进入执行事务 + +### Phase 3:执行拆账 +#### 3.1 按水量分账 +- 读取原账单水量、单价/模板/费用构成 +- 根据各子项 `split_water` 重新计算子账单金额 +- 生成 N 条目标账单 +- 校验: + - `sum(split_water) = source.bill_water` + - `sum(target.bill_amount)` 与可接受计算误差范围内守恒 + +#### 3.2 按费用组成分账 +- 读取原账单明细 `biz_charge_detail` +- 按费用项将金额拆入不同子账单 +- 汇总生成 N 条目标账单及其明细 +- 校验: + - 各费用项总额守恒 + - 原账单总金额守恒 + +### Phase 4:收尾 +- 原账单标记为: + - 已拆分 / 已失效 / 不可继续收费(建议新增状态或来源标识) +- 分账主单置为 `SUCCESS` +- 明细回填 `target_charge_id` +- 写 operat_log / 业务日志 / 查询投影 + +### Phase 5:失败回滚 +- 任一步失败:回滚事务 +- 主单置 `FAIL` +- 保留失败原因 +- 不产生部分子账单残留 + +--- + +## 7. 接口草案 + +### 7.1 申请接口(保留) +- `POST /unsold-split-submit` + +### 7.2 明细查询接口(建议新增) +- `GET /split-adjust-detail?adjustmentNo=...` +- 返回: + - 原账单摘要 + - 分账规则类型 + - 子项明细 + - 目标账单(若已执行) + +### 7.3 明细维护接口(建议新增,若前端需要) +- `POST /split-adjust-draft-save` +- 在审批前保存: + - 按水量拆分行 + - 按费用组成拆分行 + +### 7.4 审批通过执行接口(内部) +- `POST /internal/split-adjust/execute` +- 由审批流或业务服务调用,不暴露给前端 + +### 7.5 查询接口增强(建议) +- `log-detail` / `log-process` + - 增加目标账单摘要 +- `unsold-page` + - 原账单若已提交分账且审批中/已执行,要有能力位变化提示 + +--- + +## 8. 状态机建议 +### 申请主单状态 +- `PENDING_APPROVAL` +- `APPROVED_PENDING_EXECUTE` +- `PROCESSING` +- `SUCCESS` +- `FAIL` +- `REVOKED`(如审批前允许撤销) + +### 原账单状态建议 +原账单不建议简单删除,建议新增可追溯状态: +- `UNPAID` +- `SPLIT_PENDING` +- `SPLIT_DONE` +- `SPLIT_INVALIDATED` + +若不想改老字段,可用额外来源标记字段表达。 + +--- + +## 9. 与前端配合建议 +### 前端最少补充信息 +若要真正进入执行态,前端弹窗至少要能提交: +- 分账方式:按水量 / 按费用组成 +- 子项列表 + - 按水量:每笔 `split_water` + - 按费用组成:每笔目标费用项/金额归属 +- 申请人 / 联系电话 / 原因 / 备注 + +### 前端结果回看 +执行态落地后,前端需要新增: +- 原账单 -> 目标账单列表 +- 子账单金额/水量/费用项明细 +- 分账执行结果与失败原因 + +--- + +## 10. 分阶段落地建议 +### 第一阶段(最小闭环) +目标:审批通过后真正生成子账单,但先只支持**按水量分账** +- 优先原因: + - 规则相对更直观 + - 守恒约束明确 + - 更容易先做闭环 + +### 第二阶段 +扩展支持:**按费用组成分账** +- 需要补足 `biz_charge_detail` 级别重分摊能力 + +### 第三阶段 +增强: +- 目标客户维度分账 +- 更复杂的规则模板 +- 开票/收费联动优化查询 + +--- + +## 11. 最终建议 +若项目要正式推进“分账执行态”,建议: +1. 先把 **按水量分账** 做成最小执行闭环 +2. 明确 `biz_split_adjust` / `biz_split_adjust_detail` 模型 +3. 把审批通过后的执行器作为独立服务落地 +4. 再补按费用组成的二阶段能力 + +一句话: +> 不建议继续在当前“统一 adjustAccounting 申请态”里硬塞执行逻辑,而应把 `SplitAdjust` 升级成独立正式业务对象来建设。 diff --git a/docs/evidence/rev004-accounting/rev004-split-adjust-formalization-implementation-2026-04-14.md b/docs/evidence/rev004-accounting/rev004-split-adjust-formalization-implementation-2026-04-14.md new file mode 100644 index 0000000..d88f948 --- /dev/null +++ b/docs/evidence/rev004-accounting/rev004-split-adjust-formalization-implementation-2026-04-14.md @@ -0,0 +1,108 @@ +# REV004 / split-adjust formalization + dedicated interfaces evidence(2026-04-14) + +## 1. 本轮实现范围 +- 保持旧接口兼容: + - `POST /admin-api/business/accounting-adjust/unsold-split-submit` + - `GET /admin-api/business/accounting-adjust/get` + - `GET /admin-api/business/accounting-adjust/log-detail` +- 新增 split 专属接口族: + - `POST /admin-api/business/split-adjust/submit` + - `GET /admin-api/business/split-adjust/page` + - `GET /admin-api/business/split-adjust/detail` + - `GET /admin-api/business/split-adjust/result` +- split 执行真值升级为: + - `splitItems[{seqNo, splitWater}]` +- `splitCount` 作为兼容口径保留,并在旧入口适配阶段转译为 `splitItems` + +## 2. 本轮代码落点 +### 新增 +- `sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/controller/admin/splitadjust/SplitAdjustController.java` +- `.../controller/admin/splitadjust/vo/SplitAdjustSubmitReqVO.java` +- `.../controller/admin/splitadjust/vo/SplitAdjustSubmitRespVO.java` +- `.../controller/admin/splitadjust/vo/SplitAdjustDetailRespVO.java` +- `.../controller/admin/splitadjust/vo/SplitAdjustPageReqVO.java` +- `.../controller/admin/splitadjust/vo/SplitAdjustPageRespVO.java` +- `.../service/splitadjust/SplitAdjustService.java` +- `.../service/splitadjust/SplitAdjustServiceImpl.java` + +### 继续增强 +- `SplitAdjustFormalizationService` +- `AccountingAdjustActionServiceImpl` +- `AccountingAdjustProcessServiceImpl` +- `AccountingAdjustLogProcessServiceImpl` +- `AccountingAdjustDetailRespVO` +- `AccountingAdjustLogDetailRespVO` +- `ChargeDO` +- `sql/rev004/REV004_accounting_adjustments_ddl.sql` +- `Rev004AccountProcessCanaryQueryIntegrationTest` +- `AccountingAdjustActionServiceImplTest` +- `Rev004AccountProcessLiveDbReadinessTest` +- `sql/rev004/accountprocess/00_reset.sql` + +## 3. 关键实现结论 +1. 新 split submit 入口已经支持显式 `splitItems[{seqNo, splitWater}]` +2. `splitItems` 成为 formal 明细真值,审批通过执行会按明细水量比例分配子账单金额/水量 +3. 旧 `unsold-split-submit` 已兼容接入新 split 主链,可直接传 `splitItems` +4. 新增 split 专属 detail/result/page 接口 +5. 旧 `log-detail` 对新 split 专属单据也可 fallback 回看 +6. `biz_charge` 已承接最小追溯字段: + - `source_charge_id` + - `split_adjust_id` + - `charge_origin_type` + - `split_status` + +## 4. 验证命令与结果 +### 4.1 编译 +```bash +mvn -pl sw-business/sw-business-server -DskipTests compile +``` +结果:PASS + +### 4.2 targeted tests(阶段一) +```bash +REV004_IT_DB_URL='jdbc:postgresql://192.168.10.130:5436/sw_system' \ +REV004_IT_DB_USERNAME='sw_system' \ +REV004_IT_DB_PASSWORD='Em@123456' \ +mvn -pl sw-business/sw-business-server \ + -Dtest=Rev004AccountProcessCanaryQueryIntegrationTest#splitAdjustSubmit_shouldAcceptSplitItemsAndExposeDedicatedDetailRoute,AccountingAdjustActionServiceImplTest \ + test +``` +结果:PASS +- Tests run: 10 +- Failures: 0 +- Errors: 0 +- Skipped: 0 + +### 4.3 targeted tests(阶段二) +```bash +REV004_IT_DB_URL='jdbc:postgresql://192.168.10.130:5436/sw_system' \ +REV004_IT_DB_USERNAME='sw_system' \ +REV004_IT_DB_PASSWORD='Em@123456' \ +mvn -pl sw-business/sw-business-server \ + -Dtest=Rev004AccountProcessCanaryQueryIntegrationTest#splitAdjustSubmit_shouldAcceptSplitItemsAndExposeDedicatedDetailRoute+legacyUnsoldSplitSubmit_shouldCompatToSplitItemsFlow+splitAdjustPage_shouldReturnDedicatedRows+splitAdjustResult_shouldReturnSuccessAfterApprove,AccountingAdjustActionServiceImplTest \ + test +``` +结果:PASS +- Tests run: 13 +- Failures: 0 +- Errors: 0 +- Skipped: 0 + +## 5. 场景覆盖 +### 已覆盖 +- 新 split submit -> dedicated detail +- 新 split submit -> old log-detail fallback +- 旧 split submit -> new split detail +- dedicated page query +- dedicated result query after approve +- split action service unit tests(approve/reject/write-back) + +### 仍待补强 +- dedicated page + approval status filter 组合查询 +- dedicated process 专属接口(如果最终保留) +- split 执行失败/回滚路径的 real-db targeted integration + +## 6. 风险与后续 +1. 旧接口兼容已接主链,但还需要继续做更完整的批量兼容覆盖 +2. 当前仍未进入 BY_COMPONENT / `ItemStr` 真执行 +3. 若要最终收口,还应补一轮 architect verification + deslop + regression rerun diff --git a/docs/evidence/rev004-accounting/rev004-split-adjust-water-first-mvp-design-2026-04-14.md b/docs/evidence/rev004-accounting/rev004-split-adjust-water-first-mvp-design-2026-04-14.md new file mode 100644 index 0000000..b8ee961 --- /dev/null +++ b/docs/evidence/rev004-accounting/rev004-split-adjust-water-first-mvp-design-2026-04-14.md @@ -0,0 +1,234 @@ +# REV004 / 按水量分账最小闭环设计(2026-04-14) + +## 1. 目标 +本设计只覆盖 **第一阶段:按水量分账最小闭环**。 + +目标是: +- 审批通过后,能够把一笔未收费原账单按多笔水量拆分,真正生成多张目标子账单; +- 先不做“按费用组成分账”; +- 先把最小可运行闭环打通,再作为后续扩展基础。 + +--- + +## 2. 为什么第一阶段先做按水量分账 +原因: +1. **规则最清晰**:拆分水量之和必须等于原水量。 +2. **业务校验最直接**:原账单 -> 多笔子账单,按水量重算金额,容易理解。 +3. **比按费用组成更容易守恒**:先处理总水量、总金额守恒,再逐步扩到费用项粒度。 +4. **更适合先做执行态样板**:审批通过、执行、回看、失败回滚等流程都能先沉淀下来。 + +--- + +## 3. 最小闭环边界 +### 本阶段要做到 +- 提交按水量分账申请 +- 保存拆分明细(每笔分账水量) +- 审批通过后执行拆账 +- 生成多张目标账单 +- 原账单标记为已拆分/失效 +- 日志与查询可回看 + +### 本阶段不做 +- 按费用组成分账 +- 目标客户跨户分账(如无强需求,可先默认同客户) +- 更复杂规则模板 +- 开票联动优化 +- 自动撤销分账执行结果 + +--- + +## 4. 输入输出定义 + +### 4.1 前端最少输入 +按水量分账弹窗至少提交: +- `sourceChargeId` +- `splitItems[]` + - `seqNo` + - `splitWater` +- `reasonCode` +- `remark` +- `applicant` +- `contactMobile` + +### 4.2 关键校验 +- 原账单必须是未收费 +- `splitItems.length >= 2` +- 每笔 `splitWater > 0` +- `sum(splitWater) = source.billWater` +- 必须填写原因 + +### 4.3 输出结果 +申请提交成功后: +- `adjustmentNo` +- `resultStatus = PENDING_APPROVAL` + +执行成功后应可回看: +- 原账单摘要 +- 目标子账单列表 +- 每张子账单的: + - 水量 + - 账单金额 + - 应收金额 + - 违约金(若适用) + +--- + +## 5. 数据模型(MVP) + +### 5.1 主表:`biz_split_adjust` +建议 MVP 字段: +- `id` +- `split_adjust_no` +- `source_charge_id` +- `split_rule_type` = `BY_WATER` +- `reason_code` +- `remark` +- `approval_status` +- `execute_status` +- `execute_message` +- `executed_at` +- `creator / create_time / updater / update_time` + +### 5.2 明细表:`biz_split_adjust_detail` +建议 MVP 字段: +- `id` +- `split_adjust_id` +- `seq_no` +- `split_water` +- `target_charge_id`(执行后回填) +- `split_amount`(执行后回填) +- `status` +- `creator / create_time / updater / update_time` + +### 5.3 账单表最小扩展建议 +在 `biz_charge` 里增加追溯字段(二选一或组合): +- `source_charge_id` +- `split_adjust_id` +- `charge_origin_type`(如:NORMAL / SPLIT_CHILD) + +原账单增加状态表达(二选一): +- 新字段标记 `split_status` +- 或现有字段中增加来源/失效标识 + +MVP 阶段关键不是状态字段优雅,而是: +> 后续能稳定区分“原账单”和“拆分生成的子账单”。 + +--- + +## 6. 执行流程(MVP) + +### Step 1:申请提交 +接口:`POST /unsold-split-submit` +- 校验基本参数 +- 保存 `biz_split_adjust` +- 保存 `biz_split_adjust_detail`(只保存水量) +- 返回待审批 + +### Step 2:审批通过 +- 触发内部执行器 +- 对 `biz_split_adjust` 加幂等校验:只允许执行一次 +- 锁定原账单 `source_charge_id` +- 开事务 + +### Step 3:生成目标账单 +对每个 `split_adjust_detail`: +1. 复制原账单基础信息 +2. 将 `bill_water` 改成当前 `split_water` +3. 调用现有计价逻辑重新计算: + - `bill_amount` + - `extended_amount` + - 若适用则重算 `late_fee` +4. 插入新的 `biz_charge` 记录 +5. 回填 `target_charge_id / split_amount` + +### Step 4:处理原账单 +- 原账单置为“已拆分,不可继续收费” +- 不直接删除原账单 +- 保证历史可追溯 + +### Step 5:收尾 +- `biz_split_adjust.execute_status = SUCCESS` +- 写 operat_log / log detail +- 查询面可见结果 + +### Step 6:失败回滚 +- 任一子账单生成失败:事务回滚 +- 主单置 `FAIL` +- 记录失败原因 +- 不允许出现半拆分状态 + +--- + +## 7. 重算策略建议 +MVP 不建议自己重新写一套计价逻辑,建议: +- 复用已有账单计算能力 +- 输入拆分后的水量 +- 走现有价格模板/费用计算规则 + +原因: +- 这样能减少“分账执行”和“普通开账计费”之间的口径偏差 +- 也更容易保证后续账单金额解释一致 + +关键原则: +> 分账只是“改变水量输入并生成多张账单”,不要重造一套新的计费引擎。 + +--- + +## 8. 查询回看(MVP) +建议至少补两个查询面: + +### 8.1 分账详情查询 +- 原账单摘要 +- 分账规则类型(BY_WATER) +- 每笔拆分水量 +- 每笔生成的目标账单 ID / 金额 +- 执行状态 / 错误原因 + +### 8.2 日志页增强 +在现有 `log-detail / log-process` 中,增加: +- 原账单 -> 子账单映射摘要 +- 执行结果摘要 + +--- + +## 9. 测试建议(MVP) + +### 9.1 单测 +- 水量守恒校验 +- 拆分笔数边界(<2, >12) +- 非未收费账单禁止发起 +- 执行幂等 + +### 9.2 集成测试 +- 提交按水量分账申请 -> 待审批 +- 审批通过 -> 生成 N 张子账单 +- 子账单水量之和 = 原账单水量 +- 原账单不可继续收费 +- 日志页可回看执行结果 +- 执行失败整体回滚 + +### 9.3 验收测试 +- 一张账单拆成 2 笔 +- 一张账单拆成多笔 +- 子账单后续可分别收费/开票(若本期不做全链,可先验证可查询/可识别) + +--- + +## 10. MVP 成功标准 +MVP 完成时,应满足: +1. 用户可提交按水量分账申请 +2. 审批通过后,系统真正生成多张目标账单 +3. 子账单水量之和与原账单守恒 +4. 原账单被正确标记,不再继续作为普通未收费账单使用 +5. 查询与日志能回看这次分账执行结果 + +--- + +## 11. 建议实施顺序 +1. 先补 `biz_split_adjust` / `biz_split_adjust_detail` +2. 再补审批通过后的执行器 +3. 再补查询回看 +4. 最后补前端执行态结果页 + +一句话: +> 先把“按水量分账”做成审批后真正能拆出子账单的最小闭环,再考虑按费用组成扩展。 diff --git a/docs/evidence/rev004-accounting/rev004-split-fixed-fee-first-child-2026-06-19.md b/docs/evidence/rev004-accounting/rev004-split-fixed-fee-first-child-2026-06-19.md new file mode 100644 index 0000000..77e2f87 --- /dev/null +++ b/docs/evidence/rev004-accounting/rev004-split-fixed-fee-first-child-2026-06-19.md @@ -0,0 +1,46 @@ +# REV004 分账固定费用归属修复验证记录 + +## 背景 + +按水量分账采用连续阶梯重算后,`calculationMode=3` 的固定金额费用会在每个子账单重算一次,导致固定费用被重复收取。 + +本次明确业务口径:按水量分账时,固定金额费用只归属第 1 个子账单,后续子账单该固定费用为 0。 + +## 实现范围 + +- 后端仓库:`../water-backend/` +- 基线:`6156e47f8` +- 验证日期:2026-06-19 +- 涉及文件: + - `sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/service/accountingadjust/trial/UnsoldTrialPreviewServiceImpl.java` + - `sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/service/accountingadjust/AccountingAdjustActionServiceImpl.java` + - `sw-business/sw-business-server/src/test/java/cn/com/emsoft/sw/business/service/accountingadjust/trial/UnsoldTrialPreviewServiceImplTest.java` + - `sw-business/sw-business-server/src/test/java/cn/com/emsoft/sw/business/service/accountingadjust/AccountingAdjustActionServiceImplTest.java` + +## 规则 + +- 按水量分账继续按拆分顺序做连续阶梯重算。 +- 水价费用配置中 `calculationMode=3` 的固定金额费用: + - 第 1 个子账单取原账单对应费用金额。 + - 第 2..N 个子账单置 0。 +- 正式回写时同步调整子账单费用明细,固定费用明细第 1 个子账单保留原金额,后续子账单清零。 +- 按费用组成分账不在本次范围内,保持原逻辑。 + +## 验证 + +执行命令: + +```bash +mvn -pl sw-business/sw-business-server -am -Dtest=UnsoldTrialPreviewServiceImplTest,AccountingAdjustActionServiceImplTest -Dsurefire.failIfNoSpecifiedTests=false test +``` + +结果: + +- `UnsoldTrialPreviewServiceImplTest`:11 tests, 0 failures, 0 errors +- `AccountingAdjustActionServiceImplTest`:19 tests, 0 failures, 0 errors +- Reactor build:SUCCESS + +补充说明: + +- 初次仅使用 `-pl sw-business/sw-business-server` 执行时,因未同时构建 `sw-business-api` 依赖,命中本地依赖中的 `CustPriceChangeUpdateDTO` 缺失编译错误;改用 `-am` 后源码依赖正常参与构建。 +- `-am` 执行指定测试时,上游模块需要追加 `-Dsurefire.failIfNoSpecifiedTests=false`,避免上游模块没有匹配测试导致提前失败。 diff --git a/docs/evidence/rev004-accounting/rev004-unsold-usage-adjust-zero-and-recovery-2026-06-19.md b/docs/evidence/rev004-accounting/rev004-unsold-usage-adjust-zero-and-recovery-2026-06-19.md new file mode 100644 index 0000000..a02e26e --- /dev/null +++ b/docs/evidence/rev004-accounting/rev004-unsold-usage-adjust-zero-and-recovery-2026-06-19.md @@ -0,0 +1,26 @@ +# REV-004 未销水量调整零水量与补抄追收验证记录 + +## 变更范围 + +- 按水量调整预算允许 `targetBillWater=0`,仍拒绝负数水量。 +- 正式水量调整默认保留“调整后水量不能超过抄见水量”限制。 +- 当原因编码或原因说明属于补抄、追收、漏抄、少抄、估抄偏低、补征等场景时,允许目标水量超过原抄见水量。 + +## 验证命令 + +```bash +mvn -pl sw-business/sw-business-server -am \ + -Dtest=UnsoldTrialPreviewServiceImplTest,ChargeServiceAccountingAdjustTest \ + -Dsurefire.failIfNoSpecifiedTests=false test +``` + +## 验证结果 + +- `UnsoldTrialPreviewServiceImplTest`: 12 tests, 0 failures, 0 errors. +- `ChargeServiceAccountingAdjustTest`: 24 tests, 0 failures, 0 errors. +- Maven reactor: `BUILD SUCCESS`. + +## 风险说明 + +- 本次未放开已收费、已开票、已结账、缺少抄表依据、缺少附件等既有校验。 +- 补抄追收白名单为后端兼容策略,后续可在正式原因字典稳定后收敛为字典值校验。 diff --git a/docs/evidence/rev004-accounting/rev004-unsold-water-preview-options-no-db-2026-06-19.md b/docs/evidence/rev004-accounting/rev004-unsold-water-preview-options-no-db-2026-06-19.md new file mode 100644 index 0000000..dd73188 --- /dev/null +++ b/docs/evidence/rev004-accounting/rev004-unsold-water-preview-options-no-db-2026-06-19.md @@ -0,0 +1,37 @@ +# REV-004 未销水量调整预算选项无库变更验证记录 + +## 变更范围 + +- 未销按水量调整正式提交新增 `updateAccumulated`、`updateBaseCode` 两个选项字段。 +- `unsold-adjust-submit` 控制器映射、统一提交 VO、核心账务调整 VO 均已透传上述字段。 +- `updateBaseCode=true` 时,正式水量调整要求传入 `currentReading`,并将其写入营业账本次抄码。 +- `updateBaseCode=false` 或未传时,即使传入 `currentReading`,也不写入营业账本次抄码。 +- `updateAccumulated=true` 时,按 `调整后水量 - 调整前水量` 调整营业账累计水量;`false` 或未传时不调整累计水量。 +- 操作日志记录 `updateAccumulated`、`updateBaseCode`,字段类型为 YES_OR_NO。 + +## 未纳入本轮范围 + +- 本轮按用户要求仅实现不需要数据库结构变更的功能。 +- 价差调整选项正式持久化、价差明细表新增字段、SQL 迁移仍保留为后续 DB 相关任务。 + +## 验证命令 + +```bash +mvn -pl sw-business/sw-business-server -am \ + -Dtest=UnsoldTrialPreviewServiceImplTest,AccountingAdjustActionControllerTest#createUnsoldAdjust_shouldReturnWrappedSuccess,AccountingAdjustProcessServiceImplTest#createUnsoldAdjust_shouldPassWaterOptionFlagsToUnifiedChargeService,ChargeServiceAccountingAdjustTest \ + -Dsurefire.failIfNoSpecifiedTests=false test +``` + +## 验证结果 + +- `AccountingAdjustActionControllerTest#createUnsoldAdjust_shouldReturnWrappedSuccess`: 1 test, 0 failures, 0 errors. +- `AccountingAdjustProcessServiceImplTest#createUnsoldAdjust_shouldPassWaterOptionFlagsToUnifiedChargeService`: 1 test, 0 failures, 0 errors. +- `ChargeServiceAccountingAdjustTest`: 27 tests, 0 failures, 0 errors. +- `UnsoldTrialPreviewServiceImplTest`: 12 tests, 0 failures, 0 errors. +- Maven reactor: 41 tests, 0 failures, 0 errors, `BUILD SUCCESS`. + +## 风险与兼容说明 + +- `currentReading` 不再单独触发底码写入;调用方必须显式传 `updateBaseCode=true` 才会更新本次抄码。 +- 未传 checkbox 时按默认 false 处理,避免预算页选项未确认时误写正式字段。 +- 本轮未放宽已收费、已开票、已结账、缺少抄表依据、缺少附件等既有水量调整校验。 diff --git a/docs/evidence/rev004-writtenoff-formal-table-dev-db-apply-2026-04-17.md b/docs/evidence/rev004-accounting/rev004-writtenoff-formal-table-dev-db-apply-2026-04-17.md similarity index 100% rename from docs/evidence/rev004-writtenoff-formal-table-dev-db-apply-2026-04-17.md rename to docs/evidence/rev004-accounting/rev004-writtenoff-formal-table-dev-db-apply-2026-04-17.md diff --git a/docs/evidence/rev005-invoice/2026-06-16-invoice-document-audit.md b/docs/evidence/rev005-invoice/2026-06-16-invoice-document-audit.md new file mode 100644 index 0000000..1c9b478 --- /dev/null +++ b/docs/evidence/rev005-invoice/2026-06-16-invoice-document-audit.md @@ -0,0 +1,129 @@ +# REV-005 发票业务流 — 文档审计报告 + +**审计日期**: 2026-06-16 +**审计范围**: `water-docs/specs/002-rev005-invoice-flow/` + `docs/design/` 主文档 + `water-backend` 代码(worktree `backend-rev005`) +**审计目标**: 评估发票相关文档的完整性、一致性和可追溯性 + +--- + +## 1. 审计总览 + +| 维度 | 结论 | +|------|------| +| 规格完整性 | ✅ 完备 | +| 正式设计一致性 | ⚠️ 轻微偏差(状态定义 6 vs 4 态) | +| 接口契约覆盖 | ✅ 完备 | +| 数据模型覆盖 | ✅ 完备(正式版在 DB 设计中,specs 草稿已删除) | +| 代码实现对应 | ✅ 59/65 任务完成,6 项为验证任务 | +| 前端设计覆盖 | ✅ 有独立前端设计文档(866 行) | +| 验证证据 | ❌ 8 项验证任务未完成 | + +--- + +## 2. 文档地图 + +``` +specs/002-rev005-invoice-flow/ +├── spec.md ✅ 有 +├── plan.md ✅ 有 +├── tasks.md ✅ 有(65 项,59 完成) +├── research.md ✅ 有 +├── quickstart.md ✅ 有 +├── verification.md ⚠️ 有,但 8 个验证任务未完成 +└── frontend-finance-design.md ✅ 有(2026-05-12 新增) + +docs/design/ (正式主文档) +├── 02_Detailed_Design/12_REV_Detailed.md ✅ REV-005 章节完整 +├── 03_Technical_Design/01_Database_Design.md ✅ biz_invoice 表覆盖 +└── 03_Technical_Design/03_Interface_Design.md ✅ IF-REV-008/009 定义完整 + +docs/evidence/rev005-invoice/ 📭 空(尚无证据入库) +``` + +--- + +## 3. 发现 + +### 3.1 状态定义差异(中风险) + +**问题**:`12_REV_Detailed.md` 定义了 6 个发票状态(`SUBMITTED`、`PENDING`、`SUCCESS`、`FAIL`、`INVALID`、`RED_INK`),但 `InvoiceController` 代码中实现了 `invalidate` 和 `red-ink` 两个独立端点,而 `InvoiceDO` 中的 `invoiceStatus` 字段是否支持这 6 态尚未在代码层确认。 + +**影响**:作废/红冲是二期补齐的功能,需确认 `biz_invoice` 表的 `invoice_status` 枚举已包含 `INVALID` 和 `RED_INK`,否则运行时会抛异常。 + +**建议**:检查 `InvoiceStatusEnum`(如存在)或 `biz_invoice` 的 DDL 确认枚举覆盖。 + +### 3.2 验证证据缺失(低风险) + +`specs/002-rev005-invoice-flow/verification.md` 中 8 个验证任务未完成: + +| 编号 | 内容 | 阻塞点 | +|------|------|--------| +| T022 | 重复申请、部分开票拒绝的样本 | 需联调环境 | +| T033 | SYS-008 不可用、超时等异常样本 | 需联调环境 | +| T044 | 回写/查询/下载/推送成功率统计 | 需联调环境 | +| T055 | 作废/红冲运行态日志样本 | 需联调环境 | +| T060-T063 | SC-001~SC-004 性能指标采样 | 需测试环境 | + +**影响**:不影响功能实现,但会影响验收签字。 + +**建议**:在提测前集中补齐,可安排在联调阶段同步采集。 + +### 3.3 接口路径不一致(低风险) + +| 定义位置 | 路径 | +|----------|------| +| `specs/002/contracts/if-rev-008.md`(已删除) | `/api/invoice/apply`(假设) | +| `03_Interface_Design.md` | `/business/invoice/apply` | +| `InvoiceController.java` | `/business/invoice/apply`(`@RequestMapping("/business/invoice")` + `@PostMapping("/apply")`) | + +正式接口设计和代码实现路径一致(`/business/invoice/apply`)。specs 里的旧契约已删除,不存在冲突。✅ 无问题。 + +### 3.4 前端设计文档状态(观察项) + +`frontend-finance-design.md` 是 2026-05-12 新增的,晚于主设计文档(2026-03-19)。它是独立于后端设计文档的前端实现补充,目前状态为"作为前端实现输入"。 + +**影响**:`water-frontend` 尚未同步确认是否已按照此文档实现。 + +**建议**:下一步在 `water-frontend` 的 AGENTS.md 或对应 spec 中确认前端实现进度。 + +### 3.5 数据模型一致性(已解决) + +此前 `specs/002/` 存在独立的 `data-model.md` 和 `contracts/` 目录,与正式设计文档有内容重叠。本次审计已删除冗余草稿,数据模型以 `01_Database_Design.md` 为准,接口以 `03_Interface_Design.md` 为准。 + +--- + +## 4. FR 覆盖矩阵 + +| FR | 描述 | 设计文档 | 代码 | 状态 | +|----|------|---------|------|------| +| FR-001 | 后台发票申请接口 | ✅ | ✅ `POST /apply` | 已实现 | +| FR-002 | 校验账单状态 | ✅ | ✅ `InvoiceServiceImpl` | 已实现 | +| FR-003 | 校验客户开票信息 | ✅ | ✅ | 已实现 | +| FR-004 | 校验开票限额 | ⚠️ 设计中提及但未详细展开 | ❓ 待确认 | 部分 | +| FR-005 | 生成发票申请记录 | ✅ | ✅ `biz_invoice_record` | 已实现 | +| FR-006 | 调用 SYS-008 | ✅ | ✅ `InvoicePlatformClient` | 已实现 | +| FR-007 | 定时查询兜底 | ✅ | ✅ `InvoiceCompensateJob` | 已实现 | +| FR-008 | 更新发票状态 | ✅ | ✅ | 已实现 | +| FR-009 | 发票-账单关联 | ✅ | ✅ `biz_charge_invoice_rel` | 已实现 | +| FR-010 | 客户侧查询/下载/推送 | ✅ | ✅ 3 个端点 | 已实现 | +| FR-011 | 操作日志 | ✅ | ⚠️ 部分方法有日志 | 部分 | +| FR-012 | 作废入口 | ✅ | ✅ `POST /invalidate` | 已实现 | +| FR-013 | 红冲入口 | ✅ | ✅ `POST /red-ink` | 已实现 | +| FR-014 | 终态保护与结果回写 | ✅ | ✅ | 已实现 | + +**关键发现**:FR-004(开票限额)在设计文档中提及但未明确限额来源(配置表?固定值?),代码层待确认。FR-011(操作日志)在关键动作上有日志,但完整度待验证。 + +--- + +## 5. 建议优先级 + +| 优先级 | 建议 | +|--------|------| +| **P0** | 确认 `biz_invoice` 的 `invoiceStatus` 枚举是否包含 `INVALID` 和 `RED_INK`,避免作废/红冲端点运行时报错 | +| **P1** | 明确开票限额校验逻辑(FR-004):从配置表读取还是硬编码,限额是单笔还是累计 | +| **P1** | 联调阶段集中采集 T022/T033/T044/T055/T060-T063 的验证样本 | +| **P2** | 确认 `water-frontend` 对 `frontend-finance-design.md` 的实现进度 | + +--- + +审计结论:REV-005 发票业务流的文档体系基本完备,设计文档、接口契约、数据模型和代码实现高度对齐。主要风险点是作废/红冲状态枚举的代码层覆盖确认,以及 8 项验证样本的补充。 diff --git a/docs/guides/SYSTEM_CAPABILITY_CLOSURE_MAP.md b/docs/guides/SYSTEM_CAPABILITY_CLOSURE_MAP.md index 99a59ea..4d8f6d1 100644 --- a/docs/guides/SYSTEM_CAPABILITY_CLOSURE_MAP.md +++ b/docs/guides/SYSTEM_CAPABILITY_CLOSURE_MAP.md @@ -328,7 +328,7 @@ REV-004 先统一账务状态、留痕、原交易校验口径 - `specs/001-rev004-accounting/` - `specs/002-rev005-invoice-flow/` -- `specs/003-rev006-reminder-event-design/` +- `specs/003-rev003-rev006-reminder-event-design/` - `specs/004-rev007-revenue-statistics-design/` - `docs/design/00_Management/01_Project_Progress.md` - `docs/design/00_Management/03_Task_Checklist.md` diff --git a/docs/superpowers/plans/2026-05-15-xlsx-export-unification.md b/docs/superpowers/plans/2026-05-15-xlsx-export-unification.md new file mode 100644 index 0000000..2dada9a --- /dev/null +++ b/docs/superpowers/plans/2026-05-15-xlsx-export-unification.md @@ -0,0 +1,602 @@ +# Excel 导出 xlsx 统一化与前端 CSV 替换 Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** 统一后端 Excel 下载为标准 `.xlsx`,并将 5 个前端页面从本地 CSV 导出切换为后端真实 Excel 导出。 + +**Architecture:** 后端以 `ExcelUtils` 为唯一公共导出入口,统一 MIME、文件名后缀和可编码文件名策略;前端不再拼接 `csvContent` 或创建 `text/csv` Blob,而是为目标页面新增 API 下载封装,直接请求后端导出接口并复用响应头中的文件名。实现按 backend lane / frontend lane 拆开,但在同一 feature 下联调收口。 + +**Tech Stack:** Java 17, Spring Boot, EasyExcel, MockMvc, Vue 3, TypeScript, Axios wrapper (`@/config/axios`), pnpm + +--- + +## File Structure + +### Backend files +- Modify: `../water-backend/sw-framework/sw-spring-boot-starter-excel/src/main/java/cn/com/emsoft/sw/framework/excel/core/util/ExcelUtils.java` + - 统一 `write` / `writeWithTemplate` / `writeTemplate` 的 xlsx MIME 与 `Content-Disposition`。 +- Modify: `../water-backend/sw-business/sw-business-server/src/test/java/cn/com/emsoft/sw/business/controller/admin/accountingadjust/accountProcess/AccountingAdjustRouteSmokeTest.java` + - 把现有导出 smoke 断言从 `application/vnd.ms-excel` 更新为 xlsx MIME,并验证 `Content-Disposition` 仍存在。 +- Inspect/reuse (no code unless缺口真实存在): + - `../water-backend/sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/controller/admin/accountingadjust/accountProcess/AccountingAdjustActionController.java` + - `../water-backend/sw-business-bank/sw-business-bank-server/src/main/java/cn/com/emsoft/sw/bankbusiness/controller/admin/withholdingbatch/WithholdingBatchController.java` + - `../water-backend/sw-business-bank/sw-business-bank-server/src/main/java/cn/com/emsoft/sw/bankbusiness/controller/admin/withholdingitem/WithholdingItemController.java` + - `../water-backend/sw-business-bank/sw-business-bank-server/src/main/java/cn/com/emsoft/sw/bankbusiness/controller/admin/channelstatistics/ChannelStatisticsController.java` + +### Frontend files +- Create: `../water-frontend/src/api/operatingCharges/redReversalRecord/index.ts` + - 红冲记录页导出 API。 +- Create: `../water-frontend/src/api/collection/export/index.ts` + - 银行托收 / 托收明细 / 银行代扣 / 实时收费导出 API。 +- Modify: `../water-frontend/src/utils/download.ts` + - 增加从后端响应中提取文件名并下载 Blob 的工具,支持中文文件名编码。 +- Modify: `../water-frontend/src/views/operatingCharges/redReversalRecord/index.vue` + - 删除本地 CSV 导出,改调红冲记录导出 API。 +- Modify: `../water-frontend/src/views/collection/bankCollection/index.vue` + - 删除本地 CSV 导出,改调托收批次导出 API。 +- Modify: `../water-frontend/src/views/collection/bankCollection/detail.vue` + - 删除本地 CSV 导出,改调托收明细导出 API。 +- Modify: `../water-frontend/src/views/collection/bankWithholding/index.vue` + - 删除本地 CSV 导出,改调用同一批次导出 API,并带 `businessType=WITHHOLDING`。 +- Modify: `../water-frontend/src/views/collection/realTimeBilling/index.vue` + - 删除本地 CSV 导出,改调实时收费统计导出 API。 + +--- + +### Task 1: 统一后端 ExcelUtils 为标准 xlsx 下载 + +**Files:** +- Modify: `../water-backend/sw-framework/sw-spring-boot-starter-excel/src/main/java/cn/com/emsoft/sw/framework/excel/core/util/ExcelUtils.java` +- Test: `../water-backend/sw-business/sw-business-server/src/test/java/cn/com/emsoft/sw/business/controller/admin/accountingadjust/accountProcess/AccountingAdjustRouteSmokeTest.java` + +- [ ] **Step 1: 先写出会失败的导出头断言** + +在 `AccountingAdjustRouteSmokeTest.java` 把 4 个导出断言先改成 xlsx MIME,保持其它断言不动: + +```java +mockMvc.perform(get(BASE + "/log-export")) + .andExpect(status().isOk()) + .andExpect(header().string("Content-Disposition", org.hamcrest.Matchers.startsWith("attachment;filename="))) + .andExpect(content().contentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8")); + +mockMvc.perform(get(BASE + "/log-export-excel")) + .andExpect(status().isOk()) + .andExpect(header().string("Content-Disposition", org.hamcrest.Matchers.startsWith("attachment;filename="))) + .andExpect(content().contentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8")); + +mockMvc.perform(get(BASE + "/prestorage-export")) + .andExpect(status().isOk()) + .andExpect(header().string("Content-Disposition", org.hamcrest.Matchers.startsWith("attachment;filename="))) + .andExpect(content().contentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8")); + +mockMvc.perform(get(BASE + "/prestorage-export-excel")) + .andExpect(status().isOk()) + .andExpect(header().string("Content-Disposition", org.hamcrest.Matchers.startsWith("attachment;filename="))) + .andExpect(content().contentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8")); +``` + +- [ ] **Step 2: 运行后端 smoke,确认当前实现失败** + +Run: + +```bash +mvn -f "/Volumes/Dpan/github/water-workspace/water-backend/pom.xml" -pl sw-business/sw-business-server -am -Dtest=AccountingAdjustRouteSmokeTest test +``` + +Expected: FAIL,错误类似 `Content type expected: but was:`。 + +- [ ] **Step 3: 在 ExcelUtils 中抽出统一下载头设置方法,并把 MIME 改成 xlsx** + +把 `ExcelUtils.java` 的响应头逻辑改成下面这种结构,三个写方法都复用它: + +```java +private static final String XLSX_CONTENT_TYPE = + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8"; + +private static void prepareAttachmentResponse(HttpServletResponse response, String filename) { + response.addHeader("Content-Disposition", "attachment;filename=" + HttpUtils.encodeUtf8(ensureXlsxFilename(filename))); + response.setContentType(XLSX_CONTENT_TYPE); +} + +private static String ensureXlsxFilename(String filename) { + if (filename == null || filename.isBlank()) { + return "export.xlsx"; + } + if (filename.toLowerCase().endsWith(".xlsx")) { + return filename; + } + if (filename.toLowerCase().endsWith(".xls")) { + return filename.substring(0, filename.length() - 4) + ".xlsx"; + } + return filename + ".xlsx"; +} +``` + +然后把三个入口统一改成: + +```java +public static void write(HttpServletResponse response, String filename, String sheetName, + Class head, List data) throws IOException { + prepareAttachmentResponse(response, filename); + EasyExcel.write(response.getOutputStream(), head) + .autoCloseStream(false) + .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) + .registerWriteHandler(new SelectSheetWriteHandler(head)) + .registerConverter(new LongStringConverter()) + .sheet(sheetName) + .doWrite(data); +} +``` + +```java +public static void writeWithTemplate(HttpServletResponse response, String filename, InputStream templateStream, + String sheetName, Class head, List data) throws IOException { + if (templateStream == null) { + throw new RuntimeException("Excel模板文件流不能为空"); + } + prepareAttachmentResponse(response, filename); + try (templateStream) { + EasyExcel.write(response.getOutputStream(), head) + .withTemplate(templateStream) + .autoCloseStream(false) + .registerWriteHandler(new SelectSheetWriteHandler(head)) + .registerConverter(new LongStringConverter()) + .sheet(sheetName) + .needHead(false) + .doWrite(data); + } +} +``` + +```java +public static void writeTemplate(HttpServletResponse response, String filename, InputStream templateStream) + throws IOException { + prepareAttachmentResponse(response, filename); + templateStream.transferTo(response.getOutputStream()); + templateStream.close(); +} +``` + +- [ ] **Step 4: 重新跑后端 smoke,确认通过** + +Run: + +```bash +mvn -f "/Volumes/Dpan/github/water-workspace/water-backend/pom.xml" -pl sw-business/sw-business-server -am -Dtest=AccountingAdjustRouteSmokeTest test +``` + +Expected: PASS,四个导出断言均匹配 xlsx MIME。 + +- [ ] **Step 5: 提交后端公共导出修复** + +```bash +git -C "/Volumes/Dpan/github/water-workspace/water-backend" add \ + sw-framework/sw-spring-boot-starter-excel/src/main/java/cn/com/emsoft/sw/framework/excel/core/util/ExcelUtils.java \ + sw-business/sw-business-server/src/test/java/cn/com/emsoft/sw/business/controller/admin/accountingadjust/accountProcess/AccountingAdjustRouteSmokeTest.java + +git -C "/Volumes/Dpan/github/water-workspace/water-backend" commit -m "fix(excel): standardize xlsx download headers" +``` + +### Task 2: 给前端下载工具增加后端文件流下载与文件名解码 + +**Files:** +- Modify: `../water-frontend/src/utils/download.ts` +- Test: `../water-frontend/src/views/operatingCharges/redReversalRecord/index.vue` (first consumer) + +- [ ] **Step 1: 为下载工具写出目标接口** + +在 `download.ts` 里新增两个内部函数:一个解析 `Content-Disposition`,一个下载 axios blob 响应。目标代码如下: + +```ts +const decodeFilename = (contentDisposition?: string, fallbackName = 'export.xlsx') => { + if (!contentDisposition) return fallbackName + const utf8Match = contentDisposition.match(/filename\*=utf-8''([^;]+)/i) + if (utf8Match?.[1]) { + return decodeURIComponent(utf8Match[1]) + } + const plainMatch = contentDisposition.match(/filename=([^;]+)/i) + if (plainMatch?.[1]) { + return decodeURIComponent(plainMatch[1].trim().replace(/^"|"$/g, '')) + } + return fallbackName +} + +const downloadResponse = (response: any, fallbackName = 'export.xlsx') => { + const fileName = decodeFilename(response?.headers?.['content-disposition'], fallbackName) + download0(response.data, fileName, response.data?.type || 'application/octet-stream') +} +``` + +- [ ] **Step 2: 把新工具挂到默认导出对象** + +在 `download` 对象中追加: + +```ts +response: (response: any, fallbackName?: string) => { + downloadResponse(response, fallbackName) +} +``` + +保留原有 `excel/word/zip/html/markdown/json`,不要顺手改其它行为。 + +- [ ] **Step 3: 运行前端类型检查,确认工具签名可用** + +Run: + +```bash +pnpm --dir "/Volumes/Dpan/github/water-workspace/water-frontend" ts:check +``` + +Expected: PASS;如果有 `response` 未使用或 `any` 风格告警,只修本次新增代码,不扩散重构。 + +- [ ] **Step 4: 提交前端下载工具改动** + +```bash +git -C "/Volumes/Dpan/github/water-workspace/water-frontend" add src/utils/download.ts + +git -C "/Volumes/Dpan/github/water-workspace/water-frontend" commit -m "feat(download): support backend blob responses" +``` + +### Task 3: 新增前端导出 API 封装并替换红冲记录页 + +**Files:** +- Create: `../water-frontend/src/api/operatingCharges/redReversalRecord/index.ts` +- Modify: `../water-frontend/src/views/operatingCharges/redReversalRecord/index.vue` + +- [ ] **Step 1: 新建红冲记录导出 API 文件** + +创建 `src/api/operatingCharges/redReversalRecord/index.ts`: + +```ts +import request from '@/config/axios' + +export const exportRedReversalRecord = (params: any) => { + return request.download({ + url: '/business/accounting-adjust/log-export', + params + }) +} +``` + +- [ ] **Step 2: 先删掉红冲记录页本地 CSV 构造,替换为后端下载调用** + +把 `redReversalRecord/index.vue` 的导出逻辑改成: + +```ts +import download from '@/utils/download' +import { exportRedReversalRecord } from '@/api/operatingCharges/redReversalRecord' +``` + +```ts +const handleExport = async () => { + try { + await message.exportConfirm() + exportLoading.value = true + const response = await exportRedReversalRecord({ ...queryParams }) + download.response(response, `红冲记录_${formatDate(Date.now() as any)}.xlsx`) + } finally { + exportLoading.value = false + } +} +``` + +同时删除这些旧代码: + +```ts +const data = list.value +const headers = ['红冲时间', '红冲金额', '收费员', '操作员', '收费时间', '备注'] +const csvContent = [ + headers.join(','), + ...data.map((row: any) => [ + row.reversalTime, + row.reversalAmount, + row.cashier, + row.operator, + row.chargeTime, + row.remark + ].join(',')) +].join('\n') +const blob = new Blob(['\ufeff' + csvContent], { type: 'text/csv;charset=utf-8;' }) +download.excel(blob, `红冲记录_${formatDate(Date.now() as any)}.csv`) +``` + +- [ ] **Step 3: 运行前端类型检查,确认红冲记录页接线通过** + +Run: + +```bash +pnpm --dir "/Volumes/Dpan/github/water-workspace/water-frontend" ts:check +``` + +Expected: PASS;页面仍可编译,新增 API 路径可被解析。 + +- [ ] **Step 4: 提交红冲记录页接线** + +```bash +git -C "/Volumes/Dpan/github/water-workspace/water-frontend" add \ + src/api/operatingCharges/redReversalRecord/index.ts \ + src/views/operatingCharges/redReversalRecord/index.vue + +git -C "/Volumes/Dpan/github/water-workspace/water-frontend" commit -m "feat(red-reversal): use backend excel export" +``` + +### Task 4: 新增 collection 导出 API 并替换托收批次/托收明细页面 + +**Files:** +- Create: `../water-frontend/src/api/collection/export/index.ts` +- Modify: `../water-frontend/src/views/collection/bankCollection/index.vue` +- Modify: `../water-frontend/src/views/collection/bankCollection/detail.vue` + +- [ ] **Step 1: 新建 collection 导出 API 文件** + +创建 `src/api/collection/export/index.ts`: + +```ts +import request from '@/config/axios' + +export const exportCollectionBatch = (params: any) => { + return request.download({ + url: '/bankbusiness/withholding-batch/export-excel', + params: { + ...params, + businessType: 'COLLECTION' + } + }) +} + +export const exportCollectionDetail = (params: any) => { + return request.download({ + url: '/bankbusiness/withholding-item/export-excel', + params + }) +} + +export const exportWithholdingBatch = (params: any) => { + return request.download({ + url: '/bankbusiness/withholding-batch/export-excel', + params: { + ...params, + businessType: 'WITHHOLDING' + } + }) +} + +export const exportRealtimeStatistics = (params: any) => { + return request.download({ + url: '/bankbusiness/channel-statistics/export-excel', + params + }) +} +``` + +- [ ] **Step 2: 替换银行托收页导出** + +在 `bankCollection/index.vue` 中引入: + +```ts +import download from '@/utils/download' +import { exportCollectionBatch } from '@/api/collection/export' +``` + +把导出函数改成: + +```ts +const handleExport = async () => { + try { + await message.exportConfirm() + exportLoading.value = true + const response = await exportCollectionBatch({ ...queryParams }) + download.response(response, `银行托收_${formatDate(Date.now() as any)}.xlsx`) + } finally { + exportLoading.value = false + } +} +``` + +删除 `headers.join(',')` / `csvContent` / `Blob(text/csv)` / `.csv` 文件名代码。 + +- [ ] **Step 3: 替换托收明细页导出** + +在 `bankCollection/detail.vue` 中引入: + +```ts +import download from '@/utils/download' +import { exportCollectionDetail } from '@/api/collection/export' +``` + +把导出函数改成: + +```ts +const handleExport = async () => { + try { + await message.exportConfirm() + exportLoading.value = true + const response = await exportCollectionDetail({ ...queryParams }) + download.response(response, `托收明细_${formatDate(Date.now() as any)}.xlsx`) + } finally { + exportLoading.value = false + } +} +``` + +保留 `batchNo: route.query.batchNo || ''` 作为请求参数的一部分,不要丢掉详情上下文。 + +- [ ] **Step 4: 运行前端类型检查,确认两个页面通过** + +Run: + +```bash +pnpm --dir "/Volumes/Dpan/github/water-workspace/water-frontend" ts:check +``` + +Expected: PASS;`bankCollection` 与 `detail` 不再包含 CSV 导出逻辑。 + +- [ ] **Step 5: 提交托收页面改造** + +```bash +git -C "/Volumes/Dpan/github/water-workspace/water-frontend" add \ + src/api/collection/export/index.ts \ + src/views/collection/bankCollection/index.vue \ + src/views/collection/bankCollection/detail.vue + +git -C "/Volumes/Dpan/github/water-workspace/water-frontend" commit -m "feat(collection): switch batch exports to backend excel" +``` + +### Task 5: 替换银行代扣与实时收费页面导出 + +**Files:** +- Modify: `../water-frontend/src/views/collection/bankWithholding/index.vue` +- Modify: `../water-frontend/src/views/collection/realTimeBilling/index.vue` +- Reuse: `../water-frontend/src/api/collection/export/index.ts` + +- [ ] **Step 1: 替换银行代扣页导出** + +在 `bankWithholding/index.vue` 中引入: + +```ts +import download from '@/utils/download' +import { exportWithholdingBatch } from '@/api/collection/export' +``` + +把导出函数改成: + +```ts +const handleExport = async () => { + try { + await message.exportConfirm() + exportLoading.value = true + const response = await exportWithholdingBatch({ ...queryParams }) + download.response(response, `银行代扣_${formatDate(Date.now() as any)}.xlsx`) + } finally { + exportLoading.value = false + } +} +``` + +删除本地 CSV 生成代码。 + +- [ ] **Step 2: 替换实时收费页导出** + +在 `realTimeBilling/index.vue` 中引入: + +```ts +import download from '@/utils/download' +import { exportRealtimeStatistics } from '@/api/collection/export' +``` + +把导出函数改成: + +```ts +const handleExport = async () => { + try { + await message.exportConfirm() + exportLoading.value = true + const response = await exportRealtimeStatistics({ ...queryParams }) + download.response(response, `实时收费_${formatDate(Date.now() as any)}.xlsx`) + } finally { + exportLoading.value = false + } +} +``` + +删除原 `csvContent` / `Blob(text/csv)` 代码。 + +- [ ] **Step 3: 跑前端类型检查与最小构建** + +Run: + +```bash +pnpm --dir "/Volumes/Dpan/github/water-workspace/water-frontend" ts:check +pnpm --dir "/Volumes/Dpan/github/water-workspace/water-frontend" build:dev +``` + +Expected: 两条命令都 PASS;`build:dev` 产物成功生成。 + +- [ ] **Step 4: 提交银行代扣与实时收费页改造** + +```bash +git -C "/Volumes/Dpan/github/water-workspace/water-frontend" add \ + src/views/collection/bankWithholding/index.vue \ + src/views/collection/realTimeBilling/index.vue + +git -C "/Volumes/Dpan/github/water-workspace/water-frontend" commit -m "feat(collection): route remaining exports through backend" +``` + +### Task 6: 联调验证与收口 + +**Files:** +- Verify: `../water-backend/...` changed files +- Verify: `../water-frontend/...` changed files +- Optional evidence note: `../water-docs/docs/evidence/` (only if user asks for persistent evidence) + +- [ ] **Step 1: 手工检查代码中已消失的 CSV 痕迹** + +Run: + +```bash +grep -R "text/csv\|csvContent\|\.csv" "/Volumes/Dpan/github/water-workspace/water-frontend/src/views/operatingCharges/redReversalRecord" \ + "/Volumes/Dpan/github/water-workspace/water-frontend/src/views/collection/bankCollection" \ + "/Volumes/Dpan/github/water-workspace/water-frontend/src/views/collection/bankWithholding" \ + "/Volumes/Dpan/github/water-workspace/water-frontend/src/views/collection/realTimeBilling" +``` + +Expected: 无匹配,或者仅剩注释/字符串字面量以外的历史内容为 0。 + +- [ ] **Step 2: 手工检查后端 xlsx MIME 已生效** + +Run: + +```bash +grep -R "application/vnd.ms-excel;charset=UTF-8" "/Volumes/Dpan/github/water-workspace/water-backend/sw-framework/sw-spring-boot-starter-excel/src/main/java/cn/com/emsoft/sw/framework/excel/core/util/ExcelUtils.java" +``` + +Expected: 无匹配。 + +- [ ] **Step 3: 浏览器 smoke** + +在本地/测试环境逐页点击导出并记录结果: + +- `/operatingCharges/redReversalRecord` +- `/collection/bankCollection` +- `/collection/bankCollection/detail?batchNo=` +- `/collection/bankWithholding` +- `/collection/realTimeBilling` + +Expected: +- 发起真实网络请求,不是浏览器本地 Blob 生成。 +- 返回文件为 `.xlsx`。 +- 中文文件名不乱码。 + +- [ ] **Step 4: 分别查看两仓状态并准备后续 PR** + +Run: + +```bash +git -C "/Volumes/Dpan/github/water-workspace/water-backend" status --short + +git -C "/Volumes/Dpan/github/water-workspace/water-frontend" status --short +``` + +Expected: 两仓仅包含本计划涉及的文件改动,无额外脏改动。 + +- [ ] **Step 5: 如果需要合并前整理最终提交** + +```bash +git -C "/Volumes/Dpan/github/water-workspace/water-backend" log --oneline -3 + +git -C "/Volumes/Dpan/github/water-workspace/water-frontend" log --oneline -5 +``` + +Expected: 后端至少 1 个导出统一提交,前端至少 3 个渐进提交(下载工具、红冲记录、collection 页面)。 + +--- + +## Self-Review + +- **Spec coverage:** + - FR-001/FR-002/FR-011/SC-001/SC-006 → Task 1 + - FR-003/FR-004/FR-005/FR-008/SC-002/SC-003 → Tasks 2-5 + - FR-006/FR-007/SC-004 → Tasks 3-5 通过明确 API 路径落地 + - FR-009/FR-010/FR-012/SC-005 → Task 6 + 提交拆分策略 +- **Placeholder scan:** 已避免使用 TBD/TODO/“类似 Task N”;每个改代码步骤都给了具体代码片段。 +- **Type consistency:** 统一使用 `download.response(...)` 处理后端 blob 响应;前端导出 API 全部基于 `request.download(...)`。 diff --git a/docs/superpowers/plans/2026-06-08-arrearage-reminder-frontend.md b/docs/superpowers/plans/2026-06-08-arrearage-reminder-frontend.md new file mode 100644 index 0000000..e4bab19 --- /dev/null +++ b/docs/superpowers/plans/2026-06-08-arrearage-reminder-frontend.md @@ -0,0 +1,626 @@ +# 催缴登记 (Arrearage Reminder) 前端对接 Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** 将两个前端页面(欠费催缴池 + 催缴记录)从 mock 数据切换到真实后端 API,包括 API 层补齐、催缴表单对接、汇总统计、导出功能。 + +**Architecture:** 后端 9 个接口均已就绪 (`POST /create`, `GET /page`, `GET /pending-page`, `GET /get`, `GET /detail-list`, `POST /batch-create`, `GET /pending-summary`, `GET /pending-export`, `GET /pending-detail-export`)。前端按 "API 层 → 催缴表单 → 欠费池页面 → 催缴记录页面" 的顺序逐层对接,每层完成后可独立验证。 + +**Tech Stack:** Vue 3, TypeScript, Element Plus, Axios (`@/config/axios`), pnpm + +--- + +## File Structure + +### API layer +- Modify: `../water-frontend/src/api/collectionManage/arrears/index.ts` + - 新增所有请求/响应 VO 类型 + 7 个缺失的 API 方法 + +### Components +- Modify: `../water-frontend/src/views/collectionManage/arrears/components/RemindForm.vue` + - 对接 `batchCreate` API,接收父组件传入的选中行数据 + +### Views +- Modify: `../water-frontend/src/views/collectionManage/arrears/index.vue` + - 汇总统计条对接 `getPendingSummary`、导出对接 `getPendingExportList`、催缴按钮传递选中数据给 RemindForm +- Modify: `../water-frontend/src/views/collectionManage/collectionRecord/index.vue` + - 列表对接 `getPage`、详情展开对接 `getDetailList`、导出对接后端(如有对应接口) + - 查询表单字段对齐 `ArrearageReminderPageReqVO` + +--- + +### Task 1: 补齐 API 层 — 类型定义与全部接口方法 + +**Files:** +- Modify: `../water-frontend/src/api/collectionManage/arrears/index.ts` + +- [ ] **Step 1: 添加所有 VO 类型定义和 API 方法** + +```typescript +import request from '@/config/axios' +import download from '@/utils/download' + +// ========== 请求 VO ========== + +export interface ArrearagePendingPageReqVO { + pageNo: number + pageSize: number + deptId?: number + code?: string + name?: string + address?: string + mobile?: string + custStates?: number[] + custType?: number + billMonthStart?: number + billMonthEnd?: number + meterReaderId?: number + bookCode?: string + arrearsCountMin?: number + arrearsCountMax?: number + arrearsAmountMin?: number + arrearsAmountMax?: number + remindFilter?: string +} + +export interface ArrearageReminderPageReqVO { + pageNo: number + pageSize: number + custId?: number + reminderUser?: string + reminderType?: number + reminderReason?: number + reminderResult?: number +} + +export interface ArrearageReminderCreateReqVO { + custId: number + chargeIds: number[] + reminderType: number + reminderReason: number + reminderResult: number + reminderUser: string + reminderTemplate?: number + remark?: string +} + +export interface ArrearageReminderBatchCreateReqVO { + customers: { + custId: number + chargeIds: number[] + }[] + reminderType: number + reminderReason: number + reminderResult: number + reminderUser: string + reminderTemplate?: number + remark?: string +} + +// ========== 响应 VO ========== + +export interface ArrearagePendingPageRespVO { + custId: number + custCode: string + custName: string + custAddress: string + meterCaliber: string + waterNature: string + arrearsCount: number + waterVolume: number + totalAmount: number + penaltyAmount: number + receivableAmount: number + billAmount: number + accountMonthRange: string + custStatus: string + prestoreAmount: number + mobile: string + isRemindedThisMonth: boolean + agreementNo: string + contractNo: string + details: ArrearagePendingChargeDetailRespVO[] +} + +export interface ArrearagePendingChargeDetailRespVO { + chargeId: number + billMonth: string + lastReading: number + currentReading: number + waterVolume: number + billAmount: number + penaltyAmount: number + readingDate: string +} + +export interface ArrearagePendingSummaryRespVO { + custCount: number + arrearsCount: number + waterVolume: number + billAmount: number + penaltyAmount: number + totalAmount: number + receivableAmount: number +} + +export interface ArrearageReminderPageRespVO { + id: number + custId: number + custCode: string + custName: string + reminderType: number + reminderReason: number + reminderUser: string + remark: string + reminderTemplate: number + completeTime: string + pushState: number + pushResults: string + reminderResult: number + batchStamp: string + totalBillWater: number + totalExtendedAmount: number + totalLateFee: number + deposit: number + mobile: string + createTime: string + updateTime: string +} + +export interface ArrearageReminderRespVO extends ArrearageReminderPageRespVO {} + +export interface ArrearageReminderDetailRespVO { + id: number + arrearageReminderId: number + chargeId: number + lateFee: number + createTime: string + updateTime: string +} + +export interface ArrearageReminderCreateRespVO { + id: number + detailCount: number +} + +export interface ArrearageReminderBatchCreateRespVO { + successCount: number + failCount: number + successItems: { custId: number; reminderId: number; detailCount: number }[] + failItems: { custId: number; reason: string }[] +} + +// ========== API 方法 ========== + +export const ArrearsApi = { + // 待催欠费池 + getPendingPage: async (params: ArrearagePendingPageReqVO) => { + return await request.get<{ list: ArrearagePendingPageRespVO[]; total: number }>({ + url: '/business/arrearage-reminder/pending-page', + params + }) + }, + + getPendingSummary: async (params: ArrearagePendingPageReqVO) => { + return await request.get({ + url: '/business/arrearage-reminder/pending-summary', + params + }) + }, + + // 催缴登记 CRUD + create: async (data: ArrearageReminderCreateReqVO) => { + return await request.post({ + url: '/business/arrearage-reminder/create', + data + }) + }, + + batchCreate: async (data: ArrearageReminderBatchCreateReqVO) => { + return await request.post({ + url: '/business/arrearage-reminder/batch-create', + data + }) + }, + + getPage: async (params: ArrearageReminderPageReqVO) => { + return await request.get<{ list: ArrearageReminderPageRespVO[]; total: number }>({ + url: '/business/arrearage-reminder/page', + params + }) + }, + + get: async (id: number) => { + return await request.get({ + url: '/business/arrearage-reminder/get', + params: { id } + }) + }, + + getDetailList: async (reminderId: number) => { + return await request.get({ + url: '/business/arrearage-reminder/detail-list', + params: { reminderId } + }) + }, + + // 导出 + exportPending: async (params: ArrearagePendingPageReqVO) => { + const res = await request.download({ + url: '/business/arrearage-reminder/pending-export', + params + }) + download.response(res, '待催欠费客户.xlsx') + }, + + exportPendingDetail: async (params: ArrearagePendingPageReqVO) => { + const res = await request.download({ + url: '/business/arrearage-reminder/pending-detail-export', + params + }) + download.response(res, '待催欠费明细.xlsx') + } +} +``` + +- [ ] **Step 2: 验证 API 层编译** + +Run: `cd ../water-frontend && npx vue-tsc --noEmit src/api/collectionManage/arrears/index.ts 2>&1 | head -20` +Expected: No type errors + +--- + +### Task 2: RemindForm 对接 batchCreate API + +**Files:** +- Modify: `../water-frontend/src/views/collectionManage/arrears/components/RemindForm.vue` + +- [ ] **Step 1: 重写 RemindForm 脚本,接收选中行 props 并调 batchCreate** + +将 ` + + diff --git a/output/08_planb_network.drawio b/output/08_planb_network.drawio index f807187..2e36e25 100644 --- a/output/08_planb_network.drawio +++ b/output/08_planb_network.drawio @@ -1,150 +1,203 @@ - - - + + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + + + + + + + - - - - - - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - + + - - + + - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - + + + + + + + + + + - - + + + + + + - - - - - + + + + + - + @@ -253,167 +306,4 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/output/11_UP_Detailed.docx b/output/11_UP_Detailed.docx new file mode 100644 index 0000000..ec19378 Binary files /dev/null and b/output/11_UP_Detailed.docx differ diff --git a/output/11_UP_Detailed.html b/output/11_UP_Detailed.html new file mode 100644 index 0000000..7c4b322 --- /dev/null +++ b/output/11_UP_Detailed.html @@ -0,0 +1,240 @@ + + + + + + + + 福建水务营收系统-统一平台模块正文 + + + + + +
    +

    福建水务营收系统-统一平台模块正文

    +

    系统设计团队

    +

    2024年12月19日

    +
    + +

    1 +福建水务营收系统详细设计-统一平台模块正文

    +

    1.1 章节导航(精简)

    + +

    +

    1.2 文档定位

    +

    本文档为 01_Detailed_Design.md +中“统一平台详细设计”章节的模块正文拆分稿,便于按模块独立维护。正式交付口径以主详设为准。

    +

    +

    2 统一平台详细设计

    +

    +

    2.1 UP-001 统一认证与单点登录

    +

    2.1.1 功能说明

    +

    UP-001 为全系统提供统一身份认证与单点登录能力,支撑 PC +管理端、移动作业端、客户渠道及外部集成应用的统一接入。

    +

    2.1.2 关键设计

    +
      +
    1. 支持用户名密码登录、短信验证码登录、第三方授权登录。
    2. +
    3. 采用 OAuth2.0 + JWT 实现访问令牌签发与会话管理。
    4. +
    5. 对外部系统开放标准认证接口,支持令牌续期与退出失效。
    6. +
    7. 对高敏感操作支持 MFA 二次校验。
    8. +
    +

    2.1.3 业务流程

    +
    sequenceDiagram
    +    participant 用户
    +    participant 接入端
    +    participant 认证中心
    +    participant 用户中心
    +
    +    用户->>接入端: 提交登录信息
    +    接入端->>认证中心: 发起认证请求
    +    认证中心->>用户中心: 校验用户/角色/状态
    +    用户中心-->>认证中心: 返回校验结果
    +    认证中心-->>接入端: 返回Token/权限上下文
    +    接入端-->>用户: 登录成功并进入目标系统
    +
    +

    2.1.4 核心数据

    +
      +
    • system_users:用户基本信息。
    • +
    • system_oauth2_client:客户端信息。
    • +
    • system_oauth2_access_token:访问令牌。
    • +
    • system_oauth2_refresh_token:刷新令牌。
    • +
    • system_login_log:登录审计日志。
    • +
    +

    +

    2.2 UP-002 组织用户与权限管理

    +

    2.2.1 功能说明

    +

    UP-002 +管理组织机构、岗位、角色、菜单、数据权限和用户授权关系,是业务系统权限控制与数据隔离的基础。

    +

    2.2.2 关键设计

    +
      +
    1. 支持集团—区域公司—营业所三级及以上组织结构。
    2. +
    3. 基于 RBAC 实现菜单权限、按钮权限、数据权限。
    4. +
    5. 支持多租户/多单位数据隔离与用户归属控制。
    6. +
    7. 敏感操作如账务调整、退款、作废、签章回退必须经过权限校验。
    8. +
    +

    2.2.3 主要规则

    +
      +
    • 角色权限与组织权限叠加生效。
    • +
    • 业务数据默认按所属单位、片区、岗位范围过滤。
    • +
    • 超权限查询、批量导出、敏感字段查看需单独授权。
    • +
    +

    +

    2.3 UP-003 参数字典与基础配置

    +

    2.3.1 功能说明

    +

    UP-003 +用于统一维护业务参数、地址参数、水价规则、短信模板、打印模板、字典数据与定时任务参数。

    +

    2.3.2 关键设计

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    配置类别典型内容用途
    业务字典客户类型、抄表方式、工单状态统一编码与展示
    地址参数行政区划、片区、册本归属客户与表务归属管理
    价格体系用水性质、阶梯水价、污水费规则开账与账务计算
    渠道参数支付渠道、短信模板、税控配置外部接口集成
    任务参数自动开账、对账、备份周期运维调度
    +

    +

    2.4 UP-004 审计监控与运维支撑

    +

    2.4.1 功能说明

    +

    UP-004 +提供操作日志、登录日志、接口日志、异常监控、在线用户、任务监控、性能监控等能力。

    +

    2.4.2 关键设计

    +
      +
    1. 所有核心业务操作写入统一审计日志。
    2. +
    3. 接口调用成功率、响应时长、异常码进入监控平台。
    4. +
    5. 定时任务执行结果、失败重试与人工补偿过程可追踪。
    6. +
    7. 监控与告警支持短信、邮件、站内信等通知方式。
    8. +
    + + diff --git a/output/11_UP_Detailed.pdf b/output/11_UP_Detailed.pdf new file mode 100644 index 0000000..2c8d97d Binary files /dev/null and b/output/11_UP_Detailed.pdf differ diff --git a/output/11_UP_Detailed_processed.md b/output/11_UP_Detailed_processed.md new file mode 100644 index 0000000..8455617 --- /dev/null +++ b/output/11_UP_Detailed_processed.md @@ -0,0 +1,139 @@ +--- +title: "11_UP_Detailed" +author: "系统设计团队" +date: "2024年12月19日" +documentclass: article +geometry: margin=1in +fontsize: 11pt +mainfont: "PingFang SC" +CJKmainfont: "PingFang SC" +--- + +--- +doc_id: DT-11-UP +doc_role: module_body +authority: secondary +scope: 详细设计-统一平台 +source_of_truth: false +last_reviewed: 2026-03-11 +retrieval_priority: P1 +--- + +# 福建水务营收系统详细设计-统一平台模块正文 + +## 章节导航(精简) + +- [文档定位](#sec-position) +- [统一平台详细设计正文](#sec-content) + - [UP-001 统一认证与单点登录](#mod-up-001) + - [UP-002 组织用户与权限管理](#mod-up-002) + - [UP-003 参数字典与基础配置](#mod-up-003) + - [UP-004 审计监控与运维支撑](#mod-up-004) + + + +## 文档定位 + +本文档为 `01_Detailed_Design.md` 中“统一平台详细设计”章节的模块正文拆分稿,便于按模块独立维护。正式交付口径以主详设为准。 + + + +# 统一平台详细设计 + + + +## UP-001 统一认证与单点登录 + +### 功能说明 + +UP-001 为全系统提供统一身份认证与单点登录能力,支撑 PC 管理端、移动作业端、客户渠道及外部集成应用的统一接入。 + +### 关键设计 + +1. 支持用户名密码登录、短信验证码登录、第三方授权登录。 +2. 采用 OAuth2.0 + JWT 实现访问令牌签发与会话管理。 +3. 对外部系统开放标准认证接口,支持令牌续期与退出失效。 +4. 对高敏感操作支持 MFA 二次校验。 + +### 业务流程 + + +```mermaid +sequenceDiagram + participant 用户 + participant 接入端 + participant 认证中心 + participant 用户中心 + + 用户->>接入端: 提交登录信息 + 接入端->>认证中心: 发起认证请求 + 认证中心->>用户中心: 校验用户/角色/状态 + 用户中心-->>认证中心: 返回校验结果 + 认证中心-->>接入端: 返回Token/权限上下文 + 接入端-->>用户: 登录成功并进入目标系统 + +``` + + +### 核心数据 + +- `system_users`:用户基本信息。 +- `system_oauth2_client`:客户端信息。 +- `system_oauth2_access_token`:访问令牌。 +- `system_oauth2_refresh_token`:刷新令牌。 +- `system_login_log`:登录审计日志。 + + + +## UP-002 组织用户与权限管理 + +### 功能说明 + +UP-002 管理组织机构、岗位、角色、菜单、数据权限和用户授权关系,是业务系统权限控制与数据隔离的基础。 + +### 关键设计 + +1. 支持集团—区域公司—营业所三级及以上组织结构。 +2. 基于 RBAC 实现菜单权限、按钮权限、数据权限。 +3. 支持多租户/多单位数据隔离与用户归属控制。 +4. 敏感操作如账务调整、退款、作废、签章回退必须经过权限校验。 + +### 主要规则 + +- 角色权限与组织权限叠加生效。 +- 业务数据默认按所属单位、片区、岗位范围过滤。 +- 超权限查询、批量导出、敏感字段查看需单独授权。 + + + +## UP-003 参数字典与基础配置 + +### 功能说明 + +UP-003 用于统一维护业务参数、地址参数、水价规则、短信模板、打印模板、字典数据与定时任务参数。 + +### 关键设计 + +| 配置类别 | 典型内容 | 用途 | +|---|---|---| +| 业务字典 | 客户类型、抄表方式、工单状态 | 统一编码与展示 | +| 地址参数 | 行政区划、片区、册本归属 | 客户与表务归属管理 | +| 价格体系 | 用水性质、阶梯水价、污水费规则 | 开账与账务计算 | +| 渠道参数 | 支付渠道、短信模板、税控配置 | 外部接口集成 | +| 任务参数 | 自动开账、对账、备份周期 | 运维调度 | + + + +## UP-004 审计监控与运维支撑 + +### 功能说明 + +UP-004 提供操作日志、登录日志、接口日志、异常监控、在线用户、任务监控、性能监控等能力。 + +### 关键设计 + +1. 所有核心业务操作写入统一审计日志。 +2. 接口调用成功率、响应时长、异常码进入监控平台。 +3. 定时任务执行结果、失败重试与人工补偿过程可追踪。 +4. 监控与告警支持短信、邮件、站内信等通知方式。 + diff --git a/output/12_REV_Detailed.docx b/output/12_REV_Detailed.docx new file mode 100644 index 0000000..9c4ade8 Binary files /dev/null and b/output/12_REV_Detailed.docx differ diff --git a/output/12_REV_Detailed.html b/output/12_REV_Detailed.html new file mode 100644 index 0000000..3b192d6 --- /dev/null +++ b/output/12_REV_Detailed.html @@ -0,0 +1,1299 @@ + + + + + + + + 福建水务营收系统-营收业务模块正文 + + + + + +
    +

    福建水务营收系统-营收业务模块正文

    +

    系统设计团队

    +

    2024年12月19日

    +
    + +

    1 +福建水务营收系统详细设计-营收业务模块正文

    +

    1.1 章节导航(精简)

    + +

    +

    1.2 文档定位

    +

    本文档为 01_Detailed_Design.md +中“营收业务详细设计”章节的模块正文拆分稿,便于按模块独立维护。正式交付口径以主详设为准。

    +

    +

    2 营收业务详细设计

    +

    +

    2.1 营收模块统一约束

    +
      +
    1. SYS-002 +负责营收主流程,发票、支付结算、消息触达分别通过 +SYS-008SYS-009SYS-010 +协同完成,外部系统仅回写结果状态。
    2. +
    3. 账单、收费、发票、代扣等关键状态变更必须通过业务流程驱动,不允许绕过业务校验直接改写主业务对象。
    4. +
    5. 幂等控制遵循接口主键约束:支付以业务订单号为主,发票以申请单号或账单组合为主,代扣以批次号为主,消息以业务事件号为主。
    6. +
    7. 账务调整、发票申请、催缴触达、银行批次下发等关键动作必须写入操作留痕,满足审计与问题追踪要求。
    8. +
    9. 数据口径统一采用 biz_*bk_* +命名体系,历史命名仅用于追溯,不作为本章节正式设计口径。
    10. +
    +

    +

    2.2 接口与数据追溯矩阵

    +
    +

    说明:详细字段与报文以 +../03_Technical_Design/03_Interface_Design.md +为准,数据库字段口径以 +../03_Technical_Design/01_Database_Design.md 为准。

    +
    + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    REV 模块关键接口核心数据域(摘要)主要协同对象
    REV-001 客户资料管理IF-REV-001biz_custbiz_accountbiz_cust_*客户服务模块、报装模块
    REV-002 抄表开账IF-REV-004IF-REV-005biz_meter_bookbiz_meter_readbiz_reading_*biz_charge*抄表APP、物联网集抄
    REV-003 营业收费IF-REV-006biz_charge*biz_collectionbk_transaction*SYS-009
    REV-004 账务处理IF-REV-007biz_charge*biz_operat_log*财务与营业人员
    REV-005 发票与税务处理IF-REV-008biz_invoice*biz_cust_invoiceSYS-008
    REV-006 催缴与通知IF-REV-013biz_charge*、催缴结果留痕SYS-010
    REV-007 统计分析IF-REV-010客户、抄表、收费、渠道聚合对象统计分析端
    REV-008 代收与银行业务IF-REV-011bk_withholding_*bk_reconcile_*bk_settlement_*SYS-009、银行
    REV-009 业务参数配置IF-REV-012biz_parameter_settingsbiz_page_settings*biz_price_*统一平台、营收模块
    +

    +

    2.3 REV-001 客户资料管理

    +

    2.3.1 功能说明

    +

    负责客户主档、账户主档、联系人、客户分组、客户与水表关系、客户开票信息、客户渠道绑定及托收/代扣关系维护,是抄表、收费、发票、代扣等后续业务的主数据基础。

    +

    2.3.2 关键设计

    +
      +
    1. 客户建档覆盖立户、变更、更名、过户、销户、报停等全生命周期处理。
    2. +
    3. 客户资料支持按客户类型、用水性质、片区、集团客户、重点客户等维度管理。
    4. +
    5. 客户与水表、开票主体、托收/代扣签约关系按关联表维护,避免在主表中堆叠多类属性。
    6. +
    7. 客户编号、集收标记、计划用水方案等规则类数据由统一配置与客户关系表共同支撑。
    8. +
    +

    2.3.3 核心数据

    +
      +
    • biz_cust:客户主档。
    • +
    • biz_account:客户账户与账户状态。
    • +
    • biz_cust_contact:联系人及联系方式。
    • +
    • biz_cust_group:客户分组。
    • +
    • biz_cust_meter:客户与水表绑定关系。
    • +
    • biz_cust_invoice:客户开票信息。
    • +
    • biz_cust_app_binds:渠道绑定关系。
    • +
    • biz_cust_collection_rel:客户托收关系。
    • +
    • biz_cust_withholding_rel:客户代扣关系。
    • +
    • biz_cust_water_use_schemebiz_cust_water_scheme_rel:客户计划用水方案关系。
    • +
    • biz_cust_no_rule:客户编号规则。
    • +
    • biz_cust_hub_marks:集收号/集收标记关系。
    • +
    +

    2.3.4 迁移补充(旧系统承接)

    +

    2.3.4.1 定额共享

    +
      +
    • 旧系统在“客户资料”下提供定额主客户、子客户绑定与共享清单管理能力。
    • +
    • 当前正式设计不新增并行主模型,统一归入客户与计划用水方案关系对象承接。
    • +
    • 迁移时必须至少保留主客户、子客户、绑定状态、生效时间、解除时间、备注与操作留痕,确保共享清单可查询、可解绑、可追溯。
    • +
    +

    2.3.4.2 定额核定

    +
      +
    • 旧系统支持对已建立共享关系的客户执行定额核定、撤销核定和共享清单联查。
    • +
    • 当前建议以客户关系对象和计划用水方案关系为主承接核定结果,不额外发明独立账务主表。
    • +
    • 核定结果迁移后应支持按客户、站点、核定状态、核定时间查询,并保留核定依据、操作人和变更留痕。
    • +
    +

    2.3.4.3 批量修改

    +
      +
    • 旧系统已形成“手工修改 + 模板导入修改”的双模式客户资料维护能力。
    • +
    • 当前正式设计应将其视为客户主数据治理能力的一部分,而不是临时导入工具。
    • +
    • 迁移时需明确三类口径:可批量修改字段范围、导入模板校验规则、批量修改审计留痕;历史批量修改结果至少需保留任务来源、修改字段、执行结果和失败原因。
    • +
    +

    2.3.5 接口映射

    +
      +
    • IF-REV-001:客户档案、账户状态、联系人与水表绑定关系查询。
    • +
    • IF-CS-001IF-CS-002:客户服务侧账户绑定与信息查询场景复用客户域数据。
    • +
    +

    2.3.6 落地边界

    +
      +
    • 已落地:客户主档、账户、联系人、分组、绑定、开票、托收/代扣关系。
    • +
    • 部分落地:客户扩展关系、集收与规则类对象已见明确关系表,但具体业务场景仍需结合流程进一步细化。
    • +
    • 文档先行:主副卡、部分复杂客户关系对象在当前 +backend 中未见完全独立表族,文档中仅保留业务对象表述。
    • +
    +

    +

    2.4 REV-002 抄表开账

    +

    2.4.1 功能说明

    +

    负责抄表计划、册本管理、抄表录入、抄表状态跟踪、异常复核、计费计算与账单生成,是营收核心处理链路的起点。

    +

    2.4.2 业务流程

    +
    flowchart TD
    +    A[制定抄表计划] --> B[生成抄表册本]
    +    B --> C[分配抄表任务]
    +    C --> D[人工/远传/自报抄表]
    +    D --> E[数据校验]
    +    E --> F{是否异常}
    +    F -->|是| G[异常复核处理]
    +    F -->|否| H[生成开账数据]
    +    G --> H
    +    H --> I[按价格模板与费用组成计费]
    +    I --> J[生成营业账与明细]
    +    J --> K[账单审核确认]
    +    K --> L[进入收费/催缴/开票]
    +
    +

    2.4.3 关键规则

    +
      +
    1. 抄表数据同时校验本次读数、上次读数、用量波动和抄表状态,只有通过校验或完成异常复核的数据才能进入开账。
    2. +
    3. 异常抄表支持估抄、补抄、重录、人工复核;异常处理的目标是形成可继续开账或明确阻断的统一结论,而不是绕开开账规则单独落账。
    4. +
    5. IF-REV-005 +的正式边界是“抄表校验完成后的账单生成”,不负责收费核销、发票开具、催缴执行和统计分析。
    6. +
    7. 开账计费按价格归属、价格模板、费用组成、阶梯规则、计划用水方案综合计算;价格配置缺失、费用组成不完整或规则冲突时,必须阻断生成并返回失败原因。
    8. +
    9. 账单生成结果统一由 biz_charge 与 +biz_charge_detail +承接:主表表达客户、账期、应收日期、账单总金额和主状态,明细表表达费用组成、用量、单价和明细金额。
    10. +
    11. 特殊开账、无码客户开账、罚款类开账等非标准来源,仍纳入同一营业账主明细模型承接,通过来源类型、业务类型、依据说明和操作留痕区分,不单独扩展平行账表。
    12. +
    13. 审核通过后的营业账方可进入收费、催缴和发票流程;后续链路只能消费已生成账单结果,不反向改变本接口的生成边界。
    14. +
    15. 远传抄表数据可由 SYS-006 / IoT +能力提供采集支撑,但账单生成仍归属 SYS-002。
    16. +
    +

    2.4.4 开账触发与结果表达

    +
      +
    • 触发前提:正式口径下可按抄表批次、指定客户范围或指定抄表任务范围组织生成;当前 +backend 已落地的入口为按 readingDataIds +批量复核并开账,对应 +ChargeController.generateCheckChargeBatchChargeServiceImpl.generateCheckChargeBatch +与 ReadingDataServiceImpl.batchReCheckReadingData
    • +
    • 规则来源:价格归属决定客户适用的价格口径;价格模板、阶梯规则、费用组成和计划用水方案共同决定营业账主表金额与明细拆分方式。
    • +
    • 当前承接证据:ChargeServiceImpl.generateSingleChargeWithCache +成功路径会写入 biz_charge 主表、循环写入 +biz_charge_detail +明细,并回写抄表数据开账状态,说明现有实现已具备“按抄表数据 ID +生成营业账主明细”的 backend 基础。
    • +
    • 结果表达:正式 IF-REV-005 +应返回成功清单、失败清单、生成汇总及主明细级结果;当前 backend +返回仍为“本次复核成功X条 / +本次开账成功Y条”的字符串拼接,尚未形成结构化成功/失败结果对象。
    • +
    • 阻断与限制:价格模板不存在、费用调整配置缺失、结算方式非 +ACTUAL_USAGE +等场景当前会直接阻断单条生成;其中固定水量、按人口数、最低消费等非实际水量结算方式仍未纳入当前实现。
    • +
    • 下游边界:REV-002 +只负责生成营业账结果并交由后续审核/收费链路消费,不在本章节扩展收费核销、发票申请或催缴执行细节。
    • +
    +

    2.4.5 核心数据

    +
      +
    • biz_meter_book:册本与抄表计划。
    • +
    • biz_meter_read:抄表任务状态/执行状态。
    • +
    • biz_reading_data:抄表数据。
    • +
    • biz_last_reading:上次抄表结果。
    • +
    • biz_reading_logs:抄表日志与过程留痕。
    • +
    • biz_meter:计量水表主档引用。
    • +
    • biz_charge:营业账主表。
    • +
    • biz_charge_detail:营业账明细。
    • +
    • biz_price_category:价格归属。
    • +
    • biz_price_template:价格模板。
    • +
    • biz_price_adjustment_snap:调价快照。
    • +
    • biz_price_tier_adjustment:阶梯规则。
    • +
    • biz_cost_component:费用组成。
    • +
    • biz_water_use_schemebiz_water_use_scheme_tier:计划用水方案与阶梯。
    • +
    +

    2.4.6 迁移补充(旧系统承接)

    +

    2.4.6.1 特殊开账

    +
      +
    • 旧系统支持在非标准客户、无码客户或罚款类场景下直接开账。
    • +
    • 新系统仍以 biz_chargebiz_charge_detail +作为开账结果承载对象,不建议额外平行建设“特殊开账账表”。
    • +
    • 迁移与新建场景均需保留特殊开账来源、业务类型、经办人、依据说明、打印状态与后续收费关联,避免与普通抄表开账混淆。
    • +
    +

    2.4.6.2 开账记录迁移

    +
      +
    • 旧系统“开账记录”是历史查询与账务核对的核心入口,必须纳入迁移最小保留集。
    • +
    • 迁移后的开账记录应至少支持按站点、账务年月、册本、客户、抄表员、欠费状态查询,并支持统计水量、总金额及费用构成。
    • +
    • 对已收费、已作废、销户拆表、特殊开账等旧状态,不要求照搬旧表结构,但必须保留可对照的新状态映射关系。
    • +
    +

    2.4.7 接口映射

    +
      +
    • IF-REV-004:抄表数据提交与异常标记。
    • +
    • IF-REV-005:账单生成与开账结果返回。
    • +
    • IF-METER-004:远传抄表数据接收后进入开账流程。
    • +
    +

    2.4.8 落地边界

    +
      +
    • 已落地:册本、抄表数据、上次抄表、抄表日志、营业账主明细、价格模板与阶梯规则。
    • +
    • 部分落地:部分异常场景对象可能仍通过状态字段和日志表承载,而非全部拆成独立业务表。
    • +
    • 文档先行:个别精细稽查、轨迹、下载同步对象当前未在本轮映射中确认为独立表。
    • +
    +

    +

    2.5 REV-003 营业收费

    +

    2.5.1 功能说明

    +

    支持柜台收费、预存款/余额抵扣、线上缴费回写、柜面扫码、营业网点收费及收费凭证管理,统一承接营收账单的核销处理。

    +

    2.5.2 业务流程

    +
    flowchart TD
    +    A[查询客户及待缴账单] --> B[选择账单与核销方式]
    +    B --> C[选择支付渠道]
    +    C --> D{支付方式}
    +    D -->|柜台现金/POS/扫码| E[现场收费]
    +    D -->|微信/支付宝/聚合支付| F[渠道下单]
    +    D -->|预存款/余额抵扣| G[账户余额核销]
    +    E --> H[更新营业账状态]
    +    F --> I[等待异步回调确认]
    +    G --> H
    +    I --> H
    +    H --> J[生成收费记录与凭证]
    +    J --> K[进入发票/对账流程]
    +
    +

    2.5.3 关键规则

    +
      +
    1. 一次缴费可对应多个账单或账单明细的组合核销。
    2. +
    3. 收费记录必须保留渠道、流水号、网点、操作员、终端信息。
    4. +
    5. 线上支付必须以回调或查询确认结果为准,不得以发起状态直接记账。
    6. +
    7. 支付能力由 SYS-009 提供,SYS-002 +负责账单核销与业务状态回写。
    8. +
    9. 当前实现侧已确认 PayCeb +的欠费查询、缴费处理基础闭环可用,但代理收费对账仍为预留能力;正式文档不得将实时收费对账写成已闭环能力。
    10. +
    +

    2.5.4 核心数据

    +
      +
    • biz_chargebiz_charge_detail:待缴与已缴账单主明细。
    • +
    • biz_collection:托收/代收主表。
    • +
    • biz_withholding:代扣/托收主表。
    • +
    • bk_transaction:渠道交易流水。
    • +
    • bk_transaction_callback:支付回调记录。
    • +
    • bk_transaction_exception:支付异常记录。
    • +
    +

    2.5.5 迁移补充(旧系统承接)

    +

    2.5.5.1 柜台结账

    +
      +
    • 旧系统将“柜台收费”和“柜台结账”拆分为两个菜单,结账阶段包含未结/已结查询、结账红冲、追加抄表和打印动作。
    • +
    • 当前设计可继续采用统一收费核销模型,但必须补出“收费记录 → 班结结果 → +打印/红冲/查询”的业务闭环,避免柜面日终处理缺口。
    • +
    • 迁移时需保留结账时间、结账人、网点、收费汇总口径和结账后红冲痕迹,保证财务对账与审计连续。
    • +
    +

    2.5.5.2 账单打印服务

    +
      +
    • 旧系统存在账单打印、补打、打印次数控制与打印记录查询能力。
    • +
    • 新系统不要求单独建立打印主模块,但必须明确打印模板、补打权限、打印状态与打印留痕的承接关系。
    • +
    • 对历史账单迁移,应允许基于账单主明细和打印配置恢复打印视图,避免割接后只能查账不能补打。
    • +
    +

    2.5.5.3 红冲记录

    +
      +
    • 旧系统支持红冲记录查询、导出与明细展开,是收费差错追溯的重要入口。
    • +
    • 当前设计可将红冲视为收费核销后的修正场景,不强制要求独立实体表,但必须提供历史只读查询口径。
    • +
    • 红冲迁移最小保留信息应包括原收费记录、红冲时间、红冲金额、原因、经办人、关联账单和后续账务状态。
    • +
    +

    2.5.6 接口映射

    +
      +
    • IF-REV-006:创建收费记录、执行账单核销并回写状态。
    • +
    • IF-CS-003IF-CS-007:客户渠道与柜面扫码支付场景复用收费核销链路。
    • +
    +

    2.5.7 落地边界

    +
      +
    • 已落地:营业账主明细、交易流水、回调、异常、托收/代扣主对象。
    • +
    • 部分落地:柜台班结、部分收费汇总类对象可能通过业务流程与报表实现,不一定存在独立表。
    • +
    • 文档先行:部分红冲、实时收费汇总类台账暂不表述为已确认独立实体表。
    • +
    +

    +

    2.6 REV-004 账务处理

    +

    2.6.1 功能说明

    +

    REV-004 +一期仅覆盖水量调整、金额调整、退款、冲正、坏账申请五类场景,统一挂靠 +IF-REV-007 +作为账务处理入口,目标是在既有正式文档体系内先收敛范围、承接口径、留痕要求与审批边界。

    +

    本阶段按“共性能力先统一、场景能力再分批”组织:先统一账单承接、原交易校验、结果表达、操作留痕与审批边界,再分别展开五类场景。违约金减免、分账调整、价差调整、跨周期水量、预存退款细表等内容仅作为旧系统迁移语义或后续扩展参考,不作为一期新增独立范围。

    +

    2.6.2 业务流程

    +
    flowchart TD
    +    A[发起账务调整申请] --> B[校验账单状态与权限]
    +    B --> C{是否通过}
    +    C -->|否| D[驳回并记录原因]
    +    C -->|是| E[执行重算或退款冲正]
    +    E --> F[更新账单与明细状态]
    +    F --> G[写入操作日志与审批留痕]
    +    G --> H[返回处理结果]
    +
    +

    2.6.3 关键规则

    +
      +
    1. 一期场景严格限定为水量调整、金额调整、退款、冲正、坏账申请,不扩展到其他接口族或独立账务台账重构。
    2. +
    3. 所有场景均以 biz_charge / +biz_charge_detail 为主承接对象,并通过 +biz_operat_log / biz_operat_log_detail +记录处理依据、前后变化和责任归属。
    4. +
    5. 退款、冲正必须联动 +bk_transactionbk_transaction_callbackbk_transaction_exception +等原支付流水及渠道状态校验,不允许仅依据账单状态直接处理。
    6. +
    7. 接口结果统一返回 +resultStatuswriteBackStatus,其中 +resultStatus 表示处理结论,writeBackStatus +表示账单状态回写结论,两者不得混用。
    8. +
    9. 审批相关内容一期仅保留 +approvalRequiredPENDING_APPROVAL +与审批边界说明,不展开完整 BPM +流程、节点、流转规则或审批回写实现细节。
    10. +
    11. 对于当前未见明确独立实体表的特账、跨周期水量、退款账等对象,文档以“业务处理场景”表述,不强行落为已实现表。
    12. +
    +

    2.6.4 核心数据

    +
      +
    • biz_chargebiz_charge_detail:账务调整的核心对象,承接调整前后账单主明细状态。
    • +
    • bk_transactionbk_transaction_callbackbk_transaction_exception:退款、冲正场景的原交易校验与异常追溯对象。
    • +
    • 价格调整/优惠相关表:用于重算账单或差额追溯。
    • +
    • biz_operat_logbiz_operat_log_detail:操作与变更留痕,记录字段差异、处理说明、附件依据与责任归属。
    • +
    +

    2.6.5 主要场景

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    场景说明控制要点
    水量调整更正异常水量需复核原因、附件和原抄表依据
    金额调整更正账单金额需记录依据、差异金额和审批边界
    退款退回客户支付资金或预存款需校验原交易、退款余额与幂等性
    冲正修正误收/误核销记录需关联原交易与账单状态
    坏账申请对长期欠费进行分类处理需结合账龄、客户状态与审批边界
    +

    2.6.6 迁移补充(旧系统承接)

    + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    旧账务对象当前承接方式迁移口径
    预存退款 / 预存退款详情作为账务处理场景承接保留申请单、原支付引用、退款结果与审批留痕
    已销调整汇总 / 明细作为已收费后修正场景承接保留原账单、调整原因、前后差异、处理结果
    价差调整汇总 / 明细作为重算与差额修正场景承接保留原价格口径、新价格口径、差额和生效时间
    分账调整汇总 / 明细作为费用组成重分摊场景承接保留原分摊结果、调整后结果、责任人和审批链
    账单-违约金减免作为滞纳金修正场景承接保留减免原因、减免金额、审批结果和生效时间
    账单-呆坏账作为坏账申请与生效场景承接保留账龄、申请原因、审批结果、核销状态
    +
      +
    1. P0 +阶段不要求为每一类旧账务台账都新增独立实体表,但必须在业务对象和历史查询层形成可追溯闭环。
    2. +
    3. 旧系统精细台账迁移后至少保留:原单据标识、原账单标识、处理类型、处理原因、处理前后金额/水量、申请/审批/生效时间、经办人与附件依据。
    4. +
    5. 与支付、发票、渠道回调强关联的处理场景,必须保留与原交易、原发票、原收费记录的关联关系,避免后续对账和审计断链。
    6. +
    +

    2.6.7 接口映射

    +
      +
    • IF-REV-007:账务调整、退款、冲正、坏账等处理入口。
    • +
    • IF-REV-006:与收费核销状态联动,确保调账后账单状态一致。
    • +
    +

    2.6.8 落地边界

    +
      +
    • 已落地:营业账主明细、操作日志、价格/方案相关重算支撑。
    • +
    • 部分落地:精细化账务对象更多表现为流程与场景,并未在 +backend 中全部体现为独立表族。
    • +
    • 文档先行:特账、退款账、跨周期水量等对象保留业务语义,不宣称为已实现独立表。
    • +
    +

    +

    2.7 REV-005 发票与税务处理

    +

    2.7.1 功能说明

    +

    负责发票业务闭环的业务接入与状态落账,覆盖后台发票申请、开票校验、SYS-008 +异步协同、查询兜底、结果回写、账单关联、客户侧已开票电子发票查询/下载/推送,以及后台作废与红冲处理。

    +

    2.7.2 业务流程

    +
    flowchart TD
    +    A[后台提交发票申请] --> B[校验账单、客户开票信息、税率与限额]
    +    B --> C{是否满足开票条件}
    +    C -->|否| D[返回不可开票原因]
    +    C -->|是| E[生成申请单号并写入SUBMITTED]
    +    E --> F[调用SYS-008发起异步开票]
    +    F --> G[记录受理号并转为PENDING]
    +    G --> H[系统轮询或后台查询兜底]
    +    H --> I{开票结果}
    +    I -->|成功| J[回写SUCCESS并更新账单-发票关联]
    +    I -->|失败| K[回写FAIL并记录失败原因]
    +    J --> L[客户侧查询/下载/推送电子发票]
    +
    +

    2.7.3 状态说明

    +
      +
    • SUBMITTED:后台申请已受理,已完成本地校验并生成申请单。
    • +
    • PENDING:已提交 +SYS-008,等待异步结果或查询补偿结果。
    • +
    • SUCCESS:已取得有效发票代码、号码或电子票地址,且账单关联已完成更新。
    • +
    • FAIL:开票失败,需保留失败原因、最近查询结果与后续人工核查依据。
    • +
    • INVALID:发票已作废,作为后续能力预留状态。
    • +
    • RED_INK:发票已红冲,作为后续能力预留状态。
    • +
    +

    2.7.4 关键规则

    +
      +
    1. 一期采用“后台申请开票 + +客户侧查询下载推送”的入口模式,客户侧不直接发起开票申请。
    2. +
    3. 发票申请以客户信息、已收费未开票账单、税率配置和开票限额为基础;原始单账单不支持直接任意部分金额开票。
    4. +
    5. 个人与企业开票均通过客户开票信息与税率表完成合法性校验;如需多张发票,沿用拆账/分账后的账单分别开票口径。
    6. +
    7. SYS-008 采用“异步申请 + +查询兜底”模式,成功状态不得被后续失败查询结果覆盖。
    8. +
    9. 电子发票仅在 SUCCESS +且存在票据文件地址时允许客户侧下载或推送。
    10. +
    11. 发票作废、红冲仍由 SYS-008 +统一承接税控侧处理,SYS-002 +负责后台触发入口、状态校验、查询补偿、结果落账与日志留痕;当前轮次按二期范围补齐 +backend 实现入口。
    12. +
    +

    2.7.5 后台申请入口与校验补充

    +
      +
    • 后台支持营业收费员、财务人员按单笔或批量已收费账单发起开票申请。
    • +
    • 申请时至少校验:账单收费状态、开票状态、客户开票信息完整性、票种适配性、开票限额、账单集合是否属于同一客户。
    • +
    • 企业抬头场景重点校验纳税人识别号;电子发票场景重点校验邮箱/手机号;不满足条件时直接返回不可开票原因。
    • +
    • 申请成功后生成申请单号并进入 SUBMITTED/PENDING +状态流转,失败校验场景不进入外部协同。
    • +
    • 幂等控制以 applicationNo 或 +custId + chargeIds 为主,避免相同账单组合重复申请。
    • +
    +

    2.7.6 SYS-008 +异步协同与查询补偿

    +
      +
    • 本地申请校验通过后,SYS-002 先写入 +biz_invoice 申请记录,再向 SYS-008 +发起异步开票请求,并记录 sysRequestNo +作为后续查询与回写的协同主键。
    • +
    • SYS-008 返回“已受理”后,发票状态转为 +PENDING;若仅完成本地受理但尚未拿到受理号,则保留 +SUBMITTED 并进入待补偿查询状态。
    • +
    • 查询补偿采用“回写优先、主动查询兜底”原则:IF-EXT-007 +回写为首选结果来源,后台人工查询与系统定时补偿查询共用同一结果落账逻辑。
    • +
    • 系统补偿查询至少保留最近查询时间、下次计划查询时间、累计查询次数、最近一次返回结果摘要与异常原因,便于问题追踪和人工核查。
    • +
    • 后台按申请单号或受理号触发查询时,应同步刷新查询上下文;查询仍未取得终态时,仅更新补偿上下文,不得伪造成功或失败结论。
    • +
    +

    2.7.7 终态保护与异常核查

    +
      +
    • SUCCESS +属于正常开票闭环终态,一旦已取得有效发票代码、发票号码或电子票据地址,后续失败查询结果不得覆盖成功状态。
    • +
    • FAIL 仅在 SYS-008 +明确返回失败结论或多次补偿查询确认失败时写入,并同步保留失败原因、最近查询结果与人工核查依据。
    • +
    • 当后台人工查询、系统补偿查询与外部回写结果不一致时,应以最新有效外部凭据为准,并记录差异说明,不允许直接覆盖既有成功票据关键信息。
    • +
    • 每次提交协同、主动查询、状态变更和异常分支均应写入操作留痕,确保能够追溯责任人、触发来源、状态前后值与异常说明。
    • +
    +

    2.7.8 +结果回写、账单关联与客户侧消费

    +
      +
    • IF-EXT-007 回写成功结果时,除更新 +biz_invoice.invoice_statusinvoice_codeinvoice_numberfile_url +外,还应同步刷新账单快照、账单关联状态与推送状态初值。
    • +
    • 账单关联以 biz_invoice.charge_id + +charge_ids_snapshot 记录本次开票覆盖账单集合,并同步把对应 +biz_charge.invoice_state +更新为“开票完成”,保留失败原因与开票时间,便于账单明细、收费记录和客户侧结果统一展示。
    • +
    • 客户侧查询仅允许按本人 custId +访问已存在的发票记录;可通过 +invoiceIdapplicationNo 或 +sysRequestNo 定位,但都必须命中同一客户名下记录。
    • +
    • 客户侧下载与推送前必须校验发票状态为 SUCCESS 且 +fileUrl +非空;不满足条件时仅返回不可下载/推送原因,不得伪造文件地址。
    • +
    • 推送动作应记录推送渠道、目标邮箱/手机号与结果状态;成功后更新 +pushStatus=PUSHED,失败则写入 FAIL +并保留失败原因供人工处理。
    • +
    +

    2.7.9 核心数据

    +
      +
    • biz_invoice:发票主记录。
    • +
    • biz_invoice_taxrate:税率配置。
    • +
    • biz_cust_invoice:客户开票信息。
    • +
    +

    2.7.10 迁移补充(旧系统承接)

    +
      +
    • 旧系统数据字典中存在“发票明细表、营业账开票表、开票配置表”等更细粒度对象。
    • +
    • 当前正式设计已明确主承接对象为 +biz_invoicebiz_invoice_taxratebiz_cust_invoice,但迁移时不能忽略旧开票明细和账单关联关系。
    • +
    • P0 +阶段建议先补三类迁移口径:账单与发票的关联关系、发票申请与结果回写记录、开票配置与税率的有效期;未确认已落地的细表对象仍按“历史只读或辅助映射”处理。
    • +
    +

    2.7.11 接口映射

    +
      +
    • IF-REV-008:后台发票申请接口,负责单笔/批量申请、幂等控制与受理号生成。
    • +
    • IF-REV-009:发票结果查询接口,负责后台按申请单号/受理号查询以及系统补偿查询。
    • +
    • IF-CS-004:客户侧电子发票消费接口,负责已开票结果查看、下载、推送。
    • +
    • IF-EXT-007:发票结果回写协同接口(由发票服务侧回传)。
    • +
    +

    2.7.12 落地边界

    +
      +
    • 已落地:发票主记录、税率配置、客户开票信息,以及一期正常开票闭环所需的后台申请、查询兜底、结果回写、账单关联与客户侧电子发票消费能力。
    • +
    • 部分落地:发票修改、开票过程留痕在后端中已有相关对象,但整套发票明细/批次类对象尚未全部确认。
    • +
    • 二期补齐:发票作废、红冲及其查询补偿仍由 +SYS-008 +统一承接,但当前轮次补齐后台触发入口、状态流转、结果回写与日志留痕,不再仅停留于文档预留。
    • +
    • 文档先行:发票明细、营业账开票关系等对象仍按设计能力描述,不表述为本轮已确认独立表。
    • +
    +

    +

    2.8 REV-006 催缴与通知

    +

    2.8.1 功能说明

    +

    针对欠费账单按账龄、金额、客户类别等规则生成催缴任务,通过短信、微信、站内通知等方式触达客户,并回写催缴结果;本模块同时定义催缴与停复水/工单处置之间的联动边界与追溯关系,但不展开停复水内部处置流程。

    +

    2.8.2 业务流程

    +
    flowchart TD
    +    A[生成欠费客户清单] --> B[按策略分组催缴任务]
    +    B --> C[触发IF-REV-013生成催缴任务]
    +    C --> D[调用IF-EXT-008协同SYS-010]
    +    D --> E[接收发送结果回写]
    +    E --> F[更新催缴状态与后续策略]
    +    F --> G[按联动边界挂接停复水/工单处置]
    +
    +

    2.8.3 关键规则

    +
      +
    1. 催缴策略以营业账状态、欠费金额、账龄分布、客户类别和渠道偏好为基础,支持按策略编码进行任务分组与频控。
    2. +
    3. 自动催缴与人工催缴可并行;自动任务用于常规批量催缴,人工任务用于补发、核查或例外处置。
    4. +
    5. SYS-002 +负责催缴对象筛选、任务生成、业务事件编号、结果承接与历史查询;SYS-010 +负责短信、微信公众号、站内信等触达执行与结果回传。
    6. +
    7. REV-006 正式结果状态固定为 +PENDINGSUCCESSFAILMANUAL_VERIFIED +四态,其中 MANUAL_VERIFIED +仅用于外部结果未定或需人工核查补记的场景。
    8. +
    9. 停复水在本模块中仅定义联动触发条件、处置引用与追溯关系,不展开停复水内部审批、派工或现场执行流程。
    10. +
    11. 当前后端中部分催缴汇总、停水明细对象未确认独立落表,文档中保持保守描述,不误写为已确认在线主表。
    12. +
    +

    2.8.3.1 +催缴对象筛选、排除与频控边界

    +
      +
    • IF-REV-013 +任务生成前必须完成候选筛选,筛选最小维度为:欠费状态、欠费金额、账龄分组、客户类别、渠道偏好和策略编码。
    • +
    • 候选对象必须以有效欠费账单为前提;以下场景不得进入正式催缴任务:已收费核销、已作废、已进入不允许催缴的处置流程、策略规则未命中。
    • +
    • 触发类型按 triggerType +区分自动与人工;自动用于批量触发,人工用于补发、核查和例外补记,不改变正式接口编号与状态语义。
    • +
    • 频控以“同客户/同策略/同渠道/同账期窗口”为最小拦截单元;命中频控时允许部分阻断,并返回被跳过对象及原因摘要。
    • +
    +

    2.8.4 核心数据

    +
      +
    • biz_chargebiz_charge_detail:催缴对象来源。
    • +
    • 催缴结果与通知日志:通过业务状态与消息结果联动留痕。
    • +
    +

    2.8.4.1 催缴对象与规则摘要

    +
      +
    • Reminder Candidate:由欠费账单、客户类别、账龄分组、欠费金额、联系方式集合和命中策略编码组成,是催缴任务的输入对象。
    • +
    • Reminder Strategy:定义账龄规则、金额规则、客户类别规则、渠道优先级、重复触达拦截窗口和是否触发后续处置关注。
    • +
    • Reminder Task:一次正式催缴执行单元,至少包含 +taskNoeventNostrategyCodechannelTypetriggerTypestatus +和关联账单信息;正式业务接口编号固定为 IF-REV-013
    • +
    • Reminder Result:承接 IF-EXT-008 +回传结果后由业务侧映射的正式四态结果,最少记录 +statuslastCallbackTimefailReason +与回传摘要。
    • +
    • Disposal Link:用于记录催缴结果与停水、复水、工单或人工跟进之间的关联引用,只承担追溯职责,不替代下游业务对象。
    • +
    +

    2.8.4.2 四态与人工核查边界

    +
      +
    • PENDING:已生成任务并完成外部受理或等待外部终态回传,尚未形成业务终态。
    • +
    • SUCCESS:外部触达结果明确成功,且业务侧已完成结果承接。
    • +
    • FAIL:外部返回明确失败或业务判定失败,必须记录失败原因。
    • +
    • MANUAL_VERIFIED:仅用于外部结果长期未定、人工核查补记或例外核销说明场景;必须留存核查说明与核查人。
    • +
    • 人工核查是状态收口手段,不得用于绕过候选筛选、排除条件或频控约束。
    • +
    +

    2.8.5 迁移补充(旧系统承接)

    +

    2.8.5.1 催缴记录

    +
      +
    • 旧系统支持催缴记录查询、导出和明细展开,记录中包含推送内容、号码、方式、结果等信息。
    • +
    • 新系统可继续以消息协同结果和账单状态联动承接,但必须明确催缴记录查询口径,而不能仅保留“已发送/未发送”状态。
    • +
    • 历史查询最少保留客户号、账期、催缴方式、发送对象、发送时间、执行结果、关联账单、关联处置引用等字段,并兼容四态结果或其历史映射值。
    • +
    • 历史催缴记录按只读口径承接,作为查询与追溯来源,不反推为已确认在线主表。
    • +
    +

    2.8.5.2 停水记录

    +
      +
    • 停水记录不是孤立账务对象,应由催缴结果、业务处置和现场执行工单共同形成闭环。
    • +
    • 迁移后需支持按客户、站点、停水原因、停水时间、复水状态查询,并能追溯到对应欠费账单和工单执行结果。
    • +
    • 正式设计只定义“何时建立联动、如何保存处置引用、如何追溯关联结果”,不在 +REV-006 中展开停复水内部流程设计。
    • +
    • 停复水关联以 Disposal Link +的处置引用承接,最少包含任务号、处置类型、处置引用号和建联时间。
    • +
    +

    2.8.5.3 预存短信

    +
      +
    • 旧系统对预存款余额不足客户提供短信推送和发送记录查询。
    • +
    • 新系统建议将其纳入催缴与通知统一策略,不再单建平行模型,但必须保留触发条件、发送内容、发送结果和补发记录。
    • +
    • 该类记录与催缴记录一样,按历史只读口径承接,不表述为新增同名在线主表。
    • +
    +

    2.8.6 接口映射

    +
      +
    • IF-REV-013:催缴任务生成、任务查询与结果承接接口,负责业务侧任务生成、四态状态维护和历史查询挂接。
    • +
    • IF-EXT-008:消息协同结果回写接口(由 +SYS-010 协同)。
    • +
    +

    2.8.7 落地边界

    +
      +
    • 已落地:以营业账为基础的欠费识别前提数据、催缴对象来源字段和消息协同边界约束。
    • +
    • 部分落地:催缴登记汇总、停水汇总等对象暂未在 +backend 中确认独立表,当前以业务事件、操作留痕和历史查询口径承接。
    • +
    • 文档先行:复杂催缴台账、停复水统计和人工核查界面仅作为业务场景保留,不表述为 +backend 已完成能力。
    • +
    +

    +

    2.9 REV-007 统计分析

    +

    2.9.1 功能说明

    +

    提供营收、抄表、收费、欠费、渠道、客户等多维度统计查询能力,为经营分析、业务监管和迁移核查提供统一的数据口径支撑;本模块以经营查询为主,不扩展到预测分析、专题大屏或独立 +BI 平台实现。

    +

    2.9.2 关键设计

    +
      +
    1. 统计查询按“主题 + 维度 + +指标”三层口径组织,避免仅以报表名称堆砌需求。
    2. +
    3. 主题范围至少包括营收汇总、收费与实收统计、欠费规模与账龄统计、客户结构统计、渠道交易统计、抄表完成率统计以及营收相关业务概览类摘要。
    4. +
    5. 查询维度至少包括时间区间、账期、营业所/片区、客户类别、渠道、客户/账户、状态等,并支持必要的分组汇总。
    6. +
    7. 指标口径需明确区分应收金额、实收金额、欠费余额、账单数、客户数、交易笔数、渠道占比、抄表完成率等相近但不等价的统计概念。
    8. +
    9. 导出与查询结果受数据权限控制;导出属于查询扩展能力,但不在本轮展开具体导出实现细节。
    10. +
    11. 重点查询可按聚合视图、汇总口径或预聚合结果承接,但不将未确认存在的统计表、专题分析表或离线数仓对象写成已实现事实。
    12. +
    +

    2.9.3 核心数据

    +
      +
    • 客户维度:biz_custbiz_account
    • +
    • 抄表维度:biz_meter_bookbiz_reading_databiz_last_reading
    • +
    • 账务与收费维度:biz_chargebiz_charge_detail
    • +
    • 收费与交易维度:biz_collectionbk_transaction
    • +
    • 渠道维度:bk_transactionbk_payment_channel
    • +
    • 组织与权限维度:system_dept、数据权限控制结果。
    • +
    +

    2.9.3.1 统计主题与口径摘要

    +
      +
    • Statistics Theme:按经营主题组织查询,至少覆盖营收、收费、欠费、客户、渠道、抄表完成率和必要的业务概览。
    • +
    • Statistics Dimension:按时间、账期、营业所/片区、客户类别、渠道、客户/账户、状态等条件筛选或分组。
    • +
    • Statistics Indicator:至少明确应收金额、实收金额、欠费余额、账单数、客户数、交易笔数、渠道占比、完成率等指标含义和单位。
    • +
    • Aggregation Source:统计结果以现有在线主数据聚合、视图或汇总口径承接,不反推为已存在独立统计表族。
    • +
    +

    2.9.4 接口映射

    +
      +
    • IF-REV-010:营收、收费、欠费、渠道、客户等统计查询接口,承接主题查询、维度筛选、指标汇总和权限/导出边界。
    • +
    +

    2.9.5 落地边界

    +
      +
    • 已落地:主要统计源数据在客户、抄表、账单、收费、交易和渠道等领域均已具备,足以支撑经营统计口径设计。
    • +
    • 部分落地:部分统计结果可能依赖聚合视图、汇总查询或报表层实现,当前未见明确的 +backend 统计控制器或独立统计模型入口。
    • +
    • 文档先行:预测类、专题分析类深度模型、BI +大屏和独立数仓能力暂不写成后端已实现能力。
    • +
    +

    +

    2.10 REV-008 代收与银行业务

    +

    2.10.1 功能说明

    +

    支持银行代收、银行代扣、实时收费、夜间批量扣款、对账与结算处理,是 +SYS-002 面向 SYS-009 支付与银行结算能力的业务承接模块。

    +

    2.10.2 业务流程

    +
    flowchart TD
    +    A[生成代扣批次] --> B[校验签约与待扣账单]
    +    B --> C[调用IF-REV-011下发批次]
    +    C --> D[SYS-009对接银行处理]
    +    D --> E[回写扣款结果]
    +    E --> F[执行对账与差异识别]
    +    F --> G{差异是否已处理}
    +    G -->|否| H[进入人工补偿]
    +    G -->|是| I[确认结算并更新状态]
    +
    +

    2.10.3 关键规则

    +
      +
    1. 渠道、路由、接口配置、签约、交易、回调、异常、对账、结算形成完整银行业务链条。
    2. +
    3. 实时收费场景由渠道交易流水驱动账单核销,批量代扣场景由签约关系与批次处理驱动。
    4. +
    5. 对账结果区分一致、长款、短款、失败待处理等状态,支持差异追踪与人工补偿。
    6. +
    7. 国密报文、批量文件、标准 API 等技术细节由 SYS-009 +承载,SYS-002 保留业务规则与状态协同。
    8. +
    9. 当前 backend 已确认 BankWithholding +六条银行入口(客户状态查询、送盘、送盘状态查询、取消送盘、回盘、回盘状态查询)已形成最小实现态闭环;BankCollection +平行链路、对账与结算协同仍以“部分实现或文档先行”表述,不得统一写成已闭环能力。
    10. +
    11. 银行代扣文件传输配置按“默认规则 + 银行通道覆盖 + 租户覆盖 + +租户-银行通道覆盖”建模,命中优先级固定为 +TENANT_CHANNEL > TENANT > CHANNEL > DEFAULT
    12. +
    13. 目录字段至少区分 send/back/reconcile/archive/localTemp +五类阶段;上层覆盖未完整定义时按字段级回退,不允许生成空路径。
    14. +
    15. 路径模板仅允许 +{tenantId}{companyId}{channelCode}{yyyyMMdd}{yyyyMM}{batchNo}{fileName} +七个固定变量;命中未声明变量或缺少变量取值时立即阻断文件动作。
    16. +
    17. BankWithholding 在送盘创建时固化 +sendProtocol/sendDir/sendFilePath 与 +backProtocol/backDir,配置切换仅影响新发起文件动作,已落库批次继续沿用原解析结果。
    18. +
    +

    2.10.4 核心数据

    +
      +
    • bk_payment_channel:支付渠道。
    • +
    • bk_channel_api_config:渠道接口配置。
    • +
    • bk_channel_route_rule:渠道路由规则。
    • +
    • bk_withholding_agreement:代扣签约。
    • +
    • bk_withholding_batchbk_withholding_item:代扣批次与明细。
    • +
    • bk_reconcile_batchbk_reconcile_diff:对账批次与差异。
    • +
    • bk_settlement_batch:结算批次。
    • +
    • bk_transactionbk_transaction_callbackbk_transaction_exception:交易、回调、异常。
    • +
    • biz_collectionbiz_withholding:代收/代扣业务主对象。
    • +
    +

    2.10.4.1 +文件传输配置与审计补充

    +
      +
    • 环境默认规则通过 Spring profile + Nacos +承接,不在仓库样例中写入真实密码、私钥或证书。
    • +
    • bk_channel_api_config 使用专用 +apiType=FILE_TRANSFER_CONFIG +承接文件传输覆盖配置,extParams +记录作用域、业务类型、协议、连接引用和五类目录字段。
    • +
    • bk_withholding_batch +固化送盘/回盘目录与协议,bk_reconcile_batch +固化对账阶段最终 +protocol/dir/filePath/fileName,用于审计与问题回放。
    • +
    +

    2.10.5 迁移补充(旧系统承接)

    +

    2.10.5.1 银行托收

    +
      +
    • 旧系统“银行托收”菜单重点承接托收送盘、托收信息查询和托收结果回看。
    • +
    • 当前设计已形成 biz_collection + bk_* +渠道模型,迁移时应补出“旧托收菜单 → +托收批次/交易/回盘结果”的映射,而不是按旧菜单名平移建模。
    • +
    • 旧托收历史记录应至少保留送盘批次、客户范围、送盘结果、回盘结果和账单核销结果。
    • +
    +

    2.10.5.2 实时收费查询与对账

    +
      +
    • 旧系统“实时收费”更偏运营查询和渠道对账入口,不只是支付成功回写。
    • +
    • 当前建议以 bk_transaction* +作为主承接对象,并补充按结算日期、银行/渠道、收费结果、差异状态查询和导出能力说明。
    • +
    • 对旧“实时收费汇总/日志/明细”对象,P0 +阶段先按历史只读查询口径保留,不误写为当前已落地的独立主模型。
    • +
    +

    2.10.5.3 当前实现对齐说明

    +
      +
    • PayCeb +路径已具备欠费查询、缴费处理、流水唯一性校验和交易日志留痕,可作为实时收费基础闭环的实现证据。
    • +
    • BankWithholding +路径已具备签约、解约、客户状态查询、送盘、送盘状态查询、取消送盘、回盘、回盘状态查询及对应交易留痕的实现证据,可作为代扣最小实现态闭环依据。
    • +
    • BankCollection +路径当前仍仅能确认签约、解约与协议/交易日志处理具备实现证据。
    • +
    • 对账、结算、真实银行文件解析、SFTP/文件通道联调和运行态样本补证当前仍未闭环,正式文档应继续保留为后续完善项。
    • +
    +

    2.10.6 接口映射

    +
      +
    • IF-REV-011:代扣批次、对账与结算协同入口。
    • +
    • IF-EXT-001:银行代扣批次下发与回盘协同。
    • +
    • IF-EXT-003:银行实时收费查询、缴费与结果确认协同。
    • +
    +

    2.10.7 落地边界

    +
      +
    • 已落地:渠道、路由、交易、回调、异常、代扣/托收签约、解约,以及 +BankWithholding +的客户状态查询、送盘、送盘状态查询、取消送盘、回盘、回盘状态查询和对应日志留痕等主对象已具备明确实现证据。
    • +
    • 部分落地BankCollection +批次、明细、送盘、回盘、状态查询、差异台账和后台资源管理入口已具备对象或骨架,但不等同于银行协同闭环全部完成;BankWithholding +的真实文件解析、异常补偿和运行态联调证据仍待补齐。
    • +
    • 文档先行:夜间批量代扣调度、完整对账处理、结算确认、扩展银行台账等内容不得在当前阶段写成已完成能力。
    • +
    +

    +

    2.11 REV-009 业务参数配置

    +

    2.11.1 功能说明

    +

    负责营收域的价格参数、客户编号规则、页面配置、打印与渠道相关业务参数配置,为客户、开账、收费、发票、催缴等模块提供统一配置支撑。

    +

    2.11.2 关键设计

    +
      +
    1. 业务参数按租户、单位、片区、业务类别分层管理。
    2. +
    3. 价格体系、客户编号规则、页面字段配置、打印与通知参数统一归口维护。
    4. +
    5. 配置变更应具备版本化、操作留痕与生效范围控制。
    6. +
    +

    2.11.3 核心数据

    +
      +
    • biz_parameter_settings:业务参数配置。
    • +
    • biz_page_settingsbiz_page_settings_detail:页面配置。
    • +
    • biz_price_categorybiz_price_templatebiz_template_dept_rel:价格归属与模板站点关系。
    • +
    • biz_cust_no_rule:客户编号规则。
    • +
    • sys_wechat_app_settings:微信/微网厅基础配置。
    • +
    +

    2.11.4 迁移补充(旧系统承接)

    +
      +
    • 旧系统后台存在“页面配置、业务字段、微信参数、打印维护”等运营配置入口。
    • +
    • 当前建议统一按业务参数、页面配置、渠道参数与打印参数归口承接,不新增“微客服后台配置”并行主文档。
    • +
    • 迁移时需明确三类配置映射:客户/业务办理字段展示与校验规则、微信/微网厅基础参数、打印模板与补打策略;未确认已实现的高级灰度能力继续按“文档先行”处理。
    • +
    +

    2.11.5 接口映射

    +
      +
    • IF-REV-012:查询与维护价格模板、业务参数、页面参数配置。
    • +
    • IF-UP-004:统一平台参数字典能力协同,为营收域参数提供基础字典支撑。
    • +
    +

    2.11.6 落地边界

    +
      +
    • 已落地:业务参数、页面配置、价格归属与模板站点关系、客户编号规则等核心配置对象。
    • +
    • 部分落地:部分打印模板、通知策略等参数由统一平台或外部渠道参数共同承载,营收域仅保留业务侧映射。
    • +
    • 文档先行:参数灰度发布、多版本并行生效等高级治理能力当前仅保留设计语义,不宣称为独立实现模块。
    • +
    + + diff --git a/output/12_REV_Detailed.pdf b/output/12_REV_Detailed.pdf new file mode 100644 index 0000000..94b5a88 Binary files /dev/null and b/output/12_REV_Detailed.pdf differ diff --git a/output/12_REV_Detailed_processed.md b/output/12_REV_Detailed_processed.md new file mode 100644 index 0000000..1215413 --- /dev/null +++ b/output/12_REV_Detailed_processed.md @@ -0,0 +1,750 @@ +--- +title: "12_REV_Detailed" +author: "系统设计团队" +date: "2024年12月19日" +documentclass: article +geometry: margin=1in +fontsize: 11pt +mainfont: "PingFang SC" +CJKmainfont: "PingFang SC" +--- + +--- +doc_id: DT-12-REV +doc_role: module_body +authority: secondary +scope: 详细设计-营收业务 +source_of_truth: false +last_reviewed: 2026-03-11 +retrieval_priority: P1 +--- + +# 福建水务营收系统详细设计-营收业务模块正文 + +## 章节导航(精简) + +- [文档定位](#sec-position) +- [营收业务详细设计正文](#sec-content) + - [营收模块统一约束](#sec-rev-rules) + - [接口与数据追溯矩阵](#sec-rev-trace) + - [REV-001 客户资料管理](#mod-rev-001) + - [REV-002 抄表开账](#mod-rev-002) + - [REV-003 营业收费](#mod-rev-003) + - [REV-004 账务处理](#mod-rev-004) + - [REV-005 发票与税务处理](#mod-rev-005) + - [REV-006 催缴与通知](#mod-rev-006) + - [REV-007 统计分析](#mod-rev-007) + - [REV-008 代收与银行业务](#mod-rev-008) + - [REV-009 业务参数配置](#mod-rev-009) + + + +## 文档定位 + +本文档为 `01_Detailed_Design.md` 中“营收业务详细设计”章节的模块正文拆分稿,便于按模块独立维护。正式交付口径以主详设为准。 + + + +# 营收业务详细设计 + + + +## 营收模块统一约束 + +1. `SYS-002` 负责营收主流程,发票、支付结算、消息触达分别通过 `SYS-008`、`SYS-009`、`SYS-010` 协同完成,外部系统仅回写结果状态。 +2. 账单、收费、发票、代扣等关键状态变更必须通过业务流程驱动,不允许绕过业务校验直接改写主业务对象。 +3. 幂等控制遵循接口主键约束:支付以业务订单号为主,发票以申请单号或账单组合为主,代扣以批次号为主,消息以业务事件号为主。 +4. 账务调整、发票申请、催缴触达、银行批次下发等关键动作必须写入操作留痕,满足审计与问题追踪要求。 +5. 数据口径统一采用 `biz_*` 与 `bk_*` 命名体系,历史命名仅用于追溯,不作为本章节正式设计口径。 + + + +## 接口与数据追溯矩阵 + +> 说明:详细字段与报文以 `../03_Technical_Design/03_Interface_Design.md` 为准,数据库字段口径以 `../03_Technical_Design/01_Database_Design.md` 为准。 + +| REV 模块 | 关键接口 | 核心数据域(摘要) | 主要协同对象 | +|---|---|---|---| +| REV-001 客户资料管理 | `IF-REV-001` | `biz_cust`、`biz_account`、`biz_cust_*` | 客户服务模块、报装模块 | +| REV-002 抄表开账 | `IF-REV-004`、`IF-REV-005` | `biz_meter_book`、`biz_meter_read`、`biz_reading_*`、`biz_charge*` | 抄表APP、物联网集抄 | +| REV-003 营业收费 | `IF-REV-006` | `biz_charge*`、`biz_collection`、`bk_transaction*` | `SYS-009` | +| REV-004 账务处理 | `IF-REV-007` | `biz_charge*`、`biz_operat_log*` | 财务与营业人员 | +| REV-005 发票与税务处理 | `IF-REV-008` | `biz_invoice*`、`biz_cust_invoice` | `SYS-008` | +| REV-006 催缴与通知 | `IF-REV-013` | `biz_charge*`、催缴结果留痕 | `SYS-010` | +| REV-007 统计分析 | `IF-REV-010` | 客户、抄表、收费、渠道聚合对象 | 统计分析端 | +| REV-008 代收与银行业务 | `IF-REV-011` | `bk_withholding_*`、`bk_reconcile_*`、`bk_settlement_*` | `SYS-009`、银行 | +| REV-009 业务参数配置 | `IF-REV-012` | `biz_parameter_settings`、`biz_page_settings*`、`biz_price_*` | 统一平台、营收模块 | + + + +## REV-001 客户资料管理 + +### 功能说明 + +负责客户主档、账户主档、联系人、客户分组、客户与水表关系、客户开票信息、客户渠道绑定及托收/代扣关系维护,是抄表、收费、发票、代扣等后续业务的主数据基础。 + +### 关键设计 + +1. 客户建档覆盖立户、变更、更名、过户、销户、报停等全生命周期处理。 +2. 客户资料支持按客户类型、用水性质、片区、集团客户、重点客户等维度管理。 +3. 客户与水表、开票主体、托收/代扣签约关系按关联表维护,避免在主表中堆叠多类属性。 +4. 客户编号、集收标记、计划用水方案等规则类数据由统一配置与客户关系表共同支撑。 + +### 核心数据 + +- `biz_cust`:客户主档。 +- `biz_account`:客户账户与账户状态。 +- `biz_cust_contact`:联系人及联系方式。 +- `biz_cust_group`:客户分组。 +- `biz_cust_meter`:客户与水表绑定关系。 +- `biz_cust_invoice`:客户开票信息。 +- `biz_cust_app_binds`:渠道绑定关系。 +- `biz_cust_collection_rel`:客户托收关系。 +- `biz_cust_withholding_rel`:客户代扣关系。 +- `biz_cust_water_use_scheme`、`biz_cust_water_scheme_rel`:客户计划用水方案关系。 +- `biz_cust_no_rule`:客户编号规则。 +- `biz_cust_hub_marks`:集收号/集收标记关系。 + +### 迁移补充(旧系统承接) + +#### 定额共享 + +- 旧系统在“客户资料”下提供定额主客户、子客户绑定与共享清单管理能力。 +- 当前正式设计不新增并行主模型,统一归入客户与计划用水方案关系对象承接。 +- 迁移时必须至少保留主客户、子客户、绑定状态、生效时间、解除时间、备注与操作留痕,确保共享清单可查询、可解绑、可追溯。 + +#### 定额核定 + +- 旧系统支持对已建立共享关系的客户执行定额核定、撤销核定和共享清单联查。 +- 当前建议以客户关系对象和计划用水方案关系为主承接核定结果,不额外发明独立账务主表。 +- 核定结果迁移后应支持按客户、站点、核定状态、核定时间查询,并保留核定依据、操作人和变更留痕。 + +#### 批量修改 + +- 旧系统已形成“手工修改 + 模板导入修改”的双模式客户资料维护能力。 +- 当前正式设计应将其视为客户主数据治理能力的一部分,而不是临时导入工具。 +- 迁移时需明确三类口径:可批量修改字段范围、导入模板校验规则、批量修改审计留痕;历史批量修改结果至少需保留任务来源、修改字段、执行结果和失败原因。 + +### 接口映射 + +- `IF-REV-001`:客户档案、账户状态、联系人与水表绑定关系查询。 +- `IF-CS-001`、`IF-CS-002`:客户服务侧账户绑定与信息查询场景复用客户域数据。 + +### 落地边界 + +- **已落地**:客户主档、账户、联系人、分组、绑定、开票、托收/代扣关系。 +- **部分落地**:客户扩展关系、集收与规则类对象已见明确关系表,但具体业务场景仍需结合流程进一步细化。 +- **文档先行**:主副卡、部分复杂客户关系对象在当前 backend 中未见完全独立表族,文档中仅保留业务对象表述。 + + + +## REV-002 抄表开账 + +### 功能说明 + +负责抄表计划、册本管理、抄表录入、抄表状态跟踪、异常复核、计费计算与账单生成,是营收核心处理链路的起点。 + +### 业务流程 + + +```mermaid +flowchart TD + A[制定抄表计划] --> B[生成抄表册本] + B --> C[分配抄表任务] + C --> D[人工/远传/自报抄表] + D --> E[数据校验] + E --> F{是否异常} + F -->|是| G[异常复核处理] + F -->|否| H[生成开账数据] + G --> H + H --> I[按价格模板与费用组成计费] + I --> J[生成营业账与明细] + J --> K[账单审核确认] + K --> L[进入收费/催缴/开票] + +``` + + +### 关键规则 + +1. 抄表数据同时校验本次读数、上次读数、用量波动和抄表状态,只有通过校验或完成异常复核的数据才能进入开账。 +2. 异常抄表支持估抄、补抄、重录、人工复核;异常处理的目标是形成可继续开账或明确阻断的统一结论,而不是绕开开账规则单独落账。 +3. `IF-REV-005` 的正式边界是“抄表校验完成后的账单生成”,不负责收费核销、发票开具、催缴执行和统计分析。 +4. 开账计费按价格归属、价格模板、费用组成、阶梯规则、计划用水方案综合计算;价格配置缺失、费用组成不完整或规则冲突时,必须阻断生成并返回失败原因。 +5. 账单生成结果统一由 `biz_charge` 与 `biz_charge_detail` 承接:主表表达客户、账期、应收日期、账单总金额和主状态,明细表表达费用组成、用量、单价和明细金额。 +6. 特殊开账、无码客户开账、罚款类开账等非标准来源,仍纳入同一营业账主明细模型承接,通过来源类型、业务类型、依据说明和操作留痕区分,不单独扩展平行账表。 +7. 审核通过后的营业账方可进入收费、催缴和发票流程;后续链路只能消费已生成账单结果,不反向改变本接口的生成边界。 +8. 远传抄表数据可由 `SYS-006` / IoT 能力提供采集支撑,但账单生成仍归属 SYS-002。 + +### 开账触发与结果表达 + +- 触发前提:正式口径下可按抄表批次、指定客户范围或指定抄表任务范围组织生成;当前 backend 已落地的入口为按 `readingDataIds` 批量复核并开账,对应 `ChargeController.generateCheckChargeBatch`、`ChargeServiceImpl.generateCheckChargeBatch` 与 `ReadingDataServiceImpl.batchReCheckReadingData`。 +- 规则来源:价格归属决定客户适用的价格口径;价格模板、阶梯规则、费用组成和计划用水方案共同决定营业账主表金额与明细拆分方式。 +- 当前承接证据:`ChargeServiceImpl.generateSingleChargeWithCache` 成功路径会写入 `biz_charge` 主表、循环写入 `biz_charge_detail` 明细,并回写抄表数据开账状态,说明现有实现已具备“按抄表数据 ID 生成营业账主明细”的 backend 基础。 +- 结果表达:正式 `IF-REV-005` 应返回成功清单、失败清单、生成汇总及主明细级结果;当前 backend 返回仍为“本次复核成功X条 / 本次开账成功Y条”的字符串拼接,尚未形成结构化成功/失败结果对象。 +- 阻断与限制:价格模板不存在、费用调整配置缺失、结算方式非 `ACTUAL_USAGE` 等场景当前会直接阻断单条生成;其中固定水量、按人口数、最低消费等非实际水量结算方式仍未纳入当前实现。 +- 下游边界:`REV-002` 只负责生成营业账结果并交由后续审核/收费链路消费,不在本章节扩展收费核销、发票申请或催缴执行细节。 + +### 核心数据 + +- `biz_meter_book`:册本与抄表计划。 +- `biz_meter_read`:抄表任务状态/执行状态。 +- `biz_reading_data`:抄表数据。 +- `biz_last_reading`:上次抄表结果。 +- `biz_reading_logs`:抄表日志与过程留痕。 +- `biz_meter`:计量水表主档引用。 +- `biz_charge`:营业账主表。 +- `biz_charge_detail`:营业账明细。 +- `biz_price_category`:价格归属。 +- `biz_price_template`:价格模板。 +- `biz_price_adjustment_snap`:调价快照。 +- `biz_price_tier_adjustment`:阶梯规则。 +- `biz_cost_component`:费用组成。 +- `biz_water_use_scheme`、`biz_water_use_scheme_tier`:计划用水方案与阶梯。 + +### 迁移补充(旧系统承接) + +#### 特殊开账 + +- 旧系统支持在非标准客户、无码客户或罚款类场景下直接开账。 +- 新系统仍以 `biz_charge`、`biz_charge_detail` 作为开账结果承载对象,不建议额外平行建设“特殊开账账表”。 +- 迁移与新建场景均需保留特殊开账来源、业务类型、经办人、依据说明、打印状态与后续收费关联,避免与普通抄表开账混淆。 + +#### 开账记录迁移 + +- 旧系统“开账记录”是历史查询与账务核对的核心入口,必须纳入迁移最小保留集。 +- 迁移后的开账记录应至少支持按站点、账务年月、册本、客户、抄表员、欠费状态查询,并支持统计水量、总金额及费用构成。 +- 对已收费、已作废、销户拆表、特殊开账等旧状态,不要求照搬旧表结构,但必须保留可对照的新状态映射关系。 + +### 接口映射 + +- `IF-REV-004`:抄表数据提交与异常标记。 +- `IF-REV-005`:账单生成与开账结果返回。 +- `IF-METER-004`:远传抄表数据接收后进入开账流程。 + +### 落地边界 + +- **已落地**:册本、抄表数据、上次抄表、抄表日志、营业账主明细、价格模板与阶梯规则。 +- **部分落地**:部分异常场景对象可能仍通过状态字段和日志表承载,而非全部拆成独立业务表。 +- **文档先行**:个别精细稽查、轨迹、下载同步对象当前未在本轮映射中确认为独立表。 + + + +## REV-003 营业收费 + +### 功能说明 + +支持柜台收费、预存款/余额抵扣、线上缴费回写、柜面扫码、营业网点收费及收费凭证管理,统一承接营收账单的核销处理。 + +### 业务流程 + + +```mermaid +flowchart TD + A[查询客户及待缴账单] --> B[选择账单与核销方式] + B --> C[选择支付渠道] + C --> D{支付方式} + D -->|柜台现金/POS/扫码| E[现场收费] + D -->|微信/支付宝/聚合支付| F[渠道下单] + D -->|预存款/余额抵扣| G[账户余额核销] + E --> H[更新营业账状态] + F --> I[等待异步回调确认] + G --> H + I --> H + H --> J[生成收费记录与凭证] + J --> K[进入发票/对账流程] + +``` + + +### 关键规则 + +1. 一次缴费可对应多个账单或账单明细的组合核销。 +2. 收费记录必须保留渠道、流水号、网点、操作员、终端信息。 +3. 线上支付必须以回调或查询确认结果为准,不得以发起状态直接记账。 +4. 支付能力由 `SYS-009` 提供,SYS-002 负责账单核销与业务状态回写。 +5. 当前实现侧已确认 `PayCeb` 的欠费查询、缴费处理基础闭环可用,但代理收费对账仍为预留能力;正式文档不得将实时收费对账写成已闭环能力。 + +### 核心数据 + +- `biz_charge`、`biz_charge_detail`:待缴与已缴账单主明细。 +- `biz_collection`:托收/代收主表。 +- `biz_withholding`:代扣/托收主表。 +- `bk_transaction`:渠道交易流水。 +- `bk_transaction_callback`:支付回调记录。 +- `bk_transaction_exception`:支付异常记录。 + +### 迁移补充(旧系统承接) + +#### 柜台结账 + +- 旧系统将“柜台收费”和“柜台结账”拆分为两个菜单,结账阶段包含未结/已结查询、结账红冲、追加抄表和打印动作。 +- 当前设计可继续采用统一收费核销模型,但必须补出“收费记录 → 班结结果 → 打印/红冲/查询”的业务闭环,避免柜面日终处理缺口。 +- 迁移时需保留结账时间、结账人、网点、收费汇总口径和结账后红冲痕迹,保证财务对账与审计连续。 + +#### 账单打印服务 + +- 旧系统存在账单打印、补打、打印次数控制与打印记录查询能力。 +- 新系统不要求单独建立打印主模块,但必须明确打印模板、补打权限、打印状态与打印留痕的承接关系。 +- 对历史账单迁移,应允许基于账单主明细和打印配置恢复打印视图,避免割接后只能查账不能补打。 + +#### 红冲记录 + +- 旧系统支持红冲记录查询、导出与明细展开,是收费差错追溯的重要入口。 +- 当前设计可将红冲视为收费核销后的修正场景,不强制要求独立实体表,但必须提供历史只读查询口径。 +- 红冲迁移最小保留信息应包括原收费记录、红冲时间、红冲金额、原因、经办人、关联账单和后续账务状态。 + +### 接口映射 + +- `IF-REV-006`:创建收费记录、执行账单核销并回写状态。 +- `IF-CS-003`、`IF-CS-007`:客户渠道与柜面扫码支付场景复用收费核销链路。 + +### 落地边界 + +- **已落地**:营业账主明细、交易流水、回调、异常、托收/代扣主对象。 +- **部分落地**:柜台班结、部分收费汇总类对象可能通过业务流程与报表实现,不一定存在独立表。 +- **文档先行**:部分红冲、实时收费汇总类台账暂不表述为已确认独立实体表。 + + + +## REV-004 账务处理 + +### 功能说明 + +REV-004 一期仅覆盖水量调整、金额调整、退款、冲正、坏账申请五类场景,统一挂靠 `IF-REV-007` 作为账务处理入口,目标是在既有正式文档体系内先收敛范围、承接口径、留痕要求与审批边界。 + +本阶段按“共性能力先统一、场景能力再分批”组织:先统一账单承接、原交易校验、结果表达、操作留痕与审批边界,再分别展开五类场景。违约金减免、分账调整、价差调整、跨周期水量、预存退款细表等内容仅作为旧系统迁移语义或后续扩展参考,不作为一期新增独立范围。 + +### 业务流程 + + +```mermaid +flowchart TD + A[发起账务调整申请] --> B[校验账单状态与权限] + B --> C{是否通过} + C -->|否| D[驳回并记录原因] + C -->|是| E[执行重算或退款冲正] + E --> F[更新账单与明细状态] + F --> G[写入操作日志与审批留痕] + G --> H[返回处理结果] + +``` + + +### 关键规则 + +1. 一期场景严格限定为水量调整、金额调整、退款、冲正、坏账申请,不扩展到其他接口族或独立账务台账重构。 +2. 所有场景均以 `biz_charge` / `biz_charge_detail` 为主承接对象,并通过 `biz_operat_log` / `biz_operat_log_detail` 记录处理依据、前后变化和责任归属。 +3. 退款、冲正必须联动 `bk_transaction`、`bk_transaction_callback`、`bk_transaction_exception` 等原支付流水及渠道状态校验,不允许仅依据账单状态直接处理。 +4. 接口结果统一返回 `resultStatus`、`writeBackStatus`,其中 `resultStatus` 表示处理结论,`writeBackStatus` 表示账单状态回写结论,两者不得混用。 +5. 审批相关内容一期仅保留 `approvalRequired`、`PENDING_APPROVAL` 与审批边界说明,不展开完整 BPM 流程、节点、流转规则或审批回写实现细节。 +6. 对于当前未见明确独立实体表的特账、跨周期水量、退款账等对象,文档以“业务处理场景”表述,不强行落为已实现表。 + +### 核心数据 + +- `biz_charge`、`biz_charge_detail`:账务调整的核心对象,承接调整前后账单主明细状态。 +- `bk_transaction`、`bk_transaction_callback`、`bk_transaction_exception`:退款、冲正场景的原交易校验与异常追溯对象。 +- 价格调整/优惠相关表:用于重算账单或差额追溯。 +- `biz_operat_log`、`biz_operat_log_detail`:操作与变更留痕,记录字段差异、处理说明、附件依据与责任归属。 + +### 主要场景 + +| 场景 | 说明 | 控制要点 | +|---|---|---| +| 水量调整 | 更正异常水量 | 需复核原因、附件和原抄表依据 | +| 金额调整 | 更正账单金额 | 需记录依据、差异金额和审批边界 | +| 退款 | 退回客户支付资金或预存款 | 需校验原交易、退款余额与幂等性 | +| 冲正 | 修正误收/误核销记录 | 需关联原交易与账单状态 | +| 坏账申请 | 对长期欠费进行分类处理 | 需结合账龄、客户状态与审批边界 | + +### 迁移补充(旧系统承接) + +| 旧账务对象 | 当前承接方式 | 迁移口径 | +|---|---|---| +| 预存退款 / 预存退款详情 | 作为账务处理场景承接 | 保留申请单、原支付引用、退款结果与审批留痕 | +| 已销调整汇总 / 明细 | 作为已收费后修正场景承接 | 保留原账单、调整原因、前后差异、处理结果 | +| 价差调整汇总 / 明细 | 作为重算与差额修正场景承接 | 保留原价格口径、新价格口径、差额和生效时间 | +| 分账调整汇总 / 明细 | 作为费用组成重分摊场景承接 | 保留原分摊结果、调整后结果、责任人和审批链 | +| 账单-违约金减免 | 作为滞纳金修正场景承接 | 保留减免原因、减免金额、审批结果和生效时间 | +| 账单-呆坏账 | 作为坏账申请与生效场景承接 | 保留账龄、申请原因、审批结果、核销状态 | + +1. P0 阶段不要求为每一类旧账务台账都新增独立实体表,但必须在业务对象和历史查询层形成可追溯闭环。 +2. 旧系统精细台账迁移后至少保留:原单据标识、原账单标识、处理类型、处理原因、处理前后金额/水量、申请/审批/生效时间、经办人与附件依据。 +3. 与支付、发票、渠道回调强关联的处理场景,必须保留与原交易、原发票、原收费记录的关联关系,避免后续对账和审计断链。 + +### 接口映射 + +- `IF-REV-007`:账务调整、退款、冲正、坏账等处理入口。 +- `IF-REV-006`:与收费核销状态联动,确保调账后账单状态一致。 + +### 落地边界 + +- **已落地**:营业账主明细、操作日志、价格/方案相关重算支撑。 +- **部分落地**:精细化账务对象更多表现为流程与场景,并未在 backend 中全部体现为独立表族。 +- **文档先行**:特账、退款账、跨周期水量等对象保留业务语义,不宣称为已实现独立表。 + + + +## REV-005 发票与税务处理 + +### 功能说明 + +负责发票业务闭环的业务接入与状态落账,覆盖后台发票申请、开票校验、`SYS-008` 异步协同、查询兜底、结果回写、账单关联、客户侧已开票电子发票查询/下载/推送,以及后台作废与红冲处理。 + +### 业务流程 + + +```mermaid +flowchart TD + A[后台提交发票申请] --> B[校验账单、客户开票信息、税率与限额] + B --> C{是否满足开票条件} + C -->|否| D[返回不可开票原因] + C -->|是| E[生成申请单号并写入SUBMITTED] + E --> F[调用SYS-008发起异步开票] + F --> G[记录受理号并转为PENDING] + G --> H[系统轮询或后台查询兜底] + H --> I{开票结果} + I -->|成功| J[回写SUCCESS并更新账单-发票关联] + I -->|失败| K[回写FAIL并记录失败原因] + J --> L[客户侧查询/下载/推送电子发票] + +``` + + +### 状态说明 + +- `SUBMITTED`:后台申请已受理,已完成本地校验并生成申请单。 +- `PENDING`:已提交 `SYS-008`,等待异步结果或查询补偿结果。 +- `SUCCESS`:已取得有效发票代码、号码或电子票地址,且账单关联已完成更新。 +- `FAIL`:开票失败,需保留失败原因、最近查询结果与后续人工核查依据。 +- `INVALID`:发票已作废,作为后续能力预留状态。 +- `RED_INK`:发票已红冲,作为后续能力预留状态。 + +### 关键规则 + +1. 一期采用“后台申请开票 + 客户侧查询下载推送”的入口模式,客户侧不直接发起开票申请。 +2. 发票申请以客户信息、已收费未开票账单、税率配置和开票限额为基础;原始单账单不支持直接任意部分金额开票。 +3. 个人与企业开票均通过客户开票信息与税率表完成合法性校验;如需多张发票,沿用拆账/分账后的账单分别开票口径。 +4. `SYS-008` 采用“异步申请 + 查询兜底”模式,成功状态不得被后续失败查询结果覆盖。 +5. 电子发票仅在 `SUCCESS` 且存在票据文件地址时允许客户侧下载或推送。 +6. 发票作废、红冲仍由 `SYS-008` 统一承接税控侧处理,`SYS-002` 负责后台触发入口、状态校验、查询补偿、结果落账与日志留痕;当前轮次按二期范围补齐 backend 实现入口。 + +### 后台申请入口与校验补充 + +- 后台支持营业收费员、财务人员按单笔或批量已收费账单发起开票申请。 +- 申请时至少校验:账单收费状态、开票状态、客户开票信息完整性、票种适配性、开票限额、账单集合是否属于同一客户。 +- 企业抬头场景重点校验纳税人识别号;电子发票场景重点校验邮箱/手机号;不满足条件时直接返回不可开票原因。 +- 申请成功后生成申请单号并进入 `SUBMITTED/PENDING` 状态流转,失败校验场景不进入外部协同。 +- 幂等控制以 `applicationNo` 或 `custId + chargeIds` 为主,避免相同账单组合重复申请。 + +### SYS-008 异步协同与查询补偿 + +- 本地申请校验通过后,`SYS-002` 先写入 `biz_invoice` 申请记录,再向 `SYS-008` 发起异步开票请求,并记录 `sysRequestNo` 作为后续查询与回写的协同主键。 +- `SYS-008` 返回“已受理”后,发票状态转为 `PENDING`;若仅完成本地受理但尚未拿到受理号,则保留 `SUBMITTED` 并进入待补偿查询状态。 +- 查询补偿采用“回写优先、主动查询兜底”原则:`IF-EXT-007` 回写为首选结果来源,后台人工查询与系统定时补偿查询共用同一结果落账逻辑。 +- 系统补偿查询至少保留最近查询时间、下次计划查询时间、累计查询次数、最近一次返回结果摘要与异常原因,便于问题追踪和人工核查。 +- 后台按申请单号或受理号触发查询时,应同步刷新查询上下文;查询仍未取得终态时,仅更新补偿上下文,不得伪造成功或失败结论。 + +### 终态保护与异常核查 + +- `SUCCESS` 属于正常开票闭环终态,一旦已取得有效发票代码、发票号码或电子票据地址,后续失败查询结果不得覆盖成功状态。 +- `FAIL` 仅在 `SYS-008` 明确返回失败结论或多次补偿查询确认失败时写入,并同步保留失败原因、最近查询结果与人工核查依据。 +- 当后台人工查询、系统补偿查询与外部回写结果不一致时,应以最新有效外部凭据为准,并记录差异说明,不允许直接覆盖既有成功票据关键信息。 +- 每次提交协同、主动查询、状态变更和异常分支均应写入操作留痕,确保能够追溯责任人、触发来源、状态前后值与异常说明。 + +### 结果回写、账单关联与客户侧消费 + +- `IF-EXT-007` 回写成功结果时,除更新 `biz_invoice.invoice_status`、`invoice_code`、`invoice_number`、`file_url` 外,还应同步刷新账单快照、账单关联状态与推送状态初值。 +- 账单关联以 `biz_invoice.charge_id` + `charge_ids_snapshot` 记录本次开票覆盖账单集合,并同步把对应 `biz_charge.invoice_state` 更新为“开票完成”,保留失败原因与开票时间,便于账单明细、收费记录和客户侧结果统一展示。 +- 客户侧查询仅允许按本人 `custId` 访问已存在的发票记录;可通过 `invoiceId`、`applicationNo` 或 `sysRequestNo` 定位,但都必须命中同一客户名下记录。 +- 客户侧下载与推送前必须校验发票状态为 `SUCCESS` 且 `fileUrl` 非空;不满足条件时仅返回不可下载/推送原因,不得伪造文件地址。 +- 推送动作应记录推送渠道、目标邮箱/手机号与结果状态;成功后更新 `pushStatus=PUSHED`,失败则写入 `FAIL` 并保留失败原因供人工处理。 + +### 核心数据 + +- `biz_invoice`:发票主记录。 +- `biz_invoice_taxrate`:税率配置。 +- `biz_cust_invoice`:客户开票信息。 + +### 迁移补充(旧系统承接) + +- 旧系统数据字典中存在“发票明细表、营业账开票表、开票配置表”等更细粒度对象。 +- 当前正式设计已明确主承接对象为 `biz_invoice`、`biz_invoice_taxrate`、`biz_cust_invoice`,但迁移时不能忽略旧开票明细和账单关联关系。 +- P0 阶段建议先补三类迁移口径:账单与发票的关联关系、发票申请与结果回写记录、开票配置与税率的有效期;未确认已落地的细表对象仍按“历史只读或辅助映射”处理。 + +### 接口映射 + +- `IF-REV-008`:后台发票申请接口,负责单笔/批量申请、幂等控制与受理号生成。 +- `IF-REV-009`:发票结果查询接口,负责后台按申请单号/受理号查询以及系统补偿查询。 +- `IF-CS-004`:客户侧电子发票消费接口,负责已开票结果查看、下载、推送。 +- `IF-EXT-007`:发票结果回写协同接口(由发票服务侧回传)。 + +### 落地边界 + +- **已落地**:发票主记录、税率配置、客户开票信息,以及一期正常开票闭环所需的后台申请、查询兜底、结果回写、账单关联与客户侧电子发票消费能力。 +- **部分落地**:发票修改、开票过程留痕在后端中已有相关对象,但整套发票明细/批次类对象尚未全部确认。 +- **二期补齐**:发票作废、红冲及其查询补偿仍由 `SYS-008` 统一承接,但当前轮次补齐后台触发入口、状态流转、结果回写与日志留痕,不再仅停留于文档预留。 +- **文档先行**:发票明细、营业账开票关系等对象仍按设计能力描述,不表述为本轮已确认独立表。 + + + +## REV-006 催缴与通知 + +### 功能说明 + +针对欠费账单按账龄、金额、客户类别等规则生成催缴任务,通过短信、微信、站内通知等方式触达客户,并回写催缴结果;本模块同时定义催缴与停复水/工单处置之间的联动边界与追溯关系,但不展开停复水内部处置流程。 + +### 业务流程 + + +```mermaid +flowchart TD + A[生成欠费客户清单] --> B[按策略分组催缴任务] + B --> C[触发IF-REV-013生成催缴任务] + C --> D[调用IF-EXT-008协同SYS-010] + D --> E[接收发送结果回写] + E --> F[更新催缴状态与后续策略] + F --> G[按联动边界挂接停复水/工单处置] + +``` + + +### 关键规则 + +1. 催缴策略以营业账状态、欠费金额、账龄分布、客户类别和渠道偏好为基础,支持按策略编码进行任务分组与频控。 +2. 自动催缴与人工催缴可并行;自动任务用于常规批量催缴,人工任务用于补发、核查或例外处置。 +3. `SYS-002` 负责催缴对象筛选、任务生成、业务事件编号、结果承接与历史查询;`SYS-010` 负责短信、微信公众号、站内信等触达执行与结果回传。 +4. `REV-006` 正式结果状态固定为 `PENDING`、`SUCCESS`、`FAIL`、`MANUAL_VERIFIED` 四态,其中 `MANUAL_VERIFIED` 仅用于外部结果未定或需人工核查补记的场景。 +5. 停复水在本模块中仅定义联动触发条件、处置引用与追溯关系,不展开停复水内部审批、派工或现场执行流程。 +6. 当前后端中部分催缴汇总、停水明细对象未确认独立落表,文档中保持保守描述,不误写为已确认在线主表。 + +#### 催缴对象筛选、排除与频控边界 + +- `IF-REV-013` 任务生成前必须完成候选筛选,筛选最小维度为:欠费状态、欠费金额、账龄分组、客户类别、渠道偏好和策略编码。 +- 候选对象必须以有效欠费账单为前提;以下场景不得进入正式催缴任务:已收费核销、已作废、已进入不允许催缴的处置流程、策略规则未命中。 +- 触发类型按 `triggerType` 区分自动与人工;自动用于批量触发,人工用于补发、核查和例外补记,不改变正式接口编号与状态语义。 +- 频控以“同客户/同策略/同渠道/同账期窗口”为最小拦截单元;命中频控时允许部分阻断,并返回被跳过对象及原因摘要。 + +### 核心数据 + +- `biz_charge`、`biz_charge_detail`:催缴对象来源。 +- 催缴结果与通知日志:通过业务状态与消息结果联动留痕。 + +#### 催缴对象与规则摘要 + +- `Reminder Candidate`:由欠费账单、客户类别、账龄分组、欠费金额、联系方式集合和命中策略编码组成,是催缴任务的输入对象。 +- `Reminder Strategy`:定义账龄规则、金额规则、客户类别规则、渠道优先级、重复触达拦截窗口和是否触发后续处置关注。 +- `Reminder Task`:一次正式催缴执行单元,至少包含 `taskNo`、`eventNo`、`strategyCode`、`channelType`、`triggerType`、`status` 和关联账单信息;正式业务接口编号固定为 `IF-REV-013`。 +- `Reminder Result`:承接 `IF-EXT-008` 回传结果后由业务侧映射的正式四态结果,最少记录 `status`、`lastCallbackTime`、`failReason` 与回传摘要。 +- `Disposal Link`:用于记录催缴结果与停水、复水、工单或人工跟进之间的关联引用,只承担追溯职责,不替代下游业务对象。 + +#### 四态与人工核查边界 + +- `PENDING`:已生成任务并完成外部受理或等待外部终态回传,尚未形成业务终态。 +- `SUCCESS`:外部触达结果明确成功,且业务侧已完成结果承接。 +- `FAIL`:外部返回明确失败或业务判定失败,必须记录失败原因。 +- `MANUAL_VERIFIED`:仅用于外部结果长期未定、人工核查补记或例外核销说明场景;必须留存核查说明与核查人。 +- 人工核查是状态收口手段,不得用于绕过候选筛选、排除条件或频控约束。 + +### 迁移补充(旧系统承接) + +#### 催缴记录 + +- 旧系统支持催缴记录查询、导出和明细展开,记录中包含推送内容、号码、方式、结果等信息。 +- 新系统可继续以消息协同结果和账单状态联动承接,但必须明确催缴记录查询口径,而不能仅保留“已发送/未发送”状态。 +- 历史查询最少保留客户号、账期、催缴方式、发送对象、发送时间、执行结果、关联账单、关联处置引用等字段,并兼容四态结果或其历史映射值。 +- 历史催缴记录按只读口径承接,作为查询与追溯来源,不反推为已确认在线主表。 + +#### 停水记录 + +- 停水记录不是孤立账务对象,应由催缴结果、业务处置和现场执行工单共同形成闭环。 +- 迁移后需支持按客户、站点、停水原因、停水时间、复水状态查询,并能追溯到对应欠费账单和工单执行结果。 +- 正式设计只定义“何时建立联动、如何保存处置引用、如何追溯关联结果”,不在 `REV-006` 中展开停复水内部流程设计。 +- 停复水关联以 `Disposal Link` 的处置引用承接,最少包含任务号、处置类型、处置引用号和建联时间。 + +#### 预存短信 + +- 旧系统对预存款余额不足客户提供短信推送和发送记录查询。 +- 新系统建议将其纳入催缴与通知统一策略,不再单建平行模型,但必须保留触发条件、发送内容、发送结果和补发记录。 +- 该类记录与催缴记录一样,按历史只读口径承接,不表述为新增同名在线主表。 + +### 接口映射 + +- `IF-REV-013`:催缴任务生成、任务查询与结果承接接口,负责业务侧任务生成、四态状态维护和历史查询挂接。 +- `IF-EXT-008`:消息协同结果回写接口(由 `SYS-010` 协同)。 + +### 落地边界 + +- **已落地**:以营业账为基础的欠费识别前提数据、催缴对象来源字段和消息协同边界约束。 +- **部分落地**:催缴登记汇总、停水汇总等对象暂未在 backend 中确认独立表,当前以业务事件、操作留痕和历史查询口径承接。 +- **文档先行**:复杂催缴台账、停复水统计和人工核查界面仅作为业务场景保留,不表述为 backend 已完成能力。 + + + +## REV-007 统计分析 + +### 功能说明 + +提供营收、抄表、收费、欠费、渠道、客户等多维度统计查询能力,为经营分析、业务监管和迁移核查提供统一的数据口径支撑;本模块以经营查询为主,不扩展到预测分析、专题大屏或独立 BI 平台实现。 + +### 关键设计 + +1. 统计查询按“主题 + 维度 + 指标”三层口径组织,避免仅以报表名称堆砌需求。 +2. 主题范围至少包括营收汇总、收费与实收统计、欠费规模与账龄统计、客户结构统计、渠道交易统计、抄表完成率统计以及营收相关业务概览类摘要。 +3. 查询维度至少包括时间区间、账期、营业所/片区、客户类别、渠道、客户/账户、状态等,并支持必要的分组汇总。 +4. 指标口径需明确区分应收金额、实收金额、欠费余额、账单数、客户数、交易笔数、渠道占比、抄表完成率等相近但不等价的统计概念。 +5. 导出与查询结果受数据权限控制;导出属于查询扩展能力,但不在本轮展开具体导出实现细节。 +6. 重点查询可按聚合视图、汇总口径或预聚合结果承接,但不将未确认存在的统计表、专题分析表或离线数仓对象写成已实现事实。 + +### 核心数据 + +- 客户维度:`biz_cust`、`biz_account`。 +- 抄表维度:`biz_meter_book`、`biz_reading_data`、`biz_last_reading`。 +- 账务与收费维度:`biz_charge`、`biz_charge_detail`。 +- 收费与交易维度:`biz_collection`、`bk_transaction`。 +- 渠道维度:`bk_transaction`、`bk_payment_channel`。 +- 组织与权限维度:`system_dept`、数据权限控制结果。 + +#### 统计主题与口径摘要 + +- `Statistics Theme`:按经营主题组织查询,至少覆盖营收、收费、欠费、客户、渠道、抄表完成率和必要的业务概览。 +- `Statistics Dimension`:按时间、账期、营业所/片区、客户类别、渠道、客户/账户、状态等条件筛选或分组。 +- `Statistics Indicator`:至少明确应收金额、实收金额、欠费余额、账单数、客户数、交易笔数、渠道占比、完成率等指标含义和单位。 +- `Aggregation Source`:统计结果以现有在线主数据聚合、视图或汇总口径承接,不反推为已存在独立统计表族。 + +### 接口映射 + +- `IF-REV-010`:营收、收费、欠费、渠道、客户等统计查询接口,承接主题查询、维度筛选、指标汇总和权限/导出边界。 + +### 落地边界 + +- **已落地**:主要统计源数据在客户、抄表、账单、收费、交易和渠道等领域均已具备,足以支撑经营统计口径设计。 +- **部分落地**:部分统计结果可能依赖聚合视图、汇总查询或报表层实现,当前未见明确的 backend 统计控制器或独立统计模型入口。 +- **文档先行**:预测类、专题分析类深度模型、BI 大屏和独立数仓能力暂不写成后端已实现能力。 + + + +## REV-008 代收与银行业务 + +### 功能说明 + +支持银行代收、银行代扣、实时收费、夜间批量扣款、对账与结算处理,是 SYS-002 面向 `SYS-009` 支付与银行结算能力的业务承接模块。 + +### 业务流程 + + +```mermaid +flowchart TD + A[生成代扣批次] --> B[校验签约与待扣账单] + B --> C[调用IF-REV-011下发批次] + C --> D[SYS-009对接银行处理] + D --> E[回写扣款结果] + E --> F[执行对账与差异识别] + F --> G{差异是否已处理} + G -->|否| H[进入人工补偿] + G -->|是| I[确认结算并更新状态] + +``` + + +### 关键规则 + +1. 渠道、路由、接口配置、签约、交易、回调、异常、对账、结算形成完整银行业务链条。 +2. 实时收费场景由渠道交易流水驱动账单核销,批量代扣场景由签约关系与批次处理驱动。 +3. 对账结果区分一致、长款、短款、失败待处理等状态,支持差异追踪与人工补偿。 +4. 国密报文、批量文件、标准 API 等技术细节由 `SYS-009` 承载,SYS-002 保留业务规则与状态协同。 +5. 当前 backend 已确认 `BankWithholding` 六条银行入口(客户状态查询、送盘、送盘状态查询、取消送盘、回盘、回盘状态查询)已形成最小实现态闭环;`BankCollection` 平行链路、对账与结算协同仍以“部分实现或文档先行”表述,不得统一写成已闭环能力。 +6. 银行代扣文件传输配置按“默认规则 + 银行通道覆盖 + 租户覆盖 + 租户-银行通道覆盖”建模,命中优先级固定为 `TENANT_CHANNEL > TENANT > CHANNEL > DEFAULT`。 +7. 目录字段至少区分 `send/back/reconcile/archive/localTemp` 五类阶段;上层覆盖未完整定义时按字段级回退,不允许生成空路径。 +8. 路径模板仅允许 `{tenantId}`、`{companyId}`、`{channelCode}`、`{yyyyMMdd}`、`{yyyyMM}`、`{batchNo}`、`{fileName}` 七个固定变量;命中未声明变量或缺少变量取值时立即阻断文件动作。 +9. `BankWithholding` 在送盘创建时固化 `sendProtocol/sendDir/sendFilePath` 与 `backProtocol/backDir`,配置切换仅影响新发起文件动作,已落库批次继续沿用原解析结果。 + +### 核心数据 + +- `bk_payment_channel`:支付渠道。 +- `bk_channel_api_config`:渠道接口配置。 +- `bk_channel_route_rule`:渠道路由规则。 +- `bk_withholding_agreement`:代扣签约。 +- `bk_withholding_batch`、`bk_withholding_item`:代扣批次与明细。 +- `bk_reconcile_batch`、`bk_reconcile_diff`:对账批次与差异。 +- `bk_settlement_batch`:结算批次。 +- `bk_transaction`、`bk_transaction_callback`、`bk_transaction_exception`:交易、回调、异常。 +- `biz_collection`、`biz_withholding`:代收/代扣业务主对象。 + +#### 文件传输配置与审计补充 + +- 环境默认规则通过 Spring profile + Nacos 承接,不在仓库样例中写入真实密码、私钥或证书。 +- `bk_channel_api_config` 使用专用 `apiType=FILE_TRANSFER_CONFIG` 承接文件传输覆盖配置,`extParams` 记录作用域、业务类型、协议、连接引用和五类目录字段。 +- `bk_withholding_batch` 固化送盘/回盘目录与协议,`bk_reconcile_batch` 固化对账阶段最终 `protocol/dir/filePath/fileName`,用于审计与问题回放。 + +### 迁移补充(旧系统承接) + +#### 银行托收 + +- 旧系统“银行托收”菜单重点承接托收送盘、托收信息查询和托收结果回看。 +- 当前设计已形成 `biz_collection` + `bk_*` 渠道模型,迁移时应补出“旧托收菜单 → 托收批次/交易/回盘结果”的映射,而不是按旧菜单名平移建模。 +- 旧托收历史记录应至少保留送盘批次、客户范围、送盘结果、回盘结果和账单核销结果。 + +#### 实时收费查询与对账 + +- 旧系统“实时收费”更偏运营查询和渠道对账入口,不只是支付成功回写。 +- 当前建议以 `bk_transaction*` 作为主承接对象,并补充按结算日期、银行/渠道、收费结果、差异状态查询和导出能力说明。 +- 对旧“实时收费汇总/日志/明细”对象,P0 阶段先按历史只读查询口径保留,不误写为当前已落地的独立主模型。 + +#### 当前实现对齐说明 + +- `PayCeb` 路径已具备欠费查询、缴费处理、流水唯一性校验和交易日志留痕,可作为实时收费基础闭环的实现证据。 +- `BankWithholding` 路径已具备签约、解约、客户状态查询、送盘、送盘状态查询、取消送盘、回盘、回盘状态查询及对应交易留痕的实现证据,可作为代扣最小实现态闭环依据。 +- `BankCollection` 路径当前仍仅能确认签约、解约与协议/交易日志处理具备实现证据。 +- 对账、结算、真实银行文件解析、SFTP/文件通道联调和运行态样本补证当前仍未闭环,正式文档应继续保留为后续完善项。 + +### 接口映射 + +- `IF-REV-011`:代扣批次、对账与结算协同入口。 +- `IF-EXT-001`:银行代扣批次下发与回盘协同。 +- `IF-EXT-003`:银行实时收费查询、缴费与结果确认协同。 + +### 落地边界 + +- **已落地**:渠道、路由、交易、回调、异常、代扣/托收签约、解约,以及 `BankWithholding` 的客户状态查询、送盘、送盘状态查询、取消送盘、回盘、回盘状态查询和对应日志留痕等主对象已具备明确实现证据。 +- **部分落地**:`BankCollection` 批次、明细、送盘、回盘、状态查询、差异台账和后台资源管理入口已具备对象或骨架,但不等同于银行协同闭环全部完成;`BankWithholding` 的真实文件解析、异常补偿和运行态联调证据仍待补齐。 +- **文档先行**:夜间批量代扣调度、完整对账处理、结算确认、扩展银行台账等内容不得在当前阶段写成已完成能力。 + + + +## REV-009 业务参数配置 + +### 功能说明 + +负责营收域的价格参数、客户编号规则、页面配置、打印与渠道相关业务参数配置,为客户、开账、收费、发票、催缴等模块提供统一配置支撑。 + +### 关键设计 + +1. 业务参数按租户、单位、片区、业务类别分层管理。 +2. 价格体系、客户编号规则、页面字段配置、打印与通知参数统一归口维护。 +3. 配置变更应具备版本化、操作留痕与生效范围控制。 + +### 核心数据 + +- `biz_parameter_settings`:业务参数配置。 +- `biz_page_settings`、`biz_page_settings_detail`:页面配置。 +- `biz_price_category`、`biz_price_template`、`biz_template_dept_rel`:价格归属与模板站点关系。 +- `biz_cust_no_rule`:客户编号规则。 + - `sys_wechat_app_settings`:微信/微网厅基础配置。 + +### 迁移补充(旧系统承接) + +- 旧系统后台存在“页面配置、业务字段、微信参数、打印维护”等运营配置入口。 +- 当前建议统一按业务参数、页面配置、渠道参数与打印参数归口承接,不新增“微客服后台配置”并行主文档。 +- 迁移时需明确三类配置映射:客户/业务办理字段展示与校验规则、微信/微网厅基础参数、打印模板与补打策略;未确认已实现的高级灰度能力继续按“文档先行”处理。 + +### 接口映射 + +- `IF-REV-012`:查询与维护价格模板、业务参数、页面参数配置。 +- `IF-UP-004`:统一平台参数字典能力协同,为营收域参数提供基础字典支撑。 + +### 落地边界 + +- **已落地**:业务参数、页面配置、价格归属与模板站点关系、客户编号规则等核心配置对象。 +- **部分落地**:部分打印模板、通知策略等参数由统一平台或外部渠道参数共同承载,营收域仅保留业务侧映射。 +- **文档先行**:参数灰度发布、多版本并行生效等高级治理能力当前仅保留设计语义,不宣称为独立实现模块。 diff --git a/output/13_CS_Detailed.docx b/output/13_CS_Detailed.docx new file mode 100644 index 0000000..178da0b Binary files /dev/null and b/output/13_CS_Detailed.docx differ diff --git a/output/13_CS_Detailed.html b/output/13_CS_Detailed.html new file mode 100644 index 0000000..5d3deba --- /dev/null +++ b/output/13_CS_Detailed.html @@ -0,0 +1,616 @@ + + + + + + + + 福建水务营收系统-客户服务模块正文 + + + + + +
    +

    福建水务营收系统-客户服务模块正文

    +

    系统设计团队

    +

    2024年12月19日

    +
    + +

    1 +福建水务营收系统详细设计-客户服务模块正文

    +

    1.1 章节导航(精简)

    + +

    +

    1.2 文档定位

    +

    本文档为 01_Detailed_Design.md +中“客户服务模块详细设计”章节的模块正文拆分稿,便于按模块独立维护。正式交付口径以主详设为准。

    +

    +

    1.3 架构图模块对齐说明

    +

    整体架构图中,客户渠道相关模块同时使用了 CS-* 与 +WECHAT-* 两套编号:

    +
      +
    • CS-* 用于 SYS-002 +营收业务子系统中的客户服务模块群表达;
    • +
    • WECHAT-* 用于 SYS-004 +微网厅子系统中的渠道形态表达。
    • +
    +

    当前详细设计采用“能力域优先”的承接方式,即以 CS-* +作为正式详细设计编号,将 WECHAT-* +视为渠道侧同源能力映射,不另建平行正式主稿。

    + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    架构图模块当前详设承接章节说明
    WECHAT-001 账户绑定管理CS-001微网厅渠道形态映射到统一账户绑定能力
    WECHAT-002 信息查询服务CS-002微网厅账单、发票、流水查询能力映射
    WECHAT-003 在线缴费服务CS-003微网厅渠道缴费入口映射
    WECHAT-004 电子发票服务CS-004微网厅电子发票查看/推送/下载映射
    WECHAT-005 营业网点服务CS-005微网厅网点查询与预约引导映射
    WECHAT-006 业务办理服务CS-006微网厅线上办理入口映射
    WECHAT-007 账户流水CS-002当前并入信息查询服务,不单列平行正文
    WECHAT-008 账号与机构管理CS-001当前并入账户绑定与账户切换能力
    +

    +

    2 客户服务模块详细设计

    +

    +

    2.1 客户服务模块统一约束

    +
      +
    1. 客户服务模块负责渠道侧受理与展示,核心账务、发票、通知结果均由 +SYS-002 统一落账与回写。
    2. +
    3. 支付、发票、消息分别通过 +SYS-009SYS-008SYS-010 +协同完成,客户服务模块不直接承载外部平台业务规则。
    4. +
    5. 账户绑定、在线支付、发票申请、业务办理等关键动作必须进行身份校验与权限校验,禁止匿名高风险操作。
    6. +
    7. 支付与发票场景必须具备幂等控制,避免重复下单、重复开票、重复回写导致业务状态不一致。
    8. +
    9. 渠道请求、结果回写、人工补偿动作应保留可追溯日志,满足审计与争议处理要求。
    10. +
    +

    +

    2.2 接口与数据追溯矩阵

    +
    +

    说明:详细接口字段与报文以 +../03_Technical_Design/03_Interface_Design.md 为准。

    +
    + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    CS 模块关键接口核心数据域(摘要)主要协同对象
    CS-001 账户绑定管理IF-CS-001biz_cust_app_bindsbiz_custbiz_account微信、支付宝、微网厅
    CS-002 信息查询服务IF-CS-002biz_charge*biz_reading_databiz_invoice客户渠道、SYS-002
    CS-003 在线缴费服务IF-CS-003biz_charge*biz_collectionbk_transaction*SYS-009
    CS-004 电子发票服务IF-CS-004biz_invoice*biz_cust_invoiceSYS-008
    CS-005 营业网点服务IF-CS-005biz_outletsbiz_business_types客户渠道
    CS-006 业务办理服务IF-CS-006biz_process*biz_content_attach工单系统、SYS-010
    CS-007 柜面扫码支付IF-CS-007biz_collectionbk_transaction*biz_charge营业厅、SYS-009
    +

    +

    2.3 CS-001 账户绑定管理(对齐 +WECHAT-001 / WECHAT-008)

    +

    2.3.1 功能说明

    +

    面向微信、支付宝、微网厅等渠道实现客户账户绑定、解绑、默认账户设置、多账户切换与身份校验。

    +

    2.3.2 关键规则

    +
      +
    1. 一个渠道账户可绑定多个用水账户。
    2. +
    3. 绑定、解绑、默认账户变更等敏感操作需进行身份校验。
    4. +
    5. 已销户、冻结或限制服务的账户不得新增绑定。
    6. +
    +

    2.3.3 核心数据

    +
      +
    • biz_cust_app_binds
    • +
    • biz_cust
    • +
    • biz_account
    • +
    +

    2.3.4 接口映射

    +
      +
    • IF-CS-001:渠道账户绑定、解绑、默认账户切换。
    • +
    • IF-REV-001:客户与账户信息查询,校验绑定对象合法性。
    • +
    +

    2.3.5 落地边界

    +
      +
    • 已落地:渠道绑定关系、客户与账户主数据引用。
    • +
    • 部分落地:多渠道同账号合并策略依赖业务规则与运营配置共同控制。
    • +
    • 文档先行:跨渠道统一身份画像与复杂合并规则仅保留设计语义。
    • +
    +

    +

    2.4 CS-002 信息查询服务(对齐 +WECHAT-002 / WECHAT-007)

    +

    2.4.1 功能说明

    +

    提供账单查询、缴费记录查询、用水分析、欠费查询、账户流水、历史账单等服务。

    +

    2.4.2 关键设计

    +
      +
    1. 查询范围严格限制在已绑定客户与账户范围内。
    2. +
    3. 账单、缴费、发票、办理进度等数据通过 SYS-002 标准接口聚合展示。
    4. +
    5. 常用历史数据支持按最近周期快速查询。
    6. +
    +

    2.4.3 核心数据

    +
      +
    • biz_cust
    • +
    • biz_account
    • +
    • biz_charge
    • +
    • biz_charge_detail
    • +
    • biz_invoice
    • +
    +

    2.4.4 接口映射

    +
      +
    • IF-CS-002:账单、欠费、缴费、用水、发票等聚合查询。
    • +
    • IF-REV-001:客户基础信息查询与状态校验。
    • +
    • IF-REV-010:统计类查询场景复用营收统计接口能力。
    • +
    +

    2.4.5 落地边界

    +
      +
    • 已落地:账单、缴费、发票、客户信息等基础查询链路。
    • +
    • 部分落地:部分专题分析更多依赖报表端,不在渠道侧单独建模。
    • +
    • 文档先行:个性化推荐与预测分析不作为当前已实现能力表述。
    • +
    +

    +

    2.5 CS-003 在线缴费服务(对齐 +WECHAT-003)

    +

    2.5.1 功能说明

    +

    提供微信支付、支付宝支付、银行卡支付、预存款支付等在线缴费能力。

    +

    2.5.2 业务流程

    +
    flowchart TD
    +    A[提交缴费请求] --> B[校验账单与应缴金额]
    +    B --> C[创建业务订单]
    +    C --> D[调用SYS-009下单]
    +    D --> E[接收支付回调/查询结果]
    +    E --> F[更新核销状态]
    +    F --> G[返回缴费结果]
    +
    +

    2.5.3 关键规则

    +
      +
    1. 下单前再次校验账单未缴状态和应缴金额。
    2. +
    3. 支付结果以 SYS-009 回调/查询确认为准。
    4. +
    5. 对失败订单支持补单、查询与结果回写。
    6. +
    +

    2.5.4 核心数据

    +
      +
    • biz_charge
    • +
    • biz_charge_detail
    • +
    • bk_transaction
    • +
    • bk_transaction_callback
    • +
    +

    2.5.5 接口映射

    +
      +
    • IF-CS-003:客户渠道支付下单入口。
    • +
    • IF-EXT-004IF-EXT-005:支付下单协同与结果回写。
    • +
    • IF-REV-006:账单核销与收费状态更新。
    • +
    +

    2.5.6 落地边界

    +
      +
    • 已落地:渠道下单、支付回调、账单核销主链路。
    • +
    • 部分落地:失败补偿策略部分由支付平台与人工复核协同处理。
    • +
    • 文档先行:复杂营销组合支付与分账能力暂不宣称为已实现。
    • +
    +

    +

    2.6 CS-004 电子发票服务(对齐 +WECHAT-004)

    +

    2.6.1 功能说明

    +

    在客户渠道中提供电子发票申请、查询、下载以及缴费后发票推送能力。

    +

    2.6.2 关键设计

    +
      +
    1. 电子发票开具能力经 SYS-008 统一提供。
    2. +
    3. 发票申请与客户开票信息、缴费记录和账单状态联动校验。
    4. +
    5. 发票结果支持下载、查看和渠道推送。
    6. +
    +

    2.6.3 核心数据

    +
      +
    • biz_invoice
    • +
    • biz_cust_invoice
    • +
    • biz_invoice_taxrate
    • +
    +

    2.6.4 接口映射

    +
      +
    • IF-CS-004:客户侧发票申请与状态查询。
    • +
    • IF-EXT-006IF-EXT-007:发票开具协同与结果回写。
    • +
    • IF-REV-008:营收侧发票主流程协同。
    • +
    +

    2.6.5 落地边界

    +
      +
    • 已落地:发票申请、开票信息校验、开票结果回写。
    • +
    • 部分落地:红冲、补开等复杂票据后处理以发票服务能力为主。
    • +
    • 文档先行:多税率拆票、批量异步重试等高级策略仅保留设计语义。
    • +
    +

    +

    2.7 CS-005 营业网点服务(对齐 +WECHAT-005)

    +

    2.7.1 功能说明

    +

    提供营业网点查询、服务范围查看、办事指引与营业时间展示能力。

    +

    2.7.2 关键设计

    +
      +
    1. 网点信息展示地址、联系电话、营业时间与可办理业务范围。
    2. +
    3. 网点服务以查询与引导为主,不在本模块中虚构额外业务实体表。
    4. +
    5. 与 CS-006 业务办理服务协同,支持从网点查询跳转到线上办理。
    6. +
    +

    2.7.3 核心数据

    +
      +
    • biz_outlets
    • +
    • biz_business_types
    • +
    +

    2.7.4 接口映射

    +
      +
    • IF-CS-005:网点信息、可办事项、预约入口查询。
    • +
    +

    2.7.5 落地边界

    +
      +
    • 已落地:网点查询与办事引导能力。
    • +
    • 部分落地:预约排队等能力可能由外部排队系统承载。
    • +
    • 文档先行:导航路线规划与实时客流预测仅保留扩展方向。
    • +
    +

    +

    2.8 CS-006 业务办理服务(对齐 +WECHAT-006)

    +

    2.8.1 功能说明

    +

    提供更名、过户、联系方式变更、开票方式变更、一户多人口、自主抄表、换表申请等线上业务办理入口。

    +

    2.8.2 关键设计

    +
      +
    1. 业务办理统一调用工单/流程能力,不与后台流程表重复建模。
    2. +
    3. 办理结果与客户资料、工单状态、报装或表务流程联动更新。
    4. +
    5. 触达通知通过 SYS-010 完成结果通知。
    6. +
    +

    2.8.3 核心数据

    +
      +
    • biz_process
    • +
    • biz_process_transfer
    • +
    • biz_content_attach
    • +
    +

    2.8.4 接口映射

    +
      +
    • IF-CS-006:办理申请提交、进度查询、补件上传。
    • +
    • IF-EXT-008:办理结果通知协同。
    • +
    +

    2.8.5 落地边界

    +
      +
    • 已落地:办理申请、进度查询、补件与状态联动。
    • +
    • 部分落地:复杂跨部门并行审批流程依赖后端流程引擎配置。
    • +
    • 文档先行:智能预审与自动分单规则暂不表述为已实现能力。
    • +
    +

    +

    2.9 CS-007 柜面扫码支付

    +

    2.9.1 功能说明

    +

    支持营业厅柜台二维码收款、票据关联、结果回传,是柜台收费场景对线上支付能力的补充入口。

    +

    2.9.2 业务流程

    +
    flowchart TD
    +    A[柜面发起扫码收款] --> B[生成支付订单]
    +    B --> C[客户扫码支付]
    +    C --> D[接收支付结果回写]
    +    D --> E[更新账单核销状态]
    +    E --> F[打印或展示收费凭证]
    +
    +

    2.9.3 关键设计

    +
      +
    1. 柜面扫码支付与 REV-003 营业收费统一核销口径。
    2. +
    3. 支付结果与交易流水经 SYS-009 回传后更新收费状态。
    4. +
    5. 支持支付凭证、发票申请与收费记录联动。
    6. +
    +

    2.9.4 核心数据

    +
      +
    • biz_charge
    • +
    • bk_transaction
    • +
    • bk_transaction_callback
    • +
    +

    2.9.5 接口映射

    +
      +
    • IF-CS-007:柜面扫码支付订单创建与结果回写。
    • +
    • IF-EXT-004IF-EXT-005:支付渠道协同。
    • +
    • IF-REV-006:收费核销与账单状态更新。
    • +
    +

    2.9.6 落地边界

    +
      +
    • 已落地:柜面扫码收款、支付回写、账单核销协同。
    • +
    • 部分落地:柜台班结与对账汇总由营收后台统一统计。
    • +
    • 文档先行:多终端并发收款冲突治理保留为后续优化方向。
    • +
    + + diff --git a/output/13_CS_Detailed.pdf b/output/13_CS_Detailed.pdf new file mode 100644 index 0000000..274e91c Binary files /dev/null and b/output/13_CS_Detailed.pdf differ diff --git a/output/13_CS_Detailed_processed.md b/output/13_CS_Detailed_processed.md new file mode 100644 index 0000000..a9300f5 --- /dev/null +++ b/output/13_CS_Detailed_processed.md @@ -0,0 +1,346 @@ +--- +title: "13_CS_Detailed" +author: "系统设计团队" +date: "2024年12月19日" +documentclass: article +geometry: margin=1in +fontsize: 11pt +mainfont: "PingFang SC" +CJKmainfont: "PingFang SC" +--- + +--- +doc_id: DT-13-CS +doc_role: module_body +authority: secondary +scope: 详细设计-客户服务 +source_of_truth: false +last_reviewed: 2026-03-18 +retrieval_priority: P1 +--- + +# 福建水务营收系统详细设计-客户服务模块正文 + +## 章节导航(精简) + +- [文档定位](#sec-position) +- [架构图模块对齐说明](#sec-cs-alignment) +- [客户服务详细设计正文](#sec-content) + - [客户服务模块统一约束](#sec-cs-rules) + - [接口与数据追溯矩阵](#sec-cs-trace) + - [CS-001 账户绑定管理](#mod-cs-001) + - [CS-002 信息查询服务](#mod-cs-002) + - [CS-003 在线缴费服务](#mod-cs-003) + - [CS-004 电子发票服务](#mod-cs-004) + - [CS-005 营业网点服务](#mod-cs-005) + - [CS-006 业务办理服务](#mod-cs-006) + - [CS-007 柜面扫码支付](#mod-cs-007) + + + +## 文档定位 + +本文档为 `01_Detailed_Design.md` 中“客户服务模块详细设计”章节的模块正文拆分稿,便于按模块独立维护。正式交付口径以主详设为准。 + + + +## 架构图模块对齐说明 + +整体架构图中,客户渠道相关模块同时使用了 `CS-*` 与 `WECHAT-*` 两套编号: + +- `CS-*` 用于 `SYS-002` 营收业务子系统中的客户服务模块群表达; +- `WECHAT-*` 用于 `SYS-004` 微网厅子系统中的渠道形态表达。 + +当前详细设计采用“能力域优先”的承接方式,即以 `CS-*` 作为正式详细设计编号,将 `WECHAT-*` 视为渠道侧同源能力映射,不另建平行正式主稿。 + +| 架构图模块 | 当前详设承接章节 | 说明 | +| --- | --- | --- | +| `WECHAT-001` 账户绑定管理 | `CS-001` | 微网厅渠道形态映射到统一账户绑定能力 | +| `WECHAT-002` 信息查询服务 | `CS-002` | 微网厅账单、发票、流水查询能力映射 | +| `WECHAT-003` 在线缴费服务 | `CS-003` | 微网厅渠道缴费入口映射 | +| `WECHAT-004` 电子发票服务 | `CS-004` | 微网厅电子发票查看/推送/下载映射 | +| `WECHAT-005` 营业网点服务 | `CS-005` | 微网厅网点查询与预约引导映射 | +| `WECHAT-006` 业务办理服务 | `CS-006` | 微网厅线上办理入口映射 | +| `WECHAT-007` 账户流水 | `CS-002` | 当前并入信息查询服务,不单列平行正文 | +| `WECHAT-008` 账号与机构管理 | `CS-001` | 当前并入账户绑定与账户切换能力 | + + + +# 客户服务模块详细设计 + + + +## 客户服务模块统一约束 + +1. 客户服务模块负责渠道侧受理与展示,核心账务、发票、通知结果均由 `SYS-002` 统一落账与回写。 +2. 支付、发票、消息分别通过 `SYS-009`、`SYS-008`、`SYS-010` 协同完成,客户服务模块不直接承载外部平台业务规则。 +3. 账户绑定、在线支付、发票申请、业务办理等关键动作必须进行身份校验与权限校验,禁止匿名高风险操作。 +4. 支付与发票场景必须具备幂等控制,避免重复下单、重复开票、重复回写导致业务状态不一致。 +5. 渠道请求、结果回写、人工补偿动作应保留可追溯日志,满足审计与争议处理要求。 + + + +## 接口与数据追溯矩阵 + +> 说明:详细接口字段与报文以 `../03_Technical_Design/03_Interface_Design.md` 为准。 + +| CS 模块 | 关键接口 | 核心数据域(摘要) | 主要协同对象 | +|---|---|---|---| +| CS-001 账户绑定管理 | `IF-CS-001` | `biz_cust_app_binds`、`biz_cust`、`biz_account` | 微信、支付宝、微网厅 | +| CS-002 信息查询服务 | `IF-CS-002` | `biz_charge*`、`biz_reading_data`、`biz_invoice` | 客户渠道、`SYS-002` | +| CS-003 在线缴费服务 | `IF-CS-003` | `biz_charge*`、`biz_collection`、`bk_transaction*` | `SYS-009` | +| CS-004 电子发票服务 | `IF-CS-004` | `biz_invoice*`、`biz_cust_invoice` | `SYS-008` | +| CS-005 营业网点服务 | `IF-CS-005` | `biz_outlets`、`biz_business_types` | 客户渠道 | +| CS-006 业务办理服务 | `IF-CS-006` | `biz_process*`、`biz_content_attach` | 工单系统、`SYS-010` | +| CS-007 柜面扫码支付 | `IF-CS-007` | `biz_collection`、`bk_transaction*`、`biz_charge` | 营业厅、`SYS-009` | + + + +## CS-001 账户绑定管理(对齐 WECHAT-001 / WECHAT-008) + +### 功能说明 + +面向微信、支付宝、微网厅等渠道实现客户账户绑定、解绑、默认账户设置、多账户切换与身份校验。 + +### 关键规则 + +1. 一个渠道账户可绑定多个用水账户。 +2. 绑定、解绑、默认账户变更等敏感操作需进行身份校验。 +3. 已销户、冻结或限制服务的账户不得新增绑定。 + +### 核心数据 + +- `biz_cust_app_binds` +- `biz_cust` +- `biz_account` + +### 接口映射 + +- `IF-CS-001`:渠道账户绑定、解绑、默认账户切换。 +- `IF-REV-001`:客户与账户信息查询,校验绑定对象合法性。 + +### 落地边界 + +- **已落地**:渠道绑定关系、客户与账户主数据引用。 +- **部分落地**:多渠道同账号合并策略依赖业务规则与运营配置共同控制。 +- **文档先行**:跨渠道统一身份画像与复杂合并规则仅保留设计语义。 + + + +## CS-002 信息查询服务(对齐 WECHAT-002 / WECHAT-007) + +### 功能说明 + +提供账单查询、缴费记录查询、用水分析、欠费查询、账户流水、历史账单等服务。 + +### 关键设计 + +1. 查询范围严格限制在已绑定客户与账户范围内。 +2. 账单、缴费、发票、办理进度等数据通过 SYS-002 标准接口聚合展示。 +3. 常用历史数据支持按最近周期快速查询。 + +### 核心数据 + +- `biz_cust` +- `biz_account` +- `biz_charge` +- `biz_charge_detail` +- `biz_invoice` + +### 接口映射 + +- `IF-CS-002`:账单、欠费、缴费、用水、发票等聚合查询。 +- `IF-REV-001`:客户基础信息查询与状态校验。 +- `IF-REV-010`:统计类查询场景复用营收统计接口能力。 + +### 落地边界 + +- **已落地**:账单、缴费、发票、客户信息等基础查询链路。 +- **部分落地**:部分专题分析更多依赖报表端,不在渠道侧单独建模。 +- **文档先行**:个性化推荐与预测分析不作为当前已实现能力表述。 + + + +## CS-003 在线缴费服务(对齐 WECHAT-003) + +### 功能说明 + +提供微信支付、支付宝支付、银行卡支付、预存款支付等在线缴费能力。 + +### 业务流程 + + +```mermaid +flowchart TD + A[提交缴费请求] --> B[校验账单与应缴金额] + B --> C[创建业务订单] + C --> D[调用SYS-009下单] + D --> E[接收支付回调/查询结果] + E --> F[更新核销状态] + F --> G[返回缴费结果] + +``` + + +### 关键规则 + +1. 下单前再次校验账单未缴状态和应缴金额。 +2. 支付结果以 `SYS-009` 回调/查询确认为准。 +3. 对失败订单支持补单、查询与结果回写。 + +### 核心数据 + +- `biz_charge` +- `biz_charge_detail` +- `bk_transaction` +- `bk_transaction_callback` + +### 接口映射 + +- `IF-CS-003`:客户渠道支付下单入口。 +- `IF-EXT-004`、`IF-EXT-005`:支付下单协同与结果回写。 +- `IF-REV-006`:账单核销与收费状态更新。 + +### 落地边界 + +- **已落地**:渠道下单、支付回调、账单核销主链路。 +- **部分落地**:失败补偿策略部分由支付平台与人工复核协同处理。 +- **文档先行**:复杂营销组合支付与分账能力暂不宣称为已实现。 + + + +## CS-004 电子发票服务(对齐 WECHAT-004) + +### 功能说明 + +在客户渠道中提供电子发票申请、查询、下载以及缴费后发票推送能力。 + +### 关键设计 + +1. 电子发票开具能力经 `SYS-008` 统一提供。 +2. 发票申请与客户开票信息、缴费记录和账单状态联动校验。 +3. 发票结果支持下载、查看和渠道推送。 + +### 核心数据 + +- `biz_invoice` +- `biz_cust_invoice` +- `biz_invoice_taxrate` + +### 接口映射 + +- `IF-CS-004`:客户侧发票申请与状态查询。 +- `IF-EXT-006`、`IF-EXT-007`:发票开具协同与结果回写。 +- `IF-REV-008`:营收侧发票主流程协同。 + +### 落地边界 + +- **已落地**:发票申请、开票信息校验、开票结果回写。 +- **部分落地**:红冲、补开等复杂票据后处理以发票服务能力为主。 +- **文档先行**:多税率拆票、批量异步重试等高级策略仅保留设计语义。 + + + +## CS-005 营业网点服务(对齐 WECHAT-005) + +### 功能说明 + +提供营业网点查询、服务范围查看、办事指引与营业时间展示能力。 + +### 关键设计 + +1. 网点信息展示地址、联系电话、营业时间与可办理业务范围。 +2. 网点服务以查询与引导为主,不在本模块中虚构额外业务实体表。 +3. 与 CS-006 业务办理服务协同,支持从网点查询跳转到线上办理。 + +### 核心数据 + +- `biz_outlets` +- `biz_business_types` + +### 接口映射 + +- `IF-CS-005`:网点信息、可办事项、预约入口查询。 + +### 落地边界 + +- **已落地**:网点查询与办事引导能力。 +- **部分落地**:预约排队等能力可能由外部排队系统承载。 +- **文档先行**:导航路线规划与实时客流预测仅保留扩展方向。 + + + +## CS-006 业务办理服务(对齐 WECHAT-006) + +### 功能说明 + +提供更名、过户、联系方式变更、开票方式变更、一户多人口、自主抄表、换表申请等线上业务办理入口。 + +### 关键设计 + +1. 业务办理统一调用工单/流程能力,不与后台流程表重复建模。 +2. 办理结果与客户资料、工单状态、报装或表务流程联动更新。 +3. 触达通知通过 `SYS-010` 完成结果通知。 + +### 核心数据 + +- `biz_process` +- `biz_process_transfer` +- `biz_content_attach` + +### 接口映射 + +- `IF-CS-006`:办理申请提交、进度查询、补件上传。 +- `IF-EXT-008`:办理结果通知协同。 + +### 落地边界 + +- **已落地**:办理申请、进度查询、补件与状态联动。 +- **部分落地**:复杂跨部门并行审批流程依赖后端流程引擎配置。 +- **文档先行**:智能预审与自动分单规则暂不表述为已实现能力。 + + + +## CS-007 柜面扫码支付 + +### 功能说明 + +支持营业厅柜台二维码收款、票据关联、结果回传,是柜台收费场景对线上支付能力的补充入口。 + +### 业务流程 + + +```mermaid +flowchart TD + A[柜面发起扫码收款] --> B[生成支付订单] + B --> C[客户扫码支付] + C --> D[接收支付结果回写] + D --> E[更新账单核销状态] + E --> F[打印或展示收费凭证] + +``` + + +### 关键设计 + +1. 柜面扫码支付与 REV-003 营业收费统一核销口径。 +2. 支付结果与交易流水经 `SYS-009` 回传后更新收费状态。 +3. 支持支付凭证、发票申请与收费记录联动。 + +### 核心数据 + +- `biz_charge` +- `bk_transaction` +- `bk_transaction_callback` + +### 接口映射 + +- `IF-CS-007`:柜面扫码支付订单创建与结果回写。 +- `IF-EXT-004`、`IF-EXT-005`:支付渠道协同。 +- `IF-REV-006`:收费核销与账单状态更新。 + +### 落地边界 + +- **已落地**:柜面扫码收款、支付回写、账单核销协同。 +- **部分落地**:柜台班结与对账汇总由营收后台统一统计。 +- **文档先行**:多终端并发收款冲突治理保留为后续优化方向。 diff --git a/output/14_METER_Detailed.docx b/output/14_METER_Detailed.docx new file mode 100644 index 0000000..11b10c8 Binary files /dev/null and b/output/14_METER_Detailed.docx differ diff --git a/output/14_METER_Detailed.html b/output/14_METER_Detailed.html new file mode 100644 index 0000000..d2b1e99 --- /dev/null +++ b/output/14_METER_Detailed.html @@ -0,0 +1,381 @@ + + + + + + + + 福建水务营收系统-表务模块正文 + + + + + +
    +

    福建水务营收系统-表务模块正文

    +

    系统设计团队

    +

    2024年12月19日

    +
    + +

    1 +福建水务营收系统详细设计-表务模块正文

    +

    1.1 章节导航(精简)

    + +

    +

    1.2 文档定位

    +

    本文档为 01_Detailed_Design.md +中“表务详细设计”章节的模块正文拆分稿,便于按模块独立维护。正式交付口径以主详设为准。

    +

    +

    2 表务详细设计

    +

    +

    2.1 表务模块统一约束

    +
      +
    1. 表务模块负责水表档案、状态、库存、工单与物联网接入,账单生成仍归属 +SYS-002 营收主流程。
    2. +
    3. 水表状态变更必须通过表务工单、出入库动作或报装装表流程驱动,不允许绕过业务过程直接改写生命周期状态。
    4. +
    5. 换表、移表、拆表、复装完成后,必须同步客户绑定关系、安装位置和最新表计状态,避免档案与现场状态不一致。
    6. +
    7. 库存、出入库、报废等动作必须具备批次追溯与操作留痕,满足审计与责任界定要求。
    8. +
    9. 远传抄表与设备告警数据进入 SYS-002 +后,必须先完成校验和异常判断,再进入抄表开账链路。
    10. +
    +

    +

    2.2 接口与数据追溯矩阵

    +
    +

    说明:接口字段以 +../03_Technical_Design/03_Interface_Design.md +为准,数据库口径以 +../03_Technical_Design/01_Database_Design.md 为准。

    +
    + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    METER 模块关键接口核心数据域(摘要)主要协同对象
    METER-001 表务基础管理IF-METER-001biz_meterbiz_meter_modelbiz_meter_caliberbiz_meter_range营收、报装
    METER-002 仓库与库存管理IF-METER-003biz_meter_in_outbiz_meter_in_out_relbiz_meter仓储管理端
    METER-003 设备档案管理IF-METER-001IF-METER-002IF-METER-004biz_meterbiz_meter_logbiz_process*biz_meter_readbiz_reading_databiz_last_reading工单系统、移动作业、IoT 平台、营收开账
    +

    +

    2.3 METER-001 表务基础管理

    +

    2.3.1 功能说明

    +

    管理水表档案、厂家、型号、口径、量程、检定证书、安装位置、当前状态等基础信息。

    +

    2.3.2 关键设计

    +
      +
    • 一块水表对应唯一档案主记录。
    • +
    • 设备状态覆盖在库、在用、待检、故障、报废等。
    • +
    • 与客户、水表工单、抄表记录形成关联闭环。
    • +
    +

    2.3.3 核心数据

    +
      +
    • biz_meter:水表主档。
    • +
    • biz_meter_model:水表型号。
    • +
    • biz_meter_caliber:水表口径。
    • +
    • biz_meter_range:水表量程。
    • +
    • biz_last_reading:最近有效读数状态。
    • +
    +

    2.3.4 接口映射

    +
      +
    • IF-METER-001:查询水表档案、状态与生命周期信息。
    • +
    • IF-REV-001:客户侧查询场景复用表计关联信息。
    • +
    +

    2.3.5 落地边界

    +
      +
    • 已落地:水表主档、型号、口径、量程、状态等基础档案对象。
    • +
    • 部分落地:证书、检定批次、厂家深度评价等附属对象可能由扩展字段或附件承载。
    • +
    • 文档先行:复杂设备健康评分与预测性维护不作为当前已实现能力表述。
    • +
    +

    +

    2.4 METER-002 仓库与库存管理

    +

    2.4.1 功能说明

    +

    管理新表入库、领用、出库、退库、报废及库存预警,是架构图中“仓库与库存管理”模块的正式承接章节。

    +

    2.4.2 关键设计

    +
      +
    1. 库存动作以批次和明细双层结构记录,支持领用、退库、报废等全过程追溯。
    2. +
    3. 库存状态与设备生命周期联动更新,避免“账上在库、现场在用”不一致。
    4. +
    5. 报废、退库等高风险动作需保留审批或责任人留痕。
    6. +
    +

    2.4.3 核心数据

    +
      +
    • biz_meter_in_out:出入库主表。
    • +
    • biz_meter_in_out_rel:出入库明细关系。
    • +
    • biz_meter_log:库存与生命周期动作留痕。
    • +
    • biz_meter:生命周期状态主对象。
    • +
    +

    2.4.4 接口映射

    +
      +
    • IF-METER-003:领用、退库、报废等库存动作处理。
    • +
    +

    2.4.5 落地边界

    +
      +
    • 已落地:出入库主明细、库存状态回写、动作留痕。
    • +
    • 部分落地:仓位优化、库龄分析等能力可能通过报表层实现,而非独立业务对象。
    • +
    • 文档先行:自动补货策略与仓网优化仅保留设计方向。
    • +
    +

    +

    2.5 METER-003 设备档案管理

    +

    2.5.1 功能说明

    +

    管理水表唯一电子档案、状态流转、安装历史、质检追溯,并统一承接表务工单和物联网同步相关能力。

    +

    2.5.2 关键设计

    +
      +
    1. 一块水表对应唯一档案主记录,覆盖在库、在用、待检、故障、报废等状态。
    2. +
    3. 设备档案同时关联安装历史、维修记录、库存动作与最近有效读数,形成全生命周期追溯闭环。
    4. +
    5. 表务工单和远传同步能力属于设备档案管理下的实施态支撑能力,不再作为独立模块编号表达。
    6. +
    +

    2.5.3 核心数据

    +
      +
    • biz_meter:水表主档与状态主对象。
    • +
    • biz_meter_log:设备过程留痕与工单回写对象。
    • +
    • biz_processbiz_process_transfer:表务工单流程主线。
    • +
    • biz_meter_readbiz_reading_databiz_last_reading:读数、状态与同步对象。
    • +
    +

    2.5.4 接口映射

    +
      +
    • IF-METER-001:查询水表档案、状态与生命周期信息。
    • +
    • IF-METER-002:换表、移表、校表、维修等处理结果提交。
    • +
    • IF-METER-004:远传抄表、告警与状态同步接收。
    • +
    +

    2.5.5 落地边界

    +
      +
    • 已落地:设备主档、状态流转、工单留痕、远传同步与异常标记能力。
    • +
    • 部分落地:质检批次、厂家评价、复杂设备健康评分等附属对象可能由扩展字段、附件或报表层承接。
    • +
    • 文档先行:预测性维护和实时控制指令不作为当前正式实现口径。
    • +
    +

    +

    2.5.6 物联网接入与数据同步能力

    +

    2.5.7 功能说明

    +

    接入集抄系统、智能表平台及厂家物联网平台,实现远程抄表、状态查询、设备参数同步与异常告警。

    +

    2.5.8 业务流程

    +
    flowchart TD
    +    A[定时采集任务] --> B[发送采集请求]
    +    B --> C[物联网平台返回数据]
    +    C --> D[数据校验]
    +    D --> E{是否有效}
    +    E -->|有效| F[写入抄表记录]
    +    E -->|无效| G[异常标记并告警]
    +    F --> H[参与开账]
    +    G --> I[人工复核处理]
    +
    +

    2.5.9 关键规则

    +
      +
    1. 远传抄表结果必须校验设备标识、采集时间、读数合法性和重复上送情况。
    2. +
    3. 异常读数、离线状态、设备告警需区分业务异常与设备异常两类处理。
    4. +
    5. 校验通过的有效读数进入抄表开账链路,异常结果需保留人工复核入口。
    6. +
    +

    2.5.10 核心数据

    +
      +
    • biz_meter_read:抄表任务或状态承接对象。
    • +
    • biz_reading_data:远传读数数据。
    • +
    • biz_last_reading:最新有效读数。
    • +
    • biz_meter:设备状态与参数关联对象。
    • +
    +

    2.5.11 接口映射

    +
      +
    • IF-METER-004:远传抄表、告警与状态同步接收。
    • +
    • IF-EXT-009:IoT/集抄平台数据接入协同。
    • +
    • IF-REV-004IF-REV-005:校验通过后进入抄表提交与开账流程。
    • +
    +

    2.5.12 落地边界

    +
      +
    • 已落地:远传数据接入、基础校验、异常标记与读数同步。
    • +
    • 部分落地:复杂设备诊断与厂家私有协议适配更多由外部 +IoT 平台承载。
    • +
    • 文档先行:边缘计算、实时控制指令等能力不作为当前正式实现口径。
    • +
    +

    +

    2.5.13 表务工单协同能力

    +

    处理换表、移表、拆表、复装、校表、稽查、维修等表务工单,是 +METER-003 设备档案管理的实施态过程能力。

    +

    2.5.13.1 业务流程

    +
    flowchart TD
    +    A[创建表务工单] --> B[派发现场任务]
    +    B --> C[现场处理并采集结果]
    +    C --> D[回写旧表/新表信息]
    +    D --> E[更新水表状态与客户绑定]
    +    E --> F[写入过程日志与附件]
    +    F --> G[工单办结]
    +
    +

    2.5.13.2 关键规则

    +
      +
    1. 工单类型决定必填字段、处理流程和附件要求。
    2. +
    3. 换表工单需同时记录旧表拆除信息与新表安装信息。
    4. +
    5. 工单完成后同步更新设备档案、客户绑定关系与安装历史。
    6. +
    + + diff --git a/output/14_METER_Detailed.pdf b/output/14_METER_Detailed.pdf new file mode 100644 index 0000000..2579e32 Binary files /dev/null and b/output/14_METER_Detailed.pdf differ diff --git a/output/14_METER_Detailed_processed.md b/output/14_METER_Detailed_processed.md new file mode 100644 index 0000000..504b3bf --- /dev/null +++ b/output/14_METER_Detailed_processed.md @@ -0,0 +1,238 @@ +--- +title: "14_METER_Detailed" +author: "系统设计团队" +date: "2024年12月19日" +documentclass: article +geometry: margin=1in +fontsize: 11pt +mainfont: "PingFang SC" +CJKmainfont: "PingFang SC" +--- + +--- +doc_id: DT-14-METER +doc_role: module_body +authority: secondary +scope: 详细设计-表务管理 +source_of_truth: false +last_reviewed: 2026-03-18 +retrieval_priority: P1 +--- + +# 福建水务营收系统详细设计-表务模块正文 + +## 章节导航(精简) + +- [文档定位](#sec-position) +- [表务详细设计正文](#sec-content) + - [表务模块统一约束](#sec-meter-rules) + - [接口与数据追溯矩阵](#sec-meter-trace) + - [METER-001 表务基础管理](#mod-meter-001) + - [METER-002 仓库与库存管理](#mod-meter-002) + - [METER-003 设备档案管理](#mod-meter-003) + + + +## 文档定位 + +本文档为 `01_Detailed_Design.md` 中“表务详细设计”章节的模块正文拆分稿,便于按模块独立维护。正式交付口径以主详设为准。 + + + +# 表务详细设计 + + + +## 表务模块统一约束 + +1. 表务模块负责水表档案、状态、库存、工单与物联网接入,账单生成仍归属 `SYS-002` 营收主流程。 +2. 水表状态变更必须通过表务工单、出入库动作或报装装表流程驱动,不允许绕过业务过程直接改写生命周期状态。 +3. 换表、移表、拆表、复装完成后,必须同步客户绑定关系、安装位置和最新表计状态,避免档案与现场状态不一致。 +4. 库存、出入库、报废等动作必须具备批次追溯与操作留痕,满足审计与责任界定要求。 +5. 远传抄表与设备告警数据进入 `SYS-002` 后,必须先完成校验和异常判断,再进入抄表开账链路。 + + + +## 接口与数据追溯矩阵 + +> 说明:接口字段以 `../03_Technical_Design/03_Interface_Design.md` 为准,数据库口径以 `../03_Technical_Design/01_Database_Design.md` 为准。 + +| METER 模块 | 关键接口 | 核心数据域(摘要) | 主要协同对象 | +|---|---|---|---| +| METER-001 表务基础管理 | `IF-METER-001` | `biz_meter`、`biz_meter_model`、`biz_meter_caliber`、`biz_meter_range` | 营收、报装 | +| METER-002 仓库与库存管理 | `IF-METER-003` | `biz_meter_in_out`、`biz_meter_in_out_rel`、`biz_meter` | 仓储管理端 | +| METER-003 设备档案管理 | `IF-METER-001`、`IF-METER-002`、`IF-METER-004` | `biz_meter`、`biz_meter_log`、`biz_process*`、`biz_meter_read`、`biz_reading_data`、`biz_last_reading` | 工单系统、移动作业、IoT 平台、营收开账 | + + + +## METER-001 表务基础管理 + +### 功能说明 + +管理水表档案、厂家、型号、口径、量程、检定证书、安装位置、当前状态等基础信息。 + +### 关键设计 + +- 一块水表对应唯一档案主记录。 +- 设备状态覆盖在库、在用、待检、故障、报废等。 +- 与客户、水表工单、抄表记录形成关联闭环。 + +### 核心数据 + +- `biz_meter`:水表主档。 +- `biz_meter_model`:水表型号。 +- `biz_meter_caliber`:水表口径。 +- `biz_meter_range`:水表量程。 +- `biz_last_reading`:最近有效读数状态。 + +### 接口映射 + +- `IF-METER-001`:查询水表档案、状态与生命周期信息。 +- `IF-REV-001`:客户侧查询场景复用表计关联信息。 + +### 落地边界 + +- **已落地**:水表主档、型号、口径、量程、状态等基础档案对象。 +- **部分落地**:证书、检定批次、厂家深度评价等附属对象可能由扩展字段或附件承载。 +- **文档先行**:复杂设备健康评分与预测性维护不作为当前已实现能力表述。 + + + +## METER-002 仓库与库存管理 + +### 功能说明 + +管理新表入库、领用、出库、退库、报废及库存预警,是架构图中“仓库与库存管理”模块的正式承接章节。 + +### 关键设计 + +1. 库存动作以批次和明细双层结构记录,支持领用、退库、报废等全过程追溯。 +2. 库存状态与设备生命周期联动更新,避免“账上在库、现场在用”不一致。 +3. 报废、退库等高风险动作需保留审批或责任人留痕。 + +### 核心数据 + +- `biz_meter_in_out`:出入库主表。 +- `biz_meter_in_out_rel`:出入库明细关系。 +- `biz_meter_log`:库存与生命周期动作留痕。 +- `biz_meter`:生命周期状态主对象。 + +### 接口映射 + +- `IF-METER-003`:领用、退库、报废等库存动作处理。 + +### 落地边界 + +- **已落地**:出入库主明细、库存状态回写、动作留痕。 +- **部分落地**:仓位优化、库龄分析等能力可能通过报表层实现,而非独立业务对象。 +- **文档先行**:自动补货策略与仓网优化仅保留设计方向。 + + + +## METER-003 设备档案管理 + +### 功能说明 + +管理水表唯一电子档案、状态流转、安装历史、质检追溯,并统一承接表务工单和物联网同步相关能力。 + +### 关键设计 + +1. 一块水表对应唯一档案主记录,覆盖在库、在用、待检、故障、报废等状态。 +2. 设备档案同时关联安装历史、维修记录、库存动作与最近有效读数,形成全生命周期追溯闭环。 +3. 表务工单和远传同步能力属于设备档案管理下的实施态支撑能力,不再作为独立模块编号表达。 + +### 核心数据 + +- `biz_meter`:水表主档与状态主对象。 +- `biz_meter_log`:设备过程留痕与工单回写对象。 +- `biz_process`、`biz_process_transfer`:表务工单流程主线。 +- `biz_meter_read`、`biz_reading_data`、`biz_last_reading`:读数、状态与同步对象。 + +### 接口映射 + +- `IF-METER-001`:查询水表档案、状态与生命周期信息。 +- `IF-METER-002`:换表、移表、校表、维修等处理结果提交。 +- `IF-METER-004`:远传抄表、告警与状态同步接收。 + +### 落地边界 + +- **已落地**:设备主档、状态流转、工单留痕、远传同步与异常标记能力。 +- **部分落地**:质检批次、厂家评价、复杂设备健康评分等附属对象可能由扩展字段、附件或报表层承接。 +- **文档先行**:预测性维护和实时控制指令不作为当前正式实现口径。 + + + +### 物联网接入与数据同步能力 + +### 功能说明 + +接入集抄系统、智能表平台及厂家物联网平台,实现远程抄表、状态查询、设备参数同步与异常告警。 + +### 业务流程 + + +```mermaid +flowchart TD + A[定时采集任务] --> B[发送采集请求] + B --> C[物联网平台返回数据] + C --> D[数据校验] + D --> E{是否有效} + E -->|有效| F[写入抄表记录] + E -->|无效| G[异常标记并告警] + F --> H[参与开账] + G --> I[人工复核处理] + +``` + + +### 关键规则 + +1. 远传抄表结果必须校验设备标识、采集时间、读数合法性和重复上送情况。 +2. 异常读数、离线状态、设备告警需区分业务异常与设备异常两类处理。 +3. 校验通过的有效读数进入抄表开账链路,异常结果需保留人工复核入口。 + +### 核心数据 + +- `biz_meter_read`:抄表任务或状态承接对象。 +- `biz_reading_data`:远传读数数据。 +- `biz_last_reading`:最新有效读数。 +- `biz_meter`:设备状态与参数关联对象。 + +### 接口映射 + +- `IF-METER-004`:远传抄表、告警与状态同步接收。 +- `IF-EXT-009`:IoT/集抄平台数据接入协同。 +- `IF-REV-004`、`IF-REV-005`:校验通过后进入抄表提交与开账流程。 + +### 落地边界 + +- **已落地**:远传数据接入、基础校验、异常标记与读数同步。 +- **部分落地**:复杂设备诊断与厂家私有协议适配更多由外部 IoT 平台承载。 +- **文档先行**:边缘计算、实时控制指令等能力不作为当前正式实现口径。 + + + +### 表务工单协同能力 + +处理换表、移表、拆表、复装、校表、稽查、维修等表务工单,是 `METER-003` 设备档案管理的实施态过程能力。 + +#### 业务流程 + + +```mermaid +flowchart TD + A[创建表务工单] --> B[派发现场任务] + B --> C[现场处理并采集结果] + C --> D[回写旧表/新表信息] + D --> E[更新水表状态与客户绑定] + E --> F[写入过程日志与附件] + F --> G[工单办结] + +``` + + +#### 关键规则 + +1. 工单类型决定必填字段、处理流程和附件要求。 +2. 换表工单需同时记录旧表拆除信息与新表安装信息。 +3. 工单完成后同步更新设备档案、客户绑定关系与安装历史。 diff --git a/output/15_INST_Detailed.docx b/output/15_INST_Detailed.docx new file mode 100644 index 0000000..a742f48 Binary files /dev/null and b/output/15_INST_Detailed.docx differ diff --git a/output/15_INST_Detailed.html b/output/15_INST_Detailed.html new file mode 100644 index 0000000..b3ccc80 --- /dev/null +++ b/output/15_INST_Detailed.html @@ -0,0 +1,495 @@ + + + + + + + + 福建水务营收系统-报装与签章模块正文 + + + + + +
    +

    福建水务营收系统-报装与签章模块正文

    +

    系统设计团队

    +

    2024年12月19日

    +
    + +

    1 +福建水务营收系统详细设计-报装与签章模块正文

    +

    1.1 章节导航(精简)

    + +

    +

    1.2 文档定位

    +

    本文档为 01_Detailed_Design.md +中“报装与签章详细设计”章节的模块正文拆分稿,便于按模块独立维护。正式交付口径以主详设为准。

    +

    +

    2 报装与签章详细设计

    +

    +

    2.1 报装模块统一约束

    +
      +
    1. 报装模块承担 SYS-002 +中“申请受理、踏勘方案、施工验收、立户通水、合同签章、档案归档”的完整主流程,流程主线以 +biz_process*biz_content* +为当前实现态口径。
    2. +
    3. 报装申请、踏勘结果、验收结果、签章回执、归档动作均必须通过流程节点驱动,不允许直接绕过业务过程修改主状态。
    4. +
    5. 施工验收通过后,方可进入客户建档、水表绑定、账户初始化与通水确认,避免前后置业务状态错位。
    6. +
    7. 电子签章专题表 installation_* +当前为“专题扩展口径”,若实施库结构与专题设计不一致,以实施库与主详设联合评审结果为准。
    8. +
    9. 报装过程中的申请材料、验收附件、签章文件、存证回执必须统一归档并具备可检索、可追溯能力。
    10. +
    +

    +

    2.2 接口与数据追溯矩阵

    +
    +

    说明:接口字段以 +../03_Technical_Design/03_Interface_Design.md +为准,数据库口径以 +../03_Technical_Design/01_Database_Design.md 为准。

    +
    + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    INST 模块关键接口核心数据域(摘要)主要协同对象
    INST-001 报装流程管理IF-INST-001IF-INST-002biz_processbiz_contentbiz_content_attachbiz_process_transferbiz_business_datas柜台、微网厅、政务平台、报装人员
    INST-002 工程管理IF-INST-003IF-INST-004IF-INST-005biz_process_meter_installbiz_processbiz_meterinstallation_contractinstallation_signatureinstallation_evidence表务、客户建档、泛微 CA
    INST-003 档案管理IF-INST-005biz_content_attachinstallation_evidence、过程日志报装、档案管理
    +

    +

    2.3 INST-001 报装流程管理

    +

    2.3.1 功能说明

    +

    承接新装、改造、一户一表等业务从申请受理到现场踏勘、方案编制的前半段主流程,是架构图中“报装流程管理”模块的正式承接章节。

    +

    2.3.2 业务流程

    +
    flowchart TD
    +    A[提交报装申请] --> B[采集申请信息与附件]
    +    B --> C[受理校验]
    +    C --> D{是否通过}
    +    D -->|否| E[退回补充资料]
    +    D -->|是| F[生成报装编号]
    +    F --> G[创建流程实例]
    +    G --> H[进入踏勘环节]
    +
    +

    2.3.3 关键设计

    +
      +
    • 统一采集申请人、地址、产权、用水性质、附件材料等信息。
    • +
    • 支持政务平台、柜台、微网厅等多入口申请。
    • +
    • 受理后自动生成报装编号并进入踏勘流程。
    • +
    +

    2.3.4 核心数据

    +
      +
    • biz_process:报装流程主表。
    • +
    • biz_content:申请资料主对象。
    • +
    • biz_content_attach:申请附件。
    • +
    • installation_application:报装申请映射对象(设计态)。
    • +
    +

    2.3.5 接口映射

    +
      +
    • IF-INST-001:提交报装申请、申请资料与附件。
    • +
    • IF-INST-002:回填踏勘结果、方案、审核结果。
    • +
    • IF-CS-006:客户渠道办理入口可复用报装申请主线。
    • +
    +

    2.3.6 落地边界

    +
      +
    • 已落地:申请受理主流程、资料与附件采集、流程实例创建。
    • +
    • 部分落地:不同报装类型的细化受理规则、踏勘方案差异更多依赖流程和参数配置。
    • +
    • 文档先行installation_application +当前按设计态保留,不宣称为实施库既有事实表。
    • +
    +

    +

    2.3.7 踏勘与方案设计能力

    +

    2.3.8 功能说明

    +

    组织现场勘查、工程条件确认、材料测算、施工方案与费用方案编制。

    +

    2.3.9 业务流程

    +
    flowchart TD
    +    A[接收踏勘任务] --> B[现场勘查与拍照]
    +    B --> C[记录供水条件与施工约束]
    +    C --> D[编制方案与费用]
    +    D --> E[提交审核]
    +    E --> F{审核是否通过}
    +    F -->|否| G[退回修改]
    +    F -->|是| H[进入施工或合同环节]
    +
    +

    2.3.10 关键设计

    +
      +
    1. 踏勘记录包括现场照片、供水接入条件、施工难点、估算费用。
    2. +
    3. 方案版本化管理,支持设计审核与退回修改。
    4. +
    5. 勘查结果直接驱动合同金额与施工计划。
    6. +
    +

    2.3.11 核心数据

    +
      +
    • biz_process_transfer:节点流转与处理记录。
    • +
    • biz_business_datas:踏勘与方案扩展数据。
    • +
    • biz_content_attach:现场照片与附件资料。
    • +
    +

    2.3.12 接口映射

    +
      +
    • IF-INST-002:回填踏勘结果、方案、审核结果。
    • +
    +

    2.3.13 落地边界

    +
      +
    • 已落地:踏勘流转、扩展数据回填、现场资料挂接。
    • +
    • 部分落地:材料测算、工程造价等可能在扩展数据或外部附件中承载。
    • +
    • 文档先行:复杂 +BIM/预算系统联动不作为当前正式实现口径。
    • +
    +

    +

    2.4 INST-002 工程管理

    +

    2.4.1 功能说明

    +

    承接施工派工、安装实施、竣工验收、立户通水以及合同签章协同,是架构图中“工程管理”模块的正式承接章节。

    +

    2.4.2 业务流程

    +
    flowchart TD
    +    A[下发施工任务] --> B[现场安装实施]
    +    B --> C[录入装表与施工结果]
    +    C --> D[提交竣工验收]
    +    D --> E{验收是否通过}
    +    E -->|否| F[整改后复验]
    +    E -->|是| G[触发客户建档与水表绑定]
    +    G --> H[初始化账户并确认通水]
    +
    +

    2.4.3 关键设计

    +
      +
    • 施工节点按派工、实施、验收、归档逐步留痕。
    • +
    • 验收通过后自动触发客户建档、水表绑定和账户初始化。
    • +
    • 与表务系统共享水表安装与换表数据。
    • +
    +

    2.4.4 核心数据

    +
      +
    • biz_process:施工与验收流程主线。
    • +
    • biz_process_meter_install:装表落地信息。
    • +
    • biz_meter:水表安装与状态回写对象。
    • +
    • biz_custbiz_account:立户后续创建对象。
    • +
    +

    2.4.5 接口映射

    +
      +
    • IF-INST-005:归档验收资料并提交最终办结信息。
    • +
    • IF-INST-003:发起电子签章任务并传输合同信息。
    • +
    • IF-INST-004:回写签章结果、时间戳和存证信息。
    • +
    • IF-METER-001IF-METER-002:装表与表务状态协同。
    • +
    • IF-REV-001:立户后客户主档进入营收主数据域。
    • +
    +

    2.4.6 落地边界

    +
      +
    • 已落地:施工验收主线、装表结果留痕、客户建档与水表绑定协同。
    • +
    • 部分落地:施工派工计划与现场资源调度可能由外部施工管理工具承载。
    • +
    • 文档先行:复杂工程项目管理和材料成本结转不作为当前正式开发边界。
    • +
    +

    +

    2.4.7 合同签署与电子签章能力

    +

    2.4.8 功能说明

    +

    通过集成泛微 CA +电子签章系统,实现报装合同、用水协议等文件的电子签署、时间戳和电子存证。

    +

    2.4.9 集成架构

    +
    graph TD
    +    subgraph INST[报装业务系统]
    +        A[申请受理]
    +        B[合同管理]
    +        C[电子签章模块]
    +        D[档案归档]
    +    end
    +
    +    subgraph CA[泛微CA电子签章系统]
    +        E[身份认证服务]
    +        F[电子签章服务]
    +        G[时间戳服务]
    +        H[电子存证服务]
    +    end
    +
    +    A --> B
    +    B --> C
    +    C --> E
    +    C --> F
    +    C --> G
    +    C --> H
    +    C --> D
    +
    +

    2.4.10 合同签署流程

    +
    sequenceDiagram
    +    participant 客户
    +    participant 报装系统
    +    participant 电子签章模块
    +    participant 泛微CA系统
    +
    +    客户->>报装系统: 提交签署申请
    +    报装系统->>电子签章模块: 生成签署任务
    +    电子签章模块->>泛微CA系统: 发起身份认证
    +    泛微CA系统-->>电子签章模块: 返回认证结果
    +    电子签章模块->>泛微CA系统: 发起电子签章
    +    泛微CA系统-->>电子签章模块: 返回签章结果
    +    电子签章模块->>泛微CA系统: 申请时间戳与存证
    +    泛微CA系统-->>电子签章模块: 返回凭证
    +    电子签章模块-->>报装系统: 返回签署结果
    +    报装系统-->>客户: 通知合同签署完成
    +
    +

    2.4.11 核心数据

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    数据对象说明
    installation_contract报装合同主表(设计态专题扩展)
    installation_signature电子签章记录表(设计态专题扩展)
    installation_evidence电子存证记录表(设计态专题扩展)
    installation_signature_template签章模板与签署位置配置
    +

    2.4.12 关键规则

    +
      +
    1. 合同签署前必须完成身份认证。
    2. +
    3. 合同正文、签署位置、签署人、签署时间必须完整留痕。
    4. +
    5. 签署完成文件必须归档并生成可验证凭证。
    6. +
    7. 外部 CA 接口异常时应支持重试与人工补偿处理。
    8. +
    +

    2.4.13 接口映射

    +
      +
    • IF-INST-003:发起合同签署任务并传递合同信息。
    • +
    • IF-INST-004:回写签章结果、时间戳和存证信息。
    • +
    +

    2.4.14 落地边界

    +
      +
    • 已落地:签章流程、签章回执、时间戳与存证协同设计口径已明确。
    • +
    • 部分落地installation_* +当前在数据库主文档中按专题扩展纳管,实施库需联合评审确认最终落表。
    • +
    • 文档先行:多 CA +厂商切换、批量签署编排等高级能力暂不表述为当前既有实现。
    • +
    +

    +

    2.5 INST-003 档案管理

    +

    2.5.1 功能说明

    +

    归集申请材料、设计方案、合同文件、验收资料、签章回执和过程日志,形成完整报装档案。

    +

    2.5.2 关键设计

    +
      +
    • 档案按申请单维度统一归档。
    • +
    • 电子签章合同、验收附件、影像资料统一存储。
    • +
    • 档案查询支持按申请编号、客户、地址、时间、状态检索。
    • +
    +

    2.5.3 核心数据

    +
      +
    • biz_content_attach:报装材料、验收附件、影像资料。
    • +
    • installation_evidence:签章存证与回执资料。
    • +
    • biz_processbiz_process_transfer:过程留痕主线。
    • +
    +

    2.5.4 接口映射

    +
      +
    • IF-INST-005:归档申请、合同、验收资料与签章回执。
    • +
    • IF-INST-004:签章回执结果进入归档链路。
    • +
    +

    2.5.5 落地边界

    +
      +
    • 已落地:资料归档、过程日志留存、按申请维度检索的设计边界明确。
    • +
    • 部分落地:全文检索、影像 +OCR、外部档案系统联动可能由专项系统承载。
    • +
    • 文档先行:长期电子档案治理和归档分层存储策略不作为当前应用开发首批范围。
    • +
    + + diff --git a/output/15_INST_Detailed.pdf b/output/15_INST_Detailed.pdf new file mode 100644 index 0000000..95eec41 Binary files /dev/null and b/output/15_INST_Detailed.pdf differ diff --git a/output/15_INST_Detailed_processed.md b/output/15_INST_Detailed_processed.md new file mode 100644 index 0000000..b671667 --- /dev/null +++ b/output/15_INST_Detailed_processed.md @@ -0,0 +1,330 @@ +--- +title: "15_INST_Detailed" +author: "系统设计团队" +date: "2024年12月19日" +documentclass: article +geometry: margin=1in +fontsize: 11pt +mainfont: "PingFang SC" +CJKmainfont: "PingFang SC" +--- + +--- +doc_id: DT-15-INST +doc_role: module_body +authority: secondary +scope: 详细设计-报装与签章 +source_of_truth: false +last_reviewed: 2026-03-18 +retrieval_priority: P1 +--- + +# 福建水务营收系统详细设计-报装与签章模块正文 + +## 章节导航(精简) + +- [文档定位](#sec-position) +- [报装与签章详细设计正文](#sec-content) + - [报装模块统一约束](#sec-inst-rules) + - [接口与数据追溯矩阵](#sec-inst-trace) + - [INST-001 报装流程管理](#mod-inst-001) + - [INST-002 工程管理](#mod-inst-002) + - [INST-003 档案管理](#mod-inst-003) + + + +## 文档定位 + +本文档为 `01_Detailed_Design.md` 中“报装与签章详细设计”章节的模块正文拆分稿,便于按模块独立维护。正式交付口径以主详设为准。 + + + +# 报装与签章详细设计 + + + +## 报装模块统一约束 + +1. 报装模块承担 `SYS-002` 中“申请受理、踏勘方案、施工验收、立户通水、合同签章、档案归档”的完整主流程,流程主线以 `biz_process*` 与 `biz_content*` 为当前实现态口径。 +2. 报装申请、踏勘结果、验收结果、签章回执、归档动作均必须通过流程节点驱动,不允许直接绕过业务过程修改主状态。 +3. 施工验收通过后,方可进入客户建档、水表绑定、账户初始化与通水确认,避免前后置业务状态错位。 +4. 电子签章专题表 `installation_*` 当前为“专题扩展口径”,若实施库结构与专题设计不一致,以实施库与主详设联合评审结果为准。 +5. 报装过程中的申请材料、验收附件、签章文件、存证回执必须统一归档并具备可检索、可追溯能力。 + + + +## 接口与数据追溯矩阵 + +> 说明:接口字段以 `../03_Technical_Design/03_Interface_Design.md` 为准,数据库口径以 `../03_Technical_Design/01_Database_Design.md` 为准。 + +| INST 模块 | 关键接口 | 核心数据域(摘要) | 主要协同对象 | +|---|---|---|---| +| INST-001 报装流程管理 | `IF-INST-001`、`IF-INST-002` | `biz_process`、`biz_content`、`biz_content_attach`、`biz_process_transfer`、`biz_business_datas` | 柜台、微网厅、政务平台、报装人员 | +| INST-002 工程管理 | `IF-INST-003`、`IF-INST-004`、`IF-INST-005` | `biz_process_meter_install`、`biz_process`、`biz_meter`、`installation_contract`、`installation_signature`、`installation_evidence` | 表务、客户建档、泛微 CA | +| INST-003 档案管理 | `IF-INST-005` | `biz_content_attach`、`installation_evidence`、过程日志 | 报装、档案管理 | + + + +## INST-001 报装流程管理 + +### 功能说明 + +承接新装、改造、一户一表等业务从申请受理到现场踏勘、方案编制的前半段主流程,是架构图中“报装流程管理”模块的正式承接章节。 + +### 业务流程 + + +```mermaid +flowchart TD + A[提交报装申请] --> B[采集申请信息与附件] + B --> C[受理校验] + C --> D{是否通过} + D -->|否| E[退回补充资料] + D -->|是| F[生成报装编号] + F --> G[创建流程实例] + G --> H[进入踏勘环节] + +``` + + +### 关键设计 + +- 统一采集申请人、地址、产权、用水性质、附件材料等信息。 +- 支持政务平台、柜台、微网厅等多入口申请。 +- 受理后自动生成报装编号并进入踏勘流程。 + +### 核心数据 + +- `biz_process`:报装流程主表。 +- `biz_content`:申请资料主对象。 +- `biz_content_attach`:申请附件。 +- `installation_application`:报装申请映射对象(设计态)。 + +### 接口映射 + +- `IF-INST-001`:提交报装申请、申请资料与附件。 +- `IF-INST-002`:回填踏勘结果、方案、审核结果。 +- `IF-CS-006`:客户渠道办理入口可复用报装申请主线。 + +### 落地边界 + +- **已落地**:申请受理主流程、资料与附件采集、流程实例创建。 +- **部分落地**:不同报装类型的细化受理规则、踏勘方案差异更多依赖流程和参数配置。 +- **文档先行**:`installation_application` 当前按设计态保留,不宣称为实施库既有事实表。 + + + +### 踏勘与方案设计能力 + +### 功能说明 + +组织现场勘查、工程条件确认、材料测算、施工方案与费用方案编制。 + +### 业务流程 + + +```mermaid +flowchart TD + A[接收踏勘任务] --> B[现场勘查与拍照] + B --> C[记录供水条件与施工约束] + C --> D[编制方案与费用] + D --> E[提交审核] + E --> F{审核是否通过} + F -->|否| G[退回修改] + F -->|是| H[进入施工或合同环节] + +``` + + +### 关键设计 + +1. 踏勘记录包括现场照片、供水接入条件、施工难点、估算费用。 +2. 方案版本化管理,支持设计审核与退回修改。 +3. 勘查结果直接驱动合同金额与施工计划。 + +### 核心数据 + +- `biz_process_transfer`:节点流转与处理记录。 +- `biz_business_datas`:踏勘与方案扩展数据。 +- `biz_content_attach`:现场照片与附件资料。 + +### 接口映射 + +- `IF-INST-002`:回填踏勘结果、方案、审核结果。 + +### 落地边界 + +- **已落地**:踏勘流转、扩展数据回填、现场资料挂接。 +- **部分落地**:材料测算、工程造价等可能在扩展数据或外部附件中承载。 +- **文档先行**:复杂 BIM/预算系统联动不作为当前正式实现口径。 + + + +## INST-002 工程管理 + +### 功能说明 + +承接施工派工、安装实施、竣工验收、立户通水以及合同签章协同,是架构图中“工程管理”模块的正式承接章节。 + +### 业务流程 + + +```mermaid +flowchart TD + A[下发施工任务] --> B[现场安装实施] + B --> C[录入装表与施工结果] + C --> D[提交竣工验收] + D --> E{验收是否通过} + E -->|否| F[整改后复验] + E -->|是| G[触发客户建档与水表绑定] + G --> H[初始化账户并确认通水] + +``` + + +### 关键设计 + +- 施工节点按派工、实施、验收、归档逐步留痕。 +- 验收通过后自动触发客户建档、水表绑定和账户初始化。 +- 与表务系统共享水表安装与换表数据。 + +### 核心数据 + +- `biz_process`:施工与验收流程主线。 +- `biz_process_meter_install`:装表落地信息。 +- `biz_meter`:水表安装与状态回写对象。 +- `biz_cust`、`biz_account`:立户后续创建对象。 + +### 接口映射 + +- `IF-INST-005`:归档验收资料并提交最终办结信息。 +- `IF-INST-003`:发起电子签章任务并传输合同信息。 +- `IF-INST-004`:回写签章结果、时间戳和存证信息。 +- `IF-METER-001`、`IF-METER-002`:装表与表务状态协同。 +- `IF-REV-001`:立户后客户主档进入营收主数据域。 + +### 落地边界 + +- **已落地**:施工验收主线、装表结果留痕、客户建档与水表绑定协同。 +- **部分落地**:施工派工计划与现场资源调度可能由外部施工管理工具承载。 +- **文档先行**:复杂工程项目管理和材料成本结转不作为当前正式开发边界。 + + + +### 合同签署与电子签章能力 + +### 功能说明 + +通过集成泛微 CA 电子签章系统,实现报装合同、用水协议等文件的电子签署、时间戳和电子存证。 + +### 集成架构 + + +```mermaid +graph TD + subgraph INST[报装业务系统] + A[申请受理] + B[合同管理] + C[电子签章模块] + D[档案归档] + end + + subgraph CA[泛微CA电子签章系统] + E[身份认证服务] + F[电子签章服务] + G[时间戳服务] + H[电子存证服务] + end + + A --> B + B --> C + C --> E + C --> F + C --> G + C --> H + C --> D + +``` + + +### 合同签署流程 + + +```mermaid +sequenceDiagram + participant 客户 + participant 报装系统 + participant 电子签章模块 + participant 泛微CA系统 + + 客户->>报装系统: 提交签署申请 + 报装系统->>电子签章模块: 生成签署任务 + 电子签章模块->>泛微CA系统: 发起身份认证 + 泛微CA系统-->>电子签章模块: 返回认证结果 + 电子签章模块->>泛微CA系统: 发起电子签章 + 泛微CA系统-->>电子签章模块: 返回签章结果 + 电子签章模块->>泛微CA系统: 申请时间戳与存证 + 泛微CA系统-->>电子签章模块: 返回凭证 + 电子签章模块-->>报装系统: 返回签署结果 + 报装系统-->>客户: 通知合同签署完成 + +``` + + +### 核心数据 + +| 数据对象 | 说明 | +|---|---| +| `installation_contract` | 报装合同主表(设计态专题扩展) | +| `installation_signature` | 电子签章记录表(设计态专题扩展) | +| `installation_evidence` | 电子存证记录表(设计态专题扩展) | +| `installation_signature_template` | 签章模板与签署位置配置 | + +### 关键规则 + +1. 合同签署前必须完成身份认证。 +2. 合同正文、签署位置、签署人、签署时间必须完整留痕。 +3. 签署完成文件必须归档并生成可验证凭证。 +4. 外部 CA 接口异常时应支持重试与人工补偿处理。 + +### 接口映射 + +- `IF-INST-003`:发起合同签署任务并传递合同信息。 +- `IF-INST-004`:回写签章结果、时间戳和存证信息。 + +### 落地边界 + +- **已落地**:签章流程、签章回执、时间戳与存证协同设计口径已明确。 +- **部分落地**:`installation_*` 当前在数据库主文档中按专题扩展纳管,实施库需联合评审确认最终落表。 +- **文档先行**:多 CA 厂商切换、批量签署编排等高级能力暂不表述为当前既有实现。 + + + +## INST-003 档案管理 + +### 功能说明 + +归集申请材料、设计方案、合同文件、验收资料、签章回执和过程日志,形成完整报装档案。 + +### 关键设计 + +- 档案按申请单维度统一归档。 +- 电子签章合同、验收附件、影像资料统一存储。 +- 档案查询支持按申请编号、客户、地址、时间、状态检索。 + +### 核心数据 + +- `biz_content_attach`:报装材料、验收附件、影像资料。 +- `installation_evidence`:签章存证与回执资料。 +- `biz_process`、`biz_process_transfer`:过程留痕主线。 + +### 接口映射 + +- `IF-INST-005`:归档申请、合同、验收资料与签章回执。 +- `IF-INST-004`:签章回执结果进入归档链路。 + +### 落地边界 + +- **已落地**:资料归档、过程日志留存、按申请维度检索的设计边界明确。 +- **部分落地**:全文检索、影像 OCR、外部档案系统联动可能由专项系统承载。 +- **文档先行**:长期电子档案治理和归档分层存储策略不作为当前应用开发首批范围。 diff --git a/output/PostgreSQL16_容灾与资源申请说明.docx b/output/PostgreSQL16_容灾与资源申请说明.docx new file mode 100644 index 0000000..9f3d8a7 Binary files /dev/null and b/output/PostgreSQL16_容灾与资源申请说明.docx differ diff --git a/output/PostgreSQL16_容灾与资源申请说明_含图表.docx b/output/PostgreSQL16_容灾与资源申请说明_含图表.docx new file mode 100644 index 0000000..574448c Binary files /dev/null and b/output/PostgreSQL16_容灾与资源申请说明_含图表.docx differ diff --git a/output/document_style.css b/output/document_style.css new file mode 100644 index 0000000..dc879fc --- /dev/null +++ b/output/document_style.css @@ -0,0 +1,259 @@ +/* 福建水务营收系统文档样式 */ +@page { + margin: 2cm; + size: A4; +} + +body { + font-family: "PingFang SC", "Microsoft YaHei", "SimSun", sans-serif; + font-size: 11pt; + line-height: 1.6; + color: #333; + max-width: none; + margin: 0; + padding: 0; +} + +/* 标题样式 */ +h1 { + font-size: 18pt; + font-weight: bold; + color: #1f4e79; + margin-top: 24pt; + margin-bottom: 12pt; + border-bottom: 2pt solid #1f4e79; + padding-bottom: 6pt; + page-break-after: avoid; +} + +h2 { + font-size: 16pt; + font-weight: bold; + color: #2f5597; + margin-top: 18pt; + margin-bottom: 10pt; + border-bottom: 1pt solid #2f5597; + padding-bottom: 4pt; + page-break-after: avoid; +} + +h3 { + font-size: 14pt; + font-weight: bold; + color: #365f91; + margin-top: 14pt; + margin-bottom: 8pt; + page-break-after: avoid; +} + +h4 { + font-size: 12pt; + font-weight: bold; + color: #4472c4; + margin-top: 12pt; + margin-bottom: 6pt; + page-break-after: avoid; +} + +h5 { + font-size: 11pt; + font-weight: bold; + color: #5b9bd5; + margin-top: 10pt; + margin-bottom: 5pt; + page-break-after: avoid; +} + +h6 { + font-size: 10pt; + font-weight: bold; + color: #70ad47; + margin-top: 8pt; + margin-bottom: 4pt; + page-break-after: avoid; +} + +/* 段落样式 */ +p { + margin-top: 0; + margin-bottom: 8pt; + text-align: justify; + text-justify: inter-ideograph; +} + +/* 表格样式(黑色边框) */ +table { + border-collapse: collapse; + width: 100%; + margin: 12pt 0; + font-size: 10pt; + page-break-inside: avoid; + border: 1pt solid #000; /* 外边框黑色 */ +} + +th { + background-color: #4472c4; + color: white; + font-weight: bold; + padding: 8pt; + border: 1pt solid #000; /* 表头黑线 */ + text-align: center; +} + +td { + padding: 6pt 8pt; + border: 1pt solid #000; /* 单元格黑线 */ + vertical-align: top; +} + +tr:nth-child(even) { + background-color: #f2f2f2; +} + +/* 代码样式 */ +code { + font-family: "Courier New", "Monaco", monospace; + font-size: 9pt; + background-color: #f5f5f5; + padding: 2pt 4pt; + border-radius: 2pt; + border: 1pt solid #e1e1e1; +} + +pre { + font-family: "Courier New", "Monaco", monospace; + font-size: 9pt; + background-color: #f8f8f8; + padding: 12pt; + border: 1pt solid #e1e1e1; + border-radius: 4pt; + overflow-x: auto; + margin: 12pt 0; + page-break-inside: avoid; +} + +pre code { + background: none; + padding: 0; + border: none; +} + +/* 列表样式 */ +ul, ol { + margin: 8pt 0; + padding-left: 24pt; +} + +li { + margin: 4pt 0; +} + +/* 图片样式 */ +img { + max-width: 100%; + height: auto; + display: block; + margin: 12pt auto; + border: 1pt solid #e1e1e1; + border-radius: 4pt; + page-break-inside: avoid; +} + +/* 图表标题 */ +img + p, p + img { + text-align: center; + font-weight: bold; + color: #4472c4; + font-size: 10pt; + margin: 6pt 0; +} + +/* 分页符 */ +.page-break { + page-break-before: always; +} + +/* 避免孤行和寡行 */ +p, li, dt, dd { + orphans: 2; + widows: 2; +} + +/* 链接样式 */ +a { + color: #0563c1; + text-decoration: underline; +} + +a:visited { + color: #954f72; +} + +/* 引用样式 */ +blockquote { + margin: 12pt 0; + padding: 12pt; + background-color: #f9f9f9; + border-left: 4pt solid #4472c4; + font-style: italic; +} + +/* 水平分隔线 */ +hr { + border: none; + border-top: 1pt solid #d1d1d1; + margin: 18pt 0; +} + +/* Details/Summary 样式 */ +details { + margin: 8pt 0; + border: 1pt solid #e1e1e1; + border-radius: 4pt; + padding: 8pt; +} + +summary { + font-weight: bold; + cursor: pointer; + color: #4472c4; + margin-bottom: 8pt; +} + +/* 强调样式 */ +strong, b { + font-weight: bold; + color: #1f4e79; +} + +em, i { + font-style: italic; + color: #365f91; +} + +/* 印刷样式优化 */ +@media print { + body { + font-size: 10pt; + line-height: 1.4; + } + + h1 { font-size: 16pt; } + h2 { font-size: 14pt; } + h3 { font-size: 12pt; } + h4 { font-size: 11pt; } + h5 { font-size: 10pt; } + h6 { font-size: 9pt; } + + table { font-size: 9pt; } + code, pre { font-size: 8pt; } + + /* 避免在不适当的地方分页 */ + h1, h2, h3, h4, h5, h6 { + page-break-after: avoid; + } + + table, pre, img { + page-break-inside: avoid; + } +} diff --git a/output/pgsql16_docx_rendered/07_PostgreSQL16_DR_Resource_Application.rendered.md b/output/pgsql16_docx_rendered/07_PostgreSQL16_DR_Resource_Application.rendered.md new file mode 100644 index 0000000..9de5cbf --- /dev/null +++ b/output/pgsql16_docx_rendered/07_PostgreSQL16_DR_Resource_Application.rendered.md @@ -0,0 +1,587 @@ +--- +doc_id: TC-07-PGSQL-DR +doc_role: supplemental_document +authority: secondary +scope: PostgreSQL 16 容灾资源申请 +source_of_truth: false +last_reviewed: 2026-03-24 +retrieval_priority: P1 +--- + +# 福建水务营收系统 PostgreSQL 16 容灾与资源申请说明 + +## 文档信息 +| 项目信息 | 详情 | +|---------|------| +| **项目名称** | 福建水务营收系统 | +| **文档类型** | 技术专题说明 | +| **专题用途** | 向甲方申请 PostgreSQL 16 容灾部署资源 | +| **文档版本** | v1.0 | +| **编写日期** | 2026-03-24 | +| **文档状态** | ✅ 正式建议稿 | + +## 目录 + +1. 编制目的 +2. 适用范围与说明 +3. 容灾建设目标 +4. 容灾形态说明 +5. 资源配比原则 +6. 推荐部署方案 +7. 甲方审批汇总表 +8. 详细资源申请清单 +9. 网络与存储要求 +10. 数据库代理与连接接入方案 +11. 部署实施说明 +12. 切换与恢复说明 +13. 切换实施细则 +14. 申请结论 + +## 编制目的 + +本文档用于说明福建水务营收系统采用 PostgreSQL 16 建设数据库高可用与灾难恢复能力时,所需的资源规模、部署形态、主备配比及实施要求,作为甲方进行服务器、存储、网络及运行环境审批的依据。 + +## 适用范围与说明 + +1. 本文档面向 PostgreSQL 16 数据库部署专题,重点说明容灾与资源申请口径。 +2. 本文档用于资源论证与部署申请,不替代数据库主文档和总体部署主文档。 +3. 文中关于备库资源比例、网络带宽、存储冗余和部署组合的建议,属于结合 PostgreSQL 16 流复制、热备与时间点恢复机制形成的工程实施建议。 + +## 容灾建设目标 + +PostgreSQL 16 容灾建设目标如下: + +1. 在主库节点故障时,保障数据库能够快速切换并恢复服务。 +2. 在误操作、逻辑损坏、批量异常更新等场景下,保障系统具备时间点恢复能力。 +3. 在核心收费、账务、对账等业务场景中,尽量降低故障切换时的数据丢失风险。 +4. 在资源投入可控的前提下,为甲方提供可分阶段实施的多种建设形态。 + +## 容灾形态说明 + +结合 PostgreSQL 16 能力及甲方常见基础设施条件,建议按以下四种形态进行资源申请与部署评估。 + +### 形态一:单中心主备容灾 + +适用于预算有限、优先满足基础高可用能力的场景。 + +部署关系图: + +![图1](images/diagram_1.png) + +1. 主库与备库部署在同一机房或同一可用区。 +2. 备库可采用 `Warm Standby` 或 `Hot Standby`。 +3. 推荐采用异步复制;如网络稳定且事务一致性要求较高,也可采用同步复制。 +4. 该形态可解决单机故障问题,但不能覆盖机房级灾难。 + +### 形态二:同城双可用区主备容灾 + +适用于生产系统正式上线场景,兼顾高可用与较高的数据安全要求。 + +部署关系图: + +![图2](images/diagram_2.png) + +说明: + +1. 主库与备库部署在同城不同机房或不同可用区。 +2. 推荐备库采用 `Hot Standby`,可承担只读查询与切换接管职责。 +3. 对收费、账务、实收确认等核心业务,宜优先评估同步复制。 +4. 该形态可覆盖单节点故障和单可用区故障,是生产环境优先推荐的基础方案。 + +### 形态三:同城双中心 + 异地灾备 + +适用于对连续运行能力要求较高,且需要同时覆盖机房级与区域级风险的场景。 + +部署关系图: + +![图3](images/diagram_3.png) + +说明: + +1. 同城备库承担高可用切换职责。 +2. 异地灾备库承担区域级灾难恢复职责。 +3. 异地灾备一般采用异步复制,避免远距离链路对主业务写入性能造成明显影响。 +4. 该形态可满足高可用与灾备双重要求,适合作为甲方正式建设目标方案。 + +### 形态四:主备高可用 + 备份恢复型灾备 + +适用于暂不具备异地第三节点条件,但需要形成完整灾难恢复能力的场景。 + +部署关系图: + +![图4](images/diagram_4.png) + +说明: + +1. 在线层保持主备双节点高可用。 +2. 异地侧不部署实时在线数据库实例,主要承载基础备份和 WAL 归档。 +3. 该形态投入低于三节点实时灾备,但恢复时间长于在线异地灾备库方案。 +4. 适用于二期或预算受限情况下的过渡方案。 + +## 资源配比原则 + +### 主备资源总体原则 + +1. 主库负责生产写入,CPU、内存、I/O、网络压力最大。 +2. 备库必须保存完整数据副本,因此备库存储容量原则上不得低于主库。 +3. 如备库承担实时切换接管职责,其 CPU 与内存不宜明显低于主库。 +4. 如备库仅承担异步灾备且不承载查询压力,可适当降低 CPU 与内存,但不应压缩存储容量和网络链路质量。 + +### 主备资源比例建议 + +| 备库角色 | 复制方式 | 是否承担读请求 | CPU 建议 | 内存建议 | 存储建议 | 适用说明 | +|---|---|---|---|---|---|---| +| 同步热备库 | 同步复制 | 是 | 不低于主库 100% | 不低于主库 100% | 不低于主库 100%,建议 120% | 生产正式切换节点,要求切换后立即承载全部业务 | +| 同步温备库 | 同步复制 | 否 | 主库的 70% 至 100% | 主库的 70% 至 100% | 不低于主库 100%,建议 120% | 不承载查询,但需要较快接管生产流量 | +| 异步热备库 | 异步复制 | 是 | 主库的 70% 至 100% | 主库的 70% 至 100% | 不低于主库 100%,建议 120% | 可承担报表查询或只读分析 | +| 异步温备库 | 异步复制 | 否 | 主库的 50% 至 70% | 主库的 50% 至 70% | 不低于主库 100%,建议 120% | 仅承担容灾接管,不参与日常查询 | +| 异地灾备库 | 异步复制 | 否 | 主库的 50% 左右 | 主库的 50% 至 70% | 不低于主库 100%,建议 120% | 主要用于区域级容灾恢复 | +| 备份恢复节点 | PITR | 否 | 可不单独配置在线节点 | 可不单独配置在线节点 | 备份空间建议为主库有效数据量的 2 至 3 倍 | 用于误操作恢复和灾难后重建 | + +### 资源配比说明 + +1. 备库存储不能按 CPU、内存比例缩减,原因是 PostgreSQL 备库需要保存完整数据文件、索引文件及 WAL 回放空间。 +2. 当备库承担 `Hot Standby` 查询或要求快速晋升为主库时,推荐按主库同规格申请。 +3. 当备库仅作为冷备或异步灾备节点时,可降低计算资源,但仍需预留恢复、回放和切换后的运行余量。 + +## 推荐部署方案 + +结合福建水务营收系统收费、账务、对账等核心业务连续性要求,建议分为三档申请方案。 + +### 方案 A:基础上线方案 + +1. 架构形态:单中心主备容灾。 +2. 节点组成:1 主库 + 1 备库 + 1 套备份归档存储。 +3. 复制方式:异步复制。 +4. 适用场景:预算受限、优先满足基本高可用要求。 + +### 方案 B:正式生产推荐方案 + +1. 架构形态:同城双可用区主备容灾。 +2. 节点组成:1 主库 + 1 同城热备库 + 1 套备份归档存储。 +3. 复制方式:核心业务优先评估同步复制。 +4. 适用场景:正式生产环境,要求故障切换后快速恢复业务。 + +### 方案 C:正式生产增强方案 + +1. 架构形态:同城双中心 + 异地灾备。 +2. 节点组成:1 主库 + 1 同城同步热备库 + 1 异地异步灾备库 + 1 套集中备份归档存储。 +3. 复制方式:同城同步复制,异地异步复制。 +4. 适用场景:甲方对连续运行、审计留痕、灾难恢复要求较高的正式建设项目。 + +本项目建议优先向甲方申请方案 B;如甲方同时要求区域级灾难恢复能力,建议直接申请方案 C。 + +## 甲方审批汇总表 + +以下汇总表用于甲方进行资源审批、预算评估和实施范围确认。建议优先按“方案 B:正式生产推荐方案”审批;如甲方同时要求区域级灾难恢复能力,可按“方案 C:正式生产增强方案”审批。 + +### 方案 A:基础上线方案审批汇总表 + +| 类别 | 资源项 | 数量 | 单项建议规格 | 审批说明 | +|---|---|---:|---|---| +| 服务器 | 主库服务器 | 1 台 | 16 核 CPU / 64 GB 内存 / 2 TB NVMe SSD | 承担全部生产写入 | +| 服务器 | 备库服务器 | 1 台 | 12 至 16 核 CPU / 48 至 64 GB 内存 / 2 TB NVMe SSD | 承担主库故障接管 | +| 服务器 | 管理与监控节点 | 1 台 | 8 核 CPU / 16 GB 内存 / 500 GB SSD | 部署监控、备份调度、巡检工具 | +| 存储 | 备份归档存储 | 1 套 | 可用空间 4 TB 起 | 存放全量备份与 WAL 归档 | +| 网络 | 主备复制链路 | 1 组 | 不低于 10 Gbps | 建议与业务访问链路隔离 | +| 网络 | 业务接入地址 | 1 组 | 统一数据库代理地址 | 应用统一接入,不直连数据库 IP | +| 软件 | PostgreSQL 16 | 2 套实例 | 主库 1 套,备库 1 套 | 构建基础主备容灾 | +| 软件 | PgBouncer | 1 套 | 连接池代理 | 统一控制连接数 | +| 软件 | HAProxy | 1 套 | 数据库入口代理 | 提供统一切换入口 | +| 软件 | Patroni | 1 套 | 高可用管理组件 | 管理主备选举与切换 | + +### 方案 B:正式生产推荐方案审批汇总表 + +| 类别 | 资源项 | 数量 | 单项建议规格 | 审批说明 | +|---|---|---:|---|---| +| 服务器 | 主库服务器 | 1 台 | 16 核 CPU / 64 GB 内存 / 2 TB NVMe SSD | 部署在生产可用区 | +| 服务器 | 同城热备服务器 | 1 台 | 16 核 CPU / 64 GB 内存 / 2 TB NVMe SSD | 与主库同规格,承担正式接管 | +| 服务器 | 管理与监控节点 | 1 台 | 8 核 CPU / 16 GB 内存 / 500 GB SSD | 部署监控、备份、巡检、告警 | +| 存储 | 备份归档存储 | 1 套 | 可用空间 4 TB 至 6 TB | 存放备份、WAL、恢复校验副本 | +| 网络 | 主备复制链路 | 1 组 | 不低于 10 Gbps | 同城低时延链路,适合同步复制 | +| 网络 | 主备时延要求 | 1 项 | 建议低于 2 ms | 支撑主备同步与快速切换 | +| 网络 | 业务接入地址 | 1 组 | 统一数据库代理地址 | 应用系统通过代理地址访问 | +| 软件 | PostgreSQL 16 | 2 套实例 | 主库 1 套,热备库 1 套 | 构建正式生产主备体系 | +| 软件 | PgBouncer | 1 套 | 连接池代理 | 控制连接数并稳定应用连接 | +| 软件 | HAProxy | 1 套 | 数据库入口代理 | 承担统一读写入口切换 | +| 软件 | Patroni | 1 套 | 高可用管理组件 | 管理主备状态、提升与故障切换 | + +### 方案 C:正式生产增强方案审批汇总表 + +| 类别 | 资源项 | 数量 | 单项建议规格 | 审批说明 | +|---|---|---:|---|---| +| 服务器 | 主库服务器 | 1 台 | 16 核 CPU / 64 GB 内存 / 2 TB NVMe SSD | 部署在生产中心 | +| 服务器 | 同城同步热备服务器 | 1 台 | 16 核 CPU / 64 GB 内存 / 2 TB NVMe SSD | 承担正式主备切换 | +| 服务器 | 异地灾备服务器 | 1 台 | 8 至 12 核 CPU / 32 至 48 GB 内存 / 2 TB NVMe SSD | 承担区域级灾难恢复 | +| 服务器 | 管理与监控节点 | 1 台 | 8 核 CPU / 16 GB 内存 / 500 GB SSD | 部署监控、备份、审计工具 | +| 存储 | 集中备份归档存储 | 1 套 | 可用空间 6 TB 起 | 保存全量备份、WAL、演练副本 | +| 网络 | 同城复制链路 | 1 组 | 不低于 10 Gbps | 保障同步复制稳定性 | +| 网络 | 异地复制链路 | 1 组 | 专线或稳定 VPN | 保障异步复制与备份回传 | +| 网络 | 业务接入地址 | 1 组 | 统一数据库代理地址 | 应用不直接访问数据库节点 | +| 软件 | PostgreSQL 16 | 3 套实例 | 主库 1 套,同城热备 1 套,异地灾备 1 套 | 构建高可用与灾备双层体系 | +| 软件 | PgBouncer | 1 套 | 连接池代理 | 稳定应用接入层 | +| 软件 | HAProxy | 1 套 | 数据库入口代理 | 承担统一流量入口与切换 | +| 软件 | Patroni | 1 套 | 高可用管理组件 | 管理主备状态与故障切换 | + +### 审批建议结论 + +| 审批项 | 建议结论 | 说明 | +|---|---|---| +| 首选审批方案 | 方案 B | 兼顾资源投入、主备切换能力和正式生产可用性 | +| 最低建设标准 | 不低于方案 A | 至少满足双节点主备与独立备份归档 | +| 增强建设目标 | 方案 C | 适用于要求区域级灾难恢复的正式项目 | +| 备库资源口径 | 存储不低于主库,热备计算资源宜等同主库 | 避免切换后承载不足 | +| 接入方式 | 统一数据库代理地址 | 禁止应用直连数据库物理 IP | + +## 详细资源申请清单 + +以下清单以单套生产系统为口径,作为资源申请参考基线。实际规模可根据并发量、数据量和保留周期进一步调整。 + +### 方案 A 资源申请清单 + +| 资源类型 | 数量 | 单节点建议配置 | 说明 | +|---|---:|---|---| +| 主库服务器 | 1 台 | 16 核 CPU / 64 GB 内存 / 2 TB NVMe SSD | 承担生产写入 | +| 备库服务器 | 1 台 | 12 至 16 核 CPU / 48 至 64 GB 内存 / 2 TB NVMe SSD | 温备或热备均可 | +| 备份存储 | 1 套 | 可用空间 4 TB 起 | 存放基础备份与 WAL 归档 | +| 管理与监控节点 | 1 台 | 8 核 CPU / 16 GB 内存 / 500 GB SSD | 部署监控、备份调度、巡检工具 | + +### 方案 B 资源申请清单 + +| 资源类型 | 数量 | 单节点建议配置 | 说明 | +|---|---:|---|---| +| 主库服务器 | 1 台 | 16 核 CPU / 64 GB 内存 / 2 TB NVMe SSD | 部署在生产可用区 | +| 同城热备服务器 | 1 台 | 16 核 CPU / 64 GB 内存 / 2 TB NVMe SSD | 与主库同规格,承担热备与切换 | +| 备份归档存储 | 1 套 | 可用空间 4 TB 至 6 TB | 存放基础备份、WAL、恢复校验副本 | +| 管理与监控节点 | 1 台 | 8 核 CPU / 16 GB 内存 / 500 GB SSD | 部署监控、备份、连接代理等工具 | + +### 方案 C 资源申请清单 + +| 资源类型 | 数量 | 单节点建议配置 | 说明 | +|---|---:|---|---| +| 主库服务器 | 1 台 | 16 核 CPU / 64 GB 内存 / 2 TB NVMe SSD | 部署在生产中心 | +| 同城同步热备服务器 | 1 台 | 16 核 CPU / 64 GB 内存 / 2 TB NVMe SSD | 作为正式切换节点 | +| 异地灾备服务器 | 1 台 | 8 至 12 核 CPU / 32 至 48 GB 内存 / 2 TB NVMe SSD | 用于区域级灾备恢复 | +| 集中备份归档存储 | 1 套 | 可用空间 6 TB 起 | 统一保存全量备份与 WAL 归档 | +| 管理与监控节点 | 1 台 | 8 核 CPU / 16 GB 内存 / 500 GB SSD | 部署监控、备份、审计工具 | + +### 资源申请补充说明 + +1. 如甲方要求备库长期承担报表、统计或只读查询负载,备库应按主库同规格申请。 +2. 如数据库数据量预估超过 1 TB,建议主库与备库磁盘统一提升至 4 TB 起步。 +3. 如需要保留 30 日以上 WAL 归档或多周期全量备份,备份存储应按“在线数据量的 2 至 3 倍”进行规划。 + +## 网络与存储要求 + +### 网络要求 + +| 项目 | 建议要求 | 说明 | +|---|---|---| +| 主备网络带宽 | 不低于 10 Gbps | 保障流复制稳定性与切换效率 | +| 同城主备时延 | 建议低于 2 ms | 适合同步复制 | +| 异地主备链路 | 建议专线或稳定 VPN | 适合异步复制与备份回传 | +| 复制链路隔离 | 建议与业务访问链路分离 | 降低复制抖动风险 | + +### 存储要求 + +| 项目 | 建议要求 | 说明 | +|---|---|---| +| 主库存储 | NVMe SSD 或企业级 SSD | 保障 WAL 与随机 I/O 性能 | +| 备库存储 | 不低于主库存储规格 | 保障回放与切换性能 | +| 磁盘阵列 | RAID 10 优先 | 平衡可靠性与性能 | +| 备份存储 | 独立于数据库数据盘 | 避免单点故障导致备份不可用 | + +## 数据库代理与连接接入方案 + +### 建设目标 + +为避免应用系统直接连接数据库物理节点,并降低主备切换时应用侧配置变更成本,PostgreSQL 16 容灾体系宜配套建设数据库代理与连接接入层。 + +数据库代理层建设目标如下: + +1. 为应用系统提供统一数据库访问地址。 +2. 在主备切换时避免逐台修改应用节点连接配置。 +3. 控制应用连接数,降低数据库连接管理压力。 +4. 为后续读写分离和只读查询扩展预留接入能力。 + +### 推荐组件组合 + +结合当前项目应用规模与运维复杂度控制要求,推荐采用以下组件组合: + +1. `Patroni`:负责 PostgreSQL 主备状态管理、主库选举与故障切换。 +2. `HAProxy`:负责数据库访问入口转发,将写请求路由到当前主库。 +3. `PgBouncer`:负责连接池管理,降低应用对 PostgreSQL 后端连接数的直接冲击。 + +本项目不建议以 `pgpool-II` 作为首选统一方案。原因在于 `pgpool-II` 功能较重、配置复杂、运维成本较高,不利于当前项目在甲方环境中的快速落地与稳定运维。 + +### 推荐接入拓扑 + +#### 模式一:统一读写入口 + +适用于一期先满足高可用与连接池要求,暂不启用读写分离的场景。 + +接入关系图: + +![图5](images/diagram_5.png) + +说明: + +1. 应用系统统一连接 `PgBouncer` 暴露的数据库接入地址。 +2. `PgBouncer` 后端连接到 `HAProxy` 的读写入口。 +3. `HAProxy` 根据 `Patroni` 暴露的主备状态,将流量转发到当前主库。 +4. 主备切换时,应用端数据库 URL 不变。 + +#### 模式二:读写分离入口 + +适用于二期或存在报表、统计、查询分流需求的场景。 + +接入关系图: + +![图6](images/diagram_6.png) + +说明: + +1. 写请求通过 `RW` 入口访问当前主库。 +2. 只读查询通过 `RO` 入口访问热备库。 +3. 如备库不可用,`RO` 入口可根据策略降级转发到主库或暂时关闭。 +4. 应用需在代码或配置层明确区分读写连接场景。 + +### 推荐选型结论 + +对于福建水务营收系统当前阶段,建议优先采用“`Patroni + HAProxy + PgBouncer`”组合,并采用“统一读写入口”模式上线。待系统稳定运行后,再根据报表与统计查询压力评估是否扩展为“读写分离入口”模式。 + +### HAProxy 示例配置 + +以下配置仅用于说明读写入口代理思路,实际参数应由项目环境统一配置并纳入变更管理。 + +```haproxy +global + log 127.0.0.1 local0 + maxconn 20000 + +defaults + log global + mode tcp + timeout connect 5s + timeout client 1m + timeout server 1m + +frontend pg_rw + bind *:5000 + default_backend pg_primary + +backend pg_primary + option tcp-check + default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions + server pg01 10.0.0.11:5432 check + server pg02 10.0.0.12:5432 check backup +``` + +配置说明: + +1. 应用不直接连接 PostgreSQL 5432,而是连接 `HAProxy` 暴露的 5000 端口。 +2. `pg01` 为当前主库,`pg02` 为备库。 +3. 主库不可用时,代理层将连接切换至备用节点。 +4. 正式环境建议结合 `Patroni` REST 状态接口配置更准确的主备健康检查,而非仅做普通 TCP 存活检查。 + +### PgBouncer 示例配置 + +以下配置仅用于说明连接池配置思路,实际参数应由项目环境统一配置并纳入变更管理。 + +```ini +[databases] +waterdb = host=10.0.0.20 port=5000 dbname=waterdb + +[pgbouncer] +listen_addr = 0.0.0.0 +listen_port = 6432 +auth_type = md5 +auth_file = /etc/pgbouncer/userlist.txt +pool_mode = transaction +max_client_conn = 5000 +default_pool_size = 100 +reserve_pool_size = 20 +server_reset_query = DISCARD ALL +ignore_startup_parameters = extra_float_digits +``` + +配置说明: + +1. 应用系统统一连接 `PgBouncer` 的 6432 端口。 +2. `PgBouncer` 后端目标不是数据库主机,而是 `HAProxy` 的读写入口地址。 +3. 推荐优先采用 `transaction` 池化模式,以提升连接复用效率。 +4. 如存在依赖会话级状态的特殊业务,应专项评估是否改用 `session` 模式。 + +### 应用接入建议 + +对于当前项目的 4 台应用服务器集群,不建议在每台应用服务器上分别配置数据库主机地址切换逻辑。推荐做法如下: + +1. 应用配置文件统一写入数据库代理地址,不写数据库物理主机 IP。 +2. 生产环境统一维护一个数据库接入地址,例如 `db-rw.xxx.local:6432`。 +3. 所有应用节点使用同一连接地址接入,由代理层完成后端数据库节点切换。 +4. 如后续启用读写分离,再增加只读接入地址,例如 `db-ro.xxx.local:6432`。 + +### 切换时的接入逻辑 + +当主库发生故障或进行计划切换时,推荐接入逻辑如下: + +1. `Patroni` 判定新的主库节点。 +2. `HAProxy` 将读写入口转发目标切换至新主库。 +3. `PgBouncer` 清理失效后端连接并重建到新主库的连接。 +4. 应用系统通过连接池重试机制继续访问统一代理地址。 + +在该机制下,应用系统通常无需修改数据库配置,仅在切换瞬间可能出现极短暂连接重试或少量请求失败,恢复后可继续正常提供服务。 + +### 正式文档建议表述 + +为保障福建水务营收系统数据库主备切换时应用系统的连续接入能力,数据库访问层宜采用“Patroni 负责主备选举、HAProxy 负责访问转发、PgBouncer 负责连接池管理”的组合架构。应用系统统一通过数据库代理地址访问数据库,不直接连接数据库物理节点;当主库故障或发生计划切换时,由代理层自动将访问流量切换至新的主库节点,从而实现应用侧最小感知切换。 + +## 部署实施说明 + +### 部署原则 + +1. 主库与同城备库不得部署在同一物理主机。 +2. 同城备库宜部署在独立机柜、独立电源域或独立可用区。 +3. 异地灾备节点宜部署在独立数据中心,避免与生产中心共用故障域。 +4. 备份归档存储应与数据库节点分离部署。 + +### 组件部署说明 + +1. 主库节点:部署 PostgreSQL 16 主实例,承担生产写入。 +2. 备库节点:部署 PostgreSQL 16 备用实例,通过流复制接收主库 WAL。 +3. 备份节点或备份存储:保存基础备份、WAL 归档和恢复校验文件。 +4. 管理与监控节点:部署 PostgreSQL 监控、备份调度、告警和巡检组件。 + +### 软件部署建议 + +1. 操作系统宜采用稳定版 Linux 发行版。 +2. 数据目录、WAL 目录、备份目录建议分盘或分卷部署。 +3. 主备切换宜配套连接路由、VIP 或代理层能力,避免应用侧频繁修改连接地址。 +4. 生产环境应启用备份校验、归档校验和恢复演练机制。 + +## 切换与恢复说明 + +### 故障切换 + +1. 主库故障时,由同城备库提升为新主库。 +2. 应用连接通过统一连接地址或代理切换到新主库。 +3. 原主库恢复后,应重新以备库身份加入复制体系。 + +### 数据恢复 + +1. 误删除、误更新或逻辑损坏场景,通过基础备份与 WAL 归档执行 `PITR` 时间点恢复。 +2. 区域级灾难场景下,可优先启用异地灾备库;如未建设异地在线库,则从异地备份存储重建数据库。 + +### 运维要求 + +1. 每季度至少开展 1 次主备切换演练。 +2. 每季度至少开展 1 次 `PITR` 恢复演练。 +3. 每日检查复制延迟、归档状态、备份成功率和磁盘余量。 + +## 切换实施细则 + +### 总体原则 + +福建水务营收系统数据库切换应遵循“统一入口切换、先判定后切换、先验证后恢复流量、禁止双主”的实施原则。 + +1. 应用系统统一通过数据库代理地址访问数据库,不直接连接数据库物理节点。 +2. 切换分为计划切换、故障切换和回切三类场景。 +3. 任一切换过程中,必须避免原主库与新主库同时对外提供写服务。 +4. 切换完成后,必须执行收费、开账、账务、发票、银行代扣等关键业务链路验证。 + +### 计划切换流程 + +计划切换适用于数据库补丁升级、主机维护、操作系统维护、机房迁移演练等场景。 + +执行顺序: + +发起计划切换申请 → 确认切换窗口与影响范围 → 检查主备复制状态 → 暂停高风险写入操作 → 确认备库追平主库 → 提升备库为新主库 → 切换代理入口到新主库 → 验证关键业务链路 → 恢复应用写入流量 → 原主库修复并重建为备库。 + +实施要点如下: + +1. 切换前至少确认主备复制无明显延迟。 +2. 切换窗口内应暂停批量开账、批量代扣、批量票据处理等高风险写入任务。 +3. 备库提升后,应优先切换代理层入口,不建议逐台修改应用配置。 +4. 切换成功后,原主库应以备库身份重新加入复制体系,不得直接恢复为独立写节点。 + +### 故障切换流程 + +故障切换适用于主库主机宕机、数据库实例不可用、主库存储异常、主库不可恢复等场景。 + +执行顺序: + +监控发现主库异常 → 确认主库不可服务 → 隔离原主库写入能力 → 确认备库状态可提升 → 提升备库为新主库 → 代理入口切换到新主库 → 应用重连并恢复服务 → 验证关键业务 → 故障主机修复 → 重建为新备库。 + +实施要点如下: + +1. 故障切换的前提不是“主库变慢”,而是“主库已无法稳定提供写服务”。 +2. 在故障未完全确认前,不得贸然提升多个备库。 +3. 如主库网络隔离但实例未真正关闭,应先执行隔离措施,避免形成双主风险。 +4. 故障切换后应优先恢复核心业务可用性,再执行历史备库链路重建。 + +### 回切流程 + +回切是指原主库修复完成后,在合适窗口下恢复为生产主库或重新调整主备角色。 + +执行顺序: + +原主库修复完成 → 作为备库追平现主库 → 评估是否需要回切。 + +如不需要回切,则保持现状运行。 + +如需要回切,则执行以下步骤:发起计划回切窗口 → 暂停高风险写入 → 确认复制追平 → 切换代理入口 → 恢复原主库为主库 → 验证关键业务 → 现主库调整为备库。 + +实施要点如下: + +1. 故障切换后并不要求立即回切,应以稳定运行为优先。 +2. 仅当原主机重新具备稳定承载能力,且运维窗口允许时,才建议执行回切。 +3. 回切本质上属于一次计划切换,应按计划切换流程执行。 + +### 切换前检查表 + +| 检查项 | 检查要求 | 说明 | +|---|---|---| +| 主备复制状态 | 无严重延迟或异常中断 | 确认备库具备接管条件 | +| WAL 归档状态 | 最近归档成功 | 避免切换与恢复证据缺口 | +| 备库只读可用性 | 可正常连接与查询 | 确认备库实例健康 | +| 代理状态 | `HAProxy`、`PgBouncer` 正常 | 确保切换入口可用 | +| 应用连接配置 | 使用统一代理地址 | 禁止应用直连数据库 IP | +| 定时任务状态 | 高风险写任务可暂停 | 包括批量收费、批量代扣等 | +| 业务通知 | 已通知相关业务与运维人员 | 降低切换窗口影响 | + +### 切换后验证表 + +| 验证项 | 验证要求 | 适用说明 | +|---|---|---| +| 数据库连接 | 应用可正常连接新主库 | 基础可用性验证 | +| 登录与鉴权 | 后台登录、令牌校验正常 | 确认统一平台链路正常 | +| 收费业务 | 单笔收费、销账可执行 | 核心写业务验证 | +| 开账业务 | 账单查询、开账写入正常 | 核心账务链路验证 | +| 发票业务 | 发票申请、查询可用 | 核心票据链路验证 | +| 银行代扣 | 查询和批次处理链路正常 | 涉及外联时至少完成内部链路检查 | +| 日志与监控 | 新主库监控、慢日志、告警恢复正常 | 运维可观测性验证 | +| 备份与归档 | 新主库 WAL 归档恢复正常 | 确认恢复能力未中断 | + +### 当前项目建议切换策略 + +结合当前项目部署口径,建议采用以下策略: + +1. 数据库切换统一由数据库代理层完成,不在 4 台应用服务器上分别切换配置。 +2. 一期建议采用统一读写入口模式,减少应用改造复杂度。 +3. 切换窗口内应重点管控收费、账务、发票、银行代扣等核心写入场景。 +4. 生产切换完成后,应同步检查 `Quartz` 定时任务、银行文件处理任务及发票异步任务是否恢复正常。 + +### 正式文档建议表述 + +福建水务营收系统数据库切换采用“主备切换 + 代理入口切换”的实施模式。计划切换和故障切换均由数据库高可用组件完成主备角色调整,由数据库代理层完成统一接入地址切换,应用系统不直接感知数据库物理节点变化。切换实施前应完成复制状态、归档状态、代理状态和高风险任务状态检查,切换实施后应完成收费、开账、账务、发票、银行代扣等关键业务链路验证,并将原主库按备库角色重新纳入复制体系。 + +## 申请结论 + +为满足福建水务营收系统生产环境对数据库连续运行和灾难恢复的要求,建议甲方按以下原则审批 PostgreSQL 16 容灾资源: + +1. 至少配置 1 台主库服务器、1 台备库服务器和 1 套独立备份归档存储。 +2. 如备库承担正式接管职责,CPU 与内存宜按主库 100% 配置,存储不得低于主库。 +3. 如需形成正式生产级容灾体系,建议采用“同城双可用区主备 + 备份归档”方案。 +4. 如需形成区域级灾难恢复体系,建议进一步增配 1 台异地灾备服务器。 + +综上,PostgreSQL 16 容灾资源申请可分阶段实施,但正式生产环境不宜低于“双节点主备 + 独立备份归档”的最低建设标准。 diff --git a/output/pgsql16_docx_rendered/images/diagram_1.mmd b/output/pgsql16_docx_rendered/images/diagram_1.mmd new file mode 100644 index 0000000..1936ad8 --- /dev/null +++ b/output/pgsql16_docx_rendered/images/diagram_1.mmd @@ -0,0 +1,5 @@ +flowchart TD + APP[应用集群] --> PG1[(主库 Primary)] + PG1 -->|流复制| PG2[(备库 Standby)] + PG1 --> BK[备份归档存储] + PG2 --> BK diff --git a/output/pgsql16_docx_rendered/images/diagram_1.png b/output/pgsql16_docx_rendered/images/diagram_1.png new file mode 100644 index 0000000..c311bc0 Binary files /dev/null and b/output/pgsql16_docx_rendered/images/diagram_1.png differ diff --git a/output/pgsql16_docx_rendered/images/diagram_2.mmd b/output/pgsql16_docx_rendered/images/diagram_2.mmd new file mode 100644 index 0000000..ab82bdc --- /dev/null +++ b/output/pgsql16_docx_rendered/images/diagram_2.mmd @@ -0,0 +1,12 @@ +flowchart LR + subgraph AZ1[生产可用区 A] + APP1[应用节点] + PG1[(主库 Primary)] + end + subgraph AZ2[同城可用区 B] + PG2[(同步备库 Standby)] + end + APP1 --> PG1 + PG1 -->|同步复制| PG2 + PG1 --> BK[备份归档存储] + PG2 --> BK diff --git a/output/pgsql16_docx_rendered/images/diagram_2.png b/output/pgsql16_docx_rendered/images/diagram_2.png new file mode 100644 index 0000000..bbc27a2 Binary files /dev/null and b/output/pgsql16_docx_rendered/images/diagram_2.png differ diff --git a/output/pgsql16_docx_rendered/images/diagram_3.mmd b/output/pgsql16_docx_rendered/images/diagram_3.mmd new file mode 100644 index 0000000..eaadab7 --- /dev/null +++ b/output/pgsql16_docx_rendered/images/diagram_3.mmd @@ -0,0 +1,15 @@ +flowchart LR + subgraph IDC1[生产中心] + PG1[(主库 Primary)] + end + subgraph IDC2[同城灾备中心] + PG2[(同步备库 Standby)] + end + subgraph IDC3[异地灾备中心] + PG3[(异步灾备库 DR)] + end + PG1 -->|同步复制| PG2 + PG1 -->|异步复制| PG3 + PG1 --> BK[备份归档存储] + PG2 --> BK + PG3 --> BK diff --git a/output/pgsql16_docx_rendered/images/diagram_3.png b/output/pgsql16_docx_rendered/images/diagram_3.png new file mode 100644 index 0000000..1c5e0e5 Binary files /dev/null and b/output/pgsql16_docx_rendered/images/diagram_3.png differ diff --git a/output/pgsql16_docx_rendered/images/diagram_4.mmd b/output/pgsql16_docx_rendered/images/diagram_4.mmd new file mode 100644 index 0000000..6b4b24d --- /dev/null +++ b/output/pgsql16_docx_rendered/images/diagram_4.mmd @@ -0,0 +1,5 @@ +flowchart TD + APP[应用集群] --> PG1[(主库 Primary)] + PG1 -->|同步/异步复制| PG2[(同城备库 Standby)] + PG1 -->|基础备份 + WAL 归档| OBJ[异地对象存储/异地备份库] + PG2 -->|基础备份 + WAL 归档| OBJ diff --git a/output/pgsql16_docx_rendered/images/diagram_4.png b/output/pgsql16_docx_rendered/images/diagram_4.png new file mode 100644 index 0000000..53f8821 Binary files /dev/null and b/output/pgsql16_docx_rendered/images/diagram_4.png differ diff --git a/output/pgsql16_docx_rendered/images/diagram_5.mmd b/output/pgsql16_docx_rendered/images/diagram_5.mmd new file mode 100644 index 0000000..a254246 --- /dev/null +++ b/output/pgsql16_docx_rendered/images/diagram_5.mmd @@ -0,0 +1,5 @@ +flowchart TD + APP[应用集群] --> PGB[PgBouncer] + PGB --> HAP[HAProxy RW 入口] + HAP --> PG1[(当前主库 Primary)] + PAT[Patroni] -.主备状态.-> HAP diff --git a/output/pgsql16_docx_rendered/images/diagram_5.png b/output/pgsql16_docx_rendered/images/diagram_5.png new file mode 100644 index 0000000..8cba12d Binary files /dev/null and b/output/pgsql16_docx_rendered/images/diagram_5.png differ diff --git a/output/pgsql16_docx_rendered/images/diagram_6.mmd b/output/pgsql16_docx_rendered/images/diagram_6.mmd new file mode 100644 index 0000000..9f6cc9d --- /dev/null +++ b/output/pgsql16_docx_rendered/images/diagram_6.mmd @@ -0,0 +1,9 @@ +flowchart LR + APP[应用集群] --> PGBRW[PgBouncer RW] + APP --> PGBRO[PgBouncer RO] + PGBRW --> HAPRW[HAProxy RW] + PGBRO --> HAPRO[HAProxy RO] + HAPRW --> PG1[(当前主库 Primary)] + HAPRO --> PG2[(热备库 Standby)] + PAT[Patroni] -.主备状态.-> HAPRW + PAT -.主备状态.-> HAPRO diff --git a/output/pgsql16_docx_rendered/images/diagram_6.png b/output/pgsql16_docx_rendered/images/diagram_6.png new file mode 100644 index 0000000..cff06c0 Binary files /dev/null and b/output/pgsql16_docx_rendered/images/diagram_6.png differ diff --git a/output/planb_docx_rendered/08_Integrated_Deployment_Design_PlanB.rendered.md b/output/planb_docx_rendered/08_Integrated_Deployment_Design_PlanB.rendered.md new file mode 100644 index 0000000..e1cbb98 --- /dev/null +++ b/output/planb_docx_rendered/08_Integrated_Deployment_Design_PlanB.rendered.md @@ -0,0 +1,456 @@ +--- +doc_id: TC-08-INTEGRATED-DEPLOYMENT +doc_role: supplemental_document +authority: secondary +scope: 方案二整体部署 +source_of_truth: false +last_reviewed: 2026-03-26 +retrieval_priority: P1 +--- + +# 福建水务营收系统整体部署方案说明书 + +## 文档信息 +| 项目信息 | 详情 | +|---------|------| +| **项目名称** | 福建水务营收系统 | +| **文档类型** | 技术专题说明 | +| **方案定位** | 已采纳 PostgreSQL 16 方案二作为数据库部署方案后的整体部署方案 | +| **文档版本** | v1.0 | +| **编写日期** | 2026-03-26 | +| **文档状态** | ✅ 正式建议稿 | + +## 目录 + +1. 编制目的 +2. 方案前提 +3. 整体部署原则 +4. 软件拓扑图 +5. 主机部署图 +6. 数据库访问链路图 +7. 备份恢复链路图 +8. 网络拓扑图 +9. 主机角色与部署内容 +10. 资源配置建议 +11. 资源审批汇总表 +12. 基础软件与版本清单 +13. 部署方式说明 +14. 网络需求 +15. 网络开通清单 +16. 访问控制与端口建议 +17. 实施步骤 +18. 验收标准 +19. 部署结论 + +## 编制目的 + +本文档用于在已采纳 PostgreSQL 16 方案二作为数据库部署方案的前提下,形成覆盖前端、后端、中间件、静态存储及数据库的一体化整体部署方案,作为甲方进行主机、网络、存储与基础软件资源审批的依据。 + +## 方案前提 + +本方案以以下前提为基础: + +1. 数据库部署方案已采纳 `docs/design/03_Technical_Design/07_PostgreSQL16_DR_Resource_Application.md` 中的方案二,即“同城双可用区主备容灾方案”。 +2. 前端继续采用 `Nginx + Vue3` 的静态部署模式。 +3. 对外访问经甲方或第三方管理的公网入口进行薄转发,不纳入本方案主机资源范围。 +4. 内网 `Nginx` 单独部署,负责将开放 API 端点负载到两台业务应用节点。 +5. 两台业务应用节点内均部署 `Spring Boot Gateway`,作为微服务集群统一接入入口,并同时承载业务服务。 +6. 中间件集中部署在 1 台主机上。 +7. 数据库控制组件与中间件部署在同一台主机上。 +8. `MinIO` 作为静态存储与对象存储统一入口,与中间件同机部署。 +9. 一期口径下,原“数据与中间件节点”和“文件存储节点”合并为 1 台综合节点。 +10. 银行文件交换采用独立 `SFTP/FTP` 文件交换服务器,作为银行送盘、回盘、对账文件交换专用前置机。 +11. 当前已知可用于本方案的业务与基础设施主机资源如下: + - 内网 Nginx 入口节点:8 核 CPU / 16 GB 内存 / 300 GB 存储,共 1 台 + - 业务应用节点(主):32 核 CPU / 64 GB 内存 / 300 GB 存储,共 2 台 + - 数据、中间件与文件存储综合节点:16 核 CPU / 32 GB 内存 / 2300 GB 存储,共 1 台 + - 银行文件交换服务器:2 核 CPU / 8 GB 内存 / 200 GB 存储,共 1 台 + - 另行配置 PostgreSQL 主库与热备库各 1 台 + +## 整体部署原则 + +整体部署遵循以下原则: + +1. 前后端逻辑分层部署,避免数据库节点与业务节点混部。 +2. 中间件集中部署,降低主机数量和运维复杂度。 +3. 数据库主备分离部署,避免与中间件、应用节点混部。 +4. 数据库控制组件集中部署,通过统一代理地址屏蔽主备切换细节。 +5. 网络按公网接入区、内网接入区、应用区、中间件与文件存储区、银行文件交换区、数据区分层隔离。 +6. 在现有主机数量约束下,优先复用现有业务应用节点、内网入口节点及综合节点资源。 + +## 软件拓扑图 + +**图 4-1 访问与应用软件拓扑图** + +![图1](images/diagram_1.png) + +图说明: + +1. PC 端用户通过内网直接访问内网 Nginx。 +2. 移动端用户和第三方系统先经公网入口薄转发,再由公网入口转发到内网 Nginx。 +3. 内网 Nginx 将开放 API 端点负载到两台业务应用节点。 +4. 两台业务应用节点内均部署 Spring Boot Gateway,作为微服务集群统一接入入口。 +5. 每台业务应用节点内的 Gateway 再向本节点业务服务转发请求。 + +**图 4-2 综合服务软件拓扑图** + +![图2](images/diagram_2.png) + +图说明: + +1. 综合节点承接缓存、配置、对象存储及数据库控制组件。 +2. 两台业务应用节点统一访问综合节点,不直接连接数据库。 + +**图 4-3 数据与备份软件拓扑图** + +![图3](images/diagram_3.png) + +图说明: + +1. 数据库控制组件经由主库提供数据库访问能力。 +2. 主库与热备之间通过同步复制保持一致性。 +3. 银行文件交换服务器承接送盘、回盘、对账文件交换能力。 +4. MinIO 与银行文件交换服务器分别将各自数据归档到备份归档存储。 + +## 主机部署图 + +**图 4-4 主机部署总览图** + +![图4](images/diagram_4.png) + +图说明: + +1. 内网 Nginx 入口节点作为我方统一接入入口,承接 API 转发与内部负载均衡能力。 +2. 业务应用节点 1 和业务应用节点 2 组成应用主机集群,节点内同时部署 Spring Boot Gateway 与核心业务服务。 +3. 综合节点集中承载 Redis、Nacos、MinIO、HAProxy、PgBouncer、Patroni,并同时访问数据库主库与热备服务器。 +4. 独立的 SFTP/FTP 文件交换服务器承接银行送盘、回盘、对账文件交换,并由业务应用节点直接访问。 +5. 数据库主库服务器与数据库热备服务器独立部署,满足数据库高可用要求。 + +主机部署细化说明: + +1. 内网 Nginx 入口节点部署 `Nginx`,负责开放 API 转发和内部负载均衡。 +2. 两台业务应用节点分别部署 `Spring Boot Gateway` 与业务服务实例。 +3. 综合节点部署 `Redis`、`Nacos`、`MinIO`、`HAProxy`、`PgBouncer`、`Patroni`,并负责访问数据库主库与热备服务器。 +4. SFTP/FTP 文件交换服务器部署银行文件交换服务及送盘、回盘、对账目录,由业务应用节点直接访问。 +5. 数据库主库服务器部署 PostgreSQL 主库实例,数据库热备服务器部署 PostgreSQL 热备实例。 + +## 数据库访问链路图 + +**图 4-5 数据库访问链路图** + +![图5](images/diagram_5.png) + +图说明: + +1. 业务应用不直接连接数据库主机。 +2. PgBouncer 负责连接池。 +3. HAProxy 负责数据库入口代理。 +4. Patroni 负责主备状态管理与切换控制。 +5. 综合节点侧的数据库控制组件会同时访问主库和热备,用于探测、控制和切换。 + +## 备份恢复链路图 + +**图 4-6 备份恢复链路图** + +![图6](images/diagram_6.png) + +图说明: + +1. 主库和热备均向备份归档存储输出备份数据。 +2. 综合节点中的 MinIO 文件数据也纳入备份范围。 +3. 备份归档存储作为数据库恢复与文件恢复的统一入口。 + +## 网络拓扑图 + +**图 4-7 网络拓扑图** + +![图7](images/diagram_7.png) + +图说明: + +1. PC 端用户通过内网直接访问内网 Nginx,移动端用户和第三方系统通过公网入口薄转发,再转发至内网 Nginx。 +2. 内网 Nginx 统一负载到两台业务应用节点,两台节点内部均部署 Spring Boot Gateway。 +3. 业务应用节点一方面直接访问 SFTP/FTP 文件交换服务器,另一方面访问综合节点获取缓存、配置、文件和数据库代理能力。 +4. 综合节点访问 PostgreSQL 主库与热备,数据库主备及综合节点均接入备份归档存储。 + +## 主机角色与部署内容 + +| 层级 | 主机角色 | 数量 | 主要部署内容 | 说明 | +|---|---|---:|---|---| +| 接入层 | 内网 Nginx 入口节点 | 1 台 | Nginx、API 转发、内部负载均衡 | 作为我方统一内网接入入口,承接开放 API 转发 | +| 应用层 | 业务应用节点(主) | 2 台 | Spring Boot Gateway、Spring Boot 业务服务 | 承载微服务集群接入与表务、抄表、收费、账务、发票、报表等核心应用服务 | +| 综合支撑层 | 数据、中间件与文件存储综合节点 | 1 台 | Redis、Nacos、MinIO、HAProxy、PgBouncer、Patroni | 中间件、数据库控制与文件存储同机部署 | +| 银行交换层 | SFTP/FTP 文件交换服务器 | 1 台 | SFTP/FTP 服务、送盘目录、回盘目录、对账目录、归档目录 | 作为银行文件交换专用前置机 | +| 数据库层 | PostgreSQL 主库服务器 | 1 台 | PostgreSQL 16 Primary | 部署在可用区 A | +| 数据库层 | PostgreSQL 热备服务器 | 1 台 | PostgreSQL 16 Standby | 部署在可用区 B | +| 备份层 | 备份归档存储 | 1 套 | 基础备份、WAL 归档、恢复副本 | 独立备份空间 | + +## 资源配置建议 + +| 主机角色 | 数量 | 建议配置 | 备注 | +|---|---:|---|---| +| 内网 Nginx 入口节点 | 1 台 | 8 核 CPU / 16 GB 内存 / 300 GB 存储 | 承载内网 Nginx、API 转发和内部负载均衡 | +| 业务应用节点(主) | 2 台 | 32 核 CPU / 64 GB 内存 / 300 GB 存储 | 承载 Spring Boot Gateway 及表务、抄表、收费、账务、发票、报表等核心应用服务 | +| 数据、中间件与文件存储综合节点 | 1 台 | 16 核 CPU / 32 GB 内存 / 2300 GB 存储 | 承载缓存、配置治理、数据库控制、图片、附件等非结构化数据 | +| SFTP/FTP 文件交换服务器 | 1 台 | 2 核 CPU / 8 GB 内存 / 200 GB 存储 | 承载银行送盘、回盘、对账、归档文件交换,建议独立部署 | +| PostgreSQL 主库服务器 | 1 台 | 24 核 CPU / 48 GB 内存 / 1 TB NVMe SSD | 生产写入节点,不计入上述已知 4 类业务主机 | +| PostgreSQL 热备服务器 | 1 台 | 24 核 CPU / 48 GB 内存 / 1 TB NVMe SSD | 正式切换接管节点,不计入上述已知 4 类业务主机 | +| 备份归档存储 | 1 套 | 可用空间 4 TB 至 6 TB | 存放全量备份与 WAL 归档 | + +### 银行文件交换服务器容量估算 + +按 20 万用户、5 年保留期估算,银行文件交换服务器主要承载代扣、托收、对账等批次文件,不承载全量业务明细数据库。 + +估算依据如下: + +1. 银行代扣、托收、对账文件以批次文件为主,不是每位用户每天形成独立文件。 +2. 按“仅覆盖银行代扣/托收用户,且按月批次送盘/回盘一次”的业务节奏估算,单个批次文件大小通常在 `10 MB ~ 40 MB` 量级。 +3. 按每月送盘、回盘、对账共 `3` 类核心文件估算,月文件量约为: + - `30 MB ~ 120 MB / 月` +4. 按 1 年估算,原始批次文件总量约为: + - `0.36 GB ~ 1.44 GB / 年` +5. 考虑归档副本、异常重传、中间文件和运行日志,按 `10 ~ 15` 倍放大后,5 年总量通常约为: + - `20 GB ~ 110 GB` + +因此,按最节约的一期规划,银行文件交换服务器可按 `2 核 CPU / 8 GB 内存 / 200 GB 存储` 配置满足送盘、回盘、对账文件交换与 5 年留存需要;如后续银行通道数量增加、并发文件交换增加或保留策略扩大,再扩容至 `4 核 / 8 GB / 500 GB` 即可。建议设置 `70%` 容量预警,并预留扩容机制。 + +## 资源审批汇总表 + +以下汇总表用于甲方进行主机、存储、网络及基础软件部署范围审批。 + +| 序号 | 资源名称 | 数量 | 规格 | 部署内容 | 用途说明 | 建议口径 | +|---|---:|---:|---|---|---|---| +| 1 | 内网 Nginx 入口节点 | 1 台 | 8 核 CPU / 16 GB 内存 / 300 GB 存储 | Nginx、API 转发、内部负载均衡 | 我方统一内网接入入口 | 可利旧优先 | +| 2 | 业务应用节点(主) | 2 台 | 32 核 CPU / 64 GB 内存 / 300 GB 存储 | Spring Boot Gateway、Spring Boot 核心业务服务 | 承载微服务接入与核心业务服务 | 现有资源纳入正式方案 | +| 3 | 数据、中间件与文件存储综合节点 | 1 台 | 16 核 CPU / 32 GB 内存 / 2300 GB 存储 | Redis、Nacos、MinIO、HAProxy、PgBouncer、Patroni | 承载缓存、配置治理、数据库控制、图片、附件、导出文件等能力 | 现有资源纳入正式方案 | +| 4 | SFTP/FTP 文件交换服务器 | 1 台 | 2 核 CPU / 8 GB 内存 / 200 GB 存储 | SFTP/FTP 服务、送盘/回盘/对账目录、归档目录 | 承载银行文件交换与目录隔离 | 按最节约一期规划建议新增或单独利旧 | +| 5 | PostgreSQL 主库服务器 | 1 台 | 24 核 CPU / 48 GB 内存 / 1 TB NVMe SSD | PostgreSQL 16 Primary | 承载生产写入 | 建议单独配置 | +| 6 | PostgreSQL 热备服务器 | 1 台 | 24 核 CPU / 48 GB 内存 / 1 TB NVMe SSD | PostgreSQL 16 Standby | 承载正式切换接管 | 建议单独配置 | +| 7 | 备份归档存储 | 1 套 | 可用空间 4 TB 至 6 TB | 基础备份、WAL 归档、恢复副本 | 保障恢复与审计追溯 | 可利旧或新增存储空间 | + +### 审批建议 + +1. 业务应用节点、综合节点、内网 Nginx 入口节点可优先按现有资源纳入实施范围。 +2. SFTP/FTP 文件交换服务器建议单独审批,以满足银行文件交换隔离和安全要求。 +3. PostgreSQL 主库与热备库建议作为单独审批项,避免与现有业务节点混部。 +4. 备份归档存储建议作为单独资源项审批,避免后期因备份空间不足影响正式上线。 + +## 基础软件与版本清单 + +| 类别 | 软件名称 | 建议版本 | 部署位置 | 说明 | +|---|---|---|---|---| +| 操作系统 | Linux 发行版 | openEuler 20.03+ / CentOS 7.9+ | 全部服务器 | 按甲方基础环境标准选定 | +| 运行环境 | JDK | 17 | 业务应用节点 | Spring Boot 运行环境 | +| 接入层 | Nginx | 1.20+ | 内网 Nginx 入口节点 | 内网 API 转发、内部负载均衡 | +| 网关服务 | Spring Boot Gateway | 3.x | 业务应用节点 | 微服务集群统一接入 | +| 业务服务 | Spring Boot | 3.x | 业务应用节点 | 核心业务服务框架 | +| 银行文件交换 | SFTP/FTP 服务 | 稳定版 | SFTP/FTP 文件交换服务器 | 银行送盘、回盘、对账文件交换 | +| 数据库 | PostgreSQL | 16 | 主库、热备库 | 主备数据库部署 | +| 缓存 | Redis | 6.2+ | 综合节点 | 缓存、会话、轻量级消息能力 | +| 配置中心 | Nacos | 2.x | 综合节点 | 配置治理与注册管理 | +| 对象存储 | MinIO | RELEASE 稳定版 | 综合节点 | 图片、附件、导出文件存储 | +| 数据库代理 | HAProxy | 2.x | 综合节点 | 数据库读写入口代理 | +| 连接池 | PgBouncer | 1.2x+ | 综合节点 | 统一数据库连接池 | +| 高可用控制 | Patroni | 稳定版 | 综合节点 | 主备状态管理与切换 | + +## 部署方式说明 + +### 总体部署原则 + +本方案的部署方式遵循以下原则: + +1. 入口代理类组件优先采用 `Docker` 部署,并可优先评估 `host` 网络模式。 +2. 业务应用优先采用 `Docker` 部署,但不建议使用 `host` 网络模式。 +3. 数据库主备优先采用物理机或虚拟机直接部署,不建议容器化承载 PostgreSQL 主备本体。 +4. 数据库控制组件如需容器化,应优先选择轻量代理组件容器化,高可用控制组件仍以直接部署为优先。 + +### 组件部署方式建议 + +| 组件 | 部署节点 | 建议部署方式 | 是否建议 `host` 模式 | 说明 | +|---|---|---|---|---| +| 内网 Nginx | 内网 Nginx 入口节点 | Docker 部署 | 是,优先建议 | 作为我方统一接入入口,便于端口管理与转发 | +| Spring Boot Gateway | 业务应用节点(主) | Docker 部署 | 否 | 作为微服务统一接入入口,建议与业务服务同节点部署 | +| Spring Boot 应用 | 业务应用节点(主) | Docker 部署 | 否 | 便于发布、回滚、扩容,保留容器网络隔离 | +| SFTP/FTP 服务 | SFTP/FTP 文件交换服务器 | 物理机/虚拟机直接部署 | 否 | 作为银行文件交换专用服务,建议独立部署并做目录隔离 | +| Redis | 综合节点 | Docker 部署 | 可选 | 可采用普通容器网络,必要时可评估 `host` | +| Nacos | 综合节点 | Docker 部署 | 可选 | 默认容器网络即可,便于配置治理 | +| HAProxy | 综合节点 | Docker 部署 | 是,优先建议 | 作为数据库代理入口,适合 `host` 模式 | +| PgBouncer | 综合节点 | Docker 部署 | 是,优先建议 | 作为数据库连接池入口,适合 `host` 模式 | +| Patroni | 综合节点 | 物理机/虚拟机直接部署 | 否 | 建议与系统服务集成,便于运维与切换控制 | +| MinIO | 综合节点 | Docker 部署 | 否 | 更关注数据盘挂载与对象存储目录管理 | +| PostgreSQL 主库 | 主库服务器 | 物理机/虚拟机直接部署 | 否 | 核心数据库本体不建议容器化 | +| PostgreSQL 热备 | 热备服务器 | 物理机/虚拟机直接部署 | 否 | 高可用数据库本体不建议容器化 | + +### 优先采用 Docker 且可使用 `host` 模式的组件 + +结合当前资源结构,建议优先采用 `Docker + host` 模式的组件如下: + +1. `内网 Nginx` +2. `HAProxy` +3. `PgBouncer` + +采用 `host` 模式的主要原因如下: + +1. 直接监听固定服务端口,减少端口映射复杂度。 +2. 更便于与主机防火墙、域名、VIP、健康检查配合。 +3. 对于入口类与代理类组件,运维体验更接近直接部署。 + +### 不建议采用 `host` 模式的组件 + +以下组件不建议采用 `Docker + host` 模式: + +1. `Spring Boot` 业务应用:应保留容器网络隔离,便于扩容和端口治理。 +2. `MinIO`:应以存储挂载与数据目录管理为重点,不依赖 `host` 模式。 +3. `PostgreSQL 主库 / 热备`:数据库本体优先直接部署,不建议容器化。 +4. `Patroni`:建议直接部署,便于与数据库高可用控制链路协同。 + +## 网络需求 + +### 1. 网络分区要求 + +| 网络分区 | 部署对象 | 访问要求 | +|---|---|---| +| 公网接入区 | 公网入口薄转发 | 对外提供 HTTPS 访问,不纳入我方主机资源 | +| 应用区 | 业务应用节点 | 仅允许内网接入区与运维区访问 | +| 中间件与文件存储区 | Redis、Nacos、MinIO、数据库控制组件 | 仅允许业务应用节点与运维区访问 | +| 银行文件交换区 | SFTP/FTP 文件交换服务器 | 仅允许业务应用节点、银行专线或授权外联链路访问 | +| 数据区 | PostgreSQL 主库、热备库、备份存储 | 严格限制,仅允许中间件控制主机和运维区访问 | + +### 2. 带宽与时延要求 + +| 网络链路 | 建议要求 | 说明 | +|---|---|---| +| 公网入口薄转发到内网 Nginx | 千兆网络 | 满足公网入口转发 | +| 内网 Nginx 到业务应用 | 千兆网络 | 满足开放 API 转发与网关接入 | +| 业务应用到综合节点 | 千兆网络 | 满足缓存、配置治理、文件访问与数据库代理访问 | +| 业务应用到 SFTP/FTP 服务器 | 千兆网络 | 满足送盘、回盘、对账文件交换 | +| 银行链路到 SFTP/FTP 服务器 | 千兆网络或专线 | 满足银行文件交换与目录投递 | +| 综合节点到数据库 | 千兆网络以上 | 满足数据库代理与健康检查 | +| 主备复制链路 | 不低于 10 Gbps | 支撑同步复制 | +| 同城主备时延 | 建议低于 2 ms | 支撑稳定同步复制 | +| 数据库到备份存储 | 千兆网络以上 | 满足基础备份与 WAL 归档传输 | +| 综合节点到备份存储 | 千兆网络以上 | 满足文件数据备份与归档传输 | + +### 3. 网络开通要求 + +| 类别 | 开通要求 | 说明 | +|---|---|---| +| 对外访问 | 开通 443 端口 | 提供统一 HTTPS 入口 | +| 公网入口薄转发访问内网 Nginx | 开通公网入口到内网 Nginx 的转发端口 | 仅授权链路访问 | +| 内网 Nginx 访问应用 | 开通内网 Nginx 到业务应用的 API / 网关端口 | 仅内网访问 | +| 应用访问综合节点 | 开通 Redis、Nacos、MinIO、PgBouncer 相关端口 | 仅应用区访问 | +| 业务应用访问 SFTP/FTP 服务器 | 开通 SFTP/FTP 相关端口 | 用于银行文件送盘、回盘、对账交换 | +| 银行链路访问 SFTP/FTP 服务器 | 开通 FTP/SFTP 服务端口 | 仅银行授权链路访问 | +| 综合节点访问数据库 | 开通 PostgreSQL 5432 及健康检查相关端口 | 仅综合节点访问 | +| 运维访问 | 开通运维区到各层必要管理端口 | 用于巡检、发布、恢复、切换 | + +## 网络开通清单 + +| 源区域/源主机 | 目标区域/目标主机 | 协议/端口 | 用途 | 开通要求 | +|---|---|---|---|---| +| 外部用户 | 公网入口薄转发 | HTTPS/443 | 页面访问、接口入口 | 对外开放 | +| 公网入口薄转发 | 内网 Nginx 入口节点 | HTTP/HTTPS/转发端口 | 公网访问转入内网入口 | 授权链路放通 | +| 内网 Nginx 入口节点 | 业务应用节点(主) | HTTP/HTTPS/网关端口 | 内网 API 转发与微服务接入 | 内网放通 | +| 业务应用节点(主) | 综合节点 | TCP/6379 | Redis 访问 | 内网放通 | +| 业务应用节点(主) | 综合节点 | TCP/8848 | Nacos 访问 | 内网放通 | +| 业务应用节点(主) | 综合节点 | TCP/6432 | PgBouncer 访问 | 内网放通 | +| 业务应用节点(主) | 综合节点 | TCP/9000,9001 | MinIO 文件访问 | 内网放通 | +| 业务应用节点(主) | SFTP/FTP 文件交换服务器 | TCP/21 或 22 | 银行送盘、回盘、对账文件交换 | 内网放通 | +| 银行专线或授权外联链路 | SFTP/FTP 文件交换服务器 | TCP/21 或 22 | 银行文件目录投递与回收 | 仅授权链路放通 | +| 综合节点 | PostgreSQL 主库服务器 | TCP/5432 | 数据库代理与控制访问 | 内网放通 | +| 综合节点 | PostgreSQL 热备服务器 | TCP/5432 | 数据库代理、状态探测与控制访问 | 内网放通 | +| PostgreSQL 主库服务器 | PostgreSQL 热备服务器 | TCP/5432 | 主备同步复制 | 高带宽、低时延专用链路 | +| PostgreSQL 主库/热备库 | 备份归档存储 | TCP/存储协议端口 | 基础备份与 WAL 归档 | 内网放通 | +| 综合节点 | 备份归档存储 | TCP/存储协议端口 | 文件归档与备份 | 内网放通 | +| 运维管理终端 | 各节点 | SSH/22 及必要管理端口 | 运维、巡检、发布、恢复 | 仅运维区放通 | + +## 访问控制与端口建议 + +| 服务 | 典型端口 | 访问范围 | +|---|---|---| +| Nginx/HTTPS | 443 | 对外开放 | +| Spring Boot Gateway / 业务应用端口 | 项目自定义端口 | 仅内网 Nginx 与内网调用 | +| Redis | 6379 | 仅业务应用与运维可访问 | +| Nacos | 8848 | 仅业务应用与运维可访问 | +| MinIO | 9000/9001 | 仅业务应用与运维可访问 | +| SFTP/FTP 服务 | 21 或 22 | 仅业务应用节点、运维和银行授权链路可访问 | +| PgBouncer | 6432 | 仅业务应用可访问 | +| HAProxy | 5000 或项目定义端口 | 仅 PgBouncer 与运维可访问 | +| PostgreSQL | 5432 | 仅数据库控制主机与运维可访问 | + +## 实施步骤 + +### 1. 基础资源准备 + +1. 确认内网 Nginx 入口节点、业务应用节点、综合节点是否为利旧资源。 +2. 完成 SFTP/FTP 文件交换服务器、PostgreSQL 主库服务器、热备服务器及备份归档存储审批。 +3. 完成各网络分区、IP、域名、SSL 证书、路由及防火墙策略准备。 + +### 2. 基础软件安装 + +1. 安装操作系统并完成安全基线加固。 +2. 在业务应用节点安装 JDK、部署业务运行环境。 +3. 在内网 Nginx 入口节点安装 Nginx。 +4. 在综合节点安装 Redis、Nacos、HAProxy、PgBouncer、Patroni、MinIO。 +5. 在 SFTP/FTP 文件交换服务器安装 SFTP/FTP 服务并配置目录结构。 +6. 在数据库主备节点安装 PostgreSQL 16。 + +### 3. 数据库主备部署 + +1. 初始化 PostgreSQL 主库。 +2. 初始化 PostgreSQL 热备库并建立同步复制。 +3. 配置 Patroni、HAProxy、PgBouncer 联动。 +4. 配置基础备份与 WAL 归档。 +5. 配置业务应用节点到 SFTP/FTP 文件交换服务器的文件交换目录映射。 + +### 4. 应用与存储部署 + +1. 在业务应用节点部署 Spring Boot Gateway 和业务应用服务。 +2. 在内网 Nginx 入口节点配置 API 转发和内部负载均衡规则。 +3. 在综合节点初始化 MinIO 存储桶和访问策略。 +4. 在 SFTP/FTP 文件交换服务器配置送盘、回盘、对账、归档目录。 +5. 配置业务应用到 Redis、Nacos、PgBouncer、MinIO 的连接参数。 + +### 5. 联调与演练 + +1. 完成前后端联调。 +2. 完成中间件访问验证。 +3. 完成数据库主备同步验证。 +4. 完成文件上传、下载、归档验证。 +5. 完成主备切换演练与回切演练。 + +### 6. 上线准备与正式投产 + +1. 完成上线前巡检与问题清零。 +2. 确认监控、日志、备份、告警正常。 +3. 完成上线窗口审批。 +4. 按上线顺序切换生产流量。 + +## 验收标准 + +| 验收项 | 验收标准 | 说明 | +|---|---|---| +| 对外访问 | 用户可通过统一域名正常访问系统 | 公网入口薄转发与内网 Nginx 链路正常 | +| 业务应用可用性 | 表务、抄表、收费、账务、发票、报表等核心服务正常 | 业务主流程可执行 | +| Redis 可用性 | 缓存读写正常 | 中间件能力正常 | +| Nacos 可用性 | 配置下发正常 | 配置治理能力正常 | +| MinIO 可用性 | 图片、附件上传下载正常 | 文件存储能力正常 | +| SFTP/FTP 文件交换 | 送盘、回盘、对账目录读写正常 | 银行文件交换能力正常 | +| 数据库连接能力 | 业务应用可通过 PgBouncer 正常连接数据库 | 代理接入正常 | +| PostgreSQL 主备同步 | 主备复制正常,无严重延迟 | 高可用基础正常 | +| 数据库切换演练 | 主备切换成功,业务恢复正常 | 高可用能力可验证 | +| 备份归档 | 基础备份与 WAL 归档正常 | 恢复能力可验证 | +| 运维监控 | 关键节点监控、日志、告警正常 | 运维可观测性正常 | + +## 部署结论 + +在已采纳 PostgreSQL 16 方案二作为数据库部署方案的前提下,建议福建水务营收系统采用“前后端分层部署 + 中间件集中部署 + 数据库主备分离部署”的整体部署模式。 + +本方案的最终结论如下: + +1. 公网入口薄转发不纳入我方主机资源;我方实际部署的统一接入入口为内网 Nginx 入口节点。 +2. 2 台业务应用节点作为核心业务集群,节点内同时部署 Spring Boot Gateway 和业务服务,承接微服务统一接入与核心业务处理。 +3. 综合节点集中承载 Redis、Nacos、MinIO 及数据库控制组件,进一步压缩一期主机数量并降低部署复杂度。 +4. 新增 1 台 SFTP/FTP 文件交换服务器,作为银行送盘、回盘、对账文件交换专用前置机。 +5. PostgreSQL 16 采用同城双可用区 1 主 1 热备部署,满足高可用要求。 +6. 网络采用公网接入区、内网接入区、应用区、中间件与文件存储区、银行文件交换区、数据区分层隔离模式,以满足安全性、可维护性和资源审批要求。 diff --git a/output/planb_docx_rendered/images/diagram_1.mmd b/output/planb_docx_rendered/images/diagram_1.mmd new file mode 100644 index 0000000..b45b2df --- /dev/null +++ b/output/planb_docx_rendered/images/diagram_1.mmd @@ -0,0 +1,31 @@ +flowchart LR + classDef source fill:#ecfeff,stroke:#0891b2,stroke-width:1.2px,color:#083344; + classDef access fill:#fff7ed,stroke:#ea580c,stroke-width:1.4px,color:#7c2d12; + classDef app fill:#eff6ff,stroke:#2563eb,stroke-width:1.4px,color:#1e3a8a; + + U1[PC 端用户]:::source + U2[移动端用户]:::source + U3[第三方系统]:::source + G1[公网入口薄转发]:::access + G2[内网 Nginx]:::access + + subgraph APP1[业务应用节点 1] + direction TB + A1G[Spring Boot Gateway]:::app + A1B[业务服务]:::app + end + + subgraph APP2[业务应用节点 2] + direction TB + A2G[Spring Boot Gateway]:::app + A2B[业务服务]:::app + end + + U1 -->|内网访问| G2 + U2 -->|HTTPS 443| G1 + U3 -->|接口访问| G1 + G1 -->|开放 API 转发| G2 + G2 -->|负载到节点 1| A1G + G2 -->|负载到节点 2| A2G + A1G --> A1B + A2G --> A2B diff --git a/output/planb_docx_rendered/images/diagram_1.png b/output/planb_docx_rendered/images/diagram_1.png new file mode 100644 index 0000000..6c0861b Binary files /dev/null and b/output/planb_docx_rendered/images/diagram_1.png differ diff --git a/output/planb_docx_rendered/images/diagram_2.mmd b/output/planb_docx_rendered/images/diagram_2.mmd new file mode 100644 index 0000000..d652088 --- /dev/null +++ b/output/planb_docx_rendered/images/diagram_2.mmd @@ -0,0 +1,17 @@ +flowchart TB + classDef app fill:#eff6ff,stroke:#2563eb,stroke-width:1.4px,color:#1e3a8a; + classDef service fill:#f5f3ff,stroke:#7c3aed,stroke-width:1.4px,color:#4c1d95; + + A1[业务应用节点 1
    Gateway + Biz]:::app + A2[业务应用节点 2
    Gateway + Biz]:::app + + subgraph M[综合节点] + direction TB + M2[Redis / Nacos / MinIO]:::service + M3[HAProxy / PgBouncer / Patroni]:::service + end + + A1 -->|缓存 配置 文件访问| M2 + A2 -->|缓存 配置 文件访问| M2 + A1 -->|数据库代理访问| M3 + A2 -->|数据库代理访问| M3 diff --git a/output/planb_docx_rendered/images/diagram_2.png b/output/planb_docx_rendered/images/diagram_2.png new file mode 100644 index 0000000..e455c04 Binary files /dev/null and b/output/planb_docx_rendered/images/diagram_2.png differ diff --git a/output/planb_docx_rendered/images/diagram_3.mmd b/output/planb_docx_rendered/images/diagram_3.mmd new file mode 100644 index 0000000..6861edc --- /dev/null +++ b/output/planb_docx_rendered/images/diagram_3.mmd @@ -0,0 +1,20 @@ +flowchart LR + classDef service fill:#f5f3ff,stroke:#7c3aed,stroke-width:1.4px,color:#4c1d95; + classDef data fill:#ecfdf5,stroke:#059669,stroke-width:1.4px,color:#064e3b; + classDef backup fill:#fffbeb,stroke:#d97706,stroke-width:1.4px,color:#78350f; + classDef bank fill:#fef2f2,stroke:#dc2626,stroke-width:1.4px,color:#7f1d1d; + + M2[MinIO / 附件文件]:::service + M3[HAProxy / PgBouncer / Patroni]:::service + F1[SFTP / FTP 文件交换服务器]:::bank + D1[(PostgreSQL 主库)]:::data + D2[(PostgreSQL 热备)]:::data + B1[备份归档存储]:::backup + + M3 -->|数据库访问| D1 + M3 -->|状态感知| D2 + D1 -->|同步复制| D2 + D1 -->|基础备份 WAL 归档| B1 + D2 -->|备份副本| B1 + M2 -->|对象存储归档| B1 + F1 -->|银行文件归档| B1 diff --git a/output/planb_docx_rendered/images/diagram_3.png b/output/planb_docx_rendered/images/diagram_3.png new file mode 100644 index 0000000..6f69e1b Binary files /dev/null and b/output/planb_docx_rendered/images/diagram_3.png differ diff --git a/output/planb_docx_rendered/images/diagram_4.mmd b/output/planb_docx_rendered/images/diagram_4.mmd new file mode 100644 index 0000000..9e0a43a --- /dev/null +++ b/output/planb_docx_rendered/images/diagram_4.mmd @@ -0,0 +1,23 @@ +flowchart LR + classDef gateway fill:#fff7ed,stroke:#ea580c,stroke-width:1.2px,color:#7c2d12; + classDef app fill:#eff6ff,stroke:#2563eb,stroke-width:1.2px,color:#1e3a8a; + classDef middle fill:#f5f3ff,stroke:#7c3aed,stroke-width:1.2px,color:#4c1d95; + classDef data fill:#ecfdf5,stroke:#059669,stroke-width:1.2px,color:#064e3b; + + GW[内网 Nginx 入口节点]:::gateway + APP1[业务应用节点 1
    内含 Gateway]:::app + APP2[业务应用节点 2
    内含 Gateway]:::app + MID[综合节点]:::middle + FTP[SFTP / FTP 文件交换服务器]:::middle + DB1[(数据库主库服务器)]:::data + DB2[(数据库热备服务器)]:::data + + GW --> APP1 + GW --> APP2 + APP1 --> MID + APP2 --> MID + APP1 --> FTP + APP2 --> FTP + MID --> DB1 + MID --> DB2 + DB1 --> DB2 diff --git a/output/planb_docx_rendered/images/diagram_4.png b/output/planb_docx_rendered/images/diagram_4.png new file mode 100644 index 0000000..9b3efe5 Binary files /dev/null and b/output/planb_docx_rendered/images/diagram_4.png differ diff --git a/output/planb_docx_rendered/images/diagram_5.mmd b/output/planb_docx_rendered/images/diagram_5.mmd new file mode 100644 index 0000000..7cf1c77 --- /dev/null +++ b/output/planb_docx_rendered/images/diagram_5.mmd @@ -0,0 +1,16 @@ +flowchart LR + A1[业务应用节点 1] + A2[业务应用节点 2] + P[PgBouncer] + H[HAProxy] + M[(主库)] + S[(热备)] + T[Patroni] + + A1 -->|统一代理地址| P + A2 -->|统一代理地址| P + P -->|连接池复用| H + H -->|写流量| M + H -.热备探测 / 状态访问.-> S + M -->|同步复制| S + T -.主备状态管理.-> H diff --git a/output/planb_docx_rendered/images/diagram_5.png b/output/planb_docx_rendered/images/diagram_5.png new file mode 100644 index 0000000..c203ee5 Binary files /dev/null and b/output/planb_docx_rendered/images/diagram_5.png differ diff --git a/output/planb_docx_rendered/images/diagram_6.mmd b/output/planb_docx_rendered/images/diagram_6.mmd new file mode 100644 index 0000000..5479ee8 --- /dev/null +++ b/output/planb_docx_rendered/images/diagram_6.mmd @@ -0,0 +1,5 @@ +flowchart LR + DB1[(PostgreSQL 主库)] --> BK[备份归档存储] + DB2[(PostgreSQL 热备)] --> BK + MID[综合节点 / MinIO] --> BK + BK --> REC[恢复与演练入口] diff --git a/output/planb_docx_rendered/images/diagram_6.png b/output/planb_docx_rendered/images/diagram_6.png new file mode 100644 index 0000000..af96320 Binary files /dev/null and b/output/planb_docx_rendered/images/diagram_6.png differ diff --git a/output/planb_docx_rendered/images/diagram_7.mmd b/output/planb_docx_rendered/images/diagram_7.mmd new file mode 100644 index 0000000..2836071 --- /dev/null +++ b/output/planb_docx_rendered/images/diagram_7.mmd @@ -0,0 +1,78 @@ +flowchart TB + classDef user fill:#ecfeff,stroke:#0891b2,stroke-width:1.2px,color:#083344; + classDef access fill:#fff7ed,stroke:#ea580c,stroke-width:1.2px,color:#7c2d12; + classDef app fill:#eff6ff,stroke:#2563eb,stroke-width:1.2px,color:#1e3a8a; + classDef ext fill:#fef3c7,stroke:#d97706,stroke-width:1.2px,color:#78350f; + classDef middle fill:#f5f3ff,stroke:#7c3aed,stroke-width:1.2px,color:#4c1d95; + classDef data fill:#ecfdf5,stroke:#059669,stroke-width:1.2px,color:#064e3b; + classDef backup fill:#fdf2f8,stroke:#db2777,stroke-width:1.2px,color:#831843; + + subgraph U[访问来源] + direction LR + PC[PC 端用户] + M[移动端用户] + T[第三方系统] + end + + subgraph A[接入层] + direction TB + PGW[公网入口薄转发] + IGW[内网 Nginx] + end + + subgraph B[应用层] + direction LR + APP1[业务应用节点 1
    Spring Boot Gateway] + APP2[业务应用节点 2
    Spring Boot Gateway] + end + + subgraph E[外部交换区] + direction TB + FX[SFTP/FTP 文件交换服务器] + end + + subgraph C[综合服务层] + direction TB + MID[综合节点] + end + + subgraph D[数据层] + direction LR + DBM[(PostgreSQL 主库)] + DBS[(PostgreSQL 热备)] + end + + subgraph BK[备份归档层] + direction TB + STORE[备份归档存储] + end + + PC -->|内网访问| IGW + M -->|公网 HTTPS| PGW + T -->|公网 HTTPS/接口| PGW + PGW -->|转发| IGW + + IGW -->|负载均衡| APP1 + IGW -->|负载均衡| APP2 + + APP1 -->|文件交换| FX + APP2 -->|文件交换| FX + + APP1 -->|业务访问| MID + APP2 -->|业务访问| MID + + MID -->|数据库访问| DBM + MID -->|状态感知/只读访问| DBS + DBM -->|主备同步| DBS + + DBM -->|备份/WAL 归档| STORE + DBS -->|备份副本| STORE + MID -->|文件归档| STORE + + class PC,M,T user; + class PGW,IGW access; + class APP1,APP2 app; + class FX ext; + class MID middle; + class DBM,DBS data; + class STORE backup; diff --git a/output/planb_docx_rendered/images/diagram_7.png b/output/planb_docx_rendered/images/diagram_7.png new file mode 100644 index 0000000..bbbfaca Binary files /dev/null and b/output/planb_docx_rendered/images/diagram_7.png differ diff --git a/output/福建水务营收系统整体部署方案说明书.docx b/output/福建水务营收系统整体部署方案说明书.docx new file mode 100644 index 0000000..cda4424 Binary files /dev/null and b/output/福建水务营收系统整体部署方案说明书.docx differ diff --git a/output/福建水务营收系统整体部署方案说明书0402.docx b/output/福建水务营收系统整体部署方案说明书0402.docx new file mode 100644 index 0000000..824f0a6 Binary files /dev/null and b/output/福建水务营收系统整体部署方案说明书0402.docx differ diff --git a/specs/001-rev004-accounting/contracts/if-rev-007-accounting-request.md b/specs/001-rev004-accounting/contracts/if-rev-007-accounting-request.md deleted file mode 100644 index eb5801a..0000000 --- a/specs/001-rev004-accounting/contracts/if-rev-007-accounting-request.md +++ /dev/null @@ -1,71 +0,0 @@ -# Contract: IF-REV-007 账务调整接口 - -## 1. 合同定位 - -本合同用于固化 `IF-REV-007` 在 REV-004 一期中的统一接口口径,服务于后续正式接口文档修订、任务拆解与评审,不作为代码接口定义文件。 - -## 2. 适用范围 - -适用场景: -- 水量调整 -- 金额调整 -- 退款 -- 冲正 -- 坏账申请 - -不适用范围: -- 发票申请与结果回写 -- 银行代收与结算协同 -- 新 BPM 流程模型扩展 -- 独立账务台账表族设计 - -## 3. 请求合同 - -| 字段 | 类型 | 必填 | 说明 | 约束 | -|------|------|------|------|------| -| chargeId | Long | 是 | 目标账单 ID | 必须存在于 `biz_charge.id` | -| adjustType | String | 是 | 调整类型 | `USAGE` / `AMOUNT` / `REFUND` / `REVERSE` / `BAD_DEBT` | -| adjustAmount | Decimal | 否 | 调整金额 | 金额类场景必填 | -| adjustUsage | Decimal | 否 | 调整水量 | 水量类场景必填 | -| sourceTradeNo | String | 否 | 原交易流水号 | `REFUND` / `REVERSE` 场景必填 | -| reasonCode | String | 是 | 调整原因编码 | 需可追溯到业务字典 | -| remark | String | 否 | 调整说明 | 进入操作留痕 | -| attachmentList | Array | 否 | 依据附件 | 进入依据引用 | -| operatorId | Long | 是 | 操作人 ID | 必须可追溯责任归属 | - -## 4. 响应合同 - -| 字段 | 类型 | 说明 | 约束 | -|------|------|------|------| -| adjustmentNo | String | 调整业务编号 | 用于后续追踪 | -| chargeId | Long | 目标账单 ID | 与请求一致 | -| resultStatus | String | 处理状态 | `SUCCESS` / `PENDING_APPROVAL` / `FAIL` | -| writeBackStatus | String | 账单回写状态 | `SUCCESS` / `IGNORE_REPEAT` / `FAIL` | -| approvalRequired | Boolean | 是否进入审批 | 一期仅保留能力位 | -| msg | String | 处理说明 | 供调用方和评审使用 | - -## 5. 共性规则 - -1. 所有场景必须定位到既有账单对象,不建立并行账务主对象。 -2. 所有场景必须保留处理依据、前后变化和责任归属。 -3. 退款、冲正必须校验原交易存在性、交易状态、回调结果与异常处理状态,不得只以 `bk_transaction` 主记录存在作为通过条件。 -4. 审批相关内容一期仅保留 `approvalRequired`、`PENDING_APPROVAL` 与审批边界说明,不展开完整 BPM 流程、流程节点、流转规则或审批回写实现细节。 -5. 接口结果必须能映射到 `biz_charge*`、`bk_transaction*`、`biz_operat_log*` 三类对象。 -6. `resultStatus` 与 `writeBackStatus` 必须分离表达:前者表示业务处理结论,后者表示账单状态回写结论。 - -## 6. 物理承接口径 - -| 逻辑对象 | 物理承接 | -|---------|----------| -| 账单主对象 | `biz_charge` | -| 账单明细 | `biz_charge_detail` | -| 原交易校验 | `bk_transaction*` | -| 主日志 | `biz_operat_log` | -| 差异明细日志 | `biz_operat_log_detail` | - -## 7. 验收关注点 - -- 是否所有场景都仍挂靠 `IF-REV-007` -- 是否未引入超范围接口编号 -- 是否未把审批/BPM 细化为一期必做实现 -- 是否未误写独立账务台账表族为在线新增对象 diff --git a/specs/001-rev004-accounting/contracts/rev004-scenario-matrix.md b/specs/001-rev004-accounting/contracts/rev004-scenario-matrix.md deleted file mode 100644 index 4627909..0000000 --- a/specs/001-rev004-accounting/contracts/rev004-scenario-matrix.md +++ /dev/null @@ -1,33 +0,0 @@ -# Contract: REV-004 一期场景矩阵 - -## 1. 目的 - -用于统一 REV-004 一期各场景在输入依据、关键校验、结果表达和留痕要求上的差异,支撑后续 plan/tasks 拆解。 - -## 2. 场景矩阵 - -| 场景 | 主要输入 | 关键校验 | 结果表达 | 留痕重点 | 备注 | -|------|----------|----------|----------|----------|------| -| 水量调整 | `chargeId`、`adjustUsage`、`reasonCode` | 原抄表依据、账单状态可调 | `resultStatus`、`writeBackStatus` | 调整前后水量、依据附件 | 不新增跨周期水量独立表 | -| 金额调整 | `chargeId`、`adjustAmount`、`reasonCode` | 差异金额合法性、账单状态可调 | `resultStatus`、`writeBackStatus` | 调整前后金额、原因、经办人 | 可涉及重算口径 | -| 退款 | `chargeId`、`adjustAmount`、`sourceTradeNo` | 原交易存在、可退金额、幂等性 | `resultStatus`、`approvalRequired`、`writeBackStatus` | 原交易号、退款金额、处理结果 | 一期仅保留审批能力位 | -| 冲正 | `chargeId`、`sourceTradeNo`、`reasonCode` | 原交易状态、账单状态、可冲正性 | `resultStatus`、`approvalRequired`、`writeBackStatus` | 原交易号、状态变化、处理原因 | 不强接 BPM | -| 坏账申请 | `chargeId`、`reasonCode`、`remark` | 账龄、客户状态、业务条件 | `resultStatus`、`approvalRequired`、`writeBackStatus` | 申请原因、账单状态、审批边界 | 一期仅保留审批能力位与边界说明 | - -## 3. 共性能力 - -所有场景共享以下能力: -- 统一入口:`IF-REV-007` -- 统一账单承接:`biz_charge` / `biz_charge_detail` -- 统一原交易校验:`bk_transaction` / `bk_transaction_callback` / `bk_transaction_exception` -- 统一留痕:`biz_operat_log` / `biz_operat_log_detail` -- 统一结果表达:`resultStatus` / `writeBackStatus`(前者表示处理结论,后者表示账单回写结论) -- 审批边界:只保留 `approvalRequired`、`PENDING_APPROVAL` 与边界说明,不展开完整 BPM 流程、节点、流转规则或审批回写实现细节 - -## 4. 排除说明 - -以下内容不在本矩阵覆盖范围内: -- 独立账务细表设计 -- 发票、银行结算等其他接口族 -- backend 实施代码结构 -- 完整 BPM 审批流程定义 diff --git a/specs/001-rev004-accounting/contracts/rev004-traceability-matrix.md b/specs/001-rev004-accounting/contracts/rev004-traceability-matrix.md deleted file mode 100644 index d860e7f..0000000 --- a/specs/001-rev004-accounting/contracts/rev004-traceability-matrix.md +++ /dev/null @@ -1,23 +0,0 @@ -# Contract: REV-004 一期追溯矩阵 - -## 1. 目的 - -用于建立 `spec.md`、详细设计、接口设计、数据库设计之间的稳定追溯关系,确保后续正式文档修订与任务拆解基于同一口径。 - -## 2. 追溯矩阵 - -| 规格需求/场景 | 详细设计承接 | 接口设计承接 | 数据库承接 | 说明 | -|--------------|--------------|--------------|------------|------| -| 一期纳入范围:水量调整/金额调整/退款/冲正/坏账申请 | `12_REV_Detailed.md` REV-004 场景表 | `03_Interface_Design.md` `IF-REV-007` | `biz_charge*`、`biz_operat_log*` | 五类场景统一纳入一期,排除独立账务细表扩围 | -| 统一接口入口 | REV-004 接口映射 | `IF-REV-007` 请求/响应定义 | 账单与日志对象 | 不扩展到 `IF-REV-008`、`IF-REV-011` 等其他接口族 | -| 原交易校验 | REV-004 关键规则 | `sourceTradeNo` 字段 | `bk_transaction*` | 退款/冲正必须联动原交易主状态、回调结果与异常处理状态 | -| 处理结果回写 | REV-004 业务流程/关键规则 | `writeBackStatus`、`resultStatus` | `biz_charge` 状态承接 | `resultStatus` 与 `writeBackStatus` 必须分离表达 | -| 审批边界 | 审批留痕要求 | `approvalRequired`、`PENDING_APPROVAL` | 仅能力位,无独立审批表要求 | 一期不强接 BPM,仅保留边界说明 | -| 留痕与依据 | 操作日志与审批留痕 | `remark`、`attachmentList` | `biz_operat_log` / `biz_operat_log_detail` | 必须覆盖处理类型、原交易引用、前后差异与附件依据 | -| 旧系统细粒度台账承接 | 迁移补充表 | 历史查询与迁移校验口径 | 历史只读 + 在线主模型 | 不误写为在线新增实体 | - -## 3. 使用约束 - -- 本矩阵只服务于文档规划与后续正式主文档修订。 -- 若某条追溯关系无法在三份正式文档中对齐,应先回写正式主文档,再继续 tasks 或实施讨论。 -- Archive 与执行手册可用于核对,但不得替代正式结论。 diff --git a/specs/001-rev004-accounting/data-model.md b/specs/001-rev004-accounting/data-model.md deleted file mode 100644 index 3b82044..0000000 --- a/specs/001-rev004-accounting/data-model.md +++ /dev/null @@ -1,167 +0,0 @@ -# Data Model: REV-004 账务处理一期 - -## 建模原则 - -- 以逻辑实体 + 物理承接对象双层表达,避免把未确认能力误写为已落地独立表。 -- 在线主模型优先复用 `biz_charge*`、`biz_operat_log*`、`bk_transaction*`。 -- 审批相关内容仅保留能力位,不展开完整 BPM 流程模型。 - -## 实体一:AccountingRequest(账务处理申请) - -### 作用 -统一承接 `IF-REV-007` 的五类场景输入:水量调整、金额调整、退款、冲正、坏账申请。 - -### 核心字段 - -| 字段 | 类型 | 说明 | -|------|------|------| -| requestNo | String | 申请编号/调整业务编号 | -| adjustType | Enum | `USAGE` / `AMOUNT` / `REFUND` / `REVERSE` / `BAD_DEBT` | -| chargeId | Long | 目标账单 ID | -| sourceTradeNo | String | 原交易流水号,退款/冲正场景使用 | -| adjustAmount | Decimal | 调整金额 | -| adjustUsage | Decimal | 调整水量 | -| reasonCode | String | 调整原因编码 | -| remark | String | 调整说明 | -| attachmentList | Array | 依据附件 | -| operatorId | Long | 操作人 ID | -| requestedAt | DateTime | 发起时间 | - -### 校验规则 -- `chargeId`、`adjustType`、`reasonCode`、`operatorId` 必填。 -- `REFUND` / `REVERSE` 场景必须具备 `sourceTradeNo`。 -- `adjustAmount` 与 `adjustUsage` 按场景二选一或组合使用,不允许无意义空提交。 - -### 状态 -`submitted` → `accepted` / `rejected` → `processed` / `failed` - -## 实体二:AccountingResult(账务处理结果) - -### 作用 -统一承接处理结果、回写结果与是否需要审批。 - -### 核心字段 - -| 字段 | 类型 | 说明 | -|------|------|------| -| adjustmentNo | String | 调整业务编号 | -| chargeId | Long | 目标账单 ID | -| resultStatus | Enum | `SUCCESS` / `PENDING_APPROVAL` / `FAIL` | -| writeBackStatus | Enum | `SUCCESS` / `IGNORE_REPEAT` / `FAIL` | -| approvalRequired | Boolean | 是否进入审批 | -| msg | String | 处理说明 | -| processedAt | DateTime | 处理时间 | - -### 状态关系 -- `resultStatus` 表示业务处理结果。 -- `writeBackStatus` 表示账单回写结果。 -- `approvalRequired=true` 时允许 `resultStatus=PENDING_APPROVAL`。 - -## 实体三:ChargeAggregate(账单聚合对象) - -### 作用 -作为 REV-004 调整、退款、冲正的主要业务承接对象。 - -### 物理承接 -- `biz_charge` -- `biz_charge_detail` - -### 核心字段 - -| 字段 | 来源 | 说明 | -|------|------|------| -| chargeId | `biz_charge.id` | 账单主键 | -| chargeStatus | `biz_charge` | 账单状态 | -| receivableAmount | `biz_charge` / `biz_charge_detail` | 应收金额 | -| paidAmount | 业务汇总 | 已收金额 | -| remainAmount | 业务汇总 | 剩余待支付金额 | -| detailItems | `biz_charge_detail` | 费用明细集合 | - -### 关键关系 -- 1 个 `ChargeAggregate` 对应多条 `biz_charge_detail`。 -- 1 个 `AccountingRequest` 必须定位到 1 个 `ChargeAggregate`。 - -## 实体四:Transaction(原交易流水) - -### 作用 -为退款、冲正等场景提供原交易事实依据。 - -### 物理承接 -- `bk_transaction` -- 关联扩展:`bk_transaction_callback`(异步回调结果核对) -- 关联扩展:`bk_transaction_exception`(异常处理状态核对) - -### 核心字段 - -| 字段 | 说明 | -|------|------| -| tradeNo | 渠道交易流水号 | -| tradeStatus | 原交易状态 | -| tradeAmount | 原交易金额 | -| channelCode | 渠道编码 | -| occurredAt | 交易发生时间 | - -### 关键规则 -- `REFUND` / `REVERSE` 必须关联 `tradeNo`。 -- 原交易状态必须满足“可退款/可冲正”业务前提。 -- 原交易校验应同时覆盖交易主状态、回调结果与异常处理状态,不得只校验交易主表存在性。 - -## 实体五:OperationLog(操作留痕) - -### 作用 -记录账务处理前后变化、处理依据与责任归属。 - -### 物理承接 -- `biz_operat_log` -- `biz_operat_log_detail` - -### 核心字段 - -| 字段 | 说明 | -|------|------| -| bizType | 业务类型 | -| bizId | 业务对象 ID | -| operateUser | 操作人 | -| operateTime | 操作时间 | -| remark | 处理说明 | -| beforeValue | 调整前值 | -| afterValue | 调整后值 | -| fieldName | 字段级差异项 | - -### 关键规则 -- 所有 REV-004 一期场景都必须写入主日志。 -- 涉及金额/水量/状态变化时应写入字段级差异明细。 - -## 实体六:AccountingEvidence(处理依据) - -### 作用 -统一描述原账单、原交易、附件、文字说明等处理依据。 - -### 核心字段 - -| 字段 | 说明 | -|------|------| -| evidenceType | 原账单 / 原交易 / 附件 / 说明 | -| sourceRef | 依据引用标识 | -| snapshotRef | 快照引用 | -| attachmentList | 附件集合 | - -### 说明 -该实体是逻辑约束,不要求本阶段新增物理表;由既有对象引用、附件系统与日志共同承接。 - -## 关系总览 - -```text -AccountingRequest --> ChargeAggregate -AccountingRequest --> Transaction (REFUND/REVERSE only) -AccountingRequest --> AccountingEvidence -AccountingRequest --> AccountingResult -AccountingRequest --> OperationLog -ChargeAggregate --> biz_charge_detail (1:N) -OperationLog --> biz_operat_log_detail (1:N) -``` - -## 状态与边界说明 - -- 一期仅保留审批能力位,不定义完整审批状态机。 -- 旧系统精细账务对象如预存退款明细、价差调整明细、分账调整明细等,不作为一期新增实体表;仅保留业务场景、历史只读与日志承接口径。 diff --git a/specs/001-rev004-accounting/plan.md b/specs/001-rev004-accounting/plan.md index 554b9c3..6cd0d06 100644 --- a/specs/001-rev004-accounting/plan.md +++ b/specs/001-rev004-accounting/plan.md @@ -20,7 +20,7 @@ - `docs/design/03_Technical_Design/03_Interface_Design.md` - `docs/design/03_Technical_Design/01_Database_Design.md` **Reference Sources**: -- `docs/guides/REV004_ACCOUNTING_EXECUTION_PLAYBOOK.md` +- `docs/evidence/rev004-accounting/REV004_ACCOUNTING_EXECUTION_PLAYBOOK.md` - `docs/design/00_Management/01_Project_Progress.md` - `docs/design/00_Management/02_Delivery_Standards.md` - `docs/design/00_Management/03_Task_Checklist.md` @@ -99,7 +99,7 @@ docs/design/ └── 04_Appendix/Archive/ .specify/memory/constitution.md -docs/guides/REV004_ACCOUNTING_EXECUTION_PLAYBOOK.md +docs/evidence/rev004-accounting/REV004_ACCOUNTING_EXECUTION_PLAYBOOK.md CLAUDE.md ``` diff --git a/specs/001-rev004-accounting/quickstart.md b/specs/001-rev004-accounting/quickstart.md index fcd5dd6..95a5db3 100644 --- a/specs/001-rev004-accounting/quickstart.md +++ b/specs/001-rev004-accounting/quickstart.md @@ -65,7 +65,7 @@ ### 步骤六:独立验收入口校验 确认审阅者仅通过以下文件即可完成 US3 验收: -- `docs/guides/REV004_ACCOUNTING_EXECUTION_PLAYBOOK.md` +- `docs/evidence/rev004-accounting/REV004_ACCOUNTING_EXECUTION_PLAYBOOK.md` - `docs/design/00_Management/01_Project_Progress.md` - `docs/design/00_Management/03_Task_Checklist.md` @@ -82,7 +82,7 @@ ## 3. 最小校验命令 ```bash -make validate-file FILE=docs/guides/REV004_ACCOUNTING_EXECUTION_PLAYBOOK.md +make validate-file FILE=docs/evidence/rev004-accounting/REV004_ACCOUNTING_EXECUTION_PLAYBOOK.md make validate-file FILE=docs/design/00_Management/01_Project_Progress.md make validate-file FILE=docs/design/00_Management/03_Task_Checklist.md make check-links diff --git a/specs/001-rev004-accounting/spec.md b/specs/001-rev004-accounting/spec.md index c77fcaf..0252351 100644 --- a/specs/001-rev004-accounting/spec.md +++ b/specs/001-rev004-accounting/spec.md @@ -11,7 +11,7 @@ - `docs/design/02_Detailed_Design/12_REV_Detailed.md` - `docs/design/03_Technical_Design/03_Interface_Design.md` - `docs/design/03_Technical_Design/01_Database_Design.md` - - `docs/guides/REV004_ACCOUNTING_EXECUTION_PLAYBOOK.md` + - `docs/evidence/rev004-accounting/REV004_ACCOUNTING_EXECUTION_PLAYBOOK.md` - `docs/design/00_Management/01_Project_Progress.md` - `docs/design/00_Management/03_Task_Checklist.md` - **Primary source of truth**: @@ -21,7 +21,7 @@ - `docs/design/03_Technical_Design/01_Database_Design.md` - `.specify/memory/constitution.md` - **Reference sources**: - - `docs/guides/REV004_ACCOUNTING_EXECUTION_PLAYBOOK.md` + - `docs/evidence/rev004-accounting/REV004_ACCOUNTING_EXECUTION_PLAYBOOK.md` - `docs/design/00_Management/15_Legacy_Migration_Gap_Analysis.md` - `docs/design/04_Appendix/Archive/03_Design_Docs/营业收费管理系统-概要设计说明书20250912.md` - **Scope decision**: In scope。该需求属于既有 `REV-004` 模块范围内的账务处理一期收敛任务,允许在现有正式文档体系内补齐范围、接口、数据口径和执行约束,并输出后续实施计划所需的边界、任务拆解与验收依据;本轮不直接进入 backend 代码修改,不包含超出一期边界的新业务域扩展。 diff --git a/specs/001-rev004-accounting/tasks.md b/specs/001-rev004-accounting/tasks.md index 1af0a3a..f1809b6 100644 --- a/specs/001-rev004-accounting/tasks.md +++ b/specs/001-rev004-accounting/tasks.md @@ -27,7 +27,7 @@ - [X] T001 Read prerequisite governance documents `docs/design/00_Management/01_Project_Progress.md`, `docs/design/00_Management/02_Delivery_Standards.md`, and `docs/design/00_Management/03_Task_Checklist.md` before formal document edits - [X] T002 Confirm target chapters and intended updates in `specs/001-rev004-accounting/spec.md`, `specs/001-rev004-accounting/plan.md`, `docs/design/02_Detailed_Design/12_REV_Detailed.md`, `docs/design/03_Technical_Design/03_Interface_Design.md`, and `docs/design/03_Technical_Design/01_Database_Design.md` - [X] T003 [P] Confirm source-of-truth and allowed references using `.specify/memory/constitution.md`, `docs/design/01_Overview/03_Summary_Design.md`, `docs/design/02_Detailed_Design/12_REV_Detailed.md`, `docs/design/03_Technical_Design/03_Interface_Design.md`, and `docs/design/03_Technical_Design/01_Database_Design.md` -- [X] T004 [P] Confirm scope boundary, exclusions, traceability anchors, and impacted files in `specs/001-rev004-accounting/research.md`, `specs/001-rev004-accounting/contracts/rev004-scenario-matrix.md`, `specs/001-rev004-accounting/contracts/rev004-traceability-matrix.md`, and `docs/guides/REV004_ACCOUNTING_EXECUTION_PLAYBOOK.md` +- [X] T004 [P] Confirm scope boundary, exclusions, traceability anchors, and impacted files in `specs/001-rev004-accounting/research.md`, `specs/001-rev004-accounting/contracts/rev004-scenario-matrix.md`, `specs/001-rev004-accounting/contracts/rev004-traceability-matrix.md`, and `docs/evidence/rev004-accounting/REV004_ACCOUNTING_EXECUTION_PLAYBOOK.md` --- @@ -46,16 +46,16 @@ **Goal**: 在正式详细设计与执行手册中明确 REV-004 一期纳入范围、排除项、共性能力优先顺序与审批边界。 -**Independent Test**: 审阅者仅通过 `docs/design/02_Detailed_Design/12_REV_Detailed.md` 与 `docs/guides/REV004_ACCOUNTING_EXECUTION_PLAYBOOK.md`,即可确认一期纳入场景、排除项、审批边界和“共性能力先统一、场景能力再分批”的组织方式一致。 +**Independent Test**: 审阅者仅通过 `docs/design/02_Detailed_Design/12_REV_Detailed.md` 与 `docs/evidence/rev004-accounting/REV004_ACCOUNTING_EXECUTION_PLAYBOOK.md`,即可确认一期纳入场景、排除项、审批边界和“共性能力先统一、场景能力再分批”的组织方式一致。 ### Implementation for User Story 1 - [X] T009 [US1] Update REV-004 一期范围、排除项、共性能力顺序和审批边界 in `docs/design/02_Detailed_Design/12_REV_Detailed.md` -- [X] T010 [US1] Sync REV-004 执行范围、验收入口和后续实施组织方式 in `docs/guides/REV004_ACCOUNTING_EXECUTION_PLAYBOOK.md` +- [X] T010 [US1] Sync REV-004 执行范围、验收入口和后续实施组织方式 in `docs/evidence/rev004-accounting/REV004_ACCOUNTING_EXECUTION_PLAYBOOK.md` - [X] T011 [P] [US1] Sync REV-004 一期范围摘要 and cross-references in `docs/design/01_Overview/03_Summary_Design.md` - [X] T012 [US1] Update traceability note for scoped scenarios in `specs/001-rev004-accounting/contracts/rev004-traceability-matrix.md` - [X] T013 [US1] Run `make validate-file FILE=docs/design/02_Detailed_Design/12_REV_Detailed.md` and capture result for `docs/design/02_Detailed_Design/12_REV_Detailed.md` -- [X] T014 [US1] Run `make validate-file FILE=docs/guides/REV004_ACCOUNTING_EXECUTION_PLAYBOOK.md` and capture result for `docs/guides/REV004_ACCOUNTING_EXECUTION_PLAYBOOK.md` +- [X] T014 [US1] Run `make validate-file FILE=docs/evidence/rev004-accounting/REV004_ACCOUNTING_EXECUTION_PLAYBOOK.md` and capture result for `docs/evidence/rev004-accounting/REV004_ACCOUNTING_EXECUTION_PLAYBOOK.md` - [X] T015 [US1] Run `make check-links` and capture cross-document link result for US1 file changes - [X] T016 [US1] Update important progress note in `docs/design/00_Management/01_Project_Progress.md` if US1 produces an important formal document change after validation passes - [X] T017 [US1] Update REV-004 scope task status in `docs/design/00_Management/03_Task_Checklist.md` if US1 completes a tracked task or materially changes its closure condition @@ -93,16 +93,16 @@ **Goal**: 在执行手册与管理台账中固化 REV-004 的后续实施顺序、验收入口、最小校验动作与台账更新触发条件。 -**Independent Test**: 审阅者仅通过 `docs/guides/REV004_ACCOUNTING_EXECUTION_PLAYBOOK.md`、`docs/design/00_Management/01_Project_Progress.md` 与 `docs/design/00_Management/03_Task_Checklist.md`,即可确认 REV-004 后续 tasks 的拆解依据、验收入口、最小校验动作和台账同步方式已经明确。 +**Independent Test**: 审阅者仅通过 `docs/evidence/rev004-accounting/REV004_ACCOUNTING_EXECUTION_PLAYBOOK.md`、`docs/design/00_Management/01_Project_Progress.md` 与 `docs/design/00_Management/03_Task_Checklist.md`,即可确认 REV-004 后续 tasks 的拆解依据、验收入口、最小校验动作和台账同步方式已经明确。 ### Implementation for User Story 3 -- [X] T030 [US3] Update REV-004 execution sequence, independent acceptance entry, and validation steps in `docs/guides/REV004_ACCOUNTING_EXECUTION_PLAYBOOK.md` +- [X] T030 [US3] Update REV-004 execution sequence, independent acceptance entry, and validation steps in `docs/evidence/rev004-accounting/REV004_ACCOUNTING_EXECUTION_PLAYBOOK.md` - [X] T031 [US3] Record REV-004 planning milestone and next-step entry in `docs/design/00_Management/01_Project_Progress.md` if US3 forms an important governance or formal delivery milestone - [X] T032 [US3] Update REV-004 tracked checklist items and completion criteria in `docs/design/00_Management/03_Task_Checklist.md` if US3 completes or materially redefines a tracked task - [X] T033 [P] [US3] Sync quick review and validation wording in `specs/001-rev004-accounting/quickstart.md` - [X] T034 [P] [US3] Sync task-splitting and closure assumptions in `specs/001-rev004-accounting/plan.md` -- [X] T035 [US3] Run `make validate-file FILE=docs/guides/REV004_ACCOUNTING_EXECUTION_PLAYBOOK.md` and capture result for execution playbook changes +- [X] T035 [US3] Run `make validate-file FILE=docs/evidence/rev004-accounting/REV004_ACCOUNTING_EXECUTION_PLAYBOOK.md` and capture result for execution playbook changes - [X] T036 [US3] Run `make validate-file FILE=docs/design/00_Management/01_Project_Progress.md` and capture result for project progress changes - [X] T037 [US3] Run `make validate-file FILE=docs/design/00_Management/03_Task_Checklist.md` and capture result for task checklist changes - [X] T038 [US3] Run `make check-links` and capture cross-document link result for US3 file changes @@ -115,7 +115,7 @@ **Purpose**: Ensure repository-wide consistency after all story slices are complete. -- [X] T039 [P] Re-check source-of-truth alignment across `docs/design/02_Detailed_Design/12_REV_Detailed.md`, `docs/design/03_Technical_Design/03_Interface_Design.md`, `docs/design/03_Technical_Design/01_Database_Design.md`, and `docs/guides/REV004_ACCOUNTING_EXECUTION_PLAYBOOK.md` +- [X] T039 [P] Re-check source-of-truth alignment across `docs/design/02_Detailed_Design/12_REV_Detailed.md`, `docs/design/03_Technical_Design/03_Interface_Design.md`, `docs/design/03_Technical_Design/01_Database_Design.md`, and `docs/evidence/rev004-accounting/REV004_ACCOUNTING_EXECUTION_PLAYBOOK.md` - [X] T040 [P] Re-check relative links, traceability rows, and Mermaid consistency across `docs/design/01_Overview/03_Summary_Design.md`, `docs/design/00_Management/01_Project_Progress.md`, `docs/design/00_Management/03_Task_Checklist.md`, and `specs/001-rev004-accounting/contracts/rev004-traceability-matrix.md` - [X] T041 Prepare final change summary with modified files, validation results, remaining risks, and next-step suggestions in the final response for `/specs/001-rev004-accounting/tasks.md` @@ -160,7 +160,7 @@ ```text # After T009 completes, run in parallel: -- T010 Update docs/guides/REV004_ACCOUNTING_EXECUTION_PLAYBOOK.md +- T010 Update docs/evidence/rev004-accounting/REV004_ACCOUNTING_EXECUTION_PLAYBOOK.md - T011 Update docs/design/01_Overview/03_Summary_Design.md ``` @@ -186,7 +186,7 @@ ### MVP First (User Story 1 only) -先完成 US1,把 REV-004 一期范围、排除项、审批边界和共性能力顺序稳定下来。只要 `docs/design/02_Detailed_Design/12_REV_Detailed.md` 与 `docs/guides/REV004_ACCOUNTING_EXECUTION_PLAYBOOK.md` 已可独立评审并完成最小校验,就可以形成第一版可评审增量。 +先完成 US1,把 REV-004 一期范围、排除项、审批边界和共性能力顺序稳定下来。只要 `docs/design/02_Detailed_Design/12_REV_Detailed.md` 与 `docs/evidence/rev004-accounting/REV004_ACCOUNTING_EXECUTION_PLAYBOOK.md` 已可独立评审并完成最小校验,就可以形成第一版可评审增量。 ### Incremental Delivery diff --git a/specs/002-rev005-invoice-flow/contracts/if-rev-008-invoice-application.md b/specs/002-rev005-invoice-flow/contracts/if-rev-008-invoice-application.md deleted file mode 100644 index 959e366..0000000 --- a/specs/002-rev005-invoice-flow/contracts/if-rev-008-invoice-application.md +++ /dev/null @@ -1,68 +0,0 @@ -# Contract: IF-REV-008 发票申请接口 - -## 1. 合同定位 - -本合同用于固化 REV-005 一期后台发票申请 / 单笔与批量开票接口口径,服务于后续正式接口文档修订、任务拆解与 backend 实施。 - -## 2. 适用范围 - -适用场景: -- 后台营业收费员 / 财务人员发起单笔开票 -- 后台按已收费账单集合批量发起开票 -- 生成发票申请记录并提交 `SYS-008` - -不适用范围: -- 客户侧直接申请开票 -- 原始单账单直接任意部分金额开票 -- 复杂拆分/合并开票策略配置 - -## 3. 请求合同 - -| 字段 | 类型 | 必填 | 说明 | 约束 | -|------|------|------|------|------| -| applicationNo | String | 否 | 发票申请单号 | 服务端生成,作为幂等主键之一 | -| chargeIds | Array | 是 | 关联账单 ID 列表 | 所有账单必须已收费且未开票 | -| custId | Long | 是 | 客户 ID | 必须存在可用开票信息 | -| invoiceType | String | 是 | 发票类型 | `ELECTRONIC` / `PAPER` | -| invoiceTitle | String | 是 | 发票抬头 | 来自 `biz_cust_invoice` 或后台确认输入 | -| taxNo | String | 否 | 纳税人识别号 | 企业抬头场景建议必填 | -| email | String | 否 | 接收邮箱 | 电子发票场景优先使用 | -| mobile | String | 否 | 接收手机号 | 推送或通知场景使用 | -| sourceChannel | String | 是 | 来源渠道 | `COUNTER` / `FINANCE_BACKOFFICE` | -| remark | String | 否 | 申请备注 | 进入操作留痕 | - -## 4. 响应合同 - -| 字段 | 类型 | 说明 | 约束 | -|------|------|------|------| -| invoiceId | Long | 发票申请记录 ID | 对应 `biz_invoice.id` | -| applicationNo | String | 发票申请单号 | 后续查询与幂等主键 | -| invoiceStatus | String | 当前状态 | `SUBMITTED` / `PENDING` / `REJECTED` | -| sysRequestNo | String | `SYS-008` 受理号 | 异步查询主键 | -| msg | String | 处理说明 | 不可开票时返回明确原因 | - -## 5. 共性规则 - -1. 所有账单必须处于“已收费、未开票、未作废”状态。 -2. 一期不支持对原始单账单直接任意部分金额开票。 -3. 如需多张发票,需来源于拆账/分账后的账单集合。 -4. 幂等控制可采用 `applicationNo` 或 `custId + chargeIds` 组合。 -5. 申请成功后必须生成查询补偿任务,不可依赖回调作为唯一结果来源。 -6. 所有申请动作必须写入操作留痕。 - -## 6. 物理承接口径 - -| 逻辑对象 | 物理承接 | -|---------|----------| -| 发票申请主对象 | `biz_invoice` | -| 客户开票信息 | `biz_cust_invoice` | -| 税率配置 | `biz_invoice_taxrate` | -| 关联账单 | `biz_charge*` | -| 操作留痕 | `biz_operat_log*` | - -## 7. 验收关注点 - -- 是否支持后台单笔 / 批量已收费账单开票 -- 是否拒绝原始单账单直接部分金额开票 -- 是否生成申请单号与查询主键 -- 是否与 `SYS-008` 查询兜底模式一致 diff --git a/specs/002-rev005-invoice-flow/contracts/if-rev-009-invoice-query.md b/specs/002-rev005-invoice-flow/contracts/if-rev-009-invoice-query.md deleted file mode 100644 index 5799041..0000000 --- a/specs/002-rev005-invoice-flow/contracts/if-rev-009-invoice-query.md +++ /dev/null @@ -1,65 +0,0 @@ -# Contract: IF-REV-009 发票结果查询与客户侧消费接口 - -## 1. 合同定位 - -本合同用于固化 REV-005 一期发票结果查询、查询兜底补偿以及客户侧查看/下载/推送已开票电子发票的统一口径。 - -## 2. 适用范围 - -适用场景: -- 后台按申请单号 / 受理号查询发票最终状态 -- 系统定时轮询 `SYS-008` 获取开票结果 -- 客户侧查看已开具电子发票 -- 客户侧下载、推送电子发票 - -不适用范围: -- 客户侧直接发起开票申请 -- 发票作废 / 红冲全流程深度处理 - -## 3. 查询请求合同 - -| 字段 | 类型 | 必填 | 说明 | 约束 | -|------|------|------|------|------| -| applicationNo | String | 否 | 发票申请单号 | 与 `sysRequestNo` 二选一 | -| sysRequestNo | String | 否 | 外部受理号 | 与 `applicationNo` 二选一 | -| custId | Long | 否 | 客户 ID | 客户侧查询时使用 | -| querySource | String | 是 | 查询来源 | `SYSTEM_JOB` / `ADMIN` / `CUSTOMER` | -| pushEmail | String | 否 | 推送邮箱 | 客户侧推送时使用 | - -## 4. 查询响应合同 - -| 字段 | 类型 | 说明 | 约束 | -|------|------|------|------| -| invoiceId | Long | 发票记录 ID | 对应 `biz_invoice.id` | -| applicationNo | String | 发票申请单号 | 幂等主键 | -| invoiceStatus | String | 发票状态 | `PENDING` / `SUCCESS` / `FAIL` / `INVALID` / `RED_INK` | -| invoiceCode | String | 发票代码 | 成功后返回 | -| invoiceNumber | String | 发票号码 | 成功后返回 | -| fileUrl | String | 电子票下载地址 | 成功后返回 | -| failReason | String | 失败原因 | 失败时返回 | -| pushStatus | String | 推送状态 | `NONE` / `PUSHED` / `FAIL` | -| lastQueryTime | DateTime | 最近查询时间 | 用于补偿追踪 | - -## 5. 共性规则 - -1. 查询兜底是开票结果获取的必备路径,不可省略。 -2. 已成功开票状态不得被后续失败结果覆盖。 -3. 客户侧只允许查询、下载、推送属于当前客户的已开票电子发票。 -4. 下载/推送前必须校验发票状态为 `SUCCESS` 且存在 `fileUrl`。 -5. 查询补偿任务需记录 `lastTryTime`、`nextTryTime`、`tryCount` 等信息。 - -## 6. 物理承接口径 - -| 逻辑对象 | 物理承接 | -|---------|----------| -| 发票结果主对象 | `biz_invoice` | -| 客户查询身份与资料 | `biz_cust_invoice` | -| 查询补偿与结果留痕 | `biz_invoice` 扩展字段 + `biz_operat_log*` | -| 账单发票摘要展示 | `biz_charge*` + 历史关系快照 | - -## 7. 验收关注点 - -- 是否支持后台按申请单号 / 受理号查询结果 -- 是否支持系统任务轮询补偿 -- 是否支持客户侧查看、下载、推送已开票电子发票 -- 是否避免客户侧越权查询和重复推送 diff --git a/specs/002-rev005-invoice-flow/data-model.md b/specs/002-rev005-invoice-flow/data-model.md deleted file mode 100644 index 1deb4f3..0000000 --- a/specs/002-rev005-invoice-flow/data-model.md +++ /dev/null @@ -1,170 +0,0 @@ -# Data Model: REV-005 发票业务流实现 - -## 建模原则 - -- 以“逻辑实体 + 现有在线主表承接 + 历史关系快照”三层表达,避免把旧系统全部 IV_* 细表误写为当前已落地在线表。 -- 后台开票、客户侧查询下载、`SYS-008` 查询兜底、结果回写统一围绕单一发票申请主线建模。 -- 一期不支持原始单账单直接任意部分开票,但关系模型需兼容拆账/分账后的多账单、多发票映射扩展。 - -## 实体一:InvoiceApplication(发票申请单) - -### 作用 -统一承接后台单笔/批量已收费账单的发票申请输入,是 `IF-REV-008` 的主业务对象。 - -### 核心字段 - -| 字段 | 类型 | 说明 | -|------|------|------| -| applicationNo | String | 发票申请单号 / 协同请求号 | -| chargeIds | Array | 关联账单 ID 列表 | -| custId | Long | 客户 ID | -| invoiceType | Enum | `ELECTRONIC` / `PAPER` | -| invoiceTitle | String | 发票抬头 | -| taxNo | String | 纳税人识别号 | -| invoiceAmount | Decimal | 本次申请开票总金额 | -| receiverEmail | String | 电子票接收邮箱 | -| receiverMobile | String | 电子票接收手机号 | -| sourceChannel | Enum | `COUNTER` / `FINANCE_BACKOFFICE` | -| applyStatus | Enum | `SUBMITTED` / `ACCEPTED` / `REJECTED` | -| appliedAt | DateTime | 申请时间 | - -### 校验规则 -- `chargeIds`、`custId`、`invoiceType`、`invoiceTitle` 必填。 -- 账单必须满足“已收费、未开票、未作废”。 -- 原始单账单不允许直接任意部分金额开票;如需多张发票应来源于拆账/分账后的账单集合。 -- 对同一账单组合的重复申请需按 `applicationNo` 或 `custId + chargeIds` 做幂等控制。 - -### 物理承接 -- 主承接:`biz_invoice` -- 关联输入:`biz_cust_invoice`、`biz_charge*` - -## 实体二:InvoiceRecord(发票记录) - -### 作用 -描述发票服务受理、开具成功/失败、票号回写、电子票文件地址等结果信息。 - -### 核心字段 - -| 字段 | 类型 | 说明 | -|------|------|------| -| invoiceId | Long | 发票记录 ID | -| applicationNo | String | 对应申请单号 | -| sysRequestNo | String | `SYS-008` 受理号 / 外部请求号 | -| invoiceStatus | Enum | `PENDING` / `SUCCESS` / `FAIL` / `INVALID` / `RED_INK` | -| invoiceCode | String | 发票代码 | -| invoiceNumber | String | 发票号码 | -| invoiceDate | DateTime | 开票日期 | -| fileUrl | String | 电子发票下载地址 | -| failReason | String | 开票失败原因 | -| pushStatus | Enum | `NONE` / `PUSHED` / `FAIL` | -| updatedAt | DateTime | 最近状态更新时间 | - -### 状态关系 -- `PENDING` 表示已提交给 `SYS-008` 但尚未确认最终结果。 -- `SUCCESS` 后允许客户侧查询、下载、推送电子发票。 -- `FAIL` 记录失败原因并进入异常核查或人工重试。 - -### 物理承接 -- 主承接:`biz_invoice` -- 历史参照:旧 `IV_INVOICE_INFOS` - -## 实体三:ChargeInvoiceRelation(账单-发票关联) - -### 作用 -承接账单与发票的映射关系,支持单票对应多账单、拆账后分别开票和后续合并开票扩展。 - -### 核心字段 - -| 字段 | 类型 | 说明 | -|------|------|------| -| relationId | Long | 关联记录 ID | -| chargeId | Long | 账单 ID | -| invoiceId | Long | 发票 ID | -| applicationNo | String | 申请单号 | -| relationType | Enum | `FULL_AMOUNT` / `SPLIT_BILL` / `MERGED_BILL` | -| invoiceAmount | Decimal | 当前账单对应开票金额 | -| relationStatus | Enum | `PENDING` / `BOUND` / `FAILED` | -| snapshotVersion | String | 开票配置/税率快照版本 | - -### 关键规则 -- 一期默认 `relationType=FULL_AMOUNT` 或 `SPLIT_BILL`(来自拆账后的账单),不支持对原始单账单直接自由部分金额开票。 -- 发票成功后必须把关系状态更新为 `BOUND`,并可供账单详情查询。 - -### 物理承接 -- 在线主承接:`biz_invoice` + 历史关系快照 -- 历史参照:旧 `IV_CHARGE_INVOICES`、`IV_CHARGE_INVOICE_MAPPINGS` - -## 实体四:InvoiceQueryTask(开票查询补偿任务) - -### 作用 -支持异步申请后的轮询查询、超时补偿和人工兜底查询,是“查询兜底”模式的核心对象。 - -### 核心字段 - -| 字段 | 类型 | 说明 | -|------|------|------| -| queryTaskId | Long | 查询任务 ID | -| applicationNo | String | 申请单号 | -| sysRequestNo | String | 外部受理号 | -| lastTryTime | DateTime | 最后一次查询时间 | -| nextTryTime | DateTime | 下一次查询时间 | -| tryCount | Integer | 已查询次数 | -| queryStatus | Enum | `WAITING` / `RUNNING` / `DONE` / `FAILED` | -| latestResult | String | 最近一次查询结果摘要 | -| latestError | String | 最近一次查询错误 | - -### 关键规则 -- 申请成功后默认生成查询任务。 -- 查询到终态后任务进入 `DONE`。 -- 查询异常不应覆盖已成功开票状态,只记录异常并等待人工或系统补偿。 - -### 物理承接 -- 主承接:`biz_invoice` 扩展字段或关联查询日志对象 -- 历史参照:旧发票表中的 `last_try_time`、`next_try_time`、`try_count` - -## 实体五:InvoiceResultWriteBack(结果回写) - -### 作用 -统一描述 `SYS-008` 查询结果或主动回传结果进入营收域后的状态变更、幂等控制和操作留痕。 - -### 核心字段 - -| 字段 | 类型 | 说明 | -|------|------|------| -| writeBackNo | String | 回写流水号 | -| applicationNo | String | 申请单号 | -| invoiceStatus | Enum | 发票状态 | -| writeBackStatus | Enum | `SUCCESS` / `IGNORE_REPEAT` / `FAIL` | -| invoiceCode | String | 发票代码 | -| invoiceNumber | String | 发票号码 | -| fileUrl | String | 下载地址 | -| rawPayload | String | 原始回写/查询响应 | -| processedAt | DateTime | 处理时间 | -| processedBy | String | 系统任务 / 人工处理人 | - -### 关键规则 -- 按 `applicationNo + invoiceStatus` 做幂等控制。 -- 已成功开票后收到失败结果,不覆盖成功状态,转入异常核查。 -- 所有回写处理必须记录到操作留痕对象。 - -### 物理承接 -- 主承接:`biz_invoice` + `biz_operat_log*` - -## 关系总览 - -```text -InvoiceApplication --> InvoiceRecord -InvoiceApplication --> ChargeInvoiceRelation -InvoiceApplication --> InvoiceQueryTask -InvoiceRecord --> InvoiceResultWriteBack -ChargeInvoiceRelation --> biz_charge* (N:1) -InvoiceApplication --> biz_cust_invoice -InvoiceApplication --> biz_invoice_taxrate -InvoiceResultWriteBack --> biz_operat_log* -``` - -## 状态与边界说明 - -- 一期默认后台申请、客户侧结果消费,不定义客户侧直接申请状态机。 -- 作废、红冲作为 REV-005 后续能力保留在数据模型中,但 implement 时优先保证正常开票闭环。 -- 旧发票明细、营业账开票关系、配置快照对象在当前阶段仅作为历史参照和追溯来源,不表述为已确认新增在线独立表。 diff --git a/specs/002-rev005-invoice-flow/frontend-finance-design.md b/specs/002-rev005-invoice-flow/frontend-finance-design.md new file mode 100644 index 0000000..ebba5bc --- /dev/null +++ b/specs/002-rev005-invoice-flow/frontend-finance-design.md @@ -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`,应分别建立独立设计补充,不在本文件中混合扩展。 diff --git a/specs/006-reminder-event-design/contracts/if-ext-008.md b/specs/003-rev006-reminder-event-design/contracts/if-ext-008.md similarity index 100% rename from specs/006-reminder-event-design/contracts/if-ext-008.md rename to specs/003-rev006-reminder-event-design/contracts/if-ext-008.md diff --git a/specs/006-reminder-event-design/contracts/if-rev-013.md b/specs/003-rev006-reminder-event-design/contracts/if-rev-013.md similarity index 100% rename from specs/006-reminder-event-design/contracts/if-rev-013.md rename to specs/003-rev006-reminder-event-design/contracts/if-rev-013.md diff --git a/specs/003-rev006-reminder-event-design/data-model.md b/specs/003-rev006-reminder-event-design/data-model.md index 17c4cf1..dd1012d 100644 --- a/specs/003-rev006-reminder-event-design/data-model.md +++ b/specs/003-rev006-reminder-event-design/data-model.md @@ -1,159 +1,125 @@ -# Data Model: REV-006 催缴事件与通知协同设计 +# Data Model: REV-006 催缴与通知事件设计收口 ## 1. Reminder Candidate -### Purpose +**说明**: 催缴任务的输入对象,由欠费账单和客户上下文组合形成。 -表示进入催缴评估范围的欠费账单或客户对象集合,是催缴任务生成的输入对象。 +| 字段 | 类型 | 说明 | 约束 | +|------|------|------|------| +| candidateId | String | 候选对象标识 | 可由任务生成阶段派生,不要求独立持久化主键 | +| custId | String | 客户标识 | 必填 | +| accountId | String | 账户标识 | 必填 | +| chargeIds | List | 命中的欠费账单集合 | 至少 1 条 | +| billPeriods | List | 账期集合 | 必填 | +| arrearsAmount | Decimal | 欠费总金额 | 必须大于 0 | +| agingBucket | String | 账龄分组 | 必填 | +| custCategory | String | 客户类别 | 必填 | +| preferredChannels | List | 渠道偏好 | 至少 1 个渠道 | +| strategyCode | String | 命中的催缴策略编码 | 必填 | +| frequencyWindow | String | 频控窗口 | 用于重复触达拦截 | -### Key Fields +**关系**: -| Field | Description | Rule | -|---|---|---| -| `custId` | 客户标识 | 必填;关联客户主档 | -| `chargeId` | 账单标识 | 必填;关联欠费账单 | -| `billPeriod` | 账期 | 必填;用于催缴分组和历史查询 | -| `arrearsAmount` | 欠费金额 | 必填;用于策略匹配 | -| `agingBucket` | 欠费账龄分组 | 必填;用于策略筛选 | -| `customerCategory` | 客户类别 | 必填;用于差异化催缴 | -| `contactChannelSet` | 可用联系方式集合 | 至少存在一个有效触达渠道 | -| `strategyCode` | 命中的催缴策略编码 | 必填;来源于策略规则 | - -### Relationships - -- 来自 `biz_charge` / `biz_charge_detail` -- 关联客户主档与联系方式 -- 可生成一个或多个 `Reminder Task` +- 一个 `Reminder Candidate` 可生成一个或多个 `Reminder Task` +- `Reminder Candidate` 来源于 `biz_charge`、`biz_charge_detail` 等营业账对象 ## 2. Reminder Strategy -### Purpose +**说明**: 约束候选对象筛选、任务分组和渠道优先级的规则集合。 -定义催缴对象筛选、任务分组、触达渠道和频控约束的业务规则。 +| 字段 | 类型 | 说明 | 约束 | +|------|------|------|------| +| strategyCode | String | 策略编码 | 唯一 | +| strategyName | String | 策略名称 | 必填 | +| agingRule | String | 账龄规则 | 必填 | +| amountRule | String | 金额规则 | 必填 | +| custCategoryRule | String | 客户类别规则 | 可为空,表示不限 | +| channelPriority | List | 渠道优先级 | 至少 1 项 | +| frequencyControl | String | 频控规则 | 必填 | +| disposalAttentionFlag | Boolean | 是否关注后续处置 | 必填 | -### Key Fields +**状态转换**: -| Field | Description | Rule | -|---|---|---| -| `strategyCode` | 策略编码 | 唯一 | -| `agingRule` | 账龄匹配规则 | 必填 | -| `amountRule` | 金额匹配规则 | 必填 | -| `customerCategoryRule` | 客户类别匹配规则 | 可为空;为空表示通用 | -| `channelPriority` | 触达渠道优先级 | 必填;至少 1 个渠道 | -| `dedupeWindow` | 重复触达拦截窗口 | 必填 | -| `escalationFlag` | 是否触发后续处置关注 | 必填 | - -### Relationships - -- 一个 `Reminder Strategy` 可匹配多个 `Reminder Candidate` -- 一个 `Reminder Strategy` 可驱动多个 `Reminder Task` +- 启用 +- 停用 ## 3. Reminder Task -### Purpose +**说明**: 正式催缴执行单元,是 `IF-REV-013` 的核心业务对象。 -表示一次正式催缴执行单元,负责承接业务触发、协同下发和结果回写。 +| 字段 | 类型 | 说明 | 约束 | +|------|------|------|------| +| taskNo | String | 催缴任务号 | 唯一、必填 | +| eventNo | String | 业务事件号 | 唯一、必填 | +| strategyCode | String | 策略编码 | 必填 | +| channelType | String | 执行渠道 | 必填 | +| triggerType | String | 触发类型 | 自动 / 人工 | +| status | String | 当前状态 | 仅允许 `PENDING` / `SUCCESS` / `FAIL` / `MANUAL_VERIFIED` | +| chargeIds | List | 关联账单 | 至少 1 条 | +| receiver | String | 触达对象 | 可为手机号、微信标识或站内账号 | +| sendTime | Datetime | 发送发起时间 | 可空,待触发后填写 | +| lastCallbackTime | Datetime | 最近结果回写时间 | 可空 | +| failReason | String | 失败原因 | `FAIL` 时建议记录 | +| manualVerifyNote | String | 人工核查说明 | `MANUAL_VERIFIED` 时建议记录 | -### Key Fields +**状态转换**: -| Field | Description | Rule | -|---|---|---| -| `taskNo` | 催缴任务号 | 唯一;正式业务主键 | -| `interfaceCode` | 正式接口编号 | 固定使用 `IF-REV-013` | -| `eventNo` | 业务事件号 | 唯一;用于与 `SYS-010` 协同 | -| `custId` | 客户标识 | 必填 | -| `chargeId` | 账单标识 | 必填 | -| `strategyCode` | 策略编码 | 必填 | -| `channelType` | 触达渠道 | 必填;短信/微信公众号/站内信等 | -| `triggerType` | 触发方式 | 必填;自动/人工 | -| `status` | 当前任务状态 | 必填;`PENDING` / `SUCCESS` / `FAIL` / `MANUAL_VERIFIED` | -| `sourceType` | 任务来源 | 必填;系统任务/人工补发/核查回补 | -| `createdTime` | 创建时间 | 必填 | -| `lastResultTime` | 最近结果时间 | 可为空;初次发送前为空 | - -### State Transitions - -| From | To | Condition | -|---|---|---| -| 新建 | `PENDING` | 已生成任务并发起协同 | -| `PENDING` | `SUCCESS` | 收到成功回写 | -| `PENDING` | `FAIL` | 收到失败回写或确认失败 | -| `PENDING` | `MANUAL_VERIFIED` | 人工核查后确认结果 | -| `FAIL` | `MANUAL_VERIFIED` | 人工核查补记结果 | - -### Relationships - -- 由一个 `Reminder Candidate` 和一个 `Reminder Strategy` 组合产生 -- 关联一个或多个 `Reminder Result` -- 可关联一个 `Disposal Link` +1. 新建任务后进入 `PENDING` +2. 外部触达成功后进入 `SUCCESS` +3. 外部明确失败后进入 `FAIL` +4. 外部结果长期未定或人工补记后进入 `MANUAL_VERIFIED` ## 4. Reminder Result -### Purpose +**说明**: 承接 `SYS-010` 回写结果与业务侧最终状态语义。 -表示 `SYS-010` 回传或人工核查得到的触达结果。 +| 字段 | 类型 | 说明 | 约束 | +|------|------|------|------| +| taskNo | String | 对应任务号 | 必填 | +| eventNo | String | 对应事件号 | 必填 | +| status | String | 四态结果 | 必填 | +| channelType | String | 渠道类型 | 必填 | +| externalResultCode | String | 外部结果码 | 可空 | +| externalResultMessage | String | 外部结果说明 | 可空 | +| failReason | String | 业务失败原因 | `FAIL` 时可必填 | +| callbackTime | Datetime | 回写时间 | 必填 | +| sourceSystem | String | 回写来源系统 | 默认 `SYS-010` | -### Key Fields +## 5. Disposal Link -| Field | Description | Rule | -|---|---|---| -| `eventNo` | 业务事件号 | 必填;与 `Reminder Task` 对应 | -| `status` | 结果状态 | 必填;仅允许四态 | -| `failureReason` | 失败原因 | `FAIL` 时必填 | -| `resultChannel` | 实际触达渠道 | 必填 | -| `resultTime` | 结果时间 | 必填 | -| `verifiedBy` | 核查人 | `MANUAL_VERIFIED` 时必填 | -| `verifiedNote` | 核查说明 | `MANUAL_VERIFIED` 时建议填写 | +**说明**: 催缴任务与停水、复水、工单、人工跟进之间的追溯引用。 -### Relationships +| 字段 | 类型 | 说明 | 约束 | +|------|------|------|------| +| taskNo | String | 关联催缴任务号 | 必填 | +| disposalType | String | 处置类型 | 停水 / 复水 / 工单 / 人工跟进 | +| disposalRefNo | String | 处置引用号 | 必填 | +| disposalStatus | String | 处置状态摘要 | 可空 | +| linkedAt | Datetime | 建联时间 | 必填 | +| note | String | 追溯说明 | 可空 | -- 归属于一个 `Reminder Task` -- 结果会回写到任务状态与历史查询记录 +## 6. Governance Record -## 5. Reminder History Record +**说明**: 用于治理台账登记本轮设计收口结论与后续研发建议。 -### Purpose +| 字段 | 类型 | 说明 | 约束 | +|------|------|------|------| +| reqCode | String | 需求编号 | 固定为 `SYS002-REQ-011` | +| featureName | String | Speckit feature 名称 | 固定为 `rev003-rev006-reminder-event-design` | +| implementationStatus | String | 当前实现判断 | `未见实现` | +| docStatus | String | 文档状态 | 设计已收口 / 待同步 / 待验证 | +| nextAction | String | 后续动作 | 研发立项 / 文档补证 / 治理同步 | +| evidenceRefs | List | 证据来源 | 必填 | -为历史查询和迁移验收提供最小保留信息集合。 +## 7. 关系总览 -### Key Fields - -| Field | Description | Rule | -|---|---|---| -| `custId` | 客户标识 | 必填 | -| `billPeriod` | 账期 | 必填 | -| `channelType` | 催缴方式 | 必填 | -| `messageContentRef` | 触达内容引用 | 必填;可为模板或摘要引用 | -| `receiver` | 接收目标 | 必填;手机号/OpenID/站内信对象 | -| `status` | 执行结果 | 必填;使用四态或历史映射值 | -| `sendTime` | 发送时间 | 必填 | -| `operatorSource` | 操作来源 | 必填;自动/人工/历史迁移 | -| `relatedChargeId` | 关联账单 | 必填 | -| `relatedDisposalRef` | 关联处置引用 | 可为空;用于停复水/工单追溯 | - -### Relationships - -- 可由 `Reminder Task` 和 `Reminder Result` 聚合生成 -- 同时承接历史催缴记录、停水记录、预存短信记录的查询口径 - -## 6. Disposal Link - -### Purpose - -记录催缴结果与停水、复水、工单或人工处置之间的追溯关系。 - -### Key Fields - -| Field | Description | Rule | -|---|---|---| -| `eventNo` | 关联业务事件号 | 必填 | -| `disposalType` | 处置类型 | 必填;停水/复水/工单/人工跟进 | -| `triggerCondition` | 触发条件摘要 | 必填 | -| `disposalRefNo` | 下游处置引用号 | 可为空;未创建时为空 | -| `disposalStatus` | 下游处置状态 | 可为空;仅作追溯,不定义内部流程 | -| `linkedTime` | 建立关联时间 | 必填 | - -### Relationships - -- 一个 `Reminder Task` 最多关联一个当前生效的 `Disposal Link` -- 不替代下游业务对象,只做引用和追溯 +```text +Reminder Strategy + -> Reminder Candidate + -> Reminder Task +Reminder Task + -> Reminder Result + -> Disposal Link +Governance Record + -> 引用 Reminder Task / Reminder Result 的设计结论与实现判断 +``` diff --git a/specs/003-rev006-reminder-event-design/plan.md b/specs/003-rev006-reminder-event-design/plan.md index f2436fb..afe6eb5 100644 --- a/specs/003-rev006-reminder-event-design/plan.md +++ b/specs/003-rev006-reminder-event-design/plan.md @@ -1,109 +1,108 @@ -# Implementation Plan: REV-006 催缴事件与通知协同设计 +# Plan: REV-006 催缴与通知事件设计收口 -**Branch**: `003-rev006-reminder-event-design` | **Date**: 2026-03-18 | **Spec**: [/Volumes/Dpan/github/fujian_water_biz_doc/specs/003-rev006-reminder-event-design/spec.md](/Volumes/Dpan/github/fujian_water_biz_doc/specs/003-rev006-reminder-event-design/spec.md) -**Input**: Feature specification from `/specs/003-rev006-reminder-event-design/spec.md` - -**Note**: This template is filled in by the `/speckit.plan` command. See `.specify/templates/plan-template.md` for the execution workflow. +**Branch**: `003-rev003-rev006-reminder-event-design` | **Date**: 2026-03-19 | **Spec**: [spec.md](./spec.md) +**Input**: Feature specification from `/specs/003-rev003-rev006-reminder-event-design/spec.md`(合并自 `003` 与 `006` 双会话) ## Summary -本 feature 用于补齐 `REV-006` 在正式文档体系中的设计闭环,重点收口催缴对象生成、催缴任务触发、`SYS-010` 消息协同结果回写、停复水联动边界以及历史查询最小保留集。实施方式以修订既有主文档和治理台账为主,不进入 backend 代码实现;同时将现有接口冲突纠正为 `REV-006` 使用新的独立正式接口编号,发票查询继续保留 `IF-REV-009`。 +本计划将 `REV-006` 催缴与通知事件的正式设计收口拆分为 4 个可验证的阶段:详细设计主文档对齐、接口与协同边界文档化、治理同步和实现切入点评估。每个阶段完成后需通过独立的文档校验和台账回写。 -## Technical Context +## Technical Approach - - -**Primary Work Product**: Markdown 设计文档、接口/数据库专题文档、管理台账文档 -**Source of Truth Documents**: - - `/Volumes/Dpan/github/fujian_water_biz_doc/docs/design/02_Detailed_Design/12_REV_Detailed.md` - - `/Volumes/Dpan/github/fujian_water_biz_doc/docs/design/03_Technical_Design/03_Interface_Design.md` - - `/Volumes/Dpan/github/fujian_water_biz_doc/docs/design/03_Technical_Design/01_Database_Design.md` - - `/Volumes/Dpan/github/fujian_water_biz_doc/docs/design/00_Management/04_Writing_Guide.md` - - `/Volumes/Dpan/github/fujian_water_biz_doc/AGENTS.md` -**Reference Sources**: - - `/Volumes/Dpan/github/fujian_water_biz_doc/docs/design/00_Management/15_SYS002_Requirement_Breakdown.md` - - `/Volumes/Dpan/github/fujian_water_biz_doc/docs/guides/BACKEND_CURRENT_STATUS.md` - - `/Volumes/Dpan/github/fujian_water_biz_doc/docs/guides/BACKEND_TABLE_MAPPING.md` - - `/Volumes/Dpan/github/fujian_water_biz_doc/docs/design/04_Appendix/Archive/05_Data_Dictionary/营收数据字典.md` - - `/Volumes/Dpan/github/fujian_water_biz_doc/docs/design/04_Appendix/Archive/01_Requirements/` -**Validation Commands**: - - `make validate-file FILE=docs/design/02_Detailed_Design/12_REV_Detailed.md` - - `make validate-file FILE=docs/design/03_Technical_Design/03_Interface_Design.md` - - `make validate-file FILE=docs/design/03_Technical_Design/01_Database_Design.md` - - `make validate-file FILE=docs/design/00_Management/15_SYS002_Requirement_Breakdown.md` - - `make validate-file FILE=docs/design/00_Management/01_Project_Progress.md` - - `make validate-file FILE=docs/design/00_Management/03_Task_Checklist.md` - - `make check-links` -**Target Scope**: - - `12_REV_Detailed.md` 中 `REV-006` 正文、流程、规则、落地边界 - - `03_Interface_Design.md` 中 `REV-006` 与 `SYS-010` 的接口编号、接口定义、时序、映射表、异常码、幂等策略 - - `01_Database_Design.md` 中催缴/停复水/预存短信历史只读口径与在线主模型承接边界 - - `15_SYS002_Requirement_Breakdown.md` 中实现评估和 Story/Task 建议 - - `01_Project_Progress.md`、`03_Task_Checklist.md` 的治理回写 -**Project Type**: 文档治理仓库 -**Constraints**: - - 不新增平行正式主稿,所有正式内容回写既有主文档 - - 不臆造 backend 已实现事实,只能写“已实现 / 部分实现 / 文档先行 / 历史只读” - - 仓库内引用保持相对路径 - - 停复水只定义联动边界,不展开内部处置流程 - - `REV-006` 必须使用独立正式接口编号,不再复用 `IF-REV-009` - - 催缴结果状态固定为 `PENDING`、`SUCCESS`、`FAIL`、`MANUAL_VERIFIED` -**Scale/Scope**: 跨文档专题收口,涉及详细设计、接口设计、数据库设计与治理台账四类文档 +- **Design-first, implementation-later**: 本轮仅收口正式设计文档,不在 backend 中新增业务代码。 +- **Single source of truth**: 所有修订回写到 `docs/design/` 主文档,不创建平行版本。 +- **Contract-driven**: 以 `contracts/if-rev-013.md` 和 `contracts/if-ext-008.md` 作为接口协同边界契约,驱动正式接口文档修订。 +- **Gated by validation**: 每次文档修订后必须执行 `make validate-file`、`make check-links`、`make validate-mermaid` 中适用的校验命令。 ## Constitution Check -*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.* - -- [x] **主文档归属已确认**:改动落点限定为 `12_REV_Detailed.md`、`03_Interface_Design.md`、`01_Database_Design.md` 与治理台账,不新增平行正式稿。 -- [x] **范围基线已确认**:`REV-006` 已存在于 `03_Summary_Design.md`、`12_REV_Detailed.md` 和 `15_SYS002_Requirement_Breakdown.md`,本轮仅补齐既有范围内的设计与接口口径,不引入超范围新模块。 -- [x] **Archive 使用方式合规**:Archive 仅用于核对旧“催缴记录/停水记录/预存短信”来源与历史只读口径,不直接作为正式结论输出。 -- [x] **一致性影响已列出**:受影响项包括 `REV-006` 接口编号、结果状态术语、催缴/停复水边界、历史只读查询口径、时序图与映射表。 -- [x] **校验与台账动作已规划**:已规划单文件校验、链接校验,并要求同步更新 `01_Project_Progress.md` 与 `03_Task_Checklist.md`。 +- **Single source of truth**: ✅ 只编辑现有主文档(`12_REV_Detailed.md`、`03_Interface_Design.md`),不创建平行版本 +- **Traceability**: ✅ 所有变更可追溯到本 spec 和 governance records +- **Validation required**: ✅ 每个阶段包含明确的验证任务 ## Project Structure ### Documentation (this feature) ```text -specs/[###-feature]/ -├── plan.md # This file (/speckit.plan command output) -├── research.md # Phase 0 output (/speckit.plan command) -├── data-model.md # Optional: document entities/traceability objects -├── quickstart.md # Optional: validation or review quickstart -├── contracts/ # Optional: interface or section-level artifacts -└── tasks.md # Phase 2 output (/speckit.tasks command) +specs/003-rev003-rev006-reminder-event-design/ +├── spec.md # 功能规格(合并自 003 与 006) +├── plan.md # 本文件 +├── research.md # 调研与现有基线评估 +├── data-model.md # REV-006 涉及的实体与字段分析 +├── quickstart.md # 快速开始指南 +├── tasks.md # 任务拆解 +├── contracts/ +│ ├── rev006-interface-contract.md # REV-006 接口契约(来自原 003) +│ ├── if-rev-013.md # IF-REV-013 正式接口契约(来自原 006) +│ └── if-ext-008.md # IF-EXT-008 外部协同契约(来自原 006) +└── checklists/ + └── requirements.md # 需求审查清单 ``` -### Repository Touchpoints +### Source of Truth (upstream/downstream) ```text docs/design/ -├── 00_Management/ -├── 01_Overview/ -├── 02_Detailed_Design/ -├── 03_Technical_Design/ -└── 04_Appendix/Archive/ - -README.md -AGENTS.md -.specify/templates/ +├── 02_Detailed_Design/12_REV_Detailed.md # REV 模块详细设计(本 feature 的主要编辑目标) +├── 03_Technical_Design/03_Interface_Design.md # 接口设计(IF-REV-013、IF-EXT-008 的正式落点) +└── 00_Management/ + ├── 01_Project_Progress.md # 项目进度同步 + ├── 03_Task_Checklist.md # 任务清单同步 + └── 15_SYS002_Requirement_Breakdown.md # 需求拆解同步 ``` -**Structure Decision**: - - 更新 `docs/design/02_Detailed_Design/12_REV_Detailed.md`:补齐 `REV-006` 详细设计正文与落地边界。 - - 更新 `docs/design/03_Technical_Design/03_Interface_Design.md`:修正接口编号冲突,补齐 `REV-006` 正式接口、协同时序、异常码和幂等策略。 - - 更新 `docs/design/03_Technical_Design/01_Database_Design.md`:明确在线承接与历史只读查询口径,不把旧菜单机械映射为新表。 - - 更新 `docs/design/00_Management/15_SYS002_Requirement_Breakdown.md`:同步实现评估、TAPD/Speckit 建议和后续任务入口。 - - 更新 `docs/design/00_Management/01_Project_Progress.md` 与 `docs/design/00_Management/03_Task_Checklist.md`:完成治理闭环。 +## Phase 1: Scope Confirmation -## Complexity Tracking +**Goal**: 确认本 feature 的确切编辑范围、主文档影响面和验证要求。 -> **Fill ONLY if Constitution Check has violations that must be justified** +- 确认 `12_REV_Detailed.md` 的 `REV-006` 章节需要新增/修订的具体小节 +- 确认 `03_Interface_Design.md` 的 `IF-REV-013` 和 `IF-EXT-008` 需要新增/修订的具体内容 +- 确认治理类文档的同步范围(`01_Project_Progress.md`、`03_Task_Checklist.md`、`15_SYS002_Requirement_Breakdown.md`) -| Violation | Why Needed | Simpler Alternative Rejected Because | -|-----------|------------|-------------------------------------| -| 无 | - | - | +## Phase 2: Detailed Design Alignment + +**Goal**: 将 `REV-006` 催缴事件设计的正式描述写入 `12_REV_Detailed.md`。 + +关键内容: +- 催缴对象生成规则(欠费条件、账龄、金额、客户类别、渠道偏好) +- 策略分组与任务生成维度 +- 四态结果语义(`PENDING`、`SUCCESS`、`FAIL`、`MANUAL_VERIFIED`) +- 停复水/工单联动边界(只定义追溯接口,不展开内部流程) +- 历史查询与导出口径 + +## Phase 3: Interface & Contract Documentation + +**Goal**: 将 `IF-REV-013` 和 `IF-EXT-008` 的正式定义写入 `03_Interface_Design.md`。 + +关键内容: +- `IF-REV-013`:任务生成、任务查询、人工核查、结果承接 +- `IF-EXT-008`:外部消息触达协同(`SYS-010` 负责执行,`SYS-002` 保留业务控制) +- 四态回写字段定义 +- 失败原因与处置引用字段 + +## Phase 4: Governance Sync + +**Goal**: 同步治理台账,明确 `REV-006` 的当前结论、最小实现切入点和后续行动。 + +关键动作: +- 更新 `01_Project_Progress.md` 通报本轮收口结论 +- 更新 `03_Task_Checklist.md` 登记本轮文档治理任务完成情况 +- 更新 `15_SYS002_Requirement_Breakdown.md` 中 `SYS002-REQ-011` 的状态为"设计已收口" + +## Phase 5: Implementation Entry-Point Assessment + +**Goal**: 为后续研发立项提供最小实现切入点评估,不直接实现。 + +关键输出: +- 识别 backend 中是否存在 `Reminder/Message/Notice` 相关控制器或服务骨架 +- 评估最小实现入口(如从简单查询端点开始逐步扩展) +- 输出结论建议(保留为"文档已收口、实现待立项") + +## Risks + +| Risk | Mitigation | +|------|------------| +| 治理台账同步时遗漏条目 | 每阶段完成后立即检查 `01_Project_Progress.md` 和 `03_Task_Checklist.md` | +| 接口编号冲突(IF-REV-009 误关联) | 本 feature 明确 IF-REV-013 为 REV-006 专用编号 | +| 超出本 feature 范围展开实现 | 严守"设计收口、实现待立项"约束,不新增业务代码 | diff --git a/specs/003-rev006-reminder-event-design/quickstart.md b/specs/003-rev006-reminder-event-design/quickstart.md index c2426a6..1b1cccc 100644 --- a/specs/003-rev006-reminder-event-design/quickstart.md +++ b/specs/003-rev006-reminder-event-design/quickstart.md @@ -1,57 +1,69 @@ -# Quickstart: REV-006 催缴事件与通知协同设计 +# Quickstart: REV-006 催缴与通知事件设计收口 -## 目标 +## 1. 使用目标 -本 quickstart 用于指导评审者和文档维护者快速完成 `REV-006` 设计补齐的检查,不涉及 backend 实施。 +本 quickstart 用于指导评审者或文档维护者快速完成 `REV-006` 的正式文档收口验证,不用于验证 backend 运行功能。 -## 步骤 1:阅读规格与研究结论 +## 2. 建议执行顺序 -1. 阅读 `spec.md`,确认三项澄清已固定: - - 停复水仅定义联动边界 - - `REV-006` 使用独立接口编号 `IF-REV-013` - - 结果状态固定为四态 -2. 阅读 `research.md`,确认所有关键设计决策已有依据和备选方案说明。 +1. 打开 [spec.md](/Volumes/Dpan/github/fujian_water_biz_doc/specs/003-rev006-reminder-event-design/spec.md),确认范围、四态状态和治理结论。 +2. 对照 [plan.md](/Volumes/Dpan/github/fujian_water_biz_doc/specs/003-rev006-reminder-event-design/plan.md),确认本轮只修改既有主文档与管理台账。 +3. 对照 [data-model.md](/Volumes/Dpan/github/fujian_water_biz_doc/specs/003-rev006-reminder-event-design/data-model.md),检查催缴候选对象、任务、结果和处置引用的最小字段是否齐全。 +4. 对照 `contracts/if-rev-013.md` 与 `contracts/if-ext-008.md`,确认 `SYS-002` / `SYS-010` 分工、输入输出和失败语义一致。 -## 步骤 2:执行文档改动时的目标落点 +## 3. 正式文档修订检查点 -1. 在 `docs/design/02_Detailed_Design/12_REV_Detailed.md` 补齐 `REV-006`: - - 任务生成规则 - - 结果回写规则 - - 停复水联动边界 - - 历史查询最小保留集 -2. 在 `docs/design/03_Technical_Design/03_Interface_Design.md`: - - 新增或替换 `IF-REV-013` - - 保留 `IF-EXT-008` - - 删除 `REV-006` 对 `IF-REV-009` 的错误引用 -3. 在 `docs/design/03_Technical_Design/01_Database_Design.md`: - - 明确在线主模型和历史只读查询口径 -4. 在治理台账中回写: - - `01_Project_Progress.md` - - `03_Task_Checklist.md` +- `12_REV_Detailed.md` + - 是否写清催缴对象来源、策略分组、频控和四态状态 + - 是否明确停复水/工单只作为联动边界和追溯引用 +- `03_Interface_Design.md` + - 是否统一 `IF-REV-013` 为正式业务接口编号 + - 是否区分 `IF-REV-013` 与 `IF-EXT-008` 的责任边界 +- `15_SYS002_Requirement_Breakdown.md` + - 是否保持 `SYS002-REQ-011` 为“未见实现” + - 是否明确“文档已收口,backend 未见明确实现骨架” +- `01_Project_Progress.md` / `03_Task_Checklist.md` + - 是否登记本轮文档收口与验证动作 -## 步骤 3:建议校验命令 +## 4. 最小验证命令 ```bash make validate-file FILE=docs/design/02_Detailed_Design/12_REV_Detailed.md make validate-file FILE=docs/design/03_Technical_Design/03_Interface_Design.md -make validate-file FILE=docs/design/03_Technical_Design/01_Database_Design.md make validate-file FILE=docs/design/00_Management/15_SYS002_Requirement_Breakdown.md -make validate-file FILE=docs/design/00_Management/01_Project_Progress.md -make validate-file FILE=docs/design/00_Management/03_Task_Checklist.md make check-links +make validate-mermaid ``` -## 步骤 4:验收检查点 +## 5. 完成判定 -- `REV-006` 不再复用 `IF-REV-009` -- 正式文档中统一使用四态结果集 -- 停复水只写联动边界,不扩写内部流程 -- 历史“催缴记录 / 停水记录 / 预存短信”不被误写成新在线主表 -- 台账和正式文档同步更新 +满足以下条件即可进入 `/speckit.tasks`: -## 步骤 5:本轮实现摘要 +- `REV-006` 的业务规则、接口边界、历史查询和处置追溯口径已统一 +- `SYS002-REQ-011` 的实现判断与后续研发切入点已写入治理台账 +- 验证命令已纳入计划,且无新增平行正式稿 -- 已完成 `12_REV_Detailed.md`、`03_Interface_Design.md`、`01_Database_Design.md`、`15_SYS002_Requirement_Breakdown.md`、`01_Project_Progress.md`、`03_Task_Checklist.md` 的正式文档回写。 -- `REV-006` 的正式业务接口编号已固定为 `IF-REV-013`,`IF-REV-009` 继续保留给 `REV-005` 发票结果查询。 -- 催缴结果已统一为 `PENDING`、`SUCCESS`、`FAIL`、`MANUAL_VERIFIED` 四态;数据库与历史查询口径同步收口。 -- 已执行并通过全部单文件校验与 `make check-links`。 +## 6. 2026-03-19 实施结果 + +### 已完成文档 + +- `docs/design/02_Detailed_Design/12_REV_Detailed.md` +- `docs/design/03_Technical_Design/03_Interface_Design.md` +- `docs/design/00_Management/15_SYS002_Requirement_Breakdown.md` +- `docs/design/00_Management/01_Project_Progress.md` +- `docs/design/00_Management/03_Task_Checklist.md` + +### 验证结果 + +- `make validate-file FILE=docs/design/02_Detailed_Design/12_REV_Detailed.md`:通过,0 个问题 +- `make validate-file FILE=docs/design/03_Technical_Design/03_Interface_Design.md`:通过,0 个问题 +- `make validate-file FILE=docs/design/00_Management/15_SYS002_Requirement_Breakdown.md`:通过,0 个问题 +- `make check-links`:通过,当前检查范围内未发现断链 +- `make check-mermaid-file FILE=docs/design/02_Detailed_Design/12_REV_Detailed.md`:已确认目标文件存在 6 个 Mermaid 图表 +- `make validate-mermaid`:已执行两次,但在当前环境下未返回最终结果;结合 Makefile 逻辑,该目标只校验仓库根目录 `*.md`,未直接覆盖本轮主要修改文件,后续如需全仓 Mermaid 终态结果,应单独排查该目标在当前环境中的阻塞原因 + +### 当前结论 + +- `REV-006` 已完成 implement 阶段的正式文档二次收口 +- `SYS002-REQ-011` 继续维持“未见实现”,但 Speckit 工件链、正式文档口径与治理台账已对齐 +- 当前剩余风险不是文档口径缺失,而是后续 backend 立项与 `make validate-mermaid` 全仓目标在本环境中的执行阻塞 diff --git a/specs/003-rev006-reminder-event-design/research.md b/specs/003-rev006-reminder-event-design/research.md index be51f14..80c15df 100644 --- a/specs/003-rev006-reminder-event-design/research.md +++ b/specs/003-rev006-reminder-event-design/research.md @@ -1,58 +1,46 @@ -# Phase 0 Research: REV-006 催缴事件与通知协同设计 +# Phase 0 Research: REV-006 催缴与通知事件设计收口 -## 决策 1:`REV-006` 使用新的独立正式接口编号 +## Decision 1: 以既有主文档承载 `REV-006` 收口 -- **Decision**: `REV-006` 使用新的独立正式接口编号 `IF-REV-013` 作为“催缴任务生成与结果查询/回写承接”的正式业务接口编号;`IF-REV-009` 保留给 `REV-005` 发票结果查询。 -- **Rationale**: - - 当前 `03_Interface_Design.md` 已明确 `IF-REV-009` 属于 `REV-005` 发票结果查询,继续复用会造成接口总表、异常码、幂等策略和时序图冲突。 - - 现有 `IF-REV-*` 编号已经覆盖到 `IF-REV-012`,顺延 `IF-REV-013` 是最小改动且最不易误解的做法。 - - 该决策能直接消除 `12_REV_Detailed.md` 中 `REV-006` 与接口主文档的冲突口径。 -- **Alternatives considered**: - - 继续复用 `IF-REV-009`:被否决,因为与发票查询主口径冲突。 - - 暂不落编号,只写业务能力:被否决,因为会推迟核心冲突到实施阶段。 - - 改用 `IF-EXT-*`:被否决,因为 `REV-006` 的业务接口主责仍属于 `SYS-002`,`IF-EXT-008` 只适用于与 `SYS-010` 的外部协同。 +**Decision**: 正式设计收口继续落在 `12_REV_Detailed.md`、`03_Interface_Design.md` 与 `15_SYS002_Requirement_Breakdown.md`,不新建平行正式稿。 +**Rationale**: `REV-006` 已在概要、详设、接口与治理台账中具备入口,当前问题是规则与边界不够收敛,而不是缺少载体。继续使用主文档符合单一真源原则。 +**Alternatives considered**: -## 决策 2:催缴结果状态固定为四态 +- 新建独立“催缴设计说明书”:会制造平行正式稿,违背宪章。 +- 仅在 spec 工件中描述:无法替代正式交付文档与治理台账。 -- **Decision**: `REV-006` 正式状态集固定为 `PENDING`、`SUCCESS`、`FAIL`、`MANUAL_VERIFIED`。 -- **Rationale**: - - 四态足以覆盖“待回写/待核查”“成功触达”“失败”“人工核查确认”四类评审和实施必需场景。 - - 过少状态会导致补偿与人工核查无法落地;过多状态会在当前未实现阶段引入不必要的细粒度设计。 - - 四态同时便于后续接口、数据库和台账统一。 -- **Alternatives considered**: - - 两态(成功/失败):无法表达未回写和人工核查状态。 - - 三态(待处理/成功/失败):无法区分人工核查后的确认结果。 - - 更细状态(已送达/已阅读/已补发):当前阶段超出设计收口所需。 +## Decision 2: `SYS-002` 与 `SYS-010` 按“业务侧任务控制 / 渠道侧触达执行”分界 -## 决策 3:停复水仅定义联动边界,不展开内部流程 +**Decision**: `SYS-002` 负责催缴对象筛选、任务生成、事件编号、四态状态承接、历史查询与处置引用;`SYS-010` 负责短信、微信、站内信等渠道触达及结果回传。 +**Rationale**: 该分界已在 `12_REV_Detailed.md` 与 `03_Interface_Design.md` 形成一致表达,能够避免“催缴任务生成”和“消息发送执行”职责混写。 +**Alternatives considered**: -- **Decision**: 本 feature 仅定义催缴结果与停复水之间的联动边界、触发条件、查询字段和追溯关系,不展开停复水内部处置流程、审批节点或现场执行细节。 -- **Rationale**: - - 停复水属于后续业务处置链,深入展开会把当前专题扩展到工单/现场作业子系统。 - - 当前 `REV-006` 的首要目标是把催缴闭环范围和责任边界收口,而不是设计全部后置处置流程。 - - 这样既能满足历史查询和审计追溯,又不破坏范围控制。 -- **Alternatives considered**: - - 把停复水完整流程纳入 `REV-006`:被否决,因为会扩大到非本轮范围。 - - 完全不写停复水联动:被否决,因为会留下历史查询和后续处置链断点。 +- 由 `SYS-010` 同时负责催缴任务控制:会让外部系统承担业务主控,不符合现有模块分工。 +- 由 `SYS-002` 同时负责所有消息发送:会弱化 `IF-EXT-008` 的外部协同边界。 -## 决策 4:历史“催缴记录/停水记录/预存短信”按历史只读口径承接 +## Decision 3: 正式状态集固定为四态 -- **Decision**: 旧系统“催缴记录、停水记录、预存短信记录”继续按历史只读查询对象承接,不新增同名在线主表;在线主模型以 `biz_charge`、操作留痕和消息协同结果为主。 -- **Rationale**: - - `01_Database_Design.md` 已对这些对象给出“历史只读保留”口径,且当前 backend 未见明确独立表族。 - - 直接新增同名新表会违反“不得臆造已实现事实”和“单一真源”的原则。 - - 历史只读策略既能满足迁移验收,也不影响后续按业务链逐步演进。 -- **Alternatives considered**: - - 为每个旧菜单新增在线主表:被否决,因为没有实现证据且破坏当前主模型。 - - 完全不保留历史查询口径:被否决,因为不满足迁移验收和追溯要求。 +**Decision**: `REV-006` 状态集固定为 `PENDING`、`SUCCESS`、`FAIL`、`MANUAL_VERIFIED`。 +**Rationale**: 四态已在详设与接口文档中同步表达,且足以覆盖受理中、成功、失败、人工补记三类核心语义。增加更多细粒度状态会放大实现假设。 +**Alternatives considered**: -## 决策 5:`REV-006` 与 `SYS-010` 的职责分界 +- 增加“已阅读”“已补发”等状态:超出当前正式口径,也缺少 backend 证据支持。 +- 仅保留成功/失败二态:不足以表达异步回写与人工核查场景。 -- **Decision**: `SYS-002/REV-006` 负责催缴对象筛选、任务分组、业务事件生成、状态承接、历史查询和处置关联;`SYS-010` 负责短信、微信公众号、站内信等触达执行与结果回传。 -- **Rationale**: - - 该分界与 `03_Interface_Design.md` 中跨系统协同表一致。 - - 业务筛选和状态归属留在 `SYS-002`,能保证催缴逻辑与账单口径一致。 - - 触达能力放在 `SYS-010`,避免 `REV-006` 越权扩展到消息平台实现。 -- **Alternatives considered**: - - 让 `SYS-010` 负责催缴对象筛选:被否决,因为会削弱营收主系统对账单规则的控制。 - - 让 `SYS-002` 直接承担全部消息发送:被否决,因为与既有系统边界不一致。 +## Decision 4: 历史催缴、停水、预存短信按只读查询口径承接 + +**Decision**: 旧系统催缴记录、停水记录、预存短信记录统一作为历史查询和追溯范围承接,不默认扩展为新系统已确认在线主表。 +**Rationale**: 当前 backend 未确认独立催缴台账、停水汇总表等实体;保守表达可同时满足迁移查询需求和事实一致性。 +**Alternatives considered**: + +- 直接定义新在线主表:缺少代码和数据库证据。 +- 完全忽略历史场景:会让迁移核查、客户历史查询和处置追溯失去正式口径。 + +## Decision 5: 当前实施结论维持“文档已收口,backend 未见明确实现骨架” + +**Decision**: 计划阶段保留 `SYS002-REQ-011` 为“未见实现”,并把本轮产出定位为文档收口和后续研发立项输入。 +**Rationale**: 现有治理文档已经给出相同结论,且当前未检索到明确的 `Reminder/Message/Notice` controller/service 骨架。 +**Alternatives considered**: + +- 升级为“部分实现”:会放大现有消息协同或历史查询描述,和证据不匹配。 +- 直接按“已实现”处理:与仓库现状冲突。 diff --git a/specs/003-rev006-reminder-event-design/spec.md b/specs/003-rev006-reminder-event-design/spec.md index a19fa5f..3163981 100644 --- a/specs/003-rev006-reminder-event-design/spec.md +++ b/specs/003-rev006-reminder-event-design/spec.md @@ -1,32 +1,29 @@ -# Feature Specification: REV-006 催缴事件与通知协同设计 +# Feature Specification: REV-006 催缴与通知事件设计收口 -**Feature Branch**: `003-rev006-reminder-event-design` +**Feature Branch**: `003-rev003-rev006-reminder-event-design` **Created**: 2026-03-18 -**Status**: Draft -**Input**: User description: "为 REV-006 催缴与通知补齐 spec-kit 规格,明确催缴任务生成、消息协同结果回写、停复水联动和历史查询边界" +**Status**: Ready for Planning +**Input**: 收口自 `003-rev003-rev006-reminder-event-design`(原设计会话)与 `003-rev006-reminder-event-design`(收口会话),合并后以本目录为准。 ## Document Scope & Sources *(mandatory)* - **Target documents**: - `docs/design/02_Detailed_Design/12_REV_Detailed.md` - `docs/design/03_Technical_Design/03_Interface_Design.md` - - `docs/design/03_Technical_Design/01_Database_Design.md` - `docs/design/00_Management/15_SYS002_Requirement_Breakdown.md` - `docs/design/00_Management/01_Project_Progress.md` - `docs/design/00_Management/03_Task_Checklist.md` - **Primary source of truth**: - `docs/design/02_Detailed_Design/12_REV_Detailed.md` - `docs/design/03_Technical_Design/03_Interface_Design.md` - - `docs/design/03_Technical_Design/01_Database_Design.md` - - `docs/design/00_Management/04_Writing_Guide.md` + - `docs/design/00_Management/15_SYS002_Requirement_Breakdown.md` + - `docs/design/01_Overview/03_Summary_Design.md` - `AGENTS.md` - **Reference sources**: - - `docs/design/00_Management/15_SYS002_Requirement_Breakdown.md` - `docs/guides/BACKEND_CURRENT_STATUS.md` - - `docs/guides/BACKEND_TABLE_MAPPING.md` - - `docs/design/04_Appendix/Archive/01_Requirements/` - - `docs/design/04_Appendix/Archive/05_Data_Dictionary/营收数据字典.md` -- **Scope decision**: In scope. This feature is limited to补齐 `REV-006` 的正式设计口径、接口边界、数据承接边界和后续任务拆解依据;不扩展到 `SYS-010` 的内部实现,不重写其他 `REV-*` 模块,不新建平行正式主稿。 + - `docs/design/04_Appendix/Archive/02_Manuals/营收系统_用户操作手册.md` + - `docs/design/04_Appendix/Archive/03_Design_Docs/营业收费管理系统-概要设计说明书20250912.md` +- **Scope decision**: In scope. 本 feature 聚焦 `REV-006` 催缴与通知的正式设计收口,补齐催缴对象生成、任务分组、`IF-REV-013` / `IF-EXT-008` 协同边界、四态状态语义、历史查询口径、停复水/工单联动追溯和后续研发立项输入;不在本轮直接承诺 backend 已落地催缴业务实现。 ## Clarifications @@ -38,104 +35,100 @@ ## User Scenarios & Testing *(mandatory)* -### User Story 1 - 定义催缴闭环范围 (Priority: P1) +### User Story 1 - 收口催缴任务生成规则 (Priority: P1) -作为文档维护者,我需要把 `REV-006` 的催缴生成、消息触达、结果回写和后续处置边界写清楚,使评审者能明确该模块到底负责什么、不负责什么,并据此开展后续设计与研发;其中停复水仅定义联动边界,不展开内部处置流程。 +作为文档维护者,我需要把 `REV-006` 的催缴触发时机、催缴对象筛选条件、策略分组规则和四态状态定义写清楚,使评审者能够明确欠费账单如何进入催缴任务,以及哪些场景属于自动催缴、人工补发或人工核查补记。 -**Why this priority**: `REV-006` 当前在仓库内被判定为“未见实现”,如果范围和边界不先收敛,后续 `plan/tasks` 会直接失焦。 +**Why this priority**: 当前 `REV-006` 已有第一轮场景描述,但后续研发立项仍依赖更清晰的触发规则、筛选条件和状态语义。 -**Independent Test**: 单独评审 `12_REV_Detailed.md` 中 `REV-006` 章节,应能独立回答“催缴任务如何产生、结果如何回写、停复水与工单如何衔接、哪些内容不在本轮范围内”。 +**Independent Test**: 单独评审 `12_REV_Detailed.md` 中 `REV-006` 章节,应能明确催缴对象来源、触发规则、四态状态和人工核查边界。 **Acceptance Scenarios**: -1. **Given** 当前 `REV-006` 只有概要级描述, **When** 评审者阅读更新后的详细设计, **Then** 能明确催缴对象来源、任务生成维度、自动与人工催缴边界以及停复水联动触发入口。 -2. **Given** 后续需要把 `REV-006` 拆成开发任务, **When** 维护者依据该规格开展计划拆解, **Then** 不需要再回到 Archive 才能判断本轮范围和排除项。 +1. **Given** 当前文档只概括"按策略分组催缴任务", **When** 评审者阅读补齐后的详细设计, **Then** 能明确欠费账单、账龄、金额、客户类别、渠道偏好和频控规则如何形成催缴对象与任务。 +2. **Given** 后续需要据此拆解研发任务, **When** 维护者依据该规格评估实现切入点, **Then** 能区分自动催缴、人工补发、人工核查补记和停复水联动的边界。 --- -### User Story 2 - 统一消息协同与结果回写口径 (Priority: P2) +### User Story 2 - 统一 IF-REV-013 与消息协同边界 (Priority: P2) -作为接口与系统集成评审者,我需要看到 `SYS-002` 与 `SYS-010` 之间关于催缴事件、触达结果、失败重试和状态回写的统一口径,并为 `REV-006` 使用独立正式接口编号和明确的 4 态结果集,以便避免与发票查询接口混淆。 +作为接口设计评审者,我需要看到 `IF-REV-013` 和 `IF-EXT-008` 的职责分工、请求输出、回写字段和四态结果承接口径,使 `SYS-002` 与 `SYS-010` 的边界不再停留在抽象表述。 -**Why this priority**: `REV-006` 的业务价值高度依赖消息协同结果,若回写与状态语义不清,会直接影响催缴结果查询、后续催办和停复水判断。 +**Why this priority**: `REV-006` 的核心风险在于业务筛选、任务状态承接和外部通知执行边界不清,容易出现"任务生成"和"消息发送"职责混写。 -**Independent Test**: 单独评审接口设计相关章节,应能独立确认触发方、回写方、关键状态、失败语义和查询/补偿责任分界。 +**Independent Test**: 单独评审接口主文档和需求拆解台账,应能确认 `IF-REV-013` 的业务侧职责、`IF-EXT-008` 的外部协同职责以及四态回写字段。 **Acceptance Scenarios**: -1. **Given** `SYS-002` 需要向 `SYS-010` 发送催缴事件, **When** 评审者查看规格, **Then** 能明确独立接口编号、事件生成条件、发送前置校验和最小回写字段集。 -2. **Given** 消息发送失败或结果迟迟未回写, **When** 评审者查看规格, **Then** 能明确 `PENDING`、`SUCCESS`、`FAIL`、`MANUAL_VERIFIED` 的适用边界,以及重试/补偿归属和人工核查入口。 +1. **Given** 评审者查看接口设计, **When** 阅读 `IF-REV-013` 章节, **Then** 能明确任务生成、任务查询、人工核查和结果承接的请求路径、字段与状态语义。 +2. **Given** 评审者查看需求拆解文档, **When** 阅读 `SYS002-REQ-011` 对应内容, **Then** 能明确当前属于"设计已收口、实现未见骨架"的状态,而不是误判为已实现。 --- -### User Story 3 - 明确历史查询与停复水联动边界 (Priority: P3) +### User Story 3 - 形成治理与研发切入结论 (Priority: P3) -作为后续实施和验收人员,我需要知道催缴记录、预存短信、停水记录等历史口径如何在当前体系中承接,避免为了追求“完整”而无依据地新增平行模型。 +作为后续立项和治理跟踪人员,我需要在台账和进度记录中看到 `REV-006` 的当前结论、最小实现切入点和校验动作,避免文档收口后仍无法指导后续研发排期。 -**Why this priority**: 旧系统相关对象较多,如果不先定义“最小保留集”和联动边界,后续很容易把历史菜单直接平移成新模块。 +**Why this priority**: `REV-006` 当前在治理台账中属于未见实现,需要通过本轮 feature 明确"文档先行、实现待立项"的真实结论和后续切入点。 -**Independent Test**: 单独检查规格中的迁移/历史查询要求,应能判断哪些历史信息必须可查、哪些仅保留映射说明、哪些应转交工单或外部协同模块承接。 +**Independent Test**: 单独检查治理文档,应能定位 `REV-006` 当前状态、最小研发切入点、台账同步动作和验证要求。 **Acceptance Scenarios**: -1. **Given** 需要追查某次催缴或停水处置历史, **When** 评审者阅读规格, **Then** 能明确最少需要保留的查询字段与关联对象。 -2. **Given** Archive 中存在旧“停水记录”“预存短信”等入口, **When** 评审者执行范围判断, **Then** 能明确这些内容在新体系中属于催缴协同能力还是外部协同能力,而不是新增独立正式模块。 +1. **Given** 项目需要安排后续研发排期, **When** 查看需求拆解和项目进度, **Then** 能明确 `REV-006` 当前是设计收口完成、backend 未见明确实现骨架、可继续立项推进的状态。 +2. **Given** 本轮完成正式文档修订, **When** 查看进度与任务清单, **Then** 能定位本次 `REV-006` 文档治理动作及其最小校验结果。 --- ### Edge Cases -- 当欠费账单满足多条催缴策略时,如何确定任务分组、优先级和避免重复触达? -- 当 `SYS-010` 返回失败、超时或迟迟不回写时,如何稳定映射到 `PENDING`、`SUCCESS`、`FAIL`、`MANUAL_VERIFIED`,而不再扩展更多细分状态? -- 当同一客户既存在催缴事件又进入停水/复水处置时,如何保证催缴记录与工单处置链路可追溯但不互相覆盖状态,且本 feature 不承担停复水内部流程定义? -- 当旧系统存在催缴记录、停水记录、预存短信历史数据,但当前后端未见独立表族时,如何定义最小保留查询口径而不臆造新模型? -- 当 `REV-006` 改用独立正式接口编号后,如何保证 `12_REV_Detailed.md`、`03_Interface_Design.md`、`01_Database_Design.md` 和管理台账同步更新且不保留旧冲突口径? +- 当欠费账单已被收费、作废或进入其他处置流程时,催缴对象是否仍可进入任务生成,文档必须如何表达排除条件? +- 当 `SYS-010` 只返回发送受理结果而未立即返回终态时,四态状态如何在 `SYS-002` 侧保持一致? +- 当旧系统存在催缴记录、停水记录和预存短信等历史查询场景,但当前 backend 未确认独立落表时,文档如何保持"历史只读承接"而不误写为现成在线表? +- 当人工核查补记场景发生时,哪些字段必须记录核查说明、关联任务号和后续处置引用? ## Requirements *(mandatory)* ### Functional Requirements -- **FR-001**: Specification MUST identify `REV-006` 的精确目标文档,并说明每份文档承担的职责。 -- **FR-002**: Specification MUST identify `12_REV_Detailed.md`、`03_Interface_Design.md`、`01_Database_Design.md` 作为本 feature 的主约束来源。 -- **FR-003**: Specification MUST record that the feature is in scope only for `REV-006` 的设计与任务拆解准备,不扩展到 `SYS-010` 内部实现或其他 `REV-*` 模块重写。 -- **FR-004**: Specification MUST preserve the single-source-of-truth model and MUST NOT introduce a new parallel formal design document for reminder/notice capability. -- **FR-005**: Specification MUST define reminder object sources based on overdue billing data and customer attributes, including at minimum arrears status, amount, aging, customer category, and applicable reminder strategy dimensions. -- **FR-006**: Specification MUST define the business flow for reminder generation, task grouping, message dispatch request, result writeback, and follow-up handling. -- **FR-007**: Specification MUST distinguish automatic reminder, manual reminder, and subsequent disposal linkage, including what belongs to `SYS-002`, what is coordinated by `SYS-010`, and what is handled through downstream disposal processes. -- **FR-008**: Specification MUST define exactly four formal result states for reminder collaboration: `PENDING`, `SUCCESS`, `FAIL`, and `MANUAL_VERIFIED`, with unambiguous transition intent and usage boundaries. -- **FR-008a**: Specification MUST require a dedicated formal interface identifier for `REV-006` reminder task generation and result handling, and MUST prohibit continued reuse of `IF-REV-009` for this feature because `IF-REV-009` remains reserved for invoice result query. -- **FR-009**: Specification MUST define the minimum historical query retention scope for reminder records, stop-water related records, and prepaid-balance reminder events, including the fields needed to trace content, channel, target, time, result, operator/source, and related billing object. -- **FR-010**: Specification MUST define how stop-water and recovery handling relate to reminder outcomes without collapsing them into the same business object, and MUST limit this feature to linkage conditions and traceability rather than internal disposal workflow details. -- **FR-011**: Specification MUST state the exclusions for this feature, including that historical menu names and Archive structures are reference material only and not direct targets for formal document reconstruction. -- **FR-012**: Specification MUST capture cross-document consistency impacts for interfaces, data retention, terminology, result states, and downstream ledger updates. -- **FR-013**: Specification MUST list the validation actions required after document updates, including single-file validation for impacted docs and link consistency checks. -- **FR-014**: Specification MUST state that formal document changes under this feature require synchronized updates to `01_Project_Progress.md` and `03_Task_Checklist.md`. +- **FR-001**: Specification MUST identify the exact target documents for `REV-006` reminder-event alignment and governance sync. +- **FR-002**: Specification MUST identify `12_REV_Detailed.md`、`03_Interface_Design.md`、`15_SYS002_Requirement_Breakdown.md` as the main source-of-truth set for this feature. +- **FR-003**: Specification MUST record that this feature is in scope only for reminder-candidate generation, task rules, `IF-REV-013` / `IF-EXT-008` interface boundary, four-state result semantics, historical query boundary, and governance sync. +- **FR-004**: Specification MUST preserve the single-source-of-truth model and MUST NOT create a parallel formal design document for `REV-006`. +- **FR-005**: Specification MUST define reminder-candidate selection conditions, including arrears status, aging, amount, customer category, channel preference, strategy grouping, and frequency-control boundary. +- **FR-006**: Specification MUST define the formal four-state reminder result set as `PENDING`、`SUCCESS`、`FAIL`、`MANUAL_VERIFIED`, including the intended meaning of each state. +- **FR-007**: Specification MUST define the exact business boundary of `IF-REV-013`, including task generation, task query, manual verification, result acceptance, and historical query support. +- **FR-008**: Specification MUST define the external collaboration boundary of `IF-EXT-008`, clarifying that `SYS-010` is responsible for channel delivery while `SYS-002` retains business-side task and state control. +- **FR-009**: Specification MUST define the minimum write-back and traceability fields for reminder results, including task number, event number, strategy code, channel type, trigger type, status, failure reason, and disposal reference. +- **FR-010**: Specification MUST define how reminder results link to stop-water, restore-water, work-order, or manual follow-up references without expanding those downstream internal workflows. +- **FR-011**: Specification MUST define historical query and export expectations for reminder records, including customer, bill period, reminder channel, target receiver, send time, execution result, related bills, and disposal references. +- **FR-012**: Specification MUST explicitly capture the current implementation judgment as "文档已收口,backend 未见明确催缴/通知业务实现骨架" unless stronger evidence is found later. +- **FR-013**: Specification MUST identify the minimum validation actions after document updates, including affected file validation, link checks, and Mermaid checks where flows are updated. +- **FR-014**: Specification MUST state that important formal document changes under this feature require synchronized updates to `01_Project_Progress.md` and `03_Task_Checklist.md`. ### Assumptions -- 本 feature 以正式文档补齐和后续立项准备为目标,默认不在本轮直接修改 backend 代码。 -- `SYS-010` 继续作为消息发送能力提供方,`SYS-002` 负责业务事件生成、状态承接和历史查询口径。 -- `REV-006` 将在正式文档中使用新的独立接口编号;现有 `IF-REV-009` 继续保留给发票结果查询,不再混用。 -- 催缴结果状态默认收敛为 `PENDING`、`SUCCESS`、`FAIL`、`MANUAL_VERIFIED` 四态,本轮不再细分为“已送达”“已阅读”“已补发”等更细粒度状态。 -- 旧系统“催缴记录”“预存短信”“停水记录”等历史入口默认先按查询能力和映射口径承接,不默认要求新建同名独立主表。 -- 停水/复水属于后续业务处置链的一部分,本 feature 只要求定义与催缴结果的联动边界、触发条件和追溯关系,不展开其内部节点、审批或执行流程。 +- 本 feature 以正式文档收口和后续研发立项准备为目标,默认不在本轮直接承诺 backend 业务代码实现。 +- `IF-REV-013` 继续作为 `REV-006` 的正式业务接口编号,不复用其他 `IF-REV-*` 编号。 +- `SYS-010` 负责短信、微信公众号、站内信等触达执行;`SYS-002` 保留催缴对象筛选、任务生成、四态状态承接和历史查询职责。 +- 当前 backend 中未见明确的 `Reminder/Message/Notice` 业务控制器或服务骨架,因此实现状态保持"未见实现"。 +- 催缴记录、停复水记录和预存短信等历史场景在本轮按"历史只读查询口径"承接,不默认要求新建平行在线主表。 ### Key Entities *(include if feature involves data)* -- **Reminder Candidate**: 满足欠费、账龄、客户类别等条件、可进入催缴流程的账单或客户对象集合。 -- **Reminder Strategy**: 决定催缴触发条件、分组规则、触达渠道和优先级的业务规则集。 -- **Reminder Task**: 一次可追溯的催缴执行单元,包含催缴对象、触达渠道、生成来源、执行状态和后续处置指向。 -- **Reminder Result**: 由消息协同或人工核查产生的结果记录,反映发送状态、失败原因、回写时间和后续动作建议。 -- **Reminder History Record**: 支撑历史查询的最小记录集合,至少覆盖触达内容、目标对象、渠道、发送时间、结果状态、关联账单和操作来源。 -- **Disposal Link**: 催缴结果与停水、复水、工单或人工处置之间的关联关系,用于追溯后续业务动作,但不替代下游业务对象。 -- **Ledger Update**: 当 `REV-006` 正式文档完成补齐后,需要同步回写到项目进度和任务清单的治理记录。 +- **Reminder Candidate**: 由欠费账单、账龄、欠费金额、客户类别、联系方式和命中策略组成的催缴输入对象。 +- **Reminder Strategy**: 定义账龄规则、金额规则、客户类别规则、渠道优先级、频控策略和后续联动关注条件的策略对象。 +- **Reminder Task**: 一次正式催缴执行单元,至少包含 `taskNo`、`eventNo`、`strategyCode`、`channelType`、`triggerType`、`status` 和关联账单集合。 +- **Reminder Result**: 催缴任务的四态结果及其失败原因、执行时间、外部回写摘要和业务侧处置引用。 +- **Disposal Link**: 催缴结果与停复水、工单、人工核查等后续处置之间的追溯引用对象。 +- **Governance Record**: 用于在需求拆解、项目进度和任务清单中登记本轮 `REV-006` 收口结论和后续研发建议的治理记录。 ## Success Criteria *(mandatory)* ### Measurable Outcomes -- **SC-001**: 评审者可在 5 分钟内从规格中定位 `REV-006` 的目标文档、主约束来源、范围边界和排除项。 -- **SC-002**: 规格中覆盖至少 3 类独立可评审场景:催缴任务生成、消息结果回写、历史查询/停复水联动。 -- **SC-003**: `REV-006` 的状态语义、协同边界和历史查询最小保留集在规格中均有明确表述,且不存在未解析的 `[NEEDS CLARIFICATION]` 标记。 -- **SC-004**: 后续执行 `/speckit.plan` 时,规划者无需新增范围澄清即可把工作拆分为文档对齐、接口补齐、数据口径补齐和台账更新四类任务。 -- **SC-005**: 规格明确列出全部必要验证动作,审阅者可直接据此执行至少 4 项文档校验或一致性检查而无需二次猜测。 +- **SC-001**: 评审者可在 5 分钟内从规格中定位 `REV-006` 的目标文档、催缴对象生成规则、接口边界和排除项。 +- **SC-002**: 规格中至少覆盖 3 类独立可评审内容:催缴任务生成规则、`IF-REV-013` / `IF-EXT-008` 边界、治理与研发切入结论。 +- **SC-003**: 规格明确区分至少 6 项关键任务或结果要素,如 `taskNo`、`eventNo`、`strategyCode`、`channelType`、`triggerType`、`status`、失败原因、处置引用。 +- **SC-004**: 后续执行 `/speckit.plan` 时,规划者无需再补充范围澄清即可将工作拆分为详细设计收口、接口收口、治理同步和实现切入点评估四类任务。 +- **SC-005**: 规格明确列出全部必要验证动作,审阅者可直接据此执行至少 4 项文档校验或一致性检查。 diff --git a/specs/003-rev006-reminder-event-design/tasks.md b/specs/003-rev006-reminder-event-design/tasks.md index fc9991e..9a28d66 100644 --- a/specs/003-rev006-reminder-event-design/tasks.md +++ b/specs/003-rev006-reminder-event-design/tasks.md @@ -1,6 +1,6 @@ # Tasks: REV-006 催缴事件与通知协同设计 -**Input**: Design documents from `/specs/003-rev006-reminder-event-design/` +**Input**: Design documents from `/specs/003-rev003-rev006-reminder-event-design/` **Prerequisites**: plan.md (required), spec.md (required), research.md, data-model.md, contracts/ **Validation**: Validation tasks are NOT optional in this repository. Every document change task set MUST include the applicable validation and ledger-sync tasks. @@ -24,10 +24,10 @@ **Purpose**: Confirm the source-of-truth set and impact boundary before editing. -- [X] T001 Confirm target documents and exact `REV-006` touchpoints in `/Volumes/Dpan/github/fujian_water_biz_doc/specs/003-rev006-reminder-event-design/spec.md` -- [X] T002 Confirm governing source-of-truth and allowed reference sources in `/Volumes/Dpan/github/fujian_water_biz_doc/specs/003-rev006-reminder-event-design/plan.md` -- [X] T003 [P] Record final scope judgment for `REV-006` and exclusions in `/Volumes/Dpan/github/fujian_water_biz_doc/specs/003-rev006-reminder-event-design/research.md` -- [X] T004 [P] Identify cross-document impacts for `IF-REV-013`、四态结果集、停复水联动边界和历史只读口径 in `/Volumes/Dpan/github/fujian_water_biz_doc/specs/003-rev006-reminder-event-design/contracts/rev006-interface-contract.md` +- [X] T001 Confirm target documents and exact `REV-006` touchpoints in `/Volumes/Dpan/github/fujian_water_biz_doc/specs/003-rev003-rev006-reminder-event-design/spec.md` +- [X] T002 Confirm governing source-of-truth and allowed reference sources in `/Volumes/Dpan/github/fujian_water_biz_doc/specs/003-rev003-rev006-reminder-event-design/plan.md` +- [X] T003 [P] Record final scope judgment for `REV-006` and exclusions in `/Volumes/Dpan/github/fujian_water_biz_doc/specs/003-rev003-rev006-reminder-event-design/research.md` +- [X] T004 [P] Identify cross-document impacts for `IF-REV-013`、四态结果集、停复水联动边界和历史只读口径 in `/Volumes/Dpan/github/fujian_water_biz_doc/specs/003-rev003-rev006-reminder-event-design/contracts/rev006-interface-contract.md` --- @@ -35,7 +35,7 @@ **Purpose**: Prepare the cross-document baseline that all user stories depend on. -- [X] T005 Consolidate `REV-006` decisions, entities, and contract fields from `/Volumes/Dpan/github/fujian_water_biz_doc/specs/003-rev006-reminder-event-design/research.md`, `/Volumes/Dpan/github/fujian_water_biz_doc/specs/003-rev006-reminder-event-design/data-model.md`, and `/Volumes/Dpan/github/fujian_water_biz_doc/specs/003-rev006-reminder-event-design/contracts/rev006-interface-contract.md` +- [X] T005 Consolidate `REV-006` decisions, entities, and contract fields from `/Volumes/Dpan/github/fujian_water_biz_doc/specs/003-rev003-rev006-reminder-event-design/research.md`, `/Volumes/Dpan/github/fujian_water_biz_doc/specs/003-rev003-rev006-reminder-event-design/data-model.md`, and `/Volumes/Dpan/github/fujian_water_biz_doc/specs/003-rev003-rev006-reminder-event-design/contracts/rev006-interface-contract.md` - [X] T006 [P] Cross-check current conflicting references to `IF-REV-009` and `REV-006` in `/Volumes/Dpan/github/fujian_water_biz_doc/docs/design/02_Detailed_Design/12_REV_Detailed.md` and `/Volumes/Dpan/github/fujian_water_biz_doc/docs/design/03_Technical_Design/03_Interface_Design.md` - [X] T007 [P] Cross-check historical-only retention rules for 催缴记录/停水记录/预存短信 in `/Volumes/Dpan/github/fujian_water_biz_doc/docs/design/03_Technical_Design/01_Database_Design.md` and `/Volumes/Dpan/github/fujian_water_biz_doc/docs/design/04_Appendix/Archive/05_Data_Dictionary/营收数据字典.md` - [X] T008 Confirm ledger update expectations for this feature in `/Volumes/Dpan/github/fujian_water_biz_doc/docs/design/00_Management/15_SYS002_Requirement_Breakdown.md`, `/Volumes/Dpan/github/fujian_water_biz_doc/docs/design/00_Management/01_Project_Progress.md`, and `/Volumes/Dpan/github/fujian_water_biz_doc/docs/design/00_Management/03_Task_Checklist.md` @@ -105,7 +105,7 @@ - [X] T027 [P] Re-check source-of-truth alignment across `/Volumes/Dpan/github/fujian_water_biz_doc/docs/design/02_Detailed_Design/12_REV_Detailed.md`, `/Volumes/Dpan/github/fujian_water_biz_doc/docs/design/03_Technical_Design/03_Interface_Design.md`, `/Volumes/Dpan/github/fujian_water_biz_doc/docs/design/03_Technical_Design/01_Database_Design.md`, and `/Volumes/Dpan/github/fujian_water_biz_doc/docs/design/00_Management/15_SYS002_Requirement_Breakdown.md` - [X] T028 [P] Run `make check-links` after all document changes and capture result -- [X] T029 Prepare final summary with modified files, validation results, remaining risks, and next-step suggestions in `/Volumes/Dpan/github/fujian_water_biz_doc/specs/003-rev006-reminder-event-design/quickstart.md` +- [X] T029 Prepare final summary with modified files, validation results, remaining risks, and next-step suggestions in `/Volumes/Dpan/github/fujian_water_biz_doc/specs/003-rev003-rev006-reminder-event-design/quickstart.md` --- diff --git a/specs/006-reminder-event-design/checklists/requirements.md b/specs/006-reminder-event-design/checklists/requirements.md deleted file mode 100644 index c5fe0b1..0000000 --- a/specs/006-reminder-event-design/checklists/requirements.md +++ /dev/null @@ -1,35 +0,0 @@ -# Specification Quality Checklist: REV-006 催缴与通知事件设计收口 - -**Purpose**: Validate specification completeness and quality before proceeding to planning -**Created**: 2026-03-18 -**Feature**: [/Volumes/Dpan/github/fujian_water_biz_doc/specs/006-reminder-event-design/spec.md](/Volumes/Dpan/github/fujian_water_biz_doc/specs/006-reminder-event-design/spec.md) - -## Content Quality - -- [x] No implementation details (languages, frameworks, APIs) -- [x] Focused on user value and business needs -- [x] Written for non-technical stakeholders -- [x] All mandatory sections completed - -## Requirement Completeness - -- [x] No [NEEDS CLARIFICATION] markers remain -- [x] Requirements are testable and unambiguous -- [x] Success criteria are measurable -- [x] Success criteria are technology-agnostic (no implementation details) -- [x] All acceptance scenarios are defined -- [x] Edge cases are identified -- [x] Scope is clearly bounded -- [x] Dependencies and assumptions identified - -## Feature Readiness - -- [x] All functional requirements have clear acceptance criteria -- [x] User scenarios cover primary flows -- [x] Feature meets measurable outcomes defined in Success Criteria -- [x] No implementation details leak into specification - -## Notes - -- Validated against `spec.md` on 2026-03-18; no outstanding clarification markers or blocking quality gaps were found. -- Items marked incomplete require spec updates before `/speckit.clarify` or `/speckit.plan` diff --git a/specs/006-reminder-event-design/data-model.md b/specs/006-reminder-event-design/data-model.md deleted file mode 100644 index 0c21348..0000000 --- a/specs/006-reminder-event-design/data-model.md +++ /dev/null @@ -1,125 +0,0 @@ -# Data Model: REV-006 催缴与通知事件设计收口 - -## 1. Reminder Candidate - -**说明**: 催缴任务的输入对象,由欠费账单和客户上下文组合形成。 - -| 字段 | 类型 | 说明 | 约束 | -|------|------|------|------| -| candidateId | String | 候选对象标识 | 可由任务生成阶段派生,不要求独立持久化主键 | -| custId | String | 客户标识 | 必填 | -| accountId | String | 账户标识 | 必填 | -| chargeIds | List | 命中的欠费账单集合 | 至少 1 条 | -| billPeriods | List | 账期集合 | 必填 | -| arrearsAmount | Decimal | 欠费总金额 | 必须大于 0 | -| agingBucket | String | 账龄分组 | 必填 | -| custCategory | String | 客户类别 | 必填 | -| preferredChannels | List | 渠道偏好 | 至少 1 个渠道 | -| strategyCode | String | 命中的催缴策略编码 | 必填 | -| frequencyWindow | String | 频控窗口 | 用于重复触达拦截 | - -**关系**: - -- 一个 `Reminder Candidate` 可生成一个或多个 `Reminder Task` -- `Reminder Candidate` 来源于 `biz_charge`、`biz_charge_detail` 等营业账对象 - -## 2. Reminder Strategy - -**说明**: 约束候选对象筛选、任务分组和渠道优先级的规则集合。 - -| 字段 | 类型 | 说明 | 约束 | -|------|------|------|------| -| strategyCode | String | 策略编码 | 唯一 | -| strategyName | String | 策略名称 | 必填 | -| agingRule | String | 账龄规则 | 必填 | -| amountRule | String | 金额规则 | 必填 | -| custCategoryRule | String | 客户类别规则 | 可为空,表示不限 | -| channelPriority | List | 渠道优先级 | 至少 1 项 | -| frequencyControl | String | 频控规则 | 必填 | -| disposalAttentionFlag | Boolean | 是否关注后续处置 | 必填 | - -**状态转换**: - -- 启用 -- 停用 - -## 3. Reminder Task - -**说明**: 正式催缴执行单元,是 `IF-REV-013` 的核心业务对象。 - -| 字段 | 类型 | 说明 | 约束 | -|------|------|------|------| -| taskNo | String | 催缴任务号 | 唯一、必填 | -| eventNo | String | 业务事件号 | 唯一、必填 | -| strategyCode | String | 策略编码 | 必填 | -| channelType | String | 执行渠道 | 必填 | -| triggerType | String | 触发类型 | 自动 / 人工 | -| status | String | 当前状态 | 仅允许 `PENDING` / `SUCCESS` / `FAIL` / `MANUAL_VERIFIED` | -| chargeIds | List | 关联账单 | 至少 1 条 | -| receiver | String | 触达对象 | 可为手机号、微信标识或站内账号 | -| sendTime | Datetime | 发送发起时间 | 可空,待触发后填写 | -| lastCallbackTime | Datetime | 最近结果回写时间 | 可空 | -| failReason | String | 失败原因 | `FAIL` 时建议记录 | -| manualVerifyNote | String | 人工核查说明 | `MANUAL_VERIFIED` 时建议记录 | - -**状态转换**: - -1. 新建任务后进入 `PENDING` -2. 外部触达成功后进入 `SUCCESS` -3. 外部明确失败后进入 `FAIL` -4. 外部结果长期未定或人工补记后进入 `MANUAL_VERIFIED` - -## 4. Reminder Result - -**说明**: 承接 `SYS-010` 回写结果与业务侧最终状态语义。 - -| 字段 | 类型 | 说明 | 约束 | -|------|------|------|------| -| taskNo | String | 对应任务号 | 必填 | -| eventNo | String | 对应事件号 | 必填 | -| status | String | 四态结果 | 必填 | -| channelType | String | 渠道类型 | 必填 | -| externalResultCode | String | 外部结果码 | 可空 | -| externalResultMessage | String | 外部结果说明 | 可空 | -| failReason | String | 业务失败原因 | `FAIL` 时可必填 | -| callbackTime | Datetime | 回写时间 | 必填 | -| sourceSystem | String | 回写来源系统 | 默认 `SYS-010` | - -## 5. Disposal Link - -**说明**: 催缴任务与停水、复水、工单、人工跟进之间的追溯引用。 - -| 字段 | 类型 | 说明 | 约束 | -|------|------|------|------| -| taskNo | String | 关联催缴任务号 | 必填 | -| disposalType | String | 处置类型 | 停水 / 复水 / 工单 / 人工跟进 | -| disposalRefNo | String | 处置引用号 | 必填 | -| disposalStatus | String | 处置状态摘要 | 可空 | -| linkedAt | Datetime | 建联时间 | 必填 | -| note | String | 追溯说明 | 可空 | - -## 6. Governance Record - -**说明**: 用于治理台账登记本轮设计收口结论与后续研发建议。 - -| 字段 | 类型 | 说明 | 约束 | -|------|------|------|------| -| reqCode | String | 需求编号 | 固定为 `SYS002-REQ-011` | -| featureName | String | Speckit feature 名称 | 固定为 `rev006-reminder-event-design` | -| implementationStatus | String | 当前实现判断 | `未见实现` | -| docStatus | String | 文档状态 | 设计已收口 / 待同步 / 待验证 | -| nextAction | String | 后续动作 | 研发立项 / 文档补证 / 治理同步 | -| evidenceRefs | List | 证据来源 | 必填 | - -## 7. 关系总览 - -```text -Reminder Strategy - -> Reminder Candidate - -> Reminder Task -Reminder Task - -> Reminder Result - -> Disposal Link -Governance Record - -> 引用 Reminder Task / Reminder Result 的设计结论与实现判断 -``` diff --git a/specs/006-reminder-event-design/plan.md b/specs/006-reminder-event-design/plan.md deleted file mode 100644 index 6e8b796..0000000 --- a/specs/006-reminder-event-design/plan.md +++ /dev/null @@ -1,150 +0,0 @@ -# Implementation Plan: REV-006 催缴与通知事件设计收口 - -**Branch**: `006-reminder-event-design` | **Date**: 2026-03-18 | **Spec**: [/Volumes/Dpan/github/fujian_water_biz_doc/specs/006-reminder-event-design/spec.md](/Volumes/Dpan/github/fujian_water_biz_doc/specs/006-reminder-event-design/spec.md) -**Input**: Feature specification from `/specs/006-reminder-event-design/spec.md` - -## Summary - -本次计划聚焦 `REV-006` 的正式文档收口,而非直接编写 backend 业务代码。目标是在既有主文档中补齐催缴对象生成规则、`IF-REV-013` / `IF-EXT-008` 的职责边界、四态结果语义、历史查询与处置追溯口径,并同步治理台账,使后续研发可基于统一口径继续立项。 - -目标文档包括: - -- `docs/design/02_Detailed_Design/12_REV_Detailed.md` -- `docs/design/03_Technical_Design/03_Interface_Design.md` -- `docs/design/00_Management/15_SYS002_Requirement_Breakdown.md` -- `docs/design/00_Management/01_Project_Progress.md` -- `docs/design/00_Management/03_Task_Checklist.md` - -## Technical Context - -**Primary Work Product**: Markdown 正式设计文档、治理台账与 Speckit 规划工件 -**Source of Truth Documents**: - -- `docs/design/02_Detailed_Design/12_REV_Detailed.md` -- `docs/design/03_Technical_Design/03_Interface_Design.md` -- `docs/design/00_Management/15_SYS002_Requirement_Breakdown.md` -- `docs/design/01_Overview/03_Summary_Design.md` -- `AGENTS.md` - -**Reference Sources**: - -- `docs/guides/BACKEND_CURRENT_STATUS.md` -- `docs/design/04_Appendix/Archive/02_Manuals/营收系统_用户操作手册.md` -- `docs/design/04_Appendix/Archive/03_Design_Docs/营业收费管理系统-概要设计说明书20250912.md` - -**Validation Commands**: - -- `make validate-file FILE=docs/design/02_Detailed_Design/12_REV_Detailed.md` -- `make validate-file FILE=docs/design/03_Technical_Design/03_Interface_Design.md` -- `make validate-file FILE=docs/design/00_Management/15_SYS002_Requirement_Breakdown.md` -- `make check-links` -- `make validate-mermaid` - -**Target Scope**: - -- 收口 `REV-006` 详细设计章节 -- 收口 `IF-REV-013` 与 `IF-EXT-008` 承接口径 -- 回写 `SYS002-REQ-011` 的状态判断、后续研发切入点与治理结论 -- 规划 `01_Project_Progress.md` 与 `03_Task_Checklist.md` 的同步更新动作 - -**Project Type**: 文档治理仓库 -**Constraints**: - -- 不新增平行正式稿,只回写既有主文档或治理文档 -- 不臆造 backend 已实现能力 -- Archive 仅作为来源核对,不直接替代正式口径 -- 编号、术语、相对路径、Mermaid 图与正文必须一致 -- 正式系统名称统一为“福建水务营收系统” - -**Scale/Scope**: 跨文档设计收口与治理同步,覆盖详设、接口、管理台账三类文档 - -## Constitution Check - -*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.* - -- [x] **主文档归属已确认**:本次改动只落在 `12_REV_Detailed.md`、`03_Interface_Design.md`、`15_SYS002_Requirement_Breakdown.md` 及管理台账,不新增平行正式稿。 -- [x] **范围基线已确认**:`REV-006` 已同时出现在 `03_Summary_Design.md`、`12_REV_Detailed.md` 与 Archive 范围内,属于可直接推进的交集范围。 -- [x] **Archive 使用方式合规**:Archive 仅作为旧系统催缴记录、停水记录、预存短信场景的来源核对,不直接作为正式文档替身。 -- [x] **一致性影响已列出**:受影响项包括 `REV-006` 模块编号、`IF-REV-013` / `IF-EXT-008` 编号边界、四态状态集、催缴/停复水术语、历史查询口径与 Mermaid 流程图。 -- [x] **校验与台账动作已规划**:已明确单文件校验、全仓链接校验、Mermaid 校验,并规划同步更新 `01_Project_Progress.md` 与 `03_Task_Checklist.md`。 - -## Project Structure - -### Documentation (this feature) - -```text -specs/006-reminder-event-design/ -├── plan.md -├── research.md -├── data-model.md -├── quickstart.md -├── contracts/ -│ ├── if-rev-013.md -│ └── if-ext-008.md -└── tasks.md -``` - -### Repository Touchpoints - -```text -docs/design/ -├── 00_Management/01_Project_Progress.md -├── 00_Management/03_Task_Checklist.md -├── 00_Management/15_SYS002_Requirement_Breakdown.md -├── 01_Overview/03_Summary_Design.md -├── 02_Detailed_Design/12_REV_Detailed.md -├── 03_Technical_Design/03_Interface_Design.md -└── 04_Appendix/Archive/ -``` - -**Structure Decision**: - -- `12_REV_Detailed.md`:承载 `REV-006` 的业务流程、规则、核心数据与落地边界 -- `03_Interface_Design.md`:承载 `IF-REV-013` / `IF-EXT-008` 的业务接口定义与边界说明 -- `15_SYS002_Requirement_Breakdown.md`:承载 `SYS002-REQ-011` 的实现判断、建议粒度与推进说明 -- `01_Project_Progress.md`:登记本轮正式文档收口动作与验证结果 -- `03_Task_Checklist.md`:登记 `REV-006` 相关治理任务的完成状态 - -## Phase 0: Outline & Research - -### Research Inputs - -- 既有 `REV-006` 章节是否已足够承载催缴对象生成、四态结果和联动边界 -- `IF-REV-013` / `IF-EXT-008` 的职责拆分是否与 `SYS-002` / `SYS-010` 边界一致 -- 当前 backend 未见实现骨架的结论,如何在正式文档与治理台账中保守表达 - -### Phase 0 Deliverable - -- [/Volumes/Dpan/github/fujian_water_biz_doc/specs/006-reminder-event-design/research.md](/Volumes/Dpan/github/fujian_water_biz_doc/specs/006-reminder-event-design/research.md) - -### Research Conclusion - -- 无额外 `NEEDS CLARIFICATION` 留存。 -- 计划阶段可直接以“文档先行、实现待立项”为结论进入设计与合同化表达。 - -## Phase 1: Design & Contracts - -### Planned Artifacts - -- [/Volumes/Dpan/github/fujian_water_biz_doc/specs/006-reminder-event-design/data-model.md](/Volumes/Dpan/github/fujian_water_biz_doc/specs/006-reminder-event-design/data-model.md) -- [/Volumes/Dpan/github/fujian_water_biz_doc/specs/006-reminder-event-design/contracts/if-rev-013.md](/Volumes/Dpan/github/fujian_water_biz_doc/specs/006-reminder-event-design/contracts/if-rev-013.md) -- [/Volumes/Dpan/github/fujian_water_biz_doc/specs/006-reminder-event-design/contracts/if-ext-008.md](/Volumes/Dpan/github/fujian_water_biz_doc/specs/006-reminder-event-design/contracts/if-ext-008.md) -- [/Volumes/Dpan/github/fujian_water_biz_doc/specs/006-reminder-event-design/quickstart.md](/Volumes/Dpan/github/fujian_water_biz_doc/specs/006-reminder-event-design/quickstart.md) - -### Design Decisions - -- 以“催缴候选对象 -> 催缴任务 -> 消息协同 -> 四态回写 -> 处置追溯”的业务链路组织文档,而非按旧系统页面零散堆砌。 -- 历史催缴、停水、预存短信统一按“历史只读查询口径”承接,不额外承诺独立在线主表。 -- 合同化产物只描述接口业务语义、字段边界和责任划分,不写成 backend API 已实现证明。 - -## Post-Design Constitution Check - -- [x] **主文档归属保持不变**:Phase 1 产物用于规划与任务拆解,正式结论仍回流既有主文档。 -- [x] **范围未外溢**:设计仍限定在 `REV-006` 催缴与通知收口,不扩展到停复水审批或独立消息中心建设。 -- [x] **Archive 仍为引用源**:未把 Archive 内容直接升级为独立正式稿。 -- [x] **一致性风险已收敛**:四态状态集、接口编号、协同边界和历史查询术语已统一。 -- [x] **校验闭环已具备**:已有明确验证命令、管理台账更新点和后续 tasks 拆解基础。 - -## Complexity Tracking - -本次计划无宪章违例项,无需额外豁免。 diff --git a/specs/006-reminder-event-design/quickstart.md b/specs/006-reminder-event-design/quickstart.md deleted file mode 100644 index e02eeb1..0000000 --- a/specs/006-reminder-event-design/quickstart.md +++ /dev/null @@ -1,69 +0,0 @@ -# Quickstart: REV-006 催缴与通知事件设计收口 - -## 1. 使用目标 - -本 quickstart 用于指导评审者或文档维护者快速完成 `REV-006` 的正式文档收口验证,不用于验证 backend 运行功能。 - -## 2. 建议执行顺序 - -1. 打开 [spec.md](/Volumes/Dpan/github/fujian_water_biz_doc/specs/006-reminder-event-design/spec.md),确认范围、四态状态和治理结论。 -2. 对照 [plan.md](/Volumes/Dpan/github/fujian_water_biz_doc/specs/006-reminder-event-design/plan.md),确认本轮只修改既有主文档与管理台账。 -3. 对照 [data-model.md](/Volumes/Dpan/github/fujian_water_biz_doc/specs/006-reminder-event-design/data-model.md),检查催缴候选对象、任务、结果和处置引用的最小字段是否齐全。 -4. 对照 `contracts/if-rev-013.md` 与 `contracts/if-ext-008.md`,确认 `SYS-002` / `SYS-010` 分工、输入输出和失败语义一致。 - -## 3. 正式文档修订检查点 - -- `12_REV_Detailed.md` - - 是否写清催缴对象来源、策略分组、频控和四态状态 - - 是否明确停复水/工单只作为联动边界和追溯引用 -- `03_Interface_Design.md` - - 是否统一 `IF-REV-013` 为正式业务接口编号 - - 是否区分 `IF-REV-013` 与 `IF-EXT-008` 的责任边界 -- `15_SYS002_Requirement_Breakdown.md` - - 是否保持 `SYS002-REQ-011` 为“未见实现” - - 是否明确“文档已收口,backend 未见明确实现骨架” -- `01_Project_Progress.md` / `03_Task_Checklist.md` - - 是否登记本轮文档收口与验证动作 - -## 4. 最小验证命令 - -```bash -make validate-file FILE=docs/design/02_Detailed_Design/12_REV_Detailed.md -make validate-file FILE=docs/design/03_Technical_Design/03_Interface_Design.md -make validate-file FILE=docs/design/00_Management/15_SYS002_Requirement_Breakdown.md -make check-links -make validate-mermaid -``` - -## 5. 完成判定 - -满足以下条件即可进入 `/speckit.tasks`: - -- `REV-006` 的业务规则、接口边界、历史查询和处置追溯口径已统一 -- `SYS002-REQ-011` 的实现判断与后续研发切入点已写入治理台账 -- 验证命令已纳入计划,且无新增平行正式稿 - -## 6. 2026-03-19 实施结果 - -### 已完成文档 - -- `docs/design/02_Detailed_Design/12_REV_Detailed.md` -- `docs/design/03_Technical_Design/03_Interface_Design.md` -- `docs/design/00_Management/15_SYS002_Requirement_Breakdown.md` -- `docs/design/00_Management/01_Project_Progress.md` -- `docs/design/00_Management/03_Task_Checklist.md` - -### 验证结果 - -- `make validate-file FILE=docs/design/02_Detailed_Design/12_REV_Detailed.md`:通过,0 个问题 -- `make validate-file FILE=docs/design/03_Technical_Design/03_Interface_Design.md`:通过,0 个问题 -- `make validate-file FILE=docs/design/00_Management/15_SYS002_Requirement_Breakdown.md`:通过,0 个问题 -- `make check-links`:通过,当前检查范围内未发现断链 -- `make check-mermaid-file FILE=docs/design/02_Detailed_Design/12_REV_Detailed.md`:已确认目标文件存在 6 个 Mermaid 图表 -- `make validate-mermaid`:已执行两次,但在当前环境下未返回最终结果;结合 Makefile 逻辑,该目标只校验仓库根目录 `*.md`,未直接覆盖本轮主要修改文件,后续如需全仓 Mermaid 终态结果,应单独排查该目标在当前环境中的阻塞原因 - -### 当前结论 - -- `REV-006` 已完成 implement 阶段的正式文档二次收口 -- `SYS002-REQ-011` 继续维持“未见实现”,但 Speckit 工件链、正式文档口径与治理台账已对齐 -- 当前剩余风险不是文档口径缺失,而是后续 backend 立项与 `make validate-mermaid` 全仓目标在本环境中的执行阻塞 diff --git a/specs/006-reminder-event-design/research.md b/specs/006-reminder-event-design/research.md deleted file mode 100644 index 80c15df..0000000 --- a/specs/006-reminder-event-design/research.md +++ /dev/null @@ -1,46 +0,0 @@ -# Phase 0 Research: REV-006 催缴与通知事件设计收口 - -## Decision 1: 以既有主文档承载 `REV-006` 收口 - -**Decision**: 正式设计收口继续落在 `12_REV_Detailed.md`、`03_Interface_Design.md` 与 `15_SYS002_Requirement_Breakdown.md`,不新建平行正式稿。 -**Rationale**: `REV-006` 已在概要、详设、接口与治理台账中具备入口,当前问题是规则与边界不够收敛,而不是缺少载体。继续使用主文档符合单一真源原则。 -**Alternatives considered**: - -- 新建独立“催缴设计说明书”:会制造平行正式稿,违背宪章。 -- 仅在 spec 工件中描述:无法替代正式交付文档与治理台账。 - -## Decision 2: `SYS-002` 与 `SYS-010` 按“业务侧任务控制 / 渠道侧触达执行”分界 - -**Decision**: `SYS-002` 负责催缴对象筛选、任务生成、事件编号、四态状态承接、历史查询与处置引用;`SYS-010` 负责短信、微信、站内信等渠道触达及结果回传。 -**Rationale**: 该分界已在 `12_REV_Detailed.md` 与 `03_Interface_Design.md` 形成一致表达,能够避免“催缴任务生成”和“消息发送执行”职责混写。 -**Alternatives considered**: - -- 由 `SYS-010` 同时负责催缴任务控制:会让外部系统承担业务主控,不符合现有模块分工。 -- 由 `SYS-002` 同时负责所有消息发送:会弱化 `IF-EXT-008` 的外部协同边界。 - -## Decision 3: 正式状态集固定为四态 - -**Decision**: `REV-006` 状态集固定为 `PENDING`、`SUCCESS`、`FAIL`、`MANUAL_VERIFIED`。 -**Rationale**: 四态已在详设与接口文档中同步表达,且足以覆盖受理中、成功、失败、人工补记三类核心语义。增加更多细粒度状态会放大实现假设。 -**Alternatives considered**: - -- 增加“已阅读”“已补发”等状态:超出当前正式口径,也缺少 backend 证据支持。 -- 仅保留成功/失败二态:不足以表达异步回写与人工核查场景。 - -## Decision 4: 历史催缴、停水、预存短信按只读查询口径承接 - -**Decision**: 旧系统催缴记录、停水记录、预存短信记录统一作为历史查询和追溯范围承接,不默认扩展为新系统已确认在线主表。 -**Rationale**: 当前 backend 未确认独立催缴台账、停水汇总表等实体;保守表达可同时满足迁移查询需求和事实一致性。 -**Alternatives considered**: - -- 直接定义新在线主表:缺少代码和数据库证据。 -- 完全忽略历史场景:会让迁移核查、客户历史查询和处置追溯失去正式口径。 - -## Decision 5: 当前实施结论维持“文档已收口,backend 未见明确实现骨架” - -**Decision**: 计划阶段保留 `SYS002-REQ-011` 为“未见实现”,并把本轮产出定位为文档收口和后续研发立项输入。 -**Rationale**: 现有治理文档已经给出相同结论,且当前未检索到明确的 `Reminder/Message/Notice` controller/service 骨架。 -**Alternatives considered**: - -- 升级为“部分实现”:会放大现有消息协同或历史查询描述,和证据不匹配。 -- 直接按“已实现”处理:与仓库现状冲突。 diff --git a/specs/006-reminder-event-design/spec.md b/specs/006-reminder-event-design/spec.md deleted file mode 100644 index 90bb0f7..0000000 --- a/specs/006-reminder-event-design/spec.md +++ /dev/null @@ -1,126 +0,0 @@ -# Feature Specification: REV-006 催缴与通知事件设计收口 - -**Feature Branch**: `006-reminder-event-design` -**Created**: 2026-03-18 -**Status**: Ready for Planning -**Input**: User description: "rev006-reminder-event-design" - -## Document Scope & Sources *(mandatory)* - -- **Target documents**: - - `docs/design/02_Detailed_Design/12_REV_Detailed.md` - - `docs/design/03_Technical_Design/03_Interface_Design.md` - - `docs/design/00_Management/15_SYS002_Requirement_Breakdown.md` - - `docs/design/00_Management/01_Project_Progress.md` - - `docs/design/00_Management/03_Task_Checklist.md` -- **Primary source of truth**: - - `docs/design/02_Detailed_Design/12_REV_Detailed.md` - - `docs/design/03_Technical_Design/03_Interface_Design.md` - - `docs/design/00_Management/15_SYS002_Requirement_Breakdown.md` - - `docs/design/01_Overview/03_Summary_Design.md` - - `AGENTS.md` -- **Reference sources**: - - `docs/guides/BACKEND_CURRENT_STATUS.md` - - `docs/design/04_Appendix/Archive/02_Manuals/营收系统_用户操作手册.md` - - `docs/design/04_Appendix/Archive/03_Design_Docs/营业收费管理系统-概要设计说明书20250912.md` -- **Scope decision**: In scope. 本 feature 聚焦 `REV-006` 催缴与通知的正式设计收口,补齐催缴对象生成、任务分组、`IF-REV-013` / `IF-EXT-008` 协同边界、四态状态语义、历史查询口径、停复水/工单联动追溯和后续研发立项输入;不在本轮直接承诺 backend 已落地催缴业务实现。 - -## User Scenarios & Testing *(mandatory)* - -### User Story 1 - 收口催缴任务生成规则 (Priority: P1) - -作为文档维护者,我需要把 `REV-006` 的催缴触发时机、催缴对象筛选条件、策略分组规则和四态状态定义写清楚,使评审者能够明确欠费账单如何进入催缴任务,以及哪些场景属于自动催缴、人工补发或人工核查补记。 - -**Why this priority**: 当前 `REV-006` 已有第一轮场景描述,但后续研发立项仍依赖更清晰的触发规则、筛选条件和状态语义。 - -**Independent Test**: 单独评审 `12_REV_Detailed.md` 中 `REV-006` 章节,应能明确催缴对象来源、触发规则、四态状态和人工核查边界。 - -**Acceptance Scenarios**: - -1. **Given** 当前文档只概括“按策略分组催缴任务”, **When** 评审者阅读补齐后的详细设计, **Then** 能明确欠费账单、账龄、金额、客户类别、渠道偏好和频控规则如何形成催缴对象与任务。 -2. **Given** 后续需要据此拆解研发任务, **When** 维护者依据该规格评估实现切入点, **Then** 能区分自动催缴、人工补发、人工核查补记和停复水联动的边界。 - ---- - -### User Story 2 - 统一 IF-REV-013 与消息协同边界 (Priority: P2) - -作为接口设计评审者,我需要看到 `IF-REV-013` 和 `IF-EXT-008` 的职责分工、请求输出、回写字段和四态结果承接口径,使 `SYS-002` 与 `SYS-010` 的边界不再停留在抽象表述。 - -**Why this priority**: `REV-006` 的核心风险在于业务筛选、任务状态承接和外部通知执行边界不清,容易出现“任务生成”和“消息发送”职责混写。 - -**Independent Test**: 单独评审接口主文档和需求拆解台账,应能确认 `IF-REV-013` 的业务侧职责、`IF-EXT-008` 的外部协同职责以及四态回写字段。 - -**Acceptance Scenarios**: - -1. **Given** 评审者查看接口设计, **When** 阅读 `IF-REV-013` 章节, **Then** 能明确任务生成、任务查询、人工核查和结果承接的请求路径、字段与状态语义。 -2. **Given** 评审者查看需求拆解文档, **When** 阅读 `SYS002-REQ-011` 对应内容, **Then** 能明确当前属于“设计已收口、实现未见骨架”的状态,而不是误判为已实现。 - ---- - -### User Story 3 - 形成治理与研发切入结论 (Priority: P3) - -作为后续立项和治理跟踪人员,我需要在台账和进度记录中看到 `REV-006` 的当前结论、最小实现切入点和校验动作,避免文档收口后仍无法指导后续研发排期。 - -**Why this priority**: `REV-006` 当前在治理台账中属于未见实现,需要通过本轮 feature 明确“文档先行、实现待立项”的真实结论和后续切入点。 - -**Independent Test**: 单独检查治理文档,应能定位 `REV-006` 当前状态、最小研发切入点、台账同步动作和验证要求。 - -**Acceptance Scenarios**: - -1. **Given** 项目需要安排后续研发排期, **When** 查看需求拆解和项目进度, **Then** 能明确 `REV-006` 当前是设计收口完成、backend 未见明确实现骨架、可继续立项推进的状态。 -2. **Given** 本轮完成正式文档修订, **When** 查看进度与任务清单, **Then** 能定位本次 `REV-006` 文档治理动作及其最小校验结果。 - ---- - -### Edge Cases - -- 当欠费账单已被收费、作废或进入其他处置流程时,催缴对象是否仍可进入任务生成,文档必须如何表达排除条件? -- 当 `SYS-010` 只返回发送受理结果而未立即返回终态时,四态状态如何在 `SYS-002` 侧保持一致? -- 当旧系统存在催缴记录、停水记录和预存短信等历史查询场景,但当前 backend 未确认独立落表时,文档如何保持“历史只读承接”而不误写为现成在线表? -- 当人工核查补记场景发生时,哪些字段必须记录核查说明、关联任务号和后续处置引用? - -## Requirements *(mandatory)* - -### Functional Requirements - -- **FR-001**: Specification MUST identify the exact target documents for `REV-006` reminder-event alignment and governance sync. -- **FR-002**: Specification MUST identify `12_REV_Detailed.md`、`03_Interface_Design.md`、`15_SYS002_Requirement_Breakdown.md` as the main source-of-truth set for this feature. -- **FR-003**: Specification MUST record that this feature is in scope only for reminder-candidate generation, task rules, `IF-REV-013` / `IF-EXT-008` interface boundary, four-state result semantics, historical query boundary, and governance sync. -- **FR-004**: Specification MUST preserve the single-source-of-truth model and MUST NOT create a parallel formal design document for `REV-006`. -- **FR-005**: Specification MUST define reminder-candidate selection conditions, including arrears status, aging, amount, customer category, channel preference, strategy grouping, and frequency-control boundary. -- **FR-006**: Specification MUST define the formal four-state reminder result set as `PENDING`、`SUCCESS`、`FAIL`、`MANUAL_VERIFIED`, including the intended meaning of each state. -- **FR-007**: Specification MUST define the exact business boundary of `IF-REV-013`, including task generation, task query, manual verification, result acceptance, and historical query support. -- **FR-008**: Specification MUST define the external collaboration boundary of `IF-EXT-008`, clarifying that `SYS-010` is responsible for channel delivery while `SYS-002` retains business-side task and state control. -- **FR-009**: Specification MUST define the minimum write-back and traceability fields for reminder results, including task number, event number, strategy code, channel type, trigger type, status, failure reason, and disposal reference. -- **FR-010**: Specification MUST define how reminder results link to stop-water, restore-water, work-order, or manual follow-up references without expanding those downstream internal workflows. -- **FR-011**: Specification MUST define historical query and export expectations for reminder records, including customer, bill period, reminder channel, target receiver, send time, execution result, related bills, and disposal references. -- **FR-012**: Specification MUST explicitly capture the current implementation judgment as “文档已收口,backend 未见明确催缴/通知业务实现骨架” unless stronger evidence is found later. -- **FR-013**: Specification MUST identify the minimum validation actions after document updates, including affected file validation, link checks, and Mermaid checks where flows are updated. -- **FR-014**: Specification MUST state that important formal document changes under this feature require synchronized updates to `01_Project_Progress.md` and `03_Task_Checklist.md`. - -### Assumptions - -- 本 feature 以正式文档收口和后续研发立项准备为目标,默认不在本轮直接承诺 backend 业务代码实现。 -- `IF-REV-013` 继续作为 `REV-006` 的正式业务接口编号,不复用其他 `IF-REV-*` 编号。 -- `SYS-010` 负责短信、微信公众号、站内信等触达执行;`SYS-002` 保留催缴对象筛选、任务生成、四态状态承接和历史查询职责。 -- 当前 backend 中未见明确的 `Reminder/Message/Notice` 业务控制器或服务骨架,因此实现状态保持“未见实现”。 -- 催缴记录、停复水记录和预存短信等历史场景在本轮按“历史只读查询口径”承接,不默认要求新建平行在线主表。 - -### Key Entities *(include if feature involves data)* - -- **Reminder Candidate**: 由欠费账单、账龄、欠费金额、客户类别、联系方式和命中策略组成的催缴输入对象。 -- **Reminder Strategy**: 定义账龄规则、金额规则、客户类别规则、渠道优先级、频控策略和后续联动关注条件的策略对象。 -- **Reminder Task**: 一次正式催缴执行单元,至少包含 `taskNo`、`eventNo`、`strategyCode`、`channelType`、`triggerType`、`status` 和关联账单集合。 -- **Reminder Result**: 催缴任务的四态结果及其失败原因、执行时间、外部回写摘要和业务侧处置引用。 -- **Disposal Link**: 催缴结果与停复水、工单、人工核查等后续处置之间的追溯引用对象。 -- **Governance Record**: 用于在需求拆解、项目进度和任务清单中登记本轮 `REV-006` 收口结论和后续研发建议的治理记录。 - -## Success Criteria *(mandatory)* - -### Measurable Outcomes - -- **SC-001**: 评审者可在 5 分钟内从规格中定位 `REV-006` 的目标文档、催缴对象生成规则、接口边界和排除项。 -- **SC-002**: 规格中至少覆盖 3 类独立可评审内容:催缴任务生成规则、`IF-REV-013` / `IF-EXT-008` 边界、治理与研发切入结论。 -- **SC-003**: 规格明确区分至少 6 项关键任务或结果要素,如 `taskNo`、`eventNo`、`strategyCode`、`channelType`、`triggerType`、`status`、失败原因、处置引用。 -- **SC-004**: 后续执行 `/speckit.plan` 时,规划者无需再补充范围澄清即可将工作拆分为详细设计收口、接口收口、治理同步和实现切入点评估四类任务。 -- **SC-005**: 规格明确列出全部必要验证动作,审阅者可直接据此执行至少 4 项文档校验或一致性检查。 diff --git a/specs/006-reminder-event-design/tasks.md b/specs/006-reminder-event-design/tasks.md deleted file mode 100644 index cbf7a74..0000000 --- a/specs/006-reminder-event-design/tasks.md +++ /dev/null @@ -1,164 +0,0 @@ -# Tasks: REV-006 催缴与通知事件设计收口 - -**Input**: Design documents from `/specs/006-reminder-event-design/` -**Prerequisites**: `plan.md` (required), `spec.md` (required), `research.md`, `data-model.md`, `contracts/`, `quickstart.md` - -**Validation**: Validation tasks are NOT optional in this repository. Every document change task set includes applicable validation and ledger-sync tasks. - -**Organization**: Tasks are grouped by user story so each document-maintenance slice can be completed, reviewed, and validated independently. - -## Format: `[ID] [P?] [Story] Description` - -- **[P]**: Can run in parallel (different files, no dependencies) -- **[Story]**: Which user story this task belongs to (`US1`, `US2`, `US3`) -- Every task names the exact file path to update or validate - -## Phase 1: Setup - -**Purpose**: Confirm the working boundary, source-of-truth set, and impacted files before editing formal documents. - -- [x] T001 Confirm target files and impacted chapters in `/Volumes/Dpan/github/fujian_water_biz_doc/specs/006-reminder-event-design/spec.md` -- [x] T002 Confirm source-of-truth and allowed references in `/Volumes/Dpan/github/fujian_water_biz_doc/specs/006-reminder-event-design/plan.md` and `/Volumes/Dpan/github/fujian_water_biz_doc/specs/006-reminder-event-design/research.md` -- [x] T003 [P] Confirm entity and contract inputs in `/Volumes/Dpan/github/fujian_water_biz_doc/specs/006-reminder-event-design/data-model.md`, `/Volumes/Dpan/github/fujian_water_biz_doc/specs/006-reminder-event-design/contracts/if-rev-013.md`, and `/Volumes/Dpan/github/fujian_water_biz_doc/specs/006-reminder-event-design/contracts/if-ext-008.md` -- [x] T004 [P] Confirm governance sync targets in `/Volumes/Dpan/github/fujian_water_biz_doc/docs/design/00_Management/01_Project_Progress.md`, `/Volumes/Dpan/github/fujian_water_biz_doc/docs/design/00_Management/03_Task_Checklist.md`, and `/Volumes/Dpan/github/fujian_water_biz_doc/docs/design/00_Management/15_SYS002_Requirement_Breakdown.md` - ---- - -## Phase 2: Foundational - -**Purpose**: Establish the shared editing baseline that all user stories depend on. - -- [x] T005 Normalize `REV-006`, `IF-REV-013`, `IF-EXT-008`, and four-state terminology alignment notes in `/Volumes/Dpan/github/fujian_water_biz_doc/specs/006-reminder-event-design/plan.md` -- [x] T006 Identify exact `REV-006` anchors, Mermaid scope, and cross-reference touchpoints in `/Volumes/Dpan/github/fujian_water_biz_doc/docs/design/02_Detailed_Design/12_REV_Detailed.md` and `/Volumes/Dpan/github/fujian_water_biz_doc/docs/design/03_Technical_Design/03_Interface_Design.md` -- [x] T007 Map governance evidence and current implementation conclusion for `SYS002-REQ-011` in `/Volumes/Dpan/github/fujian_water_biz_doc/docs/design/00_Management/15_SYS002_Requirement_Breakdown.md` - ---- - -## Phase 3: User Story 1 - 收口催缴任务生成规则 (Priority: P1) 🎯 MVP - -**Goal**: 补齐 `REV-006` 在详细设计中的催缴对象生成、策略分组、频控边界、四态状态和历史只读承接口径。 - -**Independent Test**: 单独评审 `/Volumes/Dpan/github/fujian_water_biz_doc/docs/design/02_Detailed_Design/12_REV_Detailed.md` 的 `REV-006` 章节,应能明确催缴对象来源、排除条件、四态状态、人工核查边界和停复水联动追溯关系。 - -### Implementation for User Story 1 - -- [x] T008 [US1] Update `REV-006` rules, candidate selection, frequency-control, and exclusion conditions in `/Volumes/Dpan/github/fujian_water_biz_doc/docs/design/02_Detailed_Design/12_REV_Detailed.md` -- [x] T009 [US1] Sync `Reminder Candidate`, `Reminder Task`, `Reminder Result`, and `Disposal Link` field coverage in `/Volumes/Dpan/github/fujian_water_biz_doc/docs/design/02_Detailed_Design/12_REV_Detailed.md` using `/Volumes/Dpan/github/fujian_water_biz_doc/specs/006-reminder-event-design/data-model.md` -- [x] T010 [US1] Align historical reminder, stop-water, and prestored-message read-only boundary wording in `/Volumes/Dpan/github/fujian_water_biz_doc/docs/design/02_Detailed_Design/12_REV_Detailed.md` -- [x] T011 [US1] Run `make validate-file FILE=docs/design/02_Detailed_Design/12_REV_Detailed.md` and record the result in `/Volumes/Dpan/github/fujian_water_biz_doc/specs/006-reminder-event-design/quickstart.md` -- [x] T012 [US1] Run `make validate-mermaid` for `/Volumes/Dpan/github/fujian_water_biz_doc/docs/design/02_Detailed_Design/12_REV_Detailed.md` flow updates and record the result in `/Volumes/Dpan/github/fujian_water_biz_doc/specs/006-reminder-event-design/quickstart.md` - -**Checkpoint**: User Story 1 is reviewable and validated independently. - ---- - -## Phase 4: User Story 2 - 统一 IF-REV-013 与消息协同边界 (Priority: P2) - -**Goal**: 在接口主文档中统一 `IF-REV-013` 与 `IF-EXT-008` 的职责分工、输入输出、四态回写和失败阻断语义。 - -**Independent Test**: 单独评审 `/Volumes/Dpan/github/fujian_water_biz_doc/docs/design/03_Technical_Design/03_Interface_Design.md`,应能区分 `SYS-002` 的业务任务控制职责与 `SYS-010` 的渠道触达职责,并定位最小回写字段。 - -### Implementation for User Story 2 - -- [x] T013 [US2] Update `IF-REV-013` business boundary, request paths, and state semantics in `/Volumes/Dpan/github/fujian_water_biz_doc/docs/design/03_Technical_Design/03_Interface_Design.md` -- [x] T014 [US2] Update `IF-EXT-008` collaboration boundary, acceptance/callback semantics, and failure mapping in `/Volumes/Dpan/github/fujian_water_biz_doc/docs/design/03_Technical_Design/03_Interface_Design.md` -- [x] T015 [US2] [P] Sync minimum traceability fields and manual-verify/write-back semantics in `/Volumes/Dpan/github/fujian_water_biz_doc/docs/design/03_Technical_Design/03_Interface_Design.md` using `/Volumes/Dpan/github/fujian_water_biz_doc/specs/006-reminder-event-design/contracts/if-rev-013.md` -- [x] T016 [US2] Run `make validate-file FILE=docs/design/03_Technical_Design/03_Interface_Design.md` and record the result in `/Volumes/Dpan/github/fujian_water_biz_doc/specs/006-reminder-event-design/quickstart.md` -- [x] T017 [US2] Run `make check-links` after interface document updates and record the result in `/Volumes/Dpan/github/fujian_water_biz_doc/specs/006-reminder-event-design/quickstart.md` - -**Checkpoint**: User Story 2 is reviewable and validated independently. - ---- - -## Phase 5: User Story 3 - 形成治理与研发切入结论 (Priority: P3) - -**Goal**: 在需求拆解和管理台账中沉淀 `REV-006` 的当前状态、最小研发切入点、文档收口动作和验证结论。 - -**Independent Test**: 单独评审 `/Volumes/Dpan/github/fujian_water_biz_doc/docs/design/00_Management/15_SYS002_Requirement_Breakdown.md`、`/Volumes/Dpan/github/fujian_water_biz_doc/docs/design/00_Management/01_Project_Progress.md`、`/Volumes/Dpan/github/fujian_water_biz_doc/docs/design/00_Management/03_Task_Checklist.md`,应能定位 `SYS002-REQ-011` 的“未见实现”判断、本轮文档收口和后续研发建议。 - -### Implementation for User Story 3 - -- [x] T018 [US3] Update `SYS002-REQ-011` implementation judgment, evidence wording, and next-step recommendation in `/Volumes/Dpan/github/fujian_water_biz_doc/docs/design/00_Management/15_SYS002_Requirement_Breakdown.md` -- [x] T019 [US3] Update the REV-006 change record and validation summary in `/Volumes/Dpan/github/fujian_water_biz_doc/docs/design/00_Management/01_Project_Progress.md` -- [x] T020 [US3] Update the REV-006 governance completion items in `/Volumes/Dpan/github/fujian_water_biz_doc/docs/design/00_Management/03_Task_Checklist.md` -- [x] T021 [US3] Run `make validate-file FILE=docs/design/00_Management/15_SYS002_Requirement_Breakdown.md` and record the result in `/Volumes/Dpan/github/fujian_water_biz_doc/specs/006-reminder-event-design/quickstart.md` -- [x] T022 [US3] Re-check that `/Volumes/Dpan/github/fujian_water_biz_doc/docs/design/00_Management/01_Project_Progress.md` and `/Volumes/Dpan/github/fujian_water_biz_doc/docs/design/00_Management/03_Task_Checklist.md` reflect the same REV-006 closure status - -**Checkpoint**: User Story 3 is reviewable and validated independently. - ---- - -## Final Phase: Polish & Cross-Cutting Concerns - -**Purpose**: Ensure repository-wide consistency after all story slices are complete. - -- [x] T023 [P] Re-check `REV-006`, `IF-REV-013`, `IF-EXT-008`, and four-state terminology consistency across `/Volumes/Dpan/github/fujian_water_biz_doc/docs/design/02_Detailed_Design/12_REV_Detailed.md`, `/Volumes/Dpan/github/fujian_water_biz_doc/docs/design/03_Technical_Design/03_Interface_Design.md`, and `/Volumes/Dpan/github/fujian_water_biz_doc/docs/design/00_Management/15_SYS002_Requirement_Breakdown.md` -- [x] T024 [P] Re-check relative links, anchors, and Mermaid consistency across `/Volumes/Dpan/github/fujian_water_biz_doc/docs/design/02_Detailed_Design/12_REV_Detailed.md`, `/Volumes/Dpan/github/fujian_water_biz_doc/docs/design/03_Technical_Design/03_Interface_Design.md`, `/Volumes/Dpan/github/fujian_water_biz_doc/docs/design/00_Management/01_Project_Progress.md`, and `/Volumes/Dpan/github/fujian_water_biz_doc/docs/design/00_Management/03_Task_Checklist.md` -- [x] T025 Prepare final delivery summary and remaining-risk note in `/Volumes/Dpan/github/fujian_water_biz_doc/specs/006-reminder-event-design/quickstart.md` - ---- - -## Dependencies & Execution Order - -### Phase Dependencies - -- **Setup**: No dependencies; must finish before document edits -- **Foundational**: Depends on Setup and must finish before user story execution -- **US1**: Depends on Foundational and is the MVP slice -- **US2**: Depends on US1 terminology and boundary baseline -- **US3**: Depends on US1 and US2 conclusions so governance wording can reflect final design state -- **Final Phase**: Depends on all selected user stories being complete - -### User Story Dependency Graph - -```text -US1 -> US2 -> US3 - \______________-> Final Phase -``` - -### Within Each User Story - -- Update target document content before running validation -- Complete validation before marking governance sync as done -- Complete ledger sync before final cross-check - -## Parallel Execution Examples - -### US1 - -```text -T008 -> T009 -T010 can run after T008 in parallel with T009 -``` - -### US2 - -```text -T013 -> T014 -T015 can run in parallel once T013 and T014 establish the final interface wording -``` - -### US3 - -```text -T019 and T020 can run in parallel after T018 -``` - -## Implementation Strategy - -### MVP First - -先完成 US1,只收口 `12_REV_Detailed.md` 的 `REV-006` 规则与状态语义,形成最小可评审增量。 - -### Incremental Delivery - -1. 用 US1 固化催缴对象、四态状态和历史只读边界。 -2. 用 US2 固化 `IF-REV-013` / `IF-EXT-008` 的接口职责与回写语义。 -3. 用 US3 回写治理台账和后续研发切入点。 -4. 最后统一做跨文档一致性复核和交付摘要。 - -## Notes - -- 所有任务均保持“主文档单一真源”原则,不新增平行正式稿。 -- Archive 只用于核对来源,不作为正式结论直接输出。 -- 本任务清单面向文档实施,不默认包含 backend 代码开发任务。 diff --git a/specs/008-rev004-legacy-finance-migration/plan.md b/specs/008-rev004-legacy-finance-migration/plan.md index f52db6d..fb019bb 100644 --- a/specs/008-rev004-legacy-finance-migration/plan.md +++ b/specs/008-rev004-legacy-finance-migration/plan.md @@ -38,7 +38,7 @@ - `docs/guides/BACKEND_TABLE_MAPPING.md` **Reference Sources**: - `docs/design/04_Appendix/Archive/05_Data_Dictionary/营收数据字典.md` -- `docs/guides/REV004_LEGACY_FINANCE_MIGRATION_PLAN_V0.md` +- `docs/evidence/rev004-accounting/REV004_LEGACY_FINANCE_MIGRATION_PLAN_V0.md` - `docs/design/00_Management/07_Migration_Mapping_Template.md` - `water-backend/sw-business/.../ChargeController.java` - `water-backend/sw-business/.../ChargeServiceImpl.java` @@ -97,7 +97,7 @@ specs/008-rev004-legacy-finance-migration/ ```text water-docs/ ├── docs/design/ -├── docs/guides/REV004_LEGACY_FINANCE_MIGRATION_PLAN_V0.md +├── docs/evidence/rev004-accounting/REV004_LEGACY_FINANCE_MIGRATION_PLAN_V0.md ├── docs/guides/BACKEND_TABLE_MAPPING.md └── .specify/ diff --git a/specs/008-rev004-legacy-finance-migration/spec.md b/specs/008-rev004-legacy-finance-migration/spec.md index 4b26c31..38a10e1 100644 --- a/specs/008-rev004-legacy-finance-migration/spec.md +++ b/specs/008-rev004-legacy-finance-migration/spec.md @@ -8,7 +8,7 @@ ## Document Scope & Sources *(mandatory)* - **Target documents**: - - `docs/guides/REV004_LEGACY_FINANCE_MIGRATION_PLAN_V0.md` + - `docs/evidence/rev004-accounting/REV004_LEGACY_FINANCE_MIGRATION_PLAN_V0.md` - `docs/design/02_Detailed_Design/12_REV_Detailed.md` - `docs/design/03_Technical_Design/03_Interface_Design.md` - `docs/design/03_Technical_Design/01_Database_Design.md` @@ -26,7 +26,7 @@ - `.specify/memory/constitution.md` - **Reference sources**: - `docs/design/04_Appendix/Archive/05_Data_Dictionary/营收数据字典.md` - - `docs/guides/REV004_LEGACY_FINANCE_MIGRATION_PLAN_V0.md` + - `docs/evidence/rev004-accounting/REV004_LEGACY_FINANCE_MIGRATION_PLAN_V0.md` - `docs/design/00_Management/07_Migration_Mapping_Template.md` - `docs/design/04_Appendix/Archive/03_Design_Docs/营业收费管理系统-概要设计说明书20250912.md` - **Scope decision**: In scope。本轮聚焦 `REV-004` 旧账务模型迁移规划,明确迁移映射如何形成、哪些旧对象进入在线主模型、哪些仅保留历史只读、以及当前 backend 相对旧模型存在的功能缺失;本轮不直接执行数据迁移脚本,不进入 backend 代码改造。 diff --git a/specs/009-openguass-to-pg16-migration/spec.md b/specs/009-openguass-to-pg16-migration/spec.md new file mode 100644 index 0000000..24f514f --- /dev/null +++ b/specs/009-openguass-to-pg16-migration/spec.md @@ -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)* + + + +### 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. diff --git a/specs/012-xlsx-export-unification/spec.md b/specs/012-xlsx-export-unification/spec.md new file mode 100644 index 0000000..d758e44 --- /dev/null +++ b/specs/012-xlsx-export-unification/spec.md @@ -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` 的高风险操作。 \ No newline at end of file diff --git a/sql/rev004_account_adjust_dict_seed.sql b/sql/rev004_account_adjust_dict_seed.sql index 981bb3b..f44f526 100644 --- a/sql/rev004_account_adjust_dict_seed.sql +++ b/sql/rev004_account_adjust_dict_seed.sql @@ -3,6 +3,7 @@ -- Purpose: -- 1) Reuse existing legacy reason/type/proc/business dictionaries -- 2) Add the minimal new dictionaries needed for REV004 object/status semantics +-- 3) Sync work_status because REV004 accountProcess already depends on the code-side four-state contract -- Note: -- This script is idempotent by (type) and (dict_type, value) checks. @@ -18,7 +19,8 @@ FROM (VALUES ('账务调整对象类型', 'account_adjust_object_type', 'REV004 objectType 字典'), ('账务调整结果状态', 'account_adjust_result_status', 'REV004 resultStatus 字典'), ('账务调整审批状态', 'account_adjust_approval_status', 'REV004 approvalStatus 字典'), - ('账务调整回写状态', 'account_adjust_writeback_status', 'REV004 writeBackStatus 字典') + ('账务调整回写状态', 'account_adjust_writeback_status', 'REV004 writeBackStatus 字典'), + ('工单状态', 'work_status', 'REV004/accountProcess 依赖的工单状态字典') ) AS v(name, type, remark) WHERE NOT EXISTS ( SELECT 1 FROM system_dict_type t WHERE t.type = v.type AND t.deleted = 0 @@ -60,7 +62,13 @@ FROM (VALUES -- account_adjust_writeback_status (10, '已回写', 'UPDATED', 'account_adjust_writeback_status', 'success', '', 'REV004 writeBackStatus'), (20, '待回写', 'PENDING', 'account_adjust_writeback_status', 'warning', '', 'REV004 writeBackStatus'), - (30, '已跳过', 'SKIPPED', 'account_adjust_writeback_status', 'default', '', 'REV004 writeBackStatus') + (30, '已跳过', 'SKIPPED', 'account_adjust_writeback_status', 'default', '', 'REV004 writeBackStatus'), + + -- work_status + (10, '未处理', '0', 'work_status', 'default', '', '工单创建,待审核/待处理'), + (20, '已审核', '1', 'work_status', 'warning', '', '审核通过或无需审批,待完成'), + (30, '已完成', '2', 'work_status', 'success', '', '处理成功且已回写完成'), + (40, '已撤销', '3', 'work_status', 'info', '', '工单已撤销') ) AS v(sort, label, value, dict_type, color_type, css_class, remark) WHERE NOT EXISTS ( SELECT 1 diff --git a/superpowers/plans/2026-06-10-unsold-adjust-bpm.md b/superpowers/plans/2026-06-10-unsold-adjust-bpm.md new file mode 100644 index 0000000..6ab60a8 --- /dev/null +++ b/superpowers/plans/2026-06-10-unsold-adjust-bpm.md @@ -0,0 +1,790 @@ +# Unsold Adjustment BPM Workflow Integration + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Wire BPM approval flows into 5 unsold adjustment types (split, bad debt, writtenoff, price diff, late fee reduce) that currently only set PENDING_APPROVAL flags without creating actual BPM process instances. + +**Architecture:** Follow the existing prestorage adjust BPM pattern — Internal API (Feign) in sw-business-api, implementation in sw-business-server, BPM ProcessInit/BusinessBridge/ApprovalListener/Controller/VOs in sw-module-bpm. Frontend forms switch from calling `/business/accounting-adjust/unsold-*-submit` to calling new `/bpm/*-adjust/create` endpoints. + +**Tech Stack:** Java 17, Spring Boot, Feign, MyBatis-Plus, Vue 3 + Element Plus + +**Pattern reference:** Prestorage adjust files in sw-module-bpm/service/prestorageadjust/ and sw-business/api/accountingadjust/PrestorageAdjustInternalApi.java + +--- + +## Shared Infrastructure (once) + +### Task 0: Create shared execute DTO + +**Files:** +- Create: `sw-business/sw-business-api/src/main/java/cn/com/emsoft/sw/business/api/accountingadjust/dto/AdjustExecuteReqDTO.java` +- Create: `sw-business/sw-business-api/src/main/java/cn/com/emsoft/sw/business/api/accountingadjust/dto/AdjustExecuteRespDTO.java` + +- [ ] **Step 1: Create AdjustExecuteReqDTO** + +```java +package cn.com.emsoft.sw.business.api.accountingadjust.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class AdjustExecuteReqDTO { + private String adjustmentNo; + private String approvalStatus; // APPROVE / REJECT + private String approvalComment; + private String operatorId; +} +``` + +- [ ] **Step 2: Create AdjustExecuteRespDTO** + +```java +package cn.com.emsoft.sw.business.api.accountingadjust.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class AdjustExecuteRespDTO { + private String resultStatus; // SUCCESS / FAILED / SKIPPED + private String adjustmentNo; + private String message; +} +``` + +- [ ] **Step 3: Commit** + +```bash +git add sw-business/sw-business-api/src/main/java/cn/com/emsoft/sw/business/api/accountingadjust/dto/AdjustExecuteReqDTO.java \ + sw-business/sw-business-api/src/main/java/cn/com/emsoft/sw/business/api/accountingadjust/dto/AdjustExecuteRespDTO.java +git commit -m "feat: add shared execute DTOs for BPM approval callbacks" +``` + +--- + +## Type 1: Split Adjust (分账调整) + +### Task 1.1: Split Adjust Internal API + DTOs + +**Files:** +- Create: `sw-business/sw-business-api/src/main/java/cn/com/emsoft/sw/business/api/accountingadjust/dto/SplitAdjustCreateReqDTO.java` +- Create: `sw-business/sw-business-api/src/main/java/cn/com/emsoft/sw/business/api/accountingadjust/dto/SplitAdjustCreateRespDTO.java` +- Create: `sw-business/sw-business-api/src/main/java/cn/com/emsoft/sw/business/api/accountingadjust/SplitAdjustInternalApi.java` + +- [ ] **Step 1: Create SplitAdjustCreateReqDTO** + +```java +package cn.com.emsoft.sw.business.api.accountingadjust.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import java.math.BigDecimal; +import java.util.List; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SplitAdjustCreateReqDTO { + private Long sourceChargeId; + private Integer splitCount; + private List splitItems; + private String reasonCode; + private String remark; + private String applicant; + private String contactMobile; + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class SplitWaterItem { + private Integer seqNo; + private BigDecimal splitWater; + } +} +``` + +- [ ] **Step 2: Create SplitAdjustCreateRespDTO** + +```java +package cn.com.emsoft.sw.business.api.accountingadjust.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SplitAdjustCreateRespDTO { + private String splitAdjustNo; +} +``` + +- [ ] **Step 3: Create SplitAdjustInternalApi** + +```java +package cn.com.emsoft.sw.business.api.accountingadjust; + +import cn.com.emsoft.sw.business.api.accountingadjust.dto.AdjustExecuteReqDTO; +import cn.com.emsoft.sw.business.api.accountingadjust.dto.AdjustExecuteRespDTO; +import cn.com.emsoft.sw.business.api.accountingadjust.dto.SplitAdjustCreateReqDTO; +import cn.com.emsoft.sw.business.api.accountingadjust.dto.SplitAdjustCreateRespDTO; +import cn.com.emsoft.sw.framework.common.pojo.CommonResult; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; + +@FeignClient(name = cn.com.emsoft.sw.business.enums.ApiConstants.NAME) +@RequestMapping("/internal/split-adjust") +public interface SplitAdjustInternalApi { + + @PostMapping("/create") + CommonResult create(@RequestBody SplitAdjustCreateReqDTO reqDTO); + + @PostMapping("/execute") + CommonResult execute(@RequestBody AdjustExecuteReqDTO reqDTO); +} +``` + +- [ ] **Step 4: Commit** + +```bash +git add sw-business/sw-business-api/src/main/java/cn/com/emsoft/sw/business/api/accountingadjust/dto/SplitAdjustCreateReqDTO.java \ + sw-business/sw-business-api/src/main/java/cn/com/emsoft/sw/business/api/accountingadjust/dto/SplitAdjustCreateRespDTO.java \ + sw-business/sw-business-api/src/main/java/cn/com/emsoft/sw/business/api/accountingadjust/SplitAdjustInternalApi.java +git commit -m "feat: add SplitAdjustInternalApi for BPM workflow integration" +``` + +### Task 1.2: Split Adjust Internal API Implementation + +**Files:** +- Create: `sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/api/accountingadjust/SplitAdjustInternalApiImpl.java` +- Modify: `sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/service/splitadjust/SplitAdjustServiceImpl.java` (add execute method) + +- [ ] **Step 1: Create SplitAdjustInternalApiImpl** + +```java +package cn.com.emsoft.sw.business.api.accountingadjust; + +import cn.com.emsoft.sw.business.api.accountingadjust.dto.AdjustExecuteReqDTO; +import cn.com.emsoft.sw.business.api.accountingadjust.dto.AdjustExecuteRespDTO; +import cn.com.emsoft.sw.business.api.accountingadjust.dto.SplitAdjustCreateReqDTO; +import cn.com.emsoft.sw.business.api.accountingadjust.dto.SplitAdjustCreateRespDTO; +import cn.com.emsoft.sw.business.controller.admin.splitadjust.vo.SplitAdjustSubmitReqVO; +import cn.com.emsoft.sw.business.service.splitadjust.SplitAdjustService; +import cn.com.emsoft.sw.framework.common.pojo.CommonResult; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.RestController; + +import static cn.com.emsoft.sw.framework.common.pojo.CommonResult.success; + +@Slf4j +@RestController +public class SplitAdjustInternalApiImpl implements SplitAdjustInternalApi { + + @Resource + private SplitAdjustService splitAdjustService; + + @Override + public CommonResult create(SplitAdjustCreateReqDTO reqDTO) { + SplitAdjustSubmitReqVO vo = new SplitAdjustSubmitReqVO(); + vo.setSourceChargeId(reqDTO.getSourceChargeId()); + vo.setSplitCount(reqDTO.getSplitCount()); + vo.setReasonCode(reqDTO.getReasonCode()); + vo.setRemark(reqDTO.getRemark()); + vo.setApplicant(reqDTO.getApplicant()); + vo.setContactMobile(reqDTO.getContactMobile()); + if (reqDTO.getSplitItems() != null) { + vo.setSplitItems(reqDTO.getSplitItems().stream().map(item -> { + SplitAdjustSubmitReqVO.SplitWaterItem voItem = new SplitAdjustSubmitReqVO.SplitWaterItem(); + voItem.setSeqNo(item.getSeqNo()); + voItem.setSplitWater(item.getSplitWater()); + return voItem; + }).toList()); + } + var resp = splitAdjustService.submit(vo); + return success(SplitAdjustCreateRespDTO.builder() + .splitAdjustNo(resp.getSplitAdjustNo()) + .build()); + } + + @Override + public CommonResult execute(AdjustExecuteReqDTO reqDTO) { + log.info("分账调整审批结果处理: splitAdjustNo={}, approvalStatus={}", + reqDTO.getAdjustmentNo(), reqDTO.getApprovalStatus()); + var resp = splitAdjustService.executeApproval(reqDTO.getAdjustmentNo(), + reqDTO.getApprovalStatus(), reqDTO.getApprovalComment()); + return success(AdjustExecuteRespDTO.builder() + .resultStatus(resp.getResultStatus()) + .adjustmentNo(reqDTO.getAdjustmentNo()) + .message(resp.getMessage()) + .build()); + } +} +``` + +- [ ] **Step 2: Add executeApproval to SplitAdjustService interface** + +In `SplitAdjustService.java`, add: + +```java +SplitAdjustExecuteRespVO executeApproval(String splitAdjustNo, String approvalStatus, String approvalComment); +``` + +Add the VO: + +```java +// SplitAdjustExecuteRespVO.java +package cn.com.emsoft.sw.business.controller.admin.splitadjust.vo; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SplitAdjustExecuteRespVO { + private String resultStatus; + private String message; +} +``` + +- [ ] **Step 3: Implement executeApproval in SplitAdjustServiceImpl** + +In `SplitAdjustServiceImpl.java`, add: + +```java +@Override +public SplitAdjustExecuteRespVO executeApproval(String splitAdjustNo, String approvalStatus, String approvalComment) { + SplitAdjustDO record = splitAdjustFormalizationService.getBySplitAdjustNo(splitAdjustNo); + if (record == null) { + return SplitAdjustExecuteRespVO.builder() + .resultStatus("FAILED") + .message("分账单不存在: " + splitAdjustNo) + .build(); + } + if ("REJECT".equals(approvalStatus)) { + splitAdjustFormalizationService.markRejected(splitAdjustNo, approvalComment); + return SplitAdjustExecuteRespVO.builder() + .resultStatus("SUCCESS").message("审批拒绝,已标记").build(); + } + if (!"APPROVE".equals(approvalStatus)) { + return SplitAdjustExecuteRespVO.builder() + .resultStatus("SKIPPED").message("非终态审批").build(); + } + try { + splitAdjustFormalizationService.executeSplit(splitAdjustNo); + return SplitAdjustExecuteRespVO.builder() + .resultStatus("SUCCESS").message("分账执行成功").build(); + } catch (Exception e) { + return SplitAdjustExecuteRespVO.builder() + .resultStatus("FAILED").message(e.getMessage()).build(); + } +} +``` + +- [ ] **Step 4: Add markRejected and getBySplitAdjustNo to SplitAdjustFormalizationService** + +Add to `SplitAdjustFormalizationService.java`: + +```java +SplitAdjustDO getBySplitAdjustNo(String splitAdjustNo); +void markRejected(String splitAdjustNo, String approvalComment); +``` + +Implement in `SplitAdjustFormalizationService`: + +```java +public SplitAdjustDO getBySplitAdjustNo(String splitAdjustNo) { + return splitAdjustMapper.selectOne( + new LambdaQueryWrapperX() + .eq(SplitAdjustDO::getSplitAdjustNo, splitAdjustNo)); +} + +public void markRejected(String splitAdjustNo, String approvalComment) { + SplitAdjustDO record = getBySplitAdjustNo(splitAdjustNo); + if (record == null) return; + record.setApprovalStatus("REJECTED"); + record.setSplitStatus("REJECTED"); + record.setExecuteMessage(approvalComment); + splitAdjustMapper.updateById(record); +} +``` + +- [ ] **Step 5: Commit** + +```bash +git add sw-business/sw-business-server/ +git commit -m "feat: add SplitAdjustInternalApiImpl with BPM approval callback" +``` + +### Task 1.3: Split Adjust BPM — ProcessInit, BusinessBridge, Controller, VOs, Listener + +**Files — Create all in sw-module-bpm:** +- `sw-module-bpm-server/src/main/java/cn/com/emsoft/sw/module/bpm/controller/app/splitadjust/vo/BpmSplitAdjustSaveReqVO.java` +- `sw-module-bpm-server/src/main/java/cn/com/emsoft/sw/module/bpm/controller/app/splitadjust/vo/BpmSplitAdjustRespVO.java` +- `sw-module-bpm-server/src/main/java/cn/com/emsoft/sw/module/bpm/controller/admin/splitadjust/BpmSplitAdjustController.java` +- `sw-module-bpm-server/src/main/java/cn/com/emsoft/sw/module/bpm/service/splitadjust/SplitAdjustBusinessBridge.java` +- `sw-module-bpm-server/src/main/java/cn/com/emsoft/sw/module/bpm/service/splitadjust/SplitAdjustProcessInit.java` +- `sw-module-bpm-server/src/main/java/cn/com/emsoft/sw/module/bpm/service/splitadjust/SplitAdjustApprovalListener.java` + +- [ ] **Step 1: BpmSplitAdjustSaveReqVO** + +```java +package cn.com.emsoft.sw.module.bpm.controller.app.splitadjust.vo; + +import cn.com.emsoft.sw.module.bpm.controller.app.process.vo.ProcessBaseSaveReqVO; +import lombok.Data; +import lombok.EqualsAndHashCode; +import java.math.BigDecimal; +import java.util.List; + +@Data +@EqualsAndHashCode(callSuper = true) +public class BpmSplitAdjustSaveReqVO extends ProcessBaseSaveReqVO { + private Long sourceChargeId; + private Integer splitCount; + private List splitItems; + private String reasonCode; + private String remark; + private String applicant; + private String contactMobile; + private String sourceCustCode; // for cust lookup in ProcessInit + + @Data + public static class SplitWaterItem { + private Integer seqNo; + private BigDecimal splitWater; + } +} +``` + +- [ ] **Step 2: BpmSplitAdjustRespVO** + +```java +package cn.com.emsoft.sw.module.bpm.controller.app.splitadjust.vo; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class BpmSplitAdjustRespVO { + private Long bizProcessId; + private String splitAdjustNo; + private String processInstanceId; +} +``` + +- [ ] **Step 3: BpmSplitAdjustController** + +```java +package cn.com.emsoft.sw.module.bpm.controller.admin.splitadjust; + +import cn.com.emsoft.sw.module.bpm.controller.app.splitadjust.vo.BpmSplitAdjustSaveReqVO; +import cn.com.emsoft.sw.module.bpm.controller.app.splitadjust.vo.BpmSplitAdjustRespVO; +import cn.com.emsoft.sw.module.bpm.service.splitadjust.SplitAdjustProcessService; +import cn.com.emsoft.sw.framework.common.pojo.CommonResult; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import static cn.com.emsoft.sw.framework.common.pojo.CommonResult.success; + +@Tag(name = "管理后台 - 分账调整工单") +@RestController +@RequestMapping("/bpm/split-adjust") +@Validated +public class BpmSplitAdjustController { + + @Resource + private SplitAdjustProcessService splitAdjustProcessService; + + @PostMapping("/create") + @Operation(summary = "创建分账调整工单") + @PreAuthorize("@ss.hasPermission('bpm:split-adjust:create')") + public CommonResult create(@Valid @RequestBody BpmSplitAdjustSaveReqVO reqVO) { + return success(splitAdjustProcessService.create(reqVO)); + } +} +``` + +- [ ] **Step 4: SplitAdjustBusinessBridge** + +```java +package cn.com.emsoft.sw.module.bpm.service.splitadjust; + +import cn.com.emsoft.sw.business.api.accountingadjust.SplitAdjustInternalApi; +import cn.com.emsoft.sw.business.api.accountingadjust.dto.SplitAdjustCreateReqDTO; +import cn.com.emsoft.sw.business.api.accountingadjust.dto.SplitAdjustCreateRespDTO; +import cn.com.emsoft.sw.module.bpm.controller.app.splitadjust.vo.BpmSplitAdjustSaveReqVO; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +public class SplitAdjustBusinessBridge { + + @Resource + private SplitAdjustInternalApi splitAdjustInternalApi; + + public SplitAdjustCreateRespDTO createAdjustRecord(BpmSplitAdjustSaveReqVO biz) { + SplitAdjustCreateReqDTO reqDTO = new SplitAdjustCreateReqDTO(); + reqDTO.setSourceChargeId(biz.getSourceChargeId()); + reqDTO.setSplitCount(biz.getSplitCount()); + reqDTO.setReasonCode(biz.getReasonCode()); + reqDTO.setRemark(biz.getRemark()); + reqDTO.setApplicant(biz.getApplicant()); + reqDTO.setContactMobile(biz.getContactMobile()); + if (biz.getSplitItems() != null) { + reqDTO.setSplitItems(biz.getSplitItems().stream().map(item -> { + SplitAdjustCreateReqDTO.SplitWaterItem dtoItem = new SplitAdjustCreateReqDTO.SplitWaterItem(); + dtoItem.setSeqNo(item.getSeqNo()); + dtoItem.setSplitWater(item.getSplitWater()); + return dtoItem; + }).toList()); + } + SplitAdjustCreateRespDTO resp = splitAdjustInternalApi.create(reqDTO).getCheckedData(); + log.info("分账调整记录创建成功, splitAdjustNo={}", resp.getSplitAdjustNo()); + return resp; + } +} +``` + +- [ ] **Step 5: SplitAdjustProcessInit** + +```java +package cn.com.emsoft.sw.module.bpm.service.splitadjust; + +import cn.com.emsoft.sw.business.api.accountingadjust.dto.SplitAdjustCreateRespDTO; +import cn.com.emsoft.sw.module.bpm.controller.app.splitadjust.vo.BpmSplitAdjustSaveReqVO; +import cn.com.emsoft.sw.module.bpm.dal.dataobject.oa.BpmProcessDO; +import cn.com.emsoft.sw.module.bpm.enums.process.BusinessType; +import cn.com.emsoft.sw.module.bpm.service.process.template.BpmProcessInit; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +public class SplitAdjustProcessInit extends BpmProcessInit { + + { PROCESS_KEY = "split_adjust"; } + + @Resource + private SplitAdjustBusinessBridge businessBridge; + + @Override + public Long initBusinessProcess(BpmProcessDO process, BpmSplitAdjustSaveReqVO biz) { + process.setBusinessType(BusinessType.FEN_ZHANG_TIAO_ZHENG.getValue()); + SplitAdjustCreateRespDTO resp = businessBridge.createAdjustRecord(biz); + process.setBusinessCode(resp.getSplitAdjustNo()); + return null; // businessId handled via businessCode + } +} +``` + +- [ ] **Step 6: SplitAdjustProcessService (thin wrapper)** + +```java +package cn.com.emsoft.sw.module.bpm.service.splitadjust; + +import cn.com.emsoft.sw.business.api.cust.CustApi; +import cn.com.emsoft.sw.business.api.cust.dto.CustDTO; +import cn.com.emsoft.sw.module.bpm.controller.app.splitadjust.vo.BpmSplitAdjustSaveReqVO; +import cn.com.emsoft.sw.module.bpm.controller.app.splitadjust.vo.BpmSplitAdjustRespVO; +import cn.com.emsoft.sw.module.bpm.dal.dataobject.oa.BpmProcessDO; +import cn.com.emsoft.sw.module.bpm.dal.mysql.oa.BpmProcessMapper; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import static cn.com.emsoft.sw.framework.common.exception.util.ServiceExceptionUtil.invalidParamException; + +@Slf4j +@Service +public class SplitAdjustProcessService { + + @Resource + private SplitAdjustProcessInit processInit; + @Resource + private BpmProcessMapper bpmProcessMapper; + @Resource + private CustApi custApi; + + @Transactional(rollbackFor = Exception.class) + public BpmSplitAdjustRespVO create(BpmSplitAdjustSaveReqVO reqVO) { + CustDTO custDTO = custApi.getCustDTObyCode(reqVO.getSourceCustCode()).getCheckedData(); + if (custDTO == null) { + throw invalidParamException("客户不存在: {}", reqVO.getSourceCustCode()); + } + processInit.mainProcess(custDTO, reqVO); + BpmProcessDO bizProcess = bpmProcessMapper.selectOne( + new LambdaQueryWrapper() + .eq(BpmProcessDO::getBusinessCode, reqVO.getSourceCustCode()) // we need to fix this lookup + ); + // Better: processInit returns the bizProcessId + return BpmSplitAdjustRespVO.builder() + .bizProcessId(bizProcess != null ? bizProcess.getId() : null) + .splitAdjustNo(bizProcess != null ? bizProcess.getBusinessCode() : null) + .processInstanceId(bizProcess != null ? bizProcess.getProcessInstanceId() : null) + .build(); + } +} +``` + +- [ ] **Step 7: SplitAdjustApprovalListener** + +```java +package cn.com.emsoft.sw.module.bpm.service.splitadjust; + +import cn.com.emsoft.sw.business.api.accountingadjust.SplitAdjustInternalApi; +import cn.com.emsoft.sw.business.api.accountingadjust.dto.AdjustExecuteReqDTO; +import cn.com.emsoft.sw.business.api.accountingadjust.dto.AdjustExecuteRespDTO; +import cn.com.emsoft.sw.module.bpm.api.event.BpmProcessInstanceStatusEvent; +import cn.com.emsoft.sw.module.bpm.dal.dataobject.oa.BpmProcessDO; +import cn.com.emsoft.sw.module.bpm.dal.mysql.oa.BpmProcessMapper; +import cn.com.emsoft.sw.module.bpm.enums.task.BpmProcessInstanceStatusEnum; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +public class SplitAdjustApprovalListener { + + private static final String PROCESS_KEY = "split_adjust"; + + @Resource + private BpmProcessMapper bpmProcessMapper; + @Resource + private SplitAdjustInternalApi splitAdjustInternalApi; + + @EventListener + public void onProcessInstanceCompleted(BpmProcessInstanceStatusEvent event) { + if (!PROCESS_KEY.equals(event.getProcessDefinitionKey())) return; + if (event.getBusinessKey() == null) return; + + Long bizProcessId; + try { + bizProcessId = Long.valueOf(event.getBusinessKey()); + } catch (NumberFormatException e) { + log.warn("无法解析 businessKey: {}", event.getBusinessKey()); + return; + } + + BpmProcessDO bizProcess = bpmProcessMapper.selectById(bizProcessId); + if (bizProcess == null || bizProcess.getBusinessCode() == null) { + log.warn("BPM 工单不存在或无 businessCode: bizProcessId={}", bizProcessId); + return; + } + + String approvalStatus = BpmProcessInstanceStatusEnum.APPROVE.getStatus().equals(event.getStatus()) + ? "APPROVE" : "REJECT"; + + AdjustExecuteReqDTO reqDTO = new AdjustExecuteReqDTO(); + reqDTO.setAdjustmentNo(bizProcess.getBusinessCode()); + reqDTO.setApprovalStatus(approvalStatus); + reqDTO.setOperatorId("BPM_AUTO"); + + AdjustExecuteRespDTO resp = splitAdjustInternalApi.execute(reqDTO).getCheckedData(); + log.info("分账调整执行结果: splitAdjustNo={}, resultStatus={}, message={}", + bizProcess.getBusinessCode(), resp.getResultStatus(), resp.getMessage()); + } +} +``` + +- [ ] **Step 8: Register Feign client in RpcConfiguration** + +In `sw-module-bpm-server/src/main/java/cn/com/emsoft/sw/module/bpm/framework/rpc/config/RpcConfiguration.java`, add `SplitAdjustInternalApi.class` to the `@EnableFeignClients` annotation. + +- [ ] **Step 9: Commit** + +```bash +git add sw-module-bpm/ +git commit -m "feat: add BPM workflow for split adjust (分账调整)" +``` + +### Task 1.4: Frontend — Switch SplitAdjustmentForm to BPM endpoint + +**Files:** +- Modify: `water-frontend/src/views/accountProcess/unsoldAdjustment/components/SplitAdjustmentForm.vue` +- Create: `water-frontend/src/api/bpm/splitAdjust/index.ts` + +- [ ] **Step 1: Create BPM split adjust API** + +```typescript +// src/api/bpm/splitAdjust/index.ts +import request from '@/config/axios' + +export interface BpmSplitAdjustSaveReqVO { + sourceCustCode: string + sourceChargeId: number + splitCount: number + splitItems: { seqNo: number; splitWater: number }[] + reasonCode?: string + remark?: string + applicant?: string + contactMobile?: string +} + +export interface BpmSplitAdjustRespVO { + bizProcessId?: number + splitAdjustNo?: string + processInstanceId?: string +} + +export const createSplitAdjust = (data: BpmSplitAdjustSaveReqVO) => + request.post({ url: '/bpm/split-adjust/create', data }) +``` + +- [ ] **Step 2: Modify SplitAdjustmentForm submitForm** + +Replace the call from `UnsoldAdjustmentApi.submitUnsoldSplit(...)` to `createSplitAdjust(...)`. The response now includes `processInstanceId` — show "已提交审批" on success. + +```typescript +// In submitForm(): +import { createSplitAdjust, type BpmSplitAdjustSaveReqVO } from '@/api/bpm/splitAdjust' + +const resp = await createSplitAdjust({ + sourceCustCode: rowData.value.custCode, + sourceChargeId: rowData.value.id, + splitCount: splitItems.length, + splitItems: splitItems.map(item => ({ seqNo: item.seqNo || 1, splitWater: item.splitWater || 0 })), + reasonCode: formData.value.applyReason || '1', + remark: formData.value.remark || undefined, + applicant: formData.value.applicant || undefined, + contactMobile: formData.value.contactMobile || undefined, +}) +message.success('分账申请已提交,待审批') +dialogVisible.value = false +emit('success') +``` + +- [ ] **Step 3: Commit** + +```bash +git add water-frontend/src/api/bpm/splitAdjust/ water-frontend/src/views/accountProcess/unsoldAdjustment/components/SplitAdjustmentForm.vue +git commit -m "feat: wire split adjust form to BPM workflow endpoint" +``` + +--- + +## Types 2-5: Remaining Adjustments (pattern replication) + +Each of the remaining 4 types follows the same pattern as Type 1. Key differences noted below. + +### Task 2: Bad Debt Adjust (呆坏账调整) + +- PROCESS_KEY: `"bad_debt_adjust"` +- BusinessType: `DAI_HUA_TONG` (203) +- Internal API path: `/internal/bad-debt-adjust` +- BPM controller path: `/bpm/bad-debt-adjust` +- Create DTO fields: `chargeId, badDebtAmount, processType, reasonCode, remark, applicant, contactMobile, sourceCustCode` +- Execute logic: mark bad debt record, no account balance change needed (just status update) +- Frontend form: `BadDebtAdjustmentForm.vue` → call `/bpm/bad-debt-adjust/create` + +**Files to create (BPM):** +- `controller/app/baddebtadjust/vo/BpmBadDebtAdjustSaveReqVO.java` +- `controller/app/baddebtadjust/vo/BpmBadDebtAdjustRespVO.java` +- `controller/admin/baddebtadjust/BpmBadDebtAdjustController.java` +- `service/baddebtadjust/BadDebtAdjustBusinessBridge.java` +- `service/baddebtadjust/BadDebtAdjustProcessInit.java` +- `service/baddebtadjust/BadDebtAdjustProcessService.java` +- `service/baddebtadjust/BadDebtAdjustApprovalListener.java` + +**Files to create (Business):** +- `api/accountingadjust/dto/BadDebtAdjustCreateReqDTO.java` +- `api/accountingadjust/dto/BadDebtAdjustCreateRespDTO.java` +- `api/accountingadjust/BadDebtAdjustInternalApi.java` +- `api/accountingadjust/BadDebtAdjustInternalApiImpl.java` + +**Files to modify:** +- `RpcConfiguration.java` — add `BadDebtAdjustInternalApi.class` +- `water-frontend/src/api/bpm/badDebtAdjust/index.ts` (new) +- `water-frontend/src/views/.../BadDebtAdjustmentForm.vue` — switch to BPM endpoint + +### Task 3: Writtenoff Adjust (核销调整) + +- PROCESS_KEY: `"writtenoff_adjust"` +- BusinessType: need new entry or reuse existing. Use `TIAO_ZHENG_JIAN_MIAN` (202) or add a new one +- Internal API path: `/internal/writtenoff-adjust` +- BPM controller path: `/bpm/writtenoff-adjust` +- Create DTO fields: `chargeId, writtenoffAmount, reasonCode, remark, applicant, contactMobile, sourceCustCode` + +Note: Writtenoff adjust currently has no frontend form — verify if one is needed before creating BPM controller. + +### Task 4: Price Diff Adjust (价差调整) + +- PROCESS_KEY: `"price_diff_adjust"` +- BusinessType: `JIA_CHA_TIAO_ZHENG` (205) +- Internal API path: `/internal/price-diff-adjust` +- BPM controller path: `/bpm/price-diff-adjust` +- Create DTO fields: `chargeIds[]` (batch), `reasonCode, remark, applicant, contactMobile, sourceCustCode` +- Frontend form: `PriceAdjustmentForm.vue` — this is a BATCH form, needs adjustment for submitting multiple charges + +### Task 5: Late Fee Reduce (违约金减免) + +- PROCESS_KEY: `"late_fee_reduce_adjust"` +- BusinessType: `WEI_YUE_JIN_JIAN_MIAN` (204) +- Internal API path: `/internal/late-fee-reduce` +- BPM controller path: `/bpm/late-fee-reduce` +- Create DTO fields: `chargeIds[], lateFeeType, lateFeeReduceAmount, startDate, endDate, reasonCode, remark, applicant, contactMobile, sourceCustCode` +- Frontend form: `PenaltyRemissionForm.vue` — also a BATCH form + +### Task 6: Frontend batch forms adaptation + +`PriceAdjustmentForm.vue` and `PenaltyRemissionForm.vue` submit multiple charges at once. Two approaches: + +A) Submit one BPM process per charge — loop create API calls +B) Submit one BPM process with all charges — requires BPM process to handle arrays + +Choose A (one process per charge) since it aligns with how `BpmProcessDO` is single-charge. The frontend loops and `Promise.all`s the calls. + +--- + +## Self-Review + +**Spec coverage:** All 5 adjustment types (split, bad debt, writtenoff, price diff, late fee reduce) have BPM flow tasks mapped. + +**Placeholder scan:** Task 1 (split) has complete code. Tasks 2-5 describe the pattern with key fields/differences — the implementing agent should replicate Task 1's exact code structure with the noted variations. + +**Type consistency:** `AdjustExecuteReqDTO` / `AdjustExecuteRespDTO` shared across all 5 types. `SplitWaterItem` DTO consistent between API, BPM VO, and service layers. + +**Risk:** BPM process definitions (`split_adjust`, `bad_debt_adjust`, etc.) must be created in the BPM designer separately. Code changes alone won't make the workflow runnable without matching process definitions.