zouyu
6 天以前 79f9c8f092ccc4160e7732bf3f94a2b7ae750617
performance-server/src/main/java/com/ruoyi/performance/service/impl/StaffAttendanceTrackingRecordServiceImpl.java
@@ -13,10 +13,7 @@
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.util.concurrent.AtomicDouble;
import com.ruoyi.common.core.domain.entity.User;
import com.ruoyi.common.enums.ClockInState;
import com.ruoyi.common.enums.EnterOrExitType;
import com.ruoyi.common.enums.CalendarType;
import com.ruoyi.common.enums.SyncStatus;
import com.ruoyi.common.enums.*;
import com.ruoyi.common.utils.api.icc.IccApiUtil;
import com.ruoyi.common.utils.api.icc.model.GetResultPageRequest;
import com.ruoyi.common.utils.api.icc.model.GetResultPageResponse;
@@ -53,10 +50,7 @@
import java.math.RoundingMode;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
@@ -240,13 +234,13 @@
                if (!enterRecords.isEmpty()) {
                    // 上班时间和状态
                    StaffAttendanceTrackingRecord enterRecord = enterRecords.stream()
                            .filter(s -> !s.getSwingTime().isAfter(currentShiftStartDateTime) && !s.getSwingTime().isBefore(boundaryTime))
                            .filter(s -> (!s.getSwingTime().isAfter(currentShiftStartDateTime) && !s.getSwingTime().isBefore(boundaryTime)) || StringUtils.equals(s.getWorkStateFlag(), StaffWorkStateFlag.WORK.getValue()))
                            .max(Comparator.comparing(StaffAttendanceTrackingRecord::getSwingTime))
                            .orElse(new StaffAttendanceTrackingRecord());
                    if (BeanUtil.isEmpty(enterRecord)) {
                        enterRecord = enterRecords.stream()
                                .filter(s -> (s.getSwingTime().isAfter(currentShiftStartDateTime)
                                        && s.getSwingTime().isBefore(currentShiftEndDateTime)))
                                        && s.getSwingTime().isBefore(currentShiftEndDateTime)) || StringUtils.equals(s.getWorkStateFlag(), StaffWorkStateFlag.WORK.getValue()))
                                .min(Comparator.comparing(StaffAttendanceTrackingRecord::getSwingTime))
                                .orElse(new StaffAttendanceTrackingRecord());
                        workDateTime = enterRecord.getSwingTime();
@@ -263,14 +257,14 @@
                if (!exitRecords.isEmpty()) {
                    // 下班时间和状态
                    StaffAttendanceTrackingRecord exitRecord = exitRecords.stream()
                            .filter(s -> !s.getSwingTime().isBefore(currentShiftEndDateTime)
                                    && s.getSwingTime().isBefore(nextShiftStartDateTime))
                            .filter(s -> (!s.getSwingTime().isBefore(currentShiftEndDateTime)
                                    && s.getSwingTime().isBefore(nextShiftStartDateTime)) || StringUtils.equals(s.getWorkStateFlag(), StaffWorkStateFlag.OFF_WORK.getValue()))
                            .min(Comparator.comparing(StaffAttendanceTrackingRecord::getSwingTime))
                            .orElse(new StaffAttendanceTrackingRecord());
                    if (BeanUtil.isEmpty(exitRecord) && !now.isBefore(currentShiftEndDateTime)) {
                        exitRecord = exitRecords.stream()
                                .filter(s -> (s.getSwingTime().isAfter(currentShiftStartDateTime)
                                        && s.getSwingTime().isBefore(currentShiftEndDateTime)))
                                        && s.getSwingTime().isBefore(currentShiftEndDateTime)) || StringUtils.equals(s.getWorkStateFlag(), StaffWorkStateFlag.OFF_WORK.getValue()))
                                .max(Comparator.comparing(StaffAttendanceTrackingRecord::getSwingTime))
                                .orElse(new StaffAttendanceTrackingRecord());
                        offWorkDateTime = exitRecord.getSwingTime();
