我正在参加「创意开发 投稿大赛」详情请看:掘金创意开发大赛来了!
前言
三月的时候,一位高中同学找到海轰,说可以帮忙写个留言小程序吗?说实话,这个留言板没有接触过,抱着试一试的心态,答应了同学。【其实心里还是没有底 毕竟没有做过 而且网课比较多】
2018年3月后申请的公众号是没有用户留言功能的,但是没有留言功能的公众号号感觉没有了灵魂。
如果想让之后的公众号拥有留言功能,其实也是有方法的。大体有两种:
- 迁移账号
- 小程序内嵌留言模块
想着自己有个小程序:***,反正也不咋用,不如添加一个留言板,这样同学还不用再申请账号,还省钱。【云开发免费版足够了】
成果展示
提出需求
- 用户可以对文章进行留言,发表观点
- 作者对留言进行审核:通过的留言,所有用户才可见
- 作者可以对留言进行回复
- 作者对所有留言进行管理,可以进行删除、审核等操作
开发过程分析
- 先做一个基础留言板,实现基本的留言功能即可,主要是验证是否可以上线,是否可以应用在公众号中(一次性做完所有功能,怕审核不过或公众号不支持,就太浪费时间了)
- 基础功能实现其验证其可以在公众号中使用,继续下一步开发,添加其余功能
- 功能大体开发完毕后,便可以进行真机测试了,检查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还是比较多,时间比较急,对于同学一个人使用应该是可以的。编程一共写了九小时,不是一天就写完了,哪有那么厉害。还不是一报错,就百度。修修补补,勉强才可以使用。【总的说来,简单功能可以实现,可以一旦用户过多,估计就凉凉了】
疑惑
开发过程中,我想实现一个点赞评论的功能:用户可以对评论点赞,一个用户只可以点赞一次,点赞后页面那个点赞按钮应该变成已经点赞后的状态。这个功能想了挺久,一直都没有思路。希望有知道的大佬可以指点指点,谢谢♪(・ω・)ノ
我正在参加「创意开发 投稿大赛」详情请看:掘金创意开发大赛来了!