



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 {@Resourceprivate IUserService userService;private final StringRedisTemplate stringRedisTemplate;public FollowServiceImpl(StringRedisTemplate stringRedisTemplate) {this.stringRedisTemplate = stringRedisTemplate;}@Overridepublic 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){//存到redisstringRedisTemplate.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();}@Overridepublic 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);}@Overridepublic 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.解析idList<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);}
}
@Overridepublic 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){// 获取粉丝idLong userId = follow.getUserId();// 推送String key = FEED_KEY + userId;stringRedisTemplate.opsForZSet().add(key, blog.getId().toString(), System.currentTimeMillis());}// 返回idreturn Result.ok(blog.getId());}@Overridepublic 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(时间戳),offsetList<Long> ids = new ArrayList<>(typedTuples.size());long minTime = 0;int os = 1;for(ZSetOperations.TypedTuple<String> tuple : typedTuples){//获取idids.add(Long.valueOf(tuple.getValue()));//获取分数(时间戳)long time = tuple.getScore().longValue();if(time == minTime){os++;}else{minTime = time;os = 1;}}// 3.根据id查询blogString 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);}