Sfoglia il codice sorgente

自己的messagebox

xiaochan 1 anno fa
parent
commit
6068af4441

+ 0 - 1
index.html

@@ -6,7 +6,6 @@
     <link rel="stylesheet" href="./src/icons/alicdn/iconfont.css"/>
     <link rel="stylesheet" href="./src/icons/iconfont.css"/>
     <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
-
     <title>工作集成平台</title>
 </head>
 <body>

BIN
src/assets/prescription.png


+ 113 - 0
src/components/xiao-chan/cy-message-box/cy-message-box.ts

@@ -0,0 +1,113 @@
+// @ts-ignore
+import CyMessageBox from "./index.vue";
+import {h, render} from "vue";
+import {uuid} from "../../../utils/getUuid";
+
+const currentBox = new Map<string, HTMLDivElement>()
+
+interface CyMessageBox {
+    message?: string;
+    showCancel?: boolean,
+    confirmClick?: (value: string) => void;
+    cancel?: (val: string) => void;
+    type?: 'success' | 'error' | 'warning' | 'info',
+    confirmButtonText?: string,
+    cancelButtonText?: string,
+    showInput?: boolean,
+    inputMinLength?: number,
+    inputMaxLength?: number,
+    inputValidator?: (val: string) => boolean | string,
+    inputErrorMessage?: string,
+    setClose?: (val: any) => void,
+    inputRows?: number,
+    boxId?: string,
+    allowToBeEmpty?: boolean,
+    dangerouslyUseHTMLString?: boolean
+}
+
+export function getCyId(): string {
+    return 'cy-' + uuid(5)
+}
+
+export function closeById(id: string) {
+    if (currentBox.has(id))
+        currentBox.get(id)?.['close']()
+}
+
+function alert(message: string, type: 'success' | 'error' | 'warning' | 'info' = 'warning', config?: CyMessageBox): Promise<string> {
+    if (config) {
+        config.showCancel = false
+    }
+    return renderFunc(message, type, config || {showCancel: false})
+}
+
+function confirm(message: string, type: 'success' | 'error' | 'warning' | 'info' = 'warning', config?: CyMessageBox): Promise<string> {
+    return renderFunc(message, type, config)
+}
+
+function prompt(message: string, type: 'success' | 'error' | 'warning' | 'info' = 'warning', config?: CyMessageBox) {
+    if (config) {
+        config.showInput = true
+    }
+    return renderFunc(message, type, config || {showInput: true})
+}
+
+
+function renderFunc(message: string, type: 'success' | 'error' | 'warning' | 'info' = 'warning', config: CyMessageBox): Promise<string> {
+    function id() {
+        if (typeof config === 'undefined') {
+            return false
+        }
+        return typeof config.boxId !== 'undefined';
+    }
+
+    const withID = id()
+
+    if (withID && document.getElementById(config.boxId)) {
+        return Promise.reject('messageBox,id重复。')
+    }
+
+    const div = document.createElement('div');
+    document.body.appendChild(div);
+    div.id = withID ? config.boxId : getCyId();
+
+    currentBox.set(div.id, div);
+
+    function closeBox(): void {
+        document.body.removeChild(div);
+        currentBox.delete(div.id);
+        if (currentBox.size === 0) {
+            document.body.className = ''
+        }
+    }
+
+    return new Promise((resolve, reject) => {
+        const data: CyMessageBox = {
+            message,
+            inputRows: config && config.inputRows || 0,
+            confirmClick: () => {
+                resolve('confirm')
+                closeBox()
+            },
+            cancel: (val: string) => {
+                reject(val)
+                closeBox()
+            },
+            type,
+            setClose: (val: any) => {
+                div['close'] = val
+            }
+        }
+
+        Object.assign(data, config)
+        const vNode = h(CyMessageBox, data, () => null)
+        render(vNode, div)
+    })
+}
+
+export const cyMessageBox = {
+    alert,
+    confirm,
+    prompt
+}
+

+ 427 - 0
src/components/xiao-chan/cy-message-box/index.vue

