树结构展示

树结构

方式一:一张表

一张表中含有id pid name 等字段

后台代码
    @RequestMapping("/showTree")
    public ABResponse showTree(){
        ABResponse groupGetAll = remoteService.group_getAll();
        List<RmGroup> getAllData = (List<RmGroup>) groupGetAll.getData();

        List<Menu>  menuList= new ArrayList<Menu>();

        for (int i = 0; i < getAllData.size(); i++) {
            Menu menu = new Menu();
            menu.setId(String.valueOf(getAllData.get(i).getId()));
            menu.setPid(String.valueOf(getAllData.get(i).getParentId()));
            menu.setText(getAllData.get(i).getName());
            menuList.add(menu);
        }
        /*让我们创建树*/
        MenuTree menuTree =new MenuTree(menuList);
        menuList=menuTree.builTree();

        String jsonOutput= JSON.toJSONString(menuList);
        System.out.println(jsonOutput);

        return ABResponse.buildSuccessData(jsonOutput);
    }
工具类

import java.util.ArrayList;
import java.util.List;

public class MenuTree {
    private List<Menu> menuList = new ArrayList<Menu>();
    public MenuTree(List<Menu> menuList) {
        this.menuList=menuList;
    }

    //建立树形结构
    public List<Menu> builTree(){
        List<Menu> treeMenus =new  ArrayList<Menu>();
        for(Menu menuNode : getRootNode()) {
            menuNode=buildChilTree(menuNode);
            treeMenus.add(menuNode);
        }
        return treeMenus;
    }

    //递归,建立子树形结构
    private Menu buildChilTree(Menu pNode){
        List<Menu> chilMenus =new  ArrayList<Menu>();
        for(Menu menuNode : menuList) {
            if(menuNode.getPid().equals(pNode.getId())) {
                chilMenus.add(buildChilTree(menuNode));
            }
        }
        pNode.setNodes(chilMenus);
        return pNode;
    }

    //获取根节点
    private List<Menu> getRootNode() {
        List<Menu> rootMenuLists =new  ArrayList<Menu>();
        for(Menu menuNode : menuList) {
            if(menuNode.getPid().equals("0")) {
                rootMenuLists.add(menuNode);
            }
        }
        return rootMenuLists;
    }
}

实体类
package com.abview.pojo;

import com.fasterxml.jackson.annotation.JsonProperty;

import java.util.List;

public class Menu {
    private String id;
    @JsonProperty(value = "pid")
    private String pid;
    private String text;
    private String url;
    private String yxbz;

    public Menu() {
    }

    @JsonProperty(value = "nodes")
    private List<Menu> nodes;

    public Menu(String id, String pid, String text, String url, String yxbz) {
        this.id = id;
        this.pid = pid;
        this.text = text;
        this.url = url;
        this.yxbz = yxbz;
    }
    /*省略get\set*/

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getPid() {
        return pid;
    }

    public void setPid(String pid) {
        this.pid = pid;
    }

    public List<Menu> getNodes() {
        return nodes;
    }

    public void setNodes(List<Menu> nodes) {
        this.nodes = nodes;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getYxbz() {
        return yxbz;
    }

    public void setYxbz(String yxbz) {
        this.yxbz = yxbz;
    }

}

前端代码使用treeview实现
<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>移动到</title>
    <script type="text/javascript" src="../../../js/jquery/jquery-2.1.4/jquery.min.js"></script>
    <script src="../../../js/common/extends.js"></script>
    <script src="../../../js/common/Utils.js"></script>
    <script type="text/javascript" src="../../../js/jquery/jquery.form.js"></script>
    <link rel="stylesheet" type="text/css" href="../../../js/bootstrap/css/bootstrap.min.css"/>
    <script src="../../../js/bootstrap/js/bootstrap.min.js" type="text/javascript"></script>
    <script type="text/javascript" src="../../../js/bootstrap/js/bootbox.min.js"></script>
    <script type='text/javascript' src='../../../js/icheck-1.x/icheck.js'></script>
    <link rel="stylesheet" href="../../../js/icheck-1.x/skins/icheck.css" type="text/css"/>
    <script src="../../../js/bootstrap/js/bootstrapValidator.js" type="text/javascript"></script>
 //  下面是treeview
    <link href="../../../js/bootstrap-treeview/bootstrap-treeview.min.css" rel="stylesheet"/>
    <script src="../../../js/bootstrap-treeview/bootstrap-treeview.min.js" type="text/javascript"></script>


