Mr丶冷文

文章 分类 评论
125 10 8221

站点介绍

冷文学习者(KEVINLU98.COM),记录一个北漂小码农的日常业余生活
友链申请地址(直接评论即可): 传送门

(二十)评论回复功能及邮件提醒

MR丶冷文 2022-10-14 1041 0条评论 个人博客项目视频教程 javaspringboot个人博客博客系统

首页 / 正文
Freewind主题v1.5版本已发布,下载请移步Freewind 1.5,同时还有主题伴生插件Freewind Markdown,下载请移步 Freewind Markdown,有问题请在留言板,交换友链请直接在友链留言,我创建了一个主题交流群,有兴趣可以加下: 点此加入
报毒我说明一下,是因为我把主题的版权信息做了加密,其中用了eval,杀毒软件认为eval函数是一个危险的操作,这点介意的话请勿下载,我也没有强迫任何人去下载,也没有向大家收取一分钱的主题费用,所以也犯不着因为这些事情来喷我,喜欢就用,不喜欢就不用,就这么简单

发布于2022-10-28

(二十)评论回复功能及邮件提醒

说明

上节课我们完成了最基本的评论功能及展示,这节课我们来说下评论回复功能、收到评论后的给站长及被评论者的邮件通知功能

回复功能

  • 给每个评论加上data-id的属性存储评论的id
<li class="lw-posr" th:each="comment:${commentPage.rows}">
  <div class="lw-comment-avatar lw-posa">
    <img th:src="${@defaultImage.avatar(comment.email)}" alt="">
  </div>
  <div class="lw-comment-content">
    <p>
      <b th:text="${comment.nickname}"></b>
      <span th:text="${#dates.format(comment.created,'yyyy-MM-dd HH:mm')}"></span>
      <a th:data-id="${comment.id}" href="javascript:void(0)"
         class="lw-comment-replay">回复</a>
      <a href="javascript:void(0)" class="lw-comment-cancel"
         style="display: none">取消回复</a>
    </p>
    <p class="lw-comment-info" th:text="${comment.content}"></p>
  </div>
  <ul>
    <li class="lw-posr">
      <div class="lw-comment-avatar lw-posa">
        <img src="https://q1.qlogo.cn/g?b=qq&nk=1518228633&s=100" alt="">
      </div>
      <div class="lw-comment-content">
        <p><b>VOODOO</b> <span>2022-09-28 19:53</span> <a href="">回复</a></p>
        <p class="lw-comment-info">
          @xpboy
          <br>
          谢谢</p>
      </div>
    </li>
  </ul>
</li>
  • 当我们点击回复按钮时将评论框移到目标评论的下方,然后清空评论框的内容并将评论框的pid改为目标评论的id
$('#lw-comment-list').on('click', '.lw-comment-replay', function () {
  $('#lw-comment-list .lw-comment-cancel').hide()
  $('#lw-comment-list .lw-comment-replay').show()
  let id = $(this).data('id');
  let source = $('#lw-comment-box')
  // 复制一个评论框
  let cloneBox = source.clone();
  //删除源评论框
  source.remove()
  //将复制的评论框加到目标评论的下方
  $(this).parent().parent().append(source)
  //更改pid
  $('#lw-comment-form input[name=pid]').val(id)
  $(this).hide()
  $(this).parent().find('.lw-comment-cancel').show()
})
  • 评论完成后将评论框移加原来的位置并将评论框的pid变为0且评论内容清空
function commBoxReset(){
  let source = $('#lw-comment-box')
  let cloneBox = source.clone();
  source.remove()
  $('#lw-article-box').after(source)
  $('#lw-comment-form input[name=pid]').val(0)
  $('#lw-comment-form textarea').val('')
  $('#lw-comment-list .lw-comment-cancel').hide()
  $('#lw-comment-list .lw-comment-replay').show()
}
$('#lw-comment-list').on('click', '.lw-comment-cancel', function () {
    commBoxReset()
})
  • 后端处理评论层级关系
//Mapper
Page<Comment> findAllByArticleAndPidOrderByCreatedDesc(Article article, Integer pid, Pageable pageable);

