package cc.mrbird.febs.dapp.service.impl; import cc.mrbird.febs.common.contants.AppContants; import cc.mrbird.febs.common.utils.LoginUserUtil; import cc.mrbird.febs.common.utils.RedisUtils; import cc.mrbird.febs.dapp.dto.SystemDto; import cc.mrbird.febs.dapp.entity.*; import cc.mrbird.febs.dapp.enumerate.*; import cc.mrbird.febs.dapp.mapper.*; import cc.mrbird.febs.dapp.service.DappSystemService; import cc.mrbird.febs.dapp.service.DappWalletService; import cc.mrbird.febs.rabbit.producer.ChainProducer; import cc.mrbird.febs.tree.MatrixTree; import cc.mrbird.febs.tree.MemberNode; import cc.mrbird.febs.tree.TreeConstants; import cn.hutool.core.collection.CollUtil; 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 com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 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 * @date 2022-03-24 **/ @Slf4j @Service @RequiredArgsConstructor public class DappSystemServiceImpl implements DappSystemService { private final DappSystemDao dappSystemDao; private final RedisUtils redisUtils; private final DappFundFlowDao dappFundFlowDao; private final DappMemberDao dappMemberDao; private final DappStorageMapper dappStorageMapper; private final DappAchieveTreeDao dappAchieveTreeDao; private final DappAchieveMemberTreeDao dappAchieveMemberTreeDao; private final DappWalletService dappWalletService; private final DataDictionaryCustomMapper dataDictionaryCustomMapper; private final DbMemberNodeMapper dbMemberNodeMapper; private final ChainProducer chainProducer; @Override public SystemDto system() { DappMemberEntity member = LoginUserUtil.getAppUser(); SystemDto system = new SystemDto(); system.setBuyAmount(new BigDecimal("100")); return system; } @Override @Transactional(rollbackFor = Exception.class) public synchronized void achieveTree(Long memberId) { DappMemberEntity member = dappMemberDao.selectById(memberId); if(ObjectUtil.isEmpty(member)){ return; } int batchNo = 0; DappAchieveTreeEntity newestTreeNode = dappAchieveTreeDao.selectNewestTreeNode(); if (newestTreeNode != null) { if (newestTreeNode.getValidState() == 2) { batchNo = newestTreeNode.getBatchNo() + 1; } else { batchNo = newestTreeNode.getBatchNo(); } } // 在大树中,插入当前节点 DappAchieveTreeEntity achieveTree = new DappAchieveTreeEntity(); achieveTree.setMidNode(memberId); achieveTree.setValidState(1); achieveTree.setBatchNo(batchNo); dappAchieveTreeDao.insert(achieveTree); // 在内存树(大树)中插入当前节点,并返回父节点 MemberNode node = new MemberNode(member.getId(), member.getAddress(), member.getInviteId(), member.getRefererId()); MatrixTree tree = MatrixTree.getInstance(); MemberNode exist = tree.getNode(member.getId()); if (exist != null) { return; } MemberNode parentNode = tree.addNode(node); // 创建该节点的矩阵 DappAchieveMemberTreeEntity achieveMemberTree = new DappAchieveMemberTreeEntity(); achieveMemberTree.setTreeNode(memberId); achieveMemberTree.setTopNode(memberId); achieveMemberTree.setDeep(1); achieveMemberTree.setHasMoney(1); if (parentNode != null) { achieveMemberTree.setParentNode(parentNode.getMemberId()); } dappAchieveMemberTreeDao.insert(achieveMemberTree); // 激活用户状态 // member.setActiveStatus(1); // dappMemberDao.updateById(member); // dappMemberDao.updateMemberActiveV2(member.getId()); // putIntoProfit(memberId, 2); if (parentNode == null) { return; } // 修改父节点在数据库中的左/右节点数据 DappAchieveTreeEntity treeMidNode = dappAchieveTreeDao.selectByMidNode(parentNode.getMemberId()); boolean isLeft = false; if (parentNode.getLeft() != null && memberId.equals(parentNode.getLeft().getMemberId())) { treeMidNode.setLeftNode(memberId); isLeft = true; } else { treeMidNode.setRightNode(memberId); } dappAchieveTreeDao.updateById(treeMidNode); // 更新矩阵中的数据 List matrixNodes = dappAchieveMemberTreeDao.selectNotBottomNodeInMatrix(parentNode.getMemberId()); for (DappAchieveMemberTreeEntity matrixNode : matrixNodes) { if (isLeft) { matrixNode.setLeftNode(memberId); } else { matrixNode.setRightNode(memberId); } dappAchieveMemberTreeDao.updateById(matrixNode); DappAchieveMemberTreeEntity newMatrixNode = new DappAchieveMemberTreeEntity(); newMatrixNode.setTreeNode(memberId); newMatrixNode.setTopNode(matrixNode.getTopNode()); newMatrixNode.setParentNode(parentNode.getMemberId()); newMatrixNode.setHasMoney(1); newMatrixNode.setDeep(matrixNode.getDeep() + 1); dappAchieveMemberTreeDao.insert(newMatrixNode); if (matrixNode.getDeep() == 2) { finishMatrixTree(matrixNode.getTopNode()); } } } @Override public void achieveTreeV2(Long fundId) { DappFundFlowEntity dappFundFlowEntity = dappFundFlowDao.selectById(fundId); if(ObjectUtil.isEmpty(dappFundFlowEntity)){ return; } Integer status = dappFundFlowEntity.getStatus(); if(2 != status){ return; } Long memberId = dappFundFlowEntity.getMemberId(); DappMemberEntity member = dappMemberDao.selectById(memberId); if(ObjectUtil.isEmpty(member)){ return; } BigDecimal amount = dappFundFlowEntity.getAmount(); //存放买入新团的类型 String toHash = dappFundFlowEntity.getToHash(); //根据金额判断属于属于购买的哪一个节点 NodeType nodeType = NodeType.NODE_1.getNode(Integer.parseInt(toHash)); if(ObjectUtil.isEmpty(nodeType)){ return; } /** * 获取一条最老的左右节点未满的记录 * 然后生成一条新的记录 * 如果添加的为左节点,那么没人出局 * 如果添加的为右节点,那么进入判断 * 1、父节点为左节点,那么没人出局 * 2、父节点为右节点,那么进入判断,父节点是否有上级节点 * 1、有,则上级节点出局复投,轮数加1,复投逻辑 * */ //获取一条最老的左右节点未满且生效中的记录 DbMemberNode dbMemberNodeOld = dbMemberNodeMapper.selectOneByWorkStateAndLeftNodeNullOrRightNodeNull(DbMemberNode.STATE_ONE,nodeType.getNodeType()); if(ObjectUtil.isEmpty(dbMemberNodeOld)){ //生成ROOT节点 DbMemberNode root = new DbMemberNode(); root.setMemberId(memberId); root.setFundId(fundId); root.setAmount(new BigDecimal(nodeType.getNodeAmount())); root.setType(nodeType.getNodeType()); root.setCountFund(1); root.setPerkState(1); root.setWorkState(1); dbMemberNodeMapper.insert(root); return; } //然后生成一条新的记录 DbMemberNode dbMemberNode = new DbMemberNode(); dbMemberNode.setMemberId(memberId); dbMemberNode.setFundId(fundId); dbMemberNode.setAmount(new BigDecimal(nodeType.getNodeAmount())); dbMemberNode.setType(nodeType.getNodeType()); dbMemberNode.setCountFund(1); dbMemberNode.setPerkState(1); dbMemberNode.setLeftRight(ObjectUtil.isEmpty(dbMemberNodeOld.getLeftNode()) ? 1 : 2); dbMemberNode.setParentNode(dbMemberNodeOld.getId()); dbMemberNode.setWorkState(1); dbMemberNodeMapper.insert(dbMemberNode); /** * 判断你的上级是否满足复投条件 */ DappMemberEntity dappMemberEntityDirect = dappMemberDao.selectMemberInfoByInviteId(member.getRefererId()); if(ObjectUtil.isNotEmpty(dappMemberEntityDirect)){ Long id = dappMemberEntityDirect.getId(); // chainProducer.sendNodeMsgLong(id); } //如果添加的为右节点,那么进入判断 if(DbMemberNode.STATE_TWO == dbMemberNode.getLeftRight()){ //更新父节点的右节点 dbMemberNodeOld.setRightNode(dbMemberNode.getId()); dbMemberNodeMapper.updateById(dbMemberNodeOld); //父节点为右节点,那么进入判断,父节点是否有上级节点 int leftRight = ObjectUtil.isEmpty(dbMemberNodeOld.getLeftRight()) ? 1 : dbMemberNodeOld.getLeftRight(); if(DbMemberNode.STATE_TWO == leftRight){ if(ObjectUtil.isEmpty(dbMemberNodeOld.getParentNode())){ return; } Long parentNode = dbMemberNodeOld.getParentNode(); DbMemberNode dbMemberNodeRoot = dbMemberNodeMapper.selectById(parentNode); if(ObjectUtil.isEmpty(dbMemberNodeRoot)){ return; } //每个星团,只复投10轮 if(10 < dbMemberNodeRoot.getCountFund()){ return; } //有,则上级节点出局复投,轮数加1,复投逻辑 this.memberNodeNext(dbMemberNodeRoot); }else{//父节点为左节点,那么没人出局 return; } }else{ //更新父节点的左节点 dbMemberNodeOld.setLeftNode(dbMemberNode.getId()); dbMemberNodeMapper.updateById(dbMemberNodeOld); //如果添加的为左节点,那么没人出局 return; } } /** * 有,则上级节点出局复投,轮数加1,复投逻辑 * @param dbMemberNodeRoot */ @Override public void memberNodeNext(DbMemberNode dbMemberNodeRoot) { log.info("进入复投"); DataDictionaryCustom inviteNumDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode( DataDictionaryEnum.INVITE_NUM.getType(), DataDictionaryEnum.INVITE_NUM.getCode() ); int inviteNum = Integer.parseInt(inviteNumDic.getValue()); Long memberId = dbMemberNodeRoot.getMemberId(); DappMemberEntity dappMemberEntity = dappMemberDao.selectById(memberId); //必须要有两个直推才能复投,或者获取收益,否则,直接返回 QueryWrapper inviteQuery = new QueryWrapper<>(); inviteQuery.eq("referer_id",dappMemberEntity.getInviteId()); List dappMemberEntities = dappMemberDao.selectList(inviteQuery); if(CollUtil.isEmpty(dappMemberEntities)){ return; } if(inviteNum > dappMemberEntities.size()){ return; } List collect = dappMemberEntities.stream().map(DappMemberEntity::getId).collect(Collectors.toList()); QueryWrapper inviteNodeQuery = new QueryWrapper<>(); inviteNodeQuery.select("member_id"); inviteNodeQuery.eq("work_state", DbMemberNode.STATE_ONE); inviteNodeQuery.in("member_id",collect); inviteNodeQuery.groupBy("member_id"); List inviteNodes = dbMemberNodeMapper.selectList(inviteNodeQuery); if(CollUtil.isEmpty(inviteNodes)){ return; } if(inviteNum > inviteNodes.size()){ return; } //任何星级的原来节点都要出局 dbMemberNodeRoot.setWorkState(DbMemberNode.STATE_TWO); dbMemberNodeMapper.updateById(dbMemberNodeRoot); //任何星级,10轮,收益本金都返回 Integer countFund = dbMemberNodeRoot.getCountFund(); //收益 BigDecimal perkAmount = dbMemberNodeRoot.getAmount().multiply(new BigDecimal("1.4")); if(10 == countFund){//任何星级,10轮,收益本金都返回 BigDecimal add = dbMemberNodeRoot.getAmount().add(perkAmount); perkSevenTeen(memberId,add,countFund); return; }else if(10 < countFund){ return; }else{ //复投 Integer type = dbMemberNodeRoot.getType(); Integer countFundNext = countFund + 1; QueryWrapper nodeQueryWrapper = new QueryWrapper<>(); nodeQueryWrapper.eq("member_id",memberId); nodeQueryWrapper.eq("type", type); nodeQueryWrapper.eq("count_fund", countFundNext); DbMemberNode dbMemberNode = dbMemberNodeMapper.selectOne(nodeQueryWrapper); if(ObjectUtil.isNotEmpty(dbMemberNode)){ return; } futouSixTeen(memberId,dbMemberNodeRoot.getAmount(),type,countFundNext); //产生收益 perkSevenTeen(memberId,perkAmount,countFund); return; // Integer type = dbMemberNodeRoot.getType(); // //如果是13星局,则直接复投产生收益 // if(NodeType.NODE_13.getNodeType() == type){ // //复投 // futouSixTeen(memberId,dbMemberNodeRoot.getAmount(),type,countFund+1); // //产生收益 // perkSevenTeen(memberId,perkAmount,countFund); // return; // } // //如果是1到12星团 // if(type >=NodeType.NODE_1.getNodeType() && type <= NodeType.NODE_12.getNodeType()){ // //需要复投本轮, // //如果是第一轮,当下一个星团没有投入时,收益复投下一个新团 // //如果是第一轮,下一个新团有投入,则产生收益 // //复投或者收益的金额 // if(1 == countFund){//第一轮 // //收益复投(当前的下一个星团没有已投入),还是收益提出 // Integer nextType = type + 1; // QueryWrapper nodeQueryWrapper = new QueryWrapper<>(); // nodeQueryWrapper.eq("member_id",memberId); // nodeQueryWrapper.eq("type", nextType); // nodeQueryWrapper.eq("work_state", DbMemberNode.STATE_ONE); // DbMemberNode dbMemberNode = dbMemberNodeMapper.selectOne(nodeQueryWrapper); // if(ObjectUtil.isEmpty(dbMemberNode)){ // futouSixTeen(memberId,perkAmount,nextType,1); // }else{ // perkSevenTeen(memberId,perkAmount,countFund); // } // //复投本轮,轮数 +1 // futouSixTeen(memberId,dbMemberNodeRoot.getAmount(),type,countFund+1); // }else{//2-9轮 // //复投本轮,轮数 +1 // futouSixTeen(memberId,dbMemberNodeRoot.getAmount(),type,countFund+1); // perkSevenTeen(memberId,perkAmount,countFund); // } // } } } /** * 产生收益 * @param memberId 会员ID * @param amount 收益金额 * @param countFund 轮数 */ public void perkSevenTeen(Long memberId,BigDecimal amount,Integer countFund){ //收益流水 DappFundFlowEntity fundFlow = new DappFundFlowEntity( memberId, amount, 17, 2, BigDecimal.ZERO, countFund.toString()); dappFundFlowDao.insert(fundFlow); //更新用户的金额 dappWalletService.updateWalletCoinWithLock(amount, memberId, 1); } /** * 复投本轮 * 插入流水,产生记录 * @param memberId 会员ID * @param amount 复投金额 * @param type 星团类型 * @param countFund 轮数 */ public void futouSixTeen(Long memberId,BigDecimal amount,Integer type,Integer countFund){ //复投流水 DappFundFlowEntity fundFlow = new DappFundFlowEntity( memberId, amount, 16, 2, BigDecimal.ZERO, null); dappFundFlowDao.insert(fundFlow); DbMemberNode dbMemberNodeOld = dbMemberNodeMapper.selectOneByWorkStateAndLeftNodeNullOrRightNodeNull(DbMemberNode.STATE_ONE,type); //复投 DbMemberNode dbMemberNode = new DbMemberNode(); dbMemberNode.setMemberId(memberId); dbMemberNode.setFundId(fundFlow.getId()); dbMemberNode.setAmount(amount); dbMemberNode.setType(type); dbMemberNode.setCountFund(countFund); dbMemberNode.setPerkState(1); if(ObjectUtil.isNotEmpty(dbMemberNodeOld)){ dbMemberNode.setLeftRight(ObjectUtil.isEmpty(dbMemberNodeOld.getLeftNode()) ? 1 : 2); dbMemberNode.setParentNode(dbMemberNodeOld.getId()); } dbMemberNode.setWorkState(1); dbMemberNodeMapper.insert(dbMemberNode); boolean flag = false;//下一级的再次复投 if(ObjectUtil.isNotEmpty(dbMemberNodeOld)){ if(dbMemberNode.getLeftRight() == 1){ dbMemberNodeOld.setLeftNode(dbMemberNode.getId()); }else{ dbMemberNodeOld.setRightNode(dbMemberNode.getId()); flag = true; } dbMemberNodeMapper.updateById(dbMemberNodeOld); } if(flag){ if(ObjectUtil.isEmpty(dbMemberNodeOld.getParentNode())){ return; } Long parentNode = dbMemberNodeOld.getParentNode(); DbMemberNode dbMemberNodeRoot = dbMemberNodeMapper.selectById(parentNode); if(ObjectUtil.isEmpty(dbMemberNodeRoot)){ return; } if(dbMemberNodeRoot.getLeftRight() == 1){ return; } //每个星团,只复投10轮 if(10 < dbMemberNodeRoot.getCountFund()){ return; } this.memberNodeNext(dbMemberNodeRoot); } } // 完成矩阵树,并重置矩阵且重入 public void finishMatrixTree(Long memberId) { List matrixTree = dappAchieveMemberTreeDao.selectMatrixTreeByTopNode(memberId, 1); // 如果达到标准,则重置该矩阵树 if (matrixTree.size() == 7) { dappAchieveMemberTreeDao.resetMatrixTree(memberId); dappAchieveMemberTreeDao.reentryMoney(memberId); putIntoProfit(memberId, 1); DappAchieveMemberTreeEntity bottomNode = dappAchieveMemberTreeDao.selectNodeByDeep(memberId, 3); if (bottomNode != null) { finishMatrixTree(bottomNode.getTopNode()); } } } @Override public void putIntoProfit(Long memberId, int isReIn) { DappMemberEntity member = dappMemberDao.selectById(memberId); DappMemberEntity parent = dappMemberDao.selectMemberInfoByInviteId(member.getRefererId()); if (parent != null) { BigDecimal directProfit = TreeConstants.PUT_IN_AMOUNT.multiply(new BigDecimal("0.1")); dappWalletService.updateWalletCoinWithLock(directProfit, parent.getId(), 1); DappFundFlowEntity fundFlow = new DappFundFlowEntity(parent.getId(), directProfit, 3, 2, null, null); dappFundFlowDao.insert(fundFlow); } // 如果是复投的,则需奖励 if (isReIn == 1) { List directCnt = dappMemberDao.selectChildMemberDirectOrNot(member.getInviteId(), 1, 1); /** * 复投后,推一个拿一轮,推两个拿两轮,推三个后终身有效。 * 200u单。 * 无直推则收益200U * 一人加一轮400u,二人二轮 * 三人永久。 */ if (directCnt.size() < 3 && member.getOutCnt() != 0 && member.getOutCnt() - 1 == directCnt.size()) { return; } else { BigDecimal amount = null; if (directCnt.size() < 1) { amount = TreeConstants.PUT_IN_AMOUNT; } else { amount = TreeConstants.FULL_PROFIT_AMOUNT; } member.setOutCnt(member.getOutCnt() + 1); dappMemberDao.updateById(member); dappWalletService.updateWalletCoinWithLock(amount, member.getId(), 1); DappFundFlowEntity matrixProfitFlow = new DappFundFlowEntity(memberId, amount, 2, 2, null, null); dappFundFlowDao.insert(matrixProfitFlow); } DappFundFlowEntity rePutInFlow = new DappFundFlowEntity(memberId, TreeConstants.PUT_IN_AMOUNT.negate(), 1, 2, null, null); dappFundFlowDao.insert(rePutInFlow); } } @Override public void tfcNewPrice(String data) { // redisUtils.set(AppContants.REDIS_KEY_TFC_NEW_PRICE, new BigDecimal(data)); } @Override public void resetMatrix() { DappAchieveTreeEntity node = dappAchieveTreeDao.selectNewestTreeNode(); if (node.getValidState() == 2) { return; } long days = DateUtil.between(node.getCreateTime(), new Date(), DateUnit.DAY); if (days < 7) { return; } DappMineDataEntity mineDataEntity = dappSystemDao.selectMineDataForOne(); List list = dappAchieveTreeDao.selectLastCountTreeNode(500); if (CollUtil.isNotEmpty(list)) { BigDecimal preAmount = mineDataEntity.getSafePool().divide(new BigDecimal(list.size()), 2, RoundingMode.HALF_UP); list.forEach(item -> { dappWalletService.updateWalletCoinWithLock(preAmount, item.getMidNode(), 1); DappFundFlowEntity flow = new DappFundFlowEntity(item.getMidNode(), preAmount, 8, 2, null, null); dappFundFlowDao.insert(flow); }); } mineDataEntity.setSafePool(BigDecimal.ZERO); dappSystemDao.updateMineData(mineDataEntity); dappAchieveTreeDao.updateNodeValidState(); dappAchieveMemberTreeDao.emptyTable(); dappMemberDao.updateMemberActive(); } @Override public void feeDistribute(String data) { if (StrUtil.isBlank(data)) { return; } Long flowId = Long.parseLong(data); DappFundFlowEntity fundFlow = dappFundFlowDao.selectById(flowId); if (fundFlow == null) { return; } DataDictionaryCustom memberFeeDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(DataDictionaryEnum.MEMBER_FEE.getType(), DataDictionaryEnum.MEMBER_FEE.getCode()); if (memberFeeDic == null) { log.info("未设置手续费返利比例"); return; } List memberList = dappMemberDao.selectMemberListNeedProfit(); if (CollUtil.isEmpty(memberList)) { return; } BigDecimal feeReturnRatio = new BigDecimal(memberFeeDic.getValue()); int size = memberList.size(); BigDecimal totalProfit = fundFlow.getFee().multiply(feeReturnRatio.divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_DOWN)); BigDecimal perProfit = totalProfit.divide(BigDecimal.valueOf(size), 8, RoundingMode.HALF_DOWN); memberList.forEach(item -> { dappWalletService.updateWalletMineWithLock(perProfit, item.getId(), 1); DappFundFlowEntity profitFlow = new DappFundFlowEntity(item.getId(), perProfit, 12, 2, null, null); dappFundFlowDao.insert(profitFlow); }); } @Override public void invitePerkMsg(Long id) { /** * * 二、DAO成员动态: * * 1.直推1个拿2代,直推10个拿20代,直推15个拿30代,最高30代 * * 2. 1-5代奖励7% * * 6-10代奖励6% * * 11-15代奖励5% * * 15-20代奖励4% * * 21-25代奖励4% * * 26-30代奖励7% */ // DappFundFlowEntity dappFundFlowEntity = dappFundFlowDao.selectById(id); // if(ObjectUtil.isEmpty(dappFundFlowEntity)){ // return; // } // if(DappFundFlowEntity.WITHDRAW_STATUS_AGREE != dappFundFlowEntity.getStatus()){ // return; // } DappStorage dappStorage = dappStorageMapper.selectById(id); if(ObjectUtil.isEmpty(dappStorage)){ return; } BigDecimal amount = dappStorage.getReleaseAmount().abs(); /** * 往上循环30层,判断每一层是否有见点奖 */ Long memberId = dappStorage.getMemberId(); for(int i = 1;i <= 30;i++){ DappMemberEntity dappMemberEntity = dappMemberDao.selectById(memberId); String refererId = dappMemberEntity.getRefererId(); //上级不存在,则停止循环。 QueryWrapper objectQueryWrapper = new QueryWrapper<>(); objectQueryWrapper.eq("invite_id",refererId); DappMemberEntity dappMemberEntityRef = dappMemberDao.selectOne(objectQueryWrapper); if(ObjectUtil.isEmpty(dappMemberEntityRef)){ return; } memberId = dappMemberEntityRef.getId(); //如果为购买星级激活用户,则跳过 Integer activeStatus = dappMemberEntityRef.getActiveStatus(); if(1 != activeStatus){ continue; } //获取上级全部的激活直推 String inviteId = dappMemberEntityRef.getInviteId(); QueryWrapper memberInviteQuery = new QueryWrapper<>(); memberInviteQuery.eq("referer_id",inviteId); memberInviteQuery.eq("active_status",1); List memberInviteList = dappMemberDao.selectList(memberInviteQuery); //如果没有直推,则跳过 if(CollUtil.isEmpty(memberInviteList)){ continue; } InviteRule rule = InviteRule.LEVEL_1.getRule(i); if(ObjectUtil.isEmpty(rule)){ return; } //如果直推不满足当前规则需要的人数,则跳过 if(memberInviteList.size() < rule.getInviteNum()){ continue; } BigDecimal perkPercent = new BigDecimal(rule.getPerkPercent()).multiply(new BigDecimal("0.01")); BigDecimal perkAmount = perkPercent.multiply(amount); Long perkMemberId = dappMemberEntityRef.getId(); this.updateBalanceInsertFlow( perkAmount, perkMemberId, MoneyFlowEnum.DYNAMIC_PERK.getValue(), StrUtil.format(MoneyFlowEnum.DYNAMIC_PERK.getDescrition(),amount,memberInviteList.size(),perkAmount)); } } @Override public void nodePerkMsg(Long id) { DappFundFlowEntity dappFundFlowEntity = dappFundFlowDao.selectById(id); if(MoneyFlowEnum.CUN_CHU.getValue() != dappFundFlowEntity.getType()){ return; } if(DappFundFlowEntity.WITHDRAW_STATUS_AGREE != dappFundFlowEntity.getStatus()){ return; } BigDecimal amount = dappFundFlowEntity.getAmount(); /** * 激励池 6% */ BigDecimal jiliAmount = new BigDecimal(AppContants.DAO_JI_LI_PERCENT).multiply(amount); DataDictionaryCustom jiliChiDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode( DataDictionaryEnum.JILI_CHI.getType(), DataDictionaryEnum.JILI_CHI.getCode() ); BigDecimal addJili = new BigDecimal(jiliChiDic.getValue()).add(jiliAmount).setScale(2,BigDecimal.ROUND_DOWN); jiliChiDic.setValue(addJili.toString()); dataDictionaryCustomMapper.updateById(jiliChiDic); /** * 补偿池 2% */ BigDecimal buchangAmount = new BigDecimal(AppContants.DAO_BU_CHANG_PERCENT).multiply(amount); DataDictionaryCustom buchangChiDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode( DataDictionaryEnum.BUCAHNG_CHI.getType(), DataDictionaryEnum.BUCAHNG_CHI.getCode() ); BigDecimal addBuchang = new BigDecimal(buchangChiDic.getValue()).add(buchangAmount).setScale(2,BigDecimal.ROUND_DOWN); buchangChiDic.setValue(addBuchang.toString()); dataDictionaryCustomMapper.updateById(buchangChiDic); /** * 团队 5 %加权分红(people数量) */ // BigDecimal tuanDuiAmount = amount.multiply(new BigDecimal(AppContants.DAO_TEAM_PERK_PERCENT)); // DataDictionaryCustom tuanDuiChiDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode( // DataDictionaryEnum.TUAN_DUI_CHI.getType(), // DataDictionaryEnum.TUAN_DUI_CHI.getCode() // ); // BigDecimal tuanDuiChi = new BigDecimal(tuanDuiChiDic.getValue()).add(tuanDuiAmount).setScale(2,BigDecimal.ROUND_DOWN); // tuanDuiChiDic.setValue(tuanDuiChi.toString()); // dataDictionaryCustomMapper.updateById(tuanDuiChiDic); /** * 技术 2 %加权分红(people数量) */ BigDecimal jiShuAmount = amount.multiply(new BigDecimal(AppContants.DAO_JI_SHU_PERCENT)); DataDictionaryCustom jiShuChiDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode( DataDictionaryEnum.JI_SHU_CHI.getType(), DataDictionaryEnum.JI_SHU_CHI.getCode() ); BigDecimal jiShuChi = new BigDecimal(jiShuChiDic.getValue()).add(jiShuAmount).setScale(2,BigDecimal.ROUND_DOWN); jiShuChiDic.setValue(jiShuChi.toString()); dataDictionaryCustomMapper.updateById(jiShuChiDic); /** * 基金会 3 %加权分红(people数量) */ BigDecimal jiJingHuiAmount = amount.multiply(new BigDecimal(AppContants.DAO_JI_JING_HUI_PERCENT)); DataDictionaryCustom jiJingHuiChiDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode( DataDictionaryEnum.JI_JING_HUI_CHI.getType(), DataDictionaryEnum.JI_JING_HUI_CHI.getCode() ); BigDecimal jiJingHuiChi = new BigDecimal(jiJingHuiChiDic.getValue()).add(jiJingHuiAmount).setScale(2,BigDecimal.ROUND_DOWN); jiJingHuiChiDic.setValue(jiJingHuiChi.toString()); dataDictionaryCustomMapper.updateById(jiJingHuiChiDic); /** * DAO联盟委员会 : 5% */ BigDecimal daoNodeAmountTotal = new BigDecimal(AppContants.DAO_NODE_PERCENT).multiply(amount); //沉淀剩余 BigDecimal daoNodeAmountAva = BigDecimal.ZERO; QueryWrapper objectQueryWrapper = new QueryWrapper<>(); objectQueryWrapper.eq("node_type",1); List dappMemberEntities = dappMemberDao.selectList(objectQueryWrapper); if(CollUtil.isNotEmpty(dappMemberEntities)){ BigDecimal daoNodeAmount = daoNodeAmountTotal.divide(new BigDecimal(dappMemberEntities.size()),2,BigDecimal.ROUND_DOWN); for(DappMemberEntity nodeMember : dappMemberEntities){ //生成一条流水 DappFundFlowEntity rePutInFlow = new DappFundFlowEntity( nodeMember.getId(), daoNodeAmount, MoneyFlowEnum.NODE_PERK.getValue(), 2, null, StrUtil.format(MoneyFlowEnum.NODE_PERK.getDescrition(),amount,dappMemberEntities.size(),daoNodeAmount)); dappFundFlowDao.insert(rePutInFlow); //更新用户的金额 dappWalletService.updateWalletCoinWithLock(daoNodeAmount, nodeMember.getId(), 1); } }else{ daoNodeAmountAva = daoNodeAmountTotal; } if(BigDecimal.ZERO.compareTo(daoNodeAmountAva) < 0){ DataDictionaryCustom jieDianChiDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode( DataDictionaryEnum.JIE_DIAN_CHI.getType(), DataDictionaryEnum.JIE_DIAN_CHI.getCode() ); BigDecimal jieDianChi = new BigDecimal(jieDianChiDic.getValue()).add(daoNodeAmountAva).setScale(2,BigDecimal.ROUND_DOWN); jieDianChiDic.setValue(jieDianChi.toString()); dataDictionaryCustomMapper.updateById(jieDianChiDic); } } @Override public void directPerkMsg(Long id) { DappFundFlowEntity dappFundFlowEntity = dappFundFlowDao.selectById(id); if(MoneyFlowEnum.CUN_CHU.getValue() != dappFundFlowEntity.getType()){ return; } if(DappFundFlowEntity.WITHDRAW_STATUS_AGREE != dappFundFlowEntity.getStatus()){ return; } Long memberId = dappFundFlowEntity.getMemberId(); DappMemberEntity dappMemberEntity = dappMemberDao.selectById(memberId); if(ObjectUtil.isEmpty(dappMemberEntity)){ return; } if(ObjectUtil.isEmpty(dappMemberEntity.getRefererId())){ return; } DappMemberEntity directMember = dappMemberDao.selectMemberInfoByInviteId(dappMemberEntity.getRefererId()); if(ObjectUtil.isEmpty(directMember)){ return; } BigDecimal amount = dappFundFlowEntity.getAmount(); /* 直推 8% */ BigDecimal directAmount = new BigDecimal(AppContants.DIRECT_PERCENT).multiply(amount); if(BigDecimal.ZERO.compareTo(directAmount) >= 0){ return; } this.updateBalanceInsertFlow( directAmount, directMember.getId(), MoneyFlowEnum.DIRECT_PERK.getValue(), StrUtil.format(MoneyFlowEnum.DIRECT_PERK.getDescrition(),amount,directAmount)); } @Override public void updateBalanceInsertFlow (BigDecimal daoNodeAmount,Long memberId,Integer type,String description){ if(BigDecimal.ZERO.compareTo(daoNodeAmount) > 0){ return; } DappMemberEntity dappMemberEntity = dappMemberDao.selectById(memberId); if(ObjectUtil.isEmpty(dappMemberEntity)){ return; } // if(1 != dappMemberEntity.getActiveStatus()){ // return; // } //减少用户的总额度 // BigDecimal usdtBalance = dappMemberEntity.getUsdtBalance(); // if(BigDecimal.ZERO.compareTo(usdtBalance) >= 0){ // return; // } // if(daoNodeAmount.compareTo(usdtBalance) >= 0){ // daoNodeAmount = usdtBalance; // usdtBalance = BigDecimal.ZERO; // }else{ // usdtBalance = usdtBalance.subtract(daoNodeAmount); // } //总额度为0,用户变成未激活 // if(BigDecimal.ZERO.compareTo(usdtBalance) >= 0){ // dappMemberEntity.setActiveStatus(2); // //更新用户所有的业绩为已失效 // QueryWrapper objectQueryWrapper = new QueryWrapper<>(); // objectQueryWrapper.eq("member_id",memberId); // objectQueryWrapper.eq("state",1); // List dappStorages = dappStorageMapper.selectList(objectQueryWrapper); // if(CollUtil.isNotEmpty(dappStorages)){ // for(DappStorage dappStorage : dappStorages){ // dappStorage.setState(2); // dappStorageMapper.updateById(dappStorage); // } // } // } // dappMemberEntity.setUsdtBalance(usdtBalance); // dappMemberDao.updateById(dappMemberEntity); dappWalletService.updateWalletCoinWithLock(daoNodeAmount, memberId, 1); DappFundFlowEntity nodeFlow = new DappFundFlowEntity( memberId, daoNodeAmount, type, 2, BigDecimal.ZERO, description); dappFundFlowDao.insert(nodeFlow); } /** * * 3. DAO成员团队奖:5%加权分红(people数量) * DAO1:小区业绩30万/币 加权分红50% * DAO2:小区业绩100万/币 加权分红30% * DAO3:小区业绩500万/币加权分红20% */ @Override public void teamPerk(Long id) { DappFundFlowEntity dappFundFlowEntity = dappFundFlowDao.selectById(id); if(ObjectUtil.isEmpty(dappFundFlowEntity)){ return; } if(MoneyFlowEnum.CUN_CHU.getValue() != dappFundFlowEntity.getType()){ return; } if(DappFundFlowEntity.WITHDRAW_STATUS_AGREE != dappFundFlowEntity.getStatus()){ return; } BigDecimal amount = dappFundFlowEntity.getAmount(); //5%加权分红(people数量) BigDecimal totalAmount = amount.multiply(new BigDecimal(AppContants.DAO_TEAM_PERK_PERCENT)).setScale(2, BigDecimal.ROUND_DOWN); //沉淀数量 BigDecimal tuanDuiAva = BigDecimal.ZERO; QueryWrapper daoOneQuery = new QueryWrapper<>(); daoOneQuery.eq("level", MemberLevelEnum.DAO_1.getCode()); List daoOnes = dappMemberDao.selectList(daoOneQuery); if(CollUtil.isNotEmpty(daoOnes)){ BigDecimal bigDecimal = totalAmount.multiply(new BigDecimal("0.5")).setScale(2, BigDecimal.ROUND_DOWN); tuanDuiAva = tuanDuiAva.add(bigDecimal); //每人平分数量 BigDecimal divide = bigDecimal.divide(new BigDecimal(daoOnes.size()), 2, BigDecimal.ROUND_DOWN); for(DappMemberEntity memberEntity : daoOnes){ this.updateBalanceInsertFlow( divide, memberEntity.getId(), MoneyFlowEnum.TEAM_ONE_PERK.getValue(), StrUtil.format(MoneyFlowEnum.TEAM_ONE_PERK.getDescrition(),divide)); } } QueryWrapper daoTwoQuery = new QueryWrapper<>(); daoTwoQuery.eq("level", MemberLevelEnum.DAO_2.getCode()); List daoTwos = dappMemberDao.selectList(daoTwoQuery); if(CollUtil.isNotEmpty(daoTwos)){ BigDecimal bigDecimal = totalAmount.multiply(new BigDecimal("0.3")).setScale(2, BigDecimal.ROUND_DOWN); tuanDuiAva = tuanDuiAva.add(bigDecimal); //每人平分数量 BigDecimal divide = bigDecimal.divide(new BigDecimal(daoTwos.size()), 2, BigDecimal.ROUND_DOWN); for(DappMemberEntity memberEntity : daoTwos){ this.updateBalanceInsertFlow( divide, memberEntity.getId(), MoneyFlowEnum.TEAM_TWO_PERK.getValue(), StrUtil.format(MoneyFlowEnum.TEAM_TWO_PERK.getDescrition(),divide)); } } QueryWrapper daoThreeQuery = new QueryWrapper<>(); daoThreeQuery.eq("level", MemberLevelEnum.DAO_3.getCode()); List daoThrees = dappMemberDao.selectList(daoThreeQuery); if(CollUtil.isNotEmpty(daoThrees)){ BigDecimal bigDecimal = totalAmount.multiply(new BigDecimal("0.2")).setScale(2, BigDecimal.ROUND_DOWN); tuanDuiAva = tuanDuiAva.add(bigDecimal); //每人平分数量 BigDecimal divide = bigDecimal.divide(new BigDecimal(daoThrees.size()), 2, BigDecimal.ROUND_DOWN); for(DappMemberEntity memberEntity : daoThrees){ this.updateBalanceInsertFlow( divide, memberEntity.getId(), MoneyFlowEnum.TEAM_THREE_PERK.getValue(), StrUtil.format(MoneyFlowEnum.TEAM_THREE_PERK.getDescrition(),divide)); } } DataDictionaryCustom tuanDuiChiDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode( DataDictionaryEnum.TUAN_DUI_CHI.getType(), DataDictionaryEnum.TUAN_DUI_CHI.getCode() ); BigDecimal tuanDuiAvaTotal = totalAmount.subtract(tuanDuiAva).setScale(2, BigDecimal.ROUND_DOWN); if(BigDecimal.ZERO.compareTo(tuanDuiAvaTotal) < 0){ BigDecimal tuanDuiChi = new BigDecimal(tuanDuiChiDic.getValue()).add(tuanDuiAvaTotal).setScale(2,BigDecimal.ROUND_DOWN); tuanDuiChiDic.setValue(tuanDuiChi.toString()); dataDictionaryCustomMapper.updateById(tuanDuiChiDic); } } @Override public void MemberLevel(Long id) { DappMemberEntity dappMemberEntity = dappMemberDao.selectById(id); if(StrUtil.isEmpty(dappMemberEntity.getRefererIds())){ return; } //获取全部上级 ArrayList activeMembers = new ArrayList<>(); List refererIds = Arrays.asList(StrUtil.split(dappMemberEntity.getRefererIds(),",")); for(String inviteId : refererIds){ DappMemberEntity memberEntity = dappMemberDao.selectMemberInfoByInviteId(inviteId); if(ObjectUtil.isNotEmpty(memberEntity)){ activeMembers.add(memberEntity); } } if(CollUtil.isEmpty(activeMembers)){ return; } for(DappMemberEntity activeMember : activeMembers){ //获取每一个上级的所有直推,分辨大小区是否满足业绩需求 List directMembers = dappMemberDao.selectChildMemberDirectOrNot(activeMember.getInviteId(), 1, null); if(CollUtil.isEmpty(directMembers)){ continue; } if(directMembers.size() < 2){ continue; } //获取activeMember的每一个直推的团队有效业绩 HashMap daXiaoQu = new HashMap<>(); for(DappMemberEntity directMember : directMembers){ //每一个直推的团队 List direct = dappMemberDao.selectChildMemberDirectOrNot(directMember.getInviteId(), 2, null); direct.add(directMember); if(CollUtil.isEmpty(direct)){ continue; } //获取直推的团队的全部有效业绩 List collect = direct.stream().map(DappMemberEntity::getId).collect(Collectors.toList()); QueryWrapper storageQueryWrapper = new QueryWrapper<>(); storageQueryWrapper.in("member_id",collect); // storageQueryWrapper.eq("state",1); List dappStorages = dappStorageMapper.selectList(storageQueryWrapper); if(CollUtil.isEmpty(dappStorages)){ continue; } BigDecimal directAchieve = dappStorages.stream() .map(DappStorage::getAmount) // 映射amount到流中 .reduce(BigDecimal.ZERO, BigDecimal::add); daXiaoQu.put(directMember.getId(),directAchieve); } if(daXiaoQu.isEmpty()){ continue; } //输出小区的总业绩 BigDecimal sum = sumExcludingMax(daXiaoQu); BigDecimal dao_1_levelAchieve = new BigDecimal(MemberLevelEnum.DAO_1.getLevelAchieve()); BigDecimal dao_2_levelAchieve = new BigDecimal(MemberLevelEnum.DAO_2.getLevelAchieve()); BigDecimal dao_3_levelAchieve = new BigDecimal(MemberLevelEnum.DAO_3.getLevelAchieve()); if(sum.compareTo(dao_3_levelAchieve) >= 0){ activeMember.setLevel(MemberLevelEnum.DAO_3.getCode()); dappMemberDao.updateById(activeMember); }else if(sum.compareTo(dao_2_levelAchieve) >= 0 && sum.compareTo(dao_3_levelAchieve) < 0){ activeMember.setLevel(MemberLevelEnum.DAO_2.getCode()); dappMemberDao.updateById(activeMember); }else if(sum.compareTo(dao_1_levelAchieve) >= 0 && sum.compareTo(dao_2_levelAchieve) < 0){ activeMember.setLevel(MemberLevelEnum.DAO_1.getCode()); dappMemberDao.updateById(activeMember); }else{ activeMember.setLevel(MemberLevelEnum.DAO_0.getCode()); dappMemberDao.updateById(activeMember); } } } /** * 计算HashMap中除最大值以外的数据的累计和 * * @param map 包含Long作为key和BigDecimal作为value的HashMap * @return 除最大值以外的数据的累计和 * @throws NullPointerException 如果HashMap为空,则抛出此异常 */ public static BigDecimal sumExcludingMax(HashMap map) { if (map == null) { throw new NullPointerException("HashMap cannot be null"); } // 使用Stream API找到最大的BigDecimal值及其对应的key Optional> maxEntry = map.entrySet().stream() .max((e1, e2) -> e1.getValue().compareTo(e2.getValue())); // 检查是否找到了最大值 if (maxEntry.isPresent()) { // 移除最大值对应的键值对 map.remove(maxEntry.get().getKey()); // 计算剩余数据的累计和 BigDecimal sumOfRemaining = map.entrySet().stream() .map(Map.Entry::getValue) .reduce(BigDecimal.ZERO, BigDecimal::add); // 返回累计和 return sumOfRemaining; } else { // 如果没有找到最大值(即HashMap为空),则返回BigDecimal.ZERO return BigDecimal.ZERO; } } // 主函数,用于测试 public static void main(String[] args) { HashMap map = new HashMap<>(); map.put(1L, new BigDecimal("100.00")); map.put(2L, new BigDecimal("200.00")); map.put(4L, new BigDecimal("200.00")); map.put(3L, new BigDecimal("50.00")); BigDecimal sum = sumExcludingMax(map); System.out.println("Sum of remaining values excluding the maximum: " + sum); } }