Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XYL5S9SsBtkg7aGyFAbrrQ
17 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 | 7210 | 团期管理员确认 / 打回改造(M1/M2) | admin | wx(GIT) | 修改接口 | deployed | verified | pending | mmg | 2026-09-07 | 后端已合 dev-v3(PR #7220、#7222)并部署测试服(order-v3 + user-service,HEAD 5ab5a6cbe),网关实测 AC-2/3/4/5/6/7/9/10/11/12/14/15/20/21 通过。破坏性变更:reject body 从可选改必填(orderIds/reason),前端与后端需同步上线。 | 2026-09-07 | dev-v3 |
团期模块:管理员确认 / 打回改造(M1/M2)
服务:
hl-order-service-v3、hl-user-service(权限种子) Issue: #7210 PR: 待合并后回填 日期: 2026-09-07 影响范围: 管理后台团期详情「查看需求」Tab,逐单详情页面打回/分房入口
⚠️ 关键变化
三条核心改造:
-
M1 整体确认需求:缺失校验 → 置标记 → 逐户 PENDING_REVIEW→PENDING + 房控同步 → afterCommit 通知房务。缺失时硬拒绝 589533,零写入;成功后返回已放行户与已有户两份清单。新增预检端点
confirm-check。 -
M2 按户打回需求:逐户 CAS 打回定制师、清 claimer、同步房控、开待办、发站内信。破坏性变更:body 从可选改必填(
orderIds必填非空、reason必填 ≤512、resourceType新增可选)。 -
逐单打回放宽与权限统一:源状态由
{PENDING_REVIEW}放宽为{PENDING_REVIEW, PENDING};已分房守卫改报 589535(批量与逐单入口都先判已分房再判源状态:房务认领后需求为 PROCESSING,已分房户一律 589535「请先由房务调整配房后再打回」,不会落成 589534)。逐单 reject/dispatch 四入口新增权限守卫group-batch:demand:confirm(589507)。
二、变更接口清单
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|---|---|---|---|---|---|
| 1 | 需求缺失预检(新增) | GET | /v3/admin/order/group-batch/{groupBatchId}/requirement/confirm-check |
新增接口 | 整体确认前的缺失清单 |
| 2 | 整体确认需求 | POST | /v3/admin/order/group-batch/{groupBatchId}/requirement/confirm |
响应 VO 改造 | 返回 GroupBatchRequirementConfirmRespVO 替代 Void |
| 3 | 按户打回需求(破坏性) | POST | /v3/admin/order/group-batch/{groupBatchId}/requirement/reject |
请求体必填改造+响应 VO | orderIds/reason 必填;响应返回 GroupBatchRequirementRejectRespVO |
| 4 | 子订单打回房需求 | POST | /v3/admin/order/{id}/hotel-requirement/reject |
权限新增+源状态放宽 | 接 group-batch:demand:confirm;对 PENDING 团单放开;已分房改报 589535 |
| 5 | 子订单打回车需求 | POST | /v3/admin/order/{id}/vehicle-requirement/reject |
权限新增+源状态放宽 | 接 group-batch:demand:confirm;源状态放宽 |
| 6 | 子订单分房(房) | POST | /v3/admin/order/{id}/hotel-requirement/dispatch |
权限新增 | 接 group-batch:demand:confirm |
| 7 | 子订单分房(车) | POST | /v3/admin/order/{id}/vehicle-requirement/dispatch |
权限新增 | 接 group-batch:demand:confirm |
三、接口详情
1. 需求缺失预检 GET /v3/admin/order/group-batch/{groupBatchId}/requirement/confirm-check
VO: GroupBatchRequirementCheckRespVO
使用场景
团期管理员在「查看需求」Tab 进入与点「确认」前调用,根据 ready 置灰确认按钮、根据 missing 展示缺失户。
入参字段表
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
groupBatchId |
Path | Long(String) | ✓ | 团期主订单 ID | order_group_batch.group_batch_id |
出参字段表
| 字段 | 类型 | 说明 |
|---|---|---|
data.groupBatchId |
Long(String) | 团期 ID |
data.batchStatus |
String | 团期当前状态 |
data.ready |
Boolean | missing 为空且 batchStatus∈{RESOURCE_PREPARING,MATERIAL_PREPARING} 时 true |
data.missing[] |
List | 缺失户清单(按 orderId 升序) |
请求示例
GET /v3/admin/order/group-batch/1867000000001/requirement/confirm-check
响应示例
{
"code": 200,
"message": "成功",
"success": true,
"data": {
"groupBatchId": "1867000000001",
"batchStatus": "RESOURCE_PREPARING",
"ready": false,
"missing": [
{
"orderId": "60123456789001",
"orderNo": "HL2609010001",
"consultantId": "10001",
"consultantName": "李四",
"reason": "NOT_SUBMITTED"
}
]
}
}
空数据 / 降级响应
所有户齐备时 ready=true,missing=[]。
错误响应
{
"code": 589507,
"message": "无操作权限",
"success": false,
"data": null
}
业务边界条目
- 缺失判定:NOT_SUBMITTED(needs_hotel=1 无 active 房需求行);ROOM_CATEGORY_MISSING(非自订晚某段首方案缺房型或房数<1);INVALID_REQUIREMENT(days 为空 / 缺住宿日期 / 非自订晚 segments 或 rooms 为空 / JSON 损坏)
- 权限:需
group-batch:demand:confirm - 零副作用:纯读接口
2. 整体确认需求 POST /v3/admin/order/group-batch/{groupBatchId}/requirement/confirm
VO: GroupBatchRequirementConfirmRespVO
使用场景
团期管理员确认全团需求齐备,允许房务向酒店下单。
入参字段表
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
groupBatchId |
Path | Long(String) | ✓ | 团期主订单 ID | - |
出参字段表
| 字段 | 类型 | 说明 |
|---|---|---|
data.requirementConfirmed |
Boolean | 固定 true |
data.dispatchedOrderIds |
List<Long(String)> | 本次放行的子订单 ID |
data.skippedOrderIds |
List<Long(String)> | 本次未动的子订单 ID |
请求示例
POST /v3/admin/order/group-batch/1867000000001/requirement/confirm
响应示例
{
"code": 200,
"message": "成功",
"success": true,
"data": {
"groupBatchId": "1867000000001",
"requirementConfirmed": true,
"dispatchedOrderIds": ["60123456789001"],
"skippedOrderIds": ["60123456789002"]
}
}
空数据 / 降级响应
dispatchedOrderIds 与 skippedOrderIds 中至少一个非空。
错误响应
{
"code": 589533,
"message": "仍有 2 户未提交需求",
"success": false,
"data": null
}
业务边界条目
- 团期必须为 RESOURCE_PREPARING 或 MATERIAL_PREPARING,否则 589501
- 任一户缺失→589533 零写入
- 权限需 group-batch:demand:confirm
3. 按户打回需求 POST /v3/admin/order/group-batch/{groupBatchId}/requirement/reject
VO: RejectRequirementReqVO → GroupBatchRequirementRejectRespVO
使用场景
团期管理员多选户打回,逐户退回定制师。
入参字段表
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
groupBatchId |
Path | Long(String) | ✓ | 团期主订单 ID | - |
orderIds |
Body | List | ✓ | @NotEmpty | 破坏性变更:改前可选现必填 |
reason |
Body | String | ✓ | @NotBlank @Size(max=512) | 破坏性变更 |
resourceType |
Body | String | 否 | 默认 ALL | 新增 |
出参字段表
| 字段 | 类型 | 说明 |
|---|---|---|
data.requirementConfirmed |
Boolean | 固定 false |
data.rejected[] |
List | 被打回的需求条目 |
请求示例
POST /v3/admin/order/group-batch/1867000000001/requirement/reject
{
"orderIds": [60123456789001],
"reason": "房间需求与套餐不匹配",
"resourceType": "ALL"
}
响应示例
{
"code": 200,
"message": "成功",
"success": true,
"data": {
"groupBatchId": "1867000000001",
"requirementConfirmed": false,
"rejected": [
{
"orderId": "60123456789001",
"resourceType": "HOTEL",
"requirementId": "90011223344"
}
]
}
}
空数据 / 降级响应
rejected 列表大小等于成功打回的数量。
错误响应
{
"code": 400,
"message": "请至少选择一个要打回的子订单",
"success": false,
"data": null
}
业务边界条目
- 全量前置校验,任一违规则整单零副作用
- 权限需 group-batch:demand:confirm
4. 子订单打回房需求 POST /v3/admin/order/{id}/hotel-requirement/reject
VO: RejectReqVO → Void
使用场景
团期管理员逐单打回定制师的房需求。
入参字段表
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
id |
Path | Long(String) | ✓ | 子订单 ID | - |
returnRemark |
Body | String | ✓ | @NotBlank | 打回原因 |
出参字段表
| 字段 | 类型 | 说明 |
|---|---|---|
| data | null | 无返回内容 |
请求示例
POST /v3/admin/order/60123456789001/hotel-requirement/reject
{
"returnRemark": "房型不符"
}
响应示例
{
"code": 200,
"message": "成功",
"success": true,
"data": null
}
空数据 / 降级响应
无。
错误响应
{
"code": 589507,
"message": "无操作权限",
"success": false,
"data": null
}
业务边界条目
- 新增权限 group-batch:demand:confirm
- 源状态放宽 {PENDING_REVIEW, PENDING}
- 已分房改报 589535
5. 子订单打回车需求 POST /v3/admin/order/{id}/vehicle-requirement/reject
VO: RejectReqVO → Void
使用场景
团期管理员逐单打回定制师的用车需求。
入参字段表
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
id |
Path | Long(String) | ✓ | 子订单 ID | - |
returnRemark |
Body | String | ✓ | @NotBlank | 打回原因 |
出参字段表
| 字段 | 类型 | 说明 |
|---|---|---|
| data | null | 无返回内容 |
请求示例
POST /v3/admin/order/60123456789001/vehicle-requirement/reject
{
"returnRemark": "车型调整"
}
响应示例
{
"code": 200,
"message": "成功",
"success": true,
"data": null
}
空数据 / 降级响应
无。
错误响应
{
"code": 589507,
"message": "无操作权限",
"success": false,
"data": null
}
业务边界条目
- 新增权限 group-batch:demand:confirm
- 源状态放宽 {PENDING_REVIEW, PENDING}
6. 子订单分房(房) POST /v3/admin/order/{id}/hotel-requirement/dispatch
VO: DispatchReqVO → Void
使用场景
房务将确认的房需求派给酒店。
入参字段表
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
id |
Path | Long(String) | ✓ | 子订单 ID | - |
dispatchRemark |
Body | String | 否 | - | 分房备注 |
出参字段表
| 字段 | 类型 | 说明 |
|---|---|---|
| data | null | 无返回内容 |
请求示例
POST /v3/admin/order/60123456789001/hotel-requirement/dispatch
{
"dispatchRemark": "已向酒店下单"
}
响应示例
{
"code": 200,
"message": "成功",
"success": true,
"data": null
}
空数据 / 降级响应
无。
错误响应
{
"code": 589507,
"message": "无操作权限",
"success": false,
"data": null
}
业务边界条目
- 新增权限 group-batch:demand:confirm
- 其余行为不变
7. 子订单分房(车) POST /v3/admin/order/{id}/vehicle-requirement/dispatch
VO: DispatchReqVO → Void
使用场景
车务将确认的用车需求派给供应商。
入参字段表
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
id |
Path | Long(String) | ✓ | 子订单 ID | - |
dispatchRemark |
Body | String | 否 | - | 分房备注 |
出参字段表
| 字段 | 类型 | 说明 |
|---|---|---|
| data | null | 无返回内容 |
请求示例
POST /v3/admin/order/60123456789001/vehicle-requirement/dispatch
{
"dispatchRemark": "已通知车队"
}
响应示例
{
"code": 200,
"message": "成功",
"success": true,
"data": null
}
空数据 / 降级响应
无。
错误响应
{
"code": 589507,
"message": "无操作权限",
"success": false,
"data": null
}
业务边界条目
- 新增权限 group-batch:demand:confirm
- 其余行为不变
四、契约约束与正确调用方式
正确 / 错误 payload 对照
| 场景 | payload | 预期 |
|---|---|---|
| ✅ 确认:所有户齐备 | POST /confirm(无 body) |
200,放行所有 PENDING_REVIEW 户 |
| ❌ 确认:某户缺需求 | POST /confirm(无 body) |
589533,零写入 |
| ✅ 打回:必填字段齐全 | { "orderIds": […], "reason": "…" } |
200,逐户打回 |
| ❌ 打回:缺 orderIds | { "reason": "…" } |
400 |
| ❌ 打回:orderIds 空数组 | { "orderIds": [], "reason": "…" } |
400 |
调用约束
- 确认前必调 confirm-check 展示缺失清单、置灰按钮
- 打回弹窗改传 orderIds 数组 + reason
- 逐单入口四个均需 group-batch:demand:confirm,无权限返 589507
五、数据库行为
order-v3:
- 需求表:CAS 打回行 status/is_active/return_remark/returned_at/returned_by
- 订单表:同步 room_control_status 为 PENDING / REJECTED_TO_CONSULTANT
- 团期表:requirement_confirmed → 1(M1)/ 0(M2)
- 时间线表:写 REQUIREMENT_DISPATCHED / BATCH_REQUIREMENT_REJECT 两条
hl-user-service:
- Flyway DML 种子 V20260906_006(INSERT 权限码 + ADMIN/SUPER_ADMIN 关联)
六、边界行为
- 团期查不到 → 589500
- M1 仅认 RESOURCE_PREPARING/MATERIAL_PREPARING;M2 不限但冻结期有例外
- 并发互斥:同一团期 confirm/reject 最多一个进入;5s 内连点被 Idempotent 拒
- 幂等:M1 重复调用第二次 dispatchedOrderIds 为空
- 权限缓存:Redis TTL 24h,Flyway 后需清缓存或重登
六.5、枚举 / 数据字典
缺失原因
| 值 | 中文 | 触发 |
|---|---|---|
| NOT_SUBMITTED | 未提交房需求 | needs_hotel=1 无 active 行 |
| ROOM_CATEGORY_MISSING | 房型或房数缺失 | 非自订晚某段首候选缺字段 |
| INVALID_REQUIREMENT | 需求数据不完整 | days 为空 / 缺住宿日期 / 非自订晚 segments 或 rooms 为空 / JSON 损坏 |
六.6、修改前后对比
字段级对比
| 接口 | 字段 | 改前 | 改后 |
|---|---|---|---|
| confirm 响应 | 类型 | Result | Result |
| reject 请求 | orderIds | 无 | 必填 @NotEmpty |
| reject 请求 | reason | 可选 | 必填 @NotBlank @Size(max=512) |
| reject 请求 | resourceType | 无 | 新增 HOTEL/VEHICLE/ALL 默认 ALL |
| reject 响应 | 类型 | Result | Result |
| hotel-requirement/reject | 源状态 | {PENDING_REVIEW} | 放宽 {PENDING_REVIEW, PENDING} |
| hotel-requirement/reject | 已分房错误码 | 582086 | 改为 589535 |
行为级对比
| 行为 | 改前 | 改后 |
|---|---|---|
| 整体确认 | 仅置标记,无缺失校验 | 缺失校验→置标记→逐户放行→通知房务 |
| 按户打回 | 置团级标记不改户状态 | 逐户 CAS 打回、房控同步、待办、站内信 |
六.7、影响评估
- 破坏向后兼容:是 —— reject 必填参数改变;旧客户端传空 body 改为 400
- 前端是否必须同步上线:是 —— 破坏性变更,前后端需同一版本发布
- 前端需清理的分支:打回弹窗改传 orderIds;确认前必调 confirm-check;reject 响应改为带 rejected[]
七、不影响范围
- 订单创建/修改
- 抢单池列表与房务认领流程本身(放行后的团单需求按既有规则以 PENDING 进池;本单只是不做抢单池 SSE 广播,团单整团汇总进池形态归 H 系列工单)
- 权限体系(仅新增一个权限码)
- 网关路由(/v3/admin/** 通配不变)
- 数据库表结构(order-v3 无新表无列变更;hl-user-service 仅 DML)
八、测试环境已验证
待后端网关实测通过后补充。
十、相关文档
- 工单正文:#7210 接口变更节、口径与定案节、验收标准 AC-1~AC-22
- 接口文档:docs/group/团期模块接口文档-v2.0.html §0C.2、GB-ADM-012/013、§3.1
- 实现方案:docs/group/团期房务实现方案-v1.0.html §3.5
关联 / 联系人
链接
- Issue: #7210
- PR: 待合并后回填
- Merge commit: 待合并后回填
联系人
- 后端负责人: wx
- 前端负责人(hl-ui): mmg