From 66f57ebef36c03353609ad3b2b6623396b5061a4 Mon Sep 17 00:00:00 2001
From: 陶杰 <1378534974@qq.com>
Date: 星期一, 28 十月 2024 15:06:54 +0800
Subject: [PATCH] 1.供应商-钱包创建并发控制

---
 src/main/java/com/mzl/flower/constant/LockConstants.java                              |    4 +
 src/main/java/com/mzl/flower/service/impl/wallet/WalletServiceImpl.java               |   78 ++++++++++++++++++++++++++-------------
 src/main/java/com/mzl/flower/service/impl/wallet/WalletWithdrawRecordServiceImpl.java |    2 
 src/main/java/com/mzl/flower/service/wallet/WalletService.java                        |   20 ++++++++++
 src/main/java/com/mzl/flower/service/impl/wallet/WalletBillRecordServiceImpl.java     |    5 +-
 5 files changed, 78 insertions(+), 31 deletions(-)

diff --git a/src/main/java/com/mzl/flower/constant/LockConstants.java b/src/main/java/com/mzl/flower/constant/LockConstants.java
index d8f300c..d1dbbeb 100644
--- a/src/main/java/com/mzl/flower/constant/LockConstants.java
+++ b/src/main/java/com/mzl/flower/constant/LockConstants.java
@@ -3,6 +3,8 @@
 public class LockConstants {
 
     // 钱包ID锁
-    public static final String WALLET_ID_KEY = "WALLET_ID_KEY:%s";
+    public static final String WALLET_ID_KEY = "com:mzl:flower:constant:WALLET_ID_KEY:%s";
+
+    public static final String WALLET_SUPPLIER_ID_KEY = "com:mzl:flower:constant:WALLET_SUPPLIER_ID_KEY:%s";
 
 }
diff --git a/src/main/java/com/mzl/flower/service/impl/wallet/WalletBillRecordServiceImpl.java b/src/main/java/com/mzl/flower/service/impl/wallet/WalletBillRecordServiceImpl.java
index 3e6196a..557116d 100644
--- a/src/main/java/com/mzl/flower/service/impl/wallet/WalletBillRecordServiceImpl.java
+++ b/src/main/java/com/mzl/flower/service/impl/wallet/WalletBillRecordServiceImpl.java
@@ -6,7 +6,6 @@
 import com.mzl.flower.dto.request.wallet.CreateWalletBillRecordDTO;
 import com.mzl.flower.dto.request.wallet.QueryWalletBillDTO;
 import com.mzl.flower.dto.response.wallet.WalletBillRecordVO;
-import com.mzl.flower.dto.response.wallet.WalletWithdrawRecordVO;
 import com.mzl.flower.entity.payment.Transfer;
 import com.mzl.flower.entity.payment.TransferDetail;
 import com.mzl.flower.entity.wallet.WalletBillRecordDO;
@@ -80,7 +79,7 @@
                 walletBillRecordDO.update("sys");
                 walletBillRecordMapper.updateById(walletBillRecordDO);
                 //更新钱包
