树形结构菜单的增删改查

树形结构的样例
在这里插入图片描述
约定:整个树形结构节点的层次最多能有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="添加子节点">&nbsp;&nbsp;<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="删除节点">&nbsp;&nbsp;<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="修改节点">&nbsp;&nbsp;<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站观看。

猜你喜欢

转载自blog.csdn.net/weixin_43897590/article/details/107081800