    <style>
        #tv {
            border: 1px solid #D6D6D6;
            display: none;
            width: 300px;
            height: 400px;
            overflow-x: hidden;
            overflow-y: auto;
        }
    </style>
    <script>
        MoveDevBackUtils = {
            submit: function () {
                //    获取设备id和分组id
                var pid = $("#pid").val();
                var deviceId = $("#deviceId").val();
                if (pid == null||pid === "") {
                    parent.parent.toastr["error"]("分组名称不存在");
                    return;
                }

                $.ajax({
                    url: '../../../ra/tree/moveDevice',
                    dataType: 'json',
                    data: {
                        pid: pid,
                        deviceId: deviceId
                    },
                    method: 'post',
                    success: function (data) {
                        parent.TopoListUtils.closeMoveDevice();
                        parent.TopoListUtils.refreshTopoList();
                        parent.parent.toastr["info"]("成功!");
                        parent.parent.parent.topoObject.flushMenu();
                    },
                    error: function () {
                        parent.parent.toastr["error"]("请重试!");
                    }
                })
            },

            getGroupId: function () {
                //    获取设备mac地址和分组id
                var pid = $("#pid").val();
                var mac = $("#deviceId").val();
                if (pid == null||pid === "") {
                    parent.parent.toastr["error"]("分组名称不存在");
                    return;
                }
                return pid;
            },




            init: function () {
                var iddata = $.UrlUtils.getParam("iddata");
                $("#deviceId").val(iddata);

                var nodeData = [];

                $.ajax({
                    url: '../../../ra/tree/showTree',
                    type: 'post',
                    dataType: 'json',
                    async: false,
                    success: function (data) {
                        nodeData = data.data;
                    }
                })

                $('#tv').treeview({
                    data: nodeData,                        // 节点数据
                    levels: 1,                             // 节点层级数
                    color: "#000",                         // 每一级通用的 节点字体颜色
                    backColor: "#fff",                     // 每一级通用的 节点字背景色
                    onhoverColor: "skyblue",               // 选中浮动颜色
                    showBorder: false,                     // 不显示边框
                    showTags: true,                        // 是否在每个节点的右侧显示标签。 其值必须在每个节点的数据结构中提供
                    highlightSelected: true,               // 是否突出显示选定的节点
                    selectedColor: "#fff",                 // 设置选定节点的前景色
                    selectedBackColor: "skyblue",          // 设置选定节点的背景色
                    onNodeSelected: function (event, data) {
                        $('#region').val(data.text);
                        $('#pid').val(data.id);
                        $('#tv').hide();
                    }
                })

                $('#region').click(function () {
                    $('#tv').show();
                })


            }
        }
    </script>
</head>

<body>
<div class="container">
    <div class="row-fluid">
        <div class="row">
            <div class="col-md-offset-4 col-md-3">
                <form id="moveGroupForm">
                    <div class="form-group">
                        <input id="pid" value="" hidden>
                        <input id="deviceId" value="" hidden>
                        <label for="region">分组名称</label>
                        <input id="region" class="form-control" value="Root" type="text" placeholder="请选择分组"
                               style="width:200px;" name="groupName"/>
                        <div id="tv"></div>
                    </div>

<!--                    <div class="form-group" style="margin-bottom: 10px ">-->
<!--                        <input class="btn btn-primary" value="确认" onclick="MoveDevUtils.submit()"/>-->
<!--                    </div>-->
                </form>
            </div>
        </div>
    </div>
</div>

<script>

    $(function () {
        MoveDevBackUtils.init();
    });

</script>

</body>
</html>

模拟数据进行展示

进行数据模拟展示

package com.example.demo2;

import com.alibaba.fastjson.JSON;
import com.example.demo.entry.Menu;
import com.example.demo.utils.MenuTreeData;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
//  classes = DemoApplicationTests.class 独立运行避免出错
@SpringBootTest(classes = DemoApplicationTests.class)
class DemoApplicationTests {
//   这个速度快
    @Test
    void contextLoads() {
        //模拟从数据库查询出来
        List<Menu> menus = Arrays.asList(
                new Menu(1,"商品管理",0),
                new Menu(2,"会员管理",0),
                new Menu(3,"系统管理",0),
                new Menu(4,"系统工具",0),
                new Menu(5,"用户管理",3),
                new Menu(6,"角色管理",3),
                new Menu(7,"菜单栏管理",3),
                new Menu(8,"日志管理",4),
                new Menu(9,"商品列表",1),
                new Menu(10,"订单列表",1),
                new Menu(11,"会员等级",2),
                new Menu(12,"品牌列表",1)
        );

        //获取父节点
        List<Menu> collect = menus.stream().filter(m -> m.getParentId() == 0).map(
                (m) -> {
                    m.setChildList(getChildrens(m, menus));
                    return m;
                }
        ).collect(Collectors.toList());
        System.out.println("-------转json输出结果-------");
        System.out.println(JSON.toJSON(collect));
    }

