docs(changelog): 订正 04_8714 团期核单 alloc-preview 试算回执 splits.teamNo 由恒 null 改为已填充真实团号(#8786 / PR #8787)
changelog-filename-gate / validate (push) Failing after 2s
changelog-filename-gate / validate (push) Failing after 2s
这个提交包含在:
@@ -0,0 +1,277 @@
|
|||||||
|
---
|
||||||
|
schema: "hl-changelog/v2"
|
||||||
|
ticket: "8786"
|
||||||
|
title: "团期核单 alloc-preview 试算回执 splits.teamNo 由恒 null 订正为已填充真实团号"
|
||||||
|
consumer: "admin"
|
||||||
|
author: "yst"
|
||||||
|
change_type: "修改接口"
|
||||||
|
backend_status: "merged"
|
||||||
|
gateway_status: "not_required"
|
||||||
|
frontend_status: "pending"
|
||||||
|
frontend_owner: ""
|
||||||
|
frontend_ref: ""
|
||||||
|
target_release: ""
|
||||||
|
verified_at: ""
|
||||||
|
status_note: "订正 04_8714 §5.5 中「alloc-preview 试算回执的 splits.teamNo 本期恒 null 未填充」的标注:#8787 已给拆账试算接口出参补 teamNo 填充,与 tab splits / panel households / sub-orders 三处同源同口径;试算仍不落库。已合 dev-v3 未部署测试服。"
|
||||||
|
updated_at: "2026-10-04"
|
||||||
|
base: "dev-v3"
|
||||||
|
---
|
||||||
|
|
||||||
|
# order-v3 groupbatch:alloc-preview 拆账试算回执 splits.teamNo 订正为已填充(管理后台)—— 订正 04_8714
|
||||||
|
|
||||||
|
> ⚠️ **本文是订正 changelog**,修订《04_8714_团期核单重做8类tab明细+公摊拆账-修改接口-管理后台.md》§5.5 与 §12.6 中「alloc-preview 试算回执的 splits[].teamNo 本期恒 null」的描述。原文件保留不改动;两处描述不一致时**以本文为准**。接口路径、入参结构、出参字段清单均无变化,唯一变化是**试算回执 splits[].teamNo 从恒 null 变为已填充真实团号**。
|
||||||
|
|
||||||
|
## 1. 接口背景
|
||||||
|
|
||||||
|
04_8714 团期核单重做落地时,拆账试算接口 `POST …/settlement/alloc-preview` 的出参 `lines[].splits[].teamNo` 未填充(试算不查团号,恒 null),changelog 据此标注「本期恒 null,不要用它做展示」。
|
||||||
|
|
||||||
|
#8786(PR #8787)补上该缺口:试算回执现在与正式读端点一样填充真实团号,前端试算预览可直接展示 teamNo,与暂存回执、tab 读端点体验一致,无需再对试算场景做 teamNo 空值特判。
|
||||||
|
|
||||||
|
## 2. 变更清单
|
||||||
|
|
||||||
|
| # | 接口 | 变更点 | 类型 |
|
||||||
|
|---|------|--------|------|
|
||||||
|
| 1 | `POST /v3/admin/order/group-batch/{groupBatchId}/settlement/alloc-preview` | 出参 `lines[].splits[].teamNo` 由**恒 null** 改为**填充真实团号**(order_main.team_no,订金支付成功后生成;未付订金的订单仍为 null)。与 tab splits / panel households / sub-orders 三处**同源同口径** | ✨ 出参字段值变化 |
|
||||||
|
|
||||||
|
路径前缀统一为 `/v3/admin/order/group-batch/{groupBatchId}/settlement`,下文用 `…` 代指。接口签名(路径 / 入参字段 / 出参字段清单)零变化,仅一个字段的值从 null 变为有值。
|
||||||
|
|
||||||
|
## 3. 接口详情
|
||||||
|
|
||||||
|
| 项 | 说明 |
|
||||||
|
|---|---|
|
||||||
|
| 服务 | hl-order-service-v3(端口 8086) |
|
||||||
|
| 路径 | `POST /v3/admin/order/group-batch/{groupBatchId}/settlement/alloc-preview` |
|
||||||
|
| 使用场景 | 管理后台 → 团期详情 → 核单 Tab:录入期拆账试算预览(不落库,前端编辑时实时预览分摊结果) |
|
||||||
|
| 认证 | 管理后台登录态(JWT);网关既有路由 `/v3/admin/**`,无新增网关配置 |
|
||||||
|
| 权限码 | `group-batch:audit:view`;缺码一律 589507 |
|
||||||
|
| 幂等性 | 纯查询型试算,**不写库**,天然幂等;无 expectedVersion |
|
||||||
|
| 限流 | 无特殊限流 |
|
||||||
|
|
||||||
|
## 4. 接口入参
|
||||||
|
|
||||||
|
入参不变(GroupSettleAllocPreviewReqVO):
|
||||||
|
|
||||||
|
| 字段 | 类型 | 必填 | 说明 |
|
||||||
|
|------|------|------|------|
|
||||||
|
| category | string | ✅ | 费用类别 8 值之一(HOTEL / TICKET / MEAL / VEHICLE / GUIDE / PHOTOGRAPHER / OTHER_INCOME / OTHER_EXPENSE) |
|
||||||
|
| lines | array | ✅ | 待试算明细行数组(≤500 行,结构同 04_8714 §4.2 `lines[]`);**无 expectedVersion**(纯试算不写库) |
|
||||||
|
|
||||||
|
路径参数 `groupBatchId`(Path,Long)必填,团期 ID。
|
||||||
|
|
||||||
|
## 5. 出参字段
|
||||||
|
|
||||||
|
出参结构(GroupSettleAllocPreviewRespVO)不变:
|
||||||
|
|
||||||
|
| 字段 | 类型 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| lines | array | 试算后的明细行(结构同 04_8714 §5.2 LineVO;confirmStatus 恒 UNCONFIRMED、lineId 原样回显或 null、sourceType 恒 MANUAL;splits 为重算预览)。**无任何写库** |
|
||||||
|
|
||||||
|
`lines[].splits[]`(SplitVO)中本次变化的字段:
|
||||||
|
|
||||||
|
| 字段 | 类型 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| orderId | string | 子订单 ID(不变) |
|
||||||
|
| **teamNo** | string 或 null | **团号**(order_main.team_no,订金支付成功后生成;未付订金的订单为 null)。⚠️ **本次订正点**:由原来恒 null 改为**已填充真实团号**,与 tab splits / panel households / sub-orders 三处**同源同口径**(服务端同一处批量取数:OrderService.selectTeamNoMapByIds,防 N+1) |
|
||||||
|
| householdName | string | 户名(客户姓名快照,不变) |
|
||||||
|
| ratio | string | 拆账比例(6 位小数,不变) |
|
||||||
|
| peopleCount | int 或 null | 该户参与人数快照(不变) |
|
||||||
|
| amount | string | 拆账金额(不变) |
|
||||||
|
| roundingBearer | boolean | 尾差承担户标记(不变) |
|
||||||
|
| note | string 或 null | 备注(不变) |
|
||||||
|
|
||||||
|
## 6. 枚举 / 数据字典
|
||||||
|
|
||||||
|
本次无枚举 / 字典变化。
|
||||||
|
|
||||||
|
## 7. 错误码
|
||||||
|
|
||||||
|
本次无错误码变化。alloc-preview 相关错误码与 04_8714 §7 一致:589507(无权限)/ 589572(所选订单不属本团)/ 589750(拆账合计与行总额不一致)/ 589751(指定报名须至少选一户)/ 589753(入参非法,含负金额,见 04_8783 订正)。
|
||||||
|
|
||||||
|
## 8. 示例
|
||||||
|
|
||||||
|
### 8.1 典型:已付订金订单,试算回执 splits.teamNo 有值
|
||||||
|
|
||||||
|
请求:
|
||||||
|
|
||||||
|
POST /v3/admin/order/group-batch/1934567890123456789/settlement/alloc-preview
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"category": "HOTEL",
|
||||||
|
"lines": [
|
||||||
|
{
|
||||||
|
"lineId": null,
|
||||||
|
"allocMode": "SHARED",
|
||||||
|
"allocRule": "PER_HEAD_AVG",
|
||||||
|
"actualAmount": 4600.00,
|
||||||
|
"hotelName": "图嘎营地",
|
||||||
|
"roomTypeName": "蒙古包",
|
||||||
|
"roomCount": 5,
|
||||||
|
"unitPrice": 380.00
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
响应 200(张三、李四家均已付订金,teamNo 有值):
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 0,
|
||||||
|
"data": {
|
||||||
|
"lines": [
|
||||||
|
{
|
||||||
|
"lineId": null,
|
||||||
|
"confirmStatus": "UNCONFIRMED",
|
||||||
|
"allocMode": "SHARED",
|
||||||
|
"allocRule": "PER_HEAD_AVG",
|
||||||
|
"actualAmount": "4600.00",
|
||||||
|
"sourceType": "MANUAL",
|
||||||
|
"hotelName": "图嘎营地",
|
||||||
|
"roomTypeName": "蒙古包",
|
||||||
|
"roomCount": 5,
|
||||||
|
"unitPrice": "380.00",
|
||||||
|
"splits": [
|
||||||
|
{ "orderId": "1934567890123450001", "teamNo": "26-0001", "householdName": "张三",
|
||||||
|
"ratio": "0.300000", "peopleCount": 3, "amount": "1380.00", "roundingBearer": true, "note": null },
|
||||||
|
{ "orderId": "1934567890123450002", "teamNo": "26-0002", "householdName": "李四",
|
||||||
|
"ratio": "0.700000", "peopleCount": 7, "amount": "3220.00", "roundingBearer": false, "note": null }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**订正前**:同样请求 splits 里两处 teamNo 均为 `null`;**订正后**:填充真实团号,与 `GET …/settlement/hotels` 读端点返回的 splits.teamNo 完全一致。
|
||||||
|
|
||||||
|
### 8.2 边界:未付订金订单,splits.teamNo 仍为 null
|
||||||
|
|
||||||
|
请求同上(团内王五家订单 1934567890123450003 未付订金):
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"category": "HOTEL",
|
||||||
|
"lines": [
|
||||||
|
{
|
||||||
|
"lineId": null,
|
||||||
|
"allocMode": "SHARED",
|
||||||
|
"allocRule": "PER_HEAD_AVG",
|
||||||
|
"actualAmount": 1500.00,
|
||||||
|
"hotelName": "图嘎营地"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
响应 200:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 0,
|
||||||
|
"data": {
|
||||||
|
"lines": [
|
||||||
|
{
|
||||||
|
"lineId": null,
|
||||||
|
"confirmStatus": "UNCONFIRMED",
|
||||||
|
"allocMode": "SHARED",
|
||||||
|
"allocRule": "PER_HEAD_AVG",
|
||||||
|
"actualAmount": "1500.00",
|
||||||
|
"sourceType": "MANUAL",
|
||||||
|
"hotelName": "图嘎营地",
|
||||||
|
"splits": [
|
||||||
|
{ "orderId": "1934567890123450001", "teamNo": "26-0001", "householdName": "张三",
|
||||||
|
"ratio": "0.300000", "peopleCount": 3, "amount": "450.00", "roundingBearer": true, "note": null },
|
||||||
|
{ "orderId": "1934567890123450003", "teamNo": null, "householdName": "王五",
|
||||||
|
"ratio": "0.700000", "peopleCount": 7, "amount": "1050.00", "roundingBearer": false, "note": null }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
读法:**teamNo 可空语义不变**——团号在订金支付成功后才生成,未付订金的订单(王五家)teamNo 仍为 null,前端列表渲染的空值兜底**必须保留**。订正只影响「有团号但试算不回填」的场景,不影响「本来就没团号」的场景。
|
||||||
|
|
||||||
|
### 8.3 业务失败:拆账合计与行总额不一致(589750,既有行为不变,供对照)
|
||||||
|
|
||||||
|
请求:
|
||||||
|
|
||||||
|
POST /v3/admin/order/group-batch/1934567890123456789/settlement/alloc-preview
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"category": "HOTEL",
|
||||||
|
"lines": [
|
||||||
|
{
|
||||||
|
"lineId": null,
|
||||||
|
"allocMode": "DESIGNATED",
|
||||||
|
"actualAmount": 3800.00,
|
||||||
|
"hotelName": "图嘎营地",
|
||||||
|
"splits": [ { "orderId": "1934567890123450001", "amount": 3000.00 } ]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
响应:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 589750,
|
||||||
|
"message": "拆账合计与明细行总额不一致(图嘎营地拆账合计 3000.00 / 明细总额 3800.00,差额 800.00),请核对后再提交"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
试算与正式提交同一套拆账校验,错误码行为不变。
|
||||||
|
|
||||||
|
## 9. 业务边界
|
||||||
|
|
||||||
|
**适用**:
|
||||||
|
- 核单录入期的拆账试算预览(公摊 / 指定报名两种口径),试算回执可直接渲染含 teamNo 的拆账明细列表,与暂存回执、tab 读端点同一渲染组件。
|
||||||
|
|
||||||
|
**不适用**:
|
||||||
|
- 试算不落库——alloc-preview 的结果仅供前端预览,刷新页面 / 重新 GET tab 后不会保留;要持久化仍走 `PUT …/settlement/{tab}` 整 tab 暂存。
|
||||||
|
|
||||||
|
**特殊边界**:
|
||||||
|
- **teamNo 可空不变**:未付订金订单恒无团号,teamNo=null 是正常业务状态,不是数据缺失;前端空值兜底逻辑必须保留。
|
||||||
|
- **同源同口径**:试算回执的 teamNo 与 tab splits / panel households / sub-orders 三处取自同一服务端批量查询(selectTeamNoMapByIds),任何场景下同一订单的 teamNo 展示一致,不会出现「试算有值、正式读出 null」或反之的口径分裂。
|
||||||
|
|
||||||
|
## 10. 修改前后对比
|
||||||
|
|
||||||
|
### 字段级对比
|
||||||
|
|
||||||
|
| 项 | 原来(04_8714 描述 / #8787 前实现) | 现在(#8787 订正后) |
|
||||||
|
|----|--------------------------------------|----------------------|
|
||||||
|
| alloc-preview 回执 `lines[].splits[].teamNo` | **恒 null**(试算不查团号) | **填充真实团号**(order_main.team_no);未付订金订单仍为 null |
|
||||||
|
|
||||||
|
### 行为级对比
|
||||||
|
|
||||||
|
| 行为 | 原来 | 现在 |
|
||||||
|
|------|------|------|
|
||||||
|
| 试算预览渲染团号列 | 前端只能显示空 / 占位,或需自行调 sub-orders 接口补 teamNo | 直接用回执里的 teamNo 渲染,与正式读端点一致 |
|
||||||
|
| 试算落库 | 不落库(不变) | 不落库(不变) |
|
||||||
|
| 其余出参字段 | 不变 | 不变 |
|
||||||
|
|
||||||
|
## 11. 影响评估 / 回滚
|
||||||
|
|
||||||
|
- **破坏兼容**:否。字段从 null 变有值,属纯增量信息;前端若按 04_8714 的建议「不要用试算回执 teamNo 做展示」而未消费该字段,则**零改动**。
|
||||||
|
- **前端必须同步上线**:否(后端已合 dev-v3 未部署测试服)。
|
||||||
|
- **workaround 清理点**:若前端此前为在试算预览里展示团号而自行调 `GET …/settlement/sub-orders` 或 panel 接口补 teamNo 的变通逻辑,现在可以删掉——试算回执自带 teamNo,直接渲染即可。
|
||||||
|
- **回滚方案**:后端回滚 = revert PR #8787 即可(纯代码改动,无 DDL / 无数据迁移)。
|
||||||
|
|
||||||
|
## 12. 注意事项
|
||||||
|
|
||||||
|
1. **本文优先于 04_8714**:两份 changelog 对 alloc-preview 回执 splits[].teamNo 的描述不一致时,以本文为准(04_8714 §5.5「本期恒 null」与 §12.6「不要用它做展示」两条作废)。04_8714 的其余内容(接口清单 / 出入参结构 / 枚举字典 / 拆账规则)继续有效。
|
||||||
|
2. **teamNo 空值兜底保留**:未付订金订单 teamNo 仍为 null,列表渲染的空值处理不能因为本次填充而删除。
|
||||||
|
3. **三处同源**:tab splits / panel households / sub-orders / alloc-preview 四处的 teamNo 现在完全同源同口径,前端不需要对试算场景做任何特判。
|
||||||
|
4. **试算仍不落库**:alloc-preview 是纯预览,任何试算结果都不会写入核单数据;持久化走 PUT 整 tab 暂存。
|
||||||
|
|
||||||
|
## 13. 关联 / 联系人
|
||||||
|
|
||||||
|
- Issue:https://git.1814.love/wx/HL/issues/8786
|
||||||
|
- PR:https://git.1814.love/wx/HL/pulls/8787
|
||||||
|
- Commit(squash merge):https://git.1814.love/wx/HL/commit/d20e6432128f
|
||||||
|
- 被订正的原 changelog:`changelogs-v2/2026-10/04_8714_团期核单重做8类tab明细+公摊拆账-修改接口-管理后台.md`(同仓同目录)
|
||||||
|
- 后端负责人:@yst
|
||||||
在新工单中引用
屏蔽一个用户