微信后端代码
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

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);
}
}