From 14e55f02461907cc0318976187115e9b579223bd Mon Sep 17 00:00:00 2001 From: API Changelog Bot Date: Fri, 24 Apr 2026 09:21:08 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=B0=BE=E6=AC=BE=20balanceAmount=20?= =?UTF-8?q?=E7=BB=9F=E4=B8=80=E8=B5=B0=20BalanceCalculator=20=E9=98=B2?= =?UTF-8?q?=E6=9C=AA=E7=A1=AE=E8=AE=A4=E4=BC=98=E6=83=A0=E6=89=A3=E8=B4=9F?= =?UTF-8?q?=E6=95=B0=20(PR=20#1340)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...x_order-v2_balance-unconfirmed-discount.md | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 changelogs/2026-04/24_fix_order-v2_balance-unconfirmed-discount.md diff --git a/changelogs/2026-04/24_fix_order-v2_balance-unconfirmed-discount.md b/changelogs/2026-04/24_fix_order-v2_balance-unconfirmed-discount.md new file mode 100644 index 0000000..a2c2f0e --- /dev/null +++ b/changelogs/2026-04/24_fix_order-v2_balance-unconfirmed-discount.md @@ -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` 字段,本次不涉及。