    /**
     * 递归查询子节点
     * @param root  根节点
     * @param all   所有节点
     * @return 根节点信息
     */
    private List<Menu> getChildrens(Menu root, List<Menu> all) {
        List<Menu> children = all.stream().filter(m -> {
            return Objects.equals(m.getParentId(), root.getId());
        }).map(
                (m) -> {
                    m.setChildList(getChildrens(m, all));
                    return m;
                }
        ).collect(Collectors.toList());
        return children;
    }


    @Test
    void contextLoads2() {
        //模拟从数据库查询出来
        List<Menu> menus = Arrays.asList(
                new Menu(1,"商品管理",0),
                new Menu(2,"会员管理",0),
                new Menu(3,"系统管理",0),
                new Menu(4,"系统工具",0),
                new Menu(5,"用户管理",3),
                new Menu(6,"角色管理",3),
                new Menu(7,"菜单栏管理",3),
                new Menu(8,"日志管理",4),
                new Menu(9,"商品列表",1),
                new Menu(10,"订单列表",1),
                new Menu(11,"会员等级",2),
                new Menu(12,"品牌列表",1)
        );
        List<Menu> list = buildDeptTreeByStream(menus);
        System.out.println(list);
        System.out.println(JSON.toJSON(list));
    }
    public static List<Menu> buildDeptTreeByStream(List<Menu> trees){
        //获取parentId = 0的根节点
        List<Menu> list = trees.stream().filter(item -> item.getParentId() == 0L).collect(Collectors.toList());
        //根据parentId进行分组
        Map<Integer, List<Menu>> map = trees.stream().collect(Collectors.groupingBy(Menu::getParentId));
        recursionFnTree(list, map);
        return list;
    }

    /**
     * 递归遍历节点
     * @param list
     * @param map
     */
    public static void recursionFnTree(List<Menu> list, Map<Integer, List<Menu>> map){
        for (Menu treeSelect : list) {
            List<Menu> childList = map.get(treeSelect.getId());
            treeSelect.setChildList(childList);
            if (null != childList && 0 < childList.size()){
                recursionFnTree(childList,map);
            }
        }
    }

    @Test
    void contextLoads3() {
        //模拟从数据库查询出来
        List<Menu> menus = Arrays.asList(
                new Menu(1,"商品管理",0),
                new Menu(2,"会员管理",0),
                new Menu(3,"系统管理",0),
                new Menu(4,"系统工具",0),
                new Menu(5,"用户管理",3),
                new Menu(6,"角色管理",3),
                new Menu(7,"菜单栏管理",3),
                new Menu(8,"日志管理",4),
                new Menu(9,"商品列表",1),
                new Menu(10,"订单列表",1),
                new Menu(11,"会员等级",2),
                new Menu(12,"品牌列表",1)
        );
        List<Menu> list = MenuTreeData.buildDeptTree(menus);
        System.out.println(list);
        System.out.println(JSON.toJSON(list));
    }


}

contextLoads3 里调用的方法
package com.example.demo.utils;

import com.example.demo.entry.Menu;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class MenuTreeData {

    /**
     * 构建前端所需要树结构
     *
     * @param trees 列表
     * @return 树结构列表
     */
    public static List<Menu> buildDeptTree(List<Menu> trees) {
        List<Menu> returnList = new ArrayList<Menu>();
        List<Long> tempList = new ArrayList<Long>();
        for (Menu dept : trees) {
            tempList.add(Long.valueOf(dept.getId()));
        }
        for (Iterator<Menu> iterator = trees.iterator(); iterator.hasNext(); ) {
            Menu treeSelect = (Menu) iterator.next();
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(treeSelect.getParentId())) {
                recursionFn(trees, treeSelect);
                returnList.add(treeSelect);
            }
        }
        if (returnList.isEmpty()) {
            returnList = trees;
        }
        return returnList;
    }

    /**
     * 递归列表
     */
    private static void recursionFn(List<Menu> list, Menu t) {
        // 得到子节点列表
        List<Menu> childList = getChildList(list, t);
        t.setChildList(childList);
        for (Menu tChild : childList) {
            if (hasChild(list, tChild)) {
                recursionFn(list, tChild);
            }
        }
    }

    /**
     * 得到子节点列表
     */
    private static List<Menu> getChildList(List<Menu> list, Menu t) {
        List<Menu> tlist = new ArrayList<Menu>();
        for (Menu n : list) {
            if (n.getParentId() != null && n.getParentId() == t.getId()) {
                tlist.add(n);
            }
        }
        return tlist;
    }

    /**
     * 判断是否有子节点
     */
    private static boolean hasChild(List<Menu> list, Menu t) {
        return getChildList(list, t).size() > 0;
    }
}

