(十)、通过云对象修改阅读量+点赞功能的实现【uniapp+uinicloud多用户社区博客实战项目(完整开发文档-从零到完整项目)】
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 = falsethis.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 反正为1let 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.isLikethis.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.isLikethis.likeTime = time;//调用点赞方法likeFun(this.artid);}
相关文章:
(十)、通过云对象修改阅读量+点赞功能的实现【uniapp+uinicloud多用户社区博客实战项目(完整开发文档-从零到完整项目)】
1,通过云对象importObj修改阅读量 1.1 新建云对象 1.2 云对象中写自增自减方法 封装云对象utilsObj中的自增自减方法,方法名取为operation,传递4个参数。 // 云对象教程: https://uniapp.dcloud.net.cn/uniCloud/cloud-obj // jsdoc语法提…...
刷力扣的第一天脑子要长出来的感觉(怎么有人大四才开始啊啊啊啊啊啊啊啊啊啊啊啊,又是等成绩的一天,)
刷力扣的第一天脑子要长出来的感觉(为什么大四才开始啊啊啊啊啊啊啊啊啊啊啊啊) emmm,自己还是想不太出来(只是一点想法),可能还是会参考评论区,求各位轻喷 分析:带符号一定不是回…...
Nuclei文*件上*传FUZZ POC
目录 1.前言 2. Nuclei文件上传FUZZ POC 3. 实战中的应用 1.前言 该文件上传FUZZ POC主要来源于一个靶*场,该POC 主要用来FUZZ目标js页面中的upload ajax请求,以此来进一步尝试文件上传漏*洞利*用。 这里也要感谢下“打工仔1号”提供的开*发人员常见的文*件上*传javaScr…...
完美解决方案-雪花算法ID到前端之后精度丢失问题
最近公司的一个项目组要把以前的单体应用进行为服务拆分,表的ID主键使用Mybatis plus默认 的雪花算法来生成。 快下班的时候,小伙伴跑过来找我,:“快给我看看这问题,卡这卡了小半天了!”。连拉带拽&#x…...
工程管理系统源码之高效的工程项目管理软件
高效的工程项目管理软件不仅能够提高效率还应可以帮你节省成本提升利润 在工程行业中,管理不畅以及不良的项目执行,往往会导致项目延期、成本上升、回款拖后,最终导致项目整体盈利下降。企企管理云业财一体化的项目管理系统,确保…...
390. 消除游戏
列表 arr 由在范围 [1, n] 中的所有整数组成,并按严格递增排序。请你对 arr 应用下述算法:从左到右,删除第一个数字,然后每隔一个数字删除一个,直到到达列表末尾。重复上面的步骤,但这次是从右到左。也就是…...
springBoot JPA代码生成器
介绍通过IDEA配置文件,根据数据库表结构快速生产Service、ServiceImpl、repository、repositoryImpl、自动生成常用的jpa增删改查等方法。使用的版本Spring Boot2.1.6.RELEASE spring-boot-starter-data-jpa使用idea 生成代码步骤打开idea(https://images.gitee.co…...
相同月利率条件下不同还款方式贷款的APR与IRR研究
文章目录前提假设一次性还本付息先息后本等额本息等额本金简单二分法求解IRR的程序汇总实验对比前提假设 因为常见的信贷产品还款期数定义都是按照月,假设只借一期的利率(月利率)为r,在此条件下,研究不同还款方式下的…...
【论文】智能隧道检测车的现状及改进策略
本文转载自《智慧城轨》2022年第11期 作者:黄丹樱1,韦强1,朱椰毅2,范骁1,林浩立1 单位:1 浙江师范大学工学院;2 浙江金温铁道开发有限公司 声明:本文仅用于学术分享,不做商业用途,如有侵权,联…...
【代码随想录二刷】Day16-二叉树-C++
代码随想录二刷Day16 每日任务 104.二叉树的最大深度 559.n叉树的最大深度 111.二叉树的最小深度 222.完全二叉树的节点个数 语言:C 104. 二叉树的最大深度 链接:https://leetcode.cn/problems/maximum-depth-of-binary-tree/ 递归法(前序…...
Lecture5 实现线性回归(Linear Regression with PyTorch)
目录 1 Pytorch实现线性回归 1.1 实现思路 1.2 完整代码 2 各部分代码逐行详解 2.1 准备数据集 2.2 设计模型 2.2.1 代码 2.2.2 代码逐行详解 2.2.3 疑难点解答 2.3 构建损失函数和优化器 2.4 训练周期 2.5 测试结果 3 线性回归中常用优化器 1 Pytorch实现线性回归…...
Python与Matlab svd分解的差异
1.差异说明 Matlab和Python的NumPy库中的SVD函数(np.linalg.svd)都是用来对矩阵进行奇异值分解(SVD)的函数,但它们在默认参数和返回结果方面有一些差异。 在Matlab中,SVD函数的默认行为是计算矩阵的完整SVD,即对于一…...
2023年光模块行业发展趋势及未来前景
随着数字化时代的到来,互联网行业的快速发展,网络通信设备行业的发展也在逐渐加速。光模块作为网络设备的重要组成部分,也在不断创新和发展。那么,光模块行业的未来发展趋势又是怎样的呢?接下来就跟着易天光通信&#…...
Sysmac Studio使用Tortoise和Git实现版本控制
Sysmac Studio使用Tortoise和Git实现版本控制实验时间:2022/11/16 实验软件:Sysmac Studio(1.52,需要软件授权支持版本控制)、Git(2.38.1)、Tortoise(2.13.0)、gitee(代码仓库) 实验目的:Sysmac Studio实现版本控制、多人同时开…...
Intent 和 Bundle 传值的区别
文章目录1、使用上1.1 Intent 方式1.2 Bundle 方式2、为什么 Bundle 使用 ArrayMap 而不是 Hashmap 实现呢?1、使用上 1.1 Intent 方式 举例:将数据从页面 A 传递到 B,然后再传递到 CA 页面: Intent intentnew Intent(MainActi…...
TypeScript 初步
一、TypeScript是什么? Typed JavaScript at Any Scale: 添加了类型系统的JavaScript,使用于任何规模的项目。 两个重要特点: 类型系统 任何规模 中文官网:文档简介 TypeScript中文网 TypeScript——JavaScript的超集 TypeS…...
leaflet 添加zoomslider,控制zoom放大缩小(074)
第074个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+leaflet中使用zoomslider,相比于普通的zoom控件,这个更加形象,更加具体些。 直接复制下面的 vue+leaflet源代码,操作2分钟即可运行实现效果 文章目录 示例效果配置方式示例源代码(共65行)相关API参考:专栏目…...
10分钟学会python对接【OpenAI API篇】
今天学习 OpenAI API,你将能够访问 OpenAI 的强大模型,例如用于自然语言的 GPT-3、用于将自然语言翻译为代码的 Codex 以及用于创建和编辑原始图像的 DALL-E。 首先获取生成 API 密钥 在我们开始使用 OpenAI API 之前,我们需要登录我们的 Op…...
2023美赛必须注意事项
文章目录首页部分要求竞赛期间题目查看题目下载论文要求比赛提示控制号提交解决方案更多注意事项首页部分要求 具体如下: 我提取一些关键词如下: 第一页:摘要页字体要求:12点的 Times New Roman 字体请勿在此页面或任何页面上…...
基于微信小程序的智能招聘小程序
文末联系获取源码 开发语言:Java 框架:ssm JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 5.7/8.0 数据库工具:Navicat11 开发软件:eclipse/myeclipse/idea Maven包:Maven3.3.9 浏览器…...
观成科技:隐蔽隧道工具Ligolo-ng加密流量分析
1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...
JavaSec-RCE
简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性,…...
在rocky linux 9.5上在线安装 docker
前面是指南,后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...
电脑插入多块移动硬盘后经常出现卡顿和蓝屏
当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时,可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案: 1. 检查电源供电问题 问题原因:多块移动硬盘同时运行可能导致USB接口供电不足&#x…...
SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...
JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...
React---day11
14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store: 我们在使用异步的时候理应是要使用中间件的,但是configureStore 已经自动集成了 redux-thunk,注意action里面要返回函数 import { configureS…...
