From 955251314452fda78718f5dc4bdac56687a305ca Mon Sep 17 00:00:00 2001 From: fl <3098731433@qq.com> Date: Fri, 9 May 2025 18:03:16 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AF=B7=E5=81=87=E6=9C=88=E5=88=9D=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E5=AE=A1=E6=A0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/SwaggerAutoConfiguration.java | 2 +- .../system/att/dao/AttSourceDataDao.java | 4 +- .../system/att/service/AttCalService.java | 9 + .../system/att/service/AttCalServiceImpl.java | 16 + .../com/bonus/system/att/tasks/AttTasks.java | 1205 ----------------- .../bonus/system/att/tasks/HolidayTasks.java | 43 + .../bonus/system/att/tasks/NewAttTask.java | 10 + .../bonus/system/holiday/dao/HolidayDao.java | 7 + .../holiday/service/HolidayService.java | 1 + .../mapper/att/AttSourceDataMapper.xml | 14 + .../mapper/att/AttendanceDetailsMapper.xml | 2 +- .../mapper/holiday/HolidayMapper.xml | 13 + 12 files changed, 118 insertions(+), 1208 deletions(-) delete mode 100644 bonus-modules/bonus-system/src/main/java/com/bonus/system/att/tasks/AttTasks.java diff --git a/bonus-common/bonus-common-swagger/src/main/java/com/bonus/common/swagger/config/SwaggerAutoConfiguration.java b/bonus-common/bonus-common-swagger/src/main/java/com/bonus/common/swagger/config/SwaggerAutoConfiguration.java index 173ac9f..837b798 100644 --- a/bonus-common/bonus-common-swagger/src/main/java/com/bonus/common/swagger/config/SwaggerAutoConfiguration.java +++ b/bonus-common/bonus-common-swagger/src/main/java/com/bonus/common/swagger/config/SwaggerAutoConfiguration.java @@ -27,7 +27,7 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2; @Configuration @EnableSwagger2 @EnableConfigurationProperties(SwaggerProperties.class) -@ConditionalOnProperty(name = "swagger.enabled", matchIfMissing = true) +@ConditionalOnProperty(name = "swagger.enabled", matchIfMissing = false) @Import({SwaggerBeanPostProcessor.class, SwaggerWebConfiguration.class}) public class SwaggerAutoConfiguration { diff --git a/bonus-modules/bonus-system/src/main/java/com/bonus/system/att/dao/AttSourceDataDao.java b/bonus-modules/bonus-system/src/main/java/com/bonus/system/att/dao/AttSourceDataDao.java index 18cfa7b..c4cddd0 100644 --- a/bonus-modules/bonus-system/src/main/java/com/bonus/system/att/dao/AttSourceDataDao.java +++ b/bonus-modules/bonus-system/src/main/java/com/bonus/system/att/dao/AttSourceDataDao.java @@ -2,6 +2,7 @@ package com.bonus.system.att.dao; import com.bonus.common.datasource.annotation.Slave; import com.bonus.system.att.entity.*; +import com.bonus.system.holiday.entity.HolidayBean; import org.apache.ibatis.annotations.Param; import org.springframework.stereotype.Repository; import java.util.List; @@ -223,7 +224,6 @@ public interface AttSourceDataDao { * 修改月的应考勤天数 * @param userId * @param nowDate - * @param i */ void updateMonthReportRequiredDay(@Param("userId") String userId, @Param("nowDate") String nowDate, @Param("requiredDays") Long requiredDays, @Param("requiredDayRemark") String requiredDayRemark); @@ -233,4 +233,6 @@ public interface AttSourceDataDao { * @return */ List getOrgDataByUserId(String userId); + + List getLeaveDataById(HolidayBean o); } diff --git a/bonus-modules/bonus-system/src/main/java/com/bonus/system/att/service/AttCalService.java b/bonus-modules/bonus-system/src/main/java/com/bonus/system/att/service/AttCalService.java index 588585e..b26c59e 100644 --- a/bonus-modules/bonus-system/src/main/java/com/bonus/system/att/service/AttCalService.java +++ b/bonus-modules/bonus-system/src/main/java/com/bonus/system/att/service/AttCalService.java @@ -3,6 +3,7 @@ package com.bonus.system.att.service; import com.bonus.system.att.entity.AttGroupBean; import com.bonus.system.att.entity.AttMonthReportBean; import com.bonus.system.att.entity.AttSourceDataBean; +import com.bonus.system.holiday.entity.HolidayBean; import java.util.List; @@ -134,4 +135,12 @@ public interface AttCalService { * @return */ int getPersonAttGroup(Long userId); + + /** + * 查询通过的请假记录根据id + * 修改考勤数据 + * @param id + * @return + */ + void rollbackAttDataByLeave(HolidayBean o); } diff --git a/bonus-modules/bonus-system/src/main/java/com/bonus/system/att/service/AttCalServiceImpl.java b/bonus-modules/bonus-system/src/main/java/com/bonus/system/att/service/AttCalServiceImpl.java index f596f4d..e359319 100644 --- a/bonus-modules/bonus-system/src/main/java/com/bonus/system/att/service/AttCalServiceImpl.java +++ b/bonus-modules/bonus-system/src/main/java/com/bonus/system/att/service/AttCalServiceImpl.java @@ -12,6 +12,7 @@ import com.bonus.system.att.entity.*; import com.bonus.system.att.utils.AddressCoordinateFormatUtil; import com.bonus.system.att.utils.AttTimeUtil; import com.bonus.system.att.utils.WorkdayCalculator; +import com.bonus.system.holiday.entity.HolidayBean; import lombok.extern.slf4j.Slf4j; import org.apache.commons.beanutils.BeanUtils; import org.mybatis.spring.SqlSessionTemplate; @@ -480,6 +481,21 @@ public class AttCalServiceImpl implements AttCalService { return attGroupDao.getPersonAttGroup(userId); } + /** + * 查询通过的请假记录根据id + * 修改考勤数据 + * @param o + * @return + */ + @Override + public void rollbackAttDataByLeave(HolidayBean o) { + List list = attSourceDataDao.getLeaveDataById(o); + for (HolidayBean bean : list) { + //先去还原 原始表和明细表数据 + //调用单人数据区间更新 + } + } + /** * 查出每一个考勤组的应出勤天数以及考勤组的规则 * diff --git a/bonus-modules/bonus-system/src/main/java/com/bonus/system/att/tasks/AttTasks.java b/bonus-modules/bonus-system/src/main/java/com/bonus/system/att/tasks/AttTasks.java deleted file mode 100644 index 27b77ea..0000000 --- a/bonus-modules/bonus-system/src/main/java/com/bonus/system/att/tasks/AttTasks.java +++ /dev/null @@ -1,1205 +0,0 @@ -//package com.bonus.system.att.tasks; -// -//import cn.hutool.core.date.DateUnit; -//import cn.hutool.core.date.DateUtil; -//import com.bonus.common.core.utils.DateTimeHelper; -//import com.bonus.common.core.utils.DateUtils; -//import com.bonus.common.core.utils.StringUtils; -//import com.bonus.system.att.dao.AttGroupDao; -//import com.bonus.system.att.dao.AttSourceDataDao; -//import com.bonus.system.att.entity.*; -//import com.bonus.system.att.utils.AddressCoordinateFormatUtil; -//import com.bonus.system.att.utils.WorkdayCalculator; -//import com.bonus.system.holiday.dao.HolidayDao; -//import lombok.extern.slf4j.Slf4j; -//import org.apache.commons.beanutils.BeanUtils; -//import org.mybatis.spring.SqlSessionTemplate; -//import org.springframework.context.annotation.Configuration; -//import org.springframework.scheduling.annotation.Async; -//import org.springframework.scheduling.annotation.EnableAsync; -//import org.springframework.scheduling.annotation.EnableScheduling; -//import org.springframework.scheduling.annotation.Scheduled; -// -//import javax.annotation.Resource; -//import java.text.DateFormat; -//import java.text.ParseException; -//import java.text.SimpleDateFormat; -//import java.time.*; -//import java.time.format.DateTimeFormatter; -//import java.time.format.DateTimeParseException; -//import java.util.*; -//import java.util.concurrent.ExecutorService; -//import java.util.concurrent.Executors; -//import java.util.concurrent.TimeUnit; -//import java.util.concurrent.atomic.AtomicReference; -//import java.util.stream.Collectors; -// -///** -// * @author zys -// * 考勤定时器 -// */ -//@Configuration -//@EnableScheduling -//@Slf4j -//@EnableAsync -//public class AttTasks { -// -// @Resource(name = "attSourceDataDao") -// private AttSourceDataDao attSourceDataDao; -// @Resource(name = "sqlSessionTemplate") -// private SqlSessionTemplate sqlSessionTemplate; -// -// @Resource(name = "attGroupDao") -// private AttGroupDao attGroupDao; -// -// @Resource(name = "HolidayDao") -// private HolidayDao holidayDao; -// -// -// private static final int BATCH_SIZE = 10; // 每批次处理的日期数量 -// private static final int THREAD_POOL_SIZE = 5; // 线程池大小 -// private volatile boolean executed = false; // 标志位,表示任务是否已经执行过 -// -//// @Scheduled(cron = "0 0/10 * * * ?") -//// @Scheduled(initialDelay = 60000, fixedDelay = 60000 * 10) -// @Async -// public void getAttTasks() { -// log.info("--------考勤定时器开启------"); -// String today = DateUtil.today(); -// pushAttData(today, 1); -// log.info("--------考勤定时器完毕------"); -// } -// -// /** -// * 历史考勤数据 -// */ -//// @Scheduled(initialDelay = 6000,fixedDelay = 60000 * 30) -//// @Scheduled(cron = "0 50 19 * * ?") -// @Async -// public void getHisAttTasks() { -// log.info("--------考勤定时器开启------"); -// if (executed) { -// return; // 如果任务已经执行过,直接返回 -// } -// executed = true; // 设置标志位,表示任务已经执行过 -// String startDate = "2025-01-01"; -// String endDate = "2025-01-31"; -// List dateList = getStrDateListBetween(startDate, endDate); -//// List dateList = new ArrayList<>(); -//// dateList.add("2024-10-18"); -// hisAttPush(dateList); -// log.info("--------考勤定时器完毕------"); -// } -// -// /** -// * 防止黔送离线数据每月前三天晚上将数据重新执行 -// */ -//// @Scheduled(cron = "0 30 22 1-3 * *") -// @Async -// public void getHisMonthAttTask() { -// // 获取当前日期 -// LocalDate today = LocalDate.now(); -// // 获取上个月的YearMonth实例 -// YearMonth previousMonth = YearMonth.from(today).minusMonths(1); -// // 上个月的第一天 -// LocalDate startOfPreviousMonth = previousMonth.atDay(1); -// // 上个月的最后一天 -// LocalDate endOfPreviousMonth = previousMonth.atEndOfMonth(); -// String startDate = startOfPreviousMonth.toString(); -// String endDate = endOfPreviousMonth.toString(); -// List dateList = getStrDateListBetween(startDate, endDate); -// hisAttPush(dateList); -// log.info("--------考勤定时器完毕------"); -// } -// -// /** -// * 凌晨0-5点得到数据,算作昨天,将昨天的重新执行 -// */ -//// @Scheduled(cron = "0 5 6 * * ?") -// @Async -// public void getHisYesterdayAttTask() { -// // 获取今天的日期 -// LocalDate today = LocalDate.now(); -// // 计算昨天的日期 -// LocalDate yesterday = today.minusDays(1); -// String startDate = yesterday.toString(); -// String endDate = yesterday.toString(); -// List dateList = getStrDateListBetween(startDate, endDate); -// hisAttPush(dateList); -// log.info("--------考勤定时器完毕------"); -// } -// -// -// public void hisAttPush(List dateList) { -// // 创建固定大小的线程池 -// ExecutorService executorService = Executors.newFixedThreadPool(THREAD_POOL_SIZE); -// // 分批处理日期列表 -// for (int i = 0; i < dateList.size(); i += BATCH_SIZE) { -// int end = Math.min(i + BATCH_SIZE, dateList.size()); -// List batch = dateList.subList(i, end); -// // 提交任务到线程池 -// executorService.submit(() -> { -// for (String date : batch) { -// try { -// delHisData(date); -// pushAttData(date, 2); -// } catch (Exception e) { -// // 记录异常并继续处理下一个日期 -// System.err.println("Error processing date: " + date + ", error: " + e.getMessage()); -// } -// } -// }); -// } -// // 关闭线程池 -// executorService.shutdown(); -// try { -// // 等待所有任务完成 -// executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); -// } catch (InterruptedException e) { -// e.printStackTrace(); -// } -// } -// -// private void delHisData(String date) { -// //查询基础数据是否完备 -// int i = attSourceDataDao.getFirstAttendanceData(date); -// if(i > 0){ -// attSourceDataDao.updateHisData(date); -// }else{ -// attSourceDataDao.delHisData(date); -// } -// } -// -// -// /** -// * 推送考勤数据 -// * -// * @param pushDate 时间 -// * @param pushType 1:自动推送 2:手动 -// */ -// private void pushAttData(String pushDate, int pushType) { -// //获取黔送云的考勤数据 -// getQsyAttendanceData(pushDate, pushType); -// //获取考勤机中的考勤数据 -// getMachineAttendanceData(pushDate, pushType); -//// //查出每一个考勤组的应出勤天数以及考勤组的规则 -// List groupList = getGroupData(pushDate); -//// //新增默认考勤数据到考勤数据和修改表 -// insertAttData(groupList, pushDate, pushType); -// //更新请假数据 -// updateLeaveData(pushDate); -// //修改考勤数据 -// updateAttData(groupList, pushDate, pushType); -//// 根据考勤数据生成报表数据 -// createReportData(groupList, pushDate, pushType); -// } -// -// /** -// * 获取黔送云的考勤数据 -// */ -// private void getQsyAttendanceData(String pushDate, int pushType) { -// List attSourceList = Optional.ofNullable(attSourceDataDao.getQsyAttendances(pushDate, pushType)). -// orElseGet(ArrayList::new); -// if (!attSourceList.isEmpty()) { -// attSourceList.forEach(c -> { -// String address; -// try { -// address = AddressCoordinateFormatUtil. -// coordinateToAddress(c.getAttLon(), c.getAttLat()); -// }catch (IllegalArgumentException e){ -// address = "地址未转化成功"; -// } -// c.setAttAddress(address); -// if ("0".equals(c.getAttType())) { -// int i = checkTime(c.getAttCurrentTime()); -// c.setAttType(String.valueOf(i)); -// } -// //将00:00:00 至 04:59:59 时间变成att_current_day上一天的 -// changeAttCurrentDay(c); -// } -// ); -// //新增考勤到考勤来源表(数据过多时分批次插入) -// insertAttSourceData(attSourceList); -// } -// } -// -// /** -// * 将00:00:00 至 04:59:59 时间变成att_current_day上一天的 -// * -// * @param c -// */ -// public void changeAttCurrentDay(AttSourceDataBean c) { -// // 定义时间格式 -// DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); -// // 解析传入的时间字符串 -// LocalTime time = LocalTime.parse(c.getAttCurrentTime(), formatter); -// // 定义早上5点和中午12点的时间 -// LocalTime morningStart = LocalTime.of(0, 0); -// LocalTime noonEnd = LocalTime.of(5, 0); -// // 判断时间是否在0:00到05:00之间 -// if (time.isAfter(morningStart) && !time.isAfter(noonEnd)) { -// //获取前一天时间 -// String afterDate = DateUtils.getAfterDate(c.getAttCurrentDay()); -// c.setAttCurrentDay(afterDate); -// } -// } -// -// public void insertAttSourceData(List attSourceList) { -// if (attSourceList == null || attSourceList.isEmpty()) { -// return; -// } -// int batchSize = 3000; -// int totalBatches = (int) Math.ceil((double) attSourceList.size() / batchSize); -// try { -// for (int i = 0; i < totalBatches; i++) { -// int fromIndex = i * batchSize; -// int toIndex = Math.min(fromIndex + batchSize, attSourceList.size()); -// List batch = attSourceList.subList(fromIndex, toIndex); -// attSourceDataDao.insertAttSourceData(batch); -// if ((i + 1) % 100 == 0 || i + 1 == totalBatches) { -// sqlSessionTemplate.flushStatements(); // 提交事务 -// sqlSessionTemplate.clearCache(); // 清理缓存 -// } -// } -// } catch (Exception e) { -// throw new RuntimeException("Error replacing data", e); -// } -// } -// -// -// /** -// * 获取考勤机的考勤数据 -// */ -// private void getMachineAttendanceData(String pushDate, int pushType) { -// List attSourceList = Optional.ofNullable(attSourceDataDao.getMachineAttendances(pushDate, pushType)). -// orElseGet(ArrayList::new); -// attSourceList.forEach(c -> { -// if ("0".equals(c.getAttType())) { -// int i = checkTime(c.getAttCurrentTime()); -// c.setAttType(String.valueOf(i)); -// } -// //将00:00:00 至 04:59:59 时间变成att_current_day上一天的 -// changeAttCurrentDay(c); -// }); -// //新增考勤到考勤来源表(数据过多时分批次插入) -// insertAttSourceData(attSourceList); -// } -// -// public int checkTime(String currentTime) { -// if (currentTime == null || currentTime.isEmpty()) { -// // 如果输入为空或为空字符串,则返回默认值(例如2) -// return 1; -// } -// try { -// // 定义时间格式 -// DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); -// // 解析传入的时间字符串 -// LocalTime time = LocalTime.parse(currentTime, formatter); -// // 定义早上5点和中午12点的时间 -// LocalTime morningStart = LocalTime.of(5, 0); -// LocalTime noonEnd = LocalTime.of(12, 0); -// // 判断时间是否在5:00到12:00之间 -// if (time.isAfter(morningStart) && !time.isAfter(noonEnd)) { -// return 1; // 在早上5点到12点之间 -// } else { -// return 2; // 其他时间 -// } -// } catch (DateTimeParseException e) { -// // 如果时间格式不正确,返回默认值(例如2) -// e.printStackTrace(); -// return 1; -// } -// } -// -// /** -// * 更新所有的请假数据 -// */ -// private void updateLeaveData(String pushDate) { -// /** -// * 查出在考勤组人员的请假数据 -// */ -// List leaveList = Optional.ofNullable(attSourceDataDao.getLeaveData(pushDate)). -// orElseGet(ArrayList::new); -// if (!leaveList.isEmpty()) { -// leaveList.forEach(leaveData -> threadLeaveData(leaveData, pushDate)); -// } -// } -// -// /** -// * 根据请假数据去更新考勤数据 -// */ -// private void threadLeaveData(LeaveBean c, String pushDate) { -// //1.将请假区间变成日期集合 -//// if(c.getUserId() == 263){ -//// System.out.println("米娜"); -//// } -// List dateLists = getStrDateListBetween(c.getLeaveStartDate(), c.getLeaveEndDate()); -// if (!dateLists.isEmpty()) { -//// //根据开始时间、结束时间获取节假日的日期集合 -// // 1 表示固定打卡 -// if("1".equals(c.getAttType())){ -// //只有固定打卡蒋周六日不算在请假轮休天数中 -// List holidayList = holidayDao.getHolidayDataByType(c.getLeaveStartDate(), c.getLeaveEndDate()); -// // 使用Stream API去除A中包含在B中的元素 -// dateLists = dateLists.stream().filter(element -> !holidayList.contains(element)).collect(Collectors.toList()); -// } -// dateLists.forEach(v -> { -// boolean tf = false; -// AttDataBean toWorkBean = new AttDataBean(v, c.getAttStatus(), "1", -// c.getOrgId(), c.getUserId()); -// AttDataBean offWorkBean = new AttDataBean(v, c.getAttStatus(), "2", -// c.getOrgId(), c.getUserId()); -// //开始和结束的那天是否只请了半天 -// if (c.getLeaveStartDate().equals(v)) { -// if (c.getLeaveStartInterval().equals("2")) { -// replaceHolidayData(offWorkBean, 0); -// } else { -// tf = true; -// } -// } else if (c.getLeaveEndDate().equals(v)) { -// if (c.getLeaveEndInterval().equals("1")) { -// replaceHolidayData(toWorkBean, 0); -// } else { -// tf = true; -// } -// } else { -// tf = true; -// } -// if (tf) { -// replaceHolidayData(toWorkBean, 0); -// replaceHolidayData(offWorkBean, 0); -// } -// }); -// } -// } -// -// public static List getStrDateListBetween(String startDateString, String endDateString) { -// List dateList = new ArrayList<>(); -// DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); -// try { -// // 解析开始日期和结束日期 -// Date startDate = dateFormat.parse(startDateString); -// Date endDate = dateFormat.parse(endDateString); -// // 创建 Calendar 实例并设置为开始日期 -// Calendar calendar = Calendar.getInstance(); -// calendar.setTime(startDate); -// // 循环直到当前日期超过结束日期 -// while (!calendar.getTime().after(endDate)) { -// // 将日期格式化为字符串,并添加到列表中 -// dateList.add(dateFormat.format(calendar.getTime())); -// // 将日期加一天 -// calendar.add(Calendar.DAY_OF_MONTH, 1); -// } -// } catch (ParseException ignored) { -// } -// return dateList; -// } -// -// /** -// * 查出每一个考勤组的应出勤天数以及考勤组的规则 -// * -// * @return 考勤组集合 -// */ -// public List getGroupData(String pushDate) { -// //查出考勤组的数据 -// List groupList = Optional.ofNullable(attGroupDao.selectAttGroupList(new AttGroupBean())). -// orElseGet(ArrayList::new); -// if (groupList.isEmpty()) { -// return new ArrayList<>(); -// } -// //查询当月否有节假日或补班 -// List holidays = attSourceDataDao.selectHolidayByMonth(pushDate); -// groupList.forEach(c -> { -// //应考勤天 -// List attDayList = WorkdayCalculator.getWorkDay(c.getAttDay(), -// Integer.parseInt(c.getAttType()), holidays,pushDate); -// c.setAttWorkDayBean(new PersonAttWorkDayBean(c.getGroupId(), attDayList.size(), attDayList)); -// }); -// return groupList; -// } -// -// /** -// * 新增默认考勤数据到考勤数据和修改表 -// * -// * @param groupList 考勤组集合 -// */ -// private void insertAttData(List groupList, String pushDate, int pushType) { -// //获取所有的用户 -// // 2025-01-17 添加时间,查出每个人在对应时间存在的考勤组 -// List listPerson = attSourceDataDao.getAllPerson(pushDate); -// if (!listPerson.isEmpty()) { -// listPerson.forEach(v -> { -// groupList.stream() -// .filter(c -> Objects.equals(v.getGroupId(), c.getGroupId()) && !c.getAttWorkDayBean() -// .getAttDayList().contains(pushDate)) -// .findFirst() -// .ifPresent(c -> v.setAttStatus("11")); -// v.setAttCurrentDay(pushDate); -// replaceAttData(v, pushDate); -// }); -// } -// } -// -// /** -// * 新增修改考勤数据 -// */ -// private void replaceAttData(AttDataBean v, String pushDate) { -// //查询考勤模版数据是否已经插入 -// Boolean isAttExist = attSourceDataDao.selectAttIsExist(v); -// if (!isAttExist) { -// //查询能修改的考勤模版数据是否已经插入 -// // 判断 pushDate 是否在今天之前 -// boolean isPastDate = isBeforeToday(pushDate); -// if (isPastDate) { -// //不存在且在今天之前 -// //之前处理过节假日的数据,只有是默认数据才能将旷工状态写入 -// if (v.getAttStatus().equals("0")) { -// v.setAttStatus("3"); -// } -// }else{ -// //不存在就在今天 -// //逻辑跟修改相同,第一次就不去麻烦根据时间判断状态了 -// } -// attSourceDataDao.insertAttData(v); -// } else { -// if (!v.getAttStatus().equals("0")) { -// attSourceDataDao.updateAttData(v, 0); -// } -// if (v.getAttStatus().equals("0")) { -// //将未打卡的全部置为旷工 -// changeAbsenteeAttStatus(v, 0, 0, pushDate); -// } -// } -// //查询能修改的考勤模版数据是否已经插入 -// Boolean isAttUpdateExist = attSourceDataDao.selectAttUpdateIsExist(v); -// if (!isAttUpdateExist) { -// // 判断 pushDate 是否在今天之前 -// boolean isPastDate = isBeforeToday(pushDate); -// if (isPastDate) { -// //之前处理过节假日的数据,只有是默认数据才能将旷工状态写入 -// if (v.getAttStatus().equals("0")) { -// v.setAttStatus("3"); -// } -// } -// attSourceDataDao.insertAttUpdateData(v); -// } else { -// if (!v.getAttStatus().equals("0")) { -// attSourceDataDao.updateAttUpdateData(v, 0); -// } else { -// //将未打卡的全部置为旷工 -// changeAbsenteeAttStatus(v, 0, 1, pushDate); -// } -// } -// } -// -// -// /** -// * 新增修改请假数据(更新考勤表) -// */ -// private void replaceHolidayData(AttDataBean v, int type) { -// //查询考勤模版数据是否已经插入 -// Boolean isAttExist = attSourceDataDao.selectAttIsExist(v); -// if (!isAttExist) { -// //没有基础数据,插入基础数据并改状态为对应请假状态 -// attSourceDataDao.insertAttData(v); -// } else { -// if (!v.getAttStatus().equals("0")) { -// //改状态为对应请假状态 -// attSourceDataDao.updateAttData(v, type); -// } -// } -// //查询能修改的考勤模版数据是否已经插入 -// Boolean isAttUpdateExist = attSourceDataDao.selectAttUpdateIsExist(v); -// if (!isAttUpdateExist) { -// //没有基础数据,插入基础数据并改状态为对应请假状态 -// attSourceDataDao.insertAttUpdateData(v); -// } else { -// if (!v.getAttStatus().equals("0")) { -// //改状态为对应请假状态 -// attSourceDataDao.updateAttUpdateData(v, type); -// } -// } -// } -// -// -// /** -// * 将未打卡的全部置为旷工 -// * -// * @param v 考勤数据 -// * @param type 0表示考勤数据,1表示考勤修改数据 -// * @param update 0表示修改考勤数据,1表示修改考勤修改数据 -// * @param pushDate 推送时间 -// */ -// private void changeAbsenteeAttStatus(AttDataBean v, int type, int update, String pushDate) { -// //将未打卡的全部置为旷工 -// // 判断 pushDate 是否在今天之前 -// boolean isPastDate = isBeforeToday(pushDate); -// if (isPastDate) { -// // 如果 pushDate 是过去的时间,直接执行原逻辑 -// v.setAttStatus("3"); -// if (update == 0) { -// attSourceDataDao.updateAttData(v, type); -// } else if (update == 1) { -// attSourceDataDao.updateAttUpdateData(v, type); -// } -// } else { -// LocalTime currentTime; -// // 使用当前时间 -// currentTime = LocalTime.now(); -// // 定义中午 12 点 -// LocalTime noon = LocalTime.of(12, 0); -// // 定义下午 22 点 -// LocalTime eightPM = LocalTime.of(22, 0); -// // 当前时间逻辑 -// if (currentTime.isAfter(noon)) { -// if ("1".equals(v.getAttType())) { -// v.setAttStatus("3"); -// if (update == 0) { -// attSourceDataDao.updateAttData(v, type); -// } else if (update == 1) { -// attSourceDataDao.updateAttUpdateData(v, type); -// } -// } -// } -// if (currentTime.isAfter(eightPM)) { -// if ("2".equals(v.getAttType())) { -// v.setAttStatus("3"); -// if (update == 0) { -// attSourceDataDao.updateAttData(v, type); -// } else if (update == 1) { -// attSourceDataDao.updateAttUpdateData(v, type); -// } -// } -// } -// } -// } -// -// /** -// * 判断传入的日期是否在今天的日期之前 -// * -// * @param dateStr 传入的日期字符串,格式为 "yyyy-MM-dd" -// * @return 如果传入的日期在今天的日期之前,返回 true;否则返回 false -// */ -// public boolean isBeforeToday(String dateStr) { -// if (dateStr == null || dateStr.isEmpty()) { -// return false; -// } -// try { -// LocalDate date = LocalDate.parse(dateStr, DateTimeFormatter.ofPattern("yyyy-MM-dd")); -// LocalDate today = LocalDate.now(); -// return date.isBefore(today); -// } catch (Exception e) { -// // 如果日期格式不正确,返回 false -// e.printStackTrace(); -// return false; -// } -// } -// -// /** -// * 修改考勤数据 -// * -// * @param groupList 考勤组集合 -// */ -// private void updateAttData(List groupList, String pushDate, int pushType) { -// //查出最近三天的人员考勤记录 -// AtomicReference> sourceDataList = new AtomicReference<>(attSourceDataDao.getSourceAttData(pushDate, pushType)); -// //根据考勤组的规则和请假记录算出人员的考勤状态 -// groupList.forEach(c -> { -// List list = Collections.emptyList(); -// //考勤规则里面的attType 1 固定打卡 2 自由打卡 -// if ("1".equals(c.getAttType())) { -// list = GroupFixedData(sourceDataList.get().stream() -// .filter(a -> "1".equals(a.getGroupType()) && -// a.getGroupId() == c.getGroupId()) -// .collect(Collectors.toList()), c); -// } else if ("2".equals(c.getAttType())) { -// list = getDataList(sourceDataList.get().stream() -// .filter(a -> "2".equals(a.getGroupType()) && -// a.getGroupId() == c.getGroupId()) -// .collect(Collectors.toList()), c, true); -// } -// //修改考勤记录 att_data -// if (!list.isEmpty()) { -// if ("1".equals(c.getAttType())) { -// //固定打卡 -// // 定义时间格式 -// DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); -// // 移除移除 attType 为 2 且 attCurrentTime 在上午 5 点到 12 点之间的元素 -// list.removeIf(record -> { -// String attType = record.getAttType(); -// String attCurrentTime = record.getAttCurrentTime(); -// if (!"".equals(attCurrentTime)) { -// if (attCurrentTime.contains(" ")) { -// attCurrentTime = attCurrentTime.split(" ")[0]; -// } -// LocalDateTime time = LocalDateTime.parse(attCurrentTime, formatter); -// // 提取时间部分 -// LocalTime localTime = time.toLocalTime(); -// boolean condition1 = "2".equals(attType) && localTime.isAfter(LocalTime.of(5, 0)) && localTime.isBefore(LocalTime.of(12, 0)); -// boolean condition2 = "1".equals(attType) && localTime.isAfter(LocalTime.of(12, 0)) && localTime.isBefore(LocalTime.of(23, 59)); -// return condition1 || condition2; -// } else { -// return false; -// } -// }); -// // 插入剩余的元素 -// attSourceDataDao.updateAttStatusData(list); -// } else if ("2".equals(c.getAttType())) { -// //自由打卡 -// attSourceDataDao.updateAttStatusData(list); -// } -// } -// }); -// } -// -// /** -// * 固定考勤数据计算 -// * -// * @param list 考勤来源数据 -// * @param attGroupBean 考勤组数据 -// * @return 考勤数据 -// */ -// private List GroupFixedData(List list, -// AttGroupBean attGroupBean) { -// List newList = getDataList(list, attGroupBean, false); -// Iterator iterator = newList.iterator(); -// while (iterator.hasNext()) { -// if (iterator.next() == null) { -// iterator.remove(); -// } -// } -// processAttendanceStatus(newList, attGroupBean.getToWorkTime(), attGroupBean.getOffWorkTime(), attGroupBean.getLateMinute(), -// attGroupBean.getAbsenteeismLateMinute(), attGroupBean.getLeaveMinute(), attGroupBean.getAbsenteeismLeaveMinute()); -// return newList; -// } -// -// /** -// * 上下班考勤计算 -// * -// * @param list 考勤来源数据 -// * @param attGroupBean 考勤组数据 -// * @param tf 固定|自由 -// * @return 考勤数据 -// */ -// private List getDataList(List list, -// AttGroupBean attGroupBean, -// Boolean tf) { -// List newList = new ArrayList<>(); -// //分组排序(将每个人每天在自己考勤组的数据分组) -// Map> groupedItems = list.stream() -// .collect(Collectors.groupingBy( -// c -> c.getUserId() + "|" + c.getOrgId() + "|" + c.getAttCurrentDay(), -// Collectors.collectingAndThen( -// Collectors.toList(), -// v -> { -// v.sort(Comparator.comparing(AttSourceDataBean::getAttCurrentTime)); -// return v; -// } -// ) -// )); -// if (!tf) { -// //固定打卡,以最靠近上班打卡时间前的出闸机的时间为基准,去除掉之前的所有打卡数据 -// processGroupedItems(groupedItems, attGroupBean); -// } -// groupedItems.forEach((c, v) -> { -// //第一次上班时间 -// AttSourceDataBean frontToWorkBean = v.stream() -// .filter(a -> a.getAttType().equals("1")) -// .collect(Collectors.toList()) -// .stream().min(Comparator.comparing(AttSourceDataBean::getAttCurrentTime)).orElse(null); -// //最新一次下班时间 -// AttSourceDataBean backOffWorkBean = v.stream() -// .filter(a -> a.getAttType().equals("2")) -// .collect(Collectors.toList()) -// .stream().max(Comparator.comparing(AttSourceDataBean::getAttCurrentTime)).orElse(null); -// if (tf) { -// if(v!=null&&v.size()>0&&v.get(0).getName().equals("任荣辉")){ -// System.out.println("11111111111"); -// } -// //自由打卡不需要去除数据 -// getFreeAttData(newList, frontToWorkBean, backOffWorkBean, attGroupBean); -// } else { -// if (backOffWorkBean != null) { -// //最新一次下班时间插入list -// newList.add(backOffWorkBean); -// } -//// if(v.get(0).getName().equals("肖阳")){ -//// System.out.println("c.getAttCurrentTime() = "); -//// } -// // 处理逻辑 出入异常的逻辑 -//// try { -//// Map> result = checkAdjacentAttType1WithGapAndCheckTypesBefore(v, attGroupBean.getEntryAbnormalMinute()); -//// if (result.containsKey(true)) { -//// List matchingItems = result.get(true); -//// frontToWorkBean = matchingItems.get(0); -//// frontToWorkBean.setAbnormalAttTime(matchingItems.get(1).getAttCurrentTime()); -//// frontToWorkBean.setAbnormalAttAddress(matchingItems.get(1).getAttAddress()); -//// frontToWorkBean.setAttStatus(8); -//// } -//// }catch(Exception e){ -//// e.printStackTrace(); -//// log.error("出入异常处理报错"); -//// } -// //没有下班卡则添加第一次打卡数据 -// newList.add(frontToWorkBean); -// //获取工作异常 -// LocalTime lastOutTime = null; -// DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); -// DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss"); -// try { -// //存储工作异常的list -// List longBreakRecords = new ArrayList<>(); -// for (int i = 0; i < v.size(); i++) { -// AttSourceDataBean record = v.get(i); -// // 如果是“出”的记录,保存时间 -// if ("2".equals(record.getAttType())) { -// lastOutTime = LocalDateTime.parse(record.getAttCurrentTime(), dateTimeFormatter).toLocalTime(); -// if(lastOutTime.isAfter(LocalTime.parse(attGroupBean.getOffWorkTime(), timeFormatter))){ -// //进在下班之后,不考虑 -// break; -// } -// } -// // 如果是“进”的记录并且之前有“出”的记录 -// else if ("1".equals(record.getAttType()) && lastOutTime != null) { -// LocalTime inTime = LocalDateTime.parse(record.getAttCurrentTime(), dateTimeFormatter).toLocalTime(); -// // 计算实际工作时间(不包括午休时间) -//// if(record.getName().equals("何波")){ -//// System.out.println("11111111111"); -//// } -// // 出-》进 的时间在上班时间前,去除 -// if(inTime.isBefore(LocalTime.parse(attGroupBean.getToWorkTime(), timeFormatter))){ -// //进在上班之后,不考虑 -// break; -// } -// Duration workDuration = calculateWorkDuration(lastOutTime, inTime, attGroupBean); -// // 如果工作时间外出超过了规定时间,记录下这对“出”和“进” -// if (workDuration != null && !workDuration.isNegative() && workDuration.toMinutes() > attGroupBean.getWorkAbnormalMinute()) { -// AttSourceDataBean longBreakRecord = new AttSourceDataBean(); -// longBreakRecord.setUserId(record.getUserId()); -// longBreakRecord.setName(record.getName()); -// longBreakRecord.setOrgId(attGroupBean.getOrgId()); -// longBreakRecord.setAttCurrentDay(record.getAttCurrentDay()); -// longBreakRecord.setAttCurrentTime(v.get(i - 1).getAttCurrentTime() + " " + record.getAttCurrentTime()); -// longBreakRecord.setAttAddress(v.get(i - 1).getAttAddress() + " " + record.getAttAddress()); -// longBreakRecords.add(longBreakRecord); -// } -// // 更新lastOutTime为null,因为已经处理了这一对 -// lastOutTime = null; -// } -// } -// //判断有没有临时外出请假等等 -// if(!longBreakRecords.isEmpty()){ -// int x = attSourceDataDao.getLeaveDataByUserId(longBreakRecords.get(0)); -// if(x==0){ -// attSourceDataDao.insertWorkAbnormal(longBreakRecords); -// } -// } -// }catch(Exception e){ -// e.printStackTrace(); -// log.error("工作异常处理报错"); -// } -// -// } -// }); -// return newList; -// } -// -// private static Duration calculateWorkDuration(LocalTime outTime, LocalTime inTime, AttGroupBean group) { -// try { -// DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss"); -// // 解析上班、下班、午休开始、结束时间 -// LocalTime offWorkTime = LocalTime.parse(group.getOffWorkTime(), formatter); -// LocalTime breakStartTime = LocalTime.parse(group.getBreakStartTime(), formatter); -// LocalTime breakEndTime = LocalTime.parse(group.getBreakEndTime(), formatter); -// // 如果出勤时间在午休时间内,调整出勤时间为午休结束时间 -// if (outTime.isAfter(breakStartTime) && outTime.isBefore(breakEndTime)) { -// outTime = breakEndTime; -// } -// // 如果进入时间在午休时间内,调整进入时间为午休开始时间 -// if (inTime.isAfter(breakStartTime) && inTime.isBefore(breakEndTime)) { -// inTime = breakStartTime; -// } -// // 如果进入时间在下班时间内,调整进入时间为下班时间 -// if (inTime.isAfter(offWorkTime)) { -// inTime = offWorkTime; -// } -// // 计算总的工作时间 -// Duration totalDuration = Duration.between(outTime, inTime); -// // 如果时间段跨越了午休时间,减去午休时长 -// if (outTime.isBefore(breakEndTime) && inTime.isAfter(breakStartTime)) { -// Duration breakDuration = Duration.between(breakStartTime, breakEndTime); -// totalDuration = totalDuration.minus(breakDuration); -// } -// return totalDuration; -// } catch (DateTimeParseException e) { -// // 处理解析异常,例如记录日志或返回默认值 -// System.err.println("时间解析错误: " + e.getMessage()); -// return null; // 或者返回一个默认的 LocalDateTime -// } -// } -// -// /** -// * 根据getAttCurrentTime对List进行正序排序。 -// * 遍历排序后的列表,找到最早相邻且间隔时间大于2分钟的两个attType = 1的数据项。 -// * 检查这两个数据项之前的数据集合是否同时包含attType = 1和attType = 2的数据。 -// * -// * @param items -// * @param entryAbnormalMinute -// * @return -// */ -// private Map> checkAdjacentAttType1WithGapAndCheckTypesBefore(List items, Long entryAbnormalMinute) { -// DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss"); -// // 步骤1:根据 getAttCurrentTime 排序 -// items.sort(Comparator.comparing(AttSourceDataBean::getAttCurrentTime)); -// // 步骤2:找到最早相邻且间隔时间大于2分钟的两个 attType = 1 的数据项 -// AttSourceDataBean firstAttType1 = null; -// AttSourceDataBean secondAttType1 = null; -// for (int i = 0; i < items.size() - 1; i++) { -// if ("1".equals(items.get(i).getAttType()) && "1".equals(items.get(i + 1).getAttType())) { -// // 提取时间部分 -// String firstTimeStr = items.get(i).getAttCurrentTime().substring(11); -// String secondTimeStr = items.get(i + 1).getAttCurrentTime().substring(11); -// LocalTime firstTime = LocalTime.parse(firstTimeStr, timeFormatter); -// LocalTime secondTime = LocalTime.parse(secondTimeStr, timeFormatter); -// Duration duration = Duration.between(firstTime, secondTime); -// if (duration.toMinutes() > entryAbnormalMinute) { -// firstAttType1 = items.get(i); -// secondAttType1 = items.get(i + 1); -// break; -// } -// } -// } -// // 如果没有找到符合条件的两个 attType = 1 的数据项,直接返回 false -// if (firstAttType1 == null || secondAttType1 == null) { -// Map> result = new HashMap<>(); -// result.put(false, Collections.emptyList()); -// return result; -// } -// -// // 步骤3:检查这两个数据项之前的数据集合是否同时包含 attType = 1 和 attType = 2 的数据 -// int indexFirstAttType1 = items.indexOf(firstAttType1); -// List dataBeforeFirstAttType1 = items.subList(0, indexFirstAttType1); -// -// Set attTypesBefore = dataBeforeFirstAttType1.stream() -// .map(AttSourceDataBean::getAttType) -// .collect(Collectors.toSet()); -// -// boolean containsBothTypes = attTypesBefore.contains("1") && attTypesBefore.contains("2"); -// // 返回结果 -// Map> result = new HashMap<>(); -// if (containsBothTypes) { -// result.put(true, Arrays.asList(firstAttType1, secondAttType1)); -// } else { -// result.put(false, Collections.emptyList()); -// } -// return result; -// } -// -// /** -// * 固定打卡清除数据 -// * -// * @param groupedItems -// */ -// private void processGroupedItems(Map> groupedItems, AttGroupBean attGroupBean) { -// DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss"); -// DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); -// for (Map.Entry> entry : groupedItems.entrySet()) { -// String key = entry.getKey(); -// List items = entry.getValue(); -// if (items.isEmpty()) { -// continue; // 如果列表为空,跳过 -// } -// //五点之前的数据属于过来当天的下班打卡,不计入 -// LocalTime noonEnd = LocalTime.of(5, 0); -// // 获取上班时间并转换为 LocalTime 以便比较 -// LocalTime toWorkTime = LocalTime.parse(attGroupBean.getToWorkTime(), timeFormatter); -// // 初始化变量来保存最接近上班时间的数据项及其索引 -// AttSourceDataBean closestBeforeToWork = null; -// int closestIndex = -1; -// // 遍历并查找最接近上班时间且 attType=2 的数据项 -// //前面已经排过序了,取第一个就可以了 -// for (int i = 0; i < items.size(); i++) { -// AttSourceDataBean item = items.get(i); -//// System.out.println(item.getName()); -//// if("王义".equals(item.getName())){ -//// System.out.println(111); -//// } -// if ("2".equals(item.getAttType())) { -// // 只提取时间部分进行比较 -// LocalTime recordTime = LocalTime.parse(item.getAttCurrentTime().substring(11), timeFormatter); -// // 检查是否在上班时间之前并且是目前找到的最接近上班时间的 -// if (recordTime.isBefore(toWorkTime) && recordTime.isAfter(noonEnd) && -// (closestBeforeToWork == null || -// recordTime.isAfter(LocalTime.parse(closestBeforeToWork.getAttCurrentTime().substring(11), timeFormatter)))) { -// closestBeforeToWork = item; -// closestIndex = i; -// } -// } -// } -// -// // 如果找到了符合条件的数据项,则移除它之前的所有数据,包括它自己 -// if (closestIndex != -1) { -// List filteredItems = items.stream() -// .skip(closestIndex) // 跳过最接近上班时间的数据项及其之前的所有数据 -// .collect(Collectors.toList()); -// // 更新原始映射中的列表 -// groupedItems.put(key, filteredItems); -// } else { -// // 如果没有找到符合条件的数据项,可以选择保留所有数据或清空列表 -// // groupedItems.put(key, Collections.emptyList()); // 清空列表 -// } -// } -// } -// -// /** -// * 获取自由考勤数据 -// * -// * @param newList 考勤数据 -// * @param frontToWorkBean 第一次上班考勤数据 -// * @param backOffWorkBean 最后一次下班考勤数据 -// * @param attGroupBean 考勤组数据 -// */ -// private void getFreeAttData(List newList, -// AttSourceDataBean frontToWorkBean, -// AttSourceDataBean backOffWorkBean, -// AttGroupBean attGroupBean) { -// // todayClockNum 自由打卡每天打卡次数 -// if (attGroupBean.getTodayClockNum() == 2) { -// if (frontToWorkBean != null) { -// frontToWorkBean.setAttStatus(1); -// newList.add(frontToWorkBean); -// } -// if (backOffWorkBean != null) { -// if (frontToWorkBean != null) { -// long minutesDiff = DateUtil.between( -// DateUtils.parseDate(frontToWorkBean.getAttCurrentTime()), -// DateUtils.parseDate(backOffWorkBean.getAttCurrentTime()), -// DateUnit.MINUTE -// ); -// if (minutesDiff >= attGroupBean.getAttendanceDuration()) { -// backOffWorkBean.setAttStatus(1); -// } else { -// if (minutesDiff > attGroupBean.getAbsenteeismLateMinute()) { -// backOffWorkBean.setAttStatus(1); -// }else if (minutesDiff > attGroupBean.getAbsenteeismLeaveMinute()) { -// backOffWorkBean.setAttStatus(4); -// }else{ -// backOffWorkBean.setAttStatus(3); -// } -// } -// newList.add(backOffWorkBean); -// } else { -// backOffWorkBean.setAttStatus(1); -// newList.add(backOffWorkBean); -// } -// } -// } else { -// if (frontToWorkBean != null) { -//// if(frontToWorkBean.getName().equals("位兆虎")){ -//// System.out.println(1); -//// } -// frontToWorkBean.setAttStatus(1); -// AttSourceDataBean bean; -// try { -// bean = (AttSourceDataBean) BeanUtils.cloneBean(frontToWorkBean); -// } catch (Exception e) { -// throw new RuntimeException(e); -// } -// bean.setAttCurrentTime(""); -// bean.setAttType("2"); -// newList.add(bean); -// newList.add(frontToWorkBean); -// } else if (backOffWorkBean != null) { -// backOffWorkBean.setAttStatus(1); -// AttSourceDataBean bean; -// try { -// bean = (AttSourceDataBean) BeanUtils.cloneBean(backOffWorkBean); -// } catch (Exception e) { -// throw new RuntimeException(e); -// } -// bean.setAttCurrentTime(""); -// bean.setAttType("1"); -// newList.add(bean); -// newList.add(backOffWorkBean); -// } -// -// } -// } -// -// /** -// * 根据时间段处理上下班 -// * -// * @param bean -// * @param startHour -// * @param startMinute -// * @param endHour -// * @param endMinute -// * @param oldAttType -// * @param newAttType -// * @return -// */ -// private void dealWithDateToAttType(AttSourceDataBean bean, int startHour, int startMinute, int endHour, int endMinute, String oldAttType, String newAttType) { -// DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); -// String attType = bean.getAttType(); -// String attCurrentTime = bean.getAttCurrentTime(); -// if (!"".equals(attCurrentTime)) { -// if (attCurrentTime.contains(" ")) { -// attCurrentTime = attCurrentTime.split(" ")[0]; -// } -// LocalDateTime time = LocalDateTime.parse(attCurrentTime, formatter); -// // 提取时间部分 -// LocalTime localTime = time.toLocalTime(); -// if (oldAttType.equals(attType) && localTime.isAfter(LocalTime.of(startHour, startMinute)) && localTime.isBefore(LocalTime.of(startMinute, endMinute))) { -// bean.setAttType(newAttType); -// } -// } -// } -// -// -// /** -// * 处理打卡状态 -// * -// * @param newList 考勤数据 -// * @param toWorkTime 上班时间 -// * @param offWorkTime 下班时间 -// * @param lateMinute 迟到时间 -// * @param absenteeismLateMinute 旷工迟到分钟 -// * @param leaveMinute 早退分钟 -// * @param absenteeismLeaveMinute 旷工早退分钟 -// */ -// private void processAttendanceStatus(List newList, String toWorkTime, -// String offWorkTime, long lateMinute, -// long absenteeismLateMinute, long leaveMinute, -// long absenteeismLeaveMinute) { -// newList.forEach(c -> { -//// if(c.getName().equals("肖阳")){ -//// System.out.println("c.getAttCurrentTime() = " + c.getAttCurrentTime()); -//// } -// System.out.println(c.getName()); -// int attStatus = calculateStatus( -// c.getAttType(), -// c.getAttCurrentTime(), -// "1".equals(c.getAttType()) ? toWorkTime : offWorkTime, -// "1".equals(c.getAttType()) ? lateMinute : leaveMinute, -// "1".equals(c.getAttType()) ? absenteeismLateMinute : absenteeismLeaveMinute -// ); -// System.out.println(1111); -// // 如打卡状态为正常,检查是否有异常出入时间 -// if (attStatus == 1 && c.getAttStatus() != null && c.getAttStatus() == 8) { -// attStatus = 8; // 异常 -// boolean b = DateTimeHelper.compareTime2(c.getAttCurrentTime(), c.getAbnormalAttTime()); -// String time = ""; -// String address = ""; -// if (b) { -// time = c.getAttCurrentTime() + " " + c.getAbnormalAttTime(); -// address = c.getAttAddress() + " " + c.getAbnormalAttAddress(); -// } else { -// time = c.getAbnormalAttTime() + " " + c.getAttCurrentTime(); -// address = c.getAbnormalAttAddress() + " " + c.getAttAddress(); -// } -// c.setAttCurrentTime(time); -// c.setAttAddress(address); -// } -// System.out.println(2222); -// c.setAttStatus(attStatus); -// }); -// } -// -// -// /** -// * 计算时间差并返回状态 -// * -// * @param attType 考勤类型 -// * @param attTime 考勤时间 -// * @param standardTime 上、下班时间 -// * @param lateThreshold 迟到、早退时间 -// * @param absenteeismThreshold 旷工时间 -// * @return 考勤状态 -// */ -// private int calculateStatus(String attType, String attTime, String standardTime, -// long lateThreshold, long absenteeismThreshold) { -// int status = 1; -// // 创建两个时间点 -// Date date1 = DateUtils.parseDate(DateUtils.getYyyyMmDd(attTime) + " " + standardTime); -// Date date2 = DateUtils.parseDate(attTime); -// if ("2".equals(attType)) { -// String startTime = DateUtils.getYyyyMmDd(attTime) + " 00:00:00"; -// String endTime = DateUtils.getYyyyMmDd(attTime) + " 04:59:59"; -// if (DateUtils.getTimeIsRange(attTime, startTime, endTime)) { -// date1 = DateUtils.parseDate(DateUtils.getAfterDate(DateUtils.getYyyyMmDd(attTime)) + " " + standardTime); -// } -// } -// if ("1".equals(attType)) { // 上班打卡 -// // 计算时间差 -// // 减 1 原因:30上班,30:59不算迟到,类似于默认可以迟到一分钟 -// double difference = (date2.getTime() - date1.getTime()) / 60000.0 - 1; -// if (difference > 0) { -// if (difference > absenteeismThreshold) { -// status = 3; // 旷工 -// } else if (difference > lateThreshold) { -// status = 2; // 迟到 -// } -// } -// } else if ("2".equals(attType)) { // 下班打卡 -// // 计算时间差 -// double difference = (date2.getTime() - date1.getTime()) / 60000.0; -// if (difference < 0) { -// if (Math.abs(difference) > lateThreshold) { -// status = 4; // 早退 -// } -// if (Math.abs(difference) > absenteeismThreshold) { -// status = 3; // 旷工 -// } -// } -// } -// return status; // 正常 -// } -// -// /** -// * 根据考勤数据生成报表数据 -// * -// * @param groupList 考勤组集合 -// */ -// public void createReportData(List groupList, String pushDate, int pushType) { -// //日报表查询 -// List dayReportList = attSourceDataDao.selectAttDayReport(pushDate); -// //日报表新增 -// attSourceDataDao.insertAttDayReport(dayReportList); -// List monthReportList = attSourceDataDao.selectAttMonthReport(pushDate); -// //人员对应出月出勤天数 -// monthReportList.forEach(c -> -// groupList.stream() -// .filter(v -> c.getGroupId() != null && c.getGroupId().equals(v.getGroupId())) -// .findFirst() -// .ifPresent(v -> c.setRequiredDays(v.getAttWorkDayBean().getRequiredDays())) -// ); -// //先将本月数据删除,重新生成 -// attSourceDataDao.deleteAttMonthReport(pushDate); -// //月报表新增 -// attSourceDataDao.insertAttMonthReport(monthReportList); -// } -// -// /** -// * 根据当前日期计算目标日期 -// * -// * @param now 当前日期时间 -// * @return 目标日期 -// */ -// public static LocalDate getTargetDate(LocalDateTime now) { -// // 获取当前日期的年份和月份 -// YearMonth currentYearMonth = YearMonth.from(now); -// -// // 获取当前日期的月初日期 -// LocalDate firstDayOfMonth = currentYearMonth.atDay(1); -// -// // 判断是否是当月 -// if (now.getMonth().equals(firstDayOfMonth.getMonth())) { -// // 如果是当月,返回当前日期的日期部分 -// return now.toLocalDate(); -// } else { -// // 如果是之前月份,返回该月份的最后一天 -// return currentYearMonth.atEndOfMonth(); -// } -// } -// -//} \ No newline at end of file diff --git a/bonus-modules/bonus-system/src/main/java/com/bonus/system/att/tasks/HolidayTasks.java b/bonus-modules/bonus-system/src/main/java/com/bonus/system/att/tasks/HolidayTasks.java index 4308849..9d2a4dd 100644 --- a/bonus-modules/bonus-system/src/main/java/com/bonus/system/att/tasks/HolidayTasks.java +++ b/bonus-modules/bonus-system/src/main/java/com/bonus/system/att/tasks/HolidayTasks.java @@ -1,13 +1,20 @@ package com.bonus.system.att.tasks; +import cn.hutool.core.date.DateUtil; import cn.hutool.http.HttpUtil; import com.alibaba.fastjson2.JSONObject; import com.bonus.common.core.utils.DateUtils; +import com.bonus.common.security.utils.SecurityUtils; +import com.bonus.system.api.domain.SysUser; import com.bonus.system.att.dao.AttSourceDataDao; import com.bonus.system.att.entity.Holiday; import com.bonus.system.att.entity.OrgChangeBean; import com.bonus.system.att.service.OrgChangeService; +import com.bonus.system.holiday.dao.HolidayDao; +import com.bonus.system.holiday.entity.HolidayBean; +import com.bonus.system.holiday.service.HolidayService; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.CollectionUtils; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.EnableAsync; @@ -16,6 +23,9 @@ import org.springframework.scheduling.annotation.Scheduled; import javax.annotation.Resource; import java.time.Instant; +import java.time.LocalDate; +import java.time.YearMonth; +import java.time.format.DateTimeFormatter; import java.util.*; /** @@ -35,6 +45,9 @@ public class HolidayTasks { @Resource(name = "OrgChangeService") private OrgChangeService orgChangeService; + @Resource(name = "HolidayDao") + private HolidayDao holidayDao; + @Scheduled(cron = "0 0 5 26 11 *")//每天12月26日凌晨5点 @Async public void getAttTasks(){ @@ -67,6 +80,36 @@ public class HolidayTasks { } } + /** + * 月初自动通过上月所有未通过的请假数据 + */ + @Scheduled(cron = "0 0 5 1 * ?") // 每月1日凌晨5点执行 + @Async + public void updateHolidayStatus(){ + // 获取当前日期 + LocalDate today = LocalDate.now(); + // 获取上个月的年份和月份 + YearMonth previousMonth = YearMonth.from(today).minusMonths(1); + // 上个月的第一天 + LocalDate startOfPreviousMonth = previousMonth.atDay(1); + // 上个月的最后一天 + LocalDate endOfPreviousMonth = previousMonth.atEndOfMonth(); + // 定义日期格式 + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + // 将日期转换为指定格式的字符串 + String startStr = startOfPreviousMonth.format(formatter); + String endStr = endOfPreviousMonth.format(formatter); + HolidayBean bean = new HolidayBean(); + bean.setLeaveStartInterval(startStr); + bean.setLeaveEndInterval(endStr); + List list = holidayDao.getHolidayListByDate(bean); + bean.setIds(list); + bean.setExamineOpinion("同意 月初自动审核上月未审核数据"); + //通过 + bean.setExamineStatus("1"); + holidayDao.batchCheckStatus(bean); + } + /** * 考勤组变更更新数据 */ diff --git a/bonus-modules/bonus-system/src/main/java/com/bonus/system/att/tasks/NewAttTask.java b/bonus-modules/bonus-system/src/main/java/com/bonus/system/att/tasks/NewAttTask.java index 233de36..806f7a0 100644 --- a/bonus-modules/bonus-system/src/main/java/com/bonus/system/att/tasks/NewAttTask.java +++ b/bonus-modules/bonus-system/src/main/java/com/bonus/system/att/tasks/NewAttTask.java @@ -2,6 +2,7 @@ package com.bonus.system.att.tasks; import cn.hutool.core.date.DateUtil; import com.bonus.system.att.service.AttCalService; +import com.bonus.system.holiday.entity.HolidayBean; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.Async; @@ -278,4 +279,13 @@ public class NewAttTask { attCalService.updateMonthReportData(pushDate); } + + /** + * 请假等模块数据回退,需要将数据考勤数据回退再重新调用 + */ + public void rollbackAttDataByLeave(HolidayBean o) { + log.info("--------请假等模块数据回退调用------"); + attCalService.rollbackAttDataByLeave(o); + } + } \ No newline at end of file diff --git a/bonus-modules/bonus-system/src/main/java/com/bonus/system/holiday/dao/HolidayDao.java b/bonus-modules/bonus-system/src/main/java/com/bonus/system/holiday/dao/HolidayDao.java index 974a547..f75f1e0 100644 --- a/bonus-modules/bonus-system/src/main/java/com/bonus/system/holiday/dao/HolidayDao.java +++ b/bonus-modules/bonus-system/src/main/java/com/bonus/system/holiday/dao/HolidayDao.java @@ -111,4 +111,11 @@ public interface HolidayDao { * @return */ List judgeRepeatEnd(HolidayBean o); + + /** + * 根据日期查询请假数据 + * @param bean + * @return + */ + List getHolidayListByDate(HolidayBean bean); } diff --git a/bonus-modules/bonus-system/src/main/java/com/bonus/system/holiday/service/HolidayService.java b/bonus-modules/bonus-system/src/main/java/com/bonus/system/holiday/service/HolidayService.java index cfee75d..5f9d681 100644 --- a/bonus-modules/bonus-system/src/main/java/com/bonus/system/holiday/service/HolidayService.java +++ b/bonus-modules/bonus-system/src/main/java/com/bonus/system/holiday/service/HolidayService.java @@ -73,4 +73,5 @@ public interface HolidayService { * @date 2025/2/11 14:19 */ AjaxResult batchCheckStatus(HolidayBean o); + } diff --git a/bonus-modules/bonus-system/src/main/resources/mapper/att/AttSourceDataMapper.xml b/bonus-modules/bonus-system/src/main/resources/mapper/att/AttSourceDataMapper.xml index a0c4c81..c83c767 100644 --- a/bonus-modules/bonus-system/src/main/resources/mapper/att/AttSourceDataMapper.xml +++ b/bonus-modules/bonus-system/src/main/resources/mapper/att/AttSourceDataMapper.xml @@ -548,5 +548,19 @@ LEFT JOIN sys_organization so ON so.id = suo.org_id where su.user_id = #{userId} + \ No newline at end of file diff --git a/bonus-modules/bonus-system/src/main/resources/mapper/att/AttendanceDetailsMapper.xml b/bonus-modules/bonus-system/src/main/resources/mapper/att/AttendanceDetailsMapper.xml index 8dcd4e4..107ba61 100644 --- a/bonus-modules/bonus-system/src/main/resources/mapper/att/AttendanceDetailsMapper.xml +++ b/bonus-modules/bonus-system/src/main/resources/mapper/att/AttendanceDetailsMapper.xml @@ -221,7 +221,7 @@ select su.user_name, so.org_name, v.* from v_att_data v left join sys_user su on su.user_id = v.user_id left join sys_organization so on so.id = v.org_id - where v.att_current_day BETWEEN #{bean.startDate} AND #{bean.endDate} and su.is_active = 1 + where v.att_current_day BETWEEN #{bean.startDate} AND #{bean.endDate} AND v.org_id = #{bean.orgId} diff --git a/bonus-modules/bonus-system/src/main/resources/mapper/holiday/HolidayMapper.xml b/bonus-modules/bonus-system/src/main/resources/mapper/holiday/HolidayMapper.xml index f9a7cdd..be26174 100644 --- a/bonus-modules/bonus-system/src/main/resources/mapper/holiday/HolidayMapper.xml +++ b/bonus-modules/bonus-system/src/main/resources/mapper/holiday/HolidayMapper.xml @@ -89,6 +89,9 @@ update_user_id = #{updateUserId}, + + examine_opinion = #{examineOpinion}, + examine_status = #{examineStatus} WHERE id IN @@ -283,6 +286,16 @@ and id !=#{id} + \ No newline at end of file