如何给前端返回树结构数据

项目中经常会有我们需要按照前端提供的接口文档返回数据

其中树型结构很常见,除了ztree、jstree等树,还有一种常用的森林树:

森林树的实现比较繁琐,如果和前端开发沟通能使用id、pid来实现是最好不过的,可以大大减少后台逻辑

//我们查询出来的list数据中一定要有id和pid来指定对应关系
@ResponseBody
	@RequestMapping("treelist")
	@ApiOperation(notes = "treelist", httpMethod = "GET", value = "树结构的对比分析接口")
	public Object treelist(HttpServletRequest request, HttpServletResponse response) {
		
		try {
			
            //查询出来的数组
			List<ZtAnalysisConfig> findAllList = ztAnalysisConfigService.findAllListByZtid(ztid);
			
					List<ZtAnaTreeNode> resultList = new ArrayList<>();
					for (ZtAnalysisConfig ztAnalysisConfig : findAllList) {
								ZtAnaTreeNode node = new ZtAnaTreeNode();
								
                                //这里写业务逻辑
								
								resultList.add(node);
							
					}
					List<ZtAnaTreeNode> tns = ForestNodeMerger.merge(resultList);
					JSONArray jsonArray = JSONArray.fromObject(tns);
			
			return jsonArray;
		} catch (Exception e) {
			e.printStackTrace();
			HashMap<Object,Object> hashMap = new HashMap<>();
			hashMap.put("success", false);
			hashMap.put("message", "请正确配置专题分析配置");
			return hashMap;
		}
		
		
	}



