--- schema: "hl-changelog/v2" ticket: "5255" title: "已派车恢复改派与行程单入口更正" consumer: "admin" change_type: "修改接口" backend_status: "deployed" gateway_status: "verified" frontend_status: "implemented" frontend_owner: "hl-ui-codex" frontend_ref: "mmg/hl-ui@f9251d0ffabf13641630588733d103e00f35e85d" target_release: "" verified_at: "" status_note: "后端已部署并完成网关验证;前端需恢复已派车改派按钮,并将看板行程单入口直接复用订单详情现有打印实现。本文件覆盖 #5186 的已派车禁用改派及复制司机 H5 链接口径。" updated_at: "2026-07-26T03:32:07.805Z" base: "dev-v3" --- # 车务:已派车恢复改派与行程单入口更正 > **服务**: `hl-fleet-service` > > **工单**: [wx/HL#5255](https://git.1814.love:8443/wx/HL/issues/5255) > > **后端 PR**: [wx/HL#5258](https://git.1814.love:8443/wx/HL/pulls/5258) > > **影响范围**: 车务管理 → 派单看板操作区、既有派车/改派弹窗、行程单打印入口 ## 关键变化 - 当前有效派单状态为 `assigned` 时,派单看板列表现在返回 `canAssign=true`,并继续下发 `CHANGE_ASSIGNMENT`。车辆已经配好后,只要派单尚未进入 `completed/canceled` 终态,车务仍可 随时进入既有改派流程,再次更换当前车辆槽位的车辆、司机或两者。 - `holding/holding_urgent` 的改派能力不变;`completed/canceled` 继续不可改派。 - 看板操作区的行程单入口统一为“打印行程单”,直接复用订单详情已有的 `PrintItineraryModal.vue` 和 `getPrintItinerary(orderId)`,不新写打印组件、打印接口或打印数据模型。 ## ⚠️ 对 #5186 的口径更正 本文件取代 `23_5186_排车中订单恢复派车派人入口-修改接口-管理后台.md` 中的以下两项旧交接: 1. #5186 响应矩阵把 `assigned` 与终态一起写成 `canAssign=false`。该口径已失效: `assigned` 现在允许改派,只有 `completed/canceled` 禁止改派。 2. #5186 要求看板复制 `currentAssignment.itineraryUrl`,并明确“不复用 `PrintItineraryModal.vue`”。该口径已撤销:看板不再把“复制司机 H5 链接”作为本入口的实现, 而是直接复用订单详情现有打印代码。 #5186 中与本次两项更正无关的候选上下文、稳定槽位和待确认流程说明继续有效。本次也不删除后端 司机 H5 短链能力;只是看板这个用户入口不再消费它。 ## 变更接口 | 方法 | 路径 | 本次口径 | | --- | --- | --- | | `GET` | `/admin/fleet/board/orders` | 既有字段语义更正:有效 `assigned` 记录返回 `canAssign=true`,且 `availableActionCodes` 包含 `CHANGE_ASSIGNMENT` | | `POST` | `/admin/fleet/assignments//change` | 既有改派接口,路径和请求/响应契约不变;继续按稳定车辆槽位与生效日原子替换 | | `GET` | `/v3/admin/order//print-itinerary` | 订单详情已有打印接口,本次无后端变更;看板直接复用现有前端调用 | ## 1. 派单看板动作语义 `GET /admin/fleet/board/orders` 的字段名、类型和必填性均未变化。前端按后端动作字段渲染: | `assignmentStatus` | `canAssign` | `availableActionCodes` | 看板主操作 | | --- | ---: | --- | --- | | `unassigned/unassigned_urgent` | `true` | 包含 `ASSIGN` | “派车派人”,进入既有首次派车流程 | | `holding/holding_urgent` | `true` | 包含 `CHANGE_ASSIGNMENT` | “改派”,进入既有改派流程 | | `assigned` | `true` | 包含 `CHANGE_ASSIGNMENT` | “改派”,已配车后仍可再次调整 | | `completed/canceled` | `false` | 不包含 `CHANGE_ASSIGNMENT` | 不显示改派入口 | 前端不得再把“已有车辆/司机”或 `assignmentStatus === 'assigned'` 当作隐藏改派按钮的条件。 入口首先以 `canAssign === true` 判断是否可进入,再以 `availableActionCodes` 区分首次派车或改派。 ## 2. 继续复用既有按槽位改派 点击“改派”后继续使用当前派车弹窗和现有 `POST /admin/fleet/assignments//change`: - `assignmentId` 取用户选中的 `activeAssignments[]` 派车组/槽位,不得固定取代表项后误改其它车; - 生效日及之后只替换该稳定 `assignmentSlotId` 的逐日切片; - 同一订单其它车辆槽位保持不变; - 可只换车辆、只换司机或同时替换; - 成功后重新拉取看板列表与详情,不缓存旧的 `canAssign`、动作码或派车组数据; - 后端返回 `ORDER_HAS_OTHER_VEHICLES` 等既有警告时继续沿用当前强提示。 本次没有新增写接口,也没有修改改派请求字段、错误码或事务规则。 ## 3. 行程单入口直接复用订单详情打印代码 管理后台现有可复用实现位于: - `src/views/order-v2/detail/modals/PrintItineraryModal.vue` - `src/api/orderV2.js` 的 `getPrintItinerary(orderId)` - 既有接口 `GET /v3/admin/order//print-itinerary` 看板按以下方式接入: - 操作文案统一为“打印行程单”,点击后把当前订单的字符串 `orderId` 传给现有 `PrintItineraryModal`; - 打印预览、加载、错误提示、页面排版和打印动作全部沿用订单详情现有组件; - 可抽取共享挂载点或直接复用组件,但不得复制组件源码形成第二套打印实现; - 不新增 fleet 打印 API,不在前端重新组装行程节点、费用、住宿、大交通或每日行程; - 不调用看板详情去读取 `currentAssignment.itineraryUrl`,不执行剪贴板复制,也不继续使用 `ItinerarySendSheet.vue` 承载这个入口; - 无 `orderId` 时不打开弹窗、不提示成功,沿用现有缺少订单上下文的错误态。 ## 前端展示矩阵 | 页面区域 | 展示内容 | 数据来源 | 包含/排除状态 | 空数据表现 | 标签与颜色 | 守恒规则 | | --- | --- | --- | --- | --- | --- | --- | | 派车看板操作区 | 派车派人 | `availableActionCodes` 含 `ASSIGN` | 包含待派车;排除终态 | 无候选沿用现有提示 | 沿用现有待派状态色 | 只创建目标槽位 | | 派车看板操作区 | 改派 | `availableActionCodes` 含 `CHANGE_ASSIGNMENT` | 包含待确认;排除终态 | 无有效派单不显示 | 沿用现有待确认状态色 | 只替换选中槽位 | | 派车看板操作区 | 改派 | `canAssign=true` 且含 `CHANGE_ASSIGNMENT` | 包含已派车且未完结;排除已完结/已取消 | 无剩余可改服务日时展示既有后端错误 | 沿用现有已派状态色 | 配完仍可再次改派,其他槽位不变 | | 派车看板操作区 | 不显示改派 | 无 `CHANGE_ASSIGNMENT` | 仅已完结/已取消 | 不展示按钮 | 沿用终态灰 | 不恢复终态 | | 派车看板操作区 | 打印行程单 | 订单 `orderId` 与既有打印接口 | 包含可查看订单;排除无订单 ID | 沿用现有打印弹窗加载/错误态 | 沿用现有打印按钮样式 | 只复用一套 `PrintItineraryModal.vue` | ## 前端处理清单 - [ ] `assigned + canAssign=true + CHANGE_ASSIGNMENT` 显示“改派”,点击进入既有改派流程。 - [ ] `holding/holding_urgent` 继续显示“改派”,首次待派仍显示“派车派人”。 - [ ] `completed/canceled` 不显示改派入口。 - [ ] 用户选择哪个 `activeAssignments[]` 槽位,就把该槽位的 `assignmentId` 传给既有 change 接口。 - [ ] 改派成功后刷新列表与详情,当前槽位更新,其他槽位数量和身份保持不变。 - [ ] 将看板行程单操作统一为“打印行程单”,直接复用订单详情 `PrintItineraryModal.vue + getPrintItinerary(orderId)`。 - [ ] 不新增打印组件/API,不读取或复制 `currentAssignment.itineraryUrl`,不继续使用 `ItinerarySendSheet.vue` 实现该入口。 - [ ] 覆盖无订单 ID、打印接口失败和打印数据空态,全部沿用既有打印弹窗行为。 ## 验证证据 - 后端提交:`9ea7d555a078101cbf57d1571d106cd0ec2863af`;PR #5258。 - `BoardControllerTest + BoardOrderServiceTest` 共 54 项通过。 - `AssignmentServiceTest#change_directFromEffectiveDate_replacesDailySlicesAndWarnsOtherVehicle` 通过,验证只替换目标稳定槽位,其它车辆槽位不取消。 - `mvn -pl hl-fleet-service spotless:check` 通过。 - `mvn -pl hl-fleet-service -am verify` 通过;fleet 207 套件、2,373 项测试, 0 失败、0 错误、1 个既有跳过。 - 测试环境已滚动部署 `hl-fleet-service`;Nacos `test` 命名空间的 8087、8187 两实例健康。 - 测试网关查询 `assigned` 返回 4 条真实记录,全部为 `canAssign=true + CHANGE_ASSIGNMENT`,HTTP/code 均为 200。 - 测试环境当时没有 `holding/holding_urgent/completed/canceled` 样本;这些状态不冒充网关实测, 由已通过的服务状态矩阵与 Controller JSON 测试覆盖。 - 网关证据 SHA-256: `1409d22ce9fc2c86101d9f811fef867e0493f177191fb8ac5ee30eb4427185e2`。 - OpenAPI/oasdiff:`not_configured`。字段名、类型和 requiredness 未变;仓库没有可复现的 Swagger2 → OAS3 导出链且未安装 `oasdiff`,已用 Controller JSON、服务状态矩阵和当前 `hl-ui` 消费源码做人工回退核对。 - 消费者契约/Spring Cloud Contract:`not_required`。本次没有内部 Feign 或共享 Java DTO 变化。 ## 不影响范围 - 不修改或部署 `D:/work2/hl-ui`;`frontend_status` 保持 `pending`,页面实现和发布独立流转。 - 不删除司机 H5 行程短链、签名 token 或公开行程接口;仅更正看板入口的前端消费方式。 - 不新增/删除 API 字段,不改变字段类型、必填性、错误码或雪花 ID 的字符串消费要求。 - 不修改首次派车、待确认推进、取消派单、司机确认、资源占用或通知冻结规则。 - 不新增 DDL,不迁移、清理或回填数据。