一直对小程序开发很感兴趣,之前就准备做一款属于自己的小程序,无奈还需要购买云服务器和部署后台,有点麻烦,自从知道有了云开发这个免去服务器搭建和运维的一站式后端云服务“神器”,就一鼓作气花了几个周末的时间做了一款自己的博客小程序,如果你也想打造一款自己的博客,那你阅读这篇文章就够啦。
▌博客小程序介绍
主要功能:
包括文章的发布及浏览、评论、点赞、浏览历史、分类、排行榜、分享、生成海报图等。
效果展示:
▌数据库设计
数据库主要就7张表,分别为:用户表,分类表,文章表,文章内容表,评论表,点赞表,历史浏览表。
▌评论功能设计
以文章评论功能为例,我们来看看代码以及小程序云开发的整个流程。
1. 实现思路
一开始的实现思路是准备搞两张表,一张评论主表,一张回复评论的子表,后来想着不用这么复杂,其实就用一张表也能实现评论及回复的功能。
2. 代码实现
发表评论有三种情况,第一种是评论文章,为一级评论,第二种是评论别人的评论,为二级评论,第三种是回复别人的评论,为三级评论。
2.1 如何新增一条评论
结合上面图片,我们再来看看代码,就很清晰了。
/** * 发布评论 */ submit() { var comment = this.data.inputData if (comment == '') { wx.showToast({ title: '请填写评论', icon: 'none' }) } else { console.log("我的评论:" + this.data.inputData) var type = this.data.type; if (type == 1) { // 1是评论别人的评论》二级评论 this.replyComment(1) } else if (type == 2) { this.replyComment(2) // 2是回复别人的评论》三级评论 } else if (type == 3) { // 3是评论文章》一级评论 this.addComment(); } } }, /** * 新增评论 */ addComment() { var _this = this; var openid = wx.getStorageSync("openid") wx.showLoading({ title: '正在加载...', }) var create_date = util.formatTime(new Date()); console.log("当前时间为:" + create_date); var timestamp = Date.parse(new Date()); timestamp = timestamp / 1000; console.log("当前时间戳为:" + timestamp); // 调用云函数 wx.cloud.callFunction({ name: 'addComment', data: { //_id: timestamp + _this.data.otherUserInfo._id, id: _this.data.articleDetail._id, _openid: openid, avatarUrl: _this.data.userInfo.avatarUrl, nickName: _this.data.userInfo.nickName, comment: _this.data.inputData, create_date: create_date, flag: 0, article_id: _this.data.articleDetail.article_id, timestamp: timestamp, childComment: [], }, success: res => { // res.data 包含该记录的数据 console.log("新增评论成功---") wx.showToast({ title: '评论提交成功', }) wx.navigateBack({ delta: 1 }) }, fail: err => { console.error('[云函数]调用失败', err) }, complete: res => { wx.hideLoading() } }) }, /** * 回复评论 */ replyComment(commentType) { var _this = this; wx.showLoading({ title: '正在加载...', }) var create_date = util.formatTime(new Date()); console.log("当前时间为:" + create_date); var timestamp = Date.parse(new Date()); timestamp = timestamp / 1000; wx.cloud.callFunction({ name: 'replyComment', data: { id: _this.data.articleDetail._id, _id: _this.data.otherUserInfo._id, avatarUrl: _this.data.userInfo.avatarUrl, nickName: _this.data.userInfo.nickName, openId: _this.data.openid, comment: _this.data.inputData, createDate: create_date, flag: commentType, opposite_avatarUrl: _this.data.otherUserInfo.avatarUrl, opposite_nickName: _this.data.otherUserInfo.nickName, opposite_openId: _this.data.otherUserInfo._openid, timestamp: timestamp, }, success: res => { // res.data 包含该记录的数据 console.log("回复评论成功---") wx.showToast({ title: '回复提交成功', }) wx.navigateBack({ delta: 1 }) }, fail: err => { console.error('[云函数]调用失败', err) }, complete: res => { wx.hideLoading() } }) },下面是新增评论和回复评论的两个云函数,主要用到了async和await这两个函数,让新增和回复函数执行完后我们再更新一下article文章表的评论字段,让其加1,async和await的好处就是可以让函数有序的进行,这里就不赘述。
// 新增评论云函数 const cloud = require('wx-server-sdk') var env = 'hsf-blog-product-xxxxx'; // 正式环境 // var env = 'xxxxxxxxxxxxx'; // 测试环境 cloud.init({ env: env }) const db = cloud.database() const _ = db.command exports.main = async(event, context) => { try { let res = await db.collection('comment').add({ data: { _openid: event._openid, avatarUrl: event.avatarUrl, nickName: event.nickName, comment: event.comment, create_date: event.create_date, flag: event.flag, article_id: event.article_id, timestamp: event.timestamp, childComment: [], } }).then(res => { return res; }) await db.collection('article').doc(event.id).update({ data: { comment_count: _.inc(1) } }) return res; } catch (e) { console.error(e) } } // 回复评论云函数 const cloud = require('wx-server-sdk') var env = 'hsf-blog-product-xxxxx'; // 正式环境 // var env = 'xxxxxxxxxxxxxx'; // 测试环境 cloud.init({ env: env }) const db = cloud.database() const _ = db.command exports.main = async(event, context) => { try { let res = await db.collection('comment').doc(event._id).update({ data: { childComment: _.push({ avatarUrl: event.avatarUrl, nickName: event.nickName, openId: event.openId, comment: event.comment, createDate: event.createDate, flag: event.flag, opposite_avatarUrl: event.opposite_avatarUrl, opposite_nickName: event.opposite_nickName, opposite_openId: event.opposite_openId, timestamp: event.timestamp, }) } }).then(res => { return res; }) await db.collection('article').doc(event.id).update({ data: { comment_count: _.inc(1) } }) return res; } catch (e) { console.error(e) } }2.2 如何显示每一条评论