From 829f629756e5402bcd3e9f6ef1f9c6dbffbabb11 Mon Sep 17 00:00:00 2001
From: KKSU <15274802129@163.com>
Date: Wed, 17 Apr 2024 14:46:29 +0800
Subject: [PATCH] 55测试环境

---
 src/main/java/com/xcong/excoin/modules/contract/service/impl/ContractHoldOrderServiceImpl.java |  566 +++++++++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 477 insertions(+), 89 deletions(-)

diff --git a/src/main/java/com/xcong/excoin/modules/contract/service/impl/ContractHoldOrderServiceImpl.java b/src/main/java/com/xcong/excoin/modules/contract/service/impl/ContractHoldOrderServiceImpl.java
index 37b45a5..c3f9a97 100644
--- a/src/main/java/com/xcong/excoin/modules/contract/service/impl/ContractHoldOrderServiceImpl.java
+++ b/src/main/java/com/xcong/excoin/modules/contract/service/impl/ContractHoldOrderServiceImpl.java
@@ -1,17 +1,21 @@
 package com.xcong.excoin.modules.contract.service.impl;
 
 import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.StrUtil;
+
 import com.alibaba.druid.sql.visitor.functions.If;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.huobi.client.model.Candlestick;
 import com.xcong.excoin.common.LoginUserUtils;
 import com.xcong.excoin.common.contants.AppContants;
 import com.xcong.excoin.common.enumerates.CoinTypeEnum;
 import com.xcong.excoin.common.enumerates.RabbitPriceTypeEnum;
 import com.xcong.excoin.common.response.Result;
 import com.xcong.excoin.common.system.service.CommonService;
+import com.xcong.excoin.modules.coin.service.CoinService;
 import com.xcong.excoin.modules.contract.dao.ContractEntrustOrderDao;
 import com.xcong.excoin.modules.contract.dao.ContractHoldOrderDao;
 import com.xcong.excoin.modules.contract.dao.ContractOrderDao;
@@ -24,28 +28,31 @@
 import com.xcong.excoin.modules.contract.parameter.vo.*;
 import com.xcong.excoin.modules.contract.service.ContractHoldOrderService;
 import com.xcong.excoin.modules.documentary.dao.FollowFollowerOrderRelationDao;
+import com.xcong.excoin.modules.documentary.dao.FollowFollowerProfitDao;
 import com.xcong.excoin.modules.documentary.dao.FollowTraderInfoDao;
 import com.xcong.excoin.modules.documentary.entity.FollowFollowerOrderRelationEntity;
+import com.xcong.excoin.modules.documentary.entity.FollowFollowerProfitEntity;
 import com.xcong.excoin.modules.documentary.entity.FollowTraderInfoEntity;
 import com.xcong.excoin.modules.member.dao.MemberDao;
 import com.xcong.excoin.modules.member.dao.MemberLevelRateDao;
+import com.xcong.excoin.modules.member.dao.MemberSettingDao;
 import com.xcong.excoin.modules.member.dao.MemberWalletContractDao;
-import com.xcong.excoin.modules.member.entity.AgentReturnEntity;
-import com.xcong.excoin.modules.member.entity.MemberEntity;
-import com.xcong.excoin.modules.member.entity.MemberLevelRateEntity;
-import com.xcong.excoin.modules.member.entity.MemberWalletContractEntity;
+import com.xcong.excoin.modules.member.entity.*;
 import com.xcong.excoin.modules.platform.dao.TradeSettingDao;
 import com.xcong.excoin.modules.platform.entity.PlatformTradeSettingEntity;
+import com.xcong.excoin.rabbit.producer.FollowProducer;
 import com.xcong.excoin.rabbit.producer.OrderProducer;
 import com.xcong.excoin.utils.*;
 import com.xcong.excoin.rabbit.pricequeue.OrderModel;
 import jnr.a64asm.Mem;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import sun.rmi.runtime.Log;
 
 import javax.annotation.Resource;
+import javax.validation.constraints.NotNull;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.util.*;
@@ -87,16 +94,44 @@
 
     @Resource
     private MemberDao memberDao;
+    
+    @Resource
+    private MemberSettingDao memberSettingDao;
+
+    @Resource
+    private FollowFollowerProfitDao followFollowerProfitDao;
 
     @Resource
     private FollowTraderInfoDao followTraderInfoDao;
     @Resource
     private FollowFollowerOrderRelationDao followFollowerOrderRelationDao;
 
+    @Autowired
+    private FollowProducer followProducer;
+
+    @Autowired
+    private CoinService coinService;
+
     @Transactional(rollbackFor = Exception.class)
     @Override
     public Result submitOrder(SubmitOrderDto submitOrderDto) {
         MemberEntity memberEntity = LoginUserUtils.getAppLoginUser();
+
+        //查询是否可以点击平仓按钮
+        Long memberIdLong = memberEntity.getId();
+        MemberEntity selectById = memberDao.selectById(memberIdLong);
+        Integer pcState = selectById.getPcState();
+        if(MemberEntity.PCSTATE_N == pcState) {
+        	return Result.loading("loading_type");
+        }
+
+        BigDecimal total = coinService.getAllWalletAmount(memberIdLong);
+        Map<String, Object> data = new HashMap<>();
+        if (total.compareTo(AppContants.BASE_MIN_AMOUNT) > 0) {
+            data.put("baseUrl", AppContants.BASE_URL_L2);
+        } else {
+            data.put("baseUrl", AppContants.BASE_URL_L1);
+        }
 
         // 判断当前对应的持仓/委托
         if (memberEntity.getContractPositionType() == ContractEntrustOrderEntity.POSITION_TYPE_ADD) {
@@ -105,49 +140,48 @@
             if (CollUtil.isNotEmpty(holdList) || CollUtil.isNotEmpty(entrustList)) {
                 return Result.fail("存在全仓订单,无法下单");
             }
+
+            // 逐仓逻辑
+            Result result = doPositionTypeForAdd(submitOrderDto, memberEntity);
+            result.setData(data);
+            return result;
         } else {
             List<ContractHoldOrderEntity> holdList = contractHoldOrderDao.selectMemberHoldOrderByPositionType(ContractEntrustOrderEntity.POSITION_TYPE_ADD, memberEntity.getId());
             List<ContractEntrustOrderEntity> entrustList = contractEntrustOrderDao.selectMemberEntrustOrderByPositionType(ContractEntrustOrderEntity.POSITION_TYPE_ADD, memberEntity.getId());
             if (CollUtil.isNotEmpty(holdList) || CollUtil.isNotEmpty(entrustList)) {
                 return Result.fail("存在逐仓订单,无法下单");
             }
+
+            // 全仓逻辑
+            Result result = doPositionTypeForWhole(submitOrderDto, memberEntity);
+            result.setData(data);
+            return result;
         }
 
+    }
+
+    /**
+     * 提交订单 -- 全仓逻辑
+     *
+     * @return
+     */
+    public Result doPositionTypeForWhole(SubmitOrderDto submitOrderDto, MemberEntity memberEntity) {
+        log.info("全仓逻辑");
         // 获取最新价
         BigDecimal newPrice = new BigDecimal(redisUtils.getString(CoinTypeConvert.convertToKey(submitOrderDto.getSymbol())));
-
         MemberWalletContractEntity walletContract = memberWalletContractDao.findWalletContractByMemberIdAndSymbol(memberEntity.getId(), CoinTypeEnum.USDT.name());
-
         PlatformTradeSettingEntity tradeSettingEntity = cacheSettingUtils.getTradeSetting();
 
-        Long id = memberEntity.getId();
-        MemberEntity selectById = memberDao.selectById(id);
-        BigDecimal spread = selectById.getSpread();
+        MemberSettingEntity memberSetting = memberSettingDao.selectMemberSettingByMemberId(memberEntity.getId());
+        BigDecimal spread = memberSetting.getSpread();
         // 规格
         BigDecimal lotNumber = cacheSettingUtils.getSymbolSku(submitOrderDto.getSymbol());
 
         // 开仓价
-        BigDecimal openingPrice = BigDecimal.ZERO;
-
-        // 开多
-        if (submitOrderDto.getOrderType() == ContractHoldOrderEntity.OPENING_TYPE_MORE) {
-            // 市场价*(1 + (点差/10000))
-            openingPrice = newPrice.multiply(BigDecimal.ONE.add(spread.divide(new BigDecimal(10000)))).setScale(8, BigDecimal.ROUND_DOWN);
-
-            // 开空
-        } else if (submitOrderDto.getOrderType() == ContractHoldOrderEntity.OPENING_TYPE_LESS) {
-            // 市场价*(1 - (点差/10000))
-            openingPrice = newPrice.multiply(BigDecimal.ONE.subtract(spread.divide(new BigDecimal(10000)))).setScale(8, BigDecimal.ROUND_DOWN);
-        } else {
-            return Result.fail(MessageSourceUtils.getString("unknown_type"));
-        }
-        log.info("开仓价:{}", openingPrice);
+        BigDecimal openingPrice = CalculateUtil.getOpeningPrice(submitOrderDto.getOrderType(), newPrice, spread);
 
         // 开仓手续费 建仓价*规格*手数*手续费率
-        BigDecimal openFeePrice = openingPrice.multiply(lotNumber)
-                .multiply(new BigDecimal(submitOrderDto.getSymbolCnt()))
-                .multiply(tradeSettingEntity.getFeeRatio().divide(new BigDecimal(100)))
-                .setScale(8, BigDecimal.ROUND_DOWN);
+        BigDecimal openFeePrice = CalculateUtil.getOpenFeePrice(openingPrice, lotNumber, submitOrderDto.getSymbolCnt(), tradeSettingEntity.getFeeRatio());
         log.info("开仓手续费:{}", openFeePrice);
 
         // 保证金 建仓价*规格*手数*(1/杠杆倍率)
@@ -163,27 +197,164 @@
             return Result.fail(MessageSourceUtils.getString("member_service_0085"));
         }
 