List<Comment> findAllByPidOrderByCreatedDesc(Integer pid);
//Service
public void save(Comment comment) {
  //新评论
  if (Objects.isNull(comment.getId())) {
    comment.setCreated(new Date());
    comment.setView(false);
    if (comment.getPid() != 0) {
      Comment parent = detail(comment.getPid());
      comment.setContent("@"+parent.getNickname()+": "+comment.getContent());
      comment.setPid(findParent(comment.getPid()));
    }
  }
  mapper.save(comment);
}
private Integer findParent(Integer id) {
  Comment comment = detail(id);
  if (comment.getPid() == 0) {
    return comment.getId();
  }
  return findParent(comment.getPid());
}
  • 修改分页查询评论Service层的代码为其加上子评论列表
PageHelper.<Comment>builder()
  .rows(page.getContent().stream().peek(x -> x.setChildren(mapper.findAllByPidOrderByCreatedDesc(x.getId()))).collect(Collectors.toList()))
  .current(pageNum)
  .total(page.getTotalElements())
  .totalPage(page.getTotalPages())
  .build();
  • 页面子评论处理
<ul>
  <li class="lw-posr" th:each="comment:${commentPage.rows}">
    <div class="lw-comment-avatar lw-posa">
      <img th:src="${@defaultImage.avatar(comment.email)}" alt="">
    </div>
    <div class="lw-comment-content">
      <p>
        <b th:text="${comment.nickname}"></b>
        <span th:text="${#dates.format(comment.created,'yyyy-MM-dd HH:mm')}"></span>
        <a th:data-id="${comment.id}" href="javascript:void(0)"
           class="lw-comment-replay">回复</a>
        <a href="javascript:void(0)" class="lw-comment-cancel"
           style="display: none">取消回复</a>
      </p>
      <p class="lw-comment-info" th:text="${comment.content}"></p>
    </div>
    <ul th:if="${comment.children.size() > 0}">
      <li class="lw-posr" th:each="child:${comment.children}">
        <div class="lw-comment-avatar lw-posa">
          <img th:src="${@defaultImage.avatar(child.email)}" alt="">
        </div>
        <div class="lw-comment-content">
          <p>
            <b th:text="${child.nickname}"></b>
            <span th:text="${#dates.format(child.created,'yyyy-MM-dd HH:mm')}"></span>
            <a th:data-id="${child.id}" href="javascript:void(0)"
               class="lw-comment-replay">回复</a>
            <a href="javascript:void(0)" class="lw-comment-cancel"
               style="display: none">取消回复</a>
          </p>
          <p class="lw-comment-info" th:text="${child.content}"></p>
        </div>
      </li>
    </ul>
  </li>
</ul>

邮件提醒

准备工作

我这里以QQ邮箱为例,其它邮箱同理

  • 我们先准备一个QQ邮箱且开通时长大于15天
  • 开启POP3/IMAP/SMTP/服务并生成授权码

常见SMTP服务器地址

邮箱类型SMTP服务器地址端口号
QQ邮箱smtp.qq.com465或587
sina邮箱smtp.sina.cn465或587
126邮箱smtp.126.com465或994
aliyun邮箱smtp.aliyun.com465或994
163邮箱smtp.163.com465或994
yeah邮箱smtp.yeah.net465或994

SpringBootMail邮件测试

  • 导入依赖
<!-- springboot 邮件mail -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-mail</artifactId>
</dependency>
  • 配置发件人
spring:
  mail:
    #  默认的邮件编码为UTF-8
    default-encoding: UTF-8
    # 邮箱服务器
    host: smtp.qq.com
    # 邮箱
    username: xxx@qq.com
    # 密码
    password: xxxxx
    # 端口
    port: 587
    # 其它属性,这里只开启debug输出错误信息
    properties:
      debug: true
  • 创建一个邮件工具类
package cn.kevinlu98.common;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.util.Date;

/**
 * Author: Mr丶冷文
 * Date: 2022/10/14 19:44
 * Email: kevinlu98@qq.com
 * Description:
 */
@Slf4j
@Component
public class MailHelper {

  @Value("${spring.mail.username}")
  private String from;
  private final JavaMailSender javaMailSender;

  public MailHelper(JavaMailSender javaMailSender) {
    this.javaMailSender = javaMailSender;
  }

  /**
     * 发送邮件
     *
     * @param send    收件人
     * @param subject 主题
     * @param text    内容
     */
  public void sendMail(String send, String subject, String text) {
    MimeMessage message = javaMailSender.createMimeMessage();
    MimeMessageHelper helper = new MimeMessageHelper(message);
    try {
      helper.setSentDate(new Date()); //设置发件时间
      helper.setFrom(from); //发件人
      helper.setTo(send); //设置收件人
      helper.setSubject(subject); //设置标签
      helper.setText(text, true); //设置内容
      javaMailSender.send(message); //发邮件
    } catch (MessagingException e) {
      log.error(e.getMessage(), e);
    }
  }
}
  • 测试是否发送成功
