Skip to content

📧 邮件服务设计

1. 模块概述

邮件服务模块是系统的核心功能之一,基于 Spring Mail 框架实现,提供了可靠的邮件发送功能和邮件任务管理功能。该模块采用数据库存储配置(JSON格式),支持 SSL 加密和 SMTP 认证,同时提供了邮件任务的创建、发送、修改、删除等功能,适用于各种业务场景下的邮件发送需求。

2. 核心功能

  • 💾 数据库配置: 配置信息存储在数据库中,使用JSON格式管理,支持运行时更新
  • 📧 多种邮件类型: 支持简单邮件、HTML邮件、带附件邮件和带图片资源邮件
  • 🔒 SSL加密: 支持SMTP SSL加密,保障邮件传输安全
  • 🗂️ 任务管理: 支持邮件任务的创建、查询、修改、删除和发送
  • 🚀 异步发送: 支持异步发送邮件,提高系统响应速度
  • 📄 模板支持: 支持使用模板发送邮件
  • 📋 状态管理: 支持记录邮件发送状态和结果
  • 📊 Excel导出: 支持邮件任务列表的Excel导出

3. 目录结构

zs-mail/
├── zs-mail-api/              # 邮件API定义
│   ├── src/main/java/mail/
│   │   └── SysMailApi.java   # 邮件API接口
│   └── pom.xml
├── zs-mail-service/          # 邮件服务实现
│   ├── src/main/java/com/zs/mail/
│   │   ├── api/              # API实现
│   │   │   └── SysMailApiImpl.java  # 邮件API实现
│   │   ├── config/           # 配置类
│   │   │   └── MailConfig.java      # 邮件配置
│   │   ├── controller/       # 控制器
│   │   │   ├── SysMailConfigController.java  # 邮件配置控制器
│   │   │   └── SysMailTasksController.java  # 邮件任务控制器
│   │   ├── domain/           # 数据模型
│   │   │   ├── entity/       # 实体类
│   │   │   │   ├── SysMailConfigEntity.java  # 邮件配置实体
│   │   │   │   └── SysMailTasksEntity.java  # 邮件任务实体
│   │   │   ├── excel/        # Excel导出模型
│   │   │   │   └── SysMailTasksExcel.java  # 邮件任务Excel导出
│   │   │   ├── params/       # 请求参数
│   │   │   └── vo/           # 响应VO
│   │   ├── mapper/           # Mapper接口
│   │   │   ├── SysMailConfigMapper.java  # 邮件配置Mapper
│   │   │   └── SysMailTasksMapper.java  # 邮件任务Mapper
│   │   └── service/          # 服务层
│   │       ├── impl/         # 服务实现
│   │       │   ├── MailServiceImpl.java      # 邮件发送服务实现
│   │       │   ├── SysMailConfigServiceImpl.java  # 邮件配置服务实现
│   │       │   └── SysMailTasksServiceImpl.java  # 邮件任务服务实现
│   │       ├── MailService.java      # 邮件发送服务
│   │       ├── SysMailConfigService.java  # 邮件配置服务
│   │       └── SysMailTasksService.java  # 邮件任务服务
│   ├── src/main/resources/
│   │   └── mapper/mail/
│   │       ├── SysMailConfigMapper.xml  # 邮件配置Mapper XML
│   │       └── SysMailTasksMapper.xml  # 邮件任务Mapper XML
│   └── pom.xml
└── pom.xml                    # 父级POM

4. 核心设计

4.1 核心组件

4.1.1 邮件API

文件路径: mail.SysMailApi

邮件服务的公共API接口,定义了邮件发送的核心方法。

java
/**
 * 📧 邮件服务API接口
 * 定义邮件发送的核心方法
 */
public interface SysMailApi {
    // 发送简单邮件
    void sendSimpleEmail(String from, String to, String subject, String content);
    
    // 发送HTML邮件
    void sendHtmlEmail(String from, String to, String subject, String content);
    
    // 发送带附件的邮件
    void sendAttachmentsMail(String from, String to, String subject, String content, String filePath);
    
