feat: 尾款 balanceAmount 统一走 BalanceCalculator 防未确认优惠扣负数 (PR #1340)
这个提交包含在:
父节点
d4bcd96434
当前提交
14e55f0246
@ -0,0 +1,70 @@
|
|||||||
|
# 未确认优惠不再扣减尾款(修复 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-5448` balanceAmount 从 -558.10 修正为 1.90
|
||||||
|
- 回滚:revert PR #1340 即可恢复旧行为
|
||||||
|
|
||||||
|
## 遗留优化(后续独立 PR)
|
||||||
|
|
||||||
|
`order_info.discount_amount` 字段由 `OrderDiscountService.sumByOrderId` 写入时未过滤 `confirmed`,语义上包含 pending。本 PR 未动(前端「优惠合计」依赖这个字段显示 pending+confirmed 总和)。后续会单独统一语义并给前端提供独立 `pendingDiscountSum` / `confirmedDiscountSum` 字段,本次不涉及。
|
||||||
正在加载...
x
在新工单中引用
屏蔽一个用户