文件
hl-api-changelog/changelogs-v2/2026-10/04_8767_出团通知书默认车辆补团车与车辆未派司机缺项-修改接口-管理后台.md
T

18 KiB
原始文件 Blame 文件历史

schema, ticket, title, consumer, author, change_type, backend_status, gateway_status, frontend_status, frontend_owner, frontend_ref, target_release, verified_at, status_note, updated_at, base
schema ticket title consumer author change_type backend_status gateway_status frontend_status frontend_owner frontend_ref target_release verified_at status_note updated_at base
hl-changelog/v2 8767 出团通知书:默认车辆信息补上团车(整团派车)的车辆与司机,releaseBlockers 新增「车辆未派司机」DRIVER 与「司机信息暂不可用」DRIVER_UNAVAILABLE admin jw(GIT) 修改接口 deployed verified not_required 已合并 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 展示即可,无需新适配。 2026-10-04 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 🔄 先团车、再逐户派车,格式见上
其余字段 — 不变

请求示例

GET /v3/admin/order/group-batch/2106331639531601921/docs/notice HTTP/1.1
Authorization: Bearer <管理员 token>

响应示例

示例:待出发、四项资源都已完成、团车两辆车里一辆没派司机,从未保存过(草稿)——取自 TEST 验收读数。

{
  "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 只含逐户派车部分。形如:
{
  "code": 200,
  "data": {
    "releasable": false,
    "releaseBlockers": [
      {
        "key": "DRIVER_UNAVAILABLE",
        "name": "司机信息暂不可用"
      }
    ]
  }
}

错误响应

code 条件
589500 团期不存在或已删除(不变)
589507 当前角色没有 group-batch:docs 权限(不变)
{
  "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 不变,保存后的新版本
其余字段 — 不变

请求示例

{
  "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(保存不卡下发门)。

{
  "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 正文含证件号形态的数字(不变)
{
  "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

关联 / 联系人

链接

联系人

  • 后端负责人: @jw