框架前端是基于 Element UI 的,因此,需要用到 el-tree 组件,这里介绍转换方法。el-tree 接收有格式为:
{
"data": [
{
"children": [],
"label": "节点1",
"id": 2
},
{
"children": [],
"label": "节点2",
"id": 3
},
{
"children": [],
"label": "节点3",
"id": 4
}
]
}也就是说,只需要将结果转换为 el-tree 接收的格式即可。
表结构:
CREATE TABLE `wechat_category` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID', `parent_id` int(11) unsigned DEFAULT NULL COMMENT '父分类', `name` varchar(255) DEFAULT NULL COMMENT '名称', `weigh` int(10) unsigned DEFAULT '0' COMMENT '排序', `create_by` varchar(64) DEFAULT '' COMMENT '创建者', `create_time` datetime DEFAULT NULL COMMENT '创建时间', `update_by` varchar(64) DEFAULT '' COMMENT '更新者', `update_time` datetime DEFAULT NULL COMMENT '更新时间', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COMMENT='分类管理';
控制器层:controller/WechatCategoryController.java
/**
* 获取分类树列表
*/
@PreAuthorize("@ss.hasPermi('WeChat:category:list')")
@GetMapping("/tree")
public AjaxResult tree(WechatCategory wechatCategory)
{
List<WechatCategory> list = wechatCategoryService.selectWechatCategoryList(wechatCategory);
return success(wechatCategoryService.listToElTree(list,"parentId","id","name"));
}服务层:service/IWechatCategoryService.java
public List<Map<String, Object>> listToElTree(List<WechatCategory> entityList, String parentFieldName, String idFileName, String labelFieldName);
实现层:service/impl/WechatCategoryServiceImpl.java
/**
* 对象List转为Tree树形结构
*
* @param entityList 传进来的泛型List
* @param parentFieldName 父级字段名称
* @param idFileName ID 字段名
* @param labelFieldName 标签字段
* @return
*/
public final List<Map<String, Object>> listToElTree(List<WechatCategory> entityList, String parentFieldName, String idFileName, String labelFieldName) {
//返回的map Tree树形结构
List<Map<String, Object>> treeMap = new ArrayList<>();
//将传进的参数entityList转为MapList
List<Map<String, Object>> listMap = JSON.parseObject(JSON.toJSONString(entityList), List.class);
//声明一个map用来存listMap中的对象,key为对象id,value为对象本身
Map<String, Map<String, Object>> entityMap = new Hashtable<>();
//循环listMap把map对象put到entityMap中去
listMap.forEach(map -> entityMap.put(map.get("id").toString(), map));
//循环listMap进行Tree树形结构组装
listMap.forEach(map -> {
//获取map的pid
Object pid = map.get(parentFieldName);
if (pid == null || pid.equals(0)) { //判断pid是否为空,为空说明是最顶级,直接add到返回的treeMap中去
treeMap.add(map);
} else { //如果pid不为空
//根据当前map的pid获取上级 parentMap
Map<String, Object> parentMap = entityMap.get(pid);
if (parentMap == null) { //如果parentMap为空,则说明当前map没有父级,当前map就是顶级
treeMap.add(map);
} else { //如果parentMap不为空,则当前map为parentMap的子级
//取出parentMap的所有子级的List集合
List<Map<String, Object>> children = (List<Map<String, Object>>) parentMap.get("children");
if (children == null) { //判断子级集合是否为空,为空则新创建List
children = new ArrayList<>();
parentMap.put("children", children);
}
//把当前map对象add到parentMap的子级List中去
children.add(map);
/**
* 因为parentMap是从entityMap中get出来的,
* 而entityMap中的value又是来自于listMap对象,
* 所以parentMap和entityMap中的value的地址都是指向listMap中的对象,
* 所以parentMap的children和entityMap中的value的children改变时,都会改变listMap中的对象,
* 这里涉及到了地址、指针,就不多说了。
*/
}
}
});
// 调整生成的列表中的 id 和 label 字段
List<Map<String, Object>> newMap = new ArrayList<>();
treeMap.forEach(map -> {
Map<String, Object> newItem = new HashMap<>();
if (map.containsKey("children")) {
newItem.put("children", map.get("children"));
}
newItem.put("label", map.get(labelFieldName));
newItem.put("id", map.get(idFileName));
newMap.add(newItem);
});
return newMap;
}前端: category.js
// 查询分类下拉树结构
export function categoryTreeSelect() {
return request({
url: '/WeChat/category/tree',
method: 'get'
})
}另一种方法:通过前端 \src\utils\ruoyi.js 中 handleTree 方法来实现转换
/** 查询分类管理下拉树结构 */
getTreeselect() {
listCategory().then((response) => {
this.categoryOptions = [];
const data = { id: 0, name: '顶级节点', children: [] };
data.children = this.handleTree(response.data, 'id', 'parentId');
this.categoryOptions.push(data);
});
},