fujian_water_biz_doc/docs/superpowers/specs/2026-06-08-revenue-bugfix-clear-scope-design.md

7.7 KiB
Raw Blame History

营收明确缺陷第一批修复设计

日期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 汇总。
  • 写入结账明细时,chargeIdbillMonth 可为空。
  • chargeMapper.markCounterSettled() 只处理真实账单收费记录对应的 chargeIds

收费员筛选

柜台结账查询的收费员解析规则改为:

  • 请求 cashierId 为空时,默认使用当前登录用户。
  • 请求 cashierId 非空时,使用请求值查询。
  • 如后续接入完整数据权限,可在此基础上限制普通用户只能查自己、管理员可查指定收费员。本轮先不让后端无条件覆盖前端筛选值。

预存抵扣校验

柜台收费继续由前端传入 prepayDeductAmount

  • 后端校验抵扣金额不得小于 0。
  • 抵扣金额不得超过账单应收金额。
  • 抵扣金额不得超过账户预存余额。
  • 抵扣金额大于 0 时扣减账户余额,并在支付记录 extJson 中保留 prepayDeductAmount

本轮不启用后端自动计算抵扣金额,避免改变用户输入语义。

柜台红冲记录查询

红冲记录页应基于柜台结账红冲链路展示,而不是复用账务调整日志:

  • 查询来源为 settle_recordsettle_record_detailpayment_record 的柜台红冲结果。
  • 默认包含部分红冲和全部红冲状态。
  • 日期筛选使用红冲时间 reversedTime,而不是账务日志的创建时间或处理时间。
  • 返回字段至少包含结账单号、收费员、客户、红冲金额、红冲时间、红冲原因。

前端设计

水价调整失败恢复

水价调整提交失败后,前端不再只把页面退出调整态。推荐交互:

  1. 显示调价失败原因。
  2. 自动调用 startAdjustment() 尝试重新获取锁。
  3. 重新获取成功时保留当前页面数据,提示用户可继续修正后提交。
  4. 重新获取失败时提示锁被占用或已过期,并引导用户重新开始调价。

待审批动作状态文案

未销分账、呆坏账、价差调整、违约金减免等提交后,根据响应状态显示文案:

  • approvalRequired=trueresultStatus=PENDING_APPROVAL:显示“申请已提交,待审批”。
  • writeBackStatus=PENDING:显示“待回写”或“待执行”,不刷新为已生效。
  • resultStatus=SUCCESSwriteBackStatus=UPDATED:显示“处理完成”。

页面不得仅用“提交成功”表达所有结果。

柜台结账页面

未结账列表需要正常展示预存充值记录:

  • chargeIdbillMonth 时显示 --
  • 客户、收费员、金额、缴费时间正常展示。
  • 结账确认汇总包含预存充值金额。

收费员筛选继续保留,前端传入的 cashierId 应与后端查询语义一致。

红冲记录页面

红冲记录页面改为柜台红冲记录视图:

  • 查询接口改为柜台红冲记录接口。
  • 日期筛选标签改为“红冲时间”。
  • 参数使用 beginReversedTimeendReversedTime
  • 列表展示柜台红冲相关字段,不再按账务调整日志字段组织。

预存抵扣交互

柜台收费页面保留当前按选中账单分摊 prepayDeductAmount 的逻辑,并补充交互保护:

  • 抵扣金额不得超过预存余额。
  • 抵扣金额不得超过选中账单应收合计。
  • 用户开启预存抵扣但计算抵扣为 0 时,提交前给出明确提示或确认。

测试设计

后端测试

  • 水价调整:覆盖失败后前端可重新开始调价;覆盖刷新锁不释放抢占。
  • 柜台结账:覆盖 CHARGE_PAYMENTDEPOSIT_TOPUP 都进入未结账;覆盖预存记录结账时不要求 chargeId
  • 收费员筛选:覆盖请求 cashierId 非空时后端按请求值查询。
  • 预存抵扣:覆盖正常抵扣、余额不足、非法金额。
  • 红冲记录:覆盖红冲状态默认可查,按 reversedTime 范围筛选。

前端测试

  • 水价调整提交失败后重新获取锁或展示重获锁失败提示。
  • 分账和呆坏账返回待审批时提示“申请已提交,待审批”。
  • 柜台结账未结账列表能展示预存充值记录。
  • 红冲记录页调用柜台红冲记录接口,并按红冲时间传参。
  • 预存抵扣开启但抵扣金额为 0 时出现确认或提示。

验收标准

  1. 用户在水价调整报错后无需关闭菜单即可继续修正并重新提交。
  2. 柜台预存缴费能在柜台结账待结清列表中查询并完成结账。
  3. 柜台结账收费员筛选不再无条件固定为当前登录用户。
  4. 柜台红冲成功后,红冲记录页可按红冲时间查询到记录。
  5. 分账、呆坏账等待审批动作不再被前端表达为已生效。
  6. 预存抵扣金额写入支付记录并扣减账户余额,非法金额有明确错误。

实施边界

本设计不包含以下内容:

  • 不重构完整 REV004 账务调整状态机。
  • 不新增完整 BPM 审批能力。
  • 不修改呆坏账、分账从待审批到已执行的业务规则。
  • 不处理未复现的 #70 和产品规则未确认的 #9