🎨 优化邮件发送

master
linhaojun 4 years ago
parent f1b30f14ba
commit 35aea6ac34

@ -44,6 +44,10 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>

@ -29,13 +29,11 @@ public class CommonConst {
/**
*
*/
// public static final String PRE_TAG = "<span style='color:#f47466'>";
public static final String PRE_TAG = "<mark>";
/**
*
*/
// public static final String POST_TAG = "</span>";
public static final String POST_TAG = "</mark>";
/**
@ -63,26 +61,11 @@ public class CommonConst {
*/
public static final String DEFAULT_NICKNAME = "用户";
/**
*
*/
public static String ARTICLE_SET = "articleSet";
/**
*
*/
public static String COMPONENT = "Layout";
/**
*
*/
public static final String PROVINCE = "省";
/**
*
*/
public static final String CITY = "市";
/**
*
*/
@ -109,4 +92,19 @@ public class CommonConst {
*/
public final static Integer TWENTY_MINUTES = 20;
/**
*
*/
public static final String CAPTCHA = "验证码";
/**
*
*/
public static final String CHECK_REMIND = "审核提醒";
/**
*
*/
public static final String COMMENT_REMIND = "评论提醒";
}

@ -2,15 +2,14 @@ package com.aurora.consumer;
import com.alibaba.fastjson.JSON;
import com.aurora.model.dto.EmailDTO;
import com.aurora.utils.EmailUtils;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Component;
import static com.aurora.constant.CommonConst.*;
import static com.aurora.constant.MQPrefixConst.EMAIL_QUEUE;
/**
@ -21,23 +20,17 @@ import static com.aurora.constant.MQPrefixConst.EMAIL_QUEUE;
@RabbitListener(queues = EMAIL_QUEUE)
public class CommentNoticeConsumer {
/**
*
*/
@Value("${spring.mail.username}")
private String email;
@Autowired
private JavaMailSender javaMailSender;
private EmailUtils emailUtils;
@RabbitHandler
public void process(byte[] data) {
EmailDTO emailDTO = JSON.parseObject(new String(data), EmailDTO.class);
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom(email);
message.setTo(emailDTO.getEmail());
message.setSubject(emailDTO.getSubject());
message.setText(emailDTO.getContent());
javaMailSender.send(message);
EmailDTO mailDTO = JSON.parseObject(new String(data), EmailDTO.class);
if (CAPTCHA.equals(mailDTO.getSubject()) || CHECK_REMIND.equals(mailDTO.getSubject())) {
emailUtils.sendSimpleMail(mailDTO);
}
if (COMMENT_REMIND.equals(mailDTO.getSubject())) {
emailUtils.sendHtmlMail(mailDTO);
}
}
}

@ -12,9 +12,9 @@ import lombok.Getter;
public enum CommentTypeEnum {
/**
*
*
*/
ARTICLE(1, "文章评论", "/articles/"),
ARTICLE(1, "文章", "/articles/"),
/**
*
@ -27,14 +27,14 @@ public enum CommentTypeEnum {
ABOUT(3, "关于我", "/about/"),
/**
*
*
*/
LINK(4, "友链评论", "/friends/"),
LINK(4, "友链", "/friends/"),
/**
*
*
*/
TALK(5, "说说评论", "/talks/");
TALK(5, "说说", "/talks/");
/**
*

@ -5,6 +5,8 @@ import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Map;
/**
* @author
*
@ -30,4 +32,14 @@ public class EmailDTO {
*/
private String content;
/**
*
*/
private Map<String, Object> commentMap;
/**
*
*/
private String template;
}

