changelog-filename-gate / validate (push) Failing after 1s
- #8629 出行人/大交通新增的幂等键补上对象身份段,同订单录入第二个对象不再被误拒 - #8630 团期最后一户取消后自动复位 requirement_confirmed 与整团用车需求(CONFIRMED→DRAFT), 并写 BATCH_REQUIREMENT_REOPENED 时间线(trigger=ALL_SUB_ORDERS_CANCELLED) Refs #8629 Refs #8630 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
149 行
10 KiB
Markdown
149 行
10 KiB
Markdown
---
|
||
schema: "hl-changelog/v2"
|
||
ticket: "8630"
|
||
title: "团期活跃子订单清零后,自动复位团级需求确认与整团用车需求"
|
||
consumer: "admin"
|
||
author: "wx(GIT)"
|
||
change_type: "修复"
|
||
backend_status: "deployed"
|
||
gateway_status: "not_required"
|
||
frontend_status: "pending"
|
||
frontend_owner: ""
|
||
frontend_ref: ""
|
||
target_release: ""
|
||
verified_at: ""
|
||
status_note: "hl-order-service-v3 dev-v3 合入提交 8e00cc98bc(PR #8640,同 PR 还含 #8631 的两处纯 javadoc 订正,与本单契约无关,未在本文档中提及)。本次改动不涉及任何接口的请求/响应结构变化,只影响既有字段在特定场景下的取值。"
|
||
updated_at: "2026-09-30"
|
||
base: "dev-v3"
|
||
---
|
||
|
||
# 团期活跃子订单清零后,自动复位团级需求确认与整团用车需求
|
||
|
||
> **存放目录**: 二期(order-v3/fleet)→ `changelogs-v2/2026-09/`
|
||
>
|
||
> **服务**: hl-order-service-v3
|
||
> **PR**: [#8640](https://git.1814.love:8443/wx/HL/pulls/8640)
|
||
> **Issue**: [#8630](https://git.1814.love:8443/wx/HL/issues/8630)
|
||
> **日期**: 2026-09-30
|
||
> **影响范围**: 团期详情页「需求确认」状态、整团用车需求状态;不涉及任何请求/响应字段结构变化
|
||
|
||
---
|
||
|
||
## ⚠️ 关键变化
|
||
|
||
**改前**:一个团期整体确认需求(`requirementConfirmed=true`)、且整团用车需求也已确认(`CONFIRMED`)之后,如果该团期名下的子订单被逐个取消,直到**最后一个活跃子订单也被取消**,系统没有任何收尾动作——`requirementConfirmed` 停留在 `true`,整团用车需求状态停留在 `CONFIRMED`。此时团期详情页、车务待办侧仍显示「需求已确认」「用车已确认」,而这个团实际上已经一户不剩,且这个不一致**不报错、不告警**,只能靠人工发现。
|
||
|
||
**改后**:当一个团期的活跃子订单数(`order_status != CANCELLED` 的子订单条数)由非零变为零时,系统自动做两件事:
|
||
1. 若整团用车需求当前处于 `CONFIRMED`,自动退回 `DRAFT`(不是 `PENDING_RECONFIRM`);
|
||
2. 若团级 `requirementConfirmed` 当前为 `true`,自动清为 `false`。
|
||
|
||
只要这两项里至少有一项真的发生了状态变化,就会在该团期的时间线写入一条 `BATCH_REQUIREMENT_REOPENED`(需求重开待确认)事件,`extra` 中携带 `trigger: "ALL_SUB_ORDERS_CANCELLED"`、`orderId`(触发收尾的最后一个取消子订单 ID)、`requirementConfirmedCleared`(布尔)、`groupVehicleRequirementWithdrawn`(布尔)。两项复位互相独立、各自按条件写,天然幂等;两项都无需变化时(例如本来就是 `false`/`DRAFT`)不写时间线、不产生噪声。
|
||
|
||
本次改动**不涉及任何请求体或响应体的字段增删/改类型**,纯粹是既有字段在「团期归零」这一新增场景下会被系统自动改写取值。
|
||
|
||
---
|
||
|
||
## 二、影响的字段与读取入口
|
||
|
||
以下字段的**读取路径未变**,本次改动只影响它们在「团期活跃子订单清零」这一时刻之后的取值:
|
||
|
||
| 字段 | 归属接口(示例) | 改前在团期归零后的取值 | 改后 |
|
||
|------|------|------|------|
|
||
| `requirementConfirmed` | `GET /v3/admin/order/group-batch/{groupBatchId}`(`GroupBatchDetailRespVO`)及房务看板系列 VO | 停留在归零前的最后取值(可能仍是 `true`) | 若归零前为 `true`,归零后自动变为 `false` |
|
||
| 整团用车需求 `status` | 整团用车需求相关读端点(`GroupVehicleRequirementRespVO.status`) | 停留在归零前的最后取值(可能仍是 `CONFIRMED`) | 若归零前为 `CONFIRMED`,归零后自动变为 `DRAFT` |
|
||
| 团期时间线 | 团期时间线读端点 | 归零无任何留痕 | 新增一条 `BATCH_REQUIREMENT_REOPENED` 事件(仅当至少一项真的被复位时才写) |
|
||
|
||
---
|
||
|
||
## 三、精确触发条件
|
||
|
||
- **"活跃子订单"的判据** = `order_status != CANCELLED`(含 `PENDING_PAY`、`COMPLETED` 等非取消状态均计入活跃;与既有人数计数、归团回填、对账口径一致)。**不是**看板上「免闸户不计」的统计口径——房务免闸的户在用车这一侧仍可能要车,因此不按闸门维度扣减分母。
|
||
- **收尾时点** = 该团期的活跃子订单数由非零变为零的那一刻(子订单取消事务提交之后)。覆盖以下所有取消入口:admin 出行前取消、C 端取消、退团审批、流团逐户取消、通用 `transition()` 的 CANCEL 分支、超时自动取消——这些入口最终都汇流到同一个内部取消事件,因此逐个入口都会触发本收尾逻辑。
|
||
- **不覆盖**的取消路径:
|
||
- `TERMINATE`(出行中终止行程 → `COMPLETED`)是与 `CANCEL`(→ `CANCELLED`)完全不同的状态路径,不会触发本收尾——出行中终止行程不代表这个团没有人,语义上也不应该清需求确认。
|
||
- 直接修改数据库、绕过应用层的取消不会触发(无代码路径可挂载)。
|
||
- **用车需求只在 `CONFIRMED` 这一档被自动退回**:`DRAFT`/`PENDING_RECONFIRM` 本来就不是已确认,无需处理;`DISPATCHED`(已发车务)/`DONE`(配车完成)**不会**被自动撤回——车务可能已经接单甚至配完车,自动撤回等于单方面掀掉车务在办的工作,这属于另一个业务决策,本次不做;`CANCELLED` 是流团终态,不会走到本路径。
|
||
|
||
---
|
||
|
||
## 六、边界行为(刻意不做的部分)
|
||
|
||
- **`batchStatus`(团期阶段)本次不变**:一个活跃子订单数归零的团期,其 `batchStatus` 可以继续停留在任意阶段(例如 `RESOURCE_PREPARING`「资源准备中」),不会被自动置为 `CANCELLED` 或退回 `RECRUITING`——自动改阶段涉及流团审批合规性判断,留给后续工单单独定案。前端据此判断"团是否还有效"时,**不能只看 `batchStatus`**,需要结合活跃子订单数或 `requirementConfirmed`/用车需求状态的复位来综合判断。
|
||
- **`DISPATCHED`/`DONE` 的用车需求不会被回退**:见上节"三、精确触发条件"。
|
||
- **房务就绪标记(`hotel_ready`)本次不动**:本收尾只处理 `requirementConfirmed` 与整团用车需求两项,房务侧的就绪标记不在本次收尾范围内,两者目前不对称——这是已知缺口,不在本单范围内一并解决。
|
||
- **不做历史数据回填**:已经处于"团期归零但需求确认/用车需求未复位"这种旧脏数据状态的历史团期,本次改动不会自动纠正,只对本次改动上线之后新发生的"归零"事件生效。
|
||
|
||
---
|
||
|
||
## 六.5、枚举 / 数据字典
|
||
|
||
整团用车需求状态 `GroupVehicleRequirementStatus`(本次改动涉及的部分状态,完整枚举 6 值):
|
||
|
||
| 值 | 中文名 | 说明 |
|
||
|------|------|------|
|
||
| DRAFT | 草稿 | 本次改动的复位目标 |
|
||
| CONFIRMED | 已确认 | 本次改动的复位起点(仅此档会被自动退回) |
|
||
| PENDING_RECONFIRM | 待重新确认 | 不受本次改动影响 |
|
||
| DISPATCHED | 已发车务 | 不受本次改动影响(明确不回退) |
|
||
| DONE | 配车完成 | 不受本次改动影响(明确不回退) |
|
||
| CANCELLED | 已取消 | 不受本次改动影响 |
|
||
|
||
团期时间线事件类型(本次涉及):
|
||
|
||
| 值 | 中文名 | 说明 |
|
||
|------|------|------|
|
||
| BATCH_REQUIREMENT_REOPENED | 需求重开待确认 | 复用既有事件类型(此前用于"定制师在整团确认后自行改需求"场景),本次新增一种触发来源;两种来源在 `extra.trigger` 字段区分,本次新增值为 `ALL_SUB_ORDERS_CANCELLED` |
|
||
|
||
---
|
||
|
||
## 六.6、修改前后对比
|
||
|
||
### 行为级对比
|
||
|
||
| 场景 | 改前 | 改后 |
|
||
|------|------|------|
|
||
| 团期活跃子订单数由非零变为零,此前 `requirementConfirmed=true` | 停留 `true`,无提示 | 自动变为 `false` |
|
||
| 团期活跃子订单数由非零变为零,此前整团用车需求 `CONFIRMED` | 停留 `CONFIRMED`,无提示 | 自动退回 `DRAFT` |
|
||
| 团期活跃子订单数由非零变为零,此前两项均已是"未确认"状态 | 无变化 | 无变化,不写时间线(幂等,无噪声) |
|
||
| 团期时间线 | 归零无任何记录 | 至少一项被复位时,新增一条 `BATCH_REQUIREMENT_REOPENED` 事件,`extra.trigger=ALL_SUB_ORDERS_CANCELLED` |
|
||
|
||
---
|
||
|
||
## 六.7、影响评估
|
||
|
||
- **是否破坏向后兼容**: 否——字段名称、类型、接口路径均未变,只是取值在新场景下会被后端自动改写
|
||
- **前端是否必须同步上线**: 视前端现有逻辑而定——若前端曾假设"一旦确认过就不会自动变回未确认"并据此做过缓存/跳过重复请求之类的优化,需要重新核对该假设在"团期归零"场景下不再成立
|
||
- **需要前端注意的读取口径变化**: `requirementConfirmed`、整团用车需求 `status` 在团期活跃子订单归零后可能被系统自动改写,不再只由人工操作(确认/打回)改变;`batchStatus` 不受此次自动复位联动,读取时不能用 `batchStatus` 代替对这两个字段的直接读取
|
||
|
||
---
|
||
|
||
## 七、不影响范围
|
||
|
||
- **仅影响**: 团期活跃子订单数归零这一时刻,`requirementConfirmed` 与整团用车需求 `CONFIRMED` 状态的自动复位
|
||
- **零影响**:
|
||
- 团期阶段 `batchStatus` 的取值与流转规则(见"六、边界行为")
|
||
- 房务就绪标记 `hotel_ready`
|
||
- 整团用车需求 `DISPATCHED`/`DONE`/`PENDING_RECONFIRM`/`CANCELLED` 四档的自动流转规则
|
||
- 所有接口的请求体、响应体字段结构(本次零新增、零删除、零改类型)
|
||
- 团期归零之前已经存在的历史脏数据(不做回填)
|
||
- 受控重配窗口相关的 `BATCH_VEHICLE_REQUIREMENT_REOPENED` 事件(另一独立事件类型,与本次复用的 `BATCH_REQUIREMENT_REOPENED` 不是同一个)
|
||
|
||
---
|
||
|
||
## 十、相关文档
|
||
|
||
- 关联 Issue: [wx/HL#8630](https://git.1814.love:8443/wx/HL/issues/8630)
|
||
- 关联 PR: [wx/HL#8640](https://git.1814.love:8443/wx/HL/pulls/8640)
|
||
|
||
## 关联 / 联系人
|
||
|
||
### 链接
|
||
|
||
- **Issue**: [#8630](https://git.1814.love:8443/wx/HL/issues/8630)
|
||
- **PR**: [#8640](https://git.1814.love:8443/wx/HL/pulls/8640)
|
||
- **Merge commit**: [8e00cc98bc](https://git.1814.love:8443/wx/HL/commit/8e00cc98bc)
|
||
|
||
### 联系人
|
||
|
||
- **后端负责人**: @wx
|