134 changed files with 53 additions and 67360 deletions
			
			
		| @ -1,2 +0,0 @@ | |||
| NODE_ENV=development | |||
| VUE_APP_NODE_ENV=dev | |||
| @ -1,2 +0,0 @@ | |||
| NODE_ENV=localhost | |||
| VUE_APP_NODE_ENV=local | |||
| @ -1,2 +0,0 @@ | |||
| NODE_ENV=production | |||
| VUE_APP_NODE_ENV=prod | |||
| @ -1,2 +0,0 @@ | |||
| NODE_ENV=production | |||
| VUE_APP_NODE_ENV=staging | |||
| @ -1,72 +0,0 @@ | |||
| <template> | |||
|   <div class="bread"> | |||
|     <div class="example-container"> | |||
|       <el-breadcrumb separator="/"> | |||
|         <el-breadcrumb-item | |||
|           v-for="(item,index) in breadList" | |||
|           :key="index" | |||
|           :to="item.name.includes('seeDoctor') ? item.path + '?info=' + queryList.info : item.path" | |||
|           @click.native="breadcrumbClick(item)" | |||
|         >{{ item.meta.title }}</el-breadcrumb-item> | |||
|       </el-breadcrumb> | |||
|     </div> | |||
|   </div> | |||
| </template> | |||
| <script> | |||
| export default { | |||
|   data() { | |||
|     return { | |||
|       breadList: [], // 路由集合, | |||
|       userData: {}, | |||
|       queryList: {} | |||
|     } | |||
|   }, | |||
|   watch: { | |||
|     $route() { | |||
|       this.getBreadcrumb() | |||
|     } | |||
|   }, | |||
|   created() { | |||
|     this.userData = window.sessionStorage.getItem('qg-userData') | |||
|     this.getBreadcrumb() | |||
|   }, | |||
|   methods: { | |||
|     getBreadcrumb() { | |||
|       const matched = this.$route.matched | |||
|       // 浏览器参数点击面包屑传回给seeDoctor页面 | |||
|       if (this.$route.name === 'templateManagement') { | |||
|         this.queryList = this.$route.query | |||
|       } | |||
|       matched.forEach((item, i) => { | |||
|         if (item.meta.title === '首页' && item.redirect && item.redirect.name) { | |||
|           item.name = 'outpatientManagement' | |||
|           item.path = '/outpatientManagement-call' | |||
|           item.meta.title = '首页' | |||
|         } | |||
|       }) | |||
|       this.breadList = matched | |||
|     }, | |||
|     breadcrumbClick(item) { | |||
|       console.log(item) | |||
|       if (item.meta.title === '首页') { | |||
|         this.$store.commit('activeIndexFun', window.SITE_CONFIG.menuList[0].children[0].id) | |||
|       } | |||
|     } | |||
|   } | |||
| } | |||
| </script> | |||
| <style scoped> | |||
| .bread  /deep/ .el-breadcrumb{ | |||
|   display: inline-block; | |||
|   display: inline-block; | |||
|   height: 50px; | |||
|   vertical-align: top; | |||
|   line-height: 50px; | |||
| } | |||
| .bread /deep/ .is-link{ | |||
|   font-weight: normal; | |||
| } | |||
| .bread{ | |||
|   float:left; | |||
| } | |||
| </style> | |||
| @ -1,58 +0,0 @@ | |||
| <template> | |||
|   <div :class="['footer',{'footer-left':$store.state.sidebarFold}]"> | |||
|     <div class="footer-left"> | |||
|       <el-checkbox | |||
|         v-model="cheackAllFooter" | |||
|         label="全选" | |||
|         @change="cheackAllChange(tableRef)" | |||
|       /> | |||
|       <el-link | |||
|         :underline="true" | |||
|         @click="cheackReverseClick(tableRef)" | |||
|       >反选</el-link> | |||
|     </div> | |||
|     <div class="footer-right"> | |||
|       <div class="checkNum_cancel"> | |||
|         <span class="checked"> | |||
|           已选 | |||
|           <span class="number">{{ currentTableList.length }}</span> | |||
|           项 | |||
|         </span> | |||
|         <span class="cancel" @click="cancelClick(tableRef)">取消</span> | |||
|       </div> | |||
|       <div class="batch_button"> | |||
|         <slot /> | |||
|       </div> | |||
|     </div> | |||
|   </div> | |||
| </template> | |||
| <script> | |||
| import checked from '@/mixins/checked' | |||
| export default { | |||
|   mixins: [checked], | |||
|   props: { | |||
|     dataList: { | |||
|       type: Array, | |||
|       default: () => [] | |||
|     }, | |||
|     currentTableList: { | |||
|       type: Array, | |||
|       default: () => [] | |||
|     }, | |||
|     tableRef: { | |||
|       type: String, | |||
|       default: '' | |||
|     } | |||
|   }, | |||
|   data() { | |||
|     return { | |||
|       cheackAllFooter: false | |||
|     } | |||
|   }, | |||
|   methods: { | |||
|   } | |||
| } | |||
| </script> | |||
| 
 | |||
| <style lang="scss" scoped> | |||
| </style> | |||
| @ -1,41 +0,0 @@ | |||
| <template> | |||
|   <el-select | |||
|     :value="value" | |||
|     :placeholder="placeholder" | |||
|     :multiple="multiple" | |||
|     clearable | |||
|     filterable | |||
|     style="width:100%;" | |||
|     @change="$emit('input', $event)" | |||
|   > | |||
|     <el-option | |||
|       v-for="item in dataList" | |||
|       :key="item.id" | |||
|       :label="item.name" | |||
|       :value="item.id" | |||
|     /> | |||
|   </el-select> | |||
| </template> | |||
| <script> | |||
| export default { | |||
|   props: { | |||
|     value: { type: String, default: '' }, | |||
|     multiple: { type: Boolean, default: false }, | |||
|     placeholder: { type: String, default: '请选择' } | |||
|   }, | |||
|   data() { | |||
|     return { | |||
|       dataList: [] | |||
|     } | |||
|   }, | |||
|   mounted() { this.getDataList() }, | |||
|   methods: { | |||
|     getDataList(id) { | |||
|       // /sys/user/getDeptList4AddUser | |||
|       return this.$http.get('/sys/dept/list?type=1').then(({ data: res }) => { | |||
|         if (res.code === 0) { this.dataList = res.data } else { this.$message.error(res.msg) } | |||
|       }).catch(() => {}) | |||
|     } | |||
|   } | |||
| } | |||
| </script> | |||
| @ -1,40 +0,0 @@ | |||
| <template> | |||
|   <el-select | |||
|     :value="value" | |||
|     :placeholder="placeholder" | |||
|     :multiple="multiple" | |||
|     clearable | |||
|     filterable | |||
|     style="width:100%;" | |||
|     @change="$emit('input', $event)" | |||
|   > | |||
|     <el-option | |||
|       v-for="item in dataList" | |||
|       :key="item.id" | |||
|       :label="item.name" | |||
|       :value="item.id" | |||
|     /> | |||
|   </el-select> | |||
| </template> | |||
| <script> | |||
| export default { | |||
|   props: { | |||
|     value: { type: Array, default: () => [] }, | |||
|     multiple: { type: Boolean, default: false }, | |||
|     placeholder: { type: String, default: '请选择' } | |||
|   }, | |||
|   data() { | |||
|     return { | |||
|       dataList: [] | |||
|     } | |||
|   }, | |||
|   mounted() { this.getDataList() }, | |||
|   methods: { | |||
|     getDataList(id) { | |||
|       return this.$http.get('/device/project/getList').then(({ data: res }) => { | |||
|         if (res.code === 0) { this.dataList = res.data } else { this.$message.error(res.msg) } | |||
|       }).catch(() => {}) | |||
|     } | |||
|   } | |||
| } | |||
| </script> | |||
| @ -1,145 +0,0 @@ | |||
| <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> | |||
| @ -1,129 +0,0 @@ | |||
| <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('/project/crf/template/' + 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: rgba(193, 193, 193, 0.2); | |||
| 
 | |||
|       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> | |||
| @ -1,88 +0,0 @@ | |||
| <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> | |||
| @ -1,177 +0,0 @@ | |||
| <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> | |||
| @ -1,194 +0,0 @@ | |||
| <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> | |||
| @ -1,40 +0,0 @@ | |||
| <template> | |||
|   <el-select | |||
|     :value="value" | |||
|     :placeholder="placeholder" | |||
|     :multiple="multiple" | |||
|     clearable | |||
|     filterable | |||
|     style="width:100%;" | |||
|     @change="$emit('input', $event)" | |||
|   > | |||
|     <el-option | |||
|       v-for="item in dataList" | |||
|       :key="item.id" | |||
|       :label="item.name" | |||
|       :value="item.id" | |||
|     /> | |||
|   </el-select> | |||
| </template> | |||
| <script> | |||
| export default { | |||
|   props: { | |||
|     value: { type: Array, default: () => [] }, | |||
|     multiple: { type: Boolean, default: false }, | |||
|     placeholder: { type: String, default: '请选择' } | |||
|   }, | |||
|   data() { | |||
|     return { | |||
|       dataList: [] | |||
|     } | |||
|   }, | |||
|   mounted() { this.getDataList() }, | |||
|   methods: { | |||
|     getDataList(id) { | |||
|       return this.$http.get('/checkItem/project/getList').then(({ data: res }) => { | |||
|         if (res.code === 0) { this.dataList = res.data } else { this.$message.error(res.msg) } | |||
|       }).catch(() => {}) | |||
|     } | |||
|   } | |||
| } | |||
| </script> | |||
| @ -1,102 +0,0 @@ | |||
| <template> | |||
|   <div class="flex-container"> | |||
|     <div class="file-list"> | |||
|       <el-table :data="fileList" style="width: 100%" highlight-current-row @row-click="rowClick"> | |||
|         <el-table-column label="文件列表"> | |||
|           <template slot-scope="scope"> | |||
|             <span style="margin-left: 10px">{{ scope.row.name|f_fileName }}</span> | |||
|           </template> | |||
|         </el-table-column> | |||
|       </el-table> | |||
|     </div> | |||
|     <div class="file-show"> | |||
|       <template v-if="isImg(activeFile.url)"> | |||
|         <el-image :fit="'fill'" :src="activeFile.url" /> | |||
|       </template> | |||
|       <template v-if="isPdf(activeFile.url)"> | |||
|         <pdf :src="activeFile.url" /> | |||
|       </template> | |||
|     </div> | |||
|   </div> | |||
| </template> | |||
| 
 | |||
| <script> | |||
| import pdf from 'vue-pdf' | |||
| 
 | |||
| export default { | |||
|   components: { | |||
|     pdf | |||
|   }, | |||
|   filters: { | |||
|     f_fileName(val) { | |||
|       return val.substring(0, val.lastIndexOf('-')) | |||
|     }, | |||
|     f_url(val) { | |||
|       return `${window.SITE_CONFIG['apiURL']}/upload/${val}` | |||
|     } | |||
|   }, | |||
|   props: { | |||
|     fileList: { type: Array, required: true } | |||
|   }, | |||
|   data() { | |||
|     return { | |||
|       activeFile: {} | |||
|     } | |||
|   }, | |||
|   watch: { | |||
|     fileList: { | |||
|       immediate: true, | |||
|       handler(val) { | |||
|         this.activeFile = this.fileList[0] || {} | |||
|       } | |||
|     } | |||
|   }, | |||
|   mounted() { | |||
|     this.$nextTick(() => { | |||
|     }) | |||
|   }, | |||
|   methods: { | |||
|     fileType(url) { | |||
|       return url ? url.substring(url.lastIndexOf('.') + 1) : '' | |||
|     }, | |||
|     isImg(url) { | |||
|       const type = this.fileType(url) | |||
|       return ['png', 'jpg', 'jpeg', 'bmp'].indexOf(type.toLowerCase()) >= 0 | |||
|     }, | |||
|     isPdf(url) { | |||
|       const type = this.fileType(url) | |||
|       return ['pdf'].indexOf(type.toLowerCase()) >= 0 | |||
|     }, | |||
|     rowClick(row) { | |||
|       this.activeFile = row | |||
|     } | |||
|   } | |||
| 
 | |||
| } | |||
| </script> | |||
| 
 | |||
| <style lang="scss" scoped> | |||
| .flex-container { | |||
|     display: flex; | |||
|     width: 100%; | |||
|     height: 100%; | |||
|     // height: 500px; | |||
| } | |||
| .file-list{ | |||
|     // display:flex; | |||
|     width: 200px; | |||
|     height: 100%; | |||
|     margin-right: 20px; | |||
| 
 | |||
|     .file-item{ | |||
|         display: block; | |||
|     } | |||
| } | |||
| 
 | |||
| .file-show{ | |||
|     // display:flex; | |||
|     width: calc(100% - 220px); | |||
|     height: 100%; | |||
|     border:1px solid; | |||
| } | |||
| </style> | |||
| @ -1,224 +0,0 @@ | |||
| <template> | |||
|   <div class="component-container"> | |||
|     <span class="title">{{ title }}</span> | |||
|     <div v-for="(queryItem,queryIndex) in queryItemList" :key="queryIndex" class="query-item-wrapper"> | |||
|       <!-- 关系(或,与,非) --> | |||
|       <div :class="{disvisible:queryIndex==0}" class="query-item"> | |||
|         <el-select v-model="queryItem.connection" filterable placeholder="" style="width:80px"> | |||
|           <el-option | |||
|             v-for="(itemRel,indexRel) in dictRel" | |||
|             :key="indexRel" | |||
|             :label="itemRel.name" | |||
|             :value="itemRel.value" | |||
|           /> | |||
|         </el-select> | |||
|       </div> | |||
|       <!-- 查询字段 --> | |||
|       <div class="query-item"> | |||
|         <el-select v-model="queryItem.fieldItem" filterable placeholder="检索字段" @change="clickHandle_fieldName(queryItem)"> | |||
|           <!-- axios获取列表 --> | |||
|           <el-option-group | |||
|             v-for="(groupItem,groupIndex) in dataListDemo" | |||
|             :key="groupIndex" | |||
|             :label="groupItem.tableDescription" | |||
|             class="select-group" | |||
|           > | |||
|             <el-option | |||
|               v-for="(fieldItem,fieldIndex) in groupItem.fieldList" | |||
|               :key="fieldIndex" | |||
|               :label="fieldItem.fieldDescription" | |||
|               :value="fieldItem" | |||
|             /> | |||
|           </el-option-group> | |||
|         </el-select> | |||
|       </div> | |||
|       <!-- 检索类型:匹配、精准匹配、范围查询 --> | |||
|       <div class="query-item"> | |||
|         <el-select v-model="queryItem.queryType" placeholder="" style="width:100px"> | |||
|           <el-option | |||
|             v-for="(item,index) in dictQuery" | |||
|             :key="index" | |||
|             :label="item.name" | |||
|             :value="item.value" | |||
|           /> | |||
|         </el-select> | |||
|       </div> | |||
|       <!-- 查询内容 --> | |||
|       <!-- 范围 --> | |||
|       <div v-if="queryItem.queryType=='number'" class="query-item"> | |||
|         <!-- dictLogicValueGt --> | |||
|         <el-select style="width:100px"> | |||
|           <el-option label=">" value="gt" /> | |||
|           <el-option label=">=" value="gte" /> | |||
|         </el-select> | |||
|         <el-input-number v-model="queryItem.queryValue1" controls-position="right" /> | |||
|         <!-- dictLogicValueLt --> | |||
|         <el-select style="width:100px"> | |||
|           <el-option label="<" value="lt" /> | |||
|           <el-option label="<=" value="lte" /> | |||
|         </el-select> | |||
|         <el-input-number v-model="queryItem.queryValue2" controls-position="right" /> | |||
|       </div> | |||
|       <!-- 日期 --> | |||
|       <div v-else-if="queryItem.queryType=='date'" class="query-item"> | |||
|         <!-- dictLogicValueGt --> | |||
|         <el-select style="width:100px"> | |||
|           <el-option label=">" value="gt" /> | |||
|           <el-option label=">=" value="gte" /> | |||
|         </el-select> | |||
|         <el-date-picker v-model="queryItem.queryValue1" type="datetime" /> | |||
|         <!-- dictLogicValueLt --> | |||
|         <el-select style="width:100px"> | |||
|           <el-option label="<" value="lt" /> | |||
|           <el-option label="<=" value="lte" /> | |||
|         </el-select> | |||
|         <el-date-picker v-model="queryItem.queryValue2" type="datetime" /> | |||
|       </div> | |||
|       <!-- 值 --> | |||
|       <div v-else class="query-item"> | |||
|         <!-- dictLogicValueEq --> | |||
|         <el-select v-model="queryItem.queryLogic" style="width:80px"> | |||
|           <!-- <el-option | |||
|             v-for="(item,index) in dictLogicValueEq" | |||
|             :key="index" | |||
|             :label="item.name" | |||
|             :value="item.value" | |||
|           /> --> | |||
|           <el-option label="等于" value="eq" /> | |||
|         </el-select> | |||
|       </div> | |||
|     </div> | |||
|   </div> | |||
| </template> | |||
| 
 | |||
| <script> | |||
| // 关系 | |||
| const dictRel = [ | |||
|   { name: '并且', value: 'must' }, // and | |||
|   { name: '可以', value: 'should' }, // or | |||
|   { name: '排除', value: 'must_not' } // not | |||
| ] | |||
| // 值逻辑 | |||
| const dictLogicValue = [ | |||
|   { name: '等于', value: 'eq' }, // = | |||
|   { name: '小于', value: 'lt' }, // < | |||
|   { name: '小于等于', value: 'lte' }, // <= | |||
|   { name: '大于', value: 'gt' }, // > | |||
|   { name: '大于等于', value: 'gte' } // >= | |||
| ] | |||
| // 检索类型 | |||
| const dictQuery = [ | |||
|   { name: '匹配', value: 'matchQuery' }, | |||
|   { name: '精准匹配', value: 'termQuery' }, | |||
|   { name: '范围查询', value: 'rangeQuery' } | |||
| ] | |||
| 
 | |||
| const dataListDemo = [ | |||
|   { | |||
|     tableDescription: '基础信息', // 表名(注释) | |||
|     tableName: 'REGISTER_PATIENT', // 表名 | |||
|     type: '1', // 1患者信息,2数据查询 | |||
|     fieldList: [ | |||
|       { fieldDescription: '登记号', fieldName: 'patientId', fieldType: 'string' }, | |||
|       { fieldDescription: '年龄', fieldName: 'age', fieldType: 'number' }, | |||
|       { fieldDescription: '出生日期', fieldName: 'birthday', fieldType: 'date' }, | |||
|       { fieldDescription: '地址', fieldName: 'address', fieldType: 'string' } | |||
|     ] | |||
|   }, | |||
|   { | |||
|     tableDescription: '就诊信息', | |||
|     tableName: 'REGISTER_EXAMINE', | |||
|     type: '1', | |||
|     fieldList: [ | |||
|       { fieldDescription: '就诊日期', fieldName: 'registerTime', fieldType: 'date' }, | |||
|       { fieldDescription: '主诉', fieldName: 'complain', fieldType: 'string' }, | |||
|       { fieldDescription: '诊断', fieldName: 'diag', fieldType: 'string' } | |||
|     ] | |||
|   } | |||
| ] | |||
| export default { | |||
|   props: { | |||
|     title: { type: String, required: true }, | |||
|     isGroup: { type: Boolean, default: true }, | |||
|     dataList: { type: Array, required: true } | |||
|   }, | |||
|   data() { | |||
|     return { | |||
|       dictRel: dictRel, | |||
|       dictLogicValue: dictLogicValue, | |||
|       dictQuery: dictQuery, | |||
|       queryItemList: [{ | |||
|         connection: 'must', | |||
|         tableName: '', | |||
|         fieldName: '', | |||
|         fieldItem: undefined, | |||
|         queryType: 'matchQuery', | |||
|         queryValue: { | |||
|           eq: '', | |||
|           lt: '', | |||
|           gt: '', | |||
|           lte: '', | |||
|           gte: '' | |||
|         }, | |||
|         queryLogic: 'eq', // eq,lt,gt,lte,gte | |||
|         queryValue1: '', | |||
|         queryValue2: '' | |||
|       }, { | |||
|         connection: 'must', | |||
|         tableName: '', | |||
|         fieldName: '', | |||
|         fieldItem: undefined, | |||
|         queryType: 'matchQuery', | |||
|         queryLogic: '', | |||
|         queryValue: { | |||
|           eq: '', | |||
|           lt: '', | |||
|           gt: '', | |||
|           lte: '', | |||
|           gte: '' | |||
|         } | |||
|       }], | |||
|       dataListDemo: dataListDemo | |||
|     } | |||
|   }, | |||
|   watch: {}, | |||
|   methods: { | |||
|     clickHandle_fieldName(val) { | |||
|     } | |||
|   } | |||
| } | |||
| </script> | |||
| <style scoped> | |||
| .select-group >>> .el-select-group__title { | |||
|   font-size: 14px; | |||
|   font-weight: 600; | |||
|   color: #409eff; | |||
| } | |||
| </style> | |||
| <style lang='scss' scoped> | |||
| .component-container { | |||
|   padding: 10px; | |||
| 
 | |||
|   .title { | |||
|     display: block; | |||
|     font-size: 16px; | |||
|     font-weight: 600; | |||
|     height: 30px; | |||
|     line-height: 30px; | |||
|     margin: 5px 0px; | |||
|     padding-left: 5px; | |||
|   } | |||
|   .query-item-wrapper { | |||
|     margin-bottom: 10px; | |||
| 
 | |||
|     .query-item { | |||
|       display: inline-block; | |||
|       margin-right: 10px; | |||
|     } | |||
|   } | |||
| } | |||
| 
 | |||
| .disvisible{ | |||
|   visibility: hidden; | |||
| } | |||
| </style> | |||
| @ -1,61 +0,0 @@ | |||
| <template> | |||
|   <div class="head"> | |||
|     <div class="head-left"> | |||
|       <div class="ceshi" /> | |||
|       <span v-show="isShowIcon" class="left-icon" /> | |||
|       <span class="text">{{ headLeft }}</span> | |||
|       <!-- <svg class="icon-svg"> | |||
|         <use xlink:href="#icon-sync" /> | |||
|       </svg> --> | |||
|     </div> | |||
|     <div class="head-right"> | |||
|       <slot /> | |||
|     </div> | |||
|   </div> | |||
| </template> | |||
| <script> | |||
| export default { | |||
|   props: { | |||
|     headLeft: { | |||
|       type: String, | |||
|       default: '' | |||
|     }, | |||
|     isShowIcon: { | |||
|       type: Boolean, | |||
|       default: false | |||
|     } | |||
|   }, | |||
|   data() { | |||
|     return { | |||
|     } | |||
|   }, | |||
|   created() { | |||
|   }, | |||
|   methods: { | |||
|   } | |||
| } | |||
| </script> | |||
| <style lang="scss" scoped> | |||
| .head { | |||
|   display: flex; | |||
|   justify-content: space-between; | |||
|   align-items: center; | |||
|   padding-bottom: 10px; | |||
|   .head-left { | |||
|     .left-icon { | |||
|       display: inline-block; | |||
|       width: 4px; | |||
|       height: 12px; | |||
|       background-color: #1e79ff; | |||
|       border-radius: 25px; | |||
|       margin-right: 6px; | |||
|     } | |||
|     .text { | |||
|       padding-right: 16px; | |||
|     } | |||
|     .icon-svg { | |||
|       color: #1e79ff; | |||
|     } | |||
|   } | |||
| } | |||
| </style> | |||
| @ -1,87 +0,0 @@ | |||
| <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> | |||
| @ -1,49 +0,0 @@ | |||
| <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> | |||
| @ -1,88 +0,0 @@ | |||
| <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> | |||
| @ -1,100 +0,0 @@ | |||
| <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> | |||
| @ -1,239 +0,0 @@ | |||
| <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> | |||
| @ -1,76 +0,0 @@ | |||
| <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> | |||
| @ -1,10 +0,0 @@ | |||
| // 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>' | |||
|   } | |||
| }) | |||
| @ -1,7 +0,0 @@ | |||
| // Exports the "default" icons for usage with module loaders
 | |||
| // Usage:
 | |||
| //   CommonJS:
 | |||
| //     require('tinymce/icons/default')
 | |||
| //   ES2015:
 | |||
| //     import 'tinymce/icons/default'
 | |||
| require('./icons.js') | |||
| @ -1,7 +0,0 @@ | |||
| // Exports the "anchor" plugin for usage with module loaders
 | |||
| // Usage:
 | |||
| //   CommonJS:
 | |||
| //     require('tinymce/plugins/anchor')
 | |||
| //   ES2015:
 | |||
| //     import 'tinymce/plugins/anchor'
 | |||
| require('./plugin.js') | |||
| @ -1,234 +0,0 @@ | |||
| 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() | |||
| }()) | |||
| @ -1,7 +0,0 @@ | |||
| // Exports the "anchor" plugin for usage with module loaders
 | |||
| // Usage:
 | |||
| //   CommonJS:
 | |||
| //     require('tinymce/plugins/anchor')
 | |||
| //   ES2015:
 | |||
| //     import 'tinymce/plugins/anchor'
 | |||