@ -34,6 +34,7 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
@ -92,8 +93,9 @@ public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment> impl
.isReview(isCommentReview == TRUE ? FALSE : TRUE)
.build();
commentMapper.insert(comment);
String fromNickname = UserUtils.getUserDetailsDTO().getNickname();
if (websiteConfig.getIsEmailNotice().equals(TRUE)) {
CompletableFuture.runAsync(() -> notice(comment));
CompletableFuture.runAsync(() -> notice(comment, fromNickname));
}
}
@ -215,10 +217,19 @@ public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment> impl
}
}
public void notice(Comment comment) {
private void notice(Comment comment, String fromNickname) {
// 评论自己不发邮件提醒
if (comment.getUserId().equals(comment.getReplyUserId())) {
return;
}
// 博主自己发评论不发邮件提醒
if (comment.getUserId().equals(BLOGGER_ID) && Objects.isNull(comment.getParentId())) {
return;
}
// 查询回复用户邮箱号
String title;
Integer userId = BLOGGER_ID;
String id = Objects.nonNull(comment.getTopicId()) ? comment.getTopicId().toString() : "";
String topicId = Objects.nonNull(comment.getTopicId()) ? comment.getTopicId().toString() : "";
if (Objects.nonNull(comment.getReplyUserId())) {
userId = comment.getReplyUserId();
} else {
@ -232,26 +243,54 @@ public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment> impl
break;
}
}
String email = userInfoMapper.selectById(userId).getEmail();
if (StringUtils.isNotBlank(email)) {
// 发送消息
EmailDTO emailDTO = new EmailDTO();
if (comment.getIsReview().equals(TRUE)) {
// 评论提醒
emailDTO.setEmail(email);
if (Objects.requireNonNull(getCommentEnum(comment.getType())).equals(ARTICLE)) {
title = articleMapper.selectById(comment.getTopicId()).getArticleTitle();
} else {
title = Objects.requireNonNull(getCommentEnum(comment.getType())).getDesc();
}
UserInfo user = userInfoMapper.selectById(userId);
if (StringUtils.isNotBlank(user.getEmail())) {
EmailDTO emailDTO = getEmailDTO(comment, user, fromNickname, topicId, title, userId);
rabbitTemplate.convertAndSend(EMAIL_EXCHANGE, "*", new Message(JSON.toJSONBytes(emailDTO), new MessageProperties()));
}
}
private EmailDTO getEmailDTO(Comment comment, UserInfo user, String fromNickname, String topicId, String title, Integer userId) {
EmailDTO emailDTO = new EmailDTO();
if (comment.getIsReview().equals(TRUE)) {
Map<String, Object> map = new HashMap<>();
String url = websiteUrl + getCommentPath(comment.getType()) + topicId;
if (Objects.isNull(comment.getParentId())) {
emailDTO.setEmail(user.getEmail());
emailDTO.setSubject("评论提醒");
// 获取评论路径
String url = websiteUrl + getCommentPath(comment.getType()) + id;
emailDTO.setContent("您收到了一条新的回复,请前往" + url + "页面查看");
emailDTO.setTemplate("owner.html");
String createTime = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm").format(comment.getCreateTime());
map.put("time", createTime);
map.put("url", url);
map.put("title", title);
map.put("nickname", fromNickname);
map.put("content", comment.getCommentContent());
} else {
// 管理员审核提醒
String adminEmail = userInfoMapper.selectById(BLOGGER_ID).getEmail();
emailDTO.setEmail(adminEmail);
emailDTO.setSubject("审核提醒");
emailDTO.setContent("您收到了一条新的回复,请前往后台管理页面审核");
Comment parentComment = commentMapper.selectOne(new LambdaQueryWrapper<Comment>().select(Comment::getCommentContent, Comment::getCreateTime).eq(Comment::getId, comment.getParentId()));
emailDTO.setEmail(user.getEmail());
emailDTO.setSubject("评论提醒");
emailDTO.setTemplate("user.html");
map.put("url", url);
map.put("title", title);
String createTime = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm").format(parentComment.getCreateTime());
map.put("time", createTime);
map.put("toUser", user.getNickname());
map.put("fromUser", fromNickname);
map.put("parentComment", parentComment.getCommentContent());
map.put("replyComment", comment.getCommentContent());
}
System.out.println(emailDTO);
rabbitTemplate.convertAndSend(EMAIL_EXCHANGE, "*", new Message(JSON.toJSONBytes(emailDTO), new MessageProperties()));
emailDTO.setCommentMap(map);
} else {
String adminEmail = userInfoMapper.selectById(BLOGGER_ID).getEmail();
emailDTO.setEmail(adminEmail);
emailDTO.setSubject("审核提醒");
emailDTO.setContent("您收到了一条新的回复,请前往后台管理页面审核");
}
return emailDTO;
}
}

@ -0,0 +1,61 @@
package com.aurora.utils;
import com.aurora.model.dto.EmailDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
/**
*
*
* @author ican
*/
@Component
public class EmailUtils {
/**
*
*/
@Value("${spring.mail.username}")
private String email;
@Autowired
private JavaMailSender javaMailSender;
@Autowired
private TemplateEngine templateEngine;
public void sendSimpleMail(EmailDTO emailDTO) {
SimpleMailMessage simpleMail = new SimpleMailMessage();
simpleMail.setFrom(email);
simpleMail.setTo(emailDTO.getEmail());
simpleMail.setSubject(emailDTO.getSubject());
simpleMail.setText(emailDTO.getContent());
javaMailSender.send(simpleMail);
}
public void sendHtmlMail(EmailDTO emailDTO) {
try {
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage);
Context context = new Context();
context.setVariables(emailDTO.getCommentMap());
String process = templateEngine.process(emailDTO.getTemplate(), context);
mimeMessageHelper.setFrom(email);
mimeMessageHelper.setTo(emailDTO.getEmail());
mimeMessageHelper.setSubject(emailDTO.getSubject());
mimeMessageHelper.setText(process, true);
javaMailSender.send(mimeMessage);
} catch (MessagingException e) {
e.printStackTrace();
}
}
}

