From 3d8c9b6f4455b4efd34812c8e66073bebfacfce7 Mon Sep 17 00:00:00 2001
From: zj <1772600164@qq.com>
Date: Fri, 05 Jun 2026 11:20:23 +0800
Subject: [PATCH] 1

---
 trading-order-service/src/main/java/com/yami/trading/service/future/FuturesOrderService.java |  135 +++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 130 insertions(+), 5 deletions(-)

diff --git a/trading-order-service/src/main/java/com/yami/trading/service/future/FuturesOrderService.java b/trading-order-service/src/main/java/com/yami/trading/service/future/FuturesOrderService.java
index d47f294..8a03f51 100644
--- a/trading-order-service/src/main/java/com/yami/trading/service/future/FuturesOrderService.java
+++ b/trading-order-service/src/main/java/com/yami/trading/service/future/FuturesOrderService.java
@@ -2,7 +2,9 @@
 
 import cn.hutool.core.collection.CollectionUtil;
 import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -11,10 +13,7 @@
 import com.yami.trading.bean.future.dto.TFuturesOrderDTO;
 import com.yami.trading.bean.future.query.FuturesOrderQuery;
 import com.yami.trading.bean.item.domain.Item;
-import com.yami.trading.bean.model.Log;
-import com.yami.trading.bean.model.User;
-import com.yami.trading.bean.model.UserRecom;
-import com.yami.trading.bean.model.Wallet;
+import com.yami.trading.bean.model.*;
 import com.yami.trading.bean.syspara.domain.Syspara;
 import com.yami.trading.common.constants.Constants;
 import com.yami.trading.common.constants.TipConstants;
@@ -22,6 +21,7 @@
 import com.yami.trading.common.exception.YamiShopBindException;
 import com.yami.trading.common.util.*;
 import com.yami.trading.dao.future.FuturesOrderMapper;
+import com.yami.trading.service.CapitaltWalletService;
 import com.yami.trading.service.WalletService;
 import com.yami.trading.service.data.DataService;
 import com.yami.trading.service.item.ItemService;
@@ -85,6 +85,9 @@
     private TipService tipService;
     @Autowired
     private UserDataService userDataService;
+
+    @Autowired
+    CapitaltWalletService capitaltWalletService;
 
     @Autowired
     private ProfitLossConfigService profitLossConfigService;
@@ -252,6 +255,84 @@
     }
 
     /**
+     * 修改持仓订单方向(买涨/买跌)
+     */
+    public String saveOrderDirection(String orderNo, String direction, String operaName) {
+        if (!FuturesOrder.DIRECTION_BUY.equals(direction) && !FuturesOrder.DIRECTION_SELL.equals(direction)) {
+            return "方向参数错误";
+        }
+        String message = "";
+        boolean lock = false;
+        while (true) {
+            try {
+                if (!FuturesLock.add(orderNo)) {
+                    continue;
+                }
+                lock = true;
+
+                FuturesOrder futuresOrder = (FuturesOrder) RedisUtil.get(FuturesRedisKeys.FUTURES_SUBMITTED_ORDERNO + orderNo);
+                if (futuresOrder == null) {
+                    futuresOrder = getOne(new LambdaQueryWrapper<FuturesOrder>()
+                            .eq(FuturesOrder::getOrderNo, orderNo)
+                            .eq(FuturesOrder::getState, FuturesOrder.STATE_SUBMITTED));
+                }
+                if (futuresOrder == null) {
+                    message = "订单已结算或不存在";
+                    break;
+                }
+                if (direction.equals(futuresOrder.getDirection())) {
+                    message = "方向未变化";
+                    break;
+                }
+
+                Map<String, Double> futuresAssetsOld = this.walletService.getMoneyFuturesByOrder(futuresOrder);
+                String oldDirection = futuresOrder.getDirection();
+                futuresOrder.setDirection(direction);
+
+                List<Realtime> realtimeList = this.dataService.realtime(futuresOrder.getSymbol());
+                if (CollectionUtil.isNotEmpty(realtimeList) && realtimeList.get(0).getClose() != null) {
+                    refreshCache(futuresOrder, realtimeList.get(0).getClose().doubleValue());
+                } else {
+                    RedisUtil.set(FuturesRedisKeys.FUTURES_SUBMITTED_ORDERNO + futuresOrder.getOrderNo(), futuresOrder);
+                    cache.put(futuresOrder.getOrderNo(), futuresOrder);
+                    updateById(futuresOrder);
+                }
+
+                Map<String, Double> futuresAssetsOrder = this.walletService.getMoneyFuturesByOrder(futuresOrder);
+                Double futuresAssets = (Double) RedisUtil.get(FuturesRedisKeys.FUTURES_ASSETS_PARTY_ID + futuresOrder.getPartyId());
+                Double futuresAssetsProfit = (Double) RedisUtil.get(FuturesRedisKeys.FUTURES_ASSETS_PROFIT_PARTY_ID + futuresOrder.getPartyId());
+                RedisUtil.set(FuturesRedisKeys.FUTURES_ASSETS_PARTY_ID + futuresOrder.getPartyId(),
+                        Arith.add(null == futuresAssets ? 0.000D : futuresAssets, futuresAssetsOrder.get("money_futures") - futuresAssetsOld.get("money_futures")));
+                RedisUtil.set(FuturesRedisKeys.FUTURES_ASSETS_PROFIT_PARTY_ID + futuresOrder.getPartyId(),
+                        Arith.add(null == futuresAssetsProfit ? 0.000D : futuresAssetsProfit, futuresAssetsOrder.get("money_futures_profit") - futuresAssetsOld.get("money_futures_profit")));
+
+                User party = userService.getById(futuresOrder.getPartyId());
+                String oldDirLabel = FuturesOrder.DIRECTION_BUY.equals(oldDirection) ? "买涨" : "买跌";
+                String newDirLabel = FuturesOrder.DIRECTION_BUY.equals(direction) ? "买涨" : "买跌";
+                Log log = new Log();
+                log.setCategory(Constants.LOG_CATEGORY_OPERATION);
+                log.setOperator(operaName);
+                log.setUsername(party.getUserName());
+                log.setUserId(party.getUserId());
+                log.setCreateTime(new Date());
+                log.setLog("管理员手动修改交割订单方向。订单号[" + futuresOrder.getOrderNo() + "],原方向[" + oldDirLabel + "],修改后方向[" + newDirLabel + "].");
+                this.logService.save(log);
+                updateById(futuresOrder);
+                ThreadUtils.sleep(100);
+            } catch (Throwable e) {
+                log.error("saveOrderDirection error:", e);
+                message = "修改错误";
+            } finally {
+                if (lock) {
+                    FuturesLock.remove(orderNo);
+                    break;
+                }
+            }
+        }
+        return message;
+    }
+
+    /**
      * 业绩交易奖励
      */
     public void saveRecomProfit(String partyId, BigDecimal volume) {
@@ -314,6 +395,7 @@
         if (futuresPara.getUnitMaxAmount().doubleValue() > 0 && futuresOrder.getVolume() > futuresPara.getUnitMaxAmount().doubleValue()) {
             throw new BusinessException("金额不在购买区间");
         }
+
         checkSubmitOrder(futuresOrder.getPartyId().toString(), futuresPara);
 
         futuresOrder.setOrderNo(DateUtil.getToday("yyMMddHHmmss") + RandomUtil.getRandomNum(8));
@@ -361,6 +443,7 @@
         // 钱包扣费
         walletService.updateMoney(futuresOrder.getSymbol(), futuresOrder.getPartyId(), moneyCost, BigDecimal.ZERO,
                 Constants.MONEYLOG_CATEGORY_CONTRACT, Constants.WALLET, Constants.DELIVERY_MONEYLOG_CONTENT_CONTRACT_OPEN, "交割合约,订单号[" + futuresOrder.getOrderNo() + "]");
+
         checkProfitAndLoss(futuresOrder);
         save(futuresOrder);
 
@@ -370,7 +453,6 @@
         if (Constants.SECURITY_ROLE_MEMBER.equals(party.getRoleName())) {
             tipService.saveTip(futuresOrder.getUuid().toString(), TipConstants.FUTURES_ORDER);
         }
-//		saveRecomProfit(futuresOrder.getPartyId().toString(),futuresOrder.getVolume());
         return futuresOrder;
     }
 
