Browse Source

Merge branch 'master' of http://47.100.37.243:10191/quyueting/manHourHousekeeper

QuYueTing 1 month ago
parent
commit
880cf2c7d4

+ 58 - 9
fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/service/impl/AttendanceStaffServiceImpl.java

@@ -71,6 +71,7 @@ public class AttendanceStaffServiceImpl extends ServiceImpl<AttendanceStaffMappe
         DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM");
         YearMonth yearMonth = YearMonth.parse(month, formatter);
         LocalDate localDate = yearMonth.plusMonths(1).atDay(2);//查询条件
+        LocalDate localDate1 = yearMonth.plusMonths(0).atDay(1);//查询条件
 
         LocalDate startDate = yearMonth.atDay(1);//本月开始日期
         LocalDate endDate = yearMonth.atEndOfMonth();//本月结束日期
@@ -84,7 +85,7 @@ public class AttendanceStaffServiceImpl extends ServiceImpl<AttendanceStaffMappe
         System.out.println("开始获取attendanceData==="+new Date().toString());
         List<Attendance> attendanceList = attendanceService.list(new QueryWrapper<Attendance>()
                 .eq("month", month)
-                .or().le("clock_time", localDate)
+                .or().and(i->i.ge("clock_time",localDate1).le("clock_time", localDate))
                 .orderByAsc("job_number","clock_time"));
         System.out.println("开始获取applyFormList==="+new Date().toString());
         //获取申请单数据
@@ -146,10 +147,7 @@ public class AttendanceStaffServiceImpl extends ServiceImpl<AttendanceStaffMappe
                         else if (applyForm.getType()==4){
                             //加班以实际打卡的时间和时长为准
                             List<Attendance> dayAttendance = attendances.stream().filter(a -> a.getClockTime().toLocalDate().equals(date)).collect(Collectors.toList());
-                            //7点之前的算是前一天的打卡时间
-                            dayAttendance = dayAttendance.stream().filter(a->a.getClockTime().toLocalTime().isAfter(LocalTime.of(7,0)))
-                                    .sorted(Comparator.comparing(Attendance::getClockTime))
-                                    .collect(Collectors.toList());
+                            dayAttendance = resolveDayClockAttendances(date, dayAttendance, attendances);
                             if (dayAttendance.size() > 0) {
                                 if (dayAttendance.size() == 1) {
                                     staff.setClockStartTime(dayAttendance.get(0).getClockTime());
@@ -294,11 +292,12 @@ public class AttendanceStaffServiceImpl extends ServiceImpl<AttendanceStaffMappe
                         //白班或者异常小夜班,下班时间是当天
                         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();
+                            List<Attendance> effectiveDayAttendances = resolveDayClockAttendances(date, curDateAttendances, attendances);
+                            if (effectiveDayAttendances.isEmpty()) {
+                                continue;
                             }
+                            staff.setClockStartTime(effectiveDayAttendances.get(0).getClockTime());
+                            endClockTime = effectiveDayAttendances.get(effectiveDayAttendances.size() - 1).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) {
@@ -340,6 +339,56 @@ public class AttendanceStaffServiceImpl extends ServiceImpl<AttendanceStaffMappe
         return msg;
     }
 
+    private static final LocalTime EARLY_MORNING_CUTOFF = LocalTime.of(7, 0);
+    private static final LocalTime NIGHT_SHIFT_START_THRESHOLD = LocalTime.of(16, 0);
+
+    /**
+     * 解析当天有效打卡:同日≥2次保留全部;仅1次凌晨卡且前日未闭合夜班则归前日下班。
+     */
+    private List<Attendance> resolveDayClockAttendances(LocalDate date, List<Attendance> dayAttendances, List<Attendance> allAttendances) {
+        if (dayAttendances == null || dayAttendances.isEmpty()) {
+            return Collections.emptyList();
+        }
+        List<Attendance> sorted = dayAttendances.stream()
+                .sorted(Comparator.comparing(Attendance::getClockTime))
+                .collect(Collectors.toList());
+        if (sorted.size() >= 2) {
+            return sorted;
+        }
+        Attendance only = sorted.get(0);
+        if (!only.getClockTime().toLocalTime().isAfter(EARLY_MORNING_CUTOFF)
+                && isPreviousDayUnclosedNightShift(date, allAttendances, only.getClockTime())) {
+            return Collections.emptyList();
+        }
+        return sorted;
+    }
+
+    /**
+     * 前一日末卡为晚班/夜班且未形成完整班次时,当日凌晨单卡视为前一日下班。
+     */
+    private boolean isPreviousDayUnclosedNightShift(LocalDate date, List<Attendance> allAttendances, LocalDateTime earlyPunch) {
+        LocalDate prevDate = date.minusDays(1);
+        List<Attendance> prevDay = allAttendances.stream()
+                .filter(a -> a.getClockTime().toLocalDate().equals(prevDate))
+                .sorted(Comparator.comparing(Attendance::getClockTime))
+                .collect(Collectors.toList());
+        if (prevDay.isEmpty()) {
+            return false;
+        }
+        if (prevDay.size() >= 2) {
+            long hours = Duration.between(prevDay.get(0).getClockTime(), prevDay.get(prevDay.size() - 1).getClockTime()).toHours();
+            if (hours >= 8) {
+                return false;
+            }
+        }
+        Attendance lastPrev = prevDay.get(prevDay.size() - 1);
+        if (lastPrev.getClockTime().toLocalTime().isBefore(NIGHT_SHIFT_START_THRESHOLD)) {
+            return false;
+        }
+        long hoursSinceLastPrev = Duration.between(lastPrev.getClockTime(), earlyPunch).toHours();
+        return hoursSinceLastPrev < 8;
+    }
+
     private AttendanceStaff getWorkTimeType(List<AttendanceRule> ruleList, List<Attendance> attendanceList) {
         AttendanceRule baiBanRule = ruleList.get(0);
         AttendanceRule yichangBaiBan1Rule = ruleList.get(1);