1,通过云对象importObj修改阅读量
1.1 新建云对象
1.2 云对象中写自增自减方法
封装云对象utilsObj中的自增自减方法,方法名取为operation,传递4个参数。
// 云对象教程: https://uniapp.dcloud.net.cn/uniCloud/cloud-obj
// jsdoc语法提示教程:https://ask.dcloud.net.cn/docs/#//ask.dcloud.net.cn/article/129
const db = uniCloud.database();
const dbCmd = db.command;
module.exports = {
_before: function() { // 通用预处理器
},
/**
* @param {Object} table 数据表
* @param {Object} attr 属性字段
* @param {Object} id
* @param {Object} num 1自增 -1自减
*/
async operation(table, attr, id, num) {
let obj = {}
obj[attr] = dbCmd.inc(num);
return await db.collection(table).doc(id).update(obj)
}
}
1.3 detail页面中引入云对象
在script中引入云对象
const utilsObj = uniCloud.importObject("utilsObj", {
customUI: true
});
methods中封装修改阅读量方法,调用云对象中的operation方法。
//修改阅读量
readUpdate() {
utilsObj.operation("quanzi_articles", "view_count", this.artid, 1).then(res => {
console.log(res);
})
},
onload中调用readupdate方法,测试一下:
后台显示更新一次成功。
2,点赞的功能实现
2.1 创建点赞表
创建点赞表的schema.json
quanzi_like.schema.json
{
"bsonType": "object",
"required": ["article_id", "user_id"],
"permission": {
"read": true,
"create": "auth.uid != null",
"update": "doc.user_id == auth.uid",
"delete": "doc.user_id == auth.uid"
},
"properties": {
"_id": {
"description": "存储文档 ID(文章 ID),系统自动生成"
},
"article_id": {
"bsonType": "string",
"description": "文章ID",
"foreignKey": "quanzi_articles._id"
},
"user_id": {
"bsonType": "string",
"description": "评论者ID,参考`uni-id-users` 表",
"forceDefaultValue": {
"$env": "uid"
},
"foreignKey": "uni-id-users._id"
},
"publish_date": {
"bsonType": "timestamp",
"title": "点赞时间",
"description": "点赞时间",
"defaultValue": {
"$env": "now"
}
},
"ip": {
"bsonType": "string",
"description": "评论发表时 IP 地址",
"forceDefaultValue": {
"$env": "clientIP"
}
}
},
"version": "0.0.1"
}
2.2 添加@clic点击事件
<!-- 点赞 -->
<view class="btn" @click="clickLike">
<text class="iconfont icon-good-fill"></text>
<text v-if="detailObj.like_count">{{detailObj.like_count}}</text>
</view>
点赞点击方法
//点击点赞方法
clickLike() {
db.collection('quanzi_like').add({
article_id: this.artid
}).then(res => {
console.log(res)
})
}
查看数据库中article_like中已经增加了一条记录
2.3 避免重复点赞的处理
修改clickLike方法:
首先查询点赞表中 当前登录用户和当前文章的记录数,如果已经当前用户已经点赞了当前文章,查询到的数量应该为1,否则为0;然后通过count进行判断,避免当前登录用户重复点赞当前文章。
//点击点赞方法
async clickLike() {
let count = await db.collection("quanzi_like").where(`article_id=="${this.artid}" && user_id==$cloudEnv_uid`)
.count()
console.log(count)
if (count.result.total) {
} else {
db.collection("quanzi_like").add({
article_id: this.artid
})
}
}
2.4 取消点赞操作
修改clickLike方法:
//点击点赞方法
async clickLike() {
// 查询数量
let count = await db.collection("quanzi_like").where(`article_id=="${this.artid}" && user_id==$cloudEnv_uid`)
.count()
console.log(count)
//total为1,点赞过 进行取消点赞操作 去数据库删除点赞记录
if (count.result.total) {
//删除点赞记录
db.collection("quanzi_like").where(`article_id=="${this.artid}" && user_id==$cloudEnv_uid`)
.remove();
} else { //total为0,没有点赞过,数据库新增点赞记录
//新增点赞记录
db.collection("quanzi_like").add({
article_id: this.artid
})
}
}
3,修改点赞样式
3.1 三表联查
三表对应关系
三表联查,修改detail.vue中的getdata方法
//联表查询获取数据
getData() {
let artTemp = db.collection('quanzi_articles').where(`_id =="${this.artid}"`).getTemp()
let userTemp = db.collection('uni-id-users').field("_id,username,nickname,avatar_file").getTemp()
let likeTemp = db.collection("quanzi_like").getTemp(); //.where(`article_id=="${this.artid}" && user_id==$cloudEnv_uid`)
db.collection(artTemp, userTemp, likeTemp).get({
getOne: true
}).then(res => {
console.log(res)
//如果文章id不存在
if (!res.result.data) {
this.errFun();
return;
}
this.loadState = false
this.detailObj = res.result.data
}).catch(err => {
this.errFun();
})
}
打印输出结果:
注:如果没有点赞记录,_id.quanzi_like数组长度为0 。
3.2 判断用户是否点赞
对点赞数据库的操作(quanzi_like)
添加过滤条件
let likeTemp = db.collection("quanzi_like").where(`article_id=="${this.artid}" && user_id==$cloudEnv_uid`)
.getTemp();
定义islike并且将自定义属性islike追加到对象detailObj中。
//是否点过赞 如果没有点赞记录,_id.quanzi_like数组长度为0 反正为1
let isLike = res.result.data._id.quanzi_like.length ? true : false;
res.result.data.isLike = isLike;
this.detailObj = res.result.data
3.3 对点赞数量进行增减
对文章数据库的操作(quanzi_articles)
修改clicklike方法:
//点击点赞方法
async clickLike() {
// 查询数量
let count = await db.collection("quanzi_like").where(`article_id=="${this.artid}" && user_id==$cloudEnv_uid`)
.count()
console.log(count)
//total为1,点赞过 进行取消点赞操作 去数据库删除点赞记录
if (count.result.total) {
//删除点赞记录
db.collection("quanzi_like").where(`article_id=="${this.artid}" && user_id==$cloudEnv_uid`)
.remove();
utilsObj.operation("quanzi_articles", "like_count", this.artid, -1)
} else { //total为0,没有点赞过,数据库新增点赞记录
//新增点赞记录
db.collection("quanzi_like").add({
article_id: this.artid
})
utilsObj.operation("quanzi_articles", "like_count", this.artid, 1)
}
}
3.4 对点赞优化无感操作
自动显示交互界面
取消自动展示的交互提示界面
const utilsObj = uniCloud.importObject("utilsObj",{
customUI: true // 取消自动展示的交互提示界面
});
点赞优化无感操作
对clicklike方法进行添加如下代码:
//点击点赞方法
async clickLike() {
this.detailObj.isLike ? this.detailObj.like_count-- : this.detailObj.like_count++;
this.detailObj.isLike = !this.detailObj.isLike
//省略其他
}
3.4 恶意盗刷点赞的处理
问题如下图:
解决方案:
限制两次点赞之间的时间不能小于1秒或者2秒。
//点击点赞方法
async clickLike() {
//限制两次点赞之间的时间不能小于2秒
let time = Date.now();
if (time - this.likeTime < 2000) {
uni.showToast({
title: "操作太频繁,请稍后...",
icon: "none"
})
return;
}
this.detailObj.isLike ? this.detailObj.like_count-- : this.detailObj.like_count++;
this.detailObj.isLike = !this.detailObj.isLike
this.likeTime = time;
//省略其他
}
动态设置当前页面的标题 参考链接
在getdata方法中,添加如下代码:
uni.setNavigationBarTitle({
title: this.detailObj.title
})
4,封装发送网络请求的点赞方法
4.1 公共工具类tools.js封装点赞方法
…utils/tools.js 方法名likeFun
//点赞操作数据库的方法
export async function likeFun(artid) {
let count = await db.collection("quanzi_like")
.where(`article_id=="${artid}" && user_id==$cloudEnv_uid`).count()
if (count.result.total) {
db.collection("quanzi_like").where(`article_id=="${artid}" && user_id==$cloudEnv_uid`)
.remove();
utilsObj.operation("quanzi_articles", "like_count", artid, -1)
} else {
db.collection("quanzi_like").add({
article_id: artid
})
utilsObj.operation("quanzi_articles", "like_count", artid, 1)
}
}
4.2 修改detail.vue中的点赞点击方法
首先页面中引入js
import {
likeFun
} from "../../utils/tools.js"
修改点赞clicklike方法:
//点击点赞方法
async clickLike() {
//限制两次点赞之间的时间不能小于2秒
let time = Date.now();
if (time - this.likeTime < 2000) {
uni.showToast({
title: "操作太频繁,请稍后...",
icon: "none"
})
return;
}
this.detailObj.isLike ? this.detailObj.like_count-- : this.detailObj.like_count++;
this.detailObj.isLike = !this.detailObj.isLike
this.likeTime = time;
//调用点赞方法
likeFun(this.artid);
}