using JNPF.Common.Extension; using JNPF.DependencyInjection; namespace JNPF.Common.Security; /// /// 树结构帮助类. /// [SuppressSniffer] public static class TreeHelper { /// /// 建造树结构. /// /// 所有的节点. /// 节点. /// public static List ToTree(this List allNodes, string parentId = "0") where T : TreeModel, new() { List resData = new List(); // 查找出父类对象 List rootNodes = allNodes.FindAll(x => x.parentId == parentId || x.parentId.IsNullOrEmpty()); // 移除父类对象 allNodes.RemoveAll(x => x.parentId == parentId || x.parentId.IsNullOrEmpty()); resData = rootNodes; resData.ForEach(aRootNode => { aRootNode.hasChildren = HaveChildren(allNodes, aRootNode.id); if (aRootNode.hasChildren) { aRootNode.children = _GetChildren(allNodes, aRootNode); aRootNode.num = aRootNode.children.Count(); } else { aRootNode.isLeaf = !aRootNode.hasChildren; aRootNode.children = null; } }); return resData; } #region 私有成员 /// /// 获取所有子节点. /// /// 树模型(TreeModel或继承它的模型. /// 所有节点列表. /// 父节点Id. /// private static List _GetChildren(List nodes, T parentNode) where T : TreeModel, new() { Type type = typeof(T); var properties = type.GetProperties().ToList(); List resData = new List(); // 查找出父类对象 var children = nodes.FindAll(x => x.parentId == parentNode.id); // 移除父类对象 nodes.RemoveAll(x => x.parentId == parentNode.id); children.ForEach(aChildren => { T newNode = new T(); resData.Add(newNode); // 赋值属性 foreach (var aProperty in properties.Where(x => x.CanWrite)) { var value = aProperty.GetValue(aChildren, null); aProperty.SetValue(newNode, value); } newNode.hasChildren = HaveChildren(nodes, aChildren.id); if (newNode.hasChildren) { newNode.children = _GetChildren(nodes, newNode); } else { newNode.isLeaf = !newNode.hasChildren; newNode.children = null; } }); return resData; } /// /// 判断当前节点是否有子节点. /// /// 树模型. /// 所有节点. /// 当前节点Id. /// private static bool HaveChildren(List nodes, string nodeId) where T : TreeModel, new() { return nodes.Exists(x => x.parentId == nodeId); } #endregion } /// /// 树模型基类. /// public class TreeModel { /// /// 获取节点id. /// /// public string id { get; set; } /// /// 获取节点父id. /// /// public string parentId { get; set; } /// /// 是否有子级. /// public bool hasChildren { get; set; } /// /// 设置Children. /// public List? children { get; set; } = new List(); /// /// 子节点数量. /// public int num { get; set; } /// /// 是否为子节点. /// public bool isLeaf { get; set; } = false; }