hl-api-changelog/changelogs-v2/2026-08/11_5824_换版后看板缺口与订单车控修复-修改接口-管理后台.md
Mimingguang 63fd34d7fd
所有检测均成功
changelog-filename-gate / validate (push) Successful in 1s
chore(changelog): #5824 前端 implemented(aa9c087b)
2026-08-11 15:39:03 +08:00

13 KiB

schema, ticket, title, consumer, change_type, author, 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 author backend_status gateway_status frontend_status frontend_owner frontend_ref target_release verified_at status_note updated_at base
hl-changelog/v2 5824 换版后看板缺口消失 / 订单车控误标 DONE 修复assignmentProgress 新增 staleFinalizedPlan,finalizedByFleet 语义收窄为「已对当前用车需求定稿」 admin 修改接口 wx(GIT) deployed not_required implemented mmg aa9c087b 2026-08-11 后端 PR #5843 已合并 dev-v3 并部署测试服,26-5067 双出口实测通过。前端已实现(aa9c087b)BoardSlotSummary 在 assignmentProgress.staleFinalizedPlan===true 时头部挂「需求已换版 · 请核对车型与数量」warning 轻提示(严格 === true,旧契约缺省不误亮,不做按钮禁用)。其余 checklist 实证零改动——finalizedByFleet 前端零消费;「已派几台车」boardSummary 已走 assignmentProgress.assignedSlots/totalSlots 不数 assignmentSlots;CANCELED 槽位渲染层已按 assignmentStatus 区分(display.js canceled 态样式 + OrderDrawer 着色与短信/费用编辑排除);待派车 tab 记录级状态由后端驱动。测试:board-slot-summary 10/10(新增 3 分支用例),fleet 全域 66 文件 619 用例全绿,checkpoint light 全过。 2026-08-11 dev-v3

车务看板:换版后缺口重新露出 + 订单车控不再误标完成(#5824

服务: hl-fleet-service 日期: 2026-08-11 含 Flyway: 20260811.005fleet_assignment 新增 plan_finalized_requirement_id 定稿归属列) 无新增端点 · 无字段删除 · 无请求参数变化 · 无需改网关路由


背景(一句话)

#5810 换版整槽平移只改派单行的 requirement_id,「已定稿」标记原样保留,于是上一版需求的定稿被当成当前版需求的定稿 看板把缺口整体抹平(多要的车看不见),订单侧还会据此回发最终方案把车控标成已完成(实测 26-5067 少 1 台车仍 DONE。 本次给定稿加上「归属哪一版需求」的证据,读侧据此区分「当代定稿」与「换版平移来的陈旧定稿」,修两个出口: ①看板缺口重新露出下文「变更接口」;②订单车控不再误标完成下文「订单车控状态order-v3 侧)」)。


变更接口

GET /admin/fleet/board/orders —— assignmentProgress 结构变化

1. 新增字段 staleFinalizedPlanBoolean,恒非 null

取值 含义
true 该需求名下存在任一非终态派单行携带「上一版需求的定稿」:换版后旧派单被整槽平移过来,车务尚未对这些行按当前需求重新定稿。判据是析取——当代定稿行与陈旧定稿行并存(例如部分槽已按新需求重新确认、部分槽仍是平移过来的旧定稿)时同样为 true,不要求「只剩」旧定稿
false 全部定稿行都归属当前需求(当代定稿)/ 未定稿 / 历史存量行无归属证据(新列上线前的行,按兼容口径视同当代)/ 携带陈旧归属的行已是终态canceledcompleted 一律豁免,不判 true

终态豁免的原因:改派与按天改派只把行置为 canceled、不清定稿标记,完结行同理不会再被刷进新方案; 不豁免就会让这些永远动不了的历史行把需求永久钉成「陈旧」(看板永久缺口提示、订单车控永久卡处理中)。

它只是提示,不一定改判:只有 staleFinalizedPlan=true 且确有缺口suggestedSlots > 现有槽位数)时才撤销定稿权威。 换版只改车型或人数、车数没变时V1 商务车×1 → V2 SUV×1,本字段仍为 true,但计数与卡片状态一律不动—— 车型/数量不符按 #5810 已定口径只做提示、不做门禁。

