浏览代码

优化规则提示以及搜索医嘱时多次点击取消上一次的请求

xiaochan 2 年之前
父节点
当前提交
299486fd9a

+ 8 - 1
src/api/zhu-yuan-yi-sheng/yi-zhu-lu-ru.ts

@@ -92,10 +92,17 @@ export function huoQuYiZhuShuJu(data) {
     })
 }
 
-export function huoQuXiangMu(code, groupNo) {
+
+let huoQuXiangMuSignal = null;
+
+export function huoQuXiangMu(code: string, groupNo: string) {
+    huoQuXiangMuSignal && huoQuXiangMuSignal.abort();
+    huoQuXiangMuSignal = new AbortController();
+
     return requestV2({
         url: url + '/huoQuXiangMu',
         method: 'get',
+        signal: huoQuXiangMuSignal.signal,
         params: {code, groupNo},
     })
 }

+ 10 - 1
src/components/zhu-yuan-yi-sheng/yi-zhu-lu-ru/yz-edit/YzEditor.vue

@@ -487,7 +487,7 @@ const itemDefaultValue = (isSearch: boolean, data: SearchOrdersType | YzType) =>
   setYzData('kjywFlag', 0)
   const queryKey = feeKey(data.orderCode, '00', props.patientInfo.zkWard, queryParam.value.groupNo, yiZhuData.value.superiorDoctor, yiZhuData.value.statusFlag)
   const {
-    prompt,
+    prompt
   }: FeeInfo = huoQuFeiYongXinXi(queryKey).catch(() => {
     clearAndErrorMessage('请联系管理员。')
   })
@@ -497,6 +497,11 @@ const itemDefaultValue = (isSearch: boolean, data: SearchOrdersType | YzType) =>
   if (isSearch) {
     setYzData('dose', 1)
     setYzData('supplyCode', null)
+
+  }
+
+  if (yiZhuData.value.statusFlag === '1') {
+    openTheOrderPopUpWindow()
   }
 
   if (!yiZhuData.value.frequCode) {
@@ -546,6 +551,10 @@ const defaultAll = async (isSearch: boolean, data: SearchOrdersType | YzType) =>
     })
   }
 
