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.
		
		
		
		
			
				
					154 lines
				
				5.9 KiB
			
		
		
			
		
	
	
					154 lines
				
				5.9 KiB
			| 
											3 years ago
										 | 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);
 | ||
|  |     }
 | ||
|  | 
 | ||
|  | }
 |