60 changed files with 39284 additions and 175 deletions
			
			
		| @ -0,0 +1,234 @@ | |||
| <template> | |||
|   <div class="chart" :class="className" :style="{ height: height, width: width }" /> | |||
| </template> | |||
| <script> | |||
| import echarts from 'echarts' | |||
| import resize from './mixins/resize' | |||
| import cloneDeep from 'lodash/cloneDeep' | |||
| 
 | |||
| import { getAllDateMonthList, formatDate } from '@/utils' | |||
| 
 | |||
| export default { | |||
|   mixins: [resize], | |||
|   props: { | |||
|     className: { type: String, default: '' }, | |||
|     width: { type: String, default: '100%' }, | |||
|     height: { type: String, default: '200px' }, | |||
|     chartData: { type: Array, default: () => [] }, | |||
|     title: { type: String, default: '眼压' } | |||
|   }, | |||
|   data() { | |||
|     return { | |||
|       chart: null, | |||
|       disabled: false, | |||
|       data: [] | |||
|     } | |||
|   }, | |||
|   watch: { | |||
|     chartData: { | |||
|       handler(newVal, oldVal) { | |||
|         this.initChart() | |||
|       }, | |||
|       deep: true | |||
|     } | |||
|   }, | |||
|   mounted() { | |||
|     this.$nextTick(() => { | |||
|       this.initChart() | |||
|     }) | |||
|   }, | |||
|   beforeDestroy() { | |||
|     if (!this.chart) { return } | |||
|     this.chart.dispose() | |||
|     this.chart = null | |||
|   }, | |||
|   methods: { | |||
|     initChart() { | |||
|       this.chart = echarts.init(this.$el) | |||
|       this.data = cloneDeep(this.chartData) || [] | |||
|       this.setOptions() | |||
|     }, | |||
|     resize() { | |||
|       this.$_resizeHandler() | |||
|     }, | |||
|     setOptions() { | |||
|       let xDateStart = null | |||
|       let xDateEnd = null | |||
|       let dateMonthList = [] | |||
|       let xArrayDataValue = [] | |||
|       if (this.data && this.data.length > 0) { | |||
|         this.disabled = false | |||
|         this.data.sort((a, b) => { | |||
|           if (a && b && a.examTime && b.examTime) { return new Date(a.examTime) - new Date(b.examTime) } | |||
|         }) | |||
|         this.data = this.data.map(item => { | |||
|           return { | |||
|             ...item, | |||
|             examDate: formatDate(item.examTime, 'yyyy-MM-dd') | |||
|           } | |||
|         }) | |||
| 
 | |||
|         xDateStart = this.data[0].examDate | |||
|         xDateEnd = this.data[this.data.length - 1 || 0].examDate | |||
|         dateMonthList = getAllDateMonthList(xDateStart, xDateEnd) | |||
|         xArrayDataValue = [...new Set(this.data.map(item => item.examDate))] | |||
|       } else { | |||
|         this.disabled = true | |||
|       } | |||
| 
 | |||
|       const legendData = [] | |||
|       const seriesData = [] | |||
| 
 | |||
|       // const demo= { | |||
|       //   examTime: '', | |||
|       //   examDate: '', | |||
|       //   examType: '', | |||
|       //   examMemo: '', | |||
|       //   odIop: 1, | |||
|       //   osIop: 1, | |||
|       //   sodIop: null, | |||
|       //   sosIop: null, | |||
|       // } | |||
| 
 | |||
|       const itemObj = { | |||
|         'OD': ['odIop', 'sodIop'], | |||
|         'OS': ['osIop', 'sosIop'] | |||
|       } | |||
|       const colors = ['#FF7F00', '#6A3D9A', '#6af1b0', '#4d9bf9'] | |||
| 
 | |||
|       let i = 0 | |||
|       for (const obj in itemObj) { | |||
|         legendData.push(obj) | |||
| 
 | |||
|         const objValueColName = itemObj[obj][0] | |||
|         const objLabelColName = itemObj[obj][1] | |||
|         const serieData = [] | |||
| 
 | |||
|         this.data.forEach(item => { | |||
|           if (item[objValueColName] != null) { | |||
|             serieData.push({ | |||
|               name: item.examDate, | |||
|               value: [ | |||
|                 item.examDate, | |||
|                 item[objValueColName], | |||
|                 item[objLabelColName] | |||
|               ] | |||
|             }) | |||
|           } | |||
|         }) | |||
| 
 | |||
|         seriesData.push({ | |||
|           name: obj, | |||
|           type: 'line', | |||
|           data: serieData, | |||
|           showAllSymbol: true, | |||
|           smooth: true, | |||
|           itemStyle: { color: colors[i] }, | |||
|           symbolSize: 10 | |||
|         }) | |||
|         i++ | |||
|       } | |||
|       const thatData = this.data | |||
| 
 | |||
|       this.chart.setOption({ | |||
|         title: { text: this.title }, | |||
|         tooltip: { | |||
|           trigger: 'axis', | |||
|           className: 'test', | |||
|           axisPointer: { type: 'line' }, | |||
|           formatter: function(params, ticket, callback) { | |||
|             const thisDate = params[0].data.name | |||
|             let result = `日期:${thisDate} <br/>` | |||
|             const dateDataList = thatData.filter(item => { | |||
|               return String(item.examDate) === String(thisDate) | |||
|             }) | |||
| 
 | |||
|             // 效果1 | |||
|             // const styleCommon = `display:inline-block;width:60px;text-align:left;` | |||
|             // result += ` | |||
|             // <div style='border-top:1px dashed #fff;border-bottom:1px dashed #fff;padding:2px 0;margin:5px 0;'> | |||
|             // <span style="${styleCommon}margin-left:5px;">OD</span> | |||
|             // <span style="${styleCommon}">OS</span> | |||
|             // <span style="${styleCommon}width:100px;">检查时间</span> | |||
|             // </div>` | |||
|             // dateDataList.forEach(item => { | |||
|             //   result += ` | |||
|             //   <span style="${styleCommon}margin-left:5px;">${item.odIop || '-'}</span> | |||
|             //   <span style="${styleCommon}">${item.osIop || '-'}</span> | |||
|             //   <span style="${styleCommon}">${formatDate(item.examTime, 'hh:mm:ss')}(${item.iopType || '-'})</span> | |||
|             //   <br/>` | |||
|             // }) | |||
| 
 | |||
|             // 效果2 | |||
|             const tabelBorderStyle = 'border-right:1px solid #fff;border-bottom:1px solid #fff;' | |||
|             const tdStyle = 'border-left:1px solid #fff;border-top:1px solid #fff;width:60px;text-align:center;' | |||
|             result += `<table border="0" cellspacing="0" cellpadding="0" style="${tabelBorderStyle}" > | |||
|                         <tr> | |||
|                           <td style="${tdStyle}">OD</td> | |||
|                           <td style="${tdStyle}">OS</td> | |||
|                           <td style="${tdStyle}">检查时间</td> | |||
|                         </tr>` | |||
|             let trStr = '' | |||
|             dateDataList.forEach(item => { | |||
|               trStr += `<tr> | |||
|                           <td style="${tdStyle}">${item.odIop || '-'}</td> | |||
|                           <td style="${tdStyle}">${item.osIop || '-'}</td> | |||
|                           <td style="${tdStyle} width:100px;text-align:left;padding:0 5px;"> | |||
|                             ${formatDate(item.examTime, 'hh:mm:ss')} (${item.iopType || '-'}) | |||
|                           </td> | |||
|                         </tr>` | |||
|             }) | |||
|             result += `${trStr}</table>` | |||
| 
 | |||
|             return result | |||
|           } | |||
|         }, | |||
|         legend: { | |||
|           data: legendData, | |||
|           icon: 'pin' | |||
|         }, | |||
|         dataZoom: [{ | |||
|           type: 'inside', | |||
|           disabled: this.disabled, | |||
|           start: 0, | |||
|           end: 100 | |||
|         }], | |||
|         grid: { | |||
|           top: 45, | |||
|           left: 50, | |||
|           right: 50, | |||
|           bottom: 30, | |||
|           containLabel: false | |||
|         }, | |||
|         xAxis: [{ | |||
|           type: 'time', | |||
|           min: xDateStart, | |||
|           max: xDateEnd, | |||
|           data: xArrayDataValue, | |||
|           splitLine: { show: false }, | |||
|           axisLabel: { show: false }, | |||
|           axisTick: { show: false } | |||
|         }, { | |||
|           type: 'category', | |||
|           position: 'bottom', | |||
|           data: dateMonthList, | |||
|           axisPointer: { | |||
|             triggerTooltip: false, | |||
|             show: false | |||
|           }, | |||
|           axisTick: { show: true } | |||
|         }], | |||
|         yAxis: { type: 'value' }, | |||
|         series: seriesData | |||
|       }) | |||
|     } | |||
|   } | |||
| } | |||
| </script> | |||
| 
 | |||
| <style scoped> | |||
| .chart{ | |||
|   padding: 0 20px; | |||
| } | |||
| </style> | |||
| 
 | |||
| @ -0,0 +1,145 @@ | |||
| <template> | |||
|   <div class="component-container"> | |||
|     <div class="exam-info-container clearfix"> | |||
|       <div class="exam-title">{{ examName }}</div> | |||
|       <div class="exam-date-time-list" /> | |||
|     </div> | |||
| 
 | |||
|     <div class="dialog-container"> | |||
|       <el-table :data="activeObj.data" :span-method="arraySpanMethod" border style="width: 100%"> | |||
|         <el-table-column align="center" show-overflow-tooltip width="150px"> | |||
|           <template slot="header"> | |||
|             <el-select | |||
|               ref="select" | |||
|               v-model="activeRecId" | |||
|               placeholder="请选择" | |||
|               popper-class="c-el-select-popper" | |||
|               :popper-append-to-body="false" | |||
|               @visible-change="selectVisibleHandle" | |||
|             > | |||
|               <el-option | |||
|                 v-for="item in list" | |||
|                 :key="item.recId" | |||
|                 :label="item.time" | |||
|                 :value="item.recId" | |||
|                 @mouseover.native="preview(item)" | |||
|                 @mouseout.native="restore()" | |||
|               /> | |||
|             </el-select> | |||
|           </template> | |||
|           <template slot-scope="scope"> | |||
|             <span>{{ scope.row.name }}</span> | |||
|           </template> | |||
|         </el-table-column> | |||
|         <el-table-column align="center" show-overflow-tooltip label="OD"> | |||
|           <template slot-scope="scope"> | |||
|             <span>{{ (scope.row.both||scope.row.od)|f_null }}</span> | |||
|           </template> | |||
|         </el-table-column> | |||
|         <el-table-column align="center" show-overflow-tooltip label="OS"> | |||
|           <template slot-scope="scope"> | |||
|             <span>{{ (scope.row.both||scope.row.os)|f_null }}</span> | |||
|           </template> | |||
|         </el-table-column> | |||
|       </el-table> | |||
|     </div> | |||
|   </div> | |||
| </template> | |||
| 
 | |||
| <script> | |||
| export default { | |||
|   filters: { | |||
|     f_null(val) { | |||
|       if ((!val) || val === 'null') { return '' } else { return val } | |||
|     } | |||
|   }, | |||
|   props: { | |||
|     examName: { type: String, default: '' }, | |||
|     list: { type: Array, default: () => [] }, | |||
|     value: { type: Object, default: () => {} } | |||
|   }, | |||
|   data() { | |||
|     return { | |||
|       activeRecId: '', | |||
|       activeObj: { | |||
|         type: '', | |||
|         time: null, | |||
|         recId: '', | |||
|         data: [] | |||
|       } | |||
|     } | |||
|   }, | |||
|   watch: { | |||
|     activeRecId(val) { | |||
|       this.activeObj = this.list.find((item, index, array) => item.recId === val) | |||
|       this.$emit('input', this.activeObj) | |||
|     }, | |||
|     list(val) { | |||
|       this.init() | |||
|     } | |||
|   }, | |||
|   mounted() { | |||
|     if (this.list.length > 0) { this.init() } | |||
|   }, | |||
|   methods: { | |||
|     init() { | |||
|       this.activeRecId = this.list[0].recId | |||
|     }, | |||
|     arraySpanMethod({ row, column, rowIndex, columnIndex }) { | |||
|       if (row.both && column.property !== 'name') { | |||
|         // od列1,os列2.(合并od,隐藏os) | |||
|         if (columnIndex === 1) { | |||
|           return [1, 2] | |||
|         } else if (columnIndex === 2) { | |||
|           return [0, 0] | |||
|         } | |||
|       } | |||
|     }, | |||
|     preview(item) { | |||
|       this.activeObj = item | |||
|     }, | |||
|     restore() { | |||
|       this.activeObj = this.list.find((item, index, array) => item.recId === this.activeRecId) | |||
|     }, | |||
|     selectVisibleHandle(val) { | |||
|       if (val && this.list.length > 0) { | |||
|         const selectInputDom = this.$refs.select.$el | |||
|         // 偏移量 | |||
|         const width = selectInputDom.offsetWidth | |||
|         const selectPoper = selectInputDom.getElementsByClassName('c-el-select-popper')[0] | |||
|         const arrowDom = selectInputDom.getElementsByClassName('popper__arrow')[0] | |||
|         this.$nextTick(function() { | |||
|           const left = parseInt(selectPoper.style.left) | |||
| 
 | |||
|           // 偏右 | |||
|           // arrowDom.style.left = '10px' | |||
|           // selectPoper.style.left = (left + width - 25) + 'px' | |||
| 
 | |||
|           // 偏左 | |||
|           arrowDom.style.left = (width + 20) + 'px' | |||
|           selectPoper.style.left = (left - width - 10) + 'px' | |||
|         }) | |||
|       } | |||
|     } | |||
|   } | |||
| } | |||
| </script> | |||
| 
 | |||
| <style lang="scss" scoped> | |||
| .component-container{ | |||
|     margin-bottom: 5px; | |||
| } | |||
| .exam-info-container { | |||
|   margin-bottom: 5px; | |||
| 
 | |||
|   .exam-title { | |||
|     float: left; | |||
|     margin-top: 5px; | |||
|     font-size: 16px; | |||
|     font-weight: 600; | |||
|   } | |||
|   .exam-date-time-list { | |||
|     float: right; | |||
|   } | |||
| } | |||
| </style> | |||
| @ -0,0 +1,129 @@ | |||
| <template> | |||
|   <el-dialog title="查看" :visible.sync="visible" append-to-body class="dialog-crf" top="4vh" width="280mm"> | |||
|     <hm-preview v-if="content" ref="ecrf" :value="content" class="hmPreview" /> | |||
| 
 | |||
|     <!-- 工具 --> | |||
|     <div class="tool-bar"> | |||
|       <el-button v-if="print" icon="el-icon-printer" circle title="打印" @click="btnPrintClick" /> | |||
|       <el-button v-if="edit" icon="el-icon-edit-outline" circle title="编辑" @click="btnEditClick" /> | |||
|       <el-button v-if="remove" icon="el-icon-delete" circle title="删除" @click="btnDeleteClick" /> | |||
|     </div> | |||
|   </el-dialog> | |||
| </template> | |||
| 
 | |||
| <script> | |||
| import hmPreview from '@/components/hm-crf/load-content' | |||
| const Base64 = require('js-base64').Base64 | |||
| 
 | |||
| export default { | |||
|   components: { hmPreview }, | |||
|   props: { | |||
|     height: { type: String, default: '100%' }, | |||
|     type: { type: String, default: 'load' }, | |||
|     print: { type: Boolean, default: false }, | |||
|     edit: { type: Boolean, default: false }, | |||
|     remove: { type: Boolean, default: false } | |||
|   }, | |||
|   data() { | |||
|     return { | |||
|       visible: false, | |||
|       id: '', | |||
|       content: '' | |||
|     } | |||
|   }, | |||
|   watch: { | |||
|     id(val) { console.log(val) } | |||
|   }, | |||
|   mounted() { }, | |||
|   methods: { | |||
|     init() { | |||
|       this.visible = true | |||
|       this.$nextTick(() => { | |||
|         this.content = '' | |||
|         this.getInfo() | |||
|       }) | |||
|     }, | |||
|     // 获取信息 | |||
|     getInfo() { | |||
|       if (this.type === 'load') { | |||
|         // 加载 | |||
|         this.$http.get('/crf/form', { params: { id: this.id }}).then(({ data: res }) => { | |||
|           if (res.data) { | |||
|             this.content = Base64.decode(res.data.content) | |||
|           } | |||
|         }) | |||
|       } else { | |||
|         // 预览模板 | |||
|         this.$http.get('/crf/template', { params: { crfId: this.id }}).then(({ data: res }) => { | |||
|           if (res.data) { | |||
|             this.content = Base64.decode(res.data.content) | |||
|           } | |||
|         }) | |||
|       } | |||
|     }, | |||
|     btnPrintClick() { | |||
|       this.$refs.ecrf.print() | |||
|     }, | |||
|     btnEditClick() { | |||
|       this.$emit('edit', this.id) | |||
|     }, | |||
|     btnDeleteClick() { | |||
|       this.$confirm(this.$t('prompt.info', { handle: this.$t('delete') }), this.$t('prompt.title'), { | |||
|         confirmButtonText: this.$t('confirm'), | |||
|         cancelButtonText: this.$t('cancel'), | |||
|         type: 'warning' | |||
|       }).then(() => { | |||
|         this.$http.delete('/crf/form/' + this.id).then(({ data: res }) => { | |||
|           this.$message.success('删除成功!') | |||
|           this.visible = false | |||
|           this.$emit('remove', this.id) | |||
|         }) | |||
|       }) | |||
|     } | |||
|   } | |||
| } | |||
| </script> | |||
| <style lang="scss" scoped> | |||
| .dialog-crf { | |||
|   ::v-deep .el-dialog { | |||
|     margin-bottom: 10px; | |||
| 
 | |||
|     .el-dialog__header { | |||
|       padding: 10px 20px; | |||
| 
 | |||
|       .el-dialog__headerbtn { | |||
|         top: 10px; | |||
|         font-size: 20px; | |||
| 
 | |||
|         .el-dialog__close { | |||
|           font-weight: bolder; | |||
|         } | |||
|       } | |||
|     } | |||
|     .el-dialog__body { | |||
|       padding: 10px 0; | |||
|       text-align: center; | |||
|       background: #606266; | |||
| 
 | |||
|       height: calc(96vh - 55px); | |||
| 
 | |||
|       .hmPreview { | |||
|         background: #fff; | |||
|         height: 100%; | |||
|       } | |||
|     } | |||
|   } | |||
| } | |||
| 
 | |||
| .tool-bar { | |||
|   position: absolute; | |||
|   width: 50px; | |||
|   bottom: 20px; | |||
|   right: 5px; | |||
| 
 | |||
|   .el-button + .el-button { | |||
|     margin-left: 0; | |||
|     margin-top: 10px; | |||
|   } | |||
| } | |||
| </style> | |||
| @ -0,0 +1,88 @@ | |||
| <template> | |||
|   <el-dialog title="选择表单" :visible.sync="visible" append-to-body> | |||
|     <el-table v-loading="dataListLoading" :data="dataList" row-key="id" border style="width: 100%;"> | |||
|       <!-- 名称 --> | |||
|       <el-table-column prop="name" :label="'名称'" /> | |||
|       <!-- 操作 --> | |||
|       <el-table-column prop="operation" :label="$t('handle')" fixed="right" width="150"> | |||
|         <template slot-scope="scope"> | |||
|           <el-button type="text" size="small" @click="preview(scope.row)">{{ '预览' }}</el-button> | |||
|           <el-button type="text" size="small" @click="followUp(scope.row)">{{ '填写' }}</el-button> | |||
|         </template> | |||
|       </el-table-column> | |||
|     </el-table> | |||
| 
 | |||
|     <template slot="footer"> | |||
|       <el-button @click="visible = false">{{ $t('close') }}</el-button> | |||
|     </template> | |||
| 
 | |||
|     <!-- 预览 --> | |||
|     <preview v-if="previewVisible" ref="preview" :type="'preview'" /> | |||
|     <!-- 填写 --> | |||
|     <follow-up v-if="followUpVisible" ref="followUp" v-on="$listeners" /> | |||
| 
 | |||
|   </el-dialog> | |||
| </template> | |||
| 
 | |||
| <script> | |||
| import preview from '@/components/ecrf/dialog-load' | |||
| import followUp from './follow-up.vue' | |||
| 
 | |||
| export default { | |||
|   components: { preview, followUp }, | |||
|   props: { | |||
|     patientIdNumber: { type: String, required: true } | |||
|   }, | |||
|   data() { | |||
|     return { | |||
|       visible: false, | |||
|       previewVisible: false, | |||
|       followUpVisible: false, | |||
|       dataListLoading: false, | |||
|       dataList: [] | |||
|     } | |||
|   }, | |||
|   mounted() { | |||
| 
 | |||
|   }, | |||
|   methods: { | |||
|     init() { | |||
|       this.visible = true | |||
|       this.dataListLoading = true | |||
|       this.$nextTick(() => { | |||
|         this.$http.get('/crf/page', { | |||
|           params: { | |||
|             projectId: window.SITE_CONFIG['projectId'], | |||
|             order: '', | |||
|             orderField: '', | |||
|             page: 1, | |||
|             limit: 1000 | |||
|           } | |||
|         }).then(({ data: res }) => { | |||
|           this.dataList = res.data.list | |||
|           this.dataListLoading = false | |||
|         }).catch(() => { this.dataListLoading = false }) | |||
|       }) | |||
|     }, | |||
|     preview(row) { | |||
|       this.previewVisible = true | |||
|       this.$nextTick(() => { | |||
|         this.$refs.preview.id = row.id | |||
|         this.$refs.preview.init() | |||
|       }) | |||
|     }, | |||
|     followUp(row) { | |||
|       this.followUpVisible = true | |||
|       this.$nextTick(() => { | |||
|         this.$refs.followUp.crfId = row.id | |||
|         this.$refs.followUp.patientIdNumber = this.patientIdNumber | |||
|         this.$refs.followUp.init() | |||
|       }) | |||
|     } | |||
|   } | |||
| } | |||
| </script> | |||
| 
 | |||
| <style> | |||
| 
 | |||
| </style> | |||
| @ -0,0 +1,177 @@ | |||
| <template> | |||
|   <el-dialog | |||
|     title="填写表单" | |||
|     top="1vh" | |||
|     width="calc(220mm + 600px)" | |||
|     :visible.sync="visible" | |||
|     append-to-body | |||
|   > | |||
|     <div class="dialog-container"> | |||
|       <!-- 表单内容 --> | |||
|       <div class="crf-container" style="width: 220mm;"> | |||
|         <hm-crf v-if="crfVisible" ref="hmCrf" :value="content" class="hmPreview" :js-arr="jsArr" /> | |||
|       </div> | |||
|       <!-- 填充数据 --> | |||
|       <div class="crf-data" style="width: calc(100% - 220mm);"> | |||
|         <template v-if="examData.length>0"> | |||
|           <div v-for="(item,index) in examData" :key="index"> | |||
|             <crf-data | |||
|               v-if="crfDataVisible&&item.exams.length>0" | |||
|               v-model="item.value" | |||
|               :exam-name="item.name" | |||
|               :list="item.exams" | |||
|             /> | |||
|           </div> | |||
|         </template> | |||
|         <template v-else> | |||
|           <el-empty description="没有可用的填充数据" /> | |||
|         </template> | |||
|       </div> | |||
|     </div> | |||
| 
 | |||
|     <template slot="footer"> | |||
|       <!-- <el-button @click="visible = false">{{ $t('cancel') }}</el-button> --> | |||
|       <el-button type="primary" @click="fillCrf">{{ '一键填充' }}</el-button> | |||
|       <el-button type="primary" @click="submit">{{ '保存' }}</el-button> | |||
|     </template> | |||
|   </el-dialog> | |||
| </template> | |||
| 
 | |||
| <script> | |||
| const Base64 = require('js-base64').Base64 | |||
| 
 | |||
| import hmCrf from '../hm-crf/load-content.vue' | |||
| import crfData from './crf-data.vue' | |||
| import { formatDate } from '@/utils/index.js' | |||
| 
 | |||
| export default { | |||
|   components: { hmCrf, crfData }, | |||
|   data() { | |||
|     return { | |||
|       visible: false, | |||
|       crfVisible: false, | |||
|       crfDataVisible: false, | |||
|       jsArr: [], | |||
|       inputDate: formatDate(new Date(), 'yyyy-MM-dd'), | |||
|       id: '', | |||
|       crfId: '', | |||
|       patientIdNumber: '', | |||
|       // CRF内容,填充用 | |||
|       content: '', | |||
|       // 获取的检查数据,【item.value】为v-model绑定值,即用于填充左侧iframe | |||
|       examData: [] | |||
|     } | |||
|   }, | |||
|   mounted() { }, | |||
|   methods: { | |||
|     init() { | |||
|       this.visible = true | |||
|       this.crfVisible = false | |||
|       this.crfDataVisible = false | |||
|       this.$nextTick(() => { | |||
|         // 加载 | |||
|         this.$http.get('/crf/form', { params: { id: this.id }}).then(({ data: res }) => { | |||
|           if (res.data) { | |||
|             this.content = Base64.decode(res.data.content) | |||
|             this.crfVisible = true | |||
|           } | |||
|         }) | |||
|         // 获取数据填充数据 | |||
|         this.$http.get('/crf/fillData', { | |||
|           params: { | |||
|             crfId: this.crfId, | |||
|             idNumber: this.patientIdNumber | |||
|           } | |||
|         }).then(({ data: res }) => { | |||
|           if (res.code !== 0) { | |||
|             return this.$message.error(res.msg) | |||
|           } | |||
|           if (res.data) { | |||
|             this.examData = res.data | |||
|             this.crfDataVisible = true | |||
|           } | |||
|         }).catch(() => { }) | |||
|       }) | |||
|     }, | |||
|     fillCrf() { | |||
|       // 过滤数据 | |||
|       const dataSelect = [] | |||
|       let fillItemList = [] | |||
|       this.examData.forEach(item => { | |||
|         if (item.value) { | |||
|           dataSelect.push(item.value) | |||
|           if (item.value.data) { | |||
|             const examItemList = item.value.data.map((obj, index, arr) => { | |||
|               obj.recId = item.value.recId | |||
|               obj.time = item.value.time | |||
|               return obj | |||
|             }) | |||
|             fillItemList = fillItemList.concat(examItemList) | |||
|           } | |||
|         } | |||
|       }) | |||
|       const ifr = this.$refs.hmCrf.$el | |||
|       const ifrWin = ifr.contentWindow | |||
|       ifrWin.dataFill(fillItemList) | |||
|     }, | |||
|     submit() { | |||
|       const ifr = this.$refs.hmCrf.$el | |||
|       const ifrDoc = ifr.contentWindow.document || ifr.contentDocument | |||
|       const body = ifrDoc.getElementsByTagName('body')[0] | |||
|       const crfContent = body.innerHTML | |||
| 
 | |||
|       this.$http.put('/crf/form', { | |||
|         formId: this.id, | |||
|         dataContent: Base64.encode(crfContent) | |||
|       }).then(({ data: res }) => { | |||
|         if (res.code !== 0) { | |||
|           return this.$message.error(res.msg) | |||
|         } | |||
|         this.$message({ | |||
|           message: this.$t('prompt.success'), | |||
|           type: 'success', | |||
|           duration: 500, | |||
|           onClose: () => { | |||
|             this.visible = false | |||
|             this.$emit('refreshData') | |||
|           } | |||
|         }) | |||
|       }) | |||
|     } | |||
|   } | |||
| } | |||
| </script> | |||
| 
 | |||
| <style lang="scss" scoped> | |||
| .dialog-container { | |||
|   height: calc(100vh - 1vh - 54px - 70px); | |||
| 
 | |||
|   // 表单 | |||
|   .crf-container { | |||
|     display: inline-block; | |||
|     vertical-align: top; | |||
|     height: 100%; | |||
|     // border: 1px solid; | |||
|     padding: 10px 0; | |||
|     text-align: center; | |||
|     background: #606266; | |||
| 
 | |||
|     .hmPreview { | |||
|       background: #fff; | |||
|       height: 100%; | |||
|     } | |||
|   } | |||
|   // 匹配数据 | |||
|   .crf-data { | |||
|     display: inline-block; | |||
|     vertical-align: top; | |||
|     height: 100%; | |||
|     overflow: auto; | |||
|     padding: 0 20px 0 20px; | |||
|   } | |||
| } | |||
| 
 | |||
| // .btn-fill { | |||
| //   margin-right: calc(100% - 960px - 160px); | |||
| // } | |||
| </style> | |||
| @ -0,0 +1,194 @@ | |||
| <template> | |||
|   <el-dialog | |||
|     title="填写表单" | |||
|     top="1vh" | |||
|     width="calc(220mm + 600px)" | |||
|     :visible.sync="visible" | |||
|     append-to-body | |||
|   > | |||
|     <div class="dialog-container"> | |||
|       <!-- 表单内容 --> | |||
|       <div class="crf-container" style="width: 220mm;"> | |||
|         <hm-crf v-if="crfVisible" ref="hmCrf" :value="content" class="hmPreview" :js-arr="jsArr" /> | |||
|       </div> | |||
|       <!-- 填充数据 --> | |||
|       <div class="crf-data" style="width: calc(100% - 220mm);"> | |||
|         <template v-if="examData.length>0"> | |||
|           <div v-for="(item,index) in examData" :key="index"> | |||
|             <crf-data | |||
|               v-if="crfDataVisible&&item.exams.length>0" | |||
|               v-model="item.value" | |||
|               :exam-name="item.name" | |||
|               :list="item.exams" | |||
|             /> | |||
|           </div> | |||
|         </template> | |||
|         <template v-else> | |||
|           <el-empty description="没有可用的填充数据" /> | |||
|         </template> | |||
|       </div> | |||
|     </div> | |||
| 
 | |||
|     <template slot="footer"> | |||
|       <el-button type="primary" @click="fillCrf">{{ '一键填充' }}</el-button> | |||
|       <!-- <el-button @click="visible = false">{{ $t('cancel') }}</el-button> --> | |||
|       <el-button type="primary" @click="submit">{{ '保存' }}</el-button> | |||
|     </template> | |||
|   </el-dialog> | |||
| </template> | |||
| 
 | |||
| <script> | |||
| const Base64 = require('js-base64').Base64 | |||
| 
 | |||
| import hmCrf from '../hm-crf/load-content.vue' | |||
| import crfData from './crf-data.vue' | |||
| import { formatDate } from '@/utils/index.js' | |||
| 
 | |||
| export default { | |||
|   components: { hmCrf, crfData }, | |||
|   data() { | |||
|     return { | |||
|       visible: false, | |||
|       crfVisible: false, | |||
|       crfDataVisible: false, | |||
|       jsArr: [], | |||
|       inputDate: formatDate(new Date(), 'yyyy-MM-dd'), | |||
|       crfId: '', | |||
|       patientIdNumber: '', | |||
|       // CRF内容,填充用 | |||
|       content: '', | |||
|       // 获取的检查数据,【item.value】为v-model绑定值,即用于填充左侧iframe | |||
|       examData: [] | |||
|     } | |||
|   }, | |||
|   mounted() { | |||
|   }, | |||
|   methods: { | |||
|     init() { | |||
|       this.visible = true | |||
|       this.crfVisible = false | |||
|       this.crfDataVisible = false | |||
|       this.$nextTick(() => { | |||
|         this.$http.get('/crf/template', { params: { crfId: this.crfId }}).then(({ data: res }) => { | |||
|           if (res.code !== 0) { | |||
|             return this.$message.error(res.msg) | |||
|           } | |||
|           if (res.data) { | |||
|             this.content = Base64.decode(res.data.content) | |||
|             this.crfVisible = true | |||
|           } | |||
|         }).catch(() => { }) | |||
| 
 | |||
|         this.$http.get('/crf/fillData', { | |||
|           params: { | |||
|             crfId: this.crfId, | |||
|             idNumber: this.patientIdNumber | |||
|           } | |||
|         }).then(({ data: res }) => { | |||
|           if (res.code !== 0) { | |||
|             return this.$message.error(res.msg) | |||
|           } | |||
|           if (res.data) { | |||
|             this.examData = res.data | |||
|             this.crfDataVisible = true | |||
|           } | |||
|         }).catch(() => { }) | |||
|       }) | |||
|     }, | |||
|     fillCrf() { | |||
|       // 过滤数据 | |||
|       const dataSelect = [] | |||
|       let fillItemList = [] | |||
|       this.examData.forEach(item => { | |||
|         if (item.value) { | |||
|           dataSelect.push(item.value) | |||
|           if (item.value.data) { | |||
|             const examItemList = item.value.data.map((obj, index, arr) => { | |||
|               obj.recId = item.value.recId | |||
|               obj.time = item.value.time | |||
|               return obj | |||
|             }) | |||
|             fillItemList = fillItemList.concat(examItemList) | |||
|           } | |||
|         } | |||
|       }) | |||
|       const ifr = this.$refs.hmCrf.$el | |||
|       const ifrWin = ifr.contentWindow | |||
|       ifrWin.dataFill(fillItemList) | |||
|     }, | |||
|     submit() { | |||
|       const ifr = this.$refs.hmCrf.$el | |||
|       const ifrDoc = ifr.contentWindow.document || ifr.contentDocument | |||
|       const body = ifrDoc.getElementsByTagName('body')[0] | |||
|       const crfContent = body.innerHTML | |||
|       this.$http.post('/crf/form', { | |||
|         crfId: this.crfId, | |||
|         dataContent: Base64.encode(crfContent), | |||
|         idNumber: this.patientIdNumber, | |||
|         inputDate: this.inputDate, | |||
|         projectId: window.SITE_CONFIG['projectId'] | |||
|       }).then(({ data: res }) => { | |||
|         if (res.code !== 0) { | |||
|           return this.$message.error(res.msg) | |||
|         } | |||
|         // this.updateVisitPlan() | |||
|         this.$message({ | |||
|           message: this.$t('prompt.success'), | |||
|           type: 'success', | |||
|           duration: 500, | |||
|           onClose: () => { | |||
|             this.visible = false | |||
|             this.$emit('refreshData') | |||
|           } | |||
|         }) | |||
|       }) | |||
|     } | |||
|     // 20211014 | |||
|     // 已弃用:随访更新触发条件改为检查项目 | |||
|     // updateVisitPlan() { | |||
|     //   this.$http.post('/visit/list/updateVisitPlan', { | |||
|     //     patientIdNumber: this.patientIdNumber, | |||
|     //     projectId: window.SITE_CONFIG['projectId'] | |||
|     //   }).then(({ data: res }) => { | |||
|     //     if (res.code !== 0) { | |||
|     //       return this.$message.error(res.msg) | |||
|     //     } | |||
|     //   }) | |||
|     // } | |||
|   } | |||
| } | |||
| </script> | |||
| 
 | |||
| <style lang="scss" scoped> | |||
| .dialog-container { | |||
|   height: calc(100vh - 1vh - 54px - 70px); | |||
| 
 | |||
|   // 表单 | |||
|   .crf-container { | |||
|     display: inline-block; | |||
|     vertical-align: top; | |||
|     height: 100%; | |||
|     // border: 1px solid; | |||
|     padding: 10px 0; | |||
|     text-align: center; | |||
|     background: #606266; | |||
| 
 | |||
|     .hmPreview { | |||
|       background: #fff; | |||
|       height: 100%; | |||
|     } | |||
|   } | |||
|   // 匹配数据 | |||
|   .crf-data { | |||
|     display: inline-block; | |||
|     vertical-align: top; | |||
|     height: 100%; | |||
|     overflow: auto; | |||
|     padding: 0 20px 0 20px; | |||
|   } | |||
| } | |||
| 
 | |||
| // .btn-fill { | |||
| //   margin-right: calc(100% - 960px - 160px); | |||
| // } | |||
| </style> | |||
| @ -0,0 +1,87 @@ | |||
| <template> | |||
|   <el-dialog | |||
|     title="查看" | |||
|     :visible.sync="visible" | |||
|     append-to-body | |||
|     class="dialog-crf" | |||
|     top="4vh" | |||
|     width="240mm" | |||
|   > | |||
|     <hm-preview v-if="content" :value="content" class="hmPreview" /> | |||
|   </el-dialog> | |||
| </template> | |||
| 
 | |||
| <script> | |||
| import hmPreview from './load-content' | |||
| const Base64 = require('js-base64').Base64 | |||
| 
 | |||
| export default { | |||
|   components: { hmPreview }, | |||
|   props: { | |||
|     id: { type: String, required: true }, | |||
|     height: { type: String, default: '100%' } | |||
|   }, | |||
|   data() { | |||
|     return { | |||
|       visible: false, | |||
|       content: '' | |||
|     } | |||
|   }, | |||
|   watch: { | |||
|     id(val) { | |||
|       console.log(val) | |||
|     } | |||
|   }, | |||
|   mounted() { }, | |||
|   methods: { | |||
|     init() { | |||
|       this.visible = true | |||
|       this.$nextTick(() => { | |||
|         this.content = '' | |||
|         this.getInfo() | |||
|       }) | |||
|     }, | |||
|     // 获取信息 | |||
|     getInfo() { | |||
|       this.$http.get('/crf/form', { params: { id: '1435810703477837825' }}).then(({ data: res }) => { | |||
|         if (res.data) { | |||
|           this.content = Base64.decode(res.data.content) | |||
|         } | |||
|       }) | |||
|     } | |||
|   } | |||
| } | |||
| </script> | |||
| <style lang="scss" scoped> | |||
| .dialog-crf { | |||
| 
 | |||
|   ::v-deep .el-dialog { | |||
|     margin-bottom: 10px; | |||
| 
 | |||
|     .el-dialog__header { | |||
|       padding: 10px 20px; | |||
| 
 | |||
|       .el-dialog__headerbtn { | |||
|         top: 10px; | |||
|         font-size: 20px; | |||
| 
 | |||
|         .el-dialog__close { | |||
|           font-weight: bolder; | |||
|         } | |||
|       } | |||
|     } | |||
|     .el-dialog__body { | |||
|       padding: 10px 0; | |||
|       text-align: center; | |||
|       background: #606266; | |||
| 
 | |||
|       height: calc(96vh - 55px); | |||
| 
 | |||
|       .hmPreview { | |||
|         background: #fff; | |||
|         height: 100%; | |||
|       } | |||
|     } | |||
|   } | |||
| } | |||
| </style> | |||
| @ -0,0 +1,49 @@ | |||
| <template> | |||
|   <hm-preview v-if="content" :value="content" /> | |||
| </template> | |||
| 
 | |||
| <script> | |||
| import hmPreview from './load-content' | |||
| const Base64 = require('js-base64').Base64 | |||
| 
 | |||
| export default { | |||
|   components: { hmPreview }, | |||
|   props: { | |||
|     id: { | |||
|       type: String, | |||
|       required: true | |||
|     }, | |||
|     height: { | |||
|       type: String, | |||
|       default: '100%' | |||
|     } | |||
|   }, | |||
|   data() { | |||
|     return { | |||
|       content: '' | |||
|     } | |||
|   }, | |||
|   watch: { | |||
|     id(val) { | |||
|       console.log(val) | |||
|     } | |||
|   }, | |||
|   mounted() { | |||
|     this.getInfo() | |||
|   }, | |||
|   methods: { | |||
|     init() { | |||
|       this.content = '' | |||
|       this.getInfo() | |||
|     }, | |||
|     // 获取信息 | |||
|     getInfo() { | |||
|       this.$http.get('/crf/form', { params: { id: this.id }}).then(({ data: res }) => { | |||
|         if (res.data) { | |||
|           this.content = Base64.decode(res.data.content) | |||
|         } | |||
|       }) | |||
|     } | |||
|   } | |||
| } | |||
| </script> | |||
| @ -0,0 +1,88 @@ | |||
| <template> | |||
|   <el-dialog | |||
|     title="查看" | |||
|     :visible.sync="visible" | |||
|     append-to-body | |||
|     class="dialog-crf" | |||
|     top="4vh" | |||
|     width="240mm" | |||
|   > | |||
|     <hm-preview v-if="content" :value="content" class="hmPreview" /> | |||
|   </el-dialog> | |||
| </template> | |||
| 
 | |||
| <script> | |||
| import hmPreview from './load-content' | |||
| const Base64 = require('js-base64').Base64 | |||
| 
 | |||
| export default { | |||
|   components: { hmPreview }, | |||
|   props: { | |||
|     // id: { type: String, required: true }, | |||
|     height: { type: String, default: '100%' } | |||
|   }, | |||
|   data() { | |||
|     return { | |||
|       visible: false, | |||
|       id: '', | |||
|       content: '' | |||
|     } | |||
|   }, | |||
|   watch: { | |||
|     id(val) { | |||
|       console.log(val) | |||
|     } | |||
|   }, | |||
|   mounted() { }, | |||
|   methods: { | |||
|     init() { | |||
|       this.visible = true | |||
|       this.$nextTick(() => { | |||
|         this.content = '' | |||
|         this.getInfo() | |||
|       }) | |||
|     }, | |||
|     // 获取信息 | |||
|     getInfo() { | |||
|       this.$http.get('/crf/template', { params: { crfId: this.id }}).then(({ data: res }) => { | |||
|         if (res.data) { | |||
|           this.content = Base64.decode(res.data.content) | |||
|         } | |||
|       }) | |||
|     } | |||
|   } | |||
| } | |||
| </script> | |||
| <style lang="scss" scoped> | |||
| .dialog-crf { | |||
| 
 | |||
|   ::v-deep .el-dialog { | |||
|     margin-bottom: 10px; | |||
| 
 | |||
|     .el-dialog__header { | |||
|       padding: 10px 20px; | |||
| 
 | |||
|       .el-dialog__headerbtn { | |||
|         top: 10px; | |||
|         font-size: 20px; | |||
| 
 | |||
|         .el-dialog__close { | |||
|           font-weight: bolder; | |||
|         } | |||
|       } | |||
|     } | |||
|     .el-dialog__body { | |||
|       padding: 10px 0; | |||
|       text-align: center; | |||
|       background: #606266; | |||
| 
 | |||
|       height: calc(96vh - 55px); | |||
| 
 | |||
|       .hmPreview { | |||
|         background: #fff; | |||
|         height: 100%; | |||
|       } | |||
|     } | |||
|   } | |||
| } | |||
| </style> | |||
| @ -0,0 +1,100 @@ | |||
| <template> | |||
|   <el-dialog | |||
|     width="90%" | |||
|     top="2vh" | |||
|     :visible.sync="visible" | |||
|     :title="'预览'" | |||
|     :close-on-click-modal="false" | |||
|     :close-on-press-escape="false" | |||
|     append-to-body | |||
|   > | |||
|     <iframe | |||
|       ref="ifrCRF" | |||
|       style="margin: 0;padding: 0;width: 100%;border: 1px solid #000;" | |||
|       :style="{ height: height }" | |||
|     /> | |||
|     <template slot="footer"> | |||
|       <el-button @click="visible = false">{{ $t('cancel') }}</el-button> | |||
|     </template> | |||
|   </el-dialog> | |||
| </template> | |||
| 
 | |||
| <script> | |||
| const Base64 = require('js-base64').Base64 | |||
| 
 | |||
| export default { | |||
|   data() { | |||
|     return { | |||
|       visible: false, | |||
|       height: 'calc(100vh - 200px)', | |||
|       dataForm: { | |||
|         id: '', | |||
|         projectId: '', | |||
|         name: '', | |||
|         description: '', | |||
|         content: '' | |||
|       } | |||
|     } | |||
|   }, | |||
|   methods: { | |||
|     init() { | |||
|       this.visible = true | |||
|       this.$nextTick(() => { | |||
|         this.dataForm.projectId = window.SITE_CONFIG['projectId'] | |||
|         this.getInfo() | |||
|       }) | |||
|     }, | |||
|     // 获取信息 | |||
|     getInfo() { | |||
|       this.$http.get('/crf/template', { params: { crfId: this.dataForm.id }}).then(({ data: res }) => { | |||
|         if (res.code !== 0) { | |||
|           return this.$message.error(res.msg) | |||
|         } | |||
|         if (res.data) { | |||
|           this.dataForm.content = Base64.decode(res.data.content) | |||
|           this.dataForm = { ...this.dataForm } | |||
|           this.render() | |||
|         } | |||
|       }).catch(() => {}) | |||
|     }, | |||
|     render() { | |||
|       const baseUrl = window.location.origin | |||
|       // const ifr = document.getElementById('crfPreview') | |||
|       const ifr = this.$refs.ifrCRF | |||
|       const doc = ifr.contentWindow.document || ifr.contentDocument | |||
|       const head = doc.getElementsByTagName('head')[0] | |||
|       const body = doc.getElementsByTagName('body')[0] | |||
| 
 | |||
|       const cssArr = ['skins-tinymce/ui/oxide/content.min.css', 'hmcrf.css'] | |||
|       const jsHeadArr = ['jquery-3.5.1/jquery.min.js', 'laydate/laydate.js'] | |||
| 
 | |||
|       cssArr.forEach(href => { | |||
|         const css = document.createElement('link') | |||
|         css.type = 'text/css' | |||
|         css.rel = 'stylesheet' | |||
|         css.href = baseUrl + '/static/css/' + href | |||
|         head.appendChild(css) | |||
|       }) | |||
| 
 | |||
|       jsHeadArr.forEach(src => { | |||
|         const script = document.createElement('script') | |||
|         script.type = 'text/javascript' | |||
|         script.src = baseUrl + '/static/js/' + src | |||
|         head.appendChild(script) | |||
|       }) | |||
| 
 | |||
|       body.innerHTML = this.dataForm.content | |||
| 
 | |||
|       setTimeout(() => { | |||
|         const jsBodyArr = ['hmcrf.js'] | |||
|         jsBodyArr.forEach(src => { | |||
|           const script = document.createElement('script') | |||
|           script.type = 'text/javascript' | |||
|           script.src = baseUrl + '/static/js/' + src | |||
|           body.appendChild(script) | |||
|         }) | |||
|       }, 500) | |||
|     } | |||
|   } | |||
| } | |||
| </script> | |||
| @ -0,0 +1,239 @@ | |||
| <template> | |||
|   <div id="tinymceContainer" class="tinymce-editor"> | |||
|     <editor id="myEditor" v-model="myValue" :init="init" :disabled="disabled" @onClick="onClick" /> | |||
|   </div> | |||
| </template> | |||
| 
 | |||
| <script> | |||
| // import Cookies from 'js-cookie' | |||
| import tinymce from 'tinymce' | |||
| import Editor from '@tinymce/tinymce-vue' | |||
| // import 'tinymce/skins/content/default/content.min.css' | |||
| import 'tinymce/icons/default/icons' | |||
| import 'tinymce/plugins/image' | |||
| import 'tinymce/plugins/media' | |||
| import 'tinymce/plugins/table' | |||
| import 'tinymce/plugins/lists' | |||
| import 'tinymce/plugins/contextmenu' | |||
| import 'tinymce/plugins/colorpicker' | |||
| import 'tinymce/plugins/textcolor' | |||
| import 'tinymce/plugins/code' | |||
| import 'tinymce/plugins/print' | |||
| import 'tinymce/plugins/quickbars' | |||
| import 'tinymce/plugins/hr' | |||
| import 'tinymce/plugins/pagebreak' | |||
| 
 | |||
| /** | |||
|  * 自定义部分 | |||
|  */ | |||
| import './tinymce/themes/silver' | |||
| import './tinymce/icons' | |||
| import './tinymce/plugins/letterspacing' | |||
| import './tinymce/plugins/hm_preview' | |||
| import './tinymce/plugins/hm_input' | |||
| import './tinymce/plugins/hm_checkbox' | |||
| import './tinymce/plugins/hm_radio' | |||
| 
 | |||
| import { isInclude } from './tinymce/plugins/hm_utils' | |||
| 
 | |||
| const tinyID = 'myEditor' | |||
| 
 | |||
| export default { | |||
|   components: { | |||
|     Editor | |||
|   }, | |||
|   props: { | |||
|     value: { | |||
|       type: String, | |||
|       default: '' | |||
|     }, | |||
|     height: { | |||
|       type: String, | |||
|       default: '500px' | |||
|     }, | |||
|     disabled: { | |||
|       type: Boolean, | |||
|       default: false | |||
|     }, | |||
|     plugins: { | |||
|       type: [String, Array], | |||
|       default: 'hminput hmcheckbox hmradio quickbars print hmpreview lists image media table code letterspacing hr pagebreak'// paste contextmenu colorpicker textcolor | |||
|     }, | |||
|     toolbar: { | |||
|       type: [String, Array], | |||
|       default: | |||
|         `hminput hmcheckbox hmradio |  | |||
|         image table | | |||
|         formatselect | fontselect fontsizeselect  | hr pagebreak | | |||
|         bold italic forecolor backcolor |  | |||
|         hmpreview print |  | |||
|         alignleft aligncenter alignright alignjustify |  | |||
|         bullist numlist outdent indent | letterspacing lineheight` | |||
|         // media removeformat | |||
|         // code | | |||
|     }, | |||
|     contextmenu: { | |||
|       type: [String, Array], | |||
|       default: 'hminput hmcheckbox hmradio image imagetools table spellchecker lists' | |||
|     } | |||
|   }, | |||
|   data() { | |||
|     return { | |||
|       init: { | |||
|         selector: '#' + tinyID, | |||
|         icons: 'custom', | |||
|         language_url: '/static/tinymce/langs/zh_CN.js', | |||
|         language: 'zh_CN', | |||
|         skin_url: '/static/tinymce/skins/ui/oxide', // oxide-dark',//暗色系 | |||
|         theme: 'silver', // 主题:负责编辑器的框架构建、如编辑器上下左右,垂直水平、内外部等行为 | |||
|         height: this.height, // '100vh', | |||
|         statusbar: false, // 底栏 | |||
|         // -------------------------------【菜单栏】------------------------------- | |||
|         menubar: false, | |||
|         // -------------------------------【右键菜单栏】------------------------------- | |||
|         contextmenu_never_use_native: true, | |||
|         contextmenu: this.contextmenu, | |||
|         // -------------------------------【插件】------------------------------- | |||
|         plugins: this.plugins, | |||
|         // -------------------------------【工具栏】------------------------------- | |||
|         toolbar_mode: 'wrap', // 工具栏模式: 默认 floating/sliding/scrolling/wrap | |||
|         toolbar: this.toolbar, // 工具栏 | |||
|         // -------------------------------【快速工具栏】------------------------------- | |||
|         quickbars_selection_toolbar: false, | |||
|         // quickbars_selection_toolbar: 'bold italic underline strikethrough | code fontsizeselect ', | |||
|         paste_data_images: true, | |||
|         // images_upload_url: "/demo/eUpload.php", | |||
|         images_upload_base_path: '', // "/demo/" | |||
|         images_upload_handler: function(blobInfo, succFun, failFun) { | |||
|         // 自定义插入图片函数 | |||
|         // blobInfo: 本地图片blob对象 | |||
|         // succFun(url|string): 成功回调(插入图片链接到文本中) | |||
|         // failFun(string):失败回调 | |||
|           var file = blobInfo.blob() | |||
|           var reader = new FileReader() | |||
|           reader.onload = function(e) { | |||
|             succFun(e.target.result) | |||
|           } | |||
|           reader.readAsDataURL(file) | |||
|         }, | |||
|         content_css: '/static/css/hmcrf.css', | |||
|         setup: (editor) => { | |||
|           // editor.hmBaseCss = ['/static/css/hmcrf.css']; | |||
|           editor.hmBaseScripts = [ | |||
|             '/static/js/jquery-3.5.1/jquery.min.js', | |||
|             '/static/js/hmcrf.js' | |||
|           ] | |||
|         }, | |||
|         init_instance_callback: (editor) => { | |||
|         }, | |||
|         init: () => { | |||
|         }, | |||
|         font_formats: '微软雅黑=Microsoft YaHei,Helvetica Neue,PingFang SC,sans-serif;苹果苹方=PingFang SC,Microsoft YaHei,sans-serif;宋体=simsun,serif;仿宋体=FangSong,serif;黑体=SimHei,sans-serif;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;' | |||
| 
 | |||
|       }, | |||
|       myValue: this.value | |||
|     } | |||
|   }, | |||
|   watch: { | |||
|     value(newValue) { | |||
|       this.myValue = newValue | |||
|     }, | |||
|     myValue(newValue) { | |||
|       this.$emit('input', newValue) | |||
|     } | |||
|   }, | |||
|   mounted() { | |||
|     // Cookies.set('token', '9def6f4db676363e9f01990d56e62929') | |||
|     // 检索字典表 | |||
|     this.$http.get('/table/dict/optionsColumn', { params: { type: 3 }}).then(({ data: res }) => { | |||
|       const data = res.data | |||
|       window.sessionStorage.setItem('dictField', JSON.stringify(data)) | |||
|     }) | |||
|     // this.$http.get(`/table/dict/getTableDictTreeForCRF`).then(({ data: res }) => { | |||
|     //   if (res.code === 0) { | |||
|     //     const data = res.data | |||
|     //     window.sessionStorage.setItem('dictField', JSON.stringify(data)) | |||
|     //   } | |||
|     // }) | |||
| 
 | |||
|     this.$nextTick(() => { | |||
|     }) | |||
|   }, | |||
|   methods: { | |||
|     // 添加相关的事件,可用的事件参照文档=> https://github.com/tinymce/tinymce-vue => All available events | |||
|     onClick(e) { | |||
|       this.$emit('onClick', e, tinymce) | |||
|     }, | |||
|     clear() { | |||
|       this.myValue = '' | |||
|     }, | |||
|     setReadOnly() { | |||
|       tinymce.editors[tinyID].setMode('readonly') | |||
|     }, | |||
|     setDesign() { | |||
|       tinymce.editors[tinyID].setMode('design') | |||
|     }, | |||
|     exportHtml() { | |||
|       this.fileDown(tinymce.editors[tinyID].getDoc().documentElement.outerHTML, '文件.html') | |||
|     }, | |||
|     fileDown(content, filename) { | |||
|       const eleLink = document.createElement('a') | |||
|       eleLink.download = filename | |||
|       eleLink.style.display = 'none' | |||
|       const blob = new Blob([content]) | |||
|       eleLink.href = URL.createObjectURL(blob) | |||
|       document.body.appendChild(eleLink) | |||
|       eleLink.click() | |||
|       document.body.removeChild(eleLink) | |||
|     }, | |||
|     // 渲染内容 | |||
|     renderContent() { | |||
|       const baseUrl = window.location.origin | |||
|       const ifr = document.getElementsByClassName('tox-edit-area__iframe')[0] | |||
|       const doc = ifr.contentWindow.document | |||
|       const head = doc.getElementsByTagName('head')[0] | |||
|       const jsHeadArr = ['jquery-3.5.1/jquery.min.js'] | |||
|       jsHeadArr.forEach(src => { | |||
|         if (!isInclude(src, doc)) { | |||
|           const script = document.createElement('script') | |||
|           script.type = 'text/javascript' | |||
|           script.src = baseUrl + '/static/js/' + src | |||
|           head.appendChild(script) | |||
|         } | |||
|       }) | |||
| 
 | |||
|       // 由于append方式追加js,无法确定jQuery是否加载完成,故设置定时 | |||
|       setTimeout(() => { | |||
|         const jsHeadArr2 = ['hmcrf.js'] | |||
|         jsHeadArr2.forEach(src => { | |||
|           if (!isInclude(src, doc)) { | |||
|             const script = document.createElement('script') | |||
|             script.type = 'text/javascript' | |||
|             script.src = baseUrl + '/static/js/' + src | |||
|             head.appendChild(script) | |||
|           } | |||
|         }) | |||
|       }, 1000) | |||
|     } | |||
|   } | |||
| } | |||
| </script> | |||
| 
 | |||
| <style> | |||
| /*没有申请key的话会出现一个弹窗要去申请key,在这里把那个弹窗隐藏,当然也可以自己申请key再使用 */ | |||
| .tox-notifications-container { | |||
|   display: none; | |||
| } | |||
| /* 在页面正常使用时不用加这个样式,在弹窗使用时,要加这个样式,因为使用弹窗,z-index层数比较低,工具栏的一些工具不能使用,要将z-index层数提高。 */ | |||
| .tox-tinymce-aux { | |||
|   z-index: 5000 !important; | |||
| } | |||
| button { | |||
|   margin: 0px 5px 5px 0px; | |||
| } | |||
| 
 | |||
| /* 弹窗微调 */ | |||
| .tox-dialog-wrap .tox-dialog .tox-dialog__header { | |||
|   padding: 0 16px; | |||
| } | |||
| </style> | |||
| @ -0,0 +1,76 @@ | |||
| <template> | |||
|   <iframe | |||
|     ref="ifrCRF" | |||
|     style="margin: 0;padding:0px;width: 210mm;" | |||
|     :style="{ height: height,border:border }" | |||
|     scrolling="auto" | |||
|     frameborder="0" | |||
|   /> | |||
| </template> | |||
| 
 | |||
| <script> | |||
| export default { | |||
|   name: 'IfrCRF', | |||
|   props: { | |||
|     value: { type: String, required: true }, | |||
|     height: { type: String, default: '100%' }, | |||
|     border: { type: String, default: 'none' }, | |||
|     jsArr: { type: Array, default: () => [] } | |||
|   }, | |||
|   data() { | |||
|     return { | |||
|       // content: '' | |||
|     } | |||
|   }, | |||
|   mounted() { | |||
|     this.init() | |||
|   }, | |||
|   methods: { | |||
|     init() { | |||
|       const baseUrl = window.location.origin | |||
|       // const ifr = document.getElementById('ifrCRF')  =>  this.$refs.ifrCRF | |||
|       const ifr = this.$refs.ifrCRF | |||
|       const doc = ifr.contentWindow.document || ifr.contentDocument | |||
|       const head = doc.getElementsByTagName('head')[0] | |||
|       const body = doc.getElementsByTagName('body')[0] | |||
| 
 | |||
|       const cssArr = ['skins-tinymce/ui/oxide/content.min.css', 'hmcrf.css'] | |||
|       const jsHeadArr = ['jquery-3.5.1/jquery.min.js', 'laydate/laydate.js'] | |||
| 
 | |||
|       cssArr.forEach(href => { | |||
|         const css = document.createElement('link') | |||
|         css.type = 'text/css' | |||
|         css.rel = 'stylesheet' | |||
|         css.href = baseUrl + '/static/css/' + href | |||
|         head.appendChild(css) | |||
|       }) | |||
| 
 | |||
|       jsHeadArr.forEach(src => { | |||
|         const script = document.createElement('script') | |||
|         script.type = 'text/javascript' | |||
|         script.src = baseUrl + '/static/js/' + src | |||
|         head.appendChild(script) | |||
|       }) | |||
| 
 | |||
|       body.innerHTML = this.value | |||
| 
 | |||
|       setTimeout(() => { | |||
|         const jsArr = ['hmcrf.js', ...this.jsArr] | |||
|         jsArr.forEach(src => { | |||
|           const script = document.createElement('script') | |||
|           script.type = 'text/javascript' | |||
|           script.src = baseUrl + '/static/js/' + src | |||
|           head.appendChild(script) | |||
|         }) | |||
|       }, 500) | |||
|     }, | |||
|     print() { | |||
|       const ifr = this.$refs.ifrCRF | |||
|       ifr.contentWindow.print() | |||
|     } | |||
|   } | |||
| } | |||
| </script> | |||
| <style lang="scss" scoped> | |||
| 
 | |||
| </style> | |||
| @ -0,0 +1,10 @@ | |||
| // eslint-disable-next-line no-undef
 | |||
| tinymce.IconManager.add('custom', { | |||
|   icons: { | |||
|     'input-date': '<svg t="1623053598045" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="839" width="32" height="32"><path d="M950.4 182.4H73.6C32 182.4 0 214.4 0 256v512c0 41.6 32 73.6 73.6 73.6h876.8c41.6 0 73.6-32 73.6-73.6V256c0-41.6-32-73.6-73.6-73.6z m0 550.4c0 22.4-16 35.2-35.2 35.2H108.8c-22.4 0-35.2-16-35.2-35.2V291.2c0-19.2 12.8-35.2 35.2-35.2h803.2c22.4 0 35.2 16 35.2 35.2v441.6h3.2z" p-id="840"></path><path d="M771.2 320h44.8v70.4h-44.8zM588.8 320h44.8v70.4h-44.8z" p-id="841"></path><path d="M860.8 364.8h-22.4v44.8h-89.6v-44.8h-89.6v44.8h-89.6v-44.8H544c-12.8 0-22.4 9.6-22.4 22.4v294.4c0 12.8 9.6 22.4 22.4 22.4h316.8c12.8 0 22.4-9.6 22.4-22.4v-294.4c0-12.8-9.6-22.4-22.4-22.4z m-230.4 249.6h-44.8v-44.8h44.8v44.8z m0-89.6h-44.8V480h44.8v44.8z m92.8 89.6h-44.8v-44.8h44.8v44.8z m0-89.6h-44.8V480h44.8v44.8z m89.6 89.6H768v-44.8h44.8v44.8z m0-89.6H768V480h44.8v44.8zM230.4 352h-64c-19.2 0-32 12.8-32 32v256c0 16 12.8 32 32 32h64c19.2 0 32-12.8 32-32v-256c0-16-12.8-32-32-32z" p-id="842"></path></svg>', | |||
|     'input': '<svg t="1623053714556" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5638" width="32" height="32"><path d="M73.142857 731.428571h877.714286V292.571429H73.142857v438.857142z m0-512h877.714286c43.885714 0 73.142857 29.257143 73.142857 73.142858v438.857142c0 43.885714-29.257143 73.142857-73.142857 73.142858H73.142857c-43.885714 0-73.142857-29.257143-73.142857-73.142858V292.571429c0-43.885714 29.257143-73.142857 73.142857-73.142858z m131.657143 146.285715h73.142857v292.571428h-73.142857V365.714286z" p-id="5639"></path></svg>', | |||
|     'radio': '<svg t="1623292373056" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5458" width="16" height="16"><path d="M512 256c-143.36 0-256 112.64-256 256S368.64 768 512 768 768 655.36 768 512 655.36 256 512 256zM512 0C230.4 0 0 230.4 0 512s230.4 512 512 512 512-230.4 512-512S793.6 0 512 0z m0 921.6c-225.28 0-409.6-184.32-409.6-409.6S286.72 102.4 512 102.4s409.6 184.32 409.6 409.6-184.32 409.6-409.6 409.6z" p-id="5459"></path></svg>', | |||
|     'checkbox': '<svg t="1623292420789" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5717" width="16" height="16"><path d="M278.755556 403.911111l-79.644445 79.644445L455.111111 739.555556l568.888889-568.888889-79.644444-79.644445L455.111111 580.266667l-176.355555-176.355556zM910.222222 910.222222H113.777778V113.777778h568.888889V0H113.777778C51.2 0 0 51.2 0 113.777778v796.444444c0 62.577778 51.2 113.777778 113.777778 113.777778h796.444444c62.577778 0 113.777778-51.2 113.777778-113.777778V455.111111h-113.777778v455.111111z" p-id="5718"></path></svg>', | |||
|     'textarea': '<svg t="1623773458085" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4996" width="40" height="24"><path d="M29.866667 85.333333v853.333334h968.533333V85.333333H29.866667z m883.2 597.333334L768 827.733333H110.933333V196.266667h802.133334V682.666667z" p-id="4997"></path><path d="M196.266667 337.066667c8.533333-29.866667 8.533333-29.866667 42.666666-29.866667V469.333333h-38.4v46.933334h136.533334V469.333333H298.666667V307.2h12.8c21.333333 0 25.6 0 29.866666 29.866667v17.066666l42.666667-8.533333v-25.6c0-17.066667-4.266667-38.4 0-51.2v-21.333333h-38.4L341.333333 256H196.266667l-4.266667-8.533333h-38.4v21.333333c0 17.066667 0 38.4-4.266667 59.733333v21.333334h42.666667l4.266667-12.8z m473.6 409.6l179.2-179.2 29.866666 29.866666-179.2 179.2-29.866666-29.866666z" p-id="4998"></path></svg>' | |||
|   } | |||
| }) | |||
| @ -0,0 +1,7 @@ | |||
| // Exports the "default" icons for usage with module loaders
 | |||
| // Usage:
 | |||
| //   CommonJS:
 | |||
| //     require('tinymce/icons/default')
 | |||
| //   ES2015:
 | |||
| //     import 'tinymce/icons/default'
 | |||
| require('./icons.js') | |||
| @ -0,0 +1,7 @@ | |||
| // Exports the "anchor" plugin for usage with module loaders
 | |||
| // Usage:
 | |||
| //   CommonJS:
 | |||
| //     require('tinymce/plugins/anchor')
 | |||
| //   ES2015:
 | |||
| //     import 'tinymce/plugins/anchor'
 | |||
| require('./plugin.js') | |||
| @ -0,0 +1,234 @@ | |||
| import { | |||
|   loadJS_ifrEditArea, | |||
|   loadCSS_ifrEditArea, | |||
|   isPlugin, | |||
|   // updateElm,
 | |||
|   updateAttrib, | |||
|   getIdByClassName, | |||
|   __assign, | |||
|   isElm | |||
|   // dataFormToElmPartStr,
 | |||
|   // elmToDataForm,
 | |||
|   // hasElm
 | |||
| } | |||
|   from '../hm_utils/index' | |||
| 
 | |||
| (function() { | |||
|   'use strict' | |||
| 
 | |||
|   const pluginOptions = { | |||
|     jsArr: [], | |||
|     cssArr: [], | |||
|     name: 'hmcheckbox', | |||
|     className: 'hmcheckbox', // 判断依据,建议和name值一致
 | |||
|     cmdName: 'cmdhmcheckbox', | |||
|     editName: 'hmcheckbox_edit', | |||
|     dataForm: { | |||
|       'data-hm_id': '', | |||
|       'data-hm_type': 'checkbox', | |||
|       'label': '', | |||
|       'value': '' | |||
|     } | |||
|   } | |||
| 
 | |||
|   const global = tinymce.util.Tools.resolve('tinymce.PluginManager') | |||
| 
 | |||
|   // 初始设置
 | |||
|   const setup = function(editor) { | |||
|     // 编辑器初始化后执行
 | |||
|     editor.on('init', function() { | |||
|       loadJS_ifrEditArea(editor, pluginOptions.jsArr) | |||
|       loadCSS_ifrEditArea(editor, pluginOptions.cssArr) | |||
|     }) | |||
|     // 右键菜单,选定目标
 | |||
|     editor.on('contextmenu', function(evt) { | |||
|       const elm = evt.target | |||
|       editor.selection.select(elm) | |||
|     }, true) | |||
|   } | |||
| 
 | |||
|   const open = function(editor) { | |||
|     editor.windowManager.open({ | |||
|       title: '新增', | |||
|       size: 'normal', // 'normal', 'medium' or 'large'
 | |||
|       body: { | |||
|         type: 'panel', | |||
|         items: [ | |||
|           { | |||
|             type: 'input', | |||
|             name: 'data-hm_id', | |||
|             label: '组号', | |||
|             placeholder: '分组编号' | |||
|           }, | |||
|           { | |||
|             type: 'input', | |||
|             name: 'label', | |||
|             label: '选项名' | |||
|           }, | |||
|           { | |||
|             type: 'input', | |||
|             name: 'value', | |||
|             label: '选项值' | |||
|           } | |||
|         ] | |||
| 
 | |||
|       }, | |||
|       initialData: elmToDataForm(editor, pluginOptions.dataForm, pluginOptions.className), | |||
|       buttons: [ | |||
|         { | |||
|           type: 'cancel', | |||
|           name: 'cancel', | |||
|           text: '取消' | |||
|         }, | |||
|         { | |||
|           type: 'submit', | |||
|           name: 'save', | |||
|           text: '确定', | |||
|           primary: true | |||
|         } | |||
|       ], | |||
|       onSubmit: function(api) { | |||
|         const dataForm = api.getData() | |||
|         dataForm['data-hm_type'] = pluginOptions.dataForm['data-hm_type'] | |||
|         const hmType = dataForm['data-hm_type'] | |||
|         const className = pluginOptions.className | |||
|         const elm = editor.selection.getNode() | |||
| 
 | |||
|         let elm_input, elm_label | |||
|         if (elm.className.indexOf(className + '-label') >= 0) { | |||
|           elm_input = isElm(elm.previousElementSibling, 'data-hm_type', hmType) ? elm.previousElementSibling : undefined | |||
|           elm_label = elm | |||
|         } else if (elm.className.indexOf(className) >= 0 && isElm(elm, 'data-hm_type', hmType)) { | |||
|           elm_input = elm | |||
|           elm_label = isElm(elm.nextElementSibling, 'data-hm_type', hmType) ? elm.previousElementSibling : undefined | |||
|         } | |||
| 
 | |||
|         if (elm && isPlugin(elm, className)) { | |||
|           // 更新
 | |||
|           updateElm(editor, elm_input, elm_label, dataForm, changeHandler) | |||
|           api.close() | |||
|         } else { | |||
|           // 插入
 | |||
|           insertElm(editor, dataForm) | |||
|           api.close() | |||
|         } | |||
|       } | |||
|     }) | |||
|   } | |||
| 
 | |||
|   const elmToDataForm = function(editor, initDataForm, pluginClassName) { | |||
|     const elm = editor.selection.getNode() | |||
|     const dataForm = __assign({}, initDataForm) | |||
|     const hmType = initDataForm['data-hm_type'] | |||
|     if (isPlugin(elm, pluginClassName)) { | |||
|       let elm_input, elm_label | |||
|       if (elm.className.indexOf(pluginClassName + '-label') >= 0) { | |||
|         elm_input = isElm(elm.previousElementSibling, 'data-hm_type', hmType) ? elm.previousElementSibling : undefined | |||
|         elm_label = elm | |||
|       } else if (elm.className.indexOf(pluginClassName) >= 0 && isElm(elm, 'data-hm_type', hmType)) { | |||
|         elm_input = elm | |||
|         elm_label = isElm(elm.nextElementSibling, 'data-hm_type', hmType) ? elm.previousElementSibling : undefined | |||
|       } | |||
|       dataForm['data-hm_id'] = elm_input.getAttribute('data-hm_id') | |||
|       dataForm['label'] = elm_label.innerText | |||
|       dataForm['value'] = elm_input.getAttribute('value') | |||
|     } | |||
|     return dataForm | |||
|   } | |||
| 
 | |||
|   const insertElm = function(editor, dataForm) { | |||
|     const doc = editor.contentDocument || editor.contentWindow.document | |||
|     const className = pluginOptions.className | |||
|     const id = getIdByClassName(doc, className) | |||
|     const name = dataForm['data-hm_id'] | |||
|     const hmType = dataForm['data-hm_type'] | |||
|     const label = dataForm['label'] | |||
|     const value = dataForm['value'] || label | |||
|     const win = editor.contentWindow | |||
| 
 | |||
|     const domStr_input = `<input type="checkbox" id="${id}" class="${className}" name="${name}" value="${value}" data-hm_id="${name}" data-hm_type="${hmType}">` | |||
|     const domStr_label = `<label class="${className}-label" for="${id}">${label}</label></input>` | |||
|     editor.insertContent(domStr_input + domStr_label) | |||
|     // 渲染控件
 | |||
|     renderElm(doc, win, id, dataForm['data-hm_type']) | |||
|   } | |||
| 
 | |||
|   const updateElm = function(editor, elm_input, elm_label, dataForm, changeHandler) { | |||
|     const name = dataForm['data-hm_id'] | |||
|     const label = dataForm['label'] | |||
|     const value = dataForm['value'] || label | |||
|     if (elm_input) { | |||
|       updateAttrib(elm_input, 'name', name) | |||
|       updateAttrib(elm_input, 'value', value) | |||
|       updateAttrib(elm_input, 'data-hm_id', name) | |||
|     } | |||
|     if (elm_label) { | |||
|       elm_label.innerText = label | |||
|     } | |||
|   } | |||
| 
 | |||
|   // 编辑控件状态后,触发处理逻辑
 | |||
|   const changeHandler = function(editor, elm, dataForm) { | |||
|     const doc = editor.contentDocument || editor.contentWindow.document | |||
|     const win = editor.contentWindow | |||
|     const id = editor.dom.getAttrib(elm, 'id') | |||
| 
 | |||
|     renderElm(doc, win, id, dataForm['data-hm_type']) | |||
|   } | |||
| 
 | |||
|   const renderElm = function(doc, win, id, type) { | |||
|   } | |||
| 
 | |||
|   const register = function(editor) { | |||
|     editor.addCommand(pluginOptions.cmdName, function() { | |||
|       open(editor) | |||
|     }) | |||
|   } | |||
| 
 | |||
|   const register$1 = function(editor) { | |||
|     // 工具栏
 | |||
|     editor.ui.registry.addButton(pluginOptions.name, { | |||
|       icon: 'checkbox', | |||
|       title: '复选框', | |||
|       tooltip: '复选框', | |||
|       onAction: function() { | |||
|         open(editor) | |||
|       }, | |||
|       onSetup: function(buttonApi) { | |||
|       } | |||
|     }) | |||
|     // 菜单栏
 | |||
|     editor.ui.registry.addMenuItem(pluginOptions.name, { | |||
|       icon: 'checkbox', | |||
|       text: '复选框', | |||
|       onAction: function() { | |||
|         open(editor) | |||
|       } | |||
|     }) | |||
| 
 | |||
|     // 菜单栏(编辑)
 | |||
|     editor.ui.registry.addMenuItem(pluginOptions.editName, { | |||
|       icon: 'checkbox', | |||
|       text: '编辑', | |||
|       onAction: function() { | |||
|         open(editor) | |||
|       } | |||
|     }) | |||
| 
 | |||
|     editor.ui.registry.addContextMenu(pluginOptions.name, { | |||
|       update: function(elm) { | |||
|         return isPlugin(elm, pluginOptions.className) ? [pluginOptions.editName] : [] | |||
|       } | |||
|     }) | |||
|   } | |||
| 
 | |||
|   function Plugin() { | |||
|     global.add(pluginOptions.name, function(editor) { | |||
|       setup(editor) | |||
|       register(editor) | |||
|       register$1(editor) | |||
|     }) | |||
|   } | |||
| 
 | |||
|   Plugin() | |||
| }()) | |||
| @ -0,0 +1,7 @@ | |||
| // Exports the "anchor" plugin for usage with module loaders
 | |||
| // Usage:
 | |||
| //   CommonJS:
 | |||
| //     require('tinymce/plugins/anchor')
 | |||
| //   ES2015:
 | |||
| //     import 'tinymce/plugins/anchor'
 | |||
| require('./plugin.js') | |||
| @ -0,0 +1,366 @@ | |||
| /* eslint-disable no-useless-escape */ | |||
| /* eslint-disable no-undef */ | |||
| /* eslint-disable no-unused-vars */ | |||
| import { | |||
|   loadJS_ifrEditArea, | |||
|   loadCSS_ifrEditArea, | |||
|   isPlugin, | |||
|   updateElm, | |||
|   dataFormToElmPartStr, | |||
|   elmToDataForm, | |||
|   getIdByClassName, | |||
|   getListbox_Field, | |||
|   hasElm, | |||
|   __assign | |||
| } | |||
|   from '../hm_utils/index' | |||
| 
 | |||
| (function() { | |||
|   'use strict' | |||
| 
 | |||
|   const pluginOptions = { | |||
|     jsArr: ['/static/js/laydate/laydate.js'], | |||
|     cssArr: [], // '/static/css/hmcrf.css'
 | |||
|     name: 'hminput', | |||
|     className: 'hminput', // 判断依据,建议和name值一致
 | |||
|     cmdName: 'cmdhminput', | |||
|     editName: 'hminput_edit', | |||
|     dataForm: { | |||
|       'data-hm_id': '', | |||
|       'data-hm_type': '', | |||
|       'data-hm_required': 'false', | |||
|       'data-hm_bd_eye_type': '', | |||
|       'data-hm_bd_id': '', | |||
|       'placeholder': '', | |||
|       'title': '', | |||
|       'class.border': '', | |||
|       'style.width': '120', | |||
|       'style.height': '18', | |||
|       'style.text-align': 'center', | |||
|       'style.background-color': '' | |||
|     } | |||
|   } | |||
| 
 | |||
|   const global = tinymce.util.Tools.resolve('tinymce.PluginManager') | |||
| 
 | |||
|   // 初始设置
 | |||
|   const setup = function(editor) { | |||
|     // 编辑器初始化后执行
 | |||
|     editor.on('init', function() { | |||
|       loadJS_ifrEditArea(editor, pluginOptions.jsArr) | |||
|       loadCSS_ifrEditArea(editor, pluginOptions.cssArr) | |||
|     }) | |||
|     // 右键菜单,选定目标
 | |||
|     editor.on('contextmenu', function(evt) { | |||
|       console.log(evt) | |||
|       const target = evt.target | |||
|       editor.selection.select(target) | |||
|     }, true) | |||
|   } | |||
|   const dialogBody = function() { | |||
|     return { | |||
|       type: 'panel', | |||
|       items: [ | |||
|         { | |||
|           type: 'grid', | |||
|           columns: 2, | |||
|           items: [ | |||
|             { | |||
|               type: 'input', | |||
|               name: 'data-hm_id', | |||
|               label: '编号 (ID)', | |||
|               // other: 't1',
 | |||
|               placeholder: '唯一编号' | |||
|             }, | |||
|             { | |||
|               type: 'selectbox', | |||
|               name: 'data-hm_type', | |||
|               label: '类型', | |||
|               size: 1, | |||
|               disabled: false, | |||
|               items: [ | |||
|                 { value: 'text', text: '文本' }, | |||
|                 { value: 'textarea', text: '文本域', hmto: 'textarea' }, | |||
|                 { value: 'number', text: '数字' }, | |||
|                 { value: 'date', text: '日期' }, | |||
|                 { value: 'datetime', text: '日期时间' }, | |||
|                 { value: 'time', text: '时间' } | |||
|               ] | |||
|             }, | |||
|             // --------
 | |||
|             { | |||
|               type: 'input', | |||
|               name: 'style.width', | |||
|               label: '宽度 (px或%)' | |||
|             }, | |||
|             { | |||
|               type: 'input', | |||
|               name: 'style.height', | |||
|               label: '高度 (px或%)' | |||
|             }, | |||
|             // --------
 | |||
|             { | |||
|               type: 'selectbox', | |||
|               name: 'style.text-align', | |||
|               label: '对齐方式', | |||
|               size: 1, | |||
|               items: [ | |||
|                 { value: 'left', text: '居左' }, | |||
|                 { value: 'center', text: '居中' }, | |||
|                 { value: 'right', text: '居右' } | |||
|               ] | |||
|             }, | |||
|             { | |||
|               type: 'selectbox', | |||
|               name: 'class.border', | |||
|               label: '边框', | |||
|               size: 1, | |||
|               items: [ | |||
|               // 必须是class.X的【X-】形式命名选项值
 | |||
|                 { value: 'border-1', text: '下划线' }, | |||
|                 { value: 'border-2', text: '可见' }, | |||
|                 { value: 'border-3', text: '不可见' } | |||
|               ] | |||
|             }, | |||
|             // --------
 | |||
|             { | |||
|               type: 'colorinput', | |||
|               name: 'style.background-color', | |||
|               label: '背景色' | |||
|             }, | |||
|             { | |||
|               type: 'selectbox', | |||
|               name: 'data-hm_required', | |||
|               label: '必填', | |||
|               size: 1, | |||
|               items: [ | |||
|                 { value: 'false', text: '否' }, | |||
|                 { value: 'true', text: '是' } | |||
|               ] | |||
|             }, | |||
|             // --------
 | |||
|             { | |||
|               type: 'listbox', | |||
|               name: 'data-hm_bd_id', | |||
|               label: '绑定字段', | |||
|               items: getListbox_Field() | |||
|             }, | |||
|             { | |||
|               type: 'selectbox', | |||
|               name: 'data-hm_bd_eye_type', | |||
|               label: '绑定眼别', | |||
|               size: 1, | |||
|               items: [ | |||
|                 { value: '', text: '----无----' }, | |||
|                 { value: 'os', text: '左眼(OS)' }, | |||
|                 { value: 'od', text: '右眼(OD)' } | |||
|               ] | |||
|             }, | |||
|             // --------
 | |||
|             { | |||
|               type: 'input', | |||
|               name: 'placeholder', | |||
|               label: '背景文字' | |||
|             }, | |||
|             { | |||
|               type: 'input', | |||
|               name: 'title', | |||
|               label: '提示' | |||
|             } | |||
|           ] | |||
|         } | |||
|       ] | |||
|     } | |||
|   } | |||
|   const open = function(editor) { | |||
|     editor.windowManager.open({ | |||
|       title: '新增', | |||
|       size: 'medium', // 'normal', 'medium' or 'large'
 | |||
|       // height:500,
 | |||
|       body: dialogBody(), | |||
|       initialData: elmToDataForm(editor, pluginOptions.dataForm, pluginOptions.className, init), | |||
|       buttons: [ | |||
|         { | |||
|           type: 'cancel', | |||
|           name: 'cancel', | |||
|           text: '取消' | |||
|         }, | |||
|         { | |||
|           type: 'submit', | |||
|           name: 'save', | |||
|           text: '确定', | |||
|           primary: true | |||
|         } | |||
| 
 | |||
|       ], | |||
|       onChange: function(api, details) { | |||
|         // const dataForm = api.getData()
 | |||
|         // console.log(details, dataForm[details.name])
 | |||
|       }, | |||
|       onSubmit: function(api) { | |||
|         const dataForm = api.getData() | |||
|         const doc = editor.contentDocument || editor.contentWindow.document | |||
|         const className = pluginOptions.className | |||
|         const hmType = dataForm['data-hm_type'] | |||
| 
 | |||
|         const elm = editor.selection.getNode() | |||
|         if (dataForm['data-hm_id'].length === 0) { | |||
|           tinymce.activeEditor.windowManager.alert('请填写编号') | |||
|         } else { | |||
|           if (elm && isPlugin(elm, className)) { | |||
|             const elmHmType = editor.dom.getAttrib(elm, 'data-hm_type') | |||
|             if (elmHmType !== hmType) { | |||
|               // 先插后删
 | |||
|               insertElm(editor, dataForm) | |||
|               elm.remove() | |||
|             } else { | |||
|             // 更新
 | |||
|               updateElm(editor, elm, className, dataForm, changeHandler) | |||
|             } | |||
| 
 | |||
|             api.close() | |||
|           } else { | |||
|           // 判读是否存在相同编号ID的控件
 | |||
|             if (hasElm(doc, 'data-hm_id', dataForm['data-hm_id'])) { | |||
|               tinymce.activeEditor.windowManager.confirm('已存在,确定使用该ID吗?', function(s) { | |||
|               // tinymce.activeEditor.windowManager.alert("Ok");
 | |||
|                 if (s) { | |||
|                 // 插入
 | |||
|                   insertElm(editor, dataForm) | |||
|                   api.close() | |||
|                 } else { | |||
|                   return | |||
|                 } | |||
|               }) | |||
|             } else { | |||
|             // 插入
 | |||
|               insertElm(editor, dataForm) | |||
|               api.close() | |||
|             } | |||
|           } | |||
|         } | |||
|       } | |||
|     }) | |||
|   } | |||
|   const init = function(editor, dataForm) { | |||
|     // const elm = editor.selection.getNode()
 | |||
|     // const hmType = editor.dom.getAttrib(elm, 'data-hm_type')
 | |||
|     // if (hmType === 'number' || hmType === 'textarea') {
 | |||
|     //   dataForm['data-hm_type']
 | |||
|     // }
 | |||
| 
 | |||
|     // const tempDataForm = JSON.parse(window.sessionStorage.getItem('crfInputOptions'))
 | |||
|     // if (tempDataForm) {
 | |||
|     //   dataForm = __assign({}, dataForm, tempDataForm)
 | |||
|     //   return dataForm
 | |||
|     // }
 | |||
|   } | |||
| 
 | |||
|   const insertElm = function(editor, dataForm) { | |||
|     const doc = editor.contentDocument || editor.contentWindow.document | |||
|     const className = pluginOptions.className | |||
|     const id = getIdByClassName(doc, className) | |||
|     const name = dataForm['data-hm_id'] | |||
|     const win = editor.contentWindow | |||
| 
 | |||
|     let domStr = '' | |||
|     switch (dataForm['data-hm_type']) { | |||
|       case 'number': | |||
|         domStr = `<input type="number" name="${name}" id="${id}" ${dataFormToElmPartStr(dataForm, className)} 
 | |||
|         autocomplete="off" | |||
|         onkeypress="return(/[\d]/.test(String.fromCharCode(event.keyCode) ) )"  | |||
|         onkeyup="this.value=this.value.replace(/[^\d]/g,'');"/>` | |||
|         break | |||
|       case 'textarea': | |||
|         domStr = `<textarea name="${name}" id="${id}" autocomplete="off" ${dataFormToElmPartStr(dataForm, className)} ></textarea>` | |||
|         break | |||
|       default: | |||
|         domStr = `<input type="text" name="${name}" id="${id}" autocomplete="off" ${dataFormToElmPartStr(dataForm, className)}/>` | |||
|         break | |||
|     } | |||
|     // console.log(domStr)
 | |||
| 
 | |||
|     editor.insertContent(domStr) | |||
| 
 | |||
|     //  const ifr = document.getElementsByClassName('tox-edit-area__iframe')[0]
 | |||
|     // 【ifr.contentDocument = ifr.contentWindow.document】
 | |||
|     // 【editor.contentDocument = editor.contentWindow.document】
 | |||
| 
 | |||
|     // 渲染控件
 | |||
|     initElm(doc, win, id, dataForm['data-hm_type']) | |||
| 
 | |||
|     // // 记录此次配置,方便下次新增
 | |||
|     // window.sessionStorage.setItem('crfInputOptions', JSON.stringify(dataForm))
 | |||
|   } | |||
| 
 | |||
|   // 编辑控件状态后,触发处理逻辑
 | |||
|   const changeHandler = function(editor, elm, dataForm) { | |||
|     const doc = editor.contentDocument || editor.contentWindow.document | |||
|     const win = editor.contentWindow | |||
|     const id = editor.dom.getAttrib(elm, 'id') | |||
|     // 二次渲染重置处理,【失败】,暂时保留BUG // elm.removeAttribute('lay-key');
 | |||
|     initElm(doc, win, id, dataForm['data-hm_type']) | |||
|   } | |||
| 
 | |||
|   const initElm = function(doc, win, id, type) { | |||
|     if (type === 'date' || type === 'datetime' || type === 'time') { | |||
|       win.laydate.render({ | |||
|         elem: '#' + id, | |||
|         type: type | |||
|       }) | |||
|     } | |||
|   } | |||
| 
 | |||
|   const register = function(editor) { | |||
|     editor.addCommand(pluginOptions.cmdName, function() { | |||
|       open(editor) | |||
|     }) | |||
|   } | |||
| 
 | |||
|   const register$1 = function(editor) { | |||
|     // 工具栏
 | |||
|     editor.ui.registry.addButton(pluginOptions.name, { | |||
|       icon: 'input', | |||
|       title: '输入框', | |||
|       tooltip: '输入框', | |||
|       onAction: function() { | |||
|         open(editor) | |||
|       }, | |||
|       onSetup: function(buttonApi) { | |||
|       } | |||
|     }) | |||
|     // 菜单栏
 | |||
|     editor.ui.registry.addMenuItem(pluginOptions.name, { | |||
|       icon: 'duplicate-row', | |||
|       text: '属性', | |||
|       onAction: function() { | |||
|         open(editor) | |||
|       } | |||
|     }) | |||
| 
 | |||
|     // 菜单栏(编辑)
 | |||
|     editor.ui.registry.addMenuItem(pluginOptions.editName, { | |||
|       icon: 'duplicate-row', | |||
|       text: '编辑', | |||
|       onAction: function() { | |||
|         open(editor) | |||
|       } | |||
|     }) | |||
| 
 | |||
|     editor.ui.registry.addContextMenu(pluginOptions.name, { | |||
|       update: function(element) { | |||
|         return isPlugin(element, pluginOptions.className) ? [pluginOptions.editName] : [] | |||
|       } | |||
|     }) | |||
|   } | |||
| 
 | |||
|   function Plugin() { | |||
|     global.add(pluginOptions.name, function(editor) { | |||
|       setup(editor) | |||
|       register(editor) | |||
|       register$1(editor) | |||
|     }) | |||
|   } | |||
| 
 | |||
|   Plugin() | |||
| }()) | |||
| @ -0,0 +1,7 @@ | |||
| // Exports the "preview" plugin for usage with module loaders
 | |||
| // Usage:
 | |||
| //   CommonJS:
 | |||
| //     require('tinymce/plugins/preview')
 | |||
| //   ES2015:
 | |||
| //     import 'tinymce/plugins/preview'
 | |||
| require('./plugin.js') | |||
| @ -0,0 +1,143 @@ | |||
| /* eslint-disable no-undef */ | |||
| /** | |||
|  * Copyright (c) Tiny Technologies, Inc. All rights reserved. | |||
|  * Licensed under the LGPL or a commercial license. | |||
|  * For LGPL see License.txt in the project root for license information. | |||
|  * For commercial licenses see https://www.tiny.cloud/
 | |||
|  * | |||
|  * Version: 5.7.0 (2021-02-10) | |||
|  */ | |||
| 
 | |||
| (function() { | |||
|   'use strict' | |||
| 
 | |||
|   var global = tinymce.util.Tools.resolve('tinymce.PluginManager') | |||
| 
 | |||
|   var global$1 = tinymce.util.Tools.resolve('tinymce.Env') | |||
| 
 | |||
|   var global$2 = tinymce.util.Tools.resolve('tinymce.util.Tools') | |||
| 
 | |||
|   var getContentStyle = function(editor) { | |||
|     return editor.getParam('content_style', '', 'string') | |||
|   } | |||
|   var shouldUseContentCssCors = function(editor) { | |||
|     return editor.getParam('content_css_cors', false, 'boolean') | |||
|   } | |||
|   var getBodyClassByHash = function(editor) { | |||
|     var bodyClass = editor.getParam('body_class', '', 'hash') | |||
|     return bodyClass[editor.id] || '' | |||
|   } | |||
|   var getBodyClass = function(editor) { | |||
|     var bodyClass = editor.getParam('body_class', '', 'string') | |||
|     if (bodyClass.indexOf('=') === -1) { | |||
|       return bodyClass | |||
|     } else { | |||
|       return getBodyClassByHash(editor) | |||
|     } | |||
|   } | |||
|   var getBodyIdByHash = function(editor) { | |||
|     var bodyId = editor.getParam('body_id', '', 'hash') | |||
|     return bodyId[editor.id] || bodyId | |||
|   } | |||
|   var getBodyId = function(editor) { | |||
|     var bodyId = editor.getParam('body_id', 'tinymce', 'string') | |||
|     if (bodyId.indexOf('=') === -1) { | |||
|       return bodyId | |||
|     } else { | |||
|       return getBodyIdByHash(editor) | |||
|     } | |||
|   } | |||
| 
 | |||
|   var getPreviewHtml = function(editor) { | |||
|     console.log(editor) | |||
|     var headHtml = '' | |||
|     var encode = editor.dom.encode | |||
|     var contentStyle = getContentStyle(editor) | |||
|     headHtml += '<base href="' + encode(editor.documentBaseURI.getURI()) + '">' | |||
|     var cors = shouldUseContentCssCors(editor) ? ' crossorigin="anonymous"' : '' | |||
|     global$2.each(editor.contentCSS, function(url) { | |||
|       headHtml += '<link type="text/css" rel="stylesheet" href="' + encode(editor.documentBaseURI.toAbsolute(url)) + '"' + cors + '>' | |||
|     }) | |||
|     if (contentStyle) { | |||
|       headHtml += '<style type="text/css">' + contentStyle + '</style>' | |||
|     } | |||
| 
 | |||
|     // ----------------------------------
 | |||
|     global$2.each(editor.hmPluginCss, function(url) { | |||
|       headHtml += `<link type="text/css" rel="stylesheet" href="${encode(editor.documentBaseURI.toAbsolute(url))}" ${cors}/>` | |||
|     }) | |||
| 
 | |||
|     global$2.each(editor.hmBaseScripts, function(src) { | |||
|       headHtml += `<script src="${encode(editor.documentBaseURI.toAbsolute(src))}" ${cors}></script>` | |||
|     }) | |||
| 
 | |||
|     global$2.each(editor.hmPluginScript, function(src) { | |||
|       headHtml += `<script src="${encode(editor.documentBaseURI.toAbsolute(src))}" ${cors}></script>` | |||
|     }) | |||
| 
 | |||
|     var bodyId = getBodyId(editor) | |||
|     var bodyClass = getBodyClass(editor) | |||
|     var isMetaKeyPressed = global$1.mac ? 'e.metaKey' : 'e.ctrlKey && !e.altKey' | |||
|     var preventClicksOnLinksScript = '<script>' + 'document.addEventListener && document.addEventListener("click", function(e) {' + 'for (var elm = e.target; elm; elm = elm.parentNode) {' + 'if (elm.nodeName === "A" && !(' + isMetaKeyPressed + ')) {' + 'e.preventDefault();' + '}' + '}' + '}, false);' + '</script> ' | |||
|     var directionality = editor.getBody().dir | |||
|     var dirAttr = directionality ? ' dir="' + encode(directionality) + '"' : '' | |||
|     var previewHtml = '<!DOCTYPE html>' + '<html>' + '<head>' + headHtml + '</head>' + '<body id="' + encode(bodyId) + '" class="mce-content-body ' + encode(bodyClass) + '"' + dirAttr + '>' + editor.getContent() + preventClicksOnLinksScript + '</body>' + '</html>' | |||
|     return previewHtml | |||
|   } | |||
| 
 | |||
|   var open = function(editor) { | |||
|     var content = getPreviewHtml(editor) | |||
|     var dataApi = editor.windowManager.open({ | |||
|       title: 'Preview', | |||
|       size: 'large', | |||
|       body: { | |||
|         type: 'panel', | |||
|         items: [{ | |||
|           name: 'preview', | |||
|           type: 'iframe', | |||
|           sandboxed: true | |||
|         }] | |||
|       }, | |||
|       buttons: [{ | |||
|         type: 'cancel', | |||
|         name: 'close', | |||
|         text: 'Close', | |||
|         primary: true | |||
|       }], | |||
|       initialData: { preview: content } | |||
|     }) | |||
|     dataApi.focus('close') | |||
|   } | |||
| 
 | |||
|   var register = function(editor) { | |||
|     editor.addCommand('cmdhmpreview', function() { | |||
|       open(editor) | |||
|     }) | |||
|   } | |||
| 
 | |||
|   var register$1 = function(editor) { | |||
|     editor.ui.registry.addButton('hmpreview', { | |||
|       icon: 'preview', | |||
|       tooltip: 'Preview', | |||
|       onAction: function() { | |||
|         return editor.execCommand('cmdhmpreview') | |||
|       } | |||
|     }) | |||
|     editor.ui.registry.addMenuItem('hmpreview', { | |||
|       icon: 'preview', | |||
|       text: 'Preview', | |||
|       onAction: function() { | |||
|         return editor.execCommand('cmdhmpreview') | |||
|       } | |||
|     }) | |||
|   } | |||
| 
 | |||
|   function Plugin() { | |||
|     global.add('hmpreview', function(editor) { | |||
|       register(editor) | |||
|       register$1(editor) | |||
|     }) | |||
|   } | |||
| 
 | |||
|   Plugin() | |||
| }()) | |||
| @ -0,0 +1,7 @@ | |||
| // Exports the "anchor" plugin for usage with module loaders
 | |||
| // Usage:
 | |||
| //   CommonJS:
 | |||
| //     require('tinymce/plugins/anchor')
 | |||
| //   ES2015:
 | |||
| //     import 'tinymce/plugins/anchor'
 | |||
| require('./plugin.js') | |||
| @ -0,0 +1,235 @@ | |||
| 
 | |||
| import { | |||
|   loadJS_ifrEditArea, | |||
|   loadCSS_ifrEditArea, | |||
|   isPlugin, | |||
|   // updateElm,
 | |||
|   updateAttrib, | |||
|   getIdByClassName, | |||
|   __assign, | |||
|   isElm | |||
|   // dataFormToElmPartStr,
 | |||
|   // elmToDataForm,
 | |||
|   // hasElm
 | |||
| } | |||
|   from '../hm_utils/index' | |||
| 
 | |||
| (function() { | |||
|   'use strict' | |||
| 
 | |||
|   const pluginOptions = { | |||
|     jsArr: [], | |||
|     cssArr: [], | |||
|     name: 'hmradio', | |||
|     className: 'hmradio', // 判断依据,建议和name值一致
 | |||
|     cmdName: 'cmdhmradio', | |||
|     editName: 'hmradio_edit', | |||
|     dataForm: { | |||
|       'data-hm_id': '', | |||
|       'data-hm_type': 'radio', | |||
|       'label': '', | |||
|       'value': '' | |||
|     } | |||
|   } | |||
| 
 | |||
|   const global = tinymce.util.Tools.resolve('tinymce.PluginManager') | |||
| 
 | |||
|   // 初始设置
 | |||
|   const setup = function(editor) { | |||
|     // 编辑器初始化后执行
 | |||
|     editor.on('init', function() { | |||
|       loadJS_ifrEditArea(editor, pluginOptions.jsArr) | |||
|       loadCSS_ifrEditArea(editor, pluginOptions.cssArr) | |||
|     }) | |||
|     // 右键菜单,选定目标
 | |||
|     editor.on('contextmenu', function(evt) { | |||
|       const elm = evt.target | |||
|       editor.selection.select(elm) | |||
|     }, true) | |||
|   } | |||
| 
 | |||
|   const open = function(editor) { | |||
|     editor.windowManager.open({ | |||
|       title: '新增', | |||
|       size: 'normal', // 'normal', 'medium' or 'large'
 | |||
|       body: { | |||
|         type: 'panel', | |||
|         items: [ | |||
|           { | |||
|             type: 'input', | |||
|             name: 'data-hm_id', | |||
|             label: '组号', | |||
|             placeholder: '分组编号' | |||
|           }, | |||
|           { | |||
|             type: 'input', | |||
|             name: 'label', | |||
|             label: '选项名' | |||
|           }, | |||
|           { | |||
|             type: 'input', | |||
|             name: 'value', | |||
|             label: '选项值' | |||
|           } | |||
|         ] | |||
| 
 | |||
|       }, | |||
|       initialData: elmToDataForm(editor, pluginOptions.dataForm, pluginOptions.className), | |||
|       buttons: [ | |||
|         { | |||
|           type: 'cancel', | |||
|           name: 'cancel', | |||
|           text: '取消' | |||
|         }, | |||
|         { | |||
|           type: 'submit', | |||
|           name: 'save', | |||
|           text: '确定', | |||
|           primary: true | |||
|         } | |||
|       ], | |||
|       onSubmit: function(api) { | |||
|         const dataForm = api.getData() | |||
|         dataForm['data-hm_type'] = pluginOptions.dataForm['data-hm_type'] | |||
|         const hmType = dataForm['data-hm_type'] | |||
|         const className = pluginOptions.className | |||
|         const elm = editor.selection.getNode() | |||
| 
 | |||
|         let elm_input, elm_label | |||
|         if (elm.className.indexOf(className + '-label') >= 0) { | |||
|           elm_input = isElm(elm.previousElementSibling, 'data-hm_type', hmType) ? elm.previousElementSibling : undefined | |||
|           elm_label = elm | |||
|         } else if (elm.className.indexOf(className) >= 0 && isElm(elm, 'data-hm_type', hmType)) { | |||
|           elm_input = elm | |||
|           elm_label = isElm(elm.nextElementSibling, 'data-hm_type', hmType) ? elm.previousElementSibling : undefined | |||
|         } | |||
| 
 | |||
|         if (elm && isPlugin(elm, className)) { | |||
|           // 更新
 | |||
|           updateElm(editor, elm_input, elm_label, dataForm, changeHandler) | |||
|           api.close() | |||
|         } else { | |||
|           // 插入
 | |||
|           insertElm(editor, dataForm) | |||
|           api.close() | |||
|         } | |||
|       } | |||
|     }) | |||
|   } | |||
| 
 | |||
|   const elmToDataForm = function(editor, initDataForm, pluginClassName) { | |||
|     const elm = editor.selection.getNode() | |||
|     const dataForm = __assign({}, initDataForm) | |||
|     const hmType = initDataForm['data-hm_type'] | |||
|     if (isPlugin(elm, pluginClassName)) { | |||
|       let elm_input, elm_label | |||
|       if (elm.className.indexOf(pluginClassName + '-label') >= 0) { | |||
|         elm_input = isElm(elm.previousElementSibling, 'data-hm_type', hmType) ? elm.previousElementSibling : undefined | |||
|         elm_label = elm | |||
|       } else if (elm.className.indexOf(pluginClassName) >= 0 && isElm(elm, 'data-hm_type', hmType)) { | |||
|         elm_input = elm | |||
|         elm_label = isElm(elm.nextElementSibling, 'data-hm_type', hmType) ? elm.previousElementSibling : undefined | |||
|       } | |||
|       dataForm['data-hm_id'] = elm_input.getAttribute('data-hm_id') | |||
|       dataForm['label'] = elm_label.innerText | |||
|       dataForm['value'] = elm_input.getAttribute('value') | |||
|     } | |||
|     return dataForm | |||
|   } | |||
| 
 | |||
|   const insertElm = function(editor, dataForm) { | |||
|     const doc = editor.contentDocument || editor.contentWindow.document | |||
|     const className = pluginOptions.className | |||
|     const id = getIdByClassName(doc, className) | |||
|     const name = dataForm['data-hm_id'] | |||
|     const hmType = dataForm['data-hm_type'] | |||
|     const label = dataForm['label'] | |||
|     const value = dataForm['value'] || label | |||
|     const win = editor.contentWindow | |||
| 
 | |||
|     const domStr_input = `<input type="radio" id="${id}" class="${className}" name="${name}" value="${value}" data-hm_id="${name}" data-hm_type="${hmType}">` | |||
|     const domStr_label = `<label class="${className}-label" for="${id}">${label}</label></input>` | |||
|     editor.insertContent(domStr_input + domStr_label) | |||
|     // 渲染控件
 | |||
|     renderElm(doc, win, id, dataForm['data-hm_type']) | |||
|   } | |||
| 
 | |||
|   const updateElm = function(editor, elm_input, elm_label, dataForm, changeHandler) { | |||
|     const name = dataForm['data-hm_id'] | |||
|     const label = dataForm['label'] | |||
|     const value = dataForm['value'] || label | |||
|     if (elm_input) { | |||
|       updateAttrib(elm_input, 'name', name) | |||
|       updateAttrib(elm_input, 'value', value) | |||
|       updateAttrib(elm_input, 'data-hm_id', name) | |||
|     } | |||
|     if (elm_label) { | |||
|       elm_label.innerText = label | |||
|     } | |||
|   } | |||
| 
 | |||
|   // 编辑控件状态后,触发处理逻辑
 | |||
|   const changeHandler = function(editor, elm, dataForm) { | |||
|     const doc = editor.contentDocument || editor.contentWindow.document | |||
|     const win = editor.contentWindow | |||
|     const id = editor.dom.getAttrib(elm, 'id') | |||
| 
 | |||
|     renderElm(doc, win, id, dataForm['data-hm_type']) | |||
|   } | |||
| 
 | |||
|   const renderElm = function(doc, win, id, type) { | |||
|   } | |||
| 
 | |||
|   const register = function(editor) { | |||
|     editor.addCommand(pluginOptions.cmdName, function() { | |||
|       open(editor) | |||
|     }) | |||
|   } | |||
| 
 | |||
|   const register$1 = function(editor) { | |||
|     // 工具栏
 | |||
|     editor.ui.registry.addButton(pluginOptions.name, { | |||
|       icon: 'radio', | |||
|       title: '复选框', | |||
|       tooltip: '复选框', | |||
|       onAction: function() { | |||
|         open(editor) | |||
|       }, | |||
|       onSetup: function(buttonApi) { | |||
|       } | |||
|     }) | |||
|     // 菜单栏
 | |||
|     editor.ui.registry.addMenuItem(pluginOptions.name, { | |||
|       icon: 'radio', | |||
|       text: '复选框', | |||
|       onAction: function() { | |||
|         open(editor) | |||
|       } | |||
|     }) | |||
| 
 | |||
|     // 菜单栏(编辑)
 | |||
|     editor.ui.registry.addMenuItem(pluginOptions.editName, { | |||
|       icon: 'radio', | |||
|       text: '编辑', | |||
|       onAction: function() { | |||
|         open(editor) | |||
|       } | |||
|     }) | |||
| 
 | |||
|     editor.ui.registry.addContextMenu(pluginOptions.name, { | |||
|       update: function(elm) { | |||
|         return isPlugin(elm, pluginOptions.className) ? [pluginOptions.editName] : [] | |||
|       } | |||
|     }) | |||
|   } | |||
| 
 | |||
|   function Plugin() { | |||
|     global.add(pluginOptions.name, function(editor) { | |||
|       setup(editor) | |||
|       register(editor) | |||
|       register$1(editor) | |||
|     }) | |||
|   } | |||
| 
 | |||
|   Plugin() | |||
| }()) | |||
| @ -0,0 +1,304 @@ | |||
| 
 | |||
| // 判断是否已引用
 | |||
| export const isInclude = function(name, doc) { | |||
|   doc = doc || document | |||
|   var js = /js$/i.test(name) | |||
|   var es = doc.getElementsByTagName(js ? 'script' : 'link') | |||
|   for (var i = 0; i < es.length; i++) { if (es[i][js ? 'src' : 'href'].indexOf(name) !== -1) return true } | |||
|   return false | |||
| } | |||
| 
 | |||
| // 加载插件所需js
 | |||
| export const loadJS_ifrEditArea = function(editor, jsArr) { | |||
|   if (jsArr.length > 0) { | |||
|     const nodeList = document.getElementsByClassName('tox-edit-area__iframe') | |||
|     nodeList.forEach(node => { | |||
|       const ifr = node.contentWindow.document | |||
|       const head = ifr.getElementsByTagName('head')[0] | |||
|       jsArr.forEach(src => { | |||
|         if (!isInclude(src, ifr)) { | |||
|           const script = document.createElement('script') | |||
|           script.type = 'text/javascript' | |||
|           script.src = editor.dom.encode(editor.documentBaseURI.toAbsolute(src)) | |||
|           head.appendChild(script) | |||
|         } | |||
|       }) | |||
|     }) | |||
|     editor.hmPluginScript = (editor.hmPluginScript || []).concat(jsArr) | |||
|   } | |||
| } | |||
| 
 | |||
| // 加载插件所需css
 | |||
| export const loadCSS_ifrEditArea = function(editor, cssArr) { | |||
|   if (cssArr.length > 0) { | |||
|     const nodeList = document.getElementsByClassName('tox-edit-area__iframe') | |||
|     nodeList.forEach(node => { | |||
|       const ifr = node.contentWindow.document | |||
|       const head = ifr.getElementsByTagName('head')[0] | |||
|       cssArr.forEach(href => { | |||
|         if (!isInclude(href, ifr)) { | |||
|           const css = document.createElement('link') | |||
|           css.type = 'text/css' | |||
|           css.rel = 'stylesheet' | |||
|           css.href = editor.dom.encode(editor.documentBaseURI.toAbsolute(href)) | |||
|           head.appendChild(css) | |||
|         } | |||
|       }) | |||
|     }) | |||
|     editor.hmPluginCss = (editor.hmPluginCss || []).concat(cssArr) | |||
|   } | |||
| } | |||
| 
 | |||
| /** | |||
|  * 生成dom对象id(取最大值+1) | |||
|  * @param {*} doc document对象 | |||
|  * @param {*} className 样式名(插件名) | |||
|  * @returns | |||
|  */ | |||
| export const getIdByClassName = function(doc, className) { | |||
|   let i = 0 | |||
|   doc.querySelectorAll('.' + className).forEach(elm => { | |||
|     const j = Number(elm.id && elm.id.replace(className, '') || 0) | |||
|     if (i <= j) { | |||
|       i = j | |||
|     } | |||
|   }) | |||
|   return className + (i + 1) | |||
| } | |||
| 
 | |||
| /** | |||
|  * 判断是否已存在相应的dom对象 | |||
|  * @param {*} doc document对象 | |||
|  * @param {*} attrName 属性名 | |||
|  * @param {*} attrValue 属性值 | |||
|  * @returns | |||
|  */ | |||
| export const hasElm = function(doc, attrName, attrValue) { | |||
|   return attrValue !== '' && (doc.querySelectorAll(`[${attrName}='${attrValue}']`).length > 0) | |||
| } | |||
| 
 | |||
| /** | |||
|  * 判断element对象 | |||
|  * @param {*} elm element对象 | |||
|  * @param {*} attrName 属性名 | |||
|  * @param {*} attrValue 属性值 | |||
|  * @returns | |||
|  */ | |||
| export const isElm = function(elm, attrName, attrValue) { | |||
|   return elm.hasAttribute(attrName) && elm.getAttribute(attrName) === attrValue | |||
| } | |||
| 
 | |||
| /** | |||
|  * 判断插件(根据样式) | |||
|  * @param {*} element dom对象 | |||
|  * @param {*} pluginClassName 插件名 | |||
|  * @returns | |||
|  */ | |||
| export const isPlugin = function(elm, pluginClassName) { | |||
|   if (elm.className && elm.className.indexOf(pluginClassName) >= 0) { | |||
|     return true | |||
|   } | |||
|   return false | |||
| } | |||
| 
 | |||
| /** | |||
|  * 字典表:样式单位匹配 | |||
|  */ | |||
| export const styleUnitMap = { | |||
|   width: 'px', | |||
|   height: 'px' | |||
| } | |||
| 
 | |||
| /** | |||
|  * 属性更新 | |||
|  * @param {*} elm dom节点 | |||
|  * @param {*} name 属性名 | |||
|  * @param {*} value 属性值 | |||
|  */ | |||
| export const updateAttrib = function(elm, name, value) { | |||
|   if (value === '') { | |||
|     elm.removeAttribute(name) | |||
|   } else { | |||
|     elm.setAttribute(name, value) | |||
|   } | |||
| } | |||
| 
 | |||
| /** | |||
|  * 更新dom对象 | |||
|  * @param {*} editor 编辑器 | |||
|  * @param {*} elm dom对象 | |||
|  * @param {*} dataForm 新数据集合对象 | |||
|  * @param {*} initHandler 初始化执行函数 | |||
|  */ | |||
| export const updateElm = function(editor, elm, className, dataForm, initHandler) { | |||
|   const styleObj = {} | |||
|   let classes = className + ' ' | |||
|   for (const key of Object.keys(dataForm)) { | |||
|     if (key.indexOf('style.') >= 0) { | |||
|       const styleName = key.replace('style.', '') | |||
|       let styleValue = dataForm[key] | |||
|       if (styleName === 'width' || styleName === 'height') { | |||
|         if (dataForm[key].indexOf('%') > 0 || dataForm[key].indexOf('px') > 0) { | |||
|           styleValue = dataForm[key] | |||
|         } else { | |||
|           styleValue = dataForm[key] + 'px' | |||
|         } | |||
|       } | |||
|       styleObj[styleName] = styleValue | |||
|     } else if (key.indexOf('class.') >= 0) { | |||
|       if (dataForm[key] !== '') { | |||
|         classes += dataForm[key] + ' ' | |||
|       } | |||
|     } else { | |||
|       if (dataForm[key] !== editor.dom.getAttrib(elm, key)) { | |||
|         updateAttrib(elm, key, dataForm[key]) | |||
|       } | |||
|     } | |||
|   } | |||
|   editor.dom.setStyles(elm, styleObj) | |||
|   elm.className = classes | |||
|   // 初始化控件
 | |||
|   if (initHandler) { initHandler(editor, elm, dataForm) } | |||
| } | |||
| 
 | |||
| /** | |||
|  * 根据数据集合对象转换成dom对象代码片段 | |||
|  * @param {*} dataForm 数据集合对象 | |||
|  * @returns dom对象代码片段 | |||
|  */ | |||
| export const dataFormToElmPartStr = function(dataForm, className) { | |||
|   let attributes = '' | |||
|   let styles = '' | |||
|   let classes = className + ' ' | |||
|   for (const key of Object.keys(dataForm)) { | |||
|     if (key.indexOf('style.') === 0) { | |||
|       if (dataForm[key] !== '') { | |||
|         const styleName = key.replace('style.', '') | |||
|         let styleValue = dataForm[key] | |||
|         if (styleName === 'width' || styleName === 'height') { | |||
|           if (dataForm[key].indexOf('%') > 0 || dataForm[key].indexOf('px') > 0) { | |||
|             styleValue = dataForm[key] | |||
|           } else { | |||
|             styleValue = dataForm[key] + 'px' | |||
|           } | |||
|         } | |||
|         styles += `${styleName}:${styleValue};` | |||
|       } | |||
|     } else if (key.indexOf('class.') === 0) { | |||
|       if (dataForm[key] !== '') { | |||
|         classes += dataForm[key] + ' ' | |||
|       } | |||
|     } else { | |||
|       attributes += `${key}="${dataForm[key]}" ` | |||
|     } | |||
|   } | |||
|   return `class="${classes}" style="${styles} font-family: inherit;font-size: inherit;" ${attributes}` | |||
| } | |||
| 
 | |||
| /** | |||
|  * dom对象提取数据集合对象 | |||
|  * @param {*} editor 编辑器 | |||
|  * @param {*} initDataForm 原始数据对象 | |||
|  * @param {*} pluginClassName 插件名 | |||
|  * @returns 数据集合对象 | |||
|  */ | |||
| export const elmToDataForm = function(editor, initDataForm, pluginClassName, customHandle) { | |||
|   const elm = editor.selection.getNode() | |||
|   const dataForm = __assign({}, initDataForm) | |||
|   if (isPlugin(elm, pluginClassName)) { | |||
|     for (const key of Object.keys(dataForm)) { | |||
|       if (key.indexOf('style.') >= 0) { | |||
|         const styleName = key.replace('style.', '') | |||
|         dataForm[key] = editor.dom.getStyle(elm, styleName).replace(styleUnitMap[styleName] || '', '') | |||
|       } else if (key.indexOf('class.') >= 0) { | |||
|         dataForm[key] = classMap(elm.className, key) || '' | |||
|       } else { | |||
|         dataForm[key] = editor.dom.getAttrib(elm, key) | |||
|       } | |||
|     } | |||
|   } | |||
|   customHandle ? customHandle(editor, dataForm) : null | |||
|   return dataForm | |||
| } | |||
| 
 | |||
| /** | |||
|  * 根据id获取选项具体信息 | |||
|  * @param {*} id 匹配字段,对应listbox中的value | |||
|  * @returns 对象 | |||
|  */ | |||
| export const getItemInfo_Field = function(id) { | |||
|   if (window.sessionStorage.getItem('dictField')) { | |||
|     const dict = Array.from(JSON.parse(window.sessionStorage.getItem('dictField'))) | |||
|     dict.forEach(item => { | |||
|       if (item.id && item.id === id) { | |||
|         return item | |||
|       } else { | |||
|         item.childrenList.forEach(item2 => { | |||
|           if (item2.id && item2.id === id) { | |||
|             return id | |||
|           } | |||
|         }) | |||
|       } | |||
|     }) | |||
|   } | |||
|   return null | |||
| } | |||
| 
 | |||
| /** | |||
|  * 获取字段字典表的listbox格式的数据 | |||
|  * @returns listbox数组 | |||
|  */ | |||
| export const getListbox_Field = function() { | |||
|   const selectbox = [{ text: '----无----', value: '' }] | |||
|   if (window.sessionStorage.getItem('dictField')) { | |||
|     const dict = Array.from(JSON.parse(window.sessionStorage.getItem('dictField'))) | |||
|     dict.forEach(examItem => { | |||
|       const obj = { | |||
|         text: '', | |||
|         items: [] | |||
|       } | |||
|       obj.text = examItem.label | |||
|       if (examItem.children && examItem.children.length > 0) { | |||
|         examItem.children.forEach(field => { | |||
|           obj.items.push({ | |||
|             text: field.label, | |||
|             value: field.value | |||
|           }) | |||
|         }) | |||
|       } | |||
|       selectbox.push(obj) | |||
|     }) | |||
|   } | |||
|   return selectbox | |||
| } | |||
| 
 | |||
| /** | |||
|  * 根据dom的className匹配属性选项值 | |||
|  * 如:className中的【XXX-1】 =>  dataForm["class.XXX"]=XXX-1 | |||
|  * @param {*} className dom元素的className | |||
|  * @param {*} dataFormKey 需要匹配的属性 | |||
|  * @returns | |||
|  */ | |||
| export const classMap = function(className, dataFormKey) { | |||
|   const classList = className.split(' ') | |||
|   const temp = dataFormKey.replace('class.', '') | |||
|   for (let i = 0; i < classList.length; i++) { | |||
|     if (classList[i].indexOf(temp + '-') === 0) { | |||
|       return classList[i] | |||
|     } | |||
|   } | |||
| } | |||
| 
 | |||
| // 浅拷贝
 | |||
| export let __assign = function() { | |||
|   __assign = Object.assign || function __assign(t) { | |||
|     for (var s, i = 1, n = arguments.length; i < n; i++) { | |||
|       s = arguments[i] | |||
|       for (var p in s) { | |||
|         if (Object.prototype.hasOwnProperty.call(s, p)) { t[p] = s[p] } | |||
|       } | |||
|     } | |||
|     return t | |||
|   } | |||
|   return __assign.apply(this, arguments) | |||
| } | |||
| @ -0,0 +1,56 @@ | |||
| /* eslint-disable no-unused-vars */ | |||
| /* eslint-disable no-undef */ | |||
| tinymce.PluginManager.add('letterspacing', function(editor, url) { | |||
|   var pluginName = '字间距' | |||
|   var global$1 = tinymce.util.Tools.resolve('tinymce.util.Tools') | |||
|   var letterspacing_val = editor.getParam('letterspacing_val', '1px 2px 3px 4px 5px') | |||
| 
 | |||
|   editor.on('init', function() { | |||
|     editor.formatter.register({ | |||
|       letterspacing: { inline: 'span', styles: { 'letter-spacing': '%value' }} | |||
|     }) | |||
|   }) | |||
| 
 | |||
|   var doAct = function(value) { | |||
|     editor.formatter.apply('letterspacing', { value: value }) | |||
|     editor.fire('change', {}) | |||
|   } | |||
| 
 | |||
|   editor.ui.registry.addMenuButton('letterspacing', { | |||
|     text: '<svg t="1570979572631" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="12244" width="20" height="20" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style type="text/css"></style></defs><path d="M33.450667 3.413333h102.4v956.8256H33.450667V3.413333z m887.330133 1.8432h102.4v957.713067h-102.4V5.188267z m-425.301333 200.704h108.9536l223.6416 584.977067h-102.4l-53.248-146.6368H427.485867l-53.248 146.6368h-102.4l223.6416-584.9088z m-39.3216 359.697067H643.754667L552.004267 309.248h-3.2768L456.157867 565.6576z" fill="#2c2c2c" p-id="12245"></path></svg>', | |||
|     tooltip: pluginName, | |||
|     fetch: function(callback) { | |||
|       var dom = editor.dom | |||
|       var blocks = editor.selection.getSelectedBlocks() | |||
|       var lhv = 0 | |||
|       global$1.each(blocks, function(block) { | |||
|         if (lhv === 0) { | |||
|           lhv = dom.getStyle(block, 'letterspacing') ? dom.getStyle(block, 'letterspacing') : 0 | |||
|         } | |||
|       }) | |||
| 
 | |||
|       var items = letterspacing_val.split(' ').map(function(item) { | |||
|         var text = item | |||
|         var value = item | |||
|         return { | |||
|           type: 'togglemenuitem', | |||
|           text: text, | |||
|           active: lhv === value, | |||
|           onAction: function() { | |||
|             doAct(value) | |||
|           } | |||
|         } | |||
|       }) | |||
|       callback(items) | |||
|     } | |||
|   }) | |||
| 
 | |||
|   return { | |||
|     getMetadata: function() { | |||
|       return { | |||
|         name: pluginName, | |||
|         url: 'http://tinymce.ax-z.cn/more-plugins/lineheight.php' | |||
|       } | |||
|     } | |||
|   } | |||
| }) | |||
| @ -0,0 +1,7 @@ | |||
| // Exports the "silver" theme for usage with module loaders
 | |||
| // Usage:
 | |||
| //   CommonJS:
 | |||
| //     require('tinymce/themes/silver')
 | |||
| //   ES2015:
 | |||
| //     import 'tinymce/themes/silver'
 | |||
| require('./theme.js') | |||
								
									
										File diff suppressed because it is too large
									
								
							
						
					| @ -0,0 +1,149 @@ | |||
| <template> | |||
|   <el-input | |||
|     v-model="searchKeyWord" | |||
|     class="header-search" | |||
|     size="mini" | |||
|     placeholder="关键词" | |||
|     @keyup.enter.native="searchNext" | |||
|   > | |||
|     <span slot="suffix" class="search-result"> | |||
|       {{ ((searchIndex==-1)?0:(searchIndex+1))+'/'+searchResult.length }} | |||
|     </span> | |||
|     <i slot="suffix" class="el-input__icon el-icon-arrow-down" title="下一个" @click="searchNext" /> | |||
|     <i slot="suffix" class="el-input__icon el-icon-arrow-up" title="上一个" @click="searchLast" /> | |||
|     <i slot="suffix" class="el-input__icon el-icon-refresh" title="重置" @click="searchReset" /> | |||
|   </el-input> | |||
| </template> | |||
| 
 | |||
| <script> | |||
| import cloneDeep from 'lodash/cloneDeep' | |||
| 
 | |||
| export default { | |||
|   props: { | |||
|     value: { type: Array, default: () => [] } | |||
|   }, | |||
|   data() { | |||
|     return { | |||
|       dataList: [], | |||
|       dataListTemp: [], | |||
|       searchKeyWord: '', | |||
|       searchIndex: -1, | |||
|       searchResult: [] | |||
|     } | |||
|   }, | |||
|   watch: { | |||
|     searchKeyWord(val) { | |||
|       if (val) { | |||
|         this.searchHandle() | |||
|       } | |||
|     }, | |||
|     value(val) { | |||
|     //   this.dataListTemp = val | |||
|     } | |||
|   }, | |||
|   methods: { | |||
|     searchLast() { | |||
|       if (this.searchResult.length > 0) { | |||
|         if (this.searchIndex > 0) { | |||
|           this.searchIndex-- | |||
|         } else { | |||
|           this.searchIndex = this.searchResult.length - 1 | |||
|         } | |||
|         this.searchIndexDisplay() | |||
|       } else { | |||
|         this.searchIndex = -1 | |||
|       } | |||
|     }, | |||
|     searchNext() { | |||
|       if (this.searchResult.length > 0) { | |||
|         if (this.searchIndex + 1 < this.searchResult.length) { | |||
|           this.searchIndex++ | |||
|         } else if (this.searchIndex + 1 >= this.searchResult.length) { | |||
|           this.searchIndex = 0 | |||
|         } | |||
|         this.searchIndexDisplay() | |||
|       } else { | |||
|         this.searchIndex = -1 | |||
|       } | |||
|     }, | |||
|     searchReset() { | |||
|       this.searchIndex = -1 | |||
|       this.searchKeyWord = '' | |||
|       this.searchResult = [] | |||
|       this.dataList = cloneDeep(this.dataListTemp) | |||
|     }, | |||
|     searchIndexDisplay() { | |||
|       if (this.searchIndex >= 0 && this.searchResult.length > 0) { | |||
|         const index = this.searchResult[this.searchIndex] | |||
|         // this.$refs.dataList.toggleRowExpansion(this.dataList[index], true) | |||
|         // this.setCurrentRow(index) | |||
|         this.$emit('focusResult', index) | |||
|       } | |||
|     }, | |||
|     searchHandle() { | |||
|       if (!this.searchKeyWord) { return false } | |||
|       this.searchIndex = -1 | |||
|       this.searchResult = [] | |||
|       this.dataList = cloneDeep(this.dataListTemp) | |||
| 
 | |||
|       const regex = new RegExp(this.searchKeyWord, 'g') | |||
|       let rowCount = 0 | |||
|       this.dataList.forEach((item1, rowIndex1) => { | |||
|         const data = item1.data | |||
|         let isFlag = false | |||
|         if (data && data.length > 0) { | |||
|           data.forEach((item2, rowIndex2) => { | |||
|             // 遍历行对象 | |||
|             Object.keys(item2).forEach(key => { | |||
|               if (item2[key] && item2[key].toString().includes(this.searchKeyWord)) { | |||
|                 isFlag = true | |||
|                 // 关键词标记 | |||
|                 item2[key] = item2[key].toString().replace(regex, `<span style='color:red;'>${this.searchKeyWord}</span>`) | |||
|               } | |||
|             }) | |||
|           }) | |||
|         } | |||
|         if (isFlag) { | |||
|           // 记录数据位置 | |||
|           this.searchResult[rowCount] = rowIndex1 | |||
|           rowCount++ | |||
|         } | |||
|       }) | |||
|       this.$emit('input', this.dataList) | |||
| 
 | |||
|     //   this.$emit('update:queryItem', queryItem) | |||
|     } | |||
|   } | |||
| } | |||
| </script> | |||
| 
 | |||
| <style lang="scss" scoped> | |||
| .header-search { | |||
|   width: 300px; | |||
| } | |||
| ::v-deep .el-input__suffix { | |||
|   display: flex; | |||
|   align-items: center; | |||
| 
 | |||
|   .el-input__suffix-inner { | |||
|     .search-result { | |||
|       display: inline-block; | |||
|       padding: 0 10px; | |||
|       border-right: 1px solid #c0c4cc; | |||
|     } | |||
| 
 | |||
|     .el-input__icon { | |||
|       cursor: pointer; | |||
|       width: 20px; | |||
|       border-radius: 20px; | |||
|       line-height: 20px; | |||
|       margin: 4px 2px; | |||
|     } | |||
| 
 | |||
|     .el-input__icon:hover { | |||
|       background: #c0c4cc; | |||
|       color: #fff; | |||
|     } | |||
|   } | |||
| } | |||
| </style> | |||
| @ -0,0 +1,150 @@ | |||
| import cloneDeep from 'lodash/cloneDeep' | |||
| 
 | |||
| export default { | |||
|   props: { | |||
|     patientIdNumber: { type: String, required: true }, | |||
|     projectId: { type: String, default: '' } | |||
|   }, | |||
|   data() { | |||
|     return { | |||
|       dataListLoading: false, | |||
|       dataList: [], | |||
|       dataListTemp: [], | |||
|       type: '', | |||
|       searchKeyWord: '', | |||
|       searchIndex: -1, | |||
|       searchResult: [], | |||
|       searchColumn: [] | |||
|     } | |||
|   }, | |||
|   watch: { | |||
|     searchKeyWord(val) { | |||
|       if (val) { | |||
|         this.searchHandle() | |||
|       } else { | |||
|         this.searchReset() | |||
|       } | |||
|     } | |||
|   }, | |||
|   created() { this.getDataList() }, | |||
|   methods: { | |||
|     refreshData() { this.getDataList() }, | |||
|     getDataList() { | |||
|       this.dataListLoading = true | |||
|       this.$http.get('/patient/view/examData', { | |||
|         params: { | |||
|           patientIdNumber: this.patientIdNumber, | |||
|           projectId: this.projectId ? this.projectId : null, | |||
|           type: this.type | |||
|         } | |||
|       }).then(({ data: res }) => { | |||
|         this.dataList = cloneDeep(res.data) | |||
|         this.dataListTemp = cloneDeep(res.data) | |||
|         this.dataListLoading = false | |||
|       }).catch(() => { this.dataListLoading = false }) | |||
|     }, | |||
|     setIndexDate(date) { | |||
|       if (date) { | |||
|         const rowIndex = this.dataList.findIndex(item => { | |||
|           return (item.opDate && item.opDate === date) || | |||
|           (item.examTime && item.examTime.indexOf(date) >= 0) || | |||
|           (item.EXAM_TIME && item.EXAM_TIME.indexOf(date) >= 0) | |||
|         }) | |||
|         if (rowIndex >= 0) { | |||
|           setTimeout(() => { | |||
|             this.setCurrentRow(rowIndex) | |||
|           }, 100) | |||
|         } | |||
|       } | |||
|     }, | |||
|     setCurrentRow(i) { | |||
|       if (this.$refs.dataList) { | |||
|         this.$refs.dataList.setCurrentRow(this.dataList[i]) | |||
|         // this.$refs.dataList.toggleRowExpansion(this.dataList[i], true)
 | |||
|         const targetTop = this.$refs.dataList.$el.querySelectorAll('.el-table__body .row-1')[i].getBoundingClientRect().top | |||
|         const containerTop = this.$refs.dataList.$el.querySelector('.el-table__body').getBoundingClientRect().top | |||
|         const scrollParent = this.$refs.dataList.$el.querySelector('.el-table__body-wrapper') | |||
|         // console.log(this.$refs.dataList.$el, scrollParent, targetTop, containerTop)
 | |||
|         // const el = this.$refs.dataList.$el.querySelectorAll('.el-table__body .row-1')[i]
 | |||
|         // console.log(el, el.getClientRects(), el.getBoundingClientRect())
 | |||
|         scrollParent.scrollTop = targetTop - containerTop | |||
|       } | |||
|     }, | |||
|     searchLast() { | |||
|       if (this.searchResult.length > 0) { | |||
|         if (this.searchIndex > 0) { | |||
|           this.searchIndex-- | |||
|         } else { | |||
|           this.searchIndex = this.searchResult.length - 1 | |||
|         } | |||
|         this.searchIndexDisplay() | |||
|       } else { | |||
|         this.searchIndex = -1 | |||
|       } | |||
|     }, | |||
|     searchNext() { | |||
|       if (this.searchResult.length > 0) { | |||
|         if (this.searchIndex + 1 < this.searchResult.length) { | |||
|           this.searchIndex++ | |||
|         } else if (this.searchIndex + 1 >= this.searchResult.length) { | |||
|           this.searchIndex = 0 | |||
|         } | |||
|         this.searchIndexDisplay() | |||
|       } else { | |||
|         this.searchIndex = -1 | |||
|       } | |||
|     }, | |||
|     searchReset() { | |||
|       this.searchIndex = -1 | |||
|       this.searchKeyWord = '' | |||
|       this.searchResult = [] | |||
|       this.dataList = cloneDeep(this.dataListTemp) | |||
|     }, | |||
|     searchIndexDisplay() { | |||
|       if (this.searchIndex >= 0 && this.searchResult.length > 0) { | |||
|         const index = this.searchResult[this.searchIndex] | |||
|         this.$refs.dataList.toggleRowExpansion(this.dataList[index], true) | |||
|         this.setCurrentRow(index) | |||
|       } | |||
|     }, | |||
|     searchHandle() { | |||
|       if (!this.searchKeyWord) { return false } | |||
|       this.searchIndex = -1 | |||
|       this.searchResult = [] | |||
|       this.dataList = cloneDeep(this.dataListTemp) | |||
| 
 | |||
|       const regex = new RegExp(this.searchKeyWord, 'g') | |||
|       let rowCount = 0 | |||
|       this.dataList.forEach((item1, rowIndex1) => { | |||
|         const data = item1.data | |||
|         let isFlag = false | |||
|         if (data && data.length > 0) { | |||
|           // data子集匹配
 | |||
|           data.forEach((item2, rowIndex2) => { | |||
|             // 遍历行对象
 | |||
|             // Object.keys(item2).forEach(key => {
 | |||
|             this.searchColumn.forEach(key => { | |||
|               if (item2[key] && item2[key].toString().includes(this.searchKeyWord)) { | |||
|                 isFlag = true | |||
|                 item2[key] = item2[key].toString().replace(regex, `<span style='color:red;'>${this.searchKeyWord}</span>`) | |||
|               } | |||
|             }) | |||
|           }) | |||
|         } else { | |||
|           // 无data子集,自匹配
 | |||
|           this.searchColumn.forEach(key => { | |||
|             if (item1[key] && item1[key].toString().includes(this.searchKeyWord)) { | |||
|               isFlag = true | |||
|               item1[key] = item1[key].toString().replace(regex, `<span style='color:red;'>${this.searchKeyWord}</span>`) | |||
|             } | |||
|           }) | |||
|         } | |||
|         if (isFlag) { | |||
|           // 记录数据位置
 | |||
|           this.searchResult[rowCount] = rowIndex1 | |||
|           rowCount++ | |||
|         } | |||
|       }) | |||
|     } | |||
|   } | |||
| } | |||
| @ -0,0 +1,75 @@ | |||
| <template> | |||
|   <div class="component-wrapper"> | |||
|     <el-table | |||
|       ref="dataList" | |||
|       v-loading="dataListLoading" | |||
|       highlight-current-row | |||
|       height="100%" | |||
|       :data="dataList" | |||
|       border | |||
|       :row-class-name="'row-1'" | |||
|     > | |||
|       <el-table-column type="expand" :label="'展开'" width="50px"> | |||
|         <template slot-scope="scope"> | |||
|           <el-table :data="scope.row.data"> | |||
|             <el-table-column prop="OP_TIME" :label="'诊断时间'" width="155px"> | |||
|               <template slot-scope="scope2"> | |||
|                 <div v-html="scope2.row.OP_TIME" /> | |||
|               </template> | |||
|             </el-table-column> | |||
|             <el-table-column prop="DIAG_ICD" :label="'诊断编码'"> | |||
|               <template slot-scope="scope2"> | |||
|                 <div v-html="scope2.row.DIAG_ICD" /> | |||
|               </template> | |||
|             </el-table-column> | |||
|             <el-table-column prop="DIAG_NAME" :label="'诊断内容'" show-overflow-tooltip> | |||
|               <template slot-scope="scope2"> | |||
|                 <div v-html="scope2.row.DIAG_NAME" /> | |||
|               </template> | |||
|             </el-table-column> | |||
|             <el-table-column prop="DIAG_ICD_ATTACH" :label="'附加'"> | |||
|               <template slot-scope="scope2"> | |||
|                 <div v-html="scope2.row.DIAG_ICD_ATTACH" /> | |||
|               </template> | |||
|             </el-table-column> | |||
|             <el-table-column prop="OP_USER_NAME" :label="'诊断医生'"> | |||
|               <template slot-scope="scope2"> | |||
|                 <div v-html="scope2.row.OP_USER_NAME" /> | |||
|               </template> | |||
|             </el-table-column> | |||
|           </el-table> | |||
|         </template> | |||
|       </el-table-column> | |||
|       <el-table-column prop="opDate" :label="'日期'" width="120px" header-align="center" align="center" /> | |||
|       <el-table-column prop="opContent" show-overflow-tooltip> | |||
|         <template slot="header" slot-scope="{}"> | |||
|           <div class="header-wrapper"> | |||
|             <span>主要内容(诊断)</span> | |||
|             <el-input v-model="searchKeyWord" class="header-search" size="mini" placeholder="关键词" @keyup.enter.native="searchNext"> | |||
|               <span slot="suffix" class="search-result"> | |||
|                 {{ ((searchIndex==-1)?0:(searchIndex+1))+'/'+searchResult.length }} | |||
|               </span> | |||
|               <i slot="suffix" class="el-input__icon el-icon-arrow-down" title="下一个" @click="searchNext" /> | |||
|               <i slot="suffix" class="el-input__icon el-icon-arrow-up" title="上一个" @click="searchLast" /> | |||
|               <i slot="suffix" class="el-input__icon el-icon-refresh" title="重置" @click="searchReset" /> | |||
|             </el-input> | |||
|           </div> | |||
|         </template> | |||
|       </el-table-column> | |||
|     </el-table> | |||
|   </div> | |||
| </template> | |||
| 
 | |||
| <script> | |||
| import myMixin from './_mixin' | |||
| 
 | |||
| export default { | |||
|   mixins: [myMixin], | |||
|   data() { | |||
|     return { | |||
|       type: '诊断', | |||
|       searchColumn: ['OP_TIME', 'DIAG_ICD', 'DIAG_NAME', 'DIAG_ICD_ATTACH', 'OP_USER_NAME'] | |||
|     } | |||
|   } | |||
| } | |||
| </script> | |||
| @ -0,0 +1,73 @@ | |||
| <template> | |||
|   <div class="component-wrapper"> | |||
|     <el-table | |||
|       ref="dataList" | |||
|       v-loading="dataListLoading" | |||
|       highlight-current-row | |||
|       height="100%" | |||
|       :data="dataList" | |||
|       border | |||
|       :row-class-name="'row-1'" | |||
|     > | |||
|       <el-table-column prop="INPUT_DATE" :label="'日期'" width="120px" header-align="center" align="center" /> | |||
|       <el-table-column prop="CRF_NAME" :label="'表单'" show-overflow-tooltip /> | |||
|       <el-table-column label="操作" header-align="center" align="center" width="120"> | |||
|         <template slot-scope="scope"> | |||
|           <el-button type="text" size="small" @click="btnEcrfViewClick(scope.row)">查看</el-button> | |||
|         </template> | |||
|       </el-table-column> | |||
|     </el-table> | |||
| 
 | |||
|     <ecrf-view v-if="visible" ref="ecrfView" :type="'load'" print edit remove @remove="remove" @edit="edit" /> | |||
|     <!-- 填写 --> | |||
|     <follow-up-edit v-if="followUpVisible" ref="followUpEdit" @refreshData="refreshData" /> | |||
|   </div> | |||
| </template> | |||
| 
 | |||
| <script> | |||
| import myMixin from './_mixin' | |||
| import ecrfView from '@/components/ecrf/dialog-load.vue' | |||
| import followUpEdit from '@/components/ecrf/follow-up-edit.vue' | |||
| 
 | |||
| export default { | |||
|   components: { ecrfView, followUpEdit }, | |||
|   mixins: [myMixin], | |||
|   data() { | |||
|     return { | |||
|       visible: false, | |||
|       followUpVisible: false, | |||
|       ecrfId: '', | |||
|       type: '表单' | |||
|     } | |||
|   }, | |||
|   methods: { | |||
|     btnEcrfViewClick(row) { | |||
|       this.visible = true | |||
|       this.$nextTick(() => { | |||
|         this.$refs.ecrfView.id = String(row.ID) | |||
|         this.$refs.ecrfView.init() | |||
|       }) | |||
|     }, | |||
|     remove(id) { | |||
|       this.$emit('refresh') | |||
|     }, | |||
|     edit(id) { | |||
|       const obj = this.dataList.find(item => item.ID === id) | |||
|       console.log(this.dataList, obj, id) | |||
|       if (obj) { | |||
|         this.visible = false | |||
|         this.$nextTick(() => { | |||
|           this.followUpVisible = true | |||
| 
 | |||
|           this.$nextTick(() => { | |||
|             this.$refs.followUpEdit.id = String(obj.ID) | |||
|             this.$refs.followUpEdit.crfId = String(obj.CRF_ID) | |||
|             this.$refs.followUpEdit.patientIdNumber = obj.PATIENT_ID_NUMBER | |||
|             this.$refs.followUpEdit.init() | |||
|           }) | |||
|         }) | |||
|       } | |||
|     } | |||
|   } | |||
| } | |||
| </script> | |||
| @ -0,0 +1,83 @@ | |||
| <template> | |||
|   <div class="component-wrapper"> | |||
|     <el-table | |||
|       ref="dataList" | |||
|       v-loading="dataListLoading" | |||
|       highlight-current-row | |||
|       height="100%" | |||
|       :data="dataList" | |||
|       border | |||
|       :row-class-name="'row-1'" | |||
|     > | |||
|       <el-table-column type="expand" :label="'展开'" width="50px"> | |||
|         <template slot-scope="scope"> | |||
|           <el-form label-width="120px" class="expand-form"> | |||
|             <el-form-item :label="'就诊时间'"> | |||
|               <div v-html="scope.row.TREAT_TIME" /> | |||
|             </el-form-item> | |||
|             <el-form-item :label="'主诉'"> | |||
|               <div v-html="scope.row.COMP_CONTENT" /> | |||
|             </el-form-item> | |||
|             <el-form-item :label="'现病史'"> | |||
|               <div v-html="scope.row.ILLN_CONTENT" /> | |||
|             </el-form-item> | |||
|             <el-form-item :label="'既往史'"> | |||
|               <div v-html="scope.row.HIS_ILLN_CONTENT" /> | |||
|             </el-form-item> | |||
|             <el-form-item :label="'诊断'"> | |||
|               <div v-html="scope.row.DIAG_NAME" /> | |||
|             </el-form-item> | |||
|             <el-form-item :label="'处理意见'"> | |||
|               <div v-html="scope.row.EMR_TREA_SUGGESTION" /> | |||
|             </el-form-item> | |||
|             <el-form-item :label="'专科检查文本'"> | |||
|               <div v-html="scope.row.EMR_SPEC_TEXT" /> | |||
|             </el-form-item> | |||
|             <el-form-item :label="'医生姓名'"> | |||
|               <div v-html="scope.row.DOCTOR_NAME" /> | |||
|             </el-form-item> | |||
|           </el-form> | |||
|         </template> | |||
|       </el-table-column> | |||
|       <el-table-column prop="OP_DATE" :label="'日期'" width="120px" header-align="center" align="center" /> | |||
|       <el-table-column prop="DIAG_NAME" :label="'主要内容(诊断)'" show-overflow-tooltip> | |||
|         <template slot="header" slot-scope="{}"> | |||
|           <div class="header-wrapper"> | |||
|             <span>主要内容(诊断)</span> | |||
|             <el-input v-model="searchKeyWord" class="header-search" size="mini" placeholder="关键词" @keyup.enter.native="searchNext"> | |||
|               <span slot="suffix" class="search-result"> | |||
|                 {{ ((searchIndex==-1)?0:(searchIndex+1))+'/'+searchResult.length }} | |||
|               </span> | |||
|               <i slot="suffix" class="el-input__icon el-icon-arrow-down" title="下一个" @click="searchNext" /> | |||
|               <i slot="suffix" class="el-input__icon el-icon-arrow-up" title="上一个" @click="searchLast" /> | |||
|               <i slot="suffix" class="el-input__icon el-icon-refresh" title="重置" @click="searchReset" /> | |||
|             </el-input> | |||
|           </div> | |||
|         </template> | |||
|       </el-table-column> | |||
|     </el-table> | |||
|   </div> | |||
| </template> | |||
| 
 | |||
| <script> | |||
| import myMixin from './_mixin' | |||
| 
 | |||
| export default { | |||
|   mixins: [myMixin], | |||
|   data() { | |||
|     return { | |||
|       type: '门诊', | |||
|       searchColumn: [ | |||
|         'TREAT_TIME', | |||
|         'COMP_CONTENT', | |||
|         'ILLN_CONTENT', | |||
|         'HIS_ILLN_CONTENT', | |||
|         'DIAG_NAME', | |||
|         'EMR_TREA_SUGGESTION', | |||
|         'EMR_SPEC_TEXT', | |||
|         'DOCTOR_NAME' | |||
|       ] | |||
|     } | |||
|   } | |||
| } | |||
| </script> | |||
| @ -0,0 +1,118 @@ | |||
| <template> | |||
|   <div class="component-wrapper"> | |||
|     <el-table | |||
|       ref="dataList" | |||
|       v-loading="dataListLoading" | |||
|       highlight-current-row | |||
|       height="100%" | |||
|       :data="dataList" | |||
|       border | |||
|       :row-class-name="'row-1'" | |||
|     > | |||
|       <el-table-column type="expand" :label="'展开'" width="50px"> | |||
|         <template slot-scope="scope"> | |||
|           <el-table :data="scope.row.data"> | |||
|             <el-table-column prop="EXAM_TIME" :label="'检查时间'" width="155px"> | |||
|               <template slot-scope="scope2"> | |||
|                 <div v-html="scope2.row.EXAM_TIME" /> | |||
|               </template> | |||
|             </el-table-column> | |||
|             <el-table-column prop="EXAMINE_ITEM" :label="'检查项目'"> | |||
|               <template slot-scope="scope2"> | |||
|                 <div v-html="scope2.row.ITEM_NAME || scope2.row.EXAMINE_ITEM" /> | |||
|               </template> | |||
|             </el-table-column> | |||
|             <el-table-column :label="'检查报告'"> | |||
|               <template slot-scope="scope2"> | |||
|                 <el-button type="text" @click="showReport(scope2.row)">当次报告</el-button> | |||
|                 <el-button type="text" @click="showReportAll(scope2.row)">所有报告</el-button> | |||
|               </template> | |||
|             </el-table-column> | |||
|           </el-table> | |||
|           <!-- EXAM_NO EXAMINE_CODE  ITEM_ID ITEM_NAME --> | |||
|         </template> | |||
|       </el-table-column> | |||
|       <el-table-column prop="opDate" :label="'日期'" width="120px" header-align="center" align="center" /> | |||
|       <el-table-column prop="opContent" :label="'主要内容(检查项目)'" show-overflow-tooltip> | |||
|         <template slot="header" slot-scope="{}"> | |||
|           <div class="header-wrapper"> | |||
|             <span>主要内容(检查项目)</span> | |||
|             <el-input v-model="searchKeyWord" class="header-search" size="mini" placeholder="关键词" @keyup.enter.native="searchNext"> | |||
|               <span slot="suffix" class="search-result"> | |||
|                 {{ ((searchIndex==-1)?0:(searchIndex+1))+'/'+searchResult.length }} | |||
|               </span> | |||
|               <i slot="suffix" class="el-input__icon el-icon-arrow-down" title="下一个" @click="searchNext" /> | |||
|               <i slot="suffix" class="el-input__icon el-icon-arrow-up" title="上一个" @click="searchLast" /> | |||
|               <i slot="suffix" class="el-input__icon el-icon-refresh" title="重置" @click="searchReset" /> | |||
|             </el-input> | |||
|           </div> | |||
|         </template> | |||
|       </el-table-column> | |||
|     </el-table> | |||
|     <el-dialog | |||
|       width="95%" | |||
|       top="5vh" | |||
|       class="dialog-iframe" | |||
|       :title="examItemName||''" | |||
|       :visible.sync="dialogVisible" | |||
|       append-to-body | |||
|     > | |||
|       <iframe :src="src" width="100%" height="100%" frameborder="0" scrolling="yes" /> | |||
|     </el-dialog> | |||
|   </div> | |||
| </template> | |||
| 
 | |||
| <script> | |||
| import myMixin from './_mixin' | |||
| 
 | |||
| export default { | |||
|   mixins: [myMixin], | |||
|   data() { | |||
|     return { | |||
|       dialogVisible: false, | |||
|       examItemName: '', | |||
|       src: '', | |||
|       type: '检查', | |||
|       searchColumn: [ | |||
|         'EXAM_TIME', | |||
|         'ITEM_NAME' | |||
|       ] | |||
|     } | |||
|   }, | |||
|   methods: { | |||
|     showReport(scopeRow) { | |||
|       // scopeRow.examTime = this.$options.filters['dateFilterThree'](scopeRow.examTime) | |||
|       this.dialogVisible = true | |||
|       this.examItemName = scopeRow.EXAMINE_ITEM | |||
|       this.src = `${window.SITE_CONFIG['pacsWeb2URL']}/file/default1.asp?pid=${scopeRow.PATIENT_ID}&examdate=(''${this.$options.filters['dateFilterThree'](scopeRow.EXAM_DATE)}${scopeRow.EXAMINE_CODE}'')&itemcode=x&language=zh-CN&risNo=${scopeRow.RIS_NO}&examNo=${scopeRow.EXAM_NO}` | |||
|     }, | |||
|     showReportAll(scopeRow) { | |||
|       // scopeRow.examTime = this.$options.filters['dateFilterThree'](scopeRow.examTime) | |||
|       this.dialogVisible = true | |||
|       this.examItemName = scopeRow.EXAMINE_ITEM | |||
|       this.src = `${window.SITE_CONFIG['pacsWeb2URL']}/file/default1.asp?pid=${scopeRow.PATIENT_ID}&itemcode=''${scopeRow.EXAMINE_CODE}''` | |||
|     } | |||
|   } | |||
| } | |||
| </script> | |||
| 
 | |||
| <style lang="scss" scoped> | |||
| // .component-wrapper{ | |||
| //   height: auto !important; | |||
| // } | |||
| 
 | |||
| .dialog-iframe   { | |||
| 
 | |||
|   ::v-deep .el-dialog__header{ | |||
|     padding: 5px 20px; | |||
| 
 | |||
|     .el-dialog__headerbtn{ | |||
|       top: 10px; | |||
|     } | |||
|   } | |||
| 
 | |||
|   ::v-deep .el-dialog__body{ | |||
|     height: calc(90vh - 70px); | |||
|   } | |||
| } | |||
| </style> | |||
| @ -0,0 +1,57 @@ | |||
| <template> | |||
|   <div class="component-wrapper"> | |||
|     <el-table | |||
|       ref="dataList" | |||
|       v-loading="dataListLoading" | |||
|       highlight-current-row | |||
|       height="100%" | |||
|       :data="dataList" | |||
|       border | |||
|       :row-class-name="'row-1'" | |||
|     > | |||
|       <el-table-column prop="IN_DATE" :label="'住院时间'" width="160px" /> | |||
|       <el-table-column prop="OUT_DATE" :label="'出院时间'" width="160px" /> | |||
|       <el-table-column prop="DIAG_NAME" :label="'住院诊断'" show-overflow-tooltip /> | |||
|       <el-table-column prop="DIAG_ID" :label="'诊断编号'" /> | |||
|       <el-table-column prop="DEPT_NAME" :label="'部门'" /> | |||
|       <el-table-column prop="WARD_NAME" :label="'病区'" /> | |||
|     </el-table> | |||
|   </div> | |||
| </template> | |||
| 
 | |||
| <script> | |||
| import myMixin from './_mixin' | |||
| 
 | |||
| export default { | |||
|   mixins: [myMixin], | |||
|   props: { | |||
|     dateType: { type: String, default: 'in' } | |||
|   }, | |||
|   data() { | |||
|     return { | |||
|       type: '住院' | |||
|     } | |||
|   }, | |||
|   methods: { | |||
|     setIndexDate(date) { | |||
|       // console.log(date, this.dateType) | |||
|       if (date) { | |||
|         const rowIndex = this.dataList.findIndex(item => { | |||
|           return (this.dateType === 'in' && item.IN_DATE && item.IN_DATE.indexOf(date) >= 0) || | |||
|           (this.dateType === 'out' && item.OUT_DATE && item.OUT_DATE.indexOf(date) >= 0) | |||
|         }) | |||
| 
 | |||
|         setTimeout(() => { | |||
|           this.setCurrentRow(rowIndex) | |||
|         }, 200) | |||
|       } | |||
|     } | |||
|   } | |||
| } | |||
| </script> | |||
| 
 | |||
| <style lang="scss" scoped> | |||
| // .component-wrapper{ | |||
| //   height: auto !important; | |||
| // } | |||
| </style> | |||
| @ -0,0 +1,38 @@ | |||
| <template> | |||
|   <div class="component-wrapper"> | |||
|     <el-table | |||
|       ref="dataList" | |||
|       v-loading="dataListLoading" | |||
|       highlight-current-row | |||
|       height="100%" | |||
|       :data="dataList" | |||
|       border | |||
|       :row-class-name="'row-1'" | |||
|     > | |||
|       <el-table-column prop="EXAM_TIME" :label="'检查时间'" width="155px" /> | |||
|       <el-table-column prop="IOP_TYPE" :label="'检查类型'" width="155px" /> | |||
|       <el-table-column prop="S_OD_IOP" :label="'OD'" /> | |||
|       <el-table-column prop="S_OS_IOP" :label="'OS'" /> | |||
|       <el-table-column prop="EXAM_MEMO" :label="'备注'" /> | |||
|     </el-table> | |||
|   </div> | |||
| </template> | |||
| 
 | |||
| <script> | |||
| import myMixin from './_mixin' | |||
| 
 | |||
| export default { | |||
|   mixins: [myMixin], | |||
|   data() { | |||
|     return { | |||
|       type: '眼压' | |||
|     } | |||
|   } | |||
| } | |||
| </script> | |||
| 
 | |||
| <style lang="scss" scoped> | |||
| // .component-wrapper{ | |||
| //   height: auto !important; | |||
| // } | |||
| </style> | |||
| @ -0,0 +1,113 @@ | |||
| 
 | |||
| <template> | |||
|   <div class="component-container"> | |||
|     <div> | |||
|       <kpi-select v-model="kpiIdList" class="kpi-select" :type="2" @change="kpiChangeHandle" /> | |||
|     </div> | |||
|     <div> | |||
|       <echarts-line-kpi-iop ref="chartIOP" class="echart-kpi" :chart-data="dataVaIop.yanya" :title="'眼压'" /> | |||
|       <echarts-line-kpi-va ref="chartVA" class="echart-kpi" :chart-data="dataVaIop.shili" /> | |||
|       <!-- 指标选择 --> | |||
|       <echarts-line-kpi | |||
|         v-for="(item,index) in kpiValEchartsList" | |||
|         ref="chartKPI" | |||
|         :key="index" | |||
|         class="echart-kpi" | |||
|         :chart-data="item.data" | |||
|         :title="item.label" | |||
|       /> | |||
|     </div> | |||
|   </div> | |||
| </template> | |||
| 
 | |||
| <script> | |||
| import kpiSelect from '@/components/kpi-select' | |||
| import echartsLineKpi from '@/components/echarts/line-kpi' | |||
| import echartsLineKpiVa from '@/components/echarts/line-kpi-va' | |||
| import echartsLineKpiIop from '@/components/echarts/line-kpi-iop' | |||
| 
 | |||
| export default { | |||
|   components: { echartsLineKpi, echartsLineKpiVa, echartsLineKpiIop, kpiSelect }, | |||
|   props: { | |||
|     patientIdNumber: { type: String, required: true }, | |||
|     indexDate: { type: String, default: '' }, | |||
|     projectId: { type: String, default: '' } | |||
|   }, | |||
|   data() { | |||
|     return { | |||
|       dataVaIop: [], | |||
|       kpiIdList: [], | |||
|       kpiValEchartsList: [], // 根据指标获取过来的echarts数据 | |||
|       kpiSelectItemList: [] | |||
|     } | |||
|   }, | |||
|   watch: { | |||
|     kpiSelectItemList: { | |||
|       handler(newVal, oldVal) { | |||
|         // 新增 | |||
|         const arrAdd = newVal.filter(x => oldVal.every(y => y.value !== x.value)) | |||
|         // 删除 | |||
|         const arrDel = oldVal.filter(x => newVal.every(y => y.value !== x.value)) | |||
| 
 | |||
|         arrAdd.forEach(item => { | |||
|           this.getKPIValue(item) | |||
|         }) | |||
| 
 | |||
|         arrDel.forEach(item => { | |||
|           const index = this.kpiValEchartsList.findIndex(item2 => item2.id === item.value) | |||
|           if (index >= 0) { this.kpiValEchartsList.splice(index, 1) } | |||
|         }) | |||
|       }, | |||
|       deep: true | |||
|     } | |||
|   }, | |||
|   created() { this.getDataVaIop() }, | |||
|   mounted() { }, | |||
|   methods: { | |||
|     getDataVaIop() { | |||
|       this.$http.get('/patient/view/getShiLiAndYanyaData', { params: { patientIdNumber: this.patientIdNumber }}) | |||
|         .then(({ data: res }) => { | |||
|           this.dataVaIop = res.data | |||
|         }) | |||
|     }, | |||
|     kpiChangeHandle(itemList) { | |||
|       this.kpiSelectItemList = itemList | |||
|     }, | |||
|     getKPIValue(item) { | |||
|       this.$http.get('/patient/view/kpiData', { | |||
|         params: { | |||
|           kpiId: item.value, | |||
|           patientIdNumber: this.patientIdNumber | |||
|         } | |||
|       }).then(({ data: res }) => { | |||
|         this.kpiValEchartsList.push({ | |||
|           id: item.value, | |||
|           label: item.label, | |||
|           data: res.data | |||
|         }) | |||
|       }) | |||
|     }, | |||
|     resize() { | |||
|       this.$refs.chartIOP.resize() | |||
|       this.$refs.chartVA.resize() | |||
|       if (Array.isArray(this.$refs.chartKPI)) { | |||
|         this.$refs.chartKPI.forEach(el => { | |||
|           el.resize() | |||
|         }) | |||
|       } | |||
|     } | |||
|   } | |||
| } | |||
| </script> | |||
| 
 | |||
| <style lang="scss" scoped> | |||
| .kpi-select { | |||
|   width: calc(100% - 40px); | |||
|   padding-left: 20px; | |||
| } | |||
| 
 | |||
| .echart-kpi { | |||
|   width: 100%; | |||
|   margin-top: 10px; | |||
| } | |||
| </style> | |||
| @ -0,0 +1,99 @@ | |||
| <template> | |||
|   <div class="component-wrapper"> | |||
|     <el-table | |||
|       ref="dataList" | |||
|       v-loading="dataListLoading" | |||
|       highlight-current-row | |||
|       height="100%" | |||
|       :data="dataList" | |||
|       border | |||
|       :row-class-name="'row-1'" | |||
|     > | |||
|       <el-table-column type="expand" :label="'展开'" width="50px"> | |||
|         <template slot-scope="scope"> | |||
|           <el-table :data="scope.row.data"> | |||
|             <el-table-column prop="OP_TIME" :label="'开药时间'" width="155px"> | |||
|               <template slot-scope="scope2"> | |||
|                 <div v-html="scope2.row.OP_TIME" /> | |||
|               </template> | |||
|             </el-table-column> | |||
|             <el-table-column prop="MED_NAME" :label="'药品(商品名)'"> | |||
|               <template slot-scope="scope2"> | |||
|                 <div v-html="scope2.row.MED_NAME" /> | |||
|               </template> | |||
|             </el-table-column> | |||
|             <el-table-column prop="SOC_NAME" :label="'药品(通用名)'" show-overflow-tooltip> | |||
|               <template slot-scope="scope2"> | |||
|                 <div v-html="scope2.row.SOC_NAME" /> | |||
|               </template> | |||
|             </el-table-column> | |||
|             <el-table-column prop="NUMBER_USE" :label="'用药数量'"> | |||
|               <template slot-scope="scope2"> | |||
|                 <div v-html="scope2.row.NUMBER_USE" /> | |||
|               </template> | |||
|             </el-table-column> | |||
|             <el-table-column prop="SITE" :label="'用药部位'"> | |||
|               <template slot-scope="scope2"> | |||
|                 <div v-html="scope2.row.SITE" /> | |||
|               </template> | |||
|             </el-table-column> | |||
|             <el-table-column prop="FREQUENCY" :label="'给药频率'"> | |||
|               <template slot-scope="scope2"> | |||
|                 <div v-html="scope2.row.FREQUENCY" /> | |||
|               </template> | |||
|             </el-table-column> | |||
|             <el-table-column prop="ITEM_TYPE" :label="'门诊/住院'"> | |||
|               <template slot-scope="scope2"> | |||
|                 <div v-html="scope2.row.ITEM_TYPE" /> | |||
|               </template> | |||
|             </el-table-column> | |||
|           </el-table> | |||
|         </template> | |||
|       </el-table-column> | |||
|       <el-table-column prop="opDate" :label="'日期'" width="120px" header-align="center" align="center" /> | |||
|       <el-table-column prop="opContent" :label="'主要内容(商品名)'" show-overflow-tooltip> | |||
|         <template slot="header" slot-scope="{}"> | |||
|           <div class="header-wrapper"> | |||
|             <span>主要内容(商品名)</span> | |||
|             <el-input v-model="searchKeyWord" class="header-search" size="mini" placeholder="关键词" @keyup.enter.native="searchNext"> | |||
|               <span slot="suffix" class="search-result"> | |||
|                 {{ ((searchIndex==-1)?0:(searchIndex+1))+'/'+searchResult.length }} | |||
|               </span> | |||
|               <i slot="suffix" class="el-input__icon el-icon-arrow-down" title="下一个" @click="searchNext" /> | |||
|               <i slot="suffix" class="el-input__icon el-icon-arrow-up" title="上一个" @click="searchLast" /> | |||
|               <i slot="suffix" class="el-input__icon el-icon-refresh" title="重置" @click="searchReset" /> | |||
|             </el-input> | |||
|           </div> | |||
|         </template> | |||
|       </el-table-column> | |||
|     </el-table> | |||
|   </div> | |||
| </template> | |||
| 
 | |||
| <script> | |||
| import myMixin from './_mixin' | |||
| 
 | |||
| export default { | |||
|   mixins: [myMixin], | |||
|   data() { | |||
|     return { | |||
|       type: '用药', | |||
|       searchColumn: [ | |||
|         'OP_TIME', | |||
|         'MED_NAME', | |||
|         'SOC_NAME', | |||
|         'NUMBER_USE', | |||
|         'SITE', | |||
|         'FREQUENCY', | |||
|         'ITEM_TYPE' | |||
|       ] | |||
|     } | |||
|   } | |||
| } | |||
| </script> | |||
| 
 | |||
| <style lang="scss" scoped> | |||
| // .component-wrapper{ | |||
| //   height: auto !important; | |||
| // } | |||
| </style> | |||
| @ -0,0 +1,87 @@ | |||
| <template> | |||
|   <div class="component-wrapper"> | |||
|     <el-table | |||
|       ref="dataList" | |||
|       v-loading="dataListLoading" | |||
|       highlight-current-row | |||
|       height="100%" | |||
|       :data="dataList" | |||
|       border | |||
|       :row-class-name="'row-1'" | |||
|     > | |||
|       <el-table-column type="expand" :label="'展开'" width="50px"> | |||
|         <template slot-scope="scope"> | |||
|           <el-table :data="scope.row.data"> | |||
|             <el-table-column prop="OP_TIME" :label="'手术时间'" width="155px"> | |||
|               <template slot-scope="scope2"> | |||
|                 <div v-html="scope2.row.OP_TIME" /> | |||
|               </template> | |||
|             </el-table-column> | |||
|             <el-table-column prop="OP_NAME" :label="'手术名称'"> | |||
|               <template slot-scope="scope2"> | |||
|                 <div v-html="scope2.row.OP_NAME" /> | |||
|               </template> | |||
|             </el-table-column> | |||
|             <el-table-column prop="OP_PART_NAME" :label="'手术部位'"> | |||
|               <template slot-scope="scope2"> | |||
|                 <div v-html="scope2.row.OP_PART_NAME" /> | |||
|               </template> | |||
|             </el-table-column> | |||
|             <el-table-column prop="MAIN_DR_NAME" :label="'主刀医生'"> | |||
|               <template slot-scope="scope2"> | |||
|                 <div v-html="scope2.row.MAIN_DR_NAME" /> | |||
|               </template> | |||
|             </el-table-column> | |||
|             <el-table-column prop="DEPT_NAME" :label="'部门'"> | |||
|               <template slot-scope="scope2"> | |||
|                 <div v-html="scope2.row.DEPT_NAME" /> | |||
|               </template> | |||
|             </el-table-column> | |||
|             <el-table-column prop="WARD_NAME" :label="'病区'"> | |||
|               <template slot-scope="scope2"> | |||
|                 <div v-html="scope2.row.WARD_NAME" /> | |||
|               </template> | |||
|             </el-table-column> | |||
|           </el-table> | |||
|         </template> | |||
|       </el-table-column> | |||
|       <el-table-column prop="opDate" :label="'日期'" width="120px" header-align="center" align="center" /> | |||
|       <el-table-column prop="opContent" :label="'主要内容(手术)'" show-overflow-tooltip> | |||
|         <template slot="header" slot-scope="{}"> | |||
|           <div class="header-wrapper"> | |||
|             <span>主要内容(手术)</span> | |||
|             <el-input v-model="searchKeyWord" class="header-search" size="mini" placeholder="关键词" @keyup.enter.native="searchNext"> | |||
|               <span slot="suffix" class="search-result"> | |||
|                 {{ ((searchIndex==-1)?0:(searchIndex+1))+'/'+searchResult.length }} | |||
|               </span> | |||
|               <i slot="suffix" class="el-input__icon el-icon-arrow-down" title="下一个" @click="searchNext" /> | |||
|               <i slot="suffix" class="el-input__icon el-icon-arrow-up" title="上一个" @click="searchLast" /> | |||
|               <i slot="suffix" class="el-input__icon el-icon-refresh" title="重置" @click="searchReset" /> | |||
|             </el-input> | |||
|           </div> | |||
|         </template> | |||
|       </el-table-column> | |||
|     </el-table> | |||
|   </div> | |||
| </template> | |||
| 
 | |||
| <script> | |||
| import myMixin from './_mixin' | |||
| 
 | |||
| export default { | |||
|   mixins: [myMixin], | |||
|   data() { | |||
|     return { | |||
|       type: '手术', | |||
|       searchColumn: [ | |||
|         'OP_TIME', | |||
|         'OP_NAME', | |||
|         'OP_PART_NAME', | |||
|         'MAIN_DR_NAME', | |||
|         'DEPT_NAME', | |||
|         'WARD_NAME' | |||
|       ] | |||
|     } | |||
|   } | |||
| } | |||
| </script> | |||
| @ -0,0 +1,55 @@ | |||
| <template> | |||
|   <div class="component-wrapper"> | |||
|     <el-table | |||
|       ref="dataList" | |||
|       v-loading="dataListLoading" | |||
|       highlight-current-row | |||
|       height="100%" | |||
|       :data="dataList" | |||
|       border | |||
|       :row-class-name="'row-1'" | |||
|     > | |||
|       <el-table-column prop="EXAM_TIME" :label="'检查时间'" width="160px" /> | |||
|       <el-table-column prop="EXAM_TYPE" :label="'验光类型'" width="120px" header-align="center" align="center" /> | |||
|       <el-table-column :label="'OD'" header-align="center"> | |||
|         <el-table-column prop="OD_SPH" label="球镜" header-align="center" align="center" /> | |||
|         <el-table-column prop="OD_CYL" label="柱镜" header-align="center" align="center" /> | |||
|         <el-table-column prop="OD_AX" label="轴向" header-align="center" align="center" /> | |||
|         <el-table-column prop="OD_SE" label="等效球镜" header-align="center" align="center" /> | |||
|         <el-table-column prop="OD_VA" label="矫正视力" header-align="center" align="center" /> | |||
|         <el-table-column prop="OD_VD" label="顶点距" header-align="center" align="center" /> | |||
|         <el-table-column prop="OD_PS" label="瞳孔大小" header-align="center" align="center" /> | |||
|         <el-table-column prop="S_OD_MEMO" label="备注" /> | |||
|       </el-table-column> | |||
|       <el-table-column :label="'OS'" header-align="center"> | |||
|         <el-table-column prop="OS_SPH" label="球镜" header-align="center" align="center" /> | |||
|         <el-table-column prop="OS_CYL" label="柱镜" header-align="center" align="center" /> | |||
|         <el-table-column prop="OS_AX" label="轴向" header-align="center" align="center" /> | |||
|         <el-table-column prop="OS_SE" label="等效球镜" header-align="center" align="center" /> | |||
|         <el-table-column prop="OS_VA" label="矫正视力" header-align="center" align="center" /> | |||
|         <el-table-column prop="OS_VD" label="顶点距" header-align="center" align="center" /> | |||
|         <el-table-column prop="OS_PS" label="瞳孔大小" header-align="center" align="center" /> | |||
|         <el-table-column prop="S_OS_MEMO" label="备注" /> | |||
|       </el-table-column> | |||
|     </el-table> | |||
|   </div> | |||
| </template> | |||
| 
 | |||
| <script> | |||
| import myMixin from './_mixin' | |||
| 
 | |||
| export default { | |||
|   mixins: [myMixin], | |||
|   data() { | |||
|     return { | |||
|       type: '验光' | |||
|     } | |||
|   } | |||
| } | |||
| </script> | |||
| 
 | |||
| <style lang="scss" scoped> | |||
| // .component-wrapper{ | |||
| //   height: auto !important; | |||
| // } | |||
| </style> | |||
| @ -0,0 +1,40 @@ | |||
| <template> | |||
|   <div class="component-wrapper"> | |||
|     <el-table | |||
|       ref="dataList" | |||
|       v-loading="dataListLoading" | |||
|       highlight-current-row | |||
|       height="100%" | |||
|       :data="dataList" | |||
|       border | |||
|       :row-class-name="'row-1'" | |||
|     > | |||
|       <el-table-column prop="EXAM_TIME" :label="'检查时间'" width="155px" /> | |||
|       <el-table-column prop="EXAM_TYPE" :label="'数据来源'" width="150px" /> | |||
|       <el-table-column prop="S_OD_VAN" :label="'OD(裸眼)'" /> | |||
|       <el-table-column prop="S_OS_VAN" :label="'OS(裸眼)'" /> | |||
|       <el-table-column prop="S_OD_VAG" :label="'OD(矫正)'" /> | |||
|       <el-table-column prop="S_OS_VAG" :label="'OS(矫正)'" /> | |||
|       <el-table-column prop="EXAM_MEMO" :label="'备注'" show-overflow-tooltip /> | |||
|     </el-table> | |||
|   </div> | |||
| </template> | |||
| 
 | |||
| <script> | |||
| import myMixin from './_mixin' | |||
| 
 | |||
| export default { | |||
|   mixins: [myMixin], | |||
|   data() { | |||
|     return { | |||
|       type: '视力' | |||
|     } | |||
|   } | |||
| } | |||
| </script> | |||
| 
 | |||
| <style lang="scss" scoped> | |||
| // .component-wrapper{ | |||
| //   height: auto !important; | |||
| // } | |||
| </style> | |||
| @ -0,0 +1,629 @@ | |||
| <template> | |||
|   <el-container class="component-wrapper"> | |||
|     <!-- 时间轴 --> | |||
|     <el-aside class="time-line-wrapper" width="250px"> | |||
|       <!-- 检索 --> | |||
|       <div class="toolbar-wrapper"> | |||
|         <el-input v-model="filterText" size="mini" placeholder="快速检索" class="filter-input" /> | |||
|         <el-dropdown size="medium" class="tree-set"> | |||
|           <i class="el-icon-set-up icon-dropdown" /> | |||
|           <el-dropdown-menu slot="dropdown"> | |||
|             <el-dropdown-item @click.native="expandAll(true)">全部展开</el-dropdown-item> | |||
|             <el-dropdown-item @click.native="expandAll(false)">全部折叠</el-dropdown-item> | |||
|           </el-dropdown-menu> | |||
|         </el-dropdown> | |||
|       </div> | |||
|       <div v-loading="treeLoading" class="tree-wrapper"> | |||
|         <el-tree | |||
|           ref="tree" | |||
|           class="filter-tree" | |||
|           :data="treeData" | |||
|           :props="treeSet" | |||
|           :expand-on-click-node="true" | |||
|           default-expand-all | |||
|           :filter-node-method="filterNode" | |||
|         > | |||
|           <span slot-scope="{ node, data }" class="custom-tree-node"> | |||
|             <!-- 日期节点 --> | |||
|             <template v-if="data.children"> | |||
|               <span>{{ data.label }}</span> | |||
|             </template> | |||
|             <!-- 叶子节点 --> | |||
|             <template v-else> | |||
|               <template v-if="data.opContent"> | |||
|                 <el-tooltip effect="dark" :content="data.opContent" placement="bottom-end"> | |||
|                   <el-tag size="mini" @click="treeNodeTagClickHandle(data)">{{ data.label }}</el-tag> | |||
|                 </el-tooltip> | |||
|               </template> | |||
|               <template v-else> | |||
|                 <el-tag size="mini" @click="treeNodeTagClickHandle(data)">{{ data.label }}</el-tag> | |||
|               </template> | |||
|             </template> | |||
|           </span> | |||
|         </el-tree> | |||
|       </div> | |||
|     </el-aside> | |||
| 
 | |||
|     <el-container class="info-wrapper"> | |||
|       <!-- 信息 --> | |||
|       <el-header class="patient-info-wrapper" :height="isSubject&&patientInfo.visitInfo?'200px':'145px'"> | |||
|         <el-descriptions v-loading="infoLoading" :title="patientInfo.patientName||''" :column="3" border> | |||
|           <template slot="title"> | |||
|             {{ patientInfo.patientName||'' }} | |||
|             <i :class="sexClass" class="icon-sex" /> | |||
|             <!-- <el-button size="mini" icon="el-icon-refresh" title="刷新" @click="refresh" /> | |||
|             <el-button size="mini" icon="el-icon-refresh" title="刷新" @click="refresh" /> --> | |||
|           </template> | |||
| 
 | |||
|           <template slot="extra"> | |||
|             <!-- 收藏 --> | |||
|             <el-button | |||
|               size="mini" | |||
|               :icon="isCollected?'el-icon-star-on':'el-icon-star-off'" | |||
|               :title="isCollected?'已收藏':'收藏'" | |||
|               :class="[isCollected?'isCollected':'']" | |||
|               @click="collect" | |||
|             /> | |||
|             <!-- 全屏 --> | |||
|             <el-button size="mini" icon="el-icon-full-screen" title="全屏切换" @click="fullscreenHandle" /> | |||
|             <!-- 刷新 --> | |||
|             <el-button size="mini" icon="el-icon-refresh" title="刷新" @click="refresh" /> | |||
|             <!-- 其他按钮 --> | |||
|             <template v-if="isSubject&&projectId"> | |||
|               <el-button type="primary" size="mini" icon="el-icon-edit" @click="btnEcrfClick">表单</el-button> | |||
|               <el-button type="primary" size="mini" icon="el-icon-setting" @click="btnFollowUpClick">随访</el-button> | |||
|             </template> | |||
|           </template> | |||
| 
 | |||
