全栈项目|小书架|服务器端-NodeJS+Koa2 实现点赞功能

效果图

接口分析

通过上面的效果图可以看出,点赞入口主要是在书籍的详情页面。
而书籍详情页面,有以下几个功能是和点赞有关的:

  • 获取点赞状态
  • 点赞
  • 取消点赞

所以项目中理论上与点赞相关的接口就以上三个。

点赞 model 的设计

既然明确了接口数量,那么下一步就是设计接口对应的model,通过model生成表格like,里面存放点赞数据。

那么需要存在哪些点赞数据呢?

这里简单分析后,记录一条点赞信息只需要保存以下的信息即可:

  • 点赞 id
  • 书籍 id
  • 用户 id
  • created_at
  • deleted_at
  • updated_at

因此最终在数据库表中生成的内容如下:

获取点赞状态

在书籍详情页面需要根据书籍的点赞状态显示不同的icon图标。

如何获取点赞状态呢?

只需要向like表中传递当前用户id书籍id进行搜索即可。有数据则证明该用户对书籍已经点赞了,没有数据则反之。

代码具体实现:

// 获取书籍的喜欢状态
    static async userLikeIt(uid, bid) {
        const like = await Like.findOne({
            where: {
                bkid: bid,
                uid: uid
            }
        })
        return like ? true : false
    }

通过以上代码的返回值,判断用户是否点赞,返回true则表示用户对该书籍已点赞,反之则未点赞。

点赞实现

获取到点赞状态之后,我们可以通过点击点赞 icon来实现点赞或者取消点赞功能。

点赞的实现,需要传递当前用户 id书籍 id,通过数据库查询是否有数据,有数据则将点赞结果保存到数据表中。并提示点赞成功,返回的数据格式如下:

{"msg":"ok","error_code":0,"request":"POST /v1/like"}

这里还做了一步额外的操作,因为用户的点赞是和书籍的点赞数量挂钩的。
也就是说用户点赞或者取消赞,书籍表中的书籍点赞数量也相应的会增加或者减少。

伪代码实现如下:

static async like(uid,bkid){
        const like = await Like.findOne({
            where: {
                uid: uid,
                bkid: bkid
            }
        })

        if (like) {
            throw new global.errs.NotFound("喜欢失败", NotFound.LIKE_FAIL)
        }
        return sequelize.transaction(async t => {
            await Like.create({
                uid,
                bkid
            }, {
                transaction: t
            })
            const book = await Book.detail(bkid)
            await book.increment('like_count', {
                by: 1,
                transaction: t
            })
        })
    }

上面代码使用到了数据库中的事务功能。具体的事务介绍可参考这篇文章 javaweb学习总结(三十八)——事务

书籍的点赞数量有可能因为多人同一时间下操作而导致数据的不正确性,使用事务可以避免出现这种问题。

取消点赞实现

取消点赞功能,其实可以使用点赞的接口,然后再接口中添加一个类别区分是点赞还是取消点赞,然后做相应的处理。我这里是设计了取消点赞的接口。

取消点赞功能需要传递用户 id书籍 id,然后根据两个id查询数据库。查询到数据将like 表的数据 destroy以及将book 表的数据 decrement即可。

伪代码如下:

 static async disLike(uid,bid){
        let like = await Like.findOne({
            uid: uid,
            bkid: bid
        })
        if (!like) {
            throw new global.errs.NotFound("不喜欢失败", NotFound.UN_LIKE_FAIL)
        }
        // Favor 表 favor 记录
        return sequelize.transaction(async t => {
            await like.destroy({
                force: true,
                transaction: t
            })
            const book = await Book.detail(bid)
            await book.decrement('like_count', {
                by: 1,
                transaction: t
            })
        })
    }

以上就是本次的介绍。


扫码关注公众号,轻撩即可。

原文地址:https://www.cnblogs.com/gdragon/p/12003991.html

时间: 2024-10-21 14:41:05

全栈项目|小书架|服务器端-NodeJS+Koa2 实现点赞功能的相关文章

全栈项目|小书架|服务器端-NodeJS+Koa2实现首页图书列表接口

通过上篇文章 全栈项目|小书架|微信小程序-首页水平轮播实现 我们实现了前端(小程序)效果图的展示,这篇文章来介绍服务器端的实现. 首页书籍信息 先来回顾一下首页书籍都有哪些信息: 从下面的图片可以看出目前一本图书信息主要有: 图片字段 名称字段 作者字段 出版社字段 除了以上前端页面中可见的信息外,在服务器开发中还需要给每一条记录(数据)都加上下面的几个字段: 创建时间字段 更新时间字段 删除时间字段 最后完成的数据库表如下: ps:由于数据库是直接导入的,之前的数据库是没有时间字段的,所以前

全栈项目|小书架|服务器端-NodeJS+Koa2 实现书籍详情接口

