feat(邮件通知): 添加测试邮件发送功能

在邮件通知设置页面添加发送测试邮件按钮,用于验证SMTP配置是否正确。同时添加QQ邮箱授权码的使用提示,帮助用户正确配置。

- 新增测试邮件API接口
- 前端添加测试邮件按钮及相关逻辑
- 优化错误提示,特别是针对QQ邮箱的535错误
- 添加QQ邮箱授权码使用说明文档
This commit is contained in:
anghunk
2026-01-20 12:38:48 +08:00
parent 6d3bdb2b11
commit 1c9e8c02b6
5 changed files with 165 additions and 1 deletions

View File

@@ -99,6 +99,19 @@ export function saveEmailNotifySettings(data: {
return put<{ message: string }>('/admin/settings/email-notify', data);
}
export function sendTestEmail(data: {
toEmail: string;
smtp?: {
host?: string;
port?: number;
user?: string;
pass?: string;
secure?: boolean;
};
}): Promise<{ message: string }> {
return post<{ message: string }>('/admin/settings/email-test', data);
}
export function fetchCommentSettings(): Promise<CommentSettingsResponse> {
return get<CommentSettingsResponse>('/admin/settings/comments');
}

View File

@@ -89,6 +89,10 @@
<div class="form-item">
<label class="form-label">授权码/密码</label>
<input v-model="smtpPass" class="form-input" type="password" placeholder="QQ邮箱请使用授权码" />
<div v-if="smtpProvider === 'qq'" class="form-hint">
注意QQ邮箱必须使用<a href="https://service.mail.qq.com/detail/0/75" target="_blank">授权码</a>而非QQ密码<br/>
请登录QQ邮箱网页版设置-账户中开启 POP3/SMTP 服务并生成授权码
</div>
</div>
<div
@@ -97,7 +101,11 @@
>
{{ message }}
</div>
<div class="card-actions">
<div class="card-actions" style="justify-content: space-between;">
<button class="card-button secondary" :disabled="testingEmail" @click="testEmail">
<span v-if="testingEmail">发送中...</span>
<span v-else>发送测试邮件</span>
</button>
<button class="card-button" :disabled="savingEmail" @click="saveEmail">
<span v-if="savingEmail">保存中...</span>
<span v-else>保存配置</span>
@@ -117,6 +125,7 @@ import {
saveCommentSettings,
fetchEmailNotifySettings,
saveEmailNotifySettings,
sendTestEmail
} from "../api/admin";
const email = ref("");
@@ -126,6 +135,7 @@ const commentAdminBadge = ref("");
const avatarPrefix = ref("");
const commentAdminEnabled = ref(false);
const savingEmail = ref(false);
const testingEmail = ref(false);
const savingComment = ref(false);
const loading = ref(false);
const message = ref("");
@@ -225,6 +235,49 @@ async function saveEmail() {
}
}
async function testEmail() {
if (!email.value) {
message.value = "请输入管理员通知邮箱作为测试接收邮箱";
messageType.value = "error";
return;
}
if (!smtpUser.value || !smtpPass.value) {
message.value = "请先填写 SMTP 账号和密码";
messageType.value = "error";
return;
}
testingEmail.value = true;
message.value = "";
try {
const res = await sendTestEmail({
toEmail: email.value,
smtp: {
host: smtpHost.value,
port: smtpPort.value,
user: smtpUser.value,
pass: smtpPass.value,
secure: smtpSecure.value
}
});
showToast(res.message || "发送成功,请查收邮件", "success");
} catch (e: any) {
// 显示详细错误信息
console.error(e);
let errorMsg = e.message || "发送失败";
// 针对 QQ 邮箱 535 错误的友好提示
if (errorMsg.includes('535') && (errorMsg.includes('Login fail') || errorMsg.includes('authentication failed'))) {
errorMsg = "验证失败 (535):请检查 1. QQ邮箱是否已开启 POP3/SMTP 服务2. 密码栏是否填写了“授权码”非QQ密码。";
}
message.value = errorMsg;
messageType.value = "error";
} finally {
testingEmail.value = false;
}
}
async function saveComment() {
savingComment.value = true;
message.value = "";
@@ -400,6 +453,16 @@ onMounted(() => {
cursor: pointer;
}
.card-button.secondary {
background-color: #f6f8fa;
color: #24292f;
border: 1px solid #d0d7de;
}
.card-button.secondary:hover {
background-color: #f3f4f6;
border-color: #d0d7de;
}
.card-button:disabled {
opacity: 0.7;
cursor: default;
@@ -453,4 +516,17 @@ onMounted(() => {
font-size: 14px;
color: #57606a;
}
.form-hint {
font-size: 12px;
color: #57606a;
margin-top: 4px;
line-height: 1.5;
}
.form-hint a {
color: #0969da;
text-decoration: none;
}
.form-hint a:hover {
text-decoration: underline;
}
</style>