|
|
@@ -3,9 +3,11 @@ package org.dromara.jcbt.service.impl;
|
|
|
import cn.hutool.core.bean.BeanUtil;
|
|
|
import cn.hutool.core.util.ObjectUtil;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
import lombok.RequiredArgsConstructor;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.dromara.common.core.utils.MapstructUtils;
|
|
|
import org.dromara.common.core.utils.StringUtils;
|
|
|
@@ -30,6 +32,7 @@ import java.util.List;
|
|
|
* @author ruoyi
|
|
|
* @date 2025-01-27
|
|
|
*/
|
|
|
+@Slf4j
|
|
|
@RequiredArgsConstructor
|
|
|
@Service
|
|
|
public class JcbtScholarshipBatchServiceImpl implements IJcbtScholarshipBatchService {
|
|
|
@@ -112,9 +115,52 @@ public class JcbtScholarshipBatchServiceImpl implements IJcbtScholarshipBatchSer
|
|
|
@Override
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
public Boolean updateByBo(JcbtScholarshipBatchBo bo) {
|
|
|
+ // 添加调试日志 - 检查BO的ID
|
|
|
+ log.info("=== 修改操作调试 ===");
|
|
|
+ log.info("输入BO的ID: {}, 类型: {}", bo.getId(), bo.getId() != null ? bo.getId().getClass().getSimpleName() : "null");
|
|
|
+ log.info("输入BO的批次编码: {}", bo.getBatchCode());
|
|
|
+
|
|
|
JcbtScholarshipBatch update = MapstructUtils.convert(bo, JcbtScholarshipBatch.class);
|
|
|
+
|
|
|
+ // 添加调试日志 - 检查转换后实体的ID
|
|
|
+ log.info("转换后实体的ID: {}, 类型: {}", update.getId(), update.getId() != null ? update.getId().getClass().getSimpleName() : "null");
|
|
|
+ log.info("转换后实体的批次编码: {}", update.getBatchCode());
|
|
|
+
|
|
|
validEntityBeforeSave(update);
|
|
|
- boolean flag = baseMapper.updateById(update) > 0;
|
|
|
+
|
|
|
+ // 添加详细调试 - 检查updateById前的状态
|
|
|
+ log.info("=== updateById执行前检查 ===");
|
|
|
+ log.info("实体ID是否为null: {}", update.getId() == null);
|
|
|
+ log.info("实体ID值: {}", update.getId());
|
|
|
+ log.info("实体批次编码: {}", update.getBatchCode());
|
|
|
+
|
|
|
+ // 先检查数据库中是否存在该记录
|
|
|
+ JcbtScholarshipBatch existingRecord = baseMapper.selectById(update.getId());
|
|
|
+ log.info("数据库中是否存在该记录: {}", existingRecord != null);
|
|
|
+ if (existingRecord != null) {
|
|
|
+ log.info("数据库中的记录: ID={}, 批次编码={}", existingRecord.getId(), existingRecord.getBatchCode());
|
|
|
+ }
|
|
|
+
|
|
|
+ log.info("=== 开始执行updateById ===");
|
|
|
+
|
|
|
+ // 使用更安全的更新策略,避免唯一键约束冲突
|
|
|
+ boolean flag;
|
|
|
+ try {
|
|
|
+ flag = baseMapper.updateById(update) > 0;
|
|
|
+ log.info("updateById执行成功: {}", flag);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("updateById执行失败,错误信息: {}", e.getMessage());
|
|
|
+
|
|
|
+ // 如果是唯一键冲突,尝试使用自定义更新SQL
|
|
|
+ if (e.getMessage().contains("Duplicate entry") || e.getMessage().contains("duplicate key")) {
|
|
|
+ log.info("检测到唯一键冲突,尝试使用自定义更新策略");
|
|
|
+ flag = updateByIdSafely(update);
|
|
|
+ log.info("自定义更新策略执行结果: {}", flag);
|
|
|
+ } else {
|
|
|
+ // 其他异常直接抛出
|
|
|
+ throw e;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
if (flag) {
|
|
|
// 更新批次类型关联关系
|
|
|
@@ -129,8 +175,17 @@ public class JcbtScholarshipBatchServiceImpl implements IJcbtScholarshipBatchSer
|
|
|
* 保存前的数据校验
|
|
|
*/
|
|
|
private void validEntityBeforeSave(JcbtScholarshipBatch entity){
|
|
|
+ // 添加调试日志 - 检查校验时的ID
|
|
|
+ log.info("=== 数据校验调试 ===");
|
|
|
+ log.info("校验时实体的ID: {}, 类型: {}", entity.getId(), entity.getId() != null ? entity.getId().getClass().getSimpleName() : "null");
|
|
|
+ log.info("校验时实体的批次编码: {}", entity.getBatchCode());
|
|
|
+
|
|
|
// 批次编码重复性校验
|
|
|
- if (!checkBatchCodeUnique(entity.getBatchCode(), entity.getId())) {
|
|
|
+ boolean isUnique = checkBatchCodeUnique(entity.getBatchCode(), entity.getId());
|
|
|
+ log.info("唯一性校验结果: {}", isUnique);
|
|
|
+
|
|
|
+ if (!isUnique) {
|
|
|
+ log.error("批次编码唯一性校验失败 - 编码: {}, ID: {}", entity.getBatchCode(), entity.getId());
|
|
|
throw new RuntimeException("批次编码已存在");
|
|
|
}
|
|
|
|
|
|
@@ -208,12 +263,125 @@ public class JcbtScholarshipBatchServiceImpl implements IJcbtScholarshipBatchSer
|
|
|
*/
|
|
|
@Override
|
|
|
public Boolean checkBatchCodeUnique(String batchCode, Long id) {
|
|
|
- boolean exist = baseMapper.exists(Wrappers.<JcbtScholarshipBatch>lambdaQuery()
|
|
|
+ // 添加调试日志 - 检查唯一性校验逻辑
|
|
|
+ log.info("=== 唯一性校验调试 ===");
|
|
|
+ log.info("校验参数 - 批次编码: {}, ID: {}", batchCode, id);
|
|
|
+ log.info("ID是否非空: {}", ObjectUtil.isNotNull(id));
|
|
|
+
|
|
|
+ // 获取当前租户ID
|
|
|
+ String tenantId = LoginHelper.getTenantId();
|
|
|
+ log.info("当前租户ID: {}", tenantId);
|
|
|
+
|
|
|
+ LambdaQueryWrapper<JcbtScholarshipBatch> queryWrapper = Wrappers.<JcbtScholarshipBatch>lambdaQuery()
|
|
|
.eq(JcbtScholarshipBatch::getBatchCode, batchCode)
|
|
|
- .ne(ObjectUtil.isNotNull(id), JcbtScholarshipBatch::getId, id));
|
|
|
+ .eq(JcbtScholarshipBatch::getDeleted, 0); // 关键修复:只检查未删除的记录
|
|
|
+
|
|
|
+ // 如果是修改操作(ID不为空),排除当前记录
|
|
|
+ if (ObjectUtil.isNotNull(id)) {
|
|
|
+ queryWrapper.ne(JcbtScholarshipBatch::getId, id);
|
|
|
+ log.info("修改操作 - 排除当前记录ID: {}", id);
|
|
|
+ } else {
|
|
|
+ log.info("新增操作 - 不排除任何记录");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 查询数量而不是存在性,以便调试
|
|
|
+ long count = baseMapper.selectCount(queryWrapper);
|
|
|
+ boolean exist = count > 0;
|
|
|
+
|
|
|
+ log.info("数据库查询结果 - 相同编码的其他未删除记录数量: {}", count);
|
|
|
+ log.info("数据库查询结果 - 存在相同编码的其他未删除记录: {}", exist);
|
|
|
+ log.info("唯一性校验最终结果: {}", !exist);
|
|
|
+
|
|
|
+ // 详细分析重复记录情况
|
|
|
+ if (count > 0) {
|
|
|
+ log.error("=== 发现重复记录,详细查询 ===");
|
|
|
+ List<JcbtScholarshipBatch> duplicateRecords = baseMapper.selectList(queryWrapper);
|
|
|
+ for (JcbtScholarshipBatch record : duplicateRecords) {
|
|
|
+ log.error("重复记录详情 - ID: {}, 批次编码: {}, 是否删除: {}",
|
|
|
+ record.getId(), record.getBatchCode(), record.getDeleted());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查是否为ID不匹配问题
|
|
|
+ if (ObjectUtil.isNotNull(id)) {
|
|
|
+ boolean foundExactMatch = duplicateRecords.stream()
|
|
|
+ .anyMatch(record -> record.getId().equals(id));
|
|
|
+ if (!foundExactMatch) {
|
|
|
+ log.error("=== ID不匹配问题 ===");
|
|
|
+ log.error("请求修改的ID: {}", id);
|
|
|
+ log.error("数据库中实际存在的ID: {}",
|
|
|
+ duplicateRecords.stream().map(JcbtScholarshipBatch::getId).toList());
|
|
|
+ throw new RuntimeException(String.format(
|
|
|
+ "记录ID不匹配!请求ID: %s,数据库实际ID: %s。请刷新页面重新获取最新数据。",
|
|
|
+ id, duplicateRecords.get(0).getId()));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
return !exist;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 安全更新方法 - 避免唯一键约束冲突
|
|
|
+ * 使用指定字段更新,绕过可能的唯一键约束问题
|
|
|
+ */
|
|
|
+ private Boolean updateByIdSafely(JcbtScholarshipBatch update) {
|
|
|
+ log.info("=== 执行安全更新策略 ===");
|
|
|
+
|
|
|
+ // 构建更新条件
|
|
|
+ LambdaUpdateWrapper<JcbtScholarshipBatch> updateWrapper = Wrappers.lambdaUpdate();
|
|
|
+ updateWrapper.eq(JcbtScholarshipBatch::getId, update.getId());
|
|
|
+
|
|
|
+ // 只更新非唯一键相关的字段,避免约束冲突
|
|
|
+ if (update.getBatchName() != null) {
|
|
|
+ updateWrapper.set(JcbtScholarshipBatch::getBatchName, update.getBatchName());
|
|
|
+ }
|
|
|
+ if (update.getAcademicYear() != null) {
|
|
|
+ updateWrapper.set(JcbtScholarshipBatch::getAcademicYear, update.getAcademicYear());
|
|
|
+ }
|
|
|
+ if (update.getSemester() != null) {
|
|
|
+ updateWrapper.set(JcbtScholarshipBatch::getSemester, update.getSemester());
|
|
|
+ }
|
|
|
+ if (update.getBatchType() != null) {
|
|
|
+ updateWrapper.set(JcbtScholarshipBatch::getBatchType, update.getBatchType());
|
|
|
+ }
|
|
|
+ if (update.getStartTime() != null) {
|
|
|
+ updateWrapper.set(JcbtScholarshipBatch::getStartTime, update.getStartTime());
|
|
|
+ }
|
|
|
+ if (update.getEndTime() != null) {
|
|
|
+ updateWrapper.set(JcbtScholarshipBatch::getEndTime, update.getEndTime());
|
|
|
+ }
|
|
|
+ if (update.getApplyStartTime() != null) {
|
|
|
+ updateWrapper.set(JcbtScholarshipBatch::getApplyStartTime, update.getApplyStartTime());
|
|
|
+ }
|
|
|
+ if (update.getApplyEndTime() != null) {
|
|
|
+ updateWrapper.set(JcbtScholarshipBatch::getApplyEndTime, update.getApplyEndTime());
|
|
|
+ }
|
|
|
+ if (update.getReviewStartTime() != null) {
|
|
|
+ updateWrapper.set(JcbtScholarshipBatch::getReviewStartTime, update.getReviewStartTime());
|
|
|
+ }
|
|
|
+ if (update.getReviewEndTime() != null) {
|
|
|
+ updateWrapper.set(JcbtScholarshipBatch::getReviewEndTime, update.getReviewEndTime());
|
|
|
+ }
|
|
|
+ if (update.getStatus() != null) {
|
|
|
+ updateWrapper.set(JcbtScholarshipBatch::getStatus, update.getStatus());
|
|
|
+ }
|
|
|
+ if (update.getDescription() != null) {
|
|
|
+ updateWrapper.set(JcbtScholarshipBatch::getDescription, update.getDescription());
|
|
|
+ }
|
|
|
+ if (update.getNoticeContent() != null) {
|
|
|
+ updateWrapper.set(JcbtScholarshipBatch::getNoticeContent, update.getNoticeContent());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新基础字段
|
|
|
+ updateWrapper.set(JcbtScholarshipBatch::getUpdateBy, update.getUpdateBy());
|
|
|
+ updateWrapper.set(JcbtScholarshipBatch::getUpdateTime, update.getUpdateTime());
|
|
|
+
|
|
|
+ int result = baseMapper.update(null, updateWrapper);
|
|
|
+ log.info("安全更新策略影响行数: {}", result);
|
|
|
+
|
|
|
+ return result > 0;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 更改批次状态
|
|
|
*/
|