@@ -946,4 +1028,47 @@
         return map;
     }
 
+
+//    public static void main(String[] args) {
+//        BigDecimal balance = new BigDecimal("9772.9");     // 账户余额
+//        BigDecimal feeRate = new BigDecimal("0.0005");      // 手续费率(基于下单金额)
+//        BigDecimal price = new BigDecimal("1");     // 商品价格
+//        int leverage = 150;                              // 杠杆倍数
+//
+////        可购买数量=(余额 ÷ (1÷杠杆 + 费率))/杠杆
+//
+//
+//        // 1. 计算最大可下单金额(x)
+//        BigDecimal denominator = BigDecimal.ONE.divide(new BigDecimal(leverage), 10, RoundingMode.HALF_UP).add(feeRate);
+//        BigDecimal maxOrderAmount = balance.divide(denominator, 2, RoundingMode.FLOOR);
+//
+//        // 2. 计算可购买数量
+//        BigDecimal quantity = maxOrderAmount.divide(price, 0, RoundingMode.FLOOR);
+//        BigDecimal actualOrderAmount = quantity.multiply(price);
+//
+//        // 3. 计算费用
+//        BigDecimal margin = actualOrderAmount
+//                .divide(new BigDecimal(leverage), 2, RoundingMode.HALF_UP);
+//        BigDecimal fee = actualOrderAmount.multiply(feeRate).setScale(2, RoundingMode.HALF_UP);
+//        BigDecimal totalCost = margin.add(fee);
+//
+//        // 输出结果
+//        System.out.println("【输入参数】");
+//        System.out.printf("账户余额: %s 元\n", balance);
+//        System.out.printf("手续费率: %s%%\n", feeRate.multiply(new BigDecimal(100)));
+//        System.out.printf("商品价格: %s 元\n", price);
+//        System.out.printf("杠杆倍数: %d 倍\n\n", leverage);
+//
+//        System.out.println("【计算结果】");
+//        System.out.printf("理论最大可下单金额: %s 元\n", maxOrderAmount);
+//        System.out.printf("实际可购买数量: %s 份\n", quantity);
+//        System.out.printf("实际下单金额: %s 元\n", actualOrderAmount);
+//        System.out.println("--------------------------------");
+//        System.out.printf("保证金: %s 元\n", margin);
+//        System.out.printf("手续费: %s 元\n", fee);
+//        System.out.printf("总支出: %s 元\n", totalCost);
+//        System.out.printf("剩余余额: %s 元\n", balance.subtract(totalCost));
+//    }
+
+
 }

--
Gitblit v1.9.3