mirror of
https://gitee.com/zhijiantianya/ruoyi-vue-pro.git
synced 2026-03-22 05:07:17 +08:00
feat:【system】发送邮件时,携带附件,对应 https://gitee.com/zhijiantianya/yudao-cloud/pulls/233
This commit is contained in:
@@ -23,14 +23,14 @@ public class MailSendApiImpl implements MailSendApi {
|
||||
public Long sendSingleMailToAdmin(MailSendSingleToUserReqDTO reqDTO) {
|
||||
return mailSendService.sendSingleMailToAdmin(reqDTO.getUserId(),
|
||||
reqDTO.getToMails(), reqDTO.getCcMails(), reqDTO.getBccMails(),
|
||||
reqDTO.getTemplateCode(), reqDTO.getTemplateParams());
|
||||
reqDTO.getTemplateCode(), reqDTO.getTemplateParams(), reqDTO.getAttachments());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long sendSingleMailToMember(MailSendSingleToUserReqDTO reqDTO) {
|
||||
return mailSendService.sendSingleMailToMember(reqDTO.getUserId(),
|
||||
reqDTO.getToMails(), reqDTO.getCcMails(), reqDTO.getBccMails(),
|
||||
reqDTO.getTemplateCode(), reqDTO.getTemplateParams());
|
||||
reqDTO.getTemplateCode(), reqDTO.getTemplateParams(), reqDTO.getAttachments());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package cn.iocoder.yudao.module.system.api.mail.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import jakarta.validation.constraints.Email;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -47,4 +47,9 @@ public class MailSendSingleToUserReqDTO {
|
||||
*/
|
||||
private Map<String, Object> templateParams;
|
||||
|
||||
/**
|
||||
* 附件
|
||||
*/
|
||||
private File[] attachments;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
package cn.iocoder.yudao.module.system.mq.message.mail;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 邮箱发送消息
|
||||
@@ -55,4 +54,9 @@ public class MailSendMessage {
|
||||
@NotEmpty(message = "邮件内容不能为空")
|
||||
private String content;
|
||||
|
||||
/**
|
||||
* 附件
|
||||
*/
|
||||
private File[] attachments;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
package cn.iocoder.yudao.module.system.mq.producer.mail;
|
||||
|
||||
import cn.iocoder.yudao.module.system.mq.message.mail.MailSendMessage;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import static java.util.Collections.singletonList;
|
||||
|
||||
/**
|
||||
* Mail 邮件相关消息的 Producer
|
||||
@@ -28,23 +25,25 @@ public class MailProducer {
|
||||
/**
|
||||
* 发送 {@link MailSendMessage} 消息
|
||||
*
|
||||
* @param sendLogId 发送日志编码
|
||||
* @param toMails 接收邮件地址
|
||||
* @param ccMails 抄送邮件地址
|
||||
* @param bccMails 密送邮件地址
|
||||
* @param accountId 邮件账号编号
|
||||
* @param nickname 邮件发件人
|
||||
* @param title 邮件标题
|
||||
* @param content 邮件内容
|
||||
* @param sendLogId 发送日志编码
|
||||
* @param toMails 接收邮件地址
|
||||
* @param ccMails 抄送邮件地址
|
||||
* @param bccMails 密送邮件地址
|
||||
* @param accountId 邮件账号编号
|
||||
* @param nickname 邮件发件人
|
||||
* @param title 邮件标题
|
||||
* @param content 邮件内容
|
||||
* @param attachments 附件
|
||||
*/
|
||||
public void sendMailSendMessage(Long sendLogId,
|
||||
Collection<String> toMails, Collection<String> ccMails, Collection<String> bccMails,
|
||||
Long accountId, String nickname, String title, String content) {
|
||||
Long accountId, String nickname, String title, String content,
|
||||
File[] attachments) {
|
||||
MailSendMessage message = new MailSendMessage()
|
||||
.setLogId(sendLogId)
|
||||
.setToMails(toMails).setCcMails(ccMails).setBccMails(bccMails)
|
||||
.setAccountId(accountId).setNickname(nickname)
|
||||
.setTitle(title).setContent(content);
|
||||
.setTitle(title).setContent(content).setAttachments(attachments);
|
||||
applicationContext.publishEvent(message);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ 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.io.File;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -23,13 +24,15 @@ public interface MailSendService {
|
||||
* @param bccMails 密送邮箱
|
||||
* @param templateCode 邮件模版编码
|
||||
* @param templateParams 邮件模版参数
|
||||
* @param attachments 附件
|
||||
* @return 发送日志编号
|
||||
*/
|
||||
default Long sendSingleMailToAdmin(Long userId,
|
||||
Collection<String> toMails, Collection<String> ccMails, Collection<String> bccMails,
|
||||
String templateCode, Map<String, Object> templateParams) {
|
||||
String templateCode, Map<String, Object> templateParams,
|
||||
File... attachments) {
|
||||
return sendSingleMail(toMails, ccMails, bccMails, userId, UserTypeEnum.ADMIN.getValue(),
|
||||
templateCode, templateParams);
|
||||
templateCode, templateParams, attachments);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -41,13 +44,15 @@ public interface MailSendService {
|
||||
* @param bccMails 密送邮箱
|
||||
* @param templateCode 邮件模版编码
|
||||
* @param templateParams 邮件模版参数
|
||||
* @param attachments 附件
|
||||
* @return 发送日志编号
|
||||
*/
|
||||
default Long sendSingleMailToMember(Long userId,
|
||||
Collection<String> toMails, Collection<String> ccMails, Collection<String> bccMails,
|
||||
String templateCode, Map<String, Object> templateParams) {
|
||||
String templateCode, Map<String, Object> templateParams,
|
||||
File... attachments) {
|
||||
return sendSingleMail(toMails, ccMails, bccMails, userId, UserTypeEnum.MEMBER.getValue(),
|
||||
templateCode, templateParams);
|
||||
templateCode, templateParams, attachments);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -60,11 +65,13 @@ public interface MailSendService {
|
||||
* @param userType 用户类型
|
||||
* @param templateCode 邮件模版编码
|
||||
* @param templateParams 邮件模版参数
|
||||
* @param attachments 附件
|
||||
* @return 发送日志编号
|
||||
*/
|
||||
Long sendSingleMail(Collection<String> toMails, Collection<String> ccMails, Collection<String> bccMails,
|
||||
Long userId, Integer userType,
|
||||
String templateCode, Map<String, Object> templateParams);
|
||||
String templateCode, Map<String, Object> templateParams,
|
||||
File... attachments);
|
||||
|
||||
/**
|
||||
* 执行真正的邮件发送
|
||||
|
||||
@@ -20,6 +20,7 @@ import org.dromara.hutool.extra.mail.MailUtil;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
@@ -56,7 +57,8 @@ public class MailSendServiceImpl implements MailSendService {
|
||||
@Override
|
||||
public Long sendSingleMail(Collection<String> toMails, Collection<String> ccMails, Collection<String> bccMails,
|
||||
Long userId, Integer userType,
|
||||
String templateCode, Map<String, Object> templateParams) {
|
||||
String templateCode, Map<String, Object> templateParams,
|
||||
File... attachments) {
|
||||
// 1.1 校验邮箱模版是否合法
|
||||
MailTemplateDO template = validateMailTemplate(templateCode);
|
||||
// 1.2 校验邮箱账号是否合法
|
||||
@@ -94,7 +96,7 @@ public class MailSendServiceImpl implements MailSendService {
|
||||
// 发送 MQ 消息,异步执行发送短信
|
||||
if (isSend) {
|
||||
mailProducer.sendMailSendMessage(sendLogId, toMailSet, ccMailSet, bccMailSet,
|
||||
account.getId(), template.getNickname(), title, content);
|
||||
account.getId(), template.getNickname(), title, content, attachments);
|
||||
}
|
||||
return sendLogId;
|
||||
}
|
||||
@@ -123,7 +125,7 @@ public class MailSendServiceImpl implements MailSendService {
|
||||
// 2. 发送邮件
|
||||
try {
|
||||
String messageId = MailUtil.send(mailAccount, message.getToMails(), message.getCcMails(), message.getBccMails(),
|
||||
message.getTitle(), message.getContent(), true);
|
||||
message.getTitle(), message.getContent(), true, message.getAttachments());
|
||||
// 3. 更新结果(成功)
|
||||
mailLogService.updateMailSendResult(message.getLogId(), messageId, null);
|
||||
} catch (Exception e) {
|
||||
|
||||
@@ -13,13 +13,15 @@ import cn.iocoder.yudao.module.system.mq.producer.mail.MailProducer;
|
||||
import cn.iocoder.yudao.module.system.service.member.MemberService;
|
||||
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
|
||||
import org.assertj.core.util.Lists;
|
||||
import org.dromara.hutool.extra.mail.*;
|
||||
import org.dromara.hutool.extra.mail.MailAccount;
|
||||
import org.dromara.hutool.extra.mail.MailUtil;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockedStatic;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@@ -106,7 +108,7 @@ public class MailSendServiceImplTest extends BaseMockitoUnitTest {
|
||||
|
||||
// 调用
|
||||
Long resultMailLogId = mailSendService.sendSingleMail(toMails, ccMails, bccMails, userId,
|
||||
UserTypeEnum.ADMIN.getValue(), templateCode, templateParams);
|
||||
UserTypeEnum.ADMIN.getValue(), templateCode, templateParams, (File[]) null);
|
||||
// 断言
|
||||
assertEquals(mailLogId, resultMailLogId);
|
||||
// 断言调用
|
||||
@@ -114,7 +116,7 @@ public class MailSendServiceImplTest extends BaseMockitoUnitTest {
|
||||
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));
|
||||
eq(account.getId()), eq(template.getNickname()), eq(title), eq(content), isNull());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -156,7 +158,7 @@ public class MailSendServiceImplTest extends BaseMockitoUnitTest {
|
||||
eq(account), eq(template), eq(content), eq(templateParams), eq(true))).thenReturn(mailLogId);
|
||||
|
||||
// 调用
|
||||
Long resultMailLogId = mailSendService.sendSingleMail(toMails, null, null, userId, userType, templateCode, templateParams);
|
||||
Long resultMailLogId = mailSendService.sendSingleMail(toMails, null, null, userId, userType, templateCode, templateParams, (java.io.File[]) null);
|
||||
// 断言
|
||||
assertEquals(mailLogId, resultMailLogId);
|
||||
// 断言调用
|
||||
@@ -164,7 +166,7 @@ public class MailSendServiceImplTest extends BaseMockitoUnitTest {
|
||||
argThat(toMailSet -> toMailSet.contains(mail)),
|
||||
argThat(Collection::isEmpty),
|
||||
argThat(Collection::isEmpty),
|
||||
eq(account.getId()), eq(template.getNickname()), eq(title), eq(content));
|
||||
eq(account.getId()), eq(template.getNickname()), eq(title), eq(content), isNull());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -206,12 +208,12 @@ public class MailSendServiceImplTest extends BaseMockitoUnitTest {
|
||||
eq(account), eq(template), eq(content), eq(templateParams), eq(false))).thenReturn(mailLogId);
|
||||
|
||||
// 调用
|
||||
Long resultMailLogId = mailSendService.sendSingleMail(toMails, null, null, userId, userType, templateCode, templateParams);
|
||||
Long resultMailLogId = mailSendService.sendSingleMail(toMails, null, null, userId, userType, templateCode, templateParams, (java.io.File[]) null);
|
||||
// 断言
|
||||
assertEquals(mailLogId, resultMailLogId);
|
||||
// 断言调用
|
||||
verify(mailProducer, times(0)).sendMailSendMessage(anyLong(), any(), any(), any(),
|
||||
anyLong(), anyString(), anyString(), anyString());
|
||||
anyLong(), anyString(), anyString(), anyString(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -261,7 +263,7 @@ public class MailSendServiceImplTest extends BaseMockitoUnitTest {
|
||||
|
||||
// 调用,并断言异常
|
||||
assertServiceException(() -> mailSendService.sendSingleMail(toMails, null, null, userId,
|
||||
UserTypeEnum.ADMIN.getValue(), templateCode, templateParams),
|
||||
UserTypeEnum.ADMIN.getValue(), templateCode, templateParams, (java.io.File[]) null),
|
||||
MAIL_SEND_MAIL_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@@ -288,7 +290,7 @@ public class MailSendServiceImplTest extends BaseMockitoUnitTest {
|
||||
assertEquals(account.getSslEnable(), mailAccount.isSslEnable());
|
||||
return true;
|
||||
}), eq(message.getToMails()), eq(message.getCcMails()), eq(message.getBccMails()),
|
||||
eq(message.getTitle()), eq(message.getContent()), eq(true)))
|
||||
eq(message.getTitle()), eq(message.getContent()), eq(true), eq(message.getAttachments())))
|
||||
.thenReturn(messageId);
|
||||
|
||||
// 调用
|
||||
@@ -310,17 +312,8 @@ public class MailSendServiceImplTest extends BaseMockitoUnitTest {
|
||||
|
||||
// mock 方法(发送邮件)
|
||||
Exception e = new NullPointerException("啦啦啦");
|
||||
mailUtilMock.when(() -> MailUtil.send(argThat(mailAccount -> {
|
||||
assertEquals("芋艿 <7685@qq.com>", mailAccount.getFrom());
|
||||
assertTrue(mailAccount.isAuth());
|
||||
assertEquals(account.getUsername(), mailAccount.getUser());
|
||||
assertArrayEquals(account.getPassword().toCharArray(), mailAccount.getPass());
|
||||
assertEquals(account.getHost(), mailAccount.getHost());
|
||||
assertEquals(account.getPort(), mailAccount.getPort());
|
||||
assertEquals(account.getSslEnable(), mailAccount.isSslEnable());
|
||||
return true;
|
||||
}), eq(message.getToMails()), eq(message.getCcMails()), eq(message.getBccMails()),
|
||||
eq(message.getTitle()), eq(message.getContent()), eq(true))).thenThrow(e);
|
||||
mailUtilMock.when(() -> MailUtil.send(any(MailAccount.class), any(), any(), any(),
|
||||
any(), any(), eq(true), any(java.io.File[].class))).thenThrow(e);
|
||||
|
||||
// 调用
|
||||
mailSendService.doSendMail(message);
|
||||
|
||||
Reference in New Issue
Block a user