Browse Source

肖蟾好用的组件

xiaochan 1 year ago
parent
commit
d2dc290816

+ 39 - 0
src/App.vue

@@ -468,6 +468,26 @@ input[type=number]::-webkit-outer-spin-button {
 }
 }
 
 
 
 
+.vxe-padding_zero_4 {
+  .vxe-header--row {
+
+    th {
+      padding: 0 4px !important;
+    }
+
+    .vxe-cell {
+      padding: 0 4px !important;
+    }
+  }
+
+  .vxe-body--row {
+    .vxe-cell {
+      padding: 0 4px pximportant;
+    }
+  }
+}
+
+
 .select_v2_width_150 {
 .select_v2_width_150 {
   .el-vl__window {
   .el-vl__window {
     width: 150px !important;
     width: 150px !important;
@@ -502,6 +522,10 @@ input[type=number]::-webkit-outer-spin-button {
 
 
 }
 }
 
 
+.vxe-table--body-wrapper {
+  background: white;
+}
+
 .cy_display_flex {
 .cy_display_flex {
   width: 100%;
   width: 100%;
   height: 100%;
   height: 100%;
@@ -509,6 +533,14 @@ input[type=number]::-webkit-outer-spin-button {
   box-sizing: border-box;
   box-sizing: border-box;
 }
 }
 
 
+.cy_display_flex_y {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  box-sizing: border-box;
+  flex-flow: column nowrap;
+}
+
 .cy_display_flex-align-items_center {
 .cy_display_flex-align-items_center {
   align-items: center;
   align-items: center;
 }
 }
@@ -535,4 +567,11 @@ input[type=number]::-webkit-outer-spin-button {
   border: 0;
   border: 0;
 }
 }
 
 
+.cy-vxe-table-checkbox_clear {
+  border: 1px solid #000;
+  cursor: pointer;
+  border-radius: 5px;
+  user-select: none;
+}
+
 </style>
 </style>

+ 1 - 0
src/api/zhu-yuan-yi-sheng/jian-yan-jian-cha-shen-qing.ts

@@ -171,6 +171,7 @@ export function getAncillaryInformation(patNo, times) {
         url: url + 'getAncillaryInformation',
         url: url + 'getAncillaryInformation',
         showLoading: false,
         showLoading: false,
         method: 'get',
         method: 'get',
+        timeout: 2000,
         params: {patNo, times}
         params: {patNo, times}
     })
     })
 }
 }

+ 53 - 84
src/components/zhu-yuan-yi-sheng/public/PatientList.vue

@@ -14,20 +14,15 @@
       <div style="display: flex ; align-content: center">
       <div style="display: flex ; align-content: center">
         <xc-checkbox v-model="myPatient" @change="myPatientChange" label="我的病人"/>
         <xc-checkbox v-model="myPatient" @change="myPatientChange" label="我的病人"/>
         <div style="color:red;">
         <div style="color:red;">
-          {{ overviews.length }}人
+          {{ tableProps.data.length }}人
         </div>
         </div>
       </div>
       </div>
     </template>
     </template>
-    <el-table :data="overviews"
-              height="100%"
-              v-loading="tableLoading"
-              @row-click="handleClickOverview"
-              ref="elTableRef"
-              :row-class-name="rowClass"
-              class="remove_hover"
-              @row-contextmenu="settingUpAThirdLevelDoctor">
-      <el-table-column label="床" prop="bedNo" width="30"/>
-      <el-table-column label="姓名" width="70" prop="name">
+
+    <CyVxeTable
+        class="vxe-padding_zero">
+      <VxeColumn title="床" field="bedNo" width="50"/>
+      <VxeColumn title="姓名" field="name" width="70">
         <template #default="{row}">
         <template #default="{row}">
             <span>
             <span>
               {{ row.name }}
               {{ row.name }}
@@ -36,92 +31,88 @@
               {{ row.orderNoCount }}
               {{ row.orderNoCount }}
           </span>
           </span>
         </template>
         </template>
-      </el-table-column>
-      <el-table-column label="住院号" prop="inpatientNo" width="65">
+      </VxeColumn>
+      <VxeColumn title="住院号" field="inpatientNo" width="65">
         <template #default="{row}">
         <template #default="{row}">
           <div :style="{color: row.dismissOrder ===1 ? 'red' : 'black'}">
           <div :style="{color: row.dismissOrder ===1 ? 'red' : 'black'}">
             {{ row.inpatientNo }}
             {{ row.inpatientNo }}
           </div>
           </div>
         </template>
         </template>
-      </el-table-column>
-      <el-table-column label="性别" prop="sex" width="65">
+      </VxeColumn>
+      <VxeColumn title="性别" field="sex" width="65">
         <template #default="scope">
         <template #default="scope">
           {{ cptSex(scope.row.sex) }}
           {{ cptSex(scope.row.sex) }}
         </template>
         </template>
-      </el-table-column>
-    </el-table>
+      </VxeColumn>
+    </CyVxeTable>
   </CyFlex>
   </CyFlex>
 
 
