- #8385 团期订房计划建守卫(未认领团 808612)与 808660 释放文案 - #8386 住宿 supplier-reject 加角色门与认领校验,车务 supplier-reject 下线 - #8387 下线订单侧房间分配三口 /v3/admin/order/{id}/room - #8388 最终确认回执上传加认领校验、列表加读门、808184 带具体原因 - #8389 下线 POST /v3/admin/order/assignments/{assignmentId}/rooms - #8390 房务 16 个只读端点加角色读门,ADMIN 房务菜单撤授 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 | 8385 | 团期订房计划建守卫:超管未认领团上禁建(808612),释放文案改为可操作指引 | admin | wx(GIT) | 修改接口 | deployed | verified | pending | 超管在未被房务整团认领的团期上新建订房计划时返回 808612(复用已有码);释放端点的 808660 文案改为可操作的指引(删除计划、联系超管接管)。后端改动已合入 dev-v3 并部署测试服,808612 新守卫与 808660 新文案均已网关实测。 | 2026-09-26 | dev-v3 |
order-v3:团期订房计划守卫与释放指引改进(管理后台)
服务: hl-order-service-v3
PR: #8395
Issue: #8385
⚠️ 关键变化
-
新增入口守卫:超管(SUPER_ADMIN)在未被房务认领的团期上调用
POST /v3/admin/house/group-batches/{groupBatchId}/room-plans时,返回 808612「该团期尚未被房务整团认领」,不落库。- 背景:超管本可在无人认领的团上直接建计划,导致"团没人管、但计划和库存都在"的状态。释放时房务因为 808660 无法释放,只剩逐条删计划这一条路。
- 约束:超管要在团上排房,必须先
POST /v3/admin/order/grab-pool/group-batches/{groupBatchId}/takeover指派给某个房务,再建计划。
-
改进释放文案:端点
POST /v3/admin/order/grab-pool/group-batches/{groupBatchId}/release的错误码 808660 文案改为:
「该团仍有 {0} 条未取消的订房计划,无法释放:请先逐条删除订房计划后再释放;如需更换认领房务请联系超管接管」- 改前文案提到的「走接管」对房务不可用(接管只有超管能做)。改后提供两条可行出口:删除计划(房务自助)/ 联系超管接管(超管权限)。
一、背景
团期整团认领的唯一真实指针是 order_group_batch.house_claimer_id。超管出于"人离职、团转手"的清理需要被允许越过认领校验,但在一个没人认领、也不需要清理的团上直接建计划,不属于这类处置。
释放时的 808660 守卫堵住了"有计划+无认领人"的释放口,文案则指向一个房务无法执行的操作(接管),导致房务被无谓地卡住。
二、变更接口清单
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|---|---|---|---|---|---|
| 1 | 提交订房计划 | POST | /v3/admin/house/group-batches/{groupBatchId}/room-plans |
新增入口守卫 | 超管未认领团上返回 808612 |
| 2 | 释放认领 | POST | /v3/admin/order/grab-pool/group-batches/{groupBatchId}/release |
错误码文案改进 | 808660 文案改为可操作指引 |
网关无改动(既有 /v3/admin/house/ 与 /v3/admin/order/ 前缀均可达);返回码、触发条件、已认领团的行为全部不变。
三、接口详情
1. 提交订房计划 POST /v3/admin/house/group-batches/{groupBatchId}/room-plans
VO: GroupBatchRoomPlanSaveReqVO → Result<List<GroupBatchRoomPlanRespVO>>
使用场景
房务或超管在团期上提交多条订房计划(房型、房数、价格、结算方式、库存扣减等)。超管在未认领的团上调用时新增拒绝,改后只能通过先 takeover 指派给房务的方式排房。
入参字段表
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| groupBatchId | Path | Long | 是 | — | 团期 ID |
| items | Body | List | 是 | ≤200 条 | 订房计划行 |
| items[].stayDate | Body | LocalDate | 是 | 格式 yyyy-MM-dd |
入住日期 |
| items[].hotelId | Body | Long | 是 | — | 酒店 ID |
| items[].roomTypeId | Body | Long | 是 | — | 房型 ID |
| items[].roomCount | Body | Integer | 是 | ≥1 | 房间数 |
| items[].roomCategory | Body | String | 否 | ≤32 | 房型大类 code;服务端以 resource 权威值覆盖,仅用于前端回显 |
| items[].protoPrice | Body | BigDecimal | 否 | ≥0 | 协议价快照;不传按「日历价 → 酒店协议价」兜底 |
| items[].settlementPrice | Body | BigDecimal | 否 | ≥0 | 结算价快照;不传按「日历价 → 协议价」兜底 |
| items[].settleType | Body | String | 否 | cash | sign | company |
结算方式;不传取酒店资源配置 |
| items[].deductInventory | Body | Boolean | 否 | 默认 true | 是否扣库存 |
| items[].remark | Body | String | 否 | ≤512 | 备注 |
| items[].version | Body | Integer | 否 | — | 乐观锁版本;本端点(批量新建)不校验,只有单行修改端点必填并校验 |
| items[].replaceReason | Body | String | 否 | ≤256 | 替换原因;本端点不使用,仅单行修改端点在语义为"删旧建新"时使用 |
出参字段表
| 字段 | 类型 | 说明 |
|---|---|---|
| planId | String | 计划行 ID(雪花 ID,序列化为字符串) |
| groupBatchId | String | 团期 ID(雪花 ID,序列化为字符串) |
| stayDate | LocalDate | 入住日期 |
| hotelId / hotelName | String / String | 酒店 ID(序列化为字符串)及名称 |
| roomTypeId / roomTypeName | String / String | 房型 ID(序列化为字符串)及名称 |
| roomCount | Integer | 房间数 |
| protoPrice | String | 协议价快照,可为 null(BigDecimal,序列化为字符串) |
| settlementPrice | String | 结算价快照,可为 null(BigDecimal,序列化为字符串) |
| settleType | String | 结算方式快照,可为 null |
| planStatus | String | 状态码(PENDING / CONFIRMED) |
| version | Integer | 乐观锁版本号 |
请求示例
POST /v3/admin/house/group-batches/2099918391610314754/room-plans HTTP/1.1
Host: api.test.1814.love:9443
Authorization: Bearer <admin token>
Content-Type: application/json
{
"items": [
{
"stayDate": "2026-10-01",
"hotelId": 1001,
"roomTypeId": 5001,
"roomCount": 2,
"settlementPrice": 450.00,
"deductInventory": true,
"remark": "标准间"
}
]
}
响应示例
成功(已认领团):
{
"code": 200,
"message": "成功",
"success": true,
"data": [
{
"planId": "2103794613192208385",
"groupBatchId": "2099918391610314754",
"stayDate": "2026-10-01",
"hotelId": "1001",
"hotelName": "丽思卡尔顿",
"roomTypeId": "5001",
"roomTypeName": "豪华标间",
"roomCount": 2,
"settlementPrice": "450.00",
"planStatus": "PENDING",
"version": 1,
"createTime": "2026-09-26 14:30:00"
}
]
}
失败(未认领团,超管):
{
"code": 808612,
"message": "该团期尚未被房务整团认领",
"success": false,
"data": null
}
空数据 / 降级响应
- 参数校验失败(日期格式错、房间数 ≤0):HTTP 200,
code=400,message 含具体字段文案;不落库。
错误响应
{
"code": 808612,
"message": "该团期尚未被房务整团认领",
"success": false,
"data": null
}
其他错误码:
- 808090:未登录或非房务角色,无权操作。
- 808091:房务组长为只读监督角色,无权执行该操作(HOUSE_KEEPER_LEAD)。
- 808613:该团期由其他房务认领,无权操作。
- 808600:团期当前阶段不允许修改订房计划(订房计划仅在配置阶段可改)。
- 808614:该入住日在酒店的该房型上已有订房计划,请改用修改单行。
- 808611:团期出发日或结束日缺失,无法录入订房计划。
- 808602:入住日不在团期出行区间内。
- 808603:订房间数必须大于 0。
- 808691:无法确定房型大类(取权威房型数据失败),请稍后重试。
- 808112:房型不属于该酒店。
- 100502:3 秒幂等窗口内重复提交,「订房计划提交处理中,请勿重复提交」。
业务边界
- 整团认领:认领人本人或超管可提交;非认领房务提交返回 808613;团未认领(
house_claimer_id IS NULL)时所有人(含超管)返回 808612。 - 超管排房出口:超管要在未认领的团上排房,必须先
POST /v3/admin/order/grab-pool/group-batches/{groupBatchId}/takeover指派给房务,再来提交计划。 - 库存扣减:
deductInventory=true时,CONFIRMED 状态的计划会扣掉resource_hotel_room_inventory对应房型该日的可用房数;PENDING 阶段不扣。 - 日期范围:入住日期必须在团期的出发日期与结束日期之间。
2. 释放认领 POST /v3/admin/order/grab-pool/group-batches/{groupBatchId}/release
VO: HouseGroupReleaseReqVO → Result<Void>
使用场景
房务释放所有团期认领,团回到抢单池状态(house_claimer_id → NULL)。房务有订房计划待处理时返回 808660,文案告知删除计划或联系超管接管两条出口。
入参字段表
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| groupBatchId | Path | Long | 是 | — | 团期 ID |
| reason | Body | String | 否 | ≤200 字 | 释放原因;超管必填且不少于 10 字 |
出参字段表
| 字段 | 类型 | 说明 |
|---|---|---|
| — | null | 成功返回 null |
请求示例
POST /v3/admin/order/grab-pool/group-batches/2099918391610314754/release HTTP/1.1
Host: api.test.1814.love:9443
Authorization: Bearer <room_manager token>
Content-Type: application/json
{
"reason": "已完成配房"
}
响应示例
成功:
{
"code": 200,
"message": "成功",
"success": true,
"data": null
}
失败(有计划待删):
{
"code": 808660,
"message": "该团仍有 4 条未取消的订房计划,无法释放:请先逐条删除订房计划后再释放;如需更换认领房务请联系超管接管",
"success": false,
"data": null
}
空数据 / 降级响应
不适用。
错误响应
{
"code": 808660,
"message": "该团仍有 4 条未取消的订房计划,无法释放:请先逐条删除订房计划后再释放;如需更换认领房务请联系超管接管",
"success": false,
"data": null
}
其他错误码:
- 808655:该团期不属于当前房务,无法释放;非认领人释放时触发(超管不受此限),CAS 并发失败(读到时归本人、提交时已被超管释放/接管)也报此码。
- 808656:该团期尚未被认领,无需释放。
- 808657:超管操作原因长度不足 10 字(房务释放时 reason 可为空)。
- 808090:未登录或非房务角色,无权操作。
- 808091:房务组长为只读监督角色,无权执行该操作(HOUSE_KEEPER_LEAD)。
业务边界
- 释放前置:须先删光全部未取消的订房计划(PENDING + CONFIRMED)才能释放;所有角色(含超管)受 808660 约束,release 本身不碰计划行。
- 幂等:幂等键按团(
groupBatchId),窗口 5 秒;窗口内重复提交返回 100502「整团释放处理中,请勿重复提交」。
四、契约约束与正确调用方式
| 场景 | 调用方法 | 说明 |
|---|---|---|
| ✅ 超管先排房再指派 | 先 POST /v3/admin/order/grab-pool/group-batches/{id}/takeover 指派给房务 → 再 POST .../room-plans 提交 |
takeover 让团被指定房务认领,之后超管仍可在上面操作 |
| ✅ 房务提交计划 | POST /v3/admin/house/group-batches/{id}/room-plans |
认领的房务可随时提交,RESOURCE_PREPARING 阶段有效 |
| ✅ 房务释放有计划 | 先 DELETE /v3/admin/house/group-batches/{id}/room-plans/{planId} 逐条删 → 再 POST .../release |
删除由 HouseGroupBatchClaimGuard 控制,认领人可删(含他人建的),释放成功返回 200 |
| ❌ 超管在未认领团直接建计划 | — | 返回 808612,需先 takeover 指派 |
| ❌ 有计划待删时释放 | — | 返回 808660,不释放;先删后释 |
五、数据库行为
无表结构变更、无 Flyway 迁移。
六、边界行为
| 场景 | 行为 |
|---|---|
| 超管 POST room-plans on 未认领团 | 返回 808612,group_batch_room_plan 零新增 |
| 超管 takeover 后 POST room-plans | 返回 200,计划行正常落库 |
| 房务释放、仍有 PENDING 计划 | 返回 808660,计数含 PENDING |
| 房务删掉全部计划、再释放 | 返回 200,团回到池里 |
| 超管释放、仍有计划 | 同样返回 808660(不分角色) |
六.6、修改前后对比
| 维度 | 改前 | 改后 |
|---|---|---|
| 超管在未认领团上 POST room-plans | 返回 200,计划落库,团仍无主 | 返回 808612,不落库 |
| 释放时有计划、808660 文案 | 「无法释放(请先处理订房计划或走接管)」 | 「无法释放:请先逐条删除订房计划后再释放;如需更换认领房务请联系超管接管」 |
六.7、影响评估
- 兼容性:hl-ui 在
origin/v2.1上房务页面无调用takeover(该接口仍在,超管直接用也可以);超管排房流程可能需要调整为"先指派再排"。 - 前端要动的:房务页面若有"直接排房"的超管入口,需提示"未认领团先指派再排";释放时若遇到 808660,按改后文案提示房务删除计划。
- 数据影响:无;本单仅加守卫,不改历史数据。
- 其它服务:product-v2、fleet、user-service 无改动。
七、不影响范围
- 已认领团的超管操作(确认、分房、delete 等)全部不动。
- 更新/删除/确认计划的守卫不动(仍走
assertWritableByCurrentUser,超管仍可清理)。 - 其他团期相关接口(认领、接管、整团确认等)无改动。
八、测试环境已验证
部署:测试环境 order-v3 1f65d7894(含 e2313790b)。网关 api.test.1814.love:9443。
| # | 场景 | 实测结果 |
|---|---|---|
| 1 | 超管 POST 未认领团(RESOURCE_PREPARING) | code 808612,计划行零新增 |
| 2 | 该团由超管 takeover 给某房务后,超管再 POST | code 200 |
| 3 | 超管 DELETE 上一步新增的计划行 | code 200,releasedLogId=null |
| 4 | 该房务 release | code 200,团回到无主 |
| 5 | 另一认领房务逐条 DELETE 自己团的 4 条 PENDING 计划 | 全部 200(releasedLogId=null) |
| 6 | 上一步之后 release | code 200 |
| 7 | 超管对他人认领团的存量计划行 DELETE(62 行) | 全部 200 |
| 8 | 认领房务在团上挂 1 条 PENDING 计划时 release | code 808660,message「该团仍有 1 条未取消的订房计划,无法释放:请先逐条删除订房计划后再释放;如需更换认领房务请联系超管接管」,与源码逐字一致 |
| 9 | 删掉该计划后再 release | code 200,团回到无主 |
十、相关文档
- Issue:wx/HL#8385
- PR:wx/HL#8395
- takeover API:
POST /v3/admin/order/grab-pool/group-batches/{groupBatchId}/takeover - 同批单号:#8386、#8387、#8388、#8389、#8390(房务接口审计批次)
关联 / 联系人
联系人
- 后端负责人: @wx