changelog(#5824): 换版后看板缺口与订单车控修复——测试服实测通过(PR #5843)
所有检测均成功
changelog-filename-gate / validate (push) Successful in 2s
所有检测均成功
changelog-filename-gate / validate (push) Successful in 2s
这个提交包含在:
父节点
1c022e7943
当前提交
76c446312b
@ -0,0 +1,209 @@
|
||||
---
|
||||
schema: "hl-changelog/v2"
|
||||
ticket: "5824"
|
||||
title: "换版后看板缺口消失 / 订单车控误标 DONE 修复:assignmentProgress 新增 staleFinalizedPlan,finalizedByFleet 语义收窄为「已对当前用车需求定稿」"
|
||||
consumer: "admin"
|
||||
change_type: "修改接口"
|
||||
author: "wx(GIT)"
|
||||
backend_status: "deployed"
|
||||
gateway_status: "not_required"
|
||||
frontend_status: "pending"
|
||||
frontend_owner: "mmg"
|
||||
frontend_ref: ""
|
||||
target_release: ""
|
||||
verified_at: "2026-08-11"
|
||||
status_note: "后端 PR #5843 已合并 dev-v3 并部署测试服,26-5067 双出口实测通过;前端待接 staleFinalizedPlan 提示与 CANCELED 槽位区分渲染。"
|
||||
updated_at: "2026-08-11"
|
||||
base: "dev-v3"
|
||||
---
|
||||
|
||||
# 车务看板:换版后缺口重新露出 + 订单车控不再误标完成(#5824)
|
||||
|
||||
> **服务**: hl-fleet-service
|
||||
> **日期**: 2026-08-11
|
||||
> **含 Flyway**: `20260811.005`(`fleet_assignment` 新增 `plan_finalized_requirement_id` 定稿归属列)
|
||||
> **无新增端点 · 无字段删除 · 无请求参数变化 · 无需改网关路由**
|
||||
|
||||
---
|
||||
|
||||
## 背景(一句话)
|
||||
|
||||
`#5810` 换版整槽平移只改派单行的 `requirement_id`,「已定稿」标记原样保留,于是**上一版需求的定稿被当成当前版需求的定稿**:
|
||||
看板把缺口整体抹平(多要的车看不见),订单侧还会据此回发最终方案把车控标成已完成(实测 26-5067 少 1 台车仍 DONE)。
|
||||
本次给定稿加上「归属哪一版需求」的证据,读侧据此区分「当代定稿」与「换版平移来的陈旧定稿」,修两个出口:
|
||||
①看板缺口重新露出(下文「变更接口」);②订单车控不再误标完成(下文「订单车控状态(order-v3 侧)」)。
|
||||
|
||||
---
|
||||
|
||||
## 变更接口
|
||||
|
||||
### `GET /admin/fleet/board/orders` —— `assignmentProgress` 结构变化
|
||||
|
||||
#### 1. 新增字段 `staleFinalizedPlan`(Boolean,恒非 null)
|
||||
|
||||
| 取值 | 含义 |
|
||||
|---|---|
|
||||
| `true` | 该需求名下**存在任一非终态派单行携带「上一版需求的定稿」**:换版后旧派单被整槽平移过来,车务尚未对这些行按当前需求重新定稿。判据是**析取**——当代定稿行与陈旧定稿行并存(例如部分槽已按新需求重新确认、部分槽仍是平移过来的旧定稿)时同样为 `true`,不要求「只剩」旧定稿 |
|
||||
| `false` | 全部定稿行都归属当前需求(当代定稿)/ 未定稿 / 历史存量行无归属证据(新列上线前的行,按兼容口径视同当代)/ **携带陈旧归属的行已是终态**(`canceled`、`completed` 一律豁免,不判 `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.statusCounts`、`statusOptions` 与 `/orders` 列表用的是同一份记录级派生态,
|
||||
「tab 上有 N 条 → 点进去就是 N 条」这一保证在本次改动后仍然成立(已加回归用例锁定)。
|
||||
|
||||
#### 4. ⚠️ 破坏性提醒:`assignmentSlots` 会包含 `CANCELED` 槽位
|
||||
|
||||
`assignmentSlots` 原本在 `finalizedByFleet=true` 时会过滤掉已取消的槽位。
|
||||
由于本次「陈旧定稿 + 有缺口」会把 `finalizedByFleet` 置为 `false`,**这类卡片的 `assignmentSlots` 里会重新出现
|
||||
`baseAssignmentStatus=canceled` / `assignmentStatus=canceled` 的槽位**(该需求下整槽被取消的历史槽位;
|
||||
该需求没有整槽取消历史时列表内容不变)。
|
||||
|
||||
**前端必须按槽位状态区分渲染**:不要假设 `assignmentSlots` 只含活跃槽位;已取消槽位应置灰或折叠,
|
||||
不要计入「已派几台车」的展示口径(改用 `assignmentProgress` 的 `assignedSlots`/`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-5067**(`HL20260809095538772`)。
|
||||
|
||||
该单需求 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` 实际返回:
|
||||
|
||||
```json
|
||||
"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` 等于「有过最终方案」,语义已收窄为「对当前需求定稿」
|
||||
- [ ] `assignmentSlots` 按 `assignmentStatus` 区分渲染,容忍 `canceled` 槽位出现
|
||||
- [ ] 「已派几台车」一律取 `assignmentProgress`,不要自己数 `assignmentSlots` 长度
|
||||
- [ ] 待派车 tab 会新增这类换版订单,确认列表/角标/急单分组渲染正常
|
||||
正在加载...
x
在新工单中引用
屏蔽一个用户