本批变更(测试环境已部署验证): 1. 后端修复 9 个 BUG(#956/957/958/959/960 + hotfix #965/966/967) 2. BUG 10 产品地图支持高德自动生成(#962) 3. BUG 15 备品组合功能(#963) 4. BUG 20 早鸟优惠改造为 1:N 多方案(#964) 前端待跟进 BUG:1/2/5/6/8/12/19
146 行
4.7 KiB
Markdown
146 行
4.7 KiB
Markdown
# 备品组合功能(BUG 15)
|
||
|
||
**日期**:2026-04-20
|
||
**PR**:#963 + gateway 路由 hotfix #966
|
||
**影响**:管理端备品管理(新菜单)+ 产品编辑 Step3
|
||
|
||
---
|
||
|
||
## 业务变化
|
||
|
||
运营反馈备品单选操作繁琐,常用备品组合(如"亲子研学基础包"=N 个备品打包)每次新建产品都要重复选。
|
||
|
||
**改造**:支持"备品组合"实体。一个组合 = N 个备品。产品编辑时可引用组合 ID,后端保存时自动展开合并到 supplies。
|
||
|
||
**展开规则**:同 `suppliesResourceId` 的,**前端手工项优先**(手工传 quantity/unitPrice 覆盖组合项)。自定义项(`suppliesResourceId=null`)不参与去重全保留。
|
||
|
||
---
|
||
|
||
## 新增接口:`/admin/supplies-combo/*`
|
||
|
||
| Method | Path | 说明 | 注解 |
|
||
|---|---|---|---|
|
||
| POST | `/admin/supplies-combo` | 创建组合 | @Idempotent(5s) |
|
||
| PUT | `/admin/supplies-combo/{comboId}` | 编辑(主信息+明细整体替换) | @Lock4j |
|
||
| DELETE | `/admin/supplies-combo/{comboId}` | 软删 | @Lock4j |
|
||
| GET | `/admin/supplies-combo/page?pageNum=1&pageSize=10&name=xx&status=ENABLED` | 分页 | — |
|
||
| GET | `/admin/supplies-combo/{comboId}` | 详情(含 items 展开) | — |
|
||
| GET | `/admin/supplies-combo/enabled` | 下拉框(List,不分页,仅 ENABLED) | — |
|
||
| PUT | `/admin/supplies-combo/{comboId}/toggle-status` | 启用/禁用切换 | @Lock4j |
|
||
|
||
### 创建/编辑请求 VO
|
||
|
||
```ts
|
||
{
|
||
"name": "亲子研学基础包", // @NotBlank, @Size(max=128)
|
||
"description": "适用 3-8 岁儿童", // @Size(max=512)
|
||
"status": "ENABLED", // ENABLED/DISABLED
|
||
"sortOrder": 0,
|
||
"items": [ // @NotEmpty, 1-50 个
|
||
{ "suppliesId": 123, "quantity": 2, "sortOrder": 0 },
|
||
{ "suppliesId": 456, "quantity": 1, "sortOrder": 1 }
|
||
]
|
||
}
|
||
```
|
||
|
||
校验:
|
||
- `items.suppliesId` 去重(同组合不能重复加)
|
||
- 每个 `suppliesId` 必须存在于 `supplies_item` 表且 `status=1`(启用中的备品)
|
||
|
||
### 响应 VO(详情)
|
||
|
||
```ts
|
||
{
|
||
"comboId": "2046079787104866306",
|
||
"name": "亲子研学基础包",
|
||
"description": "...",
|
||
"status": "ENABLED",
|
||
"sortOrder": 0,
|
||
"itemCount": 2, // 明细数量(列表也有)
|
||
"items": [ // 详情才返回,列表为 null
|
||
{
|
||
"id": "1001", "suppliesId": "123", "quantity": 2, "sortOrder": 0,
|
||
"suppliesName": "睡袋", // 从 supplies_item 回填
|
||
"categoryCode": "OUTDOOR",
|
||
"billingType": "PER_PERSON",
|
||
"basePrice": 50.00
|
||
},
|
||
...
|
||
],
|
||
"createdBy": 1, "createdAt": "...", "updatedAt": "..."
|
||
}
|
||
```
|
||
|
||
### 下拉 VO(enabled)
|
||
|
||
```ts
|
||
[
|
||
{ "comboId": "123", "name": "亲子研学基础包", "itemCount": 5 },
|
||
{ "comboId": "456", "name": "摄影出行包", "itemCount": 3 }
|
||
]
|
||
```
|
||
|
||
---
|
||
|
||
## 产品 Step3 保存扩展
|
||
|
||
### `PUT /admin/product/item/{id}/route` 请求 VO
|
||
|
||
`ProductRouteSaveReqVO` 新增:
|
||
|
||
```ts
|
||
{
|
||
// 老字段
|
||
"supplies": [
|
||
{ "suppliesResourceId": 123, "suppliesName": "睡袋", "quantity": 2, ... }
|
||
],
|
||
|
||
// 新字段
|
||
"supplyComboIds": [789, 790] // NEW 可选,引用的备品组合 ID 列表
|
||
}
|
||
```
|
||
|
||
**后端展开逻辑**(前端无感):
|
||
1. 读 `supplyComboIds` 调内部 Feign 批量查组合展开
|
||
2. 合并到 `supplies`:同 `suppliesResourceId` 手工优先(保留前端 quantity/unitPrice)
|
||
3. 自定义项(`suppliesResourceId=null`)不参与去重
|
||
4. 展开项会被打上 `fromComboId`(DB 层面审计用)
|
||
|
||
`SuppliesItem` 内部类新增字段(前端无需传,后端审计):
|
||
|
||
```ts
|
||
{
|
||
...
|
||
"fromComboId": null // NEW 来源组合ID,NULL=单品,非空=组合展开
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 前端 TODO
|
||
|
||
### 1. 原生 BUG 排查
|
||
运营反馈"备品栏点击后选项框一直存在、单选很麻烦"。推断是产品编辑 Step3 `SuppliesPicker` 组件的下拉关闭逻辑问题,请前端同学排查。
|
||
|
||
### 2. 新菜单:备品组合管理
|
||
在"备品管理"菜单同组新建"备品组合管理":
|
||
- 列表页:分页 + 名称搜索 + 启用状态筛选
|
||
- 新建/编辑:表单含名称/描述/状态/排序 + 备品多选 + 每个备品的数量
|
||
- 启停按钮
|
||
- 删除按钮(软删)
|
||
|
||
### 3. 产品编辑 Step3 增强
|
||
- 备品区块加"从组合选择"按钮
|
||
- 点击后弹出下拉选组合(调 `/admin/supplies-combo/enabled`)
|
||
- 用户选中后把 `comboId` 追加到 `supplyComboIds` 字段
|
||
- 保存时和 `supplies` 一起提交
|
||
- 可视化:展开后的备品列表(后端返回的)可以标出"来自组合"徽标(读 `fromComboId`)
|
||
|
||
---
|
||
|
||
## 兼容性
|
||
|
||
- 老数据:产品表 `product_supplies.from_combo_id` 默认 NULL
|
||
- 老产品保存(前端不传 `supplyComboIds`):行为零变化
|
||
- 老接口:`ProductRouteSaveReqVO.supplies` 字段保留不动
|