前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >关于无限极(类似楼盖楼)评论回复系统的想法与构思

关于无限极(类似楼盖楼)评论回复系统的想法与构思

作者头像
躺平程序员老修
发布2023-09-05 15:57:46
2660
发布2023-09-05 15:57:46
举报
文章被收录于专栏:躺平程序员老修

评论系统

缘起

最近正在准备设计自己的社区网站,到设计评论这里的时候,引出了很多疑惑,于是记录一下,希望大佬们可以多多提出自己的想法,集思广益。

首先声明一下,我自己的项目不会这么做的,大家应该都没有类似的场景出现,我自己准备做一级评论对应多个回复的模式,不会有递归的方式。

ok,开始正文。

正文

一般我们的个人项目中,评论方式基本是一对一,或者有限的一对多,类似于网易云音乐的评论:

image2018-3-23 15_26_13.png
image2018-3-23 15_26_13.png

这种设计比较简单。当然还有稍微复杂的类似bbs的有限评论:

image2018-3-23 15_27_43.png
image2018-3-23 15_27_43.png

ok,接下来探讨一下我们要说的无限极的设计思路。

首先并不推荐这种方式,因为在实际场景中根本不会有这种场景,如果是有限的话,会有更多优秀的解决思路,比如左右值。

我的解决思路是这样的,每一条评论记录除主体内容之外,还记录parent_id,也就是父级评论,当parent_id为0则为主体评论,这样一张表即可解决数据存储的问题。

image2018-3-23 15_32_9.png
image2018-3-23 15_32_9.png

接下来,我们不能直接把这样的list给前端,因为要考虑到分页的情况,而我们根本不知道每一条主体评论的层级深度。

于是现在出现了两种做法:1.先筛选出几条主体评论,然后依次用ajax取出下面的回复。2.递归。 ajax的就比较基础了,接下来我来说一下递归的方式。

通过递归直接把主体评论与下面对应的回复返回给前端,数据结构如下:

image2018-3-23 15_41_53.png
image2018-3-23 15_41_53.png

这样前端在展示的时候也可以使用递归(我不会),或者另一种基础的方式,比如我新增一个字段给出每条主体评论的回复层级深度,这样前端使用 foreach(for(foreach())) 即可完成展示工作。

不过这种方式,我能想象,对性能的要求应该不少,谁让是无限极的呢,如果您有更屌的想法欢迎到https://www.litblc.com留言。

示例代码 :

代码语言:javascript
复制
<?php
/**
 * Author huaixiu.zhen
 * http://litblc.com
 * User: litblc
 * Date: 2018/3/20
 * Time: 15:14
 */

namespace App\Http\Controllers\Home;


use App\Model\Comment;
use App\Model\User;

class CommentController
{
    /**
     * 得到该图片的所有评论信息
     * Author huaixiu.zhen
     * http://litblc.com
     * @param $imageId
     * @return array
     */
    public function getAllComments($imageId = 1)
    {
        $comments = Comment::where('image_id', $imageId)
            ->whereParentId(0)
            ->orderBy('created_at')
            //分页处理,取出特定几条
            ->get();

        $res = [];
        foreach ($comments as $key => $value) {
            $comm['id'] = $value->id;
            $comm['user_id'] = $value->user_id;
            $comm['username'] = $this->getUserName($value->user_id);
            $comm['avatar'] = $this->getAvatar($value->user_id);
            $comm['comment'] = $value->content;
            $comm['created_at'] = $value->created_at;
            $comm['son'] = $this->getSonComment($value->id);   // 多维数组 所有父级为$value->id的评论
            $res[] = $comm;
        }

        dd($res);
    }

    /**
     * Author huaixiu.zhen
     * http://litblc.com
     * @param $userId
     * @return string
     */
    private function getUserName($userId)
    {
        $user = User::find($userId);
        if ($user) {
            $userName = $user->name;
        } else {
            $userName = '用户已注销';
        }

        return $userName;
    }

    /**
     * Author huaixiu.zhen
     * http://litblc.com
     * @param $userId
     * @return string
     */
    private function getAvatar($userId)
    {
        $user = User::find($userId);
        if ($user) {
            $avatar = $user->avatar;
        } else {
            $avatar = 'default.jpg';
        }

        return $avatar;
    }

    /**
     * 递归得到所有子评论
     * Author huaixiu.zhen
     * http://litblc.com
     * @param $commentId
     * @return mixed
     */
    private function getSonComment($commentId)
    {
        $comments = Comment::whereParentId($commentId)
            ->orderBy('created_at', 'desc')
            ->get();

        $res = [];
        if ($comments->count() > 0) {
            foreach ($comments as $key => $value) {
                $comm['id'] = $value->id;
                $comm['user_id'] = $value->user_id;
                $comm['username'] = $this->getUserName($value->user_id);
                $comm['avatar'] = $this->getAvatar($value->user_id);
                $comm['comment'] = $value->content;
                $comm['created_at'] = $value->created_at;
                $comm['son'] = $this->getSonComment($value->id);
                $res[] = $comm;
            }
        }

        return $res;
    }
}
  • 帮朋友做过一个无限极分销的获取子用户ID的功能
代码语言:javascript
复制
    /**
     * 初始化子用户ID数组
     *
     * @Author huaixiu.zhen
     * http://litblc.com
     * @var array
     */
    private $userIds = [];

    /**
     * 迭代获取所有子用户ID
     *
     * @Author huaixiu.zhen
     * http://litblc.com
     *
     * @param $userId
     *
     * @return array
     */
    private function getSonUserIds($userId)
    {
        $users = Users::where('partent_id', $userId)
            ->get(['id']);

        if ($users->count() > 0) {
            foreach ($users as $value) {

                $this->getSonUserIds($value->id);
                $this->userIds[] = $value->id;
            }
        }

        return $this->userIds;
    }

ok,如果是有限的话就简单很多了,最近刚刚发现一个很吊的思路:参考左右值无限层级存储方法https://segmentfault.com/a/1190000000329012

在消除了递归操作的前提下实现了无限分组,而且查询条件是基于整形数字的比较,效率很高。 但是节点的添加、删除及修改代价较大,将会涉及到表中多方面数据的改动。有兴趣的朋友可以研究一下。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 缘起
  • 正文
相关产品与服务
数据保险箱
数据保险箱(Cloud Data Coffer Service,CDCS)为您提供更高安全系数的企业核心数据存储服务。您可以通过自定义过期天数的方法删除数据,避免误删带来的损害,还可以将数据跨地域存储,防止一些不可抗因素导致的数据丢失。数据保险箱支持通过控制台、API 等多样化方式快速简单接入,实现海量数据的存储管理。您可以使用数据保险箱对文件数据进行上传、下载,最终实现数据的安全存储和提取。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档