重构作业结构:优化实体模型、DTO映射和前端界面
Some checks failed
TechAct / explore-gitea-actions (push) Failing after 13s

- 重构AppMainStruct、AssignmentQuestion、Question等实体模型
- 更新相关DTO以匹配新的数据结构
- 优化前端页面布局和组件
- 添加全局信息和笔记功能相关代码
- 更新数据库迁移和程序配置
This commit is contained in:
SpecialX
2025-09-04 15:43:33 +08:00
parent 730b0ba04b
commit 6a65281850
58 changed files with 5459 additions and 244 deletions

View File

@@ -1,5 +1,6 @@
@using Entities.DTO
@using Entities.Contracts
@using Newtonsoft.Json
@using TechHelper.Client.Exam
@using TechHelper.Client.Pages.Exam.QuestionCard
@@ -12,12 +13,30 @@
<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.Root">@AssignmentStructType.Root</MudChip>
<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>
<MudChipSet T="string" SelectedValue="@AssignmentQuestion.QType" CheckMark SelectionMode="SelectionMode.SingleSelection" SelectedValueChanged="HandleQTSelectedValueChanged">
@foreach (var item in QuestionTypes)
{
var qt = item;
@* Style = "@($"background - color:{ item.Value.Color} ")"*@
<MudChip Style="@(qt.Key == AssignmentQuestion.QType ?
$"background-color:#ffffff; color:{item.Value.Color}" :
$"background-color:{item.Value.Color}; color:#ffffff")"
Value="@item.Key">
@item.Value.DisplayName
</MudChip>
}
</MudChipSet>
</MudPaper>
@if (AssignmentQuestion.Question != null)
{
@@ -30,6 +49,10 @@
[Parameter]
public AssignmentQuestionDto AssignmentQuestion { get; set; } = new AssignmentQuestionDto();
public QuestionDto TempQuesdto;
Dictionary<string, QuestionDisplayTypeData> QuestionTypes = new Dictionary<string, QuestionDisplayTypeData>();
[Inject]
private ILocalStorageService LocalStorageService { get; set; }
protected override void OnInitialized()
{
base.OnInitialized();
@@ -37,6 +60,30 @@
{
TempQuesdto = AssignmentQuestion.Question;
}
var cs = LocalStorageService.GetItem<string>("GlobalInfo");
var GlobalInfo = JsonConvert.DeserializeObject<Dictionary<string, QuestionDisplayTypeData>>(cs);
if(GlobalInfo != null)
{
QuestionTypes = GlobalInfo;
}
}
private void HandleQTSelectedValueChanged(string type)
{
AssignmentQuestion.QType = type;
if (AssignmentQuestion.ChildrenAssignmentQuestion.Count > 0 && AssignmentQuestion.StructType == AssignmentStructType.Group)
{
foreach (var item in AssignmentQuestion.ChildrenAssignmentQuestion)
{
item.QType = type;
if (item.Question != null)
{
item.Question.QType = type;
}
}
}
StateHasChanged();
}
private void HandleSelectedValueChanged(AssignmentStructType type)

View File

@@ -1,5 +1,7 @@
@page "/exam/create"
@using AutoMapper
@using Entities.Contracts
@using Newtonsoft.Json
@using TechHelper.Client.Pages.Common
@using TechHelper.Client.Pages.Exam.ExamView
@using TechHelper.Client.Services
@@ -39,10 +41,12 @@
<MudStack Class="flex-grow-1 h-100">
<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>
<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>
<MudButton Variant="Variant.Filled" Color="Color.Secondary" Class="rounded-xl" Size="Size.Small" OnClick="OpenTest">Test</MudButton>
<MudButton Variant="Variant.Filled" Color="Color.Secondary" Class="rounded-xl" Size="Size.Small" OnClick="HandleGlobalInfo">GlobalExamInfo</MudButton>
</MudPaper>
@@ -84,11 +88,32 @@
private ExamParserConfig _examParserConfig { get; set; } = new ExamParserConfig();
private string EditorText = "";
[Inject]
private ILocalStorageService LocalStorageService { get; set; }
[Inject]
public IMapper Mapper { get; set; }
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
var response = await NoteService.GetNote((byte)SubjectAreaEnum.Literature);
if (response.Status)
{
try
{
LocalStorageService.SetItem("GlobalInfo", response.Result);
}
catch (Exception ex)
{
}
}
}
private async void OpenEditor()
{
var parameters = new DialogParameters<TextEditorDialog> { { x => x.TextEditor, _textEditor } };
@@ -169,13 +194,43 @@
[Inject]
public IExamService examService { get; set; }
[Inject]
public INoteService NoteService { get; set; }
public async Task Publish()
{
var apiRespon = await examService.SaveParsedExam(ExamContent);
Snackbar.Add(apiRespon.Message);
}
public async Task OpenTest()
{
Dictionary<string, (Color, string)> Note = new Dictionary<string, (Color, string)> { { "Hello", (Color.Surface, "World") }, { "My", (Color.Surface, "App") }, };
var json = JsonConvert.SerializeObject(Note);
var result = await NoteService.AddNote(new GlobalDto { SubjectArea = Entities.Contracts.SubjectAreaEnum.Physics, Data = json });
Console.WriteLine(json);
var res = JsonConvert.DeserializeObject<Dictionary<string, (Color, string)>>(json);
}
private async void HandleGlobalInfo()
{
// _open = true;
// _edit = true;
// StateHasChanged();
var parameters = new DialogParameters<ExamGlobalInfoDialog> { { x => x.Assignment, ExamContent } };
var dialog = await DialogService.ShowAsync<ExamGlobalInfoDialog>("Exam_GlobalInfo", parameters);
var result = await dialog.Result;
if (!result.Canceled)
{
}
StateHasChanged();
}
}

