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 = "获取当前委托单列表") @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,6 +13,7 @@ public interface ContractHoldOrderDao extends BaseMapper<ContractHoldOrderEntity> { /** * 根据ids更新所有订单的平仓状态 * * @param list * @return */ @@ -20,6 +21,7 @@ /** * 根据批次号查询次仓订单 * * @param batchNo * @return */ @@ -27,8 +29,15 @@ /** * 更新该订单为可平仓状态 * * @param 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"); } @@ -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,33 +3,40 @@ 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和后台打包都开启 * * @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 信道 */ @@ -45,6 +52,7 @@ /** * 开空止盈 * * @param message * @param channel */ @@ -61,6 +69,7 @@ /** * 开多止损 * * @param message * @param channel */ @@ -76,6 +85,7 @@ /** * 开空止损 * * @param message * @param channel */ @@ -91,6 +101,7 @@ /** * 限价委托 * * @param message * @param channel */ @@ -106,6 +117,7 @@ /** * 爆仓消费者 * * @param message * @param channel */ @@ -121,15 +133,16 @@ /** * 平仓 * * @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); log.info("我收到消息了平仓: {}", content); // 订单 List<Long> ids = JSONArray.parseArray(content, Long.class); //orderService.closeTradeForMq(ids); 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,6 +14,7 @@ /** * rabbitMq示例生产者 */ @Slf4j @Component public class OrderProducer implements ConfirmCallback { @@ -44,6 +46,7 @@ /** * 开空止盈 * * @param content */ public void sendLessPro(String content) { @@ -54,6 +57,7 @@ /** * 开多止损 * * @param content */ public void sendMoreLoss(String content) { @@ -64,6 +68,7 @@ /** * 开空止损 * * @param content */ public void sendLessLoss(String content) { @@ -74,6 +79,7 @@ /** * 发送委托交易消息 * * @param content */ public void sendLimit(String content){ @@ -84,6 +90,7 @@ /** * 发送爆仓消息 * * @param content */ public void sendCoinout(String content){ @@ -95,6 +102,7 @@ /** * 发送价格操作消息 * * @param content */ public void sendPriceOperate(String content){ @@ -105,11 +113,12 @@ /** * 发送平仓 * * @param content */ public void sendCloseTrade(String content){ CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString()); System.out.println("发送平仓消息:"+content+"==pid:"+correlationData.getId()); log.info("发送平仓消息:{}==pid : {}", content, correlationData.getId()); rabbitTemplate.convertAndSend(RabbitMqConfig.EXCHANGE_A, RabbitMqConfig.ROUTINGKEY_CLOSETRADE, content, correlationData); } 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>