From a137c3d4e13eb1c18c7fc72834d32fc250276845 Mon Sep 17 00:00:00 2001 From: smail Date: Sat, 17 Oct 2026 14:56:29 +0800 Subject: [PATCH] =?UTF-8?q?=E5=86=85=E7=BD=AE=E5=A4=9A=E5=9C=BA=E6=99=AF?= =?UTF-8?q?=E9=82=AE=E4=BB=B6=E9=AA=8C=E8=AF=81=E7=A0=81=E6=A8=A1=E6=9D=BF?= =?UTF-8?q?=E5=B9=B6=E4=BF=9D=E9=9A=9C=E7=A7=BB=E5=8A=A8=E7=AB=AF=E8=87=AA?= =?UTF-8?q?=E9=80=82=E5=BA=94=E5=8D=95=E8=A1=8C=E6=8E=92=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/services/verification/delivery.go | 212 ++++++++++++++++++++-- 1 file changed, 200 insertions(+), 12 deletions(-) diff --git a/backend/services/verification/delivery.go b/backend/services/verification/delivery.go index c4c40755..e9c11d63 100644 --- a/backend/services/verification/delivery.go +++ b/backend/services/verification/delivery.go @@ -238,7 +238,7 @@ func CodeHTML(challenge Challenge, code string) string { if strings.TrimSpace(recipientName) == "" { recipientName = challenge.Email } - return buildCodeHTML(recipientName, code, verificationExpiryMinutes(challenge)) + return buildCodeHTML(challenge.Purpose, recipientName, code, verificationExpiryMinutes(challenge)) } func verificationExpiryMinutes(challenge Challenge) int { @@ -251,7 +251,26 @@ func verificationExpiryMinutes(challenge Challenge) int { return int(DefaultTTL / time.Minute) } -func buildCodeHTML(recipientName, code string, expiresInMinutes int) string { +func buildCodeHTML(purpose Purpose, recipientName, code string, expiresInMinutes int) string { + headerColor := "#4f46e5" + headerTitle := "邮箱验证码" + actionPrompt := "您的验证码是:" + + switch purpose { + case PurposeExternalEmailBind, PurposeExternalEmailChange: + headerColor = "#0ea5e9" + headerTitle = "通知邮箱验证" + actionPrompt = "您正在添加额外的通知邮箱,请输入以下验证码完成验证。" + case PurposePasswordRecover, PurposePasswordChange: + headerColor = "#7c3aed" + headerTitle = "密码重置" + actionPrompt = "我们收到了您的密码重置请求,请输入以下验证码完成重置。" + default: + headerColor = "#4f46e5" + headerTitle = "邮箱验证码" + actionPrompt = "您的验证码是:" + } + return fmt.Sprintf(` @@ -261,31 +280,200 @@ func buildCodeHTML(recipientName, code string, expiresInMinutes int) string { + + +
+

%s

+
+

%s,您好:

+

%s

+

%s

+

验证码将在 %d 分钟后失效。

+

如果不是您本人操作,请忽略此邮件。

+
+ +
+ +`, + headerColor, + headerTitle, + html.EscapeString(recipientName), + actionPrompt, + html.EscapeString(code), + expiresInMinutes, + ) +} + +// AccountDisabledHTML 生成账户已被禁用通知邮件正文。 +func AccountDisabledHTML(recipientName, triggeredAt, groupName, moderationCategory, moderationScore, violationCount, banThreshold, siteName string) string { + if siteName == "" { + siteName = "Smail" + } + return fmt.Sprintf(` + + + + + + + + +
+

账户已被禁用

+
+

%s,您好:

+

您的账户在统计周期内多次触发平台内容审核/风控规则,系统已自动禁用该账户。

+ + + + + +
禁用时间%s
所属分组%s
命中类别 / 分数%s / %s
累计触发次数%s / %s
+

如需申诉或恢复账号,请联系平台管理员处理。

+
+ +
+ +`, + html.EscapeString(recipientName), + html.EscapeString(triggeredAt), + html.EscapeString(groupName), + html.EscapeString(moderationCategory), + html.EscapeString(moderationScore), + html.EscapeString(violationCount), + html.EscapeString(banThreshold), + html.EscapeString(siteName), + ) +} + +// AlertHTML 生成运维告警通知邮件正文。 +func AlertHTML(ruleName, severity, alertStatus, metricType, operator, metricValue, thresholdValue, triggeredAt, alertDescription, siteName string) string { + if siteName == "" { + siteName = "Smail" + } + return fmt.Sprintf(` + + + + + +
-

邮箱验证码

+

运维告警

+
+

规则:%s

+

严重级别:%s

+

状态:%s

+

指标:%s %s %s(阈值 %s)

+

触发时间:%s

+

说明:%s

+
+ +
+ +`, + html.EscapeString(ruleName), + html.EscapeString(severity), + html.EscapeString(alertStatus), + html.EscapeString(metricType), + html.EscapeString(operator), + html.EscapeString(metricValue), + html.EscapeString(thresholdValue), + html.EscapeString(triggeredAt), + html.EscapeString(alertDescription), + html.EscapeString(siteName), + ) +} + +// RiskWarningHTML 生成账户风控提醒通知邮件正文。 +func RiskWarningHTML(recipientName, triggeredAt, groupName, moderationCategory, moderationScore, violationCount, banThreshold, siteName string) string { + if siteName == "" { + siteName = "Smail" + } + return fmt.Sprintf(` + + + + + + + + +
+

账户风控提醒

%s,您好:

-

您的验证码是:

-

%s

-

验证码将在 %d 分钟后失效。

-

如果不是您本人操作,请忽略此邮件。

+

您的 API 请求触发了平台内容审核/风控策略。

+ + + + + +
触发时间%s
所属分组%s
命中类别 / 分数%s / %s
累计触发次数%s / %s
+

请检查请求内容,避免后续服务受到影响。

- +
`, html.EscapeString(recipientName), - html.EscapeString(code), - expiresInMinutes, + html.EscapeString(triggeredAt), + html.EscapeString(groupName), + html.EscapeString(moderationCategory), + html.EscapeString(moderationScore), + html.EscapeString(violationCount), + html.EscapeString(banThreshold), + html.EscapeString(siteName), ) }