View File

@@ -1,5 +1,6 @@
@using Entities.Contracts
@using Entities.DTO
@using Newtonsoft.Json
@using TechHelper.Client.Exam
@using TechHelper.Client.Pages.Exam.QuestionCard
@@ -22,6 +23,11 @@
<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>
<MudChip T="string" Color="Color.Warning" Class="justify-content-end">@(ExamStruct.QType == string.Empty ? "" : QuestionTypes[ExamStruct.QType].DisplayName)</MudChip>
@if(ExamStruct.Question!=null)
{
<MudRating SelectedValue="@((int)ExamStruct.Question.DifficultyLevel)" ReadOnly="true" Size="Size.Small" />
}
</MudStack>
</MudStack>
@@ -75,6 +81,22 @@
[Parameter]
public string Style { get; set; } = "background-color : #eeeeee";
Dictionary<string, QuestionDisplayTypeData> QuestionTypes = new Dictionary<string, QuestionDisplayTypeData>();
[Inject]
private ILocalStorageService LocalStorageService { get; set; }
protected override void OnInitialized()
{
base.OnInitialized();
var cs = LocalStorageService.GetItem<string>("GlobalInfo");
var GlobalInfo = JsonConvert.DeserializeObject<Dictionary<string, QuestionDisplayTypeData>>(cs);
if (GlobalInfo != null)
{
QuestionTypes = GlobalInfo;
}
}
private async void HandleClick()
{
await ClickedStruct.InvokeAsync(ExamStruct);
@@ -84,4 +106,10 @@
{
await ClickedStruct.InvokeAsync(clickedChildExamStruct);
}
private void HandleSelected(int num)
{
ExamStruct.Question.DifficultyLevel = (DifficultyLevel)num;
}
}

View File

@@ -1,10 +1,29 @@
@using Entities.DTO
@using Entities.Contracts
@using Newtonsoft.Json
@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>
<MudChipSet T="string" SelectedValue="@Question.QType" CheckMark SelectionMode="SelectionMode.SingleSelection" SelectedValueChanged="HandleQTSelectedValueChanged">
@foreach (var item in QuestionTypes)
{
var qt = item;
@* Style = "@($"background - color:{ item.Value.Color} ")"*@
<MudChip Style="@(qt.Key == Question.QType ?
$"background-color:#ffffff; color:{item.Value.Color}" :
$"background-color:{item.Value.Color}; color:#ffffff")"
Value="@item.Key">
@item.Value.DisplayName
</MudChip>
}
</MudChipSet>
<MudRating SelectedValue="@(diffi)" SelectedValueChanged="HandleSelected" Size="Size.Small" />
<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" />
@@ -15,4 +34,35 @@
@code {
[Parameter]
public QuestionDto Question { get; set; } = new QuestionDto();
public int diffi = 0;
Dictionary<string, QuestionDisplayTypeData> QuestionTypes = new Dictionary<string, QuestionDisplayTypeData>();
[Inject]
private ILocalStorageService LocalStorageService { get; set; }
protected override void OnInitialized()
{
base.OnInitialized();
var cs = LocalStorageService.GetItem<string>("GlobalInfo");
var GlobalInfo = JsonConvert.DeserializeObject<Dictionary<string, QuestionDisplayTypeData>>(cs);
if (GlobalInfo != null)
{
QuestionTypes = GlobalInfo;
}
}
private void HandleSelectedValueChanged(QuestionType type)
{
Question.Type = type;
}
private void HandleSelected(int num)
{
Question.DifficultyLevel = (DifficultyLevel)num;
}
private void HandleQTSelectedValueChanged(string type)
{
Question.QType = type;
StateHasChanged();
}
}