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.findEnumByOutTradeNo(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);
|
|
}
|
|
|
|
}
|
|
|