实体类
package com.example.demo.entry;

import lombok.Builder;
import lombok.Data;

import java.util.List;

/**
 * 树结构:Menu
 */
@Data
@Builder
public class Menu {
    /**
     * id
     */
    public Integer id;
    /**
     * 名称
     */
    public String name;
    /**
     * 父id ,根节点为0
     */
    public Integer parentId;
    /**
     * 子节点信息
     */
    public List<Menu> childList;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getParentId() {
        return parentId;
    }

    public void setParentId(Integer parentId) {
        this.parentId = parentId;
    }

    public List<Menu> getChildList() {
        return childList;
    }

    public void setChildList(List<Menu> childList) {
        this.childList = childList;
    }

    public Menu(Integer id, String name, Integer parentId) {
        this.id = id;
        this.name = name;
        this.parentId = parentId;
    }

    public Menu(Integer id, String name, Integer parentId, List<Menu> childList) {
        this.id = id;
        this.name = name;
        this.parentId = parentId;
        this.childList = childList;
    }

}


显示数据结果
[Menu(id=1, name=商品管理, parentId=0, childList=[Menu(id=9, name=商品列表, parentId=1, childList=[]), Menu(id=10, name=订单列表, parentId=1, childList=[]), Menu(id=12, name=品牌列表, parentId=1, childList=[])]), Menu(id=2, name=会员管理, parentId=0, childList=[Menu(id=11, name=会员等级, parentId=2, childList=[])]), Menu(id=3, name=系统管理, parentId=0, childList=[Menu(id=5, name=用户管理, parentId=3, childList=[]), Menu(id=6, name=角色管理, parentId=3, childList=[]), Menu(id=7, name=菜单栏管理, parentId=3, childList=[])]), Menu(id=4, name=系统工具, parentId=0, childList=[Menu(id=8, name=日志管理, parentId=4, childList=[])]), Menu(id=5, name=用户管理, parentId=3, childList=[]), Menu(id=6, name=角色管理, parentId=3, childList=[]), Menu(id=7, name=菜单栏管理, parentId=3, childList=[]), Menu(id=8, name=日志管理, parentId=4, childList=[]), Menu(id=9, name=商品列表, parentId=1, childList=[]), Menu(id=10, name=订单列表, parentId=1, childList=[]), Menu(id=11, name=会员等级, parentId=2, childList=[]), Menu(id=12, name=品牌列表, parentId=1, childList=[])]
[{"name":"商品管理","childList":[{"name":"商品列表","childList":[],"id":9,"parentId":1},{"name":"订单列表","childList":[],"id":10,"parentId":1},{"name":"品牌列表","childList":[],"id":12,"parentId":1}],"id":1,"parentId":0},{"name":"会员管理","childList":[{"name":"会员等级","childList":[],"id":11,"parentId":2}],"id":2,"parentId":0},{"name":"系统管理","childList":[{"name":"用户管理","childList":[],"id":5,"parentId":3},{"name":"角色管理","childList":[],"id":6,"parentId":3},{"name":"菜单栏管理","childList":[],"id":7,"parentId":3}],"id":3,"parentId":0},{"name":"系统工具","childList":[{"name":"日志管理","childList":[],"id":8,"parentId":4}],"id":4,"parentId":0},{"name":"用户管理","childList":[],"id":5,"parentId":3},{"name":"角色管理","childList":[],"id":6,"parentId":3},{"name":"菜单栏管理","childList":[],"id":7,"parentId":3},{"name":"日志管理","childList":[],"id":8,"parentId":4},{"name":"商品列表","childList":[],"id":9,"parentId":1},{"name":"订单列表","childList":[],"id":10,"parentId":1},{"name":"会员等级","childList":[],"id":11,"parentId":2},{"name":"品牌列表","childList":[],"id":12,"parentId":1}]

方式二 :两张表

两张表,例如:group表1中包含id pid name等字段 ;device表2中包含id groupId(表1的主键id字段) name 等其他字段

