From 55a4f22db43ec34bc7f59103f4a94005bd613850 Mon Sep 17 00:00:00 2001
From: zainali5120 <512061637@qq.com>
Date: Wed, 31 Mar 2021 15:40:04 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/activity' into activity

---
 src/main/resources/mapper/contract/ContractOrderDao.xml                                              |   19 +
 src/main/java/com/xcong/excoin/modules/contract/service/impl/ContractHoldOrderServiceImpl.java       |   66 +++--
 src/main/java/com/xcong/excoin/modules/documentary/service/impl/FollowOrderOperationServiceImpl.java |   51 ++++
 src/main/java/com/xcong/excoin/modules/coin/service/impl/CoinServiceImpl.java                        |  132 +++++++++++--
 src/main/java/com/xcong/excoin/modules/contract/service/impl/OrderWebsocketServiceImpl.java          |   53 ++++
 src/main/java/com/xcong/excoin/modules/contract/controller/ContractOrderController.java              |   17 +
 src/main/java/com/xcong/excoin/modules/contract/dao/ContractOrderDao.java                            |    4 
 src/main/java/com/xcong/excoin/modules/contract/parameter/dto/SymbolDto.java                         |    3 
 src/main/java/com/xcong/excoin/modules/documentary/dao/FollowFollowerProfitDao.java                  |    4 
 src/main/java/com/xcong/excoin/utils/CalculateUtil.java                                              |   43 ++++
 src/main/java/com/xcong/excoin/modules/documentary/dao/FollowFollowerOrderRelationDao.java           |    1 
 src/main/java/com/xcong/excoin/modules/contract/service/impl/RabbitOrderServiceImpl.java             |   45 +++-
 src/test/java/com/xcong/excoin/WholeTest.java                                                        |   19 +
 src/main/resources/mapper/documentary/FollowTraderProfitDetailDao.xml                                |   13 +
 src/main/resources/mapper/documentary/FollowFollowerProfitDao.xml                                    |   26 ++
 src/main/java/com/xcong/excoin/quartz/job/LoopExecutorJob.java                                       |    1 
 src/main/java/com/xcong/excoin/modules/documentary/common/NoticeConstant.java                        |    5 
 src/main/java/com/xcong/excoin/modules/documentary/dao/FollowTraderProfitDetailDao.java              |    7 
 src/main/java/com/xcong/excoin/quartz/job/FollowProfitUpdateJob.java                                 |   27 ++
 src/main/java/com/xcong/excoin/modules/contract/service/ContractHoldOrderService.java                |    4 
 src/main/resources/mapper/member/MemberAccountMoneyChangeDao.xml                                     |    2 
 src/main/resources/mapper/documentary/FollowFollowerOrderRelationDao.xml                             |    7 
 22 files changed, 474 insertions(+), 75 deletions(-)

diff --git a/src/main/java/com/xcong/excoin/modules/coin/service/impl/CoinServiceImpl.java b/src/main/java/com/xcong/excoin/modules/coin/service/impl/CoinServiceImpl.java
index a3e53bb..48bd01d 100644
--- a/src/main/java/com/xcong/excoin/modules/coin/service/impl/CoinServiceImpl.java
+++ b/src/main/java/com/xcong/excoin/modules/coin/service/impl/CoinServiceImpl.java
@@ -9,7 +9,13 @@
 import javax.annotation.Resource;
 import javax.validation.Valid;
 
+import com.xcong.excoin.modules.contract.dao.ContractHoldOrderDao;
+import com.xcong.excoin.modules.contract.entity.ContractEntrustOrderEntity;
+import com.xcong.excoin.modules.contract.entity.ContractHoldOrderEntity;
+import com.xcong.excoin.modules.contract.entity.ContractOrderEntity;
 import com.xcong.excoin.modules.platform.entity.PlatformCnyUsdtExchangeEntity;
+import com.xcong.excoin.modules.platform.entity.PlatformTradeSettingEntity;
+import com.xcong.excoin.utils.*;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -48,10 +54,6 @@
 import com.xcong.excoin.modules.member.entity.MemberWalletCoinEntity;
 import com.xcong.excoin.modules.member.entity.MemberWalletContractEntity;
 import com.xcong.excoin.modules.platform.dao.PlatformCnyUsdtExchangeDao;
-import com.xcong.excoin.utils.CoinTypeConvert;
-import com.xcong.excoin.utils.MessageSourceUtils;
-import com.xcong.excoin.utils.RedisUtils;
-import com.xcong.excoin.utils.ThreadPoolUtils;
 
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.ObjectUtil;
@@ -81,6 +83,10 @@
     MemberCoinWithdrawDao memberCoinWithdrawDao;
     @Resource
     RedisUtils redisUtils;
+    @Resource
+    CacheSettingUtils cacheSettingUtils;
+    @Resource
+    ContractHoldOrderDao contractHoldOrderDao;
 
 
     @Override
@@ -318,7 +324,9 @@
             //更新合约全仓模式下的订单权益
             MemberEntity memberEntity = memberDao.selectById(memberId);
             String symbols = symbol+"/USDT";
-            ThreadPoolUtils.sendWholeForceClosingPrice(symbols, memberEntity);
+            //ThreadPoolUtils.sendWholeForceClosingPrice(symbols, memberEntity);
+            // 全仓爆仓
+            ThreadPoolUtils.sendWholePrice(memberEntity.getId());
             
             //添加币币资金划转历史记录
             MemberAccountMoneyChange memberAccountRecord = new MemberAccountMoneyChange();