通过上篇文章 全栈项目|小书架|微信小程序-首页水平轮播实现 我们实现了前端(小程序)效果图的展示,这篇文章来介绍服务器端的实现. 书籍详情分析 书籍详情页面如下: 从上图可以分析出详情页面大概有以下几个接口: 获取书籍详情信息 获取用户对书籍的喜欢状态接口 喜欢/不喜欢书籍接口 获取评论列表 写评论接口 以上的接口,有的数据可以直接从已存在的数据表中去获取,比如:书籍详情信息,而其他新接口就需要创建对应的model,然后根据model创建相应的数据表. 比如 用户对书籍的喜欢操作,可以创建li

全栈项目|小书架|服务器开发-Koa2 全局异常处理

什么是异常 做开发的基本都知道异常,像Android开发中常见的ANR异常.空指针异常,服务器开发中经常遇到的异常404,500异常,还有一些其他常见的异常,具体可见HTTP状态码. 基本上这些异常可以总结为:已知异常和未知异常. 已知异常就是程序中能够预想到异常,比如:服务器接口开发中某个api接口需要5个参数,而用户传递的参数多余5个或者少于5个,这种错误就是已知错误. 未知异常就说程序中不能预想到的异常,比如:服务器接口开发中遇到了空指针而程序中又没有做相应处理就会抛出HTTP状态码为50

全栈项目|小书架|服务器开发-Koa2中间件机制洋葱模型了解一下

KOA2 是什么? Koa是一个新的 web 框架,由 Express 幕后的原班人马打造, 致力于成为 web 应用和 API 开发领域中的一个更小.更富有表现力.更健壮的基石. 通过利用 async函数,Koa帮你丢弃回调函数,并有力地增强错误处理. Koa 并没有捆绑任何中间件, 而是提供了一套优雅的方法,帮助您快速而愉快地编写服务端应用程序. 为什么产生? 笔者对这几个框架都不熟,这里就不误人子弟了.可以看看下面一些大佬的介绍. Koa是由Express的原班人马打造,那么他们为什么不将

全栈项目|小书架|服务器开发-Koa全局路由实现

什么是路由 路由就是具体的访问路径,指向特定的功能模块.一个api接口是由ip(域名)+端口号+路径组成,例如 :https://www.npmjs.com/package/koa-router就是一个路由,指向了koa-router的npm页面. 为什么需要 koa-router 路由 当然不需要koa-router也能实现路由功能,通过ctx.request.path去指定路径实现.例子如下: const koa = require('koa2') const app = new koa()

全栈项目|小书架|小程序端-评论功能实现

效果图 发布评论 发布评论的入口在图书详情页面,点击 写评论 按钮之后跳转到发布评论页面. wxml布局比较简单了,目前还没有添加图片评论功能,也没有子评论功能,所以伪代码就比较简单了: <view class="comment-container"> <!-- book name --> <view class="book-name"> <text>{{bookInfo.name}}</text> <

基于NodeJS的全栈式开发(基于NodeJS的前后端分离)

也谈基于NodeJS的全栈式开发(基于NodeJS的前后端分离) 前言 为了解决传统Web开发模式带来的各种问题,我们进行了许多尝试,但由于前/后端的物理鸿沟,尝试的方案都大同小异.痛定思痛,今天我们重新思考了“前后端”的定义,引入前端同学都熟悉的NodeJS,试图探索一条全新的前后端分离模式. 随着不同终端(Pad/Mobile/PC)的兴起,对开发人员的要求越来越高,纯浏览器端的响应式已经不能满足用户体验的高要求,我们往往需要针对不同的终端开发定制的版本.为了提升开发效率,前后端分离的需求越

《从零开始做一个MEAN全栈项目》(1)

欢迎关注本人的微信公众号"前端小填填",专注前端技术的基础和项目开发的学习. 在本系列的开篇,我打算讲一下全栈项目开发的优势,以及MEAN项目各个模块的概览. 为什么选择全栈开发?     对于初学者来说,学习一门新的语言和技术的体验总是让人愉快的,也会满足于掌握了一些新的东西并且解决了一些实际问题.在一个小组中采用全栈开发时,你可以更加有效地把握项目全局概念,这也有利于让你了解项目中的不同模块以及它们之间是如何协同工作的.你会对你们的产品中他人的贡献更加清晰,你也就了解了这款产品如何

《从零开始做一个MEAN全栈项目》(2)

欢迎关注本人的微信公众号"前端小填填",专注前端技术的基础和项目开发的学习.   上一节简单介绍了什么是MEAN全栈项目,这一节将简要介绍三个内容:(1)一个通用的MEAN项目的技术架构,(2)为什么我们要打造单页应用,(3)本系列项目的技术架构和开发计划.希望通过这三个问题,我们能够对本项目产生一个全局视角. 实现一个常见的MEAN全栈项目的核心就是RESTful API.这个接口通常是用MongoDB, Express, Node.js实现的,而单页应用(SPA)由AngularJ