博客的评论与回复功能的实现

您所在的位置:网站首页 qq自动回复的文案怎么弄 博客的评论与回复功能的实现

博客的评论与回复功能的实现

2024-07-11 18:10| 来源: 网络整理| 查看: 265

你好呀,我是小邹。

在之前的文章中,提到了个人博客的简单回复功能的实现,今天记录一下完整的评论功能的实现。

实现思路

数据库设计:评论表需要定义出当前博客id以便做关联,因为评论需要有回复功能,则需要定义当前评论有无上一级评论,需要定义出上级评论id。

代码方面:点击评论需要获取当前博客id与自己评论数据进行插入,点击回复按钮需要获取上一条评论的id以及用户姓名作为回复,回复成功后,后台在数据库中查找出所有parentCommentId为-1的值进行遍历,因为上级id为-1则证明当前评论无父节点。在通过对父节点id的遍历查询出所有对应评论的子节点。

页面效果

实现的关键在于:新提交的评论排在最上面,三级评论排在二级评论的下面。 在这里插入图片描述

代码实现 实体类 package com.zou.blog.model.domain; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.util.ArrayList; import java.util.Date; import java.util.List; /** * @author: 邹祥发 * @date: 2022/7/12 08:01 */ @Data @AllArgsConstructor @NoArgsConstructor @TableName("article_comments") public class Comments { @TableId private Integer id; private String nickname; private String email; private String content; private Date createTime; private Integer blogId; private Integer isVisible; private String avatar; private String blogUrl; private String province; private String ip; private Date updateTime; private Integer sort; //评论的父节点id private Integer parentId; private String parentName; //回复评论 @TableField(exist = false) private List replyComments = new ArrayList(); @TableField(exist = false) private Comments parentComment; } 评论表单页面 发布 点击发布

js有些多余的代码,会前端的可以自己删。

$('#QQ').blur(function () { var QQ = $("#QQ").val(); $.ajax({ url: "https://api.usuuu.com/qq/" + QQ, type: "GET", dataType: "json", success: function (result) { console.log(result["data"].name, result["data"].avatar); $("#nickname").val(result["data"].name); var obj = document.getElementById("avatar"); obj.src = result["data"].avatar; $("#avatar").val(result["data"].avatar); $("[name='email']").val(QQ + '@qq.com'); } }); }); $(function () { $('#comment-btn').click(function () { var blogid = $("input[name='blogid']").val().trim(); var blogUrl = $("input[name='blogUrl']").val().trim(); var content = $("textarea[name='content']").val().trim(); var nickname = $("input[name='nickname']").val().trim(); var email = $("input[name='email']").val().trim(); var avatar = $("#avatar").val(); var parentId = $("input[name='parentCommentId']").val(); if (reply1 != null) { var parentName = reply1; } else { parentName = nickname; } var data = { blogid: blogid, blogUrl: blogUrl, content: content, nickname: nickname, email: email, avatar: avatar, parentId: parentId, parentName: parentName }; if (content !== "" && content !== null && content !== undefined && nickname !== "" && nickname !== null && nickname !== undefined) { //验证邮箱格式 const emailReg = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/; if (!emailReg.test(email)) { alert('邮箱格式错误'); return; } $.ajax({ type: "POST", url: '/comments', data: data, dataType: 'json', contentType: 'application/x-www-form-urlencoded', success: function (req) { console.log(req) }, error: function (e) { console.log(e) } }) alert('您的评论已成功投递至召田最帅boy,请耐心等待他审核吧!'); $('#aaa').val(''); } else { alert("昵称和评论内容不能为空!") return; } }) }) 点击回复按钮,在评论区显示回复给哪个用户

在这里插入图片描述

回复 对应函数 //回复 var reply1; function reply(obj) { let commentId = $(obj).data('commentid'); let commentNickname = $(obj).data('commentnickname'); reply1 = commentNickname; //添加信息到评论表单 $("[name='content']").attr("placeholder", "@" + commentNickname).focus(); $("[name='parentCommentId']").val(commentId); //滚动到评论表单 $(window).scrollTo($('#comment-form'), 500); } 后端controller层代码 /** * 发表评论 */ @ResponseBody @PostMapping(value = {"comments"}) public void comments(HttpServletRequest request, @RequestBody @RequestParam("blogid") Integer blogId, @RequestBody @RequestParam("blogUrl") String blogUrl, @RequestBody @RequestParam("content") String content, @RequestBody @RequestParam("nickname") String nickname, @RequestBody @RequestParam("email") String email, @RequestBody @RequestParam("avatar") String avatar, @RequestBody @RequestParam("parentId") Integer parentId, @RequestBody @RequestParam("parentName") String parentName) throws Exception { String ip = IpUtils.getIpAddr(request); String province = IpUtils.getIpPossession(ip); Comments comments = new Comments(); comments.setId(Integer.parseInt(String.valueOf(System.currentTimeMillis() / 1000))); comments.setContent(content); comments.setEmail(email); comments.setCreateTime(new Date()); comments.setBlogId(blogId); comments.setBlogUrl(blogUrl); comments.setProvince(province); comments.setIp(ip); comments.setUpdateTime(new Date()); //数值越大则优先展示 if (parentId == -1) { comments.setSort(1); } else { comments.setSort(Integer.parseInt(String.valueOf(System.currentTimeMillis() / 990))); } //未审核的评论默认不可见 //暂时可见 comments.setIsVisible(CommentStatus.VISIBLE.getStatus()); //设置父节点id,-1为首节点 comments.setParentId(parentId); comments.setParentName(parentName); comments.setNickname(nickname); comments.setAvatar(avatar); commentService.save(comments); } //根据文章id查询评论列表 model.addAttribute("comments", commentService.listCommentByBlogId(article.getId())); 评论列表-展示层级关系 ; 回复 ; ; 回复 后端service层代码

先获取顶级的数据,在一层一层往下找、放入集合

@Override public List listCommentByBlogId(Integer blogId) { QueryWrapper wrapper = new QueryWrapper().eq("blog_id", blogId).eq("is_visible", CommentStatus.VISIBLE.getStatus()).orderByAsc("sort").orderByDesc("create_time"); wrapper.select("id", "nickname", "content", "create_time", "avatar", "parent_id", "province", "blog_id", "parent_name"); List comments = commentsMapper.selectList(wrapper); return firstComment(comments); } public List firstComment(List comments) { //存储父评论为根评论-1的评论 ArrayList list = new ArrayList(); for (Comments comment : comments) { //其父id等于-1则为第一级别的评论 if (comment.getParentId() == -1) { //我们将该评论下的所有评论都查出来 comment.setReplyComments(findReply(comments, comment.getId())); //这就是我们最终数组中的Comment list.add(comment); } } return list; } /** * @param comments 我们所有的该博客下的评论 * @param targetId 我们要查到的目标父id * @return 返回该评论下的所有评论 */ public List findReply(List comments, int targetId) { //第一级别评论的子评论集合 ArrayList reply = new ArrayList(); for (Comments comment : comments) { //发现该评论的父id为targetId就将这个评论加入子评论集合 if (find(comment.getParentId(), targetId)) { reply.add(comment); } } return reply; } public boolean find(int id, int target) { //不将第一节评论本身加入自身的子评论集合 if (id == -1) { return false; } //如果父id等于target,那么该评论就是id为target评论的子评论 if (id == target) { return true; } else { //否则就再向上找 return find(commentsMapper.selectById(id).getParentId(), target); } } 总结

本文较全面地介绍了博客评论以及回复功能的实现。实现逻辑:因为是个人博客普通用户不需要登录即可浏览,所以没有做普通用户登录功能,评论时只需输入自己的QQ号,自动拉取头像和昵称进行评论。

相关链接:评论如何获取IP地址?



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3