@@ -415,14 +409,45 @@
        return this.saveOrUpdateBatch(records);
    }
    /**
     * 根据导出日期格式化导出时间范围
     * @param staffAttendanceDTO
     */
    private static void formatExportDateRange(StaffAttendanceDTO staffAttendanceDTO){
        if(StringUtils.isNoneBlank(staffAttendanceDTO.getReportDate())){
            LocalTime startTime = LocalTime.of(0,0,0);
            LocalTime endTime = LocalTime.of(23,59,59);
            YearMonth yearMonth;
            if(StringUtils.equals(staffAttendanceDTO.getAttendanceReportType(),CalendarType.MONTH.name())){
                yearMonth = YearMonth.parse(staffAttendanceDTO.getReportDate(),DateTimeFormatter.ofPattern("yyyy-MM"));
                LocalDateTime startDateTime = LocalDateTime.of(yearMonth.minusMonths(1L).atDay(26),startTime);
                LocalDateTime endDateTime = LocalDateTime.of(yearMonth.atDay(25),endTime);
                staffAttendanceDTO.setStartDate(startDateTime);
                staffAttendanceDTO.setEndDate(endDateTime);
            }else if(StringUtils.equals(staffAttendanceDTO.getAttendanceReportType(),CalendarType.YEAR.name())){
                Year year = Year.parse(staffAttendanceDTO.getReportDate(),DateTimeFormatter.ofPattern("yyyy"));
                yearMonth = year.atMonth(1);
                LocalDateTime startDateTime = LocalDateTime.of(yearMonth.minusMonths(1L).atDay(26),startTime);
                LocalDateTime endDateTime = LocalDateTime.of(yearMonth.withMonth(12).atDay(25),endTime);
                staffAttendanceDTO.setStartDate(startDateTime);
                staffAttendanceDTO.setEndDate(endDateTime);
            }
        }
    }
    @Override
    public void exportStaffAttendanceRecords(HttpServletResponse response, StaffAttendanceDTO staffAttendanceDTO) {
        response.reset();
        try{
            formatExportDateRange(staffAttendanceDTO);
            //查询人员架构
            List<User> userList = userMapper.selectUserListByPerformance(false);
            List<Integer> userIdList = userList.stream().map(User::getId).collect(Collectors.toList());
            List<LocalDate> attendanceDateList = buildAttendanceDateList(staffAttendanceDTO);
            //批注信息坐标信息
            List<StaffAttendanceAnnotationTextExcelData> annotationTextList = new ArrayList<>();
            // 查询班次
            List<PerformanceShiftMapDto> performanceShifts = performanceShiftMapper.selectListByWorkTime(
                    staffAttendanceDTO.getStartDate(), staffAttendanceDTO.getEndDate(), staffAttendanceDTO.getKeyword());
            //获取考勤数据
@@ -430,7 +455,7 @@
            //组装导出数据
            List<StaffAttendanceExcelData> excelData = new ArrayList<>();
            Map<Integer, List<PerformanceShiftMapDto>> groupByUserId = performanceShifts.stream().collect(Collectors.groupingBy(PerformanceShiftMapDto::getUserId));
            List<Integer> userIdKeys = groupByUserId.keySet().stream().sorted().collect(Collectors.toList());
            List<Integer> userIdKeys = groupByUserId.keySet().stream().sorted(Comparator.comparing(userIdList::indexOf)).collect(Collectors.toList());
            for (int i = 0; i < userIdKeys.size(); i++) {
                List<PerformanceShiftMapDto> shiftMapDtos = groupByUserId.get(userIdKeys.get(i));
                StaffAttendanceExcelData attendanceExcelData = new StaffAttendanceExcelData();
@@ -447,50 +472,55 @@
                AtomicInteger maternityLeaveCount = new AtomicInteger(0);//产假天数
                AtomicInteger attendanceDayCount = new AtomicInteger(0);//出勤天数
                AtomicDouble attendanceWorkHourCount = new AtomicDouble(0D);//出勤总时间
                for (int j = 0; j < shiftMapDtos.size(); j++) {
                    PerformanceShiftMapDto shiftMapDto = shiftMapDtos.get(j);
                    //统计各假期和公差的天数
                    if(StringUtils.contains(shiftMapDto.getShiftName(),holidayLeaveKeyword)){
                        holidayCount.getAndIncrement();
                    }else if(StringUtils.contains(shiftMapDto.getShiftName(),personalLeaveKeyword)){
                        personalLeaveCount.getAndIncrement();
                    }else if(StringUtils.contains(shiftMapDto.getShiftName(),annualLeaveKeyword)){
                        annualLeaveCount.getAndIncrement();
                    }else if(StringUtils.contains(shiftMapDto.getShiftName(),officialTripKeyword)){
                        officialTripCount.getAndIncrement();
                    }else if(StringUtils.contains(shiftMapDto.getShiftName(),marriageLeaveKeyword)){
                        marriageLeaveCount.getAndIncrement();
                    }else if(StringUtils.contains(shiftMapDto.getShiftName(),bereavementLeaveKeyword)){
                        bereavementLeaveCount.getAndIncrement();
                    }else if(StringUtils.contains(shiftMapDto.getShiftName(),sickLeaveKeyword)){
                        sickLeaveCount.getAndIncrement();
                    }else if(StringUtils.contains(shiftMapDto.getShiftName(),maternityLeaveKeyword)){
                        maternityLeaveCount.getAndIncrement();
                    }
                    if(StringUtils.isAllBlank(shiftMapDto.getStartTime(),shiftMapDto.getEndTime())){
                        shiftList.add(shiftMapDto.getShiftName());
                    }else{
                        //过滤当前人员的班次信息
                        StaffAttendanceVO vo = attendanceRecords.stream().filter(f->StringUtils.isNotBlank(f.getPersonCode())).filter(f -> StringUtils.equals(f.getPersonCode(), shiftMapDto.getPersonCode()) && f.getSwingDate().isEqual(shiftMapDto.getWorkTime())).findFirst().orElse(null);
                        if(ObjectUtils.isEmpty(vo)){
                            shiftList.add("");
                for (int j = 0; j < attendanceDateList.size(); j++) {
                    LocalDate localDate = attendanceDateList.get(j);
                    PerformanceShiftMapDto shiftMapDto = shiftMapDtos.stream().filter(f -> f.getWorkTime().toLocalDate().equals(localDate)).findFirst().orElse(null);
                    if(Objects.nonNull(shiftMapDto)){
                        //统计各假期和公差的天数
                        if(StringUtils.contains(shiftMapDto.getShiftName(),holidayLeaveKeyword)){
                            holidayCount.getAndIncrement();
                        }else if(StringUtils.contains(shiftMapDto.getShiftName(),personalLeaveKeyword)){
                            personalLeaveCount.getAndIncrement();
                        }else if(StringUtils.contains(shiftMapDto.getShiftName(),annualLeaveKeyword)){
                            annualLeaveCount.getAndIncrement();
                        }else if(StringUtils.contains(shiftMapDto.getShiftName(),officialTripKeyword)){
                            officialTripCount.getAndIncrement();
                        }else if(StringUtils.contains(shiftMapDto.getShiftName(),marriageLeaveKeyword)){
                            marriageLeaveCount.getAndIncrement();
                        }else if(StringUtils.contains(shiftMapDto.getShiftName(),bereavementLeaveKeyword)){
                            bereavementLeaveCount.getAndIncrement();
                        }else if(StringUtils.contains(shiftMapDto.getShiftName(),sickLeaveKeyword)){
                            sickLeaveCount.getAndIncrement();
                        }else if(StringUtils.contains(shiftMapDto.getShiftName(),maternityLeaveKeyword)){
                            maternityLeaveCount.getAndIncrement();
                        }
                        if(StringUtils.isAllBlank(shiftMapDto.getStartTime(),shiftMapDto.getEndTime())){
                            shiftList.add(shiftMapDto.getShiftName());
                        }else{
                            String actualWorkHours = Objects.toString(vo.getActualWorkHours(), "");
                            Double diffHour = ObjectUtils.defaultIfNull(vo.getDiffHour(), 0D);
                            if (StringUtils.isBlank(actualWorkHours)) {
                            //过滤当前人员的班次信息
                            StaffAttendanceVO vo = attendanceRecords.stream().filter(f->StringUtils.isNotBlank(f.getPersonCode())).filter(f -> StringUtils.equals(f.getPersonCode(), shiftMapDto.getPersonCode()) && f.getSwingDate().isEqual(shiftMapDto.getWorkTime())).findFirst().orElse(null);
                            if(ObjectUtils.isEmpty(vo)){
                                shiftList.add("");
                            } else {
                                shiftList.add(Double.compare(diffHour, 0D) < 0 ? "-" + actualWorkHours : actualWorkHours);
                                attendanceDayCount.getAndIncrement();
                                attendanceWorkHourCount.getAndAdd(Double.parseDouble(actualWorkHours));
                            }else{
                                String actualWorkHours = Objects.toString(vo.getActualWorkHours(), "");
                                Double diffHour = ObjectUtils.defaultIfNull(vo.getDiffHour(), 0D);
                                if (StringUtils.isBlank(actualWorkHours)) {
                                    shiftList.add("");
                                } else {
                                    shiftList.add(Double.compare(diffHour, 0D) < 0 ? "-" + actualWorkHours : actualWorkHours);
                                    attendanceDayCount.getAndIncrement();
                                    attendanceWorkHourCount.getAndAdd(Double.parseDouble(actualWorkHours));
                                }
                            }
                        }
                    }
                    //月度统计才插入批注数据
                    if(StringUtils.isNoneBlank(staffAttendanceDTO.getAttendanceReportType()) && StringUtils.equals(staffAttendanceDTO.getAttendanceReportType(), CalendarType.MONTH.name())){
                        if(StringUtils.isNotBlank(shiftMapDto.getAnnotationText())){
                            annotationTextList.add(new StaffAttendanceAnnotationTextExcelData(i,j,shiftMapDto.getAnnotationText()));
                        //月度统计才插入批注数据
                        if(StringUtils.isNoneBlank(staffAttendanceDTO.getAttendanceReportType()) && StringUtils.equals(staffAttendanceDTO.getAttendanceReportType(), CalendarType.MONTH.name())){
                            if(StringUtils.isNotBlank(shiftMapDto.getAnnotationText())){
                                annotationTextList.add(new StaffAttendanceAnnotationTextExcelData(i,j,shiftMapDto.getAnnotationText()));
                            }
                        }
                    }else{
                        shiftList.add("");
                    }
                }
                if(StringUtils.isNoneBlank(staffAttendanceDTO.getAttendanceReportType()) && StringUtils.equals(staffAttendanceDTO.getAttendanceReportType(), CalendarType.MONTH.name())){