Element el-tree 有一个特定的接收格式,只要你按照格式传数据给它,就能直接体现在画面上。
秉承的逻辑部分尽量放后台的开发思想,前台只做了json访问。
前台部分代码:
首先添加控件:
<div class="down-tree">
<el-tree
ref="tree"
:data="data"
node-key="id"
:props="defaultProps"
:render-content="renderContent">
</el-tree>
</div>
给data赋初始值,默认属性,并添加访问后台后的数据接收。
export default {
name: 'treeList',
data() {
return {
data: [], // ①data赋初始值
defaultProps: {
children: 'children',
label: 'label'
} // ②默认属性
}
},
methods: {
onSubmit(form) {
let params = {
code: this.form.code
}
this.$axios.get('/treeList/getTreeList', { params }).then(res => {
console.log('sucess search!!', res)
this.data = res.data.data; // ③访问后台后的数据接收
})
},
renderContent(h, { node, data, store }) {// tree节点颜色,可改可不改
return <span style="color:grey;">{node.label}</span>;
},
},
mounted: function() {// 访问页面自动触发
}
}
给tree加了样式
<style scoped>
.down-tree {
background-color: grey;
background-repeat: no-repeat;
margin-left: 12%;
margin-right: 12%;
height: 400px;
}
.el-tree {
width: 100%;
height: 100%;
overflow: auto;
}
</style>
前台部分就这么简单。主要是后台要返回符合格式的数据,该怎么处理呢?
我这边只是我根据业务以及前台需要的格式,做出的方法。
首先,说一下前台需要的数据格式:
[AssetList(id=1,
parentId=0,
name=11 1個,
childList=[AssetList(id=6,
parentId=1,
name=11 1個
childList=[AssetList(id=11
parentId=6
name=11 1個
childList=null)])])
AssetList(id=2
parentId=0
name=99 1個
childList=[AssetList(id=7
parentId=2
name=99 1個
childList=[AssetList(id=12
parentId=7
name=99 1個
childList=null)])])
AssetList(id=3
parentId=0
name=12 4個
childList=[AssetList(id=8
parentId=3
name=34 4個
childList=[AssetList(id=13
parentId=8
name=56 3個
childList=null)
AssetList(id=14
parentId=8
name=77 1個
childList=null)])])
]
后台的任务就是将数据转换成这样的格式,前台就能直接接收显示。
后台数据处理
我的DB数据是这样的:
接下来的逻辑处理是将上面查询的数据转换成前台tree需要的格式。
我个人是觉得这个处理有点chun。。见谅
先创建两个个model,按照实际需求哈,我这边名称需要拼凑,所以我定义了两个model。
label = name || qty
public class AssetListTreeResult {
private Integer id;
private Integer parentId;
private String label;
private List<AssetListTreeResult> children;
}
public class AssetListResult {
private Integer id;
private Integer parentId;
private String name;
private Integer qty;
private List<AssetListResult> childList;
}
List<ViewSpsmTrnCuttingInfo> dataList = mapper.selectList(wrapper);
List<AssetListResult> resultList = new ArrayList<>();
List<AssetListResult> firstList = new ArrayList<>();
List<AssetListResult> secondList = new ArrayList<>();
List<AssetListResult> thirdList = new ArrayList<>();
int id = 1;
Map<String, Integer> firstMap = new HashMap<String, Integer>();
for (int i = 0; i < dataList.size(); i++) {
// 获取第一级工場CD的name
String first = dataList.get(i).getFactoryCode();
Integer firstQty = dataList.get(i).getSparePartsQty();
// 如果工場CD在tree第一级已经存在,则更新数量,否则增加tree第一级
if (firstMap.containsKey(first)) {
Integer oldQty = firstMap.get(first);
firstQty = oldQty + firstQty;
}
firstMap.put(first, firstQty);
}
// 将第一级工場CD转换成model,并加到列表
for (String key : firstMap.keySet()) {
AssetListResult result = new AssetListResult();
result.setId(id);
id += 1;
result.setParentId(0);
result.setName(key);
result.setQty(firstMap.get(key));
firstList.add(result);
}
resultList.addAll(firstList);
boolean existFlag = false;
// 将第二级倉庫CD转换成model,并加到tree列表
for (int i = 0; i < resultList.size(); i++) {
Integer firstId = resultList.get(i).getId();
String firstName = resultList.get(i).getName();
// 循环tree列表resultList,如果name所在数据,将倉庫CD数据也添加到tree列表
for (int j = 0; j < dataList.size(); j++) {
if (firstName.equals(dataList.get(j).getFactoryCode())) {
String warehouseCode = dataList.get(j).getWarehouseCode();
Integer warehouseCodeQty = dataList.get(j).getSparePartsQty();
// 倉庫CD已经存在列表中,更改数量
for (int z = 0; z < secondList.size(); z++) {
if (warehouseCode.equals(secondList.get(z).getName())) {
Integer oldQty = secondList.get(z).getQty();
secondList.get(z).setQty(warehouseCodeQty + oldQty);
existFlag = true;
break;
} else {
existFlag = false;
}
}
// 倉庫CD不存在列表中
if (!existFlag) {
AssetListResult result = new AssetListResult();
result.setId(id);
id += 1;
result.setParentId(firstId);
result.setName(warehouseCode);
result.setQty(warehouseCodeQty);
secondList.add(result);
}
}
}
}
resultList.addAll(secondList);
// 将第三级棚CD转换成model,并加到tree列表
for (int i = 0; i < resultList.size(); i++) {
Integer firstId = resultList.get(i).getId();
String firstName = resultList.get(i).getName();
Integer parentId = resultList.get(i).getParentId();
String parentName = null;
// 获取parentName
for (int x = 0; x < resultList.size(); x++) {
if (parentId.equals(resultList.get(x).getId())) {
parentName = resultList.get(x).getName();
break;
}
}
// 循环tree列表resultList,如果name所在数据,将棚CD数据也添加到tree列表
for (int j = 0; j < dataList.size(); j++) {
if (parentName == null) {
continue;
}
if (firstName.equals(dataList.get(j).getWarehouseCode())) {
String shelfCode = dataList.get(j).getShelfCode();
Integer shelfCodeQty = dataList.get(j).getSparePartsQty();
if (parentName.equals(dataList.get(j).getFactoryCode())) {
// 棚CD不存在列表中
AssetListResult result = new AssetListResult();
result.setId(id);
id += 1;
result.setParentId(firstId);
result.setName(shelfCode);
result.setQty(shelfCodeQty);
thirdList.add(result);
}
}
}
}
resultList.addAll(thirdList);
List<AssetListTreeResult> treeResultList = new ArrayList<>();
// 将CD和数量合并成name
for (int i = 0; i < resultList.size(); i++) {
AssetListResult result = new AssetListResult();
AssetListTreeResult treeResult = new AssetListTreeResult();
result = resultList.get(i);
treeResult.setId(result.getId());
treeResult.setParentId(result.getParentId());
treeResult.setLabel(result.getName() + " " + StringUtils.toStringTrim(result.getQty()) + "個");
treeResultList.add(treeResult);
}
// 调用工具类,第一个参数是默认传入的顶级id,和查询出来的数据
List<AssetListTreeResult> tree = TreeUtil.getTreeList(0, treeResultList);
return tree;
以上是逻辑部分。
这里使用到的共通方法(使用了上面提到博主的代码)
package com.ymslx.www.webserver.common.tools;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.ymslx.www.webserver.spsma.assetList.model.AssetListTreeResult;
/**
* 获取树型工具类
*
* @author mid1614
*
*/
public class TreeUtil {
// 获取顶层节点
public static <T extends dataTree<AssetListTreeResult>> List<AssetListTreeResult> getTreeList(Integer topId,
List<AssetListTreeResult> entityList) {
// 存储顶层的数据
List<AssetListTreeResult> resultList = new ArrayList<>();
Map<Object, AssetListTreeResult> treeMap = new HashMap<>();
AssetListTreeResult itemTree;
for (int i = 0; i < entityList.size() && !entityList.isEmpty(); i++) {
itemTree = entityList.get(i);
// 把所有的数据放到map当中,id为key
treeMap.put(itemTree.getId(), itemTree);
// 把顶层数据放到集合中
if (topId.equals(itemTree.getParentId()) || itemTree.getParentId() == null) {
resultList.add(itemTree);
}
}
// 循环数据,把数据放到上一级的childen属性中
for (int i = 0; i < entityList.size() && !entityList.isEmpty(); i++) {
itemTree = entityList.get(i);
// 在map集合中寻找父亲
AssetListTreeResult data = treeMap.get(itemTree.getParentId());
if (data != null) {// 判断父亲有没有
if (data.getChildren() == null) {
data.setChildren(new ArrayList<>());
}
// 把子节点 放到父节点childList当中
data.getChildren().add(itemTree);
// 把放好的数据放回map当中
treeMap.put(itemTree.getParentId(), data);
}
}
return resultList;
}
}
得到的数据就是前台想要的数据了。
其实在上面这个逻辑部分,也可以考虑写成sql来实现,原始表通过sql映射创建view表。直接查询view表,然后只需要最后使用TreeUtil转化下数据就可以实现。
如果有postgresql大佬可以实现的话,能分享sql就太好了