|
|
@@ -25,6 +25,7 @@ import org.dromara.xg.mapper.XgDormHygieneStudentScoreMapper;
|
|
|
import org.dromara.xg.service.IXgDormHygieneCheckService;
|
|
|
import org.dromara.xg.service.IXgStudentMsgService;
|
|
|
import org.dromara.xg.service.IXgHygieneCheckViolationService;
|
|
|
+import org.dromara.xg.mapper.XgHygieneCheckViolationMapper;
|
|
|
import org.dromara.system.service.ISysDictDataService;
|
|
|
import org.springframework.context.ApplicationContext;
|
|
|
|
|
|
@@ -32,6 +33,13 @@ import java.util.List;
|
|
|
import java.util.Map;
|
|
|
import java.util.Collection;
|
|
|
import java.util.HashMap;
|
|
|
+import java.util.Set;
|
|
|
+import java.util.HashSet;
|
|
|
+import java.util.Objects;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+import org.dromara.xg.domain.vo.XgHygieneCheckViolationVo;
|
|
|
+import org.dromara.xg.domain.XgHygieneCheckViolation;
|
|
|
+import java.util.Collections;
|
|
|
|
|
|
/**
|
|
|
* 宿舍卫生检查Service业务层处理
|
|
|
@@ -49,6 +57,7 @@ public class XgDormHygieneCheckServiceImpl implements IXgDormHygieneCheckService
|
|
|
private final IXgStudentMsgService xgStudentMsgService;
|
|
|
private final ISysDictDataService sysDictDataService;
|
|
|
private final IXgHygieneCheckViolationService violationService;
|
|
|
+ private final XgHygieneCheckViolationMapper violationMapper;
|
|
|
private final ApplicationContext applicationContext;
|
|
|
|
|
|
/**
|
|
|
@@ -708,7 +717,8 @@ public class XgDormHygieneCheckServiceImpl implements IXgDormHygieneCheckService
|
|
|
}
|
|
|
} catch (Exception e) {
|
|
|
log.error("处理违纪数据失败,学生ID: {}, 错误: {}", violationBo.getStudentId(), e.getMessage(), e);
|
|
|
- // 不影响主流程,继续处理下一个
|
|
|
+ throw new RuntimeException(
|
|
|
+ "处理违纪数据失败,学生ID: " + violationBo.getStudentId() + ", 错误: " + e.getMessage(), e);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -947,4 +957,344 @@ public class XgDormHygieneCheckServiceImpl implements IXgDormHygieneCheckService
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public Boolean updateCompleteData(XgDormHygieneCheckCompleteBo bo) {
|
|
|
+ try {
|
|
|
+ // 1. 更新主表数据
|
|
|
+ XgDormHygieneCheck update = MapstructUtils.convert(bo, XgDormHygieneCheck.class);
|
|
|
+ validEntityBeforeSave(update);
|
|
|
+ boolean flag = baseMapper.updateById(update) > 0;
|
|
|
+ log.info("更新宿舍卫生检查主表数据: {}", update);
|
|
|
+
|
|
|
+ if (!flag) {
|
|
|
+ log.error("更新宿舍卫生检查主表数据失败");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ Long hygieneCheckId = update.getId();
|
|
|
+
|
|
|
+ // 2. 更新学生评分数据 - 先删除旧数据,再插入新数据
|
|
|
+ LambdaQueryWrapper<XgDormHygieneStudentScore> scoreWrapper = Wrappers.lambdaQuery();
|
|
|
+ scoreWrapper.eq(XgDormHygieneStudentScore::getHygieneCheckId, hygieneCheckId);
|
|
|
+ studentScoreMapper.delete(scoreWrapper);
|
|
|
+ log.info("删除旧的学生评分数据,检查ID: {}", hygieneCheckId);
|
|
|
+
|
|
|
+ if (bo.getStudentScores() != null && !bo.getStudentScores().isEmpty()) {
|
|
|
+ for (XgDormHygieneStudentScoreBo studentScoreBo : bo.getStudentScores()) {
|
|
|
+ XgDormHygieneStudentScore studentScore = MapstructUtils.convert(studentScoreBo,
|
|
|
+ XgDormHygieneStudentScore.class);
|
|
|
+ studentScore.setHygieneCheckId(hygieneCheckId);
|
|
|
+ studentScore.setId(null); // 确保是新插入
|
|
|
+
|
|
|
+ // 根据学生ID查询学生完整信息,补充学院、专业、班级信息
|
|
|
+ if (studentScoreBo.getStudentId() != null) {
|
|
|
+ try {
|
|
|
+ var studentInfo = xgStudentMsgService.queryById(studentScoreBo.getStudentId());
|
|
|
+ if (studentInfo != null) {
|
|
|
+ // 补充学院信息
|
|
|
+ if (studentScore.getCollegeId() == null
|
|
|
+ && StringUtils.isNotBlank(studentInfo.getCollegeId())) {
|
|
|
+ try {
|
|
|
+ studentScore.setCollegeId(Long.valueOf(studentInfo.getCollegeId()));
|
|
|
+ } catch (NumberFormatException e) {
|
|
|
+ log.warn("学院ID转换失败,学生ID: {}, 学院ID: {}", studentScoreBo.getStudentId(),
|
|
|
+ studentInfo.getCollegeId());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (StringUtils.isBlank(studentScore.getCollegeName())) {
|
|
|
+ studentScore.setCollegeName(studentInfo.getCollegeName());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 补充专业信息
|
|
|
+ if (studentScore.getMajorId() == null
|
|
|
+ && StringUtils.isNotBlank(studentInfo.getMajorId())) {
|
|
|
+ try {
|
|
|
+ studentScore.setMajorId(Long.valueOf(studentInfo.getMajorId()));
|
|
|
+ } catch (NumberFormatException e) {
|
|
|
+ log.warn("专业ID转换失败,学生ID: {}, 专业ID: {}", studentScoreBo.getStudentId(),
|
|
|
+ studentInfo.getMajorId());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (StringUtils.isBlank(studentScore.getMajorName())) {
|
|
|
+ studentScore.setMajorName(studentInfo.getMajorName());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 补充班级信息
|
|
|
+ if (studentScore.getClassId() == null
|
|
|
+ && StringUtils.isNotBlank(studentInfo.getClassId())) {
|
|
|
+ try {
|
|
|
+ studentScore.setClassId(Long.valueOf(studentInfo.getClassId()));
|
|
|
+ } catch (NumberFormatException e) {
|
|
|
+ log.warn("班级ID转换失败,学生ID: {}, 班级ID: {}", studentScoreBo.getStudentId(),
|
|
|
+ studentInfo.getClassId());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (StringUtils.isBlank(studentScore.getClassName())) {
|
|
|
+ studentScore.setClassName(studentInfo.getClassName());
|
|
|
+ }
|
|
|
+
|
|
|
+ log.info("补充学生信息 - 学生ID: {}, 学院: {}, 专业: {}, 班级: {}",
|
|
|
+ studentScoreBo.getStudentId(),
|
|
|
+ studentInfo.getCollegeName(),
|
|
|
+ studentInfo.getMajorName(),
|
|
|
+ studentInfo.getClassName());
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("查询学生信息失败,学生ID: {}, 错误: {}", studentScoreBo.getStudentId(), e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ log.info("保存学生评分数据: {}", studentScore);
|
|
|
+ studentScoreMapper.insert(studentScore);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 处理违纪记录数据 - 完整的增删改逻辑
|
|
|
+ handleViolationRecords(hygieneCheckId, bo.getViolationData());
|
|
|
+
|
|
|
+ log.info("完整更新宿舍卫生检查数据成功,检查ID: {}", hygieneCheckId);
|
|
|
+ return true;
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("更新宿舍卫生检查数据失败", e);
|
|
|
+ throw new RuntimeException("更新宿舍卫生检查数据失败: " + e.getMessage(), e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理违纪记录数据 - 完整的增删改逻辑
|
|
|
+ *
|
|
|
+ * @param hygieneCheckId 卫生检查ID
|
|
|
+ * @param newViolationData 新的违纪记录数据列表
|
|
|
+ */
|
|
|
+ private void handleViolationRecords(Long hygieneCheckId, List<XgViolationDataBo> newViolationData) {
|
|
|
+ try {
|
|
|
+ // 1. 查询数据库中现有的违纪记录
|
|
|
+ List<XgHygieneCheckViolationVo> existingViolations = getViolationsByHygieneCheckId(hygieneCheckId);
|
|
|
+ log.info("数据库中现有违纪记录数量: {}", existingViolations.size());
|
|
|
+
|
|
|
+ // 2. 收集现有记录的违纪记录ID(disciplineRecordId)
|
|
|
+ Set<Long> existingDisciplineIds = existingViolations.stream()
|
|
|
+ .map(XgHygieneCheckViolationVo::getDisciplineRecordId)
|
|
|
+ .filter(Objects::nonNull)
|
|
|
+ .collect(Collectors.toSet());
|
|
|
+ log.info("现有违纪记录ID集合: {}", existingDisciplineIds);
|
|
|
+
|
|
|
+ // 3. 收集新数据中的违纪记录ID(优先使用disciplineRecordId字段,兼容旧版本的id字段)
|
|
|
+ Set<Long> newDisciplineIds = new HashSet<>();
|
|
|
+ if (newViolationData != null) {
|
|
|
+ newDisciplineIds = newViolationData.stream()
|
|
|
+ .map(violationBo -> {
|
|
|
+ // 优先使用disciplineRecordId字段,如果为空则使用id字段(向后兼容)
|
|
|
+ return violationBo.getDisciplineRecordId() != null
|
|
|
+ ? violationBo.getDisciplineRecordId()
|
|
|
+ : violationBo.getId();
|
|
|
+ })
|
|
|
+ .filter(Objects::nonNull)
|
|
|
+ .collect(Collectors.toSet());
|
|
|
+ }
|
|
|
+ log.info("新数据中的违纪记录ID集合: {}", newDisciplineIds);
|
|
|
+
|
|
|
+ // 4. 找出需要删除的记录(在数据库中存在,但不在新数据中)
|
|
|
+ Set<Long> toDeleteIds = new HashSet<>(existingDisciplineIds);
|
|
|
+ toDeleteIds.removeAll(newDisciplineIds);
|
|
|
+ log.info("需要删除的违纪记录ID集合: {}", toDeleteIds);
|
|
|
+
|
|
|
+ // 5. 删除不再存在的记录
|
|
|
+ for (Long deleteId : toDeleteIds) {
|
|
|
+ deleteViolationRecord(hygieneCheckId, deleteId);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 6. 处理新数据中的记录(新增或更新)
|
|
|
+ if (newViolationData != null && !newViolationData.isEmpty()) {
|
|
|
+ for (XgViolationDataBo violationBo : newViolationData) {
|
|
|
+ try {
|
|
|
+ log.info("处理违纪记录数据: {}", violationBo);
|
|
|
+
|
|
|
+ // 如果是已存在的违纪记录(有违纪记录ID且在现有记录中),更新统一表中的记录
|
|
|
+ Long currentDisciplineRecordId = violationBo.getDisciplineRecordId() != null
|
|
|
+ ? violationBo.getDisciplineRecordId()
|
|
|
+ : violationBo.getId();
|
|
|
+ if (currentDisciplineRecordId != null
|
|
|
+ && existingDisciplineIds.contains(currentDisciplineRecordId)) {
|
|
|
+ log.info("更新现有违纪记录,违纪记录ID: {}", currentDisciplineRecordId);
|
|
|
+ updateDisciplineRecord(violationBo);
|
|
|
+ } else {
|
|
|
+ // 新增违纪记录
|
|
|
+ log.info("新增违纪记录,学生ID: {}", violationBo.getStudentId());
|
|
|
+ Long disciplineRecordId = createDisciplineRecord(violationBo);
|
|
|
+
|
|
|
+ if (disciplineRecordId != null && violationService != null) {
|
|
|
+ XgHygieneCheckViolationBo relationBo = new XgHygieneCheckViolationBo();
|
|
|
+ relationBo.setHygieneCheckId(hygieneCheckId);
|
|
|
+ relationBo.setDisciplineRecordId(disciplineRecordId);
|
|
|
+ relationBo.setStudentId(violationBo.getStudentId());
|
|
|
+ relationBo.setStudentNo(violationBo.getStudentNo());
|
|
|
+ relationBo.setStudentName(violationBo.getStudentName());
|
|
|
+ relationBo.setDisciplineTypeId(violationBo.getDisciplineTypeId());
|
|
|
+ relationBo.setDisciplineTypeName(violationBo.getDisciplineTypeName());
|
|
|
+ relationBo.setViolationSource("1"); // 1-宿舍卫生检查
|
|
|
+ relationBo.setStatus("1"); // 1-生效
|
|
|
+
|
|
|
+ boolean relationResult = violationService.insertByBo(relationBo);
|
|
|
+ if (!relationResult) {
|
|
|
+ log.warn("创建卫生检查违纪关联记录失败,学生ID: {}", violationBo.getStudentId());
|
|
|
+ } else {
|
|
|
+ log.info("创建卫生检查违纪关联记录成功,学生ID: {},违纪记录ID: {}",
|
|
|
+ violationBo.getStudentId(), disciplineRecordId);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("处理违纪数据失败,学生ID: {}, 错误: {}", violationBo.getStudentId(), e.getMessage(), e);
|
|
|
+ throw new RuntimeException(
|
|
|
+ "处理违纪数据失败,学生ID: " + violationBo.getStudentId() + ", 错误: " + e.getMessage(), e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ log.info("违纪记录处理完成,卫生检查ID: {}", hygieneCheckId);
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("处理违纪记录数据失败,卫生检查ID: {}, 错误: {}", hygieneCheckId, e.getMessage(), e);
|
|
|
+ throw new RuntimeException("处理违纪记录数据失败: " + e.getMessage(), e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 删除违纪记录(同时删除关联表和统一表中的记录)
|
|
|
+ *
|
|
|
+ * @param hygieneCheckId 卫生检查ID
|
|
|
+ * @param disciplineRecordId 违纪记录ID
|
|
|
+ */
|
|
|
+ private void deleteViolationRecord(Long hygieneCheckId, Long disciplineRecordId) {
|
|
|
+ try {
|
|
|
+ log.info("开始逻辑删除违纪记录,卫生检查ID: {}, 违纪记录ID: {}", hygieneCheckId, disciplineRecordId);
|
|
|
+
|
|
|
+ // 1. 逻辑删除关联表中的记录 (xg_hygiene_check_violation)
|
|
|
+ if (violationMapper != null) {
|
|
|
+ LambdaQueryWrapper<XgHygieneCheckViolation> wrapper = Wrappers.lambdaQuery();
|
|
|
+ wrapper.eq(XgHygieneCheckViolation::getHygieneCheckId, hygieneCheckId)
|
|
|
+ .eq(XgHygieneCheckViolation::getDisciplineRecordId, disciplineRecordId);
|
|
|
+
|
|
|
+ // 使用逻辑删除
|
|
|
+ int deleteCount = violationMapper.delete(wrapper);
|
|
|
+ if (deleteCount > 0) {
|
|
|
+ log.info("逻辑删除卫生检查违纪关联记录成功,违纪记录ID: {}, 删除数量: {}", disciplineRecordId, deleteCount);
|
|
|
+ } else {
|
|
|
+ log.warn("逻辑删除卫生检查违纪关联记录失败,违纪记录ID: {}", disciplineRecordId);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 逻辑删除统一表中的记录 (xskh_discipline_record)
|
|
|
+ deleteDisciplineRecord(disciplineRecordId);
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("逻辑删除违纪记录失败,违纪记录ID: {}, 错误: {}", disciplineRecordId, e.getMessage(), e);
|
|
|
+ throw new RuntimeException("逻辑删除违纪记录失败: " + e.getMessage(), e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 逻辑删除统一表中的违纪记录
|
|
|
+ *
|
|
|
+ * @param disciplineRecordId 违纪记录ID
|
|
|
+ */
|
|
|
+ private void deleteDisciplineRecord(Long disciplineRecordId) {
|
|
|
+ try {
|
|
|
+ // 通过接口类型动态获取IXskhDisciplineRecordService,避免硬依赖
|
|
|
+ Class<?> serviceInterface = Class.forName("org.dromara.xskh.service.IXskhDisciplineRecordService");
|
|
|
+ Object disciplineRecordService = applicationContext.getBean(serviceInterface);
|
|
|
+
|
|
|
+ if (disciplineRecordService != null) {
|
|
|
+ // 使用deleteWithValidByIds方法进行逻辑删除
|
|
|
+ var deleteMethod = disciplineRecordService.getClass().getMethod("deleteWithValidByIds",
|
|
|
+ Collection.class, Boolean.class);
|
|
|
+ Boolean result = (Boolean) deleteMethod.invoke(disciplineRecordService,
|
|
|
+ Collections.singletonList(disciplineRecordId), false);
|
|
|
+
|
|
|
+ if (result) {
|
|
|
+ log.info("逻辑删除统一违纪记录成功,违纪记录ID: {}", disciplineRecordId);
|
|
|
+ } else {
|
|
|
+ log.error("逻辑删除统一违纪记录失败,违纪记录ID: {}", disciplineRecordId);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ log.error("未找到违纪记录服务,无法删除统一违纪记录,违纪记录ID: {}", disciplineRecordId);
|
|
|
+ }
|
|
|
+
|
|
|
+ } catch (ClassNotFoundException e) {
|
|
|
+ log.warn("学生考核管理模块(xskh)未启用,跳过统一违纪记录删除");
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("逻辑删除统一违纪记录失败,违纪记录ID: {}, 错误: {}", disciplineRecordId, e.getMessage(), e);
|
|
|
+ throw new RuntimeException("逻辑删除统一违纪记录失败: " + e.getMessage(), e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 更新学生违纪记录
|
|
|
+ *
|
|
|
+ * @param violationBo 违纪数据
|
|
|
+ */
|
|
|
+ private void updateDisciplineRecord(XgViolationDataBo violationBo) {
|
|
|
+ try {
|
|
|
+ // 通过接口类型动态获取IXskhDisciplineRecordService,避免硬依赖
|
|
|
+ Class<?> serviceInterface = Class.forName("org.dromara.xskh.service.IXskhDisciplineRecordService");
|
|
|
+ Object disciplineRecordService = applicationContext.getBean(serviceInterface);
|
|
|
+
|
|
|
+ if (disciplineRecordService != null) {
|
|
|
+ // 创建XskhDisciplineRecordBo对象
|
|
|
+ Object disciplineRecordBo = createDisciplineRecordBo(violationBo);
|
|
|
+ if (disciplineRecordBo != null) {
|
|
|
+ // 设置ID用于更新
|
|
|
+ setFieldValue(disciplineRecordBo, "id", violationBo.getId());
|
|
|
+
|
|
|
+ // 反射调用updateByBo方法
|
|
|
+ Class<?> disciplineRecordBoClass = Class
|
|
|
+ .forName("org.dromara.xskh.domain.bo.XskhDisciplineRecordBo");
|
|
|
+ var updateMethod = disciplineRecordService.getClass().getMethod("updateByBo",
|
|
|
+ disciplineRecordBoClass);
|
|
|
+ Boolean result = (Boolean) updateMethod.invoke(disciplineRecordService, disciplineRecordBo);
|
|
|
+
|
|
|
+ if (result) {
|
|
|
+ log.info("更新学生违纪记录成功,学生ID: {}, 违纪记录ID: {}",
|
|
|
+ violationBo.getStudentId(), violationBo.getId());
|
|
|
+ } else {
|
|
|
+ log.warn("更新学生违纪记录失败,学生ID: {}", violationBo.getStudentId());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (ClassNotFoundException e) {
|
|
|
+ log.warn("学生考核管理模块(xskh)未启用,跳过违纪记录更新");
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("更新学生违纪记录失败: {}", e.getMessage(), e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据卫生检查ID查询相关的违纪记录(包含详情)
|
|
|
+ *
|
|
|
+ * @param hygieneCheckId 卫生检查ID
|
|
|
+ * @return 违纪记录列表(包含详情)
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public List<XgHygieneCheckViolationVo> getViolationsByHygieneCheckId(Long hygieneCheckId) {
|
|
|
+ if (hygieneCheckId == null) {
|
|
|
+ log.warn("卫生检查ID为空,无法查询违纪记录");
|
|
|
+ return List.of();
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 使用自定义查询方法,关联查询违纪详情
|
|
|
+ List<XgHygieneCheckViolationVo> violations = violationMapper
|
|
|
+ .selectViolationsByHygieneCheckId(hygieneCheckId);
|
|
|
+
|
|
|
+ log.info("卫生检查ID: {} 查询到 {} 条违纪记录(包含详情)", hygieneCheckId, violations.size());
|
|
|
+ return violations;
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("查询卫生检查违纪记录失败,检查ID: {}, 错误: {}", hygieneCheckId, e.getMessage(), e);
|
|
|
+ return List.of();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
}
|