Commit cf93019ce123bcaeefd471c0052814bd795f554b
1 parent
162bebf5
增加 get-routers 接口的相关方法,未完全完成
Showing
11 changed files
with
181 additions
and
22 deletions
ruoyi-ui/src/api/login.js
| @@ -18,7 +18,7 @@ export function login(username, password, code, uuid) { | @@ -18,7 +18,7 @@ export function login(username, password, code, uuid) { | ||
| 18 | // 获取用户详细信息 | 18 | // 获取用户详细信息 |
| 19 | export function getInfo() { | 19 | export function getInfo() { |
| 20 | return request({ | 20 | return request({ |
| 21 | - url: '/getInfo', | 21 | + url: '/get-info', |
| 22 | method: 'get' | 22 | method: 'get' |
| 23 | }) | 23 | }) |
| 24 | } | 24 | } |
ruoyi-ui/src/api/menu.js
| @@ -3,7 +3,7 @@ import request from '@/utils/request' | @@ -3,7 +3,7 @@ import request from '@/utils/request' | ||
| 3 | // 获取路由 | 3 | // 获取路由 |
| 4 | export const getRouters = () => { | 4 | export const getRouters = () => { |
| 5 | return request({ | 5 | return request({ |
| 6 | - url: '/getRouters', | 6 | + url: '/get-routers', |
| 7 | method: 'get' | 7 | method: 'get' |
| 8 | }) | 8 | }) |
| 9 | -} | ||
| 10 | \ No newline at end of file | 9 | \ No newline at end of file |
| 10 | +} |
src/main/java/cn/iocoder/dashboard/modules/system/controller/auth/SysAuthController.http
| @@ -13,6 +13,10 @@ Content-Type: application/json | @@ -13,6 +13,10 @@ Content-Type: application/json | ||
| 13 | GET {{baseUrl}}/get-info | 13 | GET {{baseUrl}}/get-info |
| 14 | Authorization: Bearer {{token}} | 14 | Authorization: Bearer {{token}} |
| 15 | 15 | ||
| 16 | +### 请求 /get-routers 接口 => 成功 | ||
| 17 | +GET {{baseUrl}}/get-routers | ||
| 18 | +Authorization: Bearer {{token}} | ||
| 19 | + | ||
| 16 | ### 请求 /druid/xxx 接口 => 失败 TODO 临时测试 | 20 | ### 请求 /druid/xxx 接口 => 失败 TODO 临时测试 |
| 17 | GET http://127.0.0.1:8080/druid/123 | 21 | GET http://127.0.0.1:8080/druid/123 |
| 18 | Authorization: Bearer {{token}} | 22 | Authorization: Bearer {{token}} |
src/main/java/cn/iocoder/dashboard/modules/system/controller/auth/SysAuthController.java
| @@ -2,6 +2,7 @@ package cn.iocoder.dashboard.modules.system.controller.auth; | @@ -2,6 +2,7 @@ package cn.iocoder.dashboard.modules.system.controller.auth; | ||
| 2 | 2 | ||
| 3 | import cn.iocoder.dashboard.common.pojo.CommonResult; | 3 | import cn.iocoder.dashboard.common.pojo.CommonResult; |
| 4 | import cn.iocoder.dashboard.modules.system.controller.auth.vo.SysAuthGetInfoRespVO; | 4 | import cn.iocoder.dashboard.modules.system.controller.auth.vo.SysAuthGetInfoRespVO; |
| 5 | +import cn.iocoder.dashboard.modules.system.controller.auth.vo.SysAuthGetRouterRespVO; | ||
| 5 | import cn.iocoder.dashboard.modules.system.controller.auth.vo.SysAuthLoginReqVO; | 6 | import cn.iocoder.dashboard.modules.system.controller.auth.vo.SysAuthLoginReqVO; |
| 6 | import cn.iocoder.dashboard.modules.system.controller.auth.vo.SysAuthLoginRespVO; | 7 | import cn.iocoder.dashboard.modules.system.controller.auth.vo.SysAuthLoginRespVO; |
| 7 | import cn.iocoder.dashboard.modules.system.service.auth.SysAuthService; | 8 | import cn.iocoder.dashboard.modules.system.service.auth.SysAuthService; |
| @@ -12,6 +13,8 @@ import org.springframework.web.bind.annotation.*; | @@ -12,6 +13,8 @@ import org.springframework.web.bind.annotation.*; | ||
| 12 | import javax.annotation.Resource; | 13 | import javax.annotation.Resource; |
| 13 | import javax.validation.Valid; | 14 | import javax.validation.Valid; |
| 14 | 15 | ||
| 16 | +import java.util.List; | ||
| 17 | + | ||
| 15 | import static cn.iocoder.dashboard.common.pojo.CommonResult.success; | 18 | import static cn.iocoder.dashboard.common.pojo.CommonResult.success; |
| 16 | import static cn.iocoder.dashboard.framework.security.core.util.SecurityUtils.getLoginUserId; | 19 | import static cn.iocoder.dashboard.framework.security.core.util.SecurityUtils.getLoginUserId; |
| 17 | import static cn.iocoder.dashboard.framework.security.core.util.SecurityUtils.getLoginUserRoleIds; | 20 | import static cn.iocoder.dashboard.framework.security.core.util.SecurityUtils.getLoginUserRoleIds; |
| @@ -39,4 +42,11 @@ public class SysAuthController { | @@ -39,4 +42,11 @@ public class SysAuthController { | ||
| 39 | return success(respVO); | 42 | return success(respVO); |
| 40 | } | 43 | } |
| 41 | 44 | ||
| 45 | + @ApiOperation("获得菜单 Vue 路由") | ||
| 46 | + @GetMapping("get-routers") | ||
| 47 | + public CommonResult<List<SysAuthGetRouterRespVO>> getRouters() { | ||
| 48 | + List<SysAuthGetRouterRespVO> respVOList = authService.getRouters(getLoginUserId(), getLoginUserRoleIds()); | ||
| 49 | + return success(respVOList); | ||
| 50 | + } | ||
| 51 | + | ||
| 42 | } | 52 | } |
src/main/java/cn/iocoder/dashboard/modules/system/controller/auth/vo/SysAuthGetRouterRespVO.java
0 → 100644
| 1 | +package cn.iocoder.dashboard.modules.system.controller.auth.vo; | ||
| 2 | + | ||
| 3 | +import lombok.Data; | ||
| 4 | + | ||
| 5 | +import java.util.List; | ||
| 6 | + | ||
| 7 | +/** | ||
| 8 | + * 路由配置信息 | ||
| 9 | + * | ||
| 10 | + * @author ruoyi | ||
| 11 | + */ | ||
| 12 | +@Data | ||
| 13 | +public class SysAuthGetRouterRespVO { | ||
| 14 | + | ||
| 15 | + /** | ||
| 16 | + * 菜单编号 | ||
| 17 | + */ | ||
| 18 | + private Long menuId; | ||
| 19 | + /** | ||
| 20 | + * 父菜单编号 | ||
| 21 | + */ | ||
| 22 | + private Long parentId; | ||
| 23 | + | ||
| 24 | + /** | ||
| 25 | + * 路由名字 | ||
| 26 | + */ | ||
| 27 | + private String name; | ||
| 28 | + | ||
| 29 | + /** | ||
| 30 | + * 路由地址 | ||
| 31 | + */ | ||
| 32 | + private String path; | ||
| 33 | + | ||
| 34 | + /** | ||
| 35 | + * 是否隐藏路由,当设置 true 的时候该路由不会再侧边栏出现 | ||
| 36 | + */ | ||
| 37 | + private boolean hidden; | ||
| 38 | + | ||
| 39 | + /** | ||
| 40 | + * 重定向地址,当设置 noRedirect 的时候该路由在面包屑导航中不可被点击 | ||
| 41 | + */ | ||
| 42 | + private String redirect; | ||
| 43 | + | ||
| 44 | + /** | ||
| 45 | + * 组件地址 | ||
| 46 | + */ | ||
| 47 | + private String component; | ||
| 48 | + | ||
| 49 | + /** | ||
| 50 | + * 当你一个路由下面的 children 声明的路由大于1个时,自动会变成嵌套的模式--如组件页面 | ||
| 51 | + */ | ||
| 52 | + private Boolean alwaysShow; | ||
| 53 | + | ||
| 54 | + /** | ||
| 55 | + * 其他元素 | ||
| 56 | + */ | ||
| 57 | + private MetaVO meta; | ||
| 58 | + | ||
| 59 | + /** | ||
| 60 | + * 子路由 | ||
| 61 | + */ | ||
| 62 | + private List<SysAuthGetRouterRespVO> children; | ||
| 63 | + | ||
| 64 | + @Data | ||
| 65 | + public static class MetaVO { | ||
| 66 | + | ||
| 67 | + /** | ||
| 68 | + * 设置该路由在侧边栏和面包屑中展示的名字 | ||
| 69 | + */ | ||
| 70 | + private String title; | ||
| 71 | + | ||
| 72 | + /** | ||
| 73 | + * 设置该路由的图标,对应路径src/assets/icons/svg | ||
| 74 | + */ | ||
| 75 | + private String icon; | ||
| 76 | + | ||
| 77 | + /** | ||
| 78 | + * 设置为true,则不会被 <keep-alive>缓存 | ||
| 79 | + */ | ||
| 80 | + private boolean noCache; | ||
| 81 | + | ||
| 82 | + } | ||
| 83 | + | ||
| 84 | +} |
src/main/java/cn/iocoder/dashboard/modules/system/convert/auth/SysAuthConvert.java
| @@ -2,6 +2,7 @@ package cn.iocoder.dashboard.modules.system.convert.auth; | @@ -2,6 +2,7 @@ package cn.iocoder.dashboard.modules.system.convert.auth; | ||
| 2 | 2 | ||
| 3 | import cn.iocoder.dashboard.framework.security.core.LoginUser; | 3 | import cn.iocoder.dashboard.framework.security.core.LoginUser; |
| 4 | import cn.iocoder.dashboard.modules.system.controller.auth.vo.SysAuthGetInfoRespVO; | 4 | import cn.iocoder.dashboard.modules.system.controller.auth.vo.SysAuthGetInfoRespVO; |
| 5 | +import cn.iocoder.dashboard.modules.system.controller.auth.vo.SysAuthGetRouterRespVO; | ||
| 5 | import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.permission.SysMenuDO; | 6 | import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.permission.SysMenuDO; |
| 6 | import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.permission.SysRoleDO; | 7 | import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.permission.SysRoleDO; |
| 7 | import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user.SysUserDO; | 8 | import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user.SysUserDO; |
| @@ -27,4 +28,6 @@ public interface SysAuthConvert { | @@ -27,4 +28,6 @@ public interface SysAuthConvert { | ||
| 27 | return respVO; | 28 | return respVO; |
| 28 | } | 29 | } |
| 29 | 30 | ||
| 31 | + SysAuthGetRouterRespVO convertTreeNode(SysMenuDO menu); | ||
| 32 | + | ||
| 30 | } | 33 | } |
src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dataobject/permission/SysMenuDO.java
| 1 | package cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.permission; | 1 | package cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.permission; |
| 2 | 2 | ||
| 3 | import cn.iocoder.dashboard.framework.mybatis.core.BaseDO; | 3 | import cn.iocoder.dashboard.framework.mybatis.core.BaseDO; |
| 4 | -import com.baomidou.mybatisplus.annotation.TableField; | ||
| 5 | import com.baomidou.mybatisplus.annotation.TableId; | 4 | import com.baomidou.mybatisplus.annotation.TableId; |
| 6 | import com.baomidou.mybatisplus.annotation.TableName; | 5 | import com.baomidou.mybatisplus.annotation.TableName; |
| 7 | import lombok.Data; | 6 | import lombok.Data; |
| @@ -9,8 +8,6 @@ import lombok.EqualsAndHashCode; | @@ -9,8 +8,6 @@ import lombok.EqualsAndHashCode; | ||
| 9 | 8 | ||
| 10 | import javax.validation.constraints.NotBlank; | 9 | import javax.validation.constraints.NotBlank; |
| 11 | import javax.validation.constraints.Size; | 10 | import javax.validation.constraints.Size; |
| 12 | -import java.util.ArrayList; | ||
| 13 | -import java.util.List; | ||
| 14 | 11 | ||
| 15 | /** | 12 | /** |
| 16 | * 菜单权限表 | 13 | * 菜单权限表 |
| @@ -95,18 +92,4 @@ public class SysMenuDO extends BaseDO { | @@ -95,18 +92,4 @@ public class SysMenuDO extends BaseDO { | ||
| 95 | */ | 92 | */ |
| 96 | private String icon; | 93 | private String icon; |
| 97 | 94 | ||
| 98 | - // TODO 芋艿:非存储字段,需要提出 | ||
| 99 | - | ||
| 100 | - /** | ||
| 101 | - * 父菜单名称 | ||
| 102 | - */ | ||
| 103 | - @TableField(exist = false) | ||
| 104 | - private String parentName; | ||
| 105 | - | ||
| 106 | - /** | ||
| 107 | - * 子菜单 | ||
| 108 | - */ | ||
| 109 | - @TableField(exist = false) | ||
| 110 | - private List<SysMenuDO> children = new ArrayList<SysMenuDO>(); | ||
| 111 | - | ||
| 112 | } | 95 | } |
src/main/java/cn/iocoder/dashboard/modules/system/enums/permission/MenuIdEnum.java
0 → 100644
| 1 | +package cn.iocoder.dashboard.modules.system.enums.permission; | ||
| 2 | + | ||
| 3 | +import lombok.AllArgsConstructor; | ||
| 4 | +import lombok.Getter; | ||
| 5 | + | ||
| 6 | +/** | ||
| 7 | + * Menu 编号枚举 | ||
| 8 | + */ | ||
| 9 | +@Getter | ||
| 10 | +@AllArgsConstructor | ||
| 11 | +public enum MenuIdEnum { | ||
| 12 | + | ||
| 13 | + /** | ||
| 14 | + * 根节点 | ||
| 15 | + */ | ||
| 16 | + ROOT(0L); | ||
| 17 | + | ||
| 18 | + private final Long id; | ||
| 19 | + | ||
| 20 | +} |
src/main/java/cn/iocoder/dashboard/modules/system/service/auth/SysAuthService.java
| @@ -2,7 +2,9 @@ package cn.iocoder.dashboard.modules.system.service.auth; | @@ -2,7 +2,9 @@ package cn.iocoder.dashboard.modules.system.service.auth; | ||
| 2 | 2 | ||
| 3 | import cn.iocoder.dashboard.framework.security.core.service.SecurityFrameworkService; | 3 | import cn.iocoder.dashboard.framework.security.core.service.SecurityFrameworkService; |
| 4 | import cn.iocoder.dashboard.modules.system.controller.auth.vo.SysAuthGetInfoRespVO; | 4 | import cn.iocoder.dashboard.modules.system.controller.auth.vo.SysAuthGetInfoRespVO; |
| 5 | +import cn.iocoder.dashboard.modules.system.controller.auth.vo.SysAuthGetRouterRespVO; | ||
| 5 | 6 | ||
| 7 | +import java.util.List; | ||
| 6 | import java.util.Set; | 8 | import java.util.Set; |
| 7 | 9 | ||
| 8 | /** | 10 | /** |
| @@ -28,4 +30,16 @@ public interface SysAuthService extends SecurityFrameworkService { | @@ -28,4 +30,16 @@ public interface SysAuthService extends SecurityFrameworkService { | ||
| 28 | */ | 30 | */ |
| 29 | SysAuthGetInfoRespVO getInfo(Long userId, Set<Long> roleIds); | 31 | SysAuthGetInfoRespVO getInfo(Long userId, Set<Long> roleIds); |
| 30 | 32 | ||
| 33 | + /** | ||
| 34 | + * 获得用户的菜单 Vue 路由 | ||
| 35 | + * | ||
| 36 | + * 这里传输 roleIds 参数的原因,是该参数是从 LoginUser 缓存中获取到的,而我们校验权限时也是从 LoginUser 缓存中获取 roleIds | ||
| 37 | + * 通过这样的方式,保持一致 | ||
| 38 | + * | ||
| 39 | + * @param userId 用户编号 | ||
| 40 | + * @param roleIds 用户拥有的角色编号数组 | ||
| 41 | + * @return 菜单 Vue 路由 | ||
| 42 | + */ | ||
| 43 | + List<SysAuthGetRouterRespVO> getRouters(Long userId, Set<Long> roleIds); | ||
| 44 | + | ||
| 31 | } | 45 | } |
src/main/java/cn/iocoder/dashboard/modules/system/service/auth/impl/SysAuthServiceImpl.java
| @@ -5,12 +5,14 @@ import cn.hutool.core.util.StrUtil; | @@ -5,12 +5,14 @@ import cn.hutool.core.util.StrUtil; | ||
| 5 | import cn.iocoder.dashboard.framework.security.config.SecurityProperties; | 5 | import cn.iocoder.dashboard.framework.security.config.SecurityProperties; |
| 6 | import cn.iocoder.dashboard.framework.security.core.LoginUser; | 6 | import cn.iocoder.dashboard.framework.security.core.LoginUser; |
| 7 | import cn.iocoder.dashboard.modules.system.controller.auth.vo.SysAuthGetInfoRespVO; | 7 | import cn.iocoder.dashboard.modules.system.controller.auth.vo.SysAuthGetInfoRespVO; |
| 8 | +import cn.iocoder.dashboard.modules.system.controller.auth.vo.SysAuthGetRouterRespVO; | ||
| 9 | +import cn.iocoder.dashboard.modules.system.convert.auth.SysAuthConvert; | ||
| 8 | import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.permission.SysMenuDO; | 10 | import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.permission.SysMenuDO; |
| 9 | import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.permission.SysRoleDO; | 11 | import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.permission.SysRoleDO; |
| 10 | -import cn.iocoder.dashboard.modules.system.enums.user.UserStatus; | ||
| 11 | -import cn.iocoder.dashboard.modules.system.convert.auth.SysAuthConvert; | ||
| 12 | import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user.SysUserDO; | 12 | import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user.SysUserDO; |
| 13 | import cn.iocoder.dashboard.modules.system.dal.redis.dao.auth.SysLoginUserRedisDAO; | 13 | import cn.iocoder.dashboard.modules.system.dal.redis.dao.auth.SysLoginUserRedisDAO; |
| 14 | +import cn.iocoder.dashboard.modules.system.enums.permission.MenuIdEnum; | ||
| 15 | +import cn.iocoder.dashboard.modules.system.enums.user.UserStatus; | ||
| 14 | import cn.iocoder.dashboard.modules.system.service.auth.SysAuthService; | 16 | import cn.iocoder.dashboard.modules.system.service.auth.SysAuthService; |
| 15 | import cn.iocoder.dashboard.modules.system.service.auth.SysTokenService; | 17 | import cn.iocoder.dashboard.modules.system.service.auth.SysTokenService; |
| 16 | import cn.iocoder.dashboard.modules.system.service.permission.SysPermissionService; | 18 | import cn.iocoder.dashboard.modules.system.service.permission.SysPermissionService; |
| @@ -234,4 +236,38 @@ public class SysAuthServiceImpl implements SysAuthService { | @@ -234,4 +236,38 @@ public class SysAuthServiceImpl implements SysAuthService { | ||
| 234 | return SysAuthConvert.INSTANCE.convert(user, roleList, menuList); | 236 | return SysAuthConvert.INSTANCE.convert(user, roleList, menuList); |
| 235 | } | 237 | } |
| 236 | 238 | ||
| 239 | + @Override | ||
| 240 | + public List<SysAuthGetRouterRespVO> getRouters(Long userId, Set<Long> roleIds) { | ||
| 241 | + // TODO 芋艿:去除 F 的类型,去除 禁用 的 | ||
| 242 | + List<SysMenuDO> menuList = permissionService.listRoleMenusFromCache(roleIds); | ||
| 243 | + // 转换成 Tree 结构返回 | ||
| 244 | + return buildRouterTree(menuList); | ||
| 245 | + } | ||
| 246 | + | ||
| 247 | + private static List<SysAuthGetRouterRespVO> buildRouterTree(List<SysMenuDO> menuList) { | ||
| 248 | + // 排序,保证菜单的有序性 | ||
| 249 | + menuList = new ArrayList<>(menuList); // 使用 ArrayList 套一下,因为 menuList 是不可修改的 List | ||
| 250 | + menuList.sort(Comparator.comparing(SysMenuDO::getOrderNum)); | ||
| 251 | + // 构建菜单树 | ||
| 252 | + // 使用 LinkedHashMap 的原因,是为了排序 。实际也可以用 Stream API ,就是太丑了。 | ||
| 253 | + Map<Long, SysAuthGetRouterRespVO> treeNodeMap = new LinkedHashMap<>(); | ||
| 254 | + menuList.forEach(menu -> treeNodeMap.put(menu.getMenuId(), SysAuthConvert.INSTANCE.convertTreeNode(menu))); | ||
| 255 | + // 处理父子关系 | ||
| 256 | + treeNodeMap.values().stream().filter(node -> !node.getParentId().equals(MenuIdEnum.ROOT.getId())).forEach((childNode) -> { | ||
| 257 | + // 获得父节点 | ||
| 258 | + SysAuthGetRouterRespVO parentNode = treeNodeMap.get(childNode.getParentId()); | ||
| 259 | + if (parentNode == null) { | ||
| 260 | + log.error("[buildRouterTree][resource({}) 找不到父资源({})]", childNode.getMenuId(), childNode.getParentId()); | ||
| 261 | + return; | ||
| 262 | + } | ||
| 263 | + // 将自己添加到父节点中 | ||
| 264 | + if (parentNode.getChildren() == null) { | ||
| 265 | + parentNode.setChildren(new ArrayList<>()); | ||
| 266 | + } | ||
| 267 | + parentNode.getChildren().add(childNode); | ||
| 268 | + }); | ||
| 269 | + // 获得到所有的根节点 | ||
| 270 | + return CollectionUtils.filterList(treeNodeMap.values(), node -> MenuIdEnum.ROOT.getId().equals(node.getParentId())); | ||
| 271 | + } | ||
| 272 | + | ||
| 237 | } | 273 | } |
src/main/java/cn/iocoder/dashboard/util/collection/CollectionUtils.java
| @@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollectionUtil; | @@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollectionUtil; | ||
| 4 | 4 | ||
| 5 | import java.util.*; | 5 | import java.util.*; |
| 6 | import java.util.function.Function; | 6 | import java.util.function.Function; |
| 7 | +import java.util.function.Predicate; | ||
| 7 | import java.util.stream.Collectors; | 8 | import java.util.stream.Collectors; |
| 8 | 9 | ||
| 9 | /** | 10 | /** |
| @@ -17,6 +18,10 @@ public class CollectionUtils { | @@ -17,6 +18,10 @@ public class CollectionUtils { | ||
| 17 | return new HashSet<>(Arrays.asList(objs)); | 18 | return new HashSet<>(Arrays.asList(objs)); |
| 18 | } | 19 | } |
| 19 | 20 | ||
| 21 | + public static <T> List<T> filterList(Collection<T> from, Predicate<T> predicate) { | ||
| 22 | + return from.stream().filter(predicate).collect(Collectors.toList()); | ||
| 23 | + } | ||
| 24 | + | ||
| 20 | public static <T, U> List<U> convertList(List<T> from, Function<T, U> func) { | 25 | public static <T, U> List<U> convertList(List<T> from, Function<T, U> func) { |
| 21 | return from.stream().map(func).collect(Collectors.toList()); | 26 | return from.stream().map(func).collect(Collectors.toList()); |
| 22 | } | 27 | } |