7.9 KiB
7.9 KiB
REV-004 未销调整预算参数正式化设计
文档信息
| 项目 | 内容 |
|---|---|
| 项目名称 | 福建水务营收系统 |
| 模块 | REV-004 账务处理 / 未销调整 |
| 文档类型 | 实现前设计草案 |
| 编写日期 | 2026-06-19 |
| 状态 | 待实现 |
背景
未销调整页存在若干只在预算阶段生效的 checkbox 参数,例如水量调整的累计量、底码计算,以及价差调整的阶梯计费、垃圾费计算、累计量更新。当前后端现状是:部分参数参与预算,但没有完整进入正式提交、正式调整对象、审批回写和账单重算链路,导致“预算结果”和“正式入账结果”存在不一致风险。
本设计目标是将预算阶段的 checkbox 语义升级为正式调整参数,保证用户在预算页勾选的计算口径能够被正式提交、审计记录和最终回写一致承接。
设计目标
- 预算参数在正式提交时不丢失。
- 正式调整对象能够记录预算参数,形成审计轨迹。
- 审批或自动执行回写时使用与预算一致的计算开关。
- 未传 checkbox 时保持现有默认行为,避免破坏旧调用方。
- 只补齐未销调整相关链路,不扩大到已销、预存和其他 REV 场景。
非目标
- 不重构完整 REV-004 账务调整状态机。
- 不引入新的预算快照 token 机制。
- 不改变已收费、已开票、已结账等既有边界校验。
- 不在本轮统一改造前端 UI 布局,仅约束前后端字段语义。
推荐方案
采用“最小补链路”方案:沿用现有未销调整接口和正式对象结构,补齐缺失字段和默认值语义。
相比新增统一 adjustOptions 或预算快照机制,该方案改动范围较小,能快速解决当前预算与正式回写不一致的问题;后续如果 REV-004 进入全量对象化改造,再考虑统一参数模型。
水量调整设计
参数
水量预算已有参数:
| 字段 | 含义 | 当前预算行为 | 正式化要求 |
|---|---|---|---|
targetBillWater |
调整后水量 | 参与费用重算 | 已支持,继续作为正式重算水量 |
updateAccumulated |
是否计算累计量 | 返回调整前后累计量 | 正式提交需承接,并按水量差额更新账单累计量 |
updateBaseCode |
是否计算底码 | 返回调整前后底码 | 正式提交需承接,并配合 currentReading 更新本次抄码/底码 |
currentReading |
本次抄码 | 预算阶段不作为 checkbox | 正式提交继续保留,作为底码正式值来源 |
正式行为
targetBillWater始终参与费用重算。updateAccumulated=true时,正式回写按targetBillWater - 原billWater调整账单累计量字段。updateBaseCode=true时,正式回写允许更新本次抄码;若未传currentReading,应拒绝提交并提示“更新底码必须传入本次抄码”。- 两个 checkbox 未传时默认
false,保持旧行为。 - 费用重算仍使用当前水价模板、费用组成、优惠方案和用水方案,不额外改变计费规则。
影响文件
后端需要补齐:
| 层级 | 文件/对象 | 改动 |
|---|---|---|
| API VO | AccountingAdjustUnsoldAdjustSubmitReqVO |
增加 updateAccumulated、updateBaseCode |
| 统一 DTO | AccountingAdjustSubmitReqVO |
增加同名字段 |
| Controller 映射 | AccountingAdjustActionController |
将字段映射到统一 DTO |
| 核心调整 VO | AccountingAdjustReqVO |
增加同名字段 |
| 过程服务 | AccountingAdjustProcessServiceImpl |
将字段传入核心调整 VO |
| 回写服务 | ChargeServiceImpl |
水量正式调整时执行累计量/底码更新 |
| 测试 | 相关 unit test | 覆盖字段映射、底码必填、累计量更新 |
价差调整设计
参数
价差预算已有参数:
| 字段 | 含义 | 当前预算行为 | 正式化要求 |
|---|---|---|---|
isLadder |
是否阶梯计费 | false 时使用第一档单价平铺 |
正式回写必须使用相同值 |
calculateGarbageFee |
是否计算垃圾费 | false 时排除费用项 103 |
正式回写必须使用相同值 |
updateAccumulatedVolume |
是否更新客户累计量 | 提交 VO 已有字段,但正式对象链路不完整 | 正式对象和回写需保存并使用 |
正式行为
isLadder=false时,正式回写按非阶梯算法生成新账单,不能回退为阶梯算法。calculateGarbageFee=false时,正式回写不生成垃圾费金额。updateAccumulatedVolume=true时,生成新账单后同步累计量相关字段;为false时不更新累计量。- 默认值必须与预算一致:
isLadder:未传时按true处理。calculateGarbageFee:未传时按true处理。updateAccumulatedVolume:未传时按现有前端默认值处理;后端建议默认true,但需与前端确认。
- 禁止在正式回写阶段将缺失字段解释为
false。
影响文件
后端需要补齐:
| 层级 | 文件/对象 | 改动 |
|---|---|---|
| 提交 VO | AccountingAdjustUnsoldPriceDiffSubmitReqVO |
已有字段,补测试确认不丢失 |
| 统一 DTO | AccountingAdjustSubmitReqVO |
已有字段,补映射测试 |
| 核心调整 VO | AccountingAdjustReqVO |
已有字段,校正默认值语义 |
| 正式创建 DTO | PriceDiffAdjustCreateReqDTO |
增加 calculateGarbageFee、updateAccumulatedVolume |
| Internal API | PriceDiffAdjustInternalApiImpl |
将字段写入正式化 VO |
| 正式明细 DO/表 | PriceDiffAdjustDetailDO / biz_price_diff_adjust_detail |
增加或复用可审计字段 |
| 正式化服务 | PriceDiffFormalizationService |
保存 isLadder、calculateGarbageFee、updateAccumulatedVolume |
| 回写服务 | PriceDiffWriteBackService |
使用一致默认值并执行回写 |
| 审批回写 | AccountingAdjustActionServiceImpl |
从正式明细或日志明细读取三项参数 |
| 测试 | 相关 unit test | 覆盖预算参数到正式回写的一致性 |
数据持久化策略
优先在价差正式明细表增加明确字段:
| 字段建议 | 类型 | 含义 |
|---|---|---|
is_ladder |
smallint | 是否阶梯计费 |
calculate_garbage_fee |
smallint | 是否计算垃圾费 |
update_accumulated_volume |
smallint | 是否更新累计量 |
如短期不便改表,可先将字段写入操作日志明细,但这只能作为过渡方案。正式审计与回写更推荐落入正式对象表。
水量调整当前走 legacy-only 即时回写,没有独立正式对象表;本轮可先通过操作日志明细记录 checkbox 参数,并在 ChargeServiceImpl 即时回写中使用。
错误处理
- 水量调整
updateBaseCode=true且currentReading为空时,拒绝提交。 - checkbox 字段为空时统一按场景默认值处理,不能因空值导致预算与正式回写默认相反。
- 正式回写读取不到价差参数时,按默认值补齐,并记录兼容说明。
- 已收费、已开票、已结账等既有拒绝规则不变。
测试策略
最小测试集:
- 水量预算允许
targetBillWater=0且金额为 0。 - 水量正式提交携带
updateAccumulated=true时,累计量按水量差额更新。 - 水量正式提交
updateBaseCode=true且缺少currentReading时拒绝。 - 价差预算
calculateGarbageFee=false,正式回写后新账单垃圾费为 0。 - 价差预算
isLadder=false,正式回写后按第一档单价计算。 - 价差提交
updateAccumulatedVolume=false时,正式回写不更新累计量。 - checkbox 未传时,旧测试保持通过。
验收标准
- 预算和正式回写使用同一组 checkbox 参数。
- 正式调整记录或操作日志可追溯 checkbox 入值。
- 价差回写不再因字段缺失将
calculateGarbageFee默认成false。 - 水量调整的累计量、底码 checkbox 不再只停留在预算响应。
- 后端最小验证命令通过,并将验证结果记录到
docs/evidence/rev004-accounting/。