From d663147264d0fc97e9e7ddbd4aeee69e833ad025 Mon Sep 17 00:00:00 2001
From: Administrator <15274802129@163.com>
Date: Tue, 02 Jun 2026 15:14:02 +0800
Subject: [PATCH] fix(okxNewPrice): 修复合约面值配置错误并更新文档
---
src/main/java/com/xcong/excoin/utils/dingtalk/DingTalkUtils.java | 181 ++++++++++++++++++++++++++++++++++++--------
1 files changed, 147 insertions(+), 34 deletions(-)
diff --git a/src/main/java/com/xcong/excoin/utils/dingtalk/DingTalkUtils.java b/src/main/java/com/xcong/excoin/utils/dingtalk/DingTalkUtils.java
index 70ed481..ae08d82 100644
--- a/src/main/java/com/xcong/excoin/utils/dingtalk/DingTalkUtils.java
+++ b/src/main/java/com/xcong/excoin/utils/dingtalk/DingTalkUtils.java
@@ -1,6 +1,5 @@
package com.xcong.excoin.utils.dingtalk;
-import com.alibaba.fastjson.JSONObject;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiRobotSendRequest;
@@ -15,53 +14,167 @@
import java.util.List;
/**
+ * 钉钉群机器人消息发送工具。
+ *
+ * <h3>快速使用</h3>
+ * <pre>
+ * // 1. 创建发送器
+ * DingTalkRobot robot = new DingTalkRobot(accessToken, secret);
+ *
+ * // 2a. 发送文本
+ * robot.sendText("充值到账:1000 USDT");
+ *
+ * // 2b. 发送 Markdown(title 会作为 @所有人 通知标题)
+ * robot.sendMarkdown("策略通知", "## 盈亏汇总\n- 已实现: **+2.5 USDT**");
+ *
+ * // 2c. 发送 ActionCard
+ * robot.sendActionCard("止盈通知", "策略已达止盈目标", "查看详情", "https://xxx.com");
+ * </pre>
+ *
* @author wzy
- * @date 2020-04-17 22:18
- **/
+ */
@Slf4j
public class DingTalkUtils {
- private static final String SECRET = "SECc0b73559742b950f07eabbd050c406a6abb3b67d112d3735289e90f58884c543";
+ private static final String ROBOT_URL = "https://oapi.dingtalk.com/robot/send?access_token=";
- public static void sendActionCard(int type) {
- log.info("send dingtalk");
- String url = "https://oapi.dingtalk.com/robot/send?access_token=161d5e5b60ae5d6b4c80f2a9c35f9f212961a7c7154aa7e94b99503eca3886b0";
- Long timestamp = System.currentTimeMillis();
+ private final String accessToken;
+ private final String secret;
+
+ // ==================== 默认实例(向后兼容旧代码) ====================
+
+ private static volatile DingTalkUtils DEFAULT;
+
+ public static DingTalkUtils getDefault() {
+ if (DEFAULT == null) {
+ synchronized (DingTalkUtils.class) {
+ if (DEFAULT == null) {
+ DEFAULT = new DingTalkUtils(
+ "57a3e695f78d7547fe20fb7aef82cf35a27de1846bbc6966e0194761976d7597",
+ "SECd59a93c8939eeaef0d97b5b714639df4af95d922002d0a440bc82ad42710a89e");
+// DEFAULT = new DingTalkUtils(
+// "e357a3417991da86a5f79ea5bc8785b529c1da8b9d27458febed3b3d10c857c4",
+// "SECf2b819e930cb4b367cf599f11a30eb8a5d0f4b0b1c069a57aa15328a3feebf8c");
+ }
+ }
+ }
+ return DEFAULT;
+ }
+
+ /**
+ * 向后兼容:按类型代码发送 ActionCard 通知。
+ *
+ * @param typeIndex {@link DingTalkType} 的 index
+ */
+ public static void sendActionCard(int typeIndex) {
+ DingTalkType dt = DingTalkType.byIndex(typeIndex);
+ if (dt == null) {
+ log.warn("[DingTalk] 未知通知类型: {}", typeIndex);
+ return;
+ }
+ getDefault().sendActionCard(dt.getName(), dt.getName(), "查看详情", "http://baidu.com");
+ }
+
+ // ==================== 构造 ====================
+
+ /**
+ * @param accessToken 钉钉机器人 Webhook 地址中的 access_token
+ * @param secret 钉钉机器人安全设置中的加签密钥
+ */
+ public DingTalkUtils(String accessToken, String secret) {
+ this.accessToken = accessToken;
+ this.secret = secret;
+ }
+
+ // ==================== 文本消息 ====================
+
+ /**
+ * 发送纯文本消息。
+ *
+ * @param content 文本内容,最大 4096 字节,支持 @手机号 提醒
+ */
+ public void sendText(String content) {
+ OapiRobotSendRequest req = new OapiRobotSendRequest();
+ req.setMsgtype("text");
+ OapiRobotSendRequest.Text text = new OapiRobotSendRequest.Text();
+ text.setContent(content);
+ req.setText(text);
+ execute(req);
+ }
+
+ // ==================== Markdown 消息 ====================
+
+ /**
+ * 发送 Markdown 消息。
+ *
+ * @param title 消息标题,显示在会话列表和推送通知中
+ * @param markdown Markdown 正文,支持标题/加粗/链接/列表等语法
+ */
+ public void sendMarkdown(String title, String markdown) {
+ OapiRobotSendRequest req = new OapiRobotSendRequest();
+ req.setMsgtype("markdown");
+ OapiRobotSendRequest.Markdown md = new OapiRobotSendRequest.Markdown();
+ md.setTitle(title);
+ md.setText(markdown);
+ req.setMarkdown(md);
+ execute(req);
+ }
+
+ // ==================== ActionCard 消息 ====================
+
+ /**
+ * 发送单按钮 ActionCard 消息。
+ *
+ * @param title 卡片标题
+ * @param text 卡片正文(支持 Markdown,减号开头的行会被转为列表)
+ * @param btnTitle 按钮文字
+ * @param btnUrl 按钮跳转链接
+ */
+ public void sendActionCard(String title, String text, String btnTitle, String btnUrl) {
+ OapiRobotSendRequest req = new OapiRobotSendRequest();
+ req.setMsgtype("actionCard");
+ OapiRobotSendRequest.Actioncard card = new OapiRobotSendRequest.Actioncard();
+ card.setTitle(title);
+ card.setText(text);
+ card.setBtnOrientation("1");
+ List<OapiRobotSendRequest.Btns> btns = new ArrayList<>();
+ OapiRobotSendRequest.Btns btn = new OapiRobotSendRequest.Btns();
+ btn.setTitle(btnTitle);
+ btn.setActionURL(btnUrl);
+ btns.add(btn);
+ card.setBtns(btns);
+ req.setActionCard(card);
+ execute(req);
+ }
+
+ // ==================== 内部执行 ====================
+
+ private void execute(OapiRobotSendRequest request) {
try {
+ Long timestamp = System.currentTimeMillis();
String sign = generateSign(timestamp);
- url = url + "×tamp=" + timestamp + "&sign=" + sign;
+ String url = ROBOT_URL + accessToken + "×tamp=" + timestamp + "&sign=" + sign;
DingTalkClient client = new DefaultDingTalkClient(url);
- OapiRobotSendRequest request = new OapiRobotSendRequest();
- request.setMsgtype("actionCard");
- OapiRobotSendRequest.Actioncard actionCard = new OapiRobotSendRequest.Actioncard();
- actionCard.setTitle(DingTalkType.getName(type));
- actionCard.setBtnOrientation("1");
- actionCard.setText(DingTalkType.getName(type));
- List<OapiRobotSendRequest.Btns> btns = new ArrayList<>();
- OapiRobotSendRequest.Btns btn1 = new OapiRobotSendRequest.Btns();
- btn1.setTitle("查看详情");
- btn1.setActionURL("http://baidu.com");
- btns.add(btn1);
- actionCard.setBtns(btns);
-
- request.setActionCard(actionCard);
OapiRobotSendResponse response = client.execute(request);
- log.info(JSONObject.toJSONString(response));
+ if (!response.isSuccess()) {
+ log.warn("[DingTalk] 发送失败, errcode:{}, errmsg:{}", response.getErrcode(), response.getErrmsg());
+ } else {
+ log.info("[DingTalk] 发送成功");
+ }
} catch (Exception e) {
- log.error("#dingtalk send error#", e);
- } finally {
- log.error("#dingtalk finally#");
+ log.error("[DingTalk] 发送异常", e);
}
}
-
- private static String generateSign(Long timestamp) throws Exception {
- String stringToToken = timestamp + "\n" + SECRET;
+ private String generateSign(Long timestamp) throws Exception {
+ String stringToSign = timestamp + "\n" + secret;
Mac mac = Mac.getInstance("HmacSHA256");
- mac.init(new SecretKeySpec(SECRET.getBytes("UTF-8"), "HmacSHA256"));
- byte[] signData = mac.doFinal(stringToToken.getBytes("UTF-8"));
- String sign = URLEncoder.encode(new String(Base64.encodeBase64(signData)), "UTF-8");
- return sign;
+ mac.init(new SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA256"));
+ byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8"));
+ return URLEncoder.encode(new String(Base64.encodeBase64(signData)), "UTF-8");
}
+ public static void main(String[] args) {
+ DingTalkUtils.getDefault().sendActionCard("风险提示", "测试123", "", "");
+ }
}
--
Gitblit v1.9.1