效果图

接口分析

通过上面的效果图可以看出,点赞入口主要是在书籍的详情页面。

而书籍详情页面,有以下几个功能是和点赞有关的:

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

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

点赞 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({
where: {
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
})
})
}

以上就是本次的介绍。


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

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

  1. 全栈项目|小书架|服务器端-NodeJS+Koa2 实现搜索功能

    搜索功能会包含:热搜.搜索列表. 热搜功能在电商的搜索中经常看到,热搜数据的来源有两种 用户真实的搜索数据,根据算法进行排序 人为推送的数据 想想微博热搜是可以买的就知道热搜功能多么重要了. 我采用第 ...

  2. 全栈项目|小书架|服务器端-NodeJS+Koa2 实现评论功能

    评论功能分析 上图可以看出评论功能主要实现了:评论的发布.评论列表的展示. 在不考虑子评论以及图片评论的场景下,评论功能主要有以下两个接口: 发布评论 获取评论列表(考虑分页) 评论 Model 的建 ...

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

    通过上篇文章 全栈项目|小书架|微信小程序-首页水平轮播实现 我们实现了前端(小程序)效果图的展示,这篇文章来介绍服务器端的实现. 首页书籍信息 先来回顾一下首页书籍都有哪些信息: 从下面的图片可以看 ...

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

    通过上篇文章 全栈项目|小书架|微信小程序-首页水平轮播实现 我们实现了前端(小程序)效果图的展示,这篇文章来介绍服务器端的实现. 书籍详情分析 书籍详情页面如下: 从上图可以分析出详情页面大概有以下 ...

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

    什么是异常 做开发的基本都知道异常,像Android开发中常见的ANR异常.空指针异常,服务器开发中经常遇到的异常404,500异常,还有一些其他常见的异常,具体可见HTTP状态码. 基本上这些异常可 ...

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

    KOA2 是什么? Koa是一个新的 web 框架,由 Express 幕后的原班人马打造, 致力于成为 web 应用和 API 开发领域中的一个更小.更富有表现力.更健壮的基石. 通过利用 asyn ...

  7. 全栈项目|小书架|服务器开发-Koa2 连接MySQL数据库(Navicat+XAMPP)

    为什么使用数据库 为什么需要数据库?-知乎 相比与文件系统,数据库具有以下优势: 高效率:查找效率高 高可用:可数据库共享 安全性强:数据不能随意修改 选择哪个数据库 数据库可以分为关系型数据库和非关 ...

  8. 全栈项目|小书架|服务器开发-Koa2 参数校验处理

    为什么需要做参数校验 在开发中,无论是App开发还是服务器接口开发, 我们无法去预测用户传入的数据,因此参数(数据)校验是开发中不可或缺的一环. 例如像App的注册登录表单提交页面,就要做好多层的判断 ...

  9. 全栈项目|小书架|服务器开发-NodeJS 使用 JWT 实现登录认证

    通过这篇 全栈项目|小书架|服务器开发-JWT 详解 文章我们对JWT有了深入的了解,那么接下来介绍JWT如何在项目中使用. 安装 $ npm install jsonwebtoken 生成 Toke ...

随机推荐

  1. 04-树6 Complete Binary Search Tree (30 分)

    A Binary Search Tree (BST) is recursively defined as a binary tree which has the following propertie ...

  2. javaScript 判断为false

    JavaScript把null.undefined.0.NaN和空字符串''视为false,其他值一概视为true

  3. mfs分布式文件系统,分布式存储,高可用(pacemaker+corosync+pcs),磁盘共享(iscsi),fence解决脑裂问题

    一.MFS概述 MooseFS是一个分布式存储的框架,其具有如下特性:(1)通用文件系统,不需要修改上层应用就可以使用(那些需要专门api的dfs很麻烦!).(2)可以在线扩容,体系架构可伸缩性极强. ...

  4. @Autowired和@Resource的区别和联系

    背景: 今天下班路上看到一个大货车,于是想到了装配,然后脑海里跳出了一个注解@Autowired(自动装配),于是又想到最近工作项目用的都是@Resource注解来进行装配.于是本着学什么东西都要一钻 ...

  5. Android仿微信QQ等实现锁屏消息提醒

    demo代码如下: import android.content.Intent; import android.os.Bundle; import android.support.v7.app.App ...

  6. 【SpringBoot】SpringBoot配置文件及YAML简介(三)

    SpringBoot配置文件 SpringBoot使用一个全局的配置文件,配置文件名是固定的; application.properties application.yml 配置文件的作用:修改Spr ...

  7. LeetCode_485. Max Consecutive Ones

    485. Max Consecutive Ones Easy Given a binary array, find the maximum number of consecutive 1s in th ...

  8. 使用抓包工具将抓到的接口存放Jmeter中

    1. jmeter工作台新增 HTTP代理服务器.端口设置为:8888 2. 抓包工具上面设置代理服务器地址 3.代理服务器未启动时,抓包工具界面显示无法联网. 4.在Jmeter中点击[启动]HTT ...

  9. [LeetCode] 768. Max Chunks To Make Sorted II 可排序的最大块数 II

    This question is the same as "Max Chunks to Make Sorted" except the integers of the given ...

  10. Vue 搭建项目

    Vue  搭建项目 一.node下载安装: 1.下载:https://nodejs.org/en/download/ 2.安装默认许选择,下一步就行: 3.安装完之后就可以使用npm命令 二.通过@v ...