问答平台(3),显示评论

实体类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
// Comment.java
public class Comment {

private int id;
private int userId;
private int entityType;
private int entityId;
private int targetId;
private String content;
private int status;
private Date createTime;

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public int getUserId() {
return userId;
}

public void setUserId(int userId) {
this.userId = userId;
}

public int getEntityType() {
return entityType;
}

public void setEntityType(int entityType) {
this.entityType = entityType;
}

public int getEntityId() {
return entityId;
}

public void setEntityId(int entityId) {
this.entityId = entityId;
}

public int getTargetId() {
return targetId;
}

public void setTargetId(int targetId) {
this.targetId = targetId;
}

public String getContent() {
return content;
}

public void setContent(String content) {
this.content = content;
}

public int getStatus() {
return status;
}

public void setStatus(int status) {
this.status = status;
}

public Date getCreateTime() {
return createTime;
}

public void setCreateTime(Date createTime) {
this.createTime = createTime;
}

@Override
public String toString() {
return "Comment{" +
"id=" + id +
", userId=" + userId +
", entityType=" + entityType +
", entityId=" + entityId +
", targetId=" + targetId +
", content='" + content + '\'' +
", status=" + status +
", createTime=" + createTime +
'}';
}
}

数据访问层

  • 根据实体查询一页评论数据
  • 根据实体查询评论的数量
    1
    2
    3
    4
    5
    6
    7
    8
    9
    // CommentMapper.java
    @Mapper
    @Repository
    public interface CommentMapper {

    List<Comment> selectCommentsByEntity(int entityType, int entityId, int offset, int limit);

    int selectCountByEntity(int entityType, int entityId);
    }
  • comment-mapper.xml 里写sql
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    <sql id="selectFields">
    id, user_id, entity_type, entity_id, target_id, content, status, create_time
    </sql>

    <select id="selectCommentsByEntity" 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>

业务层

  • 处理查询评论的业务
  • 处理查询评论数量的业务
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    // CommentService.java
    @Service
    public class CommentService implements CommunityConstant {

    @Autowired
    private CommentMapper commentMapper;

    public List<Comment> findCommentsByEntity(int entityType, int entityId, int offset, int limit) {
    return commentMapper.selectCommentsByEntity(entityType, entityId, offset, limit);
    }

    public int findCommentCount(int entityType, int entityId) {
    return commentMapper.selectCountByEntity(entityType, entityId);
    }
    }

