import nodemailer from 'nodemailer'; import type { AdminConfig } from './admin.types'; export interface EmailOptions { to: string; subject: string; html: string; } export class EmailService { /** * 通过SMTP发送邮件 */ static async sendViaSMTP( config: NonNullable['smtp'], options: EmailOptions ): Promise { if (!config) { throw new Error('SMTP配置不存在'); } const transporter = nodemailer.createTransport({ host: config.host, port: config.port, secure: config.secure, auth: { user: config.user, pass: config.password, }, }); await transporter.sendMail({ from: config.from, to: options.to, subject: options.subject, html: options.html, }); } /** * 通过Resend API发送邮件 */ static async sendViaResend( config: NonNullable['resend'], options: EmailOptions ): Promise { if (!config) { throw new Error('Resend配置不存在'); } const response = await fetch('https://api.resend.com/emails', { method: 'POST', headers: { Authorization: `Bearer ${config.apiKey}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ from: config.from, to: options.to, subject: options.subject, html: options.html, }), }); if (!response.ok) { const errorText = await response.text(); throw new Error(`Resend API错误: ${response.statusText} - ${errorText}`); } } /** * 统一发送接口 */ static async send( emailConfig: AdminConfig['EmailConfig'], options: EmailOptions ): Promise { if (!emailConfig || !emailConfig.enabled) { console.log('邮件通知未启用,跳过发送'); return; } try { if (emailConfig.provider === 'smtp' && emailConfig.smtp) { await this.sendViaSMTP(emailConfig.smtp, options); console.log(`邮件已通过SMTP发送至: ${options.to}`); } else if (emailConfig.provider === 'resend' && emailConfig.resend) { await this.sendViaResend(emailConfig.resend, options); console.log(`邮件已通过Resend发送至: ${options.to}`); } else { throw new Error('邮件配置不完整'); } } catch (error) { console.error('邮件发送失败:', error); throw error; } } /** * 发送测试邮件 */ static async sendTestEmail( emailConfig: AdminConfig['EmailConfig'], toEmail: string, siteName?: string ): Promise { const displayName = siteName || 'MoonTVPlus'; await this.send(emailConfig, { to: toEmail, subject: `测试邮件 - ${displayName}`, html: `

📧 测试邮件

这是一封来自 ${displayName} 的测试邮件。

如果您收到这封邮件,说明邮件配置正确!

发送时间: ${new Date().toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' })}

`, }); } }