diff --git a/module/upms/NPin.Framework.Upms.Domain/Entities/FileAggregateRoot.cs b/module/upms/NPin.Framework.Upms.Domain/Entities/FileAggregateRoot.cs new file mode 100644 index 0000000..23800f0 --- /dev/null +++ b/module/upms/NPin.Framework.Upms.Domain/Entities/FileAggregateRoot.cs @@ -0,0 +1,41 @@ +using SqlSugar; +using Volo.Abp.Auditing; +using Volo.Abp.Data; +using Volo.Abp.Domain.Entities; + +namespace NPin.Framework.Upms.Domain.Entities; + +[SugarTable("File", "文件信息表")] +public class FileAggregateRoot : AggregateRoot, IAuditedObject +{ + [SugarColumn(IsPrimaryKey = true, ColumnDescription = "主键")] + public override Guid Id { get; protected set; } + + [SugarColumn(ColumnDescription = "文件大小")] + public decimal FileSize { get; set; } + + [SugarColumn(ColumnDescription = "文件名称")] + public string FileName { get; set; } + + [SugarColumn(ColumnDescription = "文件后缀")] + public string FileExt { get; set; } + + [SugarColumn(ColumnDescription = "文件路径")] + public string FilePath { get; set; } + + public DateTime CreationTime { get; } + public Guid? CreatorId { get; } + public DateTime? LastModificationTime { get; } + public Guid? LastModifierId { get; } + + [SugarColumn(IsIgnore = true)] public override ExtraPropertyDictionary ExtraProperties { get; protected set; } + + public FileAggregateRoot() + { + } + + public FileAggregateRoot(Guid id) : base(id) + { + Id = id; + } +} \ No newline at end of file diff --git a/module/upms/NPin.Framework.Upms.Domain/Entities/OrganizationEntity.cs b/module/upms/NPin.Framework.Upms.Domain/Entities/OrganizationEntity.cs new file mode 100644 index 0000000..4e5a646 --- /dev/null +++ b/module/upms/NPin.Framework.Upms.Domain/Entities/OrganizationEntity.cs @@ -0,0 +1,46 @@ +using NPin.Framework.SqlSugarCore.Abstractions.Data; +using SqlSugar; +using Volo.Abp.Auditing; +using Volo.Abp.Domain.Entities; + +namespace NPin.Framework.Upms.Domain.Entities; + +[SugarTable("Organization", "组织机构表")] +public class OrganizationEntity : Entity, ISoftDelete, IAuditedObject, IOrderNum, IEnabled +{ + [SugarColumn(IsPrimaryKey = true, ColumnDescription = "主键")] + public override Guid Id { get; protected set; } + + [SugarColumn(ColumnDescription = "组织机构名称")] + public string Name { get; set; } = string.Empty; + + [SugarColumn(ColumnDescription = "组织机构编码")] + public string Code { get; set; } = string.Empty; + + [SugarColumn(ColumnDescription = "描述")] + public string? Remark { get; set; } + + /// + /// 负责人ID + /// + public Guid LeaderId { get; set; } + + /// + /// 负责人名称,仅用户展示,不存储 + /// + [SugarColumn(IsIgnore = true)] + public string Leader { get; set; } + + /// + /// 父节点 ID + /// + public Guid ParentId { get; set; } + + public bool IsDeleted { get; } + public DateTime CreationTime { get; } = DateTime.Now; + public Guid? CreatorId { get; } + public DateTime? LastModificationTime { get; } + public Guid? LastModifierId { get; } + public int OrderNum { get; set; } + public bool IsEnabled { get; set; } +} \ No newline at end of file diff --git a/module/upms/NPin.Framework.Upms.Domain/Entities/PostEntity.cs b/module/upms/NPin.Framework.Upms.Domain/Entities/PostEntity.cs new file mode 100644 index 0000000..d5df06e --- /dev/null +++ b/module/upms/NPin.Framework.Upms.Domain/Entities/PostEntity.cs @@ -0,0 +1,30 @@ +using NPin.Framework.SqlSugarCore.Abstractions.Data; +using SqlSugar; +using Volo.Abp.Auditing; +using Volo.Abp.Domain.Entities; + +namespace NPin.Framework.Upms.Domain.Entities; + +[SugarTable("Post", "岗位表")] +public class PostEntity : Entity, ISoftDelete, IAuditedObject, IOrderNum, IEnabled +{ + [SugarColumn(IsPrimaryKey = true, ColumnDescription = "主键")] + public override Guid Id { get; protected set; } + + [SugarColumn(ColumnDescription = "岗位编码")] + public string Code { get; set; } = string.Empty; + + [SugarColumn(ColumnDescription = "岗位名称")] + public string Name { get; set; } = string.Empty; + + [SugarColumn(ColumnDescription = "岗位描述")] + public string? Remark { get; set; } + + public bool IsDeleted { get; } + public DateTime CreationTime { get; } = DateTime.Now; + public Guid? CreatorId { get; } + public DateTime? LastModificationTime { get; } + public Guid? LastModifierId { get; } + public int OrderNum { get; set; } + public bool IsEnabled { get; set; } +} \ No newline at end of file diff --git a/module/upms/NPin.Framework.Upms.Domain/Entities/RoleEntity.cs b/module/upms/NPin.Framework.Upms.Domain/Entities/RoleEntity.cs new file mode 100644 index 0000000..e52d8e6 --- /dev/null +++ b/module/upms/NPin.Framework.Upms.Domain/Entities/RoleEntity.cs @@ -0,0 +1,34 @@ +using NPin.Framework.SqlSugarCore.Abstractions.Data; +using NPin.Framework.Upms.Domain.Shared.Enums; +using SqlSugar; +using Volo.Abp.Auditing; +using Volo.Abp.Domain.Entities; + +namespace NPin.Framework.Upms.Domain.Entities; + +[SugarTable("Role", "角色表")] +public class RoleEntity : Entity, ISoftDelete, IAuditedObject, IOrderNum, IEnabled +{ + [SugarColumn(IsPrimaryKey = true, ColumnDescription = "主键")] + public override Guid Id { get; protected set; } + + [SugarColumn(ColumnDescription = "角色代码")] + public string Code { get; set; } = string.Empty; + + [SugarColumn(ColumnDescription = "角色名称")] + public string Name { get; set; } = string.Empty; + + [SugarColumn(ColumnDescription = "角色数据权限范围")] + public DataScopeEnum DataScope { get; set; } = DataScopeEnum.All; + + [SugarColumn(ColumnDescription = "描述")] + public string? Remark { get; set; } + + public bool IsDeleted { get; } + public DateTime CreationTime { get; } = DateTime.Now; + public Guid? CreatorId { get; } + public DateTime? LastModificationTime { get; } + public Guid? LastModifierId { get; } + public int OrderNum { get; set; } + public bool IsEnabled { get; set; } +} \ No newline at end of file diff --git a/module/upms/NPin.Framework.Upms.Domain/Entities/UserEntity.cs b/module/upms/NPin.Framework.Upms.Domain/Entities/UserEntity.cs index 82c16aa..b8858fc 100644 --- a/module/upms/NPin.Framework.Upms.Domain/Entities/UserEntity.cs +++ b/module/upms/NPin.Framework.Upms.Domain/Entities/UserEntity.cs @@ -1,4 +1,4 @@ -using Microsoft.Win32.SafeHandles; +using NPin.Framework.Core.Crypt.BCrypt; using NPin.Framework.SqlSugarCore.Abstractions.Data; using NPin.Framework.Upms.Domain.Shared.Enums; using SqlSugar; @@ -7,7 +7,7 @@ using Volo.Abp.Domain.Entities; namespace NPin.Framework.Upms.Domain.Entities; -[SugarTable("User")] +[SugarTable("User", "用户表")] public class UserEntity : Entity, ISoftDelete, IAuditedObject, IEnabled, IOrderNum { #region User @@ -29,6 +29,9 @@ public class UserEntity : Entity, ISoftDelete, IAuditedObject, IEnabled, I [SugarColumn(ColumnDescription = "密码")] public string Password { get; set; } = string.Empty; + [SugarColumn(ColumnDescription = "密码加盐值")] + public string Salt { get; set; } = string.Empty; + [SugarColumn(ColumnDescription = "简介")] public string? Introduction { get; set; } @@ -50,7 +53,7 @@ public class UserEntity : Entity, ISoftDelete, IAuditedObject, IEnabled, I /// public bool IsDeleted { get; } - public DateTime CreationTime { get; } + public DateTime CreationTime { get; } = DateTime.Now; public Guid? CreatorId { get; } public DateTime? LastModificationTime { get; } public Guid? LastModifierId { get; } @@ -66,6 +69,29 @@ public class UserEntity : Entity, ISoftDelete, IAuditedObject, IEnabled, I #region 关联关系(导航) + /// + /// 用户元数据,保存可扩展数据 + /// 这里不使用Json的原因是有些库不是很好支持 + /// + [Navigate(NavigateType.OneToMany, nameof(UserMetaEntity.UserId))] + public List Metadata { get; set; } + + /// + /// 角色列表,多对多 + /// + [Navigate(typeof(UserRoleEntity), nameof(UserRoleEntity.UserId), nameof(UserRoleEntity.RoleId))] + public List Roles { get; set; } + + /// + /// 岗位列表,多对多 + /// + [Navigate(typeof(UserPostEntity), nameof(UserPostEntity.UserId), nameof(UserPostEntity.PostId))] + public List Posts { get; set; } + + [Navigate(typeof(UserOrganizationEntity), nameof(UserOrganizationEntity.UserId), + nameof(UserOrganizationEntity.OrganizationId))] + public List Organizations { get; set; } + #endregion public UserEntity() @@ -80,9 +106,50 @@ public class UserEntity : Entity, ISoftDelete, IAuditedObject, IEnabled, I { username = $"用户{phoneNumber}"; } + Nickname = nickname.IsNullOrWhiteSpace() ? username : nickname; - - // Password - // SafeNCryptHandle + EncryptPassword(password); + } + + /// + /// 通过随机盐值给密码加密,使用BCrypt算法 + /// + /// + /// + /// + public UserEntity EncryptPassword(string? password) + { + // 若传入密码无值,则使用原本Password + // 若原本Password依然无值,则抛出参数异常 + if (password == null) + { + if (Password.IsNullOrEmpty()) + { + throw new ArgumentNullException(nameof(Password)); + } + + password = Password; + } + + Salt = BCrypt.GenerateSalt(); + Password = BCrypt.Generate(password, Salt, 0).ToString()!; + + return this; + } + + /// + /// 检查密码是否一致 + /// + /// + /// + /// + public bool CheckPassword(string password) + { + if (Salt is null) + { + throw new ArgumentNullException(nameof(Salt)); + } + + return BCrypt.Check(Password, password, Salt, 0); } } \ No newline at end of file diff --git a/module/upms/NPin.Framework.Upms.Domain/Entities/UserMetaEntity.cs b/module/upms/NPin.Framework.Upms.Domain/Entities/UserMetaEntity.cs new file mode 100644 index 0000000..feca0f1 --- /dev/null +++ b/module/upms/NPin.Framework.Upms.Domain/Entities/UserMetaEntity.cs @@ -0,0 +1,24 @@ +using SqlSugar; +using Volo.Abp.Auditing; +using Volo.Abp.Domain.Entities; + +namespace NPin.Framework.Upms.Domain.Entities; + +[SugarTable("UserMetadata", "用户元数据表")] +public class UserMetaEntity : Entity, IAuditedObject +{ + [SugarColumn(IsPrimaryKey = true)] public override Guid Id { get; protected set; } + + public Guid UserId; + + [SugarColumn(ColumnDescription = "元数据 键")] + public string Key { get; set; } + + [SugarColumn(ColumnDescription = "元数据 值")] + public string Value { get; set; } + + public DateTime CreationTime { get; } + public Guid? CreatorId { get; } + public DateTime? LastModificationTime { get; } + public Guid? LastModifierId { get; } +} \ No newline at end of file diff --git a/module/upms/NPin.Framework.Upms.Domain/Entities/UserOrganizationEntity.cs b/module/upms/NPin.Framework.Upms.Domain/Entities/UserOrganizationEntity.cs new file mode 100644 index 0000000..724b8c2 --- /dev/null +++ b/module/upms/NPin.Framework.Upms.Domain/Entities/UserOrganizationEntity.cs @@ -0,0 +1,16 @@ +using SqlSugar; +using Volo.Abp.Domain.Entities; + +namespace NPin.Framework.Upms.Domain.Entities; + +[SugarTable("RelUserOrganization", "用户-组织机构 关系表")] +public class UserOrganizationEntity : Entity +{ + [SugarColumn(IsPrimaryKey = true)] public override Guid Id { get; protected set; } + + [SugarColumn(ColumnDescription = "用户ID")] + public Guid UserId { get; set; } + + [SugarColumn(ColumnDescription = "组织机构ID")] + public Guid OrganizationId { get; set; } +} \ No newline at end of file diff --git a/module/upms/NPin.Framework.Upms.Domain/Entities/UserPostEntity.cs b/module/upms/NPin.Framework.Upms.Domain/Entities/UserPostEntity.cs new file mode 100644 index 0000000..3ab6167 --- /dev/null +++ b/module/upms/NPin.Framework.Upms.Domain/Entities/UserPostEntity.cs @@ -0,0 +1,17 @@ +using SqlSugar; +using Volo.Abp.Domain.Entities; + +namespace NPin.Framework.Upms.Domain.Entities; + +[SugarTable("RelUserPost","用户-岗位 关系表")] +public class UserPostEntity: Entity +{ + [SugarColumn(IsPrimaryKey = true)] + public override Guid Id { get; protected set; } + + [SugarColumn(ColumnDescription = "用户ID")] + public Guid UserId { get; set; } + + [SugarColumn(ColumnDescription = "岗位ID")] + public Guid PostId { get; set; } +} \ No newline at end of file diff --git a/module/upms/NPin.Framework.Upms.Domain/Entities/UserRoleEntity.cs b/module/upms/NPin.Framework.Upms.Domain/Entities/UserRoleEntity.cs new file mode 100644 index 0000000..a5c8272 --- /dev/null +++ b/module/upms/NPin.Framework.Upms.Domain/Entities/UserRoleEntity.cs @@ -0,0 +1,17 @@ +using SqlSugar; +using Volo.Abp.Domain.Entities; + +namespace NPin.Framework.Upms.Domain.Entities; + +[SugarTable("RelUserRole", "用户-角色 关系表")] +public class UserRoleEntity: Entity +{ + [SugarColumn(IsPrimaryKey = true, ColumnDescription = "主键")] + public override Guid Id { get; protected set; } + + [SugarColumn(ColumnDescription = "角色ID")] + public Guid RoleId { get; set; } + + [SugarColumn(ColumnDescription = "用户ID")] + public Guid UserId { get; set; } +} \ No newline at end of file