    // 发送带图片资源的邮件
    void sendResourcesMail(String from, String to, String subject, String content, String rscPath, String rscId);
}

4.1.2 邮件配置实体

数据库存储配置信息,使用JSON格式,记录邮件服务器配置。

字段名类型描述
idLong配置ID
nameString配置名称
hostStringSMTP服务器地址
portIntegerSMTP服务器端口
usernameString发件人邮箱
passwordString发件人密码或授权码
defaultEncodingString编码格式
propertiesString扩展属性(JSON格式)
statusInteger状态(0:禁用,1:启用)
createTimeDate创建时间
updateTimeDate更新时间
remarkString备注信息

4.1.3 邮件配置服务

文件路径: com.zs.mail.service.SysMailConfigService

邮件配置服务接口,定义了邮件配置的管理方法。

java
public interface SysMailConfigService extends IService<SysMailConfigEntity> {
    // 获取启用的邮件配置
    SysMailConfigVO getEnabledConfig();
    
    // 分页查询邮件配置
    PageResult<SysMailConfigVO> queryPage(SysMailConfigPageQueryParams params);
    
    // 保存邮件配置
    boolean saveConfig(SysMailConfigAddParams params);
    
    // 删除邮件配置
    boolean deleteConfig(Long id);
}

4.1.4 邮件配置类

文件路径: com.zs.mail.config.MailConfig

邮件服务的配置类,用于动态配置 JavaMailSender。

java
@Configuration
public class MailConfig {
    
    @Autowired
    private SysMailConfigService sysMailConfigService;
    
    @Bean
    public JavaMailSender javaMailSender() {
        // 从数据库获取启用的邮件配置
        SysMailConfigVO config = sysMailConfigService.getEnabledConfig();
        if (config == null) {
            throw new IllegalStateException("No enabled mail config found in database");
        }
        
        JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
        mailSender.setHost(config.getHost());
        mailSender.setPort(config.getPort());
        mailSender.setUsername(config.getUsername());
        mailSender.setPassword(config.getPassword());
        mailSender.setDefaultEncoding(config.getDefaultEncoding());
        
        // 解析JSON格式的扩展属性
        Properties props = mailSender.getJavaMailProperties();
        if (config.getProperties() != null) {
            // 从JSON字符串解析Properties
            JSONUtil.parseObj(config.getProperties()).forEach((key, value) -> {
                props.put(key, value);
            });
        } else {
            // 默认配置
            props.put("mail.transport.protocol", "smtp");
            props.put("mail.smtp.auth", "true");
            props.put("mail.smtp.ssl.enable", "true");
            props.put("mail.debug", "false");
        }
        
        return mailSender;
    }
}

4.1.5 邮件发送服务

文件路径: com.zs.mail.service.MailService

邮件发送服务接口,定义了邮件发送的核心方法。

java
public interface MailService {
    // 发送邮件
    boolean sendMail(SysMailTasksEntity mailTasksEntity);
    
    // 异步发送邮件
    @Async
    void sendMailAsync(SysMailTasksEntity mailTasksEntity);
}

4.1.6 邮件任务实体

文件路径: com.zs.mail.domain.entity.SysMailTasksEntity

邮件任务实体类,用于存储邮件任务的配置信息。

字段名类型描述
idLong任务ID
fromString发件人
toString收件人
subjectString邮件主题
contentString邮件内容
typeString邮件类型(simple/html/attachment/resource)
statusString发送状态(pending/sent/failed)
sendTimeDate发送时间
resultString发送结果
createTimeDate创建时间
updateTimeDate更新时间

4.1.7 邮件任务服务

文件路径: com.zs.mail.service.SysMailTasksService

邮件任务服务接口,定义了邮件任务的管理方法。

java
public interface SysMailTasksService extends IService<SysMailTasksEntity> {
    // 分页查询邮件任务
    PageResult<SysMailTasksVO> queryPage(SysMailTasksPageQueryParams params);
    
    // 发送邮件任务
    boolean sendMailTask(Long id);
    
