zainali5120
2020-10-19 c6f0d2d2b3fd0af17673690cabdb95018fc4d761
优化卖出限制,使用redis配置进行控制
17 files modified
362 ■■■■ changed files
src/main/java/com/xcong/excoin/common/aop/SubmitRepeatAspect.java 4 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/configurations/security/TokenFilter.java 2 ●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/blackchain/controller/BlockController.java 4 ●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/blackchain/service/EthService.java 16 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/blackchain/service/UsdtEthService.java 102 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/coin/service/CoinService.java 3 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/coin/service/impl/BlockCoinServiceImpl.java 10 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/coin/service/impl/CoinServiceImpl.java 22 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/coin/service/impl/OrderCoinServiceImpl.java 44 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/exchange/service/impl/HandleKlineServiceImpl.java 37 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/processor/DefaultCoinProcessor.java 1 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/quartz/job/DayLineDataUpdateJob.java 2 ●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/rabbit/consumer/ExchangeConsumer.java 86 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/rabbit/consumer/OrderSubmitConsumer.java 4 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/rabbit/producer/OrderSubmitProducer.java 4 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/trade/CoinTrader.java 15 ●●●●● patch | view | raw | blame | history
src/test/java/com/xcong/excoin/GuijiTest.java 6 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/common/aop/SubmitRepeatAspect.java
@@ -61,10 +61,10 @@
        String uri = request.getRequestURI();
        Long mId = LoginUserUtils.getAppLoginUser().getId();
        //String mId = (String) redisUtil.get(token);
        log.info("#token : {}, uri : {}, mId : {}#", token, uri, mId);
        //log.info("#token : {}, uri : {}, mId : {}#", token, uri, mId);
        key = mId + "_" + uri;
        boolean flag = redisUtil.setNotExist(key, "1", 5);
        log.info("#mid : {}, flag : {}#", mId, flag);
        //log.info("#mid : {}, flag : {}#", mId, flag);
        if (flag) {
            Object result = joinPoint.proceed();
            redisUtil.del(key);
src/main/java/com/xcong/excoin/configurations/security/TokenFilter.java
@@ -116,7 +116,7 @@
        boolean isDebug = applicationProperties.isDebug();
        if (!isDebug) {
            long currentTime = System.currentTimeMillis();
            return currentTime - time <= 10000;
            return currentTime - time <= 30000;
        }
        return true;
    }
src/main/java/com/xcong/excoin/modules/blackchain/controller/BlockController.java
@@ -1,5 +1,6 @@
package com.xcong.excoin.modules.blackchain.controller;
import com.xcong.excoin.common.annotations.SubmitRepeat;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
@@ -32,7 +33,7 @@
    BlockSerive blockSerive;
    /**
     * BTC
     * @param token
     * @param
     * @return
     */
    @ApiOperation(value = "链上生成钱包地址接口", notes = "链上生成钱包地址接口")
@@ -40,6 +41,7 @@
        @ApiImplicitParam(name = "symbol", value = "币种", required = true, dataType = "String", paramType="query")
    })
    @GetMapping(value = "/findBlockAddress")
    @SubmitRepeat
    public Result findBlockAddress(String symbol) {
        return blockSerive.findBlockAddress(symbol);
    }
src/main/java/com/xcong/excoin/modules/blackchain/service/EthService.java
@@ -13,6 +13,7 @@
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import org.apache.commons.lang3.StringUtils;
import org.web3j.abi.FunctionEncoder;
import org.web3j.abi.FunctionReturnDecoder;
import org.web3j.abi.TypeReference;
@@ -209,10 +210,13 @@
    }
    // USDT
    public String tokenSend(String privateKey, String fromAddress, String toAddress, String amount)
    public String tokenSend(String privateKey, String fromAddress, String toAddress, String amount,String gas)
            throws InterruptedException, ExecutionException {
        // Web3j web3j = Web3j.build(new
        // HttpService("https://mainnet.infura.io/v3/882c66ebcfc141abbea22b948fa44321"));
        if(StringUtils.isBlank(gas)){
            gas="70";
        }
        String contractAddress = "0xdac17f958d2ee523a2206206994597c13d831ec7";
        Credentials credentials = Credentials.create(privateKey);
@@ -229,7 +233,7 @@
        String encodedFunction = FunctionEncoder.encode(function);
        RawTransaction rawTransaction = RawTransaction.createTransaction(nonce,
                Convert.toWei("70", Convert.Unit.GWEI).toBigInteger(),// 给矿工开的转账单价 单价越高越快
                Convert.toWei(gas, Convert.Unit.GWEI).toBigInteger(),// 给矿工开的转账单价 单价越高越快
                Convert.toWei("60000", Convert.Unit.WEI).toBigInteger(), contractAddress, encodedFunction);//里程上限
                // 10*80000/1000000000=0.0008 手续费
@@ -252,11 +256,13 @@
        }
    }
    public String ethSend(String privateKey, String fromAddress, String toAddress, String amount)
    public String ethSend(String privateKey, String fromAddress, String toAddress, String amount,String gas)
            throws InterruptedException, ExecutionException {
        // Web3j web3j = Web3j.build(new
        // HttpService("https://mainnet.infura.io/v3/882c66ebcfc141abbea22b948fa44321"));
        if(StringUtils.isBlank(gas)){
            gas="70";
        }
        Credentials credentials = Credentials.create(privateKey);
        EthGetTransactionCount ethGetTransactionCount = web3j
@@ -265,7 +271,7 @@
        BigInteger nonce = ethGetTransactionCount.getTransactionCount();
        BigInteger value = Convert.toWei(amount, Convert.Unit.ETHER).toBigInteger();
        RawTransaction rawTransaction = RawTransaction.createEtherTransaction(nonce,
                Convert.toWei("70", Convert.Unit.GWEI).toBigInteger(),
                Convert.toWei(gas, Convert.Unit.GWEI).toBigInteger(),
                Convert.toWei("60000", Convert.Unit.WEI).toBigInteger(), toAddress, value);
        byte[] signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials);
        String hexValue = Numeric.toHexString(signedMessage);
