如何實現一個樓中樓的評論系統

文章內容由蚊子的博客進行發佈,或許你想看看他其餘的博客呢: https://www.xiabingbao.com/comments/2017/09/01/blog-comments.htmljavascript

1. 實現前的思考

在經歷過多說和網易雲跟帖後,總算是下定決心本身要寫一個評論系統了。php

咱們在使用的不少評論系統中,目前比較流行的就是樓中樓的方式了,好比百度貼吧,wordpress等等。在這之前,通常都是按照時間順序進行1樓、2樓、3樓的展現,若是要回復某我的,使用@符號標識出這個用戶的名字,而後回覆內容。但是這樣存在一個很大的問題,討論問題沒有集中在一塊兒,其餘用戶根本不知道大家在討論什麼,原做者在1樓發表評論,你進來回復這個用戶的評論時,已經到10樓了,原做者再回復你又到20樓了。其餘用戶看到10樓時,早已經忘記原做者說了什麼了。html

師少兵的博客www.xiabingbao.com(如何實現一個樓中樓的評論系統)

百度貼吧在改版以前就是這種方式,後來在新版中啓用了樓中樓的方式,這種方式,關於某個話題的討論就能集中在一塊了。前端

師少兵的博客www.xiabingbao.com(如何實現一個樓中樓的評論系統)

同時,知乎也對他的評論系統進行了一次改版,不過不是改版成樓中樓,而是在每一個有對話評論的後面加上一個彈窗連接查看對話,點擊連接後彈窗能看到這兩我的之間互動的全部評論。vue

採用時間順序倒序或者正序平鋪的方式展現評論,這種方式實現起來簡單,可是閱讀困難;採用樓中樓的方式展現評論,對用戶的閱讀習慣比較友好,可是實現起來可能比較困難。不過,最後仍然決定採用樓中樓的方式來,雖然本人博客的評論量也少的可憐,不過仍是決定要實現一下。java

2. 數據表的設計

先說下先後端使用的語言和框架,前端考慮到頁面渲染和比較多的事件調用,使用了vue框架,vue應該說不是最好的選擇,畢竟對一個評論的前端部門來講,可能有點大材小用,不過爲了快速開發,也就選擇了vue。後端使用的是php語言,數據庫使用的是mysql。node

數據庫表的設計,既要考慮到能夠導入之前的數據,又能方便之後添加新的評論。這裏我建立了3個表: 文章表,用戶表,評論表。mysql

在網易雲跟帖關閉以前,我把本身的數據導出來了(多說的數據已經丟失,不知道導出的格式是什麼了),咱們來看下網易雲跟帖裏導出數據的格式:git

{
    "title": "從0到1學習node(七)之express搭建簡易論壇",
    "url": "www.xiabingbao.com/node/2017/02/20/node-express-forum.html",
    "sourceId": "",
    "ctime": 1487581007000,
    "comments": [
        {
            "cid": "72813956",
            "ctime": 1493107384000,
            "content": "這個論壇對node 的版本有要求嗎  個人node比較老 下載你的源碼   訪問出錯",
            "pid": "0",
            "ip": "xxx",
            "port": 0,
            "sc": "web",
            "vote": 0,
            "against": 0,
            "anonymous": false,
            "user": {
                "userId": "1074123",
                "nickname": "有態度網友06q23q",
                "avatar": "",
                "anonymous": false
            }
        },
        {
            "cid": "77196403",
            "ctime": 1493714822000,
            "content": "不太清楚,我這裏node版本是6.9.4,npm版本是3.10.10,你試一下升級node版本",
            "pid": "72813956",
            "ip": "xxx",
            "port": 0,
            "sc": "web",
            "vote": 0,
            "against": 0,
            "anonymous": false,
            "user": {
                "userId": "2414123",
                "nickname": "小小dd蚊子",
                "avatar": "http://cms-bucket.nosdn.127.net/1d6faddedb544cee93ff426a4aa2fe7620170322162349.jpg",
                "anonymous": false
            }
        }
    ]
}

從上面的數據裏,能夠看到,每一個文章都有標題,url和評論,評論的每一項都有本身對應的id,其回覆的評論pid,內容content,該評論的用戶userid, nickname和avatar。我這裏也就只摘取主要的信息錄入到數據庫中。github

