Helius
2020-06-01 4b844113469b203adc40f1e540de98612321f26e
finish contrach closing order and fix rabbit some question
6 files added
14 files modified
996 ■■■■ changed files
src/main/java/com/xcong/excoin/common/enumerates/OrderClosingTypeEnum.java 55 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/contract/controller/ContractEntrustOrderController.java 4 ●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/contract/controller/ContractOrderController.java 34 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/contract/dao/ContractHoldOrderDao.java 15 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/contract/entity/ContractOrderEntity.java 22 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/contract/mapper/ContractHoldOrderEntityMapper.java 3 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/contract/parameter/dto/HoldOrderListDto.java 57 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/contract/parameter/dto/OrderDetailDto.java 11 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/contract/service/ContractHoldOrderService.java 6 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/contract/service/RabbitOrderService.java 12 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/contract/service/impl/ContractHoldOrderServiceImpl.java 130 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/contract/service/impl/OrderWebsocketServiceImpl.java 2 ●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/contract/service/impl/RabbitOrderServiceImpl.java 149 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/member/entity/AgentReturnEntity.java 15 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/member/entity/MemberEntity.java 4 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/rabbit/consumer/WebsocketPriceConsumer.java 219 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/rabbit/producer/OrderProducer.java 205 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/utils/ThreadPoolUtils.java 35 ●●●●● patch | view | raw | blame | history
src/main/resources/application.yml 1 ●●●● patch | view | raw | blame | history
src/main/resources/mapper/contract/ContractHoldOrderDao.xml 17 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/common/enumerates/OrderClosingTypeEnum.java
New file
@@ -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;
    }
}
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();
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;
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);
}
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;
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);
}
src/main/java/com/xcong/excoin/modules/contract/parameter/dto/HoldOrderListDto.java
New file
@@ -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;
}
src/main/java/com/xcong/excoin/modules/contract/parameter/dto/OrderDetailDto.java
New file
@@ -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 {
}
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();
}
src/main/java/com/xcong/excoin/modules/contract/service/RabbitOrderService.java
New file
@@ -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);
}
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("平仓成功");
    }
}
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());
            }
src/main/java/com/xcong/excoin/modules/contract/service/impl/RabbitOrderServiceImpl.java
New file
@@ -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);
        }
    }
}
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;
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;
    /**
     * 手机号(包含国际手机号)
     */
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);
    }
}
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());
        }
    }
}
src/main/java/com/xcong/excoin/utils/ThreadPoolUtils.java
New file
@@ -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);
            }
        });
    }
}
src/main/resources/application.yml
@@ -99,6 +99,7 @@
  newest-price-update-job: false
  #其他任务控制
  other-job: false
  rabbit-consumer: true
aliyun:
  oss:
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>