Compare commits

...

13 Commits

Author SHA1 Message Date
Argo-Lenovo e4b2f70ae3 feat: 增加任务日志滚动条样式 2022-01-29 18:39:54 +08:00
Argo-Lenovo 41b0dce852 feat: 任务日志增加最大数功能 2022-01-29 16:03:57 +08:00
Argo-Lenovo 188470bc1d feat: 增加任务日志功能 2022-01-29 15:26:44 +08:00
Argo-Lenovo 92e3aa4c35 feat: 实现缓存清楚逻辑 2022-01-29 14:34:00 +08:00
Argo-Tianyi 5e136d1815 fix: 修复 Client 工程编译报错问题 2022-01-28 12:24:49 +08:00
Argo-Tianyi 7506665052 feat: 登录首页增加切换功能 2022-01-27 16:00:21 +08:00
Argo-Tianyi fc2f0e84b2 feat: 增加 AdminLoginFooter 组件用于切换登录页 2022-01-27 15:43:29 +08:00
Argo-Tianyi 6ba2ef3a96 feat: 增加码云高仿登录界面 2022-01-27 15:14:09 +08:00
Argo-Tianyi 2674c6278d feat: 增加登录首页切换功能 2022-01-27 13:42:48 +08:00
Argo-Tianyi 6e881fbff4 feat: 登录首页配置增加顺序 2022-01-27 13:31:59 +08:00
Argo-Tianyi 135f0615f5 refactor: 改造登录首页组件 2022-01-27 13:31:37 +08:00
Argo-Tianyi a53c0cd791 feat: 增加更新 DisplayName 逻辑 2022-01-27 12:53:36 +08:00
Argo-Tianyi 71d5ff0a24 chore: 更新依赖包 2022-01-27 12:53:18 +08:00
30 changed files with 707 additions and 132 deletions

View File

@ -6,7 +6,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="BootstrapBlazor" Version="6.2.7" /> <PackageReference Include="BootstrapBlazor" Version="6.2.9-beta07" />
<PackageReference Include="FreeSql.Provider.Sqlite" Version="3.0.100" /> <PackageReference Include="FreeSql.Provider.Sqlite" Version="3.0.100" />
</ItemGroup> </ItemGroup>

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<ItemGroup> <ItemGroup>
<PackageReference Include="BootstrapBlazor" Version="6.2.7" /> <PackageReference Include="BootstrapBlazor" Version="6.2.9-beta07" />
<PackageReference Include="SqlSugarCore" Version="5.0.5.2" /> <PackageReference Include="SqlSugarCore" Version="5.0.5.2" />
</ItemGroup> </ItemGroup>

View File

@ -71,9 +71,9 @@ class DefaultCacheManager : ICacheManager
{ {
Cache.Remove(key); Cache.Remove(key);
} }
else else if (Cache is MemoryCache c)
{ {
//Cache.Compact(100); c.Compact(100);
} }
} }
} }

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<ItemGroup> <ItemGroup>
<PackageReference Include="BootstrapBlazor" Version="6.2.9-beta06" /> <PackageReference Include="BootstrapBlazor" Version="6.2.9-beta07" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.1" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.1" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.1" />
</ItemGroup> </ItemGroup>

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<ItemGroup> <ItemGroup>
<PackageReference Include="BootstrapBlazor" Version="6.2.9-beta06" /> <PackageReference Include="BootstrapBlazor" Version="6.2.9-beta07" />
<PackageReference Include="Longbow.Security.Cryptography" Version="5.2.0" /> <PackageReference Include="Longbow.Security.Cryptography" Version="5.2.0" />
<PackageReference Include="Microsoft.Data.Sqlite" Version="6.0.1" /> <PackageReference Include="Microsoft.Data.Sqlite" Version="6.0.1" />
<PackageReference Include="PetaPoco.Extensions" Version="6.0.0" /> <PackageReference Include="PetaPoco.Extensions" Version="6.0.0" />

View File

