From f8870109c3c5189539938be5577b903d6d625c01 Mon Sep 17 00:00:00 2001 From: Argo-Tianyi Date: Wed, 5 Jan 2022 08:26:40 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E7=99=BB=E5=BD=95=E5=90=8D=E7=A7=B0=E9=AA=8C=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BootstrapAdmin.DataAccess.Models/User.cs | 12 +++++- .../BootstrapAdminConventionMapper.cs | 14 ++++--- .../Services/DefaultDataService.cs | 19 +++++++-- .../Services/UserService.cs | 15 +++++++ .../admin/BootstrapAdmin.Web.Core/IUser.cs | 10 +++++ .../Pages/Admin/Users.razor | 27 +++++++++++-- .../Pages/Admin/Users.razor.cs | 18 +++++++++ .../Validators/UserNameValidator.cs | 40 +++++++++++++++++++ 8 files changed, 140 insertions(+), 15 deletions(-) create mode 100644 src/blazor/admin/BootstrapAdmin.Web/Validators/UserNameValidator.cs diff --git a/src/blazor/admin/BootstrapAdmin.DataAccess.Models/User.cs b/src/blazor/admin/BootstrapAdmin.DataAccess.Models/User.cs index 7fdfad86..81dc3e76 100644 --- a/src/blazor/admin/BootstrapAdmin.DataAccess.Models/User.cs +++ b/src/blazor/admin/BootstrapAdmin.DataAccess.Models/User.cs @@ -11,6 +11,10 @@ namespace BootstrapAdmin.DataAccess.Models /// 获得/设置 系统登录用户名 /// [Display(Name = "登录名称")] + [Required(ErrorMessage = "{0}不可为空")] + [RegularExpression("^[a-zA-Z0-9_@.]*$", ErrorMessage = "登录名称包含非法字符")] + [MaxLength(16, ErrorMessage = "{0}不能超过 16 个字符")] + [NotNull] public string? UserName { get; set; } /// @@ -18,7 +22,8 @@ namespace BootstrapAdmin.DataAccess.Models /// [Display(Name = "显示名称")] [Required(ErrorMessage = "{0}不可为空")] - [MaxLength(50, ErrorMessage = "{0}不能超过 50 个字符")] + [MaxLength(20, ErrorMessage = "{0}不能超过 20 个字符")] + [NotNull] public string? DisplayName { get; set; } /// @@ -49,6 +54,8 @@ namespace BootstrapAdmin.DataAccess.Models /// [Display(Name = "密码")] [Required(ErrorMessage = "{0}不可为空")] + [MaxLength(16, ErrorMessage = "{0}不能超过 16 个字符")] + [NotNull] public string? Password { get; set; } /// @@ -78,6 +85,7 @@ namespace BootstrapAdmin.DataAccess.Models /// 获得/设置 用户的申请理由 /// [Display(Name = "说明")] + [NotNull] public string? Description { get; set; } /// @@ -90,6 +98,7 @@ namespace BootstrapAdmin.DataAccess.Models /// [Display(Name = "新密码")] [Required(ErrorMessage = "{0}不可为空")] + [MaxLength(16, ErrorMessage = "{0}不能超过 16 个字符")] [NotNull] public string? NewPassword { get; set; } @@ -99,6 +108,7 @@ namespace BootstrapAdmin.DataAccess.Models [Display(Name = "确认密码")] [Required(ErrorMessage = "{0}不可为空")] [Compare("NewPassword", ErrorMessage = "{0}与{1}不一致")] + [MaxLength(16, ErrorMessage = "{0}不能超过 16 个字符")] [NotNull] public string? ConfirmPassword { get; set; } diff --git a/src/blazor/admin/BootstrapAdmin.DataAccess.PetaPoco/BootstrapAdminConventionMapper.cs b/src/blazor/admin/BootstrapAdmin.DataAccess.PetaPoco/BootstrapAdminConventionMapper.cs index ace911fb..1f583def 100644 --- a/src/blazor/admin/BootstrapAdmin.DataAccess.PetaPoco/BootstrapAdminConventionMapper.cs +++ b/src/blazor/admin/BootstrapAdmin.DataAccess.PetaPoco/BootstrapAdminConventionMapper.cs @@ -43,12 +43,14 @@ class BootstrapAdminConventionMapper : ConventionMapper { var ci = base.GetColumnInfo(pocoProperty); var resultColumns = new List - { - nameof(Models.User.Period), - nameof(Models.User.NewPassword), - nameof(Models.User.ConfirmPassword), - nameof(Models.User.IsReset) - }; + { + nameof(Models.User.Password), + nameof(Models.User.PassSalt), + nameof(Models.User.NewPassword), + nameof(Models.User.ConfirmPassword), + nameof(Models.User.Period), + nameof(Models.User.IsReset) + }; ci.ResultColumn = resultColumns.Any(c => c == ci.ColumnName); return ci; } diff --git a/src/blazor/admin/BootstrapAdmin.DataAccess.PetaPoco/Services/DefaultDataService.cs b/src/blazor/admin/BootstrapAdmin.DataAccess.PetaPoco/Services/DefaultDataService.cs index 294aeedf..cfa887e1 100644 --- a/src/blazor/admin/BootstrapAdmin.DataAccess.PetaPoco/Services/DefaultDataService.cs +++ b/src/blazor/admin/BootstrapAdmin.DataAccess.PetaPoco/Services/DefaultDataService.cs @@ -2,7 +2,9 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Website: https://www.blazor.zone or https://argozhang.github.io/ +using BootstrapAdmin.DataAccess.Models; using BootstrapAdmin.DataAccess.PetaPoco.Extensions; +using BootstrapAdmin.Web.Core; using BootstrapAdmin.Web.Extensions; using BootstrapBlazor.Components; using PetaPoco; @@ -17,10 +19,12 @@ class DefaultDataService : DataServiceBase where TModel : class, { private IDatabase Database { get; } + private IUser UserService { get; } + /// /// 构造函数 /// - public DefaultDataService(IDatabase db) => Database = db; + public DefaultDataService(IDatabase db, IUser userService) => (Database, UserService) = (db, userService); /// /// 删除方法 @@ -43,13 +47,20 @@ class DefaultDataService : DataServiceBase where TModel : class, /// public override async Task SaveAsync(TModel model, ItemChangedType changedType) { - if (changedType == ItemChangedType.Add) + if (model is User user) { - await Database.InsertAsync(model); + UserService.SaveUser(user.Id, user.UserName, user.DisplayName, user.NewPassword); } else { - await Database.UpdateAsync(model); + if (changedType == ItemChangedType.Add) + { + await Database.InsertAsync(model); + } + else + { + await Database.UpdateAsync(model); + } } return true; } diff --git a/src/blazor/admin/BootstrapAdmin.DataAccess.PetaPoco/Services/UserService.cs b/src/blazor/admin/BootstrapAdmin.DataAccess.PetaPoco/Services/UserService.cs index 80d1345e..90f3ebf2 100644 --- a/src/blazor/admin/BootstrapAdmin.DataAccess.PetaPoco/Services/UserService.cs +++ b/src/blazor/admin/BootstrapAdmin.DataAccess.PetaPoco/Services/UserService.cs @@ -172,4 +172,19 @@ class UserService : BaseDatabase, IUser } return ret; } + + public bool SaveUser(string? id, string userName, string displayName, string password) + { + var salt = LgbCryptography.GenerateSalt(); + var pwd = LgbCryptography.ComputeHash(password, salt); + if (string.IsNullOrEmpty(id)) + { + Database.Execute("INSERT INTO Users (UserName, Password, PassSalt, DisplayName, RegisterTime, ApprovedTime, ApprovedBy, [Description]) values (@0, @1, @2, @3, @4, @4, 'system', '系统默认创建');", userName, pwd, salt, displayName, DateTime.Now); + } + else + { + Database.Update("set Password = @1, PassSalt = @2, DisplayName = @3 where Id = @0", id, pwd, salt, displayName); + } + return true; + } } diff --git a/src/blazor/admin/BootstrapAdmin.Web.Core/IUser.cs b/src/blazor/admin/BootstrapAdmin.Web.Core/IUser.cs index 7822170c..342b0f64 100644 --- a/src/blazor/admin/BootstrapAdmin.Web.Core/IUser.cs +++ b/src/blazor/admin/BootstrapAdmin.Web.Core/IUser.cs @@ -80,4 +80,14 @@ public interface IUser /// /// bool TryCreateUserByPhone(string phone, string code, string appId, ICollection roles); + + /// + /// + /// + /// + /// + /// + /// + /// + bool SaveUser(string? id, string userName, string displayName, string password); } diff --git a/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Users.razor b/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Users.razor index e6bf289c..13404910 100644 --- a/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Users.razor +++ b/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Users.razor @@ -1,20 +1,39 @@ @page "/Admin/Users" - + - + - + + +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
- +
diff --git a/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Users.razor.cs b/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Users.razor.cs index 0fc21872..f8b2f6ae 100644 --- a/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Users.razor.cs +++ b/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Users.razor.cs @@ -1,6 +1,7 @@ using BootstrapAdmin.DataAccess.Models; using BootstrapAdmin.Web.Core; using BootstrapAdmin.Web.Extensions; +using BootstrapAdmin.Web.Validators; namespace BootstrapAdmin.Web.Pages.Admin; @@ -25,8 +26,25 @@ public partial class Users [NotNull] private IRole? RoleService { get; set; } + [Inject] + [NotNull] + private IUser? UserService { get; set; } + private List SortList { get; } = new List { "UserName" }; + private static bool GetDisabled(string? id) => !string.IsNullOrEmpty(id); + + private List UserRules { get; } = new List(); + + /// + /// OnInitialized 方法 + /// + protected override void OnInitialized() + { + base.OnInitialized(); + UserRules.Add(new UserNameValidator(UserService)); + } + private async Task OnAssignmentGroups(User user) { var groups = GroupService.GetAll().ToSelectedItemList(); diff --git a/src/blazor/admin/BootstrapAdmin.Web/Validators/UserNameValidator.cs b/src/blazor/admin/BootstrapAdmin.Web/Validators/UserNameValidator.cs new file mode 100644 index 00000000..ffceaf09 --- /dev/null +++ b/src/blazor/admin/BootstrapAdmin.Web/Validators/UserNameValidator.cs @@ -0,0 +1,40 @@ +using BootstrapAdmin.Web.Core; +using System.ComponentModel.DataAnnotations; + +namespace BootstrapAdmin.Web.Validators; + +public class UserNameValidator : IValidator +{ + public string? ErrorMessage { get; set; } + + private IUser UserService { get; } + + /// + /// + /// + /// + public UserNameValidator(IUser userService) => UserService = userService; + + /// + /// + /// + /// + /// + /// + public void Validate(object? propertyValue, ValidationContext context, List results) + { + var displayName = UserService.GetDisplayName(propertyValue?.ToString()); + if (!string.IsNullOrEmpty(displayName)) + { + ErrorMessage = $"{context.DisplayName}已存在"; + } + else + { + ErrorMessage = null; + } + if (!string.IsNullOrEmpty(ErrorMessage)) + { + results.Add(new ValidationResult(ErrorMessage, new string[] { context.MemberName! })); + } + } +}