文章目录
显示评论
创建帖子对应的实体类
entityType 表示不同的对象 可能回复的是帖子 ,用户 用int代表不同的类型
public class Comment {
private int id;
private int userId;
private int entityType; //回复的类型 是帖子 还是用户
private int entityId;
private int targetId;
private String content;
private int status; //0表示有效
private Date createTime;
}
编写对应的Mapper
实现两个方法 根据帖子类型查找实现分页
@Mapper
public interface CommentMapper {
//根据类型查找相应的帖子
List<Comment> selectCommentByEntity(int entityType,int entityId,int offset,int limit);
//查找相应类型的帖子的数量
int selectCountComments(int entityType,int entityId);
}
编写Mapper对应的xml实现方法
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.js.community.dao.CommentMapper">
<sql id="selectFields">
id, user_id, entity_type, entity_id, target_id, content, status, create_time
</sql>
<sql id="insertFields">
user_id, entity_type, entity_id, target_id, content, status, create_time
</sql>
<select id="selectCommentByEntity" resultType="Comment">
select <include refid="selectFields"></include>
from comment
where status = 0
and entity_type = #{entityType}
and entity_id = #{entityId}
order by create_time asc
limit #{offset}, #{limit}
</select>
<select id="selectCountComments" resultType="int">
select count(id)
from comment
where status = 0
and entity_type = #{entityType}
and entity_id = #{entityId}
</select>
</mapper>
编写Service实现Mapper的业务
@Service
public class CommentService {
@Autowired(required = false)
CommentMapper commentMapper;
public List<Comment> findCommentsByEntity(int entityType, int entityId, int offset, int limit) {
return commentMapper.selectCommentByEntity(entityType, entityId, offset, limit);
}
public int findCommentCount(int entityType, int entityId) {
return commentMapper.selectCountComments(entityType, entityId);
}
}
在查询帖子的Controller里增加显示评论的方法(重点)
思路:
1、当点即查看帖子详情的时候,下面会带上帖子的评论,评论需要分页显示,因此需要用到Page分页对象,需要对Page的属性进行设置;
2、调用CommentService方法,获得该帖子的所有评论信息,需要传入相应的类型和id,得到一个Comment对象的List集合;
3、每一条评论需要显示作者和内容,用户名称从comment表的userid获取到user对象,因此每一条评论也需要相应的user和post对象;
4、每一条评论可能又有回复列表,因此需要传入新的类型,获取该条评论的所有回复,显示用户名和内容,因此每一条评论的回复也需要相应的user和post对象;
5、为了方便类型的可变,增加了两个常量 int ENTITY_TYPE_POST,ENTITY_TYPE_COMMENT
//根据id查询帖子
@RequestMapping(value = "/discuss/detail/{discussPostId}",method = RequestMethod.GET)
public String getDiscussPost(@PathVariable("discussPostId") int id, Model model,Page page)
{
//帖子
DiscussPost discussPost = discussPostService.selectPostById(id);
model.addAttribute("post",discussPost);
//通过userid查找对应的用户
User user = userService.queryUserById(discussPost.getUserId());
model.addAttribute("user",user);
//显示帖子
// 评论分页信息
page.setLimit(5);
page.setRows(discussPost.getCommentCount());
page.setPath("/discuss/detail/"+id);
// 评论: 给帖子的评论
// 回复: 给评论的评论
// 获取评论列表
List<Comment> comments = commentService.findCommentsByEntity(
ENTITY_TYPE_POST, id, page.getOffset(), page.getLimit());
// 评论VO列表 从评论列表里取出每一条评论的用户名称和内容
List<Map<String,Object>> commentVoList=new ArrayList<>();
if(comments!=null) {
for (Comment comment : comments) {
//创建map来保存用户名称和内容
Map<String,Object> commentVo=new HashMap<>();
//保存评论和用户
commentVo.put("user",userService.queryUserById(comment.getUserId()));
commentVo.put("comment",comment);
//***
// 每一条评论又可能会有回复列表 跟评论列表操作一样
//回复列表
List<Comment> replyList = commentService.findCommentsByEntity(
ENTITY_TYPE_COMMENT, comment.getId(), 0, Integer.MAX_VALUE);
// 回复VO列表
List<Map<String, Object>> replyVoList = new ArrayList<>();
if (replyList != null) {
for (Comment reply : replyList) {
Map<String, Object> replyVo = new HashMap<>();
// 回复
replyVo.put("reply", reply);
// 作者
replyVo.put("user", userService.queryUserById(reply.getUserId()));
// 回复目标 ==0表示没有对特定人进行回复 否则对特定人进行回复
User target = reply.getTargetId() == 0 ? null : userService.queryUserById(reply.getTargetId());
replyVo.put("target", target);
replyVoList.add(replyVo);
}
}
//把回复列表添加到comments里
commentVo.put("replys", replyVoList);
// 回复数量
int replyCount = commentService.findCommentCount(ENTITY_TYPE_COMMENT, comment.getId());
commentVo.put("replyCount", replyCount);
//把每一次遍历的map添加到list里
commentVoList.add(commentVo);
}
}
//向模板添加集合
model.addAttribute("comments", commentVoList);
return "/site/discuss-detail";
}
修改相应的页面
第几楼的修改 cvoStat.count是内置的遍历次数+page.offset
<span class="badge badge-secondary float-right floor">
<i th:text="${page.offset + cvoStat.count}">1</i>#</span>
添加评论
业务层
-增加帖子 使用事务 增加帖子的时候增加评论数量
//增加帖子 使用事务 增加帖子的时候增加评论数量
@Transactional(isolation = Isolation.READ_COMMITTED,propagation = Propagation.REQUIRED)
public int addComment(Comment comment)
{
//增加帖子 过滤敏感词和标签
comment.setContent(HtmlUtils.htmlEscape(comment.getContent()));
comment.setContent(sensitiveFilter.filter(comment.getContent()));
int row = commentMapper.insertComment(comment);
// 更新帖子评论数量
if (comment.getEntityType() == ENTITY_TYPE_POST) {
int count = commentMapper.selectCountComments(comment.getEntityType(), comment.getEntityId());
discussPostService.updateCommentCount(comment.getEntityId(), count);
}
return row;
}
表现层
–添加玩评论后重定向到帖子页面
@Controller
@RequestMapping("/comment")
public class CommentController {
@Autowired
CommentService commentService;
@Autowired
HostHolder hostHolder;
//增加评论
@RequestMapping(value = "/add/{discussPostId}",method = RequestMethod.POST)
public String addComent(@PathVariable("discussPostId") int discussPostId, Comment comment)
{
comment.setUserId(hostHolder.getUser().getId());
comment.setStatus(0);
comment.setCreateTime(new Date());
commentService.addComment(comment);
return "redirect:/discuss/detail/"+discussPostId;
}
}
修改页面
1、修改给帖子回复的页面 类型为1
2、修改给评论回复的页面 类型为2 id为当前评论的id
3、修改给特定人回复的页面 类型为2 id为当前评论的id 增加一个目标id
<!-- 回帖输入 -->
<div class="container mt-3">
<form class="replyform" method="post" th:action="@{|/comment/add/${post.id}|}">
<p class="mt-3">
<a name="replyform"></a>
<textarea placeholder="在这里畅所欲言你的看法吧!" name="content"></textarea>
<input type="hidden" name="entityType" value="1">
<input type="hidden" name="entityId" th:value="${post.id}">
</p>
<p class="text-right">
<button type="submit" class="btn btn-primary btn-sm"> 回 帖 </button>
</p>
</form>
</div>
<div th:id="|huifu-${rvoStat.count}|" class="mt-4 collapse">
<form method="post" th:action="@{|/comment/add/${post.id}|}">
<div>
<input type="text" class="input-size" name="content" th:placeholder="|回复${rvo.user.username}|"/>
<input type="hidden" name="entityType" value="2">
<input type="hidden" name="entityId" th:value="${cvo.comment.id}">
<input type="hidden" name="targetId" th:value="${rvo.user.id}">
</div>
<div class="text-right mt-2">
<button type="submit" class="btn btn-primary btn-sm" onclick="#"> 回 复 </button>
</div>
</form>
</div>