开发基于SpringBoot和BootStrap的全栈论坛网站(七):完成回复和二级回复功能

news/2024/5/9 22:16:05/文章来源:https://javayz.blog.csdn.net/article/details/103232086

论坛的搭建即将进入尾声,完成回复功能后只剩最后一个大功能:通知。然后就是对页面的精修和一些bug的修复,这些不会通过博客来展示,历史博客记录可以看我的实战项目专辑,在这里也不放链接了。

对一个论坛网站来说,回复功能也是很重要的功能,在完成之前所有功能后,今天的任务就是完成问题的回复功能,主要的效果图如下:

(一)搭建Comment数据库

一个回复需要包含主键id;所回复问题或者回复评论的parent_id;一个判断是回复问题还是回复别人评论的type,当type=1时,回复问题,当type=2时,回复别人的评论;回复人commentor;回复时间createtime;点赞数like_count;回复内容content;回复数:commentcount

CREATE TABLE `comment` (`id` int(11) NOT NULL AUTO_INCREMENT,`parent_id` int(11) NOT NULL,`type` int(11) NOT NULL,`commentor` int(11) DEFAULT NULL,`createtime` bigint(20) DEFAULT NULL,`like_count` int(11) DEFAULT '0',`content` varchar(200) NOT NULL,`commentcount` int(11) DEFAULT '0',PRIMARY KEY (`id`)
) 

建完数据库之后创建实体类:

public class Comment {private int id;private int parent_id;private int type;private int commentor;private int like_count;private long createtime;private int commentcount;private String content;//省略getter and setter 方法
}

(二)Comment的数据传输结构

当用户输入回复,点击提交之后,我希望从前端传过来的数据包含parent_id(所回复对象的id),content(回复的内容)和type(判断回复的是问题还是评论),因为user的信息和创建时间等都可以直接在后端获取,不需要从前端传过来。于是建立commentcreateDTO,用来封装传递过来的数据:

public class CommentCreateDto {private int parent_id;private int type;private String content;//省略getter and setter 方法
}

 前端需要展示回复的信息,因此需要从后端传递回复数据给前端,传给前端的数据不仅要包含comment的所有属性,还要包含user的所有信息,因为我们需要展示出是回复人的姓名和头像,于是创建CommentDTO用于封装传给前端的数据:

public class CommentDto {private int id;private int parent_id;private int type;private int commentor;private int like_count;private long createtime;private int commentcount;private String content;private User user;//省略getter and setter 方法
}

 

 同时,如果comment成功插入到数据库了,我希望前端能知道成功了,因此再创建一个ResultDto,里面包含是否成功的信息以及CommentDTO的数据:

public class ResultDto<T> {private int code;private String message;private T data;public ResultDto success(){ResultDto resultDto=new ResultDto();resultDto.setCode(200);resultDto.setMessage("成功");return resultDto;}public <T> ResultDto success(T data){ResultDto resultDto=new ResultDto();resultDto.setCode(200);resultDto.setMessage("成功");resultDto.setData(data);return resultDto;}//省略getter and setter 方法
}

(三)完成回复问题功能

问题回复功能有两个模块,一是展示回复内容,二是回复框的处理。展示回复内容很简单,在questionController中增加两行代码:

List<CommentDto> comments=commentService.getByid(id);
model.addAttribute("comments",comments);

通过问题的id查找到回复信息,放进一个List中,并通过model传递给前端,前端只需要通过each的方式逐条获取数据展示就行。前端的代码请看源码的question.html

前端回复框包含一个textarea和一个button,给button设置onclick属性,通过jquery来处理点击提交后的回复的逻辑,写一个隐藏起来的input,这个input不会展示在前端页面上,但是可以用来传递问题的id,让后台知道是在哪个问题下评论 

<input type="hidden" id="question_id" th:value="${questionDto.id}">
<textarea class="form-control" rows="6" style="margin-top:10px; margin-bottom: 10px;"id="content"></textarea>
<button type="button" class="btn btn-success" style="float: right;margin: 10px;"onclick="post()">提交

 新建community.js,把数据封装成一个json格式给到后端