-  <el-dialog v-model="thirdLevelDoctorSetting.dialog" width="450px" title="三级医生设置">
-    <el-form label-width="120px">
-      <el-form-item label="患者:">
-        {{ thirdLevelDoctorSetting.data.name }}
-      </el-form-item>
-      <el-form-item label="管床医生:">
-        <select-staff-code v-model="thirdLevelDoctorSetting.data"
-                           :name="['referPhysician', 'referPhysicianName']"
-        />
-      </el-form-item>
-      <el-form-item label="主治医生:">
-        <select-staff-code v-model="thirdLevelDoctorSetting.data"
-                           :name="['consultPhysician', 'consultPhysicianName']"
-        />
-      </el-form-item>
-      <el-form-item label="主任/副主任:">
-        <select-staff-code v-model="thirdLevelDoctorSetting.data"
-                           :name="['deptDirector', 'deptDirectorName']"/>
-      </el-form-item>
-      <el-form-item label=" ">
-        <el-button @click="submitToTheThirdLevelDoctor">提交</el-button>
-      </el-form-item>
-    </el-form>
-  </el-dialog>
 </template>
 </template>
 
 
-<script setup name='PatientList' lang="ts">
+<script setup lang="ts">
 import {onMounted, ref} from "vue";
 import {onMounted, ref} from "vue";
-import {getOverView, getPatientInfo} from "@/api/inpatient/patient";
+import {getOverView} from "@/api/inpatient/patient";
 import {allWardsVisible} from "@/utils/permission";
 import {allWardsVisible} from "@/utils/permission";
 import XcCheckbox from "@/components/xiao-chan/checkbox/XcCheckbox";
 import XcCheckbox from "@/components/xiao-chan/checkbox/XcCheckbox";
 import {cptSex} from "@/utils/computed";
 import {cptSex} from "@/utils/computed";
-import {getMyPatient, saveTheThirdLevelDoctor} from "@/api/zhu-yuan-yi-sheng/yi-zhu-lu-ru";
+import {getMyPatient} from "@/api/zhu-yuan-yi-sheng/yi-zhu-lu-ru";
 import {
 import {
   clickOnThePatient,
   clickOnThePatient,
   huanZheXinXi,
   huanZheXinXi,
   yzMitt
   yzMitt
 } from "@/views/hospitalization/zhu-yuan-yi-sheng/public-js/zhu-yuan-yi-sheng";
 } from "@/views/hospitalization/zhu-yuan-yi-sheng/public-js/zhu-yuan-yi-sheng";
-import XcDialogV2 from "@/components/xiao-chan/dialog/XcDialogV2.vue";
-import SelectStaffCode from "@/components/SelectStaffCode.vue";
 import {getAllWards} from "@/api/zhu-yuan-yi-sheng/resident-doctor";
 import {getAllWards} from "@/api/zhu-yuan-yi-sheng/resident-doctor";
 import CyFlex from "@/components/cy/flex/src/CyFlex.vue";
 import CyFlex from "@/components/cy/flex/src/CyFlex.vue";
+import useVxeTable from "@/utils/cy-use/useVxeTable";
+import SetPatientDoctor from "@/views/hospitalization/zhu-yuan-yi-sheng/patient-doctor/setPatientDoctor";
 
 
 
 
 const myPatient = ref(false)
 const myPatient = ref(false)
 const wardsClearable: boolean = allWardsVisible()
 const wardsClearable: boolean = allWardsVisible()
 const allWards = ref([])
 const allWards = ref([])
 const currentWard = ref()
 const currentWard = ref()
-const overviews = ref([])
 
 
-const fetchOverviews = () => {
-  yzMitt.emit('onWardChange', currentWard.value)
-  getOverView(currentWard.value).then((res) => {
-    overviews.value = res as any
+const handleClickOverview = ({row}) => {
+  tableProps.loading = true
+  tableProps.loadingConfig!.text = '患者信息加载中...'
+  clickOnThePatient(row.inpatientNo).finally(() => {
+    tableProps.loading = false
   })
   })
 }
 }
 
 
