docs(changelog): #7066 团期子订单列表补应收总额 totalAmount
changelog-filename-gate / validate (push) Successful in 2s
changelog-filename-gate / validate (push) Successful in 2s
GET /v3/admin/order/group-batch/:groupBatchId/orders 出参新增 totalAmount 应收总额,口径复用既有 OrderAmountUtil.payableForDisplay(取消单归 0), 与 calcBalance 口径一致。纯 additive,不新建端点、不改老字段语义。 关键变化:前端不要再用 paidAmount + balanceAmount 反推应收总额。 balanceAmount 被钳在 ≥0,超付/退款/取消单三种情况反推值都偏大。 2026-09-04 于测试环境网关实测 8 组用例全部通过,两处在真实数据上 命中本单要修的缺陷: - 超付单 totalAmount=2943.00,旧反推得 3270.00,偏差 327.00 - 取消单 totalAmount=0.00 而 paidAmount=3270.00,旧算法会把已取消 子订单显示成有应收 backend_status=deployed / gateway_status=verified。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
这个提交包含在:
@@ -0,0 +1,267 @@
|
||||
---
|
||||
schema: "hl-changelog/v2"
|
||||
ticket: "7066"
|
||||
title: "团期子订单列表补应收总额 totalAmount"
|
||||
consumer: "admin"
|
||||
author: "jw(GIT)"
|
||||
change_type: "修改接口"
|
||||
backend_status: "deployed"
|
||||
gateway_status: "verified"
|
||||
frontend_status: "pending"
|
||||
frontend_owner: ""
|
||||
frontend_ref: ""
|
||||
target_release: ""
|
||||
verified_at: "2026-09-04"
|
||||
status_note: "PR #7068 已合入 dev-v3(合并提交 e1ad8550b);2026-09-04 部署测试环境,网关实测 8 组用例全部通过(含取消单归 0)"
|
||||
updated_at: "2026-09-04"
|
||||
base: "dev-v3"
|
||||
---
|
||||
|
||||
# 团期子订单: 出参新增应收总额 totalAmount
|
||||
|
||||
> **服务**: hl-order-service-v3
|
||||
> **PR**: #7068 | **Issue**: #7066 | **合并提交**: `e1ad8550b`
|
||||
> **影响范围**: 管理后台「团期详情 → 子订单」页签
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ 关键变化
|
||||
|
||||
**前端不要再用 `paidAmount + balanceAmount` 反推应收总额,改读新增的 `totalAmount`。**
|
||||
|
||||
旧反推在两种场景下**偏大**:
|
||||
|
||||
1. `balanceAmount` 被钳在 ≥0(`OrderAmountUtil.calcBalance` 末行),超付或退款后已付大于应收时反推值偏大
|
||||
2. 已取消子订单 `calcBalance` 直接返 0,反推得到的是已付而非应收
|
||||
|
||||
**这不是理论风险**:2026-09-04 测试环境实测,现存子订单 `paidAmount=3270.00`、`balanceAmount=0.00`,
|
||||
而真实应收 `totalAmount=2943.00`——**旧算法多显示 327.00**。
|
||||
|
||||
---
|
||||
|
||||
## 一、背景
|
||||
|
||||
团期详情「子订单」页签每张卡片显示「已付 / 应收总额」,但列表接口出参此前没有应收总额字段,
|
||||
前端只能自行反推。本次补齐该字段,口径与订单域既有展示口径统一。
|
||||
|
||||
---
|
||||
|
||||
## 二、变更接口清单
|
||||
|
||||
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|
||||
|---|------|------|------|----------|------|
|
||||
| 1 | 团期下子订单列表 | GET | `/v3/admin/order/group-batch/:groupBatchId/orders` | **出参新增字段** | 新增 `totalAmount` 应收总额 |
|
||||
|
||||
---
|
||||
|
||||
## 三、接口详情
|
||||
|
||||
### 1. 团期下子订单列表 `GET /v3/admin/order/group-batch/:groupBatchId/orders`
|
||||
|
||||
**VO**: `GroupBatchOrderItemRespVO`
|
||||
|
||||
#### 使用场景
|
||||
|
||||
团期详情「子订单」页签加载时调用,渲染每户卡片。卡片右下角「已付 ¥X / ¥Y」中的 Y 即本次新增的 `totalAmount`。
|
||||
|
||||
#### 入参
|
||||
|
||||
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||||
|------|------|------|------|------|------|
|
||||
| `groupBatchId` | Path | Long | ✅ | — | 运营团期 ID(订单侧 `order_group_batch` 主键) |
|
||||
| `includeTravelers` | Query | Boolean | ❌ | 缺省 false | 附出行人明细,证件号一律不返回 |
|
||||
| `includeNeeds` | Query | Boolean | ❌ | 缺省 false | 附房数 / 房型 / 特殊需求 |
|
||||
| `includeCancelled` | Query | Boolean | ❌ | 缺省 false | 是否含已取消子订单,缺省只返活跃集 |
|
||||
|
||||
#### 出参 `Result<List<GroupBatchOrderItemRespVO>>`
|
||||
|
||||
本次仅新增一个字段,其余 28 个字段不变:
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `totalAmount` | String | **本次新增**。应收总额 = `orderAmount + 增项 − 优惠`;**已取消子订单归 0**。2 位小数,字符串输出 |
|
||||
| `paidAmount` | String | 已支付金额(未变) |
|
||||
| `balanceAmount` | String | 待支付尾款,**钳在 ≥0**(未变) |
|
||||
|
||||
> 三个金额字段均带 `@JsonSerialize(ToStringSerializer)`,**JSON 里是字符串**,前端直接解析为数字会有精度风险,应按字符串处理或用高精度解析。
|
||||
|
||||
#### 请求示例
|
||||
|
||||
```http
|
||||
GET /v3/admin/order/group-batch/2089713777065832450/orders
|
||||
```
|
||||
|
||||
#### 响应示例
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "成功",
|
||||
"success": true,
|
||||
"data": [
|
||||
{
|
||||
"orderId": 2094597053924487170,
|
||||
"customerName": "6915验收造单01",
|
||||
"orderStatus": "CUSTOMIZING",
|
||||
"orderStatusName": "定制中",
|
||||
"adultCount": 2,
|
||||
"childCount": 0,
|
||||
"participantCount": 2,
|
||||
"contactPhone": "138****0001",
|
||||
"paidAmount": "3270.00",
|
||||
"balanceAmount": "0.00",
|
||||
"totalAmount": "2943.00"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### 空数据 / 降级响应
|
||||
|
||||
团期下无子订单时返回空数组,不报错:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "成功",
|
||||
"success": true,
|
||||
"data": []
|
||||
}
|
||||
```
|
||||
|
||||
#### 错误响应
|
||||
|
||||
未携带管理端令牌:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 401,
|
||||
"message": "缺少有效的 Authorization 头",
|
||||
"success": false,
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
#### 业务边界
|
||||
|
||||
- 只读接口,不产生任何写入
|
||||
- `totalAmount` **不等于** `paidAmount + balanceAmount`,超付、退款、取消单三种情况下都会不等
|
||||
- 已取消子订单(`includeCancelled=true` 才可见)的 `totalAmount` 与 `balanceAmount` 同为 0,闭合财务勾稽
|
||||
- 金额一律 2 位小数(HALF_UP),与订单域其他接口格式一致
|
||||
|
||||
---
|
||||
|
||||
## 四、契约约束与正确调用方式
|
||||
|
||||
- **应收总额一律读 `totalAmount`**,不要自行用 `paidAmount + balanceAmount` 计算。
|
||||
- **`totalAmount` 与 `balanceAmount` 是不同语义**:前者是「客户总共该付多少」,后者是「现在还差多少」。已付清时后者为 0,前者仍是原值。
|
||||
- **三个金额字段是 JSON 字符串**,不是数字。
|
||||
- 取消单场景下 `totalAmount` 归 0 是**有意设计**(对齐 `calcBalance` 的取消单归 0),用于闭合「应收 0 / 已付 0 / 已退 0 / 待收 0」的勾稽链,不是缺陷。
|
||||
|
||||
---
|
||||
|
||||
## 五、数据库行为
|
||||
|
||||
本接口只读,**不产生任何写入**,也不涉及表结构调整。`totalAmount` 由既有字段实时计算,不新增存储列。
|
||||
|
||||
---
|
||||
|
||||
## 六、边界行为
|
||||
|
||||
- 超付单 → `totalAmount` 为真实应收,小于 `paidAmount`
|
||||
- 取消单 → `totalAmount` 归 0
|
||||
- 团期无子订单 → 返回 `[]`
|
||||
- 未登录 → 401(网关拦截)
|
||||
|
||||
---
|
||||
|
||||
## 六.5、枚举 / 数据字典
|
||||
|
||||
本次无新增枚举。
|
||||
|
||||
---
|
||||
|
||||
## 六.6、修改前后对比
|
||||
|
||||
| 项 | 变更前 | 变更后 |
|
||||
|---|---|---|
|
||||
| 出参字段数 | 28 | **29** |
|
||||
| 应收总额 | **无字段**,前端用 `paidAmount + balanceAmount` 反推 | 新增 `totalAmount`,服务端按既有 `payableForDisplay` 口径给出 |
|
||||
| 超付单显示 | 反推值偏大(实测多 327.00) | `totalAmount` 为真实应收 |
|
||||
| 取消单显示 | 反推得到已付金额,非应收 | `totalAmount` 归 0,与 `balanceAmount` 一致 |
|
||||
| `paidAmount` / `balanceAmount` | — | **语义与取值均不变** |
|
||||
| 路径 / 入参 | — | **不变** |
|
||||
|
||||
## 六.7、影响评估
|
||||
|
||||
| 维度 | 评估 |
|
||||
|---|---|
|
||||
| 兼容性 | **纯 additive**,老调用方不读新字段即无感,无破坏性变更 |
|
||||
| 前端 | 需改为读 `totalAmount`;不改也不会报错,但超付 / 取消单场景显示值偏大 |
|
||||
| 数据 | 无 DDL、无迁移、无回填;`totalAmount` 实时计算不落库 |
|
||||
| 性能 | 无额外查询,复用同一 `OrderInfo` 实体计算,零新增 IO |
|
||||
| 回滚 | 移除字段即可,无数据侧残留 |
|
||||
| 风险 | 低。口径复用 `AdjustmentService` 已在生产使用的既有方法,未新造公式 |
|
||||
|
||||
## 七、不影响范围
|
||||
|
||||
- **零影响**:`paidAmount` / `balanceAmount` 的现有语义与取值
|
||||
- **零影响**:其余 28 个出参字段
|
||||
- **零影响**:老调用方——纯新增字段,不读即无感
|
||||
- **未新建端点**,未改动路径与入参
|
||||
|
||||
---
|
||||
|
||||
## 八、测试环境已验证
|
||||
|
||||
✅ 2026-09-04 于测试环境网关实测,真实鉴权(管理端 admin)。
|
||||
|
||||
- 网关 `https://api.test.1814.love`,分支 `dev-v3`,合并提交 `e1ad8550b`
|
||||
- 部署方式:双实例滚动更新(8186 → 8086),各 11s 就绪,零停机
|
||||
|
||||
| # | 用例 | 期望 | 实测 |
|
||||
|---|---|---|---|
|
||||
| 1 | 字段上线 | 出参含 `totalAmount` | ✅ 字段数 27 → 29 |
|
||||
| 2 | 真实数据口径 | `totalAmount` 为真实应收 | ✅ `2943.00`;旧反推得 `3270.00`,**偏差 327.00** |
|
||||
| 3 | 序列化格式 | 字符串、2 位小数 | ✅ `"totalAmount":"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"` |
|
||||
|
||||
**部署前基线对照**:同一接口部署前出参 27 字段、无 `totalAmount`,确认变更确实生效。
|
||||
|
||||
**本地单测**:`GroupBatchConverterTest` 新增 5 例(正常单 / 含增项优惠 / **超付单断言反推不等** / **取消单归 0** / 2 位小数);
|
||||
本地全量 **750 例全过**。
|
||||
|
||||
**取消单分支已实测**(用例 7–8):验收期间该子订单被退单,恰好提供了取消单样本。
|
||||
实测 `totalAmount="0.00"`,而 `paidAmount="3270.00"`——**旧算法 `paidAmount + balanceAmount` 会把一条
|
||||
已取消的子订单显示成「应收 3270」,真实应收应为 0**。本字段同时修正了这一场景。
|
||||
|
||||
全部 8 组用例通过,无遗留未验分支。
|
||||
|
||||
---
|
||||
|
||||
## 九、相关历史 PR
|
||||
|
||||
- #7068 本次变更
|
||||
- 口径来源:`OrderAmountUtil.payableForDisplay`(#4456 展示用应收总额,取消单归 0)
|
||||
- 相关:#5733(`calcBalance` 改为退款冲减应收)、#2896 P1-3(金额统一 2 位小数)
|
||||
|
||||
---
|
||||
|
||||
## 十、相关文档
|
||||
|
||||
- 团期需求文档:`docs/group/`(dev-v3 分支)
|
||||
- 3 天开发计划:`docs/group/团期模块3天开发计划.md`
|
||||
|
||||
---
|
||||
|
||||
## 关联 / 联系人
|
||||
|
||||
- **Issue**: #7066
|
||||
- **PR**: #7068(合并提交 `e1ad8550b`)
|
||||
- **服务**: hl-order-service-v3
|
||||
- **后端**: jw
|
||||
- **前端**: 待认领(`frontend_status: pending`)
|
||||
在新工单中引用
屏蔽一个用户