|
@@ -1,429 +0,0 @@
|
|
|
-<template>
|
|
|
- <el-scrollbar>
|
|
|
- <div class="yz_table">
|
|
|
- <table>
|
|
|
- <colgroup>
|
|
|
- <col v-for="item in header" :style="{width: item.width + 'px'}"/>
|
|
|
- </colgroup>
|
|
|
- <thead>
|
|
|
- <tr>
|
|
|
- <th v-for="(item,index) in header">
|
|
|
- <div v-if="index === 0" @click="clearSelected" style="cursor: default">
|
|
|
- #
|
|
|
- </div>
|
|
|
- <span v-else>
|
|
|
- {{ item.name }}
|
|
|
- </span>
|
|
|
- </th>
|
|
|
- </tr>
|
|
|
- </thead>
|
|
|
- </table>
|
|
|
- <el-scrollbar :height="maxHeight"
|
|
|
- @scroll="scroll"
|
|
|
- ref="elScrollbarRef">
|
|
|
- <div :style="{height: virtualHeight + 'px'}"
|
|
|
- ref="virtualHeightRef"
|
|
|
- style="position: relative">
|
|
|
- <table :style="{top:` ${translateY}px`}" style="position: absolute">
|
|
|
- <colgroup>
|
|
|
- <col v-for="item in header" :style="{width: item.width + 'px'}"/>
|
|
|
- </colgroup>
|
|
|
- <tbody>
|
|
|
- <tr v-for="(item,index) in tempYzData.slice(startIndex, startIndex + itemCount)"
|
|
|
- @click="rowClick(item)"
|
|
|
- @dblclick.stop="setDefaultStopTime(item)"
|
|
|
- @contextmenu="contextmenuItem(item,index,$event)"
|
|
|
- :style="rowStyle(item,index)">
|
|
|
- <td v-for="(he,heindex) in header"
|
|
|
- :title="item[he.code]">
|
|
|
- <div v-if="heindex === 0">
|
|
|
- <input type="checkbox"
|
|
|
- @click.stop="clickSelected(item)"
|
|
|
- v-model="item.tempCheckbox">
|
|
|
- </div>
|
|
|
- <div
|
|
|
- v-else-if="heindex === 10
|
|
|
- && stringIsBlank(item.endTime)
|
|
|
- && stringIsBlank(item.parentNo)
|
|
|
- && item.frequCode !== 'ONCE' ">
|
|
|
- <input type="datetime-local"
|
|
|
- v-model="item.endTimeTemp"
|
|
|
- :style="endDateStyle(item)"
|
|
|
- @click.stop
|
|
|
- @contextmenu.stop.prevent="cancelStopTime(item)"
|
|
|
- @dblclick.stop="setDefaultStopTime(item)">
|
|
|
- </div>
|
|
|
- <div v-else-if="heindex === 20">
|
|
|
- <button @click.stop="props.voidOrders(item)">作废</button>
|
|
|
- </div>
|
|
|
- <div v-else-if="he.func" v-html="he.func(item,startIndex + index)"/>
|
|
|
- <div v-else>
|
|
|
- {{ item[he.code] }}
|
|
|
- </div>
|
|
|
- </td>
|
|
|
- </tr>
|
|
|
- </tbody>
|
|
|
- </table>
|
|
|
- </div>
|
|
|
- </el-scrollbar>
|
|
|
- </div>
|
|
|
- </el-scrollbar>
|
|
|
-
|
|
|
- <right-click-menu :mouse-position="mousePosition" :config="opt"/>
|
|
|
-
|
|
|
-</template>
|
|
|
-
|
|
|
-<script setup name='YzTable' lang="tsx">
|
|
|
-import {stringIsBlank} from "@/utils/blank-utils";
|
|
|
-import {
|
|
|
- selectedData,
|
|
|
- tempYzData,
|
|
|
- yiZhuData,
|
|
|
- associateOrders,
|
|
|
- clearAssociate,
|
|
|
- drugManual,
|
|
|
- yzData
|
|
|
-} from "@/views/hospitalization/zhu-yuan-yi-sheng/public-js/zhu-yuan-yi-sheng";
|
|
|
-import {getFormatDatetime} from "@/utils/date";
|
|
|
-import {defineEmits, defineProps, nextTick, ref, watch} from 'vue'
|
|
|
-import sleep from "@/utils/sleep";
|
|
|
-import store from "@/store"
|
|
|
-import {ElScrollbar} from "element-plus";
|
|
|
-import RightClickMenu from "@/components/menu-item/RightClickMenu.vue";
|
|
|
-import {useIntersectionObserver} from "@vueuse/core";
|
|
|
-
|
|
|
-const props = defineProps({
|
|
|
- data: {
|
|
|
- type: Array
|
|
|
- },
|
|
|
- voidOrders: Function
|
|
|
-})
|
|
|
-
|
|
|
-const emit = defineEmits(['rowClick', 'clickAssociate'])
|
|
|
-
|
|
|
-const header = [
|
|
|
- {
|
|
|
- width: 15, name: '#'
|
|
|
- },
|
|
|
- {
|
|
|
- func: (val, index) => {
|
|
|
- return `${index + 1}`
|
|
|
- },
|
|
|
- width: 20
|
|
|
- },
|
|
|
- {code: 'orderGroup', name: '组', width: 10},
|
|
|
- {
|
|
|
- code: 'statusFlag', name: '状态', func: (val) => {
|
|
|
- return getYiZhuFlag(val.statusFlag)
|
|
|
- },
|
|
|
- width: 20
|
|
|
- },
|
|
|
- {
|
|
|
- code: 'actOrderNo', name: '医嘱号', width: 40, func: (val) => {
|
|
|
- if (val.error) {
|
|
|
- return `<span style="color: red" class="${val.newOrderFlag > 0 ? 'new_order' : ''}">${nu(val.actOrderNo)}</span>`
|
|
|
- } else {
|
|
|
- return `<span class="${val.newOrderFlag > 0 ? 'new_order' : ''}">${nu(val.actOrderNo)}</span>`
|
|
|
- }
|
|
|
- }
|
|
|
- },
|
|
|
- {
|
|
|
- code: 'orderName', name: '医嘱名称', width: 120
|
|
|
- },
|
|
|
- {
|
|
|
- code: 'dose', name: '剂量', width: 40, func: (val) => {
|
|
|
- return nu(val.dose) + ' ' + nu(val.doseUnitName)
|
|
|
- }
|
|
|
- },
|
|
|
- {code: 'frequCode', name: '频率', width: 42},
|
|
|
- {code: 'supplyCodeName', name: '给药方式', width: 50},
|
|
|
- {
|
|
|
- code: 'startTime', name: '开始时间', width: 50, func: (val) => {
|
|
|
- return timeFomat(val.startTime)
|
|
|
- }
|
|
|
- },
|
|
|
- {
|
|
|
- // 出院时间的大小不能改
|
|
|
- code: 'endTime', name: '结束时间', width: 90, func: (val) => {
|
|
|
- return timeFomat(val.endTime)
|
|
|
- }
|
|
|
- },
|
|
|
- {
|
|
|
- code: 'emergencyFlag', name: '紧急', func: (val) => {
|
|
|
- return `${val.emergencyFlag === '1' ? '√' : ''}`
|
|
|
- },
|
|
|
- width: 20
|
|
|
- },
|
|
|
- {
|
|
|
- code: 'ybSelfFlag', name: '自费', width: 20, func: (val) => {
|
|
|
- return val.ybSelfFlag === 1 ? '√' : ''
|
|
|
- }
|
|
|
- },
|
|
|
- {code: 'physicianName', name: '医生', width: 30},
|
|
|
- {code: 'selfBuyName', name: '费用标志', width: 30},
|
|
|
- {code: 'execUnitName', name: '执行科室', width: 40},
|
|
|
- {
|
|
|
- code: 'drugQuan', name: '领量', func: (val) => {
|
|
|
- return nu(val.drugQuan) + nu(val.drugQuanName)
|
|
|
- },
|
|
|
- width: 20
|
|
|
- },
|
|
|
- {code: 'groupNoName', name: '药房', width: 50},
|
|
|
- {code: 'serial', name: '序号', width: 20},
|
|
|
- {code: 'instruction', name: '嘱托', width: 80},
|
|
|
- {name: '操作', width: 30}
|
|
|
-];
|
|
|
-
|
|
|
-const virtualHeightRef = ref(null)
|
|
|
-const elScrollbarRef = ref<InstanceType<typeof ElScrollbar>>()
|
|
|
-/*
|
|
|
-* 不知道为什么路由切换的时候 elScrollbar 会没有滚动到指定的位置,
|
|
|
-* 判断页面元素是否存在如果在的话,设置为0后在设置到指定的位置
|
|
|
-* */
|
|
|
-useIntersectionObserver(elScrollbarRef,
|
|
|
- ([{isIntersecting}], observerElement) => {
|
|
|
- if (isIntersecting) {
|
|
|
- elScrollbarRef.value!.setScrollTop(0)
|
|
|
- elScrollbarRef.value!.setScrollTop(translateY.value)
|
|
|
- }
|
|
|
- },
|
|
|
-)
|
|
|
-
|
|
|
-const timeFomat = (val) => {
|
|
|
- return getFormatDatetime(val, 'YY-MM-DD HH:mm')
|
|
|
-}
|
|
|
-
|
|
|
-const endDateStyle = (item) => {
|
|
|
- if (item.endTimeTemp && item.tempCheckbox) {
|
|
|
- return {
|
|
|
- color: 'red'
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-const rowStyle = (item, index) => {
|
|
|
- if (associateOrders.value.actOrderNo === item.actOrderNo) {
|
|
|
- return {
|
|
|
- background: 'rgba(3,255,15,0.68)',
|
|
|
- color: '#fff'
|
|
|
- }
|
|
|
- }
|
|
|
- if (item.actOrderNo === yiZhuData.value.actOrderNo) {
|
|
|
- return {
|
|
|
- background: 'rgba(0, 58, 241, 0.68)',
|
|
|
- color: '#fff'
|
|
|
- }
|
|
|
- }
|
|
|
- if (item.associationFlag) {
|
|
|
- return {
|
|
|
- background: 'red',
|
|
|
- color: '#fff'
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-const clearSelected = () => {
|
|
|
- selectedData.value = []
|
|
|
- for (let i = 0, len = yzData.value.length; i < len; i++) {
|
|
|
- yzData.value[i].tempCheckbox = false
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-const clickSelected = async (row) => {
|
|
|
- await nextTick()
|
|
|
- await sleep(100)
|
|
|
- let index = selectedData.value.indexOf(row)
|
|
|
- if (index > -1) {
|
|
|
- row.tempCheckbox = false
|
|
|
- selectedData.value.splice(index, 1)
|
|
|
- } else {
|
|
|
- row.tempCheckbox = true
|
|
|
- selectedData.value.push(row)
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-const setDefaultStopTime = (val) => {
|
|
|
- if (val.parentNo) return
|
|
|
- val.endTimeTemp = getFormatDatetime(new Date(), 'yyyy-MM-DD HH:mm')
|
|
|
- if (!val.tempCheckbox) {
|
|
|
- clickSelected(val)
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-const cancelStopTime = (val) => {
|
|
|
- if (val.parentNo) return
|
|
|
- val.endTimeTemp = ''
|
|
|
- if (val.tempCheckbox) {
|
|
|
- clickSelected(val)
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-// div 的最大高度
|
|
|
-const maxHeight = ref(500)
|
|
|
-// 开始位置
|
|
|
-const startIndex = ref(0)
|
|
|
-// 可以看见 的 内容大小
|
|
|
-const itemCount = ref(0)
|
|
|
-// 实际的高度
|
|
|
-const virtualHeight = ref(0)
|
|
|
-// 每一个 元素的大小
|
|
|
-const itemHeight = ref(27)
|
|
|
-// 偏移量
|
|
|
-const translateY = ref(0)
|
|
|
-
|
|
|
-const scroll = ({scrollTop}) => {
|
|
|
- translateY.value = scrollTop
|
|
|
- startIndex.value = Math.floor(scrollTop / itemHeight.value)
|
|
|
-}
|
|
|
-
|
|
|
-const rowClick = (val) => {
|
|
|
- emit('rowClick', val)
|
|
|
-}
|
|
|
-
|
|
|
-watch(() => tempYzData.value, (oldData, newData) => {
|
|
|
- if (oldData.length !== newData.length) {
|
|
|
- itemCount.value = Math.ceil(maxHeight.value / itemHeight.value)
|
|
|
- virtualHeight.value = itemHeight.value * tempYzData.value.length
|
|
|
- }
|
|
|
-})
|
|
|
-
|
|
|
-
|
|
|
-const calculateTableHeight = async () => {
|
|
|
- await nextTick()
|
|
|
- let windowSize = store.state['app']['windowSize']
|
|
|
- maxHeight.value = Math.ceil(windowSize.h / 2) - 10
|
|
|
- virtualHeight.value = itemHeight.value * tempYzData.value.length
|
|
|
-}
|
|
|
-
|
|
|
-watch(() => store.state['app']['windowSize'], () => {
|
|
|
- calculateTableHeight()
|
|
|
-}, {immediate: true})
|
|
|
-
|
|
|
-const scrollToTheEnd = () => {
|
|
|
- elScrollbarRef.value!.setScrollTop(virtualHeight.value)
|
|
|
-}
|
|
|
-
|
|
|
-const mousePosition = ref()
|
|
|
-const opt = [
|
|
|
- {
|
|
|
- name: '关联', click: (data, index) => {
|
|
|
- emit('clickAssociate', data)
|
|
|
- }
|
|
|
- }, {
|
|
|
- name: '退出关联模式', click: () => {
|
|
|
- clearAssociate()
|
|
|
- }
|
|
|
- }, {
|
|
|
- name: '药品说明书', click: (data) => {
|
|
|
- if (data.groupNo !== '00') {
|
|
|
- drugManual.value.open(data.orderCode, data.serial);
|
|
|
- }
|
|
|
- }
|
|
|
- }, {
|
|
|
- name: '停止医嘱', click: (data) => {
|
|
|
- if (data.tempCheckbox) {
|
|
|
- cancelStopTime(data)
|
|
|
- } else {
|
|
|
- setDefaultStopTime(data)
|
|
|
- }
|
|
|
- },
|
|
|
- validator: (data) => {
|
|
|
- return !data.parentNo;
|
|
|
- }
|
|
|
- }
|
|
|
-]
|
|
|
-const contextmenuItem = async (item, index, event) => {
|
|
|
- event.returnValue = false
|
|
|
- mousePosition.value = {
|
|
|
- event,
|
|
|
- data: item,
|
|
|
- index
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-defineExpose({
|
|
|
- scrollToTheEnd
|
|
|
-})
|
|
|
-
|
|
|
-
|
|
|
-const nu = (val) => {
|
|
|
- if (val === null) {
|
|
|
- return ''
|
|
|
- } else if (typeof val === 'undefined') {
|
|
|
- return ''
|
|
|
- } else {
|
|
|
- return val
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-function getYiZhuFlag(val) {
|
|
|
- if (stringIsBlank(val)) {
|
|
|
- return val
|
|
|
- }
|
|
|
- switch (val) {
|
|
|
- case '1':
|
|
|
- return '<span style="color: #05ff00">R</span>'
|
|
|
- case '2':
|
|
|
- return '<span style="color: #0000fb">Q</span>'
|
|
|
- case '3':
|
|
|
- return '<span style="color: #ff07f3">Z</span>'
|
|
|
- case '4':
|
|
|
- return '<span style="color: #ff07f3">Z</span>'
|
|
|
- case '5':
|
|
|
- return '<span style="color: red">T</span>'
|
|
|
- case '-1':
|
|
|
- return '<span style="color: #00ffe0">D</span>'
|
|
|
- default:
|
|
|
- return 'warning'
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-</script>
|
|
|
-
|
|
|
-<style lang="scss">
|
|
|
-.yz_table {
|
|
|
- width: 1600px;
|
|
|
- height: max-content;
|
|
|
-
|
|
|
- table {
|
|
|
- width: 100%;
|
|
|
- border-spacing: 0;
|
|
|
- border-collapse: separate;
|
|
|
- table-layout: fixed;
|
|
|
-
|
|
|
- tr {
|
|
|
- height: 25px;
|
|
|
- }
|
|
|
-
|
|
|
- tr, td, th {
|
|
|
- border: 1px solid #fff;
|
|
|
- }
|
|
|
-
|
|
|
- td {
|
|
|
- height: 20px;
|
|
|
- width: 100%;
|
|
|
- word-break: keep-all; /* 不换行 */
|
|
|
- white-space: nowrap; /* 不换行 */
|
|
|
- overflow: hidden; /* 内容超出宽度时隐藏超出部分的内容 */
|
|
|
- text-overflow: ellipsis; /* 当对象内文本溢出时显示省略标记(...) ;需与overflow:hidden;一起使用*/
|
|
|
-
|
|
|
- .new_order {
|
|
|
- position: relative;
|
|
|
-
|
|
|
- &:before {
|
|
|
- position: absolute;
|
|
|
- right: -6px;
|
|
|
- font-size: 15px;
|
|
|
- top: -5px;
|
|
|
- content: "*";
|
|
|
- color: red;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-</style>
|