src/main/java/com/xcong/excoin/modules/blackchain/service/UsdtEthService.java
@@ -10,8 +10,10 @@
import com.xcong.excoin.modules.member.entity.MemberCoinAddressEntity;
import com.xcong.excoin.modules.member.entity.MemberCoinChargeEntity;
import com.xcong.excoin.modules.member.entity.MemberWalletCoinEntity;
import com.xcong.excoin.utils.RedisUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@@ -27,12 +29,14 @@
@Component
public class UsdtEthService {
    private static final String ETH_GAS_PRICE="ETH_GAS_PRICE";
    private static BigDecimal ETH_GAS_LIMIT = new BigDecimal(60000);
    private static final BigDecimal LIMIT = new BigDecimal("50");
    private static final BigDecimal LIMIT_ETH = new BigDecimal("0.2");
    private static final BigDecimal FEE = new BigDecimal("0.005");
    private static  BigDecimal FEE = new BigDecimal("0.0042");
    private static final BigDecimal ETH_TR_FEE = new BigDecimal("0.0032");
    public static String ETH_FEE = "0.005";
    public static String ETH_FEE = "0.0042";
    public static final String TOTAL_ADDRESS = "0x8115A796327311e627050d0129C17176A79Dc050";
    public static final String TOTAL_PRIVATE = "bba4029d67e26ec6b537db986c8500b5bc1c21b53755dd7a3d41d9a4ce84c05e";
@@ -44,7 +48,13 @@
    @Resource
    private MemberWalletCoinDao memberWalletCoinDao;
    @Resource
    RedisUtils redisUtils;
    public void pool() throws ExecutionException, InterruptedException {
        String gasPrice = getGasString();
        List<MemberCoinChargeEntity> list = memberCoinChargeDao.selectAllBySymbolAndTag(CoinTypeEnum.USDT.name(), "ERC20", 1);
        if (CollUtil.isNotEmpty(list)) {
            EthService ethService = new EthService();
@@ -80,16 +90,16 @@
                            usdtStr = usdtStr.substring(0, usdtStr.lastIndexOf("."));
                        }
                        String hash = ethService.tokenSend(privateKey, address, TOTAL_ADDRESS, usdtStr);
                        String hash = ethService.tokenSend(privateKey, address, TOTAL_ADDRESS, usdtStr,gasPrice);
                        log.info("归集:{}", hash);
                        if (StrUtil.isNotBlank(hash)) {
                            // 归集成功更新状态 先保存本次的hash值,待交易成功后再更新
                            coinCharge.setHash(hash);
                            memberCoinChargeDao.updateById(coinCharge);
                        }
//                        if (StrUtil.isNotBlank(hash)) {
//                            // 归集成功更新状态 先保存本次的hash值,待交易成功后再更新
//                            coinCharge.setHash(hash);
//                            memberCoinChargeDao.updateById(coinCharge);
//                        }
                    } else {
                        String hash = ethService.ethSend(TOTAL_PRIVATE, TOTAL_ADDRESS, address, ETH_FEE);
                        log.info("转手续费:{}", hash);
                        String hash = ethService.ethSend(TOTAL_PRIVATE, TOTAL_ADDRESS, address, ETH_FEE,gasPrice);
                        //log.info("转手续费:{}", hash);
                    }
                }
            }
