Commit f743ffd195df4d38c19eb3a97c1feea159c7cb05

Authored by YunaiV
1 parent 3db0c41b

feat:【system】发送邮件时,携带附件,对应 https://gitee.com/zhijiantianya/yudao-cloud/pulls/233

yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/api/mail/MailSendApiImpl.java
... ... @@ -23,14 +23,14 @@ public class MailSendApiImpl implements MailSendApi {
23 23 public Long sendSingleMailToAdmin(MailSendSingleToUserReqDTO reqDTO) {
24 24 return mailSendService.sendSingleMailToAdmin(reqDTO.getUserId(),
25 25 reqDTO.getToMails(), reqDTO.getCcMails(), reqDTO.getBccMails(),
26   - reqDTO.getTemplateCode(), reqDTO.getTemplateParams());
  26 + reqDTO.getTemplateCode(), reqDTO.getTemplateParams(), reqDTO.getAttachments());
27 27 }
28 28  
29 29 @Override
30 30 public Long sendSingleMailToMember(MailSendSingleToUserReqDTO reqDTO) {
31 31 return mailSendService.sendSingleMailToMember(reqDTO.getUserId(),
32 32 reqDTO.getToMails(), reqDTO.getCcMails(), reqDTO.getBccMails(),
33   - reqDTO.getTemplateCode(), reqDTO.getTemplateParams());
  33 + reqDTO.getTemplateCode(), reqDTO.getTemplateParams(), reqDTO.getAttachments());
34 34 }
35 35  
36 36 }
... ...
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/api/mail/dto/MailSendSingleToUserReqDTO.java
1 1 package cn.iocoder.yudao.module.system.api.mail.dto;
2 2  
3   -import lombok.Data;
4   -
5 3 import jakarta.validation.constraints.Email;
6 4 import jakarta.validation.constraints.NotNull;
  5 +import lombok.Data;
7 6  
  7 +import java.io.File;
8 8 import java.util.List;
9 9 import java.util.Map;
10 10  
... ... @@ -47,4 +47,9 @@ public class MailSendSingleToUserReqDTO {
47 47 */
48 48 private Map<String, Object> templateParams;
49 49  
  50 + /**
  51 + * 附件
  52 + */
  53 + private File[] attachments;
  54 +
50 55 }
... ...
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/mq/message/mail/MailSendMessage.java
1 1 package cn.iocoder.yudao.module.system.mq.message.mail;
2 2  
3   -import lombok.Data;
4   -
5 3 import jakarta.validation.constraints.NotEmpty;
6 4 import jakarta.validation.constraints.NotNull;
  5 +import lombok.Data;
7 6  
  7 +import java.io.File;
8 8 import java.util.Collection;
9   -import java.util.List;
10 9  
11 10 /**
12 11 * 邮箱发送消息
... ... @@ -55,4 +54,9 @@ public class MailSendMessage {
55 54 @NotEmpty(message = "邮件内容不能为空")
56 55 private String content;
57 56  
  57 + /**
  58 + * 附件
  59 + */
  60 + private File[] attachments;
  61 +
58 62 }
... ...
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/mq/producer/mail/MailProducer.java
1 1 package cn.iocoder.yudao.module.system.mq.producer.mail;
2 2  
3 3 import cn.iocoder.yudao.module.system.mq.message.mail.MailSendMessage;
  4 +import jakarta.annotation.Resource;
4 5 import lombok.extern.slf4j.Slf4j;
5 6 import org.springframework.context.ApplicationContext;
6 7 import org.springframework.stereotype.Component;
7 8  
8   -import jakarta.annotation.Resource;
9   -
  9 +import java.io.File;
