hl-api-changelog/changelogs-v2/2026-07/27_5279_车务派单全链路E2E前端缺陷交接-修改接口-管理后台.md
Mimingguang f7a0b9b539
所有检测均成功
changelog-filename-gate / validate (push) Successful in 2s
chore(changelog): 标记 #5279 已实现
修改原因:管理后台已完成 #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
2026-07-27 11:46:26 +08:00

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-servicehl-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>

前端按 canAssignavailableActionCodes 渲染,不按中文状态或本地别名推断。

生命周期 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 终态 无可写动作 只读

当前前端存在三处精确错位:

  1. 检查 CANCEL,而后端下发 CANCEL_ASSIGNMENT
  2. 检查 COMPLETE_EARLY,而后端下发 EARLY_COMPLETE
  3. driver_confirmed 已下发 CONFIRM_EXECUTION,但卡片和详情没有恢复确认执行入口。

DRIVER_REJECTRECORD_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[]/currentAssignmentdailyVehicleFeesvehicleFeeTotalvehicleFeeAdjustmentReasonchargeableServiceDatesvehicleFeeWaiverReason 是当前派车组权威快照;
  • 候选接口的价格只用于新选车草稿或日历参考,不得覆盖已经保存的 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、槽位 2 holding_wait_driver
  • 卡片却仍把代表司机显示为“待回复”;
  • “继续派车”入口消失,槽位 2 无法登记司机回复。

正确行为:

  • 订单只要任一 active 槽位包含 RECORD_DRIVER_CONFIRMATION,卡片和详情保留“继续派车”;
  • 打开后默认选中最早待回复槽位,也允许切换其它槽位;
  • 一个槽位确认不得覆盖或隐藏另一个槽位状态;
  • 订单聚合步骤取最慢槽位,代表卡文案必须明确“代表槽位”,不能冒充全单状态。

六、冲突窗口字段不能混用

候选响应同时包含:

字段 含义 页面用途
conflicts[] 真正占用冲突;blocking=true 的日期禁止选择 展示冲突订单与冲突日期
availabilityWindows[] 当前查询区间内仍可用的连续窗口 仅在资源可用/部分可用提示中展示
availabilityReasonCode AVAILABLEASSIGNMENT_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.png5277-assigned-reassign-restored.png
  • 完整逐步证据由 #5279 工单评论和测试记录保留。

十、契约审查

  • 本文件不对应新的 Controller、VO、字段、类型、必填性、动作码或错误码变更;
  • OpenAPI/oasdiffnot_required,没有新的 frontend_api diff;
  • Consumer Contractnot_required,没有 Feign/shared Java 变化;
  • 当前动作码由 AssignmentLifecycleResolver 和现有服务测试确认;部署网关响应与源码一致;
  • 前端代码审查确认当前仍检查 CANCELCOMPLETE_EARLY,且没有消费 CONFIRM_EXECUTION

不影响范围

  • 不修改 hl-ui,不在 mmg/hl-ui 建工单;本文件 frontend_status 保持 pending
  • 不要求后端新增兼容动作码、重复字段、特殊前端分支或放松资源/幂等守恒;
  • 不修改派车状态机、计费公式、库存/占用、保险、通知、Outbox 或数据库结构;
  • 不把前端实现、发布、页面验收纳入后端工单关闭条件。