增加 get-routers 接口的相关方法,未完全完成
parent
162bebf5fb
commit
cf93019ce1
|
@ -18,7 +18,7 @@ export function login(username, password, code, uuid) {
|
|||
// 获取用户详细信息
|
||||
export function getInfo() {
|
||||
return request({
|
||||
url: '/getInfo',
|
||||
url: '/get-info',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ import request from '@/utils/request'
|
|||
// 获取路由
|
||||
export const getRouters = () => {
|
||||
return request({
|
||||
url: '/getRouters',
|
||||
url: '/get-routers',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
|
@ -13,6 +13,10 @@ Content-Type: application/json
|
|||
GET {{baseUrl}}/get-info
|
||||
Authorization: Bearer {{token}}
|
||||
|
||||
### 请求 /get-routers 接口 => 成功
|
||||
GET {{baseUrl}}/get-routers
|
||||
Authorization: Bearer {{token}}
|
||||
|
||||
### 请求 /druid/xxx 接口 => 失败 TODO 临时测试
|
||||
GET http://127.0.0.1:8080/druid/123
|
||||
Authorization: Bearer {{token}}
|
||||
|
|
|
@ -2,6 +2,7 @@ package cn.iocoder.dashboard.modules.system.controller.auth;
|
|||
|
||||
import cn.iocoder.dashboard.common.pojo.CommonResult;
|
||||
import cn.iocoder.dashboard.modules.system.controller.auth.vo.SysAuthGetInfoRespVO;
|
||||
import cn.iocoder.dashboard.modules.system.controller.auth.vo.SysAuthGetRouterRespVO;
|
||||
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.service.auth.SysAuthService;
|
||||
|
@ -12,6 +13,8 @@ import org.springframework.web.bind.annotation.*;
|
|||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.dashboard.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.dashboard.framework.security.core.util.SecurityUtils.getLoginUserId;
|
||||
import static cn.iocoder.dashboard.framework.security.core.util.SecurityUtils.getLoginUserRoleIds;
|
||||
|
@ -39,4 +42,11 @@ public class SysAuthController {
|
|||
return success(respVO);
|
||||
}
|
||||
|
||||
@ApiOperation("获得菜单 Vue 路由")
|
||||
@GetMapping("get-routers")
|
||||
public CommonResult<List<SysAuthGetRouterRespVO>> getRouters() {
|
||||
List<SysAuthGetRouterRespVO> respVOList = authService.getRouters(getLoginUserId(), getLoginUserRoleIds());
|
||||
return success(respVOList);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
package cn.iocoder.dashboard.modules.system.controller.auth.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 路由配置信息
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Data
|
||||
public class SysAuthGetRouterRespVO {
|
||||
|
||||
/**
|
||||
* 菜单编号
|
||||
*/
|
||||
private Long menuId;
|
||||
/**
|
||||
* 父菜单编号
|
||||
*/
|
||||
private Long parentId;
|
||||
|
||||
/**
|
||||
* 路由名字
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 路由地址
|
||||
*/
|
||||
private String path;
|
||||
|
||||
/**
|
||||
* 是否隐藏路由,当设置 true 的时候该路由不会再侧边栏出现
|
||||
*/
|
||||
private boolean hidden;
|
||||
|
||||
/**
|
||||
* 重定向地址,当设置 noRedirect 的时候该路由在面包屑导航中不可被点击
|
||||
*/
|
||||
private String redirect;
|
||||
|
||||
/**
|
||||
* 组件地址
|
||||
*/
|
||||
private String component;
|
||||
|
||||
/**
|
||||
* 当你一个路由下面的 children 声明的路由大于1个时,自动会变成嵌套的模式--如组件页面
|
||||
*/
|
||||
private Boolean alwaysShow;
|
||||
|
||||
/**
|
||||
* 其他元素
|
||||
*/
|
||||
private MetaVO meta;
|
||||
|
||||
/**
|
||||
* 子路由
|
||||
*/
|
||||
private List<SysAuthGetRouterRespVO> children;
|
||||
|
||||
@Data
|
||||
public static class MetaVO {
|
||||
|
||||
/**
|
||||
* 设置该路由在侧边栏和面包屑中展示的名字
|
||||
*/
|
||||
private String title;
|
||||
|
||||
/**
|
||||
* 设置该路由的图标,对应路径src/assets/icons/svg
|
||||
*/
|
||||
private String icon;
|
||||
|
||||
/**
|
||||
* 设置为true,则不会被 <keep-alive>缓存
|
||||
*/
|
||||
private boolean noCache;
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -2,6 +2,7 @@ package cn.iocoder.dashboard.modules.system.convert.auth;
|
|||
|
||||
import cn.iocoder.dashboard.framework.security.core.LoginUser;
|
||||
import cn.iocoder.dashboard.modules.system.controller.auth.vo.SysAuthGetInfoRespVO;
|
||||
import cn.iocoder.dashboard.modules.system.controller.auth.vo.SysAuthGetRouterRespVO;
|
||||
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;
|
||||
|
@ -27,4 +28,6 @@ public interface SysAuthConvert {
|
|||
return respVO;
|
||||
}
|
||||
|
||||
SysAuthGetRouterRespVO convertTreeNode(SysMenuDO menu);
|
||||
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.permission;
|
||||
|
||||
import cn.iocoder.dashboard.framework.mybatis.core.BaseDO;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
@ -9,8 +8,6 @@ import lombok.EqualsAndHashCode;
|
|||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.Size;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 菜单权限表
|
||||
|
@ -95,18 +92,4 @@ public class SysMenuDO extends BaseDO {
|
|||
*/
|
||||
private String icon;
|
||||
|
||||
// TODO 芋艿:非存储字段,需要提出
|
||||
|
||||
/**
|
||||
* 父菜单名称
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String parentName;
|
||||
|
||||
/**
|
||||
* 子菜单
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private List<SysMenuDO> children = new ArrayList<SysMenuDO>();
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
package cn.iocoder.dashboard.modules.system.enums.permission;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* Menu 编号枚举
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum MenuIdEnum {
|
||||
|
||||
/**
|
||||
* 根节点
|
||||
*/
|
||||
ROOT(0L);
|
||||
|
||||
private final Long id;
|
||||
|
||||
}
|
|
@ -2,7 +2,9 @@ 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.SysAuthGetInfoRespVO;
|
||||
import cn.iocoder.dashboard.modules.system.controller.auth.vo.SysAuthGetRouterRespVO;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
|
@ -28,4 +30,16 @@ public interface SysAuthService extends SecurityFrameworkService {
|
|||
*/
|
||||
SysAuthGetInfoRespVO getInfo(Long userId, Set<Long> roleIds);
|
||||
|
||||
/**
|
||||
* 获得用户的菜单 Vue 路由
|
||||
*
|
||||
* 这里传输 roleIds 参数的原因,是该参数是从 LoginUser 缓存中获取到的,而我们校验权限时也是从 LoginUser 缓存中获取 roleIds
|
||||
* 通过这样的方式,保持一致
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @param roleIds 用户拥有的角色编号数组
|
||||
* @return 菜单 Vue 路由
|
||||
*/
|
||||
List<SysAuthGetRouterRespVO> getRouters(Long userId, Set<Long> roleIds);
|
||||
|
||||
}
|
||||
|
|
|
@ -5,12 +5,14 @@ import cn.hutool.core.util.StrUtil;
|
|||
import cn.iocoder.dashboard.framework.security.config.SecurityProperties;
|
||||
import cn.iocoder.dashboard.framework.security.core.LoginUser;
|
||||
import cn.iocoder.dashboard.modules.system.controller.auth.vo.SysAuthGetInfoRespVO;
|
||||
import cn.iocoder.dashboard.modules.system.controller.auth.vo.SysAuthGetRouterRespVO;
|
||||
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.enums.user.UserStatus;
|
||||
import cn.iocoder.dashboard.modules.system.convert.auth.SysAuthConvert;
|
||||
import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user.SysUserDO;
|
||||
import cn.iocoder.dashboard.modules.system.dal.redis.dao.auth.SysLoginUserRedisDAO;
|
||||
import cn.iocoder.dashboard.modules.system.enums.permission.MenuIdEnum;
|
||||
import cn.iocoder.dashboard.modules.system.enums.user.UserStatus;
|
||||
import cn.iocoder.dashboard.modules.system.service.auth.SysAuthService;
|
||||
import cn.iocoder.dashboard.modules.system.service.auth.SysTokenService;
|
||||
import cn.iocoder.dashboard.modules.system.service.permission.SysPermissionService;
|
||||
|
@ -234,4 +236,38 @@ public class SysAuthServiceImpl implements SysAuthService {
|
|||
return SysAuthConvert.INSTANCE.convert(user, roleList, menuList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SysAuthGetRouterRespVO> getRouters(Long userId, Set<Long> roleIds) {
|
||||
// TODO 芋艿:去除 F 的类型,去除 禁用 的
|
||||
List<SysMenuDO> menuList = permissionService.listRoleMenusFromCache(roleIds);
|
||||
// 转换成 Tree 结构返回
|
||||
return buildRouterTree(menuList);
|
||||
}
|
||||
|
||||
private static List<SysAuthGetRouterRespVO> buildRouterTree(List<SysMenuDO> menuList) {
|
||||
// 排序,保证菜单的有序性
|
||||
menuList = new ArrayList<>(menuList); // 使用 ArrayList 套一下,因为 menuList 是不可修改的 List
|
||||
menuList.sort(Comparator.comparing(SysMenuDO::getOrderNum));
|
||||
// 构建菜单树
|
||||
// 使用 LinkedHashMap 的原因,是为了排序 。实际也可以用 Stream API ,就是太丑了。
|
||||
Map<Long, SysAuthGetRouterRespVO> treeNodeMap = new LinkedHashMap<>();
|
||||
menuList.forEach(menu -> treeNodeMap.put(menu.getMenuId(), SysAuthConvert.INSTANCE.convertTreeNode(menu)));
|
||||
// 处理父子关系
|
||||
treeNodeMap.values().stream().filter(node -> !node.getParentId().equals(MenuIdEnum.ROOT.getId())).forEach((childNode) -> {
|
||||
// 获得父节点
|
||||
SysAuthGetRouterRespVO parentNode = treeNodeMap.get(childNode.getParentId());
|
||||
if (parentNode == null) {
|
||||
log.error("[buildRouterTree][resource({}) 找不到父资源({})]", childNode.getMenuId(), childNode.getParentId());
|
||||
return;
|
||||
}
|
||||
// 将自己添加到父节点中
|
||||
if (parentNode.getChildren() == null) {
|
||||
parentNode.setChildren(new ArrayList<>());
|
||||
}
|
||||
parentNode.getChildren().add(childNode);
|
||||
});
|
||||
// 获得到所有的根节点
|
||||
return CollectionUtils.filterList(treeNodeMap.values(), node -> MenuIdEnum.ROOT.getId().equals(node.getParentId()));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollectionUtil;
|
|||
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
|
@ -17,6 +18,10 @@ public class CollectionUtils {
|
|||
return new HashSet<>(Arrays.asList(objs));
|
||||
}
|
||||
|
||||
public static <T> List<T> filterList(Collection<T> from, Predicate<T> predicate) {
|
||||
return from.stream().filter(predicate).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static <T, U> List<U> convertList(List<T> from, Function<T, U> func) {
|
||||
return from.stream().map(func).collect(Collectors.toList());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue