From e1aacd2adff671b44658f476722f4c4fc30c7eb5 Mon Sep 17 00:00:00 2001
From: zouyu <2723363702@qq.com>
Date: 星期四, 13 八月 2026 09:23:21 +0800
Subject: [PATCH] 人员考勤:同步ICC门禁设备编号调整

---
 performance-server/src/main/java/com/ruoyi/performance/service/impl/StaffAttendanceTrackingRecordServiceImpl.java |  190 +++++++++++++++++++++++++++--------------------
 1 files changed, 110 insertions(+), 80 deletions(-)

diff --git a/performance-server/src/main/java/com/ruoyi/performance/service/impl/StaffAttendanceTrackingRecordServiceImpl.java b/performance-server/src/main/java/com/ruoyi/performance/service/impl/StaffAttendanceTrackingRecordServiceImpl.java
index f09e090..a85b5a3 100644
--- a/performance-server/src/main/java/com/ruoyi/performance/service/impl/StaffAttendanceTrackingRecordServiceImpl.java
+++ b/performance-server/src/main/java/com/ruoyi/performance/service/impl/StaffAttendanceTrackingRecordServiceImpl.java
@@ -12,30 +12,28 @@
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.google.common.util.concurrent.AtomicDouble;
+import com.ruoyi.common.core.domain.entity.SysDictData;
 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;
-
+import com.ruoyi.performance.dto.PerformanceShiftMapDto;
 import com.ruoyi.performance.dto.StaffAttendanceDTO;
 import com.ruoyi.performance.excel.StaffAttendanceAnnotationTextExcelData;
 import com.ruoyi.performance.excel.StaffAttendanceExcelData;
 import com.ruoyi.performance.excel.handler.attendance.CommentWriteHandler;
-import com.ruoyi.performance.mapper.StaffAttendanceTrackingRecordMapper;
-import com.ruoyi.performance.pojo.StaffAttendanceTrackingRecord;
-import com.ruoyi.performance.service.StaffAttendanceTrackingRecordService;
-import com.ruoyi.performance.dto.PerformanceShiftMapDto;
 import com.ruoyi.performance.mapper.PerformanceShiftMapper;
 import com.ruoyi.performance.mapper.ShiftTimeMapper;
+import com.ruoyi.performance.mapper.StaffAttendanceTrackingRecordMapper;
 import com.ruoyi.performance.pojo.ShiftTime;
+import com.ruoyi.performance.pojo.StaffAttendanceTrackingRecord;
+import com.ruoyi.performance.service.StaffAttendanceTrackingRecordService;
 import com.ruoyi.performance.utils.HourDiffCalculator;
 import com.ruoyi.performance.utils.TimeDiffCalculator;
 import com.ruoyi.performance.vo.StaffAttendanceVO;
 import com.ruoyi.system.mapper.UserMapper;
+import com.ruoyi.system.service.ISysDictTypeService;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.ObjectUtils;
 import org.apache.commons.lang3.StringUtils;
@@ -53,10 +51,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;
@@ -75,6 +70,9 @@
 
     @Autowired
     private IccApiUtil iccApiUtil;
+
+    @Autowired
+    private ISysDictTypeService sysDictTypeService;
 
     @Autowired
     private PerformanceShiftMapper performanceShiftMapper;
@@ -111,21 +109,6 @@
     private static final String maternityLeaveKeyword = "浜�";//浜у亣鐝鍏抽敭瀛�
 
     /**
-     * 鍚屾鐨勯棬绂佽澶囧垪琛�
-     * channel_name device_code
-     * 10.100.22.2_闂ㄧ閫氶亾_1 1001538
-     * 10.100.22.3_闂ㄧ閫氶亾_1 1001539
-     * 10.100.22.4_闂ㄧ閫氶亾_1 1001540
-     * 10.100.22.5_闂ㄧ閫氶亾_1 1001541
-     * 10.100.22.12_闂ㄧ閫氶亾_1 1001626
-     * 10.100.22.13_闂ㄧ閫氶亾_1 1001627
-     * 10.100.22.14_闂ㄧ閫氶亾_1 1001628
-     * 10.100.22.15_闂ㄧ閫氶亾_1 1001629
-     */
-    private final static List<String> syncDeviceCode = Arrays.asList("1001538", "1001539", "1001540", "1001541",
-            "1001626", "1001627", "1001628", "1001629");
-
-    /**
      * 涓婄彮鏃堕棿鍒ゅ畾杈圭晫灏忔椂鏁�
      */
     private final static long WORK_TIME_BOUNDARY = 2L;
