feat: 完善菜单维护父级菜单功能
This commit is contained in:
parent
1f2a169cc7
commit
32d74ea81a
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BootstrapBlazor" Version="6.2.9-beta07" />
|
||||
<PackageReference Include="BootstrapBlazor" Version="6.3.4-beta03" />
|
||||
<PackageReference Include="Longbow.Security.Cryptography" Version="5.2.0" />
|
||||
<PackageReference Include="Microsoft.Data.Sqlite" Version="6.0.1" />
|
||||
<PackageReference Include="PetaPoco.Extensions" Version="6.0.0" />
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
<div class="row g-3 form-inline">
|
||||
<div class="col-12 col-sm-6 col-md-6">
|
||||
<BootstrapInput @bind-Value="Value.Name" DisplayText="菜单名称" ShowLabel="true"></BootstrapInput>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-6">
|
||||
<MenuTree @bind-Value="Value.ParentId" Lookup="@ParementMenus" DisplayText="父级菜单"></MenuTree>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-6">
|
||||
<BootstrapInput @bind-Value="Value.Order"></BootstrapInput>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-6">
|
||||
<BootstrapInput @bind-Value="Value.Icon"></BootstrapInput>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<BootstrapInput @bind-Value="Value.Url"></BootstrapInput>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-6">
|
||||
<Select @bind-Value="Value.Category"></Select>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-6">
|
||||
<Select Items="@Targets" @bind-Value="Value.Target"></Select>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-6">
|
||||
<Select @bind-Value="Value.IsResource"></Select>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-6">
|
||||
<Select Items="@Apps" @bind-Value="Value.Application"></Select>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,42 @@
|
|||
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
|
||||
// Licensed under the LGPL License, Version 3.0. See License.txt in the project root for license information.
|
||||
// Website: https://admin.blazor.zone
|
||||
|
||||
using BootstrapAdmin.DataAccess.Models;
|
||||
|
||||
namespace BootstrapAdmin.Web.Components;
|
||||
|
||||
public partial class MenuEditor
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
[EditorRequired]
|
||||
[NotNull]
|
||||
public Navigation? Value { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
[EditorRequired]
|
||||
[NotNull]
|
||||
public List<SelectedItem>? ParementMenus { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
[EditorRequired]
|
||||
[NotNull]
|
||||
public List<SelectedItem>? Targets { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
[EditorRequired]
|
||||
[NotNull]
|
||||
public List<SelectedItem>? Apps { get; set; }
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
<div class="tree-dialog">
|
||||
<label class="form-label">@DisplayText</label>
|
||||
<BootstrapInputGroup>
|
||||
<Display Value="Value" Lookup="Lookup" ShowLabel="false"></Display>
|
||||
<Button Icon="fa fa-times" Color="Color.Secondary" OnClick="OnClearText"></Button>
|
||||
<Button Icon="fa fa-bars" OnClick="OnSelectMenu"></Button>
|
||||
</BootstrapInputGroup>
|
||||
</div>
|
|
@ -0,0 +1,87 @@
|
|||
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
|
||||
// Licensed under the LGPL License, Version 3.0. See License.txt in the project root for license information.
|
||||
// Website: https://admin.blazor.zone
|
||||
|
||||
using BootstrapAdmin.Web.Core;
|
||||
using BootstrapAdmin.Web.Services;
|
||||
using Microsoft.AspNetCore.Components.Web;
|
||||
|
||||
namespace BootstrapAdmin.Web.Components;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public partial class MenuTree
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
[NotNull]
|
||||
public List<SelectedItem>? Lookup { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
[NotNull]
|
||||
public string? DisplayText { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
[NotNull]
|
||||
public string? Value { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
[NotNull]
|
||||
public EventCallback<string> ValueChanged { get; set; }
|
||||
|
||||
[Inject]
|
||||
[NotNull]
|
||||
private DialogService? DialogService { get; set; }
|
||||
|
||||
private DialogOption? Option { get; set; }
|
||||
|
||||
private async Task OnSelectMenu()
|
||||
{
|
||||
Option = new DialogOption()
|
||||
{
|
||||
IsScrolling = true,
|
||||
Title = "选择菜单",
|
||||
BodyTemplate = BootstrapDynamicComponent.CreateComponent<ParentMenuTree>(new Dictionary<string, object?>
|
||||
{
|
||||
[nameof(ParentMenuTree.Value)] = Value,
|
||||
[nameof(ParentMenuTree.ValueChanged)] = EventCallback.Factory.Create<string>(this, v => OnValueChanged(v))
|
||||
}).Render(),
|
||||
FooterTemplate = BootstrapDynamicComponent.CreateComponent<Button>(new Dictionary<string, object?>
|
||||
{
|
||||
[nameof(Button.Color)] = Color.Primary,
|
||||
[nameof(Button.Text)] = "确认",
|
||||
[nameof(Button.OnClick)] = EventCallback.Factory.Create<MouseEventArgs>(this, () =>
|
||||
{
|
||||
Option?.Dialog.Close();
|
||||
}),
|
||||
}).Render()
|
||||
};
|
||||
await DialogService.Show(Option);
|
||||
}
|
||||
|
||||
private Task OnClearText() => OnValueChanged("0");
|
||||
|
||||
private async Task OnValueChanged(string v)
|
||||
{
|
||||
if (Value != v)
|
||||
{
|
||||
Value = v;
|
||||
if (ValueChanged.HasDelegate)
|
||||
{
|
||||
await ValueChanged.InvokeAsync(Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
.tree-dialog {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.tree-dialog ::deep .input-group {
|
||||
flex-wrap: nowrap !important
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
<Tree Items="InternalItems" ShowRadio="true" ShowIcon="true" OnTreeItemChecked="@OnTreeItemChecked" />
|
||||
|
||||
@code {
|
||||
RenderFragment<Navigation> RenderTreeItem => item =>
|
||||
@<div class="d-flex flex-fill"><span class="flex-fill">@item.Name</span><span class="mx-3">@item.Order</span><span class="app-type">@item.IsResource.ToDescriptionString()</span><span class="app-text">@GetApp(item.Application)</span></div>;
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
|
||||
// Licensed under the LGPL License, Version 3.0. See License.txt in the project root for license information.
|
||||
// Website: https://admin.blazor.zone
|
||||
|
||||
using BootstrapAdmin.Web.Core;
|
||||
using BootstrapAdmin.Web.Extensions;
|
||||
using BootstrapAdmin.Web.Services;
|
||||
|
||||
namespace BootstrapAdmin.Web.Components;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public partial class ParentMenuTree
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
[EditorRequired]
|
||||
[NotNull]
|
||||
public string? Value { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public EventCallback<string> ValueChanged { get; set; }
|
||||
|
||||
[NotNull]
|
||||
private List<TreeItem>? InternalItems { get; set; }
|
||||
|
||||
[Inject]
|
||||
[NotNull]
|
||||
private INavigation? NavigationService { get; set; }
|
||||
|
||||
[Inject]
|
||||
[NotNull]
|
||||
private IDict? DictService { get; set; }
|
||||
|
||||
[Inject]
|
||||
[NotNull]
|
||||
private BootstrapAppContext? Context { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
base.OnInitialized();
|
||||
|
||||
var items = NavigationService.GetAllMenus(Context.UserName);
|
||||
InternalItems = items.ToTreeItemList(new List<string> { Value }, RenderTreeItem);
|
||||
}
|
||||
|
||||
private async Task OnTreeItemChecked(List<TreeItem> items)
|
||||
{
|
||||
Value = items.First().Key?.ToString();
|
||||
if (ValueChanged.HasDelegate)
|
||||
{
|
||||
await ValueChanged.InvokeAsync(Value);
|
||||
}
|
||||
}
|
||||
|
||||
private string GetApp(string? app) => DictService.GetApps().FirstOrDefault(i => i.Key == app).Value ?? "未设置";
|
||||
}
|
|
@ -23,35 +23,7 @@
|
|||
<TableColumn @bind-Field="@context.Application" Filterable="true" Lookup="Apps"></TableColumn>
|
||||
</TableColumns>
|
||||
<EditTemplate Context="v">
|
||||
<div class="row g-3 form-inline">
|
||||
<div class="col-12 col-sm-6 col-md-6">
|
||||
<BootstrapInput @bind-Value="v.Name" DisplayText="菜单名称" ShowLabel="true"></BootstrapInput>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-6">
|
||||
<Select @bind-Value="v.ParentId" Items="@ParementMenus" IsDisabled="@(v.ParentId == "0")" DisplayText="父级菜单" ShowLabel="true"></Select>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-6">
|
||||
<BootstrapInput @bind-Value="v.Order"></BootstrapInput>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-6">
|
||||
<BootstrapInput @bind-Value="v.Icon"></BootstrapInput>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<BootstrapInput @bind-Value="v.Url"></BootstrapInput>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-6">
|
||||
<Select @bind-Value="v.Category"></Select>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-6">
|
||||
<Select Items="@Targets" @bind-Value="v.Target"></Select>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-6">
|
||||
<Select @bind-Value="v.IsResource"></Select>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-6">
|
||||
<Select Items="@Apps" @bind-Value="v.Application"></Select>
|
||||
</div>
|
||||
</div>
|
||||
<MenuEditor Value="v" ParementMenus="ParementMenus" Targets="Targets" Apps="Apps" />
|
||||
</EditTemplate>
|
||||
<RowButtonTemplate>
|
||||
<TableCellButton Size="Size.ExtraSmall" IsShow="@AuthorizeButton("assignRole")" Color="Color.Info" Icon="fa fa-sitemap" Text="分配角色" OnClick="() => OnAssignmentRoles(context)" />
|
||||
|
|
|
@ -44,5 +44,5 @@ class AdminTaskService : BackgroundService
|
|||
|
||||
// 真实任务负责周期性设置健康检查结果开关为开启
|
||||
TaskServicesManager.GetOrAdd("健康检查", token => Task.FromResult(DictService.SaveHealthCheck()), TriggerBuilder.Build(Cron.Minutely(10)));
|
||||
});
|
||||
}, stoppingToken);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue