新版仿ok交易所-后端
1
zj
2025-09-07 e4174aed067985155c157f10b0c4294f18eb2359
1
3 files modified
136 ■■■■■ changed files
trading-order-service/src/main/java/com/yami/trading/service/contract/ContractLoadCacheService.java 131 ●●●●● patch | view | raw | blame | history
trading-order-service/src/main/java/com/yami/trading/service/impl/WalletServiceImpl.java 2 ●●● patch | view | raw | blame | history
trading-order-service/src/main/resources/mapper/contract/ContractOrderMapper.xml 3 ●●●● patch | view | raw | blame | history
trading-order-service/src/main/java/com/yami/trading/service/contract/ContractLoadCacheService.java
@@ -1,5 +1,6 @@
package com.yami.trading.service.contract;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yami.trading.bean.contract.domain.ContractOrder;
import com.yami.trading.common.constants.ContractRedisKeys;
import com.yami.trading.common.util.RedisUtil;
@@ -15,6 +16,9 @@
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@Slf4j
@Component
@@ -26,64 +30,107 @@
    @Autowired
    private ContractOrderService contractOrderService;
    private ScheduledExecutorService scheduler;
    public void load() {
        List<ContractOrder> list = contractOrderService.list();
        Map<String, Map<String, ContractOrder>> cacheMap = new ConcurrentHashMap<>();
        try {
            List<ContractOrder> list = contractOrderService.list(new LambdaQueryWrapper<>(ContractOrder.class).eq(ContractOrder::getState, "submitted"));
            Map<String, Map<String, ContractOrder>> cacheMap = new ConcurrentHashMap<>();
        // 永续合约:总资产、总保证金、总未实现盈利
        Map<String, Map<String, BigDecimal>> contractAssetsMap = new ConcurrentHashMap<>();
            // 永续合约:总资产、总保证金、总未实现盈利
            Map<String, Map<String, BigDecimal>> contractAssetsMap = new ConcurrentHashMap<>();
        for (ContractOrder order : list) {
            if (ContractOrder.STATE_SUBMITTED.equals(order.getState())) {
                if (cacheMap.containsKey(order.getPartyId())) {
                    Map<String, ContractOrder> map = cacheMap.get(order.getPartyId());
                    map.put(order.getOrderNo(), order);
                    cacheMap.put(order.getPartyId(), map);
                } else {
                    Map<String, ContractOrder> map = new ConcurrentHashMap<>();
                    map.put(order.getOrderNo(), order);
                    cacheMap.put(order.getPartyId(), map);
            for (ContractOrder order : list) {
                if (ContractOrder.STATE_SUBMITTED.equals(order.getState())) {
                    // 使用computeIfAbsent简化代码
                    Map<String, ContractOrder> orderMap = cacheMap.computeIfAbsent(
                            order.getPartyId(),
                            k -> new ConcurrentHashMap<>()
                    );
                    orderMap.put(order.getOrderNo(), order);
                    // 获取单个订单永续合约总资产、总保证金、总未实现盈利
                    Map<String, BigDecimal> contractAssetsOrder = this.walletService.getMoneyContractByOrder(order);
                    // 处理资产数据
                    contractAssetsMap.compute(order.getPartyId(), (k, v) -> {
                        if (v == null) {
                            v = new HashMap<>();
                            v.put("money_contract", BigDecimal.ZERO);
                            v.put("money_contract_deposit", BigDecimal.ZERO);
                            v.put("money_contract_profit", BigDecimal.ZERO);
                        }
                        // 安全地添加值
                        v.put("money_contract", safeAdd(v.get("money_contract"), contractAssetsOrder.get("money_contract")));
                        v.put("money_contract_deposit", safeAdd(v.get("money_contract_deposit"), contractAssetsOrder.get("money_contract_deposit")));
                        v.put("money_contract_profit", safeAdd(v.get("money_contract_profit"), contractAssetsOrder.get("money_contract_profit")));
                        return v;
                    });
                }
                // 获取 单个订单 永续合约总资产、总保证金、总未实现盈利
                Map<String, BigDecimal> contractAssetsOrder = this.walletService.getMoneyContractByOrder(order);
                if (contractAssetsMap.containsKey(order.getPartyId())) {
                    Map<String, BigDecimal> contractAssetsOld = contractAssetsMap.get(order.getPartyId());
                    if (null == contractAssetsOld) {
                        contractAssetsOld = new HashMap<>();
                        contractAssetsOld.put("money_contract", BigDecimal.ZERO);
                        contractAssetsOld.put("money_contract_deposit", BigDecimal.ZERO);
                        contractAssetsOld.put("money_contract_profit", BigDecimal.ZERO);
                    }
                    contractAssetsOld.put("money_contract", contractAssetsOld.get("money_contract").add(contractAssetsOrder.get("money_contract")));
                    contractAssetsOld.put("money_contract_deposit", contractAssetsOld.get("money_contract_deposit").add(contractAssetsOrder.get("money_contract_deposit")));
                    contractAssetsOld.put("money_contract_profit", contractAssetsOld.get("money_contract_profit").add(contractAssetsOrder.get("money_contract_profit")));
                    contractAssetsMap.put(order.getPartyId(), contractAssetsOld);
                } else {
                    contractAssetsMap.put(order.getPartyId(), contractAssetsOrder);
                }
                RedisUtil.set(ContractRedisKeys.CONTRACT_ORDERNO + order.getOrderNo(), order);
            }
            RedisUtil.set(ContractRedisKeys.CONTRACT_ORDERNO + order.getOrderNo(), order);
        }
            for (Map.Entry<String, Map<String, ContractOrder>> entry : cacheMap.entrySet()) {
                RedisUtil.set(ContractRedisKeys.CONTRACT_SUBMITTED_ORDER_PARTY_ID + entry.getKey(), entry.getValue());
            }
        for (Map.Entry<String, Map<String, ContractOrder>> entry : cacheMap.entrySet()) {
            RedisUtil.set(ContractRedisKeys.CONTRACT_SUBMITTED_ORDER_PARTY_ID + entry.getKey(), entry.getValue());
        }
            for (Map.Entry<String, Map<String, BigDecimal>> entry : contractAssetsMap.entrySet()) {
                RedisUtil.set(ContractRedisKeys.CONTRACT_ASSETS_PARTY_ID + entry.getKey(), entry.getValue().get("money_contract"));
                RedisUtil.set(ContractRedisKeys.CONTRACT_ASSETS_DEPOSIT_PARTY_ID + entry.getKey(), entry.getValue().get("money_contract_deposit"));
                RedisUtil.set(ContractRedisKeys.CONTRACT_ASSETS_PROFIT_PARTY_ID + entry.getKey(), entry.getValue().get("money_contract_profit"));
            }
        for (Map.Entry<String, Map<String, BigDecimal>> entry : contractAssetsMap.entrySet()) {
            RedisUtil.set(ContractRedisKeys.CONTRACT_ASSETS_PARTY_ID + entry.getKey(), entry.getValue().get("money_contract"));
            RedisUtil.set(ContractRedisKeys.CONTRACT_ASSETS_DEPOSIT_PARTY_ID + entry.getKey(), entry.getValue().get("money_contract_deposit"));
            RedisUtil.set(ContractRedisKeys.CONTRACT_ASSETS_PROFIT_PARTY_ID + entry.getKey(), entry.getValue().get("money_contract_profit"));
            log.info("ContractOrder数据更新到Redis完成");
        } catch (Exception e) {
            log.error("更新ContractOrder数据到Redis失败", e);
        }
    }
    // 安全添加BigDecimal值
    private BigDecimal safeAdd(BigDecimal a, BigDecimal b) {
        if (a == null) a = BigDecimal.ZERO;
        if (b == null) b = BigDecimal.ZERO;
        return a.add(b);
    }
    @Override
    public void run(ApplicationArguments args) {
        log.info("开始ContractOrder数据加载redis");
        // 创建单线程调度器
        scheduler = Executors.newSingleThreadScheduledExecutor();
        // 初始加载
        load();
        log.info("完成ContractOrder数据加载redis");
        // 每隔5秒执行一次更新
        scheduler.scheduleAtFixedRate(() -> {
            try {
                load();
            } catch (Exception e) {
                log.error("定时更新ContractOrder数据失败", e);
            }
        }, 5, 5, TimeUnit.SECONDS);
        log.info("已启动ContractOrder数据定时更新,每5秒一次");
    }
    // 添加销毁方法以关闭调度器
    public void destroy() {
        if (scheduler != null && !scheduler.isShutdown()) {
            scheduler.shutdown();
            try {
                if (!scheduler.awaitTermination(5, TimeUnit.SECONDS)) {
                    scheduler.shutdownNow();
                }
            } catch (InterruptedException e) {
                scheduler.shutdownNow();
                Thread.currentThread().interrupt();
            }
            log.info("ContractOrder数据更新调度器已关闭");
        }
    }
}
trading-order-service/src/main/java/com/yami/trading/service/impl/WalletServiceImpl.java
@@ -456,7 +456,7 @@
        data.put("money_all_coin", df2.format(money_all_coin));
        data.put("money_miner", df2.format(money_miner));
        data.put("money_finance", df2.format(money_finance));
        data.put("money_contract", df2.format(Arith.add(money_contract, money_contractApply)));
        data.put("money_contract", df2.format(Arith.add(money_contract_deposit, money_contractApply)));
        data.put("money_contract_deposit", df2.format(money_contract_deposit));
        data.put("money_contract_profit", df2.format(money_contract_profit));
        data.put("money_futures", df2.format(money_futures));
trading-order-service/src/main/resources/mapper/contract/ContractOrderMapper.xml
@@ -41,7 +41,7 @@
    <select id="listRecord" resultType="com.yami.trading.bean.contract.dto.ContractOrderDTO">
        select *,b.role_name AS "roleName",b.user_code AS "userCode",c.money,item.name AS "symbolName" from t_contract_order a
        select a.*,b.role_name AS "roleName",b.user_code AS "userCode",c.money,item.name AS "symbolName" from t_contract_order a
        left join tz_user b on a.PARTY_ID = b.user_id
        left join tz_wallet c ON c.user_id = b.user_id
        left join t_item item on a.symbol = item.SYMBOL
@@ -86,6 +86,7 @@
                #{query.userName}, '%'))
            </if>
        </where>
        GROUP BY a.order_no
        order by a.create_time desc
    </select>