import Vue from 'vue' import Router from 'vue-router' import http from '../utils/request' import { isURL } from '@/utils/validate' 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: '/pacsManage', component: () => import('@/page-subspecialty/views/pages/pacsManage/index'), name: 'pacsManage', meta: { title: 'pacs浏览器', isTab: true } }, { path: '/pacs', component: () => import('@/page-subspecialty/views/pages/pacs/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') } ] } 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}` } } const dynamicRoutes = [ { ...moduleRoutes, name: `main-dynamic__${dynamicRoute.name}`, children: [dynamicRoute] } ] dynamicRoutes.forEach(res => { router.addRoute(res) }) // 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:底层调用一次 // 添加路由 const dynamicRoutes = [ { ...moduleRoutes, name: 'main-dynamic-menu', children: [...routes] }, { path: '*', redirect: { name: '404' }} ] dynamicRoutes.forEach(res => { router.addRoute(res) }) // 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