3.2 KiB
未确认优惠不再扣减尾款(修复 balanceAmount 负数显示)
日期: 2026-04-24 PR: #1340 (dev) Issue: #1339 类型: fix 服务: hl-order-service-v2
摘要
订单详情页/列表页的尾款字段 balanceAmount 之前会把未确认优惠也扣进去,导致优惠金额大于总售价时显示为负数(例如总售价 ¥2.00、未确认优惠 ¥560.00、已付 ¥0.10 → 尾款 ¥-558.10),但同页文案又写着「以下优惠未确认,暂不影响尾款」,自相矛盾。
本次修复统一让 3 处尾款计算走 BalanceCalculator(架构详设 3.1 唯一真相源),只扣 confirmed=1 的已确认优惠/增项,符合清单确认前「暂不影响尾款」的业务承诺。
影响接口(路径/返回结构不变)
所有返回 balanceAmount 字段的接口,行为一致性修复:
| 接口 | 来源 |
|---|---|
GET /admin/order/{orderId} |
OrderDetailQueryService.assembleDetail |
GET /admin/order/page |
OrderListQueryService.toOrderListVO |
GET /mp/order/page |
OrderListQueryService.toMpOrderListVO |
GET /mp/order/{orderId} |
MpOrderDetailAssembler.buildBasicFields |
新旧对比
旧公式(3 处都一样)
balance = totalPrice - order.discountAmount + order.surchargeAmount - (depositAmount 或 paidAmount)
其中 order.discountAmount = DB 缓存字段,包含未确认优惠。
新公式(统一走 BalanceCalculator)
balance = totalPrice - Σ(confirmed=1 优惠) + Σ(confirmed=1 增项) - paidAmount
未确认条目(confirmed=0 或 NULL)不算入尾款。
前端视图影响
- 顶部「尾款」 由 -558.10 之类的异常值变为合理值(本订单场景 = 1.90)
- 顶部「优惠」合计金额(
discountAmount字段) 保持不变 — 仍显示所有优惠之和(含 pending),前端继续按原字段渲染无需改动 - 确认清单时后端 T5 状态机 guard 会拦截「尾款为负」导致的锁单(此行为原已存在,本 PR 不动)
行为举例
订单场景:总售价 ¥2.00,订金 ¥0.10,已付 ¥0.10,一条 ¥560 房间优惠 confirmed=0
| 字段 | 修复前 | 修复后 |
|---|---|---|
| totalPrice | 2.00 | 2.00 |
| paidAmount | 0.10 | 0.10 |
| discountAmount(合计展示) | 560.00 | 560.00 |
| balanceAmount(尾款) | -558.10 | 1.90 |
确认清单把优惠 confirmed 置 1 后,balanceAmount 才会变为 -558.10;届时 T5 状态机 guard 会拒绝锁单,提示管理员先清理超额优惠。
风险与回滚
- 只改 VO 组装层,不改接口签名/字段/DB schema
- 所有单测(MpOrderDetailAssemblerTest 63/63、OrderDetailQueryServiceTest 17/17、OrderListQueryServiceTest 8/8)+ 全量 2414/2415 通过
- 测试服 curl 验证:订单
HL20260423175303-5448balanceAmount 从 -558.10 修正为 1.90 - 回滚:revert PR #1340 即可恢复旧行为
遗留优化(后续独立 PR)
order_info.discount_amount 字段由 OrderDiscountService.sumByOrderId 写入时未过滤 confirmed,语义上包含 pending。本 PR 未动(前端「优惠合计」依赖这个字段显示 pending+confirmed 总和)。后续会单独统一语义并给前端提供独立 pendingDiscountSum / confirmedDiscountSum 字段,本次不涉及。