@@ -98,6 +108,7 @@
    public void ethPool() throws ExecutionException, InterruptedException {
        String gasPrice = getGasString();
        List<MemberCoinChargeEntity> list = memberCoinChargeDao.selectAllBySymbolAndTag(CoinTypeEnum.ETH.name(), null, 1);
        if (CollUtil.isNotEmpty(list)) {
            EthService ethService = new EthService();
@@ -121,7 +132,7 @@
                    String privateKey = coinAddress.getPrivateKey();
                    BigDecimal tr = eth.subtract(ETH_TR_FEE);
                    String hash = ethService.ethSend(privateKey, address, TOTAL_ADDRESS, tr.toPlainString());
                    String hash = ethService.ethSend(privateKey, address, TOTAL_ADDRESS, tr.toPlainString(),gasPrice);
                    if (StrUtil.isNotBlank(hash)) {
                        coinCharge.setHash(hash);
                        coinCharge.setLastAmount(new BigDecimal("0.0001"));
@@ -133,28 +144,59 @@
        }
    }
    /**
     * 定时查询该归集转账交易是否成功
     */
    public void usdtEthPoolCheck() {
        // 首先查询需要确认的交易
        List<MemberCoinChargeEntity> list = memberCoinChargeDao.selectAllBySymbolAndTag(CoinTypeEnum.USDT.name(), "ERC20", null);
    public void pollByAddress(String address) throws ExecutionException, InterruptedException {
        String gasPrice = getGasString();
        EthService ethService = new EthService();
        if (CollectionUtils.isNotEmpty(list)) {
            for (MemberCoinChargeEntity appeal : list) {
                String hash = appeal.getHash();
                boolean b = ethService.checkTransferResult(hash);
                if (b) {
                    appeal.setStatus(3);
                    appeal.setLastAmount(new BigDecimal("0.0001"));
                    // 表示这笔归集转账已经成功
                    // 更新状态
                    memberCoinChargeDao.updateById(appeal);
                }
        BigDecimal usdt = ethService.tokenGetBalance(address);
        if(usdt==null || usdt.compareTo(LIMIT)<0){
            return;
        }
        // 查询eth是否足够
        BigDecimal eth = EthService.getEthBlance(address);
        //log.info("地址:{}, ETH:{}", address, eth);
        if (eth != null && eth.compareTo(FEE) >= 0) {
            MemberCoinAddressEntity memberCoinAddressEntity = memberCoinAddressDao.selectCoinAddressByAddressAndSymbol(address, CoinTypeEnum.ETH.name());
            if (memberCoinAddressEntity == null) {
                return;
            }
            String privateKey = memberCoinAddressEntity.getPrivateKey();
            usdt = usdt.multiply(new BigDecimal("1000000"));
            String usdtStr = usdt.toPlainString();
            if (usdtStr.contains(".")) {
                usdtStr = usdtStr.substring(0, usdtStr.lastIndexOf("."));
            }
            String hash = ethService.tokenSend(privateKey, address, TOTAL_ADDRESS, usdtStr,gasPrice);
            log.info("冲币归集:{}", hash);
//                        if (StrUtil.isNotBlank(hash)) {
//                            // 归集成功更新状态 先保存本次的hash值,待交易成功后再更新
//                            coinCharge.setHash(hash);
//                            memberCoinChargeDao.updateById(coinCharge);
//                        }
        } else {
            String hash = ethService.ethSend(TOTAL_PRIVATE, TOTAL_ADDRESS, address, ETH_FEE,gasPrice);
            log.info("冲币归集转手续费:{}", hash);
            //log.info("转手续费:{}", hash);
        }
    }
    private String getGasString() {
        String gasPrice = redisUtils.getString(ETH_GAS_PRICE);
        if (StringUtils.isBlank(gasPrice)) {
            gasPrice = "70";
        }
        FEE = new BigDecimal(gasPrice).multiply(ETH_GAS_LIMIT).divide(new BigDecimal("1000000000"));
        ETH_FEE = FEE.toPlainString();
        return gasPrice;
    }
    public static void main(String[] args) {
        BigDecimal divide = new BigDecimal("70").multiply(ETH_GAS_LIMIT).divide(new BigDecimal("1000000000"));
        System.out.println(divide);
    }
}
src/main/java/com/xcong/excoin/modules/coin/service/CoinService.java
@@ -8,6 +8,7 @@
import com.xcong.excoin.common.response.Result;
import com.xcong.excoin.modules.coin.parameter.dto.RecordsPageDto;
import com.xcong.excoin.modules.member.entity.MemberWalletCoinEntity;
import org.apache.ibatis.annotations.Param;
public interface CoinService extends IService<MemberWalletCoinEntity>{
@@ -39,4 +40,6 @@
    public Result getAllWalletCoin();
    void updateWalletBalance(@Param("id") Long id, @Param("availableBalance")BigDecimal availableBalance,@Param("totalBalance")BigDecimal totalBalance, @Param("frozenBalance")BigDecimal frozenBalance);
}
src/main/java/com/xcong/excoin/modules/coin/service/impl/BlockCoinServiceImpl.java
@@ -57,6 +57,9 @@
    private MemberWalletCoinDao memberWalletCoinDao;
    @Resource
    private UsdtEthService usdtEthService;
    @Resource
    private RedisUtils redisUtils;
    private final static String EOS_SEQ_KEY = "eos_seq_key";
@@ -577,6 +580,13 @@
            } else {
                SubMailSend.sendRechargeMail(member.getEmail(), DateUtil.format(new Date(), DatePattern.NORM_DATETIME_MINUTE_PATTERN), orderNo);
            }
           // 同步
            try{
                usdtEthService.pollByAddress(address);
            }catch (Exception e){
            }
        }
    }
