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