栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【尚筹网】IDEA版实现(五)菜单维护

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【尚筹网】IDEA版实现(五)菜单维护

由于尚硅谷的视频是通过Eclipse软件来做的,其中有些操作与IDEA上有所区别,所以我在这里将IDEA区别于Eclipse的操作、操作过程中涉及的源码(与视频的源码略有出入)以及大家可能遇到的种种问题分享给大家,这些源码在我这里均是通过测试的,仅供参考!

1 创建数据库表

在SQLyog中配置t_menu数据库表:

create table t_menu ( 
    id int(11) not null auto_increment, 
    pid int(11), 
    name varchar(200), 
    url varchar(200), 
    icon varchar(200), 
    primary key (id) 
);
insert into `t_menu` (`id`, `pid`, `name`, `icon`, `url`) values('1',NULL,'系统权限菜单','glyphicon glyphicon-th-list',NULL); 
insert into `t_menu` (`id`, `pid`, `name`, `icon`, `url`) values('2','1','控制面板 ','glyphicon glyphicon-dashboard','main.htm'); 
insert into `t_menu` (`id`, `pid`, `name`, `icon`, `url`) values('3','1','权限管理','glyphicon glyphicon glyphicon-tasks',NULL); 
insert into `t_menu` (`id`, `pid`, `name`, `icon`, `url`) values('4','3','用户维护 ','glyphicon glyphicon-user','user/index.htm'); 
insert into `t_menu` (`id`, `pid`, `name`, `icon`, `url`) values('5','3','角色维护 ','glyphicon glyphicon-king','role/index.htm'); 
insert into `t_menu` (`id`, `pid`, `name`, `icon`, `url`) values('6','3','菜单维护 ','glyphicon glyphicon-lock','permission/index.htm'); 
insert into `t_menu` (`id`, `pid`, `name`, `icon`, `url`) values('7','1','业务审核 ','glyphicon glyphicon-ok',NULL); 
insert into `t_menu` (`id`, `pid`, `name`, `icon`, `url`) values('8','7','实名认证审核 ','glyphicon glyphicon-check','auth_cert/index.htm'); 
insert into `t_menu` (`id`, `pid`, `name`, `icon`, `url`) values('9','7','广告审核 ','glyphicon glyphicon-check','auth_adv/index.htm'); 
insert into `t_menu` (`id`, `pid`, `name`, `icon`, `url`) values('10','7','项目审核 ','glyphicon glyphicon-check','auth_project/index.htm'); 
insert into `t_menu` (`id`, `pid`, `name`, `icon`, `url`) values('11','1','业务管理 ','glyphicon glyphicon-th-large',NULL); 
insert into `t_menu` (`id`, `pid`, `name`, `icon`, `url`) values('12','11','资质维护 ','glyphicon glyphicon-picture','cert/index.htm'); 
insert into `t_menu` (`id`, `pid`, `name`, `icon`, `url`) values('13','11','分类管理 ','glyphicon glyphicon-equalizer','certtype/index.htm'); 
insert into `t_menu` (`id`, `pid`, `name`, `icon`, `url`) values('14','11','流程管理 ','glyphicon glyphicon-random','process/index.htm'); 
insert into `t_menu` (`id`, `pid`, `name`, `icon`, `url`) values('15','11','广告管理 ','glyphicon glyphicon-hdd','advert/index.htm'); 
insert into `t_menu` (`id`, `pid`, `name`, `icon`, `url`) values('16','11','消息模板 ','glyphicon glyphicon-comment','message/index.htm'); 
insert into `t_menu` (`id`, `pid`, `name`, `icon`, `url`) values('17','11','项目分类 ','glyphicon glyphicon-list','projectType/index.htm'); 
insert into `t_menu` (`id`, `pid`, `name`, `icon`, `url`) values('18','11','项目标签 ','glyphicon glyphicon-tags','tag/index.htm'); 
insert into `t_menu` (`id`, `pid`, `name`, `icon`, `url`) values('19','1','参数管理 ','glyphicon glyphicon-list-alt','param/index.htm');
2 mybatis逆向工程