@@ -402,15 +410,53 @@
     @Override
     @Transactional(rollbackFor = Exception.class)
     public Result contractTransferToWalletCoins(BigDecimal balance, String symbol) {
-    	if (balance.compareTo(BigDecimal.ZERO) <= 0) {
+        //获取用户ID
+        Long memberId = LoginUserUtils.getAppLoginUser().getId();
+        MemberEntity memberEntity = memberDao.selectById(memberId);
+        if (balance.compareTo(BigDecimal.ZERO) <= 0) {
     		return Result.fail(MessageSourceUtils.getString("member_service_0004"));
     	}
-    	//获取用户ID
-    	Long memberId = LoginUserUtils.getAppLoginUser().getId();
-    	
+        //获取合约当前持仓类型
+        Integer contractPositionType = memberEntity.getContractPositionType();
+        // 总盈利
+        BigDecimal totalProfitOrLess = BigDecimal.ZERO;
+        if(contractPositionType == 2){
+            //获取全仓模式下的所有持仓信息
+            PlatformTradeSettingEntity tradeSetting = cacheSettingUtils.getTradeSetting();
+            List<ContractHoldOrderEntity> holdOrderEntities = contractHoldOrderDao.selectHoldOrderListForWholeByMemberIdAndSymbol(memberEntity.getId(),"");
+            if (CollUtil.isNotEmpty(holdOrderEntities)) {
+                for (ContractHoldOrderEntity holdOrderEntity : holdOrderEntities) {
+                    // 获取最新价
+                    BigDecimal newPrice = new BigDecimal(redisUtils.getString(CoinTypeConvert.convertToKey(holdOrderEntity.getSymbol())));
+                    BigDecimal lotNumber = cacheSettingUtils.getSymbolSku(holdOrderEntity.getSymbol());
+                    // 单个订单盈利
+                    BigDecimal profitOrLess = BigDecimal.ZERO;
+                    // 开多
+                    if (ContractHoldOrderEntity.OPENING_TYPE_MORE == holdOrderEntity.getOpeningType()) {
+                        profitOrLess = newPrice.subtract(holdOrderEntity.getOpeningPrice()).multiply(new BigDecimal(holdOrderEntity.getSymbolCntSale())).multiply(lotNumber);
+                        // 开空
+                    } else {
+                        profitOrLess = holdOrderEntity.getOpeningPrice().subtract(newPrice).multiply(new BigDecimal(holdOrderEntity.getSymbolCntSale())).multiply(lotNumber);
+                    }
+                    if (MemberEntity.IS_PROFIT_Y == memberEntity.getIsProfit()) {
+                        if (profitOrLess.compareTo(BigDecimal.ZERO) > 0) {
+                            profitOrLess = profitOrLess.multiply(BigDecimal.ONE.subtract(tradeSetting.getForceParam()));
+                        } else {
+                            profitOrLess = profitOrLess.multiply(BigDecimal.ONE.add(tradeSetting.getForceParam()));
+                        }
+                    }
+                    totalProfitOrLess = totalProfitOrLess.add(profitOrLess);
+                }
+            }
+        }
+
     	String walletCode = MemberWalletCoinEnum.WALLETCOINCODE.getValue();
     	MemberWalletContractEntity walletContract = memberWalletContractDao.findWalletContractByMemberIdAndSymbol(memberId, symbol);
     	BigDecimal availableBalance = walletContract.getAvailableBalance();
+    	//可用减去盈亏
+    	if(totalProfitOrLess.compareTo(BigDecimal.ZERO) < 0){
+            availableBalance = availableBalance.add(totalProfitOrLess);
+        }
     	// 扣币
     	BigDecimal availableSubtract = availableBalance.subtract(balance);
     	if (availableSubtract.compareTo(BigDecimal.ZERO) < 0) {
@@ -438,11 +484,9 @@
     	if (updateById < 1) {
     		return Result.fail(MessageSourceUtils.getString("member_service_0096"));
     	}
-    	
-    	//更新合约全仓模式下的订单权益
-        MemberEntity memberEntity = memberDao.selectById(memberId);
-        String symbols = symbol+"/USDT";
-        ThreadPoolUtils.sendWholeForceClosingPrice(symbols, memberEntity);
+
+        // 全仓爆仓
+        ThreadPoolUtils.sendWholePrice(memberEntity.getId());
     	
     	//添加资金划转历史记录
     	MemberAccountMoneyChange memberAccountRecord = new MemberAccountMoneyChange();
@@ -467,8 +511,52 @@
     public Result findWalletContractBySymbol(String symbol) {
         //获取用户ID
         Long memberId = LoginUserUtils.getAppLoginUser().getId();
+        MemberEntity memberEntity = memberDao.selectById(memberId);
+        //获取合约当前持仓类型
+        Integer contractPositionType = memberEntity.getContractPositionType();
+        // 总盈利
+        BigDecimal totalProfitOrLess = BigDecimal.ZERO;
+        if(contractPositionType == 2){
+            //获取全仓模式下的所有持仓信息
+            PlatformTradeSettingEntity tradeSetting = cacheSettingUtils.getTradeSetting();
+            List<ContractHoldOrderEntity> holdOrderEntities = contractHoldOrderDao.selectHoldOrderListForWholeByMemberIdAndSymbol(memberEntity.getId(),"");
+            if (CollUtil.isNotEmpty(holdOrderEntities)) {
+                for (ContractHoldOrderEntity holdOrderEntity : holdOrderEntities) {
+                    // 获取最新价
+                    BigDecimal newPrice = new BigDecimal(redisUtils.getString(CoinTypeConvert.convertToKey(holdOrderEntity.getSymbol())));
+                    BigDecimal lotNumber = cacheSettingUtils.getSymbolSku(holdOrderEntity.getSymbol());
+                    // 单个订单盈利
+                    BigDecimal profitOrLess = BigDecimal.ZERO;
+                    // 开多
+                    if (ContractHoldOrderEntity.OPENING_TYPE_MORE == holdOrderEntity.getOpeningType()) {
+                        profitOrLess = newPrice.subtract(holdOrderEntity.getOpeningPrice()).multiply(new BigDecimal(holdOrderEntity.getSymbolCntSale())).multiply(lotNumber);
+                        // 开空
+                    } else {
+                        profitOrLess = holdOrderEntity.getOpeningPrice().subtract(newPrice).multiply(new BigDecimal(holdOrderEntity.getSymbolCntSale())).multiply(lotNumber);
+                    }
+                    if (MemberEntity.IS_PROFIT_Y == memberEntity.getIsProfit()) {
+                        if (profitOrLess.compareTo(BigDecimal.ZERO) > 0) {
+                            profitOrLess = profitOrLess.multiply(BigDecimal.ONE.subtract(tradeSetting.getForceParam()));
+                        } else {
+                            profitOrLess = profitOrLess.multiply(BigDecimal.ONE.add(tradeSetting.getForceParam()));
+                        }
+                    }
+                    totalProfitOrLess = totalProfitOrLess.add(profitOrLess);
+                }
+            }
+        }
+
         MemberWalletContractEntity walletContract = memberWalletContractDao.findWalletContractByMemberIdAndSymbol(memberId, symbol);
-        BigDecimal availableBalance = walletContract.getAvailableBalance().setScale(4, BigDecimal.ROUND_DOWN);
+        BigDecimal availableBalance = walletContract.getAvailableBalance();
+        //可用减去盈亏
+        if(totalProfitOrLess.compareTo(BigDecimal.ZERO) < 0){
+            availableBalance = availableBalance.add(totalProfitOrLess);
+        }
+        if(availableBalance.compareTo(BigDecimal.ZERO) > 0){
+            availableBalance = availableBalance.setScale(4, BigDecimal.ROUND_DOWN);
+        }else{
+            availableBalance = BigDecimal.ZERO;
+        }
         return Result.ok(availableBalance);
     }
 
@@ -682,7 +770,9 @@
     		//更新合约全仓模式下的订单权益
             MemberEntity memberEntity = memberDao.selectById(memberId);
             String symbols = symbol+"/USDT";
-            ThreadPoolUtils.sendWholeForceClosingPrice(symbols, memberEntity);
+            //ThreadPoolUtils.sendWholeForceClosingPrice(symbols, memberEntity);
+            // 全仓爆仓
+            ThreadPoolUtils.sendWholePrice(memberEntity.getId());
     		
     		//添加资金划转历史记录
     		memberAccountRecord.setMemberId(memberId);
@@ -862,7 +952,9 @@
     	//更新合约全仓模式下的订单权益
         MemberEntity memberEntity = memberDao.selectById(memberId);
         String symbols = symbolOut+"/USDT";
-        ThreadPoolUtils.sendWholeForceClosingPrice(symbols, memberEntity);
+        //ThreadPoolUtils.sendWholeForceClosingPrice(symbols, memberEntity);
+        // 全仓爆仓
+        ThreadPoolUtils.sendWholePrice(memberEntity.getId());
         
         // 加币
         // 查询合约账户
@@ -880,9 +972,9 @@
         
         //更新合约全仓模式下的订单权益
         String symbolIns = symbolIn+"/USDT";
-        ThreadPoolUtils.sendWholeForceClosingPrice(symbolIns, memberEntity);
-        
-        ThreadPoolUtils.sendWholePrice(memberId);
+        //ThreadPoolUtils.sendWholeForceClosingPrice(symbolIns, memberEntity);
+        // 全仓爆仓
+        ThreadPoolUtils.sendWholePrice(memberEntity.getId());
         
         //添加币币资金划转历史记录
         MemberAccountMoneyChange memberAccountRecord = new MemberAccountMoneyChange();
diff --git a/src/main/java/com/xcong/excoin/modules/contract/controller/ContractOrderController.java b/src/main/java/com/xcong/excoin/modules/contract/controller/ContractOrderController.java
index fca4232..5f74494 100644
--- a/src/main/java/com/xcong/excoin/modules/contract/controller/ContractOrderController.java
+++ b/src/main/java/com/xcong/excoin/modules/contract/controller/ContractOrderController.java
@@ -2,6 +2,8 @@
 
 import com.xcong.excoin.common.LoginUserUtils;
 import com.xcong.excoin.common.response.Result;
+import com.xcong.excoin.modules.contract.entity.ContractHoldOrderEntity;
+import com.xcong.excoin.modules.contract.entity.ContractOrderEntity;
 import com.xcong.excoin.modules.contract.parameter.dto.*;
 import com.xcong.excoin.modules.contract.parameter.vo.ContractMoneyInfoVo;
 import com.xcong.excoin.modules.contract.parameter.vo.HoldOrderListVo;
@@ -76,6 +78,14 @@
     @ApiOperation(value = "一键平仓")
     @PostMapping(value = "/oneKeyClosing")
     public Result oneKeyClosing(@RequestBody SymbolDto symbolDto) {
+        symbolDto.setType(ContractOrderEntity.CONTRACTTYPE_NORMAL);
+        return contractHoldOrderService.cancelHoldOrderBatch(symbolDto);
+    }
+
+    @ApiOperation(value = "带单一键平仓")
+    @PostMapping(value = "/oneKeyClosingForFollow")
+    public Result oneKeyClosingForFollow(@RequestBody SymbolDto symbolDto) {
+        symbolDto.setType(ContractOrderEntity.CONTRACTTYPE_DOCUMENTARY);
         return contractHoldOrderService.cancelHoldOrderBatch(symbolDto);
     }
 
@@ -127,6 +137,13 @@
         return contractHoldOrderService.cancelHoldOrder(wholeCloseOrderDto);
     }
 
+    @ApiOperation(value = "全仓模式 - 一键平仓")
+    @PostMapping(value = "/oneKeyClosingForWhole")
+    public Result oneKeyClosingForWhole() {
+        SymbolDto symbolDto = new SymbolDto();
+        return contractHoldOrderService.cancelHoldOrderBatch(symbolDto);
+    }
+
     @ApiOperation(value = "全仓模式 - 变更仓位类型")
     @GetMapping(value = "/changePositionType")
     public Result changePositionType() {
diff --git a/src/main/java/com/xcong/excoin/modules/contract/dao/ContractOrderDao.java b/src/main/java/com/xcong/excoin/modules/contract/dao/ContractOrderDao.java
index 1ef44c6..0679e99 100644
--- a/src/main/java/com/xcong/excoin/modules/contract/dao/ContractOrderDao.java
+++ b/src/main/java/com/xcong/excoin/modules/contract/dao/ContractOrderDao.java
@@ -33,4 +33,8 @@
     int updateOrderProfitOrLessById(@Param("rewardAmount") BigDecimal rewardAmount, @Param("rewardRatio") BigDecimal rewardRatio, @Param("id") Long id);
 
 	public BigDecimal getBurstUsdtByMemberId(@Param("memberId") Long memberId);
+
+	public List<ContractOrderEntity> selectFollowOrderListByMemberId(@Param("tradeMemberId")Long tradeMemberId);
+
+	public String selectOrderNoByOrderIds(@Param("orderId")Long orderId);
 }
diff --git a/src/main/java/com/xcong/excoin/modules/contract/parameter/dto/SymbolDto.java b/src/main/java/com/xcong/excoin/modules/contract/parameter/dto/SymbolDto.java
index 4319d46..253f01c 100644
--- a/src/main/java/com/xcong/excoin/modules/contract/parameter/dto/SymbolDto.java
+++ b/src/main/java/com/xcong/excoin/modules/contract/parameter/dto/SymbolDto.java
@@ -14,4 +14,7 @@
 
     @ApiModelProperty(value = "币种", example = "BTC/USDT")
     private String symbol;
+
+    @ApiModelProperty(hidden = true)
+    private Integer type;
 }
diff --git a/src/main/java/com/xcong/excoin/modules/contract/service/ContractHoldOrderService.java b/src/main/java/com/xcong/excoin/modules/contract/service/ContractHoldOrderService.java
index bbcbbd8..9bc63b1 100644
--- a/src/main/java/com/xcong/excoin/modules/contract/service/ContractHoldOrderService.java
+++ b/src/main/java/com/xcong/excoin/modules/contract/service/ContractHoldOrderService.java
@@ -4,6 +4,8 @@
 import com.xcong.excoin.common.response.Result;
 import com.xcong.excoin.modules.contract.entity.ContractHoldOrderEntity;
 import com.xcong.excoin.modules.contract.parameter.dto.*;
+import com.xcong.excoin.modules.documentary.entity.FollowTraderInfoEntity;
+import com.xcong.excoin.modules.member.entity.MemberEntity;
 import com.xcong.excoin.rabbit.pricequeue.OrderModel;
 import org.apache.ibatis.annotations.Param;
 
@@ -49,4 +51,6 @@
     public Result changePositionType();
     public void calHoldFeeAmountForBondAmount();
 
+    public void sendFollowOrder(FollowTraderInfoEntity traderInfoEntity, ContractHoldOrderEntity holdOrderEntity);
+
 }
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 7a9967d..0532ea6 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
@@ -385,17 +385,7 @@
 
             // 若该用户为交易员且开启带单模式,则发送带单异步
             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);
