|
|
@@ -0,0 +1,386 @@
|
|
|
+<template>
|
|
|
+ <ele-pro-table
|
|
|
+ ref="table"
|
|
|
+ :needPage="false"
|
|
|
+ :columns="columns"
|
|
|
+ :datasource="tableData"
|
|
|
+ @cell-click="cellClick"
|
|
|
+ @row-click="rowClick"
|
|
|
+ @header-click="headerClick"
|
|
|
+ cache-key="systemRoleTable"
|
|
|
+ >
|
|
|
+ <!-- 表头工具栏 -->
|
|
|
+ <template v-slot:toolbar>
|
|
|
+ <el-form class="ele-form-search">
|
|
|
+ <el-row :gutter="15">
|
|
|
+ <el-col :span="4">
|
|
|
+ <el-form-item style="margin-bottom: 0">
|
|
|
+ <el-input
|
|
|
+ clearable
|
|
|
+ :placeholder="type == 'person' ? '搜索人员' : '搜索班组'"
|
|
|
+ v-model.trim="searchKey"
|
|
|
+ @input="search"
|
|
|
+ ></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="4">
|
|
|
+ <el-form-item style="margin-bottom: 0">
|
|
|
+ <el-date-picker
|
|
|
+ v-model="time"
|
|
|
+ type="month"
|
|
|
+ @change="timeChange"
|
|
|
+ value-format="yyyy-MM"
|
|
|
+ placeholder="选择月"
|
|
|
+ >
|
|
|
+ </el-date-picker>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="16">
|
|
|
+ <el-form-item class="btn-wrap" style="margin-bottom: 0">
|
|
|
+ <el-button @click="save">保存</el-button>
|
|
|
+ <el-button @click="rest">重置</el-button>
|
|
|
+ <el-button @click="anbp">{{
|
|
|
+ type == 'person' ? '按班排' : '按人排'
|
|
|
+ }}</el-button>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </el-form>
|
|
|
+ </template>
|
|
|
+ <template v-slot:item="{ row }">
|
|
|
+ {{ row.item.name }}
|
|
|
+ </template>
|
|
|
+ <template v-slot:bcHeader="{ column }">
|
|
|
+ <div v-html="showheaderName(column.label)"></div>
|
|
|
+ </template>
|
|
|
+ <template v-slot:bc="{ column, row }">
|
|
|
+ <div
|
|
|
+ class="tabel-cell-item"
|
|
|
+ :style="`background-color: ${showColor(el)};`"
|
|
|
+ v-for="el in showName(row, column)"
|
|
|
+ :key="el.id"
|
|
|
+ >
|
|
|
+ {{ el.name }}
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </ele-pro-table>
|
|
|
+</template>
|
|
|
+<script>
|
|
|
+import * as dayjs from 'dayjs';
|
|
|
+import { debounce } from 'throttle-debounce';
|
|
|
+export default {
|
|
|
+ props: ['selectedClasses', 'classesColor'],
|
|
|
+ data() {
|
|
|
+ const columnsDefault = {
|
|
|
+ person: {
|
|
|
+ prop: 'item',
|
|
|
+ label: '姓名',
|
|
|
+ slot: 'item'
|
|
|
+ },
|
|
|
+ team: {
|
|
|
+ prop: 'item',
|
|
|
+ label: '班组',
|
|
|
+ slot: 'item'
|
|
|
+ }
|
|
|
+ };
|
|
|
+ return {
|
|
|
+ type: 'person', // team 班次 person 人员
|
|
|
+ columnsDefault,
|
|
|
+ tableData: [],
|
|
|
+ //按人排数据
|
|
|
+ personData: [],
|
|
|
+ //按班排数据
|
|
|
+ teamData: [],
|
|
|
+ time: '',
|
|
|
+ columns: [],
|
|
|
+ searchKey: '',
|
|
|
+ dict: {
|
|
|
+ week: {
|
|
|
+ 0: '周末',
|
|
|
+ 1: '周一',
|
|
|
+ 2: '周二',
|
|
|
+ 3: '周三',
|
|
|
+ 4: '周四',
|
|
|
+ 5: '周五',
|
|
|
+ 6: '周六'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+ },
|
|
|
+ created() {
|
|
|
+ this.search = debounce(500, this.search);
|
|
|
+ this.time = dayjs(new Date()).format('YYYY-MM');
|
|
|
+ this.initColumns();
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ // 人员班次数据切换
|
|
|
+ setTableData() {
|
|
|
+ switch (this.type) {
|
|
|
+ case 'person':
|
|
|
+ this.tableData = this.personData;
|
|
|
+ break;
|
|
|
+ case 'team':
|
|
|
+ this.tableData = this.teamData;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 初始化columns
|
|
|
+ initColumns() {
|
|
|
+ let Month = dayjs(this.time).month() + 1;
|
|
|
+ let MonthNum = dayjs(this.time).daysInMonth();
|
|
|
+ let columns = [];
|
|
|
+ for (let index = 1; index <= MonthNum; index++) {
|
|
|
+ let week = dayjs(`${this.time}-${index}`).day();
|
|
|
+ columns.push({
|
|
|
+ prop: `${this.time}-${this.setNUm(index)} 00:00:00`,
|
|
|
+ label: `${Month}-${index}/${week}`,
|
|
|
+ slot: 'bc',
|
|
|
+ headerSlot: 'bcHeader',
|
|
|
+ width: 60
|
|
|
+ });
|
|
|
+ }
|
|
|
+ this.columns = [];
|
|
|
+ switch (this.type) {
|
|
|
+ case 'person':
|
|
|
+ this.columns.push(this.columnsDefault.person);
|
|
|
+ break;
|
|
|
+ case 'team':
|
|
|
+ this.columns.push(this.columnsDefault.team);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ this.columns = [].concat(this.columns, columns);
|
|
|
+ },
|
|
|
+ // 设置数据
|
|
|
+ setData(personData, teamData) {
|
|
|
+ this.personData = personData;
|
|
|
+ this.teamData = teamData;
|
|
|
+ this.setTableData();
|
|
|
+ },
|
|
|
+ showName(row, column) {
|
|
|
+ let list = row[column.property];
|
|
|
+ if (list) {
|
|
|
+ list.forEach((n) => {
|
|
|
+ n.name = n.name.slice(0, 4);
|
|
|
+ });
|
|
|
+ return list;
|
|
|
+ } else {
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+ },
|
|
|
+ showheaderName(label) {
|
|
|
+ let list = label.split('/');
|
|
|
+ let week = this.dict.week[list[1]];
|
|
|
+ return `${list[0]}</br>${week}`;
|
|
|
+ },
|
|
|
+ // 设置颜色
|
|
|
+ showColor(item) {
|
|
|
+ return this.classesColor[item.id];
|
|
|
+ },
|
|
|
+ // 单元格点击
|
|
|
+ cellClick(row, column) {
|
|
|
+ const selectedClasses = JSON.parse(JSON.stringify(this.selectedClasses));
|
|
|
+ if (column.property !== 'item' && selectedClasses.length > 0) {
|
|
|
+ if (selectedClasses[0].id == 'clear') {
|
|
|
+ this.$delete(row, column.property);
|
|
|
+ } else {
|
|
|
+ this.$set(row, column.property, selectedClasses);
|
|
|
+ }
|
|
|
+ // 按班排同步人员
|
|
|
+ if (this.type == 'team') {
|
|
|
+ this.SyncCellClick(row, column);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 行点击
|
|
|
+ rowClick(row, column) {
|
|
|
+ const selectedClasses = JSON.parse(JSON.stringify(this.selectedClasses));
|
|
|
+ if (column.property == 'item' && selectedClasses.length > 0) {
|
|
|
+ if (selectedClasses[0].id == 'clear') {
|
|
|
+ this.columns.forEach((n) => {
|
|
|
+ if (n.prop !== 'item') {
|
|
|
+ this.$delete(row, n.prop);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ this.columns.forEach((n) => {
|
|
|
+ if (n.prop !== 'item') {
|
|
|
+ this.$set(row, n.prop, selectedClasses);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ // 按班排同步人员
|
|
|
+ if (this.type == 'team') {
|
|
|
+ this.SyncRowClick(row, column);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 列点击
|
|
|
+ headerClick(column) {
|
|
|
+ const selectedClasses = JSON.parse(JSON.stringify(this.selectedClasses));
|
|
|
+ if (column.property !== 'item' && selectedClasses.length > 0) {
|
|
|
+ if (selectedClasses[0].id == 'clear') {
|
|
|
+ this.tableData.forEach((n) => {
|
|
|
+ this.$delete(n, column.property);
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ this.tableData.forEach((n) => {
|
|
|
+ this.$set(n, column.property, selectedClasses);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ // 按班排同步人员
|
|
|
+ if (this.type == 'team') {
|
|
|
+ this.SyncHeaderClick(column);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 按班排同步人员-单元格点击
|
|
|
+ SyncCellClick(row, column) {
|
|
|
+ const selectedClasses = JSON.parse(JSON.stringify(this.selectedClasses));
|
|
|
+ let Person = this.getid_Person(row.item.teamId);
|
|
|
+ if (selectedClasses[0].id == 'clear') {
|
|
|
+ Person.forEach((n) => {
|
|
|
+ this.$delete(n, column.property);
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ Person.forEach((n) => {
|
|
|
+ this.$set(n, column.property, selectedClasses);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 按班排同步人员-行点击
|
|
|
+ SyncRowClick(row, column) {
|
|
|
+ const selectedClasses = JSON.parse(JSON.stringify(this.selectedClasses));
|
|
|
+ let Person = this.getid_Person(row.item.teamId);
|
|
|
+ if (selectedClasses[0].id == 'clear') {
|
|
|
+ Person.forEach((n) => {
|
|
|
+ this.columns.forEach((nl) => {
|
|
|
+ if (nl.prop !== 'item') {
|
|
|
+ this.$delete(n, nl.prop);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ Person.forEach((n) => {
|
|
|
+ this.columns.forEach((nl) => {
|
|
|
+ if (nl.prop !== 'item') {
|
|
|
+ this.$set(n, nl.prop, selectedClasses);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 按班排同步人员-列点击
|
|
|
+ SyncHeaderClick(column) {
|
|
|
+ const selectedClasses = JSON.parse(JSON.stringify(this.selectedClasses));
|
|
|
+ if (selectedClasses[0].id == 'clear') {
|
|
|
+ this.personData.forEach((n) => {
|
|
|
+ this.$delete(n, column.property);
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ this.personData.forEach((n) => {
|
|
|
+ this.$set(n, column.property, selectedClasses);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 根据班组id查询人员
|
|
|
+ getid_Person(id) {
|
|
|
+ let list = this.personData.filter((n) => {
|
|
|
+ return n.item.teamId == id;
|
|
|
+ });
|
|
|
+ return list;
|
|
|
+ },
|
|
|
+ // 保存
|
|
|
+ save() {
|
|
|
+ this.$emit('save');
|
|
|
+ },
|
|
|
+ // 重置
|
|
|
+ rest() {
|
|
|
+ this.$emit('rest');
|
|
|
+ },
|
|
|
+ // 按人/班排
|
|
|
+ anbp() {
|
|
|
+ this.type = this.type == 'person' ? 'team' : 'person';
|
|
|
+ this.initColumns();
|
|
|
+ this.setTableData();
|
|
|
+ },
|
|
|
+ // 切换按班排班
|
|
|
+ changanbp() {
|
|
|
+ this.type = 'team';
|
|
|
+ this.initColumns();
|
|
|
+ this.setTableData();
|
|
|
+ },
|
|
|
+ // 选择时间
|
|
|
+ timeChange() {
|
|
|
+ this.initColumns();
|
|
|
+ },
|
|
|
+ // 补零
|
|
|
+ setNUm(num) {
|
|
|
+ let length = 2;
|
|
|
+ return (num / Math.pow(10, length)).toFixed(length).substr(2);
|
|
|
+ },
|
|
|
+ // 搜索
|
|
|
+ search(val) {
|
|
|
+ switch (this.type) {
|
|
|
+ case 'person':
|
|
|
+ if (val !== '') {
|
|
|
+ setTimeout(() => {
|
|
|
+ this.tableData = this.personData.filter((n) => {
|
|
|
+ return (
|
|
|
+ n.item.name.toLowerCase().indexOf(val.toLowerCase()) > -1
|
|
|
+ );
|
|
|
+ });
|
|
|
+ }, 200);
|
|
|
+ } else {
|
|
|
+ this.tableData = this.personData;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 'team':
|
|
|
+ if (val !== '') {
|
|
|
+ setTimeout(() => {
|
|
|
+ this.tableData = this.teamData.filter((n) => {
|
|
|
+ return (
|
|
|
+ n.item.name.toLowerCase().indexOf(val.toLowerCase()) > -1
|
|
|
+ );
|
|
|
+ });
|
|
|
+ }, 200);
|
|
|
+ } else {
|
|
|
+ this.tableData = this.teamData;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+};
|
|
|
+</script>
|
|
|
+<style lang="scss" scoped>
|
|
|
+:deep(.el-table .el-table__cell) {
|
|
|
+ cursor: pointer;
|
|
|
+ height: 60px;
|
|
|
+}
|
|
|
+.tabel-cell-item {
|
|
|
+ color: #fff;
|
|
|
+ height: 60px;
|
|
|
+ overflow: hidden;
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ padding: 15px !important;
|
|
|
+}
|
|
|
+:deep(.el-table td.el-table__cell) {
|
|
|
+ padding: 0;
|
|
|
+ div {
|
|
|
+ padding: 0;
|
|
|
+ }
|
|
|
+}
|
|
|
+.btn-wrap {
|
|
|
+ text-align: right;
|
|
|
+ padding-right: 20px;
|
|
|
+}
|
|
|
+</style>
|