|
@@ -8,6 +8,7 @@ import com.management.platform.mapper.AttendanceStaffMapper;
|
|
import com.management.platform.service.*;
|
|
import com.management.platform.service.*;
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
import com.management.platform.util.HttpRespMsg;
|
|
import com.management.platform.util.HttpRespMsg;
|
|
|
|
+import com.management.platform.util.WorkDayCalculateUtils;
|
|
import org.apache.commons.lang3.StringUtils;
|
|
import org.apache.commons.lang3.StringUtils;
|
|
import org.springframework.beans.BeanUtils;
|
|
import org.springframework.beans.BeanUtils;
|
|
import org.springframework.scheduling.annotation.Async;
|
|
import org.springframework.scheduling.annotation.Async;
|
|
@@ -99,11 +100,6 @@ public class AttendanceStaffServiceImpl extends ServiceImpl<AttendanceStaffMappe
|
|
Attendance attendance = attendances.get(0);
|
|
Attendance attendance = attendances.get(0);
|
|
//遍历本月的日期,根据考勤记录,确定考勤的上班打卡时间,下班打卡时间,上班时间, 班次类型:白班,中班,小夜班,大夜班
|
|
//遍历本月的日期,根据考勤记录,确定考勤的上班打卡时间,下班打卡时间,上班时间, 班次类型:白班,中班,小夜班,大夜班
|
|
for (LocalDate date : localDates) {
|
|
for (LocalDate date : localDates) {
|
|
-
|
|
|
|
- int year = date.getYear();
|
|
|
|
- int monthValue = date.getMonthValue();
|
|
|
|
- int dayValue = date.getDayOfMonth();
|
|
|
|
-
|
|
|
|
AttendanceStaff staff = new AttendanceStaff();
|
|
AttendanceStaff staff = new AttendanceStaff();
|
|
staff.setJobNumber(jobNumber);
|
|
staff.setJobNumber(jobNumber);
|
|
staff.setMonth(month);
|
|
staff.setMonth(month);
|
|
@@ -146,15 +142,14 @@ public class AttendanceStaffServiceImpl extends ServiceImpl<AttendanceStaffMappe
|
|
.collect(Collectors.toList());
|
|
.collect(Collectors.toList());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
//加班申请
|
|
//加班申请
|
|
else if (applyForm.getType()==4){
|
|
else if (applyForm.getType()==4){
|
|
//加班以实际打卡的时间和时长为准
|
|
//加班以实际打卡的时间和时长为准
|
|
List<Attendance> dayAttendance = attendances.stream().filter(a -> a.getClockTime().toLocalDate().equals(date)).collect(Collectors.toList());
|
|
List<Attendance> dayAttendance = attendances.stream().filter(a -> a.getClockTime().toLocalDate().equals(date)).collect(Collectors.toList());
|
|
- if (jobNumber.equals("LEW3469") && date.equals(LocalDate.of(2025, 8, 9))) {
|
|
|
|
- System.out.println("打卡数据====");
|
|
|
|
- dayAttendance.forEach(System.out::println);
|
|
|
|
- }
|
|
|
|
|
|
+ //7点之前的算是前一天的打卡时间
|
|
|
|
+ dayAttendance = dayAttendance.stream().filter(a->a.getClockTime().toLocalTime().isAfter(LocalTime.of(7,0)))
|
|
|
|
+ .sorted(Comparator.comparing(Attendance::getClockTime))
|
|
|
|
+ .collect(Collectors.toList());
|
|
if (dayAttendance.size() > 0) {
|
|
if (dayAttendance.size() > 0) {
|
|
if (dayAttendance.size() == 1) {
|
|
if (dayAttendance.size() == 1) {
|
|
staff.setClockStartTime(dayAttendance.get(0).getClockTime());
|
|
staff.setClockStartTime(dayAttendance.get(0).getClockTime());
|
|
@@ -164,19 +159,36 @@ public class AttendanceStaffServiceImpl extends ServiceImpl<AttendanceStaffMappe
|
|
staff.setAttendanceTypeName("班次异常");
|
|
staff.setAttendanceTypeName("班次异常");
|
|
} else {
|
|
} else {
|
|
//取上下班时间;按时间排序后取第一个和最后一个时间
|
|
//取上下班时间;按时间排序后取第一个和最后一个时间
|
|
- attendances = attendances.stream()
|
|
|
|
- .sorted(Comparator.comparing(Attendance::getClockTime))
|
|
|
|
- .collect(Collectors.toList());
|
|
|
|
- LocalDateTime startClockTime = dayAttendance.get(0).getClockTime();
|
|
|
|
- LocalDateTime endClockTime = dayAttendance.get(dayAttendance.size() - 1).getClockTime();
|
|
|
|
- staff.setClockStartTime(startClockTime);
|
|
|
|
- staff.setClockEndTime(endClockTime);
|
|
|
|
- BigDecimal bigDecimal = calculateWorkHours(startClockTime, endClockTime);
|
|
|
|
- staff.setWorkHour(bigDecimal.compareTo(new BigDecimal(0)) > 0 ? bigDecimal : new BigDecimal(0));
|
|
|
|
- staff.setAttendanceType(JIA_BAN);
|
|
|
|
- staff.setAttendanceTypeName("加班");
|
|
|
|
|
|
+ if (attendances.size() > 0) {
|
|
|
|
+ LocalDateTime startClockTime = dayAttendance.get(0).getClockTime();
|
|
|
|
+ LocalDateTime endClockTime = dayAttendance.get(dayAttendance.size() - 1).getClockTime();
|
|
|
|
+ //加班申请的结束时间如果是凌晨,以该时间为结束时间
|
|
|
|
+ LocalTime endLocalTime = applyForm.getEndTime().toLocalTime();
|
|
|
|
+ if (applyForm.getEndTime().toLocalDate().equals(date.plusDays(1)) && endLocalTime.getHour() == 0 && endLocalTime.getMinute() == 0) {
|
|
|
|
+ endClockTime = applyForm.getEndTime();
|
|
|
|
+ }
|
|
|
|
+ staff.setClockStartTime(startClockTime);
|
|
|
|
+ staff.setClockEndTime(endClockTime);
|
|
|
|
+ AttendanceStaff workType = getWorkTimeType(ruleList, dayAttendance);
|
|
|
|
+ if (workType == null) {
|
|
|
|
+ //打印dayAttendance
|
|
|
|
+ System.out.println("上班时间为:" + startClockTime + "下班时间为:" + endClockTime);
|
|
|
|
+ //算异常了
|
|
|
|
+ staff.setWorkHour(new BigDecimal(0));
|
|
|
|
+ staff.setAttendanceType(YI_CHANG);
|
|
|
|
+ staff.setAttendanceTypeName("班次异常");
|
|
|
|
+ continue;
|
|
|
|
+ } else {
|
|
|
|
+ BigDecimal bigDecimal = calculateWorkHours(startClockTime, endClockTime, workType.getAttendanceType());
|
|
|
|
+ staff.setWorkHour(bigDecimal.compareTo(new BigDecimal(0)) > 0 ? bigDecimal : new BigDecimal(0));
|
|
|
|
+ staff.setAttendanceType(workType.getAttendanceType());
|
|
|
|
+ staff.setAttendanceTypeName("加班");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (staff.getClockStartTime() != null) {
|
|
|
|
+ addList.add(staff);
|
|
}
|
|
}
|
|
- addList.add(staff);
|
|
|
|
}
|
|
}
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
@@ -270,223 +282,83 @@ public class AttendanceStaffServiceImpl extends ServiceImpl<AttendanceStaffMappe
|
|
.sorted(Comparator.comparing(Attendance::getClockTime))
|
|
.sorted(Comparator.comparing(Attendance::getClockTime))
|
|
.collect(Collectors.toList());
|
|
.collect(Collectors.toList());
|
|
}
|
|
}
|
|
-
|
|
|
|
- AttendanceRule baiBanRule = ruleList.get(0);
|
|
|
|
- AttendanceRule yichangBaiBan1Rule = ruleList.get(1);
|
|
|
|
- AttendanceRule yichangBaiBan2Rule = ruleList.get(2);
|
|
|
|
- AttendanceRule zhongBanRule = ruleList.get(3);
|
|
|
|
- AttendanceRule xiaoyeBan1Rule = ruleList.get(4);
|
|
|
|
- AttendanceRule xiaoyeBan2Rule = ruleList.get(5);
|
|
|
|
- AttendanceRule dayeBanRule = ruleList.get(6);
|
|
|
|
- AttendanceRule yichangxiaoyeBan1Rule = ruleList.get(7);
|
|
|
|
- AttendanceRule yichangxiaoyeBan2Rule = ruleList.get(8);
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- //早班上下班时间判断
|
|
|
|
- Optional<Attendance> zaoShangCount = attendances.stream().filter(a ->!a.getClockTime().isBefore(LocalDateTime.of(year, monthValue, dayValue, baiBanRule.getBeginWorkStartTime().getHour(),baiBanRule.getBeginWorkStartTime().getMinute()))
|
|
|
|
- &&!a.getClockTime().isAfter(LocalDateTime.of(year, monthValue, dayValue, baiBanRule.getBeginWorkEndTime().getHour(), baiBanRule.getBeginWorkEndTime().getMinute()))
|
|
|
|
- ).findFirst();
|
|
|
|
- Optional<Attendance> zaoXiaCount = attendances.stream().filter(a -> !a.getClockTime().isBefore(LocalDateTime.of(year, monthValue, dayValue, baiBanRule.getEndWorkStartTime().getHour(), baiBanRule.getEndWorkStartTime().getMinute()))
|
|
|
|
- && !a.getClockTime().isAfter(LocalDateTime.of(year, monthValue, dayValue, baiBanRule.getEndWorkEndTime().getHour(), baiBanRule.getEndWorkEndTime().getMinute()))
|
|
|
|
- ).max(Comparator.comparing(Attendance::getClockTime));
|
|
|
|
- //异常早班1时间判断
|
|
|
|
- Optional<Attendance> zaoShangYiChang1Count = attendances.stream().filter(a -> !a.getClockTime().isBefore(LocalDateTime.of(year, monthValue, dayValue, yichangBaiBan1Rule.getBeginWorkStartTime().getHour(),yichangBaiBan1Rule.getBeginWorkStartTime().getMinute()))
|
|
|
|
- && !a.getClockTime().isAfter(LocalDateTime.of(year, monthValue, dayValue, yichangBaiBan1Rule.getBeginWorkEndTime().getHour(), yichangBaiBan1Rule.getBeginWorkEndTime().getMinute()))
|
|
|
|
- ).findFirst();
|
|
|
|
- Optional<Attendance> zaoXiaYiChang1Count = attendances.stream().filter(a -> !a.getClockTime().isBefore(LocalDateTime.of(year, monthValue, dayValue, yichangBaiBan1Rule.getEndWorkStartTime().getHour(), yichangBaiBan1Rule.getEndWorkStartTime().getMinute()))
|
|
|
|
- && !a.getClockTime().isAfter(LocalDateTime.of(year, monthValue, dayValue, yichangBaiBan1Rule.getEndWorkEndTime().getHour(), yichangBaiBan1Rule.getEndWorkEndTime().getMinute())))
|
|
|
|
- .max(Comparator.comparing(Attendance::getClockTime));
|
|
|
|
-
|
|
|
|
- //异常早班2时间判断
|
|
|
|
- Optional<Attendance> zaoShangYiChang2Count = attendances.stream().filter(a -> !a.getClockTime().isBefore(LocalDateTime.of(year, monthValue, dayValue, yichangBaiBan2Rule.getBeginWorkStartTime().getHour(),yichangBaiBan2Rule.getBeginWorkStartTime().getMinute()))
|
|
|
|
- && !a.getClockTime().isAfter(LocalDateTime.of(year, monthValue, dayValue, yichangBaiBan2Rule.getBeginWorkEndTime().getHour(), yichangBaiBan2Rule.getBeginWorkEndTime().getMinute()))
|
|
|
|
- ).findFirst();
|
|
|
|
- Optional<Attendance> zaoXiaYiChang2Count = attendances.stream().filter(a -> !a.getClockTime().isBefore(LocalDateTime.of(year, monthValue, dayValue, yichangBaiBan2Rule.getEndWorkStartTime().getHour(), yichangBaiBan2Rule.getEndWorkStartTime().getMinute()))
|
|
|
|
- && !a.getClockTime().isAfter(LocalDateTime.of(year, monthValue, dayValue, yichangBaiBan2Rule.getEndWorkEndTime().getHour(), yichangBaiBan2Rule.getEndWorkEndTime().getMinute()))
|
|
|
|
- ).max(Comparator.comparing(Attendance::getClockTime));
|
|
|
|
-
|
|
|
|
- //中班上下班时间判断
|
|
|
|
- Optional<Attendance> zhongShangCount = attendances.stream().filter(a -> !a.getClockTime().isBefore(LocalDateTime.of(year, monthValue, dayValue, zhongBanRule.getBeginWorkStartTime().getHour(), zhongBanRule.getBeginWorkStartTime().getMinute()))
|
|
|
|
- && !a.getClockTime().isAfter(LocalDateTime.of(year, monthValue, dayValue, zhongBanRule.getBeginWorkEndTime().getHour(), zhongBanRule.getBeginWorkEndTime().getMinute()))
|
|
|
|
- ).findFirst();
|
|
|
|
-
|
|
|
|
- Optional<Attendance> zhongXiaCount = attendances.stream().filter(a -> !a.getClockTime().isBefore(LocalDateTime.of(year, monthValue, dayValue, zhongBanRule.getEndWorkStartTime().getHour(), zhongBanRule.getEndWorkStartTime().getMinute()))
|
|
|
|
- && !a.getClockTime().isAfter(LocalDateTime.of(year, monthValue, dayValue, zhongBanRule.getEndWorkEndTime().getHour(), zhongBanRule.getEndWorkEndTime().getMinute()))
|
|
|
|
- ).max(Comparator.comparing(Attendance::getClockTime));
|
|
|
|
- //小夜班(1)上下班时间判断
|
|
|
|
- Optional<Attendance> xiaoYeShangCount = attendances.stream().filter(a -> !a.getClockTime().isBefore(LocalDateTime.of(year, monthValue, dayValue, xiaoyeBan1Rule.getBeginWorkStartTime().getHour(), xiaoyeBan1Rule.getBeginWorkStartTime().getMinute()))
|
|
|
|
- && !a.getClockTime().isAfter(LocalDateTime.of(year, monthValue, dayValue, xiaoyeBan1Rule.getBeginWorkEndTime().getHour(), xiaoyeBan1Rule.getBeginWorkEndTime().getMinute()))
|
|
|
|
- ).findFirst();
|
|
|
|
-
|
|
|
|
- boolean isLastDay = endDate.isEqual(LocalDate.of(year, monthValue, dayValue));//是否是该月份最后一天
|
|
|
|
- Optional<Attendance> xiaoYeXiaCount = isLastDay ?
|
|
|
|
- attendances.stream().filter(a -> !a.getClockTime().isBefore(LocalDateTime.of(year, monthValue, dayValue, xiaoyeBan1Rule.getEndWorkStartTime().getHour(), xiaoyeBan1Rule.getEndWorkStartTime().getMinute()))
|
|
|
|
- && !a.getClockTime().isAfter(LocalDateTime.of(year, monthValue+1, 1, xiaoyeBan1Rule.getEndWorkEndTime().getHour(), xiaoyeBan1Rule.getEndWorkEndTime().getMinute()))
|
|
|
|
- ).max(Comparator.comparing(Attendance::getClockTime)):
|
|
|
|
- attendances.stream().filter(a -> !a.getClockTime().isBefore(LocalDateTime.of(year, monthValue, dayValue, xiaoyeBan1Rule.getEndWorkStartTime().getHour(), xiaoyeBan1Rule.getEndWorkStartTime().getMinute()))
|
|
|
|
- && !a.getClockTime().isAfter(LocalDateTime.of(year, monthValue, dayValue+1, xiaoyeBan1Rule.getEndWorkEndTime().getHour(), xiaoyeBan1Rule.getEndWorkEndTime().getMinute()))
|
|
|
|
- ).max(Comparator.comparing(Attendance::getClockTime));
|
|
|
|
-
|
|
|
|
- //小夜班(2)上下班时间判断
|
|
|
|
- Optional<Attendance> xiaoYeShang2Count = attendances.stream().filter(a -> !a.getClockTime().isBefore(LocalDateTime.of(year, monthValue, dayValue, xiaoyeBan2Rule.getBeginWorkStartTime().getHour(), xiaoyeBan2Rule.getBeginWorkStartTime().getMinute()))
|
|
|
|
- && !a.getClockTime().isAfter(LocalDateTime.of(year, monthValue, dayValue, xiaoyeBan2Rule.getBeginWorkEndTime().getHour(), xiaoyeBan2Rule.getBeginWorkEndTime().getMinute()))
|
|
|
|
- ).findFirst();
|
|
|
|
- Optional<Attendance> xiaoYeXia2Count = isLastDay ?
|
|
|
|
- attendances.stream().filter(a -> !a.getClockTime().isBefore(LocalDateTime.of(year, monthValue, dayValue, xiaoyeBan2Rule.getEndWorkStartTime().getHour(), xiaoyeBan2Rule.getEndWorkStartTime().getMinute()))
|
|
|
|
- && !a.getClockTime().isAfter(LocalDateTime.of(year, monthValue+1, 1, xiaoyeBan2Rule.getEndWorkEndTime().getHour(), xiaoyeBan2Rule.getEndWorkEndTime().getMinute()))
|
|
|
|
- ).max(Comparator.comparing(Attendance::getClockTime)):
|
|
|
|
- attendances.stream().filter(a -> !a.getClockTime().isBefore(LocalDateTime.of(year, monthValue, dayValue, xiaoyeBan2Rule.getEndWorkStartTime().getHour(), xiaoyeBan2Rule.getEndWorkStartTime().getMinute()))
|
|
|
|
- && !a.getClockTime().isAfter(LocalDateTime.of(year, monthValue, dayValue+1, xiaoyeBan2Rule.getEndWorkEndTime().getHour(), xiaoyeBan2Rule.getEndWorkEndTime().getMinute()))
|
|
|
|
- ).max(Comparator.comparing(Attendance::getClockTime));
|
|
|
|
-
|
|
|
|
- //异常小夜班(1)上下班时间判断
|
|
|
|
- Optional<Attendance> xiaoYeShangYiChang1Count = attendances.stream().filter(a -> !a.getClockTime().isBefore(LocalDateTime.of(year, monthValue, dayValue, yichangxiaoyeBan1Rule.getBeginWorkStartTime().getHour(), yichangxiaoyeBan1Rule.getBeginWorkStartTime().getMinute()))
|
|
|
|
- && !a.getClockTime().isAfter(LocalDateTime.of(year, monthValue, dayValue, yichangxiaoyeBan1Rule.getBeginWorkEndTime().getHour(), yichangxiaoyeBan1Rule.getBeginWorkEndTime().getMinute()))
|
|
|
|
- ).findFirst();
|
|
|
|
- Optional<Attendance> xiaoYeXiaYiChang1Count =attendances.stream().filter(a -> !a.getClockTime().isBefore(LocalDateTime.of(year, monthValue, dayValue, yichangxiaoyeBan1Rule.getEndWorkStartTime().getHour(), yichangxiaoyeBan1Rule.getEndWorkStartTime().getMinute()))
|
|
|
|
- && !a.getClockTime().isAfter(LocalDateTime.of(year, monthValue, dayValue, yichangxiaoyeBan1Rule.getEndWorkEndTime().getHour(), yichangxiaoyeBan1Rule.getEndWorkEndTime().getMinute()))).max(Comparator.comparing(Attendance::getClockTime));
|
|
|
|
-
|
|
|
|
- //异常小夜班(2)上下班时间判断
|
|
|
|
- Optional<Attendance> xiaoYeShangYiChang2Count = attendances.stream().filter(a -> !a.getClockTime().isBefore(LocalDateTime.of(year, monthValue, dayValue, yichangxiaoyeBan2Rule.getBeginWorkStartTime().getHour(), yichangxiaoyeBan2Rule.getBeginWorkStartTime().getMinute()))
|
|
|
|
- && !a.getClockTime().isAfter(LocalDateTime.of(year, monthValue, dayValue, yichangxiaoyeBan2Rule.getBeginWorkEndTime().getHour(), yichangxiaoyeBan2Rule.getBeginWorkEndTime().getMinute()))
|
|
|
|
- ).findFirst();
|
|
|
|
- Optional<Attendance> xiaoYeXiaYiChang2Count =isLastDay ?
|
|
|
|
- attendances.stream().filter(a -> !a.getClockTime().isBefore(LocalDateTime.of(year, monthValue, dayValue, yichangxiaoyeBan2Rule.getEndWorkStartTime().getHour(), yichangxiaoyeBan2Rule.getEndWorkStartTime().getMinute()))
|
|
|
|
- && !a.getClockTime().isAfter(LocalDateTime.of(year, monthValue+1, 1, yichangxiaoyeBan2Rule.getEndWorkEndTime().getHour(), yichangxiaoyeBan2Rule.getEndWorkEndTime().getMinute()))).max(Comparator.comparing(Attendance::getClockTime))
|
|
|
|
- :
|
|
|
|
- attendances.stream().filter(a -> !a.getClockTime().isBefore(LocalDateTime.of(year, monthValue, dayValue, yichangxiaoyeBan2Rule.getEndWorkStartTime().getHour(), yichangxiaoyeBan2Rule.getEndWorkStartTime().getMinute()))
|
|
|
|
- && !a.getClockTime().isAfter(LocalDateTime.of(year, monthValue, dayValue+1, yichangxiaoyeBan2Rule.getEndWorkEndTime().getHour(), yichangxiaoyeBan2Rule.getEndWorkEndTime().getMinute()))).max(Comparator.comparing(Attendance::getClockTime));
|
|
|
|
-
|
|
|
|
- //大夜班上下班时间判断
|
|
|
|
- Optional<Attendance> daYeShangCount =isLastDay ?
|
|
|
|
- attendances.stream().filter(a -> !a.getClockTime().isBefore(LocalDateTime.of(year, monthValue, dayValue, dayeBanRule.getBeginWorkStartTime().getHour(), dayeBanRule.getBeginWorkStartTime().getMinute()))
|
|
|
|
- && !a.getClockTime().isAfter(LocalDateTime.of(year, monthValue+1, 1, dayeBanRule.getBeginWorkEndTime().getHour(), dayeBanRule.getBeginWorkEndTime().getMinute()))
|
|
|
|
- ).findFirst():
|
|
|
|
- attendances.stream().filter(a ->!a.getClockTime().isBefore(LocalDateTime.of(year, monthValue, dayValue, dayeBanRule.getBeginWorkStartTime().getHour(), dayeBanRule.getBeginWorkStartTime().getMinute()))
|
|
|
|
- && !a.getClockTime().isAfter(LocalDateTime.of(year, monthValue, dayValue+1, dayeBanRule.getBeginWorkEndTime().getHour(), dayeBanRule.getBeginWorkEndTime().getMinute()))
|
|
|
|
- ).findFirst();
|
|
|
|
-
|
|
|
|
- Optional<Attendance> daYeXiaCount =isLastDay ?
|
|
|
|
- attendances.stream().filter(a -> !a.getClockTime().isBefore(LocalDateTime.of(year, monthValue+1, 1, dayeBanRule.getEndWorkStartTime().getHour(), dayeBanRule.getEndWorkStartTime().getMinute()))
|
|
|
|
- && !a.getClockTime().isAfter(LocalDateTime.of(year, monthValue+1, 1, dayeBanRule.getEndWorkEndTime().getHour(), dayeBanRule.getEndWorkEndTime().getMinute()))
|
|
|
|
- ).max(Comparator.comparing(Attendance::getClockTime)):
|
|
|
|
- attendances.stream().filter(a -> !a.getClockTime().isBefore(LocalDateTime.of(year, monthValue, dayValue+1, dayeBanRule.getEndWorkStartTime().getHour(), dayeBanRule.getEndWorkStartTime().getMinute()))
|
|
|
|
- && !a.getClockTime().isAfter(LocalDateTime.of(year, monthValue, dayValue+1, dayeBanRule.getEndWorkEndTime().getHour(), dayeBanRule.getEndWorkEndTime().getMinute()))
|
|
|
|
- ).max(Comparator.comparing(Attendance::getClockTime));
|
|
|
|
-
|
|
|
|
- //当天只有一次打卡的情况,为班次异常
|
|
|
|
- boolean onlyOnce = attendances.stream().filter(a->a.getClockTime().toLocalDate().isEqual(date)).count() == 1;
|
|
|
|
- if (onlyOnce) {
|
|
|
|
- //仅仅一次打卡,为异常班次
|
|
|
|
- attendances.stream().filter(a->a.getClockTime().toLocalDate().isEqual(date)).findFirst().ifPresent(a->{
|
|
|
|
- LocalDateTime time = a.getClockTime();
|
|
|
|
- staff.setClockStartTime(time);
|
|
|
|
- staff.setAttendanceType(YI_CHANG);
|
|
|
|
- staff.setAttendanceTypeName("班次异常");
|
|
|
|
- staff.setWorkHour(new BigDecimal(0));
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- //1先判断白班
|
|
|
|
- if (zaoShangCount.isPresent()&&zaoXiaCount.isPresent()) {
|
|
|
|
- LocalDateTime startClockTime = zaoShangCount.get().getClockTime();
|
|
|
|
- LocalDateTime endClockTime = zaoXiaCount.get().getClockTime();
|
|
|
|
- staff.setClockStartTime(startClockTime);
|
|
|
|
- staff.setClockEndTime(endClockTime);
|
|
|
|
- BigDecimal bigDecimal = calculateWorkHours(startClockTime, endClockTime);
|
|
|
|
- staff.setWorkHour(bigDecimal);
|
|
|
|
- staff.setAttendanceType(BAI_BAN);
|
|
|
|
- staff.setAttendanceTypeName("白班");
|
|
|
|
- }
|
|
|
|
- //异常白班1
|
|
|
|
- else if (zaoShangYiChang1Count.isPresent()&&zaoXiaYiChang1Count.isPresent()) {
|
|
|
|
- LocalDateTime startClockTime = zaoShangYiChang1Count.get().getClockTime();
|
|
|
|
- LocalDateTime endClockTime = zaoXiaYiChang1Count.get().getClockTime();
|
|
|
|
- staff.setClockStartTime(startClockTime);
|
|
|
|
- staff.setClockEndTime(endClockTime);
|
|
|
|
- BigDecimal bigDecimal = calculateWorkHours(startClockTime, endClockTime);
|
|
|
|
- staff.setWorkHour(bigDecimal);
|
|
|
|
- staff.setAttendanceType(BAI_BAN_YI_CHANG_1);
|
|
|
|
- staff.setAttendanceTypeName("异常白班1");
|
|
|
|
- }
|
|
|
|
- //异常白班2
|
|
|
|
- else if (zaoShangYiChang2Count.isPresent()&&zaoXiaYiChang2Count.isPresent()) {
|
|
|
|
- LocalDateTime startClockTime = zaoShangYiChang2Count.get().getClockTime();
|
|
|
|
- LocalDateTime endClockTime = zaoXiaYiChang2Count.get().getClockTime();
|
|
|
|
- staff.setClockStartTime(startClockTime);
|
|
|
|
- staff.setClockEndTime(endClockTime);
|
|
|
|
- BigDecimal bigDecimal = calculateWorkHours(startClockTime, endClockTime);
|
|
|
|
- staff.setWorkHour(bigDecimal);
|
|
|
|
- staff.setAttendanceType(BAI_BAN_YI_CHANG_2);
|
|
|
|
- staff.setAttendanceTypeName("异常白班2");
|
|
|
|
- }
|
|
|
|
- //2再判断中班
|
|
|
|
- else if (zhongShangCount.isPresent()&&zhongXiaCount.isPresent()) {
|
|
|
|
- LocalDateTime startClockTime = zhongShangCount.get().getClockTime();
|
|
|
|
- LocalDateTime endClockTime = zhongXiaCount.get().getClockTime();
|
|
|
|
- staff.setClockStartTime(startClockTime);
|
|
|
|
- staff.setClockEndTime(endClockTime);
|
|
|
|
- BigDecimal bigDecimal = calculateWorkHours(startClockTime, endClockTime);
|
|
|
|
- staff.setWorkHour(bigDecimal);
|
|
|
|
- staff.setAttendanceType(ZHONG_BAN);
|
|
|
|
- staff.setAttendanceTypeName("中班");
|
|
|
|
- }
|
|
|
|
- //3判断小夜班
|
|
|
|
- else if (xiaoYeShangCount.isPresent()&&xiaoYeXiaCount.isPresent()) {
|
|
|
|
- LocalDateTime startClockTime = xiaoYeShangCount.get().getClockTime();
|
|
|
|
- LocalDateTime endClockTime = xiaoYeXiaCount.get().getClockTime();
|
|
|
|
- staff.setClockStartTime(startClockTime);
|
|
|
|
- staff.setClockEndTime(endClockTime);
|
|
|
|
- BigDecimal bigDecimal = calculateWorkHours(startClockTime, endClockTime);
|
|
|
|
- staff.setWorkHour(bigDecimal);
|
|
|
|
- staff.setAttendanceType(XIAO_YE_BAN);
|
|
|
|
- staff.setAttendanceTypeName("小夜班");
|
|
|
|
- }
|
|
|
|
- //3判断小夜班2
|
|
|
|
- else if (xiaoYeShang2Count.isPresent()&&xiaoYeXia2Count.isPresent()) {
|
|
|
|
- LocalDateTime startClockTime = xiaoYeShang2Count.get().getClockTime();
|
|
|
|
- LocalDateTime endClockTime = xiaoYeXia2Count.get().getClockTime();
|
|
|
|
- staff.setClockStartTime(startClockTime);
|
|
|
|
- staff.setClockEndTime(endClockTime);
|
|
|
|
- BigDecimal bigDecimal = calculateWorkHours(startClockTime, endClockTime);
|
|
|
|
- staff.setWorkHour(bigDecimal);
|
|
|
|
- staff.setAttendanceType(XIAO_YE_BAN_2);
|
|
|
|
- staff.setAttendanceTypeName("小夜班");
|
|
|
|
|
|
+ //计算当天上班的时间,用于判断班次类型
|
|
|
|
+ List<Attendance> curDateAttendances = attendances.stream().filter(a->a.getClockTime().toLocalDate().equals(date)).collect(Collectors.toList());
|
|
|
|
+ //夜班的话,下班时间是第二天
|
|
|
|
+ List<Attendance> nextDateAttendances = attendances.stream().filter(a->a.getClockTime().toLocalDate().equals(date.plusDays(1))).collect(Collectors.toList());
|
|
|
|
+// if (!WorkDayCalculateUtils.isWorkDay(date)) {
|
|
|
|
+// if (curDateAttendances.size() > 0) {
|
|
|
|
+// //全天加班的情况,只算加班
|
|
|
|
+// staff.setAttendanceType(JIA_BAN);
|
|
|
|
+// staff.setAttendanceTypeName("加班");
|
|
|
|
+//
|
|
|
|
+// //7点以后,最早的时间算是上班时间
|
|
|
|
+// curDateAttendances.stream().filter(a->a.getClockTime().toLocalTime().isAfter(LocalTime.of(7, 0))).findFirst()
|
|
|
|
+// .ifPresent(a->staff.setClockStartTime(a.getClockTime()));
|
|
|
|
+// if (staff.getClockStartTime() != null) {
|
|
|
|
+// staff.setClockEndTime(curDateAttendances.stream().max(Comparator.comparing(Attendance::getClockTime)).get().getClockTime());
|
|
|
|
+// //计算加班时长
|
|
|
|
+// BigDecimal bigDecimal = calculateWorkHours(staff.getClockStartTime(), staff.getClockEndTime(), true);//周末以半小时为一个单位,不足半小时舍去
|
|
|
|
+// staff.setWorkHour(bigDecimal);
|
|
|
|
+// }
|
|
|
|
+// if (jobNumber.equals("LEW3055") && date.equals(LocalDate.of(2025, 8, 2))) {
|
|
|
|
+// System.out.println("刘友飞, 8-2日:"+staff.getWorkHour());
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+// } else
|
|
|
|
+ {
|
|
|
|
+ AttendanceStaff workTimeType = getWorkTimeType(ruleList, curDateAttendances);
|
|
|
|
+ if (workTimeType != null) {
|
|
|
|
+ staff.setClockStartTime(workTimeType.getClockStartTime());
|
|
|
|
+ staff.setAttendanceType(workTimeType.getAttendanceType());
|
|
|
|
+ ruleList.stream().filter(r -> r.getId().intValue() == workTimeType.getAttendanceType().intValue()).findFirst().ifPresent(r -> staff.setAttendanceTypeName(r.getName()));
|
|
|
|
+ //白班或者异常小夜班,下班时间是当天
|
|
|
|
+ LocalDateTime endClockTime = null;
|
|
|
|
+ if (workTimeType.getAttendanceType() == JIA_BAN) {
|
|
|
|
+ curDateAttendances.stream().filter(a->a.getClockTime().toLocalTime().isAfter(LocalTime.of(7, 0))).findFirst()
|
|
|
|
+ .ifPresent(a->staff.setClockStartTime(a.getClockTime()));
|
|
|
|
+ if (staff.getClockStartTime() != null) {
|
|
|
|
+ endClockTime = curDateAttendances.stream().max(Comparator.comparing(Attendance::getClockTime)).get().getClockTime();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else if (workTimeType.getAttendanceType().intValue() == BAI_BAN || workTimeType.getAttendanceType().intValue() == BAI_BAN_YI_CHANG_1 || workTimeType.getAttendanceType().intValue() == BAI_BAN_YI_CHANG_2 ||
|
|
|
|
+ workTimeType.getAttendanceType().intValue() == ZHONG_BAN || workTimeType.getAttendanceType().intValue() == XIAO_YE_BAN_YI_CHANG_1 || workTimeType.getAttendanceType().intValue() == XIAO_YE_BAN_YI_CHANG_2) {
|
|
|
|
+ endClockTime = curDateAttendances.stream().max(Comparator.comparing(Attendance::getClockTime)).get().getClockTime();
|
|
|
|
+ } else {
|
|
|
|
+ //夜班,取第二天9:59点前的时间作为下班时间
|
|
|
|
+
|
|
|
|
+ //第二日的加班申请单,看看有没有
|
|
|
|
+// List<ApplyForm> nextDayApplyFormList = applyFormList.stream().filter(a->a.getApplyId().equals(jobNumber) && a.getType() == 4
|
|
|
|
+// && a.getStartTime().toLocalDate().equals(date) && a.getEndTime().toLocalTime().getHour() <= 9).collect(Collectors.toList());
|
|
|
|
+// if (nextDayApplyFormList.size() > 0) {
|
|
|
|
+// LocalDateTime formEndTime = nextDayApplyFormList.stream().max(Comparator.comparing(ApplyForm::getEndTime)).get().getEndTime();
|
|
|
|
+// //打卡时间结束时间以加班后1小时内为范围
|
|
|
|
+// }
|
|
|
|
+ if (nextDateAttendances.size() > 0) {
|
|
|
|
+ List<Attendance> nextDateAttendances1 = nextDateAttendances.stream().filter(a->a.getClockTime().getHour() <= 9).collect(Collectors.toList());
|
|
|
|
+ if (nextDateAttendances1.size() > 0) {
|
|
|
|
+ endClockTime = nextDateAttendances1.stream().max(Comparator.comparing(Attendance::getClockTime)).get().getClockTime();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ staff.setClockEndTime(endClockTime);
|
|
|
|
+ if (staff.getClockEndTime() == null) {
|
|
|
|
+ staff.setClockEndTime(staff.getClockStartTime());
|
|
|
|
+ }
|
|
|
|
+ //仅仅一次打卡,为异常班次
|
|
|
|
+ if (staff.getClockEndTime().equals(staff.getClockStartTime())) {
|
|
|
|
+ staff.setClockStartTime(staff.getClockStartTime());
|
|
|
|
+ staff.setAttendanceType(YI_CHANG);
|
|
|
|
+ staff.setAttendanceTypeName("班次异常");
|
|
|
|
+ staff.setWorkHour(new BigDecimal(0));
|
|
|
|
+ } else {
|
|
|
|
+ //有上下班打卡时间,计算时长
|
|
|
|
+ BigDecimal bigDecimal = calculateWorkHours(staff.getClockStartTime(), endClockTime, workTimeType.getAttendanceType());
|
|
|
|
+ staff.setWorkHour(bigDecimal);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- //3判断小夜班异常1
|
|
|
|
- else if (xiaoYeShangYiChang1Count.isPresent()&&xiaoYeXiaYiChang1Count.isPresent()) {
|
|
|
|
- LocalDateTime startClockTime = xiaoYeShangYiChang1Count.get().getClockTime();
|
|
|
|
- LocalDateTime endClockTime = xiaoYeXiaYiChang1Count.get().getClockTime();
|
|
|
|
- staff.setClockStartTime(startClockTime);
|
|
|
|
- staff.setClockEndTime(endClockTime);
|
|
|
|
- BigDecimal bigDecimal = calculateWorkHours(startClockTime, endClockTime);
|
|
|
|
- staff.setWorkHour(bigDecimal);
|
|
|
|
- staff.setAttendanceType(XIAO_YE_BAN_YI_CHANG_1);
|
|
|
|
- staff.setAttendanceTypeName("异常小夜班1");
|
|
|
|
|
|
|
|
- }
|
|
|
|
- //3判断小夜班异常2
|
|
|
|
- else if (xiaoYeShangYiChang2Count.isPresent()&&xiaoYeXiaYiChang2Count.isPresent()) {
|
|
|
|
- LocalDateTime startClockTime = xiaoYeShangYiChang2Count.get().getClockTime();
|
|
|
|
- LocalDateTime endClockTime = xiaoYeXiaYiChang2Count.get().getClockTime();
|
|
|
|
- staff.setClockStartTime(startClockTime);
|
|
|
|
- staff.setClockEndTime(endClockTime);
|
|
|
|
- BigDecimal bigDecimal = calculateWorkHours(startClockTime, endClockTime);
|
|
|
|
- staff.setWorkHour(bigDecimal);
|
|
|
|
- staff.setAttendanceType(XIAO_YE_BAN_YI_CHANG_2);
|
|
|
|
- staff.setAttendanceTypeName("异常小夜班2");
|
|
|
|
- }
|
|
|
|
- //4判断大夜班
|
|
|
|
- else if (daYeShangCount.isPresent()&&daYeXiaCount.isPresent()) {
|
|
|
|
- LocalDateTime startClockTime = daYeShangCount.get().getClockTime();
|
|
|
|
- LocalDateTime endClockTime = daYeXiaCount.get().getClockTime();
|
|
|
|
- staff.setClockStartTime(startClockTime);
|
|
|
|
- staff.setClockEndTime(endClockTime);
|
|
|
|
- BigDecimal bigDecimal = calculateWorkHours(startClockTime, endClockTime);
|
|
|
|
- staff.setWorkHour(bigDecimal);
|
|
|
|
- staff.setAttendanceType(DA_YE_BAN);
|
|
|
|
- staff.setAttendanceTypeName("大夜班");
|
|
|
|
- }
|
|
|
|
//过滤掉空数据
|
|
//过滤掉空数据
|
|
if (!StringUtils.isEmpty(staff.getJobNumber()) && (staff.getClockStartTime()!=null || staff.getClockEndTime()!=null)) {
|
|
if (!StringUtils.isEmpty(staff.getJobNumber()) && (staff.getClockStartTime()!=null || staff.getClockEndTime()!=null)) {
|
|
addList.add(staff);
|
|
addList.add(staff);
|
|
@@ -498,6 +370,67 @@ public class AttendanceStaffServiceImpl extends ServiceImpl<AttendanceStaffMappe
|
|
return msg;
|
|
return msg;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ private AttendanceStaff getWorkTimeType(List<AttendanceRule> ruleList, List<Attendance> attendanceList) {
|
|
|
|
+ AttendanceRule baiBanRule = ruleList.get(0);
|
|
|
|
+ AttendanceRule yichangBaiBan1Rule = ruleList.get(1);
|
|
|
|
+ AttendanceRule yichangBaiBan2Rule = ruleList.get(2);
|
|
|
|
+ AttendanceRule zhongBanRule = ruleList.get(3);
|
|
|
|
+ AttendanceRule xiaoyeBan1Rule = ruleList.get(4);
|
|
|
|
+ AttendanceRule xiaoyeBan2Rule = ruleList.get(5);
|
|
|
|
+ AttendanceRule dayeBanRule = ruleList.get(6);
|
|
|
|
+ AttendanceRule yichangxiaoyeBan1Rule = ruleList.get(7);
|
|
|
|
+ AttendanceRule yichangxiaoyeBan2Rule = ruleList.get(8);
|
|
|
|
+ AttendanceStaff staff = new AttendanceStaff();
|
|
|
|
+ for (Attendance attendance : attendanceList) {
|
|
|
|
+ staff.setClockStartTime(attendance.getClockTime());
|
|
|
|
+ //如果是非工作日,就是加班
|
|
|
|
+ if (!WorkDayCalculateUtils.isWorkDay(attendance.getClockTime().toLocalDate())) {
|
|
|
|
+ staff.setAttendanceType(JIA_BAN);
|
|
|
|
+ staff.setAttendanceTypeName("加班");
|
|
|
|
+ return staff;
|
|
|
|
+ }
|
|
|
|
+ LocalTime workTime = attendance.getClockTime().toLocalTime();
|
|
|
|
+ if (!workTime.isBefore(baiBanRule.getBeginWorkStartTime()) && !workTime.isAfter(baiBanRule.getBeginWorkEndTime())) {
|
|
|
|
+ staff.setAttendanceType(BAI_BAN);
|
|
|
|
+ staff.setAttendanceTypeName("白班");
|
|
|
|
+ return staff;
|
|
|
|
+ } else if (!workTime.isBefore(yichangBaiBan1Rule.getBeginWorkStartTime()) && !workTime.isAfter(yichangBaiBan1Rule.getBeginWorkEndTime())) {
|
|
|
|
+ staff.setAttendanceType(BAI_BAN_YI_CHANG_1);
|
|
|
|
+ staff.setAttendanceTypeName("异常白班1");
|
|
|
|
+ return staff;
|
|
|
|
+ } else if (!workTime.isBefore(yichangBaiBan2Rule.getBeginWorkStartTime()) && !workTime.isAfter(yichangBaiBan2Rule.getBeginWorkEndTime())) {
|
|
|
|
+ staff.setAttendanceType(BAI_BAN_YI_CHANG_2);
|
|
|
|
+ staff.setAttendanceTypeName("异常白班2");
|
|
|
|
+ return staff;
|
|
|
|
+ } else if (!workTime.isBefore(zhongBanRule.getBeginWorkStartTime()) && !workTime.isAfter(zhongBanRule.getBeginWorkEndTime())) {
|
|
|
|
+ staff.setAttendanceType(ZHONG_BAN);
|
|
|
|
+ staff.setAttendanceTypeName("中班");
|
|
|
|
+ return staff;
|
|
|
|
+ } else if (!workTime.isBefore(xiaoyeBan1Rule.getBeginWorkStartTime()) && !workTime.isAfter(xiaoyeBan1Rule.getBeginWorkEndTime())) {
|
|
|
|
+ staff.setAttendanceType(XIAO_YE_BAN);
|
|
|
|
+ staff.setAttendanceTypeName("小夜班1");
|
|
|
|
+ return staff;
|
|
|
|
+ } else if (!workTime.isBefore(xiaoyeBan2Rule.getBeginWorkStartTime()) && !workTime.isAfter(xiaoyeBan2Rule.getBeginWorkEndTime())) {
|
|
|
|
+ staff.setAttendanceType(XIAO_YE_BAN_2);
|
|
|
|
+ staff.setAttendanceTypeName("小夜班2");
|
|
|
|
+ return staff;
|
|
|
|
+ } else if (!workTime.isBefore(dayeBanRule.getBeginWorkStartTime()) && !workTime.isAfter(dayeBanRule.getBeginWorkEndTime())) {
|
|
|
|
+ staff.setAttendanceType(DA_YE_BAN);
|
|
|
|
+ staff.setAttendanceTypeName("大夜班");
|
|
|
|
+ return staff;
|
|
|
|
+ } else if (!workTime.isBefore(yichangxiaoyeBan1Rule.getBeginWorkStartTime()) && !workTime.isAfter(yichangxiaoyeBan1Rule.getBeginWorkEndTime())) {
|
|
|
|
+ staff.setAttendanceType(XIAO_YE_BAN_YI_CHANG_1);
|
|
|
|
+ staff.setAttendanceTypeName("异常小夜班1");
|
|
|
|
+ return staff;
|
|
|
|
+ } else if (!workTime.isBefore(yichangxiaoyeBan2Rule.getBeginWorkStartTime()) && !workTime.isAfter(yichangxiaoyeBan2Rule.getBeginWorkEndTime())) {
|
|
|
|
+ staff.setAttendanceType(XIAO_YE_BAN_YI_CHANG_2);
|
|
|
|
+ staff.setAttendanceTypeName("异常小夜班2");
|
|
|
|
+ return staff;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
@Override
|
|
@Override
|
|
public HttpRespMsg getListData(String month,String userId,Integer pageIndex ,Integer pageSize,HttpServletRequest request) {
|
|
public HttpRespMsg getListData(String month,String userId,Integer pageIndex ,Integer pageSize,HttpServletRequest request) {
|
|
HttpRespMsg msg = new HttpRespMsg();
|
|
HttpRespMsg msg = new HttpRespMsg();
|
|
@@ -748,12 +681,12 @@ public class AttendanceStaffServiceImpl extends ServiceImpl<AttendanceStaffMappe
|
|
double v = calculateOvertimeHours(LocalTime.of(17, 0), endTime);
|
|
double v = calculateOvertimeHours(LocalTime.of(17, 0), endTime);
|
|
if (v>0) {
|
|
if (v>0) {
|
|
str += "(17:00:00-" + endTime + "加班" + v + "小时)";
|
|
str += "(17:00:00-" + endTime + "加班" + v + "小时)";
|
|
|
|
+ staff.setHasOverTime(true);
|
|
}
|
|
}
|
|
map.put("msg", str);
|
|
map.put("msg", str);
|
|
maplist.add(map);
|
|
maplist.add(map);
|
|
}
|
|
}
|
|
staff.setAttendanceTypeName("白班");
|
|
staff.setAttendanceTypeName("白班");
|
|
-
|
|
|
|
}
|
|
}
|
|
else if (type == ZHONG_BAN) {
|
|
else if (type == ZHONG_BAN) {
|
|
if (startTime.isAfter(LocalTime.of(13, 0, 0))) {
|
|
if (startTime.isAfter(LocalTime.of(13, 0, 0))) {
|
|
@@ -800,6 +733,7 @@ public class AttendanceStaffServiceImpl extends ServiceImpl<AttendanceStaffMappe
|
|
double v = calculateOvertimeHours(LocalTime.of(21, 0, 0), endTime);
|
|
double v = calculateOvertimeHours(LocalTime.of(21, 0, 0), endTime);
|
|
if (v > 0) {
|
|
if (v > 0) {
|
|
str +="(21:00:00-" + endTime + "加班" + v + "小时)";
|
|
str +="(21:00:00-" + endTime + "加班" + v + "小时)";
|
|
|
|
+ staff.setHasOverTime(true);
|
|
}
|
|
}
|
|
map.put("msg",str );
|
|
map.put("msg",str );
|
|
maplist.add(map);
|
|
maplist.add(map);
|
|
@@ -851,6 +785,7 @@ public class AttendanceStaffServiceImpl extends ServiceImpl<AttendanceStaffMappe
|
|
double v = calculateOvertimeHours(LocalTime.of(0, 0, 0), endTime);
|
|
double v = calculateOvertimeHours(LocalTime.of(0, 0, 0), endTime);
|
|
if (v > 0) {
|
|
if (v > 0) {
|
|
str += "(00:00:00-" + endTime + "加班" + v + "小时)";
|
|
str += "(00:00:00-" + endTime + "加班" + v + "小时)";
|
|
|
|
+ staff.setHasOverTime(true);
|
|
}
|
|
}
|
|
map.put("msg", str);
|
|
map.put("msg", str);
|
|
maplist.add(map);
|
|
maplist.add(map);
|
|
@@ -916,6 +851,7 @@ public class AttendanceStaffServiceImpl extends ServiceImpl<AttendanceStaffMappe
|
|
double v = calculateOvertimeHours(LocalTime.of(1, 0, 0), endTime);
|
|
double v = calculateOvertimeHours(LocalTime.of(1, 0, 0), endTime);
|
|
if (v > 0) {
|
|
if (v > 0) {
|
|
str += "(00:01:00-" + endTime + "加班" + v + "小时)";
|
|
str += "(00:01:00-" + endTime + "加班" + v + "小时)";
|
|
|
|
+ staff.setHasOverTime(true);
|
|
}
|
|
}
|
|
map.put("msg", str);
|
|
map.put("msg", str);
|
|
maplist.add(map);
|
|
maplist.add(map);
|
|
@@ -967,6 +903,7 @@ public class AttendanceStaffServiceImpl extends ServiceImpl<AttendanceStaffMappe
|
|
double v = calculateOvertimeHours(LocalTime.of(8, 0, 0), endTime);
|
|
double v = calculateOvertimeHours(LocalTime.of(8, 0, 0), endTime);
|
|
if (v > 0) {
|
|
if (v > 0) {
|
|
str += "(08:00:00-" + endTime + "加班" + v + "小时)";
|
|
str += "(08:00:00-" + endTime + "加班" + v + "小时)";
|
|
|
|
+ staff.setHasOverTime(true);
|
|
}
|
|
}
|
|
map.put("msg", str);
|
|
map.put("msg", str);
|
|
maplist.add(map);
|
|
maplist.add(map);
|
|
@@ -1018,6 +955,7 @@ public class AttendanceStaffServiceImpl extends ServiceImpl<AttendanceStaffMappe
|
|
double v = calculateOvertimeHours(LocalTime.of(18, 0), endTime);
|
|
double v = calculateOvertimeHours(LocalTime.of(18, 0), endTime);
|
|
if (v>0) {
|
|
if (v>0) {
|
|
str += "(18:00:00-" + endTime + "加班" + v + "小时)";
|
|
str += "(18:00:00-" + endTime + "加班" + v + "小时)";
|
|
|
|
+ staff.setHasOverTime(true);
|
|
}
|
|
}
|
|
map.put("msg", str);
|
|
map.put("msg", str);
|
|
maplist.add(map);
|
|
maplist.add(map);
|
|
@@ -1069,6 +1007,7 @@ public class AttendanceStaffServiceImpl extends ServiceImpl<AttendanceStaffMappe
|
|
double v = calculateOvertimeHours(LocalTime.of(19, 0), endTime);
|
|
double v = calculateOvertimeHours(LocalTime.of(19, 0), endTime);
|
|
if (v>0) {
|
|
if (v>0) {
|
|
str += "(19:00:00-" + endTime + "加班" + v + "小时)";
|
|
str += "(19:00:00-" + endTime + "加班" + v + "小时)";
|
|
|
|
+ staff.setHasOverTime(true);
|
|
}
|
|
}
|
|
map.put("msg", str);
|
|
map.put("msg", str);
|
|
maplist.add(map);
|
|
maplist.add(map);
|
|
@@ -1119,6 +1058,7 @@ public class AttendanceStaffServiceImpl extends ServiceImpl<AttendanceStaffMappe
|
|
double v = calculateOvertimeHours(LocalTime.of(22, 0, 0), endTime);
|
|
double v = calculateOvertimeHours(LocalTime.of(22, 0, 0), endTime);
|
|
if (v > 0) {
|
|
if (v > 0) {
|
|
str += "(22:00:00-" + endTime + "加班" + v + "小时)";
|
|
str += "(22:00:00-" + endTime + "加班" + v + "小时)";
|
|
|
|
+ staff.setHasOverTime(true);
|
|
}
|
|
}
|
|
map.put("msg", str);
|
|
map.put("msg", str);
|
|
maplist.add(map);
|
|
maplist.add(map);
|
|
@@ -1170,6 +1110,7 @@ public class AttendanceStaffServiceImpl extends ServiceImpl<AttendanceStaffMappe
|
|
double v = calculateOvertimeHours(LocalTime.of(23, 0, 0), endTime);
|
|
double v = calculateOvertimeHours(LocalTime.of(23, 0, 0), endTime);
|
|
if (v > 0) {
|
|
if (v > 0) {
|
|
str += "(23:00:00-" + endTime + "加班" + v + "小时)";
|
|
str += "(23:00:00-" + endTime + "加班" + v + "小时)";
|
|
|
|
+ staff.setHasOverTime(true);
|
|
}
|
|
}
|
|
map.put("msg", str);
|
|
map.put("msg", str);
|
|
maplist.add(map);
|
|
maplist.add(map);
|
|
@@ -1181,6 +1122,7 @@ public class AttendanceStaffServiceImpl extends ServiceImpl<AttendanceStaffMappe
|
|
double v = calculateOvertimeHours(LocalTime.of(23, 0, 0), endTime);
|
|
double v = calculateOvertimeHours(LocalTime.of(23, 0, 0), endTime);
|
|
if (v > 0) {
|
|
if (v > 0) {
|
|
str += "(23:00:00-" + endTime + "加班" + v + "小时)";
|
|
str += "(23:00:00-" + endTime + "加班" + v + "小时)";
|
|
|
|
+ staff.setHasOverTime(true);
|
|
}
|
|
}
|
|
map.put("msg", str);
|
|
map.put("msg", str);
|
|
maplist.add(map);
|
|
maplist.add(map);
|
|
@@ -1282,8 +1224,7 @@ public class AttendanceStaffServiceImpl extends ServiceImpl<AttendanceStaffMappe
|
|
}
|
|
}
|
|
|
|
|
|
staff.setMaplist(maplist);
|
|
staff.setMaplist(maplist);
|
|
- }
|
|
|
|
- else {
|
|
|
|
|
|
+ } else {
|
|
List<HashMap<String, Object>> mapList = new ArrayList<>();
|
|
List<HashMap<String, Object>> mapList = new ArrayList<>();
|
|
if (!applyFormList.isEmpty()){
|
|
if (!applyFormList.isEmpty()){
|
|
StringBuilder stringBuilder = new StringBuilder();
|
|
StringBuilder stringBuilder = new StringBuilder();
|
|
@@ -1327,12 +1268,31 @@ public class AttendanceStaffServiceImpl extends ServiceImpl<AttendanceStaffMappe
|
|
HashMap<String, Object> map = new HashMap<>();
|
|
HashMap<String, Object> map = new HashMap<>();
|
|
map.put("res", "未知");
|
|
map.put("res", "未知");
|
|
String str = endStr + "下班考勤打卡:";
|
|
String str = endStr + "下班考勤打卡:";
|
|
- map.put("msg",str );
|
|
|
|
|
|
+ map.put("msg",str);
|
|
map.put("color","#F56C6C");
|
|
map.put("color","#F56C6C");
|
|
mapList.add(map);
|
|
mapList.add(map);
|
|
}
|
|
}
|
|
staff.setMaplist(mapList);
|
|
staff.setMaplist(mapList);
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ //企微加班申请单,要加上显示
|
|
|
|
+ List<ApplyForm> curDateApplyFormList = applyFormList.stream().filter(applyForm -> applyForm.getType() == 4 && applyForm.getStartTime().toLocalDate().isEqual(clockDate)).collect(Collectors.toList());
|
|
|
|
+ if (!curDateApplyFormList.isEmpty()) {
|
|
|
|
+ HashMap<String, Object> map = new HashMap<>();
|
|
|
|
+ StringBuilder stringBuilder = new StringBuilder();
|
|
|
|
+ for (ApplyForm applyForm : curDateApplyFormList) {
|
|
|
|
+ stringBuilder.append("企微申请:"+applyForm.getStartTime().format(formatter2))
|
|
|
|
+ .append("-").append(applyForm.getEndTime().format(formatter2));
|
|
|
|
+ stringBuilder.append(" 时长: ").append(applyForm.getSumTime()).append("小时");
|
|
|
|
+ }
|
|
|
|
+ map.put("res", stringBuilder.toString());
|
|
|
|
+ map.put("color","#FF0000");
|
|
|
|
+ if (staff.getMaplist() == null) {
|
|
|
|
+ staff.setMaplist(new ArrayList<>());
|
|
|
|
+ }
|
|
|
|
+ //加上企微申请数据显示
|
|
|
|
+ staff.getMaplist().add(map);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
msg.setData(allList);
|
|
msg.setData(allList);
|
|
return msg;
|
|
return msg;
|
|
@@ -1416,16 +1376,67 @@ public class AttendanceStaffServiceImpl extends ServiceImpl<AttendanceStaffMappe
|
|
return holidays;
|
|
return holidays;
|
|
}
|
|
}
|
|
|
|
|
|
- public BigDecimal calculateWorkHours(LocalDateTime start, LocalDateTime end) {
|
|
|
|
- // 1. 计算时间差
|
|
|
|
- Duration duration = Duration.between(start, end);
|
|
|
|
|
|
+ public static void main(String[] args) {
|
|
|
|
+ LocalDateTime start = LocalDateTime.of(2025, 1, 1, 7, 47);
|
|
|
|
+ LocalDateTime end = LocalDateTime.of(2025, 1, 1, 15, 32);
|
|
|
|
+// System.out.println(calculateWorkHours(start, end, true,true));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public static BigDecimal calculateWorkHours(LocalDateTime start, LocalDateTime end, int workType) {
|
|
|
|
+ String startTime = start.format(DateTimeFormatter.ofPattern("HH:mm"));
|
|
|
|
+ String endTime = end.format(DateTimeFormatter.ofPattern("HH:mm"));
|
|
|
|
|
|
- // 2. 转换为小时数(double)
|
|
|
|
- double hours = duration.toMinutes() / 60.0;
|
|
|
|
|
|
+ LocalDate startDate = start.toLocalDate();
|
|
|
|
+ boolean isWorkDay = WorkDayCalculateUtils.isWorkDay(startDate);
|
|
|
|
|
|
- // 3. 转换为BigDecimal并四舍五入保留1位小数
|
|
|
|
- return BigDecimal.valueOf(hours)
|
|
|
|
- .setScale(1, RoundingMode.HALF_UP);
|
|
|
|
|
|
+ // 12:00-13:00为午休,中间来的得从下午上班时间开始算
|
|
|
|
+ if (startTime.compareTo("12:00") > 0 && startTime.compareTo("13:00") < 0) {
|
|
|
|
+ startTime = "13:00";
|
|
|
|
+ }
|
|
|
|
+ if (endTime.compareTo("12:00") > 0 && endTime.compareTo("13:00") < 0) {
|
|
|
|
+ endTime = "12:00";
|
|
|
|
+ }
|
|
|
|
+ String[] startParts = startTime.split(":");
|
|
|
|
+ boolean isEndNextDay = end.toLocalDate().isAfter(start.toLocalDate());
|
|
|
|
+ String[] endParts = endTime.split(":");
|
|
|
|
+ int startHour = Integer.parseInt(startParts[0]);
|
|
|
|
+ int startMinute = Integer.parseInt(startParts[1]);
|
|
|
|
+ int endHour = Integer.parseInt(endParts[0]) + (isEndNextDay ? 24 : 0);
|
|
|
|
+ int endMinute = Integer.parseInt(endParts[1]);
|
|
|
|
+ double hours = (endHour - startHour) + (endMinute - startMinute) / 60.0;
|
|
|
|
+ if (isWorkDay) {
|
|
|
|
+ //工作日,白班需要减去休息时间
|
|
|
|
+ if ((workType == BAI_BAN || workType == BAI_BAN_YI_CHANG_1 || workType == BAI_BAN_YI_CHANG_2)) {
|
|
|
|
+ // 减去午休时间(假设12:00-13:00为午休)
|
|
|
|
+ if (startHour <= 12 && endHour >= 13) {
|
|
|
|
+ hours -= 1;
|
|
|
|
+ }
|
|
|
|
+ if (workType == BAI_BAN) {
|
|
|
|
+ //正常白班减去晚休时间,17:30-18:00
|
|
|
|
+ if (startHour <= 17 && endHour >= 18) {
|
|
|
|
+ hours -= 0.5;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ double minPart = hours - (int)hours;
|
|
|
|
+ //始终按0.5小时对齐
|
|
|
|
+ if (minPart > 0 && minPart < 0.5) {
|
|
|
|
+ minPart = 0;
|
|
|
|
+ } else if (minPart > 0.5) {
|
|
|
|
+ minPart = 0.5;
|
|
|
|
+ }
|
|
|
|
+// if (halfUnit) {
|
|
|
|
+//
|
|
|
|
+// } else {
|
|
|
|
+// minPart = hours - (int)hours;
|
|
|
|
+// }
|
|
|
|
+
|
|
|
|
+ hours = (int)hours + minPart;
|
|
|
|
+ //四舍五入到小数点后一位
|
|
|
|
+ BigDecimal bigDecimal = new BigDecimal(hours);
|
|
|
|
+ bigDecimal = bigDecimal.setScale(1, BigDecimal.ROUND_HALF_UP);
|
|
|
|
+ return bigDecimal;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -1437,7 +1448,6 @@ public class AttendanceStaffServiceImpl extends ServiceImpl<AttendanceStaffMappe
|
|
*/
|
|
*/
|
|
public static int calculateOvertimeUnits(LocalTime startTime, LocalTime endTime) {
|
|
public static int calculateOvertimeUnits(LocalTime startTime, LocalTime endTime) {
|
|
Duration workDuration;
|
|
Duration workDuration;
|
|
-
|
|
|
|
// 处理跨午夜情况
|
|
// 处理跨午夜情况
|
|
if (endTime.isBefore(startTime)) {
|
|
if (endTime.isBefore(startTime)) {
|
|
workDuration = Duration.between(startTime, LocalTime.MAX)
|
|
workDuration = Duration.between(startTime, LocalTime.MAX)
|
|
@@ -1445,12 +1455,13 @@ public class AttendanceStaffServiceImpl extends ServiceImpl<AttendanceStaffMappe
|
|
.plusMinutes(1); // 加上午夜这一分钟
|
|
.plusMinutes(1); // 加上午夜这一分钟
|
|
} else {
|
|
} else {
|
|
workDuration = Duration.between(startTime, endTime);
|
|
workDuration = Duration.between(startTime, endTime);
|
|
|
|
+ //如果加班时间段包含17:00-17:30,需要减去半小时
|
|
|
|
+ if (!startTime.isAfter(LocalTime.of(17, 0)) && endTime.isAfter(LocalTime.of(17, 30))) {
|
|
|
|
+ workDuration = workDuration.minus(Duration.between(LocalTime.of(17, 0), LocalTime.of(17, 30)));
|
|
|
|
+ }
|
|
}
|
|
}
|
|
-
|
|
|
|
long totalMinutes = workDuration.toMinutes();
|
|
long totalMinutes = workDuration.toMinutes();
|
|
-
|
|
|
|
if (totalMinutes < 60) return 0;
|
|
if (totalMinutes < 60) return 0;
|
|
-
|
|
|
|
long overtimeMinutes = totalMinutes;
|
|
long overtimeMinutes = totalMinutes;
|
|
return (int) Math.floor(overtimeMinutes / 30.0);
|
|
return (int) Math.floor(overtimeMinutes / 30.0);
|
|
}
|
|
}
|