From e08991a58864a6bcea294e9cb942e2b5ffe2a087 Mon Sep 17 00:00:00 2001 From: jw Date: Sun, 4 Oct 2026 17:16:16 +0800 Subject: [PATCH] =?UTF-8?q?docs(changelog):=20#8767=20=E5=87=BA=E5=9B=A2?= =?UTF-8?q?=E9=80=9A=E7=9F=A5=E4=B9=A6=E9=BB=98=E8=AE=A4=E8=BD=A6=E8=BE=86?= =?UTF-8?q?=E8=A1=A5=E5=9B=A2=E8=BD=A6=E3=80=81=E4=B8=8B=E5=8F=91=E7=BC=BA?= =?UTF-8?q?=E9=A1=B9=E6=96=B0=E5=A2=9E=20DRIVER=20/=20DRIVER=5FUNAVAILABLE?= =?UTF-8?q?=EF=BC=88=E4=BF=AE=E6=94=B9=E6=8E=A5=E5=8F=A3=C2=B7=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E5=90=8E=E5=8F=B0=EF=BC=89+=20=E8=BD=A6=E5=8A=A1?= =?UTF-8?q?=E5=9B=A2=E8=BD=A6=E6=B4=BB=E8=B7=83=E6=B4=BE=E8=BD=A6=E8=A1=8C?= =?UTF-8?q?=E5=86=85=E9=83=A8=E8=AF=BB=E5=8F=A3=EF=BC=88=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=C2=B7internal=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 --- ...车辆补团车与车辆未派司机缺项-修改接口-管理后台.md | 426 ++++++++++++++++++ ...¡团车活跃派车行内部读口-新增接口-管理后台.md | 224 +++++++++ 2 files changed, 650 insertions(+) create mode 100644 changelogs-v2/2026-10/04_8767_出团通知书默认车辆补团车与车辆未派司机缺项-修改接口-管理后台.md create mode 100644 changelogs-v2/2026-10/04_8767_车务团车活跃派车行内部读口-新增接口-管理后台.md diff --git a/changelogs-v2/2026-10/04_8767_出团通知书默认车辆补团车与车辆未派司机缺项-修改接口-管理后台.md b/changelogs-v2/2026-10/04_8767_出团通知书默认车辆补团车与车辆未派司机缺项-修改接口-管理后台.md new file mode 100644 index 00000000..0d351d16 --- /dev/null +++ b/changelogs-v2/2026-10/04_8767_出团通知书默认车辆补团车与车辆未派司机缺项-修改接口-管理后台.md @@ -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` + +#### 使用场景 + +团期详情「出团通知书」弹窗打开时调用。按 `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` + +#### 使用场景 + +运营编辑通知书后保存。入参不变;响应与读接口同一个结构,`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 diff --git a/changelogs-v2/2026-10/04_8767_车务团车活跃派车行内部读口-新增接口-管理后台.md b/changelogs-v2/2026-10/04_8767_车务团车活跃派车行内部读口-新增接口-管理后台.md new file mode 100644 index 00000000..bf3c8919 --- /dev/null +++ b/changelogs-v2/2026-10/04_8767_车务团车活跃派车行内部读口-新增接口-管理后台.md @@ -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>` + +#### 使用场景 + +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