更新班组
This commit is contained in:
567
src/views/group/Calendar/index.vue
Normal file
567
src/views/group/Calendar/index.vue
Normal file
@@ -0,0 +1,567 @@
|
||||
<!--
|
||||
* @Author: zwq
|
||||
* @Date: 2025-10-23 13:43:55
|
||||
* @LastEditors: zwq
|
||||
* @LastEditTime: 2025-10-24 11:14:55
|
||||
* @Description:
|
||||
-->
|
||||
<template>
|
||||
<el-row :gutter="10" style="background-color: #f2f4f9">
|
||||
<!--部门数据-->
|
||||
<el-col :span="4">
|
||||
<div class="head-container">
|
||||
<el-tabs v-model="activeName" stretch @tab-click="tabsClick">
|
||||
<el-tab-pane label="部门" name="first"></el-tab-pane>
|
||||
<el-tab-pane label="班组" name="second"></el-tab-pane>
|
||||
</el-tabs>
|
||||
<div v-if="activeName == 'first'">
|
||||
<el-input
|
||||
v-model="deptName"
|
||||
placeholder="请输入部门名称"
|
||||
clearable
|
||||
size="small"
|
||||
prefix-icon="el-icon-search"
|
||||
style="margin-bottom: 20px" />
|
||||
<el-tree
|
||||
:data="deptOptions"
|
||||
:props="defaultProps"
|
||||
:expand-on-click-node="false"
|
||||
:filter-node-method="filterNode"
|
||||
ref="tree"
|
||||
default-expand-all
|
||||
highlight-current
|
||||
@node-click="handleNodeClick" />
|
||||
</div>
|
||||
<div v-else>
|
||||
<el-input
|
||||
v-model="groupName"
|
||||
placeholder="请输入班组名称"
|
||||
clearable
|
||||
size="small"
|
||||
prefix-icon="el-icon-search"
|
||||
style="margin-bottom: 20px" />
|
||||
<el-tree
|
||||
:data="groupOptions"
|
||||
:props="defaultProps"
|
||||
:expand-on-click-node="false"
|
||||
:filter-node-method="filterNode"
|
||||
ref="tree1"
|
||||
default-expand-all
|
||||
highlight-current
|
||||
@node-click="handleNodeClick1" />
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="20">
|
||||
<div class="groupTeamScheduling">
|
||||
<div class="operationArea">
|
||||
<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"
|
||||
@change="selectMonth"
|
||||
:clearable="false"
|
||||
style="width: 120px"></el-date-picker>
|
||||
<span
|
||||
style="color: #909399; font-size: 12px"
|
||||
v-if="activeName == 'first'">
|
||||
提示:排班日历仅展示当前选中部门的节假日设置,若休假日中仍有排班,则表示下级组织已通过自定义假期进行排班。
|
||||
</span>
|
||||
<span v-else>
|
||||
组长:{{ showTeamName?.leaderName || '-' }} 组长电话:{{
|
||||
showTeamName?.leaderPhone || '-'
|
||||
}}
|
||||
</span>
|
||||
</el-form-item>
|
||||
<el-form-item style="float: right">
|
||||
<el-button
|
||||
size="small"
|
||||
type="primary"
|
||||
@click="(startDay = new Date()), getHolidayPage()">
|
||||
跳转到今天
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<!-- 日历区域 -->
|
||||
<div class="calenderArea">
|
||||
<el-calendar v-model="startDay">
|
||||
<template slot="dateCell" slot-scope="{ data }">
|
||||
<div v-if="data.type === 'current-month'">
|
||||
<!-- 日期 -->
|
||||
<div class="dateStyle">
|
||||
<el-row :gutter="20">
|
||||
<!-- 公历和农历 -->
|
||||
<el-col :span="18">
|
||||
{{ Number(data.day.split('-')[2]) }}
|
||||
<div class="lunar-date">{{ getLunarDate(data.day) }}</div>
|
||||
</el-col>
|
||||
<!-- 显示假或班 -->
|
||||
<el-col :span="6">
|
||||
<div
|
||||
class="work-tip"
|
||||
:style="{
|
||||
backgroundColor: HolidayList[
|
||||
Number(data.day.split('-')[2]) - 1
|
||||
]?.isHoliday
|
||||
? '#67C23A'
|
||||
: '#409EFF',
|
||||
}">
|
||||
{{
|
||||
HolidayList[Number(data.day.split('-')[2]) - 1]
|
||||
?.isHoliday
|
||||
? '假'
|
||||
: '班'
|
||||
}}
|
||||
<!-- //变更节假日未更新排班计划的角标 -->
|
||||
<div
|
||||
class="subIcon"
|
||||
v-if="
|
||||
HolidayList[Number(data.day.split('-')[2]) - 1]
|
||||
?.isUpdate
|
||||
">
|
||||
<el-tooltip
|
||||
effect="dark"
|
||||
content="本日节假日变更已影响当前排班计划,但尚未同步,请及时处理。"
|
||||
placement="top">
|
||||
<i
|
||||
class="el-icon-warning"
|
||||
style="color: #f56c6c"></i>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<!-- 显示排班 -->
|
||||
<div
|
||||
v-if="
|
||||
HolidayList[Number(data.day.split('-')[2]) - 1]?.det
|
||||
.length > 0
|
||||
">
|
||||
<el-col
|
||||
:span="24"
|
||||
v-for="(item, index) in HolidayList[
|
||||
Number(data.day.split('-')[2]) - 1
|
||||
]?.det.filter(
|
||||
(item) =>
|
||||
item.schedulingPlanId ==
|
||||
HolidayList[Number(data.day.split('-')[2]) - 1]
|
||||
?.schedulingPlanId
|
||||
)"
|
||||
:key="index">
|
||||
<el-tooltip
|
||||
effect="dark"
|
||||
content="点击展示全部排班计划"
|
||||
placement="top-start">
|
||||
<div
|
||||
class="holiday-div"
|
||||
:style="{
|
||||
backgroundColor:
|
||||
holidayDivColor[item?.classesCode],
|
||||
}"
|
||||
@click="
|
||||
holidayLog(
|
||||
HolidayList[Number(data.day.split('-')[2]) - 1]
|
||||
?.det,
|
||||
HolidayList[Number(data.day.split('-')[2]) - 1]
|
||||
?.date
|
||||
)
|
||||
"
|
||||
:title="
|
||||
item.classesName +
|
||||
' | ' +
|
||||
item.teamName +
|
||||
' | ' +
|
||||
item.workTime
|
||||
">
|
||||
{{
|
||||
item.classesName +
|
||||
' | ' +
|
||||
item.teamName +
|
||||
' | ' +
|
||||
item.workTime
|
||||
}}
|
||||
</div>
|
||||
</el-tooltip>
|
||||
</el-col>
|
||||
</div>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
style="font-size: 20px; font-weight: 500; text-align: left">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="24">
|
||||
{{ Number(data.day.split('-')[2]) }}
|
||||
<span style="font-size: 12px">
|
||||
{{ getLunarDate(data.day) }}
|
||||
</span>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
</el-calendar>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<base-dialog
|
||||
:dialogTitle="dialogTitle"
|
||||
:dialogVisible="logVisible"
|
||||
@cancel="cancelLog"
|
||||
:before-close="cancelLog"
|
||||
:destroy-on-close="true"
|
||||
width="70%">
|
||||
<holiday-log ref="holidayLogRef"></holiday-log>
|
||||
<template #footer>
|
||||
<slot name="footer">
|
||||
<el-row slot="footer" type="flex" justify="end">
|
||||
<el-col :span="24">
|
||||
<el-button size="small" class="btnTextStyle" @click="cancelLog">
|
||||
取消
|
||||
</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</slot>
|
||||
</template>
|
||||
</base-dialog>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import moment from 'moment';
|
||||
import { solarToLunar } from 'chinese-lunar';
|
||||
|
||||
import { getUserProfile } from '@/api/system/user';
|
||||
import { listByDeptId } from '@/api/group/Schedule';
|
||||
import { getEnableData } from '@/api/group/holidaySetting';
|
||||
import {
|
||||
getDeptSchedulingList,
|
||||
getClassSchedulingList,
|
||||
} from '@/api/group/calendar';
|
||||
import holidayLog from './holidayLog';
|
||||
|
||||
export default {
|
||||
name: '',
|
||||
components: {
|
||||
holidayLog,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
activeName: 'first',
|
||||
startDay: '', // 查询参数
|
||||
HolidayList: [],
|
||||
// 选择的部门名称
|
||||
showDeptName: undefined,
|
||||
showTeamName: {},
|
||||
// 部门树选项
|
||||
deptOptions: undefined,
|
||||
groupOptions: undefined,
|
||||
// 查询的部门名称
|
||||
deptName: undefined,
|
||||
groupName: undefined,
|
||||
|
||||
topDept: {}, // 保存当前用户的部门id为最高级部门id
|
||||
deptId: undefined,
|
||||
teamId: undefined,
|
||||
|
||||
defaultProps: {
|
||||
children: 'children',
|
||||
label: 'name',
|
||||
},
|
||||
logVisible: false,
|
||||
dialogTitle: '',
|
||||
holidayDivColor: ['#67c23a', '#69d983', '#f5c931', '#4fa6f0'],
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
// 根据名称筛选部门树
|
||||
deptName(val) {
|
||||
this.$refs.tree.filter(val);
|
||||
},
|
||||
groupName(val) {
|
||||
this.$refs.tree1.filter(val);
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.startDay = new Date();
|
||||
// 查询用户个人信息
|
||||
getUserProfile().then((response) => {
|
||||
this.showDeptName = response.data.dept.name || '';
|
||||
this.topDept = {
|
||||
name: response.data.dept.name || '',
|
||||
id: response.data.dept.id || '',
|
||||
}; // 保存当前用户的部门为最高级部门id
|
||||
this.deptId = response.data.dept.id || '';
|
||||
this.getHolidayPage();
|
||||
this.getTreeselect();
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
getHolidayPage() {
|
||||
const now = new Date(this.startDay);
|
||||
const year = now.getFullYear();
|
||||
const month = now.getMonth();
|
||||
const startTime = `${year}-${String(month + 1).padStart(2, '0')}-01`;
|
||||
const lastDate = new Date(year, month + 1, 0).getDate();
|
||||
const endTime = `${year}-${String(month + 1).padStart(2, '0')}-${String(
|
||||
lastDate
|
||||
).padStart(2, '0')}`;
|
||||
|
||||
this.HolidayList = [];
|
||||
if (this.activeName == 'first') {
|
||||
getDeptSchedulingList({
|
||||
deptId: this.deptId,
|
||||
startTime: Date.parse(startTime),
|
||||
endTime: Date.parse(endTime),
|
||||
}).then((res) => {
|
||||
this.HolidayList = res.data;
|
||||
});
|
||||
} else {
|
||||
getClassSchedulingList({
|
||||
teamId: this.teamId,
|
||||
startTime: Date.parse(startTime),
|
||||
endTime: Date.parse(endTime),
|
||||
}).then((res) => {
|
||||
this.HolidayList = res.data;
|
||||
});
|
||||
}
|
||||
},
|
||||
// 切换月份
|
||||
selectMonth() {
|
||||
this.getHolidayPage();
|
||||
},
|
||||
/** 查询部门下拉树结构 */
|
||||
getTreeselect() {
|
||||
getEnableData().then((response) => {
|
||||
// 处理 deptOptions 参数
|
||||
this.deptOptions = [];
|
||||
this.deptOptions.push(...this.handleTree(response.data, 'id'));
|
||||
});
|
||||
listByDeptId(this.topDept.id).then((response) => {
|
||||
this.groupOptions = [];
|
||||
this.groupOptions.push(...response.data);
|
||||
});
|
||||
},
|
||||
// 筛选节点
|
||||
filterNode(value, data) {
|
||||
if (!value) return true;
|
||||
return data.name.indexOf(value) !== -1;
|
||||
},
|
||||
tabsClick() {
|
||||
if (this.activeName == 'second' && this.groupOptions.length > 0) {
|
||||
this.teamId = this.groupOptions[0].id;
|
||||
this.showTeamName = {
|
||||
leaderName: this.groupOptions[0].leaderName || '-',
|
||||
leaderPhone: this.groupOptions[0].leaderPhone || '-',
|
||||
};
|
||||
} else if (this.activeName == 'first') {
|
||||
this.deptId = this.topDept.id;
|
||||
}
|
||||
this.getHolidayPage();
|
||||
},
|
||||
// 节点单击事件
|
||||
handleNodeClick(data) {
|
||||
this.deptId = data.id;
|
||||
this.showDeptName = data.name;
|
||||
this.getHolidayPage();
|
||||
},
|
||||
handleNodeClick1(data) {
|
||||
this.teamId = data.id;
|
||||
this.showTeamName = {
|
||||
leaderName: data.leaderName || '-',
|
||||
leaderPhone: data.leaderPhone || '-',
|
||||
};
|
||||
this.getHolidayPage();
|
||||
},
|
||||
//获取农历
|
||||
getLunarDate(solarDate) {
|
||||
try {
|
||||
const [year, month, day] = solarDate.split('-').map(Number);
|
||||
|
||||
const date = new Date(year, month - 1, day);
|
||||
const lunar = solarToLunar(date);
|
||||
|
||||
// 将数字月份和日期转换为中文
|
||||
const monthMap = {
|
||||
1: '正',
|
||||
2: '二',
|
||||
3: '三',
|
||||
4: '四',
|
||||
5: '五',
|
||||
6: '六',
|
||||
7: '七',
|
||||
8: '八',
|
||||
9: '九',
|
||||
10: '十',
|
||||
11: '冬',
|
||||
12: '腊',
|
||||
};
|
||||
|
||||
const dayMap = {
|
||||
1: '初一',
|
||||
2: '初二',
|
||||
3: '初三',
|
||||
4: '初四',
|
||||
5: '初五',
|
||||
6: '初六',
|
||||
7: '初七',
|
||||
8: '初八',
|
||||
9: '初九',
|
||||
10: '初十',
|
||||
11: '十一',
|
||||
12: '十二',
|
||||
13: '十三',
|
||||
14: '十四',
|
||||
15: '十五',
|
||||
16: '十六',
|
||||
17: '十七',
|
||||
18: '十八',
|
||||
19: '十九',
|
||||
20: '二十',
|
||||
21: '廿一',
|
||||
22: '廿二',
|
||||
23: '廿三',
|
||||
24: '廿四',
|
||||
25: '廿五',
|
||||
26: '廿六',
|
||||
27: '廿七',
|
||||
28: '廿八',
|
||||
29: '廿九',
|
||||
30: '三十',
|
||||
};
|
||||
|
||||
// 返回 "三月初四" 格式
|
||||
return `${monthMap[lunar.month]}月${dayMap[lunar.day]}`;
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
return '';
|
||||
}
|
||||
},
|
||||
holidayLog(det, date) {
|
||||
this.dialogTitle = this.showDeptName + '-' + date + '-排班详情';
|
||||
this.logVisible = true;
|
||||
this.$nextTick(() => {
|
||||
this.$refs.holidayLogRef.init(det);
|
||||
});
|
||||
},
|
||||
cancelLog() {
|
||||
this.dialogTitle = '';
|
||||
this.logVisible = false;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.head-container {
|
||||
padding: 20px 10px 0;
|
||||
background-color: #fff;
|
||||
min-height: calc(100vh - 120px - 8px);
|
||||
border-radius: 8px;
|
||||
}
|
||||
.groupTeamScheduling {
|
||||
.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;
|
||||
}
|
||||
.el-form-item {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
// 日历
|
||||
.calenderArea {
|
||||
padding: 14px 10px 0 20px;
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
min-height: calc(100vh - 120px - 8px - 168px);
|
||||
.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;
|
||||
}
|
||||
.is-selected,
|
||||
.is-today {
|
||||
background-color: #e4f0fd;
|
||||
}
|
||||
.el-calendar-day {
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
:hover {
|
||||
background-color: #e4f0fd;
|
||||
}
|
||||
.dateStyle {
|
||||
font-size: 20px;
|
||||
font-weight: 500;
|
||||
color: #000000;
|
||||
text-align: left;
|
||||
height: 133px;
|
||||
line-height: 28px;
|
||||
padding: 10px;
|
||||
overflow: hidden;
|
||||
|
||||
.lunar-date {
|
||||
display: inline-block;
|
||||
font-size: 12px;
|
||||
color: #909399;
|
||||
}
|
||||
.work-tip {
|
||||
background: #87c1ff;
|
||||
color: white;
|
||||
font-size: 18px;
|
||||
width: 30px;
|
||||
text-align: center;
|
||||
float: right;
|
||||
position: relative;
|
||||
.subIcon {
|
||||
position: absolute;
|
||||
top: -18px;
|
||||
right: -10px;
|
||||
font-size: 10px;
|
||||
}
|
||||
}
|
||||
.holiday-div {
|
||||
background-color: #67c23a;
|
||||
border-radius: 3px;
|
||||
height: 25px;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
line-height: 24px;
|
||||
color: #fff;
|
||||
margin-bottom: 2px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user