Selaa lähdekoodia

fix(charging): 优化价格策略同步和充电站信息同步定时任务

- 修改开发环境数据库和Redis连接配置,更新测试库和Redis地址密码
- 更新生产环境支付回调地址为新的域名
- 优化充电站信息同步任务日志和异常处理,确保同步流程清晰稳定
- 添加价格策略同步任务并发执行标记,防止重复执行
- 在价格策略同步任务中增加了接口调用频率控制,避免触发第三方保护机制
- 实现价格策略更新时间检查,若距离上次更新时间不足1小时则跳过同步
- 详细记录价格策略同步成功与失败数量,完善日志信息
- 增强异常捕获,防止单个接口异常影响整体任务执行
SheepHy 3 viikkoa sitten
vanhempi
commit
585cd62ad9

+ 34 - 34
src/main/java/com/zsElectric/boot/charging/quartz/ChargingJob.java

@@ -35,7 +35,7 @@ public class ChargingJob {
     private final ThirdPartyConnectorInfoMapper connectorInfoMapper;
     private final ThirdPartyEquipmentPricePolicyMapper pricePolicyMapper;
     private final ThirdPartyPolicyInfoMapper policyInfoMapper;
-    
+
     // 任务执行标记,防止并发执行
     private volatile boolean isPricePolicySyncRunning = false;
 
@@ -48,32 +48,32 @@ public class ChargingJob {
 //    @Scheduled(cron = "0 0/15 * * * ?")
     public void syncStationsInfo() {
         log.info("开始执行充电站信息同步定时任务");
-        
+
         try {
             // 获取当前时间作为查询时间
             String lastQueryTime = LocalDateTime.now().minusMinutes(30).format(FORMATTER);
-            
+
             // 分页查询,每次查询100条
             Integer pageNo = 1;
             Integer pageSize = 100;
-            
+
             log.info("查询参数 - LastQueryTime: {}, PageNo: {}, PageSize: {}", lastQueryTime, pageNo, pageSize);
-            
+
             // 调用业务服务查询充电站信息(会自动保存到数据库)
             QueryStationsInfoVO result = chargingBusinessService.queryStationsInfo(lastQueryTime, pageNo, pageSize);
-            
+
             if (result != null && result.getStationInfos() != null) {
                 log.info("充电站信息同步完成,共同步 {} 个充电站", result.getStationInfos().size());
             } else {
                 log.warn("充电站信息同步结果为空");
             }
-            
+
         } catch (JsonProcessingException e) {
             log.error("充电站信息同步失败 - JSON处理异常", e);
         } catch (Exception e) {
             log.error("充电站信息同步失败 - 系统异常", e);
         }
-        
+
         log.info("充电站信息同步定时任务执行结束");
     }
 
@@ -89,56 +89,56 @@ public class ChargingJob {
             log.warn("价格策略同步任务正在执行中,跳过本次调度");
             return;
         }
-        
+
         isPricePolicySyncRunning = true;
         log.info("开始执行设备价格策略同步定时任务");
-        
+
         try {
             // 查询所有充电桩接口信息
             List<ThirdPartyConnectorInfo> connectorList = connectorInfoMapper.selectList(null);
-            
+
             if (CollectionUtils.isEmpty(connectorList)) {
                 log.warn("未查询到充电桩接口信息,跳过价格策略同步");
                 return;
             }
-            
+
             log.info("开始同步价格策略,总共 {} 个充电桩接口", connectorList.size());
-            
+
             int successCount = 0;
             int failCount = 0;
-            
+
             // 遍历每个充电桩接口,查询价格策略
             for (ThirdPartyConnectorInfo connector : connectorList) {
                 try {
                     String connectorId = connector.getConnectorId();
                     String equipmentId = connector.getEquipmentId();
-                    
+
                     // 检查该充电桩的价格策略上次更新时间,如果不足1小时则跳过
                     if (shouldSkipUpdate(connectorId)) {
-                        log.info("充电桩价格策略上次更新时间不足1小时,跳过本次同步 - connectorId: {}, equipmentId: {}", 
+                        log.info("充电桩价格策略上次更新时间不足1小时,跳过本次同步 - connectorId: {}, equipmentId: {}",
                                 connectorId, equipmentId);
                         continue; // 跳过本次充电桩,不调用第三方接口
                     }
-                    
+
                     log.info("查询价格策略 - connectorId: {}, equipmentId: {}", connectorId, equipmentId);
-                    
+
                     // 调用业务服务查询价格策略(会自动保存到数据库)
                     ChargingPricePolicyVO result = chargingBusinessService.queryEquipBusinessPolicy(equipmentId, connectorId);
-                    
+
                     // 立即休眠10秒,避免触发第三方接口保护机制
                     // 第三方接口可能有频率限制,需要足够的间隔时间
 //                    Thread.sleep(18000); // 10秒间隔
-                    
+
                     if (result != null && result.getSuccStat() != null && result.getSuccStat() == 0) {
                         successCount++;
                         log.info("价格策略同步成功 - connectorId: {}, 时段数: {}", connectorId, result.getSumPeriod());
                     } else {
                         failCount++;
-                        log.warn("价格策略同步失败 - connectorId: {}, 失败原因: {}, 跳过该接口继续处理下一个", connectorId, 
+                        log.warn("价格策略同步失败 - connectorId: {}, 失败原因: {}, 跳过该接口继续处理下一个", connectorId,
                                 result != null ? result.getFailReason() : "返回结果为空");
                         continue; // 跳过失败的接口,继续处理下一个
                     }
-                    
+
 //                } catch (InterruptedException e) {
 //                    Thread.currentThread().interrupt();
 //                    log.error("线程休眠被中断 - connectorId: {}", connector.getConnectorId(), e);
@@ -149,9 +149,9 @@ public class ChargingJob {
                     log.error("同步价格策略失败 - connectorId: {}", connector.getConnectorId(), e);
                 }
             }
-            
+
             log.info("设备价格策略同步完成 - 成功: {}, 失败: {}, 总数: {}", successCount, failCount, connectorList.size());
-            
+
         } catch (Exception e) {
             log.error("设备价格策略同步定时任务执行异常", e);
         } finally {
@@ -160,11 +160,11 @@ public class ChargingJob {
             log.info("设备价格策略同步定时任务执行结束");
         }
     }
-    
+
     /**
      * 检查是否应该跳过更新
      * 如果该充电桩的价格策略上次更新时间不足1小时,则跳过
-     * 
+     *
      * @param connectorId 充电接口ID
      * @return true-跳过更新, false-需要更新
      */
@@ -177,12 +177,12 @@ public class ChargingJob {
                             .orderByDesc(ThirdPartyEquipmentPricePolicy::getCreateTime)
                             .last("LIMIT 1")
             ).stream().findFirst().orElse(null);
-            
+
             if (latestPolicy == null) {
                 // 没有记录,需要更新
                 return false;
             }
-            
+
             // 2. 查询该价格策略的明细记录,获取最近的更新时间
             List<ThirdPartyPolicyInfo> policyInfoList = policyInfoMapper.selectList(
                     new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<ThirdPartyPolicyInfo>()
@@ -190,30 +190,30 @@ public class ChargingJob {
                             .orderByDesc(ThirdPartyPolicyInfo::getUpdateTime)
                             .last("LIMIT 1")
             );
-            
+
             if (policyInfoList.isEmpty()) {
                 // 没有明细记录,需要更新
                 return false;
             }
-            
+
             LocalDateTime lastUpdateTime = policyInfoList.get(0).getUpdateTime();
             if (lastUpdateTime == null) {
                 // 没有更新时间,需要更新
                 return false;
             }
-            
+
             // 3. 判断是否距离上次更新不足1小时
             LocalDateTime oneHourAgo = LocalDateTime.now().minusHours(1);
             if (lastUpdateTime.isAfter(oneHourAgo)) {
                 // 上次更新时间在1小时内,跳过更新
-                log.debug("充电桩价格策略距离上次更新不足1小时 - connectorId: {}, lastUpdateTime: {}", 
+                log.debug("充电桩价格策略距离上次更新不足1小时 - connectorId: {}, lastUpdateTime: {}",
                         connectorId, lastUpdateTime);
                 return true;
             }
-            
+
             // 距离上次更新超过1小时,需要更新
             return false;
-            
+
         } catch (Exception e) {
             log.error("检查更新时间失败,默认需要更新 - connectorId: {}", connectorId, e);
             // 发生异常时,默认需要更新

+ 4 - 4
src/main/resources/application-dev.yml

@@ -5,15 +5,15 @@ spring:
   datasource:
     type: com.alibaba.druid.pool.DruidDataSource
     driver-class-name: com.mysql.cj.jdbc.Driver
-    url: jdbc:mysql://rm-2vc2zl1990od9qvg0eo.mysql.cn-chengdu.rds.aliyuncs.com:3306/z_electric?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+    url: jdbc:mysql://rm-2vc2zl1990od9qvg0eo.mysql.cn-chengdu.rds.aliyuncs.com:3306/zs_test?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
     username: root
     password: 1KQaNI+vPz8^xfYcb%l6
   data:
     redis:
-      database: 7
-      host: 47.109.18.141
+      database: 9
+      host: 192.168.1.242
       port: 6379
-      password: BXyzm3RKR2nA9vn5ZkeP
+      password: FaajjVy8rl(k
       timeout: 10s
       lettuce:
         pool:

+ 1 - 1
src/main/resources/application-prod.yml

@@ -306,7 +306,7 @@ wx:
   #支付请求成功后的回调地址--需要配置正确的域名
   #  notify_url: http://120.78.228.211:8880/orderApi/enditPay
 #  notify_url: https://13cd4c06.r28.cpolar.top/applet/v1/wft/order/notify
-  notify_url: https://47.109.18.141:8989/applet/v1/wft/order/notify
+  notify_url: https://cd.admin.zswlgz.com/applet/v1/wft/order/notify
   #私钥
   mchPrivateKey: MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDeFB5G2OYT762PpUytCw7Du40i6WnzcmbvEE9IXPXi+QirPwMvW9mBqNDIUk5hQS3ZnHjj80YQRWG6yksjE6kHAYIWahCDiaPlBqYvYSJ8ePzbT61THZJbzqFaIG3svW7xq9nsUmzVBub0ATIzC1DQRu9ZTdrj/iuMUEhJyJ8IHrTP09eTwNYdoagHQlKWRVoNE3LuU4GXG3VCbkQ2ixbMo8dXBisDIi3GYOSFWzota6H+OCp9Mta1jTqdwALKAU9PNlRkQwOMLk2OmMqGUhImVVpl+eGrIYn3iARce0alNFg8hghFMJ8MKpSxJDM6YHNOJQ06S25YYhTpd+C2/VOBAgMBAAECggEBAM/W9ksJ/bJU0xOn+W3N9oB7C+jLmMwtmmZM1lZ8IefNeC6Ep59wD81ISDXiydY9YQLTbVSxPjZGKOPfJZjrcnrLD4uYsmHYtFnI8klPWC40MTmzhRxPhcWESgAGb7prw+RMGIUS0yY/8nAUmn2pLnXunVzv/1b3bpxAGpdrOmMmU28GBt9AlXiIpVmnxnkhp66c4zFj5gvvVoDrz9m/6Acyn6n7yccCHD2iYw0D78GPItEWky38tH/FV0lRcCCYAf5fc2nFnicrdgj1RYjqTWxM7A92UecviTAbiuPO6CQQl7+sMtGU2d6UeKj0Xrrl2gly+lOS97P/NcLtZf5vklECgYEA8SMlCg5AToSkIwal7dXYgM2VlNFwSRDuO3hEVoWe7bM/LkEp8dqSpV025ZtngTY/qziXsGP/7l8bcS1th19cX/+/MFFOWsoxtqvOam2Elp+Qg1johEfnWI+Bo4WiQ5CHYNQRN3cuiWTc5HHuI0KQAEPx/aYogD057X2FIsiu6S0CgYEA68RAFsupZ6R8BhJbfY2CK07XLNvXu5DAYBmU3trmQFnaxXeQFfhQ8hi9m5Awu14YCnRmHzc8+QXFD/GqTAbxtImc6AZQKWdLuUntkitPWmJK6dtJC8Is3U9Yqz5+CkSmgZSfqW0DvEt7jagoNfpKgy29Qq4r35b6JsDXtnTQICUCgYEAjmwnkEzihn2pRFbE4jiP62OBmagqHb22N8HM+x1oxRQ9mOA8GfDy9GCd7/ddpt+Xs1V1omUt4GikGLCwJGiacsjm727WTKFnw3CuNgYBbcVI4Ys9qgOeDJyWATMIp8dRbktS7+OgxN2h6fuwn3rM+psm7p2ZBkUjVbXxUJ4fUPECgYEAw1wmAv2VjRUF0/4oI5w7bWlx8XDljT1/uuHXsuZN/qq2FgRht2LAqCsKCjprtwZcA2W6LUmXU32Ncg29ICxs4j1ZcAWzLOu0GoAAxKrwoSNrkeYr2/t1M5kJDzTEOfvywNMHjduQSdl+Mr5RO5D/Zz1iYztxjV9MPwpydHTM9KUCgYAHuT98NkBilMxQNNmUB13E10MYQvZuiGVFZtT3up69Elpmtm7Z5cEW7QNG0g1LPPfkzfWPsq+6I98FmozLickqvjntdpul4czTITn8SNHqoxvdbcVnDipF1KwlHcnXhjO1KjSZg3a/iv554OR3/rbD9SWDzDAT7Zy6zX9n8OwGRA==
   #公钥(商户平台的公钥,不是自己生成的公钥)