hl-api-changelog/changelogs/2026-04/2026-04-20_dict-icon-field.md

4.1 KiB

字典数据项新增 icon 图标字段

日期2026-04-20 PR#994Closes #993 影响:管理端字典管理页、所有使用字典的展示组件


为什么变

sys_dict_data 原先只有 dict_label / dict_value / sort_order / remark,部分业务场景(如活动分类、房型、状态等级)希望能给字典项配图标用于前端可视化(活动卡片角标、状态彩色 Dot、Tab 图标等)。本次加一个 icon 字段TEXT,允许为空,字典 CRUD 和所有读取接口全部透传。

接口契约变化

新字段

所有字典数据项(DictDataVO 及 Entity 序列化)新增:

{
  "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 内部接口,前端不直接调用,此处略。

响应样例

// 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
        }
      ]
    }
  ]
}
// POST /admin/dict/data 请求体
{
  "dictType": "activity_category",
  "dictLabel": "骑马",
  "dictValue": "HORSEBACK",
  "icon": "https://cdn.example.com/icons/horse.png",   // ⭐ 可选
  "sortOrder": 10,
  "remark": "骑马体验项目"
}
// 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 条件渲染,比如:
    • 分类 Tabicon ? <img src=icon /> : null + label
    • 状态 Badgeicon 可以是 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 或重新拉一次字典