    // 批量发送邮件任务
    boolean batchSendMailTask(List<Long> ids);
    
    // 导出邮件任务Excel
    void exportExcel(HttpServletResponse response, SysMailTasksSelectQueryParams params);
}

5. 核心流程

5.1 邮件发送流程

mermaid
sequenceDiagram
    participant Client as 客户端
    participant Controller as 控制器
    participant MailService as 邮件服务
    participant ConfigService as 配置服务
    participant DB as 数据库
    participant JavaMailSender as JavaMailSender
    participant SMTP as SMTP服务器

    Client->>Controller: 调用邮件发送接口
    Controller->>MailService: 调用sendMail方法
    MailService->>ConfigService: 查询数据库获取邮件配置
    ConfigService->>DB: 查询配置信息
    DB-->>ConfigService: 返回配置(JSON格式)
    ConfigService-->>MailService: 返回解析后的配置
    MailService->>JavaMailSender: 调用send方法
    JavaMailSender->>SMTP: 发送邮件
    SMTP-->>JavaMailSender: 返回发送结果
    JavaMailSender-->>MailService: 返回发送结果
    MailService->>DB: 更新邮件发送状态
    MailService-->>Controller: 返回发送结果
    Controller-->>Client: 返回响应

6. 使用示例

6.1 发送简单邮件

java
// 注入邮件API
@Autowired
private SysMailApi sysMailApi;

// 发送简单邮件
String from = "sender@example.com";
String to = "receiver@example.com";
String subject = "测试邮件";
String content = "这是一封测试邮件";
sysMailApi.sendSimpleEmail(from, to, subject, content);

6.2 发送HTML邮件

java
// 注入邮件API
@Autowired
private SysMailApi sysMailApi;

// 发送HTML邮件
String from = "sender@example.com";
String to = "receiver@example.com";
String subject = "HTML测试邮件";
String content = "<h1>这是一封HTML测试邮件</h1><p>包含HTML标签</p>";
sysMailApi.sendHtmlEmail(from, to, subject, content);

6.3 保存邮件配置

java
// 注入邮件配置服务
@Autowired
private SysMailConfigService sysMailConfigService;

// 保存邮件配置
SysMailConfigAddParams params = new SysMailConfigAddParams();
params.setName("默认配置");
params.setHost("smtp.example.com");
params.setPort(465);
params.setUsername("sender@example.com");
params.setPassword("password");
params.setDefaultEncoding("UTF-8");

// 设置扩展属性(JSON格式)
Map<String, Object> properties = new HashMap<>();
properties.put("mail.smtp.auth", "true");
properties.put("mail.smtp.ssl.enable", "true");
properties.put("mail.debug", "false");
params.setProperties(JSONUtil.toJsonStr(properties));

params.setStatus(1);
params.setRemark("默认邮件配置");
sysMailConfigService.saveConfig(params);

6.4 创建邮件任务

java
// 注入邮件任务服务
@Autowired
private SysMailTasksService sysMailTasksService;

// 创建邮件任务
SysMailTasksAddParams params = new SysMailTasksAddParams();
params.setFrom("sender@example.com");
params.setTo("receiver@example.com");
params.setSubject("任务邮件");
params.setContent("这是一封任务邮件");
params.setType("simple");
sysMailTasksService.save(params);

6.5 发送邮件任务

java
// 注入邮件任务服务
@Autowired
private SysMailTasksService sysMailTasksService;

// 发送邮件任务
Long taskId = 1L;
sysMailTasksService.sendMailTask(taskId);

7. 配置说明

7.1 邮件配置JSON示例

数据库中存储的邮件配置示例

字段名示例值
name企业邮箱配置
hostsmtp.example.com
port465
usernamenoreply@example.com
passwordpassword123
defaultEncodingUTF-8
properties{"mail.smtp.auth": true, "mail.smtp.ssl.enable": true, "mail.debug": false}
status1
remark企业官方邮件配置

7.2 依赖配置

pom.xml 中添加邮件相关依赖:

xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mail</artifactId>
</dependency>

