diff --git a/klp-wms/src/main/java/com/klp/service/impl/WmsAttendanceCheckServiceImpl.java b/klp-wms/src/main/java/com/klp/service/impl/WmsAttendanceCheckServiceImpl.java index d1c51848..dfd4f3df 100644 --- a/klp-wms/src/main/java/com/klp/service/impl/WmsAttendanceCheckServiceImpl.java +++ b/klp-wms/src/main/java/com/klp/service/impl/WmsAttendanceCheckServiceImpl.java @@ -386,18 +386,91 @@ public class WmsAttendanceCheckServiceImpl implements IWmsAttendanceCheckService if (hasPeriod2) { LocalTime p1End = toLocalTime(schedule.getShiftEndTime()); LocalTime p2Start = toLocalTime(schedule.getShiftStartTime2()); - LocalTime split = LocalTime.of( - (p1End.getHour() + p2Start.getHour()) / 2, - (p1End.getMinute() + p2Start.getMinute()) / 2); + + // 按理论时间范围分割:p1End之前、中间区间、p2Start之后 + List beforeGap = new ArrayList<>(); + List inGap = new ArrayList<>(); + List afterGap = new ArrayList<>(); + for (AttendanceRecords r : records) { + LocalTime t = toLocalDateTime(r.getChecktime()).toLocalTime(); + if (!t.isAfter(p1End)) { + beforeGap.add(r); + } else if (!t.isBefore(p2Start)) { + afterGap.add(r); + } else { + inGap.add(r); + } + } List p1Records = new ArrayList<>(); List p2Records = new ArrayList<>(); - for (AttendanceRecords r : records) { - LocalTime t = toLocalDateTime(r.getChecktime()).toLocalTime(); - if (t.isBefore(split)) { - p1Records.add(r); - } else { - p2Records.add(r); + boolean lunchPatternFound = false; + + // 检测[p1End, p2Start]区间内是否有午休打卡(取最远两条判断>10分钟,按最大连续间隔切开) + if (inGap.size() >= 2) { + LocalDateTime firstInGap = toLocalDateTime(inGap.get(0).getChecktime()); + LocalDateTime lastInGap = toLocalDateTime(inGap.get(inGap.size() - 1).getChecktime()); + if (Duration.between(firstInGap, lastInGap).getSeconds() > 600) { + int splitIdx = 0; + long maxGap = 0; + for (int i = 0; i < inGap.size() - 1; i++) { + LocalDateTime t1 = toLocalDateTime(inGap.get(i).getChecktime()); + LocalDateTime t2 = toLocalDateTime(inGap.get(i + 1).getChecktime()); + long gap = Duration.between(t1, t2).getSeconds(); + if (gap > maxGap) { + maxGap = gap; + splitIdx = i; + } + if (gap > 600) { + break; + } + } + p1Records = new ArrayList<>(beforeGap); + p1Records.addAll(inGap.subList(0, splitIdx + 1)); + p2Records = new ArrayList<>(inGap.subList(splitIdx + 1, inGap.size())); + p2Records.addAll(afterGap); + lunchPatternFound = true; + } + } + + // 检测边界:beforeGap最后一条 与 inGap第一条 间隔>10分钟(提前下班+午饭回来) + if (!lunchPatternFound && !beforeGap.isEmpty() && !inGap.isEmpty()) { + LocalDateTime lastBefore = toLocalDateTime(beforeGap.get(beforeGap.size() - 1).getChecktime()); + LocalDateTime firstIn = toLocalDateTime(inGap.get(0).getChecktime()); + if (Duration.between(lastBefore, firstIn).getSeconds() > 600) { + p1Records = new ArrayList<>(beforeGap); + p2Records = new ArrayList<>(inGap); + p2Records.addAll(afterGap); + lunchPatternFound = true; + } + } + + // 检测边界:inGap最后一条 与 afterGap第一条 间隔>10分钟(午休晚归) + if (!lunchPatternFound && !inGap.isEmpty() && !afterGap.isEmpty()) { + LocalDateTime lastIn = toLocalDateTime(inGap.get(inGap.size() - 1).getChecktime()); + LocalDateTime firstAfter = toLocalDateTime(afterGap.get(0).getChecktime()); + if (Duration.between(lastIn, firstAfter).getSeconds() > 600) { + p1Records = new ArrayList<>(beforeGap); + p1Records.addAll(inGap); + p2Records = new ArrayList<>(afterGap); + lunchPatternFound = true; + } + } + + if (!lunchPatternFound) { + // 没有午休打卡模式,回退原中值法 + LocalTime split = LocalTime.of( + (p1End.getHour() + p2Start.getHour()) / 2, + (p1End.getMinute() + p2Start.getMinute()) / 2); + p1Records = new ArrayList<>(); + p2Records = new ArrayList<>(); + for (AttendanceRecords r : records) { + LocalTime t = toLocalDateTime(r.getChecktime()).toLocalTime(); + if (t.isBefore(split)) { + p1Records.add(r); + } else { + p2Records.add(r); + } } }