33.点赞功能

需求:

1.同一个用户只能点赞一次,再次点赞则取消点赞。

2.如果当前用户已经点赞,则点赞按钮高亮显示(前端实现,只需要根据Blog类中的isLike属性表示是否点赞过了)

sql 复制代码
CREATE TABLE `tb_blog` (
  `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
  `shop_id` bigint NOT NULL COMMENT '商户id',
  `user_id` bigint unsigned NOT NULL COMMENT '用户id',
  `title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '标题',
  `images` varchar(2048) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '探店的照片,最多9张,多张以","隔开',
  `content` varchar(2048) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '探店的文字描述',
  `liked` int unsigned DEFAULT '0' COMMENT '点赞数量',
  `comments` int unsigned DEFAULT NULL COMMENT '评论数量',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=COMPACT;
java 复制代码
package com.xkj.org.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;

import java.time.LocalDateTime;

/**
 * @author xiankejin
 * @descrition
 * @date 2025/10/25
 */
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("tb_blog")
public class Blog {

    private static final long serialVersionUID = 1L;

    @TableId(value = "id", type = IdType.AUTO)
    private Long id;

    private Long shopId;

    private Long userId;

    private String title;
    /**
     * 探店的照片,最多9张,多张以","隔开'
     */
    private String images;
    /**
     * 探店的文字描述
     */
    private String content;
    /**
     * 点赞数量
     */
    private Integer liked;
    /**
     * 评论数量
     */
    private Integer comments;

    private LocalDateTime createTime;

    private LocalDateTime updateTime;

    /**
     * 用户图标
     */
    @TableField(exist = false)
    private String icon;
    /**
     * 用户姓名
     */
    @TableField(exist = false)
    private String name;


    /**
     * 是否点赞过了
     */
    @TableField(exist = false)
    private Boolean isLike;

}
java 复制代码
@Override
    public List<Blog> queryHotBlog(Integer current) {
        //根据点赞数量倒序排列
        Page<Blog> page = query().orderByDesc("liked")
                .page(new Page<>(current, UserConstant.MAX_PAGE_SIZE));
        List<Blog> records = page.getRecords();
        //这里采用lambda表达式简写
        records.forEach(this::queryBlogUser);
        return records;
    }

    @Override
    public Blog detail(Integer id) {
        Blog blog = getById(id);
        queryBlogUser(blog);
        return blog;
    }

    @Override
    public void likeBlog(Integer id) {
        //1.判断当前用户是否已经点赞
        UserDTO user = UserHolder.getUser();
        //这里的userId一定要转成String类型,因为使用的是StringRedisTemplate
        String key = "blog:liked:" + id.toString();
        Boolean isMember = stringRedisTemplate.opsForSet().isMember(key, user.getId().toString());
        //如果未点赞,可以点赞
        //这里不要直接判断布尔值,而是使用工具类判断,防止isMember对象为null,报空指针异常
        if (BooleanUtil.isFalse(isMember)) {
            //数据库点赞数 + 1
            boolean isSuccess = update().setSql("liked = liked + 1").eq("id", id).update();
            //数据更新成功了在更新redis
            if (isSuccess) {
                //保存用户id到redis的set集合
                stringRedisTemplate.opsForSet().add(key, user.getId().toString());
            }
        } else {
            //如果点赞,则取消点赞
            //数据库点赞数 - 1
            boolean isSuccess = update().setSql("liked = liked - 1").eq("id", id).update();
            //数据更新成功了在更新redis
            if (isSuccess) {
                //将用户id从redis的set集合中移除
                stringRedisTemplate.opsForSet().remove(key, user.getId().toString());
            }
        }

    }

    /**
     * 给BLog对象添加用户信息
     *
     * @param blog
     */
    private void queryBlogUser(Blog blog) {
        User user = userService.getById(blog.getUserId());
        blog.setName(user.getNickName());
        blog.setIcon(user.getIcon());
        //查询blog是否被点赞
        //1.判断当前用户是否已经点赞
        UserDTO currentUser = UserHolder.getUser();
        String key = "blog:liked:" + blog.getId().toString();
        Boolean isMember = stringRedisTemplate.opsForSet().isMember(key, currentUser.getId().toString());
        blog.setIsLike(BooleanUtil.isTrue(isMember));
    }
相关推荐
帅气的你4 分钟前
Spring Boot 集成 AOP 实现日志记录与接口权限校验
java·spring boot
zhglhy24 分钟前
Spring Data Slice使用指南
java·spring
win x36 分钟前
Redis 主从复制
java·数据库·redis
weixin_423995001 小时前
unity 处理图片:截图,下载,保存
java·unity·游戏引擎
帅气的你1 小时前
从零封装一个通用的 API 接口返回类:统一前后端交互格式
java·设计模式
qq_178057071 小时前
基于minio实现的分片上传-支持断点续传
java
高山上有一只小老虎1 小时前
灵异背包?
java·算法
码农水水1 小时前
大疆Java面试被问:TCC事务的悬挂、空回滚问题解决方案
java·开发语言·人工智能·面试·职场和发展·单元测试·php
qq_2518364571 小时前
基于java Web 个人网站系统设计与实现
java·开发语言·数据库
帅气的你1 小时前
Spring Boot 1.x 接口性能优化:从 3 秒到 200 毫秒的实战调优之路
java·spring boot