@ -29,7 +29,7 @@ public class HTMLUtils {
*/
public static String filter(String source) {
// 敏感词过滤
source = sensitiveWordBs.replace(source);
// source = sensitiveWordBs.replace(source);
// 保留图片标签
source = source.replaceAll("(?!<(img).*?>)<.*?>", "")
.replaceAll("(onload(.*?)=)", "")

@ -0,0 +1,55 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div style="
border-radius: 10px 10px 10px 10px;
font-size: 13px;
color: #555555;
width: 666px;
margin: 50px auto;
border: 1px solid #eee;
max-width: 100%;
background: #ffffff repeating-linear-gradient(-45deg,#fff,#fff 1.125rem,transparent 1.125rem,transparent 2.25rem);
box-shadow: 0 1px 5px rgb(0 0 0 / 15%);">
<div style="
background:#49BDAD;
color:#ffffff;
border-radius: 10px 10px 0 0;
background-image: -moz-linear-gradient(0deg, rgb(67, 198, 184), rgb(255, 209, 244));
background-image: -webkit-linear-gradient(0deg, rgb(67, 198, 184), rgb(255, 209, 244));
height: 66px;">
<p style="font-size:15px;
word-break:break-all;
padding: 23px 32px;
margin:0;
background-color: hsla(0,0%,100%,.4);
border-radius: 10px 10px 0 0;">
您的<a style="text-decoration:none;
color: #ffffff;" th:text="|《${title}》|" target="_blank"></a>有的新评论啦!
</p>
</div>
<div style="margin:20px auto;width:90%">
<p>时间:<span th:text="${time}"></span></p>
<p><strong th:text="${nickname}"></strong> 同学 给您的评论如下:</p>
<div style="background: #f5f5f5;
margin:20px 0;
padding:15px;
border-radius:5px;
font-size:14px;">
<p th:utext="${content}"></p>
</div>
<p>
您可以点击<a style="text-decoration:none;
color:#12addb" th:href="@{${url}}" target="_blank">查看回复的完整內容</a>
</p>
<div style="color: #8c8c8c; font-size: 10px;width: 100%;text-align: center;word-wrap: break-word;">
<p style="padding: 20px">什么都无法舍弃的人,什么都改变不了。——《进击的巨人》</p>
</div>
</div>
</div>
</body>
</html>

@ -0,0 +1,66 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div style="
border-radius: 10px 10px 10px 10px;
font-size: 13px;
color: #555555;
width: 666px;
margin: 50px auto;
border: 1px solid #eee;
max-width: 100%;
background: #ffffff repeating-linear-gradient(-45deg,#fff,#fff 1.125rem,transparent 1.125rem,transparent 2.25rem);
box-shadow: 0 1px 5px rgb(0 0 0 / 15%);">
<div style="
background:#49BDAD;
color:#ffffff;
border-radius: 10px 10px 0 0;
background-image: -moz-linear-gradient(0deg, rgb(67, 198, 184), rgb(255, 209, 244));
background-image: -webkit-linear-gradient(0deg, rgb(67, 198, 184), rgb(255, 209, 244));
height: 66px;">
<p style="font-size:15px;
word-break:break-all;
padding: 23px 32px;
margin:0;
background-color: hsla(0,0%,100%,.4);
border-radius: 10px 10px 0 0;">
您在<a style="text-decoration:none;
color: #ffffff;" href="https://www.ttkwsd.top/" target="_blank">花未眠的个人博客</a>上的留言有新回复啦!
</p>
</div>
<div style="margin:20px auto;width:90%">
<p>时间:<span th:text="${time}"></span></p>
<p><strong th:text="${toUser}"></strong> 同学,您曾在<a th:text="|《${title}》|" style="text-decoration: none;
color:#12addb"></a>上发表评论:</p>
<div style="background: #f5f5f5;
margin:20px 0;
padding:15px;
border-radius:5px;
font-size:14px;">
<p th:utext="${parentComment}"></p>
</div>
<p><strong th:text="${fromUser}"></strong> 给您的回复如下:</p>
<div style="background: #f5f5f5;
margin:20px 0;
padding:15px;
border-radius:5px;
font-size:14px;">
<p th:utext="${replyComment}"></p>
</div>
<p>
您可以点击<a style="text-decoration:none;
color:#12addb" target="_blank" th:href="@{${url}}">查看回复的完整內容</a>
,欢迎再次光临<a style="text-decoration:none;
color:#12addb" href="https://www.linhaojun.top/" target="_blank">花未眠的个人博客</a>
</p>
<div style="color: #8c8c8c; font-size: 10px;width: 100%;text-align: center;word-wrap: break-word;">
<p style="padding: 20px">不管当下的境遇如何,提瓦特大陆的星空永远会有你的位置。——《原神》</p>
</div>
</div>
</div>
</body>
</html>
Loading…
Cancel
Save