|
|
@@ -0,0 +1,90 @@
|
|
|
+package com.gree.mall.miniapp.logic.user;
|
|
|
+
|
|
|
+import cn.hutool.core.date.DateUtil;
|
|
|
+import com.gree.mall.miniapp.commonmapper.LockQueryMapper;
|
|
|
+import com.gree.mall.miniapp.constant.Constant;
|
|
|
+import com.gree.mall.miniapp.exception.RemoteServiceException;
|
|
|
+import com.gree.mall.miniapp.helper.ResponseHelper;
|
|
|
+import com.gree.mall.miniapp.plus.entity.OrderInfo;
|
|
|
+import com.gree.mall.miniapp.plus.entity.User;
|
|
|
+import com.gree.mall.miniapp.plus.entity.UserCompanyCredit;
|
|
|
+import com.gree.mall.miniapp.plus.service.UserCompanyCreditService;
|
|
|
+import lombok.RequiredArgsConstructor;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.integration.redis.util.RedisLockRegistry;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.support.TransactionSynchronization;
|
|
|
+import org.springframework.transaction.support.TransactionSynchronizationManager;
|
|
|
+
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.util.Arrays;
|
|
|
+import java.util.Objects;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
+import java.util.concurrent.locks.Lock;
|
|
|
+
|
|
|
+@Service
|
|
|
+@Slf4j
|
|
|
+@RequiredArgsConstructor
|
|
|
+public class UserCompanyCreditLogic {
|
|
|
+
|
|
|
+ private final RedisLockRegistry redisLockRegistry;
|
|
|
+ private final UserCompanyCreditService userCompanyCreditService;
|
|
|
+ private final LockQueryMapper lockQueryMapper;
|
|
|
+
|
|
|
+ public void createCreditRecord(OrderInfo orderInfo, User user) throws Exception {
|
|
|
+ if(!TransactionSynchronizationManager.isSynchronizationActive()) {
|
|
|
+ throw new RemoteServiceException("请先开启事务");
|
|
|
+ }
|
|
|
+ Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.LOCK_CREDIT_ORDER + user.getUserId());
|
|
|
+ if(!obtain.tryLock(10, TimeUnit.SECONDS)){
|
|
|
+ throw new RemoteServiceException("订单创建过于频繁, 请稍后再试");
|
|
|
+ }
|
|
|
+ // 处理授信
|
|
|
+ try{
|
|
|
+ final BigDecimal payAmount = orderInfo.getPayAmount();
|
|
|
+ final UserCompanyCredit userCompanyCredit = lockQueryMapper.queryExistUserCompanyCredit(orderInfo.getCompanyWechatId(), orderInfo.getUserId());
|
|
|
+ if (Objects.isNull(userCompanyCredit)) {
|
|
|
+ throw new RemoteServiceException("用户在该商户下无授信关系");
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!userCompanyCredit.getIsCreditEnabled()) {
|
|
|
+ throw new RemoteServiceException("用户在该商户下的授信未启用");
|
|
|
+ }
|
|
|
+
|
|
|
+ if (userCompanyCredit.getAvailableCredit().compareTo(payAmount) < 0) {
|
|
|
+ throw new RemoteServiceException("商户授信额度不足");
|
|
|
+ }
|
|
|
+
|
|
|
+ userCompanyCreditService.lambdaUpdate()
|
|
|
+ .set(UserCompanyCredit::getAvailableCredit, userCompanyCredit.getAvailableCredit().subtract(payAmount))
|
|
|
+ .set(UserCompanyCredit::getUpdateTime, DateUtil.date())
|
|
|
+ .eq(UserCompanyCredit::getId, userCompanyCredit.getId())
|
|
|
+ .update();
|
|
|
+
|
|
|
+ } finally {
|
|
|
+ this.txCallUnlock(obtain);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void txCallUnlock(Lock obtain) {
|
|
|
+ //事务提交完成后才释放锁,此方法禁止执行mysql相关操作,否则将导致重大问题。
|
|
|
+ if (TransactionSynchronizationManager.isActualTransactionActive()) {
|
|
|
+ TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
|
|
|
+ @Override
|
|
|
+ public void afterCompletion(int status) {
|
|
|
+
|
|
|
+ if(TransactionSynchronization.STATUS_COMMITTED == status){
|
|
|
+ log.info("=========【授信支付】======事务提交==============");
|
|
|
+ }else if(TransactionSynchronization.STATUS_ROLLED_BACK == status){
|
|
|
+ log.info("========【授信支付】=========事务回滚============");
|
|
|
+ }
|
|
|
+
|
|
|
+ obtain.unlock();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ log.info("【授信支付】====没有事务===释放锁");
|
|
|
+ obtain.unlock();
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|