diff --git a/BootstrapBlazorApp.Server/Components/Pages/HomePage.razor b/BootstrapBlazorApp.Server/Components/Pages/HomePage.razor
index da6c61e8ff75e915ea2cd3ac36c91dbe7715bd61..718e57c3237be42b412cf9e01aa0a73c175d982f 100644
--- a/BootstrapBlazorApp.Server/Components/Pages/HomePage.razor
+++ b/BootstrapBlazorApp.Server/Components/Pages/HomePage.razor
@@ -1,4 +1,5 @@
-@page "/"
+@page "/HomePage"
+@using System.Security.Claims
@using BootstrapBlazorApp.Server.Components.CustomComponent;
@@ -69,8 +70,11 @@
@inject NavigationManager NavigationManager
+@inject AuthenticationStateProvider AuthenticationStateProvider
+@inject SwalService SwalService
@code {
- private User user=new User();
+ private ClaimsPrincipal? _user;
+ private User user;
private List questions=new List();
private List status=new List();
private List questionsWithStatus=new List();
@@ -79,9 +83,24 @@
};
private int activeIndex = 0;
- protected override void OnInitialized()
+ protected override async Task OnInitializedAsync()
{
+ base.OnInitializedAsync();
//获取当前用户对象
+ _user = (await AuthenticationStateProvider.GetAuthenticationStateAsync()).User;
+
+ if (_user == null)
+ {
+ return;
+ }
+
+ var value = _user.FindFirst(ClaimTypes.NameIdentifier)?.Value;
+ if (value != null)
+ {
+ var user_id = int.Parse(value);
+ user = User.Find(user_id);
+ }
+
//获取题目列表
GetAllQuestions();
user=User.Where(u => u.Id == 1).First();
diff --git a/BootstrapBlazorApp.Server/Components/Pages/Login.razor b/BootstrapBlazorApp.Server/Components/Pages/Login.razor
new file mode 100644
index 0000000000000000000000000000000000000000..3cbdb70e4a80ab22a7127cc948c0955c0693fc0a
--- /dev/null
+++ b/BootstrapBlazorApp.Server/Components/Pages/Login.razor
@@ -0,0 +1,78 @@
+@page "/"
+@page "/Login"
+
+@using BootstrapBlazorApp.Server.Pojo
+@inject AuthenticationStateProvider AuthenticationStateProvider
+@layout LoginLayout
+@inject AjaxService AjaxService
+@inject SwalService SwalService
+@inject NavigationManager NavigationManager
+
+@attribute [AllowAnonymous]
+
+@code
+{
+ private LoginVo LoginVo { get; set; } = new LoginVo();
+
+ private async Task OnValidSubmit(EditContext arg)
+ {
+ StateHasChanged();
+ try
+ {
+ var document = await AjaxService.InvokeAsync(new AjaxOption()
+ {
+ Url = "/api/Account/Login",
+ Data = LoginVo
+ });
+
+ if (document?.RootElement.GetProperty("code").GetInt32() == 200)
+ {
+ await AjaxService.Goto("/HomePage"); //交换cookie
+ }
+ else
+ {
+ await SwalService.Show(new SwalOption()
+ {
+ Category = SwalCategory.Error,
+ Content = document?.RootElement.GetProperty("message").GetString() ?? "系统异常",
+ Title = "登录失败"
+ });
+ }
+ }
+ catch (Exception ex)
+ {
+ // 处理网络请求或其他异常
+ await SwalService.Show(new SwalOption()
+ {
+ Category = SwalCategory.Error,
+ Content = "发生错误:" + ex.Message,
+ Title = "系统错误"
+ });
+ }
+ }
+
+
+
+ protected override async Task OnInitializedAsync()
+ {
+ await base.OnInitializedAsync();
+ var user = (await AuthenticationStateProvider.GetAuthenticationStateAsync()).User;
+ if (user?.Identity?.IsAuthenticated == true)
+ {
+ NavigationManager.NavigateTo("/HomePage");
+ }
+ }
+}
\ No newline at end of file
diff --git a/BootstrapBlazorApp.Server/Components/Pages/Login.razor.css b/BootstrapBlazorApp.Server/Components/Pages/Login.razor.css
new file mode 100644
index 0000000000000000000000000000000000000000..61185820eec6f945cbc945f218bd10b158128f5b
--- /dev/null
+++ b/BootstrapBlazorApp.Server/Components/Pages/Login.razor.css
@@ -0,0 +1,51 @@
+.login-item-gitee {
+ --bs-border-radius: 6px;
+ --login-padding-x: .75rem;
+ margin: 1.5rem auto;
+}
+
+.login-item-gitee a {
+ color: #005980;
+}
+
+.login-item-gitee .login-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: flex-end;
+ margin-bottom: 1.5rem;
+}
+
+.login-item-gitee .login-header > span {
+ font-size: 1.5rem;
+ font-weight: bold;
+}
+
+.login-item-gitee .login-header > span {
+ font-size: 1.5rem;
+ font-weight: bold;
+}
+
+.login-item-gitee .login-sms {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+}
+
+.login-item-gitee .login-sms > a {
+ padding: var(--login-padding-y) var(--login-padding-x);
+ margin-bottom: 1rem;
+}
+
+.login-item-gitee .login-oauth {
+ display: flex;
+ justify-content: space-between;
+}
+
+.login-item-gitee .login-oauth i {
+ font-size: 2rem;
+ color: #485585;
+}
+
+.login-item-gitee ::deep .divider {
+ --bb-divider-margin: 2rem;
+}
diff --git a/BootstrapBlazorApp.Server/Components/Pages/PersonalPage.razor b/BootstrapBlazorApp.Server/Components/Pages/PersonalPage.razor
index ec906f36a9a5f8b993b2de14b6882ef12dcd3a7d..08df012417331c964bfdbcc9b0967ea6fceff49e 100644
--- a/BootstrapBlazorApp.Server/Components/Pages/PersonalPage.razor
+++ b/BootstrapBlazorApp.Server/Components/Pages/PersonalPage.razor
@@ -1,5 +1,6 @@
-@page "/PersonalPage"
+@page "/PersonalPage"
@inject NavigationManager NavigationManager
+@using System.Security.Claims
@using Newtonsoft.Json;
@using BootstrapBlazorApp.Server.Components.CustomComponent
@@ -9,13 +10,6 @@
IsPage="true">
- @*logo*@
- @*
-

