package cc.mrbird.febs.vip.service.impl; import cc.mrbird.febs.common.enumerates.*; import cc.mrbird.febs.common.exception.FebsException; import cc.mrbird.febs.mall.dto.ScoreSettingDto; 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.alibaba.fastjson.JSONObject; 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 MallOrderItemMapper mallOrderItemMapper; 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; private final DataDictionaryCustomMapper dataDictionaryCustomMapper; /** * 根据订单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); BigDecimal scorePercent = BigDecimal.ONE; DataDictionaryCustom dic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode( DataDictionaryEnum.SCORE_SIGN_SETTING.getType(), DataDictionaryEnum.SCORE_SIGN_SETTING.getCode()); if (dic != null) { ScoreSettingDto scoreSettingDto = JSONObject.parseObject(dic.getValue(), ScoreSettingDto.class); BigDecimal bigDecimal = ObjectUtil.isEmpty(scoreSettingDto.getScorePercent()) ? BigDecimal.ONE : new BigDecimal(scoreSettingDto.getScorePercent()); if (bigDecimal.compareTo(BigDecimal.ZERO) > 0) { scorePercent = bigDecimal; } } // 下单自己获得积分,推荐人获得积分 //的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).multiply(scorePercent).setScale(0, RoundingMode.HALF_DOWN); log.info("下单获得积分:{}", mineScore); if(mineScore.compareTo(BigDecimal.ZERO) > 0){ mallMoneyFlowService.addMoneyFlow( memberId, mineScore, ScoreFlowTypeEnum.MINE_RECOMMEND.getValue(), mallOrderInfo.getOrderNo(), FlowTypeEnum.PRIZE_SCORE.getValue(), StrUtil.format( ScoreFlowTypeEnum.MINE_RECOMMEND.getDesc(),mineScore), 2); mallMemberWalletService.add(mineScore,memberId , "prizeScore"); // 记录会员购买获得的经验 BigDecimal multiply = amount.multiply(minePercent).setScale(2, RoundingMode.HALF_DOWN); mallMoneyFlowService.addMoneyFlow( memberId, multiply, ScoreFlowTypeEnum.BUY.getValue(), mallOrderInfo.getOrderNo(), FlowTypeEnum.SCORE.getValue(), StrUtil.format(ScoreFlowTypeEnum.BUY.getDesc(),multiply), 2 ); // 更新会员钱包中的分数 mallMemberWalletService.add(multiply, memberId, "score"); // 发送会员等级升级消息 agentProducer.sendVipLevelUp(memberId); } // 计算推荐人获得的积分 if(StrUtil.isNotEmpty(member.getReferrerId())){ MallMember refMember = mallMemberMapper.selectInfoByInviteId(member.getReferrerId()); BigDecimal otherPercent = happyMemberLevel.getOtherPercent(); BigDecimal otherScore = amount.multiply(otherPercent).multiply(scorePercent).setScale(0, RoundingMode.HALF_DOWN); log.info("推荐人获得积分:{}", otherScore); if(otherScore.compareTo(BigDecimal.ZERO) > 0){ mallMoneyFlowService.addMoneyFlow( refMember.getId(), otherScore, ScoreFlowTypeEnum.OTHER_RECOMMEND.getValue(), mallOrderInfo.getOrderNo(), FlowTypeEnum.PRIZE_SCORE.getValue(), StrUtil.format( ScoreFlowTypeEnum.OTHER_RECOMMEND.getDesc(),otherScore), 2); mallMemberWalletService.add(otherScore,refMember.getId() , "prizeScore"); // 记录会员购买获得的经验 BigDecimal multiply = amount.multiply(otherPercent).setScale(2, RoundingMode.HALF_DOWN); mallMoneyFlowService.addMoneyFlow( refMember.getId(), multiply, ScoreFlowTypeEnum.BUY.getValue(), mallOrderInfo.getOrderNo(), FlowTypeEnum.SCORE.getValue(), StrUtil.format(ScoreFlowTypeEnum.BUY.getDesc(),multiply), 2 ); // 更新会员钱包中的分数 mallMemberWalletService.add(multiply, refMember.getId(), "score"); // 发送会员等级升级消息 agentProducer.sendVipLevelUp(refMember.getId()); } } } // 发送分销等级升级消息 agentProducer.sendSaleLevelUp(orderId); } /** * 根据订单ID升级会员等级 * 当订单完成时,根据会员当前的经验值升级会员等级 * * @param orderId 订单ID */ @Override @Transactional(rollbackFor = Exception.class) public void levelUp(Long orderId) { // 根据订单中的会员ID获取会员信息 MallMember member = mallMemberMapper.selectById(orderId); // 如果会员信息为空,则记录日志并返回 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; } if(member.getDirector() > code){ return; } // 更新会员的导演等级为当前会员等级代码 member.setDirector(code); // 更新会员信息 mallMemberMapper.updateById(member); } /** * 升级销售级别时处理订单相关的逻辑 * * @param orderId 订单ID,用于识别和处理特定的订单 */ @Override @Transactional(rollbackFor = Exception.class) 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) .orderByDesc(MallMember::getId) .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; } // 计算返佣金额 List mallOrderItems = mallOrderItemMapper.selectList( new LambdaQueryWrapper() .eq(MallOrderItem::getOrderId, orderId) .eq(MallOrderItem::getState, 1) ); if(CollUtil.isEmpty(mallOrderItems)){ return; } BigDecimal amount = mallOrderItems.stream().map(MallOrderItem::getLevelOnePrice).reduce(BigDecimal.ZERO, BigDecimal::add); BigDecimal returnPercent = happySaleLevel.getReturnPercent(); BigDecimal multiply = amount.multiply(returnPercent).setScale(2, RoundingMode.HALF_DOWN); log.info("团长获得返佣:{}",multiply); // 如果返佣金额小于等于0,则直接返回 if(BigDecimal.ZERO.compareTo(multiply) >=0){ return; } // 如果返佣金额大于等于订单金额,则直接返回 if(multiply.compareTo(amount) > 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(), "totalScore"); MallAchieveRecord mallAchieveRecord = new MallAchieveRecord(); mallAchieveRecord.setMemberId(storeMasterMember.getId()); 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; } }