From d5ddaed89aaf4b00ee5571acf9c43395266ace8c Mon Sep 17 00:00:00 2001 From: API Changelog Bot Date: Thu, 2 Apr 2026 14:30:28 +0800 Subject: [PATCH] =?UTF-8?q?update:=20=E4=BA=A7=E5=93=81=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=88=86=E7=BB=84+=E4=BA=A7=E5=93=81=E7=BA=BF=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=20=E6=9C=80=E7=BB=88=E7=89=88changelog=20(PR=20#129-#?= =?UTF-8?q?133)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- changelogs/2026-04/0402-product-grade.md | 133 +++++++++++------------ 1 file changed, 64 insertions(+), 69 deletions(-) diff --git a/changelogs/2026-04/0402-product-grade.md b/changelogs/2026-04/0402-product-grade.md index b42ac7e..d49556a 100644 --- a/changelogs/2026-04/0402-product-grade.md +++ b/changelogs/2026-04/0402-product-grade.md @@ -1,128 +1,123 @@ -# 产品等级功能 (PR #129, #131, #132) +# 产品版本分组 + 产品线绑定类型 (PR #129, #131, #132, #133) > 日期: 2026-04-02 | 服务: hl-product-service | 需重启: 是 -## 新增字典 +## 功能概述 -等级数据通过 `sys_dict` 管理,字典类型:`product_grade` +1. **产品版本分组**:同一行程的不同版本(如"轻奢版""高档版")可关联为一组,列表合并为一张卡片,详情页可切换版本 +2. **产品线绑定产品类型**:创建产品线时指定类型,创建产品时按类型筛选产品线 -| dict_value | dict_label | sort_order | -|-----------|-----------|-----------| -| LIGHT_LUXURY | 轻奢 | 1 | -| HIGH_END | 高档 | 2 | +## 核心概念 -**前端获取方式**:调用 `GET /dict/all` 或 `GET /admin/dict/data/product_grade` 即可获取等级选项列表。后续新增等级(如"经济"、"至尊")由运营在字典管理中添加,无需改代码。 +- 产品名本身就是版本名(如"呼伦贝尔5天·轻奢版"、"呼伦贝尔5天·高档版") +- 同一 `gradeGroupId` 的产品是同行程的不同版本 +- `gradeGroupId` 为 null = 独立产品,不属于任何版本组 -## 新增功能 - -### 产品等级分组 -同一行程的不同档次(如轻奢版、高档版)可以关联为一组,小程序列表页合并为一张卡片,详情页可切换等级。 +--- ## 接口变更 -### 1. 产品列表接口(C端) +### 1. 产品列表(C端) **接口**: `GET /mp/product/list` -**变更类型**: 返回字段新增 -列表中同等级分组的产品只返回一条(主等级),附带所有等级选项。 +同一版本组的产品只返回一条,附带所有版本选项。 **新增返回字段**: | 字段 | 类型 | 说明 | |------|------|------| -| `productGrade` | String | 产品等级编码,null=无等级。值: `LIGHT_LUXURY`=轻奢, `HIGH_END`=高档 | -| `productGradeLabel` | String | 等级中文标签,如"轻奢" | -| `gradeGroupId` | String | 等级分组ID,null=独立产品 | -| `gradeOptions` | Array | 同组所有等级选项(含自己),null=无等级 | -| `gradeOptions[].productId` | String | 该等级对应的产品ID | -| `gradeOptions[].productGrade` | String | 等级编码 | -| `gradeOptions[].productGradeLabel` | String | 等级中文 | -| `gradeOptions[].startPrice` | Number | 该等级起步价 | +| `gradeGroupId` | String | 版本分组ID,null=独立产品 | +| `gradeOptions` | Array | 同组所有版本选项,null=独立产品 | +| `gradeOptions[].productId` | String | 该版本的产品ID | +| `gradeOptions[].name` | String | 产品名(即版本名) | +| `gradeOptions[].startPrice` | Number | 起步价 | | `gradeOptions[].startPriceLabel` | String | "起" 或 "订金起" | -**返回示例(有等级的产品)**: +**返回示例(有版本组的产品)**: ```json { "productId": "123", - "name": "呼伦贝尔5天亲子深度游", - "productGrade": "LIGHT_LUXURY", - "productGradeLabel": "轻奢", + "name": "呼伦贝尔5天·轻奢版", "gradeGroupId": "123", "gradeOptions": [ - {"productId": "123", "productGrade": "LIGHT_LUXURY", "productGradeLabel": "轻奢", "startPrice": 3999, "startPriceLabel": "起"}, - {"productId": "456", "productGrade": "HIGH_END", "productGradeLabel": "高档", "startPrice": 6999, "startPriceLabel": "起"} + {"productId": "123", "name": "呼伦贝尔5天·轻奢版", "startPrice": 3999, "startPriceLabel": "起"}, + {"productId": "456", "name": "呼伦贝尔5天·高档版", "startPrice": 6999, "startPriceLabel": "起"} ] } ``` -**返回示例(无等级的产品,不受影响)**: +**返回示例(独立产品,不受影响)**: ```json { "productId": "789", "name": "丽江3天自由行", - "productGrade": null, "gradeGroupId": null, "gradeOptions": null } ``` -### 2. 产品详情接口(C端) +### 2. 产品详情(C端) **接口**: `GET /mp/product/{productId}` -**变更类型**: 返回字段新增 -product 对象中新增相同的等级字段(productGrade, productGradeLabel, gradeGroupId, gradeOptions)。 +product 对象中新增 `gradeGroupId` 和 `gradeOptions`。 -**前端切换等级的方式**: 用 `gradeOptions` 中其他等级的 `productId` 重新调用此接口即可,无需新接口。 +**前端切换版本**:用 `gradeOptions` 中其他版本的 `productId` 重新调用此接口。 ### 3. 推荐产品列表(C端) -**接口**: `GET /mp/product/recommend`(内部Feign) -同样新增等级字段,同等级分组去重。 +**接口**: Feign `GET /internal/mp/product/recommend` +同样新增版本字段,同版本组去重。 -### 4. 管理端产品列表 -**接口**: `GET /admin/product/item/list` -新增字段: `productGrade`, `productGradeLabel`, `gradeGroupId`(不含gradeOptions,管理端不去重) +### 4. 管理端产品列表/详情 +新增 `gradeGroupId` 字段(不去重,管理端显示所有产品)。 -### 5. 管理端产品详情 -**接口**: `GET /admin/product/item/{productId}` -新增字段同C端详情。 +### 5. [新增] 版本分组查询 +**接口**: `GET /admin/product/item/grade-groups?lineId=xxx` +**用途**: 管理端创建版本产品时,查询已有分组列表 +**返回**: `[{gradeGroupId, groupName, lineId, products: [{productId, name}]}]` -### 6. [新增] 等级分组查询 -**接口**: `GET /admin/product/item/grade-groups` -**参数**: `lineId`(可选,按产品线筛选) -**用途**: 管理端创建等级产品时,查询已有等级分组列表用于关联 -**返回**: 分组列表,每组含 gradeGroupId、groupName、products[] - -### 7. 产品保存接口 +### 6. 产品保存 **接口**: `POST /admin/product/item/save` **新增请求字段**: | 字段 | 类型 | 说明 | |------|------|------| -| `productGrade` | String | 产品等级,不传=无等级 | -| `gradeGroupId` | Long | 等级分组ID,关联已有组时传入 | -| `gradeSort` | Integer | 等级排序,越小越前 | +| `gradeGroupId` | Long | 版本分组ID。传`0`=新建分组,传已有ID=加入该组,不传=不分组 | -**校验规则**: -- 同一等级分组内不能有重复等级 -- 同一等级分组内的产品必须在同一产品线 -- 同一产品线只能包含同一类型的产品 +### 7. 产品线接口变更 +**接口**: `GET /admin/product/line/active` +**新增参数**: `productType`(可选,CORE/GROUP/CUSTOM/ROUTE) +**行为**: 传参时只返回该类型的产品线 + 未绑定类型的产品线 + +**接口**: `POST /admin/product/line`(创建产品线) +**新增请求字段**: `productType`(可选,绑定产品类型) + +**产品线VO新增字段**: `productType` + +--- ## 前端开发指引 ### 列表页 -- 判断 `gradeOptions != null && gradeOptions.length > 1` 时,显示等级价格标签 -- 卡片示例: `[轻奢 ¥3,999起] [高档 ¥6,999起]` +- `gradeOptions != null && gradeOptions.length > 1` 时,显示版本选项 +- 卡片示例: `[轻奢版 ¥3,999起] [高档版 ¥6,999起]`(用 name + startPrice 展示) - `gradeOptions == null` 的产品照常展示 ### 详情页 -- 判断 `gradeOptions != null && gradeOptions.length > 1` 时,顶部显示等级切换tab -- 当前等级高亮(匹配 productId) -- 点击其他等级 → 用该等级的 productId 重新请求详情接口 -- 报价/下单用当前页面的 productId,不受影响 +- `gradeOptions != null && gradeOptions.length > 1` 时,顶部显示版本切换tab +- 当前版本高亮(匹配 productId) +- 点击其他版本 → 用该 productId 重新请求详情 +- 报价/下单用当前 productId -## DDL(已在测试/正式服务器执行) +### 管理端-创建产品 +1. 选择产品类型(CORE/GROUP等) +2. 产品线下拉调用 `GET /admin/product/line/active?productType=CORE` 只显示对应类型的线 +3. 如需创建版本组:`gradeGroupId` 传 `0`(新建组)或传已有组ID(加入组) + +--- + +## DDL(已在本地/测试/正式执行) ```sql -ALTER TABLE product - ADD COLUMN product_grade VARCHAR(16) DEFAULT NULL COMMENT '产品等级' AFTER product_type, - ADD COLUMN grade_group_id BIGINT DEFAULT NULL COMMENT '等级分组ID' AFTER product_grade, - ADD COLUMN grade_sort INT DEFAULT 0 COMMENT '等级排序' AFTER grade_group_id, - ADD INDEX idx_grade_group_id (grade_group_id); +-- 产品线加类型 +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 保持不变 ```