# 5.11 字典配置与使用 :::tip 概述 本节是 {field}Text 字典驱动的使用手册:如何声明、填充链路如何工作、文案如何修改生效、常见坑有哪些。后端声明一处,全链路(列表/详情/导出)自动带显示名。 ::: ## 使用三步 ```text 1. 建表时列注释写枚举: status int DEFAULT 1 COMMENT '状态:1-正常 2-禁用' (生成器自动创建字典 user_status + 字典项;或字典管理页手工建) 2. logic 模块头部声明映射: var userSerializeMaps = map[string]string{ "status": "user_status", } 挂进 spec:SerializeMaps: userSerializeMaps 3. api/v1 行结构体加 Text 字段: Status int `json:"status"` StatusText string `json:"statusText"` // 状态显示名(dict_item 解析) ``` 读取时基座自动填充,前端直接展示 `statusText`。 ## 填充链路(机制详解) ```text spec.SerializeMaps 声明 {字段: 字典编码} │ ▼ 基座 FillTextFields(结构体存在 {Field}Text string 字段即自动填充, 反射计划按类型缓存) │ ▼ DictGetText(ctx, code, value) │ 查 dict→dict_item 的 name ▼ 进程内缓存 dictTetxCache({code}:{value} → 显示名,TTL 300s) │ 未命中回源 Redis(dict:item:{code},3600s)→ 数据库 ▼ 返回显示名;查无此项返回原值(不报错) ``` map 场景(非结构体,如导出行)用 `SerializeMapOnRead(ctx, row, maps)` 原地补 `row[field+"Text"]`。 ## 修改文案如何生效 | 场景 | 生效时间 | |------|---------| | 字典管理页改 dict_item.name | 进程内缓存最迟 5 分钟(300s)自然过期 | | 需要立即全实例生效 | 调 `GET /api/dict/refreshCache`(刷 Redis 层;进程内层仍等过期) | | 新增字典项 | 同上(旧值缓存不受影响) | ::: warning 三层缓存认知 Redis 层(3600s,refreshCache 主动刷)→ 进程内层(300s,只等过期)→ 无缓存。改文案"看起来没生效"通常是进程内层未过期,等 5 分钟或重启。 ::: ## 导出中的字典文本 导出不走结构体填充,显式调用(真实模式,摘自 example 导出): ```go data = append(data, []any{ r["name"].String(), DictGetText(ctx, "example_type", r["type"]), DictGetText(ctx, "example_status", r["status"]), }) ``` 枚举列输出字典文本,Excel 直接可读(导出=所见)。 ## 前端消费 ```text 1. 行内 {field}Text:直接展示后端返回的 statusText(首选——文案唯一真相在字典) 2. 筛选下拉选项:调 /api/dict/item/getDictItemList/:code 拿字典项驱动 Select (example 模块 querySchemas 的 options 是静态示例;真实模块建议字典驱动) 3. 表单单选/多选:同上,按字典编码取选项 ``` ## 命名与例外 ```text 编码规范:{模块snake}_{字段snake}(user_status / job_execute_policy / example_status) 公共字典:role_data_scope(数据范围)等不带模块前缀 例外:operation_log.type 存注解常量值(0-40/99),用静态表 LogTypeText (consts.LogTypeNames),不走字典——数值与 gmeta logType 绑定,改动会破坏存量日志 ``` ## 常见问题 | 症状 | 原因与处理 | |------|-----------| | {field}Text 全是数字 | spec 未声明 SerializeMaps / 结构体无 {Field}Text 字段 / 字典编码写错 | | 部分值有文本部分没有 | dict_item 缺该 value 的项 | | 改了文案没变化 | 进程内 300s 缓存未过期;调 refreshCache 只刷 Redis 层 | | 生成器没建字典 | 列注释格式不对(须 `字段:1-x 2-y` 形式)或非 MySQL 库内省不到注释 | | 查询返回原值 | DictGetText 设计为"查无返回原值"——排查 dict/dict_item 数据 |