From 0686db9ad5100ed7bb125edbad04e53c50011df6 Mon Sep 17 00:00:00 2001 From: jw Date: Sun, 13 Sep 2026 19:04:55 +0800 Subject: [PATCH] =?UTF-8?q?changelog(#7528):=20=E5=9B=A2=E6=9C=9F=E8=BF=9B?= =?UTF-8?q?=E5=85=A5=E5=BE=85=E5=87=BA=E5=8F=91=E4=B8=83=E9=A1=B9=E7=A1=AC?= =?UTF-8?q?=E9=97=A8=20+=20=E8=AF=A6=E6=83=85=20departureGates=20=E5=B1=95?= =?UTF-8?q?=E7=A4=BA=20+=20recheck=20=E7=AB=AF=E7=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...出发七项硬门与详情硬门展示-修改接口-管理后台.md | 291 ++++++++++++++++++ 1 file changed, 291 insertions(+) create mode 100644 changelogs-v2/2026-09/13_7528_团期进入待出发七项硬门与详情硬门展示-修改接口-管理后台.md diff --git a/changelogs-v2/2026-09/13_7528_团期进入待出发七项硬门与详情硬门展示-修改接口-管理后台.md b/changelogs-v2/2026-09/13_7528_团期进入待出发七项硬门与详情硬门展示-修改接口-管理后台.md new file mode 100644 index 00000000..26719eeb --- /dev/null +++ b/changelogs-v2/2026-09/13_7528_团期进入待出发七项硬门与详情硬门展示-修改接口-管理后台.md @@ -0,0 +1,291 @@ +--- +schema: "hl-changelog/v2" +ticket: "7528" +title: "团期进入待出发+出发推进两跳共用七项硬门(系统自动闸)+ 团期详情展示七项硬门 + 手工复判端点" +consumer: "admin" +author: "jw(GIT)" +change_type: "修改接口" +backend_status: "deployed" +gateway_status: "not_required" +frontend_status: "pending" +frontend_owner: "mmg" +frontend_ref: "#7528" +target_release: "" +verified_at: "2026-09-13" +status_note: "团期详情响应新增 departureGates(纯加字段,老前端不读该 key 照常运行);但这是「发车受阻可见性」的主入口,需前端在详情页渲染七项硬门状态(定案16)。另:确认物资 confirm-material 之后不能再假设已跳转待出发,需重新拉详情。零 DDL、零错误码、零网关改动。" +updated_at: "2026-09-13" +base: "dev-v3" +--- + +# order-v3: 团期进入待出发七项硬门 + 详情硬门展示 + 手工复判端点 + +**服务**: hl-order-service-v3 +**PR**: #7628 +**Issue**: #7528 + +--- + +## ⚠️ 关键变化 + +🟡 **行为变化(需前端配合,但非破坏)**: + +1. **进入待出发从「零条件自动推进」改为「七项硬门系统自动闸」**。确认物资后不再无条件跳待出发;只有七项硬门全过才推进,任一未过则停在 `MATERIAL_PREPARING`(接口仍 200)。**前端点完确认物资后需重新拉详情看状态。** +2. **团期详情响应新增 `departureGates`**(七项硬门逐项状态,纯加字段)。发车受阻可见性主入口,需前端渲染。仅 `MATERIAL_PREPARING` / `PENDING_DEPARTURE` 返回,其余状态与求值失败均为 `null`。 +3. **新增手工复判端点** `recheck-departure-gate`:补齐缺失项后手工触发一次进入待出发复判(幂等)。 + +七项硬门:①已成团 ②房车导摄四项配齐 ③物资已确认 ④活跃子订单全部已确认 ⑤出行人证件齐全 ⑥合同保险全齐 ⑦主报账人已设。 + +## 一、背景 + +团期状态机后半段两跳(进入待出发、出发推进)此前进入待出发是「双门恰好满足即自动推进」、出发推进是「到日子零校验发车」。本单为两跳加同一套七项硬门系统自动闸(GB-ADM-006),两跳复用同一求值器,判据永远一致。受阻不阻断、不报错、不倒退——补齐后由既有触发点或定时扫描自动重试;受阻原因通过详情页 `departureGates` 与时间线 `BATCH_DEPARTURE_BLOCKED` 展示。**无人工勾选字段、无人工提交端点、校验结果不落库。** + +## 二、变更接口清单 + +| # | 接口 | 方法 | 路径 | 变更类型 | 说明 | +|---|------|------|------|----------|------| +| 1 | 团期详情 | GET | `/v3/admin/order/group-batch/:groupBatchId` | 修改 | 出参新增 `departureGates` 数组 | +| 2 | 确认物资 | POST | `/v3/admin/order/group-batch/:groupBatchId/confirm-material` | 修改 | 行为变化:按七项硬门决定是否推进,受阻停留并留痕 | +| 3 | 手工复判进入待出发硬门 | POST | `/v3/admin/order/group-batch/:groupBatchId/recheck-departure-gate` | 新增 | 补齐后手工触发一次复判 | + +## 三、接口详情 + +### 1. 团期详情 `GET /v3/admin/order/group-batch/:groupBatchId` + +**VO**: `GroupBatchDetailRespVO` + +#### 使用场景 + +团期详情页展示。除既有字段外,新增七项硬门逐项状态,供运营看清「这个团还差哪几项才能发车」。 + +#### 入参字段表 + +| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | +|---|---|---|---|---|---| +| groupBatchId | path | string(Long) | 是 | 雪花 ID | 团期主订单 ID | + +#### 出参字段表 + +(仅列新增字段,既有字段一字未改) + +| 字段 | 类型 | 说明 | +|---|---|---| +| departureGates | array\|null | 七项硬门逐项状态,**恒 7 项、顺序固定门①~门⑦**;仅 `MATERIAL_PREPARING`/`PENDING_DEPARTURE` 返回,其余状态或求值失败为 `null` | +| departureGates[].gateCode | string | 门码(FORMED/RESOURCE_READY/MATERIAL_CONFIRMED/SUB_ORDERS_CONFIRMED/TRAVELER_PROFILE/CONTRACT_INSURANCE/PRIMARY_REPORTER) | +| departureGates[].gateName | string | 门中文名,前端直接渲染,与时间线 content 同源 | +| departureGates[].passed | boolean | 是否通过 | +| departureGates[].failReason | string\|null | 未通过原因(通过时 null) | +| departureGates[].blockedOrderId | string\|null | 卡在哪一户(门⑤/⑥ 才有;**字符串形态**,防大整数精度丢失) | + +#### 请求示例 + +```http +GET /v3/admin/order/group-batch/2099073597908647938 +Authorization: Bearer +``` + +#### 响应示例 + +```json +{ + "code": 200, + "msg": "成功", + "data": { + "groupBatchId": "2099073597908647938", + "batchStatus": "MATERIAL_PREPARING", + "departureGates": [ + { "gateCode": "FORMED", "gateName": "已成团", "passed": true, "failReason": null, "blockedOrderId": null }, + { "gateCode": "RESOURCE_READY", "gateName": "房车导摄四项配齐", "passed": false, "failReason": "四项资源未配齐:房=未配置 车=已配置 导=已配置 摄=已配置", "blockedOrderId": null }, + { "gateCode": "MATERIAL_CONFIRMED", "gateName": "物资已确认", "passed": true, "failReason": null, "blockedOrderId": null }, + { "gateCode": "SUB_ORDERS_CONFIRMED", "gateName": "活跃子订单全部已确认", "passed": true, "failReason": null, "blockedOrderId": null }, + { "gateCode": "TRAVELER_PROFILE", "gateName": "出行人证件齐全", "passed": true, "failReason": null, "blockedOrderId": null }, + { "gateCode": "CONTRACT_INSURANCE", "gateName": "合同保险全齐", "passed": false, "failReason": "子订单 2099073597711515649 合同状态 GENERATED(需 SIGNED)", "blockedOrderId": "2099073597711515649" }, + { "gateCode": "PRIMARY_REPORTER", "gateName": "主报账人已设", "passed": true, "failReason": null, "blockedOrderId": null } + ] + } +} +``` + +#### 空数据 / 降级响应 + +- 团期状态不属 `MATERIAL_PREPARING`/`PENDING_DEPARTURE`(招募中、已出行、已结算等):`departureGates` 为 `null`,前端整块不渲染。 +- 求值取数失败(软依赖降级):`departureGates` 为 `null`,其余字段照常,后端记 WARN。 + +#### 错误响应 + +```json +{ "code": 589500, "msg": "团期不存在", "data": null } +``` + +(589507=无 group-batch:view 权限;求值器内部异常不转错误码,降级为 departureGates=null) + +#### 业务边界 + +- `departureGates` 是**纯展示**、无动作按钮;补齐缺失项由系统自动重试。 +- 门②的 `passed` = 既有 `hotelReady`/`vehicleReady`/`guideReady`/`photographerReady` 四布尔 AND;既有四字段与 `materialConfirmed` 原样保留、值不变。 +- `blockedOrderId` 是字符串形态(`ToStringSerializer`),前端勿转 number。 + +### 2. 确认物资 `POST /v3/admin/order/group-batch/:groupBatchId/confirm-material` + +**VO**: `Result` + +#### 使用场景 + +运营确认团期物资清单,确认后系统尝试按七项硬门推进到待出发。 + +#### 入参字段表 + +| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | +|---|---|---|---|---|---| +| groupBatchId | path | string(Long) | 是 | 雪花 ID | 团期主订单 ID | + +#### 出参字段表 + +| 字段 | 类型 | 说明 | +|---|---|---| +| data | null | 返回 200 表示物资确认成功;**是否推进到待出发由七项硬门决定,需前端重新拉详情确认状态** | + +#### 请求示例 + +```http +POST /v3/admin/order/group-batch/2099073597908647938/confirm-material +Authorization: Bearer +``` + +#### 响应示例 + +```json +{ "code": 200, "msg": "成功", "data": null } +``` + +#### 空数据 / 降级响应 + +受阻时接口仍返 200(物资确认本身成功),团期停在 `MATERIAL_PREPARING`,时间线新增一条 `BATCH_DEPARTURE_BLOCKED`(`changeType=DATA`,content 为未通过门中文名逗号串,如「房车导摄四项配齐,合同保险全齐」)。 + +#### 错误响应 + +```json +{ "code": 589500, "msg": "团期不存在", "data": null } +``` + +(589507=无 group-batch:manage 权限;状态非 MATERIAL_PREPARING 等既有校验口径一行未改) + +#### 业务边界 + +- **行为变化**:改前双门满足即推进;改后重判七项硬门,全过才跳 `PENDING_DEPARTURE`,否则停留并留痕。 +- 七项不短路——一次收齐全部未通过项写进同一条留痕。 +- 受阻不抛业务码、零新增错误码。 + +### 3. 手工复判进入待出发硬门 `POST /v3/admin/order/group-batch/:groupBatchId/recheck-departure-gate` + +**VO**: `GroupBatchDepartureGateRecheckRespVO` + +#### 使用场景 + +补齐缺失项(设主报账人、出齐合同保险等)后,运营手工触发一次进入待出发复判,不必等定时扫描。 + +#### 入参字段表 + +| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | +|---|---|---|---|---|---| +| groupBatchId | path | string(Long) | 是 | 雪花 ID | 团期主订单 ID | + +#### 出参字段表 + +| 字段 | 类型 | 说明 | +|---|---|---| +| advanced | boolean | 是否本次推进到待出发 | +| notApplicable | boolean | 状态不是 MATERIAL_PREPARING 等不适用场景(不报错) | +| gates | array\|null | 受阻时逐项返回未通过原因(结构同 departureGates) | + +#### 请求示例 + +```http +POST /v3/admin/order/group-batch/2099073597908647938/recheck-departure-gate +Authorization: Bearer +``` + +#### 响应示例 + +```json +{ "code": 200, "msg": "成功", "data": { "advanced": true, "notApplicable": false, "gates": null } } +``` + +#### 空数据 / 降级响应 + +不可复判(状态已变、七门未全过)时返回 `advanced=false`(或 `notApplicable=true`),**不抛业务异常**,故本端点零新增错误码。 + +#### 错误响应 + +```json +{ "code": 589500, "msg": "团期不存在", "data": null } +``` + +(589507=无 group-batch:manage 权限) + +#### 业务边界 + +- 幂等:重复调用第二次因状态已变返 `notApplicable`。 +- 与确认物资走同一套七项硬门求值器,判据一致。 + +## 四、契约约束与正确调用方式 + +- `departureGates[].blockedOrderId` 是字符串,勿按 number 解析。 +- 确认物资返回 200 **不代表已进入待出发**——必须重新拉详情看 `batchStatus` 与 `departureGates`。 +- 七项门中文名以后端 `gateName` 为准,前端直接渲染,勿在前端另写一份字面量。 + +## 五、数据库行为 + +- 唯一持久化相关改动:团期时间线 `group_batch_status_log.event_type` 新增枚举值 `BATCH_DEPARTURE_BLOCKED`(该列为 VARCHAR(64),**零 DDL**)。 +- 无新表、无新列、无新索引、无 Flyway 迁移。 + +## 六、边界行为 + +- 出发推进跳(定时任务 1041)受阻:按指纹去重后写一条 `BATCH_DEPARTURE_BLOCKED`(同团同组未通过项最多一条,未通过项变化才追加),团期停在 `PENDING_DEPARTURE` 不倒退。 +- 出行完毕跳(1042)不设门,行为一字未改。 +- 进入待出发后某项被打回(房务打回 hotel_ready、主报账人改 NONE、合同重开):团期主状态**有意不倒退**,但出发跳会被拦下——运营需看详情页 `departureGates` 与时间线补齐。 + +## 六.6、修改前后对比 + +| 维度 | 改前 | 改后 | +|---|---|---| +| 进入待出发 | 确认物资时「双门恰好满足即自动推进」 | 确认物资后重判**七项硬门**,全过才推进,受阻停留 `MATERIAL_PREPARING` 并留痕 | +| 出发推进(1041) | 到日子零校验发车 | 到日子重判**同一套七项硬门**,受阻跳过该团(去重留痕),全过才发车 | +| 团期详情 `GroupBatchDetailRespVO` | 无 `departureGates` | 新增 `departureGates`(7 项,仅两个状态返回,否则 null) | +| 端点数 | — | 新增 `recheck-departure-gate` 1 个 | +| 确认物资响应 | 200 即已推进 | 200 仅表示物资确认成功,是否推进另看详情 | +| 错误码 / DDL / 网关 | — | **零新增、零改动** | + +## 六.7、影响评估 + +- **兼容性**:详情响应体**纯增** `departureGates`,未消费该 key 的前端页面无需改动即可继续工作。 +- **需要前端动的**: + 1. 团期详情页渲染 `departureGates` 七项硬门状态(发车受阻可见性主入口,定案16,不渲染等于没落地); + 2. 确认物资后改为**重新拉详情**判断状态,不再假设已跳待出发; + 3. `blockedOrderId` 按字符串处理。 +- **性能**:详情多一次「一次投影 + N 次出行人计数 + 复用已取的主报账人」,仅对 `MATERIAL_PREPARING`/`PENDING_DEPARTURE` 两状态求值;团内活跃子订单个位到几十,成本可接受,软依赖失败降级为 null。 +- **存量风险(预期行为)**:存量团被新门卡住不豁免(定案10),处置是补齐缺失项(补合同保险/证件/主报账人/回补四项 ready),非开旁路。 + +## 七、不影响范围 + +- 既有字段(含四项 ready、materialConfirmed)名称/类型/取值/null 语义一字未改。 +- 无网关路由改动、无 Feign/MQ 改动、无错误码新增。 +- 出行完毕推进(1042)、其它团期端点行为不变。 + +## 八、测试环境已验证 + +2026-09-13 TEST 网关 + 内部端口 + 真 MySQL IT 三路取证,工单 #7528 的 AC-1~26 + AC-R1~R3 共 29 条全部逐条通过: + +- 网关实测(自签 admin token):confirm-material 七门逐项拦截/放行、详情 departureGates 七项含字符串 blockedOrderId、TRAVELLING/RECRUITING → null。 +- 内部端口(X-Internal-Token 直连 8086):1041 准入轮兜底推进、出发跳拦截留痕 + 指纹去重(3 次→1 条、换因→+1 条)、放行 TRAVELLING、一团受阻不影响其余、出行完毕跳不设门。 +- 真 MySQL IT:`REQUIRES_NEW` 事务语义(外层回滚后写入存活)。 +- 全量:order-v3 单测 10574 test / 0 failure / 0 error。 + +## 十、相关文档 + +- 工单 #7528(GB-ADM-006) +- 全过程记录:HL 仓 `dev-records/records/2026-09-13-local-7528-departure-gates.md` + +## 关联 / 联系人 + +- 后端:jw(已部署 dev-v3 + TEST 实测) +- 前端:mmg(需在团期详情页渲染 departureGates 七项硬门状态;确认物资后改为重新拉详情)