关注、取关、Redis实现共同关注、 博客推送与分页查询

@Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private IUserService userService;
    @Override
    public Result follow(Long followUserId, Boolean isFollow) {
        //1.获取登陆的用户
        Long userId = UserHolder.getUser().getId();
        //1.判断是关注还是取关
        if(isFollow){
            //关注,新增数据
            Follow follow = new Follow();
            follow.setUserId(userId);
            follow.setFollowUserId(followUserId);
            boolean isSuccess = this.save(follow);
            if(isSuccess){
                // 把关注用户的id,放入到redis的set集合 sadd userId followerUserId
                String key = "follows:" + userId;
                stringRedisTemplate.opsForSet().add(key, followUserId.toString());
            }
        }else {
            //取关,删除
            QueryWrapper<Follow> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("follow_user_id", followUserId).eq("user_id", userId);
            boolean isSuccess = this.remove(queryWrapper);
            if(isSuccess){
                //从redis集合中移除
                String key = "follows:" + userId;
                stringRedisTemplate.opsForSet().remove(key, followUserId.toString());
            }

        }
        return Result.ok();
    }

    @Override
    public Result isFollow(Long followUserId) {
        //1.获取登陆的用户
        Long userId = UserHolder.getUser().getId();
        //查询是否关注
        Integer count = this.query().eq("follow_user_id", followUserId).eq("user_id", userId).count();
        return Result.ok(count > 0);
    }

    @Override
    public Result followCommons(Long id) {
        //获取当前的用户
        Long userId = UserHolder.getUser().getId();
        //知道两个用户在Redis中求交集
        String key1 = "follows:" + userId;
        String key2 = "follows:" + id;
        Set<String> intersect = stringRedisTemplate.opsForSet().intersect(key1, key2);
        if(intersect == null || intersect.isEmpty()){
            //无交集
            return Result.ok(Collections.emptyList());
        }
        //通过Set集合解析出Id集合
        List<Long> ids = intersect.stream().map(Long::valueOf).collect(Collectors.toList());
        //查询用户
        List<UserDTO> users = userService.listByIds(ids)
                .stream()
                .map(user -> BeanUtil.copyProperties(user, UserDTO.class))
                .collect(Collectors.toList());
        return Result.ok(users);
    }

 博客推送与分页查询

 查询的控制层

    @GetMapping("/of/follow")
    public Result queryBlogOfFollow(@RequestParam("lastId") Long max, @RequestParam(value = "offset", defaultValue = "0") Integer offset){
        return blogService.queryBlogOfFollow(max, offset);
    }

 发布与查询的服务层

    //大V发布,并进行推送
    @Override
    public Result saveBlog(Blog blog) {
        // 获取登录用户
        UserDTO user = UserHolder.getUser();
        blog.setUserId(user.getId());
        // 保存探店博文
        boolean isSuccess = this.save(blog);
        if(!isSuccess){
            return Result.fail("新增笔记失败");
        }
        //查询笔记作者的所有粉丝  follow_user_id时大V的id
        List<Follow> follows = followService.query().eq("follow_user_id", user.getId()).list();
        //推送笔记id给所有粉丝
        for (Follow follow : follows) {
            //获取粉丝id
            Long userId = follow.getUserId();
            //推送
            String key = "feed:" + userId;
            stringRedisTemplate.opsForZSet().add(key, blog.getId().toString(), System.currentTimeMillis());
        }
        // 返回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);
        //非空判断
        if(typedTuples == null || typedTuples.isEmpty()){
            return Result.ok();
        }
        //3.解析数据:blogId,minTime(时间戳)、offset
        List<Long> ids = new ArrayList<>(typedTuples.size());
        long minTime = 0;
        int os = 1; //最少为一个与最小一样
        for (ZSetOperations.TypedTuple<String> typedTuple : typedTuples) {
            //获取id
            ids.add(Long.valueOf(typedTuple.getValue()));
            //获取分数
            long time = typedTuple.getScore().longValue();
            if(time == minTime){
                os++;
            }else {
                minTime = time;
                os = 1;
            }
        }
        //4.根据id查询blog
        String idStr = StrUtil.join(",", ids);
        List<Blog> blogs = this.query().in("id", ids).last("ORDER BY FIELD(id," + idStr + ")").list();
        for (Blog blog : blogs) {
            //查询blog有关的用户
            this.queryBlogUser(blog);
            //查询blog是否被点赞
            this.isBlogLiked(blog);
        }
        //5.封装并返回
        ScrollResult r = new ScrollResult();
        r.setList(blogs);
        r.setOffset(os);
        r.setMinTime(minTime);
        return Result.ok(r);
    }

### 回答1: BootstrapValidator是一个基于Bootstrap框架的jQuery表单验证插件。它可以用来验证各种类型的表单元素,如文本框、下拉框、单选按钮等。它支持多种验证方式,如长度限制、数字范围、邮箱格式等。使用BootstrapValidator可以轻松地在表单中添加验证功能,提高用户体验。 ### 回答2: bootstrapvalidator是一个基于Bootstrap框架的表单验证插件。它通过添加各种验证规则和选项,能够为表单提供强大的实时验证功能。 使用bootstrapvalidator可以轻松地对用户的输入进行验证,确保数据的准确性和完整性。它支持各种验证类型,如必填字段验证、长度验证、数字验证、邮箱验证、密码强度验证等等。你只需简单地在表单元素上添加相应的验证规则,bootstrapvalidator就会自动实时验证输入的数据,并在错误发生时提供错误消息。 通过bootstrapvalidator的配置选项,你可以根据需要定制验证的方式和提示信息。它提供了丰富的回调函数,可以在验证通过或验证失败时执行相应的操作。你可以用自定义的错误消息替换默认的提示信息,或者修改验证的样式以适应你的网站风格。 bootstrapvalidator的使用非常简便,只需在页面中引入相关的CSS和JavaScript文件,并在表单元素上添加相应的class和data属性即可。其官方文档提供了详细的使用说明和示例代码,帮助你快速上手。 总而言之,bootstrapvalidator是一个功能强大、灵活易用的表单验证插件。它可以帮助开发者简化表单验证的过程,提高用户输入数据的准确性和完整性。无论是开发响应式网站还是移动应用,bootstrapvalidator都是一个不错的选择。 ### 回答3: BootstrapValidator是一个基于Bootstrap的表单验证插件。它提供了一套简单易用的验证规则和方法,可以方便地对表单进行前端验证。使用BootstrapValidator可以减少后端的验证压力,提高用户体验。 BootstrapValidator支持多种常见的验证规则,比如必填字段、电子邮件格式、URL格式、数字范围等等。通过设置相应的选项,可以定义验证规则,并在表单提交之前对数据进行验证。验证结果会实时显示在表单中,如果数据不符合规则,会给出相应的错误提示。 使用BootstrapValidator,可以灵活地自定义验证规则和错误提示信息。可以根据需要,自定义正则表达式验证规则,或者自定义提示信息的显示方式。 BootstrapValidator还支持在表单提交之前进行远程验证。可以通过AJAX请求向后端发送数据,并根据返回结果判断数据是否合法。 总的来说,BootstrapValidator是一个简单、易用且功能强大的表单验证插件。它可以减少开发者在后端处理表单验证的工作量,提高用户体验。使用BootstrapValidator,可以轻松地实现表单验证功能,保证数据的准确性和完整性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值