From 32518311183c0021cd756d1963718ccefc018d95 Mon Sep 17 00:00:00 2001 From: ryan Date: Fri, 28 Aug 2026 10:30:52 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E9=92=89=E9=92=89=E9=80=9A=E7=9F=A5):=20?= =?UTF-8?q?=E5=A2=9E=E5=BC=BA=E6=A0=87=E9=A2=98=E7=94=9F=E6=88=90=E9=80=BB?= =?UTF-8?q?=E8=BE=91=E4=BB=A5=E4=BC=98=E5=85=88=E4=BD=BF=E7=94=A8=E5=86=85?= =?UTF-8?q?=E5=AE=B9=E9=A6=96=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changes: * 新增 dingtalkTitle 函数,优先使用内容的第一行作为标题,若内容为空则回退到默认标题 * 更新 Send 方法以使用新的标题生成逻辑 * 添加单元测试以验证标题生成的正确性 --- internal/adapter/dingtalk.go | 19 ++++++++++++++++++- internal/adapter/dingtalk_test.go | 16 +++++++++++++++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/internal/adapter/dingtalk.go b/internal/adapter/dingtalk.go index 7e5a467..426e827 100644 --- a/internal/adapter/dingtalk.go +++ b/internal/adapter/dingtalk.go @@ -69,7 +69,7 @@ func (s *DingTalkSender) Send(title, content string, config json.RawMessage) err msg := dingtalkMessage{ MsgType: "markdown", Markdown: &dingtalkMD{ - Title: title, + Title: dingtalkTitle(title, content), Text: dingtalkMarkdownText(content), }, } @@ -87,6 +87,23 @@ func (s *DingTalkSender) Send(title, content string, config json.RawMessage) err return nil } +// dingtalkTitle is the markdown.Title shown on DingTalk PC as the card header +// and in the session-list preview. Prefer the first content line (e.g. 空单开仓) +// over the internal "source: event" title. +func dingtalkTitle(fallback, content string) string { + content = strings.ReplaceAll(content, "\r\n", "\n") + content = strings.ReplaceAll(content, "\r", "\n") + line, _, _ := strings.Cut(content, "\n") + line = strings.TrimSpace(line) + if line != "" { + return line + } + if strings.TrimSpace(fallback) != "" { + return fallback + } + return "通知" +} + // dingtalkMarkdownText turns template newlines into DingTalk markdown paragraph // breaks. A single \n is collapsed to a space by DingTalk markdown, so each // logical line must be separated by \n\n. diff --git a/internal/adapter/dingtalk_test.go b/internal/adapter/dingtalk_test.go index bb00def..fe10830 100644 --- a/internal/adapter/dingtalk_test.go +++ b/internal/adapter/dingtalk_test.go @@ -2,6 +2,20 @@ package adapter import "testing" +func TestDingTalkTitleUsesFirstContentLine(t *testing.T) { + got := dingtalkTitle("trade-signal: trade", "空单开仓\n交易品种: ETHUSDT") + if got != "空单开仓" { + t.Fatalf("got %q", got) + } +} + +func TestDingTalkTitleFallsBackWhenContentEmpty(t *testing.T) { + got := dingtalkTitle("trade-signal: trade", " \n") + if got != "trade-signal: trade" { + t.Fatalf("got %q", got) + } +} + func TestDingTalkMarkdownTextDoublesNewlines(t *testing.T) { in := "空单开仓\n交易品种: ETHUSDT\n开仓价格: 2542.33\n\n推送时间: 2026.08.27 16:30:12" got := dingtalkMarkdownText(in) @@ -40,4 +54,4 @@ func TestDingtalkConfigWebhookURL(t *testing.T) { } }) } -} \ No newline at end of file +}