12 files modified
3 files added
| | |
| | | @Data |
| | | @ApiModel(value = "TransferDto", description = "转账接口参数类") |
| | | public class TransferDto { |
| | | |
| | | // 第一次{金额 amount: val, 手续费fee: 0, txHash: '', 1-买入type: 1, 钱包buyType: 2} |
| | | // 成功{type: 1, txHash: result.transactionHash, id: res.data, flag: 'success', buyType: 2} |
| | | // 失败{type: 1, id: res.data, flag: 'fail', buyType: 2} |
| | | @ApiModelProperty(value = "1-买入 2-卖出", example = "1") |
| | | private Integer type; |
| | | |
| | |
| | | this.fee = fee; |
| | | } |
| | | |
| | | // public DappFundFlowEntity(Long memberId, BigDecimal amount, Integer type, Integer status, BigDecimal fee,Long systemProfitId) { |
| | | // this.memberId = memberId; |
| | | // this.amount = amount; |
| | | // this.type = type; |
| | | // this.status = status; |
| | | // this.fee = fee; |
| | | // this.systemProfitId = systemProfitId; |
| | | // } |
| | | |
| | | public DappFundFlowEntity(Long memberId, BigDecimal amount, Integer type, Integer status, BigDecimal fee, String fromHash) { |
| | | this.memberId = memberId; |
| | | this.amount = amount; |
| | |
| | | this.fromHash = fromHash; |
| | | } |
| | | |
| | | public DappFundFlowEntity(Long memberId, BigDecimal amount, Integer type, Integer status, BigDecimal fee, String fromHash,Long systemProfitId) { |
| | | this.memberId = memberId; |
| | | this.amount = amount; |
| | | this.type = type; |
| | | this.status = status; |
| | | this.fee = fee; |
| | | this.fromHash = fromHash; |
| | | this.systemProfitId = systemProfitId; |
| | | } |
| | | |
| | | private Long memberId; |
| | | |
| | | private BigDecimal amount; |
| | | |
| | | /** |
| | | * 类型 1-买入 2-矩阵收益 3-直推收益 4-保险池 5-提现 6-手续费充值 7-手续费扣除 8-结算 9-冻结 10-冻结释放 11-产矿 12-手续费返利 |
| | | * 类型 1-加入动能 2-技术方收益 3-直推收益 4-层级收益 5-剩余层级收益 6-手续费充值 7-手续费扣除 8-结算 9-冻结 10-冻结释放 11-产矿 12-手续费返利 |
| | | */ |
| | | private Integer type; |
| | | |
| | |
| | | private BigDecimal newestPrice; |
| | | |
| | | private BigDecimal targetAmount; |
| | | |
| | | private Long systemProfitId; |
| | | } |
| New file |
| | |
| | | package cc.mrbird.febs.dapp.entity; |
| | | |
| | | import cc.mrbird.febs.common.entity.BaseEntity; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | |
| | | @Data |
| | | @TableName("dapp_system_profit") |
| | | public class DappSystemProfit extends BaseEntity { |
| | | |
| | | private Long memberId; |
| | | |
| | | private BigDecimal amount; |
| | | //1:入列 2:出列 |
| | | private Integer state; |
| | | |
| | | public DappSystemProfit() {} |
| | | |
| | | public DappSystemProfit(Long memberId, BigDecimal amount) { |
| | | this.memberId = memberId; |
| | | this.amount = amount; |
| | | } |
| | | } |
| | |
| | | |
| | | @Getter |
| | | public enum DataDictionaryEnum { |
| | | // 会员代理等级 |
| | | BIG_BOSS("MEMBER_LEVEL","BIG_BOSS"), |
| | | BOSS("MEMBER_LEVEL","BOSS"), |
| | | AGENT("MEMBER_LEVEL","AGENT"), |
| | | MEMBER("MEMBER_LEVEL","MEMBER"), |
| | | // 层级奖励比率 |
| | | LEVEL_PROFIT("SYSTEM_SETTING","LEVEL_PROFIT"), |
| | | // 直推奖励比率 |
| | | DIRECT_PROFIT("SYSTEM_SETTING","DIRECT_PROFIT"), |
| | | // 技术方收取BNB数量 |
| | | SYSTEM_PROFIT("SYSTEM_SETTING","SYSTEM_PROFIT"), |
| | | // 每日返利的产矿百分比 |
| | | REBATE_PERCENT("SYSTEM_SETTING","REBATE_PERCENT"), |
| | | // 分给推荐三人的终身VIP会员手续费 |
| New file |
| | |
| | | package cc.mrbird.febs.dapp.enumerate; |
| | | |
| | | import lombok.Getter; |
| | | |
| | | import java.math.BigDecimal; |
| | | |
| | | @Getter |
| | | public enum LevelProfitEnum { |
| | | /** |
| | | *层级奖励,最多十层 |
| | | profit : 层级收益率 |
| | | memberCnt : 获取层级收益的最少推荐人数 |
| | | */ |
| | | |
| | | YI("YI", 2,1), |
| | | ER("ER", 2,2), |
| | | SAN("SAN", 2,3), |
| | | SI("SI", 2,4), |
| | | WU("WU", 2,5), |
| | | LIU("LIU", 4,6), |
| | | QI("QI", 4,7), |
| | | BA("BA", 4,8), |
| | | JIU("JIU", 4,9), |
| | | SHI("SHI", 4,10) |
| | | ; |
| | | |
| | | private String type; |
| | | |
| | | private Integer profit; |
| | | |
| | | private Integer memberCnt; |
| | | |
| | | LevelProfitEnum(String type, Integer profit,Integer memberCnt) { |
| | | this.type = type; |
| | | this.profit = profit; |
| | | this.memberCnt = memberCnt; |
| | | } |
| | | |
| | | public BigDecimal getProfit(int memberCnt) { |
| | | for (LevelProfitEnum value : LevelProfitEnum.values()) { |
| | | if (value.memberCnt == memberCnt) { |
| | | return new BigDecimal(value.profit).multiply(new BigDecimal(0.01)).setScale(BigDecimal.ROUND_DOWN, 2); |
| | | } |
| | | } |
| | | return BigDecimal.ZERO; |
| | | } |
| | | } |
| New file |
| | |
| | | package cc.mrbird.febs.dapp.mapper; |
| | | |
| | | import cc.mrbird.febs.dapp.entity.DappSystemProfit; |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | |
| | | public interface DappSystemProfitDao extends BaseMapper<DappSystemProfit> { |
| | | } |
| | |
| | | void resetMatrix(); |
| | | |
| | | void feeDistribute(String data); |
| | | //层级奖励分发消息 |
| | | void levelProfit(Long id); |
| | | //计算是否有人出局 |
| | | void memberOut(Long id); |
| | | } |
| | |
| | | @Override |
| | | public DappMemberEntity insertMember(String address, String refererId) { |
| | | |
| | | return insertMember(address, refererId, "BSC", "normal"); |
| | | return insertMember(address, refererId, "BSC", DataDictionaryEnum.MEMBER.getCode()); |
| | | } |
| | | |
| | | @Override |
| | |
| | | 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.LevelProfitEnum; |
| | | import cc.mrbird.febs.dapp.mapper.*; |
| | | import cc.mrbird.febs.dapp.service.DappSystemService; |
| | | import cc.mrbird.febs.dapp.service.DappWalletService; |
| | |
| | | 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; |
| | |
| | | private final DappAchieveMemberTreeDao dappAchieveMemberTreeDao; |
| | | private final DappWalletService dappWalletService; |
| | | private final DataDictionaryCustomMapper dataDictionaryCustomMapper; |
| | | private final DappSystemProfitDao dappSystemProfitDao; |
| | | |
| | | |
| | | @Override |
| | |
| | | dappFundFlowDao.insert(profitFlow); |
| | | }); |
| | | } |
| | | |
| | | @Override |
| | | public void levelProfit(Long id) { |
| | | DappSystemProfit dappSystemProfit = dappSystemProfitDao.selectById(id); |
| | | if(ObjectUtil.isEmpty(dappSystemProfit)){ |
| | | return; |
| | | } |
| | | Long memberId = dappSystemProfit.getMemberId(); |
| | | //获取用户的上级用户信息 |
| | | DappMemberEntity dappMemberEntity = dappMemberDao.selectById(memberId); |
| | | if(ObjectUtil.isEmpty(dappMemberEntity)){ |
| | | return; |
| | | } |
| | | String refererIds = dappMemberEntity.getRefererIds(); |
| | | if(StrUtil.isEmpty(refererIds)){ |
| | | return; |
| | | } |
| | | DataDictionaryCustom levelProfitSet = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(DataDictionaryEnum.LEVEL_PROFIT.getType(), DataDictionaryEnum.LEVEL_PROFIT.getCode()); |
| | | BigDecimal levelProfit = new BigDecimal(StrUtil.isEmpty(levelProfitSet.getValue()) ? "0.3" : levelProfitSet.getValue()); |
| | | //投入金额减去技术方收益 |
| | | DataDictionaryCustom systemProfitSet = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(DataDictionaryEnum.SYSTEM_PROFIT.getType(), DataDictionaryEnum.SYSTEM_PROFIT.getCode()); |
| | | BigDecimal systemProfit = new BigDecimal(StrUtil.isEmpty(systemProfitSet.getValue()) ? "0.05" : systemProfitSet.getValue()); |
| | | BigDecimal amount = dappSystemProfit.getAmount().subtract(systemProfit); |
| | | //层级奖励总奖金 |
| | | BigDecimal levelProfitTotal = amount.multiply(levelProfit); |
| | | //实发层级奖励 -- 如果还有剩余给技术方 |
| | | BigDecimal systemProfitTotal = BigDecimal.ZERO; |
| | | //返回十层 |
| | | List<String> refererIdList = StrUtil.split(refererIds, ','); |
| | | //i:计数层数,同时i也为对应层数应推广的人数,当达到对应的直推人数时,才能获取对应层级奖励 |
| | | for(int i = 0;i < 10; i++){ |
| | | if(systemProfitTotal.compareTo(levelProfitTotal) < 0){ |
| | | String inviteId = refererIdList.get(i); |
| | | //获取每层用户的直推人数,判断能否获得这个层级的层级奖励 |
| | | DappMemberEntity refererMember = dappMemberDao.selectMemberInfoByInviteId(inviteId); |
| | | //获取直推用户数量 |
| | | QueryWrapper<DappMemberEntity> objectQueryWrapper = new QueryWrapper<>(); |
| | | objectQueryWrapper.eq("referer_id",refererMember.getInviteId()); |
| | | Integer selectCount = dappMemberDao.selectCount(objectQueryWrapper); |
| | | if(i > selectCount){ |
| | | continue; |
| | | } |
| | | //获取对应层级奖励 |
| | | BigDecimal profit = LevelProfitEnum.YI.getProfit(i); |
| | | BigDecimal memberLevelProfit = levelProfitTotal.multiply(profit); |
| | | |
| | | DappFundFlowEntity fundFlow = new DappFundFlowEntity(refererMember.getId(), memberLevelProfit, 4, 2, BigDecimal.ZERO,null,dappSystemProfit.getId()); |
| | | dappFundFlowDao.insert(fundFlow); |
| | | systemProfitTotal = systemProfitTotal.add(memberLevelProfit); |
| | | } |
| | | } |
| | | //如果还有剩余给技术方 |
| | | if(levelProfitTotal.compareTo(systemProfitTotal) > 0){ |
| | | BigDecimal avaProfit = levelProfitTotal.subtract(systemProfit); |
| | | DappFundFlowEntity fundFlow = new DappFundFlowEntity(memberId, avaProfit, 5, 2, BigDecimal.ZERO,null,dappSystemProfit.getId()); |
| | | dappFundFlowDao.insert(fundFlow); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void memberOut(Long id) { |
| | | //获取当前是第几轮队列 |
| | | //判断当前是否符合出局条件 |
| | | //符合则出局,轮数+1 |
| | | } |
| | | |
| | | public static void main(String[] args) { |
| | | String refererIds = "1,2,3,4,5," + |
| | | "6,7,8,9,10," + |
| | | "11,12,13,14,15"; |
| | | List<String> refererIdList = StrUtil.split(refererIds, ','); |
| | | System.out.println(refererIdList); |
| | | } |
| | | } |
| | |
| | | import cn.hutool.core.date.DateField; |
| | | 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.Wrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| | |
| | | |
| | | private final ChainProducer chainProducer; |
| | | private final DappSystemDao dappSystemDao; |
| | | private final DappSystemProfitDao dappSystemProfitDao; |
| | | |
| | | @Override |
| | | public WalletInfoVo walletInfo() { |
| | |
| | | return dappAccountMoneyChangeDao.selectInPage(change, page); |
| | | } |
| | | |
| | | /** |
| | | * // 第一次{amount: val, fee: 0, txHash: '', type: 1, buyType: 2} |
| | | * // 成功{type: 1, txHash: result.transactionHash, id: res.data, flag: 'success', buyType: 2} |
| | | * // 失败{type: 1, id: res.data, flag: 'fail', buyType: 2} |
| | | */ |
| | | @Override |
| | | public Long transfer(TransferDto transferDto) { |
| | | DappMemberEntity member = LoginUserUtil.getAppUser(); |
| | |
| | | } |
| | | |
| | | if ("success".equals(transferDto.getFlag())) { |
| | | //插入一条会员入列记录,即加入动能队列 |
| | | DappSystemProfit dappSystemProfit = new DappSystemProfit(member.getId(), transferDto.getAmount()); |
| | | dappSystemProfitDao.insert(dappSystemProfit); |
| | | DappFundFlowEntity flow = dappFundFlowDao.selectById(transferDto.getId()); |
| | | flow.setFromHash(transferDto.getTxHash()); |
| | | flow.setSystemProfitId(dappSystemProfit.getId()); |
| | | dappFundFlowDao.updateById(flow); |
| | | |
| | | //直接拿走0.05个BNB放入技术方 |
| | | DataDictionaryCustom systemProfit = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(DataDictionaryEnum.SYSTEM_PROFIT.getType(), DataDictionaryEnum.SYSTEM_PROFIT.getCode()); |
| | | String systemProfitStr = StrUtil.isEmpty(systemProfit.getValue()) ? "0.05" : systemProfit.getValue(); |
| | | DappFundFlowEntity systemProfitFlow = new DappFundFlowEntity(member.getId(), new BigDecimal(systemProfitStr), 2, 2, BigDecimal.ZERO, transferDto.getTxHash(),dappSystemProfit.getId()); |
| | | dappFundFlowDao.insert(systemProfitFlow); |
| | | //直接返利30%给直接上级 |
| | | DappMemberEntity dappMemberEntity = dappMemberDao.selectById(member.getId()); |
| | | String refererId = dappMemberEntity.getRefererId(); |
| | | DappMemberEntity refererMember = dappMemberDao.selectMemberInfoByInviteId(refererId); |
| | | |
| | | DataDictionaryCustom directProfitSet = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(DataDictionaryEnum.DIRECT_PROFIT.getType(), DataDictionaryEnum.DIRECT_PROFIT.getCode()); |
| | | BigDecimal directProfitStr = new BigDecimal(StrUtil.isEmpty(directProfitSet.getValue()) ? "0.3" : directProfitSet.getValue()); |
| | | BigDecimal directProfit = (transferDto.getAmount().subtract(new BigDecimal(systemProfitStr))).multiply(directProfitStr).setScale(BigDecimal.ROUND_DOWN, 2); |
| | | |
| | | DappFundFlowEntity fundFlow = new DappFundFlowEntity(refererMember.getId(), directProfit, 3, 2, BigDecimal.ZERO, transferDto.getTxHash(),dappSystemProfit.getId()); |
| | | dappFundFlowDao.insert(fundFlow); |
| | | //层级奖励30% |
| | | chainProducer.sendLevelProfitMsg(dappSystemProfit.getId()); |
| | | //发送一个消息,计算当前是否有人可以出局 |
| | | |
| | | } else { |
| | | DappFundFlowEntity flow = dappFundFlowDao.selectById(transferDto.getId()); |
| | | if (flow.getStatus() == 1) { |
| | |
| | | * @date 2022-05-31 |
| | | **/ |
| | | public class QueueConstants { |
| | | |
| | | public static final String QUEUE_MEMBER_OUT = "queue_bnb_member_out"; |
| | | public static final String QUEUE_LEVEL_PROFIT = "queue_bnb_level_profit_transfer"; |
| | | |
| | | public static final String ONLINE_TRANSFER = "queue_sdm_online_transfer"; |
| | | public static final String DISTRIB_PROFIT = "queue_sdm_distrib_profit"; |
| | | public static final String USER_BUY_REWARD = "queue_sdm_user_buy_reward"; |
| | |
| | | |
| | | @Getter |
| | | public enum QueueEnum { |
| | | //计算是否有人出局 |
| | | MEMBER_OUT("exchange_bnb_member_out", "route_key_bnb_member_out", "queue_bnb_member_out"), |
| | | //层级奖励 |
| | | LEVEL_PROFIT("exchange_bnb_level_profit_transfer", "route_key_bnb_level_profit_transfer", "queue_bnb_level_profit_transfer"), |
| | | |
| | | ONLINE_TRANSFER("exchange_sdm_online_transfer", "route_key_sdm_online_transfer", "queue_sdm_online_transfer"), |
| | | DISTRIB_PROFIT("exchange_sdm_distrib_profit", "route_key_sdm_distrib_profit", "queue_sdm_distrib_profit"), |
| | |
| | | return BindingBuilder.bind(feeDistributeQueue()).to(feeDistributeExchange()).with(QueueEnum.DISTRIB_PROFIT.getRoute()); |
| | | } |
| | | // === 手续费分发 end === |
| | | |
| | | |
| | | |
| | | // === 层级奖励分发 start === |
| | | @Bean |
| | | public DirectExchange levelProfitExchange() { |
| | | return new DirectExchange(QueueEnum.LEVEL_PROFIT.getExchange()); |
| | | } |
| | | |
| | | @Bean |
| | | public Queue levelProfitQueue() { |
| | | return new Queue(QueueEnum.LEVEL_PROFIT.getQueue()); |
| | | } |
| | | |
| | | @Bean |
| | | public Binding levelProfitBind() { |
| | | return BindingBuilder.bind(levelProfitQueue()).to(levelProfitExchange()).with(QueueEnum.LEVEL_PROFIT.getRoute()); |
| | | } |
| | | // === 层级奖励分发 end === |
| | | |
| | | |
| | | |
| | | // === 计算是否有人出局 start === |
| | | @Bean |
| | | public DirectExchange memberOutExchange() { |
| | | return new DirectExchange(QueueEnum.MEMBER_OUT.getExchange()); |
| | | } |
| | | |
| | | @Bean |
| | | public Queue memberOutQueue() { |
| | | return new Queue(QueueEnum.MEMBER_OUT.getQueue()); |
| | | } |
| | | |
| | | @Bean |
| | | public Binding memberOutBind() { |
| | | return BindingBuilder.bind(memberOutQueue()).to(memberOutExchange()).with(QueueEnum.MEMBER_OUT.getRoute()); |
| | | } |
| | | // === 计算是否有人出局 end === |
| | | } |
| | |
| | | public void feeDistribute(String data) { |
| | | dappSystemService.feeDistribute(data); |
| | | } |
| | | |
| | | /**层级奖励分发消息 |
| | | * @param id |
| | | */ |
| | | @RabbitListener(queues = QueueConstants.QUEUE_LEVEL_PROFIT) |
| | | public void levelProfit(Long id) { |
| | | dappSystemService.levelProfit(id); |
| | | } |
| | | |
| | | /**计算是否有人出局分发消息 |
| | | * @param id |
| | | */ |
| | | @RabbitListener(queues = QueueConstants.QUEUE_MEMBER_OUT) |
| | | public void memberOut(Long id) { |
| | | dappSystemService.memberOut(id); |
| | | } |
| | | } |
| | |
| | | package cc.mrbird.febs.rabbit.producer; |
| | | |
| | | import cc.mrbird.febs.rabbit.QueueEnum; |
| | | import cn.hutool.core.date.DateUtil; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.amqp.rabbit.connection.CorrelationData; |
| | | import org.springframework.amqp.rabbit.core.RabbitTemplate; |
| | |
| | | CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString()); |
| | | rabbitTemplate.convertAndSend(QueueEnum.DISTRIB_PROFIT.getExchange(), QueueEnum.DISTRIB_PROFIT.getRoute(), id, correlationData); |
| | | } |
| | | |
| | | /** |
| | | * 层级奖励分发消息 |
| | | * |
| | | * 会员ID |
| | | * @param id |
| | | */ |
| | | public void sendLevelProfitMsg(Long id) { |
| | | log.info("层级奖励分发消息:{}", id); |
| | | CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString()); |
| | | rabbitTemplate.convertAndSend(QueueEnum.LEVEL_PROFIT.getExchange(), QueueEnum.LEVEL_PROFIT.getRoute(), id, correlationData); |
| | | } |
| | | |
| | | /** |
| | | * 计算是否有人出局分发消息 |
| | | */ |
| | | public void sendMemberOutMsg(Long id) { |
| | | log.info("计算是否有人出局:{}", DateUtil.now()); |
| | | CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString()); |
| | | rabbitTemplate.convertAndSend(QueueEnum.LEVEL_PROFIT.getExchange(), QueueEnum.LEVEL_PROFIT.getRoute(), id, correlationData); |
| | | } |
| | | } |