You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
			
				
					
					
						
							153 lines
						
					
					
						
							5.9 KiB
						
					
					
				
			
		
		
	
	
							153 lines
						
					
					
						
							5.9 KiB
						
					
					
				| package com.ynxbd.common.service.cache;
 | |
| 
 | |
| import com.ynxbd.common.bean.enums.MerchantEnum;
 | |
| import com.ynxbd.common.bean.pay.Order;
 | |
| import com.ynxbd.common.bean.pay.Recipe;
 | |
| import com.ynxbd.common.config.EhCacheConfig;
 | |
| import com.ynxbd.common.helper.common.DateHelper;
 | |
| import com.ynxbd.common.helper.timer.TimerManager;
 | |
| import com.ynxbd.common.service.PayService;
 | |
| import com.ynxbd.common.service.RecipeService;
 | |
| import lombok.extern.slf4j.Slf4j;
 | |
| import org.apache.commons.lang3.ObjectUtils;
 | |
| import org.ehcache.Cache;
 | |
| 
 | |
| import java.util.Timer;
 | |
| 
 | |
| @Slf4j
 | |
| public class PayCache {
 | |
|     private PayCache() {
 | |
|     }
 | |
| 
 | |
|     static {
 | |
|         createAccessTokenCache();
 | |
|     }
 | |
| 
 | |
|     // 缓存
 | |
|     private static Cache<String, Recipe> RECIPE_ORDER_CACHE;
 | |
| 
 | |
|     private static Timer RECIPE_TIMER = null;
 | |
| 
 | |
| 
 | |
|     private synchronized static void createAccessTokenCache() {
 | |
|         if (RECIPE_ORDER_CACHE == null) {
 | |
|             RECIPE_ORDER_CACHE = EhCacheConfig.createCacheTTL(String.class, Recipe.class, "recipe_order_cache", (60 * 30L)); // 半小时
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     public synchronized static void putRecipeCache(String tradeNo, Recipe recipe) {
 | |
|         if (RECIPE_ORDER_CACHE == null) {
 | |
|             createAccessTokenCache();
 | |
|         }
 | |
|         if (ObjectUtils.isEmpty(tradeNo)) {
 | |
|             return;
 | |
|         }
 | |
|         if (recipe == null) {
 | |
|             return;
 | |
|         }
 | |
|         if (RECIPE_ORDER_CACHE.containsKey(tradeNo)) {
 | |
|             log.info("[处方]定时器-新增超时订单 tradeNo={}", tradeNo);
 | |
|             return;
 | |
|         }
 | |
|         recipe.setCacheNum(2); // 调用3次
 | |
| 
 | |
|         log.info("[处方]定时器-新增超时订单 tradeNo={}", tradeNo);
 | |
|         RECIPE_ORDER_CACHE.put(tradeNo, recipe);
 | |
| 
 | |
|         if (RECIPE_TIMER == null) { // 定时器(初始化|被销毁),重新生成
 | |
|             init();
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     public synchronized static void removeRecipe(String tradeNo) {
 | |
|         if (RECIPE_ORDER_CACHE.containsKey(tradeNo)) {
 | |
|             RECIPE_ORDER_CACHE.remove(tradeNo);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     private synchronized static void init() {
 | |
|         if (RECIPE_TIMER != null) { // 防止定时器重复创建
 | |
|             return;
 | |
|         }
 | |
|         RECIPE_TIMER = TimerManager.setInterval(new TimerManager.TimerMethod() {
 | |
|             @Override
 | |
|             public void run() {
 | |
|                 if (DateHelper.inTimeRangeH_m_s("23:55:00", "23:59:59")) {
 | |
|                     RECIPE_ORDER_CACHE.clear();
 | |
|                 }
 | |
| 
 | |
|                 RecipeService recipeService = new RecipeService();
 | |
|                 Recipe errorRecipe;
 | |
|                 String outTradeNo, tradeNo;
 | |
|                 Recipe resp;
 | |
|                 int size = 0;
 | |
|                 for (Cache.Entry<String, Recipe> cache : RECIPE_ORDER_CACHE) {
 | |
|                     size++;
 | |
|                     if (size == 200) { // 防止过多请求导致HIS阻塞
 | |
|                         log.info("[处方][定时器]超时订单数量超过200,清除当前任务");
 | |
|                         RECIPE_ORDER_CACHE.clear();
 | |
|                         break;
 | |
|                     }
 | |
| 
 | |
|                     errorRecipe = cache.getValue();
 | |
|                     tradeNo = cache.getKey();
 | |
|                     outTradeNo = errorRecipe.getOutTradeNo();
 | |
|                     if (outTradeNo == null || !"500".equals(errorRecipe.getErrorCode())) {
 | |
|                         RECIPE_ORDER_CACHE.remove(tradeNo);
 | |
|                         continue;
 | |
|                     }
 | |
| 
 | |
|                     Order order = PayService.queryOrderByOutTradeNo(outTradeNo, null);
 | |
|                     if (!order.isSuccess() || order.isRefund()) { // 订单未找到 | 订单发生退款
 | |
|                         log.info("[处方][定时器]订单未找到或发生过退款 outTradeNo={}, tradeNo={}", outTradeNo, tradeNo);
 | |
|                         RECIPE_ORDER_CACHE.remove(tradeNo);
 | |
|                         continue;
 | |
|                     }
 | |
| 
 | |
|                     // HIS处方缴费
 | |
|                     MerchantEnum merchantEnum = MerchantEnum.getMerchantEnumByOutTradeNo(outTradeNo);
 | |
|                     if (MerchantEnum.ALI.equals(merchantEnum)) {
 | |
|                         log.info("[处方]定时器,支付宝订单不处理");
 | |
|                         RECIPE_ORDER_CACHE.remove(tradeNo);
 | |
|                         continue;
 | |
|                     }
 | |
| 
 | |
|                     log.info("[处方][定时器]HIS请求开始 outTradeNo={}, tradeNo={}", outTradeNo, tradeNo);
 | |
|                     resp = recipeService.recipeSinglePay(errorRecipe,
 | |
|                             DateHelper.getCurDate(), DateHelper.getCurTime(), merchantEnum);
 | |
| 
 | |
|                     if (resp.isSuccess()) {
 | |
|                         RECIPE_ORDER_CACHE.remove(tradeNo);
 | |
|                         continue;
 | |
|                     }
 | |
| 
 | |
|                     if ("500".equals(resp.getErrorCode())) { // 500调用超时
 | |
|                         log.info("[处方][定时器]HIS请求超时 outTradeNo={}, tradeNo={}", outTradeNo, tradeNo);
 | |
|                         int cacheNum = errorRecipe.getCacheNum();
 | |
|                         if (cacheNum <= 0) {
 | |
|                             RECIPE_ORDER_CACHE.remove(tradeNo);
 | |
|                         } else {
 | |
|                             cacheNum--;
 | |
|                             errorRecipe.setCacheNum(cacheNum);
 | |
|                             RECIPE_ORDER_CACHE.replace(tradeNo, errorRecipe);
 | |
|                         }
 | |
| 
 | |
|                     } else {
 | |
|                         log.info("[处方][定时器]检测到需手动退费订单 outTradeNo={}, tradeNo={}", outTradeNo, tradeNo);
 | |
|                     }
 | |
|                     try {
 | |
|                         Thread.sleep(500);
 | |
|                     } catch (Exception e) {
 | |
|                         e.printStackTrace();
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 if (size == 0) { // 数据处理完成,清除定时器
 | |
|                     TimerManager.closeTimer(RECIPE_TIMER);
 | |
|                     RECIPE_TIMER = null;
 | |
|                 }
 | |
|             }
 | |
|         }, 120);
 | |
|     }
 | |
| 
 | |
| }
 | |
| 
 |