新版仿ok交易所-后端
1
zj
19 hours ago 640ccb9229224642515527daf87f308a7aa9bdf4
trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiContractApplyOrderController.java
@@ -1,6 +1,8 @@
package com.yami.trading.api.controller;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yami.trading.api.dto.CloseAction;
import com.yami.trading.api.dto.OpenAction;
@@ -21,6 +23,7 @@
import com.yami.trading.common.util.ThreadUtils;
import com.yami.trading.security.common.util.SecurityUtils;
import com.yami.trading.service.SessionTokenService;
import com.yami.trading.service.StrongLevelCalculationService;
import com.yami.trading.service.WalletService;
import com.yami.trading.service.contract.ContractApplyOrderService;
import com.yami.trading.service.contract.ContractLockService;
@@ -126,7 +129,6 @@
        BigDecimal contractOpenLimitMax = new BigDecimal(sysparaService.find("contract_open_limit_max").getSvalue());
        data.put("contract_open_limit_max", contractOpenLimitMax);
        return Result.succeed(data);
    }
@@ -191,69 +193,114 @@
     */
    @RequestMapping(action + "open.action")
    public Result<String> open(@Valid OpenAction openAction) throws IOException, InterruptedException {
        String symbol = openAction.getSymbol();
//        Item bySymbol = itemService.findBySymbol(symbol);
//        if(bySymbol == null){
//            throw  new YamiShopBindException("当前币对不存在");
//        }
//        boolean isOpen = MarketOpenChecker.isMarketOpenByItemCloseType(bySymbol.getOpenCloseType());
//        if(!isOpen){
//            throw  new YamiShopBindException("当前已经休市");
//        }
        String partyId = SecurityUtils.getUser().getUserId();
        RLock rLock = redissonClient.getLock("contract_open_" + partyId);
        boolean lockResult = rLock.tryLock(5, TimeUnit.SECONDS);
        if (!lockResult) {
            throw new YamiShopBindException("请稍后再试");
        }
        boolean lockAcquired = false;
        double faceValue = 0.01;//面值
        double minAmount = 0.01;//最低张数
        try {
            User user = userService.getById(partyId);
            if (!user.isEnabled()) {
                throw new YamiShopBindException("用户已锁定");
            // 尝试获取锁,最多等待5秒
            lockAcquired = rLock.tryLock(5, TimeUnit.SECONDS);
            if (!lockAcquired) {
                log.warn("无法获取锁: contract_open_{}", partyId);
                throw new YamiShopBindException("Please try again later");
            }
            //判断下单金额是否符合最低金额  最低下单张数:0.01
            //合约张数  张数=保证金*杠杆倍数/(面值*最新成交价)
            double v = openAction.getAmount().doubleValue() * openAction.getLever_rate().doubleValue() / (faceValue * openAction.getPrice().doubleValue());
            BigDecimal amount = BigDecimal.valueOf(v).setScale(4, RoundingMode.DOWN);
            if (amount.compareTo(new BigDecimal(faceValue)) < 0) {
                double minimumAmount = minAmount * faceValue * openAction.getPrice().doubleValue() / openAction.getLever_rate().doubleValue();
                double roundedAmount = Math.ceil(minimumAmount * 10000) / 10000;
                throw new YamiShopBindException("Minimum order amount: " + roundedAmount);
            }
            Syspara syspara = sysparaService.find("stop_user_internet");
            String stopUserInternet = syspara.getSvalue();
            if(org.apache.commons.lang3.StringUtils.isNotEmpty(stopUserInternet)) {
                String[] stopUsers = stopUserInternet.split(",");
            // 校验当前用户订单状态
            checkContractOrderStatus(openAction, partyId);
                System.out.println("userName = " + user.getUserName());
                System.out.println("stopUserInternet = " + stopUserInternet);
            // 校验用户是否被锁定
            checkUserStatus(partyId);
                if(Arrays.asList(stopUsers).contains(user.getUserName())){
                    throw new YamiShopBindException("无网络");
                }
            }
            // 校验用户网络限制
            checkUserNetworkRestriction(partyId);
            ContractApplyOrder order = new ContractApplyOrder();
            order.setPartyId(partyId);
            order.setSymbol(openAction.getSymbol());
            order.setDirection(openAction.getDirection());
            order.setOffset(ContractApplyOrder.OFFSET_OPEN);
            order.setVolume(openAction.getAmount());
            order.setVolumeOpen(openAction.getAmount());
            order.setLeverRate(openAction.getLever_rate());
            order.setPrice(openAction.getPrice());
            order.setStopPriceProfit(openAction.getStop_price_profit());
            order.setStopPriceLoss(openAction.getStop_price_loss());
            order.setOrderPriceType(openAction.getPrice_type());
            order.setState(ContractApplyOrder.STATE_SUBMITTED);
            this.contractApplyOrderService.saveCreate(order);
            // 创建新的合约申请订单
            createContractApplyOrder(openAction, partyId);
        } catch (YamiShopBindException e) {
            log.error("错误信息: {}", e.getMessage(), e);
            throw e; // 重新抛出自定义异常
        } catch (Exception e) {
           log.error("下单失败" , e);
            return Result.failed(e.getMessage());
            log.error("系统异常: {}", e.getMessage(), e);
            throw new YamiShopBindException("Operation failed, please try again later");
        } finally {
            rLock.unlock();
            // 确保释放锁
            if (lockAcquired && rLock.isHeldByCurrentThread()) {
                rLock.unlock();
            }
        }
        return Result.succeed(null,"ok");
        return Result.succeed(null, "ok");
    }
    // 校验合约订单状态
    private void checkContractOrderStatus(OpenAction openAction, String partyId) {
        LambdaQueryWrapper<ContractOrder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ContractOrder::getPartyId, partyId);
        wrapper.eq(ContractOrder::getState, "submitted");
        wrapper.eq(ContractOrder::getLocationType, openAction.getLocationType() == 0 ? 1 : 0);
        List<ContractOrder> list = contractOrderService.list(wrapper);
        if (CollectionUtil.isNotEmpty(list)) {
            String errorMessage = openAction.getLocationType() == 0 ?
                    "下单失败,当前持有全仓仓位,不支持逐仓下单!" :
                    "下单失败,当前持有逐仓仓位,不支持全仓下单!";
            throw new YamiShopBindException(errorMessage);
        }
    }
    // 校验用户状态
    private void checkUserStatus(String partyId) {
        User user = userService.getById(partyId);
        if (!user.isEnabled()) {
            throw new YamiShopBindException("User is locked");
        }
    }
    // 校验用户网络限制
    private void checkUserNetworkRestriction(String partyId) {
        Syspara syspara = sysparaService.find("stop_user_internet");
        String stopUserInternet = syspara.getSvalue();
        if (StringUtils.isNotEmpty(stopUserInternet)) {
            String[] stopUsers = stopUserInternet.split(",");
            User user = userService.getById(partyId);
            if (Arrays.asList(stopUsers).contains(user.getUserName())) {
                throw new YamiShopBindException("No network connection");
            }
        }
    }
    // 创建合约申请订单
    private void createContractApplyOrder(OpenAction openAction, String partyId) {
        ContractApplyOrder order = new ContractApplyOrder();
        order.setPartyId(partyId);
        order.setSymbol(openAction.getSymbol());
        order.setDirection(openAction.getDirection());
        order.setOffset(ContractApplyOrder.OFFSET_OPEN);
//        order.setVolume(openAction.getAmount());
//        order.setVolumeOpen(openAction.getAmount());
        order.setLeverRate(openAction.getLever_rate());
        order.setPrice(openAction.getPrice());
        order.setStopPriceProfit(openAction.getStop_price_profit());
        order.setStopPriceLoss(openAction.getStop_price_loss());
        order.setOrderPriceType(openAction.getPrice_type());
        order.setState(ContractApplyOrder.STATE_SUBMITTED);
        order.setMoney(openAction.getAmount());
        order.setLocationType(openAction.getLocationType());
        contractApplyOrderService.saveCreate(order);
    }
    /**
@@ -265,12 +312,12 @@
        RLock rLock = redissonClient.getLock("contract_close_" + partyId);
        boolean lockResult = rLock.tryLock(5, TimeUnit.SECONDS);
        if (!lockResult) {
            throw new YamiShopBindException("请稍后再试");
            throw new YamiShopBindException("Please try again later");
        }
        try {
            User user = userService.getById(partyId);
            if (!user.isEnabled()) {
                throw new YamiShopBindException("用户已锁定");
                throw new YamiShopBindException("User is locked");
            }
            Syspara syspara = sysparaService.find("stop_user_internet");
@@ -282,7 +329,7 @@
                System.out.println("stopUserInternet = " + stopUserInternet);
                if(Arrays.asList(stopUsers).contains(user.getUserName())){
                    throw new YamiShopBindException("无网络");
                    throw new YamiShopBindException("No network connection");
                }
            }
@@ -290,7 +337,7 @@
            order.setPartyId(partyId);
            order.setSymbol(closeAction.getSymbol());
            order.setDirection(closeAction.getDirection());
            order.setOffset(ContractApplyOrder.OFFSET_OPEN);
            order.setOffset(ContractApplyOrder.OFFSET_CLOSE);
            order.setVolume(closeAction.getAmount());
            order.setVolumeOpen(closeAction.getAmount());
            order.setPrice(closeAction.getPrice());
@@ -353,7 +400,7 @@
        ContractApplyOrder order = this.contractApplyOrderService.findByOrderNo(order_no);
        if (order == null) {
            throw new YamiShopBindException("委托单不存在");
            throw new YamiShopBindException("Order does not exist");
        }
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("order_no", order.getOrderNo());
@@ -402,7 +449,7 @@
        } catch (Exception e) {
            log.error("执行撤单异常", e);
            throw new YamiShopBindException("执行撤单异常");
            throw new YamiShopBindException("Failed to cancel order");
        }
        return Result.succeed(null,"success");
@@ -420,7 +467,7 @@
        } catch (Exception e) {
            log.error("执行撤单异常", e);
            throw new YamiShopBindException("执行撤单异常");
            throw new YamiShopBindException("Failed to cancel order");
        }
        return Result.succeed(null,"success");
@@ -511,10 +558,10 @@
        Page<ContractApplyOrder> result = contractApplyOrderService.findList(page, SecurityUtils.getUser().getUserId(), type,  symbolType);
        List<ContractApplyOrder> datas = result.getRecords();
        if (!StringUtils.isInteger(page_no)) {
            throw new YamiShopBindException("页码不是整数");
            throw new YamiShopBindException("Page number must be an integer");
        }
        if (Integer.valueOf(page_no).intValue() <= 0) {
            throw new YamiShopBindException("页码不能小于等于0");
            throw new YamiShopBindException("Page number must be greater than 0");
        }
        Long count = 0L;