| require('./plugin.js') | |||
| @ -1,366 +0,0 @@ | |||
| /* 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() | |||
| }()) | |||
| @ -1,7 +0,0 @@ | |||
| // Exports the "preview" plugin for usage with module loaders
 | |||
| // Usage:
 | |||
| //   CommonJS:
 | |||
| //     require('tinymce/plugins/preview')
 | |||
| //   ES2015:
 | |||
| //     import 'tinymce/plugins/preview'
 | |||
| require('./plugin.js') | |||
| @ -1,143 +0,0 @@ | |||
| /* 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() | |||
| }()) | |||
| @ -1,7 +0,0 @@ | |||
| // Exports the "anchor" plugin for usage with module loaders
 | |||
| // Usage:
 | |||
| //   CommonJS:
 | |||
| //     require('tinymce/plugins/anchor')
 | |||
| //   ES2015:
 | |||
| //     import 'tinymce/plugins/anchor'
 | |||
| require('./plugin.js') | |||
| @ -1,235 +0,0 @@ | |||
| 
 | |||
| 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() | |||
| }()) | |||
| @ -1,305 +0,0 @@ | |||
| 
 | |||
| // 判断是否已引用
 | |||
| 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 = Array.from(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 = Array.from(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) | |||
| } | |||
| @ -1,56 +0,0 @@ | |||
| /* 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' | |||
|       } | |||
|     } | |||
|   } | |||
| }) | |||
| @ -1,7 +0,0 @@ | |||
| // 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
									
								
							
						
					| @ -1,174 +0,0 @@ | |||
| <template> | |||
|   <div> | |||
|     <div> | |||
|       <div class="title-wrapper"> | |||
|         必须 | |||
|       </div> | |||
|       <div class="select-wrapper"> | |||
|         <el-tag v-for="(item,index) in queryItemData_must" :key="index" size="small" class="match-item"> | |||
|           <span class="match-item-name">{{ item.itemName }} | |||
|             (<span class="match-item-kpi">{{ item.kpiName }}</span>) | |||
|           </span> | |||
|           <span class="match-item-type">{{ item.queryLogicName }}</span> | |||
|           <span class="match-item-value">{{ item.queryValue }}</span> | |||
|         </el-tag> | |||
|       </div> | |||
|     </div> | |||
|     <div> | |||
|       <div class="title-wrapper"> | |||
|         可以 | |||
|       </div> | |||
|       <div class="select-wrapper"> | |||
|         <el-tag v-for="(item,index) in queryItemData_should" :key="index" size="small" class="match-item"> | |||
|           <span class="match-item-name">{{ item.itemName }} | |||
|             (<span class="match-item-kpi">{{ item.kpiName }}</span>) | |||
|           </span> | |||
|           <span class="match-item-type">{{ item.queryLogicName }}</span> | |||
|           <span class="match-item-value">{{ item.queryValue }}</span> | |||
|         </el-tag> | |||
|       </div> | |||
|     </div> | |||
|     <div> | |||
|       <div class="title-wrapper"> | |||
|         排除 | |||
|       </div> | |||
|       <div class="select-wrapper"> | |||
|         <el-tag v-for="(item,index) in queryItemData_must_not" :key="index" size="small" class="match-item"> | |||
|           <span class="match-item-name">{{ item.itemName }} | |||
|             (<span class="match-item-kpi">{{ item.kpiName }}</span>) | |||
|           </span> | |||
|           <span class="match-item-type">{{ item.queryLogicName }}</span> | |||
|           <span class="match-item-value">{{ item.queryValue }}</span> | |||
|         </el-tag> | |||
|       </div> | |||
|     </div> | |||
|   </div> | |||
| </template> | |||
| 
 | |||
| <script> | |||
| import cloneDeep from 'lodash/cloneDeep' | |||
| import { findItem, findPathArray } from '@/utils/tree' | |||
| 
 | |||
| const options_matchValue = [ | |||
|   { label: '匹配', value: 'eq' }, | |||
|   { label: '大于', value: 'gt' }, | |||
|   { label: '大于等于', value: 'gte' }, | |||
|   { label: '小于', value: 'lt' }, | |||
|   { label: '小于等于', value: 'lte' } | |||
| ] | |||
| 
 | |||
| export default { | |||
|   props: { | |||
|     condition: { type: Array, default: () => [] } | |||
|   }, | |||
|   data() { | |||
|     return { | |||
|       options_kpi: [], | |||
|       queryItemData_must: [], | |||
|       queryItemData_should: [], | |||
|       queryItemData_must_not: [] | |||
|     } | |||
|   }, | |||
|   watch: { | |||
|     condition: { | |||
|       handler(newVal, oldVal) { | |||
|         if (this.options_kpi.length === 0) { this.getOptionsKPI() } | |||
|         const arrayData = cloneDeep(newVal) | |||
|         const must = [] | |||
|         const should = [] | |||
|         const must_not = [] | |||
|         // this.getOptionsKPI() | |||
|         arrayData.forEach(item => { | |||
|           const valueList = findPathArray(this.options_kpi, item.id, 'value', 'children') | |||
|           const itemParentInfo = this.getItem(valueList[(valueList.length - 2) || 0]) | |||
|           const itemInfo = this.getItem(valueList[(valueList.length - 1) || 0]) | |||
|           // console.log(valueList, itemParentInfo, itemInfo, this.options_kpi, window.SITE_CONFIG['dict_colSearch']) | |||
| 
 | |||
|           const obj = { | |||
|             connection: item.connection, | |||
|             itemName: itemParentInfo.label, | |||
|             kpiId: item.id, | |||
|             kpiName: itemInfo.label, | |||
|             kpiType: itemInfo.type, | |||
|             queryType: item.queryType, // 查询用 | |||
|             // queryTypeName: options_matchType.find((item2) => item2.value === item.queryType).label, | |||
|             queryLogic: item.queryLogic, // 查询用 | |||
|             queryLogicName: options_matchValue.find((item2) => item2.value === item.queryLogic).label, | |||
|             queryValue: item.queryValue // 查询用 | |||
|           } | |||
|           if (item.connection === 'must') { | |||
|             must.push(obj) | |||
|           } | |||
|           if (item.connection === 'should') { | |||
|             should.push(obj) | |||
|           } | |||
|           if (item.connection === 'must_not') { | |||
|             must_not.push(obj) | |||
|           } | |||
|         }) | |||
|         this.queryItemData_must = must | |||
|         this.queryItemData_should = should | |||
|         this.queryItemData_must_not = must_not | |||
|       }, | |||
|       immediate: true | |||
|     } | |||
|   }, | |||
|   created() { this.getOptionsKPI() }, | |||
|   mounted() { }, | |||
|   methods: { | |||
|     getItem(value) { | |||
|       return findItem(this.options_kpi, value, 'value', 'children') | |||
|     }, | |||
|     async getOptionsKPI() { | |||
|       if (window.SITE_CONFIG['dict_colSearch']) { | |||
|         this.options_kpi = window.SITE_CONFIG['dict_colSearch'] | |||
|       } else { | |||
|         // 检索字典表 | |||
|         const { data: res } = await this.$http.get('/sys/table/dict/getList', { params: { type: 1 }}) | |||
|         this.options_kpi = res.data | |||
|       } | |||
|     } | |||
|   } | |||
| } | |||
| 
 | |||
| </script> | |||
| 
 | |||
| <style lang="scss" scoped> | |||
| $width_title: 35px; | |||
| .title-wrapper { | |||
|   display: inline-block; | |||
|   width: $width_title; | |||
|   vertical-align: top; | |||
| } | |||
| .select-wrapper { | |||
|   display: inline-block; | |||
|   width: calc(100% - #{$width_title}); | |||
| 
 | |||
|   .match-item { | |||
|     display: inline-block; | |||
|     border-radius: 15px; | |||
|     background-color: #e6f7ff; | |||
|     margin-right: 10px; | |||
| 
 | |||
|     .match-item-name { | |||
|       color: #000; | |||
|       margin-left: 5px; | |||
|       margin-right: 5px; | |||
|     } | |||
|     .match-item-kpi { | |||
|       color: #fa0d35; | |||
|       margin-left: 3px; | |||
|       margin-right: 3px; | |||
|       font-size: 13px; | |||
|     } | |||
|     .match-item-type { | |||
|       color: #1e79ff; | |||
|       margin-right: 5px; | |||
|     } | |||
|     .match-item-value { | |||
|       color: #000; | |||
|       margin-right: 5px; | |||
|     } | |||
|   } | |||
| } | |||
| </style> | |||
| @ -1,99 +0,0 @@ | |||
| <template> | |||
|   <div class="input-container"> | |||
|     <!-- 显示的输入框,用v-model绑定数据,并且绑定focus事件 --> | |||
|     <Input v-model="inputData" class="input-number" @on-focus="_showInputNumber" /> | |||
|     <!--  --> | |||
|     <div class="input-dropdown-wrap"> | |||
|       <Dropdown trigger="custom" :visible="visibNormal" class="input-dropdown"> | |||
|         <Dropdown-menu slot="list"> | |||
|           <div class="dropdown-list"> | |||
|             <Row :key="item.code" v-for="item in arrayList" class="item" :value="item.code" @click.native="_inputNumChange(item.code)">{{ item.text }}</Row> | |||
|           </div> | |||
|         </Dropdown-menu> | |||
|       </Dropdown> | |||
|     </div> | |||
|   </div> | |||
| </template> | |||
| <script> | |||
| import cloneDeep from 'lodash/cloneDeep' | |||
| export default { | |||
|   props: { | |||
|     arrayList: { // 下拉列表的数据 | |||
|       type: Array, | |||
|       default: [] | |||
|     } | |||
|   }, | |||
|   data() { | |||
|     return { | |||
|       inputData: '1', // 输入框的默认值 | |||
|       visibNormal: false // 下拉显示控制 | |||
|     } | |||
|   }, | |||
|   watch: { | |||
|     inputData(newVal) { | |||
|       this.$emit('getInputNum', newVal) | |||
|     } | |||
|   }, | |||
|   mounted() { | |||
|     this.getOptionsKPI() | |||
|   }, | |||
|   methods: { | |||
|     // 展示下拉选项 | |||
|     _showInputNumber(e) { | |||
|       const _this = this | |||
|       if (this.visibNormal) return | |||
| 
 | |||
|       this.visibNormal = true | |||
|       // 给输入框元素加入阻止冒泡事件 | |||
|       e.target.addEventListener('click', (e) => { | |||
|         e.stopPropagation() | |||
|       }) | |||
|       document.addEventListener('click', _this._hideNormal) | |||
|     }, | |||
|     // 下拉框列表的点击事件 | |||
|     _inputNumChange(data) { | |||
|       this.$emit('getInputNum', data) | |||
|     }, | |||
|     // 隐藏下拉框 | |||
|     _hideNormal() { | |||
|       let curTarget = event.target; | |||
|       if(curTarget.nodeName === 'SPAN' && curTarget.classList.contains('switch')){ | |||
|         return | |||
|       } | |||
|       this.visibNormal = false | |||
|       document.removeEventListener('click', this._hideNormal) | |||
|     } | |||
|   } | |||
| } | |||
| 
 | |||
| </script> | |||
| 
 | |||
| <style lang="scss" scoped> | |||
| .input-container { | |||
|   .input-dropdown-wrap { | |||
|     height: 0 !important; | |||
|     overflow: hidden; | |||
|   } | |||
|   .dropdown-list { | |||
|     height: 1.3rem; | |||
|     overflow: auto; | |||
|     border-bottom: .01rem solid #E4E4E4; | |||
|     .item { | |||
|       line-height: .25rem; | |||
|       padding-left: .15rem; | |||
|       &:hover { | |||
|         background: grey; | |||
|       } | |||
|     } | |||
|   } | |||
|   .input-number { | |||
|     width: 2.2rem; | |||
|   } | |||
|   .input-dropdown { | |||
|     width: 2.2rem; | |||
|     .ivu-select-dropdown { | |||
|       margin-top: -.2rem; | |||
|     } | |||
|   } | |||
| } | |||
| </style> | |||
| @ -1,174 +0,0 @@ | |||
| <template> | |||
|   <div> | |||
|     <div> | |||
|       <div class="title-wrapper"> | |||
|         必须 | |||
|       </div> | |||
|       <div class="select-wrapper"> | |||
|         <el-tag v-for="(item,index) in queryItemData_must" :key="index" size="small" class="match-item"> | |||
|           <span class="match-item-name">{{ item.itemName }} | |||
|             (<span class="match-item-kpi">{{ item.kpiName }}</span>) | |||
|           </span> | |||
|           <span class="match-item-type">{{ item.queryLogicName }}</span> | |||
|           <span class="match-item-value">{{ item.queryValue }}</span> | |||
|         </el-tag> | |||
|       </div> | |||
|     </div> | |||
|     <div> | |||
|       <div class="title-wrapper"> | |||
|         可以 | |||
|       </div> | |||
|       <div class="select-wrapper"> | |||
|         <el-tag v-for="(item,index) in queryItemData_should" :key="index" size="small" class="match-item"> | |||
|           <span class="match-item-name">{{ item.itemName }} | |||
|             (<span class="match-item-kpi">{{ item.kpiName }}</span>) | |||
|           </span> | |||
|           <span class="match-item-type">{{ item.queryLogicName }}</span> | |||
|           <span class="match-item-value">{{ item.queryValue }}</span> | |||
|         </el-tag> | |||
|       </div> | |||
|     </div> | |||
|     <div> | |||
|       <div class="title-wrapper"> | |||
|         排除 | |||
|       </div> | |||
|       <div class="select-wrapper"> | |||
|         <el-tag v-for="(item,index) in queryItemData_must_not" :key="index" size="small" class="match-item"> | |||
|           <span class="match-item-name">{{ item.itemName }} | |||
|             (<span class="match-item-kpi">{{ item.kpiName }}</span>) | |||
|           </span> | |||
|           <span class="match-item-type">{{ item.queryLogicName }}</span> | |||
|           <span class="match-item-value">{{ item.queryValue }}</span> | |||
|         </el-tag> | |||
|       </div> | |||
|     </div> | |||
|   </div> | |||
| </template> | |||
| 
 | |||
| <script> | |||
| import cloneDeep from 'lodash/cloneDeep' | |||
| import { findItem, findPathArray } from '@/utils/tree' | |||
| 
 | |||
| const options_matchValue = [ | |||
|   { label: '匹配', value: 'eq' }, | |||
|   { label: '大于', value: 'gt' }, | |||
|   { label: '大于等于', value: 'gte' }, | |||
|   { label: '小于', value: 'lt' }, | |||
|   { label: '小于等于', value: 'lte' } | |||
| ] | |||
| 
 | |||
| export default { | |||
|   props: { | |||
|     condition: { type: Array, default: () => [] } | |||
|   }, | |||
|   data() { | |||
|     return { | |||
|       options_kpi: [], | |||
|       queryItemData_must: [], | |||
|       queryItemData_should: [], | |||
|       queryItemData_must_not: [] | |||
|     } | |||
|   }, | |||
|   watch: { | |||
|     condition: { | |||
|       handler(newVal, oldVal) { | |||
|         if (this.options_kpi.length === 0) { this.getOptionsKPI() } | |||
|         const arrayData = cloneDeep(newVal) | |||
|         const must = [] | |||
|         const should = [] | |||
|         const must_not = [] | |||
|         // this.getOptionsKPI() | |||
|         arrayData.forEach(item => { | |||
|           const valueList = findPathArray(this.options_kpi, item.id, 'value', 'children') | |||
|           const itemParentInfo = this.getItem(valueList[(valueList.length - 2) || 0]) | |||
|           const itemInfo = this.getItem(valueList[(valueList.length - 1) || 0]) | |||
|           // console.log(valueList, itemParentInfo, itemInfo, this.options_kpi, window.SITE_CONFIG['dict_colSearch']) | |||
| 
 | |||
|           const obj = { | |||
|             connection: item.connection, | |||
|             itemName: itemParentInfo.label, | |||
|             kpiId: item.id, | |||
|             kpiName: itemInfo.label, | |||
|             kpiType: itemInfo.type, | |||
|             queryType: item.queryType, // 查询用 | |||
|             // queryTypeName: options_matchType.find((item2) => item2.value === item.queryType).label, | |||
|             queryLogic: item.queryLogic, // 查询用 | |||
|             queryLogicName: options_matchValue.find((item2) => item2.value === item.queryLogic).label, | |||
|             queryValue: item.queryValue // 查询用 | |||
|           } | |||
|           if (item.connection === 'must') { | |||
|             must.push(obj) | |||
|           } | |||
|           if (item.connection === 'should') { | |||
|             should.push(obj) | |||
|           } | |||
|           if (item.connection === 'must_not') { | |||
|             must_not.push(obj) | |||
|           } | |||
|         }) | |||
|         this.queryItemData_must = must | |||
|         this.queryItemData_should = should | |||
|         this.queryItemData_must_not = must_not | |||
|       }, | |||
|       immediate: true | |||
|     } | |||
|   }, | |||
|   created() { this.getOptionsKPI() }, | |||
|   mounted() { }, | |||
|   methods: { | |||
|     getItem(value) { | |||
|       return findItem(this.options_kpi, value, 'value', 'children') | |||
|     }, | |||
|     async getOptionsKPI() { | |||
|       if (window.SITE_CONFIG['dict_colSearch']) { | |||
|         this.options_kpi = window.SITE_CONFIG['dict_colSearch'] | |||
|       } else { | |||
|         // 检索字典表 | |||
|         const { data: res } = await this.$http.get('/table/dict/optionsColumn', { params: { type: 1 }}) | |||
|         this.options_kpi = res.data | |||
|       } | |||
|     } | |||
|   } | |||
| } | |||
| 
 | |||
| </script> | |||
| 
 | |||
| <style lang="scss" scoped> | |||
| $width_title: 35px; | |||
| .title-wrapper { | |||
|   display: inline-block; | |||
|   width: $width_title; | |||
|   vertical-align: top; | |||
| } | |||
| .select-wrapper { | |||
|   display: inline-block; | |||
|   width: calc(100% - #{$width_title}); | |||
| 
 | |||
|   .match-item { | |||
|     display: inline-block; | |||
|     border-radius: 15px; | |||
|     background-color: #e6f7ff; | |||
|     margin-right: 10px; | |||
| 
 | |||
|     .match-item-name { | |||
|       color: #000; | |||
|       margin-left: 5px; | |||
|       margin-right: 5px; | |||
|     } | |||
|     .match-item-kpi { | |||
|       color: #fa0d35; | |||
|       margin-left: 3px; | |||
|       margin-right: 3px; | |||
|       font-size: 13px; | |||
|     } | |||
|     .match-item-type { | |||
|       color: #1e79ff; | |||
|       margin-right: 5px; | |||
|     } | |||
|     .match-item-value { | |||
|       color: #000; | |||
|       margin-right: 5px; | |||
|     } | |||
|   } | |||
| } | |||
| </style> | |||
| @ -1,397 +0,0 @@ | |||
| <template> | |||
|   <div> | |||
|     <div> | |||
|       <el-tag | |||
|         v-for="(item,index) in dataList" | |||
|         :key="index" | |||
|         class="match-item" | |||
|         closable | |||
|         @close="btnRemove(item)" | |||
|         @click="editItem(item)" | |||
|       > | |||
|         <span class="match-item-name">{{ item.itemName }} | |||
|           (<span class="match-item-kpi">{{ item.kpiName }}</span>) | |||
|         </span> | |||
|         <span class="match-item-type">{{ item.queryLogicName }}</span> | |||
|         <span class="match-item-value">{{ item.queryValue }}</span> | |||
|       </el-tag> | |||
|       <span class="btn-add"> | |||
|         <i class="el-icon-plus" @click="btnAdd" /> | |||
|       </span> | |||
|     </div> | |||
|     <div v-show="isAdd"> | |||
|       <el-form :inline="true" :model="dataForm" class="form-query" @submit.native.prevent> | |||
|         <!-- KPI --> | |||
|         <el-form-item> | |||
|           <el-cascader | |||
|             v-model="CascaderValue" | |||
|             :options="options_kpi" | |||
|             size="mini" | |||
|             popper-class="kpi-select-filter" | |||
|             class="item-query-kpi" | |||
|             placeholder="请选择" | |||
|             filterable | |||
|             @change="changeHandle_kpi" | |||
|           /> | |||
|         </el-form-item> | |||
|         <!-- 匹配逻辑 --> | |||
|         <el-form-item> | |||
|           <el-select v-model="dataForm.queryLogic" size="mini" class="item-query-logic" placeholder="请选择"> | |||
|             <el-option | |||
|               v-for="item in options_matchValue" | |||
|               :key="item.value" | |||
|               :label="item.label" | |||
|               :value="item.value" | |||
|               :disabled="item.disabled" | |||
|             /> | |||
|           </el-select> | |||
|         </el-form-item> | |||
|         <!-- 匹配数值 --> | |||
|         <el-form-item> | |||
|           <el-input-number | |||
|             v-if="dataForm.kpiType==='number'" | |||
|             v-model="dataForm.queryValue" | |||
|             size="mini" | |||
|             class="item-query-value" | |||
|             placeholder="请输入" | |||
|           /> | |||
|           <el-input | |||
|             v-if="dataForm.kpiType==='string'" | |||
|             v-model="dataForm.queryValue" | |||
|             size="mini" | |||
|             class="item-query-value" | |||
|             placeholder="请输入" | |||
|           /> | |||
|           <el-date-picker | |||
|             v-if="dataForm.kpiType==='date'" | |||
|             v-model="dataForm.queryValue" | |||
|             size="mini" | |||
|             align="right" | |||
|             type="date" | |||
|             placeholder="选择日期" | |||
|             value-format="yyyy/MM/dd" | |||
|           /> | |||
|           <!-- 设备选择 --> | |||
|           <el-select | |||
|             v-if="dataForm.kpiType==='selectDevice'" | |||
|             v-model="dataForm.queryValue" | |||
|             filterable | |||
|             size="mini" | |||
|             placeholder="请选择" | |||
|           > | |||
|             <el-option | |||
|               v-for="item in options_device" | |||
|               :key="item.deviceId" | |||
|               :label="item.deviceName+(item.location?'('+item.location+')':'')" | |||
|               :value="item.deviceId" | |||
|             > | |||
|               <span style="float: left">{{ item.deviceName }}</span> | |||
|               <span style="float: right; color: #8492a6; font-size: 13px">{{ item.location?item.location:'' }}</span> | |||
|             </el-option> | |||
|           </el-select> | |||
|         </el-form-item> | |||
|         <!-- 按钮 --> | |||
|         <el-form-item> | |||
|           <el-button type="primary" icon="el-icon-check" size="mini" @click="btnOk" /> | |||
|           <el-button type="danger" icon="el-icon-close" size="mini" @click="btnCancel" /> | |||
|         </el-form-item> | |||
|       </el-form> | |||
| 
 | |||
|     </div> | |||
|   </div> | |||
| 
 | |||
| </template> | |||
| 
 | |||
| <script> | |||
| import cloneDeep from 'lodash/cloneDeep' | |||
| // import { getBirthday, getAge, formatDate } from '@/utils' | |||
| import { findItem, findPathArray } from '@/utils/tree' | |||
| 
 | |||
| // const options_matchType = [ | |||
| //   { label: '匹配', value: 'matchQuery' }, | |||
| //   { label: '范围', value: 'rangeQuery' } | |||
| // ] | |||
| 
 | |||
| // const demo = { | |||
| //   connection: '', // 条件类型:必须、可以、排除 | |||
| //   id: '', // 字段ID(用于字段字典表取数据) | |||
| //   queryType: '', // 匹配类型:模糊匹配、精准匹配、范围查询 | |||
| //   queryLogic: 'eq', | |||
| //   queryValue: '' | |||
| // } | |||
| 
 | |||
| const options_matchValue = [ | |||
|   { label: '匹配', value: 'eq' }, | |||
|   { label: '大于', value: 'gt' }, | |||
|   { label: '大于等于', value: 'gte' }, | |||
|   { label: '小于', value: 'lt' }, | |||
|   { label: '小于等于', value: 'lte' } | |||
| ] | |||
| 
 | |||
| export default { | |||
|   props: { | |||
|     value: { type: Array, default: () => [] }, | |||
|     connection: { type: String, default: '' } | |||
|   }, | |||
|   data() { | |||
|     return { | |||
|       isAdd: false, | |||
|       dataList: [], | |||
|       options_kpi: [], | |||
|       options_device: [], | |||
|       options_matchValue: options_matchValue, | |||
|       CascaderValue: [], | |||
|       dataForm: { | |||
|         itemName: '', // label | |||
|         kpiName: '', | |||
|         kpiId: '', | |||
|         kpiType: 'string', // string,number,date | |||
|         queryType: 'matchQuery', | |||
|         queryLogic: 'eq', | |||
|         queryValue: '' | |||
|       } | |||
|     } | |||
|   }, | |||
|   watch: { | |||
|     'dataForm.queryType': { | |||
|       handler(newVal, oldVal) { | |||
|         if (newVal !== 'rangeQuery') { | |||
|           this.dataForm.queryLogic = 'eq' | |||
|           this.options_matchValue = [ | |||
|             { label: '匹配', value: 'eq' }, | |||
|             { label: '大于', value: 'gt', disabled: true }, | |||
|             { label: '大于等于', value: 'gte', disabled: true }, | |||
|             { label: '小于', value: 'lt', disabled: true }, | |||
|             { label: '小于等于', value: 'lte', disabled: true } | |||
|           ] | |||
|         } else { | |||
|           this.dataForm.queryLogic = 'gt' | |||
|           this.options_matchValue = [ | |||
|             { label: '匹配', value: 'eq', disabled: true }, | |||
|             { label: '大于', value: 'gt' }, | |||
|             { label: '大于等于', value: 'gte' }, | |||
|             { label: '小于', value: 'lt' }, | |||
|             { label: '小于等于', value: 'lte' } | |||
|           ] | |||
|         } | |||
|       }, | |||
|       immediate: true | |||
|     }, | |||
|     value(val) { | |||
|       const arrayData = cloneDeep(val) | |||
|       // dataList 赋值 | |||
|       this.dataList = arrayData.map(item => { | |||
|         if (this.options_kpi.length === 0) { this.getOptionsKPI() } | |||
|         const valueList = findPathArray(this.options_kpi, item.id, 'value', 'children') | |||
|         const itemParentInfo = this.getItem(valueList[(valueList.length - 2) || 0]) | |||
|         const itemInfo = this.getItem(valueList[(valueList.length - 1) || 0]) | |||
|         // 过滤设备字典数据 | |||
|         if (item.id.indexOf('DEVICE_ID') >= 0) { | |||
|           const dict = cloneDeep(window.SITE_CONFIG['dict_device_item']) | |||
|           const itemId = item.id.split('.')[0] || '' | |||
|           const obj = dict.find(item2 => item2.value === itemId) | |||
|           this.options_device = obj ? obj.children : [] | |||
|         } | |||
|         return { | |||
|           recId: item.recId, | |||
|           itemName: item.itemName, | |||
|           kpiId: item.id, | |||
|           kpiName: item.kpiName, | |||
|           kpiType: item.kpiType, | |||
|           queryType: item.queryType, // 查询用 | |||
|           // queryTypeName: options_matchType.find((item2) => item2.value === item.queryType).label, | |||
|           queryLogic: item.queryLogic, // 返回数据格式问题:queryValue=》queryLogic | |||
|           queryLogicName: options_matchValue.find((item2) => item2.value === item.queryLogic).label, | |||
|           queryValue: item.queryValue // 查询用 | |||
|         } | |||
|       }) | |||
|     } | |||
|   }, | |||
|   created() { | |||
|     this.getOptionsKPI() | |||
|   }, | |||
|   mounted() { }, | |||
|   methods: { | |||
|     changeHandle_kpi(valueList) { | |||
|       if (valueList.length > 0) { | |||
|         // 获取父节点信息 | |||
|         const parentValue = valueList[(valueList.length - 2) || 0] | |||
|         const parentItem = this.getItem(parentValue) | |||
|         // 获取当前节点信息 | |||
|         const value = valueList[(valueList.length - 1) || 0] | |||
|         const item = this.getItem(value) | |||
| 
 | |||
|         const oldValType = this.dataForm.kpiType | |||
|         this.dataForm.itemName = parentItem.label | |||
|         this.dataForm.kpiId = item.id | |||
|         this.dataForm.kpiName = item.label | |||
|         this.dataForm.kpiType = item.fieldType | |||
|         this.dataForm.queryType = (this.dataForm.kpiType === 'number' || this.dataForm.kpiType === 'date') ? 'rangeQuery' : 'matchQuery' | |||
|         this.dataForm.queryValue = this.dataForm.kpiType === oldValType ? this.dataForm.queryValue : null | |||
| 
 | |||
|         // 过滤设备字典数据 | |||
|         if (item.value.indexOf('DEVICE_ID') >= 0) { | |||
|           // this.options_device = cloneDeep(window.SITE_CONFIG['dict_device']).filter(item2 => (item.value.split('.')[1] || '') === item2.datSource) | |||
|           const dict = cloneDeep(window.SITE_CONFIG['dict_device_item']) | |||
|           const itemId = item.value.split('.')[0] || '' | |||
|           const obj = dict.find(item2 => item2.value === itemId) | |||
|           this.options_device = obj ? obj.children : [] | |||
|         } | |||
|       } | |||
|     }, | |||
|     // 转换成通用数据结构 | |||
|     convertItem(item) { | |||
|       const filterItem = { | |||
|         ...item, | |||
|         connection: this.connection, | |||
|         id: item.kpiId, | |||
|         // queryType: item.queryType, | |||
|         // queryValue: {}, // post是对象,get返回值是logic字符串 | |||
|         queryValue: String(item.queryValue) | |||
|       } | |||
|       // filterItem.queryValue[item.queryLogic] = String(item.queryValue) | |||
| 
 | |||
|       return filterItem | |||
|     }, | |||
|     convertItemList(itemList) { | |||
|       const list = [] | |||
|       itemList.forEach(item => { | |||
|         list.push(this.convertItem(item)) | |||
|       }) | |||
|       return list | |||
|     }, | |||
|     // 移除 | |||
|     btnRemove(item) { | |||
|       const index = this.dataList.findIndex((item2, index) => { | |||
|         return item2 === item | |||
|       }) | |||
|       this.dataList.splice(index, 1) | |||
| 
 | |||
|       this.$emit('remove', this.convertItem(item)) | |||
|       this.$emit('input', this.convertItemList(this.dataList)) | |||
|       this.$emit('change', this.convertItemList(this.dataList)) | |||
|     }, | |||
|     // 编辑 | |||
|     editItem(item) { | |||
|       if (!this.isAdd) { | |||
|         this.isAdd = true | |||
|       } else if (this.isAdd && item.kpiId === this.dataForm.kpiId) { | |||
|         this.isAdd = false | |||
|       } | |||
|       this.dataForm = cloneDeep(item) | |||
|       this.dataForm.recId = null | |||
|       this.CascaderValue = findPathArray(this.options_kpi, this.dataForm.kpiId, 'value', 'children') | |||
|     }, | |||
|     btnAdd() { | |||
|       this.resetDataForm() | |||
|       this.isAdd = true | |||
|     }, | |||
|     btnCancel() { | |||
|       this.isAdd = false | |||
|     }, | |||
|     btnOk() { | |||
|       if (!this.dataForm.kpiId || | |||
|         this.dataForm.queryValue === null || | |||
|         this.dataForm.queryValue === undefined || | |||
|         this.dataForm.queryValue === '') { | |||
|         this.$message.error('请明确查询条件!') | |||
|         return false | |||
|       } | |||
|       const item = { ...this.dataForm, queryLogicName: options_matchValue.find((item) => item.value === this.dataForm.queryLogic).label } | |||
|       this.dataList.push(item) | |||
| 
 | |||
|       this.$emit('add', this.convertItem(item)) | |||
|       this.$emit('input', this.convertItemList(this.dataList)) | |||
|       this.$emit('change', this.convertItemList(this.dataList)) | |||
|     }, | |||
|     resetDataForm() { | |||
|       this.CascaderValue = [] | |||
|       this.dataForm = { | |||
|         itemName: '', | |||
|         kpiName: '', | |||
|         kpiId: '', | |||
|         kpiType: 'string', | |||
|         queryType: 'matchQuery', | |||
|         queryLogic: 'eq', | |||
|         queryValue: '' | |||
|       } | |||
|     }, | |||
|     getItem(value) { | |||
|       return findItem(this.options_kpi, value, 'value', 'children') | |||
|     }, | |||
|     async getOptionsKPI() { | |||
|       if (window.SITE_CONFIG['dict_colSearch']) { | |||
|         this.options_kpi = window.SITE_CONFIG['dict_colSearch'] | |||
|       } else { | |||
|         // 检索字典表 | |||
|         const { data: res } = await this.$http.get('/sys/table/dict/getList', { params: { type: 1, isSearch: 1 }}) | |||
|         if (res.data.length) { | |||
|           res.data.forEach(item => { | |||
|             item.label = item.tableDescription | |||
|             item.value = item.tableName | |||
|             item.list.forEach(row => { | |||
|               row.label = row.fieldDescription | |||
|               row.value = row.fieldName | |||
|             }) | |||
|             item.children = JSON.parse(JSON.stringify(item.list)) | |||
|           }) | |||
|         } | |||
|         this.options_kpi = res.data | |||
|       } | |||
|     } | |||
|   } | |||
| } | |||
| 
 | |||
| </script> | |||
| 
 | |||
| <style lang="scss"> | |||
| .kpi-select-filter .el-cascader-menu__wrap { | |||
|   height: 400px; | |||
| } | |||
| </style> | |||
| 
 | |||
| <style lang="scss" scoped> | |||
| .match-item { | |||
|   display: inline-block; | |||
|   border-radius: 15px; | |||
|   background-color: #e6f7ff; | |||
|   margin-right: 10px; | |||
| 
 | |||
|   .match-item-name { | |||
|     color: #000; | |||
|     margin-left: 5px; | |||
|     margin-right: 5px; | |||
|   } | |||
|   .match-item-kpi { | |||
|     color: #fa0d35; | |||
|     margin-left: 3px; | |||
|     margin-right: 3px; | |||
|     font-size: 13px; | |||
|   } | |||
|   .match-item-type { | |||
|     color: #1e79ff; | |||
|     margin-right: 5px; | |||
|   } | |||
|   .match-item-value { | |||
|     color: #000; | |||
|     margin-right: 5px; | |||
|   } | |||
| } | |||
| 
 | |||
| .btn-add { | |||
|   padding: 5px; | |||
|   cursor: pointer; | |||
| } | |||
| 
 | |||
| .form-query { | |||
|   .item-query-kpi { | |||
|     width: 300px; | |||
|   } | |||
|   .item-query-type { | |||
|     width: 100px; | |||
|   } | |||
|   .item-query-logic { | |||
|     width: 100px; | |||
|   } | |||
| } | |||
| </style> | |||
| @ -1,73 +0,0 @@ | |||
| <template> | |||
|   <div> | |||
|     <el-tag v-for="(item,index) in kpiItemList" :key="index" size="small" class="match-item"> | |||
|       <span class="match-item-name">{{ item.itemName }} | |||
|         (<span class="match-item-kpi">{{ item.kpiName }}</span>) | |||
|       </span> | |||
|     </el-tag> | |||
|   </div> | |||
| </template> | |||
| 
 | |||
| <script> | |||
| import cloneDeep from 'lodash/cloneDeep' | |||
| import { findItem, findPathArray } from '@/utils/tree' | |||
| 
 | |||
| export default { | |||
|   props: { | |||
|     type: { type: Number, default: 4 }, | |||
|     value: { type: Array, default: () => [] } | |||
|   }, | |||
|   data() { | |||
|     return { | |||
|       options_kpi: [], | |||
|       kpiItemList: [] | |||
|     } | |||
|   }, | |||
|   watch: { | |||
|     value: { | |||
|       handler(newVal, oldVal) { | |||
|         if (this.options_kpi.length === 0) { this.getOptionsKPI() } | |||
|         const arrayData = cloneDeep(newVal) | |||
|         const itemList = [] | |||
|         // this.getOptionsKPI() | |||
|         arrayData.forEach(id => { | |||
|           const valueList = findPathArray(this.options_kpi, id, 'value', 'children') | |||
|           const itemParentInfo = findItem(this.options_kpi, valueList[(valueList.length - 2) || 0], 'value', 'children') | |||
|           const itemInfo = findItem(this.options_kpi, id, 'value', 'children') | |||
| 
 | |||
|           console.log(valueList, itemParentInfo, itemInfo, this.options_kpi) | |||
| 
 | |||
|           itemList.push({ | |||
|             itemName: itemParentInfo.label, | |||
|             kpiName: itemInfo.label | |||
|           }) | |||
|         }) | |||
| 
 | |||
|         this.kpiItemList = itemList | |||
|       }, | |||
|       immediate: true | |||
|     } | |||
|   }, | |||
|   created() { }, | |||
|   mounted() { }, | |||
|   methods: { | |||
|     async getOptionsKPI() { | |||
|       if (this.type === 4 && window.SITE_CONFIG.dict_colExport) { | |||
|         this.options_kpi = window.SITE_CONFIG.dict_colExport | |||
|       } else if (this.type === 2 && window.SITE_CONFIG.dict_colChart) { | |||
|         this.options_kpi = window.SITE_CONFIG.dict_colChart | |||
|       } else { | |||
|         const { data: res } = await this.$http.get('/table/dict/optionsColumn', { params: { type: this.type }}) | |||
|         this.options_kpi = res.data | |||
|       } | |||
|     } | |||
|   } | |||
| 
 | |||
| } | |||
| </script> | |||
| 
 | |||
| <style lang="scss"> | |||
| .match-item{ | |||
|     margin-right: 5px; | |||
| } | |||
| </style> | |||
| @ -1,92 +0,0 @@ | |||
| <template> | |||
|   <div> | |||
|     <el-cascader | |||
|       v-model="optionValue" | |||
|       popper-class="kpi-select-filter" | |||
|       :style="{ width: width }" | |||
|       :options="options" | |||
|       :props="optionSet" | |||
|       :clearable="clearable" | |||
|       filterable | |||
|       @change="changeHandle" | |||
|     /> | |||
|   </div> | |||
| </template> | |||
| 
 | |||
| <script> | |||
| import { findItem, findPathArray } from '@/utils/tree' | |||
| 
 | |||
| export default { | |||
|   props: { | |||
|     type: { type: Number, default: 0 }, | |||
|     value: { type: Array, default: () => [] }, | |||
|     width: { type: String, default: '100%' }, | |||
|     optionSet: { type: Object, default: () => { return { multiple: true } } }, | |||
|     clearable: { type: Boolean, default: true } | |||
|   }, | |||
|   data() { | |||
|     return { | |||
|       optionValue: [], | |||
|       options: [] | |||
|     } | |||
|   }, | |||
|   watch: { | |||
|     value: { | |||
|       handler(newVal, oldVal) { | |||
|         if (this.options.length === 0) { | |||
|           this.getOptions() | |||
|         } | |||
|         this.valueHandle() | |||
|       }, | |||
|       immediate: true | |||
|     } | |||
|   }, | |||
|   created() { // this.getOptions() | |||
|   }, | |||
|   mounted() { }, | |||
|   methods: { | |||
|     valueHandle() { | |||
|       const valuePathList = [] | |||
|       this.value.forEach(id => { | |||
|         const val = findPathArray(this.options, id, 'value', 'children') | |||
|         if (val) { valuePathList.push(val) } | |||
|       }) | |||
|       this.optionValue = valuePathList | |||
|     }, | |||
|     async getOptions() { | |||
|       if (this.type === 4 && window.SITE_CONFIG.dict_colExport) { | |||
|         this.options = window.SITE_CONFIG.dict_colExport | |||
|       } else if (this.type === 2 && window.SITE_CONFIG.dict_colChart) { | |||
|         this.options = window.SITE_CONFIG.dict_colChart | |||
|       } else { | |||
|         const { data: res } = await this.$http.get('/table/dict/optionsColumn', { params: { type: this.type }}) | |||
|         this.options = res.data | |||
|       } | |||
|       // this.valueHandle() | |||
|     }, | |||
|     changeHandle(valueList) { | |||
|       const idList = [] | |||
|       const itemList = [] | |||
|       valueList.forEach(arrayItem => { | |||
|         if (arrayItem.length > 0) { | |||
|           // id | |||
|           const id = arrayItem[arrayItem.length - 1] | |||
|           if (id) { idList.push(id) } | |||
|           // item | |||
|           const item = findItem(this.options, id, 'value', 'children') | |||
|           if (item) { itemList.push(item) } | |||
|         } | |||
|       }) | |||
|       this.$emit('input', idList) | |||
|       this.$emit('change', itemList) | |||
|     } | |||
|   } | |||
| 
 | |||
| } | |||
| </script> | |||
| 
 | |||
| <style lang="scss"> | |||
| .kpi-select-filter .el-cascader-menu__wrap{ | |||
|     height: 400px; | |||
| } | |||
| </style> | |||
| @ -1,226 +0,0 @@ | |||
| <template> | |||
|   <div class="component-container searchContent"> | |||
|     <el-table | |||
|       ref="multipleTable" | |||
|       v-loading="dataListLoading" | |||
|       :data="dataList" | |||
|       @select="selectHandle" | |||
|       @select-all="selectHandle" | |||
|     > | |||
|       <el-table-column type="selection" width="55" :selectable="selectable" /> | |||
|       <!-- 行展开 --> | |||
|       <el-table-column type="expand"> | |||
|         <template slot-scope="scope"> | |||
|           <el-form label-width="90px" class="expand-form"> | |||
|             <!-- 摘要 --> | |||
|             <el-form-item :label="'主要内容'"> | |||
|               <div class="overViewHtml" v-html="scope.row.allHighlight" /> | |||
|             </el-form-item> | |||
|             <!-- 检查项目 --> | |||
|             <el-form-item :label="'检查计次'"> | |||
|               <div class="exam"> | |||
|                 <p v-for="(item, index) in scope.row.checkCount" :key="index"> | |||
|                   <span class="exam-name" :title="item.checkName">{{ item.checkName }}</span> | |||
|                   <span class="exam-num">{{ item.count }}次</span> | |||
|                 </p> | |||
|               </div> | |||
|             </el-form-item> | |||
|             <template v-if="visibleChart"> | |||
|               <!-- 折线图 --> | |||
|               <el-form-item :label="'折线图'"> | |||
|                 <el-row :gutter="20"> | |||
|                   <el-col :span="12"> | |||
|                     <echarts-line-kpi :chart-data="scope.row.yanya" :title="'眼压'" /> | |||
|                   </el-col> | |||
|                   <el-col :span="12"> | |||
|                     <echarts-line-kpi-va :chart-data="scope.row.vision" :title="'视力'" /> | |||
|                   </el-col> | |||
|                 </el-row> | |||
|               </el-form-item> | |||
|             </template> | |||
|           </el-form> | |||
|         </template> | |||
|       </el-table-column> | |||
|       <!-- 姓名 --> | |||
|       <el-table-column :label="'姓名'" header-align="center" align="center" show-overflow-tooltip> | |||
|         <template slot-scope="scope"> | |||
|           {{ (scope.row.esPatientInfo?scope.row.esPatientInfo.patientName:'') | f_desensitize_name }} | |||
|         </template> | |||
|       </el-table-column> | |||
|       <!-- 性别 --> | |||
|       <el-table-column :label="'性别'" header-align="center" align="center"> | |||
|         <template slot-scope="scope"> | |||
|           {{ (scope.row.esPatientInfo?scope.row.esPatientInfo.patientSex:'') | f_sex }} | |||
|         </template> | |||
|       </el-table-column> | |||
|       <!-- 年龄 --> | |||
|       <el-table-column :label="'年龄'" header-align="center" align="center"> | |||
|         <template slot-scope="scope"> | |||
|           {{ (scope.row.esPatientInfo?scope.row.esPatientInfo.patientAge:'') }} | |||
|         </template> | |||
|       </el-table-column> | |||
|       <!-- 身份证号 --> | |||
|       <el-table-column prop="patientIdNumber" :label="'身份证号'" header-align="center" align="center"> | |||
|         <template slot-scope="scope"> | |||
|           {{ (scope.row.id) | f_desensitize_idNumber }} | |||
|         </template> | |||
|       </el-table-column> | |||
|       <!-- 检索内容 --> | |||
|       <!-- <el-table-column prop="patientIdNumber" :label="'检索内容'" header-align="center" align="center" show-overflow-tooltip> | |||
|         <template slot-scope="scope"> | |||
|           <p v-html="scope.row.allHighlight" /> | |||
|         </template> | |||
|       </el-table-column> --> | |||
|       <!-- 操作 --> | |||
|       <el-table-column label="操作" header-align="center" align="center" width="120"> | |||
|         <template slot-scope="scope"> | |||
|           <el-button type="text" size="small" @click="showDetail(scope.row)">查看详情</el-button> | |||
|         </template> | |||
|       </el-table-column> | |||
|     </el-table> | |||
|   </div> | |||
| </template> | |||
| 
 | |||
| <script> | |||
| import echartsLineKpi from '@/components/echarts/line-kpi' | |||
| import echartsLineKpiVa from '@/components/echarts/line-kpi-va' | |||
| import { findItem } from '@/utils/tree' | |||
| 
 | |||
| export default { | |||
|   components: { | |||
|     echartsLineKpi, | |||
|     echartsLineKpiVa | |||
|   }, | |||
|   props: { | |||
|     dataListLoading: { type: Boolean, default: false }, | |||
|     dataList: { type: Array, default: () => [] }, | |||
|     visibleChart: { type: Boolean, default: false }, | |||
|     selectDisableIdList: { type: Array, default: () => [] }, | |||
|     projectId: { type: String, default: '' } | |||
|   }, | |||
|   data() { | |||
|     return { | |||
|       selectIdList: [], | |||
|       selectList: [], | |||
|       patientId: '' | |||
|     } | |||
|   }, | |||
|   mounted() { | |||
|   }, | |||
|   methods: { | |||
|     getExamItem(obj) { | |||
|       const result = [] | |||
|       for (const key in obj) { | |||
|         if (obj[key]) { | |||
|           const dictItem = findItem(window.SITE_CONFIG['dict_colSearch'], key, 'name', 'children') | |||
|           console.log(window.SITE_CONFIG['dict_colSearch']) | |||
|           result.push({ id: key, name: dictItem ? dictItem.label : '', num: obj[key] }) | |||
|         } | |||
|       } | |||
|       return result | |||
|     }, | |||
|     selectHandle(selection, row) { | |||
|       this.selectIdList = [] | |||
|       this.selectList = selection | |||
|       selection.forEach(item => { | |||
|         this.selectIdList.push(item.id) | |||
|       }) | |||
|       this.$emit('vmSelectIdList', this.selectIdList) | |||
|       this.$emit('vmSelectList', this.selectList) | |||
|     }, | |||
|     clearSelect() { | |||
|       console.log(1) | |||
|       this.selectIdList = [] | |||
|       this.selectList = [] | |||
|       this.$refs.multipleTable.clearSelection() | |||
|     }, | |||
|     selectable(row, index) { | |||
|       return this.selectDisableIdList.indexOf(row.id) < 0 | |||
|     }, | |||
|     // 查看详情 | |||
|     showDetail(scopeRow) { | |||
|       this.$emit('viewDetail', scopeRow.esPatientInfo.patientId) | |||
|       // this.patientId = scopeRow.patientId | |||
|       const mzName = scopeRow.mzDoctorName ? scopeRow.mzDoctorName : '' | |||
|       const jzNumber = scopeRow.jzNumber ? scopeRow.jzNumber : '' | |||
|       window.sessionStorage.setItem('mzDoctorName', mzName) | |||
|       window.sessionStorage.setItem('jzNumber', jzNumber) | |||
|     } | |||
|   } | |||
| } | |||
| </script> | |||
| 
 | |||
| <style lang="scss" scoped> | |||
| .searchContent { | |||
|   // 搜索内容 | |||
|   .overViewHtml { | |||
|     font-size: 14px; | |||
|     line-height: normal; | |||
|     white-space: pre-wrap; | |||
|   } | |||
| 
 | |||
|   .exam { | |||
|     display: flex; | |||
|     flex-wrap: wrap; | |||
|     padding-bottom: 10px; | |||
|     p { | |||
|       display: flex; | |||
|       flex-wrap: nowrap; | |||
|       height: 32px; | |||
|       line-height: 32px; | |||
|       width: 18%; | |||
|       background-color: #eee; | |||
|       padding: 0 10px; | |||
|       margin: 6px; | |||
|       span { | |||
|         display: block; | |||
|         // flex: 1; | |||
|         overflow: hidden; | |||
|         white-space: nowrap; | |||
|         text-overflow: ellipsis; | |||
|         text-align: center; | |||
|       } | |||
| 
 | |||
|       $width_num: 60px; | |||
|       .exam-name { | |||
|         width: calc(100% - #{$width_num}); | |||
|       } | |||
|       .exam-num { | |||
|         width: $width_num; | |||
|         color: #0072f9; | |||
|       } | |||
|     } | |||
|   } | |||
| } | |||
| 
 | |||
| ::v-deep .el-table__expanded-cell { | |||
|   padding: 5px 10px; | |||
|   background-color: #f5f7fa; | |||
| } | |||
| 
 | |||
| .dialog { | |||
|   ::v-deep .el-dialog__header { | |||
|     padding: 10px 20px; | |||
|     background: #696969; | |||
| 
 | |||
|     .el-dialog__title { | |||
|       color: #fff; | |||
|     } | |||
| 
 | |||
|     .el-dialog__headerbtn { | |||
|       top: 10px; | |||
|       font-size: 20px; | |||
| 
 | |||
|       .el-dialog__close { | |||
|         color: #fff; | |||
|         font-weight: bolder; | |||
|       } | |||
|     } | |||
|   } | |||
|   ::v-deep .el-dialog__body { | |||
|     min-height: calc(100% - 60px); | |||
|     background: #f5f5f5; | |||
|   } | |||
| } | |||
| </style> | |||
| 
 | |||
| @ -1,276 +0,0 @@ | |||
| <template> | |||
|   <div class="project-main"> | |||
|     <div v-if="!detailViewVisible" style="height: 100%"> | |||
|       <el-card shadow="never" class="aui-card--fill"> | |||
|         <el-form | |||
|           :inline="true" | |||
|           :model="dataForm" | |||
|           class="search-wrapper" | |||
|           @submit.native.prevent | |||
|           @keyup.enter.native="getDataListInitial" | |||
|         > | |||
|           <div class="search-wrapper-top"> | |||
|             <el-form-item class="search-item-input-wrapper"> | |||
|               <el-input v-model="keyWord" size="small" :placeholder="'全文检索(主要内容)关键词'" clearable> | |||
|                 <el-button slot="append" icon="el-icon-search" size="small" @click="getDataListInitial">搜索</el-button> | |||
|               </el-input> | |||
|             </el-form-item> | |||
|             <!-- 筛选条件 --> | |||
|             <el-form-item> | |||
|               <el-button type="primary" size="small" @click="queryItemVisible=!queryItemVisible">筛选 | |||
|                 <i v-if="!queryItemVisible" class="el-icon-arrow-right el-icon--right" /> | |||
|                 <i v-else class="el-icon-arrow-down el-icon--right" /> | |||
|               </el-button> | |||
|             </el-form-item> | |||
|             <!-- slot --> | |||
|             <el-form-item> | |||
|               <slot name="btn" /> | |||
|             </el-form-item> | |||
|           </div> | |||
|           <transition name="slide-fade"> | |||
|             <div v-show="queryItemVisible" class="find-"> | |||
|               <!-- 查询条件 --> | |||
|               <el-form-item label="必须" style="width:100%;"> | |||
|                 <item-select v-model="queryItemData_must" :connection="'must'" /> | |||
|               </el-form-item> | |||
|               <el-form-item label="可以" style="width:100%;"> | |||
|                 <item-select v-model="queryItemData_should" :connection="'should'" /> | |||
|               </el-form-item> | |||
|               <el-form-item label="排除" style="width:100%;"> | |||
|                 <item-select v-model="queryItemData_must_not" :connection="'must_not'" /> | |||
|               </el-form-item> | |||
|             </div> | |||
|           </transition> | |||
|         </el-form> | |||
|         <!-- 查询结果 --> | |||
|         <div class="result-wrapper"> | |||
|           <data-list | |||
|             ref="dataList" | |||
|             :data-list-loading="dataListLoading" | |||
|             :data-list="dataList" | |||
|             :project-id="projectId" | |||
|             v-bind="$attrs" | |||
|             @viewDetail="viewDetail" | |||
|             v-on="$listeners" | |||
|           /> | |||
|           <!-- 分页 --> | |||
|           <el-pagination | |||
|             background | |||
|             :current-page="page" | |||
|             :page-sizes="[10, 20, 50, 100, 200, 500]" | |||
|             :page-size="limit" | |||
|             :total="total" | |||
|             layout="total, prev, pager, next, jumper" | |||
|             @size-change="pageSizeChangeHandle" | |||
|             @current-change="pageCurrentChangeHandle" | |||
|           /> | |||
|         </div> | |||
|       </el-card> | |||
|       <!-- 底部全选反选 --> | |||
|       <!--      <checked-footer ref="checkfooter" table-ref="multipleTable" :current-table-list="currentTableList" :data-list="dataList">--> | |||
|       <!--        <div class="batch_button">--> | |||
|       <!--          <div class="batch_button">--> | |||
|       <!--            <el-button type="primary" size="small" :disabled="currentTableList.length > 0 ? false :true">加入分组--> | |||
|       <!--            </el-button>--> | |||
|       <!--          </div>--> | |||
|       <!--        </div>--> | |||
|       <!--      </checked-footer>--> | |||
|     </div> | |||
|     <detail-view v-if="detailViewVisible" ref="viewRef" :only-read="onlyRead" :is-search="'1'" :patient-id="patientId" @detailViewVisible="detailViewVisible=false" /> | |||
|   </div> | |||
| </template> | |||
| 
 | |||
| <script> | |||
| import detailView from '@/components/360View/index' // 360试图 | |||
| import checked from '@/mixins/checked' | |||
| import checkedFooter from '@/components/checked-footer' | |||
| import dataList from './data-list.vue' | |||
| import itemSelect from '@/components/item-select' | |||
| import Cookies from 'js-cookie' | |||
| 
 | |||
| export default { | |||
|   components: { | |||
|     itemSelect, | |||
|     detailView, | |||
|     dataList, | |||
|     checkedFooter | |||
|   }, | |||
|   mixins: [checked], | |||
|   inheritAttrs: false, | |||
|   props: { | |||
|     queryItem: { type: Object, default: () => { } }, // 可修改 | |||
|     projectId: { type: String, default: '' } | |||
|   }, | |||
|   data() { | |||
|     return { | |||
|       uploadUrl: window.SITE_CONFIG['apiURL'] + '/patient/data/searchByExcel', | |||
|       headers: { | |||
|         token: window.sessionStorage.getItem('xa-token') | |||
|       }, | |||
|       dataForm: {}, | |||
|       keyWord: '', | |||
|       patientId: '', | |||
|       limit: 10, | |||
|       page: 1, | |||
|       total: 0, | |||
|       onlyRead: true, | |||
|       dataListLoading: false, // 数据列表,loading状态 | |||
|       queryItemVisible: false, | |||
|       isExpandAll: false, | |||
|       detailViewVisible: false, | |||
|       queryItemData_must: [], | |||
|       queryItemData_should: [], | |||
|       queryItemData_must_not: [], | |||
|       dataList: [], | |||
|       currentTableList: [] | |||
|     } | |||
|   }, | |||
|   watch: { | |||
|     queryItem: { | |||
|       deep: true, | |||
|       handler(val) { | |||
|         if (val.must.length > 0 || val.should.length > 0 || val.must_not.length > 0) { | |||
|           this.queryItemVisible = true | |||
|           this.queryItemData_must = val.must | |||
|           this.queryItemData_should = val.should | |||
|           this.queryItemData_must_not = val.must_not | |||
|           // this.getDataList() | |||
|         } | |||
|       } | |||
|     } | |||
|   }, | |||
|   created() { }, | |||
|   mounted() { | |||
|     this.retrieval() | |||
|   }, | |||
|   methods: { | |||
|     reFresh() { | |||
|       this.pageCurrentChangeHandle(this.page) | |||
|     }, | |||
|     // 初始化查询 | |||
|     getDataListInitial() { | |||
|       this.page = 1 | |||
|       this.retrieval() | |||
|     }, | |||
|     viewDetail(val) { | |||
|       this.patientId = val | |||
|       this.detailViewVisible = true | |||
|     }, | |||
|     // 检索 | |||
|     retrieval() { | |||
|       this.getDataList() | |||
|       const queryItem = { | |||
|         must: this.queryItemData_must, | |||
|         should: this.queryItemData_should, | |||
|         must_not: this.queryItemData_must_not | |||
|       } | |||
|       this.$emit('update:queryItem', queryItem) | |||
|       // this.$emit('getQueryItem', queryItem) | |||
|     }, | |||
|     getDataList() { | |||
|       this.dataListLoading = true | |||
|       this.$http.post('/search/page', { | |||
|         filterItemList: [...this.queryItemData_must, ...this.queryItemData_should, ...this.queryItemData_must_not], | |||
|         key: this.keyWord, | |||
|         limit: this.limit, | |||
|         page: this.page | |||
|       }).then(({ data: res }) => { | |||
|         this.dataListLoading = false | |||
|         this.total = res.data.total | |||
|         this.dataList = res.data.list | |||
|         if (this.isExpandAll) { | |||
|           this.$refs.dataList.expend() | |||
|         } | |||
|       }).catch(() => { | |||
|         this.dataListLoading = false | |||
|       }) | |||
|     }, | |||
|     // 分页, 每页条数 | |||
|     pageSizeChangeHandle(val) { | |||
|       this.page = 1 | |||
|       this.limit = val | |||
|       this.retrieval() | |||
|     }, | |||
|     // 分页, 当前页 | |||
|     pageCurrentChangeHandle(val) { | |||
|       this.page = val | |||
|       this.retrieval() | |||
|     }, | |||
|     clearSelect() { | |||
|       this.$refs.dataList.clearSelect() | |||
|     }, | |||
|     beforeUpload() { | |||
|       this.dataListLoading = true | |||
|     }, | |||
|     // 文件上传成功时的钩子 | |||
|     onSuccess(response, file, fileList) { | |||
|       this.$message.success('检索完成!') | |||
|       this.dataListLoading = false | |||
|       if (response && response.data) { | |||
|         this.dataList = response.data | |||
|         this.total = response.data.length | |||
|       } else { | |||
|         this.dataList = [] | |||
|         this.total = 0 | |||
|       } | |||
|     }, | |||
|     onError() { | |||
|       this.dataListLoading = false | |||
|     } | |||
|   } | |||
| } | |||
| </script> | |||
| 
 | |||
| <style lang='scss' scoped> | |||
| .aui-card--fill{ | |||
|   height: 100%; | |||
|   ::v-deep .el-card__body{ | |||
|     height: 100%; | |||
|     overflow-y: auto; | |||
|   } | |||
| } | |||
| .search-wrapper-top { | |||
|   display: flex; | |||
|   align-items: center; | |||
|   .search-item-input-wrapper { | |||
|     width: 400px; | |||
|     padding-right: 10px; | |||
|     flex: 1; | |||
|   } | |||
| } | |||
| 
 | |||
| .result-wrapper { | |||
|   margin-top: 15px; | |||
| } | |||
| 
 | |||
| .slide-fade-enter-active { | |||
|   transition: all 0.3s ease; | |||
| } | |||
| .slide-fade-leave-active { | |||
|   transition: all 0.3s cubic-bezier(1, 0.5, 0.8, 1); | |||
| } | |||
| .slide-fade-enter, | |||
| .slide-fade-leave-to { | |||
|   transform: translateY(5px); | |||
|   opacity: 0; | |||
| } | |||
| </style> | |||
| 
 | |||
| <style lang="scss"> | |||
| .project-main { | |||
|   height: 100%; | |||
|   .search-wrapper-top { | |||
|     .el-form-item__content { | |||
|       width: 100%; | |||
|       line-height: 0; | |||
|     } | |||
|     .el-form-item { | |||
|       margin-bottom: 5px; | |||
| 
 | |||
|       .el-switch .is-active { | |||
|         color: inherit; | |||
|       } | |||
|     } | |||
|   } | |||
| } | |||
| </style> | |||
| @ -1,149 +0,0 @@ | |||
| <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> | |||
| @ -1,150 +0,0 @@ | |||
| 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++ | |||
|         } | |||
|       }) | |||
|     } | |||
|   } | |||
| } | |||
| @ -1,75 +0,0 @@ | |||
| <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> | |||
| @ -1,73 +0,0 @@ | |||
| <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> | |||
| @ -1,83 +0,0 @@ | |||
| <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> | |||
| @ -1,118 +0,0 @@ | |||
| <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> | |||
| @ -1,57 +0,0 @@ | |||
| <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> | |||
| @ -1,38 +0,0 @@ | |||
| <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> | |||
| @ -1,113 +0,0 @@ | |||
| 
 | |||
| <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> | |||
| @ -1,99 +0,0 @@ | |||
| <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> | |||
| @ -1,87 +0,0 @@ | |||
| <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> | |||
| @ -1,55 +0,0 @@ | |||
| <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> | |||
| @ -1,40 +0,0 @@ | |||
| <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> | |||
| @ -1,629 +0,0 @@ | |||
| <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> | |||
| @ -1,134 +0,0 @@ | |||
| <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> | |||
| @ -1,52 +0,0 @@ | |||
| <template> | |||
|   <el-cascader | |||
|     :value="value" | |||
|     style="width:100%;" | |||
|     :options="dataList" | |||
|     :props="cascaderProps" | |||
|     :placeholder="placeholder" | |||
|     clearable | |||
|     @change="$emit('input', $event)" | |||
|   /> | |||
| </template> | |||
| <script> | |||
| import { treeDataTranslateChildren } from '@/utils' | |||
| export default { | |||
|   props: { | |||
|     id: { | |||
|       type: String, | |||
|       default: '' | |||
|     }, | |||
|     value: { | |||
|       type: Array, | |||
|       default: () => [] | |||
|     }, | |||
|     placeholder: { | |||
|       type: String, | |||
|       default: '请选择地区' | |||
|     } | |||
|   }, | |||
|   data() { | |||
|     return { | |||
|       dataList: [], | |||
|       cascaderProps: { multiple: false, value: 'id', label: 'name' } | |||
|     } | |||
|   }, | |||
|   mounted() { | |||
|     this.getDataList() | |||
|   }, | |||
|   methods: { | |||
|     getDataList(id) { | |||
|       return this.$http.get('/sys/region/tree').then(({ data: res }) => { | |||
|         if (res.code === 0) { | |||
|           this.dataList = treeDataTranslateChildren(res.data) | |||
|           // this.dataList = treeDataTranslate(res.data, 'id', 'pid') | |||
|         } else { | |||
|           this.$message.error(res.msg) | |||
|         } | |||
|       }).catch(() => {}) | |||
|     } | |||
| 
 | |||
|   } | |||
| } | |||
| </script> | |||
| @ -1,195 +0,0 @@ | |||
| <template> | |||
|   <div class="time-line"> | |||
|     <div v-for="year in years" :key="year"> | |||
|       <!-- 年份 --> | |||
|       <div class="time-line-year"> | |||
|         <div class="time-line-item-tail" /> | |||
|         <div class="time-line-item-date">{{ year }} </div> | |||
|       </div> | |||
|       <div v-for="(item, index) in filterYearDataList(year)" :key="index" class="time-line-item"> | |||
|         <!-- 节点 --> | |||
|         <div class="time-line-item-node"> | |||
|           <i class="node" /> | |||
|           <!-- <div class="node" :class="{ nodeActive: item.active }" /> --> | |||
|         </div> | |||
|         <!-- 节点尾 --> | |||
|         <div class="time-line-item-tail" /> | |||
|         <!-- 内容 --> | |||
|         <div class="time-line-item-wrapper"> | |||
|           <!-- 抬头 --> | |||
|           <div class="time-line-item-wrapper-title" @click="selectMenu(dataList, index)"> | |||
|             <span class="title-date">{{ item.date|convertDate }} </span> | |||
|             <span class="title-name">{{ item.name }}</span> | |||
|           </div> | |||
|           <!-- 内容 --> | |||
|           <div v-for="(item2, index2) in item.list" :key="index2" class="time-line-item-wrapper-item"> | |||
|             <span>{{ item2.name }}</span> | |||
|           </div> | |||
|         </div> | |||
|       </div> | |||
|     </div> | |||
| 
 | |||
|   </div> | |||
| </template> | |||
| 
 | |||
| <script> | |||
| import { formatDate } from '@/utils/index.js' | |||
| export default { | |||
|   name: 'TimeLine', | |||
|   props: { | |||
|     dataList: { | |||
|       type: Array, | |||
|       required: true | |||
|     } | |||
|   }, | |||
|   data() { | |||
|     return { | |||
|     } | |||
|   }, | |||
|   computed: { | |||
|     years() { | |||
|       const result = [] | |||
|       this.dataList.forEach(item => { | |||
|         const year = formatDate(item.date, 'YYYY') | |||
|         if (result.indexOf(year) < 0) { | |||
|           result.push(year) | |||
|         } | |||
|       }) | |||
|       return result | |||
|     } | |||
|   }, | |||
|   methods: { | |||
|     selectMenu(arr, index) { | |||
|       arr[index].active = !arr[index].active | |||
|     }, | |||
|     filterYearDataList(val) { | |||
|       return this.dataList.filter(item => { | |||
|         return item.date.indexOf(val) >= 0 | |||
|       }) | |||
|     } | |||
|   } | |||
| } | |||
| </script> | |||
| 
 | |||
| <style lang="scss" scoped> | |||
| $color: #fff; | |||
| $containerBgColor: #333335; | |||
| $borderColor: #424242; | |||
| $paddingRight: 20px; | |||
| 
 | |||
| .time-line { | |||
|   margin: 0; | |||
|   padding: 5px $paddingRight; | |||
|   font-size: 14px; | |||
|   color: $color; | |||
|   background-color: $containerBgColor; | |||
|   list-style: none; | |||
| 
 | |||
|   .time-line-year { | |||
|     position: relative; | |||
|     height: 50px; | |||
| 
 | |||
|     // 年份 | |||
|     .time-line-item-date { | |||
|       position: relative; | |||
|       top: 13px; | |||
|       padding-left: 10px; | |||
|       margin-left: -10px; | |||
|       margin-right: -$paddingRight; | |||
|       height: 24px; | |||
|       line-height: 24px; | |||
|       font-size: 16px; | |||
|       font-style: oblique; | |||
|       font-family: fantasy; | |||
|       border-top-left-radius: 10px; | |||
|       border-bottom-left-radius: 10px; | |||
|       background-color: #424242; | |||
|       letter-spacing: 1px; | |||
|     } | |||
|   } | |||
| 
 | |||
|   .time-line-item { | |||
|     position: relative; | |||
|     padding-bottom: 10px; | |||
| 
 | |||
|     // 节点 | |||
|     .time-line-item-node { | |||
|       z-index: 3; | |||
|       display: inline-block; | |||
|       position: absolute; | |||
|       border-radius: 50%; | |||
|       display: flex; | |||
|       justify-content: center; | |||
|       align-items: center; | |||
|       width: 16px; | |||
|       height: 15px; | |||
|       background-color: #fff; | |||
|       border: 1px solid #3e9fff; | |||
|       border-color: $borderColor; | |||
| 
 | |||
|       .node { | |||
|         width: 6px; | |||
|         height: 6px; | |||
|         border-radius: 50%; | |||
|         background-color: #959595; | |||
|       } | |||
|     } | |||
| 
 | |||
|     // wrapper | |||
|     .time-line-item-wrapper { | |||
|       position: relative; | |||
|       padding-left: 28px; | |||
|       top: -3px; | |||
| 
 | |||
|       // 抬头 | |||
|       .time-line-item-wrapper-title { | |||
|         color: $color; | |||
| 
 | |||
|         .title-date { | |||
|           display: inline-block; | |||
|           padding-right: 10px; | |||
|           color: #ecb36d; | |||
|         } | |||
|         .title-name { | |||
|           display: inline-block; | |||
|           background-color: #fff; | |||
|           color: #000; | |||
|           cursor: pointer; | |||
|           padding: 0 10px; | |||
|           border-radius: 5px; | |||
|         } | |||
|       } | |||
| 
 | |||
|       // 内容 | |||
|       .time-line-item-wrapper-item { | |||
|         margin-top: 5px; | |||
|         padding: 2px 0px; | |||
|         // background-color: #fff; | |||
|         color: #fff; | |||
|         border-radius: 3px; | |||
|       } | |||
|     } | |||
| 
 | |||
|     .transitionCon { | |||
|       position: relative; | |||
|     } | |||
|   } | |||
| } | |||
| 
 | |||
| // 节点尾(竖线) | |||
| .time-line-item-tail { | |||
|   position: absolute; | |||
|   left: 7px; | |||
|   top: 4px; | |||
|   height: 100%; | |||
|   border-left: 3px solid; | |||
|   border-color: $color; | |||
| } | |||
| 
 | |||
| .nodeActive { | |||
|   background-color: #3e9fff !important; | |||
| } | |||
| // .time-line .time-line-item:last-child .time-line-item-tail { | |||
| //   display: none; | |||
| // } | |||
| </style> | |||
| @ -1,54 +0,0 @@ | |||
| <template> | |||
|   <el-select | |||
|     :value="value" | |||
|     :placeholder="placeholder" | |||
|     :multiple="multiple" | |||
|     clearable | |||
|     filterable | |||
|     style="width:100%;" | |||
|     @change="$emit('input', $event)" | |||
|   > | |||
|     <el-option | |||
|       v-for="item in dataList" | |||
|       :key="item.id" | |||
|       :label="item.jobNumber?`${item.realName}(${item.jobNumber})`:item.realName" | |||
|       :value="item.id" | |||
|     /> | |||
|   </el-select> | |||
| </template> | |||
| <script> | |||
| export default { | |||
|   props: { | |||
|     deptId: { type: String, default: '' }, | |||
|     value: { type: String, default: '' }, | |||
|     multiple: { type: Boolean, default: false }, | |||
|     placeholder: { type: String, default: '请选择' } | |||
|   }, | |||
|   data() { | |||
|     return { | |||
|       dataList: [] | |||
|     } | |||
|   }, | |||
|   // watch: { | |||
|   //   deptId(newVal, oldval) { | |||
|   //     if (newVal) { | |||
|   //       this.getDataList() | |||
|   //     } else { | |||
|   //       this.dataList = [] | |||
|   //     } | |||
|   //   } | |||
|   // }, | |||
|   mounted() { | |||
|     this.getDataList() | |||
|     this.getDataList() | |||
|   }, | |||
|   methods: { | |||
|     // 添加项目时,获取人员列表 | |||
|     getDataList(id) { | |||
|       return this.$http.get('/project/getPresonListForAddProject').then(({ data: res }) => { | |||
|         if (res.code === 0) { this.dataList = res.data } else { this.$message.error(res.msg) } | |||
|       }).catch(() => {}) | |||
|     } | |||
|   } | |||
| } | |||
| </script> | |||
| @ -1,217 +0,0 @@ | |||
| /** | |||
|  * Should objects be aligned by a bounding box? | |||
|  * [Bug] Scaled objects sometimes can not be aligned by edges | |||
|  * https://github.com/fabricjs/fabric.js/blob/master/lib/aligning_guidelines.js
 | |||
|  */ | |||
| function initAligningGuidelines(canvas) { | |||
| 
 | |||
|     var ctx = canvas.getSelectionContext(), | |||
|         aligningLineOffset = 5, | |||
|         aligningLineMargin = 4, | |||
|         aligningLineWidth = 1, | |||
|         aligningLineColor = 'rgb(0,255,0)', | |||
|         viewportTransform, | |||
|         zoom = 1; | |||
| 
 | |||
|     function drawVerticalLine(coords) { | |||
|         drawLine( | |||
|             coords.x + 0.5, | |||
|             coords.y1 > coords.y2 ? coords.y2 : coords.y1, | |||
|             coords.x + 0.5, | |||
|             coords.y2 > coords.y1 ? coords.y2 : coords.y1); | |||
|     } | |||
| 
 | |||
|     function drawHorizontalLine(coords) { | |||
|         drawLine( | |||
|             coords.x1 > coords.x2 ? coords.x2 : coords.x1, | |||
|             coords.y + 0.5, | |||
|             coords.x2 > coords.x1 ? coords.x2 : coords.x1, | |||
|             coords.y + 0.5); | |||
|     } | |||
| 
 | |||
|     function drawLine(x1, y1, x2, y2) { | |||
|         ctx.save(); | |||
|         ctx.lineWidth = aligningLineWidth; | |||
|         ctx.strokeStyle = aligningLineColor; | |||
|         ctx.beginPath(); | |||
|         ctx.moveTo(((x1 + viewportTransform[4]) * zoom), ((y1 + viewportTransform[5]) * zoom)); | |||
|         ctx.lineTo(((x2 + viewportTransform[4]) * zoom), ((y2 + viewportTransform[5]) * zoom)); | |||
|         ctx.stroke(); | |||
|         ctx.restore(); | |||
|     } | |||
| 
 | |||
|     function isInRange(value1, value2) { | |||
|         value1 = Math.round(value1); | |||
|         value2 = Math.round(value2); | |||
|         for (var i = value1 - aligningLineMargin, len = value1 + aligningLineMargin; i <= len; i++) { | |||
|             if (i === value2) { | |||
|                 return true; | |||
|             } | |||
|         } | |||
|         return false; | |||
|     } | |||
| 
 | |||
|     var verticalLines = [], | |||
|         horizontalLines = []; | |||
| 
 | |||
|     canvas.on('mouse:down', function () { | |||
|         viewportTransform = canvas.viewportTransform; | |||
|         zoom = canvas.getZoom(); | |||
|     }); | |||
| 
 | |||
|     canvas.on('object:moving', function (e) { | |||
| 
 | |||
|         var activeObject = e.target, | |||
|             canvasObjects = canvas.getObjects(), | |||
|             activeObjectCenter = activeObject.getCenterPoint(), | |||
|             activeObjectLeft = activeObjectCenter.x, | |||
|             activeObjectTop = activeObjectCenter.y, | |||
|             activeObjectBoundingRect = activeObject.getBoundingRect(), | |||
|             activeObjectHeight = activeObjectBoundingRect.height / viewportTransform[3], | |||
|             activeObjectWidth = activeObjectBoundingRect.width / viewportTransform[0], | |||
|             horizontalInTheRange = false, | |||
|             verticalInTheRange = false, | |||
|             transform = canvas._currentTransform; | |||
| 
 | |||
|         if (!transform) return; | |||
| 
 | |||
|         // It should be trivial to DRY this up by encapsulating (repeating) creation of x1, x2, y1, and y2 into functions,
 | |||
|         // but we're not doing it here for perf. reasons -- as this a function that's invoked on every mouse move
 | |||
| 
 | |||
|         for (var i = canvasObjects.length; i--;) { | |||
| 
 | |||
|             if (canvasObjects[i] === activeObject) continue; | |||
| 
 | |||
|             var objectCenter = canvasObjects[i].getCenterPoint(), | |||
|                 objectLeft = objectCenter.x, | |||
|                 objectTop = objectCenter.y, | |||
|                 objectBoundingRect = canvasObjects[i].getBoundingRect(), | |||
|                 objectHeight = objectBoundingRect.height / viewportTransform[3], | |||
|                 objectWidth = objectBoundingRect.width / viewportTransform[0]; | |||
| 
 | |||
|             // snap by the horizontal center line
 | |||
|             if (isInRange(objectLeft, activeObjectLeft)) { | |||
|                 verticalInTheRange = true; | |||
|                 verticalLines.push({ | |||
|                     x: objectLeft, | |||
|                     y1: (objectTop < activeObjectTop) | |||
|                         ? (objectTop - objectHeight / 2 - aligningLineOffset) | |||
|                         : (objectTop + objectHeight / 2 + aligningLineOffset), | |||
|                     y2: (activeObjectTop > objectTop) | |||
|                         ? (activeObjectTop + activeObjectHeight / 2 + aligningLineOffset) | |||
|                         : (activeObjectTop - activeObjectHeight / 2 - aligningLineOffset) | |||
|                 }); | |||
|                 activeObject.setPositionByOrigin(new fabric.Point(objectLeft, activeObjectTop), 'center', 'center'); | |||
|             } | |||
| 
 | |||
|             // snap by the left edge
 | |||
|             if (isInRange(objectLeft - objectWidth / 2, activeObjectLeft - activeObjectWidth / 2)) { | |||
|                 verticalInTheRange = true; | |||
|                 verticalLines.push({ | |||
|                     x: objectLeft - objectWidth / 2, | |||
|                     y1: (objectTop < activeObjectTop) | |||
|                         ? (objectTop - objectHeight / 2 - aligningLineOffset) | |||
|                         : (objectTop + objectHeight / 2 + aligningLineOffset), | |||
|                     y2: (activeObjectTop > objectTop) | |||
|                         ? (activeObjectTop + activeObjectHeight / 2 + aligningLineOffset) | |||
|                         : (activeObjectTop - activeObjectHeight / 2 - aligningLineOffset) | |||
|                 }); | |||
|                 activeObject.setPositionByOrigin(new fabric.Point(objectLeft - objectWidth / 2 + activeObjectWidth / 2, activeObjectTop), 'center', 'center'); | |||
|             } | |||
| 
 | |||
|             // snap by the right edge
 | |||
|             if (isInRange(objectLeft + objectWidth / 2, activeObjectLeft + activeObjectWidth / 2)) { | |||
|                 verticalInTheRange = true; | |||
|                 verticalLines.push({ | |||
|                     x: objectLeft + objectWidth / 2, | |||
|                     y1: (objectTop < activeObjectTop) | |||
|                         ? (objectTop - objectHeight / 2 - aligningLineOffset) | |||
|                         : (objectTop + objectHeight / 2 + aligningLineOffset), | |||
|                     y2: (activeObjectTop > objectTop) | |||
|                         ? (activeObjectTop + activeObjectHeight / 2 + aligningLineOffset) | |||
|                         : (activeObjectTop - activeObjectHeight / 2 - aligningLineOffset) | |||
|                 }); | |||
|                 activeObject.setPositionByOrigin(new fabric.Point(objectLeft + objectWidth / 2 - activeObjectWidth / 2, activeObjectTop), 'center', 'center'); | |||
|             } | |||
| 
 | |||
|             // snap by the vertical center line
 | |||
|             if (isInRange(objectTop, activeObjectTop)) { | |||
|                 horizontalInTheRange = true; | |||
|                 horizontalLines.push({ | |||
|                     y: objectTop, | |||
|                     x1: (objectLeft < activeObjectLeft) | |||
|                         ? (objectLeft - objectWidth / 2 - aligningLineOffset) | |||
|                         : (objectLeft + objectWidth / 2 + aligningLineOffset), | |||
|                     x2: (activeObjectLeft > objectLeft) | |||
|                         ? (activeObjectLeft + activeObjectWidth / 2 + aligningLineOffset) | |||
|                         : (activeObjectLeft - activeObjectWidth / 2 - aligningLineOffset) | |||
|                 }); | |||
|                 activeObject.setPositionByOrigin(new fabric.Point(activeObjectLeft, objectTop), 'center', 'center'); | |||
|             } | |||
| 
 | |||
|             // snap by the top edge
 | |||
|             if (isInRange(objectTop - objectHeight / 2, activeObjectTop - activeObjectHeight / 2)) { | |||
|                 horizontalInTheRange = true; | |||
|                 horizontalLines.push({ | |||
|                     y: objectTop - objectHeight / 2, | |||
|                     x1: (objectLeft < activeObjectLeft) | |||
|                         ? (objectLeft - objectWidth / 2 - aligningLineOffset) | |||
|                         : (objectLeft + objectWidth / 2 + aligningLineOffset), | |||
|                     x2: (activeObjectLeft > objectLeft) | |||
|                         ? (activeObjectLeft + activeObjectWidth / 2 + aligningLineOffset) | |||
|                         : (activeObjectLeft - activeObjectWidth / 2 - aligningLineOffset) | |||
|                 }); | |||
|                 activeObject.setPositionByOrigin(new fabric.Point(activeObjectLeft, objectTop - objectHeight / 2 + activeObjectHeight / 2), 'center', 'center'); | |||
|             } | |||
| 
 | |||
|             // snap by the bottom edge
 | |||
|             if (isInRange(objectTop + objectHeight / 2, activeObjectTop + activeObjectHeight / 2)) { | |||
|                 horizontalInTheRange = true; | |||
|                 horizontalLines.push({ | |||
|                     y: objectTop + objectHeight / 2, | |||
|                     x1: (objectLeft < activeObjectLeft) | |||
|                         ? (objectLeft - objectWidth / 2 - aligningLineOffset) | |||
|                         : (objectLeft + objectWidth / 2 + aligningLineOffset), | |||
|                     x2: (activeObjectLeft > objectLeft) | |||
|                         ? (activeObjectLeft + activeObjectWidth / 2 + aligningLineOffset) | |||
|                         : (activeObjectLeft - activeObjectWidth / 2 - aligningLineOffset) | |||
|                 }); | |||
|                 activeObject.setPositionByOrigin(new fabric.Point(activeObjectLeft, objectTop + objectHeight / 2 - activeObjectHeight / 2), 'center', 'center'); | |||
|             } | |||
|         } | |||
| 
 | |||
|         if (!horizontalInTheRange) { | |||
|             horizontalLines.length = 0; | |||
|         } | |||
| 
 | |||
|         if (!verticalInTheRange) { | |||
|             verticalLines.length = 0; | |||
|         } | |||
|     }); | |||
| 
 | |||
|     canvas.on('before:render', function () { | |||
|         // fix 保存图片时报错
 | |||
|         try { | |||
|             canvas.clearContext(canvas.contextTop); | |||
|         } catch (error) { | |||
| 
 | |||
|         } | |||
|     }); | |||
| 
 | |||
|     canvas.on('after:render', function () { | |||
|         for (var i = verticalLines.length; i--;) { | |||
|             drawVerticalLine(verticalLines[i]); | |||
|         } | |||
|         for (var i = horizontalLines.length; i--;) { | |||
|             drawHorizontalLine(horizontalLines[i]); | |||
|         } | |||
| 
 | |||
|         verticalLines.length = horizontalLines.length = 0; | |||
|     }); | |||
| 
 | |||
|     canvas.on('mouse:up', function () { | |||
|         verticalLines.length = horizontalLines.length = 0; | |||
|         canvas.renderAll(); | |||
|     }); | |||
| } | |||
| export default initAligningGuidelines; | |||
| @ -1,60 +0,0 @@ | |||
| /* | |||
|  * @Author: 秦少卫 | |||
|  * @Date: 2023-01-09 22:49:02 | |||
|  * @LastEditors: 秦少卫 | |||
|  * @LastEditTime: 2023-01-09 23:08:54 | |||
|  * @Description: 控制条样式 | |||
|  */ | |||
| 
 | |||
