前言
三月的時候,一位高中同學找到海轟,說可以幫忙寫個留言小程序嗎?說實話,這個留言板沒有接觸過,抱着試一試的心態,答應了同學。【其實心裏還是沒有底 畢竟沒有做過 而且網課比較多】
2018年3月後申請的公衆號是沒有用戶留言功能的,但是沒有留言功能的公衆號號感覺沒有了靈魂。
如果想讓之後的公衆號擁有留言功能,其實也是有方法的。大體有兩種:
- 遷移賬號
- 小程序內嵌留言模塊
想着自己有個小程序:海轟Po,反正也不咋用,不如添加一個留言板,這樣同學還不用再申請賬號,還省錢。【雲開發免費版足夠了】
成果展示
提出需求
- 用戶可以對文章進行留言,發表觀點
- 作者對留言進行審覈:通過的留言,所有用戶纔可見
- 作者可以對留言進行回覆
- 作者對所有留言進行管理,可以進行刪除、審覈等操作
開發過程分析
- 先做一個基礎留言板,實現基本的留言功能即可,主要是驗證是否可以上線,是否可以應用在公衆號中(一次性做完所有功能,怕審覈不過或公衆號不支持,就太浪費時間了)
- 基礎功能實現其驗證其可以在公衆號中使用,繼續下一步開發,添加其餘功能
- 功能大體開發完畢後,便可以進行真機測試了,檢查bug。
留言板實現思路
鑑於留言板使用頻率較低和同一時刻使用人數較少,基礎的 雲開發 足以勝任。每一篇文章都有可能產生留言,用一條記錄表示;一篇文章產生的留言爲0條或者多條,用數組存儲。又一篇公衆號可能不會產生留言,如果作者創建一篇文章留言板系統就創建一天該文章的記錄,那麼一定會有很大的資源浪費,畢竟我們還是希望數據庫中存儲的東西需要存在一定的價值。爲此,這裏海轟給出的思路是,作者爲每一篇文章創建留言板時,只是提供小程序頁面啓動參數,數據庫中並不產生該文章記錄。只有當第一個用戶在該文章產生留言時,則在數據庫中添加該文章的記錄,而當第二個用戶(之後的所有用戶)產生留言時,就只需要在原記錄上面更新即可。
對於作者回復功能,這裏就需要多考慮一點:每個用戶都是使用同一個界面,但是我們只需要作者進行留言回覆,而普通用戶則不可以進行留言。所有,我們需要判斷點擊事件的發生者是否爲作者?這裏解決方法也很簡單:利用用戶的openid標記每一個用戶,而頁面的啓動參數中,我們只需要添加一項爲作者的openid,然後繼續比對即可。對於回覆,這裏可以簡單的理解爲對原留言記錄進行更新即可。同樣,這個原理也可以用於留言管理,使得管理員可以進行刪除等操作
留言審覈,這裏海轟的解決方法時,對每一條留言進行flag標記,比如flag=true時,表示審覈通過;flag=flase,表示不通過。顯示留言時,根據flag進行篩選即可
編程第一小時
- 探索公衆號與小程序如何連接
- 編寫初始版留言板
理清兩者如何聯繫?
微信公衆平臺中,文章中是可以插入小程序的,讀者通過點擊我們在文章中設置的文字或圖片,就可以進入小程序。而且我們還可以確定小程序頁面的啓動參數,便於實現不同文章進入小程序顯示不同的留言內容
基礎留言板功能開發
寫留言:獲取用戶輸入的值,添加新記錄或者更新新記錄即可。注意:雲開發中對記錄的更新只可以允許該記錄的上傳者進行修改,爲此我們必須借用雲函數。
// 上傳留言
hideModal_sure: function () {
var k = this
var content = k.data.content
var article_url = k.data.article_url
var flag = k.data.ishave //判斷是否含有該文章留言記錄
var year = new Date().getFullYear()//年
var month = new Date().getMonth() + 1//月
var day = new Date().getDate()//日
var hour = new Date().getHours()//小時
var minute = new Date().getMinutes()// 分鐘
var user_name = k.data.user_name
var user_image = k.data.user_image
var time = year + "年" + month + "月" + day + "日" + hour + "時" + minute + "分"
wx.showLoading({
title: '留言中...',
})
// 含有記錄 只需要添加即可
if (flag == true) {
console.log("已有記錄,需要添加")
// 調用雲函數 push新留言
console.log(article_url)
console.log(content)
wx.cloud.callFunction({
// 要調用的雲函數名稱
name: 'HHPro_functions',
// 傳遞給雲函數的event參數
data: {
function_name: "push_content",
id_url: article_url,
content_1: content,//用戶留言
user_name: user_name,//用戶暱稱
user_image: user_image,//用戶頭像
time: time// 留言時間
}
}).then(res => {
console.log("push 新記錄成功")
wx.hideLoading()
k.hideModal_cancel()
k.onLoad()
}).catch(err => {
console.error(err)
})
}
// 沒有記錄 新建記錄
else {
db.collection('liuyan').add({
// data 字段表示需新增的 JSON 數據
data: {
id_url: article_url,
liuyan_content: [
{
user_name: user_name,//用戶暱稱
user_image: user_image,//用戶頭像
time: time,//評論時間
content_1: content,//用戶評論
content_2: ""//作者評論
}
]
}
})
.then(res => {
//console.log(res)
console.log("原本無記錄,現已添加成功!")
wx.hideLoading()
k.hideModal_cancel()
k.onLoad()
})
.catch(console.error)
}
console.log("上傳留言內容爲:" + content)
},
雲函數
try {
return await db.collection('liuyan').where({
id_url: id_url
})
.update({
data: {
liuyan_content: _.push([
{
content_1: content_1,//用戶留言
content_2:"",// 作者留言,
user_name:user_name,//暱稱
user_image:user_image,//頭像
time:time,//時間
ispass:ispass//是否審覈
}
])
},
})
} catch (e) {
console.error(e)
}
測試
內嵌了基礎留言板的小程序"海轟Pro"通過審覈,經過公衆號文章測試,原理驗證成功。不過bug還是存在:由於ishava變量漏寫了一個,導致當第二個用戶留言時,系統會產生兩條記錄;"閱讀原文"不可以正確使用
編程第二~第七小時
- 添加作者審覈功能
- 添加作者回復功能
- 添加密令生成功能
- 添加留言管理功能
- 修復初始版bug
審覈模塊
// 審覈留言
check:function(e){
var k=this
wx.showModal({
title: '審覈',
content: '是否審覈通過這條留言?',
success(res) {
if (res.confirm) {
console.log('用戶點擊確定')
wx.showLoading({
title: '審覈中...',
})
console.log(e.currentTarget.dataset.id)// 該篇文章的第幾個留言
var id_url = k.data.id_url// 需要審覈記錄的id_url
var replys = k.data.replys//所有文章留言
setTimeout(function () {
var index_1 = k.data.index_1// 第幾篇文章
replys[index_1].liuyan_content[e.currentTarget.dataset.id].ispass = true
wx.cloud.callFunction({
// 要調用的雲函數名稱
name: 'HHPro_functions',
// 傳遞給雲函數的event參數
data: {
function_name: "reply",
id_url: id_url,// 記錄標識
all_content: replys[index_1].liuyan_content//更新後的留言
}
}).then(res => {
console.log("審覈通過")
wx.showToast({
title: '審覈通過^_^',
icon: "none"
})
k.setData({
value_x: "",
isreachbottom:false,
nums:0
})
wx.hideLoading()
k.onLoad()
}).catch(err => {
console.error(err)
wx.hideLoading()
wx.showToast({
title: '審覈失敗┭┮﹏┭┮',
icon: "none"
})
})
}, 1000)
} else if (res.cancel) {
console.log('用戶點擊取消')
}
}
})
}
回覆模塊
// 提交 作者回復
formSubmit:function(e){
var k=this
this.setData({
modalname: ""
})
wx.showLoading({
title: '回覆中...',
})
console.log("確定")
console.log(e.detail.value.reply)// 作者回復的內容
// 考慮回覆內容爲空的情況
if (e.detail.value.reply=="")
{
wx.showToast({
title: '回覆內容不可以爲空哦(⊙.⊙)!',
icon:"none"
})
}
// 回覆內容不爲空的情況
else
{
var content = e.detail.value.reply // 留言內容
var index = k.data.liuyan_index// 回覆第幾個留言
var article_url = k.data.article_url// 記錄標識
// 作者已經回覆
if (k.data.liuyan_content[index].content_2!="")
{
k.setData({
value_x:""
})
console.log("已經回覆了哦o(*^@^*)o")
wx.showToast({
title: '已經回覆了哦o(*^@^*)o',
icon:"none"
})
}
// 沒有回覆
else
{
k.data.liuyan_content[index].content_2 = content
wx.cloud.callFunction({
// 要調用的雲函數名稱
name: 'HHPro_functions',
// 傳遞給雲函數的event參數
data: {
function_name: "reply",
id_url: article_url,// 記錄標識
all_content: k.data.liuyan_content//更新後的留言
}
}).then(res => {
console.log("作者回覆成功")
wx.showToast({
title: '回覆成功^_^',
icon: "none"
})
k.setData({
value_x: ""
})
wx.hideLoading()
k.onLoad()
}).catch(err => {
console.error(err)
wx.hideLoading()
wx.showToast({
title: '回覆失敗┭┮﹏┭┮',
icon: "none"
})
})
}
},
密令生成
// 獲取密令
db.collection('images').where({
_id: '1583323590594_0.2267614604186734_33609397' // 填入當前用戶 openid
}).get().then(res => {
console.log(res.data[0].password)
k.setData({
password: res.data[0].password
})
})
// 調用獲取用戶openid的雲函數
wx.cloud.callFunction({
name: 'login',
data: {
}
}).then(res => {
console.log(res.result.openid)
wx.hideLoading()
k.setData({
user_openid: res.result.openid,
})
})
管理模塊(部分)
//刪除
delete:function(e){
var k = this
var replys = k.data.replys// 所有文章留言
wx.showModal({
title: '提示',
content: '是否刪除該留言?',
success(res) {
if (res.confirm) {
console.log('用戶點擊確定')
wx.showLoading({
title: '刪除中...',
})
setTimeout(function () {
var id_url = k.data.id_url// 需要修改文章的id_url
replys[k.data.index_1].liuyan_content.splice(e.target.dataset.id, 1)
console.log(id_url)
wx.cloud.callFunction({
// 要調用的雲函數名稱
name: 'HHPro_functions',
// 傳遞給雲函數的event參數
data: {
function_name: "reply",
id_url: id_url,// 記錄標識
all_content: replys[k.data.index_1].liuyan_content//更新後的留言
}
}).then(res => {
wx.hideLoading()
k.onLoad()
wx.showToast({
title: '刪除成功O(∩_∩)O',
icon: "none"
})
}).catch(err => {
console.error(err)
wx.hideLoading()
wx.showToast({
title: '刪除失敗┭┮﹏┭┮',
icon: "none"
})
})
}, 1000)
} else if (res.cancel) {
console.log('用戶點擊取消')
}
}
})
},
測試
內嵌第二個版本留言板的小程序一天就通過了審覈。可是… 小程序頁面啓動參數中的一個 ? 被我寫成了 & ,密令生成模塊作廢。好在可以在公衆號中修改一下就行了。之後用來快一個小時,測試了留言板所有功能,全部正確!!
編程第九小時
留言板功能基本實現,剩下的一點就是修復bug,對界面進行改進。這點工作很快就完成,上傳代碼,提交審覈!!幸運的是,一次就通過審覈了,開心!O(∩_∩)O哈哈~
總結
通過這次的留言板,自己也是學到了很多,特別是在一些細節處理上,原來做的是真的不行。由於本學期學習任務比較重,時間比較少,所以這次的功能做的就顯得有點粗糙。但是經過海轟的測試,基礎功能還是可以實現的,O(∩_∩)O哈哈~
目前bug還是比較多,時間比較急,對於同學一個人使用應該是可以的。編程一共寫了九小時,不是一天就寫完了,哪有那麼厲害。還不是一報錯,就百度。修修補補,勉強纔可以使用。【總的說來,簡單功能可以實現,可以一旦用戶過多,估計就涼涼了】
疑惑
開發過程中,我想實現一個點贊評論的功能:用戶可以對評論點贊,一個用戶只可以點贊一次,點贊後頁面那個點贊按鈕應該變成已經點贊後的狀態。這個功能想了挺久,一直都沒有思路。希望有知道的大佬可以指點指點,謝謝♪(・ω・)ノ