From 4b844113469b203adc40f1e540de98612321f26e Mon Sep 17 00:00:00 2001
From: Helius <wangdoubleone@gmail.com>
Date: Mon, 01 Jun 2020 20:49:07 +0800
Subject: [PATCH] finish contrach closing order and fix rabbit some question

---
 src/main/java/com/xcong/excoin/modules/contract/parameter/dto/HoldOrderListDto.java            |   57 +++
 src/main/java/com/xcong/excoin/modules/contract/service/impl/ContractHoldOrderServiceImpl.java |  130 +++++++
 src/main/java/com/xcong/excoin/modules/contract/mapper/ContractHoldOrderEntityMapper.java      |    3 
 src/main/java/com/xcong/excoin/modules/contract/service/RabbitOrderService.java                |   12 
 src/main/java/com/xcong/excoin/modules/contract/controller/ContractEntrustOrderController.java |    4 
 src/main/java/com/xcong/excoin/modules/contract/service/impl/OrderWebsocketServiceImpl.java    |    2 
 src/main/java/com/xcong/excoin/modules/contract/controller/ContractOrderController.java        |   34 +
 src/main/java/com/xcong/excoin/utils/ThreadPoolUtils.java                                      |   35 ++
 src/main/java/com/xcong/excoin/modules/member/entity/MemberEntity.java                         |    4 
 src/main/java/com/xcong/excoin/common/enumerates/OrderClosingTypeEnum.java                     |   55 +++
 src/main/java/com/xcong/excoin/modules/contract/service/impl/RabbitOrderServiceImpl.java       |  149 ++++++++
 src/main/java/com/xcong/excoin/rabbit/producer/OrderProducer.java                              |  205 ++++++-----
 src/main/resources/mapper/contract/ContractHoldOrderDao.xml                                    |   17 
 src/main/java/com/xcong/excoin/modules/contract/entity/ContractOrderEntity.java                |   22 +
 src/main/java/com/xcong/excoin/modules/contract/dao/ContractHoldOrderDao.java                  |   15 
 src/main/java/com/xcong/excoin/rabbit/consumer/WebsocketPriceConsumer.java                     |  219 ++++++------
 src/main/java/com/xcong/excoin/modules/member/entity/AgentReturnEntity.java                    |   15 
 src/main/java/com/xcong/excoin/modules/contract/service/ContractHoldOrderService.java          |    6 
 src/main/java/com/xcong/excoin/modules/contract/parameter/dto/OrderDetailDto.java              |   11 
 src/main/resources/application.yml                                                             |    1 
 20 files changed, 766 insertions(+), 230 deletions(-)

diff --git a/src/main/java/com/xcong/excoin/common/enumerates/OrderClosingTypeEnum.java b/src/main/java/com/xcong/excoin/common/enumerates/OrderClosingTypeEnum.java
new file mode 100644
index 0000000..3d22b26
--- /dev/null
+++ b/src/main/java/com/xcong/excoin/common/enumerates/OrderClosingTypeEnum.java
@@ -0,0 +1,55 @@
+package com.xcong.excoin.common.enumerates;
+
+import lombok.Getter;
+
+/**
+ * 合约历史订单 -- 平仓类型
+ *
+ * @author wzy
+ * @date 2020-06-01
+ **/
+@Getter
+public enum OrderClosingTypeEnum {
+
+    /**
+     * 平多
+     */
+    CLOSE_MORE(2)
+    /**
+     * 平空
+     */
+    , CLOSE_LESS(3)
+    /**
+     * 爆仓平多
+     */
+    , BOMB_CLOSE_MORE(4)
+    /**
+     * 爆仓平空
+     */
+    , BOMB_CLOSE_LESS(5)
+    /**
+     * 止盈平多
+     */
+    , PROFIT_STOP_MORE(6)
+    /**
+     * 止盈平空
+     */
+    , PROFIT_STOP_LESS(7)
+    /**
+     * 止损平多
+     */
+    , LESS_STOP_MORE(8)
+    /**
+     * 止损平空
+     */
+    , LESS_STOP_LESS(9);
+
+    /**
+     * 平仓类型
+     */
+    private final int value;
+
+    private OrderClosingTypeEnum(int value) {
+        this.value = value;
+    }
+}
diff --git a/src/main/java/com/xcong/excoin/modules/contract/controller/ContractEntrustOrderController.java b/src/main/java/com/xcong/excoin/modules/contract/controller/ContractEntrustOrderController.java
index dc7f0c7..f37d8dd 100644
--- a/src/main/java/com/xcong/excoin/modules/contract/controller/ContractEntrustOrderController.java
+++ b/src/main/java/com/xcong/excoin/modules/contract/controller/ContractEntrustOrderController.java
@@ -45,7 +45,9 @@
     }
 
     @ApiOperation(value = "获取当前委托单列表", notes = "获取当前委托单列表")