| import { fabric } from 'fabric'; | |||
| 
 | |||
| function initControls(canvas) { | |||
| 
 | |||
|     var deleteIcon = "data:image/svg+xml,%3C%3Fxml version='1.0' encoding='utf-8'%3F%3E%3C!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'%3E%3Csvg version='1.1' id='Ebene_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='595.275px' height='595.275px' viewBox='200 215 230 470' xml:space='preserve'%3E%3Ccircle style='fill:%23F44336;' cx='299.76' cy='439.067' r='218.516'/%3E%3Cg%3E%3Crect x='267.162' y='307.978' transform='matrix(0.7071 -0.7071 0.7071 0.7071 -222.6202 340.6915)' style='fill:white;' width='65.545' height='262.18'/%3E%3Crect x='266.988' y='308.153' transform='matrix(0.7071 0.7071 -0.7071 0.7071 398.3889 -83.3116)' style='fill:white;' width='65.544' height='262.179'/%3E%3C/g%3E%3C/svg%3E"; | |||
|     var img = document.createElement('img'); | |||
|     img.src = deleteIcon; | |||
|     fabric.Object.prototype.controls.deleteControl = new fabric.Control({ | |||
|         x: 0.5, | |||
|         y: -0.5, | |||
|         offsetY: -16, | |||
|         offsetX: 16, | |||
|         cursorStyle: 'pointer', | |||
|         mouseUpHandler: deleteObject, | |||
|         render: renderIcon, | |||
|         cornerSize: 24 | |||
|     }); | |||
| 
 | |||
|     function deleteObject() { | |||
|         const activeObject = canvas.getActiveObjects() | |||
|         if (activeObject) { | |||
|             activeObject.map(item => canvas.remove(item)) | |||
|             canvas.requestRenderAll() | |||
|             canvas.discardActiveObject() | |||
|         } | |||
|     } | |||
| 
 | |||
|     function renderIcon(ctx, left, top, styleOverride, fabricObject) { | |||
|         var size = this.cornerSize; | |||
|         ctx.save(); | |||
|         ctx.translate(left, top); | |||
|         ctx.rotate(fabric.util.degreesToRadians(fabricObject.angle)); | |||
|         ctx.drawImage(img, -size / 2, -size / 2, size, size); | |||
|         ctx.restore(); | |||
|     } | |||
| 
 | |||
|     setControlsStyle() | |||
| } | |||
| 
 | |||