前端建议staleFinalizedPlan=true 时在卡片上挂一个「需求已换版,请核对车型与数量」的轻提示,配合已有的 requirementFleetText(当前需求车队组成语句)让车管一眼比对。不要用它做任何按钮禁用。

2. finalizedByFleet 语义收窄

旧语义 新语义
finalizedByFleet=true 车务已提交最终实派方案(不区分是哪一版需求的方案) 车务已对当前用车需求提交最终实派方案

只有当「陈旧定稿 + 确有缺口」同时成立时,finalizedByFleet 才由旧口径的 true 变成 false。 其余场景取值不变(含少派:车务对当前需求定稿后少派也仍是 true,缺口按实派守恒不再报)。

3. staleFinalizedPlan=true 且有缺口时的具体变化

以「V1 商务车×1 已定稿并派车 → 换版为 V2 SUV×2」为例suggestedSlots=2,现有 1 个槽位):

字段 修复前 修复后
finalizedByFleet true(按上一版定稿) false
staleFinalizedPlan 无此字段 true
totalSlots 1(按实派守恒) 2(按当前需求估算)
unassignedSlots 0(缺口被抹平) 1(缺口露出)
canceledSlots 0(定稿分支恒 0 按实际取消槽位数返回(可 > 0
记录级 assignmentStatus assigned unassigned(当天/临近出发则 unassigned_urgent

卡片会换 tab:这类订单从「已派车」跳到「待派车」(临近出发进急单组)。这是本次修复的目的—— 车管必须在待派车里看到它,否则新需求多要的那台车永远没人补。

statusCounts 与列表条数同源一致summary.statusCountsstatusOptions/orders 列表用的是同一份记录级派生态, 「tab 上有 N 条 → 点进去就是 N 条」这一保证在本次改动后仍然成立(已加回归用例锁定)。

4. ⚠️ 破坏性提醒:assignmentSlots 会包含 CANCELED 槽位

assignmentSlots 原本在 finalizedByFleet=true 时会过滤掉已取消的槽位。 由于本次「陈旧定稿 + 有缺口」会把 finalizedByFleet 置为 false这类卡片的 assignmentSlots 里会重新出现 baseAssignmentStatus=canceled / assignmentStatus=canceled 的槽位(该需求下整槽被取消的历史槽位; 该需求没有整槽取消历史时列表内容不变)。

前端必须按槽位状态区分渲染:不要假设 assignmentSlots 只含活跃槽位;已取消槽位应置灰或折叠, 不要计入「已派几台车」的展示口径(改用 assignmentProgressassignedSlots/totalSlots)。 这类槽位的 availableActionCodes 为空、canAssign=false,点不动,但会占版面。


GET /admin/fleet/board/summary —— 口径变化(字段结构不变)

字段 变化
todayDepartCount 「今日出团」只数「今天出发 且记录级已派车」。陈旧定稿且缺口的卡片记录级已被改判为待派车,不再计入本数
pendingCount / pendingUrgentCount 上述卡片改由这两个数体现(今天出发必然落在 unassigned_urgent
statusCounts.unassigned / .assigned 随记录级派生态同步变化,与 /orders 列表同源

口径理由:车还没配齐,算作「已派车出团」会让当天出团数虚高、车管漏配车。


订单车控状态order-v3 侧,定制师页面可见)

本工单修的是两个出口,上面是看板(出口①),这里是订单车控(出口②)。无接口结构变化 fleet 不新增/修改端点,变的是 order-v3 既有字段 vehicle_control_status 的推进时机。

触发条件(两个条件必须同时成立,与看板同一份「陈旧」行级判据):

  1. 该需求下存在任一非终态派单行携带上一版需求的定稿(终态行同样豁免);
  2. 当前需求车数 > 现有非取消槽位数(订单侧刻意排除已取消槽位——取消掉的槽位不是交付出去的车, 与看板按槽位视图计数略有差异,这里统一取更保守的一侧,宁可判未完成也不误报完成)。

结果对比

修复前 修复后
车务确认后的满派判定 按「上一版定稿即权威」判已满派(该分支刻意不比对需求车数) 退回常规拓扑校验,按当前需求的车数 × 服务日核对,缺车即未满派
是否回发 DAILY_V3 最终方案 回发 不回发
订单 vehicle_control_status 被标 DONE(定制师页面显示派车已完成,实际少一台车,实测 26-5067 停在处理中(PROCESSING),定制师页面继续显示派车进行中

恢复方式:车务在看板对当前需求重新提交/确认最终方案即可自动恢复——确认时定稿归属会被盖章成当前需求 ID, 陈旧判据随即失效,满派后照常回发最终方案、车控回到 DONE。无需人工改库,也不需要运维介入。

只陈旧不缺车不改判:车数没变的换版(只改车型/人数)仍按定稿权威判已满派,车控照常推进到 DONE, 与看板「只提示不改判」保持同一口径。


详情端点说明(无变化)

GET /admin/fleet/board/orders/{orderId} 不返回 assignmentProgress,因此也没有 staleFinalizedPlan。 详情页已有等价且更可操作的信息:requirementFleetText(当前需求车队组成)+ suggestedVehicleCount(需求车数)

  • actualVehicleCount(实派槽位数)。由于本次改判只在「确有缺口」时发生,凡列表把卡片挪进待派车的订单, 详情页必然满足 suggestedVehicleCount > actualVehicleCount,两处不会互相矛盾。


验证证据

测试服(hl-fleet-service 部署于 2026-08-11 14:44,含 PR #5843 合并提交 6789811ea),实测订单 26-5067HL20260809095538772)。

该单需求 V1 mpv×1(已派 1 台并定稿)→ V2 suv×2,属于典型「换版后车数变多」场景。

存量回填

Flyway 20260811.005 执行后,该单派单行 plan_finalized_requirement_id 精确回填为 V1 的 requirement_id,与行上当前 requirement_id 不等 → 判定为陈旧定稿。真库统计17 行活跃定稿中 12 行可由确认回执精确反查,其中仅 1 行为真陈旧(即本单),其余存量归属 = 当前需求或留 NULL兼容档,状态无跳变。

出口①:看板缺口重新露出

GET /admin/fleet/board/orders?keyword=26-5067 实际返回:

"assignmentProgress": {
  "totalSlots": 2, "suggestedSlots": 2,
  "finalizedByFleet": false, "staleFinalizedPlan": true,
  "unassignedSlots": 1, "holdingSlots": 0, "assignedSlots": 1,
  "completedSlots": 0, "canceledSlots": 0
}
  • 记录级状态 unassigned / 「待派车」(修复前为 assigned「已派车」)
  • tab 计数与列表条数一致:statuses=unassigned → 1 条;statuses=assigned → 0 条
  • 与订单侧「部分回配 (1/2)」口径对齐

出口②:订单车控不再误标完成

在测试服对该单再提交一次换版V3 suv×2,车数不变仍缺 1 台)实测:

修复前V2 换版时) 修复后V3 换版时)
fleet 行 requirement_id 平移到新需求 平移到新需求(一致)
plan_finalized_requirement_id 无此列 仍为 V1 → 陈旧
是否回发 DAILY_V3 最终方案
order_main.vehicle_control_status DONE(缺 1 台车却判完成) PENDING

门禁与测试

  • 受影响 6 个测试类 666/666 全绿;FleetRedLineArchTest 12/12;spotless:check 通过
  • 全量 3505 用例,剩余失败均为环境相关且已在干净 origin/dev-v3 基线复现Testcontainers 并发起容器失败、ReleaseE-Dfleet.mysql.releaseE.finalMigrationSha256 系统属性),低负载单独重跑 32/32 通过

已知取舍

statuses=[unassigned](含 unassigned_urgent)筛选时,后端为了不漏掉「落库态是 assigned/holding、 但记录级会被改判成待派车」的卡片,会把 DB 候选集扩到 unassigned + holding + assigned 再在内存精筛。 副作用:该筛选条件下扫描量变大,更容易触发 5000 条安全上限(触发后走游标扫描,或提示「请增加日期或关键词条件」)。 不带状态筛选的默认首屏不受影响(本来就查全状态)。


前端 checklist

  • assignmentProgress.staleFinalizedPlan=true 时展示换版核对提示(不做按钮禁用)
  • 不再假设 finalizedByFleet=true 等于「有过最终方案」,语义已收窄为「对当前需求定稿」
  • assignmentSlotsassignmentStatus 区分渲染,容忍 canceled 槽位出现
  • 「已派几台车」一律取 assignmentProgress,不要自己数 assignmentSlots 长度
  • 待派车 tab 会新增这类换版订单,确认列表/角标/急单分组渲染正常