后端已合入 dev-v3(PR #8024 -> 920f29d76)并部署测试服,四条真实网关调用取证: 读口双槽(带全 null 阳性对照) / 一次 submit 同交两份落两条 active 行 / 两条 label 原文不同的调整记录 / 无大交通时 809002。 service_dates 两个 kind 分别派生成行程三天与接机送机两天,前端一个日期都不传。 覆盖边界写在正文与 status_note 里: 本文只验到「提交」为止。同一次实测观测到 TRANSFER 需求同步车务的 outbox 恒失败 605905(fleet AssignmentService:11492 取当前需求不带 kind),前端可并行开工但端到端尚未打通。
9.9 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 | 7443 | 调整订单「车辆安排」页同页提交 行程用车(TRAVEL) + 接送机用车(TRANSFER) 两类需求 | admin | wx(GIT) | 修改接口 | deployed | verified | pending | mmg | 2026-09-20 | 后端已合入 dev-v3(PR #8024,squash 提交 920f29d76)并部署测试服:deploy-status.sh 回读 hl-order-service-v3 = dev-v3 @ 920f29d76、BEHIND=0/N、STATE=ok,两实例滚动重启均 UP,判据 git merge-base --is-ancestor 920f29d76 920f29d76 = true。gateway_status=verified 的依据是四条真实网关调用而非源码推断:①读口双槽(含阳性对照:未提交需求的订单两个字段都是 null,证明不是恒有值)②一次 submit 同时提交两份 → HTTP 200,落库两条 active 行,fleet 分别为 bus/19座/1台 与 mpv/7座/2台 ③调整记录两条 label 原文不同 ④无大交通时 809002。🔴 一条必须连着读的限定:本文只验证了「提交」这一段。同一次实测观测到 TRANSFER 需求同步给车务的 outbox 命令持续失败(order_fleet_command_outbox command_type=RECONCILE,TRAVEL=SUCCEEDED 而 TRANSFER=PENDING/retry_count=2,last_error_message='Fleet 用车需求换版失败: code=605905, message=需求版本过期'),根因是 hl-fleet-service AssignmentService:11492 requireCurrentVehicleRequirementForMutation 取当前需求时不带 kind、恒取 TRAVEL,与 TRANSFER 的 requirementId 比对必然不等。即:前端按本文接完即可正常提交并回显,但提交出去的接送机需求在修复该缺陷之前到不了车务侧,端到端业务尚未打通。该缺陷已在修(属 #7990 那一族),修好后另发交接件,不影响本文的前端契约。 | 2026-09-20 | dev-v3 |
order-v3: 调整订单「车辆安排」页同页提交 行程用车 + 接送机用车 两类需求
服务: hl-order-service-v3(adjustment 层,唯一变化点) 影响范围: 管理后台「调整订单 → 车辆安排」页。此前该页结构上只能提交行程用车,本次补上接送机用车的读口与写口。
这次修的是什么
「车辆安排」页此前只有一个用车需求槽。页面上那张接送机卡片(航班号、抵离时间、接送备注)
来自 vehicleTransportSummary,它是只读的大交通摘要——没有车型、座位数、数量输入,
也没有对应的提交字段。于是业务上「接机用什么车、用几辆」没有任何录入通道。
后端的用车需求模型本身早就支持两类并存:表 order_vehicle_requirement 的
requirement_kind 取 TRAVEL(行程用车,服务日=行程日)/ TRANSFER(接送机,服务日=航班日),
唯一键 (order_id, active_kind) ⇒ 同一订单两类 active 需求合法并存,各有自己的 fleet 与 service_dates。
缺口只在 adjustment 这一层把 kind 焊死成了 TRAVEL。本次把它透出来。
接口变更
1. GET /v3/admin/order/{orderId}/adjustment/snapshot(读)
新增响应字段 transferRequirement,类型与既有 vehicleRequirement 完全相同。
| 字段 | 说明 |
|---|---|
vehicleRequirement |
行为不变,仍是 TRAVEL(行程用车)。⚠️ 字段名与类型均未改动,现网页面无需调整 |
transferRequirement |
新增,TRANSFER(接送机用车)。该订单没有接送机需求时为 null |
两个字段的结构(同一个 VO):
| 字段 | 类型 | 说明 |
|---|---|---|
id |
String | 需求 id |
version |
Integer | 版本号 |
status |
String | 需求状态(如 PENDING_REVIEW) |
fleet |
Array | 车辆组合,元素 {vehicleType, seats, count} —— 即「用什么车、几座、几辆」 |
specialTags |
Array<String> | 特殊诉求标签 |
pickupRequired |
Boolean | 是否需要平台接机/接站 |
dropoffRequired |
Boolean | 是否需要平台送机/送站 |
remark |
String | 备注 |
claimerId / claimerName / claimedAt |
- | 抢单人信息 |
vehicleType / requiredSeats |
- | ⚠️ 旧兼容字段,恒为 null。车型与座位已迁入 fleet,不要再读这两个 |
vehicleTransportSummary(大交通摘要)保持原样不变,仍是只读展示用。
2. POST /v3/admin/order/{orderId}/adjustment/submit(写)
updates 下新增 transferRequirement,结构与既有 updates.vehicleRequirement 完全相同
(fleet / specialTags / pickupRequired / dropoffRequired / remark)。
- 只传
vehicleRequirement→ 行为与改动前逐字节一致(行程用车) - 只传
transferRequirement→ 只提交接送机用车 - 两个都传 → 一次提交落两条需求,这正是「同页提交」要的效果
调整记录(adjustment-record)里两者会产出可区分的两条 VEHICLE_REQ 条目:
行程用车需求已调整 / 接送机用车需求已调整。改动前恒为「车辆需求已调整」,两条无法区分。
🔴 serviceDates 前端不传。服务日由后端派生:TRAVEL 取行程日,TRANSFER 取大交通的航班/车次日期
(客人可能提前一天到、返程后一天走,所以允许落在行程日窗口之外)。
🔴 前端必须处理的前置:没有大交通时提交接送机需求会失败
TRANSFER 的服务日来自大交通,空集合不会兜底成行程日(那样会把航班日写错、
派车日期落到需求单声明范围之外)。因此该订单没有录入大交通行程时,
提交 transferRequirement 会返回 809002。
⇒ 建议前端在没有大交通时把接送机那一段的输入置灰,并提示「请先录入大交通行程」,
不要让用户填完再吃一个错误码。判断依据用同一份快照里的 vehicleTransportSummary.hasPickupTime
(为 false 时它还会给出 emptyText,当前文案是「暂无接送机时间」)。
⚠️ 两份同时提交而接送机这半抛 809002 时,整笔调整回滚(一次 submit = 一笔原子调整), 行程用车那半也不会落库。所以置灰比事后补救重要。
环境开关
hl.order.requirement.transfer-kind-submit-enabled
- 代码默认
false;生产环境未开,提交kind=TRANSFER返809009 - 测试服已置
true(2026-09-19 15:33:32 发布,随 order-v3 重启生效) - ⚠️ 该配置无
@RefreshScope,改完必须重启服务才生效
联调样本
| 订单 | 2101219133700952066(订单号 HL20260919155734730,散客单) |
| 特征 | 已录大交通 2 条;TRAVEL 与 TRANSFER 两类需求均已存在,可直接用来验双槽回显 |
实测读数(2026-09-20,测试服真实网关调用)
后端版本:hl-order-service-v3 @ 920f29d76(PR #8024 squash 合入 dev-v3)。
① 读口双槽 —— 带阳性对照
| 订单 | vehicleRequirement |
transferRequirement |
|---|---|---|
2101566624467419137(提交前) |
null |
null |
2101219133700952066(两类都有) |
{id:2101219223517659138, fleet:[{mpv,7,1}]} |
{id:2101219393722634242, fleet:[{mpv,7,1}]} |
⚠️ 第二行两者的 fleet 恰好相同(样本单本身如此),所以"两个字段不同"这件事不能拿来证明按 kind 取数生效;
真正证明它的是第一行那个全 null 的阳性对照,以及两者 requirementId 不同。
② 同页提交(本文的核心)
POST /v3/admin/order/2101566624467419137/adjustment/submit
updates.vehicleRequirement = {fleet:[{vehicleType:"bus", seats:19, count:1}]}
updates.transferRequirement = {fleet:[{vehicleType:"mpv", seats:7, count:2}]}
→ HTTP 200 {"code":200,"data":{"success":true}}
落库 order_vehicle_requirement 两条 active 行:
active_kind |
fleet |
service_dates |
|---|---|---|
TRAVEL |
[{"count":1,"seats":19,"vehicleType":"bus"}] |
["2026-10-20","2026-10-21","2026-10-22"](行程三天) |
TRANSFER |
[{"count":2,"seats":7,"vehicleType":"mpv"}] |
["2026-10-20","2026-10-23"](接机日 + 送机日) |
🔴 两个 service_dates 一个都不是前端传的,全部由后端按 kind 派生——这是「前端不传日期」这条约定的硬证据。
③ 调整记录可区分
GET /v3/admin/order/{id}/adjustment-record → 本次 changeCount:2,两条 type=VEHICLE_REQ,
label 分别是 行程用车需求已调整 / 接送机用车需求已调整。改动前两条 label 完全相同、事后分不出改的是哪一份。
④ 无大交通的失败形态
订单 2101567681155207169(同产品、已付款、无大交通),只提交 transferRequirement:
→ HTTP 200 + {"code":809002,"message":"接送机需求缺少服务日期,请先补齐大交通信息"}
(提交前已确认测试服 Nacos hl.order.requirement.transfer-kind-submit-enabled: true,
所以这个 809002 不是被开关挡住的假象。)
🔴 本文的覆盖边界:只验到「提交」为止
同一次实测里观测到:TRANSFER 需求同步给车务的 outbox 命令持续失败
(order_fleet_command_outbox,command_type=RECONCILE:TRAVEL SUCCEEDED,
TRANSFER PENDING / retry_count=2 / last_error_message="Fleet 用车需求换版失败: code=605905, message=需求版本过期")。
⇒ 前端按本文接完即可正常提交并回显,但提交出去的接送机需求目前到不了车务侧。
该缺陷在 fleet(AssignmentService:11492 取当前需求不带 kind、恒取 TRAVEL),已在修,
修好后另发交接件。它不改变本文的前端契约,可以并行开工。
⚠️ 写下这段是因为「四条实测全达成」这个汇总句丢掉边界之后会变强—— 会被读成「接送机用车已经端到端可用」,而那句话今天还不成立。