| function setControlsStyle(){ | |||
|     fabric.Object.prototype.transparentCorners = false; | |||
|     fabric.Object.prototype.cornerSize = 10; | |||
|     fabric.Object.prototype.cornerStrokeColor = '#C2C2C2'; | |||
|     fabric.Object.prototype.cornerColor = '#ffffff'; | |||
|     fabric.Object.prototype.cornerStyle = 'circle'; | |||
|     fabric.Object.prototype.borderColor = '#85CCF9'; | |||
| } | |||
| 
 | |||
| 
 | |||
| 
 | |||
| 
 | |||
| export default initControls | |||
| @ -1,86 +0,0 @@ | |||
| /* | |||
|  * @Author: 秦少卫 | |||
|  * @Date: 2022-12-07 23:50:05 | |||
|  * @LastEditors: 秦少卫 | |||
|  * @LastEditTime: 2023-01-07 02:06:16 | |||
|  * @Description: 快捷键功能 | |||
|  */ | |||
| 
 | |||
| import hotkeys from 'hotkeys-js' | |||
| import { cloneDeep } from 'lodash-es' | |||
| import { v4 as uuid } from 'uuid' | |||
| 
 | |||
| const keyNames = { | |||
|   lrdu: 'left,right,down,up', // 左右上下
 | |||
|   backspace: 'backspace', // backspace键盘
 | |||
|   ctrlz: 'ctrl+z', | |||
|   ctrlc: 'ctrl+c', | |||
|   ctrlv: 'ctrl+v' | |||
| } | |||
| 
 | |||
| function initHotkeys(canvas) { | |||
|   // 删除快捷键
 | |||
|   hotkeys(keyNames.backspace, function() { | |||
|     const activeObject = canvas.getActiveObjects() | |||
|     if (activeObject) { | |||
|       activeObject.map(item => canvas.remove(item)) | |||
|       canvas.requestRenderAll() | |||
|       canvas.discardActiveObject() | |||
|     } | |||
|   }) | |||
| 
 | |||
|   // 移动快捷键
 | |||
|   hotkeys(keyNames.lrdu, (event, handler) => { | |||
|     const activeObject = canvas.getActiveObject() | |||
|     if (activeObject) { | |||
|       switch (handler.key) { | |||
|         case 'left': | |||
|           activeObject.set('left', activeObject.left - 1) | |||
|           break | |||
|         case 'right': | |||
|           activeObject.set('left', activeObject.left + 1) | |||
|           break | |||
|         case 'down': | |||
|           activeObject.set('top', activeObject.top + 1) | |||
|           break | |||
|         case 'up': | |||
|           activeObject.set('top', activeObject.top - 1) | |||
|           break | |||
|         default: | |||
|       } | |||
|       canvas.renderAll() | |||
|     } | |||
|   }) | |||
| 
 | |||
|   // 复制粘贴
 | |||
|   copyElement(canvas) | |||
| } | |||
| 
 | |||
| function copyElement(canvas) { | |||
|   let copyEl = null | |||
| 
 | |||
|   // 复制
 | |||
|   hotkeys(keyNames.ctrlc, (event, handler) => { | |||
|     const activeObject = canvas.getActiveObjects() | |||
|     if (activeObject.length === 0) return | |||
|     copyEl = cloneDeep(activeObject[0]) | |||
|     if (copyEl.left === activeObject[0].left) { | |||
|       copyEl.left += 10 | |||
|       copyEl.top += 10 | |||
|     } | |||
|     this.$message.success('复制成功') | |||
|   }) | |||
|   // 粘贴
 | |||
|   hotkeys(keyNames.ctrlv, (event, handler) => { | |||
|     if (!copyEl) return this.$message.warning('暂无复制内容') | |||
|     const myCopyEl = cloneDeep(copyEl) | |||
|     myCopyEl.id = uuid() | |||
|     copyEl.left += 10 | |||
|     copyEl.top += 10 | |||
|     canvas.add(myCopyEl) | |||
|     canvas.setActiveObject(myCopyEl) | |||
|   }) | |||
| } | |||
| 
 | |||
| export default initHotkeys | |||
| export { keyNames, hotkeys } | |||
| @ -1,89 +0,0 @@ | |||
| /* | |||
|  * @Author: 秦少卫 | |||
|  * @Date: 2023-01-06 23:40:09 | |||
|  * @LastEditors: 秦少卫 | |||
|  * @LastEditTime: 2023-01-07 01:35:50 | |||
|  * @Description: 线条绘制 | |||
|  */ | |||
| 
 | |||
| import { v4 as uuid } from 'uuid'; | |||
| import Arrow from "@/core/objects/Arrow"; | |||
| function initializeLineDrawing (canvas, defaultPosition) { | |||
|     let isDrawingLine = false,isDrawingLineMode = false, isArrow = false, | |||
|         lineToDraw, pointer, pointerPoints | |||
|     canvas.on('mouse:down', (o) => { | |||
|         if (!isDrawingLineMode) return | |||
| 
 | |||
|         isDrawingLine = true | |||
|         pointer = canvas.getPointer(o.e) | |||
|         pointerPoints = [pointer.x, pointer.y, pointer.x, pointer.y] | |||
| 
 | |||
| 
 | |||
|         const nodeHandler = isArrow ? Arrow : fabric.Line | |||
|         lineToDraw = new nodeHandler(pointerPoints, { | |||
|             strokeWidth: 2, | |||
|             stroke: '#000000', | |||
|             ...defaultPosition, | |||
|             id: uuid(), | |||
|         }); | |||
| 
 | |||
|         lineToDraw.selectable = false | |||
|         lineToDraw.evented = false | |||
|         lineToDraw.strokeUniform = true | |||
|         canvas.add(lineToDraw) | |||
|     }); | |||
| 
 | |||
|     canvas.on('mouse:move', (o) => { | |||
|         if (!isDrawingLine) return | |||
| 
 | |||
|         pointer = canvas.getPointer(o.e) | |||
| 
 | |||
|         if (o.e.shiftKey) { | |||
|             // calc angle
 | |||
|             let startX = pointerPoints[0] | |||
|             let startY = pointerPoints[1] | |||
|             let x2 = pointer.x - startX | |||
|             let y2 = pointer.y - startY | |||
|             let r = Math.sqrt(x2 * x2 + y2 * y2) | |||
|             let angle = (Math.atan2(y2, x2) / Math.PI * 180) | |||
| 
 | |||
|             angle = parseInt(((angle + 7.5) % 360) / 15) * 15 | |||
| 
 | |||
|             let cosx = r * Math.cos(angle * Math.PI / 180) | |||
|             let sinx = r * Math.sin(angle * Math.PI / 180) | |||
| 
 | |||
|             lineToDraw.set({ | |||
|                 x2: cosx + startX, | |||
|                 y2: sinx + startY | |||
|             }) | |||
| 
 | |||
|         } else { | |||
|             lineToDraw.set({ | |||
|                 x2: pointer.x, | |||
|                 y2: pointer.y | |||
|             }) | |||
|         } | |||
| 
 | |||
|         canvas.renderAll() | |||
| 
 | |||
|     }); | |||
| 
 | |||
|     canvas.on('mouse:up', () => { | |||
|         if (!isDrawingLine) return | |||
|         lineToDraw.setCoords() | |||
|         isDrawingLine = false | |||
|     }); | |||
| 
 | |||
|     return { | |||
|         setArrow(params){ | |||
|             isArrow = params | |||
|         }, | |||
|         setMode(params){ | |||
|             isDrawingLineMode = params | |||
|         } | |||
|     } | |||
| 
 | |||
| } | |||
| 
 | |||
| 
 | |||
| export default initializeLineDrawing; | |||
| @ -1,46 +0,0 @@ | |||
| /* | |||
|  * @Author: 秦少卫 | |||
|  * @Date: 2023-01-07 01:15:50 | |||
|  * @LastEditors: 秦少卫 | |||
|  * @LastEditTime: 2023-01-07 01:16:07 | |||
|  * @Description: 箭头元素 | |||
|  */ | |||
| import { fabric } from 'fabric'; | |||
| 
 | |||
| const Arrow = fabric.util.createClass(fabric.Line, { | |||
| 	type: 'arrow', | |||
| 	superType: 'drawing', | |||
| 	initialize(points, options) { | |||
| 		if (!points) { | |||
| 			const { x1, x2, y1, y2 } = options; | |||
| 			points = [x1, y1, x2, y2]; | |||
| 		} | |||
| 		options = options || {}; | |||
| 		this.callSuper('initialize', points, options); | |||
| 	}, | |||
| 	_render(ctx) { | |||
| 		this.callSuper('_render', ctx); | |||
| 		ctx.save(); | |||
| 		const xDiff = this.x2 - this.x1; | |||
| 		const yDiff = this.y2 - this.y1; | |||
| 		const angle = Math.atan2(yDiff, xDiff); | |||
| 		ctx.translate((this.x2 - this.x1) / 2, (this.y2 - this.y1) / 2); | |||
| 		ctx.rotate(angle); | |||
| 		ctx.beginPath(); | |||
| 		// Move 5px in front of line to start the arrow so it does not have the square line end showing in front (0,0)
 | |||
| 		ctx.moveTo(5, 0); | |||
| 		ctx.lineTo(-5, 5); | |||
| 		ctx.lineTo(-5, -5); | |||
| 		ctx.closePath(); | |||
| 		ctx.fillStyle = this.stroke; | |||
| 		ctx.fill(); | |||
| 		ctx.restore(); | |||
| 	}, | |||
| }); | |||
| 
 | |||
| Arrow.fromObject = (options, callback) => { | |||
| 	const { x1, x2, y1, y2 } = options; | |||
| 	return callback(new Arrow([x1, y1, x2, y2], options)); | |||
| }; | |||
| 
 | |||
| export default Arrow; | |||
| @ -1,46 +1,46 @@ | |||
| 
 | |||
| import { formatDate, formatTime, getAge, desensitizeField } from '@/utils/index.js' | |||
| 
 | |||
| // --------------------------------------------------【杂项】--------------------------------------------------
 | |||
| // 性别
 | |||
| export const f_sex = (val) => { | |||
|   return val ? val.replace('性', '') : '' | |||
| } | |||
| // --------------------------------------------------【日期】--------------------------------------------------
 | |||
| // 月份日期过滤器
 | |||
| export const convertDate = (val) => { | |||
|   return formatDate(val, 'MM-DD') | |||
| } | |||
| // 年过滤器
 | |||
| export const convertYear = (val) => { | |||
|   return formatDate(val, 'MM-DD') | |||
| } | |||
| // 年月日过滤器(xxxx年x月xx日)
 | |||
| export const dateFilterOne = (val) => { | |||
|   return formatDate(val, 'yyyy年MM月dd日') | |||
| } | |||
| // 年月日过滤器(yyyy-MM-dd)
 | |||
| export const dateFilterTwo = (val) => { | |||
|   return formatDate(val, 'yyyy-MM-dd') | |||
| } | |||
| // 年月日过滤器(yyyyMMdd)
 | |||
| export const dateFilterThree = (val) => { | |||
|   return formatDate(val, 'yyyyMMdd') | |||
| } | |||
| // 根据出生日期获取年龄
 | |||
| export const f_getAge = (val) => { | |||
|   return val ? getAge(val) : '' | |||
| } | |||
| // --------------------------------------------------【脱敏】--------------------------------------------------
 | |||
| // 身份证号
 | |||
| export const f_desensitize_idNumber = (val) => { | |||
|   return desensitizeField(val, 6, 4, '********') | |||
| } | |||
| // 联系电话
 | |||
| export const f_desensitize_phone = (val) => { | |||
|   return desensitizeField(val, 4, 4, '****') | |||
| } | |||
| // 姓名
 | |||
| export const f_desensitize_name = (val) => { | |||
|   return desensitizeField(val, 1, (val && val.length) > 2 ? 1 : 0) | |||
| } | |||
| 
 | |||
| import { formatDate, formatTime, getAge, desensitizeField } from '@/utils/index.js' | |||
| 
 | |||
| // --------------------------------------------------【杂项】--------------------------------------------------
 | |||
| // 性别
 | |||
| export const f_sex = (val) => { | |||
|   return val ? val.replace('性', '') : '' | |||
| } | |||
| // --------------------------------------------------【日期】--------------------------------------------------
 | |||
| // 月份日期过滤器
 | |||
| export const convertDate = (val) => { | |||
|   return formatDate(val, 'MM-DD') | |||
| } | |||
| // 年过滤器
 | |||
| export const convertYear = (val) => { | |||
|   return formatDate(val, 'MM-DD') | |||
| } | |||
| // 年月日过滤器(xxxx年x月xx日)
 | |||
| export const dateFilterOne = (val) => { | |||
|   return formatDate(val, 'yyyy年MM月dd日') | |||
| } | |||
| // 年月日过滤器(yyyy-MM-dd)
 | |||
| export const dateFilterTwo = (val) => { | |||
|   return formatDate(val, 'yyyy-MM-dd') | |||
| } | |||
| // 年月日过滤器(yyyyMMdd)
 | |||
| export const dateFilterThree = (val) => { | |||
|   return formatDate(val, 'yyyyMMdd') | |||
| } | |||
| // 根据出生日期获取年龄
 | |||
| export const f_getAge = (val) => { | |||
|   return val ? getAge(val) : '' | |||
| } | |||
| // --------------------------------------------------【脱敏】--------------------------------------------------
 | |||
| // 身份证号
 | |||
| export const f_desensitize_idNumber = (val) => { | |||
|   return desensitizeField(val, 6, 4, '********') | |||
| } | |||
| // 联系电话
 | |||
| export const f_desensitize_phone = (val) => { | |||
|   return desensitizeField(val, 4, 4, '****') | |||
| } | |||
| // 姓名
 | |||
| export const f_desensitize_name = (val) => { | |||
|   return desensitizeField(val, 1, (val && val.length) > 2 ? 1 : 0) | |||
| } | |||
|  | |||
| @ -1,107 +0,0 @@ | |||
| export default { | |||
|   data() { | |||
|     return { | |||
|       CRFLoading: false, | |||
|       timer: null, | |||
|       flag: 1, | |||
|       multipleSelectFullSetTime: null | |||
|     } | |||
|   }, | |||
|   methods: { | |||
|     // 智能填充
 | |||
|     getFirstFeedbackData(title, id) { | |||
|       console.log(this.timer) | |||
|       this.timer ? clearInterval(this.timer) : '' | |||
|       console.log('------------------') | |||
|       this.CRFLoading = true | |||
|       // 获取已保存的手术列表--调取hmcrf.multipleSelectFull()方法回显
 | |||
|       this.$http.get(`/from/data/getFirstFeedbackData/${this.dataForm.formName}/${this.dataForm.patientIdNumber}/${id}`).then(({ data: res }) => { | |||
|         if (res.code !== 0) { | |||
|           return this.$message.error(res.msg) | |||
|         } | |||
|         if (res.data) { | |||
|           const fillData = res.data | |||
|           this.crfDataVisible = true | |||
|           // 需要等待时间原因:load_content.vue文件iframe需要插入js、css等文件需要时间
 | |||
|           // CRFLoading加载慢原因: quguang/from/data/getFirstFeedbackData接口速度慢
 | |||
|           this.timer = setInterval(() => { | |||
|             if (title === '智能填充') { | |||
|               console.log(123, title) | |||
|               this.isClick = true | |||
|               this.oldCRFListItem = {} | |||
|               if (this.$refs.crfComponent && this.$refs.crfComponent.$el.contentWindow.dataFill) { | |||
|                 this.$refs.crfComponent.$el.contentWindow.dataFill(fillData) | |||
|                 clearInterval(this.timer) | |||
|                 this.CRFLoading = false | |||
|               } else { | |||
|                 clearInterval(this.timer) | |||
|               } | |||
|             } else if (title === '病历模板') { | |||
|               console.log(456, title) | |||
|               this.oldCRFListItem = {} | |||
|               const ifr = document.getElementsByClassName('tox-edit-area__iframe')[0] | |||
|               console.log(ifr.contentWindow) | |||
|               console.log(ifr.contentWindow.dataFill) | |||
|               if (ifr.contentWindow.dataFill) { | |||
|                 ifr.contentWindow.dataFill(fillData) | |||
|                 clearInterval(this.timer) | |||
|                 this.CRFLoading = false | |||
|               } | |||
|             } | |||
|           }, 500) | |||
|         } | |||
|       }).catch(() => { }) | |||
|     }, | |||
|     // 获取已保存的手术列表--调取hmcrf.multipleSelectFull()方法回显
 | |||
|     async getsaveOperaList(formId) { | |||
|       // clearInterval(this.multipleSelectFullSetTime)
 | |||
|       const { data: res } = await this.$http.get('/opera/patient/getExecuteOperaList', { | |||
|         params: { | |||
|           crfFormId: formId | |||
|         } | |||
|       }) | |||
|       if (res.code !== 0) { | |||
|         return this.$message.error(res.msg) | |||
|       } else { | |||
|         const operaList = { | |||
|           OD: [], | |||
|           OS: [], | |||
|           OU: [] | |||
|         } | |||
|         // console.log(res.data)
 | |||
|         res.data.forEach(item => { | |||
|           if (item.eyeType === 'OD') { | |||
|             operaList.OD = item.operaEntityList.map(item => item.operationName) | |||
|           } else if (item.eyeType === 'OS') { | |||
|             operaList.OS = item.operaEntityList.map(item => item.operationName) | |||
|           } else if (item.eyeType === 'OU') { | |||
|             operaList.OU = item.operaEntityList.map(item => item.operationName) | |||
|           } | |||
|         }) | |||
|         setTimeout(() => { | |||
|           console.log('multipleSelectFull') | |||
|           if (this.$refs.crfComponent && this.$refs.crfComponent.$el.contentWindow.multipleSelectFull) { | |||
|             console.log(this.$refs.crfComponent) | |||
|             // const ceshi = {
 | |||
|             //   OD: ['快速角膜胶原交联术[KXL]'],
 | |||
|             //   OS: ['激光老视矫正术(Presby MAX)']
 | |||
|             // }
 | |||
|             console.log(operaList) | |||
|             this.$refs.crfComponent.$el.contentWindow.multipleSelectFull(operaList) | |||
|           } | |||
|         }, 2000) | |||
|         // this.$nextTick(() => {
 | |||
|         //   if (this.$refs.crfComponent && this.$refs.crfComponent.$el.contentWindow.multipleSelectFull) {
 | |||
|         //     console.log(this.$refs.crfComponent)
 | |||
|         //     // const ceshi = {
 | |||
|         //     //   OD: ['快速角膜胶原交联术[KXL]'],
 | |||
|         //     //   OS: ['激光老视矫正术(Presby MAX)']
 | |||
|         //     // }
 | |||
|         //     console.log(operaList)
 | |||
|         //     this.$refs.crfComponent.$el.contentWindow.multipleSelectFull(operaList)
 | |||
|         //   }
 | |||
|         // })
 | |||
|       } | |||
|     } | |||
|   } | |||
| } | |||
| @ -1,88 +0,0 @@ | |||
| export default { | |||
|   data() { | |||
|     return { | |||
|       CRFLoading: false, | |||
|       timer: null, | |||
|       flag: 1, | |||
|       multipleSelectFullSetTime: null | |||
|     } | |||
|   }, | |||
|   methods: { | |||
|     // 智能填充
 | |||
|     getFirstFeedbackData(title, id) { | |||
|       console.log(this.dataForm) | |||
|       console.log(this.flag) | |||
|       if (this.flag === 1) { | |||
|         console.log('------------------') | |||
|         this.flag++ // 解决多次调用定时器清除不掉的问题
 | |||
|         this.CRFLoading = true | |||
|         // 获取已保存的手术列表--调取hmcrf.multipleSelectFull()方法回显
 | |||
|         console.log(99999999999999) | |||
|         this.$http.get(`/from/data/getFirstFeedbackData/${this.dataForm.formName}/${this.dataForm.patientIdNumber}/${id}`).then(({ data: res }) => { | |||
|           if (res.code !== 0) { | |||
|             return this.$message.error(res.msg) | |||
|           } | |||
|           if (res.data) { | |||
|             const fillData = res.data | |||
|             this.crfDataVisible = true | |||
|             this.timer = setInterval(() => { | |||
|               if (title === '智能填充') { | |||
|                 console.log(123, title) | |||
|                 this.isClick = true | |||
|                 this.oldCRFListItem = {} | |||
|                 if (this.$refs.crfComponent && this.$refs.crfComponent.$el.contentWindow.dataFill) { | |||
|                   this.$refs.crfComponent.$el.contentWindow.dataFill(fillData) | |||
|                   clearInterval(this.timer) | |||
|                   this.flag = 1 | |||
|                   this.CRFLoading = false | |||
|                 } else { | |||
|                   clearInterval(this.timer) | |||
|                   this.flag = 1 | |||
|                 } | |||
|               } else if (title === '病历模板') { | |||
|                 console.log(456, title) | |||
|                 this.oldCRFListItem = {} | |||
|                 const ifr = document.getElementsByClassName('tox-edit-area__iframe')[0] | |||
|                 console.log(ifr.contentWindow) | |||
|                 console.log(ifr.contentWindow.dataFill) | |||
|                 if (ifr.contentWindow.dataFill) { | |||
|                   ifr.contentWindow.dataFill(fillData) | |||
|                   clearInterval(this.timer) | |||
|                   this.flag = 1 | |||
|                   this.CRFLoading = false | |||
|                 } | |||
|               } | |||
|             }, 500) | |||
|           } | |||
|         }).catch(() => { }) | |||
|       } else { | |||
|         clearInterval(this.timer) | |||
|         this.oldCRFListItem = {} | |||
|         this.flag = 1 | |||
|         this.CRFLoading = false | |||
|         console.log('flag', this.flag) | |||
|       } | |||
|     }, | |||
|     // 获取已保存的手术列表--调取hmcrf.multipleSelectFull()方法回显
 | |||
|     async getsaveOperaList(formId) { | |||
|       this.multipleSelectFullSetTime ? clearInterval(this.multipleSelectFullSetTime) : '' | |||
|       const { data: res } = await this.$http.get('/opera/patient/getExecuteOperaList', { | |||
|         params: { | |||
|           crfFormId: formId | |||
|         } | |||
|       }) | |||
|       if (res.code !== 0) { | |||
|         return this.$message.error(res.msg) | |||
|       } else { | |||
|         this.multipleSelectFullSetTime = setInterval(() => { | |||
|           console.log('multipleSelectFull') | |||
|           if (this.$refs.crfComponent && this.$refs.crfComponent.$el.contentWindow.multipleSelectFull) { | |||
|             console.log(this.$refs.crfComponent) | |||
|             clearInterval(this.multipleSelectFullSetTime) | |||
|             this.$refs.crfComponent.$el.contentWindow.multipleSelectFull(res.data) | |||
|           } | |||
|         }, 500) | |||
|       } | |||
|     } | |||
|   } | |||
| } | |||
| @ -1,37 +0,0 @@ | |||
| export default { | |||
|   data() { | |||
|     return {} | |||
|   }, | |||
|   methods: { | |||
|     // table-checkbox选择项发生变化时会触发该事件
 | |||
|     handleSelectionChange(val) { | |||
|       if (val.length === this.dataList.length) { | |||
|         this.$refs.checkfooter.cheackAllFooter = true | |||
|       } else { | |||
|         this.$refs.checkfooter.cheackAllFooter = false | |||
|       } | |||
|       this.currentTableList = val | |||
|       console.log(this.currentTableList) | |||
|     }, | |||
|     // 全选
 | |||
|     cheackAllChange(tableRef) { | |||
|       if (this.cheackAllFooter) { | |||
|         this.$parent.$refs[tableRef].toggleAllSelection() | |||
|       } else { | |||
|         this.$parent.$refs[tableRef].clearSelection() | |||
|       } | |||
|     }, | |||
|     // 反选
 | |||
|     cheackReverseClick(tableRef) { | |||
|       this.dataList.forEach((row) => { | |||
|         this.$parent.$refs[tableRef].toggleRowSelection(row) | |||
|       }) | |||
|     }, | |||
|     // 取消
 | |||
|     cancelClick(tableRef) { | |||
|       this.cheackAllFooter = false | |||
|       this.cheackReverseFooter = false | |||
|       this.$parent.$refs[tableRef].clearSelection() | |||
|     } | |||
|   } | |||
| } | |||
| @ -1,16 +0,0 @@ | |||
| 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,35 +0,0 @@ | |||
| export default { | |||
|   data() { | |||
|     return { | |||
|       printHidden: true, | |||
|       printIndex: 0, | |||
|       printType: '', | |||
|       print: { | |||
|         id: '', | |||
|         closeCallback: () => { | |||
|           console.log('关闭') | |||
|           this.$nextTick(() => { | |||
|             this.printHidden = true | |||
|           }) | |||
|         }, | |||
|         clickMounted: () => { | |||
|           console.log('触发点击打印回调') | |||
|         }, | |||
|         openCallback: () => { | |||
|           console.log('执行打印') | |||
|           this.printIndex += 1 | |||
|         } | |||
|       } | |||
|     } | |||
|   }, | |||
|   watch: { | |||
|     printIndex(val) { | |||
|       if (val) { | |||
|         this.printType = 'warning' | |||
|       } | |||
|     } | |||
|   }, | |||
|   created() { | |||
|     this.print.id = this.printId | |||
|   } | |||
| } | |||
| @ -1,35 +0,0 @@ | |||
| export default { | |||
|   data() { | |||
|     return { | |||
|     } | |||
|   }, | |||
|   methods: { | |||
|     // 青光眼的数据获取不在crf/getFlowForm下的firstVisit中,需要单独调取此接口获取
 | |||
|     getQgyCRFData() { | |||
|       this.$http.get('/view/out/patient/getVisitOutPatientForHis', { | |||
|         params: { | |||
|           patientIdNumber: this.patientIdNumber, | |||
|           patientId: this.patientId ? this.patientId : '', | |||
|           visitDate: this.realVisitTime ? this.realVisitTime : '', | |||
|           realVisitType: this.realVisitType ? this.realVisitType : '' | |||
|         } | |||
|       }) | |||
|         .then(({ data: res }) => { | |||
|           if (res.code !== 0) { | |||
|             return this.$message.error(res.msg) | |||
|           } | |||
|           if (res.data) { | |||
|             setTimeout(() => { | |||
|               if (this.$refs.crfComponent) { | |||
|                 const ifr = this.$refs.crfComponent.$el | |||
|                 const ifrWin = ifr.contentWindow | |||
|                 console.log(ifr.contentWindow) | |||
|                 ifrWin.dataFill(res.data) | |||
|               } | |||
|             }, 800) | |||
|           } | |||
|         }).catch(() => { }) | |||
|     } | |||
|   } | |||
| } | |||
| 
 | |||
