feat: 增加码云高仿登录界面

This commit is contained in:
Argo-Tianyi 2022-01-27 15:14:09 +08:00
parent 2674c6278d
commit 6ba2ef3a96
8 changed files with 425 additions and 52 deletions

View File

@ -1,4 +1,4 @@
<div class="@LoginClassString">
<div class="wrap">
<div class="container">
<form method="post" class="form-signin" action="@PostUrl" @ref="LoginForm">
<h2 class="form-signin-heading">@Title</h2>

View File

@ -13,19 +13,40 @@ namespace BootstrapAdmin.Web.Components;
/// </summary>
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; }
@ -41,13 +62,19 @@ public partial class AdminLogin : IDisposable
[Parameter]
public string? AppId { get; set; }
/// <summary>
///
/// </summary>
[Inject]
[NotNull]
private IDict? DictsService { get; set; }
protected IDict? DictsService { get; set; }
/// <summary>
///
/// </summary>
[Inject]
[NotNull]
private ILogin? LoginService { get; set; }
protected ILogin? LoginService { get; set; }
[Inject]
[NotNull]
@ -58,7 +85,7 @@ public partial class AdminLogin : IDisposable
/// </summary>
[Inject]
[NotNull]
private WebClientService? WebClientService { get; set; }
protected WebClientService? WebClientService { get; set; }
/// <summary>
///
@ -67,16 +94,13 @@ public partial class AdminLogin : IDisposable
[NotNull]
private IIPLocatorProvider? IPLocatorProvider { get; set; }
private string? LoginView { get; set; }
private string? ClassString => CssBuilder.Default("login-wrap")
/// <summary>
///
/// </summary>
protected string? ClassString => CssBuilder.Default("login-wrap")
.AddClass("is-mobile", UseMobileLogin)
.Build();
private string? LoginClassString => CssBuilder.Default("wrap")
.AddClass(LoginView)
.Build();
/// <summary>
///
/// </summary>
@ -84,7 +108,6 @@ public partial class AdminLogin : IDisposable
{
base.OnInitialized();
LoginView = LoginHelper.GetCurrentLoginTheme(DictsService.GetCurrentLogin());
Title = DictsService.GetWebTitle();
PostUrl = QueryHelper.AddQueryString("Account/Login", new Dictionary<string, string?>
{
@ -93,7 +116,10 @@ public partial class AdminLogin : IDisposable
});
}
void OnClickSwitchButton()
/// <summary>
///
/// </summary>
protected void OnClickSwitchButton()
{
var rem = RememberPassword ? "true" : "false";
PostUrl = QueryHelper.AddQueryString(UseMobileLogin ? "Account/Mobile" : "Account/Login", new Dictionary<string, string?>()
@ -121,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();
return Task.CompletedTask;
}
void OnSignUp()
/// <summary>
///
/// </summary>
protected void OnSignUp()
{
}
void OnForgotPassword()
/// <summary>
///
/// </summary>
protected void OnForgotPassword()
{
}

View File

@ -148,3 +148,17 @@
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,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,55 @@
// 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; }
[Inject]
[NotNull]
private IDict? DictsService { get; set; }
/// <summary>
/// BuildRenderTree 方法
/// </summary>
/// <param name="builder"></param>
protected override void BuildRenderTree(RenderTreeBuilder builder)
{
var view = LoginHelper.GetCurrentLoginTheme(DictsService.GetCurrentLogin());
var componentType = view switch
{
"gitee" => typeof(AdminLoginGitee),
_ => typeof(AdminLogin)
};
builder.OpenComponent(0, componentType);
builder.AddAttribute(1, nameof(AdminLogin.ReturnUrl), ReturnUrl);
builder.AddAttribute(1, nameof(AdminLogin.AppId), AppId);
builder.CloseComponent();
}
}

View File

@ -1,4 +0,0 @@
@layout LoginLayout
@page "/Account/Login"
<AdminLogin ReturnUrl="@ReturnUrl" AppId="@AppId" />

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; }
}