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(".");
}
}