| @ -1,80 +0,0 @@ | |||
| 
 | |||
| export default { | |||
|   inject: ['canvas', 'fabric', 'event'], | |||
|   data() { | |||
|     return { | |||
|       mSelectMode: '', // one | multiple
 | |||
|       mSelectOneType: '', // i-text | group ...
 | |||
|       mSelectId: '', // 选择id
 | |||
|       mSelectIds: [] // 选择id
 | |||
|     } | |||
|   }, | |||
|   created() { | |||
|     this.event.on('selectOne', (e) => { | |||
|       console.log('selectOne', e) | |||
|       this.mSelectMode = 'one' | |||
|       this.mSelectId = e[0].id | |||
|       this.mSelectOneType = e[0].type | |||
|       // console.log(e[0].id)
 | |||
|       // console.log(e[0].type)
 | |||
|       this.mSelectIds = e.map(item => item.id) | |||
|     }) | |||
| 
 | |||
|     this.event.on('selectMultiple', (e) => { | |||
|       console.log('selectMultiple') | |||
|       this.mSelectMode = 'multiple' | |||
|       this.mSelectId = '' | |||
|       this.mSelectIds = e.map(item => item.id) | |||
|     }) | |||
| 
 | |||
|     this.event.on('selectCancel', () => { | |||
|       console.log('selectCancel') | |||
|       this.mSelectId = '' | |||
|       this.mSelectIds = [] | |||
|       this.mSelectMode = '' | |||
|       this.mSelectOneType = '' | |||
|     }) | |||
|   }, | |||
|   methods: { | |||
|     /** | |||
|      * @description: 保存data数据 | |||
|      * @param {Object} data 房间详情数据 | |||
|      */ | |||
|     _mixinSelected({ event, selected }) { | |||
|       if (selected.length === 1) { | |||
|         const selectItem = selected[0] | |||
|         this.mSelectMode = 'one' | |||
|         this.mSelectOneType = selectItem.type | |||
|         this.mSelectId = [selectItem.id] | |||
|         this.mSelectActive = [selectItem] | |||
|       } else if (selected.length > 1) { | |||
|         this.mSelectMode = 'multiple' | |||
|         this.mSelectActive = selected | |||
|         this.mSelectId = selected.map(item => item.id) | |||
|       } else { | |||
|         this._mixinCancel() | |||
|       } | |||
|     }, | |||
|     /** | |||
|      * @description: 保存data数据 | |||
|      * @param {Object} data 房间详情数据 | |||
|      */ | |||
|     _mixinCancel(data) { | |||
|       this.mSelectMode = '' | |||
|       this.mSelectId = [] | |||
|       this.mSelectActive = [] | |||
|       this.mSelectOneType = '' | |||
|     }, | |||
|     /** | |||
|      * @description: 复制到剪切板 | |||
|      * @param {String} clipboardText 复制内容 | |||
|      */ | |||
|     _mixinClipboard(clipboardText) { | |||
|       this.$copyText(clipboardText).then(() => { | |||
|         this.$Message.success('复制成功') | |||
|       }, () => { | |||
|         this.$Message.error('复制失败') | |||
|       }) | |||
|     } | |||
|   } | |||
| } | |||
| @ -1,128 +0,0 @@ | |||
| export default { | |||
|   data() { | |||
|     return { | |||
|       plugin: null, | |||
|       type: 1, // 1 验光师 2 配戴者 3 监护人
 | |||
|       optomFlag: true, | |||
|       wearerFlag: true, | |||
|       guardianFlag: true, | |||
|       readFlag: true, | |||
|       doctorSign: '', | |||
|       patientSign: '123', | |||
|       guardianSign: '', | |||
|       readerSign: '' | |||
|     } | |||
|   }, | |||
| 
 | |||
|   methods: { | |||
|     initPlugin() { | |||
|       if (this.plugin) { | |||
|         this.plugin.DestroyPlugin() | |||
|       } | |||
|       this.plugin = new PluginNSV() | |||
|       const that = this | |||
|       console.log(this.plugin) | |||
|       this.plugin.InitPlugin(function(state) { | |||
|         if (state === 1) { | |||
|           // set pen size
 | |||
|           that.plugin.setPenSizeRange(1, 5, null) | |||
|           // set pen color
 | |||
|           that.plugin.setPenColor(0, 0, 0, null) | |||
|           that.plugin.setDisplayMapMode(1, 0, 0, null) | |||
|           console.log('succeeded') | |||
|         } else { | |||
|           console.log('fails') | |||
|         } | |||
|       }) | |||
| 
 | |||
|       /* confirm event*/ | |||
|       this.plugin.onConfirm = function() { | |||
|         if (that.type === 1) { | |||
|           that.optomFlag = false | |||
|         } else if (that.type === 2) { | |||
|           console.log(111111111111111111111111) | |||
|           that.wearerFlag = false | |||
|         } else if (that.type === 3) { | |||
|           that.guardianFlag = false | |||
|         } else if (that.type === 4) { | |||
|           that.readFlag = false | |||
|         } | |||
| 
 | |||
|         that.saveSignToBase64() | |||
|         that.endSign() | |||
|       } | |||
|       // /*clear event*/
 | |||
|       this.plugin.onClear = function() { | |||
|         this.clearSign() | |||
|       } | |||
|       /* cancel event*/ | |||
|       this.plugin.onCancel = function() { | |||
|         this.endSign() | |||
|       } | |||
|       this.plugin.onStateChange = function(state) {} | |||
| 
 | |||
|       this.plugin.onDevNotifyEvent = function(state) { | |||
|         if (state === 1) { | |||
|           console.log('connected') | |||
|         } else { | |||
|           console.log('disconnected') | |||
|         } | |||
|       } | |||
|     }, | |||
|     beginSign(type) { | |||
|       this.type = type | |||
|       if (this.plugin) { | |||
|         this.plugin.beginSign(function(state, args) { | |||
|         }) | |||
|       } | |||
|       // document.getElementById('img_sign_result').src = '';
 | |||
|     }, | |||
|     clearSign() { | |||
|       if (this.plugin) { | |||
|         this.plugin.clearSign(function(state, args) {}) | |||
|       } | |||
|       // Reset the image.
 | |||
|       if (this.type === 1) { | |||
|         this.doctorSign = '' | |||
|       } else if (this.type === 2) { | |||
|         this.patientSign = '' | |||
|       } else if (this.type === 3) { | |||
|         this.guardianSign = '' | |||
|       } else if (this.type === 4) { | |||
|         this.readerSign = '' | |||
|       } | |||
|     }, | |||
|     endSign() { | |||
|       if (this.plugin) { | |||
|         /* plugin.endSign(null);*/ | |||
|         this.plugin.endSign(function(state, args) {}) | |||
|       } | |||
|     }, | |||
|     saveSignToBase64() { | |||
|       console.log('base64') | |||
|       if (this.plugin) { | |||
|         // Get the plugin's signature image data.
 | |||
|         this.plugin.saveSignToBase64(/* 615, 272*/0, 0, (state, args) => { | |||
|           if (state) { | |||
|             const img_base64_data = args[0] | |||
|             console.log(img_base64_data) | |||
|             const img_base64 = 'data:image/png;base64,' + img_base64_data | |||
|             if (this.type === 1) { | |||
|               this.doctorSign = img_base64 | |||
|             } else if (this.type === 2) { | |||
|               this.patientSign = 'data:image/png;base64,' + img_base64_data | |||
|               console.log(this.patientSign) | |||
|             } else if (this.type === 3) { | |||
|               this.guardianSign = img_base64 | |||
|             } else if (this.type === 4) { | |||
|               this.readerSign = img_base64 | |||
|             } | |||
|           } else { | |||
|             // debugPrint("saveSignToBase64 error,description:" + args[0]);
 | |||
|           } | |||
|         }) | |||
|       } | |||
|     } | |||
|   } | |||
| } | |||
| 
 | |||
| @ -1,121 +0,0 @@ | |||
| import { Notification } from 'element-ui' | |||
| import emptySign from '@static/js/emptySign' | |||
| export default { | |||
|   data() { | |||
|     return { | |||
|       plugin: null, | |||
|       optomFlag: true, | |||
|       wearerFlag: true, | |||
|       guardianFlag: true, | |||
|       readFlag: true, | |||
|       currentSignText: '' | |||
|     } | |||
|   }, | |||
|   methods: { | |||
|     // 销毁签字笔
 | |||
|     destroyPlugin(state) { | |||
|       console.log(this.plugin) | |||
|       if (this.plugin) { | |||
|         console.log('--------3333-------') | |||
|         this.plugin.DestroyPlugin() | |||
|       } | |||
|     }, | |||
|     initPlugin(text) { | |||
|       // console.log(JSON.parse(window.sessionStorage.getItem('signPlugin')))
 | |||
|       // if (this.plugin) {
 | |||
|       //   this.plugin.DestroyPlugin()
 | |||
|       // }
 | |||
|       this.plugin = new PluginNSV() | |||
|       // window.sessionStorage.setItem('signPlugin', JSON.stringify(this.plugin))
 | |||
|       const that = this | |||
|       console.log('plugin', this.plugin) | |||
|       this.plugin.InitPlugin(function(state) { | |||
|         if (state === 1) { | |||
|           // set pen size
 | |||
|           that.plugin.setPenSizeRange(1, 5, null) | |||
|           // set pen color
 | |||
|           that.plugin.setPenColor(0, 0, 0, null) | |||
|           that.plugin.setDisplayMapMode(1, 0, 0, null) | |||
|           console.log('succeeded') | |||
|           that.beginSign(text) | |||
|         } else { | |||
|           console.log('fails') | |||
|         } | |||
|       }) | |||
| 
 | |||
|       /* confirm event*/ | |||
|       this.plugin.onConfirm = function() { | |||
|         that.saveSignToBase64() | |||
|         that.endSign() | |||
|       } | |||
|       // /*clear event*/
 | |||
|       this.plugin.onClear = function() { | |||
|         this.clearSign() | |||
|       } | |||
|       /* cancel event*/ | |||
|       this.plugin.onCancel = function() { | |||
|         this.endSign() | |||
|       } | |||
|       this.plugin.onStateChange = function(state) {} | |||
| 
 | |||
|       this.plugin.onDevNotifyEvent = function(state) { | |||
|         if (state === 1) { | |||
|           Notification.success({ | |||
|             title: '成功', | |||
|             message: '签字笔已插入', | |||
|             showClose: false, | |||
|             duration: 800 | |||
|           }) | |||
|         } else { | |||
|           Notification.error({ | |||
|             title: '提示', | |||
|             message: '签字笔已拔出', | |||
|             showClose: false, | |||
|             duration: 800 | |||
|           }) | |||
|         } | |||
|       } | |||
|     }, | |||
|     beginSign(text) { | |||
|       const that = this | |||
|       that.currentSignText = text | |||
|       console.log(that.plugin) | |||
|       if (this.plugin) { | |||
|         console.log(123) | |||
|         this.plugin.beginSign(function(state, args) { | |||
|         }) | |||
|       } | |||
|       // document.getElementById('img_sign_result').src = '';
 | |||
|     }, | |||
|     clearSign() { | |||
|       if (this.plugin) { | |||
|         this.plugin.clearSign(function(state, args) {}) | |||
|       } | |||
|     }, | |||
|     endSign() { | |||
|       if (this.plugin) { | |||
|         /* plugin.endSign(null);*/ | |||
|         this.plugin.endSign(function(state, args) {}) | |||
|       } | |||
|     }, | |||
|     saveSignToBase64() { | |||
|       if (this.plugin) { | |||
|         // Get the plugin's signature image data.
 | |||
|         this.plugin.saveSignToBase64(/* 615, 272*/0, 0, (state, args) => { | |||
|           if (state) { | |||
|             const img_base64_data = args[0] | |||
|             const img_base64 = 'data:image/png;base64,' + img_base64_data | |||
|             this.formListValue[this.currentSignText] = img_base64 | |||
|             if (this.formListValue[this.currentSignText] === emptySign) { | |||
|               this.$message.error('签字未成功请重新签字') | |||
|             } | |||
|             this.destroyPlugin() | |||
|           } else { | |||
|             // debugPrint("saveSignToBase64 error,description:" + args[0]);
 | |||
|           } | |||
|         }) | |||
|       } | |||
|     } | |||
|   } | |||
| } | |||
| 
 | |||
| @ -1,100 +0,0 @@ | |||
| <template> | |||
|   <el-dialog | |||
|     :visible.sync="visible" | |||
|     :title="$t('updatePassword.title')" | |||
|     :close-on-click-modal="false" | |||
|     :close-on-press-escape="false" | |||
|     :append-to-body="true" | |||
|   > | |||
|     <el-form ref="dataForm" :model="dataForm" :rules="dataRule" label-width="auto" @keyup.enter.native="dataFormSubmitHandle()"> | |||
|       <el-form-item :label="$t('updatePassword.username')"> | |||
|         <span>{{ $store.state.user.name }}</span> | |||
|       </el-form-item> | |||
|       <el-form-item prop="password" :label="$t('updatePassword.password')"> | |||
|         <el-input v-model="dataForm.password" type="password" :placeholder="$t('updatePassword.password')" /> | |||
|       </el-form-item> | |||
|       <el-form-item prop="newPassword" :label="$t('updatePassword.newPassword')"> | |||
|         <el-input v-model="dataForm.newPassword" type="password" :placeholder="$t('updatePassword.newPassword')" /> | |||
|       </el-form-item> | |||
|       <el-form-item prop="confirmPassword" :label="$t('updatePassword.confirmPassword')"> | |||
|         <el-input v-model="dataForm.confirmPassword" type="password" :placeholder="$t('updatePassword.confirmPassword')" /> | |||
|       </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 { clearLoginInfo } from '@/page-subspecialty/utils/request.js' | |||
| import { resetRouter } from '@/page-subspecialty/router/index.js' | |||
| export default { | |||
|   data() { | |||
|     return { | |||
|       visible: false, | |||
|       dataForm: { | |||
|         password: '', | |||
|         newPassword: '', | |||
|         confirmPassword: '' | |||
|       } | |||
|     } | |||
|   }, | |||
|   computed: { | |||
|     dataRule() { | |||
|       var validateConfirmPassword = (rule, value, callback) => { | |||
|         if (this.dataForm.newPassword !== value) { | |||
|           return callback(new Error(this.$t('updatePassword.validate.confirmPassword'))) | |||
|         } | |||
|         callback() | |||
|       } | |||
|       return { | |||
|         password: [ | |||
|           { required: true, message: this.$t('validate.required'), trigger: 'blur' } | |||
|         ], | |||
|         newPassword: [ | |||
|           { required: true, message: this.$t('validate.required'), trigger: 'blur' } | |||
|         ], | |||
|         confirmPassword: [ | |||
|           { required: true, message: this.$t('validate.required'), trigger: 'blur' }, | |||
|           { validator: validateConfirmPassword, trigger: 'blur' } | |||
|         ] | |||
|       } | |||
|     } | |||
|   }, | |||
|   methods: { | |||
|     init() { | |||
|       this.visible = true | |||
|       this.$nextTick(() => { | |||
|         this.$refs['dataForm'].resetFields() | |||
|       }) | |||
|     }, | |||
|     // 表单提交 | |||
|     dataFormSubmitHandle: debounce(function() { | |||
|       this.$refs['dataForm'].validate((valid) => { | |||
|         if (!valid) { | |||
|           return false | |||
|         } | |||
|         this.$http.put('/sys/user/password', this.dataForm).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 | |||
|               clearLoginInfo() | |||
|               resetRouter() | |||
|               this.$router.replace({ name: 'login' }) | |||
|             } | |||
|           }) | |||
|         }).catch(() => {}) | |||
|       }) | |||
|     }, 1000, { 'leading': true, 'trailing': false }) | |||
|   } | |||
| } | |||
| </script> | |||
| @ -1,132 +0,0 @@ | |||
| <template> | |||
|   <nav class="aui-navbar" :class="`aui-navbar--${$store.state.navbarLayoutType}`"> | |||
|     <div class="aui-navbar__header" style="height:100px;"> | |||
|       <!-- logo --> | |||
|       <h1 class="aui-navbar__brand" @click="logoClick"> | |||
|         <a class="aui-navbar__brand-lg" href="javascript:;" style="text-align:center;"> | |||
|           <svg-icon icon-class="icon-yzk-login" style="font-size:36px" /> | |||
|           <div style="margin-top:5px;">眼科工作平台</div> | |||
|         </a> | |||
|         <a class="aui-navbar__brand-mini" href="javascript:;"> <svg-icon icon-class="icon-yzk-login" style="font-size:36px" /></a> | |||
|       </h1> | |||
|     </div> | |||
|     <div class="aui-navbar__body"> | |||
|       <el-menu class="aui-navbar__menu mr-auto" mode="horizontal"> | |||
|         <!-- 收缩 --> | |||
|         <el-menu-item index="1" @click="$store.state.sidebarFold = !$store.state.sidebarFold"> | |||
|           <svg class="icon-svg aui-navbar__icon-menu aui-navbar__icon-menu--switch" aria-hidden="true"><use xlink:href="#icon-outdent" /></svg> | |||
|         </el-menu-item> | |||
|         <!-- 刷新 --> | |||
|         <el-menu-item index="2" style="padding:0 6px;" @click="refresh()"> | |||
|           <svg class="icon-svg aui-navbar__icon-menu aui-navbar__icon-menu--refresh" aria-hidden="true"><use xlink:href="#icon-sync" /></svg> | |||
|         </el-menu-item> | |||
|         <el-menu-item index="3" style="padding:0 6px;"> | |||
|           <bread-crumb /> | |||
|         </el-menu-item> | |||
|       </el-menu> | |||
|       <el-menu class="aui-navbar__menu" mode="horizontal"> | |||
|         <!-- 全屏 --> | |||
|         <el-menu-item index="4" @click="fullscreenHandle()"> | |||
|           <svg-icon icon-class="fullscreen" /> | |||
|         </el-menu-item> | |||
|         <!-- 头像、按钮组 --> | |||
|         <el-menu-item index="5" class="aui-navbar__avatar"> | |||
|           <el-dropdown placement="bottom" :show-timeout="0"> | |||
|             <span class="el-dropdown-link"> | |||
|               <img src="~@/assets/img/avatar.png"> | |||
|               <span>{{ $store.state.user.name }}</span> | |||
|               <i class="el-icon-arrow-down" /> | |||
|             </span> | |||
|             <el-dropdown-menu slot="dropdown"> | |||
|               <!-- 修改密码 --> | |||
|               <el-dropdown-item @click.native="updatePasswordHandle()">修改密码</el-dropdown-item> | |||
|               <!-- 退出 --> | |||
|               <el-dropdown-item style="color:#FF4D4F" @click.native="logoutHandle()">退出登录</el-dropdown-item> | |||
|             </el-dropdown-menu> | |||
|           </el-dropdown> | |||
|         </el-menu-item> | |||
|       </el-menu> | |||
|     </div> | |||
|     <!-- 弹窗, 修改密码 --> | |||
|     <update-password v-if="updatePasswordVisible" ref="updatePassword" /> | |||
|   </nav> | |||
| </template> | |||
| <script> | |||
| import { messages } from '@/i18n' | |||
| import screenfull from 'screenfull' | |||
| import UpdatePassword from './main-navbar-update-password.vue' | |||
| import { clearLoginInfo } from '@/page-subspecialty/utils/request.js' | |||
| import breadCrumb from '@/components/bread-crumb' | |||
| import { resetRouter } from '@/page-subspecialty/router/index.js' | |||
| export default { | |||
|   inject: ['refresh'], | |||
|   components: { | |||
|     UpdatePassword, | |||
|     breadCrumb | |||
|   }, | |||
|   data() { | |||
|     return { | |||
|       i18nMessages: messages, | |||
|       updatePasswordVisible: false, | |||
|       messageTip: false, | |||
|       logo: require('@/assets/img/logo.png') | |||
|     } | |||
|   }, | |||
|   created() { | |||
|   }, | |||
|   methods: { | |||
|     logoClick() { | |||
|       this.$store.commit('activeIndexFun', window.SITE_CONFIG.menuList[0].children[0].id) | |||
|       this.$router.push({ name: 'outpatientManagement-call' }) | |||
|     }, | |||
|     // 全屏 | |||
|     fullscreenHandle() { | |||
|       if (!screenfull.enabled) { | |||
|         return this.$message({ | |||
|           message: this.$t('fullscreen.prompt'), | |||
|           type: 'warning', | |||
|           duration: 500 | |||
|         }) | |||
|       } | |||
|       screenfull.toggle() | |||
|     }, | |||
|     // 修改密码 | |||
|     updatePasswordHandle() { | |||
|       this.updatePasswordVisible = true | |||
|       this.$nextTick(() => { | |||
|         this.$refs.updatePassword.init() | |||
|       }) | |||
|     }, | |||
|     // 退出 | |||
|     logoutHandle() { | |||
|       this.$confirm(this.$t('prompt.info', { handle: this.$t('logout') }), this.$t('prompt.title'), { | |||
|         confirmButtonText: this.$t('confirm'), | |||
|         cancelButtonText: this.$t('cancel'), | |||
|         type: 'warning' | |||
|       }).then(() => { | |||
|         this.$http.post('/logout').then(({ data: res }) => { | |||
|           if (res.code !== 0) { | |||
|             return this.$message.error(res.msg) | |||
|           } | |||
|           clearLoginInfo() | |||
|           resetRouter() | |||
|           this.$router.push({ name: 'login' }) | |||
|           this.$store.commit('activeIndexFun', window.SITE_CONFIG.menuList[0].children[0].id) | |||
|         }).catch(() => {}) | |||
|       }).catch(() => {}) | |||
|     } | |||
|   } | |||
| } | |||
| </script> | |||
| <style lang='scss' scoped> | |||
| .aui-navbar__header{ | |||
|   width: 160px; | |||
| } | |||
| .aui-navbar__brand{ | |||
|   font-size: 17px; | |||
|   .sidebar-logo { | |||
|       width: 36px; | |||
|       height: 36px; | |||
|     } | |||
| } | |||
| </style> | |||
| @ -1,135 +0,0 @@ | |||
| <template> | |||
|   <div class="left-menu"> | |||
|     <el-submenu v-if="menu.children && menu.children.length >= 1 && menu.children[0].isShow == 1" :index="menu.id" :popper-append-to-body="false"> | |||
|       <template slot="title"> | |||
|         <svg class="icon-svg aui-sidebar__menu-icon" aria-hidden="true"><use :xlink:href="`#${menu.icon}`" /></svg> | |||
|         <span v-show="$store.state.sidebarFold===false">{{ menu.name }}</span> | |||
|       </template> | |||
|       <sub-menu v-for="item in menu.children" :key="item.id" :menu="item" /> | |||
|     </el-submenu> | |||
|     <el-menu-item v-else ref="li" :index="menu.id" @click="openMenuHandle(menu.id)"> | |||
|       <!-- :href="isBrowserTabOpen(menu) ? iframeURL: 'javascript:;'" | |||
|       :target="isBrowserTabOpen(menu) ? '_blank' : '_self'" --> | |||
|       <a> | |||
|         <svg class="icon-svg aui-sidebar__menu-icon" aria-hidden="true"><use :xlink:href="`#${menu.icon}`" /></svg> | |||
|         <span v-show="$store.state.sidebarFold===false">{{ menu.name }}</span> | |||
|       </a> | |||
|     </el-menu-item> | |||
|   </div> | |||
| </template> | |||
| 
 | |||
| <script> | |||
| import SubMenu from './main-sidebar-sub-menu.vue' | |||
| export default { | |||
|   inject: ['refresh'], | |||
|   name: 'SubMenu', | |||
|   components: { | |||
|     SubMenu | |||
|   }, | |||
|   props: { | |||
|     menu: { | |||
|       type: Object, | |||
|       required: true | |||
|     } | |||
|   }, | |||
|   data() { | |||
|     return { | |||
|       browserTabOpenList: [ | |||
|         // '1353981045241810946', // 写死,另打开iframe | |||
|         // '1344097112555024386' | |||
|       ], | |||
|       iframeURL: '', | |||
|       routerName: '' | |||
|     } | |||
|   }, | |||
|   watch: { | |||
|     $route(val) { | |||
|       // console.log(val) | |||
|       this.routerName = val.name | |||
|     } | |||
|   }, | |||
|   created() { | |||
|     this.routerName = this.$route.name | |||
|     // this.$nextTick(() => { | |||
|     //   if (this.$refs.li) { | |||
|     //     const $li = this.$refs.li.$el | |||
|     //     const $a = $li.firstElementChild | |||
|     //     if ($a) { | |||
|     //       let pl = '0'; let pr = '0' | |||
|     //       if ($li.currentStyle) { | |||
|     //         pl = $li.currentStyle.paddingLeft | |||
|     //         pr = $li.currentStyle.paddingRight | |||
|     //       } else { | |||
|     //         pl = window.document.defaultView.getComputedStyle($li, null).paddingLeft | |||
|     //         pr = window.document.defaultView.getComputedStyle($li, null).paddingRight | |||
|     //       } | |||
|     //       $li.setAttribute('style', 'padding-left: 0; padding-right: 0;') | |||
|     //       $a.setAttribute('style', `padding-left: ${pl}; padding-right: ${pr};`) | |||
|     //     } | |||
|     //   } | |||
|     // }) | |||
|   }, | |||
|   methods: { | |||
|     // 判断menuId | |||
|     isMenuIdFun(menuId, dynamicMenuRoutes, callback) { | |||
|       dynamicMenuRoutes.forEach((item) => { | |||
|         if (item.meta.menuId === menuId) { | |||
|           return callback && callback(item) | |||
|         } else if (item.children.length > 0) { | |||
|           this.isMenuIdFun(menuId, item.children, callback) | |||
|         } | |||
|       }) | |||
|     }, | |||
|     // 是否通过浏览器Tab打开菜单 | |||
|     isBrowserTabOpen(menu) { | |||
|       return this.browserTabOpenList.filter(item => item === menu.id).length >= 1 | |||
|       // return false | |||
|     }, | |||
|     // 获取浏览器Tab打开菜单URL | |||
|     getBrowserTabOpenURL(menuId) { | |||
|       this.isMenuIdFun(menuId, window.SITE_CONFIG.dynamicMenuRoutes, (item) => { | |||
|         this.iframeURL = item.meta.iframeURL | |||
|       }) | |||
|     }, | |||
|     // 点击菜单获取id | |||
|     openMenuHandle(menuId) { | |||
|       this.$store.commit('activeIndexFun', menuId) | |||
|       this.isMenuIdFun(menuId, window.SITE_CONFIG.dynamicMenuRoutes, (item) => { | |||
|         // console.log(item) | |||
|         setTimeout(() => { | |||
|           if (this.routerName === item.name) { | |||
|             this.refresh() | |||
|           } else { | |||
|             // console.log(item.name) | |||
|             this.$router.push({ | |||
|               name: item.name | |||
|             }) | |||
|           } | |||
|         }, 200) | |||
|       }) | |||
|     } | |||
|   } | |||
| } | |||
| </script> | |||
| 
 | |||
| <style lang="scss"> | |||
| .aui-sidebar__menu { | |||
|   .el-menu-item > a { | |||
|     display: block; | |||
|     color: inherit; | |||
|     text-decoration: none; | |||
|   } | |||
| } | |||
| .left-menu { | |||
|   .el-menu-item ,.el-submenu__title{ | |||
|       padding-left: 4px !important; | |||
|   } | |||
|   .el-menu--inline { | |||
|     padding-left: 10px; | |||
|   } | |||
|   .el-submenu__icon-arrow { | |||
|     top: 60%; | |||
|   } | |||
| } | |||
| 
 | |||
| </style> | |||
| @ -1,149 +0,0 @@ | |||
| <template> | |||
|   <aside :class="['aui-sidebar', `aui-sidebar--${$store.state.sidebarLayoutSkin}`]"> | |||
|     <div class="aui-sidebar__inner"> | |||
|       <el-menu | |||
|         :collapse="$store.state.sidebarFold" | |||
|         :unique-opened="true" | |||
|         :collapse-transition="false" | |||
|         class="aui-sidebar__menu" | |||
|         active-text-color="#fff" | |||
|         :default-active="defauleActiveIndex" | |||
|       > | |||
|         <sub-menu v-for="menu in $store.state.sidebarMenuList" :key="menu.id" :menu="menu" /> | |||
|       </el-menu> | |||
|     </div> | |||
| <!--    <el-tooltip class="item" effect="dark" content="可点击下载操作手册" placement="top">--> | |||
| <!--      <div v-if="!$store.state.sidebarFold" class="sidebar-operation-manual" style="width:30px" @click="exportclick(wordData)">--> | |||
| <!--        <i class="el-icon-question" />--> | |||
| <!--      </div>--> | |||
| <!--      <div v-else class="sidebar-operation-manual" style="width:40px" @click="exportclick(wordData)">--> | |||
| <!--        <i class="el-icon-question" style="font-size:18px;" />--> | |||
| <!--      </div>--> | |||
| <!--    </el-tooltip>--> | |||
|   </aside> | |||
| </template> | |||
| 
 | |||
