Переглянути джерело

fix(customer): 解决客户编号生成冲突问题

- 添加 DuplicateKeyException 导入用于处理主键冲突
- 实现客户编号生成的重试机制,最多重试3次
- 每次重试重新生成客户编号避免冲突
- 添加插入成功的判断逻辑和异常处理
- 记录重试日志便于问题排查
- 提供兜底的失败处理机制
hurx 1 місяць тому
батько
коміт
d601fbb7b5

+ 30 - 3
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/CustomerInfoServiceImpl.java

@@ -32,6 +32,7 @@ import org.dromara.customer.utils.qcc.domain.CompanyInfoResponse;
 import org.dromara.system.api.*;
 import org.dromara.system.api.domain.bo.RemoteUserBo;
 import org.dromara.system.api.domain.vo.RemoteDeptVo;
+import org.springframework.dao.DuplicateKeyException;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -944,15 +945,41 @@ public class CustomerInfoServiceImpl extends ServiceImpl<CustomerInfoMapper, Cus
         //构建客户信息实体
         CustomerInfo customerEntity = new CustomerInfo();
         customerEntity.setCustomerName(bo.getCustomerName());
-        customerEntity.setCustomerNo(SequenceUtils.nextPaddedIdStr(CUSTOMER_NO_KEY, Duration.ofDays(3650), 6));
         customerEntity.setBusinessCustomerName(companyInfo.getResult().getName());
         customerEntity.setShortName(companyInfo.getResult().getName());
         customerEntity.setInvoiceTop(companyInfo.getResult().getName());
         customerEntity.setStatus("0"); // 正常状态
         customerEntity.setDelFlag("0"); // 未删除
+        boolean insertSuccess = false;
+        int maxRetries = 3;
+
+// 1. 执行带重试的客户插入逻辑
+        for (int i = 0; i < maxRetries; i++) {
+            try {
+                // 生成编号 (注意:每次重试都要重新生成,避免使用冲突的号码)
+                String customerNo = SequenceUtils.nextPaddedIdStr(CUSTOMER_NO_KEY, Duration.ofDays(3650), 6);
+                customerEntity.setCustomerNo(customerNo);
+
+                // 执行插入
+                if (baseMapper.insert(customerEntity) > 0) {
+                    insertSuccess = true;
+                    break; // 【关键】插入成功,跳出循环,继续执行后续业务,而不是 return
+                } else {
+                    // 如果 insert 返回 0 (虽然通常主键冲突会抛异常,但以防万一)
+                    throw new ServiceException("客户信息新增失败 (影响行数为0)");
+                }
+            } catch (DuplicateKeyException e) {
+                if (i == maxRetries - 1) {
+                    log.error("客户编号生成冲突,重试 {} 次后仍失败", maxRetries, e);
+                    throw new ServiceException("客户编号生成冲突,请稍后重试");
+                }
+                log.warn("客户编号 {} 冲突,正在重试第 {} 次", customerEntity.getCustomerNo(), i + 1);
+                // 循环继续,下一次迭代会重新生成 customerNo
+            }
+        }
 
-        // 设置其他工商信息
-        if (baseMapper.insert(customerEntity) <= 0) {
+        if (!insertSuccess) {
+            // 理论上如果没抛异常且没成功,应该到这里,作为兜底
             throw new ServiceException("客户信息新增失败");
         }