基于vue3+ts-el-table合并单元格实现排班功能

<template>
    <div class="dwj_ss_pb_div" style="width: 100%;height: 800px;">
        <el-table ref="multipleTable"
                  class="theme-el-table"
                  :data="tableData"
                  :height="500" border
                  :row-style="{height: '150px'}"
                  :cell-style="tableCellStyle"
                  :span-method="arraySpanMethod"
                  :row-class-name="tableRowClassName"
                  highlight-current-row>
            <el-table-column label="手术间" prop="itemName" width="100" align="center"/>
            <el-table-column v-for="itemCol in tbSetColList"
                             :key="itemCol.value"
                             :index="itemCol.value"
                             :property="itemCol.value"
                             :label="itemCol.value"
                             show-overflow-tooltip
                             width="70" align="center">
                <template v-slot="scope">
                    <span v-if="getDivBoxInfo(scope.row,itemCol.value)!='noInfo'">
                        <div class="dwj_time_bc_div">
                            <span v-if="false">{{itemCol.value}}</span>
                            <div v-for="(item,key) in [getDivBoxInfo(scope.row,itemCol.value)]">
                                <div class="div-inline dwj_box_lefts">
                                    <span>{{item.ssxh+1}}</span>
                                </div>
                                <div class="div-inline dwj_box_right">
                                    <span v-if="item.hzxm!=null&&item.hzxm!=''">
                                        <div class="dwj_box_row">{{item.hzxm}},{{item.sex}},{{item.nl}}{{item.nldw}}</div>
                                        <div class="dwj_box_row">{{item.ksmc}},{{item.zdmc}}</div>
                                        <div class="dwj_box_row">{{item.ydrq}}</div>
                                        <div class="dwj_box_row">{{item.mzys}},{{item.kdys}}</div>
                                    </span>
                                </div>
                            </div>
                        </div>
                    </span>
                    <span v-else><span v-if="true">{{itemCol.value}}</span></span>
                </template>
            </el-table-column>
        </el-table>
    </div>
</template>

