樹形菜單

  樹形菜單應該是很常見的了,相似下面這種,一般咱們的作法是後端從數據庫中查詢出來數據,而後將其轉爲樹的結構,丟給前端,前端就渲染到樹組件中;前端

 

  那麼返給前端的數據是什麼樣的呢?以下所示java

[    {
          id: 1,
          label: '一級 1',
          children: [{
            id: 4,
            label: '二級 1-1',
            children: [{
              id: 9,
              label: '三級 1-1-1'
            }, {
              id: 10,
              label: '三級 1-1-2'
            }]
          }]
        },
    {xxx}

]    

 

 

  那麼對應在數據庫中的表示什麼樣子的呢?Subject表下圖所示,若是parent_id爲0的,表示是一級菜單,其餘多個二級菜單的parent_id等於某個一級菜單的id,依次類推,可有有不少級別菜單node

 

 

下面用java代碼實現spring

  1.工具類:數據庫

package com.protagonist.edu.utils;

import com.protagonist.edu.bo.SubjectTreeNodeBO;
import com.protagonist.edu.entity.Subject;
import com.protagonist.responseVO.StatusCode;
import com.protagonist.servicebase.exception.ProtagonistException;
import org.springframework.beans.BeanUtils;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * 用於構建樹形結構
 */
public class TreeUtil {
    /**
     * 默認樹形菜單最頂層的pid是"0"
     * @param list 全部數據
     * @return 樹形的數據
     */
    public static  List<SubjectTreeNodeBO> buildTree(List<Subject> list) {
        if (CollectionUtils.isEmpty(list)){
            throw new ProtagonistException(StatusCode.ERROR,"查詢的菜單數據爲空,不能轉爲樹形");
        }
        return buildTree(list, "0");
    }

    /**
     *   獲取樹形菜單結構
     *      思路:首先遍歷一次將全部的數據轉化爲前端須要的數據類型,而後放入到map中,以id->T對應關係
     *      而後再遍歷一次,此次的話判斷parentId是否爲0(這裏暫時能夠特使pid爲0時表示一級菜單),是的話就是一級菜單,就放到rootTree中;
     *      不爲0的話,說明不是一級菜單,咱們就須要獲取它的父菜單
     *      根據pid去map中獲取,而後將當前菜單放入其父菜單的子菜單中,等遍歷完以後樹形菜單就ok了,這種作法能夠完成多級子菜單變成樹形
     * @param list 全部的數據
     * @param pid 父id
     * @return 樹形數據
     */
    public static  List<SubjectTreeNodeBO> buildTree(List<Subject> list, String pid) {
        if (CollectionUtils.isEmpty(list)){
            throw new ProtagonistException(StatusCode.ERROR,"查詢的菜單數據爲空,不能轉爲樹形");
        }
        List<SubjectTreeNodeBO> allTreeNode = new ArrayList<>();
        List<SubjectTreeNodeBO> rootTree = new ArrayList<>();
        Map<String, SubjectTreeNodeBO> nodeMap = new HashMap<>();
        //將全部的數據都放入到map中一份
        for (Subject item : list) {
            SubjectTreeNodeBO nodeBO = new SubjectTreeNodeBO();
            BeanUtils.copyProperties(item,nodeBO);
            allTreeNode.add(nodeBO);
            nodeMap.put(item.getId(),nodeBO);
        }
        for (SubjectTreeNodeBO t : allTreeNode) {
            //若是父id等於傳進來的pid,那麼該菜單是最頂級的菜單,放入到rootTree中
            if (Objects.equals(t.getParentId(), pid)){
                rootTree.add(t);
                //若是不是頂級菜單,那就獲取父菜單,而後嫁給你本BO設置到父菜單的children中
            }else {
                SubjectTreeNodeBO parentNode = nodeMap.get(t.getParentId());
                parentNode.getChildren().add(t);
            }
        }
        return rootTree;
    }
}

 

   2.subject類:後端

@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("subject")
@ApiModel(value="Subject對象", description="課程科目")
public class Subject implements Serializable {

    private static final long serialVersionUID = 1L;

    @ApiModelProperty(value = "課程類別ID")
    @TableId(value = "id", type = IdType.ID_WORKER_STR)
    private String id;

    @ApiModelProperty(value = "類別名稱")
    private String title;

    @ApiModelProperty(value = "父ID")
    private String parentId;

}

 

3.SubjectTreeNodeBO類:
package com.protagonist.edu.bo;

import lombok.Data;

import java.util.ArrayList;
import java.util.List;

@Data
public class SubjectTreeNodeBO {

    private String id;

    private String title;

    private String parentId;

    private List<SubjectTreeNodeBO> children = new ArrayList<>();
}

 

  4. 測試,成功,而後配合element的Tree 樹形控件一塊兒使用,就好了工具

相關文章
相關標籤/搜索