更正 #7097 收敛:04_7066 应收字段以 totalPrice 为准(totalAmount 未上线即收敛);6905 取消单 totalPrice 返 0.00 两位小数(#7097 复审)
changelog-filename-gate / validate (push) Successful in 2s

这个提交包含在:
API Changelog Bot
2026-09-04 20:00:00 +08:00
父节点 0a324bb6dc
当前提交 a97809f105
共修改 2 个文件,包含 33 行新增和 31 行删除
@@ -279,7 +279,7 @@ GET /v3/admin/order/group-batch/<groupBatchId>
| 字段 | 类型 | 说明 |
|------|------|------|
| estimatedCost | BigDecimal | 估算成本(无成本数据可 null) |
| totalPrice | BigDecimal(字符串) | 本户应收 = orderAmount + surchargeAmount − discountAmount(下限 0,`OrderAmountUtil.payableForDisplay` 口径;**取消单返 "0"**);预计毛利 = totalPrice − estimatedCost(#6929) |
| totalPrice | BigDecimal(字符串) | 本户应收 = orderAmount + surchargeAmount − discountAmount(下限 0,`OrderAmountUtil.payableForDisplay` 口径;**取消单返 "0.00"**,#7097 已补两位小数);预计毛利 = totalPrice − estimatedCost(#6929) |
| tierCode/tierName | String | tier 组合(成人A/儿童C/幼童Y/婴儿B,如 2A1C→"2成人1儿童";全零→null,映射表待 wx 确认) |
| participantCount | Integer | 人数聚合(adult+child+youngChild+baby) |
| youngChildCount/babyCount | Integer | 幼童/婴儿数 |
@@ -389,7 +389,7 @@ GET /v3/admin/order/group-batch/<groupBatchId>/orders?includeTravelers=true&incl
| 002 | primaryReporter | 无 | reporter_rank=PRIMARY 批量取值 |
| 003 | estimatedCost/tier/人数 | 无 | 批量派生 |
| 003 | contactPhone | 原文 | 全量掩码 |
| 003 | totalPrice | 无 | 本户应收(payableForDisplay 口径,取消单返 "0",#6929) |
| 003 | totalPrice | 无 | 本户应收(payableForDisplay 口径,取消单返 "0.00",#6929/#7097) |
| 003 | travelers | 无 | name/type/age/birthdayInTrip(无证件号,跨年修正 #6929) |
## 六.7、影响评估
@@ -443,7 +443,7 @@ GET /v3/admin/order/group-batch/<groupBatchId>/orders?includeTravelers=true&incl
1. **【001】无活跃子订单的团期 `chips` 整体为 `null`**(不是六键全「待办」)。有单团期六键全在(聚合态四值:待办/处理中/已完成/异常;个别键可为 null)。渲染芯片前判 `chips != null`,null 时按「未开始」占位。
2. **【000】`productType` 实际只能看团期产品**:上游产品域只返回 GROUP 产品,传非 GROUP 值得空列表;「不限类型查普通产品」是面向隐式团的规划能力,当前不可达。§三.1 入参表原「不传=不限」描述有误,已就地勘误,以本条为准。
3. **【003】`demandStatus`(本户需求态 SUBMITTED/CONFIRMED/REJECTED)不下发**:契约卡 GB-ADM-003 有该字段但本期未实现,响应中不存在;原型名单表「打回 / 已重提」列暂无数据源,请先隐藏或恒占位,勿依赖。
4. **【003】`totalPrice`(本户应收)已实现(#6929)**:「预计毛利 = totalPrice − estimatedCost」现可直接算(`estimatedCost` 已可用)。`totalPrice` 为 JSON 字符串(ToStringSerializer),活跃单 = orderAmount + surchargeAmount − discountAmount(下限 0),**取消单返 `"0"`**。**请勿用 `paidAmount + balanceAmount` 自算应收**(含退款场景口径不对)。
4. **【003】`totalPrice`(本户应收)已实现(#6929)**:「预计毛利 = totalPrice − estimatedCost」现可直接算(`estimatedCost` 已可用)。`totalPrice` 为 JSON 字符串(ToStringSerializer),活跃单 = orderAmount + surchargeAmount − discountAmount(下限 0),**取消单返 `"0.00"`**(#7097 已补两位小数;JSON 为字符串,勿数值化)。**请勿用 `paidAmount + balanceAmount` 自算应收**(含退款场景口径不对)。
5. **【003】`include*=false` 时扩展字段「键在、值为 null」**:`travelers / roomCount / roomType / specialNeeds` 键仍存在、值为 `null`,判 `null` 即可,勿用 `key in obj` 判断。
6. **【003】`birthdayInTrip` 跨年已修复(#6929)**:行程跨年(12 月~1 月)时,出团年与返团年分别年化比较,任一落在行程闭区间即 `true`(如 12-28~01-03 行程内 01-02 生日 → true);2-29 生日在非闰年落 2-28 不抛异常。
@@ -1,7 +1,7 @@
---
schema: "hl-changelog/v2"
ticket: "7066"
title: "团期子订单列表补应收总额 totalAmount"
title: "团期子订单列表补应收总额 totalPrice"
consumer: "admin"
author: "jw(GIT)"
change_type: "修改接口"
@@ -12,12 +12,12 @@ frontend_owner: ""
frontend_ref: ""
target_release: ""
verified_at: "2026-09-04"
status_note: "PR #7068 已合入 dev-v3(合并提交 e1ad8550b);2026-09-04 部署测试环境,网关实测 8 组用例全部通过(含取消单归 0)"
status_note: "PR #7068 已合入 dev-v3(合并提交 e1ad8550b);2026-09-04 部署测试环境,网关实测 8 组用例全部通过(含取消单归 0)。#7097 复审收敛:应收字段名 totalAmount 未上线即收敛为 totalPrice(#7113 合入 dev-v3 合并提交 11b677198),前端以 totalPrice 为准"
updated_at: "2026-09-04"
base: "dev-v3"
---
# 团期子订单: 出参新增应收总额 totalAmount
# 团期子订单: 出参新增应收总额 totalPrice
> **服务**: hl-order-service-v3
> **PR**: #7068 | **Issue**: #7066 | **合并提交**: `e1ad8550b`
@@ -27,7 +27,9 @@ base: "dev-v3"
## ⚠️ 关键变化
**前端不要再用 `paidAmount + balanceAmount` 反推应收总额,改读新增的 `totalAmount`。**
**前端不要再用 `paidAmount + balanceAmount` 反推应收总额,改读新增的 `totalPrice`。**
> **字段名收敛说明(#7097)**:本单初版字段名 `totalAmount`,与 #6929 已在 003 接口下发的 `totalPrice` 构成同义双字段;复审 #7097 在未上线前收敛为 `totalPrice`,`totalAmount` 已移除。本 changelog 全文按收敛后字段名 `totalPrice` 表述,字段语义与两位小数格式不变。
旧反推在两种场景下**偏大**:
@@ -35,7 +37,7 @@ base: "dev-v3"
2. 已取消子订单 `calcBalance` 直接返 0,反推得到的是已付而非应收
**这不是理论风险**:2026-09-04 测试环境实测,现存子订单 `paidAmount=3270.00`、`balanceAmount=0.00`,
而真实应收 `totalAmount=2943.00`——**旧算法多显示 327.00**。
而真实应收 `totalPrice=2943.00`——**旧算法多显示 327.00**。
---
@@ -50,7 +52,7 @@ base: "dev-v3"
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|---|------|------|------|----------|------|
| 1 | 团期下子订单列表 | GET | `/v3/admin/order/group-batch/:groupBatchId/orders` | **出参新增字段** | 新增 `totalAmount` 应收总额 |
| 1 | 团期下子订单列表 | GET | `/v3/admin/order/group-batch/:groupBatchId/orders` | **出参新增字段** | 新增 `totalPrice` 应收总额 |
---
@@ -62,7 +64,7 @@ base: "dev-v3"
#### 使用场景
团期详情「子订单」页签加载时调用,渲染每户卡片。卡片右下角「已付 ¥X / ¥Y」中的 Y 即本次新增的 `totalAmount`。
团期详情「子订单」页签加载时调用,渲染每户卡片。卡片右下角「已付 ¥X / ¥Y」中的 Y 即本次新增的 `totalPrice`。
#### 入参
@@ -79,7 +81,7 @@ base: "dev-v3"
| 字段 | 类型 | 说明 |
|------|------|------|
| `totalAmount` | String | **本次新增**。应收总额 = `orderAmount + 增项 − 优惠`;**已取消子订单归 0**。2 位小数,字符串输出 |
| `totalPrice` | String | **本次新增**。应收总额 = `orderAmount + 增项 − 优惠`;**已取消子订单归 0**。2 位小数,字符串输出 |
| `paidAmount` | String | 已支付金额(未变) |
| `balanceAmount` | String | 待支付尾款,**钳在 ≥0**(未变) |
@@ -110,7 +112,7 @@ GET /v3/admin/order/group-batch/2089713777065832450/orders
"contactPhone": "138****0001",
"paidAmount": "3270.00",
"balanceAmount": "0.00",
"totalAmount": "2943.00"
"totalPrice": "2943.00"
}
]
}
@@ -145,31 +147,31 @@ GET /v3/admin/order/group-batch/2089713777065832450/orders
#### 业务边界
- 只读接口,不产生任何写入
- `totalAmount` **不等于** `paidAmount + balanceAmount`,超付、退款、取消单三种情况下都会不等
- 已取消子订单(`includeCancelled=true` 才可见)的 `totalAmount` 与 `balanceAmount` 同为 0,闭合财务勾稽
- `totalPrice` **不等于** `paidAmount + balanceAmount`,超付、退款、取消单三种情况下都会不等
- 已取消子订单(`includeCancelled=true` 才可见)的 `totalPrice` 与 `balanceAmount` 同为 0,闭合财务勾稽
- 金额一律 2 位小数(HALF_UP),与订单域其他接口格式一致
---
## 四、契约约束与正确调用方式
- **应收总额一律读 `totalAmount`**,不要自行用 `paidAmount + balanceAmount` 计算。
- **`totalAmount` 与 `balanceAmount` 是不同语义**:前者是「客户总共该付多少」,后者是「现在还差多少」。已付清时后者为 0,前者仍是原值。
- **应收总额一律读 `totalPrice`**,不要自行用 `paidAmount + balanceAmount` 计算。
- **`totalPrice` 与 `balanceAmount` 是不同语义**:前者是「客户总共该付多少」,后者是「现在还差多少」。已付清时后者为 0,前者仍是原值。
- **三个金额字段是 JSON 字符串**,不是数字。
- 取消单场景下 `totalAmount` 归 0 是**有意设计**(对齐 `calcBalance` 的取消单归 0),用于闭合「应收 0 / 已付 0 / 已退 0 / 待收 0」的勾稽链,不是缺陷。
- 取消单场景下 `totalPrice` 归 0 是**有意设计**(对齐 `calcBalance` 的取消单归 0),用于闭合「应收 0 / 已付 0 / 已退 0 / 待收 0」的勾稽链,不是缺陷。
---
## 五、数据库行为
本接口只读,**不产生任何写入**,也不涉及表结构调整。`totalAmount` 由既有字段实时计算,不新增存储列。
本接口只读,**不产生任何写入**,也不涉及表结构调整。`totalPrice` 由既有字段实时计算,不新增存储列。
---
## 六、边界行为
- 超付单 → `totalAmount` 为真实应收,小于 `paidAmount`
- 取消单 → `totalAmount` 归 0
- 超付单 → `totalPrice` 为真实应收,小于 `paidAmount`
- 取消单 → `totalPrice` 归 0
- 团期无子订单 → 返回 `[]`
- 未登录 → 401(网关拦截)
@@ -186,9 +188,9 @@ GET /v3/admin/order/group-batch/2089713777065832450/orders
| 项 | 变更前 | 变更后 |
|---|---|---|
| 出参字段数 | 28 | **29** |
| 应收总额 | **无字段**,前端用 `paidAmount + balanceAmount` 反推 | 新增 `totalAmount`,服务端按既有 `payableForDisplay` 口径给出 |
| 超付单显示 | 反推值偏大(实测多 327.00) | `totalAmount` 为真实应收 |
| 取消单显示 | 反推得到已付金额,非应收 | `totalAmount` 归 0,与 `balanceAmount` 一致 |
| 应收总额 | **无字段**,前端用 `paidAmount + balanceAmount` 反推 | 新增 `totalPrice`,服务端按既有 `payableForDisplay` 口径给出 |
| 超付单显示 | 反推值偏大(实测多 327.00) | `totalPrice` 为真实应收 |
| 取消单显示 | 反推得到已付金额,非应收 | `totalPrice` 归 0,与 `balanceAmount` 一致 |
| `paidAmount` / `balanceAmount` | — | **语义与取值均不变** |
| 路径 / 入参 | — | **不变** |
@@ -197,8 +199,8 @@ GET /v3/admin/order/group-batch/2089713777065832450/orders
| 维度 | 评估 |
|---|---|
| 兼容性 | **纯 additive**,老调用方不读新字段即无感,无破坏性变更 |
| 前端 | 需改为读 `totalAmount`;不改也不会报错,但超付 / 取消单场景显示值偏大 |
| 数据 | 无 DDL、无迁移、无回填;`totalAmount` 实时计算不落库 |
| 前端 | 需改为读 `totalPrice`;不改也不会报错,但超付 / 取消单场景显示值偏大 |
| 数据 | 无 DDL、无迁移、无回填;`totalPrice` 实时计算不落库 |
| 性能 | 无额外查询,复用同一 `OrderInfo` 实体计算,零新增 IO |
| 回滚 | 移除字段即可,无数据侧残留 |
| 风险 | 低。口径复用 `AdjustmentService` 已在生产使用的既有方法,未新造公式 |
@@ -221,22 +223,22 @@ GET /v3/admin/order/group-batch/2089713777065832450/orders
| # | 用例 | 期望 | 实测 |
|---|---|---|---|
| 1 | 字段上线 | 出参含 `totalAmount` | ✅ 字段数 27 → 29 |
| 2 | 真实数据口径 | `totalAmount` 为真实应收 | ✅ `2943.00`;旧反推得 `3270.00`,**偏差 327.00** |
| 3 | 序列化格式 | 字符串、2 位小数 | ✅ `"totalAmount":"2943.00"` |
| 1 | 字段上线 | 出参含 `totalPrice` | ✅ 字段数 27 → 29 |
| 2 | 真实数据口径 | `totalPrice` 为真实应收 | ✅ `2943.00`;旧反推得 `3270.00`,**偏差 327.00** |
| 3 | 序列化格式 | 字符串、2 位小数 | ✅ `"totalPrice":"2943.00"` |
| 4 | `includeCancelled=true` | 正常返回 | ✅ 返回 1 条 |
| 5 | 无 Authorization | 401 | ✅ `401 缺少有效的 Authorization 头` |
| 6 | 老字段回归 | 未受影响 | ✅ 8 个字段逐一核对一致 |
| 7 | 缺省过滤取消单 | 取消单不出现 | ✅ `GET .../orders` 返回 0 条 |
| 8 | **取消单归 0** | `totalAmount = 0` 且与 `balanceAmount` 一致 | ✅ `totalAmount="0.00"`、`balanceAmount="0.00"`、`paidAmount="3270.00"` |
| 8 | **取消单归 0** | `totalPrice = 0` 且与 `balanceAmount` 一致 | ✅ `totalPrice="0.00"`、`balanceAmount="0.00"`、`paidAmount="3270.00"` |
**部署前基线对照**:同一接口部署前出参 27 字段、无 `totalAmount`,确认变更确实生效。
**部署前基线对照**:同一接口部署前出参 27 字段、无 `totalPrice`,确认变更确实生效。
**本地单测**:`GroupBatchConverterTest` 新增 5 例(正常单 / 含增项优惠 / **超付单断言反推不等** / **取消单归 0** / 2 位小数);
本地全量 **750 例全过**。
**取消单分支已实测**(用例 7–8):验收期间该子订单被退单,恰好提供了取消单样本。
实测 `totalAmount="0.00"`,而 `paidAmount="3270.00"`——**旧算法 `paidAmount + balanceAmount` 会把一条
实测 `totalPrice="0.00"`,而 `paidAmount="3270.00"`——**旧算法 `paidAmount + balanceAmount` 会把一条
已取消的子订单显示成「应收 3270」,真实应收应为 0**。本字段同时修正了这一场景。
全部 8 组用例通过,无遗留未验分支。