| <script> | |||
| import SubMenu from './main-sidebar-sub-menu' | |||
| import docxtemplater from 'docxtemplater' | |||
| import PizZip from 'pizzip' | |||
| import JSZipUtils from 'jszip-utils' | |||
| import { saveAs } from 'file-saver' | |||
| export default { | |||
|   components: { | |||
|     SubMenu | |||
|   }, | |||
|   data() { | |||
|     return { | |||
|       fileHref: '', | |||
|       wordData: { | |||
|         user_name: 'XXX', | |||
|         remark: '' | |||
|       } | |||
|     } | |||
|   }, | |||
|   computed: { | |||
|     defauleActiveIndex: { | |||
|       get() { | |||
|         return this.$store.getters.defauleActiveIndex | |||
|       }, | |||
|       set(val) { | |||
| 
 | |||
|       } | |||
|     } | |||
|   }, | |||
|   created() { | |||
|     const defauleActiveIndex = window.sessionStorage.getItem('defauleActiveIndex') | |||
|       ? window.sessionStorage.getItem('defauleActiveIndex') : window.SITE_CONFIG.menuList[0].children[0].id | |||
|     setTimeout(() => { | |||
|       this.$store.state.sidebarMenuList = window.SITE_CONFIG.menuList | |||
|     }, 200) | |||
|     this.$store.commit('activeIndexFun', defauleActiveIndex) | |||
|   }, | |||
|   mounted() { | |||
| 
 | |||
|   }, | |||
|   methods: { | |||
|     exportclick(e) { | |||
|       this.$message('暂时没有操作手册可下载') | |||
|       return | |||
|       const docxsrc = '../../../static/word/operation-manual-YSG.docx' // 模板文件的位置 | |||
|       const docxname = '眼科电子病历操作手册'// 导出文件的名字 | |||
|       // 读取并获得模板文件的二进制内容 | |||
|       JSZipUtils.getBinaryContent(docxsrc, function(error, content) { | |||
|         // docxsrc是模板。我们在导出的时候,会根据此模板来导出对应的数据 | |||
|         if (error) { | |||
|           throw error | |||
|         } | |||
| 
 | |||
|         // 创建一个PizZip实例,内容为模板的内容 | |||
|         const zip = new PizZip(content) | |||
|         // 创建并加载docx templater实例对象 | |||
|         const doc = new docxtemplater().loadZip(zip) | |||
|         // 设置模板变量的值 | |||
|         doc.setData({ | |||
|           ...e// e中的数据可以再模板中直接使用 | |||
|         }) | |||
| 
 | |||
|         try { | |||
|           // 用模板变量的值替换所有模板变量 | |||
|           doc.render() | |||
|         } catch (error) { | |||
|           // 抛出异常 | |||
|           const e = { | |||
|             message: error.message, | |||
|             name: error.name, | |||
|             stack: error.stack, | |||
|             properties: error.properties | |||
|           } | |||
|           console.log(JSON.stringify({ | |||
|             error: e | |||
|           })) | |||
|           throw error | |||
|         } | |||
| 
 | |||
|         // 生成一个代表docxtemplater对象的zip文件(不是一个真实的文件,而是在内存中的表示) | |||
|         const out = doc.getZip().generate({ | |||
|           type: 'blob', | |||
|           mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' | |||
|         }) | |||
|         // 将目标文件对象保存为目标类型的文件,并命名 | |||
|         saveAs(out, docxname) | |||
|       }) | |||
|     } | |||
|   } | |||
| } | |||
| </script> | |||
| <style lang="scss" scoped> | |||
|   .sidebar-operation-manual { | |||
|     font-size: 14px; | |||
|     color: #fff; | |||
|     height: 30px; | |||
|     line-height: 30px; | |||
|     text-align: center; | |||
|     background-color: #3c4658; | |||
|     border-radius: 4px; | |||
|     position: absolute; | |||
|     right: 10px; | |||
|     bottom: 6px; | |||
|     cursor: pointer; | |||
|     z-index: 1; | |||
|     .title { | |||
|       display: inline-block; | |||
|       padding-left: 10px; | |||
|     } | |||
| } | |||
| </style> | |||
| <style lang="scss"> | |||
| .aui-sidebar{ | |||
|   width: 160px !important; | |||
| } | |||
| .aui-sidebar__menu{ | |||
|   width: 160px; | |||
| } | |||
| .aui-sidebar__inner { | |||
|   .el-menu-item:hover { | |||
|   background: #545c64 !important; | |||
| } | |||
| } | |||
| </style> | |||
| @ -1,19 +0,0 @@ | |||
| <template> | |||
|   <div> | |||
|     123 | |||
|   </div> | |||
| </template> | |||
| <script> | |||
| export default { | |||
|   data() { | |||
|     return { | |||
|     } | |||
|   }, | |||
|   created() { | |||
|   }, | |||
|   methods: { | |||
|   } | |||
| } | |||
| </script> | |||
| <style lang="scss" scoped> | |||
| </style> | |||
| @ -1,18 +0,0 @@ | |||
| <template> | |||
|   <div /> | |||
| </template> | |||
| <script> | |||
| export default { | |||
|   name: 'Reload', | |||
|   props: {}, | |||
|   beforeCreate() { | |||
|     console.log(this.$route.params) | |||
|     this.$router.push({ | |||
|       name: this.$route.params.name | |||
|     }) | |||
|   }, | |||
|   created() { | |||
|     console.log(this.$route.params) | |||
|   } | |||
| } | |||
| </script> | |||
| @ -1,122 +0,0 @@ | |||
| var CreatedOKLodop7766 = null; var CLodopIsLocal | |||
| 
 | |||
| // ====判断是否需要 Web打印服务CLodop:===
 | |||
| // ===(不支持插件的浏览器版本需要用它)===
 | |||
| export function needCLodop() { | |||
|   try { | |||
|     var ua = navigator.userAgent | |||
|     if (ua.match(/Windows\sPhone/i)) { return true } | |||
|     if (ua.match(/iPhone|iPod|iPad/i)) { return true } | |||
|     if (ua.match(/Android/i)) { return true } | |||
|     if (ua.match(/Edge\D?\d+/i)) { return true } | |||
| 
 | |||
|     var verTrident = ua.match(/Trident\D?\d+/i) | |||
|     var verIE = ua.match(/MSIE\D?\d+/i) | |||
|     var verOPR = ua.match(/OPR\D?\d+/i) | |||
|     var verFF = ua.match(/Firefox\D?\d+/i) | |||
|     var x64 = ua.match(/x64/i) | |||
|     if ((!verTrident) && (!verIE) && (x64)) { return true } else if (verFF) { | |||
|       verFF = verFF[0].match(/\d+/) | |||
|       if ((verFF[0] >= 41) || (x64)) { return true } | |||
|     } else if (verOPR) { | |||
|       verOPR = verOPR[0].match(/\d+/) | |||
|       if (verOPR[0] >= 32) { return true } | |||
|     } else if ((!verTrident) && (!verIE)) { | |||
|       var verChrome = ua.match(/Chrome\D?\d+/i) | |||
|       if (verChrome) { | |||
|         verChrome = verChrome[0].match(/\d+/) | |||
|         if (verChrome[0] >= 41) { return true } | |||
|       } | |||
|     } | |||
|     return false | |||
|   } catch (err) { | |||
|     return true | |||
|   } | |||
| } | |||
| 
 | |||
| // ====页面引用CLodop云打印必须的JS文件,用双端口(8000和18000)避免其中某个被占用:====
 | |||
| if (needCLodop()) { | |||
|   var src1 = 'http://localhost:8000/CLodopfuncs.js?priority=1' | |||
|   var src2 = 'http://localhost:18000/CLodopfuncs.js?priority=0' | |||
| 
 | |||
|   var head = document.head || document.getElementsByTagName('head')[0] || document.documentElement | |||
|   var oscript = document.createElement('script') | |||
|   oscript.src = src1 | |||
|   head.insertBefore(oscript, head.firstChild) | |||
|   oscript = document.createElement('script') | |||
|   oscript.src = src2 | |||
|   head.insertBefore(oscript, head.firstChild) | |||
|   CLodopIsLocal = !!((src1 + src2).match(/\/\/localho|\/\/127.0.0./i)) | |||
| } | |||
| 
 | |||
| // ====获取LODOP对象的主过程:====
 | |||
| export function getLodop(oOBJECT, oEMBED) { | |||
|   var strHtmInstall = "<br><font color='#FF00FF'>打印控件未安装!点击这里<a href='install_lodop32.exe' target='_self'>执行安装</a>,安装后请刷新页面或重新进入。</font>" | |||
|   var strHtmUpdate = "<br><font color='#FF00FF'>打印控件需要升级!点击这里<a href='install_lodop32.exe' target='_self'>执行升级</a>,升级后请重新进入。</font>" | |||
|   var strHtm64_Install = "<br><font color='#FF00FF'>打印控件未安装!点击这里<a href='install_lodop64.exe' target='_self'>执行安装</a>,安装后请刷新页面或重新进入。</font>" | |||
|   var strHtm64_Update = "<br><font color='#FF00FF'>打印控件需要升级!点击这里<a href='install_lodop64.exe' target='_self'>执行升级</a>,升级后请重新进入。</font>" | |||
|   var strHtmFireFox = "<br><br><font color='#FF00FF'>(注意:如曾安装过Lodop旧版附件npActiveXPLugin,请在【工具】->【附加组件】->【扩展】中先卸它)</font>" | |||
|   var strHtmChrome = "<br><br><font color='#FF00FF'>(如果此前正常,仅因浏览器升级或重安装而出问题,需重新执行以上安装)</font>" | |||
|   var strCLodopInstall_1 = "<br><font color='#FF00FF'>Web打印服务CLodop未安装启动,点击这里<a href='CLodop_Setup_for_Win32NT.exe' target='_self'>下载执行安装</a>" | |||
|   var strCLodopInstall_2 = "<br>(若此前已安装过,可<a href='CLodop.protocol:setup' target='_self'>点这里直接再次启动</a>)" | |||
|   var strCLodopInstall_3 = ',成功后请刷新本页面。</font>' | |||
|   var strCLodopUpdate = "<br><font color='#FF00FF'>Web打印服务CLodop需升级!点击这里<a href='CLodop_Setup_for_Win32NT.exe' target='_self'>执行升级</a>,升级后请刷新页面。</font>" | |||
|   var LODOP | |||
|   try { | |||
|     var ua = navigator.userAgent | |||
|     var isIE = !!(ua.match(/MSIE/i)) || !!(ua.match(/Trident/i)) | |||
|     if (needCLodop()) { | |||
|       try { | |||
|         LODOP = getCLodop() | |||
|       } catch (err) { } | |||
|       if (!LODOP && document.readyState !== 'complete') { | |||
|         alert('网页还没下载完毕,请稍等一下再操作.') | |||
|         return | |||
|       } | |||
|       if (!LODOP) { | |||
|         // document.body.innerHTML = strCLodopInstall_1 + (CLodopIsLocal ? strCLodopInstall_2 : "") + strCLodopInstall_3 + document.body.innerHTML;
 | |||
|         return | |||
|       } else { | |||
|         if (CLODOP.CVERSION < '3.0.8.3') { | |||
|           document.body.innerHTML = strCLodopUpdate + document.body.innerHTML | |||
|         } | |||
|         if (oEMBED && oEMBED.parentNode) { oEMBED.parentNode.removeChild(oEMBED) } | |||
|         if (oOBJECT && oOBJECT.parentNode) { oOBJECT.parentNode.removeChild(oOBJECT) } | |||
|       } | |||
|     } else { | |||
|       var is64IE = isIE && !!(ua.match(/x64/i)) | |||
|       // =====如果页面有Lodop就直接使用,没有则新建:==========
 | |||
|       if (oOBJECT || oEMBED) { | |||
|         if (isIE) { LODOP = oOBJECT } else { LODOP = oEMBED } | |||
|       } else if (!CreatedOKLodop7766) { | |||
|         LODOP = document.createElement('object') | |||
|         LODOP.setAttribute('width', 0) | |||
|         LODOP.setAttribute('height', 0) | |||
|         LODOP.setAttribute('style', 'position:absolute;left:0px;top:-100px;width:0px;height:0px;') | |||
|         if (isIE) { LODOP.setAttribute('classid', 'clsid:2105C259-1E0C-4534-8141-A753534CB4CA') } else { LODOP.setAttribute('type', 'application/x-print-lodop') } | |||
|         document.documentElement.appendChild(LODOP) | |||
|         CreatedOKLodop7766 = LODOP | |||
|       } else { LODOP = CreatedOKLodop7766 } | |||
|       // =====Lodop插件未安装时提示下载地址:==========
 | |||
|       if ((!LODOP) || (!LODOP.VERSION)) { | |||
|         if (ua.indexOf('Chrome') >= 0) { document.body.innerHTML = strHtmChrome + document.body.innerHTML } | |||
|         if (ua.indexOf('Firefox') >= 0) { document.body.innerHTML = strHtmFireFox + document.body.innerHTML } | |||
|         document.body.innerHTML = (is64IE ? strHtm64_Install : strHtmInstall) + document.body.innerHTML | |||
|         return LODOP | |||
|       } | |||
|     } | |||
|     if (LODOP.VERSION < '6.2.2.6') { | |||
|       if (!needCLodop()) { document.body.innerHTML = (is64IE ? strHtm64_Update : strHtmUpdate) + document.body.innerHTML } | |||
|     } | |||
|     // ===如下空白位置适合调用统一功能(如注册语句、语言选择等):==
 | |||
| 
 | |||
|     // 添加注册码,打印就不会出现 “本页由lodop试用版输出 ”
 | |||
|     LODOP.SET_LICENSES('', 'XXXXX', 'XXXX', '') | |||
| 
 | |||
|     // =======================================================
 | |||
|     return LODOP | |||
|   } catch (err) { | |||
|     alert('getLodop出错:' + err) | |||
|   } | |||
| } | |||
| 
 | |||
| @ -1,33 +0,0 @@ | |||
| /* | |||
|  * @Author: 秦少卫 | |||
|  * @Date: 2022-09-03 19:16:55 | |||
|  * @LastEditors: 秦少卫 | |||
|  * @LastEditTime: 2022-09-04 00:01:00 | |||
|  * @Description: 自定义事件 | |||
|  */ | |||
| 
 | |||
| import EventEmitter from 'events' | |||
| 
 | |||
| class EventHandle extends EventEmitter { | |||
|   init(handler) { | |||
|     this.handler = handler | |||
|     this.handler.on('selection:created', (e) => this._selected(e)) | |||
|     this.handler.on('selection:updated', (e) => this._selected(e)) | |||
|     this.handler.on('selection:cleared', (e) => this._selected(e)) | |||
|   } | |||
| 
 | |||
|   // 暴露单选多选事件
 | |||
|   _selected(e) { | |||
|     const actives = this.handler.getActiveObjects() | |||
|     if (actives && actives.length === 1) { | |||
|       this.emit('selectOne', actives) | |||
|     } else if (actives && actives.length > 1) { | |||
|       this.mSelectMode = 'multiple' | |||
|       this.emit('selectMultiple', actives) | |||
|     } else { | |||
|       this.emit('selectCancel') | |||
|     } | |||
|   } | |||
| } | |||
| 
 | |||
| export default EventHandle | |||
| @ -1,113 +0,0 @@ | |||
| /** | |||
|  * 树形json中根据id查找,并返回路径 | |||
|  * @param {Array} data | |||
|  * @param {string} id | |||
|  * @param {Array} indexArray | |||
|  */ | |||
| export function findIndexArray(data, id, indexArray) { | |||
|   const arr = Array.from(indexArray) | |||
|   for (let i = 0, len = data.length; i < len; i++) { | |||
|     arr.push(data[i].id) | |||
|     if (data[i].id === id) { | |||
|       return arr | |||
|     } | |||
|     const children = data[i].children | |||
|     if (children && children.length) { | |||
|       const result = findIndexArray(children, id, arr) | |||
|       if (result.length > 0) return result | |||
|     } | |||
|     arr.pop() | |||
|   } | |||
|   return [] | |||
| } | |||
| 
 | |||
| /** | |||
|  * 树形json中根据字段值查找,并返回路径 | |||
|  * @param {Array} data | |||
|  * @param {string} fieldValue | |||
|  * @param {string} fieldName | |||
|  * @param {string} childrenName | |||
|  * @param {Array} indexArray | |||
|  * @returns 路径【fieldName】数组 | |||
|  */ | |||
| export function findPathArray(data, fieldValue, fieldName = 'id', childrenName = 'children', indexArray = []) { | |||
|   const arr = Array.from(indexArray) | |||
|   for (let i = 0, len = data.length; i < len; i++) { | |||
|     arr.push(data[i][fieldName]) | |||
|     if (data[i][fieldName] === fieldValue) { | |||
|       return arr | |||
|     } | |||
|     const children = data[i][childrenName] | |||
|     if (children && children.length) { | |||
|       const result = findPathArray(children, fieldValue, fieldName, childrenName, arr) | |||
|       if (result.length > 0) return result | |||
|     } | |||
|     arr.pop() | |||
|   } | |||
|   return [] | |||
| } | |||
| 
 | |||
| /** | |||
|  * 树中查找指定对象 | |||
|  * @param {Array} data | |||
|  * @param {String} fieldValue | |||
|  * @param {String} childrenName | |||
|  * @param {String} fieldName | |||
|  * @returns 目标对象 | |||
|  */ | |||
| export function findItem(data, fieldValue, fieldName = 'id', childrenName = 'children') { | |||
|   // console.log(data, fieldValue, fieldName)
 | |||
|   for (let i = 0, len = data.length; i < len; i++) { | |||
|     if (data[i][fieldName] && data[i][fieldName] === fieldValue) { | |||
|       return data[i] | |||
|     } else if (data[i][childrenName]) { | |||
|       const temp = findItem(data[i][childrenName], fieldValue, fieldName, childrenName) | |||
|       if (temp) { | |||
|         return temp | |||
|       } | |||
|     } | |||
|   } | |||
| } | |||
| 
 | |||
| /** | |||
|  * 分组(2层) | |||
|  * @param {Array} array | |||
|  * @param {String} groupKey | |||
|  * @returns [数组]数组 | |||
|  */ | |||
| export function groupBy(array, groupKey = 'name', labelKey = 'label', idKey = 'id') { | |||
|   const groups = {} | |||
|   array.forEach(item => { | |||
|     const groupValue = JSON.stringify(item[groupKey]) // 值转字段名
 | |||
|     groups[groupValue] = groups[groupValue] || [] | |||
|     item.id = item[idKey] || '' | |||
|     item.label = item[labelKey] || '' | |||
|     groups[groupValue].push(item) // 分组
 | |||
|   }) | |||
|   return Object.keys(groups).map(key => { | |||
|     const item = { } | |||
|     item.label = JSON.parse(key) | |||
|     item.id = item[idKey] || item.label | |||
|     item.children = groups[key] | |||
|     return item | |||
|   }) | |||
| } | |||
| 
 | |||
| export function groupBy_getArray(array, groupKey = 'name') { | |||
|   const groups = {} | |||
|   array.forEach(item => { | |||
|     const groupValue = JSON.stringify(item[groupKey]) // 值转字段名
 | |||
|     groups[groupValue] = groups[groupValue] || [] | |||
|     groups[groupValue].push(item) // 分组
 | |||
|   }) | |||
|   return Object.keys(groups).map(key => groups[key]) | |||
| } | |||
| 
 | |||
| export function groupBy_getName(array, groupKey = 'name') { | |||
|   const groups = {} | |||
|   array.forEach(item => { | |||
|     const groupValue = item[groupKey] // 值转字段名
 | |||
|     groups[groupValue] = groups[groupValue] || [] | |||
|   }) | |||
|   return Object.keys(groups) | |||
| } | |||
| @ -1,47 +0,0 @@ | |||
| /* | |||
|  * @Author: 秦少卫 | |||
|  * @Date: 2022-09-05 22:21:55 | |||
|  * @LastEditors: 秦少卫 | |||
|  * @LastEditTime: 2022-09-05 23:00:29 | |||
|  * @Description: 工具文件 | |||
|  */ | |||
| 
 | |||
| import FontFaceObserver from 'fontfaceobserver' | |||
| 
 | |||
| /** | |||
|  * @description: 图片文件转字符串 | |||
|  * @param {Blob|File} file 文件 | |||
|  * @return {String} | |||
|  */ | |||
| export function getImgStr(file) { | |||
|     return new Promise((resolve, reject) => { | |||
|         try { | |||
|             const reader = new FileReader(); | |||
|             reader.readAsDataURL(file); | |||
|             reader.onload = () => { | |||
|                 resolve(reader.result) | |||
|             }; | |||
|         } catch (error) { | |||
|             reject(error) | |||
|         } | |||
|     }); | |||
| } | |||
| 
 | |||
| 
 | |||
| /** | |||
|  * @description: 根据json模板下载字体文件 | |||
|  * @param {String} str | |||
|  * @return {Promise} | |||
|  */ | |||
| export function downFontByJSON(str) { | |||
|     const skipFonts = ['arial', 'Microsoft YaHei'] | |||
|     const fontFamilys = JSON.parse(str).objects.filter(item => { | |||
|         // 为text 并且不为包含字体
 | |||
|         return (item.type.includes('text') && !skipFonts.includes(item.fontFamily)) | |||
|     }).map(item => item.fontFamily) | |||
|     const fontFamilysAll = fontFamilys.map(fontName => { | |||
|         const font = new FontFaceObserver(fontName); | |||
|         return font.load(null, 150000) | |||
|     }) | |||
|     return Promise.all(fontFamilysAll) | |||
| } | |||
| @ -1,16 +0,0 @@ | |||
| body { | |||
|     /* 整个body不可点击 */ | |||
|     pointer-events: none;  | |||
| } | |||
| /* textarea去除右下角拖拽键 */ | |||
| textarea { | |||
|     resize:none; | |||
| } | |||
| /* 签名按钮打印时不显示 */ | |||
| .hmbutton  { | |||
|     display: none; | |||
| } | |||
| /* .hmselectmultiple  { | |||
|     border-radius: 6px; | |||
| } */ | |||
| 
 | |||
| @ -1,124 +0,0 @@ | |||
| html { | |||
|   height: 100%; | |||
| } | |||
| 
 | |||
| body { | |||
|   padding: 0px; | |||
|   margin: 0px; | |||
| } | |||
| 
 | |||
| /*定义滚动条高宽及背景 高宽分别对应横竖滚动条的尺寸*/ | |||
| ::-webkit-scrollbar { | |||
|   width: 6px; | |||
|   /*滚动条宽度*/ | |||
|   height: 8px; | |||
|   /*滚动条高度*/ | |||
|   background-color: rgb(224, 223, 223, .2); | |||
| } | |||
| 
 | |||
| /*定义滑块 内阴影+圆角*/ | |||
| ::-webkit-scrollbar-thumb { | |||
|   -webkit-box-shadow: inset 0 0 0px white; | |||
|   background-color: rgb(193, 193, 193); | |||
|   /*滚动条的背景颜色*/ | |||
|   border-radius: 30px; | |||
| } | |||
| 
 | |||
| /* .MsoNormal { | |||
|     display: inline-block; | |||
|   } */ | |||
| 
 | |||
| table { | |||
|   border-collapse: collapse; | |||
|    | |||
| } | |||
| 
 | |||
| input, | |||
| textarea { | |||
|   margin-right: 2px; | |||
|   border-radius: 2px 2px 0 0; | |||
|   outline: none; | |||
|   background: transparent; | |||
| } | |||
| 
 | |||
| .border-1 { | |||
|   border: none; | |||
|   border-bottom: 1px solid #767676; | |||
|   border-width: thin; | |||
| } | |||
| 
 | |||
| .border-2 { | |||
|   border: revert; | |||
|   border-width: thin; | |||
| } | |||
| 
 | |||
| .border-3 { | |||
|   border: none; | |||
| } | |||
| 
 | |||
| textarea { | |||
|   text-align: left !important; | |||
|   max-width: 550px !important; | |||
|   line-height: 18px; | |||
|   overflow-y: hidden; | |||
|   margin: 0 !important; | |||
| } | |||
| 
 | |||
| #work-unit { | |||
|   max-width: 500px !important; | |||
| } | |||
| 
 | |||
| p { | |||
|   margin: 0 0 12px 0; | |||
| } | |||
| p:last-child { | |||
|   margin: 0; | |||
| } | |||
| .hmbutton { | |||
|   /* padding: 5px 14px; */ | |||
|   border: none; | |||
|   /* background: #409eff; */ | |||
|   /* color: #fff; */ | |||
|   color: #409eff; | |||
|   cursor: pointer | |||
| } | |||
| 
 | |||
| @media print { | |||
| 
 | |||
|   /* 避免表格断开 */ | |||
|   /* table{ | |||
|         page-break-after: avoid; | |||
|     }    */ | |||
|   /* 避免某行文字断裂 */ | |||
|   table { | |||
|     /* page-break-inside: avoid; */ | |||
|   } | |||
| 
 | |||
|   html { | |||
|     zoom: 75%; | |||
|   } | |||
| 
 | |||
|   .mce-item-anchor { | |||
|     display: none; | |||
|   } | |||
| } | |||
| 
 | |||
| .el-input { | |||
|   width: 100px !important; | |||
| } | |||
| 
 | |||
| .el-input__inner { | |||
|   border: none !important; | |||
|   text-align: right !important; | |||
| } | |||
| 
 | |||
