fujian_water_biz_doc/docs/evidence/rev004-accounting/rev004-split-adjust-execution-design-draft-2026-04-14.md
tangweijie 3eccab2cf9 docs: 文档治理统一 — AGENTS.md 生命周期规则 + 模块归档 + DDL 修正
1. AGENTS.md 更新
   - water-docs: 新增 specs/ 与 docs/design/ 生命周期规则章节
   - water-backend: 更新协作引用(建设期/建成后、evidence 模块化)

2. specs/ 重复合并
   - 006-reminder-event-design 合并入 003-rev006-reminder-event-design
   - 001-rev004-accounting 删除冗余 data-model.md + contracts/
   - 002-rev005-invoice-flow 删除冗余 data-model.md + contracts/

3. evidence 按模块归档
   - 35 个 REV-004 文件归入 evidence/rev004-accounting/
   - 7 个通用 bugfix 文件归入 evidence/bugfix/ 和 bugfix/frontend/
   - 新建 rev005-invoice/、rev006-reminder/、rev007-statistics/ 目录

4. guides/ 清理
   - 14 个 REV004_*.md 移入 evidence/rev004-accounting/

5. 遗留文件处理
   - docs/research/ 归档到 Archive/06_Migration_Plans/
   - backend-check detached worktrees 清理

6. 交叉引用修复
   - 006-reminder-event-design → 003-rev006-reminder-event-design
   - docs/guides/REV004_ → docs/evidence/rev004-accounting/REV004_

7. DB 设计文档修正(01_Database_Design.md)
   - biz_invoice 明确为开票配置表,非发票记录表
   - 新增 biz_invoice_record 为发票申请/结果主表
   - 新增 biz_charge_invoice_rel 账单-发票关联说明
   - REV-005 承接口径表名全部修正

8. 发票审计证据
   - 新增 evidence/rev005-invoice/2026-06-16-invoice-document-audit.md
2026-06-16 11:47:16 +08:00

7.1 KiB
Raw Blame History

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_statusPENDING / 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 升级成独立正式业务对象来建设。