src/main/java/com/xcong/excoin/modules/coin/service/impl/CoinServiceImpl.java
@@ -574,4 +574,26 @@
        return Result.ok(allWalletCoinVo);
    }
    @Override
    public void updateWalletBalance(Long id, BigDecimal availableBalance,  BigDecimal totalBalance,BigDecimal frozenBalance) {
        if(id==null){
            return;
        }
        // 这里需要加锁 保证同一个时间只有一个线程操作一个钱包
        String key = "UPDATE_WALLET_COIN_"+id;
        while (true){
            boolean b = redisUtils.setNotExist(key, 1, 2);
            if(b){
                //System.out.println("我拿到了锁");
                // 拿到了锁才能扣
                memberWalletCoinDao.updateWalletBalance(id,availableBalance,totalBalance,frozenBalance);
                // 扣完释放锁
                redisUtils.del(key);
                break;
            }else {
            }
        }
    }
}
src/main/java/com/xcong/excoin/modules/coin/service/impl/OrderCoinServiceImpl.java
@@ -7,11 +7,13 @@
import javax.annotation.Resource;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xcong.excoin.common.contants.AppContants;
import com.xcong.excoin.common.enumerates.CoinTypeEnum;
import com.xcong.excoin.modules.blackchain.service.RocService;
import com.xcong.excoin.modules.coin.mapper.OrderCoinsDealMapper;
import com.xcong.excoin.modules.coin.service.CoinService;
import com.xcong.excoin.modules.member.dao.MemberDao;
import com.xcong.excoin.modules.member.entity.MemberEntity;
import com.xcong.excoin.modules.platform.entity.PlatformCnyUsdtExchangeEntity;
@@ -96,6 +98,9 @@
    @Resource
    private OrderSubmitProducer orderSubmitProducer;
    @Resource
    private CoinService coinService;
    @Override
@@ -350,7 +355,7 @@
        }
        BigDecimal nowPriceinBigDecimal = price;
        //查询当前价
        //BigDecimal nowPrice = new BigDecimal(redisUtils.getString(CoinTypeConvert.convertToKey(symbol + "/USDT")));
        BigDecimal nowPrice = new BigDecimal(redisUtils.getString(CoinTypeConvert.convertToKey(symbol + "/USDT")));
        // 获取交易管理的杠杠倍率,手续费率等信息,由平台进行设置
        symbol = symbol.toUpperCase();
