changelog-filename-gate / validate (push) Failing after 1s
- 6 份 #7441 changelog:正文与 status_note 里的内部取证目录引用(20 处)改为「见工单 #7441 验收评论」,时间戳与部署提交号保留 - 5 份管理后台分册补「验收口径边界:页面完成状态单独跟踪(前端归 mmg),不计入 #7441 验收」;3 份补「前端负责人(收件人)@mmg」 - 15_确认行程清单 / 15_结算核单:frontend_status=not_required 时 verified_at 按校验器 E_FRONTEND_STATE 规则置空(mmg 核实结论保留在 status_note) Refs #7441 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
281 行
14 KiB
Markdown
281 行
14 KiB
Markdown
---
|
||
schema: "hl-changelog/v2"
|
||
ticket: "7441"
|
||
title: "团期用车内部回调——团车配完/清零双向回写户级需求状态(内部接口分册)"
|
||
consumer: "internal"
|
||
author: "wx(GIT)"
|
||
change_type: "修改接口"
|
||
backend_status: "deployed"
|
||
gateway_status: "verified"
|
||
frontend_status: "not_required"
|
||
frontend_owner: ""
|
||
frontend_ref: ""
|
||
target_release: ""
|
||
verified_at: ""
|
||
status_note: "两个端点均为 /v3/internal/** Feign 接口,经网关访问返回 403(JwtAuthFilter 按设计拒绝),取证走直连 order-v3 服务端口(192.168.100.236:8086)+ X-Internal-Token,与 hl-fleet-service 实际调用路径一致。正向(vehicle-ready)与反向(vehicle-ready-reset)均有四次真实调用的完整前后快照(S1-S4,见第八节,见工单 #7441 验收评论)。被测服务:order-v3 = dev-v3 64c3f72a3(2026-09-15 12:06:01 部署),行为在 870610927(含 PR-3)上未再变化。"
|
||
updated_at: "2026-09-15"
|
||
base: "dev-v3"
|
||
---
|
||
|
||
# order-v3: 团期用车内部回调——团车完成双向回写(内部接口分册)
|
||
|
||
> **本文件是分册。** 本单(`#7441`)同批还有 3 份面向前端的 changelog(正式用车需求声明四端点、确认行程清单房车安排短路判定、结算核单车侧闸门升级),本册收件人是后端与 fleet 侧,**不是 mmg**——两个端点均为跨服务 Feign 调用,hl-ui 调不到。拆分依据 `BACKEND_CHANGELOG_DELIVERY_GUIDE.md` 2.5 节:`/v3/internal/*` 必须单独成篇,不许和 admin/mp 接口塞同一份。
|
||
>
|
||
> **服务**: hl-order-service-v3 (端口 8083)
|
||
> **消费方**: hl-fleet-service(Feign,`/v3/internal/**`,不经 JWT,靠网关不暴露该前缀做隔离)
|
||
> **PR**: #7742(PR-2)
|
||
> **Issue**: #7441
|
||
> **日期**: 2026-09-15
|
||
> **影响范围**: 既有内部端点 `POST /v3/internal/group-batch/{groupBatchId}/vehicle-ready` 与 `POST .../vehicle-ready-reset`,路径/参数/响应结构/错误码均未改,新增户级用车需求状态双向回写副作用
|
||
|
||
---
|
||
|
||
## ⚠️ 关键变化
|
||
|
||
1. **团级配车完成回调(`vehicle-ready`)从此会连带把在团户的行程用车(TRAVEL)需求状态回写为完成**——改前该回调只置团级 `vehicle_ready=true` 一列,户级需求行一行不动;改后同一次调用内,未经逐户 DAILY_V3 快照完成的在团户,会被批量推到"已完成"状态并同步订单镜像列。
|
||
2. **团级配车清零回调(`vehicle-ready-reset`)从此会连带把"由团车路径完成"的户打回"处理中"**——只接管由本回调正向产出的那批户,已经由逐户 DAILY_V3 快照完成的户、以及完成来源标识为空的历史行,一律不动。
|
||
3. **两个端点自身的请求/响应契约完全不变**(`Result<Void>`,团期不存在也返回 200 幂等友好),fleet 侧调用代码无需任何改动。
|
||
|
||
---
|
||
|
||
## 一、背景
|
||
|
||
fleet 团级配车完成后经 Outbox → Feign 回调 `vehicle-ready`;团级清零/释放(取消成团、流团、fleet 侧整团释放)后回调 `vehicle-ready-reset`。改前这两个回调只维护团期聚合根自己的 `vehicle_ready` 标志位,户级用车需求(`order_vehicle_requirement`)一行都不碰——全仓唯一把户级需求置完成的生产者是逐户 DAILY_V3 派车快照回调,而团期用车此时已经走团级配车(不逐户派车),于是"整团车已配好、各户需求仍停在待处理",被 `#7445` 的结算闸拦死且无任何运营操作能解开。本单补上这个双向回写。
|
||
|
||
---
|
||
|
||
## 二、变更接口清单
|
||
|
||
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|
||
|---|------|------|------|----------|------|
|
||
| 1 | 回填配车就绪(正向) | POST | `/v3/internal/group-batch/{groupBatchId}/vehicle-ready` | 行为变化 | 新增在团户 TRAVEL 需求批量完成回写,契约不变 |
|
||
| 2 | 重置配车就绪(反向) | POST | `/v3/internal/group-batch/{groupBatchId}/vehicle-ready-reset` | 行为变化 | 新增"由团车完成"的户打回处理中,契约不变 |
|
||
|
||
---
|
||
|
||
## 三、接口详情
|
||
|
||
### 1. 回填配车就绪(正向) `POST /v3/internal/group-batch/{groupBatchId}/vehicle-ready`
|
||
|
||
**VO**: `无请求体 → Result<Void>`
|
||
|
||
#### 使用场景
|
||
|
||
fleet-service 整团配车完成后回调。仅限内部 Feign 调用,不经网关(`JwtAuthFilter` 按设计拒绝 `/v3/internal/**`),fleet 侧走服务发现直连。幂等:重复调用安全。回填成功后内部自动检测四项资源就绪门,满足则推进团期状态。
|
||
|
||
#### 入参字段表
|
||
|
||
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||
|------|------|------|------|------|------|
|
||
| groupBatchId | Path | Long | 是 | - | 团期主订单 ID(不变) |
|
||
|
||
(无请求体,不变。)
|
||
|
||
#### 出参字段表
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| data | null | 结构完全不变,`Result<Void>` |
|
||
|
||
#### 请求示例
|
||
|
||
```http
|
||
POST /v3/internal/group-batch/2099716821799047169/vehicle-ready HTTP/1.1
|
||
X-Internal-Token: ***
|
||
```
|
||
|
||
(无请求体。测试环境经服务端口直连,生产环境由 fleet-service 经 Feign LB 直连。)
|
||
|
||
#### 响应示例
|
||
|
||
(测试服真实响应,2026-09-15 12:28:19,直连 order-v3:8086,见工单 #7441 验收评论)
|
||
|
||
```json
|
||
{ "code": 200, "message": "成功", "data": null, "traceId": null, "success": true }
|
||
```
|
||
|
||
#### 空数据 / 降级响应
|
||
|
||
团期不存在时仍返回上述成功结构(幂等友好,不抛错),仅记 WARN 日志,不做任何户级回写。
|
||
|
||
```json
|
||
{ "code": 200, "success": true, "data": null }
|
||
```
|
||
|
||
#### 错误响应
|
||
|
||
本单不新增错误码。团期不存在按幂等成功处理(见上),不返回错误响应;其余异常沿用全局异常处理,无本单专属错误码。
|
||
|
||
```json
|
||
{ "code": 500, "message": "系统异常,请稍后重试", "success": false, "data": null }
|
||
```
|
||
|
||
#### 业务边界
|
||
|
||
- 同一事务内先置团级 `vehicle_ready=true`,再取在团户,把 `kind=TRAVEL` 且状态在"待处理/处理中"的 active 需求 CAS 推进为"已完成",并同步订单镜像列;团期状态推进在事务外进行。
|
||
- **已由逐户 DAILY_V3 快照完成的户跳过、不覆盖**:这类户是更权威的完成来源(带逐日车辆/司机明细),团车回写不覆盖它。
|
||
- **仍停在"待审核"(配车后才入团、尚未经整团放行)的户跳过并记 WARN,不强推**。
|
||
- **重复回调幂等**:已完成的户读侧直接跳过、不发 CAS;CAS 命中 0 行(读到未完成后被并发推进)记 WARN 跳过,不抛错。
|
||
- 团期不存在只记 WARN,不抛错,不影响 Outbox 重投语义。
|
||
- 本次回写**只改状态与完成来源标识两列,不写任何逐户配车明细列**(不产生逐户车辆/司机数据)——车与司机在团级承担,任何逐户配车行都只可能是历史残留。
|
||
|
||
---
|
||
|
||
### 2. 重置配车就绪(反向) `POST /v3/internal/group-batch/{groupBatchId}/vehicle-ready-reset`
|
||
|
||
**VO**: `无请求体 → Result<Void>`
|
||
|
||
#### 使用场景
|
||
|
||
fleet-service 整团清零、或取消成团/流团释放后回调,把 `vehicle_ready` 重置为与当前有效计划一致的值。仅限内部 Feign 调用,同上不经网关。幂等:重复调用安全。不触发任何团期状态推进(与置位方向相反)。
|
||
|
||
#### 入参字段表
|
||
|
||
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||
|------|------|------|------|------|------|
|
||
| groupBatchId | Path | Long | 是 | - | 团期主订单 ID(不变) |
|
||
|
||
(无请求体,不变。)
|
||
|
||
#### 出参字段表
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| data | null | 结构完全不变,`Result<Void>` |
|
||
|
||
#### 请求示例
|
||
|
||
```http
|
||
POST /v3/internal/group-batch/2099716821799047169/vehicle-ready-reset HTTP/1.1
|
||
X-Internal-Token: ***
|
||
```
|
||
|
||
#### 响应示例
|
||
|
||
(测试服真实响应,2026-09-15 12:28:20,直连 order-v3:8086,见工单 #7441 验收评论)
|
||
|
||
```json
|
||
{ "code": 200, "message": "成功", "data": null, "traceId": null, "success": true }
|
||
```
|
||
|
||
#### 空数据 / 降级响应
|
||
|
||
团期不存在时仍返回成功结构,仅记 WARN,不做任何户级回写。
|
||
|
||
```json
|
||
{ "code": 200, "success": true, "data": null }
|
||
```
|
||
|
||
#### 错误响应
|
||
|
||
本单不新增错误码,异常处理同「三、1」。
|
||
|
||
```json
|
||
{ "code": 500, "message": "系统异常,请稍后重试", "success": false, "data": null }
|
||
```
|
||
|
||
#### 业务边界
|
||
|
||
- 同一事务内先重置团级 `vehicle_ready=false`,再取在团户逐一按行锁 + 锁内复读判定资格后打回"处理中":**只接管"完成来源标识为团车"且"非逐户 DAILY_V3 契约版本"的户**——这是必要条件,不是可选加强。
|
||
- **两类户一律跳过、三列一字不改**:①已由逐户 DAILY_V3 快照完成的户;②完成来源标识为空的历史 legacy 完成行(这类行即使表面状态与团车形态相同,也不会被本回调碰)。测试服实测两类对照户在四步(基线 → reset → ready)全程逐列不变。
|
||
- **反向不清"完成来源"标识列**:只把状态打回"处理中",完成来源标识保留,供下一次团车正向回写复用同一判据(幂等)。
|
||
- **锁内复读**:判定资格必须在拿到需求行锁之后重新读取,不能用取锁前的内存值判断——避免与并发的逐户 DAILY 回调交错时把刚完成的快照户误判打回。
|
||
- 团期不存在只记 WARN,不抛错。
|
||
|
||
---
|
||
|
||
## 四、契约约束与正确调用方式
|
||
|
||
fleet-service 侧调用代码**无需任何改动**——两个端点的路径、方法、请求体(均无)、响应结构(均为 `Result<Void>`)与调用时机(配车完成后调正向、清零释放后调反向)全部不变。本单的行为变化完全由 order-v3 内部消化,不要求消费方感知或配合。
|
||
|
||
---
|
||
|
||
## 五、数据库行为
|
||
|
||
正向回调新增的写行为:同一事务内,在置团级就绪标志之后,把符合条件的在团户行程用车需求状态由"待处理/处理中"推进为"已完成",同步一列"完成来源"标识,并同步订单侧的用车控制状态镜像列;不写入任何逐户配车明细(车辆/司机/座位等)。反向回调新增的写行为:把"完成来源标识为团车"且"非逐户快照契约"的户由"已完成"打回"处理中",同步镜像列;"完成来源"标识本身不清空。两个方向均在各自既有事务内完成,不额外引入跨服务同步写。
|
||
|
||
---
|
||
|
||
## 六、边界行为
|
||
|
||
- 团期不存在 → 两个端点均只记 WARN,返回成功结构,不抛错(不变)
|
||
- 已由逐户 DAILY_V3 快照完成的户 → 正向跳过不覆盖,反向跳过不动
|
||
- 完成来源标识为空的历史 legacy 完成行 → 反向跳过不动(正向不适用,因为该状态本就不是"待处理/处理中")
|
||
- 仍在"待审核"的户 → 正向跳过并记 WARN,不强推
|
||
- 重复调用(Outbox 重投)→ 两个方向均幂等,不抛错、不重复产生副作用
|
||
|
||
---
|
||
|
||
## 六.6、修改前后对比
|
||
|
||
### 字段级对比
|
||
|
||
本单不改两个端点的请求/响应字段结构。
|
||
|
||
### 行为级对比
|
||
|
||
| 场景 | 改前 | 改后 |
|
||
|------|------|------|
|
||
| 团车配完回调(正向) | 只置团级 vehicle_ready=true,户级需求一行不动 | 同一事务内追加:在团户 TRAVEL 需求批量推进为已完成,同步镜像列 |
|
||
| 户已由逐户 DAILY_V3 快照完成 | 不适用(正向改前不碰户级) | 跳过、不覆盖 |
|
||
| 户仍在"待审核" | 不适用 | 跳过并记 WARN,不强推 |
|
||
| 团车清零回调(反向) | 只置团级 vehicle_ready=false | 同一事务内追加:把"由团车完成"的户打回处理中 |
|
||
| 逐户 DAILY_V3 快照户 / 历史 legacy 完成行 | 不适用(反向改前不碰户级) | 一律跳过,三列不变 |
|
||
| 重复回调 | 幂等(改前无户级副作用可言) | 仍幂等:已完成的户直接跳过不发 CAS |
|
||
|
||
---
|
||
|
||
## 六.7、影响评估
|
||
|
||
- **是否破坏向后兼容**: 否,端点契约完全不变,fleet 侧零改动。
|
||
- **前端是否必须同步上线**: 不适用(`frontend_status: not_required`,本册收件人是后端与 fleet 侧,hl-ui 调不到这两个端点)。
|
||
- **前端 workaround 清理点**: 无。
|
||
|
||
---
|
||
|
||
## 七、不影响范围
|
||
|
||
- **仅影响**: 两个内部端点在"团车配完/清零"场景下的户级用车需求状态副作用,端点本身契约不变。
|
||
- **零影响**:
|
||
- `GET /v3/internal/group-batch/{groupBatchId}/dispatch-baseline`——同 Controller 第三个端点,本单未改。
|
||
- 逐户 DAILY_V3 派车快照回调链路——完全独立,本单不改其任何代码。
|
||
- fleet-service 自身代码——零改动,仅消费方数据(户级需求状态)随之变化。
|
||
- `hl-gateway` 路由——`/v3/internal/**` 本就不上网关,本单不涉及网关配置。
|
||
|
||
---
|
||
|
||
## 八、测试环境已验证
|
||
|
||
**取证环境**:order-v3 = dev-v3 `64c3f72a3`(2026-09-15 12:06:01 部署),经直连服务端口 `192.168.100.236:8086` + `X-Internal-Token` 调用(与 fleet-service 实际调用路径一致;经 `hl-gateway` 访问 `/v3/internal/**` 返回 403,非本单行为,属既有设计)。
|
||
|
||
四组户级快照对照(S1→S4,见工单 #7441 验收评论):
|
||
|
||
| 快照 | 操作 | 团车户(GV/MIX) | DAILY_V3 快照户(DV) |
|
||
|---|---|---|---|
|
||
| S1→S2 | 正向 `vehicle-ready` | 待处理 → 已完成,完成来源写入 | 逐列不变(含 update_time) |
|
||
| S2→S3 | 反向 `vehicle-ready-reset` | 已完成 → 处理中,完成来源保留 | 仅 update_time 变化(取锁刷新),其余不变 |
|
||
| S3→S4 | 再次正向 `vehicle-ready` | 处理中 → 已完成,完成来源仍为团车 | 幂等跳过,逐列不变 |
|
||
|
||
历史 legacy 完成行(LEG 户,SQL 构造成"已完成+完成来源为空")在同一组四步全程三列逐字不变,反向回调按"跳过并记 WARN"处理,日志打出了具体判定值。
|
||
|
||
---
|
||
|
||
## 十、相关文档
|
||
|
||
- 关联 Issue: [wx/HL#7441](https://git.1814.love:8443/wx/HL/issues/7441)
|
||
- 关联 PR: [#7742](https://git.1814.love:8443/wx/HL/pulls/7742)
|
||
- 前置依赖:`#7439`(户级需求表与状态枚举)、`#5319`(vehicle-ready-reset 端点首次交付)、`#3857`(vehicle-ready 端点首次交付)
|
||
- 相关分册:`#7441` 正式用车需求声明四端点、确认行程清单房车安排短路判定(消费本单产出的完成状态)、结算核单车侧闸门升级(同样消费本单产出的完成状态)
|
||
|
||
## 关联 / 联系人
|
||
|
||
### 链接
|
||
|
||
- **Issue**: [#7441](https://git.1814.love:8443/wx/HL/issues/7441)
|
||
- **PR**: [#7742](https://git.1814.love:8443/wx/HL/pulls/7742)
|
||
|
||
### 联系人
|
||
|
||
- **后端负责人**: @wx
|
||
|