KKSU
2024-04-22 ab2e891f19ff1af9d877a33a8c2a4a1a18881fb8
src/main/java/cc/mrbird/febs/dapp/service/impl/DappSystemServiceImpl.java
@@ -1,6 +1,8 @@
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.utils.LoginUserUtil;
import cc.mrbird.febs.common.utils.RedisUtils;
import cc.mrbird.febs.dapp.chain.ChainEnum;
@@ -9,19 +11,21 @@
import cc.mrbird.febs.dapp.dto.SystemDto;
import cc.mrbird.febs.dapp.entity.*;
import cc.mrbird.febs.dapp.mapper.*;
import cc.mrbird.febs.dapp.service.AsyncCjService;
import cc.mrbird.febs.dapp.service.DappSystemService;
import cc.mrbird.febs.dapp.utils.OnlineTransferUtil;
import cc.mrbird.febs.dapp.vo.RedisTransferPoolVo;
import cc.mrbird.febs.dapp.vo.SlipSettingVo;
import cc.mrbird.febs.job.SystemTradeJob;
import cc.mrbird.febs.rabbit.producer.ChainProducer;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
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.beans.factory.annotation.Autowired;
@@ -32,6 +36,7 @@
import java.math.BigInteger;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;
/**
 * @author 
@@ -50,6 +55,10 @@
    private final DataDictionaryCustomMapper dataDictionaryCustomMapper;
    private final DappOnlineTransferDao dappOnlineTransferDao;
    private final ChainProducer chainProducer;
    private final DappAchieveMapper dappAchieveMapper;
    private final DappAchieveItemMapper dappAchieveItemMapper;
    private final DappHdRecordMapper dappHdRecordMapper;
    private final AsyncCjService asyncCjService;
    @Override
@@ -62,6 +71,8 @@
        result.put("total", mineAddress.getBalance());
        result.put("addreessCnt", addresses.size());
        result.put("coinCnt", coinCnt);
        result.put("sourceTFC", ChainService.getInstance(ChainEnum.BSC_TFC.name()).balanceOf(ChainEnum.BSC_TFC_SOURCE.getAddress()));
        result.put("sourceUSDT", ChainService.getInstance(ChainEnum.BSC_USDT.name()).balanceOf(ChainEnum.BSC_USDT_SOURCE.getAddress()));
        return result;
    }
@@ -116,7 +127,14 @@
        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 minLimit = new BigDecimal(50);
        BigDecimal coinTotal;
        if (balance.compareTo(minLimit) > 0) {
            coinTotal = balance.multiply(BigDecimal.valueOf(0.3)).setScale(instance.decimals(), RoundingMode.HALF_DOWN);
        } else {
            coinTotal = new BigDecimal(50);
        }
        BigDecimal remain;
        if (o == null) {
            DateTime tomorrow = DateUtil.beginOfDay(DateUtil.tomorrow());
@@ -145,77 +163,260 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void tradeProfitDistribute(Long id) {
        DappFundFlowEntity fundflow = dappFundFlowDao.selectById(id);
        String batchNo = RandomUtil.randomString(16) + id.toString();
        asyncCjService.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, 2, BigDecimal.ROUND_DOWN);
//        //每一份有多少
//        BigDecimal divideEveryCoin = coinAmountReal.divide(totalPercent, 2, BigDecimal.ROUND_DOWN);
//        //1%用自身质押
//        selfHdPerk(selfPercent,divideEveryUsdt,divideEveryCoin);
//        //3%用于团队业绩计算
//        teamHdPerk(teamPercent,divideEveryUsdt,divideEveryCoin);
    }
        BigDecimal fee = fundflow.getFee();
        DappMemberEntity member = dappMemberDao.selectById(fundflow.getMemberId());
    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);
        if (StrUtil.isBlank(member.getRefererId()) || "0".equals(member.getRefererId())) {
        List<DappMemberEntity> dappMemberEntities = dappMemberDao.selectList(null);//获取全部成员
        if(CollUtil.isEmpty(dappMemberEntities)){
            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);
        // 源池
        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());
        // 销毁
        OnlineTransferUtil.addTransfer(AppContants.DESTROY_ADDRESS, destroy, fundflow.getType(), 3, ChainEnum.BSC_TFC_SOURCE.name(), AppContants.SYMBOL_COIN, batchNo);
        // 总分发金额
        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);
        if (CollUtil.isNotEmpty(parents)) {
            int i = 1;
            for (DappMemberEntity parent : parents) {
                BigDecimal balance = instance.balanceOf(parent.getAddress());
                log.info("地址:{}, 余额:{}", parent.getAddress(), balance);
                // 若地址持币少了指定数量
                if (balance.compareTo(new BigDecimal(miniHoldCoin.getValue())) < 0) {
                    continue;
        //如果没有进行中的质押,直接返回
        QueryWrapper<DappAchieve> objectQueryWrapper = new QueryWrapper<>();
        objectQueryWrapper.eq("state",DappAchieve.STATUS_ING);
        List<DappAchieve> dappAchieves = dappAchieveMapper.selectList(objectQueryWrapper);
        if(CollUtil.isEmpty(dappAchieves)){
            return;
        }
        //可以获取奖励的用户
        Map<Long, BigDecimal> memberPerkMap = new HashMap<>();
        //总团队业绩
        BigDecimal memberPerkTotal = BigDecimal.ZERO;
        //获取全部会员
        Set<Long> allMembers = dappMemberEntities.stream().map(DappMemberEntity::getId).collect(Collectors.toSet());
        //获取正在质押的会员ID
        Set<Long> achieveMembers = dappAchieves.stream().map(DappAchieve::getMemberId).collect(Collectors.toSet());
        Collection<Long> intersection = CollUtil.intersection(allMembers, achieveMembers);
        for(Long memberId : intersection){
            /**
             * 获取每一个成员的四级直推
             */
            DappMemberEntity dappMemberEntity = dappMemberDao.selectById(memberId);
            String inviteId = dappMemberEntity.getInviteId();
            List<String> inviteIds = new ArrayList<>();
            inviteIds.add(inviteId);
            //每一个账号的往下四级直推
            List<DappMemberEntity> downMembersList = new ArrayList<>();
            int teamLevel = Convert.toInt(redisUtils.getString(DataDicEnum.GFA_HUA_DIAN_LEVEL.getValue()));
            while(teamLevel >= 1){
                //获取直推用户
                List<DappMemberEntity> downMembers = dappMemberDao.selectChildMemberDirectOrNotInlist(inviteIds);
                if(CollUtil.isEmpty(downMembers)){
                    teamLevel = 0;
                }
                DataDictionaryCustom distribDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(AppContants.DIC_TYPE_DISTRIBUTE_PROP, String.valueOf(i));
                if (distribDic == null) {
                    break;
                }
                BigDecimal total = distrbAmount.multiply(new BigDecimal(distribDic.getValue()).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP));
                OnlineTransferUtil.addTransfer(parent.getAddress(), total, fundflow.getType(), 1, ChainEnum.BSC_TFC_SOURCE.name(), AppContants.SYMBOL_COIN, batchNo);
                DappFundFlowEntity distribFlow = new DappFundFlowEntity(parent.getId(), total, 4, 2, BigDecimal.ZERO);
                dappFundFlowDao.insert(distribFlow);
                nodeAmount = nodeAmount.subtract(total);
                i++;
                CollUtil.addAll(downMembersList,downMembers);
                List<String> collect = downMembers.stream().map(DappMemberEntity::getInviteId).collect(Collectors.toList());
                inviteIds.clear();
                inviteIds.addAll(collect);
                teamLevel = teamLevel -1;
            }
            if(CollUtil.isEmpty(downMembersList)){
                continue;
            }
            Set<Long> collect = downMembersList.stream().map(DappMemberEntity::getId).collect(Collectors.toSet());
            QueryWrapper<DappAchieve> queryWrapper = new QueryWrapper<>();
            queryWrapper.in("member_id",collect);
            queryWrapper.eq("state",DappAchieve.STATUS_ING);
            List<DappAchieve> 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);
        }
        // 若节点金额还有剩余,则进入技术金额
        techAmount = techAmount.add(nodeAmount);
        OnlineTransferUtil.addTransfer(ChainEnum.BSC_TFC_TECH.getAddress(), techAmount, fundflow.getType(), 2, ChainEnum.BSC_TFC_SOURCE.name(), AppContants.SYMBOL_COIN, batchNo);
        BigDecimal everyUsdt = multiplyDivideEveryUsdt.divide(memberPerkTotal,4,BigDecimal.ROUND_DOWN);
        BigDecimal everyCoin = multiplyDivideEveryCoin.divide(memberPerkTotal,4,BigDecimal.ROUND_DOWN);
        Set<Long> set = memberPerkMap.keySet(); // 得到所有key的集合
        for (Long memberId : set) {
            //当前生效中的团队业绩
            BigDecimal amountMember = memberPerkMap.get(memberId);
            //这个人实际可以分到的数量USDT
            BigDecimal multiplyUsdt = amountMember.multiply(everyUsdt).setScale(2, BigDecimal.ROUND_DOWN);
            //这个人实际可以分到的数量COIN
            BigDecimal multiplyCoin = divideEveryCoin.multiply(everyCoin).setScale(2, BigDecimal.ROUND_DOWN);
        Map<String, String> map = new HashMap<>();
        map.put("batchNo", batchNo);
        map.put("type", "batch");
            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(),
                    FlowTypeEnum.HUA_DIAN_TUANDUI_DAIBI.getDescrition(),
                    4,
                    1,
                    ChainEnum.BSC_TFC_REWARD.name(),
                    DataDicEnum.USDT_COIN.getValue(),
                    1);
        // 发送转账消息
        chainProducer.sendOnlineTransfer(JSONObject.toJSONString(map));
        }
    }
    public void selfHdPerk(int selfPercent,BigDecimal divideEveryUsdt,BigDecimal divideEveryCoin){
        QueryWrapper<DappAchieve> objectQueryWrapper = new QueryWrapper<>();
        objectQueryWrapper.eq("state",DappAchieve.STATUS_ING);
        List<DappAchieve> 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);
        BigDecimal everyUsdt = multiplyDivideEveryUsdt.divide(amountMemberTotal,4,BigDecimal.ROUND_DOWN);
        BigDecimal everyCoin = multiplyDivideEveryCoin.divide(amountMemberTotal,4,BigDecimal.ROUND_DOWN);
        Map<Long, List<DappAchieve>> collect = dappAchieves.stream().collect(Collectors.groupingBy(DappAchieve::getMemberId));
        Set<Long> 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(2, BigDecimal.ROUND_DOWN);
            //这个人实际可以分到的数量COIN
            BigDecimal multiplyCoin = divideEveryCoin.multiply(everyCoin).setScale(2, 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(),
                    FlowTypeEnum.HUA_DIAN_GEREN.getDescrition(),
                    4,
                    1,
                    ChainEnum.BSC_TFC_REWARD.name(),
                    DataDicEnum.GFA_COIN.getValue(),
                    1);
        }
    }
    /**
     * 插入流水记录,增加转账记录,发送线上转账的消息
     * @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<String, String> map = new HashMap<>();
                    map.put("batchNo", fundFlowTuiJian.getId().toString());
                    map.put("type", AppContants.SYMBOL_FLOW_TYPE_BATCH);
                    //发送链上转账消息
                    chainProducer.sendOnlineTransfer(JSONObject.toJSONString(map));
                }
            }else{
                asyncCjService.updateAmount(typeadd,memberId,multiplyUsdt);
            }
        }
    }
    @Override
    public void mining() {
@@ -270,7 +471,7 @@
        Map<String, String> map = new HashMap<>();
        map.put("batchNo", batchNo);
        map.put("type", "batch");
        map.put("type", AppContants.SYMBOL_FLOW_TYPE_BATCH);
        // 发送转账消息
        chainProducer.sendOnlineTransfer(JSONObject.toJSONString(map));
@@ -292,6 +493,7 @@
            }
            String txHash = ChainService.getInstance(transfer.getFromType()).transfer(transfer.getAddress(), transfer.getAmount());
            int retryTime = 0;//重试次数
            while (StrUtil.isEmpty(txHash)) {
                // 休眠2s
                try {
@@ -299,7 +501,13 @@
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                txHash = ChainService.getInstance(transfer.getFromType()).transfer(transfer.getAddress(), transfer.getAmount());
                if(retryTime < 3){
                    txHash = ChainService.getInstance(transfer.getFromType()).transfer(transfer.getAddress(), transfer.getAmount());
                }
                retryTime ++ ;
            }
            if(StrUtil.isEmpty(txHash)){
                return;
            }
            transfer.setTxHash(txHash);
@@ -307,7 +515,7 @@
            transfer.setUpdateTime(new Date());
            dappOnlineTransferDao.updateById(transfer);
            if ("flow".equals(jsonObject.getString("type"))) {
            if (AppContants.SYMBOL_FLOW_TYPE_FLOW.equals(jsonObject.getString("type"))) {
                DappFundFlowEntity fundFlow = dappFundFlowDao.selectById(Long.parseLong(batchNo));
                fundFlow.setToHash(txHash);
                dappFundFlowDao.updateById(fundFlow);
@@ -317,6 +525,12 @@
    @Override
    public void userBuyReward(Long id) {
        // 系统未启动不参与
        String hasStart = redisUtils.getString(AppContants.SYSTEM_START_FLAG);
        if (!"start".equals(hasStart)) {
            return;
        }
        DappFundFlowEntity fundFlow = dappFundFlowDao.selectById(id);
        DappMemberEntity member = dappMemberDao.selectById(fundFlow.getMemberId());
@@ -345,21 +559,127 @@
        chainProducer.sendOnlineTransfer(JSONObject.toJSONString(map));
    }
    @Autowired
    private SystemTradeJob systemTradeJob;
//    @Autowired
//    private SystemTradeJob systemTradeJob;
    @Override
    public void startSystem() {
        log.info("启动系统");
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                systemTradeJob.transferPoolVol();
                systemTradeJob.sourcePoolUsdtOutLimit();
            }
        });
//        Thread thread = new Thread(new Runnable() {
//            @Override
//            public void run() {
//                systemTradeJob.transferPoolVol();
//                systemTradeJob.sourcePoolUsdtOutLimit();
//            }
//        });
//
//        thread.start();
    }
        thread.start();
    @Override
    public void getZhiYaDelayMsg(Long achieveId) {
        DappAchieve dappAchieve = dappAchieveMapper.selectById(achieveId);
        if(ObjectUtil.isEmpty(dappAchieve)){
            return;
        }
        if(DappAchieve.STATUS_DONE == dappAchieve.getState()){
            return;
        }
        Long memberId = dappAchieve.getMemberId();
        BigDecimal amountDone = dappAchieve.getAmountDone();
        BigDecimal amountDay = dappAchieve.getAmountDay();
        BigDecimal amountMax = dappAchieve.getAmountMax();
        BigDecimal amountReal = BigDecimal.ZERO;//本次产出数量
        int flag = amountMax.compareTo(amountDone.add(amountDay));
        int state = DappAchieve.STATUS_ING;//判断质押任务是否继续
        if( flag > 0){
            amountReal = amountDay;
            amountDone = amountDone.add(amountDay);
        }else if (flag == 0){
            amountReal = amountDay;
            amountDone = amountMax;
            state = DappAchieve.STATUS_DONE;
        }else{
            amountReal = amountMax.subtract(amountDone);
            amountDone = amountMax;
            state = DappAchieve.STATUS_DONE;
        }
        if(BigDecimal.ZERO.compareTo(amountReal) < 0){
            /**
             * 更新主表记录
             * 插入一条子表记录
             * 插入一条流水记录
             * 发送链上转账记录
             */
            dappAchieve.setAmountDone(amountDone);
            dappAchieve.setState(state);
            dappAchieve.setUpdateTime(new Date());
            dappAchieveMapper.updateById(dappAchieve);
            DappAchieveItem dappAchieveItem = new DappAchieveItem();
            dappAchieveItem.setType(DappAchieveItem.TYPE_ZHI_YA);
            dappAchieveItem.setState(DappAchieveItem.STATUS_AGREE);
            dappAchieveItem.setAchieveId(achieveId);
            dappAchieveItem.setMemberId(memberId);
            dappAchieveItem.setAmount(amountReal);
            dappAchieveItemMapper.insert(dappAchieveItem);
            DappFundFlowEntity fundFlowTuiJian = new DappFundFlowEntity(
                    memberId,
                    amountReal,
                    FlowTypeEnum.ZHIYA_CHA_CHU.getValue(),
                    DappFundFlowEntity.WITHDRAW_STATUS_AGREE,
                    FlowTypeEnum.ZHIYA_CHA_CHU.getDescrition());
            dappFundFlowDao.insert(fundFlowTuiJian);
            //生成转账记录
            DappMemberEntity dappMemberEntity = dappMemberDao.selectById(memberId);
            if(ObjectUtil.isNotEmpty(dappMemberEntity)){
                OnlineTransferUtil.addTransfer(
                        dappMemberEntity.getAddress(),
                        amountReal,
                        3,//挖矿
                        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<String, String> map = new HashMap<>();
                map.put("batchNo", fundFlowTuiJian.getId().toString());
                map.put("type", AppContants.SYMBOL_FLOW_TYPE_FLOW);
                //发送链上转账消息
                chainProducer.sendOnlineTransfer(JSONObject.toJSONString(map));
            }
            //发送一个延时队列消息。24小时之后产生下一次的质押产出
//            chainProducer.sendZhiYaDelayMsg(dappAchieve.getId(), 24 * 60 * 60 * 1000L);
        }
    }
    @Override
    public void getZhiYaDelayMsgFlow(Long flowId) {
        DappFundFlowEntity dappFundFlowEntity = dappFundFlowDao.selectById(flowId);
        if(ObjectUtil.isEmpty(dappFundFlowEntity)){
            return;
        }
        Integer type = dappFundFlowEntity.getType();
        if(FlowTypeEnum.ZHI_YA.getValue() != type){
            return;
        }
        Integer status = dappFundFlowEntity.getStatus();
        if(DappFundFlowEntity.WITHDRAW_STATUS_AGREE == status){
            return;
        }
        if(StrUtil.isNotEmpty(dappFundFlowEntity.getFromHash())){
            return;
        }
        dappFundFlowDao.deleteById(flowId);
    }
}