树形结构菜单的增删改查

    技术2022-07-14  76

    树形结构的样例 约定:整个树形结构节点的层次最多能有3级。

    数据库中表示树形结构

    pid表示父节点id,name为节点名称,url为节点的链接地址,icon为节点旁边的图标。

    关联方式是通过pid字段关联到父节点的id字段,建立父子关系;

    后台代码

    实体类

    /** * (TMenu)实体类 * * @author sxyuser * @since 2020-06-30 20:38:25 */ public class TMenu implements Serializable { private static final long serialVersionUID = 440358921050052093L; /** * 表id */ private Integer id; /** * 父节点id */ private Integer pid; /** * 节点名称 */ private String name; /** * 地址 */ private String url; /** * 图标 */ private String icon; /** * 存储子节点的集合,初始化是为了防止空指针异常 */ private List<TMenu> children = new ArrayList<> (); /** * 控制节点是否打开 */ private Boolean open=true; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public Integer getPid() { return pid; } public void setPid(Integer pid) { this.pid = pid; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getIcon() { return icon; } public void setIcon(String icon) { this.icon = icon; } public List<TMenu> getChildren() { return children; } public void setChildren(List<TMenu> children) { this.children = children; } public Boolean getOpen() { return open; } public void setOpen(Boolean open) { this.open = open; } }

    mybatis的xml文件

    <?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.demo.springboot.dao.TMenuMapper"> <resultMap type="com.demo.springboot.entity.TMenu" id="TMenuMap"> <result property="id" column="id" jdbcType="INTEGER"/> <result property="pid" column="pid" jdbcType="INTEGER"/> <result property="name" column="name" jdbcType="VARCHAR"/> <result property="url" column="url" jdbcType="VARCHAR"/> <result property="icon" column="icon" jdbcType="VARCHAR"/> </resultMap> <!--查询单个--> <select id="queryById" resultMap="TMenuMap"> select id, pid, name, url, icon from t_menu where id = #{id} </select> <!--通过实体作为筛选条件查询--> <select id="queryAll" resultMap="TMenuMap"> select id, pid, name, url, icon from t_menu </select> <!--新增所有列--> <insert id="insert" keyProperty="id" useGeneratedKeys="true"> insert into t_menu(pid, name, url, icon) values (#{pid}, #{name}, #{url}, #{icon}) </insert> <!--通过主键修改数据--> <update id="update"> update t_menu <set> <if test="pid != null"> pid = #{pid}, </if> <if test="name != null and name != ''"> name = #{name}, </if> <if test="url != null and url != ''"> url = #{url}, </if> <if test="icon != null and icon != ''"> icon = #{icon}, </if> </set> where id = #{id} </update> <!--通过主键删除--> <delete id="deleteById"> delete from t_menu where id = #{id} </delete> </mapper>

    dao层

    /** * (TMenu)表数据库访问层 * * @author sxyuser * @since 2020-06-30 20:38:29 */ public interface TMenuMapper { /** * 通过ID查询单条数据 * * @param id 主键 * @return 实例对象 */ TMenu queryById(Integer id); /** * 通过实体作为筛选条件查询 * * @return 对象列表 */ List<TMenu> queryAll(); /** * 新增数据 * * @param tMenu 实例对象 * @return 影响行数 */ int insert(TMenu tMenu); /** * 修改数据 * * @param tMenu 实例对象 * @return 影响行数 */ int update(TMenu tMenu); /** * 通过主键删除数据 * * @param id 主键 * @return 影响行数 */ int deleteById(Integer id); }

    service层

    /** * (TMenu)表服务接口 * * @author sxyuser * @since 2020-06-30 20:38:29 */ public interface TMenuService { /** * 通过ID查询单条数据 * * @param id 主键 * @return 实例对象 */ TMenu queryById(Integer id); /** * 新增数据 * * @param tMenu 实例对象 * @return 实例对象 */ TMenu insert(TMenu tMenu); /** * 修改数据 * * @param tMenu 实例对象 * @return 实例对象 */ TMenu update(TMenu tMenu); /** * 通过主键删除数据 * * @param id 主键 * @return 是否成功 */ boolean deleteById(Integer id); /** * 通过实体作为筛选条件查询 * * @return 对象列表 */ List<TMenu> queryAll(); }

    impl层

    /** * (TMenu)表服务实现类 * * @author sxyuser * @since 2020-06-30 20:38:30 */ @Service("tMenuService") public class TMenuServiceImpl implements TMenuService { @Resource private TMenuMapper tMenuMapper; /** * 通过ID查询单条数据 * * @param id 主键 * @return 实例对象 */ @Override public TMenu queryById(Integer id) { return this.tMenuMapper.queryById(id); } /** * 新增数据 * * @param tMenu 实例对象 * @return 实例对象 */ @Override public TMenu insert(TMenu tMenu) { this.tMenuMapper.insert(tMenu); return tMenu; } /** * 修改数据 * * @param tMenu 实例对象 * @return 实例对象 */ @Override public TMenu update(TMenu tMenu) { this.tMenuMapper.update(tMenu); return this.queryById(tMenu.getId()); } /** * 通过主键删除数据 * * @param id 主键 * @return 是否成功 */ @Override public boolean deleteById(Integer id) { return this.tMenuMapper.deleteById(id) > 0; } /** * 通过实体作为筛选条件查询 * * @return 对象列表 */ @Override public List<TMenu> queryAll() { return tMenuMapper.queryAll(); } }

    controller层

    /** * (TMenu)表控制层 * * @author sxyuser * @since 2020-06-30 20:38:30 */ @RestController @RequestMapping("tMenu") @Api(tags = "菜单模块API文档") public class TMenuController { /** * 服务对象 */ @Resource private TMenuService tMenuService; @ApiOperation(value = "查询所有菜单功能", produces = "application/json") @PostMapping("wholeTree") public AjaxResult<TMenu> getWholeTree() { // 查询所有Menu对象 List<TMenu> menuList = tMenuService.queryAll(); // 声明一个变量,用来存放找到的根节点 TMenu root = null; //创建Map对象用来存储id和Menu对象的对应关系便于查找父节点 Map<Integer, TMenu> menuMap = new HashMap<>(); for (TMenu e : menuList) { // 获取当前的pid属性 Integer id = e.getId(); menuMap.put(id, e); } //再次遍历menuList查找根节点、组装父子节点 for (TMenu item : menuList) { Integer pid = item.getPid(); //如果pid为0,表示为根节点 if (Objects.equals(pid, 0)) { // 把当前获取的menu赋值给root root = item; // 停止本次循环,继续执行下次循环 continue; } //如果pid不为0,说明当前节点有父节点,那么可以根据pid到menuMap中查找对应的TMenu对象 TMenu father = menuMap.get(pid); // 将子节点存入父节点的children集合中 father.getChildren().add(item); } //将组装的树形结构(也就是根节点对象)返回给浏览器 return success(root); } /** * 添加菜单功能 * * @param menu * @return */ @ApiOperation(value = "添加菜单功能", produces = "application/json") @PostMapping("saveTree") public AjaxResult<Boolean> saveTree(@RequestBody TMenu menu) { TMenu insert = tMenuService.insert(menu); if (ObjectUtils.allNotNull(insert)) { return success(true); } return error404(false); } /** * 更新菜单功能 * * @param menu * @return */ @ApiOperation(value = "更新菜单功能", produces = "application/json") @PostMapping("editTree") public AjaxResult<Boolean> editTree(@RequestBody TMenu menu) { TMenu update = tMenuService.update(menu); if (ObjectUtils.allNotNull(update)) { return success(true); } return error404(false); } /** * 通过主键查询单条数据 * * @param id 主键 * @return 单条数据 */ @ApiOperation(value = "删除菜单功能", produces = "application/json") @PostMapping("deleteTree") public AjaxResult<Boolean> deleteTree(@RequestParam("id") Integer id) { boolean deleteById = tMenuService.deleteById(id); return success(deleteById); } }

    AjaxResult是个人设置的一个统一返回json格式类型的类,这个可以改成自己的,或者参考我的这篇博客。 前台代码

    首先需要引入jQuery和ztree的js和css样式,因为我使用的thymeleaf,所有在maven中需要导入thymeleaf依赖。还需要引入bootstrap。

    <!--thymeleaf视图解析器--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>

    对thymeleaf的版本进行调整

    <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>11</java.version> <thymeleaf.version>3.0.11.RELEASE</thymeleaf.version> <!-- 布局功能的支持程序 thymeleaf3主程序 layout2以上版本 --> <!-- thymeleaf2 layout1--> <thymeleaf-layout-dialect.version>2.2.2</thymeleaf-layout-dialect.version> </properties>

    前端的布局代码

    <link rel="stylesheet" href="../static/ztree/zTreeStyle.css" th:href="@{/ztree/zTreeStyle.css}"> <div class="panel-body"> <ul id="treeDemo" class="ztree"></ul> </div> <div th:include="~{script::script}"></div> //引入的增加功能的拟态框 <div th:include="~{permissions-add::permission-add}"></div> //引入的删除功能的拟态框 <div th:include="~{permissions-delete::deleteTree}"></div> //引入的编辑功能的拟态框 <div th:include="~{permissions-edit::editTree}"></div> <script th:src="@{/js/permissions/permissions.js}" src="../static/js/permissions/permissions.js"></script>

    这是主要代码,具体样式可以根据需求自己调整;

    这里引入的也就是jQuery和zTree的js以及bootstrap。增删改功能使用的是bootstrap的拟态框,可以自行了解。

    增加功能的拟态框。

    <!DOCTYPE html> <!--suppress ThymeleafVariablesResolveInspection --> <html lang="zh" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="description" content=""> <meta name="author" content=""> <title>权限菜单增加</title> </head> <body th:fragment="permission-add"> <div id="menuAddModal" class="modal fade" tabindex="-1" role="dialog"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">&times;</span> </button> <h4 class="modal-title">增加功能弹窗</h4> </div> <form> <div class="modal-body"> 请输入节点名称:<input type="text" name="name" /><br /> 请输入URL地址:<input type="text" name="url" /><br /> <i class="glyphicon glyphicon-th-list"></i> <input type="radio" name="icon" value="glyphicon glyphicon-th-list" />&nbsp; <i class="glyphicon glyphicon-dashboard"></i> <input type="radio" name="icon" value="glyphicon glyphicon-dashboard" /> &nbsp; <i class="glyphicon glyphicon glyphicon-tasks"></i> <input type="radio" name="icon" value="glyphicon glyphicon glyphicon-tasks" /> &nbsp; <i class="glyphicon glyphicon-user"></i> <input type="radio" name="icon" value="glyphicon glyphicon-user" /> &nbsp; <i class="glyphicon glyphicon-king"></i> <input type="radio" name="icon" value="glyphicon glyphicon-king" /> &nbsp; <i class="glyphicon glyphicon-lock"></i> <input type="radio" name="icon" value="glyphicon glyphicon-lock" /> &nbsp; <i class="glyphicon glyphicon-ok"></i> <input type="radio" name="icon" value="glyphicon glyphicon-ok" /> &nbsp; <i class="glyphicon glyphicon-check"></i> <input type="radio" name="icon" value="glyphicon glyphicon-check" /> &nbsp; <i class="glyphicon glyphicon-th-large"></i> <input type="radio" name="icon" value="glyphicon glyphicon-th-large" /> <br /> <i class="glyphicon glyphicon-picture"></i> <input type="radio" name="icon" value="glyphicon glyphicon-picture" /> &nbsp; <i class="glyphicon glyphicon-equalizer"></i> <input type="radio" name="icon" value="glyphicon glyphicon-equalizer" /> &nbsp; <i class="glyphicon glyphicon-random"></i> <input type="radio" name="icon" value="glyphicon glyphicon-random" /> &nbsp; <i class="glyphicon glyphicon-hdd"></i> <input type="radio" name="icon" value="glyphicon glyphicon-hdd" /> &nbsp; <i class="glyphicon glyphicon-comment"></i> <input type="radio" name="icon" value="glyphicon glyphicon-comment" /> &nbsp; <i class="glyphicon glyphicon-list"></i> <input type="radio" name="icon" value="glyphicon glyphicon-list" /> &nbsp; <i class="glyphicon glyphicon-tags"></i> <input type="radio" name="icon" value="glyphicon glyphicon-tags" /> &nbsp; <i class="glyphicon glyphicon-list-alt"></i> <input type="radio" name="icon" value="glyphicon glyphicon-list-alt" /> &nbsp; <br /> </div> <div class="modal-footer"> <button id="menuSaveBtn" type="button" class="btn btn-default"><i class="glyphicon glyphicon-plus"></i> 保存</button> <button id="menuResetBtn" type="reset" class="btn btn-primary"><i class="glyphicon glyphicon-refresh"></i> 重置</button> </div> </form> </div> </div> </div> </body> </html>

    删除功能的拟态框

    <!DOCTYPE html> <!--suppress ThymeleafVariablesResolveInspection --> <html lang="zh" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="description" content=""> <meta name="author" content=""> <title>菜单删除</title> </head> <body th:fragment="deleteTree"> <div id="menuConfirmModal" class="modal fade" tabindex="-1" role="dialog"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">&times;</span> </button> <h4 class="modal-title">删除功能弹窗</h4> </div> <form> <div class="modal-body"> 您真的要删除<span id="removeNodeSpan"></span>这个节点吗? </div> <div class="modal-footer"> <button id="confirmBtn" type="button" class="btn btn-danger"><i class="glyphicon glyphicon-ok"></i> OK</button> </div> </form> </div> </div> </div> </body> </html>

    修改功能的拟态框

    <!DOCTYPE html> <!--suppress ThymeleafVariablesResolveInspection --> <html lang="zh" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="description" content=""> <meta name="author" content=""> <title>菜单编辑</title> </head> <body th:fragment="editTree"> <div id="menuEditModal" class="modal fade" tabindex="-1" role="dialog"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">&times;</span> </button> <h4 class="modal-title">编辑功能弹窗</h4> </div> <form> <div class="modal-body"> 请输入节点名称:<input type="text" name="name" /><br /> 请输入URL地址:<input type="text" name="url" /><br /> <i class="glyphicon glyphicon-th-list"></i> <input type="radio" name="icon" value="glyphicon glyphicon-th-list" />&nbsp; <i class="glyphicon glyphicon-dashboard"></i> <input type="radio" name="icon" value="glyphicon glyphicon-dashboard" /> &nbsp; <i class="glyphicon glyphicon glyphicon-tasks"></i> <input type="radio" name="icon" value="glyphicon glyphicon glyphicon-tasks" /> &nbsp; <i class="glyphicon glyphicon-user"></i> <input type="radio" name="icon" value="glyphicon glyphicon-user" /> &nbsp; <i class="glyphicon glyphicon-king"></i> <input type="radio" name="icon" value="glyphicon glyphicon-king" /> &nbsp; <i class="glyphicon glyphicon-lock"></i> <input type="radio" name="icon" value="glyphicon glyphicon-lock" /> &nbsp; <i class="glyphicon glyphicon-ok"></i> <input type="radio" name="icon" value="glyphicon glyphicon-ok" /> &nbsp; <i class="glyphicon glyphicon-check"></i> <input type="radio" name="icon" value="glyphicon glyphicon-check" /> &nbsp; <i class="glyphicon glyphicon-th-large"></i> <input type="radio" name="icon" value="glyphicon glyphicon-th-large" /> <br /> <i class="glyphicon glyphicon-picture"></i> <input type="radio" name="icon" value="glyphicon glyphicon-picture" /> &nbsp; <i class="glyphicon glyphicon-equalizer"></i> <input type="radio" name="icon" value="glyphicon glyphicon-equalizer" /> &nbsp; <i class="glyphicon glyphicon-random"></i> <input type="radio" name="icon" value="glyphicon glyphicon-random" /> &nbsp; <i class="glyphicon glyphicon-hdd"></i> <input type="radio" name="icon" value="glyphicon glyphicon-hdd" /> &nbsp; <i class="glyphicon glyphicon-comment"></i> <input type="radio" name="icon" value="glyphicon glyphicon-comment" /> &nbsp; <i class="glyphicon glyphicon-list"></i> <input type="radio" name="icon" value="glyphicon glyphicon-list" /> &nbsp; <i class="glyphicon glyphicon-tags"></i> <input type="radio" name="icon" value="glyphicon glyphicon-tags" /> &nbsp; <i class="glyphicon glyphicon-list-alt"></i> <input type="radio" name="icon" value="glyphicon glyphicon-list-alt" /> &nbsp; <br /> </div> <div class="modal-footer"> <button id="menuEditBtn" type="button" class="btn btn-default"><i class="glyphicon glyphicon-edit"></i> 更新</button> </div> </form> </div> </div> </div> </body> </html>

    树形结构菜单的js

    window.pid = ''; $(function () { wholeTree(); //点击弹出拟态框 $("#treeDemo").on("click", ".addBtn", function () { //将当前节点的id作为新节点的pid保存到全局变量中 window.pid = this.id; $("#menuAddModal").modal("show"); return false; }); //点击弹出拟态框 $("#treeDemo").on("click", ".editBtn", function () { //将当前节点的id作为新节点的pid保存到全局变量中 window.id = this.id; console.log("编辑节点获取的id",window.id); $("#menuEditModal").modal("show"); //获取zTreeObj对象 let zTreeObj=$.fn.zTree.getZTreeObj("treeDemo"); //根据id属性查询节点对象 //用来搜索节点的属性名 let key="id"; //用来搜索节点的属性值 let value=window.id; //根据节点数据的属性搜索,获取条件完全匹配的节点数据json对象 let currentNode=zTreeObj.getNodeByParam(key,value); console.log("当前节点数据",currentNode); $("#menuEditModal [name=name]").val(currentNode.name); $("#menuEditModal [name=url]").val(currentNode.url); //radio回显的本质是把value属性和currentNode.icon一致的radio选中 $("#menuEditModal [name=icon]").val([currentNode.icon]); return false; }); //点击弹出拟态框 $("#treeDemo").on("click", ".removeBtn", function () { //将当前节点的id作为新节点的pid保存到全局变量中 window.id = this.id; $("#menuConfirmModal").modal("show"); //获取zTreeObj对象 let zTreeObj=$.fn.zTree.getZTreeObj("treeDemo"); //根据id属性查询节点对象 //用来搜索节点的属性名 let key="id"; //用来搜索节点的属性值 let value=window.id; //根据节点数据的属性搜索,获取条件完全匹配的节点数据json对象 let currentNode=zTreeObj.getNodeByParam(key,value); console.log("当前节点数据",currentNode); $("#removeNodeSpan").html('【<i class="'+currentNode.icon+'"></i>'+currentNode.name+'】'); return false; }); //添加按钮点击事件 $("#menuSaveBtn").click(function () { addTree(); }); //编辑按钮点击事件 $("#menuEditBtn").click(function () { editTree(); }); //删除按钮点击事件 $("#confirmBtn").click(function () { deleteTree(); }); }) //查询所有菜单信息 function wholeTree() { //创建JSON对象用于存储zTree所做的设置 let setting = { view: { addDiyDom: myAddDiyDom, addHoverDom: myAddHoveDom, removeHoverDom: myRemoveHoveDom }, //去除点击链接跳转的效果,URL中随便输入一个不存在的地址即可 data: { key: { url: "sxy" } }, }; $.ajax({ type: "post", url: ctx + "tMenu/wholeTree", dataType: "json", async: false, success: function (result) { console.log("输出结果:", result.data); // 初始化树形结构 $.fn.zTree.init($("#treeDemo"), setting, result.data); }, error: function (error) { console.log("错误信息", this.error); } }); } //修改默认图标 function myAddDiyDom(treeId, treeNode) { //找到图标的id let icoObj = $("#" + treeNode.tId + "_ico"); console.log("树状图图标", treeNode.icon); icoObj.removeClass("button ico_docu ico_open").addClass(treeNode.icon) .css("background", ""); } //鼠标移入节点范围时添加按钮组 function myAddHoveDom(treeId, treeNode) { //找到附着按钮组的超链接id var aObj = $("#" + treeNode.tId + "_a"); let btnFGroupId = treeNode.tId + "_btnGrp"; //判断一下以前是否已经添加了按钮组 if ($("#" + btnFGroupId).length > 0) { return; } let addBtn = '<a id="' + treeNode.id + '" class="btn btn-info dropdown-toggle btn-xs addBtn" style="margin-left:10px;padding-top:0;" href="#" title="添加子节点">  <i class="fa fa-fw fa-plus rbg "></i></a>'; let removeBtn = '<a id="' + treeNode.id + '" class="btn btn-info dropdown-toggle btn-xs removeBtn" style="margin-left:10px;padding-top:0;" href="#" title="删除节点">  <i class="fa fa-fw fa-times rbg "></i></a>'; let editBtn = '<a id="' + treeNode.id + '" class="btn btn-info dropdown-toggle btn-xs editBtn" style="margin-left:10px;padding-top:0;" href="#" title="修改节点">  <i class="fa fa-fw fa-edit rbg "></i></a>'; //获取当前节点的级别 var btnHTML = ''; if (treeNode.level === 0) { btnHTML = addBtn; } else if (treeNode.level === 1) { btnHTML = addBtn + " " + editBtn; if (treeNode.children.length === 0) { btnHTML += " " + removeBtn; } } else if (treeNode.level === 2) { btnHTML = editBtn + " " + removeBtn; } aObj.after('<span id="' + btnFGroupId + '">' + btnHTML + '</span>'); } //鼠标移开节点范围删除按钮组 function myRemoveHoveDom(treeId, treeNode) { $("#" + treeNode.tId + "_btnGrp").remove(); } //添加节点 function addTree() { //收集表单中的数据 let name = $("#menuAddModal [name=name]").val().trim(); let url = $("#menuAddModal [name=url]").val().trim(); //定位到被选中的那个按钮 let icon = $("#menuAddModal [name=icon]:checked").val(); if (name !== '' && url !== '' && icon !== '') { $.ajax({ type: "post", url: ctx + "tMenu/saveTree", data: JSON.stringify({ "pid": window.pid, "name": name, "url": url, "icon": icon }), dataType: "json", async: false, contentType: "application/json;charset=UTF-8", success: function (result) { console.log("输出结果:", result.data); if (result.data) { layer.msg("添加成功!"); wholeTree(); } else { layer.msg("添加失败!"); } }, error: function (error) { console.log("错误信息", this.error); } }); } else { layer.msg("所填信息不能为空!"); } $("#menuAddModal").modal("hide"); } //更新节点信息 function editTree() { //收集表单中的数据 let name = $("#menuEditModal [name=name]").val().trim(); let url = $("#menuEditModal [name=url]").val().trim(); //定位到被选中的那个按钮 let icon = $("#menuEditModal [name=icon]:checked").val(); if (name !== '' && url !== '' && icon !== '') { $.ajax({ type: "post", url: ctx + "tMenu/editTree", data: JSON.stringify({ "id": window.id, "name": name, "url": url, "icon": icon }), dataType: "json", async: false, contentType: "application/json;charset=UTF-8", success: function (result) { console.log("输出结果:", result.data); if (result.data) { layer.msg("添加成功!"); wholeTree(); } else { layer.msg("添加失败!"); } }, error: function (error) { console.log("错误信息", this.error); } }); } else { layer.msg("所填信息不能为空!"); } $("#menuEditModal").modal("hide"); } //删除节点 function deleteTree() { $.ajax({ type: "post", url: ctx + "tMenu/deleteTree", data: { "id": window.id }, dataType: "json", async: false, success: function (result) { console.log("输出结果:", result.data); if (result.data) { layer.msg("删除成功!"); wholeTree(); } else { layer.msg("删除失败!"); } }, error: function (error) { console.log("错误信息", this.error); } }); $("#menuConfirmModal").modal("hide"); }

    本篇参考尚硅谷实战教程尚筹网教学视频,如果想详细了解请去B站观看。

    Processed: 0.009, SQL: 9