---
schema: "hl-changelog/v2"
ticket: "5870"
title: "看板详情 vehicleSlots 新增展示序号 slotDisplayNo + 候选车辆新增需求不匹配原因字段"
consumer: "admin"
change_type: "修改接口"
author: "wx(GIT)"
backend_status: "deployed"
gateway_status: "verified"
frontend_status: "implemented"
frontend_owner: "mmg"
frontend_ref: "b9b17dbf"
target_release: ""
verified_at: "2026-08-12"
status_note: "后端已修复并部署测试服，API 实测通过。(1) #5870 项8：详情端点 `/admin/fleet/board/orders/{orderId}` 的 vehicleSlots 每条新增 slotDisplayNo（1 起，当前有效槽位按 fleetItemIndex 升序位次，删除意图槽过滤不占编号；换版保留行 superseded 尾部追加 slotDisplayNo=null）。实测订单 HL20260811204009314：活跃 idx1 + 已删意图 idx2 + canceled idx0 → vehicleSlots 返回 displayNo=1,2，删除意图槽不占位。(2) #5871 项6：候选接口 `/admin/fleet/assignments/candidates` 车辆候选项新增 requirementMismatchReasonCode（VEHICLE_TYPE/SEATS/VEHICLE_TYPE_AND_SEATS，匹配时 null）+ requirementMismatchMessage（后端直出中文指明本槽位需求，如「本槽位需求为商务车7座，该车为SUV」）。实测订单 HL20260811205737244（需求 mpv×2）：11 台 SUV/大巴 mismatch 车辆 reasonCode=VEHICLE_TYPE 且文案指明本槽位需求，大巴正确识别「大巴客车」。前端 2026-08-12 已接入并交付：①详情/列表槽位「车辆槽位 N」改读 slotDisplayNo（构建侧 batchAssignmentSlots+daily-vehicle-plan 透传，6 处展示点统一走 display.js resolveSlotDisplayNo，兜底 fleetItemIndex+1→列表位次）；②候选「需求不匹配」标签改读 requirementMismatchMessage（VehiclePickerList 两处 NTag，兜底「需求不匹配」，只提示不阻断），reasonCode 仅透传未用。fleet/board 35 文件 421 用例全绿，checkpoint 含生产构建全过。"
updated_at: "2026-08-12"
base: "dev-v3"
---

# 看板详情展示序号 + 候选需求不匹配原因（#5870 项8 / #5871 项6，PR #5908 + #5909）

> **服务**: hl-fleet-service
> **PR**: #5908（候选 mismatch 字段 + Step2 多车型建槽定位）+ #5909（详情端点 slotDisplayNo 补齐）
> **日期**: 2026-08-12
> **背景**: #5893 按等价实现修了 #5870/#5871 核心缺陷，但两个契约字段按工单方案原文应下发而未落地。本批补全兑现，全部为**新增响应字段，向后兼容，无破坏性变更**。

---

## 一、变更接口

| 方法 | 路径 | 变更 |
|------|------|------|
| `GET` | `/admin/fleet/board/orders/{orderId}` | `vehicleSlots[]` 新增 `slotDisplayNo` 字段 |
| `GET` | `/admin/fleet/board/orders` | `assignmentSlots[]` 新增 `slotDisplayNo` 字段（列表端点同步） |
| `POST` | `/admin/fleet/assignments/candidates` | 车辆候选项新增 `requirementMismatchReasonCode` / `requirementMismatchMessage` |

---

## 二、#5870 项 8：看板详情展示序号 slotDisplayNo

### 为什么改

前端「车辆槽位 N」此前用 `fleetItemIndex + 1` 本地计算。删槽-加槽后 fleetItemIndex 走「最小空缺复用」，身份序号与展示位次会劈叉；前端加/删槽的乐观更新与刷新竞态还会出现跳号/重号。必须由后端统一下发与身份序号解耦的展示序号。

### 契约字段

| 字段 | 类型 | 说明 |
|------|------|------|
| `slotDisplayNo` | `Integer` | 当前有效槽位按 `fleetItemIndex` 升序的展示位次，**1 起**。删除意图命中的槽位被过滤、不占编号；换版保留行（superseded）追加在尾部，`slotDisplayNo=null` 不参与当前编号。详情 `vehicleSlots` 与列表 `assignmentSlots` 同口径下发。 |

### 前端接入

「车辆槽位 N」改读 `slotDisplayNo`（兜底 `fleetItemIndex + 1`）。删除槽位后其余槽位的 `slotDisplayNo` 由后端刷新时重新计算，前端无需本地重排。

---

## 三、#5871 项 6：候选需求不匹配原因

### 为什么改

车型/座位不匹配此前只有 `requirementMatched: false` 裸布尔，前端只能笼统打「需求不匹配」，无法讲清「本槽位到底要什么」。本批让后端直出可直显的维度与文案。

### 契约字段

| 字段 | 类型 | 说明 |
|------|------|------|
| `requirementMismatchReasonCode` | `String` | 不匹配维度：`VEHICLE_TYPE`（车型不符）/ `SEATS`（座位不足）/ `VEHICLE_TYPE_AND_SEATS`（双不符）。`requirementMatched=true` 时为 `null`；槽位需求不可达回退前端传参时也为 `null`（保持「仅提示不限制」）。 |
| `requirementMismatchMessage` | `String` | 后端直出中文文案，指明本槽位需求，如「本槽位需求为商务车7座，该车为SUV」「本槽位需求座位数为7，该车核定座位不足」。匹配或需求不可达时为 `null`。 |

### 与 `selectable` 的关系（务必分清）

车型/座位不匹配**只提示不阻断**：`requirementMatched=false` 不影响 `selectable`，与 #5810 / #5824 / #5849 既定口径一致。前端不应据 mismatch 字段禁用选择。

### 前端接入

候选列表「需求不匹配」标签文案改读 `requirementMismatchMessage`（兜底「不符合本槽位需求」）。

---

## 验证证据（测试服 API 实测）

- **详情 slotDisplayNo**：订单 HL20260811204009314（活跃 idx1 + 删除意图 idx2 + canceled idx0）→ `vehicleSlots` 返回 `slotDisplayNo=1,2`，删除意图槽（idx2）被过滤不占编号，序号连续补位。
- **候选 mismatch 字段**：订单 HL20260811205737244（需求 mpv×2）→ 11 台 SUV/大巴 mismatch 车辆 `requirementMismatchReasonCode=VEHICLE_TYPE`，文案「本槽位需求为商务车7座，该车为SUV」；大巴车正确识别为「大巴客车」（验证 label↔key 闭合）。