@@ -0,0 +1,427 @@
+<script lang="ts" setup>
+import {useZIndex, ElIcon, ElInput} from "element-plus";
+import {nextTick, onMounted, ref, h} from "vue";
+import sleep from "@/utils/sleep";
+// @ts-ignore
+import {
+  Close,
+  Warning,
+  SuccessFilled,
+  InfoFilled,
+  CircleCloseFilled
+} from '@element-plus/icons-vue'
+import {getCyId} from "@/components/xiao-chan/cy-message-box/cy-message-box";
+import {useCompRef} from "@/utils/useCompRef";
+
+const props = withDefaults(defineProps<{
+  message?: string;
+  showCancel?: boolean,
+  confirmClick?: (value: string) => void;
+  cancel?: (val: string) => void;
+  type?: 'success' | 'error' | 'warning' | 'info',
+  confirmButtonText?: string,
+  cancelButtonText?: string,
+  showInput?: boolean,
+  inputMinLength?: number,
+  inputMaxLength?: number,
+  inputValidator?: (val: string) => boolean | string,
+  inputErrorMessage?: string,
+  setClose?: (val: any) => void,
+  inputRows?: number,
+  boxId?: string,
+  allowToBeEmpty?: boolean,
+  dangerouslyUseHTMLString?: boolean
+}>(), {
+  showCancel: true,
+  confirmButtonText: '确认',
+  cancelButtonText: '取消',
+  inputErrorMessage: '校验未通过',
+  allowToBeEmpty: false,
+  dangerouslyUseHTMLString: false
+})
+
+const visible = ref(false)
+const headerRef = ref<HTMLHeadElement>(null)
+const inputValue = ref('')
+const errorMsg = ref('')
+const inputRef = useCompRef(ElInput)
+
+const inputId = ref(getCyId())
+
+let closeMode = ''
+
+const mainStyle = ref({
+  zIndex: 0,
+  display: 'flex'
+})
+
+const contentStyle = ref({
+  zIndex: 0,
+})
+
+function nextZIndex() {
+  return useZIndex().nextZIndex()
+}
+
+/**
+ * 关闭动画
+ */
+function onAfterLeave() {
+  mainStyle.value.display = 'none'
+  if (!visible.value) {
+    if (closeMode === 'close' || closeMode === 'cancel') {
+      props.cancel(closeMode)
+    } else {
+      props.confirmClick(inputValue.value)
+    }
+  }
+}
+
+/**
+ * 开启动画
+ */
+function onAfterEnter() {
+  mainStyle.value.display = 'flex'
+}
+
+function handleConfirm() {
+  if (props.showInput) {
+    handlePrompt()
+  } else {
+    visible.value = false;
+    closeMode = ''
+  }
+}
+
+function handlePrompt() {
+  function next() {
+    visible.value = false;
+    closeMode = ''
+  }
+
+  if (!props.allowToBeEmpty) {
+    if (inputValue.value === '') {
+      errorMsg.value = '不允许为空。'
+      return
+    }
+  }
+
+  if (props.inputValidator) {
+    const inputValidator = props.inputValidator(inputValue.value)
+    if (typeof inputValidator === 'boolean') {
+      if (inputValidator) {
+        next()
+      } else {
+        errorMsg.value = props.inputErrorMessage
+      }
+    }
+
+    if (typeof inputValidator === 'string') {
+      if (inputValidator) {
+        errorMsg.value = inputValidator
+      } else {
+        next()
+      }
+    }
+
+  } else {
+    next()
+  }
+}
+
+function handleClose(val) {
+  visible.value = false
+  closeMode = val
+}
+
+
+function headerIcon() {
+  switch (props.type) {
+    case "success":
+      return h(SuccessFilled, null, null)
+    case "warning":
+      return h(Warning, null, null)
+    case 'info':
+      return h(InfoFilled, null, null)
+    case 'error':
+      return h(CircleCloseFilled)
+  }
+}
+
+function titleRender() {
+  const title = {
+    'success': '成功',
+    'warning': '警告',
+    'info': '提示',
+    'error': '错误',
+  }
+  return h('span', {style: {marginLeft: '8px'}}, title[props.type])
+}
+
+
+onMounted(async () => {
+  mainStyle.value.zIndex = nextZIndex()
+  contentStyle.value.zIndex = nextZIndex()
+  document.body.className = 'el-popup-parent--hidden'
+  await nextTick()
+  await sleep(100)
+  visible.value = true
+  props.setClose(close)
+  if (props.showInput) {
+    await inputRef.value.focus();
+  }
+})
+
+function close() {
+  handleClose('close')
+}
+
+</script>
+
+<template>
+  <div class="cy-message-box_main" :style="mainStyle" role="dialog" aria-modal="true">
+    <transition name="cy-message_show" @after-enter="onAfterEnter" @after-leave="onAfterLeave">
+      <div class="cy-message-box_body" v-show="visible" :style="contentStyle">
+        <div class="cy-message-box_close" @click="handleClose('close')">
+          <ElIcon @click="handleClose('close')">
+            <Close/>
+          </ElIcon>
+        </div>
+        <header ref="headerRef">
+          <el-icon :class="['cy-' + props.type]" class="cy-message_header-icon">
+            <component :is="headerIcon"/>
+          </el-icon>
+          <Component :is="titleRender"/>
+        </header>
+        <div class="cy_message-box_content">
+          <div class="message">
+            <component
+                v-if="props.dangerouslyUseHTMLString"
+                :for="inputId"
+                :is="props.showInput ? 'label' : 'span'"
+                v-html="props.message">
+            </component>
+            <component v-else
+                       :is="props.showInput ? 'label' : 'span'"
+                       :for="inputId">
+              {{ props.message }}
+            </component>
+          </div>
+          <div v-if="props.showInput" style="margin-top: 9px">
+            <ElInput
+                ref="inputRef"
+                :autofocus="true"
+                :rows="props.inputRows"
+                :type="props.inputRows === 0 ? '' : 'textarea'"
+                :minlength="props.inputMinLength"
+                :maxlength="props.inputMaxLength"
+                show-word-limit
+                :id="inputId"
+                v-model.trim="inputValue"/>
+          </div>
+          <div v-if="props.showInput" class="error_msg">
+            {{ errorMsg }}
+          </div>
+        </div>
+        <footer>
+          <div class="cancel"
+               v-if="props.showCancel"
+               @click="handleClose('cancel')"
+               :style="{'--cy--bg-color': '245,108,108','--cy-color': '#F56C6C'}">
+            {{ props.cancelButtonText }}
+          </div>
+          <div class="confirm" :style="{'--cy--bg-color': '26, 92, 255','--cy-color': '#2C69FF'}"
+               @click="handleConfirm">
+            {{ props.confirmButtonText }}
+          </div>
+        </footer>
+      </div>
+    </transition>
+  </div>
+
+</template>
+
+<style lang="scss">
+.cy-message_show-enter-active {
+  transform: scale(0.9);
+}
+
+.cy-message_show-enter-to {
+  transform: scale(1);
+}
+
+.cy-message_show-leave-active {
+  transform: scale(1);
+}
+
+.cy-message_show-leave-to {
+  transform: scale(0);
+}
+
+.cy-message-box_main {
+  background: rgba(0, 0, 0, .2);
+  position: fixed;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+
+  justify-content: center;
+  align-content: center;
+  -webkit-backdrop-filter: saturate(180%) blur(15px);
+  backdrop-filter: saturate(180%) blur(15px);
+
+  .cy-message-box_body {
+    height: max-content;
+    width: 418px;
+    margin: auto;
+    background-color: white;
+    border-radius: 20px;
+    padding: 5px;
+    position: relative;
+    transition: transform .2s ease-out;
+
+    .cy-message-box_close {
+      position: absolute;
+      top: -6px;
+      right: -6px;
+      border: 0;
+      height: 34px;
+      width: 34px;
+      box-sizing: border-box;
+      background: inherit;
+      border-radius: 12px;
+      box-shadow: 0 5px 20px 0 rgba(0, 0, 0, .05);
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      font-size: 20px;
+      color: black;
+      cursor: pointer;
+
+      &:hover {
+        -webkit-box-shadow: 0 0 4px 0 rgba(0, 0, 0, .05);
+        box-shadow: 0 0 4px 0 rgba(0, 0, 0, .05);
+        transform: translate(-2px, 2px);
+      }
+    }
+
+    header {
+      user-select: none;
+      display: -webkit-box;
+      display: -ms-flexbox;
+      display: flex;
+      align-items: center;
+      justify-content: start;
+      padding: 10px 16px;
+      box-sizing: border-box !important;
+
+      span {
+        margin-left: 8px;
+        font-size: 20px;
+        font-weight: bold;
+      }
+
+      .cy-message_header-icon {
+        font-size: 24px;
+      }
+
+      .cy-warning {
+        color: #e6a23c;
+      }
+
+      .cy-success {
+        color: #67c23a;
+      }
+
+      .cy-info {
+        color: #909399;
+      }
+
+      .cy-error {
+        color: #f56c6c;
+      }
+    }
+
+    .cy_message-box_content {
+      padding: 10px 16px;
+      width: 100%;
+      position: relative;
+      border-radius: inherit;
+      box-sizing: border-box;
+
+      .error_msg {
+        color: #f56c6c;
+        font-size: 12px;
+        min-height: 18px;
+        margin-top: 2px;
+      }
+
+      .message {
+        box-sizing: border-box;
+        min-height: 20px;
+        max-height: 200px;
+        overflow: auto;
+
+        &::-webkit-scrollbar {
+          width: 5px;
+          height: 5px;
+          display: block;
+          background: white;
+        }
+
+        &::-webkit-scrollbar-thumb {
+          background: #2C3E50;
+          border-radius: 5px;
+        }
+
+      }
+
+    }
+
+    footer {
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+
+      div {
+        width: 85px;
+        line-height: 39px;
+        text-align: center;
+        border-radius: 12px;
+        cursor: pointer;
+        position: relative;
+        color: var(--cy-color);
+        outline: none;
+        list-style: none;
+        user-select: none;
+
+        &:hover:before {
+          opacity: 1;
+          transform: scale(1);
+        }
+
+        &:before {
+          content: "";
+          background: rgba(var(--cy--bg-color), .1);
+          position: absolute;
+          bottom: 0;
+          left: 0;
+          width: 100%;
+          height: 100%;
+          border-radius: inherit;
+          pointer-events: none;
+          -webkit-transition: all .25s ease;
+          transition: all .25s ease;
+          z-index: -1;
+          transform: scale(.5);
+          opacity: 0;
+          box-sizing: border-box;
+        }
+      }
+
+    }
+
+  }
+}
+</style>

