33.点赞功能
需求:
1.同一个用户只能点赞一次,再次点赞则取消点赞。
2.如果当前用户已经点赞,则点赞按钮高亮显示(前端实现,只需要根据Blog类中的isLike属性表示是否点赞过了)
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;
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;}
@Overridepublic 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;}@Overridepublic Blog detail(Integer id) {Blog blog = getById(id);queryBlogUser(blog);return blog;}@Overridepublic void likeBlog(Integer id) {//1.判断当前用户是否已经点赞UserDTO user = UserHolder.getUser();//这里的userId一定要转成String类型,因为使用的是StringRedisTemplateString key = "blog:liked:" + id.toString();Boolean isMember = stringRedisTemplate.opsForSet().isMember(key, user.getId().toString());//如果未点赞,可以点赞//这里不要直接判断布尔值,而是使用工具类判断,防止isMember对象为null,报空指针异常if (BooleanUtil.isFalse(isMember)) {//数据库点赞数 + 1boolean isSuccess = update().setSql("liked = liked + 1").eq("id", id).update();//数据更新成功了在更新redisif (isSuccess) {//保存用户id到redis的set集合stringRedisTemplate.opsForSet().add(key, user.getId().toString());}} else {//如果点赞,则取消点赞//数据库点赞数 - 1boolean isSuccess = update().setSql("liked = liked - 1").eq("id", id).update();//数据更新成功了在更新redisif (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));}