项目-22-置顶、加精、删除

置顶、加精、删除

1.导包thymeleaf和springsecurity5的整合

		<dependency>
			<groupId>org.thymeleaf.extras</groupId>
			<artifactId>thymeleaf-extras-springsecurity5</artifactId>
		</dependency>

功能实现

  • 点击“置顶”、“加精”、“删除”,修改帖子的状态

    在DiscussPostMapper增加修改方法

    	 //置顶帖子 加精帖子的方法
        int updateType(int id, int type);
        int updateStatus(int id, int status);
    

    DiscussPostService、DiscussPostController相应增加方法,注意在Es中同步变化

        <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>
        ------------------------
            //置顶
        public int updateType(int id, int type){
            return discussPostMapper.updateType(id, type);
        }
    
        public int updateStatus(int id, int status){
            return discussPostMapper.updateType(id, status);
        }
        --------------------------
        //置顶
    
        /**
         *
         * @param id 帖子id
         * @return
         */
        @RequestMapping(path = "/top",method = RequestMethod.POST)
        @ResponseBody
        public String setTop(int id){
            discussPostService.updateType(id,1);
            //将帖子数据同步到es
            Event event = new Event()
                    .setTopic(TOPIC_PUBLISH)
                    .setEntityType(ENTITY_TYPE_POST)
                    .setEntityId(id)
                    .setUserId(hostHolder.getUser().getId());
    
            eventProducer.fireEvent(event);
    
            return CommunityUtil.getJSONString(0);
        }
    
        //加精
        @RequestMapping(path = "/wonderful",method = RequestMethod.POST)
        @ResponseBody
        public String setWonderful(int id){
            discussPostService.updateStatus(id,1);
            //将帖子数据同步到es
            Event event = new Event()
                    .setTopic(TOPIC_PUBLISH)
                    .setEntityType(ENTITY_TYPE_POST)
                    .setEntityId(id)
                    .setUserId(hostHolder.getUser().getId());
    
            eventProducer.fireEvent(event);
    
            return CommunityUtil.getJSONString(0);
        }
    
        //删除
        @RequestMapping(path = "/delete",method = RequestMethod.POST)
        @ResponseBody
        public String setDelete(int id){
            discussPostService.updateStatus(id,2);
            //从es删除帖子
            Event event = new Event()
                    .setTopic(TOPIC_DELETE)
                    .setEntityType(ENTITY_TYPE_POST)
                    .setEntityId(id)
                    .setUserId(hostHolder.getUser().getId());
            eventProducer.fireEvent(event);
    
            return CommunityUtil.getJSONString(0);
        }
    
    • 要在EventConsumer增加消费删帖事件
        //消费者发帖的方法
        //监听主题为TOPIC_PUBLISH的事件
        @KafkaListener(topics = {TOPIC_PUBLISH})
        public void handlePublishMessage(ConsumerRecord record){
            //判断是否为空
            if (record == null || record.value() == null){
                logger.error("消息的内容为空");
                return;
            }
            //获取生产者的event,通过获得的json字符串转换为Event对象
            Event event = JSONObject.parseObject(record.value().toString(), Event.class);
    
            if (event == null){
                logger.error("消息格式错误");
                return;
            }
    
            //查询帖子信息
            DiscussPost discussPost = discussPostService.findDiscussPostById(event.getEntityId());
            //存入es
            elasticsearchService.saveDiscussPost(discussPost);
        }
    
        //删除帖子
        @KafkaListener(topics = {TOPIC_DELETE})
        public void handleDeleteMessage(ConsumerRecord record){
            //判断是否为空
            if (record == null || record.value() == null){
                logger.error("消息的内容为空");
                return;
            }
            //获取生产者的event,通过获得的json字符串转换为Event对象
            Event event = JSONObject.parseObject(record.value().toString(), Event.class);
    
            if (event == null){
                logger.error("消息格式错误");
                return;
            }
    
            //删除es
            elasticsearchService.deleteDiscussPost(event.getEntityId());
        }
    

    修改html和js文件

    discusspost-detail.html

    <!-- 添加 thymeleaf和spring-security整合的信息-->
    <html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
    
    <!-- 标题 -->
    <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>
    	<button type="button" class="btn btn-danger btn-sm" id="wonderfulBtn"     th:disabled="${post.status==1}" sec:authorize="hasAnyAuthority('moderator')">加精 
      </button>
        <button type="button" class="btn btn-danger btn-sm" id="deleteBtn"
     		th:disabled="${post.status==2}" sec:authorize="hasAnyAuthority('admin')">删除
        </button>
    </div>
    

    discuss.js

    /*在加载静态页面后调用以下3个方法:置顶 加精 删除*/
    $(function () {
        $("#topBtn").click(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()},
            function (data) {
                data = $.parseJSON(data);
                if (data.code==0){
                    $("#topBtn").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);
                }
            }
        );
    }
    

