Ver Fonte

考勤统计,统计时包含当天的,重新拉取数据并固化考勤数据

dzx há 4 semanas atrás
pai
commit
d52534e4a3

+ 66 - 7
src/main/java/com/xjrsoft/module/attendance/service/impl/AttendanceStatisticsServiceImpl.java

@@ -26,14 +26,21 @@ import com.xjrsoft.module.attendance.service.IAttendanceRuleCategoryService;
 import com.xjrsoft.module.attendance.service.IAttendanceStatisticsRecordService;
 import com.xjrsoft.module.attendance.service.IAttendanceStatisticsService;
 import com.xjrsoft.module.attendance.service.ITeacherAttendanceRecordService;
+import com.xjrsoft.module.attendance.vo.AttendanceRuleDetailsUserVo;
 import com.xjrsoft.module.attendance.vo.AttendanceStatisticsPageVo;
 import com.xjrsoft.module.attendance.vo.AttendanceStatisticsRecordVo;
+import com.xjrsoft.module.hikvision.util.OutInRecordUtil;
 import com.xjrsoft.module.holiday.entity.HolidayDate;
 import com.xjrsoft.module.holiday.service.IHolidayDateService;
+import com.xjrsoft.module.job.AttendanceRecordTask;
 import com.xjrsoft.module.organization.entity.User;
 import com.xjrsoft.module.organization.service.IUserService;
 import com.xjrsoft.module.organization.vo.UserIdDeptNameVo;
+import com.xjrsoft.module.outint.service.ICarOutInRecordService;
+import com.xjrsoft.module.outint.service.ITeacherOutInRecordService;
 import com.xjrsoft.module.teacher.entity.BaseTeacher;
+import com.xjrsoft.module.teacher.mapper.FaceImportMapper;
+import com.xjrsoft.module.teacher.service.IWfTeacherleaveService;
 import lombok.AllArgsConstructor;
 import me.zhyd.oauth.log.Log;
 import org.apache.poi.ss.usermodel.Cell;
@@ -53,6 +60,7 @@ import org.springframework.transaction.annotation.Transactional;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.time.LocalDate;
+import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
 import java.time.temporal.ChronoUnit;
 import java.util.ArrayList;
@@ -62,7 +70,6 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
-import java.util.concurrent.CompletableFuture;
 import java.util.stream.Collectors;
 
 /**
@@ -86,16 +93,57 @@ public class AttendanceStatisticsServiceImpl extends MPJBaseServiceImpl<Attendan
 
     private final IHolidayDateService holidayDateService;
 
+    private final FaceImportMapper faceImportMapper;
+
+    private final IWfTeacherleaveService wfTeacherleaveService;
+
+    private final ITeacherOutInRecordService outInRecordService;
+
+    private final ICarOutInRecordService carOutInRecordService;
+
+
 
     @Override
     @Transactional(rollbackFor = Exception.class)
     public Boolean add(AddAttendanceStatisticsDto dto) {
-        AttendanceStatistics attendanceStatistics = BeanUtil.toBean(dto, AttendanceStatistics.class);
-        attendanceStatistics.setCreateDate(new Date());
-        attendanceStatistics.setStatus(0);
-        statisticsMapper.insert(attendanceStatistics);
-        refreshRecord(attendanceStatistics.getId());
-        return true;
+        try {
+            AttendanceStatistics statistics = BeanUtil.toBean(dto, AttendanceStatistics.class);
+            statistics.setCreateDate(new Date());
+            statistics.setStatus(0);
+            statisticsMapper.insert(statistics);
+
+            List<LocalDate> dateList = getDatesBetween(dto.getStartDate(), dto.getEndDate());
+            LocalDateTime now = LocalDateTime.now();
+            if(dateList.contains(now.toLocalDate())){
+                OutInRecordUtil outInRecordUtil = new OutInRecordUtil();
+                LocalDateTime startDateTime = now.plusDays(-1).withHour(0).withMinute(0).withSecond(0).withNano(0);
+                LocalDateTime endDateTime = startDateTime.plusDays(1).plusSeconds(-1);
+
+                Map<Long, AttendanceRuleDetailsUserVo> teacherRules = ruleCategoryService.getAllTeacherTodyRule(now.getDayOfWeek().name());
+//                //教师&学生拉取数据
+//                outInRecordUtil.getTeacherRecords(faceImportMapper, startDateTime, endDateTime, teacherRules);
+//                //拉取车辆数据
+//                outInRecordUtil.GetVehicleRecord(faceImportMapper, startDateTime, endDateTime);
+
+                AttendanceRecordTask recordTask = new AttendanceRecordTask();
+                recordTask.teacherAttendanceRecord(startDateTime, statistics.getTimePeriod(),
+                        userService,
+                        ruleCategoryService,
+                        holidayDateService,
+                        wfTeacherleaveService,
+                        outInRecordService,
+                        carOutInRecordService,
+                        recordService);
+            }
+
+            //1、同步出入记录的数据
+            //2、固化考勤数据
+            refreshRecord(statistics.getId());
+            return true;
+        } catch (Exception e) {
+            Log.error(e.getMessage(), e);
+            throw new MyException("添加报错,请联系管理员");
+        }
     }
 
     @Override
@@ -345,6 +393,17 @@ public class AttendanceStatisticsServiceImpl extends MPJBaseServiceImpl<Attendan
         return dates;
     }
 
+    private List<LocalDate> getDatesBetween(LocalDate startDate, LocalDate endDate) {
+        List<LocalDate> dates = new ArrayList<>();
+        long numOfDaysBetween = ChronoUnit.DAYS.between(startDate, endDate) + 1; // +1 包含结束日期
+        for (long i = 0; i < numOfDaysBetween; i++) {
+            LocalDate localDate = startDate.plusDays(i);
+            dates.add(localDate);
+        }
+
+        return dates;
+    }
+
     private Map<String, String> initWeekCn() {
         Map<String, String> result = new HashMap<>();
 

+ 200 - 2
src/main/java/com/xjrsoft/module/hikvision/util/OutInRecordUtil.java

@@ -9,6 +9,7 @@ import com.xjrsoft.common.enums.OutInStatusEnum;
 import com.xjrsoft.common.mybatis.SqlRunnerAdapter;
 import com.xjrsoft.common.utils.SqlRunnerAdapterUtil;
 import com.xjrsoft.module.attendance.entity.AttendanceRuleDetails;
+import com.xjrsoft.module.attendance.vo.AttendanceRuleDetailsUserVo;
 import com.xjrsoft.module.teacher.mapper.FaceImportMapper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -19,6 +20,7 @@ import java.text.SimpleDateFormat;
 import java.time.LocalDateTime;
 import java.time.ZoneOffset;
 import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
@@ -437,8 +439,6 @@ public class OutInRecordUtil {
 
             if (visit_id_list.contains(eventId)) continue;
 
-
-
             visitInsertRecord(Long.parseLong(reservationSchoolId), eventTime, picUri, status + "", eventId);
         }
 
@@ -812,4 +812,202 @@ public class OutInRecordUtil {
             }
         }
     }
+
+    public void getTeacherRecords(FaceImportMapper faceImportMapper, LocalDateTime startDateTime, LocalDateTime endDateTime,
+                                 Map<Long, AttendanceRuleDetailsUserVo> teacherRules) throws ParseException {
+        JsonArray responseBuilder = new JsonArray();
+
+        AtomicInteger pageNo = new AtomicInteger(1);
+        int pageSize = 1000;
+        boolean hasMorePages = true;
+
+        while (hasMorePages) {
+            String response = GetDoorEvent(pageNo, pageSize, startDateTime, endDateTime);
+
+            JsonElement responseElement = new Gson().fromJson(response, JsonElement.class);
+            JsonArray dataList = responseElement.getAsJsonObject().getAsJsonObject("data").getAsJsonArray("list");
+            responseBuilder.addAll(dataList);
+            JsonObject responseJson = new Gson().fromJson(response, JsonObject.class);
+            int totalCount = responseJson.getAsJsonObject("data").get("totalPage").getAsInt();
+            hasMorePages = pageNo.getAndIncrement() < totalCount;
+        }
+        //存数据
+        if(responseBuilder.size() > 0){
+            return;
+        }
+        InsertTeacherStudentRecords(responseBuilder, faceImportMapper);
+
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+        List<Long> teacherUserIds = faceImportMapper.getTeacherUserIds();
+        List<String> insertSqls = new ArrayList<>();
+        for (JsonElement element : responseBuilder) {
+            JsonObject item = element.getAsJsonObject();
+
+            Long personId;
+            try {
+                personId = item.get("personId").isJsonNull() ? null : item.get("personId").getAsLong();
+            }catch (Exception e){
+                continue;
+            }
+            if (personId == null) continue;
+
+            int statusInt = item.get("inAndOutType").getAsInt();
+            int status = 1;
+            switch (statusInt){
+                case 0:
+                    status = 1;
+                    break;
+                case 1:
+                    status = 0;
+                    break;
+            }
+
+            String uri = item.get("picUri").isJsonNull() ? null : item.get("picUri").getAsString();
+            String recordTime = item.get("eventTime").isJsonNull() ? null : item.get("eventTime").getAsString();
+            String eventId = item.get("eventId").isJsonNull() ? null : item.get("eventId").getAsString();
+            String recordTimeStr = ChangeTime(recordTime);
+            if (teacherUserIds.contains(personId)) {
+                // 老师记录
+                LocalDateTime recordTimeDate = LocalDateTime.parse(recordTimeStr, formatter);
+                String attendanceStatus = discernTeacherStatus(recordTimeDate, status, teacherRules.get(personId));
+                String insSql = "INSERT INTO teacher_out_in_record(create_date, user_id, record_time, face_photo, eventId, status,delete_mark,enabled_mark, attendance_status) "
+                        + "select now(), '"  + personId + "', '" + recordTimeStr + "', '" +
+                        ApiUtil.GetRedirectURL(uri) + "', '" + eventId + "', '" +status + "',0,1,'" + attendanceStatus + "'" +
+                        " WHERE NOT EXISTS (SELECT 1 FROM teacher_out_in_record WHERE eventId = '" + eventId + "')";
+                insertSqls.add(insSql);
+            }
+            if(!insertSqls.isEmpty()){
+                for (String insertSql : insertSqls) {
+                    SqlRunnerAdapter.db().insert(insertSql);
+                }
+            }
+        }
+    }
+
+    String discernTeacherStatus(LocalDateTime recordTime, int status, AttendanceRuleDetailsUserVo ruleDetails){
+        String attendanceStatus = "";
+        if (ruleDetails != null) {
+            if (ruleDetails.getIsAttendance() != null && ruleDetails.getIsAttendance() == 0) {
+                attendanceStatus = "不考勤";
+            } else {
+                LocalDateTime amStartTime = null, amEndTime = null, pmStartTime = null, pmEndTime = null, eveningStartTime = null, eveningEndTime = null;
+                if (ruleDetails.getAmStatus() != null && ruleDetails.getAmStatus() == 1
+                        && ruleDetails.getAmStartTime() != null && ruleDetails.getAmEndTime() != null) {
+                    amStartTime = recordTime.withHour(ruleDetails.getAmStartTime().getHour())
+                            .withMinute(ruleDetails.getAmStartTime().getMinute())
+                            .withSecond(ruleDetails.getAmStartTime().getSecond());
+                    amEndTime = recordTime.withHour(ruleDetails.getAmEndTime().getHour())
+                            .withMinute(ruleDetails.getAmEndTime().getMinute())
+                            .withSecond(ruleDetails.getAmEndTime().getSecond());
+                }
+                if (ruleDetails.getPmStatus() != null && ruleDetails.getPmStatus() == 1
+                        && ruleDetails.getPmEndTime() != null && ruleDetails.getPmStartTime() != null) {
+                    pmStartTime = recordTime.withHour(ruleDetails.getPmStartTime().getHour())
+                            .withMinute(ruleDetails.getPmStartTime().getMinute())
+                            .withSecond(ruleDetails.getPmStartTime().getSecond());
+                    pmEndTime = recordTime.withHour(ruleDetails.getPmEndTime().getHour())
+                            .withMinute(ruleDetails.getPmEndTime().getMinute())
+                            .withSecond(ruleDetails.getPmEndTime().getSecond());
+                }
+                if (status == OutInStatusEnum.goOut.getCode()) {//出
+                    if (recordTime.isBefore(amEndTime) && recordTime.isAfter(amStartTime)) {
+                        attendanceStatus = "早退";
+                    } else if (recordTime.isBefore(pmEndTime) && recordTime.isAfter(pmStartTime)) {
+                        attendanceStatus = "早退";
+                    } else {
+                        attendanceStatus = "离校";
+                    }
+                } else {//进
+                    if (recordTime.isBefore(amEndTime) && recordTime.isAfter(amStartTime)) {
+                        attendanceStatus = "迟到";
+                    } else if (recordTime.isBefore(pmEndTime) && recordTime.isAfter(pmStartTime)) {
+                        attendanceStatus = "迟到";
+                    } else {
+                        attendanceStatus = "到校";
+                    }
+                }
+            }
+        }
+        return attendanceStatus;
+    }
+
+    String discernStudentStatus(LocalDateTime recordTime, int status, AttendanceRuleDetailsUserVo ruleDetails){
+        String attendanceStatus = "";
+        if(ruleDetails.getIsAllowInOutSchool() != null && ruleDetails.getIsAllowInOutSchool() == 0){
+            attendanceStatus = "不考勤";
+        }else{
+            LocalDateTime amStartTime = null, amEndTime = null, pmStartTime = null, pmEndTime = null, eveningStartTime = null, eveningEndTime = null;
+            if(ruleDetails.getAmStatus() != null && ruleDetails.getAmStatus() == 1 && ruleDetails.getAmStartTime() != null
+                    &&  ruleDetails.getAmEndTime() != null){
+                amStartTime = recordTime.withHour(ruleDetails.getAmStartTime().getHour())
+                        .withMinute(ruleDetails.getAmStartTime().getMinute())
+                        .withSecond(ruleDetails.getAmStartTime().getSecond());
+                amEndTime = recordTime.withHour(ruleDetails.getAmEndTime().getHour())
+                        .withMinute(ruleDetails.getAmEndTime().getMinute())
+                        .withSecond(ruleDetails.getAmEndTime().getSecond());
+            }
+            if(ruleDetails.getPmStatus() != null && ruleDetails.getPmStatus() == 1 && ruleDetails.getPmStartTime() != null
+                    &&  ruleDetails.getPmEndTime() != null){
+                pmStartTime = recordTime.withHour(ruleDetails.getPmStartTime().getHour())
+                        .withMinute(ruleDetails.getPmStartTime().getMinute())
+                        .withSecond(ruleDetails.getPmStartTime().getSecond());
+                pmEndTime = recordTime.withHour(ruleDetails.getPmEndTime().getHour())
+                        .withMinute(ruleDetails.getPmEndTime().getMinute())
+                        .withSecond(ruleDetails.getPmEndTime().getSecond());
+            }
+            if(ruleDetails.getEveningStatus() != null && ruleDetails.getEveningStatus() == 1
+                    && ruleDetails.getEveningStartTime() != null
+                    &&  ruleDetails.getEveningEndTime() != null){
+                eveningStartTime = recordTime.withHour(ruleDetails.getEveningStartTime().getHour())
+                        .withMinute(ruleDetails.getEveningStartTime().getMinute())
+                        .withSecond(ruleDetails.getEveningStartTime().getSecond());
+                eveningEndTime = recordTime.withHour(ruleDetails.getEveningEndTime().getHour())
+                        .withMinute(ruleDetails.getEveningEndTime().getMinute())
+                        .withSecond(ruleDetails.getEveningEndTime().getSecond());
+            }
+            if(status == OutInStatusEnum.goOut.getCode()){//出
+                if(amEndTime != null && amStartTime != null && recordTime.isBefore(amEndTime) && recordTime.isAfter(amStartTime)){
+                    attendanceStatus = "早退";
+                }else if(pmEndTime != null && pmStartTime != null && recordTime.isBefore(pmEndTime) && recordTime.isAfter(pmStartTime)){
+                    attendanceStatus = "早退";
+                }else if(eveningEndTime != null && recordTime.isBefore(eveningEndTime) && recordTime.isAfter(eveningStartTime)){
+                    attendanceStatus = "早退";
+                }else{
+                    attendanceStatus = "离校";
+                }
+            }else{//进
+                if(amEndTime != null && amStartTime != null && recordTime.isBefore(amEndTime) && recordTime.isAfter(amStartTime)){
+                    attendanceStatus = "迟到";
+                    LocalDateTime localDateTime = amStartTime;
+                    if(ruleDetails.getOverMinutes() != null){
+                        localDateTime = amStartTime.plusMinutes(ruleDetails.getOverMinutes());
+                    }
+                    if(recordTime.isAfter(localDateTime)){
+                        attendanceStatus = "旷课";
+                    }
+                }else if(pmEndTime != null && pmStartTime != null && recordTime.isBefore(pmEndTime) && recordTime.isAfter(pmStartTime)){
+                    attendanceStatus = "迟到";
+                    LocalDateTime localDateTime = pmStartTime;
+                    if(ruleDetails.getOverMinutes() != null){
+                        localDateTime = pmStartTime.plusMinutes(ruleDetails.getOverMinutes());
+                    }
+                    if(recordTime.isAfter(localDateTime)){
+                        attendanceStatus = "旷课";
+                    }
+                }else if(eveningEndTime != null && recordTime.isBefore(eveningEndTime) && recordTime.isAfter(eveningStartTime)){
+                    attendanceStatus = "迟到";
+                    LocalDateTime localDateTime = eveningStartTime;
+                    if(ruleDetails.getOverMinutes() != null){
+                        localDateTime = eveningStartTime.plusMinutes(ruleDetails.getOverMinutes());
+                    }
+                    if(recordTime.isAfter(localDateTime)){
+                        attendanceStatus = "旷课";
+                    }
+                }else{
+                    attendanceStatus = "到校";
+                }
+            }
+        }
+        return attendanceStatus;
+    }
 }

+ 156 - 17
src/main/java/com/xjrsoft/module/job/AttendanceRecordTask.java

@@ -21,10 +21,7 @@ import com.xjrsoft.module.outint.service.ICarOutInRecordService;
 import com.xjrsoft.module.outint.service.ITeacherOutInRecordService;
 import com.xjrsoft.module.personnel.entity.CarMessageApply;
 import com.xjrsoft.module.teacher.entity.BaseTeacher;
-import com.xjrsoft.module.teacher.entity.WfHeadTeacherLeave;
 import com.xjrsoft.module.teacher.entity.WfTeacherleave;
-import com.xjrsoft.module.teacher.entity.XjrUser;
-import com.xjrsoft.module.teacher.service.IWfHeadTeacherLeaveService;
 import com.xjrsoft.module.teacher.service.IWfTeacherleaveService;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -58,9 +55,6 @@ public class AttendanceRecordTask {
     @Autowired
     private IWfTeacherleaveService wfTeacherleaveService;
 
-    @Autowired
-    private IWfHeadTeacherLeaveService headTeacherLeaveService;
-
     @Autowired
     private ITeacherOutInRecordService teacherOutInRecordService;
 
@@ -190,16 +184,156 @@ public class AttendanceRecordTask {
                 continue;
             }
 
-            WfHeadTeacherLeave teacherLeave = headTeacherLeaveService.selectJoinOne(WfHeadTeacherLeave.class,
-                    new MPJLambdaWrapper<WfHeadTeacherLeave>()
-                            .select(WfHeadTeacherLeave.class, x -> VoToColumnUtil.fieldsToColumns(WfHeadTeacherLeave.class).contains(x.getProperty()))
-                            .innerJoin(XjrUser.class, XjrUser::getId, WfHeadTeacherLeave::getApplicantUserId)
-                            .eq(WfHeadTeacherLeave::getStatus, 1)
-                            .eq(WfHeadTeacherLeave::getApplicantUserId, record.getUserId())
-                            .between(WfHeadTeacherLeave::getStartTime, startTime, endTime)
-            );
-            if(teacherLeave != null){
-                record.setAttendanceStatus(teacherLeave.getLeaveReason());
+            TeacherOutInRecordDto outInDto = new TeacherOutInRecordDto();
+            outInDto.setQueryDate(startTime.toLocalDate());
+            outInDto.setEndTime(endTime);
+            outInDto.setStartTime(startTime);
+            outInDto.setStatus(OutInStatusEnum.enter.getCode());
+            outInDto.setUserId(record.getUserId());
+            List<TeacherOutInRecord> outInRecords = teacherOutInRecordService.getListByParam(outInDto);
+            if(!outInRecords.isEmpty()){
+                TeacherOutInRecord outInRecord = outInRecords.get(0);
+                if(outInRecord != null){
+                    record.setRecordTime(outInRecord.getRecordTime());
+                    record.setAttendanceStatus(outInRecord.getAttendanceStatus());
+                    record.setAttendanceMode(1);
+                }
+            }else{
+                //查询该教师是否通过车辆进入
+                List<CarOutInRecord> list = carOutInRecordService.list(
+                        new MPJLambdaWrapper<CarOutInRecord>()
+                                .select(CarOutInRecord.class, x -> VoToColumnUtil.fieldsToColumns(CarOutInRecord.class).contains(x.getProperty()))
+                                .leftJoin(CarMessageApply.class, CarMessageApply::getId, CarOutInRecord::getCarMessageApplyId)
+                                .le(CarOutInRecord::getRecordTime, endTime)
+                                .eq("DATE_FORMAT(record_time, '%Y-%m-%d')", endTime.toLocalDate())
+                                .eq(CarMessageApply::getUserId, record.getUserId())
+                                .ge(timePeriod != null && timePeriod == 2 && amEndTime != null, CarOutInRecord::getRecordTime, amEndTime)
+                                .eq(CarOutInRecord::getStatus, OutInStatusEnum.enter.getCode())
+                                .orderByAsc(CarOutInRecord::getRecordTime)
+                );
+                if(!list.isEmpty()){
+                    CarOutInRecord outInRecord = list.get(0);
+                    if(outInRecord != null && outInRecord.getRecordTime().isBefore(startTime)){
+                        record.setRecordTime(outInRecord.getRecordTime());
+                        record.setAttendanceStatus("到校");
+                        record.setAttendanceMode(2);
+                        record.setCarNumber(outInRecord.getPlanNo());
+                    }else if(outInRecord != null && outInRecord.getRecordTime().isAfter(startTime)){
+                        record.setRecordTime(outInRecord.getRecordTime());
+                        record.setAttendanceStatus("迟到");
+                        record.setAttendanceMode(1);
+                        record.setCarNumber(outInRecord.getPlanNo());
+                    }
+                }
+            }
+
+            if(record.getAttendanceStatus() == null){
+                record.setAttendanceStatus("缺勤");
+            }
+
+            insertList.add(record);
+        }
+
+        if(!insertList.isEmpty()){
+            recordService.saveBatch(insertList);
+        }
+    }
+
+    public void teacherAttendanceRecord(LocalDateTime startDateTime, Integer timePeriod,
+                                        IUserService userService,
+                                        IAttendanceRuleCategoryService ruleCategoryService,
+                                        IHolidayDateService holidayDateService,
+                                        IWfTeacherleaveService wfTeacherleaveService,
+                                        ITeacherOutInRecordService teacherOutInRecordService,
+                                        ICarOutInRecordService carOutInRecordService,
+                                        ITeacherAttendanceRecordService recordService){
+        List<User> teacherList = userService.list(
+                new MPJLambdaWrapper<User>()
+                        .select(User::getId)
+                        .select(User.class, x -> VoToColumnUtil.fieldsToColumns(User.class).contains(x.getProperty()))
+                        .innerJoin(BaseTeacher.class, BaseTeacher::getUserId, User::getId)
+        );
+        List<Long> userIds = teacherList.stream().map(User::getId).collect(Collectors.toList());
+        Map<Long, AttendanceRuleDetailsUserVo> teacherTodyRuleByUserId = ruleCategoryService.getTeacherTodyRuleByUserId(userIds);
+
+        List<Integer> holidayTypes = Arrays.asList(1, 3);
+        List<HolidayDate> holidayDates = holidayDateService.list(
+                new QueryWrapper<HolidayDate>().lambda()
+                        .in(HolidayDate::getStatus, holidayTypes)
+        );
+        List<String> holidayDateList = holidayDates.stream().map(HolidayDate::getDate).collect(Collectors.toList());
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+        LocalDate queryDate = startDateTime.toLocalDate();
+        List<TeacherAttendanceRecord> insertList = new ArrayList<>();
+        List<String> weekList =Arrays.asList("SUNDAY", "SATURDAY");
+
+        List<HolidayDate> workHolidayDates = holidayDateService.list(
+                new QueryWrapper<HolidayDate>().lambda()
+                        .eq(HolidayDate::getStatus, 2)
+        );
+        List<String> workHolidayDateListg = workHolidayDates.stream().map(HolidayDate::getDate).collect(Collectors.toList());
+
+        for (User user : teacherList) {
+            TeacherAttendanceRecord record = new TeacherAttendanceRecord();
+            record.setCreateDate(LocalDateTime.now());
+            record.setAttendanceDate(queryDate);
+            record.setUserId(user.getId());
+            record.setTimeInterval(timePeriod);
+            AttendanceRuleDetailsUserVo detailsUserVo = teacherTodyRuleByUserId.get(user.getId());
+
+            if(detailsUserVo == null){
+                record.setAttendanceStatus("不考勤");
+                insertList.add(record);
+                continue;
+            }
+            AttendanceRuleDetails holidayRule = ruleCategoryService.getHolidayRuleByParam(user.getId());
+            if(((!workHolidayDateListg.contains(queryDate.format(formatter)) && weekList.contains(queryDate.getDayOfWeek().name()))
+                    || holidayDateList.contains(queryDate.format(formatter))) && (holidayRule.getIsAttendance() == null || holidayRule.getIsAttendance() == 0)){
+                record.setAttendanceStatus("不考勤");
+                insertList.add(record);
+                continue;
+            }
+
+            LocalDateTime startTime, endTime, amEndTime = null;
+
+            if(timePeriod == 1){
+                startTime = queryDate.atTime(5, 0, 0);
+                if(detailsUserVo.getAmStartTime() != null){
+                    startTime = queryDate.atTime(detailsUserVo.getAmStartTime());
+                }
+                endTime = queryDate.atTime(12, 0, 0);
+                if(detailsUserVo.getAmEndTime() != null){
+                    endTime = queryDate.atTime(detailsUserVo.getAmEndTime());
+                }
+            }else if(timePeriod == 2){
+                startTime = queryDate.atTime(12, 0, 0);
+                if(detailsUserVo.getPmStartTime() != null){
+                    startTime = queryDate.atTime(detailsUserVo.getPmStartTime());
+                }
+                endTime = queryDate.atTime(18, 0, 0);
+                if(detailsUserVo.getPmEndTime() != null){
+                    endTime = queryDate.atTime(detailsUserVo.getPmEndTime());
+                }
+                amEndTime  = queryDate.atTime(12, 0, 0);
+                if(detailsUserVo.getAmEndTime() != null){
+                    amEndTime = queryDate.atTime(detailsUserVo.getAmEndTime());
+                }
+            }else{
+                startTime = queryDate.atTime(0, 0, 0);
+                if(detailsUserVo.getEveningStartTime() != null){
+                    startTime = queryDate.atTime(detailsUserVo.getEveningStartTime());
+                }
+                endTime = queryDate.atTime(23, 59, 59);
+                if(detailsUserVo.getEveningEndTime() != null){
+                    endTime = queryDate.atTime(detailsUserVo.getEveningEndTime());
+                }
+            }
+            record.setStartTime(startTime);
+            record.setEndTime(endTime);
+
+            WfTeacherleave studentLeave = wfTeacherleaveService.getLeaveByUserId(startTime, endTime, user.getId());
+            if(studentLeave != null){
+                record.setAttendanceStatus(studentLeave.getLeaveType());
                 continue;
             }
             TeacherOutInRecordDto outInDto = new TeacherOutInRecordDto();
@@ -225,7 +359,7 @@ public class AttendanceRecordTask {
                                 .le(CarOutInRecord::getRecordTime, endTime)
                                 .eq("DATE_FORMAT(record_time, '%Y-%m-%d')", endTime.toLocalDate())
                                 .eq(CarMessageApply::getUserId, record.getUserId())
-                                .ge(timePeriod != null && timePeriod == 2 && amEndTime != null, CarOutInRecord::getRecordTime, amEndTime)
+                                .ge(timePeriod == 2 && amEndTime != null, CarOutInRecord::getRecordTime, amEndTime)
                                 .eq(CarOutInRecord::getStatus, OutInStatusEnum.enter.getCode())
                                 .orderByAsc(CarOutInRecord::getRecordTime)
                 );
@@ -253,6 +387,11 @@ public class AttendanceRecordTask {
         }
 
         if(!insertList.isEmpty()){
+            recordService.remove(
+                    new QueryWrapper<TeacherAttendanceRecord>().lambda()
+                            .eq(TeacherAttendanceRecord::getAttendanceDate, startDateTime.toLocalDate())
+                            .eq(TeacherAttendanceRecord::getTimeInterval, timePeriod)
+            );
             recordService.saveBatch(insertList);
         }
     }

+ 2 - 2
src/test/java/com/xjrsoft/module/job/AttendanceRecordTaskTest.java

@@ -75,8 +75,8 @@ class AttendanceRecordTaskTest {
     @Test
     public void execute() {
 
-        LocalDateTime now = LocalDateTime.of(2024, 9, 1, 0, 0, 0);
-        for (int i = 0; i < 30; i ++){
+        LocalDateTime now = LocalDateTime.of(2024, 10, 1, 0, 0, 0);
+        for (int i = 0; i < 21; i ++){
             LocalDateTime startDateTime = now.plusDays(i).withHour(0).withMinute(0).withSecond(0).withNano(0);
             LocalDateTime endDateTime = startDateTime.plusDays(i).withHour(23).withMinute(59).withSecond(59);