Browse Source

电子病历提示

DESKTOP-0GD05B0\Administrator 2 years ago
parent
commit
6995b21d54

+ 50 - 0
src/api/zhu-yuan-yi-sheng/emr-patient.js

@@ -198,5 +198,55 @@ export function getHistory(documentId) {
     })
 }
 
+export function getEmrTips() {
+    return request({
+        url: url + 'getEmrTips',
+        method: 'get',
+    })
+}
+
+export function addEmrTips(data) {
+    return request({
+        url: url + 'addEmrTips',
+        method: 'post',
+        data
+    })
+}
+
+export function updateEmrTips(data) {
+    return request({
+        url: url + 'updateEmrTips',
+        method: 'post',
+        data
+    })
+}
+
+export function deleteEmrTips(id) {
+    return request({
+        url: url + 'deleteEmrTips',
+        method: 'get',
+        params: {id}
+    })
+}
+
+export function getEmrTipsData(name) {
+    return request({
+        url: url + 'getEmrTipsData',
+        method: 'get',
+        params: {name}
+    })
+}
+
+export function hotSearchSorting(userCode, code, tableName,) {
+    return request({
+        url: url + 'hotSearchSorting',
+        method: 'get',
+        params: {userCode, code, tableName}
+    })
+}
+
+
+
+
 
 

+ 0 - 1
src/components/med-tec-mod/HuoQuMuBan.vue

@@ -13,7 +13,6 @@
               </template>
               <!-- 这里是弹出框中的数据 -->
               <xc-table :data="muBanXiangQing" :height="170"
-
                         @selection-change="xuanZeXiangMuTable" :open-paging="false">
                 <el-table-column type="selection"></el-table-column>
                 <el-table-column label="项目名称" prop="chargeName"></el-table-column>

+ 7 - 2
src/components/xiao-chan/combo-grid/XcComboGrid.vue

@@ -104,7 +104,7 @@ const props = defineProps({
   }
 })
 
-const emit = defineEmits(['input', 'rowClick', 'clear', 'focus'])
+const emit = defineEmits(['input', 'rowClick', 'clear', 'focus', 'blur'])
 
 const placeholder = ref(props.placeholder)
 const inputData = ref('')
@@ -258,6 +258,7 @@ const highlightRow = async () => {
 }
 
 const inputBlur = () => {
+  emit('blur')
   isFocus.value = false
   if (isObj) {
     inputData.value = props.modelValue[props.name]
@@ -297,6 +298,9 @@ const inputRef = ref()
 const focus = () => {
   inputRef.value.focus()
 }
+const blur = () => {
+  inputRef.value.blur()
+};
 
 const isObj = typeof props.modelValue === 'object'
 onMounted(() => {
@@ -326,7 +330,8 @@ onMounted(() => {
 })
 
 defineExpose({
-  focus
+  focus,
+  blur
 })
 
 </script>

+ 73 - 0
src/components/zhu-yuan-yi-sheng/emr/EmrPopup.vue

@@ -0,0 +1,73 @@
+<template>
+  <xc-combo-grid v-model="inputValue"
+                 class="popup-main"
+                 v-show="isShow"
+                 @blur="isShow = false"
+                 ref="gridRef"
+                 :table-header="[]"
+                 :query-data-func="getEmrTipsData"
+                 @rowClick="rowClick">
+    <el-table-column label="内容"
+                     prop="content"
+                     width="600"
+                     show-overflow-tooltip/>
+  </xc-combo-grid>
+</template>
+
+<script setup name='EmrPopup'>
+
+import XcComboGrid from "@/components/xiao-chan/combo-grid/XcComboGrid.vue";
+import {getEmrTipsData} from "@/api/zhu-yuan-yi-sheng/emr-patient";
+
+const emit = defineEmits(['fillData'])
+
+const coordinate = ref({
+  x: '200px',
+  y: '0px'
+})
+
+const isShow = ref(false)
+const inputValue = ref()
+const gridRef = ref()
+
+const positionChange = (evt, view, position) => {
+  console.log(position)
+  position.x = position.x + 2 + 'px'
+  position.y += 'px'
+  coordinate.value = position
+  open()
+  gridRef.value.focus()
+}
+
+const rowClick = (row) => {
+  emit('fillData', row)
+}
+
+const closed = () => {
+  isShow.value = false
+}
+
+const open = () => {
+  isShow.value = true
+}
+
+defineExpose({
+  positionChange,
+  closed,
+  open
+})
+
+
+</script>
+
+<style scoped lang="scss">
+.popup-main {
+  position: absolute;
+  z-index: 99;
+
+  //left: 0;
+  //top: 0;
+  left: v-bind('coordinate.x');
+  top: v-bind('coordinate.y');
+}
+</style>

+ 7 - 0
src/router/modules/dashboard.js

@@ -554,6 +554,13 @@ const route = [
                             title: '申请出院病历编辑',
                         },
                     },
+                    {
+                        path: 'MedicalHistoryPrompts',
+                        component: createNameComponent(() => import('@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/MedicalHistoryPrompts.vue')),
+                        meta: {
+                            title: '病历文本提示维护',
+                        },
+                    },
                 ],
             },
         ],

