|
@@ -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.conditions.update.UpdateWrapper;
|
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
import com.github.yulichang.wrapper.MPJLambdaWrapper;
|
|
import com.github.yulichang.wrapper.MPJLambdaWrapper;
|
|
|
|
|
+import com.google.common.collect.Lists;
|
|
|
import com.xjrsoft.common.constant.GlobalConstant;
|
|
import com.xjrsoft.common.constant.GlobalConstant;
|
|
|
import com.xjrsoft.common.enums.ArchivesStatusEnum;
|
|
import com.xjrsoft.common.enums.ArchivesStatusEnum;
|
|
|
import com.xjrsoft.common.enums.DeleteMark;
|
|
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.BaseNewStudentMapper;
|
|
|
import com.xjrsoft.module.student.mapper.StudentReportPlanMapper;
|
|
import com.xjrsoft.module.student.mapper.StudentReportPlanMapper;
|
|
|
import com.xjrsoft.module.student.service.*;
|
|
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.ObjectUtils;
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
import org.junit.jupiter.api.AfterEach;
|
|
import org.junit.jupiter.api.AfterEach;
|
|
@@ -48,6 +51,12 @@ import org.junit.jupiter.api.BeforeEach;
|
|
|
import org.junit.jupiter.api.Test;
|
|
import org.junit.jupiter.api.Test;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.boot.test.context.SpringBootTest;
|
|
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 org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
|
|
|
import java.time.LocalDate;
|
|
import java.time.LocalDate;
|
|
@@ -58,6 +67,7 @@ import java.util.Comparator;
|
|
|
import java.util.Date;
|
|
import java.util.Date;
|
|
|
import java.util.List;
|
|
import java.util.List;
|
|
|
import java.util.concurrent.CompletableFuture;
|
|
import java.util.concurrent.CompletableFuture;
|
|
|
|
|
+import java.util.concurrent.atomic.AtomicInteger;
|
|
|
import java.util.stream.Collectors;
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
import static org.junit.jupiter.api.Assertions.*;
|
|
import static org.junit.jupiter.api.Assertions.*;
|
|
@@ -67,6 +77,7 @@ import static org.junit.jupiter.api.Assertions.*;
|
|
|
* @date 2025/2/11
|
|
* @date 2025/2/11
|
|
|
*/
|
|
*/
|
|
|
@SpringBootTest
|
|
@SpringBootTest
|
|
|
|
|
+@Slf4j
|
|
|
class StudentReportRecordServiceImplTest {
|
|
class StudentReportRecordServiceImplTest {
|
|
|
|
|
|
|
|
@Autowired
|
|
@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
|
|
@Test
|
|
|
- @Transactional(rollbackFor = Exception.class)
|
|
|
|
|
void tryReadingSign() {
|
|
void tryReadingSign() {
|
|
|
|
|
+ log.info("开始处理学生签到数据...");
|
|
|
LocalDateTime now = LocalDateTime.now();
|
|
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()))
|
|
.select(BaseNewStudent.class, x -> VoToColumnUtil.fieldsToColumns(BaseNewStudent.class).contains(x.getProperty()))
|
|
|
.innerJoin(BandingTaskClassStudent.class, BandingTaskClassStudent::getNewStudentId, BaseNewStudent::getId)
|
|
.innerJoin(BandingTaskClassStudent.class, BandingTaskClassStudent::getNewStudentId, BaseNewStudent::getId)
|
|
|
.innerJoin(BandingTaskClass.class, BandingTaskClass::getId, BandingTaskClassStudent::getBandingTaskClassId)
|
|
.innerJoin(BandingTaskClass.class, BandingTaskClass::getId, BandingTaskClassStudent::getBandingTaskClassId)
|
|
|
.innerJoin(BandingTask.class, BandingTask::getId, BandingTaskClass::getBandingTaskId)
|
|
.innerJoin(BandingTask.class, BandingTask::getId, BandingTaskClass::getBandingTaskId)
|
|
|
.eq(BandingTask::getGradeId, 1868532405673439232L)
|
|
.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");
|
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
|
|
|
|
|
+
|
|
|
try {
|
|
try {
|
|
|
return LocalDate.parse(birthdayString, formatter);
|
|
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++; }
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|