Bläddra i källkod

电子病历问题

DESKTOP-0GD05B0\Administrator 2 år sedan
förälder
incheckning
1af69d9a2c

+ 244 - 0
src/components/xc/dialog/XcDialog.vue

@@ -0,0 +1,244 @@
+<template>
+  <Transition name="cy-dialog">
+    <div class="cy-dialog__v2"
+         ref="dialogRef"
+         :style="config.fullScreen ? fullScreenStyle : dislogStyle"
+         v-show="config.dialog"
+         :class="config.fullScreen ? 'cy-dialog__fullScreen' : 'cy-dialog__cancelFullScreen' ">
+      <div class="cy-dialog__header" ref="dialogHeadRef"
+           @mousedown.stop.prevent>
+        <div class="cy-dialog__title">
+          <span>
+          {{ config.title }}
+          </span>
+        </div>
+        <div class="cy-dialog__icon">
+          <div style="background-color: rgb(253,201,45)">
+            <i class="iconfont icon-suoxiao"/>
+          </div>
+          <div style="background-color: rgb(40,211,63)">
+            <i class="iconfont"
+               @click="clickFullScreen"
+               :class="config.fullScreen ? 'icon-quxiaoquanping' : 'icon-quanping' ">
+            </i>
+          </div>
+          <div class="cy-dialog__close" style="background-color: rgb(254,98,84)">
+            <i class="iconfont icon-guanbi" @click="closed"></i>
+          </div>
+        </div>
+      </div>
+      <div class="cy-dialog__main">
+        <slot/>
+      </div>
+    </div>
+  </Transition>
+</template>
+
+<script setup name='XcDialog' lang="ts">
+import {PropType, Ref, ref, watch, onMounted, nextTick} from "vue";
+import {useDraggable, onClickOutside} from '@vueuse/core'
+import {$ref} from "vue/macros";
+
+interface dialogConfig {
+  fullScreen: boolean,
+  title: string,
+  top?: number,
+  dialog: boolean,
+  img?: any,
+  width: '',
+}
+
+const props = defineProps({
+  config: Object as PropType<dialogConfig>
+})
+const emit = defineEmits(['closed'])
+
+
+const dialogRef: Ref<HTMLElement | null> = ref(null)
+const dialogHeadRef: Ref<HTMLElement | null> = ref(null)
+
+onClickOutside(dialogRef, (event) => {
+  closed()
+})
+
+const draggable = ref()
+const fullScreenStyle = $ref({
+  position: 'fixed',
+  top: '0',
+  left: '0',
+  width: '100%',
+  height: '100%',
+  zIndex: 0,
+})
+
+let dislogStyle = $ref({
+  left: '',
+  top: '',
+  zIndex: 0,
+  width: '30%'
+})
+
+const clickFullScreen = () => {
+  let zIndex = [...document.all].reduce((r, e) => Math.max(r, +window.getComputedStyle(e).zIndex || 0), 0)
+  props.config!.fullScreen = !props.config?.fullScreen
+  fullScreenStyle.zIndex = zIndex
+}
+
+
+const closed = () => {
+  emit('closed')
+  props.config!.dialog = false
+}
+
+watch(() => props.config?.dialog, () => {
+  if (props.config?.dialog) {
+    let zIndex = [...document.all].reduce((r, e) => Math.max(r, +window.getComputedStyle(e).zIndex || 0), 0)
+    dislogStyle.zIndex = zIndex
+  }
+})
+
+watch(() => draggable.value?.x, async () => {
+  if (props.config!.fullScreen) return
+  let right = window.innerWidth - dialogRef.value!.clientWidth
+  if (draggable.value.x < 0) {
+    draggable.value.x = 0
+  } else if (draggable.value.x > right) {
+    draggable.value.x = right
+  }
+  dislogStyle.left = draggable.value.x + 'px'
+})
+
+watch(() => draggable.value?.y, async () => {
+  if (props.config!.fullScreen) return
+  let bottom = window.innerHeight - dialogRef.value!.clientHeight
+  if (draggable.value.y < 0) {
+    draggable.value.y = 0
+  } else if (draggable.value.y > bottom) {
+    draggable.value.y = bottom
+  }
+  dislogStyle.top = draggable.value.y + 'px'
+})
+
+onMounted(async () => {
+  await nextTick()
+  if (dialogRef.value === null) {
+    return
+  }
+  let top = (window.innerHeight * (10 / 100))
+  let left = (window.innerWidth / 2) - (dialogRef.value?.clientWidth / 2);
+
+  draggable.value = useDraggable(dialogHeadRef, {
+    initialValue: {x: left as number, y: top as number},
+  })
+  let zIndex = [...document.all].reduce((r, e) => Math.max(r, +window.getComputedStyle(e).zIndex || 0), 0)
+  dislogStyle.zIndex = zIndex
+
+  if (props.config?.width) {
+    dislogStyle.width = props.config?.width
+  }
+
+  const body = document.querySelector("body");
+  if (body.append) {
+    body.append(dialogRef.value);
+  } else {
+    body.appendChild(dialogRef.value);
+  }
+
+
+})
+
+</script>
+
+<style lang="scss" scoped>
+
+.cy-dialog-enter-active {
+  animation: xing .3s;
+}
+
+.cy-dialog-leave-active {
+  animation: xing .3s reverse;
+}
+
+@keyframes xing {
+  0% {
+    transform: scale(0.5);
+  }
+  100% {
+    transform: scale(1);
+  }
+}
+
+.cy-dialog__v2 {
+  position: absolute;
+  height: max-content;
+  border-radius: 10px;
+
+  background-color: white;
+  box-shadow: 0 4px 8px rgb(0 0 0 / 20%), 0 6px 20px rgb(0 0 0 / 19%);
+
+
+  .cy-dialog__header {
+    width: 100%;
+    position: relative;
+    border-bottom: 1px solid;
+    cursor: move;
+    background-color: white;
+
+    .cy-dialog__title {
+      line-height: 40px;
+      text-align: center;
+      font-size: 12px;
+    }
+
+    .cy-dialog__icon {
+      padding: 10px 0;
+      display: flex;
+      position: absolute;
+      width: content-box;
+      top: 0;
+      right: 5px;
+      cursor: default;
+
+      div {
+        width: 12px;
+        height: 12px;
+        padding: 4px;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        border-radius: 10px;
+        margin-left: 5px;
+
+
+        &:hover {
+          i {
+            opacity: 1;
+          }
+        }
+
+        i {
+          font-size: 12px;
+          color: black;
+          transform: scale(0.8);
+          opacity: 0;
+          transition: opacity .2s;
+        }
+      }
+    }
+  }
+}
+
+.cy-dialog__fullScreen {
+  width: 100%;
+  height: 100%;
+  margin: 0;
+  border-radius: 0;
+}
+
+.cy-dialog__main {
+  display: flex;
+  height: max-content;
+  padding: 10px;
+}
+
+</style>

