|
|
@@ -1,76 +1,84 @@
|
|
|
<template>
|
|
|
- <ele-pro-table
|
|
|
- ref="table"
|
|
|
- :needPage="false"
|
|
|
- :columns="columns"
|
|
|
- :datasource="tableData"
|
|
|
- @cell-click="cellClick"
|
|
|
- @row-click="rowClick"
|
|
|
- @header-click="headerClick"
|
|
|
- cache-key="systemRoleTable19"
|
|
|
+ <div
|
|
|
+ @mousedown="startSelecting"
|
|
|
+ @mousemove="updateSelection"
|
|
|
+ @mouseup="stopSelecting"
|
|
|
>
|
|
|
- <!-- 表头工具栏 -->
|
|
|
- <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>
|
|
|
+ <ele-pro-table
|
|
|
+ ref="table"
|
|
|
+ :needPage="false"
|
|
|
+ :columns="columns"
|
|
|
+ :datasource="tableData"
|
|
|
+ @cell-click="cellClick"
|
|
|
+ @row-click="rowClick"
|
|
|
+ @header-click="headerClick"
|
|
|
+ cache-key="systemRoleTable19"
|
|
|
+ >
|
|
|
+ <!-- 表头工具栏 -->
|
|
|
+ <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" type="primary">保存</el-button>
|
|
|
+ <el-button @click="rest">重置</el-button>
|
|
|
+ <el-button @click="anbp" type="primary">{{
|
|
|
+ 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, $index }">
|
|
|
+ <div
|
|
|
+ class="tabel-cell-item"
|
|
|
+ :style="`background-color: ${showColor(el)};`"
|
|
|
+ v-for="el in showName(row, column)"
|
|
|
+ :key="el.id"
|
|
|
+ ref="tabelItem"
|
|
|
+ >
|
|
|
+ {{ el.name }}
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </ele-pro-table>
|
|
|
+ <div v-if="isSelecting" class="selection-box" :style="selectionStyle"></div>
|
|
|
+ </div>
|
|
|
</template>
|
|
|
<script>
|
|
|
import * as dayjs from 'dayjs';
|
|
|
import { debounce } from 'throttle-debounce';
|
|
|
export default {
|
|
|
props: ['selectedClasses', 'classesColor'],
|
|
|
- data () {
|
|
|
+ data() {
|
|
|
const columnsDefault = {
|
|
|
person: {
|
|
|
prop: 'item',
|
|
|
@@ -84,6 +92,11 @@
|
|
|
}
|
|
|
};
|
|
|
return {
|
|
|
+ isSelecting: false,
|
|
|
+ startX: 0,
|
|
|
+ startY: 0,
|
|
|
+ endX: 0,
|
|
|
+ endY: 0,
|
|
|
type: 'person', // team 班次 person 人员
|
|
|
columnsDefault,
|
|
|
tableData: [],
|
|
|
@@ -107,14 +120,68 @@
|
|
|
}
|
|
|
};
|
|
|
},
|
|
|
- created () {
|
|
|
+ computed: {
|
|
|
+ selectionStyle() {
|
|
|
+ return {
|
|
|
+ position: 'absolute',
|
|
|
+ left: `${Math.min(this.startX, this.endX)}px`,
|
|
|
+ top: `${Math.min(this.startY, this.endY)}px`,
|
|
|
+ width: `${Math.abs(this.endX - this.startX)}px`,
|
|
|
+ height: `${Math.abs(this.endY - this.startY)}px`,
|
|
|
+ border: '2px dashed black'
|
|
|
+ };
|
|
|
+ }
|
|
|
+ },
|
|
|
+ created() {
|
|
|
this.search = debounce(500, this.search);
|
|
|
this.time = dayjs(new Date()).format('YYYY-MM');
|
|
|
this.initColumns();
|
|
|
},
|
|
|
methods: {
|
|
|
+ startSelecting(event) {
|
|
|
+ return
|
|
|
+ this.isSelecting = true;
|
|
|
+ this.startX = event.clientX;
|
|
|
+ this.startY = event.clientY;
|
|
|
+ this.endX = this.startX;
|
|
|
+ this.endY = this.startY;
|
|
|
+ },
|
|
|
+ updateSelection(event) {
|
|
|
+ return
|
|
|
+ if (this.isSelecting) {
|
|
|
+ this.endX = event.clientX;
|
|
|
+ this.endY = event.clientY;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ stopSelecting() {
|
|
|
+ return
|
|
|
+ this.isSelecting = false;
|
|
|
+ // 在这里处理框选结果,例如计算被框选的元素
|
|
|
+ this.selectedItems = this.calculateSelectedItems();
|
|
|
+ },
|
|
|
+ calculateSelectedItems() {
|
|
|
+ return this.tableData.filter((item, index) => {
|
|
|
+ console.log(item,'item');
|
|
|
+ console.log(
|
|
|
+ this.$refs[
|
|
|
+ (this.type == 'person' ? item.item?.userId : item.item?.teamId) + index
|
|
|
+ ]
|
|
|
+ );
|
|
|
+ const rect =
|
|
|
+ this.$refs[
|
|
|
+ (this.type == 'person' ? item.item?.userId : item.item?.teamId) + index
|
|
|
+ ].getBoundingClientRect();
|
|
|
+ console.log(rect);
|
|
|
+ return (
|
|
|
+ rect.left < this.endX &&
|
|
|
+ rect.right > this.startX &&
|
|
|
+ rect.top < this.endY &&
|
|
|
+ rect.bottom > this.startY
|
|
|
+ );
|
|
|
+ });
|
|
|
+ },
|
|
|
// 人员班次数据切换
|
|
|
- setTableData () {
|
|
|
+ setTableData() {
|
|
|
switch (this.type) {
|
|
|
case 'person':
|
|
|
this.tableData = this.personData;
|
|
|
@@ -127,7 +194,7 @@
|
|
|
}
|
|
|
},
|
|
|
// 初始化columns
|
|
|
- initColumns () {
|
|
|
+ initColumns() {
|
|
|
let Month = dayjs(this.time).month() + 1;
|
|
|
let MonthNum = dayjs(this.time).daysInMonth();
|
|
|
let columns = [];
|
|
|
@@ -156,33 +223,36 @@
|
|
|
this.columns = [].concat(this.columns, columns);
|
|
|
},
|
|
|
// 设置数据
|
|
|
- setData (personData, teamData) {
|
|
|
+ setData(personData, teamData) {
|
|
|
this.personData = personData;
|
|
|
this.teamData = teamData;
|
|
|
this.setTableData();
|
|
|
},
|
|
|
- showName (row, column) {
|
|
|
+ showName(row, column) {
|
|
|
+
|
|
|
let list = row[column.property];
|
|
|
if (list) {
|
|
|
list.forEach((n) => {
|
|
|
n.name = n.name.slice(0, 4);
|
|
|
+ n['userId'] = row.item?.userId;
|
|
|
+ n['teamId'] = row.item?.teamId;
|
|
|
});
|
|
|
return list;
|
|
|
} else {
|
|
|
return [];
|
|
|
}
|
|
|
},
|
|
|
- showheaderName (label) {
|
|
|
+ showheaderName(label) {
|
|
|
let list = label.split('/');
|
|
|
let week = this.dict.week[list[1]];
|
|
|
return `${list[0]}</br>${week}`;
|
|
|
},
|
|
|
// 设置颜色
|
|
|
- showColor (item) {
|
|
|
+ showColor(item) {
|
|
|
return this.classesColor[item.id];
|
|
|
},
|
|
|
// 单元格点击
|
|
|
- cellClick (row, column) {
|
|
|
+ cellClick(row, column) {
|
|
|
const selectedClasses = JSON.parse(
|
|
|
JSON.stringify(this.selectedClasses)
|
|
|
);
|
|
|
@@ -199,7 +269,7 @@
|
|
|
}
|
|
|
},
|
|
|
// 行点击
|
|
|
- rowClick (row, column) {
|
|
|
+ rowClick(row, column) {
|
|
|
const selectedClasses = JSON.parse(
|
|
|
JSON.stringify(this.selectedClasses)
|
|
|
);
|
|
|
@@ -224,7 +294,7 @@
|
|
|
}
|
|
|
},
|
|
|
// 列点击
|
|
|
- headerClick (column) {
|
|
|
+ headerClick(column) {
|
|
|
const selectedClasses = JSON.parse(
|
|
|
JSON.stringify(this.selectedClasses)
|
|
|
);
|
|
|
@@ -245,7 +315,7 @@
|
|
|
}
|
|
|
},
|
|
|
// 按班排同步人员-单元格点击
|
|
|
- SyncCellClick (row, column) {
|
|
|
+ SyncCellClick(row, column) {
|
|
|
const selectedClasses = JSON.parse(
|
|
|
JSON.stringify(this.selectedClasses)
|
|
|
);
|
|
|
@@ -261,7 +331,7 @@
|
|
|
}
|
|
|
},
|
|
|
// 按班排同步人员-行点击
|
|
|
- SyncRowClick (row, column) {
|
|
|
+ SyncRowClick(row, column) {
|
|
|
const selectedClasses = JSON.parse(
|
|
|
JSON.stringify(this.selectedClasses)
|
|
|
);
|
|
|
@@ -285,7 +355,7 @@
|
|
|
}
|
|
|
},
|
|
|
// 按班排同步人员-列点击
|
|
|
- SyncHeaderClick (column) {
|
|
|
+ SyncHeaderClick(column) {
|
|
|
const selectedClasses = JSON.parse(
|
|
|
JSON.stringify(this.selectedClasses)
|
|
|
);
|
|
|
@@ -300,43 +370,43 @@
|
|
|
}
|
|
|
},
|
|
|
// 根据班组id查询人员
|
|
|
- getid_Person (id) {
|
|
|
+ getid_Person(id) {
|
|
|
let list = this.personData.filter((n) => {
|
|
|
return n.item.teamId == id;
|
|
|
});
|
|
|
return list;
|
|
|
},
|
|
|
// 保存
|
|
|
- save () {
|
|
|
+ save() {
|
|
|
this.$emit('save');
|
|
|
},
|
|
|
// 重置
|
|
|
- rest () {
|
|
|
+ rest() {
|
|
|
this.$emit('rest');
|
|
|
},
|
|
|
// 按人/班排
|
|
|
- anbp () {
|
|
|
+ anbp() {
|
|
|
this.type = this.type == 'person' ? 'team' : 'person';
|
|
|
this.initColumns();
|
|
|
this.setTableData();
|
|
|
},
|
|
|
// 切换按班排班
|
|
|
- changanbp () {
|
|
|
+ changanbp() {
|
|
|
this.type = 'team';
|
|
|
this.initColumns();
|
|
|
this.setTableData();
|
|
|
},
|
|
|
// 选择时间
|
|
|
- timeChange () {
|
|
|
+ timeChange() {
|
|
|
this.initColumns();
|
|
|
},
|
|
|
// 补零
|
|
|
- setNUm (num) {
|
|
|
+ setNUm(num) {
|
|
|
let length = 2;
|
|
|
return (num / Math.pow(10, length)).toFixed(length).substr(2);
|
|
|
},
|
|
|
// 搜索
|
|
|
- search (val) {
|
|
|
+ search(val) {
|
|
|
switch (this.type) {
|
|
|
case 'person':
|
|
|
if (val !== '') {
|
|
|
@@ -395,4 +465,12 @@
|
|
|
text-align: right;
|
|
|
padding-right: 20px;
|
|
|
}
|
|
|
+ :deep(.el-button--medium) {
|
|
|
+ padding: 10px 20px !important;
|
|
|
+ }
|
|
|
+ .selection-box {
|
|
|
+ position: absolute;
|
|
|
+ border: 2px dashed black;
|
|
|
+ pointer-events: none; /* 确保选择框不会干扰鼠标事件 */
|
|
|
+ }
|
|
|
</style>
|