+ 28 - 14
src/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/EmrMain.vue

@@ -132,11 +132,11 @@
               </el-select>
               <el-divider direction="vertical"/>
               <el-button-group>
-                <el-button @click="styleFunc('fontSizeAdjust','increase')"
+                <el-button @click="textStyleFunc.fontSizeAdjust('increase')"
                            title="放大字体">
                   +
                 </el-button>
-                <el-button @click="styleFunc('fontSizeAdjust','decrease')"
+                <el-button @click="textStyleFunc.fontSizeAdjust('decrease') "
                            title="缩小字体">
                   -
                 </el-button>
@@ -251,6 +251,8 @@
           </el-scrollbar>
         </div>
         <div class="emr-iframe">
+          <emr-popup ref="popupRef"
+                     @fill-data="popupFunc.fillData"/>
           <iframe ref="emrRef"
                   :height="maxHeight - 100 + 'px' "
                   :src="caseHistoryUrl"/>
@@ -287,10 +289,10 @@ import {BizException, ExceptionEnum} from "@/utils/BizException";
 import EmrSnippet from "@/components/zhu-yuan-yi-sheng/emr/EmrSnippet.vue";
 import store from "@/store";
 import {onBeforeRouteLeave} from "vue-router";
-import {getUuid} from "@/api/public-api";
+import {getServerDateApi, getUuid} from "@/api/public-api";
 import {
   getDrgIntelligentGrouping,
-  getExtractDataElement,
+  getExtractDataElement, hotSearchSorting,
   submitMedicalRecord
 } from "@/api/zhu-yuan-yi-sheng/emr-patient";
 import {useDocumentVisibility} from "@vueuse/core";
@@ -301,6 +303,7 @@ import {xcMessage} from "@/utils/xiaochan-element-plus";
 import EmrUnorderedList from "@/components/zhu-yuan-yi-sheng/emr/EmrUnorderedList.vue";
 import HistoricalEmr from "@/components/zhu-yuan-yi-sheng/emr/HistoricalEmr.vue";
 import {stringIsBlank} from "@/utils/blank-utils";
