|
@@ -1,41 +1,79 @@
|
|
|
<template>
|
|
|
<el-container>
|
|
|
<el-header>
|
|
|
- <el-button :disabled="!emrConfig.editor" type="success" icon="CircleCheck" @click="clickSaveData">保存</el-button>
|
|
|
- <el-button :disabled="!emrConfig.editor" icon="Delete" type="danger" @click="clickDelete">删除</el-button>
|
|
|
- <el-button style="margin-left: 5px" @click="clickToSubmitTheMedicalRecord"
|
|
|
- :disabled="!documentId || !emrConfig.editor">
|
|
|
- 提交病历
|
|
|
- </el-button>
|
|
|
+ <el-button-group>
|
|
|
+ <el-button :disabled="!emrConfig.editor"
|
|
|
+ type="success"
|
|
|
+ icon="CircleCheck"
|
|
|
+ @click="clickSaveData">
|
|
|
+ 保存
|
|
|
+ </el-button>
|
|
|
+ <el-button
|
|
|
+ type="primary"
|
|
|
+ @click="clickToSubmitTheMedicalRecord"
|
|
|
+ :disabled="!documentId || !emrConfig.editor">
|
|
|
+ 提交病历
|
|
|
+ </el-button>
|
|
|
+ <el-button :disabled="!emrConfig.editor"
|
|
|
+ icon="Delete" type="danger"
|
|
|
+ @click="clickDelete">
|
|
|
+ 删除
|
|
|
+ </el-button>
|
|
|
+ </el-button-group>
|
|
|
+ <el-divider direction="vertical"/>
|
|
|
<el-button-group>
|
|
|
<el-button type="primary" icon="Printer" @click="frontEndPrinting"
|
|
|
- title="页面打印支持病历续打,但是可能会出现打印错误。">页面打印
|
|
|
+ title="页面打印支持病历续打,但是可能会出现打印错误。">
|
|
|
+ 页面
|
|
|
</el-button>
|
|
|
<el-button type="primary" icon="Printer" @click="servicePrint"
|
|
|
- title="服务打印慢,但是不会出现页面打印错误,不支持病历续打。">服务打印
|
|
|
+ title="服务打印慢,但是不会出现页面打印错误,不支持病历续打。">
|
|
|
+ 服务
|
|
|
</el-button>
|
|
|
</el-button-group>
|
|
|
- <el-button style="margin-left: 5px" type="primary" @click="openAssistant.dialog = true">
|
|
|
- 病历助手
|
|
|
- </el-button>
|
|
|
+ <el-divider direction="vertical"/>
|
|
|
<el-button-group>
|
|
|
- <el-button icon="RefreshLeft" @click="clickUndo('undo')">撤销</el-button>
|
|
|
- <el-button icon="RefreshRight" @click="clickUndo('redo')">重做</el-button>
|
|
|
+ <el-button
|
|
|
+ type="primary"
|
|
|
+ @click="openAssistant.dialog = true"
|
|
|
+ title="电子病历助手,目前只能填充手术病历">
|
|
|
+ 助手
|
|
|
+ </el-button>
|
|
|
+ <el-button @click="drgIntelligentGrouping"
|
|
|
+ type="primary"
|
|
|
+ title="drg的预分组">
|
|
|
+ DRG分组
|
|
|
+ </el-button>
|
|
|
</el-button-group>
|
|
|
- <el-button @click="drgIntelligentGrouping" type="primary">DRG智能分组</el-button>
|
|
|
<emr-assistant :data="openAssistant" :to-fill-in-data="clickToFillInData"/>
|
|
|
- <el-button title="根据病程记录的时间来进行排序,从小到大。"
|
|
|
- @click="diseaseCourseSequencing">
|
|
|
- 病程排序 ❓
|
|
|
- </el-button>
|
|
|
- <el-switch v-model="reviewMode"
|
|
|
- active-color="#ff4949"
|
|
|
- active-text="关闭审阅"
|
|
|
- :active-value="0"
|
|
|
- inactive-color="#13ce66"
|
|
|
+ <el-divider direction="vertical"/>
|
|
|
+ <el-select v-model="reviewMode"
|
|
|
+ style="width: 60px; "
|
|
|
@change="isRevisionMode"
|
|
|
- inactive-text="开启审阅"
|
|
|
- :inactive-value="1"/>
|
|
|
+ title="审阅模式">
|
|
|
+ <el-option :value="0" label="关闭"
|
|
|
+ title="页面上不显示修改记录"/>
|
|
|
+ <el-option :value="1" label="开启"
|
|
|
+ title="病历右侧会以列表的形式显示 添加,删除,更新的记录"/>
|
|
|
+ <el-option :value="2" label="嵌入"
|
|
|
+ title="嵌入病历显示修改记录,新增的记录会用背景颜色标记,删除的记录 通过画删除线标记"/>
|
|
|
+ </el-select>
|
|
|
+ <el-button-group>
|
|
|
+ <el-button icon="RefreshLeft"
|
|
|
+ @click="clickUndo('undo')"
|
|
|
+ title="撤销"/>
|
|
|
+ <el-button icon="RefreshRight"
|
|
|
+ @click="clickUndo('redo')"
|
|
|
+ title="重做"/>
|
|
|
+ </el-button-group>
|
|
|
+ <el-button-group>
|
|
|
+ <el-button title="仅在病程记录中生效,根据病程记录的时间来进行排序,从小到大。"
|
|
|
+ icon="SortDown"
|
|
|
+ @click="diseaseCourseSequencing"/>
|
|
|
+ <el-button title="为页面添加分页标识符,分页符后强制为新页面。" @click="paginationSymbol">
|
|
|
+ <i class="iconfont icon-chaifenyemian"></i>
|
|
|
+ </el-button>
|
|
|
+ </el-button-group>
|
|
|
|
|
|
</el-header>
|
|
|
<el-container>
|
|
@@ -47,9 +85,112 @@
|
|
|
<el-main v-loading="loaded">
|
|
|
<el-row>
|
|
|
<el-col :span="20">
|
|
|
+ <div class="tool_emr">
|
|
|
+ <el-select style="width: 150px;"
|
|
|
+ @change="textStyleFunc.fontFamily()"
|
|
|
+ v-model="emrStyle.fontFamily">
|
|
|
+ <el-option v-for="item in availableFonts"
|
|
|
+ :value="item.font"
|
|
|
+ :label="item.text">
|
|
|
+ <span :style="{'fontFamily':item.font }">
|
|
|
+ {{ item.text }}
|
|
|
+ </span>
|
|
|
+ </el-option>
|
|
|
+ </el-select>
|
|
|
+ <el-select style="width: 70px;"
|
|
|
+ @change="textStyleFunc.fontSize()"
|
|
|
+ v-model="emrStyle.fontSize">
|
|
|
+ <el-option v-for="item in fontSizes"
|
|
|
+ :value="item.code"
|
|
|
+ :label="item.name"/>
|
|
|
+ </el-select>
|
|
|
+ <el-divider direction="vertical"/>
|
|
|
+ <el-button-group>
|
|
|
+ <el-button @click="styleFunc('fontSizeAdjust','increase')"
|
|
|
+ title="放大字体">
|
|
|
+ +
|
|
|
+ </el-button>
|
|
|
+ <el-button @click="styleFunc('fontSizeAdjust','decrease')"
|
|
|
+ title="缩小字体">
|
|
|
+ -
|
|
|
+ </el-button>
|
|
|
+ </el-button-group>
|
|
|
+ <el-divider direction="vertical"/>
|
|
|
+ <el-button-group>
|
|
|
+ <el-button
|
|
|
+ title="字体加粗"
|
|
|
+ :class="buttonClass('fontWeight','bold')"
|
|
|
+ @click="textStyleFunc.fontWeight()">
|
|
|
+ <i class="iconfont icon-jiacu"></i>
|
|
|
+ </el-button>
|
|
|
+ <el-button
|
|
|
+ title="斜体"
|
|
|
+ :class="buttonClass('fontStyle','oblique')"
|
|
|
+ @click="textStyleFunc.fontStyle()">
|
|
|
+ <i class="iconfont icon-xieti"></i>
|
|
|
+ </el-button>
|
|
|
+ <el-button
|
|
|
+ title="下划线"
|
|
|
+ :class="buttonClass('underline')"
|
|
|
+ @click="textStyleFunc.underline()">
|
|
|
+ <i class="iconfont icon-xiahuaxian"></i>
|
|
|
+ </el-button>
|
|
|
+ <el-button
|
|
|
+ title="删除线"
|
|
|
+ :class="buttonClass('lineThrough')"
|
|
|
+ @click="textStyleFunc.lineThrough()">
|
|
|
+ <i class="iconfont icon-shanchuxian"></i>
|
|
|
+ </el-button>
|
|
|
+ <el-button
|
|
|
+ title="上标"
|
|
|
+ :class="buttonClass('super')"
|
|
|
+ @click="textStyleFunc.super()">
|
|
|
+ <i class="iconfont icon-zitishangbiao"></i>
|
|
|
+ </el-button>
|
|
|
+ <el-button
|
|
|
+ title="下标"
|
|
|
+ :class="buttonClass('sub')"
|
|
|
+ @click="textStyleFunc.sub()">
|
|
|
+ <i class="iconfont icon-zitixiabiao"></i>
|
|
|
+ </el-button>
|
|
|
+ </el-button-group>
|
|
|
+ <div class="color_picker"
|
|
|
+ title="字体颜色">
|
|
|
+ <i class="iconfont icon-zitiyanse"></i>
|
|
|
+ <el-color-picker v-model="emrStyle.color"
|
|
|
+ @change="textStyleFunc.color()"
|
|
|
+ :predefine="predefineColors"/>
|
|
|
+ </div>
|
|
|
+ <div class="color_picker"
|
|
|
+ title="背景颜色">
|
|
|
+ <i class="iconfont icon-beijingyanse"></i>
|
|
|
+ <el-color-picker v-model="emrStyle.backgroundColor"
|
|
|
+ @change="textStyleFunc.backgroundColor()"
|
|
|
+ :predefine="predefineColors"/>
|
|
|
+ </div>
|
|
|
+ <el-divider direction="vertical"/>
|
|
|
+ <el-button-group>
|
|
|
+ <el-button title="左对齐"
|
|
|
+ @click="textStyleFunc.alignment('left')">
|
|
|
+ <i class="iconfont icon-zuoduiqi"></i>
|
|
|
+ </el-button>
|
|
|
+ <el-button title="居中对其"
|
|
|
+ @click="textStyleFunc.alignment('center')">
|
|
|
+ <i class="iconfont icon-juzhongduiqi"></i>
|
|
|
+ </el-button>
|
|
|
+ <el-button title="右对齐"
|
|
|
+ @click="textStyleFunc.alignment('right')">
|
|
|
+ <i class="iconfont icon-youduiqi"></i>
|
|
|
+ </el-button>
|
|
|
+ <el-button title="两端对齐"
|
|
|
+ @click="textStyleFunc.alignment('justify')">
|
|
|
+ <i class="iconfont icon-zuoyouduiqi"></i>
|
|
|
+ </el-button>
|
|
|
+ </el-button-group>
|
|
|
+ </div>
|
|
|
<div class="emr-iframe">
|
|
|
<iframe ref="emrRef"
|
|
|
- :height="maxHeight - 80 + 'px' "
|
|
|
+ :height="maxHeight - 100 + 'px' "
|
|
|
:src="caseHistoryUrl"/>
|
|
|
</div>
|
|
|
</el-col>
|
|
@@ -73,7 +214,11 @@
|
|
|
<script setup name="emr">
|
|
|
import {getEmrInpatientData} from "@/api/dictionary/emr-data-maintenance-api";
|
|
|
import EmrSidebar from "@/components/zhu-yuan-yi-sheng/emr/EmrSidebar.vue";
|
|
|
-import {EMRInteractive, emrConfig} from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-init";
|
|
|
+import {
|
|
|
+ EMRInteractive,
|
|
|
+ emrConfig,
|
|
|
+ fontSizes, availableFonts
|
|
|
+} from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-init";
|
|
|
import {ElMessage, ElMessageBox} from "element-plus";
|
|
|
import {BizException, ExceptionEnum} from "@/utils/BizException";
|
|
|
import EmrSnippet from "@/components/zhu-yuan-yi-sheng/emr/EmrSnippet.vue";
|
|
@@ -113,7 +258,7 @@ let documentId = $ref('')
|
|
|
let patientId = $ref('')
|
|
|
let categoryId = $ref('')
|
|
|
let templateName = $ref('')
|
|
|
-let caseHistoryUrl = $ref('')
|
|
|
+let caseHistoryUrl = $ref('/emr/runtime/#/editor')
|
|
|
let openAssistant = $ref({
|
|
|
data: {},
|
|
|
dialog: false
|
|
@@ -145,6 +290,45 @@ let createId = null;
|
|
|
// 获取提取到的数据。
|
|
|
let extractData = {}
|
|
|
|
|
|
+let emrStyle = $ref({
|
|
|
+ // 字体样式
|
|
|
+ fontFamily: '"Microsoft YaHei"',
|
|
|
+ // 字体大小
|
|
|
+ fontSize: '10.5pt',
|
|
|
+ // 字体加粗
|
|
|
+ fontWeight: 'normal',
|
|
|
+ // 斜体
|
|
|
+ fontStyle: 'normal',
|
|
|
+ // 下划线
|
|
|
+ underline: false,
|
|
|
+ //删除线
|
|
|
+ lineThrough: false,
|
|
|
+ // 上标
|
|
|
+ super: false,
|
|
|
+ // 下标
|
|
|
+ sub: false,
|
|
|
+ // 颜色
|
|
|
+ color: '',
|
|
|
+ backgroundColor: '',
|
|
|
+ paragraphSetting: {}
|
|
|
+})
|
|
|
+const predefineColors = ref([
|
|
|
+ '#ff4500',
|
|
|
+ '#ff8c00',
|
|
|
+ '#ffd700',
|
|
|
+ '#90ee90',
|
|
|
+ '#00ced1',
|
|
|
+ '#1e90ff',
|
|
|
+ '#c71585',
|
|
|
+ 'rgba(255, 69, 0, 0.68)',
|
|
|
+ 'rgb(255, 120, 0)',
|
|
|
+ 'hsv(51, 100, 98)',
|
|
|
+ 'hsva(120, 40, 94, 0.5)',
|
|
|
+ 'hsl(181, 100%, 37%)',
|
|
|
+ 'hsla(209, 100%, 56%, 0.73)',
|
|
|
+ '#c7158577',
|
|
|
+])
|
|
|
+
|
|
|
// 点击保存病历
|
|
|
const clickSaveData = async () => {
|
|
|
// 只读模式无法保存数据
|
|
@@ -428,6 +612,25 @@ const emrEvent = {
|
|
|
}
|
|
|
},
|
|
|
|
|
|
+ 'contextUpdate': (evt, contextMap, component, context) => {
|
|
|
+ emrStyle.fontSize = context.fontSize
|
|
|
+ emrStyle.fontFamily = context.fontFamily
|
|
|
+ emrStyle.fontStyle = context.italic ? 'oblique' : 'normal'
|
|
|
+ emrStyle.fontWeight = context.bold ? 'bold' : 'normal'
|
|
|
+ emrStyle.underline = context.underline
|
|
|
+ emrStyle.lineThrough = context.linethrough
|
|
|
+ emrStyle.super = context.superScript
|
|
|
+ emrStyle.sub = context.subScript
|
|
|
+ emrStyle.color = context.color
|
|
|
+ emrStyle.backgroundColor = context.backgroundColor
|
|
|
+ emrStyle.paragraphSetting = context.paragraphSetting
|
|
|
+ console.log(evt, contextMap, component, context)
|
|
|
+ },
|
|
|
+
|
|
|
+ 'ready': (event) => {
|
|
|
+ editor = currentEmr.value.getEditor()
|
|
|
+ }
|
|
|
+
|
|
|
}
|
|
|
|
|
|
// 设置编辑器的模式
|
|
@@ -660,7 +863,12 @@ const extractFields = (val) => {
|
|
|
|
|
|
// 是否开启审阅模式
|
|
|
const isRevisionMode = () => {
|
|
|
- editor.setRevisionShowMode(reviewMode)
|
|
|
+ try {
|
|
|
+ editor.setRevisionShowMode(reviewMode);
|
|
|
+ } catch (e) {
|
|
|
+ console.error(e)
|
|
|
+ }
|
|
|
+
|
|
|
}
|
|
|
|
|
|
// 电子病历排序
|
|
@@ -679,8 +887,11 @@ const diseaseCourseSequencing = () => {
|
|
|
const root = editor.model.document.getRoot(); //文档跟节点
|
|
|
for (const node of root.getChildren()) { //遍历区域并把时间和区域关键放进areas
|
|
|
if (node.type === 'area') {
|
|
|
- if (!walker) walker = service.createTreeWalker(node)
|
|
|
- else service.setWalkerRoot(walker, node);
|
|
|
+ if (!walker) {
|
|
|
+ walker = service.createTreeWalker(node)
|
|
|
+ } else {
|
|
|
+ service.setWalkerRoot(walker, node);
|
|
|
+ }
|
|
|
let dataElements = service.getDataElementsFromWalker(walker, '查房时间', 'business');
|
|
|
let time = dataElements['查房时间'].value;
|
|
|
areas.push({
|
|
@@ -714,6 +925,108 @@ const diseaseCourseSequencing = () => {
|
|
|
})
|
|
|
}
|
|
|
|
|
|
+const paginationSymbol = () => {
|
|
|
+ editor.execute('insertContents', {value: [{type: 'pagebreak'}]})
|
|
|
+}
|
|
|
+
|
|
|
+// 通用的方法
|
|
|
+const styleFunc = (name, value) => {
|
|
|
+ emrStyle[name] = value
|
|
|
+ editor.execute(name, {value: value})
|
|
|
+}
|
|
|
+
|
|
|
+const styleFuncNormal = (name, style) => {
|
|
|
+ let value = emrStyle[name]
|
|
|
+ styleFunc(name, value === 'normal' ? style : 'normal')
|
|
|
+}
|
|
|
+
|
|
|
+const textStyleFunc = ref({
|
|
|
+ fontFamily: () => {
|
|
|
+ editor.execute('fontFamily', {value: emrStyle.fontFamily})
|
|
|
+ editor.focus()
|
|
|
+ },
|
|
|
+ fontSize: () => {
|
|
|
+ editor.execute('fontSize', {value: emrStyle.fontSize})
|
|
|
+ editor.focus()
|
|
|
+ },
|
|
|
+ fontWeight: () => {
|
|
|
+ let val = emrStyle.fontWeight === 'normal' ? 'bold' : 'normal'
|
|
|
+ emrStyle.fontWeight = val
|
|
|
+ editor.execute('fontWeight', {value: val})
|
|
|
+ editor.focus()
|
|
|
+ },
|
|
|
+ fontStyle: () => {
|
|
|
+ let val = emrStyle.fontStyle === 'normal' ? 'oblique' : 'normal'
|
|
|
+ emrStyle.fontStyle = val
|
|
|
+ editor.execute('fontStyle', {value: val})
|
|
|
+ editor.focus()
|
|
|
+ },
|
|
|
+ underline: () => {
|
|
|
+ emrStyle.underline = !emrStyle.underline
|
|
|
+ let value = emrStyle.underline ? 'underline' : 'remove underline'
|
|
|
+ editor.execute('textDecoration', {value})
|
|
|
+ },
|
|
|
+ lineThrough: () => {
|
|
|
+ emrStyle.lineThrough = !emrStyle.lineThrough
|
|
|
+ let value = emrStyle.lineThrough ? 'line-through' : 'remove line-through'
|
|
|
+ editor.execute('textDecoration', {value})
|
|
|
+ },
|
|
|
+ super: () => {
|
|
|
+ emrStyle.super = !emrStyle.super
|
|
|
+ let value = emrStyle.super ? 'super' : 'baseline'
|
|
|
+ editor.execute('verticalAlign', {value})
|
|
|
+ },
|
|
|
+ sub: () => {
|
|
|
+ emrStyle.sub = !emrStyle.sub
|
|
|
+ let value = emrStyle.sub ? 'sub' : 'baseline'
|
|
|
+ editor.execute('verticalAlign', {value})
|
|
|
+ },
|
|
|
+ color: () => {
|
|
|
+ editor.execute('color', {value: emrStyle.color})
|
|
|
+ },
|
|
|
+ backgroundColor: () => {
|
|
|
+ editor.execute('backgroundColor', {value: emrStyle.backgroundColor})
|
|
|
+ },
|
|
|
+ alignment: (val) => {
|
|
|
+ return
|
|
|
+ emrStyle.paragraphSetting.textAlign = {value: val}
|
|
|
+ console.log(emrStyle.paragraphSetting)
|
|
|
+
|
|
|
+
|
|
|
+ editor.execute('paragraphSetting', {
|
|
|
+ value: {
|
|
|
+ "lineHeight": {
|
|
|
+ "type": "单倍行距",
|
|
|
+ "value": 1
|
|
|
+ },
|
|
|
+ "paragraphSpacing": {
|
|
|
+ "before": 0,
|
|
|
+ "after": 0
|
|
|
+ },
|
|
|
+ "paragraphIndent": {
|
|
|
+ "left": 0,
|
|
|
+ "right": 0
|
|
|
+ },
|
|
|
+ "specialIndent": {
|
|
|
+ "type": "无",
|
|
|
+ "value": 0
|
|
|
+ },
|
|
|
+ "textAlign": {
|
|
|
+ "value": "center"
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+})
|
|
|
+
|
|
|
+const buttonClass = (val, activation = true) => {
|
|
|
+ if (emrStyle[val] === activation) {
|
|
|
+ return 'emr__button_select'
|
|
|
+ } else {
|
|
|
+ return 'button'
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
|
|
|
onMounted(() => {
|
|
|
getExtractDataElement(props.huanZheXinXi.inpatientNo, props.huanZheXinXi.admissTimes).then((res) => {
|
|
@@ -755,8 +1068,35 @@ onBeforeRouteLeave((to, from, next) => {
|
|
|
|
|
|
</script>
|
|
|
|
|
|
-<style scoped>
|
|
|
+<style scoped lang="scss">
|
|
|
.emr-iframe, iframe {
|
|
|
width: 100%;
|
|
|
}
|
|
|
+
|
|
|
+.emr__button_select {
|
|
|
+ border: 1px solid #a0a0a0;
|
|
|
+ font-size: 14px;
|
|
|
+}
|
|
|
+
|
|
|
+.button {
|
|
|
+ border: 1px solid transparent;
|
|
|
+ font-size: 14px;
|
|
|
+}
|
|
|
+
|
|
|
+.tool_emr {
|
|
|
+ width: 100%;
|
|
|
+ height: 30px;
|
|
|
+ background-color: #f0f0f0;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+}
|
|
|
+
|
|
|
+.color_picker {
|
|
|
+ &:hover {
|
|
|
+ cursor: pointer;
|
|
|
+ color: #409EFF;
|
|
|
+ }
|
|
|
+
|
|
|
+ background-color: white;
|
|
|
+}
|
|
|
</style>
|