@ -1,35 +1,39 @@
<form method="post" class="form-signin" action="@PostUrl" @ref="LoginForm"> <div class="wrap white">
<h2 class="form-signin-heading">@Title</h2> <div class="container">
<div class="@ClassString"> <form method="post" class="form-signin" action="@PostUrl" @ref="LoginForm">
@if (AllowMobile) <h2 class="form-signin-heading">@Title</h2>
{ <div class="@ClassString">
<div class="login-sms"> @if (AllowMobile)
<SMSLogin /> {
<div class="login-sms">
<SMSLogin />
</div>
}
<div class="login-up">
<UserLogin />
</div>
<div class="d-flex justify-content-between mt-3">
<Checkbox @bind-Value="RememberPassword" Color="Color.Primary" ShowAfterLabel="true" DisplayText="记住密码自动登录" OnValueChanged="OnRememberPassword" />
<Block Condition="AllowMobile">
<SwitchButton @bind-ToggleState="UseMobileLogin" OnClick="OnClickSwitchButton" OffText="短信验证登录" OnText="用户密码登录" />
</Block>
</div>
<button class="btn-login btn-lg btn-block mt-3" data-bs-toggle="tooltip" title="不填写密码默认使用 Gitee 认证">登 录</button>
<div class="d-flex justify-content-between mt-3">
<LinkButton Text="申请账号" OnClick="OnSignUp" />
<LinkButton Text="忘记密码" OnClick="OnForgotPassword" />
</div>
<Block Condition="AllowOAuth">
<Divider Text="其他方式登录" />
<div class="login-list">
<LinkButton Url="Account/Gitee" Title="使用 Gitee 帐号登录" ImageUrl="images/gitee.svg" />
<LinkButton Url="Account/Gitee" Title="使用 GitHub 帐号登录" ImageUrl="images/git.svg" />
<LinkButton Url="#" Title="微信-暂未实现" ImageUrl="images/weixin-2.svg" />
<LinkButton Url="Account/Tencent" Title="使用 QQ 账号登录" ImageUrl="images/qq.svg" />
<LinkButton Url="Account/Alipay" Title="使用支付宝账号登录" ImageUrl="images/zhifubao.svg" />
</div>
</Block>
</div> </div>
} </form>
<div class="login-up">
<UserLogin />
</div>
<div class="d-flex justify-content-between mt-3">
<Checkbox @bind-Value="RememberPassword" Color="Color.Primary" ShowAfterLabel="true" DisplayText="记住密码自动登录" OnValueChanged="OnRememberPassword" />
<Block Condition="AllowMobile">
<SwitchButton @bind-ToggleState="UseMobileLogin" OnClick="OnClickSwitchButton" OffText="短信验证登录" OnText="用户密码登录" />
</Block>
</div>
<button class="btn-login btn-lg btn-block mt-3" data-bs-toggle="tooltip" title="不填写密码默认使用 Gitee 认证">登 录</button>
<div class="d-flex justify-content-between mt-3">
<LinkButton Text="申请账号" OnClick="OnSignUp" />
<LinkButton Text="忘记密码" OnClick="OnForgotPassword" />
</div>
<Block Condition="AllowOAuth">
<Divider Text="其他方式登录" />
<div class="login-list">
<LinkButton Url="Account/Gitee" Title="使用 Gitee 帐号登录" ImageUrl="images/gitee.svg" />
<LinkButton Url="Account/Gitee" Title="使用 GitHub 帐号登录" ImageUrl="images/git.svg" />
<LinkButton Url="#" Title="微信-暂未实现" ImageUrl="images/weixin-2.svg" />
<LinkButton Url="Account/Tencent" Title="使用 QQ 账号登录" ImageUrl="images/qq.svg" />
<LinkButton Url="Account/Alipay" Title="使用支付宝账号登录" ImageUrl="images/zhifubao.svg" />
</div>
</Block>
</div> </div>
</form> </div>

View File

@ -3,6 +3,7 @@
// Website: https://admin.blazor.zone // Website: https://admin.blazor.zone
using BootstrapAdmin.Web.Core; using BootstrapAdmin.Web.Core;
using BootstrapAdmin.Web.Utils;
using Microsoft.JSInterop; using Microsoft.JSInterop;
namespace BootstrapAdmin.Web.Components; namespace BootstrapAdmin.Web.Components;
@ -12,19 +13,40 @@ namespace BootstrapAdmin.Web.Components;
/// </summary> /// </summary>
public partial class AdminLogin : IDisposable public partial class AdminLogin : IDisposable
{ {
private string? Title { get; set; } /// <summary>
///
/// </summary>
protected string? Title { get; set; }
private bool AllowMobile { get; set; } = true; /// <summary>
///
/// </summary>
protected bool AllowMobile { get; set; } = true;
private bool UseMobileLogin { get; set; } /// <summary>
///
/// </summary>
protected bool UseMobileLogin { get; set; }
private bool AllowOAuth { get; set; } = true; /// <summary>
///
/// </summary>
protected bool AllowOAuth { get; set; } = true;
private bool RememberPassword { get; set; } /// <summary>
///
/// </summary>
protected bool RememberPassword { get; set; }
private ElementReference LoginForm { get; set; } /// <summary>
///
/// </summary>
protected ElementReference LoginForm { get; set; }
private string? PostUrl { get; set; } /// <summary>
///
/// </summary>
protected string? PostUrl { get; set; }
private JSInterop<AdminLogin>? Interop { get; set; } private JSInterop<AdminLogin>? Interop { get; set; }
@ -40,13 +62,19 @@ public partial class AdminLogin : IDisposable
[Parameter] [Parameter]
public string? AppId { get; set; } public string? AppId { get; set; }
/// <summary>
///
/// </summary>
[Inject] [Inject]
[NotNull] [NotNull]
private IDict? DictsService { get; set; } protected IDict? DictsService { get; set; }
/// <summary>
///
/// </summary>
[Inject] [Inject]
[NotNull] [NotNull]
private ILogin? LoginService { get; set; } protected ILogin? LoginService { get; set; }
[Inject] [Inject]
[NotNull] [NotNull]
@ -57,7 +85,7 @@ public partial class AdminLogin : IDisposable
/// </summary> /// </summary>
[Inject] [Inject]
[NotNull] [NotNull]
private WebClientService? WebClientService { get; set; } protected WebClientService? WebClientService { get; set; }
/// <summary> /// <summary>
/// ///
@ -66,7 +94,10 @@ public partial class AdminLogin : IDisposable
[NotNull] [NotNull]
private IIPLocatorProvider? IPLocatorProvider { get; set; } private IIPLocatorProvider? IPLocatorProvider { get; set; }
private string? ClassString => CssBuilder.Default("login-wrap") /// <summary>
///
/// </summary>
protected string? ClassString => CssBuilder.Default("login-wrap")
.AddClass("is-mobile", UseMobileLogin) .AddClass("is-mobile", UseMobileLogin)
.Build(); .Build();
@ -78,17 +109,20 @@ public partial class AdminLogin : IDisposable
base.OnInitialized(); base.OnInitialized();
Title = DictsService.GetWebTitle(); Title = DictsService.GetWebTitle();
PostUrl = QueryHelper.AddQueryString("/Account/Login", new Dictionary<string, string?> PostUrl = QueryHelper.AddQueryString("Account/Login", new Dictionary<string, string?>
{ {
["ReturnUrl"] = ReturnUrl, ["ReturnUrl"] = ReturnUrl,
["AppId"] = AppId ["AppId"] = AppId
}); });
} }
void OnClickSwitchButton() /// <summary>
///
/// </summary>
protected void OnClickSwitchButton()
{ {
var rem = RememberPassword ? "true" : "false"; var rem = RememberPassword ? "true" : "false";
PostUrl = QueryHelper.AddQueryString(UseMobileLogin ? "/Account/Mobile" : "/Account/Login", new Dictionary<string, string?>() PostUrl = QueryHelper.AddQueryString(UseMobileLogin ? "Account/Mobile" : "Account/Login", new Dictionary<string, string?>()
{ {
[nameof(ReturnUrl)] = ReturnUrl, [nameof(ReturnUrl)] = ReturnUrl,
["AppId"] = AppId, ["AppId"] = AppId,
@ -113,18 +147,29 @@ public partial class AdminLogin : IDisposable
} }
} }
Task OnRememberPassword(bool remember) /// <summary>
///
/// </summary>
/// <param name="remember"></param>
/// <returns></returns>
protected Task OnRememberPassword(bool remember)
{ {
OnClickSwitchButton(); OnClickSwitchButton();
return Task.CompletedTask; return Task.CompletedTask;
} }
void OnSignUp() /// <summary>
///
/// </summary>
protected void OnSignUp()
{ {
} }
void OnForgotPassword() /// <summary>
///
/// </summary>
protected void OnForgotPassword()
{ {
} }

View File

@ -1,4 +1,29 @@
.form-signin-heading { .wrap {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
@media (min-width: 768px) {
.wrap {
background-color: #5bc0de;
background: url('../images/bg2.jpg') fixed no-repeat;
background-size: 100% 100%;
}
.container {
background: url('../images/bg3.png') no-repeat;
background-size: contain;
width: 704px;
height: 404px;
margin: 0 auto;
margin-top: calc(100vh / 2 - 190px);
}
}
.form-signin-heading {
margin: 0; margin: 0;
padding: 20px 15px; padding: 20px 15px;
text-align: center; text-align: center;
@ -123,3 +148,17 @@
color: #e0e0e0; color: #e0e0e0;
} }
} }
@media (min-width: 768px) {
.gitee.wrap {
background-color: #f1f2f7;
background-image: none;
}
.gitee .container {
width: 704px;
height: 404px;
margin: 0 auto;
margin-top: calc(100vh / 2 - 190px);
}
}

View File

@ -0,0 +1,11 @@
<div class="login-footer">
<ul class="login-footer-body">
<li><a href="https://www.gitee.com/LongbowEnterprise" target="_blank"><i class="fa fa-copyright"></i> Bootstrap Admin</a></li>
<li><a href="https://www.gitee.com/LongbowEnterprise/BootstrapAdmin/wikis" target="_blank">帮助文档</a></li>
<li><a href="Account/Login?View=Login">系统默认</a></li>
<li><a href="Account/Login?View=Login-Gitee">高仿码云</a></li>
<li><a href="Account/Login?View=Login-Blue">蓝色简约</a></li>
<li><a href="Account/Login?View=Login-Tec">科技动感</a></li>
<li><a href="Account/Login?View=Login-LTE">Admin-LTE</a></li>
</ul>
</div>

View File

@ -0,0 +1,24 @@
.login-footer {
position: fixed;
bottom: 0;
left: 0;
right: 0;
display: flex;
justify-content: center;
}
.login-footer-body {
display: flex;
}
li {
list-style: none;
}
li:not(:last-child) {
margin-right: 1rem;
}
.white + .login-footer li a {
color: #fff;
}

View File

@ -0,0 +1,68 @@
@inherits AdminLogin
<div class="wrap">
<div class="container">
<section class="login-sidebox">
<div class="login-sidebox-content">
<div class="login-sidebox-header">
<div class="login-sidebox-logo">
<img alt="logo" src="../favicon.png"><span>Bootstrap Admin</span>
</div>
<h2 class="login-sidebox-subtitle">
通用后台权限管理系统
</h2>
</div>
<div class="login-sidebox-body">
<p>
基于 RBAC 的 NetCore 后台管理框架权限管理前后台分离支持多站点单点登录兼容所有主流浏览器内置微信、支付宝、QQ等多种登录方式内置多种样式可切换至 Blazor 多 Tabs 模式,权限控制细化到网页内任意元素(按钮、表格、文本框等等)
</p>
</div>
<div class="login-sidebox-footer">
<div>开源文档:<a href="https://gitee.com/LongbowEnterprise/BootstrapAdmin/wikis">码云托管平台 - Wiki</a></div>
</div>
</div>
</section>
<section class="login-form">
<div class="login-form-header">
<h2>登录</h2>
<span class="flex-self-end">
没有帐号?
<LinkButton Text="申请账号" OnClick="OnSignUp" />
</span>
</div>
<form method="post" class="form-signin" action="@PostUrl" @ref="LoginForm">
<div class="@ClassString">
@if (AllowMobile)
{
<div class="login-sms">
<SMSLogin />
</div>
}
<div class="login-up">
<UserLogin />
</div>
</div>
<div class="d-flex justify-content-between mt-4">
<Checkbox @bind-Value="RememberPassword" Color="Color.Primary" ShowAfterLabel="true" DisplayText="记住密码自动登录" OnValueChanged="OnRememberPassword" />
<Block Condition="AllowMobile">
<SwitchButton @bind-ToggleState="UseMobileLogin" OnClick="OnClickSwitchButton" OffText="短信验证登录" OnText="用户密码登录" />
</Block>
</div>
<button class="btn-login btn-lg btn-block mt-4" data-bs-toggle="tooltip" title="不填写密码默认使用 Gitee 认证">登 录</button>
<div class="d-flex justify-content-center mt-3 mb-4">
<LinkButton Text="已有账号,忘记密码?" OnClick="OnForgotPassword" />
</div>
<Block Condition="AllowOAuth">
<Divider Text="其他方式登录" />
<div class="login-list">
<LinkButton Url="Account/Gitee" Title="使用 Gitee 帐号登录" ImageUrl="images/gitee.svg" />
<LinkButton Url="Account/Gitee" Title="使用 GitHub 帐号登录" ImageUrl="images/git.svg" />
<LinkButton Url="#" Title="微信-暂未实现" ImageUrl="images/weixin-2.svg" />
<LinkButton Url="Account/Tencent" Title="使用 QQ 账号登录" ImageUrl="images/qq.svg" />
<LinkButton Url="Account/Alipay" Title="使用支付宝账号登录" ImageUrl="images/zhifubao.svg" />
</div>
</Block>
</form>
</section>
</div>
</div>

View File

@ -0,0 +1,228 @@
.wrap {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
color: #40485b;
background-color: #f1f2f7;
-webkit-font-smoothing: antialiased;
font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";
}
.container {
display: flex;
box-shadow: 0px 20px 80px 0px rgb(0 0 0 / 30%);
width: 1000px;
height: 500px;
padding: 0;
margin: 0 auto;
margin-top: calc(100vh / 2 - 275px);
}
section {
width: 50%;
}
.login-sidebox {
position: relative;
background: -webkit-gradient(linear, left bottom, left top, from(#3a485a), to(#607089));
background: linear-gradient(0deg, #3a485a 0%, #607089 100%);
color: #fff;
}
.login-sidebox::before,
.login-sidebox::after {
content: '';
top: 0;
right: 0;
bottom: 0;
left: 0;
position: absolute;
}
.login-sidebox::before {
background: url(../images/left-1.png) no-repeat 0 0;
}
.login-sidebox::after {
background: url(../images/left-2.png) no-repeat right bottom;
}
.login-sidebox .login-sidebox-content {
padding: 80px 80px 48px;
position: relative;
z-index: 1;
}
.login-sidebox-header {
margin-bottom: 40px;
}
.login-sidebox-logo {
display: flex;
align-items: center;
margin-bottom: 14px;
}
.login-sidebox-logo img {
width: 48px;
height: auto;
border-radius: 50%;
margin-right: 14px;
}
.login-sidebox-logo span {
display: inline;
font-size: 1.5rem;
font-weight: 700;
}
.login-sidebox-subtitle {
font-size: 20pt;
font-weight: normal;
}
.login-sidebox-footer {
margin-top: 40px;
border-top: solid 1px #ddd;
padding-top: 28px;
font-size: 0.875rem;
font-weight: 500;
}
.login-sidebox-footer a {
cursor: pointer;
color: #fff;
}
.login-form {
padding: 64px;
font-size: 0.875rem;
}
.login-form-header {
display: flex;
justify-content: space-between;
align-items: flex-end;
margin-bottom: 20px;
}
.login-form-header h2 {
margin-bottom: 0;
font-size: 24px;
font-weight: bold;
line-height: 32px;
}
.login-list {
display: flex;
justify-content: space-between;
}
.login-list .item {
width: 32px;
height: 32px;
}
.forget-password {
padding: 16px 0;
}
.form-signin-heading {
margin: 0;
padding: 20px 15px;
text-align: center;
background-color: #41cac0;
border-radius: 5px 5px 0 0;
color: #fff;
}
.login-sms,
.is-mobile .login-up {
display: none;
}
.is-mobile .login-sms {
display: block;
}
::deep .btn-login {
color: #fff;
background: #fe7300;
border-color: transparent;
text-transform: uppercase;
font-weight: 300;
font-family: 'Open Sans', sans-serif;
line-height: 1;
}
::deep .btn-login:hover {
background: #fe7300;
}
::deep .divider-wrap {
background-color: #7c86bb;
}
::deep .divider-text {
background-color: #f1f2f7;
}
.login-list {
display: flex;
justify-content: space-between;
}
.login-list ::deep img {
width: 32px;
height: 32px;
}
::deep .btn-sms {
width: 140px;
}
@media (max-width: 767px) {
.form-signin {
margin: 0 auto;
background: #fff;
border-radius: 5px;
max-width: 320px;
border: solid 1px #ddd;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.125);
}
}
@media (min-width: 768px) {
.form-signin-heading {
padding: 28px 0;
background-color: transparent;
}
.slidercaptcha {
width: 300px;
}
.slidercaptcha, .slidercaptcha.oauth {
height: 280px;
}
.slidercaptcha.card .card-body {
padding: 15px 15px 0 15px;
}
.login-footer {
width: 100%;
display: flex;
justify-content: space-around;
}
.login-footer .login-footer-body li a {
color: #e0e0e0;
}
}
::deep .divider {
margin: 1.5rem 0;
}

View File

@ -0,0 +1 @@
<BootstrapBlazor.Components.Console Items="@Messages" Height="280" ShowAutoScroll="true" />

View File

@ -0,0 +1,77 @@
// 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.Models;
using Longbow.Tasks;
namespace BootstrapAdmin.Web.Components;
/// <summary>
///
/// </summary>
public partial class TaskInfo : IDisposable
{
/// <summary>
///
/// </summary>
[Parameter]
[NotNull]
[EditorRequired]
public TasksModel? Model { get; set; }
private List<ConsoleMessageItem> Messages { get; } = new(24);
/// <summary>
///
/// </summary>
/// <param name="firstRender"></param>
/// <returns></returns>
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
var sche = TaskServicesManager.Get(Model.Name);
if (sche != null)
{
sche.Triggers.First().PulseCallback = async t => await DispatchMessage(t);
await DispatchMessage(sche.Triggers.First());
}
}
}
private async Task DispatchMessage(ITrigger trigger)
{
var message = $"Trigger({trigger.GetType().Name}) LastRuntime: {trigger.LastRuntime} Run({trigger.LastResult}) NextRuntime: {trigger.NextRuntime} Elapsed: {trigger.LastRunElapsedTime.TotalSeconds}";
Messages.Add(new ConsoleMessageItem()
{
Message = message
});
if (Messages.Count > 20)
{
Messages.RemoveAt(0);
}
await InvokeAsync(StateHasChanged);
}
private void Dispose(bool disposing)
{
if (disposing)
{
var sche = TaskServicesManager.Get(Model.Name);
if (sche != null)
{
sche.Triggers.First().PulseCallback = null;
}
}
}
/// <summary>
///
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}

View File

@ -0,0 +1,69 @@
// 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.Components;
using BootstrapAdmin.Web.Core;
using BootstrapAdmin.Web.Shared;
using BootstrapAdmin.Web.Utils;
using Microsoft.AspNetCore.Components.Rendering;
namespace BootstrapAdmin.Web.Pages.Account;
/// <summary>
///
/// </summary>
[Layout(typeof(LoginLayout))]
[Route("/Account/Login")]
public class Login : ComponentBase
{
/// <summary>
///
/// </summary>
[SupplyParameterFromQuery]
[Parameter]
public string? ReturnUrl { get; set; }
/// <summary>
///
/// </summary>
[SupplyParameterFromQuery]
[Parameter]
public string? AppId { get; set; }
/// <summary>
///
/// </summary>
[SupplyParameterFromQuery]
[Parameter]
public string? View { get; set; }
[Inject]
[NotNull]
private IDict? DictsService { get; set; }
/// <summary>
/// BuildRenderTree 方法
/// </summary>
/// <param name="builder"></param>
protected override void BuildRenderTree(RenderTreeBuilder builder)
{
if (!string.IsNullOrEmpty(View))
{
View = $"0-{View}";
}
var view = LoginHelper.GetCurrentLoginTheme(View ?? DictsService.GetCurrentLogin());
var componentType = view switch
{
"gitee" => typeof(AdminLoginGitee),
_ => typeof(AdminLogin)
};
builder.OpenComponent(0, componentType);
builder.AddAttribute(1, nameof(AdminLogin.ReturnUrl), ReturnUrl);
builder.AddAttribute(2, nameof(AdminLogin.AppId), AppId);
builder.CloseComponent();
builder.OpenComponent<AdminLoginFooter>(3);
builder.CloseComponent();
}
}

View File

@ -1,8 +0,0 @@
@layout LoginLayout
@page "/Account/Login"
<div class="wrap">
<div class="container">
<AdminLogin ReturnUrl="@ReturnUrl" AppId="@AppId" />
</div>
</div>

View File

@ -1,25 +0,0 @@
// 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
namespace BootstrapAdmin.Web.Pages.Account;
/// <summary>
///
/// </summary>
public partial class Login
{
/// <summary>
///
/// </summary>
[SupplyParameterFromQuery]
[Parameter]
public string? ReturnUrl { get; set; }
/// <summary>
///
/// </summary>
[SupplyParameterFromQuery]
[Parameter]
public string? AppId { get; set; }
}

View File

@ -1,24 +0,0 @@
.wrap {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
@media (min-width: 768px) {
.wrap {
background-color: #5bc0de;
background: url('../images/bg2.jpg') fixed no-repeat;
background-size: 100% 100%;
}
.container {
background: url('../images/bg3.png') no-repeat;
background-size: contain;
width: 704px;
height: 404px;
margin: 0 auto;
margin-top: calc(100vh / 2 - 190px);
}
}

View File

@ -56,6 +56,10 @@ public partial class Profiles
[NotNull] [NotNull]
private string? DefaultLogoFolder { get; set; } private string? DefaultLogoFolder { get; set; }
[CascadingParameter]
[NotNull]
private Layout? Layout { get; set; }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
@ -109,8 +113,13 @@ public partial class Profiles
private async Task OnSaveDisplayName(EditContext context) private async Task OnSaveDisplayName(EditContext context)
{ {
var ret = UserService.SaveDisplayName(CurrentUser.DisplayName, CurrentUser.UserName); var ret = UserService.SaveDisplayName(CurrentUser.UserName, CurrentUser.DisplayName);
await ShowToast(ret, "显示名称"); await ShowToast(ret, "显示名称");
if (ret)
{
AppContext.DisplayName = CurrentUser.DisplayName;
await RenderLayout("displayName");
}
} }
private async Task OnSavePassword(EditContext context) private async Task OnSavePassword(EditContext context)
@ -177,4 +186,12 @@ public partial class Profiles
await ShowToast(ret, "用户头像", "删除"); await ShowToast(ret, "用户头像", "删除");
return ret; return ret;
} }
private async Task RenderLayout(string key)
{
if (Layout.OnUpdateAsync != null)
{
await Layout.OnUpdateAsync(key);
}
}
} }

View File

@ -48,7 +48,7 @@ public partial class Settings
base.OnInitialized(); base.OnInitialized();
IsDemo = DictService.IsDemo(); IsDemo = DictService.IsDemo();
Logins = DictService.GetLogins().ToSelectedItemList(); Logins = DictService.GetLogins().ToSelectedItemList().OrderBy(i => i.Value).ToList();
Themes = DictService.GetThemes().ToSelectedItemList(); Themes = DictService.GetThemes().ToSelectedItemList();
IPLocators = DictService.GetIpLocators().ToSelectedItemList(); IPLocators = DictService.GetIpLocators().ToSelectedItemList();
IPLocators.Insert(0, new SelectedItem("", "未选择")); IPLocators.Insert(0, new SelectedItem("", "未选择"));
@ -180,9 +180,9 @@ public partial class Settings
private async Task RenderLayout(string key) private async Task RenderLayout(string key)
{ {
if (Layout.OnUpdate != null) if (Layout.OnUpdateAsync != null)
{ {
await Layout.OnUpdate(key); await Layout.OnUpdateAsync(key);
} }
} }
} }

View File

@ -2,6 +2,7 @@
// Licensed under the LGPL License, Version 3.0. See License.txt in the project root for license information. // Licensed under the LGPL License, Version 3.0. See License.txt in the project root for license information.
// Website: https://admin.blazor.zone // Website: https://admin.blazor.zone
using BootstrapAdmin.Web.Components;
using BootstrapAdmin.Web.Core; using BootstrapAdmin.Web.Core;
using BootstrapAdmin.Web.Extensions; using BootstrapAdmin.Web.Extensions;
using BootstrapAdmin.Web.Models; using BootstrapAdmin.Web.Models;
@ -32,6 +33,10 @@ public partial class Tasks
[NotNull] [NotNull]
private IDict? DictService { get; set; } private IDict? DictService { get; set; }
[Inject]
[NotNull]
private DialogService? DialogService { get; set; }
private bool IsDemo { get; set; } private bool IsDemo { get; set; }
/// <summary> /// <summary>
@ -157,9 +162,18 @@ public partial class Tasks
return Task.CompletedTask; return Task.CompletedTask;
} }
private static Task OnLog(TasksModel model) private async Task OnLog(TasksModel model)
{ {
return Task.CompletedTask; var option = new DialogOption()
{
Class = "modal-dialog-task",
Title = $"{model.Name} - 日志窗口(最新 20 条)",
Component = BootstrapDynamicComponent.CreateComponent<TaskInfo>(new Dictionary<string, object?>
{
[nameof(TaskInfo.Model)] = model
})
};
await DialogService.Show(option);
} }
private static bool OnCheckTaskStatus(TasksModel model) => model.Status != SchedulerStatus.Disabled; private static bool OnCheckTaskStatus(TasksModel model) => model.Status != SchedulerStatus.Disabled;

View File

@ -3,10 +3,10 @@
<Layout SideWidth="0" IsPage="true" IsFullSide="true" IsFixedHeader="true" <Layout SideWidth="0" IsPage="true" IsFullSide="true" IsFixedHeader="true"
ShowFooter="true" ShowGotoTop="true" ShowCollapseBar="true" Menus="@MenuItems" ShowFooter="true" ShowGotoTop="true" ShowCollapseBar="true" Menus="@MenuItems"
OnAuthorizing="@OnAuthorizing" OnErrorHandleAsync="OnErrorHandleAsync" OnAuthorizing="@OnAuthorizing" OnErrorHandleAsync="OnErrorHandleAsync"
UseTabSet="true" TabDefaultUrl="/Admin/Index" OnUpdate="OnUpdate"> UseTabSet="true" TabDefaultUrl="/Admin/Index" OnUpdateAsync="OnUpdateAsync">
<Header> <Header>
<span class="ms-3 flex-fill">Bootstrap of Blazor</span> <span class="ms-3 flex-fill">Bootstrap of Blazor</span>
<Logout ImageUrl="@Icon" DisplayName="@DisplayName" UserName="@UserName"> <Logout ImageUrl="@Icon" DisplayName="@Context.DisplayName" UserName="@UserName">
<LinkTemplate> <LinkTemplate>
<a href="/Admin/Profiles"><i class="fa fa-suitcase"></i>个人中心</a> <a href="/Admin/Profiles"><i class="fa fa-suitcase"></i>个人中心</a>
<a href="/Admin/Index"><i class="fa fa-cog"></i>设置</a> <a href="/Admin/Index"><i class="fa fa-cog"></i>设置</a>
@ -26,7 +26,7 @@
<div class="layout-user"> <div class="layout-user">
<img class="layout-avatar" src="@Icon"> <img class="layout-avatar" src="@Icon">
<div class="layout-title"> <div class="layout-title">
<span>@DisplayName</span> <span>@Context.DisplayName</span>
</div> </div>
<div class="layout-user-state"></div> <div class="layout-user-state"></div>
</div> </div>