|           <el-descriptions-item> | |||
|             <template slot="label"> | |||
|               <i class="el-icon-user" /> | |||
|               身份证号 | |||
|             </template> | |||
|             {{ patientInfo.patientIdNumber | f_desensitize_idNumber }} | |||
|           </el-descriptions-item> | |||
|           <el-descriptions-item> | |||
|             <template slot="label"> | |||
|               <svg-icon icon-class="icon-birthday" /> | |||
|               当前年龄 | |||
|             </template> | |||
|             {{ patientInfo.birthday | f_getAge }} | |||
|           </el-descriptions-item> | |||
|           <el-descriptions-item> | |||
|             <template slot="label"> | |||
|               <i class="el-icon-mobile-phone" /> | |||
|               联系电话 | |||
|             </template> | |||
|             <span style="display: inline-block;width: 100px;">{{ patientTel }} </span> | |||
|             <template v-if="isSubject"> | |||
|               <svg-icon :icon-class="viewTel?'icon-visible':'icon-disvisible'" @click="viewTel = !viewTel" /> | |||
|             </template> | |||
|           </el-descriptions-item> | |||
| 
 | |||
|           <!-- 随访信息 --> | |||
|           <template v-if="isSubject&&patientInfo.visitInfo"> | |||
|             <el-descriptions-item> | |||
|               <template slot="label"> | |||
|                 <i class="el-icon-tickets" /> | |||
|                 随访方案 | |||
|               </template> | |||
|               {{ patientInfo.visitInfo.visitName }} | |||
|             </el-descriptions-item> | |||
|             <el-descriptions-item> | |||
|               <template slot="label"> | |||
|                 <i class="el-icon-time" /> | |||
|                 最近到访 | |||
|               </template> | |||
|               {{ patientInfo.visitInfo.lastDate | dateFilterTwo }} | |||
|             </el-descriptions-item> | |||
|             <el-descriptions-item> | |||
|               <template slot="label"> | |||
|                 <i class="el-icon-time" /> | |||
|                 下次到访 | |||
|               </template> | |||
|               {{ patientInfo.visitInfo.planDate | dateFilterTwo }} | |||
|             </el-descriptions-item> | |||
|           </template> | |||
| 
 | |||
|           <el-descriptions-item> | |||
|             <template slot="label"> | |||
|               <i class="el-icon-office-building" /> | |||
|               联系地址 | |||
|             </template> | |||
|             {{ patientInfo.address | f_desensitize_address }} | |||
|           </el-descriptions-item> | |||
|         </el-descriptions> | |||
|       </el-header> | |||
| 
 | |||
|       <!-- 展示面板 --> | |||
|       <el-main class="view-wrapper"> | |||
|         <el-tabs ref="tabs" v-model="tabActiveName" class="tabs-wrapper" type="border-card" @tab-click="tabClickHandle"> | |||
|           <el-tab-pane label="诊断" name="诊断"> | |||
|             <diagnose ref="diagnose" :style="{height:tabBodyHeight}" :patient-id-number="patientIdNumber" /> | |||
|           </el-tab-pane> | |||
|           <el-tab-pane label="手术" name="手术"> | |||
|             <operation ref="operation" :style="{height:tabBodyHeight}" :patient-id-number="patientIdNumber" /> | |||
|           </el-tab-pane> | |||
|           <el-tab-pane label="用药" name="用药"> | |||
|             <medication ref="medication" :style="{height:tabBodyHeight}" :patient-id-number="patientIdNumber" /> | |||
|           </el-tab-pane> | |||
|           <el-tab-pane label="检查项目" name="检查项目"> | |||
|             <exam-item ref="examItem" :style="{height:tabBodyHeight}" :patient-id-number="patientIdNumber" /> | |||
|           </el-tab-pane> | |||
|           <el-tab-pane label="门诊" name="门诊"> | |||
|             <emr-treatments ref="emrTreatments" :style="{height:tabBodyHeight}" :patient-id-number="patientIdNumber" /> | |||
|           </el-tab-pane> | |||
|           <el-tab-pane label="住院" name="住院"> | |||
|             <inhospital | |||
|               ref="inhospital" | |||
|               :style="{height:tabBodyHeight}" | |||
|               :date-type="inhospitalType" | |||
|               :patient-id-number="patientIdNumber" | |||
|             /> | |||
|           </el-tab-pane> | |||
|           <el-tab-pane label="视力" name="视力"> | |||
|             <va ref="va" :style="{height:tabBodyHeight}" :patient-id-number="patientIdNumber" /> | |||
|           </el-tab-pane> | |||
|           <el-tab-pane label="眼压" name="眼压"> | |||
|             <iop ref="iop" :style="{height:tabBodyHeight}" :patient-id-number="patientIdNumber" /> | |||
|           </el-tab-pane> | |||
|           <el-tab-pane label="验光" name="验光"> | |||
|             <ref ref="ref" :style="{height:tabBodyHeight}" :patient-id-number="patientIdNumber" /> | |||
|           </el-tab-pane> | |||
|           <el-tab-pane v-if="projectId" label="表单" name="表单"> | |||
|             <ecrf | |||
|               ref="ecrf" | |||
|               :style="{height:tabBodyHeight}" | |||
|               :patient-id-number="patientIdNumber" | |||
|               :project-id="projectId" | |||
|               @refresh="refreshDataEcrf" | |||
|             /> | |||
|           </el-tab-pane> | |||
|           <el-tab-pane label="单项数据" name="单项数据"> | |||
|             <kpi ref="kpi" :style="{height:tabBodyHeight}" :patient-id-number="patientIdNumber" /> | |||
|           </el-tab-pane> | |||
|         </el-tabs> | |||
|       </el-main> | |||
|     </el-container> | |||
| 
 | |||
|     <!-- 弹窗--随访表单 --> | |||
|     <ecrf-select | |||
|       v-if="crfSelectVisible" | |||
|       ref="goCrfSelect" | |||
|       :patient-id-number="patientIdNumber" | |||
|       @refreshData="refreshDataEcrf" | |||
|     /> | |||
|     <set-followup | |||
|       v-if="setFollowUpVisible" | |||
|       ref="goFollowUp" | |||
|       :patient-id-number="patientIdNumber" | |||
|       @refreshData="refreshInfo" | |||
|     /> | |||
| 
 | |||
|   </el-container> | |||
| </template> | |||
| 
 | |||
| <script> | |||
| import fullscreen from '@/mixins/full-screen' | |||
| import { isMobile } from '@/utils/validate.js' | |||
| import { groupBy } from '@/utils/tree.js' | |||
| import diagnose from './detail/diagnose.vue' | |||
| import operation from './detail/operation.vue' | |||
| import medication from './detail/medication.vue' | |||
| import examItem from './detail/exam-item.vue' | |||
| import inhospital from './detail/inhospital.vue' | |||
| import va from './detail/va.vue' | |||
| import iop from './detail/iop.vue' | |||
| import ref from './detail/ref.vue' | |||
| import ecrf from './detail/ecrf.vue' | |||
| import kpi from './detail/kpi.vue' | |||
| import emrTreatments from './detail/emr-treatments.vue' | |||
| import ecrfSelect from '@/components/ecrf/ecrf-select.vue' | |||
| import setFollowup from './set-followup.vue' | |||
| 
 | |||
| export default { | |||
|   components: { | |||
|     diagnose, | |||
|     operation, | |||
|     medication, | |||
|     examItem, | |||
|     inhospital, | |||
|     emrTreatments, | |||
|     va, | |||
|     iop, | |||
|     ref, | |||
|     kpi, | |||
|     ecrf, | |||
| 
 | |||
|     ecrfSelect, | |||
|     setFollowup | |||
|   }, | |||
|   mixins: [fullscreen], | |||
|   props: { | |||
|     patientIdNumber: { type: String, required: true }, | |||
|     projectId: { type: String, default: '' }, | |||
|     isSubject: { type: Boolean, default: false } | |||
|   }, | |||
|   data() { | |||
|     return { | |||
|       isCollected: false, | |||
|       treeLoading: false, | |||
|       infoLoading: false, | |||
|       treeSet: { | |||
|         children: 'children', | |||
|         label: 'label' | |||
|       }, | |||
|       timeLineData: [], | |||
|       filterText: '', | |||
|       treeData: [], | |||
| 
 | |||
|       patientInfo: {}, | |||
|       tabActiveName: '诊断', | |||
|       tabBodyHeight: '500px', | |||
|       inhospitalType: 'in', | |||
| 
 | |||
|       crfSelectVisible: false, | |||
|       setFollowUpVisible: false, | |||
| 
 | |||
|       viewTel: false | |||
|     } | |||
|   }, | |||
|   computed: { | |||
|     sexClass() { | |||
|       if (this.patientInfo.sex) { | |||
|         return { | |||
|           'el-icon-female female': this.patientInfo.sex.indexOf('女') >= 0, | |||
|           'el-icon-male male': this.patientInfo.sex.indexOf('男') >= 0 | |||
|         } | |||
|       } else { | |||
|         return { 'el-icon-user': true } | |||
|       } | |||
|     }, | |||
|     patientTel() { | |||
|       if (this.viewTel) { | |||
|         return this.patientInfo.tel | |||
|       } | |||
|       if (this.patientInfo.tel && isMobile(this.patientInfo.tel)) { | |||
|         return this.$options.filters['f_desensitize_phone'](this.patientInfo.tel) | |||
|       } else { return this.patientInfo.tel } | |||
|     } | |||
|   }, | |||
|   watch: { | |||
|     filterText(val) { | |||
|       this.$refs.tree.filter(val) | |||
|     } | |||
|   }, | |||
|   created() { | |||
|     this.getPatientInfo() | |||
|     this.getTimeLine() | |||
|   }, | |||
|   mounted() { | |||
|     const elTabsBody = this.$refs.tabs.$el.querySelector('.el-tabs__content') | |||
|     this.tabBodyHeight = (elTabsBody.clientHeight - 30) + 'px' | |||
|   }, | |||
|   methods: { | |||
|     hasCollected() { | |||
|       this.$http.get('/collect/patient/judgeExist', { params: { patientIdNumber: this.patientIdNumber }}).then(({ data: res }) => { | |||
|         // eslint-disable-next-line no-eval | |||
|         this.isCollected = eval(res.data) | |||
|       }) | |||
|     }, | |||
|     collect() { | |||
|       if (!this.isCollected) { | |||
|         // 新增 | |||
|         this.$http.post('/collect/patient', { patientIdNumber: this.patientIdNumber }).then(({ data: res }) => { | |||
|           this.isCollected = true | |||
|         }) | |||
|       } else { | |||
|         // 删除 | |||
|         this.$http.delete('/collect/patient', { data: [this.patientIdNumber] }).then(({ data: res }) => { | |||
|           this.isCollected = false | |||
|         }) | |||
|       } | |||
|     }, | |||
|     refreshInfo() { | |||
|       this.getPatientInfo() | |||
|       this.getTimeLine() | |||
|     }, | |||
|     refreshDataEcrf() { | |||
|       this.crfSelectVisible = false | |||
|       this.tabActiveName = '表单' | |||
|       this.$refs.ecrf.getDataList('表单') | |||
|       this.getTimeLine() | |||
|     }, | |||
|     refresh() { | |||
|       this.getPatientInfo() | |||
|       this.getTimeLine() | |||
|       this.tabActiveName = '诊断' | |||
|       this.$refs.diagnose.refreshData() | |||
|       this.$refs.operation.refreshData() | |||
|       this.$refs.medication.refreshData() | |||
|       this.$refs.examItem.refreshData() | |||
|       this.$refs.emrTreatments.refreshData() | |||
|       this.$refs.inhospital.refreshData() | |||
|       this.$refs.va.refreshData() | |||
|       this.$refs.iop.refreshData() | |||
|       this.$refs.ref.refreshData() | |||
|       if (this.$refs.ecrf) { this.$refs.ecrf.refreshData() } | |||
|     }, | |||
|     getPatientInfo() { | |||
|       this.infoLoading = true | |||
|       this.$http.get('/patient/view/patInfo', { | |||
|         params: { | |||
|           patientIdNumber: this.patientIdNumber, | |||
|           projectId: this.projectId ? this.projectId : null | |||
|         } | |||
|       }).then(({ data: res }) => { | |||
|         this.patientInfo = res.data || {} | |||
|         this.infoLoading = false | |||
|       }).catch(() => { this.infoLoading = false }) | |||
| 
 | |||
|       this.hasCollected() | |||
|     }, | |||
|     getTimeLine() { | |||
|       this.treeLoading = true | |||
|       this.$http.get('/patient/view/timeline', { | |||
|         params: { | |||
|           patientIdNumber: this.patientIdNumber, | |||
|           projectId: this.projectId ? this.projectId : null | |||
|         } | |||
|       }).then(({ data: res }) => { | |||
|         this.timeLineData = res.data | |||
|         this.treeData = groupBy(this.timeLineData, 'opDate', 'groupName') | |||
|         // this.$nextTick(() => {console.log(this.$refs.tree.$children) }) | |||
|         this.treeLoading = false | |||
|       }).catch(() => { this.treeLoading = false }) | |||
|     }, | |||
|     filterNode(value, data, node) { | |||
|       // value-过滤词 | |||
|       // data -节点数据 | |||
|       // node -节点 | |||
|       if (!value) return true | |||
|       this.expandAll(true) | |||
|       value = value.toUpperCase() | |||
|       return data.label.toUpperCase().indexOf(value) !== -1 || (data.opContent && data.opContent.toUpperCase().indexOf(value) !== -1) | |||
|     }, | |||
|     expandAll(isExpandAll) { | |||
|       this.$refs.tree.$children.forEach(item => { | |||
|         item.expanded = isExpandAll | |||
|       }) | |||
|     }, | |||
|     tabClickHandle(tab, event) { | |||
|       if (tab.name === '单项数据') { | |||
|         this.$refs.kpi.resize() | |||
|       } | |||
|     }, | |||
|     treeNodeTagClickHandle(nodeData) { | |||
|       switch (nodeData.label) { | |||
|         case '诊断': | |||
|           this.tabActiveName = '诊断' | |||
|           this.$refs.diagnose.setIndexDate(nodeData.opDate) | |||
|           break | |||
|         case '手术': | |||
|           this.tabActiveName = '手术' | |||
|           this.$refs.operation.setIndexDate(nodeData.opDate) | |||
|           break | |||
|         case '用药': | |||
|           this.tabActiveName = '用药' | |||
|           this.$refs.medication.setIndexDate(nodeData.opDate) | |||
|           break | |||
|         case '检查': | |||
|           this.tabActiveName = '检查项目' | |||
|           this.$refs.examItem.setIndexDate(nodeData.opDate) | |||
|           break | |||
|         case '门诊': | |||
|           this.tabActiveName = '门诊' | |||
|           this.$refs.emrTreatments.setIndexDate(nodeData.opDate) | |||
|           break | |||
|         case '住院': | |||
|           this.tabActiveName = '住院' | |||
|           this.inhospitalType = 'in' | |||
|           this.$refs.inhospital.setIndexDate(nodeData.opDate) | |||
|           break | |||
|         case '出院': | |||
|           this.tabActiveName = '住院' | |||
|           this.inhospitalType = 'out' | |||
|           this.$refs.inhospital.setIndexDate(nodeData.opDate) | |||
|           break | |||
|         case '视力': | |||
|           this.tabActiveName = '视力' | |||
|           this.$refs.va.setIndexDate(nodeData.opDate) | |||
|           break | |||
|         case '眼压': | |||
|           this.tabActiveName = '眼压' | |||
|           this.$refs.iop.setIndexDate(nodeData.opDate) | |||
|           break | |||
|         case '验光': | |||
|           this.tabActiveName = '验光' | |||
|           this.$refs.ref.setIndexDate(nodeData.opDate) | |||
|           break | |||
|         case '表单': | |||
|           this.tabActiveName = '表单' | |||
|           this.$refs.ecrf.setIndexDate(nodeData.opDate) | |||
|           break | |||
|         default: | |||
|           this.tabActiveName = '诊断' | |||
|           this.$refs.diagnose.setIndexDate(nodeData.opDate) | |||
|           break | |||
|       } | |||
|     }, | |||
|     // 表单 | |||
|     btnEcrfClick() { | |||
|       this.crfSelectVisible = true | |||
|       this.$nextTick(() => { | |||
|         this.$refs.goCrfSelect.init() | |||
|       }) | |||
|     }, | |||
|     // 随访方案 | |||
|     btnFollowUpClick() { | |||
|       this.setFollowUpVisible = true | |||
|       this.$nextTick(() => { | |||
|         this.$refs.goFollowUp.init() | |||
|       }) | |||
|     } | |||
| 
 | |||
|   } | |||
| 
 | |||
| } | |||
| </script> | |||
| 
 | |||
| <style lang="scss" scoped> | |||
| .component-wrapper { | |||
|   width: 100%; | |||
|   height: calc(100vh - 65px); | |||
| } | |||
| 
 | |||
| // 时间轴 | |||
| .time-line-wrapper { | |||
|   .toolbar-wrapper { | |||
|     height: 40px; | |||
|     .filter-input { | |||
|       padding: 5px; | |||
|       width: 200px; | |||
|     } | |||
| 
 | |||
|     .tree-set { | |||
|       vertical-align: middle; | |||
| 
 | |||
|       .icon-dropdown { | |||
|         margin-left: 10px; | |||
|         font-size: 20px; | |||
|       } | |||
|     } | |||
|   } | |||
|   // 树形时间轴 | |||
|   .tree-wrapper { | |||
|     height: calc(100% - 40px); | |||
|     padding-top: 5px; | |||
|     overflow: auto; | |||
| 
 | |||
|     border: 1px solid #ebeef5; | |||
|     background: #fff; | |||
|   } | |||
| } | |||
| 
 | |||
| // 信息 | |||
| .info-wrapper { | |||
|   padding-left: 10px; | |||
| 
 | |||
|   // 患者信息 | |||
|   .patient-info-wrapper { | |||
|     padding: 5px 0 0; | |||
| 
 | |||
|     .icon-sex { | |||
|       font-size: 16px; | |||
|     } | |||
| 
 | |||
|     .female { | |||
|       color: #f8667f; | |||
|     } | |||
| 
 | |||
|     .male { | |||
|       color: #4550f3; | |||
|     } | |||
| 
 | |||
|     ::v-deep .el-descriptions__header { | |||
|       margin-bottom: 8px; | |||
|       // margin-top: 5px; | |||
|       padding-left: 5px; | |||
| 
 | |||
|       .el-descriptions__title { | |||
|         font-size: 20px; | |||
|         font-weight: bolder; | |||
|         color: #767a82; | |||
|       } | |||
|     } | |||
|   } | |||
| 
 | |||
|   // 展示面板 | |||
|   .view-wrapper { | |||
|     // background: #c4e93f; | |||
|     padding: 0; | |||
| 
 | |||
|     .tabs-wrapper { | |||
|       height: 100%; | |||
|       overflow: hidden; | |||
| 
 | |||
|       // ::v-deep .el-tabs__header{ | |||
|       //   height: 39px; | |||
|       // } | |||
| 
 | |||
|       ::v-deep .el-tabs__content { | |||
|         height: calc(100% - 39px); | |||
|         overflow: auto; | |||
|       } | |||
|     } | |||
|   } | |||
| } | |||
| 
 | |||
| .filter-tree { | |||
|   padding-right: 20px; | |||
| 
 | |||
|   // 日期节点 | |||
|   > ::v-deep .el-tree-node > .el-tree-node__content { | |||
|     font-weight: 700; | |||
|   } | |||
|   // children节点容器 | |||
|   > ::v-deep .el-tree-node > .el-tree-node__children { | |||
|     white-space: normal; | |||
|     padding-left: 20px; | |||
| 
 | |||
|     // (子)节点容器 | |||
|     > .el-tree-node { | |||
|       display: inline-block; | |||
| 
 | |||
|       // 节点内容 | |||
|       .el-tree-node__content { | |||
|         padding-left: 5px !important; | |||
| 
 | |||
|         .is-leaf { | |||
|           display: none; | |||
|         } | |||
|       } | |||
|     } | |||
|   } | |||
| } | |||
| 
 | |||
| .isCollected { | |||
|   padding: 2px 12px 5px 12px; | |||
|   color: #f1a33c; | |||
|   font-size: 18px; | |||
| } | |||
| </style> | |||
| 
 | |||
| <style lang='scss'> | |||
| .header-wrapper { | |||
|   display: flex; | |||
|   justify-content: space-between; | |||
| 
 | |||
|   .header-search { | |||
|     width: 300px; | |||
|   } | |||
| 
 | |||
|   .el-input__suffix { | |||
|     display: flex; | |||
|     align-items: center; | |||
| 
 | |||
|     .el-input__suffix-inner { | |||
|       .search-result { | |||
|         display: inline-block; | |||
|         padding: 0 10px; | |||
|         border-right: 1px solid #c0c4cc; | |||
|       } | |||
| 
 | |||
|       .el-input__icon { | |||
|         cursor: pointer; | |||
|         width: 20px; | |||
|         border-radius: 20px; | |||
|         line-height: 20px; | |||
|         margin: 4px 2px; | |||
|       } | |||
| 
 | |||
|       .el-input__icon:hover { | |||
|         background: #c0c4cc; | |||
|         color: #fff; | |||
|       } | |||
|     } | |||
|   } | |||
| } | |||
| </style> | |||
| @ -0,0 +1,134 @@ | |||
| <template> | |||
|   <el-dialog title="设置随访方案" :visible.sync="visible" append-to-body> | |||
|     <el-form | |||
|       ref="dataForm" | |||
|       v-loading="loading" | |||
|       :model="dataForm" | |||
|       :rules="dataRule" | |||
|       label-width="120px" | |||
|       @submit.native.prevent | |||
|       @keyup.enter.native="dataFormSubmitHandle()" | |||
|     > | |||
|       <el-form-item label="上次到访日期" prop="lastVisitDate"> | |||
|         <el-date-picker | |||
|           v-model="dataForm.lastVisitDate" | |||
|           type="date" | |||
|           placeholder="请选择日期" | |||
|           format="yyyy-MM-dd" | |||
|           value-format="yyyy-MM-dd" | |||
|           style="width:300px;" | |||
|         /> | |||
|       </el-form-item> | |||
|       <el-form-item label="选择随访方案" prop="visitId"> | |||
|         <el-select v-model="dataForm.visitId" placeholder="请选择随访方案" style="width:300px;"> | |||
|           <el-option v-for="item in options_visit" :key="item.id" :label="item.name" :value="item.id" /> | |||
|         </el-select> | |||
|       </el-form-item> | |||
|       <el-form-item label="备注信息" prop="remark"> | |||
|         <el-input v-model="dataForm.remark" type="textarea" placeholder="请输入变更随访方案的原因" /> | |||
|       </el-form-item> | |||
|     </el-form> | |||
|     <template slot="footer"> | |||
|       <el-button @click="visible = false">{{ $t('cancel') }}</el-button> | |||
|       <el-button type="primary" @click="dataFormSubmitHandle()">{{ $t('confirm') }}</el-button> | |||
|     </template> | |||
|   </el-dialog> | |||
| </template> | |||
| 
 | |||
| <script> | |||
| import debounce from 'lodash/debounce' | |||
| 
 | |||
| export default { | |||
|   props: { | |||
|     patientIdNumber: { type: String, required: true } | |||
|   }, | |||
|   data() { | |||
|     return { | |||
|       loading: false, | |||
|       visible: false, | |||
|       options_visit: [], | |||
|       dataForm: { | |||
|         lastVisitDate: '', | |||
|         visitId: '', | |||
|         remark: '' | |||
|       } | |||
|     } | |||
|   }, | |||
|   computed: { | |||
|     dataRule() { | |||
|     //   const validate_planList = (rule, value, callback) => { | |||
|     //     return (value && value.length > 0) ? callback() : callback(new Error('请填写随访步骤')) | |||
|     //   } | |||
|     //   return { | |||
|     //     name: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }], | |||
|     //     planList: [{ required: true, validator: validate_planList, trigger: 'blur' }] | |||
|     //   } | |||
|       return {} | |||
|     } | |||
|   }, | |||
|   created() { this.getFollowList() }, | |||
|   methods: { | |||
|     init() { | |||
|       this.visible = true | |||
|       this.$nextTick(() => { | |||
|         this.resetDataForm() | |||
|         this.getInfo() | |||
|       }) | |||
|     }, | |||
|     resetDataForm() { | |||
|       this.$refs.dataForm.resetFields() | |||
|     }, | |||
|     // 获取随访方案列表 | |||
|     getFollowList() { | |||
|       this.$http.get('/visit/page', { params: { | |||
|         limit: 1000, | |||
|         page: 1, | |||
|         projectId: window.SITE_CONFIG['projectId'] } | |||
|       }).then(({ data: res }) => { | |||
|         if (res.data) { this.options_visit = res.data.list || [] } | |||
|       }) | |||
|     }, | |||
|     // 获取信息 | |||
|     getInfo() { | |||
|       this.loading = true | |||
|       this.$http.get('/visit/pat', { | |||
|         params: { | |||
|           patientIdNumber: this.patientIdNumber, | |||
|           projectId: window.SITE_CONFIG['projectId'] | |||
|         } | |||
|       }).then(({ data: res }) => { | |||
|         console.log(res.data) | |||
|         this.dataForm = { ...this.dataForm, ...res.data } | |||
|         this.loading = false | |||
|       }).catch(() => { this.loading = false }) | |||
|     }, | |||
|     // 表单提交 | |||
|     dataFormSubmitHandle: debounce(function() { | |||
|       this.$refs.dataForm.validate((valid) => { | |||
|         if (!valid) { return false } | |||
| 
 | |||
|         this.$http.post('/visit/bindPat', | |||
|           { ...this.dataForm, | |||
|             lastDate: this.dataForm.lastVisitDate, | |||
|             projectId: window.SITE_CONFIG['projectId'], | |||
|             patientIdNumber: this.patientIdNumber | |||
|           }).then(({ data: res }) => { | |||
|           this.$message({ | |||
|             message: this.$t('prompt.success'), | |||
|             type: 'success', | |||
|             duration: 500, | |||
|             onClose: () => { | |||
|               this.visible = false | |||
|               this.$emit('refreshData') | |||
|             } | |||
|           }) | |||
|         }) | |||
|       }) | |||
|     }, 1000, { leading: true, trailing: false }) | |||
|   } | |||
| } | |||
| </script> | |||
| 
 | |||
| <style> | |||
| 
 | |||
| </style> | |||
| @ -0,0 +1,16 @@ | |||
| import screenfull from 'screenfull' | |||
| 
 | |||
| export default { | |||
|   methods: { | |||
|     fullscreenHandle() { | |||
|       if (!screenfull.enabled) { | |||
|         return this.$message({ | |||
|           message: this.$t('fullscreen.prompt'), | |||
|           type: 'warning', | |||
|           duration: 500 | |||
|         }) | |||
|       } | |||
|       screenfull.toggle() | |||
|     } | |||
|   } | |||
| } | |||
| @ -1,98 +1,385 @@ | |||
| <template> | |||
|   <div class="first-visit"> | |||
|     <!-- 首诊记录头部 --> | |||
|     <head-template head-left="首诊记录"> | |||
|       <el-tooltip class="item" effect="dark" content="首诊单模板有新版本可点击更新" placement="top"> | |||
|         <el-button v-if="dataForm.isNew==2" type="danger" size="small" @click="updateHandle">更新</el-button> | |||
|       </el-tooltip> | |||
| <!--      <el-button type="primary" size="small" @click="addOrUpdateHandle">填写</el-button>--> | |||
|       <!-- <button v-print="'#printMe'" class="printer">打印</button> --> | |||
|       <button class="printer" @click="printerHandle">打印</button> | |||
|     <head-template> | |||
|       <el-button type="primary" size="small" @click="saveCheckData()">保存</el-button> | |||
|       <el-button v-print="'cornealPrint'" size="small">打印</el-button> | |||
|     </head-template> | |||
|     <p class="tips">如需补充患者首诊记录信息请点击“填写”按钮</p> | |||
|     <!-- 首诊内容 --> | |||
|     <div class="first-visit-content"> | |||
| 
 | |||
|     <div class="notice-content"> | |||
|       <div class="notice-box"> | |||
|         <div id="cornealPrint" class="notice_tip" style="page-break-after:always"> | |||
|           <h2 style="text-align: center;margin-bottom: 32px;"> | |||
|             验配流程 | |||
|           </h2> | |||
|           <div style="float: right"> | |||
|             <span style="word-break: keep-all;font-size: 18px">验配日期</span> | |||
|             <el-date-picker | |||
|               style="width: 220px" | |||
|               v-model="formData.patientCheckDate" | |||
|               type="date" | |||
|             /> | |||
|           </div> | |||
|           <table class="cornealTable"> | |||
|             <tr> | |||
|               <td colspan="1"><div class="tdItem">姓名 <el-input v-model="formData.patientName" style="flex: 1" placeholder="" /></div></td> | |||
|               <td colspan="1"><div class="tdItem">姓别 <el-input v-model="formData.patientName" style="flex: 1" placeholder="" /></div></td> | |||
|               <td colspan="1"> | |||
|                 <div class="tdItem"> | |||
|                   <span style="word-break: keep-all">检查日期</span> | |||
|                   <el-date-picker | |||
|                     v-model="formData.patientCheckDate" | |||
|                     type="date" | |||
|                   /> | |||
|                 </div> | |||
|               </td> | |||
|               <td colspan="1"><div class="tdItem">联系电话 <el-input v-model="formData.patientWearTime" style="flex: 1" placeholder="" /></div></td> | |||
|             </tr> | |||
|             <tr> | |||
|               <td colspan="2"> | |||
|                 <div class="tdItem">家庭住址 <el-input v-model="formData.patientName" style="flex: 1" placeholder="" /></div> | |||
|               </td> | |||
|               <td colspan="2"> | |||
|                 <div class="tdItem">近视家族史 <el-input v-model="formData.patientName" style="flex: 1" placeholder="" /></div> | |||
|               </td> | |||
|             </tr> | |||
|             <tr> | |||
|               <td colspan="2"> | |||
|                 <div class="tdItem">裸眼视力: <el-input v-model="formData.patientName" style="flex: 1" placeholder="" /></div> | |||
|               </td> | |||
|               <td colspan="2"> | |||
|                 <div class="tdItem">眼压: <el-input v-model="formData.patientName" style="flex: 1" placeholder="" /></div> | |||
|               </td> | |||
|             </tr> | |||
|             <tr> | |||
|               <td colspan="4"> | |||
|                 <div class="tdItem">电脑验光: | |||
|                   R<el-input v-model="formData.patientName" style="flex: 1" placeholder="" /> | |||
|                   L<el-input v-model="formData.patientName" style="flex: 1" placeholder="" /> | |||
|                 </div> | |||
|               </td> | |||
|             </tr> | |||
|             <tr> | |||
|               <td colspan="4"> | |||
|                 <div class="tdItem">主觉验光: | |||
|                   R<el-input v-model="formData.patientName" style="flex: 1" placeholder="" /> | |||
|                   L<el-input v-model="formData.patientName" style="flex: 1" placeholder="" /> | |||
|                 </div> | |||
|               </td> | |||
|             </tr> | |||
|             <tr> | |||
|               <td colspan="2">右眼</td> | |||
|               <td colspan="2">左眼</td> | |||
|             </tr> | |||
|             <tr> | |||
|               <td colspan="2"> | |||
|                 <div class="tdItem">H: <el-input v-model="formData.patientName" style="flex: 1" placeholder="" /></div> | |||
|               </td> | |||
|               <td colspan="2"> | |||
|                 <div class="tdItem">H: <el-input v-model="formData.patientName" style="flex: 1" placeholder="" /></div> | |||
|               </td> | |||
|             </tr> | |||
|             <tr> | |||
|               <td colspan="2"> | |||
|                 <div class="tdItem">V: <el-input v-model="formData.patientName" style="flex: 1" placeholder="" /></div> | |||
|               </td> | |||
|               <td colspan="2"> | |||
|                 <div class="tdItem">V: <el-input v-model="formData.patientName" style="flex: 1" placeholder="" /></div> | |||
|               </td> | |||
|             </tr> | |||
|             <tr> | |||
|               <td colspan="2"> | |||
|                 <div class="tdItem">E值: <el-input v-model="formData.patientName" style="flex: 1" placeholder="" /></div> | |||
|               </td> | |||
|               <td colspan="2"> | |||
|                 <div class="tdItem">E值: <el-input v-model="formData.patientName" style="flex: 1" placeholder="" /></div> | |||
|               </td> | |||
|             </tr> | |||
|             <tr> | |||
|               <td colspan="2"> | |||
|                 <div class="tdItem">直径: <el-input v-model="formData.patientName" style="flex: 1" placeholder="" /></div> | |||
|               </td> | |||
|               <td colspan="2"> | |||
|                 <div class="tdItem">直径: <el-input v-model="formData.patientName" style="flex: 1" placeholder="" /></div> | |||
|               </td> | |||
|             </tr> | |||
|             <tr> | |||
|               <td colspan="2"> | |||
|                 <div class="tdItem">眼轴: <el-input v-model="formData.patientName" style="flex: 1" placeholder="" /></div> | |||
|               </td> | |||
|               <td colspan="2"> | |||
|                 <div class="tdItem">眼轴: <el-input v-model="formData.patientName" style="flex: 1" placeholder="" /></div> | |||
|               </td> | |||
|             </tr> | |||
|             <tr> | |||
|               <td colspan="2"> | |||
|                 <div class="tdItem">厚度: <el-input v-model="formData.patientName" style="flex: 1" placeholder="" /></div> | |||
|               </td> | |||
|               <td colspan="2"> | |||
|                 <div class="tdItem">厚度: <el-input v-model="formData.patientName" style="flex: 1" placeholder="" /></div> | |||
|               </td> | |||
|             </tr> | |||
|             <tr> | |||
|               <td colspan="2"> | |||
|                 <div class="tdItem">内皮: <el-input v-model="formData.patientName" style="flex: 1" placeholder="" /></div> | |||
|               </td> | |||
|               <td colspan="2"> | |||
|                 <div class="tdItem">内皮: <el-input v-model="formData.patientName" style="flex: 1" placeholder="" /></div> | |||
|               </td> | |||
|             </tr> | |||
|             <tr> | |||
|               <td colspan="2"> | |||
|                 <div class="tdItem">BUT: <el-input v-model="formData.patientName" style="flex: 1" placeholder="" /></div> | |||
|               </td> | |||
|               <td colspan="2"> | |||
|                 <div class="tdItem">BUT: <el-input v-model="formData.patientName" style="flex: 1" placeholder="" /></div> | |||
|               </td> | |||
|             </tr> | |||
|             <tr> | |||
|               <td colspan="4">试戴参数:</td> | |||
|             </tr> | |||
|             <tr> | |||
|               <td colspan="2"> | |||
|                 <div class="tdItem">R: <el-input v-model="formData.patientName" style="flex: 1" placeholder="" /></div> | |||
|               </td> | |||
|               <td colspan="2"> | |||
|                 <div class="tdItem">L: <el-input v-model="formData.patientName" style="flex: 1" placeholder="" /></div> | |||
|               </td> | |||
|             </tr> | |||
|             <tr> | |||
|               <td colspan="2"> | |||
|                 <div class="tdItem">R: <el-input v-model="formData.patientName" style="flex: 1" placeholder="" /></div> | |||
|               </td> | |||
|               <td colspan="2"> | |||
|                 <div class="tdItem">L: <el-input v-model="formData.patientName" style="flex: 1" placeholder="" /></div> | |||
|               </td> | |||
|             </tr> | |||
|             <tr> | |||
|               <td colspan="2"> | |||
|                 <div class="tdItem">R: <el-input v-model="formData.patientName" style="flex: 1" placeholder="" /></div> | |||
|               </td> | |||
|               <td colspan="2"> | |||
|                 <div class="tdItem">L: <el-input v-model="formData.patientName" style="flex: 1" placeholder="" /></div> | |||
|               </td> | |||
|             </tr> | |||
|             <tr> | |||
|               <td colspan="4">订片参数:</td> | |||
|             </tr> | |||
|             <tr> | |||
|               <td colspan="2"> | |||
|                 <div class="tdItem">R: <el-input v-model="formData.patientName" style="flex: 1" placeholder="" /></div> | |||
|               </td> | |||
|               <td colspan="2"> | |||
|                 <div class="tdItem">L: <el-input v-model="formData.patientName" style="flex: 1" placeholder="" /></div> | |||
|               </td> | |||
|             </tr> | |||
|           </table> | |||
|         </div> | |||
|       </div> | |||
|     </div> | |||
|     <!-- 弹窗, 新增 / 修改 --> | |||
| <!--    <follow-up v-if="followUpVisible" ref="followUp" is-first="1" :title="drgsName + '首诊'" @refreshDataList="init()" />--> | |||
|   </div> | |||
| </template> | |||
| 
 | |||
