hl-api-changelog/changelogs/2026-04/2026-04-23_equipment-list-structured.md

165 行
4.8 KiB
Markdown

此文件含有模棱两可的 Unicode 字符

此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。

# 装备建议字段改造 — 条目列表结构化
**日期**: 2026-04-23
**PR**: #1259 (Closes #1244)
**服务**: hl-product-service-v2 / hl-order-service-v2 / hl-mp-service
**类型**: feat新增字段,向后兼容
---
## 背景
管理后台「产品编辑 → 补充信息 → 预订须知 → 装备建议」从纯文本 textarea 改为**条目列表**形式。小程序端目标视觉:左图标 + 右文案,一行一条。
**图标责任**:后端只存文本,图标由前端自行实现(硬编码关键词匹配 / 内置图标库 / 顺序样式),后端不提供图标字段。
---
## 字段新增契约
### 数据结构
```typescript
interface EquipmentItem {
text: string; // 文案,必填,1-50 字
}
```
- **条目数上限**: 20
- **单条 text 长度**: 1-50 字(非空非空白)
- **text 必填非空**
- 超限后端返 `code=400 message="装备建议不合法:..."`
### 旧字段(保留,降级兜底)
`equipmentAdvice: string`(富文本 HTML 字符串)继续返回,**不删**。
### 降级三态(前端必须实现)
| equipmentList | equipmentAdvice | 前端行为 |
|---------------|-----------------|---------|
| 非空数组 | 任意 | 渲染条目列表(图标前端自行匹配) |
| null / 空数组 | 非空字符串 | 渲染纯文本(可能含 HTML |
| null / 空数组 | null / 空 | 不渲染"装备建议"模块 |
---
## 涉及接口5 处响应体变化 + 1 处请求体)
### 1. Admin 保存 `POST /admin/product/supplement/save`
**请求体新增**
```json
{
"productId": 123,
"equipmentList": [
{"text": "防晒霜 SPF50+"},
{"text": "长袖防晒衣"},
{"text": "薄外套早晚温差15°C+"}
]
}
```
**请求体删除**`equipmentAdvice` 字段从 `ProductSupplementSaveReqVO` 彻底移除(老 UI 已无入口)。
### 2. Admin 详情 `GET /admin/product/{id}` → `SupplementVO`
**响应新增**
```json
{
"supplement": {
"equipmentAdvice": "<p>老富文本旧字段</p>",
"equipmentList": [{"text": "防晒霜 SPF50+"}]
}
}
```
### 3. MP 产品详情 `GET /mp/product/{id}`
**响应新增**
```json
{
"equipmentAdvice": "<p>...</p>",
"equipmentList": [{"text": "防晒霜 SPF50+"}]
}
```
### 4. 订单详情 `GET /mp/order/{id}`
**响应新增** `OrderDetailVO.equipmentList`(下单时固化自产品快照):
```json
{
"equipmentAdvice": "...",
"equipmentList": [{"text": "..."}]
}
```
### 5. 供应清单 `GET /mp/order/{orderId}/supplies-checklist`
**响应新增** `MpSuppliesChecklistRespVO.equipmentList`
```json
{
"orderId": 1001,
"categories": [...],
"equipmentAdvice": "...",
"equipmentList": [{"text": "..."}]
}
```
---
## 向后兼容说明
- **老订单快照**2026-04-23 之前下单的订单,产品快照 JSON 中不含 `equipmentList` 键 → 后端 `path("equipmentList").isArray()` 返 false → `equipmentList` 返 null → 前端按三态降级兜底渲染 `equipmentAdvice`
- **老产品**:未重新保存过的产品 DB 列 `equipment_list` 为 null → 接口返 null
- **零破坏性**:所有响应字段只新增不删除,前端不升级也不会报错
---
## 前端实现要点
1. **管理端**
- 移除原 `equipmentAdvice` 富文本输入框
- 新增"+ 新增装备"条目列表 UI一行一条,单条文案输入 + 删除按钮)
- 保存时只传 `equipmentList: List<{text}>`,不传 `equipmentAdvice`
- 本地做条目数 ≤20 / 单条 1-50 字前置校验,避免 400
2. **小程序端**
- 实现三态降级逻辑(见上表)
- 图标硬编码或按文案关键词匹配(例: "防晒" → 太阳图标, "外套" → 衣服图标, "鞋" → 鞋图标)
- 一行一条布局:`<Icon> <Text>`
3. **订单详情/供应清单**:老订单自然走 `equipmentAdvice` 纯文本分支,新订单渲染 `equipmentList`
---
## 硬约束提醒
- **不要传空字符串 text**:后端会 400`@NotBlank`
- **不要传 >20 条**:后端会 400`@Size(max=20)`
- **不要传 >50 字 text**:后端会 400`@Size(max=50)`
- **前端可以传空数组 `[]`** 表示"清空装备建议",这是合法意图
---
## 代码位置参考(前端调试用)
- Admin VO: `hl-product-service-v2/.../vo/admin/ProductSupplementSaveReqVO.java`
- Admin 详情: `hl-product-service-v2/.../vo/admin/ProductDetailRespVO.SupplementVO`
- MP VO: `hl-product-service-v2/.../vo/mp/MpProductDetailRespVO`
- 订单详情: `hl-order-service-v2/.../controller/vo/OrderDetailVO`
- 供应清单: `hl-order-service-v2/.../internal/vo/MpSuppliesChecklistRespVO`
---
## 部署说明
测试服已执行 DDL本次部署前必须先跑
```sql
ALTER TABLE product_supplement
ADD COLUMN equipment_list JSON DEFAULT NULL
COMMENT '装备建议条目列表([{text}]),优先于 equipment_advice';
```
正式环境上线前同步 DDL。