接着上一篇文章《手写一个Hexo评论系统(一)》,本篇文章主要是讲述记述评论系统实现的一些具体的设计方案与技术细节,方便之后修改或者重构。还有项目的部署问题,包括域名解析,Nginx配置代理,云服务器选购的一些问题,选购服务器的坑是真的大,因此仍是尽可能选择大厂,稳定一点,好用一点就不用在意多几那块钱嘛,并且根据本身的须要买配置仍是比较划算的。html
<!-- more -->前端
上次总共列出了以下的一些需求,根据这些需求来构想一下如何设计:ios
一、无需登陆和验证码,直接评论便可nginx
二、支持回复评论,且可无限递归回复git
三、支持评论点赞,按照点赞排序,相同则按照时间排序spring
三、支持文章评分,显示评分人数和评分的平均分数数据库
四、支持本身的评论被别人回复后能够邮件通知axios
五、支持评论后台管理系统,能够设置对应属性后端
六、支持评论导出,且高度100%可恢复数据api
初版得UI就长这样了,总体看起来风格比较简单,这也是我比较喜欢的风格。在文章加载后评论者会得到一个随机的昵称与头像,点击昵称能够切换昵称和头像,不过都是随机的而已。而后就是三个输入框,邮箱输入框、评论内容、文章评分。因此从总体上分红了两部分,一部分是用户信息和评论框,另外一部分是具体评论展现区域,只要思考清楚了那么就能够开始了。
反正是作PC的Web端UI嘛,直接上ElementUI了,其实还真的挺适合的,尤为是在展现具体评论的时候按照时间线来展现最合适不过了,并且评分组件也很OK,挺好看的,之后有时间再拿其余的组件库试试!
首先用户要一打开博客就能够得到随机头像和昵称,而且要保持这个用户的状态,因此总体思路以下:
首先对于一个从未打开过某篇博客的页面的用户来讲,在浏览器端存储的clientID确定是没有这个字段的,直接能够断定为新用户,因此去请求后台给一个ClientID,而且分配随机的昵称和头像,把这个用户信息给落库,即便用户点击了刷新昵称和头像,可是ClientID并无变,用户信息就这样得以保存了下来。若是浏览器已经存在了ClientID,那么数据库里面也应该有对应的用户信息,因此就直接请求后台拿到用户数据便可。
第二个问题,后端怎么知道哪些评论是哪些博客的呢?其实这里使用了一个比较简略的方式,那就是直接根据URL来判断,相同的URL确定是同一篇博客,可是这样作也是有缺陷的,就是在本地调试的时候是localhost:8080开头,可是远程是zouchanglin.cn,这样在本地的测试数据就不会展现在正式的博客评论上。并且zouchanglin.cn和zouchanglin.gitee.io的评论并不相通,其实这是不合理的,应该把域名和剩余部分URL分离出来,这样通用性才会更好,这一点之后有时间了我会进行重构。
第三个问题,用户设置了邮箱那么怎么才能回复的时候相互通知呢?其实对这样的Client端设计,只要在用户填写了邮箱后,进行评论或者回复的操做,均可以设置邮箱,由于这样能够从很大程度上减小业务复杂度,只要你的邮箱出现变动,你的下一次评论想到获得通知的时候确定会填写新的邮箱,这样就能够直接更新整个用户的邮箱,很是方便。
数据库使用MySQL 8.0。首先是设计客户端信息表,也就是表明了用户信息(主要包括了客户端ID、Email、昵称、建立时间、头像、客户端OS等信息,其余字段等有须要再添加就OK):
而后是文章信息表(主要字段是文章URL、文章评论数),一条数据对应着一条博客,其中还有博客的评论总计数目,其实彻底能够拿URL作主键,可是为了之后改动方便,目前仍是决定自定义生成主键比较好一些。
而后是评论表,在这里我把评论分红了两种类型,一种是文章评论(主要字段是文章ID、comment_parent是无效字段、评论客户端ID、评论内容、点赞数、建立时间、文章评分),也就是直接在文章下面的评论;另外一种是子评论(主要字段是所在的文章评论ID、评论客户端ID、评论内容、点赞数、回复的客户端ID、建立时间),这个就是文章评论的回复而已,固然不管是文章评论的子评论仍是子评论的回复评论都被看成子评论来存储,全部分了两张表。惟一不一样之处在于文章评论会存储本身是那一篇文章下的评论,而子评论会存储本身位于哪一条文章评论底下,并且会存储回复的Client是谁,因此还存储了reply_client这个字段。
点击此处直到后端代码仓库:https://gitee.com/zouchanglin/comment-box
后端系统仍是基于SpringBoot搭建的后端服务,其实用的都是比较常见的技术,SpringMVC、SpringDataJPA等,平时用的比较少的就是邮件发送服务,其实使用spring-boot-starter-mail来发送邮件简直不要太容易。须要注意的就是后端的跨域问题,须要配置一个容许跨域的配置类,可是后面部署的时候推荐使用Nginx同域部署,跨域问题也就不存在了,这是我目前最喜欢的方案。
仍是比较推荐腾讯云88/年,百度云太贵、阿里云用过了。腾讯云学生及仍是能够买一买的,1核2G的配置,其实彻底够用了。刚开始脑子抽搐了买个天翼云,虽然才77元/年,可是难用的要死,并且最高速度也就130K/s,这谁受得了这么慢的速度。仍是宁愿多花几块钱买个好一点的呀,毕竟大厂靠谱。千万别买天翼云呀,千万别买天翼云呀,千万别买天翼云呀,重要的事情说三遍。
整个代码其实都已经写好了,就剩一个部署了,可是因为个人网站全是HTTPS的,因此评论系统也必须是HTTPS的,不然因为浏览器的安全策略会致使评论模块没法加载。因而乎经过域名解析了一个二级域名comment.zouchanglin.cn到服务器上,为这个二级域名申请一个证书,这样就彻底OK了。
前端项目打包后直接使用Nginx部署一下,顺便把HTTPS证书配置一下,这样前端项目就能够HTTPS访问了,那么后端呢?不可能有https://comment.zouchanglin.cn:8080
这种URL存在吧,因此仍是经过Nginx很轻松的解决了这个问题,只要经过Nginx配置一个代理,100%搞定,并且完全、一劳永逸地解决了跨域问题,而且共享域名,还利用反向代理隐藏了后端地址,比较方便集中管理。
因此我我的仍是很是推荐采用Nginx将先后端同域部署的,Nginx真的帮了大忙!
后端项目application.yml配置以下,其实就是访问路径都变成了http://127.0.0.1:8080/api/....
server: port: 8080 servlet: context-path: /api
前端项目记得关闭History模式,而后请求的基础URL就写成了:
axios.defaults.baseURL = 'https://comment.zouchanglin.cn/api/'
Nginx的配置文件以下:
user root; worker_processes 2; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; gzip on; # HTTPS server server { listen 443 ssl; server_name comment.zpuchanglin.cn; # 配置证书 ssl_certificate /opt/ssl_file/cn_chain.crt; ssl_certificate_key /opt/ssl_file/cn_key.key; ssl_session_cache shared:SSL:1m; ssl_session_timeout 5m; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; location / { root /root/dist; try_files $uri $uri/ /index.html; } location ^~/api/ { proxy_pass http://127.0.0.1:8080; } } }
集思广益,你们也能够评论留言...
原文地址:《手写一个Hexo评论系统(二)》