+ 34 - 0
src/components/zhu-yuan-yi-sheng/emr/EmrAssistant.vue

@@ -0,0 +1,34 @@
+<template>
+  <xc-dialog :config="config" @closed="emit('update:modelValue',false)">
+  </xc-dialog>
+</template>
+
+<script setup name='EmrAssistant'>
+import XcDialog from "@/components/xc/dialog/XcDialog";
+
+const props = defineProps({
+  modelValue: {
+    type: Boolean,
+    default: false
+  }
+})
+
+const emit = defineEmits(['update:modelValue'])
+
+let config = $ref({
+  fullScreen: false,
+  title: '电子病历助手',
+  dialog: true,
+  img: '',
+  width: '500px'
+})
+
+watch(() => props.modelValue, () => {
+  config.dialog = props.modelValue
+})
+
+</script>
+
+<style scoped lang="scss">
+
+</style>

+ 3 - 3
src/components/zhu-yuan-yi-sheng/yi-zhu-lu-ru/BaoCunXinXi.vue

@@ -1,7 +1,7 @@
 <template>
   <div :style="style"
        class="main xc_box 小手指">
-    <div ref="div" class="header">
+    <div ref="divRef" class="header">
       <div style="flex: 1">上传提示</div>
       <div class="circle_close " @click="close">
         <el-icon :size="21">
@@ -54,9 +54,9 @@ const props = defineProps({
 
 const emit = defineEmits(['openOrCloseErrorMsg', 'clickError'])
 
-const div: Ref<Document> = ref(null)
+const divRef: Ref<Document> = ref(null)
 
-const {x, y, style} = useDraggable(div, {
+const {x, y, style} = useDraggable(divRef, {
   initialValue: {x: 77, y: 494},
 });
 

+ 19 - 3
src/icons/iconfont.css

@@ -1,8 +1,8 @@
 @font-face {
   font-family: "iconfont"; /* Project id 2473230 */
-  src: url('iconfont.woff2?t=1667897125811') format('woff2'),
-       url('iconfont.woff?t=1667897125811') format('woff'),
-       url('iconfont.ttf?t=1667897125811') format('truetype');
+  src: url('iconfont.woff2?t=1668413714002') format('woff2'),
+       url('iconfont.woff?t=1668413714002') format('woff'),
+       url('iconfont.ttf?t=1668413714002') format('truetype');
 }
 
 .iconfont {
@@ -13,6 +13,22 @@
   -moz-osx-font-smoothing: grayscale;
 }
 
+.icon-quxiaoquanping:before {
+  content: "\e662";
+}
+
+.icon-suoxiao:before {
+  content: "\e63c";
+}
+
+.icon-guanbi:before {
+  content: "\eaf2";
+}
+
+.icon-quanping:before {
+  content: "\e651";
+}
+
 .icon-tools-hardware:before {
   content: "\e882";
 }

BIN
src/icons/iconfont.ttf


BIN
src/icons/iconfont.woff


BIN
src/icons/iconfont.woff2


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

@@ -12,7 +12,8 @@
         <el-button icon="Delete" type="danger" @click="clickDelete">删除电子病历</el-button>
       </div>
       <el-button style="margin-left: 5px" type="primary" icon="Printer" @click="testPrint">打印电子病历</el-button>
-
+      <el-button style="margin-left: 5px" type="primary" @click="openAssistant = true">电子助手</el-button>
+      <emr-assistant v-model="openAssistant"/>
       <el-switch v-model="reviewMode" active-color="#ff4949" active-text="关闭审阅" :active-value="false"
                  inactive-color="#13ce66" inactive-text="开启审阅" :inactive-value="true">
       </el-switch>
@@ -57,6 +58,7 @@ 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 EmrAssistant from "@/components/zhu-yuan-yi-sheng/emr/EmrAssistant";
 
 const currentEmr = ref(null)
 const emrRef = ref(null)
@@ -69,6 +71,8 @@ let patientId = $ref('')
 let categroyId = $ref('')
 let templateName = $ref('')
 let caseHistoryUrl = $ref('')
+let openAssistant = $ref(true)
+
 // 编辑器
 let editor = null
 // 患者历史记录