update: 最终版changelog——产品版本分组(lineId)+产品线详情接口 (PR #129-#137)
这个提交包含在:
父节点
b1e6ab784b
当前提交
6acffd7281
@ -1,17 +1,18 @@
|
||||
# 产品版本分组 + 产品线绑定类型 (PR #129, #131, #132, #133)
|
||||
# 产品版本分组(基于产品线)+ 产品线详情接口 (PR #129-#137)
|
||||
|
||||
> 日期: 2026-04-02 | 服务: hl-product-service | 需重启: 是
|
||||
> 日期: 2026-04-02 | 服务: hl-product-service, hl-mp-service | 需重启: 是
|
||||
|
||||
## 功能概述
|
||||
|
||||
1. **产品版本分组**:同一行程的不同版本(如"轻奢版""高档版")可关联为一组,列表合并为一张卡片,详情页可切换版本
|
||||
2. **产品线绑定产品类型**:创建产品线时指定类型,创建产品时按类型筛选产品线
|
||||
1. **产品版本分组**:同一产品线下的已上架产品自动视为不同版本,列表合并为一张卡片,详情页可切换版本
|
||||
2. **产品线详情接口**:一次请求返回产品线信息 + 所有产品摘要 + 第一个产品完整详情
|
||||
3. **产品线绑定产品类型**:创建产品线时指定类型,创建产品时按类型筛选产品线
|
||||
|
||||
## 核心概念
|
||||
|
||||
- 产品名本身就是版本名(如"呼伦贝尔5天·轻奢版"、"呼伦贝尔5天·高档版")
|
||||
- 同一 `gradeGroupId` 的产品是同行程的不同版本
|
||||
- `gradeGroupId` 为 null = 独立产品,不属于任何版本组
|
||||
- 同一产品线下有 2 个以上已上架产品时,自动返回版本切换选项(`gradeOptions`)
|
||||
- 产品线只有 1 个产品时,表现和之前完全一样
|
||||
|
||||
---
|
||||
|
||||
@ -20,24 +21,22 @@
|
||||
### 1. 产品列表(C端)
|
||||
**接口**: `GET /mp/product/list`
|
||||
|
||||
同一版本组的产品只返回一条,附带所有版本选项。
|
||||
同一产品线的产品只返回一条,附带所有版本选项。
|
||||
|
||||
**新增返回字段**:
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `gradeGroupId` | String | 版本分组ID,null=独立产品 |
|
||||
| `gradeOptions` | Array | 同组所有版本选项,null=独立产品 |
|
||||
| `gradeOptions` | Array | 同产品线版本选项,null=独立产品或仅一个版本 |
|
||||
| `gradeOptions[].productId` | String | 该版本的产品ID |
|
||||
| `gradeOptions[].name` | String | 产品名(即版本名) |
|
||||
| `gradeOptions[].startPrice` | Number | 起步价 |
|
||||
| `gradeOptions[].startPriceLabel` | String | "起" 或 "订金起" |
|
||||
|
||||
**返回示例(有版本组的产品)**:
|
||||
**返回示例(有多版本)**:
|
||||
```json
|
||||
{
|
||||
"productId": "123",
|
||||
"name": "呼伦贝尔5天·轻奢版",
|
||||
"gradeGroupId": "123",
|
||||
"gradeOptions": [
|
||||
{"productId": "123", "name": "呼伦贝尔5天·轻奢版", "startPrice": 3999, "startPriceLabel": "起"},
|
||||
{"productId": "456", "name": "呼伦贝尔5天·高档版", "startPrice": 6999, "startPriceLabel": "起"}
|
||||
@ -45,12 +44,11 @@
|
||||
}
|
||||
```
|
||||
|
||||
**返回示例(独立产品,不受影响)**:
|
||||
**无版本的产品(不受影响)**:
|
||||
```json
|
||||
{
|
||||
"productId": "789",
|
||||
"name": "丽江3天自由行",
|
||||
"gradeGroupId": null,
|
||||
"gradeOptions": null
|
||||
}
|
||||
```
|
||||
@ -58,30 +56,35 @@
|
||||
### 2. 产品详情(C端)
|
||||
**接口**: `GET /mp/product/{productId}`
|
||||
|
||||
product 对象中新增 `gradeGroupId` 和 `gradeOptions`。
|
||||
product 对象中新增 `gradeOptions`(同上,null=无版本切换)。
|
||||
|
||||
**前端切换版本**:用 `gradeOptions` 中其他版本的 `productId` 重新调用此接口。
|
||||
**切换版本方式**: 用 `gradeOptions` 中其他版本的 `productId` 重新调用此接口。
|
||||
|
||||
### 3. 推荐产品列表(C端)
|
||||
**接口**: Feign `GET /internal/mp/product/recommend`
|
||||
同样新增版本字段,同版本组去重。
|
||||
### 3. [新增] 产品线详情
|
||||
**接口**: `GET /mp/product/line/{lineId}`
|
||||
**用途**: 小程序产品线详情页,一次请求加载全部数据
|
||||
**返回结构**:
|
||||
```json
|
||||
{
|
||||
"line": {
|
||||
"lineId": "123",
|
||||
"lineName": "呼伦贝尔亲子游",
|
||||
"productType": "CORE",
|
||||
"productCount": 2
|
||||
},
|
||||
"products": [
|
||||
// 该产品线下所有已上架产品摘要(不去重)
|
||||
{"productId": "123", "name": "轻奢版", "startPrice": 3999, ...},
|
||||
{"productId": "456", "name": "高档版", "startPrice": 6999, ...}
|
||||
],
|
||||
"defaultProduct": {
|
||||
// 第一个产品的完整详情(含行程、酒店、评价等聚合数据)
|
||||
// 结构同 GET /mp/product/{productId} 返回的 product 对象
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 管理端产品列表/详情
|
||||
新增 `gradeGroupId` 字段(不去重,管理端显示所有产品)。
|
||||
|
||||
### 5. [新增] 版本分组查询
|
||||
**接口**: `GET /admin/product/item/grade-groups?lineId=xxx`
|
||||
**用途**: 管理端创建版本产品时,查询已有分组列表
|
||||
**返回**: `[{gradeGroupId, groupName, lineId, products: [{productId, name}]}]`
|
||||
|
||||
### 6. 产品保存
|
||||
**接口**: `POST /admin/product/item/save`
|
||||
**新增请求字段**:
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `gradeGroupId` | Long | 版本分组ID。传`0`=新建分组,传已有ID=加入该组,不传=不分组 |
|
||||
|
||||
### 7. 产品线接口变更
|
||||
### 4. 产品线接口变更
|
||||
**接口**: `GET /admin/product/line/active`
|
||||
**新增参数**: `productType`(可选,CORE/GROUP/CUSTOM/ROUTE)
|
||||
**行为**: 传参时只返回该类型的产品线 + 未绑定类型的产品线
|
||||
@ -91,13 +94,16 @@ product 对象中新增 `gradeGroupId` 和 `gradeOptions`。
|
||||
|
||||
**产品线VO新增字段**: `productType`
|
||||
|
||||
### 5. 已删除接口
|
||||
- `GET /admin/product/item/grade-groups` — 不再需要
|
||||
|
||||
---
|
||||
|
||||
## 前端开发指引
|
||||
|
||||
### 列表页
|
||||
- `gradeOptions != null && gradeOptions.length > 1` 时,显示版本选项
|
||||
- 卡片示例: `[轻奢版 ¥3,999起] [高档版 ¥6,999起]`(用 name + startPrice 展示)
|
||||
- 卡片示例: `[轻奢版 ¥3,999起] [高档版 ¥6,999起]`(用 name + startPrice)
|
||||
- `gradeOptions == null` 的产品照常展示
|
||||
|
||||
### 详情页
|
||||
@ -106,18 +112,22 @@ product 对象中新增 `gradeGroupId` 和 `gradeOptions`。
|
||||
- 点击其他版本 → 用该 productId 重新请求详情
|
||||
- 报价/下单用当前 productId
|
||||
|
||||
### 产品线详情页(新页面)
|
||||
- 调用 `GET /mp/product/line/{lineId}`
|
||||
- `defaultProduct` 直接渲染产品详情
|
||||
- `products` 列表做顶部版本切换tab
|
||||
- 切换版本时调用 `GET /mp/product/{productId}` 获取新详情
|
||||
|
||||
### 管理端-创建产品
|
||||
1. 选择产品类型(CORE/GROUP等)
|
||||
2. 产品线下拉调用 `GET /admin/product/line/active?productType=CORE` 只显示对应类型的线
|
||||
3. 如需创建版本组:`gradeGroupId` 传 `0`(新建组)或传已有组ID(加入组)
|
||||
- 选择产品类型后,产品线下拉调用 `GET /admin/product/line/active?productType=CORE`
|
||||
- 创建产品线时可指定 `productType`
|
||||
|
||||
---
|
||||
|
||||
## DDL(已在本地/测试/正式执行)
|
||||
## DDL
|
||||
```sql
|
||||
-- 产品线加类型
|
||||
-- 产品线加类型(已执行)
|
||||
ALTER TABLE product_line ADD COLUMN product_type VARCHAR(16) DEFAULT NULL AFTER name;
|
||||
|
||||
-- 产品表只保留 grade_group_id(product_grade 和 grade_sort 已删除)
|
||||
-- grade_group_id + idx_grade_group_id 保持不变
|
||||
-- grade_group_id 已删除(已执行)
|
||||
```
|
||||
|
||||
正在加载...
x
在新工单中引用
屏蔽一个用户