-                WalletDO walletDO = walletService.getBySupplierId(walletBillRecordDO.getWalletId());
+                WalletDO walletDO = walletService.getOrCreateBySupplierId(walletBillRecordDO.getWalletId());
                 if(!ObjectUtils.isEmpty(walletDO)){
                     //提现中金额:减少提现中金额
                     walletDO.setWithdrawingAmount(walletDO.getWithdrawingAmount().subtract(walletBillRecordDO.getChangeAmount()));
@@ -99,7 +98,7 @@
                 walletBillRecordDO.setTransferState(Constants.SETTLEMENT_STATUS.FAILED.name());
                 walletBillRecordDO.update("sys");
                 walletBillRecordMapper.updateById(walletBillRecordDO);
-                WalletDO walletDO = walletService.getBySupplierId(walletBillRecordDO.getWalletId());
+                WalletDO walletDO = walletService.getOrCreateBySupplierId(walletBillRecordDO.getWalletId());
                 if(!ObjectUtils.isEmpty(walletDO)){
                     //提现中金额:减少提现中金额
                     walletDO.setWithdrawingAmount(walletDO.getWithdrawingAmount().subtract(walletBillRecordDO.getChangeAmount()));
diff --git a/src/main/java/com/mzl/flower/service/impl/wallet/WalletServiceImpl.java b/src/main/java/com/mzl/flower/service/impl/wallet/WalletServiceImpl.java
index 2f44539..45291a2 100644
--- a/src/main/java/com/mzl/flower/service/impl/wallet/WalletServiceImpl.java
+++ b/src/main/java/com/mzl/flower/service/impl/wallet/WalletServiceImpl.java
@@ -2,9 +2,9 @@
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.mzl.flower.config.security.SecurityUtils;
+import com.mzl.flower.constant.LockConstants;
 import com.mzl.flower.dto.request.wallet.QueryWalletAmountDTO;
 import com.mzl.flower.dto.response.supplier.SupplierDTO;
-import com.mzl.flower.entity.coupon.CouponTemplateDO;
 import com.mzl.flower.entity.wallet.WalletDO;
 import com.mzl.flower.enums.TrueOrFalseEnum;
 import com.mzl.flower.mapper.wallet.WalletMapper;
@@ -13,6 +13,8 @@
 import com.mzl.flower.service.wallet.WalletService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import org.apache.commons.collections4.CollectionUtils;
+import org.redisson.api.RLock;
+import org.redisson.api.RedissonClient;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -20,6 +22,7 @@
 import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.List;
+import java.util.concurrent.TimeUnit;
 import java.util.regex.Pattern;
 
 /**
@@ -42,6 +45,8 @@
     private static final String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
     private static final Pattern dateTimeRegex = Pattern.compile("^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$");
 
+    @Autowired
+    RedissonClient redissonClient;
 
     @Override
     public String getWalletOnLineTime() {
@@ -64,42 +69,63 @@
 
             // 查询的条件的deleted的字段得为0
             // 下面的单独封装成一个方法
-            WalletDO walletDO = getBySupplierId(currentSupplier.getId());
-
-            if(null==walletDO){
-                // 先创建一个钱包
-                walletDO=new WalletDO();
-                walletDO.setUserId(SecurityUtils.getUserId());
-                walletDO.setSupplierId(currentSupplier.getId());
-                walletDO.setTotalAmount(BigDecimal.ZERO);
-                walletDO.setWithdrawableAmount(BigDecimal.ZERO);
-                //把所有涉及BigDecimal的金额都设置为0
-                walletDO.setWithdrawingAmount(BigDecimal.ZERO);
-                walletDO.setWithdrawnAmount(BigDecimal.ZERO);
-                walletDO.setSettlingAmount(BigDecimal.ZERO);
-                walletDO.setTotalDeduction(BigDecimal.ZERO);
-                walletDO.setTotalTransactionAmount(BigDecimal.ZERO);
-                walletDO.setSettlingAmount(BigDecimal.ZERO);
-                walletDO.create(SecurityUtils.getUserId());
-                baseMapper.insert(walletDO);
-                // 将再次查询的结果返回
-                walletDO=getBySupplierId(currentSupplier.getId());
-            }
-
+            WalletDO walletDO = getOrCreateBySupplierId(currentSupplier.getId());
 
         return walletDO;
     }
 
     @Override
-    public WalletDO getBySupplierId(Long supplierId) {
-        // 不用getOne,用获取list的第一个元素
+    public WalletDO getOrCreateBySupplierId(Long supplierId) {
+        WalletDO walletDO=getBySupplierId(supplierId);
+        if(null==walletDO){
+            RLock lock = redissonClient.getLock(String.format(LockConstants.WALLET_SUPPLIER_ID_KEY, supplierId));
+            try {
+                if (lock.tryLock(10, 30, TimeUnit.SECONDS)) {
+                    try {
+                        walletDO=getBySupplierId(supplierId);
+                        if(null!=walletDO) return walletDO;
+                        // 创建一个钱包
+                        walletDO =new WalletDO();
+                        walletDO.setUserId(SecurityUtils.getUserId());
+                        walletDO.setSupplierId(supplierId);
+                        walletDO.setTotalAmount(BigDecimal.ZERO);
+                        walletDO.setWithdrawableAmount(BigDecimal.ZERO);
+                        //把所有涉及BigDecimal的金额都设置为0
+                        walletDO.setWithdrawingAmount(BigDecimal.ZERO);
+                        walletDO.setWithdrawnAmount(BigDecimal.ZERO);
+                        walletDO.setSettlingAmount(BigDecimal.ZERO);
+                        walletDO.setTotalDeduction(BigDecimal.ZERO);
+                        walletDO.setTotalTransactionAmount(BigDecimal.ZERO);
+                        walletDO.setSettlingAmount(BigDecimal.ZERO);
+                        walletDO.create(SecurityUtils.getUserId());
+                        baseMapper.insert(walletDO);
+                        // 将再次查询的结果返回
+                        walletDO= getBySupplierId(supplierId);
+                        return walletDO;
 
+                    } finally {
+                        lock.unlock();
+                    }
+                }
+            } catch (InterruptedException e) {
+                throw new RuntimeException(e);
+            }
+
+            return null;
+        }else{
+            return walletDO;
+        }
+    }
+
+    @Override
+    public WalletDO getBySupplierId(Long supplierId) {
         List<WalletDO> walletDOS = baseMapper.selectList(new LambdaQueryWrapper<WalletDO>()
                 .eq(WalletDO::getDeleted, TrueOrFalseEnum.FALSE.isFlag())
                 .eq(WalletDO::getSupplierId, supplierId));
         if(!CollectionUtils.isEmpty(walletDOS)){
             return walletDOS.get(0);
-        }else return null;
+        }
+        return null;
     }
 
     @Override
diff --git a/src/main/java/com/mzl/flower/service/impl/wallet/WalletWithdrawRecordServiceImpl.java b/src/main/java/com/mzl/flower/service/impl/wallet/WalletWithdrawRecordServiceImpl.java
index 4001c52..71a4ed5 100644
--- a/src/main/java/com/mzl/flower/service/impl/wallet/WalletWithdrawRecordServiceImpl.java
+++ b/src/main/java/com/mzl/flower/service/impl/wallet/WalletWithdrawRecordServiceImpl.java
@@ -252,7 +252,7 @@
         if (Constants.WALLET_APPROVE_STATE.REJECT.name().equals(walletWithdrawRecordDTO.getApproveState())) {
             //更新钱包
             Supplier s = supplierMapper.selectById(withdrawRecordDO.getSupplierId());
-            WalletDO walletDO = walletService.getBySupplierId(s.getId());
+            WalletDO walletDO = walletService.getOrCreateBySupplierId(s.getId());
             if(!ObjectUtils.isEmpty(walletDO)){
                 //提现中金额:审核失败体现中金额扣减
                 walletDO.setWithdrawingAmount(walletDO.getWithdrawingAmount().subtract(withdrawRecordDO.getAmount()));
diff --git a/src/main/java/com/mzl/flower/service/wallet/WalletService.java b/src/main/java/com/mzl/flower/service/wallet/WalletService.java
index ce72bf9..79716d3 100644
--- a/src/main/java/com/mzl/flower/service/wallet/WalletService.java
+++ b/src/main/java/com/mzl/flower/service/wallet/WalletService.java
@@ -15,11 +15,31 @@
  */
 public interface WalletService extends IService<WalletDO> {
 
+    /**
+     * 获取钱包的上线时间
+     * @return
+     */
     String getWalletOnLineTime();
 
+    /**
+     * 获取当前登录供应商的钱包信息
+     * @return 钱包信息
+     */
     WalletDO getCurrentSupplier();
 
+    /**
+     * 先尝试获取,如果不存在则创建。
+     * @param supplierId 供应商ID
+     * @return 钱包信息
+     */
+    WalletDO getOrCreateBySupplierId(Long supplierId);
 
+
+    /**
+     * 根据供应商的ID获取钱包信息
+     * @param supplierId 供应商ID
+     * @return 钱包信息
+     */
     WalletDO getBySupplierId(Long supplierId);
 
     BigDecimal getWaittingSettlementAmount(WalletDO walletDO);

--
Gitblit v1.9.3