2026-01-06 10:55:05 +08:00
|
|
|
@inherits LayoutComponentBase
|
|
|
|
|
@using System.Reflection
|
|
|
|
|
@using System.Globalization
|
|
|
|
|
@inject WtmBlazorContext wtmblazor;
|
|
|
|
|
@inject IJSRuntime JSRuntime;
|
|
|
|
|
|
|
|
|
|
@inject NavigationManager NavigationManager;
|
|
|
|
|
|
|
|
|
|
<CascadingValue Value="this" IsFixed="true">
|
|
|
|
|
|
|
|
|
|
<Layout SideWidth="0" IsPage="true" ShowGotoTop="true" ShowCollapseBar="true"
|
|
|
|
|
IsFullSide="@IsFullSide" IsFixedHeader="@IsFixedHeader" IsFixedFooter="@IsFixedFooter" ShowFooter="@ShowFooter"
|
|
|
|
|
Menus="@Menus" UseTabSet="@UseTabSet" AdditionalAssemblies="new[] { GetType().Assembly }" class="color1">
|
|
|
|
|
<Header>
|
|
|
|
|
<span class="ml-3 flex-sm-fill d-none d-sm-block"></span>
|
|
|
|
|
@*<div class="header-right" style="width: 90px;">
|
|
|
|
|
<nav class="menu">
|
|
|
|
|
<div class="navbar navbar-expand d-flex">
|
|
|
|
|
<ul class="navbar-nav">
|
|
|
|
|
<li class="nav-item dropdown">
|
|
|
|
|
<a class="nav-link dropdown-toggle" data-bs-toggle="dropdown" role="button" href="#">
|
|
|
|
|
<span class="mx-1" style="">@SelectedCulture</span>
|
|
|
|
|
</a>
|
|
|
|
|
<div class="dropdown-menu">
|
|
|
|
|
<a @onclick="@(x=>SetCulture("zh"))" class="dropdown-item"><span class="nav-link-text">简体中文</span></a>
|
|
|
|
|
<a @onclick="@(x=>SetCulture("en"))" class="dropdown-item"><span class="nav-link-text">English</span></a>
|
|
|
|
|
</div>
|
|
|
|
|
</li>
|
|
|
|
|
</ul>
|
|
|
|
|
</div>
|
|
|
|
|
</nav>
|
|
|
|
|
</div>*@
|
|
|
|
|
@if (tenants.Count() >0)
|
|
|
|
|
{
|
|
|
|
|
<div class="header-right" style="width: 60px;">
|
|
|
|
|
<nav class="menu">
|
|
|
|
|
<div class="navbar navbar-expand d-flex">
|
|
|
|
|
<ul class="navbar-nav">
|
|
|
|
|
<li class="nav-item dropdown">
|
|
|
|
|
<a class="nav-link dropdown-toggle" data-bs-toggle="dropdown" role="button" href="#">
|
|
|
|
|
<span class="mx-1" style="">@(UserInfo.CurrentTenant==UserInfo.TenantCode?wtmblazor.Localizer["_Admin.TenantHost"]:tenants.Where(x=>x.Value == UserInfo.CurrentTenant).Select(x=>x.Text).FirstOrDefault())</span>
|
|
|
|
|
</a>
|
|
|
|
|
<div class="dropdown-menu">
|
|
|
|
|
<a @onclick="@(x=>SetTenant(UserInfo.TenantCode))" class="dropdown-item"><span class="nav-link-text">@wtmblazor.Localizer["_Admin.TenantHost"]</span></a>
|
|
|
|
|
@foreach (var t in tenants)
|
|
|
|
|
{
|
|
|
|
|
<a @onclick="@(x=>SetTenant(t.Value))" class="dropdown-item"><span class="nav-link-text">@t.Text</span></a>
|
|
|
|
|
}
|
|
|
|
|
</div>
|
|
|
|
|
</li>
|
|
|
|
|
</ul>
|
|
|
|
|
</div>
|
|
|
|
|
</nav>
|
|
|
|
|
</div>
|
|
|
|
|
}
|
|
|
|
|
<div class="header-right">
|
|
|
|
|
<nav class="menu">
|
|
|
|
|
<div class="navbar navbar-expand d-flex">
|
|
|
|
|
<ul class="navbar-nav">
|
|
|
|
|
<li class="nav-item dropdown">
|
|
|
|
|
<a class="nav-link dropdown-toggle" data-bs-toggle="dropdown" role="button" href="#">
|
|
|
|
|
@if (!string.IsNullOrEmpty(UserInfo.PhotoId.ToString()))
|
|
|
|
|
{
|
|
|
|
|
<Avatar style="margin-top:3px;" GetUrlAsync="()=>wtmblazor.GetBase64Image(UserInfo.PhotoId.ToString(),150,150)" IsCircle="true" Size="Size.ExtraSmall" />
|
|
|
|
|
}
|
|
|
|
|
<span class="mx-1" style="">@UserInfo.Name</span>
|
|
|
|
|
</a>
|
|
|
|
|
<div class="dropdown-menu">
|
|
|
|
|
<a @onclick="@Show" class="dropdown-item"><i class="fa fa-key fa-fw"></i><span class="nav-link-text">@wtmblazor.Localizer["Login.ChangePassword"]</span></a><!--!--><!--!-->
|
|
|
|
|
<a target="_self" href="/" class="dropdown-item"><i class="fa fa-house fa-fw"></i><span class="nav-link-text">@wtmblazor.Localizer["Sys.BackHome"]</span></a><!--!--><!--!-->
|
|
|
|
|
@if (wtmblazor.ConfigInfo.IsQuickDebug == true)
|
|
|
|
|
{
|
|
|
|
|
<a target="_blank" href="/_codegen?ui=blazor" class="dropdown-item"><i class="fa fa-cogs fa-fw"></i><span class="nav-link-text">@wtmblazor.Localizer["Sys.CodeGen"]</span></a>
|
|
|
|
|
<a target="_blank" href="/swagger" class="dropdown-item"><i class="fa fa-file-text fa-fw"></i><span class="nav-link-text">@wtmblazor.Localizer["Sys.ApiDoc"]</span></a>
|
|
|
|
|
}
|
|
|
|
|
<a @onclick="async ()=>await DeleteToken() " class="dropdown-item"><i class="fa fa-sign-out fa-fw"></i><span class="nav-link-text">@wtmblazor.Localizer["Login.LogOut"]</span></a>
|
|
|
|
|
</div>
|
|
|
|
|
</li>
|
|
|
|
|
</ul>
|
|
|
|
|
</div>
|
|
|
|
|
</nav>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
@* <div class="layout-drawer" @onclick="@(e => IsOpen = !IsOpen)"><i class="fa fa-gears"></i></div>*@
|
|
|
|
|
</Header>
|
|
|
|
|
<Side>
|
|
|
|
|
<div class="layout-banner">
|
|
|
|
|
<img class="layout-logo" src="/images/logo.png" style="width:50px;height:34px" />
|
|
|
|
|
<div class="layout-title">
|
|
|
|
|
<span style="font-size:large;">厦钨鸣鹤</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</Side>
|
|
|
|
|
<Main>
|
|
|
|
|
<CascadingValue Value="UserInfo" IsFixed=true>
|
|
|
|
|
@Body
|
|
|
|
|
</CascadingValue>
|
|
|
|
|
</Main>
|
|
|
|
|
</Layout>
|
|
|
|
|
|
|
|
|
|
<Drawer Placement="Placement.Right" @bind-IsOpen="@IsOpen" IsBackdrop="true">
|
|
|
|
|
<div class="layout-drawer-body">
|
|
|
|
|
<div class="btn btn-info w-100" @onclick="@(e => IsOpen = false)">@wtmblazor.Localizer["Sys.Close"]</div>
|
|
|
|
|
<GroupBox Title="@wtmblazor.Localizer["Sys.Layout"]">
|
|
|
|
|
<div class="row">
|
|
|
|
|
<div class="col-6">
|
|
|
|
|
<div class="layout-item @(IsFullSide ? "active d-flex" : "d-flex")" @onclick="@(e => IsFullSide = true)" data-bs-toggle="tooltip" title="@wtmblazor.Localizer["Sys.LeftRight"]">
|
|
|
|
|
<div class="layout-left d-flex flex-column">
|
|
|
|
|
<div class="layout-left-header"></div>
|
|
|
|
|
<div class="layout-left-body flex-fill"></div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="layout-right d-flex flex-column flex-fill">
|
|
|
|
|
<div class="layout-right-header"></div>
|
|
|
|
|
<div class="layout-right-body flex-fill"></div>
|
|
|
|
|
<div class="layout-right-footer"></div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="col-6">
|
|
|
|
|
<div class="layout-item flex-column @(IsFullSide ? "d-flex" : "active d-flex")" @onclick="@(e => IsFullSide = false)" data-toggle="tooltip" title="@wtmblazor.Localizer["Sys.UpDown"]">
|
|
|
|
|
<div class="layout-top">
|
|
|
|
|
</div>
|
|
|
|
|
<div class="layout-body d-flex flex-fill">
|
|
|
|
|
<div class="layout-left">
|
|
|
|
|
</div>
|
|
|
|
|
<div class="layout-right flex-fill">
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="layout-footer">
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
</GroupBox>
|
|
|
|
|
|
|
|
|
|
<GroupBox Title="@wtmblazor.Localizer["Sys.MoreSettings"]">
|
|
|
|
|
<div class="row">
|
|
|
|
|
<div class="col-6 d-flex align-items-center">
|
|
|
|
|
<Switch OnValueChanged="TabChanged" @bind-Value="@UseTabSet" OnColor="@Color.Success" OffColor="@Color.Primary"></Switch>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="col-6 text-right">
|
|
|
|
|
<span>@(UseTabSet ? @wtmblazor.Localizer["Sys.Tabs"] : @wtmblazor.Localizer["Sys.SinglePage"])</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</GroupBox>
|
|
|
|
|
</div>
|
|
|
|
|
</Drawer>
|
|
|
|
|
</CascadingValue>
|
|
|
|
|
@code
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
private bool UseTabSet { get; set; } = false;
|
|
|
|
|
|
|
|
|
|
private bool IsOpen { get; set; }
|
|
|
|
|
|
|
|
|
|
private bool IsFixedHeader { get; set; } = true;
|
|
|
|
|
|
|
|
|
|
private bool IsFixedFooter { get; set; } = true;
|
|
|
|
|
|
|
|
|
|
private bool IsFullSide { get; set; } = true;
|
|
|
|
|
|
|
|
|
|
private bool ShowFooter { get; set; } = false;
|
|
|
|
|
|
|
|
|
|
private List<BootstrapBlazor.Components.MenuItem> Menus { get; set; }
|
|
|
|
|
|
|
|
|
|
private List<SelectedItem> tenants = new List<SelectedItem>();
|
|
|
|
|
private string SelectedCulture
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
if (CultureInfo.CurrentUICulture.Name.Contains("zh"))
|
|
|
|
|
{
|
|
|
|
|
return "简体中文";
|
|
|
|
|
}
|
|
|
|
|
if (CultureInfo.CurrentUICulture.Name.Contains("en"))
|
|
|
|
|
{
|
|
|
|
|
return "English";
|
|
|
|
|
}
|
|
|
|
|
return CultureInfo.CurrentUICulture.Name;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[CascadingParameter]
|
|
|
|
|
public LoginUserInfo UserInfo
|
|
|
|
|
{
|
|
|
|
|
get;
|
|
|
|
|
set;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task DeleteToken()
|
|
|
|
|
{
|
|
|
|
|
var dir = await wtmblazor.Api.CallAPI("/api/_account/logout");
|
|
|
|
|
await JSRuntime.InvokeAsync<string>("localStorageFuncs.remove", "wtmtoken");
|
|
|
|
|
await JSRuntime.InvokeAsync<string>("localStorageFuncs.remove", "wtmrefreshtoken");
|
|
|
|
|
await JSRuntime.InvokeVoidAsync("urlFuncs.redirect", dir.Data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private async Task Show()
|
|
|
|
|
{
|
|
|
|
|
await wtmblazor.OpenDialog<Password>(wtmblazor.Localizer["Login.ChangePassword"], size: Size.Small, userinfo: UserInfo);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override async Task OnInitializedAsync()
|
|
|
|
|
{
|
|
|
|
|
List<BootstrapBlazor.Components.MenuItem> menus = null;
|
|
|
|
|
menus = new List<BootstrapBlazor.Components.MenuItem> { };
|
|
|
|
|
menus.Add(new BootstrapBlazor.Components.MenuItem() { Text = wtmblazor.Localizer["Sys.Home"], Icon = "fa fa-fw fa-home", Url = "/", Match = NavLinkMatch.All });
|
|
|
|
|
if (wtmblazor.ConfigInfo.IsQuickDebug == true)
|
|
|
|
|
{
|
|
|
|
|
var pages = wtmblazor.GetAllPages();
|
|
|
|
|
foreach (var item in pages)
|
|
|
|
|
{
|
|
|
|
|
BootstrapBlazor.Components.MenuItem m = new BootstrapBlazor.Components.MenuItem
|
|
|
|
|
{
|
|
|
|
|
Text = item.PageName,
|
|
|
|
|
Icon = item.Icon,
|
|
|
|
|
Url = item.Url
|
|
|
|
|
};
|
|
|
|
|
if (item.Children != null)
|
|
|
|
|
{
|
|
|
|
|
var items = new List<BootstrapBlazor.Components.MenuItem>();
|
|
|
|
|
|
|
|
|
|
foreach (var child in item.Children)
|
|
|
|
|
{
|
|
|
|
|
items.Add(new BootstrapBlazor.Components.MenuItem
|
|
|
|
|
{
|
|
|
|
|
Text = child.PageName,
|
|
|
|
|
Icon = child.Icon,
|
|
|
|
|
Url = child.Url
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
m.Items = items;
|
|
|
|
|
}
|
|
|
|
|
menus.Add(m);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
var usermenu = UserInfo.Attributes["Menus"] as WalkingTec.Mvvm.Core.Support.Json.SimpleMenuApi[];
|
|
|
|
|
|
|
|
|
|
var formatedmenu = new List<FrameworkMenu>();
|
|
|
|
|
formatedmenu.AddRange(toMenuTree(usermenu.AsQueryable()));
|
|
|
|
|
GetMenuFromFrameworkMenu(formatedmenu).ForEach(x => menus.Add(x));
|
|
|
|
|
}
|
|
|
|
|
Menus = menus;
|
|
|
|
|
|
|
|
|
|
tenants = await wtmblazor.Api.CallItemsApi($"/api/_frameworktenant/GetFrameworkTenants?parent={UserInfo.TenantCode}");
|
|
|
|
|
bool tab=false;
|
|
|
|
|
var test = await JSRuntime.InvokeAsync<string>("localStorageFuncs.get", "wtmtab");
|
|
|
|
|
bool suc = bool.TryParse(test, out tab);
|
|
|
|
|
if(suc == false){
|
|
|
|
|
tab = wtmblazor.ConfigInfo.PageMode == PageModeEnum.Tab ? true : false;
|
|
|
|
|
}
|
|
|
|
|
UseTabSet = tab;
|
|
|
|
|
await base.OnInitializedAsync();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 整理为树形
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="origs">来源列表</param>
|
|
|
|
|
/// <param name="parentID">当前级的父ID</param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
private List<FrameworkMenu> toMenuTree(IQueryable<WalkingTec.Mvvm.Core.Support.Json.SimpleMenuApi> origs,string parentID=null)
|
|
|
|
|
{
|
|
|
|
|
var rets = new List<FrameworkMenu>();
|
|
|
|
|
var _thisList = origs.Where(t => t.ParentId==parentID);
|
|
|
|
|
foreach (var item in _thisList)
|
|
|
|
|
{
|
|
|
|
|
var _item = new FrameworkMenu
|
|
|
|
|
{
|
|
|
|
|
ID = new Guid(item.Id),
|
|
|
|
|
PageName = item.Text,
|
|
|
|
|
Icon = item.Icon,
|
|
|
|
|
Url = item.Url,
|
|
|
|
|
Children = new List<FrameworkMenu>()
|
|
|
|
|
};
|
|
|
|
|
_item.Children.AddRange(toMenuTree(origs, item.Id));
|
|
|
|
|
rets.Add(_item);
|
|
|
|
|
}
|
|
|
|
|
return rets;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private List<BootstrapBlazor.Components.MenuItem> GetMenuFromFrameworkMenu(List<FrameworkMenu> input)
|
|
|
|
|
{
|
|
|
|
|
List<BootstrapBlazor.Components.MenuItem> rv = new List<BootstrapBlazor.Components.MenuItem>();
|
|
|
|
|
foreach (var item in input)
|
|
|
|
|
{
|
|
|
|
|
var m = new BootstrapBlazor.Components.MenuItem
|
|
|
|
|
{
|
|
|
|
|
Text = wtmblazor.Localizer[item.PageName],
|
|
|
|
|
Icon = item.Icon,
|
|
|
|
|
Url = item.Url
|
|
|
|
|
};
|
|
|
|
|
if (m.Url != null)
|
|
|
|
|
{
|
|
|
|
|
if (m.Url.ToLower().StartsWith("http://") || m.Url.ToLower().StartsWith("https://"))
|
|
|
|
|
{
|
|
|
|
|
m.Url = "/Outside/" + System.Web.HttpUtility.UrlEncode(m.Url);
|
|
|
|
|
m.Match = NavLinkMatch.All;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (item.Children?.Any() == true)
|
|
|
|
|
{
|
|
|
|
|
m.Items = GetMenuFromFrameworkMenu(item.Children);
|
|
|
|
|
}
|
|
|
|
|
rv.Add(m);
|
|
|
|
|
}
|
|
|
|
|
return rv;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private async Task SetCulture(string Value)
|
|
|
|
|
{
|
|
|
|
|
var cultureName = Value;
|
|
|
|
|
if (cultureName != CultureInfo.CurrentUICulture.Name)
|
|
|
|
|
{
|
|
|
|
|
await JSRuntime.InvokeAsync<string>("localStorageFuncs.set", "wtmculture", Value);
|
|
|
|
|
var culture = new CultureInfo(cultureName);
|
|
|
|
|
CultureInfo.CurrentCulture = culture;
|
|
|
|
|
CultureInfo.CurrentUICulture = culture;
|
|
|
|
|
var uri = await JSRuntime.InvokeAsync<string>("urlFuncs.getCurrentUrl");
|
|
|
|
|
var query = $"?culture={Uri.EscapeDataString(Value)}&" +
|
|
|
|
|
$"redirect={Uri.EscapeDataString(uri)}";
|
|
|
|
|
NavigationManager.NavigateTo(wtmblazor.GetServerUrl() + "/_framework/SetLanguageForBlazor" + query, forceLoad: true);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private async Task SetTenant(string Value)
|
|
|
|
|
{
|
|
|
|
|
_ = await wtmblazor.Api.CallAPI("/api/_account/SetTenant?tenant=" + Value);
|
|
|
|
|
_ = await JSRuntime.InvokeAsync<string>("urlFuncs.refresh");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private async Task TabChanged(bool v)
|
|
|
|
|
{
|
|
|
|
|
await JSRuntime.InvokeAsync<bool>("localStorageFuncs.set", "wtmtab",v);
|
|
|
|
|
}
|
|
|
|
|
}
|