using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using Abp.Collections.Extensions; using Abp.Domain.Entities; using Abp.Domain.Entities.Auditing; using Abp.Extensions; namespace VberZero.BaseSystem.Organizations; /// /// 组织单位 (OU)。 /// [Table("Sys_OrganizationUnits")] public class OrganizationUnit : FullAuditedEntity, IMayHaveTenant { public const int MaxDisplayNameLength = 128; public const int MaxDepth = 16; public const int CodeUnitLength = 5; public const int MaxCodeLength = MaxDepth * (CodeUnitLength + 1) - 1; public const int MaxPathLength = 1000; public virtual int? TenantId { get; set; } /// /// 父 /// 空,如果这个 OU 是根 /// [ForeignKey("ParentId")] public virtual OrganizationUnit Parent { get; set; } /// /// 父 Id /// 空,如果这个 OU 是根 /// public virtual long? ParentId { get; set; } /// /// 本组织单位的层级代码 /// [Required] [StringLength(MaxCodeLength)] public virtual string? Code { get; set; } public virtual string Path { get; set; } public virtual bool IsLeaf { get; set; } /// /// 显示名称 /// [Required] [StringLength(MaxDisplayNameLength)] public virtual string DisplayName { get; set; } public virtual ICollection Children { get; set; } public OrganizationUnit() { } public OrganizationUnit(int? tenantId, string displayName, long? parentId = null) { TenantId = tenantId; DisplayName = displayName; ParentId = parentId; } /// /// 为给定数字创建代码。 /// 示例:如果数字是 4,2,则返回“00004.00002”; /// /// Numbers public static string? CreateCode(params int[] numbers) { if (numbers.IsNullOrEmpty()) { return null; } return numbers.Select(number => number.ToString(new string('0', CodeUnitLength))).JoinAsString("."); } /// /// 将子代码附加到父代码。 /// 示例:如果 parentCode = "00001", childCode = "00042" 然后返回 "00001.00042"。 /// /// Parent code. Can be null or empty if parent is a root. /// Child code. public static string? AppendCode(string? parentCode, string? childCode) { if (childCode.IsNullOrEmpty()) { throw new ArgumentNullException(nameof(childCode), "childCode can not be null or empty."); } if (parentCode.IsNullOrEmpty()) { return childCode; } return parentCode + "." + childCode; } /// /// 获取父级的相关代码。 /// 示例:如果代码 = "00019.00055.00001" 且 parentCode = "00019",则返回 "00055.00001"。 /// /// The code. /// The parent code. public static string? GetRelativeCode(string? code, string? parentCode) { if (code.IsNullOrEmpty()) { throw new ArgumentNullException(nameof(code), "code can not be null or empty."); } if (parentCode.IsNullOrEmpty()) { return code; } if (code!.Length == parentCode!.Length) { return null; } return code.Substring(parentCode.Length + 1); } /// /// 计算给定代码的下一个代码。 /// 示例:如果代码 = "00019.00055.00001" 返回 "00019.00055.00002"。 /// /// The code. public static string? CalculateNextCode(string? code) { if (code.IsNullOrEmpty()) { throw new ArgumentNullException(nameof(code), "code can not be null or empty."); } var parentCode = GetParentCode(code); var lastUnitCode = GetLastUnitCode(code); return AppendCode(parentCode, CreateCode(Convert.ToInt32(lastUnitCode) + 1)); } /// /// 获取最后一个单位代码。 /// 示例:如果代码 = "00019.00055.00001" 返回 "00001"。 /// /// The code. public static string GetLastUnitCode(string? code) { if (code.IsNullOrEmpty()) { throw new ArgumentNullException(nameof(code), "code can not be null or empty."); } var splittedCode = code!.Split('.'); return splittedCode[^1]; } /// /// 获取父代码。 /// 示例:如果代码 = "00019.00055.00001" 返回 "00019.00055"。 /// /// The code. public static string? GetParentCode(string? code) { if (code.IsNullOrEmpty()) { throw new ArgumentNullException(nameof(code), "code can not be null or empty."); } if (code == null) { return null; } var splittedCode = code.Split('.'); if (splittedCode.Length == 1) { return null; } return splittedCode.Take(splittedCode.Length - 1).JoinAsString("."); } }