企业行业树形图,层级结构展示
一、业务需求
按照行业分类标准,实现行业间的层级关系,标准中行业分为四级,门类–大类–中类–小类,点击最后一层小类时,打开该类行业的查询结果页面,还有一点就是如果企业表中没有这个行业,树形图就不展示此行业,ifUse字段控制。
先看一下效果图:
点击最后一层小类谷物种植弹出查询结果页面如下。
二、实现步骤
1.库表设计(我用的mysql)
CREATE TABLE `ytjr_sjzx_hylx_mapping` (
`id` int NOT NULL,
`code` varchar(255) DEFAULT NULL COMMENT '门类代码',
`parent_code` varchar(255) DEFAULT NULL COMMENT '上级代码',
`lbmc` varchar(255) DEFAULT NULL COMMENT '类别名称',
`level` varchar(255) DEFAULT NULL COMMENT '等级(1:一级,2:二级,3:三级,4:四级)',
`if_use` varchar(10) DEFAULT NULL COMMENT '是否使用',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
2.行业分类标准文档数据清洗,入库
行业分类标准文件下载地址如下:https://download.csdn.net/download/weixin_39611547/87537247
行业分类标准dmp文件下载如下(mysql数据库,根据表结构清洗后的数据,注意:ifUse是N代表我们企业库中没有该行业,树形图中也不做展示了)
https://download.csdn.net/download/weixin_39611547/87537251
3.前台实现
运用echarts树形结构,只需引入相关js即可。
echarts官网参考demo地址如下:
https://echarts.apache.org/examples/zh/editor.html?c=tree-basic
<!DOCTYPE html>
<html>
<head>
<title>行业分类模型</title>
<meta content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no' name='viewport' />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<script src="../../static/framework/js/contextPath.js"></script>
<script src="../../webpage/js/layui/layui.all.js"></script>
<link href="../../webpage/js/layui/css/layui.css" rel="stylesheet"/>
<script src="../../webpage/js/layui-2.5.5/layui.js"></script>
</head>
<body class='contrast-blue'>
<div style="height:50px;width:100%;background:white;">
<div style="height:50px;line-height:50px;font-size:18px;padding-left:30px;"><span style="color: #a58f8f">信息查询 </span><span style="color: #411111;">/ 行业分类模型</span></div>
</div>
<div v-cloak style="height: calc(100% - 50px); width: 100%;overflow-y: auto;">
<div id='wrapper'>
<section id='content'>
<div class="tree-container">
<div id="main" style="width:100%;height:800px;"></div>
</div>
</section>
</div>
</div>
</body>
<script src='https://cdn.bootcss.com/jquery/1.11.1/jquery.min.js' type='text/javascript'></script>
<script src='https://cdn.staticfile.org/echarts/5.1.0/echarts.js' type='text/javascript'></script>
<script type="text/javascript">
var chartDom = document.getElementById('main');
var myChart = echarts.init(chartDom, 'light');//
var option;
//flare.json是静态JSON文件,为了测试所用,实际应用时替换为接口返回的数据
//注意:json数据格式中子节点的key名必须为children
myChart.showLoading();//echarts自带的Loading遮罩方法
$.getJSON('../../fg/json/hylx.json', {}, function (data) {
myChart.hideLoading();
data.collapsed=false;
data.children.forEach(function (datum, index) {
datum.collapsed = true
//index % 2 === 0 && (datum.collapsed = true);
});
option={
series: [
{
type: 'tree',
data: [data],
top: '10%',
left: 'center',
// bottom: '1%',
// right: '15%',
symbolSize: 5,
itemStyle:{
color: '#228EFB' ,
},
lineStyle:{
color: '#DDD',
},
label: {
color: "#000",
position: 'left',
verticalAlign: 'middle',
align: 'right',
fontSize: 11,
},
leaves: {
label: {
position: 'right',
verticalAlign: 'middle',
align: 'left'
}
},
emphasis: {
focus: 'descendant'
},
edgeForkPosition: "72%",
roam : true,//鼠标缩放,拖拽整颗树
expandAndCollapse: true,
animationDuration: 550,
animationDurationUpdate: 750
}
]
};
myChart.setOption(option);
}, 'json');
myChart.on("click", this.treeNodeclick);
// 节点点击事件
function treeNodeclick(param){
if(param.value=='4'){//value后台给的是level,如果是4代表最后的节点
var jthy = encodeURI(encodeURI(param.name));
layer.open({
type: 2,
title:['行业企业查询','font-size:16px;color:#FFF;background-color: #bc1c23;'],
area: ['90%', '90%'],
content: frontUrl+"jr/common/hyqyxxcx.html?jthy="+jthy,
});
}
}
</script>
</html>
如上页面中使用了hylx.json文件,此json中存储了行业的层级关系,由于行业层级关系不会经常变动,我直接在json中写死了。
json代码下载地址如下(注意:json中过滤掉了ifUse是N的结构关系,树形图中也不做展示了):
https://download.csdn.net/download/weixin_39611547/87537277
解释一下json中的value,value我其实存的是level字段的值,level等于4时,代表最后一个层级,触发弹窗列表页面。
4.后台实现
后台主要是为了生成json,如果你的json不需要改变,可以直接用我的json文件,就不需要再处理后台了。
如果行业分类变了或者不需要过滤ifUse是N的,需要重新生成json文件。
后台代码如下
实体类
package com.haiyisoft.jr.common.controller;
import java.util.List;
public class TreeEntityTest {
private String name ;
private String value ;
private List<TreeEntityTest> children;
public TreeEntityTest() {
}
public TreeEntityTest(String name, List<TreeEntityTest> children) {
this.name = name;
this.children=children;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<TreeEntityTest> getChildren() {
return children;
}
public void setChildren(List<TreeEntityTest> children) {
this.children = children;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
生成json类,如果企业表中没有这个行业,树形图就不展示,ifUse字段控制
package com.haiyisoft.jr.common.controller;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.alibaba.fastjson.JSON;
import com.haiyisoft.cloud.core.model.PageInfo;
import com.haiyisoft.cloud.core.model.QueryParam;
import com.haiyisoft.cloud.core.model.QueryParamList;
import com.haiyisoft.cloud.core.model.SortParam;
import com.haiyisoft.cloud.core.model.SortParamList;
import com.haiyisoft.cloud.jpa.util.JPAUtil;
import com.haiyisoft.cloud.web.ui.spring.model.AjaxDataWrap;
import com.haiyisoft.cloud.web.ui.spring.model.DataCenter;
import com.haiyisoft.entity.jr.YtjrSjzxHylxMapping;
import com.haiyisoft.entity.jr.YtjrSjzxHylxRelation;
import com.haiyisoft.entity.zx.qy.HnzxSjzxQyxxdjbReg;
import com.haiyisoft.jt.util.JtBaseController;
import com.haiyisoft.jt.util.JtCommonUtil;
import cn.hutool.json.JSONArray;
@Controller
@RequestMapping("/jr/common/treeJsonTest")
public class TreeJsonTest extends JtBaseController {
private static final long serialVersionUID = 1L;
List<YtjrSjzxHylxMapping> nodes = new ArrayList<YtjrSjzxHylxMapping>();
//List<TreeEntityTest> nodes = new ArrayList<TreeEntityTest>();
/**
* 构建JSON树形结构
* @return
*/
@RequestMapping("/buildJSONTree")
@ResponseBody
public String buildJSONTree() {
List<YtjrSjzxHylxMapping> nodeTree = buildTree();
List<TreeEntityTest> datas = changeTree(nodeTree) ;
String datasjsonArray = JSON.toJSONString(datas);
System.out.println(datasjsonArray);
return datasjsonArray.toString();
}
private List<TreeEntityTest> changeTree(List<YtjrSjzxHylxMapping> nodeTree){
List<TreeEntityTest> datas = new ArrayList<TreeEntityTest>();
for(YtjrSjzxHylxMapping tree:nodeTree) {
TreeEntityTest data = new TreeEntityTest();
data.setName(tree.getLbmc());
data.setValue(tree.getLevel());
data.setChildren(changeChildTree(tree.getChildren()));
datas.add(data);
}
return datas ;
}
private List<TreeEntityTest> changeChildTree(List<YtjrSjzxHylxMapping> nodeTree){
List<TreeEntityTest> datas = new ArrayList<TreeEntityTest>();
for(YtjrSjzxHylxMapping tree:nodeTree) {
TreeEntityTest data = new TreeEntityTest();
data.setName(tree.getLbmc());
data.setValue(tree.getLevel());
if(null!=tree.getChildren()&&tree.getChildren().size()>0) {
data.setChildren(changeChildTree(tree.getChildren()));
}
// else {
// if(!tree.getLevel().equals("4")) {
// List<TreeEntityTest> nulls = new ArrayList<TreeEntityTest>();
// data.setChildren(nulls);
// }
// }
datas.add(data);
}
return datas ;
}
/**
* 构建树形结构
* @return
*/
@RequestMapping("/buildTree")
@ResponseBody
public List<YtjrSjzxHylxMapping> buildTree() {
List<YtjrSjzxHylxMapping> treeNodes = new ArrayList<YtjrSjzxHylxMapping>();
List<YtjrSjzxHylxMapping> rootNodes = getRootNodes();
for (YtjrSjzxHylxMapping rootNode : rootNodes) {
buildChildNodes(rootNode);
treeNodes.add(rootNode);
}
return treeNodes;
}
/**
* 递归子节点
* @param node
*/
@RequestMapping("/buildChildNodes")
@ResponseBody
public void buildChildNodes(YtjrSjzxHylxMapping node) {
List<YtjrSjzxHylxMapping> children = getChildNodes(node);
if (!children.isEmpty()) {
for(YtjrSjzxHylxMapping child : children) {
buildChildNodes(child);
// TreeEntityTest test = new TreeEntityTest();
// test.setName(child.getLbmc());
// nodes.add(test);
}
node.setChildren(children);
}
}
/**
* 获取集合中所有的根节点
* @return
*/
@RequestMapping("/getRootNodes")
@ResponseBody
public List<YtjrSjzxHylxMapping> getRootNodes() {
List<YtjrSjzxHylxMapping> rootNodes = new ArrayList<YtjrSjzxHylxMapping>();
QueryParamList params = new QueryParamList();
params.addParam("parentCode", "0");
params.addParam("ifUse", "Y");
SortParamList sortParams=new SortParamList();
sortParams.addParam("id",SortParam.SORT_TYPE_ASCENDING);
List<YtjrSjzxHylxMapping> list = JPAUtil.load(YtjrSjzxHylxMapping.class, params,null, null, sortParams, null);
for (YtjrSjzxHylxMapping n : list){
rootNodes.add(n);//把所有的根节点放入rootNodes集合中
}
return rootNodes;
}
/**
* 获取父节点下所有的子节点
* @param pnode
* @return
*/
@RequestMapping("/getChildNodes")
@ResponseBody
public List<YtjrSjzxHylxMapping> getChildNodes(YtjrSjzxHylxMapping pnode) {//传入父节点对象,如果为该父节点的子节点,则放入子节点集合中
List<YtjrSjzxHylxMapping> childNodes = new ArrayList<YtjrSjzxHylxMapping>();
QueryParamList params = new QueryParamList();
params.addParam("parentCode", pnode.getCode());
params.addParam("ifUse", "Y");
SortParamList sortParams=new SortParamList();
sortParams.addParam("id",SortParam.SORT_TYPE_ASCENDING);
List<YtjrSjzxHylxMapping> list = JPAUtil.load(YtjrSjzxHylxMapping.class, params,null, null, sortParams, null);
for (YtjrSjzxHylxMapping n : list){
childNodes.add(n);
}
return childNodes;
}
}