调整UI布局,消息模版新增语言字段
This commit is contained in:
@@ -47,6 +47,9 @@
|
|||||||
<ChildContent>
|
<ChildContent>
|
||||||
@Body
|
@Body
|
||||||
</ChildContent>
|
</ChildContent>
|
||||||
|
<FooterRender>
|
||||||
|
<FooterView Copyright="2025 Atomlust.com"></FooterView>
|
||||||
|
</FooterRender>
|
||||||
</AntDesign.ProLayout.BasicLayout>
|
</AntDesign.ProLayout.BasicLayout>
|
||||||
</ChildContent>
|
</ChildContent>
|
||||||
<ErrorContent Context="ex">
|
<ErrorContent Context="ex">
|
||||||
|
|||||||
@@ -1,24 +1,32 @@
|
|||||||
@page "/"
|
@page "/"
|
||||||
|
@page "/{locale}/"
|
||||||
@attribute [Authorize]
|
@attribute [Authorize]
|
||||||
|
<PageContainer Title="控制台首页">
|
||||||
|
|
||||||
<PageTitle>Home</PageTitle>
|
|
||||||
|
|
||||||
<h1>Hello, world!</h1>
|
|
||||||
|
|
||||||
Welcome to your new app.
|
<h1>Hello, world!</h1>
|
||||||
|
|
||||||
<li>
|
Welcome to your new app.
|
||||||
<a href="/category/list">产品分类</a>
|
|
||||||
</li>
|
<li>
|
||||||
<li>
|
<a href="/category/list">产品分类</a>
|
||||||
<a href="/product/category/edit">产品分类编辑</a>
|
</li>
|
||||||
</li>
|
<li>
|
||||||
<li>
|
<a href="/product/category/edit">产品分类编辑</a>
|
||||||
<a href="/system/language/list">多语言设置</a>
|
</li>
|
||||||
</li>
|
<li>
|
||||||
<li>
|
<a href="/system/language/list">多语言设置</a>
|
||||||
<a href="/system/locale/resource/list">多语言资源设置</a>
|
</li>
|
||||||
</li>
|
<li>
|
||||||
<li>
|
<a href="/system/locale/resource/list">多语言资源设置</a>
|
||||||
<a href="/system/role/list">角色管理</a>
|
</li>
|
||||||
</li>
|
<li>
|
||||||
|
<a href="/system/role/list">角色管理</a>
|
||||||
|
</li>
|
||||||
|
</PageContainer>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
[Parameter]
|
||||||
|
public string Locale { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
@@ -1,9 +1,25 @@
|
|||||||
@page "/system/app/version/list"
|
@page "/system/app/version/list"
|
||||||
|
@page "/{locale}/system/app/version/list"
|
||||||
|
|
||||||
@inject ILogger<AppVersionList> Logger
|
@inject ILogger<AppVersionList> Logger
|
||||||
@attribute [Authorize]
|
@attribute [Authorize]
|
||||||
|
<div>
|
||||||
|
<PageContainer Title="App版本管理">
|
||||||
|
<Breadcrumb>
|
||||||
|
<Breadcrumb>
|
||||||
|
<BreadcrumbItem Href="/">管理后台</BreadcrumbItem>
|
||||||
|
<BreadcrumbItem Href="/settings">系统配置</BreadcrumbItem>
|
||||||
|
<BreadcrumbItem>版本管理</BreadcrumbItem>
|
||||||
|
</Breadcrumb>
|
||||||
|
</Breadcrumb>
|
||||||
|
<ChildContent>
|
||||||
|
<h3>App Version List</h3>
|
||||||
|
</ChildContent>
|
||||||
|
</PageContainer>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
[Parameter]
|
||||||
|
public string Locale { get; set; } = string.Empty;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,149 +1,165 @@
|
|||||||
@page "/admin/list"
|
@page "/admin/list"
|
||||||
|
@page "/{locale}/admin/list"
|
||||||
@inject ILogger<AdminList> Logger
|
@inject ILogger<AdminList> Logger
|
||||||
@attribute [Authorize]
|
@attribute [Authorize]
|
||||||
|
|
||||||
|
|
||||||
<PageTitle>管理员账号管理</PageTitle>
|
<PageContainer Title="管理员帐号">
|
||||||
|
<Breadcrumb>
|
||||||
|
<Breadcrumb>
|
||||||
|
<BreadcrumbItem Href="/">管理后台</BreadcrumbItem>
|
||||||
|
<BreadcrumbItem Href="/admin/list">系统功能</BreadcrumbItem>
|
||||||
|
<BreadcrumbItem>版本管理</BreadcrumbItem>
|
||||||
|
</Breadcrumb>
|
||||||
|
</Breadcrumb>
|
||||||
|
<ChildContent>
|
||||||
|
<Card Class="">
|
||||||
|
<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.Username" Placeholder="帐号" AllowClear />
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
|
||||||
<Title Level="4">管理员帐号</Title>
|
<Col>
|
||||||
<Card Class="">
|
<div class="ant-form-item" style="width:200px;display:flex;">
|
||||||
<Form @ref="searchForm" Model="search" Layout="FormLayout.Inline" Class="search-form" OnFinish="OnSearchFinish">
|
<Button Type="ButtonType.Primary" HtmlType="submit">查询</Button>
|
||||||
<Row Justify="RowJustify.Start" Gutter="16">
|
<Button Style="margin: 0 8px;" OnClick="OnSearchReset">重置</Button>
|
||||||
<Col>
|
</div>
|
||||||
<FormItem Label="帐号">
|
</Col>
|
||||||
<Input @bind-Value="search.Username" Placeholder="帐号" AllowClear />
|
</Row>
|
||||||
</FormItem>
|
</Form>
|
||||||
</Col>
|
</Card>
|
||||||
|
<br />
|
||||||
|
<Card Class="mt-3">
|
||||||
|
<Table DataSource="PagingList.Items" PageSize="100" HidePagination="true" Resizable>
|
||||||
|
<TitleTemplate>
|
||||||
|
<Flex Justify="FlexJustify.SpaceBetween">
|
||||||
|
帐号列表
|
||||||
|
<div>
|
||||||
|
<AuthorizeCheck Permission="@Permissions.Admin.Create">
|
||||||
|
<Button Class="me-3" OnClick="OnCreateClick" Type="ButtonType.Primary">新增</Button>
|
||||||
|
</AuthorizeCheck>
|
||||||
|
</div>
|
||||||
|
</Flex>
|
||||||
|
</TitleTemplate>
|
||||||
|
<ColumnDefinitions>
|
||||||
|
<PropertyColumn Property="c => c.Username" Title="帐号">
|
||||||
|
</PropertyColumn>
|
||||||
|
<PropertyColumn Property="c => c.Email" Title="邮件">
|
||||||
|
|
||||||
<Col>
|
</PropertyColumn>
|
||||||
<div class="ant-form-item" style="width:200px;display:flex;">
|
<PropertyColumn Property="c => c.Mobile" Title="手机号" />
|
||||||
<Button Type="ButtonType.Primary" HtmlType="submit">查询</Button>
|
<PropertyColumn Property="c => c.Status" Title="状态" Width="80px" Align="ColumnAlign.Center">
|
||||||
<Button Style="margin: 0 8px;" OnClick="OnSearchReset">重置</Button>
|
@if (context.Status == 1)
|
||||||
</div>
|
{
|
||||||
</Col>
|
<AntDesign.Text Type="TextElementType.Success"><Icon Type="check" Theme=" IconThemeType.Outline" Width="1.3em" Height="1.3em" /></AntDesign.Text>
|
||||||
</Row>
|
|
||||||
</Form>
|
|
||||||
</Card>
|
|
||||||
<br />
|
|
||||||
<Card Class="mt-3">
|
|
||||||
<Table DataSource="PagingList.Items" PageSize="100" HidePagination="true" Resizable>
|
|
||||||
<TitleTemplate>
|
|
||||||
<Flex Justify="FlexJustify.SpaceBetween">
|
|
||||||
帐号列表
|
|
||||||
<div>
|
|
||||||
<AuthorizeCheck Permission="@Permissions.Admin.Create">\
|
|
||||||
<Button Class="me-3" OnClick="OnCreateClick" Type="ButtonType.Primary">新增</Button>
|
|
||||||
</AuthorizeCheck>
|
|
||||||
</div>
|
|
||||||
</Flex>
|
|
||||||
</TitleTemplate>
|
|
||||||
<ColumnDefinitions>
|
|
||||||
<PropertyColumn Property="c => c.Username" Title="帐号">
|
|
||||||
</PropertyColumn>
|
|
||||||
<PropertyColumn Property="c => c.Email" Title="邮件">
|
|
||||||
|
|
||||||
</PropertyColumn>
|
}
|
||||||
<PropertyColumn Property="c => c.Mobile" Title="手机号" />
|
else
|
||||||
<PropertyColumn Property="c => c.Status" Title="状态" Width="80px" Align="ColumnAlign.Center">
|
{
|
||||||
@if (context.Status == 1)
|
<Icon Type="close" Theme="IconThemeType.Outline" Width="1.3em" Height="1.3em" />
|
||||||
|
}
|
||||||
|
</PropertyColumn>
|
||||||
|
<PropertyColumn Property="c => c.LastLogin" Title="最后登录" />
|
||||||
|
<PropertyColumn Property="c => c.UpdateTime" Title="最后更新" />
|
||||||
|
<ActionColumn Title="操作" Align="ColumnAlign.Right" Width="160px">
|
||||||
|
<Space>
|
||||||
|
<SpaceItem>
|
||||||
|
<Dropdown Trigger="@(new Trigger[] { Trigger.Click })">
|
||||||
|
<Overlay>
|
||||||
|
<Menu>
|
||||||
|
|
||||||
|
<MenuItem>
|
||||||
|
<a @onclick="(e) => OnEditClick(context)"> <Icon Type="@IconType.Outline.Edit" /> 编辑</a>
|
||||||
|
</MenuItem>
|
||||||
|
<MenuDivider />
|
||||||
|
<MenuItem>
|
||||||
|
<Popconfirm Placement="@Placement.Left" Title="@("删除这条数据无法恢复,您确定要删除吗?")"
|
||||||
|
OnConfirm="@(e=>HandleDeleteConfirmAsync(e,context.Id))"
|
||||||
|
OkText="确定"
|
||||||
|
CancelText="取消">
|
||||||
|
<a> <Icon Type="@IconType.Outline.Delete" /> 删除</a>
|
||||||
|
</Popconfirm>
|
||||||
|
</MenuItem>
|
||||||
|
</Menu>
|
||||||
|
</Overlay>
|
||||||
|
<ChildContent>
|
||||||
|
<a class="ant-dropdown-link" @onclick:preventDefault>
|
||||||
|
<Icon Type="@IconType.Outline.Menu" />
|
||||||
|
</a>
|
||||||
|
</ChildContent>
|
||||||
|
</Dropdown>
|
||||||
|
</SpaceItem>
|
||||||
|
</Space>
|
||||||
|
</ActionColumn>
|
||||||
|
</ColumnDefinitions>
|
||||||
|
</Table>
|
||||||
|
<br />
|
||||||
|
<Row Justify="RowJustify.End">
|
||||||
|
<Pagination PageIndex="pager.Index" Total="PagingList.Count" PageSize="PagingList.Size" ShowSizeChanger="false" OnChange="OnPageChanged"></Pagination>
|
||||||
|
</Row>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
<Drawer Closable="true" Width="520" Visible="drawerVisible" Title='(model.Id == 0 ? "新增帐号" : "编辑帐号")' OnClose="_ => CloseDrawer()">
|
||||||
|
<Form LabelColSpan="5" @ref="@editform" Model="@model" OnFinish="OnFormFinish">
|
||||||
|
<FluentValidationValidator />
|
||||||
|
<FormItem Label="帐号名称">
|
||||||
|
<Input @bind-Value="model.Username" For="(()=>model.Username)" Placeholder="帐号名称" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem Label="电子邮件">
|
||||||
|
<Input @bind-Value="model.Email" For="(()=>model.Email)" Placeholder="电子邮件" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem Label="手机号码">
|
||||||
|
<Input @bind-Value="model.Mobile" For="(()=>model.Mobile)" Placeholder="手机号码" />
|
||||||
|
</FormItem>
|
||||||
|
@if (context.Id > 0)
|
||||||
{
|
{
|
||||||
<AntDesign.Text Type="TextElementType.Success"><Icon Type="check" Theme=" IconThemeType.Outline" Width="1.3em" Height="1.3em" /></AntDesign.Text>
|
<FormItem Label="密码设置">
|
||||||
|
<Checkbox @bind-Value="@context.SetPassword" Disabled=false>
|
||||||
|
重置密码
|
||||||
|
</Checkbox>
|
||||||
|
</FormItem>
|
||||||
}
|
}
|
||||||
else
|
@if (context.Id == 0)
|
||||||
{
|
{
|
||||||
<Icon Type="close" Theme="IconThemeType.Outline" Width="1.3em" Height="1.3em" />
|
<FormItem Label="登录密码">
|
||||||
|
<Input @bind-Value="@context.Password" Placeholder="登录密码" />
|
||||||
|
</FormItem>
|
||||||
}
|
}
|
||||||
</PropertyColumn>
|
@if ((context.Id > 0 && context.SetPassword) || context.Id == 0)
|
||||||
<PropertyColumn Property="c => c.LastLogin" Title="最后登录" Width="120px" />
|
{
|
||||||
<PropertyColumn Property="c => c.UpdateTime" Title="最后更新" />
|
|
||||||
<ActionColumn Title="操作" Align="ColumnAlign.Right" Width="160px">
|
|
||||||
<Space>
|
|
||||||
<SpaceItem>
|
|
||||||
<Dropdown Trigger="@(new Trigger[] { Trigger.Click })">
|
|
||||||
<Overlay>
|
|
||||||
<Menu>
|
|
||||||
|
|
||||||
<MenuItem>
|
<FormItem Label="新密码">
|
||||||
<a @onclick="(e) => OnEditClick(context)"> <Icon Type="@IconType.Outline.Edit" /> 编辑</a>
|
<Input @bind-Value="@context.NewPassword" Placeholder="新登录密码" />
|
||||||
</MenuItem>
|
</FormItem>
|
||||||
<MenuDivider />
|
}
|
||||||
<MenuItem>
|
@if ((context.Id > 0 && context.SetPassword) || context.Id == 0)
|
||||||
<Popconfirm Placement="@Placement.Left" Title="@("删除这条数据无法恢复,您确定要删除吗?")"
|
{
|
||||||
OnConfirm="@(e=>HandleDeleteConfirmAsync(e,context.Id))"
|
|
||||||
OkText="确定"
|
|
||||||
CancelText="取消">
|
|
||||||
<a> <Icon Type="@IconType.Outline.Delete" /> 删除</a>
|
|
||||||
</Popconfirm>
|
|
||||||
</MenuItem>
|
|
||||||
</Menu>
|
|
||||||
</Overlay>
|
|
||||||
<ChildContent>
|
|
||||||
<a class="ant-dropdown-link" @onclick:preventDefault>
|
|
||||||
<Icon Type="@IconType.Outline.Menu" />
|
|
||||||
</a>
|
|
||||||
</ChildContent>
|
|
||||||
</Dropdown>
|
|
||||||
</SpaceItem>
|
|
||||||
</Space>
|
|
||||||
</ActionColumn>
|
|
||||||
</ColumnDefinitions>
|
|
||||||
</Table>
|
|
||||||
</Card>
|
|
||||||
|
|
||||||
<Drawer Closable="true" Width="520" Visible="drawerVisible" Title='(model.Id == 0 ? "新增帐号" : "编辑帐号")' OnClose="_ => CloseDrawer()">
|
<FormItem Label="确认密码">
|
||||||
<Form LabelColSpan="5" @ref="@editform" Model="@model" OnFinish="OnFormFinish">
|
<Input @bind-Value="@context.RePassword" Placeholder="确认密码" />
|
||||||
<FluentValidationValidator />
|
</FormItem>
|
||||||
<FormItem Label="帐号名称">
|
}
|
||||||
<Input @bind-Value="model.Username" For="(()=>model.Username)" Placeholder="帐号名称" />
|
<FormItem Label="可用状态">
|
||||||
</FormItem>
|
<RadioGroup @bind-Value="@context.Status">
|
||||||
<FormItem Label="电子邮件">
|
<Radio RadioButton Value=0>禁用</Radio>
|
||||||
<Input @bind-Value="model.Email" For="(()=>model.Email)" Placeholder="电子邮件" />
|
<Radio RadioButton Value=1>启用</Radio>
|
||||||
</FormItem>
|
</RadioGroup>
|
||||||
<FormItem Label="手机号码">
|
</FormItem>
|
||||||
<Input @bind-Value="model.Mobile" For="(()=>model.Mobile)" Placeholder="手机号码" />
|
<FormItem WrapperColOffset="4">
|
||||||
</FormItem>
|
<Button Type="ButtonType.Primary" HtmlType="submit" Style="width: 100%;">保存</Button>
|
||||||
@if (context.Id > 0)
|
</FormItem>
|
||||||
{
|
</Form>
|
||||||
<FormItem Label="密码设置">
|
</Drawer>
|
||||||
<Checkbox @bind-Value="@context.SetPassword" Disabled=false>
|
</ChildContent>
|
||||||
重置密码
|
</PageContainer>
|
||||||
</Checkbox>
|
|
||||||
</FormItem>
|
|
||||||
}
|
|
||||||
@if (context.Id == 0)
|
|
||||||
{
|
|
||||||
<FormItem Label="登录密码">
|
|
||||||
<Input @bind-Value="@context.Password" Placeholder="登录密码" />
|
|
||||||
</FormItem>
|
|
||||||
}
|
|
||||||
@if ((context.Id > 0 && context.SetPassword) || context.Id == 0)
|
|
||||||
{
|
|
||||||
|
|
||||||
<FormItem Label="新密码">
|
|
||||||
<Input @bind-Value="@context.NewPassword" Placeholder="新登录密码" />
|
|
||||||
</FormItem>
|
|
||||||
}
|
|
||||||
@if ((context.Id > 0 && context.SetPassword) || context.Id == 0)
|
|
||||||
{
|
|
||||||
|
|
||||||
<FormItem Label="确认密码">
|
|
||||||
<Input @bind-Value="@context.RePassword" Placeholder="确认密码" />
|
|
||||||
</FormItem>
|
|
||||||
}
|
|
||||||
<FormItem Label="可用状态">
|
|
||||||
<RadioGroup @bind-Value="@context.Status">
|
|
||||||
<Radio RadioButton Value=0>禁用</Radio>
|
|
||||||
<Radio RadioButton Value=1>启用</Radio>
|
|
||||||
</RadioGroup>
|
|
||||||
</FormItem>
|
|
||||||
<FormItem WrapperColOffset="4">
|
|
||||||
<Button Type="ButtonType.Primary" HtmlType="submit" Style="width: 100%;">保存</Button>
|
|
||||||
</FormItem>
|
|
||||||
</Form>
|
|
||||||
</Drawer>
|
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
[Parameter]
|
||||||
|
public string Locale { get; set; } = string.Empty;
|
||||||
|
|
||||||
[SupplyParameterFromQuery]
|
[SupplyParameterFromQuery]
|
||||||
int? Page { get; set; }
|
int? Page { get; set; }
|
||||||
|
|
||||||
@@ -276,6 +292,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnPageChanged(PaginationEventArgs args)
|
||||||
|
{
|
||||||
|
OnSearch(args.Page);
|
||||||
|
}
|
||||||
|
|
||||||
void OnCreateClick()
|
void OnCreateClick()
|
||||||
{
|
{
|
||||||
model = new();
|
model = new();
|
||||||
@@ -325,7 +346,7 @@
|
|||||||
{
|
{
|
||||||
|
|
||||||
CloseDrawer();
|
CloseDrawer();
|
||||||
_= LoadList();
|
_ = LoadList();
|
||||||
await ModalService.InfoAsync(new ConfirmOptions() { Title = "提示", Content = "数据提交成功!" });
|
await ModalService.InfoAsync(new ConfirmOptions() { Title = "提示", Content = "数据提交成功!" });
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
8
Atomx.Admin/Atomx.Admin.Client/Pages/Systems/Info.razor
Normal file
8
Atomx.Admin/Atomx.Admin.Client/Pages/Systems/Info.razor
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
@page "/system/info"
|
||||||
|
@page "/{locale}/system/info"
|
||||||
|
<h3>Info</h3>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
[Parameter]
|
||||||
|
public string Locale { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
@@ -1,90 +1,103 @@
|
|||||||
@page "/system/role/permission/{RoleId:long}"
|
@page "/system/role/permission/{RoleId:long}"
|
||||||
|
@page "/{locale}/system/role/permission/{RoleId:long}"
|
||||||
@attribute [Authorize]
|
@attribute [Authorize]
|
||||||
@inject ILogger<RoleList> Logger
|
@inject ILogger<RoleList> Logger
|
||||||
|
|
||||||
<PageTitle>权限设置</PageTitle>
|
<PageContainer Title="权限角色设置">
|
||||||
<Spin Spinning="loading">
|
<Breadcrumb>
|
||||||
<Title Level="4">编辑角色权限</Title>
|
<Breadcrumb>
|
||||||
<Card>
|
<BreadcrumbItem Href="/">管理后台</BreadcrumbItem>
|
||||||
<Form @ref="editForm" Model="model" LabelColSpan="2" WrapperColSpan="22" Class="search-form" OnFinish="OnFormFinishAsync">
|
<BreadcrumbItem Href="/admin/list">系统功能</BreadcrumbItem>
|
||||||
<FormItem Label="角色">
|
<BreadcrumbItem>权限编辑</BreadcrumbItem>
|
||||||
为角色 <Text>@role?.Name</Text> 设置权限
|
</Breadcrumb>
|
||||||
</FormItem>
|
</Breadcrumb>
|
||||||
<FormItem Label="权限">
|
<ChildContent>
|
||||||
<div class="ant-form-item-control-input-content">
|
<Spin Spinning="loading">
|
||||||
@if (!PermissionGroups.Any())
|
<Card>
|
||||||
{
|
<Form @ref="editForm" Model="model" LabelColSpan="2" WrapperColSpan="22" Class="search-form" OnFinish="OnFormFinishAsync">
|
||||||
<div>
|
<FormItem Label="角色">
|
||||||
<p>暂无权限可设置</p>
|
为角色 <Text>@role?.Name</Text> 设置权限
|
||||||
</div>
|
</FormItem>
|
||||||
}
|
<FormItem Label="权限">
|
||||||
else
|
<div class="ant-form-item-control-input-content">
|
||||||
{
|
@if (!PermissionGroups.Any())
|
||||||
@foreach (var group in PermissionGroups)
|
{
|
||||||
{
|
<div>
|
||||||
<GridRow Style="padding-top:10px;">
|
<p>暂无权限可设置</p>
|
||||||
<GridCol Span="24">
|
</div>
|
||||||
<label class="ant-checkbox-wrapper">
|
}
|
||||||
<span class="ant-checkbox @((@group.PermissionItems.Count(p => p.IsSelected) > 0 && @group.PermissionItems.Count(p => p.IsSelected) < @group.PermissionItems.Count) ? "ant-checkbox-indeterminate" : "")">
|
else
|
||||||
<input class="ant-checkbox-input" type="checkbox"
|
{
|
||||||
@onchange="(e) => ToggleAllPermissions(group, (bool)e.Value!)"
|
@foreach (var group in PermissionGroups)
|
||||||
checked="@group.PermissionItems.All(p => p.IsSelected)" />
|
|
||||||
<span class="ant-checkbox-inner"></span>
|
|
||||||
|
|
||||||
</span>
|
|
||||||
<span>
|
|
||||||
<span class="form-check-label fw-bold">
|
|
||||||
@group.CategoryName
|
|
||||||
</span>
|
|
||||||
<small class="text-muted ms-2">
|
|
||||||
(@group.PermissionItems.Count(p => p.IsSelected)/@group.PermissionItems.Count)
|
|
||||||
</small>
|
|
||||||
</span>
|
|
||||||
</label>
|
|
||||||
</GridCol>
|
|
||||||
</GridRow>
|
|
||||||
<GridRow Style="margin-left:20px;margin-right:20px;">
|
|
||||||
@foreach (var permission in group.PermissionItems)
|
|
||||||
{
|
{
|
||||||
<GridCol Span="6">
|
<GridRow Style="padding-top:10px;">
|
||||||
<label class="ant-checkbox-wrapper">
|
<GridCol Span="24">
|
||||||
<span class="ant-checkbox">
|
<label class="ant-checkbox-wrapper">
|
||||||
<input class="ant-checkbox-input" type="checkbox"
|
<span class="ant-checkbox @((@group.PermissionItems.Count(p => p.IsSelected) > 0 && @group.PermissionItems.Count(p => p.IsSelected) < @group.PermissionItems.Count) ? "ant-checkbox-indeterminate" : "")">
|
||||||
@bind="permission.IsSelected"
|
<input class="ant-checkbox-input" type="checkbox"
|
||||||
id="perm_@permission.Name" />
|
@onchange="(e) => ToggleAllPermissions(group, (bool)e.Value!)"
|
||||||
<span class="ant-checkbox-inner"></span>
|
checked="@group.PermissionItems.All(p => p.IsSelected)" />
|
||||||
|
<span class="ant-checkbox-inner"></span>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
<span class="form-check-label" for="perm_@permission.Name">
|
<span>
|
||||||
@permission.Description
|
<span class="form-check-label fw-bold">
|
||||||
<small class="text-muted d-block">@permission.Name</small>
|
@group.CategoryName
|
||||||
</span>
|
</span>
|
||||||
</label>
|
<small class="text-muted ms-2">
|
||||||
</GridCol>
|
(@group.PermissionItems.Count(p => p.IsSelected)/@group.PermissionItems.Count)
|
||||||
|
</small>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
</GridCol>
|
||||||
|
</GridRow>
|
||||||
|
<GridRow Style="margin-left:20px;margin-right:20px;">
|
||||||
|
@foreach (var permission in group.PermissionItems)
|
||||||
|
{
|
||||||
|
<GridCol Span="6">
|
||||||
|
<label class="ant-checkbox-wrapper">
|
||||||
|
<span class="ant-checkbox">
|
||||||
|
<input class="ant-checkbox-input" type="checkbox"
|
||||||
|
@bind="permission.IsSelected"
|
||||||
|
id="perm_@permission.Name" />
|
||||||
|
<span class="ant-checkbox-inner"></span>
|
||||||
|
|
||||||
|
</span>
|
||||||
|
<span class="form-check-label" for="perm_@permission.Name">
|
||||||
|
@permission.Description
|
||||||
|
<small class="text-muted d-block">@permission.Name</small>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
</GridCol>
|
||||||
|
}
|
||||||
|
</GridRow>
|
||||||
}
|
}
|
||||||
</GridRow>
|
}
|
||||||
}
|
</div>
|
||||||
}
|
</FormItem>
|
||||||
</div>
|
<FormItem WrapperCol="new ColLayoutParam { Span = 24, Offset = 2 }">
|
||||||
</FormItem>
|
<Button Type="@ButtonType.Primary" HtmlType="submit" Loading="@isSaving">
|
||||||
<FormItem WrapperCol="new ColLayoutParam { Span = 24, Offset = 2 }">
|
@if (isSaving)
|
||||||
<Button Type="@ButtonType.Primary" HtmlType="submit" Loading="@isSaving">
|
{
|
||||||
@if (isSaving)
|
<span>保存中...</span>
|
||||||
{
|
}
|
||||||
<span>保存中...</span>
|
else
|
||||||
}
|
{
|
||||||
else
|
<span>保存权限设置</span>
|
||||||
{
|
}
|
||||||
<span>保存权限设置</span>
|
|
||||||
}
|
|
||||||
|
|
||||||
</Button>
|
</Button>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
</Form>
|
</Form>
|
||||||
|
|
||||||
</Card>
|
</Card>
|
||||||
</Spin>
|
</Spin>
|
||||||
|
</ChildContent>
|
||||||
|
</PageContainer>
|
||||||
@code {
|
@code {
|
||||||
|
[Parameter]
|
||||||
|
public string Locale { get; set; } = string.Empty;
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public long RoleId { get; set; }
|
public long RoleId { get; set; }
|
||||||
|
|
||||||
|
|||||||
@@ -1,112 +1,123 @@
|
|||||||
@page "/system/role/list"
|
@page "/system/role/list"
|
||||||
|
@page "/{locale}/system/role/list"
|
||||||
@attribute [Authorize]
|
@attribute [Authorize]
|
||||||
@inject ILogger<RoleList> Logger
|
@inject ILogger<RoleList> Logger
|
||||||
|
|
||||||
<PageTitle>角色管理</PageTitle>
|
<PageContainer Title="角色管理">
|
||||||
|
<Breadcrumb>
|
||||||
|
<Breadcrumb>
|
||||||
|
<BreadcrumbItem Href="/">管理后台</BreadcrumbItem>
|
||||||
|
<BreadcrumbItem Href="/admin/list">系统功能</BreadcrumbItem>
|
||||||
|
<BreadcrumbItem>角色管理</BreadcrumbItem>
|
||||||
|
</Breadcrumb>
|
||||||
|
</Breadcrumb>
|
||||||
|
<ChildContent>
|
||||||
|
<Card Class="mt-3">
|
||||||
|
<Table DataSource="PagingList.Items" 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="角色">
|
||||||
|
</PropertyColumn>
|
||||||
|
<PropertyColumn Property="c => c.Description" Title="说明" />
|
||||||
|
<PropertyColumn Property="c => c.IsSystemRole" Title="系统" Width="80px" Align="ColumnAlign.Center">
|
||||||
|
@if (context.IsSystemRole)
|
||||||
|
{
|
||||||
|
<AntDesign.Text Type="TextElementType.Success"><Icon Type="check" Theme=" IconThemeType.Outline" Width="1.3em" Height="1.3em" /></AntDesign.Text>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<AntDesign.Text Type="TextElementType.Secondary"><Icon Type="minus" Theme="IconThemeType.Outline" Width="1.3em" Height="1.3em" /></AntDesign.Text>
|
||||||
|
}
|
||||||
|
</PropertyColumn>
|
||||||
|
<PropertyColumn Property="c => c.Count" Title="用户数" Width="100px" />
|
||||||
|
<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>
|
||||||
|
|
||||||
<Title Level="4">角色管理</Title>
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<Icon Type="close" Theme="IconThemeType.Outline" Width="1.3em" Height="1.3em" />
|
||||||
|
}
|
||||||
|
</PropertyColumn>
|
||||||
|
|
||||||
<Card Class="mt-3">
|
<PropertyColumn Property="c => c.UpdateTime" Title="最后更新" Width="190px" />
|
||||||
<Table DataSource="PagingList.Items" PageSize="100" HidePagination="true" Resizable>
|
<ActionColumn Title="操作" Align="ColumnAlign.Right" Width="160px">
|
||||||
<TitleTemplate>
|
<Space>
|
||||||
<Flex Justify="FlexJustify.SpaceBetween">
|
<SpaceItem>
|
||||||
角色列表
|
<Button Type="ButtonType.Link" OnClick="() => OnEditPermissionClick(context)">权限管理</Button>
|
||||||
<div>
|
</SpaceItem>
|
||||||
<Button Class="me-3" OnClick="OnCreateClick" Type="ButtonType.Primary">新增</Button>
|
<SpaceItem>
|
||||||
</div>
|
<Dropdown Trigger="@(new Trigger[] { Trigger.Click })">
|
||||||
</Flex>
|
<Overlay>
|
||||||
</TitleTemplate>
|
<Menu>
|
||||||
<ColumnDefinitions>
|
|
||||||
<PropertyColumn Property="c => c.Name" Title="角色">
|
|
||||||
</PropertyColumn>
|
|
||||||
<PropertyColumn Property="c => c.Description" Title="说明" />
|
|
||||||
<PropertyColumn Property="c => c.IsSystemRole" Title="系统" Width="80px" Align="ColumnAlign.Center">
|
|
||||||
@if (context.IsSystemRole)
|
|
||||||
{
|
|
||||||
<AntDesign.Text Type="TextElementType.Success"><Icon Type="check" Theme=" IconThemeType.Outline" Width="1.3em" Height="1.3em" /></AntDesign.Text>
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<AntDesign.Text Type="TextElementType.Secondary"><Icon Type="minus" Theme="IconThemeType.Outline" Width="1.3em" Height="1.3em" /></AntDesign.Text>
|
|
||||||
}
|
|
||||||
</PropertyColumn>
|
|
||||||
<PropertyColumn Property="c => c.Count" Title="用户数" Width="100px" />
|
|
||||||
<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>
|
|
||||||
|
|
||||||
}
|
<MenuItem>
|
||||||
else
|
<a @onclick="(e) => OnEditClick(context)"> <Icon Type="@IconType.Outline.Edit" /> 编辑</a>
|
||||||
{
|
</MenuItem>
|
||||||
<Icon Type="close" Theme="IconThemeType.Outline" Width="1.3em" Height="1.3em" />
|
@if (!context.IsSystemRole)
|
||||||
}
|
{
|
||||||
</PropertyColumn>
|
<MenuDivider />
|
||||||
|
<MenuItem>
|
||||||
|
<Popconfirm Placement="@Placement.Left" Title="@("删除这条数据无法恢复,您确定要删除吗?")"
|
||||||
|
OnConfirm="@(e=>HandleDeleteConfirmAsync(e,context.Id))"
|
||||||
|
OkText="确定"
|
||||||
|
CancelText="取消">
|
||||||
|
<a> <Icon Type="@IconType.Outline.Delete" /> 删除</a>
|
||||||
|
</Popconfirm>
|
||||||
|
</MenuItem>
|
||||||
|
}
|
||||||
|
</Menu>
|
||||||
|
</Overlay>
|
||||||
|
<ChildContent>
|
||||||
|
<a class="ant-dropdown-link" @onclick:preventDefault>
|
||||||
|
<Icon Type="@IconType.Outline.Menu" />
|
||||||
|
</a>
|
||||||
|
</ChildContent>
|
||||||
|
</Dropdown>
|
||||||
|
</SpaceItem>
|
||||||
|
</Space>
|
||||||
|
</ActionColumn>
|
||||||
|
</ColumnDefinitions>
|
||||||
|
</Table>
|
||||||
|
<br />
|
||||||
|
<Row Justify="RowJustify.End">
|
||||||
|
<Pagination PageIndex="pager.Index" Total="PagingList.Count" PageSize="PagingList.Size" ShowSizeChanger="false" OnChange="OnPageChanged"></Pagination>
|
||||||
|
</Row>
|
||||||
|
</Card>
|
||||||
|
|
||||||
<PropertyColumn Property="c => c.UpdateTime" Title="最后更新" Width="190px" />
|
<Drawer Closable="true" Width="520" Visible="drawerVisible" Title='(model.Id == 0 ? "新增角色" : "编辑角色")' OnClose="_ => CloseDrawer()">
|
||||||
<ActionColumn Title="操作" Align="ColumnAlign.Right" Width="160px">
|
<Form LabelColSpan="5" @ref="@editform" Model="@model" OnFinish="OnFormFinish">
|
||||||
<Space>
|
<FluentValidationValidator />
|
||||||
<SpaceItem>
|
<FormItem Label="角色名称">
|
||||||
<Button Type="ButtonType.Link" OnClick="() => OnEditPermissionClick(context)">权限管理</Button>
|
<Input @bind-Value="model.Name" For="(()=>model.Name)" Placeholder="角色名称" />
|
||||||
</SpaceItem>
|
</FormItem>
|
||||||
<SpaceItem>
|
<FormItem Label="角色说明">
|
||||||
<Dropdown Trigger="@(new Trigger[] { Trigger.Click })">
|
<Input @bind-Value="model.Description" For="(()=>model.Culture)" Placeholder="角色说明" />
|
||||||
<Overlay>
|
</FormItem>
|
||||||
<Menu>
|
<FormItem Label="可用状态">
|
||||||
|
<Checkbox T="bool" Label="启用" @bind-value="model.Enabled" Size="InputSize.Small" Class="ps-0" />
|
||||||
<MenuItem>
|
</FormItem>
|
||||||
<a @onclick="(e) => OnEditClick(context)"> <Icon Type="@IconType.Outline.Edit" /> 编辑</a>
|
<FormItem WrapperColOffset="4">
|
||||||
</MenuItem>
|
<Button Type="ButtonType.Primary" HtmlType="submit" Style="width: 100%;">保存</Button>
|
||||||
@if (!context.IsSystemRole)
|
</FormItem>
|
||||||
{
|
</Form>
|
||||||
<MenuDivider />
|
</Drawer>
|
||||||
<MenuItem>
|
</ChildContent>
|
||||||
<Popconfirm Placement="@Placement.Left" Title="@("删除这条数据无法恢复,您确定要删除吗?")"
|
</PageContainer>
|
||||||
OnConfirm="@(e=>HandleDeleteConfirmAsync(e,context.Id))"
|
|
||||||
OkText="确定"
|
|
||||||
CancelText="取消">
|
|
||||||
<a> <Icon Type="@IconType.Outline.Delete" /> 删除</a>
|
|
||||||
</Popconfirm>
|
|
||||||
</MenuItem>
|
|
||||||
}
|
|
||||||
</Menu>
|
|
||||||
</Overlay>
|
|
||||||
<ChildContent>
|
|
||||||
<a class="ant-dropdown-link" @onclick:preventDefault>
|
|
||||||
<Icon Type="@IconType.Outline.Menu" />
|
|
||||||
</a>
|
|
||||||
</ChildContent>
|
|
||||||
</Dropdown>
|
|
||||||
</SpaceItem>
|
|
||||||
</Space>
|
|
||||||
</ActionColumn>
|
|
||||||
</ColumnDefinitions>
|
|
||||||
</Table>
|
|
||||||
<br />
|
|
||||||
<Row Justify="RowJustify.End">
|
|
||||||
<Pagination PageIndex="pager.Index" Total="PagingList.Count" PageSize="PagingList.Size" ShowSizeChanger="false" OnChange="OnPageChanged"></Pagination>
|
|
||||||
</Row>
|
|
||||||
</Card>
|
|
||||||
|
|
||||||
<Drawer Closable="true" Width="520" Visible="drawerVisible" Title='(model.Id == 0 ? "新增角色" : "编辑角色")' OnClose="_ => CloseDrawer()">
|
|
||||||
<Form LabelColSpan="5" @ref="@editform" Model="@model" OnFinish="OnFormFinish">
|
|
||||||
<FluentValidationValidator />
|
|
||||||
<FormItem Label="角色名称">
|
|
||||||
<Input @bind-Value="model.Name" For="(()=>model.Name)" Placeholder="角色名称" />
|
|
||||||
</FormItem>
|
|
||||||
<FormItem Label="角色说明">
|
|
||||||
<Input @bind-Value="model.Description" For="(()=>model.Culture)" Placeholder="角色说明" />
|
|
||||||
</FormItem>
|
|
||||||
<FormItem Label="可用状态">
|
|
||||||
<Checkbox T="bool" Label="启用" @bind-value="model.Enabled" Size="InputSize.Small" Class="ps-0" />
|
|
||||||
</FormItem>
|
|
||||||
<FormItem WrapperColOffset="4">
|
|
||||||
<Button Type="ButtonType.Primary" HtmlType="submit" Style="width: 100%;">保存</Button>
|
|
||||||
</FormItem>
|
|
||||||
</Form>
|
|
||||||
</Drawer>
|
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
[Parameter]
|
||||||
|
public string Locale { get; set; } = string.Empty;
|
||||||
|
|
||||||
[SupplyParameterFromQuery]
|
[SupplyParameterFromQuery]
|
||||||
int? Page { get; set; }
|
int? Page { get; set; }
|
||||||
|
|
||||||
|
|||||||
9
Atomx.Admin/Atomx.Admin.Client/Pages/Systems/Tools.razor
Normal file
9
Atomx.Admin/Atomx.Admin.Client/Pages/Systems/Tools.razor
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
@page "/system/tools"
|
||||||
|
@page "/{locale}/system/tools"
|
||||||
|
|
||||||
|
<h3>Tools</h3>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
[Parameter]
|
||||||
|
public string Locale { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@ using Atomx.Data;
|
|||||||
using Atomx.Data.Services;
|
using Atomx.Data.Services;
|
||||||
using Atomx.Utils.Extension;
|
using Atomx.Utils.Extension;
|
||||||
using MapsterMapper;
|
using MapsterMapper;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
@@ -14,6 +15,7 @@ namespace Atomx.Admin.Controllers
|
|||||||
{
|
{
|
||||||
[Route("api/[controller]")]
|
[Route("api/[controller]")]
|
||||||
[ApiController]
|
[ApiController]
|
||||||
|
[Authorize]
|
||||||
public class AppVersionController : ControllerBase
|
public class AppVersionController : ControllerBase
|
||||||
{
|
{
|
||||||
readonly ILogger<AppVersionController> _logger;
|
readonly ILogger<AppVersionController> _logger;
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ a, .btn-link {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
|
.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
|
||||||
box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
|
box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
@@ -75,3 +75,89 @@ h1:focus {
|
|||||||
.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
|
.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
|
||||||
text-align: start;
|
text-align: start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
html,
|
||||||
|
body,
|
||||||
|
#root,
|
||||||
|
#app,
|
||||||
|
app {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.colorWeak {
|
||||||
|
filter: invert(80%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-layout {
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
canvas {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
text-rendering: optimizeLegibility;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul,
|
||||||
|
ol {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-page-header {
|
||||||
|
background: #f0f2f5;
|
||||||
|
padding: 12px 24px 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-breadcrumb + .ant-page-header-heading {
|
||||||
|
padding: 0px;
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-pro-page-container-children-content {
|
||||||
|
margin: 0 24px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-page-header-heading-extra {
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-page-header-content {
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
.ant-table {
|
||||||
|
width: 100%;
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-table-thead > tr > th,
|
||||||
|
.ant-table-tbody > tr > th,
|
||||||
|
.ant-table-thead > tr > td,
|
||||||
|
.ant-table-tbody > tr > td {
|
||||||
|
white-space: pre;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-table-thead > tr > th > span,
|
||||||
|
.ant-table-tbody > tr > th > span,
|
||||||
|
.ant-table-thead > tr > td > span,
|
||||||
|
.ant-table-tbody > tr > td > span {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
|
||||||
|
body .ant-design-pro > .ant-layout {
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -16,6 +16,11 @@ namespace Atomx.Common.Entities
|
|||||||
[Key]
|
[Key]
|
||||||
public long Id { get; set; }
|
public long Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 语言编码
|
||||||
|
/// </summary>
|
||||||
|
public int LanguageId { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 消息模板类型
|
/// 消息模板类型
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
Reference in New Issue
Block a user