diff --git a/changelogs-v2/2026-06/20_配房选酒店流程评审11点_候选房型富化+段候选+池内快照+特殊诉求字典-修改接口-管理后台.md b/changelogs-v2/2026-06/20_配房选酒店流程评审11点_候选房型富化+段候选+池内快照+特殊诉求字典-修改接口-管理后台.md new file mode 100644 index 0000000..50876ec --- /dev/null +++ b/changelogs-v2/2026-06/20_配房选酒店流程评审11点_候选房型富化+段候选+池内快照+特殊诉求字典-修改接口-管理后台.md @@ -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`(存字典 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 +``` + +--- + +如对契约/字段有疑问随时找后端(王骁)。