cloudroam
2024-11-08 52081904dc467b81db0b28ff7cfed5979f14d1d2
src/main/java/com/mzl/flower/service/impl/wallet/WalletServiceImpl.java
@@ -1,13 +1,31 @@
package com.mzl.flower.service.impl.wallet;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.mzl.flower.entity.coupon.CouponTemplateDO;
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.supplier.Supplier;
import com.mzl.flower.entity.wallet.WalletDO;
import com.mzl.flower.enums.TrueOrFalseEnum;
import com.mzl.flower.mapper.wallet.WalletMapper;
import com.mzl.flower.service.supplier.SupplierService;
import com.mzl.flower.service.wallet.WalletReduceService;
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;
import org.springframework.util.StringUtils;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
/**
 * <p>
@@ -20,16 +38,166 @@
@Service
public class WalletServiceImpl extends ServiceImpl<WalletMapper, WalletDO> implements WalletService {
    @Autowired
    private SupplierService supplierService;
    @Autowired
    private WalletReduceService walletReduceService;
    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() {
        String walletOnlineTime =baseMapper.selectWalletOnlineTime();
        // 这里需要判断walletOnlineTime是不是一个正确的yyyy-mm-dd hh24:mi:ss的时间
        String startTime;
        if (isValidDateTime(walletOnlineTime)) {
            startTime = walletOnlineTime;
        } else {
            // 如果 walletOnlineTime 无效,则使用当前时间的字符串
            startTime = getCurrentDateTime();
        }
        return startTime;
    }
    @Override
    public WalletDO getCurrentSupplier() {
        final SupplierDTO currentSupplier = supplierService.getCurrentSupplier();
        // 根据供应商ID获取钱包信息
            // 查询的条件的deleted的字段得为0
            // 下面的单独封装成一个方法
            WalletDO walletDO = getOrCreateBySupplierId(currentSupplier.getId());
        return walletDO;
    }
    @Override
    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;
                        final Supplier supplier = supplierService.getSupplierById(supplierId);
                        // 创建一个钱包
                        walletDO =new WalletDO();
                        walletDO.setUserId(supplier.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.setSettledAmount(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) {
        // 根据供应商ID获取钱包信息
        if (supplierId != null) {
            // 查询的条件的deleted的字段得为0
            return getOne(new LambdaQueryWrapper<WalletDO>()
                    .eq(WalletDO::getDeleted, TrueOrFalseEnum.FALSE.isFlag())
                    .eq(WalletDO::getSupplierId, 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);
        }
        return null;
    }
    @Override
    public BigDecimal getWaittingSettlementAmount(WalletDO walletDO) {
        if(null!=walletDO && !StringUtils.isEmpty(walletDO.getSupplierId()) && StringUtils.isEmpty(walletDO.getUserId())){
            final Supplier supplier = supplierService.getSupplierById(walletDO.getSupplierId());
            walletDO.setUserId(supplier.getUserId());
        }
        return baseMapper.getWaittingSettlementAmount(walletDO);
    }
    @Override
    public BigDecimal getSupplierTotalTransactionAmount(WalletDO walletDO) {
        QueryWalletAmountDTO queryWalletAmountDTO=new QueryWalletAmountDTO();
        queryWalletAmountDTO.setSupplierId(walletDO.getSupplierId());
        queryWalletAmountDTO.setStartTime(getWalletOnLineTime());
        queryWalletAmountDTO.setUserId(walletDO.getUserId());
        BigDecimal totalTransactionAmount=baseMapper.getSupplierTotalTransactionAmount(queryWalletAmountDTO);
        return totalTransactionAmount;
    }
    @Override
    public BigDecimal getSupplierDeductAmount(WalletDO walletDO) {
        QueryWalletAmountDTO queryWalletAmountDTO=new QueryWalletAmountDTO();
        queryWalletAmountDTO.setSupplierId(walletDO.getSupplierId());
        queryWalletAmountDTO.setStartTime(getWalletOnLineTime());
        queryWalletAmountDTO.setUserId(walletDO.getUserId());
        // 质检扣款
        BigDecimal checkDeduceAmount = walletReduceService.getCheckReduceAmount(queryWalletAmountDTO);
        checkDeduceAmount = checkDeduceAmount != null ? checkDeduceAmount : BigDecimal.ZERO;
        // 售后扣款
        BigDecimal saleDeduceAmount = walletReduceService.getSaleReduceAmount(queryWalletAmountDTO);
        saleDeduceAmount = saleDeduceAmount != null ? saleDeduceAmount : BigDecimal.ZERO;
        // 集货站运费
        BigDecimal stationFeeAmount = walletReduceService.getStationFeeAmount(queryWalletAmountDTO);
        stationFeeAmount = stationFeeAmount != null ? stationFeeAmount : BigDecimal.ZERO;
        // 总扣款
        BigDecimal deduceAmount = checkDeduceAmount.add(saleDeduceAmount).add(stationFeeAmount);
        return deduceAmount;
    }
    public static boolean isValidDateTime(String dateTime) {
        if (dateTime == null || !dateTimeRegex.matcher(dateTime).matches()) {
            return false;
        }
        SimpleDateFormat sdf = new SimpleDateFormat(DATE_TIME_PATTERN);
        sdf.setLenient(false);
        try {
            sdf.parse(dateTime);
            return true;
        } catch (Exception e) {
            return false;
        }
    }
    public static String getCurrentDateTime() {
        SimpleDateFormat sdf = new SimpleDateFormat(DATE_TIME_PATTERN);
        return sdf.format(new Date());
    }
}