unicloud云开发进阶40-项目24点赞的逻辑分析及点赞表的创建

148 阅读2分钟

点赞自增1

使数据库里的like_count字段+1 点过赞之后再次进入页面应该是高亮状态,就得需要一张表来记录谁点过赞、点的哪一篇文章的赞,哪个用户点的

创建表

记录谁点过赞就需要用户id,点的哪一篇文章的赞需要文章ID,点赞时间(需要根据时间来显示最后点赞用户的头像)

右键database,创建DB Schema quanzi_like.schema.json 在模板中找评论表,评论表的逻辑和点赞表几乎相同,就用这张表来改

image.png

改表

required部分只留下面这两个字段

"article_id",
"user_id"

在article_id这里是关联quanzi_article._id

增加一个点赞时间字段

这张表改成这样 然后在编辑器中点击上传这张表

{
  "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_article._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"
}

追加数据

在详情页中写事件 之前给按钮写了样式,但没有使用,给点赞按钮加上active,样式就生效了

css样式

// 默认灰色,点赞后背景变成蓝色
&.active{
    background: #0199FE;
}

image.png

给按钮写点击事件,点击按钮记录文章

      // 点击点赞按钮,数量加+1
      clickLike(){
        db.collection("quanzi_like").add({
          article_id:this.artId
        })
      },

image.png

现在有一个问题,再点一次,在数据库中又多增加一条数据,所以点赞之前要查询用户是否进行过点赞,用户再次点击

查询文章id是否等于这里的文章id

      // 点击点赞按钮,数量加+1
      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){
          
        }else{
          // 新增
          db.collection("quanzi_like").add({
            article_id:this.artId
          })
        }
        
      },

取消点赞

// 用户取消点赞则删除数据库的点赞记录
db.collection("quanzi_like").where(`article_id=="${this.artId}" && user_id==$cloudEnv_uid`).remove()

现在全部的代码

<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()
        }else{
          // 向数据库新增点赞记录
          // 把当前文章ID保存到数据库的文章ID字段
          db.collection("quanzi_like").add({
            article_id:this.artId
          })
        }
        
      },
      // 修改阅读量方法
      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").getTemp();
        let userTemp =  db.collection("uni-id-users").field("_id,username,nickname,avatar_file").getTemp();
        db.collection(artTemp,userTemp).where(`_id=="${this.artId}"`).get(
        {
          getOne:true
        }).then(res=>{
          // 如果data参数不存在吗,表示传递的参数id有误
          if(!res.result.data){
            this.errFun();
            return;
          }
          // 网络数据获取完成后将骨架屏状态重置为false
          this.loadState = false;
          // 把获取到的用户信息赋值
          this.detailObj = res.result.data
        }).catch(err=>{
          this.errFun();
        })
      }
    }
  }
</script>

用户进入自己点过赞的文章按钮高亮

这个功能要关联用户点赞quanzi_like表,之前是quanzi_article和uni-id-users表关联,所以现在是三张表关联

现在是主表quanzi_article通过uni-id-users._id关联副表quanzi_article,

以后可能会在文章表quanzi_article中增加权限,就又要关联roles表,这张表是用户权限的表,例如超级管理员、管理员、站长、用户等的信息

所以在这个项目中,文章表是最核心的表

image.png

现在文章表没有关联点赞表,但是点赞表关联了文章表的ID

先改之前写的getData方法,之前是先获取数据,再在where里过滤的

// 获取网络数据
getData(){
    // 将主表副表都查出一个临时表来
    let artTemp = db.collection("quanzi_article").getTemp();
    let userTemp =  db.collection("uni-id-users").field("_id,username,nickname,avatar_file").getTemp();

    db.collection(artTemp,userTemp).where(`_id=="${this.artId}"`).get(
...
)

改成先用where过滤再获取数据库

// 获取网络数据
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();
    db.collection(artTemp,userTemp).get(
    ...
    )

接下来再将点赞表与主表关联

      // 获取网络数据
      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").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;
          // 把获取到的用户信息赋值
          this.detailObj = res.result.data
        }).catch(err=>{
          this.errFun();
        })
      }

点赞表的数据就在_id属性里,quanzi_like就是点赞表,id在value中 image.png

image.png 现在quanzi_like这张表里只有一条数据,所以拿过来的数组里只有一个值 image.png