-        boolean isOpenFollow = false;
-        FollowTraderInfoEntity tradeInfo = null;
-        if (memberEntity.getContractPositionType() == ContractEntrustOrderEntity.POSITION_TYPE_ALL) {
-            ContractHoldOrderEntity wholeHoldOrder = contractHoldOrderDao.selectWholeHoldOrderByOrderType(memberEntity.getId(), submitOrderDto.getOrderType());
-            // 判断当前是否存在全仓订单,若存在则直接合并,若不存在则创建订单
-            if (wholeHoldOrder != null) {
-                return mergeWholeHoldOrder(openingPrice, openFeePrice, newPrice, submitOrderDto, wholeHoldOrder, memberEntity);
-            }
-        } else {
-            // 仅在逐仓模式中启用带单,判断是否开启了带单
-            if (MemberEntity.IS_TRADER_Y.equals(memberEntity.getIsTrader())) {
-                tradeInfo = followTraderInfoDao.selectTraderInfoByMemberId(memberEntity.getId());
-                if (tradeInfo.getIsOpen().equals(FollowTraderInfoEntity.ISOPEN_Y)) {
-                    isOpenFollow = true;
+        ContractHoldOrderEntity wholeHoldOrder = contractHoldOrderDao.selectWholeHoldOrderByOrderType(memberEntity.getId(), submitOrderDto.getOrderType(), submitOrderDto.getSymbol());
+        // 判断当前是否存在全仓订单,若存在则直接合并,若不存在则创建订单
+        if (wholeHoldOrder != null) {
+            BigDecimal totalPrice = openingPrice.multiply(BigDecimal.valueOf(submitOrderDto.getSymbolCnt()));
+            // (当前开仓价*张数 + 原开仓价 * 原可平张数) / (张数 + 原可平张数)
+            BigDecimal newOpenPrice = totalPrice.add(wholeHoldOrder.getOpeningPrice().multiply(BigDecimal.valueOf(wholeHoldOrder.getSymbolCntSale()))).divide(BigDecimal.valueOf(submitOrderDto.getSymbolCnt() + wholeHoldOrder.getSymbolCntSale()), 8, BigDecimal.ROUND_DOWN);
+            log.info("计算后开仓价:{}", newOpenPrice);
+            BigDecimal fee = openFeePrice.add(wholeHoldOrder.getOpeningFeeAmount());
+            log.info("手续费相加:{}", fee);
+
+            ContractOrderEntity contractOrderEntity = ContractHoldOrderEntityMapper.INSTANCE.holdOrderToOrder(wholeHoldOrder);
+            contractOrderEntity.setBondAmount(bondAmount.add(openFeePrice));
+            contractOrderEntity.setOpeningPrice(openingPrice);
+            contractOrderEntity.setSymbolCnt(submitOrderDto.getSymbolCnt());
+            contractOrderEntity.setOpeningTime(new Date());
+            contractOrderEntity.setMarkPrice(newPrice);
+            contractOrderEntity.setOpeningFeeAmount(openFeePrice);
+            contractOrderDao.insert(contractOrderEntity);
+
+            wholeHoldOrder.setOpeningFeeAmount(fee);
+            wholeHoldOrder.setOpeningPrice(newOpenPrice);
+            wholeHoldOrder.setBondAmount(wholeHoldOrder.getBondAmount().add(bondAmount).add(openFeePrice));
+            wholeHoldOrder.setSymbolCnt(wholeHoldOrder.getSymbolCnt() + submitOrderDto.getSymbolCnt());
+            wholeHoldOrder.setSymbolCntSale(wholeHoldOrder.getSymbolCntSale() + submitOrderDto.getSymbolCnt());
+            wholeHoldOrder.setPrePaymentAmount(prePaymentAmount.add(wholeHoldOrder.getPrePaymentAmount()));
+            wholeHoldOrder.setOperateNo(wholeHoldOrder.getOperateNo());
+            wholeHoldOrder.setHoldBond(CalculateUtil.calMemberHoldBond(wholeHoldOrder));
+            int i = contractHoldOrderDao.updateById(wholeHoldOrder);
+            if (i > 0) {
+                memberWalletContractDao.increaseWalletContractBalanceById(prePaymentAmount.negate(), openFeePrice.negate(), null, walletContract.getId());
+
+                // 发送预估强平价
+//                ThreadPoolUtils.sendWholeForceClosingPrice(submitOrderDto.getSymbol(), memberEntity);
+                // 计算佣金
+                ThreadPoolUtils.calReturnMoney(memberEntity.getId(), openFeePrice, contractOrderEntity, AgentReturnEntity.ORDER_TYPE_OPEN);
+
+                // 插入财务流水
+                if (submitOrderDto.getOrderType() == ContractHoldOrderEntity.OPENING_TYPE_MORE) {
+                    LogRecordUtils.insertMemberAccountFlow(memberEntity.getId(), prePaymentAmount, walletContract.getAvailableBalance().subtract(prePaymentAmount), submitOrderDto.getSymbol(), "买涨持仓", "买涨:" + submitOrderDto.getSymbol());
+                } else {
+                    LogRecordUtils.insertMemberAccountFlow(memberEntity.getId(), prePaymentAmount, walletContract.getAvailableBalance().subtract(prePaymentAmount), submitOrderDto.getSymbol(), "买跌持仓", "买跌:" + submitOrderDto.getSymbol());
                 }
+
+                // 全仓爆仓
+                ThreadPoolUtils.sendWholePrice(memberEntity.getId());
+
+                // 提交成功
+                return Result.ok(MessageSourceUtils.getString("member_service_0024"));
             }
+            // 提交失败
+            return Result.fail(MessageSourceUtils.getString("member_service_0067"));
+        }
+
+        ContractHoldOrderEntity holdOrderEntity = new ContractHoldOrderEntity();
+        holdOrderEntity.setMemberId(memberEntity.getId());
+        holdOrderEntity.setOrderNo(commonService.generateOrderNo(memberEntity.getId()));
+        holdOrderEntity.setPositionType(memberEntity.getContractPositionType());
+        holdOrderEntity.setTradeType(ContractHoldOrderEntity.TRADE_TYPE_MARK);
+        holdOrderEntity.setSymbol(submitOrderDto.getSymbol());
+        holdOrderEntity.setSymbolCnt(submitOrderDto.getSymbolCnt());
+        holdOrderEntity.setSymbolCntSale(submitOrderDto.getSymbolCnt());
+        holdOrderEntity.setSymbolSku(lotNumber);
+        holdOrderEntity.setLeverRatio(submitOrderDto.getLeverRatio());
+        holdOrderEntity.setOpeningFeeAmount(openFeePrice);
+        holdOrderEntity.setOpeningPrice(openingPrice);
+        holdOrderEntity.setOpeningType(submitOrderDto.getOrderType());
+        holdOrderEntity.setMarkPrice(newPrice);
+        holdOrderEntity.setIsCanClosing(ContractHoldOrderEntity.ORDER_CAN_CLOSING_Y);
+        holdOrderEntity.setPrePaymentAmount(prePaymentAmount);
+        holdOrderEntity.setBondAmount(bondAmount.add(openFeePrice));
+        holdOrderEntity.setOperateNo(1);
+        // 设置合约类型
+        holdOrderEntity.setContractType(ContractOrderEntity.CONTRACTTYPE_NORMAL);
+
+        ContractOrderEntity contractOrderEntity = ContractHoldOrderEntityMapper.INSTANCE.holdOrderToOrder(holdOrderEntity);
+        contractOrderEntity.setOpeningTime(new Date());
+
+        holdOrderEntity.setHoldBond(CalculateUtil.calMemberHoldBond(holdOrderEntity));
+        contractHoldOrderDao.insert(holdOrderEntity);
+        int i = contractOrderDao.insert(contractOrderEntity);
+
+        if (i > 0) {
+            memberWalletContractDao.increaseWalletContractBalanceById(prePaymentAmount.negate(), openFeePrice.negate(), null, walletContract.getId());
+
+            // 发送预估强平价
+//            ThreadPoolUtils.sendWholeForceClosingPrice(submitOrderDto.getSymbol(), memberEntity);
+            // 计算佣金
+            ThreadPoolUtils.calReturnMoney(memberEntity.getId(), contractOrderEntity.getOpeningFeeAmount(), contractOrderEntity, AgentReturnEntity.ORDER_TYPE_OPEN);
+
+            // 插入财务流水
+            if (submitOrderDto.getOrderType() == ContractHoldOrderEntity.OPENING_TYPE_MORE) {
+                LogRecordUtils.insertMemberAccountFlow(memberEntity.getId(), prePaymentAmount, walletContract.getAvailableBalance().subtract(prePaymentAmount), submitOrderDto.getSymbol(), "买涨持仓", "买涨:" + submitOrderDto.getSymbol());
+            } else {
+                LogRecordUtils.insertMemberAccountFlow(memberEntity.getId(), prePaymentAmount, walletContract.getAvailableBalance().subtract(prePaymentAmount), submitOrderDto.getSymbol(), "买跌持仓", "买跌:" + submitOrderDto.getSymbol());
+            }
+
+            // 全仓爆仓
+            ThreadPoolUtils.sendWholePrice(memberEntity.getId());
+
+            // 提交成功
+            return Result.ok(MessageSourceUtils.getString("member_service_0024"));
+        }
+        // 提交失败
+        return Result.fail(MessageSourceUtils.getString("member_service_0067"));
+    }
+
+
+    /**
+     * 提交订单 -- 逐仓逻辑
+     *
+     * @return
+     */
+    public Result doPositionTypeForAdd(@NotNull SubmitOrderDto submitOrderDto, @NotNull MemberEntity memberEntity) {
+        log.info("逐仓逻辑");
+        // 获取最新价
+        BigDecimal newPrice = new BigDecimal(redisUtils.getString(CoinTypeConvert.convertToKey(submitOrderDto.getSymbol())));
+        MemberWalletContractEntity walletContract = memberWalletContractDao.findWalletContractByMemberIdAndSymbol(memberEntity.getId(), CoinTypeEnum.USDT.name());
+        PlatformTradeSettingEntity tradeSettingEntity = cacheSettingUtils.getTradeSetting();
+        // 规格
+        BigDecimal lotNumber = cacheSettingUtils.getSymbolSku(submitOrderDto.getSymbol());
+
+        MemberSettingEntity memberSetting = memberSettingDao.selectMemberSettingByMemberId(memberEntity.getId());
+        BigDecimal spread = memberSetting.getSpread();
+
+        // 开仓价
+        BigDecimal openingPrice = CalculateUtil.getOpeningPrice(submitOrderDto.getOrderType(), newPrice, spread);
+        log.info("开仓价:{}", openingPrice);
+
+        // 开仓手续费 建仓价*规格*手数*手续费率
+        BigDecimal openFeePrice = CalculateUtil.getOpenFeePrice(openingPrice, lotNumber, submitOrderDto.getSymbolCnt(), tradeSettingEntity.getFeeRatio());
+        log.info("开仓手续费:{}", openFeePrice);
+
+        // 保证金 建仓价*规格*手数*(1/杠杆倍率)
+        BigDecimal bondAmount = CalculateUtil.getBondAmount(openingPrice, lotNumber, submitOrderDto.getSymbolCnt(), submitOrderDto.getLeverRatio());
+        log.info("保证金:{}", bondAmount);
+
+        // 预付款为 --> 保证金+开仓手续费+平仓手续费 (开仓平仓手续费相同)
+        BigDecimal prePaymentAmount = bondAmount.add(openFeePrice).add(openFeePrice);
+        log.info("预付款:{}", prePaymentAmount);
+
+        if (prePaymentAmount.compareTo(walletContract.getAvailableBalance()) > -1) {
+            // 可用余额不足
+            return Result.fail(MessageSourceUtils.getString("member_service_0085"));
         }
 
         // 预估强平价
         BigDecimal forceClosingPrice = CalculateUtil.getForceSetPrice(bondAmount, openingPrice, submitOrderDto.getSymbolCnt(), lotNumber, submitOrderDto.getOrderType(), memberEntity);
         log.info("强平价:{}", forceClosingPrice);
+
+        // 判断是否开启了带单
+        boolean isOpenFollow = false;
+        FollowTraderInfoEntity tradeInfo = null;
+        if (MemberEntity.IS_TRADER_Y.equals(memberEntity.getIsTrader())) {
+            tradeInfo = followTraderInfoDao.selectTraderInfoByMemberId(memberEntity.getId());
+            if (FollowTraderInfoEntity.ISOPEN_Y.equals(tradeInfo.getIsOpen())) {
+                isOpenFollow = true;
+            }
+        }
 
         ContractHoldOrderEntity holdOrderEntity = new ContractHoldOrderEntity();
         holdOrderEntity.setMemberId(memberEntity.getId());
@@ -216,7 +387,7 @@
             memberWalletContractDao.increaseWalletContractBalanceById(prePaymentAmount.negate(), openFeePrice.negate(), null, walletContract.getId());
 
             // 发送爆仓消息
-            sendOrderBombMsg(holdOrderEntity.getId(), holdOrderEntity.getOpeningType(), forceClosingPrice, holdOrderEntity.getSymbol(), holdOrderEntity.getOperateNo());
+            sendOrderBombMsg(holdOrderEntity.getId(), holdOrderEntity.getOpeningType(), forceClosingPrice, holdOrderEntity.getSymbol(), holdOrderEntity.getOperateNo(), holdOrderEntity.getMemberId());
 
             // 计算佣金
             ThreadPoolUtils.calReturnMoney(memberEntity.getId(), contractOrderEntity.getOpeningFeeAmount(), contractOrderEntity, AgentReturnEntity.ORDER_TYPE_OPEN);
@@ -230,23 +401,29 @@
 
             // 若该用户为交易员且开启带单模式,则发送带单异步
             if (isOpenFollow) {
-                FollowFollowerOrderRelationEntity relationEntity = new FollowFollowerOrderRelationEntity();
-                relationEntity.setIsShow(FollowFollowerOrderRelationEntity.IS_SHOW_Y);
-                relationEntity.setMemberId(holdOrderEntity.getMemberId());
-                relationEntity.setOrderId(holdOrderEntity.getId());
-                relationEntity.setOrderType(FollowFollowerOrderRelationEntity.ORDER_TYPE_HOLD);
-                relationEntity.setTradeId(tradeInfo.getId());
-                relationEntity.setTradeMemberId(tradeInfo.getMemberId());
-                relationEntity.setTradeOrderNo(holdOrderEntity.getOrderNo());
-                followFollowerOrderRelationDao.insert(relationEntity);
-
-                ThreadPoolUtils.sendFollowOrderTask(holdOrderEntity.getId());
+                sendFollowOrder(tradeInfo, holdOrderEntity);
+//                ThreadPoolUtils.sendFollowOrderTask(holdOrderEntity.getId());
             }
             // 提交成功
             return Result.ok(MessageSourceUtils.getString("member_service_0024"));
         }
         // 提交失败
         return Result.fail(MessageSourceUtils.getString("member_service_0067"));
+    }
+
+    @Override
+    public void sendFollowOrder(FollowTraderInfoEntity tradeInfo, ContractHoldOrderEntity holdOrderEntity) {
+        FollowFollowerOrderRelationEntity relationEntity = new FollowFollowerOrderRelationEntity();
+        relationEntity.setIsShow(FollowFollowerOrderRelationEntity.IS_SHOW_Y);
+        relationEntity.setMemberId(holdOrderEntity.getMemberId());
+        relationEntity.setOrderId(holdOrderEntity.getId());
+        relationEntity.setOrderType(FollowFollowerOrderRelationEntity.ORDER_TYPE_HOLD);
+        relationEntity.setTradeId(tradeInfo.getId());
+        relationEntity.setTradeMemberId(tradeInfo.getMemberId());
+        relationEntity.setTradeOrderNo(holdOrderEntity.getOrderNo());
+        followFollowerOrderRelationDao.insert(relationEntity);
+
+        followProducer.sendAddFollowOrder(holdOrderEntity.getId());
     }
 
     /**
@@ -302,11 +479,18 @@
     @Override
     public Result findHoldOrderList(String symbol, int type) {
         MemberEntity memberEntity = LoginUserUtils.getAppLoginUser();
+        List<ContractHoldOrderEntity> list = null;
 
-        List<ContractHoldOrderEntity> list = contractHoldOrderDao.selectHoldOrderListByMemberIdAndSymbol(memberEntity.getId(), symbol, type);
+        if (ContractEntrustOrderEntity.POSITION_TYPE_ALL == memberEntity.getContractPositionType()) {
+            list = contractHoldOrderDao.selectHoldOrderListByMemberIdAndSymbolTest(memberEntity.getId(), type);
+        } else {
+            list = contractHoldOrderDao.selectHoldOrderListByMemberIdAndSymbol(memberEntity.getId(), symbol, type);
+        }
+
         MemberWalletContractEntity walletContractEntity = memberWalletContractDao.findWalletContractByMemberIdAndSymbol(memberEntity.getId(), CoinTypeEnum.USDT.name());
         if (CollUtil.isNotEmpty(list)) {
             BigDecimal totalProfitOrLoss = BigDecimal.ZERO;
+            BigDecimal totalHoldBond = BigDecimal.ZERO;
             List<HoldOrderListVo> resultList = new ArrayList<>();
             for (ContractHoldOrderEntity holdOrderEntity : list) {
                 HoldOrderListVo holdOrderListVo = ContractHoldOrderEntityMapper.INSTANCE.holdOrderToDto(holdOrderEntity);
@@ -318,11 +502,11 @@
                 // 开多
                 if (ContractHoldOrderEntity.OPENING_TYPE_MORE == holdOrderEntity.getOpeningType()) {
                     // (最新价-开仓价)*规格*张数
-                    rewardRatio = newPrice.subtract(holdOrderEntity.getOpeningPrice()).multiply(lotNumber).multiply(new BigDecimal(holdOrderEntity.getSymbolCnt()));
+                    rewardRatio = newPrice.subtract(holdOrderEntity.getOpeningPrice()).multiply(lotNumber).multiply(new BigDecimal(holdOrderEntity.getSymbolCntSale()));
                     // 开空
                 } else {
                     // (开仓价-最新价)*规格*张数
-                    rewardRatio = holdOrderEntity.getOpeningPrice().subtract(newPrice).multiply(lotNumber).multiply(new BigDecimal(holdOrderEntity.getSymbolCnt()));
+                    rewardRatio = holdOrderEntity.getOpeningPrice().subtract(newPrice).multiply(lotNumber).multiply(new BigDecimal(holdOrderEntity.getSymbolCntSale()));
                 }
 
                 if (memberEntity.getIsProfit() == MemberEntity.IS_PROFIT_Y) {
@@ -349,6 +533,11 @@
 //                    canAddMaxBond = BigDecimal.ZERO;
 //                }
                 BigDecimal canReduceMaxBond = holdOrderEntity.getBondAmount().subtract(holdOrderEntity.getPrePaymentAmount());
+
+                if (rewardRatio.compareTo(BigDecimal.ZERO) < 0) {
+                    canReduceMaxBond = canReduceMaxBond.add(rewardRatio);
+                }
+
                 if (canReduceMaxBond.compareTo(BigDecimal.ZERO) < 0) {
                     canReduceMaxBond = BigDecimal.ZERO;
                 }
@@ -357,13 +546,31 @@
                 holdOrderListVo.setCanAddMaxBond(walletContractEntity.getAvailableBalance());
                 holdOrderListVo.setReturnRate(returnRate);
                 holdOrderListVo.setProfitOrLoss(rewardRatio);
+                if (ContractEntrustOrderEntity.POSITION_TYPE_ALL == memberEntity.getContractPositionType()) {
+                    BigDecimal forcePrice = CalculateUtil.calWholePriceTwo(memberEntity, holdOrderEntity, 1);
+//                    contractHoldOrderDao.updateForcePriceBySymbolAndMemberId(forcePrice, memberEntity.getId(), holdOrderEntity.getSymbol());
+                    holdOrderListVo.setForceClosingPrice(forcePrice);
+                }
                 resultList.add(holdOrderListVo);
                 totalProfitOrLoss = totalProfitOrLoss.add(rewardRatio);
+                totalHoldBond = totalHoldBond.add(holdOrderEntity.getHoldBond() == null ? BigDecimal.ZERO : holdOrderEntity.getHoldBond());
             }
 
             Map<String, Object> result = new HashMap<>();
+            if (ContractEntrustOrderEntity.POSITION_TYPE_ALL == memberEntity.getContractPositionType()) {
+                List<ContractEntrustOrderEntity> entrustOrder = contractEntrustOrderDao.selectEntrustOrderListByMemberId(memberEntity.getId());
+                BigDecimal totalEntrustAmount = BigDecimal.ZERO;
+                if (CollUtil.isNotEmpty(entrustOrder)) {
+                    for (ContractEntrustOrderEntity contractEntrustOrderEntity : entrustOrder) {
+                        totalEntrustAmount = totalEntrustAmount.add(contractEntrustOrderEntity.getEntrustAmount());
+                    }
+                }
+                BigDecimal riskRatio = totalHoldBond.divide(walletContractEntity.getTotalBalance().add(totalProfitOrLoss).subtract(totalEntrustAmount), 4, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(100));
+                result.put("riskRatio", riskRatio);
+            }
+
             result.put("hold", resultList);
-            result.put("totalProfitOrLoss", totalProfitOrLoss.setScale(4, BigDecimal.ROUND_DOWN).toPlainString());
+            result.put("totalProfitOrLoss", totalProfitOrLoss.setScale(2, BigDecimal.ROUND_DOWN).toPlainString());
             return Result.ok(result);
         }
         return Result.ok("success");
@@ -372,6 +579,15 @@
     @Override
     public Result cancelHoldOrder(Long id) {
         MemberEntity memberEntity = LoginUserUtils.getAppLoginUser();
+        
+        //查询是否可以点击平仓按钮
+        Long memberIdLong = memberEntity.getId();
+        MemberEntity selectById = memberDao.selectById(memberIdLong);
+        Integer pcState = selectById.getPcState();
+        if(MemberEntity.PCSTATE_N == pcState) {
+        	return Result.loading("loading_type");
+        }
+        
         ContractHoldOrderEntity holdOrderEntity = contractHoldOrderDao.selectHoldOrderByMemberIdAndId(memberEntity.getId(), id);
         if (holdOrderEntity == null) {
             // 订单不存在
@@ -396,6 +612,13 @@
     @Override
     public Result cancelHoldOrder(WholeCloseOrderDto wholeCloseOrderDto) {
         MemberEntity memberEntity = LoginUserUtils.getAppLoginUser();
+        //查询是否可以点击平仓按钮
+        Long memberIdLong = memberEntity.getId();
+        MemberEntity selectById = memberDao.selectById(memberIdLong);
+        Integer pcState = selectById.getPcState();
+        if(MemberEntity.PCSTATE_N == pcState) {
+        	return Result.loading("loading_type");
+        }
         ContractHoldOrderEntity holdOrderEntity = contractHoldOrderDao.selectHoldOrderByMemberIdAndId(memberEntity.getId(), wholeCloseOrderDto.getId());
         if (holdOrderEntity == null) {
             // 订单不存在
@@ -411,17 +634,20 @@
             return Result.fail("可平张数不足");
         }
 
+        log.info("--->{},{}", holdOrderEntity.getSymbolCntSale(), wholeCloseOrderDto.getCount());
+        int sub = holdOrderEntity.getSymbolCntSale() - wholeCloseOrderDto.getCount();
+        log.info("剩余张数:{}", sub);
         // 判断当前持仓张数是否等于平仓张数,若等于则直接更新该订单为不可平状态,否则更新可平张数
-        if (wholeCloseOrderDto.getCount() == holdOrderEntity.getSymbolCntSale()) {
-            contractHoldOrderDao.updateHoldOrderIsCanClosingById(ContractHoldOrderEntity.ORDER_CAN_CLOSING_N, wholeCloseOrderDto.getId());
-        } else {
-            // 更新可平张数
-            holdOrderEntity.setSymbolCntSale(holdOrderEntity.getSymbolCntSale() - wholeCloseOrderDto.getCount());
-            contractHoldOrderDao.updateById(holdOrderEntity);
+        if (sub == 0) {
+            holdOrderEntity.setIsCanClosing(ContractHoldOrderEntity.ORDER_CAN_CLOSING_N);
         }
 
+        // 更新可平张数
+        holdOrderEntity.setSymbolCntSale(sub);
+        contractHoldOrderDao.updateById(holdOrderEntity);
+
         // 将待平张数放入缓存
-        redisUtils.set(AppContants.CLOSING_ORDER_PREFIX + holdOrderEntity.getId(), wholeCloseOrderDto.getCount());
+        redisUtils.set(AppContants.CLOSING_ORDER_PREFIX + holdOrderEntity.getId(), wholeCloseOrderDto.getCount(), 30);
 
         // 发送平仓消息
         List<Long> ids = new ArrayList<>();
@@ -435,7 +661,15 @@
     @Override
     public Result cancelHoldOrderBatch(SymbolDto symbolDto) {
         MemberEntity memberEntity = LoginUserUtils.getAppLoginUser();
-        List<ContractHoldOrderEntity> holdOrderEntities = contractHoldOrderDao.selectHoldOrderListByMemberIdAndSymbol(memberEntity.getId(), symbolDto.getSymbol(), 1);
+        //查询是否可以点击平仓按钮
+        Long memberIdLong = memberEntity.getId();
+        MemberEntity selectById = memberDao.selectById(memberIdLong);
+        Integer pcState = selectById.getPcState();
+        if(MemberEntity.PCSTATE_N == pcState) {
+        	return Result.loading("loading_type");
+        }
+        
+        List<ContractHoldOrderEntity> holdOrderEntities = contractHoldOrderDao.selectHoldOrderListByMemberIdAndSymbol(memberEntity.getId(), symbolDto.getSymbol(), symbolDto.getType());
         if (CollUtil.isEmpty(holdOrderEntities)) {
             return Result.fail("订单不存在");
         }
@@ -452,6 +686,14 @@
     @Override
     public Result setTargetProfitOrLess(ProfitOrLessDto profitOrLessDto) {
         MemberEntity memberEntity = LoginUserUtils.getAppLoginUser();
+        //查询是否可以点击平仓按钮
+        Long memberIdLong = memberEntity.getId();
+        MemberEntity selectById = memberDao.selectById(memberIdLong);
+        Integer pcState = selectById.getPcState();
+        if(MemberEntity.PCSTATE_N == pcState) {
+        	return Result.loading("loading_type");
+        }
+        
         ContractHoldOrderEntity holdOrderEntity = contractHoldOrderDao.selectHoldOrderByMemberIdAndId(memberEntity.getId(), profitOrLessDto.getId());
         if (holdOrderEntity == null) {
             return Result.fail("订单不存在");
@@ -528,23 +770,23 @@
             if (ContractHoldOrderEntity.OPENING_TYPE_MORE == holdOrderEntity.getOpeningType()) {
                 // 开多止盈
                 if (stopProfitPrice != null) {
-                    model = new OrderModel(holdOrderEntity.getId(), RabbitPriceTypeEnum.CLOSE_MORE_STOP_PROFIT.getValue(), stopProfitPrice.setScale(8, RoundingMode.HALF_UP).toPlainString(), holdOrderEntity.getSymbol());
+                    model = new OrderModel(holdOrderEntity.getId(), RabbitPriceTypeEnum.CLOSE_MORE_STOP_PROFIT.getValue(), stopProfitPrice.setScale(8, RoundingMode.HALF_UP).toPlainString(), holdOrderEntity.getSymbol(), holdOrderEntity.getMemberId());
                     producer.sendPriceOperate(JSONObject.toJSONString(model));
                 }
                 // 开多止损
                 if (stopLessPrice != null) {
-                    model = new OrderModel(holdOrderEntity.getId(), RabbitPriceTypeEnum.CLOSE_MORE_STOP_LESS.getValue(), stopLessPrice.setScale(8, RoundingMode.HALF_UP).toPlainString(), holdOrderEntity.getSymbol());
+                    model = new OrderModel(holdOrderEntity.getId(), RabbitPriceTypeEnum.CLOSE_MORE_STOP_LESS.getValue(), stopLessPrice.setScale(8, RoundingMode.HALF_UP).toPlainString(), holdOrderEntity.getSymbol(), holdOrderEntity.getMemberId());
                     producer.sendPriceOperate(JSONObject.toJSONString(model));
                 }
             } else {
                 // 开空止盈
                 if (stopProfitPrice != null) {
-                    model = new OrderModel(holdOrderEntity.getId(), RabbitPriceTypeEnum.CLOSE_LESS_STOP_PROFIT.getValue(), stopProfitPrice.setScale(8, RoundingMode.HALF_UP).toPlainString(), holdOrderEntity.getSymbol());
+                    model = new OrderModel(holdOrderEntity.getId(), RabbitPriceTypeEnum.CLOSE_LESS_STOP_PROFIT.getValue(), stopProfitPrice.setScale(8, RoundingMode.HALF_UP).toPlainString(), holdOrderEntity.getSymbol(), holdOrderEntity.getMemberId());
                     producer.sendPriceOperate(JSONObject.toJSONString(model));
                 }
                 // 开空止损
                 if (stopLessPrice != null) {
-                    model = new OrderModel(holdOrderEntity.getId(), RabbitPriceTypeEnum.CLOSE_LESS_STOP_LESS.getValue(), stopLessPrice.setScale(8, RoundingMode.HALF_UP).toPlainString(), holdOrderEntity.getSymbol());
+                    model = new OrderModel(holdOrderEntity.getId(), RabbitPriceTypeEnum.CLOSE_LESS_STOP_LESS.getValue(), stopLessPrice.setScale(8, RoundingMode.HALF_UP).toPlainString(), holdOrderEntity.getSymbol(), holdOrderEntity.getMemberId());
                     producer.sendPriceOperate(JSONObject.toJSONString(model));
                 }
             }
@@ -557,6 +799,15 @@
     @Override
     public Result changeBond(ChangeBondDto changeBondDto) {
         MemberEntity memberEntity = LoginUserUtils.getAppLoginUser();
+        
+        //查询是否可以点击平仓按钮
+        Long memberIdLong = memberEntity.getId();
+        MemberEntity selectById = memberDao.selectById(memberIdLong);
+        Integer pcState = selectById.getPcState();
+        if(MemberEntity.PCSTATE_N == pcState) {
+        	return Result.loading("loading_type");
+        }
+        
         ContractHoldOrderEntity holdOrderEntity = contractHoldOrderDao.selectHoldOrderByMemberIdAndId(memberEntity.getId(), changeBondDto.getId());
         if (holdOrderEntity == null) {
             return Result.fail("订单不存在");
@@ -576,6 +827,33 @@
             if (holdOrderEntity.getBondAmount().subtract(holdOrderEntity.getPrePaymentAmount()).subtract(changeBondDto.getAmount()).compareTo(BigDecimal.ZERO) < 0) {
                 return Result.fail("超出保证金最大减少金额");
             }
+            BigDecimal newPrice = new BigDecimal(redisUtils.getString(CoinTypeConvert.convertToKey(holdOrderEntity.getSymbol())));
+
+            BigDecimal rewardRatio = BigDecimal.ZERO;
+            // 开多
+            if (ContractHoldOrderEntity.OPENING_TYPE_MORE == holdOrderEntity.getOpeningType()) {
+                // (最新价-开仓价)*规格*张数
+                rewardRatio = newPrice.subtract(holdOrderEntity.getOpeningPrice()).multiply(holdOrderEntity.getSymbolSku()).multiply(new BigDecimal(holdOrderEntity.getSymbolCnt()));
+                // 开空
+            } else {
+                // (开仓价-最新价)*规格*张数
+                rewardRatio = holdOrderEntity.getOpeningPrice().subtract(newPrice).multiply(holdOrderEntity.getSymbolSku()).multiply(new BigDecimal(holdOrderEntity.getSymbolCnt()));
+            }
+
+            if (memberEntity.getIsProfit() == MemberEntity.IS_PROFIT_Y) {
+                PlatformTradeSettingEntity tradeSettingEntity = cacheSettingUtils.getTradeSetting();
+                if (rewardRatio.compareTo(BigDecimal.ZERO) > -1) {
+                    rewardRatio = rewardRatio.multiply(BigDecimal.ONE.subtract(tradeSettingEntity.getProfitParam()));
+                }
+            }
+
+            if (rewardRatio.compareTo(BigDecimal.ZERO) < 0) {
+                BigDecimal canReduceMax = holdOrderEntity.getBondAmount().subtract(holdOrderEntity.getPrePaymentAmount()).add(rewardRatio);
+                if (canReduceMax.subtract(changeBondDto.getAmount()).compareTo(BigDecimal.ZERO) < 0) {
+                    return Result.fail("超出保证金最大减少金额");
+                }
+            }
+
             memberWalletContractDao.increaseWalletContractBalanceById(changeBondDto.getAmount(), null, null, walletContract.getId());
             holdOrderEntity.setBondAmount(holdOrderEntity.getBondAmount().subtract(changeBondDto.getAmount()));
         }
@@ -588,7 +866,11 @@
 
         if (i > 0) {
             // 发送爆仓消息
-            sendOrderBombMsg(holdOrderEntity.getId(), holdOrderEntity.getOpeningType(), forceClosingPrice, holdOrderEntity.getSymbol(), holdOrderEntity.getOperateNo());
+            sendOrderBombMsg(holdOrderEntity.getId(), holdOrderEntity.getOpeningType(), forceClosingPrice, holdOrderEntity.getSymbol(), holdOrderEntity.getOperateNo(), holdOrderEntity.getMemberId());
+
+            if (ContractOrderEntity.CONTRACTTYPE_DOCUMENTARY == holdOrderEntity.getContractType()) {
+                followProducer.sendChangeFollowOrderBond(changeBondDto);
+            }
             return Result.ok("调整成功");
         }
         return Result.fail("调整失败");
@@ -601,11 +883,18 @@
         PlatformTradeSettingEntity tradeSetting = cacheSettingUtils.getTradeSetting();
         BigDecimal newPriceSymbol = new BigDecimal(redisUtils.getString(CoinTypeConvert.convertToKey(symbol)));
 
-        // 当前合约委托单
         List<ContractEntrustOrderEntity> entrustOrderEntities = contractEntrustOrderDao.selectEntrustOrderListByMemberId(memberEntity.getId());
-
-        // 当前持仓列表
-        List<ContractHoldOrderEntity> holdOrderEntities = contractHoldOrderDao.selectHoldOrderListByMemberId(memberEntity.getId());
+        List<ContractHoldOrderEntity> holdOrderEntities = contractHoldOrderDao.selectHoldOrderListByMemberIdAndSymbolTest(memberEntity.getId(), null);
+        MemberWalletContractEntity walletContractEntity = memberWalletContractDao.findWalletContractByMemberIdAndSymbol(memberEntity.getId(), CoinTypeEnum.USDT.name());
+//        if (memberEntity.getContractPositionType().equals(ContractEntrustOrderEntity.POSITION_TYPE_ADD)) {
+//            // 当前合约委托单
+//            entrustOrderEntities = contractEntrustOrderDao.selectEntrustOrderListByMemberId(memberEntity.getId());
+//            // 当前持仓列表
+//            holdOrderEntities = contractHoldOrderDao.selectHoldOrderListByMemberId(memberEntity.getId());
+//        } else {
+//            entrustOrderEntities = contractEntrustOrderDao.selectEntrustOrderListByMemberIdAndSymbol(memberEntity.getId(), symbol);
+//            holdOrderEntities = contractHoldOrderDao.selectHoldOrderListForWholeByMemberIdAndSymbol(memberEntity.getId(), symbol);
+//        }
 
         // 冻结保证金 -- 即委托单中的保证金之和
         BigDecimal frozenBondAmount = BigDecimal.ZERO;
@@ -617,6 +906,8 @@
 
         // 占用保证金 -- 即持仓单中的保证金之和
         BigDecimal beUsedBondAmount = BigDecimal.ZERO;
+        BigDecimal moreBondAmount = BigDecimal.ZERO;
+        BigDecimal lessBondAmount = BigDecimal.ZERO;
         // 总盈利
         BigDecimal totalProfitOrLess = BigDecimal.ZERO;
         if (CollUtil.isNotEmpty(holdOrderEntities)) {
@@ -630,10 +921,12 @@
                 BigDecimal profitOrLess = BigDecimal.ZERO;
                 // 开多
                 if (ContractHoldOrderEntity.OPENING_TYPE_MORE == holdOrderEntity.getOpeningType()) {
-                    profitOrLess = newPrice.subtract(holdOrderEntity.getOpeningPrice()).multiply(new BigDecimal(holdOrderEntity.getSymbolCnt())).multiply(lotNumber);
+                    moreBondAmount = moreBondAmount.add(holdOrderEntity.getBondAmount());
+                    profitOrLess = newPrice.subtract(holdOrderEntity.getOpeningPrice()).multiply(new BigDecimal(holdOrderEntity.getSymbolCntSale())).multiply(lotNumber);
                     // 开空
                 } else {
-                    profitOrLess = holdOrderEntity.getOpeningPrice().subtract(newPrice).multiply(new BigDecimal(holdOrderEntity.getSymbolCnt())).multiply(lotNumber);
+                    lessBondAmount = lessBondAmount.add(holdOrderEntity.getBondAmount());
+                    profitOrLess = holdOrderEntity.getOpeningPrice().subtract(newPrice).multiply(new BigDecimal(holdOrderEntity.getSymbolCntSale())).multiply(lotNumber);
                 }
 
                 if (MemberEntity.IS_PROFIT_Y == memberEntity.getIsProfit()) {
@@ -648,29 +941,53 @@
             }
         }
 
-        MemberWalletContractEntity walletContractEntity = memberWalletContractDao.findWalletContractByMemberIdAndSymbol(memberEntity.getId(), CoinTypeEnum.USDT.name());
-
         MemberLevelRateEntity rateEntity = memberLevelRateDao.selectLeverRateByMemberIdAndSymbol(memberEntity.getId(), symbol);
 
+        ContractMoneyInfoVo contractMoneyInfoVo = new ContractMoneyInfoVo();
         // 权益
         BigDecimal equity = walletContractEntity.getTotalBalance().add(totalProfitOrLess);
-
-        ContractMoneyInfoVo contractMoneyInfoVo = new ContractMoneyInfoVo();
-        contractMoneyInfoVo.setAvailableBalance(walletContractEntity.getAvailableBalance());
+        if (equity.compareTo(BigDecimal.ZERO) <= 0) {
+            equity = BigDecimal.ZERO;
+        }
+        
+        BigDecimal available = walletContractEntity.getAvailableBalance();
+        if (ContractEntrustOrderEntity.POSITION_TYPE_ALL == memberEntity.getContractPositionType()) {
+            if (totalProfitOrLess.compareTo(BigDecimal.ZERO) <= 0) {
+                available = available.add(totalProfitOrLess);
+                if (available.compareTo(BigDecimal.ZERO) <= 0) {
+                    available = BigDecimal.ZERO;
+                }
+            }
+        }
+        
+        // 获取当日k线的开盘价
+        Candlestick symbolObject = (Candlestick) redisUtils.get(symbol);
+        BigDecimal openPrice = symbolObject.getOpen();
+        BigDecimal upOrDown = newPriceSymbol.subtract(openPrice).divide(openPrice, 8, BigDecimal.ROUND_HALF_UP);
         contractMoneyInfoVo.setBeUsedBondAmount(beUsedBondAmount);
         contractMoneyInfoVo.setFrozenBondAmount(frozenBondAmount);
         contractMoneyInfoVo.setEquity(equity);
+        contractMoneyInfoVo.setAvailableBalance(available);
         contractMoneyInfoVo.setFeeRatio(tradeSetting.getFeeRatio());
         contractMoneyInfoVo.setLeverAgeRatio(tradeSetting.getLeverageRatio());
         contractMoneyInfoVo.setNewPrice(newPriceSymbol);
+        contractMoneyInfoVo.setUpOrDown(upOrDown);
         contractMoneyInfoVo.setSymbolSku(cacheSettingUtils.getSymbolSku(symbol));
         contractMoneyInfoVo.setLeverRate(rateEntity.getLevelRateUp());
+        contractMoneyInfoVo.setMoreBondAmount(moreBondAmount);
+        contractMoneyInfoVo.setLessBondAmount(lessBondAmount);
+        contractMoneyInfoVo.setProfitOrLess(totalProfitOrLess);
         return Result.ok(contractMoneyInfoVo);
     }
 
     @Override
     public Result changeLeverRate(ChangeLeverRateDto changeLeverRateDto) {
         MemberEntity memberEntity = LoginUserUtils.getAppLoginUser();
+
+        List<ContractHoldOrderEntity> holdOrders = contractHoldOrderDao.selectHoldOrderListForWholeByMemberIdAndSymbol(memberEntity.getId(), changeLeverRateDto.getSymbol());
+        if (CollUtil.isNotEmpty(holdOrders)) {
+            return Result.fail("存在持仓, 无法调整杠杆");
+        }
         MemberLevelRateEntity levelRateEntity = memberLevelRateDao.selectLeverRateByMemberIdAndSymbol(memberEntity.getId(), changeLeverRateDto.getSymbol());
         levelRateEntity.setLevelRateUp(changeLeverRateDto.getLeverRate());
         levelRateEntity.setLevelRateDown(changeLeverRateDto.getLeverRate());
@@ -751,7 +1068,7 @@
                 } else {
                     BigDecimal available = walletContractEntity.getAvailableBalance();
                     BigDecimal lessAmount = thisTimeHold.subtract(available);
-                    MemberEntity memberEntity = memberDao.selectById(holdOrderEntity.getId());
+                    MemberEntity memberEntity = memberDao.selectById(holdOrderEntity.getMemberId());
                     memberWalletContractDao.increaseWalletContractBalanceById(available.negate(), available.negate(), null, walletContractEntity.getId());
 
                     BigDecimal newBondAmount = holdOrderEntity.getBondAmount().subtract(lessAmount);
@@ -765,20 +1082,20 @@
                     contractHoldOrderDao.updateById(holdOrderEntity);
 
                     // 发送爆仓消息
-                    sendOrderBombMsg(holdOrderEntity.getId(), holdOrderEntity.getOpeningType(), newForcePrice, holdOrderEntity.getSymbol(), holdOrderEntity.getOperateNo());
+                    sendOrderBombMsg(holdOrderEntity.getId(), holdOrderEntity.getOpeningType(), newForcePrice, holdOrderEntity.getSymbol(), holdOrderEntity.getOperateNo(), holdOrderEntity.getMemberId());
                 }
             }
         }
     }
 
-    public void sendOrderBombMsg(Long id, int type, BigDecimal forceClosingPrice, String symbol, int operateNo) {
+    public void sendOrderBombMsg(Long id, int type, BigDecimal forceClosingPrice, String symbol, int operateNo, Long memberId) {
         OrderModel model = null;
         // 开多
         if (ContractHoldOrderEntity.OPENING_TYPE_MORE == type) {
-            model = new OrderModel(id, RabbitPriceTypeEnum.CLOSE_MORE_BOMB.getValue(), forceClosingPrice.setScale(8, RoundingMode.HALF_UP).toPlainString(), symbol, operateNo);
+            model = new OrderModel(id, RabbitPriceTypeEnum.CLOSE_MORE_BOMB.getValue(), forceClosingPrice.setScale(8, RoundingMode.HALF_UP).toPlainString(), symbol, operateNo, memberId);
             // 开空
         } else {
-            model = new OrderModel(id, RabbitPriceTypeEnum.CLOSE_LESS_BOMB.getValue(), forceClosingPrice.setScale(8, RoundingMode.HALF_UP).toPlainString(), symbol, operateNo);
+            model = new OrderModel(id, RabbitPriceTypeEnum.CLOSE_LESS_BOMB.getValue(), forceClosingPrice.setScale(8, RoundingMode.HALF_UP).toPlainString(), symbol, operateNo, memberId);
         }
         producer.sendPriceOperate(JSONObject.toJSONString(model));
     }
@@ -790,8 +1107,36 @@
         List<ContractHoldOrderEntity> list = contractHoldOrderDao.selectHoldOrderListByMemberId(member.getId());
         List<ContractEntrustOrderEntity> entrustList = contractEntrustOrderDao.selectEntrustOrderListByMemberId(member.getId());
 
-        if (CollUtil.isNotEmpty(list) || CollUtil.isNotEmpty(entrustList)) {
-            return Result.fail("存在持仓/委托, 无法更改");
+//        if (CollUtil.isNotEmpty(list) || CollUtil.isNotEmpty(entrustList)) {
+//            return Result.fail("存在持仓/委托, 无法更改");
+//        }
+        
+        if(CollUtil.isNotEmpty(list)) {
+        	for(ContractHoldOrderEntity contractHoldOrderEntity : list) {
+        		String symbol = contractHoldOrderEntity.getSymbol();
+        		if(StrUtil.isEmpty(symbol)) {
+        			return Result.fail("存在持仓/委托, 无法更改");
+        		}
+        		return Result.fail("币种"+symbol+"存在持仓/委托, 无法更改");
+        	}
+        }
+        if(CollUtil.isNotEmpty(entrustList)) {
+        	for(ContractEntrustOrderEntity contractEntrustOrderEntity : entrustList) {
+        		String symbol = contractEntrustOrderEntity.getSymbol();
+        		if(StrUtil.isEmpty(symbol)) {
+        			return Result.fail("存在持仓/委托, 无法更改");
+        		}
+        		return Result.fail("币种"+symbol+"存在持仓/委托, 无法更改");
+        	}
+        }
+        
+        /**
+         * 验证用户是否存在跟随交易员
+         * 是:不允许切换成全仓模式
+         */
+        List<FollowFollowerProfitEntity> followFollowerProfitEntitys = followFollowerProfitDao.selectByMemberIdandIsFollow(member.getId(),FollowFollowerProfitEntity.IS_FOLLOW_Y);
+        if(CollUtil.isNotEmpty(followFollowerProfitEntitys)) {
+        	return Result.fail(MessageSourceUtils.getString("documentary_service_0018"));
         }
 
         Integer positionType = member.getContractPositionType() == ContractEntrustOrderEntity.POSITION_TYPE_ADD ? ContractEntrustOrderEntity.POSITION_TYPE_ALL : ContractEntrustOrderEntity.POSITION_TYPE_ADD;
@@ -800,9 +1145,52 @@
         updateEntity.setId(member.getId());
         int i = memberDao.updateById(updateEntity);
         if (i > 0) {
+            member.setContractPositionType(positionType);
             LoginUserUtils.resetAppLoginUser(member);
             return Result.ok(MessageSourceUtils.getString("member_service_0040"));
         }
         return Result.fail(MessageSourceUtils.getString("member_service_0041"));
     }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void calHoldFeeAmountForBondAmount() {
+        List<ContractHoldOrderEntity> list = contractHoldOrderDao.selectAllHoldOrder();
+        PlatformTradeSettingEntity tradeSettingEntity = cacheSettingUtils.getTradeSetting();
+
+        if (CollUtil.isNotEmpty(list)) {
+            for (ContractHoldOrderEntity holdOrderEntity : list) {
+                BigDecimal thisTimeHold = holdOrderEntity.getBondAmount().subtract(holdOrderEntity.getOpeningFeeAmount()).multiply(tradeSettingEntity.getDoingRatio());
+                MemberWalletContractEntity wallet = memberWalletContractDao.findWalletContractByMemberIdAndSymbol(holdOrderEntity.getMemberId(), CoinTypeEnum.USDT.name());
+                log.info("订单编号:{}, 持仓费:{}", holdOrderEntity.getOrderNo(), thisTimeHold);
+
+                BigDecimal holdAmount = holdOrderEntity.getHoldAmount();
+                if (holdAmount == null) {
+                    holdAmount = BigDecimal.ZERO;
+                }
+
+                holdAmount = holdAmount.add(thisTimeHold);
+                if (ContractEntrustOrderEntity.POSITION_TYPE_ADD == holdOrderEntity.getPositionType()) {
+
+                    MemberEntity memberEntity = memberDao.selectById(holdOrderEntity.getMemberId());
+                    BigDecimal subBond = holdOrderEntity.getBondAmount().subtract(thisTimeHold);
+                    BigDecimal newForcePrice = CalculateUtil.getForceSetPrice(subBond.subtract(holdOrderEntity.getOpeningFeeAmount()), holdOrderEntity.getOpeningPrice(), holdOrderEntity.getSymbolCnt(), holdOrderEntity.getSymbolSku(), holdOrderEntity.getOpeningType(), memberEntity);
+                    holdOrderEntity.setBondAmount(subBond);
+                    holdOrderEntity.setHoldAmount(holdAmount);
+                    holdOrderEntity.setForceClosingPrice(newForcePrice);
+                    holdOrderEntity.setOperateNo(holdOrderEntity.getOperateNo() + 1);
+                    contractHoldOrderDao.updateById(holdOrderEntity);
+
+                    memberWalletContractDao.increaseWalletContractBalanceById(null, thisTimeHold.negate(), null, wallet.getId());
+                    // 发送爆仓消息
+                    sendOrderBombMsg(holdOrderEntity.getId(), holdOrderEntity.getOpeningType(), newForcePrice, holdOrderEntity.getSymbol(), holdOrderEntity.getOperateNo(), holdOrderEntity.getMemberId());
+                } else {
+//                    holdOrderEntity.setHoldAmount(holdAmount);
+//                    contractHoldOrderDao.updateById(holdOrderEntity);
+//                    memberWalletContractDao.increaseWalletContractBalanceById(thisTimeHold.negate(), thisTimeHold.negate(), null, wallet.getId());
+//                    ThreadPoolUtils.sendWholePrice(holdOrderEntity.getMemberId());
+                }
+            }
+        }
+    }
 }

--
Gitblit v1.9.1