88caa74 房务接口审计批次:#8385 订房计划守卫/#8386 住宿驳回加门+删车务口/#8387 旧房间分配三口下线/#8388 回执认领校验+读门/#8389 家庭维度写口下线/#8390 16 读端点补门+菜单撤授。前端按钮后端字段驱动+错误码拦截器透 message+被删端点零调用/入口仅房务角色页,6 条均 not_required;#8387/#8389 后端已标,余 4 条翻 not_required,owner/ref 留空,status_note 引号内追充实证。
12 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 | 8386 | 住宿需求驳回:加房务角色门与认领人校验;车务驳回接口下线 | admin | wx(GIT) | 删除接口 | deployed | verified | not_required | 住宿需求供应方驳回新增房务角色门(808090/808091)与认领人校验(808110/808116,超管豁免);车务驳回接口删除,调用返回 HTTP 200 + code 404。已在测试环境网关实测各角色分支与已删除端点响应。前端实证(mmg 2026-09-27):车务驳回口零调用;住宿驳回按钮 enabled/disabledReason 由后端 canRejectRequirement 驱动,新码拦截器透 message,零改动 not_required。 | 2026-09-26 | dev-v3 |
order-v3:住宿需求驳回守卫加固与车务驳回下线(管理后台)
服务: hl-order-service-v3
PR: #8397
Issue: #8386
⚠️ 关键变化
-
住宿需求供应方驳回
POST /v3/admin/order/{id}/hotel-requirement/supplier-reject:- 新增房务角色门:
@HouseWriteGuarded,非房务角色返回 808090,房务组长返回 808091。 - 新增认领人校验:需求必须被当前操作人认领,否则返回 808110(非本人)/ 808116(未认领,仅超管可驳)。
- 超管可绕过认领限制(跳过本人限制,但仍受角色门约束)。
- 新增房务角色门:
-
车务需求供应方驳回
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 |
请求示例
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": "房型不符,请调整"
}
响应示例
成功:
{
"code": 200,
"message": "成功",
"success": true,
"data": null
}
失败(非认领人):
{
"code": 808110,
"message": "需求不属于当前用户",
"success": false,
"data": null
}
失败(无房务权限):
{
"code": 808090,
"message": "未登录或非房务角色,无权操作",
"success": false,
"data": null
}
空数据 / 降级响应
returnRemark缺失或为空白:@Valid校验不通过,HTTP 200 +code: 400+ 具体字段错误信息(不进入业务逻辑)。
错误响应
{
"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: 已删除
状态:已删除
使用场景
该接口已删除,不可用。
入参字段表
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| — | — | — | — | — | 已删除 |
出参字段表
| 字段 | 类型 | 说明 |
|---|---|---|
| — | — | 已删除 |
请求示例
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:
{
"code": 404,
"message": "接口不存在: POST /v3/admin/order/770145/vehicle-requirement/supplier-reject",
"success": false,
"data": null
}
空数据 / 降级响应
不适用(路由已删)。前端应只判 code,不依赖 HTTP 状态码。
错误响应
{
"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 」 |
调用来源:测试网关 nginx 日志 2026-09-12~09-26 窗口内车务 supplier-reject 共 19 次,全部是脚本(Python-urllib / curl / 空 UA),零浏览器 UA;hl-ui 全部远程 ref 零调用。
十、相关文档
- Issue:wx/HL#8386
- PR:wx/HL#8397
- 相关单号:#8373(车务我的接单下线)、#8388(回执认领人校验同口径)
- API-SPEC:
docs/order-v3/api/API-SPEC-HOUSE-V1.1.html§2.8
关联 / 联系人
联系人
- 后端负责人: @wx