//以下是树结构相关的内部类
/**  
	 * @ClassName: ZtAnaTreeNode  
	 * @Description: TODO(这里用一句话描述这个类的作用)  
	 * @author Administrator  
	 * @date 2020年3月23日  
	 *    
	 */
	public static class ZtAnaTreeNode {

		private String id; // 分析配置的id
		private String pid; // 分析配置项pid
		private String name; //分析配置的名称
		private String tcid; //图层id
		private String tcurl; //图层地址
		private String tcmc; // 图层名称
		private String type; //图层类型
		private String servertype; //服务类型
		private String dictstr; //关联的字典表
		private List<Map<String,Object>> showfield; //显示字段
		private List<Map<String,Object>> outtableheader; //外层表头
		private String classfyfield; //分类字段
		private String countfield; //统计字段
		private String defaultunit; //默认显示单位
		private String shownumber; // 显示位数
		private String relateid; //关联id
		public List<ZtAnaTreeNode> children = new ArrayList<ZtAnaTreeNode>();
		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 String getName() {
			return name;
		}
		public void setName(String name) {
			this.name = name;
		}
		public String getTcid() {
			return tcid;
		}
		public void setTcid(String tcid) {
			this.tcid = tcid;
		}
		public String getTcurl() {
			return tcurl;
		}
		public void setTcurl(String tcurl) {
			this.tcurl = tcurl;
		}
		public String getTcmc() {
			return tcmc;
		}
		public void setTcmc(String tcmc) {
			this.tcmc = tcmc;
		}
		public String getType() {
			return type;
		}
		public void setType(String type) {
			this.type = type;
		}
		public String getServertype() {
			return servertype;
		}
		public void setServertype(String servertype) {
			this.servertype = servertype;
		}
		public String getDictstr() {
			return dictstr;
		}
		public void setDictstr(String dictstr) {
			this.dictstr = dictstr;
		}
		public List<Map<String,Object>> getOuttableheader() {
			return outtableheader;
		}
		public void setOuttableheader(List<Map<String,Object>> outtableheader) {
			this.outtableheader = outtableheader;
		}
		public List<Map<String, Object>> getShowfield() {
			return showfield;
		}
		public void setShowfield(List<Map<String, Object>> showfield) {
			this.showfield = showfield;
		}
		public String getClassfyfield() {
			return classfyfield;
		}
		public void setClassfyfield(String classfyfield) {
			this.classfyfield = classfyfield;
		}
		public String getCountfield() {
			return countfield;
		}
		public void setCountfield(String countfield) {
			this.countfield = countfield;
		}
		public String getDefaultunit() {
			return defaultunit;
		}
		public void setDefaultunit(String defaultunit) {
			this.defaultunit = defaultunit;
		}
		public String getShownumber() {
			return shownumber;
		}
		public void setShownumber(String shownumber) {
			this.shownumber = shownumber;
		}
		public String getRelateid() {
			return relateid;
		}
		public void setRelateid(String relateid) {
			this.relateid = relateid;
		}
		public List<ZtAnaTreeNode> getChildren() {
			return children;
		}
		public void setChildren(List<ZtAnaTreeNode> children) {
			this.children = children;
		}
		
	}

	public static class ForestNodeManager  {
		
		private List<ZtAnaTreeNode> list;// 森林的所有节点
	 
		public ForestNodeManager(ZtAnaTreeNode[] items) {
			list = new ArrayList<ZtAnaTreeNode>();
			for (ZtAnaTreeNode treeNode : items) {
				list.add(treeNode);
			}
		}
	 
		public ForestNodeManager(List<ZtAnaTreeNode> items) {
			list = items;
		}
	 
		/**
		 * 根据节点ID获取一个节点
		 * 
		 * @param id
		 *            节点ID
		 * @return 对应的节点对象
		 */
		public ZtAnaTreeNode getTreeNodeAT(String id) {
			for (ZtAnaTreeNode treeNode : list) {
				if (id.equals(treeNode.getId()))
					return treeNode;
			}
			return null;
		}
	 
		/**
		 * 获取树的根节点【一个森林对应多颗树】
		 * 
		 * @return 树的根节点集合
		 */
		public List<ZtAnaTreeNode> getRoot() {
			List<ZtAnaTreeNode> roots = new ArrayList<ZtAnaTreeNode>();
			for (ZtAnaTreeNode treeNode : list) {
				if ("0".equals(treeNode.getPid()))
					roots.add(treeNode);
			}
			return roots;
		}
	}

	public static class ForestNodeMerger  {/**
		 * 将节点数组归并为一个森林(多棵树)(填充节点的children域)
		 * 时间复杂度为O(n^2)
		 * @param items 节点域
		 * @return 多棵树的根节点集合
		 */
		public static List<ZtAnaTreeNode> merge(ZtAnaTreeNode[] items){
			ForestNodeManager forestNodeManager = new ForestNodeManager(items);
			for (ZtAnaTreeNode treeNode : items) {
				if(!"0".equals(treeNode.getPid())){
					ZtAnaTreeNode t = forestNodeManager.getTreeNodeAT(treeNode.getPid());
					t.getChildren().add(treeNode);
				}
			}
			return forestNodeManager.getRoot();
		}
		
		/**
		 * 将节点数组归并为一个森林(多棵树)(填充节点的children域)
		 * 时间复杂度为O(n^2)
		 * @param items 节点域
		 * @return 多棵树的根节点集合
		 */
		public static List<ZtAnaTreeNode> merge(List<ZtAnaTreeNode> items){
			ForestNodeManager forestNodeManager = new ForestNodeManager(items);
			for (ZtAnaTreeNode treeNode : items) {
				if(!"0".equals(treeNode.getPid())){
					ZtAnaTreeNode t = forestNodeManager.getTreeNodeAT(treeNode.getPid());
					t.getChildren().add(treeNode);
				}
			}
			return forestNodeManager.getRoot();
		}
	}


返回结果:[{
    id: xxx,
    pid: xxx,
children: [{
    ......
}]
}]

以上的返回结果存在一个问题:没有子节点的数据会有children为[]的情况,我们可以通过后台的递归去消除,也可以在前端递归消除:

function deleteChildren(arr) {
      let childs = arr
      for (let i = childs.length; i--; i > 0) {
        if (childs[i].children) {
          if (childs[i].children.length) {
            this.deleteChildren(childs[i].children)
          } else {
            delete childs[i].children
          }
        }
      }
      return arr
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dong__xue

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值