changelogs-v2: 派单 Step2 下一步多日行程被误拦——前端缺陷根因与修复指引(#5849)
所有检测均成功
changelog-filename-gate / validate (push) Successful in 2s

这个提交包含在:
API Changelog Bot 2026-08-12 13:39:55 +08:00
父节点 1aeb52b8cd
当前提交 de40c74d73

查看文件

@ -0,0 +1,78 @@
---
schema: "hl-changelog/v2"
ticket: "frontend"
title: "派单 Step2「下一步」多日行程被误拦候选证据只支持单日,多日每格判「未通过候选校验」置灰"
consumer: "admin"
change_type: "前端缺陷"
author: "wx(GIT)"
backend_status: "not_required"
gateway_status: "not_required"
frontend_status: "pending"
frontend_owner: "mmg"
frontend_ref: ""
target_release: ""
verified_at: ""
status_note: "后端零改动。后端提交校验口径已满足业务要求(工单 #5849):车型/座位/数量与当前需求不符不拦截、降级为提示AssignmentService.java:3038 创建链、assertFinalConfirmationBaseline:4676 baseline 均已定稿,#5810/#5824 一脉;真实资源冲突与日期越窗仍为硬拦605001/605003/605062,该保留。26-5067 被卡的根因在前端useVehicleDriverPicker.js 的 candidateServiceDate 只在 startDate===endDate单日行程才返回日期,多日行程返回空串 → candidateEvidence 为 null → daily-vehicle-plan.js 的 dailyVehiclePlanCandidateEvidenceMatches 要求 evidence.serviceDate===cell.serviceDate 永不匹配 → 每个用车日格都判「未通过候选校验」→ 槽位 selectionReady=false → 「已完成 0/1」、按钮置灰。后端候选接口已返回 availabilityWindows按请求日期范围扣除阻断冲突后的可用窗口,数据足够前端判断「车/司机覆盖整个服务期」,无需新增接口。"
updated_at: "2026-08-12"
base: "dev-v3"
---
# 派单 Step2「下一步」多日行程被误拦#5849,前端修复)
> **页面**:车务管理 → 派单看板 → 订单派车弹窗 → Step2「排车」→「下一步 · 发送给司机」按钮
> **后端**:本条**零改动**。后端口径已满足,根因在前端候选证据只支持单日。
> **业务口径**wx 2026-08-11,#5849):只要槽位有车+有司机、且日期在行程窗内,就可以下一步;定制师换版改需求不等于车务必须改派车。
---
## 一、现象
订单 26-5067三日行程 08/20~08/22车辆槽位 1 已有车蒙A-E5555+司机(阿木古愣),三天全部「已规划用车」、日历价派车价都填了,但仍被拦——
- 8月21日 行挂橙条「2026-08-21 车辆槽位1 尚未通过当前日期、车辆和司机的候选校验」
- 底部「已完成 **0/1** 个最终方案槽位」
- 「下一步 · 发送给司机1 辆)」按钮置灰
## 二、根因(前端)
按钮置灰链路:`AssignModalFooter.vue:108` `:disabled="!selectionReady"``AssignModal.vue:2401-2416` `syncSlotCompletion``slot.selectionReady = cells.every(isDailyVehiclePlanCellComplete)``daily-vehicle-plan.js:571-577` 要求每格 `dailyVehiclePlanCandidateEvidenceMatches(cell)` ← 该函数要求 `evidence.serviceDate === cell.serviceDate`
而证据来源 `useVehicleDriverPicker.js:68-71`
```js
function candidateServiceDate(order = {}) {
const startDate = String(order.startDate || '')
return startDate && startDate === String(order.endDate || '') ? startDate : ''
}
```
**只在单日行程返回日期,多日行程返回空串** → `candidateEvidence``useVehicleDriverPicker.js:313-323`)为 `null``dailyVehiclePlanCandidateEvidenceMatches` 永不匹配 → 多日行程下每个用车日格都判「未通过候选校验」→ 整槽 selectionReady=false → 0/1、置灰。
单日行程不触发此 bugserviceDate 非空、能匹配),所以只在多日行程复发。
## 三、后端口径现状(已满足,勿再拦)
后端提交链对「车型/座位/数量与当前需求不符」**已经不拦截**,与 #5810/#5824 一脉:
- `AssignmentService.java:3038`:「车型与座位差异不再阻断:车务可按现场调度选择任意车辆,候选接口返回匹配标记供醒目提示」
- `assertFinalConfirmationBaseline``AssignmentService.java:4676-4680`):「车型/数量/人数不符一律不拦截、降级为看板提示语句,日期是唯一硬门禁」
- 候选接口 `requirementMatched`/`requirementMismatchReasonCode`/`requirementMismatchMessage` 只作提示,不影响 `selectable`
**必须保留的硬拦**(前端不要用候选证据把它们也放行):真实资源冲突(同车/同司机同日被别单占用,605001/605003、资源状态不可用维保/停用/休假/黑名单,605037/605038/605006/605013、跨常驻未确认605014、日期越出行程窗605062
**前端可用的数据**:候选接口每个车辆/司机候选已返回 `availabilityWindows`(按请求日期范围扣除阻断冲突后的可用窗口区间列表)+ `selectable`。前端据此即可判断「车/司机组合覆盖整个服务期且无阻断冲突」,无需新增接口。
## 四、前端修复点mmg
1. **`useVehicleDriverPicker.js:68-71` `candidateServiceDate`**:多日/整段行程也要能给出证据日期范围。建议返回 `{ startDate, endDate }` 或服务期日期列表,而非单日或空串。
2. **`useVehicleDriverPicker.js:313-323` `candidateEvidence`**:证据携带服务期(起止日期或日期数组),不再只带单日 `serviceDate`
3. **`daily-vehicle-plan.js:81-90` `dailyVehiclePlanCandidateEvidenceMatches`**:匹配口径由「`evidence.serviceDate === cell.serviceDate`」放宽为「`cell.serviceDate` 落在证据服务期范围内」(车/司机/跨常驻确认仍精确比对)。
4. **`daily-vehicle-plan.js:443-466` `isDailyVehiclePlanCellComplete``AssignModal.vue:2401-2416` `syncSlotCompletion`**:完成口径对齐业务口径——槽位内所有服务日已决策(用车/不用车)、用车日有车+司机、价格/跨常驻合规、候选证据覆盖整个服务期,即视为完成、可下一步。已 finalized 的只读行保持 `preservedFinalized` 短路。
5. 完成度文案「已完成 N/M 个最终方案槽位」随之正确(不再「三天已规划却 0/1」
## 五、验收
- 多日行程≥2 天)下:槽位有车+有司机+日期在行程窗内 → 「下一步」可点,不再被「候选校验」误拦
- 车型/座位/数量与当前需求不符 → 只提示不拦
- 真实资源冲突 / 日期越出行程窗 → 仍硬拦(沿用候选接口 selectable/availabilityWindows 的阻断冲突判定)
- 「已完成 N/M」口径与放宽后一致