+ 17 - 15
src/views/hospitalization/zhu-yuan-yi-sheng/public-js/zhu-yuan-yi-sheng.ts

@@ -13,20 +13,20 @@ import {computed} from 'vue'
 import {getAncillaryInformation} from '../../../../api/zhu-yuan-yi-sheng/jian-yan-jian-cha-shen-qing'
 
 export interface PatInfo {
-    inpatientNo: string
-    admissTimes: number,
-    ledgerSn: number
-    admissDate: string
-    groupInfoName: string;
-    groupInfoWeight: string;
-    groupInfoBl: string
-    setGroupInfoProfit: string
-    groupInfoFeeStand: string
-    referPhysician: string
-    consultPhysician: string
-    deptDirector: string
-    zkWard: string
-    zkWardName: string
+    inpatientNo?: string
+    admissTimes?: number,
+    ledgerSn?: number
+    admissDate?: string
+    groupInfoName?: string;
+    groupInfoWeight?: string;
+    groupInfoBl?: string
+    setGroupInfoProfit?: string
+    groupInfoFeeStand?: string
+    referPhysician?: string
+    consultPhysician?: string
+    deptDirector?: string
+    zkWard?: string
+    zkWardName?: string
 }
 
 // 患者信息
@@ -857,7 +857,9 @@ export interface YzMitt {
     clickOnTheOrderTemplate: () => void,
     clickAssociate: (data: YzType) => Promise<void>
     rowClick: (data: YzType) => void
-    queryFeeByOrderNo: (data: YzType) => void
+    queryFeeByOrderNo: (data: YzType) => void,
+
+    [key: string]: (...args: any[]) => any
 }
 
 // type YzMitt = {

