From 6a51f45e6a00b65a9e7b0b0707b453c11311f3ef Mon Sep 17 00:00:00 2001
From: Administrator <15274802129@163.com>
Date: Mon, 11 May 2026 22:38:13 +0800
Subject: [PATCH] feat(okxApi): 添加仓位模式配置和REST客户端功能

---
 src/main/java/com/xcong/excoin/modules/okxApi/OkxWsUtil.java |  132 ++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 132 insertions(+), 0 deletions(-)

diff --git a/src/main/java/com/xcong/excoin/modules/okxApi/OkxWsUtil.java b/src/main/java/com/xcong/excoin/modules/okxApi/OkxWsUtil.java
new file mode 100644
index 0000000..7e11158
--- /dev/null
+++ b/src/main/java/com/xcong/excoin/modules/okxApi/OkxWsUtil.java
@@ -0,0 +1,132 @@
+package com.xcong.excoin.modules.okxApi;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+import java.security.SecureRandom;
+import java.security.cert.X509Certificate;
+import java.text.SimpleDateFormat;
+import java.util.Base64;
+import java.util.Date;
+import java.util.Random;
+
+/**
+ * OKX API 工具类:SSL配置、HMAC-SHA256签名、订单ID生成、日期格式化、JSON构建。
+ *
+ * @author Administrator
+ */
+@Slf4j
+public final class OkxWsUtil {
+
+    private OkxWsUtil() {}
+
+    // ==================== SSL ====================
+
+    public static void configureSSL() {
+        try {
+            TrustManager[] trustAllCerts = new TrustManager[]{
+                    new X509TrustManager() {
+                        @Override
+                        public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; }
+                        @Override
+                        public void checkClientTrusted(X509Certificate[] certs, String authType) {}
+                        @Override
+                        public void checkServerTrusted(X509Certificate[] certs, String authType) {}
+                    }
+            };
+            SSLContext sc = SSLContext.getInstance("TLS");
+            sc.init(null, trustAllCerts, new SecureRandom());
+            SSLContext.setDefault(sc);
+        } catch (Exception e) {
+            log.error("SSL配置失败", e);
+        }
+    }
+
+    // ==================== HMAC-SHA256 签名 ====================
+
+    public static String signWebsocket(String timestamp, String secretKey) {
+        return sign(timestamp, "GET", "/users/self/verify", "", secretKey);
+    }
+
+    public static String signRest(String timestamp, String method, String path, String body, String secretKey) {
+        return sign(timestamp, method.toUpperCase(), path, body, secretKey);
+    }
+
+    private static String sign(String timestamp, String method, String path, String body, String secretKey) {
+        try {
+            String message = String.format("%s%s%s%s", timestamp, method, path, body);
+            Mac mac = Mac.getInstance("HmacSHA256");
+            SecretKeySpec spec = new SecretKeySpec(secretKey.getBytes("UTF-8"), "HmacSHA256");
+            mac.init(spec);
+            byte[] hash = mac.doFinal(message.getBytes("UTF-8"));
+            return Base64.getEncoder().encodeToString(hash);
+        } catch (Exception e) {
+            log.error("签名计算失败", e);
+            return "";
+        }
+    }
+
+    // ==================== 订单ID ====================
+
+    private static final ThreadLocal<SimpleDateFormat> ORDER_ID_DF =
+            ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyyMMddHHmmss"));
+
+    private static final ThreadLocal<Random> RANDOM =
+            ThreadLocal.withInitial(Random::new);
+
+    public static String getOrderNum(String prefix) {
+        String dd = ORDER_ID_DF.get().format(new Date());
+        if (prefix != null && !prefix.isEmpty()) {
+            return prefix + dd + getRandomNum(5);
+        }
+        return dd + getRandomNum(5);
+    }
+
+    private static String getRandomNum(int length) {
+        String str = "0123456789";
+        Random random = RANDOM.get();
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < length; ++i) {
+            sb.append(str.charAt(random.nextInt(str.length())));
+        }
+        return sb.toString();
+    }
+
+    // ==================== JSON构建 ====================
+
+    public static JSONObject buildJsonObject(String connId, String op, JSONArray args) {
+        JSONObject jsonObject = new JSONObject();
+        if (connId != null && !connId.isEmpty()) {
+            jsonObject.put("id", connId);
+        }
+        jsonObject.put("op", op);
+        jsonObject.put("args", args);
+        return jsonObject;
+    }
+
+    // ==================== 日期格式化 ====================
+
+    private static final ThreadLocal<SimpleDateFormat> DATE_TIME_DF =
+            ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
+
+    private static final ThreadLocal<SimpleDateFormat> ISO8601_DF =
+            ThreadLocal.withInitial(() -> {
+                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
+                sdf.setTimeZone(java.util.TimeZone.getTimeZone("UTC"));
+                return sdf;
+            });
+
+    public static String getIso8601Timestamp() {
+        return ISO8601_DF.get().format(new Date());
+    }
+
+    public static String timestampToDateTime(long timestamp) {
+        return DATE_TIME_DF.get().format(new Date(timestamp));
+    }
+}

--
Gitblit v1.9.1