zainali5120
2020-12-01 ce3b47fdf62926f80510a94f7a520dbf05267d6d
src/main/java/com/xcong/excoin/modules/coin/service/impl/OrderCoinServiceImpl.java
@@ -1,17 +1,21 @@
package com.xcong.excoin.modules.coin.service.impl;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
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.DateUtil;
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 +100,16 @@
    @Resource
    private OrderSubmitProducer orderSubmitProducer;
    @Resource
    private CoinService coinService;
    private static BigDecimal PERSENT = new BigDecimal("100");
    /**
     *  每日卖出限制 日期 20201128 会员ID
     */
    String LIMIT_SELL_PERSENT_KEY ="SELL:PERSENT:%s:%s";
    @Override
@@ -352,37 +366,34 @@
        String phone = memberEntity.getPhone();
        if (!"13632989240".equals(phone) && !"15158130575".equals(phone)) {
            if (OrderCoinsEntity.ORDERTYPE_BUY.equals(type)) {
                // 不能超过800个
                // 禁止挂卖
                String string = redisUtils.getString("BUY_LIMIT_KEY_PHONE");
                if (StringUtils.isNotBlank(string) && StringUtils.isNotBlank(phone) && string.contains(phone)) {
                    return Result.fail("");
                }
//                if (amount != null && amount.compareTo(new BigDecimal("800")) > 0) {
//                    return Result.fail("买入额度受限");
//                }
//                BigDecimal bigDecimal = orderCoinDealDao.sumTodayBuyAmount(memberId, symbol);
//                if (bigDecimal == null) {
//                    bigDecimal = BigDecimal.ZERO;
//                }
//                amount = amount == null ? BigDecimal.ZERO : amount;
//                bigDecimal = bigDecimal.add(amount);
//                if (bigDecimal != null && bigDecimal.compareTo(new BigDecimal("800")) > 0) {
//                    return Result.fail("买入额度受限");
//                }
//                // 挂单不能超过800
//                BigDecimal bigDecimal1 = orderCoinDealDao.sumTodayEntrustCntBuyAmount(memberId, symbol);
//                if (bigDecimal1 == null) {
//                    bigDecimal1 = BigDecimal.ZERO;
//                }
//                bigDecimal1 = bigDecimal1.add(amount);
//                if (bigDecimal1 != null && bigDecimal1.compareTo(new BigDecimal("800")) > 0) {
//                    return Result.fail("买入额度受限");
//                }
                if (StringUtils.isNotBlank(string) && StringUtils.isNotBlank(memberEntity.getEmail()) && string.contains(memberEntity.getEmail())) {
                    return Result.fail("");
                }
                // 不能超过800个
            } else {
               return Result.fail("卖出受限");
                // 判断redis开关
                //String string = redisUtils.getString("SELL_LIMIT_KEY");
                String string = redisUtils.getString("SELL_LIMIT_KEY_PHONE");
                if (StringUtils.isNotBlank(string) && StringUtils.isNotBlank(phone) && string.contains(phone)) {
                    return Result.fail("");
                }
                if (StringUtils.isNotBlank(string) && StringUtils.isNotBlank(memberEntity.getEmail()) && string.contains(memberEntity.getEmail())) {
                    return Result.fail("");
                }
            }
        }
        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();
@@ -413,6 +424,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) {
@@ -433,6 +454,30 @@
            BigDecimal availableBalance = walletCoin.getAvailableBalance();
            if (amount.compareTo(availableBalance) > 0) {
                return Result.fail(MessageSourceUtils.getString("order_service_0010"));
            }
            // 控制这个用户每日的挂卖额度 TODO
            // 每天3% 第一次的为基数
            BigDecimal spread = memberEntity.getSpread();
            if(spread!=null && spread.compareTo(BigDecimal.ZERO)>0 && spread.compareTo(PERSENT)<0){
                // 获取当日的额度
                String yyyyMMdd = DateUtil.dateToString(new Date(), "yyyyMMdd");
                String persentKey = String.format(LIMIT_SELL_PERSENT_KEY,yyyyMMdd,memberId.toString());
                BigDecimal aviSell  =BigDecimal.ZERO;
                String string = redisUtils.getString(persentKey);
                if(StringUtils.isBlank(string)){
                    // 当日可以卖的数量
                     aviSell = spread.divide(PERSENT,4, RoundingMode.HALF_UP).multiply(availableBalance);
                }else{
                    aviSell = new BigDecimal(string);
                }
                if(aviSell.compareTo(amount)<0){
                    return Result.fail("卖出超过上限"+spread.setScale(0,RoundingMode.HALF_UP)+"%");
                }
                aviSell = aviSell.subtract(amount);
                // 设置
                redisUtils.set(persentKey,aviSell.toPlainString());
                //redisUtils.getString()
            }
        }
@@ -485,10 +530,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);
@@ -639,6 +684,12 @@
        OrderCoinsEntity coinsEntityCancel = trader.cancelOrder(orderCoinsEntity);
        if (coinsEntityCancel == null) {
            // 此时说明撮合系统已经没这个单了 不需要继续处理
            // 直接更新状态先
            OrderCoinsEntity update = new OrderCoinsEntity();
            update.setId(Long.valueOf(orderId));
            update.setOrderStatus(OrderCoinsEntity.ORDERSTATUS_CANCEL);
            //orderCoinsEntity.setOrderStatus(OrderCoinsEntity.ORDERSTATUS_CANCEL);
            orderCoinsDao.updateById(update);
            return null;
        }
@@ -691,7 +742,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);
@@ -707,15 +758,25 @@
                    return Result.ok(MessageSourceUtils.getString("order_service_0013"));
                }
            } else {
                //如果是限价卖出,撤单将对应的钱包冻结金额返回
                MemberWalletCoinEntity walletCoin = memberWalletCoinDao.selectWalletCoinBymIdAndCode(memberId, symbol);
                if (ObjectUtil.isNotEmpty(walletCoin)) {
                    // 卖出按卖出的数量计算手续费
                    BigDecimal returnBalance = orderCoinsEntity.getEntrustCnt().subtract(coinsEntityCancel.getDealCnt());
                    // 取消订单 则退回额度
                    String yyyyMMdd = DateUtil.dateToString(new Date(), "yyyyMMdd");
                    String persentKey = String.format(LIMIT_SELL_PERSENT_KEY,yyyyMMdd,memberId.toString());
                    String aviSell = redisUtils.getString(persentKey);
                    // TODO
                    if(StringUtils.isNotBlank(aviSell)){
                        BigDecimal needSub = new BigDecimal(aviSell).add(returnBalance);
                        redisUtils.set(persentKey,needSub.toPlainString());
                    }
                    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);
@@ -1005,12 +1066,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();
@@ -1049,12 +1110,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();
@@ -1077,16 +1138,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());
                            }
                        }
                    }