三个功能实现非常相似,可以一并开发完
按钮显示中 thymeleaf可以支持security的一些标签
一、功能实现:
1.数据访问层
无论是置顶、删除、加精都要对帖子进行处理,因此先打开DiscussPostMapper接口,增加几个方法。
int updateType(int id, int type);
int updateStatus(int id, int status);
int updateScore(int id, double score);
然后打开对应配置文件,增加:
<update id="updateType">
update discuss_post set type = #{type} where id = #{id}
</update>
<update id="updateStatus">
update discuss_post set status = #{status} where id = #{id}
</update>
<update id="updateScore">
update discuss_post set score = #{score} where id = #{id}
</update>
在DiscussPostService类中,新加:
public int updateType(int id, int type) {
return discussPostMapper.updateType(id, type);
}
public int updateStatus(int id, int status) {
return discussPostMapper.updateStatus(id, status);
}
public int updateScore(int id, double score) {
return discussPostMapper.updateScore(id, score);
}
2.表现层
在DiscussPostController中
// 加精
@RequestMapping(path = "/wonderful", method = RequestMethod.POST)
@ResponseBody
public String setWonderful(int id) {
discussPostService.updateStatus(id, 1);
// 触发发帖事件
Event event = new Event()
.setTopic(TOPIC_PUBLISH)
.setUserId(hostHolder.getUser().getId())
.setEntityType(ENTITY_TYPE_POST)
.setEntityId(id);
eventProducer.fireEvent(event);
// 删除
@RequestMapping(path = "/delete", method = RequestMethod.POST)
@ResponseBody
public String setDelete(int id) {
discussPostService.updateStatus(id, 2);//删除状态是2
// 触发ES删帖事件
Event event = new Event()
.setTopic(TOPIC_DELETE)
.setUserId(hostHolder.getUser().getId())
.setEntityType(ENTITY_TYPE_POST)
.setEntityId(id);
eventProducer.fireEvent(event);
return CommunityUtil.getJSONString(0);
}
在event consumer中
// 消费删帖事件
@KafkaListener(topics = {TOPIC_DELETE})
public void handleDeleteMessage(ConsumerRecord record) {
if (record == null || record.value() == null) {
logger.error("消息的内容为空!");
return;
}
Event event = JSONObject.parseObject(record.value().toString(), Event.class);
if (event == null) {
logger.error("消息格式错误!");
return;
}
elasticsearchService.deleteDiscussPost(event.getEntityId());
}
接下来处理模板。
置顶、加精、删除是在帖子详情页面上操作的。
在discuss.js中,
$(function(){// 该函数在页面加载完之后进行处理
$("#topBtn").click(setTop);//函数名setTop,当点击按钮的时候,执行setTop函数
$("#wonderfulBtn").click(setWonderful);
$("#deleteBtn").click(setDelete);
});
function like(btn, entityType, entityId, entityUserId, postId) {
$.post(
CONTEXT_PATH + "/like",
{"entityType":entityType,"entityId":entityId,"entityUserId":entityUserId,"postId":postId},
function(data) {
data = $.parseJSON(data);
if(data.code == 0) {
$(btn).children("i").text(data.likeCount);
$(btn).children("b").text(data.likeStatus==1?'已赞':"赞");
} else {
alert(data.msg);
}
}
);
}
// 置顶
function setTop() {
$.post(
CONTEXT_PATH + "/discuss/top",//第一个参数是要提交的路径
{"id":$("#postId").val()},//key是id,值是
function(data) {//处理响应的结果
data = $.parseJSON(data);//解析为js对象
if(data.code == 0) {
$("#topBtn").attr("disabled", "disabled");//点击置顶以后,可以把按钮设置为不可用。attr修改属性,将disabled属性修改为disabled
} else {
alert(data.msg);//否则给出错误提示
}
}
);
}
// 加精
function setWonderful() {
$.post(
CONTEXT_PATH + "/discuss/wonderful",
{"id":$("#postId").val()},
function(data) {
data = $.parseJSON(data);
if(data.code == 0) {
$("#wonderfulBtn").attr("disabled", "disabled");
} else {
alert(data.msg);
}
}
);
}
// 删除
function setDelete() {
$.post(
CONTEXT_PATH + "/discuss/delete",
{"id":$("#postId").val()},
function(data) {
data = $.parseJSON(data);
if(data.code == 0) {
location.href = CONTEXT_PATH + "/index";//删除帖子后 直接返回到首页
} else {
alert(data.msg);
}
}
);
}
在 discuss-detail.html中
<div class="float-right">
<input type="hidden" id="postId" th:value="${post.id}"><!-- 在置顶、加精、删除之前加隐藏框-->
<button type="button" class="btn btn-danger btn-sm" id="topBtn"
th:disabled="${post.type==1}" sec:authorize="hasAnyAuthority('moderator')">置顶</button><<!-- th:disabled="${post.type==1}"表示判断当前类型是不是1,如果是1的话,说明已经置顶,则此按钮不可用 --> <!--加id是为了之后定义js事件方便 id=topBtn -->
<button type="button" class="btn btn-danger btn-sm" id="wonderfulBtn"
th:disabled="${post.status==1}" sec:authorize="hasAnyAuthority('moderator')">加精</button><!-- id=wonderfulBtn-->
<button type="button" class="btn btn-danger btn-sm" id="deleteBtn"
th:disabled="${post.status==2}" sec:authorize="hasAnyAuthority('admin')">删除</button><!-- id=deleteBtn-->
</div>
测试:
点击以后变灰了
功能实现已经处理完毕,接下来处理权限管理。
配置权限:在SecurityConfig中
@Override
protected void configure(HttpSecurity http) throws Exception {
// 授权
http.authorizeRequests()
.antMatchers(
"/user/setting",//设置
"/user/upload",//上传头像
"/discuss/add",//发帖
"/comment/add/**",//添加评论
"/letter/**",//私信所有的功能
"/notice/**",//通知,登录才能接收通知
"/like",//点赞
"/follow",
"/unfollow"
)
.hasAnyAuthority(//对以上路径,只要拥有以下任意一个权限,就可以访问
AUTHORITY_USER,
AUTHORITY_ADMIN,
AUTHORITY_MODERATOR
)
//以下是新添加的权限管理
.antMatchers(
"/discuss/top",//置顶路径
"/discuss/wonderful"//加精路径
)
.hasAnyAuthority(
AUTHORITY_MODERATOR//MODERATOR才有置顶、加精权限
)
.antMatchers(
"/discuss/delete",//删除路径
"/data/**"
)
.hasAnyAuthority(
AUTHORITY_ADMIN//ADMIN才有删除权限
)
.anyRequest().permitAll()//除了以上请求外,都允许
.and().csrf().disable();
测试:
当没有登录权限而点击置顶的时候:
用一个普通用户账号登录后,
前三个是管理员,管理员有删除权限,没有置顶和加精的权限
后五个是版主,版主没有删除权限。
对于没有置顶和加精的权限的用户,还是会显示这俩个按钮,那么如何不显示呢?
三、按钮显示:
需要一个组件 以在模板上获得当前用户的权限。
将discuss-detail.html中的这句话 替换为
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
表示thymeleaf 语法以 th 为前缀;而另一个语法以 sec 为前缀(表示security安全)
这个便是设置权限
管理员只能看删除
版主: