什么是Feed流?
feed流即持续更新并呈现给用户内容的信息流。feed是将用户主动订阅的若干消息源组合在一起形成内容聚合器,帮助用户持续地获取最新的订阅源内容。
feed直接翻译是饲料的意思,其实是把用户都比喻成爱吃东西得某种动物,不断的给他喂食,满足他的需求,wiki百科上定义是一种数据格式,网站可通过它将最新信息传播给用户,用户能够订阅网站的先决条件是网站可提供持续更新的信息。
流,就是他的呈现形式,就是这个信息怎么呈现的,大多数的都是根据时间排列的形式呈现的。
应用场景
使用了feed流的APP有很多,例如:微信朋友圈、百度信息流、今日头条推荐页等等。
代码实现
模拟下抖音网红发布新作品后抄送到粉丝关注可见
public R addBLong(Blog blog) {
//获取当前用户信息
UserDto userDto = threadLocal.get();
//新增数据
boolean isSuccess = save(blog.setUserId(userDto.getId()));
if (!isSuccess) {
return R.error("新增失败");
}
//查询作者的所有粉丝
List<Follow> follows = followService.query()
.eq("follow_user_id", userDto.getId()).list();
//推送给所有粉丝
String key = "all:follows:";
follows.stream().forEach(
follow -> stringRedisTemplate.opsForZSet().add(
key + follow.getUserId(),
blog.getId(),
System.currentTimeMillis()));
return R.ok().data("data", blog.getId());
}
粉丝登陆后查询接口实现
public R queryBLongOfFollow(Long max, Integer offset) {
//获取当前用户id
String userId = threadLocal.get().getId();
//key
String key = "all:follows:" + userId;
//查询收件箱
Set<ZSetOperations.TypedTuple<String>> typedTuples = stringRedisTemplate.opsForZSet().
reverseRangeByScoreWithScores(key, 0, max, offset, 2);
if (typedTuples == null || typedTuples.isEmpty()) {
return R.ok();
}
//笔记id集合
ArrayList<String> listIds = new ArrayList<>(typedTuples.size());
//记录最小的时间戳
long minTime = 0;
//offset最小的时间戳出现的个数,用来跳过相同分数避免重复数据查询
int os = 1;
for (ZSetOperations.TypedTuple<String> tuple : typedTuples) {
//笔记id
String blogId = tuple.getValue();
listIds.add(blogId);
//时间戳
long time = tuple.getScore().longValue();
if (minTime == time) {
os++;
} else {
minTime = time;
os = 1;
}
}
//将笔记id集合以,拼接
String idsStr = StrUtil.join(",", listIds);
//按照顺序查询笔记集合
List<Blog> blogList = query().in("id", listIds)
.last("order by field(id," + idsStr + ")").list();
for (Blog b : blogList) {
isLikeBLong(b);
if (b == null) {
return R.error("查询失败");
}
User user = userService.query().eq("id", b.getUserId()).one();
b.setUser(user);
}
ScrollResult result = new ScrollResult();
result.setList(blogList);
result.setMinTime(minTime);
result.setOffset(os);
return R.ok().data("result",result);
}