import Vue from "vue"; import Router from "vue-router"; import http from "../utils/request"; import { isURL } from "@/utils/validate"; import Cookies from "js-cookie"; Vue.use(Router); // 解决Vue-Router升级导致的Uncaught(in promise) navigation guard问题---------- const originalPush = Router.prototype.push; Router.prototype.push = function push(location, onResolve, onReject) { if (onResolve || onReject) { return originalPush.call(this, location, onResolve, onReject); } return originalPush.call(this, location).catch((err) => err); }; // 解决Vue-Router升级导致的Uncaught(in promise) navigation guard问题---------- // 页面路由(独立页面) export const pageRoutes = [ { path: "/404", component: () => import("@/page-subspecialty/views/pages/404"), name: "404", meta: { title: "404未找到" }, beforeEnter(to, from, next) { // 拦截处理特殊业务场景 // 如果, 重定向路由包含__双下划线, 为临时添加路由 if (/__.*/.test(to.redirectedFrom)) { return next(to.redirectedFrom.replace(/__.*/, "")); } next(); }, }, { path: "/login", component: () => import("@/page-subspecialty/views/pages/login"), name: "login", meta: { title: "登录" }, }, { path: "/pacs", component: () => import("@/page-subspecialty/views/pages/pacsManage/index"), name: "pacs", meta: { title: "pacs浏览器", isTab: true }, }, ]; // 模块路由(基于主入口布局页面)*8 export const moduleRoutes = { path: "/", component: () => import("@/page-subspecialty/views/main"), name: "main", redirect: { name: "outpatientManagement" }, meta: { title: "首页" }, children: [ { path: "/outpatientManagement", component: () => import("@/page-subspecialty/views/modules/outpatientManagement/call"), name: "outpatientManagement", meta: { title: "分诊管理", isTab: true }, }, // ok镜 { path: "/patientInfo", name: "patientInfo", meta: { title: "详情", isTab: true }, component: () => import( "@/page-subspecialty/views/modules/optometryManagement/seeDoctor/index" ), }, { path: "/iframe", component: null, name: "iframe", meta: { title: "iframe", isTab: true }, }, { path: "/redirect", name: "redirect", component: () => import("@/page-subspecialty/views/redirect"), }, { path: "/ot", name: "ot", component: () => import("@/page-subspecialty/views/modules/formList/laserSurgery.vue"), }, ], }; export function addDynamicRoute(routeParams, router) { // 组装路由名称, 并判断是否已添加, 如是: 则直接跳转 var routeName = routeParams.routeName; var dynamicRoute = window.SITE_CONFIG["dynamicRoutes"].filter( (item) => item.name === routeName )[0]; if (dynamicRoute) { return router.push({ name: routeName, params: routeParams.params }); } // 否则: 添加并全局变量保存, 再跳转 dynamicRoute = { path: routeName, component: () => Promise.resolve( require(`@/page-subspecialty/views/modules/${routeParams.path}`).default ), // component: () => import(`@/views/modules/${routeParams.path}`), name: routeName, meta: { ...window.SITE_CONFIG["contentTabDefault"], menuId: routeParams.menuId, title: `${routeParams.title}`, }, }; router.addRoutes([ { ...moduleRoutes, name: `main-dynamic__${dynamicRoute.name}`, children: [dynamicRoute], }, ]); window.SITE_CONFIG["dynamicRoutes"].push(dynamicRoute); router.push({ name: dynamicRoute.name, params: routeParams.params }); } const createRouter = () => new Router({ mode: "history", scrollBehavior: () => ({ y: 0 }), routes: pageRoutes.concat(moduleRoutes), }); const router = createRouter(); // [vue-router] Duplicate named routes definition 重复的命名路由定义 // 动态路由退出再登录会出现警告重复路由 // 解决方案:在退出时调用resetRouter()方法 export function resetRouter() { const newRouter = createRouter(); router.matcher = newRouter.matcher; // reset router } router.beforeEach((to, from, next) => { // 添加动态(菜单)路由 // 已添加或者当前路由为页面路由, 可直接访问 if ( window.SITE_CONFIG["dynamicMenuRoutesHasAdded"] || fnCurrentRouteIsPageRoute(to, pageRoutes) ) { return next(); } if (to.path === from.path) { return; } if ( to.name === "login" || to.path === "/login" || to.path === "satusScreen" || to.name === "satusScreen" ) { next(); } else { // 获取字典列表, 添加并全局变量保存 // http.get('/sys/dict/type/all').then(({ data: res }) => { // if (res.code !== 0) { // return // } // window.SITE_CONFIG['dictList'] = res.data // }).catch(() => {}) // 获取左侧菜单列表,添加并全局变量保存 http .get("/sys/menu/nav") .then(({ data: res }) => { if (res.code !== 0) { Vue.prototype.$message.error(res.msg); return next({ name: "login" }); } window.SITE_CONFIG["menuList"] = res.data; }) .catch(() => { return next({ name: "login" }); }); // 获取菜单管理菜单列表,并添加动态路由 http .get("/sys/menu/list", { params: { type: 0, }, }) .then(({ data: res }) => { if (res.code !== 0) { Vue.prototype.$message.error(res.msg); return next({ name: "login" }); } // window.SITE_CONFIG['menuList'] = res.data const menuListChild = res.data.filter( (item) => item.children.length > 0 ); // console.log(menuListChild) fnAddDynamicMenuRoutes( JSON.parse(JSON.stringify(res.data)), menuListChild.length ); next({ ...to, replace: true }); }) .catch(() => { // console.log(123) return next({ name: "login" }); }); // 获取【字段字典表】, 添加并全局变量保存 // http.get('/sys/table/dict/getList', { params: { type: 1 }}).then(({ data: res }) => { // window.SITE_CONFIG['dict_colSearch'] = res.data // }) getInitData(); } }); function getInitData() { // 获取字典列表, 添加并全局变量保存 // http.get('/sys/dict/type/all').then(({ data: res }) => { // if (res.code !== 0) { return } // window.SITE_CONFIG['dictList'] = res.data // }) // 获取【字段字典表】, 添加并全局变量保存 // http.get('/table/dict/optionsColumn').then(({ data: res }) => { // window.SITE_CONFIG['dict_colAll'] = res.data // }) // // // 获取【字段字典表】, 添加并全局变量保存 // http.get('/table/dict/optionsColumn', { params: { type: 1 }}).then(({ data: res }) => { // window.SITE_CONFIG['dict_colSearch'] = res.data // }) // // // 获取【字段字典表】, 添加并全局变量保存 // http.get('/table/dict/optionsColumn', { params: { type: 2 }}).then(({ data: res }) => { // window.SITE_CONFIG['dict_colChart'] = res.data // }) // // // 获取【字段字典表】, 添加并全局变量保存 // http.get('/table/dict/optionsColumn', { params: { type: 3 }}).then(({ data: res }) => { // window.SITE_CONFIG['dict_colCrf'] = res.data // }) // // // 获取【字段字典表】, 添加并全局变量保存 // http.get('/table/dict/optionsColumn', { params: { type: 4 }}).then(({ data: res }) => { // window.SITE_CONFIG['dict_colExport'] = res.data // }) // 获取【检查项目字典】, 添加并全局变量保存 // http.get('/table/dict/examItem').then(({ data: res }) => { // sortChinese(res.data, 'itemName') // window.SITE_CONFIG['dict_examItem'] = res.data // }) // 获取【设备信息字典】, 添加并全局变量保存 // http.get('/device/getData2RelDeviceList').then(({ data: res }) => { // window.SITE_CONFIG['dict_device'] = res.data // }) // 获取【设备与检查项目字典】, 添加并全局变量保存 // http.get('/device/getData2RelDeviceItemList').then(({ data: res }) => { // window.SITE_CONFIG['dict_device_item'] = res.data // }) } /** * 判断当前路由是否为页面路由 * @param {*} route 当前路由 * @param {*} pageRoutes 页面路由 */ function fnCurrentRouteIsPageRoute(route, pageRoutes = []) { var temp = []; for (var i = 0; i < pageRoutes.length; i++) { if (route.path === pageRoutes[i].path) { return true; } if (pageRoutes[i].children && pageRoutes[i].children.length >= 1) { temp = temp.concat(pageRoutes[i].children); } } return temp.length >= 1 ? fnCurrentRouteIsPageRoute(route, temp) : false; } /** * 添加动态(菜单)路由 * PH:自上而下遍历,累积平铺 * @param {*} menuList 菜单列表 * @param {*} routes 递归创建的动态(菜单)路由 */ function fnAddDynamicMenuRoutes( menuList = [], menuListChildLength, routes = [] ) { let index = 0; // console.log(menuList) menuList.forEach((item, i) => { // eslint-disable-next-line let URL = (item.url || "").replace(/{{([^}}]+)?}}/g, (s1, s2) => eval(s2)); // URL支持{{ window.xxx }}占位符变量 item["meta"] = { ...window.SITE_CONFIG["contentTabDefault"], menuId: item.id, title: item.name, }; if (isURL(URL)) { item["path"] = item["name"] = `i-${item.id}`; item["meta"].push({ iframeURL: URL, }); } else { // console.log(URL) URL = URL.replace(/^\//, "").replace(/_/g, "-"); item["path"] = "/" + URL.replace(/\//g, "-"); item["name"] = URL.replace(/\//g, "-"); // 坑!!!父级也必须要有component,父级要有自己的vue组件,父级路由必须有占位符 // 其孩子children才能展示出来,孩子展示在父级占位符的地方 URL.includes("seeDoctor") ? (URL = "seeDoctor") : ""; // 不同父级有相同子级seeDoctor,防止面包屑冲突,动态路由名字区分设置为seeDoctor、seeDoctorOne,在寻找组件时替换回seeDoctor,可以找到对应组件路径 item["component"] = () => Promise.resolve( require(`@/page-subspecialty/views/modules/${URL}`).default ); // 如果是父级给父级添加重定向到子菜单第一项 if (item.children.length > 0 && item.children[0].url) { // console.log(item) // isShow:0显示不菜单 1显示菜单 item.children[0].isShow === 0 ? "" : (item["redirect"] = "/" + item.children[0].url.replace(/\//g, "-")); } } if (item.children.length > 0) { index++; fnAddDynamicMenuRoutes(item.children); } }); // routes = menuList // console.log(routes) // 此处一定要加判断,因为此方法在递归,要等到递归完成后再执行下面的内容 // 坑!!!如果不加此判断,this.$route.matched面包屑的父级就不会展示 if (menuListChildLength === index) { routes = menuList; // PH:底层调用一次 // 添加路由 router.addRoutes([ { ...moduleRoutes, name: "main-dynamic-menu", children: [...routes], }, { path: "*", redirect: { name: "404" } }, ]); // console.log('----------------------') window.SITE_CONFIG["dynamicMenuRoutes"] = routes; window.SITE_CONFIG["dynamicMenuRoutesHasAdded"] = true; } } export default router;