日历操作——有标记-请假 旷工 申诉
效果
代码
index.vue
结构
<div>
<!-- style="pointer-events:none;" -->
<el-calendar
:model-value='date'
align='left'
class='attendance-details-calendar plr-12'
>
<template #dateCell='{ data }'>
<div class='scheduling-item flex-column' style="position: relative;" :class="[formatterCellColor(data.day)?'red-color':'']">
<!-- v-if="calendarData[data.day.slice(8, 10).replace(/\b(0+)/gi, '') - 1]?.optionFlag == 2" -->
<el-button v-if='isShowBtn(data) && isShowBtns'
:disabled='appealDisable(data.day)' size='mini' type='primary'
@click='onAppeal(data)'
class="w-30 padding-0 height-20"
style="position: absolute;top: 0;line-height: 20px;min-height: 22px"
>申诉
</el-button>
<p class='scheduling-calendar-status fs-18' style="line-height:18px" >
{{ data.day?.split('-')?.slice(2).toString() }}
<!-- {{ data.day?.split('-').slice(2).toString() }} -->
</p>
<div class='scheduling-calendar-status' >
<div v-if="timeMonth === data.day?.split('-')[1]">
<div v-if='getDateInfo(data.day)?.length'>
<!-- <div v-if='getDateInfo(data.day).length'> -->
<div v-for="(p,index) in getDateInfo(data.day)" :key="index">
<p v-html="p" style="margin-top:-4px"></p>
</div>
</div>
<span v-else>-</span>
</div>
<span v-else> - </span>
<!-- <el-button v-if='parentMenu && isShowBtn(data) && isShowBtns'
:disabled='appealDisable(data.day)' size='mini' type='primary'
@click='onAppeal(data)'>申诉
</el-button> -->
<!-- <el-button v-if='parentMenu && setApproval(data.day) && isShowBtns' type='primary' @click='approval(data.day)'>补卡</el-button> -->
<!-- <el-button :disabled="handleEdit(data.day)" v-if='parentMenu && setHandle(data.day) && isShowBtns' type='primary' @click='handle(data.day)' size="mini" style="margin-left:8px;">处理</el-button> -->
</div>
</div>
</template>
</el-calendar>
</div>
逻辑
const state = reactive({
nodeList: [],
calendarData: [],
userInfoData: {},
proInfo: {},
workInfo: {
timeSign: 1
},
StaffAttendAccount: {
currentWorkExtraHours: 0,
workExtraHours: 0
},
detailsShow: false,
appealDialogShow: false,
handleDialogShow: false,
procsslsShow: false,
time: null,
timeMonth: '',
date: null as any,
timeDisabled: [],
timeHandles: []
});
const methods = {
//旷工显示
isShowBtn: day => {
return (state.calendarData || []).find((e)=>{
return e.time === day.day && e.resultStatus === 617
// return e.time === day.day && e.eidtStateList?.some(e=>e.optionFlag ==2)
})
},
appealDisable: day => {
return !!(state.calendarData || []).find((e)=>{
return e.time == day && e.eidtStateList?.every(o=>( o.edit == 2) && e.eidtStateList?.some(o=>o.optionFlag ==2 ) )
})
},
formatterCellColor: (day) => {
return !!(state.calendarData || []).find(e =>e.time == day && e.red )
},
//
getCalendarData: obj => {
state.calendarData = [];
getAttendDayList.getAttendDayList(obj).then(res => {
state.calendarData = res.data;
if (res.code == 200) {
if (res.data) {
state.calendarData = res.data || [];
state.timeMonth = state.calendarData[0]?.time?.split('-')?.[1] || '';
}
}else {
mrginTop.value = 120
error.value.code = res.code
error.value.message = res.message || '已超过查看期限,请联系人资人员'
}
});
},
// 获取考勤用户信息
getCalendarUserInfo: obj => {
getAttendDayList.getStaffAttendScheduleDto(obj).then(res => {
state.userInfoData = res.data;
let {sickLeaveDays, ...oneUserInfoDataTitle} = userInfoDataTitle[0];
state.oneUserInfoDataTitle=oneUserInfoDataTitle;
let {compensatoryDays, ...twoUserInfoDataTitle} = userInfoDataTitle[1];
state.twoUserInfoDataTitle=twoUserInfoDataTitle;
let {yearDays, ...threeUserInfoDataTitle} = userInfoDataTitle[2];
state.threeUserInfoDataTitle=threeUserInfoDataTitle;
});
},
// 切换时间
changeDate: val => {
state.time = formatDateMonth(val);
state.date = val;
const obj = {
time: formatDateMonth(val),
staffNo: route.query.staffNo
? route.query.staffNo
: localStorage.getItem('userDepartId')
};
methods.getCalendarData(obj);
methods.getCalendarUserInfo(obj);
},
setApiData: () => {
return {
postName: kgProcessInfo.postName,
postId: kgProcessInfo.postId,
departId: kgProcessInfo.departId,
staffNo: kgProcessInfo.staffNo,
staffName: kgProcessInfo.staffName,
processItemId: kgProcessInfo.processItemId
};
},
judgeProcess: (code, show) => {
api.getCode(code).then(res => {
if (res.code === 200 && res.data && res.data.id) {
const processItemId = res.data.id;
api.enableProcessItemId(processItemId).then((res) => {
if (res.code === 200 && res.data) {
state[show] = true;
api.findProcessInfoList({}).then((res) => {
if (res.code === 200) {
kgProcessInfo = res.data;
kgProcessInfo.processItemId = processItemId;
}
});
} else {
ElMessage.error('请先配置审批流程!');
}
});
} else {
ElMessage.error('请先配置审批流程!');
}
});
},
// 迟到早退 处理
handle: data => {
state.handleTime = data;
let code = '100007';
methods.judgeProcess(code, 'handleDialogShow');
const date = (state.calendarData || []).filter(val => {
return val.time == data;
});
if (date.length) {
let eidtStateList = date[0].eidtStateList;
state.timeDisabled = eidtStateList?.map(e => {
return e.edit;
});
state.timeHandles = eidtStateList?.map(e => {
return e.optionFlag;
});
} else {
state.timeDisabled = [];
}
},
// 补卡
approval: async date => {
const processInfo = await getAttendDayList.processInfo({
code: '100004'
});
if (processInfo.code === 200) {
if (!processInfo.data.id) {
return Message.warning('暂无流程');
}
}
state.procsslsShow = true;
// const procsslsShow
const processList = await getAttendDayList.findProcessInfoList({
processId: processInfo.data.processId,
staffNo: route.query.staffNo
? route.query.staffNo
: localStorage.getItem('userDepartId')
});
if (processList.code === 200) {
state.proInfo = Object.assign(
{},
{
processNodeDTOList: processList.data,
applyTime: formatDateTime(new Date(date)),
processId: processInfo.data.processId,
processName: processInfo.data.name
}
);
}
},
// 旷工
onAppeal: (data) => {
state.complainTime = data.day;
const dateObj = (state.calendarData || []).filter(val => {
return val.time == data.day;
});
state.eidtStateList = dateObj.length? dateObj[0].eidtStateList:{};
let code = '150001';
methods.judgeProcess(code, 'appealDialogShow');
},
cancel: () => {
state.appealDialogShow = false;
},
cancelHandle: () => {
state.handleDialogShow = false;
},
// 异常处理
submitHnadle: param => {
getAttendDayList.attendApprovalInsert({ ...param, ...methods.setApiData() }).then((res) => {
if (res.code === 200) {
state.handleDialogShow = false;
Message.success('异常处理成功');
init();
}
});
},
// --申诉-
submit: param => {
getAttendDayList
.saveAbsentApplay({ ...param, ...methods.setApiData() })
.then(res => {
if (res.code === 200) {
state.appealDialogShow = false;
Message.success('申诉成功');
init(1);
}
});
},
subProcess: i => {
state.procsslsShow = false;
if (i) {
Message.success('补卡成功');
const Last_month = `${new Date().getFullYear()}-${
new Date().getMonth() == 0 ? 12 : new Date().getMonth()
}`;
const obj = {
time: route.query.time ? route.query.time : Last_month,
staffNo: route.query.staffNo
? route.query.staffNo
: localStorage.getItem('userDepartId')
};
methods.getCalendarData(obj);
init();
} else {
Message('取消补卡');
}
},
subProcessAttend: i => {
state.detailsShow = false;
if (i) {
Message.success('兑换成功');
getStaffAttendAccountDto();
}
},
// 调休兑换
workdh: async () => {
if (!state.StaffAttendAccount.workExtraHours) {
return Message.warning('最小调休时长为1小时');
}
const processInfo = null;
api.getCode('130007').then(res => {
if (res.code === 200 && res.data && res.data.id) {
const processItemId = res.data.id;
api.enableProcessItemId(processItemId).then((res) => {
if (res.code === 200 && res.data) {
state.detailsShow = true;
api.findProcessInfoList({}).then((res) => {
state.workInfo = Object.assign({ timeSign: 1 },
{
processItemId: processItemId,
staffNo: res.data.staffNo,
processName: res.data.name,
exchangeType: 1,
exchangeDuration: '',
startTime: '',
workExtraHours: state.StaffAttendAccount.workExtraHours
}
);
});
} else {
ElMessage.error('请先配置审批流程!');
}
});
} else {
ElMessage.error('请先配置审批流程!');
}
});
},
getDateInfo: info => {
const date = (state.calendarData || []).filter(val => {
return val.time == info;
});
if (date.length){
// let desList = date[0].desc.split(';');
let desList = date[0].descInnerList?.map(ele => {
return `<span style="color: ${ele.color};">${ele.name}</span>`
});
return desList;
}else {
return []
}
},
getUserInfo:()=>{
UserAPI.getCurrentDetails({}).then(res => {
if (res.code === 200) {
state.postAttrCode = res.data.postAttrCode;
}
});
},
样式
.attendance-details-calendar:deep(.el-calendar__header) {
display: none;
}
.attendance-details-calendar:deep(.el-calendar-day) {
text-align: left;
min-height: 49px !important;
}
.attendance-details-item {
width: 100%;
height: 100%;
}
.attendance-details-calendar-status {
text-align: center;
}
.rest-btn {
float: right;
}
.btn-group {
text-align: center;
margin-top: 20px;
}
.has-seized {
background: #faad14;
border-color: #faad14;
&:hover {
background: #faad14;
border-color: #faad14;
}
}
.description {
color: #1890ff;
border: 1px solid #1890ff;
background-color: #e8f4ff;
border-radius: 5px;
font-size: 10px;
margin-top: 5px;
span {
display: inline-block;
padding-left: 8px;
border-left: 3px solid #1890ff;
}
}
.flex-column {
justify-content: center;
height: 100%;
}
.scheduling-calendar-status {
text-align: center;
transform: scale(0.83);
}
.zc {
color: #1890ff;
}
.kg {
color: #f5222d;
}
.xx {
color: #13c2c2;
}
.sj {
color: #13c2c2;
}
.flex-column > .el-button {
width: 50%;
}
:deep(.el-calendar-table) {
thead {
height: 48px !important;
}
th {
height: 48px !important;
font-weight: bold;
background: #f1f1f1;
padding: 0;
border-right: 1px solid #eaeaea;
border-top: 1px solid #eaeaea;
&:nth-of-type(1) {
border-left: 1px solid #eaeaea;
}
}
}
.count {
padding: 18px 24px 0;
.num {
font-size: 16px;
color: #52c41a;
line-height: 22px;
}
}
.red-color {
color: red;
}