- #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>
10 KiB
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 | 8630 | 团期活跃子订单清零后,自动复位团级需求确认与整团用车需求 | admin | wx(GIT) | 修复 | deployed | not_required | pending | hl-order-service-v3 dev-v3 合入提交 8e00cc98bc(PR #8640,同 PR 还含 #8631 的两处纯 javadoc 订正,与本单契约无关,未在本文档中提及)。本次改动不涉及任何接口的请求/响应结构变化,只影响既有字段在特定场景下的取值。 | 2026-09-30 | dev-v3 |
团期活跃子订单清零后,自动复位团级需求确认与整团用车需求
存放目录: 二期(order-v3/fleet)→
changelogs-v2/2026-09/服务: hl-order-service-v3 PR: #8640 Issue: #8630 日期: 2026-09-30 影响范围: 团期详情页「需求确认」状态、整团用车需求状态;不涉及任何请求/响应字段结构变化
⚠️ 关键变化
改前:一个团期整体确认需求(requirementConfirmed=true)、且整团用车需求也已确认(CONFIRMED)之后,如果该团期名下的子订单被逐个取消,直到最后一个活跃子订单也被取消,系统没有任何收尾动作——requirementConfirmed 停留在 true,整团用车需求状态停留在 CONFIRMED。此时团期详情页、车务待办侧仍显示「需求已确认」「用车已确认」,而这个团实际上已经一户不剩,且这个不一致不报错、不告警,只能靠人工发现。
改后:当一个团期的活跃子订单数(order_status != CANCELLED 的子订单条数)由非零变为零时,系统自动做两件事:
- 若整团用车需求当前处于
CONFIRMED,自动退回DRAFT(不是PENDING_RECONFIRM); - 若团级
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
- 关联 PR: wx/HL#8640
关联 / 联系人
链接
- Issue: #8630
- PR: #8640
- Merge commit: 8e00cc98bc
联系人
- 后端负责人: @wx