代码如下(简单明了,直接复制粘贴使用):
package com.pipilin.api.controller;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pipilin.common.core.controller.BaseController;
import com.pipilin.common.core.domain.AjaxResult;
import com.pipilin.vim.domain.Article;
import com.pipilin.vim.service.ArticleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
* @title: 文章
* @author: 289151517520@qq.com
* @date: 2022/7/11 9:49
*/
@RestController
@RequestMapping("/system/like")
public class PArticleController extends BaseController {
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Autowired
private ArticleService articleService;
/**
* @title: 文章分页
* @params: page 分页对象 articleId 文章ID
* @date: 2022/7/9 21:41
*/
@GetMapping("/queryArticleList")
public AjaxResult queryArticleList(Page page, Long articleId) {
Page page1 = articleService.page(page, new LambdaQueryWrapper<Article>().orderByDesc(Article::getLiked));
List<Article> records = page1.getRecords();
records.forEach(article -> {
articleService.queryArticleUser(article);
isArticleLiked(article);
});
return AjaxResult.success(records);
}
/**
* @title: 文章详情
* @params: articleId 文章ID
* @date: 2022/7/9 21:41
*/
@GetMapping("/queryArticleById")
public AjaxResult queryArticleById(Long articleId) {
// 1.查询article
Article article = articleService.getById(articleId);
if (ObjectUtil.isNull(article)) {
return AjaxResult.error("文章不存在!");
}
// 2. 查询article有关的用户
List<Article> articles = articleService.queryArticleUser(article);
// 3. 查询article是否被点赞
isArticleLiked(article);
return AjaxResult.success(article);
}
/**
* @title: 文章是否点赞
* @params: articleId 文章ID
* @date: 2022/7/9 21:42
*/
private void isArticleLiked(Article article) {
// 1.获取登录用户ID
Long userId = getUserId();
// 1.2用户未登录,无需查询是否点赞
if (userId == null) {
return;
}
// 2.判断当前登录用户是否已经点赞
String key = "article:liked:" + article.getId();
Double score = stringRedisTemplate.opsForZSet().score(key, userId.toString());
article.setLiked(BooleanUtil.isTrue(ObjectUtil.isNotNull(score)));
}
/**
* @title: 文章点赞、取消点赞
* @params: articleId 文章ID
* @date: 2022/7/9 21:09
*/
@PostMapping
public AjaxResult likedArticle(Long articleId) {
// 1.获取登录用户ID
Long userId = getUserId();
// 2.判断当前登录用户是否已经点赞
String key = "article:liked:" + articleId;
Double score = stringRedisTemplate.opsForZSet().score(key, userId.toString());
if (ObjectUtil.isNull(score)) {
// 3.如果未点赞,可以点赞
// 3.1 数据库点赞数 + 1
boolean isSuccess = articleService.update().setSql("liked = liked + 1").eq("id", articleId).update();
// 3.2 保存用户到Redis的set集合
if (isSuccess) {
stringRedisTemplate.opsForZSet().add(key, userId.toString(), System.currentTimeMillis());
}
} else {
// 4. 如果已经点赞,取消点赞
// 4.1 数据库点赞数 - 1
boolean isSuccess = articleService.update().setSql("liked = liked - 1").eq("id", articleId).update();
// 4.2 把用户从Redis的set集合移除
if (isSuccess) {
stringRedisTemplate.opsForZSet().remove(key, userId.toString());
}
}
return AjaxResult.success();
}
/**
* @title: 文章点赞top5
* @params: articleId 文章ID
* @date: 2022/7/11 9:53
*/
@GetMapping("/queryArticleLikes")
public AjaxResult queryArticleLikes(Long articleId) {
String key = "article:liked:" + articleId;
// 1.查询top5点赞用户 SortedSet zRange key 0 4
Set<String> top5 = stringRedisTemplate.opsForZSet().range(key, 0, 4);
// 1.2判断点赞用户集合是否为空
if (top5 == null || top5.isEmpty()) {
return AjaxResult.success(Collections.emptyList());
}
// 2.解析其中用户ID
List<Long> ids = top5.stream().map(Long::valueOf).collect(Collectors.toList());
String idStr = StrUtil.join(",", ids);
// 3.根据用户ID查询用户信息 WHERE id IN (5,1) ORDER BY FIELD(id,5,1)
// 3.1 MySQL使用IN查询的时候怎么保证查询结果是根据我们传入的ids顺序排列,使用ORDER BY FIELD(id,ids)
List<UserDTO> userDTOS = userService.query().in("id", ids).last("ORDER BY FIELD(id," + idStr + ")").list()
.stream()
.map(user -> BeanUtil.copyProperties(user, UserDTO.class))
.collect(Collectors.toList());
return AjaxResult.success(userDTOS);
}
}