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);