docs(changelog): #7925 全团需求汇总房间合计对齐预检判定 + 补房型中文名与需房/已提交户数(修改接口)
changelog-filename-gate / validate (push) Failing after 1s
changelog-filename-gate / validate (push) Failing after 1s
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
这个提交包含在:
@@ -0,0 +1,266 @@
|
|||||||
|
---
|
||||||
|
schema: "hl-changelog/v2"
|
||||||
|
ticket: "7925"
|
||||||
|
title: "全团需求汇总:房间合计只计需房且非打回的户 + 新增需房/已提交户数与房型中文名"
|
||||||
|
consumer: "admin"
|
||||||
|
author: "jw(GIT)"
|
||||||
|
change_type: "修改接口"
|
||||||
|
backend_status: "deployed"
|
||||||
|
gateway_status: "verified"
|
||||||
|
frontend_status: "pending"
|
||||||
|
frontend_owner: "mmg"
|
||||||
|
frontend_ref: ""
|
||||||
|
target_release: ""
|
||||||
|
verified_at: ""
|
||||||
|
status_note: "全团需求汇总 GET /v3/admin/order/group-batch/{groupBatchId}/requirement-summary 有一处行为变更 + 三个纯新增出参。行为:dailyRoomBreakdown 每日房间合计此前把「已改成不需要订房」的户和「被打回重改中」的户也算进去,房数虚高;现在只计 needsHotel=true 且状态非打回的户,与整体确认前的缺失预检口径一致。新增出参 hotelNeededOrderCount(需房户数)、hotelSubmittedOrderCount(需房且已提交的户数,即计入合计的户数)、dailyRoomBreakdown[].rooms[].roomCategoryName(房型中文名,字典无此编码时为 null)。既有字段一个没删没改。户范围保持「在团」口径(含已完成的户),与预检刻意不同,见第四节。后端已合并 dev-v3(20465f21e)并部署 TEST,网关实测通过(工单 #7925 AC-2~AC-5)。"
|
||||||
|
updated_at: "2026-09-20"
|
||||||
|
base: "dev-v3"
|
||||||
|
---
|
||||||
|
|
||||||
|
# order-v3: 全团需求汇总房间合计对齐预检判定 + 补房型中文名与需房/已提交户数
|
||||||
|
|
||||||
|
> **存放目录**: `changelogs-v2/{YYYY-MM}/`(管理后台,二期 order-v3)
|
||||||
|
>
|
||||||
|
> **服务**: hl-order-service-v3 (端口 8086)
|
||||||
|
> **PR**: [#7927](https://git.1814.love:8443/wx/HL/pulls/7927)
|
||||||
|
> **Issue**: [#7925](https://git.1814.love:8443/wx/HL/issues/7925)
|
||||||
|
> **日期**: 2026-09-20
|
||||||
|
> **影响范围**: 团期详情「查看需求」页的全团需求汇总
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚠️ 关键变化
|
||||||
|
|
||||||
|
1. **每日房间合计的数会变小(变准)**:此前把「已改成不需要订房」的户、「被打回正在重改」的户也算进每日合计,房数虚高;现在只算需要订房且非打回的户。
|
||||||
|
2. **新增三个出参**(纯增量,不接入也不影响现有功能):`hotelNeededOrderCount`、`hotelSubmittedOrderCount`、`dailyRoomBreakdown[].rooms[].roomCategoryName`。
|
||||||
|
3. **既有字段全部保留、语义不变**;入参、路径、错误码都没变。
|
||||||
|
4. `roomCategory` 一直是**编码**(如 `STANDARD`),本次只是补了它的中文名字段,编码本身原样返回。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 一、背景
|
||||||
|
|
||||||
|
「查看需求」页的每日房间合计与「整体确认」前的缺失预检各算各的:汇总把全部有效房需求都加起来,预检只认「需要订房且没被打回」的那些。于是页面显示要 8 间、预检却按 5 户算,运营无法判断到底该订几间。本次把汇总的计数口径对齐预检,并补上两个户数字段,让「几户需要订房 / 其中几户已提交」在页面上可见。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二、变更接口清单
|
||||||
|
|
||||||
|
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|
||||||
|
|---|------|------|------|----------|------|
|
||||||
|
| 1 | 全团需求汇总 | GET | `/v3/admin/order/group-batch/{groupBatchId}/requirement-summary` | 修改 | 每日房间合计改为只计需房且非打回的户;新增 3 个出参 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 三、接口详情
|
||||||
|
|
||||||
|
### 1. 全团需求汇总 `GET /v3/admin/order/group-batch/{groupBatchId}/requirement-summary`
|
||||||
|
|
||||||
|
**VO**: `Result<GroupRequirementSummaryRespVO>`
|
||||||
|
|
||||||
|
#### 使用场景
|
||||||
|
|
||||||
|
团期详情「查看需求」页:展示全团逐日要订几间房、大巴座位合计、各户的特殊需求标签。运营据此向酒店/车队报数。
|
||||||
|
|
||||||
|
#### 入参
|
||||||
|
|
||||||
|
本次入参**不变**。
|
||||||
|
|
||||||
|
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||||||
|
|------|------|------|------|------|------|
|
||||||
|
| groupBatchId | Path | Long | ✅ | 团期 ID | 团期不存在返回 589500 |
|
||||||
|
|
||||||
|
#### 出参
|
||||||
|
|
||||||
|
| 字段 | 类型 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| activeOrderCount | Integer | 在团户数(不变) |
|
||||||
|
| hotelRequirementCount | Integer | 有效房需求条数(不变。**注意**:它不看 needsHotel、也不看打回状态,和下面两个户数不是一回事) |
|
||||||
|
| hotelNeededOrderCount | Integer | **新增**。在团户中「需要订房」的户数 |
|
||||||
|
| hotelSubmittedOrderCount | Integer | **新增**。需要订房**且**需求非打回的户数,即真正计入每日合计的户数 |
|
||||||
|
| vehicleRequirementCount | Integer | 有效用车需求条数(不变) |
|
||||||
|
| dailyRoomBreakdown | List | 逐日房间明细(**合计口径本次变更**) |
|
||||||
|
| dailyRoomBreakdown[].dayNumber | Integer | 第几天(不变) |
|
||||||
|
| dailyRoomBreakdown[].rooms[].roomCategory | String | 房型**编码**,如 `STANDARD`(不变) |
|
||||||
|
| dailyRoomBreakdown[].rooms[].roomCategoryName | String | **新增**。房型中文名;字典里没有该编码、或字典不可用时为 `null` |
|
||||||
|
| dailyRoomBreakdown[].rooms[].totalRoomCount | Integer | 该天该房型的房间合计(不变,但数值口径变准) |
|
||||||
|
| vehicleSeatSummary | List | 车型座位合计(不变;`vehicleType` 仍是编码,中文名见 #7937) |
|
||||||
|
| orderSpecialTags | List | 各户特殊需求标签(不变,仍取全部有效需求) |
|
||||||
|
|
||||||
|
#### 请求示例
|
||||||
|
|
||||||
|
```http
|
||||||
|
GET /v3/admin/order/group-batch/2099927193172815873/requirement-summary
|
||||||
|
Authorization: Bearer <token>
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 响应示例
|
||||||
|
|
||||||
|
(测试服真实响应,2026-09-20,5 户各需 1 间标间、住 2 晚)
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"message": "成功",
|
||||||
|
"data": {
|
||||||
|
"activeOrderCount": 5,
|
||||||
|
"hotelRequirementCount": 5,
|
||||||
|
"hotelNeededOrderCount": 5,
|
||||||
|
"hotelSubmittedOrderCount": 5,
|
||||||
|
"vehicleRequirementCount": 1,
|
||||||
|
"dailyRoomBreakdown": [
|
||||||
|
{ "dayNumber": 1, "rooms": [ { "roomCategory": "STANDARD", "roomCategoryName": "标间", "totalRoomCount": 5 } ] },
|
||||||
|
{ "dayNumber": 2, "rooms": [ { "roomCategory": "STANDARD", "roomCategoryName": "标间", "totalRoomCount": 5 } ] }
|
||||||
|
],
|
||||||
|
"vehicleSeatSummary": [ { "vehicleType": "suv", "totalSeats": 5, "totalCount": 1 } ],
|
||||||
|
"orderSpecialTags": []
|
||||||
|
},
|
||||||
|
"success": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 空数据 / 降级响应
|
||||||
|
|
||||||
|
全团都不需要订房时(测试服真实响应,该团 1 户且已置为不需订房):房间相关全为空/0,接口照常 200,且不会去查字典。
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"message": "成功",
|
||||||
|
"data": {
|
||||||
|
"activeOrderCount": 1,
|
||||||
|
"hotelRequirementCount": 0,
|
||||||
|
"hotelNeededOrderCount": 0,
|
||||||
|
"hotelSubmittedOrderCount": 0,
|
||||||
|
"vehicleRequirementCount": 1,
|
||||||
|
"dailyRoomBreakdown": [],
|
||||||
|
"vehicleSeatSummary": [ { "vehicleType": "suv", "totalSeats": 5, "totalCount": 1 } ],
|
||||||
|
"orderSpecialTags": []
|
||||||
|
},
|
||||||
|
"success": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
字典服务不可用或某编码不在字典里时,只有 `roomCategoryName` 为 `null`,`roomCategory` 与房间数照常返回,接口不报错。
|
||||||
|
|
||||||
|
#### 错误响应
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "code": 589507, "message": "无操作权限(当前角色未授予团期权限,或该团期不在您名下)", "data": null, "success": false }
|
||||||
|
```
|
||||||
|
|
||||||
|
| code | 触发条件 |
|
||||||
|
|------|----------|
|
||||||
|
| 589507 | 当前角色没有 `group-batch:view`(本次不变) |
|
||||||
|
| 589500 | 团期不存在(本次不变) |
|
||||||
|
| 401 | 未登录(网关拦截) |
|
||||||
|
|
||||||
|
本次无新增错误码。
|
||||||
|
|
||||||
|
#### 业务边界
|
||||||
|
|
||||||
|
- **计入每日合计的户**:需要订房(`needsHotel=true`)且需求状态非打回(打回态为退回定制师、退回管理员两种)。
|
||||||
|
- **户范围**:与此前一致的「在团」口径,**包含已完成的户**;整体确认前的缺失预检不含已完成的户,两者刻意不同——汇总回答「全团一共要几间」,预检回答「确认前还缺谁」。团内没有已完成的户时,`hotelNeededOrderCount` 与预检检查的户数相同。
|
||||||
|
- `hotelRequirementCount` 是**需求条数**,不看 needsHotel 与打回状态,和两个新户数字段口径不同,不要混用。
|
||||||
|
- `orderSpecialTags` 不受本次过滤影响,仍取全部有效需求。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 四、契约约束与正确调用方式
|
||||||
|
|
||||||
|
| 场景 | 做法 |
|
||||||
|
|------|------|
|
||||||
|
| ✅ 页面显示「几户需要订房 / 其中几户已提交」 | 用 `hotelNeededOrderCount` / `hotelSubmittedOrderCount` |
|
||||||
|
| ✅ 房型显示中文 | 优先 `roomCategoryName`,为 null 时回落显示 `roomCategory` 编码,别显示空白 |
|
||||||
|
| ✅ 与「整体确认」预检对照 | 两者户范围不同(汇总含已完成的户),页面若要并排展示需注明 |
|
||||||
|
| ❌ 把 `hotelRequirementCount` 当作「需要订房的户数」 | 它是需求条数,不看 needsHotel 与打回状态 |
|
||||||
|
| ❌ 前端自己维护房型编码→中文映射 | 会与后端字典漂移,直接用 `roomCategoryName` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 六、边界行为
|
||||||
|
|
||||||
|
- 户需求被打回(退回定制师 / 退回管理员)→ 不计入每日合计,但仍计入 `hotelNeededOrderCount`(它只看需不需要订房)。
|
||||||
|
- 户被改成不需要订房 → 既不计入合计,也不计入两个新户数。
|
||||||
|
- 全团无人需要订房 → `dailyRoomBreakdown` 为空数组、两个新户数为 0,且不查字典。
|
||||||
|
- 房型编码不在字典里 → 该项 `roomCategoryName` 为 null,编码与房间数照常返回(单测 `summary_fillsRoomCategoryNameFromDict` 用 `LOFT` 钉住)。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 六.6、修改前后对比
|
||||||
|
|
||||||
|
### 字段级对比
|
||||||
|
|
||||||
|
| 字段 | 改前 | 改后 |
|
||||||
|
|------|------|------|
|
||||||
|
| `hotelNeededOrderCount` | 无 | 新增,Integer |
|
||||||
|
| `hotelSubmittedOrderCount` | 无 | 新增,Integer |
|
||||||
|
| `dailyRoomBreakdown[].rooms[].roomCategoryName` | 无 | 新增,String,可为 null |
|
||||||
|
| 其余既有字段 | — | 不变(无删除、无改名、无类型变化) |
|
||||||
|
| 入参 / 路径 / 错误码 | — | 不变 |
|
||||||
|
|
||||||
|
### 行为级对比
|
||||||
|
|
||||||
|
| 场景 | 改前 | 改后 |
|
||||||
|
|------|------|------|
|
||||||
|
| 户已改为不需要订房,但历史需求记录还在 | 计入每日合计(房数虚高) | 不计入 |
|
||||||
|
| 户需求被打回、正在重改 | 计入每日合计 | 不计入 |
|
||||||
|
| 需要订房且未被打回的户 | 计入 | 计入(不变) |
|
||||||
|
| 与预检的关系 | 两边计数口径不同 | 「哪份需求算数」已对齐,仅户范围仍按设计不同 |
|
||||||
|
|
||||||
|
## 六.7、影响评估
|
||||||
|
|
||||||
|
- **是否破坏向后兼容**: 字段层面兼容(只增不删);**数值层面**每日房间合计可能变小——这正是本次要修的虚高。
|
||||||
|
- **前端是否必须同步上线**: 否。新字段不接入也不影响现有页面;接入后才能显示户数与房型中文名。
|
||||||
|
- **回滚**: 回滚 PR #7927 即可,无数据变更(只读接口)。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 七、不影响范围
|
||||||
|
|
||||||
|
- **仅影响**: 本接口的每日房间合计口径与三个新增出参。
|
||||||
|
- **零影响**: 整体确认前的缺失预检、整体确认写操作、房务侧订房与分房、用车需求与座位合计、各户特殊需求标签、数据库结构(只读接口,无表变更)。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 八、测试环境已验证
|
||||||
|
|
||||||
|
被测版本:hl-order-service-v3 = dev-v3 `20465f21e`(2026-09-20 09:45 部署,双实例 running)。
|
||||||
|
|
||||||
|
```
|
||||||
|
团期 2099927193172815873(5 户,各 1 间标间 × 2 天)
|
||||||
|
逐日合计 接口 {1:{STANDARD:5}, 2:{STANDARD:5}}
|
||||||
|
手算 {1:{STANDARD:5}, 2:{STANDARD:5}}(逐户取其需求明细相加) ✓
|
||||||
|
hotelNeededOrderCount=5 / hotelSubmittedOrderCount=5,与逐户手算一致 ✓
|
||||||
|
roomCategoryName:STANDARD → 标间 ✓
|
||||||
|
团期 2099919607530762241(1 户,已置为不需订房)
|
||||||
|
dailyRoomBreakdown=[],两个户数均为 0,接口 200 ✓
|
||||||
|
判权(自签 token 按角色打真实网关)
|
||||||
|
团期管理员 GROUP_BATCH_MANAGER → 200;定制师 CUSTOMIZER → 200(#7949 已授码)
|
||||||
|
房务 ROOM_MANAGER / 车务 VEHICLE_MANAGER → 589507;超管 → 200(短路放行) ✓
|
||||||
|
```
|
||||||
|
|
||||||
|
本地:`GroupBatchRequirementSummaryTest` 13/13 通过,含 `summary_countsOnlyHotelNeededAndNonRejected`(六户六形态精确合计)、`summary_fillsRoomCategoryNameFromDict`(字典命中与缺值 null)、`summary_noHotelNeeded_emptyRoomsAndNoDictCall`。
|
||||||
|
|
||||||
|
> 说明:本次逐日合计的「手算」取自各户需求明细接口(`GET /v3/admin/order/{orderId}/adjustment/snapshot` 的 `hotelRequirement.days`,与库内存的是同一份 JSON),因取证机器当时连不上测试库。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 十、相关文档
|
||||||
|
|
||||||
|
- 关联 Issue: [wx/HL#7925](https://git.1814.love:8443/wx/HL/issues/7925)
|
||||||
|
- 关联 PR: [wx/HL#7927](https://git.1814.love:8443/wx/HL/pulls/7927)
|
||||||
|
- 车型编码的同类问题(`vehicleSeatSummary[].vehicleType` 无中文名)见 [wx/HL#7937](https://git.1814.love:8443/wx/HL/issues/7937)
|
||||||
|
|
||||||
|
## 关联 / 联系人
|
||||||
|
|
||||||
|
### 链接
|
||||||
|
|
||||||
|
- **Issue**: [#7925](https://git.1814.love:8443/wx/HL/issues/7925)
|
||||||
|
- **PR**: [#7927](https://git.1814.love:8443/wx/HL/pulls/7927)
|
||||||
|
- **Merge commit**: [20465f21e](https://git.1814.love:8443/wx/HL/commit/20465f21e)
|
||||||
|
|
||||||
|
### 联系人
|
||||||
|
|
||||||
|
- **后端负责人**: @jw
|
||||||
|
- **前端负责人**: @mmg
|
||||||
在新工单中引用
屏蔽一个用户