From 80901c138aa7c550fda0f84f5ee4f3585ffdc68b Mon Sep 17 00:00:00 2001 From: ronger Date: Wed, 21 Apr 2021 13:48:53 +0800 Subject: [PATCH 1/3] :art: update README.md --- README.md | 2 +- src/main/resources/static/logo_size.jpg | Bin 0 -> 4376 bytes src/main/resources/static/logo_size_invert.jpg | Bin 0 -> 4531 bytes 3 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 src/main/resources/static/logo_size.jpg create mode 100644 src/main/resources/static/logo_size_invert.jpg diff --git a/README.md b/README.md index 5e88293..7942e77 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # forest - +![forest](src/main/resources/static/logo_size.jpg) 下一代的知识社区系统,为未来而建 ## 💡 简介 diff --git a/src/main/resources/static/logo_size.jpg b/src/main/resources/static/logo_size.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f06a1090fecea0be3b8ad45103c6fcd16a41fc25 GIT binary patch literal 4376 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 literal 0 HcmV?d00001 From 0ade2bdc535f0fe9c6b25623d513ab5a04501c97 Mon Sep 17 00:00:00 2001 From: ronger Date: Thu, 22 Apr 2021 22:34:38 +0800 Subject: [PATCH 2/3] =?UTF-8?q?:poop:=20=E8=AF=84=E8=AE=BA=E6=B6=88?= =?UTF-8?q?=E6=81=AF-=E9=82=AE=E4=BB=B6=E9=80=9A=E7=9F=A5=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../rymcu/forest/service/JavaMailService.java | 12 ++ .../service/impl/JavaMailServiceImpl.java | 121 ++++++++----- .../service/impl/NotificationServiceImpl.java | 100 +---------- .../rymcu/forest/util/NotificationUtils.java | 100 ++++++++++- .../templates/mail/commentNotification.html | 162 ++++++++++++++++++ 5 files changed, 345 insertions(+), 150 deletions(-) create mode 100644 src/main/resources/templates/mail/commentNotification.html diff --git a/src/main/java/com/rymcu/forest/service/JavaMailService.java b/src/main/java/com/rymcu/forest/service/JavaMailService.java index 269cd20..761d3c6 100644 --- a/src/main/java/com/rymcu/forest/service/JavaMailService.java +++ b/src/main/java/com/rymcu/forest/service/JavaMailService.java @@ -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; } diff --git a/src/main/java/com/rymcu/forest/service/impl/JavaMailServiceImpl.java b/src/main/java/com/rymcu/forest/service/impl/JavaMailServiceImpl.java index 0b40654..fe4f4cc 100644 --- a/src/main/java/com/rymcu/forest/service/impl/JavaMailServiceImpl.java +++ b/src/main/java/com/rymcu/forest/service/impl/JavaMailServiceImpl.java @@ -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 thymeleafTemplateVariable = new HashMap(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 thymeleafTemplateVariable = new HashMap(); - thymeleafTemplateVariable.put("url", url); + String thymeleafTemplatePath = "mail/forgetPasswordTemplate"; + Map thymeleafTemplateVariable = new HashMap(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 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 - * 邮件内容 如:测试邮件逗你玩的。 - * @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 邮件内容 如:测试邮件逗你玩的。 + * @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()); } diff --git a/src/main/java/com/rymcu/forest/service/impl/NotificationServiceImpl.java b/src/main/java/com/rymcu/forest/service/impl/NotificationServiceImpl.java index 4883182..22b22d1 100644 --- a/src/main/java/com/rymcu/forest/service/impl/NotificationServiceImpl.java +++ b/src/main/java/com/rymcu/forest/service/impl/NotificationServiceImpl.java @@ -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 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 imple public List findNotifications(Integer idUser) { List 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 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); diff --git a/src/main/java/com/rymcu/forest/util/NotificationUtils.java b/src/main/java/com/rymcu/forest/util/NotificationUtils.java index b301bdd..c6b0500 100644 --- a/src/main/java/com/rymcu/forest/util/NotificationUtils.java +++ b/src/main/java/com/rymcu/forest/util/NotificationUtils.java @@ -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()); @@ -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; + } } diff --git a/src/main/resources/templates/mail/commentNotification.html b/src/main/resources/templates/mail/commentNotification.html new file mode 100644 index 0000000..920498e --- /dev/null +++ b/src/main/resources/templates/mail/commentNotification.html @@ -0,0 +1,162 @@ + + + + RYMCU 消息通知 + + + + + + + + + + + + + + + + + + +

+
+
+ + + + + + + + + +
+ Logo +
+ welcome image + +
+
+
+ + + + + + + + + +
+
+

+ 消息通知

+
+
+
+
+ 评论了您的文章《 》: +
+
+
+
+
+
+
+ + + + +
+ +
+
+
+
+
+ + \ No newline at end of file From 534ad89633a913fe4469f9162c674503ef659ac3 Mon Sep 17 00:00:00 2001 From: ronger Date: Fri, 23 Apr 2021 09:35:09 +0800 Subject: [PATCH 3/3] :arrow_up: shiro 1.4.1 -> 1.7.1 --- pom.xml | 6 +++--- src/main/java/com/rymcu/forest/answer/AnswerController.java | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 8edbd3b..c418103 100644 --- a/pom.xml +++ b/pom.xml @@ -88,19 +88,19 @@ com.github.pagehelper pagehelper - 5.1.10 + 5.2.0 com.alibaba fastjson - 1.2.67 + 1.2.76 org.apache.shiro shiro-spring - 1.4.1 + 1.7.1 diff --git a/src/main/java/com/rymcu/forest/answer/AnswerController.java b/src/main/java/com/rymcu/forest/answer/AnswerController.java index 605e189..92df131 100644 --- a/src/main/java/com/rymcu/forest/answer/AnswerController.java +++ b/src/main/java/com/rymcu/forest/answer/AnswerController.java @@ -2,7 +2,6 @@ package com.rymcu.forest.answer; import com.alibaba.fastjson.JSONObject; import com.rymcu.forest.core.result.GlobalResult; -import com.rymcu.forest.core.result.GlobalResultGenerator; import com.rymcu.forest.core.service.log.annotation.TransactionLogger; import com.rymcu.forest.dto.AnswerDTO; import com.rymcu.forest.entity.User;