12 KiB
schema, ticket, title, consumer, author, change_type, backend_status, gateway_status, frontend_status, frontend_owner, frontend_ref, target_release, verified_at, status_note, updated_at, base
| schema | ticket | title | consumer | author | change_type | backend_status | gateway_status | frontend_status | frontend_owner | frontend_ref | target_release | verified_at | status_note | updated_at | base |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| hl-changelog/v2 | 8786 | 团期核单 alloc-preview 试算回执 splits.teamNo 由恒 null 订正为已填充真实团号 | admin | yst | 修改接口 | merged | not_required | not_required | 订正 04_8714 §5.5 中「alloc-preview 试算回执的 splits.teamNo 本期恒 null 未填充」的标注:#8787 已给拆账试算接口出参补 teamNo 填充,与 tab splits / panel households / sub-orders 三处同源同口径;试算仍不落库。已合 dev-v3 未部署测试服。 | 2026-10-04 | 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
{
"category": "HOTEL",
"lines": [
{
"lineId": null,
"allocMode": "SHARED",
"allocRule": "PER_HEAD_AVG",
"actualAmount": 4600.00,
"hotelName": "图嘎营地",
"roomTypeName": "蒙古包",
"roomCount": 5,
"unitPrice": 380.00
}
]
}
响应 200(张三、李四家均已付订金,teamNo 有值):
{
"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 未付订金):
{
"category": "HOTEL",
"lines": [
{
"lineId": null,
"allocMode": "SHARED",
"allocRule": "PER_HEAD_AVG",
"actualAmount": 1500.00,
"hotelName": "图嘎营地"
}
]
}
响应 200:
{
"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
{
"category": "HOTEL",
"lines": [
{
"lineId": null,
"allocMode": "DESIGNATED",
"actualAmount": 3800.00,
"hotelName": "图嘎营地",
"splits": [ { "orderId": "1934567890123450001", "amount": 3000.00 } ]
}
]
}
响应:
{
"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. 注意事项
- 本文优先于 04_8714:两份 changelog 对 alloc-preview 回执 splits[].teamNo 的描述不一致时,以本文为准(04_8714 §5.5「本期恒 null」与 §12.6「不要用它做展示」两条作废)。04_8714 的其余内容(接口清单 / 出入参结构 / 枚举字典 / 拆账规则)继续有效。
- teamNo 空值兜底保留:未付订金订单 teamNo 仍为 null,列表渲染的空值处理不能因为本次填充而删除。
- 三处同源:tab splits / panel households / sub-orders / alloc-preview 四处的 teamNo 现在完全同源同口径,前端不需要对试算场景做任何特判。
- 试算仍不落库:alloc-preview 是纯预览,任何试算结果都不会写入核单数据;持久化走 PUT 整 tab 暂存。
13. 关联 / 联系人
- Issue:wx/HL#8786
- PR:wx/HL#8787
- Commit(squash merge):https://git.1814.love/wx/HL/commit/d20e6432128f
- 被订正的原 changelog:
changelogs-v2/2026-10/04_8714_团期核单重做8类tab明细+公摊拆账-修改接口-管理后台.md(同仓同目录) - 后端负责人:@yst