From 1b6ed7538b05f1cdf99a27d229374e42f48310c2 Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 7 Jan 2026 09:42:43 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=92=89=E9=92=89=E5=8D=A1=E7=89=87?= =?UTF-8?q?=E6=B6=88=E6=81=AF=E4=BD=BF=E7=94=A8=E5=BA=94=E7=94=A8=E5=86=85?= =?UTF-8?q?=E8=B7=B3=E8=BD=AC=E9=93=BE=E6=8E=A5=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../designhub/service/DingTalkService.java | 51 ++++++++++++++++--- 1 file changed, 45 insertions(+), 6 deletions(-) diff --git a/backend/src/main/java/com/designhub/service/DingTalkService.java b/backend/src/main/java/com/designhub/service/DingTalkService.java index 67d0cf3..9a4150d 100644 --- a/backend/src/main/java/com/designhub/service/DingTalkService.java +++ b/backend/src/main/java/com/designhub/service/DingTalkService.java @@ -210,6 +210,43 @@ public class DingTalkService { return siteUrl; } + /** + * 构建钉钉应用内跳转链接 + * 格式: dingtalk://dingtalkclient/action/openapp?corpid=xxx&container_type=work_platform&app_id=0_xxx&redirect_type=jump&redirect_url=xxx + * @param config 钉钉配置 + * @param targetUrl 目标跳转地址 + * @return 钉钉应用内跳转链接 + */ + private String buildDingTalkAppLink(DingTalkConfig config, String targetUrl) { + try { + String corpId = config.getCorpId(); + String agentId = config.getAgentId(); + + // 如果没有配置corpId或agentId,回退到旧的跳转方式 + if (corpId == null || corpId.trim().isEmpty() || agentId == null || agentId.trim().isEmpty()) { + log.warn("钉钉corpId或agentId未配置,使用普通跳转链接"); + return "dingtalk://dingtalkclient/page/link?url=" + + URLEncoder.encode(targetUrl, StandardCharsets.UTF_8.toString()); + } + + // 构建钉钉应用内跳转链接 + // app_id 格式为 0_agentId + String appId = "0_" + agentId; + String encodedUrl = URLEncoder.encode(targetUrl, StandardCharsets.UTF_8.toString()); + + String dingTalkLink = String.format( + "dingtalk://dingtalkclient/action/openapp?corpid=%s&container_type=work_platform&app_id=%s&redirect_type=jump&redirect_url=%s", + corpId, appId, encodedUrl + ); + + log.debug("构建钉钉应用内跳转链接: {}", dingTalkLink); + return dingTalkLink; + } catch (Exception e) { + log.error("构建钉钉应用内跳转链接失败", e); + return targetUrl; + } + } + /** * 发送工作通知(卡片消息格式) * 用户点击卡片可跳转到官网 @@ -241,8 +278,10 @@ public class DingTalkService { String url = String.format("%s/topapi/message/corpconversation/asyncsend_v2?access_token=%s", DINGTALK_API_BASE, accessToken); - // 获取跳转链接 - String jumpUrl = (customUrl != null && !customUrl.trim().isEmpty()) ? customUrl : getSiteUrl(); + // 获取目标跳转地址 + String targetUrl = (customUrl != null && !customUrl.trim().isEmpty()) ? customUrl : getSiteUrl(); + // 构建钉钉应用内跳转链接 + String jumpUrl = buildDingTalkAppLink(config, targetUrl); // 构建卡片消息 Map msg = new HashMap<>(); @@ -254,8 +293,7 @@ public class DingTalkService { String markdown = "### " + title + "\n\n" + content + "\n\n---\n*点击下方按钮查看详情*"; actionCard.put("markdown", markdown); actionCard.put("single_title", "查看详情 »"); - actionCard.put("single_url", "dingtalk://dingtalkclient/page/link?url=" + - URLEncoder.encode(jumpUrl, StandardCharsets.UTF_8.toString())); + actionCard.put("single_url", jumpUrl); msg.put("action_card", actionCard); Map request = new HashMap<>(); @@ -321,8 +359,9 @@ public class DingTalkService { webhook = webhook + "×tamp=" + timestamp + "&sign=" + sign; } - // 获取官网地址 + // 获取官网地址并构建钉钉应用内跳转链接 String siteUrl = getSiteUrl(); + String jumpUrl = buildDingTalkAppLink(config, siteUrl); // 构建卡片消息(ActionCard格式) Map message = new HashMap<>(); @@ -346,7 +385,7 @@ public class DingTalkService { actionCard.put("markdown", markdownBuilder.toString()); actionCard.put("single_title", "查看详情 »"); - actionCard.put("single_url", siteUrl); + actionCard.put("single_url", jumpUrl); message.put("action_card", actionCard);