From aa11cd2610e556b16134141d9f7e454446f232b6 Mon Sep 17 00:00:00 2001 From: yaosutu <770858045@qq.com> Date: Sat, 10 Oct 2026 12:44:09 +0800 Subject: [PATCH] =?UTF-8?q?docs(changelog):=20=E5=9B=A2=E6=9C=9F=E6=A0=B8?= =?UTF-8?q?=E5=8D=95=E6=98=8E=E7=BB=86=E5=B8=A6=E5=87=BA/=E6=9A=82?= =?UTF-8?q?=E5=AD=98=E5=90=88=E5=B9=B6=20+=20bizKey=20=E6=BA=AF=E6=BA=90?= =?UTF-8?q?=EF=BC=88#8813=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - GET/PUT/POST settlement 三端点行为变化:已暂存 tab 持续带出未暂存预览行 - 行出参加 bizKey,暂存入参可透传 sourceType/bizKey - PUT 响应新增 warnMessage/missedCarryOverCount,新错误码 589756/589757 - 前端必须同步上线(否则双显双计) --- ...8813_团期核单带出合并-修改接口-管理后台.md | 305 ++++++++++++++++++ 1 file changed, 305 insertions(+) create mode 100644 changelogs-v2/2026-10/10_8813_团期核单带出合并-修改接口-管理后台.md diff --git a/changelogs-v2/2026-10/10_8813_团期核单带出合并-修改接口-管理后台.md b/changelogs-v2/2026-10/10_8813_团期核单带出合并-修改接口-管理后台.md new file mode 100644 index 00000000..36993cac --- /dev/null +++ b/changelogs-v2/2026-10/10_8813_团期核单带出合并-修改接口-管理后台.md @@ -0,0 +1,305 @@ +--- +schema: "hl-changelog/v2" +ticket: "8813" +title: "团期核单明细带出/暂存合并:已暂存 tab 也持续带出未暂存预览行,新增 bizKey 溯源" +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: "后端 PR #8817 已合并 dev-v3(squash 4734715671),含 Flyway 迁移 V20261009_747(8 张 order_group_settlement_* 明细表加 biz_key 列),需部署 order-v3 后生效;前端必须同步改造:进入 tab 整份编辑 lines 数组(含 lineId=null 待带出行),暂存时原样透传 sourceType/bizKey,否则已暂存 tab 会出现旧暂存行与重新带出行双显双计" +updated_at: "2026-10-10" +base: "dev-v3" +--- + +# 团期核单明细带出/暂存合并 + bizKey 溯源(管理后台) + +> ⚠️ **修改接口(前端必须同步上线)**:团期核单 8 类 tab 的「带出」语义从「暂存过的 tab 不再带出」改为「**始终合并返回**」——已暂存行照原样显示、未暂存的带出预览行继续带入(lineId=null)。前端交互改为「整份 lines 编辑 + 暂存时透传 sourceType/bizKey」。**新旧前端混跑会出现双显双计**,务必同步上线。 + +## 1. 接口背景 + +团期核单 8 类费用 tab(住宿/门票/餐食/车辆/导游/摄影师/其他支出/其他收入)里,大量明细行是系统从订单、资源准备、批次成本里**自动带出**的预览行(如各订单的房费、门票费、团车公摊),运营只需确认或微调后暂存。 + +旧行为的问题:一旦某个 tab 暂存过,系统就**不再带出**该 tab 的后续预览行——后续新报名的订单费用、新产生的批次成本就「消失」了,运营完全感知不到漏了钱。 + +本次(#8813)改为: + +- **带出与暂存合并**:无论何时进入 tab,已暂存的行照常显示;**尚未被暂存覆盖的带出预览行继续带入**(lineId=null、带 sourceType/bizKey 标识),运营一眼看到「还有 N 条带出成本没纳入」。 +- **bizKey 溯源**:每条行新增 bizKey(来源业务键),暂存时原样回传,后端据此判断「这条暂存行对应哪条带出成本」,已暂存的预览行不再重复带出,防止重复计入。 +- **漏带提醒**:暂存时如果漏掉了某些带出行,响应里给 warnMessage / missedCarryOverCount 做 WARN 提示(不阻断)。 + +## 2. 变更清单 + +| # | 接口 | 方法 | 路径 | 变更类型 | 说明 | +|---|------|------|------|----------|------| +| 1 | 分类 tab 明细查询 | GET | /v3/admin/order/group-batch/{groupBatchId}/settlement/{category} | ⚠️ 行为变化 | **暂存过的 tab 也持续带出未暂存预览行**;行出参加 bizKey;sourceType 正确区分 CARRY_OVER/BATCH_COST/MANUAL | +| 2 | 整 tab 暂存 | PUT | /v3/admin/order/group-batch/{groupBatchId}/settlement/{category} | ⚠️ 行为变化 | 入参行可透传 sourceType/bizKey;响应新增 warnMessage/missedCarryOverCount;新增硬拦错误码 589756/589757 | +| 3 | 新增单行 | POST | /v3/admin/order/group-batch/{groupBatchId}/settlement/{category}/lines | 修改 | 入参同样可透传 sourceType/bizKey(接受待带出行时使用),同 589756 校验 | + +category 8 值:hotels / activities / meals / vehicles / guide-fees / photographer-fees / other-expenses / other-incomes。 + +DDL:8 张 order_group_settlement_* 明细表加 biz_key 列(迁移 V20261009_747),Flyway 部署时自动执行,**前端无需任何动作**。 + +## 3. 接口详情 + +| 项 | 说明 | +|---|---| +| 服务 | hl-order-service-v3(端口 8086) | +| 使用场景 | 管理后台 → 团期详情 → 核单 Tab:8 类费用明细查看/编辑/暂存 | +| 认证 | 管理后台登录态(JWT);网关既有路由 /v3/admin/**,无新增网关配置 | +| 权限码 | 沿用核单既有权限:group-batch:audit:view(GET)、group-batch:audit:edit(PUT / lines 新增) | +| 幂等性 | PUT 整 tab 暂存仍走 main 主行锁 + expectedVersion CAS(过期仍吃 589573);新增单行天然幂等(无去重键) | +| 限流 | 无特殊限流 | + +## 4. 接口入参 + +### 4.1 路径参数(三个端点共有) + +| 参数 | 位置 | 类型 | 必填 | 说明 | +|------|------|------|------|------| +| groupBatchId | Path | Long | 是 | 团期 ID | +| category | Path | String | 是 | 费用类别 8 值之一(见 §6) | + +### 4.2 PUT 整 tab 暂存请求体(GroupSettleTabSaveReqVO,仅列变化点) + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| expectedVersion | Number(int) | 是 | 乐观锁版本号,取 GET 响应里的 version;过期返 589573 | +| lines | Array | 是 | **整份明细行数组(全量替换语义)**,行结构见 4.3 | + +### 4.3 行结构 GroupSettleLineSaveReqVO(PUT 与 POST lines 共用) + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| lineId | String(Long) | 否 | 已暂存行带原 lineId;**带出预览行(GET 里 lineId=null 的行)暂存时不传**,由后端建档 | +| itemName / spec / quantity / unitPrice / totalAmount / remark 等业务字段 | — | 按原契约 | 无变化,沿用 #8714 契约 | +| **sourceType** | String | 否 | **新增可透传**:带出预览行暂存时**原样回传** GET 给的值(CARRY_OVER/BATCH_COST);手加行**不传**(后端默认 MANUAL) | +| **bizKey** | String | 否 | **新增可透传**:带出预览行暂存时**原样回传** GET 给的 bizKey;手加行不传 | + +> **铁律**:sourceType/bizKey 前端**不解析、不构造、不修改**,只做「GET 拿到什么 → PUT 原样回传什么」的透传。 + +## 5. 出参字段 + +### 5.1 GET 分类 tab 明细(GroupSettleTabRespVO,仅列变化点) + +| 字段 | 类型 | 说明 | +|------|------|------| +| status / version / editable / summary 等 | — | 无变化;editable 仍 = status==DRAFT | +| lines[] | Array | **行为变化**:现在 = 已暂存行 ∪ 未暂存带出预览行(合并返回,不再互斥) | +| lines[].lineId | String(Long) 或 null | 已暂存行=实际行 ID;**带出预览行=null**(前端据此区分并可渲染「待带出」样式) | +| lines[].sourceType | String | **现在会正确区分**:CARRY_OVER(订单带出)/ BATCH_COST(批次成本带出)/ MANUAL(手加) | +| **lines[].bizKey** | **String 或 null** | **新增**:来源业务键。带出行有值,手加行=null。**前端不解析**,仅透传 | + +金额与 ID 字段一律以 **JSON 字符串**返回(防 JS 精度丢失)。 + +bizKey 格式参考(仅供理解,**不需要解析**): + +- 单价型:`D1|驯鹿拉车体验|成人票|59`(slot|名称|规格|单价) +- 总额型:`TOTAL:VEHICLE:SHARED:BUS` / `TOTAL:{类别}:L{序号}` + +### 5.2 PUT 暂存响应(GroupSettleTabWriteRespVO,仅列变化点) + +| 字段 | 类型 | 说明 | +|------|------|------| +| version / lineIds 等既有字段 | — | 无变化 | +| **warnMessage** | **String 或 null** | **新增**:暂存漏了某些带出行时的提示文案,如「有 2 条带出成本未纳入本次暂存」;无遗漏时为 null | +| **missedCarryOverCount** | **Number(int)** | **新增**:漏带的带出行条数;0 = 无遗漏 | + +> WARN 只是提醒,**暂存本身成功**(HTTP 200)。前端建议 toast 展示 warnMessage,不打断流程。 + +## 6. 枚举 / 数据字典 + +### 6.1 category(路径段,8 值) + +hotels(住宿)/ activities(门票·游玩)/ meals(餐食)/ vehicles(车辆)/ guide-fees(导游)/ photographer-fees(摄影师)/ other-expenses(其他支出)/ other-incomes(其他收入)。中文名走数据字典 settlement_category。 + +### 6.2 sourceType(行来源,3 值) + +| 值 | 含义 | 出现场景 | +|---|---|---| +| CARRY_OVER | 订单带出(从各子订单费用明细带出) | 带出预览行 / 由带出行暂存落库的行 | +| BATCH_COST | 批次成本带出(团级公摊成本,如团车) | 同上 | +| MANUAL | 手加行 | 前端手工新增的行(默认,不传即 MANUAL) | + +## 7. 错误码 + +| 错误码 | 触发场景 | 前端处理 | +|---|---|---| +| **589756** | **明细行来源标识与本团带出成本不匹配**:提交的 sourceType/bizKey 不在本 tab 当前带出预览集内(如过期预览行、伪造 bizKey) | 硬拦。提示用户刷新 tab 重新加载最新带出集后再暂存 | +| **589757** | **存在重复的来源成本行**:同一次提交里出现两条相同 bizKey 的行 | 硬拦。前端去重逻辑自查(正常整份编辑不会触发) | +| 589573 | expectedVersion 过期(并发暂存冲突) | 沿用原处理:刷新重载 | + +## 8. 示例 + +### 8.1 典型:tab 已暂存过,新带出预览行继续带入 + +GET /v3/admin/order/group-batch/1024/settlement/hotels + +```json +{ + "code": 0, + "data": { + "status": "DRAFT", + "editable": true, + "version": 3, + "lines": [ + { + "lineId": "88001", + "sourceType": "CARRY_OVER", + "bizKey": "D1|驯鹿拉车体验|成人票|59", + "itemName": "驯鹿拉车体验-成人票", + "quantity": "10", + "unitPrice": "59.00", + "totalAmount": "590.00" + }, + { + "lineId": "88002", + "sourceType": "MANUAL", + "bizKey": null, + "itemName": "临时加床费", + "quantity": "1", + "unitPrice": "200.00", + "totalAmount": "200.00" + }, + { + "lineId": null, + "sourceType": "CARRY_OVER", + "bizKey": "D2|星空蒙古包|标间|480", + "itemName": "星空蒙古包-标间", + "quantity": "5", + "unitPrice": "480.00", + "totalAmount": "2400.00" + } + ] + } +} +``` + +> 第 1 条是已暂存的带出行(有 lineId + bizKey);第 2 条是手加行(bizKey=null);第 3 条是**新带出的预览行**(lineId=null),等待运营确认。 + +### 8.2 边界:暂存整份提交,带出行透传 sourceType/bizKey,漏带 1 条给 WARN + +PUT /v3/admin/order/group-batch/1024/settlement/hotels + +```json +{ + "expectedVersion": 3, + "lines": [ + { + "lineId": "88001", + "sourceType": "CARRY_OVER", + "bizKey": "D1|驯鹿拉车体验|成人票|59", + "itemName": "驯鹿拉车体验-成人票", + "quantity": "10", + "unitPrice": "59.00", + "totalAmount": "590.00" + }, + { + "lineId": "88002", + "itemName": "临时加床费", + "quantity": "1", + "unitPrice": "200.00", + "totalAmount": "200.00" + } + ] +} +``` + +响应(漏了 8.1 里那条 lineId=null 的带出行,**暂存仍成功**): + +```json +{ + "code": 0, + "data": { + "version": 4, + "warnMessage": "有 1 条带出成本未纳入本次暂存", + "missedCarryOverCount": 1 + } +} +``` + +> 手加行(第 2 条)不传 sourceType/bizKey;带出行(第 1 条)原样透传。下次再 GET,那条漏掉的预览行仍会带出(lineId=null),不会丢。 + +### 8.3 业务失败:bizKey 不在带出集触发 589756 + +暂存时提交了一条 bizKey=D9|不存在的项目|票|1(不在本 tab 当前带出预览集): + +```json +{ + "code": 589756, + "msg": "明细行来源标识与本团带出成本不匹配" +} +``` + +## 9. 业务边界 + +**适用**: + +- 核单 DRAFT 状态下的 8 类 tab 查看/编辑/暂存/单行新增。 +- 「暂存过但仍想看到新带出成本」的场景——本次核心。 + +**不适用**: + +- 核单 CONFIRMED 后:editable=false,带出行不再带入(tab 已锁定),写口全部被既有门禁拦截。 +- 前端自行拼装 bizKey:bizKey 由后端生成,前端伪造会吃 589756。 + +**特殊边界**: + +- 带出预览行**不落库**,只有暂存后才成为正式行;所以 GET 里 lineId=null 的行在「刷新页面」后可能因业务数据变化而增减,属正常。 +- 同 tab 多次暂存:已暂存的带出行(bizKey 已落库)不会重复带出。 + +## 10. 修改前后对比 + +### 行为级 + +| 场景 | 修改前 | 修改后 | +|---|---|---| +| tab 已暂存过,再次进入 | **不再带出任何预览行**,新产生的订单费用/批次成本不可见 | **已暂存行 + 未暂存带出预览行合并返回**,新成本持续可见 | +| 带出预览行标识 | sourceType 区分不可靠 | sourceType 正确区分 CARRY_OVER/BATCH_COST/MANUAL,且带 **bizKey** 溯源键 | +| 暂存漏掉带出行 | 静默漏掉,运营无感知 | 响应给 warnMessage + missedCarryOverCount(WARN 不阻断) | +| 伪造/过期 bizKey | 无校验 | 589756 硬拦 | +| 同次提交 bizKey 重复 | 无校验 | 589757 硬拦 | + +### 字段级 + +| 字段 | 修改前 | 修改后 | +|---|---|---| +| GET 出参 lines[].bizKey | 无 | **新增**(String,带出行有值,手加行 null) | +| PUT/POST 入参 lines[].sourceType / bizKey | 不接收 | **新增可透传**(带出预览行暂存时原样回传) | +| PUT 响应 warnMessage / missedCarryOverCount | 无 | **新增** | + +## 11. 影响评估 / 回滚 + +**兼容性**:⚠️ **前端必须同步上线,属破坏性行为变化**。 + +- 新后端 + 旧前端:已暂存 tab 会同时出现「旧暂存行(bizKey=null)+ 重新带出的同类预览行」,**双显双计**,金额虚高。 +- 新前端 + 旧后端:bizKey 无处可取,退化为旧行为(可接受但不解决问题)。 + +**前端改造要点**: + +1. 进入 tab 拿到的**完整 lines 数组(含 lineId=null 待带出行)整份编辑**,不再区分「带出区/暂存区」两个数据源。 +2. 暂存时把带出预览行的 sourceType/bizKey **原样透传**回去,整份提交。 +3. 渲染上可用 lineId==null 标「待带出」样式;用 missedCarryOverCount>0 toast warnMessage。 +4. 收到 589756 提示刷新重载(多半是预览集已变)。 + +**回滚方案**:后端回滚本 PR 即恢复旧行为(biz_key 列保留无害);前端若已上线透传逻辑,旧后端会忽略多余字段,不报错。建议前后端同窗口发布。 + +## 12. 注意事项 + +- bizKey 前端**不解析、不构造、不修改**,纯透传。格式见 §5.1 仅作理解参考。 +- 金额/ID 一律字符串处理。 +- editable 判定未变:仍 = status==DRAFT。 +- 部署依赖:Flyway 迁移 V20261009_747 随 order-v3 部署自动执行,**联调前先确认测试服已部署本 PR 之后的构建**。 + +## 13. 关联 / 联系人 + +- Issue: https://git.1814.love/wx/HL/issues/8813 +- PR: https://git.1814.love/wx/HL/pulls/8817 +- Commit: https://git.1814.love/wx/HL/commit/4734715671 +- 后端负责人:yst(腰苏图) +- 前置契约:#8714 团期核单重做 8 类 tab(本仓 changelogs-v2/2026-10/04_8714_团期核单重做8类tab明细+公摊拆账-修改接口-管理后台.md)