package cc.mrbird.febs.mall.service.impl; import cc.mrbird.febs.common.enumerates.*; import cc.mrbird.febs.common.utils.AppContants; import cc.mrbird.febs.mall.entity.*; import cc.mrbird.febs.mall.mapper.*; import cc.mrbird.febs.mall.service.*; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson.JSONObject; import jdk.nashorn.internal.ir.IfNode; 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.*; import java.util.stream.Collectors; /** * @author wzy * @date 2021-09-26 **/ @Slf4j @Service @RequiredArgsConstructor public class AgentServiceImpl implements IAgentService { private final DataDictionaryCustomMapper dataDictionaryCustomMapper; private final MallMemberMapper memberMapper; private final MallOrderInfoMapper mallOrderInfoMapper; private final MallOrderItemMapper mallOrderItemMapper; private final IApiMallMemberWalletService iApiMallMemberWalletService; private final IMallMoneyFlowService mallMoneyFlowService; private final MallMemberMapper mallMemberMapper; @Override @Transactional(rollbackFor = Exception.class) public void autoUpAgentLevel(Long memberId) { MallMember member = memberMapper.selectById(memberId); if(StrUtil.isBlank(member.getReferrerIds())) { return; } List ids = StrUtil.split(member.getReferrerIds(), ','); List parentMembers = memberMapper.selectByInviteIds(ids); for (MallMember parent : parentMembers) { // 未激活用户无法升级 if (AgentLevelEnum.ZERO_LEVEL.name().equals(member.getLevel())) { continue; } DataDictionaryCustom nextLevel = dataDictionaryCustomMapper.selectNextAgentLevelInfo(parent.getLevel()); if (nextLevel == null) { log.info("当前层级无下一级:{}", parent.getLevel()); continue; } AgentInfo agentInfo = JSONObject.parseObject(nextLevel.getValue(), AgentInfo.class); if (!directMemberCnt(parent, agentInfo)) { continue; } if (!agentCntFinish(parent, agentInfo)) { continue; } if (!teamIncome(parent, agentInfo)) { continue; } parent.setLevel(nextLevel.getCode()); memberMapper.updateById(parent); } } /** * 判断直推人数是否达标 * * @param member * @return */ private boolean directMemberCnt(MallMember member, AgentInfo agentInfo) { List childs = memberMapper.selectByRefererId(member.getInviteId()); if (CollUtil.isEmpty(childs)) { return false; } if (childs.size() >= agentInfo.getDirectCnt()) { return true; } log.info("用户:{}直推数量未达标, 当前等级:{}, 当前数量:{}, 目标数量:{}", member.getPhone(), member.getLevel(), childs.size(), agentInfo.getLastAgentCnt()); return false; } /** * 判断下级代理数量是否达标 * * @return */ private boolean agentCntFinish(MallMember member, AgentInfo agentInfo) { if (agentInfo.getLastAgentCnt() == null || agentInfo.getLastAgentCnt() == 0) { return true; } // 直推用户 List directMember = memberMapper.selectByRefererId(member.getInviteId()); if (CollUtil.isEmpty(directMember)) { return false; } // 用户团队达到指定代理数量,且都不在同一条线 int i = 0; for (MallMember child : directMember) { List mallMembers = memberMapper.selectChildAgentList(child.getInviteId(), member.getLevel()); if (CollUtil.isNotEmpty(mallMembers)) { i++; } } if (i >= agentInfo.getLastAgentCnt()) { return true; } log.info("用户:{}代理数量未达标, 当前等级:{}, 当前数量:{}, 目标数量:{}", member.getPhone(), member.getLevel(), i, agentInfo.getLastAgentCnt()); return false; } /** * 团队业绩是否达标 * * @param * @param agentInfo * @return */ private boolean teamIncome(MallMember member, AgentInfo agentInfo) { BigDecimal totalIncome = memberMapper.selectAchieveByMemberId(member.getInviteId(), 2); BigDecimal targetIncome = agentInfo.getTeamIncome().multiply(new BigDecimal("10000")); if (totalIncome.compareTo(targetIncome) >= 0) { return true; } log.info("用户:{}团队业绩未达标, 当前等级:{}, 当前数量:{}, 目标数量:{}", member.getPhone(), member.getLevel(), totalIncome, targetIncome); return false; } @Override @Transactional(rollbackFor = Exception.class) public void returnMoneyToAgent(Long orderId) { /** * 1、购买人获得固定比例的积分 * 2、直推获取8%的现金->余额,4%的积分->积分 * 3、不同代理级别获取不用的比例的现金和积分 * 4、董事享受全公司入单分红2%加权(现金) * 5、合伙人享全公司入单分红5%加权(现金) * 6、入单后,50%入现金池 35%的积分入积分池,更新价格 */ //获取当前订单子表信息 List mallOrderItemList = mallOrderItemMapper.selectbyOrderId(orderId); if(CollUtil.isEmpty(mallOrderItemList)){ return; } //获取订单中套餐的信息 List mallOrderItemIsTCs = mallOrderItemList.stream().filter(mallOrderItem -> mallOrderItem.getIsNormal() == 2).collect(Collectors.toList()); if(CollUtil.isEmpty(mallOrderItemIsTCs)){ return; } //获取订单中套餐总数金额 BigDecimal amountTC = mallOrderItemIsTCs.stream().map(MallOrderItem::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add); if(BigDecimal.ZERO.compareTo(amountTC) >= 0){ return; } MallOrderInfo mallOrderInfo = mallOrderInfoMapper.selectById(orderId); String orderNo = mallOrderInfo.getOrderNo(); //购买人 Long memberId = mallOrderInfo.getMemberId(); /** * 1、购买人获得固定比例的积分 * = amountTC * 固定比例 */ perkMember(memberId, PerkEnum.BUY_SET_MEAL_PERK_PERCENT, amountTC, "score", MoneyFlowTypeEnum.BUY_SET_MEAL_PERK.getValue(), memberId, FlowTypeEnum.SCORE.getValue(), orderNo); /** * 2、直推获取8%的现金->余额,4%的积分->积分 */ MallMember mallMember = mallMemberMapper.selectById(memberId); if(ObjectUtil.isNotEmpty(mallMember.getReferrerId())){ String referrerId = mallMember.getReferrerId(); MallMember mallMemberDirect = mallMemberMapper.selectInfoByInviteId(referrerId); Long directMemberId = mallMemberDirect.getId(); perkMember(directMemberId, PerkEnum.DIRECT_CASH_PERK_PERCENT, amountTC, "balance", MoneyFlowTypeEnum.DIRECT_CASH_PERK.getValue(), memberId, FlowTypeEnum.BALANCE.getValue(), orderNo); perkMember(directMemberId, PerkEnum.DIRECT_SCORE_PERK_PERCENT, amountTC, "score", MoneyFlowTypeEnum.DIRECT_SCORE_PERK.getValue(), memberId, FlowTypeEnum.SCORE.getValue(), orderNo); } /** * 4、董事享受全公司入单分红2%加权(现金) */ List mallMembersDirectors = mallMemberMapper.selectDirectorsOrStoreMaster(1); if(CollUtil.isNotEmpty(mallMembersDirectors)){ perkMembersLevel(mallMembersDirectors, PerkEnum.DIRECTOR_CASH_PERK_PERCENT, amountTC, "balance", MoneyFlowTypeEnum.DIRECTOR_CASH_PERK.getValue(), memberId, FlowTypeEnum.BALANCE.getValue(), orderNo); } /** * 5、合伙人享全公司入单分红5%加权(现金) */ List mallMemberPartners = mallMemberMapper.selectDirectorsOrStoreMaster(3); if(CollUtil.isNotEmpty(mallMemberPartners)){ perkMembersLevel(mallMemberPartners, PerkEnum.PARTNER_CASH_PERK_PERCENT, amountTC, "balance", MoneyFlowTypeEnum.PARTNER_CASH_PERK.getValue(), memberId, FlowTypeEnum.BALANCE.getValue(), orderNo); } /** * 3、团队下不同代理级别获取不用的比例的现金和积分 */ if(StrUtil.isNotEmpty(mallMember.getReferrerIds())){ //团队补贴对象 List mallMemberTeamPerk = new ArrayList<>(); String referrerIds = mallMember.getReferrerIds(); List referrerIdList = StrUtil.splitTrim(referrerIds, ","); if(CollUtil.isNotEmpty(referrerIdList)){ List mallMembers = mallMemberMapper.selectByInviteIds(referrerIdList); /** * 根据等级分组,获取对应的<级别,会员数组>map */ Map> collect = mallMembers.stream().collect(Collectors.groupingBy(MallMember::getLevel)); Set set = collect.keySet(); // 得到所有key的集合 for (String key : set) { /** * 团队补贴从v1到v6 */ int compareMin = MemberLevelEnum.V1.compareLevel(key, MemberLevelEnum.V1.getType()); int compareMax = MemberLevelEnum.V1.compareLevel(MemberLevelEnum.V6.getType(), key); if(compareMin >= 1 && compareMax >= 1){ List value = collect.get(key); mallMemberTeamPerk.add(value.get(0)); } } } if(CollUtil.isNotEmpty(mallMemberTeamPerk)){ String levelNormal = MemberLevelEnum.NORMAL.getType(); BigDecimal cashPercentNormal = BigDecimal.ZERO; BigDecimal scorePercentNormal = BigDecimal.ZERO; DataDictionaryCustom poolScorePriceDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode( PerkEnum.POOL_SCORE_PRICE.getType(), PerkEnum.POOL_SCORE_PRICE.getCode()); BigDecimal poolScorePrice = new BigDecimal(poolScorePriceDic.getValue() == null ? "1" : poolScorePriceDic.getValue()); for(MallMember teamPerkMember : mallMemberTeamPerk){ String level = teamPerkMember.getLevel(); //比较两个级别的大小,level大于levelNormal返回1 int compareLevel = MemberLevelEnum.V1.compareLevel(level, levelNormal); if(compareLevel == 1){ Long teamPerkMemberId = teamPerkMember.getId(); DataDictionaryCustom teamPerkMemberDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode( MemberLevelEnum.V1.getType(), level); AdminAgentInfo adminAgentInfo = JSONObject.parseObject(teamPerkMemberDic.getValue(), AdminAgentInfo.class); BigDecimal cashPercent = adminAgentInfo.getCashPercent().multiply(AppContants.PERCENTAGE); BigDecimal scorePercent = adminAgentInfo.getScorePercent().multiply(AppContants.PERCENTAGE); //极差 cashPercent = cashPercent.subtract(cashPercentNormal); scorePercent = scorePercent.subtract(scorePercentNormal); BigDecimal cashAmount = amountTC.multiply(cashPercent).setScale(2, BigDecimal.ROUND_DOWN); //如果是积分,除以当前价格,得到数量。 BigDecimal scoreCnt = amountTC.multiply(scorePercent).setScale(2, BigDecimal.ROUND_DOWN); scoreCnt = scoreCnt.divide(poolScorePrice, 2 ,BigDecimal.ROUND_DOWN); if(cashAmount.compareTo(BigDecimal.ZERO) > 0){ addWalletInfoAndMoneyFlow(cashAmount, teamPerkMemberId, "balance", MoneyFlowTypeEnum.AGENT_CASH_PERK.getValue(), memberId, FlowTypeEnum.BALANCE.getValue(), orderNo); } if(scoreCnt.compareTo(BigDecimal.ZERO) > 0){ addWalletInfoAndMoneyFlow(scoreCnt, teamPerkMemberId, "score", MoneyFlowTypeEnum.AGENT_SCORE_PERK.getValue(), memberId, FlowTypeEnum.SCORE.getValue(), orderNo); } levelNormal = level; cashPercentNormal = cashPercent; scorePercentNormal = scorePercent; } } } } /** * 6、入单后,50%入现金池 35%的积分入积分池,更新价格 */ DataDictionaryCustom poolCashPercentDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode( PerkEnum.POOL_CASH_PERCENT.getType(), PerkEnum.POOL_CASH_PERCENT.getCode()); DataDictionaryCustom poolScorePercentDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode( PerkEnum.POOL_SCORE_PERCENT.getType(), PerkEnum.POOL_SCORE_PERCENT.getCode()); if(ObjectUtil.isNotEmpty(poolCashPercentDic)){ BigDecimal poolCashPercent = new BigDecimal(poolCashPercentDic.getValue()).multiply(AppContants.PERCENTAGE); //新增现金数量 BigDecimal poolCashAdd = amountTC.multiply(poolCashPercent); DataDictionaryCustom poolCashDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode( PerkEnum.POOL_CASH.getType(), PerkEnum.POOL_CASH.getCode()); //当前现金池数量 BigDecimal poolCash = new BigDecimal(poolCashDic.getValue()); poolCash = poolCash.add(poolCashAdd).setScale(2,BigDecimal.ROUND_DOWN); dataDictionaryCustomMapper.updateDicValueByTypeAndCode( PerkEnum.POOL_CASH.getType(), PerkEnum.POOL_CASH.getCode(), poolCash.toString() ); DataDictionaryCustom poolScorePriceDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode( PerkEnum.POOL_SCORE_PRICE.getType(), PerkEnum.POOL_SCORE_PRICE.getCode()); BigDecimal poolScorePrice = new BigDecimal(poolScorePriceDic.getValue() == null ? "1" : poolScorePriceDic.getValue()); BigDecimal poolScorePercent = new BigDecimal(poolScorePercentDic.getValue()).multiply(AppContants.PERCENTAGE); //新增积分数量 BigDecimal poolScoreAdd = amountTC.multiply(poolScorePercent); poolScoreAdd = poolScoreAdd.divide(poolScorePrice,2,BigDecimal.ROUND_DOWN); DataDictionaryCustom poolScoreDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode( PerkEnum.POOL_SCORE.getType(), PerkEnum.POOL_SCORE.getCode()); //当前积分池数量 BigDecimal poolScore = new BigDecimal(poolScoreDic.getValue()); poolScore = poolScore.add(poolScoreAdd).setScale(2,BigDecimal.ROUND_DOWN); 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, 2, BigDecimal.ROUND_DOWN); dataDictionaryCustomMapper.updateDicValueByTypeAndCode( PerkEnum.POOL_SCORE_PRICE.getType(), PerkEnum.POOL_SCORE_PRICE.getCode(), divide.toString() ); } } } /** * 给某一个用户根据订单金额去加权平分 * @param memberId 用户ID * @param perkEnum 比例的枚举值 * @param amountTC 总金额 * @param walletField 类型:score:积分 balance:余额 * @param type 流水类型 * @param flowType 流水分类 * @param orderNo 订单编号 */ private void perkMember(Long memberId,PerkEnum perkEnum,BigDecimal amountTC,String walletField,int type,Long rtMemberId,int flowType,String orderNo){ DataDictionaryCustom perkEnumDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode( perkEnum.getType(), perkEnum.getCode()); if(ObjectUtil.isNotEmpty(perkEnumDic)){ BigDecimal perkEnumDicPercent = new BigDecimal(perkEnumDic.getValue() == null ? "0" : perkEnumDic.getValue()); //获得数量 BigDecimal perkEnumDicPercentPerk = perkEnumDicPercent.multiply(AppContants.PERCENTAGE).multiply(amountTC).setScale(2, BigDecimal.ROUND_DOWN); //如果是积分,除以当前价格,得到数量。 if(walletField.equals("score")){ DataDictionaryCustom poolScorePriceDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode( PerkEnum.POOL_SCORE_PRICE.getType(), PerkEnum.POOL_SCORE_PRICE.getCode()); BigDecimal poolScorePrice = new BigDecimal(poolScorePriceDic.getValue() == null ? "1" : poolScorePriceDic.getValue()); perkEnumDicPercentPerk = perkEnumDicPercentPerk.divide(poolScorePrice, 2 ,BigDecimal.ROUND_DOWN); } if(perkEnumDicPercentPerk.compareTo(BigDecimal.ZERO) > 0){ addWalletInfoAndMoneyFlow(perkEnumDicPercentPerk,memberId,walletField,type,rtMemberId,flowType,orderNo); } } } /** * 操作用户钱包数据,增加流水 * @param amount * @param memberId * @param walletField * @param type * @param flowType * @param orderNo */ private void addWalletInfoAndMoneyFlow(BigDecimal amount,Long memberId,String walletField,int type,Long rtMemberId,int flowType,String orderNo){ //增加 iApiMallMemberWalletService.add(amount,memberId,walletField); //增加一个流水记录 mallMoneyFlowService.addMoneyFlow( memberId, amount, type, orderNo, rtMemberId, flowType, AppContants.IS_RETURN_YES); } /** * 按照级别,根据订单金额去加权平分 * @param mallMembers 用户 * @param perkEnum 比例的枚举值 * @param amountTC 总金额 * @param walletField 类型:score:积分 balance:余额 * @param type 流水类型 * @param flowType 流水分类 * @param orderNo 订单编号 */ private void perkMembersLevel(List mallMembers,PerkEnum perkEnum,BigDecimal amountTC,String walletField,int type,Long rtMemberId,int flowType,String orderNo){ DataDictionaryCustom perkEnumDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode( perkEnum.getType(), perkEnum.getCode()); if(ObjectUtil.isNotEmpty(perkEnumDic)){ BigDecimal perkEnumDicPercent = new BigDecimal(perkEnumDic.getValue() == null ? "0" : perkEnumDic.getValue()); //获得的现金 BigDecimal perkEnumDicPercentPerkSum = perkEnumDicPercent.multiply(AppContants.PERCENTAGE).multiply(amountTC).setScale(2, BigDecimal.ROUND_DOWN); //然后董事平分 BigDecimal perkEnumDicPercentPerk = perkEnumDicPercentPerkSum.divide(new BigDecimal(mallMembers.size()), 2, BigDecimal.ROUND_DOWN); if(perkEnumDicPercentPerk.compareTo(BigDecimal.ZERO) > 0){ for(MallMember mallMember : mallMembers){ Long memberId = mallMember.getId(); addWalletInfoAndMoneyFlow(perkEnumDicPercentPerk,memberId,walletField,type,rtMemberId,flowType,orderNo); } } } } @Override public void rankReturnMoney(Long orderId) { } }