| 
					
				 | 
			
			
				@@ -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(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 |