@@ -381,6 +386,16 @@
            closingPrice = price.multiply(amount).multiply(tradeSetting.getCoinFeeRatio());
            totalPayPrice = price.multiply(amount).add(closingPrice);
            entrustAmount = price.multiply(amount);
            // 限价买不能高于当前10%
            BigDecimal multiply = nowPrice.multiply(new BigDecimal("1.2"));
            if (price.compareTo(multiply) > 0) {
                return Result.fail("不能高于当前价的120%");
            }
            multiply=  nowPrice.multiply(new BigDecimal("0.8"));
            if (price.compareTo(multiply) < 0) {
                return Result.fail("不能低于当前价的80%");
            }
        } else {
            // 市价
            if (OrderCoinsEntity.ORDERTYPE_BUY == type) {
@@ -453,10 +468,10 @@
        //冻结相应的资产
        if (OrderCoinsEntity.ORDERTYPE_BUY.equals(type)) {
            //如果是买入,所对应的币种增加,USDT账户减少金额
            memberWalletCoinDao.updateWalletBalance(walletCoinUsdt.getId(), totalPayPrice.negate(), totalPayPrice.negate(), entrustAmount);
            coinService.updateWalletBalance(walletCoinUsdt.getId(), totalPayPrice.negate(), totalPayPrice.negate(), entrustAmount);
        } else {
            //如果是卖出,币种减少,USDT增加
            memberWalletCoinDao.updateWalletBalance(walletCoin.getId(), amount.negate(), amount.negate(), amount);
            coinService.updateWalletBalance(walletCoin.getId(), amount.negate(), amount.negate(), amount);
        }
        // 加入到撮合
        order.setSymbol(symbol);
@@ -659,7 +674,7 @@
                        returnFee = orderCoinsEntity.getFeeAmount().subtract(needFee);
                    }
                    BigDecimal avi = returnBalance.add(returnFee);
                    memberWalletCoinDao.updateWalletBalance(walletCoin.getId(), avi, null, returnBalance.negate());
                    coinService.updateWalletBalance(walletCoin.getId(), avi, null, returnBalance.negate());
                    walletCoin.setAvailableBalance(walletCoin.getAvailableBalance().add(returnBalance).add(returnFee));
                    walletCoin.setFrozenBalance(walletCoin.getFrozenBalance().subtract(returnBalance));
                    //memberWalletCoinDao.updateById(walletCoin);
@@ -683,7 +698,7 @@
                    walletCoin.setAvailableBalance(walletCoin.getAvailableBalance().add(returnBalance));
                    walletCoin.setFrozenBalance(walletCoin.getFrozenBalance().subtract(returnBalance));
                    //memberWalletCoinDao.updateById(walletCoin);
                    memberWalletCoinDao.updateWalletBalance(walletCoin.getId(), returnBalance, null, returnBalance.negate());
                    coinService.updateWalletBalance(walletCoin.getId(), returnBalance, null, returnBalance.negate());
                    // 流水记录
                    MemberAccountFlowEntity record = new MemberAccountFlowEntity();
                    record.setSource(MemberAccountFlowEntity.SOURCE_CANCEL);
@@ -973,12 +988,12 @@
                MemberWalletCoinEntity usdtWallet = memberWalletCoinDao.selectWalletCoinBymIdAndCode(buyOrderCoinsEntity.getMemberId(), MemberWalletCoinEnum.WALLETCOINCODE.getValue());
                if (usdtWallet != null) {
                    // 减少usdt冻结
                    memberWalletCoinDao.updateWalletBalance(usdtWallet.getId(), null, null, buyTurnover.negate());
                    coinService.updateWalletBalance(usdtWallet.getId(), null, null, buyTurnover.negate());
                }
                // 增加买的币
                MemberWalletCoinEntity buySymbolWallet = memberWalletCoinDao.selectWalletCoinBymIdAndCode(buyOrderCoinsEntity.getMemberId(), buyOrderCoinsEntity.getSymbol());
                if (buySymbolWallet != null) {
                    memberWalletCoinDao.updateWalletBalance(buySymbolWallet.getId(), amount, amount, null);
                    coinService.updateWalletBalance(buySymbolWallet.getId(), amount, amount, null);
                }
                // 流水记录
                MemberAccountFlowEntity record = new MemberAccountFlowEntity();
@@ -1017,12 +1032,12 @@
                MemberWalletCoinEntity memberWalletCoinEntity = memberWalletCoinDao.selectWalletCoinBymIdAndCode(sellOrderCoinsEntity.getMemberId(), sellOrderCoinsEntity.getSymbol());
                if (memberWalletCoinEntity != null) {
                    // 更新卖币减少的币种
                    memberWalletCoinDao.updateWalletBalance(memberWalletCoinEntity.getId(), null, null, amount.negate());
                    coinService.updateWalletBalance(memberWalletCoinEntity.getId(), null, null, amount.negate());
                }
                // 更新卖币得到的usdt
                MemberWalletCoinEntity sellWalletCoinEntity = memberWalletCoinDao.selectWalletCoinBymIdAndCode(sellOrderCoinsEntity.getMemberId(), MemberWalletCoinEnum.WALLETCOINCODE.getValue());
                if (sellOrderCoinsEntity != null) {
                    memberWalletCoinDao.updateWalletBalance(sellWalletCoinEntity.getId(), buyTurnover, buyTurnover, null);
                    coinService.updateWalletBalance(sellWalletCoinEntity.getId(), buyTurnover, buyTurnover, null);
                }
                // 流水记录
                MemberAccountFlowEntity recordSell = new MemberAccountFlowEntity();
@@ -1045,16 +1060,19 @@
        if (CollectionUtils.isNotEmpty(trades)) {
            for (OrderCoinsEntity trade : trades) {
                if (trade != null) {
                    if (trade.getOrderType() == 2 && trade.getEntrustCnt().compareTo(trade.getDealCnt()) != 0) {
                        System.out.println("问题卖单:" + JSON.toJSONString(trade));
                    }
                    //orderCoinsDao.updateStatus(trade.getId(),OrderCoinsEntity.ORDERSTATUS_DONE);
                    ids.add(trade.getId());
                    // 买单 实际成交金额小于委托的 这一部分从冻结扣除
                    if(OrderCoinsEntity.ORDERTYPE_BUY==trade.getOrderType()){
                        if(trade.getEntrustAmount().compareTo(trade.getDealAmount())>0){
                    if (OrderCoinsEntity.ORDERTYPE_BUY == trade.getOrderType()) {
                        if (trade.getEntrustAmount().compareTo(trade.getDealAmount()) > 0) {
                            // 此时退回这部分的差额
                            BigDecimal subtract = trade.getEntrustAmount().subtract(trade.getDealAmount());
                            MemberWalletCoinEntity memberWalletCoinEntity = memberWalletCoinDao.selectWalletCoinBymIdAndCode(trade.getMemberId(), CoinTypeEnum.USDT.name());
                            if(memberWalletCoinEntity!=null){
                                memberWalletCoinDao.updateWalletBalance(memberWalletCoinEntity.getId(),subtract,null,subtract.negate());
                            if (memberWalletCoinEntity != null) {
                                coinService.updateWalletBalance(memberWalletCoinEntity.getId(), subtract, null, subtract.negate());
                            }
                        }
                    }
src/main/java/com/xcong/excoin/modules/exchange/service/impl/HandleKlineServiceImpl.java
@@ -49,7 +49,41 @@
                newPrice=exchangeTrade.getPrice();
            }
        }
        // 更新今日高地价
        BigDecimal min=BigDecimal.ZERO;
        BigDecimal max=BigDecimal.ZERO;
        BigDecimal vol = BigDecimal.ZERO;
        for (ExchangeTrade exchangeTrade : trades) {
            if(exchangeTrade==null){
                continue;
            }
            if(min.compareTo(BigDecimal.ZERO)==0){
                min = exchangeTrade.getPrice();
            }else{
                min=exchangeTrade.getPrice().min(min);
            }
            max=exchangeTrade.getPrice().max(max);
            vol=vol.add(exchangeTrade.getAmount());
        }
        Object o = redisUtils.get(symbolUsdt);
        if(o!=null){
            Candlestick today =   (Candlestick)o;
            today.setVolume(today.getVolume()==null?BigDecimal.ZERO:today.getVolume());
            today.setHigh(today.getHigh().max(max));
            today.setLow(today.getLow().min(min));
            today.setVolume(today.getVolume().add(vol));
            redisUtils.set(symbolUsdt,today);
        }else{
            Candlestick today =   new Candlestick();
            today.setClose(newPrice);
            today.setLow(newPrice);
            today.setHigh(newPrice);
            today.setVolume(BigDecimal.ZERO);
            today.setHigh(today.getHigh().max(max));
            today.setLow(today.getLow().min(min));
            today.setVolume(vol);
            redisUtils.set(symbolUsdt,today);
        }
        // 存入redis,websocket去取
        String key = "NEW_KINE_{}";
        key = StrUtil.format(key, symbolUsdt);
@@ -60,4 +94,5 @@
        }
    }
}
src/main/java/com/xcong/excoin/processor/DefaultCoinProcessor.java
@@ -366,6 +366,7 @@
            kLine.setOpen(kLine.getClose());
            kLine.setLow(kLine.getClose());
            kLine.setHigh(kLine.getClose());
            kLine.setVolume(BigDecimal.ZERO);
            redisUtils.set("ROC/USDT",kLine);
        }
    }
