数据库准备工作
数据库表结构如下:
CREATE TABLE `t_menu` (`c_id` varchar(80) NOT NULL COMMENT '主键',`c_name` varchar(15) NOT NULL COMMENT '菜单名称',`c_parent_id` varchar(80) NOT NULL COMMENT '父级菜单id',`c_icon` text COMMENT '图标',`c_type` tinyint(1) NOT NULL COMMENT '类型,字段menu_type',`c_create_id` varchar(80) NOT NULL COMMENT '创建者ID',`c_create_time` timestamp NOT NULL COMMENT '创建时间',`c_update_id` varchar(80) NOT NULL COMMENT '更新者ID',`c_update_time` timestamp NOT NULL COMMENT '更新时间',`c_no` int(10) DEFAULT NULL COMMENT '顺序',`c_del_flag` tinyint(1) NOT NULL COMMENT '是否删除',PRIMARY KEY (`c_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='菜单'
插入数据:
INSERT INTO `t_menu` (`c_id`, `c_name`,`c_parent_id`, `c_icon`,`c_type`, `c_create_id`, `c_create_time`,`c_update_id`, `c_update_time`, `c_no`, `c_del_flag`
)
VALUES('0_0_01ec9a90f6b34439bb979e4fad37852b','百叶箱数据','0_0_61379d8d12b3456797188a9044d14f3c',NULL, 2,'0_0_4c7b563b83fc410c957d08403b9e25ff', '2024-03-18 22:43:30','0_0_4c7b563b83fc410c957d08403b9e25ff', '2024-03-18 22:43:30', 1,0),('0_0_090d3da1301841f6b43e3a3ff2b44f68', '删除','0_0_c982f477026541848405484f08ff1dfa', NULL, 2,'0_0_4c7b563b83fc410c957d08403b9e25ff', '2024-03-20 11:04:09','0_0_4c7b563b83fc410c957d08403b9e25ff', '2024-03-20 11:07:34', 3, 0),('0_0_0ab19e321a5f490e9015f6e4cd496d27','分配菜单','0_0_e7b9049e8ad34a78af90286b63f4759c', NULL, 3,'0_0_4c7b563b83fc410c957d08403b9e25ff','2024-03-19 10:08:44','0_0_4c7b563b83fc410c957d08403b9e25ff', '2024-03-19 10:08:44',4, 0),('0_0_3983284d54104f359b8406a50fa45632','4444','0_0_f887ea1dc38341559285926c54123516', NULL, 3,'0_0_4c7b563b83fc410c957d08403b9e25ff','2024-03-22 11:00:16','0_0_4c7b563b83fc410c957d08403b9e25ff','2024-03-22 11:00:16', 1, 0),('0_0_3de80520f6f74b2386b8381a564c4e09', '删除','0_0_99cad34fd9814ff4a8c88e72d60a552d', NULL, 3,'0_0_4c7b563b83fc410c957d08403b9e25ff', '2024-03-19 09:54:43','0_0_4c7b563b83fc410c957d08403b9e25ff', '2024-03-19 09:54:43', 3, 0),('0_0_545fb128881f462f8bc828b54e19e034','删除', '0_0_da9e85f955f44e16bfa8a20659de30d7', NULL, 3,'0_0_4c7b563b83fc410c957d08403b9e25ff', '2024-03-19 09:38:27','0_0_4c7b563b83fc410c957d08403b9e25ff', '2024-03-19 09:38:27', 3, 0),('0_0_61379d8d12b3456797188a9044d14f3c', '智慧农业', '-1', NULL, 1,'0_0_4c7b563b83fc410c957d08403b9e25ff', '2024-03-18 21:31:47', '0_0_4c7b563b83fc410c957d08403b9e25ff','2024-03-18 21:31:47', 2, 0),('0_0_634317d8797e4aacb467e348a1ac8924','添加','0_0_c982f477026541848405484f08ff1dfa', NULL, 2,'0_0_4c7b563b83fc410c957d08403b9e25ff', '2024-03-20 11:03:33','0_0_4c7b563b83fc410c957d08403b9e25ff', '2024-03-20 11:06:46', 1,0),('0_0_661824d0f33441aba8236d5be366434f','系统管理','-1', NULL, 1,'0_0_4c7b563b83fc410c957d08403b9e25ff','2024-03-18 21:02:49','0_0_4c7b563b83fc410c957d08403b9e25ff','2024-03-18 21:02:49',1,0),('0_0_6a71439c4de84eb19f99648df760c9c0','修改','0_0_e7b9049e8ad34a78af90286b63f4759c',NULL,3,'0_0_4c7b563b83fc410c957d08403b9e25ff','2024-03-19 10:08:21','0_0_4c7b563b83fc410c957d08403b9e25ff','2024-03-19 10:08:21',2,0),('0_0_729b70ba39144dbb930547d39e4700b0', '添加','0_0_e7b9049e8ad34a78af90286b63f4759c', NULL, 3,'0_0_4c7b563b83fc410c957d08403b9e25ff','2024-03-19 10:08:13','0_0_4c7b563b83fc410c957d08403b9e25ff','2024-03-19 10:08:13',1, 0),('0_0_843138ca616b466b8904c53c31b1bd2e','添加','0_0_da9e85f955f44e16bfa8a20659de30d7',NULL,3,'0_0_4c7b563b83fc410c957d08403b9e25ff','2024-03-19 09:38:10','0_0_4c7b563b83fc410c957d08403b9e25ff','2024-03-19 09:38:10',1,0),('0_0_99cad34fd9814ff4a8c88e72d60a552d', '用户管理','0_0_661824d0f33441aba8236d5be366434f', NULL, 2,'0_0_4c7b563b83fc410c957d08403b9e25ff','2024-03-18 21:04:43','0_0_4c7b563b83fc410c957d08403b9e25ff','2024-03-18 21:04:43', 1,0),('0_0_a3486bd0026f47c298b5d2d55db6f733', '重置密码','0_0_99cad34fd9814ff4a8c88e72d60a552d', NULL, 3,'0_0_4c7b563b83fc410c957d08403b9e25ff', '2024-03-19 09:54:58','0_0_4c7b563b83fc410c957d08403b9e25ff', '2024-03-19 09:54:58', 4, 0),('0_0_a695d1d7a5c243379ceae6560855496e', '删除','0_0_e7b9049e8ad34a78af90286b63f4759c', NULL, 3,'0_0_4c7b563b83fc410c957d08403b9e25ff', '2024-03-19 10:08:28','0_0_4c7b563b83fc410c957d08403b9e25ff', '2024-03-19 10:08:28',3, 0),('0_0_a88b254640f94f3c9afab62ef10dbedb', '分配角色','0_0_99cad34fd9814ff4a8c88e72d60a552d', NULL, 3,'0_0_4c7b563b83fc410c957d08403b9e25ff', '2024-03-19 09:55:20','0_0_4c7b563b83fc410c957d08403b9e25ff', '2024-03-19 09:55:20', 5, 0),('0_0_acf36bbee31541ad874af0b78de92ff5', '删除','0_0_01ec9a90f6b34439bb979e4fad37852b', NULL, 3,'0_0_4c7b563b83fc410c957d08403b9e25ff','2024-03-19 09:35:33','0_0_4c7b563b83fc410c957d08403b9e25ff', '2024-03-19 09:35:33', 1,0),('0_0_bf244c78e686400db9808cd5fb0c3c91','修改','0_0_c982f477026541848405484f08ff1dfa', NULL,2,'0_0_4c7b563b83fc410c957d08403b9e25ff','2024-03-20 11:04:02','0_0_4c7b563b83fc410c957d08403b9e25ff','2024-03-20 11:07:19', 2,0),('0_0_c8085841164547a5834d51eb7d3f566f','修改','0_0_99cad34fd9814ff4a8c88e72d60a552d', NULL,3,'0_0_4c7b563b83fc410c957d08403b9e25ff','2024-03-19 09:54:34','0_0_4c7b563b83fc410c957d08403b9e25ff', '2024-03-19 09:54:34',2,0),('0_0_c982f477026541848405484f08ff1dfa','接口权限','0_0_661824d0f33441aba8236d5be366434f', NULL, 2,'0_0_4c7b563b83fc410c957d08403b9e25ff','2024-03-18 21:16:20','0_0_4c7b563b83fc410c957d08403b9e25ff','2024-03-20 10:58:32', 4,0),('0_0_d00f45f79a1941ad9adc0567352e6670', '修改','0_0_da9e85f955f44e16bfa8a20659de30d7', NULL, 3,'0_0_4c7b563b83fc410c957d08403b9e25ff', '2024-03-19 09:38:18','0_0_4c7b563b83fc410c957d08403b9e25ff','2024-03-19 09:38:18', 2, 0),('0_0_da9e85f955f44e16bfa8a20659de30d7', '菜单管理','0_0_661824d0f33441aba8236d5be366434f', NULL, 2,'0_0_4c7b563b83fc410c957d08403b9e25ff', '2024-03-18 21:05:38','0_0_4c7b563b83fc410c957d08403b9e25ff', '2024-03-18 21:05:38', 2, 0),('0_0_e7b9049e8ad34a78af90286b63f4759c', '角色管理','0_0_661824d0f33441aba8236d5be366434f', NULL, 2,'0_0_4c7b563b83fc410c957d08403b9e25ff', '2024-03-18 21:04:57','0_0_4c7b563b83fc410c957d08403b9e25ff', '2024-03-18 21:04:57', 3, 0),('0_0_f887ea1dc38341559285926c54123516', '添加','0_0_99cad34fd9814ff4a8c88e72d60a552d', NULL, 3, '0_0_4c7b563b83fc410c957d08403b9e25ff','2024-03-19 09:54:26', '0_0_4c7b563b83fc410c957d08403b9e25ff','2024-03-19 09:54:26', 1, 0) ;
代码实现
Menu实体类,每个属性对应数据库的字段:
import java.sql.Timestamp;public class Menu {
private String id; // 主键private String name; // 菜单名称private String parentId; // 父级菜单idprivate String icon; // 图标private Integer type; // 类型 1=目录,2=菜单,3=按钮private String createId; // 创建者IDprivate Timestamp createTime; // 创建时间private String updateId; // 更新者IDprivate Timestamp updateTime; // 更新时间private Integer no; // 顺序private Integer delFlag; // 是否删除// getter/setters 忽略
}
Menu的DTO类,用来保存树形结构:
private String id; // 主键private List<String> ids;private String name; // 菜单名称private String parentId; // 父级菜单idprivate List<String> parentIds;private String icon; // 图标private Integer code; // 菜单编码private Integer type; // 类型 字典menu_typeprivate String createId; // 创建者IDprivate Timestamp createTime; // 创建时间private String updateId; // 更新者IDprivate Timestamp updateTime; // 更新时间private Integer no; // 顺序private Integer delFlag; // 是否删除private List<MenuDto> children = new ArrayList<>();private String orderBy;private String asc;
// getter/setters 忽略
mybatis的MenuMapper接口:
package zhangchao.readdbtree;import java.util.List;
import org.apache.ibatis.annotations.Param;public interface MenuMapper {Menu selectById(@Param("id") String id);List<Menu> selectList(MenuDto menuDto);
}
MenuMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="zhangchao.readdbtree.MenuMapper"><resultMap id="rm" type="zhangchao.readdbtree.Menu"><id property="id" column="c_id"/><result property="name" column="c_name"/><result property="parentId" column="c_parent_id"/><result property="icon" column="c_icon"/><result property="type" column="c_type"/><result property="createId" column="c_create_id"/><result property="createTime" column="c_create_time"/><result property="updateId" column="c_update_id"/><result property="updateTime" column="c_update_time"/><result property="no" column="c_no"/><result property="delFlag" column="c_del_flag"/></resultMap><select id="selectById" resultMap="rm">select * from t_menu where c_id=#{id}</select><select id="selectList" resultMap="rm">select * from t_menu where 1=1<if test="name != null">and c_name like concat('%', #{name}, '%')</if><if test="parentId != null">and c_parent_id = #{parentId}</if><if test="parentIds != null and parentIds.size() > 0">and c_parent_id in<foreach collection="parentIds" open="(" close=")" separator="," item="item">#{item}</foreach></if><if test="type != null">and c_type = #{type}</if><if test="delFlag != null">and c_del_flag = #{delFlag}</if><if test="ids != null and ids.size() > 0">and c_id in<foreach collection="ids" open="(" close=")" separator="," item="item">#{item}</foreach></if><if test="orderBy != null and asc != null">order by ${orderBy} ${asc}</if></select>
</mapper>
mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="com.mysql.cj.jdbc.Driver"/><property name="url" value="jdbc:mysql://127.0.0.1:3306/test"/><property name="username" value="root"/><property name="password" value="123456"/></dataSource></environment></environments><mappers><mapper resource="mapper/CityMapper.xml"/><mapper resource="mapper/MenuMapper.xml"/>
<!-- <mapper resource="mapper/LogMapper.xml"/>--></mappers>
</configuration>
加载mybatis的类DBFactory
package zhangchao.common.db;import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;import java.io.IOException;
import java.io.InputStream;public class DBFactory {private static SqlSessionFactory sqlSessionFactory = null;static {String resource = "mybatis-config.xml";InputStream inputStream = null;try {inputStream = Resources.getResourceAsStream(resource);} catch (IOException e) {e.printStackTrace();}sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);}public static SqlSessionFactory getInstance(){return sqlSessionFactory;}}
整个算法的核心类MenuService,该类包含了三个算法:
- 查找整棵树的树形结构
- 根据若干ID查找对应的树节点,并按照树形结构返回结果。
- 传入某个节点的ID,把以该节点为根的子树都查找出来
具体代码如下:
package zhangchao.readdbtree;import org.apache.ibatis.session.SqlSession;
import zhangchao.common.db.DBFactory;import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;/*** @author zhangchao*/
public class MenuService {private void menuToDto(Menu menu, MenuDto menuDto) {menuDto.setId(menu.getId());menuDto.setName(menu.getName());menuDto.setParentId(menu.getParentId());menuDto.setIcon(menu.getIcon());menuDto.setType(menu.getType());menuDto.setNo(menu.getNo());}/*** 查找整棵树的树形结构* @return 整棵树的树形结构*/public List<MenuDto> allMenuTree() {List<MenuDto> result = new ArrayList<>();MenuDto sqlParam = new MenuDto();sqlParam.setParentId("-1");sqlParam.setDelFlag(0);sqlParam.setOrderBy("c_no");sqlParam.setAsc("asc");SqlSession sqlSession = DBFactory.getInstance().openSession(true);MenuMapper menuMapper = sqlSession.getMapper(MenuMapper.class);try {// 先把顶层加入resultList<Menu> menuList_1 = menuMapper.selectList(sqlParam);for (Menu menu_1 : menuList_1) {MenuDto menuDto_1 = new MenuDto();this.menuToDto(menu_1, menuDto_1);result.add(menuDto_1);}List<MenuDto> currentLevel = result;while (currentLevel != null && !currentLevel.isEmpty()) {List<String> parentIds = new ArrayList<>();Map<String, MenuDto> map = new HashMap<>();for (MenuDto dto : currentLevel) {String id = dto.getId();parentIds.add(id);map.put(id, dto);if (dto.getChildren() == null) {dto.setChildren(new ArrayList<>());}}sqlParam.setParentId(null);sqlParam.setParentIds(parentIds);List<Menu> dbNextLevel = menuMapper.selectList(sqlParam);List<MenuDto> nextLevel = new ArrayList<>();if (dbNextLevel != null && !dbNextLevel.isEmpty()) {for (Menu menu : dbNextLevel) {MenuDto menuDto = new MenuDto();this.menuToDto(menu, menuDto);map.get(menu.getParentId()).getChildren().add(menuDto);nextLevel.add(menuDto);}}currentLevel = nextLevel;}} finally {sqlSession.close();}return result;}/*** 根据若干ID查找对应的树节点,并按照树形结构返回结果。* @param ids 树节点ID列表* @return 树形结构*/public List<MenuDto> selectMenuTreeByIds(List<String> ids) {List<MenuDto> result = new ArrayList<>();MenuDto sqlParam = new MenuDto();sqlParam.setIds(ids);sqlParam.setParentId("-1");sqlParam.setDelFlag(0);sqlParam.setOrderBy("c_no");sqlParam.setAsc("asc");SqlSession sqlSession = DBFactory.getInstance().openSession(true);MenuMapper menuMapper = sqlSession.getMapper(MenuMapper.class);try {// 先把顶层加入resultList<Menu> menuList_1 = menuMapper.selectList(sqlParam);for (Menu menu_1 : menuList_1) {MenuDto menuDto_1 = new MenuDto();this.menuToDto(menu_1, menuDto_1);result.add(menuDto_1);}List<MenuDto> curentLevel = result;while (curentLevel != null && !curentLevel.isEmpty()) {List<String> parentIds = new ArrayList<>();Map<String, MenuDto> map = new HashMap<>();// 这个for循环是为了给 parentIds 和 map 添加元素。for (MenuDto dto : curentLevel) {String id = dto.getId();parentIds.add(id);map.put(id, dto);if (dto.getChildren() == null) {dto.setChildren(new ArrayList<>());}}// 设置查询下一级节点的参数。sqlParam.setParentId(null);sqlParam.setParentIds(parentIds);// 从数据库中查询下一级节点。List<Menu> dbNextLevel = menuMapper.selectList(sqlParam);// 下一级节点的dto列表。List<MenuDto> nextLevel = new ArrayList<>();if (dbNextLevel != null && !dbNextLevel.isEmpty()) {for (Menu menu : dbNextLevel) {MenuDto menuDto = new MenuDto();this.menuToDto(menu, menuDto);map.get(menu.getParentId()).getChildren().add(menuDto);nextLevel.add(menuDto);}}curentLevel = nextLevel;}} finally {sqlSession.close();}return result;}/*** 传入某个节点的ID,把以该节点为根的子树都查找出来* @param subRootId 节点ID* @return 以传入节点为根的子树*/public List<MenuDto> subTree(String subRootId) {List<MenuDto> result = new ArrayList<>();SqlSession sqlSession = DBFactory.getInstance().openSession(true);MenuMapper menuMapper = sqlSession.getMapper(MenuMapper.class);try {Menu root = menuMapper.selectById(subRootId);// 先把顶层加入resultList<Menu> menuList_1 = new ArrayList<>();if (root != null && root.getDelFlag() == 0) {menuList_1.add(root);}for (Menu menu_1 : menuList_1) {MenuDto menuDto_1 = new MenuDto();this.menuToDto(menu_1, menuDto_1);result.add(menuDto_1);}MenuDto sqlParam = new MenuDto();sqlParam.setDelFlag(0);sqlParam.setOrderBy("c_no");sqlParam.setAsc("asc");List<MenuDto> curentLevel = result;while (curentLevel != null && !curentLevel.isEmpty()) {List<String> parentIds = new ArrayList<>();Map<String, MenuDto> map = new HashMap<>();// 这个for循环是为了给 parentIds 和 map 添加元素。for (MenuDto dto : curentLevel) {String id = dto.getId();parentIds.add(id);map.put(id, dto);if (dto.getChildren() == null) {dto.setChildren(new ArrayList<>());}}// 设置查询下一级节点的参数。sqlParam.setParentId(null);sqlParam.setParentIds(parentIds);// 从数据库中查询下一级节点。List<Menu> dbNextLevel = menuMapper.selectList(sqlParam);// 下一级节点的dto列表。List<MenuDto> nextLevel = new ArrayList<>();if (dbNextLevel != null && !dbNextLevel.isEmpty()) {for (Menu menu : dbNextLevel) {MenuDto menuDto = new MenuDto();this.menuToDto(menu, menuDto);map.get(menu.getParentId()).getChildren().add(menuDto);nextLevel.add(menuDto);}}curentLevel = nextLevel;}} finally {sqlSession.close();}return result;}
}
调用类TestReadDbTree:
package zhangchao.readdbtree;import com.google.gson.Gson;import java.util.ArrayList;
import java.util.List;public class TestReadDbTree {public static void main(String[] args) {MenuService menuService = new MenuService();List<MenuDto> allTree = menuService.allMenuTree();Gson gson = new Gson();// 整棵树System.out.println(gson.toJson(allTree));// 选中的部分树节点List<String> ids = new ArrayList<>();ids.add("0_0_661824d0f33441aba8236d5be366434f");ids.add("0_0_99cad34fd9814ff4a8c88e72d60a552d");ids.add("0_0_61379d8d12b3456797188a9044d14f3c");ids.add("0_0_01ec9a90f6b34439bb979e4fad37852b");ids.add("0_0_acf36bbee31541ad874af0b78de92ff5");List<MenuDto> selectedTree = menuService.selectMenuTreeByIds(ids);System.out.println(gson.toJson(selectedTree));// 传入某个节点的ID,把以该节点为根的子树都查找出来List<MenuDto> subTree = menuService.subTree("0_0_99cad34fd9814ff4a8c88e72d60a552d");System.out.println(gson.toJson(subTree));}
}
输出结果
整棵树形结构:
[{"id": "0_0_661824d0f33441aba8236d5be366434f","name": "系统管理","parentId": "-1","type": 1,"no": 1,"children": [{"id": "0_0_99cad34fd9814ff4a8c88e72d60a552d","name": "用户管理","parentId": "0_0_661824d0f33441aba8236d5be366434f","type": 2,"no": 1,"children": [{"id": "0_0_f887ea1dc38341559285926c54123516","name": "添加","parentId": "0_0_99cad34fd9814ff4a8c88e72d60a552d","type": 3,"no": 1,"children": []},{"id": "0_0_c8085841164547a5834d51eb7d3f566f","name": "修改","parentId": "0_0_99cad34fd9814ff4a8c88e72d60a552d","type": 3,"no": 2,"children": []},{"id": "0_0_3de80520f6f74b2386b8381a564c4e09","name": "删除","parentId": "0_0_99cad34fd9814ff4a8c88e72d60a552d","type": 3,"no": 3,"children": []},{"id": "0_0_a3486bd0026f47c298b5d2d55db6f733","name": "重置密码","parentId": "0_0_99cad34fd9814ff4a8c88e72d60a552d","type": 3,"no": 4,"children": []},{"id": "0_0_a88b254640f94f3c9afab62ef10dbedb","name": "分配角色","parentId": "0_0_99cad34fd9814ff4a8c88e72d60a552d","type": 3,"no": 5,"children": []}]},{"id": "0_0_da9e85f955f44e16bfa8a20659de30d7","name": "菜单管理","parentId": "0_0_661824d0f33441aba8236d5be366434f","type": 2,"no": 2,"children": [{"id": "0_0_843138ca616b466b8904c53c31b1bd2e","name": "添加","parentId": "0_0_da9e85f955f44e16bfa8a20659de30d7","type": 3,"no": 1,"children": []},{"id": "0_0_d00f45f79a1941ad9adc0567352e6670","name": "修改","parentId": "0_0_da9e85f955f44e16bfa8a20659de30d7","type": 3,"no": 2,"children": []},{"id": "0_0_545fb128881f462f8bc828b54e19e034","name": "删除","parentId": "0_0_da9e85f955f44e16bfa8a20659de30d7","type": 3,"no": 3,"children": []}]},{"id": "0_0_e7b9049e8ad34a78af90286b63f4759c","name": "角色管理","parentId": "0_0_661824d0f33441aba8236d5be366434f","type": 2,"no": 3,"children": [{"id": "0_0_729b70ba39144dbb930547d39e4700b0","name": "添加","parentId": "0_0_e7b9049e8ad34a78af90286b63f4759c","type": 3,"no": 1,"children": []},{"id": "0_0_6a71439c4de84eb19f99648df760c9c0","name": "修改","parentId": "0_0_e7b9049e8ad34a78af90286b63f4759c","type": 3,"no": 2,"children": []},{"id": "0_0_a695d1d7a5c243379ceae6560855496e","name": "删除","parentId": "0_0_e7b9049e8ad34a78af90286b63f4759c","type": 3,"no": 3,"children": []},{"id": "0_0_0ab19e321a5f490e9015f6e4cd496d27","name": "分配菜单","parentId": "0_0_e7b9049e8ad34a78af90286b63f4759c","type": 3,"no": 4,"children": []}]},{"id": "0_0_c982f477026541848405484f08ff1dfa","name": "接口权限","parentId": "0_0_661824d0f33441aba8236d5be366434f","type": 2,"no": 4,"children": [{"id": "0_0_634317d8797e4aacb467e348a1ac8924","name": "添加","parentId": "0_0_c982f477026541848405484f08ff1dfa","type": 2,"no": 1,"children": []},{"id": "0_0_bf244c78e686400db9808cd5fb0c3c91","name": "修改","parentId": "0_0_c982f477026541848405484f08ff1dfa","type": 2,"no": 2,"children": []},{"id": "0_0_090d3da1301841f6b43e3a3ff2b44f68","name": "删除","parentId": "0_0_c982f477026541848405484f08ff1dfa","type": 2,"no": 3,"children": []}]}]},{"id": "0_0_61379d8d12b3456797188a9044d14f3c","name": "智慧农业","parentId": "-1","type": 1,"no": 2,"children": [{"id": "0_0_01ec9a90f6b34439bb979e4fad37852b","name": "百叶箱数据","parentId": "0_0_61379d8d12b3456797188a9044d14f3c","type": 2,"no": 1,"children": [{"id": "0_0_acf36bbee31541ad874af0b78de92ff5","name": "删除","parentId": "0_0_01ec9a90f6b34439bb979e4fad37852b","type": 3,"no": 1,"children": []}]}]}
]
选中的节点
[{"id": "0_0_661824d0f33441aba8236d5be366434f","name": "系统管理","parentId": "-1","type": 1,"no": 1,"children": [{"id": "0_0_99cad34fd9814ff4a8c88e72d60a552d","name": "用户管理","parentId": "0_0_661824d0f33441aba8236d5be366434f","type": 2,"no": 1,"children": []}]},{"id": "0_0_61379d8d12b3456797188a9044d14f3c","name": "智慧农业","parentId": "-1","type": 1,"no": 2,"children": [{"id": "0_0_01ec9a90f6b34439bb979e4fad37852b","name": "百叶箱数据","parentId": "0_0_61379d8d12b3456797188a9044d14f3c","type": 2,"no": 1,"children": [{"id": "0_0_acf36bbee31541ad874af0b78de92ff5","name": "删除","parentId": "0_0_01ec9a90f6b34439bb979e4fad37852b","type": 3,"no": 1,"children": []}]}]}
]
某棵子树
[{"id": "0_0_99cad34fd9814ff4a8c88e72d60a552d","name": "用户管理","parentId": "0_0_661824d0f33441aba8236d5be366434f","type": 2,"no": 1,"children": [{"id": "0_0_f887ea1dc38341559285926c54123516","name": "添加","parentId": "0_0_99cad34fd9814ff4a8c88e72d60a552d","type": 3,"no": 1,"children": [{"id": "0_0_3983284d54104f359b8406a50fa45632","name": "4444","parentId": "0_0_f887ea1dc38341559285926c54123516","type": 3,"no": 1,"children": []}]},{"id": "0_0_c8085841164547a5834d51eb7d3f566f","name": "修改","parentId": "0_0_99cad34fd9814ff4a8c88e72d60a552d","type": 3,"no": 2,"children": []},{"id": "0_0_3de80520f6f74b2386b8381a564c4e09","name": "删除","parentId": "0_0_99cad34fd9814ff4a8c88e72d60a552d","type": 3,"no": 3,"children": []},{"id": "0_0_a3486bd0026f47c298b5d2d55db6f733","name": "重置密码","parentId": "0_0_99cad34fd9814ff4a8c88e72d60a552d","type": 3,"no": 4,"children": []},{"id": "0_0_a88b254640f94f3c9afab62ef10dbedb","name": "分配角色","parentId": "0_0_99cad34fd9814ff4a8c88e72d60a552d","type": 3,"no": 5,"children": []}]}
]