function post() {//获取问题idvar questionid = $("#question_id").val();//获取回复内容var content = $("#content").val();if(content==''){alert("回复内容不能为空")}else {$.ajax({type:"POST",url:"/comment",contentType:'application/json',data: JSON.stringify({"parent_id":questionid,"type":1,"content":content}),//获取后端返回过来的数据,也就是ResultDTOsuccess: function (data) {if (data.code==200){window.location.reload();} else{alert("出现了错误");}},dataType:"json"});}
}

 新建CommentController,将数据写进数据库,具体操作和之前基本一致

@Controller
public class CommentController {@Resourceprivate UserMapper userMapper;@Resourceprivate CommentMapper commentMapper;@Resourceprivate QuestionMapper questionMapper;@ResponseBody@RequestMapping(value = "/comment",method = RequestMethod.POST)public Object post(@RequestBody CommentCreateDto commentCreateDto,HttpServletRequest request){//获取userCookie[] cookies = request.getCookies();if (cookies == null) {return "login";}User user = null;for (Cookie cookie : cookies) {if (cookie.getName().equals("token")) {String token = cookie.getValue();user = userMapper.findBytoken(token);if (user != null) {request.getSession().setAttribute("user", user);}break;}}//将前端传递过来的信息上传数据库Comment comment=new Comment();comment.setParent_id(commentCreateDto.getParent_id());comment.setContent(commentCreateDto.getContent());comment.setType(commentCreateDto.getType());comment.setCreatetime(System.currentTimeMillis());comment.setCommentor(user.getId());commentMapper.insert(comment);if (commentCreateDto.getType()==2){commentMapper.updatecommentcount(commentCreateDto.getParent_id());}else {questionMapper.updatecomment(commentCreateDto.getParent_id());}ResultDto resultDto=new ResultDto();//返回结果return resultDto.success();}
}

 这样一个回复功能就完成了。

(四)完成二级回复问题功能

二级回复功能的处理比一级回复要更麻烦一些,二级回复也分成回复展示和回复框两块,只是二级回复的回复展示我打算用js传递给前端,所以先写二级评论的输入框功能,同样包含一个input和button,在button上有onclick属性

<div class="col-lg-12 col-md-12 col-sm-12 col-ss-12" style="margin-top: 10px;"><input type="text" class="form-control" placeholder="评论一下....." th:id="${'input-'+comment.id}"><button type="button" class="btn btn-success" style="float: right;margin: 10px;"onclick="replypost(this)" th:data-id="${comment.id}">提交</button>
</div>

 在community.js中新增方法,也一样是将回复内容上传给后端,只是这里将type改成了2,因为回复的是别人的评论,parentid也变成了评论的id

function replypost(e) {var commentid = e.getAttribute("data-id");var content = $("#input-"+commentid).val();if(content==''){alert("回复内容不能为空")}else {$.ajax({type:"POST",url:"/comment",contentType:'application/json',data: JSON.stringify({"parent_id":commentid,"type":2,"content":content}),success: function (data) {if (data.code==200){window.location.reload();} else{alert("出现了错误");}},dataType:"json"});}
}

 在一级评论的回复按钮上增加onclick,用于点击后展开回复内容

<!--回复按钮-->
<span class="glyphicon glyphicon-comment icon" aria-hidden="true"th:data-id="${comment.id}" th:data-check="1" onclick="secondcomment(this)" th:text="${comment.commentcount}"></span>

