筛选
对点赞表获取的数据进行筛选,要获取的是对文章进行过点赞的用户数据
let likeTemp = db.collection("quanzi_like").where(`article_id=="${this.artId}" && user_id==$cloudEnv_uid`).getTemp();
现在三张表的关联和过滤情况
// 获取网络数据
getData(){
// 将主表副表都查出一个临时表来
let artTemp = db.collection("quanzi_article").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").where(`article_id=="${this.artId}" && user_id==$cloudEnv_uid`).getTemp();
获取到数据后,可以根据quanzi_like的长度进行判断,如果是0就没有点过赞
把的判断结果赋值给数据库获取的数据,这样原本没有的数据就在返回值里了,这样通过对返回值进行判断,就能知道用户有没有点过赞
// 获取网络数据
getData(){
// 将主表副表都查出一个临时表来
let artTemp = db.collection("quanzi_article").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").where(`article_id=="${this.artId}" && user_id==$cloudEnv_uid`).getTemp();
// 两张副表单独与主表关联,副表之间没有关系
db.collection(artTemp,userTemp,likeTemp).get(
{
getOne:true
}).then(res=>{
console.log(res);
// 如果data参数不存在吗,表示传递的参数id有误
if(!res.result.data){
this.errFun();
return;
}
// 网络数据获取完成后将骨架屏状态重置为false
this.loadState = false;
// 是否点过赞
let isLike = res.result.data._id.quanzi_like.length ? true : false;
// 向返回值赋值 把是否点过赞赋给返回值
res.result.data.isLike = isLike;
// 把获取到的用户信息赋值
this.detailObj = res.result.data
}).catch(err=>{
this.errFun();
})
}
现在给点赞按钮双向绑定一个class,判断返回值里有没有isLike这个属性,有就是点过赞,就使按钮高亮显示,没有就不变色
<!-- 点赞部分 like -->
<view class="like">
<view class="btn" :class="detailObj.isLike ? 'active' : ''" @click="clickLike">
<text class="iconfont icon-good-fill"></text>
<!-- 点赞数不为0才显示数量,是0就只显示图标 -->
<text v-if="detailObj.like_count > 0">{{detailObj.like_count}}</text>
</view>
<view class="users">
<image src="../../static/images/user.jpg" mode="aspectFill"></image>
</view>
<view class="text"><text class="num">{{detailObj.view_count}}</text>人看过</view>
</view>
</view>
现在点过赞之后刷新页面,就高亮显示了
使文章表的点赞量进行自增
点赞使quanzi_article表的like_count字段自增,取消点赞使字段自减1
// 数据库有点赞记录就是1,没有是0
if(count.result.total){
// 用户取消点赞则删除数据库的点赞记录
db.collection("quanzi_like").where(`article_id=="${this.artId}" && user_id==$cloudEnv_uid`).remove();
// 调用云对象的operation方法,将文章表的点赞数自减1
utilsObj.operation("quanzi_article", "like_count", this.artId,-1)
}else{
// 向数据库新增点赞记录
// 把当前文章ID保存到数据库的文章ID字段
db.collection("quanzi_like").add({
article_id:this.artId
})
// 调用云对象的operation方法,将文章表的点赞数自增1
utilsObj.operation("quanzi_article", "like_count", this.artId,1)
}
详情页detail.vue的全部代码
<template>
<view class="detail">
<!-- 评论区以上的内容部分 container-->
<view class="container">
<!-- unicloud-db获取数据库数据 -->
<view v-if="loadState">
<u-skeleton
rows="5"
title
loading
></u-skeleton>
</view>
<view v-else>
<!-- 标题部分 -->
<view class="title">{{detailObj.title}}</view>
<!-- 标题下面的用户信息部分 userinfo -->
<view class="userinfo">
<view class="avatar">
<image :src="detailObj.user_id[0].avatar_file ? detailObj.user_id[0].avatar_file.url: '../../static/images/user-default.jpg'" mode="aspectFill"></image>
</view>
<view class="text">
<view class="name">{{detailObj.user_id[0].nickname? detailObj.user_id[0].nickname : detailObj.user_id[0].username}}</view>
<view class="small">
<uni-dateformat :date="detailObj.publish_date" format="yyyy年MM月dd hh:mm:ss"></uni-dateformat> · 发布于{{detailObj.province}}</view>
</view>
</view>
<!-- 内容部分 content -->
<view class="content">
<u-parse :content="detailObj.content" :tagStyle="tagStyle"></u-parse>
</view>
<!-- 点赞部分 like -->
<view class="like">
<view class="btn" :class="detailObj.isLike ? 'active' : ''" @click="clickLike">
<text class="iconfont icon-good-fill"></text>
<!-- 点赞数不为0才显示数量,是0就只显示图标 -->
<text v-if="detailObj.like_count > 0">{{detailObj.like_count}}</text>
</view>
<view class="users">
<image src="../../static/images/user.jpg" mode="aspectFill"></image>
</view>
<view class="text"><text class="num">{{detailObj.view_count}}</text>人看过</view>
</view>
</view>
</view>
</view>
</template>
<script>
const db=uniCloud.database();
// 引入自定义云对象 utilsObj
const utilsObj = uniCloud.importObject("utilsObj")
export default {
data() {
return {
artId:"",
// 骨架屏状态
loadState:true,
tagStyle:{
p:"line-height:1.7em;font-size:16px;padding-bottom:10rpx",
// 图像间隔,上下10,左右0
img:"margin:10px 0"
},
// 用户信息
detailObj:null
};
},
onLoad(e) {
// 判断有没有ID
if(!e.id){
this.errFun();
// 必须加return,否则后面的代码还会执行
return;
};
this.artId = e.id,
this.getData();
// 调用修改阅读量方法
this.readUpdate();
},
methods:{
// 点击点赞按钮,在数据库中增加一条点赞记录
// article_id=="${this.artId} 用户创文章ID等于数据库保存文章ID
// user_id==$cloudEnv_uid 数据库的id 等于 客户端上传的id 云端变量
async clickLike(){
let count = await db.collection("quanzi_like").where(`article_id=="${this.artId}" && user_id==$cloudEnv_uid`).count()
// count中有一个值total
// 数据库有点赞记录就是1,没有是0
if(count.result.total){
// 用户取消点赞则删除数据库的点赞记录
db.collection("quanzi_like").where(`article_id=="${this.artId}" && user_id==$cloudEnv_uid`).remove();
// 调用云对象的operation方法,将文章表的点赞数自减1
utilsObj.operation("quanzi_article", "like_count", this.artId,-1)
}else{
// 向数据库新增点赞记录
// 把当前文章ID保存到数据库的文章ID字段
db.collection("quanzi_like").add({
article_id:this.artId
})
// 调用云对象的operation方法,将文章表的点赞数自增1
utilsObj.operation("quanzi_article", "like_count", this.artId,1)
}
},
// 修改阅读量方法
readUpdate(){
// 每次自增1
utilsObj.operation("quanzi_article", "view_count", this.artId, 1).then(res=>{
console.log(res);
})
},
// 错误处理方法
errFun(){
uni.showToast({
title:"参数有误",
icon:"none"
})
setTimeout(()=>{
uni.reLaunch({
url:"/pages/index/index"
})
},1000)
},
// 获取网络数据
getData(){
// 将主表副表都查出一个临时表来
let artTemp = db.collection("quanzi_article").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").where(`article_id=="${this.artId}" && user_id==$cloudEnv_uid`).getTemp();
// 两张副表单独与主表关联,副表之间没有关系
db.collection(artTemp,userTemp,likeTemp).get(
{
getOne:true
}).then(res=>{
console.log(res);
// 如果data参数不存在吗,表示传递的参数id有误
if(!res.result.data){
this.errFun();
return;
}
// 网络数据获取完成后将骨架屏状态重置为false
this.loadState = false;
// 是否点过赞
let isLike = res.result.data._id.quanzi_like.length ? true : false;
// 向返回值赋值 把是否点过赞赋给返回值
res.result.data.isLike = isLike;
// 把获取到的用户信息赋值
this.detailObj = res.result.data
}).catch(err=>{
this.errFun();
})
}
}
}
</script>
<style lang="scss">
.detail{
// 给整个页面加背景色 是灰色
background: #f8f8f8;
// 给detail页面加高度,这是全屏高度
// 后面减去的部分值是标题栏的高度
// h5占了高度,但是微信小程序是不占的,这是为了适配
min-height: calc(100vh - var(--window-top));
.container{
// 内容部分的边距
padding:30rpx;
// 内容部分背景色白色
background: #fff;
.title{
font-size: 46rpx;
color:#333;
line-height: 1.4em;
font-weight: 600;
}
.userinfo{
padding:20rpx 0 50rpx;
display: flex;
align-items: center;
.avatar{
width: 60rpx;
height: 60rpx;
padding-right: 15rpx;
image{
width: 100%;
height: 100%;
border-radius: 50%;
}
}
.text{
font-size: 28rpx;
color:#555;
.small{
font-size: 20rpx;
color:#999;
}
}
}
// 富文本区域
.content{
}
// 点赞区域
.like{
display: flex;
flex-direction: column;
align-items: center;
padding:80rpx 50rpx 50rpx;
.btn{
width: 260rpx;
height: 120rpx;
background: #e4e4e4;
border-radius: 100rpx;
color:#fff;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
font-size: 28rpx;
.iconfont{
font-size: 50rpx;
}
// 默认灰色,点赞后背景变成蓝色
&.active{
background: #0199FE;
}
}
.text{
font-size: 26rpx;
color:#666;
.num{
color:#0199FE
}
.spot{
padding:0 10rpx;
}
}
.users{
display: flex;
justify-content: center;
padding:30rpx 0;
image{
width: 50rpx;
height: 50rpx;
border-radius: 50%;
border:3px solid #fff;
margin-left:-20rpx;
}
}
}
}
}
</style>