This commit is contained in:
		
							
								
								
									
										8
									
								
								EmailLib/Dockerfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								EmailLib/Dockerfile
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
# ./EmailLib/Dockerfile
 | 
			
		||||
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS eamillib
 | 
			
		||||
WORKDIR /src
 | 
			
		||||
COPY ../EmailLib/*.csproj ./EmailLib/
 | 
			
		||||
RUN dotnet restore "EmailLib/EmailLib.csproj"
 | 
			
		||||
 | 
			
		||||
COPY ../EmailLib/. ./EmailLib/
 | 
			
		||||
RUN dotnet publish "EmailLib/EmailLib.csproj" -c Release -o /publish
 | 
			
		||||
@@ -21,7 +21,7 @@ namespace Entities.Contracts
 | 
			
		||||
		部编版,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public enum Grade : byte
 | 
			
		||||
	public enum GradeEnum : byte
 | 
			
		||||
	{
 | 
			
		||||
		Unknown = 0,
 | 
			
		||||
		一年级 = 1,
 | 
			
		||||
@@ -69,14 +69,25 @@ namespace Entities.Contracts
 | 
			
		||||
 | 
			
		||||
	public enum AssignmentStructType : byte
 | 
			
		||||
	{
 | 
			
		||||
		Root,
 | 
			
		||||
		Question,
 | 
			
		||||
		Composite,
 | 
			
		||||
		Group,
 | 
			
		||||
		Struct,
 | 
			
		||||
		SubQuestion,
 | 
			
		||||
		Option
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	public enum ExamType : byte
 | 
			
		||||
	{
 | 
			
		||||
		MidtermExam,       // 期中
 | 
			
		||||
		FinalExam,         // 期末
 | 
			
		||||
		MonthlyExam,       // 月考
 | 
			
		||||
		WeeklyExam,        // 周考
 | 
			
		||||
		DailyTest,         // 平时测试
 | 
			
		||||
		AITest,            // AI测试
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	public enum SubmissionStatus
 | 
			
		||||
	{
 | 
			
		||||
 
 | 
			
		||||
@@ -41,6 +41,10 @@ namespace Entities.Contracts
 | 
			
		||||
		[Column("score")]
 | 
			
		||||
		public float Score { get; set; }
 | 
			
		||||
 | 
			
		||||
		public string Name { get; set; } = string.Empty;
 | 
			
		||||
 | 
			
		||||
		public ExamType ExamType { get; set; } = ExamType.DailyTest;
 | 
			
		||||
 | 
			
		||||
		[Column("created_by")]
 | 
			
		||||
		public Guid CreatorId { get; set; }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -48,7 +48,7 @@ namespace Entities.Contracts
 | 
			
		||||
		[Column("lesson")]
 | 
			
		||||
		public Guid? LessonId { get; set; }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		
 | 
			
		||||
		[Required]
 | 
			
		||||
		[Column("created_by")]
 | 
			
		||||
		public Guid CreatorId { get; set; }
 | 
			
		||||
 
 | 
			
		||||
@@ -49,6 +49,12 @@ namespace Entities.Contracts
 | 
			
		||||
		[Column("deleted")]
 | 
			
		||||
		public bool IsDeleted { get; set; }
 | 
			
		||||
 | 
			
		||||
		public byte TotalQuesNum { get; set; }
 | 
			
		||||
 | 
			
		||||
		public byte ErrorQuesNum { get; set; }
 | 
			
		||||
 | 
			
		||||
		public byte TotalScore { get; set; }
 | 
			
		||||
 | 
			
		||||
		[Required]
 | 
			
		||||
		[Column("status")]
 | 
			
		||||
		public SubmissionStatus Status { get; set; }
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,7 @@ namespace Entities.Contracts
 | 
			
		||||
		[Key]
 | 
			
		||||
		public Guid Id { get; set; }
 | 
			
		||||
 | 
			
		||||
		public Grade Grade { get; set; } = Grade.Unknown;
 | 
			
		||||
		public GradeEnum Grade { get; set; } = GradeEnum.Unknown;
 | 
			
		||||
 | 
			
		||||
		public string Title { get; set; } = string.Empty;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -21,6 +21,9 @@ namespace Entities.DTO
 | 
			
		||||
		public DateTime DueDate { get; set; }
 | 
			
		||||
		public Guid CreatorId { get; set; }
 | 
			
		||||
 | 
			
		||||
		public string Name { get; set; } = string.Empty;
 | 
			
		||||
		public ExamType ExamType { get; set; } = ExamType.DailyTest;
 | 
			
		||||
 | 
			
		||||
		public AssignmentQuestionDto ExamStruct { get; set; } = new AssignmentQuestionDto();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -16,6 +16,7 @@ namespace Entities.DTO
 | 
			
		||||
		public byte Index { get; set; } = 0;
 | 
			
		||||
		public float Score { get; set; } = 0;
 | 
			
		||||
		public string Sequence { get; set; } = string.Empty;
 | 
			
		||||
		public bool BCorrect { get; set; } = true;
 | 
			
		||||
 | 
			
		||||
		public Layout Layout { get; set; } = Layout.horizontal;
 | 
			
		||||
		public AssignmentStructType StructType { get; set; } = AssignmentStructType.Question;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										8
									
								
								Entities/Dockerfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								Entities/Dockerfile
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
# ./Entities/Dockerfile
 | 
			
		||||
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS entities
 | 
			
		||||
WORKDIR /src
 | 
			
		||||
COPY ../Entities/*.csproj ./Entities/
 | 
			
		||||
RUN dotnet restore "Entities/Entities.csproj"
 | 
			
		||||
 | 
			
		||||
COPY ../Entities/. ./Entities/
 | 
			
		||||
RUN dotnet publish "Entities/Entities.csproj" -c Release -o /publish
 | 
			
		||||
							
								
								
									
										26
									
								
								TechHelper.Client/Dockerfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								TechHelper.Client/Dockerfile
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
			
		||||
# 构建阶段
 | 
			
		||||
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS client
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#COPY --from=entitieslib:latest /publish /publish/entities
 | 
			
		||||
#COPY --from=emaillib:latest /publish /publish/emaillib
 | 
			
		||||
 | 
			
		||||
WORKDIR /app
 | 
			
		||||
 | 
			
		||||
# 复制依赖文件 & 恢复
 | 
			
		||||
#COPY ./TechHelper.Client.sln ./
 | 
			
		||||
COPY ../TechHelper.Client/*.csproj ../TechHelper.Client/
 | 
			
		||||
 | 
			
		||||
RUN dotnet nuget locals all --clear
 | 
			
		||||
RUN dotnet restore "/app/TechHelper.Client/TechHelper.Client.csproj"
 | 
			
		||||
 | 
			
		||||
# 复制代码 & 发布
 | 
			
		||||
COPY . ./
 | 
			
		||||
WORKDIR /app/TechHelper.Client
 | 
			
		||||
RUN dotnet publish "/app/TechHelper.Client/TechHelper.Client.csproj" -c Release -o /publish
 | 
			
		||||
 | 
			
		||||
FROM nginx:alpine AS final
 | 
			
		||||
RUN rm -rf /usr/share/nginx/html
 | 
			
		||||
COPY --from=client /publish/wwwroot /usr/share/nginx/html
 | 
			
		||||
 | 
			
		||||
EXPOSE 80
 | 
			
		||||
@@ -50,6 +50,7 @@ namespace TechHelper.Client.Exam
 | 
			
		||||
		public List<ParseError> Errors { get; set; } = new List<ParseError>();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 试题的包裹器,  或者 单独作为一个试题结构存在
 | 
			
		||||
	public class AssignmentQuestionEx
 | 
			
		||||
	{
 | 
			
		||||
		public string Title { get; set; } = string.Empty;
 | 
			
		||||
@@ -115,7 +116,7 @@ namespace TechHelper.Client.Exam
 | 
			
		||||
			QuestionPatterns.Add(new RegexPatternConfig(@"^([一二三四五六七八九十]+)[.\、]\s*(.+)", 1, AssignmentStructType.Struct));
 | 
			
		||||
 | 
			
		||||
			// 例如:(一) 这是第一子题组
 | 
			
		||||
			QuestionPatterns.Add(new RegexPatternConfig(@"^\(([一二三四五六七八九十]{1,2}|十[一二三四五六七八九])\)\s*(.+)", 2, AssignmentStructType.Composite));
 | 
			
		||||
			QuestionPatterns.Add(new RegexPatternConfig(@"^\(([一二三四五六七八九十]{1,2}|十[一二三四五六七八九])\)\s*(.+)", 2, AssignmentStructType.Group));
 | 
			
		||||
 | 
			
		||||
			// 例如:1. 这是第一道题目 或 1 这是第一道题目
 | 
			
		||||
			QuestionPatterns.Add(new RegexPatternConfig(@"^(\d+)\.?\s*(.+)", 3, AssignmentStructType.Question));
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										0
									
								
								TechHelper.Client/Pages/Author/Component.razor
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								TechHelper.Client/Pages/Author/Component.razor
									
									
									
									
									
										Normal file
									
								
							@@ -1,48 +1,59 @@
 | 
			
		||||
@page "/login"
 | 
			
		||||
 | 
			
		||||
<MudText Typo="Typo.h2"> Login Account </MudText>
 | 
			
		||||
<div class="d-flex flex-column flex-grow-1 page-containerr">
 | 
			
		||||
 | 
			
		||||
<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="d-flex mud-paper-80-percent-centeredd w-75">
 | 
			
		||||
		<MudPaper Class="d-flex flex-grow-1 ma-0 pa-0" style="background-color:transparent; min-height:100%" Elevation="0">
 | 
			
		||||
 | 
			
		||||
				<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>
 | 
			
		||||
			<MudGrid Class="d-flex flex-grow-1" style="background-color:transparent;  min-height:100%">
 | 
			
		||||
				<MudItem xs="12" sm="4" style="background-color:transparent">
 | 
			
		||||
					<MudPaper Class="d-flex flex-column align-start justify-start mud-width-full h-100 pa-8" Elevation="0" Style="background-color:transparent">
 | 
			
		||||
						<MudText Style="color:#ffffff" Typo="Typo.h4">TechHelper</MudText>
 | 
			
		||||
						<MudText Style="color:#ffffff" Typo="Typo.body2">轻松管理,高效学习。</MudText>
 | 
			
		||||
						<MudSpacer />
 | 
			
		||||
						<MudText Style="color:#ffffff" Typo="Typo.h4">教育不是注满一桶水,</MudText>
 | 
			
		||||
						<MudText Style="color:#ffffff" Typo="Typo.h4">  而是点燃一把火。</MudText>
 | 
			
		||||
						<MudImage Alt="Hello World" Fluid="true" Src="ref/UnFinish.png" />
 | 
			
		||||
					</MudPaper>
 | 
			
		||||
				</MudItem>
 | 
			
		||||
 | 
			
		||||
				<MudItem xs="12" sm="8" style="background-color:transparent">
 | 
			
		||||
 | 
			
		||||
					<MudPaper Class="d-flex flex-row flex-grow-1 justify-center rounded-xl px-0 mud-height-full" >
 | 
			
		||||
 | 
			
		||||
						<EditForm Model="@_userForAuth" OnValidSubmit="Logining" FormName="LoginingForm" class="w-100">
 | 
			
		||||
							<DataAnnotationsValidator />
 | 
			
		||||
							<MudPaper Class="d-flex flex-column flex-grow-1 rounded-xl px-15 justify-content-center pt-15 w-100 " Elevation="0" Outlined="false">
 | 
			
		||||
								<MudText Typo="Typo.h5"> <b>登录账户</b> </MudText>
 | 
			
		||||
								<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" />
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
								<MudStack Row=true Class="align-content-center justify-content-start my-3">
 | 
			
		||||
									<MudCheckBox @bind-Value="Basic_CheckBox2" Color="Color.Primary"></MudCheckBox>
 | 
			
		||||
									<MudText Typo="Typo.body2" Align=Align.Center Class="align-content-center"> 点击登录,即表示你同意我们的服务条款和隐私政策。 </MudText>
 | 
			
		||||
								</MudStack>
 | 
			
		||||
 | 
			
		||||
								<MudButton ButtonType="ButtonType.Submit" Variant="Variant.Filled" Color="Color.Primary" Class="w-100 mx-0 my-3 justify-content-center rounded-pill">LOGIN</MudButton>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
								<MudText Typo="Typo.body2" Class="justify-content-center mx-auto mt-5" Color="Color.Dark">
 | 
			
		||||
									还没有账户?
 | 
			
		||||
									<a href="/register" style="color: blue;">Sign in</a>
 | 
			
		||||
								</MudText>
 | 
			
		||||
							</MudPaper>
 | 
			
		||||
 | 
			
		||||
						</EditForm>
 | 
			
		||||
 | 
			
		||||
					</MudPaper>
 | 
			
		||||
 | 
			
		||||
				</MudItem>
 | 
			
		||||
			</MudGrid>
 | 
			
		||||
		</MudPaper>
 | 
			
		||||
 | 
			
		||||
	</div>
 | 
			
		||||
</div>
 | 
			
		||||
 
 | 
			
		||||
@@ -16,6 +16,8 @@ namespace TechHelper.Client.Pages.Author
 | 
			
		||||
		[Inject]
 | 
			
		||||
		public NavigationManager NavigationManager { get; set; }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		public bool Basic_CheckBox2 { get; set; } = true;
 | 
			
		||||
		public bool ShowRegistrationErrors { get; set; }
 | 
			
		||||
		public string Error { get; set; }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										29
									
								
								TechHelper.Client/Pages/Author/Login.razor.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								TechHelper.Client/Pages/Author/Login.razor.css
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
			
		||||
.page-containerr {
 | 
			
		||||
	width: 100%;
 | 
			
		||||
	height: 100%; /* <20>ӿڸ߶ȣ<DFB6>ȷ<EFBFBD><C8B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>㹻<EFBFBD>ĸ߶<C4B8><DFB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD><D4AA> */
 | 
			
		||||
	display: flex;
 | 
			
		||||
	flex-direction: column; /* <20><>ֱ<EFBFBD><D6B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD><D4AA> */
 | 
			
		||||
	align-items: center; /* ˮƽ<CBAE><C6BD><EFBFBD><EFBFBD> */
 | 
			
		||||
	justify-content: center; /* <20><>ֱ<EFBFBD><D6B1><EFBFBD><EFBFBD> */
 | 
			
		||||
	background-color: white;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.mud-paper-full-width {
 | 
			
		||||
	width: 80%; /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>paper<65>Ŀ<EFBFBD><C4BF><EFBFBD> */
 | 
			
		||||
	height: auto;
 | 
			
		||||
	padding: 20px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.mud-paper-80-percent-centeredd {
 | 
			
		||||
	width: 80%;
 | 
			
		||||
	min-height: 80%;
 | 
			
		||||
	padding: 0px;
 | 
			
		||||
	margin: 0 auto;
 | 
			
		||||
	background-color: #959dff;
 | 
			
		||||
	border: 1px solid #ccc;
 | 
			
		||||
	display: flex;
 | 
			
		||||
	align-items: center;
 | 
			
		||||
	border-radius: 40px;
 | 
			
		||||
	justify-content: center;
 | 
			
		||||
	box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,96 +1,96 @@
 | 
			
		||||
@page "/register"
 | 
			
		||||
@using System.ComponentModel.DataAnnotations
 | 
			
		||||
@using Microsoft.AspNetCore.Components
 | 
			
		||||
@using Entities.Contracts
 | 
			
		||||
@using System.Globalization;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@inject ISnackbar Snackbar
 | 
			
		||||
 | 
			
		||||
<div class="d-flex flex-grow-1 page-container">
 | 
			
		||||
 | 
			
		||||
<MudText Typo="Typo.h2"> Create Account </MudText>
 | 
			
		||||
	<div class="d-flex mud-paper-80-percent-centered w-75">
 | 
			
		||||
		<MudPaper Class="d-flex flex-grow-1 ma-0 pa-0" style="background-color:transparent; min-height:100%" Elevation="0">
 | 
			
		||||
 | 
			
		||||
<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">
 | 
			
		||||
			<MudGrid Class="d-flex flex-grow-1" style="background-color:transparent;  min-height:100%">
 | 
			
		||||
				<MudItem xs="12" sm="4" style="background-color:transparent">
 | 
			
		||||
					<MudPaper Class="d-flex flex-column align-start justify-start mud-width-full h-100 pa-8" Elevation="0" Style="background-color:transparent">
 | 
			
		||||
						<MudText Style="color:#ffffff" Typo="Typo.h4">TechHelper</MudText>
 | 
			
		||||
						<MudText Style="color:#ffffff" Typo="Typo.body2">快速注册,开始你的管理之旅。</MudText>
 | 
			
		||||
						<MudSpacer />
 | 
			
		||||
						<MudText Style="color:#ffffff" Typo="Typo.h4">学而不思则罔,</MudText>
 | 
			
		||||
						<MudText Style="color:#ffffff" Typo="Typo.h4">  思而不学则殆。</MudText>
 | 
			
		||||
						<MudImage Alt="Hello World" Fluid="true" Src="ref/UnFinish.png" />
 | 
			
		||||
					</MudPaper>
 | 
			
		||||
				</MudItem>
 | 
			
		||||
 | 
			
		||||
						<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." />
 | 
			
		||||
				<MudItem xs="12" sm="8" style="background-color:transparent">
 | 
			
		||||
 | 
			
		||||
						<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>
 | 
			
		||||
					<MudPaper Class="d-flex flex-row flex-grow-1 justify-center rounded-xl px-20 mud-height-full">
 | 
			
		||||
						<EditForm Model="@_userForRegistration" OnValidSubmit="Register" FormName="RegistrationForm" class="w-100">
 | 
			
		||||
							<DataAnnotationsValidator />
 | 
			
		||||
							<MudPaper Class="d-flex flex-column flex-grow-1 rounded-xl px-5 justify-content-center pt-15 w-100 " Elevation="0" Outlined="false">
 | 
			
		||||
								<MudText Typo="Typo.h5"> <b>注册账户</b> </MudText>
 | 
			
		||||
								<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" />
 | 
			
		||||
								<MudChipSet T="UserRoles" @bind-SelectedValue="_userForRegistration.Roles" CheckMark SelectionMode="SelectionMode.SingleSelection" Class="w-100">
 | 
			
		||||
									<MudChip Text="Student" Color="Color.Primary" Value="@UserRoles.Student">Student</MudChip>
 | 
			
		||||
									<MudChip Text="Teacher" Color="Color.Secondary" Value="@UserRoles.Teacher">Teacher</MudChip>
 | 
			
		||||
								</MudChipSet>
 | 
			
		||||
 | 
			
		||||
					<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>
 | 
			
		||||
								<MudStack Row="true">
 | 
			
		||||
									<MudSelect T="GradeEnum" Value="grade" Label="Select Grade" AdornmentColor="Color.Secondary" ValueChanged="HandleSelectedValuesChanged">
 | 
			
		||||
										@foreach (GradeEnum item in Enum.GetValues(typeof(GradeEnum)))
 | 
			
		||||
										{
 | 
			
		||||
											<MudSelectItem Value="@item">@item</MudSelectItem>
 | 
			
		||||
										}
 | 
			
		||||
									</MudSelect>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
									<MudSelect T="byte" Value="selectclass" Label="Select Class" AdornmentColor="Color.Secondary" ValueChanged="HandleListSelectedValuesChanged">
 | 
			
		||||
										@foreach (byte item in Classes)
 | 
			
		||||
										{
 | 
			
		||||
											<MudSelectItem Value="@item">@item</MudSelectItem>
 | 
			
		||||
										}
 | 
			
		||||
									</MudSelect>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
								</MudStack>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
								<MudStack Row=true Class="align-content-center justify-content-start my-3">
 | 
			
		||||
									<MudCheckBox @bind-Value="Basic_CheckBox2" Color="Color.Primary"></MudCheckBox>
 | 
			
		||||
									<MudText Typo="Typo.body2" Align=Align.Center Class="align-content-center"> 点击注册,即表示你同意我们的服务条款和隐私政策。 </MudText>
 | 
			
		||||
								</MudStack>
 | 
			
		||||
 | 
			
		||||
								<MudButton ButtonType="ButtonType.Submit" Variant="Variant.Filled" Color="Color.Primary" Class="w-100 mx-0 my-3 justify-content-center rounded-pill">LOGIN</MudButton>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
								<MudText Typo="Typo.body2" Class="justify-content-center mx-auto mt-5" Color="Color.Dark">
 | 
			
		||||
									已有账户?
 | 
			
		||||
									<a href="/login" style="color: blue;">Sign up</a>
 | 
			
		||||
								</MudText>
 | 
			
		||||
							</MudPaper>
 | 
			
		||||
 | 
			
		||||
						</EditForm>
 | 
			
		||||
 | 
			
		||||
					</MudPaper>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
				</MudItem>
 | 
			
		||||
			</MudGrid>
 | 
			
		||||
		</MudPaper>
 | 
			
		||||
 | 
			
		||||
	</div>
 | 
			
		||||
</div>
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@ using MudBlazor;
 | 
			
		||||
using System.Text.RegularExpressions;
 | 
			
		||||
using TechHelper.Features;
 | 
			
		||||
using Entities.Contracts;
 | 
			
		||||
using TechHelper.Client.Services;
 | 
			
		||||
 | 
			
		||||
namespace TechHelper.Client.Pages.Author
 | 
			
		||||
{
 | 
			
		||||
@@ -12,14 +13,19 @@ namespace TechHelper.Client.Pages.Author
 | 
			
		||||
	{
 | 
			
		||||
 | 
			
		||||
		private UserForRegistrationDto _userForRegistration = new UserForRegistrationDto();
 | 
			
		||||
 | 
			
		||||
		private GradeEnum grade = GradeEnum.Unknown;
 | 
			
		||||
		[Inject]
 | 
			
		||||
		public IAuthenticationClientService AuthenticationService { get; set; }
 | 
			
		||||
 | 
			
		||||
		[Inject]
 | 
			
		||||
		public NavigationManager NavigationManager { get; set; }
 | 
			
		||||
		[Inject]
 | 
			
		||||
		public IClassServices ClassServices { get; set; }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		public bool Basic_CheckBox2 { get; set; } = true;
 | 
			
		||||
		public byte selectclass { get; set; } = 0;
 | 
			
		||||
		public List<byte> Classes { get; set; } = new List<byte>();
 | 
			
		||||
 | 
			
		||||
		public bool ShowRegistrationErrors { get; set; }
 | 
			
		||||
		public string[] Errors { get; set; }
 | 
			
		||||
@@ -51,6 +57,25 @@ namespace TechHelper.Client.Pages.Author
 | 
			
		||||
		[Inject]
 | 
			
		||||
		public IEmailSender emailSender { get; set; }
 | 
			
		||||
 | 
			
		||||
		private async void HandleSelectedValuesChanged(GradeEnum selectedValues)
 | 
			
		||||
		{
 | 
			
		||||
			grade = selectedValues;
 | 
			
		||||
			Snackbar.Add("<22><><EFBFBD>ȴ<EFBFBD>,<2C><><EFBFBD>ڻ<EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD>꼶<EFBFBD>༶", Severity.Info);
 | 
			
		||||
			var result = await ClassServices.GetGradeClasses((byte)selectedValues);
 | 
			
		||||
			if (result.Status)
 | 
			
		||||
			{
 | 
			
		||||
				Classes = result.Result as List<byte> ?? new List<byte>();
 | 
			
		||||
				Snackbar.Add("<22><>ȡ<EFBFBD>ɹ<EFBFBD>", Severity.Success);
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
			Snackbar.Add("<22><>ȡʧ<C8A1><CAA7>", Severity.Error);
 | 
			
		||||
		}
 | 
			
		||||
		private void HandleListSelectedValuesChanged(byte selectedValues)
 | 
			
		||||
		{
 | 
			
		||||
			selectclass = selectedValues;
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public async void SendEmail()
 | 
			
		||||
		{
 | 
			
		||||
			string eamilTo = "1928360026@qq.com";
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										29
									
								
								TechHelper.Client/Pages/Author/Registration.razor.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								TechHelper.Client/Pages/Author/Registration.razor.css
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
			
		||||
.page-container {
 | 
			
		||||
	width: 100%;
 | 
			
		||||
	height: 100%; /* <20>ӿڸ߶ȣ<DFB6>ȷ<EFBFBD><C8B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>㹻<EFBFBD>ĸ߶<C4B8><DFB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD><D4AA> */
 | 
			
		||||
	display: flex;
 | 
			
		||||
	flex-direction: column; /* <20><>ֱ<EFBFBD><D6B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD><D4AA> */
 | 
			
		||||
	align-items: center; /* ˮƽ<CBAE><C6BD><EFBFBD><EFBFBD> */
 | 
			
		||||
	justify-content: center; /* <20><>ֱ<EFBFBD><D6B1><EFBFBD><EFBFBD> */
 | 
			
		||||
	background-color: white;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.mud-paper-full-width {
 | 
			
		||||
	width: 80%; /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>paper<65>Ŀ<EFBFBD><C4BF><EFBFBD> */
 | 
			
		||||
	height: auto;
 | 
			
		||||
	padding: 20px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.mud-paper-80-percent-centered {
 | 
			
		||||
	width: 80%;
 | 
			
		||||
	min-height: 80%;
 | 
			
		||||
	padding: 0px;
 | 
			
		||||
	margin: 0 auto;
 | 
			
		||||
	background-color: #959dff;
 | 
			
		||||
	border: 1px solid #ccc;
 | 
			
		||||
	display: flex;
 | 
			
		||||
	align-items: center;
 | 
			
		||||
	border-radius: 40px;
 | 
			
		||||
	justify-content: center;
 | 
			
		||||
	box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										143
									
								
								TechHelper.Client/Pages/Common/Exam/AssignmentInfoCard.razor
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										143
									
								
								TechHelper.Client/Pages/Common/Exam/AssignmentInfoCard.razor
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,143 @@
 | 
			
		||||
<MudPaper Class="rounded-xl w-100 px-10 ma-3 pt-5" Elevation="5" Height="170px" Style="background-color:#6bc6be">
 | 
			
		||||
 | 
			
		||||
	<MudGrid Class="h-100">
 | 
			
		||||
 | 
			
		||||
		<MudItem xs="12" sm="2" Class="h-100 pa-1 mt-1">
 | 
			
		||||
			<MudStack Class="h-100">
 | 
			
		||||
				<MudText Style="color:white"> 期中测试BETA版本 </MudText>
 | 
			
		||||
				<MudText Style="color:white" Typo="Typo.h3"><b> 75  </b></MudText>
 | 
			
		||||
 | 
			
		||||
				<MudPaper Elevation=0 Class="h-100 w-100" Style="background-color:transparent">
 | 
			
		||||
					<MudStack Class="h-100" Row=true>
 | 
			
		||||
						<MudPaper Elevation=0 Height="100%" Width="100%" Style="background-color:transparent">
 | 
			
		||||
							<MudPaper Elevation=0 Height="50%" Style="background-color:transparent">
 | 
			
		||||
								<MudText Style="color:#9ed5f7" Typo="Typo.body2">
 | 
			
		||||
									TotalNumber:
 | 
			
		||||
									<span style="color: #fefefe;">15</span>
 | 
			
		||||
								</MudText>
 | 
			
		||||
							</MudPaper>
 | 
			
		||||
							<MudPaper Elevation=0 Height="50%" Style="background-color:transparent">
 | 
			
		||||
								<MudText Style="color:#9ed5f7" Typo="Typo.body2">
 | 
			
		||||
									TotalScore:
 | 
			
		||||
									<span style="color: #fefefe;">15</span>
 | 
			
		||||
								</MudText>
 | 
			
		||||
							</MudPaper>
 | 
			
		||||
						</MudPaper>
 | 
			
		||||
 | 
			
		||||
						<MudPaper Elevation=0 Height="100%" Width="100%" Style="background-color:transparent">
 | 
			
		||||
							<MudPaper Elevation=0 Height="50%" Style="background-color:transparent">
 | 
			
		||||
								<MudText Style="color:#9ed5f7" Typo="Typo.body2">
 | 
			
		||||
									中位数:
 | 
			
		||||
									<span style="color: #fefefe;">15</span>
 | 
			
		||||
								</MudText>
 | 
			
		||||
							</MudPaper>
 | 
			
		||||
							<MudPaper Elevation=0 Height="50%" Style="background-color:transparent">
 | 
			
		||||
								<MudText Style="color:#9ed5f7" Typo="Typo.body2">
 | 
			
		||||
									方差:
 | 
			
		||||
									<span style="color: #fefefe;">15</span>
 | 
			
		||||
								</MudText>
 | 
			
		||||
							</MudPaper>
 | 
			
		||||
						</MudPaper>
 | 
			
		||||
					</MudStack>
 | 
			
		||||
				</MudPaper>
 | 
			
		||||
			</MudStack>
 | 
			
		||||
		</MudItem>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		<MudItem xs="12" sm="9">
 | 
			
		||||
			<MudPaper Style="background-color:transparent" Class="w-100 mt-n3" Height="100%" Elevation="0">
 | 
			
		||||
				<MudChart ChartType="ChartType.Line" Class="pt-0" ChartSeries="@Series" XAxisLabels="@XAxisLabels" CanHideSeries
 | 
			
		||||
						  Height="150px" Width="100%" AxisChartOptions="_axisChartOptions" ChartOptions="options">
 | 
			
		||||
					<CustomGraphics>
 | 
			
		||||
						<style>
 | 
			
		||||
							.heavy {
 | 
			
		||||
								font: normal 12px helvetica;
 | 
			
		||||
								fill: rgb(255,255,255);
 | 
			
		||||
								letter-spacing: 2px;
 | 
			
		||||
							}
 | 
			
		||||
						</style>
 | 
			
		||||
 | 
			
		||||
						<text x="60" y="15" class="heavy"> 成绩的整体分布情况 </text>
 | 
			
		||||
					</CustomGraphics>
 | 
			
		||||
				</MudChart>
 | 
			
		||||
			</MudPaper>
 | 
			
		||||
 | 
			
		||||
		</MudItem>
 | 
			
		||||
		<MudItem xs="12" sm="1">
 | 
			
		||||
			<MudChipSet T="string" SelectedValuesChanged="HandleSelectedValuesChanged" SelectedValues="@_selected" SelectionMode="SelectionMode.MultiSelection" CheckMark="true">
 | 
			
		||||
				<MudChip Size="Size.Small" Text="类型错误数量分布" Variant="Variant.Text" Color="Color.Default">类型分布</MudChip>
 | 
			
		||||
				<MudChip Size="Size.Small" Text="类型错误成绩分布" Variant="Variant.Text" Color="Color.Primary">课时分布</MudChip>
 | 
			
		||||
				<MudChip Size="Size.Small" Text="pink" Variant="Variant.Text" Color="Color.Secondary">成绩趋势</MudChip>
 | 
			
		||||
				<MudChip Size="Size.Small" Text="blue" Variant="Variant.Text" Color="Color.Info">分值区间</MudChip>
 | 
			
		||||
				<MudChip Size="Size.Small" Text="green" Variant="Variant.Text" Color="Color.Success">Success</MudChip>
 | 
			
		||||
				<MudChip Size="Size.Small" Text="orange" Variant="Variant.Text" Color="Color.Warning">Warning</MudChip>
 | 
			
		||||
				<MudChip Size="Size.Small" Text="red" Variant="Variant.Text" Color="Color.Error">Error</MudChip>
 | 
			
		||||
				<MudChip Size="Size.Small" Text="black" Variant="Variant.Text" Color="Color.Dark">Dark</MudChip>
 | 
			
		||||
			</MudChipSet>
 | 
			
		||||
		</MudItem>
 | 
			
		||||
	</MudGrid>
 | 
			
		||||
</MudPaper>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@code {
 | 
			
		||||
	public double[] data = { 25, 77, 28, 5 };
 | 
			
		||||
	public string[] labels = { "Oil", "Coal", "Gas", "Biomass" };
 | 
			
		||||
	private AxisChartOptions _axisChartOptions = new AxisChartOptions
 | 
			
		||||
	{
 | 
			
		||||
	};
 | 
			
		||||
	private ChartOptions options = new ChartOptions
 | 
			
		||||
	{
 | 
			
		||||
		InterpolationOption = InterpolationOption.NaturalSpline,
 | 
			
		||||
		YAxisFormat = "c2",
 | 
			
		||||
		ShowLegend = false,
 | 
			
		||||
		YAxisLines = false,
 | 
			
		||||
		XAxisLines = false,
 | 
			
		||||
		XAxisLabelPosition = XAxisLabelPosition.None,
 | 
			
		||||
		YAxisLabelPosition = YAxisLabelPosition.None,
 | 
			
		||||
		YAxisTicks = 100,
 | 
			
		||||
		ShowLabels = false,
 | 
			
		||||
		ShowLegendLabels = false
 | 
			
		||||
 | 
			
		||||
	};
 | 
			
		||||
	public List<ChartSeries> Series = new List<ChartSeries>()
 | 
			
		||||
	{
 | 
			
		||||
		new ChartSeries() { Name = "类型错误数量分布", Data = new double[] { 35, 41, 35, 51, 49, 62, 69, 91, 148 } },
 | 
			
		||||
		new ChartSeries() { Name = "类型错误成绩分布", Data = new double[] { 55, 21, 45, 11, 45, 23, 11, 56, 13 } },
 | 
			
		||||
	};
 | 
			
		||||
	public string[] XAxisLabels = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep" };
 | 
			
		||||
 | 
			
		||||
	Random random = new Random();
 | 
			
		||||
	protected override void OnInitialized()
 | 
			
		||||
	{
 | 
			
		||||
		options.InterpolationOption = InterpolationOption.NaturalSpline;
 | 
			
		||||
		options.YAxisFormat = "c2";
 | 
			
		||||
		options.ShowLegend = false;
 | 
			
		||||
		options.YAxisLines = false;
 | 
			
		||||
		options.XAxisLines = false;
 | 
			
		||||
		options.XAxisLabelPosition = XAxisLabelPosition.None;
 | 
			
		||||
		options.YAxisLabelPosition = YAxisLabelPosition.None;
 | 
			
		||||
		options.ShowLabels = false;
 | 
			
		||||
		options.ShowLegendLabels = false;
 | 
			
		||||
		options.LineStrokeWidth = 1;
 | 
			
		||||
		_axisChartOptions.MatchBoundsToSize = true;
 | 
			
		||||
 | 
			
		||||
		Series[0].LineDisplayType = LineDisplayType.Area;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private IReadOnlyCollection<string> _selected;
 | 
			
		||||
 | 
			
		||||
	private void HandleSelectedValuesChanged(IReadOnlyCollection<string> selected)
 | 
			
		||||
	{
 | 
			
		||||
		Series.ForEach(x => x.Visible = false);
 | 
			
		||||
 | 
			
		||||
		foreach(var item in selected)
 | 
			
		||||
		{
 | 
			
		||||
			var sv = Series.FirstOrDefault(predicate: x => x.Name == item);
 | 
			
		||||
			if(sv != null)
 | 
			
		||||
			{
 | 
			
		||||
				sv.Visible = true;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,6 @@
 | 
			
		||||
<MudPaper Class="rounded-xl w-100 px-10 ma-3 pt-5">
 | 
			
		||||
 | 
			
		||||
	<MudText> Name </MudText>
 | 
			
		||||
	<MudText> 错误数量 </MudText>
 | 
			
		||||
	<MudText> 分数 </MudText>
 | 
			
		||||
</MudPaper>
 | 
			
		||||
@@ -0,0 +1,6 @@
 | 
			
		||||
<MudPaper Class="rounded-xl w-100 px-10 ma-3 pt-5">
 | 
			
		||||
 | 
			
		||||
	<MudText> Name </MudText>
 | 
			
		||||
	<MudText> 平均数 </MudText>
 | 
			
		||||
	<MudText> 中为数 </MudText>
 | 
			
		||||
</MudPaper>
 | 
			
		||||
							
								
								
									
										67
									
								
								TechHelper.Client/Pages/Common/PublishExamDialog.razor
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								TechHelper.Client/Pages/Common/PublishExamDialog.razor
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,67 @@
 | 
			
		||||
@using Entities.DTO
 | 
			
		||||
@inject ISnackbar Snackbar
 | 
			
		||||
@using Entities.Contracts
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<MudDialog Class="rounded-xl pa-2" Style="background-color: #dedede">
 | 
			
		||||
	<TitleContent>
 | 
			
		||||
		<MudText Typo="Typo.h6">
 | 
			
		||||
			<MudIcon Icon="@Icons.Material.Filled.EditAttributes" Class="mr-3 mb-n1" />
 | 
			
		||||
			<b> 发布! </b>
 | 
			
		||||
		</MudText>
 | 
			
		||||
	</TitleContent>
 | 
			
		||||
	<DialogContent>
 | 
			
		||||
		<MudPaper Elevation="0" Class="rounded-xl pa-1 " Style="background-color: transparent">
 | 
			
		||||
			<MudPaper Elevation="0" Class="rounded-xl pa-2 ma-2">
 | 
			
		||||
				<MudTextField @bind-Value="Exam.Name" Label="Title" Variant="Variant.Text" Margin="Margin.Dense" AutoFocus="true" />
 | 
			
		||||
				<MudTextField @bind-Value="Exam.TotalQuestions" Label="TotalQuestions" Variant="Variant.Text" Adornment="Adornment.End" AdornmentText="." Margin="Margin.Dense" AutoFocus="true" />
 | 
			
		||||
				<MudTextField @bind-Value="Exam.Score" Label="Score" Variant="Variant.Text" Adornment="Adornment.End" AdornmentText="." Margin="Margin.Dense" AutoFocus="true" />
 | 
			
		||||
			</MudPaper>
 | 
			
		||||
			<MudPaper Elevation="0" Class="rounded-xl pa-2 ma-2">
 | 
			
		||||
 | 
			
		||||
				<MudChipSet T="SubjectAreaEnum" @bind-SelectedValue="@Exam.SubjectArea" CheckMark=true SelectionMode="SelectionMode.SingleSelection" Size="Size.Small">
 | 
			
		||||
					<MudChip Text="@SubjectAreaEnum.Literature.ToString()" Color="Color.Primary" Value="@SubjectAreaEnum.Literature">    @SubjectAreaEnum.Literature</MudChip>
 | 
			
		||||
					<MudChip Text="@SubjectAreaEnum.Mathematics.ToString()" Color="Color.Secondary" Value="@SubjectAreaEnum.Mathematics">  @SubjectAreaEnum.Mathematics</MudChip>
 | 
			
		||||
					<MudChip Text="@SubjectAreaEnum.English.ToString()" Color="Color.Info" Value="@SubjectAreaEnum.English">            @SubjectAreaEnum.English</MudChip>
 | 
			
		||||
					<MudChip Text="@SubjectAreaEnum.ComputerScience.ToString()" Color="Color.Success" Value="@SubjectAreaEnum.ComputerScience">     @SubjectAreaEnum.ComputerScience</MudChip>
 | 
			
		||||
				</MudChipSet>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
			</MudPaper>
 | 
			
		||||
			<MudPaper Elevation="0" Class="rounded-xl pa-2 ma-2">
 | 
			
		||||
 | 
			
		||||
				<MudChipSet T="ExamType" @bind-SelectedValue="@Exam.ExamType" CheckMark=true SelectionMode="SelectionMode.SingleSelection" Size="Size.Small">
 | 
			
		||||
					<MudChip Text="@ExamType.DailyTest.ToString()" Color="Color.Primary"			Value="@ExamType.DailyTest">       @ExamType.DailyTest</MudChip>
 | 
			
		||||
					<MudChip Text="@ExamType.WeeklyExam.ToString()" Color="Color.Secondary"		Value="@ExamType.WeeklyExam">     @ExamType.WeeklyExam</MudChip>
 | 
			
		||||
					<MudChip Text="@ExamType.MonthlyExam.ToString()" Color="Color.Info"			Value="@ExamType.MonthlyExam">          @ExamType.MonthlyExam</MudChip>
 | 
			
		||||
					<MudChip Text="@ExamType.MidtermExam.ToString()" Color="Color.Success"		Value="@ExamType.MidtermExam">       @ExamType.MidtermExam</MudChip>
 | 
			
		||||
					<MudChip Text="@ExamType.FinalExam.ToString()" Color="Color.Warning"			Value="@ExamType.FinalExam">       @ExamType.FinalExam</MudChip>
 | 
			
		||||
					<MudChip Text="@ExamType.AITest.ToString()" Color="Color.Error"				Value="@ExamType.AITest">       @ExamType.AITest</MudChip>
 | 
			
		||||
				</MudChipSet>
 | 
			
		||||
			</MudPaper>
 | 
			
		||||
		</MudPaper>
 | 
			
		||||
	</DialogContent>
 | 
			
		||||
	<DialogActions>
 | 
			
		||||
		<MudButton OnClick="Cancel">Cancel</MudButton>
 | 
			
		||||
		<MudButton Color="Color.Error" OnClick="Confirm">确认</MudButton>
 | 
			
		||||
	</DialogActions>
 | 
			
		||||
</MudDialog>
 | 
			
		||||
 | 
			
		||||
@code {
 | 
			
		||||
	[CascadingParameter]
 | 
			
		||||
	private IMudDialogInstance MudDialog { get; set; }
 | 
			
		||||
 | 
			
		||||
	[Parameter]
 | 
			
		||||
	public AssignmentDto Exam { get; set; } = new AssignmentDto();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	public SubjectAreaEnum SubjectArea { get; set; }
 | 
			
		||||
	private void Cancel() => MudDialog.Cancel();
 | 
			
		||||
 | 
			
		||||
	private void Confirm()
 | 
			
		||||
	{
 | 
			
		||||
		Snackbar.Add("属性已更新", Severity.Success);
 | 
			
		||||
		MudDialog.Close(DialogResult.Ok(Exam));
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										34
									
								
								TechHelper.Client/Pages/Common/QuestionCardDialog.razor
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								TechHelper.Client/Pages/Common/QuestionCardDialog.razor
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
			
		||||
@using Entities.DTO
 | 
			
		||||
@inject ISnackbar Snackbar
 | 
			
		||||
 | 
			
		||||
<MudDialog Class="rounded-xl" Style="background-color: #dedede" >
 | 
			
		||||
    <TitleContent>
 | 
			
		||||
        <MudText Typo="Typo.h6">
 | 
			
		||||
            <MudIcon Icon="@Icons.Material.Filled.EditAttributes" Class="mr-3 mb-n1" />
 | 
			
		||||
            <b> 编辑属性 </b>
 | 
			
		||||
        </MudText>
 | 
			
		||||
    </TitleContent>
 | 
			
		||||
    <DialogContent>
 | 
			
		||||
        <TechHelper.Client.Pages.Exam.AssignmentQuestionEdit AssignmentQuestion="Questions"/>
 | 
			
		||||
    </DialogContent>
 | 
			
		||||
    <DialogActions>
 | 
			
		||||
        <MudButton OnClick="Cancel">Cancel</MudButton>
 | 
			
		||||
        <MudButton Color="Color.Error" OnClick="Confirm">确认</MudButton>
 | 
			
		||||
    </DialogActions>
 | 
			
		||||
</MudDialog>
 | 
			
		||||
 | 
			
		||||
@code {
 | 
			
		||||
    [CascadingParameter]
 | 
			
		||||
    private IMudDialogInstance MudDialog { get; set; }
 | 
			
		||||
 | 
			
		||||
    [Parameter]
 | 
			
		||||
    public AssignmentQuestionDto Questions { get; set; } = new AssignmentQuestionDto();
 | 
			
		||||
 | 
			
		||||
    private void Cancel() => MudDialog.Cancel();
 | 
			
		||||
 | 
			
		||||
    private void Confirm()
 | 
			
		||||
    {
 | 
			
		||||
        Snackbar.Add("属性已更新", Severity.Success);
 | 
			
		||||
        MudDialog.Close(DialogResult.Ok(Questions));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										22
									
								
								TechHelper.Client/Pages/Common/SimpleCard.razor
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								TechHelper.Client/Pages/Common/SimpleCard.razor
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
<MudPaper Elevation=5 Class="w-100 rounded-xl" Height="@Height" Style="@Style">
 | 
			
		||||
	<MudPaper Elevation=0 Class="w-100  pa-2 align-content-center" Height="20%" Style="background-color:transparent"> @TitleContent </MudPaper>
 | 
			
		||||
	<MudPaper Elevation=0 Class="w-100  pa-2" Style="background-color:transparent" Height="60%"> @BodyContent </MudPaper>
 | 
			
		||||
	<MudPaper Elevation=0 Class="w-100  pa-2  align-content-center" Style="background-color:transparent" Height="20%"> @FooterContent </MudPaper>
 | 
			
		||||
</MudPaper>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@code {
 | 
			
		||||
	[Parameter]
 | 
			
		||||
	public string Style { get; set; }
 | 
			
		||||
	[Parameter]
 | 
			
		||||
	public string Height { get; set; } = "200px";
 | 
			
		||||
 | 
			
		||||
	[Parameter]
 | 
			
		||||
	public RenderFragment TitleContent { get; set; }
 | 
			
		||||
 | 
			
		||||
	[Parameter]
 | 
			
		||||
	public RenderFragment BodyContent { get; set; }
 | 
			
		||||
 | 
			
		||||
	[Parameter]
 | 
			
		||||
	public RenderFragment FooterContent { get; set; }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										86
									
								
								TechHelper.Client/Pages/Common/TextEditorDialog.razor
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								TechHelper.Client/Pages/Common/TextEditorDialog.razor
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,86 @@
 | 
			
		||||
@using Entities.DTO
 | 
			
		||||
@inject ISnackbar Snackbar
 | 
			
		||||
 | 
			
		||||
<MudDialog Class="rounded-xl" Style="background-color: #dedede" >
 | 
			
		||||
    <TitleContent>
 | 
			
		||||
        <MudText Typo="Typo.h6">
 | 
			
		||||
            <MudIcon Icon="@Icons.Material.Filled.EditAttributes" Class="mr-3 mb-n1" />
 | 
			
		||||
            <b> 编辑属性 </b>
 | 
			
		||||
        </MudText>
 | 
			
		||||
    </TitleContent>
 | 
			
		||||
    <DialogContent>
 | 
			
		||||
		<BlazoredTextEditor @ref="@TextEditor">
 | 
			
		||||
			<ToolbarContent>
 | 
			
		||||
				<select class="ql-header">
 | 
			
		||||
					<option selected=""></option>
 | 
			
		||||
					<option value="1"></option>
 | 
			
		||||
					<option value="2"></option>
 | 
			
		||||
					<option value="3"></option>
 | 
			
		||||
					<option value="4"></option>
 | 
			
		||||
					<option value="5"></option>
 | 
			
		||||
				</select>
 | 
			
		||||
				<span class="ql-formats">
 | 
			
		||||
					<button class="ql-bold"></button>
 | 
			
		||||
					<button class="ql-italic"></button>
 | 
			
		||||
					<button class="ql-underline"></button>
 | 
			
		||||
					<button class="ql-strike"></button>
 | 
			
		||||
				</span>
 | 
			
		||||
				<span class="ql-formats">
 | 
			
		||||
					<select class="ql-color"></select>
 | 
			
		||||
					<select class="ql-background"></select>
 | 
			
		||||
				</span>
 | 
			
		||||
				<span class="ql-formats">
 | 
			
		||||
					<button class="ql-list" value="ordered"></button>
 | 
			
		||||
					<button class="ql-list" value="bullet"></button>
 | 
			
		||||
				</span>
 | 
			
		||||
				<span class="ql-formats">
 | 
			
		||||
					<button class="ql-link"></button>
 | 
			
		||||
				</span>
 | 
			
		||||
			</ToolbarContent>
 | 
			
		||||
			<EditorContent>
 | 
			
		||||
			</EditorContent>
 | 
			
		||||
		</BlazoredTextEditor>
 | 
			
		||||
    </DialogContent>
 | 
			
		||||
    <DialogActions>
 | 
			
		||||
        <MudButton OnClick="Cancel">Cancel</MudButton>
 | 
			
		||||
        <MudButton Color="Color.Error" OnClick="Confirm">确认</MudButton>
 | 
			
		||||
    </DialogActions>
 | 
			
		||||
</MudDialog>
 | 
			
		||||
 | 
			
		||||
@code {
 | 
			
		||||
	[CascadingParameter]
 | 
			
		||||
	private IMudDialogInstance MudDialog { get; set; }
 | 
			
		||||
 | 
			
		||||
	[Parameter]
 | 
			
		||||
	public BlazoredTextEditor TextEditor { get; set; } = new BlazoredTextEditor();
 | 
			
		||||
	[Parameter]
 | 
			
		||||
	public string EditorText { get; set; } = "{}";
 | 
			
		||||
 | 
			
		||||
	private void HandleClick()
 | 
			
		||||
	{
 | 
			
		||||
		TextEditor.InsertText(EditorText);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private void Cancel() => MudDialog.Cancel();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	protected async override Task OnInitializedAsync()
 | 
			
		||||
	{
 | 
			
		||||
		await DelayInsert();
 | 
			
		||||
		await base.OnInitializedAsync();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	private async Task DelayInsert()
 | 
			
		||||
	{
 | 
			
		||||
		await Task.Delay(100);
 | 
			
		||||
		HandleClick();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private async void Confirm()
 | 
			
		||||
	{
 | 
			
		||||
		Snackbar.Add("属性已更新", Severity.Success);
 | 
			
		||||
		EditorText = await TextEditor.GetText();
 | 
			
		||||
		MudDialog.Close(DialogResult.Ok(TextEditor));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,17 +1,66 @@
 | 
			
		||||
@using Entities.DTO
 | 
			
		||||
@using Entities.Contracts
 | 
			
		||||
@using TechHelper.Client.Exam
 | 
			
		||||
@using TechHelper.Client.Pages.Exam.QuestionCard
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<MudPaper>
 | 
			
		||||
	<MudText>@AssignmentQuestion.Id</MudText>
 | 
			
		||||
	<MudTextField @bind-Value="AssignmentQuestion.Title" Label="Title" Variant="Variant.Outlined" Margin="Margin.Dense" AutoFocus="true" />
 | 
			
		||||
	<MudTextField @bind-Value="AssignmentQuestion.Index" Label="Index" Variant="Variant.Outlined" Adornment="Adornment.End" AdornmentText="." Margin="Margin.Dense" AutoFocus="true" />
 | 
			
		||||
	<MudTextField @bind-Value="AssignmentQuestion.Score" Label="Score" Variant="Variant.Outlined" Adornment="Adornment.End" AdornmentText="." Margin="Margin.Dense" AutoFocus="true" />
 | 
			
		||||
	<QuestionEdit Question="AssignmentQuestion.Question"/>
 | 
			
		||||
<MudPaper Elevation="0" Class="rounded-xl" Style="background-color: transparent">
 | 
			
		||||
	@* <MudText>@AssignmentQuestion.Id</MudText> *@
 | 
			
		||||
	<MudPaper Class="ma-4 pa-5 rounded-xl">
 | 
			
		||||
		<MudText Class="mt-3" Typo="Typo.button"><b>包裹器属性</b></MudText>
 | 
			
		||||
		<MudTextField @bind-Value="AssignmentQuestion.Title" Label="Title" Variant="Variant.Text" Margin="Margin.Dense" AutoFocus="true" />
 | 
			
		||||
		<MudTextField @bind-Value="AssignmentQuestion.Index" Label="Index" Variant="Variant.Text" Adornment="Adornment.End" AdornmentText="." Margin="Margin.Dense" AutoFocus="true" />
 | 
			
		||||
		<MudTextField @bind-Value="AssignmentQuestion.Score" Label="Score" Variant="Variant.Text" Adornment="Adornment.End" AdornmentText="." Margin="Margin.Dense" AutoFocus="true" />
 | 
			
		||||
		<MudChipSet T="AssignmentStructType" SelectedValue="AssignmentQuestion.StructType" CheckMark SelectionMode="SelectionMode.SingleSelection" SelectedValueChanged="HandleSelectedValueChanged">
 | 
			
		||||
			<MudChip Text="pink" Color="Color.Secondary" Value="@AssignmentStructType.Struct">@AssignmentStructType.Struct</MudChip>
 | 
			
		||||
			<MudChip Text="purple" Color="Color.Primary" Value="@AssignmentStructType.Group">@AssignmentStructType.Group</MudChip>
 | 
			
		||||
			<MudChip Text="blue" Color="Color.Info" Value="@AssignmentStructType.Question">@AssignmentStructType.Question</MudChip>
 | 
			
		||||
			<MudChip Text="green" Color="Color.Warning" Value="@AssignmentStructType.SubQuestion">@AssignmentStructType.SubQuestion</MudChip>
 | 
			
		||||
			<MudChip Text="orange" Color="Color.Error" Value="@AssignmentStructType.Option">@AssignmentStructType.Option</MudChip>
 | 
			
		||||
		</MudChipSet>
 | 
			
		||||
	</MudPaper>
 | 
			
		||||
	@if (AssignmentQuestion.Question != null)
 | 
			
		||||
	{
 | 
			
		||||
		<QuestionEdit Question="AssignmentQuestion.Question" />
 | 
			
		||||
	}
 | 
			
		||||
</MudPaper>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@code {
 | 
			
		||||
	[Parameter]
 | 
			
		||||
	public AssignmentQuestionDto AssignmentQuestion { get; set; } = new AssignmentQuestionDto();
 | 
			
		||||
	public QuestionDto TempQuesdto;
 | 
			
		||||
	protected override void OnInitialized()
 | 
			
		||||
	{
 | 
			
		||||
		base.OnInitialized();
 | 
			
		||||
		if (AssignmentQuestion.Question != null)
 | 
			
		||||
		{
 | 
			
		||||
			TempQuesdto = AssignmentQuestion.Question;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private void HandleSelectedValueChanged(AssignmentStructType type)
 | 
			
		||||
	{
 | 
			
		||||
		AssignmentQuestion.StructType = type;
 | 
			
		||||
		if (type != AssignmentStructType.Question && AssignmentQuestion.Question != null)
 | 
			
		||||
		{
 | 
			
		||||
			AssignmentQuestion.Title = AssignmentQuestion.Question.Title;
 | 
			
		||||
			AssignmentQuestion.Question = null;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (type == AssignmentStructType.Question && AssignmentQuestion.Question == null)
 | 
			
		||||
		{
 | 
			
		||||
			if (TempQuesdto != null)
 | 
			
		||||
			{
 | 
			
		||||
				AssignmentQuestion.Question = TempQuesdto;
 | 
			
		||||
				if (AssignmentQuestion.Title == AssignmentQuestion.Question.Title)
 | 
			
		||||
				{
 | 
			
		||||
					AssignmentQuestion.Title = "";
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
				AssignmentQuestion.Question = new QuestionDto { };
 | 
			
		||||
		}
 | 
			
		||||
		StateHasChanged();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,7 @@
 | 
			
		||||
@page "/exam/create"
 | 
			
		||||
@using AutoMapper
 | 
			
		||||
@using TechHelper.Client.Pages.Common
 | 
			
		||||
@using TechHelper.Client.Pages.Exam.ExamView
 | 
			
		||||
@using TechHelper.Client.Services
 | 
			
		||||
@using Blazored.TextEditor
 | 
			
		||||
@using Entities.DTO
 | 
			
		||||
@@ -9,9 +11,9 @@
 | 
			
		||||
@using Microsoft.AspNetCore.Components
 | 
			
		||||
@using System.Globalization;
 | 
			
		||||
@using TechHelper.Client.Pages.Editor
 | 
			
		||||
@inject IDialogService DialogService
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<MudPaper Elevation="5" Class="d-flex overflow-hidden flex-grow-1" Style="overflow:hidden; position:relative;height:100%">
 | 
			
		||||
<MudPaper Elevation="5" Class="d-flex overflow-hidden flex-grow-1 pa-1 rounded-xl " Style="overflow:hidden; position:relative;height:100%">
 | 
			
		||||
	<MudDrawerContainer Class="mud-height-full flex-grow-1" Style="height:100%">
 | 
			
		||||
		<MudDrawer @bind-Open="@_open" Elevation="0" Variant="@DrawerVariant.Persistent" Color="Color.Primary" Anchor="Anchor.End" OverlayAutoClose="true">
 | 
			
		||||
 | 
			
		||||
@@ -34,45 +36,18 @@
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		</MudDrawer>
 | 
			
		||||
		<MudStack Row="true" Class="flex-grow-1" Style="height:100%">
 | 
			
		||||
			<ExamView Class="overflow-auto" ClickedStruct="HandleClickedStruct" ParsedExam="ExamContent"></ExamView>
 | 
			
		||||
		<MudStack Class="flex-grow-1 h-100">
 | 
			
		||||
 | 
			
		||||
			<MudPaper Class="ma-2">
 | 
			
		||||
				<MudPaper Elevation="0" Style="height:calc(100% - 80px)">
 | 
			
		||||
					<BlazoredTextEditor @ref="@_textEditor">
 | 
			
		||||
						<ToolbarContent>
 | 
			
		||||
							<select class="ql-header">
 | 
			
		||||
								<option selected=""></option>
 | 
			
		||||
								<option value="1"></option>
 | 
			
		||||
								<option value="2"></option>
 | 
			
		||||
								<option value="3"></option>
 | 
			
		||||
								<option value="4"></option>
 | 
			
		||||
								<option value="5"></option>
 | 
			
		||||
							</select>
 | 
			
		||||
							<span class="ql-formats">
 | 
			
		||||
								<button class="ql-bold"></button>
 | 
			
		||||
								<button class="ql-italic"></button>
 | 
			
		||||
								<button class="ql-underline"></button>
 | 
			
		||||
								<button class="ql-strike"></button>
 | 
			
		||||
							</span>
 | 
			
		||||
							<span class="ql-formats">
 | 
			
		||||
								<select class="ql-color"></select>
 | 
			
		||||
								<select class="ql-background"></select>
 | 
			
		||||
							</span>
 | 
			
		||||
							<span class="ql-formats">
 | 
			
		||||
								<button class="ql-list" value="ordered"></button>
 | 
			
		||||
								<button class="ql-list" value="bullet"></button>
 | 
			
		||||
							</span>
 | 
			
		||||
							<span class="ql-formats">
 | 
			
		||||
								<button class="ql-link"></button>
 | 
			
		||||
							</span>
 | 
			
		||||
						</ToolbarContent>
 | 
			
		||||
						<EditorContent>
 | 
			
		||||
						</EditorContent>
 | 
			
		||||
					</BlazoredTextEditor>
 | 
			
		||||
				</MudPaper>
 | 
			
		||||
			<MudPaper Class="rounded-xl ma-1 pa-2" Style="background-color:#fefefefe">
 | 
			
		||||
				<MudButton Variant="Variant.Filled" Color="Color.Secondary" Class="rounded-xl" Size="Size.Small"  OnClick="OpenEditor">文本编辑器</MudButton>
 | 
			
		||||
				<MudButton Variant="Variant.Filled" Color="Color.Secondary" Class="rounded-xl" Size="Size.Small"  OnClick="ParseExam">载入</MudButton>
 | 
			
		||||
				<MudButton Variant="Variant.Filled" Color="Color.Secondary" Class="rounded-xl" Size="Size.Small"  OnClick="OpenPublish">发布</MudButton>
 | 
			
		||||
				<MudButton Variant="Variant.Filled" Color="Color.Secondary" Class="rounded-xl" Size="Size.Small"  OnClick="OpenPublish">指派</MudButton>
 | 
			
		||||
			</MudPaper>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
			<ExamView Class="overflow-auto ma-1 pa-2 rounded-xl" ClickedStruct="HandleClickedStruct" ParsedExam="ExamContent"></ExamView>
 | 
			
		||||
 | 
			
		||||
			<MudPaper MaxWidth="300">
 | 
			
		||||
 | 
			
		||||
				@if (_parsedExam.Errors.Any())
 | 
			
		||||
@@ -83,12 +58,6 @@
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			</MudPaper>
 | 
			
		||||
			<MudButtonGroup Vertical="true" Color="Color.Primary" Variant="Variant.Filled">
 | 
			
		||||
				<MudIconButton Icon="@Icons.Material.Filled.Settings" OnClick="@ToggleDrawer" Color="Color.Secondary" />
 | 
			
		||||
				<MudIconButton Icon="@Icons.Material.Filled.TransitEnterexit" OnClick="@ParseExam" Color="Color.Secondary" />
 | 
			
		||||
				<MudIconButton Icon="@Icons.Material.Filled.Save" OnClick="@ToggleDrawer" Color="Color.Secondary" />
 | 
			
		||||
				<MudIconButton Icon="@Icons.Material.Filled.Publish" OnClick="@Publish" Color="Color.Secondary" />
 | 
			
		||||
			</MudButtonGroup>
 | 
			
		||||
		</MudStack>
 | 
			
		||||
	</MudDrawerContainer>
 | 
			
		||||
</MudPaper>
 | 
			
		||||
@@ -99,7 +68,7 @@
 | 
			
		||||
	private Task<AuthenticationState> authenticationStateTask { get; set; }
 | 
			
		||||
 | 
			
		||||
	private AssignmentQuestionDto selectedAssignmentQuestion = new AssignmentQuestionDto();
 | 
			
		||||
 | 
			
		||||
	private IReadOnlyCollection<string> _selected;
 | 
			
		||||
	private bool _open = false;
 | 
			
		||||
	private bool _edit = false;
 | 
			
		||||
 | 
			
		||||
@@ -113,16 +82,53 @@
 | 
			
		||||
	private AssignmentDto ExamContent = new AssignmentDto();
 | 
			
		||||
 | 
			
		||||
	private ExamParserConfig _examParserConfig { get; set; } = new ExamParserConfig();
 | 
			
		||||
	private string EditorText = "";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	[Inject]
 | 
			
		||||
	public IMapper Mapper { get; set; }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	private void HandleClickedStruct(AssignmentQuestionDto dto)
 | 
			
		||||
	private async void OpenEditor()
 | 
			
		||||
	{
 | 
			
		||||
		_open = true;
 | 
			
		||||
		_edit = true;
 | 
			
		||||
		selectedAssignmentQuestion = dto;
 | 
			
		||||
		var parameters = new DialogParameters<TextEditorDialog> { { x => x.TextEditor, _textEditor } };
 | 
			
		||||
		parameters.Add("EditorText", EditorText);
 | 
			
		||||
 | 
			
		||||
		var dialog = await DialogService.ShowAsync<TextEditorDialog>("TextEditor", parameters);
 | 
			
		||||
		var result = await dialog.Result;
 | 
			
		||||
		if (!result.Canceled)
 | 
			
		||||
		{
 | 
			
		||||
			_textEditor = result.Data as BlazoredTextEditor ?? new BlazoredTextEditor();
 | 
			
		||||
			await ParseExam();
 | 
			
		||||
		}
 | 
			
		||||
		StateHasChanged();
 | 
			
		||||
	}
 | 
			
		||||
	private async void OpenPublish()
 | 
			
		||||
	{
 | 
			
		||||
		var parameters = new DialogParameters<PublishExamDialog> { { x => x.Exam, ExamContent } };
 | 
			
		||||
 | 
			
		||||
		var dialog = await DialogService.ShowAsync<PublishExamDialog>("PublishExam", parameters);
 | 
			
		||||
		var result = await dialog.Result;
 | 
			
		||||
		if (!result.Canceled)
 | 
			
		||||
		{
 | 
			
		||||
			await Publish();
 | 
			
		||||
		}
 | 
			
		||||
		StateHasChanged();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private async void HandleClickedStruct(AssignmentQuestionDto dto)
 | 
			
		||||
	{
 | 
			
		||||
		// _open = true;
 | 
			
		||||
		// _edit = true;
 | 
			
		||||
		// StateHasChanged();
 | 
			
		||||
 | 
			
		||||
		var parameters = new DialogParameters<QuestionCardDialog> { { x => x.Questions, dto } };
 | 
			
		||||
 | 
			
		||||
		var dialog = await DialogService.ShowAsync<QuestionCardDialog>("Edit_Question", parameters);
 | 
			
		||||
		var result = await dialog.Result;
 | 
			
		||||
		if (!result.Canceled)
 | 
			
		||||
		{
 | 
			
		||||
		}
 | 
			
		||||
		StateHasChanged();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -130,7 +136,7 @@
 | 
			
		||||
	{
 | 
			
		||||
 | 
			
		||||
		var plainText = await _textEditor.GetText();
 | 
			
		||||
 | 
			
		||||
		EditorText = plainText;
 | 
			
		||||
 | 
			
		||||
		if (!string.IsNullOrWhiteSpace(plainText))
 | 
			
		||||
		{
 | 
			
		||||
@@ -170,4 +176,54 @@
 | 
			
		||||
		Snackbar.Add(apiRespon.Message);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<!-- #region name -->
 | 
			
		||||
@* 			<MudButtonGroup Vertical="true" Color="Color.Primary" Variant="Variant.Filled">
 | 
			
		||||
				<MudIconButton Icon="@Icons.Material.Filled.Settings" OnClick="@ToggleDrawer" Color="Color.Secondary" />
 | 
			
		||||
				<MudIconButton Icon="@Icons.Material.Filled.TransitEnterexit" OnClick="@ParseExam" Color="Color.Secondary" />
 | 
			
		||||
				<MudIconButton Icon="@Icons.Material.Filled.Save" OnClick="@ToggleDrawer" Color="Color.Secondary" />
 | 
			
		||||
				<MudIconButton Icon="@Icons.Material.Filled.Publish" OnClick="@Publish" Color="Color.Secondary" />
 | 
			
		||||
			</MudButtonGroup> *@
 | 
			
		||||
@* 				<MudPaper Class="ma-2 h-100">
 | 
			
		||||
					<MudPaper Elevation="0" Style="height:calc(100% - 80px)">
 | 
			
		||||
						<BlazoredTextEditor  @ref="@_textEditor">
 | 
			
		||||
							<ToolbarContent>
 | 
			
		||||
								<select class="ql-header">
 | 
			
		||||
									<option selected=""></option>
 | 
			
		||||
									<option value="1"></option>
 | 
			
		||||
									<option value="2"></option>
 | 
			
		||||
									<option value="3"></option>
 | 
			
		||||
									<option value="4"></option>
 | 
			
		||||
									<option value="5"></option>
 | 
			
		||||
								</select>
 | 
			
		||||
								<span class="ql-formats">
 | 
			
		||||
									<button class="ql-bold"></button>
 | 
			
		||||
									<button class="ql-italic"></button>
 | 
			
		||||
									<button class="ql-underline"></button>
 | 
			
		||||
									<button class="ql-strike"></button>
 | 
			
		||||
								</span>
 | 
			
		||||
								<span class="ql-formats">
 | 
			
		||||
									<select class="ql-color"></select>
 | 
			
		||||
									<select class="ql-background"></select>
 | 
			
		||||
								</span>
 | 
			
		||||
								<span class="ql-formats">
 | 
			
		||||
									<button class="ql-list" value="ordered"></button>
 | 
			
		||||
									<button class="ql-list" value="bullet"></button>
 | 
			
		||||
								</span>
 | 
			
		||||
								<span class="ql-formats">
 | 
			
		||||
									<button class="ql-link"></button>
 | 
			
		||||
								</span>
 | 
			
		||||
							</ToolbarContent>
 | 
			
		||||
							<EditorContent>
 | 
			
		||||
							</EditorContent>
 | 
			
		||||
						</BlazoredTextEditor>
 | 
			
		||||
					</MudPaper>
 | 
			
		||||
				</MudPaper> *@
 | 
			
		||||
 | 
			
		||||
<!-- #endregion -->
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
@page "/exam/edit/{ExamId}"
 | 
			
		||||
@using Entities.DTO
 | 
			
		||||
@using TechHelper.Client.Pages.Exam.ExamView
 | 
			
		||||
@using TechHelper.Client.Services
 | 
			
		||||
@using Entities.DTO
 | 
			
		||||
@using TechHelper.Client.Exam
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
@using Entities.DTO
 | 
			
		||||
@using Microsoft.AspNetCore.Authorization
 | 
			
		||||
@using TechHelper.Client.Exam
 | 
			
		||||
 | 
			
		||||
@using TechHelper.Client.Pages.Common.Exam
 | 
			
		||||
 | 
			
		||||
@page "/exam/manage"
 | 
			
		||||
@using Entities.DTO
 | 
			
		||||
@@ -21,7 +21,8 @@ else
 | 
			
		||||
<MudPaper Class="d-flex flex-wrap flex-grow-0 gap-4" Height="100%" Width="100%">
 | 
			
		||||
	@foreach (var item in examDtos)
 | 
			
		||||
	{
 | 
			
		||||
		<ExamPreview AssignmentDto="item" Width="256px" Height="256px"> </ExamPreview>
 | 
			
		||||
		@* <ExamPreview AssignmentDto="item" Width="256px" Height="256px"> </ExamPreview> *@
 | 
			
		||||
		<AssignmentInfoCard></AssignmentInfoCard>
 | 
			
		||||
	}
 | 
			
		||||
</MudPaper>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,51 +0,0 @@
 | 
			
		||||
@using Entities.DTO
 | 
			
		||||
@using TechHelper.Client.Exam
 | 
			
		||||
 | 
			
		||||
<MudPaper @onclick:stopPropagation>
 | 
			
		||||
	<MudPaper Elevation=@Elevation Class=@Class @onclick="HandleClick">
 | 
			
		||||
 | 
			
		||||
		<MudStack Row="true">
 | 
			
		||||
			<MudText Typo="Typo.h6">@ExamStruct.Title</MudText>
 | 
			
		||||
			@if (ExamStruct.Score > 0)
 | 
			
		||||
			{
 | 
			
		||||
				<MudText Typo="Typo.body2"><b>总分:</b> @ExamStruct.Score 分</MudText>
 | 
			
		||||
			}
 | 
			
		||||
		</MudStack>
 | 
			
		||||
 | 
			
		||||
		@if (ExamStruct.Question != null)
 | 
			
		||||
		{
 | 
			
		||||
			<QuestionCard Question="ExamStruct.Question" Index="ExamStruct.Index" Elevation=@Elevation Class="my-2 pa-1" />
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		@foreach (var examStruct in ExamStruct.ChildrenAssignmentQuestion)
 | 
			
		||||
		{
 | 
			
		||||
			<ExamStructView ExamStruct="examStruct" ClickedStruct="HandleChildStructClick" Elevation=@Elevation Class="my-2 pa-1" />
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	</MudPaper>
 | 
			
		||||
</MudPaper>
 | 
			
		||||
 | 
			
		||||
@code {
 | 
			
		||||
	[Parameter]
 | 
			
		||||
	public AssignmentQuestionDto ExamStruct { get; set; } = new AssignmentQuestionDto();
 | 
			
		||||
 | 
			
		||||
	[Parameter]
 | 
			
		||||
	public EventCallback<AssignmentQuestionDto> ClickedStruct { get; set; }
 | 
			
		||||
 | 
			
		||||
	[Parameter]
 | 
			
		||||
	public string Class { get; set; } = "my-2 pa-1";
 | 
			
		||||
 | 
			
		||||
	[Parameter]
 | 
			
		||||
	public int Elevation { get; set; } = 0;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	private async void HandleClick()
 | 
			
		||||
	{
 | 
			
		||||
		await ClickedStruct.InvokeAsync(ExamStruct);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private async void HandleChildStructClick(AssignmentQuestionDto clickedChildExamStruct)
 | 
			
		||||
	{
 | 
			
		||||
		await ClickedStruct.InvokeAsync(clickedChildExamStruct);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										87
									
								
								TechHelper.Client/Pages/Exam/ExamView/ExamStructView.razor
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								TechHelper.Client/Pages/Exam/ExamView/ExamStructView.razor
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,87 @@
 | 
			
		||||
@using Entities.Contracts
 | 
			
		||||
@using Entities.DTO
 | 
			
		||||
@using TechHelper.Client.Exam
 | 
			
		||||
@using TechHelper.Client.Pages.Exam.QuestionCard
 | 
			
		||||
 | 
			
		||||
<MudPaper @onclick:stopPropagation Style="background-color:transparent" Elevation="0">
 | 
			
		||||
	<MudPaper Elevation=@Elevation Class=@Class @onclick="HandleClick" Style="@Style">
 | 
			
		||||
 | 
			
		||||
		<MudStack Row="true" Class="justify-content-between align-content-center" Style="background-color: transparent">
 | 
			
		||||
			<MudText Class="justify-content-lg-start" Typo="Typo.h6">@ExamStruct.Title</MudText>
 | 
			
		||||
			<MudStack Row="true" Class="align-content-center">
 | 
			
		||||
				<MudText Class="ma-auto" Align="Align.Center" Typo="Typo.body2"> Num: @ExamStruct.ChildrenAssignmentQuestion.Count</MudText>
 | 
			
		||||
				<MudText Class="ma-auto" Align="Align.Center" Typo="Typo.body2"><b>总分:</b> @ExamStruct.Score 分</MudText>
 | 
			
		||||
				<MudToggleIconButton @bind-Toggled="ExamStruct.BCorrect"
 | 
			
		||||
									 Icon="@Icons.Material.Filled.Close"
 | 
			
		||||
									 Color="@Color.Error"
 | 
			
		||||
									 ToggledIcon="@Icons.Material.Filled.Check"
 | 
			
		||||
									 ToggledColor="@Color.Success"
 | 
			
		||||
									 title="@(ExamStruct.BCorrect ? "On" : "Off")" />
 | 
			
		||||
 | 
			
		||||
				<MudIconButton Color="Color.Tertiary" Icon="@Icons.Material.Filled.ExpandLess" Size="Size.Small" />
 | 
			
		||||
				<MudIconButton Color="Color.Tertiary" Icon="@Icons.Material.Filled.ExpandMore" Size="Size.Small" />
 | 
			
		||||
				<MudIconButton Icon="@Icons.Material.Filled.Delete" aria-label="delete" Size="Size.Small" />
 | 
			
		||||
				<MudChip T="string" Color="Color.Info" Class="justify-content-end">@ExamStruct.StructType</MudChip>
 | 
			
		||||
			</MudStack>
 | 
			
		||||
		</MudStack>
 | 
			
		||||
 | 
			
		||||
		@if (ExamStruct.Question != null)
 | 
			
		||||
		{
 | 
			
		||||
			<QuestionCard Question="ExamStruct.Question" Index="ExamStruct.Index" Elevation=0 Class="my-2 pa-1 rounded-xl"  />
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		@foreach (var examStruct in ExamStruct.ChildrenAssignmentQuestion)
 | 
			
		||||
		{
 | 
			
		||||
			<ExamStructView ExamStruct="examStruct" ClickedStruct="HandleChildStructClick" Elevation=@(examStruct.Question != null
 | 
			
		||||
								 && examStruct.ChildrenAssignmentQuestion.Count == 0 ? 0 : 0) Class="@($"my-2 pa-1 rounded-xl {(examStruct.StructType != AssignmentStructType.Question ? "my-5" : "my-1")}")"
 | 
			
		||||
						Style=@(examStruct.StructType switch
 | 
			
		||||
	  {
 | 
			
		||||
		  AssignmentStructType.Question => "background-color: #ececec",
 | 
			
		||||
		  AssignmentStructType.Group => "background-color: #ffffff",
 | 
			
		||||
		  AssignmentStructType.Struct => "background-color: #cccccccc",
 | 
			
		||||
		  AssignmentStructType.SubQuestion => "background-color: #ffffff",
 | 
			
		||||
		  AssignmentStructType.Option => "background-color: #ffffff",
 | 
			
		||||
		  _ => "background-color: transparent"
 | 
			
		||||
	  }) />
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
	</MudPaper>
 | 
			
		||||
</MudPaper>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@* 						Style=@(examStruct.StructType switch
 | 
			
		||||
	  {
 | 
			
		||||
		  AssignmentStructType.Question => "background-color: #ffffff",
 | 
			
		||||
		  AssignmentStructType.Composite => "background-color: #ececec",
 | 
			
		||||
		  AssignmentStructType.Struct => "background-color: #dcdcdc",
 | 
			
		||||
		  AssignmentStructType.SubQuestion => "background-color: #ffffff",
 | 
			
		||||
		  AssignmentStructType.Option => "background-color: #dddddd",
 | 
			
		||||
		  _ => "background-color: transparent"
 | 
			
		||||
	  })  *@
 | 
			
		||||
 | 
			
		||||
@code {
 | 
			
		||||
	[Parameter]
 | 
			
		||||
	public AssignmentQuestionDto ExamStruct { get; set; } = new AssignmentQuestionDto();
 | 
			
		||||
 | 
			
		||||
	[Parameter]
 | 
			
		||||
	public EventCallback<AssignmentQuestionDto> ClickedStruct { get; set; }
 | 
			
		||||
 | 
			
		||||
	[Parameter]
 | 
			
		||||
	public string Class { get; set; } = "my-2 pa-1";
 | 
			
		||||
 | 
			
		||||
	[Parameter]
 | 
			
		||||
	public int Elevation { get; set; } = 0;
 | 
			
		||||
 | 
			
		||||
	[Parameter]
 | 
			
		||||
	public string Style { get; set; } = "background-color : #eeeeee";
 | 
			
		||||
 | 
			
		||||
	private async void HandleClick()
 | 
			
		||||
	{
 | 
			
		||||
		await ClickedStruct.InvokeAsync(ExamStruct);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private async void HandleChildStructClick(AssignmentQuestionDto clickedChildExamStruct)
 | 
			
		||||
	{
 | 
			
		||||
		await ClickedStruct.InvokeAsync(clickedChildExamStruct);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -4,11 +4,11 @@
 | 
			
		||||
@if (ParsedExam != null)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	<MudPaper Height="@Height" Class="@Class" Style="@Style" Width="@Width">
 | 
			
		||||
		<MudText Class="d-flex justify-content-center" Typo="Typo.h6"> @ParsedExam.Title </MudText>
 | 
			
		||||
	<MudPaper Height="@Height" Class="@Class" Style="@Style" Width="@Width" Elevation="5">
 | 
			
		||||
		<MudText Class="d-flex justify-content-center" Typo="Typo.button"> <b> @ParsedExam.Title </b></MudText>
 | 
			
		||||
		<MudText Typo="Typo.body1"> @ParsedExam.Description </MudText>
 | 
			
		||||
 | 
			
		||||
		<ExamStructView ExamStruct="@ParsedExam.ExamStruct" Elevation="1" ClickedStruct="HandleClickedStruct" Class="ma-0 pa-2" />
 | 
			
		||||
		<ExamStructView ExamStruct="@ParsedExam.ExamStruct" Elevation="0" ClickedStruct="HandleClickedStruct" Class="ma-0 pa-2 rounded-xl" />
 | 
			
		||||
	</MudPaper>
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
@using Entities.DTO
 | 
			
		||||
@using Entities.Contracts
 | 
			
		||||
@using Entities.DTO
 | 
			
		||||
@using TechHelper.Client.Exam
 | 
			
		||||
 | 
			
		||||
<MudPaper Class=@Class Elevation=@Elevation Outlined="false">
 | 
			
		||||
@@ -28,6 +29,9 @@
 | 
			
		||||
	[Parameter]
 | 
			
		||||
	public QuestionDto Question { get; set; } = new QuestionDto();
 | 
			
		||||
 | 
			
		||||
	[Parameter]
 | 
			
		||||
	public AssignmentStructType Type { get; set; } = AssignmentStructType.Question;
 | 
			
		||||
 | 
			
		||||
	[Parameter]
 | 
			
		||||
	public byte Index { get; set; } = 0;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										18
									
								
								TechHelper.Client/Pages/Exam/QuestionCard/QuestionEdit.razor
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								TechHelper.Client/Pages/Exam/QuestionCard/QuestionEdit.razor
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
			
		||||
@using Entities.DTO
 | 
			
		||||
@using TechHelper.Client.Exam
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<MudPaper Elevation="1" Class="ma-4 pa-5 rounded-xl">
 | 
			
		||||
	@* <MudText>@Question.Id</MudText> *@
 | 
			
		||||
	<MudText Class="mt-3" Typo="Typo.button"><b>问题属性</b></MudText>
 | 
			
		||||
	<MudTextField @bind-Value="Question.Title" Label="Title" Variant="Variant.Text" Margin="Margin.Dense" AutoGrow="true" />
 | 
			
		||||
	<MudTextField @bind-Value="Question.Answer" Label="Answer" Variant="Variant.Text" Adornment="Adornment.End" AdornmentText="." Margin="Margin.Dense" AutoGrow="true" />
 | 
			
		||||
	<MudTextField @bind-Value="Question.Options" Label="Options" Variant="Variant.Text" Adornment="Adornment.End" AdornmentText="." Margin="Margin.Dense" AutoGrow="true" />
 | 
			
		||||
 | 
			
		||||
</MudPaper>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@code {
 | 
			
		||||
	[Parameter]
 | 
			
		||||
	public QuestionDto Question { get; set; } = new QuestionDto();
 | 
			
		||||
}
 | 
			
		||||
@@ -1,17 +0,0 @@
 | 
			
		||||
@using Entities.DTO
 | 
			
		||||
@using TechHelper.Client.Exam
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<MudPaper>
 | 
			
		||||
	<MudText>@Question.Id</MudText>
 | 
			
		||||
	<MudTextField @bind-Value="Question.Title" Label="Title" Variant="Variant.Outlined" Margin="Margin.Dense" AutoGrow="true" />
 | 
			
		||||
	<MudTextField @bind-Value="Question.Answer" Label="Answer" Variant="Variant.Outlined" Adornment="Adornment.End" AdornmentText="." Margin="Margin.Dense" AutoGrow="true" />
 | 
			
		||||
	<MudTextField @bind-Value="Question.Options" Label="Options" Variant="Variant.Outlined" Adornment="Adornment.End" AdornmentText="." Margin="Margin.Dense" AutoGrow="true" />
 | 
			
		||||
 | 
			
		||||
</MudPaper>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@code {
 | 
			
		||||
	[Parameter]
 | 
			
		||||
	public QuestionDto Question { get; set; } = new QuestionDto();
 | 
			
		||||
}
 | 
			
		||||
@@ -1,10 +1,23 @@
 | 
			
		||||
@page "/"
 | 
			
		||||
@using Microsoft.AspNetCore.Authorization
 | 
			
		||||
@using TechHelper.Client.Pages.Common.Exam
 | 
			
		||||
 | 
			
		||||
<TechHelper.Client.Pages.Teacher.StudentsView/>
 | 
			
		||||
<AuthorizeView Roles="Student">
 | 
			
		||||
	<Authorized>
 | 
			
		||||
		<TechHelper.Client.Pages.Student.HomePage />
 | 
			
		||||
	</Authorized>
 | 
			
		||||
</AuthorizeView>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<AssignmentInfoCard></AssignmentInfoCard>
 | 
			
		||||
 | 
			
		||||
@code {
 | 
			
		||||
	[CascadingParameter]
 | 
			
		||||
	private Task<AuthenticationState> authenticationStateTask { get; set; }
 | 
			
		||||
 | 
			
		||||
	protected override Task OnInitializedAsync()
 | 
			
		||||
	{
 | 
			
		||||
		return base.OnInitializedAsync();
 | 
			
		||||
		Console.WriteLine(authenticationStateTask.Result.User.IsInRole("Student"));
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -3,58 +3,56 @@
 | 
			
		||||
@using System.ComponentModel.DataAnnotations
 | 
			
		||||
@using Microsoft.AspNetCore.Identity
 | 
			
		||||
 | 
			
		||||
<MudPaper Class="flex-grow-1">
 | 
			
		||||
 | 
			
		||||
<PageTitle>Profile</PageTitle>
 | 
			
		||||
 | 
			
		||||
<h3>Profile</h3>
 | 
			
		||||
 | 
			
		||||
<div class="row">
 | 
			
		||||
    <div class="col-md-6">
 | 
			
		||||
        <EditForm Model="Input" FormName="profile" OnValidSubmit="OnValidSubmitAsync" method="post">
 | 
			
		||||
            <DataAnnotationsValidator />
 | 
			
		||||
            <ValidationSummary class="text-danger" role="alert" />
 | 
			
		||||
            <div class="form-floating mb-3">
 | 
			
		||||
                <input type="text" value="@username" class="form-control" placeholder="Please choose your username." disabled />
 | 
			
		||||
                <label for="username" class="form-label">Username</label>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="form-floating mb-3">
 | 
			
		||||
                <InputText @bind-Value="Input.PhoneNumber" class="form-control" placeholder="Please enter your phone number." />
 | 
			
		||||
                <label for="phone-number" class="form-label">Phone number</label>
 | 
			
		||||
                <ValidationMessage For="() => Input.PhoneNumber" class="text-danger" />
 | 
			
		||||
            </div>
 | 
			
		||||
            <button type="submit" class="w-100 btn btn-lg btn-primary">Save</button>
 | 
			
		||||
        </EditForm>
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
	<div class="row">
 | 
			
		||||
		<div class="col-md-6">
 | 
			
		||||
			<EditForm Model="Input" FormName="profile" OnValidSubmit="OnValidSubmitAsync" method="post">
 | 
			
		||||
				<DataAnnotationsValidator />
 | 
			
		||||
				<ValidationSummary class="text-danger" role="alert" />
 | 
			
		||||
				<div class="form-floating mb-3">
 | 
			
		||||
					<input type="text" value="@username" class="form-control" placeholder="Please choose your username." disabled />
 | 
			
		||||
					<label for="username" class="form-label">Username</label>
 | 
			
		||||
				</div>
 | 
			
		||||
				<div class="form-floating mb-3">
 | 
			
		||||
					<InputText @bind-Value="Input.PhoneNumber" class="form-control" placeholder="Please enter your phone number." />
 | 
			
		||||
					<label for="phone-number" class="form-label">Phone number</label>
 | 
			
		||||
					<ValidationMessage For="() => Input.PhoneNumber" class="text-danger" />
 | 
			
		||||
				</div>
 | 
			
		||||
				<button type="submit" class="w-100 btn btn-lg btn-primary">Save</button>
 | 
			
		||||
			</EditForm>
 | 
			
		||||
		</div>
 | 
			
		||||
	</div>
 | 
			
		||||
 | 
			
		||||
</MudPaper>
 | 
			
		||||
@code {
 | 
			
		||||
 | 
			
		||||
    private string? username;
 | 
			
		||||
    private string? phoneNumber;
 | 
			
		||||
	private string? username;
 | 
			
		||||
	private string? phoneNumber;
 | 
			
		||||
 | 
			
		||||
    [CascadingParameter]
 | 
			
		||||
    private Task<AuthenticationState> authenticationStateTask { get; set; }
 | 
			
		||||
	[CascadingParameter]
 | 
			
		||||
	private Task<AuthenticationState> authenticationStateTask { get; set; }
 | 
			
		||||
 | 
			
		||||
    [SupplyParameterFromForm]
 | 
			
		||||
    private InputModel Input { get; set; } = new();
 | 
			
		||||
	[SupplyParameterFromForm]
 | 
			
		||||
	private InputModel Input { get; set; } = new();
 | 
			
		||||
 | 
			
		||||
    protected override async Task OnInitializedAsync()
 | 
			
		||||
    {
 | 
			
		||||
        username = authenticationStateTask.Result.User.Identity.Name;
 | 
			
		||||
        phoneNumber = authenticationStateTask.Result.User.Identity.IsAuthenticated.ToString();
 | 
			
		||||
	protected override async Task OnInitializedAsync()
 | 
			
		||||
	{
 | 
			
		||||
		username = authenticationStateTask.Result.User.Identity.Name;
 | 
			
		||||
		phoneNumber = authenticationStateTask.Result.User.Identity.IsAuthenticated.ToString();
 | 
			
		||||
 | 
			
		||||
        Input.PhoneNumber ??= phoneNumber;
 | 
			
		||||
    }
 | 
			
		||||
		Input.PhoneNumber ??= phoneNumber;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    private async Task OnValidSubmitAsync()
 | 
			
		||||
    {
 | 
			
		||||
	private async Task OnValidSubmitAsync()
 | 
			
		||||
	{
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    private sealed class InputModel
 | 
			
		||||
    {
 | 
			
		||||
        [Phone]
 | 
			
		||||
        [Display(Name = "Phone number")]
 | 
			
		||||
        public string? PhoneNumber { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
	private sealed class InputModel
 | 
			
		||||
	{
 | 
			
		||||
		[Phone]
 | 
			
		||||
		[Display(Name = "Phone number")]
 | 
			
		||||
		public string? PhoneNumber { get; set; }
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										141
									
								
								TechHelper.Client/Pages/Student/HomePage.razor
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								TechHelper.Client/Pages/Student/HomePage.razor
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,141 @@
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<MudPaper Class="flex-grow-1 w-100 h-100 ma-auto">
 | 
			
		||||
	<MudGrid Class="w-100 h-100">
 | 
			
		||||
		<MudItem xs="12" sm="4">
 | 
			
		||||
			<MudPaper Style="background-color:transparent" Class="w-100 justify-content-center">
 | 
			
		||||
				<MudChart ChartType="ChartType.Donut" Width="200px" Height="200px" InputData="@data" InputLabels="@labels" Class="ma-auto">
 | 
			
		||||
					<CustomGraphics>
 | 
			
		||||
						<text class="donut-inner-text" x="50%" y="35%" dominant-baseline="middle" text-anchor="middle" fill="black" font-family="Helvetica" font-size="20">Total</text>
 | 
			
		||||
						<text class="donut-inner-text" x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" fill="black" font-family="Helvetica" font-size="50">@data.Sum().ToString()</text>
 | 
			
		||||
					</CustomGraphics>
 | 
			
		||||
				</MudChart>
 | 
			
		||||
			</MudPaper>
 | 
			
		||||
 | 
			
		||||
			<MudPaper Style="background-color:transparent" Class="w-100 pa-5">
 | 
			
		||||
				<TechHelper.Client.Pages.Common.SimpleCard Style="background-color:#ff4081">
 | 
			
		||||
					<BodyContent>
 | 
			
		||||
						<MudText>BodyContent</MudText>
 | 
			
		||||
					</BodyContent>
 | 
			
		||||
					<TitleContent>
 | 
			
		||||
						<MudText>TitleContent</MudText>
 | 
			
		||||
					</TitleContent>
 | 
			
		||||
					<FooterContent>
 | 
			
		||||
						<MudText>FooterContent</MudText>
 | 
			
		||||
					</FooterContent>
 | 
			
		||||
				</TechHelper.Client.Pages.Common.SimpleCard>
 | 
			
		||||
 | 
			
		||||
				<TechHelper.Client.Pages.Common.SimpleCard Style="background-color:#1ec8a5">
 | 
			
		||||
					<BodyContent>
 | 
			
		||||
						<MudText>BodyContent</MudText>
 | 
			
		||||
					</BodyContent>
 | 
			
		||||
					<TitleContent>
 | 
			
		||||
						<MudText>TitleContent</MudText>
 | 
			
		||||
					</TitleContent>
 | 
			
		||||
					<FooterContent>
 | 
			
		||||
						<MudText>FooterContent</MudText>
 | 
			
		||||
					</FooterContent>
 | 
			
		||||
				</TechHelper.Client.Pages.Common.SimpleCard>
 | 
			
		||||
 | 
			
		||||
				<TechHelper.Client.Pages.Common.SimpleCard Style="background-color:#4680ff">
 | 
			
		||||
					<TitleContent>
 | 
			
		||||
						<MudText Typo="Typo.body1">TitleContent</MudText>
 | 
			
		||||
					</TitleContent>
 | 
			
		||||
					<BodyContent>
 | 
			
		||||
						<MudText Typo="Typo.button"><b>BodyContent</b></MudText>
 | 
			
		||||
					</BodyContent>
 | 
			
		||||
					<FooterContent>
 | 
			
		||||
						<MudText Typo="Typo.body2">leran about this curson</MudText>
 | 
			
		||||
					</FooterContent>
 | 
			
		||||
				</TechHelper.Client.Pages.Common.SimpleCard>
 | 
			
		||||
			</MudPaper>
 | 
			
		||||
		</MudItem>
 | 
			
		||||
 | 
			
		||||
		<MudItem xs="12" sm="8">
 | 
			
		||||
			<MudPaper Style="background-color:transparent" Class="w-100 h-100">
 | 
			
		||||
 | 
			
		||||
				<TechHelper.Client.Pages.Common.SimpleCard Style="background-color:#c2bef8" Height="350px">
 | 
			
		||||
					<TitleContent>
 | 
			
		||||
						<MudText Typo="Typo.button"><b>Visits Summary:</b></MudText>
 | 
			
		||||
					</TitleContent>
 | 
			
		||||
					<BodyContent>
 | 
			
		||||
						<MudChart ChartType="ChartType.Line" LegendPosition="Position.Left" Class="pt-55" ChartSeries="@Series" XAxisLabels="@XAxisLabels" Height="110%" Width="100%" AxisChartOptions="_axisChartOptions" ChartOptions="options"></MudChart>
 | 
			
		||||
					</BodyContent>
 | 
			
		||||
					<FooterContent>
 | 
			
		||||
						<MudText Typo="Typo.body2">leran about this curson</MudText>
 | 
			
		||||
					</FooterContent>
 | 
			
		||||
				</TechHelper.Client.Pages.Common.SimpleCard>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@* 				<TechHelper.Client.Pages.Common.SimpleCard Style="background-color:#c2bef8" Height="100%">
 | 
			
		||||
					<TitleContent>
 | 
			
		||||
						<MudText Typo="Typo.button"><b>Visits Summary:</b></MudText>
 | 
			
		||||
					</TitleContent>
 | 
			
		||||
					<BodyContent>
 | 
			
		||||
						<MudDataGrid Items="@Elements" Filterable="true" FilterMode="@_filterMode" FilterCaseSensitivity="@_caseSensitivity">
 | 
			
		||||
							<Columns>
 | 
			
		||||
								<PropertyColumn Property="x => x.Number" Title="Nr" Filterable="false" />
 | 
			
		||||
								<PropertyColumn Property="x => x.Sign" />
 | 
			
		||||
								<PropertyColumn Property="x => x.Name" />
 | 
			
		||||
								<PropertyColumn Property="x => x.Position" Filterable="false" />
 | 
			
		||||
								<PropertyColumn Property="x => x.Molar" Title="Molar mass" />
 | 
			
		||||
								<PropertyColumn Property="x => x.Group" Title="Category" />
 | 
			
		||||
							</Columns>
 | 
			
		||||
							<PagerContent>
 | 
			
		||||
								<MudDataGridPager T="Element" />
 | 
			
		||||
							</PagerContent>
 | 
			
		||||
						</MudDataGrid>
 | 
			
		||||
					</BodyContent>
 | 
			
		||||
					<FooterContent>
 | 
			
		||||
						<MudText Typo="Typo.body2">leran about this curson</MudText>
 | 
			
		||||
					</FooterContent>
 | 
			
		||||
				</TechHelper.Client.Pages.Common.SimpleCard> *@
 | 
			
		||||
			</MudPaper>
 | 
			
		||||
		</MudItem>
 | 
			
		||||
	</MudGrid>
 | 
			
		||||
</MudPaper>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@code {
 | 
			
		||||
	public double[] data = { 25, 77, 28, 5 };
 | 
			
		||||
	public string[] labels = { "Oil", "Coal", "Gas", "Biomass" };
 | 
			
		||||
	private AxisChartOptions _axisChartOptions = new AxisChartOptions();
 | 
			
		||||
	private ChartOptions options = new ChartOptions();
 | 
			
		||||
	public List<ChartSeries> Series = new List<ChartSeries>()
 | 
			
		||||
	{
 | 
			
		||||
		new ChartSeries() { Name = "Series 1", Data = new double[] { 90, 79, 72, 69, 62, 62, 55, 65, 70 } },
 | 
			
		||||
		new ChartSeries() { Name = "Series 2", Data = new double[] { 35, 41, 35, 51, 49, 62, 69, 91, 148 } },
 | 
			
		||||
	};
 | 
			
		||||
	public string[] XAxisLabels = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep" };
 | 
			
		||||
 | 
			
		||||
	Random random = new Random();
 | 
			
		||||
	protected override void OnInitialized()
 | 
			
		||||
	{
 | 
			
		||||
		options.InterpolationOption = InterpolationOption.NaturalSpline;
 | 
			
		||||
		options.YAxisFormat = "c2";
 | 
			
		||||
		_axisChartOptions.MatchBoundsToSize = true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public void RandomizeData()
 | 
			
		||||
	{
 | 
			
		||||
		foreach (var series in Series)
 | 
			
		||||
		{
 | 
			
		||||
			for (int i = 0; i < series.Data.Length - 1; i++)
 | 
			
		||||
			{
 | 
			
		||||
				series.Data[i] = random.NextDouble() * 100 + 10;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		StateHasChanged();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void OnClickMenu(InterpolationOption interpolationOption)
 | 
			
		||||
	{
 | 
			
		||||
		options.InterpolationOption = interpolationOption;
 | 
			
		||||
		StateHasChanged();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -14,7 +14,7 @@
 | 
			
		||||
      "dotnetRunMessages": true,
 | 
			
		||||
      "launchBrowser": true,
 | 
			
		||||
      "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
 | 
			
		||||
      "applicationUrl": "https://localhost:7047;http://localhost:5190",
 | 
			
		||||
      "applicationUrl": "https://localhost:7047",
 | 
			
		||||
      "environmentVariables": {
 | 
			
		||||
        "ASPNETCORE_ENVIRONMENT": "Development"
 | 
			
		||||
      }
 | 
			
		||||
@@ -28,4 +28,6 @@
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -38,6 +38,22 @@ namespace TechHelper.Client.Services
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public async Task<ApiResponse> GetGradeClasses(byte grade)
 | 
			
		||||
		{
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				var result = await _client.PostAsJsonAsync("class/GetGradeClasses", grade);
 | 
			
		||||
				var content = await result.Content.ReadAsStringAsync();
 | 
			
		||||
				Console.WriteLine($"服务器返回的原始内容是: {content}");
 | 
			
		||||
				var users = JsonConvert.DeserializeObject<List<byte>>(content);
 | 
			
		||||
				return ApiResponse.Success(result: users);
 | 
			
		||||
			}
 | 
			
		||||
			catch (Exception ex)
 | 
			
		||||
			{
 | 
			
		||||
				return ApiResponse.Error($"获取失败,{ex.Message}, InnerException: {ex.InnerException}");
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public async Task<ResponseDto> UserRegister(UserRegistrationToClassDto userRegistrationToClassDto)
 | 
			
		||||
		{
 | 
			
		||||
			try
 | 
			
		||||
 
 | 
			
		||||
@@ -126,7 +126,7 @@ namespace TechHelper.Client.Services
 | 
			
		||||
		public async Task<ApiResponse> GetExam(Guid guid)
 | 
			
		||||
		{
 | 
			
		||||
 | 
			
		||||
			var response = await _client.GetAsync($"exam/get?id={guid}");
 | 
			
		||||
			var response = await _client.GetAsync($"exam/{guid}");
 | 
			
		||||
			if (response.IsSuccessStatusCode)
 | 
			
		||||
			{
 | 
			
		||||
				var content = await response.Content.ReadAsStringAsync();
 | 
			
		||||
 
 | 
			
		||||
@@ -8,6 +8,7 @@ namespace TechHelper.Client.Services
 | 
			
		||||
	{
 | 
			
		||||
		public Task<ResponseDto> UserRegister(UserRegistrationToClassDto userRegistrationToClassDto);
 | 
			
		||||
		public Task<ResponseDto> CreateClass(UserRegistrationToClassDto userClass);
 | 
			
		||||
		public Task<ApiResponse> GetClassStudents(); 
 | 
			
		||||
		public Task<ApiResponse> GetClassStudents();
 | 
			
		||||
		public Task<ApiResponse> GetGradeClasses(byte grade);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -5,8 +5,6 @@
 | 
			
		||||
<MudPaper Class="d-flex flex-row flex-grow-1 overflow-hidden" Height="100%">
 | 
			
		||||
 | 
			
		||||
	<MudPaper Width="200px">
 | 
			
		||||
		<h1>Manage your account</h1>
 | 
			
		||||
		<h2>Change your account settings</h2>
 | 
			
		||||
		<MudDivider Class="flex-grow-0" />
 | 
			
		||||
		<ExamNavMenu />
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -3,11 +3,8 @@
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<MudPaper Class="d-flex flex-column flex-grow-1">
 | 
			
		||||
 | 
			
		||||
	<h1>Manage your account</h1>
 | 
			
		||||
	<h2>Change your account settings</h2>
 | 
			
		||||
	<MudDivider Class="flex-grow-0" />
 | 
			
		||||
	<MudStack Row="true">
 | 
			
		||||
	<MudStack Row="true" Class="d-flex flex-grow-1">
 | 
			
		||||
		<ManageNavMenu />
 | 
			
		||||
		@Body
 | 
			
		||||
	</MudStack>
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@
 | 
			
		||||
    <TargetFramework>net8.0</TargetFramework>
 | 
			
		||||
    <Nullable>enable</Nullable>
 | 
			
		||||
    <ImplicitUsings>enable</ImplicitUsings>
 | 
			
		||||
    <DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
@@ -39,4 +40,8 @@
 | 
			
		||||
    <ProjectReference Include="..\Entities\Entities.csproj" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <Folder Include="Pages\Exam\TemplateCard\" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
</Project>
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,6 @@
 | 
			
		||||
    "ClientId": "33333333-3333-3333-33333333333333333"
 | 
			
		||||
  },
 | 
			
		||||
  "ApiConfiguration": {
 | 
			
		||||
    "BaseAddress": "http://localhost:5099"
 | 
			
		||||
    "BaseAddress": "http://localhost:8080"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								TechHelper.Client/wwwroot/ref/Border.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								TechHelper.Client/wwwroot/ref/Border.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 38 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								TechHelper.Client/wwwroot/ref/File.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								TechHelper.Client/wwwroot/ref/File.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 8.2 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								TechHelper.Client/wwwroot/ref/Login.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								TechHelper.Client/wwwroot/ref/Login.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 99 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								TechHelper.Client/wwwroot/ref/UnFinish.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								TechHelper.Client/wwwroot/ref/UnFinish.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 83 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								TechHelper.Client/wwwroot/ref/Working.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								TechHelper.Client/wwwroot/ref/Working.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 73 KiB  | 
@@ -62,7 +62,7 @@ namespace TechHelper.Server.Controllers
 | 
			
		||||
 | 
			
		||||
				var result = await _classService.GetClassStudents(classDto);
 | 
			
		||||
				var css = result.Result as ICollection<ClassStudent>;
 | 
			
		||||
				if(css == null) return BadRequest("你还没有学生");
 | 
			
		||||
				if (css == null) return BadRequest("你还没有学生");
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
				List<StudentDto> sts = new List<StudentDto>();
 | 
			
		||||
@@ -93,5 +93,15 @@ namespace TechHelper.Server.Controllers
 | 
			
		||||
 | 
			
		||||
			return Ok();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		[HttpPost("GetGradeClasses")]
 | 
			
		||||
		public async Task<IActionResult> GetGradeClasses(
 | 
			
		||||
		[FromBody] byte classDto)
 | 
			
		||||
		{
 | 
			
		||||
			var result = await _classService.GetGradeClasses(classDto);
 | 
			
		||||
			if (!result.Status) return BadRequest(result.Message);
 | 
			
		||||
 | 
			
		||||
			return Ok(result.Result);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@ using TechHelper.Services;
 | 
			
		||||
 | 
			
		||||
namespace TechHelper.Server.Controllers
 | 
			
		||||
{
 | 
			
		||||
	[Route("api/[controller]")]
 | 
			
		||||
	[Route("api/exam")]
 | 
			
		||||
	[ApiController]
 | 
			
		||||
	[Authorize]
 | 
			
		||||
	public class ExamController : ControllerBase
 | 
			
		||||
@@ -54,7 +54,6 @@ namespace TechHelper.Server.Controllers
 | 
			
		||||
		/// <param name="submissionDto">提交的数据传输对象。</param>
 | 
			
		||||
		/// <returns>提交结果或错误信息。</returns>
 | 
			
		||||
		[HttpPost("submission")]
 | 
			
		||||
		[Authorize(Roles = "Student")]
 | 
			
		||||
		public async Task<IActionResult> SubmissionAssignment([FromBody] SubmissionDto submissionDto)
 | 
			
		||||
		{
 | 
			
		||||
			var result = await _examService.SubmissionAssignment(submissionDto);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,12 +1,15 @@
 | 
			
		||||
# 请参阅 https://aka.ms/customizecontainer 以了解如何自定义调试容器,以及 Visual Studio 如何使用此 Dockerfile 生成映像以更快地进行调试。
 | 
			
		||||
 | 
			
		||||
# 此阶段用于在快速模式(默认为调试配置)下从 VS 运行时
 | 
			
		||||
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
 | 
			
		||||
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS server
 | 
			
		||||
USER $APP_UID
 | 
			
		||||
WORKDIR /app
 | 
			
		||||
EXPOSE 8080
 | 
			
		||||
EXPOSE 8081
 | 
			
		||||
 | 
			
		||||
COPY --from=entitieslib:latest /publish /publish/entities
 | 
			
		||||
COPY --from=emaillib:latest /publish /publish/emaillib
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 此阶段用于生成服务项目
 | 
			
		||||
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
 | 
			
		||||
@@ -16,15 +19,17 @@ COPY ["TechHelper.Server/TechHelper.Server.csproj", "TechHelper.Server/"]
 | 
			
		||||
RUN dotnet restore "./TechHelper.Server/TechHelper.Server.csproj"
 | 
			
		||||
COPY . .
 | 
			
		||||
WORKDIR "/src/TechHelper.Server"
 | 
			
		||||
RUN dotnet nuget locals all --clear
 | 
			
		||||
RUN dotnet build "./TechHelper.Server.csproj" -c $BUILD_CONFIGURATION -o /app/build
 | 
			
		||||
 | 
			
		||||
# 此阶段用于发布要复制到最终阶段的服务项目
 | 
			
		||||
FROM build AS publish
 | 
			
		||||
ARG BUILD_CONFIGURATION=Release
 | 
			
		||||
RUN dotnet nuget locals all --clear
 | 
			
		||||
RUN dotnet publish "./TechHelper.Server.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
 | 
			
		||||
 | 
			
		||||
# 此阶段在生产中使用,或在常规模式下从 VS 运行时使用(在不使用调试配置时为默认值)
 | 
			
		||||
FROM base AS final
 | 
			
		||||
FROM server AS final
 | 
			
		||||
WORKDIR /app
 | 
			
		||||
COPY --from=publish /app/publish .
 | 
			
		||||
ENTRYPOINT ["dotnet", "TechHelper.Server.dll"]
 | 
			
		||||
							
								
								
									
										1263
									
								
								TechHelper.Server/Migrations/20250828025055_score_in_submission.Designer.cs
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										1263
									
								
								TechHelper.Server/Migrations/20250828025055_score_in_submission.Designer.cs
									
									
									
										generated
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -0,0 +1,104 @@
 | 
			
		||||
using System;
 | 
			
		||||
using Microsoft.EntityFrameworkCore.Migrations;
 | 
			
		||||
 | 
			
		||||
#nullable disable
 | 
			
		||||
 | 
			
		||||
#pragma warning disable CA1814 // Prefer jagged arrays over multidimensional
 | 
			
		||||
 | 
			
		||||
namespace TechHelper.Server.Migrations
 | 
			
		||||
{
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    public partial class score_in_submission : Migration
 | 
			
		||||
    {
 | 
			
		||||
        /// <inheritdoc />
 | 
			
		||||
        protected override void Up(MigrationBuilder migrationBuilder)
 | 
			
		||||
        {
 | 
			
		||||
            migrationBuilder.DeleteData(
 | 
			
		||||
                table: "AspNetRoles",
 | 
			
		||||
                keyColumn: "Id",
 | 
			
		||||
                keyValue: new Guid("379143a2-8d7f-4ef7-b7c0-14701b710f87"));
 | 
			
		||||
 | 
			
		||||
            migrationBuilder.DeleteData(
 | 
			
		||||
                table: "AspNetRoles",
 | 
			
		||||
                keyColumn: "Id",
 | 
			
		||||
                keyValue: new Guid("6d49bb08-97d6-4a38-88a7-8080925b589b"));
 | 
			
		||||
 | 
			
		||||
            migrationBuilder.DeleteData(
 | 
			
		||||
                table: "AspNetRoles",
 | 
			
		||||
                keyColumn: "Id",
 | 
			
		||||
                keyValue: new Guid("e330c745-f422-43e3-bcdf-1439ace3c52f"));
 | 
			
		||||
 | 
			
		||||
            migrationBuilder.AddColumn<byte>(
 | 
			
		||||
                name: "ErrorQuesNum",
 | 
			
		||||
                table: "submissions",
 | 
			
		||||
                type: "tinyint unsigned",
 | 
			
		||||
                nullable: false,
 | 
			
		||||
                defaultValue: (byte)0);
 | 
			
		||||
 | 
			
		||||
            migrationBuilder.AddColumn<byte>(
 | 
			
		||||
                name: "TotalQuesNum",
 | 
			
		||||
                table: "submissions",
 | 
			
		||||
                type: "tinyint unsigned",
 | 
			
		||||
                nullable: false,
 | 
			
		||||
                defaultValue: (byte)0);
 | 
			
		||||
 | 
			
		||||
            migrationBuilder.AddColumn<byte>(
 | 
			
		||||
                name: "TotalScore",
 | 
			
		||||
                table: "submissions",
 | 
			
		||||
                type: "tinyint unsigned",
 | 
			
		||||
                nullable: false,
 | 
			
		||||
                defaultValue: (byte)0);
 | 
			
		||||
 | 
			
		||||
            migrationBuilder.InsertData(
 | 
			
		||||
                table: "AspNetRoles",
 | 
			
		||||
                columns: new[] { "Id", "ConcurrencyStamp", "Name", "NormalizedName" },
 | 
			
		||||
                values: new object[,]
 | 
			
		||||
                {
 | 
			
		||||
                    { new Guid("53307917-63c4-468a-ab05-a03882a69ef8"), null, "Teacher", "TEACHER" },
 | 
			
		||||
                    { new Guid("789b7819-685f-4a2b-9adf-463f397f24d1"), null, "Administrator", "ADMINISTRATOR" },
 | 
			
		||||
                    { new Guid("bbea7915-e27c-4ddc-b06c-1f579fc8104e"), null, "Student", "STUDENT" }
 | 
			
		||||
                });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <inheritdoc />
 | 
			
		||||
        protected override void Down(MigrationBuilder migrationBuilder)
 | 
			
		||||
        {
 | 
			
		||||
            migrationBuilder.DeleteData(
 | 
			
		||||
                table: "AspNetRoles",
 | 
			
		||||
                keyColumn: "Id",
 | 
			
		||||
                keyValue: new Guid("53307917-63c4-468a-ab05-a03882a69ef8"));
 | 
			
		||||
 | 
			
		||||
            migrationBuilder.DeleteData(
 | 
			
		||||
                table: "AspNetRoles",
 | 
			
		||||
                keyColumn: "Id",
 | 
			
		||||
                keyValue: new Guid("789b7819-685f-4a2b-9adf-463f397f24d1"));
 | 
			
		||||
 | 
			
		||||
            migrationBuilder.DeleteData(
 | 
			
		||||
                table: "AspNetRoles",
 | 
			
		||||
                keyColumn: "Id",
 | 
			
		||||
                keyValue: new Guid("bbea7915-e27c-4ddc-b06c-1f579fc8104e"));
 | 
			
		||||
 | 
			
		||||
            migrationBuilder.DropColumn(
 | 
			
		||||
                name: "ErrorQuesNum",
 | 
			
		||||
                table: "submissions");
 | 
			
		||||
 | 
			
		||||
            migrationBuilder.DropColumn(
 | 
			
		||||
                name: "TotalQuesNum",
 | 
			
		||||
                table: "submissions");
 | 
			
		||||
 | 
			
		||||
            migrationBuilder.DropColumn(
 | 
			
		||||
                name: "TotalScore",
 | 
			
		||||
                table: "submissions");
 | 
			
		||||
 | 
			
		||||
            migrationBuilder.InsertData(
 | 
			
		||||
                table: "AspNetRoles",
 | 
			
		||||
                columns: new[] { "Id", "ConcurrencyStamp", "Name", "NormalizedName" },
 | 
			
		||||
                values: new object[,]
 | 
			
		||||
                {
 | 
			
		||||
                    { new Guid("379143a2-8d7f-4ef7-b7c0-14701b710f87"), null, "Administrator", "ADMINISTRATOR" },
 | 
			
		||||
                    { new Guid("6d49bb08-97d6-4a38-88a7-8080925b589b"), null, "Student", "STUDENT" },
 | 
			
		||||
                    { new Guid("e330c745-f422-43e3-bcdf-1439ace3c52f"), null, "Teacher", "TEACHER" }
 | 
			
		||||
                });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										1270
									
								
								TechHelper.Server/Migrations/20250829043403_up_assign_data.Designer.cs
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										1270
									
								
								TechHelper.Server/Migrations/20250829043403_up_assign_data.Designer.cs
									
									
									
										generated
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -0,0 +1,93 @@
 | 
			
		||||
using System;
 | 
			
		||||
using Microsoft.EntityFrameworkCore.Migrations;
 | 
			
		||||
 | 
			
		||||
#nullable disable
 | 
			
		||||
 | 
			
		||||
#pragma warning disable CA1814 // Prefer jagged arrays over multidimensional
 | 
			
		||||
 | 
			
		||||
namespace TechHelper.Server.Migrations
 | 
			
		||||
{
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    public partial class up_assign_data : Migration
 | 
			
		||||
    {
 | 
			
		||||
        /// <inheritdoc />
 | 
			
		||||
        protected override void Up(MigrationBuilder migrationBuilder)
 | 
			
		||||
        {
 | 
			
		||||
            migrationBuilder.DeleteData(
 | 
			
		||||
                table: "AspNetRoles",
 | 
			
		||||
                keyColumn: "Id",
 | 
			
		||||
                keyValue: new Guid("53307917-63c4-468a-ab05-a03882a69ef8"));
 | 
			
		||||
 | 
			
		||||
            migrationBuilder.DeleteData(
 | 
			
		||||
                table: "AspNetRoles",
 | 
			
		||||
                keyColumn: "Id",
 | 
			
		||||
                keyValue: new Guid("789b7819-685f-4a2b-9adf-463f397f24d1"));
 | 
			
		||||
 | 
			
		||||
            migrationBuilder.DeleteData(
 | 
			
		||||
                table: "AspNetRoles",
 | 
			
		||||
                keyColumn: "Id",
 | 
			
		||||
                keyValue: new Guid("bbea7915-e27c-4ddc-b06c-1f579fc8104e"));
 | 
			
		||||
 | 
			
		||||
            migrationBuilder.AddColumn<byte>(
 | 
			
		||||
                name: "ExamType",
 | 
			
		||||
                table: "assignments",
 | 
			
		||||
                type: "tinyint unsigned",
 | 
			
		||||
                nullable: false,
 | 
			
		||||
                defaultValue: (byte)0);
 | 
			
		||||
 | 
			
		||||
            migrationBuilder.AddColumn<string>(
 | 
			
		||||
                name: "Name",
 | 
			
		||||
                table: "assignments",
 | 
			
		||||
                type: "longtext",
 | 
			
		||||
                nullable: false)
 | 
			
		||||
                .Annotation("MySql:CharSet", "utf8mb4");
 | 
			
		||||
 | 
			
		||||
            migrationBuilder.InsertData(
 | 
			
		||||
                table: "AspNetRoles",
 | 
			
		||||
                columns: new[] { "Id", "ConcurrencyStamp", "Name", "NormalizedName" },
 | 
			
		||||
                values: new object[,]
 | 
			
		||||
                {
 | 
			
		||||
                    { new Guid("0775702a-5db7-4747-94d0-4376fad2b58b"), null, "Teacher", "TEACHER" },
 | 
			
		||||
                    { new Guid("37f41430-0cb7-44e5-988b-976200bd602d"), null, "Administrator", "ADMINISTRATOR" },
 | 
			
		||||
                    { new Guid("df89b9a0-65ef-42dd-b2cb-e59997a72e70"), null, "Student", "STUDENT" }
 | 
			
		||||
                });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <inheritdoc />
 | 
			
		||||
        protected override void Down(MigrationBuilder migrationBuilder)
 | 
			
		||||
        {
 | 
			
		||||
            migrationBuilder.DeleteData(
 | 
			
		||||
                table: "AspNetRoles",
 | 
			
		||||
                keyColumn: "Id",
 | 
			
		||||
                keyValue: new Guid("0775702a-5db7-4747-94d0-4376fad2b58b"));
 | 
			
		||||
 | 
			
		||||
            migrationBuilder.DeleteData(
 | 
			
		||||
                table: "AspNetRoles",
 | 
			
		||||
                keyColumn: "Id",
 | 
			
		||||
                keyValue: new Guid("37f41430-0cb7-44e5-988b-976200bd602d"));
 | 
			
		||||
 | 
			
		||||
            migrationBuilder.DeleteData(
 | 
			
		||||
                table: "AspNetRoles",
 | 
			
		||||
                keyColumn: "Id",
 | 
			
		||||
                keyValue: new Guid("df89b9a0-65ef-42dd-b2cb-e59997a72e70"));
 | 
			
		||||
 | 
			
		||||
            migrationBuilder.DropColumn(
 | 
			
		||||
                name: "ExamType",
 | 
			
		||||
                table: "assignments");
 | 
			
		||||
 | 
			
		||||
            migrationBuilder.DropColumn(
 | 
			
		||||
                name: "Name",
 | 
			
		||||
                table: "assignments");
 | 
			
		||||
 | 
			
		||||
            migrationBuilder.InsertData(
 | 
			
		||||
                table: "AspNetRoles",
 | 
			
		||||
                columns: new[] { "Id", "ConcurrencyStamp", "Name", "NormalizedName" },
 | 
			
		||||
                values: new object[,]
 | 
			
		||||
                {
 | 
			
		||||
                    { new Guid("53307917-63c4-468a-ab05-a03882a69ef8"), null, "Teacher", "TEACHER" },
 | 
			
		||||
                    { new Guid("789b7819-685f-4a2b-9adf-463f397f24d1"), null, "Administrator", "ADMINISTRATOR" },
 | 
			
		||||
                    { new Guid("bbea7915-e27c-4ddc-b06c-1f579fc8104e"), null, "Student", "STUDENT" }
 | 
			
		||||
                });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -50,10 +50,17 @@ namespace TechHelper.Server.Migrations
 | 
			
		||||
                        .HasColumnType("char(36)")
 | 
			
		||||
                        .HasColumnName("exam_struct_id");
 | 
			
		||||
 | 
			
		||||
                    b.Property<byte>("ExamType")
 | 
			
		||||
                        .HasColumnType("tinyint unsigned");
 | 
			
		||||
 | 
			
		||||
                    b.Property<bool>("IsDeleted")
 | 
			
		||||
                        .HasColumnType("tinyint(1)")
 | 
			
		||||
                        .HasColumnName("deleted");
 | 
			
		||||
 | 
			
		||||
                    b.Property<string>("Name")
 | 
			
		||||
                        .IsRequired()
 | 
			
		||||
                        .HasColumnType("longtext");
 | 
			
		||||
 | 
			
		||||
                    b.Property<float>("Score")
 | 
			
		||||
                        .HasColumnType("float")
 | 
			
		||||
                        .HasColumnName("score");
 | 
			
		||||
@@ -504,6 +511,9 @@ namespace TechHelper.Server.Migrations
 | 
			
		||||
                        .HasColumnType("tinyint unsigned")
 | 
			
		||||
                        .HasColumnName("attempt_number");
 | 
			
		||||
 | 
			
		||||
                    b.Property<byte>("ErrorQuesNum")
 | 
			
		||||
                        .HasColumnType("tinyint unsigned");
 | 
			
		||||
 | 
			
		||||
                    b.Property<DateTime?>("GradedAt")
 | 
			
		||||
                        .HasColumnType("datetime(6)")
 | 
			
		||||
                        .HasColumnName("graded_at");
 | 
			
		||||
@@ -540,6 +550,12 @@ namespace TechHelper.Server.Migrations
 | 
			
		||||
                        .HasColumnType("datetime(6)")
 | 
			
		||||
                        .HasColumnName("submission_time");
 | 
			
		||||
 | 
			
		||||
                    b.Property<byte>("TotalQuesNum")
 | 
			
		||||
                        .HasColumnType("tinyint unsigned");
 | 
			
		||||
 | 
			
		||||
                    b.Property<byte>("TotalScore")
 | 
			
		||||
                        .HasColumnType("tinyint unsigned");
 | 
			
		||||
 | 
			
		||||
                    b.HasKey("Id");
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("AssignmentId");
 | 
			
		||||
@@ -755,19 +771,19 @@ namespace TechHelper.Server.Migrations
 | 
			
		||||
                    b.HasData(
 | 
			
		||||
                        new
 | 
			
		||||
                        {
 | 
			
		||||
                            Id = new Guid("6d49bb08-97d6-4a38-88a7-8080925b589b"),
 | 
			
		||||
                            Id = new Guid("df89b9a0-65ef-42dd-b2cb-e59997a72e70"),
 | 
			
		||||
                            Name = "Student",
 | 
			
		||||
                            NormalizedName = "STUDENT"
 | 
			
		||||
                        },
 | 
			
		||||
                        new
 | 
			
		||||
                        {
 | 
			
		||||
                            Id = new Guid("e330c745-f422-43e3-bcdf-1439ace3c52f"),
 | 
			
		||||
                            Id = new Guid("0775702a-5db7-4747-94d0-4376fad2b58b"),
 | 
			
		||||
                            Name = "Teacher",
 | 
			
		||||
                            NormalizedName = "TEACHER"
 | 
			
		||||
                        },
 | 
			
		||||
                        new
 | 
			
		||||
                        {
 | 
			
		||||
                            Id = new Guid("379143a2-8d7f-4ef7-b7c0-14701b710f87"),
 | 
			
		||||
                            Id = new Guid("37f41430-0cb7-44e5-988b-976200bd602d"),
 | 
			
		||||
                            Name = "Administrator",
 | 
			
		||||
                            NormalizedName = "ADMINISTRATOR"
 | 
			
		||||
                        });
 | 
			
		||||
 
 | 
			
		||||
@@ -128,7 +128,7 @@ builder.Services.AddCors(options =>
 | 
			
		||||
{
 | 
			
		||||
	options.AddPolicy("AllowSpecificOrigin",
 | 
			
		||||
		builder => builder
 | 
			
		||||
			.WithOrigins("https://localhost:7047", "http://localhost:5190") 
 | 
			
		||||
			.WithOrigins("https://localhost:7047", "http://localhost:7047") 
 | 
			
		||||
			.AllowAnyHeader()
 | 
			
		||||
			.AllowAnyMethod()
 | 
			
		||||
			.AllowCredentials()); 
 | 
			
		||||
@@ -137,7 +137,7 @@ builder.Services.AddCors(options =>
 | 
			
		||||
var app = builder.Build();
 | 
			
		||||
 | 
			
		||||
// Configure the HTTP request pipeline.
 | 
			
		||||
if (app.Environment.IsDevelopment())
 | 
			
		||||
if (/*app.Environment.IsDevelopment()*/true)
 | 
			
		||||
{
 | 
			
		||||
	app.UseSwagger();
 | 
			
		||||
	app.UseSwaggerUI();
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@
 | 
			
		||||
        "ASPNETCORE_ENVIRONMENT": "Development"
 | 
			
		||||
      },
 | 
			
		||||
      "dotnetRunMessages": true,
 | 
			
		||||
      "applicationUrl": "http://localhost:5099"
 | 
			
		||||
      "applicationUrl": "http://localhost:8080"
 | 
			
		||||
    },
 | 
			
		||||
    "https": {
 | 
			
		||||
      "commandName": "Project",
 | 
			
		||||
@@ -18,7 +18,7 @@
 | 
			
		||||
        "ASPNETCORE_ENVIRONMENT": "Development"
 | 
			
		||||
      },
 | 
			
		||||
      "dotnetRunMessages": true,
 | 
			
		||||
      "applicationUrl": "https://localhost:7037;http://localhost:5062"
 | 
			
		||||
      "applicationUrl": "https://localhost:8080"
 | 
			
		||||
    },
 | 
			
		||||
    "IIS Express": {
 | 
			
		||||
      "commandName": "IISExpress",
 | 
			
		||||
 
 | 
			
		||||
@@ -143,6 +143,22 @@ namespace TechHelper.Services
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public async Task<ApiResponse> GetGradeClasses(byte Grade)
 | 
			
		||||
		{
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				var result = await _work.GetRepository<Class>().GetAllAsync(predicate:
 | 
			
		||||
					c => c.Grade == Grade);
 | 
			
		||||
 | 
			
		||||
				var classes = result.Select(x => x.Number).ToList();
 | 
			
		||||
				return ApiResponse.Success(result: classes);
 | 
			
		||||
			}
 | 
			
		||||
			catch (Exception ex)
 | 
			
		||||
			{
 | 
			
		||||
				return ApiResponse.Error($"年级班级列表失败, {ex.Message}, {ex.InnerException}");
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public async Task<ApiResponse> GetUserClass(Guid id)
 | 
			
		||||
		{
 | 
			
		||||
			var tch = await _work.GetRepository<ClassTeacher>().GetAllAsync(predicate: user => user.TeacherId == id, include: i => i
 | 
			
		||||
 
 | 
			
		||||
@@ -10,5 +10,7 @@ namespace TechHelper.Services
 | 
			
		||||
		public Task<ApiResponse> GetUserClass(Guid user); // List<Class>
 | 
			
		||||
		public Task<ApiResponse> GetUserClassRole(Guid user); // List<UserClassRoleDto>
 | 
			
		||||
		public Task<ApiResponse> GetClassStudents(ClassDto classDto); // Class
 | 
			
		||||
		public Task<ApiResponse> GetGradeClasses(byte Grade); // Class
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -45,4 +45,7 @@ Global
 | 
			
		||||
	GlobalSection(SolutionProperties) = preSolution
 | 
			
		||||
		HideSolutionNode = FALSE
 | 
			
		||||
	EndGlobalSection
 | 
			
		||||
	GlobalSection(ExtensibilityGlobals) = postSolution
 | 
			
		||||
		SolutionGuid = {22567F58-2C4A-4DB2-9674-8F537E0891CB}
 | 
			
		||||
	EndGlobalSection
 | 
			
		||||
EndGlobal
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										38
									
								
								docker-compose.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								docker-compose.yml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,38 @@
 | 
			
		||||
version: '3.8'
 | 
			
		||||
 | 
			
		||||
services:
 | 
			
		||||
  Entities-Lib:  # 公共库独立服务
 | 
			
		||||
    build:
 | 
			
		||||
      context: .
 | 
			
		||||
      dockerfile: Entities/Dockerfile
 | 
			
		||||
    image: entitieslib:latest
 | 
			
		||||
 | 
			
		||||
  Email-Lib:  # 公共库独立服务
 | 
			
		||||
    build:
 | 
			
		||||
      context: .
 | 
			
		||||
      dockerfile: EmailLib/Dockerfile
 | 
			
		||||
    image: emaillib:latest
 | 
			
		||||
 | 
			
		||||
  web-api:     # Web API 服务
 | 
			
		||||
    # build:
 | 
			
		||||
    #   context: .
 | 
			
		||||
    #   dockerfile: TechHelper.Server/Dockerfile
 | 
			
		||||
    
 | 
			
		||||
    image: techhelperserver:latest
 | 
			
		||||
    depends_on:
 | 
			
		||||
      - Entities-Lib
 | 
			
		||||
      - Email-Lib
 | 
			
		||||
    ports:
 | 
			
		||||
      - "8084:80"
 | 
			
		||||
 | 
			
		||||
  wasm-client:  # WASM 客户端
 | 
			
		||||
    build:
 | 
			
		||||
      context: .
 | 
			
		||||
      dockerfile: TechHelper.Client/Dockerfile
 | 
			
		||||
    depends_on:
 | 
			
		||||
      - web-api
 | 
			
		||||
      - Entities-Lib
 | 
			
		||||
      - Email-Lib
 | 
			
		||||
    ports:
 | 
			
		||||
      - "3000:80"
 | 
			
		||||
      
 | 
			
		||||
		Reference in New Issue
	
	Block a user