-
-                followProducer.sendAddFollowOrder(holdOrderEntity.getId());
+                sendFollowOrder(tradeInfo, holdOrderEntity);
 //                ThreadPoolUtils.sendFollowOrderTask(holdOrderEntity.getId());
             }
             // 提交成功
@@ -405,6 +395,20 @@
         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());
+    }
 
     /**
      * 全仓模式--若当前已经存在持仓,则合并当前持仓
@@ -527,7 +531,7 @@
                 holdOrderListVo.setReturnRate(returnRate);
                 holdOrderListVo.setProfitOrLoss(rewardRatio);
                 if (ContractEntrustOrderEntity.POSITION_TYPE_ALL == memberEntity.getContractPositionType()) {
-                    BigDecimal forcePrice = CalculateUtil.getForceSetPriceForWhole(holdOrderEntity.getSymbol(), memberEntity);
+                    BigDecimal forcePrice = CalculateUtil.calForcePriceForWhole(memberEntity, holdOrderEntity);
                     holdOrderListVo.setForceClosingPrice(forcePrice);
                 }
                 resultList.add(holdOrderListVo);
@@ -648,7 +652,7 @@
         	return Result.loading("loading_type");
         }
         
-        List<ContractHoldOrderEntity> holdOrderEntities = contractHoldOrderDao.selectHoldOrderListByMemberIdAndSymbol(memberEntity.getId(), symbolDto.getSymbol(), 1);
+        List<ContractHoldOrderEntity> holdOrderEntities = contractHoldOrderDao.selectHoldOrderListByMemberIdAndSymbol(memberEntity.getId(), symbolDto.getSymbol(), symbolDto.getType());
         if (CollUtil.isEmpty(holdOrderEntities)) {
             return Result.fail("订单不存在");
         }
@@ -859,7 +863,7 @@
         BigDecimal newPriceSymbol = new BigDecimal(redisUtils.getString(CoinTypeConvert.convertToKey(symbol)));
 
         List<ContractEntrustOrderEntity> entrustOrderEntities = contractEntrustOrderDao.selectEntrustOrderListByMemberId(memberEntity.getId());
-        List<ContractHoldOrderEntity> holdOrderEntities = contractHoldOrderDao.selectHoldOrderListByMemberIdAndSymbolTest(memberEntity.getId(), ContractOrderEntity.CONTRACTTYPE_NORMAL);
+        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)) {
 //            // 当前合约委托单
@@ -1135,29 +1139,35 @@
 
         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;
                 }
 
-                BigDecimal thisTimeHold = holdOrderEntity.getBondAmount().subtract(holdOrderEntity.getOpeningFeeAmount()).multiply(tradeSettingEntity.getDoingRatio());
-                log.info("订单编号:{}, 持仓费:{}", holdOrderEntity.getOrderNo(), thisTimeHold);
-
-                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);
                 holdAmount = holdAmount.add(thisTimeHold);
-                holdOrderEntity.setBondAmount(subBond);
-                holdOrderEntity.setHoldAmount(holdAmount);
-                holdOrderEntity.setForceClosingPrice(newForcePrice);
-                holdOrderEntity.setOperateNo(holdOrderEntity.getOperateNo() + 1);
-                contractHoldOrderDao.updateById(holdOrderEntity);
-
-                memberWalletContractDao.increaseWalletContractBalanceById(null, thisTimeHold.negate(), null, holdOrderEntity.getMemberId());
                 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());
                 }
             }
         }
diff --git a/src/main/java/com/xcong/excoin/modules/contract/service/impl/OrderWebsocketServiceImpl.java b/src/main/java/com/xcong/excoin/modules/contract/service/impl/OrderWebsocketServiceImpl.java
index 06164aa..b7304af 100644
--- a/src/main/java/com/xcong/excoin/modules/contract/service/impl/OrderWebsocketServiceImpl.java
+++ b/src/main/java/com/xcong/excoin/modules/contract/service/impl/OrderWebsocketServiceImpl.java
@@ -19,6 +19,7 @@
 import com.xcong.excoin.modules.contract.service.ContractEntrustOrderService;
 import com.xcong.excoin.modules.contract.service.ContractHoldOrderService;
 import com.xcong.excoin.modules.contract.service.ContractOrderService;
+import com.xcong.excoin.modules.contract.service.RabbitOrderService;
 import com.xcong.excoin.modules.documentary.common.NoticeConstant;
 import com.xcong.excoin.modules.documentary.dao.FollowFollowerOrderRelationDao;
 import com.xcong.excoin.modules.documentary.dao.FollowFollowerProfitDao;
@@ -39,6 +40,7 @@
 import com.xcong.excoin.modules.member.service.MemberWalletContractService;
 import com.xcong.excoin.modules.platform.entity.PlatformTradeSettingEntity;
 import com.xcong.excoin.rabbit.pricequeue.OrderModel;
+import com.xcong.excoin.rabbit.producer.FollowProducer;
 import com.xcong.excoin.rabbit.producer.OrderProducer;
 import com.xcong.excoin.utils.*;
 import lombok.extern.slf4j.Slf4j;
@@ -104,6 +106,9 @@
     private RedisUtils redisUtils;
     @Resource
     private FollowOrderOperationService followOrderOperationService;
+
+    @Resource
+    private FollowProducer followProducer;
 
     public void dealOrderFromMq(List<OrderModel> list, Integer type) {
         if (CollectionUtils.isNotEmpty(list)) {
@@ -171,6 +176,21 @@
         if (CollUtil.isNotEmpty(entrustOrders)) {
             for (ContractEntrustOrderEntity entrustOrder : entrustOrders) {
                 contractEntrustOrderDao.deleteById(entrustOrder.getId());
+            }
+        }
+    }
+
+    private void closingFollowerOrders(MemberEntity memberEntity, ContractHoldOrderEntity holdOrderEntity, ContractOrderEntity contractOrderEntity) {
+        // 判断当前持仓是否为跟单订单
+        if (ContractOrderEntity.CONTRACTTYPE_DOCUMENTARY == holdOrderEntity.getContractType()) {
+            FollowTraderInfoEntity traderInfoEntity = followTraderInfoDao.selectTraderInfoByOrderId(holdOrderEntity.getId());
+            updateFollowOrderRelation(holdOrderEntity.getId(), contractOrderEntity.getId());
+
+            // 若为交易员,则平仓跟随者订单
+            if (MemberEntity.IS_TRADER_Y.equals(memberEntity.getIsTrader())) {
+                followOrderOperationService.closingFollowOrders(holdOrderEntity.getOrderNo());
+            } else {
+                LogRecordUtils.insertFollowerNotice(memberEntity.getId(), NoticeConstant.CLOSE_ORDER_TITLE, StrUtil.format(NoticeConstant.CLOSE_ORDER_CONTENT, contractOrderEntity.getSymbol(), contractOrderEntity.getClosingPrice().setScale(2, BigDecimal.ROUND_HALF_UP).toString(), contractOrderEntity.getRewardAmount().setScale(2, BigDecimal.ROUND_HALF_UP).toString(), traderInfoEntity.getNickname()));
             }
         }
     }
@@ -269,6 +289,8 @@
                         if (ContractEntrustOrderEntity.POSITION_TYPE_ALL == order.getPositionType()) {
                             ThreadPoolUtils.sendWholePrice(memberId);
                             deleteEntrustCloseOrder(order.getOrderNo());
+                        } else {
+                            closingFollowerOrders(memberEntity, order, contractOrderEntity);
                         }
                     }
                 }
@@ -370,6 +392,8 @@
                         if (ContractEntrustOrderEntity.POSITION_TYPE_ALL == order.getPositionType()) {
                             ThreadPoolUtils.sendWholePrice(memberId);
                             deleteEntrustCloseOrder(order.getOrderNo());
+                        } else {
+                            closingFollowerOrders(memberEntity, order, contractOrderEntity);
                         }
                     }
                 }
@@ -469,6 +493,8 @@
                         if (ContractEntrustOrderEntity.POSITION_TYPE_ALL == order.getPositionType()) {
                             ThreadPoolUtils.sendWholePrice(memberId);
                             deleteEntrustCloseOrder(order.getOrderNo());
+                        } else {
+                            closingFollowerOrders(memberEntity, order, contractOrderEntity);
                         }
                     }
                 }
@@ -567,6 +593,8 @@
                         if (ContractEntrustOrderEntity.POSITION_TYPE_ALL == order.getPositionType()) {
                             ThreadPoolUtils.sendWholePrice(memberId);
                             deleteEntrustCloseOrder(order.getOrderNo());
+                        } else {
+                            closingFollowerOrders(memberEntity, order, contractOrderEntity);
                         }
                     }
                 }
@@ -625,6 +653,16 @@
                     contractHoldOrderEntity.setOpeningType(ContractHoldOrderEntity.OPENING_TYPE_LESS);
                 }
 
+                // 判断是否开启了带单
+                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.setMemberId(memId);
                 contractHoldOrderEntity.setIsCanClosing(ContractHoldOrderEntity.ORDER_CAN_CLOSING_Y);
@@ -647,6 +685,7 @@
                 contractHoldOrderEntity.setTradeType(ContractHoldOrderEntity.TRADE_TYPE_LIMIT);
                 contractHoldOrderEntity.setOperateNo(1);
                 contractHoldOrderEntity.setSymbolCntSale(contractHoldOrderEntity.getSymbolCnt());
+                contractHoldOrderEntity.setContractType(isOpenFollow ? ContractOrderEntity.CONTRACTTYPE_DOCUMENTARY : ContractOrderEntity.CONTRACTTYPE_NORMAL);
                 contractHoldOrderService.save(contractHoldOrderEntity);
 
                 // 需要一个历史插入
@@ -675,6 +714,12 @@
 
                 //返佣
                 ThreadPoolUtils.calReturnMoney(memberEntity.getId(), openFeePrice, contractOrderEntity, AgentReturnEntity.ORDER_TYPE_OPEN);
+
+                // 若该用户为交易员且开启带单模式,则发送带单异步
+                if (isOpenFollow) {
+                    contractHoldOrderService.sendFollowOrder(tradeInfo, contractHoldOrderEntity);
+                }
+
             }
         }
     }
@@ -916,10 +961,10 @@
                     QueryWrapper<FollowFollowerSettingEntity> queryWrapper = new QueryWrapper<>();
                     queryWrapper.eq("member_id",coinsOrder.getMemberId());
                     FollowFollowerSettingEntity followFollowerSettingEntity = followFollowerSettingDao.selectOne(queryWrapper);
-                    if(ObjectUtil.isNotEmpty(followFollowerSettingEntity)){
-                        Long traderMemberId = followFollowerSettingEntity.getTraderMemberId();
-                        followFollowerProfitDao.updateFollowerProfitByTradeMemberId(coinsOrder.getBondAmount().negate(), coinsOrder.getBondAmount().negate(), traderMemberId, memberEntity.getId());
-                    }
+//                    if(ObjectUtil.isNotEmpty(followFollowerSettingEntity)){
+//                        Long traderMemberId = followFollowerSettingEntity.getTraderMemberId();
+//                        followFollowerProfitDao.updateFollowerProfitByTradeMemberId(coinsOrder.getBondAmount().negate(), coinsOrder.getBondAmount().negate(), traderMemberId, memberEntity.getId());
+//                    }
                     FollowTraderInfoEntity followTraderInfoEntity = followTraderInfoDao.selectById(followFollowerSettingEntity.getTraderId());
                     //更新跟随者-订单关联表
                     updateFollowOrderRelation(coinsOrder.getId(), contractOrderEntity.getId());
diff --git a/src/main/java/com/xcong/excoin/modules/contract/service/impl/RabbitOrderServiceImpl.java b/src/main/java/com/xcong/excoin/modules/contract/service/impl/RabbitOrderServiceImpl.java
index ac86e5c..a738a3d 100644
--- a/src/main/java/com/xcong/excoin/modules/contract/service/impl/RabbitOrderServiceImpl.java
+++ b/src/main/java/com/xcong/excoin/modules/contract/service/impl/RabbitOrderServiceImpl.java
@@ -6,9 +6,11 @@
 import com.alibaba.fastjson.JSONObject;
 import com.xcong.excoin.common.contants.AppContants;
 import com.xcong.excoin.common.enumerates.CoinTypeEnum;
+import com.xcong.excoin.common.enumerates.MemberWalletCoinEnum;
 import com.xcong.excoin.common.enumerates.OrderClosingTypeEnum;
 import com.xcong.excoin.common.system.service.CommonService;
 import com.xcong.excoin.modules.coin.entity.MemberAccountFlowEntity;
+import com.xcong.excoin.modules.coin.entity.MemberAccountMoneyChange;
 import com.xcong.excoin.modules.contract.dao.ContractEntrustOrderDao;
 import com.xcong.excoin.modules.contract.dao.ContractHoldOrderDao;
 import com.xcong.excoin.modules.contract.dao.ContractOrderDao;
@@ -113,7 +115,14 @@
                     List<ContractHoldOrderEntity> holdOrderEntities = contractHoldOrderDao.selectBatchIds(ids);
                     if (CollUtil.isNotEmpty(holdOrderEntities)) {
                         for (ContractHoldOrderEntity holdOrder : holdOrderEntities) {
-                            cancelHoldOrderMethod(holdOrder);
+                            // 判断仓位类型是否逐仓
+                            if (holdOrder.getPositionType() == ContractEntrustOrderEntity.POSITION_TYPE_ADD) {
+                                // 逐仓平仓
+                                cancelHoldOrderMethod(holdOrder);
+                            } else {
+                                // 全仓模式平仓
+                                closingWholeOrder(holdOrder);
+                            }
                         }
                     }
                 }
@@ -186,13 +195,24 @@
                         memberWalletContractDao.increaseWalletContractBalanceById(returnMoney, returnMoney, null, traderWallet.getId());
                         insertReturnProfitDetail(traderInfoEntity.getMemberId(), memberEntity.getId(), returnMoney, holdOrderEntity.getOrderNo());
                         //增加返佣提醒
-                        String orderNo = holdOrderEntity.getOrderNo();
-                        LogRecordUtils.insertFollowerNotice(traderInfoEntity.getMemberId(),
-                                NoticeConstant.RETURN_MONEY_TITLE,
-                                StrUtil.format(NoticeConstant.RETURN_MONEY_CONTENT,
-                                        memberEntity.getInviteId(),
-                                        orderNo,
-                                        returnMoney.setScale(2, BigDecimal.ROUND_HALF_UP).toString()));
+//                        String orderNo = holdOrderEntity.getOrderNo();
+//                        LogRecordUtils.insertFollowerNotice(traderInfoEntity.getMemberId(),
+//                                NoticeConstant.RETURN_MONEY_TITLE,
+//                                StrUtil.format(NoticeConstant.RETURN_MONEY_CONTENT,
+//                                        orderNo,
+//                                		holdOrderEntity.getSymbol(),
+//                                        returnMoney.setScale(2, BigDecimal.ROUND_HALF_UP).toString()));
+//                        //带单返利的记录要在资产页面的其他记录
+//                        LogRecordUtils.insertMemberAccountMoneyChange(
+//                        		traderInfoEntity.getMemberId(),
+//                                StrUtil.format(NoticeConstant.RETURN_MONEY_CONTENT_MAMC,
+//                                        orderNo,
+//                                		holdOrderEntity.getSymbol(),
+//                                        returnMoney.setScale(2, BigDecimal.ROUND_HALF_UP).toString()),
+//                        		returnMoney.setScale(2, BigDecimal.ROUND_HALF_UP),
+//                        		MemberWalletCoinEnum.WALLETCOINCODE.getValue(),
+//                        		MemberAccountMoneyChange.STATUS_SUCCESS_INTEGER,
+//                        		MemberAccountMoneyChange.TYPE_WALLET_AGENT);
                     }
                 }
             }
@@ -226,7 +246,7 @@
                 if (MemberEntity.IS_TRADER_Y.equals(memberEntity.getIsTrader())) {
                     followOrderOperationService.closingFollowOrders(holdOrderEntity.getOrderNo());
                 } else {
-                    followFollowerProfitDao.updateFollowerProfitByTradeMemberId(holdOrderEntity.getBondAmount(), profitOrLoss, traderInfoEntity.getMemberId(), memberEntity.getId());
+                    //followFollowerProfitDao.updateFollowerProfitByTradeMemberId(holdOrderEntity.getBondAmount(), profitOrLoss, traderInfoEntity.getMemberId(), memberEntity.getId());
                     LogRecordUtils.insertFollowerNotice(memberEntity.getId(), NoticeConstant.CLOSE_ORDER_TITLE, StrUtil.format(NoticeConstant.CLOSE_ORDER_CONTENT, contractOrderEntity.getSymbol(), contractOrderEntity.getClosingPrice().setScale(2, BigDecimal.ROUND_HALF_UP).toString(), profitOrLoss.setScale(2, BigDecimal.ROUND_HALF_UP).toString(), traderInfoEntity.getNickname()));
                 }
             }
@@ -286,6 +306,11 @@
 
             // 获取平仓张数
             Integer closeCnt = (Integer) redisUtils.get(AppContants.CLOSING_ORDER_PREFIX + holdOrderEntity.getId());
+            // 无法从redis中获取平仓张数,说明来自一键平仓
+            if (closeCnt == null) {
+                closeCnt = holdOrderEntity.getSymbolCntSale();
+                holdOrderEntity.setSymbolCntSale(0);
+            }
 
             MemberSettingEntity memberSettingEntity = memberSettingDao.selectMemberSettingByMemberId(memberEntity.getId());
             // 开多
@@ -511,7 +536,7 @@
                     continue;
                 }
 
-//                holdOrderEntity.setForceClosingPrice(getForceSetPrice(wholePriceData, holdOrderEntity, holdOrderDataModel.getSymbol()));
+                holdOrderEntity.setStopProfitPrice(CalculateUtil.calForcePriceForWhole(memberEntity, holdOrderEntity));
                 contractHoldOrderDao.deleteById(holdOrderDataModel.getId());
 
                 ContractOrderEntity contractOrderEntity = ContractHoldOrderEntityMapper.INSTANCE.holdOrderToOrder(holdOrderEntity);
diff --git a/src/main/java/com/xcong/excoin/modules/documentary/common/NoticeConstant.java b/src/main/java/com/xcong/excoin/modules/documentary/common/NoticeConstant.java
index d2d6206..dd1ab04 100644
--- a/src/main/java/com/xcong/excoin/modules/documentary/common/NoticeConstant.java
+++ b/src/main/java/com/xcong/excoin/modules/documentary/common/NoticeConstant.java
@@ -30,7 +30,8 @@
 
     public static final String BOMB_ORDER_CONTENT = "因市场剧烈波动,您的{}合约已被强制平仓,交易员:{}";
 
-    public static final String RETURN_MONEY_TITLE = "跟单-平仓返佣";
-    public static final String RETURN_MONEY_CONTENT = "跟单平仓成功,收到{}的合约单号:{}的返佣金额:{}";
+    public static final String RETURN_MONEY_TITLE = "跟单-平仓返利";
+    public static final String RETURN_MONEY_CONTENT = "平仓成功,收到的合约{},币种{}的返利金额:{}";
+    public static final String RETURN_MONEY_CONTENT_MAMC = "合约-{},订单{}的带单返利";
 
 }
diff --git a/src/main/java/com/xcong/excoin/modules/documentary/dao/FollowFollowerOrderRelationDao.java b/src/main/java/com/xcong/excoin/modules/documentary/dao/FollowFollowerOrderRelationDao.java
index cbbc8ac..988db4a 100644
--- a/src/main/java/com/xcong/excoin/modules/documentary/dao/FollowFollowerOrderRelationDao.java
+++ b/src/main/java/com/xcong/excoin/modules/documentary/dao/FollowFollowerOrderRelationDao.java
@@ -18,6 +18,7 @@
 	FollowFollowerOrderRelationEntity selectNowOneByorderId(@Param("orderId")Long orderId);
 
 	List<FollowFollowerOrderRelationEntity> selectFollowHoldOrderByTradeOrderNo(@Param("orderNo") String orderNo);
+	List<FollowFollowerOrderRelationEntity> selectFollowOrderByTradeOrderNo(@Param("orderNo") String orderNo);
 
 	BigDecimal selectTraderTotalProfit(@Param("memberId") Long memberId);
 	BigDecimal selectTraderTotalProfitSelf(@Param("memberId") Long memberId);
diff --git a/src/main/java/com/xcong/excoin/modules/documentary/dao/FollowFollowerProfitDao.java b/src/main/java/com/xcong/excoin/modules/documentary/dao/FollowFollowerProfitDao.java
index 928dc29..7d8c972 100644
--- a/src/main/java/com/xcong/excoin/modules/documentary/dao/FollowFollowerProfitDao.java
+++ b/src/main/java/com/xcong/excoin/modules/documentary/dao/FollowFollowerProfitDao.java
@@ -44,5 +44,9 @@
 	BigDecimal selectAllFollowerProfit(@Param("tradeMemberId") Long tradeMemberId);
 	
 	List<FollowFollowerProfitEntity> selectByMemberIdandIsFollow(@Param("id") Long id, @Param("isFollowY") Integer isFollowY);
+
+	BigDecimal selectSumBondAmountBymemberId(@Param("memberId")Long memberId,@Param("tradeId") Long tradeId);
+
+	BigDecimal selectSumRewardAmountByMemberId(@Param("memberId")Long memberId,@Param("tradeId") Long tradeId);
 	
 }
diff --git a/src/main/java/com/xcong/excoin/modules/documentary/dao/FollowTraderProfitDetailDao.java b/src/main/java/com/xcong/excoin/modules/documentary/dao/FollowTraderProfitDetailDao.java
index ab01a2a..6e36e67 100644
--- a/src/main/java/com/xcong/excoin/modules/documentary/dao/FollowTraderProfitDetailDao.java
+++ b/src/main/java/com/xcong/excoin/modules/documentary/dao/FollowTraderProfitDetailDao.java
@@ -1,8 +1,15 @@
 package com.xcong.excoin.modules.documentary.dao;
 
+import java.math.BigDecimal;
+import java.util.List;
+
+import org.apache.ibatis.annotations.Param;
+
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.xcong.excoin.modules.documentary.entity.FollowTraderProfitDetailEntity;
 
 public interface FollowTraderProfitDetailDao extends BaseMapper<FollowTraderProfitDetailEntity> {
 
+	BigDecimal selectFollowHoldOrderByFollowOrderNo(@Param("orderNos")List<String> orderNos);
+
 }
diff --git a/src/main/java/com/xcong/excoin/modules/documentary/service/impl/FollowOrderOperationServiceImpl.java b/src/main/java/com/xcong/excoin/modules/documentary/service/impl/FollowOrderOperationServiceImpl.java
index f51d58b..186bb73 100644
--- a/src/main/java/com/xcong/excoin/modules/documentary/service/impl/FollowOrderOperationServiceImpl.java
+++ b/src/main/java/com/xcong/excoin/modules/documentary/service/impl/FollowOrderOperationServiceImpl.java
@@ -7,9 +7,11 @@
 import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.xcong.excoin.common.enumerates.CoinTypeEnum;
+import com.xcong.excoin.common.enumerates.MemberWalletCoinEnum;
 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.entity.MemberAccountMoneyChange;
 import com.xcong.excoin.modules.contract.dao.ContractHoldOrderDao;
 import com.xcong.excoin.modules.contract.dao.ContractOrderDao;
 import com.xcong.excoin.modules.contract.entity.ContractEntrustOrderEntity;
@@ -18,10 +20,7 @@
 import com.xcong.excoin.modules.contract.mapper.ContractHoldOrderEntityMapper;
 import com.xcong.excoin.modules.contract.service.RabbitOrderService;
 import com.xcong.excoin.modules.documentary.common.NoticeConstant;
-import com.xcong.excoin.modules.documentary.dao.FollowFollowerOrderRelationDao;
-import com.xcong.excoin.modules.documentary.dao.FollowFollowerProfitDao;
-import com.xcong.excoin.modules.documentary.dao.FollowFollowerSettingDao;
-import com.xcong.excoin.modules.documentary.dao.FollowTraderInfoDao;
+import com.xcong.excoin.modules.documentary.dao.*;
 import com.xcong.excoin.modules.documentary.entity.FollowFollowerOrderRelationEntity;
 import com.xcong.excoin.modules.documentary.entity.FollowFollowerProfitEntity;
 import com.xcong.excoin.modules.documentary.entity.FollowFollowerSettingEntity;
@@ -88,6 +87,8 @@
 
     @Autowired
     private FollowProducer followProducer;
+    @Autowired
+    private FollowTraderProfitDetailDao followTraderProfitDetailDao;
 
 
     @Override
@@ -268,6 +269,48 @@
                 ids.add(orderRelation.getOrderId());
                 rabbitOrderService.cancelHoldOrder(ids);
             }
+            //生成返利记录和资金变化记录
+            List<FollowFollowerOrderRelationEntity> orderRelationDone = followFollowerOrderRelationDao.selectFollowOrderByTradeOrderNo(orderNo);
+            if(CollUtil.isNotEmpty(orderRelationDone)) {
+            	List<Long> orderIds = new ArrayList<>();
+            	for (FollowFollowerOrderRelationEntity orderRelationd : orderRelationDone) {
+                    orderIds.add(orderRelationd.getOrderId());
+                }
+            
+	            if(CollUtil.isNotEmpty(orderIds)){
+	                //获取对应的平仓记录单号
+	                List<String> orderNosList = new ArrayList<>();
+	                for(Long orderId : orderIds) {
+	                    String orderNos = contractOrderDao.selectOrderNoByOrderIds(orderId);
+	                    orderNosList.add(orderNos);
+	                }
+	                //获取总返佣
+	                BigDecimal totalAmount = followTraderProfitDetailDao.selectFollowHoldOrderByFollowOrderNo(orderNosList);
+	                totalAmount = (totalAmount == null?BigDecimal.ZERO:totalAmount.setScale(2, BigDecimal.ROUND_DOWN));
+	                if(totalAmount.compareTo(BigDecimal.ZERO) > 0){
+	                    //增加返佣提醒
+	                    String symbol = contractOrderDao.selectById(orderIds.get(0)).getSymbol();
+	                    String orderNoTrader = orderRelationDone.get(0).getTradeOrderNo();
+	                    Long traderMemberId = orderRelationDone.get(0).getTradeMemberId();
+	                    LogRecordUtils.insertFollowerNotice(traderMemberId,
+	                            NoticeConstant.RETURN_MONEY_TITLE,
+	                            StrUtil.format(NoticeConstant.RETURN_MONEY_CONTENT,
+	                                    orderNoTrader,
+	                                    symbol,
+	                                    totalAmount));
+	                    //带单返利的记录要在资产页面的其他记录
+	                    LogRecordUtils.insertMemberAccountMoneyChange(
+	                            traderMemberId,
+	                            StrUtil.format(NoticeConstant.RETURN_MONEY_CONTENT_MAMC,
+                                        symbol,
+                                        orderNoTrader.substring(8)),
+	                            totalAmount,
+	                            MemberWalletCoinEnum.WALLETCOINCODE.getValue(),
+	                            MemberAccountMoneyChange.STATUS_SUCCESS_INTEGER,
+	                            MemberAccountMoneyChange.TYPE_WALLET_AGENT);
+	                }
+	            }
+            }
         }
     }
 }
diff --git a/src/main/java/com/xcong/excoin/quartz/job/FollowProfitUpdateJob.java b/src/main/java/com/xcong/excoin/quartz/job/FollowProfitUpdateJob.java
index 1addfdb..aa2e1cb 100644
--- a/src/main/java/com/xcong/excoin/quartz/job/FollowProfitUpdateJob.java
+++ b/src/main/java/com/xcong/excoin/quartz/job/FollowProfitUpdateJob.java
@@ -7,6 +7,7 @@
 import com.xcong.excoin.modules.documentary.dao.FollowFollowerProfitDao;
 import com.xcong.excoin.modules.documentary.dao.FollowTraderInfoDao;
 import com.xcong.excoin.modules.documentary.dao.FollowTraderProfitInfoDao;
+import com.xcong.excoin.modules.documentary.entity.FollowFollowerProfitEntity;
 import com.xcong.excoin.modules.documentary.entity.FollowTraderInfoEntity;
 import com.xcong.excoin.modules.documentary.entity.FollowTraderProfitInfoEntity;
 import lombok.extern.slf4j.Slf4j;
@@ -17,7 +18,9 @@
 
 import javax.annotation.Resource;
 import java.math.BigDecimal;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 /**
  *
@@ -51,6 +54,27 @@
         if (CollUtil.isNotEmpty(allTraders)) {
             for (FollowTraderInfoEntity trader : allTraders) {
                 Long tradeMemberId = trader.getMemberId();
+                //获取交易员的当前跟随者
+                Map<String, Object> hashMap = new HashMap<>();
+                hashMap.put("trade_member_id", tradeMemberId);
+                hashMap.put("is_follow", FollowFollowerProfitEntity.IS_FOLLOW_Y);
+                List<FollowFollowerProfitEntity> followFollowerProfitEntityList = followFollowerProfitDao.selectByMap(hashMap);
+                if(CollUtil.isNotEmpty(followFollowerProfitEntityList)) {
+                	for(FollowFollowerProfitEntity followFollowerProfitEntity : followFollowerProfitEntityList) {
+                		//获取当前跟随者的跟随本金
+                		Long memberId = followFollowerProfitEntity.getMemberId();
+                		BigDecimal sumBondAmountBigDecimal = followFollowerProfitDao.selectSumBondAmountBymemberId(memberId,trader.getId());
+                		sumBondAmountBigDecimal = (sumBondAmountBigDecimal == null?BigDecimal.ZERO:sumBondAmountBigDecimal.setScale(2, BigDecimal.ROUND_DOWN));
+                		followFollowerProfitEntity.setTotalPrincipal(sumBondAmountBigDecimal);
+                		//获取当前的盈亏
+                		BigDecimal sumRewardAmountBigDecimal = followFollowerProfitDao.selectSumRewardAmountByMemberId(memberId,trader.getId());
+                		sumRewardAmountBigDecimal = (sumRewardAmountBigDecimal == null?BigDecimal.ZERO:sumRewardAmountBigDecimal.setScale(2, BigDecimal.ROUND_DOWN));
+                		followFollowerProfitEntity.setTotalProfit(sumRewardAmountBigDecimal);
+                		followFollowerProfitDao.updateById(followFollowerProfitEntity);
+                	}
+                }
+
+
                 FollowTraderProfitInfoEntity traderInfoProfit = followTraderProfitInfoDao.selectTraderInfoProfitByMemberId(tradeMemberId);
                 // 累计收益率
                 BigDecimal ljsyl = contractOrderDao.selectFollowOrderTotalProfitByMemberId(tradeMemberId);
@@ -61,7 +85,8 @@
                 //BigDecimal totalProfit = followFollowerOrderRelationDao.selectTraderTotalProfit(tradeMemberId);
                 traderInfoProfit.setTotalProfit(totalProfit);
                 // 交易笔数
-                List<ContractOrderEntity> orders = contractOrderDao.selectFollowOrderByMemberId(tradeMemberId);
+//                List<ContractOrderEntity> orders = contractOrderDao.selectFollowOrderByMemberId(tradeMemberId);
+                List<ContractOrderEntity> orders = contractOrderDao.selectFollowOrderListByMemberId(tradeMemberId);
                 traderInfoProfit.setTotalOrderCnt(CollUtil.isNotEmpty(orders) ? orders.size() : 0);
                 // 近三周胜率
                 Integer winCnt = contractOrderDao.selectFollowOrderCntForWinRate(tradeMemberId, 1);
diff --git a/src/main/java/com/xcong/excoin/quartz/job/LoopExecutorJob.java b/src/main/java/com/xcong/excoin/quartz/job/LoopExecutorJob.java
index 9fc7240..6b1981f 100644
--- a/src/main/java/com/xcong/excoin/quartz/job/LoopExecutorJob.java
+++ b/src/main/java/com/xcong/excoin/quartz/job/LoopExecutorJob.java
@@ -47,6 +47,7 @@
      * 持仓费计算
      */
     @Scheduled(cron = "0 0 0/8 * * ?")
