Merge remote-tracking branch 'origin/wx-dev' into wx-dev
This commit is contained in:
commit
0417d7e98f
@ -1,5 +1,7 @@
|
||||
package com.rymcu.forest.service;
|
||||
|
||||
import com.rymcu.forest.dto.NotificationDTO;
|
||||
|
||||
import javax.mail.MessagingException;
|
||||
|
||||
/**
|
||||
@ -12,6 +14,7 @@ public interface JavaMailService {
|
||||
* 发送验证码邮件
|
||||
* @param email 收件人邮箱
|
||||
* @return 执行结果 0:失败1:成功
|
||||
* @throws MessagingException
|
||||
* */
|
||||
Integer sendEmailCode(String email) throws MessagingException;
|
||||
|
||||
@ -19,6 +22,15 @@ public interface JavaMailService {
|
||||
* 发送找回密码邮件
|
||||
* @param email 收件人邮箱
|
||||
* @return 执行结果 0:失败1:成功
|
||||
* @throws MessagingException
|
||||
* */
|
||||
Integer sendForgetPasswordEmail(String email) throws MessagingException;
|
||||
|
||||
/**
|
||||
* 发送下消息通知
|
||||
* @param notification
|
||||
* @return
|
||||
* @throws MessagingException
|
||||
*/
|
||||
Integer sendNotification(NotificationDTO notification) throws MessagingException;
|
||||
}
|
||||
|
@ -1,7 +1,11 @@
|
||||
package com.rymcu.forest.service.impl;
|
||||
|
||||
import com.rymcu.forest.core.constant.NotificationConstant;
|
||||
import com.rymcu.forest.core.service.redis.RedisService;
|
||||
import com.rymcu.forest.dto.NotificationDTO;
|
||||
import com.rymcu.forest.entity.User;
|
||||
import com.rymcu.forest.service.JavaMailService;
|
||||
import com.rymcu.forest.service.UserService;
|
||||
import com.rymcu.forest.util.Utils;
|
||||
import org.apache.commons.lang.time.StopWatch;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
@ -34,6 +38,8 @@ public class JavaMailServiceImpl implements JavaMailService {
|
||||
private JavaMailSenderImpl mailSender;
|
||||
@Resource
|
||||
private RedisService redisService;
|
||||
@Resource
|
||||
private UserService userService;
|
||||
/**
|
||||
* thymeleaf模板引擎
|
||||
*/
|
||||
@ -53,12 +59,49 @@ public class JavaMailServiceImpl implements JavaMailService {
|
||||
|
||||
@Override
|
||||
public Integer sendEmailCode(String email) throws MessagingException {
|
||||
return sendCode(email,0);
|
||||
return sendCode(email, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer sendForgetPasswordEmail(String email) throws MessagingException {
|
||||
return sendCode(email,1);
|
||||
return sendCode(email, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer sendNotification(NotificationDTO notification) throws MessagingException {
|
||||
Properties props = new Properties();
|
||||
// 表示SMTP发送邮件,需要进行身份验证
|
||||
props.put("mail.smtp.auth", true);
|
||||
props.put("mail.smtp.ssl.enable", true);
|
||||
props.put("mail.smtp.host", SERVER_HOST);
|
||||
props.put("mail.smtp.port", SERVER_PORT);
|
||||
// 如果使用ssl,则去掉使用25端口的配置,进行如下配置,
|
||||
props.put("mail.smtp.socketFactory.class", "com.rymcu.forest.util.MailSSLSocketFactory");
|
||||
props.put("mail.smtp.socketFactory.port", SERVER_PORT);
|
||||
// 发件人的账号,填写控制台配置的发信地址,比如xxx@xxx.com
|
||||
props.put("mail.user", USERNAME);
|
||||
// 访问SMTP服务时需要提供的密码(在控制台选择发信地址进行设置)
|
||||
props.put("mail.password", PASSWORD);
|
||||
mailSender.setJavaMailProperties(props);
|
||||
User user = userService.findById(String.valueOf(notification.getIdUser()));
|
||||
if (NotificationConstant.Comment.equals(notification.getDataType())) {
|
||||
String url = notification.getDataUrl();
|
||||
String thymeleafTemplatePath = "mail/commentNotification";
|
||||
Map<String, Object> thymeleafTemplateVariable = new HashMap<String, Object>(4);
|
||||
thymeleafTemplateVariable.put("user", notification.getAuthor().getUserNickname());
|
||||
thymeleafTemplateVariable.put("articleTitle", notification.getDataTitle());
|
||||
thymeleafTemplateVariable.put("content", notification.getDataSummary());
|
||||
thymeleafTemplateVariable.put("url", url);
|
||||
|
||||
sendTemplateEmail(USERNAME,
|
||||
new String[]{user.getEmail()},
|
||||
new String[]{},
|
||||
"【RYMCU】 消息通知",
|
||||
thymeleafTemplatePath,
|
||||
thymeleafTemplateVariable);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private Integer sendCode(String to, Integer type) throws MessagingException {
|
||||
@ -79,29 +122,29 @@ public class JavaMailServiceImpl implements JavaMailService {
|
||||
SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
|
||||
simpleMailMessage.setFrom(USERNAME);
|
||||
simpleMailMessage.setTo(to);
|
||||
if(type == 0) {
|
||||
if (type == 0) {
|
||||
Integer code = Utils.genCode();
|
||||
redisService.set(to,code,5*60);
|
||||
redisService.set(to, code, 5 * 60);
|
||||
simpleMailMessage.setSubject("新用户注册邮箱验证");
|
||||
simpleMailMessage.setText("【RYMCU】您的校验码是 " + code + ",有效时间 5 分钟,请不要泄露验证码给其他人。如非本人操作,请忽略!");
|
||||
mailSender.send(simpleMailMessage);
|
||||
return 1;
|
||||
} else if(type == 1){
|
||||
} else if (type == 1) {
|
||||
String code = Utils.entryptPassword(to);
|
||||
String url = BASE_URL + "/forget-password?code=" + code;
|
||||
redisService.set(code,to,15*60);
|
||||
redisService.set(code, to, 15 * 60);
|
||||
|
||||
String thymeleafTemplatePath = "mail/forgetPasswordTemplate";
|
||||
Map<String, Object> thymeleafTemplateVariable = new HashMap<String, Object>();
|
||||
thymeleafTemplateVariable.put("url", url);
|
||||
String thymeleafTemplatePath = "mail/forgetPasswordTemplate";
|
||||
Map<String, Object> thymeleafTemplateVariable = new HashMap<String, Object>(1);
|
||||
thymeleafTemplateVariable.put("url", url);
|
||||
|
||||
sendTemplateEmail(USERNAME,
|
||||
new String[] { to },
|
||||
new String[] {},
|
||||
"【RYMCU】 找回密码",
|
||||
thymeleafTemplatePath,
|
||||
thymeleafTemplateVariable);
|
||||
return 1;
|
||||
sendTemplateEmail(USERNAME,
|
||||
new String[]{to},
|
||||
new String[]{},
|
||||
"【RYMCU】 找回密码",
|
||||
thymeleafTemplatePath,
|
||||
thymeleafTemplateVariable);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -109,25 +152,19 @@ public class JavaMailServiceImpl implements JavaMailService {
|
||||
/**
|
||||
* 发送thymeleaf模板邮件
|
||||
*
|
||||
* @param deliver
|
||||
* 发送人邮箱名 如: javalsj@163.com
|
||||
* @param receivers
|
||||
* 收件人,可多个收件人 如:11111@qq.com,2222@163.com
|
||||
* @param carbonCopys
|
||||
* 抄送人,可多个抄送人 如:33333@sohu.com
|
||||
* @param subject
|
||||
* 邮件主题 如:您收到一封高大上的邮件,请查收。
|
||||
* @param thymeleafTemplatePath
|
||||
* 邮件模板 如:mail\mailTemplate.html。
|
||||
* @param thymeleafTemplateVariable
|
||||
* 邮件模板变量集
|
||||
* @param deliver 发送人邮箱名 如: javalsj@163.com
|
||||
* @param receivers 收件人,可多个收件人 如:11111@qq.com,2222@163.com
|
||||
* @param carbonCopys 抄送人,可多个抄送人 如:33333@sohu.com
|
||||
* @param subject 邮件主题 如:您收到一封高大上的邮件,请查收。
|
||||
* @param thymeleafTemplatePath 邮件模板 如:mail\mailTemplate.html。
|
||||
* @param thymeleafTemplateVariable 邮件模板变量集
|
||||
*/
|
||||
public void sendTemplateEmail(String deliver, String[] receivers, String[] carbonCopys, String subject, String thymeleafTemplatePath,
|
||||
Map<String, Object> thymeleafTemplateVariable) throws MessagingException {
|
||||
String text = null;
|
||||
if (thymeleafTemplateVariable != null && thymeleafTemplateVariable.size() > 0) {
|
||||
Context context = new Context();
|
||||
thymeleafTemplateVariable.forEach((key, value)->context.setVariable(key, value));
|
||||
thymeleafTemplateVariable.forEach((key, value) -> context.setVariable(key, value));
|
||||
text = templateEngine.process(thymeleafTemplatePath, context);
|
||||
}
|
||||
sendMimeMail(deliver, receivers, carbonCopys, subject, text, true, null);
|
||||
@ -136,22 +173,15 @@ public class JavaMailServiceImpl implements JavaMailService {
|
||||
/**
|
||||
* 发送的邮件(支持带附件/html类型的邮件)
|
||||
*
|
||||
* @param deliver
|
||||
* 发送人邮箱名 如: javalsj@163.com
|
||||
* @param receivers
|
||||
* 收件人,可多个收件人 如:11111@qq.com,2222@163.com
|
||||
* @param carbonCopys
|
||||
* 抄送人,可多个抄送人 如:3333@sohu.com
|
||||
* @param subject
|
||||
* 邮件主题 如:您收到一封高大上的邮件,请查收。
|
||||
* @param text
|
||||
* 邮件内容 如:测试邮件逗你玩的。 <html><body><img
|
||||
* src=\"cid:attchmentFileName\"></body></html>
|
||||
* @param attachmentFilePaths
|
||||
* 附件文件路径 如:
|
||||
* 需要注意的是addInline函数中资源名称attchmentFileName需要与正文中cid:attchmentFileName对应起来
|
||||
* @throws Exception
|
||||
* 邮件发送过程中的异常信息
|
||||
* @param deliver 发送人邮箱名 如: javalsj@163.com
|
||||
* @param receivers 收件人,可多个收件人 如:11111@qq.com,2222@163.com
|
||||
* @param carbonCopys 抄送人,可多个抄送人 如:3333@sohu.com
|
||||
* @param subject 邮件主题 如:您收到一封高大上的邮件,请查收。
|
||||
* @param text 邮件内容 如:测试邮件逗你玩的。 <html><body><img
|
||||
* src=\"cid:attchmentFileName\"></body></html>
|
||||
* @param attachmentFilePaths 附件文件路径 如:
|
||||
* 需要注意的是addInline函数中资源名称attchmentFileName需要与正文中cid:attchmentFileName对应起来
|
||||
* @throws Exception 邮件发送过程中的异常信息
|
||||
*/
|
||||
private void sendMimeMail(String deliver, String[] receivers, String[] carbonCopys, String subject, String text,
|
||||
boolean isHtml, String[] attachmentFilePaths) throws MessagingException {
|
||||
@ -186,7 +216,6 @@ public class JavaMailServiceImpl implements JavaMailService {
|
||||
}
|
||||
mailSender.send(mimeMessage);
|
||||
stopWatch.stop();
|
||||
//logger.info("邮件发送成功, 花费时间{}秒", stopWatch.getStartTime());
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,22 +1,16 @@
|
||||
package com.rymcu.forest.service.impl;
|
||||
|
||||
import com.rymcu.forest.core.service.AbstractService;
|
||||
import com.rymcu.forest.dto.ArticleDTO;
|
||||
import com.rymcu.forest.dto.Author;
|
||||
import com.rymcu.forest.dto.NotificationDTO;
|
||||
import com.rymcu.forest.entity.Comment;
|
||||
import com.rymcu.forest.entity.Follow;
|
||||
import com.rymcu.forest.entity.Notification;
|
||||
import com.rymcu.forest.entity.User;
|
||||
import com.rymcu.forest.mapper.NotificationMapper;
|
||||
import com.rymcu.forest.service.*;
|
||||
import com.rymcu.forest.service.NotificationService;
|
||||
import com.rymcu.forest.util.BeanCopierUtil;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import com.rymcu.forest.util.NotificationUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@ -28,16 +22,6 @@ public class NotificationServiceImpl extends AbstractService<Notification> imple
|
||||
|
||||
@Resource
|
||||
private NotificationMapper notificationMapper;
|
||||
@Resource
|
||||
private ArticleService articleService;
|
||||
@Resource
|
||||
private CommentService commentService;
|
||||
@Resource
|
||||
private UserService userService;
|
||||
@Resource
|
||||
private FollowService followService;
|
||||
@Value("${resource.domain}")
|
||||
private String domain;
|
||||
|
||||
private final static String unRead = "0";
|
||||
|
||||
@ -51,7 +35,7 @@ public class NotificationServiceImpl extends AbstractService<Notification> imple
|
||||
public List<NotificationDTO> findNotifications(Integer idUser) {
|
||||
List<NotificationDTO> list = notificationMapper.selectNotifications(idUser);
|
||||
list.forEach(notification -> {
|
||||
NotificationDTO notificationDTO = genNotification(notification);
|
||||
NotificationDTO notificationDTO = NotificationUtils.genNotification(notification);
|
||||
// 判断关联数据是否已删除
|
||||
if (Objects.nonNull(notificationDTO.getAuthor())) {
|
||||
BeanCopierUtil.copy(notificationDTO, notification);
|
||||
@ -71,84 +55,6 @@ public class NotificationServiceImpl extends AbstractService<Notification> imple
|
||||
return list;
|
||||
}
|
||||
|
||||
private NotificationDTO genNotification(Notification notification) {
|
||||
NotificationDTO notificationDTO = new NotificationDTO();
|
||||
BeanCopierUtil.copy(notification, notificationDTO);
|
||||
ArticleDTO article;
|
||||
Comment comment;
|
||||
User user;
|
||||
Follow follow;
|
||||
switch (notification.getDataType()) {
|
||||
case "0":
|
||||
// 系统公告/帖子
|
||||
article = articleService.findArticleDTOById(notification.getDataId(), 0);
|
||||
if (Objects.nonNull(article)) {
|
||||
notificationDTO.setDataTitle("系统公告");
|
||||
notificationDTO.setDataUrl(article.getArticlePermalink());
|
||||
user = userService.findById(article.getArticleAuthorId().toString());
|
||||
notificationDTO.setAuthor(genAuthor(user));
|
||||
}
|
||||
break;
|
||||
case "1":
|
||||
// 关注
|
||||
follow = followService.findById(notification.getDataId().toString());
|
||||
notificationDTO.setDataTitle("关注提醒");
|
||||
if (Objects.nonNull(follow)) {
|
||||
user = userService.findById(follow.getFollowerId().toString());
|
||||
notificationDTO.setDataUrl(getFollowLink(follow.getFollowingType(), user.getNickname()));
|
||||
notificationDTO.setAuthor(genAuthor(user));
|
||||
}
|
||||
break;
|
||||
case "2":
|
||||
// 回帖
|
||||
comment = commentService.findById(notification.getDataId().toString());
|
||||
article = articleService.findArticleDTOById(comment.getCommentArticleId(), 0);
|
||||
if (Objects.nonNull(article)) {
|
||||
notificationDTO.setDataTitle(article.getArticleTitle());
|
||||
notificationDTO.setDataUrl(comment.getCommentSharpUrl());
|
||||
user = userService.findById(comment.getCommentAuthorId().toString());
|
||||
notificationDTO.setAuthor(genAuthor(user));
|
||||
}
|
||||
break;
|
||||
case "3":
|
||||
// 关注用户发布文章
|
||||
case "4":
|
||||
// 关注文章更新
|
||||
article = articleService.findArticleDTOById(notification.getDataId(), 0);
|
||||
if (Objects.nonNull(article)) {
|
||||
notificationDTO.setDataTitle("关注通知");
|
||||
notificationDTO.setDataUrl(article.getArticlePermalink());
|
||||
user = userService.findById(article.getArticleAuthorId().toString());
|
||||
notificationDTO.setAuthor(genAuthor(user));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return notificationDTO;
|
||||
}
|
||||
|
||||
private String getFollowLink(String followingType, String id) {
|
||||
StringBuilder url = new StringBuilder();
|
||||
url.append(domain);
|
||||
switch (followingType) {
|
||||
case "0":
|
||||
url = url.append("/user/").append(id);
|
||||
break;
|
||||
default:
|
||||
url.append("/notification");
|
||||
}
|
||||
return url.toString();
|
||||
}
|
||||
|
||||
private Author genAuthor(User user) {
|
||||
Author author = new Author();
|
||||
author.setUserNickname(user.getNickname());
|
||||
author.setUserAvatarURL(user.getAvatarUrl());
|
||||
author.setIdUser(user.getIdUser());
|
||||
return author;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Notification findNotification(Integer idUser, Integer dataId, String dataType) {
|
||||
return notificationMapper.selectNotification(idUser, dataId, dataType);
|
||||
|
@ -1,15 +1,17 @@
|
||||
package com.rymcu.forest.util;
|
||||
|
||||
import com.rymcu.forest.core.constant.NotificationConstant;
|
||||
import com.rymcu.forest.dto.ArticleDTO;
|
||||
import com.rymcu.forest.dto.Author;
|
||||
import com.rymcu.forest.dto.NotificationDTO;
|
||||
import com.rymcu.forest.entity.Comment;
|
||||
import com.rymcu.forest.entity.Follow;
|
||||
import com.rymcu.forest.entity.Notification;
|
||||
import com.rymcu.forest.entity.User;
|
||||
import com.rymcu.forest.service.FollowService;
|
||||
import com.rymcu.forest.service.NotificationService;
|
||||
import com.rymcu.forest.service.UserService;
|
||||
import com.rymcu.forest.service.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.*;
|
||||
|
||||
/**
|
||||
@ -19,12 +21,13 @@ import java.util.concurrent.*;
|
||||
*/
|
||||
public class NotificationUtils {
|
||||
|
||||
@Resource
|
||||
private static NotificationService notificationService = SpringContextHolder.getBean(NotificationService.class);
|
||||
@Resource
|
||||
private static UserService userService = SpringContextHolder.getBean(UserService.class);
|
||||
@Resource
|
||||
private static FollowService followService = SpringContextHolder.getBean(FollowService.class);
|
||||
private static JavaMailService mailService = SpringContextHolder.getBean(JavaMailService.class);
|
||||
|
||||
private static ArticleService articleService = SpringContextHolder.getBean(ArticleService.class);
|
||||
private static CommentService commentService = SpringContextHolder.getBean(CommentService.class);
|
||||
|
||||
public static void sendAnnouncement(Integer dataId, String dataType, String dataSummary) {
|
||||
ExecutorService executor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
|
||||
@ -53,6 +56,11 @@ public class NotificationUtils {
|
||||
// TODO 记录操作失败数据
|
||||
}
|
||||
}
|
||||
if (NotificationConstant.Comment.equals(dataType)) {
|
||||
notification = notificationService.findNotification(idUser, dataId, dataType);
|
||||
NotificationDTO notificationDTO = genNotification(notification);
|
||||
mailService.sendNotification(notificationDTO);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
// TODO 记录操作失败数据
|
||||
ex.printStackTrace();
|
||||
@ -83,4 +91,82 @@ public class NotificationUtils {
|
||||
return 0;
|
||||
}, executor);
|
||||
}
|
||||
|
||||
public static NotificationDTO genNotification(Notification notification) {
|
||||
NotificationDTO notificationDTO = new NotificationDTO();
|
||||
BeanCopierUtil.copy(notification, notificationDTO);
|
||||
ArticleDTO article;
|
||||
Comment comment;
|
||||
User user;
|
||||
Follow follow;
|
||||
switch (notification.getDataType()) {
|
||||
case "0":
|
||||
// 系统公告/帖子
|
||||
article = articleService.findArticleDTOById(notification.getDataId(), 0);
|
||||
if (Objects.nonNull(article)) {
|
||||
notificationDTO.setDataTitle("系统公告");
|
||||
notificationDTO.setDataUrl(article.getArticlePermalink());
|
||||
user = userService.findById(article.getArticleAuthorId().toString());
|
||||
notificationDTO.setAuthor(genAuthor(user));
|
||||
}
|
||||
break;
|
||||
case "1":
|
||||
// 关注
|
||||
follow = followService.findById(notification.getDataId().toString());
|
||||
notificationDTO.setDataTitle("关注提醒");
|
||||
if (Objects.nonNull(follow)) {
|
||||
user = userService.findById(follow.getFollowerId().toString());
|
||||
notificationDTO.setDataUrl(getFollowLink(follow.getFollowingType(), user.getNickname()));
|
||||
notificationDTO.setAuthor(genAuthor(user));
|
||||
}
|
||||
break;
|
||||
case "2":
|
||||
// 回帖
|
||||
comment = commentService.findById(notification.getDataId().toString());
|
||||
article = articleService.findArticleDTOById(comment.getCommentArticleId(), 0);
|
||||
if (Objects.nonNull(article)) {
|
||||
notificationDTO.setDataTitle(article.getArticleTitle());
|
||||
notificationDTO.setDataUrl(comment.getCommentSharpUrl());
|
||||
user = userService.findById(comment.getCommentAuthorId().toString());
|
||||
notificationDTO.setAuthor(genAuthor(user));
|
||||
}
|
||||
break;
|
||||
case "3":
|
||||
// 关注用户发布文章
|
||||
case "4":
|
||||
// 关注文章更新
|
||||
article = articleService.findArticleDTOById(notification.getDataId(), 0);
|
||||
if (Objects.nonNull(article)) {
|
||||
notificationDTO.setDataTitle("关注通知");
|
||||
notificationDTO.setDataUrl(article.getArticlePermalink());
|
||||
user = userService.findById(article.getArticleAuthorId().toString());
|
||||
notificationDTO.setAuthor(genAuthor(user));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return notificationDTO;
|
||||
}
|
||||
|
||||
private static String getFollowLink(String followingType, String id) {
|
||||
StringBuilder url = new StringBuilder();
|
||||
url.append(Utils.getProperty("resource.domain"));
|
||||
switch (followingType) {
|
||||
case "0":
|
||||
url = url.append("/user/").append(id);
|
||||
break;
|
||||
default:
|
||||
url.append("/notification");
|
||||
}
|
||||
return url.toString();
|
||||
}
|
||||
|
||||
private static Author genAuthor(User user) {
|
||||
Author author = new Author();
|
||||
author.setUserNickname(user.getNickname());
|
||||
author.setUserAvatarURL(user.getAvatarUrl());
|
||||
author.setIdUser(user.getIdUser());
|
||||
return author;
|
||||
}
|
||||
}
|
||||
|
162
src/main/resources/templates/mail/commentNotification.html
Normal file
162
src/main/resources/templates/mail/commentNotification.html
Normal file
@ -0,0 +1,162 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<title> RYMCU 消息通知 </title>
|
||||
<!--[if !mso]> -->
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
|
||||
<!--<![endif]-->
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<style type="text/css">
|
||||
#outlook a {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
-ms-text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
table,
|
||||
td {
|
||||
border-collapse: collapse;
|
||||
mso-table-lspace: 0pt;
|
||||
mso-table-rspace: 0pt;
|
||||
}
|
||||
|
||||
img {
|
||||
border: 0;
|
||||
height: auto;
|
||||
line-height: 100%;
|
||||
outline: none;
|
||||
text-decoration: none;
|
||||
-ms-interpolation-mode: bicubic;
|
||||
}
|
||||
|
||||
p {
|
||||
display: block;
|
||||
margin: 13px 0;
|
||||
}
|
||||
</style>
|
||||
<!--[if mso]>
|
||||
<xml>
|
||||
<o:OfficeDocumentSettings>
|
||||
<o:AllowPNG/>
|
||||
<o:PixelsPerInch>96</o:PixelsPerInch>
|
||||
</o:OfficeDocumentSettings>
|
||||
</xml>
|
||||
<![endif]-->
|
||||
<!--[if lte mso 11]>
|
||||
<style type="text/css">
|
||||
.mj-outlook-group-fix {
|
||||
width: 100% !important;
|
||||
}
|
||||
</style>
|
||||
<![endif]-->
|
||||
<!--[if !mso]><!-->
|
||||
<link href="https://fonts.googleapis.com/css2?family=Quattrocento:wght@400;700&display=swap" rel="stylesheet"
|
||||
type="text/css"/>
|
||||
<style type="text/css">
|
||||
@import url(https://fonts.googleapis.com/css2?family=Quattrocento:wght@400;700&display=swap);
|
||||
</style>
|
||||
<!--<![endif]-->
|
||||
<style type="text/css">
|
||||
@media only screen and (min-width: 480px) {
|
||||
.mj-column-per-100 {
|
||||
width: 100% !important;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style type="text/css">
|
||||
@media only screen and (max-width: 480px) {
|
||||
table.mj-full-width-mobile {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
td.mj-full-width-mobile {
|
||||
width: auto !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style type="text/css">
|
||||
a,
|
||||
span,
|
||||
td,
|
||||
th {
|
||||
-webkit-font-smoothing: antialiased !important;
|
||||
-moz-osx-font-smoothing: grayscale !important;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body style="background-color:#f6ab0c;text-align: center;">
|
||||
<div style="background-color:#ffffff;margin:0px auto;border-radius:8px 8px 0 0;max-width:600px;">
|
||||
<div style="max-width:600px;">
|
||||
<div style="margin-top: 40px;">
|
||||
<table align="center">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td width="150" style="padding: 20px 0;">
|
||||
<img alt="Logo" height="auto"
|
||||
src="https://static.rymcu.com/article/1619013470064"
|
||||
style="border:0;display:block;outline:none;text-decoration:none;height:auto;width:100%;font-size:14px;"
|
||||
width="150">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="200">
|
||||
<img alt="welcome image" height="auto"
|
||||
src="https://static.rymcu.com/article/1619013419068"
|
||||
style="border:0;display:block;outline:none;text-decoration:none;height:auto;width:100%;font-size:14px;"
|
||||
width="200"/>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td align="left" style="font-size:0px;padding:10px 25px;word-break:break-word;">
|
||||
<div style="font-size:18px;font-weight:400;line-height:24px;text-align:left;color:#000000;">
|
||||
<h1 style="margin: 0; font-size: 32px; line-height: 40px; font-weight: 700;">
|
||||
消息通知</h1>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left" style="font-size:0px;padding:10px 25px;word-break:break-word;">
|
||||
<div style="font-size:18px;font-weight:400;line-height:24px;text-align:left;color:#000000;">
|
||||
<div style="margin: 0;">
|
||||
<span th:text="${user}"></span> 评论了您的文章《 <span th:text="${articleTitle}"></span>》:
|
||||
</div>
|
||||
<div th:text="*{content}"></div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div style="margin:0px auto;max-width:600px;">
|
||||
<div class="mj-column-per-100 mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;">
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%">
|
||||
<tbody><tr>
|
||||
<td align="center" style="font-size:0px;padding:10px 25px;word-break:break-word;">
|
||||
<div style="font-family:Quattrocento;font-size:16px;font-weight:400;line-height:24px;text-align:center;color:#333333;">
|
||||
<a th:href="${url}" style="color: #428dfc; text-decoration: none; font-weight: bold;"> 点击这里进行查看 </a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user