10 10 import java.util.Collection;
11   -import java.util.List;
12   -
13   -import static java.util.Collections.singletonList;
14 11  
15 12 /**
16 13 * Mail 邮件相关消息的 Producer
... ... @@ -28,23 +25,25 @@ public class MailProducer {
28 25 /**
29 26 * 发送 {@link MailSendMessage} 消息
30 27 *
31   - * @param sendLogId 发送日志编码
32   - * @param toMails 接收邮件地址
33   - * @param ccMails 抄送邮件地址
34   - * @param bccMails 密送邮件地址
35   - * @param accountId 邮件账号编号
36   - * @param nickname 邮件发件人
37   - * @param title 邮件标题
38   - * @param content 邮件内容
  28 + * @param sendLogId 发送日志编码
  29 + * @param toMails 接收邮件地址
  30 + * @param ccMails 抄送邮件地址
  31 + * @param bccMails 密送邮件地址
  32 + * @param accountId 邮件账号编号
  33 + * @param nickname 邮件发件人
  34 + * @param title 邮件标题
  35 + * @param content 邮件内容
  36 + * @param attachments 附件
39 37 */
40 38 public void sendMailSendMessage(Long sendLogId,
41 39 Collection<String> toMails, Collection<String> ccMails, Collection<String> bccMails,
42   - Long accountId, String nickname, String title, String content) {
  40 + Long accountId, String nickname, String title, String content,
  41 + File[] attachments) {
43 42 MailSendMessage message = new MailSendMessage()
44 43 .setLogId(sendLogId)
45 44 .setToMails(toMails).setCcMails(ccMails).setBccMails(bccMails)
46 45 .setAccountId(accountId).setNickname(nickname)
47   - .setTitle(title).setContent(content);
  46 + .setTitle(title).setContent(content).setAttachments(attachments);
48 47 applicationContext.publishEvent(message);
49 48 }
50 49  
... ...
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/mail/MailSendService.java
... ... @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.system.service.mail;
3 3 import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
4 4 import cn.iocoder.yudao.module.system.mq.message.mail.MailSendMessage;
5 5  
  6 +import java.io.File;
6 7 import java.util.Collection;
7 8 import java.util.Map;
8 9  
... ... @@ -23,13 +24,15 @@ public interface MailSendService {
23 24 * @param bccMails 密送邮箱
24 25 * @param templateCode 邮件模版编码
25 26 * @param templateParams 邮件模版参数
  27 + * @param attachments 附件
26 28 * @return 发送日志编号
27 29 */
28 30 default Long sendSingleMailToAdmin(Long userId,
29 31 Collection<String> toMails, Collection<String> ccMails, Collection<String> bccMails,
30   - String templateCode, Map<String, Object> templateParams) {
  32 + String templateCode, Map<String, Object> templateParams,
  33 + File... attachments) {
31 34 return sendSingleMail(toMails, ccMails, bccMails, userId, UserTypeEnum.ADMIN.getValue(),
32   - templateCode, templateParams);
  35 + templateCode, templateParams, attachments);
33 36 }
34 37  
35 38 /**
... ... @@ -41,13 +44,15 @@ public interface MailSendService {
41 44 * @param bccMails 密送邮箱
42 45 * @param templateCode 邮件模版编码
43 46 * @param templateParams 邮件模版参数
  47 + * @param attachments 附件
44 48 * @return 发送日志编号
45 49 */
46 50 default Long sendSingleMailToMember(Long userId,
47 51 Collection<String> toMails, Collection<String> ccMails, Collection<String> bccMails,
48   - String templateCode, Map<String, Object> templateParams) {
  52 + String templateCode, Map<String, Object> templateParams,
  53 + File... attachments) {
49 54 return sendSingleMail(toMails, ccMails, bccMails, userId, UserTypeEnum.MEMBER.getValue(),
50   - templateCode, templateParams);
  55 + templateCode, templateParams, attachments);
51 56 }
52 57  
53 58 /**
... ... @@ -60,11 +65,13 @@ public interface MailSendService {
60 65 * @param userType 用户类型
61 66 * @param templateCode 邮件模版编码
62 67 * @param templateParams 邮件模版参数
  68 + * @param attachments 附件
63 69 * @return 发送日志编号
64 70 */
65 71 Long sendSingleMail(Collection<String> toMails, Collection<String> ccMails, Collection<String> bccMails,
66 72 Long userId, Integer userType,
67   - String templateCode, Map<String, Object> templateParams);
  73 + String templateCode, Map<String, Object> templateParams,
  74 + File... attachments);