+import EmrPopup from "@/components/zhu-yuan-yi-sheng/emr/EmrPopup.vue";
 
 const props = defineProps({
   huanZheXinXi: {
@@ -439,12 +442,11 @@ const emrEvent = {
     emrStyle.color = context.color
     emrStyle.backgroundColor = context.backgroundColor
     emrStyle.paragraphStyle = context.paragraphStyle
-
   },
 
   'ready': (event) => {
     editor = currentEmr.value.getEditor()
-    setShortcutKey()
+    popupFunc.setShortcutKey()
   }
 
 }
@@ -477,9 +479,10 @@ const clickSaveData = async () => {
     inputErrorMessage: '长度为2 - 20 个,汉字',
     inputPattern: /^\S{2,20}$/,
     inputValue: templateName
-  }).then(({value}) => {
+  }).then(async ({value}) => {
     data.name = value
-    currentEmr.value.saveDocument(data).then(res => {
+    let newDate = await getServerDateApi()
+    currentEmr.value.saveDocument(data, newDate).then(res => {
       // 把提取到的数据放到 patientData 中.
       extractData = res
       Object.assign(patientData, res)
@@ -1035,6 +1038,9 @@ const paginationSymbol = () => {
 }
 
 const textStyleFunc = ref({
+  fontSizeAdjust: (val) => {
+    editor.execute('fontSizeAdjust', {value: val})
+  },
   fontFamily: () => {
     editor.execute('fontFamily', {value: emrStyle.fontFamily})
     editor.focus()
@@ -1102,7 +1108,7 @@ const textStyleFunc = ref({
     editor.execute('orderList', {"value": val})
   },
   indent: (val) => {
-    emrStyle.paragraphStyle.specialIndent.value += val
+    emrStyle.paragraphStyle.paragraphIndent.left += val
     editor.execute('paragraphStyle', {value: emrStyle.paragraphStyle})
   }
 })
@@ -1149,11 +1155,18 @@ const restoreData = (data) => {
   recoveryDialog = false
 }
 
-const setShortcutKey = () => {
-  console.log(editor)
-  editor.setShortcutKey("F9", (evt, view, position) => {
-    console.log(evt, view, position)
-  });
+const popupRef = ref(null)
+const popupFunc = {
+  setShortcutKey: () => {
+    editor.setShortcutKey("ALT+Q", (evt, view, position) => {
+      popupRef.value.positionChange(evt, view, position)
+    });
+  },
+  fillData: (val) => {
+    hotSearchSorting(userData.code, val.queryKey, 'medical_history_prompts')
+    editor.execute('insertContents', {value: [{type: 'text', data: val.content}]})
+  }
+
 }
 
 
@@ -1207,6 +1220,7 @@ defineExpose({
 <style scoped lang="scss">
 .emr-iframe, iframe {
   width: 100%;
+  position: relative;
 }
 
 .emr__button_select {

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

@@ -0,0 +1,197 @@
+<template>
+  <div class="tips-main">
+    <div class="sidebar">
+      <xc-table :local-data="tipsData"
+                layout="total,prev, pager, next"
+                @rowClick="rowClick"
+                :height="150">
+        <el-table-column label="关键词" prop="queryKey" width="100"/>
+        <el-table-column label="内容" prop="content" show-overflow-tooltip/>
+        <el-table-column label="类型" prop="typeName" width="40"/>
+        <el-table-column fixed="right" width="60">
+          <template #header>
+            <el-button type="primary" icon="Plus" title="添加" @click="addEmrTipsClick"/>
+          </template>
+          <template #default="{row}">
+            <el-popconfirm cancel-button-text="取消"
+                           confirm-button-text="删除"
+                           icon="Delete" iconColor="#F56C6C"
+                           title="是否删除该数据"
+                           @click.stop="delClick(row.id)">
+              <template #reference>
+                <el-button icon="Delete"
+                           type="danger"
+                           @click.stop
+                           title="删除"/>
+              </template>
+            </el-popconfirm>
+
+          </template>
+        </el-table-column>
+      </xc-table>
+    </div>
+    <div class="main">
+      <div style="height: 40px"/>
+
+      <el-form label-width="80px"
+               ref="formRef"
+               :rules="rules"
+               :model="formData">
+
+        <el-form-item label="关键词:" prop="queryKey">
+          <el-input v-model="formData.queryKey"
+                    maxlength="20"
+                    show-word-limit
+                    placeholder="请设置检索关键词,建议关键词为小写英文或拼音。"/>
+        </el-form-item>
+
+        <el-form-item label="内容:" prop="content">
+          <el-input v-model="formData.content"
+                    placeholder="请写入内容"
+                    rows="10"
+                    @keydown.tab="tabInput"
+                    type="textarea"/>
+        </el-form-item>
+
+        <el-form-item label="类型:" prop="typeCode">
+          <el-select v-model="formData.typeCode">
+            <el-option v-for="item in typeList"
+                       :value="item.code"
+                       :label="item.name"/>
+          </el-select>
+        </el-form-item>
+
+        <el-form-item>
+          <el-button
+              v-if="formData.id === null"
+              type="primary"
+              @click="addPopupClick">
+            提交
+          </el-button>
+          <el-button v-else type="primary"
+                     @click="updatePopupClick">
+            修改
+          </el-button>
+        </el-form-item>
+
+      </el-form>
+    </div>
+  </div>
+
+
+</template>
+
+<script setup name='MedicalHistoryPrompts'>
+import {addEmrTips, deleteEmrTips, getEmrTips, updateEmrTips} from "@/api/zhu-yuan-yi-sheng/emr-patient";
+import XcTable from "@/components/xiao-chan/xc-table/XcTable.vue";
+
+
+const tipsData = ref([])
+const formRef = ref()
+const formData = ref({
+  id: null,
+  content: '',
+  typeCode: '',
+  queryKey: '',
+})
+
+const typeList = [
+  {code: 1, name: '个人'},
+  {code: 2, name: '科室'},
+  {code: 3, name: '全院'},
+]
+
+const rules = ref({
+  queryKey: [{required: true, message: '该项不能为空', trigger: 'blur'}],
+  typeCode: [{required: true, message: '该项不能为空', trigger: 'blur'}],
+  content: [{required: true, message: '该项不能为空', trigger: 'blur'}],
+})
+const queryData = () => {
+  getEmrTips().then(res => {
+    tipsData.value = res
+  })
+}
+
+const tabInput = (e) => {
+  e.returnValue = false
+  const insertText = '\t'
+  const elInput = e.target
+  const startPos = elInput.selectionStart
+  const endPos = elInput.selectionEnd
+  if (startPos === undefined || endPos === undefined) return
+  const txt = elInput.value
+  elInput.value = txt.substring(0, startPos) + insertText + txt.substring(endPos)
+  elInput.focus()
+  elInput.selectionStart = startPos + insertText.length;
+  elInput.selectionEnd = startPos + insertText.length;
+  formData.value.content = elInput.value
+}
+
+const addPopupClick = () => {
+  formRef.value.validate((valid) => {
+    if (!valid) {
+      return
+    }
+    addEmrTips(formData.value).then(() => {
+      queryData()
+      empty()
+    })
+  })
+}
+
+const updatePopupClick = () => {
+  formRef.value.validate((valid) => {
+    if (!valid) {
+      return
+    }
+    updateEmrTips(formData.value).then(() => {
+      queryData()
+      empty()
+    })
+
+  })
+}
+
+const delClick = (id) => {
+  deleteEmrTips(id).then(() => {
+    queryData()
+  })
+}
+
+const rowClick = (row) => {
+  formData.value = row
+}
+
+const addEmrTipsClick = () => {
+  empty()
+}
+
+const empty = () => {
+  formData.value = {
+    id: null,
+    content: '',
+    typeCode: '',
+    queryKey: '',
+  }
+}
+
+onMounted(() => {
+  queryData()
+})
+
+</script>
+
+<style scoped lang="scss">
+.tips-main {
+  display: flex;
+
+  .sidebar {
+    width: 600px;
+  }
+
+  .main {
+    flex: 1;
+    background-color: white;
+  }
+}
+</style>

+ 4 - 19
src/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-init.js

@@ -1,6 +1,4 @@
-import {ElMessage} from "element-plus";
 import store from '@/store'
-import {xcMessage} from "@/utils/xiaochan-element-plus";
 import router from "@/router";
 import {deletePatientEmrByDocumentId, insertEmrData} from "@/api/zhu-yuan-yi-sheng/emr-patient";
 
@@ -51,20 +49,7 @@ export function EMRInteractive(data, editorEvent) {
         return this.editor[name](...value)
     }
 
-    this.insertSnippet = (content, styles, patientData) => {
-        //病历片段相关参数
-        let insertContent = {
-            // 内容
-            value: content,
-            // 样式
-            styles: styles,
-            isFragment: true,
-            // 就是在这里填充的值
-            defaultData: patientData
-        }
-        this.editor.execute("insertContents", insertContent);
-    }
-
+    // 这个不能删除是编辑器需要的东西
     this.getAppContext = () => {
         return {
             endpoints: {
@@ -84,7 +69,7 @@ export function EMRInteractive(data, editorEvent) {
         }
     };
 
-    this.saveDocument = (value) => {
+    this.saveDocument = (value, newDate) => {
         let document = this.editor.getDocument();
 
         document.properties.categoryCode = value.emrCategoryCode
@@ -95,11 +80,11 @@ export function EMRInteractive(data, editorEvent) {
         if (document.properties.creator) {
             document.properties.modifier = data['编辑者姓名'];
             document.properties.modifierId = data['编辑者编码'];
-            document.properties.modifyTime = new Date()
+            document.properties.modifyTime = newDate
         } else {
             document.properties.creator = data['编辑者姓名'];
             document.properties.creatorId = data['编辑者编码'];
-            document.properties.createTime = new Date()
+            document.properties.createTime = newDate
         }
         return insertEmrData(value)
     };