在上一篇文章,我们介绍了如何实现类似 CSDN 的评论与回复。但是,在实际项目中,由于管理端的原型图做出来的晚,所以上面的代码完成之后,才知道关于评论模块除了基本的审核外,还要设置设置是否开启评论,以及评论权限是所有人还是仅登录用户
注:管理端一般都会涉及权限管理(多权),在管理端不清楚的情况下,一定要在代码中留好扩展点
所以,我们在数据库再新增一张 function 表,里面保存了配置的权限
1.实现是否开启评论
1)关于是否开启评论,我们可以通过一个拦截器实现
@Component
public class CommentStateInterceptor extends HandlerInterceptorAdapter {
@Autowired
private FunctionDao functionDao; // 查询配置信息
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception{
Function fun = new Function();
fun.setFunName("文章评论");
// 如果文章评论的 fun_state 为 1,则评论开始,则可以评论
if(this.functionDao.selectOne(fun).getFunState() == FunctionTypeRole.COMMENT_ON){
return true;
// 否则评论关闭,拦截请求
}else{
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
return false;
}
}
}
注:也可以将配置信息放到 Redis
2)配置拦截路径:
@Configuration
public class MvcConfig implements WebMvcConfigurer {
@Autowired
private LoginInterceptor loginInterceptor;
@Autowired
private CommentStateInterceptor commentStateInterceptor;
public void addInterceptors(InterceptorRegistry registry){
// 评论开启拦截
registry.addInterceptor(commentStateInterceptor).addPathPatterns("/comment")
.addPathPatterns("/reply");
// 登录拦截
registry.addInterceptor(loginInterceptor).addPathPatterns("/user/detail")
.addPathPatterns("/comment") // 评论
.addPathPatterns("/reply") // 回复
.addPathPatterns("/like")
.addPathPatterns("/upload/**")
}
}
2.实现评论权限管理
1)如果是只能登录的人评论,那么到上面就完成了,但是我们还要允许未登录的人(游客)能评论,所以就不能直接用 LoginInterceptor 了,需要再自定义一个权限拦截器
@Component
public class CommentRoleInterceptor extends HandlerInterceptorAdapter {
@Autowired
private FunctionDao functionDao; // 获取配置信息
@Resource
private JwtProperties jwtProperties; // 获取 cookie 及 token 信息
private static final ThreadLocal<Long> THREAD_LOCAL = new ThreadLocal<>();
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception{
Function function = new Function();
function.setFunName("评论权限");
// 如果评论权限是只有登录后才能评论
if(this.functionDao.selectOne(function).getFunState() == FunctionTypeRole.COMMENT_FOR_LOGIN){
// 校验 token
String cookieValue = CookieUtils.getCookieValue(request,jwtProperties.getCookieName());
if(StringUtils.isNotBlank(cookieValue)){
UserInfo info = JwtUtils.getInfoFromToken(cookieValue, jwtProperties.getPublicKey());
if(info != null){
THREAD_LOCAL.set(info.getId()); // 将 userId 放到 ThreadLocal
return true;
}
}
// token 校验失败则直接拦截请求
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
return false;
}
// 如果评论权限是所有人都能评论
String cookieValue = CookieUtils.getCookieValue(request,jwtProperties.getCookieName());
if(StringUtils.isNotBlank(cookieValue)){
UserInfo info = JwtUtils.getInfoFromToken(cookieValue, jwtProperties.getPublicKey());
if(info != null){
// 将 userId 放到 ThreadLocal
// 如果是未登录的用户,则此时 userId 为 null
THREAD_LOCAL.set(info.getId());
}
}
return true;
}
// 获取 ThreadLocal 中的 userId
public static Long getUserId(){
return THREAD_LOCAL.get();
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
THREAD_LOCAL.remove();
}
}
2)修改拦截路径配置
@Configuration
public class MvcConfig implements WebMvcConfigurer {
@Autowired
private CommentStateInterceptor commentStateInterceptor;
@Autowired
private CommentRoleInterceptor commentRoleInterceptor;
public void addInterceptors(InterceptorRegistry registry){
// 评论开启拦截
registry.addInterceptor(commentStateInterceptor).addPathPatterns("/comment")
.addPathPatterns("/reply");
// 评论权限拦截
registry.addInterceptor(commentRoleInterceptor).addPathPatterns("/comment")
.addPathPatterns("/reply");
}
}
3)CommentService 保存评论的代码也要改
@Override
@Transactional
public Boolean insertComment(CommentDto commentDto) {
if(StringUtils.isBlank(commentDto.getContent())){
return false;
}
// 创建评论
Comment comment = new Comment();
comment.setArtId(commentDto.getArticleId());
// 根据设置的评论权限,判断当前用户能否评论
Function fun = new Function();
fun.setFunName("评论权限");
// 获取到 UserId
Long uId = CommentRoleInterceptor.getUserId();
// 如果是所有人都能评论 && 当前用户未登录
if(this.functionDao.selectOne(fun).getFunState() == FunctionTypeRole.COMMENT_FOR_ALL && uId == null){
// 将未登录用户的 userId 设置 0
comment.setComAuthor(Long.valueOf(000));
// 将未登录用户的 username 设置为 游客_随机串
comment.setComAuthorName("游客_"+ StringUtils.substring(UvInterceptor.getVisitId(),0,8));
// 只有登录后才能评论
// 注:此时,未登录的请求已经被过滤
}else{
comment.setComAuthor(uId);
comment.setComAuthorName(this.userDetailService.selectUsernameById(uId));
}
comment.setComContent(commentDto.getContent());
comment.setComCreate(new Date());
// 将评论添加到数据库
this.commentDao.insertSelective(comment);
// commentCount++
this.articleDao.updateCommentCount(commentDto.getArticleId());
return true;
}
关于回复的权限,ReplyService 的修改同上,就不列出了。
本文标题:【项目杂记】实现文章评论开关及权限管理
本文链接:https://blog.quwenai.cn/post/9852.html
版权声明:本文不使用任何协议授权,您可以任何形式自由转载或使用。








还没有评论,来说两句吧...