5 changed files with 764 additions and 336 deletions
			
			
		| @ -0,0 +1,296 @@ | |||
| <template> | |||
|   <el-dialog | |||
|     title="图片编辑3" | |||
|     top="1vh" | |||
|     width="95%" | |||
|     :visible.sync="visible" | |||
|     fullscreen | |||
|     append-to-body | |||
|     class="img-editor" | |||
|     @closed="closeDialog" | |||
|   > | |||
|     <i class="el-icon-picture-outline replace-picture" /> | |||
|     <input id="inputFile" class="replace-picture" type="file" name="" accept="image/jpeg,image/jpg,image/png" @change="replaceHandle"> | |||
|     <div class="dialog-container"> | |||
|       <div id="tui-image-editor" /> | |||
|     </div> | |||
|     <template slot="footer"> | |||
|       <el-button @click="visible = false">{{ $t('cancel') }}</el-button> | |||
|       <el-button type="primary" @click="submit">{{ $t('confirm') }}</el-button> | |||
|     </template> | |||
|   </el-dialog> | |||
| </template> | |||
| 
 | |||
| <script> | |||
| import 'tui-image-editor/dist/tui-image-editor.css' | |||
| import 'tui-color-picker/dist/tui-color-picker.css' | |||
| import ImageEditor from 'tui-image-editor' | |||
| // 汉化 | |||
| const locale_zh = { | |||
|   // override default English locale to your custom | |||
|   Crop: '裁剪', | |||
|   Resize: '调整大小', | |||
|   ZoomIn: '放大', | |||
|   Hand: '拖拽', | |||
|   History: '历史记录', | |||
|   ZoomOut: '缩小', | |||
|   DeleteAll: '全部删除', | |||
|   Delete: '删除', | |||
|   Undo: '撤销', | |||
|   Redo: '反撤销', | |||
|   Reset: '重置', | |||
|   Flip: '镜像', | |||
|   Rotate: '旋转', | |||
|   Draw: '画', | |||
|   Shape: '形状标注', | |||
|   Icon: '图标标注', | |||
|   Text: '文字标注', | |||
|   Mask: '遮罩', | |||
|   Filter: '滤镜', | |||
|   Bold: '加粗', | |||
|   Italic: '斜体', | |||
|   Underline: '下划线', | |||
|   Left: '左对齐', | |||
|   Center: '居中', | |||
|   Right: '右对齐', | |||
|   Color: '颜色', | |||
|   'Text size': '字体大小', | |||
|   Custom: '自定义', | |||
|   Square: '正方形', | |||
|   Apply: '应用', | |||
|   Cancel: '取消', | |||
|   'Flip X': 'X 轴', | |||
|   'Flip Y': 'Y 轴', | |||
|   Range: '区间', | |||
|   Stroke: '描边', | |||
|   Fill: '填充', | |||
|   Circle: '圆', | |||
|   Triangle: '三角', | |||
|   Rectangle: '矩形', | |||
|   Free: '曲线', | |||
|   Straight: '直线', | |||
|   Arrow: '箭头', | |||
|   'Arrow-2': '箭头2', | |||
|   'Arrow-3': '箭头3', | |||
|   'Star-1': '星星1', | |||
|   'Star-2': '星星2', | |||
|   Polygon: '多边形', | |||
|   Location: '定位', | |||
|   Heart: '心形', | |||
|   Bubble: '气泡', | |||
|   'Custom icon': '自定义图标', | |||
|   'Load Mask Image': '加载蒙层图片', | |||
|   Grayscale: '灰度', | |||
|   Blur: '模糊', | |||
|   Sharpen: '锐化', | |||
|   Emboss: '浮雕', | |||
|   'Remove White': '除去白色', | |||
|   Distance: '距离', | |||
|   Brightness: '亮度', | |||
|   Noise: '噪音', | |||
|   'Color Filter': '彩色滤镜', | |||
|   Sepia: '棕色', | |||
|   Sepia2: '棕色2', | |||
|   Invert: '负片', | |||
|   Pixelate: '像素化', | |||
|   Threshold: '阈值', | |||
|   Tint: '色调', | |||
|   Multiply: '正片叠底', | |||
|   Blend: '混合色' | |||
|   // etc... | |||
| } | |||
| // 去除不需要的右上角的Load和Download和左上角这个默认的logo | |||
| const customTheme = { | |||
|   // image 坐上角度图片 | |||
|   'common.bi.image': '', // 在这里换上你喜欢的logo图片 | |||
|   'common.bisize.width': '0px', | |||
|   'common.bisize.height': '0px', | |||
|   'common.backgroundImage': 'none', | |||
|   'common.backgroundColor': '#f3f4f6', | |||
|   'common.border': '1px solid #444', | |||
| 
 | |||
|   // header | |||
|   'header.backgroundImage': 'none', | |||
|   'header.backgroundColor': '#f3f4f6', | |||
|   'header.border': '0px', | |||
|   'header.display': 'none', | |||
| 
 | |||
|   // load button | |||
|   'loadButton.backgroundColor': '#fff', | |||
|   'loadButton.border': '1px solid #ddd', | |||
|   'loadButton.color': '#222', | |||
|   'loadButton.fontFamily': 'NotoSans, sans-serif', | |||
|   'loadButton.fontSize': '12px', | |||
|   'loadButton.display': 'none', // 可以直接隐藏掉 | |||
| 
 | |||
|   // download button | |||
|   'downloadButton.backgroundColor': '#fdba3b', | |||
|   'downloadButton.border': '1px solid #fdba3b', | |||
|   'downloadButton.color': '#fff', | |||
|   'downloadButton.fontFamily': 'NotoSans, sans-serif', | |||
|   'downloadButton.fontSize': '12px', | |||
|   'downloadButton.display': 'none', // 可以直接隐藏掉 | |||
| 
 | |||
|   // icons default | |||
|   'menu.normalIcon.color': '#8a8a8a', | |||
|   'menu.activeIcon.color': '#555555', | |||
|   'menu.disabledIcon.color': '#434343', | |||
|   'menu.hoverIcon.color': '#e9e9e9', | |||
|   'submenu.normalIcon.color': '#8a8a8a', | |||
|   'submenu.activeIcon.color': '#e9e9e9', | |||
| 
 | |||
|   'menu.iconSize.width': '24px', | |||
|   'menu.iconSize.height': '24px', | |||
|   'submenu.iconSize.width': '32px', | |||
|   'submenu.iconSize.height': '32px', | |||
| 
 | |||
|   // submenu primary color | |||
|   'submenu.backgroundColor': '#1e1e1e', | |||
|   'submenu.partition.color': '#858585', | |||
| 
 | |||
|   // submenu labels | |||
|   'submenu.normalLabel.color': '#858585', | |||
|   'submenu.normalLabel.fontWeight': 'lighter', | |||
|   'submenu.activeLabel.color': '#fff', | |||
|   'submenu.activeLabel.fontWeight': 'lighter', | |||
| 
 | |||
|   // checkbox style | |||
|   'checkbox.border': '1px solid #ccc', | |||
|   'checkbox.backgroundColor': '#fff', | |||
| 
 | |||
|   // rango style | |||
|   'range.pointer.color': '#fff', | |||
|   'range.bar.color': '#666', | |||
|   'range.subbar.color': '#d1d1d1', | |||
| 
 | |||
|   'range.disabledPointer.color': '#414141', | |||
|   'range.disabledBar.color': '#282828', | |||
|   'range.disabledSubbar.color': '#414141', | |||
| 
 | |||
|   'range.value.color': '#fff', | |||
|   'range.value.fontWeight': 'lighter', | |||
|   'range.value.fontSize': '11px', | |||
|   'range.value.border': '1px solid #353535', | |||
|   'range.value.backgroundColor': '#151515', | |||
|   'range.title.color': '#fff', | |||
|   'range.title.fontWeight': 'lighter', | |||
| 
 | |||
|   // colorpicker style | |||
|   'colorpicker.button.border': '1px solid #1e1e1e', | |||
|   'colorpicker.title.color': '#fff' | |||
| } | |||
| export default { | |||
|   props: { | |||
|     bodyStyleShow: { | |||
|       type: Boolean, | |||
|       default: false | |||
|     }, | |||
|     // 是否为病例模板 | |||
|     title: { | |||
|       type: String, | |||
|       default: '' | |||
|     } | |||
|   }, | |||
|   data() { | |||
|     return { | |||
|       visible: false, | |||
|       imgUrl: '', | |||
|       imgAlt: '', | |||
|       instance: null, | |||
|       textOne: '', | |||
|       textTwo: '', | |||
|       textThree: '' | |||
|     } | |||
|   }, | |||
|   mounted() { | |||
|     // ImageEditor | |||
| 
 | |||
|   }, | |||
|   methods: { | |||
|     init(textOne, textTwo, textThree) { | |||
|       textOne ? this.textOne = textOne : '' | |||
|       textTwo ? this.textTwo = textTwo : '' | |||
|       textThree ? this.textThree = textThree : '' | |||
|       this.visible = true | |||
|       this.$nextTick(() => { | |||
|         // console.log(this.imgUrl) | |||
|         this.instance = new ImageEditor( | |||
|           document.querySelector('#tui-image-editor'), | |||
|           { | |||
|             includeUI: { | |||
|               loadImage: { | |||
|                 path: this.imgUrl, | |||
|                 name: 'image' | |||
|               }, | |||
|               // menu: ['crop', 'rotate', 'draw', 'shape', 'icon', 'text', 'filter'], // 底部菜单按钮列表 隐藏镜像flip和遮罩mask | |||
|               initMenu: 'draw', | |||
|               selectionStyle: { | |||
|                 lineWidth: 5, | |||
|                 borderColor: '#000000' | |||
|               }, | |||
|               menuBarPosition: 'bottom', | |||
|               locale: locale_zh, // 本地化语言为中文 | |||
|               theme: customTheme // 自定义主题 | |||
|             } | |||
|           } | |||
|         ) | |||
|         // document.querySelector('.tie-btn-resize').style.display = 'none' // 隐藏顶部重置按钮 | |||
|         document.querySelector('.tie-btn-mask').style.display = 'none' // 隐藏遮罩按钮 | |||
|       }) | |||
|     }, | |||
|     submit() { | |||
|       const base64String = this.instance.toDataURL() | |||
|       // console.log(base64String) | |||
|       this.$emit('fullImgBack', base64String, this.imgAlt, this.textOne, this.textTwo, this.textThree) | |||
|       this.visible = false | |||
|       // 掉后台接口存入后台 --- 暂时用不到 | |||
|       // const data = window.atob(base64String.split(',')[1]) | |||
|       // const ia = new Uint8Array(data.length) | |||
|       // for (let i = 0; i < data.length; i++) { | |||
|       //   ia[i] = data.charCodeAt(i) | |||
|       // } | |||
|       // const blob = new Blob([ia], { type: 'image/png' }) | |||
|       // const fd = new FormData() | |||
|       // fd.append('image', blob) | |||
|       // upload fd | |||
|     }, | |||
|     // 替换图片 | |||
|     replaceHandle(e) { | |||
|       var file = e.target.files[0] | |||
|       console.log(file) | |||
|       var reader = new FileReader() | |||
|       var that = this | |||
|       reader.readAsDataURL(file) | |||
|       console.log(reader) | |||
|       reader.onload = function(e) { | |||
|         that.imgUrl = reader.result | |||
|         that.init() | |||
|       } | |||
|     }, | |||
|     closeDialog() { | |||
|       this.$emit('closeDialog') | |||
|       this.visible = false | |||
|     } | |||
|   } | |||
| } | |||
| </script> | |||
| <style lang="scss" scoped> | |||
| .img-editor{ | |||
|   .replace-picture { | |||
|     z-index: 999; | |||
|     position: fixed; | |||
|     right:35px; | |||
|     top: 73px; | |||
|     cursor: pointer; | |||
|   } | |||
|   .dialog-container { | |||
|     height: calc(100vh - 1vh - 54px - 70px); | |||
|   } | |||
|   #inputFile { | |||
|     opacity: 0; | |||
|   } | |||
|   .el-icon-picture-outline { | |||
|     font-size: 28px; | |||
|   } | |||
| } | |||
| </style> | |||
| @ -1,316 +1,357 @@ | |||
| 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') | |||
|     } | |||
|   ] | |||
| } | |||
| 
 | |||
| 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组件,父级路由必须有<router-view />占位符
 | |||
|       // 其孩子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 | |||
| 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/mraForm.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组件,父级路由必须有<router-view />占位符
 | |||
|       // 其孩子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; | |||
|  | |||
| @ -0,0 +1,32 @@ | |||
| <template> | |||
|   <div id="operation-record" style=" background: #fff; padding: 10px 20px 50px 20px;page-break-after:always"> | |||
|     <div class="btnBox"> | |||
|       <el-button v-print="'#laserFunc'" size="small">打印</el-button> | |||
|       <el-button type="primary" size="small" @click="handleSaveTable">保存</el-button> | |||
|     </div> | |||
|     <div id="laserFunc"> | |||
|       <p style="color:#000000;font-size:32px;margin:0 0 30px 0;text-align:center;"> | |||
|         眼底血管造影知情同意书 | |||
|       </p> | |||
|     </div> | |||
|   </div> | |||
| </template> | |||
| 
 | |||
| <script> | |||
| export default { | |||
|   name: 'MraForm', | |||
|   methods: { | |||
|     handleSaveTable() { | |||
|       const data = { | |||
|         treat: this.treatData, | |||
|         beforeTreat: this.beforeTreat | |||
|       } | |||
|       this.$emit('save', data) | |||
|     } | |||
|   } | |||
| } | |||
| </script> | |||
| 
 | |||
| <style scoped> | |||
| 
 | |||
| </style> | |||
					Loading…
					
					
				
		Reference in new issue