博客项目学习笔记二十一:收藏帖子

博客项目目录: 请戳这里

准备

需求:用户登录后,点击帖子,进入详情页。点击收藏,按钮会变为取消收藏,表示帖子已被收藏,点击取消收藏,按钮又会变回收藏,表示帖子已从收藏表移除。
在这里插入图片描述

1.在category.ftl和detail.ftl添加对应js

  <script>
      layui.cache.page = 'jie';
  </script>

这个js会触发res包下的jie.js
对应js代码:

//异步渲染
  var asyncRender = function(){
    var div = $('.fly-admin-box'), jieAdmin = $('#LAY_jieAdmin');
    //查询帖子是否收藏
    if(jieAdmin[0] && layui.cache.user.uid != -1){
      fly.json('/collection/find/', {
        cid: div.data('id')
      }, function(res){
        jieAdmin.append('<span class="layui-btn layui-btn-xs jie-admin '+ (res.data.collection ? 'layui-btn-danger' : '') +'" type="collect" data-type="'+ (res.data.collection ? 'remove' : 'add') +'">'+ (res.data.collection ? '取消收藏' : '收藏') +'</span>');
      });
    }
  }();

运行项目,进入详情页后,会显示如下:
在这里插入图片描述

这里将原来的“123”改为实际的id,并且不要引号:
在这里插入图片描述

2.在controller层添加查询收藏方法

这段代码意思是找到当前用户,当前文章在收藏表是否存在,如果存在,则count必然大于0

	//判断用户是否收藏了文章
    @ResponseBody
    @PostMapping("/collection/find/")
    public Result collectionFind(Long cid) {
        int count = collectionService.count(new QueryWrapper<UserCollection>()
                .eq("user_id", getProfileId())
                .eq("post_id", cid)
        );
        return Result.success(MapUtil.of("collection", count > 0 ));
    }

在BaseController下注入对应Service:
在这里插入图片描述
测试:
在这里插入图片描述
发现cid变为实际的帖子id
在这里插入图片描述
按钮为取消收藏,说明在收藏表有查到帖子,并且相应信息为true,也说明在收藏表找到了帖子

3.在controller层添加收藏和取消收藏方法

从下面代码可以看出,当请求为/collection/add时,表示收藏;当请求为/collection/remove时,表示取消收藏
在这里插入图片描述
对于收藏文章,首先通过cid找到文章,然后声明是否已被删除,之后在收藏表查找,如果找到,则返回已经收藏,如果没找到,则将相关信息加入收藏表。
对于取消收藏,同样通过cid找到文章,生命是否已被删除,然后直接在收藏表删除对应文章。

	//收藏当前文章
    @ResponseBody
    @PostMapping("/collection/add/")
    public Result collectionAdd(Long cid) {
        Post post = postService.getById(cid);

        Assert.isTrue(post != null, "改帖子已被删除");
        int count = collectionService.count(new QueryWrapper<UserCollection>()
                .eq("user_id", getProfileId())
                .eq("post_id", cid)
        );
        if(count > 0) {
            return Result.fail("你已经收藏");
        }

        UserCollection collection = new UserCollection();
        collection.setUserId(getProfileId());
        collection.setPostId(cid);
        collection.setCreated(new Date());
        collection.setModified(new Date());

        collection.setPostUserId(post.getUserId());

        collectionService.save(collection);
        return Result.success();
    }

    //取消收藏的文章
    @ResponseBody
    @PostMapping("/collection/remove/")
    public Result collectionRemove(Long cid) {
        Post post = postService.getById(cid);
        Assert.isTrue(post != null, "改帖子已被删除");

        collectionService.remove(new QueryWrapper<UserCollection>()
                .eq("user_id", getProfileId())
                .eq("post_id", cid));

        return Result.success();
    }

测试:
进入详情页:
在这里插入图片描述
在这里插入图片描述
点击取消收藏:
在这里插入图片描述
在这里插入图片描述
按钮从取消收藏变为收藏,并且帖子也在收藏表被删除

4.自定义过滤器

问题描述:用户登录状态没有之后,在文章详情页点击收藏,应提示“请先登录”,而现在的情况是“请求异常,请重试”
在这里插入图片描述

定义过滤器:

  • 当用户请求的是ajax类型时,弹窗显示未登录
  • 当用户请求是普通web类型时,重定向到首页
public class AuthFilter extends UserFilter {

    @Override
    protected void redirectToLogin(ServletRequest request, ServletResponse response) throws IOException {

        HttpServletRequest httpServletRequest = (HttpServletRequest) request;

        // ajax 弹窗显示未登录
        String header = httpServletRequest.getHeader("X-Requested-With");
        if(header != null  && "XMLHttpRequest".equals(header)) {
            boolean authenticated = SecurityUtils.getSubject().isAuthenticated();
            if(!authenticated) {
                response.setContentType("application/json;charset=UTF-8");
                response.getWriter().print(JSONUtil.toJsonStr(Result.fail("请先登录!")));
            }
        } else {
            // web 重定向到登录页面
            super.redirectToLogin(request, response);
        }
    }
}

配置部分:

@Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
        ShiroFilterFactoryBean filterFactoryBean = new ShiroFilterFactoryBean();
        filterFactoryBean.setSecurityManager(securityManager);
        // 配置登录的url和登录成功的url
        filterFactoryBean.setLoginUrl("/login");
        filterFactoryBean.setSuccessUrl("/user/center");
        // 配置未授权跳转页面
        filterFactoryBean.setUnauthorizedUrl("/error/403");


        filterFactoryBean.setFilters(MapUtil.of("auth", authFilter()));

        Map<String, String> map = new LinkedHashMap<>();

        map.put("/res/**", "anon");

        map.put("/user/home", "auth");
        map.put("/user/set", "auth");
        map.put("/user/upload", "auth");

        map.put("/collection/remove/", "auth");
        map.put("/collection/find/", "auth");
        map.put("/collection/add/", "auth");

        map.put("/login","anon");

        filterFactoryBean.setFilterChainDefinitionMap(map);

        return filterFactoryBean;
    }

    @Bean
    public AuthFilter authFilter() {
        return new AuthFilter();
    }

测试:
在这里插入图片描述

参考资料:

https://github.com/MarkerHub/eblog

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值