2.1 用戶表

用戶表相對來講比較簡單,要考慮的就是原有的userid也要做爲字段進行保存,方便在導入評論數據時能找到對應的用戶,在評論數據也導入完成後便可將該字段刪除,之後新添加的註冊用戶用不到這個字段了。用戶表的設計:

字段 類型 說明
id int 自增,主鍵
wid int 用戶原有的userid
nickname varchar(50) 暱稱
avatar varchar(100) 頭像
status int 狀態

設計好用戶表後,將原數據中全部的用戶都單獨拿出來,而後使用userid做爲key存儲到一個數組中,這樣也能起到一個去重的效果。把拿到的全部的用戶數據存儲到用戶表

2.2 評論表

在設計評論表,主要考慮以下的因素:

  1. 評論必須依託於文章和用戶才能存在,所以評論的外鍵是文章標識和userid,留言板是一個文章內容爲空的評論形式;

  2. 我想之後新的評論能使用自增id,而不是跟隨原有評論的cid來產生新的評論id,所以此次評論表的主鍵是id,原有的評論id只做爲其中的一個字段wid來構造樓中樓的關係,這些舊評論插入到數據表時都會有新的評論id;

  3. 樓中樓的評論是處在某個評論下的,同時,樓中樓裏還有相互以前的互動回覆。所以這個評論的pid(parentid)表示當前評論處於哪一個評論之下,同時replyid表示是回覆的哪一個評論;若直接回復的父級評論,則pid與replyid相同,都是父級評論的id,若回覆的不是父級評論,則pid爲父級評論的id,replyid爲回覆評論的id;pid或replyid爲0時,則表示直接對文章發表評論。

所以咱們的評論表是這樣設計的:

字段 類型 說明
id int 自增,主鍵
wid int 評論原有的主鍵cid
uid int 用戶id
replyid int 該評論回覆的評論id,沒有則爲0
pid int 該評論所在的父級id,沒有則爲0
aid varchar(100) 文章的標識
content varchar(300) 評論內容
createtime int 評論時間的時間戳

表中的aid(文章的標識)能夠是文章的url,文章的id或者其餘任何可以惟一識別該文章的東東均可以。這裏咱們使用的是文章的uri來做爲惟一標識,好比上面數據中的文章,咱們使用/node/2017/02/20/node-express-forum.html來標識文章。其餘文章同理。

將這些評論寫入表時,咱們還要注意的是,原數據中,每一個評論都對應着一個用戶,在我設計的系統裏,用戶與評論分來了,只使用uid來進行關聯。新的用戶與新的評論都是使用自有的自增主鍵,所以在原有評論進行入庫時,須要將原來的userid轉換爲新用戶表中的主鍵id,新舊數據進行統一。

師少兵的博客www.xiabingbao.com(如何實現一個樓中樓的評論系統)

文章表不作解釋。

3. 具體實現

前端部分主要是負責展現每一個文章的評論,同時讓登陸用戶能夠添加評論。

3.1 展現評論

咱們已經對每一個評論都添加了文章標識,前端只要根據aid就能拿到當前文章全部的評論。不過咱們的評論是要樓中樓的方式展現的,不能一股腦的把數據平鋪到頁面中。咱們在2.2中也說了,pid爲0的評論都是直接對文章進行評論的,這些評論應該是做爲一級評論展現的;pid爲其餘數據的,必然是屬於某個評論之下,應看成爲樓中樓展現。

同時,不管一級評論,仍是樓中樓的評論,都有可能產生分頁的狀況,所以這裏也要作好分頁處理。

那麼最終,咱們前端拿到的結構應該大體是這樣的:

{
    code : 0,
    data : [
        {// 一級評論
            id : 1,
            content : '蚊子的博客棒棒的',
            createtime : '2017年08月08日00:26',
            nickname : '匿名者',
            reply : {// 樓中樓
                data : [
                    id : 1,
                    content : '謝謝,一塊兒學習',
                    createtime : '2017年08月08日00:36',
                    nickname : '蚊子'
                ],
                page : {
                    cur_page : 1,
                    all_page : 1
                }
            }
        }
    ],
    page : {
        cur_page : 1,
        all_page : 1
    }
}

