package com.ruoyi.staff.task;
|
|
import cn.hutool.core.collection.CollectionUtil;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.ruoyi.staff.dto.PerformanceShiftAddDto;
|
import com.ruoyi.staff.mapper.PersonalAttendanceLocationConfigMapper;
|
import com.ruoyi.staff.mapper.PersonalShiftMapper;
|
import com.ruoyi.staff.mapper.StaffOnJobMapper;
|
import com.ruoyi.staff.pojo.PersonalAttendanceLocationConfig;
|
import com.ruoyi.staff.pojo.PersonalAttendanceRecords;
|
import com.ruoyi.staff.pojo.StaffOnJob;
|
import com.ruoyi.staff.service.PersonalAttendanceRecordsService;
|
import com.ruoyi.staff.mapper.PersonalAttendanceRecordsMapper;
|
import com.ruoyi.staff.service.PersonalShiftService;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.scheduling.annotation.Scheduled;
|
import org.springframework.stereotype.Component;
|
|
import java.math.BigDecimal;
|
import java.time.LocalDate;
|
import java.time.LocalDateTime;
|
import java.time.LocalTime;
|
import java.time.ZoneId;
|
import java.time.temporal.TemporalAdjusters;
|
import java.time.temporal.WeekFields;
|
import java.util.List;
|
import java.util.Locale;
|
import java.util.Map;
|
import java.util.stream.Collectors;
|
|
/**
|
* 个人考勤记录定时任务
|
*
|
* @author 芯导软件(江苏)有限公司
|
* @since 2026-02-09
|
*/
|
@Slf4j
|
@Component
|
public class PersonalAttendanceRecordsTask {
|
|
@Autowired
|
private PersonalAttendanceRecordsMapper personalAttendanceRecordsMapper;
|
|
@Autowired
|
private PersonalAttendanceRecordsService personalAttendanceRecordsService;
|
|
@Autowired
|
private PersonalAttendanceLocationConfigMapper personalAttendanceLocationConfigMapper;
|
|
@Autowired
|
private StaffOnJobMapper staffOnJobMapper;
|
|
@Autowired
|
private PersonalShiftService personalShiftService;
|
|
/**
|
* 每天凌晨生成昨日的缺勤记录
|
* 定时任务:每天凌晨1点执行
|
* 排除今天刚入职的员工
|
*/
|
@Scheduled(cron = "0 0 1 * * ?")
|
public void generateAbsenceRecords() {
|
try {
|
// 获取昨日日期
|
LocalDate yesterday = LocalDate.now().minusDays(1);
|
|
// 直接查询昨天没有考勤记录的在职员工(排除今天刚入职的)
|
LocalDateTime todayStart = LocalDate.now().atStartOfDay();
|
List<StaffOnJob> staffWithoutAttendance = personalAttendanceRecordsMapper.selectStaffWithoutAttendanceRecordBeforeTime(yesterday, todayStart);
|
|
// 遍历没有考勤记录的员工,生成缺勤记录
|
for (StaffOnJob staff : staffWithoutAttendance) {
|
try {
|
boolean exists = personalAttendanceRecordsMapper.existsAttendanceRecord(staff.getId(), yesterday);
|
if (exists) {
|
continue;
|
}
|
|
PersonalAttendanceRecords absenceRecord = new PersonalAttendanceRecords();
|
absenceRecord.setStaffOnJobId(staff.getId());
|
absenceRecord.setDate(yesterday);
|
absenceRecord.setStatus(4); // 设置状态为缺勤
|
absenceRecord.setRemark("系统自动生成-缺勤");
|
absenceRecord.setCreateTime(LocalDateTime.now());
|
absenceRecord.setUpdateTime(LocalDateTime.now());
|
absenceRecord.setTenantId(staff.getTenantId());
|
personalAttendanceRecordsService.save(absenceRecord);
|
|
} catch (Exception e) {
|
log.error("为员工{}生成缺勤记录失败:{}", staff.getStaffName(), e.getMessage(), e);
|
}
|
}
|
|
log.info("昨日缺勤记录生成完成");
|
} catch (Exception e) {
|
log.error("生成昨日缺勤记录任务执行失败:{}", e.getMessage(), e);
|
}
|
}
|
|
/**
|
* 定时任务,每个月1号的00:00:00给下一个月排班
|
* 给每个人都进行排班(默认早班)
|
*/
|
@Scheduled(cron = "0 10 0 1 * ?")
|
private void timerCreateSchedule() {
|
log.info("开始给每个人进行排班,默认早班======start");
|
PerformanceShiftAddDto performanceShiftAddDto = new PerformanceShiftAddDto();
|
//查询所有班次(打卡规则)
|
List<PersonalAttendanceLocationConfig> personalAttendanceLocationConfigs = personalAttendanceLocationConfigMapper.selectList(null);
|
if (CollectionUtil.isEmpty(personalAttendanceLocationConfigs)){
|
return;
|
}
|
performanceShiftAddDto.setPersonalAttendanceLocationConfigId(personalAttendanceLocationConfigs.get(0).getId());
|
//在职人员
|
List<StaffOnJob> staffOnJobs = staffOnJobMapper.selectList(Wrappers.<StaffOnJob>lambdaQuery().eq(StaffOnJob::getStaffState, 1));
|
if (CollectionUtil.isEmpty(staffOnJobs)){
|
return;
|
}
|
String userIds = staffOnJobs.stream().map(user -> user.getId().toString()).distinct().collect(Collectors.joining(","));
|
performanceShiftAddDto.setStaffOnJobId(userIds);
|
//周次--当月所有
|
// 获取当前日期
|
LocalDate today = LocalDate.now(ZoneId.of(ZoneId.SHORT_IDS.get("CTT"))).plusMonths(1);
|
// 获取本月的第一天和最后一天
|
LocalDate firstDayOfMonth = today.with(TemporalAdjusters.firstDayOfMonth());
|
LocalDate lastDayOfMonth = today.with(TemporalAdjusters.lastDayOfMonth());
|
// 获取周字段信息(根据区域设置)
|
WeekFields weekFields = WeekFields.of(Locale.getDefault());
|
// 获取本月第一天的周一
|
LocalDate startOfWeek = firstDayOfMonth.with(TemporalAdjusters.previousOrSame(weekFields.getFirstDayOfWeek()));
|
// 遍历本月所有天数,找出每周的第一天和最后一天
|
LocalDate endOfWeek;
|
while (startOfWeek.isBefore(firstDayOfMonth.plusMonths(1))) {
|
endOfWeek = startOfWeek.plusDays(6);
|
LocalDateTime startDateTime = LocalDateTime.of(startOfWeek, LocalTime.MIDNIGHT);
|
LocalDateTime endDateTime = LocalDateTime.of(endOfWeek, LocalTime.MIDNIGHT);
|
log.info("Week starts on {} and ends on {}", startDateTime, endDateTime);
|
performanceShiftAddDto.setStartWeek(startDateTime);
|
performanceShiftAddDto.setEndWeek(endDateTime);
|
personalShiftService.performanceShiftAdd(performanceShiftAddDto);
|
startOfWeek = startOfWeek.plusWeeks(1);
|
}
|
log.info("排班结束======end");
|
}
|
}
|