hl-api-changelog/changelogs-v2/2026-06/03_3390_图标库模块-新增接口-管理后台+小程序.md

8.0 KiB

【新增接口·管理后台 + 小程序】图标库模块全模块首次推送,11 接口)

PR: #3396模块主体+ #3398 / #3399mp 端点公开化)+ #3401上线后审计加固 服务: hl-user-service | 更新时间: 2026-06-03

存放目录: changelogs-v2/2026-06/ 影响范围: 管理后台「图标库」管理页(分类 + 图标 CRUD + SVG 上传解析);小程序/前端 图标渲染(公开只读查询)


⚠️ 关键说明

  1. 两级结构(类似数据字典):一级「图标分类」(icon_category) + 二级「图标项」(icon_item)。图标项归属某分类编码 categoryCode
  2. SVG 直接存库(不走 OSS:图标内容是 SVG 字符串,直存数据库 svg_contentMEDIUMTEXT,上限 16MB,单图标后端限 256KB。前端拿到的 svgContent 即可直接渲染。
  3. 上传解析与保存分两步:先调 POST /admin/icon/parse-svg 上传 .svg 文件,后端读成字符串校验后只返回字符串不落库;前端拿到 svgContent 再连同 color/size 等填进保存表单调 POST /admin/icon/item 保存。
  4. SVG 安全校验(重要):上传/保存的 SVG 会经服务端 XXE-safe 解析校验,拒绝<script><foreignObject>on* 事件属性onload/onclick…javascript: 外链的内容(返回错误码 210757);非合法 XML 或根元素不是 <svg> 返回 210754前端渲染 SVG 时仍建议做一次 sanitize 作为纵深防御。
  5. mp 查询端点公开无需 token/mp/icon/categories/mp/icon/items 是 UI 参考数据(同字典),无需登录、无需 token 即可访问;只返回 status=ACTIVE 的分类与图标,且分类被禁用时其图标也不再返回
  6. admin 端点需管理后台 JWTcolor 为 hex#FFCC00),size 为像素整数,均为可选展示属性。

1. 接口背景

图标库给运营在后台统一维护一套 SVG 图标,供小程序/前端按分类拉取渲染(如分类入口图标、标签图标等)。

  • 管理后台「图标库」页:分类增删改查 + 图标增删改查 + 上传 SVG 解析。
  • 小程序/前端:按分类拉启用图标列表渲染。

2. 变更清单

管理后台(/admin/icon/**,需 admin JWT

# 方法 路径 说明
1 POST /admin/icon/category 保存分类id 空=新建,非空=修改)
2 GET /admin/icon/category/page 分类分页status / keyword 过滤)
3 GET /admin/icon/category/list 启用分类列表(下拉用)
4 DELETE /admin/icon/category/{id} 删除分类(其下有图标项时拒删)
5 POST /admin/icon/item 保存图标id 空=新建,非空=修改)
6 GET /admin/icon/item/page 图标分页categoryCode / keyword 过滤)
7 GET /admin/icon/item/{id} 图标详情(含 svgContent
8 DELETE /admin/icon/item/{id} 删除图标
9 POST /admin/icon/parse-svg 上传 SVG 文件解析为字符串(不落库)

小程序 / 前端(/mp/icon/**,公开无需 token

# 方法 路径 说明
10 GET /mp/icon/categories 启用分类列表
11 GET /mp/icon/items?categoryCode=xxx 某分类下启用图标列表

3. 接口详情

3.1 保存分类

POST /admin/icon/category

字段 类型 必填 校验 说明
id Long 空=新建,非空=修改
categoryCode String ≤64 分类编码,全局唯一,创建后不可改
categoryName String ≤100 分类名称
sort Integer 排序号,升序,默认 0
status String ACTIVE/DISABLED 状态,默认 ACTIVE
remark String ≤255 备注
curl -X POST "https://api.test.1814.love:9443/admin/icon/category" \
  -H "Authorization: Bearer {adminToken}" -H "Content-Type: application/json" \
  -d '{"categoryCode":"weather","categoryName":"天气","sort":1}'
# 返回: {"code":200,"message":"成功","data":2062087054098898945}  // data=分类ID

3.2 上传 SVG 解析(保存图标前置步骤)

POST /admin/icon/parse-svgmultipart/form-data,字段名 file.svg 文件)

curl -X POST "https://api.test.1814.love:9443/admin/icon/parse-svg" \
  -H "Authorization: Bearer {adminToken}" \
  -F "file=@sunny.svg"
# 返回:
# {"code":200,"message":"成功","data":{
#   "svgContent":"<svg viewBox=\"0 0 24 24\">...</svg>",
#   "fileName":"sunny.svg","size":1234 }}
  • 校验失败错误码:210753 文件为空 / 210754 非合法 SVG非 XML 或根非 svg/ 210755 超 256KB / 210757 含不安全内容(脚本/事件/外链)。

3.3 保存图标

POST /admin/icon/item

字段 类型 必填 校验 说明
id Long 空=新建,非空=修改
categoryCode String ≤64 所属分类编码(新建时校验分类存在;修改时不可改)
iconCode String ≤64 图标编码,同分类内唯一
name String ≤100 图标名称
svgContent String ≤256KB SVG 字符串(来自 3.2 解析结果)
color String ≤16 默认色值 hex,如 #FFCC00
size Integer 默认尺寸(像素)
keywords String ≤255 搜索关键词(逗号分隔)
sort Integer 排序号,默认 0
status String ACTIVE/DISABLED 状态,默认 ACTIVE
remark String ≤255 备注

注意SaveReqVO 全量快照语义):修改时请回填全部字段(先用 3.5 详情拉取再改),未传的可空字段会被覆盖为空。categoryCode/iconCode 创建后不可变,修改时会被忽略。

错误码:210701 分类编码已存在 / 210702 分类不存在 / 210703 分类下有图标不可删 / 210751 同分类图标编码已存在 / 210752 图标不存在。

3.4 图标分页

GET /admin/icon/item/page?page=1&pageSize=20&categoryCode=weather&keyword=晴

  • categoryCode 精确过滤(可空);keyword 模糊匹配 iconCode/name/keywords可空
  • 返回标准分页结构 {records, total, page, pageSize}records[] 为完整图标 VO含 svgContent

3.5 图标详情

GET /admin/icon/item/{id} → 返回完整图标 VO含 svgContent/color/size/keywords/status 等)。

3.6【公开】小程序查询

GET /mp/icon/categories (无需 token

curl "https://api.test.1814.love:9443/mp/icon/categories"
# 返回: {"code":200,"data":[{"categoryCode":"weather","categoryName":"天气","sort":1}, ...]}

GET /mp/icon/items?categoryCode=weather (无需 token

curl "https://api.test.1814.love:9443/mp/icon/items?categoryCode=weather"
# 返回: {"code":200,"data":[
#   {"iconCode":"sunny","name":"晴天","svgContent":"<svg ...>...</svg>","color":"#FFCC00","size":24}, ...]}
  • 只返回 ACTIVE 分类下的 ACTIVE 图标;分类被禁用时该分类的图标不再返回。
  • categoryCode 必填(缺失返 400

4. 前端对接要点

  1. 新增图标流程:上传 .svg → 调 3.2 拿 svgContent → 填表单(补 color/size/分类/编码)→ 调 3.3 保存。
  2. 渲染 SVG:拿到 svgContent 直接内联渲染;务必先做一次前端 sanitize(后端已拒明显恶意内容,前端 sanitize 作纵深防御)。
  3. 小程序拉图标:先 /mp/icon/categories 拿启用分类,再用 categoryCode/mp/icon/items。两端点均公开无需 token。
  4. 状态语义ACTIVE 启用 / DISABLED 禁用;mp 端只见 ACTIVE。

本模块已在测试服完成端到端验证admin CRUD + 上传解析 + mp 公开查询 + 大 SVG 入库 + 恶意 SVG 拒绝)。如需调整字段或新增端点请反馈。