Echo/docs/120-显示评论.md
2021-01-24 16:55:16 +08:00

5.7 KiB
Raw Blame History

显示评论


解释一下评论表中的三个字段:

  • entity_type: 可以对帖子进行评论,也可以对该帖子的评论进行评论(回复) 该字段就是用来表明评论目标的类别1 帖子2 评论
  • entity_id: 评论目标的 id。比如对 id 为 115 的 帖子进行评论,对 id 为 231 的评论进行评论
  • target_id: 指明我们这个回复是针对哪个用户的评论的(该字段只对回复生效,默认是 0

DAO

@Mapper
public interface CommentMapper {

    /**
     * 根据评论目标类别、id对评论进行分页查询
     * @param entityType 评论目标的类别
     * @param entityId 评论目标的 id
     * @param offset 每页的起始索引
     * @param limit 每页显示多少条数据
     * @return
     */
    List<Comment> selectCommentByEntity(int entityType, int entityId, int offset, int limit);

    /**
     * 查询评论的数量
     * @param entityType
     * @param entityId
     * @return
     */
    int selectCountByEntity(int entityType, int entityId);

}

对应的 maaper.xml

<mapper namespace="com.greate.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 = "selectCountByEntity" resultType="int">
        select count(id)
        from comment
        where status = 0
        and entity_type = #{entityType}
        and entity_id = #{entityId}
    </select>

</mapper>

Service

@Service
public class CommentService {

    @Autowired
    private CommentMapper commentMapper;

    /**
     * 根据评论目标类别、id对评论进行分页查询
     * @param entityType
     * @param entityId
     * @param offset
     * @param limit
     * @return
     */
    public List<Comment> findCommentByEntity(int entityType, int entityId, int offset, int limit) {
        return commentMapper.selectCommentByEntity(entityType, entityId, offset, limit);
    }


    /**
     * 查询评论的数量
     * @param entityType
     * @param entityId
     * @return
     */
    public int findCommentCount(int entityType, int entityId) {
        return commentMapper.selectCountByEntity(entityType, entityId);
    }
}

Controller

在上篇的帖子详情中进行添加(复用分页组件)

/**
 * 进入帖子详情页
 * @param discussPostId
 * @param model
 * @return
 */
@GetMapping("/detail/{discussPostId}")
public String getDiscussPost(@PathVariable("discussPostId") int discussPostId, Model model, Page page) {
    // 帖子
    DiscussPost discussPost = discussPostSerivce.findDiscussPostById(discussPostId);
    model.addAttribute("post", discussPost);
    // 作者
    User user = userService.findUserById(discussPost.getUserId());
    model.addAttribute("user", user);

    // 评论分页信息
    page.setLimit(5);
    page.setPath("/discuss/detail/" + discussPostId);
    page.setRows(discussPost.getCommentCount());

    // 存储帖子的评论
    List<Comment> commentList = commentService.findCommentByEntity(
            ENTITY_TYPE_POST, discussPost.getId(), page.getOffset(), page.getLimit());

    List<Map<String, Object>> commentVoList = new ArrayList<>(); // 封装对帖子的评论和评论的作者信息
    if (commentList != null) {
       for (Comment comment : commentList) {
            // 对帖子的评论
            Map<String, Object> commentVo = new HashMap<>();
            commentVo.put("comment", comment);
            commentVo.put("user", userService.findUserById(comment.getUserId()));

            // 存储评论的评论(不做分页)
            List<Comment> replyList = commentService.findCommentByEntity(
                   ENTITY_TYPE_COMMENT, comment.getId(), 0, Integer.MAX_VALUE);
            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.findUserById(reply.getUserId()));
                    User target = reply.getTargetId() == 0 ? null : userService.findUserById(reply.getUserId());
                    replyVo.put("target", target);

                    replyVoList.add(replyVo);
                }
            }
            commentVo.put("replys", replyVoList);
            
            // 对某个评论的回复数量
            int replyCount = commentService.findCommentCount(ENTITY_TYPE_COMMENT, comment.getId());
            commentVo.put("replyCount", replyCount);

            commentVoList.add(commentVo);
       }
    }

    model.addAttribute("comments", commentVoList);

    return "/site/discuss-detail";

}

前端

<li th:each="cvo:${comments}">
	<div th:utext="${cvo.comment.content}"></div>
    
    <li th:each="rvo:${cvo.replys}">
        <span th:text="${rvo.reply.content}"></span>

cvoStat 固定表达:循环变量名 + Stat 表示每次的循环对象

cvoStat.count 表示当前是第几次循环