权限管理

  • 版主可以执行“置顶”、“加精”操作。管理员可以执行“删除”操作。
    • 在SecurityConfig类下配置,置顶、加精、删除的访问权限。

按钮显示

  • 版主可以看到“置顶”、“加精”按钮。管理员可以看到“删除“按钮。
    • 导包:thymeleaf-extras-springsecurity5,thymeleaf对security的支持。
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.access.AccessDeniedHandler;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

//Security的配置类
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter implements CommunityConstant {

    //忽略静态资源,不对静态资源进行拦截
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/resources/**");
    }

    //授权
    @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// 权限: 版主
                )
                // 对于以下列出的所有路径
                .antMatchers(
                        "/discuss/delete",
                        "/data/**"
                )
                // 只有具有以下列出的权限才可以访问
                .hasAnyAuthority(
                        AUTHORITY_ADMIN
                )
                // 除了以上列出的权限限制约定外,其他请求路径都放行
                .anyRequest().permitAll()
                //
                .and().csrf().disable();

        //权限不够时
        // 如果权限不够时的处理
        http.exceptionHandling()
                // 没有登录时的处理
                .authenticationEntryPoint(new AuthenticationEntryPoint() {
                    // 没有登录时的处理方法
                    @Override
                    public void commence(HttpServletRequest request,
                                         HttpServletResponse response,
                                         AuthenticationException e)
                            throws IOException, ServletException {
                        // 如果请求x-requested-with 中头包含XMLHttpRequest 说明是异步请求
                        String xRequestedWith = request.getHeader("x-requested-with");
                        if ("XMLHttpRequest".equals(xRequestedWith)) {
                            // 设置响应体是json 格式(因为是异步请求,所以返回内容要是json格式)
                            response.setContentType("application/plain;charset=utf-8");
                            // 拿到输出流,输出返回内容给前端页面
                            PrintWriter writer = response.getWriter();
                            writer.write(CommunityUtil.getJSONString(403, "你还没有登录哦!"));
                        } else {// 不是异步请求
                            // 重定向到登录页面
                            response.sendRedirect(request.getContextPath() + "/login");
                        }
                    }
                })
                // 拒绝访问(权限不足时的处理)
                .accessDeniedHandler(new AccessDeniedHandler() {
                    // 权限不足
                    @Override
                    public void handle(HttpServletRequest request,
                                       HttpServletResponse response,
                                       AccessDeniedException e)
                            throws IOException, ServletException {
                        String xRequestedWith = request.getHeader("x-requested-with");
                        if ("XMLHttpRequest".equals(xRequestedWith)) {
                            // 设置响应体是json 格式(因为是异步请求,所以返回内容要是json格式)
                            response.setContentType("application/plain;charset=utf-8");
                            // 拿到输出流,输出返回内容给前端页面
                            PrintWriter writer = response.getWriter();
                            writer.write(CommunityUtil.getJSONString(403, "你没有访问此功能的权限!"));
                        } else {// 不是异步请求
                            // 重定向到没有权限页面
                            response.sendRedirect(request.getContextPath() + "/denied");
                        }
                    }
                });

        // Security底层默认会拦截/logout请求,进行退出处理.
        // 覆盖它默认的逻辑,才能执行我们自己的退出代码.
        http.logout().logoutUrl("/securitylogout");
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值