|  |  | @ -14,11 +14,20 @@ import org.springframework.stereotype.Service; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | import javax.annotation.Resource; |  |  |  | import javax.annotation.Resource; | 
			
		
	
		
		
			
				
					
					|  |  |  | import java.util.Arrays; |  |  |  | import java.util.Arrays; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | import java.util.UUID; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | import java.util.concurrent.TimeUnit; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | @Service |  |  |  | @Service | 
			
		
	
		
		
			
				
					
					|  |  |  | public class HeartTaskService { |  |  |  | public class HeartTaskService { | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     final Logger logger = LoggerFactory.getLogger(HeartTask.class); |  |  |  |     private static final Logger logger = LoggerFactory.getLogger(HeartTaskService.class); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     // 确保常量命名与HeartTask保持一致
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     private static final String REDIS_DOWNLOAD_STATUS_KEY = "SC_UDIINFO_DOWNLOAD_STATUS"; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     private static final String REDIS_UPLOAD_STATUS_KEY = "UPLOAD_UDIINFO_STATUS"; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     private static final String DOWNLOAD_LOCK_KEY = "is_doing_download"; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     // Redis锁过期时间(秒):设置合理的超时时间,避免任务卡死导致锁无法释放
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     private static final int LOCK_EXPIRY_SECONDS = 30 * 60; // 30分钟
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     @Resource |  |  |  |     @Resource | 
			
		
	
		
		
			
				
					
					|  |  |  |     SystemParamConfigService systemParamConfigService; |  |  |  |     SystemParamConfigService systemParamConfigService; | 
			
		
	
		
		
			
				
					
					|  |  |  |     @Resource |  |  |  |     @Resource | 
			
		
	
	
		
		
			
				
					|  |  | @ -34,91 +43,85 @@ public class HeartTaskService { | 
			
		
	
		
		
			
				
					
					|  |  |  |     @Value("${SPMS_WEBSOCKET_TOKEN}") |  |  |  |     @Value("${SPMS_WEBSOCKET_TOKEN}") | 
			
		
	
		
		
			
				
					
					|  |  |  |     private String socketToken; |  |  |  |     private String socketToken; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     //定时从上游下载数据
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     public void dlData() { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         SystemParamConfigEntity upConnect = systemParamConfigService.selectByParamKey("sync_upstream_enable"); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (upConnect != null && upConnect.getParamValue().equals("1")) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             dlAllData(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             scanUpload(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         SystemParamConfigEntity donwConnect = systemParamConfigService.selectByParamKey("sync_downstream_enable"); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (donwConnect != null && donwConnect.getParamValue().equals("1")) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             scanDonwload(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     private void scanUpload() { |  |  |  |     /** | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         SystemParamConfigEntity systemParamConfigEntity = systemParamConfigService.selectByParamKey("sc_udiinfo_upload"); |  |  |  |      * 从上游下载全部数据 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         long timeInterval = Long.parseLong(systemParamConfigEntity.getParamValue()) * 60 * 1000; |  |  |  |      * 该方法支持被HeartTask或其他服务直接调用 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         long curTime = System.currentTimeMillis(); |  |  |  |      * 内部实现了基于Redis的分布式锁,确保在分布式环境下也只有一个实例执行 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         //定时扫描
 |  |  |  |      */ | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         Long lastTime = (Long) redisUtil.get("UPLOAD_UDIINFO_STATUS"); |  |  |  |     public void dlAllData() { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         if (lastTime == null) { |  |  |  |         logger.info("定时从上游下载全部据-----开始"); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             lastTime = System.currentTimeMillis(); |  |  |  |         // 先更新时间戳,防止其他实例重复执行
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             redisUtil.set("UPLOAD_UDIINFO_STATUS", lastTime, 30 * 60); |  |  |  |         // 此处的时间戳更新会被HeartTask及其他服务读取用于判断是否执行
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         redisUtil.set(REDIS_DOWNLOAD_STATUS_KEY, System.currentTimeMillis()); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         if (curTime - lastTime > timeInterval) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             redisUtil.set("UPLOAD_UDIINFO_STATUS", curTime); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             scanUploadService.scanAllDatas(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             scanUploadService.scanAllBus(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             scanUploadService.scanAllOrders(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             scanUploadService.scanAllSchedule(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     private void scanDonwload() { |  |  |  |         // 生成唯一的锁标识,用于安全释放锁(避免释放其他实例的锁)
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         SystemParamConfigEntity upConnect = systemParamConfigService.selectByParamKey("sync_downstream_enable"); |  |  |  |         String lockValue = UUID.randomUUID().toString(); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         if (upConnect.getParamValue().equals("1")) { |  |  |  |         boolean lockAcquired = false; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             SystemParamConfigEntity systemParamConfigEntity = systemParamConfigService.selectByParamKey("sc_udiinfo_status"); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             long timeInterval = Long.parseLong(systemParamConfigEntity.getParamValue()) * 60 * 1000; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             long curTime = System.currentTimeMillis(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             Long lastTime = (Long) redisUtil.get("SC_UDIINFO_DOWNLOAD_STATUS"); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (lastTime == null) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 lastTime = System.currentTimeMillis(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 redisUtil.set("SC_UDIINFO_DOWNLOAD_STATUS", lastTime); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (curTime - lastTime > timeInterval) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 redisUtil.set("SC_UDIINFO_DOWNLOAD_STATUS", curTime); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 scanDownloadService.scanAllData(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 scanDownloadService.scanAllBus(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 scanDownloadService.scanAllOrder(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 scanDownloadService.scanScheduleList(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 scanDownloadService.scanUdis(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         try { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             // 检查是否已有下载任务在进行
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             String existingLock = (String) redisUtil.get(DOWNLOAD_LOCK_KEY); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             if (existingLock != null && !existingLock.equals("false")) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 logger.info("已有下载任务正在执行中,跳过本次执行"); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 return; | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     public void dlUpAllData() { |  |  |  |             // 尝试获取锁,使用唯一值标识锁的拥有者
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         SystemParamConfigEntity upConnect = systemParamConfigService.selectByParamKey("sync_upstream_enable"); |  |  |  |             lockAcquired = redisUtil.set(DOWNLOAD_LOCK_KEY, lockValue, LOCK_EXPIRY_SECONDS); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         if (upConnect != null && upConnect.getParamValue().equals("1")) { |  |  |  |             if (!lockAcquired) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             dlAllData(); |  |  |  |                 logger.warn("无法获取下载任务锁,可能有其他进程正在执行"); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |                 return; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |             logger.info("成功获取下载锁,开始执行数据下载任务,锁ID: {}", lockValue); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |             try { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     public void dlAllData() { |  |  |  |                 // 执行订单数据下载
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         logger.info("定时从上游下载全部据-----"); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         redisUtil.set("SC_UDIINFO_DOWNLOAD_STATUS", System.currentTimeMillis()); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         String doing = (String) redisUtil.get("is_doing_download"); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (doing == null || doing.equals("false")) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             redisUtil.set("is_doing_download", "true", 60); |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                 dlAllDataService.dllNewAllOrder(); |  |  |  |                 dlAllDataService.dllNewAllOrder(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 // 执行其他类型数据下载
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 Arrays.stream(BasicExportTypeEnum.values()).forEach(i -> { |  |  |  |                 Arrays.stream(BasicExportTypeEnum.values()).forEach(i -> { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     try { | 
			
		
	
		
		
			
				
					
					|  |  |  |                         dlAllDataService.pullData(i); |  |  |  |                         dlAllDataService.pullData(i); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     } catch (Exception e) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         logger.error("下载数据类型[{}]时发生异常", i, e); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     } | 
			
		
	
		
		
			
				
					
					|  |  |  |                 }); |  |  |  |                 }); | 
			
		
	
		
		
			
				
					
					|  |  |  |             dlAllDataService.dlAllDi(); |  |  |  |                 // 注释掉的DI下载,保留注释
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             redisUtil.set("is_doing_download", "false"); |  |  |  |                 // dlAllDataService.dlAllDi();
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             spsSyncWebSocket.sendMessage(SocketMsgEntity.builder().type(SocketMsgType.DL_ALL_DATA).content("").remark("下载基础信息").build(), "2:" + socketToken); |  |  |  |                 // 发送WebSocket消息通知
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |                 try { | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     spsSyncWebSocket.sendMessage( | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                             SocketMsgEntity.builder() | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                     .type(SocketMsgType.DL_ALL_DATA) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                     .content("") | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                     .remark("下载基础信息") | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                     .build(), | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                             "2:" + socketToken | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     ); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 } catch (Exception e) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     logger.error("发送WebSocket消息失败", e); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 logger.info("数据下载任务执行完成"); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             } catch (Exception e) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 logger.error("执行数据下载任务过程中发生异常", e); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } finally { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             // 确保无论如何都释放锁,但只释放自己的锁
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             if (lockAcquired) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 // 检查锁是否仍然是我们设置的值,避免释放他人的锁
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 String currentLock = (String) redisUtil.get(DOWNLOAD_LOCK_KEY); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 if (lockValue.equals(currentLock)) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     boolean released = redisUtil.set(DOWNLOAD_LOCK_KEY, "false"); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     if (!released) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         logger.error("释放下载任务锁失败"); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     } else { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         logger.info("成功释放下载锁,锁ID: {}", lockValue); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 } else { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     logger.warn("锁已被其他进程修改,不进行释放,当前锁值: {}, 期望锁值: {}", currentLock, lockValue); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |             logger.info("定时从上游下载全部据-----结束"); |  |  |  |             logger.info("定时从上游下载全部据-----结束"); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     public void getData(String message){ |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         logger.error("jiehsou 要发送的数据"); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         spsSyncWebSocket.sendMessage(SocketMsgEntity.builder().content(message).type(SocketMsgType.STAT_DATA).remark("我瞎说的数据").build(), "2:" + socketToken); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
	
		
		
			
				
					|  |  | 
 |