using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; namespace Infrastructure.Domain { public abstract class BaseTreeEntity : BaseEntity where T : BaseTreeEntity { [Required] public string Name { get; set; } [Required] public string Number { get; set; } public int Order { get; set; } public int Left { get; set; } public int Right { get; set; } public Guid? ParentId { get; set; } public T Parent { get; set; } #pragma warning disable CA2227 // 集合属性应为只读 public List Children { get; set; } = new List(); #pragma warning restore CA2227 // 集合属性应为只读 public string GetDisplayName() { var list = new List(); var item = this as T; while (item != null) { list.Add(item); if (item.Parent == null || item.Parent.Id == this.Id) { break; } item = item.Parent; } list.Reverse(); return string.Join(" / ", list.Select(o => o.Name)); } public void Update() { Left(this as T); void Left(T node, int prev = 0) { if (node.Parent == null) { node.Left = 1; } else { node.Left = prev + 1; } if (node.Children.Any()) { Left(node.Children.OrderBy(o => o.Order).First(), node.Left); } else { Right(node, node.Left); } } void Right(T node, int prev) { node.Right = prev + 1; if (node.Parent != null) { var list = node.Parent.Children.OrderBy(o => o.Order).ToList(); var index = list.IndexOf(node); if (list.Count > index + 1) { Left(list[index + 1], node.Right); } else { Right(node.Parent, node.Right); } } } } } }