写点什么

设计一套评论系统

作者:Kevin_913
  • 2023-10-25
    广东
  • 本文字数:1466 字

    阅读完需:约 5 分钟

设计一套评论系统

这一篇文章将完整的描述如何设计评论系统,从数据库到代码的实现。

需求

用户可以对文章进行评论。


1、用户对文章评论。


2、用户回复指定的评论。

模型设计

  • 用户:用户相关信息,基础表。

  • 文章:文章基础信息,业务表。

  • 图片:文章相关联图片,业务表。

  • 属性:文章相关联属性,业务表。

  • 文章评论数,通过添加评论,动态更新字段。

  • 点赞数。

  • 文章 tags。

  • 评论:文章评论,业务表。

  • 文章 ID

  • rootId,如果是直接评论文章,这个值为 0,否则将设置为根评论节点的 ID。根评论节点代表为评论文章的评论的节点。

  • parentId,如果是直接评论文章,这个值为 0,否则设置为评论节点的 ID。评论节点代表为回复评论的节点

数据库设计

代码实现

核心代码是如何将评论进行分组返回到前端。

SQL 查询

select a.*, u.name as userName,b.* from article_comment a     inner join public.user u on a.user_id = u.id     left join (select xa.id, xu.id as replyToUserId, xu.name as replyToUserName from article_comment xa inner join public.user xu on xa.user_id = xu.id) b on b.id=a.parent_id where a.article_id=1 order by created_at desc;
复制代码

代码分组

    public Flux<ArticleCommentRawData> getRawData(int articleId) {        List<ArticleCommentRawData> rawData = articleCommentMapper.getRawData(articleId);        Map<Integer, List<ArticleCommentRawData>> articleCommentMap = new HashMap<>();        List<ArticleCommentRawData> rtn = new ArrayList<>();        rawData.forEach(rd -> {            if (rd.getRootId() == 0) {                rtn.add(rd);
articleCommentMap.computeIfAbsent(rd.getId(), k -> new ArrayList<>()); } else { int rootId = rd.getRootId(); articleCommentMap.computeIfAbsent(rootId, k -> new ArrayList<>()); articleCommentMap.get(rootId).add(rd); }
}); rtn.forEach(rd -> { if (articleCommentMap.containsKey(rd.getId())) { rd.setChildren(articleCommentMap.get(rd.getId()).stream().sorted(Comparator.comparing(ArticleCommentRawData::getCreatedAt)).toList()); }
}); return Flux.fromStream(rtn.stream()); }
复制代码

前端显示

    <div class="container">      <div class="comment_header">最新评论</div>      <div class="comment_card" v-for="c in comments">        <div class="user_name">{{ handleUserName(c) }}<span>{{ format(c.createdAt), 'zh_CN' }}:</span></div>        <div style="display: flex;flex-flow: row; align-items: baseline;">          <div class="comment_content">{{ c.content }}</div>          </div>        </div>        <div class="content" v-if="c.children != null">          <div v-for="x in c.children" style="padding-left: 20px;">            <div class="user_name">{{ handleUserName(x) }}<span>{{ format(x.createdAt), 'zh_CN' }}</span>            </div>            <div style="display: flex;flex-flow: row; align-items: baseline;">              <div class="comment_content"><span>回复{{ handleReplyUserName(x) }}:</span> {{ x.content }}</div>            </div>          </div>        </div>      </div>    </div>
复制代码

最终效果


发布于: 刚刚阅读数: 5
用户头像

Kevin_913

关注

纸上得来终觉浅,绝知此事要躬行。 2019-02-25 加入

专注于代码和设计15+年。 主要涉及Java,Golang,云平台。

评论

发布
暂无评论
设计一套评论系统_Java_Kevin_913_InfoQ写作社区