-    @ApiResponse(code = 0, message = "success", response = ContractEntrustVo.class)
+    @ApiResponses({
+            @ApiResponse(code = 0, message = "success", response = ContractEntrustVo.class)
+    })
     @GetMapping(value = "/findCurrentEntrustOrderList")
     public Result findCurrentEntrustOrderList() {
         return contractEntrustOrderService.findEntrustOrderList();
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 3c9b824..f76e60e 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
@@ -1,10 +1,12 @@
 package com.xcong.excoin.modules.contract.controller;
 
 import com.xcong.excoin.common.response.Result;
+import com.xcong.excoin.modules.contract.parameter.dto.HoldOrderListDto;
 import com.xcong.excoin.modules.contract.parameter.dto.SubmitOrderDto;
 import com.xcong.excoin.modules.contract.service.ContractHoldOrderService;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
+import com.xcong.excoin.modules.contract.service.ContractOrderService;
+import com.xcong.excoin.rabbit.producer.OrderProducer;
+import io.swagger.annotations.*;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.web.bind.annotation.*;
 
@@ -23,49 +25,55 @@
     @Resource
     private ContractHoldOrderService contractHoldOrderService;
 
+    @Resource
+    private ContractOrderService contractOrderService;
+
     @ApiOperation(value = "市价提交合约订单")
     @PostMapping(value = "/submitOrder")
     public Result submitOrder(@RequestBody SubmitOrderDto submitOrderDto) {
         return contractHoldOrderService.submitOrder(submitOrderDto);
     }
 
-    @ApiOperation(value = "查询当前持仓订单列表")
+    @ApiOperation(value = "查询当前持仓订单列表 -- 轮询")
+    @ApiResponses({
+            @ApiResponse(code = 0, message = "success", response = HoldOrderListDto.class)
+    })
     @GetMapping(value = "/findHoldOrderList")
     public Result findHoldOrderList() {
-        return null;
+        return contractHoldOrderService.findHoldOrderList();
     }
 
-    @ApiOperation(value = "根据Id查询订单详情")
-    @GetMapping(value = "/findOrderDetail")
-    public Result findOrderDetail() {
+    @ApiOperation(value = "未完成--根据Id查询订单详情")
+    @GetMapping(value = "/findHoldOrderDetail")
+    public Result findHoldOrderDetail(@ApiParam(name = "id", value = "持仓ID", required = true, example = "1") @RequestParam(value = "id") Long id) {
         return null;
     }
 
     @ApiOperation(value = "根据Id平仓")
     @GetMapping(value = "/closingOrder")
-    public Result closingOrder() {
-        return null;
+    public Result closingOrder(@ApiParam(name = "id", value = "持仓ID", required = true, example = "1") @RequestParam(value = "id") Long id) {
+        return contractHoldOrderService.cancelHoldOrder(id);
     }
 
     @ApiOperation(value = "一键平仓")
     @GetMapping(value = "/oneKeyClosing")
     public Result oneKeyClosing() {
-        return null;
+        return contractHoldOrderService.cancelHoldOrderBatch();
     }
 
     @ApiOperation(value = "设置止盈止损")
-    @PostMapping(value = "/setTargetProfitOrLoss")
+    @PostMapping(value = "/未完成--setTargetProfitOrLoss")
     public Result setTargetProfitOrLoss() {
         return null;
     }
 
-    @ApiOperation(value = "调整保证金")
+    @ApiOperation(value = "未完成--调整保证金")
     @PostMapping(value = "/tuneUpBond")
     public Result tuneUpBond() {
         return null;
     }
 
-    @ApiOperation(value = "分页查询历史订单列表")
+    @ApiOperation(value = "未完成--分页查询历史订单列表")
     @GetMapping(value = "/findHistoryOrderList")
     public Result findHistoryOrderList() {
         return null;
diff --git a/src/main/java/com/xcong/excoin/modules/contract/dao/ContractHoldOrderDao.java b/src/main/java/com/xcong/excoin/modules/contract/dao/ContractHoldOrderDao.java
index 6b1a3c6..adaab0b 100644
--- a/src/main/java/com/xcong/excoin/modules/contract/dao/ContractHoldOrderDao.java
+++ b/src/main/java/com/xcong/excoin/modules/contract/dao/ContractHoldOrderDao.java
@@ -13,22 +13,31 @@
 public interface ContractHoldOrderDao extends BaseMapper<ContractHoldOrderEntity> {
     /**
      * 根据ids更新所有订单的平仓状态
+     *
      * @param list
      * @return
      */
     int updateContractHoldOrderCanNotClosingByIds(@Param("list") List<OrderModel> list, @Param("batchNo") String batchNo);
 
     /**
-     *  根据批次号查询次仓订单
+     * 根据批次号查询次仓订单
+     *
      * @param batchNo
      * @return
      */
-     List<ContractHoldOrderEntity> selectContractHoldOrderByBatchNo(@Param("batchNo") String batchNo);
+    List<ContractHoldOrderEntity> selectContractHoldOrderByBatchNo(@Param("batchNo") String batchNo);
 
     /**
      * 更新该订单为可平仓状态
+     *
      * @param id
      */
-    public void updateOrderIsCanClosingAndBatchNoById(@Param("id")Long id);
+    public void updateOrderIsCanClosingAndBatchNoById(@Param("id") Long id);
+
+    public List<ContractHoldOrderEntity> selectHoldOrderListByMemberId(@Param("memberId") Long memberId);
+
+    public ContractHoldOrderEntity selectHoldOrderByMemberIdAndId(@Param("memberId") Long memberId, @Param("id") Long id);
+
+    public int updateHoldOrderIsCanClosingById(@Param("isCanClosing") int isCanClosing, @Param("id") Long id);
 
 }
diff --git a/src/main/java/com/xcong/excoin/modules/contract/entity/ContractOrderEntity.java b/src/main/java/com/xcong/excoin/modules/contract/entity/ContractOrderEntity.java
index 0236da2..b88928d 100644
--- a/src/main/java/com/xcong/excoin/modules/contract/entity/ContractOrderEntity.java
+++ b/src/main/java/com/xcong/excoin/modules/contract/entity/ContractOrderEntity.java
@@ -33,6 +33,26 @@
      */
     public static final int ORDER_TYPE_CANCEL = -1;
 
+    /**
+     * 订单类型 开多
+     */
+    public static final int ORDER_TYPE_OPEN_MORE = 1;
+
+    /**
+     * 订单类型 开空
+     */
+    public static final int ORDER_TYPE_OPEN_LESS = 2;
+
+    /**
+     * 订单类型 平多
+     */
+    public static final int ORDER_TYPE_CLOSE_MORE = 3;
+
+    /**
+     * 订单类型 平空
+     */
+    public static final int ORDER_TYPE_CLOSE_LESS = 4;
+
 
     /**
      * 会员Id
@@ -55,7 +75,7 @@
     private int tradeType;
 
     /**
-     * 订单类型 - 0撤单,1开多,2开空,3平多,4平空,5委托开多,6委托开空,7委托平多,8委托平空,9爆仓平多,10爆仓平空
+     * 订单类型 - 0撤单,1开多,2开空,3平多,4平空
      */
     private int orderType;
 
diff --git a/src/main/java/com/xcong/excoin/modules/contract/mapper/ContractHoldOrderEntityMapper.java b/src/main/java/com/xcong/excoin/modules/contract/mapper/ContractHoldOrderEntityMapper.java
index fb991c0..cf15e0c 100644
--- a/src/main/java/com/xcong/excoin/modules/contract/mapper/ContractHoldOrderEntityMapper.java
+++ b/src/main/java/com/xcong/excoin/modules/contract/mapper/ContractHoldOrderEntityMapper.java
@@ -2,6 +2,7 @@
 
 import com.xcong.excoin.modules.contract.entity.ContractHoldOrderEntity;
 import com.xcong.excoin.modules.contract.entity.ContractOrderEntity;
+import com.xcong.excoin.modules.contract.parameter.dto.HoldOrderListDto;
 import org.mapstruct.Mapper;
 import org.mapstruct.Mapping;
 import org.mapstruct.factory.Mappers;
@@ -16,4 +17,6 @@
 
     @Mapping(target = "orderType", source = "openingType")
     public abstract ContractOrderEntity holdOrderToOrder(ContractHoldOrderEntity holdOrderEntity);
+
+    public abstract HoldOrderListDto holdOrderToDto(ContractHoldOrderEntity holdOrderEntity);
 }
diff --git a/src/main/java/com/xcong/excoin/modules/contract/parameter/dto/HoldOrderListDto.java b/src/main/java/com/xcong/excoin/modules/contract/parameter/dto/HoldOrderListDto.java
new file mode 100644
index 0000000..1966516
--- /dev/null
+++ b/src/main/java/com/xcong/excoin/modules/contract/parameter/dto/HoldOrderListDto.java
@@ -0,0 +1,57 @@
+package com.xcong.excoin.modules.contract.parameter.dto;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * @author wzy
+ * @date 2020-06-01
+ **/
+@Data
+@ApiModel(value = "HoldOrderListDto", description = "获取当前持仓列表接口返回数据类")
+public class HoldOrderListDto {
+
+    @ApiModelProperty(value = "订单ID", example = "1")
+    private Long id;
+
+    @ApiModelProperty(value = "开仓均价", example = "9000.00")
+    private BigDecimal openingPrice;
+
+    @ApiModelProperty(value = "止损")
+    private BigDecimal stopLossPrice;
+
+    @ApiModelProperty(value = "止盈")
+    private BigDecimal stopProfitPrice;
+
+    @ApiModelProperty(value = "保证金")
+    private BigDecimal bondAmount;
+
+    @ApiModelProperty(value = "强平价")
+    private BigDecimal forceClosingPrice;
+
+    @ApiModelProperty(value = "杠杆倍率")
+    private int leverRatio;
+
+    @ApiModelProperty(value = "订单类型 1-开多 2-开空")
+    private int openingType;
+
+    @ApiModelProperty(value = "币种")
+    private String symbol;
+
+    @ApiModelProperty(value = "张数")
+    private int symbolCnt;
+
+    @ApiModelProperty(value = "回报率")
+    private BigDecimal returnRate;
+
+    @ApiModelProperty(value = "盈亏")
+    private BigDecimal profitOrLoss;
+
+    @ApiModelProperty(value = "可增加的最大保证金")
+    private BigDecimal canAddMaxBond;
+
+}
diff --git a/src/main/java/com/xcong/excoin/modules/contract/parameter/dto/OrderDetailDto.java b/src/main/java/com/xcong/excoin/modules/contract/parameter/dto/OrderDetailDto.java
new file mode 100644
index 0000000..b50d0d3
--- /dev/null
+++ b/src/main/java/com/xcong/excoin/modules/contract/parameter/dto/OrderDetailDto.java
@@ -0,0 +1,11 @@
+package com.xcong.excoin.modules.contract.parameter.dto;
+
+import lombok.Data;
+
+/**
+ * @author wzy
+ * @date 2020-06-01
+ **/
+@Data
+public class OrderDetailDto {
+}
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 f0d32dc..d718ff2 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
@@ -22,4 +22,10 @@
 
     public void updateOrderIsCanClosingAndBatchNoById(Long id);
 
+    public Result findHoldOrderList();
+
+    public Result cancelHoldOrder(Long id);
+
+    public Result cancelHoldOrderBatch();
+
 }
diff --git a/src/main/java/com/xcong/excoin/modules/contract/service/RabbitOrderService.java b/src/main/java/com/xcong/excoin/modules/contract/service/RabbitOrderService.java
new file mode 100644
index 0000000..670735f
--- /dev/null
+++ b/src/main/java/com/xcong/excoin/modules/contract/service/RabbitOrderService.java
@@ -0,0 +1,12 @@
+package com.xcong.excoin.modules.contract.service;
+
+
+import java.util.List;
+
+/**
+ * @author helius
+ */
+public interface RabbitOrderService {
+
+    public void cancelHoldOrder(List<Long> ids);
+}
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 cfa7f95..f911e60 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,5 +1,7 @@
 package com.xcong.excoin.modules.contract.service.impl;
 
+import cn.hutool.core.collection.CollUtil;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.xcong.excoin.common.LoginUserUtils;
 import com.xcong.excoin.common.enumerates.CoinTypeEnum;
@@ -11,25 +13,29 @@
 import com.xcong.excoin.modules.contract.entity.ContractHoldOrderEntity;
 import com.xcong.excoin.modules.contract.entity.ContractOrderEntity;
 import com.xcong.excoin.modules.contract.mapper.ContractHoldOrderEntityMapper;
+import com.xcong.excoin.modules.contract.parameter.dto.HoldOrderListDto;
 import com.xcong.excoin.modules.contract.parameter.dto.SubmitOrderDto;
 import com.xcong.excoin.modules.contract.service.ContractHoldOrderService;
 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.MemberWalletContractEntity;
 import com.xcong.excoin.modules.platform.dao.TradeSettingDao;
 import com.xcong.excoin.modules.platform.entity.PlatformTradeSettingEntity;
-import com.xcong.excoin.utils.CacheSettingUtils;
-import com.xcong.excoin.utils.CalculateUtil;
+import com.xcong.excoin.rabbit.producer.OrderProducer;
+import com.xcong.excoin.utils.*;
 import com.xcong.excoin.rabbit.pricequeue.OrderModel;
-import com.xcong.excoin.utils.CoinTypeConvert;
-import com.xcong.excoin.utils.RedisUtils;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
+import sun.rmi.runtime.Log;
 
 import javax.annotation.Resource;
 import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 /**
  * @author wzy
@@ -56,6 +62,9 @@
 
     @Resource
     private RedisUtils redisUtils;
+
+    @Resource
+    private OrderProducer producer;
 
     @Transactional(rollbackFor = Exception.class)
     @Override
@@ -130,15 +139,18 @@
         holdOrderEntity.setMarkPrice(newPrice);
         holdOrderEntity.setIsCanClosing(ContractHoldOrderEntity.ORDER_CAN_CLOSING_Y);
         holdOrderEntity.setPrePaymentAmount(prePaymentAmount);
-        holdOrderEntity.setBondAmount(bondAmount);
+        holdOrderEntity.setBondAmount(bondAmount.add(openFeePrice));
 
         ContractOrderEntity contractOrderEntity = ContractHoldOrderEntityMapper.INSTANCE.holdOrderToOrder(holdOrderEntity);
 
         contractHoldOrderDao.insert(holdOrderEntity);
         int i = contractOrderDao.insert(contractOrderEntity);
         walletContract.setAvailableBalance(walletContract.getAvailableBalance().subtract(prePaymentAmount));
-        walletContract.setFrozenBalance(walletContract.getFrozenBalance().add(prePaymentAmount));
+        walletContract.setFrozenBalance(walletContract.getFrozenBalance().add(bondAmount.add(openFeePrice)));
         memberWalletContractDao.updateById(walletContract);
+
+        // 计算佣金
+        ThreadPoolUtils.calReturnMoney(memberEntity.getId(), contractOrderEntity.getOpeningFeeAmount(), contractOrderEntity, AgentReturnEntity.ORDER_TYPE_OPEN);
         if (i > 0) {
             return Result.ok("success");
         }
@@ -146,8 +158,8 @@
     }
 
     @Override
-    public int updateContractHoldOrderCanNotClosingByIds(List<OrderModel> list, String batchNo){
-        return contractHoldOrderDao.updateContractHoldOrderCanNotClosingByIds(list,batchNo);
+    public int updateContractHoldOrderCanNotClosingByIds(List<OrderModel> list, String batchNo) {
+        return contractHoldOrderDao.updateContractHoldOrderCanNotClosingByIds(list, batchNo);
     }
 
     @Override
@@ -160,5 +172,107 @@
         contractHoldOrderDao.updateOrderIsCanClosingAndBatchNoById(id);
     }
 
+    @Override
+    public Result findHoldOrderList() {
+        MemberEntity memberEntity = LoginUserUtils.getAppLoginUser();
 
+        List<ContractHoldOrderEntity> list = contractHoldOrderDao.selectHoldOrderListByMemberId(memberEntity.getId());
+        if (CollUtil.isNotEmpty(list)) {
+            BigDecimal totalProfitOrLoss = BigDecimal.ZERO;
+            List<HoldOrderListDto> resultList = new ArrayList<>();
+            for (ContractHoldOrderEntity holdOrderEntity : list) {
+                HoldOrderListDto holdOrderListDto = ContractHoldOrderEntityMapper.INSTANCE.holdOrderToDto(holdOrderEntity);
+                String symbol = holdOrderEntity.getSymbol();
+                // 获取最新价
+                BigDecimal newPrice = new BigDecimal(redisUtils.getString(CoinTypeConvert.convertToKey(symbol)));
+                BigDecimal lotNumber = cacheSettingUtils.getSymbolSku(symbol);
+                // 盈亏
+                BigDecimal rewardRatio = BigDecimal.ZERO;
+                // 开多
+                if (ContractHoldOrderEntity.OPENING_TYPE_MORE == holdOrderEntity.getOpeningType()) {
+                    // (最新价-开仓价)*规格*张数
+                    rewardRatio = newPrice.subtract(holdOrderEntity.getOpeningPrice()).multiply(lotNumber).multiply(new BigDecimal(holdOrderEntity.getSymbolCnt()));
+                    // 开空
+                } else {
+                    // (开仓价-最新价)*规格*张数
+                    rewardRatio = holdOrderEntity.getOpeningPrice().subtract(newPrice).multiply(lotNumber).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()));
+                    } else {
+                        rewardRatio = rewardRatio.multiply(BigDecimal.ONE.add(tradeSettingEntity.getProfitParam()));
+                    }
+                }
+
+                // 回报率
+                BigDecimal returnRate = rewardRatio.divide(holdOrderEntity.getBondAmount().subtract(holdOrderEntity.getOpeningFeeAmount()), 8, BigDecimal.ROUND_DOWN);
+
+                // 成本价格
+                BigDecimal costPrice = holdOrderEntity.getOpeningPrice()
+                        .multiply(lotNumber)
+                        .multiply(new BigDecimal(holdOrderEntity.getSymbolCnt()))
+                        .divide(new BigDecimal(holdOrderEntity.getLeverRatio()), 8, BigDecimal.ROUND_DOWN);
+
+                // 可增加最大保证金
+                BigDecimal canAddMaxBond = holdOrderEntity.getBondAmount().subtract(holdOrderEntity.getOpeningFeeAmount()).subtract(costPrice);
+                if (canAddMaxBond.compareTo(BigDecimal.ZERO) < 0) {
+                    canAddMaxBond = BigDecimal.ZERO;
+                }
+
+                holdOrderListDto.setCanAddMaxBond(canAddMaxBond);
+                holdOrderListDto.setReturnRate(returnRate);
+                holdOrderListDto.setProfitOrLoss(rewardRatio);
+                resultList.add(holdOrderListDto);
+                totalProfitOrLoss = totalProfitOrLoss.add(rewardRatio);
+            }
+
+            Map<String, Object> result = new HashMap<>();
+            result.put("hold", resultList);
+            result.put("totalProfitOrLoss", totalProfitOrLoss);
+            return Result.ok(result);
+        }
+        return Result.ok("success");
+    }
+
+    @Override
+    public Result cancelHoldOrder(Long id) {
+        MemberEntity memberEntity = LoginUserUtils.getAppLoginUser();
+        ContractHoldOrderEntity holdOrderEntity = contractHoldOrderDao.selectHoldOrderByMemberIdAndId(memberEntity.getId(), id);
+        if (holdOrderEntity == null) {
+            return Result.fail("订单不存在");
+        }
+
+        if (ContractHoldOrderEntity.ORDER_CAN_CLOSING_N == holdOrderEntity.getIsCanClosing()) {
+            return Result.fail("订单暂不可平仓");
+        }
+
+        contractHoldOrderDao.updateHoldOrderIsCanClosingById(ContractHoldOrderEntity.ORDER_CAN_CLOSING_N, id);
+        // 发送平仓消息
+        List<Long> ids = new ArrayList<>();
+        ids.add(id);
+        producer.sendCloseTrade(JSONObject.toJSONString(ids));
+
+        return Result.ok("平仓成功");
+    }
+
+    @Override
+    public Result cancelHoldOrderBatch() {
+        MemberEntity memberEntity = LoginUserUtils.getAppLoginUser();
+        List<ContractHoldOrderEntity> holdOrderEntities = contractHoldOrderDao.selectHoldOrderListByMemberId(memberEntity.getId());
+        if (CollUtil.isEmpty(holdOrderEntities)) {
+            return Result.fail("订单不存在");
+        }
+
+        List<Long> ids = new ArrayList<>();
+        for (ContractHoldOrderEntity holdOrderEntity : holdOrderEntities) {
+            contractHoldOrderDao.updateHoldOrderIsCanClosingById(ContractHoldOrderEntity.ORDER_CAN_CLOSING_N, holdOrderEntity.getId());
+            ids.add(holdOrderEntity.getId());
+        }
+        ;
+        producer.sendCloseTrade(JSONObject.toJSONString(ids));
+        return Result.ok("平仓成功");
+    }
 }
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 45eaabf..060d67b 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
@@ -726,7 +726,7 @@
             if (type == 1) {//开仓
                 agent.setOpeningFeeAmount(order.getOpeningFeeAmount());
             } else if (type == 2) {//平仓
-                agent.setClosingFeeAmount(order.getOpeningFeeAmount());
+                agent.setClosingFeeAmount(order.getClosingFeeAmount());
             } else {//持仓费
                 agent.setHoldingFeeAmount(order.getHoldAmount());
             }
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
new file mode 100644
index 0000000..c103753
--- /dev/null
+++ b/src/main/java/com/xcong/excoin/modules/contract/service/impl/RabbitOrderServiceImpl.java
@@ -0,0 +1,149 @@
+package com.xcong.excoin.modules.contract.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import com.xcong.excoin.common.enumerates.CoinTypeEnum;
+import com.xcong.excoin.common.enumerates.OrderClosingTypeEnum;
+import com.xcong.excoin.common.system.service.CommonService;
+import com.xcong.excoin.modules.contract.dao.ContractHoldOrderDao;
+import com.xcong.excoin.modules.contract.dao.ContractOrderDao;
+import com.xcong.excoin.modules.contract.entity.ContractHoldOrderEntity;
+import com.xcong.excoin.modules.contract.entity.ContractOrderEntity;
+import com.xcong.excoin.modules.contract.mapper.ContractHoldOrderEntityMapper;
+import com.xcong.excoin.modules.contract.service.RabbitOrderService;
+import com.xcong.excoin.modules.member.dao.MemberDao;
+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.MemberWalletContractEntity;
+import com.xcong.excoin.modules.platform.entity.PlatformTradeSettingEntity;
+import com.xcong.excoin.utils.CacheSettingUtils;
+import com.xcong.excoin.utils.CoinTypeConvert;
+import com.xcong.excoin.utils.RedisUtils;
+import com.xcong.excoin.utils.ThreadPoolUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @author wzy
+ * @date 2020-06-01
+ **/
+@Slf4j
+@Service
+public class RabbitOrderServiceImpl implements RabbitOrderService {
+
+    @Resource
+    private MemberDao memberDao;
+
+    @Resource
+    private OrderWebsocketServiceImpl orderWebsocketService;
+
+    @Resource
+    private ContractHoldOrderDao contractHoldOrderDao;
+
+    @Resource
+    private ContractOrderDao contractOrderDao;
+
+    @Resource
+    private CommonService commonService;
+
+    @Resource
+    private MemberWalletContractDao memberWalletContractDao;
+
+    @Resource
+    private CacheSettingUtils cacheSettingUtils;
+
+    @Resource
+    private RedisUtils redisUtils;
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void cancelHoldOrder(List<Long> ids) {
+        if (CollUtil.isNotEmpty(ids)) {
+            if (ids.size() == 1) {
+                ContractHoldOrderEntity holdOrderEntity = contractHoldOrderDao.selectById(ids.get(0));
+                cancelHoldOrderMethod(holdOrderEntity);
+            } else {
+                List<ContractHoldOrderEntity> holdOrderEntities = contractHoldOrderDao.selectBatchIds(ids);
+                if (CollUtil.isNotEmpty(holdOrderEntities)) {
+                    for (ContractHoldOrderEntity holdOrder : holdOrderEntities) {
+                        cancelHoldOrderMethod(holdOrder);
+                    }
+                }
+            }
+        }
+    }
+
+    public void cancelHoldOrderMethod(ContractHoldOrderEntity holdOrderEntity) {
+        String symbol = holdOrderEntity.getSymbol();
+        // 获取最新价
+        BigDecimal newPrice = new BigDecimal(redisUtils.getString(CoinTypeConvert.convertToKey(symbol)));
+
+        MemberEntity memberEntity = memberDao.selectById(holdOrderEntity.getMemberId());
+
+        MemberWalletContractEntity walletContract = memberWalletContractDao.findWalletContractByMemberIdAndSymbol(holdOrderEntity.getMemberId(), CoinTypeEnum.USDT.name());
+        if (walletContract != null) {
+            // 删除持仓表订单
+            contractHoldOrderDao.deleteById(holdOrderEntity.getId());
+
+            BigDecimal lotNumber = cacheSettingUtils.getSymbolSku(symbol);
+            // 盈亏
+            BigDecimal profitOrLoss = BigDecimal.ZERO;
+            Integer orderType = null;
+            Integer closingType = null;
+            // 开多
+            if (ContractHoldOrderEntity.OPENING_TYPE_MORE == holdOrderEntity.getOpeningType()) {
+                // (最新价-开仓价)*规格*张数
+                profitOrLoss = newPrice.subtract(holdOrderEntity.getOpeningPrice()).multiply(lotNumber).multiply(new BigDecimal(holdOrderEntity.getSymbolCnt()));
+                orderType = ContractOrderEntity.ORDER_TYPE_CLOSE_MORE;
+                closingType = OrderClosingTypeEnum.CLOSE_MORE.getValue();
+                // 开空
+            } else {
+                // (开仓价-最新价)*规格*张数
+                profitOrLoss = holdOrderEntity.getOpeningPrice().subtract(newPrice).multiply(lotNumber).multiply(new BigDecimal(holdOrderEntity.getSymbolCnt()));
+                orderType = ContractOrderEntity.ORDER_TYPE_CLOSE_LESS;
+                closingType = OrderClosingTypeEnum.CLOSE_LESS.getValue();
+            }
+
+            if (memberEntity.getIsProfit() == MemberEntity.IS_PROFIT_Y) {
+                PlatformTradeSettingEntity tradeSettingEntity = cacheSettingUtils.getTradeSetting();
+                if (profitOrLoss.compareTo(BigDecimal.ZERO) > -1) {
+                    profitOrLoss = profitOrLoss.multiply(BigDecimal.ONE.subtract(tradeSettingEntity.getProfitParam()));
+                } else {
+                    profitOrLoss = profitOrLoss.multiply(BigDecimal.ONE.add(tradeSettingEntity.getProfitParam()));
+                }
+            }
+
+            // 盈亏比例(回报率)
+            BigDecimal rewardRatio = profitOrLoss.divide(holdOrderEntity.getBondAmount().subtract(holdOrderEntity.getOpeningFeeAmount()), 8, BigDecimal.ROUND_DOWN);
+
+            ContractOrderEntity contractOrderEntity = ContractHoldOrderEntityMapper.INSTANCE.holdOrderToOrder(holdOrderEntity);
+            contractOrderEntity.setId(null);
+            contractOrderEntity.setOrderType(orderType);
+            contractOrderEntity.setClosingPrice(newPrice);
+            contractOrderEntity.setClosingFeeAmount(holdOrderEntity.getOpeningFeeAmount());
+            contractOrderEntity.setClosingTime(new Date());
+            contractOrderEntity.setClosingType(closingType);
+            contractOrderEntity.setRewardAmount(profitOrLoss);
+            contractOrderEntity.setRewardRatio(rewardRatio);
+            contractOrderDao.insert(contractOrderEntity);
+
+            // 计算盈利或亏损后可用金额和总金额应该增加或减少的
+            BigDecimal addMoney = holdOrderEntity.getBondAmount().subtract(holdOrderEntity.getOpeningPrice()).add(profitOrLoss);
+            log.info("平仓增加金额:{}", addMoney);
+
+            walletContract.setFrozenBalance(walletContract.getFrozenBalance().subtract(holdOrderEntity.getBondAmount()));
+            walletContract.setAvailableBalance(walletContract.getAvailableBalance().add(addMoney));
+            walletContract.setTotalBalance(walletContract.getTotalBalance().add(addMoney));
+
+            // 计算佣金
+            ThreadPoolUtils.calReturnMoney(memberEntity.getId(), contractOrderEntity.getClosingFeeAmount(), contractOrderEntity, AgentReturnEntity.ORDER_TYPE_CLOSE);
+        }
+
+    }
+}
diff --git a/src/main/java/com/xcong/excoin/modules/member/entity/AgentReturnEntity.java b/src/main/java/com/xcong/excoin/modules/member/entity/AgentReturnEntity.java
index a3f6b84..468a910 100644
--- a/src/main/java/com/xcong/excoin/modules/member/entity/AgentReturnEntity.java
+++ b/src/main/java/com/xcong/excoin/modules/member/entity/AgentReturnEntity.java
@@ -14,6 +14,21 @@
 @TableName("agent_return")
 public class AgentReturnEntity extends BaseEntity {
 
+    /**
+     * 订单类型 开仓
+     */
+    public static final int ORDER_TYPE_OPEN = 1;
+
+    /**
+     * 订单类型 平仓
+     */
+    public static final int ORDER_TYPE_CLOSE = 2;
+
+    /**
+     * 订单类型 持仓
+     */
+    public static final int ORDER_TYPE_HOLD = 3;
+
     private Long memberId;
 
     private Long orderId;
diff --git a/src/main/java/com/xcong/excoin/modules/member/entity/MemberEntity.java b/src/main/java/com/xcong/excoin/modules/member/entity/MemberEntity.java
index fa286bc..cec1162 100644
--- a/src/main/java/com/xcong/excoin/modules/member/entity/MemberEntity.java
+++ b/src/main/java/com/xcong/excoin/modules/member/entity/MemberEntity.java
@@ -54,6 +54,10 @@
      */
     public static final Integer CERTIFY_STATUS_ING = 2;
 
+    public static final int IS_PROFIT_Y = 1;
+
+    public static final int IS_PROFIT_N = 0;
+
     /**
      * 手机号(包含国际手机号)
      */
diff --git a/src/main/java/com/xcong/excoin/rabbit/consumer/WebsocketPriceConsumer.java b/src/main/java/com/xcong/excoin/rabbit/consumer/WebsocketPriceConsumer.java
index d7f8234..8368c52 100644
--- a/src/main/java/com/xcong/excoin/rabbit/consumer/WebsocketPriceConsumer.java
+++ b/src/main/java/com/xcong/excoin/rabbit/consumer/WebsocketPriceConsumer.java
@@ -3,133 +3,146 @@
 import com.alibaba.fastjson.JSONArray;
 import com.rabbitmq.client.Channel;
 import com.xcong.excoin.configurations.RabbitMqConfig;
+import com.xcong.excoin.modules.contract.service.RabbitOrderService;
+import com.xcong.excoin.modules.contract.service.impl.OrderWebsocketServiceImpl;
 import com.xcong.excoin.rabbit.pricequeue.OrderModel;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.amqp.core.Message;
 import org.springframework.amqp.rabbit.annotation.RabbitListener;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
 import org.springframework.stereotype.Component;
 
+import javax.annotation.Resource;
 import java.util.List;
 
 
 /**
- *  APP和后台打包都开启
+ * APP和后台打包都开启
  *
+ * @author helius
  */
+@Slf4j
 @Component
-@ConditionalOnProperty(name="useRabbit",havingValue="true")
+@ConditionalOnProperty(prefix = "app", name = "rabbit-consumer", havingValue = "true")
 public class WebsocketPriceConsumer {
 
-	//@Autowired
-	//OrderWebsocketService orderWebsocketService;
+    @Resource
+    OrderWebsocketServiceImpl orderWebsocketService;
 
-	//@Autowired
-	//OrderService orderService;
+    @Resource
+    RabbitOrderService orderService;
 
 
-	/**
-	 * 开多止盈
-	 * @param message 消息体
-	 * @param channel 信道
-	 */
-	@RabbitListener(queues = RabbitMqConfig.QUEUE_MOREPRO)
-	public void onMessageMorePro(Message message, Channel channel) {
-     String content = new String(message.getBody());
-		System.out.println("我收到消息了开多止盈:"+content);
-		List<OrderModel> list = JSONArray.parseArray(content,OrderModel.class);
-		// 开始处理  TODO
-		//orderWebsocketService.dealOrderFromMq(list,9);
-	}
-	// 1:买入委托2:开多3:开空4:平多5:平空6:爆仓平多7:爆仓平空8:撤单9:止盈平多10:止盈平空11:止损平多12:止损平空
+    /**
+     * 开多止盈
+     *
+     * @param message 消息体
+     * @param channel 信道
+     */
+    @RabbitListener(queues = RabbitMqConfig.QUEUE_MOREPRO)
+    public void onMessageMorePro(Message message, Channel channel) {
+        String content = new String(message.getBody());
+        System.out.println("我收到消息了开多止盈:" + content);
+        List<OrderModel> list = JSONArray.parseArray(content, OrderModel.class);
+        // 开始处理  TODO
+        //orderWebsocketService.dealOrderFromMq(list,9);
+    }
+    // 1:买入委托2:开多3:开空4:平多5:平空6:爆仓平多7:爆仓平空8:撤单9:止盈平多10:止盈平空11:止损平多12:止损平空
 
-	/**
-	 * 开空止盈
-	 * @param message
-	 * @param channel
-	 */
-	@RabbitListener(queues = RabbitMqConfig.QUEUE_LESSPRO)
-	public void onMessageLessPro(Message message, Channel channel) {
-     String content = new String(message.getBody());
-		System.out.println("我收到消息了开空止盈:"+content);
-		// 开始处理
-		List<OrderModel> list = JSONArray.parseArray(content,OrderModel.class);
-		// 开始处理
-		//orderWebsocketService.dealOrderFromMq(list,10);
-	}
+    /**
+     * 开空止盈
+     *
+     * @param message
+     * @param channel
+     */
+    @RabbitListener(queues = RabbitMqConfig.QUEUE_LESSPRO)
+    public void onMessageLessPro(Message message, Channel channel) {
+        String content = new String(message.getBody());
+        System.out.println("我收到消息了开空止盈:" + content);
+        // 开始处理
+        List<OrderModel> list = JSONArray.parseArray(content, OrderModel.class);
+        // 开始处理
+        //orderWebsocketService.dealOrderFromMq(list,10);
+    }
 
 
-	/**
-	 * 开多止损
-	 * @param message
-	 * @param channel
-	 */
-	@RabbitListener(queues = RabbitMqConfig.QUEUE_MORELOSS)
-	public void onMessageMoreLoss(Message message, Channel channel) {
-     String content = new String(message.getBody());
-		System.out.println("我收到消息了开多止损:"+content);
-		// 开始处理
-		List<OrderModel> list = JSONArray.parseArray(content,OrderModel.class);
-		// 开始处理
-		//orderWebsocketService.dealOrderFromMq(list,11);
-	}
+    /**
+     * 开多止损
+     *
+     * @param message
+     * @param channel
+     */
+    @RabbitListener(queues = RabbitMqConfig.QUEUE_MORELOSS)
+    public void onMessageMoreLoss(Message message, Channel channel) {
+        String content = new String(message.getBody());
+        System.out.println("我收到消息了开多止损:" + content);
+        // 开始处理
+        List<OrderModel> list = JSONArray.parseArray(content, OrderModel.class);
+        // 开始处理
+        //orderWebsocketService.dealOrderFromMq(list,11);
+    }
 
-	/**
-	 * 开空止损
-	 * @param message
-	 * @param channel
-	 */
-	@RabbitListener(queues = RabbitMqConfig.QUEUE_LESSLOSS)
-	public void onMessageLessLoss(Message message, Channel channel) {
-     String content = new String(message.getBody());
-		System.out.println("我收到消息了开空止损:"+content);
-		// 开始处理
-		List<OrderModel> list = JSONArray.parseArray(content,OrderModel.class);
-		// 开始处理
-		//orderWebsocketService.dealOrderFromMq(list,12);
-	}
+    /**
+     * 开空止损
+     *
+     * @param message
+     * @param channel
+     */
+    @RabbitListener(queues = RabbitMqConfig.QUEUE_LESSLOSS)
+    public void onMessageLessLoss(Message message, Channel channel) {
+        String content = new String(message.getBody());
+        System.out.println("我收到消息了开空止损:" + content);
+        // 开始处理
+        List<OrderModel> list = JSONArray.parseArray(content, OrderModel.class);
+        // 开始处理
+        //orderWebsocketService.dealOrderFromMq(list,12);
+    }
 
-	/**
-	 * 限价委托
-	 * @param message
-	 * @param channel
-	 */
-	@RabbitListener(queues = RabbitMqConfig.QUEUE_LIMIT)
-	public void onMessageLimit(Message message, Channel channel) {
-     String content = new String(message.getBody());
-		System.out.println("我收到消息了限价委托:"+content);
-		// 开始处理
-		List<OrderModel> list = JSONArray.parseArray(content,OrderModel.class);
-		// 开始处理
-		//orderWebsocketService.dealForLimitMq(list);
-	}
+    /**
+     * 限价委托
+     *
+     * @param message
+     * @param channel
+     */
+    @RabbitListener(queues = RabbitMqConfig.QUEUE_LIMIT)
+    public void onMessageLimit(Message message, Channel channel) {
+        String content = new String(message.getBody());
+        System.out.println("我收到消息了限价委托:" + content);
+        // 开始处理
+        List<OrderModel> list = JSONArray.parseArray(content, OrderModel.class);
+        // 开始处理
+        //orderWebsocketService.dealForLimitMq(list);
+    }
 
-	/**
-	 * 爆仓消费者
-	 * @param message
-	 * @param channel
-	 */
-	@RabbitListener(queues = RabbitMqConfig.QUEUE_COINOUT)
-	public void onMessageCoinout(Message message, Channel channel) {
-     String content = new String(message.getBody());
-		System.out.println("我收到消息了爆仓:"+content);
-		// 开始处理
-		List<OrderModel> list = JSONArray.parseArray(content,OrderModel.class);
-		// 开始处理
-		//orderWebsocketService.dealOrderFromMq(list,6);
-	}
+    /**
+     * 爆仓消费者
+     *
+     * @param message
+     * @param channel
+     */
+    @RabbitListener(queues = RabbitMqConfig.QUEUE_COINOUT)
+    public void onMessageCoinout(Message message, Channel channel) {
+        String content = new String(message.getBody());
+        System.out.println("我收到消息了爆仓:" + content);
+        // 开始处理
+        List<OrderModel> list = JSONArray.parseArray(content, OrderModel.class);
+        // 开始处理
+        //orderWebsocketService.dealOrderFromMq(list,6);
+    }
 
-	/**
-	 * 平仓
-	 * @param message
-	 * @param channel
-	 */
-	@RabbitListener(queues = RabbitMqConfig.QUEUE_CLOSETRADE)
-	public void onMessageCloseTrade(Message message, Channel channel) {
-     String content = new String(message.getBody());
-		System.out.println("我收到消息了平仓:"+content);
-		// 订单
-		List<Long> ids = JSONArray.parseArray(content, Long.class);
-		//orderService.closeTradeForMq(ids);
-	}
+    /**
+     * 平仓
+     *
+     * @param message
+     * @param channel
+     */
+    @RabbitListener(queues = RabbitMqConfig.QUEUE_CLOSETRADE)
+    public void onMessageCloseTrade(Message message, Channel channel) {
+        String content = new String(message.getBody());
+        log.info("我收到消息了平仓: {}", content);
+        // 订单
+        List<Long> ids = JSONArray.parseArray(content, Long.class);
+        orderService.cancelHoldOrder(ids);
+    }
 }
diff --git a/src/main/java/com/xcong/excoin/rabbit/producer/OrderProducer.java b/src/main/java/com/xcong/excoin/rabbit/producer/OrderProducer.java
index 29b946e..66986be 100644
--- a/src/main/java/com/xcong/excoin/rabbit/producer/OrderProducer.java
+++ b/src/main/java/com/xcong/excoin/rabbit/producer/OrderProducer.java
@@ -1,6 +1,7 @@
 package com.xcong.excoin.rabbit.producer;
 
 import com.xcong.excoin.configurations.RabbitMqConfig;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.amqp.rabbit.connection.CorrelationData;
 import org.springframework.amqp.rabbit.core.RabbitTemplate;
 import org.springframework.amqp.rabbit.core.RabbitTemplate.ConfirmCallback;
@@ -13,120 +14,128 @@
 /**
  * rabbitMq示例生产者
  */
+@Slf4j
 @Component
 public class OrderProducer implements ConfirmCallback {
 
-	/**
-	 * 配置中配置的RabbitTemplate的是prototype类型,不能直接注入
-	 */
-	private RabbitTemplate rabbitTemplate;
+    /**
+     * 配置中配置的RabbitTemplate的是prototype类型,不能直接注入
+     */
+    private RabbitTemplate rabbitTemplate;
 
-	/**
-	 * 在构造方法上注入RabbitTemplate
-	 *
-	 * @param
-	 */
-	@Autowired
-	public OrderProducer(RabbitTemplate rabbitTemplate) {
-		this.rabbitTemplate = rabbitTemplate;
-		rabbitTemplate.setConfirmCallback(this);
-	}
+    /**
+     * 在构造方法上注入RabbitTemplate
+     *
+     * @param
+     */
+    @Autowired
+    public OrderProducer(RabbitTemplate rabbitTemplate) {
+        this.rabbitTemplate = rabbitTemplate;
+        rabbitTemplate.setConfirmCallback(this);
+    }
 
-	/**
-	 * P发送消息方法 开多止盈
-	 */
-	public void sendMorePro(String content) {
-		CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
-		System.out.println("发送开多止盈:"+content+"==pid:"+correlationData.getId());
+    /**
+     * P发送消息方法 开多止盈
+     */
+    public void sendMorePro(String content) {
+        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
+        System.out.println("发送开多止盈:" + content + "==pid:" + correlationData.getId());
 
-		rabbitTemplate.convertAndSend(RabbitMqConfig.EXCHANGE_A, RabbitMqConfig.ROUTINGKEY_MOREPRO, content, correlationData);
-	}
+        rabbitTemplate.convertAndSend(RabbitMqConfig.EXCHANGE_A, RabbitMqConfig.ROUTINGKEY_MOREPRO, content, correlationData);
+    }
 
-	/**
-	 * 开空止盈
-	 * @param content
-	 */
-	public void sendLessPro(String content) {
-		CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
-		System.out.println("发送开空止盈:"+content+"==pid:"+correlationData.getId());
-		rabbitTemplate.convertAndSend(RabbitMqConfig.EXCHANGE_A, RabbitMqConfig.ROUTINGKEY_LESSPRO, content, correlationData);
-	}
+    /**
+     * 开空止盈
+     *
+     * @param content
+     */
+    public void sendLessPro(String content) {
+        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
+        System.out.println("发送开空止盈:" + content + "==pid:" + correlationData.getId());
+        rabbitTemplate.convertAndSend(RabbitMqConfig.EXCHANGE_A, RabbitMqConfig.ROUTINGKEY_LESSPRO, content, correlationData);
+    }
 
-	/**
-	 * 开多止损
-	 * @param content
-	 */
-	public void sendMoreLoss(String content) {
-		CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
-		System.out.println("发送开多止损:"+content+"==pid:"+correlationData.getId());
-		rabbitTemplate.convertAndSend(RabbitMqConfig.EXCHANGE_A, RabbitMqConfig.ROUTINGKEY_MORELOSS, content, correlationData);
-	}
+    /**
+     * 开多止损
+     *
+     * @param content
+     */
+    public void sendMoreLoss(String content) {
+        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
+        System.out.println("发送开多止损:" + content + "==pid:" + correlationData.getId());
+        rabbitTemplate.convertAndSend(RabbitMqConfig.EXCHANGE_A, RabbitMqConfig.ROUTINGKEY_MORELOSS, content, correlationData);
+    }
 
-	/**
-	 * 开空止损
-	 * @param content
-	 */
-	public void sendLessLoss(String content) {
-		CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
-		System.out.println("发送开空止损:"+content+"==pid:"+correlationData.getId());
-		rabbitTemplate.convertAndSend(RabbitMqConfig.EXCHANGE_A, RabbitMqConfig.ROUTINGKEY_LESSLOSS, content, correlationData);
-	}
+    /**
+     * 开空止损
+     *
+     * @param content
+     */
+    public void sendLessLoss(String content) {
+        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
+        System.out.println("发送开空止损:" + content + "==pid:" + correlationData.getId());
+        rabbitTemplate.convertAndSend(RabbitMqConfig.EXCHANGE_A, RabbitMqConfig.ROUTINGKEY_LESSLOSS, content, correlationData);
+    }
 
-	/**
-	 * 发送委托交易消息
-	 * @param content
-	 */
-	public void sendLimit(String content){
-		CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
-		System.out.println("发送限价委托:"+content+"==pid:"+correlationData.getId());
-		rabbitTemplate.convertAndSend(RabbitMqConfig.EXCHANGE_A, RabbitMqConfig.ROUTINGKEY_LIMIT, content, correlationData);
-	}
+    /**
+     * 发送委托交易消息
+     *
+     * @param content
+     */
+    public void sendLimit(String content) {
+        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
+        System.out.println("发送限价委托:" + content + "==pid:" + correlationData.getId());
+        rabbitTemplate.convertAndSend(RabbitMqConfig.EXCHANGE_A, RabbitMqConfig.ROUTINGKEY_LIMIT, content, correlationData);
+    }
 
-	/**
-	 * 发送爆仓消息
-	 * @param content
-	 */
-	public void sendCoinout(String content){
-		CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
-		System.out.println("发送爆仓:"+content+"==pid:"+correlationData.getId());
-		rabbitTemplate.convertAndSend(RabbitMqConfig.EXCHANGE_A, RabbitMqConfig.ROUTINGKEY_COINOUT, content, correlationData);
-	}
+    /**
+     * 发送爆仓消息
+     *
+     * @param content
+     */
+    public void sendCoinout(String content) {
+        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
+        System.out.println("发送爆仓:" + content + "==pid:" + correlationData.getId());
+        rabbitTemplate.convertAndSend(RabbitMqConfig.EXCHANGE_A, RabbitMqConfig.ROUTINGKEY_COINOUT, content, correlationData);
+    }
 
 
-	/**
-	 * 发送价格操作消息
-	 * @param content
-	 */
-	public void sendPriceOperate(String content){
-		CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
-		System.out.println("发送价格操作:"+content+"==pid:"+correlationData.getId());
-		rabbitTemplate.convertAndSend(RabbitMqConfig.EXCHANGE_A, RabbitMqConfig.ROUTINGKEY_PRICEOPERATE, content, correlationData);
-	}
+    /**
+     * 发送价格操作消息
+     *
+     * @param content
+     */
+    public void sendPriceOperate(String content) {
+        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
+        System.out.println("发送价格操作:" + content + "==pid:" + correlationData.getId());
+        rabbitTemplate.convertAndSend(RabbitMqConfig.EXCHANGE_A, RabbitMqConfig.ROUTINGKEY_PRICEOPERATE, content, correlationData);
+    }
 
-	/**
-	 * 发送平仓
-	 * @param content
-	 */
-	public void sendCloseTrade(String content){
-		CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
-		System.out.println("发送平仓消息:"+content+"==pid:"+correlationData.getId());
-		rabbitTemplate.convertAndSend(RabbitMqConfig.EXCHANGE_A, RabbitMqConfig.ROUTINGKEY_CLOSETRADE, content, correlationData);
-	}
+    /**
+     * 发送平仓
+     *
+     * @param content
+     */
+    public void sendCloseTrade(String content) {
+        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
+        log.info("发送平仓消息:{}==pid : {}", content, correlationData.getId());
+        rabbitTemplate.convertAndSend(RabbitMqConfig.EXCHANGE_A, RabbitMqConfig.ROUTINGKEY_CLOSETRADE, content, correlationData);
+    }
 
 
-	/**
-	 * 用于确认消息是否成功发送到队列
-	 */
-	@Override
-	public void confirm(CorrelationData correlationData, boolean ack, String cause) {
-		if (ack) {
-			//System.out.println("消息发送成功"+correlationData.getId());
-			//LogUtil.info("消息发送成功,correlationId={}", correlationData.getId());
-		} else {
-			System.out.println("消息发送失败"+correlationData.getId());
-			//LogUtil.info("消息发送失败,correlationId={}", correlationData.getId());
-		}
-	}
+    /**
+     * 用于确认消息是否成功发送到队列
+     */
+    @Override
+    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
+        if (ack) {
+            //System.out.println("消息发送成功"+correlationData.getId());
+            //LogUtil.info("消息发送成功,correlationId={}", correlationData.getId());
+        } else {
+            System.out.println("消息发送失败" + correlationData.getId());
+            //LogUtil.info("消息发送失败,correlationId={}", correlationData.getId());
+        }
+    }
 
 
 }
diff --git a/src/main/java/com/xcong/excoin/utils/ThreadPoolUtils.java b/src/main/java/com/xcong/excoin/utils/ThreadPoolUtils.java
new file mode 100644
index 0000000..78727ff
--- /dev/null
+++ b/src/main/java/com/xcong/excoin/utils/ThreadPoolUtils.java
@@ -0,0 +1,35 @@
+package com.xcong.excoin.utils;
+
+import com.xcong.excoin.modules.contract.entity.ContractOrderEntity;
+import com.xcong.excoin.modules.contract.service.impl.OrderWebsocketServiceImpl;
+
+import java.math.BigDecimal;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+/**
+ * @author wzy
+ * @date 2020-06-01
+ **/
+public class ThreadPoolUtils {
+
+    public static final ExecutorService EXECUTOR = Executors.newFixedThreadPool(20);
+
+    /**
+     * 计算佣金
+     *
+     * @param id     用户ID
+     * @param price  手续费
+     * @param entity 订单实体
+     * @param type   订单类型
+     */
+    public static void calReturnMoney(Long id, BigDecimal price, ContractOrderEntity entity, int type) {
+        OrderWebsocketServiceImpl orderWebsocketService = SpringContextHolder.getBean(OrderWebsocketServiceImpl.class);
+        EXECUTOR.execute(new Runnable() {
+            @Override
+            public void run() {
+                orderWebsocketService.calYj(id, price, entity, type);
+            }
+        });
+    }
+}
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index 49a7449..130b2ba 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -99,6 +99,7 @@
   newest-price-update-job: false
   #其他任务控制
   other-job: false
+  rabbit-consumer: true
 
 aliyun:
   oss:
diff --git a/src/main/resources/mapper/contract/ContractHoldOrderDao.xml b/src/main/resources/mapper/contract/ContractHoldOrderDao.xml
index 7114022..ae43110 100644
--- a/src/main/resources/mapper/contract/ContractHoldOrderDao.xml
+++ b/src/main/resources/mapper/contract/ContractHoldOrderDao.xml
@@ -2,14 +2,14 @@
 <!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.ContractHoldOrderDao">
 
-    <select id="updateContractHoldOrderCanNotClosingByIds" parameterType="map" resultType="int">
+    <update id="updateContractHoldOrderCanNotClosingByIds" parameterType="map">
         UPDATE contract_hold_order set is_can_closing = 0,batch_no=#{batchNo}
         where is_can_closing=1
         and id in
         <foreach collection="list" close=")" item="item" open="(" separator=",">
             #{item.orderId}
         </foreach>
-    </select>
+    </update>
 
     <select id="selectContractHoldOrderByBatchNo" parameterType="string" resultType="com.xcong.excoin.modules.contract.entity.ContractHoldOrderEntity">
         select * from contract_hold_order where batch_no=#{batchNo}
@@ -19,4 +19,17 @@
         update contract_hold_order set is_can_closing  = 1 ,batch_no=null
         where id=#{id}
     </update>
+
+    <select id="selectHoldOrderListByMemberId" resultType="com.xcong.excoin.modules.contract.entity.ContractHoldOrderEntity">
+        select * from contract_hold_order where member_id=#{memberId} and is_can_closing=1 order by create_time desc
+    </select>
+
+    <select id="selectHoldOrderByMemberIdAndId" resultType="com.xcong.excoin.modules.contract.entity.ContractHoldOrderEntity">
+        select * from contract_hold_order where member_id=#{memberId} and id=#{id}
+    </select>
+
+    <update id="updateHoldOrderIsCanClosingById">
+        update contract_hold_order set is_can_closing=#{isCanClosing}
+        where id=#{id}
+    </update>
 </mapper>
\ No newline at end of file

--
Gitblit v1.9.1