『博客开发日记-后台』之获取当前登录用户可访问的前端路由树接口的实现

本文最后更新于 2026年4月8日 下午

获取当前登录用户可访问的前端路由树接口的实现


获取当前登录用户可访问的前端路由树接口的需求

根据用户id查询menu

判断是否是管理员

如果是,返回符合要求的menu

否则就返回当前用户所具有的menu 类型为菜单和目录类型

构建tree(菜单树)

代码实现

先创建RoutersVo类和MenuVo类


新建SysMenuController类


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
* 菜单相关接口
*/
@RestController
@RequestMapping("/menus")
@Api(tags = "菜单", description = "菜单相关接口")
public class SysMenuController
{
@Autowired
private SysMenuService sysMenuService;

/**
* 获取当前登录用户可访问的前端路由树
*/
@GetMapping("/getRoutes")
@SystemLog(businessName = "获取当前登录用户可访问的前端路由树")
@ApiOperation(value = "获取当前用户菜单路由树", notes = "获取当前登录用户可访问的前端路由树")
public ResponseResult getRoutes() {
return sysMenuService.getRoutes();
}
}


创建MenuVo类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/**
* 菜单Vo
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
@ApiModel(description = "获取当前登录用户的菜单")
public class MenuVo
{
@TableId

private Long id;
//创建时间
private Date createTime;
//父菜单ID
private Long parentId;
//菜单名称
private String name;
//菜单类型(C-目录 M-菜单 B-按钮)
private String type;
//路由路径
private String path;
//路由名称(前端路由名)
private String routeName;
//路由路径(扩展字段)
private String routePath;
//跳转路径
private String redirect;
//组件路径
private String component;
//ICON
private String icon;
//菜单是否正常(0:正常;1:异常)
private Integer status;
//菜单是否可见(1:显示;0:隐藏)
private Integer visible;
//权限标识
private String perm;
//路由参数(以JSON文本形式存储)
private String paramsJson;

@TableField(exist = false)
private List<MenuVo> children;
}


在SecurityUtils类中添加判断是否为管理员的方法


在SysMenuServiceImpl中实现方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

/**
* 获取当前登录用户可访问的前端路由树
*/
@Override
public ResponseResult getRoutes()
{
//查询用户id
Long userId = SecurityUtils.getUserId();

//查询menu
SysMenuMapper menuMapper = getBaseMapper();
List<MenuVo> menus;
//判断是否是管理员
if (SecurityUtils.isAdmin()){
//如果是,返回符合要求的menu
menus = menuMapper.selectAllRouterMenu();
}else {
//否则就返回当前用户所具有的menu 类型为菜单和目录类型
menus = menuMapper.selectRouterMenuTreeByUserId(userId);
}

//构建tree
//先找第一层的菜单,然后再找他的子菜单设置到children字段中
List<MenuVo> menuTree = builderMenuTree(menus, 0L);

//封装数据返回 - 使用 RoutersVo 包装菜单数组
return ResponseResult.okResult(new RoutersVo(menuTree));
}

//创建菜单树
private List<MenuVo> builderMenuTree(List<MenuVo> menus, Long parentId)
{
List<MenuVo> menuTree = menus.stream()
.filter(menu -> menu.getParentId().equals(parentId))
.map(menu -> menu.setChildren(getChildren(menu, menus)))
.collect(Collectors.toList());
return menuTree;
}

/**
* 获取传入参数的 子菜单(menu)集合
* @param menu
* @param menus
* @return
*/
private List<MenuVo> getChildren(MenuVo menu, List<MenuVo> menus)
{
List<MenuVo> childrenList = menus.stream()
.filter(m -> m.getParentId().equals(menu.getId()))
.map(m -> m.setChildren(getChildren(m, menus)))
.collect(Collectors.toList());
return childrenList;
}

在SysMenuMapper中编写sql语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

<select id="selectAllRouterMenu" resultType="com.mengze.domain.vo.MenuVo">
SELECT DISTINCT m.id,
m.create_time,
m.parent_id,
m.name,
m.type,
m.path,
m.route_path,
m.route_name,
m.redirect,
m.component,
m.icon,
m.status,
m.visible,
IFNULL(m.perm,'') AS perm,
m.params_json
FROM sys_menu m
WHERE m.type IN ('M', 'C')
AND m.`status` = 0
AND m.visible = 1
AND m.del_flag = 0
ORDER BY m.parent_id, m.sort
</select>

<select id="selectRouterMenuTreeByUserId" resultType="com.mengze.domain.vo.MenuVo">
SELECT DISTINCT m.id,
m.create_time,
m.parent_id,
m.name,
m.type,
m.path,
m.route_path,
m.route_name,
m.redirect,
m.component,
m.icon,
m.status,
m.visible,
IFNULL(m.perm,'') AS perm,
m.params_json
FROM sys_user_role ur
LEFT JOIN sys_role_menu rm ON ur.role_id = rm.role_id
LEFT JOIN sys_menu m ON m.id = rm.menu_id
WHERE ur.user_id = #{userId}
AND m.type IN ('M', 'C')
AND m.`status` = 0
AND m.visible = 1
AND m.del_flag = 0
ORDER BY m.parent_id, m.sort
</select>



PS:该系列只做为作者学习开发项目做的笔记用

不一定符合读者来学习,仅供参考


预告

后续会记录博客的开发过程

每次学习会做一份笔记来进行发表

“一花一世界,一叶一菩提”


版权所有 © 2026 云梦泽
欢迎访问我的个人网站:https://hgt12.github.io/


『博客开发日记-后台』之获取当前登录用户可访问的前端路由树接口的实现
http://example.com/2026/04/02/『博客开发日记-后台』之获取当前登录用户可访问的前端路由树接口的实现/
作者
云梦泽
发布于
2026年4月2日
更新于
2026年4月8日
许可协议