235 lines
7.3 KiB
TypeScript
235 lines
7.3 KiB
TypeScript
/**
|
||
* @file 邮件服务插件
|
||
* @author hotok
|
||
* @date 2025-06-29
|
||
* @lastEditor hotok
|
||
* @lastEditTime 2025-06-29
|
||
* @description 集成邮件服务到Elysia,提供邮件发送、模板邮件等功能
|
||
*/
|
||
|
||
import { Elysia } from 'elysia';
|
||
import { emailService, initializeEmailService } from './email.service';
|
||
import { validateEmailConfig } from '@/config/email.config';
|
||
import { Logger } from '@/plugins/logger/logger.service';
|
||
import type {
|
||
EmailSendOptions,
|
||
EmailTemplateSendOptions,
|
||
EmailSendResult,
|
||
EmailServiceStatus,
|
||
EmailHealthCheckResult,
|
||
} from '@/type/email.type';
|
||
|
||
/**
|
||
* 邮件服务插件
|
||
* 提供邮件发送、模板邮件、健康检查等功能
|
||
*/
|
||
export const emailPlugin = new Elysia({ name: 'email' })
|
||
.onStart(async () => {
|
||
try {
|
||
// 验证邮件配置
|
||
if (!validateEmailConfig()) {
|
||
Logger.warn('邮件配置不完整,跳过邮件服务初始化');
|
||
return;
|
||
}
|
||
|
||
// 初始化邮件服务
|
||
await initializeEmailService();
|
||
Logger.info('邮件服务插件加载完成');
|
||
} catch (error) {
|
||
Logger.error(new Error(`邮件服务插件初始化失败: ${error}`));
|
||
// 不抛出错误,允许应用继续启动(邮件服务为非核心服务)
|
||
}
|
||
})
|
||
.decorate('emailService', {
|
||
/**
|
||
* 发送邮件
|
||
*/
|
||
async sendEmail(options: EmailSendOptions): Promise<EmailSendResult> {
|
||
return await emailService.sendEmail(options);
|
||
},
|
||
|
||
/**
|
||
* 发送模板邮件
|
||
*/
|
||
async sendTemplateEmail(options: EmailTemplateSendOptions): Promise<EmailSendResult> {
|
||
return await emailService.sendTemplateEmail(options);
|
||
},
|
||
|
||
/**
|
||
* 获取邮件服务状态
|
||
*/
|
||
getStatus(): EmailServiceStatus {
|
||
return emailService.status;
|
||
},
|
||
|
||
/**
|
||
* 执行健康检查
|
||
*/
|
||
async healthCheck(): Promise<EmailHealthCheckResult> {
|
||
return await emailService.healthCheck();
|
||
},
|
||
|
||
/**
|
||
* 检查服务是否已初始化
|
||
*/
|
||
isInitialized(): boolean {
|
||
return emailService.isInitialized;
|
||
},
|
||
|
||
/**
|
||
* 发送用户激活邮件
|
||
*/
|
||
async sendActivationEmail(options: {
|
||
to: string;
|
||
username: string;
|
||
nickname?: string;
|
||
activationUrl: string;
|
||
activationCode: string;
|
||
expireTime: string;
|
||
}): Promise<EmailSendResult> {
|
||
return await emailService.sendTemplateEmail({
|
||
to: options.to,
|
||
template: 'activation',
|
||
params: {
|
||
username: options.username,
|
||
nickname: options.nickname,
|
||
email: options.to,
|
||
activationUrl: options.activationUrl,
|
||
activationCode: options.activationCode,
|
||
expireTime: options.expireTime,
|
||
},
|
||
});
|
||
},
|
||
|
||
/**
|
||
* 发送密码重置邮件
|
||
*/
|
||
async sendPasswordResetEmail(options: {
|
||
to: string;
|
||
username: string;
|
||
nickname?: string;
|
||
resetUrl: string;
|
||
resetCode: string;
|
||
expireTime: string;
|
||
}): Promise<EmailSendResult> {
|
||
return await emailService.sendTemplateEmail({
|
||
to: options.to,
|
||
template: 'passwordReset',
|
||
params: {
|
||
username: options.username,
|
||
nickname: options.nickname,
|
||
email: options.to,
|
||
resetUrl: options.resetUrl,
|
||
resetCode: options.resetCode,
|
||
expireTime: options.expireTime,
|
||
},
|
||
});
|
||
},
|
||
|
||
/**
|
||
* 发送欢迎邮件
|
||
*/
|
||
async sendWelcomeEmail(options: { to: string; username: string; nickname?: string }): Promise<EmailSendResult> {
|
||
return await emailService.sendTemplateEmail({
|
||
to: options.to,
|
||
template: 'welcome',
|
||
params: {
|
||
username: options.username,
|
||
nickname: options.nickname,
|
||
email: options.to,
|
||
},
|
||
});
|
||
},
|
||
|
||
/**
|
||
* 发送密码修改通知邮件
|
||
*/
|
||
async sendPasswordChangedEmail(options: {
|
||
to: string;
|
||
username: string;
|
||
nickname?: string;
|
||
}): Promise<EmailSendResult> {
|
||
return await emailService.sendTemplateEmail({
|
||
to: options.to,
|
||
template: 'passwordChanged',
|
||
params: {
|
||
username: options.username,
|
||
nickname: options.nickname,
|
||
email: options.to,
|
||
},
|
||
});
|
||
},
|
||
|
||
/**
|
||
* 发送系统通知邮件
|
||
*/
|
||
async sendNotificationEmail(options: {
|
||
to: string | string[];
|
||
username?: string;
|
||
nickname?: string;
|
||
message: string;
|
||
subject?: string;
|
||
}): Promise<EmailSendResult> {
|
||
return await emailService.sendTemplateEmail({
|
||
to: options.to,
|
||
template: 'notification',
|
||
params: {
|
||
username: options.username,
|
||
nickname: options.nickname,
|
||
message: options.message,
|
||
},
|
||
subject: options.subject,
|
||
});
|
||
},
|
||
})
|
||
.onStop(async () => {
|
||
try {
|
||
await emailService.close();
|
||
Logger.info('邮件服务已关闭');
|
||
} catch (error) {
|
||
Logger.error(new Error(`关闭邮件服务时出错: ${error}`));
|
||
}
|
||
});
|
||
|
||
/**
|
||
* 邮件服务类型定义(用于TypeScript类型推断)
|
||
*/
|
||
export type EmailServiceDecorator = {
|
||
emailService: {
|
||
sendEmail(options: EmailSendOptions): Promise<EmailSendResult>;
|
||
sendTemplateEmail(options: EmailTemplateSendOptions): Promise<EmailSendResult>;
|
||
getStatus(): EmailServiceStatus;
|
||
healthCheck(): Promise<EmailHealthCheckResult>;
|
||
isInitialized(): boolean;
|
||
sendActivationEmail(options: {
|
||
to: string;
|
||
username: string;
|
||
nickname?: string;
|
||
activationUrl: string;
|
||
activationCode: string;
|
||
expireTime: string;
|
||
}): Promise<EmailSendResult>;
|
||
sendPasswordResetEmail(options: {
|
||
to: string;
|
||
username: string;
|
||
nickname?: string;
|
||
resetUrl: string;
|
||
resetCode: string;
|
||
expireTime: string;
|
||
}): Promise<EmailSendResult>;
|
||
sendWelcomeEmail(options: { to: string; username: string; nickname?: string }): Promise<EmailSendResult>;
|
||
sendPasswordChangedEmail(options: {
|
||
to: string;
|
||
username: string;
|
||
nickname?: string;
|
||
}): Promise<EmailSendResult>;
|
||
sendNotificationEmail(options: {
|
||
to: string | string[];
|
||
username?: string;
|
||
nickname?: string;
|
||
message: string;
|
||
subject?: string;
|
||
}): Promise<EmailSendResult>;
|
||
};
|
||
};
|