mirror of
				https://github.com/YunaiV/ruoyi-vue-pro.git
				synced 2025-10-31 10:37:41 +08:00 
			
		
		
		
	1. 完成 menu 模块的迁移
2. 增加 mybatis plus 的 QueryWrapperX 封装,方便拼接 SQL
This commit is contained in:
		| @ -66,52 +66,4 @@ public interface SysMenuMapper | ||||
|      */ | ||||
|     public List<Integer> selectMenuListByRoleId(@Param("roleId") Long roleId, @Param("menuCheckStrictly") boolean menuCheckStrictly); | ||||
|  | ||||
|     /** | ||||
|      * 根据菜单ID查询信息 | ||||
|      * | ||||
|      * @param menuId 菜单ID | ||||
|      * @return 菜单信息 | ||||
|      */ | ||||
|     public SysMenu selectMenuById(Long menuId); | ||||
|  | ||||
|     /** | ||||
|      * 是否存在菜单子节点 | ||||
|      * | ||||
|      * @param menuId 菜单ID | ||||
|      * @return 结果 | ||||
|      */ | ||||
|     public int hasChildByMenuId(Long menuId); | ||||
|  | ||||
|     /** | ||||
|      * 新增菜单信息 | ||||
|      * | ||||
|      * @param menu 菜单信息 | ||||
|      * @return 结果 | ||||
|      */ | ||||
|     public int insertMenu(SysMenu menu); | ||||
|  | ||||
|     /** | ||||
|      * 修改菜单信息 | ||||
|      * | ||||
|      * @param menu 菜单信息 | ||||
|      * @return 结果 | ||||
|      */ | ||||
|     public int updateMenu(SysMenu menu); | ||||
|  | ||||
|     /** | ||||
|      * 删除菜单管理信息 | ||||
|      * | ||||
|      * @param menuId 菜单ID | ||||
|      * @return 结果 | ||||
|      */ | ||||
|     public int deleteMenuById(Long menuId); | ||||
|  | ||||
|     /** | ||||
|      * 校验菜单名称是否唯一 | ||||
|      * | ||||
|      * @param menuName 菜单名称 | ||||
|      * @param parentId 父菜单ID | ||||
|      * @return 结果 | ||||
|      */ | ||||
|     public SysMenu checkMenuNameUnique(@Param("menuName") String menuName, @Param("parentId") Long parentId); | ||||
| } | ||||
|  | ||||
| @ -8,6 +8,7 @@ import java.util.LinkedList; | ||||
| import java.util.List; | ||||
| import java.util.Set; | ||||
| import java.util.stream.Collectors; | ||||
|  | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.stereotype.Service; | ||||
| import com.ruoyi.common.constant.UserConstants; | ||||
| @ -30,19 +31,9 @@ import com.ruoyi.system.service.ISysMenuService; | ||||
|  * @author ruoyi | ||||
|  */ | ||||
| @Service | ||||
| public class SysMenuServiceImpl implements ISysMenuService | ||||
| { | ||||
| public class SysMenuServiceImpl implements ISysMenuService { | ||||
|     public static final String PREMISSION_STRING = "perms[\"{0}\"]"; | ||||
|  | ||||
|     @Autowired | ||||
|     private SysMenuMapper menuMapper; | ||||
|  | ||||
|     @Autowired | ||||
|     private SysRoleMapper roleMapper; | ||||
|  | ||||
|     @Autowired | ||||
|     private SysRoleMenuMapper roleMenuMapper; | ||||
|  | ||||
|     /** | ||||
|      * 根据用户查询系统菜单列表 | ||||
|      * | ||||
| @ -50,8 +41,7 @@ public class SysMenuServiceImpl implements ISysMenuService | ||||
|      * @return 菜单列表 | ||||
|      */ | ||||
|     @Override | ||||
|     public List<SysMenu> selectMenuList(Long userId) | ||||
|     { | ||||
|     public List<SysMenu> selectMenuList(Long userId) { | ||||
|         return selectMenuList(new SysMenu(), userId); | ||||
|     } | ||||
|  | ||||
| @ -62,16 +52,12 @@ public class SysMenuServiceImpl implements ISysMenuService | ||||
|      * @return 菜单列表 | ||||
|      */ | ||||
|     @Override | ||||
|     public List<SysMenu> selectMenuList(SysMenu menu, Long userId) | ||||
|     { | ||||
|     public List<SysMenu> selectMenuList(SysMenu menu, Long userId) { | ||||
|         List<SysMenu> menuList = null; | ||||
|         // 管理员显示所有菜单信息 | ||||
|         if (SysUser.isAdmin(userId)) | ||||
|         { | ||||
|         if (SysUser.isAdmin(userId)) { | ||||
|             menuList = menuMapper.selectMenuList(menu); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|         } else { | ||||
|             menu.getParams().put("userId", userId); | ||||
|             menuList = menuMapper.selectMenuListByUserId(menu); | ||||
|         } | ||||
| @ -85,14 +71,11 @@ public class SysMenuServiceImpl implements ISysMenuService | ||||
|      * @return 权限列表 | ||||
|      */ | ||||
|     @Override | ||||
|     public Set<String> selectMenuPermsByUserId(Long userId) | ||||
|     { | ||||
|     public Set<String> selectMenuPermsByUserId(Long userId) { | ||||
|         List<String> perms = menuMapper.selectMenuPermsByUserId(userId); | ||||
|         Set<String> permsSet = new HashSet<>(); | ||||
|         for (String perm : perms) | ||||
|         { | ||||
|             if (StringUtils.isNotEmpty(perm)) | ||||
|             { | ||||
|         for (String perm : perms) { | ||||
|             if (StringUtils.isNotEmpty(perm)) { | ||||
|                 permsSet.addAll(Arrays.asList(perm.trim().split(","))); | ||||
|             } | ||||
|         } | ||||
| @ -106,15 +89,11 @@ public class SysMenuServiceImpl implements ISysMenuService | ||||
|      * @return 菜单列表 | ||||
|      */ | ||||
|     @Override | ||||
|     public List<SysMenu> selectMenuTreeByUserId(Long userId) | ||||
|     { | ||||
|     public List<SysMenu> selectMenuTreeByUserId(Long userId) { | ||||
|         List<SysMenu> menus = null; | ||||
|         if (SecurityUtils.isAdmin(userId)) | ||||
|         { | ||||
|         if (SecurityUtils.isAdmin(userId)) { | ||||
|             menus = menuMapper.selectMenuTreeAll(); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|         } else { | ||||
|             menus = menuMapper.selectMenuTreeByUserId(userId); | ||||
|         } | ||||
|         return getChildPerms(menus, 0); | ||||
| @ -127,8 +106,7 @@ public class SysMenuServiceImpl implements ISysMenuService | ||||
|      * @return 选中菜单列表 | ||||
|      */ | ||||
|     @Override | ||||
|     public List<Integer> selectMenuListByRoleId(Long roleId) | ||||
|     { | ||||
|     public List<Integer> selectMenuListByRoleId(Long roleId) { | ||||
|         SysRole role = roleMapper.selectRoleById(roleId); | ||||
|         return menuMapper.selectMenuListByRoleId(roleId, role.isMenuCheckStrictly()); | ||||
|     } | ||||
| @ -140,37 +118,11 @@ public class SysMenuServiceImpl implements ISysMenuService | ||||
|      * @return 下拉树结构列表 | ||||
|      */ | ||||
|     @Override | ||||
|     public List<TreeSelect> buildMenuTreeSelect(List<SysMenu> menus) | ||||
|     { | ||||
|     public List<TreeSelect> buildMenuTreeSelect(List<SysMenu> menus) { | ||||
|         List<SysMenu> menuTrees = buildMenuTree(menus); | ||||
|         return menuTrees.stream().map(TreeSelect::new).collect(Collectors.toList()); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 根据菜单ID查询信息 | ||||
|      * | ||||
|      * @param menuId 菜单ID | ||||
|      * @return 菜单信息 | ||||
|      */ | ||||
|     @Override | ||||
|     public SysMenu selectMenuById(Long menuId) | ||||
|     { | ||||
|         return menuMapper.selectMenuById(menuId); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 是否存在菜单子节点 | ||||
|      * | ||||
|      * @param menuId 菜单ID | ||||
|      * @return 结果 | ||||
|      */ | ||||
|     @Override | ||||
|     public boolean hasChildByMenuId(Long menuId) | ||||
|     { | ||||
|         int result = menuMapper.hasChildByMenuId(menuId); | ||||
|         return result > 0 ? true : false; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 查询菜单使用数量 | ||||
|      * | ||||
| @ -178,64 +130,10 @@ public class SysMenuServiceImpl implements ISysMenuService | ||||
|      * @return 结果 | ||||
|      */ | ||||
|     @Override | ||||
|     public boolean checkMenuExistRole(Long menuId) | ||||
|     { | ||||
|     public boolean checkMenuExistRole(Long menuId) { | ||||
|         int result = roleMenuMapper.checkMenuExistRole(menuId); | ||||
|         return result > 0 ? true : false; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 新增保存菜单信息 | ||||
|      * | ||||
|      * @param menu 菜单信息 | ||||
|      * @return 结果 | ||||
|      */ | ||||
|     @Override | ||||
|     public int insertMenu(SysMenu menu) | ||||
|     { | ||||
|         return menuMapper.insertMenu(menu); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 修改保存菜单信息 | ||||
|      * | ||||
|      * @param menu 菜单信息 | ||||
|      * @return 结果 | ||||
|      */ | ||||
|     @Override | ||||
|     public int updateMenu(SysMenu menu) | ||||
|     { | ||||
|         return menuMapper.updateMenu(menu); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 删除菜单管理信息 | ||||
|      * | ||||
|      * @param menuId 菜单ID | ||||
|      * @return 结果 | ||||
|      */ | ||||
|     @Override | ||||
|     public int deleteMenuById(Long menuId) | ||||
|     { | ||||
|         return menuMapper.deleteMenuById(menuId); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 校验菜单名称是否唯一 | ||||
|      * | ||||
|      * @param menu 菜单信息 | ||||
|      * @return 结果 | ||||
|      */ | ||||
|     @Override | ||||
|     public String checkMenuNameUnique(SysMenu menu) | ||||
|     { | ||||
|         Long menuId = StringUtils.isNull(menu.getMenuId()) ? -1L : menu.getMenuId(); | ||||
|         SysMenu info = menuMapper.checkMenuNameUnique(menu.getMenuName(), menu.getParentId()); | ||||
|         if (StringUtils.isNotNull(info) && info.getMenuId().longValue() != menuId.longValue()) | ||||
|         { | ||||
|             return UserConstants.NOT_UNIQUE; | ||||
|         } | ||||
|         return UserConstants.UNIQUE; | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -7,7 +7,7 @@ import store from '@/store' | ||||
|  | ||||
| export const DICT_TYPE = { | ||||
|   SYS_COMMON_STATUS: 'sys_common_status', | ||||
|   SYS_MENU_TYPE: 'menu_type' | ||||
|   SYS_MENU_TYPE: 'sys_menu_type' | ||||
| } | ||||
|  | ||||
| /** | ||||
|  | ||||
| @ -13,10 +13,10 @@ | ||||
|       <el-form-item label="状态" prop="status"> | ||||
|         <el-select v-model="queryParams.status" placeholder="菜单状态" clearable size="small"> | ||||
|           <el-option | ||||
|             v-for="dict in statusOptions" | ||||
|             :key="dict.dictValue" | ||||
|             :label="dict.dictLabel" | ||||
|             :value="dict.dictValue" | ||||
|             v-for="dict in statusDictDatas" | ||||
|             :key="dict.value" | ||||
|             :label="dict.label" | ||||
|             :value="dict.value" | ||||
|           /> | ||||
|         </el-select> | ||||
|       </el-form-item> | ||||
| @ -106,8 +106,8 @@ | ||||
|               <el-radio-group v-model="form.type"> | ||||
|                 <el-radio | ||||
|                     v-for="dict in menuTypeDictDatas" | ||||
|                     :key="dict.value" | ||||
|                     :label="dict.value" | ||||
|                     :key="parseInt(dict.value)" | ||||
|                     :label="parseInt(dict.value)" | ||||
|                 >{{dict.label}}</el-radio> | ||||
|               </el-radio-group> | ||||
|             </el-form-item> | ||||
| @ -165,7 +165,7 @@ | ||||
|                 <el-radio | ||||
|                   v-for="dict in statusDictDatas" | ||||
|                   :key="dict.value" | ||||
|                   :label="dict.value" | ||||
|                   :label="parseInt(dict.value)" | ||||
|                 >{{dict.label}}</el-radio> | ||||
|               </el-radio-group> | ||||
|             </el-form-item> | ||||
| @ -206,8 +206,6 @@ export default { | ||||
|       title: "", | ||||
|       // 是否显示弹出层 | ||||
|       open: false, | ||||
|       // 菜单状态数据字典 | ||||
|       statusOptions: [], | ||||
|       // 查询参数 | ||||
|       queryParams: { | ||||
|         name: undefined, | ||||
| @ -288,9 +286,9 @@ export default { | ||||
|         parentId: 0, | ||||
|         name: undefined, | ||||
|         icon: undefined, | ||||
|         type: "1", | ||||
|         type: SysMenuTypeEnum.DIR, | ||||
|         sort: undefined, | ||||
|         status: "0" | ||||
|         status: SysCommonStatusEnum.ENABLE | ||||
|       }; | ||||
|       this.resetForm("form"); | ||||
|     }, | ||||
| @ -329,17 +327,18 @@ export default { | ||||
|     submitForm: function() { | ||||
|       this.$refs["form"].validate(valid => { | ||||
|         if (valid) { | ||||
|           // 若权限类型为菜单时,进行 route 的校验,避免后续拼接出来的路由无法跳转 | ||||
|           if (this.form.type === ResourceTypeEnum.MENU) { | ||||
|           // 若权限类型为目录或者菜单时,进行 path 的校验,避免后续拼接出来的路由无法跳转 | ||||
|           if (this.form.type === SysMenuTypeEnum.DIR | ||||
|             || this.form.type === SysMenuTypeEnum.MENU) { | ||||
|             // 如果是外链,则不进行校验 | ||||
|             const route = this.resourceForm.route | ||||
|             if (route.indexOf('http://') === -1 || route.indexOf('https://') === -1) { | ||||
|               // 父权限为根节点,route 必须以 / 开头 | ||||
|               if (this.resourceForm.pid === 0 && route.charAt(0) !== '/') { | ||||
|                 this.messageSuccess('前端必须以 / 开头') | ||||
|             const path = this.form.path | ||||
|             if (path.indexOf('http://') === -1 || path.indexOf('https://') === -1) { | ||||
|               // 父权限为根节点,path 必须以 / 开头 | ||||
|               if (this.form.parentId === 0 && path.charAt(0) !== '/') { | ||||
|                 this.msgSuccess('前端必须以 / 开头') | ||||
|                 return | ||||
|               } else if (this.resourceForm.pid !== 0 && route.charAt(0) === '/') { | ||||
|                 this.messageSuccess('前端不能以 / 开头') | ||||
|               } else if (this.form.parentId !== 0 && path.charAt(0) === '/') { | ||||
|                 this.msgSuccess('前端不能以 / 开头') | ||||
|                 return | ||||
|               } | ||||
|             } | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| package cn.iocoder.dashboard.framework.mybatis.core; | ||||
| package cn.iocoder.dashboard.framework.mybatis.core.dataobject; | ||||
| 
 | ||||
| import com.baomidou.mybatisplus.annotation.TableLogic; | ||||
| import lombok.Data; | ||||
| @ -0,0 +1,93 @@ | ||||
| package cn.iocoder.dashboard.framework.mybatis.core.query; | ||||
|  | ||||
| import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; | ||||
| import com.baomidou.mybatisplus.core.toolkit.ArrayUtils; | ||||
| import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; | ||||
| import org.springframework.util.StringUtils; | ||||
|  | ||||
| import java.util.Collection; | ||||
|  | ||||
| /** | ||||
|  * 拓展 MyBatis Plus QueryWrapper 类,主要增加如下功能: | ||||
|  * | ||||
|  * 1. 拼接条件的方法,增加 xxxIfPresent 方法,用于判断值不存在的时候,不要拼接到条件中。 | ||||
|  * | ||||
|  * @param <T> 数据类型 | ||||
|  */ | ||||
| public class QueryWrapperX<T> extends QueryWrapper<T> { | ||||
|  | ||||
|     public QueryWrapperX<T> likeIfPresent(String column, String val) { | ||||
|         if (StringUtils.hasText(val)) { | ||||
|             return (QueryWrapperX<T>) super.like(column, val); | ||||
|         } | ||||
|         return this; | ||||
|     } | ||||
|  | ||||
|     public QueryWrapperX<T> inIfPresent(String column, Collection<?> values) { | ||||
|         if (!CollectionUtils.isEmpty(values)) { | ||||
|             return (QueryWrapperX<T>) super.in(column, values); | ||||
|         } | ||||
|         return this; | ||||
|     } | ||||
|  | ||||
|     public QueryWrapperX<T> inIfPresent(String column, Object... values) { | ||||
|         if (!ArrayUtils.isEmpty(values)) { | ||||
|             return (QueryWrapperX<T>) super.in(column, values); | ||||
|         } | ||||
|         return this; | ||||
|     } | ||||
|  | ||||
|     public QueryWrapperX<T> eqIfPresent(String column, Object val) { | ||||
|         if (val != null) { | ||||
|             return (QueryWrapperX<T>) super.eq(column, val); | ||||
|         } | ||||
|         return this; | ||||
|     } | ||||
|  | ||||
|     public QueryWrapperX<T> gtIfPresent(String column, Object val) { | ||||
|         if (val != null) { | ||||
|             return (QueryWrapperX<T>) super.gt(column, val); | ||||
|         } | ||||
|         return this; | ||||
|     } | ||||
|  | ||||
|     public QueryWrapperX<T> betweenIfPresent(String column, Object val1, Object val2) { | ||||
|         if (val1 != null && val2 != null) { | ||||
|             return (QueryWrapperX<T>) super.between(column, val1, val2); | ||||
|         } | ||||
|         if (val1 != null) { | ||||
|             return (QueryWrapperX<T>) ge(column, val1); | ||||
|         } | ||||
|         if (val2 != null) { | ||||
|             return (QueryWrapperX<T>) le(column, val2); | ||||
|         } | ||||
|         return this; | ||||
|     } | ||||
|  | ||||
|     // ========== 重写父类方法,方便链式调用 ========== | ||||
|  | ||||
|     @Override | ||||
|     public QueryWrapperX<T> eq(boolean condition, String column, Object val) { | ||||
|         super.eq(condition, column, val); | ||||
|         return this; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public QueryWrapperX<T> eq(String column, Object val) { | ||||
|         super.eq(column, val); | ||||
|         return this; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public QueryWrapperX<T> orderByDesc(String column) { | ||||
|         super.orderByDesc(true, column); | ||||
|         return this; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public QueryWrapperX<T> last(String lastSql) { | ||||
|         super.last(lastSql); | ||||
|         return this; | ||||
|     } | ||||
|  | ||||
| } | ||||
| @ -1,11 +1,21 @@ | ||||
| package cn.iocoder.dashboard.modules.system.controller.auth; | ||||
|  | ||||
| import cn.iocoder.dashboard.common.enums.CommonStatusEnum; | ||||
| import cn.iocoder.dashboard.common.pojo.CommonResult; | ||||
| import cn.iocoder.dashboard.modules.system.controller.auth.vo.SysAuthMenuRespVO; | ||||
| import cn.iocoder.dashboard.modules.system.controller.auth.vo.SysAuthPermissionInfoRespVO; | ||||
| import cn.iocoder.dashboard.modules.system.controller.auth.vo.SysAuthLoginReqVO; | ||||
| import cn.iocoder.dashboard.modules.system.controller.auth.vo.SysAuthLoginRespVO; | ||||
| import cn.iocoder.dashboard.modules.system.convert.auth.SysAuthConvert; | ||||
| import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.permission.SysMenuDO; | ||||
| import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.permission.SysRoleDO; | ||||
| import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user.SysUserDO; | ||||
| import cn.iocoder.dashboard.modules.system.enums.permission.MenuTypeEnum; | ||||
| import cn.iocoder.dashboard.modules.system.service.auth.SysAuthService; | ||||
| import cn.iocoder.dashboard.modules.system.service.permission.SysPermissionService; | ||||
| import cn.iocoder.dashboard.modules.system.service.permission.SysRoleService; | ||||
| import cn.iocoder.dashboard.modules.system.service.user.SysUserService; | ||||
| import cn.iocoder.dashboard.util.collection.SetUtils; | ||||
| import io.swagger.annotations.Api; | ||||
| import io.swagger.annotations.ApiOperation; | ||||
| import org.springframework.web.bind.annotation.*; | ||||
| @ -26,6 +36,12 @@ public class SysAuthController { | ||||
|  | ||||
|     @Resource | ||||
|     private SysAuthService authService; | ||||
|     @Resource | ||||
|     private SysUserService userService; | ||||
|     @Resource | ||||
|     private SysRoleService roleService; | ||||
|     @Resource | ||||
|     private SysPermissionService permissionService; | ||||
|  | ||||
|     @ApiOperation("使用账号密码登录") | ||||
|     @PostMapping("/login") | ||||
| @ -38,15 +54,30 @@ public class SysAuthController { | ||||
|     @ApiOperation("获取登陆用户的权限信息") | ||||
|     @GetMapping("/get-permission-info") | ||||
|     public CommonResult<SysAuthPermissionInfoRespVO> getPermissionInfo() { | ||||
|         SysAuthPermissionInfoRespVO respVO = authService.getPermissionInfo(getLoginUserId(), getLoginUserRoleIds()); | ||||
|         return success(respVO); | ||||
|         // 获得用户信息 | ||||
|         SysUserDO user = userService.getUser(getLoginUserId()); | ||||
|         if (user == null) { | ||||
|             return null; | ||||
|         } | ||||
|         // 获得角色列表 | ||||
|         List<SysRoleDO> roleList = roleService.listRolesFromCache(getLoginUserRoleIds()); | ||||
|         // 获得菜单列表 | ||||
|         List<SysMenuDO> menuList = permissionService.listRoleMenusFromCache(getLoginUserRoleIds(), | ||||
|                 SetUtils.asSet(MenuTypeEnum.DIR.getType(), MenuTypeEnum.MENU.getType(), MenuTypeEnum.BUTTON.getType()), | ||||
|                 SetUtils.asSet(CommonStatusEnum.ENABLE.getStatus())); | ||||
|         // 拼接结果返回 | ||||
|         return success(SysAuthConvert.INSTANCE.convert(user, roleList, menuList)); | ||||
|     } | ||||
|  | ||||
|     @ApiOperation("获得登陆用户的菜单列表") | ||||
|     @GetMapping("list-menus") | ||||
|     public CommonResult<List<SysAuthMenuRespVO>> listMenus() { | ||||
|         List<SysAuthMenuRespVO> respVOList = authService.listMenus(getLoginUserId(), getLoginUserRoleIds()); | ||||
|         return success(respVOList); | ||||
|         // 获得用户拥有的菜单列表 | ||||
|         List<SysMenuDO> menuList = permissionService.listRoleMenusFromCache(getLoginUserRoleIds(), | ||||
|                 SetUtils.asSet(MenuTypeEnum.DIR.getType(), MenuTypeEnum.MENU.getType()), // 只要目录和菜单类型 | ||||
|                 SetUtils.asSet(CommonStatusEnum.ENABLE.getStatus())); // 只要开启的 | ||||
|         // 转换成 Tree 结构返回 | ||||
|         return success(SysAuthConvert.INSTANCE.buildMenuTree(menuList)); | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -84,8 +84,8 @@ public class SysMenuController { | ||||
|     } | ||||
|  | ||||
|     @ApiOperation("删除菜单") | ||||
|     @PostMapping("/delete") | ||||
| //    @Log(title = "菜单管理", businessType = BusinessType.DELETE) | ||||
| //    @DeleteMapping("/{menuId}") | ||||
|     public CommonResult<Boolean> deleteMenu(@RequestParam("id") Long id) { | ||||
|         menuService.deleteMenu(id); | ||||
|         return success(true); | ||||
|  | ||||
| @ -24,7 +24,7 @@ public class SysMenuBaseVO { | ||||
|     private String permission; | ||||
|  | ||||
|     @ApiModelProperty(value = "类型", required = true, example = "1", notes = "参见 SysMenuTypeEnum 枚举类") | ||||
|     @NotBlank(message = "菜单类型不能为空") | ||||
|     @NotNull(message = "菜单类型不能为空") | ||||
|     private Integer type; | ||||
|  | ||||
|     @ApiModelProperty(value = "显示顺序不能为空", required = true, example = "1024") | ||||
|  | ||||
| @ -2,17 +2,14 @@ package cn.iocoder.dashboard.modules.system.controller.permission.vo; | ||||
|  | ||||
| import io.swagger.annotations.ApiModel; | ||||
| import io.swagger.annotations.ApiModelProperty; | ||||
| import lombok.AllArgsConstructor; | ||||
| import lombok.Builder; | ||||
| import lombok.Data; | ||||
| import lombok.NoArgsConstructor; | ||||
|  | ||||
| @ApiModel("菜单列表 Request VO") | ||||
| @Data | ||||
| public class SysMenuListReqVO { | ||||
|  | ||||
|     @ApiModelProperty(value = "菜单名称", example = "芋道", notes = "模糊匹配") | ||||
|     private String menuName; | ||||
|     private String name; | ||||
|  | ||||
|     @ApiModelProperty(value = "展示状态", example = "1", notes = "参见 SysCommonStatusEnum 枚举类") | ||||
|     private Integer status; | ||||
|  | ||||
| @ -1,10 +1,14 @@ | ||||
| package cn.iocoder.dashboard.modules.system.dal.mysql.dao.permission; | ||||
|  | ||||
| import cn.iocoder.dashboard.framework.mybatis.core.query.QueryWrapperX; | ||||
| import cn.iocoder.dashboard.modules.system.controller.permission.vo.SysMenuListReqVO; | ||||
| import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.permission.SysMenuDO; | ||||
| import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; | ||||
| import com.baomidou.mybatisplus.core.mapper.BaseMapper; | ||||
| import org.apache.ibatis.annotations.Mapper; | ||||
|  | ||||
| import java.util.List; | ||||
|  | ||||
| @Mapper | ||||
| public interface SysMenuMapper extends BaseMapper<SysMenuDO> { | ||||
|  | ||||
| @ -17,4 +21,13 @@ public interface SysMenuMapper extends BaseMapper<SysMenuDO> { | ||||
|         return selectCount(new QueryWrapper<SysMenuDO>().eq("parent_id", parentId)); | ||||
|     } | ||||
|  | ||||
|     default List<SysMenuDO> selectList(SysMenuListReqVO reqVO) { | ||||
|         return selectList(new QueryWrapperX<SysMenuDO>().likeIfPresent("name", reqVO.getName()) | ||||
|             .eqIfPresent("status", reqVO.getStatus())); | ||||
|     } | ||||
|  | ||||
|     default List<SysMenuDO> selectList() { | ||||
|         return selectList(new QueryWrapper<>()); | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| package cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.dept; | ||||
|  | ||||
| import cn.iocoder.dashboard.framework.mybatis.core.BaseDO; | ||||
| import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO; | ||||
|  | ||||
| import javax.validation.constraints.Email; | ||||
| import javax.validation.constraints.NotBlank; | ||||
|  | ||||
| @ -2,7 +2,7 @@ package cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.dict; | ||||
|  | ||||
| import cn.iocoder.dashboard.common.enums.CommonStatusEnum; | ||||
| import cn.iocoder.dashboard.framework.excel.Excel; | ||||
| import cn.iocoder.dashboard.framework.mybatis.core.BaseDO; | ||||
| import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO; | ||||
| import com.baomidou.mybatisplus.annotation.TableId; | ||||
| import com.baomidou.mybatisplus.annotation.TableName; | ||||
| import lombok.Data; | ||||
|  | ||||
| @ -2,7 +2,7 @@ package cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.dict; | ||||
|  | ||||
| import cn.iocoder.dashboard.common.enums.CommonStatusEnum; | ||||
| import cn.iocoder.dashboard.framework.excel.Excel; | ||||
| import cn.iocoder.dashboard.framework.mybatis.core.BaseDO; | ||||
| import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO; | ||||
| import com.baomidou.mybatisplus.annotation.TableField; | ||||
| import com.baomidou.mybatisplus.annotation.TableId; | ||||
| import com.baomidou.mybatisplus.annotation.TableName; | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| package cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.permission; | ||||
|  | ||||
| import cn.iocoder.dashboard.common.enums.CommonStatusEnum; | ||||
| import cn.iocoder.dashboard.framework.mybatis.core.BaseDO; | ||||
| import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO; | ||||
| import cn.iocoder.dashboard.modules.system.enums.permission.MenuTypeEnum; | ||||
| import com.baomidou.mybatisplus.annotation.TableField; | ||||
| import com.baomidou.mybatisplus.annotation.TableId; | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| package cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.permission; | ||||
|  | ||||
| import cn.iocoder.dashboard.framework.excel.Excel; | ||||
| import cn.iocoder.dashboard.framework.mybatis.core.BaseDO; | ||||
| import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO; | ||||
| import com.baomidou.mybatisplus.annotation.TableField; | ||||
| import com.baomidou.mybatisplus.annotation.TableId; | ||||
| import com.baomidou.mybatisplus.annotation.TableName; | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| package cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.permission; | ||||
|  | ||||
| import cn.iocoder.dashboard.framework.mybatis.core.BaseDO; | ||||
| import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO; | ||||
| import com.baomidou.mybatisplus.annotation.TableId; | ||||
| import com.baomidou.mybatisplus.annotation.TableName; | ||||
| import lombok.Data; | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| package cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.permission; | ||||
|  | ||||
| import cn.iocoder.dashboard.framework.mybatis.core.BaseDO; | ||||
| import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO; | ||||
| import com.baomidou.mybatisplus.annotation.TableId; | ||||
| import com.baomidou.mybatisplus.annotation.TableName; | ||||
| import lombok.Data; | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| package cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.permission; | ||||
|  | ||||
| import cn.iocoder.dashboard.framework.mybatis.core.BaseDO; | ||||
| import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO; | ||||
| import com.baomidou.mybatisplus.annotation.TableId; | ||||
| import com.baomidou.mybatisplus.annotation.TableName; | ||||
| import lombok.Data; | ||||
|  | ||||
| @ -2,7 +2,7 @@ package cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user; | ||||
|  | ||||
| import cn.iocoder.dashboard.framework.excel.Excel; | ||||
| import cn.iocoder.dashboard.framework.excel.Excels; | ||||
| import cn.iocoder.dashboard.framework.mybatis.core.BaseDO; | ||||
| import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO; | ||||
| import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.dept.SysDept; | ||||
| import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.permission.SysRoleDO; | ||||
| import com.baomidou.mybatisplus.annotation.TableField; | ||||
|  | ||||
| @ -24,6 +24,6 @@ public interface SysErrorCodeConstants { | ||||
|     ErrorCode MENU_PARENT_ERROR = new ErrorCode(1002002002, "不能设置自己为父菜单"); | ||||
|     ErrorCode MENU_NOT_EXISTS = new ErrorCode(1002002003, "菜单不存在"); | ||||
|     ErrorCode MENU_EXISTS_CHILDREN = new ErrorCode(1002002004, "存在子菜单,无法删除"); | ||||
|     ErrorCode MENU_PARENT_NOT_MENU = new ErrorCode(1002002005, "父菜单的类型必须是菜单"); | ||||
|     ErrorCode MENU_PARENT_NOT_DIR_OR_MENU = new ErrorCode(1002002005, "父菜单的类型必须是目录或者菜单"); | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -1,11 +1,6 @@ | ||||
| package cn.iocoder.dashboard.modules.system.service.auth; | ||||
|  | ||||
| import cn.iocoder.dashboard.framework.security.core.service.SecurityFrameworkService; | ||||
| import cn.iocoder.dashboard.modules.system.controller.auth.vo.SysAuthPermissionInfoRespVO; | ||||
| import cn.iocoder.dashboard.modules.system.controller.auth.vo.SysAuthMenuRespVO; | ||||
|  | ||||
| import java.util.List; | ||||
| import java.util.Set; | ||||
|  | ||||
| /** | ||||
|  * 认证 Service 接口 | ||||
| @ -18,28 +13,4 @@ public interface SysAuthService extends SecurityFrameworkService { | ||||
|  | ||||
|     String login(String username, String password, String captchaUUID, String captchaCode); | ||||
|  | ||||
|     /** | ||||
|      * 获得用户的基本信息 | ||||
|      * | ||||
|      * 这里传输 roleIds 参数的原因,是该参数是从 LoginUser 缓存中获取到的,而我们校验权限时也是从 LoginUser 缓存中获取 roleIds | ||||
|      * 通过这样的方式,保持一致 | ||||
|      * | ||||
|      * @param userId 用户编号 | ||||
|      * @param roleIds 用户拥有的角色编号数组 | ||||
|      * @return 用户的信息,包括角色权限和菜单权限 | ||||
|      */ | ||||
|     SysAuthPermissionInfoRespVO getPermissionInfo(Long userId, Set<Long> roleIds); | ||||
|  | ||||
|     /** | ||||
|      * 获得用户的菜单 Vue 路由 | ||||
|      * | ||||
|      * 这里传输 roleIds 参数的原因,是该参数是从 LoginUser 缓存中获取到的,而我们校验权限时也是从 LoginUser 缓存中获取 roleIds | ||||
|      * 通过这样的方式,保持一致 | ||||
|      * | ||||
|      * @param userId 用户编号 | ||||
|      * @param roleIds 用户拥有的角色编号数组 | ||||
|      * @return 菜单 Vue 路由 | ||||
|      */ | ||||
|     List<SysAuthMenuRespVO> listMenus(Long userId, Set<Long> roleIds); | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -226,31 +226,4 @@ public class SysAuthServiceImpl implements SysAuthService { | ||||
|         loginUserRedisDAO.set(sessionId, loginUser); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public SysAuthPermissionInfoRespVO getPermissionInfo(Long userId, Set<Long> roleIds) { | ||||
|         // 获得用户信息 | ||||
|         SysUserDO user = userService.getUser(userId); | ||||
|         if (user == null) { | ||||
|             return null; | ||||
|         } | ||||
|         // 获得角色列表 | ||||
|         List<SysRoleDO> roleList = roleService.listRolesFromCache(roleIds); | ||||
|         // 获得菜单列表 | ||||
|         List<SysMenuDO> menuList = permissionService.listRoleMenusFromCache(roleIds, | ||||
|                 SetUtils.asSet(MenuTypeEnum.DIR.getType(), MenuTypeEnum.MENU.getType(), MenuTypeEnum.BUTTON.getType()), | ||||
|                 SetUtils.asSet(CommonStatusEnum.ENABLE.getStatus())); | ||||
|         // 拼接结果返回 | ||||
|         return SysAuthConvert.INSTANCE.convert(user, roleList, menuList); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public List<SysAuthMenuRespVO> listMenus(Long userId, Set<Long> roleIds) { | ||||
|         // 获得用户拥有的菜单列表 | ||||
|         List<SysMenuDO> menuList = permissionService.listRoleMenusFromCache(roleIds, | ||||
|                 SetUtils.asSet(MenuTypeEnum.DIR.getType(), MenuTypeEnum.MENU.getType()), // 只要目录和菜单类型 | ||||
|                 SetUtils.asSet(CommonStatusEnum.ENABLE.getStatus())); // 只要开启的 | ||||
|         // 转换成 Tree 结构返回 | ||||
|         return SysAuthConvert.INSTANCE.buildMenuTree(menuList); | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -65,7 +65,7 @@ public class SysMenuServiceImpl implements SysMenuService { | ||||
|     @Override | ||||
|     @PostConstruct | ||||
|     public void init() { | ||||
|         List<SysMenuDO> menuList = menuMapper.selectList(null); | ||||
|         List<SysMenuDO> menuList = menuMapper.selectList(); | ||||
|         ImmutableMap.Builder<Long, SysMenuDO> menuCacheBuilder = ImmutableMap.builder(); | ||||
|         ImmutableMultimap.Builder<String, SysMenuDO> permMenuCacheBuilder = ImmutableMultimap.builder(); | ||||
|         menuList.forEach(menuDO -> { | ||||
| @ -79,7 +79,7 @@ public class SysMenuServiceImpl implements SysMenuService { | ||||
|  | ||||
|     @Override | ||||
|     public List<SysMenuRespVO> listMenus(SysMenuListReqVO reqVO) { | ||||
|         List<SysMenuDO> list = menuMapper.selectList(null); | ||||
|         List<SysMenuDO> list = menuMapper.selectList(reqVO); | ||||
|         // TODO 排序 | ||||
|         return SysMenuConvert.INSTANCE.convertList(list); | ||||
|     } | ||||
| @ -240,9 +240,10 @@ public class SysMenuServiceImpl implements SysMenuService { | ||||
|         if (menu == null) { | ||||
|             throw ServiceExceptionUtil.exception(MENU_PARENT_NOT_EXISTS); | ||||
|         } | ||||
|         // 父菜单必须是目录类型 | ||||
|         if (!MenuTypeEnum.DIR.getType().equals(menu.getType())) { | ||||
|             throw ServiceExceptionUtil.exception(MENU_PARENT_NOT_MENU); | ||||
|         // 父菜单必须是目录或者菜单类型 | ||||
|         if (!MenuTypeEnum.DIR.getType().equals(menu.getType()) | ||||
|             && !MenuTypeEnum.MENU.getType().equals(menu.getType())) { | ||||
|             throw ServiceExceptionUtil.exception(MENU_PARENT_NOT_DIR_OR_MENU); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|  | ||||
| @ -38,3 +38,15 @@ yudao: | ||||
|     timeout: 5m | ||||
|     width: 160 | ||||
|     height: 60 | ||||
|  | ||||
| # MyBatis Plus 的配置项 | ||||
| mybatis-plus: | ||||
|   configuration: | ||||
|     map-underscore-to-camel-case: true # 虽然默认为 true ,但是还是显示去指定下。 | ||||
|   global-config: | ||||
|     db-config: | ||||
|       id-type: auto # 自增 ID | ||||
|       logic-delete-value: 1 # 逻辑已删除值(默认为 1) | ||||
|       logic-not-delete-value: 0 # 逻辑未删除值(默认为 0) | ||||
|   mapper-locations: classpath*:mapper/*.xml | ||||
|   type-aliases-package: cn.iocoder.dashboard.modules.*.dal.mysql.dataobject | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 YunaiV
					YunaiV