浏览代码

优化电子病历中恢复病历

xiaochan 2 年之前
父节点
当前提交
63ee8e197b

+ 6 - 1
src/components/xiao-chan/dialog/XcDialogV2.vue

@@ -2,6 +2,7 @@
   <div class="xc-dialog-v2" ref="dialogRef">
     <el-dialog v-model="dialog"
                :title="props.title"
+               @opened="opened"
                :show-close="false"
                draggable
                :destroy-on-close="props.destroyOnClose"
@@ -88,7 +89,7 @@ const props = defineProps({
   }
 })
 
-const emit = defineEmits(['closed', 'update:modelValue', 'cancel', 'confirm'])
+const emit = defineEmits(['closed', 'update:modelValue', 'cancel', 'confirm', 'opened'])
 
 let fullScreen = $ref(props.maximize)
 const clickFullScreen = () => {
@@ -102,6 +103,10 @@ const closed = () => {
   emit('update:modelValue', false)
 }
 
+const opened = () => {
+  emit('opened')
+}
+
 const dialog = ref(false)
 
 watch(() => props.modelValue, () => {

+ 35 - 26
src/components/zhu-yuan-yi-sheng/emr/HistoricalEmr.vue

@@ -1,15 +1,18 @@
 <template>
-  <xc-dialog-v2 v-model="dialog"
+  <xc-dialog-v2 v-model="modelValue"
                 :maximize="true"
-                title="还原病历"
-                @closed="emit('closed')">
+                title="还原病历">
     <div class="historical__main">
       <div class="historical__left">
         <el-table :data="historicalData"
                   highlight-current-row
+                  v-loading="isLoading"
                   :height="getWindowSize.h / 1.2"
                   @row-click="rowClick">
           <el-table-column fixed="left" label="操作" width="40">
+            <template #header>
+              <el-button @click="emrMitt.emit('queryHistoryFunc')" text>刷新</el-button>
+            </template>
             <template #default="{row}">
               <el-button text type="primary" @click.stop="restoreData(row)">还原</el-button>
             </template>
@@ -40,35 +43,41 @@
   </xc-dialog-v2>
 </template>
 
-<script setup name='HistoricalEmr' lang="ts">
+<script setup lang="ts">
 import XcDialogV2 from "../../../components/xiao-chan/dialog/XcDialogV2.vue";
 import {nextTick, onMounted, ref} from "vue";
 import {
-  EMRInteractive
-} from '../../../views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/emr-init'
-import {getHistory} from '../../../api/zhu-yuan-yi-sheng/emr-patient'
-import {getFormatDatetime} from '../../../utils/date'
+  EMRInteractive,
+  emrMitt
+} from '@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/emr-init'
+import {getFormatDatetime} from '@/utils/date'
 import {ElMessageBox} from "element-plus";
-import {BizException, ExceptionEnum} from "../../../utils/BizException";
-import {getWindowSize} from '../../../utils/window-size'
+import {getWindowSize} from '@/utils/window-size'
+import {useVModels} from "@vueuse/core";
 
-const props = defineProps({
-  docunentId: {
-    type: String
-  }
-})
-const emit = defineEmits(['closed', 'restoreData'])
+interface EmrHistory {
+  documentId: string
+  _id: string
+  categoryId: string
+}
+
+const props = defineProps<{
+  modelValue: boolean
+  historicalData: EmrHistory[]
+}>()
+const emit = defineEmits(['update:modelValue'])
+const {modelValue, historicalData} = useVModels(props, emit)
 
-const dialog = ref(true)
 const emrRef = ref(null)
 const currentEmr = ref(null)
-const historicalData = ref([])
+const isLoading = ref(true)
 
 let editor = null
 
 const emrEvent = {
   'ready': (event) => {
     editor = currentEmr.value.getEditor()
+    isLoading.value = false
   }
 }
 
@@ -76,29 +85,29 @@ const rowClick = (row) => {
   editor.setDocument(row)
 }
 
+
 const restoreData = (row) => {
   ElMessageBox.confirm('是否要还原到此节点。', '提示', {
     type: 'warning'
   }).then(() => {
     row._id = row.documentId
     delete row.documentId
-    emit('restoreData', row)
+
+    const tempEdit = emrMitt.emit('editor')
+    tempEdit.setDocument(row)
+    modelValue.value = false
+
   }).catch(() => {
   })
 }
 
 onMounted(async () => {
-  if (!props.docunentId) {
-    emit('closed')
-    BizException(ExceptionEnum.MESSAGE_ERROR, "请先选择已保存的病历模板。");
-  }
   await nextTick()
   currentEmr.value = new EMRInteractive(null, emrEvent);
   emrRef.value.parentElement.emr = currentEmr.value
-  getHistory(props.docunentId).then((res) => {
-    historicalData.value = res as Array<any>;
-  });
 })
+
+
 </script>
 
 <style scoped lang="scss">

+ 19 - 35
src/utils/public.ts

@@ -32,7 +32,7 @@ export const nullToEmpty = (val: string): string => {
     }
 }
 
-export const elementAddBody = (val) => {
+export const elementAddBody = (val: HTMLElement): void => {
     const body = document.querySelector("body");
     if (body.append) {
         body.append(val);
@@ -42,46 +42,30 @@ export const elementAddBody = (val) => {
 }
 
 /**
- * 对比版本号
- * @param version1 版本1
- * @param version2 版本 2
- * @returns {number} 1 大于 -1小于 0等于
+ * 对比版本号,需要考虑带有英文字殮的版本号
  */
-export function compareVersion(version1, version2) {
-    const arr1 = version1.split('.')
-    const arr2 = version2.split('.')
-    const length1 = arr1.length
-    const length2 = arr2.length
-    const minlength = Math.min(length1, length2)
-    let i = 0
-    for (i; i < minlength; i++) {
-        let a = parseInt(arr1[i])
-        let b = parseInt(arr2[i])
-        if (a > b) {
-            return 1
-        } else if (a < b) {
-            return -1
-        }
+export const compareVersion = (v1: string, v2: string): number => {
+    const v1s = v1.split(".");
+    const v2s = v2.split(".");
+    const len = Math.max(v1s.length, v2s.length);
+    while (v1s.length < len) {
+        v1s.push("0");
     }
-    if (length1 > length2) {
-        for (let j = i; j < length1; j++) {
-            if (parseInt(arr1[j]) !== 0) {
-                return 1
-            }
-        }
-        return 0
-    } else if (length1 < length2) {
-        for (let j = i; j < length2; j++) {
-            if (parseInt(arr2[j]) !== 0) {
-                return -1
-            }
+    while (v2s.length < len) {
+        v2s.push("0");
+    }
+    for (let i = 0; i < len; i++) {
+        const num1 = parseInt(v1s[i]);
+        const num2 = parseInt(v2s[i]);
+        if (num1 > num2) {
+            return 1;
+        } else if (num1 < num2) {
+            return -1;
         }
-        return 0
     }
-    return 0
+    return 0;
 }
 
-
 export const chineseEncrypt = {
     encrypt: (val) => {
         if (XEUtils.isEmpty(val)) {

+ 83 - 45
src/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/EmrMain.vue

@@ -20,7 +20,7 @@
                  @click="clickDelete">
         删除
       </el-button>
-      <el-button @click="recoveryDialog = true">
+      <el-button @click="openRecovery">
         恢复
       </el-button>
       <el-button @click="auditClick" type="primary">
@@ -44,9 +44,8 @@
     <el-divider direction="vertical"/>
     <!--   恢复到上一次保存的状态   -->
     <historical-emr v-if="recoveryDialog"
-                    @closed="recoveryDialog = false"
-                    :docunent-id="documentId"
-                    @restore-data="restoreData"/>
+                    v-model="recoveryDialog"
+                    :historical-data="historicalData"/>
     <el-button-group>
       <el-button type="primary" icon="Printer" @click="frontEndPrinting"
                  title="页面打印支持病历续打,但是可能会出现打印错误,如果页面打印无法使用请用服务打印,服务打印也不行请换win10电脑打印。">
@@ -291,11 +290,11 @@ import {
   getDrgIntelligentGrouping,
   getExtractDataElement,
   hotSearchSorting,
-  submitMedicalRecord
+  submitMedicalRecord,
+  getHistory
 } from "@/api/zhu-yuan-yi-sheng/emr-patient";
 import {useDocumentVisibility} from "@vueuse/core";
 import XcDialogV2 from "@/components/xiao-chan/dialog/XcDialogV2.vue";
-import {getWardsApi} from "@/api/login";
 import {xcMessage} from "@/utils/xiaochan-element-plus";
 import HistoricalEmr from "@/components/zhu-yuan-yi-sheng/emr/HistoricalEmr.vue";
 import EmrPopup from "@/components/zhu-yuan-yi-sheng/emr/EmrPopup.vue";
@@ -341,7 +340,6 @@ const currentEmr = ref(null)
 const emrRef = ref(null)
 const emrSocket = ref(null)
 
-const recoveryDialog = ref(false)
 const categoryCode = ref('')
 // 文档 id 唯一值
 const documentId = ref('')
@@ -1206,9 +1204,9 @@ const diseaseCourseSequencing = () => {
           anchor = item.nextElementSibling
           pos = 'beforebegin'
         }
-        areas.sort((item1, item2) => {
-          return item1.time - item2.time
-        }).forEach((item) => {
+
+        const orderAreas = XEUtils.orderBy(areas, [['time', 'asc']])
+        XEUtils.arrayEach(orderAreas, (item) => {
           if (!anchor) {//无前后节点之间append
             anchor.parentElement.appendChild(item.view.el)
           } else {
@@ -1245,13 +1243,6 @@ const analysisIframeSrcSearch = async () => {
   return temp
 }
 
-// 恢复历史数据
-const restoreData = (data) => {
-  editor.setDocument(data)
-  xcMessage.success('恢复成功,请点击保存。')
-  recoveryDialog.value = false
-}
-
 const popupRef = ref(null)
 const popupFunc = {
   setShortcutKey: () => {
@@ -1353,6 +1344,42 @@ const monitorPageRefresh = (event) => {
   }
 }
 
+// ----------------------------- 恢复到上一次保存的状态
+const recoveryDialog = ref(false)
+const historicalData = ref<EmrHistory[]>([])
+
+interface EmrHistory {
+  documentId: string
+  _id: string
+  categoryId: string
+}
+
+const openRecovery = () => {
+  if (stringIsBlank(documentId.value)) {
+    BizException(ExceptionEnum.MESSAGE_ERROR, "请先选择已保存的病历模板。");
+  }
+
+  if (historicalData.value.length > 0) {
+    let [one] = historicalData.value
+    if (documentId.value !== one.documentId) {
+      historicalData.value = []
+      queryHistoryFunc()
+    } else {
+      recoveryDialog.value = true
+    }
+  } else {
+    queryHistoryFunc()
+  }
+}
+
+const queryHistoryFunc = () => {
+  getHistory(documentId.value).then(res => {
+    // @ts-ignore
+    historicalData.value = res as EmrHistory
+    recoveryDialog.value = true
+  })
+}
+
 /**
  * 打开已经保存了的病历
  * @param id 病历 id
@@ -1371,24 +1398,23 @@ const visibility = useDocumentVisibility()
 // 创建和编辑病历
 let emrEditCreateLimit = new EmrEditCreateLimit(props.huanZheXinXi, userData)
 
-onMounted(async () => {
-  // ts-ignore
-  autoSave.value = isDev ? false : appStore.value.emrAutoSave;
-  extractData.value = await getExtractDataElement(props.huanZheXinXi.inpatientNo, props.huanZheXinXi.admissTimes)
-  await nextTick()
-  patientId.value = props.huanZheXinXi.inpatientNo + '_' + props.huanZheXinXi.admissTimes
-  await queryingBasicPatientInformation()
-  currentEmr.value = new EMRInteractive(patientData.value, emrEvent);
-  if (emrConfig.value.editor) {
-    emrSnippetRef.value.setPatientData(patientData.value)
-  }
-  doctorLevelFunc()
-  emrRef.value.parentElement.emr = currentEmr.value
 
-  window.addEventListener('beforeunload', monitorPageRefresh, {capture: true})
-
-  autoSaveFunc()
+const watchVisibility = () => {
+  watch(() => visibility.value, () => {
+    // 离开页面的时候清空定时器
+    if (visibility.value === 'hidden' && isEditorChange.value) {
+      if (interval != null) {
+        clearInterval(interval)
+      }
+      document.title = `患者【${props.huanZheXinXi.name}】,未保存数据`
+    } else {
+      autoSaveChange()
+      document.title = `电子病历-正在编辑【${props.huanZheXinXi.name}】`
+    }
+  }, {immediate: true})
+}
 
+const emrMittInit = () => {
   emrMitt.on('editor', () => {
     return editor
   })
@@ -1409,18 +1435,29 @@ onMounted(async () => {
     location.reload();
   })
 
-  watch(() => visibility.value, () => {
-    // 离开页面的时候清空定时器
-    if (visibility.value === 'hidden' && isEditorChange.value) {
-      if (interval != null) {
-        clearInterval(interval)
-      }
-      document.title = `患者【${props.huanZheXinXi.name}】,未保存数据`
-    } else {
-      autoSaveChange()
-      document.title = `电子病历-正在编辑【${props.huanZheXinXi.name}】`
-    }
-  }, {immediate: true})
+  emrMitt.on('queryHistoryFunc', queryHistoryFunc)
+
+}
+
+
+onMounted(async () => {
+  autoSave.value = isDev ? false : appStore.value.emrAutoSave;
+  extractData.value = await getExtractDataElement(props.huanZheXinXi.inpatientNo, props.huanZheXinXi.admissTimes)
+  await nextTick()
+  patientId.value = props.huanZheXinXi.inpatientNo + '_' + props.huanZheXinXi.admissTimes
+  await queryingBasicPatientInformation()
+  currentEmr.value = new EMRInteractive(patientData.value, emrEvent);
+  if (emrConfig.value.editor) {
+    emrSnippetRef.value.setPatientData(patientData.value)
+  }
+  doctorLevelFunc()
+  emrRef.value.parentElement.emr = currentEmr.value
+
+  window.addEventListener('beforeunload', monitorPageRefresh, {capture: true})
+
+  autoSaveFunc()
+  emrMittInit()
+  watchVisibility()
 })
 
 onDeactivated(() => {
@@ -1613,6 +1650,7 @@ const setEditor = () => {
   styleBarRef.value.setEditor(editor)
 }
 
+
 defineExpose({
   closeBothSides,
   headerRef,