GET .../adjustment/snapshot 出参加 schedule 块+travelers脱敏→明文(破坏性)+editableTabLocksHint门控; POST .../adjustment/submit 启用 updates.travelers(原空转)+新增 updates.schedule; 出参加 newDepartDate/newReturnDate/newFlowStatus+changedDims.DEPART_DATE; 错误码 587034-587038;两tab窗口(出行人≤待出行/改期≤待确认)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
8.8 KiB
订单调整弹窗:出行人 tab + 改期 tab(管理后台)
- 端类型:管理后台
- 变更类型:修改接口(出参/入参扩展 + travelers 脱敏→明文,含破坏性)
- 关联 Issue:#4458(+ follow-up #4477) PR:#4468 / #4478
- 日期:2026-06-27
① 接口背景
订单调整弹窗的两个端点(GET .../adjustment/snapshot 预填 + POST .../adjustment/submit 统一提交)本期改造:
- 原「出行人数」tab(仅改 adultCount/childCount 整数)→「出行人」tab:管理真实出行人名单(增/删/改),人数由名单按类型自动派生,加减人触发算价。
- 新增「改期」tab:在"确认订单行程"之前允许修改出发日期;改期后订单退回「资源准备中」+ 配房配车重置。
两 tab 所有数据一次 submit 一起提交,零新端点、零 DDL。
② 变更清单
| 方法 | 路径 | 变更 |
|---|---|---|
| GET | /v3/admin/order/{id}/adjustment/snapshot |
出参新增 schedule 块;travelers 脱敏→明文;editableTabLocksHint 按状态门控 PEOPLE/SCHEDULE |
| POST | /v3/admin/order/{id}/adjustment/submit |
入参 updates.travelers 启用(原空转)+ 新增 updates.schedule;出参新增改期字段 |
统一响应 Result<T>:{ code, message, data, success },code=200 成功。
破坏性提示:snapshot.travelers 由脱敏视图改为明文视图(姓名/证件/手机为真实值,供 admin 编辑表单回填)。前端如有按脱敏展示逻辑需自行脱敏。
③ 可改窗口(两 tab 不同,前端按 editableTabLocksHint 控制)
| tab | 可改窗口 | 起锁点 |
|---|---|---|
| 出行人(PEOPLE) | flowStatus ≤ 待出行(PENDING_DEPARTURE) | 出行中 TRAVELLING 起锁 |
| 改期(SCHEDULE) | flowStatus ≤ 待确认(PENDING_CONFIRM) | 待出行 PENDING_DEPARTURE 起锁 |
④ 入参
snapshot
无变化(仅 path id)。
submit —— updates 扩展
{
"editReason": "客户加1人并改出发日", // ≥5字,强制审计
"tabLocks": ["PEOPLE","SCHEDULE"], // 本次改了哪些 tab
"confirmDiffHash": "...", // 防并发(拿 snapshot 时记录回送)
"updates": {
"travelers": { // 出行人 tab(原定义但未生效,本期启用)
"add": [ { "name":"李四","travelerType":"ADULT","idCardType":"ID_CARD","idCardNo":"...","phone":"...","birthday":"1990-03-07" } ],
"update": [ { "id":"92001","name":"张三","idCardNo":"..." } ],
"remove": [ "92003" ] // 出行人 id
},
"schedule": { "departDate": "2026-07-15" } // 改期 tab(新增),仅传新出发日
// 仍兼容 basic / itinerary / hotelRequirement / vehicleRequirement / feeChanges
}
}
travelers 行字段:name / travelerType(ADULT/CHILD/YOUNG_CHILD/BABY)/ idCardType / idCardNo / phone / birthday;update 项带 id。
schedule:departDate(yyyy-MM-dd,必填非空;returnDate 由后端按行程天数派生,不传)。
⑤ 出参
snapshot —— 新增 schedule 块
| 字段 | 类型 | 说明 |
|---|---|---|
| schedule.departDate | String(date) | 当前出发日 |
| schedule.returnDate | String(date) | 当前返回日(派生) |
| schedule.tripDays | Integer | 行程天数 |
| schedule.canEditDate | Boolean | 能否改期(flowStatus ≤ 待确认 = true) |
| schedule.lockReason | String | 不能改期时的原因(可改时 null) |
其余:travelers(现为明文:name/idCardNo/phone 真实值)、basic(含 adult/child/youngChild/baby 人数回显,编辑入口已移至出行人 tab)、editableTabLocksHint(含 PEOPLE/SCHEDULE 取决于状态)不变结构。
submit —— 新增字段
| 字段 | 类型 | 说明 |
|---|---|---|
| changedDims | Array | 本次变更维度,新增 DEPART_DATE(改期);出行人变人数为 HEADCOUNT |
| priceDelta | String(金额) | 价格差额(正=加费,负=优惠,0=无差额) |
| newDepartDate | String(date) | 改期后新出发日(改期时返回) |
| newReturnDate | String(date) | 改期后新返回日 |
| newFlowStatus | String | 改期后流程状态(恒 RESOURCE_PREPARING) |
| assignmentDeletedCount | Integer | 改期重置作废的配房配车 assignment 行数 |
⑥ 枚举 / 数据字典
- travelerType:ADULT 成人 / CHILD 儿童(6-12) / YOUNG_CHILD 幼童(2-5,占座不占床) / BABY 婴儿(0-1,不占座不占床)
- flowStatus(相关):RESOURCE_PREPARING 资源准备中 / PENDING_CONFIRM 待确认 / PENDING_DEPARTURE 待出行 / TRAVELLING 出行中
- changedDims:HEADCOUNT 人数 / DEPART_DATE 出发日期 / TRIP_DAYS 行程天数 / ITINERARY / HOTEL / VEHICLE
- editableTabLocksHint 取值:BASIC / PEOPLE / SCHEDULE / ITINERARY / HOTEL_REQ / VEHICLE_REQ / FEE
⑦ 错误码
| code | 含义 | 触发 |
|---|---|---|
| 587034 | 已出行,出行人不可调整 | flowStatus ≥ 出行中 时改出行人 |
| 587035 | 行程已确认,出发日期不可修改 | flowStatus ≥ 待出行 时改期(请取消重下) |
| 587036 | 团期子订单出行人调整暂不支持 | 团期子订单走出行人增删致人数变化(本期拦截) |
| 587037 | 出发日期格式非法,请使用 yyyy-MM-dd 格式 | schedule.departDate 格式错 |
| 587038 | 出发日期不能早于今天 | 改期到过去日期 |
| 581041 | 所选出发日期不可售或未配置价格 | 改期到无价格日历的日期 |
| 587002 | 订单已是终态不可调整 | COMPLETED/CANCELLED |
⑧ 示例
改期(成功)
请求:{ "editReason":"客户改出发日","tabLocks":["SCHEDULE"],"updates":{"schedule":{"departDate":"2026-06-27"}} }
响应:{ "code":200,"data":{ "changedDims":["DEPART_DATE","TRIP_DAYS"],"priceDelta":"0.00","newDepartDate":"2026-06-27","newReturnDate":"2026-06-29","newFlowStatus":"RESOURCE_PREPARING","assignmentDeletedCount":3 } }
出行人新增(成功)
请求:{ "editReason":"客户加1人","tabLocks":["PEOPLE"],"updates":{"travelers":{"add":[{"name":"李四","travelerType":"ADULT","idCardType":"ID_CARD","idCardNo":"...","phone":"138...","birthday":"1990-03-07"}]}} }
响应:{ "code":200,"data":{ "changedDims":["HEADCOUNT"],"priceDelta":"3105.00" } }(人数派生回写 order_main,价差落加费)
异常
- 改期到过去日期:
{ "code":587038,"message":"出发日期不能早于今天" } - 出行中改出行人:
{ "code":587034,"message":"已出行,出行人不可调整" }
⑨ 业务边界
- 出行人人数由名单按 travelerType 自动派生回写 order_main(4 档:成人/儿童/幼童/婴儿),不再手填。
- 算价:加减人 / 改期(价格日历差)由后端调产品侧 fetchQuote 权威重算差额,前端不传金额;差额落 order_surcharge(正)/ order_discount(负)。多 tab 同时提交时单次合并算价(终态 vs 原态),无交叉误差。
- 改期:改 departDate + returnDate 联动 + 全行程逐日 stayDate 位移 + 退回 RESOURCE_PREPARING + 配房配车作废重配;不涉及合同保险(合同保险在确认行程后才触发,改期发生在之前)。
- 出行人变更(已确认/已存在合同保险时)经 TravelerChangedEvent 自动作废重签。
- 团期子订单出行人增删致人数变化本期拦截(587036),团期容量联动后续专项。
⑩ 修改前后对比
| 修改前 | 修改后 | |
|---|---|---|
| 出行人数 tab | 仅改 adultCount/childCount 整数 | 管真实出行人名单,人数派生 |
| snapshot.travelers | 脱敏 | 明文(admin 编辑回填) |
| updates.travelers | 定义存在但 submit 空转不生效 | 启用(add/update/remove 落地) |
| 改期 | 禁止(出发日不可改) | 确认行程前可改,带级联 |
| submit 出参 | 无改期字段 | + newDepartDate/newReturnDate/newFlowStatus/assignmentDeletedCount + changedDims.DEPART_DATE |
⑪ 影响评估 / 回滚
- 破坏性:snapshot.travelers 脱敏→明文,前端展示需自行脱敏。其余为新增(向后兼容)。
- 前端尚未对接本弹窗两 tab,按此一次对接即可。
- 回滚:后端 revert PR #4468 #4478。
⑫ 注意事项
- Long ID + 金额均字符串化返回(防 JS 精度)。
- 改期/出行人为写操作,前端需防重复点击 + loading。
- 提交成功后刷新走 snapshot 重新拉取(改期后 flowStatus 已变 RESOURCE_PREPARING)。
- 改期所选新出发日须为产品可售日期(有价格日历),否则 581041。
⑬ 关联 / 联系人
- Issue:wx/HL#4458 ・ wx/HL#4477
- PR:wx/HL#4468 ・ wx/HL#4478
- 后端负责人:腰苏图
- 已部署测试服并网关实调验证通过(snapshot/改期/出行人三能力均生效)。