后台代码
public String device_getListAll2() {

        Map<String, List<TreeData>> rtnMap = new HashMap<String, List<TreeData>>();
        List<RmDevice> allDevList = deviceDao.getAll();
        String groupId = "";
        for (RmDevice dev : allDevList) {
            TreeData map = new TreeData();
            map.setId(dev.getId());
            map.setGroupId(dev.getGroupId());
            map.setIp(utils.ip.toFrontEnd(dev.getIp()));
            map.setMac(utils.mac.toFrontEnd(dev.getMac()));
            map.setName(dev.getName());
            map.setModel(dev.getModel());
            map.setSoftwareVersion(dev.getSoftwareVersion());
            map.setSystemVersion(dev.getSystemVersion());
            map.setIconCls("icon-driver");
            if (dev.getGroupId() == 0) {
                groupId = "1";
                map.setParentId(1);
            } else {
                groupId = String.valueOf(dev.getGroupId());
                map.setParentId(dev.getGroupId());
            }
            map.setMark(dev.getId() + "_" + 1);
            map.setType("1");

            if (rtnMap.containsKey(groupId)) {
                List<TreeData> tempList = rtnMap.get(groupId);
                tempList.add(map);
            } else {
                List<TreeData> tempList = new ArrayList<TreeData>();
                tempList.add(map);
                rtnMap.put(groupId, tempList);
            }
        }

        //分组
        List<RmGroup> allGroupList = groupDao.getAll();
        List<TreeData> returnList = getGroupChild(allGroupList, 0, rtnMap);

        return JSON.toJSONString(returnList);
    }

 private List<TreeData> getGroupChild(List<RmGroup> list, int root, Map<String, List<TreeData>> rtnMap) {
        List<TreeData> treeList = new ArrayList<TreeData>();
        for (RmGroup grp : list) {
            TreeData tree = new TreeData();
            tree.setId(grp.getId());
            tree.setName(grp.getName());
            tree.setParentId(grp.getParentId());
            tree.setIconCls("icon-function");
            int parentId = grp.getParentId();
            int treeId = grp.getId();
            if (root == parentId) {
                List<TreeData> lists = getGroupChild(list, treeId, rtnMap);

                if (rtnMap.get(String.valueOf(grp.getId())) != null) {
                    lists.addAll(rtnMap.get(String.valueOf(grp.getId())));
                }
                tree.setChildren(lists);
                treeList.add(tree);
            }
        }
        return treeList;
    }


实体类


public class TreeData{


	private static final long serialVersionUID = 1L;

	private int id;
	private String name;
	private int groupId;
	private String ip;
	private String mac;
	private String model;
	private String softwareVersion;
	private String systemVersion;
	private int parentId;
	private List<TreeData> children;
	private String mark;
	private String type;

	private String iconCls;

	public String getIconCls() {
		return iconCls;
	}

	public void setIconCls(String iconCls) {
		this.iconCls = iconCls;
	}

	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getGroupId() {
		return groupId;
	}
	public void setGroupId(int groupId) {
		this.groupId = groupId;
	}
	public String getIp() {
		return ip;
	}
	public void setIp(String ip) {
		this.ip = ip;
	}
	public String getMac() {
		return mac;
	}
	public void setMac(String mac) {
		this.mac = mac;
	}
	public String getSoftwareVersion() {
		return softwareVersion;
	}
	public void setSoftwareVersion(String softwareVersion) {
		this.softwareVersion = softwareVersion;
	}
	public String getSystemVersion() {
		return systemVersion;
	}
	public void setSystemVersion(String systemVersion) {
		this.systemVersion = systemVersion;
	}
	public int getParentId() {
		return parentId;
	}
	public void setParentId(int parentId) {
		this.parentId = parentId;
	}
	public List<TreeData> getChildren() {
		return children;
	}
	public void setChildren(List<TreeData> children) {
		this.children = children;
	}
	public String getMark() {
		return mark;
	}
	public void setMark(String mark) {
		this.mark = mark;
	}
	public String getType() {
		return type;
	}
	public void setType(String type) {
		this.type = type;
	}

	public String getModel() {
		return model;
	}

	public void setModel(String model) {
		this.model = model;
	}

	public TreeData() {
	}

	public TreeData(int id, String name, int groupId, String ip, String mac, String model, String softwareVersion, String systemVersion, int parentId, List<TreeData> children, String mark, String type) {
		this.id = id;
		this.name = name;
		this.groupId = groupId;
		this.ip = ip;
		this.mac = mac;
		this.model = model;
		this.softwareVersion = softwareVersion;
		this.systemVersion = systemVersion;
		this.parentId = parentId;
		this.children = children;
		this.mark = mark;
		this.type = type;
	}
}

前端代码

可以使用esayui里面的treegrid表格样式,也可以用其他的。比如layui

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值