From 2e2eeeb8291415706f4941e55270a0b23e76bf23 Mon Sep 17 00:00:00 2001 From: xiaoyong931011 <15274802129@163.com> Date: Fri, 04 Mar 2022 15:16:06 +0800 Subject: [PATCH] 20222223 --- src/main/java/com/xcong/excoin/modules/coin/service/impl/OrderCoinServiceImpl.java | 610 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 587 insertions(+), 23 deletions(-) diff --git a/src/main/java/com/xcong/excoin/modules/coin/service/impl/OrderCoinServiceImpl.java b/src/main/java/com/xcong/excoin/modules/coin/service/impl/OrderCoinServiceImpl.java index 5f330e7..cafef80 100644 --- a/src/main/java/com/xcong/excoin/modules/coin/service/impl/OrderCoinServiceImpl.java +++ b/src/main/java/com/xcong/excoin/modules/coin/service/impl/OrderCoinServiceImpl.java @@ -1,25 +1,34 @@ package com.xcong.excoin.modules.coin.service.impl; import java.math.BigDecimal; +import java.text.ParseException; import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Date; -import java.util.GregorianCalendar; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import javax.annotation.Resource; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.xcong.excoin.common.contants.AppContants; +import com.xcong.excoin.common.enumerates.CoinTypeEnum; +import com.xcong.excoin.modules.blackchain.service.RocService; import com.xcong.excoin.modules.coin.mapper.OrderCoinsDealMapper; +import com.xcong.excoin.modules.coin.service.CoinService; +import com.xcong.excoin.modules.member.dao.MemberDao; +import com.xcong.excoin.modules.member.entity.MemberEntity; import com.xcong.excoin.modules.platform.entity.PlatformCnyUsdtExchangeEntity; import com.xcong.excoin.modules.platform.entity.PlatformSymbolsCoinEntity; +import com.xcong.excoin.modules.symbols.constants.SymbolsConstats; +import com.xcong.excoin.rabbit.producer.OrderSubmitProducer; +import com.xcong.excoin.trade.CoinTrader; +import com.xcong.excoin.trade.CoinTraderFactory; +import com.xcong.excoin.trade.ExchangeTrade; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; @@ -38,15 +47,11 @@ import com.xcong.excoin.modules.coin.parameter.dto.FindAllWalletCoinOrderDto; import com.xcong.excoin.modules.coin.parameter.vo.FindCollectListVo; import com.xcong.excoin.modules.coin.parameter.vo.MemberSelectSymbolsVo; -import com.xcong.excoin.modules.coin.parameter.vo.OrderWalletCoinDealListVo; import com.xcong.excoin.modules.coin.parameter.vo.OrderWalletCoinDealVo; import com.xcong.excoin.modules.coin.parameter.vo.OrderWalletCoinListVo; import com.xcong.excoin.modules.coin.parameter.vo.OrderWalletCoinVo; import com.xcong.excoin.modules.coin.parameter.vo.TransactionPageOfWalletCoinVo; import com.xcong.excoin.modules.coin.service.OrderCoinService; -import com.xcong.excoin.modules.contract.entity.ContractOrderEntity; -import com.xcong.excoin.modules.contract.mapper.ContractOrderEntityMapper; -import com.xcong.excoin.modules.contract.parameter.vo.OrderListVo; import com.xcong.excoin.modules.member.dao.MemberWalletCoinDao; import com.xcong.excoin.modules.member.entity.MemberSelectSymbolsEntity; import com.xcong.excoin.modules.member.entity.MemberWalletCoinEntity; @@ -84,6 +89,19 @@ RedisUtils redisUtils; @Resource PlatformSymbolsCoinDao platformSymbolsCoinDao; + + @Resource + private CoinTraderFactory factory; + + @Resource + private MemberDao memberDao; + + @Resource + private OrderSubmitProducer orderSubmitProducer; + + @Resource + private CoinService coinService; + @Override public String generateSimpleSerialno(String userId) { @@ -163,13 +181,20 @@ @Override @Transactional - public Result submitSalesWalletCoinOrder(String symbol, Integer type, Integer tradeType, BigDecimal price, BigDecimal amount) { + public Result submitSalesWalletCoinOrder(String symbol, Integer type, Integer tradeType, BigDecimal price, BigDecimal amount, BigDecimal entrustAmount) { + + //获取用户ID Long memberId = LoginUserUtils.getAppLoginUser().getId(); - + BigDecimal nowPriceinBigDecimal = price; //查询当前价 BigDecimal nowPrice = new BigDecimal(redisUtils.getString(CoinTypeConvert.convertToKey(symbol + "/USDT"))); - + System.out.println(symbol + "当前价:" + nowPrice); + if (OrderCoinsEntity.ORDERTYPE_BUY.equals(type) && OrderCoinsEntity.TRADETYPE_MARKETPRICE.equals(tradeType)) { + amount = entrustAmount.divide(nowPrice, 8, BigDecimal.ROUND_DOWN); + System.out.println(symbol + "市价量:" + amount); + } + // 处理市价 // 获取交易管理的杠杠倍率,手续费率等信息,由平台进行设置 symbol = symbol.toUpperCase(); MemberWalletCoinEntity walletCoin = memberWalletCoinDao.selectWalletCoinBymIdAndCode(memberId, symbol); @@ -185,13 +210,14 @@ BigDecimal closingPrice = price.multiply(amount).multiply(tradeSetting.getCoinFeeRatio()); //总费用 = 成交价*数量+手续费 BigDecimal totalPayPrice = price.multiply(amount).add(closingPrice); + BigDecimal totalPayPricCoin = nowPrice.multiply(amount).add(closingPrice); String walletCode = MemberWalletCoinEnum.WALLETCOINCODE.getValue(); MemberWalletCoinEntity walletCoinUsdt = memberWalletCoinDao.selectWalletCoinBymIdAndCode(memberId, walletCode); if (OrderCoinsEntity.ORDERTYPE_BUY.equals(type)) { //买入,所需总费用跟用户USDT金额进行比较 BigDecimal availableBalance = walletCoinUsdt.getAvailableBalance(); - if (totalPayPrice.compareTo(availableBalance) > 0) { + if (totalPayPrice.compareTo(availableBalance) > 0 || totalPayPricCoin.compareTo(availableBalance) > 0) { return Result.fail(MessageSourceUtils.getString("order_service_0010")); } } else { @@ -204,7 +230,8 @@ // 创建订单 OrderCoinsEntity order = new OrderCoinsEntity(); - if (OrderCoinsEntity.TRADETYPE_FIXEDPRICE.equals(tradeType)) { + if ((OrderCoinsEntity.TRADETYPE_FIXEDPRICE.equals(tradeType) && type.equals(1) && price.compareTo(nowPrice) < 0) + || (OrderCoinsEntity.TRADETYPE_FIXEDPRICE.equals(tradeType) && type.equals(2) && price.compareTo(nowPrice) > 0)) { // 如果是限价交易直接插入主表数据 order.setMemberId(memberId); order.setOrderNo(generateSimpleSerialno(memberId.toString())); @@ -248,7 +275,16 @@ order.setEntrustCnt(amount); order.setEntrustPrice(price); order.setDealCnt(amount); - order.setDealPrice(price); + order.setEntrustAmount(entrustAmount); + if ((OrderCoinsEntity.TRADETYPE_FIXEDPRICE.equals(tradeType) && type.equals(1) && price.compareTo(nowPrice) >= 0) + || (OrderCoinsEntity.TRADETYPE_FIXEDPRICE.equals(tradeType) && type.equals(2) && price.compareTo(nowPrice) <= 0)) { + // 手续费用(手续费=建仓价X数量X手续费率) + closingPrice = nowPrice.multiply(amount).multiply(tradeSetting.getCoinFeeRatio()); + //总费用 = 成交价*数量+手续费 + totalPayPrice = nowPrice.multiply(amount).add(closingPrice); + price = nowPrice; + } + order.setDealPrice(nowPrice); order.setDealAmount(totalPayPrice); order.setOrderStatus(OrderCoinsEntity.ORDERSTATUS_DONE); order.setTradeType(tradeType); @@ -263,8 +299,8 @@ detail.setTradeType(tradeType); detail.setSymbol(symbol); detail.setSymbolCnt(amount); - detail.setEntrustPrice(price); - detail.setDealPrice(price); + detail.setEntrustPrice(nowPriceinBigDecimal); + detail.setDealPrice(nowPrice); detail.setDealAmount(totalPayPrice); detail.setFeeAmount(closingPrice); detail.setOrderStatus(OrderCoinsDealEntity.ORDERSTATUS_DONE); @@ -309,6 +345,191 @@ } @Override + public Result submitSalesWalletCoinOrderWithMatch(String symbol, Integer type, Integer tradeType, BigDecimal price, BigDecimal amount, BigDecimal entrustAmount) { + //获取用户ID + Long memberId = LoginUserUtils.getAppLoginUser().getId(); + // 需要实名 + MemberEntity memberEntity = memberDao.selectById(memberId); + if (!MemberEntity.CERTIFY_STATUS_Y.equals(memberEntity.getCertifyStatus())) { + return Result.fail(MessageSourceUtils.getString("member_controller_0001")); + } + // 需要先 + String phone = memberEntity.getPhone(); + if (!"13632989240".equals(phone) && !"15158130575".equals(phone)) { + if (OrderCoinsEntity.ORDERTYPE_BUY.equals(type)) { + // 禁止挂卖 + String string = redisUtils.getString("BUY_LIMIT_KEY_PHONE"); + if (StringUtils.isNotBlank(string) && StringUtils.isNotBlank(phone) && string.contains(phone)) { + return Result.fail("买入受限"); + } + + if (StringUtils.isNotBlank(string) && StringUtils.isNotBlank(memberEntity.getEmail()) && string.contains(memberEntity.getEmail())) { + return Result.fail("买入受限"); + } + // 不能超过800个 + +// if (amount != null && amount.compareTo(new BigDecimal("800")) > 0) { +// return Result.fail("买入额度受限"); +// } +// BigDecimal bigDecimal = orderCoinDealDao.sumTodayBuyAmount(memberId, symbol); +// if (bigDecimal == null) { +// bigDecimal = BigDecimal.ZERO; +// } +// amount = amount == null ? BigDecimal.ZERO : amount; +// bigDecimal = bigDecimal.add(amount); +// if (bigDecimal != null && bigDecimal.compareTo(new BigDecimal("800")) > 0) { +// return Result.fail("买入额度受限"); +// } +// // 挂单不能超过800 +// BigDecimal bigDecimal1 = orderCoinDealDao.sumTodayEntrustCntBuyAmount(memberId, symbol); +// if (bigDecimal1 == null) { +// bigDecimal1 = BigDecimal.ZERO; +// } +// bigDecimal1 = bigDecimal1.add(amount); +// if (bigDecimal1 != null && bigDecimal1.compareTo(new BigDecimal("800")) > 0) { +// return Result.fail("买入额度受限"); +// } + } else { + // 判断redis开关 + //String string = redisUtils.getString("SELL_LIMIT_KEY"); + String string = redisUtils.getString("SELL_LIMIT_KEY_PHONE"); + if (StringUtils.isNotBlank(string) && StringUtils.isNotBlank(phone) && string.contains(phone)) { + return Result.fail("卖出受限"); + } + + if (StringUtils.isNotBlank(string) && StringUtils.isNotBlank(memberEntity.getEmail()) && string.contains(memberEntity.getEmail())) { + return Result.fail("卖出受限"); + } + } + } + + BigDecimal nowPriceinBigDecimal = price; + //查询当前价 + BigDecimal nowPrice = new BigDecimal(redisUtils.getString(CoinTypeConvert.convertToKey(symbol + "/USDT"))); + + // 获取交易管理的杠杠倍率,手续费率等信息,由平台进行设置 + symbol = symbol.toUpperCase(); + MemberWalletCoinEntity walletCoin = memberWalletCoinDao.selectWalletCoinBymIdAndCode(memberId, symbol); + if (ObjectUtil.isEmpty(walletCoin)) { + // 创建这个钱包 + walletCoin = new MemberWalletCoinEntity(); + walletCoin.setAvailableBalance(BigDecimal.ZERO); + walletCoin.setFrozenBalance(BigDecimal.ZERO); + walletCoin.setTotalBalance(BigDecimal.ZERO); + walletCoin.setBorrowedFund(BigDecimal.ZERO); + walletCoin.setMemberId(memberId); + walletCoin.setWalletCode(symbol); + memberWalletCoinDao.insert(walletCoin); + } + // 查询交易设置 + PlatformTradeSettingEntity tradeSetting = platformTradeSettingDao.findTradeSetting(); + if (ObjectUtil.isEmpty(tradeSetting)) { + return Result.fail(MessageSourceUtils.getString("order_service_0009")); + } + // 手续费用(手续费=建仓价X数量X手续费率) + BigDecimal closingPrice = BigDecimal.ZERO; + // 总费用分两种 1,限价交易 是价格*数量+手续费 2,市价交易 用户输入的金额+手续费 + //总费用 = 成交价*数量+手续费 + BigDecimal totalPayPrice = BigDecimal.ZERO; + if (OrderCoinsEntity.TRADETYPE_FIXEDPRICE.equals(tradeType)) { + // 限价 + closingPrice = price.multiply(amount).multiply(tradeSetting.getCoinFeeRatio()); + totalPayPrice = price.multiply(amount).add(closingPrice); + entrustAmount = price.multiply(amount); + // 限价买不能高于当前10% + BigDecimal multiply = nowPrice.multiply(new BigDecimal("1.2")); + if (price.compareTo(multiply) > 0) { + return Result.fail("不能高于当前价的120%"); + } + multiply= nowPrice.multiply(new BigDecimal("0.8")); + if (price.compareTo(multiply) < 0) { + return Result.fail("不能低于当前价的80%"); + } + + } else { + // 市价 + if (OrderCoinsEntity.ORDERTYPE_BUY == type) { + closingPrice = entrustAmount.multiply(tradeSetting.getCoinFeeRatio()); + totalPayPrice = entrustAmount.add(closingPrice); + } + } + String walletCode = MemberWalletCoinEnum.WALLETCOINCODE.getValue(); + MemberWalletCoinEntity walletCoinUsdt = memberWalletCoinDao.selectWalletCoinBymIdAndCode(memberId, walletCode); + if (OrderCoinsEntity.ORDERTYPE_BUY.equals(type)) { + //买入,所需总费用跟用户USDT金额进行比较 + BigDecimal availableBalance = walletCoinUsdt.getAvailableBalance(); + if (totalPayPrice.compareTo(availableBalance) > 0) { + return Result.fail(MessageSourceUtils.getString("order_service_0010")); + } + } else { + //卖出,用户币是否足够 + BigDecimal availableBalance = walletCoin.getAvailableBalance(); + if (amount.compareTo(availableBalance) > 0) { + return Result.fail(MessageSourceUtils.getString("order_service_0010")); + } + } + + // 首先将单插入到数据库主表(委托表) + // 创建订单 + OrderCoinsEntity order = new OrderCoinsEntity(); + //根据委托类型生成不同数据 + // 如果是限价交易直接插入主表数据 + order.setMemberId(memberId); + order.setOrderNo(generateSimpleSerialno(memberId.toString())); + order.setOrderType(type); + order.setSymbol(symbol); + //order.setMarkPrice(nowPrice); + + // 成交量 先设置为0 + order.setDealCnt(BigDecimal.ZERO); + order.setEntrustCnt(BigDecimal.ZERO); + order.setEntrustPrice(BigDecimal.ZERO); + // 成交价 + //order.setDealPrice(price); + // 成交金额 + order.setDealAmount(BigDecimal.ZERO); + order.setOrderStatus(OrderCoinsEntity.ORDERSTATUS_DODING); + order.setTradeType(tradeType); + // 手续费 + order.setFeeAmount(closingPrice); + if (OrderCoinsEntity.TRADETYPE_FIXEDPRICE.equals(tradeType)) { + // 限价 是需要价格和数量 可以得到成交金额 + // 下单量 + order.setEntrustCnt(amount); + // 下单价格 + order.setEntrustPrice(price); + order.setEntrustAmount(amount.multiply(price)); + } else { + if (OrderCoinsEntity.ORDERTYPE_BUY.equals(type)) { + // 市价 只有金额 + order.setEntrustAmount(entrustAmount); + } else { + // 市价卖单 + // 下单量 + order.setEntrustCnt(amount); + // 下单价格 + order.setEntrustPrice(BigDecimal.ZERO); + order.setEntrustAmount(BigDecimal.ZERO); + } + } + orderCoinsDao.insert(order); + + //更新用户钱包信息 + //冻结相应的资产 + if (OrderCoinsEntity.ORDERTYPE_BUY.equals(type)) { + //如果是买入,所对应的币种增加,USDT账户减少金额 + coinService.updateWalletBalance(walletCoinUsdt.getId(), totalPayPrice.negate(), totalPayPrice.negate(), entrustAmount); + } else { + //如果是卖出,币种减少,USDT增加 + coinService.updateWalletBalance(walletCoin.getId(), amount.negate(), amount.negate(), amount); + } + // 加入到撮合 + order.setSymbol(symbol); + orderSubmitProducer.sendMsg(JSONObject.toJSONString(order)); + return Result.ok(MessageSourceUtils.getString("order_service_0011")); + } + + @Override public Result getEntrustWalletCoinOrder(String symbol, Integer status) { //获取用户ID Long memberId = LoginUserUtils.getAppLoginUser().getId(); @@ -319,6 +540,20 @@ if (CollUtil.isNotEmpty(findCoinOrderListByMemberIdAndSysmbol)) { for (OrderCoinsEntity orderCoinsEntity : findCoinOrderListByMemberIdAndSysmbol) { OrderWalletCoinVo entityToVo = OrderWalletCoinMapper.INSTANCE.entityToVo(orderCoinsEntity); + entityToVo.setFeeAmount(entityToVo.getFeeAmount() == null + ? BigDecimal.ZERO : entityToVo.getFeeAmount().setScale(4, BigDecimal.ROUND_DOWN)); + entityToVo.setMarkPrice(entityToVo.getMarkPrice() == null + ? BigDecimal.ZERO : entityToVo.getMarkPrice().setScale(4, BigDecimal.ROUND_DOWN)); + entityToVo.setEntrustCnt(entityToVo.getEntrustCnt() == null + ? BigDecimal.ZERO : entityToVo.getEntrustCnt().setScale(4, BigDecimal.ROUND_DOWN)); + entityToVo.setEntrustPrice(entityToVo.getEntrustPrice() == null + ? BigDecimal.ZERO : entityToVo.getEntrustPrice().setScale(4, BigDecimal.ROUND_DOWN)); + entityToVo.setDealCnt(entityToVo.getDealCnt() == null + ? BigDecimal.ZERO : entityToVo.getDealCnt().setScale(4, BigDecimal.ROUND_DOWN)); + entityToVo.setDealPrice(entityToVo.getDealPrice() == null + ? BigDecimal.ZERO : entityToVo.getDealPrice().setScale(4, BigDecimal.ROUND_DOWN)); + entityToVo.setDealAmount(entityToVo.getDealAmount() == null + ? BigDecimal.ZERO : entityToVo.getDealAmount().setScale(4, BigDecimal.ROUND_DOWN)); arrayList.add(entityToVo); } } @@ -329,11 +564,28 @@ @Override @Transactional public Result cancelEntrustWalletCoinOrder(String orderId) { + // 将这个取消放入redis + boolean b = redisUtils.setNotExist(AppContants.ORDER_CANCEL_KEY + orderId, orderId, 10); + if (!b) { + return Result.ok(MessageSourceUtils.getString("order_service_0012")); + } //获取用户ID Long memberId = LoginUserUtils.getAppLoginUser().getId(); OrderCoinsEntity orderCoinsEntity = orderCoinsDao.selectById(orderId); - if (ObjectUtil.isNotEmpty(orderCoinsEntity) && orderCoinsEntity.getMemberId() == memberId) { - if (orderCoinsEntity.getOrderStatus() == OrderCoinsEntity.ORDERSTATUS_CANCEL) { + if (ObjectUtil.isNotEmpty(orderCoinsEntity) && orderCoinsEntity.getMemberId().equals(memberId)) { + // 如果是撮合交易单 + if (SymbolsConstats.EXCHANGE_SYMBOLS.contains(orderCoinsEntity.getSymbol())) { + // 这里先更新状态 判断状态 防止消息发送过程中的二次提交 + if (!orderCoinsEntity.getOrderStatus().equals(OrderCoinsEntity.ORDERSTATUS_DODING)) { + // 不是持仓中 返回 + return Result.ok(MessageSourceUtils.getString("order_service_0013")); + } + + // 更新为已取消(可能在这个过程中 这个单已经成交) + orderSubmitProducer.sendCancelMsg(orderId); + return Result.ok(MessageSourceUtils.getString("order_service_0013")); + } + if (orderCoinsEntity.getOrderStatus() == OrderCoinsEntity.ORDERSTATUS_CANCEL || orderCoinsEntity.getOrderStatus() == OrderCoinsEntity.ORDERSTATUS_DONE) { return Result.fail(MessageSourceUtils.getString("order_service_0012")); } orderCoinsEntity.setOrderStatus(OrderCoinsEntity.ORDERSTATUS_CANCEL); @@ -406,6 +658,121 @@ } @Override + @Transactional + public Result cancelEntrustWalletCoinOrderForMatch(String orderId) { + //如果redis中没有这个单 则不再往下走 + OrderCoinsEntity orderCoinsEntity = orderCoinsDao.selectById(orderId); + if (orderCoinsEntity == null) { + return Result.ok(""); + } + Long memberId = orderCoinsEntity.getMemberId(); + // 取消撮合订单的单 + CoinTrader trader = factory.getTrader(orderCoinsEntity.getSymbol()); + // 从撮合交易系统得到的已成交的数据 + OrderCoinsEntity coinsEntityCancel = trader.cancelOrder(orderCoinsEntity); + if (coinsEntityCancel == null) { + // 此时说明撮合系统已经没这个单了 不需要继续处理 + // 直接更新状态先 + OrderCoinsEntity update = new OrderCoinsEntity(); + update.setId(Long.valueOf(orderId)); + update.setOrderStatus(OrderCoinsEntity.ORDERSTATUS_CANCEL); + //orderCoinsEntity.setOrderStatus(OrderCoinsEntity.ORDERSTATUS_CANCEL); + orderCoinsDao.updateById(update); + return null; + } + + if (ObjectUtil.isNotEmpty(orderCoinsEntity)) { + if (orderCoinsEntity.getOrderStatus() == OrderCoinsEntity.ORDERSTATUS_DONE) { + // 已完成的直接返回 + return Result.fail(MessageSourceUtils.getString("order_service_0012")); + } + OrderCoinsEntity update = new OrderCoinsEntity(); + update.setId(Long.valueOf(orderId)); + update.setOrderStatus(OrderCoinsEntity.ORDERSTATUS_CANCEL); + //orderCoinsEntity.setOrderStatus(OrderCoinsEntity.ORDERSTATUS_CANCEL); + orderCoinsDao.updateById(update); + + String symbol = orderCoinsEntity.getSymbol(); + + OrderCoinsDealEntity detail = new OrderCoinsDealEntity(); + detail.setMemberId(memberId); + detail.setOrderId(orderCoinsEntity.getId()); + detail.setOrderNo(generateSimpleSerialno(memberId.toString())); + detail.setOrderType(orderCoinsEntity.getOrderType()); + detail.setTradeType(orderCoinsEntity.getTradeType()); + detail.setSymbol(symbol); + detail.setOrderStatus(OrderCoinsDealEntity.ORDERSTATUS_CANCEL); + detail.setSymbolCnt(BigDecimal.ZERO); + detail.setEntrustPrice(orderCoinsEntity.getEntrustPrice()); + detail.setDealPrice(BigDecimal.ZERO); + detail.setDealAmount(BigDecimal.ZERO); + detail.setFeeAmount(orderCoinsEntity.getFeeAmount()); + if (OrderCoinsEntity.ORDERTYPE_BUY.equals(orderCoinsEntity.getOrderType())) { + //如果是限价买入,撤单将USDT账户冻结金额返回 + String walletCode = MemberWalletCoinEnum.WALLETCOINCODE.getValue(); + MemberWalletCoinEntity walletCoin = memberWalletCoinDao.selectWalletCoinBymIdAndCode(memberId, walletCode); + + if (ObjectUtil.isNotEmpty(walletCoin)) { + //手续费 = 开仓价*数量*手续费率 + //返还金额=开仓价*未成交数量+手续费 + // 这里根据成交的单计算 + BigDecimal dealAmount = coinsEntityCancel.getDealAmount(); + // 市价的按成交额退款 + BigDecimal returnBalance = orderCoinsEntity.getEntrustAmount().subtract(dealAmount); + + // 需要退回的手续费 + BigDecimal returnFee = BigDecimal.ZERO; + if (returnBalance.compareTo(orderCoinsEntity.getEntrustAmount()) == 0) { + returnFee = orderCoinsEntity.getFeeAmount(); + } else { + // 按比例退回 + BigDecimal needFee = orderCoinsEntity.getFeeAmount().multiply(dealAmount.divide(orderCoinsEntity.getEntrustAmount(), 8, BigDecimal.ROUND_DOWN)); + returnFee = orderCoinsEntity.getFeeAmount().subtract(needFee); + } + BigDecimal avi = returnBalance.add(returnFee); + coinService.updateWalletBalance(walletCoin.getId(), avi, null, returnBalance.negate()); + walletCoin.setAvailableBalance(walletCoin.getAvailableBalance().add(returnBalance).add(returnFee)); + walletCoin.setFrozenBalance(walletCoin.getFrozenBalance().subtract(returnBalance)); + //memberWalletCoinDao.updateById(walletCoin); + // 流水记录 + MemberAccountFlowEntity record = new MemberAccountFlowEntity(); + record.setSource(MemberAccountFlowEntity.SOURCE_CANCEL); + record.setRemark(MemberAccountFlowEntity.REMARK_CANCEL + symbol + MemberAccountFlowEntity.REMARK_RETURNBALANCE + returnBalance.add(returnFee)); + record.setBalance(walletCoin.getAvailableBalance()); + record.setMemberId(memberId); + record.setSymbol(symbol); + record.setPrice(returnBalance); + memberAccountFlowEntityDao.insert(record); + return Result.ok(MessageSourceUtils.getString("order_service_0013")); + } + } else { + //如果是限价卖出,撤单将对应的钱包冻结金额返回 + MemberWalletCoinEntity walletCoin = memberWalletCoinDao.selectWalletCoinBymIdAndCode(memberId, symbol); + if (ObjectUtil.isNotEmpty(walletCoin)) { + // 卖出按卖出的数量计算手续费 + BigDecimal returnBalance = orderCoinsEntity.getEntrustCnt().subtract(coinsEntityCancel.getDealCnt()); + walletCoin.setAvailableBalance(walletCoin.getAvailableBalance().add(returnBalance)); + walletCoin.setFrozenBalance(walletCoin.getFrozenBalance().subtract(returnBalance)); + //memberWalletCoinDao.updateById(walletCoin); + coinService.updateWalletBalance(walletCoin.getId(), returnBalance, null, returnBalance.negate()); + // 流水记录 + MemberAccountFlowEntity record = new MemberAccountFlowEntity(); + record.setSource(MemberAccountFlowEntity.SOURCE_CANCEL); + record.setRemark(MemberAccountFlowEntity.REMARK_CANCEL + symbol + MemberAccountFlowEntity.REMARK_RETURNBALANCE + returnBalance); + record.setBalance(walletCoin.getAvailableBalance()); + record.setMemberId(memberId); + record.setSymbol(symbol); + record.setPrice(walletCoin.getFrozenBalance()); + memberAccountFlowEntityDao.insert(record); + return Result.ok(MessageSourceUtils.getString("order_service_0013")); + } + } + orderCoinDealDao.insert(detail); + } + return Result.fail(MessageSourceUtils.getString("order_service_0043")); + } + + @Override public Result findAllWalletCoinOrder(FindAllWalletCoinOrderDto findAllWalletCoinOrderDto) { //获取用户ID Long memberId = LoginUserUtils.getAppLoginUser().getId(); @@ -416,8 +783,34 @@ orderCoinsDealEntity.setSymbol(findAllWalletCoinOrderDto.getSymbol()); IPage<OrderCoinsDealEntity> list = orderCoinDealDao.findAllWalletCoinOrderInPage(page, orderCoinsDealEntity); Page<OrderWalletCoinDealVo> pageEntityToPageVo = OrderWalletCoinDealMapper.INSTANCE.pageEntityToPageVo(list); + List<OrderWalletCoinDealVo> records = pageEntityToPageVo.getRecords(); + if (CollUtil.isNotEmpty(records)) { + for (OrderWalletCoinDealVo orderWalletCoinDealVo : records) { + orderWalletCoinDealVo.setFeeAmount(orderWalletCoinDealVo.getFeeAmount() == null + ? BigDecimal.ZERO : orderWalletCoinDealVo.getFeeAmount().setScale(4, BigDecimal.ROUND_DOWN)); + + orderWalletCoinDealVo.setDealAmount(orderWalletCoinDealVo.getDealAmount() == null + ? BigDecimal.ZERO : orderWalletCoinDealVo.getDealAmount().setScale(4, BigDecimal.ROUND_DOWN)); + + orderWalletCoinDealVo.setSymbolCnt(orderWalletCoinDealVo.getSymbolCnt() == null + ? BigDecimal.ZERO : orderWalletCoinDealVo.getSymbolCnt().setScale(4, BigDecimal.ROUND_DOWN)); + + orderWalletCoinDealVo.setEntrustPrice(orderWalletCoinDealVo.getEntrustPrice() == null + ? BigDecimal.ZERO : orderWalletCoinDealVo.getEntrustPrice().setScale(4, BigDecimal.ROUND_DOWN)); + + orderWalletCoinDealVo.setDealPrice(orderWalletCoinDealVo.getDealPrice() == null + ? BigDecimal.ZERO : orderWalletCoinDealVo.getDealPrice().setScale(4, BigDecimal.ROUND_DOWN)); + } + } + return Result.ok(pageEntityToPageVo); + } + + @Override + public Result findAllWalletCoinOrder() { + List<OrderCoinsDealEntity> orderCoinsDealEntities = orderCoinDealDao.selectAllCoinDealsOrderBySymbol(CoinTypeEnum.GRICE.toString()); + return Result.ok(orderCoinsDealEntities); } @Override @@ -426,6 +819,22 @@ Long memberId = LoginUserUtils.getAppLoginUser().getId(); OrderCoinsDealEntity selectWalletCoinOrder = orderCoinDealDao.selectWalletCoinOrder(orderId, memberId); OrderWalletCoinDealVo entityToVo = OrderWalletCoinDealMapper.INSTANCE.entityToVoOrder(selectWalletCoinOrder); + if (ObjectUtil.isNotEmpty(entityToVo)) { + entityToVo.setFeeAmount(entityToVo.getFeeAmount() == null + ? BigDecimal.ZERO : entityToVo.getFeeAmount().setScale(4, BigDecimal.ROUND_DOWN)); + + entityToVo.setDealAmount(entityToVo.getDealAmount() == null + ? BigDecimal.ZERO : entityToVo.getDealAmount().setScale(4, BigDecimal.ROUND_DOWN)); + + entityToVo.setSymbolCnt(entityToVo.getSymbolCnt() == null + ? BigDecimal.ZERO : entityToVo.getSymbolCnt().setScale(4, BigDecimal.ROUND_DOWN)); + + entityToVo.setEntrustPrice(entityToVo.getEntrustPrice() == null + ? BigDecimal.ZERO : entityToVo.getEntrustPrice().setScale(4, BigDecimal.ROUND_DOWN)); + + entityToVo.setDealPrice(entityToVo.getDealPrice() == null + ? BigDecimal.ZERO : entityToVo.getDealPrice().setScale(4, BigDecimal.ROUND_DOWN)); + } return Result.ok(entityToVo); } @@ -518,7 +927,9 @@ @Override @Transactional(rollbackFor = Exception.class) public void dealEntrustCoinOrder() { - List<OrderCoinsEntity> list = orderCoinsDao.selectAllEntrustingCoinOrderList(); + List<String> ignoreTypes = new ArrayList<>(); + ignoreTypes.add(SymbolsConstats.ROC); + List<OrderCoinsEntity> list = orderCoinsDao.selectAllEntrustingCoinOrderList(ignoreTypes); if (CollUtil.isNotEmpty(list)) { for (OrderCoinsEntity orderCoinsEntity : list) { BigDecimal nowPrice = new BigDecimal(redisUtils.getString(CoinTypeConvert.convertToKey(orderCoinsEntity.getSymbol() + "/USDT"))); @@ -583,4 +994,157 @@ } } } + + @Transactional + public void handleOrder(List<ExchangeTrade> trades) { + + // 处理撮合交易的订单 + for (ExchangeTrade exchangeTrade : trades) { + if (exchangeTrade == null) { + continue; + } + // 量 + BigDecimal amount = exchangeTrade.getAmount(); + // 买单ID + Long buyOrderId = exchangeTrade.getBuyOrderId(); + // 成交金额(usdt) + BigDecimal buyTurnover = exchangeTrade.getBuyTurnover(); + int direction = exchangeTrade.getDirection(); + // 成交价 + BigDecimal price = exchangeTrade.getPrice(); + // 卖单 + Long sellOrderId = exchangeTrade.getSellOrderId(); + + // 买卖单都需要处理 + // 买单 + OrderCoinsEntity buyOrderCoinsEntity = orderCoinsDao.selectById(buyOrderId); + if (buyOrderCoinsEntity != null) { + // 单的总金额 + BigDecimal closingPrice = buyTurnover.multiply(new BigDecimal("0.002")); + //成交总量 + // 创建一个完成的单 + OrderCoinsDealEntity detail = new OrderCoinsDealEntity(); + detail.setMemberId(buyOrderCoinsEntity.getMemberId()); + detail.setOrderId(buyOrderCoinsEntity.getId()); + detail.setOrderNo(buyOrderCoinsEntity.getOrderNo()); + detail.setOrderType(buyOrderCoinsEntity.getOrderType()); + detail.setTradeType(buyOrderCoinsEntity.getTradeType()); + detail.setSymbol(buyOrderCoinsEntity.getSymbol()); + detail.setSymbolCnt(amount); + detail.setEntrustPrice(buyOrderCoinsEntity.getEntrustPrice()); + detail.setDealPrice(price); + detail.setDealAmount(buyTurnover); + detail.setFeeAmount(closingPrice); + detail.setOrderStatus(OrderCoinsDealEntity.ORDERSTATUS_DONE); + // 如果这个单在取消状态 则不执行 + orderCoinDealDao.insert(detail); + // 更新买单 + //orderCoinsDao.updateDeal(buyOrderId, amount, buyTurnover); + // 买币扣除冻结usdt 增加币种的可用 + MemberWalletCoinEntity usdtWallet = memberWalletCoinDao.selectWalletCoinBymIdAndCode(buyOrderCoinsEntity.getMemberId(), MemberWalletCoinEnum.WALLETCOINCODE.getValue()); + if (usdtWallet != null) { + // 减少usdt冻结 + coinService.updateWalletBalance(usdtWallet.getId(), null, null, buyTurnover.negate()); + } + // 增加买的币 + MemberWalletCoinEntity buySymbolWallet = memberWalletCoinDao.selectWalletCoinBymIdAndCode(buyOrderCoinsEntity.getMemberId(), buyOrderCoinsEntity.getSymbol()); + if (buySymbolWallet != null) { + coinService.updateWalletBalance(buySymbolWallet.getId(), amount, amount, null); + } + // 流水记录 + MemberAccountFlowEntity record = new MemberAccountFlowEntity(); + record.setMemberId(buyOrderCoinsEntity.getMemberId()); + record.setPrice(buyTurnover.setScale(4, BigDecimal.ROUND_DOWN).negate()); + record.setSource(MemberAccountFlowEntity.SOURCE_BUY + buyOrderCoinsEntity.getSymbol()); + record.setRemark(MemberAccountFlowEntity.REMARK_BUY + buyOrderCoinsEntity.getSymbol() + ":" + amount); + record.setSymbol(buyOrderCoinsEntity.getSymbol()); + record.setBalance(usdtWallet.getAvailableBalance().subtract(buyTurnover)); + memberAccountFlowEntityDao.insert(record); + } + + // 卖单 + OrderCoinsEntity sellOrderCoinsEntity = orderCoinsDao.selectById(sellOrderId); + if (sellOrderCoinsEntity != null) { + // 比较剩余的量 + BigDecimal dealAmount = sellOrderCoinsEntity.getDealCnt(); + // 创建一个完成的单 + OrderCoinsDealEntity detail = new OrderCoinsDealEntity(); + detail.setMemberId(sellOrderCoinsEntity.getMemberId()); + detail.setOrderId(sellOrderCoinsEntity.getId()); + detail.setOrderNo(sellOrderCoinsEntity.getOrderNo()); + detail.setOrderType(sellOrderCoinsEntity.getOrderType()); + detail.setTradeType(sellOrderCoinsEntity.getTradeType()); + detail.setSymbol(sellOrderCoinsEntity.getSymbol()); + detail.setSymbolCnt(amount); + detail.setEntrustPrice(sellOrderCoinsEntity.getEntrustPrice()); + detail.setDealPrice(price); + detail.setDealAmount(buyTurnover); + //detail.setFeeAmount(closingPrice); + detail.setOrderStatus(OrderCoinsDealEntity.ORDERSTATUS_DONE); + orderCoinDealDao.insert(detail); + // 如果这个单成交完 更改状态 + //orderCoinsDao.updateDeal(sellOrderId, amount, buyTurnover); + // 卖家需要减少冻结的币种 增加usdt + MemberWalletCoinEntity memberWalletCoinEntity = memberWalletCoinDao.selectWalletCoinBymIdAndCode(sellOrderCoinsEntity.getMemberId(), sellOrderCoinsEntity.getSymbol()); + if (memberWalletCoinEntity != null) { + // 更新卖币减少的币种 + coinService.updateWalletBalance(memberWalletCoinEntity.getId(), null, null, amount.negate()); + } + // 更新卖币得到的usdt + MemberWalletCoinEntity sellWalletCoinEntity = memberWalletCoinDao.selectWalletCoinBymIdAndCode(sellOrderCoinsEntity.getMemberId(), MemberWalletCoinEnum.WALLETCOINCODE.getValue()); + if (sellOrderCoinsEntity != null) { + coinService.updateWalletBalance(sellWalletCoinEntity.getId(), buyTurnover, buyTurnover, null); + } + // 流水记录 + MemberAccountFlowEntity recordSell = new MemberAccountFlowEntity(); + recordSell.setMemberId(sellOrderCoinsEntity.getMemberId()); + recordSell.setPrice(buyTurnover.setScale(4, BigDecimal.ROUND_DOWN)); + recordSell.setSource(MemberAccountFlowEntity.SOURCE_SALE + sellOrderCoinsEntity.getSymbol()); + recordSell.setRemark(MemberAccountFlowEntity.REMARK_SALE + sellOrderCoinsEntity.getSymbol() + ":" + amount.toPlainString()); + recordSell.setSymbol(sellOrderCoinsEntity.getSymbol()); + recordSell.setBalance(sellWalletCoinEntity.getAvailableBalance().add(buyTurnover)); + memberAccountFlowEntityDao.insert(recordSell); + } + } + } + + @Override + @Transactional + public void completeOrder(List<OrderCoinsEntity> trades) { + // 订单完成 更新他们的状态 + List<Long> ids = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(trades)) { + for (OrderCoinsEntity trade : trades) { + if (trade != null) { + if (trade.getOrderType() == 2 && trade.getEntrustCnt().compareTo(trade.getDealCnt()) != 0) { + System.out.println("问题卖单:" + JSON.toJSONString(trade)); + } + //orderCoinsDao.updateStatus(trade.getId(),OrderCoinsEntity.ORDERSTATUS_DONE); + ids.add(trade.getId()); + // 买单 实际成交金额小于委托的 这一部分从冻结扣除 + if (OrderCoinsEntity.ORDERTYPE_BUY == trade.getOrderType()) { + if (trade.getEntrustAmount().compareTo(trade.getDealAmount()) > 0) { + // 此时退回这部分的差额 + BigDecimal subtract = trade.getEntrustAmount().subtract(trade.getDealAmount()); + MemberWalletCoinEntity memberWalletCoinEntity = memberWalletCoinDao.selectWalletCoinBymIdAndCode(trade.getMemberId(), CoinTypeEnum.USDT.name()); + if (memberWalletCoinEntity != null) { + coinService.updateWalletBalance(memberWalletCoinEntity.getId(), subtract, null, subtract.negate()); + } + } + } + } + } + } + if (CollectionUtils.isNotEmpty(ids)) { + orderCoinsDao.batchUpdateStatus(ids, OrderCoinsEntity.ORDERSTATUS_DONE); + } + } + + @Override + public void initOrders(String symbol, Integer type, Integer tradeType, BigDecimal price, + BigDecimal amount, BigDecimal entrustAmount) { + + } + + } -- Gitblit v1.9.1