zoukankan      html  css  js  c++  java
  • spring项目篇6----菜单的增删改查以及权限控制

    之前菜单都是写死的,现在做成可以变化的,首先创建一张menu的表

     使用mybatis的生成映射文件的插件,指定我们的表

    <table tableName="menu" />

    我们需要修改一下menu的pojo类

    public class Menu {
        private Integer id;
    
        private String text;
    
        private String url;
    
        private Menu parent;
    
        private Permission permission;
    
        private List<Menu> children = new ArrayList<>();
    }

    首先写controller层

    package com.yang.web;
    
    import com.yang.domain.AjaxRes;
    import com.yang.domain.Menu;
    import com.yang.domain.PageListRes;
    import com.yang.domain.QueryVo;
    import com.yang.service.MenuService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import java.util.List;
    
    @Controller
    public class MenuController {
    
        /*注入*/
        @Autowired
        private MenuService menuService;
    
        /*返回menu*/
        @RequestMapping("/menu")
        public String menu(){
            return "menu";
        }
    
        /*返回menu列表*/
        @RequestMapping("/menu/list")
        @ResponseBody
        public PageListRes menuList(QueryVo queryVo){
            return menuService.getMenuList(queryVo);
        }
    
        /*返回所有的菜单*/
        @RequestMapping("/menu/parent/list")
        @ResponseBody
        public List<Menu> parentList(){
            return menuService.getAll();
        }
    
        /*增加一个菜单*/
        @RequestMapping("/menu/add")
        @ResponseBody
        public AjaxRes menuAdd(Menu menu){
            return menuService.addMenu(menu);
        }
    
        /*更新菜单*/
        @RequestMapping("/menu/edit")
        @ResponseBody
        public AjaxRes menuUpdate(Menu menu){
            return menuService.updateMenu(menu);
        }
    
        /*删除菜单*/
        @RequestMapping("/menu/delete")
        @ResponseBody
        public AjaxRes menuUpdate(Integer id){
            return menuService.deleteMenu(id);
        }
    
        /*获取菜单结构树*/
        @RequestMapping("/menu/tree")
        @ResponseBody
        public List<Menu> menuTree(){
            return menuService.getMenuTree();
        }
    
    
    }

    接下来直接看业务层的实现类

    package com.yang.service.impl;
    
    import com.github.pagehelper.Page;
    import com.github.pagehelper.PageHelper;
    import com.yang.domain.*;
    import com.yang.mapper.MenuMapper;
    import com.yang.service.MenuService;
    import org.apache.shiro.SecurityUtils;
    import org.apache.shiro.subject.Subject;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;
    
    import java.util.Iterator;
    import java.util.List;
    
    @Service
    @Transactional
    public class MenuServiceImpl implements MenuService {
    
        /*注入mapper*/
        @Autowired
        private MenuMapper menuMapper;
    
        /*返回menu列表*/
        @Override
        public PageListRes getMenuList(QueryVo queryVo) {
            // 分页
            Page<Object> page = PageHelper.startPage(queryVo.getPage(), queryVo.getRows());
            // 查询
            List<Menu> menus = menuMapper.selectAll();
            // 封装返回结果
            PageListRes pageListRes = new PageListRes();
            pageListRes.setTotal(page.getTotal());
            pageListRes.setRows(menus);
            return pageListRes;
        }
    
        /*返回所有的菜单*/
        @Override
        public List<Menu> getAll() {
            return menuMapper.selectAll();
        }
    
        /*增加一个菜单*/
        @Override
        public AjaxRes addMenu(Menu menu) {
            AjaxRes ajaxRes = new AjaxRes();
            try{
                // 保存菜单
                menuMapper.insert(menu);
                ajaxRes.setSuccess(true);
                ajaxRes.setMsg("保存菜单成功");
            }catch (Exception e){
                ajaxRes.setMsg("保存菜单失败");
                ajaxRes.setSuccess(false);
            }
            return ajaxRes;
        }
    
        /*更新菜单*/
        @Override
        public AjaxRes updateMenu(Menu menu) {
            AjaxRes ajaxRes = new AjaxRes();
            try{
                // 获取待更新菜单父节点
                if(menu.getParent() != null){
                    Integer parentId = menuMapper.selectParentId(menu.getParent().getId());
                    if(parentId.equals(menu.getId())){
                        ajaxRes.setSuccess(false);
                        ajaxRes.setMsg("自己的子菜单不能设置为父菜单");
                        return ajaxRes;
                    }
                }
                // 更新菜单
                menuMapper.updateByPrimaryKey(menu);
                ajaxRes.setSuccess(true);
                ajaxRes.setMsg("保存菜单成功");
            }catch (Exception e){
                ajaxRes.setMsg("保存菜单失败");
                ajaxRes.setSuccess(false);
            }
            return ajaxRes;
        }
    
        /*删除菜单*/
        @Override
        public AjaxRes deleteMenu(Integer id) {
            AjaxRes ajaxRes = new AjaxRes();
            try{
                // 保存菜单
                menuMapper.deleteByPrimaryKey(id);
                ajaxRes.setSuccess(true);
                ajaxRes.setMsg("删除菜单成功");
            }catch (Exception e){
                ajaxRes.setMsg("删除菜单失败");
                ajaxRes.setSuccess(false);
            }
            return ajaxRes;
        }
    
        /*获取菜单结构树*/
        @Override
        public List<Menu> getMenuTree() {
            List<Menu> menus = menuMapper.getTreeMenu();
            // 进行权限认证
            // 首先获取当前主体
            Subject subject = SecurityUtils.getSubject();
            Employee employee = (Employee) subject.getPrincipal();
            // 判断当前用户是否是管理员,如果是,则跳过验证
            if(!employee.getAdmin()){
                // 进行权限认证
                checkPermission(menus);
            }
            return menus;
        }
    
        /*进行权限检验*/
        public void checkPermission(List<Menu> menus){
    
            // 获取主体
            Subject subject = SecurityUtils.getSubject();
            // 将菜单做成迭代器
            Iterator<Menu> iterator = menus.iterator();
            while (iterator.hasNext()){
                Menu menu = iterator.next();
                // 判断当前菜单是否需要进行权限校验
                if(menu.getPermission() != null){
                    // 获取权限
                    String resource = menu.getPermission().getResource();
                    if(!subject.isPermitted(resource)){
                        // 将当前菜单从迭代器中删除,没有权限
                        iterator.remove();
                        continue;
                    }
                }
                // 判断是否有子菜单
                if(menu.getChildren().size() >0){
                    checkPermission(menu.getChildren());
                }
            }
        }
    }

    修改一下插件帮助我们自动生成的映射文件

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.yang.mapper.MenuMapper">
      <resultMap id="BaseResultMap" type="com.yang.domain.Menu">
        <id column="id" jdbcType="INTEGER" property="id" />
        <result column="text" jdbcType="VARCHAR" property="text" />
        <result column="url" jdbcType="VARCHAR" property="url" />
    
        <!--封装父亲节点-->
        <association property="parent" javaType="com.yang.domain.Menu" columnPrefix="m_">
          <result property="id" column="id" />
          <result property="text" column="text" />
          <result property="url" column="url" />
        </association>
        <!--权限-->
        <association property="permission" javaType="com.yang.domain.Permission">
          <result property="id" column="p_id" />
          <result property="name" column="name" />
          <result property="resource" column="resource" />
        </association>
        <!--获取子菜单-->
        <collection property="children" ofType="com.yang.domain.Menu" select="listChildren" column="id"/>
      </resultMap>
      <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
        delete from menu
        where id = #{id,jdbcType=INTEGER}
      </delete>
      <insert id="insert" parameterType="com.yang.domain.Menu">
        insert into menu (id, text, url, parent_id)
        values (#{id,jdbcType=INTEGER}, #{text,jdbcType=VARCHAR}, #{url,jdbcType=VARCHAR}, 
          #{parent.id})
      </insert>
      <update id="updateByPrimaryKey" parameterType="com.yang.domain.Menu">
        update menu
        set text = #{text,jdbcType=VARCHAR},
          url = #{url,jdbcType=VARCHAR},
          parent_id = #{parent.id}
        where id = #{id,jdbcType=INTEGER}
      </update>
      <select id="selectAll" resultMap="BaseResultMap">
        select m1.id, m1.text, m1.url,
        m2.id as m_id, m2.text as m_text, m2.url as m_url from `menu` as m1
        left join `menu` as m2 on m1.parent_id = m2.id
        order by m1.id desc
      </select>
      <!--获取传入节点的父节点-->
      <select id="selectParentId" resultType="java.lang.Integer">
        select parent_id from `menu` where id=#{id}
      </select>
      <select id="getTreeMenu" resultMap="BaseResultMap">
        select m.id, m.text, m.url, m.parent_id, p.id as p_id, p.resource, p.name
        from `menu` as m
        left join `permission` as p
        on m.permission_id = p.id
        where m.parent_id is null;
      </select>
      <select id="listChildren" resultMap="BaseResultMap">
        select m.id, m.text, m.url, m.parent_id, p.id as p_id, p.resource, p.name
        from `menu` as m
        left join `permission` as p
        on m.permission_id = p.id
        where m.parent_id =#{id};
      </select>
    </mapper>

    接下来看一下前端页面的js代码

    首先修改一下index.js的代码

     $('#tree').tree({
            // 发送请求获取文件
            url:"menu/tree",
            。。。
    }

    menu.js文件

    $(function () {
        // 数据表格
        $('#dg').datagrid({
            url: "menu/list",
            columns: [[
                {field: "text", title: "名称",  100, align: "center"},
                {field: "url", title: "跳转地址",  100, align: "center"},
                {
                    field: "parent", title: "父菜单",  100, align: "center", formatter: function (value, row, index) {
                        return value ? value.text : "";
                    }
                },
            ]],
            fit: true,
            rownumbers: true,
            singleSelect: true,
            striped: true,
            pagination: true,
            fitColumns: true,
            toolbar: "#tb",
        });
    
        // 初始化增加/编辑对话框
        $('#dialog').dialog({
             300,
            height: 240,
            closed: true,
            buttons: "#menu_dialog_bt",
        });
    
        // 加载父级菜单
        $('#parentMenu').combobox({
             150,
            panelHeight: "auto",
            editable: false,
            url: "menu/parent/list",
            textField: "text",  // 显示内容
            valueField: "id",  // 传递内容
            onLoadSuccess: function () {
                /*数据加载完成之后的回调*/
                $('#parentMenu').each(function (i) {
                    let span = $(this).siblings("span")[i];
                    let targetInput = $(span).find("input:first");
                    if (targetInput) {
                        $(targetInput).attr("placeholder", $(this).attr("placeholder"))
                    }
                })
            }
    
        });
        /*添加功能*/
        $('#add').click(function () {
            $('#dialog').dialog("setTitle", "增加菜单");
            $('#menuForm').form("clear");
            $('#dialog').dialog("open")
        });
    
        /*编辑功能*/
        $('#edit').click(function () {
            // 清空表格内容
            $('#menuForm').form("clear");
            let rowData = $("#dg").datagrid("getSelected");
            if (!rowData) {
                $.messager.alert("温馨提示", "至少需要选择一条数据");
                return false;
            } else {
                /*回显的placeholder*/
                $("#parentMenu").each(function (i) {
                    let span = $(this).siblings("span")[i];
                    let targetInput = $(span).find("input:first");
                    if (targetInput) {
                        $(targetInput).attr("placeholder", $(this).attr("placeholder"));
                    }
                });
            }
            // 设置菜单回显
            if (rowData.parent) {
                rowData["parent.id"] = rowData.parent.id;
            }
            $("#dialog").dialog("setTitle", "编辑菜单");
            $('#dialog').dialog("open");
            $('#menuForm').form("load", rowData)
        })
    
        /*点击保存按钮*/
        $('#save').click(function () {
            let id = $("[name='id']").val();
            let url;
            if (id) {
                // 判断父级菜单是否等于本季点
                let parentId = $("[name='parent.id']").val();
                if (parentId === id) {
                    $.messager.alert("温馨提示", "父菜单是自身!")
                    return false;
                }
                url = "menu/edit"
            } else {
                url = "menu/add"
            }
            // 提交表单
            $('#menuForm').form("submit", {
                url: url,
                success: function (data) {
                    data = $.parseJSON(data);
                    if (data.success) {
                        $.messager.alert("温馨提示", data.msg);
                        /*关闭对话框 */
                        $("#dialog").dialog("close");
                        $("#parentMenu").combobox("reload");
                        $("#dg").datagrid("reload");
                    } else {
                        $.messager.alert("温馨提示", data.msg);
                    }
                }
            })
        });
    
        /*取消操作*/
        $('#cancel').click(function () {
            $('#dialog').dialog("close");
        })
    
        /*删除操作*/
        $('#delete').click(function () {
            // 清空表格内容
            let rowData = $("#dg").datagrid("getSelected");
            if (!rowData) {
                $.messager.alert("温馨提示", "至少需要选择一条数据");
                return false;
            }
            // 提醒用户,是否做删除操作
            $.messager.confirm("确认","是否做删除操作",function (res) {
                if(res){
                    /*做离职操作*/
                    $.get("/menu/delete?id="+rowData.id,function (data) {
                        if (data.success){
                            $.messager.alert("温馨提示",data.msg);
                            /*重新加载下拉列表数据*/
                            $("#parentMenu").combobox("reload");
                            /*重新加载数据表格*/
                            $("#dg").datagrid("reload");
                        } else {
                            $.messager.alert("温馨提示",data.msg);
                        }
    
                    });
                }
            });
        })
    
    });
  • 相关阅读:
    ovs流表机制(四)用vxlan实现多个节点的vm通信(二)
    expect
    在Scrapy中使用Selenium
    Python网络编程
    Scrapy持久化存储
    Scrapy基础
    Selenium实例
    XML和XPATH
    猫眼电影爬取
    Request模块
  • 原文地址:https://www.cnblogs.com/yangshixiong/p/12319779.html
Copyright © 2011-2022 走看看