<script lang="ts">
    import { useStore } from 'vuex';
    import { useRoute,useRouter} from 'vue-router';
    import { parseTimeOper } from '@/utils'
    import { toRefs,reactive,onMounted,onBeforeMount,getCurrentInstance } from 'vue';
    export default {
        setup(props,content) {
            const {proxy} = getCurrentInstance() as any;
            const route = useRoute()
            const state:any = reactive({
                tableData: [
                    {
                        itemeCode: '01',
                        itemName: '第一手术间',
                        surgeryList: [],
                    },
                    {
                        itemeCode: '02',
                        itemName: '第二手术间',
                        surgeryList: [],
                    },
                ],
                tbSetColList: [
                    {value:'00:00',},
                    {value:'01:00',},
                    {value:'02:00',},
                    {value:'03:00',},
                    {value:'04:00',},
                    {value:'05:00',},
                    {value:'06:00',},
                    {value:'07:00',},
                    {value:'08:00',},
                    {value:'09:00',},
                    {value:'10:00',},
                    {value:'11:00',},
                    {value:'12:00',},
                ],
                tbSetColList2: [
                    {value:'00:00',},
                    {value:'00:30',},
                    {value:'01:00',},
                    {value:'01:30',},
                    {value:'02:00',},
                    {value:'02:30',},
                    {value:'03:00',},
                    {value:'03:30',},
                    {value:'04:00',},
                    {value:'04:30',},
                    {value:'05:00',},
                    {value:'05:30',},
                    {value:'06:00',},
                    {value:'06:30',},
                    {value:'07:00',},
                    {value:'07:30',},
                    {value:'08:00',},
                    {value:'08:30',},
                    {value:'09:00',},
                    {value:'09:30',},
                    {value:'10:00',},
                    {value:'10:30',},
                    {value:'11:00',},
                    {value:'11:30',},
                    {value:'12:00',},
                ],
                SS_TIME_DIFF: 60,
            })
            const router = useRouter()
            // 全局登录者信息user
            const user = useStore().getters.user;
            onBeforeMount(() => {

            });
            // 页面加载时
            onMounted(() => {
                state.tableData[0].surgeryList = [
                    {
                        ssxh: 0,
                        kssj: '2023-10-13 00:00',
                        jssj: '2023-10-13 02:00',
                        hzxm: '孙富贵',
                        sex: '男',
                        nl: '62',
                        nldw: '岁',
                        ksmc: '骨科',
                        zdmc: '(鼻-)屁眼疼',
                        ydrq: '2023-10-17 12:00',
                        mzys: '大美丽(0123)',
                        kdys: '小索斯(0139)',
                    },
                    {
                        ssxh: 1,
                        kssj: '2023-10-13 03:00',
                        jssj: '2023-10-13 05:00',
                    }
                ]
                state.tableData[1].surgeryList = [
                    {
                        ssxh: 0,
                        kssj: '2023-10-13 01:00',
                        jssj: '2023-10-13 05:00',
                        hzxm: 'dingwangjun',
                        sex: '男人',
                        nl: '28',
                        nldw: '岁',
                        ksmc: '骨科',
                        zdmc: '鼻炎、打喷嚏',
                        ydrq: '2023-10-17 12:00',
                        mzys: '张大磊(0000)',
                        kdys: '张小斌(0230)',
                    },
                    {
                        ssxh: 1,
                        kssj: '2023-10-13 06:00',
                        jssj: '2023-10-13 08:00',
                    },
                    {
                        ssxh: 2,
                        kssj: '2023-10-13 09:00',
                        jssj: '2023-10-13 12:00',
                    },
                    {
                        ssxh: 3,
                        kssj: '2023-10-13 13:00',
                        jssj: '2023-10-13 14:00',
                    }
                ]
                methods.getTimeArray(state.SS_TIME_DIFF)
            });
            const methods = {
                parseTimeOper,
                tableRowClassName({row, rowIndex}){
                    row.index = rowIndex
                },
                getDivBoxInfo(row,value){
                    let hasInfo = row.surgeryList.find(
                        p=>parseTimeOper(p.kssj)==value)
                    if(hasInfo!=undefined){
                        return hasInfo
                    }else {
                        return 'noInfo'
                    }
                },
                getTimeArray(step) {
                    // step:以分钟为步调
                    // 比如:15分30分60分
                    /**Mr.丁计算排班动态列*/
                    let timeArray :any= [];
                    for(let h = 0; h <= 24; h++){
                        for(let m = 0; m < 60; m += step){
                            let hour = String(h).padStart(2,'0');
                            let minute = String(m).padStart(2,'0');
                            let hourMinute:any = `${hour}:${minute}`
                            timeArray.push({ value:  hourMinute});
                        }
                    }
                    state.tbSetColList = timeArray
                    return timeArray;
                },
                computeColDiffByDwj(row,i){
                    /**Mr.丁dingwangjun原创动态计算跨列数*/
                    // 中间间距60分钟|30分钟|15分钟
                    /**dwj:根据参数设置差距//设置的时间差*/
                    let midValue = state.SS_TIME_DIFF
                    // 获取一个手术计算手术开始时间位置
                    let hasSurgery = row.surgeryList[i]
                    if(row.surgeryList[i]!=undefined){
                        let kssj :any= row.surgeryList[i].kssj
                        let jssj :any= row.surgeryList[i].jssj
                        let jsrq = new Date(jssj).getTime()
                        let ksrq = new Date(kssj).getTime()
                        // 结束时间-开始时间的时间数,例如90分钟
                        let timeNo = (jsrq-ksrq)/(3600*1000)
                        // 列数:需要横跨几列(不同配置不同跨列)
                        let colNums = timeNo * 60 / midValue
                        // 开始时间的时:分;例如08:00
                        let ksValue = kssj.substring(11)
                        // 获取开始时间列的索引startNo
                        let list = state.tbSetColList
                        let startNo = list.findIndex(p=>p.value==ksValue)
                        return {
                            colNums: colNums,
                            startNo: startNo,
                        }
                    }else {
                        return {
                            colNums: 9999999,
                            startNo: 9999999,
                        }
                    }
                },
                arraySpanMethod({row,column,rowIndex,columnIndex}){
                    /**Mr.丁dingwangjun原创动态计算跨列方法*/
                    // 根据每一个手术间手术计算手术开始时间的位置
                    let opsList = row.surgeryList
                    for(let i=0;i<opsList.length;i++){
                        let dwjObj = methods.computeColDiffByDwj(row,i)
                        // dwjObj.colNums 列数需要横跨几列
                        // dwjObj.startNo 获取开始时间列的索引
                        let startIn = dwjObj.startNo+1
                        if(columnIndex===startIn){
                            // 横穿马路跨几列:colNum列
                            return [1, dwjObj.colNums];
                        }
                        let list :any= []
                        if(dwjObj.colNums>=2){
                            for(let i=0;i<dwjObj.colNums;i++){
                                list.push(startIn+i)
                            }
                            // 那几列需要合并为一列:list列
                            if(list.includes(columnIndex)){
                                return [1, 0];
                            }
                        }
                    }
                },
                tableCellStyle({row,column,rowIndex,columnIndex}){
                    let dwjObj = methods.computeColDiffByDwj(row,0)
                },
            };
            return {
                ...toRefs(state),
                ...methods,
            };
        }
    }
</script>

<style lang="scss">
    .dwj_ss_pb_div{
        /*table中单元格内边距-调整到靠近边框*/
        .el-table .cell, .el-table th div, .el-table--border .cell {
            padding-left: 1px;
            padding-right: 1px;
        }
        /*禁掉一切封装的或其他自定义的样式*/
        .el-table__body tr:hover>td{
            background-color: #FFFFFF !important;
        }
        .el-table__body tr.current-row>td {
            background-color: #FFFFFF !important;
        }
    }
    .dwj_time_bc_div{
        width: 100%;
        height: 145px;
        border-radius: 5px;
        border: 1px solid #4884F0;
    }
    .dwj_time_bc_div:hover{
        cursor: pointer;
        background: #dee4fe;
    }
    .dwj_box_lefts{
        width: 20px;
        height: 145px;
        line-height: 145px;
        border-right: 1px solid #f2f2f2;
        //background: #ffd591;
    }
    .dwj_box_right{
        width: calc(100% - 20px);
        height: 145px;
        text-align: left;
        margin-left: 5px;
        padding-top: 8px;
        padding-bottom: 5px;
        //background: #2D5AFA;
    }
    .dwj_box_row{
        height: 30px;
        line-height: 30px;
    }

</style>

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值