| | |
| | | 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.chain.ChainEnum; |
| | | import cc.mrbird.febs.dapp.chain.ChainService; |
| | | import cc.mrbird.febs.dapp.chain.ContractChainService; |
| | | import cc.mrbird.febs.dapp.dto.SystemDto; |
| | | import cc.mrbird.febs.dapp.entity.*; |
| | | import cc.mrbird.febs.dapp.enumerate.DataDictionaryEnum; |
| | | import cc.mrbird.febs.dapp.enumerate.InviteRule; |
| | | import cc.mrbird.febs.dapp.enumerate.NodeType; |
| | | import cc.mrbird.febs.dapp.mapper.*; |
| | | import cc.mrbird.febs.dapp.service.DappSystemService; |
| | | import cc.mrbird.febs.dapp.vo.RedisTransferPoolVo; |
| | | import cc.mrbird.febs.dapp.vo.SlipSettingVo; |
| | | import cc.mrbird.febs.rabbit.producer.ChainProducer; |
| | | import cc.mrbird.febs.dapp.service.DappWalletService; |
| | | 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.util.RandomUtil; |
| | | 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.alibaba.fastjson.JSONObject; |
| | | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.stereotype.Service; |
| | |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.math.RoundingMode; |
| | | import java.util.*; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * @author |
| | | * @author |
| | | * @date 2022-03-24 |
| | | **/ |
| | | @Slf4j |
| | |
| | | public class DappSystemServiceImpl implements DappSystemService { |
| | | |
| | | private final DappSystemDao dappSystemDao; |
| | | private final DappReturnRatioDao dappReturnRatioDao; |
| | | private final RedisUtils redisUtils; |
| | | private final DappFundFlowDao dappFundFlowDao; |
| | | private final DappMemberDao dappMemberDao; |
| | | |
| | | private final DappAchieveTreeDao dappAchieveTreeDao; |
| | | private final DappAchieveMemberTreeDao dappAchieveMemberTreeDao; |
| | | private final DappWalletService dappWalletService; |
| | | private final DataDictionaryCustomMapper dataDictionaryCustomMapper; |
| | | private final DappOnlineTransferDao dappOnlineTransferDao; |
| | | private final ChainProducer chainProducer; |
| | | |
| | | private final String[] ADDRESS_PREFIX = {"T", "0x"}; |
| | | @Override |
| | | public Map<String, Object> findTotalInComeAndList() { |
| | | DappMineDataEntity dataMine = dappSystemDao.selectMineDataForOne(); |
| | | private final DbMemberNodeMapper dbMemberNodeMapper; |
| | | |
| | | |
| | | Map<String, Object> result = new HashMap<>(); |
| | | result.put("total", 6000); |
| | | result.put("addreessCnt", 1234); |
| | | result.put("coinCnt", 4000); |
| | | return result; |
| | | } |
| | | |
| | | @Override |
| | | public Map<String, Object> globalSetting() { |
| | | BigDecimal newPrice = (BigDecimal) redisUtils.get(AppContants.REDIS_KEY_ETH_NEW_PRICE); |
| | | Integer changeFee = (Integer) redisUtils.get(AppContants.REDIS_KEY_CHANGE_FEE); |
| | | |
| | | List<DappReturnRatioEntity> ratios = dappReturnRatioDao.selectList(null); |
| | | Map<String, Object> result = new HashMap<>(); |
| | | result.put("newPrice", newPrice); |
| | | result.put("changeFee", changeFee); |
| | | result.put("ratio", ratios); |
| | | return result; |
| | | } |
| | | |
| | | @Override |
| | | public SystemDto system() { |
| | | DappMemberEntity member = LoginUserUtil.getAppUser(); |
| | | |
| | | SystemDto system = new SystemDto(); |
| | | |
| | | RedisTransferPoolVo transferPool = (RedisTransferPoolVo) redisUtils.get(AppContants.REDIS_KEY_TRANSFER_POOL_VOL); |
| | | BigDecimal poolRemain = (BigDecimal) redisUtils.get(AppContants.REDIS_KEY_TRANSFER_POOL_VOL_REMAIN); |
| | | // 买币数量 |
| | | system.setBuyTotal(transferPool.getTodayVol()); |
| | | system.setBuyRemain(poolRemain); |
| | | |
| | | ContractChainService instance = ChainService.getInstance(ChainEnum.BSC_TFC.name()); |
| | | BigDecimal balance = instance.balanceOf(member.getAddress()); |
| | | Object o = redisUtils.get(AppContants.REDIS_KEY_COIN_REMAIN + member.getAddress()); |
| | | |
| | | BigDecimal coinTotal = balance.multiply(BigDecimal.valueOf(0.3)).setScale(instance.decimals(), RoundingMode.HALF_DOWN); |
| | | BigDecimal remain; |
| | | if (o == null) { |
| | | remain = coinTotal; |
| | | redisUtils.set(AppContants.REDIS_KEY_COIN_REMAIN + member.getAddress(), remain); |
| | | } else { |
| | | remain = (BigDecimal) o; |
| | | } |
| | | // 卖币数量 |
| | | system.setSaleTotal(coinTotal); |
| | | system.setSaleRemain(remain); |
| | | |
| | | BigDecimal usdtRemain = (BigDecimal) redisUtils.get(AppContants.REDIS_KEY_USDT_OUT_LIMIT_REMAIN); |
| | | BigDecimal usdtTotal = (BigDecimal) redisUtils.get(AppContants.REDIS_KEY_USDT_OUT_LIMIT); |
| | | |
| | | // usdt数量 |
| | | system.setUsdtTotal(usdtTotal); |
| | | system.setUsdtRemain(usdtRemain); |
| | | |
| | | system.setFeeRatio(BigDecimal.TEN); |
| | | system.setBuyAmount(new BigDecimal("100")); |
| | | return system; |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void tradeProfitDistribute(Long id) { |
| | | DappFundFlowEntity fundflow = dappFundFlowDao.selectById(id); |
| | | |
| | | BigDecimal fee = fundflow.getFee(); |
| | | DappMemberEntity member = dappMemberDao.selectById(fundflow.getMemberId()); |
| | | |
| | | if (StrUtil.isBlank(member.getRefererId()) || "0".equals(member.getRefererId())) { |
| | | public synchronized void achieveTree(Long memberId) { |
| | | DappMemberEntity member = dappMemberDao.selectById(memberId); |
| | | if(ObjectUtil.isEmpty(member)){ |
| | | return; |
| | | } |
| | | List<String> inviteIds = StrUtil.split(member.getRefererId(), ','); |
| | | List<DappMemberEntity> parents = dappMemberDao.selectParentsList(inviteIds, 6); |
| | | |
| | | DataDictionaryCustom miniHoldCoin = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(AppContants.DIC_TYPE_SYSTEM_SETTING, AppContants.DIC_VALUE_MINI_HOLD_COIN_LIMIT); |
| | | DataDictionaryCustom slipPointSetting = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(AppContants.DIC_TYPE_SLIP_POINT_SETTING, AppContants.DIC_TYPE_SLIP_POINT_SETTING); |
| | | SlipSettingVo slipSetting = JSONObject.parseObject(slipPointSetting.getValue(), SlipSettingVo.class); |
| | | int batchNo = 0; |
| | | DappAchieveTreeEntity newestTreeNode = dappAchieveTreeDao.selectNewestTreeNode(); |
| | | if (newestTreeNode != null) { |
| | | if (newestTreeNode.getValidState() == 2) { |
| | | batchNo = newestTreeNode.getBatchNo() + 1; |
| | | } else { |
| | | batchNo = newestTreeNode.getBatchNo(); |
| | | } |
| | | } |
| | | |
| | | // 源池 |
| | | ContractChainService instance = ChainService.getInstance(ChainEnum.BSC_TFC_SOURCE.name()); |
| | | BigDecimal destroy = slipSetting.getDestroyPoint().divide(slipSetting.getAllPoint(), 2, RoundingMode.HALF_DOWN).multiply(fee); |
| | | log.info("销毁数量:{}, 比例:{}", destroy, slipSetting.getDestroyPoint()); |
| | | // 在大树中,插入当前节点 |
| | | DappAchieveTreeEntity achieveTree = new DappAchieveTreeEntity(); |
| | | achieveTree.setMidNode(memberId); |
| | | achieveTree.setValidState(1); |
| | | achieveTree.setBatchNo(batchNo); |
| | | dappAchieveTreeDao.insert(achieveTree); |
| | | |
| | | // 销毁 |
| | | // instance.transfer(AppContants.DESTROY_ADDRESS, destroy); |
| | | DappOnlineTransferEntity destroyRecord = new DappOnlineTransferEntity(AppContants.DESTROY_ADDRESS, destroy, fundflow.getType(), 3, ChainEnum.BSC_TFC_SOURCE.name(), "TFC", fundflow.getId().toString()); |
| | | dappOnlineTransferDao.insert(destroyRecord); |
| | | // 在内存树(大树)中插入当前节点,并返回父节点 |
| | | MemberNode node = new MemberNode(member.getId(), member.getAddress(), member.getInviteId(), member.getRefererId()); |
| | | |
| | | // 总分发金额 |
| | | BigDecimal distrbAmount = fee.subtract(destroy); |
| | | // 技术金额 |
| | | BigDecimal techAmount = distrbAmount.multiply(slipSetting.getTechProp().divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP)); |
| | | // 节点金额 |
| | | BigDecimal nodeAmount = distrbAmount.subtract(techAmount); |
| | | log.info("总分发金额:{}, 技术:{}, 节点:{}", distrbAmount, techAmount, nodeAmount); |
| | | MatrixTree tree = MatrixTree.getInstance(); |
| | | MemberNode exist = tree.getNode(member.getId()); |
| | | if (exist != null) { |
| | | return; |
| | | } |
| | | |
| | | int i = 1; |
| | | for (DappMemberEntity parent : parents) { |
| | | BigDecimal balance = instance.balanceOf(parent.getAddress()); |
| | | log.info("地址:{}, 余额:{}", parent.getAddress(), balance); |
| | | MemberNode parentNode = tree.addNode(node); |
| | | |
| | | // 若地址持币少了指定数量 |
| | | if (balance.compareTo(new BigDecimal(miniHoldCoin.getValue())) < 0) { |
| | | // 创建该节点的矩阵 |
| | | 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<DappAchieveMemberTreeEntity> 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); |
| | | |
| | | //如果添加的为右节点,那么进入判断 |
| | | 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,复投逻辑 |
| | | memberNodeNext(dbMemberNodeRoot); |
| | | }else{//父节点为左节点,那么没人出局 |
| | | return; |
| | | } |
| | | }else{ |
| | | //更新父节点的左节点 |
| | | dbMemberNodeOld.setLeftNode(dbMemberNode.getId()); |
| | | dbMemberNodeMapper.updateById(dbMemberNodeOld); |
| | | //如果添加的为左节点,那么没人出局 |
| | | return; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 有,则上级节点出局复投,轮数加1,复投逻辑 |
| | | * @param dbMemberNodeRoot |
| | | */ |
| | | 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<DappMemberEntity> inviteQuery = new QueryWrapper<>(); |
| | | inviteQuery.eq("referer_id",dappMemberEntity.getInviteId()); |
| | | List<DappMemberEntity> dappMemberEntities = dappMemberDao.selectList(inviteQuery); |
| | | if(CollUtil.isEmpty(dappMemberEntities)){ |
| | | return; |
| | | } |
| | | if(inviteNum > dappMemberEntities.size()){ |
| | | return; |
| | | } |
| | | List<Long> collect = dappMemberEntities.stream().map(DappMemberEntity::getId).collect(Collectors.toList()); |
| | | QueryWrapper<DbMemberNode> inviteNodeQuery = new QueryWrapper<>(); |
| | | inviteNodeQuery.select("member_id"); |
| | | inviteNodeQuery.eq("work_state", DbMemberNode.STATE_ONE); |
| | | inviteNodeQuery.in("member_id",collect); |
| | | inviteNodeQuery.groupBy("member_id"); |
| | | List<DbMemberNode> 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{ |
| | | 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){//第一轮 |
| | | //复投本轮,轮数 +1 |
| | | futouSixTeen(memberId,dbMemberNodeRoot.getAmount(),type,countFund+1); |
| | | //收益复投(当前的下一个星团没有已投入),还是收益提出 |
| | | Integer nextType = type + 1; |
| | | QueryWrapper<DbMemberNode> 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); |
| | | } |
| | | }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); |
| | | |
| | | if(ObjectUtil.isNotEmpty(dbMemberNodeOld)){ |
| | | if(dbMemberNode.getLeftRight() == 1){ |
| | | dbMemberNodeOld.setLeftNode(dbMemberNode.getId()); |
| | | }else{ |
| | | dbMemberNodeOld.setRightNode(dbMemberNode.getId()); |
| | | } |
| | | dbMemberNodeMapper.updateById(dbMemberNodeOld); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | // 完成矩阵树,并重置矩阵且重入 |
| | | public void finishMatrixTree(Long memberId) { |
| | | List<DappAchieveMemberTreeEntity> 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<DappMemberEntity> 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<DappAchieveTreeEntity> 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<DappMemberEntity> 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) { |
| | | /** |
| | | * 推荐规则: |
| | | * 无直推奖励,推2个3层,3个6层,4个10层。1%见点奖(有效层级内,每个每1%),共10层,共%10。 |
| | | */ |
| | | DappFundFlowEntity dappFundFlowEntity = dappFundFlowDao.selectById(id); |
| | | if(ObjectUtil.isEmpty(dappFundFlowEntity)){ |
| | | return; |
| | | } |
| | | BigDecimal amount = dappFundFlowEntity.getAmount().abs(); |
| | | /** |
| | | * 往上循环十层,判断每一层是否有见点奖 |
| | | */ |
| | | Long memberId = dappFundFlowEntity.getMemberId(); |
| | | for(int i = 1;i <= 10;i++){ |
| | | DappMemberEntity dappMemberEntity = dappMemberDao.selectById(memberId); |
| | | String refererId = dappMemberEntity.getRefererId(); |
| | | //上级不存在,则停止循环。 |
| | | QueryWrapper<DappMemberEntity> objectQueryWrapper = new QueryWrapper<>(); |
| | | objectQueryWrapper.eq("invite_id",refererId); |
| | | DappMemberEntity dappMemberEntityRef = dappMemberDao.selectOne(objectQueryWrapper); |
| | | if(ObjectUtil.isEmpty(dappMemberEntityRef)){ |
| | | return; |
| | | } |
| | | |
| | | DataDictionaryCustom distribDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(AppContants.DIC_TYPE_DISTRIBUTE_PROP, String.valueOf(i)); |
| | | BigDecimal total = distrbAmount.multiply(new BigDecimal(distribDic.getValue()).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP)); |
| | | memberId = dappMemberEntityRef.getId(); |
| | | //如果为购买星级激活用户,则跳过 |
| | | Integer activeStatus = dappMemberEntityRef.getActiveStatus(); |
| | | if(1 != activeStatus){ |
| | | continue; |
| | | } |
| | | //获取上级全部的直推 |
| | | String inviteId = dappMemberEntityRef.getInviteId(); |
| | | QueryWrapper<DappMemberEntity> memberInviteQuery = new QueryWrapper<>(); |
| | | memberInviteQuery.eq("referer_id",inviteId); |
| | | List<DappMemberEntity> memberInviteList = dappMemberDao.selectList(memberInviteQuery); |
| | | |
| | | DappOnlineTransferEntity distribRecord = new DappOnlineTransferEntity(parent.getAddress(), total, fundflow.getType(), 1, ChainEnum.BSC_TFC_SOURCE.name(), "TFC", fundflow.getId().toString()); |
| | | dappOnlineTransferDao.insert(distribRecord); |
| | | //如果没有直推,则跳过 |
| | | if(CollUtil.isEmpty(memberInviteList)){ |
| | | continue; |
| | | } |
| | | |
| | | nodeAmount = nodeAmount.subtract(total); |
| | | 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(); |
| | | //生成一条流水 |
| | | DappFundFlowEntity rePutInFlow = new DappFundFlowEntity( |
| | | perkMemberId, |
| | | perkAmount, |
| | | 15, |
| | | 2, |
| | | null, |
| | | null); |
| | | dappFundFlowDao.insert(rePutInFlow); |
| | | //更新用户的金额 |
| | | dappWalletService.updateWalletCoinWithLock(perkAmount, perkMemberId, 1); |
| | | } |
| | | |
| | | // 若节点金额还有剩余,则进入技术金额 |
| | | techAmount = techAmount.add(nodeAmount); |
| | | // instance.transfer(ChainEnum.BSC_TFC_TECH.getAddress(), techAmount); |
| | | |
| | | DappOnlineTransferEntity techRecord = new DappOnlineTransferEntity(ChainEnum.BSC_TFC_TECH.getAddress(), techAmount, fundflow.getType(), 2, ChainEnum.BSC_TFC_SOURCE.name(), "TFC", fundflow.getId().toString()); |
| | | dappOnlineTransferDao.insert(techRecord); |
| | | |
| | | Map<String, String> map = new HashMap<>(); |
| | | map.put("batchNo", fundflow.getId().toString()); |
| | | map.put("type", "flow"); |
| | | |
| | | // 发送转账消息 |
| | | chainProducer.sendOnlineTransfer(JSONObject.toJSONString(map)); |
| | | } |
| | | |
| | | @Override |
| | | public void mining() { |
| | | log.info("挖矿"); |
| | | public void nodePerkMsg(Long id) { |
| | | DappFundFlowEntity dappFundFlowEntity = dappFundFlowDao.selectById(id); |
| | | if(ObjectUtil.isEmpty(dappFundFlowEntity)){ |
| | | return; |
| | | } |
| | | BigDecimal amount = dappFundFlowEntity.getAmount().abs(); |
| | | log.info("买入贡献值-平分总金额-{}",amount); |
| | | /** |
| | | * 获取节点平分百分比 perkPercent |
| | | * 获取平分的份数 perKNum |
| | | * 获取每一份的金额 perkAmount |
| | | * 获取节点总数 buyNodeNum |
| | | * 如果perKNum大于buyNodeNum,则每个人获得(amount * perkPercent)/ perKNum = perkAmount |
| | | * 如果超出,再超出的人没有奖励 |
| | | */ |
| | | DataDictionaryCustom perkPercentDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode( |
| | | DataDictionaryEnum.PERK_PERCENT.getType(), |
| | | DataDictionaryEnum.PERK_PERCENT.getCode() |
| | | ); |
| | | BigDecimal perkPercent = new BigDecimal(ObjectUtil.isEmpty(perkPercentDic) ? "10" : perkPercentDic.getValue()).multiply(new BigDecimal("0.01")); |
| | | |
| | | Object o = redisUtils.get(AppContants.REDIS_KEY_MINE_ALL_INTERNET_CNT); |
| | | if (o == null) { |
| | | DataDictionaryCustom perKNumDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode( |
| | | DataDictionaryEnum.PERK_NUM.getType(), |
| | | DataDictionaryEnum.PERK_NUM.getCode() |
| | | ); |
| | | BigDecimal perKNum = new BigDecimal(ObjectUtil.isEmpty(perKNumDic) ? "200" : perKNumDic.getValue()); |
| | | |
| | | BigDecimal perkAmount = amount.multiply(perkPercent).divide(perKNum, 8, BigDecimal.ROUND_DOWN); |
| | | if(BigDecimal.ZERO.compareTo(perkAmount) >= 0){ |
| | | return; |
| | | } |
| | | |
| | | Object transferPoolObj = redisUtils.get(AppContants.REDIS_KEY_MINE_TRANSFER_POOL_TRADE_CNT); |
| | | |
| | | BigDecimal allInternet = (BigDecimal) o; |
| | | BigDecimal transferPoll = (BigDecimal) transferPoolObj; |
| | | |
| | | List<DappMemberEntity> allMembers = dappMemberDao.selectList(null); |
| | | if (CollUtil.isEmpty(allMembers)) { |
| | | QueryWrapper<DappMemberEntity> objectQueryWrapper = new QueryWrapper<>(); |
| | | objectQueryWrapper.ge("buy_node",0); |
| | | List<DappMemberEntity> dappMemberEntities = dappMemberDao.selectList(objectQueryWrapper); |
| | | if(CollUtil.isEmpty(dappMemberEntities)){ |
| | | return; |
| | | } |
| | | DataDictionaryCustom miniHoldCoin = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(AppContants.DIC_TYPE_SYSTEM_SETTING, AppContants.DIC_VALUE_MINI_HOLD_COIN_LIMIT); |
| | | |
| | | String batchNo = RandomUtil.randomString(32); |
| | | ContractChainService instance = ChainService.getInstance(ChainEnum.BSC_TFC.name()); |
| | | for (DappMemberEntity member : allMembers) { |
| | | if ("admin".equals(member.getAccountType())) { |
| | | //奖励总份数 |
| | | BigDecimal totalPerkNum = BigDecimal.ZERO; |
| | | for(DappMemberEntity dappMemberEntity : dappMemberEntities){ |
| | | //如果账号未激活,则无法领取收益 |
| | | if(1 != dappMemberEntity.getActiveStatus()){ |
| | | continue; |
| | | } |
| | | |
| | | BigDecimal balance = instance.balanceOf(member.getAddress()); |
| | | if (balance.compareTo(new BigDecimal(miniHoldCoin.getValue())) < 1) { |
| | | BigDecimal buyNode = new BigDecimal(dappMemberEntity.getBuyNode()); |
| | | totalPerkNum = totalPerkNum.add(buyNode); |
| | | if(perKNum.compareTo(totalPerkNum) < 0){ |
| | | return; |
| | | } |
| | | //奖励金额 |
| | | BigDecimal memberPerk = perkAmount.multiply(buyNode); |
| | | if(BigDecimal.ZERO.compareTo(memberPerk) >= 0){ |
| | | continue; |
| | | } |
| | | dappWalletService.updateWalletCoinWithLock(memberPerk, dappMemberEntity.getId(), 1); |
| | | |
| | | // 挖矿数量 |
| | | BigDecimal mine = transferPoll.multiply(balance.divide(allInternet, instance.decimals(), RoundingMode.HALF_UP)); |
| | | if (mine.compareTo(BigDecimal.ZERO) < 1) { |
| | | continue; |
| | | } |
| | | |
| | | DappOnlineTransferEntity tfc = new DappOnlineTransferEntity(member.getAddress(), mine, 3, 1, "TFC", ChainEnum.BSC_TFC.name(), batchNo); |
| | | dappOnlineTransferDao.insert(tfc); |
| | | DappFundFlowEntity fundFlow = new DappFundFlowEntity( |
| | | dappMemberEntity.getId(), |
| | | memberPerk, |
| | | 14, |
| | | 2, |
| | | BigDecimal.ZERO, |
| | | null); |
| | | dappFundFlowDao.insert(fundFlow); |
| | | } |
| | | |
| | | Map<String, String> map = new HashMap<>(); |
| | | map.put("batchNo", batchNo); |
| | | map.put("type", "batch"); |
| | | |
| | | // 发送转账消息 |
| | | chainProducer.sendOnlineTransfer(JSONObject.toJSONString(map)); |
| | | log.info("买入贡献值-总人数{},-每人金额{}",dappMemberEntities.size(),perkAmount); |
| | | } |
| | | |
| | | @Override |
| | | public void onlineTransfer(String str) { |
| | | JSONObject jsonObject = JSONObject.parseObject(str); |
| | | String batchNo = jsonObject.getString("batchNo"); |
| | | List<DappOnlineTransferEntity> transferList = dappOnlineTransferDao.selectByBatchNo(batchNo); |
| | | |
| | | if (CollUtil.isEmpty(transferList)) { |
| | | return; |
| | | } |
| | | |
| | | for (DappOnlineTransferEntity transfer : transferList) { |
| | | if (transfer.getHasFinish() == 1) { |
| | | continue; |
| | | } |
| | | |
| | | // TODO 线上转账,已注释 |
| | | // String txHash = ChainService.getInstance(transfer.getFromType()).transfer(transfer.getAddress(), transfer.getAmount()); |
| | | // transfer.setTxHash(txHash); |
| | | transfer.setHasFinish(1); |
| | | transfer.setUpdateTime(new Date()); |
| | | dappOnlineTransferDao.updateById(transfer); |
| | | |
| | | if ("flow".equals(jsonObject.getString("type"))) { |
| | | DappFundFlowEntity fundFlow = dappFundFlowDao.selectById(Long.parseLong(batchNo)); |
| | | |
| | | fundFlow.setStatus(3); |
| | | // fundFlow.setToHash(txHash); |
| | | |
| | | dappFundFlowDao.updateById(fundFlow); |
| | | } |
| | | |
| | | } |
| | | } |
| | | } |