【重要更新】多说评论关闭后,本站自己实现的评论系统上线
本文由 小茗同学 发表于 2017-11-14 浏览(6411)
最后修改 2017-11-23 标签:评论

背景和感叹

多说自2017年6月关闭后,本站的评论系统就一直处于关闭状态,有严重拖延症的我终于在最近疯狂晚上加班了一阵把它完成了,拖拖拉拉这么久了,再拖下去自己估计都快疯掉了。

转纯前端快1年来,感觉自己Java的功底真的是在退步,评论这样一个很简单的东西我竟然很多地方都写的很吃力,方案换了一套又一套,代码重写了一遍又一遍,再加上自己的强迫症太严重,哎,具体细节后面再道来。

最终效果

界面效果大部分是仿照多说来的,但是具体CSS和JS都是我自己完全重写的,目前支持QQ和微博登录,也可以以游客身份评论,大家要体验效果的可以到这个专门的评论测试页面尽情灌水(这里的评论我不会删除),效果截图如下:

过程

下面开始记流水账了。

一开始一直觉得,不就是个评论功能嘛,添加评论、删除评论、查询评论列表,连修改功能都不需要做,顶多一张评论表一张用户表,多简单啊,但是慢慢做着做着就感觉牵一发而动全身,有强迫症的我做了这个又想做那个,到处都不想将就,最后一拖就拖了好几个月了,再加上最近正好准备换域名,也是个大改动,具体哪个先上线也是纠结。

评论表的设计

既然是做评论功能,我想着也要做一个无限楼中楼的功能,是像百度贴吧那样的楼中楼呢,还是像网易跟帖那样的无限引用?我采用了前者,那楼中楼需不需要翻页?三级评论、四级评论等深层评论怎样一次性查出来?看了网上一些网友的实现,有的是直接把某篇文章的所有评论一次性全部查出来,然后再在前端根据parentId做解析。虽然说我这个个人博客评论也不可能很多,但有代码洁癖的我肯定不允许这种方案存在,最后我想了一个折中方案,一级评论(也就是顶级评论)分页,二级和二级以下评论不分页,毕竟楼中楼还是不会太多的,我通过增加一个rootId来实现:

评论表主要字段:

字段 含义
id 主键
type 评论类型,这个是为了将来能够扩展,比如博客评论、工具评论、留言板评论等
targetKey 对应的目标ID,如果是博客就是博客ID,如果是游戏就是游戏ID
parentId 父评论ID,如果为null说明是一级评论
rootId 根评论ID,如果是一级评论那么和父评论是一样的,否则不为null的话一定是二级、三级等评论
content 评论内容

所以,最后的方案是:先根据分页查询parentId=null的一级评论,然后再通过 rootId in (id1,id2,id3)的方式把这一页的所有子评论查询出来,然后一起返回给前端交由前端去做无限楼中楼的数据解析。

城市获取问题

然后就是根据IP获取城市的问题,希望直接知道评论者所在城市,本来是打算实时查询外部接口的,然后本地再弄一个ip-city的映射表,本地有就不从外部查了,但是一想到插入一条评论还得依赖外部接口,觉得不妥,然后就找了个离线IP数据库,弄了一个专门的根据IP获取城市的工具类。

用户表的设计

再就是用户的问题,我希望支持第三方登录,最起码支持QQ和微博,同时为了降低用户评论的门槛,也支持游客评论,但评论用户表和评论表我又希望外键关联,同时,我又希望我自己不需要登录,这就需要把现有的用户表和评论用户表打通,我希望我自己是管理员,可以随意查看任何人的评论,而普通用户呢则只能删除自己的评论,游客发表的评论则不能删除。同时,为了提醒方便,希望可以有提醒功能,最好可以邮件提醒,既然做提醒功能,又要做消息中心,消息的已读和未读处理,哎呀妈呀,这还有完没完!

支持第三方登录

光是这QQ和微博2大登录就够折腾的了,实名认证、创建应用、审核、代码对接,然后又因为我最近刚好要换域名,评论功能刚上线,换域名的话有需要重新申请应用申请新的appId,又得重新审核,尼玛!关于第三方登录的参见我单独写的一篇如何从零开始对接第三方登录(Java版):QQ登录和微博登录

换域名问题

换域名就更别说了,买域名、备案、刷脸、DNS解析、漫长的等待,旧域名的迁移、302重定向设置,nginx转发配置,等等。

点赞和踩

再就是点赞,既然是做点赞也要做踩的功能,做点赞肯定要有专门的点赞表来记录用户是否已经点赞,而且肯定可以取消点赞,同时为了带动用户点赞的积极性,允许游客点赞,但是同一个IP每天最多只能点赞1次!

添加评论

要防止XSS攻击的可能,后台需要对数据进行过滤HTML标签字符,同时因为数据库不支持utfbmb4,所以需要过滤掉包括emoji等在内的字符,还要兼容游客和已登录用户如何处理,同时评论不能太频繁,间隔必须大于多少秒,为了防止用户恶意灌水,同一IP一天最多评论多少次,等等。

删除评论

超级管理员可以删除所有评论,普通用户可以删除自己发表的评论,游客无法删除评论,删除评论麻烦的是如何删除子评论,比如我删除了一条二级评论,那么这条评论下的三级、四级等更多评论全部要删除,如何把这些评论的ID全部查出来呢,所以也是个麻烦事儿。

前端代码

本来可以直接借用多说的JS和CSS的,这样可以省很多事,但我开了一个头之后,中间想放弃又不甘心,用惯了vue发现再回过头来用jQuery时,感觉处理dom好麻烦啊,到处都要定义class添加事件,数据有变化时需要到处手动更新dom,但是又不想为了一个简单的评论把vue引进来,所以只能咬牙坚持下去了,最后代码写的很烂很烂,烂到自己都有点吐血。

表情

做评论肯定要有表情功能,第一期简单的把QQ的经典105个表情加上了,后面看能不能加上一些更多表情。

旧数据导入

旧数据虽然不多,但肯定是不能丢的,多说导出的评论数据只有评论内容、昵称、时间等主要信息,连头像都没有,所以旧数据导入时只能当做游客评论了。

旧代码改造

为了打通新的评论用户表,对以前旧的用户认证、保存token、判断是否是超管进行了改造,当然还有其它的地方,具体就不说了。

其它

其它还有很多细节需要考虑的,比如:插入删除动画、文字前后台过滤、超级管理员登录问题、超管和普通用户的删除按钮显示与否问题、跨域兼容、评论数据隐藏用户IP等敏感信息、代码移植到其它页面时样式的兼容问题、排序问题、分页问题、游客与登录按钮如何排版布局的问题……

结语

断断续续忙了一个多月,终于把这些功能都给上了,看起来是在自娱自乐,但总算兑现了自己的承诺。