Ver Fonte

Merge remote-tracking branch 'upstream/master'

hsh há 3 anos atrás
pai
commit
13ab6fad54

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

@@ -25,3 +25,12 @@ export function deletePatientEmrByDocumentId(documentId) {
         params: {documentId}
     })
 }
+
+export function existCourseRecord(patNo, times) {
+    return request({
+        url: url + 'existCourseRecord',
+        method: 'get',
+        params: {patNo, times}
+    })
+}
+

+ 37 - 13
src/components/zhu-yuan-yi-sheng/emr/EmrSidebar.vue

@@ -12,6 +12,19 @@
            ref="treeRef"
            :filter-node-method="filterNode"
            default-expand-all>
+    <template #default="{ node, data }">
+      <span v-if="templateType === 2">
+        <span v-if="data.children">
+        {{ data.name }}
+        </span>
+        <span v-else>
+        {{ data.name }}/{{ data.modifyDate ? data.modifyDate : data.createDate }}
+        </span>
+      </span>
+      <span v-else>
+        {{ data.name }}
+      </span>
+    </template>
   </el-tree>
 </template>
 
@@ -40,8 +53,6 @@ let templateType = $ref(0)
 const handleNodeClick = (val, property, event) => {
   let str = JSON.stringify(val)
   if (val.roundTime) {
-    console.log(val, property, event)
-    console.log(property.parent.data)
     emit('nodeClick', val, property.parent.data, templateType);
   } else {
     if (key !== str) {
@@ -91,11 +102,19 @@ const deleteTheSpecifiedNode = (id) => {
       returnData.patientTree.splice(i, 1)
       return
     }
+    if (item.children) {
+      for (let j = 0; j < item.children.length; j++) {
+        let child = item.children[j]
+        if (child.emrDocumentId === id) {
+          item.children.splice(i, 1)
+          return
+        }
+      }
+    }
   }
 }
 
 const diseaseDurationRecordTime = ({ward_round_time}) => {
-  console.log(ward_round_time)
   if (ward_round_time) {
     let roundTimes = []
     for (let i = 0; i < ward_round_time.length; i++) {
@@ -114,24 +133,29 @@ const diseaseDurationRecordTime = ({ward_round_time}) => {
   }
 }
 
+const queryData = () => {
+  getEmrTree(huanZheXinXi.value.inpatientNo, huanZheXinXi.value.admissTimes).then((res) => {
+    if (res.patientTree) {
+      treeData = res.patientTree
+      templateType = 2
+    } else {
+      treeData = res.emrTree
+    }
+    returnData = res
+  })
+}
+
 defineExpose({
   queryHistory,
   changeTemplateType,
   deleteTheSpecifiedNode,
-  diseaseDurationRecordTime
+  diseaseDurationRecordTime,
+  queryData
 })
 
 onMounted(() => {
   nextTick(() => {
-    getEmrTree(huanZheXinXi.value.inpatientNo, huanZheXinXi.value.admissTimes).then((res) => {
-      if (res.patientTree) {
-        treeData = res.patientTree
-        templateType = 2
-      } else {
-        treeData = res.emrTree
-      }
-      returnData = res
-    })
+    queryData()
   })
 })
 

+ 11 - 3
src/components/zhu-yuan-yi-sheng/he-li-yong-yao/YaoPingXiangQing.vue

@@ -22,6 +22,9 @@ import store from '@/store'
 const props = defineProps({
   code: {
     type: String,
+  },
+  url: {
+    type: String,
   }
 })
 const emit = defineEmits(['close'])
@@ -31,14 +34,19 @@ const windowSize = computed(() => {
 })
 
 let dialog = $ref(true)
-let src = "http://172.16.32.121:9097/web/sms/hpms_medi_show.aspx?his_code=" + props.code
+let src = $ref('')
 
 let showIframe = $ref(false)
 
 onMounted(() => {
-  setTimeout(() => {
+  nextTick(() => {
+    if (props.url) {
+      src = props.url
+    } else {
+      src = "http://172.16.32.121:9097/web/sms/hpms_medi_show.aspx?his_code=" + props.code
+    }
     showIframe = true
-  }, 100)
+  })
 })
 
 </script>

+ 53 - 29
src/layout/Tabs/index.vue

@@ -1,20 +1,26 @@
 <template>
-  <div class="tabs">
-    <el-scrollbar ref="scrollbarDom">
-      <div style="display: flex; flex-wrap: nowrap">
-        <Item v-for="menu in menuList" :key="menu.meta.title" :active="activeMenu === menu.path" :menu="menu" @close="delMenu(menu)" />
+  <div class="tabs-box">
+    <el-scrollbar ref="scrollbarDom" class="tab">
+      <div class="scrollbar-flex-content">
+        <Item v-for="menu in menuList" :key="menu.meta.title" :active="activeMenu === menu.path" :menu="menu"
+              @close="delMenu(menu)"/>
       </div>
     </el-scrollbar>
     <div class="handle">
       <el-dropdown placement="bottom">
         <div class="el-dropdown-link">
-          <el-icon><ArrowDown /></el-icon>
+          <el-icon>
+            <ArrowDown/>
+          </el-icon>
         </div>
         <template #dropdown>
           <el-dropdown-menu>
-            <el-dropdown-item :disabled="currentDisabled" icon="CircleClose" @click="closeCurrentRoute"> 关闭当前标签 </el-dropdown-item>
-            <el-dropdown-item :disabled="menuList.length < 3" icon="CircleClose" @click="closeOtherRoute"> 关闭其他标签 </el-dropdown-item>
-            <el-dropdown-item :disabled="menuList.length <= 1" icon="CircleClose" @click="closeAllRoute"> 关闭所有标签 </el-dropdown-item>
+            <el-dropdown-item :disabled="currentDisabled" icon="CircleClose" @click="closeCurrentRoute"> 关闭当前标签
+            </el-dropdown-item>
+            <el-dropdown-item :disabled="menuList.length < 3" icon="CircleClose" @click="closeOtherRoute"> 关闭其他标签
+            </el-dropdown-item>
+            <el-dropdown-item :disabled="menuList.length <= 1" icon="CircleClose" @click="closeAllRoute"> 关闭所有标签
+            </el-dropdown-item>
           </el-dropdown-menu>
         </template>
       </el-dropdown>
@@ -24,10 +30,11 @@
 
 <script name="tabs" setup>
 import Item from './item.vue'
-import { computed, nextTick, ref, watch } from 'vue'
-import { useStore } from 'vuex'
-import { useRoute, useRouter } from 'vue-router'
+import {computed, nextTick, ref, watch} from 'vue'
+import {useStore} from 'vuex'
+import {useRoute, useRouter} from 'vue-router'
 import tabsHook from './tabsHook'
+import {getScrollTop} from "@/utils/el-table-scroll";
 
 const store = useStore()
 const route = useRoute()
@@ -35,7 +42,7 @@ const router = useRouter()
 const scrollbarDom = ref(null)
 const defaultMenu = {
   path: '/dashboard',
-  meta: { title: '首页', hideClose: true },
+  meta: {title: '首页', hideClose: true},
 }
 const currentDisabled = computed(() => route.path === defaultMenu.path)
 
@@ -81,7 +88,7 @@ function closeAllRoute() {
 
 // 添加新的菜单项
 function addMenu(menu) {
-  let { path, meta, name } = menu
+  let {path, meta, name} = menu
   if (meta.activeMenu) {
     let a = menuList.value.some((obj) => {
       return obj.path === meta.activeMenu
@@ -89,7 +96,7 @@ function addMenu(menu) {
     if (!a) {
       menuList.value.push({
         path: meta.activeMenu,
-        meta: { title: meta.parentName },
+        meta: {title: meta.parentName},
       })
     }
     return
@@ -115,8 +122,8 @@ function delMenu(menu) {
       store.commit('keepAlive/delKeepAliveComponentsName', menu.name)
     }
     menuList.value.splice(
-      menuList.value.findIndex((item) => item.path === menu.path),
-      1
+        menuList.value.findIndex((item) => item.path === menu.path),
+        1
     )
   }
   if (menu.path === activeMenu.value) {
@@ -134,7 +141,9 @@ function initMenu(menu) {
   nextTick(() => {
     try {
       setPosition()
-    } catch (e) {}
+    } catch (e) {
+      console.log(e)
+    }
   })
 }
 
@@ -142,12 +151,12 @@ function initMenu(menu) {
 function setPosition() {
   if (scrollbarDom.value) {
     const domBox = {
-      scrollbar: scrollbarDom.value.scrollbar.querySelector('.el-scrollbar__wrap '),
-      activeDom: scrollbarDom.value.scrollbar.querySelector('.active'),
-      activeFather: scrollbarDom.value.scrollbar.querySelector('.el-scrollbar__view'),
+      scrollbar: scrollbarDom.value.$el.querySelector('.el-scrollbar__wrap '),
+      activeDom: scrollbarDom.value.$el.querySelector('.active'),
+      activeFather: scrollbarDom.value.$el.querySelector('.el-scrollbar__view'),
     }
-    for (let i in domBox) {
-      if (!domBox[i]) {
+    for (let key in domBox) {
+      if (!domBox[key]) {
         return
       }
     }
@@ -156,12 +165,15 @@ function setPosition() {
       activeDom: domBox.activeDom.getBoundingClientRect(),
       activeFather: domBox.activeFather.getBoundingClientRect(),
     }
-    const num = domData.activeDom.x - domData.activeFather.x + (1 / 2) * domData.activeDom.width - (1 / 2) * domData.scrollbar.width
-    domBox.scrollbar.scrollLeft = num
+    scrollbarDom.value.scrollTo({
+      top: 0,
+      left: domData.activeDom.x - domData.activeFather.x + (1 / 2) * domData.activeDom.width - (1 / 2) * domData.scrollbar.width,
+      behavior: 'smooth',
+    })
+    // domBox.scrollbar.scrollLeft = domData.activeDom.x - domData.activeFather.x + (1 / 2) * domData.activeDom.width - (1 / 2) * domData.scrollbar.width
   }
 }
 
-// 配置需要缓存的数据
 function setKeepAliveData() {
   let keepAliveNames = []
   menuList.value.forEach((menu) => {
@@ -170,13 +182,12 @@ function setKeepAliveData() {
   store.commit('keepAlive/setKeepAliveComponentsName', keepAliveNames)
 }
 
-// 初始化时调用:1. 新增菜单 2. 初始化activeMenu
 addMenu(route)
 initMenu(route)
 </script>
 
 <style lang="scss" scoped>
-.tabs {
+.tabs-box {
   display: flex;
   justify-content: space-between;
   align-items: center;
@@ -186,10 +197,14 @@ initMenu(route)
   border-top: 1px solid var(--system-header-border-color);
   box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.1);
 
+  .tab {
+    width: calc(100% - 40px);
+  }
+
   .handle {
     min-width: 35px;
     height: 100%;
-    background-color: rgb(228, 228, 228);
+    background-color: rgb(234, 233, 233);
     display: flex;
     align-items: center;
 
@@ -215,13 +230,15 @@ initMenu(route)
   overflow: hidden;
   width: 100%;
 }
+
 :deep(.scroll-container .el-scrollbar__bar) {
-  bottom: 0px;
+  bottom: 0;
 }
 
 :deep(.scroll-container .el-scrollbar__wrap) {
   height: 49px;
 }
+
 .tags-view-container {
   height: 34px;
   flex: 1;
@@ -240,4 +257,11 @@ initMenu(route)
     outline: none;
   }
 }
+
+
+.scrollbar-flex-content {
+  display: flex;
+  width: calc(100% - 50px);
+  //overflow-x: scroll;
+}
 </style>

+ 5 - 3
src/layout/Tabs/item.vue

@@ -42,10 +42,12 @@ export default defineComponent({
 
 <style lang="scss" scoped>
 .tags-view-item {
-  display: inline-block;
-  position: relative;
-  cursor: pointer;
   flex-shrink: 0;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  text-align: center;
+  cursor: pointer;
   height: 24px;
   line-height: 24px;
   border: 1px solid var(--system-header-border-color);

+ 1 - 1
src/views/hospitalization/case-front-sheet/FillCaseFrontSheet.vue

@@ -16,7 +16,7 @@
       <el-button type="primary" icon="Upload" @click="saveVerify(1)">保存首页</el-button>
       <el-button type="success" icon="Printer" @click="beforePrint(1)">打印正面</el-button>
       <el-button type="success" icon="Printer" @click="beforePrint(2)">打印反面</el-button>
-      <el-button type="danger" icon="Document" @click="execSignApply">归档申请</el-button>
+      <el-button type="danger" icon="Document" @click="execSignApply" :disabled="inOutStatus === 2">归档申请</el-button>
     </el-header>
     <el-container>
       <el-aside width="245px">

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

@@ -1,6 +1,6 @@
 import {ElMessage, ElMessageBox} from "element-plus";
 import {BizException, ExceptionEnum} from "@/utils/BizException";
-import {deletePatientEmrByDocumentId, insertEmrData} from "@/api/zhu-yuan-yi-sheng/emr-patient";
+import {deletePatientEmrByDocumentId, existCourseRecord, insertEmrData} from "@/api/zhu-yuan-yi-sheng/emr-patient";
 
 export let courseOfDisease = 'bingchengjiluzhuanyong'
 
@@ -67,6 +67,7 @@ export function EMRInteractive(data, endiorEvent) {
             BizException(ExceptionEnum.MESSAGE_ERROR, "没有通过校验")
         }
 
+
         this.runtime.saveDocument(data, (res) => {
             insertEmrData(value).then(() => {
                 successfullySaved()

+ 15 - 7
src/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/index.vue

@@ -60,12 +60,13 @@ import {
   courseOfDisease,
   EMRInteractive
 } from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-init";
-import {ElMessageBox} from "element-plus";
+import {ElMessage, ElMessageBox} from "element-plus";
 import {uuid} from "@/utils/getUuid";
 import {BizException, ExceptionEnum} from "@/utils/BizException";
 import router from '@/router'
 import EmrSnippet from "@/components/zhu-yuan-yi-sheng/emr/EmrSnippet.vue";
 import store from "@/store";
+import {existCourseRecord} from "@/api/zhu-yuan-yi-sheng/emr-patient";
 
 const emit = defineEmits(['refreshPage'])
 
@@ -99,7 +100,7 @@ const updateCaseHistoryUrl = (val) => {
   isEditorChange = false
   documentId = val.emrDocumentId;
   categoryCode = valCode
-  templateName = val.emrName ? val.emrName : val.name
+  templateName = val.name
   caseHistoryUrl = `/emr/runtime/?documentId=${documentId}&categoryCode=${categoryCode}&categroyId=${categroyId}&patientId=${patientId}#/`
 }
 
@@ -110,7 +111,11 @@ const refreshPage = () => {
   })
 }
 
-const clickSaveData = () => {
+const clickSaveData = async () => {
+  let flag = await existCourseRecord(huanZheXinXi.value.inpatientNo, huanZheXinXi.value.admissTimes)
+  if (flag && !documentId && categoryCode === courseOfDisease) {
+    BizException(ExceptionEnum.MESSAGE_ERROR, '该患者已经存在病程记录,请勿填写.')
+  }
 
   waitForLoadingToComplete()
 
@@ -132,6 +137,7 @@ const clickSaveData = () => {
     data.name = value
     await currentEmr.value.saveDocument(data, () => {
       isEditorChange = false
+      emrSidebarRef.queryData()
     }, (err) => {
       documentId = err
       isEditorChange = true
@@ -170,10 +176,12 @@ const clickDelete = () => {
   ElMessageBox.alert('是否要删除该模板。', '提示', {
     type: 'warning'
   }).then(() => {
-    currentEmr.value.deleteDocument(documentId, function () {
-      emrSidebarRef.deleteTheSpecifiedNode(documentId)
-      nodeClick({}, 2)
-    });
+    emrSidebarRef.deleteTheSpecifiedNode(documentId)
+    nodeClick({}, 2)
+    // currentEmr.value.deleteDocument(documentId, function () {
+    //   emrSidebarRef.deleteTheSpecifiedNode(documentId)
+    //   nodeClick({}, 2)
+    // });
   }).catch(() => {
 
   })

+ 29 - 2
src/views/hospitalization/zhu-yuan-yi-sheng/yi-zhu-lu-ru/TianJiaYiZhu.vue

@@ -18,6 +18,7 @@
   </el-button>
   <el-divider direction="vertical"></el-divider>
   <el-button @click="tiaoZhuanZhiHeLiYongYao">合理用药</el-button>
+  <el-button @click="drugProblem.dialog = true">分析结果</el-button>
   <el-button @click="allergenDialog = true">患者过敏信息</el-button>
   <yao-ping-xiang-qing v-if="HeLiYongYao.dialog" :code="HeLiYongYao.code"
                        @close="HeLiYongYao.dialog = false"></yao-ping-xiang-qing>
@@ -287,11 +288,12 @@
         <el-tag v-if="scope.row.emergencyFlag === '1'">是</el-tag>
       </template>
     </el-table-column>
-    <el-table-column fixed="right" label="操作" width="120">
+    <el-table-column fixed="right" label="操作" width="220">
       <template #default="scope">
         <el-button circle icon="Edit" type="warning" @click="xiuGaiYiZhu(scope.row,scope.$index)"></el-button>
         <el-button circle icon="Delete" type="danger" @click="shanChuBiaoGeYiZhu(scope.$index)"></el-button>
         <el-button circle class="iconfont icon-fuzhi" type="info" @click="dianJiFuZhiYiZhu(scope.row)"></el-button>
+        <el-button circle icon="View" type="warning" @click="synopsis(scope.row)"></el-button>
       </template>
     </el-table-column>
   </el-table>
@@ -301,6 +303,12 @@
   <!-- 这个是过敏源的 -->
   <AllergenEntry v-if="allergenDialog" :pat-no="huanZheXinXi.inpatientNo"
                  @close="allergenDialog = false"></AllergenEntry>
+  <yao-ping-xiang-qing v-if="drugProblem.dialog"
+                       :url="drugProblem.url"
+                       @close="drugProblem.dialog = false"/>
+  <yao-ping-xiang-qing v-if="synopsisDialog.dialog"
+                       :code="synopsisDialog.code"
+                       @close="synopsisDialog.dialog = false"/>
 </template>
 
 <script name="TianJiaYiZhu" setup>
@@ -339,7 +347,6 @@ import {logoutShortcut, xcHotKey} from '@/utils/xckeydown'
 import {BizException, ExceptionEnum} from '@/utils/BizException'
 import {setScrollTop} from "@/utils/el-table-scroll";
 import XcSelectV2 from "@/components/xc/select-v2/XcSelectV2.vue";
-import {nextTick} from "vue";
 
 const windowSize = computed(() => {
   return store.state.app.windowSize
@@ -355,6 +362,11 @@ const zkCode = '06286'
 let dataIndex = $ref(-1)
 // 表格的 ref
 let elTableRef = $ref(null)
+// 药品问题
+let drugProblem = $ref({
+  dialog: false,
+  url: ''
+})
 
 const yiZhuData = ref({
   id: '',
@@ -670,6 +682,16 @@ const dianJiFuZhiYiZhu = (val) => {
   ElMessage.success('复制成功')
 }
 
+let synopsisDialog = $ref({
+  dialog: false,
+  code: ''
+})
+
+const synopsis = (val) => {
+  synopsisDialog.dialog = true
+  synopsisDialog.code = val.orderCode + '_' + val.serial
+}
+
 /* 保存信息 */
 const baoCunYiZhuClick = () => {
   if (listIsBlank(yiZhuList.value)) {
@@ -713,9 +735,14 @@ function baoCunYiZhu() {
   if (listNotBlank(list)) {
     // 合理用药校验
     jiaoYan(data).then((res) => {
+      if (res.code !== 0) {
+        drugProblem.dialog = true
+        drugProblem.url = res.ShowUrl
+      }
       console.log(res)
     })
   }
+  return
   ElMessageBox.confirm('您确定要保存这些数据吗?请仔细检查数据。', '提示', {
     type: 'warning',
     closeOnClickModal: false,

+ 1 - 1
src/views/medical-insurance/allpatient/SetllistReconciliation.vue

@@ -1,7 +1,7 @@
 <template>
   <el-container>
     <el-header style="height: 35px; margin-top: 10px">
-      <el-select v-model="slctSetlPrm.clrType" placeholder="算类别" style="width: 100px" @change="setlinfos = []">
+      <el-select v-model="slctSetlPrm.clrType" placeholder="算类别" style="width: 100px" @change="setlinfos = []">
         <el-option v-for="item in clrTypes" :key="item.code" :value="item.code" :label="item.name"></el-option>
       </el-select>
       <el-date-picker

+ 1 - 0
vite.config.js

@@ -39,6 +39,7 @@ export default defineConfig({
         })
     ],
     server: {
+        host: '0.0.0.0',
         proxy: {
             '/emr/runtime': {
                 target: 'http://172.16.32.122:8001', //这里配置运行时服务地址