permission.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. import {constantRoutes} from '@/router'
  2. import {getRouters} from '@/api/menu'
  3. import Layout from '@/layout/index'
  4. import ParentView from '@/components/ParentView';
  5. import {toCamelCase} from "@/utils";
  6. const permission = {
  7. state: {
  8. routes: [],
  9. addRoutes: [],
  10. sidebarRouters: [], // 左侧边菜单的路由,被 Sidebar/index.vue 使用
  11. topbarRouters: [], // 顶部菜单的路由,被 TopNav/index.vue 使用
  12. },
  13. mutations: {
  14. SET_ROUTES: (state, routes) => {
  15. state.addRoutes = routes
  16. state.routes = constantRoutes.concat(routes)
  17. },
  18. SET_DEFAULT_ROUTES: (state, routes) => {
  19. state.defaultRoutes = constantRoutes.concat(routes)
  20. },
  21. SET_TOPBAR_ROUTES: (state, routes) => {
  22. state.topbarRouters = routes
  23. },
  24. SET_SIDEBAR_ROUTERS: (state, routes) => {
  25. state.sidebarRouters = routes
  26. },
  27. },
  28. actions: {
  29. // 生成路由
  30. GenerateRoutes({commit}) {
  31. return new Promise(resolve => {
  32. // 向后端请求路由数据(菜单)
  33. getRouters().then(res => {
  34. const sdata = JSON.parse(JSON.stringify(res.data)) // 【重要】用于菜单中的数据
  35. const rdata = JSON.parse(JSON.stringify(res.data)) // 用于最后添加到 Router 中的数据
  36. const sidebarRoutes = filterAsyncRouter(sdata)
  37. const rewriteRoutes = filterAsyncRouter(rdata, false, true)
  38. rewriteRoutes.push({path: '*', redirect: '/404', hidden: true})
  39. commit('SET_ROUTES', rewriteRoutes)
  40. commit('SET_SIDEBAR_ROUTERS', constantRoutes.concat(sidebarRoutes))
  41. commit('SET_DEFAULT_ROUTES', sidebarRoutes)
  42. commit('SET_TOPBAR_ROUTES', sidebarRoutes)
  43. resolve(rewriteRoutes)
  44. })
  45. })
  46. }
  47. }
  48. }
  49. // 遍历后台传来的路由字符串,转换为组件对象
  50. function filterAsyncRouter(asyncRouterMap, lastRouter = false, type = false) {
  51. return asyncRouterMap.filter(route => {
  52. // 将 ruoyi 后端原有耦合前端的逻辑,迁移到此处
  53. // 处理 meta 属性
  54. route.meta = {
  55. title: route.name,
  56. icon: route.icon,
  57. noCache: !route.keepAlive,
  58. }
  59. // 路由地址转首字母大写驼峰,作为路由名称,适配 keepAlive
  60. route.name = toCamelCase(route.path, true)
  61. // 处理三级及以上菜单路由缓存问题,将path名字赋值给name
  62. if (route.path.indexOf("/") !== -1) {
  63. const pathArr = route.path.split("/");
  64. route.name = toCamelCase(pathArr[pathArr.length - 1], true)
  65. }
  66. route.hidden = !route.visible
  67. // 处理 component 属性
  68. if (route.children) { // 父节点
  69. if (route.parentId === 0) {
  70. route.component = Layout
  71. } else {
  72. route.component = ParentView
  73. }
  74. // 解决只有一个菜单时无法显示目录
  75. route.alwaysShow = true
  76. } else { // 根节点
  77. route.component = loadView(route.component)
  78. }
  79. // filterChildren
  80. if (type && route.children) {
  81. route.children = filterChildren(route.children)
  82. }
  83. if (route.children != null && route.children && route.children.length) {
  84. route.children = filterAsyncRouter(route.children, route, type)
  85. } else {
  86. delete route['children']
  87. }
  88. return true
  89. })
  90. }
  91. function filterChildren(childrenMap, lastRouter = false) {
  92. let children = [];
  93. childrenMap.forEach((el, index) => {
  94. if (el.children && el.children.length) {
  95. if (!el.component && !lastRouter) {
  96. el.children.forEach(c => {
  97. c.path = el.path + '/' + c.path
  98. if (c.children && c.children.length) {
  99. children = children.concat(filterChildren(c.children, c))
  100. return
  101. }
  102. children.push(c)
  103. })
  104. return
  105. }
  106. }
  107. if (lastRouter) {
  108. el.path = lastRouter.path + '/' + el.path
  109. }
  110. children = children.concat(el)
  111. })
  112. return children
  113. }
  114. export const loadView = (view) => { // 路由懒加载
  115. return (resolve) => require([`@/views/${view}`], resolve)
  116. }
  117. export default permission