修改原因:管理后台已完成 #5279 的契约消费和回归验证,需要将 source 状态从已领取推进到已实现。 修改内容:通过 alias-aware transition 写入 frontend_status=implemented、frontend_owner=hl-admin,并记录前端提交 2ee0988c235c0483a5b51f8cc0deb195d7fd8573。 实际验证:source 测试 46 项通过,path aliases 校验和 git diff --check 通过;管理后台 checkpoint、140 项定向测试及生产构建通过。 Changelog: changelogs-v2/2026-07/27_5279_车务派单全链路E2E前端缺陷交接-修改接口-管理后台.md
13 KiB
schema, ticket, title, consumer, 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 | change_type | backend_status | gateway_status | frontend_status | frontend_owner | frontend_ref | target_release | verified_at | status_note | updated_at | base |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| hl-changelog/v2 | 5279 | 车务派单全链路 E2E 前端缺陷交接 | admin | 修改接口 | deployed | verified | implemented | hl-admin | 2ee0988c235c0483a5b51f8cc0deb195d7fd8573 | 本次没有新增或修改后端字段、类型、必填性、路径和错误码;测试环境当前契约已验证。前端需修正动作码、部分日期、HOLD 费用草稿、刷新重置和冲突日期等消费逻辑。 | 2026-07-27 | dev-v3 |
车务:派单全链路 E2E 前端缺陷交接
服务:
hl-fleet-service、hl-order-service-v3工单: wx/HL#5279
前端基线:
mmg/hl-ui v2.1@5e6718f952ed156c2e71bc38d08c3482e72ba744影响范围: 车务管理 → 派单看板、矩阵派单、派车弹窗、派单详情;订单详情 → 用车需求调整
结论
这是一份当前契约消费纠错和前端缺陷交接,不是后端接口变更:
- 后端 #5275 已保证部分日期派车只消费目标切片,剩余日期和稳定槽位守恒;
- 后端 #5277 已恢复完整已派需求
canAssign=true + CHANGE_ASSIGNMENT; - 测试环境通过真实后台 UI 完成 HOLD、DIRECT、司机确认、最终确认、司机拒接、改车、改司机、需求驳回/换版/重派、逐日费用、免费服务日、冲突和重复提交;
- 当前剩余阻断均可在最新前端稳定复现,后端不应增加旧动作码别名或重复状态来迁就页面。
变更接口
本次不新增接口、字段或错误码,仅纠正以下现有管理后台接口的前端消费:
| 方法 | 路径 | 当前契约用途 |
|---|---|---|
GET |
/admin/fleet/board/orders |
看板代表行、能力字段、稳定槽位和未派切片上下文 |
GET |
/admin/fleet/board/orders/<orderId> |
当前有效派车组、逐日费用和独立生命周期 |
POST |
/admin/fleet/assignments/candidates |
车辆/司机可用窗口与真实冲突明细 |
POST |
/admin/fleet/assignments |
HOLD/DIRECT 首次派车 |
POST |
/admin/fleet/assignments/<assignmentId>/change |
按稳定槽位改车、改司机或同时改派 |
POST |
/admin/fleet/assignments/<assignmentId>/driver-confirmation |
登记司机回复 |
POST |
/admin/fleet/assignments/<assignmentId>/confirm |
最终确认执行 |
POST |
/admin/fleet/assignments/<assignmentId>/driver-reject |
司机拒接并退回未派 |
DELETE |
/admin/fleet/assignments/<assignmentId> |
取消派单 |
POST |
/admin/fleet/assignments/<assignmentId>/early-complete |
提前完结 |
一、动作码必须消费后端当前值
权威字段来自:
GET /admin/fleet/board/orders
GET /admin/fleet/board/orders/<orderId>
前端按 canAssign 和 availableActionCodes 渲染,不按中文状态或本地别名推断。
| 生命周期 | currentStep |
当前动作码 | 正确页面行为 |
|---|---|---|---|
unassigned |
2 | ASSIGN, REJECT_REQUIREMENT |
派车派人、驳回需求 |
holding_wait_driver |
3 | CHANGE_ASSIGNMENT, RECORD_DRIVER_CONFIRMATION, DRIVER_REJECT,出团前/当天另有 CANCEL_ASSIGNMENT |
继续派车、司机拒接、改派、取消 |
driver_confirmed |
4 | CHANGE_ASSIGNMENT, CONFIRM_EXECUTION,出团前/当天另有 CANCEL_ASSIGNMENT |
恢复第 4 步确认执行;不得只剩改派 |
assigned 且未过出团日 |
4 | CHANGE_ASSIGNMENT, CANCEL_ASSIGNMENT |
改派、取消派单 |
assigned 且已过出团日 |
4 | CHANGE_ASSIGNMENT, EARLY_COMPLETE |
改派、提前完结 |
completed/canceled |
终态 | 无可写动作 | 只读 |
当前前端存在三处精确错位:
- 检查
CANCEL,而后端下发CANCEL_ASSIGNMENT; - 检查
COMPLETE_EARLY,而后端下发EARLY_COMPLETE; driver_confirmed已下发CONFIRM_EXECUTION,但卡片和详情没有恢复确认执行入口。
DRIVER_REJECT 与 RECORD_DRIVER_CONFIRMATION 是现行值,继续沿用。不要让后端同时下发新旧两套动作码。
二、部分日期稳定槽必须保留用户点击上下文
复现
测试单 26-6263 的同一 assignmentSlotId:
- 07-30、07-31:已有 HOLD;
- 08-01:唯一剩余
unassigned; - 看板卡片正确显示“用车 08-01 · 1天”;
- 8 月矩阵未派池也只显示 08-01。
但当前前端:
- 从看板进入 Step 2 后改成编辑 07-30/07-31 的 active HOLD;
- 从矩阵车辆 08-01 空闲格进入时,顶部虽显示“有效服务日期:08-01”,Step 2 却显示
已选 0/0 天,继续复用 07-30/07-31 费用并返回 0 个候选。
正确规则
- 首次派车
mode=assign必须保留用户点击的看板代表行:assignmentId/assignmentSlotId/fleetItemIndex/startDate/endDate;详情异步返回后不能被currentAssignment覆盖; - 矩阵入口以
entryContext.clickedDate + startDate + endDate与订单合法服务段求交集;本例结果固定为 08-01; currentAssignment/activeAssignments[]只用于改派和确认已有有效派车组,不代表未派切片;- 实际计费服务日为空时,应从已经校验通过的
assignmentDateRange回退生成,不得读取另一 active 组的逐日费用; - 提交仍使用原稳定
assignmentSlotId,只消费 08-01,不得重建第二槽位或覆盖 07-30/07-31。
三、HOLD 手工补价不能在司机确认后丢失
复现
26-9140 改派时:
- 07-30/07-31 使用日历价 860;
- 08-01 日历缺价,页面提交覆盖价 860 和调价原因;
/change返回并落库总价 2580;- 派单详情也正确展示 08-01 覆盖价和原因。
登记司机确认后,Step 4 又从候选价格日历重建费用,08-01 变为“待补价”,总价变为“价格不完整”,validateVehicleFeeDraft 阻断最终确认。
正确规则
- HOLD 已创建后,
activeAssignments[]/currentAssignment的dailyVehicleFees、vehicleFeeTotal、vehicleFeeAdjustmentReason、chargeableServiceDates和vehicleFeeWaiverReason是当前派车组权威快照; - 候选接口的价格只用于新选车草稿或日历参考,不得覆盖已经保存的 HOLD 费用;
- 第 3 步登记司机回复和第 4 步确认执行都不能清空已保存覆盖价;
- 详情重拉后应按
assignmentId/assignmentGroupId恢复同一派车组快照。
四、后台刷新不得重置正在编辑的派车草稿
实测派车弹窗打开后,后台订单刷新会触发整套初始化:
- 候选接口已返回 19 辆车和 11 名司机,但两个列表被清空,计数/筛选项仍保留;
- 用户已切换 DIRECT,提交前又恢复为 HOLD;
- 再点一次筛选会重新请求并恢复候选。
前端应做到:
props.order仅因列表/SSE 刷新生成新对象时,不重置当前弹窗;- 只有订单 ID、目标需求 ID、目标稳定槽位、模式或用户主动关闭/重开变化时才重新初始化;
- 已编辑车辆、司机、日期、收费日、逐日价、原因、跨常驻确认和 HOLD/DIRECT 模式全部保留;
- 若服务端基线真的变化,使用现有 baseline-difference 强提示并让用户决定,不静默改写草稿。
五、多槽 HOLD 必须按槽位推进
26-5256 有两个稳定车辆槽位。槽位 1 登记司机确认后:
- 详情真值为槽位 1
driver_confirmed、槽位 2holding_wait_driver; - 卡片却仍把代表司机显示为“待回复”;
- “继续派车”入口消失,槽位 2 无法登记司机回复。
正确行为:
- 订单只要任一 active 槽位包含
RECORD_DRIVER_CONFIRMATION,卡片和详情保留“继续派车”; - 打开后默认选中最早待回复槽位,也允许切换其它槽位;
- 一个槽位确认不得覆盖或隐藏另一个槽位状态;
- 订单聚合步骤取最慢槽位,代表卡文案必须明确“代表槽位”,不能冒充全单状态。
六、冲突窗口字段不能混用
候选响应同时包含:
| 字段 | 含义 | 页面用途 |
|---|---|---|
conflicts[] |
真正占用冲突;blocking=true 的日期禁止选择 |
展示冲突订单与冲突日期 |
availabilityWindows[] |
当前查询区间内仍可用的连续窗口 | 仅在资源可用/部分可用提示中展示 |
availabilityReasonCode |
AVAILABLE、ASSIGNMENT_CONFLICT 等判定码 |
决定禁用和提示类型 |
availabilityReasonMessage |
后端判定文案 | 展示主提示 |
实测后端冲突是 08-01,availabilityWindows 是 08-02..08-04;页面却显示“存在派单冲突 · 08-02 至 08-04”。禁用结果正确,日期解释相反。
冲突文案应从 conflicts[].startDate/endDate 汇总;availabilityWindows 不得拼在冲突文案后。
七、提交与刷新反馈
1. 防重复提交
真实 UI 同一时刻双击 DIRECT 发出两个不同 requestId:
- 第一笔成功并只生成一个有效派车;
- 第二笔被后端守恒门禁拒绝,返回
605033:用车需求完成回写处理中,请稍后重试。
前端应在第一笔进入提交函数时立即短路后续点击,并在按钮、快捷键和程序触发路径共用同一 submitting 门禁。同一草稿的网络重试应复用 requestId,不应每次生成新值。
2. 司机拒接后的详情
司机拒接成功后,卡片立即变为未派,但当前详情抽屉仍保留旧 HOLD 车辆、费用和动作。关闭重开才正确。成功后需用最新服务端详情整体替换旧对象,不得继续把 mutation 前的行快照合并回来。
3. 车务角色快捷入口
车务角色下顶部可见“订单列表”,点击却进入未注册 /housekeeper/orders 并显示 404。未注册/无权限时不要展示快捷入口;有权限时应确保动态路由已注册再导航。
八、前端验收清单
CANCEL_ASSIGNMENT显示并执行取消;不再检查CANCEL。EARLY_COMPLETE显示并执行提前完结;不再检查COMPLETE_EARLY。driver_confirmed + CONFIRM_EXECUTION可从卡片和详情恢复第 4 步。- 多槽 HOLD 任一槽位待回复时保留“继续派车”,逐槽推进且代表状态不串槽。
26-6263从看板和 8 月矩阵都只编辑/提交 08-01,07-30/07-31 不变。- 已保存 HOLD 的手工逐日价、调价原因和免费日配置在司机确认、详情刷新、最终确认之间保持不变。
- SSE/列表刷新不清空候选、车辆司机草稿或切换 HOLD/DIRECT 模式。
- 冲突日期取
conflicts[],可用窗口取availabilityWindows[],两者文案不混用。 - DIRECT/HOLD 第一击后立即禁用所有重复提交路径;同草稿重试复用 requestId。
- 司机拒接后当前卡片和详情同时刷新到 unassigned。
- 车务角色的订单快捷入口不再进入 404。
验证证据
- 后端
dev-v3@79297c838b62af2426cc83ad0e78cffbd961096b已部署,Fleet 8087/8187 两实例健康; - #5277 Fleet reactor 2,427 项通过,0 失败、0 错误、1 跳过;Spotless 通过;
- 网关验证:完整 assigned 单槽和三槽均为
canAssign=true + CHANGE_ASSIGNMENT; - 真实 UI 写入通过:HOLD、DIRECT、司机确认、最终确认(不发送短信)、司机拒接、只换车、只换司机、同时换车司机、需求驳回、V2/V3 换版重派、收费/免费日、重复提交;
- 后端守恒:重复 DIRECT 只生成一笔有效派车;需求
DONE_ADJUST返回assignmentDeletedCount=1,旧资源随后可重新选择; - 部分日期后端真值:07-30/07-31 为 HOLD,08-01 唯一 unassigned,三天共用稳定槽位,无重复/孤儿;
- 关键页面截图:
fleet-partial-continuation-broken.png、5277-assigned-reassign-restored.png; - 完整逐步证据由 #5279 工单评论和测试记录保留。
十、契约审查
- 本文件不对应新的 Controller、VO、字段、类型、必填性、动作码或错误码变更;
- OpenAPI/oasdiff:
not_required,没有新的frontend_apidiff; - Consumer Contract:
not_required,没有 Feign/shared Java 变化; - 当前动作码由
AssignmentLifecycleResolver和现有服务测试确认;部署网关响应与源码一致; - 前端代码审查确认当前仍检查
CANCEL、COMPLETE_EARLY,且没有消费CONFIRM_EXECUTION。
不影响范围
- 不修改
hl-ui,不在mmg/hl-ui建工单;本文件frontend_status保持pending; - 不要求后端新增兼容动作码、重复字段、特殊前端分支或放松资源/幂等守恒;
- 不修改派车状态机、计费公式、库存/占用、保险、通知、Outbox 或数据库结构;
- 不把前端实现、发布、页面验收纳入后端工单关闭条件。