docs: 算价/档位/定金系列变更通知 (PR #718/#720/#722/#724)
这个提交包含在:
父节点
f284e37955
当前提交
4e02058aff
@ -0,0 +1,215 @@
|
||||
# 算价/档位/定金系列变更
|
||||
|
||||
> **服务**: 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 |
|
||||
正在加载...
x
在新工单中引用
屏蔽一个用户