/**
* 判断是否有路由的权限
* @param authority 路由权限配置
* @param permissions 用户权限集合
* @returns {boolean|*}
*/
function hasPermission(authority, permissions) {
let required = '*'
if (typeof authority === 'string') {
required = authority
} else if (typeof authority === 'object') {
required = authority.permission
}
return required === '*' || (permissions && permissions.findIndex(item => item === required || item.id === required) !== -1)
}
/**
* 判断是否有路由需要的角色
* @param authority 路由权限配置
* @param roles 用户角色集合
*/
function hasRole(authority, roles) {
let required
if (typeof authority === 'object') {
required = authority.role
}
return authority === '*' || hasAnyRole(required, roles)
}
/**
* 判断是否有需要的任意一个角色
* @param required {String | Array[String]} 需要的角色,可以是单个角色或者一个角色数组
* @param roles 拥有的角色
* @returns {boolean}
*/
function hasAnyRole(required, roles) {
if (!required) {
return false
} else if (Array.isArray(required)) {
return roles.findIndex(role => {
return required.findIndex(item => item === role || item === role.id) !== -1
}) !== -1
} else {
return roles.findIndex(role => role === required || role.id === required) !== -1
}
}
/**
* 路由权限校验
* @param route 路由
* @param permissions 用户权限集合
* @param roles 用户角色集合
* @returns {boolean}
*/
function hasAuthority(route, permissions, roles) {
const authority = route.meta?.authority;
if (!authority) return true;
// 检查 role 或 permission
return (
(authority.role && hasRole(authority, roles)) ||
(authority.permission && hasPermission(authority, permissions))
);
}
/**
* 根据权限配置过滤菜单数据
* @param menuData
* @param permissions
* @param roles
*/
function filterMenu(menuData, permissions, roles) {
return menuData.filter(menu => {
if (menu.meta && menu.meta.invisible === undefined) {
if (!hasAuthority(menu, permissions, roles)) {
return false
}
}
if (menu.children && menu.children.length > 0) {
menu.children = filterMenu(menu.children, permissions, roles)
}
return true
})
}
export { filterMenu, hasAuthority }
import routerMap from '@/router/async/router.map'
import { mergeI18nFromRoutes } from '@/utils/i18n'
import Router from 'vue-router'
import deepMerge from 'deepmerge'
import basicOptions from '@/router/async/config.async'
// 应用配置
const appOptions = {
router: undefined,
i18n: undefined,
store: undefined
}
/**
* 设置应用配置
* @param options
*/
function setAppOptions(options) {
const { router, store, i18n } = options
appOptions.router = router
appOptions.store = store
appOptions.i18n = i18n
}
/**
* 根据 路由配置 和 路由组件注册 解析路由
* @param routesConfig 路由配置
* @param routerMap 本地路由组件注册配置
*/
function parseRoutes(routesConfig, routerMap) {
const routes = []
routesConfig.forEach(item => {
// 获取注册在 routerMap 中的 router,初始化 routeCfg
let router; let routeCfg = {}
if (typeof item === 'string') {
router = routerMap[item]
routeCfg = { path: (router && router.path) || item, router: item }
} else if (typeof item === 'object') {
router = routerMap[item.router]
routeCfg = item
}
if (!router) {
console.warn(`can't find register for router ${routeCfg.router}, please register it in advance.`)
router = typeof item === 'string' ? { path: item, name: item } : item
}
// 从 router 和 routeCfg 解析路由
const meta = {
authority: router.authority,
icon: router.icon,
page: router.page,
link: router.link,
params: router.params,
query: router.query,
...router.meta
}
const cfgMeta = {
authority: routeCfg.authority,
icon: routeCfg.icon,
page: routeCfg.page,
link: routeCfg.link,
params: routeCfg.params,
query: routeCfg.query,
...routeCfg.meta
}
Object.keys(cfgMeta).forEach(key => {
if (cfgMeta[key] === undefined || cfgMeta[key] === null || cfgMeta[key] === '') {
delete cfgMeta[key]
}
})
Object.assign(meta, cfgMeta)
const route = {
path: routeCfg.path || router.path || routeCfg.router,
name: routeCfg.name || router.name,
component: router.component,
redirect: routeCfg.redirect || router.redirect,
meta: { ...meta, authority: meta.authority || '*' }
}
if (routeCfg.invisible || router.invisible) {
route.meta.invisible = true
}
if (routeCfg.children && routeCfg.children.length > 0) {
route.children = parseRoutes(routeCfg.children, routerMap)
}
routes.push(route)
})
return routes
}
/**
* 加载路由
* @param routesConfig {RouteConfig[]} 路由配置
*/
// function loadRoutes(routesConfig) {
// //兼容 0.6.1 以下版本
// /*************** 兼容 version < v0.6.1 *****************/
// if (arguments.length > 0) {
// const arg0 = arguments[0]
// if (arg0.router || arg0.i18n || arg0.store) {
// routesConfig = arguments[1]
// console.error('the usage of signature loadRoutes({router, store, i18n}, routesConfig) is out of date, please use the new signature: loadRoutes(routesConfig).')
// console.error('方法签名 loadRoutes({router, store, i18n}, routesConfig) 的用法已过时, 请使用新的方法签名 loadRoutes(routesConfig)。')
// }
// }
// /*************** 兼容 version < v0.6.1 *****************/
// // 应用配置
// // const {router, store, i18n} = appOptions
// // 如果 routesConfig 有值,则更新到本地,否则从本地获取
// if (routesConfig) {
// store.commit('account/setRoutesConfig', routesConfig)
// } else {
// routesConfig = store.getters['account/routesConfig']
// }
// // 如果开启了异步路由,则加载异步路由配置
// const asyncRoutes = store.state.setting.asyncRoutes
// if (asyncRoutes) {
// if (routesConfig && routesConfig.length > 0) {
// const routes = parseRoutes(routesConfig, routerMap)
// const finalRoutes = mergeRoutes(basicOptions.routes, routes)
// formatRoutes(finalRoutes)
// router.options = {...router.options, routes: finalRoutes}
// router.matcher = new Router({...router.options, routes:[]}).matcher
// router.addRoutes(finalRoutes)
// }
// }
// // 提取路由国际化数据
// mergeI18nFromRoutes(i18n, router.options.routes)
// // 初始化Admin后台菜单数据
// const rootRoute = router.options.routes.find(item => item.path === '/')
// const menuRoutes = rootRoute && rootRoute.children
// if (menuRoutes) {
// store.commit('setting/setMenuData', menuRoutes)
// }
// }
function loadRoutes(routesConfig) {
const { router, store, i18n } = appOptions
if (routesConfig) {
store.commit('account/setRoutesConfig', routesConfig)
} else {
routesConfig = store.getters['account/routesConfig']
}
// 如果开启了异步路由,则加载异步路由配置
const asyncRoutes = store.state.setting.asyncRoutes
if (asyncRoutes) {
if (routesConfig && routesConfig.length > 0) {
const routes = parseRoutes(routesConfig, routerMap)
formatAuthority(routes)
const finalRoutes = mergeRoutes(router.options.routes, routes)
router.options = { ...router.options, routes: finalRoutes }
router.matcher = new Router({ ...router.options, routes: [] }).matcher
router.addRoutes(finalRoutes)
}
}
// 初始化Admin后台菜单数据
const rootRoute = router.options.routes.find(item => item.path === '/')
const menuRoutes = rootRoute && rootRoute.children
if (menuRoutes) {
// 提取路由国际化数据
mergeI18nFromRoutes(i18n, menuRoutes)
store.commit('setting/setMenuData', menuRoutes)
}
}
/**
* 合并路由
* @param target {Route[]}
* @param source {Route[]}
* @returns {Route[]}
*/
function mergeRoutes(target, source) {
const routesMap = {}
target.forEach(item => routesMap[item.path] = item)
source.forEach(item => routesMap[item.path] = item)
return Object.values(routesMap)
}
/**
* 深度合并路由
* @param target {Route[]}
* @param source {Route[]}
* @returns {Route[]}
*/
function deepMergeRoutes(target, source) {
// 映射路由数组
const mapRoutes = routes => {
const routesMap = {}
routes.forEach(item => {
routesMap[item.path] = {
...item,
children: item.children ? mapRoutes(item.children) : undefined
}
})
return routesMap
}
const tarMap = mapRoutes(target)
const srcMap = mapRoutes(source)
// 合并路由
const merge = deepMerge(tarMap, srcMap)
// 转换为 routes 数组
const parseRoutesMap = routesMap => {
return Object.values(routesMap).map(item => {
if (item.children) {
item.children = parseRoutesMap(item.children)
} else {
delete item.children
}
return item
})
}
return parseRoutesMap(merge)
}
/**
* 格式化路由
* @param routes 路由配置
*/
function formatRoutes(routes) {
routes.forEach(route => {
const { path } = route
if (!path.startsWith('/') && path !== '*') {
route.path = '/' + path
}
})
formatAuthority(routes)
}
/**
* 格式化路由的权限配置
* @param routes 路由
* @param pAuthorities 父级路由权限配置集合
*/
function formatAuthority(routes, pAuthorities = []) {
routes.forEach(route => {
const meta = route.meta
const defaultAuthority = pAuthorities[pAuthorities.length - 1] || { permission: '*' }
if (meta) {
let authority = {}
if (!meta.authority) {
authority = defaultAuthority
} else if (typeof meta.authority === 'string') {
authority.permission = meta.authority
} else if (typeof meta.authority === 'object') {
authority = meta.authority
const { role } = authority
if (typeof role === 'string') {
authority.role = [role]
}
if (!authority.permission && !authority.role) {
authority = defaultAuthority
}
}
meta.authority = authority
} else {
const authority = defaultAuthority
route.meta = { authority }
}
route.meta.pAuthorities = pAuthorities
if (route.children) {
formatAuthority(route.children, [...pAuthorities, route.meta.authority])
}
})
}
/**
* 从路由 path 解析 i18n key
* @param path
* @returns {*}
*/
function getI18nKey(path) {
const keys = path.split('/').filter(item => !item.startsWith(':') && item != '')
keys.push('name')
return keys.join('.')
}
/**
* 加载导航守卫
* @param guards
* @param options
*/
function loadGuards(guards, options) {
const { beforeEach, afterEach } = guards
const { router } = options
beforeEach.forEach(guard => {
if (guard && typeof guard === 'function') {
router.beforeEach((to, from, next) => guard(to, from, next, options))
}
})
afterEach.forEach(guard => {
if (guard && typeof guard === 'function') {
router.afterEach((to, from) => guard(to, from, options))
}
})
}
export { parseRoutes, loadRoutes, formatAuthority, getI18nKey, loadGuards, deepMergeRoutes, formatRoutes, setAppOptions }
import Vue from 'vue'
import App from './App.vue'
import {initRouter} from './router'
import './theme/index.less'
import Antd from 'ant-design-vue'
import Viser from 'viser-vue'
// import '@/mock'//注释掉这句话,就会使用服务端API
import store from './store'
import 'animate.css/source/animate.css'
import Plugins from '@/plugins'
import {initI18n} from '@/utils/i18n'
import bootstrap from '@/bootstrap'
import 'moment/locale/zh-cn'
const router = initRouter(store.state.setting.asyncRoutes)
const i18n = initI18n('CN', 'US')
// var sso = window.g.ssoUrlPc
// console.log(sso,'-----------------')
Vue.use(Antd)
Vue.config.productionTip = false
Vue.use(Viser)
Vue.use(Plugins)
bootstrap({router, store, i18n, message: Vue.prototype.$message})
new Vue({
router,
store,
i18n,
render: h => h(App),
}).$mount('#app')
import { loadRoutes, loadGuards, setAppOptions } from '@/utils/routerUtil'
import { loadInterceptors } from '@/utils/request'
import guards from '@/router/guards'
import interceptors from '@/utils/axios-interceptors'
/**
* 启动引导方法
* 应用启动时需要执行的操作放在这里
* @param router 应用的路由实例
* @param store 应用的 vuex.store 实例
* @param i18n 应用的 vue-i18n 实例
* @param i18n 应用的 message 实例
*/
function bootstrap({ router, store, i18n, message }) {
// 设置应用配置
setAppOptions({ router, store, i18n })
// 加载 axios 拦截器
loadInterceptors(interceptors, { router, store, i18n, message })
// 加载路由
loadRoutes()
// 加载路由守卫
loadGuards(guards, { router, store, i18n, message })
}
export default bootstrap
import TabsView from '@/layouts/tabs/TabsView'
import BlankView from '@/layouts/BlankView'
// import PageView from '@/layouts/PageView'
console.log(process.env.NODE_ENV, '----')
//const groupLink = process.env.NODE_ENV === 'production' ? window.g.groupLink : 'http://10.105.191.35:12024//#/App'
//console.log('groupLink', groupLink)
// 路由配置
const options = {
routes: [
{
path: '/login',
name: '登录页',
component: () => import('@/pages/login')
},
{
path: '*',
name: '404',
component: () => import('@/pages/exception/404')
},
{
path: '/403',
name: '403',
component: () => import('@/pages/exception/403')
},
{
path: '/',
name: '首页',
component: TabsView,
redirect: '/login',
children: [
{
path: 'dashboard',
name: '首页',
component: () => import('@/pages/dashboard/index'),
},
{
path: 'WoManage',
name: '工单管理',
meta: {
authority: {
role: 'WoAdmin'
}
},
component: BlankView,
children: [
{
path: 'search',
name: 'Search',
meta: {
authority: { permission: 'ViewSearch' }
},
component: () => import('@/pages/workorderManage/Search')
},
{
path: 'woList',
name: '工单处理',
meta: {
authority: { permission: 'ViewWorkOrderList' }
},
component: () => import('@/pages/workorderManage/WorkOrderList')
},
{
path: 'woDetail',
name: '工单详情',
meta: {
invisible: true // 不渲染到菜单栏
},
component: () => import('@/pages/workorderManage/WorkOrderDetail')
}
]
},
{
path: 'SysManage',
name: '系统管理',
component: BlankView,
meta: {
authority: {
role: 'SysAdmin'
}
},
children: [
{
path: 'product',
name: '非转贴Product维护',
meta: {
authority: { permission: 'ViewProduct' }
},
component: () => import('@/pages/sysManage/Product')
},
{
path: 'markRule',
name: 'ShenNongMark取值规则维护',
meta: {
authority: { permission: 'ViewMarkRules' }
},
component: () => import('@/pages/sysManage/MarkRules')
},
{
path: 'sjWoVersionConfig',
name: 'AB2升版卡控维护',
meta: {
authority: { permission: 'ViewSjWoVersionConfig' }
},
component: () => import('@/pages/sysManage/SjWoVersionConfig')
}
]
},
{
path: 'DieManage',
name: '配DIE工单管理',
meta: {
authority: {
role: 'DieAdmin'
}
},
component: BlankView,
children: [
{
path: 'productBom',
name: '产品型号BOM',
meta: {
authority: { permission: 'ViewProductBom' }
},
component: () => import('@/pages/dieManage/ProductBom')
},
{
path: 'woInventory',
name: '主料待工单库存',
meta: {
authority: { permission: 'ViewWoInventory' }
},
component: () => import('@/pages/dieManage/WoInventory')
},
{
path: 'topDieInventory',
name: 'TOP DIE库存',
meta: {
authority: { permission: 'ViewTopDieInventory' }
},
component: () => import('@/pages/dieManage/TopDieInventory')
}, {
path: 'dieConfig',
name: 'AB1开单管理',
meta: {
authority: { permission: 'ViewDieConfig' }
},
component: () => import('@/pages/dieManage/DieConfig')
},
{
path: 'createdWoManage',
name: '已创建工单管理',
meta: {
authority: { permission: 'ViewCreatedWoManage' }
},
component: () => import('@/pages/dieManage/CreatedWoManage')
},
{
path: 'assistMaintainInterface',
name: '产品物料维护',
meta: {
invisible: true // 不渲染到菜单栏
},
component: () => import('@/pages/dieManage/AssistMaintainInterface')
},
{
path: 'ingredientBinding',
name: '配料绑定界面',
meta: {
invisible: true // 不渲染到菜单栏
},
component: () => import('@/pages/dieManage/IngredientBinding')
},
{
path: 'woDetails',
name: '工单详情',
meta: {
invisible: true // 不渲染到菜单栏
},
component: () => import('@/pages/dieManage/WoDetails')
}
]
},
]
}
]
}
export default options
import routerMap from './router.map'
import { parseRoutes } from '@/utils/routerUtil'
// 异步路由配置
const routesConfig = [
'login',
'root',
{
router: 'exp404',
path: '*',
name: '404'
},
{
router: 'exp403',
path: '/403',
name: '403'
},
{
router: 'homes',
path: '/homes',
name: 'homes'
}
// {
// router:'toDo1',
// path: '/cp/toDo',
// name: 'toDo1',
// },
// {
// router:'toDo2',
// path: '/ft/toDo',
// name: 'toDo2',
// },
]
const options = {
routes: parseRoutes(routesConfig, routerMap)
}
export default options
基于现在这些文件,我还是固定的的路由,我该如何改成动态路由?
最新发布