122 行
4.1 KiB
Markdown
122 行
4.1 KiB
Markdown
# 字典数据项新增 icon 图标字段
|
||
|
||
**日期**:2026-04-20
|
||
**PR**:#994(Closes #993)
|
||
**影响**:管理端字典管理页、所有使用字典的展示组件
|
||
|
||
---
|
||
|
||
## 为什么变
|
||
|
||
`sys_dict_data` 原先只有 `dict_label` / `dict_value` / `sort_order` / `remark`,部分业务场景(如活动分类、房型、状态等级)希望能给字典项配图标用于前端可视化(活动卡片角标、状态彩色 Dot、Tab 图标等)。本次加一个 `icon` 字段(TEXT,允许为空),字典 CRUD 和所有读取接口全部透传。
|
||
|
||
## 接口契约变化
|
||
|
||
### 新字段
|
||
|
||
所有字典数据项(`DictDataVO` 及 Entity 序列化)新增:
|
||
|
||
```ts
|
||
{
|
||
"icon": "https://cdn.example.com/icons/camp.png" | null
|
||
}
|
||
```
|
||
|
||
**类型**:`string | null`(可为 URL、emoji、base64 data URL,旧数据默认 `null`)
|
||
|
||
### 受影响接口
|
||
|
||
| Method | Path | 变化 |
|
||
|---|---|---|
|
||
| POST | `/admin/dict/data` | **请求体**新增可选 `icon`;**响应**新增 `icon` |
|
||
| PUT | `/admin/dict/data/{id}` | **请求体**新增可选 `icon`(不传则不覆盖);**响应**新增 `icon` |
|
||
| GET | `/admin/dict/data/{id}` | 响应新增 `icon` |
|
||
| GET | `/admin/dict/data/{dictType}` | 响应每项新增 `icon` |
|
||
| GET | `/admin/dict/all` | 响应每项新增 `icon` |
|
||
| GET | `/dict/all`(公开,无需 token) | 响应每项 `dataList[].icon` |
|
||
|
||
> `/internal/mp/**` 是服务间 Feign 内部接口,前端不直接调用,此处略。
|
||
|
||
### 响应样例
|
||
|
||
```jsonc
|
||
// GET /admin/dict/all
|
||
{
|
||
"code": 200,
|
||
"data": [
|
||
{
|
||
"dictType": "activity_billing_type",
|
||
"dictName": "计费方式",
|
||
"dataList": [
|
||
{
|
||
"dictValue": "PER_PERSON",
|
||
"dictLabel": "按人",
|
||
"icon": "https://cdn.example.com/icons/per-person.png", // ⭐ 新增
|
||
"sort": 1,
|
||
"remark": null
|
||
},
|
||
{
|
||
"dictValue": "PER_GROUP",
|
||
"dictLabel": "按组/团",
|
||
"icon": null, // 旧数据默认 null
|
||
"sort": 2,
|
||
"remark": null
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
```jsonc
|
||
// POST /admin/dict/data 请求体
|
||
{
|
||
"dictType": "activity_category",
|
||
"dictLabel": "骑马",
|
||
"dictValue": "HORSEBACK",
|
||
"icon": "https://cdn.example.com/icons/horse.png", // ⭐ 可选
|
||
"sortOrder": 10,
|
||
"remark": "骑马体验项目"
|
||
}
|
||
```
|
||
|
||
```jsonc
|
||
// PUT /admin/dict/data/{id} 请求体(只传要改的字段;不传 icon 不覆盖)
|
||
{
|
||
"icon": "emoji:🏕"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 前端改造建议
|
||
|
||
### 管理端 —— 字典管理页
|
||
|
||
- **字典项创建/编辑弹窗**:在 `dictLabel` 旁新增「图标」输入框
|
||
- 建议 placeholder:"图标 URL / emoji / base64 data URL,可为空"
|
||
- 不做正则校验(后端 TEXT,无上限),由用户自己把控
|
||
- 提交时 `icon` 传空字符串即落库空串;不想改就别带这个字段(PUT 语义是"字段缺失 = 不改")
|
||
- **字典数据列表**:在 dictLabel 右侧展示一个小图标预览(URL 就 `<img>`,emoji 就文本,base64 就 `<img>`),null 留空
|
||
|
||
### 小程序端 / 管理端业务页
|
||
|
||
- 调 `/dict/all` 或 `/admin/dict/all` 时,每个 `dataList[].icon` 都能拿到
|
||
- 展示组件里按 `icon != null` 条件渲染,比如:
|
||
- 分类 Tab:`icon ? <img src=icon /> : null` + `label`
|
||
- 状态 Badge:`icon` 可以是 emoji 或彩色圆点 URL
|
||
- icon 内容不固定,前端按它的形态(http(s) URL / emoji 文本 / `data:image/...` base64)自适应渲染即可
|
||
|
||
---
|
||
|
||
## 不影响的接口
|
||
|
||
- `/admin/dict/type` 相关(字典类型 CRUD / 分页)
|
||
- 现有响应结构中已有的字段全部保持,只是**每个字典数据项多一个 `icon` 字段**
|
||
- 旧数据 `icon = null`,前端没做处理也不会报错,但展示上就没图标
|
||
|
||
## 缓存
|
||
|
||
- 后端字典缓存(Redis,5min TTL)会在字典数据 CRUD 后通过 `CacheEvictAfterCommit` 自动清,icon 更新后下一次读就能拿到新值(最坏延迟 = 事务提交 + 单次请求)
|
||
- 前端 `/dict/all` 通常也有本地缓存,建议管理端配置 icon 后引导用户 F5 或重新拉一次字典
|