12 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 | 7529 | 团期转期后按目标期重排逐日行程 + 重版用车需求(住宿不重版)+ 三条 fail-fast 前置守卫 | admin | jw(GIT) | 修改接口 | deployed | not_required | not_required | mmg | #7529 | 2026-09-14 | 转期接口请求体 / 响应体结构与既有 warning 文案一字未改;唯一前端相关变化是 3 个新错误码(589575/589576/589577)的友好提示映射(message 体后端已给全文,不映射也能原样弹出);另转期成功后该户用车需求落 PENDING_REVIEW,车务复核入口沿用既有页面。无新增出参字段、零 DDL、零网关路由改动。【前端 hl-admin】判 not_required(2026-09-14):请求/响应/warnings 一字未改;3 新码 message 后端给全文,本项目不建错误码字典(拦截器透 message),自然提示零改动;用车 PENDING_REVIEW 复核入口沿用既有页面。 | 2026-09-14 | dev-v3 |
order-v3: 团期转期后重排逐日行程 + 重版用车需求 + 三条 fail-fast 守卫
服务: hl-order-service-v3 PR: #7638 Issue: #7529
⚠️ 关键变化
🟡 行为修复(后端内部数据纠正为主,响应契约不变):
- 转期后逐日行程按目标期出发日整体位移。改前
order_itinerary_day.day_date停在源期日期(行程单、出团通知书、小程序行程页逐天日期全错);改后day_date = 目标期 depart_date + day_number - 1。 - 转期后该户用车需求重版,服务日期三列(
service_start_date/service_end_date/service_dates)按位移后的逐日行程冻结出目标期口径;旧行置is_active=0(源期日期原样保留、不被改写),新行状态落PENDING_REVIEW。住宿需求不重版(无绝对日期列,入住日由读侧按主单depart_date反推,自动跟随)。 - 源期与目标期「整团需求已确认」标记各清 0 一次,各写一条
BATCH_REQUIREMENT_REOPENED团级时间线(目标期显式重开,不依赖该户有无用车需求)。 - 三条新增 fail-fast 前置守卫,全部零写入:目标期缺出发日 → 589575;目标期日期跨度 ≠ 订单行程天数 → 589577;该户用车需求正处于最终确认占用窗口 → 589576。
请求体、响应体字段与 warnings 文案本单一字未改;无新增出参字段;无 DDL;无网关路由改动。
一、背景
团期「转订单(子订单跨期转入)」把子订单从源期迁到目标期时,主单 depart_date/return_date 已按目标期刷新,但两处冻结了绝对日期的数据没跟着走:逐日行程 day_date 与用车需求的三列服务日期都还停在源期,导致行程单错日、车务按源期派车(目标期出发日没车)。本单在 GroupBatchTransferService.transferIn 已有的同一事务内补齐这两件事,并把源期/目标期「整团需求已确认」标记各重开一次;同时为「重排」补三条 fail-fast 前置守卫,防止在缺基准数据时把订单写成「末天≠返程日」的脏数据。
二、变更接口清单
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|---|---|---|---|---|---|
| 1 | 转订单(子订单跨期转入) | POST | /v3/admin/order/group-batch/:groupBatchId/sub-order/:orderId/transfer-in |
修改 | 事务内新增:逐日行程位移 + 用车需求重版 + 两团需求确认标记重开 + 三条 fail-fast 守卫(589575/589576/589577)。请求/响应结构不变 |
三、接口详情
1. 转订单(子订单跨期转入) POST /v3/admin/order/group-batch/:groupBatchId/sub-order/:orderId/transfer-in
VO: TransferSubOrderReqVO → Result<TransferSubOrderRespVO>
使用场景
团期管理台「转订单」弹窗,把同产品其他期的一个子订单转入本期。path 上的 groupBatchId 是转入期(本期),源期在 body 的 fromGroupBatchId。沿用既有鉴权与网关路由(/v3/admin/** 已覆盖),本单不改。
入参字段表
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| groupBatchId | path | string(Long) | 是 | 雪花 ID | 转入期(本期)团期主订单 ID |
| orderId | path | string(Long) | 是 | 雪花 ID | 待转入的子订单 ID |
| fromGroupBatchId | body | string(Long) | 是 | @NotNull | 源期团期主订单 ID |
| reason | body | string | 否 | @Size(max=512) | 转期原因;为空落「管理员手动转期」 |
| notify | body | boolean | 否 | 默认 true | 转入后是否通知客户 |
出参字段表
(结构一字未改,仅列字段以便前端对照)
| 字段 | 类型 | 说明 |
|---|---|---|
| orderId | string(Long) | 被转子订单 ID |
| fromBatchNo | string | 源期期号 |
| toBatchNo | string | 目标期期号 |
| oldOrderAmount | string(decimal) | 转期前应收 |
| newOrderAmount | string(decimal) | 按目标期报价重算后的应收 |
| paidAmount | string(decimal) | 已付 |
| newBalanceDue | string(decimal) | 待收尾款 |
| warnings | array | 非阻断提示(本单不增不减其中任何一条,如「该户合同/保险已出具,转期后需人工重出」) |
请求示例
POST /v3/admin/order/group-batch/2099073597908647938/sub-order/2099073597711515649/transfer-in
Authorization: Bearer <admin token>
Content-Type: application/json
{ "fromGroupBatchId": 2099078774497681409, "reason": "客户改期", "notify": false }
响应示例
{
"code": 200,
"msg": "成功",
"data": {
"orderId": "2099073597711515649",
"fromBatchNo": "Q202612192099078773096828929",
"toBatchNo": "Q202612182099073596763615233",
"oldOrderAmount": "2000.00",
"newOrderAmount": "2000.00",
"paidAmount": "0.00",
"newBalanceDue": "2000.00",
"warnings": ["该户合同/保险已出具,转期后需人工重出"]
}
}
空数据 / 降级响应
该户没有用车需求时重版链路返 0、不报错,行程仍位移、两团需求确认标记仍各清 0(证明标记重开不依赖用车链路);该户没有逐日行程时接口仍 200,用车新 active 行服务日回退取目标期 depart_date/end_date。
错误响应
{ "code": 589577, "msg": "目标团期日期跨度(4 天)与该订单行程天数(3 天)不一致,请先核对团期日期或订单行程后再转期", "data": null }
三条新增码(均 HTTP 200 + 业务码 + 零写入):589575 目标期未设置出发日期;589576 该户用车需求正在最终确认中;589577 目标期日期跨度与订单行程天数不一致。既有码 589500/589501/589510/589512/589524~589528/589560 原样保留。
业务边界
- 转期只允许源期与目标期均在「招募中 / 资源筹备中」,且子订单状态在「待付款 / 待出行」。
- 三条 fail-fast 守卫与「源期已分房(589560)」「在途退单(589512)」守卫一样,均在两团行栅栏(本事务第一条 DB 语句)之后、任何本地写之前执行;命中即整笔零写入。
- 589577 天数守卫按定案 16 的 null 跳过口径:
order_main.trip_days为 null 时放行(守卫非恒真);现行 schema 该列tinyint NOT NULL,该分支以单测取证。 - 顺序固定不可调换:先落库逐日行程位移,再重版用车(服务日先取逐日行程、为空才回退主单日期)。
- 合同/保险不自动作废重出(团期级合同保险能力本就未实现),沿用既有
warnings文案提示人工处理。
四、契约约束与正确调用方式
- 金额四字段是
BigDecimal序列化为字符串,勿按 number 解析;orderId亦为字符串形态防大整数精度丢失。 - 转期成功后该户用车需求为新版本(旧版本
is_active=0),车务侧应按新 active 行的目标期服务日派车。 - 589575/589576/589577 的
message由后端给全文,前端可直接弹出;如需友好化映射按码映射即可。
五、数据库行为
- 无表变更、无 Flyway、无新增列、无索引调整、无 H2
*-schema.sql改动。 - 写入均落既有表:
order_itinerary_day.day_date(位移)、order_vehicle_requirement(重版新行 + 旧行置 inactive)、order_group_batch.requirement_confirmed(CAS 清 0)、group_batch_status_log(BATCH_REQUIREMENT_REOPENED时间线,该 event_type 为既有枚举)。
六、边界行为
- 转期是管理员侧写口,两团行栅栏按 groupBatchId 数值升序各下一次锁,防两个管理员对拉互转造成死锁。
- 目标期
hotel_ready转期后置 false(既有行为,不变);源期分房必须为空(增补 C8b 不变量断言,转期入口已用 589560 拦住已分房户)。 - 三条 fail-fast 守卫中,用车最终确认占用探针用「不抛异常的探针」(返回 false 而非标脏事务),命中转 589576,不产生 HTTP 500 /
UnexpectedRollbackException。
六.6、修改前后对比
| 维度 | 改前 | 改后 |
|---|---|---|
order_main.depart_date/return_date |
改为目标期 | 不变(仍改为目标期) |
order_itinerary_day.day_date |
不动(停在源期日期) | 按目标期 depart_date 整体位移 |
| 该户用车需求 | 不重版(三列服务日期留在源期) | 重版出新 active 版本,服务日按位移后行程冻结,状态落 PENDING_REVIEW |
| 该户住宿需求 | 不重版 | 不重版(入住日随主单 depart_date 自动跟随) |
| 源期 / 目标期「整团需求已确认」标记 | 不变 | 各 CAS 清 0 + 各写一条 BATCH_REQUIREMENT_REOPENED 时间线 |
| 目标期缺出发日 / 行程天数漂移 / 用车正在最终确认 | 静默成功或 500 | 分别 589575 / 589577 / 589576,零写入 |
| 请求 / 响应结构、warnings、错误码既有项、DDL、网关 | — | 一字未改 / 零改动 |
六.7、影响评估
- 兼容性:请求体、响应体字段与结构完全不变,未新增出参字段、未新增 warning 文案;未消费新错误码的前端页面无需改动即可继续工作。
- 需要前端动的(均非阻断):
- 3 个新错误码 589575/589576/589577 的友好提示映射(message 后端已给全文,不映射也能原样弹出);
- 知悉转期后该户用车需求为新版本、状态
PENDING_REVIEW,车务复核入口沿用既有页面。
- 性能:位移逐日行程 + 重版一户用车 + 两团各一次 CAS 重开,均在既有转期事务内,成本可忽略。
- 正确性修复:改前转期后行程单 / 出团通知书逐天日期错、车务按源期派车——这是修复不是回归。
七、不影响范围
- 转期请求体 / 响应体字段名称、类型、结构、warnings 文案一字未改。
- 无网关路由改动、无 Feign/MQ 改动、无 DDL、既有错误码一个未改。
- 住宿需求不重版;出行完毕、其它团期端点行为不变。
八、测试环境已验证
2026-09-14 TEST 网关(自签 admin token)+ 真 MySQL 造数三路取证,工单 #7529 的 AC-1 ~ AC-16 逐条通过:
- 归属迁移(AC-16)、逐日行程按目标期重排(AC-2)、用车重版且服务日为目标期口径 + 旧行置 inactive 且源期日期保留(AC-3)、住宿不重版(AC-4,前后 requirement_id/version/submitted_at 一致)、房务侧入住日随目标期跟随且引用未重版的住宿 v1(AC-5)、两团 requirement_confirmed 清 0 + 各一条
BATCH_REQUIREMENT_REOPENED(AC-6)、无用车户 / 无行程户不报错回退正确(AC-7/AC-8)。 - 三条 fail-fast 均返对应码 + 四表逐字节零写入:589575(AC-9)、589577 正反两向含 trip_days=null 放行的单测取证(AC-10)、589576 非 500(AC-11);既有守卫未削弱:589560 源期已分房
{0}为真实行数、行栅栏 InOrder 单测证明为本事务第一条 DB 语句(AC-12)。 - 号段:新增码恰为 589575/589576/589577 三个,与 dev-v3 基线 diff 无越界无重号(AC-13);CODE_RULES 红线逐条通过(AC-14)。
- 全量单测:
mvn -o -pl hl-order-service-v3 -am test— order-v3 模块 10584 test / 0 failure / 0 error / 7 skipped,BUILD SUCCESS(AC-15)。
十、相关文档
- 工单 #7529
- 全过程记录:HL 仓
dev-records/records/2026-09-14-local-7529-transfer-reschedule.md
关联 / 联系人
- 后端:jw(已合入 dev-v3 + TEST 实测)
- 前端:mmg(3 个新错误码可选友好映射;知悉转期后用车需求为新版本、状态 PENDING_REVIEW)