学号
This commit is contained in:
@@ -45,6 +45,11 @@ public interface SchStudentRepository extends JpaRepository<SchStudent, Integer>
|
||||
|
||||
boolean existsBySchIdAndClassIdAndNameAndIdNot(Integer schId,Integer classId, String name, Integer id);
|
||||
|
||||
/**
|
||||
* 判断同一班级内是否已存在相同学号的学生(排除自身,用于学号导入时的重复校验)
|
||||
*/
|
||||
boolean existsBySchIdAndClassIdAndStuClassNoAndIdNot(Integer schId, Integer classId, String stuClassNo, Integer id);
|
||||
|
||||
@Modifying(clearAutomatically = true)
|
||||
@Query("UPDATE SchStudent s SET s.classId = :newClassId, s.groupId = :newClassId, s.updateDate = :updateDate, s.updateUserId = :updateUserId WHERE s.id IN (:ids) AND s.schId = :schId")
|
||||
int batchUpdateClassId(@Param("ids") List<Integer> ids,
|
||||
|
||||
+84
-10
@@ -346,6 +346,47 @@ public class SchStudentImportService {
|
||||
return errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验学号导入数据中的重复项(账号、学号)
|
||||
* @param importList 导入数据列表
|
||||
* @return 错误信息列表
|
||||
*/
|
||||
private List<String> validateClassNoDuplicates(List<StudentClassNoExcelColumn> importList) {
|
||||
List<String> errors = new ArrayList<>();
|
||||
|
||||
// 1. 校验 "账号" 在本次导入中是否重复(避免同一学生被重复处理)
|
||||
Map<String, Long> accountCountMap = importList.stream()
|
||||
.filter(dto -> StringUtils.isNotBlank(dto.getAccount()))
|
||||
.collect(Collectors.groupingBy(
|
||||
dto -> dto.getAccount(),
|
||||
Collectors.counting()
|
||||
));
|
||||
|
||||
accountCountMap.entrySet().stream()
|
||||
.filter(entry -> entry.getValue() > 1)
|
||||
.forEach(entry -> errors.add(
|
||||
String.format("账号 '%s' 在表格中出现了 %d 次,请检查并去重",
|
||||
entry.getKey(), entry.getValue())
|
||||
));
|
||||
|
||||
// 2. 校验 "学号" 在本次导入中是否重复
|
||||
Map<String, Long> classNoCountMap = importList.stream()
|
||||
.filter(dto -> StringUtils.isNotBlank(dto.getClazzNo()))
|
||||
.collect(Collectors.groupingBy(
|
||||
dto -> dto.getClazzNo(),
|
||||
Collectors.counting()
|
||||
));
|
||||
|
||||
classNoCountMap.entrySet().stream()
|
||||
.filter(entry -> entry.getValue() > 1)
|
||||
.forEach(entry -> errors.add(
|
||||
String.format("学号 '%s' 在表格中出现了 %d 次,请检查并去重",
|
||||
entry.getKey(), entry.getValue())
|
||||
));
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
|
||||
public void studentClassNoTemplate(HttpServletResponse response,
|
||||
Integer schId,Integer systemId,Integer gradeId,Integer classId){
|
||||
@@ -419,9 +460,17 @@ public class SchStudentImportService {
|
||||
throw new DException("上传的 Excel 中没有有效数据行,请检查后重新上传!");
|
||||
}
|
||||
|
||||
// Excel数据重复验证(账号、学号)
|
||||
{
|
||||
List<String> validateDuplicatesMsgs = validateClassNoDuplicates(list);
|
||||
if (validateDuplicatesMsgs.size() > 0) {
|
||||
errorMsgArr.add(new ErrorExcelColumn(0, "数据重复", String.join("\r\n", validateDuplicatesMsgs)));
|
||||
}
|
||||
}
|
||||
|
||||
// 4. 业务校验与转换
|
||||
List<SchStudent> saveStudentList = new ArrayList<>();
|
||||
int currentRow = params.getTitleRows() + params.getHeadRows() ; // 从第2行开始
|
||||
int currentRow = params.getTitleRows() + params.getHeadRows() + 1; // 第一行数据从第2行开始
|
||||
|
||||
for (StudentClassNoExcelColumn item : list) {
|
||||
// Excel数据验证
|
||||
@@ -429,6 +478,7 @@ public class SchStudentImportService {
|
||||
List<String> validateMsgs = ValidationUtil.validateMsgs(item);
|
||||
if (validateMsgs.size() > 0) {
|
||||
errorMsgArr.add(new ErrorExcelColumn(currentRow, "导入规则", String.join("\r\n", validateMsgs)));
|
||||
currentRow++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -438,17 +488,22 @@ public class SchStudentImportService {
|
||||
{
|
||||
Optional<SchStudent> accountOpt = schStudentRepository.findByAccount(item.getAccount());
|
||||
if (accountOpt.isPresent()) {
|
||||
if (!accountOpt.get().getSchId().equals(schId) && accountOpt.get().getTransferStatus().equals(TransferStatus.IN)) {
|
||||
SchStudent existing = accountOpt.get();
|
||||
// 跨校防护(空安全):账号属于其他学校时一律拒绝,避免修改其他学校的学生数据
|
||||
if (!schId.equals(existing.getSchId())) {
|
||||
String schoolName = existing.getSchId() == null ? "未知学校"
|
||||
: comSchTreeService.getSchoolName(existing.getSchId());
|
||||
errorMsgArr.add(new ErrorExcelColumn(currentRow, item.getStuName(),
|
||||
"禁止将" + comSchTreeService.getSchoolName(accountOpt.get().getSchId()) + "正常学生导入!"));
|
||||
"禁止将" + schoolName + "学生导入!"));
|
||||
currentRow++;
|
||||
continue;
|
||||
} else {
|
||||
BeanUtils.copyProperties(accountOpt.get(), stu);
|
||||
stu.setUpdateDate(now);
|
||||
stu.setUpdateUserId(userId);
|
||||
}
|
||||
BeanUtils.copyProperties(existing, stu);
|
||||
stu.setUpdateDate(now);
|
||||
stu.setUpdateUserId(userId);
|
||||
} else {
|
||||
errorMsgArr.add(new ErrorExcelColumn(currentRow, item.getAccount(),item.getStuName()+"学生账号未找到!"));
|
||||
currentRow++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -465,10 +520,12 @@ public class SchStudentImportService {
|
||||
gradeId2 = gradeIdOpt.get();
|
||||
if(gradeId!=null&&!gradeId2.equals(gradeId)){
|
||||
errorMsgArr.add(new ErrorExcelColumn(currentRow, item.getGradeName(), StudentExcelColumn.GRADE_NAME + "参数年级与模板年级不一致!"));
|
||||
currentRow++;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
errorMsgArr.add(new ErrorExcelColumn(currentRow, item.getGradeName(), StudentExcelColumn.GRADE_NAME + "不存在!"));
|
||||
currentRow++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -482,20 +539,35 @@ public class SchStudentImportService {
|
||||
if(classId!=null){
|
||||
if(!schClassOpt.get().getClassId().equals(classId)){
|
||||
errorMsgArr.add(new ErrorExcelColumn(currentRow, item.getClazzName(), StudentExcelColumn.CLAZZ_NAME + "参数班级与模板班级不一致!"));
|
||||
currentRow++;
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
// 学生当前班级必须与模板班级一致,避免改错其他班级学生的学号
|
||||
if (!Objects.equals(stu.getClassId(), schClassOpt.get().getClassId())) {
|
||||
errorMsgArr.add(new ErrorExcelColumn(currentRow, item.getClazzName(), "学生当前班级与模板班级不一致!"));
|
||||
currentRow++;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
errorMsgArr.add(new ErrorExcelColumn(currentRow, item.getClazzName(), StudentExcelColumn.CLAZZ_NAME + "不存在!"));
|
||||
currentRow++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// 学号
|
||||
// 学号(为空时保留原学号,避免误清空)
|
||||
{
|
||||
stu.setStuClassNo(item.getClazzNo());
|
||||
if (StringUtils.isNotBlank(item.getClazzNo())) {
|
||||
// 同班级内学号重复校验(排除学生自身)
|
||||
boolean classNoExists = schStudentRepository.existsBySchIdAndClassIdAndStuClassNoAndIdNot(
|
||||
schId, stu.getClassId(), item.getClazzNo(), stu.getId());
|
||||
if (classNoExists) {
|
||||
errorMsgArr.add(new ErrorExcelColumn(currentRow, item.getClazzNo(), "该班级已存在相同学号的学生!"));
|
||||
currentRow++;
|
||||
continue;
|
||||
}
|
||||
stu.setStuClassNo(item.getClazzNo());
|
||||
try {
|
||||
String digits = item.getClazzNo().replaceAll("\\D+", "");
|
||||
if (StringUtils.isNotBlank(digits)) {
|
||||
@@ -507,6 +579,8 @@ public class SchStudentImportService {
|
||||
}
|
||||
}
|
||||
saveStudentList.add(stu);
|
||||
classIds.add(stu.getClassId());
|
||||
currentRow++;
|
||||
}
|
||||
|
||||
// 5. 若有错误,抛出异常(携带明细)
|
||||
|
||||
+7
-2
@@ -450,7 +450,7 @@ public class SchStudentLogService {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
List<OperationLogRecord> logs = new ArrayList<>();
|
||||
for (SchStudent stu : saveStudentList) {
|
||||
String content = "";
|
||||
String content;
|
||||
Optional<SchClass> schClassOpt = schClassList.stream()
|
||||
.filter(s -> s.getClassId().equals(stu.getClassId()))
|
||||
.findFirst();
|
||||
@@ -461,8 +461,12 @@ public class SchStudentLogService {
|
||||
.map(SelectIntVO::getName)
|
||||
.findFirst()
|
||||
.orElse("未知年级");
|
||||
content = "导入学生[" + stu.getName() + "]学号["+stu.getStuClassNo()+"]】成功,用户信息:"
|
||||
content = "导入学生[" + stu.getName() + "]学号[" + stu.getStuClassNo() + "]成功,用户信息:"
|
||||
+ JSON.toJSONString(stu, NO_PWD_FILTER)
|
||||
+ ",所在年级班级:" + gradeName + schClassOpt.get().getName();
|
||||
} else {
|
||||
content = "导入学生[" + stu.getName() + "]学号[" + stu.getStuClassNo() + "]成功,用户信息:"
|
||||
+ JSON.toJSONString(stu, NO_PWD_FILTER) + ",班级:未知";
|
||||
}
|
||||
OperationLogRecord log = logService.buildLogRecord(user, MODULE_STUDENT, content, now);
|
||||
logs.add(log);
|
||||
@@ -470,6 +474,7 @@ public class SchStudentLogService {
|
||||
if (!logs.isEmpty()) {
|
||||
logService.saveAllLogAsync(logs);
|
||||
}
|
||||
log.debug("操作人:{},学生学号导入日志成功: {}", user.getUserName(), JSON.toJSONString(saveStudentList, NO_PWD_FILTER));
|
||||
} catch (Exception e) {
|
||||
log.error("操作人:" + user.getUserName() + ",学生学号导入日志失败: {}", e.getMessage(), e);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user