ElementUI动态加载表头,每行最多显示5个姓名,同一个部门内每超过5个人员则换行

需求描述

 

  1. 数据展示:
  1. 描述按照“部门”维度归类整合后,展示系统使用人员的在线、离开、离线情况(备注:没有所属部门的人员,归类在公司下)
  2. 展示列:展示所属公司、所属部门、姓名、姓名……
  • 人员不同状态使用不用颜色标识、离开用户显示离开时间(显示到“分钟”或“小时分钟”,“秒”省略展示)

 

  • 每行最多显示5个姓名,同一个部门内每超过5个人员则换行展示(备注:没有所属部门的人员,归类在公司下,每超过10个人员也换行展示)
  • 空部门不展示(即:若部门下无姓名时候,不展示)

前端页面如下

 

<template>
  <div>
    <el-row>
      <el-col>
        <el-form
          ref="searchForm"
          :model="searchForm"
          label-width="140px"
          class="search-form"
          :rules="formRules"
          size="mini"
        >
          <el-row>
            <el-col :span="8">
              <el-form-item label="催收员:" prop="taskOwnerIdList">
                <tree-select
                  multiple
                  v-model="searchForm.taskOwnerIdList"
                  placeholder="请选择"
                  :options="taskOwnerTreeData"
                >
                  <label slot="option-label" slot-scope="{ node }">
                    <svg class="icon">
                      <use
                        :xlink:href="node.raw.data.type == 'user' ? (node.raw.data.sex == 2 ? '#icon-nvhai' : '#icon-nanhai') : '#icon-bumen'"
                      />
                    </svg>
                    <span>{{ node.label }}</span>
                  </label>
                </tree-select>
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="离开识别时间:" prop="recognitionInterval">
                <el-input v-model.number="searchForm.recognitionInterval"></el-input>
              </el-form-item>
            </el-col>

            <el-col :span="8">
              <el-button
                style="margin: 0px 0px 0px 12px;"
                type="primary"
                icon="el-icon-search"
                size="mini"
                @click="doSearch"
              >查询</el-button>
            </el-col>
          </el-row>
        </el-form>
      </el-col>
    </el-row>
    <el-row></el-row>

    <el-row class="re-breadcrumb" ref="reBreadcrumb" style="padding:0px 0px 8px 12px;">
      <el-col :span="32">
        <el-breadcrumb separator="/">
          <el-breadcrumb-item>
            <font color="#606266">
              (查询时间:
              <b>{{queryTime}}</b>)
            </font>
          </el-breadcrumb-item>
        </el-breadcrumb>
        <div class="hr"></div>
      </el-col>
    </el-row>

    <el-row class="page-table">
      <el-col>
        <el-table
          v-bind:data="tableData"
          :height="tableHeight"
          border
          width="100%;"
          size="mini"
          v-loading="dataLoading"
          id="table-content"
          :span-method="objectSpanMethod"
        >
          <template v-for="(item,index) in tableHead">
            <el-table-column
              :prop="item.column_name"
              :label="item.column_comment"
              :key="index"
              v-if="item.column_comment == '姓名' "
            >
              <template slot-scope="scope">
                <span
                  v-if="scope.column.property.substring(scope.column.property.length-1)-scope.row.onlineStatus.length<=0"
                  v-html="scope.row.onlineStatus[scope.column.property.substring(scope.column.property.length-1)-1].content"
                ></span>
              </template>
            </el-table-column>
            <el-table-column
              :prop="item.column_name"
              :label="item.column_comment"
              :key="index"
              v-if="item.column_comment != '姓名' "
            ></el-table-column>
          </template>
        </el-table>
        <div class="re-pagination" ref="pagination">
          <el-pagination
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
            :current-page="pagination.currentPage"
            :page-sizes="[10, 20, 30, 40, 50, 100]"
            :page-size="pagination.pageSize"
            layout="total, sizes, prev, pager, next, jumper"
            :total="pagination.count"
          ></el-pagination>
        </div>
      </el-col>
    </el-row>
  </div>
