Commit f9ab45df181b791da899bbd1327c7f9a436d7107

Authored by YunaiV
1 parent afced9d4

邮箱模块:完善 log 相关表结构

Showing 13 changed files with 141 additions and 148 deletions
yudao-module-system/yudao-module-system-biz/pom.xml
... ... @@ -106,6 +106,10 @@
106 106 <artifactId>yudao-spring-boot-starter-captcha</artifactId>
107 107 </dependency>
108 108  
  109 + <dependency>
  110 + <groupId>org.springframework.boot</groupId>
  111 + <artifactId>spring-boot-starter-mail</artifactId>
  112 + </dependency>
109 113 </dependencies>
110 114  
111 115 </project>
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/MailTemplateController.http 0 → 100644
  1 +### 请求 /system/mail-template/send-mail 接口 => 成功
  2 +POST {{baseUrl}}/system/mail-template/send-mail
  3 +Authorization: Bearer {{token}}
  4 +Content-Type: application/json
  5 +tenant-id: {{adminTenentId}}
  6 +
  7 +{
  8 + "templateCode": "test_01",
  9 + "mail": "7685413@qq.com",
  10 + "templateParams": {
  11 + "key01": "value01",
  12 + "key02": "value02"
  13 + }
  14 +}
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/MailTemplateController.java
... ... @@ -3,8 +3,10 @@ package cn.iocoder.yudao.module.system.controller.admin.mail;
3 3 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 5 import cn.iocoder.yudao.module.system.controller.admin.mail.vo.template.*;
  6 +import cn.iocoder.yudao.module.system.controller.admin.sms.vo.template.SmsTemplateSendReqVO;
6 7 import cn.iocoder.yudao.module.system.convert.mail.MailTemplateConvert;
7 8 import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailTemplateDO;
  9 +import cn.iocoder.yudao.module.system.service.mail.MailSendService;
