導語
一直對小程序很感興趣,之前就准備做一款自己的小程序,無奈還需要購買雲服務器和部署后台,有點麻煩,自從知道有了雲開發這個東東,就一鼓作氣花了幾個周末的時間做了一款自己的博客小程序,如果你也想打造一款自己的博客,那你閱讀這篇文章就夠啦
效果展示
二,數據庫設計
數據庫主要就7張表,分別為:用戶表,分類表,文章表,文章內容表,評論表,點贊表,歷史瀏覽表
三,評論功能設計
以文章評論功能為例,我們來看看代碼以及小程序雲開發的整個流程
1.實現思路
一開始的實現思路是准備搞兩張表,一張評論主表,一張回復評論的子表,后來想着不用這么復雜,其實就用一張表也能實現評論及回復的功能。
2.代碼實現
發表評論有三種情況,第一種是評論文章,為一級評論,第二種是評論別人的評論,為二級評論,第三種是回復別人的評論,為三級評論
2.1 如何新增一條評論
結合上面圖片,我們再來看看代碼,就很清晰了
1 /** 2 * 發布評論 3 */ 4 submit() { 5 var comment = this.data.inputData 6 if (comment == '') { 7 wx.showToast({ 8 title: '請填寫評論', 9 icon: 'none' 10 }) 11 } else { 12 console.log("我的評論:" + this.data.inputData) 13 var type = this.data.type; 14 if (type == 1) { // 1是評論別人的評論》二級評論 15 this.replyComment(1) 16 } else if (type == 2) { 17 this.replyComment(2) // 2是回復別人的評論》三級評論 18 } else if (type == 3) { // 3是評論文章》一級評論 19 this.addComment(); 20 } 21 } 22 }, 23 /** 24 * 新增評論 25 */ 26 addComment() { 27 var _this = this; 28 var openid = wx.getStorageSync("openid") 29 wx.showLoading({ 30 title: '正在加載...', 31 }) 32 var create_date = util.formatTime(new Date()); 33 console.log("當前時間為:" + create_date); 34 var timestamp = Date.parse(new Date()); 35 timestamp = timestamp / 1000; 36 console.log("當前時間戳為:" + timestamp); 37 // 調用雲函數 38 wx.cloud.callFunction({ 39 name: 'addComment', 40 data: { 41 //_id: timestamp + _this.data.otherUserInfo._id, 42 id: _this.data.articleDetail._id, 43 _openid: openid, 44 avatarUrl: _this.data.userInfo.avatarUrl, 45 nickName: _this.data.userInfo.nickName, 46 comment: _this.data.inputData, 47 create_date: create_date, 48 flag: 0, 49 article_id: _this.data.articleDetail.article_id, 50 timestamp: timestamp, 51 childComment: [], 52 }, 53 success: res => { 54 // res.data 包含該記錄的數據 55 console.log("新增評論成功---") 56 wx.showToast({ 57 title: '評論提交成功', 58 }) 59 wx.navigateBack({ 60 delta: 1 61 }) 62 }, 63 fail: err => { 64 console.error('[雲函數]調用失敗', err) 65 }, 66 complete: res => { 67 wx.hideLoading() 68 } 69 }) 70 }, 71 /** 72 * 回復評論 73 */ 74 replyComment(commentType) { 75 var _this = this; 76 wx.showLoading({ 77 title: '正在加載...', 78 }) 79 var create_date = util.formatTime(new Date()); 80 console.log("當前時間為:" + create_date); 81 var timestamp = Date.parse(new Date()); 82 timestamp = timestamp / 1000; 83 wx.cloud.callFunction({ 84 name: 'replyComment', 85 data: { 86 id: _this.data.articleDetail._id, 87 _id: _this.data.otherUserInfo._id, 88 avatarUrl: _this.data.userInfo.avatarUrl, 89 nickName: _this.data.userInfo.nickName, 90 openId: _this.data.openid, 91 comment: _this.data.inputData, 92 createDate: create_date, 93 flag: commentType, 94 opposite_avatarUrl: _this.data.otherUserInfo.avatarUrl, 95 opposite_nickName: _this.data.otherUserInfo.nickName, 96 opposite_openId: _this.data.otherUserInfo._openid, 97 timestamp: timestamp, 98 }, 99 success: res => { 100 // res.data 包含該記錄的數據 101 console.log("回復評論成功---") 102 wx.showToast({ 103 title: '回復提交成功', 104 }) 105 wx.navigateBack({ 106 delta: 1 107 }) 108 }, 109 fail: err => { 110 console.error('[雲函數]調用失敗', err) 111 }, 112 complete: res => { 113 wx.hideLoading() 114 } 115 }) 116 },
下面是新增評論和回復評論的兩個雲函數,主要用到了async和await這兩個函數,讓新增和回復函數執行完后我們再更新一下article文章表的評論字段,讓其加1,async和await的好處就是可以讓函數有序的進行,這里就不多說了
1 // 新增評論雲函數 2 const cloud = require('wx-server-sdk') 3 var env = 'hsf-blog-product-xxxxx'; // 正式環境 4 // var env = 'xxxxxxxxxxxxx'; // 測試環境 5 cloud.init({ 6 env: env 7 }) 8 const db = cloud.database() 9 const _ = db.command 10 exports.main = async(event, context) => { 11 try { 12 let res = await db.collection('comment').add({ 13 data: { 14 _openid: event._openid, 15 avatarUrl: event.avatarUrl, 16 nickName: event.nickName, 17 comment: event.comment, 18 create_date: event.create_date, 19 flag: event.flag, 20 article_id: event.article_id, 21 timestamp: event.timestamp, 22 childComment: [], 23 } 24 }).then(res => { 25 return res; 26 }) 27 await db.collection('article').doc(event.id).update({ 28 data: { 29 comment_count: _.inc(1) 30 } 31 }) 32 return res; 33 } catch (e) { 34 console.error(e) 35 } 36 }
1 // 回復評論雲函數 2 const cloud = require('wx-server-sdk') 3 var env = 'hsf-blog-product-xxxxx'; // 正式環境 4 // var env = 'xxxxxxxxxxxxxx'; // 測試環境 5 cloud.init({ 6 env: env 7 }) 8 const db = cloud.database() 9 const _ = db.command 10 exports.main = async(event, context) => { 11 try { 12 let res = await db.collection('comment').doc(event._id).update({ 13 data: { 14 childComment: _.push({ 15 avatarUrl: event.avatarUrl, 16 nickName: event.nickName, 17 openId: event.openId, 18 comment: event.comment, 19 createDate: event.createDate, 20 flag: event.flag, 21 opposite_avatarUrl: event.opposite_avatarUrl, 22 opposite_nickName: event.opposite_nickName, 23 opposite_openId: event.opposite_openId, 24 timestamp: event.timestamp, 25 }) 26 } 27 }).then(res => { 28 return res; 29 }) 30 await db.collection('article').doc(event.id).update({ 31 data: { 32 comment_count: _.inc(1) 33 } 34 }) 35 return res; 36 } catch (e) { 37 console.error(e) 38 } 39 }
2.2 如何顯示每一條評論
從數據庫取出評論的數據,循環遍歷每一條父評論,如果有子回復也一並循環。這里每一條評論的唯一標識是用戶的openId,那么我們可以用這個做一些事情,如:可以判斷如果是自己的評論是不能回復的。
1 <view class="comment" wx:if="{{commentList.length>0}}"> 2 <view class="comment-line"> 3 <text class="comment-text">評論交流</text> 4 <view class="bottom-line"></view> 5 </view> 6 <block wx:for='{{commentList}}' wx:key='*this' wx:for-item="itemfather"> 7 <view class='commentList'> 8 <view class="top-info"> 9 <view class='img-name'> 10 <image src="{{itemfather.avatarUrl}}"></image> 11 <label>{{itemfather.nickName}}</label> 12 </view> 13 </view> 14 <view class="father-content"> 15 <text class="text">{{itemfather.comment}}</text> 16 <view class="father-reply-time"> 17 <text class="create-time">{{itemfather.create_date}}</text> 18 <text class="reply" data-item="{{itemfather}}" bindtap='clickFatherConter' wx:if="{{openid != itemfather._openid}}">回復</text> 19 </view> 20 </view> 21 <view class="children-content"> 22 <block wx:for='{{itemfather.childComment}}' wx:key='*this'> 23 <view class='childComment'> 24 <view class="child-img-name"> 25 <view class="avatar-name"> 26 <image src="{{item.avatarUrl}}"></image> 27 <text class='nickName'>{{item.nickName}}</text> 28 </view> 29 </view> 30 <view class="child-comment" wx:if="{{item.flag==2 }}"> 31 <text class='huifu'>回復</text> 32 <text class='opposite-nickName'>{{item.opposite_nickName}}</text> 33 <text class='comment-text'>{{item.comment}}</text> 34 </view> 35 <view class="child-comment" wx:if="{{item.flag==1}}"> 36 <text class='comment-text'>{{item.comment}}</text> 37 </view> 38 <view class="child-reply-time"> 39 <text class="child-create-time">{{item.createDate}}</text> 40 <text class="reply" data-item="{{item}}" data-id="{{itemfather._id}}" bindtap='clickChildrenConter' wx:if="{{openid != item.openId}}">回復</text> 41 </view> 42 </view> 43 </block> 44 </view> 45 </view> 46 </block> 47 </view>
四,項目運行
1. 下載源碼
在github上將代碼下載到本地https://github.com/husanfeng/hsf_blog.git
2. 環境准備
1.下載小程序開發工具
2.注冊appid
3.使用小程序開發工具導入下載的代碼,填入自己注冊的AppID
3. 雲開發准備
1.開通雲開發功能
2.創建測試環境和生產環境
4. 修改環境ID
1.修改app.js中的環境ID為自己的環境ID
2.修改所有雲函數中的環境ID為自己的環境ID (這一步不用操作了)
5. 雲函數部署
1.右鍵雲函數目錄,點擊在終端中打開,執行npm install wx-server-sdk@1.8.2,
2.右鍵執行上傳並部署:所有文件
6. 構建npm
1.進到項目根目錄,執行npm install
2.勾選使用npm模塊
2.點擊頂部工具欄,執行構建npm
7. 創建數據庫集合
五,發布注意事項
小程序現在審核也是越來越嚴謹了,為了不讓大家在審核道路上走彎路,我把我的一些經驗分享給大家