</template>
<script>
    import request from "@/utils/request";
    import treeDataUtil from "@/utils/treeDataUtil";
    export default {
        name: "collector-online-status",
        components: {},
        data() {
            return {
                collectorList: [],
                taskOwnerTreeData: [],
                peopleLineCount: 0, //一行部门人数展示人数
                MaxPeopleLineCount: 5, //一行部门人数最多展示人数5人
                queryTime: "", 查询时间
                indexInfoList: [],
                tableHead: [],
                sortedColumn: "",
                sortedtype: "",
                searchForm: {
                    taskOwnerIdList: [],
                    recognitionInterval: 15
                },
                tableData: [],
                tableHeight: 600,
                dataLoading: false,
                formRules: {
                    recognitionInterval: [
                        { required: true, message: "必填字段", trigger: "blur" },
                        { type: "number", message: "填写数字", trigger: "blur" }
                    ]
                },
                pagination: {
                    currentPage: 1,
                    pageSize: 10,
                    // 记录总数
                    count: 0,
                    // 页数
                    pages: 0
                },
                defaultExportMaxCount: 15000
            };
        },
        computed: {},
        created: async function() {
            var self = this;

            request({
                url: "/dim/query-collector-list",
                method: "post",
                data: {
                    option: "query"
                }
            }).then(response => {
                self.collectorList = response.data.data;
            });
            request({
                url: "/collector-online-status/query-recognition-interval",
                method: "get"
            }).then(response => {
                if (response.data.ret == "0000") {
                    this.$nextTick(() => {
                        self.searchForm.recognitionInterval =
                            response.data.data.recognitionInterval;
                    });
                }
            });

            setTimeout(() => {
                self.doSearch();
            }, 500);
        },
        watch: {
            collectorList() {
                this.taskOwnerTreeData = treeDataUtil.createUserTreeData(
                    this.collectorList
                );
                this.$nextTick(() => {
                    this.searchForm.taskOwnerIdList = [];
                });
            }
        },
        methods: {
            loadData: function(currentPage, pageSize) {
                if (!this.searchForm.recognitionInterval) {
                    return;
                }
                if (currentPage) {
                    this.pagination.currentPage = currentPage;
                }
                if (pageSize) {
                    this.pagination.pageSize = pageSize;
                }
                let self = this;
                let searchForm = JSON.parse(JSON.stringify(this.searchForm));
                searchForm.taskOwnerIdList = treeDataUtil.getUserIdList(
                    searchForm.taskOwnerIdList
                );

                request({
                    url: "/collector-online-status/query-online-list",
                    method: "post",
                    loading: true,
                    data: {
                        page: {
                            currentPage: self.pagination.currentPage,
                            pageSize: self.pagination.pageSize
                        },
                        param: searchForm
                    }
                })
                    .then(response => {
                        this.dataLoading = false;
                        this.tableData = [];
                        let result = response.data.data;
                        this.queryTime = result.queryTime;
                        this.pagination = result.pageData.page;
                        let data = result.pageData.list;
                        //动态加载表格表头数据
                        for (const i in data) {
                            let ele = data[i];
                            if (
                                ele.hasOwnProperty("onlineStatus") &&
                                ele.onlineStatus.length > 0
                            ) {
                                if (
                                    ele.onlineStatus.length > this.MaxPeopleLineCount ||
                                    ele.onlineStatus.length == this.MaxPeopleLineCount
                                ) {
                                    this.peopleLineCount = this.MaxPeopleLineCount;
                                    break;
                                } else {
                                    this.peopleLineCount = ele.onlineStatus.length;
                                }
                            }
                        }
                        this.tableHead = [
                            {
                                column_name: "currentOwnerCom",
                                column_comment: "所属公司"
                            },
                            {
                                column_name: "currentOwnerDept",
                                column_comment: "所属部门"
                            }
                        ];
                        for (let i = 1; i <= this.peopleLineCount; i++) {
                            this.tableHead.push({
                                column_name: "peopel" + i,
                                column_comment: "姓名"
                            });
                        }
                        let arr = [];
                        // 公司人数超过5人数据需要拆分,同一个公司合并单元格
                        data.forEach(ele => {
                            if (ele.onlineStatus.length > this.MaxPeopleLineCount) {
                                let length = ele.onlineStatus.length;
                                let index =
                                    length % this.MaxPeopleLineCount == 0
                                        ? length / this.MaxPeopleLineCount - 1
                                        : parseInt(length / this.MaxPeopleLineCount);
                                for (let i = 0; i <= index; i++) {
                                    let obj = {};
                                    obj.currentOwnerCom = ele.currentOwnerCom;
                                    obj.currentOwnerDept = ele.currentOwnerDept;
                                    obj.onlineStatus = ele.onlineStatus.slice(
                                        i * this.MaxPeopleLineCount,
                                        (i + 1) * this.MaxPeopleLineCount
                                    );
                                    obj.onlineStatus.forEach(ele => {
                                        ele.content = this.formatterContent(ele);
                                    });
                                    this.tableData.push(obj);
                                }
                            } else {
                                ele.onlineStatus.forEach(ele => {
                                    ele.content = this.formatterContent(ele);
                                });
                                this.tableData.push(ele);
                            }
                        });

                        this.tableData.forEach(ele => {
                            let firstIndex = this.tableData.findIndex(item => {
                                return item.currentOwnerCom === ele.currentOwnerCom;
                            });
                            if (
                                arr.findIndex(item => {
                                    return item.firstIndex === firstIndex;
                                }) === -1
                            ) {
                                arr.push({
                                    length: this.tableData.filter(item => {
                                        return item.currentOwnerCom === ele.currentOwnerCom;
                                    }).length,
                                    firstIndex: firstIndex
                                });
                            }
                        });
                        this.indexInfoList = arr; // 得到的arr里面的内容:Array(3) // 0 : firstIndex : 0; length: 4  1: firstIndex: 4 length:5
                    })
                    .catch(error => {
                        self.dataLoading = false;
                    });
            },
            formatterContent(data) {
                let color = "",
                    tip = "",
                    time = "";
                if (data.status == 0) {
                    color = "green";
                    tip = "在线";
                } else if (data.status == 1) {
                    color = "yellow";
                    tip = "离开";
                } else {
                    color = "red";
                    tip = "离线";
                }
                let res =
                    "<span>" +
                    data.name +
                    "</span><span " +
                    "class = " +
                    color +
                    ">(" +
                    tip +
                    ")</span>";
                if (data.status == 1) {
                    res += "</br><span>(" + data.timeInterval + ")</span>";
                }
                return res;
            },
            doSearch: function() {
                this.loadData(1);
            },
            handleSizeChange: function(val) {
                this.loadData(1, val);
            },
            handleCurrentChange: function(val) {
                this.loadData(val);
            },
            objectSpanMethod({ row, column, rowIndex, columnIndex }) {
                if (columnIndex === 0) {
                    let index = this.indexInfoList.findIndex(item => {
                        //遍历数组
                        return item.firstIndex === rowIndex;
                    });
                    if (index > -1) {
                        return {
                            rowspan: this.indexInfoList[index].length,
                            colspan: 1
                        };
                    } else {
                        return {
                            rowspan: 0,
                            colspan: 0
                        };
                    }
                }
            }
        }
    };
</script>
<style less='lang'>
  .red {
    color: red;
  }
  .green {
    color: green;
  }
  .yellow {
    color: #fd8f08e0;
  }
</style>

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值