From 6ccf2df9304739f6f2df17c78b043978df16d9ec Mon Sep 17 00:00:00 2001 From: NoahLan <6995syu@163.com> Date: Mon, 6 May 2024 16:31:50 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E5=AF=86=E7=A0=81?= =?UTF-8?q?=E5=80=BC=E5=AF=B9=E8=B1=A1=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Entities/UserEntity.cs | 304 +++++++++--------- .../EncryptPasswordValueObject.cs | 32 ++ 2 files changed, 179 insertions(+), 157 deletions(-) create mode 100644 module/upms/NPin.Framework.Upms.Domain/Entities/ValueObjects/EncryptPasswordValueObject.cs diff --git a/module/upms/NPin.Framework.Upms.Domain/Entities/UserEntity.cs b/module/upms/NPin.Framework.Upms.Domain/Entities/UserEntity.cs index c7ba9f9..4b56d1b 100644 --- a/module/upms/NPin.Framework.Upms.Domain/Entities/UserEntity.cs +++ b/module/upms/NPin.Framework.Upms.Domain/Entities/UserEntity.cs @@ -1,158 +1,148 @@ -using NPin.Framework.Core.Crypt.BCrypt; -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("User", "用户表")] -public class UserEntity : Entity, ISoftDelete, IAuditedObject, IEnabled, IOrderNum -{ - #region User - - [SugarColumn(IsPrimaryKey = true)] public override Guid Id { get; protected set; } - - [SugarColumn(ColumnDescription = "用户名")] - public string Username { get; set; } = string.Empty; - - [SugarColumn(ColumnDescription = "手机号码")] - public string PhoneNumber { get; set; } - - [SugarColumn(ColumnDescription = "邮箱")] - public string? Email { get; set; } - - [SugarColumn(ColumnDescription = "昵称")] - public string? Nickname { get; set; } - - [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; } - - [SugarColumn(ColumnDescription = "性别")] - public GenderEnum Gender { get; set; } = GenderEnum.Secrecy; - - [SugarColumn(ColumnDescription = "注册IP地址")] - public string? IpAddr { get; set; } - - [SugarColumn(ColumnDescription = "头像")] - public string? Avatar { get; set; } - - #endregion - - #region Implements - - /// - /// 逻辑删除 - /// - public bool IsDeleted { get; } - - public DateTime CreationTime { get; } = DateTime.Now; - public Guid? CreatorId { get; } - public DateTime? LastModificationTime { get; } - public Guid? LastModifierId { get; } - - /// - /// 是否启用 - /// - public bool IsEnabled { get; set; } - - public int OrderNum { get; set; } - - #endregion - - #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() - { - } - - public UserEntity(string username, string phoneNumber, string password, string? nickname) - { - Username = username; - PhoneNumber = phoneNumber; - if (username.IsNullOrEmpty()) - { - username = $"用户{phoneNumber}"; - } - - Nickname = nickname.IsNullOrWhiteSpace() ? username : nickname; - 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); - } +using NPin.Framework.Core.Crypt.BCrypt; +using NPin.Framework.SqlSugarCore.Abstractions.Data; +using NPin.Framework.Upms.Domain.Entities.ValueObjects; +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("User", "用户表")] +public class UserEntity : Entity, ISoftDelete, IAuditedObject, IEnabled, IOrderNum +{ + #region User + + [SugarColumn(IsPrimaryKey = true)] public override Guid Id { get; protected set; } + + [SugarColumn(ColumnDescription = "用户名")] + public string Username { get; set; } = string.Empty; + + [SugarColumn(ColumnDescription = "手机号码")] + public string PhoneNumber { get; set; } + + [SugarColumn(ColumnDescription = "邮箱")] + public string? Email { get; set; } + + [SugarColumn(ColumnDescription = "昵称")] + public string? Nickname { get; set; } + + [SugarColumn(ColumnDescription = "密码", IsOwnsOne = true)] + public EncryptPasswordValueObject? EncryptPassword { get; set; } = new EncryptPasswordValueObject(); + + [SugarColumn(ColumnDescription = "简介")] + public string? Introduction { get; set; } + + [SugarColumn(ColumnDescription = "性别")] + public GenderEnum Gender { get; set; } = GenderEnum.Secrecy; + + [SugarColumn(ColumnDescription = "注册IP地址")] + public string? IpAddr { get; set; } + + [SugarColumn(ColumnDescription = "头像")] + public string? Avatar { get; set; } + + #endregion + + #region Implements + + /// + /// 逻辑删除 + /// + public bool IsDeleted { get; } + + public DateTime CreationTime { get; } = DateTime.Now; + public Guid? CreatorId { get; } + public DateTime? LastModificationTime { get; } + public Guid? LastModifierId { get; } + + /// + /// 是否启用 + /// + public bool IsEnabled { get; set; } + + public int OrderNum { get; set; } + + #endregion + + #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() + { + } + + public UserEntity(string username, string phoneNumber, string password, string? nickname) + { + Username = username; + PhoneNumber = phoneNumber; + if (username.IsNullOrEmpty()) + { + username = $"用户{phoneNumber}"; + } + + Nickname = nickname.IsNullOrWhiteSpace() ? username : nickname; + EncryptPassword.Password = password; + + BuildPassword(); + } + + /// + /// 通过随机盐值给密码加密,使用BCrypt算法 + /// + /// + public UserEntity BuildPassword(string? password = null) + { + // 若传入密码无值,则使用原本Password + // 若原本Password依然无值,则抛出参数异常 + password ??= EncryptPassword?.Password ?? throw new ArgumentNullException(nameof(EncryptPassword.Password)); + + EncryptPassword.Salt = BCrypt.GenerateSalt(); + EncryptPassword.Password = BCrypt.Generate(password, EncryptPassword.Salt, 0).ToString()!; + + return this; + } + + /// + /// 检查密码是否一致 + /// + /// + /// + /// + public bool CheckPassword(string password) + { + if (EncryptPassword?.Salt is null) + { + throw new ArgumentNullException(nameof(EncryptPassword.Salt)); + } + + return BCrypt.Check(EncryptPassword.Password, password, EncryptPassword.Salt, 0); + } } \ No newline at end of file diff --git a/module/upms/NPin.Framework.Upms.Domain/Entities/ValueObjects/EncryptPasswordValueObject.cs b/module/upms/NPin.Framework.Upms.Domain/Entities/ValueObjects/EncryptPasswordValueObject.cs new file mode 100644 index 0000000..8fb376a --- /dev/null +++ b/module/upms/NPin.Framework.Upms.Domain/Entities/ValueObjects/EncryptPasswordValueObject.cs @@ -0,0 +1,32 @@ +using Volo.Abp.Domain.Values; + +namespace NPin.Framework.Upms.Domain.Entities.ValueObjects; + +public class EncryptPasswordValueObject : ValueObject +{ + /// + /// 密码 + /// + public string Password { get; set; } = string.Empty; + + /// + /// 加密盐值 + /// + public string Salt { get; set; } = string.Empty; + + public EncryptPasswordValueObject() + { + } + + public EncryptPasswordValueObject(string password) + { + this.Password = password; + } + + + protected override IEnumerable GetAtomicValues() + { + yield return Password; + yield return Salt; + } +} \ No newline at end of file