-const elTableRef = ref(null)
-const tableLoading = ref(false)
-const handleClickOverview = (row) => {
-  tableLoading.value = true
-  clickOnThePatient(row.inpatientNo).finally(() => {
-    tableLoading.value = false
+const {tableRef, CyVxeTable, tableProps, mutation} = useVxeTable(
+    {
+      rowHeight: 32,
+      keyField: 'inpatientNo',
+      tableProps: {
+        onCellClick: handleClickOverview,
+        onCellMenu: ({row, $event, rowIndex}) => settingUpAThirdLevelDoctor(row, $event, rowIndex)
+      }
+    }
+)
+
+const settingUpAThirdLevelDoctor = (row, event, index) => {
+  event.returnValue = false
+  SetPatientDoctor(row).then((res) => {
+    if (huanZheXinXi.value.inpatientNo === res.inpatientNo) {
+      // @ts-ignore
+      huanZheXinXi.value = {...huanZheXinXi.value, ...res}
+    }
+    mutation.updateByIndex({...row, ...res}, index)
+  })
+}
+
+const fetchOverviews = () => {
+  yzMitt.emit('onWardChange', currentWard.value)
+  getOverView(currentWard.value).then((res) => {
+    tableProps.data = res as any
   })
   })
 }
 }
 
 
 const myPatientChange = () => {
 const myPatientChange = () => {
   if (myPatient.value) {
   if (myPatient.value) {
     getMyPatient().then((res) => {
     getMyPatient().then((res) => {
-      overviews.value = res
+      tableProps.data = res as any
       currentWard.value = ''
       currentWard.value = ''
     });
     });
   } else {
   } else {
@@ -130,35 +121,13 @@ const myPatientChange = () => {
   }
   }
 };
 };
 
 
-const rowClass = ({row}) => {
-  if (huanZheXinXi.value.inpatientNo === row.inpatientNo) {
-    return 'el_table__current'
-  }
-}
-
-const thirdLevelDoctorSetting = ref({
-  dialog: false,
-  data: {},
-  deptList: []
-})
-
-const settingUpAThirdLevelDoctor = (row, column, event) => {
-  event.returnValue = false
-  thirdLevelDoctorSetting.value.dialog = true
-  thirdLevelDoctorSetting.value.data = row
-}
-
-const submitToTheThirdLevelDoctor = () => {
-  saveTheThirdLevelDoctor(thirdLevelDoctorSetting.value.data).then(async () => {
-    thirdLevelDoctorSetting.value.dialog = false
-    huanZheXinXi.value = await getPatientInfo(huanZheXinXi.value.inpatientNo) as any
-  })
-}
 
 
 onMounted(() => {
 onMounted(() => {
   yzMitt.on('upperDoctorSetting', (data) => {
   yzMitt.on('upperDoctorSetting', (data) => {
-    thirdLevelDoctorSetting.value.dialog = true
-    thirdLevelDoctorSetting.value.data = data
+    settingUpAThirdLevelDoctor(data)
+  })
+  yzMitt.on('setTableKey', (data) => {
+    tableProps.currentKey = data
   })
   })
 
 
   yzMitt.on('getCurrentWard', () => {
   yzMitt.on('getCurrentWard', () => {

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

@@ -309,7 +309,6 @@ const queryYz = async (tableScrollTop = true) => {
   if (!props.patientInfo.inpatientNo) {
   if (!props.patientInfo.inpatientNo) {
     BizException(ExceptionEnum.MESSAGE_ERROR, '请先选择患者')
     BizException(ExceptionEnum.MESSAGE_ERROR, '请先选择患者')
   }
   }
-
   try {
   try {
     yiZhuDataInit()
     yiZhuDataInit()
     yzMitt.emit('clearSelected')
     yzMitt.emit('clearSelected')

+ 90 - 0
src/utils/cy-use/useDateRange.tsx

@@ -0,0 +1,90 @@
+import {ElDatePicker} from "element-plus";
+import {ref, Ref} from 'vue'
+import {currentAndAFewDaysAgo, elDateRangeAddTime} from "@/utils/moment-utils";
+import moment from 'moment'
+
+const shortcuts = [
+    {
+        text: '今天',
+        value: [moment(), moment()]
+    },
+    {
+        text: '最近一周',
+        value: [moment().subtract(7, 'days'), moment()]
+    },
+    {
+        text: '最近一个月',
+        value: [moment().startOf('month'), moment().endOf('month')]
+    },
+    {
+        text: '最近三个月',
+        value: [moment().subtract(3, 'months').startOf('month'), moment().endOf('month')]
+    },
+    {
+        text: '本月',
+        value: [moment().startOf('month'), moment().endOf('month')]
+    },
+    {
+        text: '上个月',
+        value: [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')]
+    },
+    {
+        text: '今年',
+        value: [moment().startOf('year'), moment()]
+    },
+    {
+        text: '去年',
+        value: [moment().subtract(1, 'year').startOf('year'), moment().subtract(1, 'year').endOf('year')]
+    }
+];
+
+interface ElDatePickerType {
+    clearable?: boolean,
+    defaultValue?: object,
+    teleported?: boolean,
+    aFewDaysAgo?: number,
+}
+
+export default function useDateRange(props?: ElDatePickerType) {
+    const modelValue: Ref<any[]> = ref([])
+    const dateRange = ref({})
+
+    function handelChangeDate(value) {
+        modelValue.value = value
+        dateRange.value = elDateRangeAddTime(value)
+    }
+
+    if (props?.aFewDaysAgo) {
+        currentAndAFewDaysAgo(props?.aFewDaysAgo).then(res => {
+            handelChangeDate(res)
+        })
+    }
+
+    function CyDateRange(dateProps) {
+        return (<div style="display: inline-flex;vertical-align: middle;width:220px">
+            <ElDatePicker
+                unlink-panels
+                size={'small'}
+                start-placeholder={'开始日期'}
+                end-placeholder={'结束日期'}
+                shortcuts={shortcuts}
+                // @ts-ignore
+                modelValue={modelValue.value}
+                type={'daterange'}
+                onUpdate:modelValue={(el) => {
+                    handelChangeDate(el)
+
+                }}
+                {...props}
+                {...dateProps}
+            >
+            </ElDatePicker>
+        </div>)
+    }
+
+    return {
+        CyDateRange,
+        dateRange
+    }
+}
+

+ 489 - 0
src/utils/cy-use/useVxeTable.tsx

@@ -0,0 +1,489 @@
+import {computed, nextTick, reactive, Ref, ref, watch, onMounted} from 'vue'
+import type {VxePagerProps, VxeTableProps} from "vxe-table";
+import {VxePager, VxeTable, VxeColumn} from "vxe-table";
+import {TablePublicMethods, VxeTableEventProps} from "vxe-table/types/table";
+import XEUtils from "xe-utils";
+import {stringIsBlank, stringNotBlank} from "@/utils/blank-utils";
+import {TableExportMethods} from "vxe-table/types/export";
+import {BizException, ExceptionEnum} from "@/utils/BizException";
+import {eachAndReturnList} from "@/utils/cyRefList";
+import {ElButton, ElPopover} from "element-plus";
+import setDialogToJs from "@/components/js-dialog-comp/useDialogToJs";
+import CyDialog from "@/components/cy/dialog/src/CyDialog.vue";
+import {IsCyDialog} from "@/components/cy/dialog/src/useCyDialog";
+import CyFlex from "@/components/cy/flex/src/CyFlex.vue";
+
+declare type PageQuery = {
+    currentPage?: number,
+    pageSize?: number,
+}
+
+declare type SimplifiedConfiguration<D> = {
+    rowHeight?: number,
+    keyField?: string,
+    currentKey?: string | number,
+    remoteSearch?: (data?: PageQuery & any) => Promise<D[]>,
+    tableProps?: VxeTableEventProps<D> & VxeTableProps<D>,
+    showPage?: boolean,
+    result?: string,
+    total?: string,
+    pagesProps?: VxePagerProps,
+    showCheckbox?: boolean,
+    mountedQuery?: boolean,
+    dialogProps?: IsCyDialog,
+    dialogHeader?: () => any
+}
+
+
+function tsxVModel(modelValue: object, name: string, modelName?: string) {
+    const updateName = modelName || name
+    return {
+        // @ts-ignore
+        [updateName]: modelValue[name],
+        ['onUpdate:' + updateName]: (el: any) => {
+            // @ts-ignore
+            modelValue[name] = el
+        }
+    }
+}
+
+function useVxeTable<D = any>(simplifiedConfiguration: SimplifiedConfiguration<D>) {
+    const tableRef: Ref<TablePublicMethods<D> & TableExportMethods<D> | undefined> = ref()
+    const props: VxeTableProps<D> & VxeTableEventProps<D> & SimplifiedConfiguration<D> = reactive({
+        height: '100%',
+        rowConfig: {
+            isHover: true,
+            isCurrent: true,
+            height: simplifiedConfiguration?.rowHeight || 48,
+            useKey: true,
+            keyField: simplifiedConfiguration?.keyField || '',
+        },
+        scrollY: {
+            enabled: true,
+            gt: 0
+        },
+        columnConfig: {
+            resizable: true
+        },
+        scrollX: {
+            enabled: false,
+        },
+        exportConfig: {},
+        showOverflow: true,
+        currentKey: '',
+        menuConfig: {
+            enabled: true
+        },
+        loading: false,
+        loadingConfig: {
+            text: '加载中...',
+            icon: '',
+        },
+        checkboxConfig: {
+            reserve: true,
+            highlight: true,
+            range: true,
+        },
+        data: [],
+    })
+
+    if (simplifiedConfiguration.showPage) {
+        delete props.rowConfig?.height
+        props.scrollY!.enabled = false
+        props!.showOverflow = false
+        props!.checkboxConfig!.reserve = true
+        if (stringIsBlank(props.rowConfig?.keyField)) {
+            BizException(ExceptionEnum.MESSAGE_ERROR, '请先设置行id')
+        }
+    }
+
+    const pageVO = reactive({
+        currentPage: 1,
+        pageSize: 30,
+        total: 0
+    })
+
+    const pagerProps: VxePagerProps = reactive({
+        loading: false,
+    })
+
+    watch(() => props.currentKey, () => {
+        if (stringNotBlank(defaultProps.value.rowConfig?.keyField)) {
+            const findData = XEUtils.find(tableRef.value?.getData(), (item) => {
+                // @ts-ignore
+                return item[defaultProps.value.rowConfig?.keyField] === props.currentKey;
+            })
+            if (findData) {
+                tableRef.value?.scrollToRow(findData)
+                tableRef.value?.setCurrentRow(findData)
+            }
+        }
+    }, {flush: 'post'})
+
+    const defaultProps = computed(() => {
+        return {
+            ...simplifiedConfiguration?.tableProps,
+            ...props
+        } as VxeTableProps<D>
+    })
+
+    const CyVxeTable = (props: VxeTableProps<D>, {slots}: any) => {
+
+        mutation.setTableDefaultSlots = () => {
+            return slots.default ? slots.default() : null
+        }
+
+        const TempVxeTable = () => {
+            return <VxeTable
+                ref={tableRef}
+                {...defaultProps.value}
+                {...props}
+            >
+
+                {{
+                    default: () => {
+                        function renderIcon(checked: boolean, indeterminate: boolean) {
+                            if (indeterminate) {
+                                return <i class="vxe-icon-square-minus-fill"></i>
+                            } else if (checked) {
+                                return <i class="vxe-icon-square-checked-fill"></i>
+                            } else {
+                                return <i class="vxe-icon-checkbox-unchecked"></i>
+                            }
+                        }
+
+                        function checkboxHeader(checked: boolean, indeterminate: boolean) {
+                            return <ElPopover placement="right">
+                                {{
+                                    default: () => {
+                                        return [
+                                            `当前选中${pageMemory.size}条`,
+                                            <div style="text-align: right;margin-top: 5px;">
+                                                <ElButton
+                                                    type="primary"
+                                                    onClick={(el) => {
+                                                        if (pageMemory.size > 0)
+                                                            handelLookCheckBox()
+                                                    }}
+                                                >{{default: () => '详情'}}
+                                                </ElButton>
+                                                <ElButton
+                                                    type="danger"
+                                                    onClick={(el) => {
+                                                        mutation.clearCheckboxRow()
+                                                    }}
+                                                >{{default: () => '清空'}}
+                                                </ElButton>
+                                            </div>
+                                        ]
+                                    },
+                                    reference: () => {
+                                        return <span
+                                            style={"font-size: 1.1em;cursor: pointer;"}
+                                            onClick={(el) => {
+                                                el.preventDefault()
+                                                el.stopPropagation()
+                                                handelCheckboxAll()
+                                            }}>{renderIcon(checked, indeterminate)}</span>
+                                    }
+                                }}
+                            </ElPopover>
+                        }
+
+                        return [
+                            simplifiedConfiguration.showCheckbox ?
+                                <VxeColumn type="checkbox" width={"max-content"}>
+                                    {{
+                                        // @ts-ignore
+                                        header({checked, indeterminate}) {
+                                            return checkboxHeader(checked, indeterminate)
+                                        },
+                                        // @ts-ignore
+                                        checkbox({row, checked, indeterminate}) {
+                                            return <span style={"font-size: 1.1em;cursor: pointer;"}
+                                                         onClick={(el) => {
+                                                             el.preventDefault()
+                                                             el.stopPropagation()
+                                                             handelCheckboxChange({row, checked: !checked})
+                                                         }}>
+                                                 {renderIcon(checked, indeterminate)}
+                                            </span>
+                                        }
+                                    }}
+                                </VxeColumn> : null,
+                            ...slots.default ? slots.default() : null,
+                        ];
+                    }
+                }}
+            </VxeTable>
+        }
+
+        if (simplifiedConfiguration.showPage) {
+            return <div class="cy_display_flex_y">
+                <div class="cy_flex_1-y">
+                    <TempVxeTable/>
+                </div>
+                <div style="height:max-content">
+                    <VxePager
+                        onPageChange={(data) => {
+                            pageChange()
+                        }}
+                        size={"small"}
+                        {...tsxVModel(pageVO, 'currentPage')}
+                        {...tsxVModel(pageVO, 'pageSize')}
+                        total={pageVO.total}
+                        {...simplifiedConfiguration.pagesProps}
+                        {...pagerProps}
+                    />
+                </div>
+            </div>
+
+        } else {
+            return <TempVxeTable/>
+        }
+    }
+
+    function exportExcel(filename: string = '', sheetName: string = 'sheet1') {
+        if (!XEUtils.isString(filename)) {
+            filename = ''
+        }
+        tableRef.value?.openExport({
+            filename,
+            sheetName,
+            types: ['xlsx', 'csv', 'html', 'xml', 'txt'],
+            type: 'xlsx',
+            useStyle: true,
+            original: true,
+        })
+    }
+
+    let queryParamsCache = {}
+
+    function pageChange() {
+        if (XEUtils.isEmpty(queryParamsCache)) {
+            return
+        }
+        const data = {
+            ...queryParamsCache,
+            ...pageVO
+        }
+        props.loading = true
+        pageQuery(data, false)
+    }
+
+    function pageQuery(data: any, clearCurrentPage: boolean = true) {
+        pagerProps.loading = true
+        // @ts-ignore
+        simplifiedConfiguration.remoteSearch(data).then(res => {
+            // @ts-ignore
+            const data: D[] = XEUtils.get(res, simplifiedConfiguration!.result || 'result') as D[]
+            // @ts-ignore
+            const total: number = XEUtils.get(res, simplifiedConfiguration!.total || 'total') as number
+            props.data = data
+            pageVO.total = total
+        }).catch((e) => {
+            props.data = []
+            pageVO.total = 0
+            console.error(e)
+        }).finally(() => {
+            if (clearCurrentPage) {
+                pageVO.currentPage = 1
+                pageMemory.clear()
+            }
+            props.loading = false
+            pagerProps.loading = false
+            handelPageCheckBox()
+        })
+    }
+
+    const pageMemory = reactive(new Map<any, D>());
+
+    function getCheckboxRecords() {
+        // @ts-ignore
+        return eachAndReturnList(pageMemory, (item) => {
+            return item
+        })
+    }
+
+    function handelCheckbox() {
+        const data = tableRef.value!.getCheckboxRecords()
+        if (data.length > 0) {
+            XEUtils.arrayEach(tableRef.value!.getCheckboxRecords(), (item) => {
+                // @ts-ignore
+                pageMemory.set(item[simplifiedConfiguration.keyField], item)
+            })
+        } else {
+            XEUtils.arrayEach(tableRef.value!.getData(), (item) => {
+                // @ts-ignore
+                pageMemory.delete(item[simplifiedConfiguration.keyField])
+            })
+        }
+    }
+
+    function handelPageCheckBox() {
+        nextTick().then(() => {
+            // @ts-ignore
+            XEUtils.arrayEach(pageMemory, (item) => {
+                tableRef.value?.setCheckboxRow(item, true)
+            })
+        })
+    }
+
+    function handelCheckboxChange({row, checked}: { row: any, checked: boolean }) {
+        mutation.setCheckboxRow(row, checked)
+    }
+
+    async function handelCheckboxAll() {
+        await tableRef.value?.toggleAllCheckboxRow()
+        nextTick().then(() => {
+            handelCheckbox()
+        })
+    }
+
+    function querySearch() {
+        props.loading = true
+        // @ts-ignore
+        if (simplifiedConfiguration.showPage) {
+            const pageData = {
+                ...pageVO,
+                total: 0,
+                currentPage: 1
+            }
+            queryParamsCache = pageData
+            pageQuery(pageData)
+        } else {
+            // @ts-ignore
+            simplifiedConfiguration.remoteSearch({...pageVO}).then(res => {
+                props.data = res
+            }).catch(() => {
+                props.data = []
+            }).finally(() => {
+                props.loading = false
+            })
+        }
+    }
+
+
+    function handelLookCheckBox() {
+
+        const dialog = (
+            <CyDialog title="选中详情"
+                      ignore-error
+                      body-width="70%"
+                      {...simplifiedConfiguration.dialogProps}>
+                {{
+                    default: () => {
+                        const data = getCheckboxRecords()
+                        return <CyFlex>
+                            {{
+                                header: () => {
+                                    try {
+                                        if (simplifiedConfiguration.dialogHeader) {
+                                            const Scc = simplifiedConfiguration?.dialogHeader();
+                                            if (typeof Scc !== 'undefined') {
+                                                return <Scc/>
+                                            } else {
+                                                console.error('dialogHeader需要返回一个组件')
+                                            }
+                                        }
+
+                                    } catch (e) {
+                                        console.error('dialogHeader需要返回一个组件', e)
+                                        return null
+                                    }
+                                },
+                                default: () => {
+                                    return <VxeTable data={data}
+                                                     rowConfig={{
+                                                         keyField: simplifiedConfiguration.keyField,
+                                                         isCurrent: true,
+                                                         isHover: true,
+                                                         useKey: true,
+                                                     }}
+                                                     scrollY={{enabled: true, gt: 100}}
+                                                     showOverflow={data.length > 100}
+                                                     height={"100%"}>
+                                        {{
+                                            default: () => {
+                                                return [
+                                                    <VxeColumn title={"删除"} width={80} fixed="left">
+                                                        {{
+                                                            default({row}: any) {
+                                                                return <ElButton
+                                                                    type="danger"
+                                                                    onClick={(el) => {
+                                                                        handelCheckboxChange({row, checked: false})
+                                                                    }}
+                                                                >{{default: () => '删除'}}
+                                                                </ElButton>
+                                                            }
+                                                        }}
+                                                    </VxeColumn>,
+                                                    mutation.setTableDefaultSlots()
+                                                ]
+                                            }
+                                        }}
+                                    </VxeTable>
+
+                                }
+                            }}
+
+                        </CyFlex>
+                    }
+                }}
+            </CyDialog>
+        )
+
+        setDialogToJs(dialog, null).then(() => {
+        })
+    }
+
+    const mutation = {
+        updateByIndex: function updateByIndex(data: D | any, index: number) {
+            const tableData = tableRef.value?.getData()
+            // @ts-ignore
+            tableData[index] = data
+            // @ts-ignore
+            tableRef.value?.loadData(tableData)
+        },
+        setCheckboxRow: async function (row: D, checked: boolean) {
+            await tableRef.value?.setCheckboxRow(row, checked)
+            // @ts-ignore
+            const key = XEUtils.get(row, simplifiedConfiguration!.keyField, null) as string | null
+            if (key === null) return
+            if (checked) {
+                pageMemory.set(key, row)
+            } else {
+                pageMemory.delete(key)
+            }
+        },
+        clearCheckboxRow() {
+            tableRef.value?.clearCheckboxRow()
+            pageMemory.clear()
+        },
+        setTableDefaultSlots(): any {
+
+        }
+    }
+
+    onMounted(() => {
+        if (simplifiedConfiguration.mountedQuery) {
+            nextTick().then(() => {
+                querySearch()
+            })
+        }
+    })
+
+
+    return {
+        tableRef,
+        CyVxeTable: CyVxeTable,
+        tableProps: props,
+        exportExcel,
+        mutation,
+        querySearch,
+        getCheckboxRecords
+    }
+}
+
+export default useVxeTable

+ 0 - 95
src/utils/useVxeTable.tsx

@@ -1,95 +0,0 @@
-import {ref, computed, reactive, watch, Ref, defineComponent} from 'vue'
-import {VxeTable} from "vxe-table";
-import type {VxeTableProps} from "vxe-table";
-import {TablePublicMethods, VxeTableEventProps} from "vxe-table/types/table";
-import XEUtils from "xe-utils";
-import {stringNotBlank} from "@/utils/blank-utils";
-import {TableExportMethods} from "vxe-table/types/export";
-
-declare type SimplifiedConfiguration<D> = {
-    rowHeight?: number,
-    keyField?: string,
-    currentKey?: string | number,
-    tableProps?: VxeTableEventProps<D> & VxeTableProps<D>,
-}
-
-
-function useVxeTable<D = any>(simplifiedConfiguration: SimplifiedConfiguration<D> = {}) {
-    const tableRef: Ref<TablePublicMethods<D> & TableExportMethods<D> | undefined> = ref()
-    const props: VxeTableProps<D> & VxeTableEventProps<D> & SimplifiedConfiguration<D> = reactive({
-        height: '100%',
-        rowConfig: {
-            isHover: true,
-            isCurrent: true,
-            height: simplifiedConfiguration?.rowHeight || 48,
-            useKey: true,
-            keyField: simplifiedConfiguration?.keyField || '',
-        },
-        scrollY: {
-            enabled: true,
-            gt: 0
-        },
-        scrollX: {
-            enabled: false,
-        },
-        exportConfig: {},
-        showOverflow: true,
-    })
-
-    watch(() => props.currentKey, () => {
-        if (stringNotBlank(defaultProps.value.rowConfig?.keyField)) {
-            const findData = XEUtils.find(defaultProps.value.data as [], (item) => {
-                // @ts-ignore
-                return item[defaultProps.value.rowConfig?.keyField] === props.currentKey;
-            })
-            if (!XEUtils.isEmpty(findData)) {
-                tableRef.value?.scrollToRow(findData)
-                tableRef.value?.setCurrentRow(findData)
-            }
-        }
-    }, {flush: 'post'})
-
-    const defaultProps = computed(() => {
-        return {
-            ...simplifiedConfiguration?.tableProps,
-            ...props
-        } as VxeTableProps<D>
-    })
-
-    const CyVxeTable = (props: VxeTableProps<D>, {slots}: any) => {
-        return <VxeTable
-            ref={tableRef}
-            {...defaultProps.value}
-            {...props}
-        >
-            {{
-                default: () => {
-                    return slots.default ? slots.default() : null;
-                }
-            }}
-        </VxeTable>
-    }
-
-    function exportExcel(filename: string = '', sheetName: string = 'sheet1') {
-        if (!XEUtils.isString(filename)) {
-            filename = ''
-        }
-        tableRef.value?.openExport({
-            filename,
-            sheetName,
-            types: ['xlsx', 'csv', 'html', 'xml', 'txt'],
-            type: 'xlsx',
-            useStyle: true,
-            original: true,
-        })
-    }
-
-    return {
-        tableRef,
-        CyVxeTable: CyVxeTable,
-        tableProps: props,
-        exportExcel
-    }
-}
-
-export default useVxeTable

+ 67 - 0
src/views/hospitalization/zhu-yuan-yi-sheng/patient-doctor/Index.vue

@@ -0,0 +1,67 @@
+<template>
+  <CyDialog title="三级医生设置"
+            body-height="max-content"
+            :confirm-click="submitToTheThirdLevelDoctor"
+            confirm-text="提交"
+  >
+    <el-form label-width="120px">
+      <el-form-item label="患者:">
+        {{ name }}
+      </el-form-item>
+      <el-form-item label="管床医生:">
+        <SystemStaffSelect v-model="data"
+                           value="referPhysician"
+                           label="referPhysicianName"
+        />
+      </el-form-item>
+      <el-form-item label="主治医生:">
+        <SystemStaffSelect v-model="data"
+                           value="consultPhysician"
+                           label="consultPhysicianName"
+        />
+      </el-form-item>
+      <el-form-item label="主任/副主任:">
+        <SystemStaffSelect v-model="data"
+                           value="deptDirector"
+                           label="deptDirectorName"
+        />
+      </el-form-item>
+    </el-form>
+  </CyDialog>
+</template>
+
+<script setup lang="ts">
+import SystemStaffSelect from '@/components/system/staff-select/SystemStaffSelect.vue'
+import CyDialog from "@/components/cy/dialog/src/CyDialog.vue";
+import {ref} from "vue";
+import {saveTheThirdLevelDoctor} from "@/api/zhu-yuan-yi-sheng/yi-zhu-lu-ru";
+
+const props = defineProps({
+  name: String,
+  referPhysician: String,
+  referPhysicianName: String,
+  consultPhysician: String,
+  consultPhysicianName: String,
+  deptDirector: String,
+  deptDirectorName: String,
+  inpatientNo: String,
+  admissTimes: Number
+})
+
+const data = ref({})
+
+onMounted(() => {
+  data.value = {...props}
+})
+
+function submitToTheThirdLevelDoctor(next) {
+  saveTheThirdLevelDoctor(data.value).then(() => {
+    next(data.value)
+  })
+}
+
+</script>
+
+<style scoped>
+
+</style>

+ 26 - 0
src/views/hospitalization/zhu-yuan-yi-sheng/patient-doctor/setPatientDoctor.tsx

@@ -0,0 +1,26 @@
+import setDialogToJs from "@/components/js-dialog-comp/useDialogToJs";
+import PatientDoctor from './Index.vue'
+
+export declare type SetPatientDoctorType = {
+    name: string,
+    referPhysician: string,
+    referPhysicianName: string,
+    consultPhysician: string
+    consultPhysicianName: string
+    deptDirector: string
+    deptDirectorName: string,
+    inpatientNo: string,
+    admissTimes: number,
+}
+
+function SetPatientDoctor(data: SetPatientDoctorType) {
+    return new Promise(resolve => {
+        setDialogToJs(PatientDoctor, data).then((res) => {
+            resolve(res)
+        }).catch(() => {
+        })
+    })
+}
+
+export default SetPatientDoctor
+

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

@@ -768,6 +768,8 @@ export function clickTimeLimitReminder() {
 export const clickOnThePatient = async (patNo: string) => {
 export const clickOnThePatient = async (patNo: string) => {
     switchPatients();
     switchPatients();
     huanZheXinXi.value = await getPatientInfo(patNo) as any;
     huanZheXinXi.value = await getPatientInfo(patNo) as any;
+
+    yzMitt.emit('setTableKey', huanZheXinXi.value!.inpatientNo)
     changePatientHook.forEach(item => {
     changePatientHook.forEach(item => {
         item()
         item()
     })
     })
@@ -798,15 +800,17 @@ export const clickOnThePatient = async (patNo: string) => {
     queryParam.value.zhuangTai = 0;
     queryParam.value.zhuangTai = 0;
     queryParam.value.displayRange = 2;
     queryParam.value.displayRange = 2;
     clearAssociate();
     clearAssociate();
-    const temp = getAncillaryInformation(huanZheXinXi.value.inpatientNo, huanZheXinXi.value.admissTimes);
-    if (temp) {
-        let str = JSON.stringify(temp);
-        jcExtraInformation.value = JSON.parse(str);
-        jyExtraInformation.value = JSON.parse(str);
-    } else {
-        jcExtraInformation.value = JSON.parse(strDefaultExtraInformation);
-        jyExtraInformation.value = JSON.parse(strDefaultExtraInformation);
-    }
+    getAncillaryInformation(huanZheXinXi.value.inpatientNo, huanZheXinXi.value.admissTimes).then(temp => {
+        if (temp) {
+            let str = JSON.stringify(temp);
+            jcExtraInformation.value = JSON.parse(str);
+            jyExtraInformation.value = JSON.parse(str);
+        } else {
+            jcExtraInformation.value = JSON.parse(strDefaultExtraInformation);
+            jyExtraInformation.value = JSON.parse(strDefaultExtraInformation);
+        }
+    });
+
 }
 }
 
 
 const switchPatients = (): boolean => {
 const switchPatients = (): boolean => {
@@ -990,6 +994,8 @@ export interface YzMitt {
 
 
     errorClick: (orderNo: any) => void;
     errorClick: (orderNo: any) => void;
 
 
+    setTableKey: (value: string) => void
+
     [key: string]: (...args: any[]) => any
     [key: string]: (...args: any[]) => any
 }
 }
 
 

+ 6 - 5
src/views/hospitalization/zhu-yuan-yi-sheng/yi-zhu-lu-ru/YiZhuLuRu.vue

@@ -12,11 +12,12 @@
                    :open-group-order-template="openGroupOrderTemplate"/>
                    :open-group-order-template="openGroupOrderTemplate"/>
       </template>
       </template>
       <template #default="{width,  height}">
       <template #default="{width,  height}">
-        <YzTableV3
-            :height="height"
-            :width="width"
-            @void-orders="voidOrdersClick"
-            @rowClick="rowClick"/>
+        <div :style="{width: width - 10 + 'px'}" style="height: 100%">
+          <YzTableV3
+              @void-orders="voidOrdersClick"
+              @rowClick="rowClick"/>
+        </div>
+
       </template>
       </template>
     </CyFlex>
     </CyFlex>
 
 

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

@@ -325,8 +325,8 @@ onMounted(() => {
 <template>
 <template>
   <vxe-table
   <vxe-table
       border
       border
-      :height="props.height"
-      :style="{width: props.width - 10 + 'px'}"
+      height="100%"
+      style="width: '100%'"
       :menu-config="menuConfig"
       :menu-config="menuConfig"
       @menu-click="tableRightClick"
       @menu-click="tableRightClick"
       @cell-dblclick="setDefaultStopTime"
       @cell-dblclick="setDefaultStopTime"