View File

@ -74,8 +74,6 @@ namespace BootstrapAdmin.Web.Shared
private string? Footer { get; set; } private string? Footer { get; set; }
private string? DisplayName { get; set; }
private string? UserName { get; set; } private string? UserName { get; set; }
private bool Lock { get; set; } private bool Lock { get; set; }
@ -133,9 +131,8 @@ namespace BootstrapAdmin.Web.Shared
if (!string.IsNullOrEmpty(UserName)) if (!string.IsNullOrEmpty(UserName))
{ {
var user = UsersService.GetUserByUserName(UserName); var user = UsersService.GetUserByUserName(UserName);
DisplayName = user?.DisplayName ?? "未注册账户";
Context.UserName = UserName; Context.UserName = UserName;
Context.DisplayName = DisplayName; Context.DisplayName = user?.DisplayName ?? "未注册账户"; ;
Icon = string.IsNullOrEmpty(user?.Icon) ? "/images/uploader/default.jpg" : GetIcon(user.Icon); Icon = string.IsNullOrEmpty(user?.Icon) ? "/images/uploader/default.jpg" : GetIcon(user.Icon);
MenuItems = NavigationsService.GetAllMenus(UserName).ToMenus(); MenuItems = NavigationsService.GetAllMenus(UserName).ToMenus();
@ -161,7 +158,7 @@ namespace BootstrapAdmin.Web.Shared
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public Task OnUpdate(string key) public Task OnUpdateAsync(string key)
{ {
if (key == "title") if (key == "title")
{ {

View File

@ -50,4 +50,20 @@ public static class LoginHelper
return returnUrl ?? "/Admin/Index"; return returnUrl ?? "/Admin/Index";
} }
/// <summary>
/// 将字典表中的配置 1-Login-Gitee 转化为 gitee
/// </summary>
/// <param name="loginTheme"></param>
/// <returns></returns>
public static string? GetCurrentLoginTheme(string loginTheme)
{
string? ret = null;
var segs = loginTheme.Split('-');
if (segs.Length == 3)
{
ret = segs[2].ToLowerInvariant();
}
return ret;
}
} }

View File

@ -1,4 +1,4 @@
.layout.is-page .layout-side { .layout.is-page .layout-side {
color: #3f4254; color: #3f4254;
background-color: #fff; background-color: #fff;
box-shadow: 0 0 28px 0 rgb(82 63 105 / 5%); box-shadow: 0 0 28px 0 rgb(82 63 105 / 5%);
@ -26,3 +26,11 @@
background-color: #fff !important; background-color: #fff !important;
} }
} }
.modal-dialog-task ::-webkit-scrollbar-thumb {
background-color: #ffffff66;
}
.modal-dialog-task ::-webkit-scrollbar-thumb:hover {
background-color: #ffffffb3;
}

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<ItemGroup> <ItemGroup>
<PackageReference Include="BootstrapBlazor" Version="6.2.9-beta04" /> <PackageReference Include="BootstrapBlazor" Version="6.2.9-beta07" />
<PackageReference Include="Longbow.Security.Cryptography" Version="5.2.0" /> <PackageReference Include="Longbow.Security.Cryptography" Version="5.2.0" />
<PackageReference Include="Microsoft.Data.Sqlite" Version="6.0.1" /> <PackageReference Include="Microsoft.Data.Sqlite" Version="6.0.1" />
<PackageReference Include="PetaPoco.Extensions" Version="6.0.0" /> <PackageReference Include="PetaPoco.Extensions" Version="6.0.0" />

View File

@ -56,4 +56,18 @@ public class AdminService : IBootstrapAdminService
} }
return Task.FromResult(ret); return Task.FromResult(ret);
} }
/// <summary>
///
/// </summary>
/// <param name="userName"></param>
/// <param name="url"></param>
/// <param name="blockName"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public bool AuhorizingBlock(string userName, string url, string blockName)
{
// Client 暂时未使用
return true;
}
} }

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<ItemGroup> <ItemGroup>
<PackageReference Include="Bootstrap.Security.Blazor" Version="6.0.1-beta01" /> <PackageReference Include="Bootstrap.Security.Blazor" Version="6.0.1" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -9,7 +9,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="BootstrapBlazor" Version="6.2.7" /> <PackageReference Include="BootstrapBlazor" Version="6.2.9-beta07" />
<PackageReference Include="Exceptionless.AspNetCore" Version="4.6.2" /> <PackageReference Include="Exceptionless.AspNetCore" Version="4.6.2" />
<PackageReference Include="Longbow.Logging" Version="5.2.0" /> <PackageReference Include="Longbow.Logging" Version="5.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning" Version="5.0.0" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning" Version="5.0.0" />