package cc.mrbird.febs.vip.service.impl; import cc.mrbird.febs.common.enumerates.FlowTypeEnum; import cc.mrbird.febs.common.enumerates.MoneyFlowTypeEnum; import cc.mrbird.febs.common.enumerates.OrderStatusEnum; import cc.mrbird.febs.common.enumerates.ScoreFlowTypeEnum; import cc.mrbird.febs.common.exception.FebsException; import cc.mrbird.febs.mall.entity.*; import cc.mrbird.febs.mall.mapper.*; import cc.mrbird.febs.mall.service.IApiMallGoodsService; import cc.mrbird.febs.mall.service.IApiMallMemberWalletService; import cc.mrbird.febs.mall.service.IApiMallOrderInfoService; import cc.mrbird.febs.mall.service.IMallMoneyFlowService; import cc.mrbird.febs.rabbit.producter.AgentProducer; import cc.mrbird.febs.vip.entity.MallVipBenefits; import cc.mrbird.febs.vip.entity.MallVipConfig; import cc.mrbird.febs.vip.mapper.MallVipConfigMapper; import cc.mrbird.febs.vip.service.IMallVipConfigService; import cc.mrbird.febs.vip.service.IVipCommonService; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; 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.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.logging.Handler; import java.util.stream.Collectors; @Slf4j @Service @RequiredArgsConstructor public class VipCommonServiceImpl implements IVipCommonService { private final MallOrderInfoMapper mallOrderInfoMapper; private final IMallVipConfigService mallVipConfigService; private final IMallMoneyFlowService mallMoneyFlowService; private final IApiMallMemberWalletService mallMemberWalletService; private final MallMemberWalletMapper mallMemberWalletMapper; private final MallMemberMapper mallMemberMapper; private final MallVipConfigMapper mallVipConfigMapper; private final AgentProducer agentProducer; private final IApiMallGoodsService mallGoodsService; private final HappyMemberLevelMapper happyMemberLevelMapper; private final HappySaleLevelMapper happySaleLevelMapper; private final MallAchieveRecordMapper mallAchieveRecordMapper; /** * 根据订单ID获取分数 * 此方法处理订单得分逻辑,包括直接购买得分、会员等级得分和推荐人得分 * * @param orderId 订单ID,用于查询订单详细信息 */ @Override @Transactional(rollbackFor = Exception.class) public void getScore(Long orderId) { // 根据订单ID查询订单详细信息 MallOrderInfo mallOrderInfo = mallOrderInfoMapper.selectOrderDetailsById(orderId); if (mallOrderInfo == null) { // 如果订单信息为空,则直接返回 return; } if (mallOrderInfo.getStatus() != OrderStatusEnum.FINISH.getValue()) { // 订单不是完成状态 return; } // 获取订单金额 BigDecimal amount = mallOrderInfo.getAmount(); if(BigDecimal.ZERO.compareTo(amount) >= 0){ // 如果订单金额小于等于0,则直接返回 return; } // 获取会员ID Long memberId = mallOrderInfo.getMemberId(); // 根据会员ID查询会员信息 MallMember member = mallMemberMapper.selectById(memberId); // 记录会员购买获得的经验 mallMoneyFlowService.addMoneyFlow( memberId, amount, ScoreFlowTypeEnum.BUY.getValue(), mallOrderInfo.getOrderNo(), FlowTypeEnum.SCORE.getValue(), StrUtil.format(ScoreFlowTypeEnum.BUY.getDesc(),amount), 2 ); // 更新会员钱包中的分数 mallMemberWalletService.add(amount, memberId, "score"); // 下单自己获得积分,推荐人获得积分 //的map Map recommendScoreMap = new HashMap<>(); Map recommendTypeScoreMap = new HashMap<>(); // 获取会员的董事等级代码 Integer director = member.getDirector(); // 查询与董事等级代码匹配的会员等级信息 LambdaQueryWrapper happyMemberLevelLambdaQueryWrapper = new LambdaQueryWrapper(); happyMemberLevelLambdaQueryWrapper.eq(HappyMemberLevel::getCode, director); happyMemberLevelLambdaQueryWrapper.last("limit 1"); HappyMemberLevel happyMemberLevel = happyMemberLevelMapper.selectOne(happyMemberLevelLambdaQueryWrapper); log.info("会员等级信息:{}", JSONUtil.toJsonStr(happyMemberLevel)); if(ObjectUtil.isNotEmpty(happyMemberLevel)){ // 计算自己获得的积分 BigDecimal minePercent = happyMemberLevel.getMinePercent(); BigDecimal mineScore = amount.multiply(minePercent).setScale(0, RoundingMode.HALF_DOWN); log.info("下单获得积分:{}", mineScore); if(mineScore.compareTo(BigDecimal.ZERO) > 0){ recommendScoreMap.put(memberId, mineScore); recommendTypeScoreMap.put(memberId, ScoreFlowTypeEnum.MINE_RECOMMEND.getValue()); } // 计算推荐人获得的积分 if(StrUtil.isNotEmpty(member.getReferrerId())){ MallMember refMember = mallMemberMapper.selectInfoByInviteId(member.getReferrerId()); BigDecimal otherPercent = happyMemberLevel.getOtherPercent(); BigDecimal otherScore = amount.multiply(otherPercent).setScale(0, RoundingMode.HALF_DOWN); log.info("推荐人获得积分:{}", otherScore); if(otherScore.compareTo(BigDecimal.ZERO) > 0){ recommendScoreMap.put(refMember.getId(), otherScore); recommendTypeScoreMap.put(memberId, ScoreFlowTypeEnum.OTHER_RECOMMEND.getValue()); } } } // 为推荐人和自己添加积分流动记录和更新钱包 recommendScoreMap.forEach((key, value) -> { if (value != null) { mallMoneyFlowService.addMoneyFlow( key, value, recommendTypeScoreMap.get(key), mallOrderInfo.getOrderNo(), FlowTypeEnum.PRIZE_SCORE.getValue(), StrUtil.format(ScoreFlowTypeEnum.getDescByValue(recommendTypeScoreMap.get(key)),value), 2); mallMemberWalletService.add(value, key, "prizeScore"); } }); // 发送会员等级升级消息 agentProducer.sendVipLevelUp(orderId); } /** * 根据订单ID升级会员等级 * 当订单完成时,根据会员当前的经验值升级会员等级 * * @param orderId 订单ID */ @Override public void levelUp(Long orderId) { // 根据订单ID获取订单详细信息 MallOrderInfo mallOrderInfo = mallOrderInfoMapper.selectOrderDetailsById(orderId); // 如果订单信息为空,则直接返回 if (mallOrderInfo == null) { return; } // 如果订单状态不是完成状态,则直接返回 if (mallOrderInfo.getStatus() != OrderStatusEnum.FINISH.getValue()) { // 订单不是完成状态 return; } // 根据订单中的会员ID获取会员信息 MallMember member = mallMemberMapper.selectById(mallOrderInfo.getMemberId()); // 如果会员信息为空,则记录日志并返回 if (member == null) { log.info("会员不存在"); return; } // 根据会员ID获取会员钱包信息 MallMemberWallet mallMemberWallet = mallMemberWalletMapper.selectWalletByMemberId(member.getId()); // 如果会员钱包信息为空,则记录日志并返回 if (mallMemberWallet == null) { log.info("会员钱包不存在"); return; } //当前经验值 int score = mallMemberWallet.getScore().intValue(); // 查询当前经验值对应的会员等级 HappyMemberLevel happyMemberLevel = happyMemberLevelMapper.selectOne( new LambdaQueryWrapper() .ge(HappyMemberLevel::getUpgradeScore, score) .orderByAsc(HappyMemberLevel::getCode) .last("limit 1") ); // 如果查询不到对应的会员等级,则记录日志并返回 if (happyMemberLevel == null) { log.info("会员等级不存在"); return; } // 获取当前会员等级代码 Integer code = happyMemberLevel.getCode(); // 如果当前会员等级与会员的导演等级相同,则直接返回 if(member.getDirector() == code){ return; } // 更新会员的导演等级为当前会员等级代码 member.setDirector(code); // 更新会员信息 mallMemberMapper.updateById(member); // 发送分销等级升级消息 agentProducer.sendSaleLevelUp(orderId); } /** * 升级销售级别时处理订单相关的逻辑 * * @param orderId 订单ID,用于识别和处理特定的订单 */ @Override public void saleLevelUp(Long orderId) { // 根据订单ID获取订单详细信息 MallOrderInfo mallOrderInfo = mallOrderInfoMapper.selectOrderDetailsById(orderId); // 如果订单信息为空,则直接返回 if (mallOrderInfo == null) { return; } // 如果订单状态不是完成状态,则直接返回 if (mallOrderInfo.getStatus() != OrderStatusEnum.FINISH.getValue()) { // 订单不是完成状态 return; } // 根据订单中的会员ID获取会员信息 MallMember member = mallMemberMapper.selectById(mallOrderInfo.getMemberId()); // 如果会员信息为空,则记录日志并返回 if (member == null) { log.info("会员不存在"); return; } // 如果会员的推荐人ID为空,则直接返回 if(StrUtil.isEmpty(member.getReferrerIds())){ return; } // 分割会员的推荐人ID String[] referrerIds = member.getReferrerIds().split(","); // 查询符合条件的团长会员 MallMember storeMasterMember = mallMemberMapper.selectOne( new LambdaQueryWrapper() .in(MallMember::getInviteId, referrerIds) .eq(MallMember::getAccountStatus, MallMember.ACCOUNT_STATUS_ENABLE) .eq(MallMember::getAccountType, MallMember.ACCOUNT_TYPE_NORMAL) .ne(MallMember::getStoreMaster, 0) .orderByAsc(MallMember::getStoreMaster) .last("limit 1") ); // 如果没有找到符合条件的团长,则记录日志并返回 if (storeMasterMember == null) { log.info("团长不存在"); return; } // 根据团长的等级代码查询团长等级信息 HappySaleLevel happySaleLevel = happySaleLevelMapper.selectOne( new LambdaQueryWrapper() .eq(HappySaleLevel::getCode, storeMasterMember.getStoreMaster()) ); // 如果团长等级信息不存在,则记录日志并返回 if (happySaleLevel == null) { log.info("团长等级不存在"); return; } // 计算返佣金额 BigDecimal returnPercent = happySaleLevel.getReturnPercent(); BigDecimal multiply = mallOrderInfo.getAmount().multiply(returnPercent).setScale(2, RoundingMode.HALF_DOWN); log.info("团长获得返佣:{}",multiply); // 如果返佣金额小于等于0,则直接返回 if(BigDecimal.ZERO.compareTo(multiply) >=0){ return; } // 如果返佣金额大于等于订单金额,则直接返回 if(multiply.compareTo(mallOrderInfo.getAmount()) >= 0){ return; } // 记录团长获得返佣 mallMoneyFlowService.addMoneyFlow( storeMasterMember.getId(), multiply, ScoreFlowTypeEnum.SALE_RECOMMEND.getValue(), mallOrderInfo.getOrderNo(), FlowTypeEnum.COMMISSION.getValue(), StrUtil.format(ScoreFlowTypeEnum.SALE_RECOMMEND.getDesc(),multiply), 2 ); // 更新会员钱包中的余额 mallMemberWalletService.add(multiply, storeMasterMember.getId(), "commission"); mallMemberWalletService.add(multiply, storeMasterMember.getId(), "total_score"); MallAchieveRecord mallAchieveRecord = new MallAchieveRecord(); mallAchieveRecord.setMemberId(mallOrderInfo.getMemberId()); mallAchieveRecord.setAchieveTime(new Date()); mallAchieveRecord.setAmount(mallOrderInfo.getAmount()); mallAchieveRecord.setCostAmount(multiply); mallAchieveRecord.setOrderId(mallOrderInfo.getId()); mallAchieveRecord.setIsNormal(1); mallAchieveRecord.setPayTime(mallOrderInfo.getPayTime()); mallAchieveRecordMapper.insert(mallAchieveRecord); this.autoUpAgentLevel(storeMasterMember.getId()); } /** * 自动升级代理等级 * 根据会员的当前状态和业绩,自动为其升级到下一个代理等级 * @param memberId 会员ID,用于识别需要升级的会员 */ private void autoUpAgentLevel(Long memberId) { // 根据会员ID查询会员信息 MallMember member = mallMemberMapper.selectById(memberId); // 检查会员账户状态和类型,只有在启用状态和普通类型时才进行升级操作 if(MallMember.ACCOUNT_STATUS_ENABLE != member.getAccountStatus() || MallMember.ACCOUNT_TYPE_NORMAL != member.getAccountType() ){ return; } // 获取会员当前的店铺主人等级 Integer storeMaster = member.getStoreMaster(); // 下一个分销等级 storeMaster =storeMaster +1; // 根据新的店铺主人等级查询对应的快乐销售等级信息 HappySaleLevel happySaleLevel = happySaleLevelMapper.selectOne( new LambdaQueryWrapper() .eq(HappySaleLevel::getCode, storeMaster) ); // 如果没有找到对应的快乐销售等级信息,则记录日志并返回 if (happySaleLevel == null) { log.info("当前等级无下级"); return; } // 检查直推会员数量是否达到要求 if (!directMemberCnt(member, happySaleLevel.getDirectCnt())) { return; } // 检查团队人数是否达到要求 if (!teamCntFinish(member, happySaleLevel.getTeamCnt())) { return; } // 检查团队业绩是否达到要求 if (!teamIncome(member, happySaleLevel.getTeamAmount())) { return; } // 更新会员的店铺主人等级 member.setStoreMaster(storeMaster); // 更新会员信息 mallMemberMapper.updateById(member); } /** * 判断直推人数是否达标 */ private boolean directMemberCnt(MallMember member, Integer directCnt) { List childList = mallMemberMapper.selectByRefererId(member.getInviteId()); if (CollUtil.isEmpty(childList)) { return false; } if (childList.size() >= directCnt) { return true; } log.info("用户:{}直推数量未达标, 当前等级:{}, 当前数量:{}, 目标数量:{}", member.getPhone(), member.getStoreMaster(), childList.size(), directCnt); return false; } /** * 判断团队数量是否达标 */ private boolean teamCntFinish(MallMember member, Integer teamCnt) { // 直推用户 List teamMember = mallMemberMapper.selectAllChildAgentListByInviteId(member.getInviteId()); if (CollUtil.isEmpty(teamMember)) { return false; } if (teamMember.size() >= teamCnt) { return true; } log.info("用户:{}团队数量未达标, 当前等级:{}, 当前数量:{}, 目标数量:{}", member.getPhone(), member.getStoreMaster(), teamMember.size(), teamCnt); return false; } /** * 团队业绩是否达标 */ private boolean teamIncome(MallMember member, BigDecimal teamAmount) { BigDecimal totalIncome = mallMemberMapper.selectAchieveByMemberId(member.getInviteId(), 2); if(totalIncome.compareTo(teamAmount) >= 0){ return true; } log.info("用户:{}团队业绩未达标, 当前等级:{}, 当前业绩:{}, 目标业绩:{}", member.getPhone(), member.getStoreMaster(), totalIncome, teamAmount); return false; } }