Skip to Content

邮件

核心逻辑

配置解析

邮件发送按以下默认顺序查找:

1. 当前租户默认邮件服务器 2. 平台默认邮件服务器(`tenant_id = 0`) 3. 若均不可用则抛出 BusinessException

若有多条记录标记为默认,则取 sortOrder 最小的一条。

模板解析

邮件模板按以下回退逻辑选择:

租户 + 当前语言 -> 租户 + 默认语言 -> 平台 + 当前语言 -> 平台 + 默认语言 -> BusinessException

模板占位符统一使用 Softa 语法:{{ variable }}

异步投递

  • sendAsync(...) 立即返回,在后台完成投递
  • 每次发送都会自动创建一条 MailSendRecord

业务代码通常无需显式选择邮件服务器,默认应由平台或租户管理员预先配置。

发送邮件

在需要投递邮件处注入 MailSendService

@Autowired private MailSendService mailSendService; // 纯文本 mailSendService.sendText("[email protected]", "Hello", "Welcome to Softa."); // HTML mailSendService.sendHtml("[email protected]", "Welcome", "<h1>Hello Alice</h1>"); // 多收件人 mailSendService.sendHtml(List.of("[email protected]", "[email protected]"), "Notice", "<p>...</p>"); // 完全控制 SendMailDTO dto = new SendMailDTO(); dto.setTo(List.of("[email protected]")); dto.setCc(List.of("[email protected]")); dto.setSubject("Offer Letter"); dto.setHtmlBody("<p>Dear Alice...</p>"); dto.setAttachments(List.of(attachment)); mailSendService.send(dto); // 异步 mailSendService.sendAsync(dto);

附件

MailAttachmentDTO attachment = new MailAttachmentDTO(); attachment.setFileName("report.pdf"); attachment.setContentType("application/pdf"); attachment.setData(pdfBytes); // 或 attachment.setFileId(fileId);

邮件模板

当业务内容需要复用或多语言时,使用模板:

@Autowired private MailSendService mailSendService; Map<String, Object> vars = Map.of( "name", "Alice", "activationUrl", "https://app.example.com/activate/abc123" ); mailSendService.sendByTemplate("USER_WELCOME", "[email protected]", vars); mailSendService.sendByTemplate("ORDER_CONFIRMATION", List.of("[email protected]", "[email protected]"), vars);

当前请求语言取自 ContextHolder

模板示例

POST /MailTemplate/createOne { "code": "USER_WELCOME", "name": "User Welcome Email", "language": "en-US", "subject": "Welcome, {{ name }}!", "body": "<h1>Welcome, {{ name }}</h1><p><a href='{{ activationUrl }}'>Activate</a></p>", "includePlainText": true, "isEnabled": true }

使用 language: "default" 可定义回退模板。

接收邮件

若业务需要处理入站邮件,注入 MailReceiveService

@Autowired private MailReceiveService mailReceiveService; // 从自动解析的服务器拉取 int fetched = mailReceiveService.fetchNewMails(); // 从指定服务器配置拉取 int fetchedByServer = mailReceiveService.fetchNewMails(serverConfigId); // 标记已读 mailReceiveService.markAsRead(recordId); mailReceiveService.markAsRead(List.of(id1, id2, id3));

消息按 (server_config_id, message_id) 去重,因此重复轮询是安全的。

邮件状态参考

MailSendRecord

PENDING -> SENT PENDING -> FAILED PENDING -> RETRY

MailReceiveRecord

UNREAD -> READ -> ARCHIVED -> DELETED
最后更新于