Răsfoiți Sursa

feat: 企业名称sync重试—通知失败标记+定时任务指数退避20次max

alphaH 23 ore în urmă
părinte
comite
637ec3e4ca

+ 7 - 0
java/sql/011_enterprise_name_sync_retry.sql

@@ -0,0 +1,7 @@
+-- 企业名称同步重试字段
+ALTER TABLE pay_enterprise ADD COLUMN IF NOT EXISTS name_sync_status VARCHAR(1) DEFAULT '0';
+ALTER TABLE pay_enterprise ADD COLUMN IF NOT EXISTS name_sync_retry_count INT DEFAULT 0;
+ALTER TABLE pay_enterprise ADD COLUMN IF NOT EXISTS name_sync_next_time TIMESTAMP;
+
+-- 已有记录默认标记为无需同步(避免大量重试)
+UPDATE pay_enterprise SET name_sync_status = '1' WHERE name_sync_status = '0';

+ 9 - 0
java/src/main/java/com/payment/platform/module/payment/enterprise/entity/EnterpriseEntity.java

@@ -36,6 +36,15 @@ public class EnterpriseEntity extends PaymentTenantBaseEntity {
     /** 万里汇uid(国外服务商必填) */
     /** 万里汇uid(国外服务商必填) */
     private String wanlihuiUid;
     private String wanlihuiUid;
 
 
+    /** 名称同步状态: 0=未同步, 1=已同步 */
+    private String nameSyncStatus;
+
+    /** 名称同步重试次数 */
+    private Integer nameSyncRetryCount;
+
+    /** 名称同步下次重试时间 */
+    private OffsetDateTime nameSyncNextTime;
+
     /** 入驻材料:营业执照(图片路径) */
     /** 入驻材料:营业执照(图片路径) */
     private String businessLicense;
     private String businessLicense;
 
 

+ 62 - 0
java/src/main/java/com/payment/platform/module/payment/enterprise/scheduler/EnterpriseNameSyncScheduler.java

@@ -0,0 +1,62 @@
+package com.payment.platform.module.payment.enterprise.scheduler;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.payment.platform.module.payment.enterprise.entity.EnterpriseEntity;
+import com.payment.platform.module.payment.enterprise.mapper.EnterpriseMapper;
+import com.payment.platform.module.payment.enterprise.service.AlipayEnterpriseService;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import java.time.OffsetDateTime;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 企业名称同步重试任务 — 入驻激活后支付宝查详情可能因产品未签约临时失败,周期重试
+ */
+@Slf4j
+@Component
+@RequiredArgsConstructor
+public class EnterpriseNameSyncScheduler {
+
+    private final EnterpriseMapper enterpriseMapper;
+    private final AlipayEnterpriseService alipayEnterpriseService;
+
+    private static final int MAX_RETRY = 20;
+
+    @Scheduled(fixedDelay = 10 * 60 * 1000) // 每 10 分钟
+    public void retryNameSync() {
+        List<EnterpriseEntity> list = enterpriseMapper.selectList(
+                new LambdaQueryWrapper<EnterpriseEntity>()
+                        .eq(EnterpriseEntity::getNameSyncStatus, "0")
+                        .lt(EnterpriseEntity::getNameSyncRetryCount, MAX_RETRY)
+                        .le(EnterpriseEntity::getNameSyncNextTime, OffsetDateTime.now())
+                        .last("LIMIT 50"));
+        if (list.isEmpty()) return;
+
+        log.info("[企业名称同步] 待重试: {} 条", list.size());
+        int success = 0;
+        for (EnterpriseEntity entity : list) {
+            try {
+                Map<String, Object> info = alipayEnterpriseService.queryEnterpriseDetail(entity.getEnterpriseId());
+                if (info != null && !info.isEmpty()) {
+                    if (info.get("enterprise_name") != null) entity.setName((String) info.get("enterprise_name"));
+                    if (info.get("enterprise_alias") != null) entity.setShortName((String) info.get("enterprise_alias"));
+                    if (info.get("account_id") != null) entity.setAccountId((String) info.get("account_id"));
+                    entity.setNameSyncStatus("1");
+                    success++;
+                }
+            } catch (Exception e) {
+                int retry = entity.getNameSyncRetryCount() != null ? entity.getNameSyncRetryCount() + 1 : 1;
+                entity.setNameSyncRetryCount(retry);
+                // 指数退避: 10min, 20min, 40min, 80min... 最大 12h
+                long delay = Math.min(10L * (1L << Math.min(retry, 6)), 12 * 60);
+                entity.setNameSyncNextTime(OffsetDateTime.now().plusMinutes(delay));
+            }
+            enterpriseMapper.updateIgnoreTenant(entity);
+        }
+        log.info("[企业名称同步] 完成: 成功 {}/{}", success, list.size());
+    }
+}

+ 7 - 1
java/src/main/java/com/payment/platform/module/payment/notification/handler/EnterpriseHandler.java

@@ -9,6 +9,7 @@ import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Component;
 import org.springframework.stereotype.Component;
 
 
+import java.time.OffsetDateTime;
 import java.util.Map;
 import java.util.Map;
 
 
 /**
 /**
@@ -131,10 +132,15 @@ public class EnterpriseHandler extends BaseNotifyHandler {
                     if (info.get("account_id") != null) entity.setAccountId((String) info.get("account_id"));
                     if (info.get("account_id") != null) entity.setAccountId((String) info.get("account_id"));
                     if (info.get("enterprise_name") != null) entity.setName((String) info.get("enterprise_name"));
                     if (info.get("enterprise_name") != null) entity.setName((String) info.get("enterprise_name"));
                     if (info.get("enterprise_alias") != null) entity.setShortName((String) info.get("enterprise_alias"));
                     if (info.get("enterprise_alias") != null) entity.setShortName((String) info.get("enterprise_alias"));
+                    entity.setNameSyncStatus("1");
                     enterpriseMapper.updateIgnoreTenant(entity);
                     enterpriseMapper.updateIgnoreTenant(entity);
                 }
                 }
             } catch (Exception e) {
             } catch (Exception e) {
-                log.warn("同步企业详情失败(不影响主流程): enterprise_id={}, error={}", enterpriseId, e.getMessage());
+                log.warn("同步企业详情失败,标记重试: enterprise_id={}, error={}", enterpriseId, e.getMessage());
+                entity.setNameSyncStatus("0");
+                entity.setNameSyncRetryCount(0);
+                entity.setNameSyncNextTime(OffsetDateTime.now().plusMinutes(10));
+                enterpriseMapper.updateIgnoreTenant(entity);
             }
             }
         }
         }
     }
     }