-
- 码上面试
-
-
*@
@@ -82,7 +76,8 @@
@* 退出 *@
-
+ @**@
+
@@ -188,6 +183,7 @@
+@inject AuthenticationStateProvider AuthenticationStateProvider
@code
{
private bool EditMode = false;
@@ -201,38 +197,48 @@
private int mediumNum = 2;
private int hardNum = 1;
+ private ClaimsPrincipal? _user;
//用户信息
+ private User user;
- private User user=new User()
- {
- Id=1,
- UserName = "bmmm",
- Password = "123456",
- NickName = "面包面面",
- Avatar = "https://ww3.sinaimg.cn/mw690/d315af46ly1hnn5btbjr5j20j60j7mzv.jpg",
- Introduction = "我是bmm,来自武汉大学"
- };
-
- private List users = [];
- private User newUser = new();
- private List questions = [];
- private List answerDetails= [];
- private List questionsWithStatus = [];
- protected override void OnInitialized()
+ private List users = new List();
+ private User newUser = new User();
+ private List questions = new List();
+ private List answerDetails= new List();
+ private List questionsWithStatus = new List();
+
+ protected override async Task OnInitializedAsync()
{
+ base.OnInitialized();
+ //获取当前用户对象
+ _user = (await AuthenticationStateProvider.GetAuthenticationStateAsync()).User;
+
+ if (_user == null)
+ {
+ return;
+ }
+
+ var value = _user.FindFirst(ClaimTypes.NameIdentifier)?.Value;
+ if (value != null)
+ {
+ var user_id = int.Parse(value);
+ user = User.Find(user_id);
+ }
+
GetAllHistory();
}
private void GetAllHistory()
{
answerDetails=AnswerDetail.Where(a=> a.UserId == user.Id).ToList();
- /*questions= Question.Where(q=> q.Id == answerDetails[0].QuestionId).ToList();*/
- var questionIds = answerDetails.Select(ad => ad.QuestionId).Distinct();
- questions = Question
- .Where(q => questionIds.Contains(q.Id))
- .Take(6)
- .ToList();
+ if(answerDetails!=null&&answerDetails.Count>0){
+ var questionIds = answerDetails.Select(ad => ad.QuestionId).Distinct();
+ questions = Question
+ .Where(q => questionIds.Contains(q.Id))
+ .Take(6)
+ .ToList();
+ }
}
private void Edit()
diff --git a/BootstrapBlazorApp.Server/Components/Pages/QDetail.razor b/BootstrapBlazorApp.Server/Components/Pages/QDetail.razor
index 2f48ba5d1425fe763769f1c5acce7271b5da6de4..44d13d4435fde05a3ca5a91f4fd3f48bce328074 100644
--- a/BootstrapBlazorApp.Server/Components/Pages/QDetail.razor
+++ b/BootstrapBlazorApp.Server/Components/Pages/QDetail.razor
@@ -1,4 +1,5 @@
@page "/qdetail/{Qid}"
+@using System.Security.Claims
@using BootstrapBlazorApp.Server.Components.CustomComponent
@using COSXML.Model.Tag
@@ -126,12 +127,14 @@
@inject NavigationManager NavigationManager
+@inject AuthenticationStateProvider AuthenticationStateProvider
@code {
[Parameter]
public string Qid { get; set; }
public User user { get; set; }
-
+
+ private ClaimsPrincipal? _user;
private Question question { get; set; }
private bool Staus { get; set; }
private string baseArea="30%";
@@ -146,14 +149,20 @@
{
base.OnInitialized();
//获得用户信息
- user=new User()
+ _user = (await AuthenticationStateProvider.GetAuthenticationStateAsync()).User;
+
+ if (_user == null)
+ {
+ return;
+ }
+
+ var value = _user.FindFirst(ClaimTypes.NameIdentifier)?.Value;
+ if (value != null)
{
- Id = 1,
- UserName = "bmmm",
- Password = "123456",
- NickName = "面包面面",
- Avatar = "https://ww3.sinaimg.cn/mw690/d315af46ly1hnn5btbjr5j20j60j7mzv.jpg"
- };
+ var user_id = int.Parse(value);
+ user = User.Find(user_id);
+ }
+
//获得题目信息
int qid = Convert.ToInt32(Qid);
//查询数据库获得题目详细信息
diff --git a/BootstrapBlazorApp.Server/Components/Pages/Register.razor b/BootstrapBlazorApp.Server/Components/Pages/Register.razor
new file mode 100644
index 0000000000000000000000000000000000000000..64125a543d2b5649cddc1f0cc89ca1c1e53d2e89
--- /dev/null
+++ b/BootstrapBlazorApp.Server/Components/Pages/Register.razor
@@ -0,0 +1,78 @@
+@page "/Register"
+@using BootstrapBlazorApp.Server.Pojo
+@layout LoginLayout
+@inject AjaxService AjaxService
+@inject SwalService SwalService
+@inject NavigationManager NavigationManager
+
+@attribute [AllowAnonymous]
+
+
+
欢迎使用码上面试
+ 用户注册
+
+
+
+
+
+
+
+
+
+
+
+
+
+@code
+{
+ private RegisterVo RegisterVo { get; set; } = new RegisterVo();
+
+ private void ToLogin()
+ {
+ NavigationManager.NavigateTo("/Login");
+ }
+
+ private async Task OnValidSubmit(EditContext arg)
+ {
+ try
+ {
+ // 使用Ajax调用注册API
+ var document = await AjaxService.InvokeAsync(new AjaxOption()
+ {
+ Url = "/api/Account/Register",
+ Data = RegisterVo // 直接传递RegisterVo对象作为数据
+ });
+
+ if (document?.RootElement.GetProperty("code").GetInt32() == 200)
+ {
+ await SwalService.Show(new SwalOption()
+ {
+ Category = SwalCategory.Success,
+ Content = "注册成功!",
+ Title = "欢迎"
+ });
+ //此时无需保存交换cookie,故直接使用navigation跳转即可
+ NavigationManager.NavigateTo("/Login");
+ }
+ else
+ {
+ await SwalService.Show(new SwalOption()
+ {
+ Category = SwalCategory.Error,
+ Content = document?.RootElement.GetProperty("message").GetString() ?? "系统异常",
+ Title = "注册失败"
+ });
+ }
+ }
+ catch (Exception ex)
+ {
+ // 处理网络请求或其他异常
+ await SwalService.Show(new SwalOption()
+ {
+ Category = SwalCategory.Error,
+ Content = "发生错误:" + ex.Message,
+ Title = "系统错误"
+ });
+ }
+ }
+}
\ No newline at end of file
diff --git a/BootstrapBlazorApp.Server/Components/Pages/Register.razor.css b/BootstrapBlazorApp.Server/Components/Pages/Register.razor.css
new file mode 100644
index 0000000000000000000000000000000000000000..a331fbcd5fba8e6ff088c36703bf6e20513a0442
--- /dev/null
+++ b/BootstrapBlazorApp.Server/Components/Pages/Register.razor.css
@@ -0,0 +1,60 @@
+.login-item-gitee {
+ --bs-border-radius: 6px;
+ --login-padding-x: .75rem;
+ margin: 1.5rem auto;
+ padding: 0 1.5rem;
+}
+
+.login-item-gitee a {
+ color: #005980;
+}
+
+.login-item-gitee .login-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: flex-end;
+ margin-bottom: 1.5rem;
+}
+
+.login-item-gitee .login-header > span {
+ font-size: 1.5rem;
+ font-weight: bold;
+}
+
+.login-item-gitee .login-header > span {
+ font-size: 1.5rem;
+ font-weight: bold;
+}
+
+.login-item-gitee .login-sms {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+}
+
+.login-item-gitee .login-sms > a {
+ padding: var(--login-padding-y) var(--login-padding-x);
+ margin-bottom: 1rem;
+}
+
+.login-item-gitee .login-oauth {
+ display: flex;
+ justify-content: space-between;
+}
+
+.login-item-gitee .login-oauth i {
+ font-size: 2rem;
+ color: #485585;
+}
+
+.login-item-gitee ::deep .divider {
+ --bb-divider-margin: 2rem;
+}
+.login-item-floating {
+ --login-padding-x: 1rem;
+ --bs-border-radius: 10px;
+}
+
+.text-dark{
+ font-weight: bold;
+}
\ No newline at end of file
diff --git a/BootstrapBlazorApp.Server/Components/Pages/Star.razor b/BootstrapBlazorApp.Server/Components/Pages/Star.razor
index 0debf76ee81aab933c16d3027530617c4397ac70..047af718ce83221d5f17f4a09bcd70778a3a947b 100644
--- a/BootstrapBlazorApp.Server/Components/Pages/Star.razor
+++ b/BootstrapBlazorApp.Server/Components/Pages/Star.razor
@@ -1,4 +1,5 @@
@page "/Star"
+@using System.Security.Claims
@inject NavigationManager NavigationManager
@using BootstrapBlazorApp.Server.Components.CustomComponent;
@@ -61,22 +62,37 @@
+@inject AuthenticationStateProvider AuthenticationStateProvider
@code {
+ private ClaimsPrincipal? _user;
private string PlaceHolderText = "请输入用户名";
- private User user=new User()
- {
- Id=1,
- UserName = "bmmm",
- Password = "123456",
- NickName = "面包面面",
- Avatar = "https://ww3.sinaimg.cn/mw690/d315af46ly1hnn5btbjr5j20j60j7mzv.jpg",
- Introduction = "我是bmm,来自武汉大学,嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻"
- };
+ private User user;
+ private User newUser=new User();
private List stars= new List();
private List questionWithStatus = new List();
public List questions = new List();
+ protected override async Task OnInitializedAsync()
+ {
+ base.OnInitialized();
+ //获取当前用户对象
+ _user = (await AuthenticationStateProvider.GetAuthenticationStateAsync()).User;
+
+ if (_user == null)
+ {
+ return;
+ }
+
+ var value = _user.FindFirst(ClaimTypes.NameIdentifier)?.Value;
+ if (value != null)
+ {
+ var user_id = int.Parse(value);
+ user = User.Find(user_id);
+ }
+
+ }
+
private Task OnSearch(string searchText)
{
questionWithStatus.Clear();
diff --git a/BootstrapBlazorApp.Server/Components/Shared/LoginLayout.razor b/BootstrapBlazorApp.Server/Components/Shared/LoginLayout.razor
new file mode 100644
index 0000000000000000000000000000000000000000..c45fb3ae269bd60b2ff40846aedd164565dd1727
--- /dev/null
+++ b/BootstrapBlazorApp.Server/Components/Shared/LoginLayout.razor
@@ -0,0 +1,24 @@
+@using System.Diagnostics.CodeAnalysis
+@using BootstrapBlazorApp.Server.Pojo
+@inherits LayoutComponentBase
+@layout TutorialsLayout
+
+
+
+
+
+
+
+ @Body
+
+
+
+
+
+
+
+@code
+{
+[NotNull]
+private LoginVo? Model { get; set; } = new();
+}
\ No newline at end of file
diff --git a/BootstrapBlazorApp.Server/Components/Shared/LoginLayout.razor.css b/BootstrapBlazorApp.Server/Components/Shared/LoginLayout.razor.css
new file mode 100644
index 0000000000000000000000000000000000000000..99cbd45824bc3495a9462a2ce137e78b81a0abc2
--- /dev/null
+++ b/BootstrapBlazorApp.Server/Components/Shared/LoginLayout.razor.css
@@ -0,0 +1,34 @@
+.container {
+ --login-max-width: 540px;
+ --login-padding-x: 1.5rem;
+ --login-padding-y: .75rem;
+ --bs-border-radius: 23px;
+ max-width: var(--login-max-width);
+ margin: 0 auto;
+}
+
+::deep h4 {
+ margin-bottom: 1.5rem;
+}
+
+::deep .form-control {
+ --bb-form-control-padding: var(--login-padding-y) var(--login-padding-x);
+ font-size: .875rem;
+ margin-bottom: 1rem;
+}
+
+::deep .btn {
+ --bs-btn-padding-x: var(--login-padding-x);
+ --bs-btn-padding-y: var(--login-padding-y);
+ width: 100%;
+ margin-bottom: 1rem;
+}
+
+::deep .btn:first-of-type {
+ margin-bottom: 0;
+}
+
+::deep .form-check {
+ padding: var(--login-padding-y) var(--login-padding-x);
+ margin-bottom: 1rem;
+}
diff --git a/BootstrapBlazorApp.Server/Components/Shared/MainLayout.razor b/BootstrapBlazorApp.Server/Components/Shared/MainLayout.razor
index 4c0aaaeafc189806c382dc4c406e2db3060fb8ef..8a6e00ec3168975933a594522aaed14924ecfc69 100644
--- a/BootstrapBlazorApp.Server/Components/Shared/MainLayout.razor
+++ b/BootstrapBlazorApp.Server/Components/Shared/MainLayout.razor
@@ -1,6 +1,9 @@
@inherits LayoutComponentBase
-
-
- @Body
-
+
+
+
+ @Body
+
+
+
diff --git a/BootstrapBlazorApp.Server/Components/Shared/TutorialsLayout.razor b/BootstrapBlazorApp.Server/Components/Shared/TutorialsLayout.razor
new file mode 100644
index 0000000000000000000000000000000000000000..ff872258e1eb5da44a035874efd8a5a6478fb203
--- /dev/null
+++ b/BootstrapBlazorApp.Server/Components/Shared/TutorialsLayout.razor
@@ -0,0 +1,9 @@
+@inherits LayoutComponentBase
+
+
+
\ No newline at end of file
diff --git a/BootstrapBlazorApp.Server/Components/Shared/TutorialsLayout.razor.css b/BootstrapBlazorApp.Server/Components/Shared/TutorialsLayout.razor.css
new file mode 100644
index 0000000000000000000000000000000000000000..48e1524b33e7865780d92a464abcce4c605ae7f0
--- /dev/null
+++ b/BootstrapBlazorApp.Server/Components/Shared/TutorialsLayout.razor.css
@@ -0,0 +1,50 @@
+.section {
+ --bb-sidebar-width: 0;
+}
+
+.main {
+ padding: 1rem;
+}
+
+.sidebar-title {
+ height: 50px;
+ align-items: center;
+ padding: 1rem;
+ border-bottom: solid 1px var(--bs-border-color);
+ display: none;
+}
+
+.sidebar-text {
+ font-weight: 700;
+}
+
+::deep p:last-child {
+ margin-bottom: 0;
+}
+
+@media (min-width: 768px) {
+ .section {
+ --bb-sidebar-width: 300px;
+ display: flex;
+ flex-direction: row;
+ -webkit-font-smoothing: antialiased;
+ }
+
+ .sidebar-title {
+ display: flex;
+ }
+
+ .sidebar {
+ width: var(--bb-sidebar-width);
+ height: calc(100vh);
+ position: sticky;
+ top: 0;
+ border-right: solid 1px var(--bs-border-color);
+ margin-top: calc(var(--bs-header-height) * -1);
+ }
+
+ .main {
+ flex: 1;
+ height: 100%;
+ }
+}
diff --git a/BootstrapBlazorApp.Server/Components/_Imports.razor b/BootstrapBlazorApp.Server/Components/_Imports.razor
index 40bed337921aabab6fa00c6b9ab83f68a9258f40..bb7b2d5869d7d4b359e677fc97a308012eb7d8ba 100644
--- a/BootstrapBlazorApp.Server/Components/_Imports.razor
+++ b/BootstrapBlazorApp.Server/Components/_Imports.razor
@@ -14,4 +14,6 @@
@using System.ComponentModel
@using System.ComponentModel.DataAnnotations
-@using System.Net.Http
\ No newline at end of file
+@using System.Net.Http
+
+@attribute [Authorize]
\ No newline at end of file
diff --git a/BootstrapBlazorApp.Server/Controllers/AccountController.cs b/BootstrapBlazorApp.Server/Controllers/AccountController.cs
new file mode 100644
index 0000000000000000000000000000000000000000..205b910155a92af8e9a7987a30403297d0f25107
--- /dev/null
+++ b/BootstrapBlazorApp.Server/Controllers/AccountController.cs
@@ -0,0 +1,92 @@
+using System.Security.Claims;
+using BootstrapBlazorApp.Server.Data;
+using BootstrapBlazorApp.Server.Pojo;
+using BootstrapBlazor.Components;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Authentication;
+using Microsoft.AspNetCore.Authentication.Cookies;
+using BootstrapBlazorApp.Server.Utils;
+using Microsoft.AspNetCore.Authorization;
+
+namespace BootstrapBlazorApp.Server.Controllers;
+
+[ApiController]
+[Route("/api/[controller]/[action]")]
+public class AccountController:ControllerBase
+{
+ //注入相关的数据库服务实例使用
+ private readonly IDataService _userService;
+
+ //自动查找注册到容器中的IDataService服务
+ public AccountController(IDataService userService)
+ {
+ _userService = userService;
+ }
+ //增加API方法
+ [HttpPost]
+ public async Task