表现层

  • 显示帖子详情数据时, 同时显示该帖子所有的评论数据。
    1
    2
    3
    4
    5
    // CommunityConstant.java
    // 实体类型:帖子
    int ENTITY_TYPE_POST = 1;
    // 实体类型:评论
    int ENTITY_TYPE_COMMENT = 2;
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    // DiscussPostController.java
    @Autowired
    private CommentService commentService;

    @RequestMapping(path = "/detail/{discussPostId}", method = RequestMethod.GET)
    public String getDiscussPost(@PathVariable("discussPostId") int discussPostId, Model model, Page page) {
    // 帖子
    DiscussPost post = discussPostService.findDiscussPostById(discussPostId);
    model.addAttribute("post", post);
    // 作者
    User user = userService.findUserById(post.getUserId());
    model.addAttribute("user", user);

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

    // 评论:给帖子的评论
    // 回复:给评论的评论
    // 评论列表
    List<Comment> commentList = commentService.findCommentsByEntity(
    ENTITY_TYPE_POST, post.getId(), page.getOffset(), page.getLimit());
    // 评论VO列表
    List<Map<String, Object>> commentVoList = new ArrayList<>();
    if (commentList != null) {
    for (Comment comment : commentList) {
    // 评论VO
    Map<String, Object> commentVo = new HashMap<>();
    // 评论
    commentVo.put("comment", comment);
    // 作者
    commentVo.put("user", userService.findUserById(comment.getUserId()));
    // 回复列表
    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.findUserById(reply.getUserId()));
    // 回复目标
    User target = reply.getTargetId() == 0 ? null : userService.findUserById(reply.getTargetId());
    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";
    }

页面

  • index.html
    1
    2
    3
    4
    <!-- 帖子列表 -->
    <ul class="d-inline float-right">
    <li class="d-inline ml-2">回帖 <span th:text="${map.post.commentCount}">7</span></li>
    </ul>
  • discuss-detail.html
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    <!-- 内容 -->
    <!-- 作者 -->
    <div class="media pb-3 border-bottom">
    <a th:href="@{|/user/profile/${user.id}|}">
    <img th:src="${user.headerUrl}" class="align-self-start mr-4 rounded-circle user-header" alt="用户头像">
    </a>
    <div class="media-body">
    <div class="mt-0 text-warning" th:utext="${user.username}">寒江雪</div>
    <div class="text-muted mt-3">
    发布于 <b th:text="${#dates.format(post.createTime, 'yyyy-MM-dd HH:mm:ss')}">2019-04-15 15:32:18</b>
    <ul class="d-inline float-right">
    <li class="d-inline ml-2">
    <a href="#" class="text-primary">赞 11</i></a>
    </li>
    <li class="d-inline ml-2">|</li>
    <li class="d-inline ml-2">
    <a href="#replyform" class="text-primary">回帖
    <i th:text="${post.commentCount}">7</i>
    </a>
    </li>
    </ul>
    </div>
    </div>
    </div>
    <!-- 回帖 -->
    <!-- 回帖数量 -->
    <div class="row">
    <div class="col-8">
    <h6><b class="square"></b> <i th:text="${post.commentCount}">30</i>条回帖</h6>
    </div>
    <div class="col-4 text-right">
    <a href="#replyform" class="btn btn-primary btn-sm">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</a>
    </div>
    </div>
    <!-- 回帖列表 -->
    <!-- 第1条回帖 -->
    <ul class="list-unstyled mt-4">
    <li class="media pb-3 pt-3 mb-3 border-bottom" th:each="cvo:${comments}">
    <a th:href="@{|/user/profile/${cvo.user.id}|}">
    <img th:src="${cvo.user.headerUrl}" class="align-self-start mr-4 rounded-circle user-header" alt="用户头像">
    </a>
    <div class="media-body">
    <div class="mt-0">
    <span class="font-size-12 text-success" th:utext="${cvo.user.username}">掉脑袋切切</span>
    <span class="badge badge-secondary float-right floor">
    <i th:text="${page.offset + cvoStat.count}">1</i>#
    </span>
    </div>
    <div class="mt-2" th:utext="${cvo.comment.content}">
    这开课时间是不是有点晚啊。。。
    </div>
    <div class="mt-4 text-muted font-size-12">
    <span>发布于 <b th:text="${#dates.format(cvo.comment.createTime, 'yyyy-MM-dd HH:mm:ss')}">2019-04-15 15:32:18</b></span>
    <ul class="d-inline float-right">
    <li class="d-inline ml-2">
    <a href="#" class="text-primary">赞(1)</a>
    </li>
    <li class="d-inline ml-2">|</li>
    <li class="d-inline ml-2">
    <a href="#" class="text-primary">回复(
    <i th:text="${cvo.replyCount}">2</i>)
    </a>
    </li>
    </ul>
    </div>
    <!-- 回复列表 -->
    <ul class="list-unstyled mt-4 bg-gray p-3 font-size-12 text-muted">
    <!-- 第1条回复 -->
    <li class="pb-3 pt-3 mb-3 border-bottom" th:each="rvo:${cvo.replys}">
    <div>
    <span th:if="${rvo.target==null}">
    <b class="text-info" th:text="${rvo.user.username}">寒江雪</b>:
    </span>
    <span th:if="${rvo.target!=null}">
    <i class="text-info" th:text="${rvo.user.username}">Alice</i> 回复
    <b class="text-info" th:text="${rvo.target.username}">寒江雪</b>:
    </span>
    <span th:utext="${rvo.reply.content}">这个是直播时间哈,觉得晚的话可以直接看之前的完整录播的~</span>
    </div>
    <div class="mt-3">
    <span th:text="${#dates.format(rvo.reply.createTime, 'yyyy-MM-dd HH:mm:ss')}">2019-04-15 15:32:18</span>
    <ul class="d-inline float-right">
    <li class="d-inline ml-2">
    <a href="#" class="text-primary">赞(1)</a>
    </li>
    <li class="d-inline ml-2">|</li>
    <li class="d-inline ml-2">
    <a th:href="|#huifu-${rvoStat.count}|" data-toggle="collapse" class="text-primary">回复</a>
    </li>
    </ul>
    </div>
    </li>
    <!-- 回复输入框 -->
    </ul>
    </div>
    </li>
    </ul>
    <!-- 分页 -->
    <nav class="mt-5" th:replace="index::pagination">
    <ul class="pagination justify-content-center">
    <li class="page-item"><a class="page-link" href="#">首页</a></li>
    <li class="page-item disabled"><a class="page-link" href="#">上一页</a></li>
    <li class="page-item active"><a class="page-link" href="#">1</a></li>
    <li class="page-item"><a class="page-link" href="#">2</a></li>
    <li class="page-item"><a class="page-link" href="#">3</a></li>
    <li class="page-item"><a class="page-link" href="#">4</a></li>
    <li class="page-item"><a class="page-link" href="#">5</a></li>
    <li class="page-item"><a class="page-link" href="#">下一页</a></li>
    <li class="page-item"><a class="page-link" href="#">末页</a></li>
    </ul>
    </nav>

问答平台(3),显示评论
https://lcf163.github.io/2020/05/13/问答平台(3),显示评论/
作者
乘风的小站
发布于
2020年5月13日
许可协议