docs(changelog): 房务接口审计批次 #8385~#8390 交接件
changelog-filename-gate / validate (push) Failing after 3s
changelog-filename-gate / validate (push) Failing after 3s
- #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>
这个提交包含在:
@@ -0,0 +1,373 @@
|
||||
---
|
||||
schema: "hl-changelog/v2"
|
||||
ticket: "8385"
|
||||
title: "团期订房计划建守卫:超管未认领团上禁建(808612),释放文案改为可操作指引"
|
||||
consumer: "admin"
|
||||
author: "wx(GIT)"
|
||||
change_type: "修改接口"
|
||||
backend_status: "deployed"
|
||||
gateway_status: "verified"
|
||||
frontend_status: "pending"
|
||||
frontend_owner: ""
|
||||
frontend_ref: ""
|
||||
target_release: ""
|
||||
verified_at: ""
|
||||
status_note: "超管在未被房务整团认领的团期上新建订房计划时返回 808612(复用已有码);释放端点的 808660 文案改为可操作的指引(删除计划、联系超管接管)。后端改动已合入 dev-v3 并部署测试服,808612 新守卫与 808660 新文案均已网关实测。"
|
||||
updated_at: "2026-09-26"
|
||||
base: "dev-v3"
|
||||
---
|
||||
|
||||
# order-v3:团期订房计划守卫与释放指引改进(管理后台)
|
||||
|
||||
**服务**: hl-order-service-v3
|
||||
**PR**: #8395
|
||||
**Issue**: #8385
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ 关键变化
|
||||
|
||||
1. **新增入口守卫**:超管(SUPER_ADMIN)在**未被房务认领的团期**上调用 `POST /v3/admin/house/group-batches/{groupBatchId}/room-plans` 时,返回 **808612**「该团期尚未被房务整团认领」,不落库。
|
||||
- 背景:超管本可在无人认领的团上直接建计划,导致"团没人管、但计划和库存都在"的状态。释放时房务因为 808660 无法释放,只剩逐条删计划这一条路。
|
||||
- 约束:超管要在团上排房,必须先 `POST /v3/admin/order/grab-pool/group-batches/{groupBatchId}/takeover` 指派给某个房务,再建计划。
|
||||
|
||||
2. **改进释放文案**:端点 `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 | 乐观锁版本号 |
|
||||
|
||||
#### 请求示例
|
||||
|
||||
```http
|
||||
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": "标准间"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### 响应示例
|
||||
|
||||
**成功(已认领团)**:
|
||||
|
||||
```json
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**失败(未认领团,超管)**:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 808612,
|
||||
"message": "该团期尚未被房务整团认领",
|
||||
"success": false,
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
#### 空数据 / 降级响应
|
||||
|
||||
- 参数校验失败(日期格式错、房间数 ≤0):HTTP 200,`code=400`,message 含具体字段文案;不落库。
|
||||
|
||||
#### 错误响应
|
||||
|
||||
```json
|
||||
{
|
||||
"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 |
|
||||
|
||||
#### 请求示例
|
||||
|
||||
```http
|
||||
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": "已完成配房"
|
||||
}
|
||||
```
|
||||
|
||||
#### 响应示例
|
||||
|
||||
**成功**:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "成功",
|
||||
"success": true,
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
**失败(有计划待删)**:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 808660,
|
||||
"message": "该团仍有 4 条未取消的订房计划,无法释放:请先逐条删除订房计划后再释放;如需更换认领房务请联系超管接管",
|
||||
"success": false,
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
#### 空数据 / 降级响应
|
||||
|
||||
不适用。
|
||||
|
||||
#### 错误响应
|
||||
|
||||
```json
|
||||
{
|
||||
"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:https://git.1814.love/wx/HL/issues/8385
|
||||
- PR:https://git.1814.love/wx/HL/pulls/8395
|
||||
- takeover API:`POST /v3/admin/order/grab-pool/group-batches/{groupBatchId}/takeover`
|
||||
- 同批单号:#8386、#8387、#8388、#8389、#8390(房务接口审计批次)
|
||||
|
||||
---
|
||||
|
||||
## 关联 / 联系人
|
||||
|
||||
### 联系人
|
||||
|
||||
- **后端负责人**: @wx
|
||||
@@ -0,0 +1,331 @@
|
||||
---
|
||||
schema: "hl-changelog/v2"
|
||||
ticket: "8386"
|
||||
title: "住宿需求驳回:加房务角色门与认领人校验;车务驳回接口下线"
|
||||
consumer: "admin"
|
||||
author: "wx(GIT)"
|
||||
change_type: "删除接口"
|
||||
backend_status: "deployed"
|
||||
gateway_status: "verified"
|
||||
frontend_status: "pending"
|
||||
frontend_owner: ""
|
||||
frontend_ref: ""
|
||||
target_release: ""
|
||||
verified_at: ""
|
||||
status_note: "住宿需求供应方驳回新增房务角色门(808090/808091)与认领人校验(808110/808116,超管豁免);车务驳回接口删除,调用返回 HTTP 200 + code 404。已在测试环境网关实测各角色分支与已删除端点响应。"
|
||||
updated_at: "2026-09-26"
|
||||
base: "dev-v3"
|
||||
---
|
||||
|
||||
# order-v3:住宿需求驳回守卫加固与车务驳回下线(管理后台)
|
||||
|
||||
**服务**: hl-order-service-v3
|
||||
**PR**: #8397
|
||||
**Issue**: #8386
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ 关键变化
|
||||
|
||||
1. **住宿需求供应方驳回** `POST /v3/admin/order/{id}/hotel-requirement/supplier-reject`:
|
||||
- 新增房务角色门:`@HouseWriteGuarded`,非房务角色返回 **808090**,房务组长返回 **808091**。
|
||||
- 新增认领人校验:需求必须被当前操作人认领,否则返回 **808110**(非本人)/ **808116**(未认领,仅超管可驳)。
|
||||
- 超管可绕过认领限制(跳过本人限制,但仍受角色门约束)。
|
||||
|
||||
2. **车务需求供应方驳回** `POST /v3/admin/order/{id}/vehicle-requirement/supplier-reject` **已下线**:
|
||||
- 端点删除,调用返回 404。
|
||||
- hl-ui 全部远程 ref 零调用,车务侧无此功能。
|
||||
|
||||
---
|
||||
|
||||
## 一、背景
|
||||
|
||||
### 住宿驳回
|
||||
|
||||
API-SPEC §2.8 与 CHANGELOG v6.3.8 均明文「新增房务/超管可用的住宿需求驳回端点」,但实现漏了角色门和认领人校验:
|
||||
- 任意 ADMIN token 的后台账号(包括车控、定制师)都能驳回任意订单的需求。
|
||||
- 测试服已实证车控账号(VEHICLE_MANAGER)成功打回住宿需求两次。
|
||||
- 同类操作(转单、释放、提交配房)都带认领人校验,驳回不带属于遗漏。
|
||||
- 打回副作用重:需求行终态失活、flow 回退、定制师开返工待办 + 站内信。
|
||||
|
||||
### 车务驳回
|
||||
|
||||
车务从无"抢单 → 认领"的流程,用车需求也从不写入抢单人:整个车务侧"我的接单"接口(#8373)因此下线。供应方驳回同样是"假接口"——没有实际用途、hl-ui 零调用。
|
||||
|
||||
---
|
||||
|
||||
## 二、变更接口清单
|
||||
|
||||
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|
||||
|---|------|------|------|----------|------|
|
||||
| 1 | 住宿需求供应方驳回 | POST | `/v3/admin/order/{id}/hotel-requirement/supplier-reject` | 修改接口 | 新增角色门(808090/808091)与认领人校验(808110/808116) |
|
||||
| 2 | 车务需求供应方驳回 | POST | `/v3/admin/order/{id}/vehicle-requirement/supplier-reject` | 删除接口 | 端点已删除,调用返回 404 |
|
||||
|
||||
---
|
||||
|
||||
## 三、接口详情
|
||||
|
||||
### 1. 住宿需求供应方驳回 `POST /v3/admin/order/{id}/hotel-requirement/supplier-reject`
|
||||
|
||||
**VO**: `RejectReqVO → Result<Void>`
|
||||
|
||||
#### 使用场景
|
||||
|
||||
房务(ROOM_MANAGER)或超管在配房面板「驳回需求」,把已认领的住宿需求打回给定制师,触发返工。仅认领人或超管可操作;非房务角色返回权限错误。
|
||||
|
||||
#### 入参字段表
|
||||
|
||||
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||||
|------|------|------|------|------|------|
|
||||
| id | Path | Long | 是 | — | 订单 ID |
|
||||
| returnRemark | Body | String | 是 | `@NotBlank`,≤500 字 | 驳回原因,不能为空 |
|
||||
|
||||
#### 出参字段表
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| — | null | 成功返回 null |
|
||||
|
||||
#### 请求示例
|
||||
|
||||
```http
|
||||
POST /v3/admin/order/770145/hotel-requirement/supplier-reject HTTP/1.1
|
||||
Host: api.test.1814.love:9443
|
||||
Authorization: Bearer <room_manager token>
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"returnRemark": "房型不符,请调整"
|
||||
}
|
||||
```
|
||||
|
||||
#### 响应示例
|
||||
|
||||
**成功**:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "成功",
|
||||
"success": true,
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
**失败(非认领人)**:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 808110,
|
||||
"message": "需求不属于当前用户",
|
||||
"success": false,
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
**失败(无房务权限)**:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 808090,
|
||||
"message": "未登录或非房务角色,无权操作",
|
||||
"success": false,
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
#### 空数据 / 降级响应
|
||||
|
||||
- `returnRemark` 缺失或为空白:`@Valid` 校验不通过,HTTP 200 + `code: 400` + 具体字段错误信息(不进入业务逻辑)。
|
||||
|
||||
#### 错误响应
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 400,
|
||||
"message": "打回/驳回备注不能为空",
|
||||
"success": false,
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
**校验顺序**(前一道不过不会走到后一道):写门(808090/808091)→ 参数校验(400)→ 582031(无生效需求行)→ 582083(需求状态不允许此操作)→ 认领人校验(808116/808110,超管豁免)→ 582086(已有生效配房不可驳回)→ 582083(并发 CAS 失败)。
|
||||
|
||||
**其他错误码**:
|
||||
- **808090**:未登录或非房务角色,无权操作。
|
||||
- **808091**:房务组长为只读监督角色,无权执行该操作。
|
||||
- **582031**:订单无有效需求行。
|
||||
- **582083**:需求状态不允许此操作,请检查当前状态(团期订单只放行 PENDING/PROCESSING;非团期订单放行 PENDING/PROCESSING/PENDING_REVIEW;并发 CAS 失败同样报此码)。
|
||||
- **808116**:订单未抢单, 请先抢单再配房(需求未被认领,非超管不可驳)。
|
||||
- **808110**:需求不属于当前用户(已被他人认领,非超管不可驳)。
|
||||
- **582086**:该需求已有配房记录, 不能驳回, 请走替换/修改配房。
|
||||
|
||||
#### 业务边界
|
||||
|
||||
- **认领限制**:需求 `claimer_id` 必须等于当前操作人,或当前角色为 SUPER_ADMIN。房务组长(house_keeper_lead)无法驳回,返回 808091。
|
||||
- **超管豁免**:SUPER_ADMIN 绕过认领人限制(不受 808110/808116 约束),但仍受角色门约束(必须先过 `@HouseWriteGuarded`)。
|
||||
- **副作用**:驳回目标状态按订单类型区分——核心/定制订单需求驳回后进 `REJECTED_TO_CONSULTANT`,团期订单进 `REJECTED_TO_ADMIN`;触发返工待办与站内信。
|
||||
- **转单后生效**:若需求在驳回前被转单给其他房务,原持有人的驳回请求返回 808110(当前 `claimer_id` 已是新认领人)。
|
||||
- **已有配房记录不可驳回**:需求已生成生效配房(`hasActiveHotelAssignmentsByOrder` 为真)时返回 582086,须走替换/修改配房而非驳回。
|
||||
|
||||
---
|
||||
|
||||
### 2. 车务需求供应方驳回 `POST /v3/admin/order/{id}/vehicle-requirement/supplier-reject`
|
||||
|
||||
**VO**: `已删除`
|
||||
|
||||
**状态:已删除**
|
||||
|
||||
#### 使用场景
|
||||
|
||||
该接口已删除,不可用。
|
||||
|
||||
#### 入参字段表
|
||||
|
||||
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||||
|------|------|------|------|------|------|
|
||||
| — | — | — | — | — | 已删除 |
|
||||
|
||||
#### 出参字段表
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| — | — | 已删除 |
|
||||
|
||||
#### 请求示例
|
||||
|
||||
```http
|
||||
POST /v3/admin/order/770145/vehicle-requirement/supplier-reject HTTP/1.1
|
||||
Host: api.test.1814.love:9443
|
||||
Authorization: Bearer <admin token>
|
||||
Content-Type: application/json
|
||||
|
||||
{}
|
||||
```
|
||||
|
||||
#### 响应示例
|
||||
|
||||
HTTP 状态码 **200**(非 404),业务错误码 404:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 404,
|
||||
"message": "接口不存在: POST /v3/admin/order/770145/vehicle-requirement/supplier-reject",
|
||||
"success": false,
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
#### 空数据 / 降级响应
|
||||
|
||||
不适用(路由已删)。前端应只判 `code`,不依赖 HTTP 状态码。
|
||||
|
||||
#### 错误响应
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 404,
|
||||
"message": "接口不存在: POST /v3/admin/order/770145/vehicle-requirement/supplier-reject",
|
||||
"success": false,
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
#### 业务边界
|
||||
|
||||
- 接口已删除,路由不存在;调用返回 HTTP 200 + `code: 404`(不是 HTTP 404),前端只判 `code`。
|
||||
- hl-ui 全部远程 ref 零调用;测试网关 nginx 日志 2026-09-12~09-26 窗口内该路径 19 次调用全部来自脚本(Python-urllib / curl / 空 UA),零浏览器 UA。
|
||||
|
||||
---
|
||||
|
||||
## 四、契约约束与正确调用方式
|
||||
|
||||
| 场景 | 调用方法 | 说明 |
|
||||
|------|---------|------|
|
||||
| ✅ 认领人驳回 | `POST /v3/admin/order/{orderId}/hotel-requirement/supplier-reject` | 该订单的认领房务直接调,返回 200;定制师开返工待办 |
|
||||
| ✅ 超管代驳 | 同上(SUPER_ADMIN 身份)| 超管跳过认领限制,但仍需房务角色权限 |
|
||||
| ✅ 订单详情按钮 | 查看 `actions.canRejectRequirement` | enabled 取决于 write 权限 + 认领人判定;false 时显示 disabledReason |
|
||||
| ❌ 非认领人驳回 | — | 返回 808110,需求 status 不变 |
|
||||
| ❌ 车务驳回 | — | 端点已删除,返回 HTTP 200 + code 404 |
|
||||
| ❌ 定制师驳回 | — | 返回 808090 |
|
||||
|
||||
---
|
||||
|
||||
## 五、数据库行为
|
||||
|
||||
无表结构变更、无 Flyway。
|
||||
|
||||
---
|
||||
|
||||
## 六、边界行为
|
||||
|
||||
| 场景 | 行为 |
|
||||
|---|---|
|
||||
| 认领人驳回 | 返回 200,需求进 REJECTED_TO_CONSULTANT 或 REJECTED_TO_ADMIN |
|
||||
| 非认领人驳回 | 返回 808110,需求 status 不变 |
|
||||
| 未认领需求 + 房务驳回 | 返回 808116,非超管不可驳 |
|
||||
| 超管驳回未认领 | 返回 200,驳回处理 |
|
||||
| 转单中驳回(原认领人) | 返回 808110(新认领人接管后视为他人所有) |
|
||||
| 车务驳回 | 返回 HTTP 200 + code 404,无新增副作用 |
|
||||
|
||||
## 六.6、修改前后对比
|
||||
|
||||
| 维度 | 改前 | 改后 |
|
||||
|---|---|---|
|
||||
| 车控账号调住宿驳回 | 返回 200,需求打回 | 返回 808090,需求 status 不变 |
|
||||
| 非认领人驳回 | 返回 200,需求打回 | 返回 808110,status 不变 |
|
||||
| 未认领需求 | 任意房务可驳 | 仅超管可驳,返回 808116 |
|
||||
| 车务驳回 | 路由存在,可调用 | 路由删除,返回 HTTP 200 + code 404 |
|
||||
|
||||
## 六.7、影响评估
|
||||
|
||||
- **兼容性**:hl-ui 房务驳回按钮的 `enabled` 判定由 `canRejectRequirement` 决定(已包含写权限与认领人两个维度),驳回失败收 808090/808091/808110/808116 四个新码。
|
||||
- **前端要动的**:
|
||||
- 驳回按钮的 disabled 文案区分「无房务权限」(808090/808091)与「非本人认领」(808110)。
|
||||
- 处理 808116「未认领,仅超管可驳」的提示(普通房务不应遇到,因为按钮本身 disabled)。
|
||||
- 车务不再有驳回端点,移除 vehicle-requirement/supplier-reject 调用。
|
||||
- **数据影响**:无;仅加守卫,不改历史。
|
||||
- **其它服务**:fleet 的 `rejectVehicleRequirementFromFleet` 独立存在,本单不动。
|
||||
|
||||
---
|
||||
|
||||
## 七、不影响范围
|
||||
|
||||
- 团期管理员的 dispatch/reject(走独立 `GroupBatchPermissionGuard`),无改动。
|
||||
- 转单、释放、提交配房等其他配房写操作,无改动。
|
||||
- 车务用车需求的其他接口(提交、放行、派单),无改动。
|
||||
- 整团认领释放等认领链路,无改动。
|
||||
|
||||
---
|
||||
|
||||
## 八、测试环境已验证
|
||||
|
||||
部署:测试环境 order-v3 `1f65d7894`(含 e2313790b)。网关 `api.test.1814.love:9443`。
|
||||
|
||||
| # | 场景 | 实测结果 |
|
||||
|---|---|---|
|
||||
| 1 | VEHICLE_MANAGER 调住宿 supplier-reject | code 808090,需求状态不变 |
|
||||
| 2 | house_keeper_lead 调住宿 supplier-reject | code 808091,需求状态不变 |
|
||||
| 3 | 非认领 ROOM_MANAGER(需求已被他人认领)驳回 | code 808110,需求状态不变 |
|
||||
| 4 | ROOM_MANAGER 对未认领需求驳回 | code 808116,需求状态不变 |
|
||||
| 5 | 超管打回 / 认领人打回自己认领的需求 | 成功,核心订单需求进 REJECTED_TO_CONSULTANT |
|
||||
| 6 | 车务 `POST /v3/admin/order/{id}/vehicle-requirement/supplier-reject` | HTTP 200 + code 404「接口不存在: POST <URL>」 |
|
||||
|
||||
调用来源:测试网关 nginx 日志 2026-09-12~09-26 窗口内车务 supplier-reject 共 19 次,全部是脚本(Python-urllib / curl / 空 UA),零浏览器 UA;hl-ui 全部远程 ref 零调用。
|
||||
|
||||
---
|
||||
|
||||
## 十、相关文档
|
||||
|
||||
- Issue:https://git.1814.love/wx/HL/issues/8386
|
||||
- PR:https://git.1814.love/wx/HL/pulls/8397
|
||||
- 相关单号:#8373(车务我的接单下线)、#8388(回执认领人校验同口径)
|
||||
- API-SPEC:`docs/order-v3/api/API-SPEC-HOUSE-V1.1.html` §2.8
|
||||
|
||||
---
|
||||
|
||||
## 关联 / 联系人
|
||||
|
||||
### 联系人
|
||||
|
||||
- **后端负责人**: @wx
|
||||
@@ -0,0 +1,346 @@
|
||||
---
|
||||
schema: "hl-changelog/v2"
|
||||
ticket: "8387"
|
||||
title: "订单房间分配:下线旧版三接口 GET/POST/PUT /v3/admin/order/{id}/room"
|
||||
consumer: "admin"
|
||||
author: "wx(GIT)"
|
||||
change_type: "删除接口"
|
||||
backend_status: "deployed"
|
||||
gateway_status: "verified"
|
||||
frontend_status: "not_required"
|
||||
frontend_owner: ""
|
||||
frontend_ref: ""
|
||||
target_release: ""
|
||||
verified_at: ""
|
||||
status_note: "订单侧旧版房间分配三个端点(GET list、POST add、PUT edit)已下线。API-SPEC 已标旧版,房务配房走 house 域 §2.5 接口。hl-ui 零调用。"
|
||||
updated_at: "2026-09-26"
|
||||
base: "dev-v3"
|
||||
---
|
||||
|
||||
# order-v3:下线订单房间分配旧版接口(管理后台)
|
||||
|
||||
**服务**: hl-order-service-v3
|
||||
**PR**: #8398
|
||||
**Issue**: #8387
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ 关键变化
|
||||
|
||||
三个接口已删除,路由不存在:
|
||||
- `GET /v3/admin/order/{id}/room`:查询订单房间分配列表(旧版)
|
||||
- `POST /v3/admin/order/{id}/room`:新增房间分配(旧版)
|
||||
- `PUT /v3/admin/order/{id}/room/{roomAssignmentId}`:编辑房间分配(旧版)
|
||||
|
||||
调用返回 HTTP 200 + `code: 404`(不是 HTTP 404)。房务配房改用 house 域接口:新增/清空配房走 `POST/DELETE /v3/admin/order/hotel-requirements/{requirementId}/assignments` 等 API-SPEC-HOUSE §2.2~§2.4c 写口;查询订单房间用 `GET /v3/admin/order/orders/{orderId}/rooms`(§2.5)。
|
||||
|
||||
---
|
||||
|
||||
## 一、背景
|
||||
|
||||
订单侧房间分配(`order_room_assignment` 表)是房务配房的补充记录,实现早于 house 域统一接口。API-SPEC §8 已标为"旧版",注释指向 house 域 §2.5 为正式接口。
|
||||
|
||||
hl-ui 全部远程 ref 无调用;房务页面已改用 house 域配房端点。后台读写入口全删,仅保留 internal bundle 读——house 域 `RoomAssignmentVO` 与 hl-mp-service 的 C 端聚合仍需 `order_room_assignment` 表数据,故表与内部读逻辑保留,仅删对外读写接口。
|
||||
|
||||
---
|
||||
|
||||
## 二、变更接口清单
|
||||
|
||||
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|
||||
|---|------|------|------|----------|------|
|
||||
| 1 | 查询房间分配列表(旧) | GET | `/v3/admin/order/{id}/room` | 删除 | 路由已删,任何调用返回 404 |
|
||||
| 2 | 新增房间分配(旧) | POST | `/v3/admin/order/{id}/room` | 删除 | 路由已删,返回 404 |
|
||||
| 3 | 编辑房间分配(旧) | PUT | `/v3/admin/order/{id}/room/{roomAssignmentId}` | 删除 | 路由已删,返回 404 |
|
||||
|
||||
房务配房改用 house 域接口(API-SPEC-HOUSE):提交配房 `POST /v3/admin/order/hotel-requirements/{requirementId}/assignments`(§2.2)、清空配房 `DELETE .../assignments`(§2.4b/§2.4c)、按天确认 `POST .../assignments/days/{dayNumber}/confirm`(§2.3)、调整入住 `PUT .../assignments/{id}/placement`(§2.3b);查询订单房间用 `GET /v3/admin/order/orders/{orderId}/rooms`(§2.5)。
|
||||
|
||||
---
|
||||
|
||||
## 三、接口详情
|
||||
|
||||
### 1. 房间分配查询 `GET /v3/admin/order/{id}/room`
|
||||
|
||||
**VO**: `已删除`
|
||||
|
||||
**状态**:已删除。路由不存在,返回 404。
|
||||
|
||||
#### 使用场景
|
||||
|
||||
该接口已删除。
|
||||
|
||||
#### 入参字段表
|
||||
|
||||
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||||
|------|------|------|------|------|------|
|
||||
| — | — | — | — | — | 已删除 |
|
||||
|
||||
#### 出参字段表
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| — | — | 已删除 |
|
||||
|
||||
#### 请求示例
|
||||
|
||||
```http
|
||||
GET /v3/admin/order/770145/room HTTP/1.1
|
||||
Host: api.test.1814.love:9443
|
||||
Authorization: Bearer <admin token>
|
||||
```
|
||||
|
||||
#### 响应示例
|
||||
|
||||
HTTP 状态码 **200**(非 404),业务错误码 404:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 404,
|
||||
"message": "接口不存在: GET /v3/admin/order/770145/room",
|
||||
"success": false,
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
#### 空数据 / 降级响应
|
||||
|
||||
不适用。前端应只判 `code`,不依赖 HTTP 状态码。
|
||||
|
||||
#### 错误响应
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 404,
|
||||
"message": "接口不存在: GET /v3/admin/order/770145/room",
|
||||
"success": false,
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
#### 业务边界
|
||||
|
||||
- 接口已删除,路由不存在;调用返回 HTTP 200 + `code: 404`。
|
||||
- 阳性对照:同 Controller 下 `GET /v3/admin/order/{id}` 正常返回 200,证明是该路由本身被删,不是订单不存在。
|
||||
- `order_room_assignment` 表数据仍可由服务内部通过 `internal/order/orders/{orderId}/assignments` 读取(该 internal 端点经网关直接拒绝「接口不可访问」,只服务间可达,不对前端暴露)。
|
||||
|
||||
---
|
||||
|
||||
### 2. 房间分配新增 `POST /v3/admin/order/{id}/room`
|
||||
|
||||
**VO**: `已删除`
|
||||
|
||||
**状态**:已删除。路由不存在,返回 404。
|
||||
|
||||
#### 使用场景
|
||||
|
||||
该接口已删除。
|
||||
|
||||
#### 入参字段表
|
||||
|
||||
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||||
|------|------|------|------|------|------|
|
||||
| — | — | — | — | — | 已删除 |
|
||||
|
||||
#### 出参字段表
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| — | — | 已删除 |
|
||||
|
||||
#### 请求示例
|
||||
|
||||
```http
|
||||
POST /v3/admin/order/770145/room HTTP/1.1
|
||||
Host: api.test.1814.love:9443
|
||||
Authorization: Bearer <admin token>
|
||||
Content-Type: application/json
|
||||
|
||||
{}
|
||||
```
|
||||
|
||||
#### 响应示例
|
||||
|
||||
HTTP 状态码 **200**(非 404),业务错误码 404:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 404,
|
||||
"message": "接口不存在: POST /v3/admin/order/770145/room",
|
||||
"success": false,
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
#### 空数据 / 降级响应
|
||||
|
||||
不适用。前端应只判 `code`,不依赖 HTTP 状态码。
|
||||
|
||||
#### 错误响应
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 404,
|
||||
"message": "接口不存在: POST /v3/admin/order/770145/room",
|
||||
"success": false,
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
#### 业务边界
|
||||
|
||||
- 路由已删除;调用返回 HTTP 200 + `code: 404`。
|
||||
- 新增房间分配改走 house 域 `POST /v3/admin/order/hotel-requirements/{requirementId}/assignments`(API-SPEC-HOUSE §2.2)。
|
||||
|
||||
---
|
||||
|
||||
### 3. 房间分配编辑 `PUT /v3/admin/order/{id}/room/{roomAssignmentId}`
|
||||
|
||||
**VO**: `已删除`
|
||||
|
||||
**状态**:已删除。路由不存在,返回 404。
|
||||
|
||||
#### 使用场景
|
||||
|
||||
该接口已删除。
|
||||
|
||||
#### 入参字段表
|
||||
|
||||
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||||
|------|------|------|------|------|------|
|
||||
| — | — | — | — | — | 已删除 |
|
||||
|
||||
#### 出参字段表
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| — | — | 已删除 |
|
||||
|
||||
#### 请求示例
|
||||
|
||||
```http
|
||||
PUT /v3/admin/order/770145/room/123456 HTTP/1.1
|
||||
Host: api.test.1814.love:9443
|
||||
Authorization: Bearer <admin token>
|
||||
Content-Type: application/json
|
||||
|
||||
{}
|
||||
```
|
||||
|
||||
#### 响应示例
|
||||
|
||||
HTTP 状态码 **200**(非 404),业务错误码 404:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 404,
|
||||
"message": "接口不存在: PUT /v3/admin/order/770145/room/123456",
|
||||
"success": false,
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
#### 空数据 / 降级响应
|
||||
|
||||
不适用。前端应只判 `code`,不依赖 HTTP 状态码。
|
||||
|
||||
#### 错误响应
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 404,
|
||||
"message": "接口不存在: PUT /v3/admin/order/770145/room/123456",
|
||||
"success": false,
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
#### 业务边界
|
||||
|
||||
- 路由已删除;调用返回 HTTP 200 + `code: 404`。
|
||||
- 编辑房间分配改走 house 域 `PUT /v3/admin/order/hotel-requirements/{requirementId}/assignments/{id}/placement`(API-SPEC-HOUSE §2.3b)。
|
||||
|
||||
---
|
||||
|
||||
## 四、契约约束与正确调用方式
|
||||
|
||||
| 场景 | 改前 | 改后 |
|
||||
|------|------|------|
|
||||
| 查看订单的房间 | `GET /v3/admin/order/{orderId}/room` | 调用返回 HTTP 200 + code 404;改用 `GET /v3/admin/order/orders/{orderId}/rooms`(API-SPEC-HOUSE §2.5) |
|
||||
| 新增房间 | `POST /v3/admin/order/{orderId}/room` | 路由已删,不可用;改用 `POST /v3/admin/order/hotel-requirements/{requirementId}/assignments`(§2.2) |
|
||||
| 修改房间 | `PUT /v3/admin/order/{orderId}/room/{id}` | 路由已删,不可用;改用 `PUT /v3/admin/order/hotel-requirements/{requirementId}/assignments/{id}/placement`(§2.3b) |
|
||||
|
||||
C 端房型统计(`GET /mp/order/{orderId}/hotels`)的 `roomTypeStats` 仍从 `order_room_assignment` 表经 internal bundle(hl-mp-service `MpServiceDetailAggregationService`)汇聚,对外无变化。internal 端点仅服务间可达,网关对前端直接拒绝「接口不可访问」。
|
||||
|
||||
---
|
||||
|
||||
## 五、数据库行为
|
||||
|
||||
无变更、无 Flyway。表 `order_room_assignment` 保留;存量数据由 internal bundle 继续读取。
|
||||
|
||||
---
|
||||
|
||||
## 六、边界行为
|
||||
|
||||
| 场景 | 行为 |
|
||||
|---|---|
|
||||
| 调用 GET /order/{id}/room | 返回 HTTP 200 + code 404 |
|
||||
| 调用 POST /order/{id}/room | 返回 HTTP 200 + code 404 |
|
||||
| 调用 PUT /order/{id}/room/{roomAssignmentId} | 返回 HTTP 200 + code 404 |
|
||||
| 前端经网关调用 `GET /v3/internal/order/orders/{orderId}/assignments` | 网关直接拒绝,返回「接口不可访问」(设计如此,非前端可用入口) |
|
||||
| 调用 `GET /mp/order/{orderId}/hotels` | 返回 200,roomTypeStats 从 `order_room_assignment` 经 internal bundle 读 |
|
||||
|
||||
## 六.6、修改前后对比
|
||||
|
||||
| 维度 | 改前 | 改后 |
|
||||
|------|------|------|
|
||||
| 房间分配 GET | 路由存在,可查询 | 路由删除,返回 HTTP 200 + code 404 |
|
||||
| 房间分配 POST | 路由存在,可新增 | 路由删除,返回 HTTP 200 + code 404 |
|
||||
| 房间分配 PUT | 路由存在,可编辑 | 路由删除,返回 HTTP 200 + code 404 |
|
||||
|
||||
## 六.7、影响评估
|
||||
|
||||
- **兼容性**:hl-ui 零调用这三个端点,无迁移负担。C 端房型统计无变化(经 internal bundle)。
|
||||
- **数据影响**:零;表与 API 读逻辑保留。
|
||||
- **其它服务**:hl-mp-service 无直接调用;fleet 无影响。
|
||||
|
||||
---
|
||||
|
||||
## 七、不影响范围
|
||||
|
||||
- House 域房间分配接口(§2.5 GET/POST/DELETE):无改动。
|
||||
- Internal bundle (`GET /v3/internal/order/orders/{orderId}/assignments`):保留,继续供 hl-mp-service 读。
|
||||
- `order_room_assignment` 表:保留;级联软删仍在各写口生效。
|
||||
- `RoomAssignmentVO` 与 `toRoomVO`:保留(bundle 在用)。
|
||||
- 网关配置:无改动。
|
||||
|
||||
---
|
||||
|
||||
## 八、测试环境已验证
|
||||
|
||||
部署:测试环境 order-v3 `1f65d7894`(含 e2313790b)。网关 `api.test.1814.love:9443`。
|
||||
|
||||
| # | 场景 | 实测结果 |
|
||||
|---|---|---|
|
||||
| 1 | `GET /v3/admin/order/{id}/room` | HTTP 200 + code 404「接口不存在: …」 |
|
||||
| 2 | `POST /v3/admin/order/{id}/room` | HTTP 200 + code 404「接口不存在: …」 |
|
||||
| 3 | `PUT /v3/admin/order/{id}/room/{roomAssignmentId}` | HTTP 200 + code 404「接口不存在: …」 |
|
||||
| 4 | 阳性对照:同 Controller `GET /v3/admin/order/{id}` | 200(证明是路由被删,不是订单不存在) |
|
||||
| 5 | 服务内部端口直连读 `order_room_assignment`(internal bundle) | 读数与只读 SQL 一致(经网关 internal 不可达,这是设计) |
|
||||
|
||||
调用来源:测试网关 nginx 日志窗口内旧 `room` 三路径共 71 次,全部是脚本(Python-urllib / curl / 空 UA),零浏览器 UA。
|
||||
|
||||
---
|
||||
|
||||
## 十、相关文档
|
||||
|
||||
- Issue:https://git.1814.love/wx/HL/issues/8387
|
||||
- PR:https://git.1814.love/wx/HL/pulls/8398
|
||||
- 替代接口:写房间分配走 API-SPEC-HOUSE §2.5 的配房接口(`POST /v3/admin/order/hotel-requirements/{requirementId}/assignments` 等);读订单房间用 `GET /v3/admin/order/orders/{orderId}/rooms`
|
||||
- API-SPEC:§8「房间分配」与 §11 错误码表已标下线
|
||||
|
||||
---
|
||||
|
||||
## 关联 / 联系人
|
||||
|
||||
### 联系人
|
||||
|
||||
- **后端负责人**: @wx
|
||||
@@ -0,0 +1,375 @@
|
||||
---
|
||||
schema: "hl-changelog/v2"
|
||||
ticket: "8388"
|
||||
title: "回执接口守卫:上传加认领人校验(808110/808186,超管不豁免)、列表加房务读门(808090)、缺分片改 808184"
|
||||
consumer: "admin"
|
||||
author: "wx(GIT)"
|
||||
change_type: "修改接口"
|
||||
backend_status: "deployed"
|
||||
gateway_status: "verified"
|
||||
frontend_status: "pending"
|
||||
frontend_owner: ""
|
||||
frontend_ref: ""
|
||||
target_release: ""
|
||||
verified_at: ""
|
||||
status_note: "房务回执上传新增认领人校验(超管不豁免)与可选分片处理;列表新增房务读权限门(不受灰度开关控制,常开);错误码 808184 消息补五种原因的具体文案。测试环境网关已实测各分支,含缺分片 808184 新文案。"
|
||||
updated_at: "2026-09-26"
|
||||
base: "dev-v3"
|
||||
---
|
||||
|
||||
# order-v3:房务最终确认回执接口守卫加固(管理后台)
|
||||
|
||||
**服务**: hl-order-service-v3
|
||||
**PR**: #8394(原始改动) + #8399(808184 补 {0} 占位追加)
|
||||
**Issue**: #8388
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ 关键变化
|
||||
|
||||
1. **上传回执** `POST /admin/house/assignments/requirements/{requirementId}/receipts`:
|
||||
- 新增认领人校验:需求必须被当前操作人认领,否则返回 **808110**(非本人);**SUPER_ADMIN 在本端点不豁免**,与 #8386 驳回需求口径相反。
|
||||
- 需求处于 `PENDING_CLAIM`(未认领)时先被状态闸口拦下,返回 **808186**;错误码 808116 仅作理论防御(正常调用路径不可达)。
|
||||
- 缺 file 分片 / 0 字节 file 分片改返 **808184**「回执上传失败:上传文件为空或缺少 file 分片」(改前返 HTTP 500),共 5 种原因文案。
|
||||
- 顺序:角色门(808090/808091)→ 需求存在(808100)→ 状态闸口(808186)→ 认领人校验(808110)→ 文件校验(808184)。
|
||||
|
||||
2. **回执列表** `GET /admin/house/assignments/requirements/{requirementId}/receipts`:
|
||||
- 新增房务读权限门:非房务角色(定制师、车控等)返回 **808090**。房务全角色(含组长)可见;超管可见。
|
||||
- 无认领限制(组长可看全部、他人接手前查历史回执)。
|
||||
|
||||
---
|
||||
|
||||
## 一、背景
|
||||
|
||||
回执两个端点(上传、列表)无任何权限校验,导致:
|
||||
1. 非认领人房务可为他人上传回执,破坏追责链。
|
||||
2. 定制师、车控等非房务角色可读回执列表含 OSS 直链与酒店联系信息。
|
||||
|
||||
同一配房模块的 10 个写操作都带认领人校验;回执缺失属遗漏。缺 file 分片时返回 500 属参数处理缺陷(hl-common-log 共性坑,本单仅止血)。
|
||||
|
||||
---
|
||||
|
||||
## 二、变更接口清单
|
||||
|
||||
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|
||||
|---|------|------|------|----------|------|
|
||||
| 1 | 上传最终确认回执 | POST | `/admin/house/assignments/requirements/{requirementId}/receipts` | 修改接口 | 加认领人校验、缺分片改 808184 |
|
||||
| 2 | 回执列表 | GET | `/admin/house/assignments/requirements/{requirementId}/receipts` | 修改接口 | 加房务读权限门(808090) |
|
||||
|
||||
---
|
||||
|
||||
## 三、接口详情
|
||||
|
||||
### 1. 上传最终确认回执 `POST /admin/house/assignments/requirements/{requirementId}/receipts`
|
||||
|
||||
**VO**: `multipart/form-data: file → Result<HouseFinalizeReceiptRespVO>`
|
||||
|
||||
#### 使用场景
|
||||
|
||||
房务在配房面板「最终确认」区上传回执照片/PDF,证明已与酒店确认房间。仅**该需求的认领人本人**可上传;非房务角色、房务组长、非认领人(含 SUPER_ADMIN)均返回权限错误——超管在本端点**不豁免**认领归属校验,这一点与 #8386(驳回需求超管豁免)口径不同。
|
||||
|
||||
#### 入参字段表
|
||||
|
||||
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||||
|------|------|------|------|------|------|
|
||||
| requirementId | Path | Long | 是 | — | 酒店需求 ID |
|
||||
| file | Form | MultipartFile | 是(业务校验) | ≤50MB,类型自动识别 | 回执文件;缺失返 808184 |
|
||||
|
||||
#### 出参字段表
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| receiptId | String | 回执 ID(雪花 ID,序列化为字符串) |
|
||||
| requirementId | String | 需求 ID(雪花 ID,序列化为字符串) |
|
||||
| orderId | String | 订单 ID(雪花 ID,序列化为字符串) |
|
||||
| fileName | String | 原始文件名 |
|
||||
| ossUrl | String | OSS 公网 URL,`domain + "/" + ossKey` 拼接,不签名 |
|
||||
| ossKey | String | OSS Object Key |
|
||||
| fileSize | Long | 文件大小(字节) |
|
||||
| fileType | String | 附件类型:`PDF` / `IMAGE` / `OTHER`(按扩展名识别) |
|
||||
| createTime | LocalDateTime | 上传时间,序列化格式 `yyyy-MM-dd HH:mm:ss` |
|
||||
|
||||
#### 请求示例
|
||||
|
||||
```http
|
||||
POST /admin/house/assignments/requirements/2103126783048245250/receipts HTTP/1.1
|
||||
Host: api.test.1814.love:9443
|
||||
Authorization: Bearer <room_manager token>
|
||||
Content-Type: multipart/form-data; boundary=----Boundary
|
||||
|
||||
------Boundary
|
||||
Content-Disposition: form-data; name="file"; filename="receipt.jpg"
|
||||
Content-Type: image/jpeg
|
||||
|
||||
[binary jpeg data]
|
||||
------Boundary--
|
||||
```
|
||||
|
||||
#### 响应示例
|
||||
|
||||
**成功**:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "成功",
|
||||
"success": true,
|
||||
"data": {
|
||||
"receiptId": "2103801203844689921",
|
||||
"requirementId": "2103126783048245250",
|
||||
"orderId": "2100542287908892650",
|
||||
"fileName": "receipt.jpg",
|
||||
"ossUrl": "https://hlgl-test.oss-cn-beijing.aliyuncs.com/house/finalize-receipt/...",
|
||||
"ossKey": "house/finalize-receipt/2026-09/2103126783048245250_receipt.jpg",
|
||||
"fileSize": 512000,
|
||||
"fileType": "IMAGE",
|
||||
"createTime": "2026-09-26 14:30:00"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**失败(非认领人)**:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 808110,
|
||||
"message": "需求不属于当前用户",
|
||||
"success": false,
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
**失败(缺分片,实测)**:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 808184,
|
||||
"message": "回执上传失败:上传文件为空或缺少 file 分片",
|
||||
"success": false,
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
#### 空数据 / 降级响应
|
||||
|
||||
- 文件为空或缺 `file` 分片:`code=808184`,message「回执上传失败:上传文件为空或缺少 file 分片」(改前返 HTTP 500)。
|
||||
|
||||
#### 错误响应
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 808110,
|
||||
"message": "需求不属于当前用户",
|
||||
"success": false,
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
**其他错误码**:
|
||||
- **808090**:未登录或非房务角色,无权操作。
|
||||
- **808091**:房务组长为只读监督角色,无权执行该操作。
|
||||
- **808100**:需求不存在。
|
||||
- **808186**:当前状态不允许上传回执(仅 CLAIMING/PENDING_FINALIZE 可传;PENDING_CLAIM 等其他状态走这个码,不是 808116)。
|
||||
- **808116**:订单未抢单, 请先抢单再配房(状态闸口之后理论不可达,作纵深防护保留)。
|
||||
- **808184**:回执上传失败:{0},`{0}` 按触发原因取以下固定文案之一——「上传文件为空或缺少 file 分片」/「文件大小超过 50MB」/「OSS 未配置」/「读取上传文件失败」/「文件存储服务暂不可用,请稍后重试」;异常原文只进服务端日志,不回显给客户端。
|
||||
|
||||
#### 业务边界
|
||||
|
||||
- **认领校验**:需求 `claimer_id` 必须等于当前操作人;**超管不豁免**,对他人认领的需求上传同样返回 808110。与 #8386(驳回需求,超管豁免)口径不同,前端不要套同一套按钮逻辑。
|
||||
- **校验顺序**:写门(808090/808091)→ 需求存在(808100)→ 状态闸口(808186)→ 认领归属(808116/808110)→ 文件校验(808184)。
|
||||
- **文件分片**:`file` 分片改为可选(`required=false`),缺失走 Service 内已有的空文件分支报业务码 808184(改前是 HTML form 漏填触发 `MissingServletRequestPartException`,落到兜底 `Exception` 处理器返 HTTP 200+code 500「系统繁忙」并打 ERROR 日志)。
|
||||
- **状态限制**:仅 CLAIMING(配房中)与 PENDING_FINALIZE(待确认)两个阶段可上传;PENDING_CLAIM(未抢单)等其他状态返 808186,不是 808116。
|
||||
- **无事务**:`upload()` 不加 `@Transactional`;OSS `putObject` 成功后才 `insert`,`insert` 失败可能残留孤儿 OSS 对象(由清理 job 兜底);OSS 失败(`putObject` 抛异常)返 808184 且不落库。
|
||||
|
||||
---
|
||||
|
||||
### 2. 回执列表 `GET /admin/house/assignments/requirements/{requirementId}/receipts`
|
||||
|
||||
**VO**: `→ Result<List<HouseFinalizeReceiptRespVO>>`
|
||||
|
||||
#### 使用场景
|
||||
|
||||
房务或超管查看某需求的全部回执列表(谁上传的、何时、文件链接)。非房务角色返回 808090;房务全角色可见无限制。
|
||||
|
||||
#### 入参字段表
|
||||
|
||||
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||||
|------|------|------|------|------|------|
|
||||
| requirementId | Path | Long | 是 | — | 酒店需求 ID |
|
||||
|
||||
#### 出参字段表
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| receiptId | String | 回执 ID(雪花 ID,序列化为字符串) |
|
||||
| requirementId | String | 需求 ID(雪花 ID,序列化为字符串) |
|
||||
| orderId | String | 订单 ID(雪花 ID,序列化为字符串) |
|
||||
| fileName | String | 原始文件名 |
|
||||
| ossUrl | String | OSS 公网 URL,不签名 |
|
||||
| ossKey | String | OSS Object Key |
|
||||
| fileSize | Long | 文件大小(字节) |
|
||||
| fileType | String | 附件类型:`PDF` / `IMAGE` / `OTHER` |
|
||||
| createTime | LocalDateTime | 上传时间,序列化格式 `yyyy-MM-dd HH:mm:ss` |
|
||||
|
||||
#### 请求示例
|
||||
|
||||
```http
|
||||
GET /admin/house/assignments/requirements/2103126783048245250/receipts HTTP/1.1
|
||||
Host: api.test.1814.love:9443
|
||||
Authorization: Bearer <room_manager token>
|
||||
```
|
||||
|
||||
#### 响应示例
|
||||
|
||||
**成功(房务)**:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "成功",
|
||||
"success": true,
|
||||
"data": [
|
||||
{
|
||||
"receiptId": "2103801203844689921",
|
||||
"requirementId": "2103126783048245250",
|
||||
"orderId": "2100542287908892650",
|
||||
"fileName": "receipt_1.jpg",
|
||||
"ossUrl": "https://hlgl-test.oss-cn-beijing.aliyuncs.com/house/finalize-receipt/...",
|
||||
"ossKey": "house/finalize-receipt/2026-09/2103126783048245250_receipt_1.jpg",
|
||||
"fileSize": 512000,
|
||||
"fileType": "IMAGE",
|
||||
"createTime": "2026-09-26 14:30:00"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**失败(定制师)**:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 808090,
|
||||
"message": "未登录或非房务角色,无权操作",
|
||||
"success": false,
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
#### 空数据 / 降级响应
|
||||
|
||||
- 无回执:`code=200`,`data=[]`。
|
||||
|
||||
#### 错误响应
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 808090,
|
||||
"message": "未登录或非房务角色,无权操作",
|
||||
"success": false,
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
**说明**:
|
||||
- **808090**(新增):非房务角色返回;该读门调 `HouseReadGuard.assertHouseReadPermission()`,**不受** #8390 引入的灰度开关 `group-batch.acl.enforce.house-read-role` 控制,是常开的角色门。
|
||||
|
||||
#### 业务边界
|
||||
|
||||
- **角色放行**:ROOM_MANAGER / house_keeper_lead / SUPER_ADMIN 均可读;零角色(#7609 G-2 保留项)亦放行。
|
||||
- **无认领限制**:组长可看全部需求回执(监督权),他人接手后也可查历史。
|
||||
- **直链有效期**:测试桶直链公共可读(无签名);生产桶读策略未定,前端不得缓存直链。
|
||||
|
||||
---
|
||||
|
||||
## 四、契约约束与正确调用方式
|
||||
|
||||
| 场景 | 调用方法 | 说明 |
|
||||
|------|---------|------|
|
||||
| ✅ 认领人上传 | `POST /admin/house/assignments/requirements/{id}/receipts`,`multipart: file=@...` | 该需求的当前认领人上传,返回 200 |
|
||||
| ✅ 房务查列表 | `GET /admin/house/assignments/requirements/{id}/receipts` | 返回 200 + 全部回执 |
|
||||
| ✅ 组长查列表 | 同上(house_keeper_lead 身份)| 无限制,200 返回 |
|
||||
| ❌ 非认领人上传(含 SUPER_ADMIN) | — | 返回 808110,不落库;超管在本端点**不豁免**认领归属校验 |
|
||||
| ❌ 未认领需求(PENDING_CLAIM)上传 | — | 返回 808186(先过状态闸口) |
|
||||
| ❌ 定制师查列表 | — | 返回 808090 |
|
||||
| ❌ 缺 file 分片 | 空 multipart 或无 file 字段 | 返回 808184 |
|
||||
|
||||
---
|
||||
|
||||
## 五、数据库行为
|
||||
|
||||
无变更、无 Flyway。`house_finalize_receipt` 表与逻辑保留;认领人校验在内存判断,无新增存储。
|
||||
|
||||
---
|
||||
|
||||
## 六、边界行为
|
||||
|
||||
| 场景 | 行为 |
|
||||
|---|---|
|
||||
| 认领人上传 | 返回 200,回执入库入 OSS |
|
||||
| 非认领人上传(含 SUPER_ADMIN) | 返回 808110,无新行 |
|
||||
| 转单后原人上传 | 返回 808110(新人成认领人,原人失去权限) |
|
||||
| PENDING_CLAIM 需求上传 | 返回 808186(状态闸口先于认领校验) |
|
||||
| 组长列表查询 | 返回 200,全列表 |
|
||||
| 定制师列表查询 | 返回 808090,无数据 |
|
||||
| 缺 file 分片 / 0 字节 file 分片 | 返回 808184(HTTP 200、code 业务码,5 种原因文案) |
|
||||
|
||||
## 六.6、修改前后对比
|
||||
|
||||
| 维度 | 改前 | 改后 |
|
||||
|------|------|------|
|
||||
| 非认领人上传(含超管) | 返回 200,入库 | 返回 808110 |
|
||||
| 缺 file 分片 | HTTP 500、ERROR 日志 | HTTP 200、code 808184,仅 WARN 日志 |
|
||||
| 定制师查列表 | 返回 200 + 列表 | 返回 808090 |
|
||||
|
||||
## 六.7、影响评估
|
||||
|
||||
- **兼容性**:hl-ui 回执上传与列表操作收新错误码(808090/808091/808110/808186/808184);需处理新文案提示。
|
||||
- **前端要动的**:
|
||||
- 上传失败按错误码区分:「权限不足」(808090/808091)、「非本人(含超管)」(808110)、「需求未认领」(808186)、「文件」(808184,5 种原因文案,需在 `message` 里判断具体原因而非只判 code)。
|
||||
- 定制师等非房务角色不再能查回执列表,改改导航或隐藏入口。
|
||||
- **数据影响**:无;仅加校验,不改历史回执。
|
||||
- **其它服务**:hl-mp-service、fleet 无直接调用。
|
||||
|
||||
---
|
||||
|
||||
## 七、不影响范围
|
||||
|
||||
- 房务订单详情页回执展示逻辑(虽然定制师不再能查全列表,已登录进详情页的现有回执链接仍有效)。
|
||||
- 回执删除接口(无,但实体带 `@TableLogic` 支持软删)。
|
||||
- 其他配房写操作(转单、释放、分房等),无改动。
|
||||
|
||||
---
|
||||
|
||||
## 八、测试环境已验证
|
||||
|
||||
部署:测试环境 order-v3 `1f65d7894`(含 e2313790b)。网关 `api.test.1814.love:9443`。
|
||||
|
||||
| # | 场景 | 实测结果 |
|
||||
|---|---|---|
|
||||
| 1 | 认领人上传 | code 200,新行 uploader_id = 认领人;已软删清理 |
|
||||
| 2 | 非认领人上传 | code 808110,无新行 |
|
||||
| 3 | PENDING_CLAIM 需求上传 | code 808186 |
|
||||
| 4 | SUPER_ADMIN 对他人认领的需求上传 | code 808110(不豁免) |
|
||||
| 5 | 缺 file 分片(multipart 只带无关字段)×2 | HTTP 200 + `{"code":808184,"message":"回执上传失败:上传文件为空或缺少 file 分片"}` |
|
||||
| 6 | 0 字节 file 分片 | 同 #5,同码同文案 |
|
||||
| 7 | 房务(认领人本人)查列表 | code 200,全部回执 |
|
||||
| 8 | 定制师 / VEHICLE_MANAGER 查列表 | code 808090,无数据 |
|
||||
| 9 | house_keeper_lead / 非认领 ROOM_MANAGER / SUPER_ADMIN 查列表 | code 200,全部回执 |
|
||||
|
||||
#5、#6 场景 order-v3 日志对应 3 条 WARN `Business error [order.808184]`,无 `Unexpected error` ERROR 行。
|
||||
|
||||
---
|
||||
|
||||
## 十、相关文档
|
||||
|
||||
- Issue:https://git.1814.love/wx/HL/issues/8388
|
||||
- PR:https://git.1814.love/wx/HL/pulls/8394(原始改动)、https://git.1814.love/wx/HL/pulls/8399(808184 补 `{0}` 占位追加)
|
||||
- 相关单号:#8386(认领人校验,超管在该单**有**豁免,口径与本单相反)、#8390(读权限门同配方)
|
||||
|
||||
---
|
||||
|
||||
## 关联 / 联系人
|
||||
|
||||
### 联系人
|
||||
|
||||
- **后端负责人**: @wx
|
||||
@@ -0,0 +1,192 @@
|
||||
---
|
||||
schema: "hl-changelog/v2"
|
||||
ticket: "8389"
|
||||
title: "房务配房:下线 POST /v3/admin/order/assignments/{id}/rooms 家庭维度写接口"
|
||||
consumer: "admin"
|
||||
author: "wx(GIT)"
|
||||
change_type: "删除接口"
|
||||
backend_status: "deployed"
|
||||
gateway_status: "verified"
|
||||
frontend_status: "not_required"
|
||||
frontend_owner: ""
|
||||
frontend_ref: ""
|
||||
target_release: ""
|
||||
verified_at: ""
|
||||
status_note: "house 域家庭维度房间分配写口(POST)已下线,GET 端点由 #8390 补读门。hl-ui 零调用。"
|
||||
updated_at: "2026-09-26"
|
||||
base: "dev-v3"
|
||||
---
|
||||
|
||||
# order-v3:下线家庭维度房间分配写接口(管理后台)
|
||||
|
||||
**服务**: hl-order-service-v3
|
||||
**PR**: #8396
|
||||
**Issue**: #8389
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ 关键变化
|
||||
|
||||
`POST /v3/admin/order/assignments/{assignmentId}/rooms`(家庭维度房间分配)已删除,连同 `RoomAssignReqVO`/`RoomAssignRespVO` 与错误码 **808132**(入住人数必须 > 0)一并删除,码号不复用。
|
||||
|
||||
调用返回 HTTP 200 + `code: 404`(不是 HTTP 404)。GET 端点 `/v3/admin/order/orders/{orderId}/rooms` 由 #8390 补读权限门(ROOM_MANAGER/house_keeper_lead/SUPER_ADMIN 可读;非房务返 808090)。
|
||||
|
||||
---
|
||||
|
||||
## 一、背景
|
||||
|
||||
该端口对 `rooms[].roomGroupNo` 与 `rooms[].travelerCount` 无出行人校验,会写入脏数据(`F99` 分组、`travelerCount=99` 等)。无调用方,计划下线避免继续钉住问题。
|
||||
|
||||
表 `house_room_assignment` 与 GET 端点保留(级联软删仍有效);仅删写接口,该表此后无写入方,GET 端点出参里对新数据 `roomAssignments` 恒为空数组。`house_room_assignment` 只被 `HouseAssignmentService` 读;C 端聚合读的是 #8387 相关的 `order_room_assignment` 表(不同表),两者不要混淆。
|
||||
|
||||
---
|
||||
|
||||
## 二、变更接口清单
|
||||
|
||||
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|
||||
|---|------|------|------|----------|------|
|
||||
| 1 | 房间分配写 | POST | `/v3/admin/order/assignments/{assignmentId}/rooms` | 删除 | 路由已删,返回 404 |
|
||||
|
||||
GET 端点 `/v3/admin/order/orders/{orderId}/rooms` 由 #8390 补读门(不在本单)。
|
||||
|
||||
---
|
||||
|
||||
## 三、接口详情
|
||||
|
||||
### 1. 房间分配写 `POST /v3/admin/order/assignments/{assignmentId}/rooms`
|
||||
|
||||
**VO**: `已删除`
|
||||
|
||||
**状态**:已删除。路由不存在,返回 404。
|
||||
|
||||
#### 使用场景
|
||||
|
||||
该接口已删除。
|
||||
|
||||
#### 入参字段表
|
||||
|
||||
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||||
|------|------|------|------|------|------|
|
||||
| — | — | — | — | — | 已删除 |
|
||||
|
||||
#### 出参字段表
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| — | — | 已删除 |
|
||||
|
||||
#### 请求示例
|
||||
|
||||
```http
|
||||
POST /v3/admin/order/assignments/2103126783048245250/rooms HTTP/1.1
|
||||
Host: api.test.1814.love:9443
|
||||
Authorization: Bearer <admin token>
|
||||
Content-Type: application/json
|
||||
|
||||
{}
|
||||
```
|
||||
|
||||
#### 响应示例
|
||||
|
||||
HTTP 状态码 **200**(非 404),业务错误码 404:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 404,
|
||||
"message": "接口不存在: POST /v3/admin/order/assignments/2103126783048245250/rooms",
|
||||
"success": false,
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
#### 空数据 / 降级响应
|
||||
|
||||
不适用。前端应只判 `code`,不依赖 HTTP 状态码。
|
||||
|
||||
#### 错误响应
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 404,
|
||||
"message": "接口不存在: POST /v3/admin/order/assignments/2103126783048245250/rooms",
|
||||
"success": false,
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
#### 业务边界
|
||||
|
||||
- 接口已删除,路由不存在;调用返回 HTTP 200 + `code: 404`。
|
||||
- 错误码 808132(入住人数必须 > 0)随本单一并删除,码号不复用。
|
||||
- hl-ui 零调用;测试网关 nginx 日志窗口内该路径 53 次调用全部是脚本(python-requests / Python-urllib),零浏览器 UA。
|
||||
|
||||
---
|
||||
|
||||
## 四、契约约束与正确调用方式
|
||||
|
||||
该接口已删除,不可调用。
|
||||
|
||||
---
|
||||
|
||||
## 五、数据库行为
|
||||
|
||||
无变更、无 Flyway。表 `house_room_assignment` 保留;级联软删仍有效。
|
||||
|
||||
---
|
||||
|
||||
## 六、边界行为
|
||||
|
||||
| 场景 | 行为 |
|
||||
|---|---|
|
||||
| 调用 POST /assignments/{id}/rooms | 返回 HTTP 200 + code 404 |
|
||||
| 调用 GET /orders/{id}/rooms | 仍在(200);#8390 补读门后,非房务返 808090 |
|
||||
| `house_room_assignment` 表 | 保留,此后无写入方,级联软删仍对存量数据有效 |
|
||||
|
||||
## 六.6、修改前后对比
|
||||
|
||||
| 维度 | 改前 | 改后 |
|
||||
|------|------|------|
|
||||
| POST 家庭房间 | 路由存在,可写 | 路由删除,返回 404 |
|
||||
|
||||
## 六.7、影响评估
|
||||
|
||||
- **兼容性**:hl-ui 零调用,无前端迁移。
|
||||
- **数据影响**:零;表与 GET 保留。
|
||||
- **其它服务**:无。
|
||||
|
||||
---
|
||||
|
||||
## 七、不影响范围
|
||||
|
||||
- 房间分配 GET:保留(#8390 补读门)。
|
||||
- 其他配房写(delete/updatePlacement 等):无改动。
|
||||
- 级联软删:保留。
|
||||
|
||||
---
|
||||
|
||||
## 八、测试环境已验证
|
||||
|
||||
部署:测试环境 order-v3 `1f65d7894`(含 e2313790b)。网关 `api.test.1814.love:9443`。
|
||||
|
||||
| # | 场景 | 实测结果 |
|
||||
|---|---|---|
|
||||
| 1 | `POST /v3/admin/order/assignments/{assignmentId}/rooms` | HTTP 200 + code 404「接口不存在: …」 |
|
||||
| 2 | `GET /v3/admin/order/orders/{orderId}/rooms` | 200(仍在) |
|
||||
|
||||
调用来源:测试网关 nginx 日志窗口内该路径 53 次,全部是脚本(python-requests / Python-urllib),零浏览器 UA。
|
||||
|
||||
---
|
||||
|
||||
## 十、相关文档
|
||||
|
||||
- Issue:https://git.1814.love/wx/HL/issues/8389
|
||||
- PR:https://git.1814.love/wx/HL/pulls/8396
|
||||
- 关联:#8390(补读权限门)
|
||||
|
||||
---
|
||||
|
||||
## 关联 / 联系人
|
||||
|
||||
### 联系人
|
||||
|
||||
- **后端负责人**: @wx
|
||||
文件差异内容过多而无法显示
加载差异
在新工单中引用
屏蔽一个用户