package cc.mrbird.febs.mall.service.impl; import cc.mrbird.febs.common.enumerates.DataDictionaryEnum; import cc.mrbird.febs.common.enumerates.FlowTypeEnum; import cc.mrbird.febs.common.enumerates.MoneyFlowTypeEnum; import cc.mrbird.febs.common.enumerates.PerkEnum; import cc.mrbird.febs.common.exception.FebsException; import cc.mrbird.febs.common.utils.AppContants; import cc.mrbird.febs.common.utils.LoginUserUtil; import cc.mrbird.febs.common.utils.MallUtils; import cc.mrbird.febs.mall.dto.WithdrawalDto; import cc.mrbird.febs.mall.dto.WithdrawalScoreDto; import cc.mrbird.febs.mall.entity.*; import cc.mrbird.febs.mall.mapper.*; import cc.mrbird.febs.mall.service.IApiMallMemberService; import cc.mrbird.febs.mall.service.IApiMallMemberWalletService; import cc.mrbird.febs.mall.service.IMallMemberWithdrawService; import cc.mrbird.febs.mall.service.MallMemberService; import cc.mrbird.febs.mall.vo.CashOutSettingVo; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.crypto.SecureUtil; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; /** * @author wzy * @date 2022-05-05 **/ @Slf4j @Service @RequiredArgsConstructor public class MallMemberWithdrawServiceImpl extends ServiceImpl implements IMallMemberWithdrawService { private final IApiMallMemberService mallMemberService; private final MallMoneyFlowMapper mallMoneyFlowMapper; private final MallMemberWalletMapper mallMemberWalletMapper; private final IApiMallMemberWalletService walletService; private final MallMemberPaymentMapper mallMemberPaymentMapper; private final DataDictionaryCustomMapper dataDictionaryCustomMapper; private final MallMemberBankMapper mallMemberBankMapper; @Override @Transactional(rollbackFor = Exception.class) public void withdrawal(WithdrawalDto withdrawalDto) { Long memberId = LoginUserUtil.getLoginUser().getId(); MallMember mallMember = mallMemberService.getById(memberId); if (StrUtil.isBlank(mallMember.getTradePassword())) { throw new FebsException("未设置支付密码"); } if (!mallMember.getTradePassword().equals(SecureUtil.md5(withdrawalDto.getTradePwd()))) { throw new FebsException("支付密码错误"); } CashOutSettingVo cashOutSettingVo = new CashOutSettingVo(); DataDictionaryCustom dic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(DataDictionaryEnum.CASHOUT_SETTING.getType(), DataDictionaryEnum.CASHOUT_SETTING.getCode()); if (dic != null) { cashOutSettingVo = JSONObject.parseObject(dic.getValue(), CashOutSettingVo.class); } if (withdrawalDto.getAmount().compareTo(cashOutSettingVo.getMinCashOut()) < 0) { throw new FebsException("最小提现金额为"+cashOutSettingVo.getMinCashOut().setScale(2,BigDecimal.ROUND_DOWN)); } MallMemberBank mallMemberBank = mallMemberBankMapper.selectById(withdrawalDto.getBankId()); if(ObjectUtil.isEmpty(mallMemberBank)){ throw new FebsException("未找到银行卡信息"); } MallMemberWallet wallet = mallMemberWalletMapper.selectWalletByMemberId(memberId); if(wallet.getBalance().compareTo(BigDecimal.ZERO) <= 0){ throw new FebsException("金额不足"); } if(withdrawalDto.getAmount().compareTo(wallet.getBalance()) > 0) { throw new FebsException("金额不足"); } BigDecimal commission = wallet.getCommission(); if(withdrawalDto.getAmount().compareTo(commission) > 0){ throw new FebsException("金额不足"); } BigDecimal serviceFee = cashOutSettingVo.getServiceFee().multiply(BigDecimal.valueOf(0.01)); walletService.reduce(withdrawalDto.getAmount(), memberId, "balance"); walletService.reduce(withdrawalDto.getAmount(), memberId, "commission"); String orderNo = MallUtils.getOrderNum("W"); MallMemberWithdraw withdraw = new MallMemberWithdraw(); withdraw.setWithdrawNo(orderNo); withdraw.setMemberId(memberId); withdraw.setAmount(withdrawalDto.getAmount()); withdraw.setStatus(1); withdraw.setAmountFee(serviceFee.multiply(withdrawalDto.getAmount())); withdraw.setWtihdrawTypeId(mallMemberBank.getId()); withdraw.setType(1); this.baseMapper.insert(withdraw); mallMemberService.addMoneyFlow(memberId, withdrawalDto.getAmount().negate(), MoneyFlowTypeEnum.WITHDRAWAL.getValue(), orderNo, null, null, null, 1, FlowTypeEnum.BALANCE.getValue()); } @Override public void withdrawalScore(WithdrawalScoreDto withdrawalScoreDto) { Long memberId = LoginUserUtil.getLoginUser().getId(); MallMember mallMember = mallMemberService.getById(memberId); if (StrUtil.isBlank(mallMember.getTradePassword())) { throw new FebsException("未设置支付密码"); } if (!mallMember.getTradePassword().equals(SecureUtil.md5(withdrawalScoreDto.getTradePwd()))) { throw new FebsException("支付密码错误"); } DataDictionaryCustom poolScorePriceDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(PerkEnum.POOL_SCORE_PRICE.getType(), PerkEnum.POOL_SCORE_PRICE.getCode()); //积分价格 BigDecimal poolScorePrice = new BigDecimal(poolScorePriceDic.getValue()); DataDictionaryCustom withDrawScoreCashPercentDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(PerkEnum.WITHDRAW_SCORE_CASH_PERCENT.getType(), PerkEnum.WITHDRAW_SCORE_CASH_PERCENT.getCode()); //提现的30%金额回流到积分池现金 BigDecimal withDrawScoreCashPercent = new BigDecimal(withDrawScoreCashPercentDic.getValue()).multiply(AppContants.PERCENTAGE); MallMemberWallet wallet = mallMemberWalletMapper.selectWalletByMemberId(memberId); if(wallet.getScore().compareTo(BigDecimal.ZERO) <= 0){ throw new FebsException("积分不足"); } if(withdrawalScoreDto.getAmount().compareTo(wallet.getScore()) > 0) { throw new FebsException("积分不足"); } //积分减少 walletService.reduce(withdrawalScoreDto.getAmount(), memberId, "score"); String orderNo = MallUtils.getOrderNum("W"); BigDecimal scoreAmount = withdrawalScoreDto.getAmount().multiply(poolScorePrice).setScale(2, BigDecimal.ROUND_DOWN); BigDecimal amountFee = scoreAmount.multiply(withDrawScoreCashPercent).setScale(2,BigDecimal.ROUND_DOWN); //余额增加 walletService.add(scoreAmount.subtract(amountFee), memberId, "balance"); MallMemberWithdraw withdraw = new MallMemberWithdraw(); withdraw.setWithdrawNo(orderNo); withdraw.setMemberId(memberId); withdraw.setAmount(scoreAmount); withdraw.setStatus(2); withdraw.setAmountFee(amountFee); withdraw.setType(2); withdraw.setScoreCnt(withdrawalScoreDto.getAmount()); withdraw.setScorePrice(poolScorePrice); this.baseMapper.insert(withdraw); mallMemberService.addMoneyFlow(memberId, withdrawalScoreDto.getAmount().negate(), MoneyFlowTypeEnum.SCORE_TO_CASH.getValue(), orderNo, null, null, null, 1, FlowTypeEnum.SCORE.getValue()); mallMemberService.addMoneyFlow(memberId, scoreAmount.subtract(amountFee), MoneyFlowTypeEnum.SCORE_TO_CASH.getValue(), orderNo, null, null, null, 1, FlowTypeEnum.BALANCE.getValue()); //卖出规则:卖出即销毁减少,70%现金到帐.30%回流底池,意味卖出后全网积分变少了,回流的30%到池子后.积分的价格变高了 DataDictionaryCustom poolCashDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode( PerkEnum.POOL_CASH.getType(), PerkEnum.POOL_CASH.getCode() ); BigDecimal poolCash = new BigDecimal(poolCashDic.getValue()); //先减去百分之百的提现金额在加上30%的回流金额 poolCash = poolCash.subtract(scoreAmount).add(amountFee); dataDictionaryCustomMapper.updateDicValueByTypeAndCode( PerkEnum.POOL_CASH.getType(), PerkEnum.POOL_CASH.getCode(), poolCash.toString() ); DataDictionaryCustom poolScoreDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode( PerkEnum.POOL_SCORE.getType(), PerkEnum.POOL_SCORE.getCode() ); BigDecimal poolScore = new BigDecimal(poolScoreDic.getValue()); poolScore = poolScore.subtract(withdraw.getScoreCnt()); dataDictionaryCustomMapper.updateDicValueByTypeAndCode( PerkEnum.POOL_SCORE.getType(), PerkEnum.POOL_SCORE.getCode(), poolScore.toString() ); if(poolScore.compareTo(BigDecimal.ZERO) > 0 && poolCash.compareTo(BigDecimal.ZERO) > 0){ BigDecimal divide = poolCash.divide(poolScore, 6, BigDecimal.ROUND_DOWN); dataDictionaryCustomMapper.updateDicValueByTypeAndCode( PerkEnum.POOL_SCORE_PRICE.getType(), PerkEnum.POOL_SCORE_PRICE.getCode(), divide.toString() ); } } }