【仿掘金系列】社区点赞功能的实现

3,334 阅读4分钟

该文章写得较简单,后续会更新- -

1. 点赞的流程图分析

1.1 进入尚未点赞过的文章

  1. 用户通过点击👍的按钮,实现点赞。
  2. 当点击按钮时,会判断用户是否登录
  3. 若登录,则点赞数+1且点赞按钮高亮,若再次点击,则取消点赞
  4. 若未登录,则提醒用户进行登录。

1.2 进入已经点赞过的文章

  1. 用户进入页面,首先会判断用户是否登录
  2. 若没有登录,则不做处理
  3. 若登录,则判断用户是否点赞过该文章
  4. 若点赞过,则高亮👍按钮,若再次点击,则取消点赞
  5. 若没点赞过,则不做处理

2. 数据库设计

数据库设计的很简单:

点赞表:

  1. id——主键
  2. article_id 该文章的ID
  3. user_id 用户的ID
  4. created_time 创建时间
  5. 可选,看你需不需要点踩功能,如果需要,可以加个type字段,用于区分
  6. 可选,增加个逻辑删除字段,不过我感觉对于点赞功能不是很有必要。

文章表: 看个人需求,点赞的话要有个记录点赞数的字段即可


3. 代码实现

我们按找流程图一步一步来。

具体效果图我会用最近正在做的一个仿掘金社区进行演示,帮助大家更直观的观看效果


3.1 如何判断用户是否登录

代码分析

首先进入尚未点赞过的文章的时候要判断用户是否登录

因为我是用的Vue,所以处理如下:

在Vuex的state写上isLogin字段,同时在mutation声明一个方法,当用户成功登录将isLogin设置成true

这里建议大家,安装Vuex持久化插件vuex-persistedstate,将vuex数据存储在session里面,以放每次刷新页面,导致数据丢失

完成判断用户如何登录之后,我们就可以继续处理接下来的流程


3.2 若用户没有登录的情况下点击👍按钮,则进行提醒

效果图

代码

我是直接用一行代码进行提醒。大家可以根据需要进行调整,比如直接弹出登录框也是可以的~


3.3 若用户为登陆状态,点击👍

效果图

代码分析

前端:

按钮

定义好基本的数据形式

// 点赞记录(传给后端的数据)
thumbUpArticle: {
  articleId: '',
  userId: ''
},
// 点赞按钮颜色和类型,熟悉Element-UI的同学应该了解是
// 用于动态变化按钮的颜色和右上角小圆圈的颜色
thumbUpArticleBtn: {
  type: 'info',
  color: ''
},

核心代码

可能看起来注释写的有点乱,

不过大家从第一行耐心往下读即可O(∩_∩)O,思路非常清晰

  1. 前端封装好数据传给后端
  2. 后端进行处理,返回结果给前端
  3. 前端拿到结果进行页面渲染

后端:

后端我使用的是Springboot 和 Mybatis、MybatisPlus

基本思路是 前端请求->controller->service->mapper->数据库

处理Post请求

  • controller
@RestController
@RequestMapping("/article_like")
public class ArticleLikeController {

    @Autowired
    private ArticleLikeService articleLikeService;

    @PostMapping("/")
    // 调用service的thumbUpArticle方法
    public MyJsonResult thumbUpArticle(@RequestBody ArticleLike articleLike) {
        return MyJsonResult.success(articleLikeService.thumbUpArticle(articleLike));
    }
}
  • service
@Service
@Transactional // 进行事务
public class ArticleLikeServiceImpl extends ServiceImpl<ArticleLikeMapper, ArticleLike> implements ArticleLikeService {
    @Autowired
    private ArticleLikeMapper articleLikeMapper;
    @Autowired
    private ArticleMapper articleMapper;


    @Override
    // 直接使用mp自带的insert插入点赞记录,再使用自己编写的sql进行文章点赞数+1
    public boolean thumbUpArticle(ArticleLike articleLike) {
        // 两者成功才成功
        return articleLikeMapper.insert(articleLike) > 0 && articleMapper.incrLikeCount(articleLike.getArticleId());
    }
}

  • mapper
    /**
     * 点赞文章
     * @param articleId
     * @return
     */
    @Update("update article set like_count = like_count + 1 where id = #{articleId}")
    boolean incrLikeCount(Long articleId);

处理delete请求和post差不多,就是取消点赞。


3.4 判断用户是否点赞过

如果用户在登录的情况下,进入已经点赞过的按钮,则按钮会自动高亮

效果图

代码分析

前端:

这里注意!!!

该方法需要放在vue的钩子函数created里面

因为created是组件每次创建都会触发的方法

即我们进入该文章详情页面就会触发判断

后端:

  • controller
    @GetMapping("/is")
    public MyJsonResult isThumbUp(@RequestParam("aid")Long aid,@RequestParam("uid")Long uid) {
        boolean thumbUp = articleLikeService.isThumbUp(aid, uid);
        return MyJsonResult.success(thumbUp);
    }
  • service & mapper

判断逻辑,根据前端传来的文章ID和用户ID,判断点赞表中是否有相同的数据

这边使用了mybatis-plus,正常操作也是一样的。

    @Override
    public boolean isThumbUp(Long aid, Long uid) {
        LambdaQueryWrapper<ArticleLike> lqw = new LambdaQueryWrapper<>();
        lqw
                .eq(ArticleLike::getArticleId, aid)
                .eq(ArticleLike::getUserId, uid);
        Integer res = articleLikeMapper.selectCount(lqw);
        return res>0;
    }

4. 写在最后

点赞评论的话思路其实也差不多,不过需要注意如何保持点赞过的状态,我的思路是先把用户点赞过的评论ID取出来,因为每个评论是利用v-for实现的,将点赞按钮的style写成如下:style={color:isThumbUpComment(item.id)},然后这个方法就是判断当前评论对象的ID是否在前面维持的数组里,如果存在,则返回高亮的颜色字符串,如果不是直接返回''即可。

希望大家一起进步哇!!(●'◡'●)~~


5. 福利:GIF图制作工具——Gifcam

Gifcam: 具体使用可以看下面的链接

blog.csdn.net/L_201607/ar…