| .el-radio { | |||
|   margin-right: 8px !important; | |||
| } | |||
| .mce-item-table:not([border]), .mce-item-table:not([border]) caption, .mce-item-table:not([border]) td, .mce-item-table:not([border]) th, .mce-item-table[border="0"], .mce-item-table[border="0"] caption, .mce-item-table[border="0"] td, .mce-item-table[border="0"] th, table[style*="border-width: 0px"], table[style*="border-width: 0px"] caption, table[style*="border-width: 0px"] td, table[style*="border-width: 0px"] th { | |||
|   border: none; | |||
| } | |||
| .hmselect { | |||
|   border: none; | |||
|   border-bottom: 1px solid #767676; | |||
| } | |||
| @ -1,714 +0,0 @@ | |||
| /** | |||
|  * 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/ | |||
|  */ | |||
| .mce-content-body .mce-item-anchor { | |||
|   background: transparent url("data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D'8'%20height%3D'12'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%3E%3Cpath%20d%3D'M0%200L8%200%208%2012%204.09117821%209%200%2012z'%20fill%3D%22%23cccccc%22%2F%3E%3C%2Fsvg%3E%0A") no-repeat center; | |||
|   cursor: default; | |||
|   display: inline-block; | |||
|   height: 12px !important; | |||
|   padding: 0 2px; | |||
|   -webkit-user-modify: read-only; | |||
|   -moz-user-modify: read-only; | |||
|   -webkit-user-select: all; | |||
|   -moz-user-select: all; | |||
|   -ms-user-select: all; | |||
|       user-select: all; | |||
|   width: 8px !important; | |||
| } | |||
| .mce-content-body .mce-item-anchor[data-mce-selected] { | |||
|   outline-offset: 1px; | |||
| } | |||
| .tox-comments-visible .tox-comment { | |||
|   background-color: #fff0b7; | |||
| } | |||
| .tox-comments-visible .tox-comment--active { | |||
|   background-color: #ffe168; | |||
| } | |||
| .tox-checklist > li:not(.tox-checklist--hidden) { | |||
|   list-style: none; | |||
|   margin: 0.25em 0; | |||
| } | |||
| .tox-checklist > li:not(.tox-checklist--hidden)::before { | |||
|   content: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2216%22%20height%3D%2216%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cg%20id%3D%22checklist-unchecked%22%20fill%3D%22none%22%20fill-rule%3D%22evenodd%22%3E%3Crect%20id%3D%22Rectangle%22%20width%3D%2215%22%20height%3D%2215%22%20x%3D%22.5%22%20y%3D%22.5%22%20fill-rule%3D%22nonzero%22%20stroke%3D%22%236d737b%22%20rx%3D%222%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E%0A"); | |||
|   cursor: pointer; | |||
|   height: 1em; | |||
|   margin-left: -1.5em; | |||
|   margin-top: 0.125em; | |||
|   position: absolute; | |||
|   width: 1em; | |||
| } | |||
| .tox-checklist li:not(.tox-checklist--hidden).tox-checklist--checked::before { | |||
|   content: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2216%22%20height%3D%2216%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cg%20id%3D%22checklist-checked%22%20fill%3D%22none%22%20fill-rule%3D%22evenodd%22%3E%3Crect%20id%3D%22Rectangle%22%20width%3D%2216%22%20height%3D%2216%22%20fill%3D%22%234099FF%22%20fill-rule%3D%22nonzero%22%20rx%3D%222%22%2F%3E%3Cpath%20id%3D%22Path%22%20fill%3D%22%23FFF%22%20fill-rule%3D%22nonzero%22%20d%3D%22M11.5703186%2C3.14417309%20C11.8516238%2C2.73724603%2012.4164781%2C2.62829933%2012.83558%2C2.89774797%20C13.260121%2C3.17069355%2013.3759736%2C3.72932262%2013.0909105%2C4.14168582%20L7.7580587%2C11.8560195%20C7.43776896%2C12.3193404%206.76483983%2C12.3852142%206.35607322%2C11.9948725%20L3.02491697%2C8.8138662%20C2.66090143%2C8.46625845%202.65798871%2C7.89594698%203.01850234%2C7.54483354%20C3.373942%2C7.19866177%203.94940006%2C7.19592841%204.30829608%2C7.5386474%20L6.85276923%2C9.9684299%20L11.5703186%2C3.14417309%20Z%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E%0A"); | |||
| } | |||
| [dir=rtl] .tox-checklist > li:not(.tox-checklist--hidden)::before { | |||
|   margin-left: 0; | |||
|   margin-right: -1.5em; | |||
| } | |||
| /* stylelint-disable */ | |||
| /* http://prismjs.com/ */ | |||
| /** | |||
|  * Dracula Theme originally by Zeno Rocha [@zenorocha] | |||
|  * https://draculatheme.com/ | |||
|  * | |||
|  * Ported for PrismJS by Albert Vallverdu [@byverdu] | |||
|  */ | |||
| code[class*="language-"], | |||
| pre[class*="language-"] { | |||
|   color: #f8f8f2; | |||
|   background: none; | |||
|   text-shadow: 0 1px rgba(0, 0, 0, 0.3); | |||
|   font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; | |||
|   text-align: left; | |||
|   white-space: pre; | |||
|   word-spacing: normal; | |||
|   word-break: normal; | |||
|   word-wrap: normal; | |||
|   line-height: 1.5; | |||
|   -moz-tab-size: 4; | |||
|   tab-size: 4; | |||
|   -webkit-hyphens: none; | |||
|   -ms-hyphens: none; | |||
|   hyphens: none; | |||
| } | |||
| /* Code blocks */ | |||
| pre[class*="language-"] { | |||
|   padding: 1em; | |||
|   margin: 0.5em 0; | |||
|   overflow: auto; | |||
|   border-radius: 0.3em; | |||
| } | |||
| :not(pre) > code[class*="language-"], | |||
| pre[class*="language-"] { | |||
|   background: #282a36; | |||
| } | |||
| /* Inline code */ | |||
| :not(pre) > code[class*="language-"] { | |||
|   padding: 0.1em; | |||
|   border-radius: 0.3em; | |||
|   white-space: normal; | |||
| } | |||
| .token.comment, | |||
| .token.prolog, | |||
| .token.doctype, | |||
| .token.cdata { | |||
|   color: #6272a4; | |||
| } | |||
| .token.punctuation { | |||
|   color: #f8f8f2; | |||
| } | |||
| .namespace { | |||
|   opacity: 0.7; | |||
| } | |||
| .token.property, | |||
| .token.tag, | |||
| .token.constant, | |||
| .token.symbol, | |||
| .token.deleted { | |||
|   color: #ff79c6; | |||
| } | |||
| .token.boolean, | |||
| .token.number { | |||
|   color: #bd93f9; | |||
| } | |||
| .token.selector, | |||
| .token.attr-name, | |||
| .token.string, | |||
| .token.char, | |||
| .token.builtin, | |||
| .token.inserted { | |||
|   color: #50fa7b; | |||
| } | |||
| .token.operator, | |||
| .token.entity, | |||
| .token.url, | |||
| .language-css .token.string, | |||
| .style .token.string, | |||
| .token.variable { | |||
|   color: #f8f8f2; | |||
| } | |||
| .token.atrule, | |||
| .token.attr-value, | |||
| .token.function, | |||
| .token.class-name { | |||
|   color: #f1fa8c; | |||
| } | |||
| .token.keyword { | |||
|   color: #8be9fd; | |||
| } | |||
| .token.regex, | |||
| .token.important { | |||
|   color: #ffb86c; | |||
| } | |||
| .token.important, | |||
| .token.bold { | |||
|   font-weight: bold; | |||
| } | |||
| .token.italic { | |||
|   font-style: italic; | |||
| } | |||
| .token.entity { | |||
|   cursor: help; | |||
| } | |||
| /* stylelint-enable */ | |||
| .mce-content-body { | |||
|   overflow-wrap: break-word; | |||
|   word-wrap: break-word; | |||
| } | |||
| .mce-content-body .mce-visual-caret { | |||
|   background-color: black; | |||
|   background-color: currentColor; | |||
|   position: absolute; | |||
| } | |||
| .mce-content-body .mce-visual-caret-hidden { | |||
|   display: none; | |||
| } | |||
| .mce-content-body *[data-mce-caret] { | |||
|   left: -1000px; | |||
|   margin: 0; | |||
|   padding: 0; | |||
|   position: absolute; | |||
|   right: auto; | |||
|   top: 0; | |||
| } | |||
| .mce-content-body .mce-offscreen-selection { | |||
|   left: -2000000px; | |||
|   max-width: 1000000px; | |||
|   position: absolute; | |||
| } | |||
| .mce-content-body *[contentEditable=false] { | |||
|   cursor: default; | |||
| } | |||
| .mce-content-body *[contentEditable=true] { | |||
|   cursor: text; | |||
| } | |||
| .tox-cursor-format-painter { | |||
|   cursor: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%3E%0A%20%20%3Cg%20fill%3D%22none%22%20fill-rule%3D%22evenodd%22%3E%0A%20%20%20%20%3Cpath%20fill%3D%22%23000%22%20fill-rule%3D%22nonzero%22%20d%3D%22M15%2C6%20C15%2C5.45%2014.55%2C5%2014%2C5%20L6%2C5%20C5.45%2C5%205%2C5.45%205%2C6%20L5%2C10%20C5%2C10.55%205.45%2C11%206%2C11%20L14%2C11%20C14.55%2C11%2015%2C10.55%2015%2C10%20L15%2C9%20L16%2C9%20L16%2C12%20L9%2C12%20L9%2C19%20C9%2C19.55%209.45%2C20%2010%2C20%20L11%2C20%20C11.55%2C20%2012%2C19.55%2012%2C19%20L12%2C14%20L18%2C14%20L18%2C7%20L15%2C7%20L15%2C6%20Z%22%2F%3E%0A%20%20%20%20%3Cpath%20fill%3D%22%23000%22%20fill-rule%3D%22nonzero%22%20d%3D%22M1%2C1%20L8.25%2C1%20C8.66421356%2C1%209%2C1.33578644%209%2C1.75%20L9%2C1.75%20C9%2C2.16421356%208.66421356%2C2.5%208.25%2C2.5%20L2.5%2C2.5%20L2.5%2C8.25%20C2.5%2C8.66421356%202.16421356%2C9%201.75%2C9%20L1.75%2C9%20C1.33578644%2C9%201%2C8.66421356%201%2C8.25%20L1%2C1%20Z%22%2F%3E%0A%20%20%3C%2Fg%3E%0A%3C%2Fsvg%3E%0A"), default; | |||
| } | |||
| .mce-content-body figure.align-left { | |||
|   float: left; | |||
| } | |||
| .mce-content-body figure.align-right { | |||
|   float: right; | |||
| } | |||
| .mce-content-body figure.image.align-center { | |||
|   display: table; | |||
|   margin-left: auto; | |||
|   margin-right: auto; | |||
| } | |||
| .mce-preview-object { | |||
|   border: 1px solid gray; | |||
|   display: inline-block; | |||
|   line-height: 0; | |||
|   margin: 0 2px 0 2px; | |||
|   position: relative; | |||
| } | |||
| .mce-preview-object .mce-shim { | |||
|   background: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7); | |||
|   height: 100%; | |||
|   left: 0; | |||
|   position: absolute; | |||
|   top: 0; | |||
|   width: 100%; | |||
| } | |||
| .mce-preview-object[data-mce-selected="2"] .mce-shim { | |||
|   display: none; | |||
| } | |||
| .mce-object { | |||
|   background: transparent url("data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%3E%3Cpath%20d%3D%22M4%203h16a1%201%200%200%201%201%201v16a1%201%200%200%201-1%201H4a1%201%200%200%201-1-1V4a1%201%200%200%201%201-1zm1%202v14h14V5H5zm4.79%202.565l5.64%204.028a.5.5%200%200%201%200%20.814l-5.64%204.028a.5.5%200%200%201-.79-.407V7.972a.5.5%200%200%201%20.79-.407z%22%20fill%3D%22%23cccccc%22%2F%3E%3C%2Fsvg%3E%0A") no-repeat center; | |||
|   border: 1px dashed #aaa; | |||
| } | |||
| .mce-pagebreak { | |||
|   border: 1px dashed #aaa; | |||
|   cursor: default; | |||
|   display: block; | |||
|   height: 5px; | |||
|   margin-top: 15px; | |||
|   page-break-before: always; | |||
|   width: 100%; | |||
| } | |||
| @media print { | |||
|   .mce-pagebreak { | |||
|     border: 0; | |||
|   } | |||
| } | |||
| .tiny-pageembed .mce-shim { | |||
|   background: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7); | |||
|   height: 100%; | |||
|   left: 0; | |||
|   position: absolute; | |||
|   top: 0; | |||
|   width: 100%; | |||
| } | |||
| .tiny-pageembed[data-mce-selected="2"] .mce-shim { | |||
|   display: none; | |||
| } | |||
| .tiny-pageembed { | |||
|   display: inline-block; | |||
|   position: relative; | |||
| } | |||
| .tiny-pageembed--21by9, | |||
| .tiny-pageembed--16by9, | |||
| .tiny-pageembed--4by3, | |||
| .tiny-pageembed--1by1 { | |||
|   display: block; | |||
|   overflow: hidden; | |||
|   padding: 0; | |||
|   position: relative; | |||
|   width: 100%; | |||
| } | |||
| .tiny-pageembed--21by9 { | |||
|   padding-top: 42.857143%; | |||
| } | |||
| .tiny-pageembed--16by9 { | |||
|   padding-top: 56.25%; | |||
| } | |||
| .tiny-pageembed--4by3 { | |||
|   padding-top: 75%; | |||
| } | |||
| .tiny-pageembed--1by1 { | |||
|   padding-top: 100%; | |||
| } | |||
| .tiny-pageembed--21by9 iframe, | |||
| .tiny-pageembed--16by9 iframe, | |||
| .tiny-pageembed--4by3 iframe, | |||
| .tiny-pageembed--1by1 iframe { | |||
|   border: 0; | |||
|   height: 100%; | |||
|   left: 0; | |||
|   position: absolute; | |||
|   top: 0; | |||
|   width: 100%; | |||
| } | |||
| .mce-content-body[data-mce-placeholder] { | |||
|   position: relative; | |||
| } | |||
| .mce-content-body[data-mce-placeholder]:not(.mce-visualblocks)::before { | |||
|   color: rgba(34, 47, 62, 0.7); | |||
|   content: attr(data-mce-placeholder); | |||
|   position: absolute; | |||
| } | |||
| .mce-content-body:not([dir=rtl])[data-mce-placeholder]:not(.mce-visualblocks)::before { | |||
|   left: 1px; | |||
| } | |||
| .mce-content-body[dir=rtl][data-mce-placeholder]:not(.mce-visualblocks)::before { | |||
|   right: 1px; | |||
| } | |||
| .mce-content-body div.mce-resizehandle { | |||
|   background-color: #4099ff; | |||
|   border-color: #4099ff; | |||
|   border-style: solid; | |||
|   border-width: 1px; | |||
|   box-sizing: border-box; | |||
|   height: 10px; | |||
|   position: absolute; | |||
|   width: 10px; | |||
|   z-index: 10000; | |||
| } | |||
| .mce-content-body div.mce-resizehandle:hover { | |||
|   background-color: #4099ff; | |||
| } | |||
| .mce-content-body div.mce-resizehandle:nth-of-type(1) { | |||
|   cursor: nwse-resize; | |||
| } | |||
| .mce-content-body div.mce-resizehandle:nth-of-type(2) { | |||
|   cursor: nesw-resize; | |||
| } | |||
| .mce-content-body div.mce-resizehandle:nth-of-type(3) { | |||
|   cursor: nwse-resize; | |||
| } | |||
| .mce-content-body div.mce-resizehandle:nth-of-type(4) { | |||
|   cursor: nesw-resize; | |||
| } | |||
| .mce-content-body .mce-resize-backdrop { | |||
|   z-index: 10000; | |||
| } | |||
| .mce-content-body .mce-clonedresizable { | |||
|   cursor: default; | |||
|   opacity: 0.5; | |||
|   outline: 1px dashed black; | |||
|   position: absolute; | |||
|   z-index: 10001; | |||
| } | |||
| .mce-content-body .mce-clonedresizable.mce-resizetable-columns th, | |||
| .mce-content-body .mce-clonedresizable.mce-resizetable-columns td { | |||
|   border: 0; | |||
| } | |||
| .mce-content-body .mce-resize-helper { | |||
|   background: #555; | |||
|   background: rgba(0, 0, 0, 0.75); | |||
|   border: 1px; | |||
|   border-radius: 3px; | |||
|   color: white; | |||
|   display: none; | |||
|   font-family: sans-serif; | |||
|   font-size: 12px; | |||
|   line-height: 14px; | |||
|   margin: 5px 10px; | |||
|   padding: 5px; | |||
|   position: absolute; | |||
|   white-space: nowrap; | |||
|   z-index: 10002; | |||
| } | |||
| .tox-rtc-user-selection { | |||
|   position: relative; | |||
| } | |||
| .tox-rtc-user-cursor { | |||
|   bottom: 0; | |||
|   cursor: default; | |||
|   position: absolute; | |||
|   top: 0; | |||
|   width: 2px; | |||
| } | |||
| .tox-rtc-user-cursor::before { | |||
|   background-color: inherit; | |||
|   border-radius: 50%; | |||
|   content: ''; | |||
|   display: block; | |||
|   height: 8px; | |||
|   position: absolute; | |||
|   right: -3px; | |||
|   top: -3px; | |||
|   width: 8px; | |||
| } | |||
| .tox-rtc-user-cursor:hover::after { | |||
|   background-color: inherit; | |||
|   border-radius: 100px; | |||
|   box-sizing: border-box; | |||
|   color: #fff; | |||
|   content: attr(data-user); | |||
|   display: block; | |||
|   font-size: 12px; | |||
|   font-weight: bold; | |||
|   left: -5px; | |||
|   min-height: 8px; | |||
|   min-width: 8px; | |||
|   padding: 0 12px; | |||
|   position: absolute; | |||
|   top: -11px; | |||
|   white-space: nowrap; | |||
|   z-index: 1000; | |||
| } | |||
| .tox-rtc-user-selection--1 .tox-rtc-user-cursor { | |||
|   background-color: #2dc26b; | |||
| } | |||
| .tox-rtc-user-selection--2 .tox-rtc-user-cursor { | |||
|   background-color: #e03e2d; | |||
| } | |||
| .tox-rtc-user-selection--3 .tox-rtc-user-cursor { | |||
|   background-color: #f1c40f; | |||
| } | |||
| .tox-rtc-user-selection--4 .tox-rtc-user-cursor { | |||
|   background-color: #3598db; | |||
| } | |||
| .tox-rtc-user-selection--5 .tox-rtc-user-cursor { | |||
|   background-color: #b96ad9; | |||
| } | |||
| .tox-rtc-user-selection--6 .tox-rtc-user-cursor { | |||
|   background-color: #e67e23; | |||
| } | |||
| .tox-rtc-user-selection--7 .tox-rtc-user-cursor { | |||
|   background-color: #aaa69d; | |||
| } | |||
| .tox-rtc-user-selection--8 .tox-rtc-user-cursor { | |||
|   background-color: #f368e0; | |||
| } | |||
| .tox-rtc-remote-image { | |||
|   background: #eaeaea url("data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%2236%22%20height%3D%2212%22%20viewBox%3D%220%200%2036%2012%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%20%20%3Ccircle%20cx%3D%226%22%20cy%3D%226%22%20r%3D%223%22%20fill%3D%22rgba(0%2C%200%2C%200%2C%20.2)%22%3E%0A%20%20%20%20%3Canimate%20attributeName%3D%22r%22%20values%3D%223%3B5%3B3%22%20calcMode%3D%22linear%22%20dur%3D%221s%22%20repeatCount%3D%22indefinite%22%20%2F%3E%0A%20%20%3C%2Fcircle%3E%0A%20%20%3Ccircle%20cx%3D%2218%22%20cy%3D%226%22%20r%3D%223%22%20fill%3D%22rgba(0%2C%200%2C%200%2C%20.2)%22%3E%0A%20%20%20%20%3Canimate%20attributeName%3D%22r%22%20values%3D%223%3B5%3B3%22%20calcMode%3D%22linear%22%20begin%3D%22.33s%22%20dur%3D%221s%22%20repeatCount%3D%22indefinite%22%20%2F%3E%0A%20%20%3C%2Fcircle%3E%0A%20%20%3Ccircle%20cx%3D%2230%22%20cy%3D%226%22%20r%3D%223%22%20fill%3D%22rgba(0%2C%200%2C%200%2C%20.2)%22%3E%0A%20%20%20%20%3Canimate%20attributeName%3D%22r%22%20values%3D%223%3B5%3B3%22%20calcMode%3D%22linear%22%20begin%3D%22.66s%22%20dur%3D%221s%22%20repeatCount%3D%22indefinite%22%20%2F%3E%0A%20%20%3C%2Fcircle%3E%0A%3C%2Fsvg%3E%0A") no-repeat center center; | |||
|   border: 1px solid #ccc; | |||
|   min-height: 240px; | |||
|   min-width: 320px; | |||
| } | |||
| .mce-match-marker { | |||
|   background: #aaa; | |||
|   color: #fff; | |||
| } | |||
| .mce-match-marker-selected { | |||
|   background: #39f; | |||
|   color: #fff; | |||
| } | |||
| .mce-match-marker-selected::-moz-selection { | |||
|   background: #39f; | |||
|   color: #fff; | |||
| } | |||
| .mce-match-marker-selected::selection { | |||
|   background: #39f; | |||
|   color: #fff; | |||
| } | |||
| .mce-content-body img[data-mce-selected], | |||
| .mce-content-body video[data-mce-selected], | |||
| .mce-content-body audio[data-mce-selected], | |||
| .mce-content-body object[data-mce-selected], | |||
| .mce-content-body embed[data-mce-selected], | |||
| .mce-content-body table[data-mce-selected] { | |||
|   outline: 3px solid #4099ff; | |||
| } | |||
| .mce-content-body hr[data-mce-selected] { | |||
|   outline: 3px solid #4099ff; | |||
|   outline-offset: 1px; | |||
| } | |||
| .mce-content-body *[contentEditable=false] *[contentEditable=true]:focus { | |||
|   outline: 3px solid #4099ff; | |||
| } | |||
| .mce-content-body *[contentEditable=false] *[contentEditable=true]:hover { | |||
|   outline: 3px solid #4099ff; | |||
| } | |||
| .mce-content-body *[contentEditable=false][data-mce-selected] { | |||
|   cursor: not-allowed; | |||
|   outline: 3px solid #4099ff; | |||
| } | |||
| .mce-content-body.mce-content-readonly *[contentEditable=true]:focus, | |||
| .mce-content-body.mce-content-readonly *[contentEditable=true]:hover { | |||
|   outline: none; | |||
| } | |||
| .mce-content-body *[data-mce-selected="inline-boundary"] { | |||
|   background-color: #4099ff; | |||
| } | |||
| .mce-content-body .mce-edit-focus { | |||
|   outline: 3px solid #4099ff; | |||
| } | |||
| .mce-content-body td[data-mce-selected], | |||
| .mce-content-body th[data-mce-selected] { | |||
|   position: relative; | |||
| } | |||
| .mce-content-body td[data-mce-selected]::-moz-selection, | |||
| .mce-content-body th[data-mce-selected]::-moz-selection { | |||
|   background: none; | |||
| } | |||
| .mce-content-body td[data-mce-selected]::selection, | |||
| .mce-content-body th[data-mce-selected]::selection { | |||
|   background: none; | |||
| } | |||
| .mce-content-body td[data-mce-selected] *, | |||
| .mce-content-body th[data-mce-selected] * { | |||
|   outline: none; | |||
|   -webkit-touch-callout: none; | |||
|   -webkit-user-select: none; | |||
|      -moz-user-select: none; | |||
|       -ms-user-select: none; | |||
|           user-select: none; | |||
| } | |||
| .mce-content-body td[data-mce-selected]::after, | |||
| .mce-content-body th[data-mce-selected]::after { | |||
|   background-color: rgba(180, 215, 255, 0.7); | |||
|   border: 1px solid transparent; | |||
|   bottom: -1px; | |||
|   content: ''; | |||
|   left: -1px; | |||
|   mix-blend-mode: lighten; | |||
|   position: absolute; | |||
|   right: -1px; | |||
|   top: -1px; | |||
| } | |||
| @media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) { | |||
|   .mce-content-body td[data-mce-selected]::after, | |||
|   .mce-content-body th[data-mce-selected]::after { | |||
|     border-color: rgba(0, 84, 180, 0.7); | |||
|   } | |||
| } | |||
| .mce-content-body img::-moz-selection { | |||
|   background: none; | |||
| } | |||
| .mce-content-body img::selection { | |||
|   background: none; | |||
| } | |||
| .ephox-snooker-resizer-bar { | |||
|   background-color: #4099ff; | |||
|   opacity: 0; | |||
|   -webkit-user-select: none; | |||
|   -moz-user-select: none; | |||
|   -ms-user-select: none; | |||
|   user-select: none; | |||
| } | |||
| .ephox-snooker-resizer-cols { | |||
|   cursor: col-resize; | |||
| } | |||
| .ephox-snooker-resizer-rows { | |||
|   cursor: row-resize; | |||
| } | |||
| .ephox-snooker-resizer-bar.ephox-snooker-resizer-bar-dragging { | |||
|   opacity: 1; | |||
| } | |||
| .mce-spellchecker-word { | |||
|   background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D'4'%20height%3D'4'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%3E%3Cpath%20stroke%3D'%23ff0000'%20fill%3D'none'%20stroke-linecap%3D'round'%20stroke-opacity%3D'.75'%20d%3D'M0%203L2%201%204%203'%2F%3E%3C%2Fsvg%3E%0A"); | |||
|   background-position: 0 calc(100% + 1px); | |||
|   background-repeat: repeat-x; | |||
|   background-size: auto 6px; | |||
|   cursor: default; | |||
|   height: 2rem; | |||
| } | |||
| .mce-spellchecker-grammar { | |||
|   background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D'4'%20height%3D'4'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%3E%3Cpath%20stroke%3D'%2300A835'%20fill%3D'none'%20stroke-linecap%3D'round'%20d%3D'M0%203L2%201%204%203'%2F%3E%3C%2Fsvg%3E%0A"); | |||
|   background-position: 0 calc(100% + 1px); | |||
|   background-repeat: repeat-x; | |||
|   background-size: auto 6px; | |||
|   cursor: default; | |||
| } | |||
| .mce-toc { | |||
|   border: 1px solid gray; | |||
| } | |||
| .mce-toc h2 { | |||
|   margin: 4px; | |||
| } | |||
| .mce-toc li { | |||
|   list-style-type: none; | |||
| } | |||
| table[style*="border-width: 0px"], | |||
| .mce-item-table:not([border]), | |||
| .mce-item-table[border="0"], | |||
| table[style*="border-width: 0px"] td, | |||
| .mce-item-table:not([border]) td, | |||
| .mce-item-table[border="0"] td, | |||
| table[style*="border-width: 0px"] th, | |||
| .mce-item-table:not([border]) th, | |||
| .mce-item-table[border="0"] th, | |||
| table[style*="border-width: 0px"] caption, | |||
| .mce-item-table:not([border]) caption, | |||
| .mce-item-table[border="0"] caption { | |||
|   border: 1px dashed #bbb; | |||
| } | |||
| .mce-visualblocks p, | |||
| .mce-visualblocks h1, | |||
| .mce-visualblocks h2, | |||
| .mce-visualblocks h3, | |||
| .mce-visualblocks h4, | |||
| .mce-visualblocks h5, | |||
| .mce-visualblocks h6, | |||
| .mce-visualblocks div:not([data-mce-bogus]), | |||
| .mce-visualblocks section, | |||
| .mce-visualblocks article, | |||
| .mce-visualblocks blockquote, | |||
| .mce-visualblocks address, | |||
| .mce-visualblocks pre, | |||
| .mce-visualblocks figure, | |||
| .mce-visualblocks figcaption, | |||
| .mce-visualblocks hgroup, | |||
| .mce-visualblocks aside, | |||
| .mce-visualblocks ul, | |||
| .mce-visualblocks ol, | |||
| .mce-visualblocks dl { | |||
|   background-repeat: no-repeat; | |||
|   border: 1px dashed #bbb; | |||
|   margin-left: 3px; | |||
|   padding-top: 10px; | |||
| } | |||
| .mce-visualblocks p { | |||
|   background-image: url(data:image/gif;base64,R0lGODlhCQAJAJEAAAAAAP///7u7u////yH5BAEAAAMALAAAAAAJAAkAAAIQnG+CqCN/mlyvsRUpThG6AgA7); | |||
| } | |||
| .mce-visualblocks h1 { | |||
|   background-image: url(data:image/gif;base64,R0lGODlhDQAKAIABALu7u////yH5BAEAAAEALAAAAAANAAoAAAIXjI8GybGu1JuxHoAfRNRW3TWXyF2YiRUAOw==); | |||
| } | |||
| .mce-visualblocks h2 { | |||
|   background-image: url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIajI8Hybbx4oOuqgTynJd6bGlWg3DkJzoaUAAAOw==); | |||
| } | |||
| .mce-visualblocks h3 { | |||
|   background-image: url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIZjI8Hybbx4oOuqgTynJf2Ln2NOHpQpmhAAQA7); | |||
| } | |||
| .mce-visualblocks h4 { | |||
|   background-image: url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIajI8HybbxInR0zqeAdhtJlXwV1oCll2HaWgAAOw==); | |||
| } | |||
| .mce-visualblocks h5 { | |||
|   background-image: url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIajI8HybbxIoiuwjane4iq5GlW05GgIkIZUAAAOw==); | |||
| } | |||
| .mce-visualblocks h6 { | |||
|   background-image: url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIajI8HybbxIoiuwjan04jep1iZ1XRlAo5bVgAAOw==); | |||
| } | |||
| .mce-visualblocks div:not([data-mce-bogus]) { | |||
|   background-image: url(data:image/gif;base64,R0lGODlhEgAKAIABALu7u////yH5BAEAAAEALAAAAAASAAoAAAIfjI9poI0cgDywrhuxfbrzDEbQM2Ei5aRjmoySW4pAAQA7); | |||
| } | |||
| .mce-visualblocks section { | |||
|   background-image: url(data:image/gif;base64,R0lGODlhKAAKAIABALu7u////yH5BAEAAAEALAAAAAAoAAoAAAI5jI+pywcNY3sBWHdNrplytD2ellDeSVbp+GmWqaDqDMepc8t17Y4vBsK5hDyJMcI6KkuYU+jpjLoKADs=); | |||
| } | |||
| .mce-visualblocks article { | |||
|   background-image: url(data:image/gif;base64,R0lGODlhKgAKAIABALu7u////yH5BAEAAAEALAAAAAAqAAoAAAI6jI+pywkNY3wG0GBvrsd2tXGYSGnfiF7ikpXemTpOiJScasYoDJJrjsG9gkCJ0ag6KhmaIe3pjDYBBQA7); | |||
| } | |||
| .mce-visualblocks blockquote { | |||
|   background-image: url(data:image/gif;base64,R0lGODlhPgAKAIABALu7u////yH5BAEAAAEALAAAAAA+AAoAAAJPjI+py+0Knpz0xQDyuUhvfoGgIX5iSKZYgq5uNL5q69asZ8s5rrf0yZmpNkJZzFesBTu8TOlDVAabUyatguVhWduud3EyiUk45xhTTgMBBQA7); | |||
| } | |||
| .mce-visualblocks address { | |||
|   background-image: url(data:image/gif;base64,R0lGODlhLQAKAIABALu7u////yH5BAEAAAEALAAAAAAtAAoAAAI/jI+pywwNozSP1gDyyZcjb3UaRpXkWaXmZW4OqKLhBmLs+K263DkJK7OJeifh7FicKD9A1/IpGdKkyFpNmCkAADs=); | |||
| } | |||
| .mce-visualblocks pre { | |||
|   background-image: url(data:image/gif;base64,R0lGODlhFQAKAIABALu7uwAAACH5BAEAAAEALAAAAAAVAAoAAAIjjI+ZoN0cgDwSmnpz1NCueYERhnibZVKLNnbOq8IvKpJtVQAAOw==); | |||
| } | |||
| .mce-visualblocks figure { | |||
|   background-image: url(data:image/gif;base64,R0lGODlhJAAKAIAAALu7u////yH5BAEAAAEALAAAAAAkAAoAAAI0jI+py+2fwAHUSFvD3RlvG4HIp4nX5JFSpnZUJ6LlrM52OE7uSWosBHScgkSZj7dDKnWAAgA7); | |||
| } | |||
| .mce-visualblocks figcaption { | |||
|   border: 1px dashed #bbb; | |||
| } | |||
| .mce-visualblocks hgroup { | |||
|   background-image: url(data:image/gif;base64,R0lGODlhJwAKAIABALu7uwAAACH5BAEAAAEALAAAAAAnAAoAAAI3jI+pywYNI3uB0gpsRtt5fFnfNZaVSYJil4Wo03Hv6Z62uOCgiXH1kZIIJ8NiIxRrAZNMZAtQAAA7); | |||
| } | |||
| .mce-visualblocks aside { | |||
|   background-image: url(data:image/gif;base64,R0lGODlhHgAKAIABAKqqqv///yH5BAEAAAEALAAAAAAeAAoAAAItjI+pG8APjZOTzgtqy7I3f1yehmQcFY4WKZbqByutmW4aHUd6vfcVbgudgpYCADs=); | |||
| } | |||
| .mce-visualblocks ul { | |||
|   background-image: url(data:image/gif;base64,R0lGODlhDQAKAIAAALu7u////yH5BAEAAAEALAAAAAANAAoAAAIXjI8GybGuYnqUVSjvw26DzzXiqIDlVwAAOw==); | |||
| } | |||
| .mce-visualblocks ol { | |||
|   background-image: url(data:image/gif;base64,R0lGODlhDQAKAIABALu7u////yH5BAEAAAEALAAAAAANAAoAAAIXjI8GybH6HHt0qourxC6CvzXieHyeWQAAOw==); | |||
| } | |||
| .mce-visualblocks dl { | |||
|   background-image: url(data:image/gif;base64,R0lGODlhDQAKAIABALu7u////yH5BAEAAAEALAAAAAANAAoAAAIXjI8GybEOnmOvUoWznTqeuEjNSCqeGRUAOw==); | |||
| } | |||
| .mce-visualblocks:not([dir=rtl]) p, | |||
| .mce-visualblocks:not([dir=rtl]) h1, | |||
| .mce-visualblocks:not([dir=rtl]) h2, | |||
| .mce-visualblocks:not([dir=rtl]) h3, | |||
| .mce-visualblocks:not([dir=rtl]) h4, | |||
| .mce-visualblocks:not([dir=rtl]) h5, | |||
| .mce-visualblocks:not([dir=rtl]) h6, | |||
| .mce-visualblocks:not([dir=rtl]) div:not([data-mce-bogus]), | |||
| .mce-visualblocks:not([dir=rtl]) section, | |||
| .mce-visualblocks:not([dir=rtl]) article, | |||
| .mce-visualblocks:not([dir=rtl]) blockquote, | |||
| .mce-visualblocks:not([dir=rtl]) address, | |||
| .mce-visualblocks:not([dir=rtl]) pre, | |||
| .mce-visualblocks:not([dir=rtl]) figure, | |||
| .mce-visualblocks:not([dir=rtl]) figcaption, | |||
| .mce-visualblocks:not([dir=rtl]) hgroup, | |||
| .mce-visualblocks:not([dir=rtl]) aside, | |||
| .mce-visualblocks:not([dir=rtl]) ul, | |||
| .mce-visualblocks:not([dir=rtl]) ol, | |||
| .mce-visualblocks:not([dir=rtl]) dl { | |||
|   margin-left: 3px; | |||
| } | |||
| .mce-visualblocks[dir=rtl] p, | |||
| .mce-visualblocks[dir=rtl] h1, | |||
| .mce-visualblocks[dir=rtl] h2, | |||
| .mce-visualblocks[dir=rtl] h3, | |||
| .mce-visualblocks[dir=rtl] h4, | |||
| .mce-visualblocks[dir=rtl] h5, | |||
| .mce-visualblocks[dir=rtl] h6, | |||
| .mce-visualblocks[dir=rtl] div:not([data-mce-bogus]), | |||
| .mce-visualblocks[dir=rtl] section, | |||
| .mce-visualblocks[dir=rtl] article, | |||
| .mce-visualblocks[dir=rtl] blockquote, | |||
| .mce-visualblocks[dir=rtl] address, | |||
| .mce-visualblocks[dir=rtl] pre, | |||
| .mce-visualblocks[dir=rtl] figure, | |||
| .mce-visualblocks[dir=rtl] figcaption, | |||
| .mce-visualblocks[dir=rtl] hgroup, | |||
| .mce-visualblocks[dir=rtl] aside, | |||
| .mce-visualblocks[dir=rtl] ul, | |||
| .mce-visualblocks[dir=rtl] ol, | |||
| .mce-visualblocks[dir=rtl] dl { | |||
|   background-position-x: right; | |||
|   margin-right: 3px; | |||
| } | |||
| .mce-nbsp, | |||
| .mce-shy { | |||
|   background: #aaa; | |||
| } | |||
| .mce-shy::after { | |||
|   content: '-'; | |||
| } | |||
| body { | |||
|   font-family: sans-serif; | |||
| } | |||
| table { | |||
|   border-collapse: collapse; | |||
| } | |||
| @ -1,726 +0,0 @@ | |||
| /** | |||
|  * 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/ | |||
|  */ | |||
| .mce-content-body .mce-item-anchor { | |||
|   background: transparent url("data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D'8'%20height%3D'12'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%3E%3Cpath%20d%3D'M0%200L8%200%208%2012%204.09117821%209%200%2012z'%2F%3E%3C%2Fsvg%3E%0A") no-repeat center; | |||
|   cursor: default; | |||
|   display: inline-block; | |||
|   height: 12px !important; | |||
|   padding: 0 2px; | |||
|   -webkit-user-modify: read-only; | |||
|   -moz-user-modify: read-only; | |||
|   -webkit-user-select: all; | |||
|   -moz-user-select: all; | |||
|   -ms-user-select: all; | |||
|       user-select: all; | |||
|   width: 8px !important; | |||
| } | |||
| .mce-content-body .mce-item-anchor[data-mce-selected] { | |||
|   outline-offset: 1px; | |||
| } | |||
| .tox-comments-visible .tox-comment { | |||
|   background-color: #fff0b7; | |||
| } | |||
| .tox-comments-visible .tox-comment--active { | |||
|   background-color: #ffe168; | |||
| } | |||
| .tox-checklist > li:not(.tox-checklist--hidden) { | |||
|   list-style: none; | |||
|   margin: 0.25em 0; | |||
| } | |||
| .tox-checklist > li:not(.tox-checklist--hidden)::before { | |||
|   content: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2216%22%20height%3D%2216%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cg%20id%3D%22checklist-unchecked%22%20fill%3D%22none%22%20fill-rule%3D%22evenodd%22%3E%3Crect%20id%3D%22Rectangle%22%20width%3D%2215%22%20height%3D%2215%22%20x%3D%22.5%22%20y%3D%22.5%22%20fill-rule%3D%22nonzero%22%20stroke%3D%22%234C4C4C%22%20rx%3D%222%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E%0A"); | |||
|   cursor: pointer; | |||
|   height: 1em; | |||
|   margin-left: -1.5em; | |||
|   margin-top: 0.125em; | |||
|   position: absolute; | |||
|   width: 1em; | |||
| } | |||
| .tox-checklist li:not(.tox-checklist--hidden).tox-checklist--checked::before { | |||
|   content: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2216%22%20height%3D%2216%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cg%20id%3D%22checklist-checked%22%20fill%3D%22none%22%20fill-rule%3D%22evenodd%22%3E%3Crect%20id%3D%22Rectangle%22%20width%3D%2216%22%20height%3D%2216%22%20fill%3D%22%234099FF%22%20fill-rule%3D%22nonzero%22%20rx%3D%222%22%2F%3E%3Cpath%20id%3D%22Path%22%20fill%3D%22%23FFF%22%20fill-rule%3D%22nonzero%22%20d%3D%22M11.5703186%2C3.14417309%20C11.8516238%2C2.73724603%2012.4164781%2C2.62829933%2012.83558%2C2.89774797%20C13.260121%2C3.17069355%2013.3759736%2C3.72932262%2013.0909105%2C4.14168582%20L7.7580587%2C11.8560195%20C7.43776896%2C12.3193404%206.76483983%2C12.3852142%206.35607322%2C11.9948725%20L3.02491697%2C8.8138662%20C2.66090143%2C8.46625845%202.65798871%2C7.89594698%203.01850234%2C7.54483354%20C3.373942%2C7.19866177%203.94940006%2C7.19592841%204.30829608%2C7.5386474%20L6.85276923%2C9.9684299%20L11.5703186%2C3.14417309%20Z%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E%0A"); | |||
| } | |||
| [dir=rtl] .tox-checklist > li:not(.tox-checklist--hidden)::before { | |||
|   margin-left: 0; | |||
|   margin-right: -1.5em; | |||
| } | |||
| /* stylelint-disable */ | |||
| /* http://prismjs.com/ */ | |||
| /** | |||
|  * prism.js default theme for JavaScript, CSS and HTML | |||
|  * Based on dabblet (http://dabblet.com) | |||
|  * @author Lea Verou | |||
|  */ | |||
| code[class*="language-"], | |||
| pre[class*="language-"] { | |||
|   color: black; | |||
|   background: none; | |||
|   text-shadow: 0 1px white; | |||
|   font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; | |||
|   font-size: 1em; | |||
|   text-align: left; | |||
|   white-space: pre; | |||
|   word-spacing: normal; | |||
|   word-break: normal; | |||
|   word-wrap: normal; | |||
|   line-height: 1.5; | |||
|   -moz-tab-size: 4; | |||
|   tab-size: 4; | |||
|   -webkit-hyphens: none; | |||
|   -ms-hyphens: none; | |||
|   hyphens: none; | |||
| } | |||
| pre[class*="language-"]::-moz-selection, | |||
| pre[class*="language-"] ::-moz-selection, | |||
| code[class*="language-"]::-moz-selection, | |||
| code[class*="language-"] ::-moz-selection { | |||
|   text-shadow: none; | |||
|   background: #b3d4fc; | |||
| } | |||
| pre[class*="language-"]::selection, | |||
| pre[class*="language-"] ::selection, | |||
| code[class*="language-"]::selection, | |||
| code[class*="language-"] ::selection { | |||
|   text-shadow: none; | |||
|   background: #b3d4fc; | |||
| } | |||
| @media print { | |||
|   code[class*="language-"], | |||
|   pre[class*="language-"] { | |||
|     text-shadow: none; | |||
|   } | |||
| } | |||
| /* Code blocks */ | |||
| pre[class*="language-"] { | |||
|   padding: 1em; | |||
|   margin: 0.5em 0; | |||
|   overflow: auto; | |||
| } | |||
| :not(pre) > code[class*="language-"], | |||
| pre[class*="language-"] { | |||
|   background: #f5f2f0; | |||
| } | |||
| /* Inline code */ | |||
| :not(pre) > code[class*="language-"] { | |||
|   padding: 0.1em; | |||
|   border-radius: 0.3em; | |||
|   white-space: normal; | |||
| } | |||
| .token.comment, | |||
| .token.prolog, | |||
| .token.doctype, | |||
| .token.cdata { | |||
|   color: slategray; | |||
| } | |||
| .token.punctuation { | |||
|   color: #999; | |||
| } | |||
| .namespace { | |||
|   opacity: 0.7; | |||
| } | |||
| .token.property, | |||
| .token.tag, | |||
| .token.boolean, | |||
| .token.number, | |||
| .token.constant, | |||
| .token.symbol, | |||
| .token.deleted { | |||
|   color: #905; | |||
| } | |||
| .token.selector, | |||
| .token.attr-name, | |||
| .token.string, | |||
| .token.char, | |||
| .token.builtin, | |||
| .token.inserted { | |||
|   color: #690; | |||
| } | |||
| .token.operator, | |||
| .token.entity, | |||
| .token.url, | |||
| .language-css .token.string, | |||
| .style .token.string { | |||
|   color: #9a6e3a; | |||
|   background: hsla(0, 0%, 100%, 0.5); | |||
| } | |||
| .token.atrule, | |||
| .token.attr-value, | |||
| .token.keyword { | |||
|   color: #07a; | |||
| } | |||
| .token.function, | |||
| .token.class-name { | |||
|   color: #DD4A68; | |||
| } | |||
| .token.regex, | |||
| .token.important, | |||
| .token.variable { | |||
|   color: #e90; | |||
| } | |||
| .token.important, | |||
| .token.bold { | |||
|   font-weight: bold; | |||
| } | |||
| .token.italic { | |||
|   font-style: italic; | |||
| } | |||
| .token.entity { | |||
|   cursor: help; | |||
| } | |||
| /* stylelint-enable */ | |||
| .mce-content-body { | |||
|   overflow-wrap: break-word; | |||
|   word-wrap: break-word; | |||
| } | |||
| .mce-content-body .mce-visual-caret { | |||
|   background-color: black; | |||
|   background-color: currentColor; | |||
|   position: absolute; | |||
| } | |||
| .mce-content-body .mce-visual-caret-hidden { | |||
|   display: none; | |||
| } | |||
| .mce-content-body *[data-mce-caret] { | |||
|   left: -1000px; | |||
|   margin: 0; | |||
|   padding: 0; | |||
|   position: absolute; | |||
|   right: auto; | |||
|   top: 0; | |||
| } | |||
| .mce-content-body .mce-offscreen-selection { | |||
|   left: -2000000px; | |||
|   max-width: 1000000px; | |||
|   position: absolute; | |||
| } | |||
| .mce-content-body *[contentEditable=false] { | |||
|   cursor: default; | |||
| } | |||
| .mce-content-body *[contentEditable=true] { | |||
|   cursor: text; | |||
| } | |||
| .tox-cursor-format-painter { | |||
|   cursor: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%3E%0A%20%20%3Cg%20fill%3D%22none%22%20fill-rule%3D%22evenodd%22%3E%0A%20%20%20%20%3Cpath%20fill%3D%22%23000%22%20fill-rule%3D%22nonzero%22%20d%3D%22M15%2C6%20C15%2C5.45%2014.55%2C5%2014%2C5%20L6%2C5%20C5.45%2C5%205%2C5.45%205%2C6%20L5%2C10%20C5%2C10.55%205.45%2C11%206%2C11%20L14%2C11%20C14.55%2C11%2015%2C10.55%2015%2C10%20L15%2C9%20L16%2C9%20L16%2C12%20L9%2C12%20L9%2C19%20C9%2C19.55%209.45%2C20%2010%2C20%20L11%2C20%20C11.55%2C20%2012%2C19.55%2012%2C19%20L12%2C14%20L18%2C14%20L18%2C7%20L15%2C7%20L15%2C6%20Z%22%2F%3E%0A%20%20%20%20%3Cpath%20fill%3D%22%23000%22%20fill-rule%3D%22nonzero%22%20d%3D%22M1%2C1%20L8.25%2C1%20C8.66421356%2C1%209%2C1.33578644%209%2C1.75%20L9%2C1.75%20C9%2C2.16421356%208.66421356%2C2.5%208.25%2C2.5%20L2.5%2C2.5%20L2.5%2C8.25%20C2.5%2C8.66421356%202.16421356%2C9%201.75%2C9%20L1.75%2C9%20C1.33578644%2C9%201%2C8.66421356%201%2C8.25%20L1%2C1%20Z%22%2F%3E%0A%20%20%3C%2Fg%3E%0A%3C%2Fsvg%3E%0A"), default; | |||
| } | |||
| .mce-content-body figure.align-left { | |||
|   float: left; | |||
| } | |||
| .mce-content-body figure.align-right { | |||
|   float: right; | |||
| } | |||
| .mce-content-body figure.image.align-center { | |||
|   display: table; | |||
|   margin-left: auto; | |||
|   margin-right: auto; | |||
| } | |||
| .mce-preview-object { | |||
|   border: 1px solid gray; | |||
|   display: inline-block; | |||
|   line-height: 0; | |||
|   margin: 0 2px 0 2px; | |||
|   position: relative; | |||
| } | |||
| .mce-preview-object .mce-shim { | |||
|   background: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7); | |||
|   height: 100%; | |||
|   left: 0; | |||
|   position: absolute; | |||
|   top: 0; | |||
|   width: 100%; | |||
| } | |||
| .mce-preview-object[data-mce-selected="2"] .mce-shim { | |||
|   display: none; | |||
| } | |||
| .mce-object { | |||
|   background: transparent url("data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%3E%3Cpath%20d%3D%22M4%203h16a1%201%200%200%201%201%201v16a1%201%200%200%201-1%201H4a1%201%200%200%201-1-1V4a1%201%200%200%201%201-1zm1%202v14h14V5H5zm4.79%202.565l5.64%204.028a.5.5%200%200%201%200%20.814l-5.64%204.028a.5.5%200%200%201-.79-.407V7.972a.5.5%200%200%201%20.79-.407z%22%2F%3E%3C%2Fsvg%3E%0A") no-repeat center; | |||
|   border: 1px dashed #aaa; | |||
| } | |||
| .mce-pagebreak { | |||
|   border: 1px dashed #aaa; | |||
|   cursor: default; | |||
|   display: block; | |||
|   height: 5px; | |||
|   margin-top: 15px; | |||
|   page-break-before: always; | |||
|   width: 100%; | |||
| } | |||
| @media print { | |||
|   .mce-pagebreak { | |||
|     border: 0; | |||
|   } | |||
| } | |||
| .tiny-pageembed .mce-shim { | |||
|   background: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7); | |||
|   height: 100%; | |||
|   left: 0; | |||
|   position: absolute; | |||
|   top: 0; | |||
|   width: 100%; | |||
| } | |||
| .tiny-pageembed[data-mce-selected="2"] .mce-shim { | |||
|   display: none; | |||
| } | |||
| .tiny-pageembed { | |||
|   display: inline-block; | |||
|   position: relative; | |||
| } | |||
| .tiny-pageembed--21by9, | |||
| .tiny-pageembed--16by9, | |||
| .tiny-pageembed--4by3, | |||
| .tiny-pageembed--1by1 { | |||
|   display: block; | |||
|   overflow: hidden; | |||
|   padding: 0; | |||
|   position: relative; | |||
|   width: 100%; | |||
| } | |||
| .tiny-pageembed--21by9 { | |||
|   padding-top: 42.857143%; | |||
| } | |||
| .tiny-pageembed--16by9 { | |||
|   padding-top: 56.25%; | |||
| } | |||
| .tiny-pageembed--4by3 { | |||
|   padding-top: 75%; | |||
| } | |||
| .tiny-pageembed--1by1 { | |||
|   padding-top: 100%; | |||
| } | |||
| .tiny-pageembed--21by9 iframe, | |||
| .tiny-pageembed--16by9 iframe, | |||
| .tiny-pageembed--4by3 iframe, | |||
| .tiny-pageembed--1by1 iframe { | |||
|   border: 0; | |||
|   height: 100%; | |||
|   left: 0; | |||
|   position: absolute; | |||
|   top: 0; | |||
|   width: 100%; | |||
| } | |||
| .mce-content-body[data-mce-placeholder] { | |||
|   position: relative; | |||
| } | |||
| .mce-content-body[data-mce-placeholder]:not(.mce-visualblocks)::before { | |||
|   color: rgba(34, 47, 62, 0.7); | |||
|   content: attr(data-mce-placeholder); | |||
|   position: absolute; | |||
| } | |||
| .mce-content-body:not([dir=rtl])[data-mce-placeholder]:not(.mce-visualblocks)::before { | |||
|   left: 1px; | |||
| } | |||
| .mce-content-body[dir=rtl][data-mce-placeholder]:not(.mce-visualblocks)::before { | |||
|   right: 1px; | |||
| } | |||
| .mce-content-body div.mce-resizehandle { | |||
|   background-color: #4099ff; | |||
|   border-color: #4099ff; | |||
|   border-style: solid; | |||
|   border-width: 1px; | |||
|   box-sizing: border-box; | |||
|   height: 10px; | |||
|   position: absolute; | |||
|   width: 10px; | |||
|   z-index: 10000; | |||
| } | |||
| .mce-content-body div.mce-resizehandle:hover { | |||
|   background-color: #4099ff; | |||
| } | |||
| .mce-content-body div.mce-resizehandle:nth-of-type(1) { | |||
|   cursor: nwse-resize; | |||
| } | |||
| .mce-content-body div.mce-resizehandle:nth-of-type(2) { | |||
|   cursor: nesw-resize; | |||
| } | |||
| .mce-content-body div.mce-resizehandle:nth-of-type(3) { | |||
|   cursor: nwse-resize; | |||
| } | |||
| .mce-content-body div.mce-resizehandle:nth-of-type(4) { | |||
|   cursor: nesw-resize; | |||
| } | |||
| .mce-content-body .mce-resize-backdrop { | |||
|   z-index: 10000; | |||
| } | |||
| .mce-content-body .mce-clonedresizable { | |||
|   cursor: default; | |||
|   opacity: 0.5; | |||
|   outline: 1px dashed black; | |||
|   position: absolute; | |||
|   z-index: 10001; | |||
| } | |||
| .mce-content-body .mce-clonedresizable.mce-resizetable-columns th, | |||
| .mce-content-body .mce-clonedresizable.mce-resizetable-columns td { | |||
|   border: 0; | |||
| } | |||
| .mce-content-body .mce-resize-helper { | |||
|   background: #555; | |||
|   background: rgba(0, 0, 0, 0.75); | |||
|   border: 1px; | |||
|   border-radius: 3px; | |||
|   color: white; | |||
|   display: none; | |||
|   font-family: sans-serif; | |||
|   font-size: 12px; | |||
|   line-height: 14px; | |||
|   margin: 5px 10px; | |||
|   padding: 5px; | |||
|   position: absolute; | |||
|   white-space: nowrap; | |||
|   z-index: 10002; | |||
| } | |||
| .tox-rtc-user-selection { | |||
|   position: relative; | |||
| } | |||
| .tox-rtc-user-cursor { | |||
|   bottom: 0; | |||
|   cursor: default; | |||
|   position: absolute; | |||
|   top: 0; | |||
|   width: 2px; | |||
| } | |||
| .tox-rtc-user-cursor::before { | |||
|   background-color: inherit; | |||
|   border-radius: 50%; | |||
|   content: ''; | |||
|   display: block; | |||
|   height: 8px; | |||
|   position: absolute; | |||
|   right: -3px; | |||
|   top: -3px; | |||
|   width: 8px; | |||
| } | |||
| .tox-rtc-user-cursor:hover::after { | |||
|   background-color: inherit; | |||
|   border-radius: 100px; | |||
|   box-sizing: border-box; | |||
|   color: #fff; | |||
|   content: attr(data-user); | |||
|   display: block; | |||
|   font-size: 12px; | |||
|   font-weight: bold; | |||
|   left: -5px; | |||
|   min-height: 8px; | |||
|   min-width: 8px; | |||
|   padding: 0 12px; | |||
|   position: absolute; | |||
|   top: -11px; | |||
|   white-space: nowrap; | |||
|   z-index: 1000; | |||
| } | |||
| .tox-rtc-user-selection--1 .tox-rtc-user-cursor { | |||
|   background-color: #2dc26b; | |||
| } | |||
| .tox-rtc-user-selection--2 .tox-rtc-user-cursor { | |||
|   background-color: #e03e2d; | |||
| } | |||
| .tox-rtc-user-selection--3 .tox-rtc-user-cursor { | |||
|   background-color: #f1c40f; | |||
| } | |||
| .tox-rtc-user-selection--4 .tox-rtc-user-cursor { | |||
|   background-color: #3598db; | |||
| } | |||
| .tox-rtc-user-selection--5 .tox-rtc-user-cursor { | |||
|   background-color: #b96ad9; | |||
| } | |||
| .tox-rtc-user-selection--6 .tox-rtc-user-cursor { | |||
|   background-color: #e67e23; | |||
| } | |||
| .tox-rtc-user-selection--7 .tox-rtc-user-cursor { | |||
|   background-color: #aaa69d; | |||
| } | |||
| .tox-rtc-user-selection--8 .tox-rtc-user-cursor { | |||
|   background-color: #f368e0; | |||
| } | |||
| .tox-rtc-remote-image { | |||
|   background: #eaeaea url("data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%2236%22%20height%3D%2212%22%20viewBox%3D%220%200%2036%2012%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%20%20%3Ccircle%20cx%3D%226%22%20cy%3D%226%22%20r%3D%223%22%20fill%3D%22rgba(0%2C%200%2C%200%2C%20.2)%22%3E%0A%20%20%20%20%3Canimate%20attributeName%3D%22r%22%20values%3D%223%3B5%3B3%22%20calcMode%3D%22linear%22%20dur%3D%221s%22%20repeatCount%3D%22indefinite%22%20%2F%3E%0A%20%20%3C%2Fcircle%3E%0A%20%20%3Ccircle%20cx%3D%2218%22%20cy%3D%226%22%20r%3D%223%22%20fill%3D%22rgba(0%2C%200%2C%200%2C%20.2)%22%3E%0A%20%20%20%20%3Canimate%20attributeName%3D%22r%22%20values%3D%223%3B5%3B3%22%20calcMode%3D%22linear%22%20begin%3D%22.33s%22%20dur%3D%221s%22%20repeatCount%3D%22indefinite%22%20%2F%3E%0A%20%20%3C%2Fcircle%3E%0A%20%20%3Ccircle%20cx%3D%2230%22%20cy%3D%226%22%20r%3D%223%22%20fill%3D%22rgba(0%2C%200%2C%200%2C%20.2)%22%3E%0A%20%20%20%20%3Canimate%20attributeName%3D%22r%22%20values%3D%223%3B5%3B3%22%20calcMode%3D%22linear%22%20begin%3D%22.66s%22%20dur%3D%221s%22%20repeatCount%3D%22indefinite%22%20%2F%3E%0A%20%20%3C%2Fcircle%3E%0A%3C%2Fsvg%3E%0A") no-repeat center center; | |||
|   border: 1px solid #ccc; | |||
|   min-height: 240px; | |||
|   min-width: 320px; | |||
| } | |||
| .mce-match-marker { | |||
|   background: #aaa; | |||
|   color: #fff; | |||
| } | |||
| .mce-match-marker-selected { | |||
|   background: #39f; | |||
|   color: #fff; | |||
| } | |||
| .mce-match-marker-selected::-moz-selection { | |||
|   background: #39f; | |||
|   color: #fff; | |||
| } | |||
| .mce-match-marker-selected::selection { | |||
|   background: #39f; | |||
|   color: #fff; | |||
| } | |||
| .mce-content-body img[data-mce-selected], | |||
| .mce-content-body video[data-mce-selected], | |||
| .mce-content-body audio[data-mce-selected], | |||
| .mce-content-body object[data-mce-selected], | |||
| .mce-content-body embed[data-mce-selected], | |||
| .mce-content-body table[data-mce-selected] { | |||
|   outline: 3px solid #b4d7ff; | |||
| } | |||
| .mce-content-body hr[data-mce-selected] { | |||
|   outline: 3px solid #b4d7ff; | |||
|   outline-offset: 1px; | |||
| } | |||
| .mce-content-body *[contentEditable=false] *[contentEditable=true]:focus { | |||
|   outline: 3px solid #b4d7ff; | |||
| } | |||
| .mce-content-body *[contentEditable=false] *[contentEditable=true]:hover { | |||
|   outline: 3px solid #b4d7ff; | |||
| } | |||
| .mce-content-body *[contentEditable=false][data-mce-selected] { | |||
|   cursor: not-allowed; | |||
|   outline: 3px solid #b4d7ff; | |||
| } | |||
| .mce-content-body.mce-content-readonly *[contentEditable=true]:focus, | |||
| .mce-content-body.mce-content-readonly *[contentEditable=true]:hover { | |||
|   outline: none; | |||
| } | |||
| .mce-content-body *[data-mce-selected="inline-boundary"] { | |||
|   background-color: #b4d7ff; | |||
| } | |||
| .mce-content-body .mce-edit-focus { | |||
|   outline: 3px solid #b4d7ff; | |||
| } | |||
| .mce-content-body td[data-mce-selected], | |||
| .mce-content-body th[data-mce-selected] { | |||
|   position: relative; | |||
| } | |||
| .mce-content-body td[data-mce-selected]::-moz-selection, | |||
| .mce-content-body th[data-mce-selected]::-moz-selection { | |||
|   background: none; | |||
| } | |||
| .mce-content-body td[data-mce-selected]::selection, | |||
| .mce-content-body th[data-mce-selected]::selection { | |||
|   background: none; | |||
| } | |||
| .mce-content-body td[data-mce-selected] *, | |||
| .mce-content-body th[data-mce-selected] * { | |||
|   outline: none; | |||
|   -webkit-touch-callout: none; | |||
|   -webkit-user-select: none; | |||
|      -moz-user-select: none; | |||
|       -ms-user-select: none; | |||
|           user-select: none; | |||
| } | |||
| .mce-content-body td[data-mce-selected]::after, | |||
| .mce-content-body th[data-mce-selected]::after { | |||
|   background-color: rgba(180, 215, 255, 0.7); | |||
|   border: 1px solid rgba(180, 215, 255, 0.7); | |||
|   bottom: -1px; | |||
|   content: ''; | |||
|   left: -1px; | |||
|   mix-blend-mode: multiply; | |||
|   position: absolute; | |||
|   right: -1px; | |||
|   top: -1px; | |||
| } | |||
| @media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) { | |||
|   .mce-content-body td[data-mce-selected]::after, | |||
|   .mce-content-body th[data-mce-selected]::after { | |||
|     border-color: rgba(0, 84, 180, 0.7); | |||
|   } | |||
| } | |||
| .mce-content-body img::-moz-selection { | |||
|   background: none; | |||
| } | |||
| .mce-content-body img::selection { | |||
|   background: none; | |||
| } | |||
| .ephox-snooker-resizer-bar { | |||
|   background-color: #b4d7ff; | |||
|   opacity: 0; | |||
|   -webkit-user-select: none; | |||
|   -moz-user-select: none; | |||
|   -ms-user-select: none; | |||
|   user-select: none; | |||
| } | |||
| .ephox-snooker-resizer-cols { | |||
|   cursor: col-resize; | |||
| } | |||
| .ephox-snooker-resizer-rows { | |||
|   cursor: row-resize; | |||
| } | |||
| .ephox-snooker-resizer-bar.ephox-snooker-resizer-bar-dragging { | |||
|   opacity: 1; | |||
| } | |||
| .mce-spellchecker-word { | |||
|   background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D'4'%20height%3D'4'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%3E%3Cpath%20stroke%3D'%23ff0000'%20fill%3D'none'%20stroke-linecap%3D'round'%20stroke-opacity%3D'.75'%20d%3D'M0%203L2%201%204%203'%2F%3E%3C%2Fsvg%3E%0A"); | |||
|   background-position: 0 calc(100% + 1px); | |||
|   background-repeat: repeat-x; | |||
|   background-size: auto 6px; | |||
|   cursor: default; | |||
|   height: 2rem; | |||
| } | |||
| .mce-spellchecker-grammar { | |||
|   background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D'4'%20height%3D'4'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%3E%3Cpath%20stroke%3D'%2300A835'%20fill%3D'none'%20stroke-linecap%3D'round'%20d%3D'M0%203L2%201%204%203'%2F%3E%3C%2Fsvg%3E%0A"); | |||
|   background-position: 0 calc(100% + 1px); | |||
|   background-repeat: repeat-x; | |||
|   background-size: auto 6px; | |||
|   cursor: default; | |||
| } | |||
| .mce-toc { | |||
|   border: 1px solid gray; | |||
| } | |||
| .mce-toc h2 { | |||
|   margin: 4px; | |||
| } | |||
| .mce-toc li { | |||
|   list-style-type: none; | |||
| } | |||
| table[style*="border-width: 0px"], | |||
| .mce-item-table:not([border]), | |||
| .mce-item-table[border="0"], | |||
| table[style*="border-width: 0px"] td, | |||
| .mce-item-table:not([border]) td, | |||
| .mce-item-table[border="0"] td, | |||
| table[style*="border-width: 0px"] th, | |||
| .mce-item-table:not([border]) th, | |||
| .mce-item-table[border="0"] th, | |||
| table[style*="border-width: 0px"] caption, | |||
| .mce-item-table:not([border]) caption, | |||
| .mce-item-table[border="0"] caption { | |||
|   border: 1px dashed #bbb; | |||
| } | |||
| .mce-visualblocks p, | |||
| .mce-visualblocks h1, | |||
| .mce-visualblocks h2, | |||
| .mce-visualblocks h3, | |||
| .mce-visualblocks h4, | |||
| .mce-visualblocks h5, | |||
| .mce-visualblocks h6, | |||
| .mce-visualblocks div:not([data-mce-bogus]), | |||
| .mce-visualblocks section, | |||
| .mce-visualblocks article, | |||
| .mce-visualblocks blockquote, | |||
| .mce-visualblocks address, | |||
| .mce-visualblocks pre, | |||
| .mce-visualblocks figure, | |||
| .mce-visualblocks figcaption, | |||
| .mce-visualblocks hgroup, | |||
| .mce-visualblocks aside, | |||
| .mce-visualblocks ul, | |||
| .mce-visualblocks ol, | |||
| .mce-visualblocks dl { | |||
|   background-repeat: no-repeat; | |||
|   border: 1px dashed #bbb; | |||
|   margin-left: 3px; | |||
|   padding-top: 10px; | |||
| } | |||
| .mce-visualblocks p { | |||
|   background-image: url(data:image/gif;base64,R0lGODlhCQAJAJEAAAAAAP///7u7u////yH5BAEAAAMALAAAAAAJAAkAAAIQnG+CqCN/mlyvsRUpThG6AgA7); | |||
| } | |||
| .mce-visualblocks h1 { | |||
|   background-image: url(data:image/gif;base64,R0lGODlhDQAKAIABALu7u////yH5BAEAAAEALAAAAAANAAoAAAIXjI8GybGu1JuxHoAfRNRW3TWXyF2YiRUAOw==); | |||
| } | |||
| .mce-visualblocks h2 { | |||
|   background-image: url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIajI8Hybbx4oOuqgTynJd6bGlWg3DkJzoaUAAAOw==); | |||
| } | |||
| .mce-visualblocks h3 { | |||
|   background-image: url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIZjI8Hybbx4oOuqgTynJf2Ln2NOHpQpmhAAQA7); | |||
| } | |||
| .mce-visualblocks h4 { | |||
|   background-image: url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIajI8HybbxInR0zqeAdhtJlXwV1oCll2HaWgAAOw==); | |||
| } | |||
| .mce-visualblocks h5 { | |||
|   background-image: url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIajI8HybbxIoiuwjane4iq5GlW05GgIkIZUAAAOw==); | |||
| } | |||
| .mce-visualblocks h6 { | |||
|   background-image: url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIajI8HybbxIoiuwjan04jep1iZ1XRlAo5bVgAAOw==); | |||
| } | |||
| .mce-visualblocks div:not([data-mce-bogus]) { | |||
|   background-image: url(data:image/gif;base64,R0lGODlhEgAKAIABALu7u////yH5BAEAAAEALAAAAAASAAoAAAIfjI9poI0cgDywrhuxfbrzDEbQM2Ei5aRjmoySW4pAAQA7); | |||
| } | |||
| .mce-visualblocks section { | |||
|   background-image: url(data:image/gif;base64,R0lGODlhKAAKAIABALu7u////yH5BAEAAAEALAAAAAAoAAoAAAI5jI+pywcNY3sBWHdNrplytD2ellDeSVbp+GmWqaDqDMepc8t17Y4vBsK5hDyJMcI6KkuYU+jpjLoKADs=); | |||
| } | |||
| .mce-visualblocks article { | |||
|   background-image: url(data:image/gif;base64,R0lGODlhKgAKAIABALu7u////yH5BAEAAAEALAAAAAAqAAoAAAI6jI+pywkNY3wG0GBvrsd2tXGYSGnfiF7ikpXemTpOiJScasYoDJJrjsG9gkCJ0ag6KhmaIe3pjDYBBQA7); | |||
| } | |||
| .mce-visualblocks blockquote { | |||
|   background-image: url(data:image/gif;base64,R0lGODlhPgAKAIABALu7u////yH5BAEAAAEALAAAAAA+AAoAAAJPjI+py+0Knpz0xQDyuUhvfoGgIX5iSKZYgq5uNL5q69asZ8s5rrf0yZmpNkJZzFesBTu8TOlDVAabUyatguVhWduud3EyiUk45xhTTgMBBQA7); | |||
| } | |||
| .mce-visualblocks address { | |||
|   background-image: url(data:image/gif;base64,R0lGODlhLQAKAIABALu7u////yH5BAEAAAEALAAAAAAtAAoAAAI/jI+pywwNozSP1gDyyZcjb3UaRpXkWaXmZW4OqKLhBmLs+K263DkJK7OJeifh7FicKD9A1/IpGdKkyFpNmCkAADs=); | |||
| } | |||
| .mce-visualblocks pre { | |||
|   background-image: url(data:image/gif;base64,R0lGODlhFQAKAIABALu7uwAAACH5BAEAAAEALAAAAAAVAAoAAAIjjI+ZoN0cgDwSmnpz1NCueYERhnibZVKLNnbOq8IvKpJtVQAAOw==); | |||
| } | |||
| .mce-visualblocks figure { | |||
|   background-image: url(data:image/gif;base64,R0lGODlhJAAKAIAAALu7u////yH5BAEAAAEALAAAAAAkAAoAAAI0jI+py+2fwAHUSFvD3RlvG4HIp4nX5JFSpnZUJ6LlrM52OE7uSWosBHScgkSZj7dDKnWAAgA7); | |||
| } | |||
| .mce-visualblocks figcaption { | |||
|   border: 1px dashed #bbb; | |||
| } | |||
| .mce-visualblocks hgroup { | |||
|   background-image: url(data:image/gif;base64,R0lGODlhJwAKAIABALu7uwAAACH5BAEAAAEALAAAAAAnAAoAAAI3jI+pywYNI3uB0gpsRtt5fFnfNZaVSYJil4Wo03Hv6Z62uOCgiXH1kZIIJ8NiIxRrAZNMZAtQAAA7); | |||
| } | |||
| .mce-visualblocks aside { | |||
|   background-image: url(data:image/gif;base64,R0lGODlhHgAKAIABAKqqqv///yH5BAEAAAEALAAAAAAeAAoAAAItjI+pG8APjZOTzgtqy7I3f1yehmQcFY4WKZbqByutmW4aHUd6vfcVbgudgpYCADs=); | |||
| } | |||
| .mce-visualblocks ul { | |||
|   background-image: url(data:image/gif;base64,R0lGODlhDQAKAIAAALu7u////yH5BAEAAAEALAAAAAANAAoAAAIXjI8GybGuYnqUVSjvw26DzzXiqIDlVwAAOw==); | |||
| } | |||
| .mce-visualblocks ol { | |||
|   background-image: url(data:image/gif;base64,R0lGODlhDQAKAIABALu7u////yH5BAEAAAEALAAAAAANAAoAAAIXjI8GybH6HHt0qourxC6CvzXieHyeWQAAOw==); | |||
| } | |||
| .mce-visualblocks dl { | |||
|   background-image: url(data:image/gif;base64,R0lGODlhDQAKAIABALu7u////yH5BAEAAAEALAAAAAANAAoAAAIXjI8GybEOnmOvUoWznTqeuEjNSCqeGRUAOw==); | |||
| } | |||
| .mce-visualblocks:not([dir=rtl]) p, | |||
| .mce-visualblocks:not([dir=rtl]) h1, | |||
| .mce-visualblocks:not([dir=rtl]) h2, | |||
| .mce-visualblocks:not([dir=rtl]) h3, | |||
| .mce-visualblocks:not([dir=rtl]) h4, | |||
| .mce-visualblocks:not([dir=rtl]) h5, | |||
| .mce-visualblocks:not([dir=rtl]) h6, | |||
| .mce-visualblocks:not([dir=rtl]) div:not([data-mce-bogus]), | |||
| .mce-visualblocks:not([dir=rtl]) section, | |||
| .mce-visualblocks:not([dir=rtl]) article, | |||
| .mce-visualblocks:not([dir=rtl]) blockquote, | |||
| .mce-visualblocks:not([dir=rtl]) address, | |||
| .mce-visualblocks:not([dir=rtl]) pre, | |||
| .mce-visualblocks:not([dir=rtl]) figure, | |||
| .mce-visualblocks:not([dir=rtl]) figcaption, | |||
| .mce-visualblocks:not([dir=rtl]) hgroup, | |||
| .mce-visualblocks:not([dir=rtl]) aside, | |||
| .mce-visualblocks:not([dir=rtl]) ul, | |||
| .mce-visualblocks:not([dir=rtl]) ol, | |||
| .mce-visualblocks:not([dir=rtl]) dl { | |||
|   margin-left: 3px; | |||
| } | |||
| .mce-visualblocks[dir=rtl] p, | |||
| .mce-visualblocks[dir=rtl] h1, | |||
| .mce-visualblocks[dir=rtl] h2, | |||
| .mce-visualblocks[dir=rtl] h3, | |||
| .mce-visualblocks[dir=rtl] h4, | |||
| .mce-visualblocks[dir=rtl] h5, | |||
| .mce-visualblocks[dir=rtl] h6, | |||
| .mce-visualblocks[dir=rtl] div:not([data-mce-bogus]), | |||
| .mce-visualblocks[dir=rtl] section, | |||
| .mce-visualblocks[dir=rtl] article, | |||
| .mce-visualblocks[dir=rtl] blockquote, | |||
| .mce-visualblocks[dir=rtl] address, | |||
| .mce-visualblocks[dir=rtl] pre, | |||
| .mce-visualblocks[dir=rtl] figure, | |||
| .mce-visualblocks[dir=rtl] figcaption, | |||
| .mce-visualblocks[dir=rtl] hgroup, | |||
| .mce-visualblocks[dir=rtl] aside, | |||
| .mce-visualblocks[dir=rtl] ul, | |||
| .mce-visualblocks[dir=rtl] ol, | |||
| .mce-visualblocks[dir=rtl] dl { | |||
|   background-position-x: right; | |||
|   margin-right: 3px; | |||
| } | |||
| .mce-nbsp, | |||
| .mce-shy { | |||
|   background: #aaa; | |||
| } | |||
| .mce-shy::after { | |||
|   content: '-'; | |||
| } | |||
								
									
										File diff suppressed because one or more lines are too long
									
								
							
						
					
								
									
										File diff suppressed because one or more lines are too long
									
								
							
						
					| @ -1,29 +0,0 @@ | |||
| /** | |||
|  * 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/ | |||
|  */ | |||
| .tinymce-mobile-unfocused-selections .tinymce-mobile-unfocused-selection { | |||
|   /* Note: this file is used inside the content, so isn't part of theming */ | |||
|   background-color: green; | |||
|   display: inline-block; | |||
|   opacity: 0.5; | |||
|   position: absolute; | |||
| } | |||
| body { | |||
|   -webkit-text-size-adjust: none; | |||
| } | |||
| body img { | |||
|   /* this is related to the content margin */ | |||
|   max-width: 96vw; | |||
| } | |||
| body table img { | |||
|   max-width: 95%; | |||
| } | |||
| body { | |||
|   font-family: sans-serif; | |||
| } | |||
| table { | |||
|   border-collapse: collapse; | |||
| } | |||
| @ -1,7 +0,0 @@ | |||
| /** | |||
|  * 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/ | |||
|  */ | |||
| .tinymce-mobile-unfocused-selections .tinymce-mobile-unfocused-selection{background-color:green;display:inline-block;opacity:.5;position:absolute}body{-webkit-text-size-adjust:none}body img{max-width:96vw}body table img{max-width:95%}body{font-family:sans-serif}table{border-collapse:collapse} | |||
Some files were not shown because too many files changed in this diff
					Loading…
					
					
				
		Reference in new issue