添加项目文件。
This commit is contained in:
11
TechHelper.Client/Pages/Author/EmailConfirmation.razor
Normal file
11
TechHelper.Client/Pages/Author/EmailConfirmation.razor
Normal file
@@ -0,0 +1,11 @@
|
||||
@page "/emailconfirmation"
|
||||
|
||||
<h3>EmailConfirmation</h3>
|
||||
<MudButton OnClick="ConfirmToEmail"> 点击确认 </MudButton>
|
||||
|
||||
<MudPaper>
|
||||
@if (_showSuccess)
|
||||
{
|
||||
<h3> Successful </h3>
|
||||
}
|
||||
</MudPaper>
|
42
TechHelper.Client/Pages/Author/EmailConfirmation.razor.cs
Normal file
42
TechHelper.Client/Pages/Author/EmailConfirmation.razor.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
|
||||
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.WebUtilities;
|
||||
using System.Net;
|
||||
using TechHelper.Client.HttpRepository;
|
||||
|
||||
namespace TechHelper.Client.Pages.Author
|
||||
{
|
||||
public partial class EmailConfirmation
|
||||
{
|
||||
private bool _showSuccess;
|
||||
private bool _showError;
|
||||
|
||||
|
||||
[Inject]
|
||||
public IAuthenticationClientService AuthenticationClientService { get; set; }
|
||||
[Inject]
|
||||
public NavigationManager NavigationManager { get; set; }
|
||||
|
||||
|
||||
protected async void ConfirmToEmail()
|
||||
{
|
||||
_showError = _showSuccess = false;
|
||||
|
||||
var uri = NavigationManager.ToAbsoluteUri(NavigationManager.Uri);
|
||||
|
||||
var queryStrings = QueryHelpers.ParseQuery(uri.Query);
|
||||
if (queryStrings.TryGetValue("email", out var email) &&
|
||||
queryStrings.TryGetValue("token", out var token))
|
||||
{
|
||||
var result = await AuthenticationClientService.EmailConfirmationAsync(email, token);
|
||||
if (result == HttpStatusCode.OK)
|
||||
_showSuccess = true;
|
||||
else
|
||||
_showError = true;
|
||||
}
|
||||
else
|
||||
NavigationManager.NavigateTo("/");
|
||||
}
|
||||
}
|
||||
}
|
38
TechHelper.Client/Pages/Author/ForgotPassword.razor
Normal file
38
TechHelper.Client/Pages/Author/ForgotPassword.razor
Normal file
@@ -0,0 +1,38 @@
|
||||
@page "/forgotpassword"
|
||||
|
||||
<EditForm Model="@_forgotPassDto" OnValidSubmit="Submit" FormName="ForgotForm">
|
||||
<DataAnnotationsValidator />
|
||||
<MudGrid>
|
||||
<MudItem xs="12" sm="7">
|
||||
<MudCard>
|
||||
<MudCardContent>
|
||||
<MudTextField Label="Email" Class="mt-3"
|
||||
@bind-Value="_forgotPassDto.Email" For="@(() => _forgotPassDto.Email)" />
|
||||
</MudCardContent>
|
||||
<MudCardActions>
|
||||
<MudButton ButtonType="ButtonType.Submit" Variant="Variant.Filled" Color="Color.Primary" Class="ml-auto">Register</MudButton>
|
||||
</MudCardActions>
|
||||
</MudCard>
|
||||
</MudItem>
|
||||
<MudItem xs="12" sm="5">
|
||||
<MudPaper Class="pa-4 mud-height-full">
|
||||
<MudText Typo="Typo.subtitle2">Validation Summary</MudText>
|
||||
@if (_showSuccess)
|
||||
{
|
||||
<MudText Color="Color.Success">Success</MudText>
|
||||
}
|
||||
else if(_showError)
|
||||
{
|
||||
<MudText Color="@Color.Error">
|
||||
<ValidationSummary />
|
||||
</MudText>
|
||||
}
|
||||
</MudPaper>
|
||||
</MudItem>
|
||||
<MudItem xs="12">
|
||||
<MudText Typo="Typo.body2" Align="Align.Center">
|
||||
Fill out the form correctly to see the success message.
|
||||
</MudText>
|
||||
</MudItem>
|
||||
</MudGrid>
|
||||
</EditForm>
|
30
TechHelper.Client/Pages/Author/ForgotPassword.razor.cs
Normal file
30
TechHelper.Client/Pages/Author/ForgotPassword.razor.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using Entities.DTO;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using TechHelper.Client.HttpRepository;
|
||||
|
||||
namespace TechHelper.Client.Pages.Author
|
||||
{
|
||||
public partial class ForgotPassword
|
||||
{
|
||||
private ForgotPasswordDto _forgotPassDto = new ForgotPasswordDto();
|
||||
|
||||
private bool _showSuccess;
|
||||
private bool _showError;
|
||||
|
||||
[Inject]
|
||||
public IAuthenticationClientService AuthenticationClientService { get; set; }
|
||||
|
||||
private async Task Submit()
|
||||
{
|
||||
_showError = _showSuccess = false;
|
||||
|
||||
var result = await AuthenticationClientService.ForgotPasswordAsync(_forgotPassDto);
|
||||
if (result == System.Net.HttpStatusCode.OK)
|
||||
{
|
||||
_showSuccess = true;
|
||||
}
|
||||
_showError = true;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
48
TechHelper.Client/Pages/Author/Login.razor
Normal file
48
TechHelper.Client/Pages/Author/Login.razor
Normal file
@@ -0,0 +1,48 @@
|
||||
@page "/login"
|
||||
|
||||
<MudText Typo="Typo.h2"> Login Account </MudText>
|
||||
|
||||
<EditForm Model="@_userForAuth" OnValidSubmit="Logining" FormName="LoginingForm">
|
||||
<DataAnnotationsValidator />
|
||||
<MudGrid>
|
||||
<MudItem xs="12" sm="7">
|
||||
<MudCard>
|
||||
<MudCardContent>
|
||||
<MudTextField Label="Email" Class="mt-3"
|
||||
@bind-Value="_userForAuth.Email" For="@(() => _userForAuth.Email)" />
|
||||
<MudTextField Label="Password" HelperText="Choose a strong password" Class="mt-3"
|
||||
@bind-Value="_userForAuth.Password" For="@(() => _userForAuth.Password)" InputType="InputType.Password" />
|
||||
</MudCardContent>
|
||||
<MudCardActions>
|
||||
<MudButton ButtonType="ButtonType.Submit" Variant="Variant.Filled" Color="Color.Primary" Class="ml-auto">Register</MudButton>
|
||||
</MudCardActions>
|
||||
|
||||
<div class="nav-item px-3">
|
||||
<NavLink class="nav-link" href="forgotpassword">
|
||||
<span class="bi bi-plus-square-fill-nav-menu" aria-hidden="true"></span>Forgot Password
|
||||
</NavLink>
|
||||
</div>
|
||||
</MudCard>
|
||||
</MudItem>
|
||||
<MudItem xs="12" sm="5">
|
||||
<MudPaper Class="pa-4 mud-height-full">
|
||||
<MudText Typo="Typo.subtitle2">Validation Summary</MudText>
|
||||
@if (!ShowRegistrationErrors)
|
||||
{
|
||||
<MudText Color="Color.Success">Success</MudText>
|
||||
}
|
||||
else
|
||||
{
|
||||
<MudText Color="@Color.Error">
|
||||
<ValidationSummary />
|
||||
</MudText>
|
||||
}
|
||||
</MudPaper>
|
||||
</MudItem>
|
||||
<MudItem xs="12">
|
||||
<MudText Typo="Typo.body2" Align="Align.Center">
|
||||
Fill out the form correctly to see the success message.
|
||||
</MudText>
|
||||
</MudItem>
|
||||
</MudGrid>
|
||||
</EditForm>
|
51
TechHelper.Client/Pages/Author/Login.razor.cs
Normal file
51
TechHelper.Client/Pages/Author/Login.razor.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using TechHelper.Client.HttpRepository;
|
||||
using Entities.DTO;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.WebUtilities;
|
||||
|
||||
namespace TechHelper.Client.Pages.Author
|
||||
{
|
||||
public partial class Login
|
||||
{
|
||||
|
||||
private UserForAuthenticationDto _userForAuth = new UserForAuthenticationDto();
|
||||
|
||||
[Inject]
|
||||
public IAuthenticationClientService AuthenticationService { get; set; }
|
||||
|
||||
[Inject]
|
||||
public NavigationManager NavigationManager { get; set; }
|
||||
|
||||
public bool ShowRegistrationErrors { get; set; }
|
||||
public string Error { get; set; }
|
||||
|
||||
public async Task Logining()
|
||||
{
|
||||
ShowRegistrationErrors = false;
|
||||
var result = await AuthenticationService.LoginAsync(_userForAuth);
|
||||
|
||||
if (result.Is2StepVerificationRequired)
|
||||
{
|
||||
var queryParams = new Dictionary<string, object?>
|
||||
{
|
||||
["provider"] = result.Provider,
|
||||
["Email"] = _userForAuth.Email
|
||||
};
|
||||
|
||||
var uri = NavigationManager.GetUriWithQueryParameters("/twostepverification", queryParams);
|
||||
|
||||
NavigationManager.NavigateTo(uri);
|
||||
}
|
||||
else if (!result.IsAuthSuccessful)
|
||||
{
|
||||
Error = result.ErrorMessage;
|
||||
ShowRegistrationErrors = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
NavigationManager.NavigateTo("/");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
100
TechHelper.Client/Pages/Author/Registration.razor
Normal file
100
TechHelper.Client/Pages/Author/Registration.razor
Normal file
@@ -0,0 +1,100 @@
|
||||
@page "/register"
|
||||
@using System.ComponentModel.DataAnnotations
|
||||
@using Entities.Contracts
|
||||
|
||||
@inject ISnackbar Snackbar
|
||||
|
||||
<MudButton Variant="Variant.Filled" Color="Color.Primary" @onclick="@(() => Snackbar.Add("Simple Snackbar"))">
|
||||
Open Snackbar
|
||||
</MudButton>
|
||||
|
||||
|
||||
<MudText Typo="Typo.h2"> Create Account </MudText>
|
||||
|
||||
<EditForm Model="@_userForRegistration" OnValidSubmit="Register" FormName="RegistrationForm">
|
||||
<DataAnnotationsValidator />
|
||||
<MudGrid>
|
||||
<MudItem xs="12" sm="7">
|
||||
<MudCard>
|
||||
<MudCardContent>
|
||||
<MudTextField Label="Name" HelperText="Max. 8 characters"
|
||||
@bind-Value="_userForRegistration.Name" For="@(() => _userForRegistration.Email)" />
|
||||
<MudTextField Label="Email" Class="mt-3"
|
||||
@bind-Value="_userForRegistration.Email" For="@(() => _userForRegistration.Email)" />
|
||||
<MudTextField Label="Password" HelperText="Choose a strong password" Class="mt-3"
|
||||
@bind-Value="_userForRegistration.Password" For="@(() => _userForRegistration.Password)" InputType="InputType.Password" />
|
||||
<MudTextField Label="Password" HelperText="Repeat the password" Class="mt-3"
|
||||
@bind-Value="_userForRegistration.ConfirmPassword" For="@(() => _userForRegistration.ConfirmPassword)" InputType="InputType.Password" />
|
||||
<MudRadioGroup T="UserRoles" Label="Roles" @bind-Value="_userForRegistration.Roles">
|
||||
@foreach (UserRoles item in Enum.GetValues(typeof(UserRoles)))
|
||||
{
|
||||
if (item != UserRoles.Administrator)
|
||||
{
|
||||
<MudRadio Value="@item">@item.ToString()</MudRadio>
|
||||
}
|
||||
}
|
||||
</MudRadioGroup>
|
||||
<MudStack Row="true">
|
||||
|
||||
<MudTextField Label="Class"
|
||||
HelperText="Enter a class number between 1 and 14."
|
||||
Class="mt-3"
|
||||
@bind-Value="_userForRegistration.Class"
|
||||
For="@(() => _userForRegistration.Class)"
|
||||
InputType="InputType.Number"
|
||||
Required="true"
|
||||
RequiredError="Class is required." />
|
||||
|
||||
<MudTextField Label="Grade"
|
||||
HelperText="Enter a grade number between 1 and 6."
|
||||
Class="mt-3"
|
||||
@bind-Value="_userForRegistration.Grade"
|
||||
For="@(() => _userForRegistration.Grade)"
|
||||
InputType="InputType.Number"
|
||||
Required="true"
|
||||
RequiredError="Grade is required." />
|
||||
</MudStack>
|
||||
|
||||
<MudTextField Label="Phone Number"
|
||||
HelperText="Enter your phone number (optional, 7-20 digits)."
|
||||
Class="mt-3"
|
||||
@bind-Value="_userForRegistration.PhoneNumber"
|
||||
For="@(() => _userForRegistration.PhoneNumber)"
|
||||
InputType="InputType.Telephone" /> <MudTextField Label="Home Address"
|
||||
HelperText="Enter your home address (optional, max 200 characters)."
|
||||
Class="mt-3"
|
||||
@bind-Value="_userForRegistration.HomeAddress"
|
||||
For="@(() => _userForRegistration.HomeAddress)"
|
||||
Lines="3" />
|
||||
</MudCardContent>
|
||||
<MudCardActions>
|
||||
<MudButton ButtonType="ButtonType.Submit" Variant="Variant.Filled" Color="Color.Primary" Class="ml-auto">Register</MudButton>
|
||||
</MudCardActions>
|
||||
</MudCard>
|
||||
|
||||
</MudItem>
|
||||
<MudItem xs="12" sm="5">
|
||||
<MudPaper Class="pa-4 mud-height-full">
|
||||
<MudText Typo="Typo.subtitle2">Validation Summary</MudText>
|
||||
@if (success)
|
||||
{
|
||||
<MudText Color="Color.Success">Success</MudText>
|
||||
}
|
||||
else
|
||||
{
|
||||
<MudText Color="@Color.Error">
|
||||
<ValidationSummary />
|
||||
</MudText>
|
||||
}
|
||||
</MudPaper>
|
||||
</MudItem>
|
||||
<MudItem xs="12">
|
||||
<MudText Typo="Typo.body2" Align="Align.Center">
|
||||
Fill out the form correctly to see the success message.
|
||||
</MudText>
|
||||
</MudItem>
|
||||
</MudGrid>
|
||||
|
||||
</EditForm>
|
||||
|
||||
|
62
TechHelper.Client/Pages/Author/Registration.razor.cs
Normal file
62
TechHelper.Client/Pages/Author/Registration.razor.cs
Normal file
@@ -0,0 +1,62 @@
|
||||
using TechHelper.Client.HttpRepository;
|
||||
using Entities.DTO;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using MudBlazor;
|
||||
using System.Text.RegularExpressions;
|
||||
using TechHelper.Features;
|
||||
using Entities.Contracts;
|
||||
|
||||
namespace TechHelper.Client.Pages.Author
|
||||
{
|
||||
public partial class Registration
|
||||
{
|
||||
|
||||
private UserForRegistrationDto _userForRegistration = new UserForRegistrationDto();
|
||||
|
||||
[Inject]
|
||||
public IAuthenticationClientService AuthenticationService { get; set; }
|
||||
|
||||
[Inject]
|
||||
public NavigationManager NavigationManager { get; set; }
|
||||
|
||||
|
||||
|
||||
public bool ShowRegistrationErrors { get; set; }
|
||||
public string[] Errors { get; set; }
|
||||
private bool success;
|
||||
|
||||
public async Task Register()
|
||||
{
|
||||
ShowRegistrationErrors = false;
|
||||
|
||||
var result = await AuthenticationService.RegisterUserAsync(_userForRegistration);
|
||||
if (!result.IsSuccessfulRegistration)
|
||||
{
|
||||
int index = 0;
|
||||
foreach (var error in result.Errors)
|
||||
{
|
||||
Errors[index] = error;
|
||||
index++;
|
||||
}
|
||||
ShowRegistrationErrors = true;
|
||||
Snackbar.Add(Errors.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
NavigationManager.NavigateTo("/");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Inject]
|
||||
public IEmailSender emailSender { get; set; }
|
||||
|
||||
public async void SendEmail()
|
||||
{
|
||||
string eamilTo = "1928360026@qq.com";
|
||||
string authCode = "123456";
|
||||
|
||||
await emailSender.SendEmailAuthcodeAsync(eamilTo, authCode);
|
||||
}
|
||||
}
|
||||
}
|
49
TechHelper.Client/Pages/Author/ResetPassword.razor
Normal file
49
TechHelper.Client/Pages/Author/ResetPassword.razor
Normal file
@@ -0,0 +1,49 @@
|
||||
@page "/resetpassword"
|
||||
|
||||
|
||||
<MudText Typo="Typo.h2"> Reset Password Account </MudText>
|
||||
|
||||
<EditForm Model="@_resetPassDto" OnValidSubmit="Submit" FormName="ResetPasswordForm">
|
||||
<DataAnnotationsValidator />
|
||||
<MudGrid>
|
||||
<MudItem xs="12" sm="7">
|
||||
<MudCard>
|
||||
<MudCardContent>
|
||||
<MudTextField Label="Password" HelperText="Choose a strong password" Class="mt-3"
|
||||
@bind-Value="_resetPassDto.Password" For="@(() => _resetPassDto.Password)" InputType="InputType.Password" />
|
||||
<MudTextField Label="Confirm Password" HelperText="Repet Password" Class="mt-3"
|
||||
@bind-Value="_resetPassDto.ConfirmPassword" For="@(() => _resetPassDto.ConfirmPassword)" InputType="InputType.Password" />
|
||||
</MudCardContent>
|
||||
<MudCardActions>
|
||||
<MudButton ButtonType="ButtonType.Submit" Variant="Variant.Filled" Color="Color.Primary" Class="ml-auto">Register</MudButton>
|
||||
</MudCardActions>
|
||||
|
||||
<div class="nav-item px-3">
|
||||
<NavLink class="nav-link" href="forgotpassword">
|
||||
<span class="bi bi-plus-square-fill-nav-menu" aria-hidden="true"></span>Forgot Password
|
||||
</NavLink>
|
||||
</div>
|
||||
</MudCard>
|
||||
</MudItem>
|
||||
<MudItem xs="12" sm="5">
|
||||
<MudPaper Class="pa-4 mud-height-full">
|
||||
<MudText Typo="Typo.subtitle2">Validation Summary</MudText>
|
||||
@if (_showSuccess)
|
||||
{
|
||||
<MudText Color="Color.Success">Success</MudText>
|
||||
}
|
||||
else if (_showError)
|
||||
{
|
||||
<MudText Color="@Color.Error">
|
||||
<ValidationSummary />
|
||||
</MudText>
|
||||
}
|
||||
</MudPaper>
|
||||
</MudItem>
|
||||
<MudItem xs="12">
|
||||
<MudText Typo="Typo.body2" Align="Align.Center">
|
||||
Fill out the form correctly to see the success message.
|
||||
</MudText>
|
||||
</MudItem>
|
||||
</MudGrid>
|
||||
</EditForm>
|
55
TechHelper.Client/Pages/Author/ResetPassword.razor.cs
Normal file
55
TechHelper.Client/Pages/Author/ResetPassword.razor.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
using Entities.DTO;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.WebUtilities;
|
||||
using TechHelper.Client.HttpRepository;
|
||||
|
||||
|
||||
|
||||
namespace TechHelper.Client.Pages.Author
|
||||
{
|
||||
public partial class ResetPassword : ComponentBase
|
||||
{
|
||||
private readonly ResetPasswordDto _resetPassDto = new ResetPasswordDto();
|
||||
|
||||
private bool _showSuccess;
|
||||
private bool _showError;
|
||||
private IEnumerable<string> _errors;
|
||||
|
||||
|
||||
[Inject]
|
||||
public IAuthenticationClientService AuthenticationClientService { get; set; }
|
||||
[Inject]
|
||||
public NavigationManager NavigationManager { get; set; }
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
var uri = NavigationManager.ToAbsoluteUri(NavigationManager.Uri);
|
||||
var queryStrings = QueryHelpers.ParseQuery(uri.Query);
|
||||
if (queryStrings.TryGetValue("email", out var email) &&
|
||||
queryStrings.TryGetValue("token", out var token))
|
||||
{
|
||||
_resetPassDto.Email = email;
|
||||
_resetPassDto.Token = token;
|
||||
}
|
||||
else
|
||||
{
|
||||
NavigationManager.NavigateTo("/");
|
||||
}
|
||||
}
|
||||
|
||||
private async Task Submit()
|
||||
{
|
||||
_showSuccess = _showError = false;
|
||||
var result = await AuthenticationClientService.ResetPasswordAsync(_resetPassDto);
|
||||
|
||||
if(result.IsResetPasswordSuccessful)
|
||||
_showSuccess = true;
|
||||
else
|
||||
{
|
||||
_errors = result.Errors;
|
||||
_showError = true;
|
||||
}
|
||||
NavigationManager.NavigateTo("/");
|
||||
}
|
||||
}
|
||||
}
|
11
TechHelper.Client/Pages/Author/RoleDetailInfo.razor
Normal file
11
TechHelper.Client/Pages/Author/RoleDetailInfo.razor
Normal file
@@ -0,0 +1,11 @@
|
||||
@page "/rodetail"
|
||||
<h3>RoleDetailInfo</h3>
|
||||
|
||||
<AuthorizeView>
|
||||
|
||||
<MudText> @context.User.Identity.Name </MudText>
|
||||
|
||||
</AuthorizeView>
|
||||
@code {
|
||||
|
||||
}
|
47
TechHelper.Client/Pages/Author/Signout.razor
Normal file
47
TechHelper.Client/Pages/Author/Signout.razor
Normal file
@@ -0,0 +1,47 @@
|
||||
@page "/logout"
|
||||
@inject IAuthenticationClientService AuthenticationClientService
|
||||
@inject NavigationManager NavigationManager
|
||||
|
||||
<MudText>HELLO WORLD </MudText>
|
||||
|
||||
@code {
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
// 作用:这个方法在组件渲染到 UI 后被调用。
|
||||
// 意义:这是执行 JS 互操作的安全时机,特别是在启用了预渲染的情况下,
|
||||
// 此时客户端的 JS 运行时已经可用(在 Blazor Server 中通过 SignalR,在 Blazor WASM 中是 WASM 环境本身)。
|
||||
// firstRender 参数:
|
||||
// 作用:指示本次调用是否是组件首次在客户端渲染完成。
|
||||
// 意义:注销逻辑只需要执行一次。使用 firstRender = true 可以避免在组件后续状态变化触发重新渲染时重复执行。
|
||||
|
||||
if (firstRender)
|
||||
{
|
||||
Console.WriteLine("Signout: OnAfterRenderAsync - First Render. Executing Logout..."); // 可选日志
|
||||
|
||||
try
|
||||
{
|
||||
// === 在这里安全地调用依赖 JS Interop 的注销方法 ===
|
||||
// AuthenticationClientService.Logout() 方法内部会调用 _localStorageService.RemoveItemAsync(),
|
||||
// 现在是调用它的安全时机。
|
||||
|
||||
|
||||
// 注销完成后,执行导航重定向
|
||||
NavigationManager.NavigateTo("/");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// === 处理 Logout 中可能发生的异常 ===
|
||||
// 例如,如果 Local Storage 操作失败,或者 Logout 方法内部有其他错误
|
||||
Console.WriteLine($"Error during logout in Signout component: {ex.Message}");
|
||||
// 你可能需要在这里显示错误信息给用户,或者决定是否依然重定向
|
||||
// 即使注销失败,通常也希望将用户导航到某个页面(如首页或错误页)
|
||||
// 例如:
|
||||
NavigationManager.NavigateTo("/"); // 即使失败也重定向到首页
|
||||
// 或者 NavigationManager.NavigateTo("/error"); // 重定向到错误页
|
||||
}
|
||||
Console.WriteLine("Signout: OnAfterRenderAsync - First Render. Logout execution finished."); // 可选日志
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
39
TechHelper.Client/Pages/Author/TwoStepVerification.razor
Normal file
39
TechHelper.Client/Pages/Author/TwoStepVerification.razor
Normal file
@@ -0,0 +1,39 @@
|
||||
@page "/twostepverification"
|
||||
|
||||
|
||||
<EditForm Model="@_twoFactorVerificationDto" OnValidSubmit="Submit" FormName="ForgotForm">
|
||||
<DataAnnotationsValidator />
|
||||
<MudGrid>
|
||||
<MudItem xs="12" sm="7">
|
||||
<MudCard>
|
||||
<MudCardContent>
|
||||
<MudTextField Label="Email" Class="mt-3"
|
||||
@bind-Value="_twoFactorVerificationDto.TwoFactorToken" For="@(() => _twoFactorVerificationDto.TwoFactorToken)" />
|
||||
</MudCardContent>
|
||||
<MudCardActions>
|
||||
<MudButton ButtonType="ButtonType.Submit" Variant="Variant.Filled" Color="Color.Primary" Class="ml-auto">Register</MudButton>
|
||||
</MudCardActions>
|
||||
</MudCard>
|
||||
</MudItem>
|
||||
<MudItem xs="12" sm="5">
|
||||
<MudPaper Class="pa-4 mud-height-full">
|
||||
<MudText Typo="Typo.subtitle2">Validation Summary</MudText>
|
||||
@if (_showSuccess)
|
||||
{
|
||||
<MudText Color="Color.Success">Success</MudText>
|
||||
}
|
||||
else if (_showError)
|
||||
{
|
||||
<MudText Color="@Color.Error">
|
||||
<ValidationSummary />
|
||||
</MudText>
|
||||
}
|
||||
</MudPaper>
|
||||
</MudItem>
|
||||
<MudItem xs="12">
|
||||
<MudText Typo="Typo.body2" Align="Align.Center">
|
||||
Fill out the form correctly to see the success message.
|
||||
</MudText>
|
||||
</MudItem>
|
||||
</MudGrid>
|
||||
</EditForm>
|
60
TechHelper.Client/Pages/Author/TwoStepVerification.razor.cs
Normal file
60
TechHelper.Client/Pages/Author/TwoStepVerification.razor.cs
Normal file
@@ -0,0 +1,60 @@
|
||||
using Entities.DTO;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.WebUtilities;
|
||||
using TechHelper.Client.HttpRepository;
|
||||
|
||||
namespace TechHelper.Client.Pages.Author
|
||||
{
|
||||
public partial class TwoStepVerification : ComponentBase
|
||||
{
|
||||
private TwoFactorVerificationDto _twoFactorVerificationDto = new TwoFactorVerificationDto();
|
||||
|
||||
private bool _showSuccess;
|
||||
private string? _error;
|
||||
private bool _showError;
|
||||
[Inject]
|
||||
public IAuthenticationClientService AuthenticationClientService { get; set; }
|
||||
[Inject]
|
||||
public NavigationManager NavigationManager { get; set; }
|
||||
|
||||
|
||||
[SupplyParameterFromQuery]
|
||||
[Parameter]
|
||||
public string? Email { get; set; }
|
||||
|
||||
|
||||
[SupplyParameterFromQuery]
|
||||
[Parameter]
|
||||
public string? Provider { get; set; }
|
||||
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
if(string.IsNullOrEmpty(Email) || string.IsNullOrEmpty(Provider))
|
||||
{
|
||||
|
||||
NavigationManager.NavigateTo("/");
|
||||
}
|
||||
else
|
||||
{
|
||||
_twoFactorVerificationDto.Email = Email;
|
||||
_twoFactorVerificationDto.Provider = Provider;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task Submit()
|
||||
{
|
||||
_showError = false;
|
||||
|
||||
|
||||
var result = await AuthenticationClientService.LoginVerfication(_twoFactorVerificationDto);
|
||||
if(result.IsAuthSuccessful)
|
||||
NavigationManager.NavigateTo("/");
|
||||
else
|
||||
{
|
||||
_error = result.ErrorMessage;
|
||||
_showError = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user