package com.mzl.flower.service.impl.wallet;
|
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.mzl.flower.config.exception.ValidationException;
|
import com.mzl.flower.config.security.SecurityUtils;
|
import com.mzl.flower.constant.Constants;
|
import com.mzl.flower.constant.LockConstants;
|
import com.mzl.flower.dto.request.wallet.CreateWalletWithdrawRecordDTO;
|
import com.mzl.flower.dto.request.wallet.QueryWalletWithdrawDTO;
|
import com.mzl.flower.dto.request.wallet.WalletWithdrawRecordDTO;
|
import com.mzl.flower.dto.response.supplier.SupplierDTO;
|
import com.mzl.flower.dto.response.wallet.WalletWithdrawRecordVO;
|
import com.mzl.flower.entity.wallet.WalletDO;
|
import com.mzl.flower.entity.wallet.WalletWithdrawRecordDO;
|
import com.mzl.flower.mapper.wallet.WalletWithdrawRecordMapper;
|
import com.mzl.flower.service.supplier.SupplierService;
|
import com.mzl.flower.service.wallet.WalletBillRecordService;
|
import com.mzl.flower.service.wallet.WalletService;
|
import com.mzl.flower.service.wallet.WalletWithdrawRecordService;
|
import lombok.RequiredArgsConstructor;
|
import org.redisson.api.RLock;
|
import org.redisson.api.RedissonClient;
|
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.util.StringUtils;
|
|
import java.time.LocalDateTime;
|
import java.util.List;
|
import java.util.concurrent.TimeUnit;
|
|
/**
|
* <p>
|
* 服务实现类
|
* </p>
|
*
|
* @author @TaoJie
|
* @since 2024-10-22
|
*/
|
@Service
|
@Transactional
|
@RequiredArgsConstructor
|
public class WalletWithdrawRecordServiceImpl extends ServiceImpl<WalletWithdrawRecordMapper, WalletWithdrawRecordDO> implements WalletWithdrawRecordService {
|
|
private final WalletWithdrawRecordMapper walletWithdrawRecordMapper;
|
private final WalletService walletService;
|
private final SupplierService supplierService;
|
|
private final WalletBillRecordService walletBillRecordService;
|
|
|
@Autowired
|
RedissonClient redissonClient;
|
|
@Transactional
|
@Override
|
public boolean create(CreateWalletWithdrawRecordDTO dto) {
|
|
SupplierDTO supplierDTO = supplierService.getCurrentSupplier();
|
if (null == supplierDTO) {
|
throw new ValidationException("供应商不能为空");
|
}
|
|
WalletDO walletDO = walletService.getCurrentSupplier();
|
if (null == walletDO) {
|
throw new ValidationException("钱包不能为空");
|
}
|
// 查看钱包的金额是不是大于要提现的金额
|
if (null != walletDO.getWithdrawableAmount() && null != dto.getAmount() && walletDO.getWithdrawableAmount().compareTo(dto.getAmount()) < 0) {
|
throw new ValidationException("钱包金额不足");
|
}
|
|
RLock lock = redissonClient.getLock(String.format(LockConstants.WALLET_ID_KEY, walletDO.getId()));
|
// 获取锁,最多等待 10 秒,锁自动释放时间 30 秒
|
try {
|
if (lock.tryLock(10, 30, TimeUnit.SECONDS)) {
|
try {
|
|
// 加锁了之后需要二次查询,防止未加锁之前 someone else 已经修改了
|
walletDO = walletService.getCurrentSupplier();
|
if (null == walletDO) {
|
throw new ValidationException("钱包不能为空");
|
}
|
// 查看钱包的金额是不是大于要提现的金额
|
if (null != walletDO.getWithdrawableAmount() && null != dto.getAmount() && walletDO.getWithdrawableAmount().compareTo(dto.getAmount()) < 0) {
|
throw new ValidationException("钱包金额不足");
|
}
|
|
// 1.新增一条余额提现记录
|
WalletWithdrawRecordDO withdrawRecordDO = new WalletWithdrawRecordDO();
|
withdrawRecordDO.setAmount(dto.getAmount());
|
withdrawRecordDO.setSupplierId(supplierDTO.getId());
|
withdrawRecordDO.setWithdrawState(Constants.WALLET_WITHDRAW_STATE.WAITING.name());
|
withdrawRecordDO.setMethod(Constants.WALLET_WITHDRAW_METHOD.WEIXIN.name());
|
withdrawRecordDO.create(SecurityUtils.getUserId());
|
// 保存余额提现记录
|
save(withdrawRecordDO);
|
|
/*
|
// 2.新增一条账单明细
|
WalletBillRecordDO walletBillRecordDO=new WalletBillRecordDO();
|
walletBillRecordDO.setSupplierId(supplierDTO.getId());
|
walletBillRecordDO.setWalletId(walletDO.getId());
|
// 提现
|
walletBillRecordDO.setType(Constants.BILL_CHANGE_TYPE.withdraw.name());
|
walletBillRecordDO.setMethod(Constants.BILL_CHANGE_METHOD.add.name());
|
walletBillRecordDO.setOriginalAmount(walletDO.getWithdrawableAmount());
|
walletBillRecordDO.setChangeAmount(dto.getAmount());
|
walletBillRecordDO.setBalance(walletDO.getWithdrawableAmount().subtract(dto.getAmount()));
|
|
// 保存账单明细
|
walletBillRecordService.save(walletBillRecordDO);
|
*/
|
|
// 3. 钱包更新
|
// 钱包可提现的钱等于当前钱包可提现的钱-提现的钱
|
walletDO.setWithdrawableAmount(walletDO.getWithdrawableAmount().subtract(dto.getAmount()));
|
// 提现中的钱等于原有可提现的钱+提现的钱
|
walletDO.setWithdrawingAmount(walletDO.getWithdrawingAmount().add(dto.getAmount()));
|
walletDO.update(SecurityUtils.getUserId());
|
|
// 更新钱包
|
return walletService.updateById(walletDO);
|
|
} finally {
|
lock.unlock();
|
}
|
}
|
} catch (InterruptedException e) {
|
throw new RuntimeException(e);
|
}
|
|
return false;
|
}
|
|
@Override
|
public Page<WalletWithdrawRecordVO> queryPage(QueryWalletWithdrawDTO queryWalletDTO, Page page) {
|
List<WalletWithdrawRecordVO> list = walletWithdrawRecordMapper.queryPage(queryWalletDTO, page);
|
page.setRecords(list);
|
return page;
|
}
|
|
@Override
|
public void updateWallet(WalletWithdrawRecordDTO walletWithdrawRecordDTO) {
|
WalletWithdrawRecordDO withdrawRecordDO = walletWithdrawRecordMapper.selectById(walletWithdrawRecordDTO.getId());
|
if (withdrawRecordDO == null) {
|
throw new ValidationException("提现记录信息不存在");
|
}
|
if (StringUtils.isEmpty(walletWithdrawRecordDTO.getApproveState())) {
|
throw new ValidationException("审批状态不能为空");
|
}
|
BeanUtils.copyProperties(walletWithdrawRecordDTO, withdrawRecordDO);
|
withdrawRecordDO.update(SecurityUtils.getUserId());
|
withdrawRecordDO.setApproveBy(SecurityUtils.getUserId());
|
withdrawRecordDO.setApproveTime(LocalDateTime.now());
|
walletWithdrawRecordMapper.updateById(withdrawRecordDO);
|
}
|
|
}
|