From 5915b439b5e1d0f79e73d2388a3c3cdb613d5ddb Mon Sep 17 00:00:00 2001 From: API Changelog Bot Date: Tue, 21 Apr 2026 10:04:52 +0800 Subject: [PATCH] =?UTF-8?q?docs(mp-product):=20=E5=B0=8F=E7=A8=8B=E5=BA=8F?= =?UTF-8?q?=E6=8A=A5=E4=BB=B7=E6=8E=A5=E5=8F=A3=E8=A1=A5=E6=97=A9=E9=B8=9F?= =?UTF-8?q?=E4=BC=98=E6=83=A0=E5=AD=97=E6=AE=B5=20(PR=20#1052)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MpQuoteResultVO 新增 5 个字段: earlyBirdDiscount / earlyBirdPlanId / earlyBirdPlanName / finalBalanceAmount / finalGrandTotal - 定金模式: 早鸟扣尾款 → finalBalanceAmount = balanceAmount - discount - 全款模式: 早鸟扣全款 → finalGrandTotal = grandTotal - discount - 未命中: earlyBirdDiscount=0, finalXxx=原值 --- .../2026-04/2026-04-21_mp-quote-early-bird.md | 192 ++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 changelogs/2026-04/2026-04-21_mp-quote-early-bird.md diff --git a/changelogs/2026-04/2026-04-21_mp-quote-early-bird.md b/changelogs/2026-04/2026-04-21_mp-quote-early-bird.md new file mode 100644 index 0000000..4d9511f --- /dev/null +++ b/changelogs/2026-04/2026-04-21_mp-quote-early-bird.md @@ -0,0 +1,192 @@ +# 小程序产品报价 - `/mp/product/{id}/quote` 接口补早鸟优惠字段 + +- **日期**: 2026-04-21 +- **PR**: [#1052](https://git.1814.love:8443/wx/HL/pulls/1052) (Closes #1047) +- **类型**: FEATURE(响应 VO 新增字段,向前兼容) +- **服务**: hl-product-service-v2(路由 `/mp/product/**`) +- **前端是否需要改动**: **建议改动**(展示早鸟优惠金额 + 最终应付金额给用户) + +--- + +## 一、背景 + +之前的报价接口只返回「原价合计」与「原尾款/定金」,但订单创建时后端会**自动扣早鸟优惠**(`OrderCreateService.tryApplyEarlyBirdDiscount()`),导致: + +- 小程序报价页显示 `¥10,510` 尾款 +- 用户提交订单实付却是 `¥10,410`(已扣 100 元早鸟) +- 用户困惑 / 客服被投诉报价不准 + +本次修复让报价接口**同步返回早鸟优惠信息**,与订单实扣完全一致。 + +--- + +## 二、变更接口 + +| # | 方法 | 路径 | 变更类型 | +|---|------|------|---------| +| 1 | POST | `/mp/product/{id}/quote` | 响应 VO 新增 5 个字段;请求参数不变 | + +--- + +## 三、响应 VO 新增字段(`MpQuoteResultVO`) + +| 字段 | 类型 | 含义 | 示例 | +|------|------|------|------| +| `earlyBirdDiscount` | BigDecimal | 早鸟优惠金额(未命中为 0) | `100.00` | +| `earlyBirdPlanId` | Long (字符串) | 命中的早鸟计划 ID(未命中为 null) | `"2046080027564318721"` | +| `earlyBirdPlanName` | String | 命中的早鸟计划名称(展示用,未命中为 null) | `"暑期早鸟"` | +| `finalBalanceAmount` | BigDecimal | **定金模式**下最终应付尾款 = `balanceAmount - earlyBirdDiscount`;全款模式为 `null` | `10410.00` | +| `finalGrandTotal` | BigDecimal | 最终应付总价 = `grandTotal - earlyBirdDiscount` | `11410.00` | + +**其它字段不变**:`grandTotal` / `balanceAmount` / `depositAmount` 仍是「原始价」,仅新增的 `finalXxx` 是「扣优惠后最终应付」。 + +--- + +## 四、业务规则(与订单实扣对齐) + +- 早鸟优惠**按下单日期**生效(调用报价的当下,等于订单创建时的日期) +- **定金模式 (DEPOSIT)**:定金**原价收**,早鸟优惠**从尾款扣** + - `finalBalanceAmount = balanceAmount - earlyBirdDiscount` + - `finalGrandTotal = grandTotal - earlyBirdDiscount`(整单一致) +- **全款模式 (FULL)**:早鸟优惠**从全款扣** + - `finalBalanceAmount = null` + - `finalGrandTotal = grandTotal - earlyBirdDiscount` +- **未命中 / 查询失败** → `earlyBirdDiscount = 0`,`earlyBirdPlanId = null`,`finalXxx = 原值` +- **人数门槛**:总人数(成人 + 儿童 + 小童 + 幼童)< 计划 `minPeople` → 不命中 +- **金额封顶**:早鸟优惠 ≤ 对应金额池(定金模式下不超过尾款;全款模式下不超过总价),不会让尾款 / 全款为负 + +--- + +## 五、响应示例 + +### 定金模式 + 命中早鸟(2 成人) + +```json +{ + "code": 200, + "success": true, + "data": { + "adultUnitPrice": 5755.00, + "totalAdultPrice": 11510.00, + "grandTotal": 11510.00, + "paymentType": "DEPOSIT", + "depositAmount": 1000.00, + "balanceAmount": 10510.00, + + "earlyBirdDiscount": 100.00, + "earlyBirdPlanId": "2046080027564318721", + "earlyBirdPlanName": "BUG20测试-2人", + "finalBalanceAmount": 10410.00, + "finalGrandTotal": 11410.00 + } +} +``` + +### 全款模式 + 命中早鸟 + +```json +{ + "data": { + "grandTotal": 8000.00, + "paymentType": "FULL", + "balanceAmount": null, + + "earlyBirdDiscount": 500.00, + "earlyBirdPlanId": "1234567890", + "earlyBirdPlanName": "全款早鸟", + "finalBalanceAmount": null, + "finalGrandTotal": 7500.00 + } +} +``` + +### 未命中早鸟 + +```json +{ + "data": { + "grandTotal": 5000.00, + "balanceAmount": 4000.00, + + "earlyBirdDiscount": 0, + "earlyBirdPlanId": null, + "earlyBirdPlanName": null, + "finalBalanceAmount": 4000.00, + "finalGrandTotal": 5000.00 + } +} +``` + +--- + +## 六、前端使用建议 + +### 场景 A:报价页展示早鸟优惠 + +```tsx +{data.earlyBirdDiscount > 0 && ( + + 早鸟优惠 {data.earlyBirdPlanName} + -¥{data.earlyBirdDiscount} + +)} +``` + +### 场景 B:定金模式下拆分展示 + +```tsx +订金(立付):¥{data.depositAmount} + +{data.earlyBirdDiscount > 0 ? ( + <> + 原尾款:¥{data.balanceAmount} + 最终尾款:¥{data.finalBalanceAmount} + +) : ( + 尾款:¥{data.balanceAmount} +)} +``` + +### 场景 C:全款模式下拆分展示 + +```tsx +{data.paymentType === 'FULL' && data.earlyBirdDiscount > 0 ? ( + <> + 原价:¥{data.grandTotal} + 最终应付:¥{data.finalGrandTotal} + +) : ( + 应付:¥{data.grandTotal} +)} +``` + +### ⚠️ 注意 + +- `earlyBirdPlanId` 是 Long,JSON 序列化为**字符串**防精度丢失(与项目其它 ID 字段一致) +- 未命中早鸟时 `finalBalanceAmount` / `finalGrandTotal` **等于**原值,可以无脑展示 `finalXxx`(无需判断) +- `earlyBirdDiscount` 一定是 `BigDecimal` 形式的数字(`0` 或 `>0`),不会是 null +- **全款模式**下 `finalBalanceAmount` 固定为 `null`(与 `balanceAmount` 语义保持一致) + +--- + +## 七、不兼容变更 + +**无**。仅响应 VO 新增字段,既有字段语义与取值完全不变。旧客户端(没更新适配的)继续按原逻辑渲染,只是看不到早鸟优惠而已。 + +--- + +## 八、回归验证 + +```bash +# 测试产品(班期内有早鸟"BUG20测试-2人") +curl -sk -X POST "https://api.test.1814.love:9443/mp/product/2044603865881333762/quote" \ + -H "Content-Type: application/json" \ + -d '{"departureDate":"2026-05-10","adultCount":2,"childCount":0,"tierSeq":1}' | jq .data +``` + +**预期**: + +- `earlyBirdDiscount: 100.00` +- `earlyBirdPlanName: "BUG20测试-2人"` +- `finalBalanceAmount = balanceAmount - 100` +- `finalGrandTotal = grandTotal - 100`