 在CommentController新增一个方法,把回复数据传递给前端

@ResponseBody
@RequestMapping(value = "/comment/{id}",method = RequestMethod.GET)
public ResultDto<List<CommentDto>> comments(@PathVariable(name = "id") int id,HttpServletRequest request){//查找type=2,即是回复评论的评论List<Comment> comments = commentMapper.getCommentByid(id,2);List<CommentDto> commentDto=new ArrayList<>();//找到UserCookie[] cookies = request.getCookies();User user = null;for (Cookie cookie : cookies) {if (cookie.getName().equals("token")) {String token = cookie.getValue();user = userMapper.findBytoken(token);break;}}//把二级评论和对应的User写进每个CommentDto集合中for (Comment comment:comments){CommentDto dto=new CommentDto();BeanUtils.copyProperties(comment,dto);dto.setUser(user);commentDto.add(dto);}ResultDto resultDto=new ResultDto();return resultDto.success(commentDto);
}

前端js中的secondcomment方法通过$.getJSON获取到后端发过来的数据,然后通过 $.each循环List中的每一条数据,回复展示的内容我使用jquery将html代码插入到html页面中id为comment-id的div块中,js中所插入的html代码相当于这一段

<div class="col-lg-12 col-md-12 col-sm-12 col-ss-12" th:each="comment:${comments}"><div class="media"><div class="media-left"><img class="media-object img-rounded picset"src="https://profile.csdnimg.cn/F/C/F/1_qq_41973594?v=1574041386"></div><div class="media-body"><h4 class="media-heading"><span th:text="${comment.user.name}"/><div style="font-size: 15px; margin-top:5px;"th:text="${comment.content}"></div><div class="question-menu"><span th:text="${#dates.format(comment.createtime,'yyyy-MM-dd')}"style="float: right"></span></div></h4></div></div>
</div>

 js代码

function secondcomment(e) {var id = e.getAttribute("data-id");var check = e.getAttribute("data-check");var comment = $("#comment-"+id);//如果check为1则展开二级评论,否则收缩if (check=="1"){$.getJSON("/comment/"+id , function (data) {var subCommentContainer=$("#comment-"+id) ;//如果子元素的长度为1,即第一次添加,则调用下面的方法if (subCommentContainer.children().length ==1){$.each(data.data.reverse(),function (index,comment) {//对应<span th:text="${comment.user.name}"/>var usernameElement=$("<span/>",{html:comment.user.name});//对应<div style="font-size: 15px; margin-top:5px;"//      th:text="${comment.content}">//    </div>var contentElement=$("<div/>",{"style":"font-size: 15px; margin-top:5px;",html:comment.content});var timeElement=$("<span/>",{"style":"float: right",html:moment(comment.createtime).format('YYYY-MM-DD')});var questionmenuElement=$("<div/>",{"class":"question-menu"}).append(timeElement);var imgElement = $("<img/>",{"class":"media-object img-rounded picset","src":"https://profile.csdnimg.cn/F/C/F/1_qq_41973594?v=1574041386"});var medialeftElement=$("<div/>",{"class":"media-left"}).append(imgElement);var mediaheadingElement=$("<h4/>",{"class":"media-heading",}).append(usernameElement).append(contentElement).append(questionmenuElement);var mediabodyElement=$("<div/>",{"class":"media-body",}).append(mediaheadingElement);var mediaElement=$("<div/>",{"class":"media"}).append(medialeftElement).append(mediabodyElement);var commentElement=$("<div/>",{"class":"col-lg-12 col-md-12 col-sm-12 col-ss-12 comments",}).append(mediaElement);subCommentContainer.prepend(commentElement);})}});comment.addClass("in");e.setAttribute("data-check","0");e.classList.add("active");}else {comment.removeClass("in");e.setAttribute("data-check","1")e.classList.remove("active");}
}

