新增 管理端产品详情 档位起步价与Step5模板展开字段 (#763)

这个提交包含在:
API Changelog Bot 2026-04-17 19:00:14 +08:00
父节点 eae2f907eb
当前提交 072444e473

查看文件

@ -0,0 +1,123 @@
# 管理端产品详情 扩展 档位起步价 + Step5 模板展开字段
- **日期**: 2026-04-17
- **服务**: hl-product-service-v2端口 8083
- **PR**: https://git.1814.love:8443/wx/HL/pulls/763
- **Issue**: https://git.1814.love:8443/wx/HL/issues/760
- **类型**: feat非破坏性扩展,纯字段新增
- **影响**: 管理端产品编辑/查看页可直接拿到起步价与 Step5 补充模板展开内容,无需二次查模板接口
## 变更类型
**非破坏性扩展**:对已有接口 `GET /admin/product/item/{id}` 的响应体新增若干字段。
- 所有老字段不变、含义不变、类型不变
- 旧前端客户端忽略新字段即可继续运行
- 无需迁移
## 受影响接口
### `GET /admin/product/item/{id}`
管理端产品详情接口。**签名与请求参数不变**。响应 VO `ProductDetailRespVO` 新增以下字段。
## 新增字段清单
### Step4 价格/班期 区块3 个字段)
| 字段 | 类型 | 含义 | 可能为 null 的情况 |
|------|------|------|-------------------|
| `startPrice` | BigDecimal | 起步价(未来可售最低成人售价) | 没有未来可售价格日历时为 `null` |
| `tierPrices` | `List<TierPriceInfo>` | 各档位起步价(管理端即使单档产品也会返回) | 全部档位价格已过期时为 `[]`(空数组,不是 null |
| `priceCalendars` | `List<PriceCalendarRespVO>` | 价格日历全量回显(含已过期、含零价,不做过滤) | 从未配置价格日历时为 `[]` |
> **管理端 vs 小程序端**:小程序端通常会过滤掉过期与零价,管理端此处返回全量,方便后台编辑/校对。
### Step5 补充信息 区块5 个字段,模板 ID 自动展开)
前端无需再发 GET 模板详情请求,后端已根据 `supplement.xxxTemplateId` / `supplement.xxxId` 展开内容:
| 字段 | 类型 | 含义 | 展开自 | 可能为 null 的情况 |
|------|------|------|--------|-------------------|
| `guaranteeItems` | Object/Array透传 JSON | 行程保障项 | `supplement.guaranteeTemplateId` 对应模板的 `items` JSON | `guaranteeTemplateId` 为 null 或模板不存在时为 `null` |
| `safetyItems` | Object/Array透传 JSON | 安全保障项 | `supplement.safetyTemplateId` 对应模板的 `items` JSON | `safetyTemplateId` 为 null 或模板不存在时为 `null` |
| `faqItems` | Object/Array透传 JSON | FAQ 问答 | `supplement.faqTemplateId` 对应模板的 `items` JSON | `faqTemplateId` 为 null 或模板不存在时为 `null` |
| `bookingTermsContent` | String | 预订条款内容(富文本) | `supplement.bookingTermsId` 对应的 `content` | `bookingTermsId` 为 null 或记录不存在时为 `null` |
| `warmTipsContent` | String | 温馨提示内容(富文本) | `supplement.warmTipsId` 对应的 `content` | `warmTipsId` 为 null 或记录不存在时为 `null` |
> **设计原则**:若对应 ID 为 null,后端不会查询无意义的数据,直接回空。
## 内部类结构:`TierPriceInfo`
`tierPrices` 数组的元素结构:
```json
{
"tierSeq": 1,
"tierName": "标准档",
"tierDescription": "标间 / 四人桌",
"startPrice": 2980.00
}
```
| 字段 | 类型 | 说明 |
|------|------|------|
| `tierSeq` | Integer | 档位序号1、2、3… |
| `tierName` | String | 档位名称 |
| `tierDescription` | String | 档位描述(房型/餐标等) |
| `startPrice` | BigDecimal | 该档位未来可售最低成人售价 |
## 响应示例(节选,只展示新增部分)
```json
{
"code": 200,
"data": {
"productId": 1001,
"name": "呼伦贝尔6日游",
"startPrice": 2980.00,
"tierPrices": [
{ "tierSeq": 1, "tierName": "标准档", "tierDescription": "标间", "startPrice": 2980.00 },
{ "tierSeq": 2, "tierName": "豪华档", "tierDescription": "大床房", "startPrice": 3480.00 }
],
"priceCalendars": [
{ "date": "2026-05-01", "tierSeq": 1, "adultPrice": 2980.00, "childPrice": 1980.00, "stock": 20 }
],
"supplement": {
"guaranteeTemplateId": 11,
"safetyTemplateId": 12,
"faqTemplateId": 13,
"bookingTermsId": 21,
"warmTipsId": 22
},
"guaranteeItems": [ { "title": "全程WIFI", "desc": "..." } ],
"safetyItems": [ { "title": "随车医药箱", "desc": "..." } ],
"faqItems": [ { "q": "可以加床吗?", "a": "可以,需付费" } ],
"bookingTermsContent": "<p>下单后 24 小时内完成支付...</p>",
"warmTipsContent": "<p>请携带身份证原件...</p>"
}
}
```
## 使用建议
| 场景 | 推荐字段 |
|------|---------|
| 列表页/卡片展示"起步价¥xxx" | `startPrice` |
| 编辑页档位 tab 切换展示各档起价 | `tierPrices` |
| 价格日历编辑/核对(含过期、含零价) | `priceCalendars` |
| Step5 预览页面渲染"行程保障/安全保障/FAQ" | `guaranteeItems` / `safetyItems` / `faqItems` |
| Step5 预览页面渲染"预订条款/温馨提示"富文本 | `bookingTermsContent` / `warmTipsContent` |
> 编辑模板 ID 选择时仍然使用 `supplement.xxxTemplateId` / `supplement.xxxId` 字段;本次新增的展开字段仅用于展示。
## 迁移建议
**无需迁移**。纯新增字段,老字段与老行为完全保持。
## 后端需重启的服务
- **hl-product-service-v2**(端口 8083
拉最新 `dev` 分支后重启该服务即可生效,其它服务不受影响。