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.common.utils.SpringContextUtil; import cc.mrbird.febs.dapp.chain.ChainEnum; import cc.mrbird.febs.dapp.chain.ChainService; 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.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.StrUtil; 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.*; /** * @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 DappAchieveTreeDao dappAchieveTreeDao; private final DappAchieveMemberTreeDao dappAchieveMemberTreeDao; private final DappWalletService dappWalletService; private final DataDictionaryCustomMapper dataDictionaryCustomMapper; @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); 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); 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()); } } } // 完成矩阵树,并重置矩阵且重入 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); }); } }