添加项目文件。
This commit is contained in:
145
common/Tnb.Common/Security/TreeHelper.cs
Normal file
145
common/Tnb.Common/Security/TreeHelper.cs
Normal file
@@ -0,0 +1,145 @@
|
||||
using JNPF.Common.Extension;
|
||||
using JNPF.DependencyInjection;
|
||||
|
||||
namespace JNPF.Common.Security;
|
||||
|
||||
/// <summary>
|
||||
/// 树结构帮助类.
|
||||
/// </summary>
|
||||
[SuppressSniffer]
|
||||
public static class TreeHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 建造树结构.
|
||||
/// </summary>
|
||||
/// <param name="allNodes">所有的节点.</param>
|
||||
/// <param name="parentId">节点.</param>
|
||||
/// <returns></returns>
|
||||
public static List<T> ToTree<T>(this List<T> allNodes, string parentId = "0")
|
||||
where T : TreeModel, new()
|
||||
{
|
||||
List<T> resData = new List<T>();
|
||||
|
||||
// 查找出父类对象
|
||||
List<T> 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 私有成员
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有子节点.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">树模型(TreeModel或继承它的模型.</typeparam>
|
||||
/// <param name="nodes">所有节点列表.</param>
|
||||
/// <param name="parentNode">父节点Id.</param>
|
||||
/// <returns></returns>
|
||||
private static List<object> _GetChildren<T>(List<T> nodes, T parentNode)
|
||||
where T : TreeModel, new()
|
||||
{
|
||||
Type type = typeof(T);
|
||||
var properties = type.GetProperties().ToList();
|
||||
List<object> resData = new List<object>();
|
||||
|
||||
// 查找出父类对象
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断当前节点是否有子节点.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">树模型.</typeparam>
|
||||
/// <param name="nodes">所有节点.</param>
|
||||
/// <param name="nodeId">当前节点Id.</param>
|
||||
/// <returns></returns>
|
||||
private static bool HaveChildren<T>(List<T> nodes, string nodeId)
|
||||
where T : TreeModel, new()
|
||||
{
|
||||
return nodes.Exists(x => x.parentId == nodeId);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 树模型基类.
|
||||
/// </summary>
|
||||
public class TreeModel
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取节点id.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取节点父id.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string parentId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否有子级.
|
||||
/// </summary>
|
||||
public bool hasChildren { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 设置Children.
|
||||
/// </summary>
|
||||
public List<object>? children { get; set; } = new List<object>();
|
||||
|
||||
/// <summary>
|
||||
/// 子节点数量.
|
||||
/// </summary>
|
||||
public int num { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否为子节点.
|
||||
/// </summary>
|
||||
public bool isLeaf { get; set; } = false;
|
||||
}
|
||||
Reference in New Issue
Block a user