docs(v2): 配房/选酒店流程评审11点收口(候选房型富化+段×候选+池内快照+特殊诉求字典)前端对接
这个提交包含在:
父节点
9f5731aabb
当前提交
9e8f405d62
@ -0,0 +1,142 @@
|
|||||||
|
# 【修改·管理后台】配房/选酒店流程评审 11 点收口(候选房型富化 + 段×候选 + 池内快照 + 特殊诉求字典)
|
||||||
|
|
||||||
|
> 涉及 PR:#4126 / #4127 / #4135 / #4136 / #4148 / #4149(hl-order-service-v3,区县另涉 hl-resource-service)
|
||||||
|
> 影响页面:**订单详情 → 调整订单 → 酒店安排**(配房需求表单)+ 其中的**「选择酒店」弹窗**
|
||||||
|
> 状态:已合并 dev-v3、已部署测试服双实例、候选接口已网关 API 实测通过
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚠️ 关键说明(先读)
|
||||||
|
|
||||||
|
1. 这是定制师「提交配房需求」表单 +「选择酒店」弹窗的一轮产品评审收口,共 11 个点,前后端都要改。
|
||||||
|
2. 两处契约变化,前端必改:
|
||||||
|
- **配房需求提交体** `HotelRequirementReqVO.days` 结构升级为「**段 × 候选**」(见 §三-2)。
|
||||||
|
- **选酒店候选接口** `GET /v3/admin/hotel-candidates` 出参**富化**(真实房型/城市/区县/池内,见 §三-1)。
|
||||||
|
3. **房型下拉不再用通用字典**,改由「所选酒店的真实房型」驱动;**不选酒店不能选房型**。
|
||||||
|
4. 金额字段(协议价/标价/预算)均为 **String**(后端 @JsonSerialize),前端按字符串收。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 一、配房需求表单改动
|
||||||
|
|
||||||
|
### 点1 删「当晚备注」
|
||||||
|
- 每晚的「当晚备注(当晚整体安排说明)」**整条去掉**(输入框删除)。
|
||||||
|
- 后端 `DayHotelReq.remark` 字段已移除;行程 Tab 的 `requirementDays[].remark` 也随之废弃(新单恒空,前端别再展示当晚备注)。
|
||||||
|
- **保留**「该酒店备注」(迁为每个候选酒店的备注,见点8 `CandidateHotel.remark`)。
|
||||||
|
|
||||||
|
### 点2 删「城市/区域」输入(纯前端)
|
||||||
|
- 每晚那个「城市/区域(如 拉萨市区)」输入框**删掉**——它本就没进后端,且与「选择酒店」弹窗自带的搜索框重复。
|
||||||
|
|
||||||
|
### 点3 特殊诉求改字典(多选 + 允许自定义)
|
||||||
|
- 「特殊诉求」从自由文本标签改为**绑定字典** `house_special_demand`,前端做**多选**,**仍允许回车加自定义**。
|
||||||
|
- 字典加载:`GET /admin/dict/data/house_special_demand` → `[{dictValue, dictLabel}]`(当前值:安静楼层/高楼层/景观房/无烟房/含早餐/含双早/可加床/可拆分双床/相邻房间/远离电梯,运营可在字典管理增删)。
|
||||||
|
- 提交字段不变,仍是 `specialTags: List<String>`(存字典 value,自定义则存原文)。
|
||||||
|
|
||||||
|
### 点8 酒店支持「段 × 候选」(提交体结构升级,重点)
|
||||||
|
两个**独立**维度(产品确认都要):
|
||||||
|
- **分住**:同一晚住两家(房数相加)—— 一晚有多个 **段(segment)**。
|
||||||
|
- **候选**:定制师对某段提多家心仪酒店,**房控后台择一**回配 —— 一段有多个 **候选(candidate)**。
|
||||||
|
|
||||||
|
UI:
|
||||||
|
- 每晚可「+ 加一段不同酒店(同一晚分住)」= 加 segment(每段独立填 房数/房型/预算/段备注)。
|
||||||
|
- 每段的「酒店」框支持**多选**候选酒店(房控择一);每个候选可填该酒店备注。
|
||||||
|
- 候选酒店会自动进候选接口的「定制师点名」高亮(`isConsultantRecommended`)。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二、选择酒店弹窗 + 房型
|
||||||
|
|
||||||
|
### 点4 协议价按真实房型 / 点6 可用房按真实房型 / 点7 房型按真实酒店
|
||||||
|
- 候选接口现返回每家酒店的**真实房型列表** `roomTypes[]`(来自 resource 价格日历/库存)。
|
||||||
|
- 前端:
|
||||||
|
- **房型下拉**改由所选酒店的 `roomTypes[]` 驱动(`name`/`bedType`/`maxOccupancy`),**不选酒店则房型不可选**;不再用通用 `room_category` 字典。
|
||||||
|
- **协议价**显示所选房型的 `roomTypes[].protocolPrice`(不是酒店级起步价 `protoPrice`)。
|
||||||
|
- **可用房**显示所选房型的 `roomTypes[].available`(+ `inventoryStatus` AVAILABLE/FULL/CLOSED)。
|
||||||
|
- 注:测试酒店需 resource 侧配了价格日历+库存才有 `roomTypes` 数据(无则该酒店 roomTypes 为空/价 null)。
|
||||||
|
|
||||||
|
### 点5 城市 / 点10 区县
|
||||||
|
- 候选项新增 `city`(城市,如 呼伦贝尔市)+ `district`(区/县,如 满洲里市)。
|
||||||
|
- 选酒店列表/候选展示加「城市」「区/县」两列。
|
||||||
|
|
||||||
|
### 点9+11 池内徽章:按行程天数 + 从订单产品快照取
|
||||||
|
- 「池内」徽章 `isPoolMatch` 语义修正为:**该酒店在「订单产品快照」里当天当档(order.tierSeq)的产品酒店池中**。
|
||||||
|
- 按**行程天数**:第1天只标第1天产品行程的酒店,第2天标第2天的。
|
||||||
|
- 从**订单产品快照冻结值**取(非 live 产品配置)——产品下单后被改不影响已下单订单的池内判定。
|
||||||
|
- 前端无需改调用方式,照常按 `dayNumber` 查候选,`isPoolMatch`/`poolMatchBadge` 直接用。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 三、接口契约
|
||||||
|
|
||||||
|
### 1. 候选接口出参(新增字段)
|
||||||
|
`GET /v3/admin/hotel-candidates?orderId=&dayNumber=&roomCategory=&roomCount=&keyword=&limit=`
|
||||||
|
出参 `data.candidates[]`(`HotelCandidateRespVO.Candidate`)**新增**:
|
||||||
|
|
||||||
|
| 字段 | 类型 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| `city` | String | 酒店所在城市(如 呼伦贝尔市) |
|
||||||
|
| `district` | String | 酒店所在区/县(如 满洲里市) |
|
||||||
|
| `roomTypes` | List | 该酒店当日真实房型列表(见下) |
|
||||||
|
|
||||||
|
`roomTypes[]`(`RoomTypeOption`):
|
||||||
|
|
||||||
|
| 字段 | 类型 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| `roomTypeId` | String | 房型 ID |
|
||||||
|
| `name` | String | 房型名称(如 普通标间) |
|
||||||
|
| `bedType` | String | 床型(如 TWIN_BED) |
|
||||||
|
| `maxOccupancy` | Integer | 最大入住人数 |
|
||||||
|
| `available` | Integer | 今日可用房数 |
|
||||||
|
| `stock` | Integer | 总库存 |
|
||||||
|
| `protocolPrice` | String | 协议价(金额字符串) |
|
||||||
|
| `basePrice` | String | 标价 |
|
||||||
|
| `inventoryStatus` | String | AVAILABLE / FULL / CLOSED |
|
||||||
|
|
||||||
|
`isPoolMatch`(既有字段,语义改为按天+快照)、`protoPrice`/`matchedRoomType*`(既有,向后兼容保留)不变。
|
||||||
|
|
||||||
|
### 2. 配房需求提交体(结构升级)
|
||||||
|
`HotelRequirementReqVO`(提交配房需求 / 调整订单 hotelRequirement.days 同构):
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"days": [
|
||||||
|
{
|
||||||
|
"dayNumber": 1,
|
||||||
|
"segments": [ // ← 原 hotels[] 改为 segments[](分住段)
|
||||||
|
{
|
||||||
|
"roomCount": 2,
|
||||||
|
"roomCategory": "TWIN",
|
||||||
|
"budget": "600.00", // 可空(后端反查协议价覆盖)
|
||||||
|
"remark": "段备注",
|
||||||
|
"candidates": [ // ← 候选酒店列表(房控择一)
|
||||||
|
{ "hotelId": 80001, "hotelName": "拉萨西藏宾馆", "remark": "靠湖一侧" },
|
||||||
|
{ "hotelId": 80002, "hotelName": "山景酒店", "remark": "含双早" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"specialTags": ["安静楼层", "含早餐"], // 字典 house_special_demand 的 value(允许自定义)
|
||||||
|
"remark": "整单备注"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **去掉**:`days[].remark`(当晚备注)、`days[].hotels[].source`(死字段)。
|
||||||
|
- 后端兼容旧 `hotels[]` 结构读取(存量订单不报错),但**新提交请用 `segments[].candidates[]`**。
|
||||||
|
|
||||||
|
### 3. 特殊诉求字典
|
||||||
|
`GET /admin/dict/data/house_special_demand` → `data: [{dictValue, dictLabel, ...}]`。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 四、curl 实测(候选接口,2026-06-20 测试服)
|
||||||
|
```
|
||||||
|
GET /v3/admin/hotel-candidates?orderId=2068235380959682562&dayNumber=1&limit=3
|
||||||
|
→ 200
|
||||||
|
data.candidates[0]:
|
||||||
|
hotelName=呼伦贝尔香格里拉大酒店 city=呼伦贝尔市 district=满洲里市 isPoolMatch=true
|
||||||
|
roomTypes=[{name:普通标间, bedType:TWIN_BED, available:20, protocolPrice:"280.00", inventoryStatus:AVAILABLE}, ...]
|
||||||
|
data.candidates[1]: 海拉尔嘉世豪酒店 district=海拉尔区 isPoolMatch=false
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
如对契约/字段有疑问随时找后端(王骁)。
|
||||||
正在加载...
x
在新工单中引用
屏蔽一个用户