521 lines
12 KiB
Vue
521 lines
12 KiB
Vue
<!--
|
||
* @Author: zwq
|
||
* @Date: 2024-07-01 14:54:06
|
||
* @LastEditors: zwq
|
||
* @LastEditTime: 2024-07-15 14:55:35
|
||
* @Description:
|
||
-->
|
||
<template>
|
||
<div class="groupTeamScheduling">
|
||
<div class="operationArea">
|
||
<el-tabs v-model="planId" @tab-click="setPlan">
|
||
<el-tab-pane
|
||
v-for="item in planArr"
|
||
:key="item.id"
|
||
:label="item.name"
|
||
:name="item.id" />
|
||
</el-tabs>
|
||
<el-form :inline="true" class="demo-form-inline">
|
||
<span class="blue-block"></span>
|
||
<el-form-item label="月份选择">
|
||
<el-date-picker
|
||
v-model="startDay"
|
||
type="month"
|
||
placeholder="选择月"
|
||
size="small"
|
||
:disabled="showSetting"
|
||
@change="selectMonth"
|
||
:clearable="false"
|
||
style="width: 120px"></el-date-picker>
|
||
</el-form-item>
|
||
<el-form-item>
|
||
<span
|
||
class="separateStyle"
|
||
v-if="this.$auth.hasPermi('base:group-team-scheduling:set')"></span>
|
||
</el-form-item>
|
||
<el-form-item>
|
||
<el-button
|
||
type="primary"
|
||
size="small"
|
||
v-if="this.$auth.hasPermi('base:group-team-scheduling:set')"
|
||
:disabled="showSetting || settingBtnDis"
|
||
@click="settingMsg">
|
||
设置
|
||
</el-button>
|
||
</el-form-item>
|
||
<el-form-item>
|
||
<span class="separateStyle" v-show="showSetting"></span>
|
||
</el-form-item>
|
||
<el-form-item>
|
||
<el-button
|
||
type="primary"
|
||
size="small"
|
||
v-show="showSetting"
|
||
@click="confirmSetting">
|
||
确认
|
||
</el-button>
|
||
</el-form-item>
|
||
<el-form-item>
|
||
<el-button
|
||
type="primary"
|
||
size="small"
|
||
plain
|
||
v-show="showSetting"
|
||
@click="cancelSetting">
|
||
取消
|
||
</el-button>
|
||
</el-form-item>
|
||
</el-form>
|
||
</div>
|
||
<!-- 日历区域 -->
|
||
<div class="calenderArea">
|
||
<div style="font-size: 24px; font-weight: 500">
|
||
{{ this.month }} {{ this.year }}
|
||
</div>
|
||
<el-calendar v-model="startDay">
|
||
<!-- 这里使用的是 2.5 slot 语法,对于新项目请使用 2.6 slot 语法-->
|
||
<template slot="dateCell" slot-scope="{ date, data }">
|
||
<div v-if="data.type === 'current-month'">
|
||
<!-- 日期 -->
|
||
<div class="dateStyle">
|
||
{{ Number(data.day.split('-')[2]) }}
|
||
</div>
|
||
<!-- 班次班组 -->
|
||
<!-- class有两个样式,一个是类似class1,还有个是选中红框显示 -->
|
||
<el-row
|
||
:gutter="2"
|
||
:class="
|
||
'class' +
|
||
(index + 1) +
|
||
(chooseTip === item.startDay + item.classesId
|
||
? ' team-active'
|
||
: '')
|
||
"
|
||
v-for="(item, index) in list[Number(data.day.split('-')[2])]"
|
||
:key="index">
|
||
<el-col :span="12">
|
||
<div class="selectDiv">
|
||
<!-- 选择班组图标 -->
|
||
<div
|
||
class="toggle-icon"
|
||
v-show="
|
||
showSetting &&
|
||
(new Date(data.day).valueOf() < new Date().valueOf()
|
||
? false
|
||
: true)
|
||
">
|
||
<svg-icon icon-class="toggle" />
|
||
</div>
|
||
<!-- 不能选择班组 -->
|
||
<div
|
||
class="toggle-icon-hide"
|
||
v-show="
|
||
!(
|
||
showSetting &&
|
||
(new Date(data.day).valueOf() < new Date().valueOf()
|
||
? false
|
||
: true)
|
||
)
|
||
"></div>
|
||
<el-select
|
||
v-model="item.teamId"
|
||
size="small"
|
||
:disabled="
|
||
!showSetting ||
|
||
(new Date(data.day).valueOf() > new Date().valueOf()
|
||
? false
|
||
: true)
|
||
">
|
||
<el-option
|
||
v-for="i in teamList"
|
||
:key="i.id"
|
||
:label="i.name"
|
||
:value="i.id"></el-option>
|
||
</el-select>
|
||
</div>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-button class="labelClass" @click="chooseTeam(item)">
|
||
{{ item.classesName }}
|
||
</el-button>
|
||
</el-col>
|
||
</el-row>
|
||
</div>
|
||
</template>
|
||
</el-calendar>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import {
|
||
getScheduling,
|
||
createOrUpdateList,
|
||
} from '@/api/base/groupTeamScheduling';
|
||
import {
|
||
groupPlanList,
|
||
groupPlanTeamList,
|
||
} from '@/api/base/groupSchedulingPlan';
|
||
import { listEnabled } from '@/api/base/groupTeam';
|
||
import moment from 'moment';
|
||
|
||
export default {
|
||
name: 'GroupTeamScheduling',
|
||
data() {
|
||
return {
|
||
startDay: '', // 查询参数
|
||
year: '', // 2023
|
||
month: '', // 九月
|
||
monthList: [
|
||
'一月',
|
||
'二月',
|
||
'三月',
|
||
'四月',
|
||
'五月',
|
||
'六月',
|
||
'七月',
|
||
'八月',
|
||
'九月',
|
||
'十月',
|
||
'十一月',
|
||
'十二月',
|
||
],
|
||
planId: undefined, //计划id
|
||
list: {},
|
||
planArr: [], //排班计划数组
|
||
teamList: [], // 班组下拉
|
||
showSetting: false, // 设置模式。自动排班,确认,取消按钮显示
|
||
settingBtnDis: false,
|
||
jumpDisabled: true, // 操作按钮控制
|
||
chooseObj: {}, //当前选中的数据,查询按钮用
|
||
chooseTip: '', // 当前选中数据的唯一值,显示红框
|
||
autoScheduling: false, // 只有在当前日期后的月份才生效
|
||
};
|
||
},
|
||
created() {
|
||
this.startDay = new Date();
|
||
groupPlanList().then((res) => {
|
||
this.planArr = res.data || [];
|
||
this.planId = this.planArr[0] ? this.planArr[0].id : undefined;
|
||
if (this.planId) {
|
||
this.getList();
|
||
this.getTeamList();
|
||
}
|
||
});
|
||
// 设置按钮是否置灰
|
||
this.settingBtn();
|
||
this.toggleMonth();
|
||
},
|
||
methods: {
|
||
setPlan() {
|
||
this.getList();
|
||
this.getTeamList();
|
||
},
|
||
// 切换月份
|
||
selectMonth() {
|
||
if (this.startDay) {
|
||
this.settingBtn(); // 设置按钮状态,需在getlist前面
|
||
this.toggleMonth();
|
||
this.getList();
|
||
this.clearChoose();
|
||
if (
|
||
moment(this.startDay).valueOf() > moment().endOf('month').valueOf()
|
||
) {
|
||
this.autoScheduling = true;
|
||
} else {
|
||
this.autoScheduling = false;
|
||
}
|
||
}
|
||
},
|
||
// 获取计划对应班组列表
|
||
getTeamList() {
|
||
groupPlanTeamList(this.planId).then((res) => {
|
||
this.teamList = res.data || [];
|
||
});
|
||
},
|
||
// 获取日历数据
|
||
getList() {
|
||
let year = moment(this.startDay).format('YYYY');
|
||
let month = moment(this.startDay).format('M');
|
||
getScheduling({
|
||
year: year,
|
||
month: month,
|
||
planId: this.planId,
|
||
})
|
||
.then((res) => {
|
||
let obj = res.data || {};
|
||
if (obj) {
|
||
for (let item in obj) {
|
||
for (let i = 0; i < obj[item].length; i++) {
|
||
if (!obj[item][i].teamId) {
|
||
obj[item][i].teamId = '';
|
||
}
|
||
}
|
||
}
|
||
}
|
||
this.list = obj;
|
||
})
|
||
.catch(() => {
|
||
this.list = {};
|
||
this.settingBtnDis = true; // 禁用设置按钮
|
||
});
|
||
},
|
||
// 设置
|
||
settingMsg() {
|
||
this.showSetting = !this.showSetting;
|
||
this.clearChoose();
|
||
},
|
||
// 取消
|
||
cancelSetting() {
|
||
this.showSetting = !this.showSetting;
|
||
this.getList(); // 数据还原
|
||
},
|
||
// 确认
|
||
confirmSetting() {
|
||
let num = 0;
|
||
// 当月数据的话,今天及今天之前的不传
|
||
if (
|
||
moment(this.startDay).format('YYYY-MM') === moment().format('YYYY-MM')
|
||
) {
|
||
num = Number(moment().format('DD'));
|
||
} else {
|
||
num = 0;
|
||
}
|
||
// 下月数据全部都传
|
||
// 打平数据
|
||
let tempArr = Object.values(this.list);
|
||
let arr = [];
|
||
for (let i = num; i < tempArr.length; i++) {
|
||
for (let j = 0; j < tempArr[i].length; j++) {
|
||
arr.push(tempArr[i][j]);
|
||
}
|
||
}
|
||
createOrUpdateList(arr).then((res) => {
|
||
if (res.code === 0) {
|
||
this.showSetting = !this.showSetting;
|
||
this.$modal.msgSuccess('操作成功');
|
||
this.getList(); // 数据更新
|
||
}
|
||
});
|
||
},
|
||
// 点击班次红框选中当前数据
|
||
chooseTeam(value) {
|
||
// if (this.showSetting) {
|
||
// this.$modal.msgWarning('当前处于设置模式');
|
||
// return false;
|
||
// }
|
||
this.chooseObj = value;
|
||
this.chooseTip = value.startDay + value.classesId; // 匹配当前的样式
|
||
this.jumpDisabled = false; //查询按钮不禁用
|
||
},
|
||
// 设置按钮如果是上个月或者今天是本月最后一天,设置按钮置灰
|
||
settingBtn() {
|
||
let nowMonth = moment().startOf('month').valueOf();
|
||
let startMonth = moment(this.startDay).valueOf();
|
||
let nowDate = moment(new Date()).date();
|
||
let sumDate = moment().daysInMonth();
|
||
if (nowMonth > startMonth) {
|
||
// 之前月
|
||
this.settingBtnDis = true;
|
||
} else {
|
||
if (nowDate < sumDate) {
|
||
this.settingBtnDis = false;
|
||
} else {
|
||
this.settingBtnDis = true;
|
||
}
|
||
}
|
||
},
|
||
// 清除红框选中数据
|
||
clearChoose() {
|
||
this.chooseObj = {};
|
||
this.chooseTip = '';
|
||
this.jumpDisabled = true;
|
||
},
|
||
// 切换月份显示
|
||
toggleMonth() {
|
||
this.year = moment(this.startDay).format('YYYY');
|
||
let month = Number(moment(this.startDay).format('MM'));
|
||
this.month = this.monthList[month - 1];
|
||
},
|
||
},
|
||
};
|
||
</script>
|
||
<style lang="scss">
|
||
.demo-form-inline {
|
||
.el-date-editor .el-range__icon {
|
||
font-size: 16px;
|
||
color: #0b58ff;
|
||
}
|
||
.el-input__prefix .el-icon-date {
|
||
font-size: 16px;
|
||
color: #0b58ff;
|
||
}
|
||
}
|
||
.groupTeamScheduling {
|
||
background-color: #f2f4f9;
|
||
.operationArea {
|
||
padding: 14px 10px 0 16px;
|
||
margin-bottom: 8px;
|
||
background-color: #fff;
|
||
border-radius: 8px;
|
||
.blue-block {
|
||
display: inline-block;
|
||
width: 4px;
|
||
height: 16px;
|
||
background-color: #0b58ff;
|
||
border-radius: 1px;
|
||
margin-right: 8px;
|
||
margin-top: 10px;
|
||
}
|
||
.separateStyle {
|
||
display: inline-block;
|
||
width: 1px;
|
||
height: 24px;
|
||
background: #e8e8e8;
|
||
vertical-align: middle;
|
||
}
|
||
.el-form-item {
|
||
margin-bottom: 10px;
|
||
}
|
||
.rightItem {
|
||
float: right;
|
||
}
|
||
}
|
||
// 日历
|
||
.calenderArea {
|
||
padding: 14px 10px 0 20px;
|
||
background-color: #fff;
|
||
border-radius: 8px;
|
||
.el-calendar__body {
|
||
padding: 10px 16px 16px 0;
|
||
}
|
||
.el-calendar__header {
|
||
display: none;
|
||
}
|
||
.el-calendar-table > thead {
|
||
height: 48px;
|
||
font-size: 20px;
|
||
font-weight: 500;
|
||
color: #000000;
|
||
background-color: rgba(242, 244, 249, 1);
|
||
}
|
||
.el-calendar-table__row {
|
||
height: 133px;
|
||
.prev,
|
||
.next {
|
||
pointer-events: none;
|
||
}
|
||
.el-calendar-day {
|
||
padding: 0 10px;
|
||
height: 100%;
|
||
.dateStyle {
|
||
font-size: 20px;
|
||
font-weight: 500;
|
||
color: #000000;
|
||
text-align: right;
|
||
height: 32px;
|
||
line-height: 28px;
|
||
padding-right: 10px;
|
||
}
|
||
}
|
||
}
|
||
.team-active {
|
||
// 选中班组
|
||
border: 2px solid #409eff;
|
||
}
|
||
.class1,
|
||
.class2,
|
||
.class3 {
|
||
padding: 0;
|
||
font-weight: 600;
|
||
margin-bottom: 2px;
|
||
.selectDiv {
|
||
position: relative;
|
||
.toggle-icon {
|
||
position: absolute;
|
||
width: 26px;
|
||
height: 26px;
|
||
line-height: 26px;
|
||
font-size: 14px;
|
||
z-index: 1;
|
||
text-align: center;
|
||
}
|
||
.toggle-icon-hide {
|
||
position: absolute;
|
||
width: 2px;
|
||
height: 28px;
|
||
z-index: 1;
|
||
}
|
||
.el-input__suffix {
|
||
display: none;
|
||
}
|
||
.el-input--suffix .el-input__inner {
|
||
padding: 0 4px 0 28px;
|
||
}
|
||
.el-input--small .el-input__inner {
|
||
height: 28px;
|
||
border: none;
|
||
font-weight: 600;
|
||
}
|
||
}
|
||
.labelClass {
|
||
width: 100%;
|
||
height: 28px;
|
||
border: none;
|
||
padding: 0;
|
||
font-weight: 600;
|
||
text-align: center;
|
||
}
|
||
}
|
||
.class1 {
|
||
.selectDiv {
|
||
.toggle-icon,
|
||
.toggle-icon-hide {
|
||
background-color: #face00;
|
||
}
|
||
.el-input--small .el-input__inner {
|
||
color: #e7a200;
|
||
background-color: #ffefc0;
|
||
}
|
||
}
|
||
.labelClass {
|
||
color: #e7a200;
|
||
background-color: #ffefc0;
|
||
}
|
||
}
|
||
.class2 {
|
||
.selectDiv {
|
||
.toggle-icon,
|
||
.toggle-icon-hide {
|
||
background-color: #3984ff;
|
||
}
|
||
.el-input--small .el-input__inner {
|
||
color: #2d7bff;
|
||
background-color: #beeaff;
|
||
}
|
||
}
|
||
.labelClass {
|
||
color: #2d7bff;
|
||
background-color: #beeaff;
|
||
}
|
||
}
|
||
.class3 {
|
||
.selectDiv {
|
||
.toggle-icon,
|
||
.toggle-icon-hide {
|
||
background-color: #37d97f;
|
||
}
|
||
.el-input--small .el-input__inner {
|
||
color: #129f51;
|
||
background-color: #e0ffee;
|
||
}
|
||
}
|
||
.labelClass {
|
||
color: #129f51;
|
||
background-color: #e0ffee;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</style>
|