feat: 重构 AdminLogin 组件

This commit is contained in:
Argo-Tianyi 2022-01-06 08:53:59 +08:00
parent e1a6e7379d
commit 0d0443fddb
9 changed files with 137 additions and 69 deletions

View File

@ -1,21 +1,15 @@
<form method="post" class="form-signin" data-mobile="@UseMobileLogin" action="@PostUrl" @ref="LoginForm">
<form method="post" class="form-signin" action="@PostUrl" @ref="LoginForm">
<h2 class="form-signin-heading">@Title</h2>
<div class="login-wrap">
@if (UseMobileLogin)
<div class="@ClassString">
@if (AllowMobile)
{
<SMSButton />
}
else
{
<BootstrapInputGroup>
<BootstrapInputGroupIcon Icon="fa fa-fw fa-user" />
<BootstrapInput TValue="string" name="userName" maxlength="16" title="登录账号不可为空" Value="@UserName" IsAutoFocus="true" PlaceHolder="登录账号" />
</BootstrapInputGroup>
<BootstrapInputGroup class="mt-3">
<BootstrapInputGroupIcon Icon="fa fa-fw fa-lock" />
<BootstrapPassword name="password" title="登录密码不可为空" PlaceHolder="登录密码" Value="@Password" />
</BootstrapInputGroup>
<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">

View File

@ -26,14 +26,14 @@ public partial class AdminLogin
[NotNull]
private IDict? DictsService { get; set; }
private string? UserName { get; set; }
private string? Password { get; set; }
[Inject]
[NotNull]
private IJSRuntime? JSRuntime { get; set; }
private string? ClassString => CssBuilder.Default("login-wrap")
.AddClass("is-mobile", UseMobileLogin)
.Build();
/// <summary>
///
/// </summary>
@ -44,11 +44,6 @@ public partial class AdminLogin
Title = DictsService.GetWebTitle();
PostUrl = QueryHelper.AddQueryString("/Account/Login", "ReturnUrl", ReturnUrl ?? "");
#if DEBUG
UserName = "Admin";
Password = "123789";
#endif
}
void OnClickSwitchButton()

View File

@ -17,6 +17,15 @@
border: 1px solid #84bbe2;
}
.login-sms,
.is-mobile .login-up {
display: none;
}
.is-mobile .login-sms {
display: block;
}
::deep .btn-login {
background: #f67a6e;
border-color: transparent;

View File

@ -1,11 +1,11 @@
<BootstrapInputGroup>
<BootstrapInputGroupIcon Icon="fa fa-fw fa-user" />
<BootstrapInput @bind-Value="@PhoneNumber" type="tel" name="phone" maxlength="11" PlaceHolder="手机号码" />
<BootstrapInput @bind-Value="@PhoneNumber" type="tel" name="phone" maxlength="11" data-bs-toggle="tooltip" title="手机号不可为空" PlaceHolder="手机号码" />
</BootstrapInputGroup>
<BootstrapInputGroup class="mt-3">
<BootstrapInputGroupIcon Icon="fa fa-fw fa-lock" />
<BootstrapInput TValue="string" typeof="number" name="code" maxlength="4" IsDisabled="IsSendCode" @bind-Value="@Code" PlaceHolder="验证码" />
<BootstrapInput TValue="string" type="number" name="code" maxlength="4" data-bs-toggle="tooltip" title="验证码不能为空" IsDisabled="IsSendCode" @bind-Value="@Code" PlaceHolder="验证码" />
<Button class="btn-sms" Text="@SendCodeText" OnClick="OnSendCode" LoadingIcon="" IsAsync="true">
<Tooltip Title="点击发送验证码" Placement="Placement.Top" />
</Button>

View File

@ -2,7 +2,7 @@
namespace BootstrapAdmin.Web.Components;
public partial class SMSButton : IDisposable
public partial class SMSLogin : IDisposable
{
private bool IsSendCode { get; set; } = true;

View File

@ -0,0 +1,8 @@
<BootstrapInputGroup>
<BootstrapInputGroupIcon Icon="fa fa-fw fa-user" />
<BootstrapInput TValue="string" name="userName" maxlength="16" title="登录账号不可为空" Value="@UserName" IsAutoFocus="true" PlaceHolder="登录账号" />
</BootstrapInputGroup>
<BootstrapInputGroup class="mt-3">
<BootstrapInputGroupIcon Icon="fa fa-fw fa-lock" />
<BootstrapPassword name="password" title="登录密码不可为空" PlaceHolder="登录密码" Value="@Password" />
</BootstrapInputGroup>

View File

@ -0,0 +1,18 @@
namespace BootstrapAdmin.Web.Components;
public partial class UserLogin
{
private string? UserName { get; set; }
private string? Password { get; set; }
protected override void OnInitialized()
{
base.OnInitialized();
#if DEBUG
UserName = "Admin";
Password = "123789";
#endif
}
}

View File

@ -1,4 +1,5 @@
using BootstrapAdmin.Web.Core;
using BootstrapAdmin.Web.Services.SMS;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using RouteAttribute = Microsoft.AspNetCore.Mvc.RouteAttribute;
@ -11,22 +12,38 @@ namespace BootstrapAdmin.Web.Controllers.api;
public class LoginController : ControllerBase
{
/// <summary>
/// JWT 登陆认证接口
/// 登录认证接口
/// </summary>
/// <param name="config"></param>
/// <param name="user"></param>
/// <returns></returns>
[HttpPost()]
public AuthenticateResult Post(LoginUser user, [FromServices] IUser userService)
public AuthenticateResult Post(LoginUser user, [FromQuery] bool mobile,
[FromServices] IUser userService,
[FromServices] ISMSProvider provider)
{
var result = new AuthenticateResult();
if (!string.IsNullOrEmpty(user.UserName) && !string.IsNullOrEmpty(user.Password))
if (mobile)
{
result.Authenticated = userService.Authenticate(user.UserName, user.Password);
if (!string.IsNullOrEmpty(user.UserName) && !string.IsNullOrEmpty(user.Password))
{
result.Authenticated = provider.Validate(user.UserName, user.Password);
}
if (!result.Authenticated)
{
result.Error = "验证码不正确";
}
}
if (!result.Authenticated)
else
{
result.Error = "用户名或者密码错误";
if (!string.IsNullOrEmpty(user.UserName) && !string.IsNullOrEmpty(user.Password))
{
result.Authenticated = userService.Authenticate(user.UserName, user.Password);
}
if (!result.Authenticated)
{
result.Error = "用户名或者密码错误";
}
}
return result;
}

View File

@ -13,7 +13,7 @@
$('[data-bs-toggle="tooltip"]').tooltip();
// handle input event
$('input').on('change', function () {
$form.on('change', 'input', function () {
// dispose login wrap error
$login.tooltip('dispose');
@ -36,48 +36,75 @@
$('.btn-login').on('click', function (e) {
e.preventDefault();
var mobile = $form.attr('data-mobile') === '';
var mobile = $form.find('.is-mobile').length === 1;
var userName = "";
var password = "";
if (mobile) {
$form.submit();
var $phone = $form.find('[name="phone"]');
var $code = $form.find('[name="code"]');
userName = $phone.val();
password = $code.val();
if (userName === '') {
$phone.trigger("change");
return;
}
if (password === '') {
$code.trigger("change");
return;
}
}
else {
var $userName = $form.find('[name="userName"]');
var $password = $form.find('[name="password"]');
var userName = $userName.val();
var password = $password.val();
if (userName !== '' && password !== '') {
var postData = JSON.stringify({ userName, password });
// call webapi authenticate
$.ajax({
url: $.formatUrl(url),
data: postData,
method: 'POST',
contentType: 'application/json',
dataType: 'json',
crossDomain: false,
success: function (result) {
if (result.authenticated) {
$form.submit();
}
else {
console.log(result.error);
var $login = $('.login-wrap').addClass('is-invalid').tooltip({
title: result.error
});
var handler = window.setTimeout(function () {
if (handler) {
window.clearTimeout(handler);
}
$login.tooltip('show');
}, 100);
}
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
console.log(errorThrown);
}
});
userName = $userName.val();
password = $password.val();
if (userName === '') {
$userName.trigger("change");
return;
}
if (password === '') {
password.trigger("change");
return;
}
}
var authenticate = function (postData, mobile) {
var postUrl = url + '?mobile=' + mobile;
$.ajax({
url: $.formatUrl(postUrl),
data: postData,
method: 'POST',
contentType: 'application/json',
dataType: 'json',
crossDomain: false,
success: function (result) {
if (result.authenticated) {
$form.submit();
}
else {
console.log(result.error);
var $login = $('.login-wrap').addClass('is-invalid').tooltip({
title: result.error
});
var handler = window.setTimeout(function () {
if (handler) {
window.clearTimeout(handler);
}
$login.tooltip('show');
}, 100);
}
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
console.log(errorThrown);
}
});
}
var postData = JSON.stringify({ userName, password });
// call webapi authenticate
authenticate(postData, mobile);
});
}
});