框架前端是基于 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); }); },