+ 174 - 0
src/views/hospitalization/zhu-yuan-yi-sheng/yi-zhu-lu-ru/components/PoisonAndAnestheticPrinting.vue

@@ -0,0 +1,174 @@
+<script setup lang="ts">
+import {onMounted, ref} from "vue";
+import {PatInfo} from "@/views/hospitalization/zhu-yuan-yi-sheng/public-js/zhu-yuan-yi-sheng";
+import JsBarcode from "jsbarcode";
+import {getLodop, initLodop} from "@/utils/c-lodop";
+import prescription from '@/assets/prescription.png'
+
+const barCodeRef = ref<HTMLImageElement>()
+const printRef = ref<HTMLDivElement>()
+
+function setData(drugList: any[], patInfo: PatInfo) {
+  JsBarcode(barCodeRef.value, patInfo.inpatientNo, {
+    lineColor: '#333',
+    width: 2,
+    height: 18,
+    displayValue: false,
+    margin: 0,
+    fontSize: 12,
+  })
+}
+
+function print() {
+  const html = `<style>*{font-size: 9.75pt}html,body {margin: 0}</style><body>${printRef.value.innerHTML}</body>`
+  console.log(html)
+  const LODOP = getLodop(null, null);
+  LODOP.PRINT_INIT('处方笺');
+  LODOP.SET_PRINT_PAGESIZE(1, '148mm', '210mm', '');
+  LODOP.SET_PRINT_MODE('FULL_WIDTH_FOR_OVERFLOW', true)
+  LODOP.ADD_PRINT_HTM('1mm', '1mm', '100%', '100%', html)
+  LODOP.PRINT_DESIGN();
+}
+
+onMounted(() => {
+  initLodop()
+  setData([], {inpatientNo: '123'})
+})
+
+
+</script>
+
+<template>
+  <div>
+    <el-button @click="print">打印</el-button>
+    <el-button v-print="'#print1'">打印1</el-button>
+  </div>
+  <div ref="printRef">
+    <div style="width: 148mm; height: 200mm;max-height: 200mm;background-color: white" id="print1">
+      <div style="text-align: center; font-weight:bolder ; position: relative; height: 35pt">
+        <div style="position: absolute; top: 0; left: 0">
+          <img ref="barCodeRef" alt="" src=""/>
+        </div>
+        <div style="font-size: 12pt">
+          长沙泰和医院
+        </div>
+        <div style="font-size: 10pt">
+          处方笺
+        </div>
+        <div style="position: absolute; top: 0; right: 0; border: 0.75pt solid #000;  width: max-content; padding: 3pt">
+          <!--        精二-->
+          麻、精<br/>一
+        </div>
+      </div>
+
+      <div style="border-bottom: 0.75pt solid #000">
+        <table style="width: 100%;border-collapse:separate; border-spacing:0 2pt;"
+               border="0"
+               cellpadding="0"
+               cellspacing="0">
+          <colgroup>
+            <col style="width: 17.2415%;">
+            <col style="width: 18.3908%;">
+            <col style="width: 11.6858%;">
+            <col style="width: 27.3946%;">
+            <col style="width: 15.9004%;">
+            <col style="width: 9.38697%;">
+          </colgroup>
+          <tbody>
+          <tr>
+            <td style="text-align: right">姓名:</td>
+            <td>asdasd</td>
+            <td style="text-align: right">性别:</td>
+            <td></td>
+            <td style="text-align: right">年龄:</td>
+            <td></td>
+          </tr>
+          <tr>
+            <td style="text-align: right">
+              住院号:
+            </td>
+            <td>
+            </td>
+            <td style="text-align: right">
+              科室:
+            </td>
+            <td rowspan="3">
+            </td>
+          </tr>
+          <tr>
+            <td style="text-align: right">
+              处方类型:
+            </td>
+            <td>
+            </td>
+            <td style="text-align: right">
+              处方时间:
+            </td>
+            <td rowspan="3">
+            </td>
+          </tr>
+          <tr>
+            <td style="text-align: right">身份证号码:</td>
+            <td rowspan="4"></td>
+          </tr>
+          <tr>
+            <td style="text-align: right">诊断:</td>
+            <td rowspan="4"></td>
+          </tr>
+          </tbody>
+        </table>
+      </div>
+      <div style="height: 6pt"/>
+      <div>
+        <img :src="prescription" alt="">
+      </div>
+
+      <div style=" height: 400pt;border-bottom: 0.75pt solid #000">
+        <table style="width: 100%;max-height: 380pt;min-height: 10pt" border="0" cellpadding="0" cellspacing="0">
+
+        </table>
+        <div>
+          -----(以下留白)-----
+        </div>
+      </div>
+      <div style="height: 1pt"></div>
+      <div style="width: 100%; padding: 0 2pt;box-sizing: border-box;">
+        <table style="width: 100%;border-collapse:separate; border-spacing:0 2pt;" border="0" cellpadding="0"
+               cellspacing="0">
+          <colgroup>
+            <col width="12%"/>
+            <col width="38%"/>
+            <col width="22%"/>
+            <col width="28%"/>
+          </colgroup>
+          <tbody>
+          <tr>
+            <td>处方金额:</td>
+            <td style="border-bottom: 0.75pt solid #000">
+              asdasd
+            </td>
+            <td style="text-align: right">医师:</td>
+            <td style="border-bottom: 0.75pt solid #000"></td>
+          </tr>
+          <tr>
+            <td>审核药师:</td>
+            <td style="border-bottom: 0.75pt solid #000"></td>
+            <td style="text-align: right">核对药师:</td>
+            <td style="border-bottom: 0.75pt solid #000"></td>
+          </tr>
+          <tr>
+            <td>调配药师:</td>
+            <td style="border-bottom: 0.75pt solid #000"></td>
+            <td style="text-align: right">发药药师:</td>
+            <td style="border-bottom: 0.75pt solid #000"></td>
+          </tr>
+          </tbody>
+        </table>
+      </div>
+    </div>
+  </div>
+</template>
+
+<style scoped lang="scss">
+
+</style>