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: "名称", width: 100, align: "center"},
            {field: "url", title: "跳转地址", width: 100, align: "center"},
            {
                field: "parent", title: "父菜单", width: 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({
        width: 300,
        height: 240,
        closed: true,
        buttons: "#menu_dialog_bt",
    });

    // 加载父级菜单
    $('#parentMenu').combobox({
        width: 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);
                    }

                });
            }
        });
    })

});

猜你喜欢

转载自www.cnblogs.com/yangshixiong/p/12319779.html