import { getMenus } from '@/api/system/menu' import { constantRouterIcon } from './router-icons' import { RouteRecordRaw } from 'vue-router' import { asyncRoutes } from '@/router/constant' import { BaseRoute } from '@/router/base' import type { AppRouteRecordRaw } from '@/router/types' import deepClone from '@/utils/deep.clone' import CourseKnowledgePoint from '@/views/teaching-manage/courseware-manage/model/CourseKnowledgePoint' import { PageEnum } from '@/enums/pageEnum' const Iframe = () => import('@/views/iframe/index.vue') const LayoutMap = new Map Promise>() LayoutMap.set('LAYOUT', asyncRoutes.Layout) LayoutMap.set('IFRAME', Iframe) /** * 格式化 后端 结构信息并递归生成层级路由表 * @param routerMap * @param parent * @returns {*} */ export const routerGenerator = (routerMap: any, parent?: any): any[] => { const asyncRoute: any = asyncRoutes const constantRouterI: any = constantRouterIcon return routerMap.map((item: any) => { if (item.type === 1) { return } const currentRouter: any = { // 路由地址 动态拼接生成如 /dashboard/workplace path: item.path.indexOf('/') > -1 ? item.path : `${(parent && parent.path) || ''}/${item.path}`, // 路由名称,建议唯一 name: item.path || '', // 该路由对应页面的 组件 component: asyncRoute[item.component], // meta: 页面标题, 菜单图标, 页面权限(供指令权限用,可去掉) show: item.hidden === 0 ? true : false, parent: item.parent, meta: { ...item.meta, label: item.name, title: item.name, id: item.id, icon: constantRouterI[item.icon] || null, parentPermission: item.parentPermission || null // permissions: item.meta.permissions || null, }, props: true } // console.log(item.name, '格式化路由') // 为了防止出现后端返回结果不规范,处理有可能出现拼接出两个 反斜杠 currentRouter.path = currentRouter.path.replace('//', '/') // 重定向 item.redirect && (currentRouter.redirect = item.redirect) // 是否有子菜单,并递归处理 if (item.children && item.children.length > 0) { //如果未定义 redirect 默认第一个子路由为 redirect // !item.redirect && (currentRouter.redirect = `${item.path}/${item.children[0].path}`) // Recursion currentRouter.children = routerGenerator(item.children, currentRouter) } return currentRouter }) } // 格式化路由 export const routerFormat = (routerMap: any) => { const newArr: any[] = [] for (let i = 0; i < routerMap.length; i++) { if (routerMap[i].type == 1) { continue } const { children, ...res } = routerMap[i] const currentRouter: any = { ...res } // 是否有子菜单,并递归处理 if (children && children.length > 0) { const tempChildren = routerFormat(children) // console.log(children, 'children', tempChildren) currentRouter.children = tempChildren } // console.log(currentRouter, 'currentRouter') newArr.push(currentRouter) } return newArr } // 格式化菜单 export const menuFormat = (menuMap: any, parent?: any) => { const newArr: any[] = [] for (let i = 0; i < menuMap.length; i++) { if (menuMap[i].type == 1) { continue } const { children, ...res } = menuMap[i] const currentRouter: any = { ...res, parent: parent ? parent.name : null } // 是否有子菜单,并递归处理 if (children && children.length > 0) { // let flag = false; children.forEach((item: any) => { if (item.type == 0 && !item.hidden) { item.children = null } }) const tempChildren = menuFormat(children, currentRouter) currentRouter.children = tempChildren } newArr.push(currentRouter) } return newArr } /** * 路由多级嵌套数组处理成一维数组 * @param arr 传入路由菜单数据数组 * @returns 返回处理后的一维路由菜单数组 */ export function formatFlatteningRoutes(arr: any) { if (arr.length <= 0) return false for (let i = 0; i < arr.length; i++) { if (arr[i].children) { arr = arr.slice(0, i + 1).concat(arr[i].children, arr.slice(i + 1)) } } return arr } function getFirstMenu(routes: any) { // 可能没有权限 提示管理 if (routes && routes.length > 0) { let firstMenu: any = null routes.forEach((item: any) => { // 判断是否有首页菜单 if (!firstMenu) { if (item.children?.length > 0 && !item.hidden) { firstMenu = pathErgodic(item) } } }) if (checkPathUrl(firstMenu)) { return firstMenu } else { return '/' + firstMenu } } } function pathErgodic(item: any) { // console.log(item) let firstMenu: any = null item.children.forEach((i: any) => { if (!firstMenu && i.children?.length > 0 && !i.hidden) { let isChildrenList = false i.children.forEach((ii: any) => { if (!ii.hidden && ii.type) { isChildrenList = true } }) if (isChildrenList) { firstMenu = pathErgodic(i) } else { if (!firstMenu && checkPathUrl(i.path)) { firstMenu = i.path } else { if (!firstMenu && !i.hidden) { firstMenu = item.path + '/' + i.path } } } } else { if (!firstMenu && checkPathUrl(i.path)) { firstMenu = i.path } else { if (!firstMenu && !i.hidden) { firstMenu = item.path + '/' + i.path } } } }) return firstMenu } // 判断path有没有带/,并且是第一个位置 function checkPathUrl(path: any) { return path.indexOf('/') === 0 ? true : false } let tempArr: Array = [] /** * 动态生成菜单 * @returns {Promise} */ export const generatorDynamicRouter = (): any => { return new Promise((resolve, reject) => { getMenus({ delFlag: false }) .then((result) => { // 设置路由 setAuthList(result.data) const t = menuFormat(deepClone(result.data)) const routers = routerFormat(deepClone(result.data)) // 讲多级路由转化1级路由 // 格式化路由 BaseRoute.children = formatFlatteningRoutes(routerGenerator(routers)) const menu = routerGenerator(t) const firstMenu = getFirstMenu(routers) // console.log(firstMenu, 'firstMenu', BaseRoute) PageEnum.BASE_HOME = firstMenu // 同步 异步路由 resolve({ routes: BaseRoute, authList: tempArr, menu: menu }) }) .catch((err) => { reject(err) }) }) } /** * 设置所有的权限集合 * @returns */ export const setAuthList = (arr: any) => { arr.map((item: any) => { tempArr.push(item.permission + item.id) if (item.children && item.children.length > 0) { setAuthList(item.children) } }) } /** * * @param routes: any * @param component * @returns 格式化后带顶部的路由 */ export function addTopMenu(routes: any) { if (routes.length > 0) { let newArr = [] for (let i = 0; i < routes.length; i++) { if (routes[i].type == 1) { continue } let obj = routes[i] obj.belongTopMenu = obj.path if (routes[i].sysMenus && routes[i].sysMenus.length > 0) { obj.sysMenus = setTopMenu(routes[i].sysMenus, obj) } newArr.push(obj) } return newArr } } /** * * @param routes: any * @param 递归给每一层菜单附上一个 belongTopMenu * @returns */ export function setTopMenu(arr: any, topParentArr: any) { let newArr = [] for (let i = 0; i < arr.length; i++) { let obj = arr[i] obj.belongTopMenu = topParentArr.path if (arr[i].sysMenus && arr[i].sysMenus.length > 0) { obj.sysMenus = setTopMenu(arr[i].sysMenus, topParentArr) } newArr.push(obj) } return newArr }