# 酒店价格日历「设置价格」弹窗（① 协议价回显·前端 ② 库存可空=不限·前后端就位）

> 变更类型：① 📖 前端 bug（后端已返协议价）② 📖 前端 + ⚙️ 后端已就位（库存硬扣已开）
> 端类型：管理后台（资源·酒店·房型价格日历「设置价格」弹窗）
> 日期：2026-06-25 ｜ 工单/PR：无（前端 UX/配置，走 changelog）｜ 服务：hl-resource-service
> 关联：配房硬扣库存验收时发现。本日已开启 `hotel.stock.enabled=true`（测试服），配房真实扣减/释放已生效。

---

## ① 协议价没回显（前端 bug，后端已返）

**现象**：点已有价格的日期打开「设置价格」弹窗，协议价框是空的「请输入」，没带出该日已存在的协议价。

**根因（API 实证）**：`GET /admin/hotel/room-type/{roomTypeId}/prices?year&month` **已返回每日协议价**。实测 海拉尔海棠·精品标间 2026-06-26 返回 `protocolPrice = 330.00`、`stock=10`、`stockUsed=0`、`status=AVAILABLE`、顶层 `stockEnabled=true`。是前端没把已查到的值预填进弹窗。

**前端动作**：打开「设置价格」弹窗时，从已加载的日历数据 `prices[]` 里取该日期那条 `PriceCalendarDayVO`，用其 `protocolPrice` 预填「协议价」输入框（同样可预填 `stock`/`status`/`remark`）。

> ⚠️ **wx 2026-06-25 复测:协议价仍未回显**——后端再次确认 `getPriceCalendar` 返了 `protocolPrice`（实测海拉尔海棠 2026-06-26 返 330.00），请前端务必把弹窗打开时的预填补上。

## ② 库存可留空 = 不限制库存（后端已就位，前端放开必填 + null 展示）

**诉求**：库存字段允许留空（null），语义 = 该房型该日**不限库存**（不卡上限，永远可配）。

**后端现状（已就位，无需改）**：
- 表 `room_price_calendar.stock` 本就 `DEFAULT NULL COMMENT 'NULL=unlimited'`；请求 DTO `PriceCalendarSetRequest.stock` 无 `@NotNull`（只 `@Min(0)`，允许 null）。
- 扣减 SQL `(stock IS NULL OR stock - stock_used >= ?)` —— stock=null 时跳过上限校验只累加 `stock_used`；`isAvailable` 在 stock=null 时直接返可用。
- 库存硬扣总开关 `hotel.stock.enabled` 已于本日设为 **true**（原默认 false=不扣），配房真实扣减/释放已生效（实测配 1 间 available 20→19、删配房 19→20 还原）。

**前端动作**：
- 「库存」输入框设为**可选/可留空**（去掉必填）。
- 留空提交时**不传 stock 字段或传 null**（= 该日不限库存）。
- 回显时若 `stock=null`，显示为「不限制」或留空（别显示 0）。
- 可用顶层 `stockEnabled` 决定是否展示库存相关交互（false 时库存管控关闭）。

**后端缺口已修并验证(工单 #4392)**:`batchSetPrices` 原对**已有记录**传 `stock=null` 是「保留原值」、改不回不限。后端已加 `unlimitedStock` Boolean——前端把已设库存的日期改回「不限」时传 `unlimitedStock=true`(后端即显式 `stock=null`);老逻辑不传该字段行为不变。**✅ 已部署测试服 + live 实测通过,最终契约见同目录 `26_价格日历_库存改回不限_写侧unlimitedStock最终契约_前端_管理后台.md`**。

## ③ 配房后库存「看着没变」——其实减的是占用/余量,不是总库存(前端补显示)

**现象(wx 复测)**:配了 1 间房后,价格日历「设置价格」弹窗里「库存」还是 10,以为没扣。

**真相(API + DB 实证)**:配房硬扣减的是**占用量**,不是总容量——
- `stock`(总库存/容量)= 10:在弹窗里设的总量,**配房不改它**(酒店有 10 间,卖 1 间总数还是 10)。
- `stockUsed`(已占用)配房后 **0 → 1**;`available`(可用余量)= `stock - stockUsed` = **10 → 9**。
- 实证 海拉尔海棠·标准间 2026-06-30 配 1 间:DB `stock_used=1`、候选接口 `available=9`、扣减日志 `resource_success=1`。

**前端动作**:`GET /admin/hotel-candidates` 候选列表「余 N / 可用房」列已是 `available`(配房后实时,现显示余 9)——这是看占用的地方。价格日历「设置价格」弹窗只显示总量 `stock` 易误解,**建议弹窗里同时显示「已占用 `stockUsed` · 余 `stock-stockUsed`」**(`getPriceCalendar` 的 `PriceCalendarDayVO` 已返 `stock`+`stockUsed`,数据现成,无需后端改),省得每次误以为没扣。

---

## 说明
- ① 后端无改动(GET 早返 `protocolPrice`),纯前端预填;**复测仍未生效,优先落地**。
- ② 后端扣减/约束/schema 已就位 + 硬扣开关已开;前端放开库存必填 + null 展示「不限」;「已有记录切回不限」缺口后端 #4392 修复中(传 `unlimitedStock=true`)。
- ③ 配房扣的是 `stockUsed`/`available`(非总 `stock`),前端弹窗补显占用/余即不再误解;后端 `getPriceCalendar` 已返这两个字段,无需改。
