Просмотр исходного кода

为文档添加ofd相关格式

大数据与最优化研究所 3 месяцев назад
Родитель
Сommit
5247c45554

+ 1 - 1
Makefile

@@ -5,7 +5,7 @@ merge-pre:
 	git checkout pre;git merge dev;git push;git checkout dev;
 
 create-tag:
-	git checkout master;git tag v5.3.0;git push origin --tags;git checkout dev;
+	git checkout master;git tag v5.3.1;git push origin --tags;git checkout dev;
 
 remove-tag:
 	git tag -d v1.2.0;git push origin :refs/tags/v1.1.8;

+ 12 - 0
pom.xml

@@ -536,6 +536,18 @@
             <artifactId>apm-toolkit-trace</artifactId>
             <version>${apm.toolkit.version}</version>
         </dependency>
+
+        <!-- Spring Boot Retry Starter -->
+        <dependency>
+            <groupId>org.springframework.retry</groupId>
+            <artifactId>spring-retry</artifactId>
+        </dependency>
+
+        <!-- Spring Boot AOP Starter -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-aop</artifactId>
+        </dependency>
     </dependencies>
 
     <build>

+ 6 - 1
src/main/java/com/xjrsoft/config/FileCheckRuleConfig.java

@@ -61,7 +61,9 @@ public final class FileCheckRuleConfig {
             .withExtensions(
                     "pdf", "doc", "docx", "xls", "xlsx", "ppt", "pptx", "txt",
                     // WPS 文件扩展名
-                    "wps", "et", "dps", "wpt", "ett", "dpt", "vsd", "vsdx"
+                    "wps", "et", "dps", "wpt", "ett", "dpt", "vsd", "vsdx",
+                    // OFD 文件扩展名
+                    "ofd"
             )
             .withMimeTypes(
                     "application/pdf",
@@ -80,6 +82,9 @@ public final class FileCheckRuleConfig {
                     "application/wps-office.wpt",
                     "application/wps-office.ett",
                     "application/wps-office.dpt",
+                    // OFD MIME 类型
+                    "application/ofd",
+                    "application/x-ofd",
                     // 其他可能的 MIME 类型
                     "application/octet-stream", // 某些 WPS 文件可能被识别为此类型
                     "application/x-msdownload"

+ 9 - 9
src/main/resources/application-prod.yml

@@ -5,21 +5,21 @@ spring:
   datasource:
     type: com.alibaba.druid.pool.DruidDataSource
     driver-class-name: com.mysql.cj.jdbc.Driver
-#    url: jdbc:mysql://219.153.208.35:3306/smart_campus?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true&autoReconnect=true&failOverReadOnly=false
-    url: jdbc:mysql://219.153.208.37:53256/smart_campus?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true&autoReconnect=true&failOverReadOnly=false
+    url: jdbc:mysql://219.153.208.35:3306/smart_campus?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true&autoReconnect=true&failOverReadOnly=false
+#    url: jdbc:mysql://219.153.208.37:53256/smart_campus?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true&autoReconnect=true&failOverReadOnly=false
     username: smart_campus
     password: W2Xk@8QFe3hYR7QZ?-yY
 
 
   redis:
-#    database: 10
-#    host: 219.153.208.35
-#    port: 6379
-#    password: huHJMucfC!tJ59Ri   # 密码(默认为空)
-    database: 6
-    host: 10.150.10.136
+    database: 10
+    host: 219.153.208.35
     port: 6379
-    password: 9mwar,BNq}oMa63cUd?R   # 密码(默认为空)
+    password: huHJMucfC!tJ59Ri   # 密码(默认为空)
+#    database: 6
+#    host: 10.150.10.136
+#    port: 6379
+#    password: 9mwar,BNq}oMa63cUd?R   # 密码(默认为空)
     timeout: 6000ms  # 连接超时时长(毫秒)
     jedis:
       pool:

+ 85 - 0
src/test/java/com/xjrsoft/module/student/controller/StudentReportPlanControllerTest.java

@@ -0,0 +1,85 @@
+package com.xjrsoft.module.student.controller;
+
+import cn.dev33.satoken.stp.StpUtil;
+import cn.hutool.core.bean.BeanUtil;
+import com.github.yulichang.wrapper.MPJLambdaWrapper;
+import com.xjrsoft.common.model.result.RT;
+import com.xjrsoft.common.utils.LocalDateTimeUtil;
+import com.xjrsoft.common.utils.VoToColumnUtil;
+import com.xjrsoft.module.banding.entity.BandingTask;
+import com.xjrsoft.module.banding.service.IBandingTaskClassStudentService;
+import com.xjrsoft.module.student.dto.UpdateStudentReportPlanDto;
+import com.xjrsoft.module.student.entity.EnrollmentPlan;
+import com.xjrsoft.module.student.entity.StudentReportPlan;
+import com.xjrsoft.module.student.service.IEnrollmentPlanService;
+import com.xjrsoft.module.student.service.IStudentReportPlanService;
+import com.xjrsoft.module.student.vo.StudentReportPlanVo;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import java.time.LocalDateTime;
+import java.util.Date;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+@SpringBootTest
+class StudentReportPlanControllerTest {
+
+    @BeforeEach
+    void setUp() {
+        // 模拟用户登录
+        StpUtil.login(1000000000000000000L); // 假设用户ID为1
+    }
+
+    @AfterEach
+    void tearDown() {
+        // 清理会话
+        StpUtil.logout();
+    }
+
+    @Autowired
+    private IEnrollmentPlanService enrollmentPlanService;
+
+    @Autowired
+    private IStudentReportPlanService studentReportPlanService;
+
+    @Autowired
+    private IBandingTaskClassStudentService taskClassStudentService;
+
+    @Test
+    void newStudentPlan() {
+        EnrollmentPlan enrollmentPlan = enrollmentPlanService.getById(1897950348853186562L);
+        StudentReportPlan plan = studentReportPlanService.getOne(
+                new MPJLambdaWrapper<StudentReportPlan>()
+                        .select(StudentReportPlan::getId)
+                        .select(StudentReportPlan.class, x -> VoToColumnUtil.fieldsToColumns(StudentReportPlan.class).contains(x.getProperty()))
+                        .innerJoin(BandingTask.class, BandingTask::getId, StudentReportPlan::getBandingTaskId)
+                        .eq(BandingTask::getEnrollType, enrollmentPlan.getEnrollType())
+                        .eq(BandingTask::getGradeId, enrollmentPlan.getGradeId())
+                        .eq(StudentReportPlan::getCategory, 3)
+        );
+        System.out.println("kdjfiajf");
+
+    }
+
+    @Test
+    void update() {
+        UpdateStudentReportPlanDto dto = new UpdateStudentReportPlanDto();
+        dto.setId(1917442536876085249L);
+        dto.setSemesterId(1868532124600545280L);
+        dto.setName("2025级null新生报到");
+        StudentReportPlan reportPlan = studentReportPlanService.getById(dto.getId());
+        BeanUtil.copyProperties(dto, reportPlan);
+        if((reportPlan.getCategory() == 2 || reportPlan.getCategory() == 3) && LocalDateTimeUtil.isDateTimeInRange(LocalDateTime.now(), reportPlan.getStartTime(), reportPlan.getEndTime())){
+            reportPlan.setStatus(1);
+        }
+        if(reportPlan.getCategory() == 3){
+            taskClassStudentService.syncStudentData(reportPlan);
+        }
+        System.out.println("kdjfiajf");
+
+    }
+}

+ 673 - 204
src/test/java/com/xjrsoft/module/student/service/impl/StudentReportRecordServiceImplTest.java

@@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.github.yulichang.wrapper.MPJLambdaWrapper;
+import com.google.common.collect.Lists;
 import com.xjrsoft.common.constant.GlobalConstant;
 import com.xjrsoft.common.enums.ArchivesStatusEnum;
 import com.xjrsoft.common.enums.DeleteMark;
@@ -41,6 +42,8 @@ import com.xjrsoft.module.student.entity.*;
 import com.xjrsoft.module.student.mapper.BaseNewStudentMapper;
 import com.xjrsoft.module.student.mapper.StudentReportPlanMapper;
 import com.xjrsoft.module.student.service.*;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.ObjectUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.junit.jupiter.api.AfterEach;
@@ -48,6 +51,12 @@ import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.dao.CannotAcquireLockException;
+import org.springframework.dao.RecoverableDataAccessException;
+import org.springframework.retry.annotation.Backoff;
+import org.springframework.retry.annotation.Recover;
+import org.springframework.retry.annotation.Retryable;
+import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.time.LocalDate;
@@ -58,6 +67,7 @@ import java.util.Comparator;
 import java.util.Date;
 import java.util.List;
 import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.stream.Collectors;
 
 import static org.junit.jupiter.api.Assertions.*;
@@ -67,6 +77,7 @@ import static org.junit.jupiter.api.Assertions.*;
  * @date 2025/2/11
  */
 @SpringBootTest
+@Slf4j
 class StudentReportRecordServiceImplTest {
 
     @Autowired
@@ -131,232 +142,690 @@ class StudentReportRecordServiceImplTest {
         }
     }
 
+//    @Test
+//    @Transactional(rollbackFor = Exception.class)
+//    void tryReadingSign() {
+//        LocalDateTime now = LocalDateTime.now();
+//        // 查出所有有分班存在的新生信息
+//        MPJLambdaWrapper<BaseNewStudent> baseNewStudentMPJLambdaWrapper = new MPJLambdaWrapper<>();
+//        baseNewStudentMPJLambdaWrapper
+//                .select(BaseNewStudent::getId)
+//                .select(BaseNewStudent.class, x -> VoToColumnUtil.fieldsToColumns(BaseNewStudent.class).contains(x.getProperty()))
+//                .innerJoin(BandingTaskClassStudent.class, BandingTaskClassStudent::getNewStudentId, BaseNewStudent::getId)
+//                .innerJoin(BandingTaskClass.class, BandingTaskClass::getId, BandingTaskClassStudent::getBandingTaskClassId)
+//                .innerJoin(BandingTask.class, BandingTask::getId, BandingTaskClass::getBandingTaskId)
+//                .eq(BandingTask::getGradeId, 1868532405673439232L)
+//                .isNotNull(BandingTaskClassStudent::getBandingTaskClassId)
+//                ;
+//        List<BaseNewStudent> baseNewStudents =  newStudentMapper.selectJoinList(BaseNewStudent.class, baseNewStudentMPJLambdaWrapper);
+//
+//        // 进行学生数据处理,学生信息已经存在的要修改学生班级数据
+//        for(BaseNewStudent student : baseNewStudents){
+//            BandingTaskClass taskClass = taskClassService.getOne(
+//                    new MPJLambdaWrapper<BandingTaskClass>()
+//                            .select(BandingTaskClass::getId)
+//                            .select(BandingTaskClass.class, x -> VoToColumnUtil.fieldsToColumns(BandingTaskClass.class).contains(x.getProperty()))
+//                            .innerJoin(BandingTaskClassStudent.class, BandingTaskClassStudent::getBandingTaskClassId, BandingTaskClass::getId)
+//                            .eq(BandingTaskClassStudent::getNewStudentId, student.getId())
+//                            .eq(BandingTaskClassStudent::getDeleteMark, DeleteMark.NODELETE.getCode())
+//                            .eq(BandingTaskClassStudent::getEnabledMark, EnabledMark.ENABLED.getCode())
+//                            .eq(BandingTaskClass::getDeleteMark, DeleteMark.NODELETE.getCode())
+//                            .eq(BandingTaskClass::getEnabledMark, EnabledMark.ENABLED.getCode())
+//            );
+//
+//            //先查询是否已经存在这个班级,如果存在就更新,不存在就新增
+//            BaseClass baseClass = classMapper.selectById(taskClass.getBaseClassId());
+//            if(ObjectUtils.isEmpty(baseClass)){
+//                BandingTask task = taskService.getById(taskClass.getBandingTaskId());
+//                List<BaseClass> classList = classMapper.selectList(
+//                        new QueryWrapper<BaseClass>().lambda()
+//                                .eq(BaseClass::getDeleteMark, DeleteMark.NODELETE.getCode())
+//                                .eq(BaseClass::getGradeId, task.getGradeId())
+//                                .eq(BaseClass::getEnrollType, task.getEnrollType())
+//                );
+//                BaseGrade baseGrade = gradeMapper.selectById(task.getGradeId());
+//                List<BaseClass> classCodes = classList.stream().filter(x -> x.getCode() != null)
+//                        .sorted(Comparator.comparing(BaseClass::getCode))
+//                        .collect(Collectors.toList());
+//
+//                String classCode = null;
+//                if(!classCodes.isEmpty()){
+//                    classCode = classCodes.get(0).getCode();
+//                }
+//
+//                baseClass = new BaseClass();
+//                BeanUtil.copyProperties(taskClass, baseClass);
+//                baseClass.setCreateDate(new Date());
+//                baseClass.setCreateUserId(StpUtil.getLoginIdAsLong());
+//                int i = 0;
+//                if(NumberUtil.isNumber(classCode)){
+//                    i = Integer.parseInt(classCode.trim().substring(classCode.length() - 3));
+//                    i ++;
+//                    baseClass.setCode(baseGrade.getTitle().replace("年", "") + String.format("%03d", i));
+//                }
+//                baseClass.setGradeId(task.getGradeId());
+//                BaseMajorSet majorSet = majorSetMapper.selectById(baseClass.getMajorSetId());
+//                baseClass.setOrgId(majorSet.getDepartmentId());
+//                baseClass.setId(null);
+//                classMapper.insert(baseClass);
+//
+//                taskClass.setBaseClassId(baseClass.getId());
+//                taskClassService.updateById(taskClass);
+//            }
+//
+//            //根据身份证号查询这个学生是否存在
+//            User user = userService.getOne(
+//                    new MPJLambdaWrapper<User>()
+//                            .select(User::getId)
+//                            .select(User.class, x -> VoToColumnUtil.fieldsToColumns(User.class).contains(x.getProperty()))
+//                            .eq(User::getCredentialNumber, student.getCredentialNumber())
+//                            .eq(User::getEnabledMark, EnabledMark.ENABLED.getCode())
+//            );
+//            if(ObjectUtils.isNotEmpty(user)){
+//                BaseStudentSchoolRoll isSchoolRoll = rollService.getOne(
+//                        new MPJLambdaWrapper<BaseStudentSchoolRoll>()
+//                                .disableLogicDel()
+//                                .select(BaseStudentSchoolRoll::getId)
+//                                .select(BaseStudentSchoolRoll.class, x -> VoToColumnUtil.fieldsToColumns(BaseStudentSchoolRoll.class).contains(x.getProperty()))
+//                                .eq(BaseStudentSchoolRoll::getUserId, user.getId())
+//                );
+//                if(ObjectUtils.isEmpty(isSchoolRoll)){
+//                    BaseStudentSchoolRoll schoolRoll = new BaseStudentSchoolRoll();
+//                    schoolRoll.setUserId(user.getId());
+//                    if(student.getScore() != null){
+//                        schoolRoll.setGraduatedScore(student.getScore().doubleValue());
+//                    }
+//                    schoolRoll.setInternshipState("IT_0001");
+//                    schoolRoll.setGraduatedUniversity(student.getGraduateSchool());
+//                    schoolRoll.setClassId(baseClass.getId());
+//                    schoolRoll.setMajorSetId(baseClass.getMajorSetId());
+//                    schoolRoll.setStduyStatus(student.getStduyStatus());
+//                    schoolRoll.setDeleteMark(DeleteMark.NODELETE.getCode());
+//                    schoolRoll.setEnrollType(baseClass.getEnrollType());
+//                    schoolRoll.setStudentType(student.getSource());
+//                    schoolRoll.setGradeId(baseClass.getGradeId());
+//                    schoolRoll.setArchivesStatus(ArchivesStatusEnum.FB2901.getCode());
+//                    schoolRoll.setCreateDate(now);
+//                    rollService.save(schoolRoll);
+//                }
+//
+//                BaseStudent isBaseStudent = studentService.getOne(
+//                        new QueryWrapper<BaseStudent>().lambda()
+//                                .eq(BaseStudent::getUserId, user.getId())
+//                );
+//                if(ObjectUtils.isEmpty(isBaseStudent)){
+//                    BaseStudent baseStudent = new BaseStudent() {{
+//                        setUserId(user.getId());
+//                        setCreateDate(now);
+//                        setStudentId(student.getCredentialNumber());
+//                        if(student.getHeight() != null){
+//                            setHeight(student.getHeight().doubleValue());
+//                        }
+//                        if(student.getWeight() != null){
+//                            setWeight(student.getWeight().doubleValue());
+//                        }
+//                        setIsNormal(1);
+//                    }};
+//                    studentService.save(baseStudent);
+//                }
+//
+//                // 学生已存在,则修改班级信息
+//                rollService.updateStudentClass(baseClass.getId(), user.getId());
+//                // 激活学生
+//                rollService.activateStudent(user.getId());
+//            }else{
+//                LocalDate birthDate = getBirthDate(student.getCredentialNumber());
+//                User xjrUser = new User() {{
+//                    setCreateDate(now);
+//                    // setPassword(BCrypt.hashpw(propertiesConfig.getDefaultPassword(), BCrypt.gensalt()));
+//
+//                    if (StringUtils.isEmpty(student.getCredentialNumber())) {
+//                        throw new MyException(student.getName() + "证件号为空,请填写后提交");
+//                    }
+//                    String credentialNumber = student.getCredentialNumber();
+//                    String lastSixDigits = credentialNumber.length() <= 6
+//                            ? credentialNumber
+//                            : credentialNumber.substring(credentialNumber.length() - 6);
+//                    setPassword(BCrypt.hashpw(lastSixDigits, BCrypt.gensalt()));
+//
+//                    setName(student.getName());
+//                    setUserName(student.getCredentialNumber());
+//                    setCredentialNumber(student.getCredentialNumber());
+//                    setCredentialType("ZZLS10007");
+//                    setMobile(student.getMobile());
+//                    setEnabledMark(EnabledMark.ENABLED.getCode());
+//                    setGender(student.getGender());
+//                    setIsChangePassword(1);
+//                    setBirthDate(birthDate.atStartOfDay());
+//                }};
+//                userService.save(xjrUser);
+//
+//                UserRoleRelation userRoleRelation = new UserRoleRelation() {{
+//                    setRoleId(RoleEnum.STUDENT.getCode());
+//                    setUserId(xjrUser.getId());
+//                }};
+//                roleRelationService.save(userRoleRelation);
+//
+//                BaseStudent baseStudent = new BaseStudent() {{
+//                    setUserId(xjrUser.getId());
+//                    setCreateDate(now);
+//                    setStudentId(student.getCredentialNumber());
+//                    if(student.getHeight() != null){
+//                        setHeight(student.getHeight().doubleValue());
+//                    }
+//                    if(student.getWeight() != null){
+//                        setWeight(student.getWeight().doubleValue());
+//                    }
+//                    setIsNormal(1);
+//                }};
+//                studentService.save(baseStudent);
+//
+//                BaseStudentSchoolRoll schoolRoll = new BaseStudentSchoolRoll();
+//                schoolRoll.setUserId(xjrUser.getId());
+//                if(student.getScore() != null){
+//                    schoolRoll.setGraduatedScore(student.getScore().doubleValue());
+//                }
+//                schoolRoll.setInternshipState("IT_0001");
+//                schoolRoll.setGraduatedUniversity(student.getGraduateSchool());
+//                schoolRoll.setClassId(baseClass.getId());
+//                schoolRoll.setMajorSetId(baseClass.getMajorSetId());
+//                schoolRoll.setStduyStatus(student.getStduyStatus());
+//                schoolRoll.setDeleteMark(DeleteMark.NODELETE.getCode());
+//                schoolRoll.setEnrollType(baseClass.getEnrollType());
+//                schoolRoll.setStudentType(student.getSource());
+//                schoolRoll.setGradeId(baseClass.getGradeId());
+//                schoolRoll.setArchivesStatus(ArchivesStatusEnum.FB2901.getCode());
+//                schoolRoll.setCreateDate(now);
+//
+//                rollService.save(schoolRoll);
+//
+//                BaseStudentFamily studentFamily = new BaseStudentFamily() {{
+//                    setCreateDate(now);
+//                    setUserId(xjrUser.getId());
+//                    setTelephone(student.getFamilyMobile());
+//                    setAddress(student.getFamilyAddress());
+//                }};
+//                familyService.save(studentFamily);
+//
+//                CompletableFuture.runAsync(() -> {
+//                    List<User> userList = userService.list();
+//                    redisUtil.set(GlobalConstant.USER_CACHE_KEY, userList);
+//
+//                    List<UserRoleRelation> userRoleRelationList = roleRelationService.list(Wrappers.lambdaQuery(UserRoleRelation.class));
+//                    redisUtil.set(GlobalConstant.USER_ROLE_RELATION_CACHE_KEY, userRoleRelationList);
+//                });
+//            }
+//        }
+//    }
+//
+//    LocalDate getBirthDate(String idCardNumber){
+//        // 获取出生日期前6位,即yyyyMM
+//        String birthdayString = idCardNumber.substring(6, 14);
+//
+//        // 将字符串解析为LocalDate对象
+//        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
+//        try {
+//            return LocalDate.parse(birthdayString, formatter);
+//        }catch (Exception e){
+//            throw new MyException("身份证号填写错误,无法提取出生日期");
+//        }
+//    }
+
     @Test
-    @Transactional(rollbackFor = Exception.class)
     void tryReadingSign() {
+        log.info("开始处理学生签到数据...");
         LocalDateTime now = LocalDateTime.now();
-        // 查出所有有分班存在的新生信息
-        MPJLambdaWrapper<BaseNewStudent> baseNewStudentMPJLambdaWrapper = new MPJLambdaWrapper<>();
-        baseNewStudentMPJLambdaWrapper
-                .select(BaseNewStudent::getId)
+
+        try {
+            // 1. 查询需要处理的学生(不在事务内)
+            List<BaseNewStudent> baseNewStudents = queryStudentsToProcess();
+            log.info("共找到 {} 个需要处理的学生", baseNewStudents.size());
+
+            if (baseNewStudents.isEmpty()) {
+                log.info("没有需要处理的学生数据");
+                return;
+            }
+
+            // 2. 分批处理,每批50个学生
+            int batchSize = 50;
+            List<List<BaseNewStudent>> batches = Lists.partition(baseNewStudents, batchSize);
+
+            AtomicInteger successCount = new AtomicInteger(0);
+            AtomicInteger failCount = new AtomicInteger(0);
+
+            for (int i = 0; i < batches.size(); i++) {
+                List<BaseNewStudent> batch = batches.get(i);
+                log.info("正在处理第 {} 批,共 {} 个学生", i + 1, batch.size());
+
+                try {
+                    ProcessResult result = processBatchWithRetry(batch, now, 3);
+                    successCount.addAndGet(result.getSuccessCount());
+                    failCount.addAndGet(result.getFailCount());
+                } catch (Exception e) {
+                    log.error("处理第 {} 批学生时发生异常", i + 1, e);
+                    failCount.addAndGet(batch.size());
+                }
+            }
+
+            log.info("处理完成: 成功 {} 个, 失败 {} 个", successCount.get(), failCount.get());
+
+        } catch (Exception e) {
+            log.error("处理学生签到数据时发生严重错误", e);
+            throw new RuntimeException("处理失败", e);
+        }
+    }
+
+    /**
+     * 查询需要处理的学生
+     */
+    private List<BaseNewStudent> queryStudentsToProcess() {
+        MPJLambdaWrapper<BaseNewStudent> wrapper = new MPJLambdaWrapper<>();
+        wrapper.select(BaseNewStudent::getId)
                 .select(BaseNewStudent.class, x -> VoToColumnUtil.fieldsToColumns(BaseNewStudent.class).contains(x.getProperty()))
                 .innerJoin(BandingTaskClassStudent.class, BandingTaskClassStudent::getNewStudentId, BaseNewStudent::getId)
                 .innerJoin(BandingTaskClass.class, BandingTaskClass::getId, BandingTaskClassStudent::getBandingTaskClassId)
                 .innerJoin(BandingTask.class, BandingTask::getId, BandingTaskClass::getBandingTaskId)
                 .eq(BandingTask::getGradeId, 1868532405673439232L)
-                .isNotNull(BandingTaskClassStudent::getBandingTaskClassId)
-                ;
-        List<BaseNewStudent> baseNewStudents =  newStudentMapper.selectJoinList(BaseNewStudent.class, baseNewStudentMPJLambdaWrapper);
-
-        // 进行学生数据处理,学生信息已经存在的要修改学生班级数据
-        for(BaseNewStudent student : baseNewStudents){
-            BandingTaskClass taskClass = taskClassService.getOne(
-                    new MPJLambdaWrapper<BandingTaskClass>()
-                            .select(BandingTaskClass::getId)
-                            .select(BandingTaskClass.class, x -> VoToColumnUtil.fieldsToColumns(BandingTaskClass.class).contains(x.getProperty()))
-                            .innerJoin(BandingTaskClassStudent.class, BandingTaskClassStudent::getBandingTaskClassId, BandingTaskClass::getId)
-                            .eq(BandingTaskClassStudent::getNewStudentId, student.getId())
-                            .eq(BandingTaskClassStudent::getDeleteMark, DeleteMark.NODELETE.getCode())
-                            .eq(BandingTaskClassStudent::getEnabledMark, EnabledMark.ENABLED.getCode())
-                            .eq(BandingTaskClass::getDeleteMark, DeleteMark.NODELETE.getCode())
-                            .eq(BandingTaskClass::getEnabledMark, EnabledMark.ENABLED.getCode())
-            );
-
-            //先查询是否已经存在这个班级,如果存在就更新,不存在就新增
-            BaseClass baseClass = classMapper.selectById(taskClass.getBaseClassId());
-            if(ObjectUtils.isEmpty(baseClass)){
-                BandingTask task = taskService.getById(taskClass.getBandingTaskId());
-                List<BaseClass> classList = classMapper.selectList(
-                        new QueryWrapper<BaseClass>().lambda()
-                                .eq(BaseClass::getDeleteMark, DeleteMark.NODELETE.getCode())
-                                .eq(BaseClass::getGradeId, task.getGradeId())
-                                .eq(BaseClass::getEnrollType, task.getEnrollType())
-                );
-                BaseGrade baseGrade = gradeMapper.selectById(task.getGradeId());
-                List<BaseClass> classCodes = classList.stream().filter(x -> x.getCode() != null)
-                        .sorted(Comparator.comparing(BaseClass::getCode))
-                        .collect(Collectors.toList());
-
-                String classCode = null;
-                if(!classCodes.isEmpty()){
-                    classCode = classCodes.get(0).getCode();
-                }
+                .isNotNull(BandingTaskClassStudent::getBandingTaskClassId);
 
-                baseClass = new BaseClass();
-                BeanUtil.copyProperties(taskClass, baseClass);
-                baseClass.setCreateDate(new Date());
-                baseClass.setCreateUserId(StpUtil.getLoginIdAsLong());
-                int i = 0;
-                if(NumberUtil.isNumber(classCode)){
-                    i = Integer.parseInt(classCode.trim().substring(classCode.length() - 3));
-                    i ++;
-                    baseClass.setCode(baseGrade.getTitle().replace("年", "") + String.format("%03d", i));
-                }
-                baseClass.setGradeId(task.getGradeId());
-                BaseMajorSet majorSet = majorSetMapper.selectById(baseClass.getMajorSetId());
-                baseClass.setOrgId(majorSet.getDepartmentId());
-                baseClass.setId(null);
-                classMapper.insert(baseClass);
-
-                taskClass.setBaseClassId(baseClass.getId());
-                taskClassService.updateById(taskClass);
-            }
+        return newStudentMapper.selectJoinList(BaseNewStudent.class, wrapper);
+    }
 
-            //根据身份证号查询这个学生是否存在
-            User user = userService.getOne(
-                    new MPJLambdaWrapper<User>()
-                            .select(User::getId)
-                            .select(User.class, x -> VoToColumnUtil.fieldsToColumns(User.class).contains(x.getProperty()))
-                            .eq(User::getCredentialNumber, student.getCredentialNumber())
-                            .eq(User::getEnabledMark, EnabledMark.ENABLED.getCode())
-            );
-            if(ObjectUtils.isNotEmpty(user)){
-                BaseStudentSchoolRoll isSchoolRoll = rollService.getOne(
-                        new MPJLambdaWrapper<BaseStudentSchoolRoll>()
-                                .disableLogicDel()
-                                .select(BaseStudentSchoolRoll::getId)
-                                .select(BaseStudentSchoolRoll.class, x -> VoToColumnUtil.fieldsToColumns(BaseStudentSchoolRoll.class).contains(x.getProperty()))
-                                .eq(BaseStudentSchoolRoll::getUserId, user.getId())
-                );
-                if(ObjectUtils.isEmpty(isSchoolRoll)){
-                    BaseStudentSchoolRoll schoolRoll = new BaseStudentSchoolRoll();
-                    schoolRoll.setUserId(user.getId());
-                    if(student.getScore() != null){
-                        schoolRoll.setGraduatedScore(student.getScore().doubleValue());
-                    }
-                    schoolRoll.setInternshipState("IT_0001");
-                    schoolRoll.setGraduatedUniversity(student.getGraduateSchool());
-                    schoolRoll.setClassId(baseClass.getId());
-                    schoolRoll.setMajorSetId(baseClass.getMajorSetId());
-                    schoolRoll.setStduyStatus(student.getStduyStatus());
-                    schoolRoll.setDeleteMark(DeleteMark.NODELETE.getCode());
-                    schoolRoll.setEnrollType(baseClass.getEnrollType());
-                    schoolRoll.setStudentType(student.getSource());
-                    schoolRoll.setGradeId(baseClass.getGradeId());
-                    schoolRoll.setArchivesStatus(ArchivesStatusEnum.FB2901.getCode());
-                    schoolRoll.setCreateDate(now);
-                    rollService.save(schoolRoll);
+    /**
+     * 带重试的批次处理
+     */
+    private ProcessResult processBatchWithRetry(List<BaseNewStudent> batch, LocalDateTime now, int maxRetries) {
+        ProcessResult result = new ProcessResult();
+
+        for (int retry = 0; retry < maxRetries; retry++) {
+            try {
+                if (retry > 0) {
+                    log.warn("第 {} 次重试处理批次,学生数量: {}", retry + 1, batch.size());
+                    Thread.sleep(2000 * retry); // 指数退避
                 }
 
-                BaseStudent isBaseStudent = studentService.getOne(
-                        new QueryWrapper<BaseStudent>().lambda()
-                                .eq(BaseStudent::getUserId, user.getId())
-                );
-                if(ObjectUtils.isEmpty(isBaseStudent)){
-                    BaseStudent baseStudent = new BaseStudent() {{
-                        setUserId(user.getId());
-                        setCreateDate(now);
-                        setStudentId(student.getCredentialNumber());
-                        if(student.getHeight() != null){
-                            setHeight(student.getHeight().doubleValue());
-                        }
-                        if(student.getWeight() != null){
-                            setWeight(student.getWeight().doubleValue());
-                        }
-                        setIsNormal(1);
-                    }};
-                    studentService.save(baseStudent);
-                }
+                ProcessResult batchResult = processBatchInTransaction(batch, now);
+                log.info("批次处理完成: 成功 {} 个, 失败 {} 个",
+                        batchResult.getSuccessCount(), batchResult.getFailCount());
 
-                // 学生已存在,则修改班级信息
-                rollService.updateStudentClass(baseClass.getId(), user.getId());
-                // 激活学生
-                rollService.activateStudent(user.getId());
-            }else{
-                LocalDate birthDate = getBirthDate(student.getCredentialNumber());
-                User xjrUser = new User() {{
-                    setCreateDate(now);
-                    // setPassword(BCrypt.hashpw(propertiesConfig.getDefaultPassword(), BCrypt.gensalt()));
-
-                    if (StringUtils.isEmpty(student.getCredentialNumber())) {
-                        throw new MyException(student.getName() + "证件号为空,请填写后提交");
-                    }
-                    String credentialNumber = student.getCredentialNumber();
-                    String lastSixDigits = credentialNumber.length() <= 6
-                            ? credentialNumber
-                            : credentialNumber.substring(credentialNumber.length() - 6);
-                    setPassword(BCrypt.hashpw(lastSixDigits, BCrypt.gensalt()));
-
-                    setName(student.getName());
-                    setUserName(student.getCredentialNumber());
-                    setCredentialNumber(student.getCredentialNumber());
-                    setCredentialType("ZZLS10007");
-                    setMobile(student.getMobile());
-                    setEnabledMark(EnabledMark.ENABLED.getCode());
-                    setGender(student.getGender());
-                    setIsChangePassword(1);
-                    setBirthDate(birthDate.atStartOfDay());
-                }};
-                userService.save(xjrUser);
-
-                UserRoleRelation userRoleRelation = new UserRoleRelation() {{
-                    setRoleId(RoleEnum.STUDENT.getCode());
-                    setUserId(xjrUser.getId());
-                }};
-                roleRelationService.save(userRoleRelation);
-
-                BaseStudent baseStudent = new BaseStudent() {{
-                    setUserId(xjrUser.getId());
-                    setCreateDate(now);
-                    setStudentId(student.getCredentialNumber());
-                    if(student.getHeight() != null){
-                        setHeight(student.getHeight().doubleValue());
-                    }
-                    if(student.getWeight() != null){
-                        setWeight(student.getWeight().doubleValue());
-                    }
-                    setIsNormal(1);
-                }};
-                studentService.save(baseStudent);
-
-                BaseStudentSchoolRoll schoolRoll = new BaseStudentSchoolRoll();
-                schoolRoll.setUserId(xjrUser.getId());
-                if(student.getScore() != null){
-                    schoolRoll.setGraduatedScore(student.getScore().doubleValue());
+                return batchResult;
+
+            } catch (CannotAcquireLockException e) {
+                log.warn("批次处理锁等待异常,准备重试: {}", e.getMessage());
+                if (retry == maxRetries - 1) {
+                    result.setFailCount(batch.size());
+                    log.error("批次处理最终失败,所有重试尝试均未成功");
+                }
+            } catch (RecoverableDataAccessException e) {
+                log.warn("批次处理通信异常,准备重试: {}", e.getMessage());
+                if (retry == maxRetries - 1) {
+                    result.setFailCount(batch.size());
+                    log.error("批次处理最终失败,通信问题重试未成功");
                 }
-                schoolRoll.setInternshipState("IT_0001");
-                schoolRoll.setGraduatedUniversity(student.getGraduateSchool());
-                schoolRoll.setClassId(baseClass.getId());
-                schoolRoll.setMajorSetId(baseClass.getMajorSetId());
-                schoolRoll.setStduyStatus(student.getStduyStatus());
-                schoolRoll.setDeleteMark(DeleteMark.NODELETE.getCode());
-                schoolRoll.setEnrollType(baseClass.getEnrollType());
-                schoolRoll.setStudentType(student.getSource());
-                schoolRoll.setGradeId(baseClass.getGradeId());
-                schoolRoll.setArchivesStatus(ArchivesStatusEnum.FB2901.getCode());
-                schoolRoll.setCreateDate(now);
-
-                rollService.save(schoolRoll);
-
-                BaseStudentFamily studentFamily = new BaseStudentFamily() {{
-                    setCreateDate(now);
-                    setUserId(xjrUser.getId());
-                    setTelephone(student.getFamilyMobile());
-                    setAddress(student.getFamilyAddress());
-                }};
-                familyService.save(studentFamily);
-
-                CompletableFuture.runAsync(() -> {
-                    List<User> userList = userService.list();
-                    redisUtil.set(GlobalConstant.USER_CACHE_KEY, userList);
-
-                    List<UserRoleRelation> userRoleRelationList = roleRelationService.list(Wrappers.lambdaQuery(UserRoleRelation.class));
-                    redisUtil.set(GlobalConstant.USER_ROLE_RELATION_CACHE_KEY, userRoleRelationList);
-                });
+            } catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
+                log.error("重试等待被中断", e);
+                result.setFailCount(batch.size());
+                break;
+            } catch (Exception e) {
+                log.error("批次处理异常", e);
+                result.setFailCount(batch.size());
+                break;
             }
         }
+
+        return result;
     }
 
-    LocalDate getBirthDate(String idCardNumber){
-        // 获取出生日期前6位,即yyyyMM
-        String birthdayString = idCardNumber.substring(6, 14);
+    /**
+     * 在独立事务中处理批次
+     */
+    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW, timeout = 120)
+    public ProcessResult processBatchInTransaction(List<BaseNewStudent> batch, LocalDateTime now) {
+        ProcessResult result = new ProcessResult();
+
+        for (BaseNewStudent student : batch) {
+            try {
+                processSingleStudentWithRetry(student, now);
+                result.incrementSuccess();
+                log.debug("成功处理学生: {}", student.getName());
+            } catch (Exception e) {
+                log.error("处理学生 {} 失败: {}", student.getName(), e.getMessage(), e);
+                result.incrementFail();
+                // 记录失败详情但继续处理其他学生
+            }
+        }
+
+        return result;
+    }
+
+    /**
+     * 处理单个学生(带重试)
+     */
+    @Retryable(
+            value = {CannotAcquireLockException.class, RecoverableDataAccessException.class},
+            maxAttempts = 3,
+            backoff = @Backoff(delay = 1000, multiplier = 2)
+    )
+    public void processSingleStudentWithRetry(BaseNewStudent student, LocalDateTime now) {
+        log.debug("尝试处理学生: {}", student.getName());
+
+        BandingTaskClass taskClass = getTaskClass(student.getId());
+        BaseClass baseClass = processClassInfo(taskClass);
+
+        User existingUser = findExistingUser(student.getCredentialNumber());
+        if (existingUser != null) {
+            processExistingUser(student, now, baseClass, existingUser);
+        } else {
+            processNewUser(student, now, baseClass);
+        }
+    }
+
+    /**
+     * 重试失败后的恢复方法
+     */
+    @Recover
+    public void recoverProcess(CannotAcquireLockException e, BaseNewStudent student, LocalDateTime now) {
+        log.error("处理学生 {} 重试3次后仍然失败(锁等待): {}", student.getName(), e.getMessage());
+        // 这里可以记录到重试表、发送通知等
+        saveToRetryQueue(student, now, "LOCK_TIMEOUT");
+    }
+
+    @Recover
+    public void recoverProcess(RecoverableDataAccessException e, BaseNewStudent student, LocalDateTime now) {
+        log.error("处理学生 {} 重试3次后仍然失败(通信问题): {}", student.getName(), e.getMessage());
+        saveToRetryQueue(student, now, "COMMUNICATION_ERROR");
+    }
+
+    /**
+     * 获取班级信息
+     */
+    private BandingTaskClass getTaskClass(Long newStudentId) {
+        return taskClassService.getOne(
+                new MPJLambdaWrapper<BandingTaskClass>()
+                        .select(BandingTaskClass::getId)
+                        .select(BandingTaskClass.class, x -> VoToColumnUtil.fieldsToColumns(BandingTaskClass.class).contains(x.getProperty()))
+                        .innerJoin(BandingTaskClassStudent.class, BandingTaskClassStudent::getBandingTaskClassId, BandingTaskClass::getId)
+                        .eq(BandingTaskClassStudent::getNewStudentId, newStudentId)
+                        .eq(BandingTaskClassStudent::getDeleteMark, DeleteMark.NODELETE.getCode())
+                        .eq(BandingTaskClassStudent::getEnabledMark, EnabledMark.ENABLED.getCode())
+                        .eq(BandingTaskClass::getDeleteMark, DeleteMark.NODELETE.getCode())
+                        .eq(BandingTaskClass::getEnabledMark, EnabledMark.ENABLED.getCode())
+        );
+    }
+
+    /**
+     * 处理班级信息
+     */
+    private BaseClass processClassInfo(BandingTaskClass taskClass) {
+        BaseClass baseClass = classMapper.selectById(taskClass.getBaseClassId());
+        if (ObjectUtils.isEmpty(baseClass)) {
+            baseClass = createNewClass(taskClass);
+        }
+        return baseClass;
+    }
+
+    /**
+     * 创建新班级
+     */
+    private BaseClass createNewClass(BandingTaskClass taskClass) {
+        BandingTask task = taskService.getById(taskClass.getBandingTaskId());
+        List<BaseClass> classList = classMapper.selectList(
+                new QueryWrapper<BaseClass>().lambda()
+                        .eq(BaseClass::getDeleteMark, DeleteMark.NODELETE.getCode())
+                        .eq(BaseClass::getGradeId, task.getGradeId())
+                        .eq(BaseClass::getEnrollType, task.getEnrollType())
+        );
+
+        BaseGrade baseGrade = gradeMapper.selectById(task.getGradeId());
+        String classCode = generateClassCode(classList, baseGrade);
+
+        BaseClass baseClass = new BaseClass();
+        BeanUtil.copyProperties(taskClass, baseClass);
+        baseClass.setCreateDate(new Date());
+        baseClass.setCreateUserId(StpUtil.getLoginIdAsLong());
+        baseClass.setCode(classCode);
+        baseClass.setGradeId(task.getGradeId());
+
+        BaseMajorSet majorSet = majorSetMapper.selectById(baseClass.getMajorSetId());
+        baseClass.setOrgId(majorSet.getDepartmentId());
+        baseClass.setId(null);
+
+        classMapper.insert(baseClass);
+        taskClass.setBaseClassId(baseClass.getId());
+        taskClassService.updateById(taskClass);
+
+        return baseClass;
+    }
+
+    /**
+     * 生成班级代码
+     */
+    private String generateClassCode(List<BaseClass> classList, BaseGrade baseGrade) {
+        List<BaseClass> classCodes = classList.stream()
+                .filter(x -> x.getCode() != null && NumberUtil.isNumber(x.getCode()))
+                .sorted(Comparator.comparing(BaseClass::getCode))
+                .collect(Collectors.toList());
+
+        if (classCodes.isEmpty()) {
+            return baseGrade.getTitle().replace("年", "") + "001";
+        }
+
+        String lastCode = classCodes.get(classCodes.size() - 1).getCode();
+        int nextNumber = Integer.parseInt(lastCode.substring(lastCode.length() - 3)) + 1;
+        return baseGrade.getTitle().replace("年", "") + String.format("%03d", nextNumber);
+    }
+
+    /**
+     * 查找已存在用户
+     */
+    private User findExistingUser(String credentialNumber) {
+        return userService.getOne(
+                new MPJLambdaWrapper<User>()
+                        .select(User::getId)
+                        .select(User.class, x -> VoToColumnUtil.fieldsToColumns(User.class).contains(x.getProperty()))
+                        .eq(User::getCredentialNumber, credentialNumber)
+                        .eq(User::getEnabledMark, EnabledMark.ENABLED.getCode())
+        );
+    }
+
+    /**
+     * 处理已存在用户
+     */
+    private void processExistingUser(BaseNewStudent student, LocalDateTime now, BaseClass baseClass, User user) {
+        // 检查并创建学籍信息
+        BaseStudentSchoolRoll existingRoll = rollService.getOne(
+                new MPJLambdaWrapper<BaseStudentSchoolRoll>()
+                        .disableLogicDel()
+                        .select(BaseStudentSchoolRoll::getId)
+                        .select(BaseStudentSchoolRoll.class, x -> VoToColumnUtil.fieldsToColumns(BaseStudentSchoolRoll.class).contains(x.getProperty()))
+                        .eq(BaseStudentSchoolRoll::getUserId, user.getId())
+        );
+
+        if (ObjectUtils.isEmpty(existingRoll)) {
+            BaseStudentSchoolRoll schoolRoll = createSchoolRoll(student, now, baseClass, user.getId());
+            rollService.save(schoolRoll);
+        }
+
+        // 检查并创建学生基本信息
+        BaseStudent existingStudent = studentService.getOne(
+                new QueryWrapper<BaseStudent>().lambda()
+                        .eq(BaseStudent::getUserId, user.getId())
+        );
+
+        if (ObjectUtils.isEmpty(existingStudent)) {
+            BaseStudent baseStudent = createBaseStudent(student, now, user.getId());
+            studentService.save(baseStudent);
+        }
+
+        // 更新班级信息和激活学生
+        rollService.updateStudentClass(baseClass.getId(), user.getId());
+        rollService.activateStudent(user.getId());
+    }
+
+    /**
+     * 处理新用户
+     */
+    private void processNewUser(BaseNewStudent student, LocalDateTime now, BaseClass baseClass) {
+        LocalDate birthDate = getBirthDate(student.getCredentialNumber());
+
+        // 创建用户
+        User newUser = createUser(student, now, birthDate);
+        userService.save(newUser);
+
+        // 创建角色关系
+        UserRoleRelation roleRelation = new UserRoleRelation();
+        roleRelation.setRoleId(RoleEnum.STUDENT.getCode());
+        roleRelation.setUserId(newUser.getId());
+        roleRelationService.save(roleRelation);
+
+        // 创建学生基本信息
+        BaseStudent baseStudent = createBaseStudent(student, now, newUser.getId());
+        studentService.save(baseStudent);
+
+        // 创建学籍信息
+        BaseStudentSchoolRoll schoolRoll = createSchoolRoll(student, now, baseClass, newUser.getId());
+        rollService.save(schoolRoll);
+
+        // 创建家庭信息
+        BaseStudentFamily studentFamily = new BaseStudentFamily();
+        studentFamily.setCreateDate(now);
+        studentFamily.setUserId(newUser.getId());
+        studentFamily.setTelephone(student.getFamilyMobile());
+        studentFamily.setAddress(student.getFamilyAddress());
+        familyService.save(studentFamily);
+
+        // 异步更新缓存
+        updateCacheAsync();
+    }
+
+    /**
+     * 创建用户对象
+     */
+    private User createUser(BaseNewStudent student, LocalDateTime now, LocalDate birthDate) {
+        if (StringUtils.isEmpty(student.getCredentialNumber())) {
+            throw new MyException(student.getName() + "证件号为空,请填写后提交");
+        }
+
+        String credentialNumber = student.getCredentialNumber();
+        String lastSixDigits = credentialNumber.length() <= 6
+                ? credentialNumber
+                : credentialNumber.substring(credentialNumber.length() - 6);
+
+        User user = new User();
+        user.setCreateDate(now);
+        user.setPassword(BCrypt.hashpw(lastSixDigits, BCrypt.gensalt()));
+        user.setName(student.getName());
+        user.setUserName(student.getCredentialNumber());
+        user.setCredentialNumber(student.getCredentialNumber());
+        user.setCredentialType("ZZLS10007");
+        user.setMobile(student.getMobile());
+        user.setEnabledMark(EnabledMark.ENABLED.getCode());
+        user.setGender(student.getGender());
+        user.setIsChangePassword(1);
+        user.setBirthDate(birthDate.atStartOfDay());
+
+        return user;
+    }
+
+    /**
+     * 创建学生基本信息
+     */
+    private BaseStudent createBaseStudent(BaseNewStudent student, LocalDateTime now, Long userId) {
+        BaseStudent baseStudent = new BaseStudent();
+        baseStudent.setUserId(userId);
+        baseStudent.setCreateDate(now);
+        baseStudent.setStudentId(student.getCredentialNumber());
+
+        if (student.getHeight() != null) {
+            baseStudent.setHeight(student.getHeight().doubleValue());
+        }
+        if (student.getWeight() != null) {
+            baseStudent.setWeight(student.getWeight().doubleValue());
+        }
+        baseStudent.setIsNormal(1);
+
+        return baseStudent;
+    }
+
+    /**
+     * 创建学籍信息
+     */
+    private BaseStudentSchoolRoll createSchoolRoll(BaseNewStudent student, LocalDateTime now, BaseClass baseClass, Long userId) {
+        BaseStudentSchoolRoll schoolRoll = new BaseStudentSchoolRoll();
+        schoolRoll.setUserId(userId);
 
-        // 将字符串解析为LocalDate对象
+        if (student.getScore() != null) {
+            schoolRoll.setGraduatedScore(student.getScore().doubleValue());
+        }
+
+        schoolRoll.setInternshipState("IT_0001");
+        schoolRoll.setGraduatedUniversity(student.getGraduateSchool());
+        schoolRoll.setClassId(baseClass.getId());
+        schoolRoll.setMajorSetId(baseClass.getMajorSetId());
+        schoolRoll.setStduyStatus(student.getStduyStatus());
+        schoolRoll.setDeleteMark(DeleteMark.NODELETE.getCode());
+        schoolRoll.setEnrollType(baseClass.getEnrollType());
+        schoolRoll.setStudentType(student.getSource());
+        schoolRoll.setGradeId(baseClass.getGradeId());
+        schoolRoll.setArchivesStatus(ArchivesStatusEnum.FB2901.getCode());
+        schoolRoll.setCreateDate(now);
+
+        return schoolRoll;
+    }
+
+    /**
+     * 异步更新缓存
+     */
+    private void updateCacheAsync() {
+        CompletableFuture.runAsync(() -> {
+            try {
+                List<User> userList = userService.list();
+                redisUtil.set(GlobalConstant.USER_CACHE_KEY, userList);
+
+                List<UserRoleRelation> userRoleRelationList = roleRelationService.list(
+                        Wrappers.lambdaQuery(UserRoleRelation.class));
+                redisUtil.set(GlobalConstant.USER_ROLE_RELATION_CACHE_KEY, userRoleRelationList);
+
+                log.debug("缓存更新完成");
+            } catch (Exception e) {
+                log.warn("异步更新缓存失败", e);
+            }
+        });
+    }
+
+    /**
+     * 保存到重试队列
+     */
+    private void saveToRetryQueue(BaseNewStudent student, LocalDateTime now, String reason) {
+        log.warn("学生 {} 加入重试队列,原因: {}", student.getName(), reason);
+        // 这里可以实现将失败记录保存到数据库或消息队列
+    }
+
+    LocalDate getBirthDate(String idCardNumber) {
+        if (idCardNumber == null || idCardNumber.length() < 14) {
+            throw new MyException("身份证号长度不足,无法提取出生日期");
+        }
+
+        String birthdayString = idCardNumber.substring(6, 14);
         DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
+
         try {
             return LocalDate.parse(birthdayString, formatter);
-        }catch (Exception e){
-            throw new MyException("身份证号填写错误,无法提取出生日期");
+        } catch (Exception e) {
+            throw new MyException("身份证号填写错误,无法提取出生日期: " + idCardNumber);
         }
     }
+
+    /**
+     * 处理结果类
+     */
+    @Data
+    static class ProcessResult {
+        private int successCount = 0;
+        private int failCount = 0;
+
+        public void incrementSuccess() { successCount++; }
+        public void incrementFail() { failCount++; }
+    }
 }