443 行
28 KiB
Markdown
443 行
28 KiB
Markdown
---
|
||
schema: "hl-changelog/v2"
|
||
ticket: "7149"
|
||
title: "团期子订单支付后即可提房车需求、物资准备起冻结、团单房型与间数必填"
|
||
consumer: "admin"
|
||
author: "wx(GIT)"
|
||
change_type: "修改接口"
|
||
backend_status: "deployed"
|
||
gateway_status: "verified"
|
||
frontend_status: "verified"
|
||
frontend_owner: "mmg"
|
||
frontend_ref: "22eb9b03"
|
||
target_release: ""
|
||
verified_at: "2026-09-08"
|
||
status_note: "后端已合 dev-v3 并部署测试服、网关实测通过(PR #7177/#7184/#7200)。第二轮返工(2026-09-07):打回原因长度 512→500,房务置灰口径改按订单整体判。前端第一批已交付:团单房型大类+间数必填校验(FunItemAdjustModal,房数 0/空前端即拦截)、打回户房型需求入口恢复(RoomArrangeCard),ref 85fb6d52。0451e4c 错误码优先级口径更正(对外唯一变化:团单 582099 先于 582016;结构类先于状态类)前端仅 message 透传展示后端文案、无按码分支,零改动。第二批冻结置灰(物料准备中起置灰)待后端 #7197 订单详情透传 groupBatchStatus,本条保持 pending;期间 589536 兜底。
|
||
updated_at: "2026-09-06"
|
||
base: "dev-v3"
|
||
---
|
||
|
||
# 团期模块:子订单支付后即可提房车需求、物资准备起冻结、团单房型与间数必填
|
||
|
||
> **服务**: `hl-order-service-v3`
|
||
> **Issue**: #7149
|
||
> **PR**: #7177(squash 合入 dev-v3 `a52365278`)、#7184(复审补漏:汇总跳自订晚、团单房数缺失统一 582099)、#7200(直提入口 `PUT …/hotel-requirement` 团单房数 0 同样 582099,与调整入口同序)
|
||
> **日期**: 2026-09-06
|
||
> **影响范围**: 管理后台团期子订单详情「住宿安排 / 用车安排」提需求弹窗与「订单调整」提交
|
||
|
||
## ⚠️ 关键变化
|
||
|
||
三条行为改造,请求 / 响应结构一律不变:
|
||
|
||
1. **支付后即可提需求**:团期子订单(详情里 `groupOrder=true` / `productBatchId` 非空)在客户已支付(`orderStatus=CUSTOMIZING`)后即可提 / 改用房、用车需求,团期处于「招募中 `RECRUITING`」或「资源准备中 `RESOURCE_PREPARING`」都放行,不再等团期成团。改前团期非 `RESOURCE_PREPARING` 一律 589501「团期状态不允许当前操作」。
|
||
2. **物资准备起冻结**:团期进入「物料准备中 `MATERIAL_PREPARING`」及之后(`PENDING_DEPARTURE / TRAVELLING / REVIEWING / SETTLED`)提 / 改需求被拒,新错误码 **589536「团期已进入物资准备,需求已冻结,请联系团期管理员」**(文案里的「物资准备」就是状态芯片的「物料准备中」,同义)。唯一例外:该户该资源最新一版需求被团期管理员打回(`REJECTED_TO_CONSULTANT`)时可以重提一次,重提后再改仍 589536。团期 `CANCELLED` / 查不到团期仍 589501。
|
||
3. **团单房型大类与房间数必填**:团期子订单每个非自订晚(`customerSelfBooked` 非 `true`)的每段,按段首候选 `candidates[0].rooms[]` 逐行要求 `roomCategory` 非空且 `roomCount ≥ 1`(旧结构无 `rooms[]` 时按段级 `roomCategory` + `roomCount` 判),缺失返回新错误码 **582099「团期订单第{N}晚第{M}段需填写房型大类与房间数」**(M 从 1 起),拒绝时零副作用。核心订单不受影响,房型仍选填。**团单不再接受「加晚次空白占位」段**——每晚要么填齐房型行,要么标 `customerSelfBooked=true`。
|
||
|
||
前端要做:① 团期子订单提需求弹窗把「房型大类」改必填并提示;② 589536 / 582099 直接展示后端 `message`;③ 团期子订单在招募中即显示「提交房型需求 / 用车需求」入口;进入物料准备中后入口置灰或提示已冻结(被打回的户除外);④ 团单去掉「先提交空白占位」交互。
|
||
|
||
## 二、变更接口清单
|
||
|
||
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|
||
|---|---|---|---|---|---|
|
||
| 1 | 提交 / 修改用房需求(兼容期 @Deprecated) | PUT | `/v3/admin/order/{id}/hotel-requirement` | 行为修改 | 团期闸门放宽 + 冻结 + 团单房型间数必填 |
|
||
| 2 | 订单调整统一提交 | POST | `/v3/admin/order/{id}/adjustment/submit` | 行为修改 | `updates.hotelRequirement` / `updates.vehicleRequirement` 走同一闸门与必填校验 |
|
||
| 3 | 提交 / 修改用车需求 | PUT | `/v3/admin/order/{id}/vehicle-requirement` | 行为修改 | 团期闸门放宽 + 冻结,不加必填 |
|
||
|
||
## 三、接口详情
|
||
|
||
### 1. 提交 / 修改用房需求 `PUT /v3/admin/order/{id}/hotel-requirement`
|
||
|
||
**VO**: `HotelRequirementReqVO → HotelRequirementRespVO`(`hl-order-service-v3/src/main/java/com/hulalv/order/requirement/controller/admin/vo/`)
|
||
|
||
#### 使用场景
|
||
|
||
定制师在子订单详情「住宿安排」提交或修改用房需求。后端按当前生效版本自动分支:无生效版本 → `INIT_SUBMIT`(新版本);生效版本为 `PENDING / PENDING_REVIEW` → `PENDING_EDIT`(同版本覆盖);`DONE` 等 → `DONE_ADJUST`(版本 +1)。团期子订单新版本状态恒为 `PENDING_REVIEW`(等团期管理员确认),不进房务抢单池。本端点为兼容期入口(#4515 标 @Deprecated),新客户端走接口 2。
|
||
|
||
#### 入参
|
||
|
||
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||
|---|---|---|---|---|---|
|
||
| `id` | Path | String(Long) | 是 | 订单 ID | 团期子订单 `productBatchId` 非空 |
|
||
| `days` | Body | Array | 是 | 长度 = `tripNights`,`dayNumber` 1..tripNights 不重复 | 逐晚安排 |
|
||
| `days[].dayNumber` | Body | Integer | 是 | 1..tripNights | 第几晚 |
|
||
| `days[].customerSelfBooked` | Body | Boolean | 否 | `true` = 客人自订 | 自订晚不校验房型,`segments` 可空 |
|
||
| `days[].segments` | Body | Array | 非自订晚 ≥1 | 缺段 582098 | 当晚分住段 |
|
||
| `days[].segments[].candidates` | Body | Array | 是(≥1) | 候选酒店,房控择一 | `hotelId / hotelName` 可空(无酒店候选) |
|
||
| `days[].segments[].candidates[].rooms` | Body | Array | 新结构 | 房型行 | 团单按 `candidates[0].rooms` 逐行校验 |
|
||
| `…rooms[].roomCategory` | Body | String | **团单是** | 字典 `room_category`(STANDARD/SINGLE/TWIN/QUEEN/KING/SUITE/FAMILY/YURT/SPECIAL) | 核心订单选填不变 |
|
||
| `…rooms[].roomCount` | Body | Integer | **团单是,≥1** | 有行即 >0(582016) | 房数 |
|
||
| `…rooms[].roomTypeId / roomTypeName / protocolPrice / remark` | Body | Long / String / Decimal / String | 否 | — | 真实房型与快照,可空 |
|
||
| `days[].segments[].roomCategory / roomCount` | Body | String / Integer | 兼容 | 旧结构无 `rooms[]` 时团单必填 | 段级兼容字段 |
|
||
| `days[].segments[].budget / remark` | Body | Decimal / String(≤200) | 否 | 预算由后端按协议价覆盖 | — |
|
||
| `specialTags` | Body | String[] | 否 | 字典 `house_special_demand` | 特殊诉求 |
|
||
| `remark` | Body | String(≤500) | 否 | — | 备注 |
|
||
|
||
#### 出参 `Result<HotelRequirementRespVO>`
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|---|---|---|
|
||
| `data.requirementId` | String | 需求行 ID |
|
||
| `data.version` | Integer | 版本号(INSERT-only 单调递增) |
|
||
| `data.isActive` | Boolean | 是否当前生效版本 |
|
||
| `data.status` | String | 团单恒 `PENDING_REVIEW`;核心为 `PENDING` |
|
||
| `data.submittedAt` | String | 首提时间 |
|
||
| `data.claimerId / claimerName / claimedAt` | String / String / String | 团单恒 null(不进抢单池) |
|
||
| `data.branchTaken` | String | `INIT_SUBMIT / PENDING_EDIT / DONE_ADJUST` |
|
||
| `data.previousVersion` | Integer | `DONE_ADJUST` 时上一版本号,否则 null |
|
||
| `data.assignmentDeletedCount` | Integer | `DONE_ADJUST` 时软删配房行数,否则 null |
|
||
|
||
#### 请求示例
|
||
|
||
```json
|
||
{
|
||
"days": [
|
||
{ "dayNumber": 1, "segments": [ { "remark": "第1晚", "candidates": [ { "hotelName": "网关实测酒店", "rooms": [ { "roomTypeName": "测试房型", "roomCategory": "KING", "roomCount": 1 } ] } ] } ] },
|
||
{ "dayNumber": 2, "segments": [ { "remark": "第2晚", "candidates": [ { "hotelName": "网关实测酒店", "rooms": [ { "roomTypeName": "测试房型", "roomCategory": "TWIN", "roomCount": 2 } ] } ] } ] }
|
||
],
|
||
"remark": "#7149 网关实测"
|
||
}
|
||
```
|
||
|
||
#### 响应示例
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "成功",
|
||
"success": true,
|
||
"data": {
|
||
"requirementId": "2096504560393551873",
|
||
"version": 1,
|
||
"isActive": true,
|
||
"status": "PENDING_REVIEW",
|
||
"submittedAt": "2026-09-06 15:44:21",
|
||
"claimerId": null,
|
||
"claimerName": null,
|
||
"claimedAt": null,
|
||
"branchTaken": "INIT_SUBMIT",
|
||
"previousVersion": null,
|
||
"assignmentDeletedCount": null
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 空数据 / 降级响应
|
||
|
||
本接口无空列表语义;`days` 为空数组或长度与 `tripNights` 不符返回 582011「天数长度与订单住宿晚数不一致」。第 2 晚 `customerSelfBooked=true` 且无 `segments` 时正常返回 200(自订晚不进房务分母,团单房型校验跳过)。
|
||
|
||
#### 错误响应
|
||
|
||
```json
|
||
{ "code": 582099, "message": "团期订单第2晚第1段需填写房型大类与房间数", "success": false, "data": null }
|
||
```
|
||
|
||
```json
|
||
{ "code": 589536, "message": "团期已进入物资准备,需求已冻结,请联系团期管理员", "success": false, "data": null }
|
||
```
|
||
|
||
其它沿用:589501「团期状态不允许当前操作」(团期 `CANCELLED` / 查不到)、582098「第{N}晚缺少用房需求,请填写房间需求或标记为客户自订」、582016「房间数必须大于 0」、582019「候选方案必须至少含 1 个房型行」、582017「订单状态不允许提交需求」(未支付)。HTTP 始终 200,错误在 `code` / `message`。
|
||
|
||
#### 业务边界
|
||
|
||
- 团期闸门(房车共用):`RECRUITING / RESOURCE_PREPARING` 放行;`MATERIAL_PREPARING / PENDING_DEPARTURE / TRAVELLING / REVIEWING / SETTLED` 及未知状态 589536;`CANCELLED` / 查不到团期 589501;核心订单不查团期。
|
||
- 冻结期例外:该户用房需求最高版本组(同 version 的一组行,含已失活的打回行;有生效行看生效行,否则组内任一行)为 `REJECTED_TO_CONSULTANT`(团期管理员打回)时放行重提,新版本回到 `PENDING_REVIEW`;之后再改仍 589536,要再改只能再次被打回。
|
||
- 团单房型间数必填按「段首候选 rooms 行」判,与全团需求汇总 `requirement-summary` 同口径;旧结构(无 `rooms[]`)按段级 `roomCategory + roomCount` 合成一行判。
|
||
- 校验顺序(接口对外可观察口径,PR #7184 / #7200 起):本接口**进事务前**先做入口校验——团单房型间数(582099,仅团单,含房数为空 / 0)→ 通用结构校验(582098 / 582016 / 582019 / 582020);都通过才进事务依次查订单状态(582017)→ 团期闸门(589536 / 589501)→ 晚数匹配(582011)→ 已配房晚改自订(582097)。事务内再跑的 582099 / 结构校验只是兜底,不会先于入口触发。因此**结构类错误仍先于订单状态与团期闸门返回**(冻结期团单缺房型得到 582099 而不是 589536);本单对外只改变一点:团单 582099 先于 582016。任一拒绝均在写库之前,无新版本、`room_control_status` 不变。核心订单仍以通用结构校验给码(房数 0 → 582016)。
|
||
- 成功后 `order_main.room_control_status=PENDING_REVIEW`(既有行为),团期成团时定制师不再产生「房型需求 · 待提交」待办。
|
||
|
||
### 2. 订单调整统一提交 `POST /v3/admin/order/{id}/adjustment/submit`
|
||
|
||
**VO**: `AdjustmentSubmitReqVO → AdjustmentSubmitRespVO`(`hl-order-service-v3/src/main/java/com/hulalv/order/adjustment/controller/admin/vo/`)
|
||
|
||
#### 使用场景
|
||
|
||
管理端子订单详情「订单调整」一次性提交各子域改动;本次只涉及 `updates.hotelRequirement`(用房需求完整新版本)与 `updates.vehicleRequirement`(用车需求完整新版本),两者与接口 1 / 接口 3 走同一团期闸门与团单房型间数校验。其它子域(人数 / 日期 / 出行人等)本次不变、省略。
|
||
|
||
#### 入参
|
||
|
||
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||
|---|---|---|---|---|---|
|
||
| `id` | Path | String(Long) | 是 | 订单 ID | — |
|
||
| `updates` | Body | Object | 是 | 至少一个子域非空 | 各子域修改内容 |
|
||
| `updates.hotelRequirement` | Body | `HotelRequirementBodyVO` | 否 | 结构同接口 1 的 `days / specialTags / remark` | 用房需求完整新版本,团单房型间数必填规则同接口 1 |
|
||
| `updates.vehicleRequirement` | Body | `VehicleRequirementBodyVO` | 否 | 结构同接口 3 的 `fleet / specialTags / pickupRequired / dropoffRequired / remark` | 用车需求完整新版本 |
|
||
|
||
#### 出参 `Result<AdjustmentSubmitRespVO>`
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|---|---|---|
|
||
| `data.success` | Boolean | 提交成功恒 `true` |
|
||
|
||
#### 请求示例
|
||
|
||
```json
|
||
{
|
||
"updates": {
|
||
"hotelRequirement": {
|
||
"days": [
|
||
{ "dayNumber": 1, "segments": [ { "candidates": [ { "hotelName": "网关实测酒店", "rooms": [ { "roomCategory": "KING", "roomCount": 1 } ] } ] } ] },
|
||
{ "dayNumber": 2, "segments": [ { "candidates": [ { "hotelName": "网关实测酒店", "rooms": [ { "roomCategory": "TWIN", "roomCount": 1 } ] } ] } ] }
|
||
],
|
||
"remark": "#7149 网关实测 调整入口"
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 响应示例
|
||
|
||
```json
|
||
{ "code": 200, "message": "成功", "success": true, "data": { "success": true } }
|
||
```
|
||
|
||
#### 空数据 / 降级响应
|
||
|
||
`updates` 各子域全空时沿用既有「无有效变更」拒绝;`hotelRequirement` 提交成功但版本号不变(`PENDING_EDIT` 覆盖同版本)属正常,前端以订单详情重新拉取为准。
|
||
|
||
#### 错误响应
|
||
|
||
```json
|
||
{ "code": 589536, "message": "团期已进入物资准备,需求已冻结,请联系团期管理员", "success": false, "data": null }
|
||
```
|
||
|
||
```json
|
||
{ "code": 582099, "message": "团期订单第2晚第1段需填写房型大类与房间数", "success": false, "data": null }
|
||
```
|
||
|
||
#### 业务边界
|
||
|
||
- 调整入口绕过「订单须为定制中」的普通提交闸,但**不绕**团期闸门与团单房型间数校验,行为与接口 1 / 3 一致。
|
||
- 团期冻结期内该入口同样 589536,被打回户例外同接口 1。
|
||
- 拒绝发生在事务内任何写操作之前,其它子域改动一并回滚。
|
||
|
||
### 3. 提交 / 修改用车需求 `PUT /v3/admin/order/{id}/vehicle-requirement`
|
||
|
||
**VO**: `VehicleRequirementReqVO → VehicleRequirementRespVO`(`hl-order-service-v3/src/main/java/com/hulalv/order/requirement/controller/admin/vo/`)
|
||
|
||
#### 使用场景
|
||
|
||
定制师在子订单详情「用车安排」提交或修改用车需求。本次只改团期闸门(放宽 + 冻结 + 打回例外),**不加任何必填**;车型 / 座位联动校验、容量校验、派单展开等既有逻辑不变。
|
||
|
||
#### 入参
|
||
|
||
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||
|---|---|---|---|---|---|
|
||
| `id` | Path | String(Long) | 是 | 订单 ID | — |
|
||
| `fleet` | Body | Array | 是(≥1) | 缺 582021 | 用车明细 |
|
||
| `fleet[].vehicleType` | Body | String | 是 | 车务车型大类 key(582022) | 车型大类 |
|
||
| `fleet[].seats` | Body | Integer | 是 | 该车型可选座位数(582024) | 座位数 |
|
||
| `fleet[].count` | Body | Integer | 是 | >0(582023) | 车辆数 |
|
||
| `specialTags` | Body | String[] | 否 | 字典 `vehicle_special_demand`(582025) | 特殊诉求 |
|
||
| `pickupRequired / dropoffRequired` | Body | Boolean | 否 | — | 接 / 送机 |
|
||
| `remark` | Body | String | 否 | — | 备注 |
|
||
|
||
#### 出参 `Result<VehicleRequirementRespVO>`
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|---|---|---|
|
||
| `data.requirementId` | String | 需求行 ID |
|
||
| `data.version` | Integer | 版本号 |
|
||
| `data.isActive` | Boolean | 是否当前生效版本 |
|
||
| `data.status` | String | 团单恒 `PENDING_REVIEW` |
|
||
| `data.submittedAt` | String | 首提时间 |
|
||
| `data.branchTaken` | String | `INIT_SUBMIT / PENDING_EDIT / DONE_ADJUST` |
|
||
|
||
#### 请求示例
|
||
|
||
```json
|
||
{ "fleet": [ { "vehicleType": "SUV", "seats": 7, "count": 1 } ] }
|
||
```
|
||
|
||
#### 响应示例
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "成功",
|
||
"success": true,
|
||
"data": { "requirementId": "2096504700000000001", "version": 1, "isActive": true, "status": "PENDING_REVIEW", "submittedAt": "2026-09-06 15:46:02", "branchTaken": "INIT_SUBMIT" }
|
||
}
|
||
```
|
||
|
||
#### 空数据 / 降级响应
|
||
|
||
`fleet` 为空返回 582021「用车需求数组不能为空」;车队车型库不可用返回 582091「车队车型库不可用,无法校验座位数选项」(既有降级,本次不变)。
|
||
|
||
#### 错误响应
|
||
|
||
```json
|
||
{ "code": 589536, "message": "团期已进入物资准备,需求已冻结,请联系团期管理员", "success": false, "data": null }
|
||
```
|
||
|
||
其它沿用:589501(团期 `CANCELLED` / 查不到)、582022 / 582024 / 582023 / 582025(车型 / 座位 / 数量 / 诉求校验)。
|
||
|
||
#### 业务边界
|
||
|
||
- 团期闸门与接口 1 完全一致(同一方法),放行 / 冻结 / 打回例外按**用车需求**自身的最新一版判。
|
||
- 车侧不加房型类必填;`fleet` 结构与既有校验不变。
|
||
- 成功后 `order_main.vehicle_control_status=PENDING_REVIEW`(既有行为)。
|
||
|
||
## 四、契约约束与正确调用方式(接口类必写)
|
||
|
||
### ✅ 正确 / ❌ 错误 payload 对照
|
||
|
||
| 场景 | payload 要点 | 结果 |
|
||
|---|---|---|
|
||
| ✅ 团单每晚房型行齐全 | `candidates[0].rooms[]` 每行 `roomCategory` + `roomCount ≥ 1` | 200,`status=PENDING_REVIEW` |
|
||
| ✅ 团单某晚客人自订 | `{ "dayNumber": 2, "customerSelfBooked": true }`,无 `segments` | 200,该晚跳过校验 |
|
||
| ✅ 旧结构团单 | 无 `rooms[]`,段级 `roomCategory` + `roomCount` 齐全 | 200 |
|
||
| ❌ 团单房型行缺 `roomCategory` | `rooms: [ { "roomCount": 1 } ]` | 582099 |
|
||
| ❌ 团单房型行房数为空 / 0 | `rooms: [ { "roomCategory": "KING", "roomCount": 0 } ]` | 582099(PR #7184 起;核心订单仍 582016) |
|
||
| ❌ 团单旧结构缺段级 `roomCategory` | 段级只有 `roomCount`,候选带 `roomTypeId` | 582099 |
|
||
| ❌ 团单「加晚次空白占位」段 | 候选与段全空 | 582099(核心订单该形态仍放行) |
|
||
| ❌ 团期物料准备中提交 / 修改 | 任何合法 payload | 589536(该户最新需求被打回除外) |
|
||
| ❌ 子订单未支付 | 任何 payload | 582017「订单状态不允许提交需求」 |
|
||
|
||
### 切换状态时的必要动作
|
||
|
||
- 团期从招募中推进到物料准备中后,前端应把提需求入口置灰并以 589536 文案提示;管理员打回某户后该户入口恢复一次。
|
||
- 团单弹窗保存前在前端做房型大类必填校验,减少 582099 往返;后端仍以 582099 兜底。
|
||
|
||
## 五、数据库行为(涉及写操作时必写)
|
||
|
||
- 无表结构变更、无 Flyway。
|
||
- 提交成功:`order_hotel_requirement` / `order_vehicle_requirement` 写入新版本(`PENDING_EDIT` 为同版本换行,其它版本 +1),`status=PENDING_REVIEW`;`order_main.room_control_status` / `vehicle_control_status` 回写 `PENDING_REVIEW`(既有行为)。
|
||
- 被拒(589536 / 582099 / 589501 / 结构校验):无任何写入。
|
||
|
||
## 六、边界行为
|
||
|
||
- **团单不再接受「加晚次空白占位」段**:核心订单允许先提交全空的候选 / 段占位,团期子订单的非自订晚一律按缺房型拒绝(582099「第 N 晚第 M 段」);团单每晚要么填齐 `rooms[]`,要么标 `customerSelfBooked=true`。
|
||
- **文案「物资准备」= 团期状态芯片「物料准备中」(`MATERIAL_PREPARING`)**:589536 文案沿用代码里的「物资准备」叫法,与状态枚举文案同义,前端直接展示 `message` 即可。
|
||
- **冻结期打回只给一次重提机会**:重提后最新版变 `PENDING_REVIEW`,再改回到 589536;这是有意设计(改需求须经管理员再次打回)。
|
||
- **自订晚**:`customerSelfBooked=true` 的晚不做房型校验;全团汇总 `requirement-summary` 也整晚跳过(PR #7184 复审补漏),残留 `segments/rooms` 不计入采购分母、不再出「未知」桶——前端标记自订后仍建议清空该晚 `segments`,但后端不依赖它。
|
||
- **未知团期状态**按冻结处理(fail closed),不会误放行。
|
||
- **错误码优先级(2026-09-06 复审更正,以本条为准)**:两条对外入口的可观察顺序都是「结构类校验先于状态类校验」——`PUT …/hotel-requirement` 在进事务前先做 团单 582099 → 通用结构 582098 / 582016 / 582019 / 582020,之后才是 582017 → 589536 / 589501 → 582011 → 582097;`adjustment/submit` 在自身状态边界守卫之后、任何写库与 Feign 之前先做 团单 582099 → 通用结构,团期闸门 589536 / 589501 与晚数 582011 在落库阶段。本单对外**唯一**的优先级变化是团单 582099 先于 582016(两入口一致)。PR #7184 把事务内 `doUpsertHotelRequirement` 的结构校验挪到闸门之后只是内部兜底顺序(供改期减天等内部路径),对外不可观察,核心订单的错误码顺序没有变化。本文早先版本写「结构校验挪到订单状态 / 闸门之后、核心订单也受影响」是把事务内顺序误当成接口整体优先级。
|
||
- **调整入口同口径(PR #7184)**:`adjustment/submit` 对团期子订单同样先做团单房型间数校验,房数为空 / 0 也返回 582099「第 N 晚第 M 段」,不再先出 582016。
|
||
- **全团汇总某晚全团自订则无该晚条目**:`dailyRoomBreakdown` 按 dayNumber 升序但不保证连续,前端逐日表按 dayNumber 对齐、不要按下标。
|
||
- **子订单详情统计同步(PR #7184)**:订单详情 `hotelRequirementBrief.totalRoomCount / roomTypeSummary` 也不再计入自订晚残留段,与全团汇总一致;该晚仍出现在 `days[]` 里,并**新增响应字段** `hotelRequirementBrief.days[].customerSelfBooked`(Boolean,纯新增不破坏契约)供前端解释「段里有房型行但不计入总数」。
|
||
|
||
## 六.5、枚举 / 数据字典(接口出现枚举时必写)
|
||
|
||
### roomCategory(字典 `room_category`)
|
||
|
||
| 值 | 含义 |
|
||
|---|---|
|
||
| STANDARD | 标准间 |
|
||
| SINGLE | 单人间 |
|
||
| TWIN | 双床房 |
|
||
| QUEEN | 大床房 |
|
||
| KING | 特大床房 |
|
||
| SUITE | 套房 |
|
||
| FAMILY | 家庭房 |
|
||
| YURT | 帐篷 / 毡房 |
|
||
| SPECIAL | 特色房 |
|
||
|
||
### 团期状态(`com.hulalv.order.groupbatch.enums.GroupBatchStatus`)
|
||
|
||
| 值 | 芯片文案 | 提 / 改需求 |
|
||
|---|---|---|
|
||
| RECRUITING | 招募中 | 放行 |
|
||
| RESOURCE_PREPARING | 资源准备中 | 放行 |
|
||
| MATERIAL_PREPARING | 物料准备中 | 589536(打回户例外) |
|
||
| PENDING_DEPARTURE | 待出发 | 589536(打回户例外) |
|
||
| TRAVELLING | 出行中 | 589536(打回户例外) |
|
||
| REVIEWING | 核单中 | 589536(打回户例外) |
|
||
| SETTLED | 已结算 | 589536(打回户例外) |
|
||
| CANCELLED | 已取消 | 589501 |
|
||
|
||
### 需求状态(`com.hulalv.order.requirement.enums.RequirementStatus`,`data.status` / `room_control_status`)
|
||
|
||
| 值 | 含义 |
|
||
|---|---|
|
||
| PENDING_REVIEW | 待团期管理员审核(团单提交后) |
|
||
| REJECTED_TO_CONSULTANT | 已打回定制师(冻结期可重提一次) |
|
||
| PENDING / PROCESSING / DONE | 核心订单 / 管理员提交房务后的房务侧状态,本次不变 |
|
||
|
||
## 六.6、修改前后对比(修改/删除类接口必写,新增跳过)
|
||
|
||
### 字段级对比
|
||
|
||
请求无字段增删;`rooms[].roomCategory`、`rooms[].roomCount`(及旧结构段级同名字段)由「选填」改为「团期子订单必填」,核心订单不变。响应新增 `GET /v3/admin/order/{id}`(订单详情)`hotelRequirementBrief.days[].customerSelfBooked`(Boolean,PR #7184)。
|
||
|
||
### 行为级对比
|
||
|
||
| 行为 | 修改前 | 修改后 |
|
||
|---|---|---|
|
||
| 团期子订单提 / 改需求时机 | 团期须为 `RESOURCE_PREPARING`(成团后),否则 589501 | 支付后即可:`RECRUITING / RESOURCE_PREPARING` 放行 |
|
||
| 团期物料准备及之后 | 589501 | 589536(新码,文案明确「已冻结」),最新需求被打回的户可重提一次 |
|
||
| 团单缺房型大类 / 房数 | 放行,全团汇总出现「未知」房型 | 582099 拒绝,零副作用(房数为空 / 0 也是 582099,不再先出 582016;PR #7184) |
|
||
| 自订晚残留段进入全团汇总 | 计入「未知」桶 | 整晚跳过,不计入(PR #7184) |
|
||
| 团单空白占位段 | 放行 | 582099 拒绝 |
|
||
| 用车需求 | 同 589501 闸 | 同新闸门,不加必填 |
|
||
|
||
## 六.7、影响评估(修改/删除类必写)
|
||
|
||
- 破坏向后兼容:**部分**——请求 / 响应结构不变,但团单缺房型或空白占位段的旧调用会从 200 变 582099,招募中的调用从 589501 变 200,物料准备中从 589501 变 589536。
|
||
- 前端是否必须同步上线:**建议同步**——不同步时功能可用但用户会收到 582099 / 589536 提示且入口显示时机不准。
|
||
- 前端需清理的分支:「未成团不显示提需求入口」「物料准备中仍允许提交」「团单空白占位先提交」。
|
||
|
||
## 七、不影响范围(显式声明, 帮前端/QA 缩小排查面)
|
||
|
||
- 核心订单(`productBatchId` 为空)的提需求、房型选填、抢单池、房务配房全部不变。
|
||
- 团期管理员确认 / 打回 / 提交房务(`…/hotel-requirement/reject`、`…/dispatch`、`group-batch/{groupBatchId}/requirement/*`)本次不改;打回后重提的版本号规则不变。
|
||
- `GET /v3/admin/order/group-batch/{groupBatchId}/requirement-summary` 结构不变,只是按本次提交的团单不再出现 `roomCategory="未知"` 项(历史数据仍可能出现)。
|
||
- 网关路由、权限码、表结构均无改动。
|
||
|
||
## 八、测试环境已验证
|
||
|
||
**环境**:TEST 网关 `https://api.test.1814.love:9443`,order-v3 dev-v3 `a52365278` 两实例 2026-09-06 15:43 滚动部署,登录 `admin`(adminId 1001,SUPER_ADMIN,且为两张测试单的定制师),实测 15:44–15:47。
|
||
|
||
| 场景 | 请求 | 结果 |
|
||
|---|---|---|
|
||
| 招募中(`RECRUITING`)子订单 2096412454488612866 提完整房型 | `PUT …/hotel-requirement` | 200,`status=PENDING_REVIEW` |
|
||
| 招募中,第 2 晚房型行缺 `roomCategory` | `PUT …/hotel-requirement` | 582099「团期订单第2晚第1段需填写房型大类与房间数」,DB 无新版本 |
|
||
| 招募中,旧结构段级缺 `roomCategory`(候选带 `roomTypeId`) | `PUT …/hotel-requirement` | 582099,同上 |
|
||
| 资源准备中完整提交 | `PUT …/hotel-requirement` | 200,`version=1 INIT_SUBMIT PENDING_REVIEW`;`order_main.room_control_status=PENDING_REVIEW` |
|
||
| 资源准备中经调整入口改需求 | `POST …/adjustment/submit` | 200,`data.success=true`(同版本 `PENDING_EDIT` 换行) |
|
||
| 第 2 晚 `customerSelfBooked=true` 无段 | `PUT …/hotel-requirement` | 200 |
|
||
| 团期 2089713777065832450 子订单 2096029450184347649 资源准备中提交 | `PUT …/hotel-requirement` | 200 |
|
||
| 团期管理员打回该户 | `POST …/hotel-requirement/reject` | 200,需求行 `REJECTED_TO_CONSULTANT`、`is_active=0` |
|
||
| 团期改为 `MATERIAL_PREPARING` 后被打回户重提 | `PUT …/hotel-requirement` | 200,`version=2 PENDING_REVIEW`(冻结期例外) |
|
||
| 重提后再改 | `PUT …/hotel-requirement` | 589536「团期已进入物资准备,需求已冻结,请联系团期管理员」 |
|
||
| 物料准备中经调整入口改需求 | `POST …/adjustment/submit` | 589536 |
|
||
| 物料准备中提用车需求 | `PUT …/vehicle-requirement` | 589536 |
|
||
|
||
**单测**:`RequirementServiceTest` 244 / `OrderTodoServiceTest` 15 / `RequirementGroupBatchErrorCodeRangeTest` 3 + 5 个 ArchTest(RedLine / MapperBoundary / HouseModuleBoundary / DashboardLayer / LocalCacheVetting)全绿,`BUILD SUCCESS` 396 用例。
|
||
|
||
|
||
---
|
||
|
||
---
|
||
|
||
## 十、相关文档
|
||
|
||
### 第二轮复审返工要点(2026-09-07)
|
||
|
||
本次对外前端变更汇总(同步自 #7210,两文件保持一致):
|
||
|
||
| 项 | 变更 | 前端影响 |
|
||
|---|---|---|
|
||
| ① 打回原因长度 | 512 → 500(`/hotel-requirement/reject`、`/vehicle-requirement/reject` 的 `returnRemark`,`/hotel-requirement/dispatch`、`/vehicle-requirement/dispatch` 的 `dispatchRemark`) | 打回 / 分房备注输入框 `maxlength="500"`;501+ 字返 400 |
|
||
| ② 房务置灰口径 | 改按订单整体判已分房;新增 `disabledReason` 字段「本单尚有挂在历史需求版本上的配房未清理」 | 按 disabledReason 文案直接显示,无需按码分支 |
|
||
|
||
(完整变更详见 #7210 文件的第二轮返工表)
|
||
|
||
|
||
|
||
- 团期模块接口文档 `docs/group/团期模块接口文档-v2.0.html` §0C.11.1(提需求时机)/ §0C.11.2(房型间数必填)/ GB-ADM-011:<https://web.test.1814.love:9443/hl-docs/group/>
|
||
- 团期房务实现方案 `docs/group/团期房务实现方案-v1.0.html` §3.12.1 / §3.12.2
|
||
- 后续工单(本次不做):管理员确认 / 打回改造(M1 / M2)、房务团期看板与按日订房、定制师 ↔ 团期管理员站内会话
|
||
|
||
## 关联 / 联系人
|
||
|
||
### 链接
|
||
|
||
- Issue: <https://git.1814.love:8443/wx/HL/issues/7149>
|
||
- PR: <https://git.1814.love:8443/wx/HL/pulls/7177>
|
||
- 合并提交: `a52365278`(dev-v3)
|
||
|
||
### 联系人
|
||
|
||
- 后端:wx
|
||
- 前端(hl-ui):mmg
|