Files
yudao-dev/src/views/group/holidaySetting/index.vue
2025-11-05 13:57:58 +08:00

774 lines
19 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!--
* @Author: zwq
* @Date: 2024-07-01 14:54:06
* @LastEditors: zwq
* @LastEditTime: 2025-11-05 13:46:00
* @Description:
-->
<template>
<el-row :gutter="10" style="background-color: #f2f4f9">
<!--部门数据-->
<el-col :span="4">
<div class="head-container">
<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>
</el-col>
<el-col :span="20">
<div class="groupTeamScheduling">
<div class="operationArea">
<el-row>
<el-col :span="6">
<div style="height: 40px; font-size: 16px">
<span style="color: #409eff; font-weight: 600">
{{ showDeptName }}
</span>
节假日设置
<span
:style="{
color: inherited ? '#67c23a' : '#b5b839',
fontSize: '12px',
fontWeight: 600,
}"
v-show="ishasParent">
{{ inherited ? '继承模式' : '自定义模式' }}
</span>
</div>
</el-col>
<el-col :span="18" v-if="!ishasParent">
<div style="float: right">
<el-button
size="small"
type="primary"
style="margin-right: 10px"
v-hasPermi="['base:group-holiday:create']"
@click="addHoliday">
新增节假日
</el-button>
<el-button
size="small"
v-hasPermi="['base:group-holiday-log:query']"
@click="holidayLog">
节假日变更记录
</el-button>
</div>
</el-col>
<el-col :span="18" v-else style="text-align: right">
<el-button
size="small"
type="primary"
:disabled="inherited"
v-hasPermi="['base:group-holiday:create']"
@click="addHoliday">
新增节假日
</el-button>
<el-button
size="small"
type="success"
:disabled="inherited"
v-hasPermi="['base:group-holiday:update']"
@click="reExtends">
恢复继承
</el-button>
<el-button
size="small"
type="warning"
:disabled="!inherited"
v-hasPermi="['base:group-holiday:update']"
@click="disExtends">
解除继承
</el-button>
<el-button
size="small"
:disabled="inherited"
v-hasPermi="['base:group-holiday-log:query']"
@click="holidayLog">
节假日变更记录
</el-button>
</el-col>
</el-row>
</div>
<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>
</el-form-item>
<el-form-item label="继承上一级的节假日" v-show="ishasParent">
<div
style="
width: 36px;
height: 36px;
background-color: #67c23a;
border-radius: 3px;
"></div>
</el-form-item>
<el-form-item label="本级自定义的节假日" v-show="ishasParent">
<div
style="
width: 36px;
height: 36px;
background-color: #b5b839;
border-radius: 3px;
"></div>
</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>
<el-tag
v-if="!ishasParent"
type="warning"
style="margin-bottom: 10px; color: black">
<i class="el-icon-warning" style="color: #ffbd02"></i>
当前节假日设置为组织架构中最高层级配置默认自动继承至下属部门子部门可选择
<span style="color: red">解除继承</span>
设置后进行独立修改复制后不再继承上级设置
</el-tag>
<el-tag
v-else
type="warning"
closable
style="margin-bottom: 10px; color: black">
<i class="el-icon-warning" style="color: #ffbd02"></i>
当前部门继承上级节假日设置默认不可修改可通过
<span style="color: red">解除继承</span>
进行自定义解除后将不再继承
</el-tag>
</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"
@click="
new Date(data.day).getTime() > Date.now() &&
HolidayList[Number(data.day.split('-')[2]) - 1]
?.isHoliday &&
showDetail(
HolidayList[Number(data.day.split('-')[2]) - 1]
)
">
<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>
</el-col>
<!-- 显示假期名和操作 -->
<el-col
:span="24"
v-if="
HolidayList[Number(data.day.split('-')[2]) - 1]
?.isHoliday
">
<div
class="holiday-div"
:style="{
backgroundColor: ishasParent
? HolidayList[Number(data.day.split('-')[2]) - 1]
.isInherit
? '#67c23a'
: '#b5b839'
: '',
}">
{{
HolidayList[Number(data.day.split('-')[2]) - 1]
?.holidayName
}}
<span
class="holiday-div-btn"
v-if="new Date(data.day).getTime() > Date.now()">
<i class="el-icon-more" style="color: #fff"></i>
</span>
</div>
</el-col>
</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="addOrUpdateVisible"
@cancel="cancel"
@confirm="handleConfirm"
:before-close="cancel"
:destroy-on-close="true"
class="addDialog"
width="40%">
<add-or-updata
ref="addOrUpdataRef"
@refreshPage="successSubmit"></add-or-updata>
<template #footer>
<slot name="footer">
<el-row slot="footer" type="flex" justify="end">
<el-col :span="24">
<el-button
v-if="!detail"
size="small"
class="btnTextStyle"
@click="cancel">
取消
</el-button>
<el-button
v-if="!detail"
type="primary"
class="btnTextStyle"
size="small"
@click="handleConfirm">
确定
</el-button>
<el-button
v-if="detail"
size="small"
type="primary"
class="btnTextStyle"
v-hasPermi="['base:group-holiday:update']"
@click="editHoliday">
修改
</el-button>
<el-button
v-if="detail"
class="btnTextStyle"
size="small"
v-hasPermi="['base:group-holiday:delete']"
@click="deleteHoliday">
删除
</el-button>
</el-col>
</el-row>
</slot>
</template>
</base-dialog>
<base-dialog
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 {
deptHolidayList,
getEnableData,
disExtends,
reExtends,
updateSchedule,
getSet,
} from '@/api/group/holidaySetting';
import addOrUpdata from './add-or-updata.vue';
import holidayLog from './holidayLog';
export default {
name: '',
components: {
addOrUpdata,
holidayLog,
},
data() {
return {
startDay: '', // 查询参数
HolidayList: [],
// 部门树选项
deptOptions: undefined,
// 查询的部门名称
deptName: undefined,
// 选择的部门名称
showDeptName: undefined,
topDeptId: undefined, // 保存当前用户的部门id为最高级部门id
parentId: undefined, // 保存部门点击时对象的父id用于解除和恢复继承
deptId: undefined,
ishasParent: false, // 判断是否有上级,false,则表示为最高级
defaultProps: {
children: 'children',
label: 'name',
},
dialogTitle: undefined,
addOrUpdateVisible: false,
detail: false,
logVisible: false,
inherited: true, //该部门是否为继承状态
};
},
watch: {
// 根据名称筛选部门树
deptName(val) {
this.$refs.tree.filter(val);
},
},
created() {
this.startDay = new Date();
// 查询用户个人信息
getUserProfile().then((response) => {
this.showDeptName = response.data.dept.name || '';
this.topDeptId = response.data.dept.id || ''; // 保存当前用户的部门id为最高级部门id
this.deptId = response.data.dept.id || '';
this.getTreeselect();
this.getSet();
});
},
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 = [];
deptHolidayList({
deptId: this.deptId,
startTime: Date.parse(startTime),
endTime: Date.parse(endTime),
}).then((res) => {
this.HolidayList = res.data;
});
},
// 切换月份
selectMonth() {
this.getHolidayPage();
},
/** 查询部门下拉树结构 */
getTreeselect() {
getEnableData().then((response) => {
// 遍历部门,判断当前帐号的部门是否有为最上级
const nowDept = response.data.filter((i) => i.id == this.topDeptId);
this.ishasParent = nowDept.hasParent;
this.parentId = nowDept.parentId;
// 处理 deptOptions 参数
this.deptOptions = [];
this.deptOptions.push(...this.handleTree(response.data, 'id'));
});
},
// 根据部门id查询该部门是否是继承
getSet() {
getSet({ id: this.deptId }).then((res) => {
this.inherited = res.data;
});
this.getHolidayPage();
},
// 筛选节点
filterNode(value, data) {
if (!value) return true;
return data.name.indexOf(value) !== -1;
},
// 节点单击事件
handleNodeClick(data) {
this.deptId = data.id;
this.showDeptName = data.name;
this.ishasParent = data.hasParent;
this.parentId = data.parentId;
this.getSet();
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 '';
}
},
addHoliday() {
this.addOrUpdateVisible = true;
this.detail = false;
this.dialogTitle = '新增节假日';
this.$nextTick(() => {
this.$refs.addOrUpdataRef.init(this.deptId, {
inherited: this.inherited,
});
});
},
disExtends() {
this.$confirm(
'当前节假日设置继承自上级部门,解除继承后将不再自动同步上级设置。<br/>系统将保留当前节假日配置作为初始数据,您可以自定义修改。<br/>是否确认解除继承?',
'解除继承',
{
dangerouslyUseHTMLString: true,
confirmButtonText: '确认解除',
cancelButtonText: '取消',
type: 'warning',
}
)
.then(() => {
disExtends({ id: this.deptId, pid: this.parentId }).then((res) => {
if (!res.data.updateFlag) {
this.$modal.msgSuccess('操作成功');
this.getSet();
} else {
this.$confirm(
'新增节假日影响已有排班计划,是否立即更新?',
'更新排班',
{
confirmButtonText: '立即更新',
cancelButtonText: '暂不更新',
type: 'warning',
}
)
.then(() => {
updateSchedule({ logId: res.data.logId }).then((res1) => {
this.$modal.msgSuccess('更新成功');
this.getSet();
});
})
.catch(() => {
this.$message({
type: 'info',
message: '已取消',
});
});
}
});
})
.catch((res) => {
console.log(res);
this.$message({
type: 'info',
message: '已取消',
});
});
},
reExtends() {
this.$confirm(
'恢复继承后,当前部门将重新同步未来时间的上级部门的节假日设置,<br/>现有自定义配置将被清空并替换为上级设置,不可恢复。<br/>是否确认继续?',
'恢复继承',
{
dangerouslyUseHTMLString: true,
confirmButtonText: '确认恢复继承',
cancelButtonText: '取消',
type: 'warning',
}
)
.then(() => {
reExtends({ id: this.deptId, pid: this.parentId }).then((res) => {
if (!res.data.updateFlag) {
this.$modal.msgSuccess('操作成功');
this.getSet();
} else {
this.$confirm(
'新增节假日影响已有排班计划,是否立即更新?',
'更新排班',
{
confirmButtonText: '立即更新',
cancelButtonText: '暂不更新',
type: 'warning',
}
)
.then(() => {
updateSchedule({ logId: res.data.logId }).then((res1) => {
this.$modal.msgSuccess('更新成功');
this.getSet();
});
})
.catch(() => {
this.$message({
type: 'info',
message: '已取消',
});
});
}
});
})
.catch(() => {
this.$message({
type: 'info',
message: '已取消',
});
});
},
holidayLog() {
this.logVisible = true;
this.$nextTick(() => {
this.$refs.holidayLogRef.getDataList();
});
},
cancel() {
this.getHolidayPage();
this.addOrUpdateVisible = false;
},
successSubmit() {
this.cancel();
this.getHolidayPage();
},
handleConfirm() {
this.$refs.addOrUpdataRef.dataFormSubmit();
},
showDetail(val) {
this.addOrUpdateVisible = true;
this.detail = true;
this.dialogTitle = '节假日详情';
this.$nextTick(() => {
this.$refs.addOrUpdataRef.init(this.deptId, val, true);
});
},
editHoliday() {
this.detail = false;
this.$nextTick(() => {
this.$refs.addOrUpdataRef.editHoliday();
});
},
deleteHoliday() {
this.$nextTick(() => {
this.$refs.addOrUpdataRef.deleteHoliday();
});
},
cancelLog() {
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;
.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;
}
.holiday-div {
background-color: #67c23a;
border-radius: 3px;
height: 25px;
text-align: center;
line-height: 24px;
color: #fff;
.holiday-div-btn {
float: right;
transform: rotate(90deg);
font-size: 14px;
pointer-events: none;
}
}
}
}
}
}
}
.addDialog {
.el-dialog__body {
overflow: visible;
}
}
</style>