Tips: 前面废话很多,如果只想看过程请直接跳转到“简介”。

评论大概是每个交互式网站都有的功能了,目前各类CMS和博客系统都有各自不同的实现思路,但你可曾尝试过自己写一套评论系统?

我这3年来接触了DedeCMS、Discuz、WordPress等各类主流CMS/论坛博客系统,也稍微研究了它们的一些功能模块的实现,发现尽管结构不同,但设计思路基本都差不多。

为什么想自己写一套评论系统?

可以追溯到18年,当时开发ONEMC V2时的想法。DedeCMS本身是提供了一套完善的评论系统的,但是表结构有点臃肿 不太喜欢,所以就打算自己写一套了。顺便一提,当时把收藏、消息等一些模块也重新写了,不太喜欢织梦的设计。

这次是开发biliDataV2广场,功能上其实参考了B站的动态话题。

bilidata之前有一个“聊天室”功能,算是个简陋的评论区,简单修改后就可以当成分页的评论区用,不过因为站内有不同模块 其中数据ID是各自独立的,而评论表当时设计时没考虑到这一点,只有sourceId 没有sourceType,而且不能真正“回复”,只能全选出来前端JS正则(回复+ commentId)插入那条评论内。这是去年年初做的 转眼过去一年了也没再维护……

【开发日记】合集会记录一些我在这些年建站/写软件时遇到的坑或者值得记录的一些成就,供自己以后翻看,大家也可以来借鉴借鉴经验(虽然应该不会有人看。。。)

——合集介绍

简介

本次要接入的网站是bilidata,要求无损保留前身“聊天室”的评论并动态加入话题,顺便接入消息系统……啊,没有消息系统 那就顺便再写一个。

功能

迁移:前身聊天室积攒的评论要无损迁移到新的广场话题中并根据评论内容加入“话题”TAG,需要导出表全部数据,制作脚本写出SQL文件再导入。

开发需求:每个“评论”可以当成一个“帖子”,要支持回复、点赞、点踩、举报、删除,评论不可以重复点赞,要支持@功能 要变蓝;帖子要支持添加多个“话题” 每个“话题”相当于一个板块,支持话题搜索 每个话题要有简介、图标、创建者等基本信息,创建者或管理员有权操作帖子,每隔话题要有等级限制 包括发言等级和浏览等级;回复点赞艾特要推送消息,消息要显示楼主ID、回复内容 要自动设置为已读消息。

简单说,需要建三个表:话题表、评论表、消息表,另外涉及到关联日志表、用户表。

评论表结构
话题表
消息表

这里我先设计出表结构了 因为要先迁移数据,具体就不介绍了 可以根据字段名猜测,有我没说清楚的可以私聊问。

迁移旧评论

原聊天室评论表

*原聊天室支持回复评论,但本质上是发送一条名字为“回复 [id]: [回复内容]”的评论。

我们先导出表为SQL格式的文件,Python写个脚本分析内容字段并写出新的SQL文件。

我看了一遍所有评论,总结出了几个话题,脚本里根据评论关键字添加groupId,满足多个话题的可以加入多个groupId,并且导出的旧评论自带一个话题。

脚本

不细说了,大概就是这么个思路。导出的SQL直接执行就好了。

groupid字段使用了全文索引,一个评论的groupid可能是这样的“10001,10002,”,每个id关联grouplist表的主键id,如果选择包含10002的所有条目,可以使用SQL的where从句“match(groupid) against('10002')”,同时也支持多个值匹配。

小知识:“全文索引”(fulltext) 应用

接入评论系统

唉,其实写这篇专栏已经是半个月后了,当时思路已经忘得差不多了。

基本顺序就是根据数据库的表写接口、前端JS接入、写前端样式。

先写后端接口,获取评论、点赞、新评论这些,就不细说了,放出一部分代码。

写成了一个类 然后再调用

然后分功能实现,首先是回复

引入“parentid”概念,如果是主楼 此值为0,如果是回复某一个楼,此值为楼的“aid”(其实本来想写主键id 但是为了兼容原评论表的回复ID 只能先这样了)。

回复就是加入一条“parentid”为主楼的评论,共用一个“topic”->“new”接口。

点赞、点踩

点赞=thumb+1,点踩没做 如果要做可以加一个“thumb_down”字段,比较麻烦。如果想做排序 还要涉及到权重,比如一条100点赞60踩的评论要在50点赞0踩评论的下面。

防止重复点赞:关联日志表,当初次点赞时加入一条点赞记录 提前再检测。

举报:没做,但是做起来很容易。

删除:判断权限->置评论status为已删除(而不是删除条目[1])。

*[1]根据《具有舆论属性或社会动员能力的互联网信息服务安全评估规定》第五条之规定。

正则匹配@到的用户

支持@:发评论时正则匹配“@+用户名+空格”,判断用户名是否存在,如果存在就变蓝并通知。

@功能
“话题”筛选查看

接入消息系统

“消息系统”全貌

和“话题”接入过程差不多,先把接口写成一个类,然后在回复/AT/点赞时内部调用即可。

点赞推送

顺便一提 如果做了手机APP还可以改改 顺便推送到手机通知中,和本文不太相关 这里就不多说了。

最后是消息提示和已读处理。

消息提示

这个很简单 select count(*) from 消息表 where isread=0,已读就直接在获取消息的时候update isread就好。

这样一来所有需求就实现了,写这套花了有几个小时 不过因为去年做过类似的实现,这次开发没有遇到很困难的地方。

Bilibili@HT大神