+//    @Scheduled(cron = "0 0/5 * * * ?")
     public void updateDoingPrice() {
         log.info("#持仓费计算#");
         try {
diff --git a/src/main/java/com/xcong/excoin/utils/CalculateUtil.java b/src/main/java/com/xcong/excoin/utils/CalculateUtil.java
index 935f1f3..deed491 100644
--- a/src/main/java/com/xcong/excoin/utils/CalculateUtil.java
+++ b/src/main/java/com/xcong/excoin/utils/CalculateUtil.java
@@ -163,6 +163,47 @@
         return result;
     }
 
+    /**
+     * 开仓价 +/- (权益 - 其他币种成本 - 当前币种维持保证金)/(规格*张数)
+     *
+     * @param memberEntity
+     * @param contractHoldOrderEntity
+     * @return
+     */
+    public static BigDecimal calForcePriceForWhole(MemberEntity memberEntity, ContractHoldOrderEntity contractHoldOrderEntity) {
+        ContractHoldOrderDao holdOrderDao = SpringContextHolder.getBean(ContractHoldOrderDao.class);
+        MemberWalletContractDao walletContractDao = SpringContextHolder.getBean(MemberWalletContractDao.class);
+
+        Long memberId = memberEntity.getId();
+        MemberWalletContractEntity walletContract = walletContractDao.findWalletContractByMemberIdAndSymbol(memberId, CoinTypeEnum.USDT.name());
+        List<ContractHoldOrderEntity> holdOrderEntities = holdOrderDao.selectHoldOrderListForWholeByMemberIdAndSymbol(memberId, null);
+        BigDecimal forcePrice = BigDecimal.ZERO;
+        if (CollUtil.isNotEmpty(holdOrderEntities)) {
+            BigDecimal totalBondAmount = BigDecimal.ZERO;
+            BigDecimal totalProfitOrLoss = BigDecimal.ZERO;
+            for (ContractHoldOrderEntity holdOrderEntity : holdOrderEntities) {
+                if (holdOrderEntity.getId().equals(contractHoldOrderEntity.getId())) {
+//                    totalBondAmount = totalBondAmount.add(holdOrderEntity.getHoldBond());
+                } else {
+                    totalBondAmount = totalBondAmount.add(holdOrderEntity.getBondAmount());
+                }
+                totalProfitOrLoss =  totalProfitOrLoss.add(calProfitOrLoss(holdOrderEntity, memberEntity));
+            }
+
+            BigDecimal divideChild = walletContract.getTotalBalance().subtract(totalBondAmount).add(totalProfitOrLoss);
+            BigDecimal divideParent = contractHoldOrderEntity.getSymbolSku().multiply(new BigDecimal(contractHoldOrderEntity.getSymbolCntSale()));
+
+            BigDecimal divide = divideChild.divide(divideParent, 8, BigDecimal.ROUND_DOWN);
+
+            if (ContractHoldOrderEntity.OPENING_TYPE_MORE == contractHoldOrderEntity.getOpeningType()) {
+                forcePrice = contractHoldOrderEntity.getOpeningPrice().subtract(divide);
+            } else {
+                forcePrice = contractHoldOrderEntity.getOpeningPrice().add(divide);
+            }
+        }
+        return forcePrice;
+    }
+
     public static BigDecimal calProfitOrLoss(ContractHoldOrderEntity holdOrderEntity, MemberEntity memberEntity) {
         CacheSettingUtils cacheSettingUtils = SpringContextHolder.getBean(CacheSettingUtils.class);
         RedisUtils redisUtils = SpringContextHolder.getBean(RedisUtils.class);
@@ -286,6 +327,6 @@
             redisUtils.set(AppContants.HOLD_BOND_RATIO, tradeSetting.getHoldBondRatio());
         }
 
-        return contractHoldOrder.getOpeningPrice().multiply(new BigDecimal(contractHoldOrder.getSymbolCntSale())).multiply(holdBondRatio).multiply(contractHoldOrder.getSymbolSku());
+        return contractHoldOrder.getOpeningPrice().multiply(new BigDecimal(contractHoldOrder.getSymbolCntSale())).multiply(holdBondRatio.multiply(new BigDecimal(100))).multiply(contractHoldOrder.getSymbolSku()).divide(new BigDecimal(contractHoldOrder.getLeverRatio()), 8, BigDecimal.ROUND_DOWN);
     }
 }
