需求:
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));
}