package com.webchat.ugc.service; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import com.webchat.common.bean.APIResponseBean; import com.webchat.common.bean.APIResponseBeanUtil; import com.webchat.common.enums.RedisKeyEnum; import com.webchat.common.exception.BusinessException; import com.webchat.common.service.RedisService; import com.webchat.common.util.JsonUtil; import com.webchat.common.util.SignUtil; import com.webchat.rmi.pay.PaymentApiServiceClient; import com.webchat.ugc.config.PaymentAppConfig; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.Date; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantLock; @Slf4j @Service public class PaymentService { @Autowired private PaymentApiServiceClient paymentApiServiceClient; @Autowired private PaymentAppConfig paymentAppConfig; @Autowired private RedisService redisService; private ReentrantLock lock = new ReentrantLock(); public String token() { String key = this.getTokenCacheKey(); String cache = redisService.get(key); if (StringUtils.isNotBlank(cache)) { return cache; } String token; try { lock.lock(); // 双重检查锁 token = redisService.get(key); if (StringUtils.isNotBlank(token)) { return token; } token = refreshAccessTokenCache(); } catch (Exception e) { throw new BusinessException("支付Token请求失败!"); } finally { if (lock.isHeldByCurrentThread()) { lock.unlock(); } } return token; } /** * 刷新token redis缓存 * * @return */ private String refreshAccessTokenCache() { String token = this.getTokenByClient(); String key = this.getTokenCacheKey(); redisService.set(key, token, RedisKeyEnum.PAYMENT_ACCESS_TOKEN_CACHE.getExpireTime()); return token; } /** * 获取Token redis缓存 * @return */ private String getTokenCacheKey() { return RedisKeyEnum.PAYMENT_ACCESS_TOKEN_CACHE.getKey(); } /** * 获取token * * @return */ public String getTokenByClient() { String logId = generateLogId(); // 13位时间戳 Long timestamp = System.currentTimeMillis(); // 计算签名(5分钟内有效期) // SHA256(sk, "appId - accessKey - timestamp") String signature = SignUtil.generateSignature(paymentAppConfig.getSecretKey(), String.valueOf(paymentAppConfig.getAppId()), paymentAppConfig.getAccessKey(), String.valueOf(timestamp)); APIResponseBean responseBean = paymentApiServiceClient.accessToken(paymentAppConfig.getAppId(), paymentAppConfig.getAccessKey(), paymentAppConfig.getSecretKey(), timestamp, signature, logId); if (APIResponseBeanUtil.isOk(responseBean)) { return responseBean.getData(); } log.error("UGC 支付服务异常 =====> 获取Token异常!logId:{}, responseBean:{}", logId, JsonUtil.toJsonString(responseBean)); throw new BusinessException("支付Token请求失败!"); } public String transId() { String accessToken = token(); String logId = generateLogId(); APIResponseBean responseBean = paymentApiServiceClient.transId(accessToken, logId); if (APIResponseBeanUtil.isOk(responseBean)) { return responseBean.getData(); } log.error("UGC 支付服务异常 =====> 获取TransId异常!logId:{}, responseBean:{}", logId, JsonUtil.toJsonString(responseBean)); throw new BusinessException("支付TransId请求失败!"); } private String generateLogId() { // TODO 预留: // 支持雪花算法ID生成 return null; } }