+  if (queryParam.value.frequCode === frequCodeEnum.temporary) {
+    setYzData('frequCode', 'ONCE')
+  }
+
   // 如果搜索了医嘱那么 这里就需要 重新赋值,不认表格就没办法变化了,把原来的换掉
   if (isSearch) {
     for (let i = yzData.value.length - 1; i >= 0; i--) {

+ 1 - 1
src/utils/find-name-by-list-code.ts

@@ -21,7 +21,7 @@ const defaultValue: Option = {
  */
 const findValueByListCode = (arr: any[] | object, code: string | number, option: Option = defaultValue): string => {
     const {listCode, listValue} = option
-    if (XEUtils.isEmpty(arr)) {
+    if (typeof arr === 'undefined' || arr === null) {
         return '';
     }
 

+ 6 - 0
src/utils/request.js

@@ -51,6 +51,7 @@ service.interceptors.request.use(
 
 service.interceptors.response.use(
     (response) => {
+
         endLoading()
         store.commit('app/closeButton', true)
         if (response.data.code === 200 || response.data.code === 0) {
@@ -135,6 +136,11 @@ service.interceptors.response.use(
     },
     (error) => {
         endLoading()
+        // 取消请求,不显示 message
+        if (error.code && error.code === 'ERR_CANCELED') {
+            store.commit('app/setJdt', {title: '', isOpen: false, closeButton: true})
+            return Promise.reject(error)
+        }
         ElMessage({
             message: error,
             type: 'error',

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

@@ -264,6 +264,7 @@
 
   </div>
   <EmrRefreshDialog/>
+  <EmrSaveRules ref="emrSaveRulesRef"/>
 </template>
 
 <script setup lang="ts">
@@ -300,7 +301,7 @@ import EmrPopup from "@/components/zhu-yuan-yi-sheng/emr/EmrPopup.vue";
 import EmrAuxiliaryTools from "@/components/zhu-yuan-yi-sheng/emr/auxiliary-tools/EmrAuxiliaryTools.vue";
 import sleep from "@/utils/sleep";
 import EmrWebSocket from "@/components/zhu-yuan-yi-sheng/emr/web-socket/EmrWebSocket.vue";
-import {stringIsBlank} from "@/utils/blank-utils";
+import {stringIsBlank, stringNotBlank} from "@/utils/blank-utils";
 import {isDev} from "@/utils/public";
 import {forcedKickingOutOfPersonnelByDocumentId, isThereADoctorEditing} from "@/api/zhu-yuan-yi-sheng/emr-socket";
 import {computed, nextTick, onDeactivated, onMounted, ref, watch} from "vue";
@@ -334,6 +335,8 @@ import {
   EditType,
   EditorMode
 } from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/edit";
+import EmrSaveRules
+  from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/components/EmrSaveRules.vue";
 
 const props = defineProps({
   huanZheXinXi: {
@@ -692,6 +695,10 @@ const forceTheRecipientToBeKickedOut = (forceRefreshUserInfo: string) => {
   })
 }
 
+const emrSaveRulesRef = ref<{
+  validData: (data: any) => void,
+  close: () => void
+}>()
 
 // 点击保存病历
 const clickSaveData = async () => {
@@ -704,21 +711,23 @@ const clickSaveData = async () => {
   if (editor === null) return
   // 判断是否有必填项目
   waitForLoadingToComplete()
-  const documentSocket = emrMitt.emit('getDocumentSocket')
-  if (documentSocket === null) {
-    await ElMessageBox.alert('和服务区断开连接无法保存', '提示', {
-      type: 'warning'
-    })
-    return
+  if (stringNotBlank(editor.documentData._id)) {
+    const documentSocket = emrMitt.emit('getDocumentSocket')
+    if (documentSocket === null) {
+      await ElMessageBox.alert('未连接上服务器,无法保存', '提示', {
+        type: 'warning'
+      })
+      return
+    }
   }
 
-
   try {
+    emrSaveRulesRef.value.close()
     const validator = editor.getValidator();
-    const valid = validator.valid();
+    const valid = validator.valid(true);
 
     if (valid) {
-      xcMessage.error("有必填项不能为空,请仔细检查,红色输入框。")
+      emrSaveRulesRef.value.validData(valid)
       return
     }
   } catch {
@@ -1592,6 +1601,10 @@ const emrMittInit = () => {
     return editor
   })
 
+  emrMitt.on('getIframe', () => {
+    return emrRef.value
+  })
+
   emrMitt.on('setShowIframe', (val, id) => {
     showIframe.value = val
     if (id) {
@@ -1599,6 +1612,8 @@ const emrMittInit = () => {
     }
   })
 
+  emrMitt.on('clickSaveData', clickSaveData)
+
   emrMitt.on("forceRefresh", forceTheRecipientToBeKickedOut)
   emrMitt.on('queryHistoryFunc', queryHistoryFunc)
   emrMitt.on('loadDocument', () => {

+ 187 - 0
src/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/components/EmrSaveRules.vue

@@ -0,0 +1,187 @@
+<script setup lang="ts">
+import {ref} from "vue";
+import {useDraggable} from '@vueuse/core'
+import {
+  emrMitt,
+} from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/emr-init";
+import {EditType} from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/edit";
+
+interface Item {
+  name: string;
+  level: "warn" | "error";
+  message: string;
+}
+interface Element {
+  id: string;
+  type: "element";
+  name: string;
+  code: {
+    business: string;
+    internal: string;
+    dataElement: string;
+  };
+  labels: string[];
+}
+
+interface Data {
+  base: Item[];
+  rules: any[]; // 这里暂时将 rules 设置为 any[],可根据实际情况进行调整
+  id: string;
+  code: string;
+  element: Element;
+}
+
+const rulesData = ref<Data[]>([])
+const isShow = ref(false)
+const ruleDrugRef = ref<HTMLDivElement>()
+
+const {x, y, style} = useDraggable(ruleDrugRef, {
+  initialValue: {x: 20, y: 20}
+})
+
+const validData = (data: Data[]) => {
+  isShow.value = true
+  rulesData.value = data
+}
+
+const liClick = (data: Data) => {
+  const iframe: HTMLIFrameElement = emrMitt.emit('getIframe')
+  const edit: EditType = emrMitt.emit('editor')
+  const componentView: {
+    view: {
+      focusEnter: () => void
+    } & HTMLElement,
+  } = iframe.contentDocument.getElementById(data.id) as any
+
+  if (edit && edit.view) {
+    componentView.view.focusEnter()
+    edit.highlight(componentView.view, 1500)
+    edit.scrollToCursor(true)
+  }
+
+}
+
+const getName = (val: Data) => {
+  if (val.element && val.element.name) {
+    return '数据元:' + val.element.name
+  }
+  return ''
+}
+
+const close = () => {
+  isShow.value = false
+}
+
+defineExpose({
+  validData,
+  close
+})
+</script>
+
+<template>
+  <div class="emr_rule_box" :style="style" v-show="isShow">
+    <div class="emr_rule_drug_header" ref="ruleDrugRef">
+      请检查
+      <div class="close" @click="isShow = false">
+        <el-icon>
+          <Close/>
+        </el-icon>
+      </div>
+    </div>
+    <div class="rules_main">
+      <ul>
+        <li v-for="item in rulesData" class="rule_li" @click="liClick(item)">
+          {{ getName(item) }}
+          <div style="height: 5px"></div>
+          <div v-for="base in item.base" :class="base.level" class="base">
+            {{ base.message }}
+          </div>
+        </li>
+      </ul>
+    </div>
+    <div class="rules_button">
+      <div style="color: var(--el-color-danger)">注:遇到格式错误,删了重写。</div>
+      <div>
+        <el-button type="primary"
+                   style="margin-right: 10px"
+                   @click="emrMitt.emit('clickSaveData')">
+          重新保存
+        </el-button>
+      </div>
+    </div>
+  </div>
+</template>
+
+<style scoped lang="scss">
+.emr_rule_box {
+  position: fixed;
+  height: 400px;
+  width: 300px;
+  background-color: white;
+  z-index: 10;
+  box-sizing: border-box;
+  box-shadow: 0 4px 8px rgb(0 0 0 / 20%), 0 6px 20px rgb(0 0 0 / 19%);
+  border-radius: 5px;
+
+  .emr_rule_drug_header {
+    width: 100%;
+    touch-action: none;
+    line-height: 30px;
+    box-sizing: border-box;
+    border-bottom: 1px solid #000;
+    text-align: center;
+    cursor: move;
+    position: relative;
+
+    .close {
+      display: grid;
+      align-content: center;
+      justify-content: center;
+      position: absolute;
+      box-sizing: border-box;
+      right: 0;
+      height: 30px;
+      top: 0;
+      width: 40px;
+      cursor: pointer;
+    }
+  }
+
+  .rule_li {
+    box-sizing: border-box;
+    margin: 5px;
+    padding: 10px;
+    background: var(--el-color-primary-light-9);
+    color: var(--el-color-primary);
+    border-radius: 5px;
+
+    .base {
+      box-sizing: border-box;
+      padding: 10px;
+    }
+
+    .warn {
+      background: var(--el-color-warning-light-9);
+      color: var(--el-color-warning);
+    }
+  }
+
+  .rules_main {
+    height: calc(100% - 30px - 30px);
+    overflow: auto;
+
+    &::-webkit-scrollbar {
+      width: 12px;
+    }
+
+  }
+
+  .rules_button {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    box-sizing: border-box;
+    margin: 0 5px;
+  }
+}
+</style>

+ 17 - 3
src/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/edit.ts

@@ -68,6 +68,12 @@ export declare type EditType = {
 
     getEditorMode: () => EditorMode;
 
+    highlight: (comp: HTMLElement, time: number) => void;
+
+    getElementByValue: (id: string) => any;
+
+    view: HTMLElement;
+
     ModelService: {
         setWalkerRoot: (walker: any, node: any) => any;
         createTreeWalker: (node: any) => any;
@@ -78,7 +84,12 @@ export declare type EditType = {
     setEditorMode: (val: EditorMode) => void;
 
     getValidator: () => {
-        valid: () => Validator[]
+
+        /**
+         *
+         * @param val 是否显示节点信息 , 默认值 false
+         */
+        valid: (val: boolean) => Validator[]
     };
 
     /**
@@ -133,7 +144,7 @@ export declare type EditType = {
      *
      * @param middle middle 当光标在可视区域后方时,是否滚动到屏幕中间 默认false
      */
-    scrollToCursor: (...middle: string[]) => void;
+    scrollToCursor: (...middle: boolean[]) => void;
 
     model: {
         document: {
@@ -183,7 +194,10 @@ export declare type EditType = {
      * view: 当前光标或者选区开始所在位置的组件view
      * position: {x ,y} 光标或者选区开始位置坐标(相对于文档,内部通过getBoundingClientRect()方法获取)
      */
-    setShortcutKey: (keyName: string, callback: (e: Event, view: any, position: { x: number, y: number }) => void) => void;
+    setShortcutKey: (keyName: string, callback: (e: Event, view: any, position: {
+        x: number,
+        y: number
+    }) => void) => void;
 
     /**
      * 注册右键菜单

+ 21 - 2
src/views/settings/Test.vue

@@ -1,8 +1,27 @@
 <template>
-  <PatientDistribution/>
 </template>
 
 <script setup lang="ts">
+import {huoQuXiangMu} from "@/api/zhu-yuan-yi-sheng/yi-zhu-lu-ru";
+import {onMounted} from "vue";
+import sleep from "@/utils/sleep";
+
+
+onMounted(async () => {
+  huoQuXiangMu('12', '73').then((res) => {
+    console.log('12 then', res)
+  }).catch((res) => {
+    console.log('12 catch', res)
+  })
+
+  await sleep(500)
+
+  huoQuXiangMu('23', '73').then((res) => {
+    console.log('23 then', res)
+  }).catch((res) => {
+    console.log('23 catch', res)
+  })
+})
+
 
-import PatientDistribution from "@/views/reports/patient-distribution/patient-distribution.vue";
 </script>