# 【行为变更·管理后台】订单调整保留配房与房务驳回定制师待办(#4907) > 2026-07-16 最终后端状态:零配房最终确认动作契约已由 PR #5014 补齐并合入 `dev-v3`。最新代码、部署、网关 API、DB/库存和日志证据均通过;前端页面实现属于独立交付,不作为后端工单关单门禁。 > 服务:`hl-order-service-v3` > > 生效分支:`dev-v3` > > 接口结构:新增“单条配房晚次与资源原子调整”接口;其余沿用订单调整、房务详情、最终确认和房务驳回现有接口 > > 后端状态:既有 PR [#4915](https://git.1814.love:8443/wx/HL/pulls/4915)、[#4925](https://git.1814.love:8443/wx/HL/pulls/4925)、[#4926](https://git.1814.love:8443/wx/HL/pulls/4926)、[#4928](https://git.1814.love:8443/wx/HL/pulls/4928)、[#4931](https://git.1814.love:8443/wx/HL/pulls/4931) 与最新 PR [#5014](https://git.1814.love:8443/wx/HL/pulls/5014) 均已合并;最终验证基线 `dev-v3@d54435af7`,测试环境部署任务 `86d9bf11` 成功,`8086/8186` 双实例 UP > > 联调证据:2026-07-16 部署后重新使用隔离订单执行接口面、缺口流程、订单日志和调整闭环四组探针,全部通过;最终调整报告 `D:/work2/HL-v3/.tmp/house-adjustment-flow-probe-20260716-184129.json` 为 `ok=true` ## 0. 2026-07-12 追加:返工标签唯一口径与前端未完成项 ### 0.1 返工订单不能再展示“刚抢单待配房” 后端已修复待办聚合口径:同一需求存在归属当前房务的 OPEN `REQUIREMENT_ADJUSTED` 时,`需求变更重配` 是主待办,后端不会再为该需求派生 `PENDING_ARRANGE`。 - `GET /v3/admin/order/todos`:该订单 `todoTypes[]` 不再包含 `PENDING_ARRANGE`。 - 按 `todoType=PENDING_ARRANGE` 筛选:返工订单不会进入结果。 - `GET /admin/profile/dashboard`:对应 `todoCards[].todoType` 为 `REQUIREMENT_ADJUSTED`,文案为“需求变更重配”。 - `HOTEL_REPLY_TIMEOUT`、`UNREAD_CHAT` 等独立提醒仍可与返工标签共存,前端不得把它们误删。 前端必须直接按后端 `todoTypes[]` / `todoCards[].todoType` 渲染,禁止因为 `houseStatus=CLAIMING` 再自行追加“刚抢单待配房”。 测试环境订单 `HL20260712140748356` 网关实测结果: ```json { "todoTypes": ["REQUIREMENT_ADJUSTED", "HOTEL_REPLY_TIMEOUT"], "pendingArrangeFacetRows": 0, "dashboardTodoType": "REQUIREMENT_ADJUSTED", "dashboardTodoLabel": "需求变更重配" } ``` ### 0.2 当前页面仍缺“调整配房”入口 目前房务详情仍只读展示 `stayDate`,只有“替换/配房/询房”等旧动作,无法把既有配房调整到当前行程的另一个有效晚次。前端需要在每条已有配房旁增加“调整”入口,完整调用下文 §1 的 placement 接口;不能只改页面显示,也不能组合“新增目标晚 + 删除原晚”。 ### 0.3 返工待办生命周期与刷新规则 `REQUIREMENT_ADJUSTED` 不是永久状态标签。前端每次业务动作成功后必须重新请求待办和房务详情,不能用旧页面缓存继续展示: | 业务动作 | 后端结果 | 前端处理 | |---|---|---| | 同一需求版本重复触发调整事件 | 幂等复用原待办,不新增重复标签 | 保留一条 `需求变更重配` | | 连续调整产生新需求版本 | 旧版本返工待办转 `RESOLVED`,只保留当前版本 OPEN 待办 | 刷新后仍只显示一条当前返工标签 | | 当前需求最终确认 | 当前 `REQUIREMENT_ADJUSTED` 自动 `RESOLVED` | 从未完成列表和工作台卡片移除 | | 房务驳回住宿需求 | 房务返工待办自动 `RESOLVED`,订单侧为原定制师产生 `ASSIGN_ROOM` 待办 | 房务端移除返工标签,不展示定制师待办 | | 订单取消 | 房务返工待办自动 `RESOLVED`;有配房时可能产生 `REFUND`,退款成功后该待办可立即变为 `RESOLVED` | 不得假设取消后一定存在 OPEN `REFUND` | 待办接口的当前契约: ```http GET /v3/admin/order/todos?scope=mine&status=OPEN&page=1&pageSize=20 ``` - 一订单一行,完整标签来自 `list[].todoTypes[]`;顶层 `todoType/title` 只是主标签兼容字段。 - `REQUIREMENT_ADJUSTED` 与同一需求的 `PENDING_ARRANGE` 后端已互斥,`stats.PENDING_ARRANGE` 同口径排除。 - 前端禁止根据 `houseStatus=CLAIMING` 自行补“刚抢单待配房”。 - `HOTEL_REPLY_TIMEOUT`、`UNREAD_CHAT` 可与返工标签并存,不能因为互斥普通新抢标签而一并隐藏。 - §1 的目标晚次选择和“调整”入口属于前端实现清单;前端完成后独立验收,不再用于控制后端 Issue #4907 状态。 ### 0.4 首页、待办列表、订单详情必须保持一致 前端需要同时验收以下三处,不能只修其中一个页面: 1. 房务首页:直接按 `GET /admin/profile/dashboard` 返回的 `todoCards[].todoType` / `todoLabel` 渲染。 2. 房务待办列表:直接按 `GET /v3/admin/order/todos` 返回的 `list[].todoTypes[]` 渲染完整标签,顶层 `todoType/title` 只作为主标签兼容字段。 3. 房务订单详情:业务动作成功后重新加载房务详情,并同步刷新首页和待办列表;不得沿用进入详情前的旧标签或旧计数。 同一订单在三处页面必须遵守同一口径: - 存在 OPEN `REQUIREMENT_ADJUSTED` 时,主标签只能是“需求变更重配”,不得再显示“刚抢单待配房”。 - 最终确认、房务驳回或订单取消成功后,前端必须重新请求接口;对应返工待办已关闭时,三处均不得继续显示旧标签。 - `HOTEL_REPLY_TIMEOUT`、`UNREAD_CHAT` 等独立提醒可以与返工主标签共存,但不得自行拼接同需求的 `PENDING_ARRANGE`。 - 调整配房只能提交目标 `dayNumber`,不得自行提交或计算 `stayDate`;入住日期由后端根据当前行程晚次推导。 前端独立验收建议包含同一订单在“房务首页、待办列表、订单详情”三处的刷新后截图,并证明标签、数量和当前业务状态一致;该证据用于前端交付验收,不反向重开已完成的后端 Issue。 ## 1. 订单调整后的房务口径 定制师通过以下接口修改行程天数、出发日期或出行人数: ```http POST /v3/admin/order/{orderId}/adjustment/submit ``` 后端现在按最新行程重新对齐住宿需求逐晚结构。既有配房不会被自动删除;真正改出发日期时,仍在新行程晚数范围内的配房会按 `dayNumber` 自动平移入住日期: | 调整项 | 前端应展示的结果 | |---|---| | 增加行程天数 | 原晚次配房保持;新增夜显示待配房 | | 减少行程天数 | 需求夜数减少;多余旧配房继续显示,等待房务人工清空/替换 | | 修改出发日期 | `stayDate = 新出发日期 + dayNumber - 1`;酒店、房型、房间数、价格、扣库存选择和备注原样保留;配房退回询房中重新确认 | | 同时改日期和天数 | 新行程范围内的配房自动平移;新增夜为空待配;超出新晚数的旧配房不自动删除 | | 修改出行人数 | 原配房继续显示;完整配房回到待最终确认,不完整则回配房中 | 新增夜允许空候选占位,`roomCount` 未填或为 `0` 均可提交;负数仍会被后端拒绝。前端不要为了绕过校验自行填造假的间数。 ### 改期库存原子性 - `deductInventory=false`:只平移订单配房快照,不操作资源库存。 - `deductInventory=true`:后端先逐晚预占新日期库存;全部成功后才修改订单、行程、需求和配房日期,并释放旧日期库存。 - 任意新日期库存不足或日历缺失:整次订单调整返回 `808901`;订单日期、需求版本、配房和旧库存全部保持原样,已临时预占的新日期库存自动补偿。 - 前端收到 `808901` 时只提示库存不足,不得将本地表单当作已保存。 ### 房务人工修改单条配房 当前前端仅在 `ItineraryPanel.vue` 只读显示日期,并通过整晚 `POST assignments` 做“配房/替换”。这不能安全实现“把 6 月 1 日的既有配房移动到 6 月 5 日”:若前端组合调用新增目标行和删除原行,中间任一步失败都会造成配房或库存半套。 请为每条既有配房增加“调整”入口,统一调用以下原子接口: ```http PUT /v3/admin/order/hotel-requirements/{requirementId}/assignments/{assignmentId}/placement Content-Type: application/json { "dayNumber": 1, "hotelId": "200001", "roomTypeId": "300001", "roomCategory": "DELUXE", "roomCount": 2, "protoPrice": "520.00", "settlementPrice": "480.00", "settleType": "sign", "deductInventory": true, "syncProtocolPrice": false, "syncSettlementPrice": false, "syncSettleType": false, "remark": "改期后重新询房" } ``` 成功响应: ```json { "code": 200, "message": "成功", "data": null, "success": true } ``` 字段规则: | 字段 | 必填 | 说明 | |---|---|---| | `dayNumber` | 是 | 目标晚次,从当前详情 `days[]` 选择。必须按当前行程映射:若出发日已从 6 月 1 日改为 6 月 5 日,则 6 月 5 日是当前第 1 晚,传 `1`,不是按“日期中的 5”传 `5` | | `hotelId` | 是 | 目标酒店 ID,字符串透传 | | `roomTypeId` | 是 | 目标房型 ID,字符串透传 | | `roomCategory` | 是 | 房型字典 code | | `roomCount` | 是 | 目标房间数,必须大于 0 | | `deductInventory` | 是 | 是否扣系统库存;缺失返回 `808124` | | `protoPrice` / `settlementPrice` | 否 | 不传时按目标房型和目标入住日读取资源价格日历;金额按字符串提交 | | `settleType` | 否 | `cash` / `sign` / `company` | | 三个 `sync*` | 否 | 仅用户明确选择同步时传 `true` | | `remark` | 否 | 不传时保留原备注 | 前端交互要求: 1. 目标日期不是自由输入框。下拉选项来自当前详情的有效住宿晚次,展示“第 N 晚 / 日期 / 城市”,提交其 `dayNumber`;不要提交 `stayDate`。 如果订单已改期但某条历史配房仍显示 6 月 1 日,当前行程第 1 晚已是 6 月 5 日,则房务选择“第 1 晚 / 6 月 5 日”提交;后端会把同一配房 ID 的 `stayDate` 更正为 6 月 5 日。 2. 同一弹窗必须允许同时修改目标晚次、酒店、房型、房间数、是否扣库存、协议价、结算价、支付方式和备注。 3. 后端按当前 `order_itinerary_day` 推导并保存 `stayDate`。旧配房 ID 不变,成功后该行退回 `INQUIRING`,前端关闭弹窗并重新加载详情。 4. 扣库存场景由后端先占目标库存、提交后释放原库存;失败时原配房和原库存不变。前端禁止再组合调用“目标晚新增 + 原晚删除”。 5. 现有整晚 `POST /v3/admin/order/hotel-requirements/{requirementId}/assignments` 继续用于新增候选和同晚整组对账,不替代本接口的跨晚次原子移动。 主要错误码: | code | 处理 | |---|---| | `808102` | 目标晚次已不在当前行程,刷新详情后重选 | | `808117` | 目标晚已有同酒店、同房型、同库存口径配房,提示合并房间数 | | `808124` | 未选择是否扣库存 | | `808125` | 配房或行程被并发修改,刷新详情后重试 | | `808126` | 原配房声明扣库存但缺少可释放的持有日志;禁止继续调整,需先核对库存 | | `808130` | 目标房间数小于已录入的家庭分房条数 | | `808901` | 目标日期资源库存不足;保留原页面数据 | ## 2. 最终确认 ```http POST /admin/house/assignments/requirements/{requirementId}/finalize ``` - 没有任何配房时允许最终确认,用于客人自行解决住宿的场景。 - 一旦存在任意配房,所有 active 配房必须已确认,并按晚次精确覆盖当前行程住宿日期。 - 缺夜、多余夜、日期不匹配或存在未确认配房返回: ```json { "code": 808181, "message": "已有配房与当前行程不一致,请先补配、替换或清空", "data": null } ``` 前端收到该错误后保留当前配房数据,提示房务逐日处理;不得清空页面状态或隐藏超出新行程的旧配房。 ### 2.1 零配房动作契约 详情接口与最终确认写接口现已使用同一业务口径: - 当前生效需求由当前房务持有。 - `houseStatus=CLAIMING`。 - 没有任何配房记录。 - 没有未闭环询房。 满足以上条件时,房务详情返回: ```json { "actions": { "canFinalize": { "enabled": true } } } ``` 以下场景仍保持禁用:存在部分配房、存在未闭环询房、非当前持有人、非当前生效需求或需求已经完成。最终确认成功后必须重新加载详情和待办;后端会关闭相关待办且不会创建配房或变更库存。 ## 3. 房务驳回后的定制师待办 ```http POST /v3/admin/order/{orderId}/hotel-requirement/supplier-reject Content-Type: application/json { "returnRemark": "酒店无法满足当前房型,请重新确认需求" } ``` 驳回成功后,后端会为原定制师显式创建一条待办: ```json { "todoType": "ASSIGN_ROOM", "todoLabel": "房型需求 · 已打回", "status": "PENDING", "assigneeRoleKey": "CUSTOMIZER", "relatedBizType": "HOTEL_REQUIREMENT", "relatedBizId": "2075933198734303233" } ``` 该待办与订单当前是否仍处于“补出行人资料”阶段无关。定制师待办页按现有待办接口正常展示并跳转订单调整即可。 ## 4. 前端验收 1. 增天后原配房不消失,新增夜可单独配房;不再出现 `roomCount 必须 > 0`。 2. 改期后原配房按晚次自动平移日期,酒店、房型、房间数和价格快照不变,状态退回询房中。 3. 改期同时增减天数时,新范围内配房平移、新增夜为空、超范围旧配房保留。 4. 房务可把单条既有配房原子移动到另一当前有效晚次,并同时修改酒店、房型、房间数和库存口径;日期始终与目标晚次一致。 5. 扣库存配房改期成功时旧库存释放、新库存扣减;任一晚不足时整单不变。 6. 减天后的多余旧配房继续显示,最终确认被后端阻断,直到人工清空/替换。 7. 修改人数后已有配房保持,房务重新最终确认。 8. 零配房订单允许最终确认。 9. 房务驳回后,原定制师能看到“房型需求 · 已打回”待办。 10. 历史需求和旧配房均继续展示,不得只渲染当前需求而丢失历史证据。 11. 需求变更返工订单只展示 `需求变更重配` 主标签,不得再从 `CLAIMING` 自行补出 `刚抢单待配房`;询房超时、未读消息等独立标签照常展示。 12. 每条已有配房均提供“调整”入口,可选择当前有效晚次并同时修改酒店、房型、房间数和库存口径;改期后从 6 月 1 日调整到当前第 1 晚 6 月 5 日时提交 `dayNumber=1`。 13. 同一返工订单在房务首页、待办列表、订单详情三处的主标签、数量和当前状态一致;动作成功后均使用重新请求的数据,不使用本地旧缓存补标签。 14. 前端提交单条配房调整时只提交 `dayNumber`,不得提交 `stayDate`;完成前端适配时提供三处页面刷新后的同订单截图。 ## 5. 后端验证证据 - PR:`wx/HL#4910/#4911/#4913/#4915/#4925/#4926/#4928/#4931/#5014` - 最终验证基线:`dev-v3@d54435af7` - 模块全量:5609 项测试,0 failure,0 error,15 skipped,`BUILD SUCCESS` - 最新测试环境部署任务:`86d9bf11`,`8086/8186` 双实例均 UP - 网关接口面:68/68 通过,报告 `D:/work2/HL-v3/.tmp/house-api-surface-probe-20260716-182908.json` - 缺口流程:3/3 通过,报告 `D:/work2/HL-v3/.tmp/house-api-gap-flow-probe-20260716-183121.json` - 订单日志:3/3 通过,报告 `D:/work2/HL-v3/.tmp/house-order-log-flow-probe-20260716-183224.json` - 调整闭环:4/4 通过,报告 `D:/work2/HL-v3/.tmp/house-adjustment-flow-probe-20260716-184129.json` - 实测通过:增晚、减晚、人数变化、连续调整新旧待办替代、改期+增晚、跨晚次原子调整、酒店/房型/房间数替换、入住日期对齐、人工清空、零配房最终确认、供应商驳回、订单取消、库存成功迁移、库存不足整单回滚 - 返工标签:`REQUIREMENT_ADJUSTED` 压制同需求 `PENDING_ARRANGE`;最终确认、供应商驳回、订单取消后返工待办均正确关闭