package cc.mrbird.febs.mall.service.impl; import cc.mrbird.febs.common.entity.FebsResponse; import cc.mrbird.febs.common.enumerates.FlowTypeEnum; import cc.mrbird.febs.common.enumerates.RunVipDataDictionaryEnum; import cc.mrbird.febs.common.enumerates.RunVipMoneyFlowTypeEnum; import cc.mrbird.febs.common.enumerates.YesOrNoEnum; import cc.mrbird.febs.common.exception.FebsException; import cc.mrbird.febs.common.utils.LoginUserUtil; import cc.mrbird.febs.common.utils.MallUtils; import cc.mrbird.febs.mall.conversion.RunVipConversion; import cc.mrbird.febs.mall.dto.*; import cc.mrbird.febs.mall.entity.*; import cc.mrbird.febs.mall.mapper.*; import cc.mrbird.febs.mall.service.IApiMallMemberWalletService; import cc.mrbird.febs.mall.service.IMallMoneyFlowService; import cc.mrbird.febs.mall.service.IRunVipService; import cc.mrbird.febs.mall.vo.*; import cc.mrbird.febs.rabbit.producter.AgentProducer; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateUnit; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.crypto.SecureUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 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; import java.math.RoundingMode; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import java.util.stream.IntStream; @Slf4j @Service @RequiredArgsConstructor public class RunVipServiceImpl extends ServiceImpl implements IRunVipService { private final DataDictionaryCustomMapper dataDictionaryCustomMapper; private final MallMemberPaymentMapper mallMemberPaymentMapper; private final MallChargeMapper mallChargeMapper; private final AgentProducer agentProducer; private final MallMoneyFlowMapper mallMoneyFlowMapper; private final MallMemberWalletMapper mallMemberWalletMapper; private final MallMemberMapper mallMemberMapper; private final IApiMallMemberWalletService walletService; private final IMallMoneyFlowService mallMoneyFlowService; private final RunVipGrowMapper runVipGrowMapper; @Override public List vipInfo() { Long memberId = LoginUserUtil.getLoginUser().getId(); List apiRunVipVos = new ArrayList<>(); MallMember mallMember = mallMemberMapper.selectById(memberId); if (StrUtil.isEmpty(mallMember.getLevel())) { return apiRunVipVos; } String level = mallMember.getLevel(); //获取当前用户的VIP等级 RunVip runVip = this.baseMapper.selectOne(new LambdaQueryWrapper().eq(RunVip::getVipCode, level)); //获取大于当前用户等级序号的所有的VIP等级 LambdaQueryWrapper runVipLambdaQueryWrapper = new LambdaQueryWrapper<>(); runVipLambdaQueryWrapper.eq(RunVip::getState, YesOrNoEnum.YES.getValue()); runVipLambdaQueryWrapper.ge(RunVip::getOrderNumber, runVip.getOrderNumber()); List runVips = this.baseMapper.selectList(runVipLambdaQueryWrapper); apiRunVipVos = RunVipConversion.INSTANCE.entityToVos(runVips); return apiRunVipVos; } @Override public FebsResponse goCharge(ApiGoChargeDto apiGoChargeDto) { Long memberId = LoginUserUtil.getLoginUser().getId(); MallMember mallMember = mallMemberMapper.selectById(memberId); if (StrUtil.isBlank(mallMember.getTradePassword())) { throw new FebsException("未设置资金密码"); } if (!mallMember.getTradePassword().equals(SecureUtil.md5(apiGoChargeDto.getTradeWord()))) { throw new FebsException("资金密码错误"); } Long runVipId = apiGoChargeDto.getRunVipId(); RunVip runVipNext = this.baseMapper.selectById(runVipId); if(runVipNext.getState() != YesOrNoEnum.YES.getValue()){ throw new FebsException("会员套餐已下架"); } //价格 BigDecimal presentAmount = runVipNext.getPresentPrice().multiply(new BigDecimal(apiGoChargeDto.getVipCnt())).setScale(2,BigDecimal.ROUND_DOWN); //减免价格 RunVip runVip = this.baseMapper.selectOne(new LambdaQueryWrapper().eq(RunVip::getVipCode, mallMember.getLevel())); BigDecimal reduceAmount = runVip.getPresentPrice(); RunVipGrow runVipGrow = runVipGrowMapper.selectList( new LambdaQueryWrapper() .eq(RunVipGrow::getMemberId, memberId) .eq(RunVipGrow::getLevelNow, mallMember.getLevel()) .orderByDesc(RunVipGrow::getId) ).stream().findFirst().orElse(null); if(runVipGrow != null){ BigDecimal amountNow = runVipGrow.getAmountNow(); reduceAmount = reduceAmount.add(amountNow); } presentAmount = presentAmount.subtract(reduceAmount); Long addressId = apiGoChargeDto.getAddressId(); MallMemberPayment mallMemberPayment = mallMemberPaymentMapper.selectById(addressId); if(ObjectUtil.isEmpty(mallMemberPayment)){ return new FebsResponse().fail().message("请先绑定你的地址"); } //判断系统的充值地址 String trcType = dataDictionaryCustomMapper.selectDicDataByTypeAndCode( RunVipDataDictionaryEnum.CHARGE_TYPE_TRC.getType(), RunVipDataDictionaryEnum.CHARGE_TYPE_TRC.getCode() ).getValue(); String sysAddress = ""; if(trcType.equals(mallMemberPayment.getBankNo())){ sysAddress = dataDictionaryCustomMapper.selectDicDataByTypeAndCode( RunVipDataDictionaryEnum.CHARGE_SYS_ADDRESS_TRC.getType(), RunVipDataDictionaryEnum.CHARGE_SYS_ADDRESS_TRC.getCode() ).getValue(); }else{ sysAddress = dataDictionaryCustomMapper.selectDicDataByTypeAndCode( RunVipDataDictionaryEnum.CHARGE_SYS_ADDRESS_BSC.getType(), RunVipDataDictionaryEnum.CHARGE_SYS_ADDRESS_BSC.getCode() ).getValue(); } String failMinutes = dataDictionaryCustomMapper.selectDicDataByTypeAndCode( RunVipDataDictionaryEnum.CHARGE_SYS_FAIL_TIME.getType(), RunVipDataDictionaryEnum.CHARGE_SYS_FAIL_TIME.getCode() ).getValue(); DateTime failTime = DateUtil.offsetMinute(DateUtil.date(), Integer.parseInt(failMinutes)); MallCharge mallCharge = new MallCharge(); mallCharge.setMemberId(memberId); mallCharge.setOrderNo(MallUtils.getOrderNum()); mallCharge.setState(YesOrNoEnum.ING.getValue()); mallCharge.setType(mallMemberPayment.getBankNo()); mallCharge.setAddress(mallMemberPayment.getBank()); mallCharge.setAmount(presentAmount); mallCharge.setFailTime(failTime); mallCharge.setSysAddress(sysAddress); mallCharge.setVipCode(runVipNext.getVipCode()); mallCharge.setVipName(runVipNext.getVipName()); mallCharge.setVipCnt(apiGoChargeDto.getVipCnt()); mallChargeMapper.insert(mallCharge); ApiGoChargeVo apiGoChargeVo = new ApiGoChargeVo(); apiGoChargeVo.setFailTime(mallCharge.getFailTime()); apiGoChargeVo.setAddress(mallCharge.getAddress()); apiGoChargeVo.setAmount(mallCharge.getAmount()); apiGoChargeVo.setSysAddress(mallCharge.getSysAddress()); apiGoChargeVo.setSysAddressType(mallCharge.getType()); /** * 充值接口调用后,发送一个延时队列 * 功能:延迟时间为【failMinutes】后,更新充值记录为失败。 */ ApiMemberChargeFailDto apiMemberChargeFailDto = new ApiMemberChargeFailDto(); apiMemberChargeFailDto.setChargeId(mallCharge.getId()); apiMemberChargeFailDto.setFailTime(Integer.parseInt(failMinutes) * 60L* 1000L); agentProducer.sendMemberChargeFailMsg(apiMemberChargeFailDto); return new FebsResponse().success().data(apiGoChargeVo); } @Override @Transactional(rollbackFor = Exception.class) public FebsResponse balanceBuy(ApiBalanceBuyDto apiBalanceBuyDto) { Long memberId = LoginUserUtil.getLoginUser().getId(); MallMember mallMember = mallMemberMapper.selectById(memberId); if (StrUtil.isBlank(mallMember.getTradePassword())) { throw new FebsException("未设置资金密码"); } if (!mallMember.getTradePassword().equals(SecureUtil.md5(apiBalanceBuyDto.getTradeWord()))) { throw new FebsException("资金密码错误"); } Long runVipId = apiBalanceBuyDto.getRunVipId(); RunVip runVipNext = this.baseMapper.selectById(runVipId); if(runVipNext.getState() != YesOrNoEnum.YES.getValue()){ throw new FebsException("会员套餐已下架"); } //价格 BigDecimal presentAmount = runVipNext.getPresentPrice().setScale(2,BigDecimal.ROUND_DOWN); //减免价格 RunVip runVip = this.baseMapper.selectOne(new LambdaQueryWrapper().eq(RunVip::getVipCode, mallMember.getLevel())); BigDecimal reduceAmount = runVip.getPresentPrice(); RunVipGrow runVipGrow = runVipGrowMapper.selectList( new LambdaQueryWrapper() .eq(RunVipGrow::getMemberId, memberId) .eq(RunVipGrow::getLevelNow, mallMember.getLevel()) .orderByDesc(RunVipGrow::getId) ).stream().findFirst().orElse(null); if(runVipGrow != null){ BigDecimal amountNow = runVipGrow.getAmountNow(); reduceAmount = reduceAmount.add(amountNow); } presentAmount = presentAmount.subtract(reduceAmount); MallMemberWallet mallMemberWallet = mallMemberWalletMapper.selectWalletByMemberId(memberId); if(mallMemberWallet.getCommission().compareTo(BigDecimal.ZERO) <= 0){ throw new FebsException("余额不足"); } if(mallMemberWallet.getCommission().compareTo(presentAmount) < 0){ throw new FebsException("余额不足"); } String orderNo = MallUtils.getOrderNum(); walletService.reduceCommission(presentAmount,memberId); mallMoneyFlowService.runVipMoneyFlowAdd( memberId, memberId, orderNo, FlowTypeEnum.COMMISSION.getValue(), RunVipMoneyFlowTypeEnum.COMMISSION_PAY.getValue(), presentAmount.negate(), StrUtil.format(RunVipMoneyFlowTypeEnum.COMMISSION_PAY.getDescription(),presentAmount), YesOrNoEnum.YES.getValue() ); MallCharge mallCharge = new MallCharge(); mallCharge.setMemberId(memberId); mallCharge.setOrderNo(orderNo); mallCharge.setState(YesOrNoEnum.YES.getValue()); mallCharge.setType(StrUtil.format(RunVipMoneyFlowTypeEnum.COMMISSION_PAY.getDescription(),presentAmount)); mallCharge.setAddress(mallMember.getPhone()); mallCharge.setAmount(presentAmount); mallCharge.setVipCode(runVipNext.getVipCode()); mallCharge.setVipName(runVipNext.getVipName()); mallCharge.setVipCnt(apiBalanceBuyDto.getVipCnt()); mallChargeMapper.insert(mallCharge); agentProducer.sendBuyVipSuccessMsg(mallCharge.getId()); return new FebsResponse().success().message("操作成功"); } @Override public FebsResponse goChargeInfo(ApiGoChargeInfoDto apiGoChargeInfoDto) { Long memberId = LoginUserUtil.getLoginUser().getId(); String orderNo = apiGoChargeInfoDto.getOrderNo(); LambdaQueryWrapper objectLambdaQueryWrapper = new LambdaQueryWrapper<>(); objectLambdaQueryWrapper.eq(MallCharge::getMemberId,memberId); objectLambdaQueryWrapper.eq(MallCharge::getOrderNo,orderNo); MallCharge mallCharge = mallChargeMapper.selectOne(objectLambdaQueryWrapper); ApiGoChargeVo apiGoChargeVo = new ApiGoChargeVo(); if(null == mallCharge){ throw new FebsException("记录不存在"); } apiGoChargeVo.setFailTime(mallCharge.getFailTime()); apiGoChargeVo.setAddress(mallCharge.getAddress()); apiGoChargeVo.setAmount(mallCharge.getAmount()); apiGoChargeVo.setSysAddress(mallCharge.getSysAddress()); apiGoChargeVo.setSysAddressType(mallCharge.getType()); return new FebsResponse().success().data(apiGoChargeVo); } @Override public List getChargeList(ApiChargeListDto apiChargeListDto) { Long memberId = LoginUserUtil.getLoginUser().getId(); apiChargeListDto.setMemberId(memberId); Page page = new Page<>(apiChargeListDto.getPageNum(), apiChargeListDto.getPageSize()); return mallChargeMapper.selectChargeListInPage(apiChargeListDto, page); } @Override public List getRunDate(ApiGetRunDateDto queryDto) { Long memberId = LoginUserUtil.getLoginUser().getId(); DateTime dateTime = DateUtil.parseDate(queryDto.getDateStr()); DateTime startTime = DateUtil.beginOfMonth(dateTime); DateTime endTime = DateUtil.endOfMonth(dateTime); long between = DateUtil.between(startTime, endTime, DateUnit.DAY); List apiGetRunDateVos = generateDateList(startTime, between); List mallMoneyFlows = mallMoneyFlowMapper.selectList( new LambdaQueryWrapper() .eq(MallMoneyFlow::getMemberId, memberId) .eq(MallMoneyFlow::getFlowType, FlowTypeEnum.SCORE.getValue()) .eq(MallMoneyFlow::getType, RunVipMoneyFlowTypeEnum.SCORE_OUT_BALANCE.getValue()) .ge(MallMoneyFlow::getCreatedTime, startTime) .le(MallMoneyFlow::getCreatedTime, endTime) ); if(CollUtil.isNotEmpty(mallMoneyFlows)){ calculateProfits(apiGetRunDateVos,mallMoneyFlows); } return apiGetRunDateVos; } /** * 生成日期列表 * * @param startDate 开始日期 * @param days 从开始日期算起的天数 * @return 一个包含日期信息的ApiGetRunDateVo对象列表 */ private List generateDateList(DateTime startDate, long days) { // 使用IntStream生成从0到days(包含days)的整数流,表示每一天 return IntStream.range(0, (int) days + 1) // 将每个整数映射为一个ApiGetRunDateVo对象 .mapToObj(i -> { // 创建ApiGetRunDateVo对象 ApiGetRunDateVo apiGetRunDateVo = new ApiGetRunDateVo(); // 计算日期:从起始日期开始偏移i天 DateTime dateTime = DateUtil.offsetDay(startDate, i); // 格式化日期为"yyyy-MM-dd"字符串,并设置到对象中 apiGetRunDateVo.setDateStr(DateUtil.format(dateTime, "yyyy-MM-dd")); // 初始化碳积分为0 apiGetRunDateVo.setScore(BigDecimal.ZERO); // 返回构建好的对象 return apiGetRunDateVo; }) // 将流中的对象收集到一个列表中 .collect(Collectors.toList()); } /** * 计算每日累计碳积分 * * @param dateList 日期列表,包含了每日的碳积分信息 * @param mallMoneyFlows 商城资金流列表,包含了每笔碳积分信息 */ private void calculateProfits(List dateList, List mallMoneyFlows) { // 将日期列表转换为映射,以便通过日期快速访问每日碳积分信息 Map dateMap = dateList.stream() .collect(Collectors.toMap(ApiGetRunDateVo::getDateStr, vo -> vo)); // 遍历mallMoneyFlows for (MallMoneyFlow item : mallMoneyFlows) { // 格式化当前项的创建时间,提取日期 String date = DateUtil.format(item.getCreatedTime(), "yyyy-MM-dd"); // 从日期映射中获取对应的每日碳积分信息 ApiGetRunDateVo apiGetRunDateVo = dateMap.get(date); // 如果找到了对应的每日碳积分信息 if (apiGetRunDateVo != null) { // 获取当前日期的碳积分 BigDecimal score = apiGetRunDateVo.getScore(); // 计算新的碳积分,将碳积分与碳积分相加,并向下取整到个位数 BigDecimal profit = score.add(item.getAmount().abs()).setScale(0,BigDecimal.ROUND_DOWN); // 更新每日碳积分信息的利润值 apiGetRunDateVo.setScore(profit); } } } @Override public ApiRunDataVo runData() { Long memberId = LoginUserUtil.getLoginUser().getId(); ApiRunDataVo apiRunDataVo = new ApiRunDataVo(); MallMember mallMember = mallMemberMapper.selectById(memberId); String level = mallMember.getLevel(); RunVip runVip = this.baseMapper.selectOne(new LambdaQueryWrapper().eq(RunVip::getVipCode, level)); apiRunDataVo.setAimScore(runVip.getGrowthCnt()); List mallMoneyFlows = mallMoneyFlowMapper.selectList( new LambdaQueryWrapper() .eq(MallMoneyFlow::getMemberId, memberId) .eq(MallMoneyFlow::getFlowType, FlowTypeEnum.SCORE.getValue()) .in(MallMoneyFlow::getType, RunVipMoneyFlowTypeEnum.GET_SCORE.getValue(),RunVipMoneyFlowTypeEnum.SYS_SCORE.getValue()) .ge(MallMoneyFlow::getCreatedTime, DateUtil.beginOfDay(DateUtil.date())) .le(MallMoneyFlow::getCreatedTime, DateUtil.endOfDay(DateUtil.date())) ); if(CollUtil.isNotEmpty(mallMoneyFlows)){ BigDecimal reduce = mallMoneyFlows.stream().map(MallMoneyFlow::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add); apiRunDataVo.setScore(reduce.intValue()); } MallMemberWallet mallMemberWallet = mallMemberWalletMapper.selectWalletByMemberId(memberId); apiRunDataVo.setBalance(mallMemberWallet.getBalance()); apiRunDataVo.setRealScore(mallMemberWallet.getScore().intValue()); return apiRunDataVo; } @Override public ApiRunHealthVo runHealth() { Long memberId = LoginUserUtil.getLoginUser().getId(); ApiRunHealthVo apiRunHealthVo = new ApiRunHealthVo(); MallMemberWallet mallMemberWallet = mallMemberWalletMapper.selectWalletByMemberId(memberId); int realScore = mallMemberWallet.getScore().intValue(); apiRunHealthVo.setScore(realScore); List mallMoneyFlows = mallMoneyFlowMapper.selectList( new LambdaQueryWrapper() .eq(MallMoneyFlow::getMemberId, memberId) .eq(MallMoneyFlow::getFlowType, FlowTypeEnum.SCORE.getValue()) .in(MallMoneyFlow::getType, RunVipMoneyFlowTypeEnum.GET_SCORE.getValue(),RunVipMoneyFlowTypeEnum.SYS_SCORE.getValue()) .ge(MallMoneyFlow::getCreatedTime, DateUtil.beginOfDay(DateUtil.date())) .le(MallMoneyFlow::getCreatedTime, DateUtil.endOfDay(DateUtil.date())) ); if(CollUtil.isNotEmpty(mallMoneyFlows)){ BigDecimal reduce = mallMoneyFlows.stream().map(MallMoneyFlow::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add); apiRunHealthVo.setScoreTotal(reduce.intValue()); } List mallMoneyFlowScoreOuts = mallMoneyFlowMapper.selectList( new LambdaQueryWrapper() .eq(MallMoneyFlow::getMemberId, memberId) .eq(MallMoneyFlow::getFlowType, FlowTypeEnum.SCORE.getValue()) .eq(MallMoneyFlow::getType, RunVipMoneyFlowTypeEnum.SCORE_OUT_BALANCE.getValue()) .ge(MallMoneyFlow::getCreatedTime, DateUtil.beginOfDay(DateUtil.date())) .le(MallMoneyFlow::getCreatedTime, DateUtil.endOfDay(DateUtil.date())) ); if(CollUtil.isNotEmpty(mallMoneyFlowScoreOuts)){ BigDecimal reduce = mallMoneyFlowScoreOuts.stream().map(MallMoneyFlow::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add).abs(); apiRunHealthVo.setScoreUsed(reduce.intValue()); } return apiRunHealthVo; } @Override public FebsResponse growInfo() { Long memberId = LoginUserUtil.getLoginUser().getId(); ApiGrowInfoVo apiGrowInfoVo = new ApiGrowInfoVo(); MallMember mallMember = mallMemberMapper.selectById(memberId); String memberLevel = mallMember.getLevel(); RunVipGrow runVipGrow = runVipGrowMapper.selectOne( new LambdaQueryWrapper() .eq(RunVipGrow::getMemberId, memberId) .orderByDesc(RunVipGrow::getId) .last("limit 1") ); //有升级权益的记录、当前等级和最新的升级记录是同一个 if(runVipGrow != null && memberLevel.equals(runVipGrow.getLevelNow())){ apiGrowInfoVo.setLevelNow(runVipGrow.getLevelNow()); apiGrowInfoVo.setAmountNow(runVipGrow.getAmountNow()); apiGrowInfoVo.setLevelNext(runVipGrow.getLevelNext()); apiGrowInfoVo.setAmountAll(runVipGrow.getAmountAll()); }else{ List runVips = this.baseMapper.selectList(null); Map runVipMap = runVips.stream() .collect(Collectors.toMap(RunVip::getVipCode, runVip -> runVip)); RunVip runVipNow = runVipMap.get(memberLevel); apiGrowInfoVo.setLevelNow(runVipNow.getVipCode()); apiGrowInfoVo.setAmountNow(runVipNow.getPresentPrice()); //获取runVips中的orderNumber为runVipNow.getOrderNumber() + 1的那个元素 RunVip runVipNext = runVips.stream().filter(runVip -> runVip.getOrderNumber() == runVipNow.getOrderNumber() + 1).findFirst().orElse(null); if(runVipNext != null){ apiGrowInfoVo.setLevelNext(runVipNext.getVipCode()); apiGrowInfoVo.setAmountAll(runVipNext.getPresentPrice()); } } return new FebsResponse().success().data(apiGrowInfoVo); } @Override @Transactional(rollbackFor = Exception.class) public FebsResponse growBuy(ApiGrowBuyDto apiGrowBuyDto) { Long memberId = LoginUserUtil.getLoginUser().getId(); BigDecimal amount = apiGrowBuyDto.getAmount(); if(BigDecimal.ZERO.compareTo(amount) >= 0){ throw new FebsException("金额异常"); } MallMember mallMember = mallMemberMapper.selectById(memberId); if (StrUtil.isBlank(mallMember.getTradePassword())) { throw new FebsException("未设置资金密码"); } if (!mallMember.getTradePassword().equals(SecureUtil.md5(apiGrowBuyDto.getTradeWord()))) { throw new FebsException("资金密码错误"); } MallMemberWallet mallMemberWallet = mallMemberWalletMapper.selectWalletByMemberId(memberId); if(mallMemberWallet.getCommission().compareTo(amount) < 0){ throw new FebsException("余额不足"); } String memberLevel = mallMember.getLevel(); String levelNext = apiGrowBuyDto.getLevelNext(); List runVips = this.baseMapper.selectList(null); Map runVipMap = runVips.stream() .collect(Collectors.toMap(RunVip::getVipCode, runVip -> runVip)); RunVip runVip = runVipMap.get(memberLevel); RunVip runVipNext = runVipMap.get(levelNext); if(runVipNext == null){ throw new FebsException("无法升级会员权益"); } if(runVip.getOrderNumber() < runVipNext.getOrderNumber()){ throw new FebsException("用户无法升级"); } walletService.reduceCommission(amount,memberId); String orderNo = MallUtils.getOrderNum("QY"); mallMoneyFlowService.runVipMoneyFlowAdd( memberId, memberId, orderNo, FlowTypeEnum.COMMISSION.getValue(), RunVipMoneyFlowTypeEnum.COMMISSION_PAY_GROW.getValue(), amount.negate(), StrUtil.format(RunVipMoneyFlowTypeEnum.COMMISSION_PAY_GROW.getDescription(),amount), YesOrNoEnum.YES.getValue() ); RunVipGrow runVipGrow = runVipGrowMapper.selectOne( new LambdaQueryWrapper() .eq(RunVipGrow::getMemberId, memberId) .eq(RunVipGrow::getLevelNow, memberLevel) .eq(RunVipGrow::getLevelNext, levelNext) ); MallCharge mallCharge = new MallCharge(); mallCharge.setMemberId(memberId); mallCharge.setOrderNo(orderNo); mallCharge.setState(YesOrNoEnum.YES.getValue()); mallCharge.setType(StrUtil.format(RunVipMoneyFlowTypeEnum.COMMISSION_PAY_GROW.getDescription(),amount)); mallCharge.setAddress(mallMember.getPhone()); mallCharge.setAmount(amount); mallCharge.setVipCnt(1); mallCharge.setVipName(runVip.getVipName()+"权益"); mallCharge.setVipCode(runVip.getVipCode()); //有升级权益的记录 if(runVipGrow != null){ //判断金额是否满足升级条件 BigDecimal amountNow = runVipGrow.getAmountNow(); BigDecimal amountAll = runVipGrow.getAmountAll(); BigDecimal subtract = amountAll.subtract(amountNow); if(subtract.compareTo(amount) <= 0){ runVipGrow.setAmountNow(amountAll); mallCharge.setVipCode(runVipGrow.getLevelNext()); }else{ runVipGrow.setAmountNow(amountNow.add(amount).setScale(2, RoundingMode.DOWN)); mallCharge.setVipCode(memberLevel); } runVipGrow.setAmount(amount); runVipGrowMapper.updateById(runVipGrow); }else{ runVipGrow = new RunVipGrow(); runVipGrow.setMemberId(memberId); runVipGrow.setLevelNow(memberLevel); runVipGrow.setLevelNext(runVipNext.getVipCode()); runVipGrow.setAmountAll(runVipNext.getPresentPrice()); runVipGrow.setAmount(amount); runVipGrow.setAmountNow(amount); runVipGrowMapper.insert(runVipGrow); if(runVipGrow.getAmountAll().compareTo(amount) <= 0){ mallCharge.setVipCode(runVipGrow.getLevelNext()); } } mallChargeMapper.insert(mallCharge); agentProducer.sendBuyVipSuccessMsg(mallCharge.getId()); return new FebsResponse().success().message("操作成功"); } @Override public FebsResponse growCharge(ApiGrowChargeDto apiGrowChargeDto) { Long memberId = LoginUserUtil.getLoginUser().getId(); ApiGoChargeVo apiGoChargeVo = new ApiGoChargeVo(); BigDecimal amount = apiGrowChargeDto.getAmount(); if(BigDecimal.ZERO.compareTo(amount) >= 0){ throw new FebsException("金额异常"); } MallMember mallMember = mallMemberMapper.selectById(memberId); if (StrUtil.isBlank(mallMember.getTradePassword())) { throw new FebsException("未设置资金密码"); } if (!mallMember.getTradePassword().equals(SecureUtil.md5(apiGrowChargeDto.getTradeWord()))) { throw new FebsException("资金密码错误"); } String memberLevel = mallMember.getLevel(); String levelNext = apiGrowChargeDto.getLevelNext(); List runVips = this.baseMapper.selectList(null); Map runVipMap = runVips.stream() .collect(Collectors.toMap(RunVip::getVipCode, runVip -> runVip)); RunVip runVip = runVipMap.get(memberLevel); RunVip runVipNext = runVipMap.get(levelNext); if(runVipNext == null){ throw new FebsException("无法升级会员权益"); } if(runVip.getOrderNumber() >= runVipNext.getOrderNumber()){ throw new FebsException("用户无法升级"); } Long addressId = apiGrowChargeDto.getAddressId(); MallMemberPayment mallMemberPayment = mallMemberPaymentMapper.selectById(addressId); if(ObjectUtil.isEmpty(mallMemberPayment)){ return new FebsResponse().fail().message("请先绑定你的地址"); } //判断系统的充值地址 String trcType = dataDictionaryCustomMapper.selectDicDataByTypeAndCode( RunVipDataDictionaryEnum.CHARGE_TYPE_TRC.getType(), RunVipDataDictionaryEnum.CHARGE_TYPE_TRC.getCode() ).getValue(); String sysAddress = ""; if(trcType.equals(mallMemberPayment.getBankNo())){ sysAddress = dataDictionaryCustomMapper.selectDicDataByTypeAndCode( RunVipDataDictionaryEnum.CHARGE_SYS_ADDRESS_TRC.getType(), RunVipDataDictionaryEnum.CHARGE_SYS_ADDRESS_TRC.getCode() ).getValue(); }else{ sysAddress = dataDictionaryCustomMapper.selectDicDataByTypeAndCode( RunVipDataDictionaryEnum.CHARGE_SYS_ADDRESS_BSC.getType(), RunVipDataDictionaryEnum.CHARGE_SYS_ADDRESS_BSC.getCode() ).getValue(); } String failMinutes = dataDictionaryCustomMapper.selectDicDataByTypeAndCode( RunVipDataDictionaryEnum.CHARGE_SYS_FAIL_TIME.getType(), RunVipDataDictionaryEnum.CHARGE_SYS_FAIL_TIME.getCode() ).getValue(); DateTime failTime = DateUtil.offsetMinute(DateUtil.date(), Integer.parseInt(failMinutes)); MallCharge mallCharge = new MallCharge(); String orderNo = MallUtils.getOrderNum("QY"); mallCharge.setMemberId(memberId); mallCharge.setOrderNo(orderNo); mallCharge.setState(YesOrNoEnum.ING.getValue()); mallCharge.setType(mallMemberPayment.getBankNo()); mallCharge.setAddress(mallMemberPayment.getBank()); mallCharge.setFailTime(failTime); mallCharge.setSysAddress(sysAddress); mallCharge.setAmount(amount); mallCharge.setVipCnt(1); mallCharge.setVipName(runVip.getVipName()+"权益"); mallCharge.setVipCode(runVip.getVipCode()); RunVipGrow runVipGrow = runVipGrowMapper.selectOne( new LambdaQueryWrapper() .eq(RunVipGrow::getMemberId, memberId) .eq(RunVipGrow::getLevelNow, memberLevel) .eq(RunVipGrow::getLevelNext, levelNext) ); //有升级权益的记录、当前等级和最新的升级记录是同一个 if(runVipGrow != null){ //判断金额是否满足升级条件 BigDecimal amountNow = runVipGrow.getAmountNow(); BigDecimal amountAll = runVipGrow.getAmountAll(); BigDecimal subtract = amountAll.subtract(amountNow); if(subtract.compareTo(amount) <= 0){ mallCharge.setVipCode(runVipGrow.getLevelNext()); } }else{ if(runVipNext.getPresentPrice().compareTo(amount) <= 0){ mallCharge.setVipCode(runVipNext.getVipCode()); } } mallChargeMapper.insert(mallCharge); apiGoChargeVo.setFailTime(mallCharge.getFailTime()); apiGoChargeVo.setAddress(mallCharge.getAddress()); apiGoChargeVo.setAmount(mallCharge.getAmount()); apiGoChargeVo.setSysAddress(mallCharge.getSysAddress()); apiGoChargeVo.setSysAddressType(mallCharge.getType()); /** * 充值接口调用后,发送一个延时队列 * 功能:延迟时间为【failMinutes】后,更新充值记录为失败。 */ ApiMemberChargeFailDto apiMemberChargeFailDto = new ApiMemberChargeFailDto(); apiMemberChargeFailDto.setChargeId(mallCharge.getId()); apiMemberChargeFailDto.setFailTime(Integer.parseInt(failMinutes) * 60L* 1000L); agentProducer.sendMemberChargeFailMsg(apiMemberChargeFailDto); return new FebsResponse().success().data(apiGoChargeVo); } @Override public FebsResponse reduceAmount() { Long memberId = LoginUserUtil.getLoginUser().getId(); ApiReduceAmountVo apiReduceAmountVo = new ApiReduceAmountVo(); MallMember mallMember = mallMemberMapper.selectById(memberId); //减免价格 RunVip runVip = this.baseMapper.selectOne(new LambdaQueryWrapper().eq(RunVip::getVipCode, mallMember.getLevel())); BigDecimal reduceAmount = runVip.getPresentPrice(); RunVipGrow runVipGrow = runVipGrowMapper.selectList( new LambdaQueryWrapper() .eq(RunVipGrow::getMemberId, memberId) .eq(RunVipGrow::getLevelNow, mallMember.getLevel()) .orderByDesc(RunVipGrow::getId) ).stream().findFirst().orElse(null); if(runVipGrow != null){ BigDecimal amountNow = runVipGrow.getAmountNow(); reduceAmount = reduceAmount.add(amountNow); } apiReduceAmountVo.setReduceAmount(reduceAmount); return new FebsResponse().success().data(apiReduceAmountVo); } }