package cn.kevinlu98.test;

import cn.kevinlu98.Application;
import cn.kevinlu98.common.MailHelper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

/**
 * Author: Mr丶冷文
 * Date: 2022/10/14 19:49
 * Email: kevinlu98@qq.com
 * Description:
 */
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {Application.class}, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class MailTest {
  @Autowired
  private MailHelper helper;

  @Test
  public void testSend(){
    helper.sendMail("xxx@qq.com","测试邮件","<h1>冷文学习者</h1><p>我是一个测试邮件</p>");
  }
}

评论邮件提醒

  • 在保存新评论时先给站长收一封邮件通知
@Async
public void sendMailToWebsite(Integer id) {
  Article article = articleMapper.findById(id).orElse(null);
  if (Objects.isNull(article)) return;
  String content = "<p>\n" + "    你的文章 <a href=\"" + webSite.getUrl() + "/" + id + ".html\">" + article.getTitle() + "</a>收到了新评论,点些查看\n" + "</p>\n" + "<p style=\"text-align:right ;\">\n" + "时间:\n" + new Date() + "</p>";
  helper.sendMail(webSite.getMail(), webSite.getTitle() + "收到新评论", content);
}
  • 如果父评论不为空,则给被回复者也发一封邮件
@Async
public void sendMailToComment(Integer id, Integer cid, String replay) {
  Article article = articleMapper.findById(id).orElse(null);
  if (Objects.isNull(article)) return;
  Comment comment = mapper.findById(cid).orElse(null);
  if (Objects.isNull(comment)) return;
  String content = "<p>\n" +
    "    你在<a href=\"" + webSite.getUrl() + "\">" + webSite.getTitle() +
    "</a>对 <a href=\"" + webSite.getUrl() + "/" + article.getId() + ".html\">" + article.getTitle() +
    "</a>文章的评论收到了新回复,回复内容如下:\n" +
    "</p>\n" +
    "<p>\n" +
    replay +
    "</p>\n" +
    "<p style=\"text-align:right ;\">\n" +
    "   一一发件人:" + webSite.getTitle() +
    "</p>\n" +
    "<p style=\"text-align:right ;\">\n" +
    "时间:" + new Date() +
    "</p>\n" +
    "<p style=\"text-align:right ;\">\n" +
    "    此邮件是由" + webSite.getTitle() + "自动发送,请勿回复 \n" +
    " </p>";
  helper.sendMail(comment.getEmail(), webSite.getTitle() + "收到新回复", content);
}
//Service save
public void save(Comment comment) {
  //新评论
  if (Objects.isNull(comment.getId())) {
    sendMailToWebsite(comment.getArticle().getId());
    comment.setCreated(new Date());
    comment.setView(false);
    if (comment.getPid() != 0) {
      sendMailToComment(comment.getArticle().getId(), comment.getPid(), comment.getContent());
      Comment parent = detail(comment.getPid());
      comment.setContent("@" + parent.getNickname() + ": " + comment.getContent());
      comment.setPid(findParent(comment.getPid()));
    }
  }
  mapper.save(comment);
}

评论(0)

热门文章

最新评论

  • 小凯

     感谢

  • 星涵 ⁧~喵⁧‭

    来啦

  • 星涵 ⁧~喵⁧‭

    来啦

  • 星涵 ⁧~喵⁧‭

    来啦

  • 星涵 ⁧~喵⁧‭

    来啦

日历

2024年07月

 123456
78910111213
14151617181920
21222324252627
28293031   

文章目录

站点公告
Freewind主题v1.5版本已发布,下载请移步Freewind 1.5,同时还有主题伴生插件Freewind Markdown,下载请移步 Freewind Markdown,有问题请在留言板,交换友链请直接在友链留言,我创建了一个主题交流群,有兴趣可以加下: 点此加入
报毒我说明一下,是因为我把主题的版权信息做了加密,其中用了eval,杀毒软件认为eval函数是一个危险的操作,这点介意的话请勿下载,我也没有强迫任何人去下载,也没有向大家收取一分钱的主题费用,所以也犯不着因为这些事情来喷我,喜欢就用,不喜欢就不用,就这么简单
点击小铃铛关闭