diff --git a/src/admin/Bootstrap.Admin/Components/IRules.cs b/src/admin/Bootstrap.Admin/Components/IRules.cs new file mode 100644 index 0000000000000000000000000000000000000000..3a1e672dd207ee81ebc23f8a9953fadf7a5acd45 --- /dev/null +++ b/src/admin/Bootstrap.Admin/Components/IRules.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; + +namespace Bootstrap.Admin.Components +{ + /// + /// IRules 接口 + /// + public interface IRules + { + /// + /// 获得 Rules 集合 + /// + ICollection Rules { get; } + } +} diff --git a/src/admin/Bootstrap.Admin/Components/LgbInputTextBase.cs b/src/admin/Bootstrap.Admin/Components/LgbInputBase.cs similarity index 64% rename from src/admin/Bootstrap.Admin/Components/LgbInputTextBase.cs rename to src/admin/Bootstrap.Admin/Components/LgbInputBase.cs index da9796cfc60805eb6494b094dd1f5cb031c9aa40..f706352e49c698b22e071845ab1ed5c37afae34b 100644 --- a/src/admin/Bootstrap.Admin/Components/LgbInputTextBase.cs +++ b/src/admin/Bootstrap.Admin/Components/LgbInputBase.cs @@ -7,36 +7,22 @@ namespace Bootstrap.Admin.Components /// /// LgbInputText 组件 /// - public class LgbInputTextBase : ValidateInputBase + public class LgbInputBase : ValidateInputBase { /// - /// + /// 获得/设置 控件样式 默认为 col-sm-6 /// [Parameter] public string ColumnClass { get; set; } = "col-sm-6"; /// - /// + /// 获得/设置 控件 type 属性 默认为 text /// [Parameter] public string InputType { get; set; } = "text"; /// - /// - /// - /// - /// - /// - /// - protected override bool TryParseValueFromString(string value, out string result, out string validationErrorMessage) - { - result = value; - validationErrorMessage = ""; - return true; - } - - /// - /// + /// 获取 最大长度属性 /// protected int? MaxLength { diff --git a/src/admin/Bootstrap.Admin/Components/QueryInputTextBase.cs b/src/admin/Bootstrap.Admin/Components/LgbInputText.cs similarity index 44% rename from src/admin/Bootstrap.Admin/Components/QueryInputTextBase.cs rename to src/admin/Bootstrap.Admin/Components/LgbInputText.cs index 527e5c058ec849cb62e19c12998155b391a3106f..1e9890a0949b0c09ab151f916c492b9fb5a9e8e4 100644 --- a/src/admin/Bootstrap.Admin/Components/QueryInputTextBase.cs +++ b/src/admin/Bootstrap.Admin/Components/LgbInputText.cs @@ -1,11 +1,11 @@ -using Microsoft.AspNetCore.Components; +using Bootstrap.Admin.Shared; namespace Bootstrap.Admin.Components { /// - /// + /// LgbInputText 组件 /// - public class QueryInputTextBase : LgbInputTextBase + public class LgbInputText : LgbInput { } diff --git a/src/admin/Bootstrap.Admin/Components/SelectBase.cs b/src/admin/Bootstrap.Admin/Components/SelectBase.cs index 4b790b9e9ad95e1030b43a872c43959cb7feab05..bb5fa7c3ca9b5cc5bd4678f912e52301708546b3 100644 --- a/src/admin/Bootstrap.Admin/Components/SelectBase.cs +++ b/src/admin/Bootstrap.Admin/Components/SelectBase.cs @@ -11,7 +11,7 @@ namespace Bootstrap.Admin.Components public class SelectBase : ValidateInputBase { /// - /// + /// 获得/设置 Select 组件 列样式 默认 col-sm-6 /// [Parameter] public string ColumnClass { get; set; } = "col-sm-6"; @@ -28,7 +28,13 @@ namespace Bootstrap.Admin.Components public List Items { get; set; } = new List(); /// - /// + /// 获得/设置 是否禁用 + /// + [Parameter] + public bool Disabled { get; set; } + + /// + /// OnParametersSet 方法 /// protected override void OnParametersSet() { @@ -40,7 +46,7 @@ namespace Bootstrap.Admin.Components } /// - /// + /// OnInitialized 方法 /// protected override void OnInitialized() { @@ -52,13 +58,13 @@ namespace Bootstrap.Admin.Components } /// - /// + /// SelectedItemChanged 方法 /// [Parameter] public Action? SelectedItemChanged { get; set; } /// - /// + /// 下拉框项被选中时调用此方法 /// public void ItemClickCallback(SelectedItem item) { diff --git a/src/admin/Bootstrap.Admin/Components/ValidateInputBase.cs b/src/admin/Bootstrap.Admin/Components/ValidateInputBase.cs index f38b61eb21564f9f83d6a017544a5748cdcf6653..b956506dce46a28c418112857c0ad5288f947df8 100644 --- a/src/admin/Bootstrap.Admin/Components/ValidateInputBase.cs +++ b/src/admin/Bootstrap.Admin/Components/ValidateInputBase.cs @@ -11,24 +11,24 @@ using System.Linq; namespace Bootstrap.Admin.Components { /// - /// + /// 内置验证组件基类 /// - public abstract class ValidateInputBase : InputBase, IValidateComponent + public abstract class ValidateInputBase : InputBase, IValidateComponent, IRules { /// - /// + /// 获得 IJSRuntime 实例 /// [Inject] protected IJSRuntime? JSRuntime { get; set; } /// - /// + /// 获得 LgbEditFormBase 实例 /// [CascadingParameter] public LgbEditFormBase? EditForm { get; set; } /// - /// + /// 获得 当前组件 Id /// public string Id { @@ -36,13 +36,13 @@ namespace Bootstrap.Admin.Components } /// - /// + /// 获得 子组件 RenderFragment 实例 /// [Parameter] public RenderFragment? ChildContent { get; set; } /// - /// + /// 获得 PlaceHolder 属性 /// protected string? PlaceHolder { @@ -59,22 +59,22 @@ namespace Bootstrap.Admin.Components } /// - /// + /// 获得/设置 错误描述信息 /// protected string ErrorMessage { get; set; } = ""; /// - /// + /// 获得/设置 数据合规样式 /// protected string ValidCss { get; set; } = ""; /// - /// + /// 获得/设置 显示名称 默认为 - /// protected string DisplayName { get; set; } = "-"; /// - /// + /// OnInitialized 方法 /// protected override void OnInitialized() { @@ -83,7 +83,7 @@ namespace Bootstrap.Admin.Components } /// - /// + /// OnAfterRender 方法 /// /// protected override void OnAfterRender(bool firstRender) @@ -96,13 +96,13 @@ namespace Bootstrap.Admin.Components } /// - /// + /// 获得 数据验证方法集合 /// public ICollection Rules { get; } = new HashSet(); private string _tooltipMethod = ""; /// - /// + /// 属性验证方法 /// /// /// @@ -142,7 +142,7 @@ namespace Bootstrap.Admin.Components } /// - /// + /// 将 字符串 Value 属性转化为 泛型 Value 方法 /// /// /// diff --git a/src/admin/Bootstrap.Admin/Components/ValidatorComponentBase.cs b/src/admin/Bootstrap.Admin/Components/ValidatorComponentBase.cs index a1528270b7f773935b2c0df84b84c4077a1454de..f4eace287a529e0060ddad6bd4cb113836927412 100644 --- a/src/admin/Bootstrap.Admin/Components/ValidatorComponentBase.cs +++ b/src/admin/Bootstrap.Admin/Components/ValidatorComponentBase.cs @@ -6,21 +6,21 @@ using System.ComponentModel.DataAnnotations; namespace Bootstrap.Admin.Components { /// - /// + /// 验证组件基类 /// public abstract class ValidatorComponentBase : ComponentBase { /// - /// + /// 获得/设置 错误描述信息 /// [Parameter] public string ErrorMessage { get; set; } = ""; /// - /// + /// 获得/设置 IRules 实例 /// [CascadingParameter] - public LgbInputTextBase? Input { get; set; } + public IRules? Input { get; set; } /// /// 初始化方法 @@ -30,7 +30,7 @@ namespace Bootstrap.Admin.Components if (Input == null) { throw new InvalidOperationException($"{nameof(ValidatorComponentBase)} requires a cascading " + - $"parameter of type {nameof(LgbInputTextBase)}. For example, you can use {nameof(ValidatorComponentBase)} " + + $"parameter of type {nameof(IRules)}. For example, you can use {nameof(ValidatorComponentBase)} " + $"inside an LgbInputText."); } @@ -38,7 +38,7 @@ namespace Bootstrap.Admin.Components } /// - /// + /// 验证方法 /// /// /// diff --git a/src/admin/Bootstrap.Admin/Extensions/DisplayNamesExtensions.cs b/src/admin/Bootstrap.Admin/Extensions/DisplayNamesExtensions.cs index ba419bdca6a5f5ccef688a1c09f87f30ad8ca826..9eab8d6ddba78e20d25f8d088eeb2fbecbe8f385 100644 --- a/src/admin/Bootstrap.Admin/Extensions/DisplayNamesExtensions.cs +++ b/src/admin/Bootstrap.Admin/Extensions/DisplayNamesExtensions.cs @@ -32,6 +32,17 @@ namespace Microsoft.AspNetCore.Builder _displayNameCache.TryAdd((typeof(Group), nameof(Group.GroupCode)), "部门编码"); _displayNameCache.TryAdd((typeof(Group), nameof(Group.GroupName)), "部门名称"); _displayNameCache.TryAdd((typeof(Group), nameof(Group.Description)), "部门描述"); + + _displayNameCache.TryAdd((typeof(BootstrapMenu), nameof(BootstrapMenu.Name)), "菜单名称"); + _displayNameCache.TryAdd((typeof(BootstrapMenu), nameof(BootstrapMenu.ParentName)), "父级菜单"); + _displayNameCache.TryAdd((typeof(BootstrapMenu), nameof(BootstrapMenu.Order)), "菜单序号"); + _displayNameCache.TryAdd((typeof(BootstrapMenu), nameof(BootstrapMenu.Icon)), "菜单图标"); + _displayNameCache.TryAdd((typeof(BootstrapMenu), nameof(BootstrapMenu.Url)), "菜单路径"); + _displayNameCache.TryAdd((typeof(BootstrapMenu), nameof(BootstrapMenu.Category)), "菜单类别"); + _displayNameCache.TryAdd((typeof(BootstrapMenu), nameof(BootstrapMenu.Target)), "目标"); + _displayNameCache.TryAdd((typeof(BootstrapMenu), nameof(BootstrapMenu.IsResource)), "菜单类型"); + _displayNameCache.TryAdd((typeof(BootstrapMenu), nameof(BootstrapMenu.Application)), "所属应用"); + return services; } diff --git a/src/admin/Bootstrap.Admin/Pages/Admin/Menus.razor b/src/admin/Bootstrap.Admin/Pages/Admin/Menus.razor index fecf0af70e92875e18e373ff61b2df6b9904404d..a3100691545c3bfa46f991a1ee3b55cfef09b4a9 100644 --- a/src/admin/Bootstrap.Admin/Pages/Admin/Menus.razor +++ b/src/admin/Bootstrap.Admin/Pages/Admin/Menus.razor @@ -1,6 +1,56 @@ - -

Menus

+@inherits MenusBase -@code { - -} + + + + + + + + + + + + diff --git a/src/admin/Bootstrap.Admin/Pages/Components/MenusBase.cs b/src/admin/Bootstrap.Admin/Pages/Components/MenusBase.cs new file mode 100644 index 0000000000000000000000000000000000000000..56701589383b7d7cb3e6ab74381905ef08f6d620 --- /dev/null +++ b/src/admin/Bootstrap.Admin/Pages/Components/MenusBase.cs @@ -0,0 +1,164 @@ +using Bootstrap.Admin.Components; +using Bootstrap.DataAccess; +using Bootstrap.Security; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Authorization; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Bootstrap.Pages.Admin.Components +{ + /// + /// 菜单维护组件 + /// + public class MenusBase : QueryPageBase + { + /// + /// 获得 授权服务 + /// + [Inject] + protected AuthenticationStateProvider? AuthenticationStateProvider { get; set; } + + /// + /// 获得/设置 菜单类别 + /// + protected List QueryCategory { get; set; } = new List(new SelectedItem[] { + new SelectedItem() { Text = "全部", Value = "", Active = true }, + new SelectedItem() { Text = "系统菜单", Value = "0" }, + new SelectedItem() { Text = "外部菜单", Value = "1" } + }); + + /// + /// 获得/设置 菜单类型 + /// + protected List QueryResource { get; set; } = new List(new SelectedItem[] { + new SelectedItem() { Text = "全部", Value = "-1", Active = true }, + new SelectedItem() { Text = "菜单", Value = "0" }, + new SelectedItem() { Text = "资源", Value = "1" }, + new SelectedItem() { Text = "按钮", Value = "2" } + }); + + /// + /// 获得/设置 所属应用 + /// + protected List QueryApp { get; set; } = new List(new SelectedItem[] { + new SelectedItem() { Text = "全部", Value = "", Active = true } + }); + + + /// + /// 获得/设置 菜单类别 + /// + protected List DefineCategory { get; set; } = new List(new SelectedItem[] { + new SelectedItem() { Text = "系统菜单", Value = "0" }, + new SelectedItem() { Text = "外部菜单", Value = "1" } + }); + + /// + /// 获得/设置 菜单类型 + /// + protected List DefineResource { get; set; } = new List(new SelectedItem[] { + new SelectedItem() { Text = "菜单", Value = "0" }, + new SelectedItem() { Text = "资源", Value = "1" }, + new SelectedItem() { Text = "按钮", Value = "2" } + }); + + /// + /// 获得/设置 所属应用 + /// + protected List DefineApp { get; set; } = new List(); + + /// + /// 获得/设置 所属应用 + /// + protected List DefineTarget { get; set; } = new List() { + new SelectedItem() { Text = "本窗口", Value = "_self" }, + new SelectedItem() { Text = "新窗口", Value = "_blank" }, + new SelectedItem() { Text = "父级窗口", Value = "_parent" }, + new SelectedItem() { Text = "顶级窗口", Value = "_top" } + }; + + /// + /// 获得/设置 用户登录名 + /// + protected string? UserName { get; set; } + + /// + /// OnInitializedAsync 方法 + /// + /// + protected override async System.Threading.Tasks.Task OnInitializedAsync() + { + if (AuthenticationStateProvider != null) + { + var state = await AuthenticationStateProvider.GetAuthenticationStateAsync(); + UserName = state?.User.Identity.Name; + } + } + + /// + /// OnParametersSet 方法 + /// + /// + protected override void OnParametersSet() + { + QueryModel.Category = ""; + QueryModel.IsResource = -1; + QueryApp.AddRange(DictHelper.RetrieveApps().Select(app => new SelectedItem() { Text = app.Value, Value = app.Key })); + DefineApp.AddRange(DictHelper.RetrieveApps().Select(app => new SelectedItem() { Text = app.Value, Value = app.Key })); + } + + /// + /// 查询方法 + /// + /// 页码 + /// 每页显示数据条目数量 + protected override QueryData Query(int pageIndex, int pageItems) + { + var data = MenuHelper.RetrieveMenusByUserName(UserName); + if (!string.IsNullOrEmpty(QueryModel.Name)) data = data.Where(d => d.Name.Contains(QueryModel.Name, StringComparison.OrdinalIgnoreCase)); + if (!string.IsNullOrEmpty(QueryModel.ParentName)) data = data.Where(d => d.ParentName.Contains(QueryModel.ParentName, StringComparison.OrdinalIgnoreCase)); + if (!string.IsNullOrEmpty(QueryModel.Category)) data = data.Where(d => d.Category == QueryModel.Category); + if (QueryModel.IsResource != -1) data = data.Where(d => d.IsResource == QueryModel.IsResource); + if (!string.IsNullOrEmpty(QueryModel.Application)) data = data.Where(d => d.Application.Equals(QueryModel.Application, StringComparison.OrdinalIgnoreCase)); + var totalCount = data.Count(); + var items = data.Skip((pageIndex - 1) * pageItems).Take(pageItems); + return new QueryData() { Items = items, TotalCount = totalCount, PageIndex = pageIndex, PageItems = pageItems }; + } + + /// + /// 新建方法 + /// + protected override BootstrapMenu Add() + { + return new BootstrapMenu() + { + Order = 10, + Icon = "fa fa-fa", + Target = "_self", + Category = "0", + IsResource = 0, + Application = DefineApp.First().Value + }; + } + + /// + /// 保存方法 + /// + protected override bool Save(BootstrapMenu item) => MenuHelper.Save(item); + + /// + /// 删除方法 + /// + protected override bool Delete(IEnumerable items) => MenuHelper.Delete(items.Select(item => item.Id ?? "")); + + /// + /// 分配角色方法 + /// + protected void AssignRoles() + { + + } + } +} diff --git a/src/admin/Bootstrap.Admin/Pages/Components/QueryPageBase.cs b/src/admin/Bootstrap.Admin/Pages/Components/QueryPageBase.cs index 19870852276a9e4283963d2a26305f938d2913ba..00c0101dadb099f9bdae323e68d00bd344f69475 100644 --- a/src/admin/Bootstrap.Admin/Pages/Components/QueryPageBase.cs +++ b/src/admin/Bootstrap.Admin/Pages/Components/QueryPageBase.cs @@ -24,7 +24,7 @@ namespace Bootstrap.Pages.Admin.Components /// 新建方法 ///
/// - protected TItem Add() => new TItem(); + protected virtual TItem Add() => new TItem(); /// /// 保存方法 diff --git a/src/admin/Bootstrap.Admin/Shared/LgbInputText.razor b/src/admin/Bootstrap.Admin/Shared/LgbInput.razor similarity index 92% rename from src/admin/Bootstrap.Admin/Shared/LgbInputText.razor rename to src/admin/Bootstrap.Admin/Shared/LgbInput.razor index 61d08f6cafb4df66a05e4e11d5afbe7c217c5248..f984585290589938962749ff201b4e40b4551102 100644 --- a/src/admin/Bootstrap.Admin/Shared/LgbInputText.razor +++ b/src/admin/Bootstrap.Admin/Shared/LgbInput.razor @@ -1,4 +1,5 @@ -@inherits LgbInputTextBase +@typeparam TItem +@inherits LgbInputBase
diff --git a/src/admin/Bootstrap.Admin/Shared/Select.razor b/src/admin/Bootstrap.Admin/Shared/Select.razor index fb3b295e0869bf19d5856acc5fa03ce4ede87418..fc3d990030e939cf1e852e71cc415b3303faa90b 100644 --- a/src/admin/Bootstrap.Admin/Shared/Select.razor +++ b/src/admin/Bootstrap.Admin/Shared/Select.razor @@ -3,8 +3,15 @@
-