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); } }