Files
yudao-dev/src/store/modules/permission.js
2026-03-06 09:28:06 +08:00

169 lines
5.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import {constantRoutes} from '@/router'
import Layout from '@/layout/index'
import BlankLayout from "@/layout/BlankLayout";
import ParentView from '@/components/ParentView';
import {toCamelCase} from "@/utils";
const permission = {
state: {
routes: [],
addRoutes: [],
sidebarRouters: [], // 左侧边菜单的路由,被 Sidebar/index.vue 使用
topbarRouters: [], // 顶部菜单的路由,被 TopNav/index.vue 使用
defaultPath: '/', // 登录后默认跳转路径(由菜单 jumpFlag===1 决定)
},
mutations: {
SET_DEFAULT_PATH: (state, path) => {
state.defaultPath = path || '/'
},
SET_ROUTES: (state, routes) => {
state.addRoutes = routes
state.routes = constantRoutes.concat(routes)
},
SET_DEFAULT_ROUTES: (state, routes) => {
state.defaultRoutes = constantRoutes.concat(routes)
},
SET_TOPBAR_ROUTES: (state, routes) => {
state.topbarRouters = routes
},
SET_SIDEBAR_ROUTERS: (state, routes) => {
state.sidebarRouters = routes
},
},
actions: {
/**
* 生成路由
*
* @param commit commit 函数
* @param menus 路由参数
*/
GenerateRoutes({commit}, menus) {
return new Promise(resolve => {
// 将 menus 菜单,转换为 route 路由数组
const sdata = JSON.parse(JSON.stringify(menus)) // 【重要】用于菜单中的数据
const rdata = JSON.parse(JSON.stringify(menus)) // 用于最后添加到 Router 中的数据
const sidebarRoutes = filterAsyncRouter(sdata)
const rewriteRoutes = filterAsyncRouter(rdata, false, true)
rewriteRoutes.push({path: '*', redirect: '/404', hidden: true})
commit('SET_ROUTES', rewriteRoutes)
commit('SET_SIDEBAR_ROUTERS', constantRoutes.concat(sidebarRoutes))
commit('SET_DEFAULT_ROUTES', sidebarRoutes)
commit('SET_TOPBAR_ROUTES', sidebarRoutes)
resolve(rewriteRoutes)
})
}
}
}
// 遍历后台传来的路由字符串,转换为组件对象
function filterAsyncRouter(asyncRouterMap, lastRouter = false, type = false) {
return asyncRouterMap.filter(route => {
// 将 ruoyi 后端原有耦合前端的逻辑,迁移到此处
// 处理 meta 属性
route.meta = {
title: route.name,
icon: route.icon,
noCache: !route.keepAlive,
}
route.hidden = !route.visible
// 处理 name 属性
if (route.componentName && route.componentName.length > 0) {
route.name = route.componentName
} else {
// 路由地址转首字母大写驼峰,作为路由名称,适配 keepAlive
route.name = toCamelCase(route.path, true)
// 处理三级及以上菜单路由缓存问题,将 path 名字赋值给 name
if (route.path.indexOf("/") !== -1) {
const pathArr = route.path.split("/");
route.name = toCamelCase(pathArr[pathArr.length - 1], true)
}
}
const needBlankLayout = [
"/operatingRevenue",
"/totalProfit",
"/operatingProfit",
"/expenseAnalysis",
"/grossMargin",
"/inputOutputRatio",
"/rawSheetYield",
"/productionCostAnalysis",
"/unitPriceAnalysis",
"/netPriceAnalysis",
"/salesVolumeAnalysis",
'/procurementGainAnalysis',
'/fullCostAnalysis',
// '/expenseAnalysis',
"/cost", // cost 根路由
"/cost/profitImpactAnalysis", // cost 子菜单(完整路径)
];
// 拼接完整路径(父路由路径 + 当前路由路径)
const fullPath = lastRouter
? `${lastRouter.path}/${route.path}`
: route.path;
// 3. 动态分配布局:目标路由用 BlankLayout其他用默认 Layout/ParentView
if (route.children) {
// 有子路由的父节点
// 如果是顶级父节点parentId=0且需要空白布局则用 BlankLayout
if (route.parentId === 0 && needBlankLayout.includes(route.path)) {
route.component = BlankLayout;
} else {
// 其他父节点:顶级用 Layout非顶级用 ParentView原有逻辑
route.component = route.parentId === 0 ? Layout : ParentView;
}
} else {
// 无子路由的叶子节点(最终页面)
// 如果叶子节点的完整路径在目标列表中,直接用空白布局的路由出口
if (needBlankLayout.includes(fullPath)) {
route.component = loadView(route.component); // 直接指向页面组件
} else {
route.component = loadView(route.component); // 原有逻辑
}
}
// filterChildren
if (type && route.children) {
route.children = filterChildren(route.children)
}
if (route.children != null && route.children && route.children.length) {
route.children = filterAsyncRouter(route.children, route, type)
route.alwaysShow = route.alwaysShow !== undefined ? route.alwaysShow : true
} else {
delete route['children']
delete route['alwaysShow'] // 如果没有子菜单,就不需要考虑 alwaysShow 字段
}
return true
})
}
function filterChildren(childrenMap, lastRouter = false) {
let children = [];
childrenMap.forEach((el, index) => {
if (el.children && el.children.length) {
if (!el.component && !lastRouter) {
el.children.forEach(c => {
c.path = el.path + '/' + c.path
if (c.children && c.children.length) {
children = children.concat(filterChildren(c.children, c))
return
}
children.push(c)
})
return
}
}
if (lastRouter) {
el.path = lastRouter.path + '/' + el.path
}
children = children.concat(el)
})
return children
}
export const loadView = (view) => { // 路由懒加载
return (resolve) => require([`@/views/${view}`], resolve)
}
export default permission