package com.hmdp.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hmdp.dto.Result;
import com.hmdp.dto.ScrollResult;
import com.hmdp.dto.UserDTO;
import com.hmdp.entity.Blog;
import com.hmdp.entity.Follow;
import com.hmdp.entity.User;
import com.hmdp.mapper.BlogMapper;
import com.hmdp.service.IBlogService;
import com.hmdp.service.IFollowService;
import com.hmdp.service.IUserService;
import com.hmdp.utils.SystemConstants;
import com.hmdp.utils.UserHolder;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import static com.hmdp.utils.RedisConstants.BLOG_LIKED_KEY;
import static com.hmdp.utils.RedisConstants.FEED_KEY;
/**
* <p>
* 服务实现类
* </p>
*
* @author 虎哥
* @since 2021-12-22
*/
@Service
public class BlogServiceImpl extends ServiceImpl<BlogMapper, Blog> implements IBlogService {
@Resource
private IUserService userService;
@Resource
private StringRedisTemplate stringRedisTemplate;
@Resource
private IFollowService followService;
@Override
public Result queryHotBlog(Integer current) {
// 根据用户查询
Page<Blog> page = query()
.orderByDesc("liked")
.page(new Page<>(current, SystemConstants.MAX_PAGE_SIZE));
// 获取当前页数据
List<Blog> records = page.getRecords();
// 查询用户
records.forEach(blog -> {
this.queryBlogUser(blog);
this.isBlogLiked(blog);
});
return Result.ok(records);
}
@Override
public Result queryBlogById(Long id) {
// 1.查询blog
Blog blog = getById(id);
if (blog == null) {
return Result.fail("笔记不存在!");
}
// 2.查询blog有关的用户
queryBlogUser(blog);
// 3.查询blog是否被点赞
isBlogLiked(blog);
return Result.ok(blog);
}
private void isBlogLiked(Blog blog) {
// 1.获取登录用户
UserDTO user = UserHolder.getUser();
if (user == null) {
// 用户未登录,无需查询是否点赞
return;
}
Long userId = user.getId();
// 2.判断当前登录用户是否已经点赞
String key = "blog:liked:" + blog.getId();
Double score = stringRedisTemplate.opsForZSet().score(key, userId.toString());
blog.setIsLike(score != null);
}
@Override
public Result likeBlog(Long id) {
// 1.获取登录用户
Long userId = UserHolder.getUser().getId();
// 2.判断当前登录用户是否已经点赞
String key = BLOG_LIKED_KEY + id;
Double score = stringRedisTemplate.opsForZSet().score(key, userId.toString());
if (score == null) {
// 3.如果未点赞,可以点赞
// 3.1.数据库点赞数 + 1
boolean isSuccess = update().setSql("liked = liked + 1").eq("id", id).update();
// 3.2.保存用户到Redis的set集合 zadd key value score
if (isSuccess) {
stringRedisTemplate.opsForZSet().add(key, userId.toString(), System.currentTimeMillis());
}
} else {
// 4.如果已点赞,取消点赞
// 4.1.数据库点赞数 -1
boolean isSuccess = update().setSql("liked = liked - 1").eq("id", id).update();
// 4.2.把用户从Redis的set集合移除
if (isSuccess) {
stringRedisTemplate.opsForZSet().remove(key, userId.toString());
}
}
return Result.ok();
}
@Override
public Result queryBlogLikes(Long id) {
String key = BLOG_LIKED_KEY + id;
// 1.查询top5的点赞用户 zrange key 0 4
Set<String> top5 = stringRedisTemplate.opsForZSet().range(key, 0, 4);
if (top5 == null || top5.isEmpty()) {
return Result.ok(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)
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());
// 4.返回
return Result.ok(userDTOS);
}
@Override
public Result saveBlog(Blog blog) {
// 1.获取登录用户
UserDTO user = UserHolder.getUser();
blog.setUserId(user.getId());
// 2.保存探店笔记
boolean isSuccess = save(blog);
if(!isSuccess){
return Result.fail("新增笔记失败!");
}
// 3.查询笔记作者的所有粉丝 select * from tb_follow where follow_user_id = ?
List<Follow> follows = followService.query().eq("follow_user_id", user.getId()).list();
// 4.推送笔记id给所有粉丝
for (Follow follow : follows) {
// 4.1.获取粉丝id
Long userId = follow.getUserId();
// 4.2.推送
String key = FEED_KEY + userId;
stringRedisTemplate.opsForZSet().add(key, blog.getId().toString(), System.currentTimeMillis());
}
// 5.返回id
return Result.ok(blog.getId());
}
@Override
public Result queryBlogOfFollow(Long max, Integer offset) {
// 1.获取当前用户
Long userId = UserHolder.getUser().getId();
// 2.查询收件箱 ZREVRANGEBYSCORE key Max Min LIMIT offset count
String key = FEED_KEY + userId;
Set<ZSetOperations.TypedTuple<String>> typedTuples = stringRedisTemplate.opsForZSet()
.reverseRangeByScoreWithScores(key, 0, max, offset, 2);
// 3.非空判断
if (typedTuples == null || typedTuples.isEmpty()) {
return Result.ok();
}
// 4.解析数据:blogId、minTime(时间戳)、offset
List<Long> ids = new ArrayList<>(typedTuples.size());
long minTime = 0; // 2
int os = 1; // 2
for (ZSetOperations.TypedTuple<String> tuple : typedTuples) { // 5 4 4 2 2
// 4.1.获取id
ids.add(Long.valueOf(tuple.getValue()));
// 4.2.获取分数(时间戳)
long time = tuple.getScore().longValue();
if(time == minTime){
os++;
}else{
minTime = time;
os = 1;
}
}
// 5.根据id查询blog
String idStr = StrUtil.join(",", ids);
List<Blog> blogs = query().in("id", ids).last("ORDER BY FIELD(id," + idStr + ")").list();
for (Blog blog : blogs) {
// 5.1.查询blog有关的用户
queryBlogUser(blog);
// 5.2.查询blog是否被点赞
isBlogLiked(blog);
}
// 6.封装并返回
ScrollResult r = new ScrollResult();
r.setList(blogs);
r.setOffset(os);
r.setMinTime(minTime);
return Result.ok(r);
}
private void queryBlogUser(Blog blog) {
Long userId = blog.getUserId();
User use
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
Redis实战篇的后端代码 (727个子文件)
001b5328d8ca039c781a5794cfb663a67cf3fc 208B
011f8cc5340e8ea823fae15624e4294a01fef1 79B
0147fe7dfff58041bf398e82bed523d5e574de 216B
016d99da2604866c0916f96478bef9293c68d2 200B
0193afbb4d46fe9fdbf3fdfcb9cadb2fe753ee 3KB
01e912717e117cc87c68f1c7dffa59b638160e 46B
0242b5d347504172fee3a91547932968fd33cc 2KB
02757243f02e7070a179ee2fdf8ba5fe9df979 46B
031addc034933cd68c5e227d7030af4a60f50a 117B
0386fb20efdd6bd708531d5657da234eef3c61 46B
0699762a8c7b19e28f81055e36de29806ef42d 485B
073246078489a8c263af95062ce175f72c622e 1KB
07bedb16bf49733fe995a6dc9c3e12416ecbfb 199B
07ce31afc2765fce9463faaa87695338caf8b0 134B
082b4cbae027578350890da2c772dafff1ccd0 207B
08daf30ec475855c09f81139b9e0132713e3c1 117B
08e4a1e9ee7fb8c6806c479403d91193f57a13 168B
098e6954ca8f49fda2cbf1fd6378e561bf3348 279B
098f48234dc98b0df8b34169603edd0a25ffe3 342B
099ff79bc093a96846b8453a67cc742e328cee 46B
0a0c9f6ddf912194975256951b64fd7d76b859 180KB
0a5ce1adfa617cd2ea0ff017c0ce2868f087b5 655B
0aae9cb53887e04dd7ee930ba242e0b1811a18 72B
0aea63edbf2f6f0cc8a6cd68400b10e61fd3a2 80B
0b26bb6fde9ed1357cf85acba634dfe95b75da 370B
0bdeb28c9bdcff2ce2494328a9db2c3bfa7a83 897B
0d8a3a5c8196f1d7abc03c29bacb92a0437e16 343B
0da6648661b8a477a908cf066a68fde7af8fa0 286B
0daf8510566499b849b8a0f3866e213b4edd8f 225B
0e2825d4bf0a44a768034939506fd3872c978b 45B
0f423198d4901aeefc83a6b37ea7dba97a2aba 46B
0fb8a02fc698a59d27ad38ccaa011f5eb0c258 305B
0fcac2e64cefa166c1f67d3596893bb005df53 148B
105e0cf0c1c586214d46c735aba59dff252f18 843B
10a449d75db854d364c43789be9beb91662679 46B
11144b82d54089f7bb96d96d3dcfe5f16b489a 337B
1154209e6ded2a2f38b505d0b849c322d9975e 166B
11db70068a91bf82cc63400eb1d1845783988d 308B
11e1cbc42505d73b8631d8508d76080e942442 46B
125fbe4e31049eddb931bece2b07f97fc472e4 2KB
12cab899da42a8fe633eccd78eb52520d573d9 1KB
12df83648506d5fd219a96743a45d81b237763 260B
12e0fc3877340d1e721e96c2964e65e5908ef6 117B
12f069924bc65c15d6513e48dc94c45d7b5a2a 272B
136132010490e4cdcbb97fbc486ab0f7c49c5e 198B
13d80d1874dde65da3778958f4e9ae3229329c 1KB
1463a3fe689f60bc75412a5ab0b9cd7485c22a 74B
1485ae4127855ef05a0f9b90f16c910df6097b 77B
14fe85d761cff7b65e6adbf8594d119ce206df 233B
154b5319443ce23441bc8aaf6829a19ce24472 304B
15555b435e1c9c9acd936b050b6a2f969b4ff4 598B
15deee4472c480d74faca83686b576ef6f99fb 281B
16cf14ff609b1c74e3fcbeaff247abe7e1238c 92B
17078996fcb4ad809dde8505118c97d7ba6f32 168B
177e9f9084c7ea25e68dd0dd544a9cf7193bc0 1KB
17a471f298de45d3637b8614eb91e2cff2cd13 79B
17ea3d295b05c2fbb9ad2b4928f0c6cfa6d8ee 86KB
17f2c218a794521fc37cd03a02030fbf8e8f7b 117B
180182e77d2c762b40779cdcc43f6530294e4d 46B
18f52ad5b0ae56ae673f83f1c4189b6de328b2 117B
19f50d4a59760788d2eafeb6b582cd932428b8 3KB
1a1396a54b3e4f61b316f23bfc57896178db58 587B
1a8656506e4f8f6d43709131492cd5074886a0 45B
1a931bdbeb18055864a0dac4e2ddbaf0d7b086 220B
1ac95f8d6211ad3b7a8b7c08320da59440bae3 254KB
1b0ba73800372f73399a96b5673b9572877304 45B
1c2fe959e3465706aa970cc172767b26589523 79B
1ccd34407a73996c2567a388fd86d7603b3285 2KB
1d1d26fbc2e026255d316bc027f1f321480c82 74B
1d825e93bbbf6a2162437cf7f52aea2aa282f9 580B
1e64ecf6746ce4ea816dadd3c574790912d17e 451B
1ec9f38570dc5626b5eb78e73bc495dd4d8c8f 466B
1f6697a960308b42bc8f17b3f6f8fbcda86e9f 400B
1fb00d058bc19434408fb88f95915e7ea09087 218B
201d2000599cd5b92c0a0e088eb56f0678d348 644B
208510216f50208f4179503f2549380cc82240 46B
21a81ebf17b0522c0e12eb5936b350b19ee4bf 45B
21c319df0b19da1a748cba9537392294a656cb 219B
21dafb2051c7df91131167aebfc99c53460f9d 2KB
222e5babbd88ef300f47f3974db6220a8d855b 465B
2368fe97e2a5ea99cc284478f38c8f71321282 178B
240e55a75b6461cb677fa5809272f4807190df 282B
24851fa72a98fb4e3fb1dac0047ba7d679182d 118B
25058febc0c8a95fd87e84b80d05caeb6b3df2 45B
252ad8cb1d7e074b775a96609b62eff2711032 79B
25344fdee6df2e980e91a491d54db85d82bdaf 1KB
2718b948808ea5b2c00f7c37c46e28ab1324ec 403B
27bade463898248eaf85fd8d3840f01bb8ff2e 465B
27ddd7e9c4c1e5aa36a913e98bbf06c753750e 79B
27eee85b1675e45eaac4008e01f458484ff603 63B
282fdfd1e582bcdd0a972cdbd92ef48b8867dc 351B
2977f50d9545ab4ab1b2cb0902011adb579238 289B
299305c6e72dfe0975b988669dbc7d472b52b3 79B
29a015e93f084d187cd0c2fdc2655a671230a3 293B
29c68147419d7d64f0c18fec7e9f021e07026f 171B
29fbc68f80e0150deebb39ae5864d39740771d 305B
2a1b0e6024ad7a553bd20e2eb331993a2c0a98 227B
2a5198782faeffd396b3dcf32696cf07a8bc21 939B
2a63dd83f9bde1e5ef2f5b93e9aecb82d69206 586B
2a641f53f588d03a43cfbb440b8db19720e838 45B
共 727 条
- 1
- 2
- 3
- 4
- 5
- 6
- 8
资源评论
LCQ5279
- 粉丝: 54
- 资源: 1
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功