 这样回复和二级回复功能就完成了,完成这些后,一个论坛所需要的基本功能就全部完成了,接下来就是对论坛界面和其他一些小功能的小修小补,首页的热门问题还未写,搜索功能目前也没有,用户的头像目前用的是统一的图片,个人中心中我的消息功能还未做,还想优化一下标签功能。

附上源码:github源码

 

 

 

 

 

 

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_715428.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

开发基于SpringBoot和BootStrap的全栈论坛网站(八):完成回复通知的功能

当有人回复了你的问题时&#xff0c;肯定需要有通知能让我们看到&#xff0c;今天就来完成最后一个大功能--回复通知。具体的效果如下&#xff1a; 当有未读通知时&#xff0c;在导航栏上会显示未读通知的数量&#xff0c;点进去后能看到未读的信息&#xff0c;点击每条未读信息…

如何更改PHPCMS网站后台标题(title)

打开PHPCMS安装目录&#xff0c;选择phpcms 然后选择Languages目录&#xff0c;打开。 打开目录后&#xff0c;选择zh-cn目录&#xff0c;选择admin.lang.php用editPlus打开&#xff0c;将第九行后面的引号中的内容换成你想要改变的网站后台标题&#xff0c;保存文件 转载于:ht…

查准考证网站卡了整整一个小时进不去,被抢票支配的恐惧又来了

&#xff08;一&#xff09;概述 今天是国考出准考证的时间&#xff0c;刚好女朋友也要报名了这次考试&#xff0c;作为合格的男朋友当然是要在第一时间将准考证信息下载下来。结果到了半夜12点之后&#xff0c;整个官网一直处于无法连接、502、503、接口报错等各种问题。到了…

搜索引擎登录,网站分类目录登录地址

搜索引擎登录入口 google 如果你的网站是新发布的&#xff0c;或是访问量较低的网站在内容更新时&#xff0c;很有必要主动提交到Google&#xff0c;这样会使网站资料迅速更新倒Google搜索资料库&#xff0c;让用户能及时搜索到你的最新资料。 登录地址&#xff1a;http://www…

基于SpringBoot和BootStrap的全栈论坛网站(附上源码)

耗时大约三个星期不到的时间&#xff0c;把这个论坛项目基本上算是完成了&#xff0c;做这个项目最主要的目的是熟悉SpringBoot的使用&#xff0c;然后通过整个项目了解了BootStrap、Thymeleaf、editor.md等等工具的使用&#xff0c;今天就来做一下总结 &#xff08;一&#x…

一个有意思的网站

http://www.icpoline.com 上面看到一句话&#xff1a;傻的人之所以傻&#xff0c;那就在于他&#xff08;她&#xff09;不知道自己傻&#xff0c;如果他&#xff08;她&#xff09;知道自己傻&#xff0c;那他&#xff08;她&#xff09;就不傻。 所以&#xff0c;我敢断定…

网市场云建站 v4.8 增加私有模版库,开放 Mysql 配置、在线客服源码

开发四年只会写业务代码&#xff0c;分布式高并发都不会还做程序员&#xff1f; 网市场云建站系统&#xff0c;结合各种产品&#xff0c;将一个网站的服务器成本降低到0.1元&#xff01;打破传统建站的高成本&#xff0c;让价格不再是阻碍的门槛&#xff0c;让每个人都能有自…

高并发量网站解决方案

为什么80%的码农都做不了架构师&#xff1f;>>> 最近遇到高并发数据访问的问题&#xff0c;这篇博文讲的比较全面&#xff0c;值得一看。来源参考&#xff1a; http://blog.csdn.net/y_h_t/article/details/6322823 转载于:https://my.oschina.net/garyun/blog/602…

QQ登录网站接入功能实现--非官方文档搬运

背景 最近第一次使用QQ登录功能&#xff0c;期间遇到这种问题&#xff0c;在网上找了很多资料&#xff0c;大多都是官方的搬运&#xff0c;并没有真正的干料&#xff0c;可能是个人能力问题&#xff0c;遇到了各种麻烦&#xff0c;折腾了几天&#xff0c;最终弄好&#xff0c;…

从vancl看垂直商业网站的崛起

从vancl看垂直网站的崛起&#xff08;文&#xff1a;王英雄&#xff09;如果说2007年IT业内的几大事件&#xff0c;卖衬衣的卖火了&#xff0c;这肯定是2007年的重大事件之一。提起卖衬衣的&#xff0c;大家肯定会想到的是PPG&#xff0c;但我为什么不拿PPG做标题呐&#xff1f…

大型网站应用之海量数据和高并发解决方案总结一二

一、网站应用背景 开发一个网站的应用程序&#xff0c;当用户规模比较小的时候&#xff0c;使用简单的&#xff1a;一台应用服务器一台数据库服务器一台文件服务器&#xff0c;这样的话完全可以解决一部分问题&#xff0c;也可以通过堆硬件的方式来提高网站应用的访问性能&…

小白入门:大型网站技术架构负载均衡技术介绍及学习资源推荐

十年间&#xff0c;负载均衡的前沿技术层出不穷&#xff0c;令用户眼花缭乱。经常在技术网站、文档中出现的“四层负载均衡”、“七层负载均衡”字眼有什么含义?有什么区别?对客户网络有哪些不同的优化? 在大型的网站服务器集群中&#xff0c;负载均衡技术是必不可少的。使…

Flex SEO(Search engine optimization),让浏览器找到你的flash站点

Search engine optimistation 也就是让你的站点信息能被“搜索引擎”&#xff08;Google,baidu…&#xff09;搜索到。SEO总分两大类&#xff0c;white hats和black hats&#xff0c;简单讲black hats是一作弊的方法&#xff0c; 例如在meta标签中加一堆重复的关键词&#xff0…

unsharp mark 算法_Google SEO-BERT算法更新

一. BERT介绍BERT的全称为&#xff1a;Bidirectional Encoder Representations from Transformers&#xff0c;基于神经网络的自然语言处理预训练的技术。谷歌说BERT就像是一个超大的同义词系统。2019 年 10 月 25 日&#xff0c;Google 宣布 BERT 更新上线&#xff0c;正式成为…

有些网站打开一半空白_如何发一条空白的朋友圈

所谓空白的朋友圈就是一条看起来没有文字的朋友圈&#xff0c;因为发朋友圈的时候不输入文字是没法发送的。不可见字符是有文字内容的&#xff0c;只是人的肉眼看不见&#xff0c;所以相当于空白。不可见字符不可见字符就是零宽空格&#xff0c;见维基百科解释https://zh.wikip…

另类网站版式设计欣赏

另类网站版式设计欣赏 当你在创建一个新网站的时候&#xff0c;希望这些网站富有个性的版式设计能给你带来灵感。 Popmatik 这是Rob Leach设计制作的一个个人网站&#xff0c;这个网站用了一个瓶子的底图&#xff0c;网站的内容都在瓶子的这个包装纸上。 Digitalmash.com Digi…

大型网站架构系列:负载均衡详解(3)

大型网站架构系列&#xff1a;负载均衡详解&#xff08;3&#xff09; 原文:大型网站架构系列&#xff1a;负载均衡详解&#xff08;3&#xff09;本次分享大纲 软件负载均衡概述Ngnix负载均衡Lvs负载均衡Haproxy负载均衡本次分享总结一、软件负载均衡概述 硬件负载均衡性能优越…

基于Dockfile构建JAVA环境网站镜像

查看本地目录 [rootdocker tomcat]# ls apache-tomcat-8.5.16.tar.gz Dockerfile jdk-8u91-linux-x64.tar.gz server.xml [rootdocker tomcat]# vim Dockerfile FROM centos:7 MAINTAINER zhaochengcheng ADD jdk-8u91-linux-x64.tar.gz /usr/local ENV JAVA_HOME /usr/loca…

linux卸载服务器软件,linux卸载软件命令是什么_网站服务器运行维护,linux

win10系统提示需要提供管理员权限才能更改这些属性怎么办_网站服务器运行维护win10系统提示需要提供管理员权限才能更改这些属性的解决方法是&#xff1a;1、首先打开系统设置&#xff0c;进入【账户】选项&#xff1b;2、然后切换到【家庭和其他用户】&#xff0c;点击【更改账…

[目录] ASP.Net Core 搭建微服务网站

本项目采用ASP.Net Core微服务技术&#xff0c;搭建博客和Saas平台。 全文将围绕&#xff08;1&#xff09;设计模式 &#xff08;2&#xff09;敏捷开发 目的&#xff1a; 结构足够合理&#xff0c;代码足够优美&#xff0c;扩展性、可读性、易维护性做到最优。 以下目录…