修改reversesrcmainresourcesgeneratorConfig.xml:

在IDEA右侧的maven project找到mybatis-generator:generate并点击运行,生成文件(与前文操作相同)

修改reversesrcmainjavacomatguigucrowdentityMenu.java

// 存储子节点的集合,初始化以避免空指针异常
private List children;

// 控制节点是否默认展开,设置为true表示默认打开
private Boolean open = true;

public List getChildren() {
    return children;
}

public void setChildren(List children) {
    this.children = children;
}

public Boolean getOpen() {
    return open;
}

public void setOpen(Boolean open) {
    this.open = open;
}

public Menu(Integer id, Integer pid, String name, String url, String icon, List children, Boolean open) {
    this.id = id;
    this.pid = pid;
    this.name = name;
    this.url = url;
    this.icon = icon;
    this.children = children;
    this.open = open;
}

@Override
public String toString() {
    return "Menu{" +
        "id=" + id +
        ", pid=" + pid +
        ", name='" + name + ''' +
        ", url='" + url + ''' +
        ", icon='" + icon + ''' +
        ", children=" + children +
        ", open=" + open +
        '}';
}

将Menu.java与MenuExample.java放入entitysrcmainjavacomatguigucrowdentity中

将MenuMapper.java放入componentsrcmainjavacomatguigucrowdmapper中

将MenuMapper.xml放入webuisrcmainresourcesmybatismapper中

3 树型结构显示 3.1 后端部分 3.1.1 新建后端文件

新建componentsrcmainjavacomatguigucrowdserviceapiMenuService.java

新建componentsrcmainjavacomatguigucrowdserviceimplMenuServiceImpl.java

package com.atguigu.crowd.service.impl;

import com.atguigu.crowd.mapper.MenuMapper;
import com.atguigu.crowd.service.api.MenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class MenuServiceImpl implements MenuService {

    @Autowired
    private MenuMapper menuMapper;
}

新建componentsrcmainjavacomatguigucrowdmvchandlerMenuHandler.java

package com.atguigu.crowd.mvc.handler;

import com.atguigu.crowd.service.api.MenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

@Controller
public class MenuHandler {

    @Autowired
    private MenuService menuService;

}
3.1.2 MenuHandler

修改componentsrcmainjavacomatguigucrowdmvchandlerMenuHandler.java

@Controller
public class MenuHandler {

    @Autowired
    private MenuService menuService;


    @ResponseBody
    @RequestMapping("/menu/get/whole/tree.json")
    public ResultEntity getWholeTreeNew() {

        // 1.查询全部的Menu对象
        List menuList = menuService.getAll();

        // 2.声明一个变量来存储找到的根节点
        Menu root = null;

        // 3.创建 Map 对象用来存储 id 和 Menu 对象的对应关系便于查找父节点
        Map menuMap = new HashMap<>();

        // 4.遍历 menuList 填充 menuMap
        for (Menu menu: menuList) {

            Integer id = menu.getId();

            menuMap.put(id, menu);
        }

        // 5.再次遍历 menuList 查找根节点、组装父子节点
        for (Menu menu: menuList) {

            // 6.获取当前 menu 对象的 pid 属性值
            Integer pid = menu.getPid();

            // 7.如果 pid 为 null,判定为根节点
            if (pid == null) {
                root = menu;

                // 8.如果当前节点是根节点,那么肯定没有父节点,不必继续执行
                continue;
            }
            // 9.如果 pid 不为 null,说明当前节点有父节点,那么可以根据 pid 到 menuMap 中 查找对应的 Menu 对象
            Menu father = menuMap.get(pid);

            // 10.将当前节点存入父节点的 children 集合
            father.getChildren().add(menu);
        }

        // 11.经过上面的运算,根节点包含了整个树形结构,返回根节点就是返回整个树
        return ResultEntity.successWithData(root);
    }
}

并新增getAll()方法及实现类:

修改componentsrcmainjavacomatguigucrowdserviceimplMenuServiceImpl.java

@Override
public List getAll() {
    List menuList = menuMapper.selectByExample(new MenuExample());
    return menuList;
}
3.2 前端部分

修改webuisrcmainresourcesspring-web-mvc.xml


在webuisrcmainwebappWEB-INF新建menu-page.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>


<%@include file="include-head.jsp" %>

    
    



<%@include file="include-nav.jsp" %>

    
        <%@include file="include-sidebar.jsp" %>
        

            
                 权限菜单列表 
                
                    
                    

修改菜单维护图标:webuisrcmainwebappWEB-INFinclude-sidebar.jsp

 菜单维护

新建webuisrcmainwebappcrowdmy-menu.js

// 修改默认的图标
function myAddDiyDom(treeId, treeNode) {

    // treeId是整个树形结构附着的ul标签的id
    console.log("treeId="+treeId);

    // 当前树形节点的全部数据、
    console.log(treeNode);

   // zTree 生成 id 的规则
   //例子: treeDemo_7_ico
   //解析: ul 标签的 id_当前节点的序号_功能
   //提示: “ul 标签的 id_当前节点的序号” 部分可以通过访问 treeNode 的 tId 属性得到
   //根据 id 的生成规则拼接出来 span 标签的 id

    var spanId = treeNode.tId + "_ico";

    // 根据控制图标的span标签的id找到这个span标签
    // 删除旧的class
    // 添加新的class
    $("#"+spanId).removeClass().addClass(treeNode.icon);
}

// 鼠标移入节点范围时添加按钮组
function myAddHoverDom(treeId, treeNode) {

    // 按钮组的标签结构: 
    // 按钮组出现的位置: 节点中 treeDemo_n_a 超链接的后面

    // 为了在需要移除按钮组的时候能够精确定位到按钮组所在 span, 需要给 span 设置有规律的 id
    var btnGroupId = treeNode.tId + "_btnGrp";
    // 判断一下以前是否已经添加了按钮组
    if($("#"+btnGroupId).length > 0) {
        return ;
    }
    var addBtn = "+treeNode.id+"' class='btn btn-info dropdown-toggle btn-xs' style='margin-left:10px;padding-top:0px;' href='#' title='添加子节点'>  ";
    var removeBtn = "+treeNode.id+"' class='btn btn-info dropdown-toggle btn-xs' style='margin-left:10px;padding-top:0px;' href='#' title=' 删 除 节 点 '>  ";
    var editBtn = "+treeNode.id+"' class='btn btn-info dropdown-toggle btn-xs' style='margin-left:10px;padding-top:0px;' href='#' title=' 修 改 节 点 '>  ";

    // 获取当前节点的级别数据
    var level = treeNode.level;
    // 声明变量存储拼装好的按钮代码
    var btnHTML = "";
    // 判断当前节点的级别
    if(level === 0) {
        // 级别为 0 时是根节点, 只能添加子节点
        btnHTML = addBtn;
    }
    if (level === 1) {
        // 级别为 1 时是分支节点, 可以添加子节点、 修改
        btnHTML = addBtn + " " + editBtn;
        // 获取当前节点的子节点数量
        var length = treeNode.children.length;
        // 如果没有子节点, 可以删除
        if(length === 0) {
            btnHTML = btnHTML + " " + removeBtn;
        }
    }
    if (level === 2) {
        // 级别为 2 时是叶子节点, 可以修改、 删除
        btnHTML = editBtn + " " + removeBtn;
    }
    // 找到附着按钮组的超链接
    var anchorId = treeNode.tId + "_a";
    // 执行在超链接后面附加 span 元素的操作
    $("#"+anchorId).after(""+btnHTML+"");
}

// 鼠标离开节点范围时删除按钮组
function myRemoveHoverDom(treeId, treeNode) {

    // 拼接按钮组的 id
    var btnGroupId = treeNode.tId + "_btnGrp";
    // 移除对应的元素
    $("#"+btnGroupId).remove();
}

// 生成树形结构的函数
function generateTree() {
    // 1.准备生成树形结构的JSON数据,数据来源是发送Ajax请求得到
    $.ajax({
        url: "menu/get/whole/tree.json",
        type: "post",
        dataType: "json",
        success: function (response) {
            var result = response.result;
            if (result === "SUCCESS") {

                // 2.创建json对象用于存储对zTree所做的设置
                var setting = {
                    view: {
                        addDiyDom: myAddDiyDom,
                        addHoverDom: myAddHoverDom,
                        removeHoverDom: myRemoveHoverDom
                    },
                    data: {
                        key:{
                            url: "nothing", // url值改为不存在的属性名,则点击页面响应菜单时不会跳转
                        }
                    }
                };

                // 3.从响应体中获取用来生成树形结构的JSON数据
                var zNodes = response.data;

                // 4.初始化树形结构
                $.fn.zTree.init($("#treeDemo"), setting, zNodes);
            }
            if (result === "FAILED") {
                layer.msg(response.message);
            }
        },
    });
}

测试:

4 子节点添加 4.1 前端部分

图标功能赋予:修改webuisrcmainwebappcrowdmy-menu.js

var addBtn = "+treeNode.id+"' class='addBtn btn btn-info dropdown-toggle btn-xs' style='margin-left:10px;padding-top:0px;' href='#' title='添加子节点'>  ";
var removeBtn = "+treeNode.id+"' class='removeBtn btn btn-info dropdown-toggle btn-xs' style='margin-left:10px;padding-top:0px;' href='#' title=' 删 除 节 点 '>  ";
var editBtn = "+treeNode.id+"' class='editBtn btn btn-info dropdown-toggle btn-xs' style='margin-left:10px;padding-top:0px;' href='#' title=' 修 改 节 点 '>  ";

修改webuisrcmainwebappWEB-INFmenu-page.jsp


添加模态框引入:

<%@include file="/WEB-INF/modal-menu-add.jsp"%>

新建webuisrcmainwebappWEB-INFmodal-menu-add.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

    
        
            
                
                

尚筹网系统弹窗
请输入节点名称:
请输入URL地址:
               
               

4.2 后端部分

修改componentsrcmainjavacomatguigucrowdmvchandlerMenuHandler.java

@ResponseBody
@RequestMapping("/menu/save.json")
public ResultEntity saveMenu(Menu menu) {

    menuService.saveMenu(menu);

    return ResultEntity.successWithoutData();
    }

并新增savemenu()方法及实现类:

修改componentsrcmainjavacomatguigucrowdserviceimplMenuServiceImpl.java

@Override
public void saveMenu(Menu menu) {
    menuMapper.insert(menu);
}
4.3 测试

5 节点更新 5.1 前端部分

修改webuisrcmainwebappWEB-INFmenu-page.jsp

// 给编辑按钮绑定单击响应函数
        $("#treeDemo").on("click",".editBtn",function(){

            // 将当前节点的id保存到全局变量
            window.id = this.id;

            // 打开模态框
            $("#menuEditModal").modal("show");

            // 获取zTreeObj对象
            var zTreeObj = $.fn.zTree.getZTreeObj("treeDemo");

            // 根据id属性查询节点对象
            // 用来搜索节点的属性名
            var key = "id";

            // 用来搜索节点的属性值
            var value = window.id;

            var currentNode = zTreeObj.getNodeByParam(key, value);

            // 回显表单数据
            $("#menuEditModal [name=name]").val(currentNode.name);
            $("#menuEditModal [name=url]").val(currentNode.url);

            // 回显radio可以这样理解:被选中的radio的value属性可以组成一个数组,
            // 然后再用这个数组设置回radio,就能够把对应的值选中
            $("#menuEditModal [name=icon]").val([currentNode.icon]);

            return false;
        });

        // 给更新模态框中的更新按钮绑定单击响应函数
        $("#menuEditBtn").click(function(){

            // 收集表单数据
            var name = $("#menuEditModal [name=name]").val();
            var url = $("#menuEditModal [name=url]").val();
            var icon = $("#menuEditModal [name=icon]:checked").val();

            // 发送Ajax请求
            $.ajax({
                "url":"menu/update.json",
                "type":"post",
                "data":{
                    "id": window.id,
                    "name":name,
                    "url":url,
                    "icon":icon
                },
                "dataType":"json",
                "success":function(response){
                    var result = response.result;

                    if(result === "SUCCESS") {
                        layer.msg("操作成功!");

                        // 重新加载树形结构,注意:要在确认服务器端完成保存操作后再刷新
                        // 否则有可能刷新不到最新的数据,因为这里是异步的
                        generateTree();
                    }

                    if(result === "FAILED") {
                        layer.msg("操作失败!"+response.message);
                    }
                },
                "error":function(response){
                    layer.msg(response.status+" "+response.statusText);
                }
            });

            // 关闭模态框
            $("#menuEditModal").modal("hide");

        });

添加模态框引入:

<%@include file="/WEB-INF/modal-menu-edit.jsp"%>

新建webuisrcmainwebappWEB-INFmodal-menu-edit.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

    
        
            
                
                

尚筹网系统弹窗
请输入节点名称:
请输入URL地址:
               
               

5.2 后端部分

修改componentsrcmainjavacomatguigucrowdmvchandlerMenuHandler.java

@ResponseBody
@RequestMapping("/menu/update.json")
public ResultEntity updateMenu(Menu menu) {

    menuService.updateMenu(menu);
    return ResultEntity.successWithoutData();
}

并新增updateMenu()方法及实现类:

修改componentsrcmainjavacomatguigucrowdserviceimplMenuServiceImpl.java

@Override
public void updateMenu(Menu menu) {
    menuMapper.updateByPrimaryKeySelective(menu);
}
5.3 测试


6 节点删除 6.1 前端部分

修改webuisrcmainwebappWEB-INFmenu-page.jsp

// 给 "x" 按钮绑定单击响应函数
        $("#treeDemo").on("click",".removeBtn",function(){
            // 将当前节点的 id 保存到全局变量
            window.id = this.id;
            // 打开模态框
            $("#menu/confirm/iModal").modal("show");
            // 获取 zTreeObj 对象
            var zTreeObj = $.fn.zTree.getZTreeObj("treeDemo");
            // 根据 id 属性查询节点对象
            // 用来搜索节点的属性名
            var key = "id";
            // 用来搜索节点的属性值
            var value = window.id;
            var currentNode = zTreeObj.getNodeByParam(key, value);
            $("#removeNodeSpan").html("【"+currentNode.name+"】");
            return false;
        });

// 给确认模态框中的 OK 按钮绑定单击响应函数
        $("#/confirm/iBtn").click(function(){
            $.ajax({
                "url":"menu/remove.json",
                "type":"post",
                "data":{
                    "id":window.id
                },
                "dataType":"json",
                "success":function(response){
                    var result = response.result;
                    if(result === "SUCCESS") {
                        layer.msg("操作成功!");

                        // 重新加载树形结构, 注意: 要在确认服务器端完成保存操作后再刷新
                        // 否则有可能刷新不到最新的数据, 因为这里是异步的
                        generateTree();
                    } 
                    
                    if (result === "FAILED") {
                        layer.msg("操作失败! "+response.message);
                    }
                },
                "error":function(response){
                    layer.msg(response.status+" "+response.statusText);
                }
            });

            // 关闭模态框
            $("#menu/confirm/iModal").modal("hide");
        });

添加模态框引入:

<%@include file="/WEB-INF/modal-menu-/confirm/i.jsp"%>

新建webuisrcmainwebappWEB-INFmodal-menu-/confirm/i.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

    
        
            
                
                

尚筹网系统弹窗
您真的要删除这个节点吗?

6.2 后端部分

修改componentsrcmainjavacomatguigucrowdmvchandlerMenuHandler.java

@ResponseBody
@RequestMapping("/menu/remove.json")
public ResultEntity removeMenu(@RequestParam("id") Integer id) {

    menuService.removeMenu(id);
    return ResultEntity.successWithoutData();
}

并新增updateMenu()方法及实现类:

修改componentsrcmainjavacomatguigucrowdserviceimplMenuServiceImpl.java

@Override
public void removeMenu(Integer id) {
    menuMapper.deleteByPrimaryKey(id);
}
6.3 测试

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号