![image]()
![image]()
![image]()
![image]()
package com.hmdp.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hmdp.dto.Result;
import com.hmdp.dto.UserDTO;
import com.hmdp.entity.Follow;
import com.hmdp.mapper.FollowMapper;
import com.hmdp.service.IFollowService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hmdp.service.IUserService;
import com.hmdp.utils.UserHolder;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
* <p>
* 服务实现类
* </p>
*
* @author 虎哥
* @since 2021-12-22
*/
@Service
public class FollowServiceImpl extends ServiceImpl<FollowMapper, Follow> implements IFollowService {
@Resource
private IUserService userService;
private final StringRedisTemplate stringRedisTemplate;
public FollowServiceImpl(StringRedisTemplate stringRedisTemplate) {
this.stringRedisTemplate = stringRedisTemplate;
}
@Override
public Result follow(Long followUserId, boolean isFollow) {
Long userId = UserHolder.getUser().getId();
String key = "follow_" + userId;
// 1.判断是否是关注还是取关
if(isFollow){
// 2.关注
Follow follow = new Follow();
follow.setUserId(userId);
follow.setFollowUserId(followUserId);
boolean isSuccess = save(follow);
if(isSuccess){
//存到redis
stringRedisTemplate.opsForSet().add(key,followUserId.toString());
}
}else {
// 3.取关
boolean isSuccess = remove(new QueryWrapper<Follow>()
.eq("user_id", userId).eq("follow_user_id", followUserId));
if(isSuccess) {
//出redis移除
stringRedisTemplate.opsForSet().remove(key, followUserId.toString());
}
}
return Result.ok();
}
@Override
public Result isFollow(Long followUserId) {
Long userId = UserHolder.getUser().getId();
// 1.查询是否关注
Integer count = query()
.eq("user_id", userId)
.eq("follow_user_id", followUserId)
.count();
// 2.判断
return Result.ok(count > 0);
}
@Override
public Result followCommons(Long id) {
// 1.获取当前用户
Long userId = UserHolder.getUser().getId();
String key = "follow_" + userId;
// 2.求交集
String key2 = "follow_" + id;
Set<String> intersect = stringRedisTemplate.opsForSet().intersect(key,key2);
if(intersect ==null || intersect.isEmpty()){
// 无交集
return Result.ok(Collections.emptyList());
}
// 3.解析id
List<Long> ids = intersect.stream().map(Long::valueOf).collect(Collectors.toList());
// 4.查询用户
List<UserDTO> users = userService.listByIds(ids)
.stream()
.map(user -> BeanUtil.copyProperties(user, UserDTO.class))
.collect(Collectors.toList());
return Result.ok(users);
}
}
@Override
public Result saveBlog(Blog blog) {
// 获取登录用户
UserDTO user = UserHolder.getUser();
blog.setUserId(user.getId());
// 保存探店博文
boolean isSuccess = save(blog);
if(!isSuccess){
return Result.fail("新增笔记失败");
}
// 3.查询笔记作者的所有粉丝
List<Follow> follows = followService.query()
.eq("follow_user_id", user.getId()).list();
// 4.推送笔记id给粉丝
for(Follow follow : follows){
// 获取粉丝id
Long userId = follow.getUserId();
// 推送
String key = FEED_KEY + userId;
stringRedisTemplate.opsForZSet().add(key, blog.getId().toString(), System.currentTimeMillis());
}
// 返回id
return Result.ok(blog.getId());
}
@Override
public Result queryBlogOfFollow(Long max, Integer offset) {
Long userId = UserHolder.getUser().getId();
// 1.查询收件箱
String key = FEED_KEY + userId;
Set<ZSetOperations.TypedTuple<String>> typedTuples = stringRedisTemplate.opsForZSet()
.reverseRangeByScoreWithScores(key, 0, max, offset, 2);
if(typedTuples == null || typedTuples.isEmpty()){
return Result.ok();
}
// 2.解析数据:blodId,minTime(时间戳),offset
List<Long> ids = new ArrayList<>(typedTuples.size());
long minTime = 0;
int os = 1;
for(ZSetOperations.TypedTuple<String> tuple : typedTuples){
//获取id
ids.add(Long.valueOf(tuple.getValue()));
//获取分数(时间戳)
long time = tuple.getScore().longValue();
if(time == minTime){
os++;
}else{
minTime = time;
os = 1;
}
}
// 3.根据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){
// 3.1.查询blog相关的用户
queryBlogUser(blog);
// 3.2查询blog是否被点赞
isBlogLiked(blog);
}
// 4.封装并返回
ScrollResult r = new ScrollResult();
r.setList(blogs);
r.setOffset(os);
r.setMinTime(minTime);
return Result.ok(r);
}