# 【修改接口·管理后台】调整订单出行人 tab 支持订单级紧急联系人提交 (#4908) > **PR**: #4909 | **服务**: hl-order-service-v3 | **更新时间**: 2026-07-11 18:00 ## 1. 接口背景 调整订单弹窗的出行人 tab 已能读取订单级紧急联系人姓名和电话,但提交接口此前只能通过 `updates.travelers` 提交出行人增删改,无法在同一个 tab 内提交订单级紧急联系人。 本次在统一提交接口中新增 `updates.people` 结构,前端可以在出行人 tab 一次性提交订单级紧急联系人和出行人增删改。 ## 2. 变更清单 | # | 接口 | 方法 | 路径 | 变更类型 | 说明 | |---|------|------|------|----------|------| | 1 | 调整订单统一提交 | POST | `/v3/admin/order/{orderId}/adjustment/submit` | 修改接口 | 入参新增 `updates.people`,承载订单级紧急联系人与出行人增删改 | | 2 | 调整记录变更项 | - | `items[].type` | 修改枚举 | 新增 `EMERGENCY_CONTACT`,用于表示订单级紧急联系人变更 | ## 3. 接口详情 ### 3.1 调整订单统一提交 - **使用场景**: 管理后台调整订单弹窗点击提交时调用;本次主要服务出行人 tab。 - **认证**: 管理后台 JWT。 - **幂等性**: 非幂等;每次提交会按请求内容生成调整记录。 - **路径**: `POST /v3/admin/order/{orderId}/adjustment/submit` ## 4. 入参 ### 4.1 路径参数 | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | `orderId` | Long/String | 是 | 订单 ID,雪花 ID 建议前端按字符串传递 | ### 4.2 请求体总结构 | 字段 | 类型 | 必填 | 说明 | 校验规则 | |------|------|------|------|----------| | `updates` | Object | 是 | 各子域改动容器 | 不能为 null,且至少包含一个有效子域 | | `updates.people` | PeopleUpdate | 否 | 出行人 tab 新契约;推荐前端后续使用该字段提交出行人 tab | 本字段存在时会走 PEOPLE 编辑窗口校验 | | `updates.travelers` | TravelerBatch | 否 | 旧版出行人增删改契约 | 保留兼容;当 `updates.people.travelers` 同时存在时,优先使用 `updates.people.travelers` | | `updates.schedule` | Object | 否 | 改期子域 | 本次未变 | | `updates.itinerary` | Object | 否 | 行程子域 | 本次未变 | | `updates.hotelRequirement` | Object | 否 | 房需求子域 | 本次未变 | | `updates.vehicleRequirement` | Object | 否 | 车需求子域 | 本次未变 | ### 4.3 PeopleUpdate 字段 | 字段 | 类型 | 必填 | 说明 | 校验规则 | |------|------|------|------|----------| | `emergencyContactName` | String | 否 | 订单级紧急联系人姓名;不传表示不修改姓名 | 传入时会 trim;trim 后不能为空;姓名格式不合法时返回姓名格式相关错误 | | `emergencyContactPhone` | String | 否 | 订单级紧急联系人电话;不传表示不修改电话 | 传入时会 trim;trim 后不能为空;必须为 11 位数字 | | `travelers` | TravelerBatch | 否 | 出行人增删改分组 | 与旧 `updates.travelers` 结构相同 | 说明: - 只修改紧急联系人时,可以传 `travelers` 为空数组或不传 `travelers`。 - 只提交出行人增删改时,可以只传 `updates.people.travelers`。 - 同时传 `updates.people.travelers` 和旧 `updates.travelers` 时,本次以后服务端优先读取 `updates.people.travelers`。 ### 4.4 TravelerBatch 字段 | 字段 | 类型 | 必填 | 说明 | 校验规则 | |------|------|------|------|----------| | `add` | Array | 否 | 新增出行人列表 | 空数组表示本次不新增 | | `update` | Array | 否 | 更新出行人列表 | 每项必须带 `id` 才能定位已有出行人 | | `remove` | Array | 否 | 删除出行人 ID 列表 | 空数组表示本次不删除 | ### 4.5 TravelerEdit 字段 | 字段 | 类型 | 必填 | 说明 | 校验规则 | |------|------|------|------|----------| | `id` | Long/String | 更新时必填 | 出行人记录 ID | 新增时可不传 | | `name` | String | 否 | 出行人姓名 | 规则沿用既有出行人编辑逻辑 | | `idType` | String | 否 | 证件类型 | 例如 `ID_CARD` | | `idNo` | String | 否 | 证件号 | 规则沿用既有出行人编辑逻辑 | | `phone` | String | 否 | 手机号 | 规则沿用既有出行人编辑逻辑 | | `travelerType` | String | 否 | 出行人类型 | `ADULT` / `CHILD` 等既有取值 | | `birthday` | String | 否 | 出生日期 | `yyyy-MM-dd` | | `remark` | String | 否 | 备注 | 可为空 | ## 5. 出参 ### 5.1 响应字段 | 字段 | 类型 | 说明 | |------|------|------| | `code` | Integer | 统一响应码,成功为 `200` | | `message` | String | 响应消息 | | `success` | Boolean | 统一响应派生字段;`code=200` 时为 `true` | | `data.success` | Boolean | 调整订单提交是否成功 | ### 5.2 成功响应结构 ```json { "code": 200, "message": "成功", "success": true, "data": { "success": true } } ``` ## 6. 枚举 / 数据字典 ### 6.1 调整记录变更项类型 `items[].type` 所属字段:`GET /v3/admin/order/{orderId}/adjustment-record` 响应里的 `items[].type`。 | 值 | 中文 | 说明 | |----|------|------| | `HEADCOUNT` | 出行人数变化 | 成人、儿童、幼童、婴儿数量变化 | | `DEPART_DATE` | 出发日期调整 | 改期产生 | | `TRIP_DAYS` | 行程天数变化 | 行程增减天产生 | | `EDIT_NODE` | 编辑行程节点 | 行程节点价格或数量等变化 | | `ADD_NODE` | 新增行程节点 | 行程新增节点产生 | | `REMOVE_NODE` | 删除行程节点 | 行程删除节点产生 | | `HOTEL_REQ` | 酒店需求调整 | 房需求调整产生 | | `VEHICLE_REQ` | 车辆需求调整 | 车需求调整产生 | | `TRAVELER_EDIT` | 出行人资料修改 | 已有出行人字段修改产生 | | `EMERGENCY_CONTACT` | 订单级紧急联系人变更 | 本次新增;修改 `updates.people.emergencyContactName` 或 `updates.people.emergencyContactPhone` 后产生 | ### 6.2 证件类型 `TravelerEdit.idType` | 值 | 中文 | 说明 | |----|------|------| | `ID_CARD` | 身份证 | 既有出行人证件类型 | ### 6.3 出行人类型 `TravelerEdit.travelerType` | 值 | 中文 | 说明 | |----|------|------| | `ADULT` | 成人 | 既有出行人类型 | | `CHILD` | 儿童 | 既有出行人类型 | ## 7. 错误码 | code | 含义 | 触发场景 | |------|------|----------| | `581109` | 紧急联系人姓名和电话必填 | 本次提交了 `emergencyContactName` 或 `emergencyContactPhone`,但对应字段 trim 后为空 | | `581113` | 手机号格式非法(应为 11 位数字) | `updates.people.emergencyContactPhone` 不是 11 位数字 | | `587002` | 订单已是终态,不可调整 | 订单已结算、已取消、已退款等终态时提交调整 | | `587033` | 未检测到有效变更,无需提交 | `updates` 没有有效改动,或提交值与当前值一致 | | `587034` | 已出行,出行人不可调整 | 订单流程已到出行中或之后,提交 `people` 或 `travelers` | ## 8. 示例 ### 8.1 典型成功:只修改订单级紧急联系人 **请求** ```http POST /v3/admin/order/2075415561948315650/adjustment/submit Authorization: Bearer Content-Type: application/json ``` ```json { "updates": { "people": { "emergencyContactName": "张三", "emergencyContactPhone": "13800000000", "travelers": { "add": [], "update": [], "remove": [] } } } } ``` **响应** ```json { "code": 200, "message": "成功", "success": true, "data": { "success": true } } ``` ### 8.2 典型成功:同时修改紧急联系人并新增出行人 **请求** ```http POST /v3/admin/order/2075415561948315650/adjustment/submit Authorization: Bearer Content-Type: application/json ``` ```json { "updates": { "people": { "emergencyContactName": "李四", "emergencyContactPhone": "13900000000", "travelers": { "add": [ { "name": "王五", "idType": "ID_CARD", "idNo": "110101199001011234", "phone": "13600000000", "birthday": "1990-01-01", "remark": "新增同行人" } ], "update": [], "remove": [] } } } } ``` **响应** ```json { "code": 200, "message": "成功", "success": true, "data": { "success": true } } ``` ### 8.3 边界:只使用新版 people.travelers,不修改紧急联系人 **请求** ```http POST /v3/admin/order/2075415561948315650/adjustment/submit Authorization: Bearer Content-Type: application/json ``` ```json { "updates": { "people": { "travelers": { "add": [], "update": [ { "id": "70001001", "phone": "13700000000" } ], "remove": [] } } } } ``` **响应** ```json { "code": 200, "message": "成功", "success": true, "data": { "success": true } } ``` ### 8.4 异常:紧急联系人电话格式非法 **请求** ```http POST /v3/admin/order/2075415561948315650/adjustment/submit Authorization: Bearer Content-Type: application/json ``` ```json { "updates": { "people": { "emergencyContactName": "张三", "emergencyContactPhone": "138" } } } ``` **响应** ```json { "code": 581113, "message": "手机号格式非法(应为 11 位数字)", "success": false, "data": null } ``` ## 9. 业务边界 - `updates.people.emergencyContactName` 和 `updates.people.emergencyContactPhone` 均为可选字段;不传表示不修改对应字段。 - 传入紧急联系人字段时,空字符串不表示清空,会被视为非法入参。 - 仅修改订单级紧急联系人时,不会产生人数差价,也不会触发配房或配车重新配置。 - `updates.people.travelers` 复用既有出行人增删改逻辑;新增、更新、删除出行人可能继续触发既有人数差价和后续调整逻辑。 - 订单流程已到出行中或之后时,`people` 和旧 `travelers` 均不可提交。 ## 10. 修改前后对比 ### 10.1 入参字段对比 | 字段 | 修改前 | 修改后 | |------|--------|--------| | `updates.people` | 不支持 | 新增,作为出行人 tab 推荐提交结构 | | `updates.people.emergencyContactName` | 不支持 | 支持提交订单级紧急联系人姓名 | | `updates.people.emergencyContactPhone` | 不支持 | 支持提交订单级紧急联系人电话 | | `updates.people.travelers` | 不支持 | 支持提交出行人 `add/update/remove` | | `updates.travelers` | 支持 | 继续兼容;当与 `updates.people.travelers` 同时存在时优先使用 `updates.people.travelers` | ### 10.2 调整记录对比 | 字段 | 修改前 | 修改后 | |------|--------|--------| | `items[].type` | 无法表达订单级紧急联系人变更 | 新增 `EMERGENCY_CONTACT` | | `items[].label` | 无对应值 | 紧急联系人 | | `items[].before` / `items[].after` | 无对应值 | 返回姓名和电话变更摘要,电话脱敏展示 | ## 11. 影响评估 / 回滚 ### 11.1 影响评估 - **是否破坏向后兼容**: 否。旧 `updates.travelers` 仍可用。 - **前端是否必须同步上线**: 否。旧出行人增删改调用可继续工作;需要在出行人 tab 修改订单级紧急联系人时,前端改用 `updates.people`。 - **建议前端改造点**: 出行人 tab 提交时统一组装到 `updates.people`,把订单级紧急联系人放在 `emergencyContactName/emergencyContactPhone`,把出行人增删改放在 `travelers`。 ### 11.2 回滚方案 - 如需回滚后端,前端可临时继续使用旧 `updates.travelers` 完成出行人增删改。 - 回滚后订单级紧急联系人不能再通过调整订单 submit 接口修改,需要前端隐藏或禁用出行人 tab 的紧急联系人提交入口。 ## 12. 注意事项 - 新旧契约并存期间,不建议同一次请求同时提交 `updates.people.travelers` 和 `updates.travelers`,避免前端误以为两份都会合并执行。 - `updates.people.emergencyContactPhone` 必须传 11 位数字,不支持带空格、短横线或区号。 - 紧急联系人电话在调整记录中脱敏展示,不要用调整记录回填编辑表单;编辑表单仍应以 snapshot 返回的订单级紧急联系人字段为准。 ## 13. 关联 / 联系人 ### 13.1 链接 - **Issue**: [#4908](https://git.1814.love:8443/wx/HL/issues/4908) - **PR**: [#4909](https://git.1814.love:8443/wx/HL/pulls/4909) - **Merge commit**: [85969df64](https://git.1814.love:8443/wx/HL/commit/85969df64b7d534f5ff93fbe1c7c562f0d79c6e2) ### 13.2 联系人 - **后端负责人**: @yst