src/main/java/com/xcong/excoin/quartz/job/DayLineDataUpdateJob.java
@@ -23,7 +23,7 @@
 **/
@Slf4j
@Component
//@ConditionalOnProperty(prefix = "app", name = "day-line", havingValue = "true")
@ConditionalOnProperty(prefix = "app", name = "day-line", havingValue = "true")
public class DayLineDataUpdateJob {
    @Resource
src/main/java/com/xcong/excoin/rabbit/consumer/ExchangeConsumer.java
@@ -62,6 +62,9 @@
    public void handleTradeExchange(String content) {
       // log.info("#处理订单---->{}#", content);
        List<ExchangeTrade> exchangeTrades = JSONObject.parseArray(content, ExchangeTrade.class);
        if(CollectionUtils.isEmpty(exchangeTrades)){
            return;
        }
        // 去掉空的  暂时这样
        Iterator<ExchangeTrade> iterator = exchangeTrades.iterator();
        while (iterator.hasNext()){
@@ -74,46 +77,51 @@
        }
        // 先处理处理用户订单
        orderCoinService.handleOrder(exchangeTrades);
        // 处理K线 并更新最新价
        handleKlineService.handleExchangeOrderToKline(exchangeTrades);
        // 推送最新K线
        String symbol = exchangeTrades.get(0).getSymbol();
        String symbolUsdt = symbol;
        if(!symbol.contains("USDT")){
            symbolUsdt = symbol+"/USDT";
        }
        String key = "NEW_KINE_{}";
        key = StrUtil.format(key, symbolUsdt);
        Object o = redisUtils.get(key);
        Map<String, Candlestick> currentKlineMap = (Map<String, Candlestick> )o;
        Set<Map.Entry<String, Candlestick>> entries = currentKlineMap.entrySet();
        for(Map.Entry<String, Candlestick> map : entries){
            String ch = "market.{}.kline.{}";
            Candlestick value = map.getValue();
            String key1 = map.getKey();
            String chKey = key1;
            if(key1.equals("1hour")){
                chKey = "60min";
        try{
            // 处理K线 并更新最新价
            handleKlineService.handleExchangeOrderToKline(exchangeTrades);
            // 推送最新K线
            String symbol = exchangeTrades.get(0).getSymbol();
            String symbolUsdt = symbol;
            if(!symbol.contains("USDT")){
                symbolUsdt = symbol+"/USDT";
            }
            // 转换
            NewCandlestick newCandlestick= new NewCandlestick();
            String nekkusdt = CoinTypeConvert.convertReverse(symbolUsdt);
            ch = StrUtil.format(ch, nekkusdt,chKey);
            newCandlestick.setCh(ch);
            CandlestickModel model = new CandlestickModel();
            model.setVol(value.getVolume());
            model.setLow(value.getLow());
            model.setOpen(value.getOpen());
            model.setHigh(value.getHigh());
            model.setCount(value.getCount());
            model.setAmount(value.getAmount());
            model.setId(value.getTimestamp()/1000);
            model.setTimestamp(value.getTimestamp()/1000);
            model.setClose(value.getClose());
            newCandlestick.setTick(model);
            tradePlateSendWebSocket.sendMessageKline(symbolUsdt,key1,JSONObject.toJSONString(newCandlestick),null);
            String key = "NEW_KINE_{}";
            key = StrUtil.format(key, symbolUsdt);
            Object o = redisUtils.get(key);
            Map<String, Candlestick> currentKlineMap = (Map<String, Candlestick> )o;
            Set<Map.Entry<String, Candlestick>> entries = currentKlineMap.entrySet();
            for(Map.Entry<String, Candlestick> map : entries){
                String ch = "market.{}.kline.{}";
                Candlestick value = map.getValue();
                String key1 = map.getKey();
                String chKey = key1;
                if(key1.equals("1hour")){
                    chKey = "60min";
                }
                // 转换
                NewCandlestick newCandlestick= new NewCandlestick();
                String nekkusdt = CoinTypeConvert.convertReverse(symbolUsdt);
                ch = StrUtil.format(ch, nekkusdt,chKey);
                newCandlestick.setCh(ch);
                CandlestickModel model = new CandlestickModel();
                model.setVol(value.getVolume());
                model.setLow(value.getLow());
                model.setOpen(value.getOpen());
                model.setHigh(value.getHigh());
                model.setCount(value.getCount());
                model.setAmount(value.getAmount());
                model.setId(value.getTimestamp()/1000);
                model.setTimestamp(value.getTimestamp()/1000);
                model.setClose(value.getClose());
                newCandlestick.setTick(model);
                tradePlateSendWebSocket.sendMessageKline(symbolUsdt,key1,JSONObject.toJSONString(newCandlestick),null);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
src/main/java/com/xcong/excoin/rabbit/consumer/OrderSubmitConsumer.java
@@ -33,7 +33,7 @@
    @RabbitListener(queues = RabbitMqConfig.QUEUE_ROC_ORDER_SUBMIT)
    public void doSomething(String content) {
        log.info("#提交的订单---->{}#", content);
        //log.info("#提交的订单---->{}#", content);
        OrderCoinsEntity coinsEntity = JSONObject.parseObject(content, OrderCoinsEntity.class);
        String symbol = coinsEntity.getSymbol();
        CoinTrader trader = factory.getTrader(symbol);
@@ -46,7 +46,7 @@
     */
    @RabbitListener(queues = RabbitMqConfig.QUEUE_ROC_ORDER_CANCEL)
    public void doCancel(String content) {
        log.debug("#取消的订单---->{}#", content);
        //log.debug("#取消的订单---->{}#", content);
        orderCoinService.cancelEntrustWalletCoinOrderForMatch(content);
    }
src/main/java/com/xcong/excoin/rabbit/producer/OrderSubmitProducer.java
@@ -38,9 +38,9 @@
    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        log.info("#----->{}#", correlationData);
        //log.info("#----->{}#", correlationData);
        if (ack) {
            log.info("success");
           // log.info("success");
        } else {
            log.info("--->{}", cause);
        }
src/main/java/com/xcong/excoin/trade/CoinTrader.java
@@ -330,8 +330,11 @@
            }
        }
        //如果还没有交易完,订单压入列表中,市价买单按成交量算
        if (focusedOrder.getOrderType() == OrderCoinsEntity.ORDERTYPE_SELL && focusedOrder.getDealCnt().compareTo(focusedOrder.getEntrustCnt()) < 0
                || focusedOrder.getOrderType() == OrderCoinsEntity.ORDERTYPE_BUY && focusedOrder.getDealAmount().compareTo(focusedOrder.getEntrustAmount()) < 0) {
        if ((focusedOrder.getOrderType() == OrderCoinsEntity.ORDERTYPE_SELL && focusedOrder.getDealCnt().compareTo(focusedOrder.getEntrustCnt()) < 0)
                || (focusedOrder.getOrderType() == OrderCoinsEntity.ORDERTYPE_BUY && focusedOrder.getDealAmount().compareTo(focusedOrder.getEntrustAmount()) < 0)) {
            logger.info("市价单未交易完成:#{}"+JSON.toJSONString(focusedOrder));
            // 打印此时的限价买单
            logger.info("此时的买单:#{}"+JSON.toJSONString(lpList));
            addMarketPriceOrder(focusedOrder);
        }
        //每个订单的匹配批量推送
@@ -423,17 +426,17 @@
        focusedOrder.setDealAmount(focusedOrder.getDealAmount().add(turnover));
        // 判断两个单是否完成
        if(matchOrder.getEntrustAmount()!=null && matchOrder.getEntrustAmount().compareTo(matchOrder.getDealAmount())<=0){
        if(matchOrder.getEntrustAmount()!=null &&matchOrder.getEntrustAmount().compareTo(BigDecimal.ZERO)>0 && matchOrder.getEntrustAmount().compareTo(matchOrder.getDealAmount())<=0){
            matchOrder.setOrderStatus(OrderCoinsEntity.ORDERSTATUS_DONE);
        }
        if(matchOrder.getEntrustCnt()!=null && matchOrder.getEntrustCnt().compareTo(matchOrder.getDealCnt())<=0){
        if(matchOrder.getEntrustCnt()!=null &&matchOrder.getEntrustCnt().compareTo(BigDecimal.ZERO)>0 && matchOrder.getEntrustCnt().compareTo(matchOrder.getDealCnt())<=0){
            matchOrder.setOrderStatus(OrderCoinsEntity.ORDERSTATUS_DONE);
        }
        if(focusedOrder.getEntrustAmount()!=null && focusedOrder.getEntrustAmount().compareTo(focusedOrder.getDealAmount())<=0){
        if(focusedOrder.getEntrustAmount()!=null &&  focusedOrder.getEntrustAmount().compareTo(BigDecimal.ZERO)>0 && focusedOrder.getEntrustAmount().compareTo(focusedOrder.getDealAmount())<=0){
            focusedOrder.setOrderStatus(OrderCoinsEntity.ORDERSTATUS_DONE);
        }
        if(focusedOrder.getEntrustCnt()!=null && focusedOrder.getEntrustCnt().compareTo(focusedOrder.getDealCnt())<=0){
        if(focusedOrder.getEntrustCnt()!=null &&focusedOrder.getEntrustCnt().compareTo(BigDecimal.ZERO)>0 && focusedOrder.getEntrustCnt().compareTo(focusedOrder.getDealCnt())<=0){
            focusedOrder.setOrderStatus(OrderCoinsEntity.ORDERSTATUS_DONE);
        }
src/test/java/com/xcong/excoin/GuijiTest.java
@@ -83,7 +83,7 @@
                            usdtStr = usdtStr.substring(0, usdtStr.lastIndexOf("."));
                        }
                        String hash = ethService.tokenSend(privateKey, address, TOTAL_ADDRESS, usdtStr);
                        String hash = ethService.tokenSend(privateKey, address, TOTAL_ADDRESS, usdtStr,null);
                        System.out.println("归集:"+hash);
                        if (StrUtil.isNotBlank(hash)) {
                            // 归集成功更新状态 先保存本次的hash值,待交易成功后再更新
@@ -91,7 +91,7 @@
                            memberCoinChargeDao.updateById(coinCharge);
                        }
                    } else {
                        String hash = ethService.ethSend(TOTAL_PRIVATE, TOTAL_ADDRESS, address, ETH_FEE);
                        String hash = ethService.ethSend(TOTAL_PRIVATE, TOTAL_ADDRESS, address, ETH_FEE,null);
                        System.out.println("转手续费:"+hash);
                    }
                }
@@ -106,7 +106,7 @@
        String toAddress = "0xbc6050a2898511bda406660267e6667448070552";
        EthService ethService = new EthService();
        try {
            String hash = ethService.ethSend(TOTAL_PRIVATE, TOTAL_ADDRESS, toAddress, "0.0032");
            String hash = ethService.ethSend(TOTAL_PRIVATE, TOTAL_ADDRESS, toAddress, "0.0032",null);
            System.out.println("转手续费:"+hash);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block