import { asyncRoutes, constantRoutes } from '@/router' import Layout from '@/layout' import { getAuthMenu } from '@/api/user.js' /** * Use meta.role to determine if the current user has permission * @param roles * @param route */ function hasPermission(roles, route) { if (route.meta && route.meta.roles) { return roles.some(role => route.meta.roles.includes(role)) } else { return true } } /** * 静态路由懒加载 * @param view 格式必须为 xxx/xxx 开头不要加斜杠 * @returns */ export const loadView = (view) => { return (resolve) => require([`@/views${view}`], resolve); } /** * Filter asynchronous routing tables by recursion * @param routes asyncRoutes * @param roles */ export function filterAsyncRoutes(routes, roles) { const res = [] routes.forEach(route => { const tmp = { ...route } if (hasPermission(roles, tmp)) { if (tmp.children) { tmp.children = filterAsyncRoutes(tmp.children, roles) } res.push(tmp) } }) return res } const state = { routes: [], addRoutes: [] } /** * 后台查询的菜单数据拼装成路由格式的数据 * @param routes */ const pathHandler = (item) => { if(!item.path || item.path?.includes('#') || item.path == ''){ return item.id + '_key' } if(/^\^/.test(item.path)){ return item.path.replace(/^\^+/g,"") } if(/^\$/.test(item.path)){ return item.path.replace(/^\$+/g,"") } return item.path // if(path.includes('$')){ // return path.replace(/^\$+/g,"") // } // if(path.includes('^')){ // return path.replace(/^\^+/g,"") // } // if(path.includes('#') || path == ''){ // return id + '_key' // } // return path } const componentHandler = (path) => { //return path === '#'|| path == '' ? Layout : loadView(path) if(path === '#' || path === ''){ return Layout } if(path.includes('#') && path !== '#'){ return ()=>import('@/layout/noLayout') } return loadView(path) } // path为#,左边栏根目录无视图,##下级根目录无视图,$不显示在左边栏视图,^左边栏根目录有视图 export function generaMenu(routes, data) { data.forEach(item => { if (!item.path) { item.path = item.url } let params = {}; if(item.path?.includes('?')){ let flag = item.path.split('?') item.path = flag[0] if(flag[1]){ let list = flag[1].split('&') list.forEach(item => { let kv = item.split('=') Object.defineProperty(params,kv[0],{ value:kv[1], writable:true, enumerable:true, configurable:false }) }) } } if (item.url === "/") { } else if(/^\^/.test(item.path)){ const menu = { name: item.children?.length > 1 ? 'menu_' + item.id : item.children[0]?.id, path: pathHandler(item), component: Layout, meta: { title: item.children?.length > 1 ? item.name : item.children[0]?.name, id: item.children?.length > 1 ? item.id : item.children[0]?.id, roles: ['admin'], params, icon: item.children?.length > 1 ? item.icon : item.children[0]?.icon }, children: [] } if (item.children) { if (item.children.length > 1) { menu['redirect'] = `${pathHandler(item)}${item.children[0].path}` item.children.unshift({ id: item.id, name: item.name, path: item.path.replace(/\^/g,""), url: item.url, icon: item.icon, children: [], hidden: true }) } else { menu.children.push({ path: "", name: 'menu_' + item.id, component: (item.url.includes('#')||item.path == '') ? Layout : loadView(item.url), // component: Layout, meta: { title: item.name, id: item.id, roles: ['admin'], params, icon: item.icon } }) } generaMenu(menu.children, item.children) } console.log(77, menu) routes.push(menu) } else { const menu = { path: pathHandler(item), //(item.path === '#'||item.path == '' ? item.id + '_key' : item.path), component: componentHandler(item.url), //(item.path === '#'||item.path == '' ? Layout : loadView(item.path)), // hidden: true, children: [], name: 'menu_' + item.id, meta: { title: item.name, id: item.id, roles: ['admin'], auths:item.has_auth_node_tags, params, icon: item.icon }, hidden: item.hidden } if(item.path?.includes("$")){ menu.hidden = true } if (item.children) { generaMenu(menu.children, item.children) } routes.push(menu) } }) // routes.push({ // path: '*', // redirect: '/404', // hidden: true // }) } const mutations = { SET_ROUTES: (state, routes) => { state.addRoutes = routes state.routes = constantRoutes.concat(routes) } } // const actions = { // generateRoutes({ // commit // }, roles) { // const loadMenuData = [] // return new Promise(resolve => { // let accessedRoutes // let data = _routes2; // Object.assign(loadMenuData, data) // generaMenu(asyncRoutes, loadMenuData) // if (roles.includes('admin')) { // // alert(JSON.stringify(asyncRoutes)) // accessedRoutes = asyncRoutes || [] // } else { // accessedRoutes = filterAsyncRoutes(asyncRoutes, roles) // } // commit('SET_ROUTES', accessedRoutes) // resolve(accessedRoutes) // }) // } // } const actions = { generateRoutes({ commit }, roles) { return new Promise(resolve => { const loadMenuData = [] // 先查询后台并返回左侧菜单数据并把数据添加到路由 getAuthMenu(state.token).then(response => { let data = response //console.log(JSON.stringify(data)) Object.assign(loadMenuData, data) asyncRoutes.length=0; generaMenu(asyncRoutes, loadMenuData) let accessedRoutes if (roles.includes('admin')) { // alert(JSON.stringify(asyncRoutes)) accessedRoutes = asyncRoutes || [] } else { accessedRoutes = filterAsyncRoutes(asyncRoutes, roles) } commit('SET_ROUTES', accessedRoutes) resolve(accessedRoutes) // generaMenu(asyncRoutes, data) }).catch(error => { console.log(error) }) }) } } export default { namespaced: true, state, mutations, actions }