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);
                    }

                });
            }
        });
    })

});

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM