博客项目目录: 请戳这里
准备
需求:用户登录后,点击帖子,进入详情页。点击收藏,按钮会变为取消收藏,表示帖子已被收藏,点击取消收藏,按钮又会变回收藏,表示帖子已从收藏表移除。
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