1.若依后台提供了获取当前登录用户菜单路由的方法,在SysLoginController中
java方法代码如下:
@GetMapping("getRouters")
public AjaxResult getRouters()
{
Long userId = SecurityUtils.getUserId();
List<SysMenu> menus = menuService.selectMenuTreeByUserId(userId);
return AjaxResult.success(menuService.buildMenus(menus));
}
代码逻辑是得到当前登录用户userId,根据当前登录用户Id,到sys_menu表中递归遍历用户有权访问的所有菜单,并返回一个JSON结果。
2.我们查一下sys_menu表中的数据,parent_id为0的是第一级菜单,菜单是个树状设计,可以根据parent_id查找子菜单
3.下一步我们想先了解下getRouters接口生成的JSON数据格式,再确定怎么跟我们的菜单格式做匹配,这里有个问题就是getRouters接口是不能在浏览器中直接访问测试的,要先登录,拿到当前用户登录userId,然后按照JWT规范,在Header中加入Token才能正常访问到getRouters接口,我们没法在浏览器中直接调用getRouters接口的,这个问题如何解决呢,有两个方案,方案一是按swagger规范写接口,用swagger方式来做测试,具体可以参考doc.ruoyi.vip/ruoyi-cloud…(这个版本是微服务版,仅供参考),方案二是使用postman之类的工具来做测试,方案一要改代码,繁琐一点,我们采用方案二
4.Postman的调用方式,我们用截图稍作说明,我们先实现登录,url地址里面填http://localhost:8080/login,
Headers Content-Type选application/json,
body中参数格式如下
{
"username":"admin",
"password":"admin123"
}
点发送时,正常登录的话会返回token值,我们要拿这个token只来测试/getRouters接口,这次测试登录我们拿到的token值是(每次调用的时候token值会不一样):eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6ImM1OGNjMTI5LWZjMzctNDc0YS04OTkyLTIyYmM2ZTEwZDI0ZiJ9.Jed5Kf6c-HiewxeJY44enCWJbuDkqOfXorAt_q4oUCk_-yDPQgHexd-OhK-rSRz3l4evAZ9zO_tLE2ELn8n_RQ
5.我们在postman中新建一个Tab栏,来测试/getRouters接口,请求方法改为Get,请求地址填写http://localhost:8080/getRouters,Headers Content-Type选application/json,
Header中新增一行,key中输入"Authorization",value中输入Bearer+空格+刚才拿到的Token即eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6ImM1OGNjMTI5LWZjMzctNDc0YS04OTkyLTIyYmM2ZTEwZDI0ZiJ9.Jed5Kf6c-HiewxeJY44enCWJbuDkqOfXorAt_q4oUCk_-yDPQgHexd-OhK-rSRz3l4evAZ9zO_tLE2ELn8n_RQ,完整的value值为:
Bearer eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6ImM1OGNjMTI5LWZjMzctNDc0YS04OTkyLTIyYmM2ZTEwZDI0ZiJ9.Jed5Kf6c-HiewxeJY44enCWJbuDkqOfXorAt_q4oUCk_-yDPQgHexd-OhK-rSRz3l4evAZ9zO_tLE2ELn8n_RQ
然后点发送,如下图所示:
6.顺利的话应该可以拿到admin用户可以访问的所有菜单JSON数据,最终拿到的JSON数据如下:
{
"msg":"操作成功",
"code":200,
"data":[
{
"name":"System",
"path":"/system",
"hidden":false,
"redirect":"noRedirect",
"component":"Layout",
"alwaysShow":true,
"meta":{
"title":"系统管理",
"icon":"system",
"noCache":false,
"link":null
},
"children":[
{
"name":"User",
"path":"user",
"hidden":false,
"component":"system/user/index",
"meta":{
"title":"用户管理",
"icon":"user",
"noCache":false,
"link":null
}
},
{
"name":"Role",
"path":"role",
"hidden":false,
"component":"system/role/index",
"meta":{
"title":"角色管理",
"icon":"peoples",
"noCache":false,
"link":null
}
},
{
"name":"Menu",
"path":"menu",
"hidden":false,
"component":"system/menu/index",
"meta":{
"title":"菜单管理",
"icon":"tree-table",
"noCache":false,
"link":null
}
},
{
"name":"Dept",
"path":"dept",
"hidden":false,
"component":"system/dept/index",
"meta":{
"title":"部门管理",
"icon":"tree",
"noCache":false,
"link":null
}
},
{
"name":"Post",
"path":"post",
"hidden":false,
"component":"system/post/index",
"meta":{
"title":"岗位管理",
"icon":"post",
"noCache":false,
"link":null
}
},
{
"name":"Dict",
"path":"dict",
"hidden":false,
"component":"system/dict/index",
"meta":{
"title":"字典管理",
"icon":"dict",
"noCache":false,
"link":null
}
},
{
"name":"Config",
"path":"config",
"hidden":false,
"component":"system/config/index",
"meta":{
"title":"参数设置",
"icon":"edit",
"noCache":false,
"link":null
}
},
{
"name":"Notice",
"path":"notice",
"hidden":false,
"component":"system/notice/index",
"meta":{
"title":"通知公告",
"icon":"message",
"noCache":false,
"link":null
}
},
{
"name":"Log",
"path":"log",
"hidden":false,
"redirect":"noRedirect",
"component":"ParentView",
"alwaysShow":true,
"meta":{
"title":"日志管理",
"icon":"log",
"noCache":false,
"link":null
},
"children":[
{
"name":"Operlog",
"path":"operlog",
"hidden":false,
"component":"monitor/operlog/index",
"meta":{
"title":"操作日志",
"icon":"form",
"noCache":false,
"link":null
}
},
{
"name":"Logininfor",
"path":"logininfor",
"hidden":false,
"component":"monitor/logininfor/index",
"meta":{
"title":"登录日志",
"icon":"logininfor",
"noCache":false,
"link":null
}
}
]
}
]
},
{
"name":"Monitor",
"path":"/monitor",
"hidden":false,
"redirect":"noRedirect",
"component":"Layout",
"alwaysShow":true,
"meta":{
"title":"系统监控",
"icon":"monitor",
"noCache":false,
"link":null
},
"children":[
{
"name":"Online",
"path":"online",
"hidden":false,
"component":"monitor/online/index",
"meta":{
"title":"在线用户",
"icon":"online",
"noCache":false,
"link":null
}
},
{
"name":"Job",
"path":"job",
"hidden":false,
"component":"monitor/job/index",
"meta":{
"title":"定时任务",
"icon":"job",
"noCache":false,
"link":null
}
},
{
"name":"Druid",
"path":"druid",
"hidden":false,
"component":"monitor/druid/index",
"meta":{
"title":"数据监控",
"icon":"druid",
"noCache":false,
"link":null
}
},
{
"name":"Server",
"path":"server",
"hidden":false,
"component":"monitor/server/index",
"meta":{
"title":"服务监控",
"icon":"server",
"noCache":false,
"link":null
}
},
{
"name":"Cache",
"path":"cache",
"hidden":false,
"component":"monitor/cache/index",
"meta":{
"title":"缓存监控",
"icon":"redis",
"noCache":false,
"link":null
}
}
]
},
{
"name":"Tool",
"path":"/tool",
"hidden":false,
"redirect":"noRedirect",
"component":"Layout",
"alwaysShow":true,
"meta":{
"title":"系统工具",
"icon":"tool",
"noCache":false,
"link":null
},
"children":[
{
"name":"Build",
"path":"build",
"hidden":false,
"component":"tool/build/index",
"meta":{
"title":"表单构建",
"icon":"build",
"noCache":false,
"link":null
}
},
{
"name":"Gen",
"path":"gen",
"hidden":false,
"component":"tool/gen/index",
"meta":{
"title":"代码生成",
"icon":"code",
"noCache":false,
"link":null
}
},
{
"name":"Swagger",
"path":"swagger",
"hidden":false,
"component":"tool/swagger/index",
"meta":{
"title":"系统接口",
"icon":"swagger",
"noCache":false,
"link":null
}
}
]
},
{
"name":"Http://ruoyi.vip",
"path":"http://ruoyi.vip",
"hidden":false,
"component":"Layout",
"meta":{
"title":"若依官网",
"icon":"guide",
"noCache":false,
"link":"http://ruoyi.vip"
}
}
]
}
7.以一个菜单为例,我们稍微分析下拿到的JSON数据
"name":"System",
"path":"/system",
"hidden":false,
"redirect":"noRedirect",
"component":"Layout",
"alwaysShow":true,
"meta":
{
"title":"系统管理",
"icon":"system",
"noCache":false,
"link":null
},
"children":[...]
name菜单英文名称, path 路由位置,hidden是否隐藏,redirect默认跳转路由,component使用组件, meta.title菜单中文名称,meta.icon:菜单图标,children[]子菜单数组。
8.对比下我们现在从config/config.js中拿到的菜单格式
{
name: 'table-list',
icon: 'smile',
path: '/list/table-list',
component: './list/table-list',
},
config.js中的菜单只有4个属性,name,icon,path,component,跟我们从数据库中拿到的菜单有部分不太一样,我们的icon在meta.icon中,我们的name要取中文显示,应该用meta.title,这个属性值的转换我们就不改后台的代码了,直接在前台做转换,不过由于是一个树状结构,要用到递归,有一点点麻烦,下一步我们先封装请求菜单的service方法。
最近做了个小API应用,希望大家关注支持下: www.yuque.com/docs/share/…