目录
1、树形结构基础知识
1.1、节点类型
约定:整个树形结构节点的层次最多只能有 3 级。
1.2、在数据库表中表示属性结构
1.2.1、创建菜单的数据库表
pid 时是父节点的 id
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)
);
1.2.2、插入数据
INSERT INTO `t_menu` (`id`, `pid`, `name`, `icon`, `url`) VALUES('1',NULL,'系统权限菜单','glyphiconglyphicon-th-list',NULL);
INSERT INTO `t_menu` (`id`, `pid`, `name`, `icon`, `url`) VALUES('2','1',' 控 制 面 板 ','glyphiconglyphicon-dashboard','main.htm');
INSERT INTO `t_menu` (`id`, `pid`, `name`, `icon`, `url`) VALUES('3','1','权限管理','glyphicon glyphiconglyphicon-tasks',NULL);
INSERT INTO `t_menu` (`id`, `pid`, `name`, `icon`, `url`) VALUES('4','3',' 用 户 维 护 ','glyphiconglyphicon-user','user/index.htm');
INSERT INTO `t_menu` (`id`, `pid`, `name`, `icon`, `url`) VALUES('5','3',' 角 色 维 护 ','glyphiconglyphicon-king','role/index.htm');
INSERT INTO `t_menu` (`id`, `pid`, `name`, `icon`, `url`) VALUES('6','3',' 菜 单 维 护 ','glyphiconglyphicon-lock','permission/index.htm');
INSERT INTO `t_menu` (`id`, `pid`, `name`, `icon`, `url`) VALUES('7','1',' 业 务 审 核 ','glyphiconglyphicon-ok',NULL);
INSERT INTO `t_menu` (`id`, `pid`, `name`, `icon`, `url`) VALUES('8','7',' 实 名 认 证 审 核 ','glyphiconglyphicon-check','auth_cert/index.htm');
INSERT INTO `t_menu` (`id`, `pid`, `name`, `icon`, `url`) VALUES('9','7',' 广 告 审 核 ','glyphiconglyphicon-check','auth_adv/index.htm');
INSERT INTO `t_menu` (`id`, `pid`, `name`, `icon`, `url`) VALUES('10','7',' 项 目 审 核 ','glyphiconglyphicon-check','auth_project/index.htm');
INSERT INTO `t_menu` (`id`, `pid`, `name`, `icon`, `url`) VALUES('11','1',' 业 务 管 理 ','glyphiconglyphicon-th-large',NULL);
INSERT INTO `t_menu` (`id`, `pid`, `name`, `icon`, `url`) VALUES('12','11',' 资 质 维 护 ','glyphiconglyphicon-picture','cert/index.htm');
INSERT INTO `t_menu` (`id`, `pid`, `name`, `icon`, `url`) VALUES('13','11',' 分 类 管 理 ','glyphiconglyphicon-equalizer','certtype/index.htm');
INSERT INTO `t_menu` (`id`, `pid`, `name`, `icon`, `url`) VALUES('14','11',' 流 程 管 理 ','glyphiconglyphicon-random','process/index.htm');
INSERT INTO `t_menu` (`id`, `pid`, `name`, `icon`, `url`) VALUES('15','11',' 广 告 管 理 ','glyphiconglyphicon-hdd','advert/index.htm');
INSERT INTO `t_menu` (`id`, `pid`, `name`, `icon`, `url`) VALUES('16','11',' 消 息 模 板 ','glyphiconglyphicon-comment','message/index.htm');
INSERT INTO `t_menu` (`id`, `pid`, `name`, `icon`, `url`) VALUES('17','11',' 项 目 分 类 ','glyphiconglyphicon-list','projectType/index.htm');
INSERT INTO `t_menu` (`id`, `pid`, `name`, `icon`, `url`) VALUES('18','11',' 项 目 标 签 ','glyphiconglyphicon-tags','tag/index.htm');
INSERT INTO `t_menu` (`id`, `pid`, `name`, `icon`, `url`) VALUES('19','1',' 参 数 管 理 ','glyphiconglyphicon-list-alt','param/index.htm');
1.2.3、关联方式
子节点通过 pid 字段关联到父节点的 id 字段,建立父子关系。根节点的 pid 为 null。
1.3、在 Java 类中表示属性结构
1.3.1、基本方式
在 Menu 类中使用 属性存储 List<Menu> children 当前节点的子节点。
1.3.2、为了配合 zTree 所需添加的属性
pid 属性:找到父节点
name 属性:作为节点名称
icon 属性:当前节点使用的图标
open 属性:控制节点是否默认打开
url 属性:点击节点时跳转的位置
2、菜单维护:页面显示树型结构
2.1、目标
将数据库中查询得到的数据到页面上显示出来。
2.2、思路
数据库查询全部→Java 对象组装→页面上使用 zTree 显示
2.3、逆向工程生成资源
① 在 atcrowdfunding06-common-reverse 模块的 resources 下的 generatorConfig.xml 修改配置相关信息
<!-- 数据库表名字和我们的entity 类对应的映射指定-->
<!--<table tableName="t_admin" domainObjectName="Admin" />-->
<!--<table tableName="t_role" domainObjectName="Role" />-->
<table tableName="t_menu" domainObjectName="Menu" />
② 执行逆向工程
③ 在生成的 Menu 类添加配合 zTree 使用的属性,并生成 get/set 方法、构造器、toString() 方法
// 主键
private Integer id;
// 父节点的id
private Integer pid;
// 节点名称
private String name;
// 节点附带的URL地址,是将来点击菜单项时要跳转的地址
private String url;
// 节点图标的样式
private String icon;
// 存储子节点的集合,初始化是为了避免空指针异常
private List<Menu> children = new ArrayList<>();
// 控制节点是否默认为打开状态,true表示默认打开
private Boolean open = true;
public Menu() {
}
public Menu(Integer id, Integer pid, String name, String url, String icon, List<Menu> children, Boolean open) {
this.id = id;
this.pid = pid;
this.name = name;
this.url = url;
this.icon = icon;
this.children = children;
this.open = open;
}
public List<Menu> getChildren() {
return children;
}
public void setChildren(List<Menu> children) {
this.children = children;
}
@Override
public String toString() {
return "Menu{" +
"id=" + id +
", pid=" + pid +
", name='" + name + '\'' +
", url='" + url + '\'' +
", icon='" + icon + '\'' +
", children=" + children +
", open=" + open +
'}';
}
④ 将生成的资源归位
2.4、将数据在 Java 代码中组装成树形结构
2.4.1、生成 service 层方法
MenuService
package com.atguigu.crowd.service.api;
import com.atguigu.crowd.entity.Menu;
import java.util.List;
/**
* @Author zhang
* @Date 2022/5/9 - 21:18
* @Version 1.0
*/
public interface MenuService {
/**
* 获取全部菜单信息
* @return
*/
List<Menu> getAll();
}
MenuServiceImpl
package com.atguigu.crowd.service.impl;
import com.atguigu.crowd.entity.Menu;
import com.atguigu.crowd.entity.MenuExample;
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;
import java.util.List;
/**
* @Author zhang
* @Date 2022/5/9 - 21:18
* @Version 1.0
*/
@Service
public class MenuServiceImpl implements MenuService {
@Autowired
private MenuMapper menuMapper;
/**
* 获取全部菜单信息
* @return
*/
@Override
public List<Menu> getAll() {
return menuMapper.selectByExample(new MenuExample());
}
}
2.4.2、完成 handle 方法
MenuHandle
package com.atguigu.crowd.mvc.handle;
import com.atguigu.crowd.entity.Menu;
import com.atguigu.crowd.service.api.MenuService;
import com.atguigu.crowd.util.ResultEntity;
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.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Author zhang
* @Date 2022/5/9 - 21:19
* @Version 1.0
*/
@Controller
public class MenuHandle {
@Autowired
private MenuService menuService;
@ResponseBody
@RequestMapping("/menu/get/whole/tree.json")
public ResultEntity<Menu> getAll() {
// 查询全部的menu对象
List<Menu> menuList = menuService.getAll();
// 声明一个变量用来存储找到的根节点
Menu root = null;
// 创建Map对象用来存储id和Menu对象的对应关系便于查找父节点
Map<Integer,Menu> menuMap = new HashMap<>();
// 遍历menuList找出所有id所对应的menu
for (Menu menu : menuList) {
// 获取当前菜单的id
Integer id = menu.getId();
// 填充menuMap:id所对应的menu对象
menuMap.put(id,menu);
}
for (Menu menu : menuList) {
// 获取父节点id
Integer pid = menu.getPid();
// 若父节点为空,则该节点为根节点
if (pid == null) {
// 赋值根节点
root = menu;
continue;
}
// 若父节点不为空,则找出对应关系
Menu father = menuMap.get(pid);
// 将当前节点放入父节点的子节点列表中
father.getChildren().add(menu);
}
// 根节点包含了整个树形结构,返回根节点就是返回整个树
return ResultEntity.successWithData(root);
}
}
2.5、跳转页面
spring-web-mvc.xml
<mvc:view-controller path="/menu/to/page.html" view-name="menu-page"/>
2.6、引入 zTree 环境
2.7、创建 menu-page.jsp 页面
注意引入 zTree 环境
在 WEB-INF 下创建
<%--
Created by IntelliJ IDEA.
User: zhang
Date: 2022/5/9
Time: 23:08
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html lang="zh-CN">
<%@include file="/WEB-INF/include-head.jsp" %>
<%-- 引入zTree环境 --%>
<link rel="stylesheet" href="ztree/zTreeStyle.css">
<script type="text/javascript" src="ztree/jquery.ztree.all-3.5.min.js"></script>
<body>
<%@include file="/WEB-INF/include-nav.jsp" %>
<div class="container-fluid">
<div class="row">
<%@include file="/WEB-INF/include-sidebar.jsp" %>
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
<div class="panel panel-default">
<div class="panel-heading"><i class="glyphicon glyphicon-th-list"></i> 权限菜单列表
<div style="float:right;cursor:pointer;" data-toggle="modal" data-target="#myModal"><i
class="glyphicon glyphicon-question-sign"></i></div>
</div>
<div class="panel-body">
<ul id="treeDemo" class="ztree"></ul>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
2.8、修改侧边栏菜单维护的跳转地址
<li style="height:30px;">
<a href="menu/to/page.html"><i class="glyphicon glyphicon-lock"></i> 菜单维护</a>
</li>
2.9、在页面上显示树形结构
遇到的问题:树形结构的图标不显示
解决方法:数据库 icon 字段数据错误,在第一个 glyphicon 后要加一个空格,如下图
menu-page.jsp
// 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
}
};
// 3.从响应体中获取用来生成树形结构的JSON数据
var zNodes = response.data;
// 4.初始化树形结构
$.fn.zTree.init($("#treeDemo"), setting, zNodes);
}
if(result == "FAILED") {
layer.msg(response.message);
}
}
});
// 生成树形结构的函数
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
}
};
// 3.从响应体中获取用来生成树形结构的JSON数据
var zNodes = response.data;
// 4.初始化树形结构
$.fn.zTree.init($("#treeDemo"), setting, zNodes);
}
if(result == "FAILED") {
layer.msg(response.message);
}
}
});
}
// 在鼠标离开节点范围时删除按钮组
function myRemoveHoverDom(treeId, treeNode) {
// 拼接按钮组的id
var btnGroupId = treeNode.tId + "_btnGrp";
// 移除对应的元素
$("#"+btnGroupId).remove();
}
// 在鼠标移入节点范围时添加按钮组
function myAddHoverDom(treeId, treeNode) {
// 按钮组的标签结构:<span><a><i></i></a><a><i></i></a></span>
// 按钮组出现的位置:节点中treeDemo_n_a超链接的后面
// 为了在需要移除按钮组的时候能够精确定位到按钮组所在span,需要给span设置有规律的id
var btnGroupId = treeNode.tId + "_btnGrp";
// 判断一下以前是否已经添加了按钮组
if($("#"+btnGroupId).length > 0) {
return ;
}
// 准备各个按钮的HTML标签
var addBtn = "<a id='"+treeNode.id+"' class='addBtn btn btn-info dropdown-toggle btn-xs' style='margin-left:10px;padding-top:0px;' href='#' title='添加子节点'> <i class='fa fa-fw fa-plus rbg '></i></a>";
var removeBtn = "<a id='"+treeNode.id+"' class='removeBtn btn btn-info dropdown-toggle btn-xs' style='margin-left:10px;padding-top:0px;' href='#' title='删除节点'> <i class='fa fa-fw fa-times rbg '></i></a>";
var editBtn = "<a id='"+treeNode.id+"' class='editBtn btn btn-info dropdown-toggle btn-xs' style='margin-left:10px;padding-top:0px;' href='#' title='修改节点'> <i class='fa fa-fw fa-edit rbg '></i></a>";
// 获取当前节点的级别数据
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("<span id='"+btnGroupId+"'>"+btnHTML+"</span>");
}
// 修改默认的图标
function myAddDiyDom(treeId, treeNode) {
// treeId是整个树形结构附着的ul标签的id
console.log("treeId="+treeId);
// 当前树形节点的全部的数据,包括从后端查询得到的Menu对象的全部属性
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);
}
2.10、实现点击不跳转
menu-page.jsp
在设置数组 setting 添加 data.key.url 属性
var setting = {
"view": {
"addDiyDom": myAddDiyDom
},
"data" : {
"key" : {
"url" : "maomi"
}
}
};
2.11、添加按钮组
2.11.1、思路
在鼠标移入时添加按钮组,鼠标移出后删除按钮组。
根据 treeNode 中的 level 属性,可得按钮增删改查的规则:
level0:根节点。添加子节点
level1:分支节点。修改、添加、没有子节点可以删除、有子节点不能删除
level2:叶子节点。修改、删除
2.11.2、步骤
① menu-page.jsp:在设置数组 setting 添加 maddHoverDom、removeHoverDom 属性
var setting = {
"view": {
"addDiyDom": myAddDiyDom,
"addHoverDom" : myAddHoverDom,
"removeHoverDom" : myRemoveHoverDom
},
"data" : {
"key" : {
"url" : "maomi"
}
}
};
② my-menu.js:添加鼠标移出节点时删除按钮组的函数
// 在鼠标离开节点范围时删除按钮组
function myRemoveHoverDom(treeId, treeNode) {
// 拼接按钮组的id
var btnGroupId = treeNode.tId + "_btnGrp";
// 移除对应的元素
$("#"+btnGroupId).remove();
}
③ my-menu.js:添加鼠标移入节点时显示按钮组,且按钮组根据节点增删改规律添加按钮
// 在鼠标移入节点范围时添加按钮组
function myAddHoverDom(treeId, treeNode) {
// 按钮组的标签结构:<span><a><i></i></a><a><i></i></a></span>
// 按钮组出现的位置:节点中treeDemo_n_a超链接的后面
// 为了在需要移除按钮组的时候能够精确定位到按钮组所在span,需要给span设置有规律的id
var btnGroupId = treeNode.tId + "_btnGrp";
// 判断以前是否已经添加了按钮组
if($("#"+btnGroupId).length > 0) {
return ;
}
// 准备各个按钮的HTML标签,id属性为当前节点的id
var addBtn = "<a id='"+treeNode.id+"' class='addBtn btn btn-info dropdown-toggle btn-xs' style='margin-left:10px;padding-top:0px;' href='#' title='添加子节点'> <i class='fa fa-fw fa-plus rbg '></i></a>";
var removeBtn = "<a id='"+treeNode.id+"' class='removeBtn btn btn-info dropdown-toggle btn-xs' style='margin-left:10px;padding-top:0px;' href='#' title='删除节点'> <i class='fa fa-fw fa-times rbg '></i></a>";
var editBtn = "<a id='"+treeNode.id+"' class='editBtn btn btn-info dropdown-toggle btn-xs' style='margin-left:10px;padding-top:0px;' href='#' title='修改节点'> <i class='fa fa-fw fa-edit rbg '></i></a>";
// 获取当前节点的级别数据
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("<span id='"+btnGroupId+"'>"+btnHTML+"</span>");
}
2.12、将生成树形结构的代码封装为函数
my-menu.js
// 生成树形结构的函数
function generateTree() {
// 准备生成树形结构的JSON数据,数据的来源是发送Ajax请求得到
$.ajax({
"url": "menu/get/whole/tree.json",
"type":"post",
"dataType":"json",
"success":function(response){
var result = response.result;
if(result == "SUCCESS") {
// 创建JSON对象用于存储对zTree所做的设置
var setting = {
"view": {
"addDiyDom": myAddDiyDom,
"addHoverDom" : myAddHoverDom,
"removeHoverDom" : myRemoveHoverDom
},
"data" : {
"key" : {
"url" : "maomi"
}
}
};
// 从响应体中获取用来生成树形结构的JSON数据
var zNodes = response.data;
// 4.初始化树形结构
$.fn.zTree.init($("#treeDemo"), setting, zNodes);
}
if(result == "FAILED") {
layer.msg(response.message);
}
}
});
}
3、添加子节点
3.1、目标
给当前节点添加子节点,保存到数据库并刷新树形结构的显示。
3.2、思路
3.3、代码
3.3.1、导入前端页面
在 modal-menu-edit.jsp 页面引入这三个页面
<%@include file="/WEB-INF/modal-menu-add.jsp"%>
<%@include file="/WEB-INF/modal-menu-confirm.jsp"%>
<%@include file="/WEB-INF/modal-menu-edit.jsp"%>
出现的问题:
报错:Page指令:非法出现多次出现的'contentType'具有不同的值(old:[text/html;charset=UTF-8],new:[text/html; charset=UTF-8])
原因:引入的 jsp 页面与现 jsp 页面的 contentType 不一致,将引入的前端页面的头改为与现在的一样即可
3.3.2、完成 service 方法
MenuService
/**
* 保存菜单节点
* @param menu 要保存的菜单节点
*/
void saveMenu(Menu menu);
MenuServiceImpl
/**
* 保存菜单节点
* @param menu 要保存的菜单节点
*/
@Override
public void saveMenu(Menu menu) {
menuMapper.insert(menu);
}
3.3.3、完成 handle 方法
MenuHandle
@ResponseBody
@RequestMapping("/menu/save.json")
public ResultEntity<String> saveMenu(Menu menu){
menuService.saveMenu(menu);
return ResultEntity.successWithoutData();
}
3.3.4、给添加子节点按钮绑定单击事件
// 给添加子节点按钮绑定单击事件
$("#treeDemo").on("click", ".addBtn", function (){
// 将当前节点的id作为新节点的pid保存到全局变量
window.pid = this.id;
// 打开添加节点的模态框
$("#menuAddModal").modal("show");
return false;
});
3.3.5、给添加子节点的模态框中的保存按钮绑定单击事件
// 给添加子节点的模态框中的保存按钮绑定单击事件
$("#menuSaveBtn").click(function (){
// 获取表单项中用户输入的数据
var name = $.trim($("#menuAddModal [name=name]").val());
var url = $.trim($("#menuAddModal [name=url]").val())
var icon = $("#menuAddModal [name=icon]:checked").val()
// 发送Ajax请求
$.ajax({
"url" : "menu/save.json",
"type" : "post",
"data" : {
"pid" : window.pid,
"name" : name,
"url" : url,
"icon" : icon
},
"dataType" : "json",
"success" : function (response){
var result = response.result;
if(result == "SUCCESS"){
layer.msg("操作成功!");
}
if(result == "FAILED"){
layer.msg("操作失败!" + response.message);
}
// 在保存成功后刷新树形结构(重新生成)
generateTree();
},
"error" : function (response){
layer.msg(response.status + " " + response.statusText);
}
});
// 关闭模态框
$("#menuAddModal").modal("hide");
// 清空表单:通过代码点击添加子节点的模态框中的重置按钮实现
$("#menuResetBtn").click();
});
4、更新节点
4.1、目标
contentType修改当前节点的基本属性。不更换父节点。
4.2、思路
4.3、代码
4.3.1、给修改按钮绑定单击事件
// 给修改节点按钮绑定单击事件
$("#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;
});
4.3.2、给更新模态框中的更新按钮绑定单击事件
menu-page.jsp
// 给更新模态框中的更新按钮绑定单击事件
$("#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("操作成功!");
}
if(result == "FAILED"){
layer.msg("操作失败!" + response.message);
}
// 在保存成功后刷新树形结构(重新生成)
generateTree();
},
"error" : function (response){
layer.msg(response.status + " " + response.statusText);
}
});
// 关闭模态框
$("#menuEditModal").modal("hide");
});
4.3.3、完成 service 方法
MenuService
/**
* 更新菜单节点
* @param menu 要更新的菜单节点
*/
void updateMenu(Menu menu);
MenuServiceImpl
/**
* 更新菜单节点
* @param menu 要更新的菜单节点
*/
@Override
public void updateMenu(Menu menu) {
menuMapper.updateByPrimaryKeySelective(menu);
}
4.3.4、完成 handle 方法
MenuHandle
@ResponseBody
@RequestMapping("/menu/update.json")
public ResultEntity<String> updateMenu(Menu menu){
menuService.updateMenu(menu);
return ResultEntity.successWithoutData();
}
5、删除节点
5.1、思路
5.3、代码
5.3.1、给删除节点按钮绑定单击事件
menu-page.jsp
// 给删除节点按钮绑定单击事件
$("#treeDemo").on("click", ".removeBtn", function (){
// 将当前节点的id保存到全局变量
window.id = this.id;
// 打开确认删除的模态框
$("#menuConfirmModal").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(" <i class='"+currentNode.icon+"'></i>" + currentNode.name + " ");
return false;
});
5.3.2、给确认模态框的确认按钮绑定单击事件
// 给确认模态框的确认按钮绑定单击事件
$("#confirmBtn").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("操作成功!");
}
if(result == "FAILED"){
layer.msg("操作失败!" + response.message);
}
// 刷新菜单页面
generateTree();
}
});
$("#menuConfirmModal").modal("hide");
});
});
5.3.3、完成 service 方法
MenuService
/**
* 根据id删除菜单节点
* @param id 要删除的菜单节点的id
*/
void removeMenu(Integer id);
MenuServiceImpl
/**
* 根据id删除菜单节点
* @param id 要删除的菜单节点的id
*/
@Override
public void removeMenu(Integer id) {
menuMapper.deleteByPrimaryKey(id);
}
5.3.4、完成 handle 方法
@ResponseBody
@RequestMapping("/menu/remove.json")
public ResultEntity<String> removeMenu(@RequestParam("id") Integer id){
menuService.removeMenu(id);
return ResultEntity.successWithoutData();
}