点赞功能实现思路

您所在的位置:网站首页 有赞学堂 点赞功能实现思路

点赞功能实现思路

2023-11-02 20:36| 来源: 网络整理| 查看: 265

引言

点赞功能是一种常见的社交互动功能,通常用于用户对内容或其他用户的喜爱、认可或支持进行表达。它在许多应用和网站中得到广泛应用,能够提升用户参与度,用户通过点赞表达对内容的喜爱、赞赏或认同,从而增加用户与平台的互动和留存。同样也是社交影响力的展示,通过点赞数可以作为一种社交影响力的展示指标。当用户获得大量点赞时,可以增强其在社交网络中的影响力和可见度。这对于内容创作者、个人品牌或企业来说,有助于建立声誉和吸引更多的关注。

在这里我演示一下如何实现一个简单的点赞功能;

环境:

springboot2.3.7

java8

这里我实现的是一个文章点赞功能的实现;

项目准备

首先需要两张数据库表:

article文章表

image-20230624101428156

关键是thumbs点赞数量字段;

article_user_thumb文章用户点赞关系表,用于记录哪个用户点赞了哪个文章:

image-20230624101607092

这里还有一个用户表user,这里只用userId字段,所以就不展示用户表了;

流程分析

点赞功能流程大致如下:

image-20230624102616239

这里需要注意幂等性的保证,否则就会出现一个用户刷赞的情况发生;所以需要用synchronized保证幂等性;

因为数据库操作涉及到两张表的修改,所以需要开启事务,在springboot项目中可以使用@Transactional轻松实现事务处理,但是需要注意该注解和synchronized使用过程中的问题,具体可以看这篇文章:关于@Transactional和synchronized使用的问题

代码实现

controller接口:

@PostMapping("/{articleId}") public BaseResponse postArticleThumbs(@PathVariable Long articleId) { if (articleId == null) { throw new BusinessException(StatusCode.PARAMS_ERROR); } // 判断该文章是否存在 Article article = articleService.getById(articleId); if (article == null) { throw new BusinessException(StatusCode.PARAMS_ERROR, "文章不存在"); } // 获取当前点赞用户信息 UserVo currentUser = userSupport.getCurrentUser(); if (currentUser == null) { throw new BusinessException(StatusCode.NO_AUTH); } long userId = currentUser.getId(); // 获取当前登录用户的id int res; // 这里需要注意synchronized和@Transactional注解问题 synchronized (String.valueOf(userId).intern()) { // 保证同一个用户的点赞是串行执行的,保证幂等性 res = articleUserThumbService.postArticleThumbs(articleId, userId); } return ResultUtils.success(res); }

service实现类:

@Override @Transactional(rollbackFor = Exception.class) public int postArticleThumbs(Long articleId, long userId) { if (articleId == null) { throw new BusinessException(StatusCode.PARAMS_ERROR); } // 点赞对象实体 ArticleUserThumb articleUserThumb = new ArticleUserThumb(); articleUserThumb.setArticleId(articleId); articleUserThumb.setUserId(userId); LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper(articleUserThumb); int result; // 操作结果 // 判断当前用户是否已经点赞,点赞了则取消,没有点赞则点赞 int count = articleUserThumbMapper.selectCount(queryWrapper); if (count > 0) { // 取消点赞 result = articleUserThumbMapper.delete(queryWrapper); if (result > 0) { // 删除成功 boolean res = articleService.update() .eq("id", articleId) .gt("thumbs", 0) // 确保点赞数是大于0的才能-1 .setSql("thumbs = thumbs - 1") .update(); return res ? -1 : 0; } else { throw new BusinessException(StatusCode.SYSTEM_ERROR); } } else { // 点赞 result = articleUserThumbMapper.insert(articleUserThumb); if (result > 0) { // 新增成功 boolean res = articleService.update() .eq("id", articleId) .setSql("thumbs = thumbs + 1") .update(); return res ? 1 : 0; } else { throw new BusinessException(StatusCode.SYSTEM_ERROR); } } }

这里的难点就是:为什么需要synchronized保证幂等性和synchronized与@Transactional为什么要这样分开写,搞清楚这两点这部分代码就很好明白了;

后端的功能大致就是这样,下面我简单演示一下前端的实现:

前端代码

后端点赞执行成功后,前端要有对应的相应结果,我的方法是设置一个hasThumb字段,前端通过该字段判断是否已经点赞;

前端用的组件库是ant design vue;

image-20230624105852578

通过hasThumbs判断是否点赞从而显示不同的点赞图标;

hasThumbs是从后端传来的参数,所以判断是否点赞也是后端判断的,比如在获取文章列表时判断每篇文章是否点赞;

点赞方法:

image-20230624110059941

如果用户点赞,则发送点赞请求,后端执行点赞操作,前端这里为了显示点赞状态需要修改一下hasThumb点赞状态,这里只是前端的修改,为了和后端保证点赞状态同步;

到这功能就差不多实现了:

image-20230624110504533

image-20230624110513727

总结

这就是点赞功能的一个简单实现,但是对于性能没有过多的考虑,因为对于点赞的操作是直接修改数据库的,当点赞请求过多时必然会对数据库造成压力,所以可以考虑缓存的介入等,可以自行尝试;



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3