前端拿到接口返回的數據後,就能夠渲染頁面了。在頭像的處理上,也考慮到了https的環境,所以返回的頭像連接都是//開頭的形式。

3.2 參與評論

用戶對文章或者某個評論產生了共鳴,須要留言討論一番,咱們就須要用戶可以把本身的評論也添加進去。

評論的類型,細分的話,能夠分爲3類:

  • 直接對文章發表評論,pid與replyid爲空;

  • 對一級評論進行回覆,pid與replyid均爲一級評論的id;

  • 對樓中樓進行回覆,pid爲一級評論的id,replyid爲你回覆的評論的id

我這裏前端的實現參考了oschina(開源中國)的評論方式。直接對文章評論,是直接在頂部的評論窗口進行輸入;對其餘評論進行回覆時,採用彈窗的方式來進行回覆。彈窗回覆的好處就是,頁面不用滾動,用戶對某個評論的感知也能停留在這個位置;同時也不用增長各類沒必要要的小輸入框來讓用戶輸入評論。

3.3 登陸

在登陸問題上,我也是糾結了很多的時間,到底是使用本身的登陸系統呢,仍是使用第三方登陸呢,或者是用戶不用註冊登陸,只要輸入郵箱和暱稱就能進行評論呢?

使用本身的評論系統,那麼就須要開發一套註冊和登陸流程,開發麻煩,並且對於想要回復一句話的用戶來講,可能就直接放棄註冊了;若只要輸入郵箱和暱稱就能評論,我考慮到可能會引發用戶的無限評論,沒法控制。所以,最後仍是考慮接入第三方的登陸,這裏選擇了使用微博做爲第三方登陸的入口,後續會考慮加入github的賬號登陸。

關於如何接入微博的第三方登陸,咱們下篇文章再講,文檔齊全,對不熟悉的開發者來講,剛開始可能有點懵逼,不過應該問題不大。

3.4 添加郵箱功能

用戶在第三方登陸成功後,在名字旁邊有個小的input輸入框,可讓用戶輸入郵箱來接收回復提醒,這個輸入徹底是自願的,不輸入郵箱也依然能夠評論。也是考慮到本站是個小站,訪問量極低,用戶可能一時興起評論了兩句,過後又想起這個網站來,又不知道怎麼找了。所以就想着添加一個郵件提醒功能,不讓大神的評論石沉大海。

3.5 特別注意

前端部門引入了vue框架,評論模塊在每一個文章頁都會加載。爲了防止評論模塊中的vue庫對外部的資源形成影響(好比版本衝突等),我先把全局變量給了wzVue,而後在把Vue註銷掉:

wzVue = Vue;
delete(Vue);
delete(window.Vue);

同時,在剛開始實現完成評論功能的時候,用戶只要進到這個頁面,評論就會加載。可是有個問題就是,用戶不必定會把你的文章看到底部,不必定就看你的評論。所以後來文章就改爲了按需加載,只有用戶滾動到底部,有想要看評論的意向時採起加載評論。

最終展現的效果就是這樣:

師少兵的博客www.xiabingbao.com(如何實現一個樓中樓的評論系統)

4. 總結

做爲一名前端開發,用僅有的後端知識開發一套博客的評論系統,顯得是很是的簡陋,整個框架的設計感受也是很糙。同時緩存系統用的不熟練,不能作到評論信息的當即更新。這個系統依然還有不少改進的地方。歡迎你們對蚊子(師少兵)多多提意見和建議。

在寫這篇文章的時候,想着是之後要改版的時候,能夠作成評論同步加載的方式進行。生成後的文章,更新頻率極低,甚至不太變更,那麼緩存的就是評論的內容,每當有新的評論時,就刪除當前文章的緩存,從新加載新的數據,而後再緩存上新的數據,這樣在評論數據更新比較低的時候,能夠緩存的時間更長,同時也有利於搜索引發對評論內容的抓取。

師少兵的博客www.xiabingbao.com(如何實現一個樓中樓的評論系統)

文章內容由蚊子的博客進行發佈,或許你想看看他其餘的博客呢: https://www.xiabingbao.com/comments/2017/09/01/blog-comments.html

相關文章
相關標籤/搜索