From e6667c792be898c41cda7d850dda02a403ef79c2 Mon Sep 17 00:00:00 2001 From: xiaoyong931011 <15274802129@163.com> Date: Thu, 06 Apr 2023 10:35:20 +0800 Subject: [PATCH] 关于积分凭证 --- src/main/java/cc/mrbird/febs/mall/service/impl/AgentServiceImpl.java | 293 +++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 files changed, 267 insertions(+), 26 deletions(-) diff --git a/src/main/java/cc/mrbird/febs/mall/service/impl/AgentServiceImpl.java b/src/main/java/cc/mrbird/febs/mall/service/impl/AgentServiceImpl.java index 3fce202..3bbfed9 100644 --- a/src/main/java/cc/mrbird/febs/mall/service/impl/AgentServiceImpl.java +++ b/src/main/java/cc/mrbird/febs/mall/service/impl/AgentServiceImpl.java @@ -1,15 +1,19 @@ package cc.mrbird.febs.mall.service.impl; import cc.mrbird.febs.common.enumerates.*; +import cc.mrbird.febs.common.utils.MallUtils; import cc.mrbird.febs.mall.entity.*; import cc.mrbird.febs.mall.mapper.*; import cc.mrbird.febs.mall.service.*; +import cc.mrbird.febs.mall.vo.AdminMallMoneyFlowVo; +import cc.mrbird.febs.mall.vo.AdminTeamEqualsPerkVo; import cc.mrbird.febs.system.mapper.UserMapper; import cn.hutool.core.collection.CollUtil; 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.QueryWrapper; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.ibatis.session.ExecutorType; @@ -21,10 +25,7 @@ import java.math.BigDecimal; import java.math.RoundingMode; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; /** @@ -45,6 +46,8 @@ private final MallMemberWalletMapper mallMemberWalletMapper; private final SqlSessionTemplate sqlSessionTemplate; private final IApiMallMemberWalletService memberWalletService; + private final MallMoneyFlowMapper mallMoneyFlowMapper; + private final MallMqRecordMapper mallMqRecordMapper; @Override @Transactional(rollbackFor = Exception.class) @@ -57,18 +60,20 @@ List<String> ids = StrUtil.split(member.getReferrerIds(), ','); List<MallMember> 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) { + //合伙人的下一个层级 + String parentLevel = parent.getLevel(); + String nextLevel = MemberLevelEnum.SECOND_LEVEL.getNextLevel(parentLevel); + if (parentLevel.equals(nextLevel)) { log.info("当前层级无下一级:{}", parent.getLevel()); continue; } - AgentInfo agentInfo = JSONObject.parseObject(nextLevel.getValue(), AgentInfo.class); + DataDictionaryCustom nextLevelDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode("AGENT_LEVEL_REQUIRE", nextLevel); + AgentInfo agentInfo = JSONObject.parseObject(nextLevelDic.getValue(), AgentInfo.class); if (!directMemberCnt(parent, agentInfo)) { continue; } @@ -81,7 +86,7 @@ continue; } - parent.setLevel(nextLevel.getCode()); + parent.setLevel(nextLevel); memberMapper.updateById(parent); } } @@ -102,7 +107,7 @@ return true; } - log.info("用户:{}直推数量未达标, 当前等级:{}, 当前数量:{}, 目标数量:{}", member.getPhone(), member.getLevel(), childs.size(), agentInfo.getLastAgentCnt()); + log.info("用户:{}直推数量未达标, 当前等级:{}, 当前数量:{}, 目标数量:{}", member.getPhone(), member.getLevel(), childs.size(), agentInfo.getDirectCnt()); return false; } @@ -140,20 +145,24 @@ } /** - * 团队业绩是否达标 + * 团队贡献点是否达标 * * @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) { + List<MallMember> mallMembers = memberMapper.selectAllChildAgentListByInviteId(member.getInviteId()); + List<Long> ids = mallMembers.stream().map(MallMember::getId).collect(Collectors.toList()); + List<MallMemberWallet> mallMemberWallets = mallMemberWalletMapper.selectMemberWalletsByIds(ids); + + int starSum = mallMemberWallets.stream().mapToInt(MallMemberWallet::getStar).sum(); + BigDecimal teamIncome = agentInfo.getTeamIncome(); + if (teamIncome.compareTo(new BigDecimal(starSum)) <= 0) { return true; } - log.info("用户:{}团队业绩未达标, 当前等级:{}, 当前数量:{}, 目标数量:{}", member.getPhone(), member.getLevel(), totalIncome, targetIncome); + log.info("用户:{}团队贡献点未达标, 当前等级:{}, 当前数量:{}, 目标数量:{}", member.getPhone(), member.getLevel(), starSum, teamIncome); return false; } @@ -170,6 +179,7 @@ @Override @Transactional(rollbackFor = Exception.class) public void perkMoneyConsumer(long orderId) { + long start = System.currentTimeMillis(); MallOrderInfo mallOrderInfo = mallOrderInfoMapper.selectById(orderId); if(ObjectUtil.isEmpty(mallOrderInfo)){ return; @@ -180,7 +190,7 @@ /** * 分享补贴 直推消费额10% */ - BigDecimal amount = mallOrderInfo.getAmount(); + BigDecimal amount = mallOrderInfo.getAmount().subtract(mallOrderInfo.getScoreAmount()); Long memberId = mallOrderInfo.getMemberId(); MallMember mallMember = memberMapper.selectById(memberId); @@ -194,7 +204,7 @@ String sharePerk = ObjectUtil.isEmpty(sharePerkDic.getValue()) ? "0" : sharePerkDic.getValue(); BigDecimal sharePerkPercent = new BigDecimal(sharePerk).abs().divide(new BigDecimal(100)); //分享补贴金额 - BigDecimal sharePerkAmount = amount.multiply(sharePerkPercent); + BigDecimal sharePerkAmount = amount.multiply(sharePerkPercent).setScale(2, BigDecimal.ROUND_DOWN);; //所有合伙人补贴至消费礼包的三倍额度需要复购一次。 MallMemberWallet mallMemberWallet = mallMemberWalletMapper.selectWalletByMemberId(mallMemberUp.getId()); @@ -204,16 +214,23 @@ } if(BigDecimal.ZERO.compareTo(sharePerkAmount) < 0){ //减少补贴额度 - memberWalletService.reduce(sharePerkAmount, memberId, "totalScore"); + mallMemberWalletMapper.reduceTotalScoreById(sharePerkAmount, mallMemberWallet.getId()); - iApiMallMemberWalletService.addBalance(sharePerkAmount, mallMemberUp.getId()); + reduceStar(mallMemberUp.getId(),sharePerkAmount); + + mallMemberWalletMapper.addBalanceById(sharePerkAmount, mallMemberWallet.getId()); mallMoneyFlowService.addMoneyFlow( mallMemberUp.getId(), sharePerkAmount, MoneyFlowTypeEnum.DYNAMIC_ACHIEVE.getValue(), mallOrderInfo.getOrderNo(), - FlowTypeEnum.BALANCE.getValue()); + "直推奖", + "补贴额度:"+totalScore, + memberId, + 2, + FlowTypeEnum.BALANCE.getValue(), + 1); } } /** @@ -228,10 +245,95 @@ List<MallMember> thirdLevelRecord = getStarRecord(fourLevelRecord, MemberLevelEnum.THIRD_LEVEL.name(), amount, mallOrderInfo.getOrderNo(), memberId,MoneyFlowTypeEnum.STAR_PERK_THREE.getValue()); List<MallMember> secondLevelRecord = getStarRecord(thirdLevelRecord, MemberLevelEnum.SECOND_LEVEL.name(), amount, mallOrderInfo.getOrderNo(), memberId,MoneyFlowTypeEnum.STAR_PERK_TWO.getValue()); + /** + * 团队补贴 + */ + //团队补贴百分比 + DataDictionaryCustom teamPerkDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode( + DataDictionaryEnum.TEAM_PERK.getType(), + DataDictionaryEnum.TEAM_PERK.getCode()); + String teamPerk = ObjectUtil.isEmpty(teamPerkDic.getValue()) ? "0" : teamPerkDic.getValue(); + BigDecimal teamPerkPercent = new BigDecimal(teamPerk).abs().divide(new BigDecimal(100)); + //分享补贴金额 + BigDecimal teamPerkAmount = amount.multiply(teamPerkPercent); + //团队补贴对象 + List<MallMember> mallMemberTeamPerkList = mallMemberTeamPerkListInfo(memberId); + if(CollUtil.isNotEmpty(mallMemberTeamPerkList)){ + List<Long> mallMemberTeamPerkIds = mallMemberTeamPerkList.stream().map(MallMember::getId).collect(Collectors.toList()); + List<MallMemberWallet> mallMemberWallets = mallMemberWalletMapper.selectMemberWalletsByIds(mallMemberTeamPerkIds); + flowTotalScoreBalance( + mallMemberWallets, + teamPerkAmount, + MoneyFlowTypeEnum.TEAM_PERK.getValue(), + mallOrderInfo.getOrderNo(), + memberId + ); + } + + long end = System.currentTimeMillis(); + log.info("============订单:{},时间:{}===========",mallOrderInfo.getOrderNo(),(end - start)/1000); + MallMqRecord mallMqRecord = mallMqRecordMapper.selectByOrderId(orderId); + if(ObjectUtil.isNotEmpty(mallMqRecord)){ + mallMqRecord.setState(1); + mallMqRecordMapper.updateById(mallMqRecord); + } } /** - * + * 下单人所在团队里面的已经存在的各个等级的会员集合里面的第一个会员获取2% + */ + public List<MallMember> mallMemberTeamPerkListInfo(Long memberId){ + List<MallMember> mallMemberTeamPerk = new ArrayList<>(); + MallMember mallMember = memberMapper.selectById(memberId); + List<String> ids = StrUtil.split(mallMember.getReferrerIds(), ','); + if(CollUtil.isNotEmpty(ids)){ + List<MallMember> mallMembers = memberMapper.selectByInviteIds(ids); + /** + * 根据等级分组,获取对应的<级别,会员数组>map + */ + Map<String, List<MallMember>> collect = mallMembers.stream().collect(Collectors.groupingBy(MallMember::getLevel)); + Set<String> set = collect.keySet(); // 得到所有key的集合 + for (String key : set) { + /** + * 团队补贴从二星开始 + */ + int compareLevel = MemberLevelEnum.SECOND_LEVEL.compareLevel(key, MemberLevelEnum.SECOND_LEVEL.getType()); + if(compareLevel > 0){ + List<MallMember> value = collect.get(key); + mallMemberTeamPerk.add(value.get(0)); + } + } + } + + return mallMemberTeamPerk; + } + /** + * 递归获取对应的团队补贴对象 + * 下单 + * 下单人的上级集合里面每个等级的第一个会员 + * @param memberId + * @param mallMemberTeamPerk + * @return + */ + public List<MallMember> mallMemberTeamPerkList(Long memberId,List<MallMember> mallMemberTeamPerk){ + MallMember mallMember = memberMapper.selectById(memberId); + if(ObjectUtil.isEmpty(mallMember.getReferrerId())){ + return mallMemberTeamPerk; + } + String referrerId = mallMember.getReferrerId(); + MallMember mallMemberParent = memberMapper.selectInfoByInviteId(referrerId); + + if(MemberLevelEnum.SECOND_LEVEL.compareLevel(mallMemberParent.getLevel(),mallMember.getLevel()) > 0){ + mallMemberTeamPerk.add(mallMemberParent); + } + if(!referrerId.equals(mallMember.getInviteId())){ + mallMemberTeamPerkList(mallMemberParent.getId(),mallMemberTeamPerk); + } + return mallMemberTeamPerk; + } + + /** + * 星级奖励 * @param mallMembersOlds 高一级别的用户 * @param LevelParam 当前级别 * @param amount 补贴金额的基数 @@ -240,7 +342,7 @@ * @return */ public List<MallMember> getStarRecord(List<MallMember> mallMembersOlds,String LevelParam,BigDecimal amount,String orderNo,Long memberId,int starPerkType){ - long start = System.currentTimeMillis(); + //根据用户的level获取用户 List<MallMember> mallMemberStars = memberMapper.selectMemberWithLevel(LevelParam); if(CollUtil.isNotEmpty(mallMembersOlds)){ @@ -251,9 +353,17 @@ if(CollUtil.isNotEmpty(mallMemberStars)){ List<Long> mallMemberStarIds = mallMemberStars.stream().map(MallMember::getId).collect(Collectors.toList()); + //排除掉本身 + mallMemberStarIds.remove(memberId); + if(CollUtil.isEmpty(mallMemberStarIds)){ + return mallMemberStars; + } //当前等级的总贡献点 - List<MallMemberWallet> mallMemberWallets = mallMemberWalletMapper.selectSumStarByIds(mallMemberStarIds); + List<MallMemberWallet> mallMemberWallets = mallMemberWalletMapper.selectMemberWalletsByIds(mallMemberStarIds); Integer starSum = mallMemberWallets.stream().mapToInt(MallMemberWallet::getStar).sum(); + if(starSum <= 0){ + return mallMemberStars; + } //星级补贴比例 DataDictionaryCustom starPerkDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode( "AGENT_LEVEL_REQUIRE", @@ -298,8 +408,11 @@ mallMoneyFlow.setOrderNo(orderNo); mallMoneyFlow.setRtMemberId(memberId); mallMoneyFlow.setStatus(2); + mallMoneyFlow.setRemark("补贴额度:"+mallMemberWallet.getTotalScore()); mallMoneyFlow.setFlowType(FlowTypeEnum.BALANCE.getValue()); mallMoneyFlows.add(mallMoneyFlow); + + reduceStar(mallMemberWallet.getMemberId(),starPerkAmount); } count = count + 1; if (count % 1000 == 0 || count == mallMemberWallets.size()) { @@ -336,8 +449,136 @@ } } } - long end = System.currentTimeMillis(); - log.info("============订单:{},时间:{}===========",orderNo,(end - start)/1000); return mallMemberStars; } + + /** + * 统一处理补贴,流水,余额 + * 增加的余额是一样的 + * @param mallMemberWallets + * @param amount + * @param flowType + * @param orderNo + * @param memberId + */ + @Override + public void flowTotalScoreBalance(List<MallMemberWallet> mallMemberWallets,BigDecimal amount,int flowType,String orderNo,Long memberId){ + //给当前等级的每个用户发放星级奖励 + int count = 0; + List<Map<String,Object>> result = new ArrayList<>(); + List<Map<String,Object>> resultReduce = new ArrayList<>(); + List<MallMoneyFlow> mallMoneyFlows = new ArrayList<>(); + for(MallMemberWallet mallMemberWallet : mallMemberWallets){ + Map<String,Object> hashMap = new HashMap<>(); + BigDecimal totalScorePerk = mallMemberWallet.getTotalScore(); + if(totalScorePerk.compareTo(amount) < 0){ + amount = totalScorePerk; + } + if(BigDecimal.ZERO.compareTo(amount) < 0){ + hashMap.put("id",mallMemberWallet.getId()); + hashMap.put("starPerkAmount",amount); + result.add(hashMap); + resultReduce.add(hashMap); + //生成星级奖励的流水对象 + MallMoneyFlow mallMoneyFlow = new MallMoneyFlow(); + mallMoneyFlow.setMemberId(mallMemberWallet.getMemberId()); + mallMoneyFlow.setAmount(amount); + mallMoneyFlow.setType(flowType); + mallMoneyFlow.setOrderNo(orderNo); + mallMoneyFlow.setRtMemberId(memberId); + mallMoneyFlow.setStatus(2); + mallMoneyFlow.setRemark("补贴额度:"+mallMemberWallet.getTotalScore()); + mallMoneyFlow.setFlowType(FlowTypeEnum.BALANCE.getValue()); + mallMoneyFlows.add(mallMoneyFlow); + + reduceStar(mallMemberWallet.getMemberId(),amount); + + } + count = count + 1; + if (count % 1000 == 0 || count == mallMemberWallets.size()) { + if(CollUtil.isNotEmpty(result)){ + int resultCount = mallMemberWalletMapper.updateStarByList(result); + if(resultCount>0){ + log.info("============余额新增============第{}条数据===========",resultCount); + } + //每更新完一批数据,在result内进行删除操作。 + result.clear(); + + int resultReduceCount = mallMemberWalletMapper.updateTotalScoreByList(resultReduce); + if(resultReduceCount>0){ + log.info("============额度减少============第{}条数据===========",resultReduceCount); + } + //每更新完一批数据,在result内进行删除操作。 + resultReduce.clear(); + } + } + } + if(CollUtil.isNotEmpty(mallMoneyFlows)){ + SqlSession sqlSession = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH,false); + MallMoneyFlowMapper mallMoneyFlowMapper = sqlSession.getMapper(MallMoneyFlowMapper.class); + + for(int i = 1; i <= mallMoneyFlows.size(); i++){ + mallMoneyFlowMapper.insertMoneyFlow(mallMoneyFlows.get(i-1)); + if (i % 1000 == 0 || i == mallMoneyFlows.size()) { + log.info("============插入流水============第{}条数据===========",mallMoneyFlows.size()); + sqlSession.commit(); + sqlSession.clearCache(); + } + } + sqlSession.close(); + } + } + + @Override + public void reduceStar(Long memberId,BigDecimal totalScore) { + /** + *获取用户的全部未用完的补贴额度流水 + */ + MallMemberWallet mallMemberWallet = mallMemberWalletMapper.selectWalletByMemberId(memberId); + List<MallMoneyFlow> mallMoneyFlows = mallMoneyFlowMapper.selectMoneyFlowByMemberIdAndIsRetrun(memberId,2); + //如果补贴额度全部用完则更新用户的贡献点为零 + if(CollUtil.isEmpty(mallMoneyFlows)){ + mallMemberWalletMapper.reduceStarByMemberId(mallMemberWallet.getStar(), memberId); + return; + } + for(MallMoneyFlow mallMoneyFlow : mallMoneyFlows){ + String remark = mallMoneyFlow.getRemark(); + BigDecimal remarkNum = new BigDecimal(remark); + //如果补贴额度小于记录的剩余补贴额度 + if(totalScore.compareTo(remarkNum) < 0){ + remarkNum = remarkNum.subtract(totalScore).setScale(2,BigDecimal.ROUND_DOWN); + mallMoneyFlowMapper.updateRemarkById(remarkNum.toString(),mallMoneyFlow.getId()); + break; + } + //如果补贴额度等于等于记录的剩余补贴额度 + if(totalScore.compareTo(remarkNum) == 0){ + remarkNum = remarkNum.subtract(totalScore).setScale(2,BigDecimal.ROUND_DOWN); + mallMoneyFlowMapper.updateRemarkAndIsReturnById(remarkNum.toString(),mallMoneyFlow.getId()); + + //减少用户的贡献点 + String orderNo = mallMoneyFlow.getOrderNo(); + MallMoneyFlow mallMoneyFlowStar = mallMoneyFlowMapper.selectByOrderNoAndMemberId(orderNo,memberId,2); + BigDecimal amount = mallMoneyFlowStar.getAmount(); + mallMemberWalletMapper.reduceStarByMemberId(amount.intValue(), memberId); + //更新记录的返利状态为已返利 + mallMoneyFlowMapper.updateRemarkAndIsReturnById("0",mallMoneyFlowStar.getId()); + break; + } + //如果补贴额度大于记录的剩余补贴额度 + if(totalScore.compareTo(remarkNum) > 0){ + mallMoneyFlowMapper.updateRemarkAndIsReturnById("0",mallMoneyFlow.getId()); + + //减少用户的贡献点 + String orderNo = mallMoneyFlow.getOrderNo(); + MallMoneyFlow mallMoneyFlowStar = mallMoneyFlowMapper.selectByOrderNoAndMemberId(orderNo,memberId,2); + BigDecimal amount = mallMoneyFlowStar.getAmount(); + mallMemberWalletMapper.reduceStarByMemberId(amount.intValue(), memberId); + //更新记录的返利状态为已返利 + mallMoneyFlowMapper.updateRemarkAndIsReturnById("0",mallMoneyFlowStar.getId()); + totalScore = totalScore.subtract(remarkNum); + } + } + } + + } -- Gitblit v1.9.1