From 896d14b328059863b5cc668dfc6c1d375f59de59 Mon Sep 17 00:00:00 2001
From: liusheng <337615773@qq.com>
Date: 星期二, 24 二月 2026 14:42:06 +0800
Subject: [PATCH] 代码提交

---
 ruoyi-project/src/main/java/com/ruoyi/project/utils/DingTalkProxyClient.java |  206 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 206 insertions(+), 0 deletions(-)

diff --git a/ruoyi-project/src/main/java/com/ruoyi/project/utils/DingTalkProxyClient.java b/ruoyi-project/src/main/java/com/ruoyi/project/utils/DingTalkProxyClient.java
new file mode 100644
index 0000000..0082181
--- /dev/null
+++ b/ruoyi-project/src/main/java/com/ruoyi/project/utils/DingTalkProxyClient.java
@@ -0,0 +1,206 @@
+package com.ruoyi.project.utils;
+
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
+import com.ruoyi.common.utils.http.HttpUtils;
+import com.taobao.api.ApiException;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 閽夐拤API浠g悊瀹㈡埛绔�
+ * 閫氳繃Nginx浠g悊璁块棶閽夐拤API锛岃В鍐冲唴缃戣闂缃戠殑闂
+ *
+ * @author 
+ * @date 2025-01-01
+ */
+@Slf4j
+@Component
+public class DingTalkProxyClient {
+
+    @Value("${dingtalk.proxy.enabled:false}")
+    private boolean proxyEnabled;
+
+    @Value("${dingtalk.proxy.url:https://oapi.dingtalk.com}")
+    private String proxyUrl;
+
+    @Value("${dingAppid}")
+    private String dingAppid;
+
+    @Value("${dingAppSecret}")
+    private String dingAppSecret;
+
+    private String cachedAccessToken;
+    private long tokenExpireTime;
+
+    /**
+     * 鑾峰彇璁块棶浠ょ墝
+     */
+    public String getAccessToken() throws ApiException {
+        // 妫�鏌ョ紦瀛樼殑token鏄惁浠嶇劧鏈夋晥锛堥鐣�30绉掔紦鍐叉椂闂达級
+        if (cachedAccessToken != null && System.currentTimeMillis() < tokenExpireTime - 30000) {
+            return cachedAccessToken;
+        }
+
+        String url;
+        if (proxyEnabled) {
+            url = proxyUrl + "/gettoken";
+        } else {
+            url = "https://oapi.dingtalk.com/gettoken";
+        }
+
+        Map<String, String> params = new HashMap<>();
+        params.put("appkey", dingAppid);
+        params.put("appsecret", dingAppSecret);
+        params.put("grant_type", "client_credentials");
+
+        String paramString = buildParamString(params);
+        String response = HttpUtils.sendGet(url, paramString);
+        JSONObject result = JSON.parseObject(response);
+
+        if (result.getInteger("errcode") == 0) {
+            cachedAccessToken = result.getString("access_token");
+            // token閫氬父鏈夋晥鏈熶负7200绉掞紝杩欓噷璁剧疆涓�7000绉掑悗杩囨湡
+            tokenExpireTime = System.currentTimeMillis() + 7000 * 1000L;
+            return cachedAccessToken;
+        } else {
+            throw new ApiException("鑾峰彇閽夐拤璁块棶浠ょ墝澶辫触: " + result.getString("errmsg"));
+        }
+    }
+
+    /**
+     * 灏哅ap鍙傛暟杞崲涓篣RL缂栫爜鐨勫瓧绗︿覆
+     */
+    private String buildParamString(Map<String, String> params) {
+        StringBuilder paramString = new StringBuilder();
+        if (params != null) {
+            for (Map.Entry<String, String> entry : params.entrySet()) {
+                if (paramString.length() > 0) {
+                    paramString.append("&");
+                }
+                try {
+                    paramString.append(URLEncoder.encode(entry.getKey(), "UTF-8"))
+                            .append("=")
+                            .append(URLEncoder.encode(entry.getValue() != null ? entry.getValue() : "", "UTF-8"));
+                } catch (UnsupportedEncodingException e) {
+                    // 杩欑鎯呭喌涓嶅簲璇ュ彂鐢燂紝鍥犱负UTF-8鏄爣鍑嗙紪鐮�
+                    paramString.append(entry.getKey())
+                            .append("=")
+                            .append(entry.getValue() != null ? entry.getValue() : "");
+                }
+            }
+        }
+        return paramString.toString();
+    }
+
+    /**
+     * 鎵цGET璇锋眰
+     */
+    public String executeGet(String apiPath, Map<String, String> params) throws ApiException {
+        String url;
+        if (proxyEnabled) {
+            url = proxyUrl + apiPath;
+        } else {
+            url = "https://oapi.dingtalk.com" + apiPath;
+        }
+
+        String paramString = buildParamString(params);
+        return HttpUtils.sendGet(url, paramString);
+    }
+
+    /**
+     * 鎵цPOST璇锋眰锛屾敮鎸丣SON Content-Type
+     */
+    public String executePost(String apiPathWithParams, String params) throws ApiException {
+        String url;
+        if (proxyEnabled) {
+            url = proxyUrl + apiPathWithParams;
+        } else {
+            url = "https://oapi.dingtalk.com" + apiPathWithParams;
+        }
+
+        return sendJsonPost(url, params);
+    }
+
+    /**
+     * 鍙戦�丣SON鏍煎紡鐨凱OST璇锋眰
+     */
+    private String sendJsonPost(String url, String jsonData) throws ApiException {
+        HttpURLConnection connection = null;
+        try {
+            URL obj = new URL(url);
+            connection = (HttpURLConnection) obj.openConnection();
+
+            // 璁剧疆璇锋眰鏂规硶
+            connection.setRequestMethod("POST");
+
+            // 璁剧疆璇锋眰澶�
+            connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
+            connection.setRequestProperty("Accept", "application/json");
+            connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36");
+
+            // 鍙戦�丳OST璇锋眰
+            connection.setDoOutput(true);
+            try (OutputStream os = connection.getOutputStream()) {
+                byte[] input = jsonData.getBytes("utf-8");
+                os.write(input, 0, input.length);
+            }
+
+            // 璇诲彇鍝嶅簲
+            int responseCode = connection.getResponseCode();
+            StringBuilder response = new StringBuilder();
+            try (BufferedReader br = new BufferedReader(
+                    new InputStreamReader(connection.getInputStream(), "utf-8"))) {
+                String responseLine;
+                while ((responseLine = br.readLine()) != null) {
+                    response.append(responseLine.trim());
+                }
+            }
+
+            return response.toString();
+        } catch (Exception e) {
+            throw new ApiException("POST璇锋眰澶辫触: " + e.getMessage());
+        } finally {
+            if (connection != null) {
+                connection.disconnect();
+            }
+        }
+    }
+
+    /**
+     * 鎵ц甯﹁闂护鐗岀殑GET璇锋眰
+     */
+    public String executeGetWithToken(String apiPath, Map<String, String> params) throws ApiException {
+        if (params == null) {
+            params = new HashMap<>();
+        }
+        params.put("access_token", getAccessToken());
+        return executeGet(apiPath, params);
+    }
+
+    /**
+     * 鎵ц甯﹁闂护鐗岀殑POST璇锋眰
+     */
+    public String executePostWithToken(String apiPath, String params) throws ApiException {
+        String fullParams;
+        if (params.contains("access_token=")) {
+            fullParams = params;
+        } else {
+            // 瀵逛簬JSON鏍煎紡鐨勮姹備綋锛宎ccess_token搴旇宸茬粡鍖呭惈鍦╬arams涓�
+            fullParams = params;
+        }
+        return executePost(apiPath, fullParams);
+    }
+
+    public boolean isProxyEnabled() {
+        return proxyEnabled;
+    }
+}
\ No newline at end of file

--
Gitblit v1.9.3