package cc.mrbird.febs.dapp.service.impl; import cc.mrbird.febs.common.contants.AppContants; import cc.mrbird.febs.common.enumerates.DataDicEnum; import cc.mrbird.febs.common.enumerates.FlowTypeEnum; import cc.mrbird.febs.common.exception.FebsException; import cc.mrbird.febs.common.utils.RedisUtils; import cc.mrbird.febs.dapp.chain.ChainEnum; import cc.mrbird.febs.dapp.entity.*; import cc.mrbird.febs.dapp.mapper.*; import cc.mrbird.febs.dapp.service.AsyncCjService; import cc.mrbird.febs.dapp.utils.OnlineTransferUtil; import cc.mrbird.febs.rabbit.producer.ChainProducer; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.convert.Convert; 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 com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import java.math.BigDecimal; import java.util.*; import java.util.stream.Collectors; @Slf4j @Service @RequiredArgsConstructor public class AsyncCjServiceImpl extends ServiceImpl implements AsyncCjService { private final RedisUtils redisUtils; private final DataDictionaryCustomMapper dataDictionaryCustomMapper; private final DappMemberDao dappMemberDao; private final DappFundFlowDao dappFundFlowDao; private final DappAchieveMapper dappAchieveMapper; private final DappAchieveItemMapper dappAchieveItemMapper; private final ChainProducer chainProducer; private final DappHdRecordMapper dappHdRecordMapper; @Override public void redisCacheUpdate(String key, Object value, long time) { String existToken = redisUtils.getString(key); if (StrUtil.isNotBlank(existToken)) { redisUtils.del(existToken); } redisUtils.set(key, value, time); } @Override public void updateDataDicEnumRedis(List nameList) { if(CollUtil.isEmpty(nameList)){ return; } for(String name : nameList){ DataDictionaryCustom dataDictionaryCustom = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(name, name); if(ObjectUtil.isEmpty(dataDictionaryCustom)){ continue; } if(DataDicEnum.GFA_PRICE.getValue().equals(name)){ continue; } String existToken = redisUtils.getString(dataDictionaryCustom.getCode()); if (StrUtil.isNotBlank(existToken)) { redisUtils.del(existToken); } redisUtils.set(dataDictionaryCustom.getCode(), dataDictionaryCustom.getValue(), 0); } } @Override public void updateAmount(Integer type, Long memberId, BigDecimal amount) { DappMemberEntity dappMemberEntity = dappMemberDao.selectById(memberId); BigDecimal usdtBalance = dappMemberEntity.getUsdtBalance(); BigDecimal balance = dappMemberEntity.getBalance(); if(1== type){ dappMemberEntity.setBalance(balance.add(amount)); dappMemberDao.updateBalanceWithVersion(dappMemberEntity); } if(2== type){ dappMemberEntity.setUsdtBalance(usdtBalance.add(amount)); dappMemberDao.updateUsdtBalanceWithVersion(dappMemberEntity); } } @Override public void insertTeamPerk(Long flowId, Long achieveId) { //更新第一次请求的资金划转记录 DappFundFlowEntity flow = dappFundFlowDao.selectById(flowId); if(ObjectUtil.isEmpty(flow)){ return; } //用户质押代币数量 BigDecimal amount = flow.getAmount().negate(); Long memberId = flow.getMemberId(); DappMemberEntity member = dappMemberDao.selectById(memberId); /* 新增推荐奖 * 团队总奖励 * 团队奖励层级 * 团队总奖励/团队奖励层级 = 每一个层级应该获得的推荐奖励代币 */ //团队的所占比例 BigDecimal tuanDuiPerkTimes = new BigDecimal(redisUtils.getString(DataDicEnum.GFA_TUAN_DUI_PERCENT.getValue())); BigDecimal tuanDuiPercent = new BigDecimal("0.01") .multiply(tuanDuiPerkTimes .setScale(4,BigDecimal.ROUND_DOWN)); BigDecimal tuanDuiPerkTotal = tuanDuiPercent.multiply(amount).setScale(4,BigDecimal.ROUND_DOWN); Integer tuanDuiLevel = Convert.toInt(redisUtils.getString(DataDicEnum.GFA_TUAN_DUI_LEVEL.getValue())); //分成【团队的所占比例】的份数 BigDecimal tuanDuiPerk = tuanDuiPerkTotal.divide(tuanDuiPerkTimes, 4, BigDecimal.ROUND_DOWN); //团队奖励对象 HashMap objectObjectHashMap = new HashMap<>();//累计奖励的用户集合 Long refMemberId = memberId;//循环的上级用户ID Integer dappMembersSize = 0;//累计层级数量 boolean flag = true; while (flag){ //累计四级,停止返回 if(dappMembersSize >= tuanDuiLevel){ flag = false; }else{ DappMemberEntity dappMemberEntity = dappMemberDao.selectById(refMemberId); if(ObjectUtil.isEmpty(dappMemberEntity.getRefererId())){ flag = false; }else{ DappMemberEntity dappMemberRef = dappMemberDao.selectMemberInfoByInviteId(dappMemberEntity.getRefererId()); if(ObjectUtil.isEmpty(dappMemberRef)){ flag = false; }else{ objectObjectHashMap.put(dappMembersSize,dappMemberRef); refMemberId = dappMemberRef.getId(); dappMembersSize ++; } } } } if(CollUtil.isEmpty(objectObjectHashMap)){ return; } for (Map.Entry entry : objectObjectHashMap.entrySet()) { Integer key = entry.getKey(); DappMemberEntity refMember = entry.getValue(); BigDecimal perkPercent = BigDecimal.ZERO; if(key == 0){ perkPercent = new BigDecimal(redisUtils.getString(DataDicEnum.GFA_TUAN_DUI_LEVEL_YI.getValue())).setScale(4, BigDecimal.ROUND_DOWN); } if(key == 1){ perkPercent = new BigDecimal(redisUtils.getString(DataDicEnum.GFA_TUAN_DUI_LEVEL_YI.getValue())).setScale(4, BigDecimal.ROUND_DOWN); } if(key == 2){ perkPercent = new BigDecimal(redisUtils.getString(DataDicEnum.GFA_TUAN_DUI_LEVEL_YI.getValue())).setScale(4, BigDecimal.ROUND_DOWN); } if(key == 3){ perkPercent = new BigDecimal(redisUtils.getString(DataDicEnum.GFA_TUAN_DUI_LEVEL_YI.getValue())).setScale(4, BigDecimal.ROUND_DOWN); } if(key == 4){ perkPercent = new BigDecimal(redisUtils.getString(DataDicEnum.GFA_TUAN_DUI_LEVEL_WU.getValue())).setScale(4, BigDecimal.ROUND_DOWN); } BigDecimal realPerk = tuanDuiPerk.multiply(perkPercent).setScale(4, BigDecimal.ROUND_DOWN); if(BigDecimal.ZERO.compareTo(realPerk) >= 0){ continue; } QueryWrapper objectQueryWrapper = new QueryWrapper<>(); objectQueryWrapper.eq("member_id",refMember.getId()); objectQueryWrapper.eq("state",DappAchieve.STATUS_ING); List dappAchieves = dappAchieveMapper.selectList(objectQueryWrapper); if(CollUtil.isEmpty(dappAchieves)){ DappFundFlowEntity fundFlowTuiJian = new DappFundFlowEntity( refMember.getId(), realPerk, FlowTypeEnum.TUAN_DUI_FAIL.getValue(), DappFundFlowEntity.WITHDRAW_STATUS_AGREE, FlowTypeEnum.TUAN_DUI_FAIL.getDescrition(), member.getAddress(), refMember.getAddress()); dappFundFlowDao.insert(fundFlowTuiJian); continue; } DappAchieveItem dappAchieveItem = new DappAchieveItem(); dappAchieveItem.setAchieveId(achieveId); dappAchieveItem.setType(DappAchieveItem.TYPE_TUI_JIAN); dappAchieveItem.setState(DappAchieveItem.STATUS_AGREE); dappAchieveItem.setMemberId(refMember.getId()); dappAchieveItem.setAmount(realPerk); dappAchieveItemMapper.insert(dappAchieveItem); DappFundFlowEntity fundFlowTuiJian = new DappFundFlowEntity( refMember.getId(), realPerk, FlowTypeEnum.TUAN_DUI.getValue(), DappFundFlowEntity.WITHDRAW_STATUS_AGREE, FlowTypeEnum.TUAN_DUI.getDescrition(), member.getAddress(), refMember.getAddress()); dappFundFlowDao.insert(fundFlowTuiJian); //生成转账记录 OnlineTransferUtil.addTransfer( refMember.getAddress(), realPerk, 4,//推荐奖 1,//普通账户 ChainEnum.BSC_TFC_REWARD.name(), DataDicEnum.GFA_COIN.getValue(), fundFlowTuiJian.getId().toString()); Integer systemFlag = Integer.parseInt(redisUtils.getString(DataDicEnum.GFA_ZHUAN_ZHANG_KAI_GUAN.getValue())); if(1 == systemFlag) { Map map = new HashMap<>(); map.put("batchNo", fundFlowTuiJian.getId().toString()); map.put("type", AppContants.SYMBOL_FLOW_TYPE_FLOW); //发送链上转账消息 chainProducer.sendOnlineTransfer(JSONObject.toJSONString(map)); }else{ this.updateAmount(1,refMember.getId(),realPerk); } } BigDecimal gfaDays = new BigDecimal(redisUtils.getString(DataDicEnum.GFA_DAYS.getValue())).setScale(2,BigDecimal.ROUND_DOWN); //更新每日限额的质押总数 gfaDays = gfaDays.add(flow.getAmount()).setScale(4,BigDecimal.ROUND_DOWN); dataDictionaryCustomMapper.updateDicValueByTypeAndCode( DataDicEnum.GFA_DAYS.getValue(), DataDicEnum.GFA_DAYS.getValue(), gfaDays.toString() ); this.redisCacheUpdate(DataDicEnum.GFA_DAYS.getValue(),gfaDays.toString(),0); } @Override public void tradeProfitDistribute() { /** * 获取滑点钱包的代币余额A和U余额B * 获取最新一条的记录C,然后A-C.A,B-C.B,获得这段时间内的滑点新增D * 用D来进行划定分配 * 并且生成一条新的记录dappHdRecord,用来下次分配参照 */ //当天实际当天滑点 BigDecimal gfaPrice = new BigDecimal( redisUtils.getString(DataDicEnum.GFA_PRICE.getValue()) ).setScale(2,BigDecimal.ROUND_DOWN); BigDecimal usdtAmount = new BigDecimal( redisUtils.getString(DataDicEnum.GFA_HUA_DIAN_WALLET_USDT_AMOUNT.getValue()) ).setScale(2,BigDecimal.ROUND_DOWN); BigDecimal coinAmount = new BigDecimal( redisUtils.getString(DataDicEnum.GFA_HUA_DIAN_WALLET_COIN_AMOUNT.getValue()) ).setScale(2,BigDecimal.ROUND_DOWN); if(BigDecimal.ZERO.compareTo(usdtAmount) > 0){ return; } if(BigDecimal.ZERO.compareTo(coinAmount) > 0){ return; } BigDecimal usdtAmountReal = usdtAmount; BigDecimal coinAmountReal = coinAmount; //生成一条记录 DappHdRecord dappHdRecordAdd = new DappHdRecord(); dappHdRecordAdd.setPrice(gfaPrice); dappHdRecordAdd.setUsdtEvery(usdtAmountReal); dappHdRecordAdd.setUsdtAmount(usdtAmountReal); dappHdRecordAdd.setCoinEvery(coinAmountReal); dappHdRecordAdd.setCoinAmount(coinAmountReal); dappHdRecordMapper.insert(dappHdRecordAdd); /** * 5%滑奖分配: * 1%用自身质押 * 3%用于团队业绩计算 * 1%用于布道者奖励 */ int selfPercent = Convert.toInt(redisUtils.getString(DataDicEnum.GFA_HUA_DIAN_SELF.getValue())); int teamPercent = Convert.toInt(redisUtils.getString(DataDicEnum.GFA_HUA_DIAN_TEAM.getValue())); int workPercent = Convert.toInt(redisUtils.getString(DataDicEnum.GFA_HUA_DIAN_WORK.getValue())); //平分份数 BigDecimal totalPercent = new BigDecimal(selfPercent + teamPercent + workPercent); //每一份有多少 BigDecimal divideEveryUsdt = usdtAmountReal.divide(totalPercent, 4, BigDecimal.ROUND_DOWN); //每一份有多少 BigDecimal divideEveryCoin = coinAmountReal.divide(totalPercent, 4, BigDecimal.ROUND_DOWN); //1%用自身质押 selfHdPerk(selfPercent,divideEveryUsdt,divideEveryCoin); //3%用于团队业绩计算 teamHdPerk(teamPercent,divideEveryUsdt,divideEveryCoin); } public void teamHdPerk(int teamPercent,BigDecimal divideEveryUsdt,BigDecimal divideEveryCoin){ //3%用于团队业绩计算 BigDecimal teamPercentMultiply = new BigDecimal(teamPercent); BigDecimal multiplyDivideEveryUsdt = divideEveryUsdt.multiply(teamPercentMultiply); BigDecimal multiplyDivideEveryCoin = divideEveryCoin.multiply(teamPercentMultiply); List dappMemberEntities = dappMemberDao.selectList(null);//获取全部成员 if(CollUtil.isEmpty(dappMemberEntities)){ return; } //如果没有进行中的质押,直接返回 QueryWrapper objectQueryWrapper = new QueryWrapper<>(); objectQueryWrapper.eq("state",DappAchieve.STATUS_ING); List dappAchieves = dappAchieveMapper.selectList(objectQueryWrapper); if(CollUtil.isEmpty(dappAchieves)){ return; } //可以获取奖励的用户 Map memberPerkMap = new HashMap<>(); //总团队业绩 BigDecimal memberPerkTotal = BigDecimal.ZERO; //获取全部会员 Set allMembers = dappMemberEntities.stream().map(DappMemberEntity::getId).collect(Collectors.toSet()); //获取正在质押的会员ID Set achieveMembers = dappAchieves.stream().map(DappAchieve::getMemberId).collect(Collectors.toSet()); Collection intersection = CollUtil.intersection(allMembers, achieveMembers); for(Long memberId : intersection){ /** * 获取每一个成员的四级直推 */ DappMemberEntity dappMemberEntity = dappMemberDao.selectById(memberId); String inviteId = dappMemberEntity.getInviteId(); List inviteIds = new ArrayList<>(); inviteIds.add(inviteId); //每一个账号的往下四级直推 List downMembersList = new ArrayList<>(); int teamLevel = Convert.toInt(redisUtils.getString(DataDicEnum.GFA_HUA_DIAN_LEVEL.getValue())); while(teamLevel >= 1){ //获取直推用户 List downMembers = dappMemberDao.selectChildMemberDirectOrNotInlist(inviteIds); if(CollUtil.isEmpty(downMembers)){ teamLevel = 0; } CollUtil.addAll(downMembersList,downMembers); List collect = downMembers.stream().map(DappMemberEntity::getInviteId).collect(Collectors.toList()); inviteIds.clear(); inviteIds.addAll(collect); teamLevel = teamLevel -1; } if(CollUtil.isEmpty(downMembersList)){ continue; } Set collect = downMembersList.stream().map(DappMemberEntity::getId).collect(Collectors.toSet()); QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.in("member_id",collect); queryWrapper.eq("state",DappAchieve.STATUS_ING); List dappAchieveSumList = dappAchieveMapper.selectList(queryWrapper); //个人团队总业绩 BigDecimal teamAchieveMemberSum = dappAchieveSumList.stream().map(DappAchieve::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add); if(BigDecimal.ZERO.compareTo(teamAchieveMemberSum) >= 0){ continue; } memberPerkTotal = memberPerkTotal.add(teamAchieveMemberSum); memberPerkMap.put(memberId,teamAchieveMemberSum); } if(BigDecimal.ZERO.compareTo(memberPerkTotal) >= 0){ return; } BigDecimal everyUsdt = multiplyDivideEveryUsdt.divide(memberPerkTotal,4,BigDecimal.ROUND_DOWN); BigDecimal everyCoin = multiplyDivideEveryCoin.divide(memberPerkTotal,4,BigDecimal.ROUND_DOWN); Set set = memberPerkMap.keySet(); // 得到所有key的集合 for (Long memberId : set) { //当前生效中的团队业绩 BigDecimal amountMember = memberPerkMap.get(memberId); //这个人实际可以分到的数量USDT BigDecimal multiplyUsdt = amountMember.multiply(everyUsdt).setScale(4, BigDecimal.ROUND_DOWN); //这个人实际可以分到的数量COIN BigDecimal multiplyCoin = amountMember.multiply(everyCoin).setScale(4, BigDecimal.ROUND_DOWN); // createFlow( // multiplyUsdt, // memberId, // FlowTypeEnum.HUA_DIAN_TUANDUI_USDT.getValue(), // FlowTypeEnum.HUA_DIAN_TUANDUI_USDT.getDescrition(), // 4, // 1, // ChainEnum.BSC_TFC_REWARD.name(), // DataDicEnum.USDT_COIN.getValue(), // 2); createFlow( multiplyCoin, memberId, FlowTypeEnum.HUA_DIAN_TUANDUI_DAIBI.getValue(), StrUtil.format(FlowTypeEnum.HUA_DIAN_TUANDUI_DAIBI.getDescrition(), amountMember), 4, 1, ChainEnum.BSC_TFC_REWARD.name(), DataDicEnum.USDT_COIN.getValue(), 1); } } public void selfHdPerk(int selfPercent,BigDecimal divideEveryUsdt,BigDecimal divideEveryCoin){ QueryWrapper objectQueryWrapper = new QueryWrapper<>(); objectQueryWrapper.eq("state",DappAchieve.STATUS_ING); List dappAchieves = dappAchieveMapper.selectList(objectQueryWrapper); if(CollUtil.isEmpty(dappAchieves)){ return; } BigDecimal selfPercentMultiply = new BigDecimal(selfPercent); BigDecimal multiplyDivideEveryUsdt = divideEveryUsdt.multiply(selfPercentMultiply); BigDecimal multiplyDivideEveryCoin = divideEveryCoin.multiply(selfPercentMultiply); //当前生效中的质押总数 BigDecimal amountMemberTotal = dappAchieves.stream().map(DappAchieve::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add); if(BigDecimal.ZERO.compareTo(amountMemberTotal) >= 0){ return; } BigDecimal everyUsdt = multiplyDivideEveryUsdt.divide(amountMemberTotal,4,BigDecimal.ROUND_DOWN); BigDecimal everyCoin = multiplyDivideEveryCoin.divide(amountMemberTotal,4,BigDecimal.ROUND_DOWN); Map> collect = dappAchieves.stream().collect(Collectors.groupingBy(DappAchieve::getMemberId)); Set set = collect.keySet(); // 得到所有key的集合 for (Long memberId : set) { //当前每个人生效中的质押总数 BigDecimal amountMember = collect.get(memberId).stream().map(DappAchieve::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add); //这个人实际可以分到的数量USDT BigDecimal multiplyUsdt = amountMember.multiply(everyUsdt).setScale(4, BigDecimal.ROUND_DOWN); //这个人实际可以分到的数量COIN BigDecimal multiplyCoin = amountMember.multiply(everyCoin).setScale(4, BigDecimal.ROUND_DOWN); // createFlow( // multiplyUsdt, // memberId, // FlowTypeEnum.HUA_DIAN_GEREN.getValue(), // FlowTypeEnum.HUA_DIAN_GEREN.getDescrition(), // 4, // 1, // ChainEnum.BSC_TFC_REWARD.name(), // DataDicEnum.USDT_COIN.getValue(), // 2); createFlow( multiplyCoin, memberId, FlowTypeEnum.HUA_DIAN_GEREN.getValue(), StrUtil.format(FlowTypeEnum.HUA_DIAN_GEREN.getDescrition(), amountMember), 4, 1, ChainEnum.BSC_TFC_REWARD.name(), DataDicEnum.GFA_COIN.getValue(), 1); } } public static void main(String[] args) { String format = StrUtil.format(FlowTypeEnum.HUA_DIAN_GEREN.getDescrition(), 100); System.out.println(format); } /** * 插入流水记录,增加转账记录,发送线上转账的消息 * @param multiplyUsdt * @param memberId * @param type * @param description * @param typeTransfer * @param targetType * @param chainEnumName * @param coinType */ public void createFlow(BigDecimal multiplyUsdt,Long memberId,Integer type,String description,Integer typeTransfer, Integer targetType,String chainEnumName,String coinType,Integer typeadd){ if (BigDecimal.ZERO.compareTo(multiplyUsdt) < 0) { DappFundFlowEntity fundFlowTuiJian = new DappFundFlowEntity( memberId, multiplyUsdt, type, DappFundFlowEntity.WITHDRAW_STATUS_AGREE, description); dappFundFlowDao.insert(fundFlowTuiJian); Integer systemFlag = Integer.parseInt(redisUtils.getString(DataDicEnum.GFA_ZHUAN_ZHANG_KAI_GUAN.getValue())); if (1 == systemFlag) { //生成转账记录 DappMemberEntity dappMemberEntity = dappMemberDao.selectById(memberId); if (ObjectUtil.isNotEmpty(dappMemberEntity)) { OnlineTransferUtil.addTransfer( dappMemberEntity.getAddress(), multiplyUsdt, typeTransfer,//挖矿 targetType,//普通账户 chainEnumName, coinType, fundFlowTuiJian.getId().toString()); Map map = new HashMap<>(); map.put("batchNo", fundFlowTuiJian.getId().toString()); map.put("type", AppContants.SYMBOL_FLOW_TYPE_BATCH); //发送链上转账消息 chainProducer.sendOnlineTransfer(JSONObject.toJSONString(map)); } }else{ this.updateAmount(typeadd,memberId,multiplyUsdt); } } } }