| | |
| | | import com.ruoyi.inspect.pojo.StaffAttendanceTrackingRecord; |
| | | import com.ruoyi.inspect.service.StaffAttendanceTrackingRecordService; |
| | | import com.ruoyi.inspect.util.HourDiffCalculator; |
| | | import com.ruoyi.inspect.util.TimeDiffCalculator; |
| | | import com.ruoyi.inspect.vo.StaffAttendanceVO; |
| | | import com.ruoyi.inspect.vo.StaffClockInVO; |
| | | import com.ruoyi.performance.dto.PerformanceShiftMapDto; |
| | |
| | | import java.math.RoundingMode; |
| | | import java.time.LocalDateTime; |
| | | import java.time.LocalTime; |
| | | import java.time.ZoneId; |
| | | import java.time.format.DateTimeFormatter; |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | |
| | | private final static List<String> syncDeviceCode = Arrays.asList("1001538", "1001539", "1001540", "1001541", |
| | | "1001626", "1001627", "1001628", "1001629"); |
| | | |
| | | /** |
| | | * 上班时间判定边界小时数 |
| | | */ |
| | | private final static long WORK_TIME_BOUNDARY = 2L; |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public boolean syncAttendanceRecord(LocalDateTime startDate, LocalDateTime endDate) { |
| | |
| | | public IPage<StaffAttendanceVO> pageAttendanceRecord(Page<StaffAttendanceTrackingRecord> page, |
| | | StaffAttendanceDTO staffAttendanceDTO) { |
| | | // 查询打卡记录 |
| | | System.out.println(staffAttendanceDTO.getStartDate()); |
| | | System.out.println(staffAttendanceDTO.getEndDate()); |
| | | System.out.println(ObjectUtils.allNotNull(staffAttendanceDTO.getStartDate(),staffAttendanceDTO.getEndDate())); |
| | | Wrapper<StaffAttendanceTrackingRecord> queryWrapper = Wrappers.<StaffAttendanceTrackingRecord>lambdaQuery() |
| | | .eq(StaffAttendanceTrackingRecord::getEnableReport, Boolean.TRUE) |
| | | .between(ObjectUtils.allNotNull(staffAttendanceDTO.getStartDate(),staffAttendanceDTO.getEndDate()), |
| | |
| | | * 正常:当前班次结束后第一次出门时间 |
| | | * 异常(早退):无当前班次结束到下一班次开始前的出门记录并且最后一次出门在当前班次时间范围内,取当前班次最后一次出门时间 |
| | | */ |
| | | //当前时间 |
| | | LocalDateTime now = LocalDateTime.now(ZoneId.of("Asia/Shanghai")); |
| | | // 当前班次开始天0点时间 |
| | | LocalDateTime startDateTime = LocalDateTime.of(p.getWorkTime().toLocalDate(), LocalTime.MIN); |
| | | // 当前班次结束天24点时间 |
| | |
| | | LocalTime currentShiftStartTime = LocalTime.parse(p.getStartTime(), HHmm); |
| | | LocalDateTime currentShiftStartDateTime = LocalDateTime.of(p.getWorkTime().toLocalDate(), |
| | | currentShiftStartTime); |
| | | // 当前班次结束时间 |
| | | LocalTime currentShiftEndTime = LocalTime.parse(p.getEndTime(), HHmm); |
| | | LocalDateTime currentShiftEndDateTime = LocalDateTime.of(endDateTime.toLocalDate(), |
| | | currentShiftEndTime); |
| | | // 下一班次开始时间 |
| | | LocalDateTime nextShiftStartDateTime = getShiftStartDateTime(i + 1, performanceShifts, |
| | | startDateTime.plusDays(1L)); |
| | |
| | | // 如果小时差为负数,表示跨天,结束时间需加一 |
| | | endDateTime = endDateTime.plusDays(1L); |
| | | } |
| | | // 当前班次结束时间 |
| | | LocalTime currentShiftEndTime = LocalTime.parse(p.getEndTime(), HHmm); |
| | | LocalDateTime currentShiftEndDateTime = LocalDateTime.of(endDateTime.toLocalDate(), |
| | | currentShiftEndTime); |
| | | // 过滤出当前人员当前班次的进/出记录 |
| | | LocalDateTime workDateTime = null; |
| | | LocalDateTime offWorkDateTime = null; |
| | | List<StaffAttendanceTrackingRecord> enterRecords = filterAttendanceRecord(p.getPersonCode(), |
| | | EnterOrExitType.ENTER.getValue(), startDateTime, endDateTime, recordList); |
| | | //上班时间判定边界 |
| | | LocalDateTime boundaryTime = currentShiftStartDateTime.minusHours(WORK_TIME_BOUNDARY); |
| | | if (!enterRecords.isEmpty()) { |
| | | // 上班时间和状态 |
| | | StaffAttendanceTrackingRecord enterRecord = enterRecords.stream() |
| | | .filter(s -> !s.getSwingTime().isAfter(currentShiftStartDateTime)) |
| | | .filter(s -> !s.getSwingTime().isAfter(currentShiftStartDateTime) && !s.getSwingTime().isBefore(boundaryTime)) |
| | | .max(Comparator.comparing(StaffAttendanceTrackingRecord::getSwingTime)) |
| | | .orElse(new StaffAttendanceTrackingRecord()); |
| | | if (BeanUtil.isEmpty(enterRecord)) { |
| | |
| | | && s.getSwingTime().isBefore(nextShiftStartDateTime)) |
| | | .min(Comparator.comparing(StaffAttendanceTrackingRecord::getSwingTime)) |
| | | .orElse(new StaffAttendanceTrackingRecord()); |
| | | if (BeanUtil.isEmpty(exitRecord)) { |
| | | if (BeanUtil.isEmpty(exitRecord) && !now.isBefore(currentShiftEndDateTime)) { |
| | | exitRecord = exitRecords.stream() |
| | | .filter(s -> (s.getSwingTime().isAfter(currentShiftStartDateTime) |
| | | && s.getSwingTime().isBefore(currentShiftEndDateTime))) |
| | |
| | | |
| | | } |
| | | if (ObjectUtils.allNotNull(workDateTime, offWorkDateTime)) { |
| | | vo.setActualWorkHours(HourDiffCalculator.getHourDiff(workDateTime.toLocalTime().format(HHmm), |
| | | offWorkDateTime.toLocalTime().format(HHmm))); |
| | | vo.setActualWorkHours(TimeDiffCalculator.getHourDiff(workDateTime, |
| | | offWorkDateTime)); |
| | | } |
| | | // 赋值 |
| | | vo.setShiftId(p.getShift()); |
| | | vo.setPersonCode(p.getPersonCode()); |
| | | vo.setPersonName(p.getUserName()); |
| | | vo.setPlannedWorkHours(hourDiff); |
| | | //应勤时长 |
| | | double plannedWorkHours = Math.abs(hourDiff); |
| | | vo.setPlannedWorkHours(plannedWorkHours); |
| | | vo.setSwingDate(startDateTime); |
| | | vo.setWorkDateTime(workDateTime); |
| | | vo.setOffWorkDateTime(offWorkDateTime); |
| | |
| | | vo.setCreateTime(recordList.get(0).getCreateTime()); |
| | | vo.setUpdateUser(recordList.get(0).getUpdateUser()); |
| | | vo.setUpdateTime(recordList.get(0).getUpdateTime()); |
| | | vo.setResult(ClockInState.ABNORMAL.getValue()); |
| | | if(ObjectUtils.allNotNull(vo.getWorkClockInState(),vo.getOffClockInState())){ |
| | | vo.setResult(Integer.min(vo.getWorkClockInState(),vo.getOffClockInState())); |
| | | //当前时间在下班时间过后才判断考勤结果 |
| | | if(!now.isBefore(currentShiftEndDateTime)){ |
| | | if(ObjectUtils.allNotNull(vo.getWorkClockInState(),vo.getOffClockInState())){ |
| | | vo.setResult(Integer.min(vo.getWorkClockInState(),vo.getOffClockInState())); |
| | | }else{ |
| | | vo.setResult(ClockInState.ABNORMAL.getValue()); |
| | | } |
| | | } |
| | | // 计算缺勤时长 |
| | | if (ObjectUtils.allNotNull(vo.getActualWorkHours(), vo.getPlannedWorkHours())) { |
| | |
| | | long pages = getPages(size,total); |
| | | int startIndex = Math.toIntExact((current - 1) * size >= total ? (pages - 1) * size : (current - 1) * size); |
| | | int endIndex = Math.toIntExact(Math.min(current * size, total)); |
| | | List<StaffAttendanceVO> records = resultList.subList(startIndex, endIndex); |
| | | List<StaffAttendanceVO> records; |
| | | if(resultList.isEmpty()){ |
| | | records = new ArrayList<>(); |
| | | }else{ |
| | | records = resultList.subList(startIndex, endIndex); |
| | | } |
| | | resultPage.setRecords(records); |
| | | resultPage.setTotal(total); |
| | | resultPage.setSize(size); |