From 93cb8bad066c077d9ddc8de7a9f698e0b48fe52c Mon Sep 17 00:00:00 2001 From: YunaiV Date: Tue, 5 Aug 2025 21:14:08 +0800 Subject: [PATCH] =?UTF-8?q?feat=EF=BC=9A=E3=80=90system=20=E7=B3=BB?= =?UTF-8?q?=E7=BB=9F=E5=8A=9F=E8=83=BD=E3=80=91=E9=82=AE=E7=AE=B1=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E6=8A=84=E9=80=81=E3=80=81=E5=AF=86=E9=80=81=EF=BC=8C?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=A4=9A=E4=B8=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/mysql/ruoyi-vue-pro.sql | 6 +- .../system/api/mail/MailSendApiImpl.java | 6 +- .../mail/dto/MailSendSingleToUserReqDTO.java | 19 ++- .../admin/mail/MailTemplateController.java | 3 +- .../admin/mail/vo/log/MailLogRespVO.java | 7 +- .../system/dal/dataobject/mail/MailLogDO.java | 15 +- .../system/dal/mysql/mail/MailLogMapper.java | 5 +- .../mq/message/mail/MailSendMessage.java | 7 +- .../system/mq/producer/mail/MailProducer.java | 19 +-- .../system/service/mail/MailLogService.java | 21 +-- .../service/mail/MailLogServiceImpl.java | 37 +---- .../system/service/mail/MailSendService.java | 81 ++++------ .../service/mail/MailSendServiceImpl.java | 145 ++++++------------ .../service/mail/MailLogServiceImplTest.java | 26 +++- .../service/mail/MailSendServiceImplTest.java | 123 +++++++-------- .../src/test/resources/sql/create_tables.sql | 4 +- 16 files changed, 215 insertions(+), 309 deletions(-) diff --git a/sql/mysql/ruoyi-vue-pro.sql b/sql/mysql/ruoyi-vue-pro.sql index c37fffca10..b9dad19d90 100644 --- a/sql/mysql/ruoyi-vue-pro.sql +++ b/sql/mysql/ruoyi-vue-pro.sql @@ -1259,9 +1259,9 @@ CREATE TABLE `system_mail_log` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号', `user_id` bigint NULL DEFAULT NULL COMMENT '用户编号', `user_type` tinyint NULL DEFAULT NULL COMMENT '用户类型', - `to_mail` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '接收邮箱地址', - `cc_mail` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '抄送邮箱地址', - `bcc_mail` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '密送邮箱地址', + `to_mails` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '接收邮箱地址', + `cc_mails` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '抄送邮箱地址', + `bcc_mails` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '密送邮箱地址', `account_id` bigint NOT NULL COMMENT '邮箱账号编号', `from_mail` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '发送邮箱地址', `template_id` bigint NOT NULL COMMENT '模板编号', diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/api/mail/MailSendApiImpl.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/api/mail/MailSendApiImpl.java index 0a8910e1c3..59bb505891 100644 --- a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/api/mail/MailSendApiImpl.java +++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/api/mail/MailSendApiImpl.java @@ -21,13 +21,15 @@ public class MailSendApiImpl implements MailSendApi { @Override public Long sendSingleMailToAdmin(MailSendSingleToUserReqDTO reqDTO) { - return mailSendService.sendSingleMailToAdmin(reqDTO.getMail(), reqDTO.getUserId(), + return mailSendService.sendSingleMailToAdmin(reqDTO.getUserId(), + reqDTO.getToMails(), reqDTO.getCcMails(), reqDTO.getBccMails(), reqDTO.getTemplateCode(), reqDTO.getTemplateParams()); } @Override public Long sendSingleMailToMember(MailSendSingleToUserReqDTO reqDTO) { - return mailSendService.sendSingleMailToMember(reqDTO.getMail(), reqDTO.getUserId(), + return mailSendService.sendSingleMailToMember(reqDTO.getUserId(), + reqDTO.getToMails(), reqDTO.getCcMails(), reqDTO.getBccMails(), reqDTO.getTemplateCode(), reqDTO.getTemplateParams()); } diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/api/mail/dto/MailSendSingleToUserReqDTO.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/api/mail/dto/MailSendSingleToUserReqDTO.java index 0481d59225..2d67a78087 100644 --- a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/api/mail/dto/MailSendSingleToUserReqDTO.java +++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/api/mail/dto/MailSendSingleToUserReqDTO.java @@ -4,6 +4,8 @@ import lombok.Data; import jakarta.validation.constraints.Email; import jakarta.validation.constraints.NotNull; + +import java.util.List; import java.util.Map; /** @@ -16,13 +18,24 @@ public class MailSendSingleToUserReqDTO { /** * 用户编号 + * + * 如果非空,则加载对应用户的邮箱,添加到 {@link #toMails} 中 */ private Long userId; + /** - * 邮箱 + * 收件邮箱 */ - @Email - private String mail; + private List<@Email String> toMails; + /** + * 抄送邮箱 + */ + private List<@Email String> ccMails; + /** + * 密送邮箱 + */ + private List<@Email String> bccMails; + /** * 邮件模板编号 diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/MailTemplateController.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/MailTemplateController.java index f85f9e34e4..52ac150875 100644 --- a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/MailTemplateController.java +++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/MailTemplateController.java @@ -91,7 +91,8 @@ public class MailTemplateController { @Operation(summary = "发送短信") @PreAuthorize("@ss.hasPermission('system:mail-template:send-mail')") public CommonResult sendMail(@Valid @RequestBody MailTemplateSendReqVO sendReqVO) { - return success(mailSendService.sendMultipleMailToAdmin(sendReqVO.getToMails(), sendReqVO.getCcMails(), sendReqVO.getBccMails(), getLoginUserId(), + return success(mailSendService.sendSingleMailToAdmin(getLoginUserId(), + sendReqVO.getToMails(), sendReqVO.getCcMails(), sendReqVO.getBccMails(), sendReqVO.getTemplateCode(), sendReqVO.getTemplateParams())); } diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/log/MailLogRespVO.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/log/MailLogRespVO.java index b53488510c..8e67d1df73 100755 --- a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/log/MailLogRespVO.java +++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/log/MailLogRespVO.java @@ -4,6 +4,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.time.LocalDateTime; +import java.util.List; import java.util.Map; @Schema(description = "管理后台 - 邮件日志 Response VO") @@ -20,13 +21,13 @@ public class MailLogRespVO { private Byte userType; @Schema(description = "接收邮箱地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "user1@example.com, user2@example.com") - private String toMail; + private List toMails; @Schema(description = "抄送邮箱地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "user3@example.com, user4@example.com") - private String ccMail; + private List ccMails; @Schema(description = "密送邮箱地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "user5@example.com, user6@example.com") - private String bccMail; + private List bccMails; @Schema(description = "邮箱账号编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "18107") private Long accountId; diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/mail/MailLogDO.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/mail/MailLogDO.java index 9fac8582c1..756dba2ad7 100644 --- a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/mail/MailLogDO.java +++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/mail/MailLogDO.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.system.dal.dataobject.mail; import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.framework.mybatis.core.type.StringListTypeHandler; import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; import cn.iocoder.yudao.module.system.enums.mail.MailSendStatusEnum; import com.baomidou.mybatisplus.annotation.KeySequence; @@ -12,6 +13,7 @@ import lombok.*; import java.io.Serializable; import java.time.LocalDateTime; +import java.util.List; import java.util.Map; /** @@ -47,18 +49,23 @@ public class MailLogDO extends BaseDO implements Serializable { * 枚举 {@link UserTypeEnum} */ private Integer userType; + /** * 接收邮箱地址 */ - private String toMail; + @TableField(typeHandler = StringListTypeHandler.class) + private List toMails; /** * 接收邮箱地址 */ - private String ccMail; + @TableField(typeHandler = StringListTypeHandler.class) + private List ccMails; /** - * 接收邮箱地址 + * 密送邮箱地址 */ - private String bccMail; + @TableField(typeHandler = StringListTypeHandler.class) + private List bccMails; + /** * 邮箱账号编号 * diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/mail/MailLogMapper.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/mail/MailLogMapper.java index 6b147cff62..44fab07a0d 100644 --- a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/mail/MailLogMapper.java +++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/mail/MailLogMapper.java @@ -1,8 +1,10 @@ package cn.iocoder.yudao.module.system.dal.mysql.mail; +import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils; import cn.iocoder.yudao.module.system.controller.admin.mail.vo.log.MailLogPageReqVO; import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailLogDO; import org.apache.ibatis.annotations.Mapper; @@ -14,11 +16,12 @@ public interface MailLogMapper extends BaseMapperX { return selectPage(reqVO, new LambdaQueryWrapperX() .eqIfPresent(MailLogDO::getUserId, reqVO.getUserId()) .eqIfPresent(MailLogDO::getUserType, reqVO.getUserType()) - .likeIfPresent(MailLogDO::getToMail, reqVO.getToMail()) .eqIfPresent(MailLogDO::getAccountId, reqVO.getAccountId()) .eqIfPresent(MailLogDO::getTemplateId, reqVO.getTemplateId()) .eqIfPresent(MailLogDO::getSendStatus, reqVO.getSendStatus()) .betweenIfPresent(MailLogDO::getSendTime, reqVO.getSendTime()) + .apply(StrUtil.isNotBlank(reqVO.getToMail()), + MyBatisUtils.findInSet("to_mails", reqVO.getToMail())) .orderByDesc(MailLogDO::getId)); } diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/mq/message/mail/MailSendMessage.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/mq/message/mail/MailSendMessage.java index 06c4a5102b..03a4b7f198 100644 --- a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/mq/message/mail/MailSendMessage.java +++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/mq/message/mail/MailSendMessage.java @@ -5,6 +5,7 @@ import lombok.Data; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; +import java.util.Collection; import java.util.List; /** @@ -24,15 +25,15 @@ public class MailSendMessage { * 接收邮件地址 */ @NotEmpty(message = "接收邮件地址不能为空") - private List toMails; + private Collection toMails; /** * 抄送邮件地址 */ - private List ccMails; + private Collection ccMails; /** * 密送邮件地址 */ - private List bccMails; + private Collection bccMails; /** * 邮件账号编号 */ diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/mq/producer/mail/MailProducer.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/mq/producer/mail/MailProducer.java index 8a485c7fe0..07aabb00a8 100644 --- a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/mq/producer/mail/MailProducer.java +++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/mq/producer/mail/MailProducer.java @@ -7,6 +7,7 @@ import org.springframework.stereotype.Component; import jakarta.annotation.Resource; +import java.util.Collection; import java.util.List; import static java.util.Collections.singletonList; @@ -24,21 +25,6 @@ public class MailProducer { @Resource private ApplicationContext applicationContext; - /** - * 发送 {@link MailSendMessage} 消息 - * - * @param sendLogId 发送日志编码 - * @param mail 接收邮件地址 - * @param accountId 邮件账号编号 - * @param nickname 邮件发件人 - * @param title 邮件标题 - * @param content 邮件内容 - */ - public void sendMailSendMessage(Long sendLogId, String mail, Long accountId, - String nickname, String title, String content) { - sendMailSendMessage(sendLogId, singletonList(mail), null, null, accountId, nickname, title, content); - } - /** * 发送 {@link MailSendMessage} 消息 * @@ -51,7 +37,8 @@ public class MailProducer { * @param title 邮件标题 * @param content 邮件内容 */ - public void sendMailSendMessage(Long sendLogId, List toMails, List ccMails, List bccMails, + public void sendMailSendMessage(Long sendLogId, + Collection toMails, Collection ccMails, Collection bccMails, Long accountId, String nickname, String title, String content) { MailSendMessage message = new MailSendMessage() .setLogId(sendLogId) diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/mail/MailLogService.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/mail/MailLogService.java index 168179aec7..1c66e55ef4 100644 --- a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/mail/MailLogService.java +++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/mail/MailLogService.java @@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailAccountDO; import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailLogDO; import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailTemplateDO; +import java.util.Collection; import java.util.List; import java.util.Map; @@ -33,23 +34,6 @@ public interface MailLogService { */ MailLogDO getMailLog(Long id); - /** - * 创建邮件日志 - * - * @param userId 用户编码 - * @param userType 用户类型 - * @param toMail 收件人邮件 - * @param account 邮件账号信息 - * @param template 模版信息 - * @param templateContent 模版内容 - * @param templateParams 模版参数 - * @param isSend 是否发送成功 - * @return 日志编号 - */ - Long createMailLog(Long userId, Integer userType, String toMail, - MailAccountDO account, MailTemplateDO template , - String templateContent, Map templateParams, Boolean isSend); - /** * 创建邮件日志 * @@ -65,7 +49,8 @@ public interface MailLogService { * @param isSend 是否发送成功 * @return 日志编号 */ - Long createMailLog(Long userId, Integer userType, List toMails, List ccMails, List bccMails, + Long createMailLog(Long userId, Integer userType, + Collection toMails, Collection ccMails, Collection bccMails, MailAccountDO account, MailTemplateDO template, String templateContent, Map templateParams, Boolean isSend); diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/mail/MailLogServiceImpl.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/mail/MailLogServiceImpl.java index 28d233da58..c17abaf016 100644 --- a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/mail/MailLogServiceImpl.java +++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/mail/MailLogServiceImpl.java @@ -1,6 +1,6 @@ package cn.iocoder.yudao.module.system.service.mail; -import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.collection.ListUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.system.controller.admin.mail.vo.log.MailLogPageReqVO; import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailAccountDO; @@ -13,9 +13,7 @@ import org.springframework.validation.annotation.Validated; import jakarta.annotation.Resource; import java.time.LocalDateTime; -import java.util.List; -import java.util.Map; -import java.util.Objects; +import java.util.*; import static cn.hutool.core.exceptions.ExceptionUtil.getRootCauseMessage; @@ -43,7 +41,8 @@ public class MailLogServiceImpl implements MailLogService { } @Override - public Long createMailLog(Long userId, Integer userType, String toMail, + public Long createMailLog(Long userId, Integer userType, + Collection toMails, Collection ccMails, Collection bccMails, MailAccountDO account, MailTemplateDO template, String templateContent, Map templateParams, Boolean isSend) { MailLogDO.MailLogDOBuilder logDOBuilder = MailLogDO.builder(); @@ -51,32 +50,8 @@ public class MailLogServiceImpl implements MailLogService { logDOBuilder.sendStatus(Objects.equals(isSend, true) ? MailSendStatusEnum.INIT.getStatus() : MailSendStatusEnum.IGNORE.getStatus()) // 用户信息 - .userId(userId).userType(userType).toMail(toMail) - .accountId(account.getId()).fromMail(account.getMail()) - // 模板相关字段 - .templateId(template.getId()).templateCode(template.getCode()).templateNickname(template.getNickname()) - .templateTitle(template.getTitle()).templateContent(templateContent).templateParams(templateParams); - - // 插入数据库 - MailLogDO logDO = logDOBuilder.build(); - mailLogMapper.insert(logDO); - return logDO.getId(); - } - - @Override - public Long createMailLog(Long userId, Integer userType, List toMails, List ccMails, List bccMails, - MailAccountDO account, MailTemplateDO template, - String templateContent, Map templateParams, Boolean isSend) { - String toMail = CollUtil.isEmpty(toMails) ? "" : String.join(",", toMails); - String ccMail = CollUtil.isEmpty(ccMails) ? "" : String.join(",", ccMails); - String bccMail = CollUtil.isEmpty(bccMails) ? "" : String.join(",", bccMails); - - MailLogDO.MailLogDOBuilder logDOBuilder = MailLogDO.builder(); - // 根据是否要发送,设置状态 - logDOBuilder.sendStatus(Objects.equals(isSend, true) ? MailSendStatusEnum.INIT.getStatus() - : MailSendStatusEnum.IGNORE.getStatus()) - // 用户信息 - .userId(userId).userType(userType).toMail(toMail).ccMail(ccMail).bccMail(bccMail) + .userId(userId).userType(userType) + .toMails(ListUtil.toList(toMails)).ccMails(ListUtil.toList(ccMails)).bccMails(ListUtil.toList(bccMails)) .accountId(account.getId()).fromMail(account.getMail()) // 模板相关字段 .templateId(template.getId()).templateCode(template.getCode()).templateNickname(template.getNickname()) diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/mail/MailSendService.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/mail/MailSendService.java index 5300157b15..1b600bc90c 100644 --- a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/mail/MailSendService.java +++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/mail/MailSendService.java @@ -1,8 +1,9 @@ package cn.iocoder.yudao.module.system.service.mail; +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.module.system.mq.message.mail.MailSendMessage; -import java.util.List; +import java.util.Collection; import java.util.Map; /** @@ -16,83 +17,55 @@ public interface MailSendService { /** * 发送单条邮件给管理后台的用户 * - * @param mail 邮箱 * @param userId 用户编码 + * @param toMails 收件邮箱 + * @param ccMails 抄送邮箱 + * @param bccMails 密送邮箱 * @param templateCode 邮件模版编码 * @param templateParams 邮件模版参数 * @return 发送日志编号 */ - Long sendSingleMailToAdmin(String mail, Long userId, - String templateCode, Map templateParams); + default Long sendSingleMailToAdmin(Long userId, + Collection toMails, Collection ccMails, Collection bccMails, + String templateCode, Map templateParams) { + return sendSingleMail(toMails, ccMails, bccMails, userId, UserTypeEnum.ADMIN.getValue(), + templateCode, templateParams); + } /** * 发送单条邮件给用户 APP 的用户 * - * @param mail 邮箱 * @param userId 用户编码 + * @param toMails 收件邮箱 + * @param ccMails 抄送邮箱 + * @param bccMails 密送邮箱 * @param templateCode 邮件模版编码 * @param templateParams 邮件模版参数 * @return 发送日志编号 */ - Long sendSingleMailToMember(String mail, Long userId, - String templateCode, Map templateParams); + default Long sendSingleMailToMember(Long userId, + Collection toMails, Collection ccMails, Collection bccMails, + String templateCode, Map templateParams) { + return sendSingleMail(toMails, ccMails, bccMails, userId, UserTypeEnum.MEMBER.getValue(), + templateCode, templateParams); + } /** - * 发送单条邮件给用户 + * 发送单条邮件 * - * @param mail 邮箱 - * @param userId 用户编码 + * @param toMails 收件邮箱 + * @param ccMails 抄送邮箱 + * @param bccMails 密送邮箱 + * @param userId 用户编号 * @param userType 用户类型 * @param templateCode 邮件模版编码 * @param templateParams 邮件模版参数 * @return 发送日志编号 */ - Long sendSingleMail(String mail, Long userId, Integer userType, + Long sendSingleMail(Collection toMails, Collection ccMails, Collection bccMails, + Long userId, Integer userType, String templateCode, Map templateParams); - /** - * 发送多条邮件给管理后台的用户 - * - * @param toMails 收件邮箱 - * @param ccMails 抄送邮箱 - * @param bccMails 密送邮箱 - * @param userId 用户编码 - * @param templateCode 邮件模版编码 - * @param templateParams 邮件模版参数 - * @return 发送日志编号 - */ - Long sendMultipleMailToAdmin(List toMails, List ccMails, List bccMails, - Long userId, String templateCode, Map templateParams); - - /** - * 发送多条邮件给用户 APP 的用户 - * - * @param toMails 收件邮箱 - * @param ccMails 抄送邮箱 - * @param bccMails 密送邮箱 - * @param userId 用户编码 - * @param templateCode 邮件模版编码 - * @param templateParams 邮件模版参数 - * @return 发送日志编号 - */ - Long sendMultipleMailToMember(List toMails, List ccMails, List bccMails, - Long userId, String templateCode, Map templateParams); - - /** - * 发送单条邮件给用户 - * - * @param toMails 收件邮箱 - * @param ccMails 抄送邮箱 - * @param bccMails 密送邮箱 - * @param userId 用户编码 - * @param userType 用户类型 - * @param templateCode 邮件模版编码 - * @param templateParams 邮件模版参数 - * @return 发送日志编号 - */ - Long sendMultipleMail(List toMails, List ccMails, List bccMails, - Long userId, Integer userType, String templateCode, Map templateParams); - /** * 执行真正的邮件发送 * 注意,该方法仅仅提供给 MQ Consumer 使用 diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/mail/MailSendServiceImpl.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/mail/MailSendServiceImpl.java index 580777ca70..682696f932 100644 --- a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/mail/MailSendServiceImpl.java +++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/mail/MailSendServiceImpl.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.system.service.mail; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.lang.Validator; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; @@ -14,16 +15,17 @@ import cn.iocoder.yudao.module.system.service.user.AdminUserService; import com.google.common.annotations.VisibleForTesting; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; -import org.dromara.hutool.extra.mail.*; +import org.dromara.hutool.extra.mail.MailAccount; +import org.dromara.hutool.extra.mail.MailUtil; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; -import java.util.List; +import java.util.Collection; +import java.util.LinkedHashSet; import java.util.Map; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; -import static java.util.Collections.singletonList; /** * 邮箱发送 Service 实现类 @@ -52,120 +54,67 @@ public class MailSendServiceImpl implements MailSendService { private MailProducer mailProducer; @Override - public Long sendSingleMailToAdmin(String mail, Long userId, - String templateCode, Map templateParams) { - // 如果 mail 为空,则加载用户编号对应的邮箱 - if (StrUtil.isEmpty(mail)) { - AdminUserDO user = adminUserService.getUser(userId); - if (user != null) { - mail = user.getEmail(); - } - } - // 执行发送 - return sendSingleMail(mail, userId, UserTypeEnum.ADMIN.getValue(), templateCode, templateParams); - } - - @Override - public Long sendSingleMailToMember(String mail, Long userId, - String templateCode, Map templateParams) { - // 如果 mail 为空,则加载用户编号对应的邮箱 - if (StrUtil.isEmpty(mail)) { - mail = memberService.getMemberUserEmail(userId); - } - // 执行发送 - return sendSingleMail(mail, userId, UserTypeEnum.MEMBER.getValue(), templateCode, templateParams); - } - - @Override - public Long sendSingleMail(String mail, Long userId, Integer userType, + public Long sendSingleMail(Collection toMails, Collection ccMails, Collection bccMails, + Long userId, Integer userType, String templateCode, Map templateParams) { - // 校验邮箱模版是否合法 + // 1.1 校验邮箱模版是否合法 MailTemplateDO template = validateMailTemplate(templateCode); - // 校验邮箱账号是否合法 + // 1.2 校验邮箱账号是否合法 MailAccountDO account = validateMailAccount(template.getAccountId()); - - // 校验邮箱是否存在 - mail = validateMail(mail); + // 1.3 校验邮件参数是否缺失 validateTemplateParams(template, templateParams); - // 创建发送日志。如果模板被禁用,则不发送短信,只记录日志 - Boolean isSend = CommonStatusEnum.ENABLE.getStatus().equals(template.getStatus()); - String title = mailTemplateService.formatMailTemplateContent(template.getTitle(), templateParams); - String content = mailTemplateService.formatMailTemplateContent(template.getContent(), templateParams); - Long sendLogId = mailLogService.createMailLog(userId, userType, mail, - account, template, content, templateParams, isSend); - // 发送 MQ 消息,异步执行发送短信 - if (isSend) { - mailProducer.sendMailSendMessage(sendLogId, mail, account.getId(), - template.getNickname(), title, content); + // 2. 组装邮箱 + String userMail = getUserMail(userId, userType); + Collection toMailSet = new LinkedHashSet<>(); + Collection ccMailSet = new LinkedHashSet<>(); + Collection bccMailSet = new LinkedHashSet<>(); + if (Validator.isEmail(userMail)) { + toMailSet.add(userMail); } - return sendLogId; - } - - @Override - public Long sendMultipleMailToAdmin(List toMails, List ccMails, List bccMails, Long userId, String templateCode, Map templateParams) { - // 如果 mail 为空,则加载用户编号对应的邮箱 - if (CollUtil.isEmpty(toMails)) { - AdminUserDO user = adminUserService.getUser(userId); - if (user != null) { - toMails = singletonList(user.getEmail()); - } - } - // 执行发送 - return sendMultipleMail(toMails, ccMails, bccMails, userId, UserTypeEnum.ADMIN.getValue(), templateCode, templateParams); - } - - @Override - public Long sendMultipleMailToMember(List toMails, List ccMails, List bccMails, Long userId, String templateCode, Map templateParams) { - // 如果 mail 为空,则加载用户编号对应的邮箱 - if (CollUtil.isEmpty(toMails)) { - toMails = singletonList(memberService.getMemberUserEmail(userId)); - } - // 执行发送 - return sendMultipleMail(toMails, ccMails, bccMails, userId, UserTypeEnum.MEMBER.getValue(), templateCode, templateParams); - } - - @Override - public Long sendMultipleMail(List toMails, List ccMails, List bccMails, Long userId, Integer userType, String templateCode, Map templateParams) { - // 校验邮箱模版是否合法 - MailTemplateDO template = validateMailTemplate(templateCode); - // 校验邮箱账号是否合法 - MailAccountDO account = validateMailAccount(template.getAccountId()); - // 校验邮件参数是否缺失 - validateTemplateParams(template, templateParams); - - if (CollUtil.isEmpty(toMails)) { - throw exception(MAIL_SEND_MAIL_NOT_EXISTS); - } - // 校验邮箱是否存在 - for (String mail : toMails) { - validateMail(mail); + if (CollUtil.isNotEmpty(toMails)) { + toMails.stream().filter(Validator::isEmail).forEach(toMailSet::add); } if (CollUtil.isNotEmpty(ccMails)) { - for (String mail : ccMails) { - validateMail(mail); - } + ccMails.stream().filter(Validator::isEmail).forEach(ccMailSet::add); } if (CollUtil.isNotEmpty(bccMails)) { - for (String mail : bccMails) { - validateMail(mail); - } + bccMails.stream().filter(Validator::isEmail).forEach(bccMailSet::add); + } + if (CollUtil.isEmpty(toMailSet)) { + throw exception(MAIL_SEND_MAIL_NOT_EXISTS); } // 创建发送日志。如果模板被禁用,则不发送短信,只记录日志 Boolean isSend = CommonStatusEnum.ENABLE.getStatus().equals(template.getStatus()); String title = mailTemplateService.formatMailTemplateContent(template.getTitle(), templateParams); String content = mailTemplateService.formatMailTemplateContent(template.getContent(), templateParams); - Long sendLogId = mailLogService.createMailLog(userId, userType, toMails, ccMails, bccMails, + Long sendLogId = mailLogService.createMailLog(userId, userType, toMailSet, ccMailSet, bccMailSet, account, template, content, templateParams, isSend); // 发送 MQ 消息,异步执行发送短信 if (isSend) { - mailProducer.sendMailSendMessage(sendLogId, toMails, ccMails, bccMails, account.getId(), - template.getNickname(), title, content); + mailProducer.sendMailSendMessage(sendLogId, toMailSet, ccMailSet, bccMailSet, + account.getId(), template.getNickname(), title, content); } return sendLogId; } + private String getUserMail(Long userId, Integer userType) { + if (userId == null || userType == null) { + return null; + } + if (UserTypeEnum.ADMIN.getValue().equals(userType)) { + AdminUserDO user = adminUserService.getUser(userId); + if (user != null) { + return user.getEmail(); + } + } + if (UserTypeEnum.MEMBER.getValue().equals(userType)) { + return memberService.getMemberUserEmail(userId); + } + return null; + } + @Override public void doSendMail(MailSendMessage message) { // 1. 创建发送账号 @@ -213,14 +162,6 @@ public class MailSendServiceImpl implements MailSendService { return account; } - @VisibleForTesting - String validateMail(String mail) { - if (StrUtil.isEmpty(mail)) { - throw exception(MAIL_SEND_MAIL_NOT_EXISTS); - } - return mail; - } - /** * 校验邮件参数是否缺失 * diff --git a/yudao-module-system/src/test/java/cn/iocoder/yudao/module/system/service/mail/MailLogServiceImplTest.java b/yudao-module-system/src/test/java/cn/iocoder/yudao/module/system/service/mail/MailLogServiceImplTest.java index 482aa5aeee..ec8aadacd9 100755 --- a/yudao-module-system/src/test/java/cn/iocoder/yudao/module/system/service/mail/MailLogServiceImplTest.java +++ b/yudao-module-system/src/test/java/cn/iocoder/yudao/module/system/service/mail/MailLogServiceImplTest.java @@ -10,10 +10,12 @@ import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailLogDO; import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailTemplateDO; import cn.iocoder.yudao.module.system.dal.mysql.mail.MailLogMapper; import cn.iocoder.yudao.module.system.enums.mail.MailSendStatusEnum; +import org.assertj.core.util.Lists; import org.junit.jupiter.api.Test; import org.springframework.context.annotation.Import; import jakarta.annotation.Resource; +import java.util.Collection; import java.util.Map; import static cn.hutool.core.util.RandomUtil.randomEle; @@ -43,7 +45,9 @@ public class MailLogServiceImplTest extends BaseDbUnitTest { // 准备参数 Long userId = randomLongId(); Integer userType = randomEle(UserTypeEnum.values()).getValue(); - String toMail = randomEmail(); + Collection toMails = Lists.newArrayList(randomEmail(), randomEmail()); + Collection ccMails = Lists.newArrayList(randomEmail()); + Collection bccMails = Lists.newArrayList(randomEmail()); MailAccountDO account = randomPojo(MailAccountDO.class); MailTemplateDO template = randomPojo(MailTemplateDO.class); String templateContent = randomString(); @@ -52,14 +56,20 @@ public class MailLogServiceImplTest extends BaseDbUnitTest { // mock 方法 // 调用 - Long logId = mailLogService.createMailLog(userId, userType, toMail, account, template, templateContent, templateParams, isSend); + Long logId = mailLogService.createMailLog(userId, userType, toMails, ccMails, bccMails, + account, template, templateContent, templateParams, isSend); // 断言 MailLogDO log = mailLogMapper.selectById(logId); assertNotNull(log); assertEquals(MailSendStatusEnum.INIT.getStatus(), log.getSendStatus()); assertEquals(userId, log.getUserId()); assertEquals(userType, log.getUserType()); - assertEquals(toMail, log.getToMail()); + assertEquals(toMails.size(), log.getToMails().size()); + assertTrue(log.getToMails().containsAll(toMails)); + assertEquals(ccMails.size(), log.getCcMails().size()); + assertTrue(log.getCcMails().containsAll(ccMails)); + assertEquals(bccMails.size(), log.getBccMails().size()); + assertTrue(log.getBccMails().containsAll(bccMails)); assertEquals(account.getId(), log.getAccountId()); assertEquals(account.getMail(), log.getFromMail()); assertEquals(template.getId(), log.getTemplateId()); @@ -136,7 +146,9 @@ public class MailLogServiceImplTest extends BaseDbUnitTest { MailLogDO dbMailLog = randomPojo(MailLogDO.class, o -> { // 等会查询到 o.setUserId(1L); o.setUserType(UserTypeEnum.ADMIN.getValue()); - o.setToMail("768@qq.com"); + o.setToMails(Lists.newArrayList("768@qq.com")); + o.setCcMails(Lists.newArrayList()); + o.setBccMails(Lists.newArrayList()); o.setAccountId(10L); o.setTemplateId(100L); o.setSendStatus(MailSendStatusEnum.INIT.getStatus()); @@ -148,8 +160,8 @@ public class MailLogServiceImplTest extends BaseDbUnitTest { mailLogMapper.insert(cloneIgnoreId(dbMailLog, o -> o.setUserId(2L))); // 测试 userType 不匹配 mailLogMapper.insert(cloneIgnoreId(dbMailLog, o -> o.setUserType(UserTypeEnum.MEMBER.getValue()))); - // 测试 toMail 不匹配 - mailLogMapper.insert(cloneIgnoreId(dbMailLog, o -> o.setToMail("788@.qq.com"))); + // 测试 toMails 不匹配(特殊:find_in_set 无法单测) +// mailLogMapper.insert(cloneIgnoreId(dbMailLog, o -> o.setToMails(Lists.newArrayList("788@qq.com")))); // 测试 accountId 不匹配 mailLogMapper.insert(cloneIgnoreId(dbMailLog, o -> o.setAccountId(11L))); // 测试 templateId 不匹配 @@ -162,7 +174,7 @@ public class MailLogServiceImplTest extends BaseDbUnitTest { MailLogPageReqVO reqVO = new MailLogPageReqVO(); reqVO.setUserId(1L); reqVO.setUserType(UserTypeEnum.ADMIN.getValue()); - reqVO.setToMail("768"); +// reqVO.setToMail("768@qq.com"); reqVO.setAccountId(10L); reqVO.setTemplateId(100L); reqVO.setSendStatus(MailSendStatusEnum.INIT.getStatus()); diff --git a/yudao-module-system/src/test/java/cn/iocoder/yudao/module/system/service/mail/MailSendServiceImplTest.java b/yudao-module-system/src/test/java/cn/iocoder/yudao/module/system/service/mail/MailSendServiceImplTest.java index 1ef1e12322..459568360d 100644 --- a/yudao-module-system/src/test/java/cn/iocoder/yudao/module/system/service/mail/MailSendServiceImplTest.java +++ b/yudao-module-system/src/test/java/cn/iocoder/yudao/module/system/service/mail/MailSendServiceImplTest.java @@ -20,6 +20,7 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockedStatic; +import java.util.Collection; import java.util.HashMap; import java.util.Map; @@ -65,14 +66,18 @@ public class MailSendServiceImplTest extends BaseMockitoUnitTest { } @Test - public void testSendSingleMailToAdmin() { + public void testSendSingleMail_success() { // 准备参数 Long userId = randomLongId(); String templateCode = RandomUtils.randomString(); Map templateParams = MapUtil.builder().put("code", "1234") .put("op", "login").build(); + Collection toMails = Lists.newArrayList("admin@test.com"); + Collection ccMails = Lists.newArrayList("cc@test.com"); + Collection bccMails = Lists.newArrayList("bcc@test.com"); + // mock adminUserService 的方法 - AdminUserDO user = randomPojo(AdminUserDO.class, o -> o.setMobile("15601691300")); + AdminUserDO user = randomPojo(AdminUserDO.class, o -> o.setEmail("admin@example.com")); when(adminUserService.getUser(eq(userId))).thenReturn(user); // mock MailTemplateService 的方法 @@ -93,61 +98,27 @@ public class MailSendServiceImplTest extends BaseMockitoUnitTest { when(mailAccountService.getMailAccountFromCache(eq(template.getAccountId()))).thenReturn(account); // mock MailLogService 的方法 Long mailLogId = randomLongId(); - when(mailLogService.createMailLog(eq(userId), eq(UserTypeEnum.ADMIN.getValue()), eq(user.getEmail()), + when(mailLogService.createMailLog(eq(userId), eq(UserTypeEnum.ADMIN.getValue()), + argThat(toMailSet -> toMailSet.contains(user.getEmail()) && toMailSet.contains("admin@test.com")), + argThat(ccMailSet -> ccMailSet.contains("cc@test.com")), + argThat(bccMailSet -> bccMailSet.contains("bcc@test.com")), eq(account), eq(template), eq(content), eq(templateParams), eq(true))).thenReturn(mailLogId); // 调用 - Long resultMailLogId = mailSendService.sendSingleMailToAdmin(null, userId, templateCode, templateParams); + Long resultMailLogId = mailSendService.sendSingleMail(toMails, ccMails, bccMails, userId, + UserTypeEnum.ADMIN.getValue(), templateCode, templateParams); // 断言 assertEquals(mailLogId, resultMailLogId); // 断言调用 - verify(mailProducer).sendMailSendMessage(eq(mailLogId), eq(user.getEmail()), - eq(account.getId()), eq(template.getNickname()), eq(title), eq(content)); - } - - @Test - public void testSendSingleMailToMember() { - // 准备参数 - Long userId = randomLongId(); - String templateCode = RandomUtils.randomString(); - Map templateParams = MapUtil.builder().put("code", "1234") - .put("op", "login").build(); - // mock memberService 的方法 - String mail = randomEmail(); - when(memberService.getMemberUserEmail(eq(userId))).thenReturn(mail); - - // mock MailTemplateService 的方法 - MailTemplateDO template = randomPojo(MailTemplateDO.class, o -> { - o.setStatus(CommonStatusEnum.ENABLE.getStatus()); - o.setContent("验证码为{code}, 操作为{op}"); - o.setParams(Lists.newArrayList("code", "op")); - }); - when(mailTemplateService.getMailTemplateByCodeFromCache(eq(templateCode))).thenReturn(template); - String title = RandomUtils.randomString(); - when(mailTemplateService.formatMailTemplateContent(eq(template.getTitle()), eq(templateParams))) - .thenReturn(title); - String content = RandomUtils.randomString(); - when(mailTemplateService.formatMailTemplateContent(eq(template.getContent()), eq(templateParams))) - .thenReturn(content); - // mock MailAccountService 的方法 - MailAccountDO account = randomPojo(MailAccountDO.class); - when(mailAccountService.getMailAccountFromCache(eq(template.getAccountId()))).thenReturn(account); - // mock MailLogService 的方法 - Long mailLogId = randomLongId(); - when(mailLogService.createMailLog(eq(userId), eq(UserTypeEnum.MEMBER.getValue()), eq(mail), - eq(account), eq(template), eq(content), eq(templateParams), eq(true))).thenReturn(mailLogId); - - // 调用 - Long resultMailLogId = mailSendService.sendSingleMailToMember(null, userId, templateCode, templateParams); - // 断言 - assertEquals(mailLogId, resultMailLogId); - // 断言调用 - verify(mailProducer).sendMailSendMessage(eq(mailLogId), eq(mail), + verify(mailProducer).sendMailSendMessage(eq(mailLogId), + argThat(toMailSet -> toMailSet.contains(user.getEmail()) && toMailSet.contains("admin@test.com")), + argThat(ccMailSet -> ccMailSet.contains("cc@test.com")), + argThat(bccMailSet -> bccMailSet.contains("bcc@test.com")), eq(account.getId()), eq(template.getNickname()), eq(title), eq(content)); } /** - * 发送成功,当短信模板开启时 + * 发送成功,当邮件模板开启时 */ @Test public void testSendSingleMail_successWhenMailTemplateEnable() { @@ -158,6 +129,8 @@ public class MailSendServiceImplTest extends BaseMockitoUnitTest { String templateCode = RandomUtils.randomString(); Map templateParams = MapUtil.builder().put("code", "1234") .put("op", "login").build(); + Collection toMails = Lists.newArrayList(mail); + // mock MailTemplateService 的方法 MailTemplateDO template = randomPojo(MailTemplateDO.class, o -> { o.setStatus(CommonStatusEnum.ENABLE.getStatus()); @@ -176,23 +149,29 @@ public class MailSendServiceImplTest extends BaseMockitoUnitTest { when(mailAccountService.getMailAccountFromCache(eq(template.getAccountId()))).thenReturn(account); // mock MailLogService 的方法 Long mailLogId = randomLongId(); - when(mailLogService.createMailLog(eq(userId), eq(userType), eq(mail), + when(mailLogService.createMailLog(eq(userId), eq(userType), + argThat(toMailSet -> toMailSet.contains(mail)), + argThat(Collection::isEmpty), + argThat(Collection::isEmpty), eq(account), eq(template), eq(content), eq(templateParams), eq(true))).thenReturn(mailLogId); // 调用 - Long resultMailLogId = mailSendService.sendSingleMail(mail, userId, userType, templateCode, templateParams); + Long resultMailLogId = mailSendService.sendSingleMail(toMails, null, null, userId, userType, templateCode, templateParams); // 断言 assertEquals(mailLogId, resultMailLogId); // 断言调用 - verify(mailProducer).sendMailSendMessage(eq(mailLogId), eq(mail), + verify(mailProducer).sendMailSendMessage(eq(mailLogId), + argThat(toMailSet -> toMailSet.contains(mail)), + argThat(Collection::isEmpty), + argThat(Collection::isEmpty), eq(account.getId()), eq(template.getNickname()), eq(title), eq(content)); } /** - * 发送成功,当短信模板关闭时 + * 发送成功,当邮件模板关闭时 */ @Test - public void testSendSingleMail_successWhenSmsTemplateDisable() { + public void testSendSingleMail_successWhenMailTemplateDisable() { // 准备参数 String mail = randomEmail(); Long userId = randomLongId(); @@ -200,6 +179,8 @@ public class MailSendServiceImplTest extends BaseMockitoUnitTest { String templateCode = RandomUtils.randomString(); Map templateParams = MapUtil.builder().put("code", "1234") .put("op", "login").build(); + Collection toMails = Lists.newArrayList(mail); + // mock MailTemplateService 的方法 MailTemplateDO template = randomPojo(MailTemplateDO.class, o -> { o.setStatus(CommonStatusEnum.DISABLE.getStatus()); @@ -218,15 +199,18 @@ public class MailSendServiceImplTest extends BaseMockitoUnitTest { when(mailAccountService.getMailAccountFromCache(eq(template.getAccountId()))).thenReturn(account); // mock MailLogService 的方法 Long mailLogId = randomLongId(); - when(mailLogService.createMailLog(eq(userId), eq(userType), eq(mail), + when(mailLogService.createMailLog(eq(userId), eq(userType), + argThat(toMailSet -> toMailSet.contains(mail)), + argThat(Collection::isEmpty), + argThat(Collection::isEmpty), eq(account), eq(template), eq(content), eq(templateParams), eq(false))).thenReturn(mailLogId); // 调用 - Long resultMailLogId = mailSendService.sendSingleMail(mail, userId, userType, templateCode, templateParams); + Long resultMailLogId = mailSendService.sendSingleMail(toMails, null, null, userId, userType, templateCode, templateParams); // 断言 assertEquals(mailLogId, resultMailLogId); // 断言调用 - verify(mailProducer, times(0)).sendMailSendMessage(anyLong(), anyString(), + verify(mailProducer, times(0)).sendMailSendMessage(anyLong(), any(), any(), any(), anyLong(), anyString(), anyString(), anyString()); } @@ -255,12 +239,29 @@ public class MailSendServiceImplTest extends BaseMockitoUnitTest { } @Test - public void testValidateMail_notExists() { + public void testSendSingleMail_noValidEmail() { // 准备参数 - // mock 方法 + Long userId = randomLongId(); + String templateCode = RandomUtils.randomString(); + Map templateParams = MapUtil.builder().put("code", "1234") + .put("op", "login").build(); + Collection toMails = Lists.newArrayList("invalid-email"); // 非法邮箱 + + // mock MailTemplateService 的方法 + MailTemplateDO template = randomPojo(MailTemplateDO.class, o -> { + o.setStatus(CommonStatusEnum.ENABLE.getStatus()); + o.setContent("验证码为{code}, 操作为{op}"); + o.setParams(Lists.newArrayList("code", "op")); + }); + when(mailTemplateService.getMailTemplateByCodeFromCache(eq(templateCode))).thenReturn(template); + + // mock MailAccountService 的方法 + MailAccountDO account = randomPojo(MailAccountDO.class); + when(mailAccountService.getMailAccountFromCache(eq(template.getAccountId()))).thenReturn(account); // 调用,并断言异常 - assertServiceException(() -> mailSendService.validateMail(null), + assertServiceException(() -> mailSendService.sendSingleMail(toMails, null, null, userId, + UserTypeEnum.ADMIN.getValue(), templateCode, templateParams), MAIL_SEND_MAIL_NOT_EXISTS); } @@ -286,7 +287,8 @@ public class MailSendServiceImplTest extends BaseMockitoUnitTest { assertEquals(account.getPort(), mailAccount.getPort()); assertEquals(account.getSslEnable(), mailAccount.isSslEnable()); return true; - }), eq(message.getMail()), eq(message.getTitle()), eq(message.getContent()), eq(true))) + }), eq(message.getToMails()), eq(message.getCcMails()), eq(message.getBccMails()), + eq(message.getTitle()), eq(message.getContent()), eq(true))) .thenReturn(messageId); // 调用 @@ -317,7 +319,8 @@ public class MailSendServiceImplTest extends BaseMockitoUnitTest { assertEquals(account.getPort(), mailAccount.getPort()); assertEquals(account.getSslEnable(), mailAccount.isSslEnable()); return true; - }), eq(message.getMail()), eq(message.getTitle()), eq(message.getContent()), eq(true))).thenThrow(e); + }), eq(message.getToMails()), eq(message.getCcMails()), eq(message.getBccMails()), + eq(message.getTitle()), eq(message.getContent()), eq(true))).thenThrow(e); // 调用 mailSendService.doSendMail(message); diff --git a/yudao-module-system/src/test/resources/sql/create_tables.sql b/yudao-module-system/src/test/resources/sql/create_tables.sql index 4df039b8df..d8b68369aa 100644 --- a/yudao-module-system/src/test/resources/sql/create_tables.sql +++ b/yudao-module-system/src/test/resources/sql/create_tables.sql @@ -553,7 +553,9 @@ CREATE TABLE IF NOT EXISTS "system_mail_log" ( "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, "user_id" bigint, "user_type" varchar, - "to_mail" varchar NOT NULL, + "to_mails" varchar NOT NULL, + "cc_mails" varchar, + "bcc_mails" varchar, "account_id" bigint NOT NULL, "from_mail" varchar NOT NULL, "template_id" bigint NOT NULL,