diff --git a/src/main/resources/mapper/contract/ContractOrderDao.xml b/src/main/resources/mapper/contract/ContractOrderDao.xml
index ff042eb..4e8d023 100644
--- a/src/main/resources/mapper/contract/ContractOrderDao.xml
+++ b/src/main/resources/mapper/contract/ContractOrderDao.xml
@@ -2,6 +2,25 @@
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.xcong.excoin.modules.contract.dao.ContractOrderDao">
 
+    <select id="selectOrderNoByOrderIds" resultType="java.lang.String">
+        SELECT
+            order_no
+        FROM
+            contract_order
+        WHERE
+              id = #{orderId}
+    </select>
+
+    <select id="selectFollowOrderListByMemberId" resultType="com.xcong.excoin.modules.contract.entity.ContractOrderEntity">
+        SELECT
+            *
+        FROM
+            contract_order
+        WHERE
+            member_id = #{tradeMemberId}
+          AND contract_type = 2
+          AND closing_price IS NOT NULL;
+    </select>
 
     <select id="selectContractOrderInPage" resultType="com.xcong.excoin.modules.contract.entity.ContractOrderEntity">
         select
diff --git a/src/main/resources/mapper/documentary/FollowFollowerOrderRelationDao.xml b/src/main/resources/mapper/documentary/FollowFollowerOrderRelationDao.xml
index 374d8e0..72cbfe5 100644
--- a/src/main/resources/mapper/documentary/FollowFollowerOrderRelationDao.xml
+++ b/src/main/resources/mapper/documentary/FollowFollowerOrderRelationDao.xml
@@ -33,6 +33,13 @@
 		and a.order_type=1
 	</select>
 
