三份交接件:新增房务控制台接口,下线旧的房务列表接口,调整配房接口的字段与口径。每份的「测试环境已验证」一节填测试服实测读数。 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
66 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 | 8491 | 房务配房接口调整:任务类型、只读标识、早餐、改配记录、转单名单校验、读权限对全体房务开放 | admin | wx(GIT) | 修改接口 | deployed | not_required | pending | 2026-09-30 | dev-v3 |
房务配房: 15 个既有接口的字段与口径调整(任务类型 / 只读标识 / 早餐 / 改配记录 / 转单名单校验 / 读权限开放)
存放目录: 二期 →
changelogs-v2/2026-09/服务: hl-order-service-v3 Issue: #8491 日期: 2026-09-29 影响范围: 管理后台「房务控制台」的常规单 / 团期列表、订单房务详情弹窗、逐晚配房与改配、转单 / 超管指派、房务待办、团期房务看板与订房计划
⚠️ 关键变化(非必须,本版与上版行为不同 / 纠错 / 撤销时必写)
- 户级转单与超管指派(接口 7)在房务人员名单取不到时改为拒绝,返回 808343「房务人员名单暂不可用,请稍后重试」,需求持有人不变。改前该情况放行。只有超管「整团接管」
POST /v3/admin/order/grab-pool/group-batches/{groupBatchId}/takeover在名单取不到时仍放行,接收人姓名显示占位user-{id}。 - 「房务组长」角色取消:错误码 808091、808092、582204 已删除且不复用。原组长账号访问房务接口返回 808090「未登录或非房务角色,无权操作」。
- 读权限对全体房务开放:待办
scope=all/others、团期看板scope=ALL、团期看板详情 / 房间需求 / 分房总览 / 确认前检查,普通房务都能看他人持有与未认领的数据;这些读接口不再因「不是本人认领」返回 808612 / 808613。写接口仍校验归属,仍返回 808612 / 808613 / 808110。 - 列表与详情新增
readOnly/readOnlyReason:- 户级(常规单行、非团期订单的详情)超管不豁免:超管看别人持有的单同样
readOnly=true,要改须先「指派」或「转单」给自己; - 团期级(团期行、团期子订单的详情、看板详情)超管豁免,超管恒为
readOnly=false。
- 户级(常规单行、非团期订单的详情)超管不豁免:超管看别人持有的单同样
- 配房行与团期订房计划新增早餐
breakfast(INCLUDED / EXCLUDED / PENDING)与房源roomSource(STOCK / HOTEL);订单房务详情逐晚新增nightRoomSource,配房行新增subtotal。 - 改晚次 / 酒店 / 房型 / 间数(接口 6)在换酒店或减间数时写一条改配记录,出现在订单房务详情的
changes[];原订为非控房且未上传取消凭证时记录为HELD,须在房务控制台做「取消确认」。
一、背景(选填)
#8491 把房务日常操作收拢到「房务控制台」。本文件只写既有接口因此发生的变化:列表按任务类型(新订 / 修改 / 退团)筛选并带未读数与只读标识;配房与团期订房计划记录早餐;改配留痕;转单在名单取不到时不再放行;取消「房务组长」只读监督角色,改为全体房务可读、写仍按归属。控制台新增的 17 个接口见同目录新增接口文件,下线的 4 个旧列表接口见同目录删除接口文件。
二、变更接口清单
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|---|---|---|---|---|---|
| 1 | 常规单配房列表 | GET | /v3/admin/order/house-allocation/households |
修改 | 新增入参 taskKind;行新增 taskKind / unreadCount / readOnly |
| 2 | 团期配房列表 | GET | /v3/admin/order/house-allocation/group-batches |
修改 | 新增入参 taskKind;行新增 taskKind / unreadCount / readOnly |
| 3 | 订单房务详情 | GET | /admin/house/orders/{orderId} |
修改 | 新增 taskKind / readOnly / changes;逐晚 nightRoomSource;配房行 breakfast / roomSource / subtotal |
| 4 | 逐晚提交配房 | POST | /v3/admin/order/hotel-requirements/{requirementId}/assignments |
修改 | items[] 新增 breakfast |
| 5 | 修改配房 | PUT | /v3/admin/order/assignments/{id} |
修改 | 新增 breakfast |
| 6 | 改晚次 / 酒店 / 房型 / 间数 | PUT | /v3/admin/order/hotel-requirements/{requirementId}/assignments/{id}/placement |
修改 | 新增 breakfast 与取消凭证 / 取消费 / 改配备注;换酒店或减间数写改配记录 |
| 7 | 转单 / 超管指派 | POST | /v3/admin/order/hotel-requirements/{requirementId}/transfer |
修改 | 名单取不到返回 808343 |
| 8 | 房务待办列表 | GET | /v3/admin/order/todos |
修改 | scope=all/others 对全体房务开放,582204 删除 |
| 9 | 团期房务看板列表 | GET | /v3/admin/house/group-batches |
修改 | scope=ALL 对全体房务开放,808092 删除 |
| 10 | 团期房务看板详情 | GET | /v3/admin/house/group-batches/{groupBatchId} |
修改 | 全体房务可看;新增 readOnly;计划行带早餐与房源 |
| 11 | 团期房间需求 | GET | /v3/admin/house/group-batches/{groupBatchId}/room-requirements |
修改 | 全体房务可看 |
| 12 | 团期分房总览 | GET | /v3/admin/house/group-batches/{groupBatchId}/allocations |
修改 | 全体房务可看;计划与分房行带早餐与房源 |
| 13 | 团期计划确认前检查 | GET | /v3/admin/house/group-batches/{groupBatchId}/room-plans/confirm-check |
修改 | 全体房务可看 |
| 14 | 团期订房计划保存 | POST | /v3/admin/house/group-batches/{groupBatchId}/room-plans |
修改 | items[] 新增 breakfast;响应带早餐与房源 |
| 15 | 团期订房计划修改 | PUT | /v3/admin/house/group-batches/{groupBatchId}/room-plans/{planId} |
修改 | 新增 breakfast;响应带早餐与房源 |
三、接口详情
本节示例 JSON 的字段名、类型、错误码与文案逐一取自源码;ID、日期、金额、姓名等取值为说明用的构造值。所有接口统一返回 Result 信封(code / message / data / traceId / success),示例省略 traceId;业务失败与入参校验失败均为 HTTP 200,靠 code 区分。ID 与金额字段序列化为字符串。入参 / 出参表只列本次新增或口径变化的字段及路径参数,未列出的字段名、类型与含义均不变。
1. 常规单配房列表 GET /v3/admin/order/house-allocation/households
VO: HouseAllocationHouseholdPageReqVO → HouseAllocationHouseholdPageRespVO
使用场景
房务控制台「常规单」页签。新增按任务类型(新订 / 修改 / 退团)筛选;行内显示任务类型标签、房务会话未读数,并按 readOnly 置灰操作按钮、用 readOnlyReason 提示「由谁处理」。
入参
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| taskKind | Query | String | ❌ | NEW / CHANGE / WITHDRAWAL,或不传 | 新增。任务类型筛选;不传不筛。筛选在分页之前生效,total 与 stats 七个计数都按筛选后的结果算 |
| scope | Query | String | ❌ | all / mine,默认 all | 不变 |
| status | Query | String | ❌ | pendingClaim / unfinished / claiming / pendingConfirm / confirmed / exception,默认 unfinished | 不变 |
| page | Query | Integer | ❌ | ≥1,默认 1 | 不变 |
| pageSize | Query | Integer | ❌ | 1~100,默认 20 | 不变 |
出参 Result<HouseAllocationHouseholdPageRespVO>
| 字段 | 类型 | 说明 |
|---|---|---|
| list | List | 行列表 |
| total | Long | 总数(受 taskKind 筛选) |
| stats | HouseAllocationHouseholdStatsVO | pendingClaim / claiming / pendingConfirm / confirmed / exception / unfinished / all,结构不变,受 taskKind 筛选 |
| list[].taskKind | String | 新增。NEW / CHANGE / WITHDRAWAL,规则见六.5 |
| list[].taskKindLabel | String | 新增。新订 / 修改 / 退团 |
| list[].unreadCount | Integer | 新增。该订单房务会话未读数;取不到按 0 |
| list[].readOnly | Boolean | 新增。待认领、本人持有为 false;他人持有为 true;超管看他人持有的单同样为 true |
| list[].readOnlyReason | String | 新增。readOnly=true 时为「由 {姓名} 处理」,姓名为空时为「由其他房务处理」;可写时为 null |
请求示例
GET /v3/admin/order/house-allocation/households?scope=all&status=unfinished&taskKind=CHANGE&page=1&pageSize=20
响应示例
{
"code": 200,
"message": "成功",
"data": {
"list": [
{
"id": "1940000000000000011",
"orderId": "1930000000000000021",
"orderNo": "26-0915",
"teamNo": "26-0920",
"guestName": "李女士一家",
"houseStatus": "CLAIMING",
"houseStatusLabel": "配房中",
"claimerId": "30002",
"claimerName": "王芳",
"isMine": false,
"canStartAllocation": false,
"taskKind": "CHANGE",
"taskKindLabel": "修改",
"unreadCount": 2,
"readOnly": true,
"readOnlyReason": "由 王芳 处理"
}
],
"total": 1,
"stats": {
"pendingClaim": 0,
"claiming": 1,
"pendingConfirm": 0,
"confirmed": 0,
"exception": 0,
"unfinished": 1,
"all": 1
}
},
"success": true
}
空数据 / 降级响应
- 筛选无结果:
list=[]、total=0,stats各项为 0。 - 任务类型取数失败时按空集处理,行的
taskKind显示NEW;按CHANGE/WITHDRAWAL筛选返回空页。 - 未读数取不到时
unreadCount=0,不影响列表其余字段。
错误响应
{
"code": 400,
"message": "taskKind 只能是 NEW、CHANGE 或 WITHDRAWAL",
"data": null,
"success": false
}
其余错误:
| code | message | 触发 |
|---|---|---|
| 808090 | 未登录或非房务角色,无权操作 | 非房务角色(含原房务组长账号) |
业务边界
- 一行同时满足退团与修改时显示
WITHDRAWAL(退团优先)。 readOnly只决定按钮状态;真正的拒绝由写接口的错误码决定(例如配房写接口的 808110)。- 超管要改别人持有的常规单,先调接口 7 把需求指派给自己,指派成功后该行
readOnly=false。
2. 团期配房列表 GET /v3/admin/order/house-allocation/group-batches
VO: HouseAllocationGroupPageReqVO → HouseAllocationGroupPageRespVO
使用场景
房务控制台「团期」页签。与接口 1 相同,新增任务类型筛选、未读数与只读标识;团期的只读判定超管豁免。
入参
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| taskKind | Query | String | ❌ | NEW / CHANGE / WITHDRAWAL,或不传 | 新增。任务类型筛选;不传不筛;筛选在分页之前生效 |
| batchStatus | Query | String | ❌ | RECRUITING / RESOURCE_PREPARING / MATERIAL_PREPARING / PENDING_DEPARTURE / TRAVELLING / TRIP_FINISHED / REVIEWING / SETTLED / CANCELLED | 取值不变(校验常量移入本 VO) |
| scope | Query | String | ❌ | all / mine,默认 all | 不变 |
| status | Query | String | ❌ | pendingClaim / claimed | 不变 |
| page | Query | Integer | ❌ | ≥1,默认 1 | 不变 |
| pageSize | Query | Integer | ❌ | 1~100,默认 20 | 不变 |
出参 Result<HouseAllocationGroupPageRespVO>
| 字段 | 类型 | 说明 |
|---|---|---|
| list | List | 行列表 |
| total | Long | 总数(受 taskKind 筛选) |
| stats | HouseAllocationGroupStatsVO | pendingClaim / claimed / all,结构不变 |
| list[].taskKind | String | 新增。NEW / CHANGE / WITHDRAWAL |
| list[].taskKindLabel | String | 新增。新订 / 修改 / 退团 |
| list[].unreadCount | Integer | 新增。团下活跃子订单房务会话未读数之和;取不到按 0 |
| list[].readOnly | Boolean | 新增。待认领、本人认领、超管为 false;他人认领为 true |
| list[].readOnlyReason | String | 新增。readOnly=true 时为「由 {姓名} 处理」或「由其他房务处理」;可写时为 null |
请求示例
GET /v3/admin/order/house-allocation/group-batches?scope=all&status=claimed&taskKind=WITHDRAWAL&page=1&pageSize=20
响应示例
{
"code": 200,
"message": "成功",
"data": {
"list": [
{
"groupBatchId": "1950000000000000031",
"batchNo": "GB261005",
"batchName": "呼伦贝尔秋色 6 日",
"batchStatus": "PENDING_DEPARTURE",
"batchStatusLabel": "待出发",
"departDate": "2026-10-05",
"houseClaimerId": "30001",
"houseClaimerName": "张敏",
"isMine": true,
"canStartAllocation": true,
"taskKind": "WITHDRAWAL",
"taskKindLabel": "退团",
"unreadCount": 0,
"readOnly": false,
"readOnlyReason": null
}
],
"total": 1,
"stats": {
"pendingClaim": 0,
"claimed": 1,
"all": 1
}
},
"success": true
}
空数据 / 降级响应
- 筛选无结果:
list=[]、total=0。 - 任务类型取数失败按空集处理,行显示
NEW;未读数取不到按 0。
错误响应
{
"code": 400,
"message": "taskKind 只能是 NEW、CHANGE 或 WITHDRAWAL",
"data": null,
"success": false
}
其余错误:
| code | message | 触发 |
|---|---|---|
| 808090 | 未登录或非房务角色,无权操作 | 非房务角色(含原房务组长账号) |
业务边界
- 团下任一订单为退团 / 修改,该团期即为退团 / 修改;退团另含「以该团期为来源、仍待处理的退团房转房」。
- 团期只读判定超管豁免:超管对任何团期
readOnly=false。
3. 订单房务详情 GET /admin/house/orders/{orderId}
VO: orderId + requirementId → HouseOrderDetailRespVO
使用场景
房务打开订单房务详情弹窗。新增任务类型、只读标识、改配记录 changes[](控制台「取消确认」的入口数据),逐晚新增整晚房源,配房行新增早餐、房源与小计。注意本接口路径没有 /v3 前缀。
入参
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| orderId | Path | Long | ✅ | - | 订单 ID |
| requirementId | Query | Long | ❌ | 须属于该订单 | 不传返回当前生效需求;传入可查看历史作废版本(不变) |
出参 Result<HouseOrderDetailRespVO>
| 字段 | 类型 | 说明 |
|---|---|---|
| taskKind | String | 新增。NEW / CHANGE / WITHDRAWAL;取数异常时为 NEW |
| taskKindLabel | String | 新增。新订 / 修改 / 退团 |
| readOnly | Boolean | 新增。团期子订单按团期判定(团期认领人,超管豁免);其余订单按需求持有人判定(超管不豁免);团期判定取数失败时回退为按需求持有人判定 |
| readOnlyReason | String | 新增。「由 {姓名} 处理」或「由其他房务处理」;可写时为 null |
| changes | List | 新增。改配记录,按创建时间倒序;无记录或取数失败时为 [] |
| changes[].changeId | Long | 改配记录 ID,调控制台「取消确认」用 |
| changes[].assignmentId | Long | 被改的配房行 ID |
| changes[].changeKind | String | HOTEL / ROOM_COUNT |
| changes[].oldStatus | String | HELD / CANCEL_CONFIRMED |
| changes[].oldStatusLabel | String | 原酒店待取消 / 已确认取消 |
| changes[].cancelFee | BigDecimal | 取消费用(元),可为 null |
| changes[].proofFileIds | List | 取消凭证文件 ID |
| changes[].remark | String | 备注 |
| changes[].operatorName | String | CANCEL_CONFIRMED 时为确认人,否则为改配操作人 |
| changes[].createTime | LocalDateTime | 记录时间 |
| itinerary[].nightRoomSource | String | 新增。SELF / STOCK / HOTEL / MIXED / UNSET,见六.5 |
| itinerary[].nightRoomSourceLabel | String | 新增。客人自订 / 控房 / 非控房 / 混合 / 待选择 |
| itinerary[].assignments[].breakfast | String | 新增。INCLUDED / EXCLUDED / PENDING;库里为空输出 PENDING |
| itinerary[].assignments[].breakfastLabel | String | 新增。含早餐 / 不含早餐 / 早餐待确认 |
| itinerary[].assignments[].roomSource | String | 新增。STOCK / HOTEL,由 deductInventory 推导,不单独存储 |
| itinerary[].assignments[].roomSourceLabel | String | 新增。控房 / 非控房 |
| itinerary[].assignments[].subtotal | BigDecimal | 新增。roomCount × settlementPrice,2 位小数;任一为 null 时为 null |
请求示例
GET /admin/house/orders/1930000000000000021
响应示例
{
"code": 200,
"message": "成功",
"data": {
"taskKind": "CHANGE",
"taskKindLabel": "修改",
"readOnly": false,
"readOnlyReason": null,
"changes": [
{
"changeId": "1960000000000000041",
"assignmentId": "1970000000000000051",
"changeKind": "HOTEL",
"oldStatus": "HELD",
"oldStatusLabel": "原酒店待取消",
"cancelFee": null,
"proofFileIds": [],
"remark": "客人要求换到河景房",
"operatorName": "张敏",
"createTime": "2026-09-28 15:20:00"
}
],
"itinerary": [
{
"dayNumber": 1,
"stayDate": "2026-10-05",
"cityName": "海拉尔",
"nightRoomSource": "MIXED",
"nightRoomSourceLabel": "混合",
"assignments": [
{
"assignmentId": "1970000000000000052",
"hotelName": "海拉尔河畔酒店",
"roomTypeName": "高级双床房",
"confirmStatus": "INQUIRING",
"roomCount": 2,
"settlementPrice": "380.00",
"deductInventory": true,
"breakfast": "INCLUDED",
"breakfastLabel": "含早餐",
"roomSource": "STOCK",
"roomSourceLabel": "控房",
"subtotal": "760.00"
},
{
"assignmentId": "1970000000000000053",
"hotelName": "海拉尔雅园宾馆",
"roomTypeName": "标准大床房",
"confirmStatus": "INQUIRING",
"roomCount": 1,
"settlementPrice": null,
"deductInventory": false,
"breakfast": "PENDING",
"breakfastLabel": "早餐待确认",
"roomSource": "HOTEL",
"roomSourceLabel": "非控房",
"subtotal": null
}
]
}
]
},
"success": true
}
空数据 / 降级响应
- 无改配记录或改配记录取数失败:
changes=[],详情其余部分照常返回。 - 某晚没有配房行且非客人自订:
nightRoomSource="UNSET",assignments=[]。 - 任务类型取数异常:
taskKind="NEW"。
错误响应
{
"code": 808141,
"message": "该订单非房务可见",
"data": null,
"success": false
}
其余错误:
| code | message | 触发 |
|---|---|---|
| 808100 | 需求不存在 | 传入的 requirementId 不属于该订单 |
| 808090 | 未登录或非房务角色,无权操作 | 非房务角色(含原房务组长账号) |
业务边界
readOnly的口径因订单类型而异:团期子订单跟团期认领人走、超管豁免;其他订单跟需求持有人走、超管不豁免。changes[]里oldStatus=HELD的记录才可调控制台「取消确认」;CANCEL_CONFIRMED为已办结。- 客人自订的那一晚
nightRoomSource="SELF",不看配房行。 subtotal只用结算价计算,不含协议价。
4. 逐晚提交配房 POST /v3/admin/order/hotel-requirements/{requirementId}/assignments
VO: AssignmentSubmitReqVO → AssignmentSubmitRespVO
使用场景
房务在订单房务详情里为各晚提交配房。本次 items[] 每行新增早餐 breakfast。
入参
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| requirementId | Path | Long | ✅ | - | 住宿需求 ID |
| items | Body | List | ✅ | 非空 | 逐晚配房行(不变) |
| items[].breakfast | Body | String | ❌ | INCLUDED / EXCLUDED / PENDING;传空串校验失败 | 新增。早餐;不传存为空、读出为 PENDING |
| items[].dayNumber | Body | Integer | ✅ | ≥1 | 不变 |
| items[].hotelId | Body | Long | ✅ | - | 不变 |
| items[].roomTypeId | Body | Long | ✅ | - | 不变 |
| items[].roomCount | Body | Integer | ✅ | ≥1 | 不变 |
| items[].deductInventory | Body | Boolean | ❌ | - | 不变;true 即控房(roomSource=STOCK) |
出参 Result<AssignmentSubmitRespVO>
| 字段 | 类型 | 说明 |
|---|---|---|
| successCount | Integer | 不变 |
| failCount | Integer | 不变 |
| items | List | dayNumber / assignmentId / arrange / deductInventory,不变 |
请求示例
{
"items": [
{
"dayNumber": 1,
"hotelId": 100001,
"roomTypeId": 300001,
"roomCount": 2,
"settlementPrice": "380.00",
"deductInventory": true,
"breakfast": "INCLUDED"
}
]
}
响应示例
{
"code": 200,
"message": "成功",
"data": {
"successCount": 1,
"failCount": 0,
"items": [
{
"dayNumber": 1,
"assignmentId": "1970000000000000052",
"arrange": "pending",
"deductInventory": true
}
]
},
"success": true
}
空数据 / 降级响应
本接口为写接口,无降级分支;失败返回非 200 的 code,不落库。
错误响应
{
"code": 400,
"message": "breakfast 只能是 INCLUDED / EXCLUDED / PENDING",
"data": null,
"success": false
}
其余错误(本次未变,列出便于对照):
| code | message | 触发 |
|---|---|---|
| 808090 | 未登录或非房务角色,无权操作 | 非房务角色(含原房务组长账号) |
| 808116 | 订单未抢单, 请先抢单再配房 | 需求无人持有 |
| 808110 | 需求不属于当前用户 | 当前登录人不是持有人(超管同样拒绝) |
业务边界
- 同一需求 3 秒内重复提交被防重拦截。
- 提交时保留下来的既有配房行:
breakfast传了才改,不传保持原值。 breakfast传null等同不传;传空串""返回 400。
5. 修改配房 PUT /v3/admin/order/assignments/{id}
VO: AssignmentUpdateReqVO → Result<Void>
使用场景
房务修改单个配房行的价格、结算方式、备注。本次新增 breakfast。
入参
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| id | Path | Long | ✅ | - | 配房行 ID |
| breakfast | Body | String | ❌ | INCLUDED / EXCLUDED / PENDING | 新增。不传保持原值 |
| protoPrice | Body | BigDecimal | ❌ | ≥0 | 不变 |
| settlementPrice | Body | BigDecimal | ❌ | ≥0 | 不变 |
出参 Result<Void>
| 字段 | 类型 | 说明 |
|---|---|---|
| data | null | 成功无返回体 |
请求示例
{
"settlementPrice": "360.00",
"breakfast": "EXCLUDED"
}
响应示例
{
"code": 200,
"message": "成功",
"data": null,
"success": true
}
空数据 / 降级响应
写接口,成功时 data 恒为 null;无降级分支。
错误响应
{
"code": 599602,
"message": "应付款台账行已锁定",
"data": null,
"success": false
}
其余错误:
| code | message | 触发 |
|---|---|---|
| 400 | breakfast 只能是 INCLUDED / EXCLUDED / PENDING | 入参校验 |
| 808090 | 未登录或非房务角色,无权操作 | 非房务角色 |
| 808116 | 订单未抢单, 请先抢单再配房 | 需求无人持有 |
| 808110 | 需求不属于当前用户 | 当前登录人不是持有人(超管同样拒绝) |
业务边界
- 599602(本次未变):已确认(CONFIRMED)的配房行改价格时,若该行对应的应付款台账行已有在途付款申请,拒绝改价,配房行不变。
- 只改
breakfast不涉及价格,不触发 599602。
6. 改晚次 / 酒店 / 房型 / 间数 PUT /v3/admin/order/hotel-requirements/{requirementId}/assignments/{id}/placement
VO: AssignmentPlacementUpdateReqVO → Result<Void>
使用场景
房务对已配的某行换晚次、换酒店 / 房型、改间数。本次新增早餐,以及换酒店或减间数时对原订的取消信息(凭证、费用、备注)。
入参
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| requirementId | Path | Long | ✅ | - | 当前生效住宿需求 ID |
| id | Path | Long | ✅ | - | 配房行 ID |
| dayNumber | Body | Integer | ✅ | ≥1 | 目标晚次(不变) |
| hotelId | Body | Long | ✅ | - | 目标酒店(不变) |
| roomTypeId | Body | Long | ✅ | - | 目标房型(不变) |
| roomCount | Body | Integer | ✅ | ≥1 | 目标间数(不变) |
| deductInventory | Body | Boolean | ❌ | - | 不变 |
| breakfast | Body | String | ❌ | INCLUDED / EXCLUDED / PENDING | 新增。不传保持原值 |
| cancelProofFileIds | Body | List | ❌ | 最多 9 个 | 新增。原订取消凭证 |
| cancelFee | Body | BigDecimal | ❌ | ≥0,整数最多 10 位、小数最多 2 位 | 新增。原订取消费用(元) |
| changeRemark | Body | String | ❌ | ≤200 字 | 新增。改配备注 |
出参 Result<Void>
| 字段 | 类型 | 说明 |
|---|---|---|
| data | null | 成功无返回体;改配记录在订单房务详情 changes[] 查看 |
请求示例
{
"dayNumber": 1,
"hotelId": 100002,
"roomTypeId": 300005,
"roomCount": 1,
"deductInventory": false,
"breakfast": "INCLUDED",
"cancelProofFileIds": [],
"changeRemark": "客人要求换到河景房"
}
响应示例
{
"code": 200,
"message": "成功",
"data": null,
"success": true
}
空数据 / 降级响应
写接口,成功时 data 恒为 null;无降级分支。
错误响应
{
"code": 400,
"message": "cancelProofFileIds 最多 9 个",
"data": null,
"success": false
}
其余错误:
| code | message | 触发 |
|---|---|---|
| 400 | cancelFee 不能为负数 / cancelFee 最多 10 位整数、2 位小数 / changeRemark 最长 200 字 / breakfast 只能是 INCLUDED / EXCLUDED / PENDING | 入参校验 |
| 808090 | 未登录或非房务角色,无权操作 | 非房务角色 |
| 808116 | 订单未抢单, 请先抢单再配房 | 需求无人持有 |
| 808110 | 需求不属于当前用户 | 当前登录人不是持有人(超管同样拒绝) |
业务边界
- 何时写改配记录:换了酒店记
changeKind=HOTEL(优先);同酒店但间数减少记ROOM_COUNT;间数增加或未变不写记录,此时cancelProofFileIds/cancelFee/changeRemark不落库。 - 记录状态:原配房行是控房(
deductInventory=true),或上传了至少一个取消凭证 → 直接CANCEL_CONFIRMED;原行为非控房且没传凭证 →HELD,须在房务控制台对该记录做「取消确认」。 HELD记录会让该订单在列表中显示taskKind=CHANGE,并出现在房务控制台异常检查的HOTEL_CANCEL_PENDING(原酒店待取消)项里;不生成房务待办。- 目标行的确认状态重置为
INQUIRING,已确认(CONFIRMED)的行同样重置。已知缺口 #8508:对 CONFIRMED 行执行本接口时不校验应付款台账行是否锁定(不返回 599602),也不处理该行的应付款。
7. 转单 / 超管指派 POST /v3/admin/order/hotel-requirements/{requirementId}/transfer
VO: HouseTransferReqVO → Result<Void>
使用场景
普通房务把自己持有的常规单需求转给同事;超管把任意常规单需求指派给某个房务(包括指派给自己,用于解除 readOnly)。同一路径按登录身份分流。
入参
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| requirementId | Path | Long | ✅ | - | 住宿需求 ID |
| toUserId | Body | Long | ✅ | 须在房务人员名单内 | 接收人 adminId |
| reason | Body | String | ❌ | ≤200 字;超管须 ≥10 字 | 原因;普通房务可不填(记为「转单」) |
| skipUpperLimit | Body | Boolean | ❌ | - | 历史字段,不变 |
出参 Result<Void>
| 字段 | 类型 | 说明 |
|---|---|---|
| data | null | 成功无返回体,前端刷新列表与详情 |
请求示例
{
"toUserId": 30002,
"reason": "客人改到下周出行,转给负责该线路的同事"
}
响应示例
{
"code": 200,
"message": "成功",
"data": null,
"success": true
}
空数据 / 降级响应
无降级:房务人员名单取不到(调用异常、返回空)时直接返回 808343,需求持有人不变。改前该情况放行。
错误响应
{
"code": 808343,
"message": "房务人员名单暂不可用,请稍后重试",
"data": null,
"success": false
}
其余错误:
| code | message | 触发 |
|---|---|---|
| 400 | toUserId 不能为空 / reason 长度不超过 200 字 | 入参校验 |
| 808090 | 未登录或非房务角色,无权操作 | 非房务角色(含原房务组长账号) |
| 808016 | 超管指派原因长度不足 10 字 | 超管 reason 不足 10 字 |
| 808002 | 需求已不存在 | requirementId 不存在 |
| 808650 | 团期订单须整团认领后配房,不支持逐户认领 / 转单 | 团期子订单的需求(普通房务一律;超管在团期已被认领时) |
| 808010 | 需求不属于当前用户,无法转单 | 普通房务转别人持有的需求 |
| 808014 | 接收人就是当前归属人,无需操作 | toUserId 等于当前持有人 |
| 808013 | 一单转单次数达上限(3 次) | 普通房务;超管指派不受限 |
| 808011 | 接收人不存在或已离职 | 名单可用但不含 toUserId |
| 808001 | 该需求已被其他房务认领或状态已变化,请刷新后重试 | 并发改持有人;需求未被认领 |
| 808930 | 配房状态机非法流转:原状态={0},事件={1} | 需求状态不允许转单 |
业务边界
- 808343 同时作用于普通房务转单与超管指派;前端收到后保持弹窗,提示用户重试。
- 名单可用、接收人在名单里但姓名为空时,接收人姓名记为
user-{id}。 - 团期层面的换人不走本接口:团期持有人用新增接口「团期转交」,超管用「整团接管」
POST /v3/admin/order/grab-pool/group-batches/{groupBatchId}/takeover;后者在名单取不到时仍放行并记user-{id}。 - 需求级有写锁,同一需求的并发转单串行执行。
8. 房务待办列表 GET /v3/admin/order/todos
VO: HouseTodoPageReqVO → HouseTodoListRespVO
使用场景
房务查看待办。scope=all(全部)与 scope=others(同事在处理)改为全体房务可用,不再限组长 / 超管。
入参
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| scope | Query | String | ❌ | mine / others / all,不传为 mine | 口径变化:others / all 对全体房务开放 |
| todoType | Query | String | ❌ | 多选逗号分隔 | 不变 |
| 分页参数 | Query | - | ❌ | 继承通用分页参数 | 不变 |
出参 Result<HouseTodoListRespVO>
| 字段 | 类型 | 说明 |
|---|---|---|
| list | List | 不变 |
| total | long | 不变 |
| stats | HouseTodoStatsVO | 不变;JSON 键为大写待办类型(SWAP_HOTEL / REFUND / … / UNREAD_CHAT) |
请求示例
GET /v3/admin/order/todos?scope=all
响应示例
{
"code": 200,
"message": "成功",
"data": {
"list": [
{
"id": "1980000000000000061",
"todoType": "REQUIREMENT_ADJUSTED",
"todoTypeLabel": "需求调整",
"title": "客人调整入住人数",
"status": "OPEN",
"orderId": "1930000000000000021",
"orderNo": "26-0915",
"teamNo": "26-0920",
"guestName": "李女士一家"
}
],
"total": 1,
"stats": {
"SWAP_HOTEL": 0,
"REFUND": 0,
"INVENTORY_CHECK_OVERDUE": 0,
"RETURN_TO_HK": 0,
"REQUIREMENT_ADJUSTED": 1,
"HOTEL_REPLY_TIMEOUT": 0,
"PENDING_ARRANGE": 0,
"PENDING_FINALIZE": 0,
"UNREAD_CHAT": 0
}
},
"success": true
}
空数据 / 降级响应
无待办时 list=[]、total=0,stats 各项为 0。
错误响应
{
"code": 582201,
"message": "查询范围取值非法(仅支持我的/他人/全部)",
"data": null,
"success": false
}
其余错误:582204 已删除,普通房务传 scope=all / others 不再报错。
业务边界
scope=mine含未归属的待办;others为同事在处理的;all为全部。- 看到同事的待办不代表能处理:处理动作仍按订单归属校验。
9. 团期房务看板列表 GET /v3/admin/house/group-batches
VO: HouseGroupBatchBoardPageReqVO → PageResult<HouseGroupBatchBoardSimpleRespVO>
使用场景
团期房务看板列表。scope=ALL 改为全体房务可用。
入参
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| scope | Query | String | ❌ | MINE / ALL,≤8 字符,默认 MINE | 口径变化:ALL 对全体房务开放 |
| claimerAdminId | Query | Long | ❌ | - | 按认领人筛选(不变) |
| keyword | Query | String | ❌ | ≤32 字 | 不变 |
| page | Query | Long | ❌ | ≥1,默认 1 | 不变 |
| pageSize | Query | Long | ❌ | 1~50,默认 20 | 不变 |
出参 Result<PageResult<HouseGroupBatchBoardSimpleRespVO>>
| 字段 | 类型 | 说明 |
|---|---|---|
| records | List | 结构不变 |
| total | int | 不变 |
| page | int | 不变 |
| pageSize | int | 不变 |
请求示例
GET /v3/admin/house/group-batches?scope=ALL&page=1&pageSize=20
响应示例
{
"code": 200,
"message": "成功",
"data": {
"records": [
{
"groupBatchId": "1950000000000000031",
"batchNo": "GB261005",
"batchName": "呼伦贝尔秋色 6 日",
"batchStatus": "PENDING_DEPARTURE",
"departDate": "2026-10-05",
"claimerAdminId": "30002",
"claimerName": "王芳",
"demandDays": 5,
"plannedDays": 5,
"confirmedDays": 3,
"mismatchDays": 0
}
],
"total": 1,
"page": 1,
"pageSize": 20
},
"success": true
}
空数据 / 降级响应
无数据时 records=[]、total=0。
错误响应
{
"code": 808090,
"message": "未登录或非房务角色,无权操作",
"data": null,
"success": false
}
其余错误:
| code | message | 触发 |
|---|---|---|
| 400 | scope 非法 / keyword 最长 32 字 / pageSize 最大 50 | 入参校验 |
808092 已删除,普通房务传 scope=ALL 不再报错。
业务边界
- 列表只读,看得见不等于能写;写团期计划仍须本人认领(808612 / 808613)。
10. 团期房务看板详情 GET /v3/admin/house/group-batches/{groupBatchId}
VO: groupBatchId → HouseGroupBatchBoardRespVO
使用场景
打开某个团期的房务看板。全体房务可看他人认领与未认领的团期,按新字段 readOnly 决定是否可编辑。
入参
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| groupBatchId | Path | Long | ✅ | - | 团期 ID |
出参 Result<HouseGroupBatchBoardRespVO>
| 字段 | 类型 | 说明 |
|---|---|---|
| readOnly | Boolean | 新增。未认领、本人认领、超管为 false;他人认领为 true |
| readOnlyReason | String | 新增。「由 {姓名} 处理」或「由其他房务处理」;可写时为 null |
| days[].plans | List | 计划行,新增 breakfast / breakfastLabel / roomSource / roomSourceLabel(同接口 14 出参) |
| 其余字段 | - | 不变 |
请求示例
GET /v3/admin/house/group-batches/1950000000000000031
响应示例
{
"code": 200,
"message": "成功",
"data": {
"groupBatchId": "1950000000000000031",
"batchNo": "GB261005",
"claimerAdminId": "30002",
"claimerName": "王芳",
"readOnly": true,
"readOnlyReason": "由 王芳 处理",
"days": [
{
"stayDate": "2026-10-05",
"dayNumber": 1,
"plans": [
{
"planId": "1990000000000000071",
"hotelName": "海拉尔河畔酒店",
"roomTypeName": "高级双床房",
"roomCount": 12,
"deductInventory": true,
"breakfast": "INCLUDED",
"breakfastLabel": "含早餐",
"roomSource": "STOCK",
"roomSourceLabel": "控房"
}
]
}
]
},
"success": true
}
空数据 / 降级响应
团期尚无订房计划时 days[].plans=[];未认领团期 readOnly=false、claimerAdminId=null。
错误响应
{
"code": 808090,
"message": "未登录或非房务角色,无权操作",
"data": null,
"success": false
}
其余错误:查看他人认领或未认领的团期不再返回 808612 / 808613。
业务边界
- 本接口的 Swagger 说明仍提到 808612 / 808613,以本文为准:读取不校验认领归属。
readOnly=false的未认领团期仍须先整团认领才能写计划,否则写接口返回 808612。
11. 团期房间需求 GET /v3/admin/house/group-batches/{groupBatchId}/room-requirements
VO: groupBatchId → HouseGroupBatchRoomRequirementRespVO
使用场景
看板里查看团期逐晚、逐户的房间需求。本次只放开读权限,响应结构不变。
入参
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| groupBatchId | Path | Long | ✅ | - | 团期 ID |
出参 Result<HouseGroupBatchRoomRequirementRespVO>
| 字段 | 类型 | 说明 |
|---|---|---|
| groupBatchId | Long | 不变 |
| days | List | 不变 |
| householdsWithoutBasis | List | 不变 |
| outOfRangeHouseholds | List | 不变 |
请求示例
GET /v3/admin/house/group-batches/1950000000000000031/room-requirements
响应示例
{
"code": 200,
"message": "成功",
"data": {
"groupBatchId": "1950000000000000031",
"batchNo": "GB261005",
"departDate": "2026-10-05",
"endDate": "2026-10-10",
"days": [],
"householdsWithoutBasis": [],
"outOfRangeHouseholds": []
},
"success": true
}
空数据 / 降级响应
无需求时各列表为 []。
错误响应
{
"code": 808090,
"message": "未登录或非房务角色,无权操作",
"data": null,
"success": false
}
其余错误:查看他人认领或未认领的团期不再返回 808612 / 808613。
业务边界
- 只读接口,全体房务可看;不涉及写入。
12. 团期分房总览 GET /v3/admin/house/group-batches/{groupBatchId}/allocations
VO: groupBatchId → GroupBatchRoomAllocationOverviewRespVO
使用场景
看板里查看团期逐晚计划与分户分房。本次放开读权限,计划行与分房行新增早餐与房源。
入参
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| groupBatchId | Path | Long | ✅ | - | 团期 ID |
出参 Result<GroupBatchRoomAllocationOverviewRespVO>
| 字段 | 类型 | 说明 |
|---|---|---|
| days[].plans[].breakfast | String | 新增。INCLUDED / EXCLUDED / PENDING |
| days[].plans[].breakfastLabel | String | 新增。含早餐 / 不含早餐 / 早餐待确认 |
| days[].plans[].roomSource | String | 新增。STOCK / HOTEL |
| days[].plans[].roomSourceLabel | String | 新增。控房 / 非控房 |
| days[].plans[].allocations[].breakfast | String | 新增。取自所属计划行 |
| days[].plans[].allocations[].breakfastLabel | String | 新增。取自所属计划行 |
| days[].plans[].allocations[].roomSource | String | 新增。取自所属计划行 |
| days[].plans[].allocations[].roomSourceLabel | String | 新增。取自所属计划行 |
| 其余字段 | - | 不变 |
请求示例
GET /v3/admin/house/group-batches/1950000000000000031/allocations
响应示例
{
"code": 200,
"message": "成功",
"data": {
"groupBatchId": "1950000000000000031",
"batchNo": "GB261005",
"balanced": true,
"days": [
{
"stayDate": "2026-10-05",
"plannedRooms": 12,
"allocatedRooms": 12,
"plans": [
{
"planId": "1990000000000000071",
"hotelName": "海拉尔河畔酒店",
"roomTypeName": "高级双床房",
"plannedRooms": 12,
"allocatedRooms": 12,
"leftoverRooms": 0,
"breakfast": "INCLUDED",
"breakfastLabel": "含早餐",
"roomSource": "STOCK",
"roomSourceLabel": "控房",
"allocations": [
{
"allocId": "2000000000000000081",
"orderId": "1930000000000000022",
"teamNo": "26-0921",
"orderNo": "26-0916",
"roomCount": 2,
"breakfast": "INCLUDED",
"breakfastLabel": "含早餐",
"roomSource": "STOCK",
"roomSourceLabel": "控房"
}
]
}
],
"households": []
}
],
"blockedHouseholds": []
},
"success": true
}
空数据 / 降级响应
无计划时 days=[];计划行没有分房时 allocations=[]。
错误响应
{
"code": 808090,
"message": "未登录或非房务角色,无权操作",
"data": null,
"success": false
}
其余错误:查看他人认领或未认领的团期不再返回 808612 / 808613。
业务边界
- 分房行的早餐与房源不单独存储,恒等于所属计划行。
- 同一控制器的两个写接口(保存手工分房、重建)仍校验认领归属。
13. 团期计划确认前检查 GET /v3/admin/house/group-batches/{groupBatchId}/room-plans/confirm-check
VO: groupBatchId → GroupBatchRoomConfirmCheckRespVO
使用场景
确认团期订房计划前的预检。本次只放开读权限,响应结构不变。
入参
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| groupBatchId | Path | Long | ✅ | - | 团期 ID |
出参 Result<GroupBatchRoomConfirmCheckRespVO>
| 字段 | 类型 | 说明 |
|---|---|---|
| ready | Boolean | 不变 |
| days | List | 不变 |
| 其余字段 | - | 不变 |
请求示例
GET /v3/admin/house/group-batches/1950000000000000031/room-plans/confirm-check
响应示例
{
"code": 200,
"message": "成功",
"data": {
"groupBatchId": "1950000000000000031",
"batchStatus": "PENDING_DEPARTURE",
"stageAllowed": true,
"baselineExists": true,
"hotelReady": true,
"ready": true,
"blockedByOutOfRange": false,
"days": [],
"noBaselineOrders": [],
"outOfRangeOrders": []
},
"success": true
}
空数据 / 降级响应
无计划时 days=[],ready 按检查结果给出。
错误响应
{
"code": 808090,
"message": "未登录或非房务角色,无权操作",
"data": null,
"success": false
}
其余错误:查看他人认领或未认领的团期不再返回 808612 / 808613。
业务边界
- 预检可看,确认计划的写接口仍校验认领归属。
14. 团期订房计划保存 POST /v3/admin/house/group-batches/{groupBatchId}/room-plans
VO: GroupBatchRoomPlanSaveReqVO → List<GroupBatchRoomPlanRespVO>
使用场景
团期认领人批量新增订房计划行。本次 items[] 新增早餐,响应计划行新增早餐与房源。
入参
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| groupBatchId | Path | Long | ✅ | - | 团期 ID |
| items | Body | List | ✅ | 1~200 行 | 计划行(不变) |
| items[].breakfast | Body | String | ❌ | INCLUDED / EXCLUDED / PENDING | 新增。不传存为空、读出为 PENDING |
| items[].stayDate | Body | LocalDate | ✅ | - | 不变 |
| items[].hotelId | Body | Long | ✅ | - | 不变 |
| items[].roomTypeId | Body | Long | ✅ | - | 不变 |
| items[].roomCount | Body | Integer | ✅ | ≥1 | 不变 |
| items[].settleType | Body | String | ❌ | cash / sign / company | 不变 |
| items[].deductInventory | Body | Boolean | ❌ | - | 不变;true 即控房 |
出参 Result<List<GroupBatchRoomPlanRespVO>>
| 字段 | 类型 | 说明 |
|---|---|---|
| [].breakfast | String | 新增。INCLUDED / EXCLUDED / PENDING |
| [].breakfastLabel | String | 新增。含早餐 / 不含早餐 / 早餐待确认 |
| [].roomSource | String | 新增。STOCK / HOTEL,由 deductInventory 推导 |
| [].roomSourceLabel | String | 新增。控房 / 非控房 |
| 其余字段 | - | 不变 |
请求示例
{
"items": [
{
"stayDate": "2026-10-05",
"hotelId": 100001,
"roomTypeId": 300001,
"roomCount": 12,
"settlementPrice": "360.00",
"settleType": "sign",
"deductInventory": true,
"breakfast": "INCLUDED"
}
]
}
响应示例
{
"code": 200,
"message": "成功",
"data": [
{
"planId": "1990000000000000071",
"groupBatchId": "1950000000000000031",
"stayDate": "2026-10-05",
"hotelName": "海拉尔河畔酒店",
"roomTypeName": "高级双床房",
"roomCount": 12,
"settlementPrice": "360.00",
"settleType": "sign",
"deductInventory": true,
"breakfast": "INCLUDED",
"breakfastLabel": "含早餐",
"roomSource": "STOCK",
"roomSourceLabel": "控房",
"version": 0
}
],
"success": true
}
空数据 / 降级响应
写接口,无降级分支;失败返回非 200 的 code,不落库。
错误响应
{
"code": 808613,
"message": "该团期由其他房务认领,无权操作",
"data": null,
"success": false
}
其余错误:
| code | message | 触发 |
|---|---|---|
| 400 | items 不能为空 / items 一次最多 200 行 / breakfast 只能是 INCLUDED / EXCLUDED / PENDING | 入参校验 |
| 808090 | 未登录或非房务角色,无权操作 | 非房务角色 |
| 808612 | 该团期尚未被房务整团认领 | 团期未认领 |
业务边界
- 写仍校验团期认领归属;读权限的放开不影响本接口。
- 团期计划行不涉及 599602。
15. 团期订房计划修改 PUT /v3/admin/house/group-batches/{groupBatchId}/room-plans/{planId}
VO: GroupBatchRoomPlanItemReqVO → GroupBatchRoomPlanRespVO
使用场景
团期认领人修改单个订房计划行。本次新增早餐。
入参
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| groupBatchId | Path | Long | ✅ | - | 团期 ID |
| planId | Path | Long | ✅ | - | 计划行 ID |
| version | Body | Integer | ✅ | - | 乐观锁版本(不变) |
| breakfast | Body | String | ❌ | INCLUDED / EXCLUDED / PENDING | 新增。不传保持原值 |
| replaceReason | Body | String | ❌ | ≤256 字 | 不变 |
出参 Result<GroupBatchRoomPlanRespVO>
| 字段 | 类型 | 说明 |
|---|---|---|
| breakfast | String | 新增 |
| breakfastLabel | String | 新增 |
| roomSource | String | 新增 |
| roomSourceLabel | String | 新增 |
| 其余字段 | - | 不变 |
请求示例
{
"version": 0,
"breakfast": "EXCLUDED"
}
响应示例
{
"code": 200,
"message": "成功",
"data": {
"planId": "1990000000000000071",
"groupBatchId": "1950000000000000031",
"roomCount": 12,
"deductInventory": true,
"breakfast": "EXCLUDED",
"breakfastLabel": "不含早餐",
"roomSource": "STOCK",
"roomSourceLabel": "控房",
"version": 1
},
"success": true
}
空数据 / 降级响应
写接口,无降级分支。
错误响应
{
"code": 808612,
"message": "该团期尚未被房务整团认领",
"data": null,
"success": false
}
其余错误:
| code | message | 触发 |
|---|---|---|
| 400 | version 不能为空 / breakfast 只能是 INCLUDED / EXCLUDED / PENDING | 入参校验 |
| 808090 | 未登录或非房务角色,无权操作 | 非房务角色 |
| 808613 | 该团期由其他房务认领,无权操作 | 他人认领 |
业务边界
- 不传
breakfast时原值保留:原地修改与「删旧建新」两条路径都保留原早餐。
四、契约约束与正确调用方式(接口类必写)
本节只写后端接受/拒绝 payload 的规则,不写 UI 渲染建议。
✅ 正确 / ❌ 错误 payload 对照
| 场景 | payload |
|---|---|
| ✅ 早餐未知时不传 | { "items": [ { "dayNumber": 1, "hotelId": 100001, "roomTypeId": 300001, "roomCount": 1 } ] } → 读出 breakfast=PENDING |
| ✅ 显式标待确认 | { "breakfast": "PENDING" } |
| ❌ 早餐传空串 | { "breakfast": "" } → 400 breakfast 只能是 INCLUDED / EXCLUDED / PENDING |
| ❌ 早餐传中文 | { "breakfast": "含早" } → 400 |
| ✅ 换酒店并附原订取消凭证 | { "dayNumber": 1, "hotelId": 100002, "roomTypeId": 300005, "roomCount": 1, "cancelProofFileIds": [1930000000000000501] } → 记录直接 CANCEL_CONFIRMED |
| ❌ 取消凭证超 9 个 | { ..., "cancelProofFileIds": [1,2,3,4,5,6,7,8,9,10] } → 400 cancelProofFileIds 最多 9 个 |
| ❌ 取消费为负 | { ..., "cancelFee": "-1" } → 400 cancelFee 不能为负数 |
| ❌ 超管指派原因过短 | { "toUserId": 30002, "reason": "改派" } → 808016 |
| ❌ 列表 taskKind 小写 | ?taskKind=change → 400 taskKind 只能是 NEW、CHANGE 或 WITHDRAWAL |
切换状态时的必要动作
- 超管要编辑别人持有的常规单:先调接口 7 把需求指派给自己,再调配房写接口;直接写返回 808110。
- 收到 808343:持有人没变,保持当前界面,由用户重试。
- 改晚次 / 酒店 / 房型 / 间数成功后,重新拉取订单房务详情,读取新的
changes[]与taskKind。 HELD改配记录办结走房务控制台「取消确认」接口,changeId取自changes[].changeId。
五、数据库行为(涉及写操作时必写)
| 前端提交 | 写入位置 | 行为 |
|---|---|---|
| 逐晚提交配房 | 配房行 breakfast 列 |
新建行:传则写入,未传写空(读出 PENDING);保留的既有行:传了才改 |
| 修改配房 | 配房行 | 未传 breakfast 保持原值;价格变更规则不变 |
| 改晚次 / 酒店 / 房型 / 间数 | 配房行、house_assignment_change |
目标行确认状态置 INQUIRING;换酒店或减间数时新增一条改配记录(HELD 或 CANCEL_CONFIRMED) |
| 转单 / 超管指派 | 需求认领字段 | CAS 换持有人;808343 / 808011 时不写 |
| 团期订房计划保存 | 团期订房计划行 breakfast 列 |
传则写入,未传写空 |
| 团期订房计划修改 | 团期订房计划行 | 未传 breakfast 保持原值,删旧建新时也带过去 |
显式 SET NULL 说明: 本次新增字段都不支持「传 null 清空」:breakfast 传 null 等同不传(新建写空、修改保持原值),要改回待确认须显式传 PENDING。改配记录的 cancelFee / cancelProofFileIds / changeRemark 只在写入新记录时落库,间数增加或未变时忽略。
六、边界行为
- 已登录但不是房务角色(ROOM_MANAGER / SUPER_ADMIN 以外)→ 808090「未登录或非房务角色,无权操作」;原「房务组长」账号同样返回 808090。
- 读接口不校验认领归属,全体房务可看;写接口仍校验:常规单 808116 / 808110,团期 808612 / 808613。
readOnly与写接口的拒绝口径一致:户级超管不豁免(对应 808110 超管同样拒绝),团期级超管豁免。- 常规单列表的 Swagger 字段说明写「超管为 false」,与实际行为不符,以本文为准:户级
readOnly超管不豁免。 - 581045「房务角色无权查看订单详情,房务仅可配房」只改说明文字(去掉组长),码值与文案不变。
- 599602 出现位置(本次均未变):修改配房对已确认行改价格、删除配房行
DELETE /v3/admin/order/assignments/{id}、清空需求配房DELETE /v3/admin/order/hotel-requirements/{requirementId}/assignments,以及房务控制台退团房转房(来源为订单时)。含义:该配房行对应的应付款台账行已有在途付款申请而被锁定。团期订房计划不涉及 599602。
六.5、枚举 / 数据字典(接口出现枚举时必写)
taskKind(HouseTaskKind)
所属字段: HouseAllocationHouseholdRespVO.taskKind、HouseAllocationGroupRespVO.taskKind、HouseOrderDetailRespVO.taskKind,及列表入参 taskKind / 类型: String
| 值 | 中文 | 说明 |
|---|---|---|
WITHDRAWAL |
退团 | 订单有未关闭的退款待办,或有以该订单为来源、仍待处理的退团房转房;团期行:团下任一订单为退团,或有以该团期为来源、仍待处理的转房;优先级最高 |
CHANGE |
修改 | 订单有未关闭的需求调整待办(与列表 isRework 同一口径),或有 HELD 改配记录;团期行:团下任一订单为修改 |
NEW |
新订 | 以上都不满足;某项判据取数失败时该项按空集处理 |
breakfast(HouseBreakfast)
所属字段: 配房行与团期订房计划行的 breakfast(入参与出参) / 类型: String
| 值 | 中文 | 说明 |
|---|---|---|
INCLUDED |
含早餐 | - |
EXCLUDED |
不含早餐 | - |
PENDING |
早餐待确认 | 未填时按此输出 |
roomSource(HouseRoomSource)
所属字段: 配房行与团期订房计划行、团期分房行的 roomSource / 类型: String
| 值 | 中文 | 说明 |
|---|---|---|
STOCK |
控房 | deductInventory=true |
HOTEL |
非控房 | deductInventory 为 false 或空 |
nightRoomSource(订单房务详情逐晚)
所属字段: HouseOrderDetailRespVO.itinerary[].nightRoomSource / 类型: String
| 值 | 中文 | 说明 |
|---|---|---|
SELF |
客人自订 | 该晚客人自订 |
STOCK |
控房 | 该晚配房行全部为控房 |
HOTEL |
非控房 | 该晚配房行全部为非控房 |
MIXED |
混合 | 该晚同时有控房与非控房 |
UNSET |
待选择 | 该晚没有配房行 |
changeKind(HouseAssignmentChangeConstants)
所属字段: HouseOrderDetailRespVO.changes[].changeKind / 类型: String
| 值 | 中文 | 说明 |
|---|---|---|
HOTEL |
换酒店 | 同时减间数也记为此值 |
ROOM_COUNT |
减间数 | 同酒店、间数减少 |
oldStatus(HouseAssignmentChangeConstants)
所属字段: HouseOrderDetailRespVO.changes[].oldStatus / 类型: String
| 值 | 中文 | 说明 |
|---|---|---|
HELD |
原酒店待取消 | 可在房务控制台做取消确认 |
CANCEL_CONFIRMED |
已确认取消 | 已办结 |
待办 scope
所属字段: HouseTodoPageReqVO.scope / 类型: String
| 值 | 中文 | 说明 |
|---|---|---|
mine |
我的 | 含未归属;不传时的默认值 |
others |
他人 | 同事在处理的;全体房务可用 |
all |
全部 | 全体房务可用 |
看板 scope
所属字段: HouseGroupBatchBoardPageReqVO.scope / 类型: String
| 值 | 中文 | 说明 |
|---|---|---|
MINE |
我的 | 默认 |
ALL |
全部 | 全体房务可用 |
已删除错误码
所属字段: Result.code / 类型: Integer
| 值 | 中文 | 说明 |
|---|---|---|
808091 |
房务组长为只读监督角色,无权执行该操作 | 已删除,不复用 |
808092 |
无权查看全部房务订单(仅房务组长或超管可查看) | 已删除,不复用 |
582204 |
无权查看全部/他人房务待办(仅房务组长或超管可查看) | 已删除,不复用 |
六.6、修改前后对比(修改/删除接口必写)
字段级对比
| 字段 | 改前 | 改后 |
|---|---|---|
常规单 / 团期列表入参 taskKind |
无 | NEW / CHANGE / WITHDRAWAL,可选 |
常规单 / 团期列表行 taskKind / taskKindLabel |
无 | 有 |
常规单 / 团期列表行 unreadCount |
无 | 有,取不到为 0 |
列表行、订单房务详情、看板详情 readOnly / readOnlyReason |
无 | 有 |
订单房务详情 changes[] |
无 | 改配记录,倒序 |
订单房务详情 itinerary[].nightRoomSource / nightRoomSourceLabel |
无 | 有 |
配房行 breakfast / breakfastLabel / roomSource / roomSourceLabel / subtotal |
无 | 有 |
团期计划行、分房行 breakfast / breakfastLabel / roomSource / roomSourceLabel |
无 | 有 |
配房写入参 breakfast |
无 | 可选 |
改晚次等入参 cancelProofFileIds / cancelFee / changeRemark |
无 | 可选 |
行为级对比
| 行为 | 改前 | 改后 |
|---|---|---|
| 户级转单 / 超管指派,房务人员名单取不到 | 放行 | 返回 808343,不换持有人 |
| 原房务组长账号访问房务接口 | 可读,写返回 808091 | 返回 808090 |
| 普通房务查待办 scope=all / others | 返回 582204 | 放行 |
| 普通房务查看板 scope=ALL | 返回 808092 | 放行 |
| 查看他人认领 / 未认领团期的看板详情、房间需求、分房总览、确认前检查 | 返回 808612 / 808613 | 放行,看板详情给出 readOnly |
| 换酒店或减间数 | 不留记录 | 写改配记录(HELD 或 CANCEL_CONFIRMED) |
六.7、影响评估
- 是否破坏向后兼容: 是。户级转单 / 超管指派在名单取不到时由放行改为 808343;808091 / 808092 / 582204 三个码删除,按这三个码映射文案或分支的前端逻辑不再被触发。新增字段均为追加,旧字段含义不变。
- 前端是否必须同步上线: 否。新增入参均为可选,旧前端不传照常工作;但 808343 的提示需要前端能展示后端
message。 - 前端 workaround 清理点: 组长只读视图、按 808091 / 808092 / 582204 做的分支与文案;按「是否本人认领」自行推导按钮置灰的逻辑,改为直接读
readOnly/readOnlyReason。
七、不影响范围(显式声明, 帮前端/QA 缩小排查面)
- 仅影响: 管理后台房务相关页面(房务控制台常规单 / 团期列表、订单房务详情弹窗、团期房务看板与订房计划、房务待办)。
- 零影响:
- 小程序与 H5(本文接口均为管理端路由)
- 写接口的归属校验口径:常规单 808116 / 808110、团期 808612 / 808613,码值与文案不变
- 配房行与团期计划行既有字段(价格、结算方式、确认状态)的含义与取值
八、测试环境已验证
所有接口都经测试服网关调用。HTTP 状态恒为 200,下面的 code 指响应 body 里的 code,带 ✓ 标记。行尾 @ 后面是当时测试服 order-v3 的部署提交。bdde64a3a、9c7ac9382、ff6863754、3ecf38797 四个提交都包含本单合并提交 7c21cf0e40。
GET /v3/admin/order/house-allocation/households 房务 A scope=all 查别人持有的单 → code=200,该行 readOnly=true,readOnlyReason「由<持有人姓名>处理」 ✓ @9c7ac9382
GET /v3/admin/order/house-allocation/households 刚认领、未配房的单 → taskKind=NEW ✓ @bdde64a3a
GET /v3/admin/order/house-allocation/households 测试定制师提交需求调整(新增 OPEN 的 REQUIREMENT_ADJUSTED)后 → taskKind=CHANGE、isRework=true、todoCount=1 ✓ @ff6863754
GET /v3/admin/order/house-allocation/households 改酒店产生 HELD 改配记录后 → 该单 taskKind=CHANGE ✓ @bdde64a3a
GET /v3/admin/order/house-allocation/households scope=all&taskKind=WITHDRAWAL → code=200,已配房后取消的单 taskKind=WITHDRAWAL;结果 5 行全是退团单,上面那张 CHANGE 单不在其中 ✓ @9c7ac9382
GET /v3/admin/order/house-allocation/households HOUSE 会话发 2 条未读 → 该行 unreadCount=2;没有会话的行 unreadCount=0 ✓ @bdde64a3a
GET /v3/admin/order/house-allocation/households scope=mine&status=unfinished,需求最终确认后 → code=200,5 行,不含该需求所在单 ✓ @9c7ac9382,带房需求复测 ✓ @ff6863754
GET /v3/admin/order/house-allocation/group-batches 团期转交后 scope=all 查该团 → code=200,houseClaimerName 变为接收人 ✓ @9c7ac9382
GET /admin/house/orders/{orderId} 一晚两行(一行 breakfast=INCLUDED + deductInventory=true,一行两者都不传) → breakfastLabel「含早餐」/「早餐待确认」,roomSource STOCK / HOTEL,该晚 nightRoomSource=MIXED;客人自订晚 SELF,未配房晚 UNSET ✓ @bdde64a3a
GET /admin/house/orders/{orderId} 非控房已确认行改酒店不带凭证后 → changes[] 多一条 oldStatus=HELD;确认取消后该条 CANCEL_CONFIRMED、cancelFee="200.00";控房行改酒店的新 change 直接是 CANCEL_CONFIRMED ✓ @bdde64a3a
GET /admin/house/orders/{orderId} 间数 3→2 后 changes[] 多一条 changeKind=ROOM_COUNT、oldStatus=HELD;2→3 后没有新增 ✓ @bdde64a3a
POST /v3/admin/order/hotel-requirements/{requirementId}/assignments 一晚一行扣控房 + 一行不扣控房 → code=200 ✓ @bdde64a3a
POST /v3/admin/order/hotel-requirements/{requirementId}/assignments 对别人持有的需求提交 → code=808110;持有人经转单转给本人后同一请求 → code=200 ✓ @9c7ac9382
POST /v3/admin/order/hotel-requirements/{requirementId}/assignments 控房表调价后提交同酒店同房型同晚 → code=200,快照价 680.00 / 675.00;调价前已有行仍是 620.00 / 615.00 ✓ @9c7ac9382
PUT /v3/admin/order/assignments/{id} 测试服未单独调用,由 HouseAssignmentServiceTest#update_breakfast_overwritesWhenGivenKeepsWhenOmitted 覆盖
PUT /v3/admin/order/hotel-requirements/{requirementId}/assignments/{id}/placement 非控房已确认行改酒店、不带凭证 → code=200,产生 oldStatus=HELD 改配记录 ✓ @bdde64a3a
PUT /v3/admin/order/hotel-requirements/{requirementId}/assignments/{id}/placement 控房行改酒店、不带凭证 → code=200,改配记录直接是 CANCEL_CONFIRMED ✓ @bdde64a3a
PUT /v3/admin/order/hotel-requirements/{requirementId}/assignments/{id}/placement 间数 3→2 → code=200,多一条 ROOM_COUNT / HELD 改配记录;2→3 → code=200,不新增 ✓ @bdde64a3a
POST /v3/admin/order/hotel-requirements/{requirementId}/transfer 持有人把需求转给房务 A → code=200,之后房务 A 对该需求提交配房成功 ✓ @9c7ac9382
GET /v3/admin/order/todos 房务 A scope=all → code=200 ✓;scope=others → code=200 ✓ @9c7ac9382
GET /v3/admin/house/group-batches 测试服未单独调用,由 HouseGroupBatchBoardManagerTest#page_scopeAllRoomManager_allClaims 覆盖
GET /v3/admin/house/group-batches/{groupBatchId} 房务 A 查看房务 B 持有的团 → code=200,readOnly=true ✓ @9c7ac9382
GET /v3/admin/house/group-batches/{groupBatchId}/room-requirements 团期转交前后查计划 → code=200,计划行数 1→1 ✓ @9c7ac9382;RESOURCE_PREPARING 团期该晚 needRoomCount=4 ✓ @ff6863754
GET /v3/admin/house/group-batches/{groupBatchId}/allocations 团里一户出行前取消后 → code=200,该户 allocatedRooms 2→0,本团 leftoverRooms 0→2,计划行保留 ✓ @3ecf38797
GET /v3/admin/house/group-batches/{groupBatchId}/room-plans/confirm-check 测试服未单独调用,由 HouseGroupBatchClaimGuardTest#assertReadable_others_noThrow、GroupBatchRoomDayConfirmManagerTest#check_staleAllocation_dayNotReadyAndBatchNotReady 覆盖
POST /v3/admin/house/group-batches/{groupBatchId}/room-plans 团期持有人新建一行 2 间计划 → code=200 ✓ @9c7ac9382
PUT /v3/admin/house/group-batches/{groupBatchId}/room-plans/{planId} 测试服未单独调用,由 GroupBatchRoomPlanManagerTest#update_replace_breakfastGiven_overridesOld、#update_breakfastOnly_pendingRow_inPlacePatchCarriesBreakfast 覆盖
验证身份:房务 A / B / C、测试定制师、超管测试账号,全部是测试专用账号。落库读数来自测试服只读 SQL。
十、相关文档
- 关联 Issue: wx/HL#8491
- 契约文档:
docs/order-v3/api/API-SPEC-HOUSE-V1.1.html§1.3 转单 / 超管指派、§11.12 错误码、§12 房务控制台 - 同批变更: 同目录
30_8491_房务控制台接口-新增接口-管理后台.md、30_8491_房务旧列表接口下线-删除接口-管理后台.md - 已知缺口: #8508(改晚次 / 酒店 / 房型 / 间数对已确认行的应付款处理)
关联 / 联系人
链接
- Issue: #8491
联系人
- 后端负责人: @wx