docs: add revenue bugfix first batch design

This commit is contained in:
tangweijie 2026-06-08 17:50:01 +08:00
parent 3bc4e4184f
commit 256b431add

View File

@ -0,0 +1,168 @@
# 营收明确缺陷第一批修复设计
日期2026-06-08
## 背景
本设计用于收敛当前营收缺陷中代码证据最明确、可闭环验收的一批问题。前期排查表明,部分缺陷并非单纯后端写库失败,而是前后端接口契约、页面状态文案、查询语义和锁恢复流程不一致导致用户认为“成功但未生效”或“查不到记录”。
本轮不改变账务调整审批规则,不把待审批动作改成即时落账;目标是让系统行为与用户提示一致,并补齐明确漏查和重试闭环。
## 修复范围
本轮纳入以下缺陷:
- `#78` 水价调整:执行报错后,用户不应只能关闭菜单从头开始。
- `#39` 柜台结账:柜台预存缴费记录应能进入待结清并完成结账。
- `#50` 柜台结账:收费员筛选不应被后端无条件覆盖为当前登录用户。
- `#53` 柜台收费:预存抵扣金额需要前后端契约保护和回归验证。
- `#58/#59` 红冲记录:柜台红冲后应能在红冲记录页按红冲时间查到。
- `#69/#76` 未销分账、呆坏账:前端应准确表达“申请已提交,待审批/待回写”,不得提示为已生效。
以下缺陷不进入本轮实现,仅保留后续复现或产品确认:
- `#70` 未销调整提示成功但账单未变:现有后端金额/水量调整路径会写回,需要先抓请求体确认字段和值。
- `#9` 抄表状态修改无影响:需要产品确认状态配置影响已生成任务还是仅影响后续任务。
## 设计原则
1. 保持最小闭环,不重构完整账务调整体系。
2. 保留现有审批流语义,修正文案和状态展示,不把待审批改为立即落账。
3. 查询接口按业务语义返回数据,页面筛选字段与后端字段一致。
4. 后端对关键金额和状态做兜底校验,前端负责交互提示和用户确认。
5. 所有修改需要有最小单测、前端合约测试或页面 smoke 覆盖。
## 后端设计
### 水价调整锁恢复
`PriceTemplateServiceImpl.updatePriceTemplate()` 继续保持执行完成后释放调价锁的总体策略,但失败路径需要让前端能够明确恢复:
- 后端异常响应保持业务错误信息可读。
- 前端失败后重新进入 `startAdjustment()` 流程获取新锁。
- `PriceTemplateAdjustmentLockRedisDAO.refreshLock()` 不再采用 `forceUnlock()` 后重新 `tryLock()` 的刷新模式,改为安全续期,避免刷新瞬间锁被其他用户抢占。
### 柜台预存缴费进入结账
`PaymentRecordMapper.selectCounterUnsettledRecords()` 从仅查询 `CHARGE_PAYMENT` 扩展为同时包含 `DEPOSIT_TOPUP`
- `CHARGE_PAYMENT` 表示账单收费记录。
- `DEPOSIT_TOPUP` 表示柜台预存充值记录。
`CounterSettleApplicationServiceImpl.confirm()` 需要支持预存充值记录无营业账 ID
- 结账总金额仍以 `PaymentRecord.paymentAmount` 汇总。
- 写入结账明细时,`chargeId``billMonth` 可为空。
- `chargeMapper.markCounterSettled()` 只处理真实账单收费记录对应的 `chargeIds`
### 收费员筛选
柜台结账查询的收费员解析规则改为:
- 请求 `cashierId` 为空时,默认使用当前登录用户。
- 请求 `cashierId` 非空时,使用请求值查询。
- 如后续接入完整数据权限,可在此基础上限制普通用户只能查自己、管理员可查指定收费员。本轮先不让后端无条件覆盖前端筛选值。
### 预存抵扣校验
柜台收费继续由前端传入 `prepayDeductAmount`
- 后端校验抵扣金额不得小于 0。
- 抵扣金额不得超过账单应收金额。
- 抵扣金额不得超过账户预存余额。
- 抵扣金额大于 0 时扣减账户余额,并在支付记录 `extJson` 中保留 `prepayDeductAmount`
本轮不启用后端自动计算抵扣金额,避免改变用户输入语义。
### 柜台红冲记录查询
红冲记录页应基于柜台结账红冲链路展示,而不是复用账务调整日志:
- 查询来源为 `settle_record``settle_record_detail``payment_record` 的柜台红冲结果。
- 默认包含部分红冲和全部红冲状态。
- 日期筛选使用红冲时间 `reversedTime`,而不是账务日志的创建时间或处理时间。
- 返回字段至少包含结账单号、收费员、客户、红冲金额、红冲时间、红冲原因。
## 前端设计
### 水价调整失败恢复
水价调整提交失败后,前端不再只把页面退出调整态。推荐交互:
1. 显示调价失败原因。
2. 自动调用 `startAdjustment()` 尝试重新获取锁。
3. 重新获取成功时保留当前页面数据,提示用户可继续修正后提交。
4. 重新获取失败时提示锁被占用或已过期,并引导用户重新开始调价。
### 待审批动作状态文案
未销分账、呆坏账、价差调整、违约金减免等提交后,根据响应状态显示文案:
- `approvalRequired=true``resultStatus=PENDING_APPROVAL`:显示“申请已提交,待审批”。
- `writeBackStatus=PENDING`:显示“待回写”或“待执行”,不刷新为已生效。
- `resultStatus=SUCCESS``writeBackStatus=UPDATED`:显示“处理完成”。
页面不得仅用“提交成功”表达所有结果。
### 柜台结账页面
未结账列表需要正常展示预存充值记录:
- 无 `chargeId``billMonth` 时显示 `--`
- 客户、收费员、金额、缴费时间正常展示。
- 结账确认汇总包含预存充值金额。
收费员筛选继续保留,前端传入的 `cashierId` 应与后端查询语义一致。
### 红冲记录页面
红冲记录页面改为柜台红冲记录视图:
- 查询接口改为柜台红冲记录接口。
- 日期筛选标签改为“红冲时间”。
- 参数使用 `beginReversedTime``endReversedTime`
- 列表展示柜台红冲相关字段,不再按账务调整日志字段组织。
### 预存抵扣交互
柜台收费页面保留当前按选中账单分摊 `prepayDeductAmount` 的逻辑,并补充交互保护:
- 抵扣金额不得超过预存余额。
- 抵扣金额不得超过选中账单应收合计。
- 用户开启预存抵扣但计算抵扣为 0 时,提交前给出明确提示或确认。
## 测试设计
### 后端测试
- 水价调整:覆盖失败后前端可重新开始调价;覆盖刷新锁不释放抢占。
- 柜台结账:覆盖 `CHARGE_PAYMENT``DEPOSIT_TOPUP` 都进入未结账;覆盖预存记录结账时不要求 `chargeId`
- 收费员筛选:覆盖请求 `cashierId` 非空时后端按请求值查询。
- 预存抵扣:覆盖正常抵扣、余额不足、非法金额。
- 红冲记录:覆盖红冲状态默认可查,按 `reversedTime` 范围筛选。
### 前端测试
- 水价调整提交失败后重新获取锁或展示重获锁失败提示。
- 分账和呆坏账返回待审批时提示“申请已提交,待审批”。
- 柜台结账未结账列表能展示预存充值记录。
- 红冲记录页调用柜台红冲记录接口,并按红冲时间传参。
- 预存抵扣开启但抵扣金额为 0 时出现确认或提示。
## 验收标准
1. 用户在水价调整报错后无需关闭菜单即可继续修正并重新提交。
2. 柜台预存缴费能在柜台结账待结清列表中查询并完成结账。
3. 柜台结账收费员筛选不再无条件固定为当前登录用户。
4. 柜台红冲成功后,红冲记录页可按红冲时间查询到记录。
5. 分账、呆坏账等待审批动作不再被前端表达为已生效。
6. 预存抵扣金额写入支付记录并扣减账户余额,非法金额有明确错误。
## 实施边界
本设计不包含以下内容:
- 不重构完整 REV004 账务调整状态机。
- 不新增完整 BPM 审批能力。
- 不修改呆坏账、分账从待审批到已执行的业务规则。
- 不处理未复现的 `#70` 和产品规则未确认的 `#9`