--- schema: "hl-changelog/v2" ticket: "7441" title: "确认订单前置清单——不需要住宿的订单直接通过 HOTEL_DONE,团车完成路径认 VEHICLE_DONE" consumer: "admin" author: "wx(GIT)" change_type: "修改接口" backend_status: "deployed" gateway_status: "verified" frontend_status: "not_required" frontend_owner: "" frontend_ref: "" target_release: "" verified_at: "" status_note: "HOTEL_DONE 短路(needsHotel=false)与 VEHICLE_DONE 认团车完成路径(isGroupVehicleCompleted)均有测试服真实网关调用前后对照(见第八节,见工单 #7441 验收评论,同一订单同一端点,PR-2b/2c 部署前后各一次)。被测服务:order-v3 = dev-v3 7d8cecb3e,2026-09-15 15:38 部署(含 PR-1~PR-3)。mmg 2026-09-15 核实:ConfirmChecklistModal 纯透传 checkName/failReason/passed 渲染,confirmChecklistActions 仅提供跳转动作不涉判定;LockModal 司机信息 driverName||'未配置' 已兜 null。两项判定放宽对前端零影响,判 not_required。" updated_at: "2026-09-15" base: "dev-v3" --- # order-v3: 确认订单前置清单——房车安排短路判定 > **存放目录**: `changelogs-v2/{YYYY-MM}/`(管理后台,二期 order-v3) > > **服务**: hl-order-service-v3 (端口 8083) > **PR**: #7753(PR-2b)、#7762(PR-2c) > **Issue**: #7441 > **日期**: 2026-09-15 > **影响范围**: 既有端点 `GET /v3/admin/order/{id}/confirm-checklist`(及其内部复用的确认行程弹框预览),`items[]` 中 `HOTEL_DONE`/`VEHICLE_DONE` 两项的判定条件变化,响应结构与错误码均未改 --- ## ⚠️ 关键变化 1. **`needsHotel=false` 的订单,`HOTEL_DONE` 项从此直接通过**——改前该类订单恒得"未提交用房需求",永久卡在"确认订单"这一步走不到结算定稿;本单起与既有的 `needsVehicle=false` 短路同口径。 2. **团期用车走"团车"路径完成(而非逐户 DAILY_V3 快照)的订单,`VEHICLE_DONE` 项从此能通过**——改前该类订单即使团车已经配好、订单镜像与需求状态都已是 `DONE`,仍会因为找不到逐户配车记录而恒得"未找到有效配车记录",同样永久卡在确认订单这一步。这是团期用车走团级配车(而不是逐户派车)这一新路径(`#7441` D-C22)与本清单既有判据之间的缺口,本单补上。 3. **确认行程弹框预览的司机信息**:团车完成路径的订单不再尝试查逐户配车记录来展示司机/车牌(那本就查不到,展示出来也是误导),预览里该块留空,其余预览字段不受影响。 --- ## 一、背景 `GET /v3/admin/order/{id}/confirm-checklist` 是"确认订单"前的 5 项前置校验(款项、出行人、住宿、用车、合同方案),本单只涉及其中住宿(`HOTEL_DONE`)与用车(`VEHICLE_DONE`)两项,接口本身在此前已有 changelog 记录(见 `13_4941`/`13_4853` 等既有文档),完整字段与另外三项判据不在本单重复。 `#7441` 落地了"团车"完成路径(`D-C22`:fleet 团级配车完成后,order-v3 只回写户级需求状态与镜像列为 `DONE`,不落任何逐户配车记录)。`VEHICLE_DONE` 原判据要求"当前 active 需求必须有对应的逐户配车记录",这与团车路径天然矛盾——2026-09-15 测试服取证时发现该缺口(团车完成的订单到不了"确认行程",见发现记录),当场排进本单一并修复;同批顺带修了此前已知的 `needsHotel=0` 卡死问题。 --- ## 二、变更接口清单 | # | 接口 | 方法 | 路径 | 变更类型 | 说明 | |---|------|------|------|----------|------| | 1 | 5 项 checklist 校验(确认订单前置) | GET | `/v3/admin/order/{id}/confirm-checklist` | 判定逻辑修正 | HOTEL_DONE 对 needsHotel=false 短路;VEHICLE_DONE 认团车完成路径 | --- ## 三、接口详情 ### 1. 5 项 checklist 校验(确认订单前置) `GET /v3/admin/order/{id}/confirm-checklist` **VO**: `无请求体 → Result` #### 使用场景 订单详情页点"确认订单"前调用,5 项全部通过时返回确认预览数据(`allPassed=true`),否则返回逐项失败原因(`allPassed=false`)。本单只影响 `HOTEL_DONE`/`VEHICLE_DONE` 两项的判定条件,接口结构、调用方式不变。 #### 入参字段表 | 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | |------|------|------|------|------|------| | id | Path | Long | 是 | - | 订单 ID(不变) | #### 出参字段表 | 字段 | 类型 | 说明 | |------|------|------| | allPassed | Boolean | 是否全部通过(唯一开关,不变) | | items | List | 5 项详细结果(仅 allPassed=false 时返回,不变) | | items[].code | String | 检查项代码:TRAVELER_COMPLETE/PAYMENT_OK/HOTEL_DONE/VEHICLE_DONE/CONTRACT_TEMPLATE_OK(不变) | | items[].checkName | String | 检查项中文名(不变) | | items[].passed | Boolean | 是否通过(本单:HOTEL_DONE/VEHICLE_DONE 两项的判定条件变化,见业务边界) | | items[].failReason | String | 未通过原因(通过时为 null,不变) | | preview | PreviewVO | 确认行程弹框预览(仅 allPassed=true 时返回,不变) | | preview.driverName/driverPhoneMasked | String | 司机信息;团车完成路径的订单本单起不再查逐户配车记录,恒为 null(其余预览字段不受影响) | #### 请求示例 ```http GET /v3/admin/order/2099716821748715521/confirm-checklist HTTP/1.1 Authorization: Bearer {token} ``` #### 响应示例 改前(测试服真实响应,2026-09-15 12:30:55,dev-v3 64c3f72a3,见工单 #7441 验收评论): ```json { "code": 200, "message": "成功", "data": { "allPassed": false, "items": [ { "code": "PAYMENT_OK", "checkName": "款项校验", "passed": true, "failReason": null }, { "code": "TRAVELER_COMPLETE", "checkName": "出行人信息", "passed": true, "failReason": null }, { "code": "HOTEL_DONE", "checkName": "房型安排", "passed": false, "failReason": "未提交用房需求" }, { "code": "VEHICLE_DONE", "checkName": "用车安排", "passed": false, "failReason": "未找到有效配车记录" }, { "code": "CONTRACT_TEMPLATE_OK", "checkName": "合同方案配置", "passed": false, "failReason": "产品未配置合同方案" } ], "preview": null }, "success": true } ``` 改后(测试服真实响应,2026-09-15 15:44:23,dev-v3 7d8cecb3e,同一订单,见工单 #7441 验收评论): ```json { "code": 200, "message": "成功", "data": { "allPassed": false, "items": [ { "code": "PAYMENT_OK", "checkName": "款项校验", "passed": true, "failReason": null }, { "code": "TRAVELER_COMPLETE", "checkName": "出行人信息", "passed": true, "failReason": null }, { "code": "HOTEL_DONE", "checkName": "房型安排", "passed": true, "failReason": null }, { "code": "VEHICLE_DONE", "checkName": "用车安排", "passed": true, "failReason": null }, { "code": "CONTRACT_TEMPLATE_OK", "checkName": "合同方案配置", "passed": false, "failReason": "产品未配置合同方案" } ], "preview": null }, "success": true } ``` (该订单其余 3 项判定未变,`allPassed` 此时仍为 false 是因为 `CONTRACT_TEMPLATE_OK` 未过——与本单无关,如实随原始响应带出。) #### 空数据 / 降级响应 互斥语义不变:`allPassed=true` 时 `items` 为 null、`preview` 有值;`allPassed=false` 时相反。本单不改这一互斥规则。 ```json { "code": 200, "success": true, "data": { "allPassed": true, "items": null } } ``` #### 错误响应 本单不新增错误码,沿用既有: ```json { "code": 404, "message": "订单不存在", "success": false, "data": null } ``` #### 业务边界 - HOTEL_DONE 判定顺序:0. needsHotel=false 直接通过(本单新增);1. roomControlStatus=DONE 直接通过;2. 镜像非 DONE 且子表无记录,"未提交用房需求";3. 子表最新版本非 DONE,"用房需求未完成"。第 0 步只在 Boolean.FALSE.equals(needsHotel) 时短路,null 仍按"需要配房"从严处理(生产库该列 NOT NULL DEFAULT 0,不会读出 null)。 - VEHICLE_DONE 判定顺序:1. needsVehicle=false 直接通过(不变);2. 订单镜像与当前 active 需求必须同时为 DONE(不变);3. 完成来源按序三分支(本单改):① 契约版本 DAILY_V3,校验本地快照合格(不变);② 团车合法缺席(本单新增):非 DAILY_V3 且需求 DONE 且完成来源标识为 GROUP_VEHICLE,直接通过,不要求逐户配车记录;③ 其余仍要求当前 active 需求存在对应逐户配车记录(不变)。 - ② 为何必须用正向标识、不能用"非 DAILY_V3 即团车"反推:历史上存在一类逐户完成行,完成来源标识同样为空,与团车形态在其余列上逐列相同;用排除法会把这批历史订单也一并放行,而这类订单在结算侧仍会被拦(见另一份 PR-3 changelog 的 584100),造成"清单放行、核单拦截"的分叉。测试服实测确认历史形态(LEG 户)仍被本判据正确拦住,"未找到有效配车记录"。 - 与结算侧同一份判据、同一处代码来源,保证"清单放行"与"核单不因车侧被拦"结论一致,不会出现两处矛盾。 - 老数据兼容:存量订单的 HOTEL_DONE/VEHICLE_DONE 若此前一直显示"未提交需求"类失败,本单合并部署后若满足上述新增短路条件会变为通过——这是修复缺陷,不是引入新的不通过场景。 --- ## 四、契约约束与正确调用方式 本单不改请求参数或响应结构,前端无需修改调用方式。唯一需要知道的是:`HOTEL_DONE`/`VEHICLE_DONE` 从"失败"变为"通过"的订单,此前若因为这两项失败而在前端做过特殊提示或跳转,需要确认该提示不再误触发(正常情况下前端只是照 `items[].passed` 渲染,无需改动)。 --- ## 五、数据库行为 本端点全程只读,不产生任何写入。本单只改判定条件,不改任何查询语句涉及的表。 --- ## 六、边界行为 - 未登录 → 401(网关拦截) - 订单不存在 → 404(不变) - needsHotel/needsVehicle 为 null(仅可能出现在极少数历史数据或测试环境)→ 从严按"需要"处理,不短路 - 老数据兼容:不改变任何已通过订单的结果,只让此前被误拦的两类订单变为通过 --- ## 六.6、修改前后对比 ### 字段级对比 本单不改字段结构,仅改 `items[].passed`/`items[].failReason` 在特定条件下的取值。 ### 行为级对比 | 订单形态 | 改前 | 改后 | |------|------|------| | needsHotel=false | HOTEL_DONE 恒 false,"未提交用房需求" | HOTEL_DONE 直接 true | | 团车完成路径(需求 DONE + 完成来源 GROUP_VEHICLE,非 DAILY_V3) | VEHICLE_DONE 恒 false,"未找到有效配车记录" | VEHICLE_DONE 直接 true | | 历史 legacy 逐户完成行(需求 DONE,完成来源标识为空,非 DAILY_V3) | VEHICLE_DONE false | 仍为 false(本单未改,与团车形态用完成来源标识区分开) | | DAILY_V3 逐户快照完成 | 按本地快照校验(不变) | 不变 | | needsHotel=true 且用房需求未完成 | HOTEL_DONE false(不变) | 不变 | --- ## 六.7、影响评估 - **是否破坏向后兼容**: 否。本单只放宽两项误拦,不收紧任何既有通过条件。 - **前端是否必须同步上线**: 否,接口契约不变。若前端此前对这两项失败做过特殊 UI 处理(例如"该订单团车已配好但系统显示未完成,请联系技术"之类的人工绕过提示),可以清理。 - **前端 workaround 清理点**: 若存在上述人工绕过提示,可清理;未做特殊处理则零改动。 --- ## 七、不影响范围 - **仅影响**: `GET /v3/admin/order/{id}/confirm-checklist` 的 `HOTEL_DONE`/`VEHICLE_DONE` 两项判定条件与确认预览的司机信息展示。 - **零影响**: - `PAYMENT_OK`/`TRAVELER_COMPLETE`/`CONTRACT_TEMPLATE_OK` 三项判定——未改。 - `POST /v3/admin/order/{id}/confirm-itinerary`(确认行程,内部复用同一套 checklist 判定)——契约未改,行为随 checklist 联动。 - 结算侧车侧闸门(584131/584100)——判据来源同一处代码,但那是另一个端点,另案说明(见另一份 PR-3 changelog)。 - hl-common-*、hl-fleet-service、hl-gateway 路由——本单只改 hl-order-service-v3,未新增路由。 --- ## 八、测试环境已验证 **取证环境**:order-v3 = dev-v3,改前批次 `64c3f72a3`(2026-09-15 12:06:01 部署),改后批次 `7d8cecb3e`(2026-09-15 15:38:56 部署,含 PR-1~PR-3);同一订单(orderId=2099716821748715521,团期用车走团车路径,needsHotel=0)在两次部署上各调用一次 `GET .../confirm-checklist`,经 hl-gateway 网关实调,响应对比见「三、1」响应示例。历史 legacy 完成行的对照户(orderId=2099716832188338178)同一时刻仍返回 VEHICLE_DONE=false,证明本单没有连带放宽这类订单,详见工单 #7441 验收评论。 --- ## 十、相关文档 - 关联 Issue: [wx/HL#7441](https://git.1814.love:8443/wx/HL/issues/7441) - 关联 PR: [#7753](https://git.1814.love:8443/wx/HL/pulls/7753)(PR-2b,VEHICLE_DONE 团车路径)、[#7762](https://git.1814.love:8443/wx/HL/pulls/7762)(PR-2c,HOTEL_DONE 短路) - 既有基线:`13_4941_确认订单checklist删除actionPath-修改接口-管理后台.md`、`13_4853_确认订单预览提交接口-修改接口-管理后台.md`(本单不重复其内容,仅描述本次增量) - 相关分册:`#7441` PR-1(正式用车需求声明四端点)、`#7441` PR-2 内部接口分册(团车完成回写是本单能通过的前提数据来源)、`#7441` PR-3(finalize 584131 硬阻断) - **验收口径边界**:页面完成状态单独跟踪(前端归 mmg),不计入 #7441 验收;#7441 验收范围 = API 契约 + 状态流转 + 占用账本 + changelog 交接件。 ## 关联 / 联系人 ### 链接 - **Issue**: [#7441](https://git.1814.love:8443/wx/HL/issues/7441) - **PR**: [#7753](https://git.1814.love:8443/wx/HL/pulls/7753)、[#7762](https://git.1814.love:8443/wx/HL/pulls/7762) ### 联系人 - **后端负责人**: @wx - **前端负责人(收件人)**: @mmg