docs(changelog): #8767 出团通知书默认车辆补团车、下发缺项新增 DRIVER / DRIVER_UNAVAILABLE(修改接口·管理后台)+ 车务团车活跃派车行内部读口(新增接口·internal)
changelog-filename-gate / validate (push) Failing after 2s

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
这个提交包含在:
jw
2026-10-04 17:16:16 +08:00
共同撰写人 Claude Opus 5.5
父节点 b4f2e3da14
当前提交 e08991a588
共修改 2 个文件,包含 650 行新增和 0 行删除
@@ -0,0 +1,426 @@
---
schema: "hl-changelog/v2"
ticket: "8767"
title: "出团通知书:默认车辆信息补上团车(整团派车)的车辆与司机,releaseBlockers 新增「车辆未派司机」DRIVER 与「司机信息暂不可用」DRIVER_UNAVAILABLE"
consumer: "admin"
author: "jw(GIT)"
change_type: "修改接口"
backend_status: "deployed"
gateway_status: "verified"
frontend_status: "not_required"
frontend_owner: ""
frontend_ref: ""
target_release: ""
verified_at: ""
status_note: "已合并 dev-v3(PR #8794,merge commit a281744c8)并部署 TEST(order-v3 与 fleet 同为 dev-v3 a281744c8),自签 token 经网关实测:团车团 defaults.bus 与车务派车逐字一致且手机全脱敏;团车有车没派司机时 releasable=false、缺项恰为 DRIVER,补派后恢复;车务服务读不到时缺项为 DRIVER_UNAVAILABLE、接口仍 200;无团车的团读数与部署前逐项一致;判权不变。纯加取值,入参与路径不变;页面按 #8746 约定用 releaseBlockers[].name 展示即可,无需新适配。"
updated_at: "2026-10-04"
base: "dev-v3"
---
# order-v3: 出团通知书默认车辆补团车,下发缺项新增 DRIVER / DRIVER_UNAVAILABLE
**服务**: hl-order-service-v3(读团车经 hl-fleet-service 内部读口,见同日 04_8767 新增接口那份)
**PR**: `#8794`(已合入 `dev-v3`,合并提交 `a281744c8`)
**Issue**: #8767
---
## ⚠️ 关键变化
🔴 **`releasable` 又多一个条件**:在 #8746「阶段 + 四项资源」之上,还要求**团车(整团派车)的车辆都已派司机**。团车有车没派司机的团,`releasable` 由 `true` 变 `false`。
🟢 **`releaseBlockers` 追加两个取值**:`DRIVER`「车辆未派司机」、`DRIVER_UNAVAILABLE`「司机信息暂不可用」,排在 `PHOTOGRAPHER` 之后,二者互斥。
🟢 **默认车辆信息 `defaults.bus` 补上团车**:先列团车,再列逐户派车;格式仍是「车型 车牌 司机 姓名 脱敏手机」。
🟢 入参、路径、判权、错误码全部不变;保存仍然不卡下发门。
---
## 一、背景
#8746 给出团通知书加了「下发门缺项」和「默认车辆带司机」,但只覆盖逐户派车。团车(整团派车)的车辆与司机只在车务服务里,通知书读不到:团车团的默认车辆信息是空的,团车「排了车没排司机」也查不出来——车务那边判团车就绪的硬门不含司机,`vehicle_ready=true` 不代表司机已派。
本单让通知书向车务读团车的活跃派车,补进默认车辆信息,并把「车辆未派司机」加进下发门。
---
## 二、变更接口清单
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|---|------|------|------|----------|------|
| 1 | 读出团通知书 | GET | `/v3/admin/order/group-batch/:groupBatchId/docs/notice` | 修改 | `releaseBlockers` 新增 `DRIVER` / `DRIVER_UNAVAILABLE`;`releasable` 加「团车都已派司机」;`defaults.bus`(及未保存时正文 `bus`)含团车 |
| 2 | 保存出团通知书 | PUT | `/v3/admin/order/group-batch/:groupBatchId/docs/notice` | 修改 | 响应同上 |
---
## 三、接口详情
**`releasable` 规则**(两个接口相同):团期状态是 待出发 / 出行中 / 待核单 / 核单中 / 已结算 之一,**且**配房、配车、配导游、配摄影四项都已完成,**且**团车的车辆都已派司机,才为 `true`。
**`releaseBlockers[]` 取值**(按下表顺序排列,`releasable=true` 时为 `[]`,从不为 `null`):
| key | name | 何时出现 |
|---|---|---|
| `STAGE` | 团期未到待出发 | 团期状态不在上面五个之内(不变) |
| `HOTEL` | 配房未完成 | 已成团且配房未完成(不变) |
| `VEHICLE` | 配车未完成 | 已成团且配车未完成(不变) |
| `GUIDE` | 配导游未完成 | 已成团且配导游未完成(不变) |
| `PHOTOGRAPHER` | 配摄影未完成 | 已成团且配摄影未完成(不变) |
| `DRIVER` | 车辆未派司机 | 🆕 已成团,且团车有车没派司机(按车务「团期配车总览」口径,已取消的派车不算) |
| `DRIVER_UNAVAILABLE` | 司机信息暂不可用 | 🆕 已成团,且这次没能从车务读到团车信息(车务服务不可用或超时);稍后重读即可 |
- 未成团(招募中、已流团)仍**只列 `STAGE`**,不判资源也不判司机。
- `DRIVER` 与 `VEHICLE` 各判各的:配车已完成的团照样可能缺司机。
- `DRIVER` 与 `DRIVER_UNAVAILABLE` 不会同时出现。
- 只用逐户派车(没有团车)的团不会出现 `DRIVER`:逐户派车的车一定带司机。
- 车务读不到时按「不可下发」处理:这期间所有已成团的团都会带 `DRIVER_UNAVAILABLE`,接口本身照常返回 `code=200`。
**`bus` 默认值**:先列团车,再列逐户派车,每辆车 `车型 车牌 司机 姓名 脱敏手机`。
- 团车的车型是车辆型号名,例 `丰田考斯特 蒙A-K1999 司机 巴特尔 135****5020`。
- 同一辆车(车型 + 车牌相同)在团车和逐户派车里都出现时只列一次,司机去重合并。
- 多日换过司机用 ` / ` 并列;车与车之间用 `、`。
- 团车全程没派司机的车只有车型车牌,例 `丰田埃尔法 蒙A-E5555`。
- 车务读不到时团车部分不出现,逐户派车部分照常。
- 手机号一律脱敏;已保存的正文不会自动刷新,只有 `defaults` 是实时值。
### 1. 读出团通知书 `GET /v3/admin/order/group-batch/:groupBatchId/docs/notice`
**VO**: `GroupBatchNoticeRespVO`(入参只有路径参数)→ `Result<GroupBatchNoticeRespVO>`
#### 使用场景
团期详情「出团通知书」弹窗打开时调用。按 `releasable` 置灰「打印 / 存 PDF」,`releasable=false` 时把 `releaseBlockers[].name` 列给用户看(与 #8746 相同,新取值无需单独处理)。
#### 入参字段表
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|------|------|------|------|------|------|
| groupBatchId | Path | Long | ✅ | 团期 ID | **不变** |
#### 出参字段表
| 字段 | 类型 | 说明 |
|------|------|------|
| releasable | Boolean | 🔄 再加「团车都已派司机」(规则见上) |
| releaseBlockers[].key | String | 🔄 新增取值 `DRIVER` / `DRIVER_UNAVAILABLE` |
| releaseBlockers[].name | String | 🔄 新增「车辆未派司机」/「司机信息暂不可用」 |
| bus | String | 🔄 未保存过(`saved=false`)时等于 `defaults.bus`,含团车;已保存时为保存的原文 |
| defaults.bus | String | 🔄 先团车、再逐户派车,格式见上 |
| 其余字段 | — | **不变** |
#### 请求示例
```http
GET /v3/admin/order/group-batch/2106331639531601921/docs/notice HTTP/1.1
Authorization: Bearer <管理员 token>
```
#### 响应示例
示例:待出发、四项资源都已完成、团车两辆车里一辆没派司机,从未保存过(草稿)——取自 TEST 验收读数。
```json
{
"code": 200,
"message": "成功",
"data": {
"title": "冻干粉发短信给 · 出团通知书",
"greeting": "亲爱的团友,欢迎参加本次行程!",
"meetTime": "2026-11-20 08:30",
"meetPlace": "",
"leader": "",
"bus": "丰田考斯特 蒙A-K1999 司机 巴特尔 135****5020、丰田埃尔法 蒙A-E5555",
"contacts": "",
"service": "",
"bring": "",
"saved": false,
"releasable": false,
"releaseBlockers": [
{
"key": "DRIVER",
"name": "车辆未派司机"
}
],
"version": 0,
"updateTime": null,
"defaults": {
"title": "冻干粉发短信给 · 出团通知书",
"greeting": "亲爱的团友,欢迎参加本次行程!",
"meetTime": "2026-11-20 08:30",
"meetPlace": "",
"leader": "",
"bus": "丰田考斯特 蒙A-K1999 司机 巴特尔 135****5020、丰田埃尔法 蒙A-E5555",
"contacts": "",
"service": "",
"bring": ""
}
}
}
```
给那辆车派上司机后:`releasable=true`、`releaseBlockers=[]`,`bus` 变为 `丰田考斯特 蒙A-K1999 司机 巴特尔 135****5020、丰田埃尔法 蒙A-E5555 司机 乌力吉 135****5015`。
#### 空数据 / 降级响应
- 没有团车、也没有逐户派车:`defaults.bus` 为 `""`。
- 车务服务读不到:接口仍 `code=200`;已成团的团 `releaseBlockers` 带 `DRIVER_UNAVAILABLE`、`releasable=false`;`defaults.bus` 只含逐户派车部分。形如:
```json
{
"code": 200,
"data": {
"releasable": false,
"releaseBlockers": [
{
"key": "DRIVER_UNAVAILABLE",
"name": "司机信息暂不可用"
}
]
}
}
```
#### 错误响应
| code | 条件 |
|---|---|
| `589500` | 团期不存在或已删除(不变) |
| `589507` | 当前角色没有 `group-batch:docs` 权限(不变) |
```json
{
"code": 589507,
"message": "无操作权限(当前角色未授予团期权限,或该团期不在您名下)",
"data": null
}
```
#### 业务边界
- `releasable` 只管「能否打印 / 下发」,不影响读取与保存。
- 同一个团在不同时间读,`releaseBlockers` 可能不同(车务补派司机、或车务恢复可读后会变)。
- `DRIVER_UNAVAILABLE` 是暂时状态,不代表真缺司机;重读即可。
### 2. 保存出团通知书 `PUT /v3/admin/order/group-batch/:groupBatchId/docs/notice`
**VO**: `GroupBatchNoticeSaveReqVO` → `Result<GroupBatchNoticeRespVO>`
#### 使用场景
运营编辑通知书后保存。入参不变;响应与读接口同一个结构,`releasable` / `releaseBlockers` 按上面的新规则计算。
#### 入参字段表
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|------|------|------|------|------|------|
| groupBatchId | Path | Long | ✅ | 团期 ID | **不变** |
| bus | Body | String | ✅ | ≤256 字 | **不变**;默认值含团车后可能更长,车与司机组合很多时需删减后再存 |
| title / greeting / meetTime / meetPlace / leader / contacts / service / bring | Body | String | ✅ | 同 #7532 | **不变** |
| expectedVersion | Body | Integer | ✅ | ≥0 | **不变**,取读接口的 `version` |
#### 出参字段表
| 字段 | 类型 | 说明 |
|------|------|------|
| releasable / releaseBlockers | — | 🔄 同读接口 |
| version | Integer | **不变**,保存后的新版本 |
| 其余字段 | — | **不变** |
#### 请求示例
```json
{
"title": "冻干粉发短信给 · 出团通知书",
"greeting": "亲爱的团友,欢迎参加本次行程!",
"meetTime": "2026-11-20 08:30",
"meetPlace": "海拉尔东山国际机场 T1 到达厅 3 号门",
"leader": "",
"bus": "丰田考斯特 蒙A-K1999 司机 巴特尔 135****5020、丰田埃尔法 蒙A-E5555",
"contacts": "",
"service": "",
"bring": "",
"expectedVersion": 4
}
```
#### 响应示例
示例:团车一辆车没派司机时保存——保存成功、版本 4 → 5,响应同样带 `DRIVER`(保存不卡下发门)。
```json
{
"code": 200,
"message": "成功",
"data": {
"bus": "丰田考斯特 蒙A-K1999 司机 巴特尔 135****5020、丰田埃尔法 蒙A-E5555",
"meetPlace": "海拉尔东山国际机场 T1 到达厅 3 号门",
"saved": true,
"releasable": false,
"releaseBlockers": [
{
"key": "DRIVER",
"name": "车辆未派司机"
}
],
"version": 5
}
}
```
#### 空数据 / 降级响应
- 车务服务读不到时保存照常成功,响应缺项为 `DRIVER_UNAVAILABLE`。
#### 错误响应
| code | 条件 |
|---|---|
| `589500` | 团期不存在(不变) |
| `589507` | 当前角色没有 `group-batch:docs` 权限(不变) |
| `589585` | 版本冲突,请重读后再存(不变) |
| `589587` | 正文含证件号形态的数字(不变) |
```json
{
"code": 589585,
"message": "通知书已被他人修改,请刷新后重试",
"data": null
}
```
#### 业务边界
- 保存**不卡**下发门:缺司机、车务读不到都能保存。
- 保存成功仍在团期时间线新增「保存出团通知书(第 N 版)」(#8746 口径不变)。
---
## 四、契约约束与正确调用方式
- 「打印 / 存 PDF」按 `releasable` 置灰,`releasable=false` 时展示 `releaseBlockers[].name`;判断用 `key`,不要用中文名。
- 按 #8746 约定「遇到不认识的 `key` 按 `name` 展示」实现的页面,本单零适配。
- 不要自己根据车辆、司机数据推算能否打印,以 `releasable` 为准。
- 看到 `DRIVER_UNAVAILABLE` 时可以提示「稍后重试」,它不是业务缺项。
---
## 五、数据库行为
- 零表结构变更、零数据迁移。
- 读接口零写入;保存接口行为与 #8746 相同。
- 团车数据在保存前、写事务之外读取。
---
## 六、边界行为
- 团车派车行里车已被删除、取不到车型和车牌的,不进默认车辆信息,但仍参与「是否派了司机」的判断。
- 派过司机但司机档案已删除的,视为已派司机(不报 `DRIVER`),默认车辆信息里不显示该司机。
- 车务返回的手机号本已脱敏,通知书侧再脱敏一次,不会出现明文。
## 六.6、修改前后对比
| 场景 | 改前(#8746) | 改后 |
|---|---|---|
| 团车团默认车辆信息 | `""` | `丰田考斯特 蒙A-K1999 司机 巴特尔 135****5020` |
| 待出发、四项已完成、团车有车没派司机 | `releasable=true`,`[]` | `releasable=false`,`[DRIVER]` |
| 同上,补派司机后 | `releasable=true` | `releasable=true`,`[]` |
| 车务服务不可用 | 无影响(读不到团车) | 已成团的团带 `[DRIVER_UNAVAILABLE]`,`releasable=false` |
| 只用逐户派车的团 | — | 与改前相同 |
## 六.7、影响评估
- **是否破坏向后兼容**:`releaseBlockers` 只是多了两个取值;`releasable` 在「团车缺司机」与「车务读不到」时由 `true` 变 `false`。按 `name` 通用展示的页面无需改动。
- **前端是否必须同步上线**:不需要。
- **回滚**:revert PR #8794 后重新部署 order-v3 与 fleet。
---
## 七、不影响范围
- 两个接口的路径、入参、判权(`group-batch:docs`)、错误码:不变。
- 只用逐户派车的团:读数与改前一致(TEST 6 个团前后逐项比对一致)。
- 已保存的通知书正文:不会被改写。
- 小程序端:无影响。
---
## 八、测试环境已验证
**环境**:TEST(`https://api.test.1814.love`) **验证时间**:2026-10-04 17:04~17:13
**构建身份**:order-v3、fleet 均部署 `dev-v3 @ a281744c8`(本单合并提交);`releaseBlockers` 出现 `DRIVER` / `DRIVER_UNAVAILABLE` 新取值只可能来自新字节,fleet 两实例新内部读口返回 200。
**身份**:自签 token 直打网关,用 TEST 真实账号 ID 配对应角色。
### 8.1 团车团默认车辆(只读,3 个现成团车团)
| 团期 | `defaults.bus`(6 次读一致) | 与车务派车推算 |
|---|---|---|
| T27-5637 | `坦克300 蒙P318A 司机 P3测试司机18 139****0018、别克GL8 C0927T01 司机 测B0927司机甲 199****0001` | 一致 |
| T26-3963 | `丰田考斯特 蒙A-K1999 司机 巴特尔 135****5020` | 一致 |
| T26-0352 | `丰田埃尔法 蒙A-E5555 司机 乌力吉 135****5015` | 一致 |
部署前这三个团的 `defaults.bus` 都是 `""`。
### 8.2 车辆未派司机(自建团期,待出发、四项已完成,团车两辆、一辆没派司机)
| 步骤 | `releasable` | `releaseBlockers` | `defaults.bus` |
|---|---|---|---|
| 一辆没派司机 | `false` | `[DRIVER]` | `丰田考斯特 蒙A-K1999 司机 巴特尔 135****5020、丰田埃尔法 蒙A-E5555` |
| 补派司机后 | `true` | `[]` | `… 丰田埃尔法 蒙A-E5555 司机 乌力吉 135****5015` |
| 撤回司机后保存 | `false` | `[DRIVER]`(PUT 响应) | 版本 4 → 5,时间线新增「保存出团通知书(第 5 版)」 |
每步各读 6 次,读数一致。
### 8.3 车务服务读不到
只对通知书读团车这一条调用临时压 1ms 超时(17:02~17:08,验完还原配置并核对一致):4 个团各读 6 次全部 `code=200`;已成团的团都带 `DRIVER_UNAVAILABLE`(如资源准备中的团为 `[STAGE, HOTEL, DRIVER_UNAVAILABLE]`、核单中的团为 `[HOTEL, DRIVER_UNAVAILABLE]`),`defaults.bus` 不含团车;两个实例各记录 12 条降级告警,无系统异常。
### 8.4 只用逐户派车的团
6 个没有团车的团(资源准备中 4 个、核单中 1 个、已结算 1 个),部署前后 `releasable`、`releaseBlockers`、`bus`、`defaults.bus` 逐项一致,均未出现 `DRIVER`。
### 8.5 判权与日志
| 调用方 | 读 | 存 |
|---|---|---|
| 不带 token | 网关 `401` | 网关 `401` |
| 车务、财务(无 `group-batch:docs`) | `589507` | `589507`,零写入 |
| 管理员、团期管理员 | `200` | `200` |
验收时间窗内 order-v3、fleet 四个实例的日志,按 4 名司机脱敏号的前三后四检索明文手机号,零命中(同窗口内本轮请求的团期号四个实例均有命中,窗口有效)。
### 本地证据
| 项 | 读数 |
|---|---|
| 定向 7 类 | 125/0/0 |
| order-v3 `groupbatch` + `fleet` + `archunit` 包 + 全模块架构测试(有 Docker) | 3799/0/0 |
| fleet `dispatch` 包 + 红线架构测试 | 517/0/0,跳过 2(需显式开启的容器类) |
| 变基到最新 `dev-v3` 后重测(定向 + 流团相关 + 上下文 IT + 全部架构测试) | 315/0/0 |
### 未覆盖
- TEST 上没有「未删除团期 + 未取消订单 + 逐户派车快照」的现成团,逐户派车与团车同车合并只由单测覆盖。
- 团车有车没派司机用临时插入的派车行模拟,车务真实排车流程未走;验完已删除。
---
## 十、相关文档
- Issue `#8767`;PR `#8794`
- 拆单来源:Issue `#8746`(下发门缺项、逐户派车带司机)
- 团车读口:同日 `04_8767` 新增接口(内部)那份
- 接口文档:`docs/group/团期模块接口文档-v2.0.html` GB-ADM-081 / 082
## 关联 / 联系人
### 链接
- **Issue**: [#8767](https://git.1814.love/wx/HL/issues/8767)
- **PR**: [#8794](https://git.1814.love/wx/HL/pulls/8794)
- **Merge commit**: [a281744c8](https://git.1814.love/wx/HL/commit/a281744c8)
### 联系人
- **后端负责人**: @jw
@@ -0,0 +1,224 @@
---
schema: "hl-changelog/v2"
ticket: "8767"
title: "车务新增内部接口「按团期列出团车活跃派车行」(order-v3 出团通知书调用):车型车牌、司机与脱敏手机,排除已取消"
consumer: "internal"
author: "jw(GIT)"
change_type: "新增接口"
backend_status: "deployed"
gateway_status: "not_required"
frontend_status: "not_required"
frontend_owner: ""
frontend_ref: ""
target_release: ""
verified_at: ""
status_note: "新增 GET /internal/fleet/dispatch/group-batch/:groupBatchId/vehicles,供 order-v3 出团通知书拼团车车辆、判「车辆未派司机」。内部接口不经网关(公网网关返回 code 403「接口不可访问」),直连 fleet 须带 X-Internal-Token,缺失返回 HTTP 403;前端无需对接。司机手机在 fleet 侧脱敏后才出域。已合并 dev-v3(PR #8794,merge commit a281744c8)并部署 TEST,两实例直连实测。管理后台侧变化见同日 04_8767 修改接口那份。"
updated_at: "2026-10-04"
base: "dev-v3"
---
# fleet: 新增内部接口「按团期列出团车活跃派车行」
> **服务**: hl-fleet-service(端口 8087 / 8187,双实例;内部接口,网关不放行)
> **PR**: `#8794`(已合入 `dev-v3`,合并提交 `a281744c8`)
> **Issue**: #8767
---
## ⚠️ 关键变化
🟢 新增 `GET /internal/fleet/dispatch/group-batch/:groupBatchId/vehicles`:按团期返回团车(整团派车)的活跃派车行,每行一天一辆车,带车型、车牌、司机与脱敏手机;`driverId` 为空表示「只排了车、没排司机」。
🟢 首个调用方:order-v3 出团通知书(`FleetGroupDispatchFeignClient`,contextId `fleetGroupDispatchVehicle`)。
🟢 出参载体是共享 DTO `com.hulalv.common.dto.fleet.GroupDispatchVehicleDTO`(hl-common-core,纯新增类)。
---
## 一、背景
团车的车辆与司机只存在车务的 `fleet_group_dispatch`,order-v3 的逐户派车快照里没有团车户的行,出团通知书既拼不出团车车辆,也判不出「车辆未派司机」。车务原有的团车读口(团期配车总览)要先回调 order-v3 取团期基线,被 order-v3 调用会形成同步环,所以另开一个只读本域表的内部读口。
---
## 二、变更接口清单
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|---|------|------|------|----------|------|
| 1 | 按团期列出团车活跃派车行 | GET | `/internal/fleet/dispatch/group-batch/:groupBatchId/vehicles` | 新增 | 内部接口,order-v3 出团通知书调用 |
---
## 三、接口详情
### 1. 按团期列出团车活跃派车行 `GET /internal/fleet/dispatch/group-batch/:groupBatchId/vehicles`
**VO**: `GroupDispatchVehicleDTO`(入参只有路径参数)→ `Result<List<GroupDispatchVehicleDTO>>`
#### 使用场景
order-v3 读、存出团通知书时各调一次:拼默认车辆信息 `bus`,并判断下发门 `DRIVER`。只在写事务之外调用。
#### 入参字段表
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|------|------|------|------|------|------|
| groupBatchId | Path | Long | ✅ | 团期主订单 ID | 单个团期,不涉及批量分片 |
| X-Internal-Token | Header | String | ✅ | 内部令牌 | 由公共 Feign 拦截器自动附带 |
#### 出参字段表
| 字段 | 类型 | 说明 |
|------|------|------|
| dispatchId | String | 团期配车行 ID(Long 序列化为字符串) |
| tripDate | String | 服务日,`yyyy-MM-dd` |
| vehicleId | String | 车辆 ID |
| vehiclePlateNo | String | 车牌;车已删除时为 `null` |
| vehicleModelName | String | 车型名称(车辆型号,如「丰田考斯特」);车已删除时为 `null` |
| driverId | String | 司机 ID;为 `null` 表示只排了车、没排司机 |
| driverName | String | 司机姓名;没排司机或司机档案已删除时为 `null` |
| driverPhone | String | **脱敏**司机手机,形如 `135****5020`;没有时为 `null` |
| status | String | 派车状态 `ASSIGNED`(已派车)/ `CONFIRMED`(已确认);`CANCELLED` 不返回 |
#### 请求示例
```http
GET /internal/fleet/dispatch/group-batch/2104962917969608705/vehicles HTTP/1.1
Host: 192.168.100.236:8087
X-Internal-Token: <内部令牌>
```
#### 响应示例
取自 TEST(团期 T27-5637,两辆车三天,节选前两行):
```json
{
"code": 200,
"message": "成功",
"data": [
{
"dispatchId": "2104969512002682882",
"tripDate": "2027-03-18",
"vehicleId": "2089691299660644353",
"vehiclePlateNo": "蒙P318A",
"vehicleModelName": "坦克300",
"driverId": "2089691297869651969",
"driverName": "P3测试司机18",
"driverPhone": "139****0018",
"status": "CONFIRMED"
},
{
"dispatchId": "2104969512002682883",
"tripDate": "2027-03-18",
"vehicleId": "2104029270659780610",
"vehiclePlateNo": "C0927T01",
"vehicleModelName": "别克GL8",
"driverId": "2104030084715433986",
"driverName": "测B0927司机甲",
"driverPhone": "199****0001",
"status": "CONFIRMED"
}
]
}
```
#### 空数据 / 降级响应
- 该团没有团车(只用逐户派车,或派车全部已取消):`data=[]`。
- 调用方(order-v3)侧:fleet 不可用或超时,降级返回错误结果(`584072`「车务司机车辆信息暂时不可用」),**不会**伪装成空数组;通知书据此报 `DRIVER_UNAVAILABLE`。
```json
{
"code": 200,
"message": "成功",
"data": []
}
```
#### 错误响应
| HTTP / code | 条件 |
|---|---|
| HTTP 403 / `403` | 未带或带错 `X-Internal-Token`:`内部接口禁止外部访问` |
| 网关 `403` | 经公网网关访问:`接口不可访问` |
```json
{
"code": 403,
"msg": "内部接口禁止外部访问"
}
```
#### 业务边界
- 只读车务本域表,**不回调 order-v3**,不校验团期是否存在(团期不存在即返回 `[]`)。
- 「已取消不返回」与车务「团期配车总览」、团车就绪判定同一口径:总览上看不到的行这里也不返回。
- 同一辆车多天各一行;去重、拼接由调用方负责。
- 司机手机只有脱敏形态,明文不出车务服务。
---
## 四、契约约束与正确调用方式
- 只能服务间调用:走 Feign(`name=hl-fleet-service`,`path=/internal/fleet/dispatch`),不经网关。
- `driverId` 为空才算「没派司机」;`driverName` 为空但 `driverId` 有值是「派过、司机档案已删」,不算缺司机。
- 失败要保留为失败,不要把降级当成空数组(空数组的含义是「没有团车」)。
---
## 五、数据库行为
- 只读:`fleet_group_dispatch`(存活行),批量取 `fleet_vehicle`、`fleet_driver`;零写入、零表结构变更。
---
## 六、边界行为
- 返回顺序:服务日升序,同日按配车行 ID 升序。
- 车或司机已软删:对应展示字段为 `null`,ID 照给。
---
## 七、不影响范围
- 车务既有接口(团期配车总览、重配、释放、覆盖查询等):不变。
- 其他依赖 hl-common-core 的服务:只多了一个类,行为不变。
- 管理后台、小程序:不直接调用本接口。
---
## 八、测试环境已验证
**环境**:TEST,fleet 两实例直连(8087 / 8187) **验证时间**:2026-10-04 17:01~17:13
**构建身份**:fleet 部署 `dev-v3 @ a281744c8`(本单合并提交),新路径两实例均返回 `code=200`(旧字节无此路径)。
| 用例 | 结果 |
|---|---|
| 团期 T27-5637,带内部令牌 | 两实例均 `code=200`,6 行(2 辆车 × 3 天),手机全为 `ddd****dddd` 形态 |
| 不带内部令牌 | 两实例均 HTTP 403「内部接口禁止外部访问」 |
| 经公网网关(不带 / 带管理员 token) | 均 `code=403`「接口不可访问」 |
| 自建团期插入两行(一行有司机、一行无司机) | 无司机那行 `driverId=null`;补派后带司机,通知书读数与本接口推算逐字一致 |
| 日志 | 验收窗口内两实例按司机脱敏号前三后四检索明文手机号零命中 |
本地:fleet `dispatch` 包 + 红线架构测试 517/0/0(跳过 2,需显式开启的容器类),含本读口 4 条单测与「与总览同一分母」一致性用例。
---
## 十、相关文档
- Issue `#8767`;PR `#8794`
- 调用方变化:同日 `04_8767` 修改接口(管理后台)那份
- 团车 CANCELLED 口径来源:Issue `#8550`
## 关联 / 联系人
### 链接
- **Issue**: [#8767](https://git.1814.love/wx/HL/issues/8767)
- **PR**: [#8794](https://git.1814.love/wx/HL/pulls/8794)
- **Merge commit**: [a281744c8](https://git.1814.love/wx/HL/commit/a281744c8)
### 联系人
- **后端负责人**: @jw