8 10 import cn.iocoder.yudao.module.system.service.mail.MailTemplateService;
9 11 import io.swagger.annotations.Api;
10 12 import io.swagger.annotations.ApiImplicitParam;
... ... @@ -25,6 +27,8 @@ public class MailTemplateController {
25 27  
26 28 @Resource
27 29 private MailTemplateService mailTempleService;
  30 + @Resource
  31 + private MailSendService mailSendService;
28 32  
29 33 @PostMapping("/create")
30 34 @ApiOperation("创建邮件模版")
... ... @@ -73,4 +77,13 @@ public class MailTemplateController {
73 77 List<MailTemplateDO> list = mailTempleService.getMailTemplateList();
74 78 return success(MailTemplateConvert.INSTANCE.convertList02(list));
75 79 }
  80 +
  81 + @PostMapping("/send-mail")
  82 + @ApiOperation("发送短信")
  83 + @PreAuthorize("@ss.hasPermission('system:mail-template:send-mail')")
  84 + public CommonResult<Long> sendMail(@Valid @RequestBody MailTemplateSendReqVO sendReqVO) {
  85 + return success(mailSendService.sendSingleMailToAdmin(sendReqVO.getMail(), null,
  86 + sendReqVO.getTemplateCode(), sendReqVO.getTemplateParams()));
  87 + }
  88 +
76 89 }
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/send/MailReqVO.java deleted
1   -package cn.iocoder.yudao.module.system.controller.admin.mail.vo.send;
2   -
3   -import io.swagger.annotations.ApiModel;
4   -import io.swagger.annotations.ApiModelProperty;
5   -import lombok.Data;
6   -
7   -import javax.validation.constraints.Email;
8   -import javax.validation.constraints.NotNull;
9   -import java.util.List;
10   -
11   -@ApiModel("管理后台 - 邮件发送 Req VO")
12   -@Data
13   -public class MailReqVO { // TODO @wangjingqi:1), 不用空格;2)应该只要传递 templateCode、参数就好,title、from、content、附件应该都是参数里的
14   -
15   - @ApiModelProperty(value = "邮箱",required = true,example = "yudaoyuanma@123.com")
16   - @NotNull(message = "邮箱账号不能为空")
17   - @Email(message = "邮箱账号格式错误")
18   - private String from;
19   -
20   - @ApiModelProperty(value = "标题",example = "标题")
21   - private String title;
22   -
23   - @ApiModelProperty(value = "内容",example = "内容")
24   - private String content;
25   -
26   - @ApiModelProperty(value = "邮箱模版id",example = "1024")
27   - @NotNull(message = "邮箱模版id不能为空")
28   - private Integer templateId;
29   -
30   - @ApiModelProperty(value = "收件人",required = true,example = "yudaoyuanma@123.com")
31   - @NotNull(message = "收件人不能为空")
32   - private List<String> tos;
33   -
34   - @ApiModelProperty(value = "附件",example = "附件编码")
35   - private List<String> fileIds;
36   -
37   -}
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/template/MailTemplateSendReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.system.controller.admin.mail.vo.template;
  2 +
  3 +import io.swagger.annotations.ApiModel;
  4 +import io.swagger.annotations.ApiModelProperty;
  5 +import lombok.Data;
  6 +
  7 +import javax.validation.constraints.NotEmpty;
  8 +import javax.validation.constraints.NotNull;
  9 +import java.util.Map;
  10 +
  11 +@ApiModel("管理后台 - 邮件发送 Req VO")
  12 +@Data
  13 +public class MailTemplateSendReqVO {
  14 +
  15 + @ApiModelProperty(value = "接收邮箱", required = true, example = "7685413@qq.com")
  16 + @NotEmpty(message = "接收邮箱不能为空")
  17 + private String mail;
  18 +
  19 + @ApiModelProperty(value = "模板编码", required = true, example = "test_01")
  20 + @NotNull(message = "模板编码不能为空")
  21 + private String templateCode;
  22 +
  23 + @ApiModelProperty(value = "模板参数")
  24 + private Map<String, Object> templateParams;
  25 +
  26 +}
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/mail/MailAccountConvert.java
... ... @@ -33,7 +33,7 @@ public interface MailAccountConvert {
33 33 .setHost(bean.getHost())
34 34 .setPort(bean.getPort())
35 35 .setAuth(true)
36   - .setFrom(bean.getFromAddress())
  36 + .setFrom(bean.getMail())
37 37 .setUser(bean.getUsername())
38 38 .setPass(bean.getPassword())
39 39 .setSslEnable(bean.getSslEnable());
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/mail/MailLogDO.java
... ... @@ -96,7 +96,7 @@ public class MailLogDO extends BaseDO implements Serializable {
96 96 * 基于 {@link MailTemplateDO#getParams()} 输入后的参数
97 97 */
98 98 @TableField(typeHandler = JacksonTypeHandler.class)
99   - private Map<String,Object> templateParams;
  99 + private Map<String, Object> templateParams;
100 100  
101 101 // ========= 发送相关字段 =========
102 102 /**
... ... @@ -109,16 +109,13 @@ public class MailLogDO extends BaseDO implements Serializable {
109 109 * 发送时间
110 110 */
111 111 private Date sendTime;
112   -
113   - // ========= 接收相关字段 =========
114 112 /**
115   - * 发送结果
  113 + * 发送返回的消息 ID
116 114 */
117   - private String sendResult;
  115 + private String sendMessageId;
118 116 /**
119   - * 消息ID
  117 + * 发送结果
120 118 */
121   - private String messageId;
122   -
  119 + private String sendResult;
123 120  
124 121 }
... ...
yudao-module-system/yudao-module-system-biz/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 cn.iocoder.yudao.framework.common.core.KeyValue;
4 3 import cn.iocoder.yudao.framework.mq.core.stream.AbstractStreamMessage;
5 4 import lombok.Data;
6 5 import lombok.EqualsAndHashCode;
7 6  
  7 +import javax.validation.constraints.NotEmpty;
8 8 import javax.validation.constraints.NotNull;
9   -import java.util.List;
10   -import java.util.Map;
11 9  
12 10 /**
13 11 * 邮箱发送消息
... ... @@ -19,61 +17,35 @@ import java.util.Map;
19 17 public class MailSendMessage extends AbstractStreamMessage {
20 18  
21 19 /**
22   - * 日志id
  20 + * 邮件日志编号
23 21 */
24   - @NotNull(message = "邮箱日志id不能为空")
  22 + @NotNull(message = "邮件日志编号不能为空")
25 23 private Long logId;
26 24 /**
27   - * 邮箱地址
  25 + * 接收邮件地址
28 26 */
29   - @NotNull(message = "邮箱地址不能为空")
30   - private String fromAddress;
  27 + @NotNull(message = "接收邮件地址不能为空")
  28 + private String mail;
31 29 /**
32   - * 用户名
  30 + * 邮件账号编号
33 31 */
34   - @NotNull(message = "用户名不能为空")
35   - private String username;
36   - /**
37   - * 密码
38   - */
39   - @NotNull(message = "密码不能为空")
40   - private String password;
41   - /**
42   - * 邮箱模板编号
43   - */
44   - @NotNull(message = "邮箱模板编号不能为空")
45   - private String templateCode;
  32 + @NotNull(message = "邮件账号编号不能为空")
  33 + private Long accountId;
  34 +
46 35 /**
47   - * 收件人
  36 + * 邮件发件人
48 37 */
49   - @NotNull(message = "收件人不能为空")
50   - private String to;
  38 + private String nickname;
51 39 /**
52   - * 标题
  40 + * 邮件标题
53 41 */
  42 + @NotEmpty(message = "邮件标题不能为空")
54 43 private String title;
55 44 /**
56   - * 内容
  45 + * 邮件内容
57 46 */
  47 + @NotEmpty(message = "邮件内容不能为空")
58 48 private String content;
59   - /**
60   - * 主机
61   - */
62   - @NotNull(message = "host不能为空")
63   - private String host;
64   - /**
65   - * 端口
66   - */
67   - @NotNull(message = "端口号不能为空")
68   - private Integer port;
69   - /**
70   - * 是否开启 SSL
71   - */
72   - private Boolean sslEnable;
73   - /**
74   - * 邮箱模板参数
75   - */
76   - private List<KeyValue<String, Object>> templateParams;
77 49  
78 50 @Override
79 51 public String getStreamKey() {
... ...
yudao-module-system/yudao-module-system-biz/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   -import cn.iocoder.yudao.framework.common.core.KeyValue;
4 3 import cn.iocoder.yudao.framework.mq.core.RedisMQTemplate;
5   -import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailAccountDO;
6   -import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailTemplateDO;
7 4 import cn.iocoder.yudao.module.system.mq.message.mail.MailAccountRefreshMessage;
8 5 import cn.iocoder.yudao.module.system.mq.message.mail.MailSendMessage;
9 6 import cn.iocoder.yudao.module.system.mq.message.mail.MailTemplateRefreshMessage;
... ... @@ -11,13 +8,12 @@ import lombok.extern.slf4j.Slf4j;
11 8 import org.springframework.stereotype.Component;
12 9  
13 10 import javax.annotation.Resource;
14   -import java.util.List;
15 11  
16 12 /**
17 13 * Mail 邮件相关消息的 Producer
18 14 *
19 15 * @author wangjingyi
20   - * @date 2021/4/19 13:33
  16 + * @since 2021/4/19 13:33
21 17 */
22 18 @Slf4j
23 19 @Component
... ... @@ -46,26 +42,18 @@ public class MailProducer {
46 42 * 发送 {@link MailSendMessage} 消息
47 43 *
48 44 * @param sendLogId 发送日志编码
49   - * @param mailAccountDO 邮箱账号信息
50   - * @param mailTemplateDO 邮箱模版信息
51   - * @param content 内容
52   - * @param templateParams 邮箱模版参数
53   - * @param to 收件人
  45 + * @param mail 接收邮件地址
  46 + * @param accountId 邮件账号编号
  47 + * @param nickname 邮件发件人
  48 + * @param title 邮件标题
  49 + * @param content 邮件内容
54 50 */
55   - public void sendMailSendMessage(Long sendLogId,MailAccountDO mailAccountDO, MailTemplateDO mailTemplateDO, String content,List<KeyValue<String, Object>> templateParams,String to) {
56   - MailSendMessage message = new MailSendMessage();
57   - message.setContent(content)
58   - .setFromAddress(mailAccountDO.getMail())
59   - .setHost(mailAccountDO.getHost())
60   - .setPort(mailAccountDO.getPort())
61   - .setPassword(mailAccountDO.getPassword())
62   - .setUsername(mailAccountDO.getUsername())
63   - .setSslEnable(mailAccountDO.getSslEnable())
64   - .setTemplateCode(mailTemplateDO.getCode())
65   - .setTitle(mailTemplateDO.getTitle())
66   - .setTo(to)
67   - .setLogId(sendLogId)
68   - .setTemplateParams(templateParams);
  51 + public void sendMailSendMessage(Long sendLogId, String mail, Long accountId,
  52 + String nickname, String title, String content) {
  53 + MailSendMessage message = new MailSendMessage()
  54 + .setLogId(sendLogId).setMail(mail).setAccountId(accountId)
  55 + .setNickname(nickname).setTitle(title).setContent(content);
69 56 redisMQTemplate.send(message);
70 57 }
  58 +
71 59 }
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/mail/MailLogService.java
... ... @@ -11,7 +11,7 @@ import java.util.List;
11 11 import java.util.Map;
12 12  
13 13 /**
14   - * 邮箱日志服务类
  14 + * 邮件日志 Service 接口
15 15 *
16 16 * @author wangjingyi
17 17 * @since 2022-03-21
... ... @@ -19,7 +19,7 @@ import java.util.Map;
19 19 public interface MailLogService {
20 20  
21 21 /**
22   - * 邮箱日志分页
  22 + * 邮件日志分页
23 23 *
24 24 * @param pageVO 分页参数
25 25 * @return 分页结果
... ... @@ -27,7 +27,7 @@ public interface MailLogService {
27 27 PageResult<MailLogDO> getMailLogPage(MailLogPageReqVO pageVO);
28 28  
29 29 /**
30   - * 邮箱日志数组信息
  30 + * 邮件日志数组信息
31 31 *
32 32 * @param exportReqVO 导出筛选请求
33 33 * @return 导出的日志数据
... ... @@ -35,12 +35,12 @@ public interface MailLogService {
35 35 List<MailLogDO> getMailLogList(MailLogExportReqVO exportReqVO);
36 36  
37 37 /**
38   - * 创建邮箱日志
  38 + * 创建邮件日志
39 39 *
40 40 * @param userId 用户编码
41 41 * @param userType 用户类型
42 42 * @param to 收件人
43   - * @param mailAccountDO 邮箱账号信息
  43 + * @param mailAccountDO 邮件账号信息
44 44 * @param template 模版信息
45 45 * @param templateContent 模版内容
46 46 * @param templateParams 模版参数
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/mail/MailLogServiceImpl.java
... ... @@ -8,7 +8,6 @@ import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailLogDO;
8 8 import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailTemplateDO;
9 9 import cn.iocoder.yudao.module.system.dal.mysql.mail.MailLogMapper;
10 10 import cn.iocoder.yudao.module.system.enums.mail.MailSendStatusEnum;
11   -import cn.iocoder.yudao.module.system.service.mail.MailLogService;
12 11 import org.springframework.stereotype.Service;
13 12 import org.springframework.validation.annotation.Validated;
14 13  
... ... @@ -19,7 +18,7 @@ import java.util.Map;
19 18 import java.util.Objects;
20 19  
21 20 /**
22   - * 邮箱日志实现类
  21 + * 邮件日志 Service 实现类
23 22 *
24 23 * @author wangjingyi
25 24 * @since 2022-03-21
... ... @@ -42,29 +41,19 @@ public class MailLogServiceImpl implements MailLogService {
42 41 }
43 42  
44 43 @Override
45   - public Long createMailLog(Long userId,Integer userType,String to,MailAccountDO mailAccountDO, MailTemplateDO template , String templateContent, Map<String, Object> templateParams, Boolean isSend) {
  44 + public Long createMailLog(Long userId, Integer userType, String toMail,
  45 + MailAccountDO account, MailTemplateDO template,
  46 + String templateContent, Map<String, Object> templateParams, Boolean isSend) {
46 47 MailLogDO.MailLogDOBuilder logDOBuilder = MailLogDO.builder();
47   - // TODO @wangjingyi:使用 builder 的时候,不用每个 set 是一行。DONE
48 48 // 根据是否要发送,设置状态
49 49 logDOBuilder.sendStatus(Objects.equals(isSend, true) ? MailSendStatusEnum.INIT.getStatus()
50 50 : MailSendStatusEnum.IGNORE.getStatus())
51   - // 设置邮箱相关字段
52   - .fromMail(mailAccountDO.getMail())
53   - .accountId(mailAccountDO.getId())
54   - // TODO @wangjingyi:userId、userType
55   - //用户信息
56   - .userId(userId).userType(userType)
57   - //模版信息
58   - .templateId(template.getId()).templateParams(templateParams).templateContent(templateContent);
59   -
60   -
61   - logDOBuilder.fromMail(mailAccountDO.getMail());
62   - logDOBuilder.accountId(mailAccountDO.getId());
63   - // TODO @wangjingyi:每个接收人一条日志。发送多个人,就调用多次,业务方。因为某个邮箱有问题,会导致所有都发送失败。 DONE
64   - // 设置模板相关字段
65   - // TODO @wangjingyi:可以参考下 sms 短信的逻辑,templateContent、templateParams
66   - // TODO @wangjingyi:有结果的时候,才是 sendTime 哈 DONE
67   - //logDOBuilder.sendTime(new Date());
  51 + // 用户信息
  52 + .userId(userId).userType(userType).toMail(toMail)
  53 + .accountId(account.getId()).fromMail(account.getMail())
  54 + // 模板相关字段
  55 + .templateId(template.getId()).templateCode(template.getCode()).templateNickname(template.getNickname())
  56 + .templateTitle(template.getTitle()).templateContent(templateContent).templateParams(templateParams);
68 57  
69 58 // 插入数据库
70 59 MailLogDO logDO = logDOBuilder.build();
... ... @@ -76,7 +65,7 @@ public class MailLogServiceImpl implements MailLogService {
76 65 @Override
77 66 public void updateMailSendResult(Long logId, String result) {
78 67 MailLogDO.MailLogDOBuilder logDOBuilder = MailLogDO.builder();
79   - logDOBuilder.id(logId).sendTime(new Date()).sendResult(result).messageId(result).sendStatus(MailSendStatusEnum.SUCCESS.getStatus());
  68 + logDOBuilder.id(logId).sendTime(new Date()).sendResult(result).sendMessageId(result).sendStatus(MailSendStatusEnum.SUCCESS.getStatus());
80 69 MailLogDO mailLogDO = logDOBuilder.build();
81 70 mailLogMapper.updateById(mailLogDO);
82 71 }
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/mail/MailSendServiceImpl.java
... ... @@ -100,22 +100,23 @@ public class MailSendServiceImpl implements MailSendService {
100 100 Boolean isSend = CommonStatusEnum.ENABLE.getStatus().equals(template.getStatus());
101 101 String content = mailTemplateService.formatMailTemplateContent(template.getContent(), templateParams);
102 102 Long sendLogId = mailLogService.createMailLog(userId, userType, mail,
103   - account, template, content, templateParams, isSend); // TODO 芋艿:待测试
  103 + account, template, content, templateParams, isSend);
104 104 // 发送 MQ 消息,异步执行发送短信
105 105 if (isSend) {
106   - mailProducer.sendMailSendMessage(sendLogId, account, template, content, newTemplateParams, mail); // TODO 芋艿:待测试
  106 + mailProducer.sendMailSendMessage(sendLogId, mail, account.getId(),
  107 + template.getNickname(), template.getTitle(), content);
107 108 }
108 109 return sendLogId;
109 110 }
110 111  
111 112 @Override
112 113 public void doSendMail(MailSendMessage message) {
113   - // TODO @wangjingyi:直接使用 hutool 发送,不要封装 mail client 哈,因为短信的客户端都是比较统一的 DONE
114   - //装载账号信息
115   - MailAccount account = MailAccountConvert.INSTANCE.convertAccount(message);
116   - //发送邮件
  114 + // 装载账号信息
  115 + MailAccount mailAccount = MailAccountConvert.INSTANCE.convertAccount(message);
  116 + // 发送邮件
117 117 try {
118   - String messageId = MailUtil.send(account,message.getTo(),message.getTitle(),message.getContent(),false,null);
  118 + String messageId = MailUtil.send(mailAccount, message.getMail(),
  119 + message.getTitle(), message.getContent(),true);
119 120 mailLogService.updateMailSendResult(message.getLogId() , messageId);
120 121 } catch (Exception e){
121 122 mailLogService.updateFailMailSendResult(message.getLogId() , e.getMessage());
... ...
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/mail/MailSendServiceImplTest.java 0 → 100644
  1 +package cn.iocoder.yudao.module.system.service.mail;
  2 +
  3 +import cn.hutool.extra.mail.MailAccount;
  4 +import cn.hutool.extra.mail.MailUtil;
  5 +import org.junit.jupiter.api.Disabled;
  6 +import org.junit.jupiter.api.Test;
  7 +
  8 +import static org.junit.jupiter.api.Assertions.*;
  9 +
  10 +class MailSendServiceImplTest {
  11 +
  12 + /**
  13 + * 用于快速测试你的邮箱账号是否正常
  14 + */
  15 + @Test
  16 + @Disabled
  17 + public void testDemo() {
  18 + MailAccount mailAccount = new MailAccount()
  19 + .setFrom("奥特曼 <ydym_test@163.com>")
  20 + .setHost("smtp.163.com").setPort(465).setSslEnable(true)
  21 + .setAuth(true).setUser("ydym_test@163.com").setPass("WBZTEINMIFVRYSOE");
  22 + String messageId = MailUtil.send(mailAccount, "7685413@qq.com", "主题", "内容", false);
  23 + System.out.println("发送结果:" + messageId);
  24 + }
  25 +
  26 +}
... ...