我们先看看界面:
我们如果要实现评论功能, 先看一下总的数据结构:
那么需要什么参数呢?
参数如下
comment: 评论内容
username: 用户名
time: 评论时间
userId: 用户id
id: 评论的贴子id
avatar: 用户头像
先上代码, wxml:
<!--pages/itemDetail/itemDetail.wxml-->
<view class='flexDownC content'>
<view class='content flexDownC w100'>
<view class='userInfo flexRowL w100'>
<view class='user flexC '>
<image src='{{data.userImg || defaultImg}}' class='userImg'></image> {{data.username || '糗皮虎'}}</view>
</view>
<view class='txt'>{{data.content}}</view>
<view class='img w100' wx:for="{{data.image}}" wx:for-item='imgItem'>
<image lazy-load="{{lazy_load}}" mode='widthFix' src='{{(imgItem) || ""}}' class='{{data.image.length ==1 ?"dzImg1": data.image.length == 2 ?"dzimg2": data.image.length == 3 ? "dzImg3" : data.image.length == 4 ? "dzImg4": "" }} dzImg'></image>
</view>
<view class='btnsRow flexRowL'>
<view class='ml20 flexC' bindtap='zan' data-id='{{data.id}}' data-vote='{{data.vote}}'>
<image src='{{!voteFlag ? shareIconUrl: shareIconUrl1}}' class='btns ml20'></image>
<text class='ml10'> {{data.vote || 0}}</text>
</view>
<view class='ml60 flexC'>
<image src='../../images/comment.png' class='btns ml40'></image>
<text class='ml10'> {{data.commentNum || 0}}</text>
</view>
<view class='ml60 flexC'>
<label class='flexC' data-qiuId='{{data.id}}'>
<image src='../../images/share.png' class='btns ml40'></image>
<button open-type='share' hidden='hidden' data-qiuId='{{data.id}}' data-shareNum='{{data.shareNum}}'></button>
</label>
<text class='ml10'> {{data.shareNum || 0}}</text>
</view>
</view>
</view>
<view class='garyLine'></view>
<view class='comments flexDownC'>
<view wx:if='{{data.comment.length > 0}}' class='com'>
<view wx:for='{{data.comment}}' wx:key="{{index}}" class='comItem flexDownC'>
<view class='userInfo flexRowL'>
<view class='user flexC'>
<image src='{{item.avatar || defaultImg}}' class='userImg'></image> {{item.username || '糗皮虎'}}</view>
</view>
<view class='txt'>{{item.comment}}</view>
<view class='time textalignRight'>{{item.time}}</view>
</view>
</view>
<view wx:else class='noComment'>
暂无评论...
</view>
</view>
</view>
<view class='flexC w100' wx:if='{{isShareTip}}'>
<button bindtap='navBack' class='navBtn'>回到首页</button>
</view>
<view class='bottomInput flexC' >
<input class='inputB' placeholder='友善发言的人运气不会太差' placeholder-style='color:#ccc' maxlength='120' value='{{commentTxt}}' confirm-type='send' bindinput='inputHandler' bindconfirm='confirm'></input>
</view>
wxss: 引入首页样式,减少代码量
/* pages/itemDetail/itemDetail.wxss */
@import '../index/index.wxss';
.content{
align-items: flex-start;
}
.noComment{
font-size: 28rpx;
margin-top: 30rpx;
color: #ccc;
}
.comItem, .comments, .com{
width: 100%;
}
.userImg{
margin-right: 10rpx;
}
.comItem{
padding:10rpx 20rpx;
margin-top: 30rpx;
margin-bottom: 20rpx;
border-bottom: 1px solid #f7f7f7;
}
.navBtn{
width: 80%;
height: 80rpx;
color: #fff;
background: #ea9518;
line-height: 80rpx;
margin-top: 60rpx;
}
.comItem:last-child{
border: none
}
.time{
width: 100%;
font-size: 24rpx;
color: #ccc;
margin-right: 50rpx;
}
.bottomInput{
width: 100%;
height: 100rpx;
}
.inputB{
width: 95%;
height: 80rpx;
line-height: 80rpx;
border: 1px solid #f4f4f4;
border-radius: 10rpx;
background: #f9f9f9;
}
js:
// pages/itemDetail/itemDetail.js
const db = wx.cloud.database()
const _ = db.command
var app = getApp()
const util = require('../../util/util.js');
Page({
/**
* 页面的初始数据
*/
data: {
defaultImg: '../../images/tx.png',
data: {},
shareIconUrl: '../../images/zan.png',
shareIconUrl1: '../../images/zan1.png',
commentTxt: '',
itemId: '',
comments: [],
isShareTip: false,
voteFlag: false
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
if (options.isShareTip){
this.setData({
isShareTip: true
})
}
if (options.id){
this.setData({
itemId: options.id
})
console.log(options.id)
this.search(options.id)
}
},
search: function(id){
let idNum = 0;
if (Number(id) || Number(id) == 0)
idNum = Number(id)
else
idNum = this.data.itemId;
db.collection('funnys').where({
id: _.eq(idNum)
}).get({
success: res => {
console.log(res)
let D = res.data;
this.setData({
data: D[0]
})
},
fail: function (e) {
console.log(e)
}
})
},
inputHandler: function(e){
console.log(e)
this.setData({
commentTxt: e.detail.value
})
},
confirm: function(){
const db = wx.cloud.database()
const _ = db.command
let userOpenId = wx.getStorageSync('openId')
//发送评论
let d = new Date(),data = {};
let arr = util.typeC(this.data.data.comment) == 'array' ? this.data.data.comment : new Array(this.data.data.comment);
if (this.data.commentTxt){
data = {
comment: this.data.commentTxt,
username: wx.getStorageSync('username'),
time: d.getFullYear() + '-' + (d.getMonth() + 1) + '-' + d.getDate(),
userId: wx.getStorageSync('userId'),
id: this.data.itemId,
avatar: wx.getStorageSync('avatar')
}
arr.push(data)
}else
wx.showToast({
title: '请填写内容',
icon:'none'
})
if (!userOpenId){
wx.showToast({
title: '您还未登录,请先登录',
icon: 'none'
})
setTimeout(()=>{
wx.switchTab({
url: '../me/me',
})
}, 1000)
}else{
var cn = this.data.data.comment.length + 1;
db.collection('comments').add({
data: {
id: data.userId,
userId: data.userId,
text: data.comment,
_openid: userOpenId
},
success: res=>{
console.log('comment新增成功')
},
fail: e=>{
console.log('comment新增失败')
}
})
wx.cloud.callFunction({
name: 'comment',
data: {
comment: arr,
id: this.data.itemId,
commentNum: cn
},
success: res => {
wx.showToast({
title: '评论成功',
})
this.search()
},
fail: err => {
wx.showToast({
icon: 'none',
title: '评论失败',
})
console.error('[云函数] [comment] 调用失败:', err)
}
})
}
console.log(data)
},
navBack: function(){
wx.switchTab({
url: '../index/index',
})
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function (res) {
console.log(res)
var that = this;
if (res.from === "button") {
wx.cloud.callFunction({
name: 'shareHandler',
data: {
id: res.target.dataset.qiuid,
shareNum: Number(res.target.dataset.sharenum) + 1
},
success: e => {
wx.showToast({
title: '分享成功',
})
that.search(that.data.pageId)
console.log(e)
},
fail: e => {
console.log(e)
}
})
return {
title: "我发现了一个好笑的东西,分享给你 --糗皮虎",
path: '/pages/itemDetail/itemDetail?id=' + res.target.dataset.qiuid + '&isShareTip=1',
imageUrl: ''
}
}
},
zan: function (e) {
if (!this.data.voteFlag){
var id = Number(e.currentTarget.dataset.id),
vote = Number(e.currentTarget.dataset.vote)
;
var that = this,
D = this.data.data;
D.vote = vote + 1
wx.cloud.callFunction({
name: 'zan',
data: {
data: {
vote: vote + 1,
id: id,
}
},
success: res => {
wx.showToast({
title: '点赞成功',
})
that.setData({
data: D,
voteFlag: true
})
},
fail: err => {
wx.showToast({
icon: 'none',
title: '点赞失败',
})
console.error('[云函数] [zan] 调用失败:', err)
}
})
}else{
wx.showToast({
title: '你已经投过票了',
icon: 'none'
})
}
},
})
我们仔细看看onload函数:
我们判断路径中是否有参数isShareTip, 有代表是通过分享出去的链接点击进来的, 那么我们就必须给他一个回到首页的按钮;
然后判断是否有id, 如果有,就进行数据库搜索,展示该条贴子;
没有就不搜索。
我们把search封装成一个函数,适合调用。
我们看看评论功能:
confirm: function(){
const db = wx.cloud.database()
const _ = db.command
let userOpenId = wx.getStorageSync('openId')
//发送评论
let d = new Date(),data = {};
let arr = util.typeC(this.data.data.comment) == 'array' ? this.data.data.comment : new Array(this.data.data.comment);
if (this.data.commentTxt){
data = {
comment: this.data.commentTxt,
username: wx.getStorageSync('username'),
time: d.getFullYear() + '-' + (d.getMonth() + 1) + '-' + d.getDate(),
userId: wx.getStorageSync('userId'),
id: this.data.itemId,
avatar: wx.getStorageSync('avatar')
}
//把评论的信息组成一个数组,通过云函数的update函数更新
arr.push(data)
}else
wx.showToast({
title: '请填写内容',
icon:'none'
})
if (!userOpenId){
wx.showToast({
title: '您还未登录,请先登录',
icon: 'none'
})
setTimeout(()=>{
wx.switchTab({
url: '../me/me',
})
}, 1000)
}else{
var cn = this.data.data.comment.length + 1;
db.collection('comments').add({
data: {
id: data.userId,
userId: data.userId,
text: data.comment,
_openid: userOpenId
},
success: res=>{
console.log('comment新增成功')
},
fail: e=>{
console.log('comment新增失败')
}
})
wx.cloud.callFunction({
name: 'comment',
data: {
comment: arr,
id: this.data.itemId,
commentNum: cn
},
success: res => {
wx.showToast({
title: '评论成功',
})
this.search()
},
fail: err => {
wx.showToast({
icon: 'none',
title: '评论失败',
})
console.error('[云函数] [comment] 调用失败:', err)
}
})
}
console.log(data)
},
云函数:
// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init()
const db = cloud.database()
// 云函数入口函数
exports.main = async (event, context) => {
var comment = event.comment, id = event.id,
commentNum = event.commentNum;
console.log('云函数comment成功', comment, id)
// console.warn(data)
try {
return await db.collection('funnys').where({
id: Number(id)
}).update({
data: {
comment: comment,
commentNum: commentNum
},
success: res => {
console.log('云函数comment成功', comment, id)
},
fail: e => {
console.error(e)
}
})
} catch (e) {
console.error(e)
}
}
现在, 审核功能就完成了。
小程序云开发教程一: 新建一个云开发项目以及基本布局
小程序云开发教程二:数据的获取(爬虫)
小程序云开发教程三: 数据的布局以及展示
小程序云开发教程四:云函数的使用与点赞功能的实现
小程序云开发教程五: 图片上传及发表文字的实现
小程序云开发教程六:贴子的审核
那么,到此为止,点赞功能就基本完成了, 详细代码请看:
https://github.com/LWJcoder/qiupihu
大家看在我码字那么辛苦的份上,顺手给github点一个小星星呗 ?
以上代码我会放在我的github上: LWJCoder