Files
Atomx/Atomx.Admin/Atomx.Admin.Client/Pages/Systems/MenuList.razor
2025-12-02 13:10:10 +08:00

350 lines
11 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
@page "/system/menu/list"
@inject ILogger<MenuList> Logger
@using MenuItem = Atomx.Admin.Client.Models.MenuItem
@using Menu = Atomx.Common.Entities.Menu
@* @attribute [Authorize] *@
<PageTitle>菜单管理</PageTitle>
<Title Level="4">菜单管理</Title>
<Card>
<Form @ref="searchForm" Model="search" Layout="FormLayout.Inline" Class="search-form" OnFinish="OnSearchFinish">
<Row Justify="RowJustify.Start" Gutter="16">
<Col>
<FormItem Label="名称">
<Input @bind-Value="search.Name" Placeholder="名称" AllowClear />
</FormItem>
</Col>
<Col>
<div class="ant-form-item" style="width:200px;display:flex;">
<Button Type="ButtonType.Primary" HtmlType="submit">查询</Button>
<Button Style="margin: 0 8px;" OnClick="OnSearchReset">重置</Button>
</div>
</Col>
</Row>
</Form>
</Card>
<Card Class="mt-3">
<Table DataSource="Menus" PageSize="100" HidePagination="true" Resizable>
<TitleTemplate>
<Flex Justify="FlexJustify.SpaceBetween">
菜单列表
<div>
<Button Class="me-3" OnClick="OnCreateClick" Type="ButtonType.Primary">新增</Button>
</div>
</Flex>
</TitleTemplate>
<ColumnDefinitions>
<PropertyColumn Property="c=>c.Name" Title="名称">
<AntDesign.Text>@GetName(context)</AntDesign.Text>
</PropertyColumn>
<PropertyColumn Property="c=>c.Icon" Title="图标" Width="60px" Align="ColumnAlign.Center">
@if (!string.IsNullOrEmpty(context.Icon)) {
<Icon Type="@context.Icon" Theme="IconThemeType.Outline" Width="1.3em" Height="1.3em" />
}
</PropertyColumn>
<PropertyColumn Property="c=>c.Key" Title="分组标识" Ellipsis/>
<PropertyColumn Property="c=>c.Url" Title="链接" />
<PropertyColumn Property="c=>c.DisplayOrder" Title="排序" Width="80px" Align="ColumnAlign.Center" />
<PropertyColumn Property="c=>c.Enabled" Title="状态" Width="80px" Align="ColumnAlign.Center">
@if (context.Enabled)
{
<AntDesign.Text Type="TextElementType.Success"><Icon Type="check" Theme=" IconThemeType.Outline" Width="1.3em" Height="1.3em" /></AntDesign.Text>
}
else
{
<Icon Type="close" Theme="IconThemeType.Outline" Width="1.3em" Height="1.3em" />
}
</PropertyColumn>
<PropertyColumn Property="c=>c.CreateTime" Title="时间" Width="150px" />
<ActionColumn Title="操作" Align="ColumnAlign.Right" Width="120px">
<Space>
<SpaceItem>
<a @onclick="(e)=>OnEditClick(context)">编辑</a>
</SpaceItem>
<SpaceItem>
<Popconfirm Placement="@Placement.Left" Title="@("删除这条数据无法恢复,您确定要删除吗?")"
OnConfirm="@(e=>HandleDeleteConfirmAsync(e,context.Id))"
OkText="确定"
CancelText="取消">
<a>删除</a>
</Popconfirm>
</SpaceItem>
</Space>
</ActionColumn>
</ColumnDefinitions>
</Table>
</Card>
<Drawer Closable="true" Width="520" Visible="drawerVisible" Title='("设置菜单")' OnClose="_=>CloseDrawer()">
<Form LabelColSpan="4" @ref="@editform" Model="@menu" Class="px-5" OnFinish="OnFormFinish">
<FluentValidationValidator />
<FormItem Label="名称">
<Input @bind-Value="menu.Name" For="(()=>menu.Name)" />
</FormItem>
<FormItem Label="分组标识">
<Input @bind-Value="menu.Key" For="(()=>menu.Key)" />
</FormItem>
<FormItem Label="链接">
<Input @bind-Value="menu.Url" For="(()=>menu.Url)" />
</FormItem>
<FormItem Label="上级分类">
<Select @bind-Value="@menu.ParentId" TItemValue="long" TItem="string" Placeholder="请选择上级分类">
<SelectOptions>
<SelectOption Value="0L" Label="无" />
@foreach(var item in Menus)
{
<SelectOption Value="@item.Id" Label="@GetName(item)" />
}
</SelectOptions>
</Select>
</FormItem>
@if (menu.ParentId == 0)
{
<FormItem Label="图标">
<Select ItemValue="c=>c"
ItemLabel="c=>c"
DataSource="IconsExtension.IconList()"
@bind-Value="@menu.Icon">
<ItemTemplate Context="Icon">
<p class="mt-2"><Icon Type="@Icon" /> @Icon</p>
</ItemTemplate>
<LabelTemplate Context="Icon">
<p class="mt-1"><Icon Type="@Icon" /> @Icon</p>
</LabelTemplate>
</Select>
</FormItem>
}
<FormItem Label="显示排序">
<Input @bind-Value="menu.DisplayOrder" For="(()=>menu.DisplayOrder)" />
</FormItem>
<FormItem Label="状态">
<Checkbox T="bool" Label="启用" @bind-value="menu.Enabled" Size="InputSize.Small" Class="ps-0" />
</FormItem>
<FormItem WrapperColOffset="4">
<Button Type="ButtonType.Primary" HtmlType="submit" Class="mt-5" Style="width: 100%;">保存</Button>
</FormItem>
</Form >
</Drawer>
@code {
[SupplyParameterFromQuery]
int? Page { get; set; }
[SupplyParameterFromForm]
MenuSearch search { get; set; } = new();
Form<MenuSearch> searchForm = null!;
[SupplyParameterFromForm]
MenuModel menu { get; set; } = new();
Form<MenuModel> editform = null!;
List<MenuItem> Menus = new();
private bool drawerVisible;
protected override void OnInitialized()
{
base.OnInitialized();
}
protected override void OnParametersSet()
{
loadQueryString();
LoadList();
base.OnParametersSet();
}
void loadQueryString()
{
var uri = new Uri(Navigation.Uri);
var query = uri.Query;
search.Name = query.GetQueryString("Name");
}
private async void LoadList()
{
var url = "/api/menu/list";
var apiResult = await HttpService.Get<ApiResult<List<MenuItem>>>(url);
if (apiResult.Success)
{
if (apiResult.Data != null)
{
Menus = apiResult.Data;
StateHasChanged();
}
}
}
void OnSearchFinish()
{
Page = Page.GetValueOrDefault(1) - 1;
OnSearch(Page.Value);
}
void OnSearchReset()
{
search = new();
searchForm?.Reset();
OnSearchFinish();
}
private void OnReset()
{
search = new();
LoadList();
}
private void OnSearch(int page)
{
var queryString = search.BuildQueryString();
if (string.IsNullOrEmpty(queryString))
{
if (page > 1)
{
Navigation.NavigateTo($"/system/menu/list?page={page}");
}
else
{
Navigation.NavigateTo($"/system/menu/list");
}
}
else
{
if (page > 1)
{
Navigation.NavigateTo($"/system/menu/list?page={page}&{queryString}");
}
else
{
Navigation.NavigateTo($"/system/menu/list?{queryString}");
}
}
LoadList();
}
async Task HandleDeleteConfirmAsync(MouseEventArgs e, long id)
{
var url = $"/api/menu/delete/{id}";
var apiResult = await HttpService.Post<ApiResult<string>>(url, new());
if (apiResult.Success)
{
LoadList();
ModalService.Info(new ConfirmOptions() { Title = "操作提示", Content = "删除数据成功" });
}
else
{
ModalService.Error(new ConfirmOptions() { Title = "操作提示", Content = $"数据删除失败.{apiResult.Message}" });
}
}
void OnCreateClick()
{
menu = new();
drawerVisible = true;
}
void OnEditClick(Common.Entities.Menu model)
{
menu = model.Adapt<MenuModel>();
drawerVisible = true;
}
async Task OnFormFinish()
{
if (editform.Validate())
{
var result = new ApiResult<string>();
var data = menu.Adapt<Menu>();
if (menu.Id > 0)
{
var url = $"api/menu/edit";
result = await HttpService.Post<ApiResult<string>>(url, data);
}
else
{
var url = $"api/menu/add";
result = await HttpService.Post<ApiResult<string>>(url, data);
}
if (result.Code == (int)ResultCode.Success)
{
CloseDrawer();
LoadList();
await ModalService.InfoAsync(new ConfirmOptions() { Title="提示", Content="数据提交成功!" });
}
else
{
await ModalService.ErrorAsync(new ConfirmOptions() { Title = "服务异常", Content = result.Message });
}
}
}
private string GetPath(string path)
{
var array = path.Split(",").ToList();
var pathText = string.Empty;
foreach (var item in array)
{
var name = Menus.Where(p => p.Id == item.ToLong()).Select(p => p.Name).SingleOrDefault();
if (string.IsNullOrEmpty(pathText))
{
pathText = name;
}
else
{
pathText = $"{pathText}>{name}";
}
}
return pathText ?? string.Empty;
}
private string GetName(MenuItem menu)
{
string name = string.Empty;
if (menu.Depth > 0)
{
var symbol = " ";
for (var i = 0; i < menu.Depth; i++)
{
symbol = $"{symbol}├ ";
}
name = $"{symbol}{menu.Name}";
}
else
{
name = menu.Name;
}
return name;
}
private void OpenDrawer()
{
drawerVisible = true;
}
private void CloseDrawer()
{
menu = new();
drawerVisible = false;
}
}