68 75  
69 76 /**
70 77 * 执行真正的邮件发送
... ...
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/mail/MailSendServiceImpl.java
... ... @@ -20,6 +20,7 @@ import org.dromara.hutool.extra.mail.MailUtil;
20 20 import org.springframework.stereotype.Service;
21 21 import org.springframework.validation.annotation.Validated;
22 22  
  23 +import java.io.File;
23 24 import java.util.Collection;
24 25 import java.util.LinkedHashSet;
25 26 import java.util.Map;
... ... @@ -56,7 +57,8 @@ public class MailSendServiceImpl implements MailSendService {
56 57 @Override
57 58 public Long sendSingleMail(Collection<String> toMails, Collection<String> ccMails, Collection<String> bccMails,
58 59 Long userId, Integer userType,
59   - String templateCode, Map<String, Object> templateParams) {
  60 + String templateCode, Map<String, Object> templateParams,
  61 + File... attachments) {
60 62 // 1.1 校验邮箱模版是否合法
61 63 MailTemplateDO template = validateMailTemplate(templateCode);
62 64 // 1.2 校验邮箱账号是否合法
... ... @@ -94,7 +96,7 @@ public class MailSendServiceImpl implements MailSendService {
94 96 // 发送 MQ 消息,异步执行发送短信
95 97 if (isSend) {
96 98 mailProducer.sendMailSendMessage(sendLogId, toMailSet, ccMailSet, bccMailSet,
97   - account.getId(), template.getNickname(), title, content);
  99 + account.getId(), template.getNickname(), title, content, attachments);
98 100 }
99 101 return sendLogId;
100 102 }
... ... @@ -123,7 +125,7 @@ public class MailSendServiceImpl implements MailSendService {
123 125 // 2. 发送邮件
124 126 try {
125 127 String messageId = MailUtil.send(mailAccount, message.getToMails(), message.getCcMails(), message.getBccMails(),
126   - message.getTitle(), message.getContent(), true);
  128 + message.getTitle(), message.getContent(), true, message.getAttachments());
127 129 // 3. 更新结果(成功)
128 130 mailLogService.updateMailSendResult(message.getLogId(), messageId, null);
129 131 } catch (Exception e) {
... ...
yudao-module-system/src/test/java/cn/iocoder/yudao/module/system/service/mail/MailSendServiceImplTest.java
... ... @@ -13,13 +13,15 @@ import cn.iocoder.yudao.module.system.mq.producer.mail.MailProducer;
13 13 import cn.iocoder.yudao.module.system.service.member.MemberService;
14 14 import cn.iocoder.yudao.module.system.service.user.AdminUserService;
15 15 import org.assertj.core.util.Lists;
16   -import org.dromara.hutool.extra.mail.*;
  16 +import org.dromara.hutool.extra.mail.MailAccount;
  17 +import org.dromara.hutool.extra.mail.MailUtil;
17 18 import org.junit.jupiter.api.Disabled;
18 19 import org.junit.jupiter.api.Test;
19 20 import org.mockito.InjectMocks;
20 21 import org.mockito.Mock;
21 22 import org.mockito.MockedStatic;
22 23  
  24 +import java.io.File;
23 25 import java.util.Collection;
24 26 import java.util.HashMap;
25 27 import java.util.Map;
... ... @@ -106,7 +108,7 @@ public class MailSendServiceImplTest extends BaseMockitoUnitTest {
106 108  
107 109 // 调用
108 110 Long resultMailLogId = mailSendService.sendSingleMail(toMails, ccMails, bccMails, userId,
109   - UserTypeEnum.ADMIN.getValue(), templateCode, templateParams);
  111 + UserTypeEnum.ADMIN.getValue(), templateCode, templateParams, (File[]) null);
110 112 // 断言
111 113 assertEquals(mailLogId, resultMailLogId);
112 114 // 断言调用
... ... @@ -114,7 +116,7 @@ public class MailSendServiceImplTest extends BaseMockitoUnitTest {
114 116 argThat(toMailSet -> toMailSet.contains(user.getEmail()) && toMailSet.contains("admin@test.com")),
115 117 argThat(ccMailSet -> ccMailSet.contains("cc@test.com")),
116 118 argThat(bccMailSet -> bccMailSet.contains("bcc@test.com")),
117   - eq(account.getId()), eq(template.getNickname()), eq(title), eq(content));
  119 + eq(account.getId()), eq(template.getNickname()), eq(title), eq(content), isNull());
118 120 }
119 121  
120 122 /**
... ... @@ -156,7 +158,7 @@ public class MailSendServiceImplTest extends BaseMockitoUnitTest {
156 158 eq(account), eq(template), eq(content), eq(templateParams), eq(true))).thenReturn(mailLogId);
157 159  
158 160 // 调用
159   - Long resultMailLogId = mailSendService.sendSingleMail(toMails, null, null, userId, userType, templateCode, templateParams);
  161 + Long resultMailLogId = mailSendService.sendSingleMail(toMails, null, null, userId, userType, templateCode, templateParams, (java.io.File[]) null);
160 162 // 断言
161 163 assertEquals(mailLogId, resultMailLogId);
162 164 // 断言调用
... ... @@ -164,7 +166,7 @@ public class MailSendServiceImplTest extends BaseMockitoUnitTest {
164 166 argThat(toMailSet -> toMailSet.contains(mail)),
165 167 argThat(Collection::isEmpty),
166 168 argThat(Collection::isEmpty),
167   - eq(account.getId()), eq(template.getNickname()), eq(title), eq(content));
  169 + eq(account.getId()), eq(template.getNickname()), eq(title), eq(content), isNull());
168 170 }
169 171  
170 172 /**
... ... @@ -206,12 +208,12 @@ public class MailSendServiceImplTest extends BaseMockitoUnitTest {
206 208 eq(account), eq(template), eq(content), eq(templateParams), eq(false))).thenReturn(mailLogId);
207 209  
208 210 // 调用
209   - Long resultMailLogId = mailSendService.sendSingleMail(toMails, null, null, userId, userType, templateCode, templateParams);
  211 + Long resultMailLogId = mailSendService.sendSingleMail(toMails, null, null, userId, userType, templateCode, templateParams, (java.io.File[]) null);
210 212 // 断言
211 213 assertEquals(mailLogId, resultMailLogId);
212 214 // 断言调用
213 215 verify(mailProducer, times(0)).sendMailSendMessage(anyLong(), any(), any(), any(),
214   - anyLong(), anyString(), anyString(), anyString());
  216 + anyLong(), anyString(), anyString(), anyString(), any());
215 217 }
216 218  
217 219 @Test
... ... @@ -261,7 +263,7 @@ public class MailSendServiceImplTest extends BaseMockitoUnitTest {
261 263  
262 264 // 调用,并断言异常
263 265 assertServiceException(() -> mailSendService.sendSingleMail(toMails, null, null, userId,
264   - UserTypeEnum.ADMIN.getValue(), templateCode, templateParams),
  266 + UserTypeEnum.ADMIN.getValue(), templateCode, templateParams, (java.io.File[]) null),
265 267 MAIL_SEND_MAIL_NOT_EXISTS);
266 268 }
267 269  
... ... @@ -288,7 +290,7 @@ public class MailSendServiceImplTest extends BaseMockitoUnitTest {
288 290 assertEquals(account.getSslEnable(), mailAccount.isSslEnable());
289 291 return true;
290 292 }), eq(message.getToMails()), eq(message.getCcMails()), eq(message.getBccMails()),
291   - eq(message.getTitle()), eq(message.getContent()), eq(true)))
  293 + eq(message.getTitle()), eq(message.getContent()), eq(true), eq(message.getAttachments())))
292 294 .thenReturn(messageId);
293 295  
294 296 // 调用
... ... @@ -310,17 +312,8 @@ public class MailSendServiceImplTest extends BaseMockitoUnitTest {
310 312  
311 313 // mock 方法(发送邮件)
312 314 Exception e = new NullPointerException("啦啦啦");
313   - mailUtilMock.when(() -> MailUtil.send(argThat(mailAccount -> {
314   - assertEquals("芋艿 <7685@qq.com>", mailAccount.getFrom());
315   - assertTrue(mailAccount.isAuth());
316   - assertEquals(account.getUsername(), mailAccount.getUser());
317   - assertArrayEquals(account.getPassword().toCharArray(), mailAccount.getPass());
318   - assertEquals(account.getHost(), mailAccount.getHost());
319   - assertEquals(account.getPort(), mailAccount.getPort());
320   - assertEquals(account.getSslEnable(), mailAccount.isSslEnable());
321   - return true;
322   - }), eq(message.getToMails()), eq(message.getCcMails()), eq(message.getBccMails()),
323   - eq(message.getTitle()), eq(message.getContent()), eq(true))).thenThrow(e);
  315 + mailUtilMock.when(() -> MailUtil.send(any(MailAccount.class), any(), any(), any(),
  316 + any(), any(), eq(true), any(java.io.File[].class))).thenThrow(e);
324 317  
325 318 // 调用
326 319 mailSendService.doSendMail(message);
... ...