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