RuoYi扩展插件开发:自定义字典类型实战案例
一、痛点解析:为什么需要自定义字典类型?
你是否还在为系统中充斥的硬编码枚举值而烦恼?当业务需要新增状态类型时,是否必须修改Java代码并重启服务?在企业级应用开发中,字典管理(Dictionary Management)是解决这类问题的关键组件。RuoYi框架作为基于SpringBoot的权限管理系统,内置了完善的字典管理功能,但多数开发者仅停留在基础使用层面,未能充分发挥其扩展能力。
本文将通过一个实战案例,带你从零构建一个"订单状态"自定义字典插件,彻底解决硬编码痛点。读完本文后,你将掌握:
- 字典类型的设计原理与缓存机制
- 自定义字典的完整开发流程(后端接口+前端界面)
- 字典数据在代码生成器中的集成应用
- 高性能字典查询的实现方案
二、字典类型系统架构深度剖析
2.1 核心类关系图
2.2 字典系统工作流程图
三、开发准备:环境与技术栈
3.1 开发环境配置
| 组件 | 版本要求 | 备注 |
|---|---|---|
| JDK | 1.8+ | 推荐OpenJDK 1.8.0_301 |
| SpringBoot | 2.5.x | RuoYi框架默认版本 |
| Maven | 3.6+ | 依赖管理工具 |
| MySQL | 8.0+ | 数据库服务器 |
| IDE | IntelliJ IDEA | 推荐2021.2+版本 |
| Git | 2.30+ | 版本控制工具 |
3.2 项目目录结构解析
RuoYi/
├── ruoyi-admin/ # 管理后台模块
│ └── src/main/java/com/ruoyi/web/controller/system/
│ └── SysDictTypeController.java # 字典类型控制器
├── ruoyi-common/ # 通用工具模块
│ └── src/main/java/com/ruoyi/common/core/domain/entity/
│ ├── SysDictType.java # 字典类型实体
│ └── SysDictData.java # 字典数据实体
├── ruoyi-system/ # 系统核心模块
│ ├── src/main/java/com/ruoyi/system/service/
│ │ ├── ISysDictTypeService.java # 字典类型服务接口
│ │ └── impl/SysDictTypeServiceImpl.java # 服务实现类
│ └── src/main/java/com/ruoyi/system/mapper/
│ ├── SysDictTypeMapper.java # 字典类型数据访问接口
│ └── SysDictDataMapper.java # 字典数据访问接口
└── sql/ # 数据库脚本
└── ry_20250416.sql # 包含字典表结构的初始化脚本
3.3 核心依赖引入
在ruoyi-system/pom.xml中确认以下依赖:
<!-- 字典核心依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3.4</version>
</dependency>
四、实战开发:自定义"订单状态"字典类型
4.1 数据库表结构设计
虽然RuoYi框架已提供字典表结构,我们仍需了解其设计细节:
sys_dict_type表结构(字典类型表):
CREATE TABLE `sys_dict_type` (
`dict_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '字典主键',
`dict_name` varchar(100) NOT NULL COMMENT '字典名称',
`dict_type` varchar(100) NOT NULL COMMENT '字典类型',
`status` char(1) NOT NULL DEFAULT '0' COMMENT '状态(0正常 1停用)',
`create_by` varchar(64) DEFAULT '' COMMENT '创建者',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_by` varchar(64) DEFAULT '' COMMENT '更新者',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`dict_id`),
UNIQUE KEY `uk_dict_type` (`dict_type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='字典类型表';
sys_dict_data表结构(字典数据表):
CREATE TABLE `sys_dict_data` (
`dict_code` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '字典编码',
`dict_sort` int(11) NOT NULL DEFAULT '0' COMMENT '字典排序',
`dict_label` varchar(100) NOT NULL COMMENT '字典标签',
`dict_value` varchar(100) NOT NULL COMMENT '字典键值',
`dict_type` varchar(100) NOT NULL COMMENT '字典类型',
`css_class` varchar(100) DEFAULT NULL COMMENT '样式属性(其他样式扩展)',
`list_class` varchar(100) DEFAULT NULL COMMENT '表格字典样式',
`is_default` char(1) DEFAULT 'N' COMMENT '是否默认(Y是 N否)',
`status` char(1) NOT NULL DEFAULT '0' COMMENT '状态(0正常 1停用)',
`create_by` varchar(64) DEFAULT '' COMMENT '创建者',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_by` varchar(64) DEFAULT '' COMMENT '更新者',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`dict_code`),
KEY `idx_dict_type` (`dict_type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='字典数据表';
4.2 实体类定义
SysDictType.java(字典类型实体):
package com.ruoyi.common.core.domain.entity;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.annotation.Excel.ColumnType;
import com.ruoyi.common.core.domain.BaseEntity;
public class SysDictType extends BaseEntity {
private static final long serialVersionUID = 1L;
/** 字典主键 */
@Excel(name = "字典主键", cellType = ColumnType.NUMERIC)
private Long dictId;
/** 字典名称 */
@Excel(name = "字典名称")
@NotBlank(message = "字典名称不能为空")
@Size(min = 0, max = 100, message = "字典类型名称长度不能超过100个字符")
private String dictName;
/** 字典类型 */
@Excel(name = "字典类型")
@NotBlank(message = "字典类型不能为空")
@Size(min = 0, max = 100, message = "字典类型类型长度不能超过100个字符")
private String dictType;
/** 状态(0正常 1停用) */
@Excel(name = "状态", readConverterExp = "0=正常,1=停用")
private String status;
// Getters and Setters
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
.append("dictId", getDictId())
.append("dictName", getDictName())
.append("dictType", getDictType())
.append("status", getStatus())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("remark", getRemark())
.toString();
}
}
4.3 服务层实现
ISysDictTypeService接口:
public interface ISysDictTypeService {
/**
* 根据条件分页查询字典类型
*
* @param dictType 字典类型信息
* @return 字典类型集合信息
*/
public List<SysDictType> selectDictTypeList(SysDictType dictType);
/**
* 根据所有字典类型
*
* @return 字典类型集合信息
*/
public List<SysDictType> selectDictTypeAll();
/**
* 根据字典类型查询字典数据
*
* @param dictType 字典类型
* @return 字典数据集合信息
*/
public List<SysDictData> selectDictDataByType(String dictType);
/**
* 通过字典ID查询字典类型信息
*
* @param dictId 字典ID
* @return 字典类型信息
*/
public SysDictType selectDictTypeById(Long dictId);
/**
* 通过字典类型查询字典类型信息
*
* @param dictType 字典类型
* @return 字典类型信息
*/
public SysDictType selectDictTypeByType(String dictType);
/**
* 批量删除字典类型
*
* @param ids 需要删除的数据ID
* @return 结果
*/
public int deleteDictTypeByIds(String ids);
/**
* 清空缓存数据
*/
public void resetDictCache();
/**
* 新增保存字典类型信息
*
* @param dictType 字典类型信息
* @return 结果
*/
public int insertDictType(SysDictType dictType);
/**
* 修改保存字典类型信息
*
* @param dictType 字典类型信息
* @return 结果
*/
public int updateDictType(SysDictType dictType);
/**
* 校验字典类型称是否唯一
*
* @param dictType 字典类型
* @return 结果
*/
public boolean checkDictTypeUnique(SysDictType dictType);
}
SysDictTypeServiceImpl实现类:
@Service
public class SysDictTypeServiceImpl implements ISysDictTypeService {
@Autowired
private SysDictTypeMapper dictTypeMapper;
@Autowired
private SysDictDataMapper dictDataMapper;
@Override
public List<SysDictType> selectDictTypeList(SysDictType dictType) {
return dictTypeMapper.selectDictTypeList(dictType);
}
@Override
public List<SysDictData> selectDictDataByType(String dictType) {
List<SysDictData> dictDatas = DictUtils.getDictCache(dictType);
if (StringUtils.isNotNull(dictDatas)) {
return dictDatas;
}
dictDatas = dictDataMapper.selectDictDataByType(dictType);
if (StringUtils.isNotNull(dictDatas)) {
DictUtils.setDictCache(dictType, dictDatas);
}
return dictDatas;
}
@Override
public int insertDictType(SysDictType dictType) {
int row = dictTypeMapper.insertDictType(dictType);
if (row > 0) {
DictUtils.clearDictCache();
}
return row;
}
@Override
public int updateDictType(SysDictType dictType) {
SysDictType oldDict = dictTypeMapper.selectDictTypeById(dictType.getDictId());
dictDataMapper.updateDictDataType(oldDict.getDictType(), dictType.getDictType());
int row = dictTypeMapper.updateDictType(dictType);
if (row > 0) {
DictUtils.clearDictCache();
}
return row;
}
@Override
public boolean checkDictTypeUnique(SysDictType dictType) {
Long dictId = StringUtils.isNull(dictType.getDictId()) ? -1L : dictType.getDictId();
SysDictType info = dictTypeMapper.checkDictTypeUnique(dictType.getDictType());
if (StringUtils.isNotNull(info) && info.getDictId().longValue() != dictId.longValue()) {
return false;
}
return true;
}
}
4.4 控制器实现
SysDictTypeController.java:
@Controller
@RequestMapping("/system/dict")
public class SysDictTypeController extends BaseController {
private String prefix = "system/dict/type";
@Autowired
private ISysDictTypeService dictTypeService;
@RequiresPermissions("system:dict:view")
@GetMapping()
public String dictType() {
return prefix + "/type";
}
@RequiresPermissions("system:dict:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(SysDictType dictType) {
startPage();
List<SysDictType> list = dictTypeService.selectDictTypeList(dictType);
return getDataTable(list);
}
@RequiresPermissions("system:dict:add")
@GetMapping("/add")
public String add() {
return prefix + "/add";
}
@RequiresPermissions("system:dict:add")
@Log(title = "字典类型", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(@Validated SysDictType dict) {
if (!dictTypeService.checkDictTypeUnique(dict)) {
return error("新增字典'" + dict.getDictName() + "'失败,字典类型已存在");
}
dict.setCreateBy(getLoginName());
return toAjax(dictTypeService.insertDictType(dict));
}
@RequiresPermissions("system:dict:edit")
@GetMapping("/edit/{dictId}")
public String edit(@PathVariable("dictId") Long dictId, ModelMap mmap) {
mmap.put("dict", dictTypeService.selectDictTypeById(dictId));
return prefix + "/edit";
}
@RequiresPermissions("system:dict:edit")
@Log(title = "字典类型", businessType = BusinessType.UPDATE)
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(@Validated SysDictType dict) {
if (!dictTypeService.checkDictTypeUnique(dict)) {
return error("修改字典'" + dict.getDictName() + "'失败,字典类型已存在");
}
dict.setUpdateBy(getLoginName());
return toAjax(dictTypeService.updateDictType(dict));
}
@RequiresPermissions("system:dict:remove")
@Log(title = "字典类型", businessType = BusinessType.DELETE)
@PostMapping("/remove")
@ResponseBody
public AjaxResult remove(String ids) {
return toAjax(dictTypeService.deleteDictTypeByIds(ids));
}
@RequiresPermissions("system:dict:remove")
@Log(title = "字典类型", businessType = BusinessType.CLEAN)
@GetMapping("/refreshCache")
@ResponseBody
public AjaxResult refreshCache() {
dictTypeService.resetDictCache();
return success();
}
}
4.5 字典工具类DictUtils
DictUtils是字典缓存管理的核心工具类,负责字典数据的缓存读写:
public class DictUtils {
/**
* 分隔符
*/
public static final String SEPARATOR = ",";
/**
* 设置字典缓存
*
* @param key 参数键
* @param dictDatas 字典数据列表
*/
public static void setDictCache(String key, List<SysDictData> dictDatas) {
CacheUtils.put(getCacheName(), getCacheKey(key), dictDatas);
}
/**
* 获取字典缓存
*
* @param key 参数键
* @return dictDatas 字典数据列表
*/
public static List<SysDictData> getDictCache(String key) {
Object cacheObj = CacheUtils.get(getCacheName(), getCacheKey(key));
if (StringUtils.isNotNull(cacheObj)) {
return StringUtils.cast(cacheObj);
}
return null;
}
/**
* 根据字典类型和字典值获取字典标签
*
* @param dictType 字典类型
* @param dictValue 字典值
* @return 字典标签
*/
public static String getDictLabel(String dictType, String dictValue) {
if (StringUtils.isEmpty(dictValue)) {
return StringUtils.EMPTY;
}
StringBuilder propertyString = new StringBuilder();
List<SysDictData> datas = getDictCache(dictType);
if (StringUtils.isNull(datas)) {
return StringUtils.EMPTY;
}
for (SysDictData dict : datas) {
if (dictValue.equals(dict.getDictValue())) {
propertyString.append(dict.getDictLabel()).append(SEPARATOR);
}
}
return StringUtils.stripEnd(propertyString.toString(), SEPARATOR);
}
/**
* 删除指定字典缓存
*
* @param key 字典键
*/
public static void removeDictCache(String key) {
CacheUtils.remove(getCacheName(), getCacheKey(key));
}
/**
* 清空字典缓存
*/
public static void clearDictCache() {
CacheUtils.removeAll(getCacheName());
}
/**
* 获取cache name
*
* @return 缓存名
*/
public static String getCacheName() {
return Constants.SYS_DICT_CACHE;
}
/**
* 设置cache key
*
* @param configKey 参数键
* @return 缓存键key
*/
public static String getCacheKey(String configKey) {
return Constants.SYS_DICT_KEY + configKey;
}
}
四、实战案例:创建"订单状态"自定义字典
5.1 步骤1:新增字典类型
-
访问系统管理 → 字典管理 → 字典类型页面
-
点击"新增"按钮,填写以下信息:
- 字典名称:订单状态
- 字典类型:order_status(必须小写字母+下划线)
- 状态:正常
- 备注:订单流程状态管理
-
点击保存,完成字典类型创建
后台接口调用流程:
- 前端调用
/system/dict/add接口 - 后端执行
dictTypeService.insertDictType(dictType) - 数据写入
sys_dict_type表 - 清除字典缓存
DictUtils.clearDictCache()
5.2 步骤2:添加字典数据
为"订单状态"字典类型添加具体数据项:
- 在字典类型列表点击"订单状态"的"字典数据"按钮
- 依次添加以下字典数据:
| 排序 | 字典标签 | 字典键值 | 状态 | 是否默认 | 样式属性 |
|---|---|---|---|---|---|
| 1 | 待支付 | 0 | 正常 | Y | success |
| 2 | 已支付 | 1 | 正常 | N | primary |
| 3 | 已发货 | 2 | 正常 | N | info |
| 4 | 已完成 | 3 | 正常 | N | success |
| 5 | 已取消 | 4 | 正常 | N | danger |
数据插入SQL示例:
INSERT INTO `sys_dict_data` (`dict_sort`, `dict_label`, `dict_value`, `dict_type`, `is_default`, `status`)
VALUES
(1, '待支付', '0', 'order_status', 'Y', '0'),
(2, '已支付', '1', 'order_status', 'N', '0'),
(3, '已发货', '2', 'order_status', 'N', '0'),
(4, '已完成', '3', 'order_status', 'N', '0'),
(5, '已取消', '4', 'order_status', 'N', '0');
5.3 步骤3:前端页面集成
在订单管理页面中使用自定义字典:
订单列表页面(order.html):
<!-- 订单状态列 -->
<th data-field="orderStatus" data-formatter="orderStatusFormatter">订单状态</th>
<script>
// 订单状态格式化函数
function orderStatusFormatter(value, row, index) {
// 调用RuoYi框架的字典格式化方法
return $.table.selectDictLabel('order_status', value);
}
// 订单状态筛选下拉框
<select name="orderStatus" class="form-control selectpicker" data-live-search="true">
<option value="">所有状态</option>
<!-- 动态加载字典数据 -->
<#list @dict.getType("order_status") as dict>
<option value="${dict.dictValue}">${dict.dictLabel}</option>
</#list>
</select>
</script>
字典数据加载JavaScript代码:
// 页面加载时获取字典数据
$(function() {
// 获取订单状态字典
$.get(ctx + "system/dict/data/type/order_status", function(data) {
// 将字典数据缓存到页面
window.orderStatusDict = data;
// 渲染下拉框
renderOrderStatusSelect();
});
});
// 渲染订单状态下拉框
function renderOrderStatusSelect() {
var html = '<option value="">所有状态</option>';
$.each(window.orderStatusDict, function(index, dict) {
html += '<option value="' + dict.dictValue + '">' + dict.dictLabel + '</option>';
});
$("#orderStatus").html(html);
// 刷新selectpicker
$("#orderStatus").selectpicker('refresh');
}
5.4 步骤4:后端业务代码中使用
在Service层使用字典工具类获取字典数据:
@Service
public class OrderServiceImpl implements IOrderService {
@Override
public List<Order> selectOrderList(Order order) {
List<Order> orderList = orderMapper.selectOrderList(order);
// 转换订单状态为字典标签
for (Order item : orderList) {
// 使用DictUtils获取字典标签
String statusLabel = DictUtils.getDictLabel("order_status", item.getOrderStatus());
item.setOrderStatusLabel(statusLabel);
}
return orderList;
}
@Override
public AjaxResult changeOrderStatus(Long orderId, String status) {
// 校验状态值是否在字典范围内
List<SysDictData> statusDict = dictTypeService.selectDictDataByType("order_status");
boolean isValid = statusDict.stream()
.anyMatch(dict -> dict.getDictValue().equals(status));
if (!isValid) {
return AjaxResult.error("订单状态值无效");
}
Order order = new Order();
order.setId(orderId);
order.setOrderStatus(status);
order.setUpdateBy(SecurityUtils.getUsername());
return toAjax(orderMapper.updateOrder(order));
}
}
六、高级应用:集成代码生成器
RuoYi框架的代码生成器支持将字典类型与实体类字段关联,实现自动生成带字典功能的CRUD代码。
6.1 在代码生成器中配置字典
- 进入代码生成 → 导入表 → 选择目标表
- 点击"编辑"进入字段配置页面
- 对需要使用字典的字段(如order_status)进行配置:
- 字段名称:order_status
- 字典类型:order_status(选择已创建的字典类型)
- HTML类型:select(下拉选择框)
配置效果:生成的代码将自动包含:
- 页面下拉框使用字典数据
- 列表页状态值自动转换为字典标签
- 表单验证包含字典值范围检查
6.2 生成代码中的字典应用
生成的Controller层代码示例:
@RestController
@RequestMapping("/system/order")
public class OrderController extends BaseController {
@Autowired
private IOrderService orderService;
@GetMapping("/list")
public TableDataInfo list(Order order) {
startPage();
List<Order> list = orderService.selectOrderList(order);
return getDataTable(list);
}
// 其他接口...
}
生成的前端页面代码示例(列表页状态列):
{
field: 'orderStatus',
title: '订单状态',
formatter: function(value, row, index) {
return $.table.selectDictLabel('order_status', value);
}
}
生成的表单页面代码示例(状态选择框):
<div class="form-group">
<label class="col-sm-3 control-label">订单状态:</label>
<div class="col-sm-8">
<select name="orderStatus" class="form-control" th:with="type=${@dict.getType('order_status')}">
<option value="">请选择</option>
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}"></option>
</select>
</div>
</div>
七、性能优化:字典缓存策略
7.1 缓存实现原理
RuoYi字典系统使用多级缓存机制:
- 本地缓存:使用
CacheUtils工具类(基于ConcurrentHashMap) - Redis缓存:若配置Redis则使用分布式缓存(默认未启用)
缓存更新策略:
- 新增/修改/删除字典时清除缓存
- 定时任务定期刷新缓存(默认未启用)
- 支持手动刷新缓存(通过"刷新缓存"按钮)
7.2 性能优化建议
- 批量查询优化:
// 优化前:多次查询
String status1 = DictUtils.getDictLabel("order_status", "0");
String status2 = DictUtils.getDictLabel("pay_type", "1");
// 优化后:一次查询整个字典
List<SysDictData> orderStatusDict = dictTypeService.selectDictDataByType("order_status");
- 缓存预热:
在系统启动时加载常用字典到缓存:
@Component
public class DictCacheInitializer implements CommandLineRunner {
@Autowired
private ISysDictTypeService dictTypeService;
@Override
public void run(String... args) throws Exception {
// 预热常用字典缓存
List<String> commonDictTypes = Arrays.asList("order_status", "pay_type", "user_status");
for (String dictType : commonDictTypes) {
dictTypeService.selectDictDataByType(dictType);
}
}
}
- 使用Redis分布式缓存:
修改 application.yml 配置:
# 启用Redis缓存
spring:
redis:
host: localhost
port: 6379
password:
database: 0
# 配置缓存类型为Redis
ruoyi:
cache:
type: redis
八、常见问题与解决方案
8.1 字典缓存不刷新问题
问题描述:新增字典数据后,页面仍显示旧数据。
解决方案:
- 检查是否调用了缓存清除方法
DictUtils.clearDictCache() - 确认当前用户有刷新缓存权限(
system:dict:remove) - 手动调用刷新缓存接口:
GET /system/dict/refreshCache
代码修复示例:
// 修改字典数据后强制刷新缓存
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(SysDictData dictData) {
int rows = dictDataService.updateDictData(dictData);
if (rows > 0) {
// 只清除当前字典类型的缓存,而非全部缓存
DictUtils.removeDictCache(dictData.getDictType());
return success();
}
return error();
}
8.2 字典类型唯一性冲突
问题描述:创建字典类型时提示"字典类型已存在"。
解决方案:
- 查询数据库确认是否存在重复记录:
SELECT * FROM sys_dict_type WHERE dict_type = 'order_status'; - 若存在重复记录,可删除或重命名已有字典类型
- 检查是否有其他模块已定义相同字典类型
8.3 字典数据排序异常
问题描述:字典数据显示顺序与配置不符。
解决方案:
- 确认
dict_sort字段值是否正确设置 - 检查查询SQL是否包含排序条件:
// 正确的查询方式(包含排序) SELECT * FROM sys_dict_data WHERE dict_type = ? ORDER BY dict_sort ASC - 清除缓存后重试:
DictUtils.removeDictCache("order_status")
九、总结与扩展
9.1 本文核心要点回顾
- 字典系统架构:基于
sys_dict_type和sys_dict_data双表设计,采用缓存机制提高性能 - 开发流程:定义字典类型→添加字典数据→前后端集成→业务应用
- 性能优化:合理使用缓存、批量查询、缓存预热等技术
- 代码生成器集成:通过配置字典类型实现自动化CRUD代码生成
9.2 扩展方向
- 字典数据权限控制:基于部门/角色的字典数据隔离
- 字典变更日志:记录字典修改历史,支持审计和回滚
- 字典导入导出:Excel批量导入导出字典数据
- 高级缓存策略:实现字典缓存的过期时间和自动刷新
9.3 下期预告
《RuoYi框架代码生成器高级应用:自定义模板开发实战》
通过本文学习,你已掌握RuoYi框架自定义字典类型的完整开发流程。合理使用字典功能可以显著提高系统的灵活性和可维护性,减少硬编码带来的问题。建议在实际项目中,将所有状态码、类型码等统一使用字典管理,为系统后期扩展奠定基础。
如果你觉得本文对你有帮助,请点赞、收藏、关注三连支持!如有任何问题,欢迎在评论区留言讨论。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



