Browse Source

优化表格

xiaochan 2 years ago
parent
commit
d95584347e

+ 3 - 1
src/components/xiao-chan/xc-table-v2/XcTableV2.vue

@@ -307,6 +307,7 @@ onMounted(async () => {
         }
       },
   )
+
   containerProps.ref.value.addEventListener('scroll', () => {
     tempScrollTop = containerProps.ref.value.scrollTop
     headerRef.value.scrollLeft = containerProps.ref.value.scrollLeft
@@ -318,7 +319,8 @@ defineExpose({
   scrollToByData,
   scrollToByKey,
   scrollTo,
-  clearSelected
+  clearSelected,
+  dataRef
 })
 
 

+ 1 - 27
src/components/zhu-yuan-yi-sheng/yi-zhu-lu-ru/table/YzTableV2.vue

@@ -293,17 +293,6 @@ const clickSelected = (isSelected, data, index) => {
 }
 
 const twinkleList = ref({})
-const scrollTo = (key) => {
-  twinkleList.value[key] = true
-  let index = XEUtils.findLastIndexOf(tempYzData.value, (item) => {
-    return item.actOrderNo === key
-  })
-
-  if (index > -1) {
-    tableRef.value.scrollTo(index)
-  }
-
-}
 
 const scrollToEnd = async () => {
   await nextTick()
@@ -384,11 +373,6 @@ const contextmenuItem = (data, index, event) => {
   }
 }
 
-const callTemplate = (list) => {
-  twinkleList.value = list
-  scrollToEnd()
-}
-
 onMounted(() => {
 
   yzMitt.on('tableScroll', (val) => {
@@ -407,7 +391,7 @@ onMounted(() => {
 
 
   yzMitt.on('setOrderNoTwinkle', async (val) => {
-    scrollTo(val)
+    twinkleList.value[val] = true
   })
 
   yzMitt.on('getSelectedData', () => {
@@ -416,16 +400,6 @@ onMounted(() => {
 
 })
 
-watch(() => tempYzData.value.length, () => {
-  tableRef.value.scrollTo(0)
-})
-
-defineExpose({
-  scrollTo,
-  scrollToEnd,
-  callTemplate
-})
-
 </script>
 
 <style lang="scss">

+ 16 - 75
src/components/zhu-yuan-yi-sheng/yi-zhu-lu-ru/yz-edit/YzEditor.vue

@@ -276,7 +276,7 @@ import {
   frequCodeEnum,
   yaoPinPingLvData,
   geiYaoFangShiData,
-  yzMitt, huanZheXinXi, frequencyConfig
+  yzMitt, huanZheXinXi, frequencyConfig, addTempOrderNo, yiZhuDataInit, setYzOrderGroup
 } from "@/views/hospitalization/zhu-yuan-yi-sheng/public-js/zhu-yuan-yi-sheng";
 import {ElMessageBox} from "element-plus";
 import YzDialog from "@/components/zhu-yuan-yi-sheng/yi-zhu-lu-ru/dialog/YzDialog";
@@ -320,7 +320,7 @@ const xuanZhongFeiYong = async (row, laiyuan = 1) => {
     qingKong()
     return BizException(ExceptionEnum.LOGICAL_ERROR, '出院带药不能开项目')
   }
-  if (yiZhuData.value.actOrderNo === 'tempOrderNo') {
+  if (yiZhuData.value.actOrderNo === addTempOrderNo) {
     yiZhuData.value.actOrderNo = await getOrderNo()
   }
   let tempOrderNo = null
@@ -409,8 +409,7 @@ const xuanZhongFeiYong = async (row, laiyuan = 1) => {
     } catch (e) {
       if (yiZhuData.value.statusFlag === '1') {
         await Sleep(200);
-        qingKong();
-        yiZhuData.value.actOrderNo === 'tempOrderNo'
+        setTheTemporaryVariableMedicalOrder()
       }
     }
   } else {
@@ -433,8 +432,7 @@ const xuanZhongFeiYong = async (row, laiyuan = 1) => {
     } catch (e) {
       if (yiZhuData.value.statusFlag === '1') {
         await Sleep(200)
-        qingKong()
-        yiZhuData.value.actOrderNo === 'tempOrderNo'
+        setTheTemporaryVariableMedicalOrder()
       }
     }
   }
@@ -584,25 +582,13 @@ const clearDoctorSOrder = () => {
   yiZhuData.value.parentNoName = ''
 }
 
-/**
- * 添加医嘱
- * @returns {Promise<void>}
- */
-const addOrderNo = async () => {
-  if (stringNotBlank(yiZhuData.value.actOrderNo) && yiZhuData.value.actOrderNo !== 'tempOrderNo') {
-    await toAddAnOrder()
-  } else {
-    setTheTemporaryVariableMedicalOrder()
-  }
-}
-
 /**
  * 设置医嘱为临时变量,可以新增医嘱,关闭医嘱错误信息的弹窗。
  */
 const setTheTemporaryVariableMedicalOrder = () => {
   qingKong()
   baoCunXinXiRef.value.openOrClose(false);
-  yiZhuData.value.actOrderNo = 'tempOrderNo'
+  yiZhuData.value.actOrderNo = addTempOrderNo
   openSearch()
 }
 
@@ -611,51 +597,7 @@ const qingKong = () => {
   jiLiangValue.value = 0
   tiShiBiaoTi.value = []
   tempData = null
-  yiZhuData.value = {
-    id: '',
-    actOrderNo: null,
-    orderName: '',
-    orderCode: '',
-    // 频率
-    frequCode: '',
-    frequCodeName: '',
-    drugSpecification: '',
-    dose: 0,
-    // 领量
-    doseUnit: '',
-    doseUnitName: '',
-    supplyCode: '',
-    supplyCodeName: '',
-    startTime: '',
-    endTime: '',
-    orderTime: '',
-    doctorName: '',
-    drugFlag: '',
-    execUnit: '',
-    execUnitName: '',
-    parentNo: '',
-    parentNoName: '',
-    physicianName: '',
-    discription: '',
-    instruction: null,
-    kfFlag: null,
-    selfBuy: null,
-    ybSelfFlag: '0',
-    emergencyFlag: '0',
-    drugQuan: 0,
-    miniUnitName: '',
-    serial: '',
-    miniUnit: '',
-    psFlag: false,
-    kjywFlag: 0,
-    yyfs: null,
-    ssqk: null,
-    yysj: null,
-    zkObj: '',
-    zkWardCode: '',
-    zkDeptCode: '',
-    statusFlag: '1'
-  }
+  yiZhuDataInit()
 }
 
 // 判断是否可以编辑
@@ -674,7 +616,7 @@ const toAddAnOrder = async () => {
   if (stringIsBlank(props.patientInfo.inpatientNo)) {
     BizException(ExceptionEnum.MESSAGE_ERROR, '请先选择患者')
   }
-  if (stringIsBlank(yiZhuData.value.actOrderNo) || yiZhuData.value.actOrderNo === 'tempOrderNo') {
+  if (stringIsBlank(yiZhuData.value.actOrderNo) || yiZhuData.value.actOrderNo === addTempOrderNo) {
     BizException(ExceptionEnum.MESSAGE_ERROR, '请先选择一个医嘱')
   }
   // 有 医嘱 不是 录入就说明在看医嘱 直接清空就可以了
@@ -704,29 +646,30 @@ const toAddAnOrder = async () => {
       errorMessageData.value = {}
       let temp = res.data
       let tempMap = new Map()
-      // 获取新增的医嘱,如果是一组医嘱就会返回多个,做成map集合
       XEUtils.arrayEach(temp, (item) => {
         tempMap.set(item.actOrderNo, item)
       })
+
       for (let i = yzData.value.length - 1; i >= 0; i--) {
         let item = yzData.value[i];
         if (item.statusFlag !== '1') {
           continue;
         }
-        let key = i;
-        let orderNo = item.actOrderNo
+        let orderNo = item.actOrderNo;
         if (tempMap.has(orderNo)) {
-          yzData.value[key] = tempMap.get(orderNo)
+          yzData.value[i] = tempMap.get(orderNo)
           tempMap.delete(orderNo)
         }
         if (tempMap.size === 0) {
           break;
         }
       }
-      // 考虑如果是新增的就要直接添加到数组中
+
       if (tempMap.size > 0) {
-        yzData.value.push(...tempMap.values())
+        let list = Array.from(tempMap.values());
+        yzData.value.push(...list);
       }
+      setYzOrderGroup()
       await nextTick()
       // 设置高亮
       yzMitt.emit('setOrderNoTwinkle', yiZhuData.value.actOrderNo);
@@ -895,7 +838,7 @@ const copyFuncApi = async () => {
  * @returns {Promise<void>}
  */
 const duplicateAndPaste = () => {
-  if (stringIsBlank(yiZhuData.value.actOrderNo) || yiZhuData.value.actOrderNo === 'tempOrderNo') {
+  if (stringIsBlank(yiZhuData.value.actOrderNo) || yiZhuData.value.actOrderNo === addTempOrderNo) {
     BizException(ExceptionEnum.MESSAGE_ERROR, '请先选择医嘱')
   }
   copyOrderNo = {
@@ -911,7 +854,7 @@ const duplicateAndPaste = () => {
 
 let shortcutKeyRegistration = {
   ctrl: {s: toAddAnOrder},
-  alt: {a: addOrderNo}
+  alt: {a: toAddAnOrder}
 }
 
 /**
@@ -934,7 +877,6 @@ onMounted(() => {
   yzMitt.on('allowReplication', () => {
     return copyOrderNo.actOrderNo !== null
   })
-  yzMitt.on('addOrderNo', addOrderNo)
 
   yzMitt.on('deleteAnOrderByOrderNo', ({actOrderNo, orderName}, clearOrNot = true) => {
     if (stringIsBlank(actOrderNo)) {
@@ -973,7 +915,6 @@ onActivated(() => {
 
 
 defineExpose({
-  addOrderNo,
   fillData,
   toDeleteAnOrderClick,
   confirmOrdersClick,

+ 3 - 3
src/components/zhu-yuan-yi-sheng/yi-zhu-lu-ru/yz-header/YzQueryCondition.vue

@@ -126,7 +126,7 @@
         </template>
       </el-dropdown>
 
-      <el-dropdown split-button title="进入医嘱关联模式" @click="confirmAssociationClick">
+      <el-dropdown split-button title="设置医嘱关联" @click="confirmAssociationClick">
         关联
         <template #dropdown>
           <el-dropdown-menu>
@@ -239,6 +239,7 @@ import ReportOfInfectiousDiseases
 import OutpatientAppointments
   from "@/views/hospitalization/zhu-yuan-yi-sheng/yi-zhu-lu-ru/components/OutpatientAppointments.vue";
 import OneClickStop from "@/views/hospitalization/zhu-yuan-yi-sheng/yi-zhu-lu-ru/components/OneClickStop.vue";
+import XEUtils from 'xe-utils'
 
 const props = defineProps({
   patientInfo: {
@@ -276,7 +277,7 @@ const queryYz = async (isScroll = true) => {
 }
 
 const addYiZhuClick = () => {
-  yzMitt.emit('addOrderNo')
+  yzMitt.emit('toAddAnOrder')
 }
 
 const currentConfirmOrdersClick = () => {
@@ -447,7 +448,6 @@ const oneClickStopOpen = () => {
   oneClickStopDialog.value = true
 }
 
-
 onMounted(async () => {
   yzMitt.on('queryYz', (val) => {
     return queryYz(val)

+ 181 - 138
src/views/hospitalization/zhu-yuan-yi-sheng/public-js/zhu-yuan-yi-sheng.ts

@@ -65,11 +65,141 @@ export const frequCodeEnum = {
 
 // 生成的长期医嘱频率
 export const frequencyConfig = 'QD'
+export const addTempOrderNo: number = -1
+
+export interface yzType {
+    id: string;
+    inpatientNo: string;
+    admissTimes: number;
+    actOrderNo: number;
+    orderCode: string;
+    orderName: string;
+    nationalCode?: any;
+    packRetprice?: any;
+    frequCode: string;
+    frequCodeName: string;
+    instruction?: any;
+    discription?: any;
+    infantFlag: string;
+    orderTime: string;
+    startTime: string;
+    endTime?: any;
+    endTimeTemp?: any;
+    modifier?: any;
+    modifierName?: any;
+    physician: string;
+    physicianName: string;
+    drugSpecification?: any;
+    drugQuan?: any;
+    drugQuanName?: any;
+    supplyCode?: any;
+    supplyCodeName?: any;
+    drugFlag: string;
+    enterOper: string;
+    psFlag: boolean;
+    zkObj: string
+    enterOperName: string;
+    packSizeName: string
+    enterTime: string;
+    signer: string;
+    signerName: string;
+    confirmTime: string;
+    miniUnit?: any;
+    miniUnitName?: any;
+    drugWeight?: any;
+    drugWeightUnit?: any;
+    drugWeightUnitName?: any;
+    statusFlag: string;
+    statusTime?: any;
+    selfBuy: string;
+    dose?: any;
+    doseUnit?: any;
+    doseUnitName?: any;
+    drugOcc?: any;
+    drugVolume?: any;
+    drugVolUnit?: any;
+    parentNo?: any;
+    parentNoName?: any;
+    packSize: number;
+    packUnit?: any;
+    paySelf: string;
+    serial: string;
+    serialName: string;
+    groupNo: string;
+    groupNoName: string;
+    doctorFlag: string;
+    execUnit: string;
+    execUnitName: string;
+    regFlag: string;
+    ybSelfFlag?: any;
+    emergencyFlag?: any;
+    kfFlag?: any;
+    kjywFlag?: any;
+    stockAmount?: any;
+    deptRestrictions?: any;
+    visibleFlagZy?: any;
+    excluBackTime?: any;
+    excluActOrderNo?: any;
+    excluType: string;
+    clCode?: any;
+    endTimeB?: any;
+    deptCode: string;
+    deptName: string;
+    wardCode: string;
+    wardName: string;
+    newFlag: string;
+    referPhysician?: any;
+    referPhysicianName?: any;
+    consultPhysician?: any;
+    consultPhysicianName?: any;
+    yyfs?: any;
+    ssqk?: any;
+    yysj?: any;
+    ypLevel?: any;
+    delFlag?: any;
+    zkWardCode?: any;
+    zkDeptCode?: any;
+    children?: any;
+    orderGroup?: any;
+    executer1?: any;
+    executer2?: any;
+    newOrderFlag: number;
+    superiorDoctor?: any;
+    selfBuyName: string;
+    statusFlagName: string;
+    // 关联标志只在前端使用
+    associationFlag?: boolean
+    doctorName: string
+}
 
 // 医嘱数据
-export const yiZhuData = ref({
+export const yiZhuData = ref<yzType>({
+    admissTimes: 0,
+    confirmTime: "",
+    deptCode: "",
+    deptName: "",
+    doctorFlag: "",
+    enterOper: "",
+    enterOperName: "",
+    enterTime: "",
+    excluType: "",
+    groupNoName: "",
+    infantFlag: "",
+    inpatientNo: "",
+    newFlag: "",
+    newOrderFlag: 0,
+    paySelf: "",
+    physician: "",
+    regFlag: "",
+    selfBuyName: "",
+    serialName: "",
+    signer: "",
+    signerName: "",
+    statusFlagName: "",
+    wardCode: "",
+    wardName: "",
     id: '',
-    actOrderNo: isDev ? 'tempOrderNo' : null,
+    actOrderNo: addTempOrderNo,
     orderName: '',
     orderCode: '',
     // 频率
@@ -117,13 +247,36 @@ export const yiZhuData = ref({
     packUnit: '',
     // 执行用量
     drugOcc: '',
-    packSize: 0,
+    packSize: 0
 });
-
 export const yiZhuDataInit = () => {
     yiZhuData.value = {
         id: '',
-        actOrderNo: isDev ? 'tempOrderNo' : null,
+        actOrderNo: addTempOrderNo,
+        admissTimes: 0,
+        confirmTime: "",
+        deptCode: "",
+        deptName: "",
+        doctorFlag: "",
+        enterOper: "",
+        enterOperName: "",
+        enterTime: "",
+        excluType: "",
+        groupNoName: "",
+        infantFlag: "",
+        inpatientNo: "",
+        newFlag: "",
+        newOrderFlag: 0,
+        paySelf: "",
+        physician: "",
+        regFlag: "",
+        selfBuyName: "",
+        serialName: "",
+        signer: "",
+        signerName: "",
+        statusFlagName: "",
+        wardCode: "",
+        wardName: "",
         orderName: '',
         orderCode: '',
         // 频率
@@ -171,111 +324,10 @@ export const yiZhuDataInit = () => {
         packUnit: '',
         // 执行用量
         drugOcc: '',
-        packSize: 0,
+        packSize: 0
     }
 }
 
-export interface yzType {
-    id: string;
-    inpatientNo: string;
-    admissTimes: number;
-    actOrderNo: number;
-    orderCode: string;
-    orderName: string;
-    nationalCode?: any;
-    packRetprice?: any;
-    frequCode: string;
-    frequCodeName: string;
-    instruction?: any;
-    discription?: any;
-    infantFlag: string;
-    orderTime: string;
-    startTime: string;
-    endTime?: any;
-    endTimeTemp?: any;
-    modifier?: any;
-    modifierName?: any;
-    physician: string;
-    physicianName: string;
-    drugSpecification?: any;
-    drugQuan?: any;
-    drugQuanName?: any;
-    supplyCode?: any;
-    supplyCodeName?: any;
-    drugFlag: string;
-    enterOper: string;
-    enterOperName: string;
-    enterTime: string;
-    signer: string;
-    signerName: string;
-    confirmTime: string;
-    miniUnit?: any;
-    miniUnitName?: any;
-    drugWeight?: any;
-    drugWeightUnit?: any;
-    drugWeightUnitName?: any;
-    statusFlag: string;
-    statusTime?: any;
-    selfBuy: string;
-    dose?: any;
-    doseUnit?: any;
-    doseUnitName?: any;
-    drugOcc?: any;
-    drugVolume?: any;
-    drugVolUnit?: any;
-    parentNo?: any;
-    parentNoName?: any;
-    packSize: number;
-    packUnit?: any;
-    paySelf: string;
-    serial: string;
-    serialName: string;
-    groupNo: string;
-    groupNoName: string;
-    doctorFlag: string;
-    execUnit: string;
-    execUnitName: string;
-    regFlag: string;
-    ybSelfFlag?: any;
-    emergencyFlag?: any;
-    kfFlag?: any;
-    kjywFlag?: any;
-    stockAmount?: any;
-    deptRestrictions?: any;
-    visibleFlagZy?: any;
-    excluBackTime?: any;
-    excluActOrderNo?: any;
-    excluType: string;
-    clCode?: any;
-    endTimeB?: any;
-    deptCode: string;
-    deptName: string;
-    wardCode: string;
-    wardName: string;
-    newFlag: string;
-    referPhysician?: any;
-    referPhysicianName?: any;
-    consultPhysician?: any;
-    consultPhysicianName?: any;
-    yyfs?: any;
-    ssqk?: any;
-    yysj?: any;
-    ypLevel?: any;
-    delFlag?: any;
-    zkWardCode?: any;
-    zkDeptCode?: any;
-    children?: any;
-    orderGroup?: any;
-    executer1?: any;
-    executer2?: any;
-    newOrderFlag: number;
-    superiorDoctor?: any;
-    selfBuyName: string;
-    statusFlagName: string;
-    // 关联标志只在前端使用
-    associationFlag?: boolean
-}
-
 // 保存医嘱数据
 export const yzData = ref<Array<yzType>>([])
 
@@ -303,7 +355,8 @@ export const queryParam = ref({
     times: 0,
 });
 
-export function setYzOrderGroup() {
+// 设置分组符号
+export function setYzOrderGroup(): void {
     yzData.value = yzDataToTree(yzData.value)
 }
 
@@ -313,14 +366,14 @@ export function yzDataToTree(data: yzType[]): yzType[] {
         return []
     }
     // 没有匹配到父级的子节点
-    let noParent: Map<number, any> = new Map();
+    let noParent: Map<number, yzType> = new Map();
     // 克隆一下原来的数据
-    let cloneData: Array<yzType> = JSON.parse(JSON.stringify(data))
-    // 定位校领医嘱
-    let tempMap: Map<number, any> = new Map();
-    let tree = [];
+    let cloneData: yzType[] = JSON.parse(JSON.stringify(data))
+    // 转 map
+    let tempMap: Map<number, yzType> = new Map();
+    let tree: yzType[] = [];
     // 保存子元素的数据
-    let children = [];
+    let children: yzType[] = [];
     XEUtils.arrayEach(cloneData, (item) => {
         let key: number = item.actOrderNo
         noParent.set(key, item);
@@ -350,21 +403,18 @@ export function yzDataToTree(data: yzType[]): yzType[] {
     // 判断 noParent 不为空
     if (noParent.size > 0) {
         // 把 noParent 的 value 全部放到 tree 数组中
-        // @ts-ignore
-        XEUtils.arrayEach(noParent.values(), (item) => {
-            tree.push(item)
-        });
+        let a: yzType[] = Array.from(noParent.values());
+        tree.push(...a)
     }
 
     let list: yzType[] = []
 
-    //循环 tree 节点
+    //循环 tree 节点,设置结尾的 orderGroup 为 "└" 并且清空children数组
     XEUtils.arrayEach(tree, (item) => {
         list.push(item)
         // 判断 item 的 children 节点不为空
         if (item.children && item.children.length > 0) {
             item.children[item.children.length - 1].orderGroup = "└"
-            console.log(item.children[item.children.length - 1].actOrderNo, item.children[item.children.length - 1].orderGroup)
             // 把 item 的 children 节点全部添加到 list数组
             list.push(...item.children)
             item.children = []
@@ -374,7 +424,6 @@ export function yzDataToTree(data: yzType[]): yzType[] {
     return list
 }
 
-
 // 设置项目名称
 function getSerial(val: string): string {
     val = XEUtils.trim(val)
@@ -408,14 +457,15 @@ function setSerialName(item: any) {
 
 // 数据筛选
 export const tempYzData = computed<yzType[]>(() => {
-    // 转成数状图
-    return yzData.value.filter((item, index) => {
+    let temp = XEUtils.filter(yzData.value, (item) => {
         let flag = queryParam.value.displayRange === 0
         let frequFlag = queryParam.value.frequCode === frequCodeEnum.all
         let zhuangTai = queryParam.value.zhuangTai === 0
+
         if (isCydy()) {
             return item.selfBuy === '4'
         }
+
         if (item.statusFlag === '1') {
             return true
         }
@@ -444,10 +494,10 @@ export const tempYzData = computed<yzType[]>(() => {
         } else if (queryParam.value.zhuangTai === 5) {
             zhuangTai = item.statusFlag === '5'
         }
-        return flag && frequFlag && zhuangTai && item.selfBuy !== '4';
-    }).sort((a, b) => {
-        return a.actOrderNo - b.actOrderNo
+        return flag && frequFlag && zhuangTai;
     })
+
+    return XEUtils.orderBy(temp, [['actOrderNo', 'asc']])
 })
 
 // 获取医嘱的下标
@@ -469,7 +519,7 @@ export const errorMsg = ref({
     data: {}
 })
 
-// 添加新会诊申请
+// 添加新会诊申请
 export const consultationApplication = ref(false)
 
 // 添加手术申请
@@ -488,11 +538,6 @@ export const jyTree = ref([])
 // 检查树状图
 export const jcTree = ref([])
 
-/**
- * 具体的草药明细
- * @type {Ref<UnwrapRef<{weiYi: *[], list: *[]}>>}
- */
-
 export const mingXi = ref({
     weiYi: [],
     list: [],
@@ -505,11 +550,11 @@ export const mingXi = ref({
 export const clickOnThePatient = async (patNo) => {
     switchPatients()
     huanZheXinXi.value = await getPatientInfo(patNo) as any
-    if (!yzMitt.exists('queryYz')) {
-        await jsQueryYzData()
-    } else {
+    if (yzMitt.exists('queryYz')) {
         await nextTick()
         yzMitt.emit('queryYz')
+    } else {
+        await jsQueryYzData()
     }
     queryParam.value.frequCode = frequCodeEnum.all
     queryParam.value.zhuangTai = 0
@@ -518,12 +563,10 @@ export const clickOnThePatient = async (patNo) => {
 }
 
 
-
-
 const switchPatients = () => {
     let str = ''
     if (stringNotBlank(yiZhuData.value.actOrderNo) && yiZhuData.value.statusFlag === '1') {
-        if (yiZhuData.value.actOrderNo !== 'tempOrderNo') {
+        if (yiZhuData.value.actOrderNo !== addTempOrderNo) {
             str += "存在未保存的医嘱。"
         }
     }

+ 10 - 12
src/views/hospitalization/zhu-yuan-yi-sheng/yi-zhu-lu-ru/YiZhuLuRu.vue

@@ -11,16 +11,17 @@
                  :open-group-order-template="openGroupOrderTemplate"/>
     </div>
 
-    <yz-table-v2 ref="tableRef"
-                 :height="editSizeRef?.clientHeight"
-                 @void-orders="voidOrdersClick"
-                 @clickAssociate="clickAssociate"
-                 @rowClick="rowClick"/>
+    <yz-table-v2
+        :height="editSizeRef?.clientHeight"
+        @void-orders="voidOrdersClick"
+        @clickAssociate="clickAssociate"
+        @rowClick="rowClick"/>
 
     <doctor-s-order-fee :data="chargeDetails.data"
                         v-if="chargeDetails.dialog"
                         :sum="chargeDetails.sum"
                         @close="chargeDetails.dialog = false"/>
+
     <!--  获取模板的数据  -->
     <huo-qu-mu-ban
         ref="mubanRef"
@@ -43,7 +44,7 @@
   </div>
 </template>
 
-<script name="YiZhuLuRuZhuJian" setup>
+<script setup>
 import {
   deleteMultipleOrders,
   getFrequency,
@@ -58,7 +59,7 @@ import {
   clickOnThePatient,
   drugManual,
   associateOrders,
-  youWuXuanZheHuanZhe, yzData, errorMsg, yzMitt, jsQueryYzData, geiYaoFangShiData, yaoPinPingLvData
+  youWuXuanZheHuanZhe, yzData, errorMsg, yzMitt, geiYaoFangShiData, yaoPinPingLvData
 } from '../public-js/zhu-yuan-yi-sheng'
 import store from '@/store'
 import {stringIsBlank, stringNotBlank} from '@/utils/blank-utils'
@@ -128,9 +129,6 @@ const confirmOrder = async () => {
   await yzMitt.emit('queryYz');
 }
 
-
-// 表格
-const tableRef = ref(null)
 const rowClick = (val) => {
   orderProgressRef.value.fillOrder(val)
   if (associateOrders.value.actOrderNo) {
@@ -159,10 +157,10 @@ const rowClick = (val) => {
 }
 
 const orderQuash = (val) => {
-  if (val.statusFlag == '2') {
+  if (val.statusFlag === '2') {
     BizException(ExceptionEnum.LOGICAL_ERROR, "确认医嘱无需撤销删除即可。");
   }
-  if (val.statusFlag == '1') {
+  if (val.statusFlag === '1') {
     BizException(ExceptionEnum.LOGICAL_ERROR, "录入医嘱无需撤销删除即可。");
   }
 

+ 388 - 38
src/views/hospitalization/zhu-yuan-yi-sheng/yi-zhu-lu-ru/components/table/YzTableV3.vue

@@ -1,23 +1,170 @@
-<script setup name='YzTableV3'>
-import {stringIsBlank} from "@/utils/blank-utils";
-import {tempYzData} from "@/views/hospitalization/zhu-yuan-yi-sheng/public-js/zhu-yuan-yi-sheng";
+<script setup lang="ts">
+import {stringIsBlank} from "../../../../../../utils/blank-utils";
+import {
+  associateOrders,
+  clearAssociate, drugManual,
+  tempYzData, yiZhuData, yzMitt,
+  yzSize,
+  yzType
+} from "../../../../../../views/hospitalization/zhu-yuan-yi-sheng/public-js/zhu-yuan-yi-sheng";
+import {ref, h, reactive, onMounted, nextTick} from 'vue'
+import {VxeTableInstance, VxeTablePropTypes} from 'vxe-table'
+import {nullToEmpty} from '../../../../../../utils/public'
+import {getFormatDatetime} from '../../../../../../utils/date'
+import {getServerDateApi} from '../../../../../../api/public-api'
+import XEUtils from "xe-utils";
+import {updateOrderInstruction} from '../../../../../../api/zhu-yuan-yi-sheng/yi-zhu-lu-ru'
+import sleep from "../../../../../../utils/sleep";
 
-const xTableRef = ref(null)
+const {height} = defineProps({
+  height: [Number, null]
+})
+
+const tableRef = ref<VxeTableInstance>(null)
 
 const toggleAllCheckboxEvent = () => {
-  const $table = xTableRef.value
+  const $table = tableRef.value
   if ($table) {
     $table.toggleAllCheckboxRow()
   }
 }
 
 const toggleCheckboxEvent = (row) => {
-  const $table = xTableRef.value
+  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: '说明书'}
+      ],
+    ],
+  },
+  visibleMethod({options, column}) {
+    options.forEach(list => {
+      list.forEach((item) => {
+        item.disabled = !column;
+        if (item.code === 'paste') {
+          item.disabled = !yzMitt.emit('allowReplication')
+        }
+      })
+    })
+    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": (data: yzType) => {
+    yzMitt.emit('clickAssociate', data)
+  },
+  "exitTheAssociation": (data: yzType) => {
+    clearAssociate()
+  },
+  "instructions": (data: yzType) => {
+    if (data.groupNo !== '00') {
+      drugManual.value.open(data.orderCode, data.serial);
+    }
+  },
+}
+// 触发鼠标右键的时间
+const tableRightClick = (val: MenuClick) => {
+  let {row, menu} = val
+  try {
+    rightFunc[menu.code](row)
+  } catch {
+  }
+}
+
+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 (XEUtils.isEmpty(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
@@ -39,52 +186,255 @@ function getYiZhuFlag(val) {
       return 'warning'
   }
 }
+
+const timeFomat = (val) => {
+  return getFormatDatetime(val, 'YY-MM-DD HH:mm')
+}
+
+const showEndTime = (data: yzType) => {
+  return stringIsBlank(data.endTime) && stringIsBlank(data.parentNo) && data.frequCode !== 'ONCE';
+}
+
+const rowClick = ({row}) => {
+  yzMitt.emit('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,
+    }
+  }
+}
+
+onMounted(() => {
+
+  yzMitt.on('tableScroll', (val) => {
+    tableRef.value.scrollTo(0, val)
+  })
+
+  yzMitt.on('clearSelected', () => {
+    tableRef.value.clearSelected()
+  })
+
+  yzMitt.on('scrollEndAndTwinkle', async (val) => {
+    let endRow = tempYzData.value[tempYzData.value.length - 1]
+    twinkleList.value = val;
+    await nextTick()
+    // 滚动到最后一行
+    await tableRef.value.scrollToRow(endRow, 'actOrderNo')
+  })
+
+  yzMitt.on('setOrderNoTwinkle', async (val: yzType) => {
+    twinkleList.value[val] = true;
+    let endRow = tempYzData.value[tempYzData.value.length - 1]
+    // await nextTick()
+    console.log(val)
+    await tableRef.value.scrollToRow(endRow)
+  })
+
+  yzMitt.on('getSelectedData', () => {
+    return tableRef.value.getCheckboxRecords(true)
+  })
+
+})
+
 </script>
 
 <template>
-  <vxe-table :height="662"
-             border
-             :scroll-x="{gt: 0,enabled: false}"
-             :scroll-y="{gt: 0 ,enabled: true}"
-             :column-config="{resizable: true}"
-             :row-config="{height: 24}"
-             class="vxe-padding_zero"
-             show-header-overflow
-             show-overflow
-             ref="xTableRef"
-             :data="tempYzData">
-    <vxe-column type="checkbox" width="20">
-      <template #header="{ checked, indeterminate }">
+  <div style="width: max-content; height: max-content">
+    <vxe-table :height="yzSize.h - height - 35"
+               border
+               :style="{width:yzSize.w + 'px' }"
+               :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}"
+               class="vxe-padding_zero vxe-header-max_content hl-style vxe-scroll_15"
+               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 }">
+        </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"></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="1980">
-      <template #default="scope">
-
-      </template>
-    </vxe-column>
-  </vxe-table>
+        </template>
+      </vxe-column>
+      <vxe-column type="seq" width="30"/>
+      <vxe-column field="orderGroup" title="组" width="20"></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="140">
+        <template #default="scope">
+          <input v-if="showEndTime(scope.row)"
+                 type='datetime-local'
+                 @click.stop.prevent
+                 @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="100" fixed="right">
+        <template #default="scope">
+          <div class="yz_button">
+            <div class="toVoid">作废</div>
+            <div class="delete">删除</div>
+          </div>
+        </template>
+      </vxe-column>
+
+
+    </vxe-table>
+  </div>
 </template>
 
-<style scoped lang="scss">
+<style lang="scss">
+
+.new_order {
+  position: relative;
+
+  &:before {
+    position: absolute;
+    right: -6px;
+    font-size: 15px;
+    top: -5px;
+    content: "*";
+    color: red;
+  }
+}
+
+@keyframes hzfirst {
+  from {
+    background-color: #95d475
+  }
+  to {
+    background-color: white;
+  }
+}
+
+.yz_button {
+  width: 100%;
+  cursor: pointer;
+  padding: 0 5px;
+  display: flex;
+  justify-content: space-between;
+
+  div {
+    width: max-content;
+    margin: 0 5px;
+  }
+
+  .toVoid {
+    color: #E6A23C;
+    background-color: inherit;
+  }
+
+  .delete {
+    color: #F56C6C;
+    background-color: inherit;
+  }
+}
+
+.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>