mirror of
				https://github.com/YunaiV/ruoyi-vue-pro.git
				synced 2025-10-31 18:49:06 +08:00 
			
		
		
		
	1. 增加字典数据接口
2. 前端接入全局字典数据
This commit is contained in:
		| @ -59,3 +59,11 @@ export function exportData(query) { | ||||
|     params: query | ||||
|   }) | ||||
| } | ||||
|  | ||||
| // 查询全部字典数据列表 | ||||
| export function listSimpleDictDatas() { | ||||
|   return request({ | ||||
|     url: '/system/dict-data/list-all-simple', | ||||
|     method: 'get', | ||||
|   }) | ||||
| } | ||||
|  | ||||
| @ -18,6 +18,8 @@ router.beforeEach((to, from, next) => { | ||||
|       NProgress.done() | ||||
|     } else { | ||||
|       if (store.getters.roles.length === 0) { | ||||
|         // 获取字典数据 | ||||
|         store.dispatch('dict/loadDictDatas') | ||||
|         // 判断当前用户是否已拉取完user_info信息 | ||||
|         store.dispatch('GetInfo').then(res => { | ||||
|           // 拉取user_info | ||||
|  | ||||
| @ -12,5 +12,7 @@ const getters = { | ||||
|   permissions: state => state.user.permissions, | ||||
|   permission_routes: state => state.permission.routes, | ||||
|   sidebarRouters:state => state.permission.sidebarRouters, | ||||
|   // 数据字典 | ||||
|   dict_datas: state => state.dict.dictDatas | ||||
| } | ||||
| export default getters | ||||
|  | ||||
| @ -5,6 +5,7 @@ import user from './modules/user' | ||||
| import tagsView from './modules/tagsView' | ||||
| import permission from './modules/permission' | ||||
| import settings from './modules/settings' | ||||
| import dict from './modules/dict' | ||||
| import getters from './getters' | ||||
|  | ||||
| Vue.use(Vuex) | ||||
| @ -15,7 +16,8 @@ const store = new Vuex.Store({ | ||||
|     user, | ||||
|     tagsView, | ||||
|     permission, | ||||
|     settings | ||||
|     settings, | ||||
|     dict | ||||
|   }, | ||||
|   getters | ||||
| }) | ||||
|  | ||||
							
								
								
									
										46
									
								
								ruoyi-ui/src/store/modules/dict.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								ruoyi-ui/src/store/modules/dict.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,46 @@ | ||||
| import { listSimpleDictDatas } from '@/api/system/dict/data' | ||||
|  | ||||
| const state = { | ||||
|   /** | ||||
|    * 数据字典 MAP | ||||
|    * key:数据字典大类枚举值 dictType | ||||
|    * dictValue:数据字典小类数值 {dictValue: '', dictLabel: ''} 的数组 | ||||
|    */ | ||||
|   dictDatas: {} | ||||
| } | ||||
|  | ||||
| const mutations = { | ||||
|   SET_DICT_DATAS: (state, dictDatas) => { | ||||
|     state.dictDatas = dictDatas | ||||
|   } | ||||
| } | ||||
|  | ||||
| const actions = { | ||||
|   loadDictDatas({ commit }) { | ||||
|     listSimpleDictDatas().then(response => { | ||||
|       // 设置数据 | ||||
|       const dictDataMap = {} | ||||
|       response.data.forEach(dictData => { | ||||
|         // 获得 dictType 层级 | ||||
|         const enumValueObj = dictDataMap[dictData.dictType] | ||||
|         if (!enumValueObj) { | ||||
|           dictDataMap[dictData.dictType] = [] | ||||
|         } | ||||
|         // 处理 dictValue 层级 | ||||
|         dictDataMap[dictData.dictType].push({ | ||||
|           dictValue: dictData.dictValue, | ||||
|           dictLabel: dictData.dictLabel | ||||
|         }) | ||||
|       }) | ||||
|       // 存储到 Store 中 | ||||
|       commit('SET_DICT_DATAS', dictDataMap) | ||||
|     }) | ||||
|   } | ||||
| } | ||||
|  | ||||
| export default { | ||||
|   namespaced: true, | ||||
|   state, | ||||
|   mutations, | ||||
|   actions | ||||
| } | ||||
| @ -37,6 +37,7 @@ const user = { | ||||
|       const uuid = userInfo.uuid | ||||
|       return new Promise((resolve, reject) => { | ||||
|         login(username, password, code, uuid).then(res => { | ||||
|           res = res.data; | ||||
|           setToken(res.token) | ||||
|           commit('SET_TOKEN', res.token) | ||||
|           resolve() | ||||
| @ -53,7 +54,6 @@ const user = { | ||||
|           res = res.data; // 读取 data 数据 | ||||
|           const user = res.user | ||||
|           const avatar = user.avatar === "" ? require("@/assets/images/profile.jpg") : process.env.VUE_APP_BASE_API + user.avatar; | ||||
|           debugger | ||||
|           if (res.roles && res.roles.length > 0) { // 验证返回的roles是否是一个非空数组 | ||||
|             commit('SET_ROLES', res.roles) | ||||
|             commit('SET_PERMISSIONS', res.permissions) | ||||
|  | ||||
							
								
								
									
										36
									
								
								ruoyi-ui/src/utils/dict.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								ruoyi-ui/src/utils/dict.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,36 @@ | ||||
| /** | ||||
|  * Created by 芋道源码 | ||||
|  * | ||||
|  * 数据字典工具类 | ||||
|  */ | ||||
| import store from '@/store' | ||||
|  | ||||
| export const DICT_TYPE = { | ||||
|   SYS_COMMON_STATUS: 'sys_common_status' | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * 获取 dictType 对应的数据字典数组 | ||||
|  * | ||||
|  * @param dictType 数据类型 | ||||
|  * @returns {*|Array} 数据字典数组 | ||||
|  */ | ||||
| export function getDictDatas(dictType) { | ||||
|   return store.getters.dict_datas[dictType] || [] | ||||
| } | ||||
|  | ||||
| export function getDictDataLabel(dictType, value) { | ||||
|   // 获取 dictType 对应的数据字典数组 | ||||
|   const dictDatas = getDictDatas(dictType) | ||||
|   if (!dictDatas || dictDatas.length === 0) { | ||||
|     return '' | ||||
|   } | ||||
|   // 获取 value 对应的展示名 | ||||
|   value = value + '' // 强制转换成字符串,因为 DictData 小类数值,是字符串 | ||||
|   for (const dictData of dictDatas) { | ||||
|     if (dictData.dictValue === value) { | ||||
|       return dictData.dictLabel | ||||
|     } | ||||
|   } | ||||
|   return '' | ||||
| } | ||||
| @ -99,6 +99,7 @@ export default { | ||||
|   methods: { | ||||
|     getCode() { | ||||
|       getCodeImg().then(res => { | ||||
|         res = res.data; | ||||
|         this.codeUrl = "data:image/gif;base64," + res.img; | ||||
|         this.loginForm.uuid = res.uuid; | ||||
|       }); | ||||
|  | ||||
| @ -211,6 +211,8 @@ import Treeselect from "@riophae/vue-treeselect"; | ||||
| import "@riophae/vue-treeselect/dist/vue-treeselect.css"; | ||||
| import IconSelect from "@/components/IconSelect"; | ||||
|  | ||||
| import { getDictDataLabel, getDictDatas, DICT_TYPE } from '@/utils/dict' | ||||
|  | ||||
| export default { | ||||
|   name: "Menu", | ||||
|   components: { Treeselect, IconSelect }, | ||||
| @ -255,12 +257,6 @@ export default { | ||||
|   }, | ||||
|   created() { | ||||
|     this.getList(); | ||||
|     this.getDicts("sys_show_hide").then(response => { | ||||
|       this.visibleOptions = response.data; | ||||
|     }); | ||||
|     this.getDicts("sys_normal_disable").then(response => { | ||||
|       this.statusOptions = response.data; | ||||
|     }); | ||||
|   }, | ||||
|   methods: { | ||||
|     // 选择图标 | ||||
| @ -295,19 +291,9 @@ export default { | ||||
|         this.menuOptions.push(menu); | ||||
|       }); | ||||
|     }, | ||||
|     // 显示状态字典翻译 | ||||
|     visibleFormat(row, column) { | ||||
|       if (row.menuType == "3") { | ||||
|         return ""; | ||||
|       } | ||||
|       return this.selectDictLabel(this.visibleOptions, row.visible); | ||||
|     }, | ||||
|     // 菜单状态字典翻译 | ||||
|     statusFormat(row, column) { | ||||
|       if (row.menuType == "3") { | ||||
|         return ""; | ||||
|       } | ||||
|       return this.selectDictLabel(this.statusOptions, row.status); | ||||
|       return getDictDataLabel(DICT_TYPE.SYS_COMMON_STATUS, row.status) | ||||
|     }, | ||||
|     // 取消按钮 | ||||
|     cancel() { | ||||
|  | ||||
| @ -0,0 +1,3 @@ | ||||
| ### 请求 /menu/list 接口 => 成功 | ||||
| GET {{baseUrl}}/system/dict-data/list-all-simple | ||||
| Authorization: Bearer {{token}} | ||||
| @ -0,0 +1,35 @@ | ||||
| package cn.iocoder.dashboard.modules.system.controller.dict; | ||||
|  | ||||
| import cn.iocoder.dashboard.common.pojo.CommonResult; | ||||
| import cn.iocoder.dashboard.modules.system.controller.dict.vo.SysDataDictSimpleVO; | ||||
| import cn.iocoder.dashboard.modules.system.convert.dict.SysDictDataConvert; | ||||
| import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.dict.SysDictDataDO; | ||||
| import cn.iocoder.dashboard.modules.system.service.dict.SysDictDataService; | ||||
| import io.swagger.annotations.Api; | ||||
| import io.swagger.annotations.ApiOperation; | ||||
| import org.springframework.web.bind.annotation.GetMapping; | ||||
| import org.springframework.web.bind.annotation.RequestMapping; | ||||
| import org.springframework.web.bind.annotation.RestController; | ||||
|  | ||||
| import javax.annotation.Resource; | ||||
| import java.util.List; | ||||
|  | ||||
| import static cn.iocoder.dashboard.common.pojo.CommonResult.success; | ||||
|  | ||||
| @Api(tags = "数据字典 API") | ||||
| @RestController | ||||
| @RequestMapping("/system/dict-data") | ||||
| public class SysDictDataController { | ||||
|  | ||||
|     @Resource | ||||
|     private SysDictDataService dictDataService; | ||||
|  | ||||
|     @GetMapping("/list-all-simple") | ||||
|     @ApiOperation(value = "获得全部字典数据列表", notes = "一般用于管理后台缓存字典数据在本地") | ||||
|     // 无需添加权限认证,因为前端全局都需要 | ||||
|     public CommonResult<List<SysDataDictSimpleVO>> listSimpleDictDatas() { | ||||
|         List<SysDictDataDO> list = dictDataService.listDictDatas(); | ||||
|         return success(SysDictDataConvert.INSTANCE.convertList(list)); | ||||
|     } | ||||
|  | ||||
| } | ||||
| @ -0,0 +1,20 @@ | ||||
| package cn.iocoder.dashboard.modules.system.controller.dict.vo; | ||||
|  | ||||
| import io.swagger.annotations.ApiModel; | ||||
| import io.swagger.annotations.ApiModelProperty; | ||||
| import lombok.Data; | ||||
|  | ||||
| @ApiModel("数据字典精简 VO") | ||||
| @Data | ||||
| public class SysDataDictSimpleVO { | ||||
|  | ||||
|     @ApiModelProperty(value = "字典类型", required = true, example = "gender") | ||||
|     private String dictType; | ||||
|  | ||||
|     @ApiModelProperty(value = "字典键值", required = true, example = "1") | ||||
|     private String dictValue; | ||||
|  | ||||
|     @ApiModelProperty(value = "字典标签", required = true, example = "男") | ||||
|     private String dictLabel; | ||||
|  | ||||
| } | ||||
| @ -1,3 +1,3 @@ | ||||
| ### 请求 /menu/list 接口 => 成功 | ||||
| GET {{baseUrl}}//menu/list | ||||
| GET {{baseUrl}}/system/menu/list | ||||
| Authorization: Bearer {{token}} | ||||
|  | ||||
| @ -19,6 +19,9 @@ public class SysMenuRespVO extends SysMenuBaseVO { | ||||
|     @ApiModelProperty(value = "菜单编号", required = true, example = "1024") | ||||
|     private Integer menuId; | ||||
|  | ||||
|     @ApiModelProperty(value = "状态", required = true, example = "1", notes = "参见 CommonStatusEnum 枚举类") | ||||
|     private Integer status; | ||||
|  | ||||
|     @ApiModelProperty(value = "创建时间", required = true, example = "时间戳格式") | ||||
|     private Date createTime; | ||||
|  | ||||
|  | ||||
| @ -0,0 +1,17 @@ | ||||
| package cn.iocoder.dashboard.modules.system.convert.dict; | ||||
|  | ||||
| import cn.iocoder.dashboard.modules.system.controller.dict.vo.SysDataDictSimpleVO; | ||||
| import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.dict.SysDictDataDO; | ||||
| import org.mapstruct.Mapper; | ||||
| import org.mapstruct.factory.Mappers; | ||||
|  | ||||
| import java.util.List; | ||||
|  | ||||
| @Mapper | ||||
| public interface SysDictDataConvert { | ||||
|  | ||||
|     SysDictDataConvert INSTANCE = Mappers.getMapper(SysDictDataConvert.class); | ||||
|  | ||||
|     List<SysDataDictSimpleVO> convertList(List<SysDictDataDO> list); | ||||
|  | ||||
| } | ||||
| @ -0,0 +1,9 @@ | ||||
| package cn.iocoder.dashboard.modules.system.dal.mysql.dao.dict; | ||||
|  | ||||
| import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.dict.SysDictDataDO; | ||||
| import com.baomidou.mybatisplus.core.mapper.BaseMapper; | ||||
| import org.apache.ibatis.annotations.Mapper; | ||||
|  | ||||
| @Mapper | ||||
| public interface SysDictDataMapper extends BaseMapper<SysDictDataDO> { | ||||
| } | ||||
| @ -19,7 +19,7 @@ import javax.validation.constraints.Size; | ||||
| @TableName("sys_dict_data") | ||||
| @Data | ||||
| @EqualsAndHashCode(callSuper = true) | ||||
| public class SysDictData extends BaseDO { | ||||
| public class SysDictDataDO extends BaseDO { | ||||
| 
 | ||||
|     /** | ||||
|      * 字典编码 | ||||
| @ -31,7 +31,7 @@ public class SysDictData extends BaseDO { | ||||
|      * 字典排序 | ||||
|      */ | ||||
|     @Excel(name = "字典排序", cellType = Excel.ColumnType.NUMERIC) | ||||
|     private Long dictSort; | ||||
|     private Integer dictSort; | ||||
|     /** | ||||
|      * 字典标签 | ||||
|      */ | ||||
| @ -48,6 +48,8 @@ public class SysDictData extends BaseDO { | ||||
|     private String dictValue; | ||||
|     /** | ||||
|      * 字典类型 | ||||
|      * | ||||
|      * 外键 {@link SysDictDataDO#getDictType()} | ||||
|      */ | ||||
|     @Excel(name = "字典类型") | ||||
|     @NotBlank(message = "字典类型不能为空") | ||||
| @ -0,0 +1,16 @@ | ||||
| package cn.iocoder.dashboard.modules.system.service.dict; | ||||
|  | ||||
| import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.dict.SysDictDataDO; | ||||
|  | ||||
| import java.util.List; | ||||
|  | ||||
| /** | ||||
|  * 字典数据 Service 接口 | ||||
|  * | ||||
|  * @author ruoyi | ||||
|  */ | ||||
| public interface SysDictDataService { | ||||
|  | ||||
|     List<SysDictDataDO> listDictDatas(); | ||||
|  | ||||
| } | ||||
| @ -0,0 +1,34 @@ | ||||
| package cn.iocoder.dashboard.modules.system.service.dict.impl; | ||||
|  | ||||
| import cn.iocoder.dashboard.modules.system.dal.mysql.dao.dict.SysDictDataMapper; | ||||
| import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.dict.SysDictDataDO; | ||||
| import cn.iocoder.dashboard.modules.system.service.dict.SysDictDataService; | ||||
| import org.springframework.stereotype.Service; | ||||
|  | ||||
| import javax.annotation.Resource; | ||||
| import java.util.Comparator; | ||||
| import java.util.List; | ||||
|  | ||||
| /** | ||||
|  * 字典数据 Service 实现类 | ||||
|  * | ||||
|  * @author ruoyi | ||||
|  */ | ||||
| @Service | ||||
| public class SysDictDataServiceImpl implements SysDictDataService { | ||||
|  | ||||
|     private static final Comparator<SysDictDataDO> COMPARATOR_TYPE_AND_SORT = Comparator | ||||
|             .comparing(SysDictDataDO::getDictType) | ||||
|             .thenComparingInt(SysDictDataDO::getDictSort); | ||||
|  | ||||
|     @Resource | ||||
|     private SysDictDataMapper dictDataMapper; | ||||
|  | ||||
|     @Override | ||||
|     public List<SysDictDataDO> listDictDatas() { | ||||
|         List<SysDictDataDO> list = dictDataMapper.selectList(null); | ||||
|         list.sort(COMPARATOR_TYPE_AND_SORT); | ||||
|         return list; | ||||
|     } | ||||
|  | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 YunaiV
					YunaiV