import { mergeI18nFromRoutes } from '@/utils/i18nUtil'; import deepMerge from 'deepmerge'; //应用配置 let 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) { let routes = []; routesConfig.forEach(item => { // 获取注册在 routerMap 中的 router,初始化 routeCfg let router = undefined, 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 route = { path: routeCfg.path || router.path || routeCfg.router, name: routeCfg.name || router.name, component: router.component, redirect: routeCfg.redirect || router.redirect, meta: { authority: routeCfg.authority || router.authority || routeCfg.meta?.authority || router.meta?.authority || '*', icon: routeCfg.icon || router.icon || routeCfg.meta?.icon || router.meta?.icon, page: routeCfg.page || router.page || routeCfg.meta?.page || router.meta?.page, link: routeCfg.link || router.link || routeCfg.meta?.link || router.meta?.link, }, }; 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) { // 应用配置 const { router, store, i18n } = appOptions; // 如果 routesConfig 有值,则更新到本地,否则从本地获取 if (routesConfig) { store.commit('accountModule/setRoutesConfig', routesConfig); } else { routesConfig = store.getters['accountModule/routesConfig']; } // 提取路由国际化数据 mergeI18nFromRoutes(i18n, router.options.routes); // 初始化Admin后台菜单数据 const rootRoute = router.options.routes.find(item => item.path === '/'); const menuRoutes = rootRoute && rootRoute.children; if (menuRoutes) { store.commit('settingModule/setMenuData', menuRoutes); } } /** * 深度合并路由 * @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, };