docs(changelog): #8615 转房记录作废原因与退房给酒店口径调整
changelog-filename-gate / validate (push) Failing after 2s
changelog-filename-gate / validate (push) Failing after 2s
- 转房列表 cancelReason 新增三个系统作废取值(本团已再分配 / 本团已撤销该晚计划 / 团期已解散) - 退房给酒店(I-21)对团期来源行补批次门禁与超量码 808324 - 附测试环境实测结论 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
这个提交包含在:
@@ -0,0 +1,314 @@
|
|||||||
|
---
|
||||||
|
schema: hl-changelog/v2
|
||||||
|
ticket: "8615"
|
||||||
|
title: "退团转房:作废原因新增三个系统取值,向酒店取消追加团期栅栏与联动缩减"
|
||||||
|
consumer: admin
|
||||||
|
author: wx(GIT)
|
||||||
|
change_type: 修改接口
|
||||||
|
backend_status: deployed
|
||||||
|
gateway_status: not_required
|
||||||
|
frontend_status: pending
|
||||||
|
frontend_owner: ""
|
||||||
|
frontend_ref: ""
|
||||||
|
target_release: ""
|
||||||
|
verified_at: ""
|
||||||
|
status_note: ""
|
||||||
|
updated_at: "2026-09-30"
|
||||||
|
base: dev-v3
|
||||||
|
---
|
||||||
|
|
||||||
|
# 退团转房:作废原因新增三个系统取值,向酒店取消追加团期栅栏与联动缩减
|
||||||
|
|
||||||
|
## ⚠️ 关键变化
|
||||||
|
|
||||||
|
- 退团转房池列表(#8491 I-17)的 `records[].cancelReason` 由原来只有一个取值 `HOTEL_CANCELLED`,扩展为**四个**取值,新增 `GROUP_REALLOCATED` / `GROUP_PLAN_REMOVED` / `GROUP_DISBANDED` 三个由团期写口在同一事务内系统作废时写入的取值;这三种情况下 `handlerName` 恒为 `null`(无人工处理人),`handledAt` 仍会写入系统作废发生的时刻。前端按 `cancelReason` 分支展示原因文案的地方需要扩展这三个分支,否则会落到未知分支的兜底展示。
|
||||||
|
- 退团房向酒店取消(#8491 I-21,`POST .../room-transfers/{id}/cancel-hotel`)新增两个错误码:**团期来源行**在源团期已不在「资源准备中」阶段时返回 `808323`(此前 I-21 对团期来源行不做团期状态校验,任何状态都能直接取消,改动后与转房接口 I-20 同口径);团期来源行的源计划空余不足以覆盖本行待转间数时返回 `808324`。这两个码此前只出现在 I-20 的错误表里,I-21 的错误表新增了它们。
|
||||||
|
- 退团房向酒店取消**成功后**,若该行是团期来源行,会在同一事务内按取消的间数**同步缩减**源团期计划行的 `roomCount`(联动 `shrinkForTransfer`);这一步不改变本接口的响应结构,只影响该房间此后是否还会被团期自动分配算进可用余量。
|
||||||
|
- 转房接口(#8491 I-20)不在本次变更接口清单内——其错误表已发布过 `808324`,本次只是把此前一个应报 `808324`(源计划空余不足)却会先报到 `808932`(并发冲突)的边界情况改为直接报 `808324`,错误码本身与文案都没有新增,属于既有契约内的分支修正,前端已有的 `808324`/`808932` 处理分支不需要改动。
|
||||||
|
|
||||||
|
## 二、变更接口清单
|
||||||
|
|
||||||
|
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|
||||||
|
|---|------|------|------|----------|------|
|
||||||
|
| 1 | 退团转房池分页 | GET | `/v3/admin/order/house-console/room-transfers` | 响应字段取值扩展 | `cancelReason` 新增三个系统作废取值,系统作废行 `handlerName` 为空 |
|
||||||
|
| 2 | 退团房向酒店取消 | POST | `/v3/admin/order/house-console/room-transfers/{id}/cancel-hotel` | 新增错误码 + 联动行为 | 团期来源行新增 808323/808324 校验;取消成功后同步缩减源团期计划间数 |
|
||||||
|
|
||||||
|
## 三、接口详情
|
||||||
|
|
||||||
|
### 1. 退团转房池分页 `GET /v3/admin/order/house-console/room-transfers`
|
||||||
|
|
||||||
|
**VO**: `HouseRoomTransferPageReqVO → HouseRoomTransferPageRespVO`
|
||||||
|
|
||||||
|
#### 使用场景
|
||||||
|
|
||||||
|
房务控制台「退团房」页签展示当前待处理 / 已转出 / 已取消的转房行列表。本次改动只涉及列表行里 `cancelReason` 取值集合的扩展,请求参数与响应结构均未变化。
|
||||||
|
|
||||||
|
#### 入参
|
||||||
|
|
||||||
|
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||||||
|
|------|------|------|------|------|------|
|
||||||
|
| page | Query | Integer | ❌ | 默认 1 | 页码 |
|
||||||
|
| pageSize | Query | Integer | ❌ | 1~100,默认 20 | 每页条数 |
|
||||||
|
| status | Query | String | ❌ | PENDING / TRANSFERRED / CANCELLED,默认 PENDING | 状态筛选 |
|
||||||
|
| risk | Query | String | ❌ | OVERDUE / NEAR / NO_DEADLINE / NORMAL | 风险筛选,仅对 PENDING 行有意义 |
|
||||||
|
| cityCode | Query | String | ❌ | ≤64 | 城市中文名 |
|
||||||
|
| keyword | Query | String | ❌ | ≤64 | 团号或酒店名关键词 |
|
||||||
|
| stayDateFrom | Query | LocalDate | ❌ | yyyy-MM-dd | 入住晚起(含) |
|
||||||
|
| stayDateTo | Query | LocalDate | ❌ | yyyy-MM-dd | 入住晚止(含) |
|
||||||
|
|
||||||
|
#### 出参
|
||||||
|
|
||||||
|
| 字段 | 类型 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| records | List<HouseRoomTransferRespVO> | 当前页转房行 |
|
||||||
|
| records[].id | Long(String) | 转房行 ID |
|
||||||
|
| records[].sourceType | String | 来源类型 ORDER / GROUP_BATCH |
|
||||||
|
| records[].sourceGroupBatchId / sourceBatchNo | Long(String) / String | 团期来源行的源团期 ID 与批次号 |
|
||||||
|
| records[].stayDate | LocalDate | 入住晚 |
|
||||||
|
| records[].hotelName / roomTypeName | String | 酒店名 / 房型名 |
|
||||||
|
| records[].roomCount | Integer | 原始间数 |
|
||||||
|
| records[].remainingCount | Integer | 剩余待处理间数;部分被系统收敛时会减少,行仍保持 PENDING |
|
||||||
|
| records[].status / statusLabel | String | PENDING / TRANSFERRED / CANCELLED 及中文 |
|
||||||
|
| records[].cancelReason | 【改动】String | 仅 CANCELLED 行有值。`HOTEL_CANCELLED`=房务人工向酒店取消(不变);新增 `GROUP_REALLOCATED`=本团已再分配、`GROUP_PLAN_REMOVED`=本团已撤销该晚计划、`GROUP_DISBANDED`=团期已解散,三者都是团期写口系统作废,见「六.5」 |
|
||||||
|
| records[].handlerName | 【改动】String | 处理人姓名;`cancelReason` 为三个新增取值之一时恒为 `null`(无人工处理人) |
|
||||||
|
| records[].handledAt | LocalDateTime | 处理时间;系统作废时同样写入作废发生的时刻,不为 null |
|
||||||
|
| records[].readOnly / readOnlyReason | Boolean / String | 对当前登录人是否只读及理由 |
|
||||||
|
| total / page / pageSize | long / int / int | 分页信息 |
|
||||||
|
| summary.pendingRooms 等 4 项 | int | 全部 PENDING 行的风险汇总,恒不受本次筛选条件影响 |
|
||||||
|
|
||||||
|
#### 请求示例
|
||||||
|
|
||||||
|
```http
|
||||||
|
GET /v3/admin/order/house-console/room-transfers?status=CANCELLED&cityCode=海拉尔&page=1&pageSize=20
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 响应示例
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"message": "成功",
|
||||||
|
"data": {
|
||||||
|
"records": [
|
||||||
|
{
|
||||||
|
"id": "9100234", "sourceType": "GROUP_BATCH", "sourceOrderId": null, "teamNo": null,
|
||||||
|
"sourceTeamNo": "HLT-20261012-003", "sourceGroupBatchId": "500321", "sourceBatchNo": "HLT-20261012-003",
|
||||||
|
"stayDate": "2026-10-12", "cityName": "海拉尔", "hotelId": "60088", "hotelName": "海拉尔国际大酒店",
|
||||||
|
"roomTypeId": "70012", "roomTypeName": "高级大床房", "roomCount": 2, "remainingCount": 2,
|
||||||
|
"status": "CANCELLED", "statusLabel": "已取消", "cancelDays": 3, "cancelCutoff": "18:00", "remindDays": 1,
|
||||||
|
"deadlineAt": "2026-10-09T18:00:00", "risk": "NORMAL", "riskLabel": "正常",
|
||||||
|
"targetType": null, "targetOrderId": null, "targetTeamNo": null, "targetRequirementId": null,
|
||||||
|
"targetGroupBatchId": null, "targetBatchNo": null, "hotelConfirmNo": null, "proofFileIds": [],
|
||||||
|
"cancelFee": null, "cancelReason": "GROUP_REALLOCATED", "handlerName": null,
|
||||||
|
"handledAt": "2026-09-30T10:02:11", "remark": null, "readOnly": false, "readOnlyReason": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"total": 1,
|
||||||
|
"page": 1,
|
||||||
|
"pageSize": 20,
|
||||||
|
"summary": { "pendingRooms": 6, "overdueRooms": 0, "nearRooms": 1, "noDeadlineRooms": 0 }
|
||||||
|
},
|
||||||
|
"success": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 空数据 / 降级响应
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "code": 200, "message": "成功", "data": { "records": [], "total": 0, "page": 1, "pageSize": 20, "summary": { "pendingRooms": 0, "overdueRooms": 0, "nearRooms": 0, "noDeadlineRooms": 0 } }, "success": true }
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 错误响应
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 400,
|
||||||
|
"message": "status 取值非法",
|
||||||
|
"data": null,
|
||||||
|
"success": false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
| code | message | 触发 |
|
||||||
|
|------|---------|------|
|
||||||
|
| 400 | status 取值非法 / risk 取值非法 | 入参校验,未变 |
|
||||||
|
| 808090 | 未登录或非房务角色,无权操作 | 非房务角色,未变 |
|
||||||
|
|
||||||
|
#### 业务边界
|
||||||
|
|
||||||
|
- 团期写口(分房重算、加入团期自动分房、改计划间数、删计划、团期解散)触发系统收敛时:某计划行下全部 PENDING 转房行都被覆盖,则行整体变为 CANCELLED 并写入对应 `cancelReason`;只覆盖了一部分,则行仍是 PENDING,仅 `remainingCount` 减少,`cancelReason`/`handlerName`/`handledAt` 均不变。
|
||||||
|
- 系统作废(`cancelReason` 为 `GROUP_REALLOCATED`/`GROUP_PLAN_REMOVED`/`GROUP_DISBANDED`)的行没有人工处理人:`handlerName` 为 `null`;触发它的管理员记在操作日志里,不在本接口暴露。
|
||||||
|
- `summary` 恒统计全部 PENDING 行,不受本次筛选条件影响。
|
||||||
|
|
||||||
|
### 2. 退团房向酒店取消 `POST /v3/admin/order/house-console/room-transfers/{id}/cancel-hotel`
|
||||||
|
|
||||||
|
**VO**: `HouseRoomTransferCancelReqVO → HouseRoomTransferRespVO`
|
||||||
|
|
||||||
|
#### 使用场景
|
||||||
|
|
||||||
|
退团房没有合适的转入对象时,房务直接向酒店办理取消,上传凭证并可录入取消费用。本次改动只影响**团期来源行**(`sourceType=GROUP_BATCH`):新增源团期状态与源计划余量两道校验,取消成功后联动缩减源团期计划间数;常规单来源行(`sourceType=ORDER`)的路径与校验顺序不变。
|
||||||
|
|
||||||
|
#### 入参
|
||||||
|
|
||||||
|
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||||||
|
|------|------|------|------|------|------|
|
||||||
|
| id | Path | Long | ✅ | - | 转房行 ID |
|
||||||
|
| proofFileIds | Body | List<Long> | ✅ | 1~9 个,元素非空 | 取消凭证文件 ID |
|
||||||
|
| cancelFee | Body | BigDecimal | ❌ | ≥0,最多 2 位小数 | 取消费用(元) |
|
||||||
|
| remark | Body | String | ❌ | ≤200 字 | 备注 |
|
||||||
|
|
||||||
|
#### 出参
|
||||||
|
|
||||||
|
| 字段 | 类型 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| (整行) | HouseRoomTransferRespVO | 取消后的该行,字段同接口 1 的 `records[]` |
|
||||||
|
| status / statusLabel | String | CANCELLED / 已取消 |
|
||||||
|
| cancelReason | String | 恒为 `HOTEL_CANCELLED`;本接口触发的取消不会写入三个系统作废取值,那三个只由团期写口的系统收敛写入 |
|
||||||
|
| hotelConfirmNo | String | 本接口不接收确认号,恒为 `null`(未变) |
|
||||||
|
| cancelFee / proofFileIds | BigDecimal(String) / List<String> | 录入的取消费与凭证 |
|
||||||
|
|
||||||
|
#### 请求示例
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"proofFileIds": [88031, 88032],
|
||||||
|
"cancelFee": 0,
|
||||||
|
"remark": "酒店已免费取消"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 响应示例
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"message": "成功",
|
||||||
|
"data": {
|
||||||
|
"id": "9100235", "sourceType": "GROUP_BATCH", "sourceOrderId": null, "teamNo": null,
|
||||||
|
"sourceTeamNo": "HLT-20261012-004", "sourceGroupBatchId": "500322", "sourceBatchNo": "HLT-20261012-004",
|
||||||
|
"stayDate": "2026-10-15", "cityName": "满洲里", "hotelId": "60090", "hotelName": "满洲里丽景大酒店",
|
||||||
|
"roomTypeId": "70020", "roomTypeName": "行政大床房", "roomCount": 3, "remainingCount": 3,
|
||||||
|
"status": "CANCELLED", "statusLabel": "已取消", "risk": null, "riskLabel": null,
|
||||||
|
"hotelConfirmNo": null, "proofFileIds": ["88031", "88032"], "cancelFee": "0.00",
|
||||||
|
"cancelReason": "HOTEL_CANCELLED", "handlerName": "王芳", "handledAt": "2026-09-30T10:15:32",
|
||||||
|
"remark": "酒店已免费取消", "readOnly": false, "readOnlyReason": null
|
||||||
|
},
|
||||||
|
"success": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 空数据 / 降级响应
|
||||||
|
|
||||||
|
本接口无列表数据;任何失败都返回非 200 的 `code`,该行状态不变。
|
||||||
|
|
||||||
|
#### 错误响应
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 808324,
|
||||||
|
"message": "转出间数超过剩余 1 间",
|
||||||
|
"data": null,
|
||||||
|
"success": false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
| code | message | 触发 |
|
||||||
|
|------|---------|------|
|
||||||
|
| 400 | 凭证最多 9 个 / 凭证文件 ID 不能为空 / 取消费用不能为负 / 取消费用最多 2 位小数 / 备注不能超过 200 字 | 入参校验,未变 |
|
||||||
|
| 808090 | 未登录或非房务角色,无权操作 | 非房务角色,未变 |
|
||||||
|
| 808320 | 转房记录不存在 | id 不存在(未变;锁前锁后各判一次,同一个码) |
|
||||||
|
| 808326 | 只有原单处理人可以处理退团房间 | 非源单持有人且非超管,未变 |
|
||||||
|
| 808325 | 请填写酒店确认号并上传凭证 | 未上传凭证(本接口不要求确认号,文案沿用同一错误码),未变 |
|
||||||
|
| 808323 | 目标团期已确认,不能转入 | 【新增,仅团期来源行】源团期已不在「资源准备中」阶段。文案沿用 I-20 已发布的措辞,这里没有「目标」,实际含义是「源团期已不可再改动,不能取消这一行」 |
|
||||||
|
| 808321 | 该房间已处理 | 行已不是 PENDING,未变 |
|
||||||
|
| 808932 | 房务状态已被并发修改,请刷新后重试 | 【团期来源行新增触发场景】源团期或源计划行在读取时已不存在(并发被删/改);以及原有的 CAS 并发冲突 |
|
||||||
|
| 808324 | 转出间数超过剩余 {0} 间 | 【新增,仅团期来源行】源计划行已分配间数 > `roomCount − 本行剩余间数`,即空余不足以覆盖本行待取消间数;`{0}` = `max(roomCount − 已分配间数, 0)` |
|
||||||
|
| 100502 | 取消处理中,请勿重复提交 | 3 秒内重复提交,未变 |
|
||||||
|
|
||||||
|
#### 业务边界
|
||||||
|
|
||||||
|
- 只有源单持有人或超管可操作;凭证为空返回 808325(业务码,不是 400)。
|
||||||
|
- 校验顺序(团期来源行):808320(不锁定读)→ 808326 → 808325 → 808323(源团期栅栏)→ 808320(锁定读复验,同一个码)→ 808321 → 808932(源团期/源计划缺失)→ 808324(源计划空余不足)→ 808932(CAS 并发冲突)。常规单来源行没有 808323/808324 两步,其余顺序不变。
|
||||||
|
- 团期来源行取消成功后,源团期计划行的 `roomCount` 会在同一事务内按取消间数同步缩减;这一步对本接口响应体不可见,影响的是该房间此后是否还计入团期自动分配的可用余量。
|
||||||
|
- 成功后该行整行变为 CANCELLED,不再出现在待处理汇总里;已部分转出的行取消的是剩余部分。
|
||||||
|
|
||||||
|
## 四、契约约束与正确调用方式
|
||||||
|
|
||||||
|
- 接口 2 的团期来源行取消前,前端应先确认该行所属团期仍处于允许改动的阶段;若已收到 808323,不应重试,应提示房务该团期已不可再取消这一行。
|
||||||
|
- 接口 2 收到 808324 时,`message` 里的数字是此刻可取消的上限间数(可能为 0),不代表本行 `remainingCount`;不要直接拿 `remainingCount` 去重试提交。
|
||||||
|
- 接口 1 展示已取消行的原因文案时必须按 `cancelReason` 四个取值分支处理,不要假设该字段只有一个可能值;系统作废三种取值下 `handlerName` 为 `null` 是正常状态,不是数据缺失。
|
||||||
|
|
||||||
|
## 五、数据库行为
|
||||||
|
|
||||||
|
| 场景 | 团期计划行 `room_count` | 转房行 `status` / `remaining_count` |
|
||||||
|
|------|------|------|
|
||||||
|
| 常规单来源行(ORDER)取消 | 不涉及团期计划 | CANCELLED,其余字段照旧写入 |
|
||||||
|
| 团期来源行取消,源计划空余充足 | 按本次取消间数同步减少(`shrinkForTransfer`) | CANCELLED |
|
||||||
|
| 团期来源行取消,源计划空余不足(命中 808324) | 不变 | 不变,整体事务回滚 |
|
||||||
|
| 团期写口触发系统收敛(分房重算 / 自动分房 / 改计划间数 / 删计划 / 团期解散) | 视触发写口而定 | 全部覆盖:CANCELLED + 对应 `cancel_reason`;部分覆盖:仍 PENDING,`remaining_count` 减少 |
|
||||||
|
|
||||||
|
## 六、边界行为
|
||||||
|
|
||||||
|
- 转房行不存在或已被删除 → 808320(接口 2,未变)。
|
||||||
|
- 团期整团解散时,其下全部 PENDING 转房行在同一事务内作废(`cancelReason=GROUP_DISBANDED`),此后对这些行调用接口 2 会先命中 808321(已非 PENDING)。
|
||||||
|
- 源团期推进出「资源准备中」阶段后,其团期来源的 PENDING 行调用接口 2 会命中 808323;同一场景下调用 I-20(转房)此前已经是 808323,两个接口现在口径一致。
|
||||||
|
- 本单上线前已存在、且所属计划行已被删除但转房行仍是 PENDING 的存量脏数据,不会被本次新增的系统收敛机制回溯处理,仍会出现在接口 1 的列表里;对这类行调用接口 2,源团期已不在「资源准备中」时返回 808323,否则因源计划不存在返回 808932。
|
||||||
|
|
||||||
|
## 六.5、枚举
|
||||||
|
|
||||||
|
**cancelReason**(`house_room_transfer.cancel_reason`,仅 `status=CANCELLED` 时有值)
|
||||||
|
|
||||||
|
| 取值 | 中文 | 说明 | 是否本次新增 |
|
||||||
|
|------|------|------|------|
|
||||||
|
| HOTEL_CANCELLED | 房务人工向酒店取消 | 房务通过接口 2 主动办理 | 否 |
|
||||||
|
| GROUP_REALLOCATED | 本团已再分配 | 计划行还在,但空余已不足以覆盖待转间数——本团别的户分到了这批房,或计划间数被调少 | 是 |
|
||||||
|
| GROUP_PLAN_REMOVED | 本团已撤销该晚计划 | 待转房挂的计划行已不在活跃计划里:被删除、被替换成不同房型/酒店的新行,或缩减到 0 被整行删除 | 是 |
|
||||||
|
| GROUP_DISBANDED | 团期已解散 | 流团/解散时该团全部待转房一并作废 | 是 |
|
||||||
|
|
||||||
|
## 六.6、修改前后对比
|
||||||
|
|
||||||
|
**字段取值**
|
||||||
|
|
||||||
|
| 字段 | 改前 | 改后 |
|
||||||
|
|------|------|------|
|
||||||
|
| 接口 1 `records[].cancelReason` | 仅 `HOTEL_CANCELLED` 一个取值 | 新增 `GROUP_REALLOCATED` / `GROUP_PLAN_REMOVED` / `GROUP_DISBANDED` 三个取值 |
|
||||||
|
| 接口 2 错误码集合 | 808320 / 808321 / 808325 / 808326 / 808932(另有 400 / 808090 / 100502) | 团期来源行新增 808323、808324 |
|
||||||
|
|
||||||
|
**行为**
|
||||||
|
|
||||||
|
| 行为 | 改前 | 改后 |
|
||||||
|
|------|------|------|
|
||||||
|
| 本团某户分到已释放的团期房 | 原 PENDING 转房行照常留在池里,房务仍可在接口 2 / I-20 继续处理,存在一房两卖风险 | 团期写口在同一事务内收敛该计划行下的 PENDING 转房行,全部覆盖则整行作废并写入对应 `cancelReason`,部分覆盖则 `remaining_count` 减少 |
|
||||||
|
| 接口 2 对团期来源行的源团期状态 | 不做校验,源团期任意状态都能直接取消 | 源团期不在「资源准备中」时返回 808323 |
|
||||||
|
| 接口 2 取消团期来源行后源计划间数 | 不变 | 按取消间数同步缩减 |
|
||||||
|
| 接口 2 团期来源行空余不足 | 无此校验 | 返回 808324,行与源计划均不写入 |
|
||||||
|
|
||||||
|
## 六.7、影响评估
|
||||||
|
|
||||||
|
- 是否破坏向后兼容:否。`cancelReason` 是新增取值,不是重命名或语义变更;两个错误码是接口 2 的新增分支,不是复用/覆盖已有码的语义。
|
||||||
|
- 前端是否必须同步上线:是。不同步的话,系统作废行在列表上会落入未处理的 `cancelReason` 分支;团期来源行取消撞上 808323/808324 时若没有对应分支,会呈现为未识别错误。
|
||||||
|
- 前端 workaround 清理点:若此前把「`cancelReason` 非 `HOTEL_CANCELLED`」当异常兜底处理,需要改为按四个取值分别展示;否则无需清理,只需新增分支。
|
||||||
|
|
||||||
|
## 七、不影响范围
|
||||||
|
|
||||||
|
- 常规单来源行(`sourceType=ORDER`)在接口 2 的校验顺序、错误码与响应结构均未变化。
|
||||||
|
- 接口 1 的入参、分页结构、`summary` 汇总口径未变化。
|
||||||
|
- 转房接口 I-20 的请求/响应结构、错误码集合未新增,本单不改变其契约,仅修正一处原本应报 808324 却先报到 808932 的边界分支,不在本次变更接口清单内。
|
||||||
|
- 房务分房重建(H11)等团期写口自身的请求/响应契约未变化,只是这些写口在检测到需要收敛的 PENDING 转房行时会按本单的规则写入新的 `cancelReason`。
|
||||||
|
|
||||||
|
## 八、测试环境已验证
|
||||||
|
|
||||||
|
测试环境已验证(部署提交 405fc8db0,验证时刻 2026-09-30 10:22~10:41):
|
||||||
|
1. 转出间数超过计划剩余:`POST /v3/admin/order/house-console/room-transfers/{id}/cancel-hotel`,body code=808324("转出间数超过剩余 0 间"),转房行与计划行均无变化。
|
||||||
|
2. 团内户取消离团后另一户经重算分到房:`POST /v3/admin/order/{id}/cancel/pre-trip` + `POST /v3/admin/house/group-batches/{id}/allocations/rebuild`,转房行由 PENDING 变为 CANCELLED,`cancelReason=GROUP_REALLOCATED`,处理人为空,有对应操作日志。
|
||||||
|
3. 计划仍有空余时人工办理转出:`POST .../cancel-hotel`,body code=200,转房行变 CANCELLED/HOTEL_CANCELLED,计划 roomCount 由 2 减为 0 并软删(预期)。
|
||||||
|
|
||||||
|
## 十、相关文档
|
||||||
|
|
||||||
|
- 工单 #8615
|
||||||
|
- 参考发布契约:`changelogs-v2/2026-09/30_8491_房务控制台接口-新增接口-管理后台.md`(I-17 / I-20 / I-21 的既有字段与错误码定义)
|
||||||
|
|
||||||
|
## 关联 / 联系人
|
||||||
|
|
||||||
|
- 关联工单:#8615
|
||||||
|
- 关联历史 changelog:#8491
|
||||||
在新工单中引用
屏蔽一个用户