fix: mp 订单详情单房差展示修复 + 5 字段独立暴露 (PR #1906 + #1909)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
这个提交包含在:
API Changelog Bot 2026-05-09 11:23:46 +08:00
父节点 c935ef7905
当前提交 cbadc13684

查看文件

@ -0,0 +1,115 @@
# mp 订单详情单房差展示修复 + 5 字段独立暴露
> **服务**: hl-order-service-v2(8094)
> **PR**: #1906 + #1909 (Refs #1900)
> **日期**: 2026-05-09
> **影响范围**: 小程序订单详情页
---
## ⚠️ 关键变化
`GET /mp/order/{orderId}` 接口:
1. **修复 GROUP 订单 priceBreakdown JSON 漏字段**(#1906):创建 GROUP 订单时 `priceBreakdownJson` 没写 `singleRoomDiff` / `singleRoomSurcharge`,导致明细面板看不到"单房差"行
2. **新增 5 个独立字段**(#1909):对齐 `POST /mp/product/{id}/quote` 接口
---
## 一、新增字段(`MpOrderDetailVO`)
| 字段 | 类型 | 说明 |
|------|------|------|
| `singleRoomSurcharge` | BigDecimal | 单房差实际加价金额(下单时按 D1: `adultCount==1` 触发);老订单/不触发 = `null` |
| `earlyBirdDiscount` | BigDecimal | 早鸟优惠金额(从 `order_discount` 表 EARLY_BIRD 取);无早鸟 = `null` |
| `earlyBirdPlanName` | String | 命中的早鸟计划名称(格式 `"早鸟优惠:xxx"`);无早鸟 = `null` |
| `finalGrandTotal` | BigDecimal | **应付总额** = `priceBreakdown.totalPayable` = `totalPrice - 优惠总额 + 附加费总额` |
| `finalBalanceAmount` | BigDecimal | **应付尾款**:DEPOSIT 模式 = `balanceAmount - earlyBirdDiscount`;FULL 模式 = `null` |
字段位置:`discountAmount` 之后、`priceBreakdown` 之前。
## 二、响应示例
订单 1 大 1 小、班期单房差 500、命中早鸟优惠 200、DEPOSIT 模式(订金 1000):
```json
{
"code": 200,
"data": {
"orderId": "2052941051093520386",
"adultCount": 1,
"childCount": 1,
"totalPrice": 5850.00,
"depositAmount": 1000.00,
"balanceAmount": 5850.00,
"discountAmount": 200.00,
"singleRoomSurcharge": 500.00,
"earlyBirdDiscount": 200.00,
"earlyBirdPlanName": "早鸟优惠:暑期早鸟",
"finalGrandTotal": 5650.00,
"finalBalanceAmount": 5650.00,
"priceBreakdown": {
"items": [
{ "label": "成人", "unitPrice": 2925, "quantity": 1, "amount": 2925 },
{ "label": "儿童", "unitPrice": 2425, "quantity": 1, "amount": 2425 },
{ "label": "单房差", "unitPrice": null, "quantity": null, "amount": 500 }
],
"subtotal": 5850.00,
"discounts": [
{ "tag": "早鸟优惠", "description": "早鸟优惠:暑期早鸟", "amount": -200.00 }
],
"totalDiscount": -200.00,
"totalPayable": 5650.00
}
}
}
```
## 三、字段使用建议(mmg)
订单详情页价格区域可用**两种展示风格**任选其一:
### 风格 A:简洁(推荐,与 quote 接口一致)
```
团费总价 ¥5,850.00 ← totalPrice (含单房差)
单房差 +¥500.00 ← singleRoomSurcharge (条件展示, null 隐藏)
早鸟优惠 -¥200.00 ← earlyBirdDiscount (条件展示, null 隐藏)
应付总额 ¥5,650.00 ← finalGrandTotal (粗体,主视觉)
其中订金 ¥1,000.00 ← depositAmount
应付尾款 ¥5,650.00 ← finalBalanceAmount (DEPOSIT 模式)
```
### 风格 B:展开明细(用现有 priceBreakdown 数组渲染)
继续用 `priceBreakdown.items` + `priceBreakdown.discounts` + `priceBreakdown.surcharges` 列表渲染明细,**总价显示用 `finalGrandTotal`**(等同 `priceBreakdown.totalPayable`)。
## 四、PR #1906 修复内容
**问题**:`GroupOrderStrategy.calculatePrice` 序列化 `priceBreakdownJson` 时手动 copy 字段,**漏 set `singleRoomDiff``singleRoomSurcharge`**。导致 mp 端 `priceBreakdown.items` 解析时 `isMissingNode` 跳过,GROUP 订单详情明细面板看不到"单房差"行。
**修复**:加 2 行 `q.setSingleRoomDiff(quote.getSingleRoomDiff()); q.setSingleRoomSurcharge(quote.getSingleRoomSurcharge());`
`CoreOrderStrategy.calculatePrice` 直接 `objectMapper.writeValueAsString(quote)` 序列化整个 SimpleQuoteVO,**无此问题**。
## 五、向后兼容
- 老订单 `priceBreakdown` JSON 缺 `singleRoomSurcharge` → 5 字段中 `singleRoomSurcharge=null`,其他正常
- 无早鸟订单 → `earlyBirdDiscount=null`,`earlyBirdPlanName=null`,`finalBalanceAmount=balanceAmount`(无优惠减)
- FULL 模式 → `finalBalanceAmount=null`(全款无尾款概念)
- 老前端不读新字段不报错(Jackson `fail-on-unknown-properties=false`)
- 未改 `totalPrice` / `discountAmount` / `priceBreakdown` 现有字段语义
## 六、测试覆盖
- `GroupOrderStrategyTest +1`(快照含 singleRoomDiff/Surcharge,#1906)
- `MpOrderDetailAssemblerTest +4`(单房差+早鸟+老订单+FULL,#1909)
- 共 +5 用例,**全绿**
## 七、@mmg 关注点
1. 订单详情页价格区域改造:加"单房差"行 + "早鸟优惠"行(都是条件展示,null 隐藏)
2. 总价用 `finalGrandTotal`(应付总额)替代 `totalPrice`(后者含单房差但不减优惠,继续保留作为"团费原价")
3. 应付尾款 DEPOSIT 模式用 `finalBalanceAmount`,FULL 模式用 `totalPrice`
4. 老前端不动也能跑(只是看不到新字段拆分)
5. 已存在的"老订单"(单房差功能上线前下的)`singleRoomSurcharge=null` 仍按原 totalPrice 展示,行为不变