AsiignmentStruct
This commit is contained in:
@@ -67,11 +67,11 @@ namespace Entities.Contracts
|
||||
ComputerScience, // 计算机科学
|
||||
}
|
||||
|
||||
public enum QuestionGroupState : byte
|
||||
public enum AssignmentStructType : byte
|
||||
{
|
||||
Standalone,
|
||||
Group,
|
||||
Subquestion
|
||||
Question,
|
||||
Struct,
|
||||
SubQuestion
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -5,6 +5,7 @@ using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Entities.DTO;
|
||||
|
||||
namespace Entities.Contracts
|
||||
{
|
||||
@@ -53,7 +54,7 @@ namespace Entities.Contracts
|
||||
[ForeignKey(nameof(CreatorId))]
|
||||
public User Creator { get; set; }
|
||||
public ICollection<AssignmentClass> AssignmentClasses { get; set; }
|
||||
public AssignmentStruct ExamStruct { get; set; }
|
||||
public AssignmentQuestion ExamStruct { get; set; }
|
||||
public ICollection<AssignmentAttachment> AssignmentAttachments { get; set; }
|
||||
public ICollection<Submission> Submissions { get; set; }
|
||||
|
||||
|
@@ -18,23 +18,28 @@ namespace Entities.Contracts
|
||||
public Guid Id { get; set; }
|
||||
|
||||
[Column("question_id")]
|
||||
public Guid QuestionId { get; set; }
|
||||
public Guid? QuestionId { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("group_id")]
|
||||
[ForeignKey("AssignmentGroup")]
|
||||
public Guid AssignmentStructId { get; set; }
|
||||
[Column("assignment")]
|
||||
[ForeignKey("Assignment")]
|
||||
public Guid? AssignmentId { get; set; }
|
||||
|
||||
[Column("title")]
|
||||
[MaxLength(1024)]
|
||||
public string? Title { get; set; }
|
||||
|
||||
[Column("description")]
|
||||
public Guid? QuestionContextId { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("question_number")]
|
||||
public byte Index { get; set; }
|
||||
|
||||
|
||||
[Column("parent_question_group_id")]
|
||||
public Guid? ParentAssignmentQuestionId { get; set; }
|
||||
|
||||
[Column("group_state")]
|
||||
public QuestionGroupState GroupState { get; set; } = QuestionGroupState.Standalone;
|
||||
public AssignmentStructType StructType { get; set; } = AssignmentStructType.Question;
|
||||
|
||||
[Column("created_at")]
|
||||
public DateTime CreatedAt { get; set; }
|
||||
@@ -42,13 +47,17 @@ namespace Entities.Contracts
|
||||
[Column("score")]
|
||||
public float? Score { get; set; }
|
||||
|
||||
|
||||
[Column("deleted")]
|
||||
public bool IsDeleted { get; set; }
|
||||
|
||||
|
||||
public Question Question { get; set; }
|
||||
public AssignmentStruct AssignmentStruct { get; set; }
|
||||
public Question? Question { get; set; }
|
||||
public Assignment? Assignment { get; set; }
|
||||
|
||||
|
||||
[ForeignKey(nameof(QuestionContextId))]
|
||||
public QuestionContext? QuestionContext { get; set; }
|
||||
|
||||
public ICollection<SubmissionDetail> SubmissionDetails { get; set; }
|
||||
|
||||
[ForeignKey(nameof(ParentAssignmentQuestionId))]
|
||||
|
@@ -1,61 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Entities.Contracts
|
||||
{
|
||||
[Table("assignment_group")]
|
||||
public class AssignmentStruct
|
||||
{
|
||||
[Key]
|
||||
[Column("id")]
|
||||
public Guid Id { get; set; }
|
||||
|
||||
[Column("assignment")]
|
||||
[ForeignKey("Assignment")]
|
||||
public Guid? AssignmentId { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("title")]
|
||||
[MaxLength(65535)]
|
||||
public string Title { get; set; }
|
||||
|
||||
[Column("descript")]
|
||||
[MaxLength(65535)]
|
||||
public string Description { get; set; }
|
||||
|
||||
[Column("layout")]
|
||||
public Layout Layout { get; set; }
|
||||
|
||||
[Column("total_points")]
|
||||
public float? Score { get; set; }
|
||||
|
||||
[Column("index")]
|
||||
public byte Index { get; set; }
|
||||
|
||||
[Column("parent_group")]
|
||||
public Guid? ParentStructId { get; set; }
|
||||
|
||||
[Column("deleted")]
|
||||
public bool IsDeleted { get; set; } = false;
|
||||
|
||||
// Navigation Properties
|
||||
public Assignment? Assignment { get; set; }
|
||||
public AssignmentStruct? ParentStruct { get; set;}
|
||||
public ICollection<AssignmentStruct> ChildrenGroups { get; set; }
|
||||
public ICollection<AssignmentQuestion> AssignmentQuestions { get; set; }
|
||||
|
||||
|
||||
public AssignmentStruct()
|
||||
{
|
||||
Id = Guid.NewGuid();
|
||||
ChildrenGroups = new HashSet<AssignmentStruct>();
|
||||
AssignmentQuestions = new HashSet<AssignmentQuestion>();
|
||||
}
|
||||
}
|
||||
}
|
@@ -24,8 +24,7 @@ namespace Entities.Contracts
|
||||
[MaxLength(65535)]
|
||||
public string? Answer { get; set; }
|
||||
|
||||
[Column("description")]
|
||||
public Guid? DescriptionId { get; set; }
|
||||
|
||||
|
||||
[Required]
|
||||
[Column("type")]
|
||||
@@ -68,11 +67,6 @@ namespace Entities.Contracts
|
||||
[ForeignKey(nameof(CreatorId))]
|
||||
public User Creator { get; set; }
|
||||
|
||||
[ForeignKey(nameof(DescriptionId))]
|
||||
public QuestionContext Description { get; set; }
|
||||
public Question? ParentQuestion { get; set; }
|
||||
public ICollection<Question>? ChildrenQuestion { get; set; }
|
||||
|
||||
[ForeignKey(nameof(KeyPointId))]
|
||||
public KeyPoint? KeyPoint { get; set; }
|
||||
[ForeignKey(nameof(LessonId))]
|
||||
@@ -84,7 +78,6 @@ namespace Entities.Contracts
|
||||
{
|
||||
Id = Guid.NewGuid();
|
||||
AssignmentQuestions = new HashSet<AssignmentQuestion>();
|
||||
ChildrenQuestion = new HashSet<Question>();
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -13,13 +13,13 @@ namespace Entities.Contracts
|
||||
|
||||
public string Description { get; set; } = string.Empty;
|
||||
|
||||
[InverseProperty(nameof(Question.Description))]
|
||||
public ICollection<Question> Questions { get; set; } = new List<Question>();
|
||||
[InverseProperty(nameof(AssignmentQuestion.QuestionContext))]
|
||||
public ICollection<AssignmentQuestion>? Questions { get; set; } = new List<AssignmentQuestion>();
|
||||
|
||||
|
||||
public QuestionContext()
|
||||
{
|
||||
Questions = new HashSet<Question>();
|
||||
Questions = new HashSet<AssignmentQuestion>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -9,17 +9,19 @@ namespace Entities.DTO
|
||||
{
|
||||
public class AssignmentQuestionDto
|
||||
{
|
||||
public float Score { get; set; } = 0;
|
||||
public Guid Id { get; set; } = Guid.Empty;
|
||||
public string Title { get; set; } = string.Empty;
|
||||
public QuestionContextDto? Description { get; set; }
|
||||
|
||||
public byte Index { get; set; } = 0;
|
||||
public QuestionGroupState GroupState { get; set; } = QuestionGroupState.Standalone;
|
||||
|
||||
public float Score { get; set; } = 0;
|
||||
|
||||
public Layout Layout { get; set; } = Layout.horizontal;
|
||||
public AssignmentStructType StructType { get; set; } = AssignmentStructType.Question;
|
||||
|
||||
public AssignmentQuestionDto? ParentAssignmentQuestion { get; set; }
|
||||
public ICollection<AssignmentQuestionDto> ChildrenAssignmentQuestion { get; set; } = new List<AssignmentQuestionDto>();
|
||||
|
||||
|
||||
|
||||
public QuestionDto Question { get; set; }
|
||||
public QuestionDto? Question { get; set; }
|
||||
}
|
||||
}
|
||||
|
@@ -8,25 +8,6 @@ using System.Xml.Serialization;
|
||||
|
||||
namespace Entities.DTO
|
||||
{
|
||||
|
||||
public class AssignmentStructDto
|
||||
{
|
||||
public Guid Id { get; set; } = Guid.Empty;
|
||||
public string Title { get; set; } = string.Empty;
|
||||
public string Description { get; set; } = string.Empty;
|
||||
public float Score { get; set; } = 0;
|
||||
public byte Index { get; set; } = 0;
|
||||
public Layout Layout { get; set; } = Layout.horizontal;
|
||||
|
||||
|
||||
|
||||
|
||||
public ICollection<AssignmentQuestionDto> AssignmentQuestions { get; set; } = new List<AssignmentQuestionDto>();
|
||||
|
||||
public AssignmentStructDto? ParentStruct { get; set; }
|
||||
public ICollection<AssignmentStructDto> ChildrenGroups { get; set; } = new List<AssignmentStructDto>();
|
||||
}
|
||||
|
||||
public class AssignmentDto
|
||||
{
|
||||
public Guid Id { get; set; } = Guid.Empty;
|
||||
@@ -41,7 +22,7 @@ namespace Entities.DTO
|
||||
public DateTime DueDate { get; set; }
|
||||
public Guid CreatorId { get; set; }
|
||||
|
||||
public AssignmentStructDto ExamStruct { get; set; } = new AssignmentStructDto();
|
||||
public AssignmentQuestionDto ExamStruct { get; set; } = new AssignmentQuestionDto();
|
||||
}
|
||||
|
||||
public class AssignmentClassDto
|
||||
|
@@ -15,8 +15,6 @@ namespace Entities.DTO
|
||||
|
||||
public string Title { get; set; } = string.Empty;
|
||||
|
||||
public QuestionContextDto? Description { get; set; }
|
||||
|
||||
public QuestionType Type { get; set; } = QuestionType.Unknown;
|
||||
|
||||
public string? Answer { get; set; } = string.Empty;
|
||||
|
@@ -26,12 +26,12 @@ namespace TechHelper.Client.Exam
|
||||
Enum.TryParse<SubjectAreaEnum>(examPaper.SubjectArea, out SubjectArea);
|
||||
dto.SubjectArea = SubjectArea;
|
||||
|
||||
AssignmentStructDto examStruct = new AssignmentStructDto();
|
||||
AssignmentQuestionDto examStruct = new AssignmentQuestionDto();
|
||||
|
||||
foreach (var qg in examPaper.QuestionGroups)
|
||||
{
|
||||
examStruct.ChildrenGroups.Add(ParseMajorQuestionGroup(qg));
|
||||
examStruct.ChildrenGroups.Last().Index = (byte)(examStruct.ChildrenGroups.Count());
|
||||
examStruct.ChildrenAssignmentQuestion.Add(ParseMajorQuestionGroup(qg));
|
||||
examStruct.ChildrenAssignmentQuestion.Last().Index = (byte)(examStruct.ChildrenAssignmentQuestion.Count());
|
||||
}
|
||||
|
||||
dto.ExamStruct = examStruct;
|
||||
@@ -39,28 +39,20 @@ namespace TechHelper.Client.Exam
|
||||
return dto;
|
||||
}
|
||||
|
||||
private static AssignmentStructDto ParseMajorQuestionGroup(MajorQuestionGroup sqg)
|
||||
private static AssignmentQuestionDto ParseMajorQuestionGroup(MajorQuestionGroup sqg)
|
||||
{
|
||||
var examStruct = new AssignmentStructDto();
|
||||
|
||||
var examStruct = new AssignmentQuestionDto();
|
||||
examStruct.Title = sqg.Title;
|
||||
examStruct.Score = sqg.Score;
|
||||
if (sqg.SubQuestionGroups != null)
|
||||
{
|
||||
|
||||
examStruct.Title = sqg.Title;
|
||||
examStruct.Score = sqg.Score;
|
||||
examStruct.ChildrenGroups = new List<AssignmentStructDto>();
|
||||
|
||||
examStruct.ChildrenAssignmentQuestion = new List<AssignmentQuestionDto>();
|
||||
sqg.SubQuestionGroups?.ForEach(ssqg =>
|
||||
{
|
||||
if (string.IsNullOrEmpty(ssqg.Descript))
|
||||
{
|
||||
examStruct.ChildrenGroups.Add(ParseMajorQuestionGroup(ssqg));
|
||||
examStruct.ChildrenGroups.Last().Index = (byte)(examStruct.ChildrenGroups.Count());
|
||||
}
|
||||
else
|
||||
{
|
||||
examStruct.AssignmentQuestions.Add(ParseGroupToAssignmentQuestion(ssqg, false));
|
||||
examStruct.AssignmentQuestions.Last().Index = (byte)(examStruct.AssignmentQuestions.Count());
|
||||
}
|
||||
examStruct.ChildrenAssignmentQuestion.Add(ParseMajorQuestionGroup(ssqg));
|
||||
examStruct.ChildrenAssignmentQuestion.Last().Index = (byte)(examStruct.ChildrenAssignmentQuestion.Count());
|
||||
|
||||
});
|
||||
|
||||
@@ -72,12 +64,8 @@ namespace TechHelper.Client.Exam
|
||||
|
||||
sqg.SubQuestions?.ForEach(sq =>
|
||||
{
|
||||
if(sq.SubQuestions.Any())
|
||||
{
|
||||
|
||||
}
|
||||
examStruct.AssignmentQuestions.Add(ParseAssignmentQuestion(sq));
|
||||
examStruct.AssignmentQuestions.Last().Index = (byte)(examStruct.AssignmentQuestions.Count());
|
||||
examStruct.ChildrenAssignmentQuestion.Add(ParseAssignmentQuestion(sq));
|
||||
examStruct.ChildrenAssignmentQuestion.Last().Index = (byte)(examStruct.ChildrenAssignmentQuestion.Count());
|
||||
});
|
||||
}
|
||||
|
||||
@@ -91,47 +79,6 @@ namespace TechHelper.Client.Exam
|
||||
.Where(line => !string.IsNullOrWhiteSpace(line)).ToList();
|
||||
}
|
||||
|
||||
private static QuestionDto ParseGroupToQuestion(MajorQuestionGroup qg, bool subQ = true)
|
||||
{
|
||||
var dq = new QuestionDto();
|
||||
dq.Title = qg.Title + Environment.NewLine + qg.Descript;
|
||||
|
||||
if (subQ) dq.GroupState = QuestionGroupState.Subquestion;
|
||||
else dq.GroupState = QuestionGroupState.Group;
|
||||
|
||||
qg.SubQuestions?.ForEach(ssq =>
|
||||
{
|
||||
dq.ChildrenQuestion.Add(ParseQuestion(ssq));
|
||||
});
|
||||
|
||||
qg.SubQuestionGroups?.ForEach(sqg =>
|
||||
{
|
||||
dq.ChildrenQuestion.Add(ParseGroupToQuestion(sqg));
|
||||
});
|
||||
|
||||
return dq;
|
||||
}
|
||||
|
||||
private static AssignmentQuestionDto ParseGroupToAssignmentQuestion(MajorQuestionGroup qg, bool subQ = true)
|
||||
{
|
||||
var aq = new AssignmentQuestionDto();
|
||||
aq.Score = qg.Score;
|
||||
|
||||
qg.SubQuestions?.ForEach(ssq =>
|
||||
{
|
||||
aq.Question.ChildrenQuestion.Add(ParseQuestion(ssq));
|
||||
aq.Question.ChildrenQuestion.Last().Index = (byte)aq.Question.ChildrenQuestion.Count;
|
||||
});
|
||||
|
||||
qg.SubQuestionGroups?.ForEach(sqg =>
|
||||
{
|
||||
aq.Question.ChildrenQuestion.Add(ParseGroupToQuestion(sqg));
|
||||
aq.Question.ChildrenQuestion.Last().Index = (byte)aq.Question.ChildrenQuestion.Count;
|
||||
});
|
||||
|
||||
return aq;
|
||||
}
|
||||
|
||||
|
||||
private static AssignmentQuestionDto ParseAssignmentQuestion(PaperQuestion sq)
|
||||
{
|
||||
@@ -143,8 +90,8 @@ namespace TechHelper.Client.Exam
|
||||
sq.SubQuestions?.ForEach(ssq =>
|
||||
{
|
||||
|
||||
aq.Question.ChildrenQuestion.Add(ParseQuestion(ssq));
|
||||
aq.Question.ChildrenQuestion.Last().Index = (byte)aq.Question.ChildrenQuestion.Count;
|
||||
aq.ChildrenAssignmentQuestion.Add(ParseAssignmentQuestion(ssq));
|
||||
aq.ChildrenAssignmentQuestion.Last().Index = (byte)aq.ChildrenAssignmentQuestion.Count;
|
||||
|
||||
});
|
||||
|
||||
@@ -156,14 +103,6 @@ namespace TechHelper.Client.Exam
|
||||
var dq = new QuestionDto();
|
||||
dq.Title = sq.Stem;
|
||||
dq.Options = string.Join(Environment.NewLine, sq.Options.Select(opt => $"{opt.Label} {opt.Text}"));
|
||||
dq.Score = sq.Score;
|
||||
|
||||
|
||||
sq.SubQuestions?.ForEach(ssq =>
|
||||
{
|
||||
dq.ChildrenQuestion.Add(ParseQuestion(ssq));
|
||||
dq.ChildrenQuestion.Last().Index = (byte)dq.ChildrenQuestion.Count;
|
||||
});
|
||||
|
||||
return dq;
|
||||
}
|
||||
|
@@ -6,14 +6,14 @@ using System.Text.RegularExpressions;
|
||||
|
||||
namespace TechHelper.Client.Exam
|
||||
{
|
||||
// --- 新增错误处理相关类 ---
|
||||
|
||||
public class ParseError
|
||||
{
|
||||
public ParseErrorType Type { get; }
|
||||
public string Message { get; }
|
||||
public int? Index { get; } // 错误发生的文本索引或匹配项索引
|
||||
public string MatchedText { get; } // 如果与某个匹配项相关,记录其文本
|
||||
public Exception InnerException { get; } // 捕获到的原始异常
|
||||
public int? Index { get; }
|
||||
public string MatchedText { get; }
|
||||
public Exception InnerException { get; }
|
||||
|
||||
public ParseError(ParseErrorType type, string message, int? index = null, string matchedText = null, Exception innerException = null)
|
||||
{
|
||||
|
17
TechHelper.Client/Pages/Exam/AssignmentQuestionEdit.razor
Normal file
17
TechHelper.Client/Pages/Exam/AssignmentQuestionEdit.razor
Normal file
@@ -0,0 +1,17 @@
|
||||
@using Entities.DTO
|
||||
@using TechHelper.Client.Exam
|
||||
|
||||
|
||||
<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>
|
||||
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public AssignmentQuestionDto AssignmentQuestion { get; set; } = new AssignmentQuestionDto();
|
||||
}
|
@@ -9,9 +9,18 @@
|
||||
@using System.Globalization;
|
||||
@using TechHelper.Client.Pages.Editor
|
||||
|
||||
|
||||
<MudPaper Elevation="5" Class="d-flex overflow-hidden flex-grow-1" 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">
|
||||
|
||||
@if (_edit)
|
||||
{
|
||||
<AssignmentQuestionEdit AssignmentQuestion="selectedAssignmentQuestion" />
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
<MudDrawerHeader>
|
||||
<MudText Typo="Typo.h6"> 配置 </MudText>
|
||||
</MudDrawerHeader>
|
||||
@@ -20,9 +29,12 @@
|
||||
<ParseRoleConfig />
|
||||
<MudButton Color="Color.Success"> ParseExam </MudButton>
|
||||
</MudStack>
|
||||
}
|
||||
|
||||
|
||||
</MudDrawer>
|
||||
<MudStack Row="true" Class="flex-grow-1" Style="height:100%">
|
||||
<ExamView Class="overflow-auto" ParsedExam="ExamContent"></ExamView>
|
||||
<ExamView Class="overflow-auto" ClickedStruct="HandleClickedStruct" ParsedExam="ExamContent"></ExamView>
|
||||
|
||||
<MudPaper Class="ma-2">
|
||||
<MudPaper Elevation="0" Style="height:calc(100% - 80px)">
|
||||
@@ -75,11 +87,15 @@
|
||||
[CascadingParameter]
|
||||
private Task<AuthenticationState> authenticationStateTask { get; set; }
|
||||
|
||||
private AssignmentQuestionDto selectedAssignmentQuestion = new AssignmentQuestionDto();
|
||||
|
||||
private bool _open = false;
|
||||
private bool _edit = false;
|
||||
|
||||
private void ToggleDrawer()
|
||||
{
|
||||
_open = !_open;
|
||||
_edit = false;
|
||||
}
|
||||
private BlazoredTextEditor _textEditor = new BlazoredTextEditor();
|
||||
private ExamPaper _parsedExam = new ExamPaper();
|
||||
@@ -87,6 +103,14 @@
|
||||
|
||||
private ExamParserConfig _examParserConfig { get; set; } = new ExamParserConfig();
|
||||
|
||||
private void HandleClickedStruct(AssignmentQuestionDto dto)
|
||||
{
|
||||
_open = true;
|
||||
_edit = true;
|
||||
selectedAssignmentQuestion = dto;
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
private async Task ParseExam()
|
||||
{
|
||||
|
||||
|
@@ -1,36 +0,0 @@
|
||||
@using Entities.DTO
|
||||
@using TechHelper.Client.Exam
|
||||
|
||||
|
||||
<MudPaper Elevation=@Elevation Class=@Class>
|
||||
|
||||
<MudStack Row="true">
|
||||
<MudText Typo="Typo.h6">@ExamStruct.Title</MudText>
|
||||
@if (ExamStruct.Score > 0)
|
||||
{
|
||||
<MudText Typo="Typo.body2"><b>总分:</b> @ExamStruct.Score 分</MudText>
|
||||
}
|
||||
</MudStack>
|
||||
|
||||
@foreach (var childStruct in ExamStruct.ChildrenGroups)
|
||||
{
|
||||
<ExamGroupView ExamStruct="childStruct"/>
|
||||
}
|
||||
|
||||
@foreach (var question in ExamStruct.AssignmentQuestions)
|
||||
{
|
||||
<QuestionCard Question="question.Question" Elevation=@Elevation Class="my-2 pa-1" />
|
||||
}
|
||||
|
||||
</MudPaper>
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public AssignmentStructDto ExamStruct { get; set; } = new AssignmentStructDto();
|
||||
|
||||
[Parameter]
|
||||
public string Class { get; set; } = "my-2 pa-1";
|
||||
|
||||
[Parameter]
|
||||
public int Elevation { get; set; } = 0;
|
||||
}
|
51
TechHelper.Client/Pages/Exam/ExamStructView.razor
Normal file
51
TechHelper.Client/Pages/Exam/ExamStructView.razor
Normal file
@@ -0,0 +1,51 @@
|
||||
@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);
|
||||
}
|
||||
}
|
@@ -8,7 +8,7 @@
|
||||
<MudText Class="d-flex justify-content-center" Typo="Typo.h6"> @ParsedExam.Title </MudText>
|
||||
<MudText Typo="Typo.body1"> @ParsedExam.Description </MudText>
|
||||
|
||||
<ExamGroupView ExamStruct="@ParsedExam.ExamStruct" Elevation="1" Class="ma-0 pa-2" />
|
||||
<ExamStructView ExamStruct="@ParsedExam.ExamStruct" Elevation="1" ClickedStruct="HandleClickedStruct" Class="ma-0 pa-2" />
|
||||
</MudPaper>
|
||||
|
||||
}
|
||||
@@ -25,6 +25,10 @@ else
|
||||
|
||||
[Parameter]
|
||||
public AssignmentDto ParsedExam { get; set; } = new AssignmentDto();
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<AssignmentQuestionDto> ClickedStruct { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public string Height { get; set; } = "100%";
|
||||
[Parameter]
|
||||
@@ -33,4 +37,10 @@ else
|
||||
public string Class { get; set; } = "";
|
||||
[Parameter]
|
||||
public string Style { get; set; } = "";
|
||||
|
||||
|
||||
private void HandleClickedStruct(AssignmentQuestionDto dto)
|
||||
{
|
||||
ClickedStruct.InvokeAsync(dto);
|
||||
}
|
||||
}
|
@@ -4,14 +4,14 @@
|
||||
<MudPaper Class=@Class Elevation=@Elevation Outlined="false">
|
||||
|
||||
<MudText Typo="Typo.subtitle1">
|
||||
<b>@Question.Index</b> @((MarkupString)Question.Title.Replace("\n", "<br />"))
|
||||
@if (Question.Score > 0)
|
||||
<b>@Index</b> @((MarkupString)Question.Title.Replace("\n", "<br />"))
|
||||
@if (Score > 0)
|
||||
{
|
||||
<MudText Typo="Typo.body2" Class="d-inline ml-2">(@Question.Score 分)</MudText>
|
||||
<MudText Typo="Typo.body2" Class="d-inline ml-2">(@Score 分)</MudText>
|
||||
}
|
||||
</MudText>
|
||||
|
||||
@if (Question.Options != null)
|
||||
@if (!string.IsNullOrEmpty(Question.Options))
|
||||
{
|
||||
<div class="mt-2">
|
||||
@foreach (var option in Question.Options.ParseOptionsFromText())
|
||||
@@ -22,12 +22,6 @@
|
||||
</div>
|
||||
}
|
||||
|
||||
|
||||
@foreach(var item in Question.ChildrenQuestion)
|
||||
{
|
||||
<QuestionCard Question="item"/>
|
||||
|
||||
}
|
||||
</MudPaper>
|
||||
|
||||
@code {
|
||||
@@ -35,7 +29,13 @@
|
||||
public QuestionDto Question { get; set; } = new QuestionDto();
|
||||
|
||||
[Parameter]
|
||||
public string Class { get; set; }
|
||||
public byte Index { get; set; } = 0;
|
||||
|
||||
[Parameter]
|
||||
public byte Score { get; set; } = 0;
|
||||
|
||||
[Parameter]
|
||||
public string Class { get; set; } = string.Empty;
|
||||
|
||||
[Parameter]
|
||||
public int Elevation { get; set; }
|
||||
|
17
TechHelper.Client/Pages/Exam/QuestionEdit.razor
Normal file
17
TechHelper.Client/Pages/Exam/QuestionEdit.razor
Normal file
@@ -0,0 +1,17 @@
|
||||
@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();
|
||||
}
|
@@ -13,7 +13,6 @@ namespace TechHelper.Context
|
||||
|
||||
public DbSet<AssignmentClass> AssignmentClasses { get; set; }
|
||||
public DbSet<Assignment> Assignments { get; set; }
|
||||
public DbSet<AssignmentQuestion> AssignmentGroups { get; set; }
|
||||
public DbSet<AssignmentQuestion> AssignmentQuestions { get; set; }
|
||||
public DbSet<Class> Classes { get; set; }
|
||||
public DbSet<ClassTeacher> ClassStudents { get; set; }
|
||||
@@ -21,6 +20,7 @@ namespace TechHelper.Context
|
||||
public DbSet<Question> Questions { get; set; }
|
||||
public DbSet<Submission> Submissions { get; set; }
|
||||
public DbSet<SubmissionDetail> SubmissionDetails { get; set; }
|
||||
public DbSet<QuestionContext> QuestionContexts { get; set; }
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder builder)
|
||||
{
|
||||
@@ -28,7 +28,6 @@ namespace TechHelper.Context
|
||||
builder.ApplyConfiguration(new RoleConfiguration());
|
||||
builder.ApplyConfiguration(new AssignmentConfiguration());
|
||||
builder.ApplyConfiguration(new AssignmentClassConfiguration());
|
||||
builder.ApplyConfiguration(new AssignmentGroupConfiguration());
|
||||
builder.ApplyConfiguration(new AssignmentQuestionConfiguration());
|
||||
builder.ApplyConfiguration(new ClassConfiguration());
|
||||
builder.ApplyConfiguration(new ClassStudentConfiguration());
|
||||
|
@@ -50,10 +50,11 @@ namespace TechHelper.Context
|
||||
// =============================================================
|
||||
// ENTITY -> DTO Mappings (用于读取/查询)
|
||||
// =============================================================
|
||||
CreateMap<Assignment, AssignmentDto>()
|
||||
.ForMember(dest => dest.ExamStruct, opt => opt.MapFrom(src => src.ExamStruct));
|
||||
CreateMap<Assignment, AssignmentDto>();
|
||||
|
||||
CreateMap<QuestionContext, QuestionContextDto>().ReverseMap();
|
||||
|
||||
|
||||
CreateMap<AssignmentStruct, AssignmentStructDto>(); // 直接映射,因为成员现在对等了
|
||||
|
||||
// 新增!从实体到新的 DTO 的映射
|
||||
CreateMap<AssignmentQuestion, AssignmentQuestionDto>();
|
||||
@@ -64,7 +65,6 @@ namespace TechHelper.Context
|
||||
// DTO -> ENTITY Mappings (用于创建/更新) - 现在变得极其简单!
|
||||
// =================================================================
|
||||
CreateMap<AssignmentDto, Assignment>();
|
||||
CreateMap<AssignmentStructDto, AssignmentStruct>();
|
||||
|
||||
// 新增!从新的 DTO 到实体的映射
|
||||
CreateMap<AssignmentQuestionDto, AssignmentQuestion>();
|
||||
|
@@ -1,83 +0,0 @@
|
||||
using Entities.Contracts;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace TechHelper.Context.Configuration
|
||||
{
|
||||
public class AssignmentGroupConfiguration : IEntityTypeConfiguration<AssignmentStruct>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<AssignmentStruct> builder)
|
||||
{
|
||||
// 1. 设置表名
|
||||
// 将此实体映射到数据库中名为 "assignment_detail" 的表。
|
||||
builder.ToTable("assignment_group");
|
||||
|
||||
// 2. 配置主键
|
||||
// Id 属性作为主键。
|
||||
builder.HasKey(ag => ag.Id);
|
||||
|
||||
// 3. 配置列名、必需性、长度和默认值
|
||||
|
||||
// 配置 Id 属性对应的数据库列名为 "id"。
|
||||
builder.Property(ag => ag.Id)
|
||||
.HasColumnName("id");
|
||||
// EF Core 默认 Guid 类型主键由应用程序生成,因此无需 ValueGeneratedOnAdd()。
|
||||
|
||||
// 配置 AssignmentId 属性对应的数据库列名为 "assignment",并设置为必需字段。
|
||||
builder.Property(ag => ag.AssignmentId)
|
||||
.HasColumnName("assignment");
|
||||
|
||||
// 配置 Title 属性对应的数据库列名为 "title",设置为必需字段,并设置最大长度。
|
||||
builder.Property(ag => ag.Title)
|
||||
.HasColumnName("title")
|
||||
.IsRequired()
|
||||
.HasMaxLength(65535); // 对应 MaxLength(65535)
|
||||
|
||||
// 配置 Descript 属性对应的数据库列名为 "descript",并设置最大长度。
|
||||
builder.Property(ag => ag.Description)
|
||||
.HasColumnName("descript")
|
||||
.HasMaxLength(65535); // 对应 MaxLength(65535)
|
||||
|
||||
// 配置 TotalPoints 属性对应的数据库列名为 "total_points"。
|
||||
// TotalPoints 是 decimal? 类型,默认就是可选的,无需 IsRequired(false)。
|
||||
builder.Property(ag => ag.Score)
|
||||
.HasColumnName("total_points");
|
||||
|
||||
// 配置 Number 属性对应的数据库列名为 "number"。
|
||||
builder.Property(ag => ag.Index)
|
||||
.HasColumnName("number")
|
||||
.IsRequired(); // byte 默认非空,显式 IsRequired 增加可读性。
|
||||
|
||||
// 配置 ParentGroup 属性对应的数据库列名为 "sub_group"。
|
||||
// ParentGroup 是 Guid? 类型,默认就是可选的,无需 IsRequired(false)。
|
||||
builder.Property(ag => ag.ParentStructId)
|
||||
.HasColumnName("parent_group")
|
||||
.IsRequired(false);
|
||||
|
||||
// 配置 IsDeleted 属性对应的数据库列名为 "deleted",并设置默认值为 false。
|
||||
builder.Property(ag => ag.IsDeleted)
|
||||
.HasColumnName("deleted")
|
||||
.HasDefaultValue(false); // 适用于软删除策略
|
||||
|
||||
// 4. 配置导航属性和外键关系
|
||||
|
||||
// 配置 AssignmentGroup 到 Assignment 的多对一关系。
|
||||
// 一个 AssignmentGroup 记录属于一个 Assignment。
|
||||
builder.HasOne(ag => ag.Assignment) // 当前 AssignmentGroup 有一个 Assignment
|
||||
.WithOne(a => a.ExamStruct) // 该 Assignment 可以有多个 AssignmentGroup 记录
|
||||
.HasForeignKey<AssignmentStruct>(ag => ag.AssignmentId); // 通过 AssignmentId 建立外键
|
||||
|
||||
|
||||
// 配置 AssignmentGroup 到 AssignmentGroup 的自引用关系(父子关系)。
|
||||
// 一个 AssignmentGroup 可以有一个父 AssignmentGroup (SubAssignmentGroup)。
|
||||
// 假设父 AssignmentGroup 实体中有一个名为 ChildAssignmentGroups 的集合属性来表示它所包含的所有子组。
|
||||
builder.HasOne(ag => ag.ParentStruct) // 当前 AssignmentGroup 有一个父 AssignmentGroup
|
||||
.WithMany(parentAg => parentAg.ChildrenGroups) // 该父 AssignmentGroup 可以有多个子 AssignmentGroup
|
||||
.HasForeignKey(ag => ag.ParentStructId) // 通过 SubGroup 建立外键
|
||||
.IsRequired(false) // SubGroup 是可空的 (Guid?),所以这个关系是可选的。
|
||||
.OnDelete(DeleteBehavior.SetNull); // 当父 AssignmentGroup 被删除时,其子 AssignmentGroup 的 SubGroup 外键将被设置为 NULL。
|
||||
// 如果你希望父组被删除时子组不能脱离父组(即不允许父组被删除),
|
||||
// 可以使用 DeleteBehavior.Restrict 或 DeleteBehavior.NoAction。
|
||||
}
|
||||
}
|
||||
}
|
@@ -38,12 +38,6 @@ namespace TechHelper.Context.Configuration
|
||||
builder.Property(aq => aq.Score)
|
||||
.HasColumnName("score");
|
||||
|
||||
// 配置 AssignmentGroupId 列
|
||||
// 该列在数据库中名为 "detail_id"
|
||||
builder.Property(aq => aq.AssignmentStructId)
|
||||
.HasColumnName("group_id")
|
||||
.IsRequired();
|
||||
|
||||
builder.Property(aq => aq.IsDeleted)
|
||||
.HasColumnName("deleted")
|
||||
.HasDefaultValue(false); // 适用于软删除策略
|
||||
@@ -60,17 +54,11 @@ namespace TechHelper.Context.Configuration
|
||||
.HasForeignKey(aq => aq.QuestionId) // 外键是 AssignmentQuestion.QuestionId
|
||||
.OnDelete(DeleteBehavior.Cascade); // 当 Question 被删除时,相关的 AssignmentQuestion 也级联删除。
|
||||
|
||||
// ---
|
||||
// 配置 AssignmentQuestion 到 AssignmentGroup 的关系 (多对一)
|
||||
// 一个 AssignmentQuestion 属于一个 AssignmentGroup。
|
||||
//
|
||||
// 你的 `AssignmentQuestion` 类现在有了 `public AssignmentGroup AssignmentGroup { get; set; }`
|
||||
// 这是一个非常好的改进,它与 `AssignmentGroupId` 外键完美匹配。
|
||||
// 假设 `AssignmentGroup` 实体中有一个名为 `AssignmentQuestions` 的 `ICollection<AssignmentQuestion>` 集合属性。
|
||||
builder.HasOne(aq => aq.AssignmentStruct) // 当前 AssignmentQuestion 有一个 AssignmentGroup
|
||||
.WithMany(ag => ag.AssignmentQuestions) // 那个 AssignmentGroup 可以有多个 AssignmentQuestion
|
||||
.HasForeignKey(aq => aq.AssignmentStructId) // 外键是 AssignmentQuestion.AssignmentGroupId (列名 detail_id)
|
||||
.OnDelete(DeleteBehavior.Cascade); // 当 AssignmentGroup 被删除时,相关的 AssignmentQuestion 也级联删除。
|
||||
|
||||
builder.HasOne(aq => aq.QuestionContext)
|
||||
.WithMany(qc => qc.Questions)
|
||||
.HasForeignKey(aq => aq.QuestionContextId)
|
||||
.OnDelete(DeleteBehavior.SetNull);
|
||||
|
||||
// ---
|
||||
// 配置 AssignmentQuestion 到 SubmissionDetail 的关系 (一对多)
|
||||
|
@@ -111,11 +111,6 @@ namespace TechHelper.Context.Configuration
|
||||
.HasForeignKey(q => q.LessonId)
|
||||
.OnDelete(DeleteBehavior.SetNull);
|
||||
|
||||
builder.HasOne(q => q.ParentQuestion)
|
||||
.WithMany(pq => pq.ChildrenQuestion)
|
||||
.IsRequired(false)
|
||||
.HasForeignKey(q => q.ParentQuestionId)
|
||||
.OnDelete(DeleteBehavior.SetNull);
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -12,7 +12,7 @@ using TechHelper.Context;
|
||||
namespace TechHelper.Server.Migrations
|
||||
{
|
||||
[DbContext(typeof(ApplicationContext))]
|
||||
[Migration("20250619070929_init")]
|
||||
[Migration("20250620104952_init")]
|
||||
partial class init
|
||||
{
|
||||
/// <inheritdoc />
|
||||
@@ -161,9 +161,9 @@ namespace TechHelper.Server.Migrations
|
||||
.HasColumnType("char(36)")
|
||||
.HasColumnName("id");
|
||||
|
||||
b.Property<Guid>("AssignmentGroupId")
|
||||
b.Property<Guid?>("AssignmentId")
|
||||
.HasColumnType("char(36)")
|
||||
.HasColumnName("group_id");
|
||||
.HasColumnName("assignment");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime(6)")
|
||||
@@ -179,7 +179,15 @@ namespace TechHelper.Server.Migrations
|
||||
.HasDefaultValue(false)
|
||||
.HasColumnName("deleted");
|
||||
|
||||
b.Property<Guid>("QuestionId")
|
||||
b.Property<Guid?>("ParentAssignmentQuestionId")
|
||||
.HasColumnType("char(36)")
|
||||
.HasColumnName("parent_question_group_id");
|
||||
|
||||
b.Property<Guid?>("QuestionContextId")
|
||||
.HasColumnType("char(36)")
|
||||
.HasColumnName("description");
|
||||
|
||||
b.Property<Guid?>("QuestionId")
|
||||
.HasColumnType("char(36)")
|
||||
.HasColumnName("question_id");
|
||||
|
||||
@@ -187,58 +195,13 @@ namespace TechHelper.Server.Migrations
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("score");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("AssignmentGroupId");
|
||||
|
||||
b.HasIndex("QuestionId");
|
||||
|
||||
b.ToTable("assignment_questions", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Entities.Contracts.AssignmentStruct", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("char(36)")
|
||||
.HasColumnName("id");
|
||||
|
||||
b.Property<Guid?>("AssignmentId")
|
||||
.HasColumnType("char(36)")
|
||||
.HasColumnName("assignment");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasMaxLength(65535)
|
||||
.HasColumnType("longtext")
|
||||
.HasColumnName("descript");
|
||||
|
||||
b.Property<byte>("Index")
|
||||
b.Property<byte>("StructType")
|
||||
.HasColumnType("tinyint unsigned")
|
||||
.HasColumnName("number");
|
||||
|
||||
b.Property<bool>("IsDeleted")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("tinyint(1)")
|
||||
.HasDefaultValue(false)
|
||||
.HasColumnName("deleted");
|
||||
|
||||
b.Property<byte>("Layout")
|
||||
.HasColumnType("tinyint unsigned")
|
||||
.HasColumnName("layout");
|
||||
|
||||
b.Property<Guid?>("ParentGroupId")
|
||||
.HasColumnType("char(36)")
|
||||
.HasColumnName("parent_group");
|
||||
|
||||
b.Property<float?>("Score")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("total_points");
|
||||
.HasColumnName("group_state");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.IsRequired()
|
||||
.HasMaxLength(65535)
|
||||
.HasColumnType("longtext")
|
||||
.HasMaxLength(1024)
|
||||
.HasColumnType("varchar(1024)")
|
||||
.HasColumnName("title");
|
||||
|
||||
b.HasKey("Id");
|
||||
@@ -246,9 +209,13 @@ namespace TechHelper.Server.Migrations
|
||||
b.HasIndex("AssignmentId")
|
||||
.IsUnique();
|
||||
|
||||
b.HasIndex("ParentGroupId");
|
||||
b.HasIndex("ParentAssignmentQuestionId");
|
||||
|
||||
b.ToTable("assignment_group", (string)null);
|
||||
b.HasIndex("QuestionContextId");
|
||||
|
||||
b.HasIndex("QuestionId");
|
||||
|
||||
b.ToTable("assignment_questions", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Entities.Contracts.Class", b =>
|
||||
@@ -408,6 +375,7 @@ namespace TechHelper.Server.Migrations
|
||||
|
||||
b.Property<string>("Question")
|
||||
.IsRequired()
|
||||
.HasMaxLength(65535)
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.HasKey("Id");
|
||||
@@ -445,10 +413,6 @@ namespace TechHelper.Server.Migrations
|
||||
.HasColumnType("tinyint unsigned")
|
||||
.HasColumnName("difficulty_level");
|
||||
|
||||
b.Property<byte>("GroupState")
|
||||
.HasColumnType("tinyint unsigned")
|
||||
.HasColumnName("group_state");
|
||||
|
||||
b.Property<bool>("IsDeleted")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("tinyint(1)")
|
||||
@@ -467,10 +431,6 @@ namespace TechHelper.Server.Migrations
|
||||
.HasColumnType("longtext")
|
||||
.HasColumnName("options");
|
||||
|
||||
b.Property<Guid?>("ParentQuestionId")
|
||||
.HasColumnType("char(36)")
|
||||
.HasColumnName("parent_question_group_id");
|
||||
|
||||
b.Property<byte>("SubjectArea")
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("tinyint unsigned")
|
||||
@@ -501,14 +461,27 @@ namespace TechHelper.Server.Migrations
|
||||
|
||||
b.HasIndex("LessonId");
|
||||
|
||||
b.HasIndex("ParentQuestionId");
|
||||
|
||||
b.HasIndex("Title")
|
||||
.HasAnnotation("MySql:IndexPrefixLength", new[] { 20 });
|
||||
|
||||
b.ToTable("questions", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Entities.Contracts.QuestionContext", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("QuestionContexts");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Entities.Contracts.Submission", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
@@ -774,19 +747,19 @@ namespace TechHelper.Server.Migrations
|
||||
b.HasData(
|
||||
new
|
||||
{
|
||||
Id = new Guid("895d8f32-714e-4a14-bd97-8fa262b83172"),
|
||||
Id = new Guid("577dbfe8-7b77-4ead-9386-678f02dea5f4"),
|
||||
Name = "Student",
|
||||
NormalizedName = "STUDENT"
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = new Guid("d182c396-c656-42da-965a-d93c17a1f74f"),
|
||||
Id = new Guid("04b04eed-32b9-4eb0-b5f5-a97bb4626718"),
|
||||
Name = "Teacher",
|
||||
NormalizedName = "TEACHER"
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = new Guid("4e65fab9-3315-4474-b92c-bdab5a617e65"),
|
||||
Id = new Guid("82354e4d-902d-4dd6-9790-6ef50ba9bc11"),
|
||||
Name = "Administrator",
|
||||
NormalizedName = "ADMINISTRATOR"
|
||||
});
|
||||
@@ -942,37 +915,31 @@ namespace TechHelper.Server.Migrations
|
||||
|
||||
modelBuilder.Entity("Entities.Contracts.AssignmentQuestion", b =>
|
||||
{
|
||||
b.HasOne("Entities.Contracts.AssignmentStruct", "AssignmentGroup")
|
||||
.WithMany("AssignmentQuestions")
|
||||
.HasForeignKey("AssignmentGroupId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
b.HasOne("Entities.Contracts.Assignment", "Assignment")
|
||||
.WithOne("ExamStruct")
|
||||
.HasForeignKey("Entities.Contracts.AssignmentQuestion", "AssignmentId");
|
||||
|
||||
b.HasOne("Entities.Contracts.AssignmentQuestion", "ParentAssignmentQuestion")
|
||||
.WithMany("ChildrenAssignmentQuestion")
|
||||
.HasForeignKey("ParentAssignmentQuestionId");
|
||||
|
||||
b.HasOne("Entities.Contracts.QuestionContext", "QuestionContext")
|
||||
.WithMany("Questions")
|
||||
.HasForeignKey("QuestionContextId")
|
||||
.OnDelete(DeleteBehavior.SetNull);
|
||||
|
||||
b.HasOne("Entities.Contracts.Question", "Question")
|
||||
.WithMany("AssignmentQuestions")
|
||||
.HasForeignKey("QuestionId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("AssignmentGroup");
|
||||
|
||||
b.Navigation("Question");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Entities.Contracts.AssignmentStruct", b =>
|
||||
{
|
||||
b.HasOne("Entities.Contracts.Assignment", "Assignment")
|
||||
.WithOne("ExamStruct")
|
||||
.HasForeignKey("Entities.Contracts.AssignmentStruct", "AssignmentId");
|
||||
|
||||
b.HasOne("Entities.Contracts.AssignmentStruct", "ParentGroup")
|
||||
.WithMany("ChildrenGroups")
|
||||
.HasForeignKey("ParentGroupId")
|
||||
.OnDelete(DeleteBehavior.SetNull);
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.Navigation("Assignment");
|
||||
|
||||
b.Navigation("ParentGroup");
|
||||
b.Navigation("ParentAssignmentQuestion");
|
||||
|
||||
b.Navigation("Question");
|
||||
|
||||
b.Navigation("QuestionContext");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Entities.Contracts.Class", b =>
|
||||
@@ -1075,18 +1042,11 @@ namespace TechHelper.Server.Migrations
|
||||
.HasForeignKey("LessonId")
|
||||
.OnDelete(DeleteBehavior.SetNull);
|
||||
|
||||
b.HasOne("Entities.Contracts.Question", "ParentQuestion")
|
||||
.WithMany("ChildrenQuestion")
|
||||
.HasForeignKey("ParentQuestionId")
|
||||
.OnDelete(DeleteBehavior.SetNull);
|
||||
|
||||
b.Navigation("Creator");
|
||||
|
||||
b.Navigation("KeyPoint");
|
||||
|
||||
b.Navigation("Lesson");
|
||||
|
||||
b.Navigation("ParentQuestion");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Entities.Contracts.Submission", b =>
|
||||
@@ -1207,16 +1167,11 @@ namespace TechHelper.Server.Migrations
|
||||
|
||||
modelBuilder.Entity("Entities.Contracts.AssignmentQuestion", b =>
|
||||
{
|
||||
b.Navigation("ChildrenAssignmentQuestion");
|
||||
|
||||
b.Navigation("SubmissionDetails");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Entities.Contracts.AssignmentStruct", b =>
|
||||
{
|
||||
b.Navigation("AssignmentQuestions");
|
||||
|
||||
b.Navigation("ChildrenGroups");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Entities.Contracts.Class", b =>
|
||||
{
|
||||
b.Navigation("AssignmentClasses");
|
||||
@@ -1243,8 +1198,11 @@ namespace TechHelper.Server.Migrations
|
||||
modelBuilder.Entity("Entities.Contracts.Question", b =>
|
||||
{
|
||||
b.Navigation("AssignmentQuestions");
|
||||
});
|
||||
|
||||
b.Navigation("ChildrenQuestion");
|
||||
modelBuilder.Entity("Entities.Contracts.QuestionContext", b =>
|
||||
{
|
||||
b.Navigation("Questions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Entities.Contracts.Submission", b =>
|
@@ -77,6 +77,20 @@ namespace TechHelper.Server.Migrations
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "QuestionContexts",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
Description = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_QuestionContexts", x => x.Id);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "textbook",
|
||||
columns: table => new
|
||||
@@ -327,39 +341,6 @@ namespace TechHelper.Server.Migrations
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "assignment_group",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
assignment = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
|
||||
title = table.Column<string>(type: "longtext", maxLength: 65535, nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
descript = table.Column<string>(type: "longtext", maxLength: 65535, nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
layout = table.Column<byte>(type: "tinyint unsigned", nullable: false),
|
||||
total_points = table.Column<float>(type: "float", nullable: true),
|
||||
number = table.Column<byte>(type: "tinyint unsigned", nullable: false),
|
||||
parent_group = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
|
||||
deleted = table.Column<bool>(type: "tinyint(1)", nullable: false, defaultValue: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_assignment_group", x => x.id);
|
||||
table.ForeignKey(
|
||||
name: "FK_assignment_group_assignment_group_parent_group",
|
||||
column: x => x.parent_group,
|
||||
principalTable: "assignment_group",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.SetNull);
|
||||
table.ForeignKey(
|
||||
name: "FK_assignment_group_assignments_assignment",
|
||||
column: x => x.assignment,
|
||||
principalTable: "assignments",
|
||||
principalColumn: "id");
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "submissions",
|
||||
columns: table => new
|
||||
@@ -507,7 +488,7 @@ namespace TechHelper.Server.Migrations
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
Question = table.Column<string>(type: "longtext", nullable: false)
|
||||
Question = table.Column<string>(type: "longtext", maxLength: 65535, nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
LessonID = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci")
|
||||
},
|
||||
@@ -535,12 +516,10 @@ namespace TechHelper.Server.Migrations
|
||||
question_type = table.Column<byte>(type: "tinyint unsigned", maxLength: 20, nullable: false),
|
||||
difficulty_level = table.Column<byte>(type: "tinyint unsigned", maxLength: 10, nullable: false),
|
||||
subject_area = table.Column<byte>(type: "tinyint unsigned", maxLength: 100, nullable: false),
|
||||
group_state = table.Column<byte>(type: "tinyint unsigned", nullable: false),
|
||||
options = table.Column<string>(type: "longtext", nullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
key_point = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
|
||||
lesson = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
|
||||
parent_question_group_id = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
|
||||
created_by = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
created_at = table.Column<DateTime>(type: "datetime(6)", nullable: false)
|
||||
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||
@@ -568,12 +547,6 @@ namespace TechHelper.Server.Migrations
|
||||
principalTable: "lesson",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.SetNull);
|
||||
table.ForeignKey(
|
||||
name: "FK_questions_questions_parent_question_group_id",
|
||||
column: x => x.parent_question_group_id,
|
||||
principalTable: "questions",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.SetNull);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
@@ -582,9 +555,14 @@ namespace TechHelper.Server.Migrations
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
question_id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
group_id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
question_id = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
|
||||
assignment = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
|
||||
title = table.Column<string>(type: "varchar(1024)", maxLength: 1024, nullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
description = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
|
||||
question_number = table.Column<byte>(type: "tinyint unsigned", nullable: false),
|
||||
parent_question_group_id = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
|
||||
group_state = table.Column<byte>(type: "tinyint unsigned", nullable: false),
|
||||
created_at = table.Column<DateTime>(type: "datetime(6)", nullable: false),
|
||||
score = table.Column<float>(type: "float", nullable: true),
|
||||
deleted = table.Column<bool>(type: "tinyint(1)", nullable: false, defaultValue: false)
|
||||
@@ -593,11 +571,21 @@ namespace TechHelper.Server.Migrations
|
||||
{
|
||||
table.PrimaryKey("PK_assignment_questions", x => x.id);
|
||||
table.ForeignKey(
|
||||
name: "FK_assignment_questions_assignment_group_group_id",
|
||||
column: x => x.group_id,
|
||||
principalTable: "assignment_group",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
name: "FK_assignment_questions_QuestionContexts_description",
|
||||
column: x => x.description,
|
||||
principalTable: "QuestionContexts",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.SetNull);
|
||||
table.ForeignKey(
|
||||
name: "FK_assignment_questions_assignment_questions_parent_question_gr~",
|
||||
column: x => x.parent_question_group_id,
|
||||
principalTable: "assignment_questions",
|
||||
principalColumn: "id");
|
||||
table.ForeignKey(
|
||||
name: "FK_assignment_questions_assignments_assignment",
|
||||
column: x => x.assignment,
|
||||
principalTable: "assignments",
|
||||
principalColumn: "id");
|
||||
table.ForeignKey(
|
||||
name: "FK_assignment_questions_questions_question_id",
|
||||
column: x => x.question_id,
|
||||
@@ -655,9 +643,9 @@ namespace TechHelper.Server.Migrations
|
||||
columns: new[] { "Id", "ConcurrencyStamp", "Name", "NormalizedName" },
|
||||
values: new object[,]
|
||||
{
|
||||
{ new Guid("4e65fab9-3315-4474-b92c-bdab5a617e65"), null, "Administrator", "ADMINISTRATOR" },
|
||||
{ new Guid("895d8f32-714e-4a14-bd97-8fa262b83172"), null, "Student", "STUDENT" },
|
||||
{ new Guid("d182c396-c656-42da-965a-d93c17a1f74f"), null, "Teacher", "TEACHER" }
|
||||
{ new Guid("04b04eed-32b9-4eb0-b5f5-a97bb4626718"), null, "Teacher", "TEACHER" },
|
||||
{ new Guid("577dbfe8-7b77-4ead-9386-678f02dea5f4"), null, "Student", "STUDENT" },
|
||||
{ new Guid("82354e4d-902d-4dd6-9790-6ef50ba9bc11"), null, "Administrator", "ADMINISTRATOR" }
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
@@ -708,20 +696,20 @@ namespace TechHelper.Server.Migrations
|
||||
column: "class_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_assignment_group_assignment",
|
||||
table: "assignment_group",
|
||||
name: "IX_assignment_questions_assignment",
|
||||
table: "assignment_questions",
|
||||
column: "assignment",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_assignment_group_parent_group",
|
||||
table: "assignment_group",
|
||||
column: "parent_group");
|
||||
name: "IX_assignment_questions_description",
|
||||
table: "assignment_questions",
|
||||
column: "description");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_assignment_questions_group_id",
|
||||
name: "IX_assignment_questions_parent_question_group_id",
|
||||
table: "assignment_questions",
|
||||
column: "group_id");
|
||||
column: "parent_question_group_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_assignment_questions_question_id",
|
||||
@@ -783,11 +771,6 @@ namespace TechHelper.Server.Migrations
|
||||
table: "questions",
|
||||
column: "lesson");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_questions_parent_question_group_id",
|
||||
table: "questions",
|
||||
column: "parent_question_group_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_questions_question_text",
|
||||
table: "questions",
|
||||
@@ -874,7 +857,7 @@ namespace TechHelper.Server.Migrations
|
||||
name: "submissions");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "assignment_group");
|
||||
name: "QuestionContexts");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "questions");
|
@@ -158,9 +158,9 @@ namespace TechHelper.Server.Migrations
|
||||
.HasColumnType("char(36)")
|
||||
.HasColumnName("id");
|
||||
|
||||
b.Property<Guid>("AssignmentGroupId")
|
||||
b.Property<Guid?>("AssignmentId")
|
||||
.HasColumnType("char(36)")
|
||||
.HasColumnName("group_id");
|
||||
.HasColumnName("assignment");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime(6)")
|
||||
@@ -176,7 +176,15 @@ namespace TechHelper.Server.Migrations
|
||||
.HasDefaultValue(false)
|
||||
.HasColumnName("deleted");
|
||||
|
||||
b.Property<Guid>("QuestionId")
|
||||
b.Property<Guid?>("ParentAssignmentQuestionId")
|
||||
.HasColumnType("char(36)")
|
||||
.HasColumnName("parent_question_group_id");
|
||||
|
||||
b.Property<Guid?>("QuestionContextId")
|
||||
.HasColumnType("char(36)")
|
||||
.HasColumnName("description");
|
||||
|
||||
b.Property<Guid?>("QuestionId")
|
||||
.HasColumnType("char(36)")
|
||||
.HasColumnName("question_id");
|
||||
|
||||
@@ -184,58 +192,13 @@ namespace TechHelper.Server.Migrations
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("score");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("AssignmentGroupId");
|
||||
|
||||
b.HasIndex("QuestionId");
|
||||
|
||||
b.ToTable("assignment_questions", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Entities.Contracts.AssignmentStruct", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("char(36)")
|
||||
.HasColumnName("id");
|
||||
|
||||
b.Property<Guid?>("AssignmentId")
|
||||
.HasColumnType("char(36)")
|
||||
.HasColumnName("assignment");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasMaxLength(65535)
|
||||
.HasColumnType("longtext")
|
||||
.HasColumnName("descript");
|
||||
|
||||
b.Property<byte>("Index")
|
||||
b.Property<byte>("StructType")
|
||||
.HasColumnType("tinyint unsigned")
|
||||
.HasColumnName("number");
|
||||
|
||||
b.Property<bool>("IsDeleted")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("tinyint(1)")
|
||||
.HasDefaultValue(false)
|
||||
.HasColumnName("deleted");
|
||||
|
||||
b.Property<byte>("Layout")
|
||||
.HasColumnType("tinyint unsigned")
|
||||
.HasColumnName("layout");
|
||||
|
||||
b.Property<Guid?>("ParentGroupId")
|
||||
.HasColumnType("char(36)")
|
||||
.HasColumnName("parent_group");
|
||||
|
||||
b.Property<float?>("Score")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("total_points");
|
||||
.HasColumnName("group_state");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.IsRequired()
|
||||
.HasMaxLength(65535)
|
||||
.HasColumnType("longtext")
|
||||
.HasMaxLength(1024)
|
||||
.HasColumnType("varchar(1024)")
|
||||
.HasColumnName("title");
|
||||
|
||||
b.HasKey("Id");
|
||||
@@ -243,9 +206,13 @@ namespace TechHelper.Server.Migrations
|
||||
b.HasIndex("AssignmentId")
|
||||
.IsUnique();
|
||||
|
||||
b.HasIndex("ParentGroupId");
|
||||
b.HasIndex("ParentAssignmentQuestionId");
|
||||
|
||||
b.ToTable("assignment_group", (string)null);
|
||||
b.HasIndex("QuestionContextId");
|
||||
|
||||
b.HasIndex("QuestionId");
|
||||
|
||||
b.ToTable("assignment_questions", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Entities.Contracts.Class", b =>
|
||||
@@ -405,6 +372,7 @@ namespace TechHelper.Server.Migrations
|
||||
|
||||
b.Property<string>("Question")
|
||||
.IsRequired()
|
||||
.HasMaxLength(65535)
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.HasKey("Id");
|
||||
@@ -442,10 +410,6 @@ namespace TechHelper.Server.Migrations
|
||||
.HasColumnType("tinyint unsigned")
|
||||
.HasColumnName("difficulty_level");
|
||||
|
||||
b.Property<byte>("GroupState")
|
||||
.HasColumnType("tinyint unsigned")
|
||||
.HasColumnName("group_state");
|
||||
|
||||
b.Property<bool>("IsDeleted")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("tinyint(1)")
|
||||
@@ -464,10 +428,6 @@ namespace TechHelper.Server.Migrations
|
||||
.HasColumnType("longtext")
|
||||
.HasColumnName("options");
|
||||
|
||||
b.Property<Guid?>("ParentQuestionId")
|
||||
.HasColumnType("char(36)")
|
||||
.HasColumnName("parent_question_group_id");
|
||||
|
||||
b.Property<byte>("SubjectArea")
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("tinyint unsigned")
|
||||
@@ -498,14 +458,27 @@ namespace TechHelper.Server.Migrations
|
||||
|
||||
b.HasIndex("LessonId");
|
||||
|
||||
b.HasIndex("ParentQuestionId");
|
||||
|
||||
b.HasIndex("Title")
|
||||
.HasAnnotation("MySql:IndexPrefixLength", new[] { 20 });
|
||||
|
||||
b.ToTable("questions", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Entities.Contracts.QuestionContext", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("QuestionContexts");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Entities.Contracts.Submission", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
@@ -771,19 +744,19 @@ namespace TechHelper.Server.Migrations
|
||||
b.HasData(
|
||||
new
|
||||
{
|
||||
Id = new Guid("895d8f32-714e-4a14-bd97-8fa262b83172"),
|
||||
Id = new Guid("577dbfe8-7b77-4ead-9386-678f02dea5f4"),
|
||||
Name = "Student",
|
||||
NormalizedName = "STUDENT"
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = new Guid("d182c396-c656-42da-965a-d93c17a1f74f"),
|
||||
Id = new Guid("04b04eed-32b9-4eb0-b5f5-a97bb4626718"),
|
||||
Name = "Teacher",
|
||||
NormalizedName = "TEACHER"
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = new Guid("4e65fab9-3315-4474-b92c-bdab5a617e65"),
|
||||
Id = new Guid("82354e4d-902d-4dd6-9790-6ef50ba9bc11"),
|
||||
Name = "Administrator",
|
||||
NormalizedName = "ADMINISTRATOR"
|
||||
});
|
||||
@@ -939,37 +912,31 @@ namespace TechHelper.Server.Migrations
|
||||
|
||||
modelBuilder.Entity("Entities.Contracts.AssignmentQuestion", b =>
|
||||
{
|
||||
b.HasOne("Entities.Contracts.AssignmentStruct", "AssignmentGroup")
|
||||
.WithMany("AssignmentQuestions")
|
||||
.HasForeignKey("AssignmentGroupId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
b.HasOne("Entities.Contracts.Assignment", "Assignment")
|
||||
.WithOne("ExamStruct")
|
||||
.HasForeignKey("Entities.Contracts.AssignmentQuestion", "AssignmentId");
|
||||
|
||||
b.HasOne("Entities.Contracts.AssignmentQuestion", "ParentAssignmentQuestion")
|
||||
.WithMany("ChildrenAssignmentQuestion")
|
||||
.HasForeignKey("ParentAssignmentQuestionId");
|
||||
|
||||
b.HasOne("Entities.Contracts.QuestionContext", "QuestionContext")
|
||||
.WithMany("Questions")
|
||||
.HasForeignKey("QuestionContextId")
|
||||
.OnDelete(DeleteBehavior.SetNull);
|
||||
|
||||
b.HasOne("Entities.Contracts.Question", "Question")
|
||||
.WithMany("AssignmentQuestions")
|
||||
.HasForeignKey("QuestionId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("AssignmentGroup");
|
||||
|
||||
b.Navigation("Question");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Entities.Contracts.AssignmentStruct", b =>
|
||||
{
|
||||
b.HasOne("Entities.Contracts.Assignment", "Assignment")
|
||||
.WithOne("ExamStruct")
|
||||
.HasForeignKey("Entities.Contracts.AssignmentStruct", "AssignmentId");
|
||||
|
||||
b.HasOne("Entities.Contracts.AssignmentStruct", "ParentGroup")
|
||||
.WithMany("ChildrenGroups")
|
||||
.HasForeignKey("ParentGroupId")
|
||||
.OnDelete(DeleteBehavior.SetNull);
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.Navigation("Assignment");
|
||||
|
||||
b.Navigation("ParentGroup");
|
||||
b.Navigation("ParentAssignmentQuestion");
|
||||
|
||||
b.Navigation("Question");
|
||||
|
||||
b.Navigation("QuestionContext");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Entities.Contracts.Class", b =>
|
||||
@@ -1072,18 +1039,11 @@ namespace TechHelper.Server.Migrations
|
||||
.HasForeignKey("LessonId")
|
||||
.OnDelete(DeleteBehavior.SetNull);
|
||||
|
||||
b.HasOne("Entities.Contracts.Question", "ParentQuestion")
|
||||
.WithMany("ChildrenQuestion")
|
||||
.HasForeignKey("ParentQuestionId")
|
||||
.OnDelete(DeleteBehavior.SetNull);
|
||||
|
||||
b.Navigation("Creator");
|
||||
|
||||
b.Navigation("KeyPoint");
|
||||
|
||||
b.Navigation("Lesson");
|
||||
|
||||
b.Navigation("ParentQuestion");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Entities.Contracts.Submission", b =>
|
||||
@@ -1204,16 +1164,11 @@ namespace TechHelper.Server.Migrations
|
||||
|
||||
modelBuilder.Entity("Entities.Contracts.AssignmentQuestion", b =>
|
||||
{
|
||||
b.Navigation("ChildrenAssignmentQuestion");
|
||||
|
||||
b.Navigation("SubmissionDetails");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Entities.Contracts.AssignmentStruct", b =>
|
||||
{
|
||||
b.Navigation("AssignmentQuestions");
|
||||
|
||||
b.Navigation("ChildrenGroups");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Entities.Contracts.Class", b =>
|
||||
{
|
||||
b.Navigation("AssignmentClasses");
|
||||
@@ -1240,8 +1195,11 @@ namespace TechHelper.Server.Migrations
|
||||
modelBuilder.Entity("Entities.Contracts.Question", b =>
|
||||
{
|
||||
b.Navigation("AssignmentQuestions");
|
||||
});
|
||||
|
||||
b.Navigation("ChildrenQuestion");
|
||||
modelBuilder.Entity("Entities.Contracts.QuestionContext", b =>
|
||||
{
|
||||
b.Navigation("Questions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Entities.Contracts.Submission", b =>
|
||||
|
@@ -27,12 +27,12 @@ builder.Services.AddDbContext<ApplicationContext>(options =>
|
||||
).AddUnitOfWork<ApplicationContext>()
|
||||
.AddCustomRepository<Assignment, AssignmentRepository>()
|
||||
.AddCustomRepository<AssignmentAttachment, AssignmentAttachmentRepository>()
|
||||
.AddCustomRepository<AssignmentStruct, AssignmentGroupRepository>()
|
||||
.AddCustomRepository<AssignmentQuestion, AssignmentQuestionRepository>()
|
||||
.AddCustomRepository<Class, ClassRepository>()
|
||||
.AddCustomRepository<ClassStudent, ClassStudentRepository>()
|
||||
.AddCustomRepository<ClassTeacher, ClassTeacherRepository>()
|
||||
.AddCustomRepository<Question, QuestionRepository>()
|
||||
.AddCustomRepository<QuestionContext, QuestionContextRepository>()
|
||||
.AddCustomRepository<Submission, SubmissionRepository>();
|
||||
|
||||
builder.Services.AddAutoMapper(typeof(AutoMapperProFile).Assembly);
|
||||
|
@@ -10,14 +10,12 @@ namespace TechHelper.Server.Repositories
|
||||
{
|
||||
private readonly IUnitOfWork _unitOfWork;
|
||||
private readonly IRepository<Assignment> _assignmentRepo;
|
||||
private readonly IRepository<AssignmentStruct> _assignmentGroupRepo;
|
||||
private readonly IRepository<Question> _questionRepo;
|
||||
|
||||
public ExamRepository(IUnitOfWork unitOfWork)
|
||||
{
|
||||
_unitOfWork = unitOfWork;
|
||||
_assignmentRepo = _unitOfWork.GetRepository<Assignment>();
|
||||
_assignmentGroupRepo = _unitOfWork.GetRepository<AssignmentStruct>();
|
||||
}
|
||||
|
||||
public async Task<Assignment?> GetFullExamByIdAsync(Guid assignmentId)
|
||||
@@ -27,30 +25,7 @@ namespace TechHelper.Server.Repositories
|
||||
}
|
||||
|
||||
|
||||
private async Task LoadSubGroupsRecursive(AssignmentStruct group)
|
||||
{
|
||||
// EF Core 已经加载了下一层,我们需要确保更深层次的加载
|
||||
var groupWithChildren = await _assignmentGroupRepo.GetFirstOrDefaultAsync(
|
||||
predicate: g => g.Id == group.Id,
|
||||
include: source => source
|
||||
.Include(g => g.ChildrenGroups.Where(cg => !cg.IsDeleted))
|
||||
.ThenInclude(cg => cg.AssignmentQuestions.Where(aq => !aq.IsDeleted))
|
||||
.ThenInclude(aq => aq.Question)
|
||||
.Include(g => g.AssignmentQuestions.Where(aq => !aq.IsDeleted))
|
||||
.ThenInclude(aq => aq.Question)
|
||||
);
|
||||
|
||||
group.ChildrenGroups = groupWithChildren.ChildrenGroups;
|
||||
group.AssignmentQuestions = groupWithChildren.AssignmentQuestions;
|
||||
|
||||
if (group.ChildrenGroups != null)
|
||||
{
|
||||
foreach (var child in group.ChildrenGroups)
|
||||
{
|
||||
await LoadSubGroupsRecursive(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Assignment>> GetExamPreviewsByUserAsync(Guid userId)
|
||||
{
|
||||
@@ -72,11 +47,6 @@ namespace TechHelper.Server.Repositories
|
||||
}
|
||||
}
|
||||
|
||||
public async Task AddAsync(AssignmentStruct assignment)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public async Task AddAsync(AssignmentQuestion assignment)
|
||||
{
|
||||
}
|
||||
|
@@ -26,7 +26,6 @@ namespace TechHelper.Server.Repositories
|
||||
|
||||
|
||||
|
||||
Task AddAsync(AssignmentStruct assignment);
|
||||
|
||||
Task AddAsync(AssignmentQuestion assignment);
|
||||
|
||||
|
@@ -5,10 +5,13 @@ using TechHelper.Context;
|
||||
|
||||
namespace TechHelper.Repository
|
||||
{
|
||||
public class AssignmentGroupRepository : Repository<AssignmentStruct>, IRepository<AssignmentStruct>
|
||||
public class QuestionContextRepository : Repository<QuestionContext>, IRepository<QuestionContext>
|
||||
{
|
||||
public AssignmentGroupRepository(ApplicationContext dbContext) : base(dbContext)
|
||||
public QuestionContextRepository(ApplicationContext dbContext) : base(dbContext)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
@@ -24,6 +24,8 @@ namespace TechHelper.Server.Services
|
||||
}
|
||||
|
||||
public async Task<ApiResponse> CreateExamAsync(AssignmentDto assignmentDto)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
Assignment newAssi = _mapper.Map<Assignment>(assignmentDto);
|
||||
@@ -45,67 +47,21 @@ namespace TechHelper.Server.Services
|
||||
|
||||
}
|
||||
|
||||
await _unitOfWork.SaveChangesAsync();
|
||||
|
||||
if (await _unitOfWork.SaveChangesAsync() > 0)
|
||||
{
|
||||
return ApiResponse.Success();
|
||||
}
|
||||
|
||||
private async void ParseStruct(AssignmentStructDto assignmentStruct, Guid ParentID)
|
||||
{
|
||||
|
||||
var newStruct = _mapper.Map<AssignmentStruct>(assignmentStruct);
|
||||
newStruct.ParentStructId = Guid.Empty == ParentID ? null : ParentID;
|
||||
await _examRepository.AddAsync(newStruct);
|
||||
|
||||
|
||||
foreach (var item in assignmentStruct.AssignmentQuestions)
|
||||
{
|
||||
var newQuestion = _mapper.Map<Question>(item);
|
||||
//newQuestion.ParentQuestionId = item.ParentQuestion == null ? null : item.ParentQuestion.Id;
|
||||
await _examRepository.AddAsync(newQuestion);
|
||||
|
||||
//await ParseAssignmentQuestion(assignmentStruct, item, newQuestion);
|
||||
return ApiResponse.Error("保存失败");
|
||||
}
|
||||
|
||||
|
||||
foreach (var item in assignmentStruct.ChildrenGroups)
|
||||
catch (Exception ex)
|
||||
{
|
||||
ParseStruct(item, assignmentStruct.Id);
|
||||
return ApiResponse.Error(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ParseAssignmentQuestion(AssignmentStructDto assignmentStruct, QuestionDto item, Question newQuestion)
|
||||
{
|
||||
AssignmentQuestion newAssignQues = new AssignmentQuestion();
|
||||
newAssignQues.QuestionId = newQuestion.Id;
|
||||
newAssignQues.AssignmentStructId = assignmentStruct.Id;
|
||||
newAssignQues.CreatedAt = DateTime.UtcNow;
|
||||
newAssignQues.Score = item.Score;
|
||||
await _examRepository.AddAsync(newAssignQues);
|
||||
}
|
||||
|
||||
private void SetEntityIdsAndRelations(AssignmentStruct group, Guid? assignmentId, Guid creatorId)
|
||||
{
|
||||
group.Id = Guid.NewGuid();
|
||||
group.AssignmentId = assignmentId;
|
||||
|
||||
foreach (var aq in group.AssignmentQuestions)
|
||||
{
|
||||
aq.Id = Guid.NewGuid();
|
||||
aq.AssignmentStructId = group.Id;
|
||||
aq.Question.Id = Guid.NewGuid();
|
||||
aq.Question.CreatorId = creatorId;
|
||||
aq.CreatedAt = DateTime.UtcNow;
|
||||
// ... 其他默认值
|
||||
}
|
||||
|
||||
foreach (var childGroup in group.ChildrenGroups)
|
||||
{
|
||||
// 子题组的 AssignmentId 为 null,通过 ParentGroup 关联
|
||||
SetEntityIdsAndRelations(childGroup, null, creatorId);
|
||||
childGroup.ParentStructId = group.Id;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<AssignmentDto> GetExamByIdAsync(Guid id)
|
||||
{
|
||||
|
@@ -1,9 +0,0 @@
|
||||
using Entities.Contracts;
|
||||
using TechHelper.Services;
|
||||
|
||||
namespace TechHelper.Server.Services
|
||||
{
|
||||
public interface IAssignmentGroupService : IBaseService<AssignmentStruct, Guid>
|
||||
{
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user