效果图

接口分析

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

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

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

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

点赞 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. TopK问题及优化

    腾讯面试题:有100W个战斗力,取前100名的算法. 经典topK问题,结论是:随机选择算法 + 快排思想,通过随机选择算法,找到第k大的数,再进行一次快排中的partition,就能得到TopK的结 ...

  2. pytest以函数形式形成测试用例

    #coding=utf- from __future__ import print_function #开始执行该文件时,该函数执行 def setup_module(module): print(' ...

  3. ARC098F Donation

    传送门 Atcoder Solution 首先是几个引理: 重新定义权值\(val_i=max(a_i-b_i,0)\),那么通过这个点必须需要\(val_i+b_i\)的钱. 多次经过一个点一定是在 ...

  4. 安全测试基础-SQL注入详解

    1:什么是SQL注入 SQL注入是一种将SQL代码插入或添加到应用(用户)的输入参数中的攻击,之后再将这些参数传递给后台的SQL服务器加以解析并执行. www.xx.com/news.php?id=1 ...

  5. 高并发&高可用系统的常见应对策略 秒杀等-(阿里)

    对于一个需要处理高并发的系统而言,可以从多个层面去解决这个问题. 1.数据库系统:数据库系统可以采取集群策略以保证某台数据库服务器的宕机不会影响整个系统,并且通过负载均衡策略来降低每一台数据库服务器的 ...

  6. 【转】Android原生PDF功能实现

    1.背景 近期,公司希望实现安卓原生端的PDF功能,要求:高效.实用. 经过两天的调研.编码,实现了一个简单Demo,如上图所示.关于安卓原生端的PDF功能实现,技术点还是很多的,为了咱们安卓开发的同 ...

  7. C++11版本不能使用一个单行命名空间方式特化一个函数的bug

    warning: specialization of ‘template<class _Iterator> struct std::iterator_traits’ in differen ...

  8. Vue使用NProgress

    NProgress是页面跳转是出现在浏览器顶部的进度条官网:http://ricostacruz.com/nprogress/github:https://github.com/rstacruz/np ...

  9. hive函数 get_json_object

    pandas和SQL数据分析实战 https://study.163.com/course/courseMain.htm?courseId=1006383008&share=2&sha ...

  10. HDFS修改副本数,并生效。

    1.hadoop集群使用的ucloud的uahdoop 2.是公司集群配置小,只有两台core节点,实际就是两台的datanode. 容量占用超过了80%,需要缩减副本以空出容量. 3.查看 hado ...