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> | <template> | ||||
|   <div class="first-visit"> |   <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> |     </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> |     </div> | ||||
|     <!-- 弹窗, 新增 / 修改 --> |  | ||||
| <!--    <follow-up v-if="followUpVisible" ref="followUp" is-first="1" :title="drgsName + '首诊'" @refreshDataList="init()" />--> |  | ||||
|   </div> |   </div> | ||||
| </template> | </template> | ||||
| 
 | 
 | ||||
| <script> | <script> | ||||
| import headTemplate from '@/components/head' | import headTemplate from '@/components/head' | ||||
| const Base64 = require('js-base64').Base64 |  | ||||
| export default { | export default { | ||||
|   inject: ['refresh'], |  | ||||
|  |   name: 'CornealReview', | ||||
|   components: { |   components: { | ||||
|     headTemplate |     headTemplate | ||||
|     // followUp |  | ||||
|   }, |  | ||||
|   mixins: [], |  | ||||
|   props: { |  | ||||
|     patientId: { |  | ||||
|       type: String, |  | ||||
|       default: '' |  | ||||
|     } |  | ||||
|   }, |   }, | ||||
|   data() { |   data() { | ||||
|     return { |     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: { |   methods: { | ||||
|     // 打印 |  | ||||
|     printerHandle() { |  | ||||
|       this.$refs.crfComponent.$el.contentWindow.print() |  | ||||
|  |     saveCheckData() { | ||||
|  |       console.log(this.formData) | ||||
|     } |     } | ||||
|   } |   } | ||||
| } | } | ||||
| </script> | </script> | ||||
|  | 
 | ||||
| <style lang="scss" scoped> | <style lang="scss" scoped> | ||||
| .first-visit{ | .first-visit{ | ||||
|   .head { |  | ||||
|     padding-bottom: 0px; |  | ||||
|  |   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; | ||||
| } | } | ||||
|   .printer { |  | ||||
|  | .el-date-editor.el-input, .el-date-editor.el-input__inner{ | ||||
|  |   width: 100%; | ||||
|  | } | ||||
|  | .cornealTable{ | ||||
|  |   width: 100%; | ||||
|  |   tr td{ | ||||
|     border: 1px solid #ccc; |     border: 1px solid #ccc; | ||||
|     width: 56px; |  | ||||
|     height: 32px; |  | ||||
|     border-radius: 3px; |  | ||||
|     margin: 0; |  | ||||
|     margin-left: 10px; |  | ||||
|  |     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; |       cursor: pointer; | ||||
|  |       user-select: none; | ||||
|  |       word-break: keep-all; | ||||
|  |       margin-right: 20px; | ||||
|     } |     } | ||||
|   .tips { |  | ||||
|     color: #ff4d4f; |  | ||||
|     margin-bottom: 6px; |  | ||||
|   } |   } | ||||
|   .first-visit-content { |  | ||||
|     min-width: 960px; |  | ||||
|     height: calc(100vh - 50px - 32px - 42px - 54px - 32px); |  | ||||
|     padding: 16px; |  | ||||
|     background: #ededed; |  | ||||
|     text-align: center; |  | ||||
|  | } | ||||
|  | .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%; | ||||
|  |   } | ||||
|  | 
 | ||||
|  |   .notice_tip{ | ||||
|  |     height: 100%; | ||||
|  |     overflow-y: auto; | ||||
|  |     border: 1px solid #000; | ||||
|  |     padding: 64px 32px; | ||||
|  |     margin-right: 16px; | ||||
|   } |   } | ||||
| } | } | ||||
| </style> | </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