Refs wx/HL#8508 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
15 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 | 8508 | 调整配房(placement)已确认行同事务作废应付台账,有在途付款申请时新增 599602 拒绝 | admin | wx(GIT) | 修改接口 | deployed | not_required | not_required | PR #8575 已合并 dev-v3(合并提交 72baca1fd),测试服 order-v3 运行 99fb369ba8(含本单)。测试服实测:已确认行调整后原台账行作废、配房行回到询价中;再确认后生成一条新台账行,金额=结算价×新间数;调整后在询价中删除,无孤儿台账行。599602 拒绝、已付行红冲、无台账存量行、询价中阴性对照由单测覆盖:在途付款申请与已付状态需要财务域写入才能造出来,测试服不造。gateway_status=not_required:路径与方法未变。 | 2026-09-30 | dev-v3 |
order-v3: 调整配房已确认行同事务作废应付台账,有在途付款申请时新增 599602 拒绝
存放目录:
- 一期(v2,无
order-v3标签的工单)→changelogs/{YYYY-MM}/- 二期(v3,
order-v3标签的工单)→changelogs-v2/{YYYY-MM}/服务: hl-order-service-v3 PR: #8575 Issue: #8508 日期: 2026-09-30 影响范围: 管理后台「房务配房工作台」§2.3b 调整单条配房位置与资源接口,原配房行为已确认(CONFIRMED)且有在途付款申请的调整场景
⚠️ 关键变化(非必须,本版与上版行为不同 / 纠错 / 撤销时必写)
PUT /v3/admin/order/hotel-requirements/{requirementId}/assignments/{id}/placement新增一条失败分支:原配房行为「已确认(CONFIRMED)」,且该行的应付款台账有在途付款申请(applied>0)时,本次调整整体失败,返回 599602。此前这种情况会调整成功,但应付台账仍停在旧酒店旧价,产生台账与配房不一致。- 除新增该错误码外,接口路径、方法、入参字段(
AssignmentPlacementUpdateReqVO)、出参(Result<Void>)逐字节不变。
二、变更接口清单
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|---|---|---|---|---|---|
| 1 | 调整单条配房位置与资源 | PUT | /v3/admin/order/hotel-requirements/{requirementId}/assignments/{id}/placement |
新增可能返回的错误码 | 原行已确认且应付台账有在途付款申请时返 599602 |
三、接口详情
1. 调整单条配房位置与资源 PUT /v3/admin/order/hotel-requirements/{requirementId}/assignments/{id}/placement
VO: AssignmentPlacementUpdateReqVO → Void
使用场景
房务对已存在的单条配房行原子调整目标晚次、酒店、房型和房间数(前端只传目标 dayNumber,入住日期由后端按当前订单行程推导)。本次改动不涉及入参/出参字段,只新增一条业务失败分支:原行为「已确认」且其应付款台账行有在途付款申请时,整次调整被拒绝。
入参
路径参数 + Body(与改造前逐字节相同):
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| requirementId | Path | Long | ✅ | - | 当前生效住宿需求 ID |
| id | Path | Long | ✅ | - | house_hotel_assignment 主键 |
| dayNumber | Body | Integer | ✅ | ≥1 | 目标晚次(1=第1晚) |
| hotelId | Body | Long | ✅ | - | 目标酒店 ID |
| roomTypeId | Body | Long | ✅ | - | 目标房型 ID,须归属该 hotelId |
| roomCategory | Body | String | ✅ | @NotBlank |
目标房型字典 code |
| roomCount | Body | Integer | ✅ | ≥1 | 目标房间数 |
| protoPrice | Body | BigDecimal | - | ≥0 | 协议价快照,不传按目标房型和目标入住日读取资源价格日历 |
| settlementPrice | Body | BigDecimal | - | ≥0 | 结算价快照,不传同上兜底 |
| settleType | Body | String | - | cash|sign|company |
支付方式快照 |
| deductInventory | Body | Boolean | ✅ | - | 是否扣减资源库存 |
| breakfast | Body | String | - | INCLUDED|EXCLUDED|PENDING |
早餐,不传保留原值 |
| cancelProofFileIds | Body | List<Long> | - | 最多 9 个 | 原酒店取消凭证文件 ID |
| cancelFee | Body | BigDecimal | - | ≥0,最多 2 位小数 | 原酒店取消费用 |
| changeRemark | Body | String | - | ≤200 字 | 改配说明 |
| syncProtocolPrice | Body | Boolean | - | 默认 false | 是否同步协议价到目标房型目标日期价格日历 |
| syncSettlementPrice | Body | Boolean | - | 默认 false | 是否同步结算价 |
| syncSettleType | Body | Boolean | - | 默认 false | 是否同步支付方式到目标酒店资源 |
| remark | Body | String | - | - | 备注,不传保留原备注 |
出参 Result<Void>
| 字段 | 类型 | 说明 |
|---|---|---|
| data | null | 无返回数据 |
请求示例
{
"dayNumber": 2,
"hotelId": 200001,
"roomTypeId": 300001,
"roomCategory": "STANDARD",
"roomCount": 2,
"protoPrice": 320.00,
"settlementPrice": 280.00,
"settleType": "cash",
"deductInventory": true,
"syncProtocolPrice": false,
"syncSettlementPrice": false,
"syncSettleType": false,
"remark": "改期后重新询房"
}
响应示例
{ "code": 200, "message": "成功", "data": null, "success": true }
空数据 / 降级响应
本接口无「空数据」概念(成功恒返回 data: null),无降级路径。
错误响应
{ "code": 599602, "message": "应付款台账行已锁定", "data": null, "success": false }
| code | 触发条件 |
|---|---|
| 599602(本次新增) | 原配房行为已确认(CONFIRMED),且其应付款台账最新有效行有在途付款申请(applied>0) |
(其余既有错误码——鉴权、参数校验、需求状态、库存迁移相关——均未变化,本次未改动,不在此重复列出。)
业务边界
- 触发条件只看原配房行的
confirmStatus:只有原行为CONFIRMED时才会查应付台账锁;原行为INQUIRING时零台账查询,行为与改造前完全一致。 - 599602 命中时零写入:库存迁移分两处闸——一次是预占目标库存之前的只读预检,一次是写库前事务内的兜底闸;命中任一处都不会预占新库存、不会改配房行、不会动台账;若预检已通过但事务内并发被占用而在兜底闸命中,已预占的新库存会被同步补偿释放。
- 原行已确认且已付(
paid>0)不受本次新增拒绝影响:由财务域内部对该行做整行红冲(CLOSED),调整照常成功。 - 原行已确认但没有应付台账行(台账上线前确认的存量行):判存后跳过台账处理,调整照常成功,不报错。
- 调整成功后该行照旧退回询价中(
INQUIRING,改造前既有行为不变);台账不在本次调整时重推,由下次单日确认按新酒店、新间数、新结算价重新推送。
四、契约约束与正确调用方式(接口类必写)
本节只写后端接受/拒绝 payload 的规则,不写 UI 渲染建议。
- 触发 599602 与请求体字段无关,完全由服务端读取的原配房行状态(
confirmStatus)与其应付台账的applied值决定;前端无法通过改写请求体规避或复现这条错误,只能据响应处理。 - 判断失败必须读响应体
code === 599602(业务失败,HTTP 状态码仍是 200),不要判 HTTP 状态码。 - 该错误码不是全新码——删除、改价、清空三条既有写路径已经会返回同一个 599602;前端若已对这三条路径统一处理该码,调整配房无需额外新增分支即可覆盖。
五、数据库行为(涉及写操作时必写)
本次不改变调整配房成功时原有的写入内容(配房行更新、库存迁移记账逐字节不变)。新增变化只发生在「原行已确认」这一分支:
| 场景 | 改前 | 改后 |
|---|---|---|
| 原行已确认、有台账行、未付、无在途申请 | 台账行不处理,停留在旧酒店旧价 | 同事务作废该台账行(未付取消),配房行照常更新 |
原行已确认、已付(paid>0)、无在途申请 |
台账行不处理 | 同事务由财务域整行红冲(CLOSED),配房行照常更新 |
原行已确认、有在途付款申请(applied>0) |
调整成功,台账行不处理 | 整次调整失败(599602),配房行、库存、台账三者均不写入 |
| 原行已确认、无台账行(存量行) | 调整成功 | 调整成功(无变化) |
| 原行询价中(INQUIRING) | 调整成功,不涉及台账 | 调整成功,不涉及台账(无变化) |
被作废的台账行不在本次调整时重新推送;下一次该晚单日确认(confirmDay)时按新酒店、新间数、新结算价重新推送。
六、边界行为
- 未登录 → 401(网关拦截)
- 非房务角色 → 808090(原「房务组长只读监督 808091」已随 #8491 删除:全体房务可读全部配房单)
- 配房行不存在,或 requirementId 与该行实际归属需求不一致 → 808120
- 需求不存在 / 已作废 / 不属于当前用户 / 未被抢单 → 808100/808113/808110/808116
- 订单已取消或异常处置中 → 808119
- 目标 dayNumber 超出应配晚数 → 808102
- 目标房型不属于目标酒店 → 808112
- 涉及库存迁移但原配房缺少可释放的持有日志 → 808126
- 团期子订单未成团 / 班期未建团 → 589552/589553
- 原行已确认且应付台账有在途付款申请(本次新增)→ 599602,HTTP 200,零写入
- 老数据兼容:请求/响应字段无增删,存量数据无需迁移
六.5、枚举 / 数据字典(接口出现枚举时必写)
confirmStatus 不是本接口的请求/响应字段,但它是决定本次新增分支是否触发的关键状态,前端可从既有的配房行读接口(如 HouseOrderDetailRespVO 里配房行的 confirmStatus/confirmStatusLabel,字段本身未变)预判会不会撞上 599602。
confirmStatus(配房行确认态,HouseAssignmentConfirmStatus)
所属字段: 配房行 confirmStatus(既有字段,本次未变) | 类型: String
| 值 | 中文 | 说明 |
|---|---|---|
INQUIRING |
询房中 | 调用本接口零台账查询,行为与改造前一致 |
CONFIRMED |
已确认 | 调用本接口会先查该行应付台账是否有在途付款申请,命中则 599602 |
六.6、修改前后对比(修改/删除类接口必写,新增跳过)
字段级对比
| 字段 | 改前 | 改后 |
|---|---|---|
| (无) | 请求体、响应体字段逐字节不变 | 同左 |
行为级对比
| 行为 | 改前 | 改后 |
|---|---|---|
| 原行已确认、有台账行、有在途付款申请时调整 | 调整成功,台账行不处理,停留在旧酒店旧价 | 整次调整失败,返回 599602,配房/库存/台账三者均不变 |
| 原行已确认、有台账行、无在途申请(未付或已付)时调整 | 台账行不处理 | 同事务作废(未付取消 / 已付整行红冲),下次单日确认按新值重推 |
| 原行已确认、无台账行的存量行调整 | 调整成功 | 调整成功(无变化) |
| 原行询价中时调整 | 调整成功,不涉及台账 | 调整成功,不涉及台账(无变化) |
| 请求/响应字段 | 不变 | 不变 |
六.7、影响评估(修改/删除类必写)
- 是否破坏向后兼容: 否——不改字段、不改既有错误码语义;新增一条此前不存在的失败路径(599602),且该码在删除/改价/清空三条既有路径中已经存在。
- 前端是否必须同步上线: 若前端已对既有的删除/改价/清空三条路径统一处理 599602(按响应体
code分支、非静默吞掉),调整配房无需新增代码即可覆盖;若尚未统一处理,需要补上。 - 前端 workaround 清理点: 无。
七、不影响范围(显式声明, 帮前端/QA 缩小排查面)
- 仅影响:
PUT .../placement端点,原配房行为已确认(CONFIRMED)时的应付台账处理与新增失败分支 - 零影响:
- 原配房行为询价中(INQUIRING)时的调整(零台账查询,行为不变)
- 已确认但无应付台账行的存量配房行调整(判存后跳过,成功不报错)
- 已确认且已付(
paid>0)的配房行调整(由财务域内部整行红冲,不新增拒绝) - 本接口的请求体、响应体字段结构
- 删除、改价、清空、转房、订单取消级联等既有路径对 599602 的处理逻辑(本次未改动这些路径)
- hl-gateway 路由配置——端点路径、方法零变化
八、测试环境已验证
测试服 order-v3 运行 99fb369ba8 及其后代 ff68637542(均含 PR #8575 合并提交 72baca1fd),全部用自造订单:
- 已确认行调整(
PUT .../assignments/{id}/placement,间数 1→2):code=200,配房行回到INQUIRING,原台账行(seq=0)软删,改后无有效 NORMAL 行。 - 再确认该晚:配房行回到
CONFIRMED,台账新增 1 条有效行 seq=1,payable=600.00(300.00×2)。 - 换酒店(同一接口,改为同城另一家酒店,且两家酒店的供应商不同):
code=200,配房行回到INQUIRING,原台账行软删;再确认后台账有且只有 1 条有效行,resource_id为新酒店,supplier_id为新酒店的供应商(与原供应商不同),payable=280.00(280.00×1)。本条在 order-v3ff68637542上取证。 - 调整后在询价中删除(
DELETE /v3/admin/order/assignments/{id}):只读孤儿判据 SQL 读数 0,无孤儿台账行。
以下分支由随 PR 提交的单测覆盖(HouseAssignmentServiceTest,DisplayName 均带 #8508 前缀;测试服不造「在途付款申请」「已付」状态,因为它们要在财务域写入):
updatePlacement_payableLockedAtPreflight_throws599602BeforeInventoryDeduct:预检命中在途申请 → 599602,库存迁移、配房行更新、台账作废均未调用。updatePlacement_payableLockedAtFallback_throws599602AndCompensatesTargetInventory:预检通过、事务内并发被占用 → 599602,新预占库存同步释放。updatePlacement_confirmedPaidLine_removesLineAndMigratesInventory:已付(paid>0)无在途申请 → 不拦,作废台账行一次;财务域据此整行红冲(CLOSED),再推时按 seq+1 生成新行(财务域既有单测PayablePushServiceTest覆盖)。updatePlacement_confirmedWithoutPayableLine_skipsRemoveAndSucceeds:已确认无台账行的存量行 → 调整照常成功。updatePlacement_inquiringOriginal_skipsPayableQueries:原行询价中 → 不做任何台账查询或作废。
十、相关文档
- 关联 Issue: wx/HL#8508
- 关联 PR: wx/HL#8575
关联 / 联系人
链接
联系人
- 后端负责人: @wx