Browse Source

电子病历中的书写提示

xiaochan 1 year ago
parent
commit
1292fcc1ad

+ 3 - 3
src/api/emr-control/emr-control.ts

@@ -1,7 +1,7 @@
 import request from "./request";
 import requestV2 from "../../utils/request-v2";
 
-export function linkQualityControl(startDate, endDate, sid, timeType) {
+export function linkQualityControl(startDate: string, endDate: string, sid: string, timeType: string) {
     return request({
         url: '/emrQualityControl/linkControl',
         method: 'get',
@@ -9,7 +9,7 @@ export function linkQualityControl(startDate, endDate, sid, timeType) {
     })
 }
 
-export function obtainTheProportionOfMedicalRecords(startDate, endDate, finalControl) {
+export function obtainTheProportionOfMedicalRecords(startDate: string, endDate: string, finalControl: number) {
     return requestV2<string>({
         url: '/emrQualityControl/obtainTheProportionOfMedicalRecords',
         method: 'get',
@@ -34,7 +34,7 @@ export function selectControlByPatNo(patNo: string, times: number) {
     })
 }
 
-export function saveEmr(data) {
+export function saveEmr(data: any) {
     return request({
         url: '/save',
         method: 'post',

+ 1 - 0
src/api/emr-control/request.ts

@@ -16,6 +16,7 @@ service.interceptors.request.use(
     // @ts-ignore
     (config) => {
         if (store.getters['user/token']) {
+            // @ts-ignore
             config.headers['token'] = store.state.user.token
         }
         return config

+ 14 - 2
src/utils/emr/emr-init-v2.ts

@@ -14,7 +14,8 @@ interface Options {
     event?: {
         [key: string]: (...val: any[]) => void
     }
-    tabletMode?: boolean
+    tabletMode?: boolean,
+    allEvent?: (name: string, ...value: any[]) => void
 }
 
 function changeRatio() {
@@ -107,6 +108,7 @@ export function useEmrInit(
     return new Promise((resolve, reject) => {
         // @ts-ignore
         if (div['emr']) {
+            // @ts-ignore
             div.querySelector('iframe').remove()
         }
 
@@ -192,7 +194,17 @@ export function useEmrInit(
 
                 if (options && options.event) {
                     for (const key in options.event) {
-                        editor.on(key, options.event[key])
+                        if (options && options.allEvent) {
+                            editor.on(key, function (...val) {
+                                // @ts-ignore
+                                options!.allEvent(key, val)
+                                // @ts-ignore
+                                options!.event[key](...val)
+                            })
+                        } else {
+                            editor.on(key, options.event[key])
+                        }
+
                     }
                 }
 

+ 629 - 0
src/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/EmrScriptTest.vue

@@ -0,0 +1,629 @@
+<template>
+  <div>
+    asd
+  </div>
+</template>
+
+<script setup>
+
+import XEUtils from "xe-utils";
+
+const editor = {
+  getDataElements: function (...val) {
+    return {
+      "肠鸣音": {
+        "id": "Z2M-fdd1oB0Q",
+        "value": [
+          {
+            "code": "01",
+            "name": "减弱,约2次/分"
+          }
+        ],
+        "format": null,
+        "element": {
+          "id": "8dffa750ebea11edbdbb6bac0cf7ed17",
+          "type": "element",
+          "name": "肠鸣音",
+          "code": {
+            "business": "肠鸣音",
+            "internal": "",
+            "dataElement": ""
+          }
+        }
+      },
+      "胸廓": {
+        "id": "ZOo8dJtqV_d",
+        "value": [
+          {
+            "code": "02",
+            "name": "桶状胸"
+          }
+        ],
+        "format": null,
+        "element": {
+          "id": "c132a700eb1b11ed85056b28bb063824",
+          "type": "element",
+          "name": "胸廓",
+          "code": {
+            "business": "胸廓",
+            "internal": "",
+            "dataElement": ""
+          },
+          "labels": [
+            ""
+          ]
+        }
+      },
+      "心浊音界": {
+        "id": "e3RPAODf2RBeL",
+        "value": [
+          {
+            "code": "01",
+            "name": "正常"
+          }
+        ],
+        "format": null,
+        "element": {
+          "id": "6adf7460ebc411edbdbb6bac0cf7ed17",
+          "type": "element",
+          "name": "心浊音界",
+          "code": {
+            "business": "心浊音界",
+            "internal": "",
+            "dataElement": ""
+          },
+          "labels": [
+            ""
+          ]
+        }
+      },
+      "麦氏点": {
+        "id": "Z5fgBAcDSYi3",
+        "value": [
+          {
+            "code": "01",
+            "name": "无压痛"
+          }
+        ],
+        "format": null,
+        "element": {
+          "id": "540f1240ebe711edbdbb6bac0cf7ed17",
+          "type": "element",
+          "name": "麦氏点",
+          "code": {
+            "business": "麦氏点",
+            "internal": "",
+            "dataElement": ""
+          }
+        }
+      },
+      "腹部压痛": {
+        "id": "Y9VZ_og4TCIK",
+        "value": [
+          {
+            "code": "01",
+            "name": "无压痛"
+          }
+        ],
+        "format": null,
+        "element": {
+          "id": "de69fb90ebe111edbdbb6bac0cf7ed17",
+          "type": "element",
+          "name": "腹部压痛",
+          "code": {
+            "business": "腹部压痛",
+            "internal": "",
+            "dataElement": ""
+          }
+        }
+      },
+      "四肢活动度": {
+        "id": "nk4uB_LGCgmA",
+        "value": [
+          {
+            "code": "01",
+            "name": "活动度正常"
+          }
+        ],
+        "format": null,
+        "element": {
+          "id": "5a35d280ed4011edbdfa8b45d3db89d3",
+          "type": "element",
+          "name": "四肢活动度",
+          "code": {
+            "business": "四肢活动度",
+            "internal": "",
+            "dataElement": ""
+          },
+          "labels": [
+            ""
+          ]
+        }
+      },
+      "淋巴结": {
+        "id": "s8NAMJcd2Ip",
+        "value": [
+          {
+            "code": "01",
+            "name": "全身浅表淋巴结未触及肿"
+          }
+        ],
+        "format": null,
+        "element": {
+          "id": "7f233aa0eb1111edbc373d3487e63c1b",
+          "type": "element",
+          "name": "淋巴结",
+          "code": {
+            "business": "淋巴结",
+            "internal": "",
+            "dataElement": ""
+          },
+          "labels": [
+            ""
+          ]
+        }
+      },
+      "皮肤黏膜": {
+        "id": "Ngrz5EqDMeR",
+        "value": [
+          {
+            "code": "01",
+            "name": "正常"
+          }
+        ],
+        "format": null,
+        "element": {
+          "id": "62fc73f0e95411eda5033b03435677ca",
+          "type": "element",
+          "name": "皮肤黏膜",
+          "code": {
+            "business": "皮肤黏膜",
+            "internal": "",
+            "dataElement": ""
+          },
+          "labels": [
+            ""
+          ]
+        }
+      },
+      "粉尘接触史": {
+        "id": "Ngrz5EqDMeR",
+        "value": [
+          {
+            "code": "01",
+            "name": "正常"
+          }
+        ],
+        "format": null,
+        "element": {
+          "id": "62fc73f0e95411eda5033b03435677ca",
+          "type": "element",
+          "name": "皮肤黏膜",
+          "code": {
+            "business": "皮肤黏膜",
+            "internal": "",
+            "dataElement": ""
+          },
+          "labels": [
+            ""
+          ]
+        }
+      },
+      "入院诊断": {
+        "id": "xan6jyKPFi",
+        "value": [
+          {
+            "code": "K56.100",
+            "name": "慢性阻塞性肺病伴有急性加重",
+            "showExtraDisplay": "慢性阻塞性肺病伴有急性加重"
+          },
+          {
+            "code": "J62.100",
+            "name": "慢性阻塞性肺病伴有急性加重",
+            "showExtraDisplay": "慢性阻塞性肺病伴有急性加重"
+          }
+        ],
+        "format": null,
+        "element": {
+          "id": "278b04a054fb11eda5682b9e7526e088",
+          "type": "element",
+          "name": "入院诊断",
+          "code": {
+            "business": "入院诊断",
+            "internal": "入院诊断",
+            "dataElement": ""
+          },
+          "labels": [
+            ""
+          ]
+        }
+      }
+    }
+  }
+}
+
+const current = {}
+const patInfo = {}
+
+function setMsg(value) {
+  console.log(value)
+}
+
+function newFunc() {
+  const diagList = [
+    {
+      "codeList": [
+        "K56%"
+      ],
+      "main": true,
+      "contrast": "肠鸣音",
+      "equals": "01",
+      "msg": "肠梗阻患者,请注意肠鸣音的描述。",
+      "level": 'warn'
+    },
+    {
+      "codeList": [
+        "J62%"
+      ],
+      "main": false,
+      "contrast": "粉尘接触史",
+      "equals": "01",
+      "msg": "矽肺患者,请认真询问粉尘接触史。",
+      "level": 'warn'
+    },
+    {
+      "codeList": [
+        "J44%"
+      ],
+      "main": false,
+      "contrast": "吸烟史",
+      "equals": "01",
+      "msg": "慢支、慢阻肺患者,请认真询问吸烟史。",
+      "level": 'warn'
+    },
+    {
+      "codeList": [
+        "J44.1%",
+        "J44.9%"
+      ],
+      "main": false,
+      "contrast": "胸廓",
+      "equals": "01",
+      "msg": "慢阻肺患者,请注意胸廓形态等相关体格检查。",
+      "level": 'warn'
+    },
+    {
+      "codeList": [
+        "I51.700x009"
+      ],
+      "main": false,
+      "contrast": "心浊音界",
+      "equals": "01",
+      "msg": "心脏扩大的患者,请注意体格检查中心浊音界的描述。",
+      "level": 'warn'
+    },
+    {
+      "codeList": [
+        "Z90%"
+      ],
+      "main": false,
+      "contrast": "手术史",
+      "equals": "01",
+      "msg": "患者为术后状态,请完善手术史相关记录。",
+      "level": 'warn'
+    },
+    {
+      "codeList": [
+        "K35%"
+      ],
+      "main": false,
+      "contrast": "麦氏点",
+      "equals": "01",
+      "msg": "患者有急性阑尾炎相关诊断,请注意体格检查麦氏点压痛。",
+      "level": 'warn'
+    },
+    {
+      "codeList": [
+        "K81.000",
+        "K81.007",
+        "K81.006",
+        "K81.004",
+        "K81.003",
+        "K81.005"
+      ],
+      "main": false,
+      "contrast": "腹部压痛",
+      "equals": "01",
+      "msg": "患者有急性胆囊相关疾患,请注意体格检查腹部压痛、墨菲氏征等的描述。",
+      "level": 'warn'
+    },
+    {
+      "codeList": [
+        "G82%"
+      ],
+      "main": false,
+      "contrast": "四肢活动度",
+      "equals": "01",
+      "msg": "截瘫患者,请注意肢体活动的相关描述和记录。",
+      "level": 'warn'
+    },
+    {
+      "codeList": [
+        "Z51.500x003"
+      ],
+      "main": false,
+      "contrast": "淋巴结",
+      "equals": "01",
+      "msg": "恶性肿瘤终末期患者,请注意淋巴结的相关描述和记录。",
+      "level": 'warn'
+    },
+    {
+      "codeList": [
+        "K83.102",
+        "P78.800x008",
+        "O26.606",
+        "K83.101",
+        "K75.804",
+        "K71.001",
+        "K71.000x002",
+        "E80.600x008",
+        "E80.600x001"
+      ],
+      "main": false,
+      "contrast": "皮肤黏膜",
+      "equals": "01",
+      "msg": "患者存在胆汁淤积,请注意皮肤巩膜的相关描述。",
+      "level": 'warn'
+    }
+  ]
+
+  const tempData = editor.getDataElements('business', false, true)
+  if (tempData === null && XEUtils.isEmpty(tempData)) {
+    return;
+  }
+
+  if (current.tempData === tempData) {
+    return;
+  }
+
+  current['tempData'] = tempData
+
+  function codeLike(currentCode, equalsCode) {
+    if (equalsCode.endsWith("%")) {
+      const str = equalsCode.substring(0, equalsCode.length - 1);
+      return currentCode.startsWith(str);
+    } else if (equalsCode.startsWith("%")) {
+      const str = equalsCode.substring(1);
+      return currentCode.endsWith(str);
+    }
+    return currentCode === equalsCode;
+  }
+
+  function select(contrast, equals) {
+    return XEUtils.get(tempData[contrast], 'value[0].code') === equals
+  }
+
+  const msgList = {}
+
+  function pushMsg(key, msg) {
+    const id = tempData[key].id
+    msg["id"] = id
+
+    if (msgList[key]) {
+      msgList[key].push(msg)
+    } else {
+      msgList[key] = [msg]
+    }
+  }
+
+  diagList.forEach(item => {
+    const {main, codeList, contrast, equals, msg, level} = item
+    if (main) {
+      codeList.forEach(s => {
+        if (codeLike(codeList[0], s) && select(contrast, equals)) {
+          pushMsg(contrast, {message: msg, level, label: contrast})
+        }
+      })
+    } else {
+      const emrDiag = XEUtils.get(tempData, '入院诊断.value')
+      if (emrDiag === null && !XEUtils.isArray(emrDiag)) {
+        return
+      }
+      codeList.forEach(s => {
+        emrDiag.forEach(codeName => {
+          if (codeLike(codeName.code, s) && select(contrast, equals)) {
+            pushMsg(contrast, {message: msg, level, label: contrast})
+          }
+        })
+      })
+    }
+  })
+
+  setMsg(msgList)
+
+}
+
+newFunc()
+
+function newFuncStr() {
+  const str = `
+   const diagList = [
+    {
+      "codeList": [
+        "K56%"
+      ],
+      "main": true,
+      "contrast": "肠鸣音",
+      "equals": "01",
+      "msg": "肠梗阻患者,请注意肠鸣音的描述。"
+    },
+    {
+      "codeList": [
+        "J62%"
+      ],
+      "main": false,
+      "contrast": "粉尘接触史",
+      "equals": "01",
+      "msg": "矽肺患者,请认真询问粉尘接触史。"
+    },
+    {
+      "codeList": [
+        "J44%"
+      ],
+      "main": false,
+      "contrast": "吸烟史",
+      "equals": "01",
+      "msg": "慢支、慢阻肺患者,请认真询问吸烟史。"
+    },
+    {
+      "codeList": [
+        "J44.1%",
+        "J44.9%"
+      ],
+      "main": false,
+      "contrast": "胸廓",
+      "equals": "01",
+      "msg": "慢阻肺患者,请注意胸廓形态等相关体格检查。"
+    },
+    {
+      "codeList": [
+        "I51.700x009"
+      ],
+      "main": false,
+      "contrast": "心浊音界",
+      "equals": "01",
+      "msg": "心脏扩大的患者,请注意体格检查中心浊音界的描述。"
+    },
+    {
+      "codeList": [
+        "Z90%"
+      ],
+      "main": false,
+      "contrast": "手术史",
+      "equals": "01",
+      "msg": "患者为术后状态,请完善手术史相关记录。"
+    },
+    {
+      "codeList": [
+        "K35%"
+      ],
+      "main": false,
+      "contrast": "麦氏点",
+      "equals": "01",
+      "msg": "患者有急性阑尾炎相关诊断,请注意体格检查麦氏点压痛。"
+    },
+    {
+      "codeList": [
+        "K81.000",
+        "K81.007",
+        "K81.006",
+        "K81.004",
+        "K81.003",
+        "K81.005"
+      ],
+      "main": false,
+      "contrast": "腹部压痛",
+      "equals": "01",
+      "msg": "患者有急性胆囊相关疾患,请注意体格检查腹部压痛、墨菲氏征等的描述。"
+    },
+    {
+      "codeList": [
+        "G82%"
+      ],
+      "main": false,
+      "contrast": "四肢活动度",
+      "equals": "01",
+      "msg": "截瘫患者,请注意肢体活动的相关描述和记录。"
+    },
+    {
+      "codeList": [
+        "Z51.500x003"
+      ],
+      "main": false,
+      "contrast": "淋巴结",
+      "equals": "01",
+      "msg": "恶性肿瘤终末期患者,请注意淋巴结的相关描述和记录。"
+    },
+    {
+      "codeList": [
+        "K83.102",
+        "P78.800x008",
+        "O26.606",
+        "K83.101",
+        "K75.804",
+        "K71.001",
+        "K71.000x002",
+        "E80.600x008",
+        "E80.600x001"
+      ],
+      "main": false,
+      "contrast": "皮肤黏膜",
+      "equals": "01",
+      "msg": "患者存在胆汁淤积,请注意皮肤巩膜的相关描述。"
+    }
+  ]
+
+  const tempData = editor.getDataElements('business', false, true)
+  if (tempData === null && XEUtils.isEmpty(tempData)) {
+    return;
+  }
+
+  if (current.tempData === tempData) {
+    return;
+  }
+
+  current['tempData'] = tempData
+
+  function codeLike(currentCode, equalsCode) {
+    if (equalsCode.endsWith("%")) {
+      const str = equalsCode.substring(0, equalsCode.length - 1);
+      return currentCode.startsWith(str);
+    } else if (equalsCode.startsWith("%")) {
+      const str = equalsCode.substring(1);
+      return currentCode.endsWith(str);
+    }
+    return currentCode === equalsCode;
+  }
+
+  function select(contrast, equals) {
+    return XEUtils.get(tempData[contrast], 'value[0].code') === equals
+  }
+
+  const msgList = []
+
+  diagList.forEach(item => {
+    const {main, codeList, contrast, equals, msg} = item
+    if (main) {
+      codeList.forEach(s => {
+        if (codeLike(codeList[0], s) && select(contrast, equals)) {
+          msgList.push(msg)
+        }
+      })
+    } else {
+      const emrDiag = XEUtils.get(tempData, '入院诊断.value')
+      if (emrDiag === null && !XEUtils.isArray(emrDiag)) {
+        return
+      }
+      codeList.forEach(s => {
+        emrDiag.forEach(codeName => {
+          if (codeLike(codeName.code, s) && select(contrast, equals)) {
+            msgList.push(msg)
+          }
+        })
+      })
+    }
+  })
+
+  console.log(msgList)
+  `
+
+  const func = new Function('editor', 'patInfo', 'current', 'XEUtils', str)
+
+  func(editor, patInfo, current, XEUtils)
+}
+
+</script>
+
+<style>
+
+</style>

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

@@ -271,7 +271,6 @@ import {
   emrTitle,
   getEmrCopy,
   IframeTabs,
-  loadingTime,
   parsingDataElements,
   patientInfo,
   query,
@@ -335,8 +334,6 @@ import {
 import EmrRecycleBin
   from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/components/EmrRecycleBin.vue";
 import {useEmrInit, UseEmrInitReturn} from "@/utils/emr/emr-init-v2";
-import moment from "moment";
-import {formatDateToStr} from "@/utils/moment-utils";
 import {reportQueryCenterApiByGet} from "@/api/base-data/report-center";
 import type {PatientDiagnosisIsCrb} from "@/api/zhu-yuan-yi-sheng/infectious-diseasest";
 import {infectiousDiseasesAreRequired,} from "@/api/zhu-yuan-yi-sheng/infectious-diseasest";
@@ -349,6 +346,7 @@ import emrStore from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medic
 import HuanZheXinXi from "@/components/zhu-yuan-yi-sheng/HuanZheXinXi.vue";
 import CyFlex from "@/components/cy/flex/src/CyFlex.vue";
 import {magicApi} from "@/utils/database/magic-api-request";
+import useEmrScript from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/useEmrScript";
 
 const props = defineProps({
   maxHeight: {
@@ -363,9 +361,20 @@ const editRef = ref(null)
 // 编辑器
 let editor: EditType | null = null
 let runtime: Runtime | null = null
-let editMain: UseEmrInitReturn = {}
+let editMain: UseEmrInitReturn | {} = {}
 let extractData = {}
 
+const {magicScript, allEvent} = useEmrScript({
+  getData: () => {
+    return {
+      editor: editor,
+      patientData: patientData.value
+    }
+  },
+  setMsg: value => {
+    emrMitt.emit('kindReminder', value)
+  }
+})
 
 const emrSocket = ref<{
   clearDocument: () => void;
@@ -382,17 +391,6 @@ let copy = true
 // 侧边栏
 const emrSidebarRef = ref<InstanceType<typeof EmrSidebar> | null>(null)
 
-
-/**
- * <{
- *   changeTemplateType: (val) => void,
- *   queryData: () => void
- *   diseaseDurationRecordTime: (id: string, times: any[]) => void
- * } | null>
- */
-
-// 片段预览
-const emrSnippetRef = ref(null)
 // 是否加载完成了
 const loaded = ref(false)
 // 是否 改变了数据
@@ -453,6 +451,8 @@ const emrMainWidth = () => {
 
 const emrEvent = {
   'loaded': async (_event) => {
+    emrMitt.emit('clearKindReminder')
+    magicScript(categoryCode.value)
     getOutline()
     setEditor();
     loaded.value = false
@@ -553,6 +553,7 @@ const emrEvent = {
   }
 }
 
+
 const saveInputRef = useCompRef(ElInput)
 const saveDialog = ref({
   dialog: false,
@@ -567,13 +568,13 @@ const saveDialog = ref({
     saveDialog.value.err = err
     nextTick(async () => {
       await sleep(200)
-      await saveInputRef.value.focus()
+      await saveInputRef.value!.focus()
     })
   },
   close: () => {
     saveDialog.value.dialog = false
     if (saveDialog.value.err !== null) {
-      saveDialog.value.err(saveDialog.value.name)
+      saveDialog.value!.err(saveDialog.value!.name)
     }
     saveDialog.value.clear()
   },
@@ -1183,13 +1184,12 @@ const courseSegmentLocking = async () => {
       emrDocumentId: getId(),
       emrCategoryCode: categoryCode.value,
       jump: true,
-      createName: parsingDataElements(value, '编辑者', 'name'),
+      createName: XEUtils.get(value, '编辑者.value[0].name'),
       createDate: value['查房时间']?.value,
-      createId: parsingDataElements(value, '编辑者', 'code') || fragment.createId,
+      createId: XEUtils.get(value, '编辑者.value[0].code') || fragment.createId,
       type: 'category',
       trueCreationTime: '',
     }
-
     if (fragment != null) {
       pushData.trueCreationTime = fragment?.creationTime
     }
@@ -1221,7 +1221,7 @@ const courseSegmentLocking = async () => {
       node.view.setDeletable(false);
     }
   })
-  emrSidebarRef.value.diseaseDurationRecordTime(getId(), courseTitles);
+  emrSidebarRef.value!.diseaseDurationRecordTime(getId(), courseTitles);
 }
 
 /**
@@ -1460,7 +1460,7 @@ const rightClickOnRegistration = () => {
     })
   })
 
-  editor.regCtxMenu({
+  editor!.regCtxMenu({
     global: [
       {
         text: '辅助工具',
@@ -1469,7 +1469,7 @@ const rightClickOnRegistration = () => {
       {
         text: '病历提示',
         handler: function (_menu) {
-          popupRef.value.positionChange(null, null, editor.getCursorPosition())
+          popupRef.value?.positionChange(null, null, editor!.getCursorPosition())
         }
       },
     ]
@@ -1479,7 +1479,7 @@ const rightClickOnRegistration = () => {
 let zoom = 1
 const zoomFunc = (val) => {
   zoom += val
-  editor.execute('zoom', {value: zoom})
+  editor!.execute('zoom', {value: zoom})
 }
 
 /**
@@ -1487,6 +1487,9 @@ const zoomFunc = (val) => {
  * @param event
  */
 const monitorPageRefresh = (event) => {
+  if (isDev) {
+    return
+  }
   if (readonlyPattern()) {
     isEditorChange.value = false;
   }
@@ -1718,12 +1721,6 @@ const emrMittInit = () => {
 }
 
 const initEdit = () => {
-  async function timeConsuming(): Promise<void> {
-    const end = moment(new Date())
-    const start = formatDateToStr(loadingTime.value)
-    xcMessage.success(`加载完成耗时${end.diff(start, 'seconds')}秒`)
-  }
-
   const tempData = {
     endpoints: {
       app: "http://172.16.32.160:9205/thyy/api/dataEmr/comp",
@@ -1743,8 +1740,7 @@ const initEdit = () => {
     }
   }
 
-  useEmrInit(editRef.value, {event: emrEvent, appContext: tempData}).then((res) => {
-    timeConsuming();
+  useEmrInit(editRef.value, {event: emrEvent, appContext: tempData, allEvent: allEvent}).then((res) => {
     emrMitt.emit('closeProgress')
     emrStore.mutation.setEditor(res.editor)
     editor = res.editor
@@ -1764,7 +1760,7 @@ const hisSaveEmrInit = () => {
 }
 
 
-let hisSaveEmr: UseEmrInitReturn = {}
+let hisSaveEmr: UseEmrInitReturn | {} = {}
 
 onMounted(async () => {
   doctorLevelFunc()
@@ -1905,6 +1901,7 @@ const 循环病程返回数据元 = (callback) => {
  */
 async function getOutline() {
   try {
+    await Promise.resolve()
     emrStore.mutation.setOutline(editor!.getOutline())
   } catch (e) {
   }

+ 2 - 9
src/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/Home.vue

@@ -58,7 +58,7 @@ import {
   query,
   resolveRoute,
   unlockEnum,
-  patientInfo, loadingTime
+  patientInfo,
 } from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/emr-init";
 import EmrPatientList from "@/components/zhu-yuan-yi-sheng/emr/EmrPatientList.vue";
 import EmrLeaveHospitalPatient from "@/components/zhu-yuan-yi-sheng/emr/EmrLeaveHospitalPatient.vue";
@@ -237,10 +237,6 @@ const listRowClick = async (val) => {
   await routerFunc()
 }
 
-const patientInfoIsShow = (flag, height) => {
-  maxHeight.value = window.innerHeight - height - 24
-}
-
 const 操作指南 = (val) => {
   let fileName = null
   getOperationGuide("住院医生教程").then((res) => {
@@ -291,10 +287,7 @@ onMounted(async () => {
   emrMitt.on('closeProgress', () => {
     progressRef.value.close()
   })
-  loadingTime.value = new Date()
-  if (!isDev) {
-    progressRef.value.start()
-  }
+  progressRef.value.start()
   await nextTick();
   await routerFunc();
 })

+ 1 - 1
src/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/components/emr-right/EmrOutline.vue

@@ -12,7 +12,7 @@ import CyFlex from "@/components/cy/flex/src/CyFlex.vue";
 
 const inputVal = ref('')
 
-const {contentRef, headerRef, style} = useContentHeader()
+const {headerRef, style} = useContentHeader()
 const defaultProps = {
   children: 'children',
   label: 'typeName',

+ 69 - 2
src/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/components/emr-right/EmrRightComp.vue

@@ -7,6 +7,20 @@
       <CyTabPane label="大纲" name="outline">
         <EmrOutline/>
       </CyTabPane>
+      <CyTabPane label="温馨提示" name="kindReminder">
+        <div v-for="(value, key) in kindReminder"
+             class="kindReminder"
+             :class="currentId === value[0].id ?  'activation' : '' "
+             @click="kindReminderClick(value[0].id)">
+          <div class="kindReminder_key">
+            {{ key }}
+          </div>
+          <div v-for="msg in value"
+               :class="`kindReminder_item kindReminder_item-${msg.level}`">
+            {{ msg.message }}
+          </div>
+        </div>
+      </CyTabPane>
     </CyTabs>
   </div>
 </template>
@@ -15,13 +29,14 @@
 import CyTabs from "@/components/cy/tabs/src/CyTabs";
 import CyTabPane from "@/components/cy/tabs/src/CyTabPane.vue";
 import EmrSnippet from "./EmrSnippet.vue";
-import {ref} from 'vue'
+import {Ref, ref} from 'vue'
 import EmrOutline
   from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/components/emr-right/EmrOutline.vue";
 import {
   emrMitt,
   EmrRightTabs
 } from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/emr-init";
+import XEUtils from "xe-utils";
 
 const props = defineProps({
   height: {
@@ -31,14 +46,66 @@ const props = defineProps({
 
 const tabsModel = ref<EmrRightTabs>(EmrRightTabs.fragment)
 
+const kindReminder: Ref<{
+  [key: string]: {
+    message: string,
+    level: 'warn' | 'info' | 'error',
+    label: string,
+    id: string
+  }[]
+}> = ref({})
+
+function kindReminderClick(id: string) {
+  emrMitt.emit('jumpDataElementById', id)
+  currentId.value = id
+}
+
+const currentId = ref('')
+
 onMounted(() => {
   emrMitt.on('changeRightTabs', (val) => {
     tabsModel.value = val
   })
+  emrMitt.on('kindReminder', (val: any) => {
+    kindReminder.value = val
+    if (!XEUtils.isEmpty(val))
+      tabsModel.value = EmrRightTabs.kindReminder
+  })
+  emrMitt.on('clearKindReminder', () => {
+    kindReminder.value = {}
+    currentId.value = ''
+  })
 })
 
 </script>
 
-<style scoped>
+<style lang="scss">
+
+.kindReminder {
+  padding: 5px;
+  box-shadow: var(--el-box-shadow);
+  cursor: pointer;
+
+  &.activation {
+    border: 1px solid #0a2fe7;
+    border-radius: 5px;
+  }
+
+  .kindReminder_key {
+    padding: 5px;
+  }
+
+  .kindReminder_item {
+    padding: 5px;
+  }
+
+  .kindReminder_item-warn {
+    background-color: #e6a23c;
+    color: white;
+    border-radius: 5px;
+  }
+
+}
+
 
 </style>

+ 10 - 38
src/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/emr-init.ts

@@ -365,7 +365,8 @@ export interface Audit {
 
 export enum EmrRightTabs {
     fragment = "fragment",
-    outline = "outline"
+    outline = "outline",
+    kindReminder = 'kindReminder'
 }
 
 export interface EmrMitt {
@@ -392,6 +393,8 @@ export interface EmrMitt {
     clickSnippet: (data) => void
     changeElementById: (id: string) => void;
     changeRightTabs: (value: EmrRightTabs) => void
+    kindReminder: (value: any) => void
+    clearKindReminder: () => void
 }
 
 //@ts-ignore
@@ -450,32 +453,17 @@ export const patientInfo = ref<EmrPatient>({
     finalControl: 0
 })
 
-export const loadingTime = ref<any>(null)
-
-export function parsingDataElements(data: any, name: string, codeName: string | 'code' | 'name' = 'code'): null | string {
-    function isNullAndUndefined(value: any) {
-        return value === null || typeof value === 'undefined';
+export function parsingDataElements(data: any, path: string): null | string {
+    const value = XEUtils.get(data, name + '.value')
+    if (value === null) {
+        return null
     }
-
-    if (isNullAndUndefined(data)) return null;
-    if (isNullAndUndefined(data[name])) return null;
-    if (isNullAndUndefined(data[name].value)) return null;
-    const value = data[name].value
     if (XEUtils.isArray(value)) {
-        try {
-            return value[0][codeName]
-        } catch {
-            return null;
-        }
+        return XEUtils.get(value, '[0].' + codeName)
     }
 
-
     if (XEUtils.isObject(value)) {
-        try {
-            return value[codeName]
-        } catch {
-            return null;
-        }
+        return XEUtils.get(value, codeName)
     }
 
     return null
@@ -489,25 +477,9 @@ export enum IframeTabs {
     "审核",
 }
 
-export function btnIframeTabs(tabs: IframeTabs, current: number): "default" | "primary" {
-    if (tabs === current) {
-        return 'primary'
-    }
-    return 'default'
-}
 
 export const showIframe = ref(IframeTabs.正在编辑)
 
-export const vIframeTabs = {
-    mounted: (el: HTMLHtmlElement, binding, vnode, prevVnod) => {
-        el.addEventListener('click', () => {
-            showIframe.value = binding.value
-        })
-    },
-    updated: (el, binding, vnode, prevVnod) => {
-        vnode.ref.i.props.type = showIframe.value === binding.value ? 'primary' : 'default'
-    },
-}
 
 export function showIframeIsList(...val: number[]) {
     return val.includes(showIframe.value)

+ 72 - 0
src/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/useEmrScript.ts

@@ -0,0 +1,72 @@
+import {magicApi} from "@/utils/database/magic-api-request";
+import {xcMessage} from "@/utils/xiaochan-element-plus";
+import XEUtils from "xe-utils";
+
+function useEmrScript(props: { getData: () => any, setMsg: (value: any[]) => void }) {
+    let emrScript: {
+        onStr: string;
+        on: {
+            [key: string]: {
+                scriptStr: string,
+                script: any
+            }
+        }
+    } = {
+        onStr: '',
+        on: {},
+    };
+
+    function clear() {
+        emrScript.onStr = ""
+        emrScript.on = {}
+    }
+
+    async function magicScript(code: string) {
+        clear()
+        if (code === '') {
+            return
+        }
+        await magicApi({
+            method: 'get',
+            url: `/intergration/cyEmr/script/${code}`
+        }).then(res => {
+            emrScript.onStr = res
+            for (const key in res || {}) {
+                try {
+                    emrScript.on[key] = {
+                        scriptStr: '',
+                        script: null
+                    }
+                    emrScript.on[key].scriptStr = res[key]
+                    emrScript.on[key].script = new Function('editor', 'patInfo', 'current', 'XEUtils', 'setMsg', res[key])
+                } catch (e) {
+                    console.error(e)
+                    xcMessage.error('脚本执行失败请联系管理员')
+                }
+            }
+        }).catch(() => {
+
+        })
+    }
+
+    async function allEvent(key: string, val: any) {
+        if (XEUtils.isEmpty(emrScript.on)) {
+            return
+        }
+        const data = props.getData()
+        const {editor, patientData} = data
+        if (XEUtils.isObject(emrScript.on)) {
+            if (emrScript.on[key]) {
+                emrScript.on[key].script(editor, patientData, emrScript.on[key], XEUtils, props.setMsg)
+            }
+        }
+    }
+
+    return {
+        magicScript,
+        allEvent
+    }
+
+}
+
+export default useEmrScript