From 487f5fb399263f6fe01ca35f37c43647090bd0ef Mon Sep 17 00:00:00 2001 From: API Changelog Bot Date: Wed, 30 Sep 2026 04:20:42 +0800 Subject: [PATCH] =?UTF-8?q?docs(changelog):=20#8508=20=E8=B0=83=E6=95=B4?= =?UTF-8?q?=E5=B7=B2=E7=A1=AE=E8=AE=A4=E9=85=8D=E6=88=BF=E8=A1=8C=E6=97=B6?= =?UTF-8?q?=E5=A4=84=E7=90=86=E5=BA=94=E4=BB=98=E5=8F=B0=E8=B4=A6=EF=BC=88?= =?UTF-8?q?=E5=9C=A8=E9=80=94=E4=BB=98=E6=AC=BE=E7=94=B3=E8=AF=B7=E6=8B=92?= =?UTF-8?q?=E7=BB=9D=20599602=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refs wx/HL#8508 Co-Authored-By: Claude Opus 5.5 (1M context) --- ...确认行有在途付款申请时拒绝-修改接口-管理后台.md | 273 ++++++++++++++++++ 1 file changed, 273 insertions(+) create mode 100644 changelogs-v2/2026-09/30_8508_调整配房已确认行有在途付款申请时拒绝-修改接口-管理后台.md diff --git a/changelogs-v2/2026-09/30_8508_调整配房已确认行有在途付款申请时拒绝-修改接口-管理后台.md b/changelogs-v2/2026-09/30_8508_调整配房已确认行有在途付款申请时拒绝-修改接口-管理后台.md new file mode 100644 index 00000000..a9f8e54a --- /dev/null +++ b/changelogs-v2/2026-09/30_8508_调整配房已确认行有在途付款申请时拒绝-修改接口-管理后台.md @@ -0,0 +1,273 @@ +--- +schema: "hl-changelog/v2" +ticket: "8508" +title: "调整配房(placement)已确认行同事务作废应付台账,有在途付款申请时新增 599602 拒绝" +consumer: "admin" +author: "wx(GIT)" +change_type: "修改接口" +backend_status: "deployed" +gateway_status: "not_required" +frontend_status: "not_required" +frontend_owner: "" +frontend_ref: "" +target_release: "" +verified_at: "" +status_note: "PR #8575 已合并 dev-v3(合并提交 72baca1fd),测试服 order-v3 运行 99fb369ba8(含本单)。测试服实测:已确认行调整后原台账行作废、配房行回到询价中;再确认后生成一条新台账行,金额=结算价×新间数;调整后在询价中删除,无孤儿台账行。599602 拒绝、已付行红冲、无台账存量行、询价中阴性对照由单测覆盖:在途付款申请与已付状态需要财务域写入才能造出来,测试服不造。gateway_status=not_required:路径与方法未变。" +updated_at: "2026-09-30" +base: "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`)逐字节不变。 + +--- + +## 二、变更接口清单 + +| # | 接口 | 方法 | 路径 | 变更类型 | 说明 | +|---|------|------|------|----------|------| +| 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\ | - | 最多 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` + +| 字段 | 类型 | 说明 | +|------|------|------| +| data | null | 无返回数据 | + +#### 请求示例 + +```json +{ + "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": "改期后重新询房" +} +``` + +#### 响应示例 + +```json +{ "code": 200, "message": "成功", "data": null, "success": true } +``` + +#### 空数据 / 降级响应 + +本接口无「空数据」概念(成功恒返回 `data: null`),无降级路径。 + +#### 错误响应 + +```json +{ "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-v3 `ff68637542` 上取证。 +- 调整后在询价中删除(`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](https://git.1814.love:8443/wx/HL/issues/8508) +- 关联 PR: [wx/HL#8575](https://git.1814.love:8443/wx/HL/pulls/8575) + +## 关联 / 联系人 + +### 链接 + +- **Issue**: [#8508](https://git.1814.love:8443/wx/HL/issues/8508) +- **PR**: [#8575](https://git.1814.love:8443/wx/HL/pulls/8575) +- **Merge commit**: [72baca1fd](https://git.1814.love:8443/wx/HL/commit/72baca1fd) + +### 联系人 + +- **后端负责人**: @wx