From db6698061ba48cb2ad395683fae4761e2242af74 Mon Sep 17 00:00:00 2001 From: jw Date: Fri, 4 Sep 2026 15:01:20 +0800 Subject: [PATCH] =?UTF-8?q?docs(changelog):=20#7066=20=E5=9B=A2=E6=9C=9F?= =?UTF-8?q?=E5=AD=90=E8=AE=A2=E5=8D=95=E5=88=97=E8=A1=A8=E8=A1=A5=E5=BA=94?= =?UTF-8?q?=E6=94=B6=E6=80=BB=E9=A2=9D=20totalAmount?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- ...期子订单列表补应收总额-修改接口-管理后台.md | 267 ++++++++++++++++++ 1 file changed, 267 insertions(+) create mode 100644 changelogs-v2/2026-09/04_7066_团期子订单列表补应收总额-修改接口-管理后台.md diff --git a/changelogs-v2/2026-09/04_7066_团期子订单列表补应收总额-修改接口-管理后台.md b/changelogs-v2/2026-09/04_7066_团期子订单列表补应收总额-修改接口-管理后台.md new file mode 100644 index 00000000..28a0ba9f --- /dev/null +++ b/changelogs-v2/2026-09/04_7066_团期子订单列表补应收总额-修改接口-管理后台.md @@ -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>` + +本次仅新增一个字段,其余 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`)