diff --git a/src/admin/Bootstrap.Admin/Components/EditPageBase.cs b/src/admin/Bootstrap.Admin/Components/EditPageBase.cs index 49ef57bd7f97c3cc68b1826da5ed4cf0e8413da6..c2c38b9049727db8a4b7e4c64adbf961ee1c3935 100644 --- a/src/admin/Bootstrap.Admin/Components/EditPageBase.cs +++ b/src/admin/Bootstrap.Admin/Components/EditPageBase.cs @@ -34,7 +34,7 @@ namespace Bootstrap.Admin.Components /// 查询按钮回调方法 /// [Parameter] - public Func>? OnQuery { get; set; } + public Func>? OnQuery { get; set; } /// /// 获得/设置 TableHeader 实例 @@ -163,10 +163,8 @@ namespace Bootstrap.Admin.Components /// /// 分页查询方法 /// - /// - /// - /// + /// /// - protected QueryData QueryData(int pageIndex, int pageItems, string searchText) => OnQuery?.Invoke(pageIndex, pageItems, searchText) ?? new QueryData(); + protected QueryData QueryData(QueryPageOptions options) => OnQuery?.Invoke(options) ?? new QueryData(); } } diff --git a/src/admin/Bootstrap.Admin/Components/ITableHeader.cs b/src/admin/Bootstrap.Admin/Components/ITableHeader.cs new file mode 100644 index 0000000000000000000000000000000000000000..0c08920d1ca41137179d8a393f050ec9e298eef4 --- /dev/null +++ b/src/admin/Bootstrap.Admin/Components/ITableHeader.cs @@ -0,0 +1,25 @@ +using Microsoft.AspNetCore.Components.Forms; + +namespace Bootstrap.Admin.Components +{ + /// + /// ITableHeader 接口 + /// + public interface ITableHeader + { + /// + /// 获取绑定字段显示名称方法 + /// + string GetDisplayName(); + + /// + /// 获取绑定字段信息方法 + /// + string GetFieldName(); + + /// + /// 获得/设置 是否允许排序 默认为 false + /// + bool Sort { get; set; } + } +} diff --git a/src/admin/Bootstrap.Admin/Components/LgbTableHeader.cs b/src/admin/Bootstrap.Admin/Components/LgbTableHeader.cs index fe3a641b944be2e0827a8ab28664c1d8a22bd627..a0050a0e733a1917a78082ca9268aa400966c7a1 100644 --- a/src/admin/Bootstrap.Admin/Components/LgbTableHeader.cs +++ b/src/admin/Bootstrap.Admin/Components/LgbTableHeader.cs @@ -1,45 +1,69 @@ using Bootstrap.Admin.Extensions; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Forms; -using Microsoft.AspNetCore.Components.Rendering; using System; using System.Linq.Expressions; namespace Bootstrap.Admin.Components { /// - /// + /// 表头组件 /// - public class LgbTableHeader : ComponentBase + public class LgbTableHeader : ComponentBase, ITableHeader { #nullable disable /// - /// + /// 获得/设置 数据绑定 Value /// [Parameter] public TItem Value { get; set; } #nullable restore /// - /// + /// 获得/设置 ValueChanged 事件 /// [Parameter] public EventCallback ValueChanged { get; set; } /// - /// + /// 获得/设置 ValueExpression 表达式 /// [Parameter] public Expression>? ValueExpression { get; set; } /// - /// + /// 获得/设置 是否排序 默认 false /// - /// - protected override void BuildRenderTree(RenderTreeBuilder builder) + [Parameter] public bool Sort { get; set; } + + /// + /// 获得/设置 Table Header 实例 + /// + [CascadingParameter] + protected TableHeaderBase? Header { get; set; } + + /// + /// 组件初始化方法 + /// + protected override void OnInitialized() + { + Header?.AddHeaders(this); + } + + private FieldIdentifier? _fieldIdentifier; + /// + /// 获取绑定字段显示名称方法 + /// + public string GetDisplayName() + { + if (_fieldIdentifier == null) _fieldIdentifier = FieldIdentifier.Create(ValueExpression); + return _fieldIdentifier?.GetDisplayName() ?? ""; + } + + /// + /// 获取绑定字段信息方法 + /// + public string GetFieldName() { - var filed = FieldIdentifier.Create(ValueExpression); - var text = filed.GetDisplayName(); - builder.OpenElement(0, "th"); - builder.AddContent(1, text); - builder.CloseElement(); + if (_fieldIdentifier == null) _fieldIdentifier = FieldIdentifier.Create(ValueExpression); + return _fieldIdentifier?.FieldName ?? ""; } } } diff --git a/src/admin/Bootstrap.Admin/Components/QueryPageOptions.cs b/src/admin/Bootstrap.Admin/Components/QueryPageOptions.cs new file mode 100644 index 0000000000000000000000000000000000000000..f5c54215d47cb624455af44b0ac0e00304cfd63d --- /dev/null +++ b/src/admin/Bootstrap.Admin/Components/QueryPageOptions.cs @@ -0,0 +1,33 @@ +namespace Bootstrap.Admin.Components +{ + /// + /// 查询条件实体类 + /// + public class QueryPageOptions + { + /// + /// 获得/设置 查询关键字 + /// + public string SearchText { get; set; } = ""; + + /// + /// 获得/设置 排序字段名称 + /// + public string SortName { get; set; } = ""; + + /// + /// 获得/设置 排序方式 + /// + public SortOrder SortOrder { get; set; } + + /// + /// 获得/设置 当前页码 首页为 第一页 + /// + public int PageIndex { get; set; } = 1; + + /// + /// 获得/设置 每页条目数量 + /// + public int PageItems { get; set; } = 20; + } +} diff --git a/src/admin/Bootstrap.Admin/Components/TableBase.cs b/src/admin/Bootstrap.Admin/Components/TableBase.cs index a260574320f37ec6cb54c94782423694977e684f..cc71f394e4a1b52d4d527ddf46286e5dc50a9e95 100644 --- a/src/admin/Bootstrap.Admin/Components/TableBase.cs +++ b/src/admin/Bootstrap.Admin/Components/TableBase.cs @@ -159,7 +159,7 @@ namespace Bootstrap.Admin.Components /// 点击翻页回调方法 /// [Parameter] - public Func>? OnQuery { get; set; } + public Func>? OnQuery { get; set; } /// /// 点击翻页回调方法 @@ -194,6 +194,12 @@ namespace Bootstrap.Admin.Components [Parameter] public Func? OnSave { get; set; } + /// + /// 表头排序时回调方法 + /// + [Parameter] + public Action OnSort { get; set; } = new Action((name, order) => { }); + /// /// 删除按钮回调方法 /// @@ -253,11 +259,26 @@ namespace Bootstrap.Admin.Components [Parameter] public string SubmitModalTitle { get; set; } = ""; + /// + /// 获得/设置 当前排序字段名称 + /// + protected string SortName { get; set; } = ""; + + /// + /// 获得/设置 当前排序规则 + /// + protected SortOrder SortOrder { get; set; } + /// /// OnInitialized 方法 /// protected override void OnInitialized() { + OnSort = new Action((sortName, sortOrder) => + { + (SortName, SortOrder) = (sortName, sortOrder); + Query(); + }); if (EditModel == null && OnAdd != null) EditModel = OnAdd.Invoke(); if (OnDataSourceQuery != null) { @@ -265,7 +286,7 @@ namespace Bootstrap.Admin.Components } if (OnQuery != null) { - var queryData = OnQuery(1, DefaultPageItems, SearchText); + var queryData = OnQuery(new QueryPageOptions() { PageItems = DefaultPageItems, SearchText = SearchText, SortName = SortName, SortOrder = SortOrder }); Items = queryData.Items; TotalCount = queryData.TotalCount; } @@ -399,7 +420,7 @@ namespace Bootstrap.Admin.Components /// protected void Query() { - if (OnQuery != null) Query(OnQuery(PageIndex, PageItems, SearchText)); + if (OnQuery != null) Query(OnQuery(new QueryPageOptions() { PageIndex = PageIndex, PageItems = PageItems, SearchText = SearchText, SortOrder = SortOrder, SortName = SortName })); } /// diff --git a/src/admin/Bootstrap.Admin/Components/TableHeaderBase.cs b/src/admin/Bootstrap.Admin/Components/TableHeaderBase.cs new file mode 100644 index 0000000000000000000000000000000000000000..07abb7aefe49cc11c03e429d1b61d1d4f1fe8127 --- /dev/null +++ b/src/admin/Bootstrap.Admin/Components/TableHeaderBase.cs @@ -0,0 +1,34 @@ +using Microsoft.AspNetCore.Components; +using System; +using System.Collections.Generic; + +namespace Bootstrap.Admin.Components +{ + /// + /// Table Header 组件 + /// + public class TableHeaderBase : ComponentBase + { + /// + /// Specifies the content to be rendered inside this + /// + [Parameter] + public RenderFragment? ChildContent { get; set; } + + /// + /// 添加表头组件到集合方法 + /// + public void AddHeaders(ITableHeader header) => Headers.Add(header); + + /// + /// 获得 表头集合 + /// + public ICollection Headers { get; } = new HashSet(); + + /// + /// 点击表头排序是触发此回调函数 + /// + [Parameter] + public Action? OnSort { get; set; } + } +} diff --git a/src/admin/Bootstrap.Admin/Components/TableHeaderContent.cs b/src/admin/Bootstrap.Admin/Components/TableHeaderContent.cs new file mode 100644 index 0000000000000000000000000000000000000000..b15e0939010c8b4a1741ad8cf69d99cfb0d913eb --- /dev/null +++ b/src/admin/Bootstrap.Admin/Components/TableHeaderContent.cs @@ -0,0 +1,110 @@ +using System; +using Bootstrap.Admin.Extensions; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Rendering; + +namespace Bootstrap.Admin.Components +{ + /// + /// Table Header 表头组件 + /// + public class TableHeaderContent : ComponentBase + { + /// + /// 获得/设置 Table Header 实例 + /// + [CascadingParameter] + protected TableHeaderBase? Header { get; set; } + + /// + /// 获得/设置 升序图标 + /// + [Parameter] + public string SortIconAsc { get; set; } = "fa fa-sort-asc"; + + /// + /// 获得/设置 降序图标 + /// + [Parameter] + public string SortIconDesc { get; set; } = "fa fa-sort-desc"; + + /// + /// 获得/设置 默认图标 + /// + [Parameter] + public string SortDefault { get; set; } = "fa fa-sort"; + + private string sortName = ""; + private SortOrder sortOrder; + + /// + /// 渲染组件方法 + /// + protected override void BuildRenderTree(RenderTreeBuilder builder) + { + // 渲染正常按钮 + if (Header != null) + { + var index = 0; + foreach (var header in Header.Headers) + { + var fieldName = header.GetFieldName(); + var displayName = header.GetDisplayName(); + builder.OpenElement(index++, "th"); + + // 如果允许排序 + if (header.Sort) + { + builder.AddAttribute(index++, "onclick", new Action(() => + { + if (sortName != fieldName) sortOrder = SortOrder.Asc; + else sortOrder = sortOrder == SortOrder.Asc ? SortOrder.Desc : SortOrder.Asc; + sortName = fieldName; + + // 通知 Table 组件刷新数据 + Header.OnSort?.Invoke(sortName, sortOrder); + StateHasChanged(); + })); + builder.AddAttribute(index++, "class", "sortable"); + } + builder.OpenElement(index++, "span"); + builder.AddContent(index++, displayName); + builder.CloseElement(); + if (header.Sort) + { + builder.OpenElement(index++, "i"); + var order = sortName == fieldName ? sortOrder : SortOrder.Unset; + var icon = order switch + { + SortOrder.Asc => SortIconAsc, + SortOrder.Desc => SortIconDesc, + _ => SortDefault + }; + builder.AddAttribute(index++, "class", icon); + builder.CloseElement(); + } + builder.CloseElement(); + } + } + } + } + + /// + /// 排序顺序枚举类型 + /// + public enum SortOrder + { + /// + /// 未设置 + /// + Unset, + /// + /// 升序 0-9 A-Z + /// + Asc, + /// + /// 降序 9-0 Z-A + /// + Desc, + } +} diff --git a/src/admin/Bootstrap.Admin/Pages/Admin/Dicts.razor b/src/admin/Bootstrap.Admin/Pages/Admin/Dicts.razor index 2ec1ddad489c481b50a4686987702eaf0fdbc50d..ccd5085cd532cdfc40aaa5280c998c5561c81b52 100644 --- a/src/admin/Bootstrap.Admin/Pages/Admin/Dicts.razor +++ b/src/admin/Bootstrap.Admin/Pages/Admin/Dicts.razor @@ -14,10 +14,10 @@ - - - - + + + + @context.Category diff --git a/src/admin/Bootstrap.Admin/Pages/Admin/Groups.razor b/src/admin/Bootstrap.Admin/Pages/Admin/Groups.razor index ec9a2d74ec0efe3977bdbe6924f6b9fd722c0cbc..161e532aeaa003549d741a357be970958345ee87 100644 --- a/src/admin/Bootstrap.Admin/Pages/Admin/Groups.razor +++ b/src/admin/Bootstrap.Admin/Pages/Admin/Groups.razor @@ -10,9 +10,9 @@ - - - + + + @context.GroupCode diff --git a/src/admin/Bootstrap.Admin/Pages/Admin/Roles.razor b/src/admin/Bootstrap.Admin/Pages/Admin/Roles.razor index 63082ba29b9f9650e9085a750827b36a7977cfff..04c606c8bb8e512be34773f9a431c1a8dff33fc4 100644 --- a/src/admin/Bootstrap.Admin/Pages/Admin/Roles.razor +++ b/src/admin/Bootstrap.Admin/Pages/Admin/Roles.razor @@ -17,8 +17,8 @@ - - + + @context.RoleName diff --git a/src/admin/Bootstrap.Admin/Pages/Admin/Users.razor b/src/admin/Bootstrap.Admin/Pages/Admin/Users.razor index 436ae219344e33899cc361775c21244b85218527..9524b479480ffc347363741da3a7c3902c89cb44 100644 --- a/src/admin/Bootstrap.Admin/Pages/Admin/Users.razor +++ b/src/admin/Bootstrap.Admin/Pages/Admin/Users.razor @@ -10,12 +10,12 @@ - - - - - - + + + + + + @context.UserName diff --git a/src/admin/Bootstrap.Admin/Pages/Components/DictsBase.cs b/src/admin/Bootstrap.Admin/Pages/Components/DictsBase.cs index 1178fb36baa46dfc033cb564d33555efd8b747a8..141fa2daa1feb1df206134d88e5def72305c48b0 100644 --- a/src/admin/Bootstrap.Admin/Pages/Components/DictsBase.cs +++ b/src/admin/Bootstrap.Admin/Pages/Components/DictsBase.cs @@ -32,19 +32,28 @@ namespace Bootstrap.Pages.Admin.Components /// /// 查询方法 /// - /// 页码 - /// 每页显示数据条目数量 - /// - protected override QueryData Query(int pageIndex, int pageItems, string searchText) + /// + protected override QueryData Query(QueryPageOptions options) { var data = DataAccess.DictHelper.RetrieveDicts(); + // filter if (QueryModel.Define != -1) data = data.Where(d => d.Define == QueryModel.Define); if (!string.IsNullOrEmpty(QueryModel.Name)) data = data.Where(d => d.Name.Contains(QueryModel.Name, StringComparison.OrdinalIgnoreCase)); if (!string.IsNullOrEmpty(QueryModel.Category)) data = data.Where(d => d.Category.Contains(QueryModel.Category, StringComparison.OrdinalIgnoreCase)); - if (!string.IsNullOrEmpty(searchText)) data = data.Where(d => d.Category.Contains(searchText, StringComparison.OrdinalIgnoreCase) || d.Name.Contains(searchText, StringComparison.OrdinalIgnoreCase) || d.Code.Contains(searchText, StringComparison.OrdinalIgnoreCase)); + if (!string.IsNullOrEmpty(options.SearchText)) data = data.Where(d => d.Category.Contains(options.SearchText, StringComparison.OrdinalIgnoreCase) || d.Name.Contains(options.SearchText, StringComparison.OrdinalIgnoreCase) || d.Code.Contains(options.SearchText, StringComparison.OrdinalIgnoreCase)); + + // sort + data = options.SortName switch + { + nameof(BootstrapDict.Category) => options.SortOrder == SortOrder.Asc ? data.OrderBy(d => d.Category) : data.OrderByDescending(d => d.Category), + nameof(BootstrapDict.Name) => options.SortOrder == SortOrder.Asc ? data.OrderBy(d => d.Name) : data.OrderByDescending(d => d.Name), + nameof(BootstrapDict.Code) => options.SortOrder == SortOrder.Asc ? data.OrderBy(d => d.Code) : data.OrderByDescending(d => d.Code), + nameof(BootstrapDict.Define) => options.SortOrder == SortOrder.Asc ? data.OrderBy(d => d.Define) : data.OrderByDescending(d => d.Define), + _ => data + }; var totalCount = data.Count(); - var items = data.Skip((pageIndex - 1) * pageItems).Take(pageItems); - return new QueryData() { Items = items, TotalCount = totalCount, PageIndex = pageIndex, PageItems = pageItems }; + var items = data.Skip((options.PageIndex - 1) * options.PageItems).Take(options.PageItems); + return new QueryData() { Items = items, TotalCount = totalCount, PageIndex = options.PageIndex, PageItems = options.PageItems }; } /// diff --git a/src/admin/Bootstrap.Admin/Pages/Components/GroupsBase.cs b/src/admin/Bootstrap.Admin/Pages/Components/GroupsBase.cs index 6379c3af9cde771c040b2c16a9eb7fb030c55c0e..56d3d1b26edec7677ce8d174d3ee5d9df5c3fe4a 100644 --- a/src/admin/Bootstrap.Admin/Pages/Components/GroupsBase.cs +++ b/src/admin/Bootstrap.Admin/Pages/Components/GroupsBase.cs @@ -14,18 +14,26 @@ namespace Bootstrap.Pages.Admin.Components /// /// 查询方法 /// - /// 页码 - /// 每页显示数据条目数量 - /// - protected override QueryData Query(int pageIndex, int pageItems, string searchText) + /// + protected override QueryData Query(QueryPageOptions options) { var data = GroupHelper.Retrieves(); if (!string.IsNullOrEmpty(QueryModel.GroupName)) data = data.Where(d => d.GroupName.Contains(QueryModel.GroupName, StringComparison.OrdinalIgnoreCase)); if (!string.IsNullOrEmpty(QueryModel.Description)) data = data.Where(d => d.Description != null && d.Description.Contains(QueryModel.Description, StringComparison.OrdinalIgnoreCase)); - if (!string.IsNullOrEmpty(searchText)) data = data.Where(d => d.GroupName.Contains(searchText, StringComparison.OrdinalIgnoreCase) || (d.Description ?? "").Contains(searchText, StringComparison.OrdinalIgnoreCase)); + if (!string.IsNullOrEmpty(options.SearchText)) data = data.Where(d => d.GroupName.Contains(options.SearchText, StringComparison.OrdinalIgnoreCase) || (d.Description ?? "").Contains(options.SearchText, StringComparison.OrdinalIgnoreCase)); + + // sort + data = options.SortName switch + { + nameof(Group.GroupName) => options.SortOrder == SortOrder.Asc ? data.OrderBy(d => d.GroupName) : data.OrderByDescending(d => d.GroupName), + nameof(Group.GroupCode) => options.SortOrder == SortOrder.Asc ? data.OrderBy(d => d.GroupCode) : data.OrderByDescending(d => d.GroupCode), + nameof(Group.Description) => options.SortOrder == SortOrder.Asc ? data.OrderBy(d => d.Description) : data.OrderByDescending(d => d.Description), + _ => data + }; + var totalCount = data.Count(); - var items = data.Skip((pageIndex - 1) * pageItems).Take(pageItems); - return new QueryData() { Items = items, TotalCount = totalCount, PageIndex = pageIndex, PageItems = pageItems }; + var items = data.Skip((options.PageIndex - 1) * options.PageItems).Take(options.PageItems); + return new QueryData() { Items = items, TotalCount = totalCount, PageIndex = options.PageIndex, PageItems = options.PageItems }; } /// diff --git a/src/admin/Bootstrap.Admin/Pages/Components/MenusBase.cs b/src/admin/Bootstrap.Admin/Pages/Components/MenusBase.cs index 37cd2ff411d728dd910443474e9ad40232f66e45..a6db0fc0862a33d254bcc5f7b9277d04e2cf6743 100644 --- a/src/admin/Bootstrap.Admin/Pages/Components/MenusBase.cs +++ b/src/admin/Bootstrap.Admin/Pages/Components/MenusBase.cs @@ -113,10 +113,8 @@ namespace Bootstrap.Pages.Admin.Components /// /// 查询方法 /// - /// 页码 - /// 每页显示数据条目数量 - /// - protected override QueryData Query(int pageIndex, int pageItems, string searchText) + /// + protected override QueryData Query(QueryPageOptions options) { var data = MenuHelper.RetrieveMenusByUserName(UserName); if (!string.IsNullOrEmpty(QueryModel.Name)) data = data.Where(d => d.Name.Contains(QueryModel.Name, StringComparison.OrdinalIgnoreCase)); @@ -124,10 +122,10 @@ namespace Bootstrap.Pages.Admin.Components 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)); - if (!string.IsNullOrEmpty(searchText)) data = data.Where(d => d.Name.Contains(searchText, StringComparison.OrdinalIgnoreCase) || d.ParentName.Contains(searchText, StringComparison.OrdinalIgnoreCase) || d.Category.Contains(searchText, StringComparison.OrdinalIgnoreCase) || d.Application.Contains(searchText, StringComparison.OrdinalIgnoreCase)); + if (!string.IsNullOrEmpty(options.SearchText)) data = data.Where(d => d.Name.Contains(options.SearchText, StringComparison.OrdinalIgnoreCase) || d.ParentName.Contains(options.SearchText, StringComparison.OrdinalIgnoreCase) || d.Category.Contains(options.SearchText, StringComparison.OrdinalIgnoreCase) || d.Application.Contains(options.SearchText, 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 }; + var items = data.Skip((options.PageIndex - 1) * options.PageItems).Take(options.PageItems); + return new QueryData() { Items = items, TotalCount = totalCount, PageIndex = options.PageIndex, PageItems = options.PageItems }; } /// @@ -155,7 +153,7 @@ namespace Bootstrap.Pages.Admin.Components /// 删除方法 /// protected override bool Delete(IEnumerable items) => MenuHelper.Delete(items.Select(item => item.Id ?? "")); - + /// /// 重置搜索方法 /// diff --git a/src/admin/Bootstrap.Admin/Pages/Components/QueryPageBase.cs b/src/admin/Bootstrap.Admin/Pages/Components/QueryPageBase.cs index 6981f52cac005a02df921b42e90b59152ce4989f..6b8bd9c55d6c5ce5db8fc4113ef2d02c183ecaeb 100644 --- a/src/admin/Bootstrap.Admin/Pages/Components/QueryPageBase.cs +++ b/src/admin/Bootstrap.Admin/Pages/Components/QueryPageBase.cs @@ -24,10 +24,8 @@ namespace Bootstrap.Pages.Admin.Components /// /// 查询方法 /// - /// 页码 - /// 每页显示数据条目数量 - /// - protected abstract QueryData Query(int pageIndex, int pageItems, string searchText); + /// + protected abstract QueryData Query(QueryPageOptions options); /// /// OnParametersSet 方法 @@ -46,11 +44,13 @@ namespace Bootstrap.Pages.Admin.Components /// /// 保存方法 /// - protected abstract bool Save(TItem dict); + /// + protected abstract bool Save(TItem item); /// /// 删除方法 /// + /// protected abstract bool Delete(IEnumerable items); } } diff --git a/src/admin/Bootstrap.Admin/Pages/Components/RolesBase.cs b/src/admin/Bootstrap.Admin/Pages/Components/RolesBase.cs index c26ebb1625dcf3c3c61895a394c991faf71bf1cf..f59a0af506fae29af81628fd0e60b4aa88f6c9b1 100644 --- a/src/admin/Bootstrap.Admin/Pages/Components/RolesBase.cs +++ b/src/admin/Bootstrap.Admin/Pages/Components/RolesBase.cs @@ -14,18 +14,25 @@ namespace Bootstrap.Pages.Admin.Components /// /// 查询方法 /// - /// 页码 - /// 每页显示数据条目数量 - /// - protected override QueryData Query(int pageIndex, int pageItems, string searchText) + /// + protected override QueryData Query(QueryPageOptions options) { var data = RoleHelper.Retrieves(); if (!string.IsNullOrEmpty(QueryModel.RoleName)) data = data.Where(d => d.RoleName.Contains(QueryModel.RoleName, StringComparison.OrdinalIgnoreCase)); if (!string.IsNullOrEmpty(QueryModel.Description)) data = data.Where(d => d.Description != null && d.Description.Contains(QueryModel.Description, StringComparison.OrdinalIgnoreCase)); - if (!string.IsNullOrEmpty(searchText)) data = data.Where(d => d.RoleName.Contains(searchText, StringComparison.OrdinalIgnoreCase) || d.Description.Contains(searchText, StringComparison.OrdinalIgnoreCase)); + if (!string.IsNullOrEmpty(options.SearchText)) data = data.Where(d => d.RoleName.Contains(options.SearchText, StringComparison.OrdinalIgnoreCase) || d.Description.Contains(options.SearchText, StringComparison.OrdinalIgnoreCase)); + + // sort + data = options.SortName switch + { + nameof(Role.RoleName) => options.SortOrder == SortOrder.Asc ? data.OrderBy(d => d.RoleName) : data.OrderByDescending(d => d.RoleName), + nameof(Role.Description) => options.SortOrder == SortOrder.Asc ? data.OrderBy(d => d.Description) : data.OrderByDescending(d => d.Description), + _ => data + }; + var totalCount = data.Count(); - var items = data.Skip((pageIndex - 1) * pageItems).Take(pageItems); - return new QueryData() { Items = items, TotalCount = totalCount, PageIndex = pageIndex, PageItems = pageItems }; + var items = data.Skip((options.PageIndex - 1) * options.PageItems).Take(options.PageItems); + return new QueryData() { Items = items, TotalCount = totalCount, PageIndex = options.PageIndex, PageItems = options.PageItems }; } /// @@ -37,7 +44,7 @@ namespace Bootstrap.Pages.Admin.Components /// 删除方法 /// protected override bool Delete(IEnumerable items) => RoleHelper.Delete(items.Select(item => item.Id ?? "")); - + /// /// 重置搜索方法 /// @@ -78,6 +85,5 @@ namespace Bootstrap.Pages.Admin.Components { } - } } diff --git a/src/admin/Bootstrap.Admin/Pages/Components/UsersBase.cs b/src/admin/Bootstrap.Admin/Pages/Components/UsersBase.cs index 880ccee77d2becc4f4f57ca83519ca2916e2a1a9..6ac4d352bdef5cceccec5a0653cb7801c425d6ef 100644 --- a/src/admin/Bootstrap.Admin/Pages/Components/UsersBase.cs +++ b/src/admin/Bootstrap.Admin/Pages/Components/UsersBase.cs @@ -14,18 +14,29 @@ namespace Bootstrap.Pages.Admin.Components /// /// 查询方法 /// - /// 页码 - /// 每页显示数据条目数量 - /// - protected override QueryData Query(int pageIndex, int pageItems, string searchText) + /// + protected override QueryData Query(QueryPageOptions options) { var data = UserHelper.Retrieves(); if (!string.IsNullOrEmpty(QueryModel.UserName)) data = data.Where(d => d.UserName.Contains(QueryModel.UserName, StringComparison.OrdinalIgnoreCase)); if (!string.IsNullOrEmpty(QueryModel.DisplayName)) data = data.Where(d => d.DisplayName.Contains(QueryModel.DisplayName, StringComparison.OrdinalIgnoreCase)); - if (!string.IsNullOrEmpty(searchText)) data = data.Where(d => d.UserName.Contains(searchText, StringComparison.OrdinalIgnoreCase) || d.DisplayName.Contains(searchText, StringComparison.OrdinalIgnoreCase)); + if (!string.IsNullOrEmpty(options.SearchText)) data = data.Where(d => d.UserName.Contains(options.SearchText, StringComparison.OrdinalIgnoreCase) || d.DisplayName.Contains(options.SearchText, StringComparison.OrdinalIgnoreCase)); + + // sort + data = options.SortName switch + { + nameof(User.UserName) => options.SortOrder == SortOrder.Asc ? data.OrderBy(d => d.UserName) : data.OrderByDescending(d => d.UserName), + nameof(User.DisplayName) => options.SortOrder == SortOrder.Asc ? data.OrderBy(d => d.DisplayName) : data.OrderByDescending(d => d.DisplayName), + nameof(User.Description) => options.SortOrder == SortOrder.Asc ? data.OrderBy(d => d.Description) : data.OrderByDescending(d => d.Description), + nameof(User.ApprovedBy) => options.SortOrder == SortOrder.Asc ? data.OrderBy(d => d.ApprovedBy) : data.OrderByDescending(d => d.ApprovedBy), + nameof(User.ApprovedTime) => options.SortOrder == SortOrder.Asc ? data.OrderBy(d => d.ApprovedTime) : data.OrderByDescending(d => d.ApprovedTime), + nameof(User.RegisterTime) => options.SortOrder == SortOrder.Asc ? data.OrderBy(d => d.RegisterTime) : data.OrderByDescending(d => d.RegisterTime), + _ => data + }; + var totalCount = data.Count(); - var items = data.Skip((pageIndex - 1) * pageItems).Take(pageItems); - return new QueryData() { Items = items, TotalCount = totalCount, PageIndex = pageIndex, PageItems = pageItems }; + var items = data.Skip((options.PageIndex - 1) * options.PageItems).Take(options.PageItems); + return new QueryData() { Items = items, TotalCount = totalCount, PageIndex = options.PageIndex, PageItems = options.PageItems }; } /// @@ -37,7 +48,7 @@ namespace Bootstrap.Pages.Admin.Components /// 删除方法 /// protected override bool Delete(IEnumerable users) => UserHelper.Delete(users.Select(item => item.Id ?? "")); - + /// /// 重置搜索方法 /// diff --git a/src/admin/Bootstrap.Admin/Shared/Table.razor b/src/admin/Bootstrap.Admin/Shared/Table.razor index becb2f0314082451611bfa14d334ec7f687e548b..c07fd005400f0f5f80b079439f8a1cedb4cf76d2 100644 --- a/src/admin/Bootstrap.Admin/Shared/Table.razor +++ b/src/admin/Bootstrap.Admin/Shared/Table.razor @@ -61,7 +61,10 @@ { 行号 } - @TableHeader?.Invoke(EditModel) + + + @TableHeader?.Invoke(EditModel) + @if (ShowExtendButtons) { @ButtonTemplateHeaderText @@ -82,7 +85,10 @@ { 行号 } - @TableHeader?.Invoke(EditModel) + + + @TableHeader?.Invoke(EditModel) + @if (ShowExtendButtons) { @ButtonTemplateHeaderText diff --git a/src/admin/Bootstrap.Admin/Shared/TableHeader.razor b/src/admin/Bootstrap.Admin/Shared/TableHeader.razor new file mode 100644 index 0000000000000000000000000000000000000000..62297ea9fee3243836c5ecc4a309be425a2305de --- /dev/null +++ b/src/admin/Bootstrap.Admin/Shared/TableHeader.razor @@ -0,0 +1,5 @@ +@inherits TableHeaderBase + + + @ChildContent + diff --git a/src/admin/Bootstrap.Admin/wwwroot/css/blazor.css b/src/admin/Bootstrap.Admin/wwwroot/css/blazor.css index b01f4f602b91a6f6bb6a58534df1a1df6352eb91..5f29c59b7b3efdcdbcbe31b569e0685ee579e4a8 100644 --- a/src/admin/Bootstrap.Admin/wwwroot/css/blazor.css +++ b/src/admin/Bootstrap.Admin/wwwroot/css/blazor.css @@ -163,6 +163,24 @@ nav .dropdown .nav-link-close.dropdown-toggle:after { border-bottom: 1px solid #dee2e6; } +.bootstrap-table .sortable { + padding-right: 30px; + cursor: pointer; +} + + .bootstrap-table .sortable span { + display: inline-block; + width: 100%; + } + + .bootstrap-table .sortable i { + margin-left: 8px; + } + + .bootstrap-table .sortable .fa-sort { + color: #dee2e6; + } + .table-wrapper { border-radius: 4px; margin-bottom: 1rem;