递归实现部门树形数据结构

  今儿个给大伙来一篇干货,树形结构 构建算法

  客户端是用ztree控件实现的,我们先来看下展示效果


 直接上model类文件


//部门数据结构类
public class DepartModel
{
        public int DepartID { get; set; }
        public string DepartName { get; set; }
        public string DepaetNo { get; set; }
        public int ParDepartID { get; set; }
        public string DepartLevel { get; set; } //层级树,存储所有父节点id,以逗号隔开的方式
        public string DepartCode { get; set; }
        public string TreeText { get; set; }
        public int? Rank { get; set; }
}

//组建树形数据结构
public class TreeNodeDepart
{
        public int id { get; set; }
	public int pid { get; set; }
	public string text { get; set; }
	public string departCode { get; set; }
	public string departLevel { get; set; }
	public List<TreeNodeDepart> children { get; set; }
}

再上递归算法

public class DepartUserController : BaseController
{
     public ActionResult GetPageTree()
     {
         List<DepartModel> list = base.GetDepartList();//获取所有数据,,结构如model所示
         var selectModel = list.OrderBy(p => p.ParDepartID).FirstOrDefault(); //按照父节点排序,找到最大的父节点ID
         int parendId = 0;
         if (selectModel != null)
         {
             parendId = selectModel.ParDepartID;//根节点ID
         }
         var newList = ToTreeNodes(list, parendId);
         return Json(newList);
    }


    public List<TreeNodeDepart> ToTreeNodes(IList<DepartModel> listPer, int parent)
    {
         List<TreeNodeDepart> listNodes = new List<TreeNodeDepart>();
         LoadTreeNode(listPer, listNodes, parent);//生成树节点时,根据pid=0的根节点来生成
         return listNodes;
    }

    public void LoadTreeNode(IList<DepartModel> listPer, List<TreeNodeDepart> listNodes, int pid)
    {
         var childNode = listPer.Where(s => s.ParDepartID == pid);//根据父节点pid过滤所有子节点数据
         if (childNode.Any())//判断是否有子节点数据
         {
             foreach (var item in childNode)
             {
                 TreeNodeDepart node = ToNode(item);//将父节点为pid的子节点构建为新的节点
                 listNodes.Add(node);//将节点加入到树节点集合
                 LoadTreeNode(listPer, node.children, node.id); //递归 为这个新创建的树节点找子节点
             }
         }
    }

    public TreeNodeDepart ToNode(DepartModel objDepart)
    {
        TreeNodeDepart node = new TreeNodeDepart()
        {
               id = objDepart.DepartID,
               pid = objDepart.ParDepartID,
               text = objDepart.DepartName,
               departCode = objDepart.DepartCode,
               departLevel = objDepart.DepartLevel,
               children = new List<TreeNodeDepart>()
        };
        return node;
    }
}

另一种实现方案,基于多级文件菜单的:

其实无非也就是循环遍历将扁平化数据构建成树形数据

下面的方案比较简单,But,从效率上来讲可能没有上面那种方案好

代码如下:

public class HelpCenterController
{
     BHelpCenter bllHelpCenter = BHelpCenter.GetInstance();
     public IHttpActionResult GetList(string groupNo ="0")
     {
         ApiResultMsg apiResult = new ApiResultMsg { Code = 0 };
         var list = bllHelpCenter.GetAllByCondition(new SEHelpCenter() {GroupNo= groupNo });
         List<EHelpCenter> array = new List<EHelpCenter>();
         foreach (var item in list)
         {
              if (item.ParentID == 0)
              {
                  array.Add(item);
              }
         }
         apiResult.Data = children(array, list);
         return Json(apiResult);
     }

     public List<EHelpCenter> children(List<EHelpCenter> parent, IList<EHelpCenter> list)
     {
         if (parent != null)
         {
             foreach (var item in parent)
             {
                 item.childrenList = new List<EHelpCenter>();
                 foreach (var dataItem in list)
                 {
                     if (dataItem.ParentID == item.HelpCenterID)
                      {
                          item.childrenList.Add(dataItem);
                      }
                 }
                     children(item.childrenList, list);
             }
          }
            return parent;
     }
}

//实体类文件,为了方便就不单独聆出来了
public partial class EHelpCenter
{
    public virtual int? HelpCenterID { get; set; } 

    public virtual int? ParentID { get; set; } 

    public virtual string Title { get; set; }

    public virtual string Des { get; set; }

    public virtual int? Rank { get; set; } 

    public virtual string AddUserName { get; set; }

    public virtual DateTime? AddTime { get; set; } 

    public virtual string GroupNo { get; set; }

    public List<EHelpCenter> childrenList{ get; set; }
}

接口请求 获取到的数据结构如图所示:

想了下,还是把相关的js代码附上

html 部分 在头部或者尾部引入zTree 相关js包,使用ul控件来存放树形数据

注意要点:在引入zTree.js相关包之前必须先引用jQuery包

<div data-options="region:'west',title:'组织管理'" style="width:230px;">
        <ul id="tree" class="ztree"></ul>
</div>

@section scripts{
    <script src="~/Scripts/ztree-v3/jquery.ztree.core.min.js"></script>
    <script src="~/Scripts/ztree-v3/jquery.ztree.excheck.min.js"></script>
    <script src="~/Scripts/ztree-v3/jquery.ztree.exedit.min.js"></script>
    <script src="~/Areas/Admin/Scripts/DepartUser/Index.js"></script>
}

js部分代码

var zTreeObj,
    setting = {
        view: {
            selectedMulti: false
        },
        data: {
            key: { //节点显示属性配置
                name: "text",
            }
        },
        edit: {
            enable: true,//开启节点拖拽控制
            showRemoveBtn: false //删除按钮控制
        },
        callback: {//各类回调函数
            onClick: zTreeOnClick,
            beforeDrop: zTreeBeforeDrop,
            onDrop: zTreeOnDrop,
            beforeRename: zTreeBeforeRename,
            onRename: zTreeOnRename
        }
    },
    zTreeNodes = [{//初始化数据
        "name": "网站导航", open: true, children: [
            { "name": "google", "url": "http://g.cn", "target": "_blank" },
            { "name": "baidu", "url": "http://baidu.com", "target": "_blank" },
            { "name": "sina", "url": "http://www.sina.com.cn", "target": "_blank" }
        ]
    }];

window.onload = function(){
    InitTree();
}

function InitTree() {
    $.ajax({
        url: "/Admin/DepartUser/GetPageTree",
        data: {},
        type: 'post',
        async: false,
        success: function (data) {
            zTreeNodes = data;
        },
    })
    zTreeObj = $.fn.zTree.init($("#tree"), setting, zTreeNodes);
    zTreeObj.expandAll(true);//展开所有节点
}

        

当然,数据也可以不在服务端处理,统一返回数组对象到js客户端做处理,代码也比较简洁,这里可以参考一下这位朋友的js代码

猜你喜欢

转载自blog.csdn.net/cslx5zx5/article/details/107043398