8. 注意事项

  1. 📋 邮件服务器配置: 确保SMTP服务器地址、端口、用户名和密码配置正确
  2. 🔒 SSL配置: 根据邮件服务器要求配置SSL或STARTTLS
  3. 🔑 授权码: 某些邮件服务(如QQ邮箱、163邮箱)需要使用授权码而不是登录密码
  4. 🚫 并发限制: 注意邮件服务器的并发发送限制,避免被封禁
  5. 🚀 异步发送: 建议使用异步方式发送邮件,避免影响系统响应速度
  6. ⚠️ 异常处理: 捕获邮件发送异常,记录发送结果
  7. 📝 日志记录: 记录邮件发送日志,便于调试和审计
  8. 🔒 配置安全: 妥善保管邮件服务器的密码或授权码,建议使用加密存储
  9. 📄 模板安全: 使用邮件模板时,注意防止XSS攻击
  10. 💾 数据库配置: 配置信息存储在数据库中,使用JSON格式管理,便于动态修改

9. 扩展建议

  1. 📄 邮件模板管理: 支持自定义邮件模板,便于统一管理和维护
  2. 📊 邮件队列: 使用消息队列处理邮件发送,提高系统可靠性和扩展性
  3. 📈 发送统计: 统计邮件发送数量、成功率、失败原因等
  4. 🔄 重试机制: 对发送失败的邮件自动重试
  5. ⏰ 定时发送: 支持设置邮件发送时间,定时发送
  6. 👥 收件人组: 支持创建收件人组,方便批量发送
  7. 📡 邮件跟踪: 支持跟踪邮件是否被打开、链接是否被点击
  8. 🔄 多邮件服务器: 支持配置多个邮件服务器,实现负载均衡和故障转移
  9. 📊 邮件分析: 提供邮件发送统计分析报表

10. 常见问题排查

10.1 邮件发送失败

问题:邮件发送失败,返回异常信息

可能原因

  • 数据库中邮件配置错误
  • SMTP服务器地址或端口配置错误
  • 用户名或密码/授权码错误
  • SSL配置与邮件服务器要求不符
  • 发件人被邮件服务器封禁
  • 网络连接问题

解决方案

  • 检查数据库中的邮件配置
  • 验证SMTP服务器配置
  • 验证用户名和密码/授权码
  • 调整SSL配置
  • 联系邮件服务器提供商
  • 检查网络连接

10.2 邮件发送延迟

问题:邮件发送延迟或超时

可能原因

  • 邮件服务器响应慢
  • 网络延迟
  • 同步发送邮件影响系统性能

解决方案

  • 使用异步方式发送邮件
  • 检查网络连接
  • 考虑更换邮件服务器

10.3 邮件被标记为垃圾邮件

问题:收件人收到的邮件被标记为垃圾邮件

可能原因

  • 邮件内容包含垃圾邮件关键词
  • 发件人IP被列入黑名单
  • 邮件格式不符合规范
  • 缺少必要的邮件头信息

解决方案

  • 优化邮件内容,避免垃圾邮件关键词
  • 联系邮件服务器提供商解决IP黑名单问题
  • 确保邮件格式符合规范
  • 添加必要的邮件头信息

10.4 附件无法打开

问题:收件人无法打开邮件附件

可能原因

  • 附件路径错误
  • 附件文件不存在
  • 附件文件损坏
  • 附件大小超过邮件服务器限制

解决方案

  • 检查附件路径
  • 确保附件文件存在
  • 验证附件文件完整性
  • 检查邮件服务器的附件大小限制

11. 总结

邮件服务模块基于 Spring Mail 框架实现,支持多种邮件类型和安全配置,采用数据库存储配置(JSON格式),具有良好的扩展性和灵活性。该模块提供了邮件发送、模板管理、记录管理等功能,适用于各种业务场景下的邮件发送需求。

通过合理配置和使用,可以避免常见问题,提高邮件发送的可靠性和安全性。同时,该模块具有良好的扩展性,可以根据业务需求进行功能扩展和优化。