123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517 |
- <script setup lang="ts">
- import {stringIsBlank, stringNotBlank} from "@/utils/blank-utils";
- import {
- associateOrders,
- clearAssociate,
- jsQueryYzData,
- openDrugManual,
- OrderBy,
- queryParam,
- tempYzData,
- yiZhuData,
- yzMitt,
- YzType
- } from "@/views/hospitalization/zhu-yuan-yi-sheng/public-js/zhu-yuan-yi-sheng";
- import {h, nextTick, reactive, ref} from 'vue'
- import {VxeTable, VxeTablePropTypes} from 'vxe-table'
- import {nullToEmpty} from '@/utils/public'
- import {getFormatDatetime} from '@/utils/date'
- import {getServerDateApi} from '@/api/public-api'
- import {updateOrderInstruction} from '@/api/zhu-yuan-yi-sheng/yi-zhu-lu-ru'
- import sleep from "../../../../../../utils/sleep";
- import {ElButton, ElButtonGroup} from "element-plus";
- import {xcMessage} from "@/utils/xiaochan-element-plus";
- import XEUtils from "xe-utils";
- import {TablePublicMethods} from "vxe-table/types/table";
- const props = defineProps({
- height: {
- type: [Number]
- },
- width: {
- type: [Number]
- }
- })
- const emits = defineEmits(['rowClick', 'voidOrders'])
- const tableRef = ref<TablePublicMethods>()
- const toggleAllCheckboxEvent = () => {
- const $table = tableRef.value
- if ($table) {
- $table!.toggleAllCheckboxRow()
- }
- }
- const toggleCheckboxEvent = (row) => {
- const $table = tableRef.value
- if ($table) {
- $table!.toggleCheckboxRow(row)
- }
- }
- interface MenuClick {
- $event: Event,
- row: YzType,
- menu: { code: string, name: string, disabled?: boolean },
- column: any
- }
- // 鼠标右键配置文件
- const menuConfig = reactive<VxeTablePropTypes.MenuConfig>({
- body: {
- options: [
- [
- {code: 'fee', name: '医嘱费用'}
- ],
- [
- {code: 'copy', name: '复制', prefixIcon: 'vxe-icon-copy'}
- ],
- [
- {
- code: 'paste',
- name: '粘贴',
- prefixIcon: 'vxe-icon-paste'
- }
- ],
- [
- {code: 'relevancy', name: '关联'}
- ],
- [
- {code: 'exitTheAssociation', name: '退出关联'}
- ],
- [
- {
- code: 'instructions',
- name: '说明书'
- }
- ],
- [
- {
- code: 'stopTime',
- name: '停止医嘱'
- }
- ]
- ],
- },
- visibleMethod({options, column, row}) {
- options.forEach(list => {
- list.forEach((item) => {
- item.disabled = true
- if (item.code === 'paste') {
- item.disabled = !yzMitt.emit('allowReplication')
- }
- if (row) {
- if (['copy', 'relevancy', 'exitTheAssociation'].includes(item.code)) {
- item.disabled = false
- }
- if (['relevancy', 'instructions'].includes(item.code)) {
- item.disabled = row.serial == '00'
- }
- if (item.code === 'fee') {
- item.disabled = false
- }
- if (item.code === 'stopTime') {
- item.disabled = !showEndTime(row)
- }
- }
- })
- })
- return true
- }
- })
- // 鼠标右键执行的函数
- const rightFunc = {
- "fee": (data: YzType) => {
- yzMitt.emit('queryFeeByOrderNo', data)
- },
- "copy": (data: YzType) => {
- yzMitt.emit('copy', data.actOrderNo, data.frequCode)
- },
- "paste": (data: YzType) => {
- yzMitt.emit('paste')
- },
- "relevancy": async (data: YzType) => {
- if (canBeAssociated(data, true)) {
- if (associateOrders.value.actOrderNo === null) {
- await jsQueryYzData()
- associateOrders.value.actOrderNo = data.actOrderNo
- } else {
- xcMessage.error('请先确认当前关联医嘱。')
- }
- }
- },
- "exitTheAssociation": (data: YzType) => {
- clearAssociate()
- },
- "instructions": (data: YzType) => {
- openDrugManual(data.orderCode, data.serial)
- },
- "stopTime": (data) => {
- if (tableRef.value.isCheckedByCheckboxRow(data)) {
- cancelStopTime(data)
- } else {
- setDefaultStopTime({row: data})
- }
- }
- }
- // 触发鼠标右键的事件
- const tableRightClick = (val: MenuClick) => {
- let {row, menu} = val
- try {
- rightFunc[menu.code](row)
- } catch {
- }
- }
- function canBeAssociated(data: YzType, showMessage = false) {
- function message(message) {
- showMessage && xcMessage.error(message);
- }
- if (stringNotBlank(data.parentNo)) {
- message('该医嘱已经有父医嘱了。');
- return false
- } else if (data.statusFlag !== '1') {
- message('不是录入状态的医嘱无法关联。');
- return false
- } else if (data.serial === '00') {
- message('项目无法关联。');
- return false
- }
- return true
- }
- const twinkleList = ref({})
- const rowClassName = ({row, rowIndex}) => {
- let data = row as YzType
- if (typeof twinkleList.value[data.actOrderNo] !== 'undefined') {
- sleep(3000).then(() => {
- delete twinkleList.value[data.actOrderNo]
- })
- return 'animation_hzfirst'
- } else if (typeof twinkleList.value[data.parentNo] !== 'undefined') {
- return 'animation_hzfirst'
- }
- // 父级
- if (data.associationFlag) {
- return 'parent_level'
- }
- // 子级
- if (associateOrders.value.actOrderNo === data.actOrderNo) {
- return 'child_level'
- }
- if (data.actOrderNo === yiZhuData.value.actOrderNo) {
- return 'activation'
- }
- }
- const setDefaultStopTime = async (val) => {
- let {row} = val
- if (showEndTime(row)) {
- row.endTimeTemp = getFormatDatetime(await getServerDateApi(), 'YYYY-MM-DDTHH:mm')
- await tableRef.value.setCheckboxRow(row, true)
- }
- }
- const endTimeChange = (val, row) => {
- if (stringIsBlank(val)) {
- tableRef.value.setCheckboxRow(row, false)
- } else {
- tableRef.value.setCheckboxRow(row, true)
- }
- }
- const cancelStopTime = (row) => {
- if (row.parentNo) return
- row.endTimeTemp = ''
- tableRef.value.setCheckboxRow(row, false)
- }
- const instructionEnter = (row: YzType) => {
- updateOrderInstruction(row.actOrderNo, row.instruction)
- }
- function getYiZhuFlag(val) {
- if (stringIsBlank(val)) {
- return val
- }
- switch (val) {
- case '1':
- return h('span', {style: {color: '#05ff00'}}, 'R')
- case '2':
- return h('span', {style: {color: '#0000fb'}}, 'Q')
- case '3':
- return h('span', {style: {color: '#ff07f3'}}, 'Z')
- case '4':
- return h('span', {style: {color: '#ff07f3'}}, 'Z')
- case '5':
- return h('span', {style: {color: 'red'}}, 'T')
- case '-1':
- return h('span', {style: {color: '#00ffe0'}}, 'D')
- default:
- return 'warning'
- }
- }
- const timeFomat = (val) => {
- return getFormatDatetime(val, 'YY-MM-DD HH:mm')
- }
- const showEndTime = (data: YzType) => {
- if (!data) {
- return false
- }
- return stringIsBlank(data.endTime) && stringIsBlank(data.parentNo) && data.frequCode !== 'ONCE';
- }
- const rowClick = ({row}) => {
- emits('rowClick', row)
- }
- const endDateStyle = (item) => {
- if (item.endTimeTemp && tableRef.value!.isCheckedByCheckboxRow(item)) {
- return {
- width: '140px',
- color: 'white',
- backgroundColor: 'red',
- border: 0,
- }
- } else {
- return {
- width: '140px',
- border: 0,
- }
- }
- }
- function groupConversion(value: string) {
- if (queryParam.value.sort === OrderBy.desc) {
- switch (value) {
- case '┌':
- return "└";
- case '└':
- return "┌";
- case "丨":
- return "丨"
- default:
- return value;
- }
- }
- return value
- }
- yzMitt.on('tableScroll', (val) => {
- tableRef.value!.scrollTo(0, val)
- })
- yzMitt.on('clearSelected', () => {
- tableRef.value!.clearSelected()
- })
- yzMitt.on('scrollEndAndTwinkle', async (val: any) => {
- twinkleList.value = val;
- await nextTick()
- await sleep(500)
- if (queryParam.value.sort === OrderBy.asc) {
- const tmp = tableRef.value!.getData()
- await tableRef.value!.scrollTo(0, tmp.length * 24)
- } else {
- await tableRef.value?.scrollTo(0, 0);
- }
- })
- yzMitt.on('setOrderNoTwinkle', async (val: number) => {
- twinkleList.value[val] = true;
- await nextTick()
- await sleep(500)
- if (queryParam.value.sort === OrderBy.asc) {
- const tmp = tableRef.value!.getData()
- tableRef.value!.scrollTo(0, tmp.length * 24)
- } else {
- await tableRef.value?.scrollTo(0, 0);
- }
- })
- yzMitt.on('getSelectedData', () => {
- return XEUtils.clone(tableRef.value!.getCheckboxRecords(), true) as YzType[]
- })
- </script>
- <template>
- <vxe-table
- border
- height="auto"
- sync-resize
- auto-resize
- :menu-config="menuConfig"
- @menu-click="tableRightClick"
- @cell-dblclick="setDefaultStopTime"
- @cell-click="rowClick"
- :scroll-x="{gt: 40,enabled: false}"
- :scroll-y="{gt: 0,enabled: true}"
- :column-config="{resizable: true}"
- :row-config="{height: 24, isHover: true, keyField:'actOrderNo'}"
- class="vxe-padding_zero vxe-header-max_content hl-style"
- header-row-class-name="padding_zero"
- show-header-overflow
- show-overflow
- :row-class-name="rowClassName"
- ref="tableRef"
- :data="tempYzData">
- <vxe-column type="checkbox" width="20">
- <template #header="{ checked, indeterminate }">
- <span class="custom-checkbox" @click.stop="toggleAllCheckboxEvent">
- <i v-if="indeterminate" class="vxe-icon-square-minus-fill"></i>
- <i v-else-if="checked" class="vxe-icon-square-checked-fill"></i>
- <i v-else class="vxe-icon-checkbox-unchecked"></i>
- </span>
- </template>
- <template #checkbox="{ row, checked, indeterminate }">
- <span class="custom-checkbox" @click.stop="toggleCheckboxEvent(row)">
- <i v-if="indeterminate" class="vxe-icon-square-minus-fill"></i>
- <i v-else-if="checked" class="vxe-icon-square-checked-fill"></i>
- <i v-else class="vxe-icon-checkbox-unchecked"></i>
- </span>
- </template>
- </vxe-column>
- <vxe-column type="seq" width="30"/>
- <vxe-column field="orderGroup" title="组" width="20">
- <template #default={row}>
- <span>{{ groupConversion(row['orderGroup']) }}</span>
- </template>
- </vxe-column>
- <vxe-column field="statusFlag" width="20">
- <template #default="scope">
- <component :is="getYiZhuFlag(scope.row.statusFlag)"/>
- </template>
- </vxe-column>
- <vxe-column field="actOrderNo" title="医嘱号" width="70"/>
- <vxe-column field="orderName" title="医嘱名称" width="225"/>
- <vxe-column field="dose" title="剂量" width="65">
- <template #default="{row}">
- {{ nullToEmpty(row.dose) + ' ' + nullToEmpty(row.doseUnitName) }}
- </template>
- </vxe-column>
- <vxe-column field="frequCode" title="频率" width="75"/>
- <vxe-column field="supplyCodeName" title="给药方式" width="60"/>
- <vxe-column field="startTime" title="开始时间" width="100">
- <template #default="{row}">
- {{ timeFomat(row.startTime) }}
- </template>
- </vxe-column>
- <vxe-column field="endTime" title="结束时间" width="150">
- <template #default="scope">
- <input v-if="showEndTime(scope.row)"
- type='datetime-local'
- @click.stop
- @change="endTimeChange(scope.row.endTimeTemp, scope.row)"
- @contextmenu.stop.prevent="cancelStopTime(scope.row)"
- :style="endDateStyle(scope.row)"
- v-model="scope.row.endTimeTemp"/>
- <span v-else>{{ timeFomat(scope.row.endTime) }}</span>
- </template>
- </vxe-column>
- <vxe-column field="emergencyFlag" title="紧急" width="30">
- <template #default="{row}">
- {{ row.emergencyFlag === '1' ? '√' : '' }}
- </template>
- </vxe-column>
- <vxe-column field="ybSelfFlag" title="自费" width="30">
- <template #default="{row}">
- {{ row.ybSelfFlag === '1' ? '√' : '' }}
- </template>
- </vxe-column>
- <vxe-column field="physicianName" title="医生" width="65"/>
- <vxe-column field="selfBuyName" title="费用标志" width="60"/>
- <vxe-column field="execUnitName" title="执行科室" width="80"/>
- <vxe-column field="drugQuan" title="领量" width="30">
- <template #default="{row}">
- {{ nullToEmpty(row.drugQuan) + nullToEmpty(row.miniUnitName) }}
- </template>
- </vxe-column>
- <vxe-column field="groupNoName" title="药房" width="91"/>
- <vxe-column field="serial" title="序号" width="35"/>
- <vxe-column field="instruction" title="嘱托" width="180">
- <template #default="scope">
- <input v-if="scope.row.statusFlag === '1' || scope.row.statusFlag === '2' "
- :title="scope.row.instruction"
- v-model="scope.row.instruction"
- :maxlength="50"
- @keydown.enter="instructionEnter(scope.row)"
- />
- <span v-else>{{ scope.row.instruction }}</span>
- </template>
- </vxe-column>
- <vxe-column field="right" title="操作" width="95" fixed="right">
- <template #default="{row}">
- <el-button-group
- >
- <el-button text
- type="warning"
- @click.stop.prevent="emits('voidOrders', row)"
- >
- 作废
- </el-button>
- <el-button text
- type="danger"
- @click.stop.prevent="yzMitt.emit('deleteAnOrderByOrderNo', row, false)"
- >
- 删除
- </el-button>
- </el-button-group>
- </template>
- </vxe-column>
- </vxe-table>
- </template>
- <style lang="scss">
- @keyframes hzfirst {
- from {
- background-color: #95d475
- }
- to {
- background-color: white;
- }
- }
- .animation_hzfirst {
- td {
- animation: hzfirst 1s linear infinite
- }
- }
- .activation {
- background-color: #5376e7cc !important;
- color: white;
- }
- .parent_level {
- background-color: red;
- color: white;
- }
- .child_level {
- background-color: rgba(3, 255, 15);
- color: black;
- }
- </style>
|