@@ -136,7 +119,9 @@
         if (ObjectUtil.isAllEmpty(startDate, endDate)) {
             throw new RuntimeException("鍚屾鏃ユ湡涓嶈兘涓虹┖");
         }
-
+        //鏌ヨ闂ㄧ璁惧瀛楀吀鍒楄〃
+        List<SysDictData> performanceIccDevice = sysDictTypeService.selectDictDataByType("performance_icc_device");
+        Set<String> syncDeviceCode = performanceIccDevice.stream().map(SysDictData::getDictValue).collect(Collectors.toSet());
         // 鏌ヨ宸插悓姝ョ殑璁板綍
         List<Long> trackingRecordIccIdList = baseMapper.selectIccIdList();
         try {
@@ -240,13 +225,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 +248,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,10 +400,37 @@
         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());
@@ -426,6 +438,7 @@
             //鎵规敞淇℃伅鍧愭爣淇℃伅
             List<StaffAttendanceAnnotationTextExcelData> annotationTextList = new ArrayList<>();
             // 鏌ヨ鐝
+
             List<PerformanceShiftMapDto> performanceShifts = performanceShiftMapper.selectListByWorkTime(
                     staffAttendanceDTO.getStartDate(), staffAttendanceDTO.getEndDate(), staffAttendanceDTO.getKeyword());
             //鑾峰彇鑰冨嫟鏁版嵁
@@ -450,50 +463,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())){
@@ -741,22 +759,34 @@
     public static String restorePersonCode(Object number) {
         // 1. 绌哄�兼牎楠�
         if (number == null) {
-            throw new IllegalArgumentException("浼犲叆鏁板瓧涓嶈兘涓虹┖");
+            return "";
         }
 
+        String original = number.toString();
+        try {
         // 2. 缁熶竴杞崲涓哄瓧绗︿覆骞跺幓闄ら灏剧┖鏍�
-        String numStr = number.toString().trim();
+            String numStr = original.trim();
 
         // 3. 鏍¢獙鏄惁涓虹函鏁板瓧锛堟帓闄よ礋鏁般�侀潪鏁板瓧瀛楃锛�
-        if (!numStr.matches("\\d+")) {
-            throw new IllegalArgumentException("浼犲叆鐨勪笉鏄湁鏁堟鏁存暟锛�" + numStr);
-        }
+            String digitStr;
+            if (numStr.matches("\\d+")) {
+                digitStr = numStr;
+            } else if (numStr.matches("(?i)^ZT\\d+$")) {
+                digitStr = numStr.substring(2);
+            } else if (numStr.matches("(?i)^ZT-\\d+$")) {
+                digitStr = numStr.substring(3);
+            } else {
+                return original;
+            }
 
         // 4. 琛ュ墠缃�0鍒版寚瀹氶暱搴︼紙6浣嶏級锛岃秴鍑哄垯淇濈暀鍘熸暟瀛�
-        String paddedNum = String.format("%0" + DIGIT_LENGTH + "d", Long.parseLong(numStr));
+            String paddedNum = StringUtils.leftPad(digitStr, DIGIT_LENGTH, '0');
 
         // 5. 鎷兼帴鍓嶇紑杩斿洖
-        return PREFIX + paddedNum;
+            return PREFIX + paddedNum;
+        } catch (Exception e) {
+            return original;
+        }
     }
 
 }

--
Gitblit v1.9.3