| <script> | |||
| import headTemplate from '@/components/head' | |||
| const Base64 = require('js-base64').Base64 | |||
| export default { | |||
|   inject: ['refresh'], | |||
|   name: 'CornealReview', | |||
|   components: { | |||
|     headTemplate | |||
|     // followUp | |||
|   }, | |||
|   mixins: [], | |||
|   props: { | |||
|     patientId: { | |||
|       type: String, | |||
|       default: '' | |||
|     } | |||
|   }, | |||
|   data() { | |||
|     return { | |||
|       height: 'calc(100vh - 200px)', | |||
|       dataForm: { | |||
|         name: '', | |||
|         description: '', | |||
|         content: '' | |||
|       }, | |||
|       crfVisible: false, | |||
|       followUpVisible: false, | |||
|       // 获取的检查数据,【item.value】为v-model绑定值,即用于填充左侧iframe | |||
|       examData: [], | |||
|       jsArr: [], | |||
|       addOrUpdateVisible: false, | |||
|       bodyStyleShow: false, | |||
|       clearTimeOut: null, | |||
|       realVisitType: '首诊单', // 表单类型 | |||
|       isFirst: 1 | |||
|       formData: { | |||
|         patientName: '', | |||
|         patientCheckDate: '', | |||
|         patientWearTime: '', | |||
|         checkList: [ | |||
|           { | |||
|             name: '正常', | |||
|             isSelect: false | |||
|           }, { | |||
|             name: '重影', | |||
|             isSelect: false | |||
|           }, { | |||
|             name: '视力波动', | |||
|             isSelect: false | |||
|           }, { | |||
|             name: '异物感', | |||
|             isSelect: false | |||
|           }, { | |||
|             name: '镜片难摘', | |||
|             isSelect: false | |||
|           }, { | |||
|             name: '眼红', | |||
|             isSelect: false | |||
|           }, { | |||
|             name: '眼痛', | |||
|             isSelect: false | |||
|           }, { | |||
|             name: '眩光', | |||
|             isSelect: false | |||
|           }, { | |||
|             name: '视力不佳', | |||
|             isSelect: false | |||
|           }, { | |||
|             name: '其他', | |||
|             isSelect: false | |||
|           } | |||
|         ], | |||
|         projectList: [ | |||
|           { | |||
|             name: '视力', | |||
|             os: '', | |||
|             od: '' | |||
|           }, { | |||
|             name: '眼压', | |||
|             os: '', | |||
|             od: '' | |||
|           }, { | |||
|             name: '角膜地形图', | |||
|             os: '', | |||
|             od: '' | |||
|           }, { | |||
|             name: '眼轴', | |||
|             os: '', | |||
|             od: '' | |||
|           }, { | |||
|             name: '眼表', | |||
|             os: '', | |||
|             od: '', | |||
|             areaList: [ | |||
|               { | |||
|                 name: '角膜', | |||
|                 os: '', | |||
|                 od: '' | |||
|               }, { | |||
|                 name: '结膜', | |||
|                 os: '', | |||
|                 od: '' | |||
|               }, { | |||
|                 name: '其他', | |||
|                 os: '', | |||
|                 od: '' | |||
|               } | |||
|             ] | |||
|           }, { | |||
|             name: '镜片', | |||
|             os: '', | |||
|             od: '', | |||
|             osList: [ | |||
|               { | |||
|                 name: '正常', | |||
|                 isSelect: false | |||
|               }, { | |||
|                 name: '划痕', | |||
|                 isSelect: false | |||
|               }, { | |||
|                 name: '污染', | |||
|                 isSelect: false | |||
|               }, { | |||
|                 name: '破损', | |||
|                 isSelect: false | |||
|               } | |||
|             ], | |||
|             odList: [ | |||
|               { | |||
|                 name: '正常', | |||
|                 isSelect: false | |||
|               }, { | |||
|                 name: '划痕', | |||
|                 isSelect: false | |||
|               }, { | |||
|                 name: '污染', | |||
|                 isSelect: false | |||
|               }, { | |||
|                 name: '破损', | |||
|                 isSelect: false | |||
|               } | |||
|             ] | |||
|           } | |||
|         ], | |||
|         remark: '', | |||
|         patientSign: '', | |||
|         docSign: '' | |||
|       } | |||
|     } | |||
|   }, | |||
|   created() { | |||
|   }, | |||
|   // beforeDestroy() { | |||
|   //   clearInterval(this.clearTimeOut) | |||
|   //   this.clearTimeOut = null | |||
|   // }, | |||
|   methods: { | |||
|     // 打印 | |||
|     printerHandle() { | |||
|       this.$refs.crfComponent.$el.contentWindow.print() | |||
|     saveCheckData() { | |||
|       console.log(this.formData) | |||
|     } | |||
|   } | |||
| } | |||
| </script> | |||
| 
 | |||
| <style lang="scss" scoped> | |||
| .first-visit { | |||
|   .head { | |||
|     padding-bottom: 0px; | |||
|   } | |||
|   .printer { | |||
| .first-visit{ | |||
|   height: 100%; | |||
| } | |||
| input{ | |||
|   -webkit-appearance: checkbox !important; | |||
|   margin-right: 5px; | |||
| } | |||
| ::v-deep .el-input__inner { | |||
|   border: none !important; | |||
|   text-align: center; | |||
|   border-radius: 0; | |||
|   padding: 0; | |||
|   font-size: 16px; | |||
| } | |||
| ::v-deep .el-input__prefix { | |||
|   display: none; | |||
| } | |||
| .el-date-editor.el-input, .el-date-editor.el-input__inner{ | |||
|   width: 100%; | |||
| } | |||
| .cornealTable{ | |||
|   width: 100%; | |||
|   tr td{ | |||
|     border: 1px solid #ccc; | |||
|     width: 56px; | |||
|     height: 32px; | |||
|     border-radius: 3px; | |||
|     margin: 0; | |||
|     margin-left: 10px; | |||
|     cursor: pointer; | |||
|     font-size: 18px; | |||
|     padding: 5px 10px; | |||
|     ::v-deep .el-input__inner { | |||
|       border: none !important; | |||
|       text-align: center; | |||
|       border-radius: 0; | |||
|       padding: 0; | |||
|     } | |||
|     ::v-deep .el-textarea__inner{ | |||
|       border: none; | |||
|     } | |||
|     .tdItem{ | |||
|       display: flex !important; | |||
|       align-items: center; | |||
|     } | |||
|     .checkItem{ | |||
|       cursor: pointer; | |||
|       user-select: none; | |||
|       word-break: keep-all; | |||
|       margin-right: 20px; | |||
|     } | |||
|   } | |||
|   .tips { | |||
|     color: #ff4d4f; | |||
|     margin-bottom: 6px; | |||
| } | |||
| .corneal{ | |||
|   width: 100%; | |||
|   height: 100%; | |||
|   display:flex; | |||
|   flex-direction: column; | |||
| } | |||
| .notice-content{ | |||
|   width: 100%; | |||
|   height: calc(100% - 50px); | |||
|   flex:1; | |||
|   //overflow-y: auto; | |||
|   .notice-box{ | |||
|     width: 100%; | |||
|     height: 100%; | |||
|   } | |||
|   .first-visit-content { | |||
|     min-width: 960px; | |||
|     height: calc(100vh - 50px - 32px - 42px - 54px - 32px); | |||
|     padding: 16px; | |||
|     background: #ededed; | |||
|     text-align: center; | |||
| 
 | |||
|   .notice_tip{ | |||
|     height: 100%; | |||
|     overflow-y: auto; | |||
|     border: 1px solid #000; | |||
|     padding: 64px 32px; | |||
|     margin-right: 16px; | |||
|   } | |||
| } | |||
| </style> | |||
|  | |||
| @ -0,0 +1,286 @@ | |||
| <template> | |||
|   <el-card shadow="never" class="aui-card--fill"> | |||
|     <div class="doctor-management"> | |||
|       <el-form | |||
|         :inline="true" | |||
|         @submit.native.prevent | |||
|       > | |||
|         <el-form-item> | |||
|           <el-button | |||
|             type="primary" | |||
|             style="margin-left:12px;" | |||
|             icon="el-icon-plus" | |||
|             @click="assignPeopleClick()" | |||
|           >分配人员 | |||
|           </el-button> | |||
|         </el-form-item> | |||
|       </el-form> | |||
| 
 | |||
|       <el-table :data="doctorList"> | |||
|         <el-table-column prop="userName" label="用户名" header-align="center" align="center" /> | |||
|         <el-table-column prop="realName" label="真实姓名" header-align="center" align="center" /> | |||
|         <el-table-column prop="gender" label="性别" header-align="center" align="center"> | |||
|           <template slot-scope="scope"> | |||
|             <span>{{ scope.row.gender=='0' ? '男': (scope.row.gender=='1' ? '女':'保密') }}</span> | |||
|           </template> | |||
|         </el-table-column> | |||
|         <el-table-column prop="mobile" label="手机号" header-align="center" align="center" /> | |||
|         <el-table-column prop="roleNameList" label="角色" header-align="center" align="center"> | |||
|           <template slot-scope="scope"> | |||
|             <div v-if="scope.row.roleNameList.length>0"> | |||
|               <p v-for="(item,index) in scope.row.roleNameList" :key="index" style="margin:0">{{ item }} | |||
|               </p> | |||
|             </div> | |||
|           </template> | |||
|         </el-table-column> | |||
|         <el-table-column prop="status" label="状态" header-align="center" align="center"> | |||
|           <template slot-scope="scope"> | |||
|             <span | |||
|               :class="scope.row.status=='1' ? 'state-circle state-circle-green' :'state-circle state-circle-red'" | |||
|             /> | |||
|             <span>{{ scope.row.status == '1' ? '正常':'停用' }}</span> | |||
|           </template> | |||
|         </el-table-column> | |||
|         <el-table-column prop="operation" label="操作" header-align="center" align="center"> | |||
|           <template slot-scope="scope"> | |||
|             <span v-if="opPermission(scope.row)"> | |||
|               <el-dropdown trigger="click" @command="handleRoleCommand(scope.row,$event)"> | |||
|                 <span class="el-dropdown-link" style="padding-right:8px;cursor: pointer;">更改角色</span> | |||
|                 <el-dropdown-menu slot="dropdown"> | |||
|                   <el-dropdown-item v-for="item in roleList" :key="item.roleId" :command="item.id">{{ item.name }}</el-dropdown-item> | |||
|                 </el-dropdown-menu> | |||
|               </el-dropdown> | |||
|               <span | |||
|                 style="color:#FF4D4F" | |||
|                 class="operation-delete" | |||
|                 @click="deleteClick(scope.row)" | |||
|               >移出</span> | |||
|             </span> | |||
|           </template> | |||
|         </el-table-column> | |||
|       </el-table> | |||
|       <el-pagination | |||
|         background | |||
|         layout="prev, pager, next" | |||
|         :total="total" | |||
|         @current-change="pageCurrentChangeHandle" | |||
|       /> | |||
|     </div> | |||
|     <!-- 弹框 --> | |||
|     <el-dialog title="分配人员" :visible.sync="dialogFormVisible" width="650px"> | |||
|       <div style="text-align: center"> | |||
|         <el-transfer | |||
|           v-model="rightValue" | |||
|           style="text-align: left; display: inline-block" | |||
|           :render-content="renderFunc" | |||
|           :format="{noChecked: '${total}',hasChecked: '${checked}/${total}'}" | |||
|           :titles="['未加入', '已加入课题']" | |||
|           :props="{key: 'userId', label: 'realName'}" | |||
|           :data="AllJoinedPeopleList" | |||
|           @change="handleChange" | |||
|         /> | |||
|       </div> | |||
|       <span slot="footer" class="dialog-footer"> | |||
|         <el-button @click="dialogFormVisible = false">取 消</el-button> | |||
|         <el-button type="primary" @click="sureJoinedPeopleClick">确 定</el-button> | |||
|       </span> | |||
|     </el-dialog> | |||
|   </el-card> | |||
| </template> | |||
| <script> | |||
| import { confirm } from '@/utils/confirm' | |||
| export default { | |||
|   inject: ['refresh'], | |||
|   data() { | |||
|     const generateData = _ => { | |||
|       const transferData = [] | |||
|       for (let i = 1; i <= 15; i++) { | |||
|         transferData.push({ | |||
|           key: i, | |||
|           label: `备选项 ${i}`, | |||
|           disabled: i % 4 === 0 | |||
|         }) | |||
|       } | |||
|       return transferData | |||
|     } | |||
|     return { | |||
|       inputSearchValue: '', | |||
|       transferData: generateData(), | |||
|       renderFunc(h, option) { | |||
|         return <span>{option.realName}</span> | |||
|       }, | |||
|       dialogFormVisible: false, | |||
|       projectId: '', | |||
|       doctorList: [], | |||
|       roleList: [], | |||
|       limit: 10, | |||
|       currentPage: 1, | |||
|       total: 0, | |||
|       searchTime: '', | |||
|       JoinedPeopleList: [], | |||
|       notJoinedPeopleList: [], | |||
|       AllJoinedPeopleList: [], | |||
|       rightValue: [], | |||
|       joinedListUserId: [] | |||
|     } | |||
|   }, | |||
|   created() { | |||
|     this.projectId = window.SITE_CONFIG['projectId'] | |||
|     this.getDoctorList() | |||
|     this.getProjectUser() | |||
|     this.getRoleList() | |||
|   }, | |||
|   methods: { | |||
|     reload() { | |||
|       this.isRouterAlive = false | |||
|       this.$nextTick(() => { | |||
|         this.isRouterAlive = true | |||
|       }) | |||
|     }, | |||
|     opPermission(rowObj) { | |||
|       return rowObj.userId !== this.$store.state.user.id | |||
|     }, | |||
|     // 分配人员显示弹框 | |||
|     assignPeopleClick() { | |||
|       this.dialogFormVisible = true | |||
|     }, | |||
|     // 获取人员列表 | |||
|     getProjectUser() { | |||
|       this.$http.get(`/projectUser/getUserList/${this.projectId}`) | |||
|         .then(({ data: res }) => { | |||
|           this.JoinedPeopleList = res.data.joinedList | |||
|           this.notJoinedPeopleList = res.data.notJoined | |||
|           // 已加入 | |||
|           if (res.data.joinedList.length > 0) { | |||
|             res.data.joinedList.forEach(item => { | |||
|               this.rightValue.push(item.userId) | |||
|               if (item.isAdmin === 1) { | |||
|                 item.disabled = true | |||
|               } | |||
|             }) | |||
|           } | |||
|           // 未加入 | |||
|           if (res.data.notJoined.length > 0) { | |||
|             res.data.notJoined.forEach(item => { | |||
|               if (item.isAdmin === 1) { | |||
|                 item.disabled = true | |||
|               } | |||
|             }) | |||
|           } | |||
|           this.AllJoinedPeopleList = [...res.data.joinedList, ...res.data.notJoined] | |||
|         }) | |||
|     }, | |||
|     // 分配人员变化时 | |||
|     handleChange(value) { | |||
|       this.joinedListUserId = value | |||
|     }, | |||
|     // 分配人员确认 | |||
|     sureJoinedPeopleClick() { | |||
|       this.dialogFormVisible = false | |||
|       this.$http.post('/projectUser', { | |||
|         projectId: this.projectId, | |||
|         userIdList: this.joinedListUserId | |||
|       }).then(({ data: res }) => { | |||
|         this.$message.success('分配成功') | |||
|         this.refresh() | |||
|       }) | |||
|     }, | |||
|     // 获取角色列表 | |||
|     getRoleList(scopeRow) { | |||
|       this.$http.get('/sys/role/getProjectRoleList', { | |||
|         params: { | |||
|           deptId: this.$store.state.user.deptId || window.SITE_CONFIG['projectInfo'].deptId | |||
|         } | |||
|       }).then(({ data: res }) => { | |||
|         this.roleList = res.data | |||
|       }) | |||
|     }, | |||
|     // 点击角色更改角色 | |||
|     handleRoleCommand(scopeRow, e) { | |||
|       this.$http.post('projectUser/saveOrUpdateUserRoleForProject', { | |||
|         projectId: this.projectId, | |||
|         roleIdList: [e], | |||
|         userId: scopeRow.userId | |||
|       }).then(({ data: res }) => { | |||
|         this.$message.success('更改角色成功!') | |||
|         this.refresh() | |||
|       }) | |||
|     }, | |||
|     // 获取医生列表 | |||
|     getDoctorList(e) { | |||
|       this.$http.get('/projectUser/page', { | |||
|         params: { | |||
|           limit: this.limit, | |||
|           page: this.currentPage, | |||
|           projectId: this.projectId, | |||
|           realName: '' | |||
|         } | |||
|       }).then(({ data: res }) => { | |||
|         this.doctorList = res.data.list | |||
|         this.total = res.data.total | |||
|       }) | |||
|     }, | |||
|     // 当前页改变时触发 | |||
|     pageCurrentChangeHandle(e) { | |||
|       this.currentPage = e | |||
|       this.getDoctorList() | |||
|     }, | |||
|     // 移出 | |||
|     deleteClick(scopeRow) { | |||
|       confirm('').then(async() => { | |||
|         this.$http({ | |||
|           method: 'delete', | |||
|           url: '/projectUser', | |||
|           data: [scopeRow.id] | |||
|         }).then(({ data: res }) => { | |||
|           this.$message.success('删除成功!') | |||
|           this.refresh() | |||
|         }) | |||
|       }) | |||
|     } | |||
|   } | |||
| } | |||
| </script> | |||
| <style lang='scss' scoped> | |||
| 
 | |||
|   .state-circle { | |||
|     display: inline-block; | |||
|     width: 6px; | |||
|     height: 6px; | |||
|     border-radius: 50%; | |||
|     margin-right: 8px; | |||
|   } | |||
|   .state-circle-green { | |||
|     background-color: #52c41a; | |||
|   } | |||
|   .state-circle-red { | |||
|     background-color: #ff4d4f; | |||
|   } | |||
|   .operation-details, | |||
|   .operation-delete, | |||
|   .el-dropdown-link { | |||
|     cursor: pointer; | |||
|   } | |||
|   .el-dropdown-link { | |||
|     color:#1890FF; | |||
|     padding-right: 8px; | |||
|   } | |||
| </style> | |||
| <style lang="scss"> | |||
| 
 | |||
| .el-transfer__button:first-child { | |||
|   margin-bottom: 4px; | |||
| } | |||
| .el-transfer__buttons { | |||
|   .el-button { | |||
|     display: block; | |||
|     padding: 0; | |||
|     width: 24px; | |||
|     height: 24px; | |||
|   } | |||
|   .el-button:nth-child(2) { | |||
|     margin-left: 0; | |||
|   } | |||
| } | |||
| 
 | |||
| </style> | |||
| @ -0,0 +1,138 @@ | |||
| <template> | |||
|   <el-dialog | |||
|     width="calc(210mm + 90px + 100px)" | |||
|     top="2vh" | |||
|     :visible.sync="visible" | |||
|     :title="dataForm.title||(!dataForm.id ? $t('add') : $t('update'))" | |||
|     :close-on-click-modal="false" | |||
|     :close-on-press-escape="false" | |||
|   > | |||
|     <el-form | |||
|       ref="dataForm" | |||
|       :model="dataForm" | |||
|       :rules="dataRule" | |||
|       label-width="auto" | |||
|       @submit.native.prevent | |||
|       @keyup.enter.native="initBaseInfo()" | |||
|     > | |||
| 
 | |||
|       <el-form-item prop="name" :label="'名称'"> | |||
|         <el-input | |||
|           v-model="dataForm.name" | |||
|           :placeholder="'请填写表单名称'" | |||
|         /> | |||
|       </el-form-item> | |||
|       <el-form-item prop="content" :label="'表单'"> | |||
|         <crf-editor ref="crf" v-model="dataForm.content" :height="height" /> | |||
|       </el-form-item> | |||
|       <el-form-item prop="description" :label="'描述'"> | |||
|         <el-input | |||
|           v-model="dataForm.description" | |||
|           type="textarea" | |||
|           :rows="1" | |||
|           :placeholder="'相关描述'" | |||
|         /> | |||
|       </el-form-item> | |||
|     </el-form> | |||
|     <template slot="footer"> | |||
|       <el-button @click="visible = false">{{ $t('cancel') }}</el-button> | |||
|       <el-button type="primary" @click="dataFormSubmitHandle()">{{ $t('confirm') }}</el-button> | |||
|     </template> | |||
|   </el-dialog> | |||
| </template> | |||
| 
 | |||
| <script> | |||
| import debounce from 'lodash/debounce' | |||
| import crfEditor from '@/components/hm-crf' | |||
| const Base64 = require('js-base64').Base64 | |||
| 
 | |||
| export default { | |||
|   components: { crfEditor }, | |||
|   data() { | |||
|     return { | |||
|       visible: false, | |||
|       height: 'calc(100vh - 300px)', | |||
|       dataForm: { | |||
|         id: '', | |||
|         projectId: '', | |||
|         name: '', | |||
|         description: '', | |||
|         content: '' | |||
|       } | |||
|     } | |||
|   }, | |||
|   computed: { | |||
|     dataRule() { | |||
|       var validate_content = (rule, value, callback) => { | |||
|         if (this.dataForm.content === '') { | |||
|           return callback(new Error('请设计表单内容')) | |||
|         } | |||
|         callback() | |||
|       } | |||
|       return { | |||
|         name: [ | |||
|           { required: true, message: this.$t('validate.required'), trigger: 'blur' } | |||
|         ], | |||
|         content: [ | |||
|           { required: true, validator: validate_content, trigger: 'change' } | |||
|         ] | |||
|       } | |||
|     } | |||
|   }, | |||
|   methods: { | |||
|     init() { | |||
|       this.visible = true | |||
|       this.$nextTick(() => { | |||
|         this.$refs.dataForm.resetFields() | |||
|         this.dataForm.projectId = window.SITE_CONFIG['projectId'] | |||
|         if (this.dataForm.id) { | |||
|           this.getInfo() | |||
|         } else { | |||
|           this.dataForm = { ...this.dataForm } | |||
|         } | |||
|       }) | |||
|     }, | |||
|     // 获取信息 | |||
|     getInfo() { | |||
|       this.$http.get('/crf/template', { params: { crfId: this.dataForm.id }}).then(({ data: res }) => { | |||
|         if (res.code !== 0) { | |||
|           return this.$message.error(res.msg) | |||
|         } | |||
|         if (res.data) { | |||
|           this.dataForm.name = res.data.name | |||
|           this.dataForm.content = Base64.decode(res.data.content) | |||
|           this.dataForm.description = res.data.description | |||
|           this.$refs['crf'].renderContent() | |||
|         } | |||
|       }).catch(() => {}) | |||
|     }, | |||
| 
 | |||
|     // 表单提交 | |||
|     dataFormSubmitHandle: debounce(function() { | |||
|       this.$refs.dataForm.validate((valid) => { | |||
|         if (!valid) { | |||
|           return false | |||
|         } | |||
|         this.$http[!this.dataForm.id ? 'post' : 'put']('/crf/template', { ...this.dataForm, content: Base64.encode(this.dataForm.content) }).then(({ data: res }) => { | |||
|           if (res.code !== 0) { | |||
|             return this.$message.error(res.msg) | |||
|           } | |||
|           this.$message({ | |||
|             message: this.$t('prompt.success'), | |||
|             type: 'success', | |||
|             duration: 500, | |||
|             onClose: () => { | |||
|               this.visible = false | |||
|               this.$emit('refreshDataList') | |||
|             } | |||
|           }) | |||
|         }).catch(() => {}) | |||
|       }) | |||
|     }, 1000, { leading: true, trailing: false }) | |||
|   } | |||
| } | |||
| </script> | |||
| 
 | |||
| <style lang="scss"> | |||
| 
 | |||
| </style> | |||
| @ -0,0 +1,99 @@ | |||
| <template> | |||
|   <el-card shadow="never" class="aui-card--fill"> | |||
|     <el-form | |||
|       :inline="true" | |||
|       :model="dataForm" | |||
|       @submit.native.prevent | |||
|       @keyup.enter.native="getDataList()" | |||
|     > | |||
|       <el-form-item> | |||
|         <el-button type="primary" @click="addOrUpdateHandle(null,null,'新增表单')">{{ $t('add') }}</el-button> | |||
|       </el-form-item> | |||
|     </el-form> | |||
|     <el-table v-loading="dataListLoading" :data="dataList" row-key="id" border style="width: 100%;"> | |||
|       <!-- 名称 --> | |||
|       <el-table-column prop="name" :label="'名称'" /> | |||
|       <!-- 描述 --> | |||
|       <el-table-column prop="description" :label="'描述'" /> | |||
|       <!-- 创建时间 --> | |||
|       <el-table-column prop="createDate" :label="'创建时间'" /> | |||
|       <!-- 操作 --> | |||
|       <el-table-column prop="operation" :label="$t('handle')"> | |||
|         <template slot-scope="scope"> | |||
|           <!-- <el-button type="text" size="small" @click="testClick1(scope.row.id,...scope.row)">{{ '测试1' }}</el-button> --> | |||
|           <!-- <el-button type="text" size="small" @click="testClick2(scope.row.id,...scope.row)">{{ '测试2' }}</el-button> --> | |||
|           <el-button | |||
|             type="text" | |||
|             size="small" | |||
|             @click="preview(scope.row.id,...scope.row)" | |||
|           >{{ $t('preview') }}</el-button> | |||
|           <el-button | |||
|             type="text" | |||
|             size="small" | |||
|             @click="addOrUpdateHandle(scope.row.id,...scope.row)" | |||
|           >{{ $t('update') }}</el-button> | |||
|           <el-button | |||
|             type="text" | |||
|             size="small" | |||
|             style="color:red" | |||
|             @click="deleteHandle(scope.row.id)" | |||
|           >{{ $t('delete') }}</el-button> | |||
|         </template> | |||
|       </el-table-column> | |||
|     </el-table> | |||
|     <!-- 添加分页组件 --> | |||
|     <el-pagination | |||
|       background | |||
|       layout="prev, pager, next" | |||
|       :total="total" | |||
|       @current-change="pageCurrentChangeHandle" | |||
|     /> | |||
|     <!-- <el-pagination | |||
|         :current-page="page" | |||
|         :page-sizes="[10, 20, 50, 100]" | |||
|         :page-size="limit" | |||
|         :total="total" | |||
|         layout="total, sizes, prev, pager, next, jumper" | |||
|         @size-change="pageSizeChangeHandle" | |||
|         @current-change="pageCurrentChangeHandle" | |||
|       /> --> | |||
|     <!-- 弹窗, 新增 / 修改 --> | |||
|     <add-or-update v-if="addOrUpdateVisible" ref="addOrUpdate" @refreshDataList="getDataList" /> | |||
|     <!-- 弹窗, 预览 --> | |||
|     <preview v-if="previewVisible" ref="preview" :type="'preview'" /> | |||
| 
 | |||
|   </el-card> | |||
| </template> | |||
| 
 | |||
| <script> | |||
| import mixinViewModule from '@/mixins/view-module' | |||
| import AddOrUpdate from './add-or-update' | |||
| import preview from '@/components/ecrf/dialog-load' | |||
| 
 | |||
| export default { | |||
|   components: { AddOrUpdate, preview }, | |||
|   mixins: [mixinViewModule], | |||
|   data() { | |||
|     return { | |||
|       previewVisible: false, | |||
|       mixinViewModuleOptions: { | |||
|         getDataListURL: '/crf/page', | |||
|         getDataListIsPage: true, | |||
|         deleteURL: '/crf' | |||
|       }, | |||
|       dataForm: { | |||
|         projectId: window.SITE_CONFIG['projectId'] | |||
|       } | |||
|     } | |||
|   }, | |||
|   methods: { | |||
|     preview(id, params, title) { | |||
|       this.previewVisible = true | |||
|       this.$nextTick(() => { | |||
|         this.$refs.preview.id = id | |||
|         this.$refs.preview.init() | |||
|       }) | |||
|     } | |||
|   } | |||
| } | |||
| </script> | |||
| @ -0,0 +1,50 @@ | |||
| <template> | |||
|   <div class="template-container"> | |||
|     <el-tabs v-model="activeName" @tab-click="handleClick"> | |||
|       <el-tab-pane label="样本库" name="first"> | |||
|         <search /> | |||
|       </el-tab-pane> | |||
|       <el-tab-pane label="医生管理" name="second"> | |||
|         <doctor /> | |||
|       </el-tab-pane> | |||
|       <el-tab-pane label="eCRF管理" name="third"> | |||
|         <eCrf></eCrf> | |||
|       </el-tab-pane> | |||
|       <el-tab-pane label="受试者管理" name="fourth"> | |||
|         <patientSubject></patientSubject> | |||
|       </el-tab-pane> | |||
|       <el-tab-pane label="日志" name="five"> | |||
|         <operateLog></operateLog> | |||
|       </el-tab-pane> | |||
|     </el-tabs> | |||
|   </div> | |||
| </template> | |||
| 
 | |||
| <script> | |||
| import search from './patient-search/index' | |||
| import doctor from './doctor/index' | |||
| import eCrf from './ecrf/index' | |||
| import patientSubject from './patient-subject/index' | |||
| import operateLog from './log/index' | |||
| 
 | |||
| export default { | |||
|   components: { doctor, search, eCrf, patientSubject, operateLog }, | |||
|   data() { | |||
|     return { | |||
|       activeName: 'first' | |||
|     } | |||
|   }, | |||
|   mounted() { | |||
|   }, | |||
|   methods: { | |||
|     handleClick() { | |||
| 
 | |||
|     } | |||
|   } | |||
| } | |||
| </script> | |||
| 
 | |||
| <style lang='scss' scoped> | |||
| .template-container { | |||
| } | |||
| </style> | |||
| @ -0,0 +1,103 @@ | |||
| <template> | |||
|   <el-card shadow="never" class="aui-card--fill"> | |||
|     <div class="filter-wrapper"> | |||
|       <el-form :inline="true" :model="dataForm" @submit.native.prevent @keyup.enter.native="getDataList()"> | |||
| 
 | |||
|         <el-form-item> | |||
|           <el-input v-model="input" placeholder="关键词" class="input-with-select" clearable> | |||
|             <el-select slot="prepend" v-model="select" placeholder="请选择"> | |||
|               <el-option label="用户名" value="username" /> | |||
|               <el-option label="用户姓名" value="realName" /> | |||
|               <el-option label="用户操作" value="action" /> | |||
|               <el-option label="IP地址" value="ip" /> | |||
|             </el-select> | |||
|             <el-button slot="append" icon="el-icon-search" @click="getDataList()">{{ $t('query') }}</el-button> | |||
|           </el-input> | |||
|         </el-form-item> | |||
| 
 | |||
|       </el-form> | |||
| 
 | |||
|       <el-table | |||
|         v-loading="dataListLoading" | |||
|         :data="dataList" | |||
|         border | |||
|         style="width: 100%;" | |||
|         @sort-change="dataListSortChangeHandle" | |||
|       > | |||
|         <el-table-column prop="creatorName" :label="'账号'" header-align="center" align="center" width="120" /> | |||
|         <el-table-column prop="realName" :label="'用户姓名'" header-align="center" align="center" width="120" /> | |||
|         <el-table-column prop="operation" :label="'用户操作'" /> | |||
|         <!-- <el-table-column prop="projectName" :label="'课题'" header-align="center" align="center" show-overflow-tooltip /> --> | |||
|         <el-table-column prop="ip" :label="'操作IP'" width="125" header-align="center" /> | |||
|         <el-table-column prop="createDate" :label="'操作时间'" header-align="center" sortable="custom" width="160" /> | |||
|       </el-table> | |||
| 
 | |||
|       <!-- 分页 --> | |||
|       <el-pagination | |||
|         :current-page="page" | |||
|         :page-sizes="[10, 20, 50, 100]" | |||
|         :page-size="limit" | |||
|         :total="total" | |||
|         layout="total, sizes, prev, pager, next, jumper" | |||
|         @size-change="pageSizeChangeHandle" | |||
|         @current-change="pageCurrentChangeHandle" | |||
|       /> | |||
|     </div> | |||
|   </el-card> | |||
| </template> | |||
| 
 | |||
| <script> | |||
| import mixinViewModule from '@/mixins/view-module' | |||
| export default { | |||
|   mixins: [mixinViewModule], | |||
|   data() { | |||
|     return { | |||
|       mixinViewModuleOptions: { | |||
|         getDataListURL: '/sys/log/operation/page4User', | |||
|         getDataListIsPage: true | |||
|       }, | |||
|       select: 'action', | |||
|       input: '', | |||
|       dataForm: { | |||
|         username: '', | |||
|         realName: '', | |||
|         action: '', | |||
|         ip: '' | |||
|       } | |||
|     } | |||
|   }, | |||
|   watch: { | |||
|     select(val) { this.dataFormHandle() }, | |||
|     input(val) { this.dataFormHandle() } | |||
|   }, | |||
|   methods: { | |||
|     dataFormHandle() { | |||
|       const inputValue = !(this.input) ? null : this.input | |||
|       switch (this.select) { | |||
|         case 'realName': | |||
|           this.dataForm.realName = inputValue | |||
|           break | |||
|         case 'action': | |||
|           this.dataForm.action = inputValue | |||
|           break | |||
|         case 'ip': | |||
|           this.dataForm.ip = inputValue | |||
|           break | |||
|       } | |||
|     } | |||
|   } | |||
| } | |||
| </script> | |||
| <style lang="scss" scoped> | |||
| .input-with-select { | |||
|   width: 500px; | |||
| 
 | |||
|   ::v-deep .el-select .el-input { | |||
|     width: 120px; | |||
|   } | |||
| 
 | |||
|   ::v-deep .el-input-group__prepend { | |||
|     background-color: #fff; | |||
|   } | |||
| } | |||
| </style> | |||
| @ -0,0 +1,71 @@ | |||
| <!-- 样本库 --> | |||
| <template> | |||
|   <div class="search"> | |||
|     <patient-search | |||
|       ref="patientSearch" | |||
|       :enable-select="enableSelect" | |||
|       :project-id="projectId" | |||
|       :select-disable-id-list="selectDisableIdList" | |||
|       :query-item.sync="queryItem" | |||
|       :size="'small'" | |||
|       @vmSelectIdList="vmSelectIdList" | |||
|     > | |||
|       <template slot="btn"> | |||
|         <el-button type="primary" size="small" @click="btnPullInSubjectClick">引入受试者</el-button> | |||
|       </template> | |||
|     </patient-search> | |||
|   </div> | |||
| </template> | |||
| 
 | |||
| <script> | |||
| import patientSearch from '@/components/patient-search' | |||
| 
 | |||
| export default { | |||
|   components: { patientSearch }, | |||
|   data() { | |||
|     return { | |||
|       enableSelect: true, | |||
|       projectId: window.SITE_CONFIG['projectId'], | |||
|       selectIdList: [], | |||
|       selectDisableIdList: [], | |||
|       queryItem: {} | |||
|     } | |||
|   }, | |||
|   created() { | |||
|     this.getSubjectIdNumberList() | |||
|   }, | |||
|   mounted() { | |||
|   }, | |||
|   methods: { | |||
|     vmSelectIdList(data) { | |||
|       this.selectIdList = data | |||
|     }, | |||
|     // 引入受试者 | |||
|     btnPullInSubjectClick() { | |||
|       if (this.selectIdList.length === 0) { | |||
|         return this.$message.error('请勾选需要导出的患者!') | |||
|       } | |||
| 
 | |||
|       this.$refs.patientSearch.clearSelect() | |||
|       this.getSubjectIdNumberList() | |||
|       this.$http.post('/project/patient', { | |||
|         projectId: this.projectId, | |||
|         hospitalCode: '52618662', | |||
|         idNumberList: this.selectIdList | |||
|       }).then(({ data: res }) => { | |||
|         this.$message.success('引入成功!') | |||
| 
 | |||
|         // 课题状态改为进行中(1:未开始,2:进行中,3:已完成) | |||
|         this.$http.put('/project/status', { projectId: this.projectId, status: 2 }) | |||
|         this.getSubjectIdNumberList() | |||
|       }) | |||
|     }, | |||
|     getSubjectIdNumberList() { | |||
|       this.$http.get('/project/patient/patIdNumberList', { params: { projectId: this.projectId }}) | |||
|         .then(({ data: res }) => { | |||
|           this.selectDisableIdList = res.data | |||
|         }) | |||
|     } | |||
|   } | |||
| } | |||
| </script> | |||
| @ -0,0 +1,775 @@ | |||
| <template> | |||
|   <div class="subject-management"> | |||
|     <div class="subject-left"> | |||
|       <el-scrollbar style="height: 100%"> | |||
|         <div class="photo-groups"> | |||
|           <span>受试者分组</span> | |||
|           <i class="el-icon-circle-plus" @click="addGroupClick" /> | |||
|         </div> | |||
|         <div | |||
|           v-for="(item, index) in groupList" | |||
|           :key="item.id" | |||
|           class="group-list" | |||
|           :class="currentIndex == index ? 'group-list-active' : ''" | |||
|           @click="grouplistClick(item.id, index)" | |||
|         > | |||
|           <span>{{ item.name }}</span> | |||
|           <span v-if="item.name == '全部'" style="margin-right:20px;">{{ groupListAll.total }}</span> | |||
|           <span v-else-if="item.name == '未分组'" style="margin-right:20px;">{{ groupListAll.noInGroup }}</span> | |||
|           <div v-else class="dropdown-right"> | |||
|             <span class="number">{{ item.groupTotal }}</span> | |||
|             <el-dropdown trigger="click" @command="handleDropdownCommand(item.id, $event)"> | |||
|               <i class="el-icon-more" /> | |||
|               <el-dropdown-menu slot="dropdown"> | |||
|                 <el-dropdown-item command="1">修改</el-dropdown-item> | |||
|                 <el-dropdown-item command="2">删除</el-dropdown-item> | |||
|               </el-dropdown-menu> | |||
|             </el-dropdown> | |||
|           </div> | |||
|         </div> | |||
|       </el-scrollbar> | |||
|     </div> | |||
|     <div class="subject-right"> | |||
|       <div class="input-search"> | |||
|         <el-input | |||
|           v-model="inputSearchValue" | |||
|           placeholder="姓名" | |||
|           class="input-with-select" | |||
|           clearable | |||
|           @clear="getDataList()" | |||
|           @change="getDataList()" | |||
|         > | |||
|           <el-button slot="append" icon="el-icon-search" @click="getDataList()" /> | |||
|         </el-input> | |||
|       </div> | |||
| 
 | |||
|       <div class="people-list"> | |||
|         <!-- <div class="title">人员列表</div> --> | |||
|         <el-table | |||
|           ref="multipleTable" | |||
|           v-loading="tabelLoading" | |||
|           :data="dataList" | |||
|           tooltip-effect="dark" | |||
|           style="width: 100%" | |||
|           @selection-change="handleSelectionChange" | |||
|         > | |||
|           <el-table-column type="selection" width="55" /> | |||
|           <el-table-column type="index" width="55" label="序号" header-align="center" align="center" /> | |||
|           <el-table-column prop="patientName" label="姓名" header-align="center" align="center" /> | |||
|           <el-table-column prop="age" label="年龄" header-align="center" align="center" /> | |||
|           <el-table-column prop="patientSex" label="性别" header-align="center" align="center" /> | |||
|           <el-table-column prop="suggest" label="纳排建议" header-align="center" align="center"> | |||
|             <template slot-scope="scope"> | |||
|               <span | |||
|                 v-if="scope.row.suggest" | |||
|                 :class="scope.row.suggest == '1' ? 'suggest-circle suggest-circle-green' : 'suggest-circle suggest-circle-red'" | |||
|               /> | |||
|               <span>{{ scope.row.suggest==1 ? '符合': (scope.row.suggest==0 ? '不符合' : '无') }}</span> | |||
|             </template> | |||
|           </el-table-column> | |||
|           <el-table-column label="分组信息" header-align="center" align="center"> | |||
|             <template slot-scope="scope"> | |||
|               <div v-show="scope.row.groupList.length > 0"> | |||
|                 <span v-for="item in scope.row.groupList" :key="item.id">{{ item.name }}</span> | |||
|               </div> | |||
|             </template> | |||
|           </el-table-column> | |||
|           <el-table-column prop="operation" label="操作" width="200"> | |||
|             <template slot-scope="scope"> | |||
|               <span | |||
|                 style="color: #1890ff; padding-right: 8px" | |||
|                 class="operation-details" | |||
|                 @click="showDetail(scope.row)" | |||
|               >详情</span> | |||
|               <span | |||
|                 style="color: #ff4d4f" | |||
|                 class="operation-delete" | |||
|                 @click="deleteSubjectClick(scope.row.id)" | |||
|               >移出课题</span> | |||
|               <span | |||
|                 v-show="groupId!==0 && groupId!=='' ? true:false" | |||
|                 style="color: #ff4d4f;padding-left:10px;" | |||
|                 class="operation-delete" | |||
|                 @click="deleteGroupClick(scope.row)" | |||
|               >移出分组</span> | |||
|             </template> | |||
|           </el-table-column> | |||
|         </el-table> | |||
|         <!-- 分页 --> | |||
|         <el-pagination | |||
|           :current-page="page" | |||
|           :page-sizes="[10, 20, 50, 100]" | |||
|           :page-size="limit" | |||
|           :total="total" | |||
|           layout="total, sizes, prev, pager, next, jumper" | |||
|           @size-change="pageSizeChangeHandle" | |||
|           @current-change="pageCurrentChangeHandle" | |||
|         /> | |||
| 
 | |||
|         <!-- 底部全选反选 --> | |||
|         <checked-footer | |||
|           ref="checkfooter" | |||
|           table-ref="multipleTable" | |||
|           :current-table-list="currentTableList" | |||
|           :data-list="dataList" | |||
|         > | |||
|           <div class="batch_button"> | |||
|             <!-- <el-button | |||
|               size="small" | |||
|               :disabled="(groupId==0 || groupId=='') && currentTableList.length > 0 ? false:true" | |||
|               @click="batchDeleteSubjectClick" | |||
|             >批量移出课题</el-button> | |||
|             <el-button | |||
|               size="small" | |||
|               :disabled="groupId!==0 && groupId!==''&& currentTableList.length > 0 ? false:true" | |||
|               @click="batchDeleteGroupClick" | |||
|             >批量移出分组</el-button> | |||
|             <el-button size="small" @click="btnExportClick">{{ currentTableList.length > 0 ?"导出":"全部导出" }}</el-button> | |||
|             <el-dropdown @command="handleGroupCommand($event)"> | |||
|               <el-button type="primary" size="small" :disabled="currentTableList.length > 0 ? false :true">分组 | |||
|               </el-button> | |||
|               <el-dropdown-menu slot="dropdown"> | |||
|                 <el-dropdown-item | |||
|                   v-for="item in groupList" | |||
|                   :key="item.id" | |||
|                   :command="item.id" | |||
|                   :disabled="item.name=='全部' || item.name=='未分组'" | |||
|                 >{{ item.name }} | |||
|                 </el-dropdown-item> | |||
|               </el-dropdown-menu> | |||
|             </el-dropdown> --> | |||
| 
 | |||
|             <!-- 批量 --> | |||
|             <el-dropdown @command="handleCommandChecked"> | |||
|               <el-button split-button size="small" type="primary" :disabled="currentTableList.length === 0"> | |||
|                 <span class="el-dropdown-link"> | |||
|                   批量操作 | |||
|                 </span> | |||
|               </el-button> | |||
|               <el-dropdown-menu slot="dropdown"> | |||
|                 <el-dropdown-item command="export">导出</el-dropdown-item> | |||
|                 <el-dropdown-item command="remove">移除</el-dropdown-item> | |||
|                 <el-dropdown-item command="group">分组</el-dropdown-item> | |||
|               </el-dropdown-menu> | |||
|             </el-dropdown> | |||
|             <!-- 全部 --> | |||
|             <el-dropdown @command="handleCommandAll"> | |||
|               <el-button split-button size="small" type="primary"> | |||
|                 <span class="el-dropdown-link"> | |||
|                   全部操作 | |||
|                 </span> | |||
|               </el-button> | |||
|               <el-dropdown-menu slot="dropdown"> | |||
|                 <el-dropdown-item command="export">导出</el-dropdown-item> | |||
|                 <el-dropdown-item command="remove">移除</el-dropdown-item> | |||
|                 <el-dropdown-item command="group">分组</el-dropdown-item> | |||
|               </el-dropdown-menu> | |||
|             </el-dropdown> | |||
|           </div> | |||
|         </checked-footer> | |||
|       </div> | |||
|     </div> | |||
| 
 | |||
|     <!-- 分组 --> | |||
|     <el-dialog | |||
|       title="提示" | |||
|       :visible.sync="dialogVisible_group" | |||
|       width="30%" | |||
|     > | |||
|       <div> | |||
|         <el-select v-model="dialogGroup.groupSelect" placeholder="请选择"> | |||
|           <el-option | |||
|             v-for="item in c_groupList" | |||
|             :key="item.id" | |||
|             :label="item.name" | |||
|             :value="item.id" | |||
|           /> | |||
|         </el-select> | |||
|       </div> | |||
|       <span slot="footer" class="dialog-footer"> | |||
|         <el-button @click="dialogVisible_group = false">取 消</el-button> | |||
|         <el-button type="primary" @click="handleGroup_OK">确 定</el-button> | |||
|       </span> | |||
|     </el-dialog> | |||
| 
 | |||
|     <!-- 详情页 --> | |||
|     <el-dialog | |||
|       class="dialog-360" | |||
|       :visible.sync="dialogVisible" | |||
|       :title="'患者360'" | |||
|       :close-on-click-modal="false" | |||
|       :close-on-press-escape="false" | |||
|       :fullscreen="true" | |||
|       append-to-body | |||
|     > | |||
|       <patient-view | |||
|         v-if="dialogVisible" | |||
|         ref="detailView" | |||
|         :patient-id-number="patient.patientIdNumber" | |||
|         :project-id="patient.projectId" | |||
|         :is-subject="true" | |||
|       /> | |||
|     </el-dialog> | |||
| 
 | |||
|     <!-- 添加分组弹框 --> | |||
|     <el-dialog title="添加分组" :visible.sync="dialogFormVisible" @close="CloseDialog"> | |||
|       <el-form ref="addGroupRuleForm" :model="formGroup" :rules="addGroupRules" @submit.native.prevent> | |||
|         <el-form-item label="分组名称" label-width="120px" prop="name"> | |||
|           <el-input v-model="formGroup.name" /> | |||
|         </el-form-item> | |||
|         <el-form-item label="分组描述" label-width="120px"> | |||
|           <el-input v-model="formGroup.description" /> | |||
|         </el-form-item> | |||
|       </el-form> | |||
|       <div slot="footer" class="dialog-footer"> | |||
|         <el-button @click="dialogFormVisible = false">取 消</el-button> | |||
|         <el-button v-if="sureShow == true" type="primary" @click="sureSubjectGroupClick(1)">确 定</el-button> | |||
|         <el-button v-else type="primary" @click="sureSubjectGroupClick(2)">修 改</el-button> | |||
|       </div> | |||
|     </el-dialog> | |||
| 
 | |||
|     <!-- 导出数据指标 --> | |||
|     <el-dialog title="导出数据" :visible.sync="dialogExportVisible" append-to-body> | |||
|       <el-form> | |||
|         <el-form-item label="指标"> | |||
|           <kpi-select v-if="dialogExportVisible" v-model="kpiList" style="width:100%" :type="4" /> | |||
|         </el-form-item> | |||
|         <el-form-item label="设备过滤"> | |||
|           <device-select | |||
|             v-if="dialogExportVisible" | |||
|             v-model="deviceIdList" | |||
|             style="width:100%" | |||
|             :placeholder="'选择设备后,将过滤相关项目数据'" | |||
|             @change="deviceChangeHandle" | |||
|           /> | |||
|         </el-form-item> | |||
|       </el-form> | |||
|       <span slot="footer" class="dialog-footer"> | |||
|         <el-button @click="dialogExportVisible = false">取 消</el-button> | |||
|         <el-button type="primary" @click="exportOK()">确 定</el-button> | |||
|       </span> | |||
|     </el-dialog> | |||
|   </div> | |||
| </template> | |||
| <script> | |||
| import checked from '@/mixins/checked' | |||
| import patientView from '@/components/patient-view' | |||
| import checkedFooter from '@/components/checked-footer' | |||
| import kpiSelect from '@/components/kpi-select' | |||
| import deviceSelect from '@/components/device-select' | |||
| import { confirm } from '@/utils/confirm' | |||
| import { formatDate } from '@/utils/index.js' | |||
| 
 | |||
| export default { | |||
|   components: { patientView, checkedFooter, kpiSelect, deviceSelect }, | |||
|   mixins: [checked], | |||
|   data() { | |||
|     return { | |||
|       inputSearchValue: '', | |||
|       dataList: [], | |||
|       cheackAllFooter: false, | |||
|       dialogVisible: false, | |||
|       dialogVisible_group: false, | |||
|       dialogGroup: { | |||
|         groupSelect: '', | |||
|         type: '' | |||
|       }, | |||
|       dialogFormVisible: false, | |||
|       dialogExportVisible: false, | |||
|       tabelLoading: false, | |||
|       currentTableList: [], | |||
|       limit: 10, | |||
|       page: 1, | |||
|       projectId: window.SITE_CONFIG['projectId'], | |||
|       total: 0, | |||
|       groupList: [ | |||
|         // { name: '全部', id: '' }, | |||
|         // { name: '未分组', id: 0 } | |||
|       ], | |||
|       groupListAll: {}, | |||
|       addGroupRules: { | |||
|         name: [ | |||
|           { required: true, message: '请输入分组名称', trigger: 'blur' } | |||
|         ] | |||
|       }, | |||
|       formGroup: { | |||
|         name: '', | |||
|         description: '', | |||
|         projectId: window.SITE_CONFIG['projectId'], | |||
|         id: '' | |||
|       }, | |||
|       sureShow: true, | |||
|       currentIndex: 0, | |||
|       groupId: '', | |||
|       detailId: '', | |||
|       patientIdNumber: '', | |||
|       activeTab: '', | |||
|       kpiList: [], | |||
|       deviceIdList: [], | |||
|       deviceSelectItemList: [], | |||
|       checkList: [], | |||
| 
 | |||
|       patient: { | |||
|         patientIdNumber: '', | |||
|         projectId: '' | |||
|       } | |||
| 
 | |||
|     } | |||
|   }, | |||
|   computed: { | |||
|     c_groupList() { | |||
|       return this.groupList.filter(item => item.id !== '' && item.id !== 0) | |||
|     } | |||
|   }, | |||
|   activated() { | |||
|     this.refresh() | |||
|   }, | |||
|   created() { | |||
|     this.getDataList() | |||
|     this.getGroupList() | |||
|   }, | |||
|   mounted() { }, | |||
|   methods: { | |||
| 
 | |||
|     refresh() { | |||
|       this.getGroupList() | |||
|       this.grouplistClick(this.groupId, this.currentIndex) | |||
|     }, | |||
|     // 查看详情 | |||
|     showDetail(row) { | |||
|       // console.log(row) | |||
|       this.dialogVisible = true | |||
|       this.patient.patientIdNumber = row.patientIdNumber | |||
|       this.patient.projectId = this.projectId | |||
|     }, | |||
|     // 点击分组列表 | |||
|     grouplistClick(id, index) { | |||
|       this.groupId = id | |||
|       this.currentIndex = index | |||
|       this.page = 1 | |||
|       this.getDataList() | |||
|     }, | |||
|     // 获取受试者分组里的列表 右侧 | |||
|     getDataList() { | |||
|       this.tabelLoading = true | |||
|       this.$http.get('/project/patient/page', { | |||
|         params: { | |||
|           limit: this.limit, | |||
|           page: this.page, | |||
|           projectId: this.formGroup.projectId, | |||
|           patientName: this.inputSearchValue, // 受试者姓名 | |||
|           groupId: this.groupId // 分组id | |||
|         } | |||
|       }).then(({ data: res }) => { | |||
|         this.dataList = res.data.list | |||
|         this.total = res.data.total | |||
|         this.tabelLoading = false | |||
|       }).catch(() => { this.tabelLoading = false }) | |||
|     }, | |||
|     // 移出受试者 | |||
|     deleteSubjectClick(id) { | |||
|       this.deleteSubjectFun([id]) | |||
|     }, | |||
|     // 批量移出受试者 | |||
|     batchDeleteSubjectClick() { | |||
|       this.deleteSubjectFun(this.currentTableList.map(item => item.id)) | |||
|     }, | |||
|     // 移除受试者封装 | |||
|     deleteSubjectFun(ids) { | |||
|       confirm('您确定要移除此受试者吗?').then(async() => { | |||
|         this.$http({ | |||
|           method: 'delete', | |||
|           url: '/project/patient', | |||
|           data: ids | |||
|         }).then(({ data: res }) => { | |||
|           this.$message.success('删除成功!') | |||
|           this.refresh() | |||
|         }) | |||
|       }) | |||
|     }, | |||
|     // 移除全部受试者 | |||
|     deleteSubjectAll() { | |||
|       confirm('您确定要移除所有受试者吗?').then(async() => { | |||
|         this.$http.delete('/project/patient/' + this.projectId).then(({ data: res }) => { | |||
|           this.$message.success('删除成功!') | |||
|           this.visible = false | |||
|           this.refresh() | |||
|         }) | |||
|       }) | |||
|     }, | |||
|     // 移除此分组 | |||
|     deleteGroupClick(scopeRow) { | |||
|       const patientList = [{ | |||
|         hospitalCode: scopeRow.hospitalCode, | |||
|         patientId: scopeRow.patientId | |||
|       }] | |||
|       this.deleteGroupFun(patientList) | |||
|     }, | |||
|     // 批量移除分组 | |||
|     batchDeleteGroupClick() { | |||
|       this.deleteGroupFun(this.currentTableList) | |||
|     }, | |||
|     // 移除此分组封装 | |||
|     deleteGroupFun(patientList) { | |||
|       confirm('您确定要移除此分组吗').then(async() => { | |||
|         this.$http.post('/patient/group/removeGroup', { | |||
|           groupId: this.groupId, | |||
|           patientList: patientList | |||
|         }).then(({ data: res }) => { | |||
|           this.$message.success('删除成功!') | |||
|           this.refresh() | |||
|         }) | |||
|       }) | |||
|     }, | |||
|     // 添加分组按钮 | |||
|     addGroupClick() { | |||
|       this.dialogFormVisible = true | |||
|       this.sureShow = true | |||
|     }, | |||
|     // 获取分组左侧列表 | |||
|     getGroupList() { | |||
|       this.$http.get('/group/getList', { | |||
|         params: { | |||
|           projectId: this.formGroup.projectId | |||
|         } | |||
|       }).then(({ data: res }) => { | |||
|         this.groupList = [{ name: '全部', id: '' }, { name: '未分组', id: 0 }, ...res.data.list] | |||
|         this.groupListAll = res.data | |||
|       }) | |||
|     }, | |||
|     // 修改编辑分组列表 | |||
|     editGroup(id) { | |||
|       this.dialogFormVisible = true | |||
|       // 根据id获取分组的详细信息 | |||
|       this.$http.get('group', { | |||
|         params: { id: id } | |||
|       }).then(({ data: res }) => { | |||
|         this.formGroup = res.data | |||
|       }) | |||
|     }, | |||
|     // 删除分组列表 | |||
|     deleteGroup(id) { | |||
|       confirm('').then(async() => { | |||
|         this.$http.delete('/group', { | |||
|           params: { id: id } | |||
|         }).then(({ data: res }) => { | |||
|           this.$message.success('删除成功!') | |||
|           this.refresh() | |||
|         }) | |||
|       }) | |||
|     }, | |||
|     // 触发下拉菜单 | |||
|     handleDropdownCommand(id, command) { | |||
|       if (command === '1') { | |||
|         this.sureShow = false | |||
|         this.editGroup(id) | |||
|       } else if (command === '2') { | |||
|         this.deleteGroup(id) | |||
|       } | |||
|     }, | |||
| 
 | |||
|     handleCommandChecked(command) { | |||
|       switch (command) { | |||
|         case 'export': | |||
|           this.handleExport() | |||
|           break | |||
|         case 'remove': | |||
|           this.batchDeleteSubjectClick() | |||
|           break | |||
|         case 'group': | |||
|           this.handleGroup('group') | |||
|           break | |||
|       } | |||
|     }, | |||
|     handleCommandAll(command) { | |||
|       switch (command) { | |||
|         case 'export': | |||
|           this.handleExport() | |||
|           break | |||
|         case 'remove': | |||
|           this.deleteSubjectAll() | |||
|           break | |||
|         case 'group': | |||
|           this.handleGroup('all') | |||
|           break | |||
|       } | |||
|     }, | |||
|     // 分组 | |||
|     handleGroup(type) { | |||
|       this.dialogVisible_group = true | |||
|       this.dialogGroup.type = type | |||
|     }, | |||
|     handleGroup_OK() { | |||
|       this.$http.post('/patient/group', { | |||
|         groupId: this.dialogGroup.groupSelect, | |||
|         patientList: this.dialogGroup.type === 'group' ? this.currentTableList : [] | |||
|       }).then(({ data: res }) => { | |||
|         this.$message.success(this.dialogGroup.type === 'group' ? '批量分组成功!' : '全部分组成功!') | |||
|         this.dialogVisible_group = false | |||
|         this.dialogGroup.type = '' | |||
|         this.refresh() | |||
|       }) | |||
|     }, | |||
|     // 确定受试者分组 | |||
|     sureSubjectGroupClick(num) { | |||
|       this.$refs.addGroupRuleForm.validate(async(valid) => { | |||
|         if (valid) { | |||
|           this.$http({ | |||
|             method: num === 1 ? 'post' : 'put', | |||
|             url: '/group', | |||
|             data: this.formGroup | |||
|           }).then(({ data: res }) => { | |||
|             this.$message.success('操作成功!') | |||
|             this.dialogFormVisible = false | |||
|             this.refresh() | |||
|           }) | |||
|         } else { | |||
|           console.log('error submit!!') | |||
|           return false | |||
|         } | |||
|       }) | |||
|     }, | |||
|     btnExportClick() { | |||
|       this.handleExport() | |||
|     }, | |||
|     handleExport() { | |||
|       this.dialogExportVisible = true | |||
|       if (this.kpiList.length === 0 && window.SITE_CONFIG['projectInfo']) { | |||
|         this.kpiList = window.SITE_CONFIG['projectInfo'].kpiList || [] | |||
|       } | |||
|     }, | |||
|     // 点击导出按钮 | |||
|     exportOK() { | |||
|       this.dialogExportVisible = false | |||
|       this.exportExecl() | |||
|     }, | |||
|     // 导出execl | |||
|     exportExecl() { | |||
|       const patientIdNumbers = [] | |||
|       this.currentTableList.forEach(item => { | |||
|         patientIdNumbers.push(item.patientIdNumber) | |||
|       }) | |||
| 
 | |||
|       // if (patientIdNumbers.length === 0) { | |||
|       //   return this.$message.error('请勾选需要导出的患者!') | |||
|       // } | |||
|       if (this.kpiList.length === 0) { | |||
|         return this.$message.error('请勾选需要导出的指标!') | |||
|       } | |||
| 
 | |||
|       const loading = this.$loading({ | |||
|         lock: true, | |||
|         text: '导出数据生成中,请稍等...', | |||
|         spinner: 'el-icon-loading', | |||
|         background: 'rgba(0, 0, 0, 0.7)', | |||
|         customClass: 'export-loading' | |||
|       }) | |||
|       this.$http.post('/project/patient/exportPatient', | |||
|         { | |||
|           patientIdNumbers: patientIdNumbers, | |||
|           tableDictIds: this.kpiList, | |||
|           projectId: this.projectId, | |||
|           deviceList: this.deviceSelectItemList.map(item => { return { dataSource: item.dataSource || item.datSource, deviceId: item.deviceId || item.value } }) | |||
|         }, | |||
|         { | |||
|           responseType: 'blob', | |||
|           timeout: 60000 * 10 | |||
|         } | |||
|       ).then(({ data: res }) => { | |||
|         loading.close() | |||
|         const link = document.createElement('a') | |||
|         // 第一个参数是后台返回的文件流变量,第二个参数是要转换的类型,由type的值来决定。 | |||
|         const blob = new Blob([res], { type: 'application/zip' }) | |||
|         link.style.display = 'none' | |||
|         link.href = URL.createObjectURL(blob) | |||
|         link.setAttribute('download', `数据导出_${formatDate(new Date(), 'yyyy-MM-dd')}_${this.$store.state.user.realName}`) | |||
|         document.body.appendChild(link) | |||
|         link.click() | |||
|         document.body.removeChild(link) | |||
|         this.checkList = [] | |||
|         // this.$refs.multipleTable.clearSelection() | |||
|       }).catch((error) => { | |||
|         this.$message.error(error) | |||
|         loading.close() | |||
|       }) | |||
|     }, | |||
| 
 | |||
|     // MessageBox 关闭前的回调,会暂停实例的关闭 | |||
|     CloseDialog() { | |||
|       this.formGroup.name = '' | |||
|       this.formGroup.description = '' | |||
|     }, | |||
|     // 分页, 当前页 | |||
|     pageCurrentChangeHandle(val) { | |||
|       this.page = val | |||
|       this.getDataList() | |||
|     }, | |||
|     // 分页, 每页条数 | |||
|     pageSizeChangeHandle(val) { | |||
|       this.page = 1 | |||
|       this.limit = val | |||
|       this.getDataList() | |||
|     }, | |||
|     // 分组下拉菜单 | |||
|     async handleGroupCommand(e) { | |||
|       this.$http.post('/patient/group', { | |||
|         groupId: e, | |||
|         patientList: this.currentTableList | |||
|       }).then(({ data: res }) => { | |||
|         this.$message.success('分组成功!') | |||
|         this.refresh() | |||
|       }) | |||
|     }, | |||
|     deviceChangeHandle(val) { | |||
|       this.deviceSelectItemList = val | |||
|     } | |||
|   } | |||
| } | |||
| </script> | |||
| <style lang='scss' scoped> | |||
| .subject-management { | |||
|   display: flex; | |||
|   .subject-left { | |||
|     min-width: 240px; | |||
|     background-color: #fff; | |||
|     margin-right: 10px; | |||
|     height: calc(calc(100vh - 50px - 38px - 80px)); | |||
|     .photo-groups, | |||
|     .group-list { | |||
|       display: flex; | |||
|       justify-content: space-between; | |||
|       align-items: center; | |||
|       padding-left: 24px; | |||
|       padding-right: 16px; | |||
|       color: #000; | |||
|     } | |||
|     .photo-groups { | |||
|       height: 48px; | |||
|       font-size: 16px; | |||
|       font-weight: 700; | |||
|       .el-icon-circle-plus { | |||
|         cursor: pointer; | |||
|         color: #1e79ff; | |||
|         font-size: 24px; | |||
|       } | |||
|     } | |||
|     .group-list { | |||
|       height: 32px; | |||
|       line-height: 32px; | |||
|       font-size: 14px; | |||
|       .el-icon-more { | |||
|         transform: rotate(90deg); | |||
|       } | |||
|       .dropdown-right { | |||
|         .number { | |||
|           padding-right: 10px; | |||
|         } | |||
|       } | |||
|     } | |||
|     .group-list-active { | |||
|       background-color: #1890ff; | |||
|       color: #fff; | |||
|       .el-icon-more { | |||
|         color: #fff; | |||
|       } | |||
|     } | |||
|     // .group-list:hover { | |||
|     //   background-color: #eee; | |||
|     // } | |||
|   } | |||
|   .subject-right { | |||
|     flex: 1; | |||
|     background-color: #fff; | |||
|     padding: 16px 10px; | |||
|   } | |||
|   .input-search { | |||
|     display: flex; | |||
|   } | |||
|   .people-list { | |||
|     padding-bottom: 10px; | |||
|     margin-top: 10px; | |||
|     margin-bottom: 50px; | |||
|   } | |||
|   .title { | |||
|     height: 64px; | |||
|     padding-left: 24px; | |||
|     line-height: 64px; | |||
|     font-size: 16px; | |||
|     background-color: #fff; | |||
|     box-shadow: inset 0px -1px 0px #f0f0f0; | |||
|     border-radius: 2px 2px 0px 0px; | |||
|   } | |||
|   .suggest-circle { | |||
|     display: inline-block; | |||
|     width: 6px; | |||
|     height: 6px; | |||
|     border-radius: 50%; | |||
|     margin-right: 8px; | |||
|   } | |||
|   .suggest-circle-green { | |||
|     background-color: #52c41a; | |||
|   } | |||
|   .suggest-circle-red { | |||
|     background-color: #ff4d4f; | |||
|   } | |||
|   .operation-details, | |||
|   .operation-delete { | |||
|     cursor: pointer; | |||
|   } | |||
|   .scroll-father-head { | |||
|     height: 150px; | |||
|   } | |||
| } | |||
| 
 | |||
| .batch_button{ | |||
|   .el-dropdown { | |||
|     margin-left: 15px; | |||
|   } | |||
| } | |||
| </style> | |||
| 
 | |||
| <style lang="scss"> | |||
| .input-search { | |||
|   display: flex; | |||
| 
 | |||
|   .el-icon-d-arrow-right { | |||
|     transform: rotate(-90deg); | |||
|   } | |||
|   .el-dropdown { | |||
|     vertical-align: top; | |||
|   } | |||
|   .el-dropdown { | |||
|     margin-left: 15px; | |||
|   } | |||
|   .el-icon-arrow-down { | |||
|     font-size: 12px; | |||
|   } | |||
| } | |||
| .subject-management .detail-view { | |||
|   .el-dialog { | |||
|     background: #000; | |||
|     overflow: hidden; | |||
|   } | |||
| 
 | |||
|   .el-dialog__header { | |||
|     padding: 10px 20px 10px; | |||
| 
 | |||
|     .el-dialog__title { | |||
|       color: #fff; | |||
|       padding: 10px; | |||
|     } | |||
| 
 | |||
|     .el-dialog__headerbtn { | |||
|       top: 5px; | |||
|       font-size: 30px; | |||
|     } | |||
|     .el-dialog__headerbtn .el-dialog__close { | |||
|       color: #fff; | |||
|     } | |||
|   } | |||
|   .el-dialog__body { | |||
|     height: calc(100vh - 60px); | |||
|     padding: 0 10px; | |||
|   } | |||
| } | |||
| </style> | |||
| @ -1,56 +0,0 @@ | |||
| <template> | |||
|   <div class="subjectManagement"> | |||
|     <el-container style=""> | |||
|       <el-aside width="200px" style="background-color: rgb(238, 241, 246)"> | |||
|         <el-menu :default-openeds="['1', '3']"> | |||
| 
 | |||
|         </el-menu> | |||
|       </el-aside> | |||
|       <el-container> | |||
|         <el-header style="text-align: right; font-size: 12px"> | |||
|           <el-dropdown> | |||
|             <i class="el-icon-setting" style="margin-right: 15px" /> | |||
|             <el-dropdown-menu slot="dropdown"> | |||
|               <el-dropdown-item>查看</el-dropdown-item> | |||
|               <el-dropdown-item>新增</el-dropdown-item> | |||
|               <el-dropdown-item>删除</el-dropdown-item> | |||
|             </el-dropdown-menu> | |||
|           </el-dropdown> | |||
|           <span>王小虎</span> | |||
|         </el-header> | |||
| 
 | |||
|         <el-main> | |||
|           <el-table :data="tableData"> | |||
|             <el-table-column prop="date" label="日期" width="140" /> | |||
|             <el-table-column prop="name" label="姓名" width="120" /> | |||
|             <el-table-column prop="address" label="地址" /> | |||
|           </el-table> | |||
|         </el-main> | |||
|       </el-container> | |||
|     </el-container> | |||
|   </div> | |||
| </template> | |||
| 
 | |||
| <script> | |||
| 
 | |||
| export default { | |||
|   components: { | |||
|   }, | |||
|   data() { | |||
|     return { | |||
|     } | |||
|   }, | |||
|   mounted() { | |||
|   }, | |||
|   methods: { | |||
| 
 | |||
|   } | |||
| } | |||
| 
 | |||
| </script> | |||
| <style lang="scss" scoped> | |||
|   .subjectManagement{ | |||
|     width: 100%; | |||
|     height: 100%; | |||
|   } | |||
| </style> | |||
					Loading…
					
					
				
		Reference in new issue