Files
Atomx/Atomx.Admin/Atomx.Admin.Client/Layout/MainLayout.razor

181 lines
5.7 KiB
Plaintext

@inherits LayoutComponentBase
@inject ILogger<MainLayout> _logger
@inject Atomx.Admin.Client.Services.ILocalizationProvider LocalizationProvider
@inject NavigationManager Navigation
<ErrorBoundary>
<ChildContent>
<AntDesign.ProLayout.BasicLayout MenuData="MenuDatas" Title="Atomx" MenuAccordion @bind-Collapsed="_open">
<HeaderContentRender>
<Space Size="@("24")">
<SpaceItem>
<Icon Class="action" Type="@(_open ? "menu-unfold" : "menu-fold")" OnClick="ToggleDrawer" />
</SpaceItem>
</Space>
</HeaderContentRender>
<RightContentRender>
<Space Size="@("24")">
@* <SpaceItem>
<HeaderSearch Class="action search"
Placeholder="Site Search"
DefaultValue="umi ui"
Options="DefaultOptions" />
</SpaceItem> *@
<SpaceItem>
<Text Type="TextElementType.Warning">@handler</Text>
</SpaceItem>
<SpaceItem>
<AntDesign.Tooltip Title="@("Help")" Placement="@Placement.Bottom">
<Unbound>
<span @ref="@context.Current" class="action">
<Icon Type="question-circle" Theme="IconThemeType.Outline" />
</span>
</Unbound>
</AntDesign.Tooltip>
</SpaceItem>
<SpaceItem>
<AvatarDropdown Name="Test"
Avatar=""
MenuItems="@AvatarMenuItems"
OnItemSelected="HandleSelectUser" />
</SpaceItem>
@*<SpaceItem>
<SelectLang OnItemSelected="HandleSelectLang" />
</SpaceItem> *@
</Space>
</RightContentRender>
<ChildContent>
@Body
</ChildContent>
<FooterRender>
<FooterView Copyright="2025 Atomlust.com"></FooterView>
</FooterRender>
</AntDesign.ProLayout.BasicLayout>
</ChildContent>
<ErrorContent Context="ex">
<div class="pa-5" style="user-select: text;">
<div class="d-flex justify-space-between align-center">
<Alert Class="mr-2">程序遇到了未知错误!</Alert>
<Button Type="ButtonType.Link" OnClick="@(() => ResetError(ex))">确定</Button>
</div>
<div class="error-message mt-3">
@($"{ex.Message}{Environment.NewLine}{ex.StackTrace}")
</div>
</div>
</ErrorContent>
</ErrorBoundary>
@code {
string handler = "Server";
private ErrorBoundary? _errorBoundary;
private void ResetError(Exception ex)
{
_logger.LogError(ex, "未处理的异常。");
_errorBoundary?.Recover();
}
private bool _open = true;
private void ToggleDrawer()
{
_open = !_open;
}
private MenuDataItem[] MenuDatas;
private AvatarMenuItem[] AvatarMenuItems =>
[
new() { Key = "center", IconType = "user", Option = "通知消息" },
new() { Key = "setting", IconType = "setting", Option = "修改资料" },
new() { IsDivider = true },
new() { Key = "logout", IconType = "logout", Option = "退出登录" }
];
public void HandleSelectUser(AntDesign.MenuItem item)
{
switch (item.Key)
{
case "center":
Navigation.NavigateTo("/account/center");
break;
case "setting":
Navigation.NavigateTo("/account/settings");
break;
case "logout":
Navigation.NavigateTo("/logout");
break;
}
}
protected async override Task OnInitializedAsync()
{
if (OperatingSystem.IsBrowser())
{
handler = "Wasm";
}
else
{
handler = "Server";
}
var url = "/api/menu/tree";
var apiResult = await HttpService.Get<ApiResult<List<MenuDataItem>>>(url);
if (apiResult.Success)
{
if (apiResult.Data != null)
{
MenuDatas = apiResult.Data.ToArray();
StateHasChanged();
}
}
}
protected override void OnInitialized()
{
if (LocalizationProvider != null)
{
LocalizationProvider.LanguageChanged += OnLanguageChanged;
}
}
private void OnLanguageChanged(object? sender, string culture)
{
// ensure UI updates on the SyncContext; small delay to let cache update
_ = InvokeAsync(async () =>
{
await Task.Yield();
try
{
// Force route and page components to remount and re-render translations
Navigation.NavigateTo(Navigation.Uri, forceLoad: false);
}
catch { }
});
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender && LocalizationProvider != null)
{
try
{
await LocalizationProvider.InitializeAsync();
}
catch { }
}
}
public void Dispose()
{
if (LocalizationProvider != null)
{
LocalizationProvider.LanguageChanged -= OnLanguageChanged;
}
}
}