+	<select id="selectFollowOrderByTradeOrderNo" resultType="com.xcong.excoin.modules.documentary.entity.FollowFollowerOrderRelationEntity">
+		select a.*
+		from follow_follower_order_relation a, follow_follower_profit b
+		where a.trade_member_id=b.trade_member_id and a.trade_order_no=#{orderNo} and b.is_follow=1
+		  and a.order_type=2
+	</select>
+
 	<select id="selectTraderTotalProfit" resultType="java.math.BigDecimal">
 		select sum(b.reward_amount)
 		from follow_follower_order_relation a, contract_order b
diff --git a/src/main/resources/mapper/documentary/FollowFollowerProfitDao.xml b/src/main/resources/mapper/documentary/FollowFollowerProfitDao.xml
index bfca65f..3a2147d 100644
--- a/src/main/resources/mapper/documentary/FollowFollowerProfitDao.xml
+++ b/src/main/resources/mapper/documentary/FollowFollowerProfitDao.xml
@@ -1,7 +1,31 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.xcong.excoin.modules.documentary.dao.FollowFollowerProfitDao">
-	
+
+	<select id="selectSumRewardAmountByMemberId" resultType="java.math.BigDecimal">
+		SELECT
+			SUM(a.reward_amount)
+		FROM
+			contract_order a
+				LEFT JOIN follow_follower_order_relation b ON a.id = b.order_id
+		WHERE
+			a.member_id = #{memberId}
+		  AND b.order_type = 2
+			and b.trade_id = #{tradeId};
+	</select>
+
+	<select id="selectSumBondAmountBymemberId" resultType="java.math.BigDecimal">
+		SELECT
+			SUM(a.bond_amount)
+		FROM
+			contract_order a
+				LEFT JOIN follow_follower_order_relation b ON a.id = b.order_id
+		WHERE
+			a.member_id = #{memberId}
+		  AND b.order_type = 2
+		  and b.trade_id = #{tradeId};
+	</select>
+
 	<select id="selectByMemberIdandIsFollow" resultType="com.xcong.excoin.modules.documentary.entity.FollowFollowerProfitEntity">
 		SELECT
 			*
diff --git a/src/main/resources/mapper/documentary/FollowTraderProfitDetailDao.xml b/src/main/resources/mapper/documentary/FollowTraderProfitDetailDao.xml
index a6e586a..c397480 100644
--- a/src/main/resources/mapper/documentary/FollowTraderProfitDetailDao.xml
+++ b/src/main/resources/mapper/documentary/FollowTraderProfitDetailDao.xml
@@ -1,6 +1,17 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.xcong.excoin.modules.documentary.dao.FollowTraderProfitDetailDao">
-	
+
+    <select id="selectFollowHoldOrderByFollowOrderNo" resultType="java.math.BigDecimal">
+        SELECT
+        sum(amount)
+        FROM
+        follow_trader_profit_detail
+        WHERE
+        order_no in
+        <foreach collection="orderNos" item="item" index="" open="(" separator="," close=")">
+            #{item}
+        </foreach>
+    </select>
     
 </mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/member/MemberAccountMoneyChangeDao.xml b/src/main/resources/mapper/member/MemberAccountMoneyChangeDao.xml
index 90a0164..d3c6b83 100644
--- a/src/main/resources/mapper/member/MemberAccountMoneyChangeDao.xml
+++ b/src/main/resources/mapper/member/MemberAccountMoneyChangeDao.xml
@@ -64,7 +64,7 @@
 		<if test="record != null">
             <where>
             	type = 3
