216 行
6.6 KiB
Markdown
216 行
6.6 KiB
Markdown
# 算价/档位/定金系列变更
|
||
|
||
> **服务**: hl-product-service-v2 (端口 8083)
|
||
> **PR**: #718, #720, #722, #724
|
||
> **日期**: 2026-04-17
|
||
> **影响范围**: 小程序算价、管理端算价、管理端下单产品选择、小程序档位对比
|
||
|
||
---
|
||
|
||
## 一、变更总览
|
||
|
||
| # | 主题 | PR |
|
||
|---|------|----|
|
||
| 1 | 固定定金算价按总人头 × 单价 | #718 |
|
||
| 2 | 管理端下单产品选择列表补档位 + 新增档位下拉接口 | #720 |
|
||
| 3 | 算价接口补全4类人员单价/小计(成人/儿童/小童/幼童) | #722 |
|
||
| 4 | 小程序档位对比响应补充档位名称 tierName | #724 |
|
||
|
||
---
|
||
|
||
## 二、变更接口清单
|
||
|
||
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|
||
|---|------|------|------|---------|------|
|
||
| 1 | 小程序算价 | POST | `/mp/product/quote` | 响应字段语义 + 新增字段 | 固定定金按总人头×单价;新增4类人员单价/小计 |
|
||
| 2 | 管理端算价 | POST | `/admin/product/item/quote` | 响应新增字段 | 新增4类人员单价/小计 |
|
||
| 3 | 商品选择列表 | GET | `/admin/product/item/simple-list` | 响应新增字段 | 新增 `tiers` 档位数组 |
|
||
| 4 | 产品档位下拉 | GET | `/admin/product/item/{productId}/tiers` | **新增接口** | 下单选档位用 |
|
||
| 5 | 小程序档位对比 | GET | `/mp/product/{id}/tier-compare` | 响应新增字段 | 每组新增 `tierName` |
|
||
|
||
---
|
||
|
||
## 三、接口详情
|
||
|
||
### 1. 小程序算价 `POST /mp/product/quote`
|
||
|
||
**响应完整字段**(新增 4 类人员细分):
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| `adultUnitPrice` | BigDecimal | 成人单价 |
|
||
| `childUnitPrice` | BigDecimal | 儿童单价 |
|
||
| **`toddlerUnitPrice`** | BigDecimal | 🆕 小童单价 = max(儿童价 + 小童优惠额, 0) |
|
||
| **`infantUnitPrice`** | BigDecimal | 🆕 幼童单价(0=免费) |
|
||
| `totalAdultPrice` | BigDecimal | 成人小计 |
|
||
| `totalChildPrice` | BigDecimal | 儿童小计 |
|
||
| **`totalToddlerPrice`** | BigDecimal | 🆕 小童小计 |
|
||
| **`totalInfantPrice`** | BigDecimal | 🆕 幼童小计 |
|
||
| `grandTotal` | BigDecimal | 总价(4类小计之和,**旧版只含成人+儿童**) |
|
||
| `paymentType` | String | `FULL` / `DEPOSIT` |
|
||
| `depositRatio` | Integer | 订金比例(%),仅比例定金 |
|
||
| `depositAmount` | BigDecimal | 订金金额(⚠️ 固定定金语义变更见下方) |
|
||
| `balanceAmount` | BigDecimal | 尾款金额 |
|
||
|
||
**⚠️ 固定定金算法变更(#718)**:
|
||
|
||
产品设置"订金固定额"时,之前返回的 `depositAmount` 是单人额度(不随人数变),导致前端显示与实际收款不符。
|
||
|
||
- **旧**:`depositAmount = product.depositAmount`
|
||
- **新**:`depositAmount = product.depositAmount × (adultCount + childCount + toddlerCount + infantCount)`
|
||
- 若乘出金额 > `grandTotal`,取 `grandTotal` 兜底(防止 balance 为负)
|
||
- 比例定金逻辑**不变**(仍按 `grandTotal × ratio%`)
|
||
|
||
**示例**(固定定金 500/人,2成人+1儿童+1幼童,grandTotal=13498):
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"data": {
|
||
"adultUnitPrice": 4999.00,
|
||
"childUnitPrice": 3500.00,
|
||
"toddlerUnitPrice": 0,
|
||
"infantUnitPrice": 0,
|
||
"totalAdultPrice": 9998.00,
|
||
"totalChildPrice": 3500.00,
|
||
"totalToddlerPrice": 0,
|
||
"totalInfantPrice": 0,
|
||
"grandTotal": 13498.00,
|
||
"paymentType": "DEPOSIT",
|
||
"depositAmount": 2000.00, // 500 × 4人
|
||
"balanceAmount": 11498.00
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 2. 管理端算价 `POST /admin/product/item/quote`
|
||
|
||
响应新增字段与小程序端一致(`toddlerUnitPrice` / `infantUnitPrice` / `totalToddlerPrice` / `totalInfantPrice`),`grandTotal` 同步包含 4 类。
|
||
|
||
---
|
||
|
||
### 3. 商品选择列表 `GET /admin/product/item/simple-list`
|
||
|
||
**请求参数**(无变化):
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|------|------|------|------|
|
||
| productType | String | 否 | CORE / GROUP / CUSTOM |
|
||
| keyword | String | 否 | 名称/编号模糊 |
|
||
| pageNo / pageSize | Integer | 是 | 分页 |
|
||
|
||
**响应新增字段**:
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| **`tiers`** | Array | 🆕 档位列表(tierSeq / tierName / tierDescription) |
|
||
|
||
**响应示例**:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"data": {
|
||
"records": [
|
||
{
|
||
"productId": 2043246204711550977,
|
||
"productNo": "C260409001",
|
||
"name": "额吉的故乡·亲子版",
|
||
"tripDays": 6,
|
||
"lineName": "草原环线",
|
||
"tiers": [
|
||
{"tierSeq": 1, "tierName": "标准档", "tierDescription": "三星酒店"},
|
||
{"tierSeq": 2, "tierName": "豪华档", "tierDescription": "四星酒店升级"}
|
||
]
|
||
}
|
||
],
|
||
"total": 10,
|
||
"page": 1,
|
||
"pageSize": 50
|
||
}
|
||
}
|
||
```
|
||
|
||
**使用场景**:下单搜索产品时,前端直接展示"有几档/具体档位",避免再次请求。
|
||
|
||
---
|
||
|
||
### 4. 产品档位下拉 `GET /admin/product/item/{productId}/tiers` 🆕
|
||
|
||
**场景**:下单弹窗内选档位用。算价接口需要 `tierSeq` 参数,前端必须先让用户选档位。
|
||
|
||
**请求**:路径参数 `productId`
|
||
|
||
**响应**:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"data": [
|
||
{"tierSeq": 1, "tierName": "标准档", "tierDescription": "三星酒店"},
|
||
{"tierSeq": 2, "tierName": "豪华档", "tierDescription": "四星酒店升级"}
|
||
]
|
||
}
|
||
```
|
||
|
||
**异常**:产品不存在 → `code=404`,`message="产品不存在: xxx"`
|
||
|
||
---
|
||
|
||
### 5. 小程序档位对比 `GET /mp/product/{id}/tier-compare`
|
||
|
||
**响应变化**:`tiers[].tierName` 🆕 新增字段。
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"data": {
|
||
"tiers": [
|
||
{
|
||
"tierSeq": 1,
|
||
"tierName": "标准档", // 🆕
|
||
"hotels": [...]
|
||
},
|
||
{
|
||
"tierSeq": 2,
|
||
"tierName": "豪华档", // 🆕
|
||
"hotels": [...]
|
||
}
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 四、前端适配指南
|
||
|
||
### 小程序端
|
||
1. **算价展示**:渲染 4 类人员的单价和小计;固定定金产品场景下 `depositAmount` 现在会随人数变化
|
||
2. **档位对比页**:用 `tiers[].tierName` 作为卡片标题(此前只能显示"档位1"之类)
|
||
|
||
### 管理端
|
||
1. **下单产品选择弹窗**:`simple-list` 响应里直接拿 `tiers` 展示档位数;选中产品后用 `GET /{productId}/tiers` 渲染档位下拉
|
||
2. **算价展示**:渲染 4 类人员单价/小计
|
||
|
||
---
|
||
|
||
## 五、重启提示
|
||
|
||
**需要重启的服务**:`hl-product-service-v2`(端口 8083)
|
||
|
||
不涉及 DB DDL,仅代码变更;字段注释有更新(`deposit_amount` COMMENT),但不影响运行时。
|
||
|
||
---
|
||
|
||
## 六、关联 Issue/PR
|
||
|
||
| Issue | PR | 主题 |
|
||
|-------|-----|------|
|
||
| #717 | #718 | 固定定金按人数计算 |
|
||
| #719 | #720 | simple-list 补档位 + 档位下拉接口 |
|
||
| #721 | #722 | 算价补全 4 类人员单价 |
|
||
| #723 | #724 | 档位对比补 tierName |
|