-            	and (content like '%佣金到账%' or content like '%活动%')
+            	and (content like '%佣金到账%' or content like '%活动%' or content like '%返利%')
                 <if test="record.memberId != null" >
                     and member_id=#{record.memberId}
                 </if>
diff --git a/src/test/java/com/xcong/excoin/WholeTest.java b/src/test/java/com/xcong/excoin/WholeTest.java
index 708ff9d..1123b19 100644
--- a/src/test/java/com/xcong/excoin/WholeTest.java
+++ b/src/test/java/com/xcong/excoin/WholeTest.java
@@ -115,8 +115,15 @@
      */
     @Test
     public void forceSetPriceTest() {
-        MemberEntity memberEntity = memberDao.selectById(21L);
-        CalculateUtil.getForceSetPriceForWhole("BTC/USDT", memberEntity);
+        MemberEntity memberEntity = memberDao.selectById(15L);
+        System.out.println(CalculateUtil.getForceSetPriceForWhole("BTC/USDT", memberEntity));
+    }
+
+    @Test
+    public void profitOrLessTest() {
+        MemberEntity memberEntity = memberDao.selectById(15L);
+        ContractHoldOrderEntity contractHoldOrderEntity = contractHoldOrderDao.selectById(144L);
+        System.out.println(CalculateUtil.calProfitOrLoss(contractHoldOrderEntity, memberEntity));
     }
 
     @Resource
@@ -191,4 +198,12 @@
         // 29157.72306836 --
     }
 
+    @Test
+    public void wholeForceNewTest() {
+        MemberEntity memberEntity = memberDao.selectById(15L);
+        ContractHoldOrderEntity holdOrder = contractHoldOrderDao.selectById(400L);
+
+        System.out.println(CalculateUtil.calForcePriceForWhole(memberEntity, holdOrder));
+    }
+
 }

--
Gitblit v1.9.1