CleanExamDto
This commit is contained in:
@@ -38,77 +38,9 @@ namespace Entities.DTO
|
|||||||
public string Description { get; set; } = string.Empty;
|
public string Description { get; set; } = string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class ExamDto
|
|
||||||
{
|
|
||||||
public Guid? AssignmentId { get; set; }
|
|
||||||
public string CreaterEmail { get; set; }
|
|
||||||
public string AssignmentTitle { get; set; } = string.Empty;
|
|
||||||
public string Description { get; set; }
|
|
||||||
public string SubjectArea { get; set; }
|
|
||||||
public QuestionGroupDto ExamStruct { get; set; } = new QuestionGroupDto();
|
|
||||||
}
|
|
||||||
|
|
||||||
public class QuestionGroupDto
|
|
||||||
{
|
|
||||||
public byte Index { get; set; }
|
|
||||||
|
|
||||||
public string? Title { get; set; }
|
|
||||||
|
|
||||||
public float Score { get; set; }
|
|
||||||
|
|
||||||
public string? Descript { get; set; }
|
|
||||||
public List<SubQuestionDto> SubQuestions { get; set; } = new List<SubQuestionDto>();
|
|
||||||
public List<QuestionGroupDto> SubQuestionGroups { get; set; } = new List<QuestionGroupDto>();
|
|
||||||
|
|
||||||
public bool ValidQuestionGroup { get; set; } = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class SubQuestionDto
|
|
||||||
{
|
|
||||||
|
|
||||||
public byte Index { get; set; }
|
|
||||||
|
|
||||||
public string? Stem { get; set; }
|
|
||||||
|
|
||||||
public float Score { get; set; }
|
|
||||||
|
|
||||||
public List<OptionDto> Options { get; set; } = new List<OptionDto>();
|
|
||||||
|
|
||||||
public string? SampleAnswer { get; set; }
|
|
||||||
|
|
||||||
public string? QuestionType { get; set; }
|
|
||||||
public string? DifficultyLevel { get; set; }
|
|
||||||
|
|
||||||
public bool ValidQuestion { get; set; } = false;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public class OptionDto
|
public class OptionDto
|
||||||
{
|
{
|
||||||
public string? Value { get; set; } = string.Empty;
|
public string? Value { get; set; } = string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static class ExamDtoExtension
|
|
||||||
{
|
|
||||||
public static void Convert(this ExamDto examDto)
|
|
||||||
{
|
|
||||||
var qg = examDto.ExamStruct;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Convert(this QuestionGroupDto examDto)
|
|
||||||
{
|
|
||||||
if (examDto.ValidQuestionGroup)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -40,7 +40,7 @@ namespace TechHelper.Client.Exam
|
|||||||
|
|
||||||
public static class ExamStructExtensions
|
public static class ExamStructExtensions
|
||||||
{
|
{
|
||||||
public static ExamStruct GetStruct(this ExamDto dto)
|
public static ExamStruct GetStruct(this AssignmentDto dto)
|
||||||
{
|
{
|
||||||
if (dto == null)
|
if (dto == null)
|
||||||
{
|
{
|
||||||
@@ -49,7 +49,7 @@ namespace TechHelper.Client.Exam
|
|||||||
|
|
||||||
var examStruct = new ExamStruct
|
var examStruct = new ExamStruct
|
||||||
{
|
{
|
||||||
Title = dto.AssignmentTitle
|
Title = dto.Title
|
||||||
};
|
};
|
||||||
|
|
||||||
GetSeqRecursive(dto.ExamStruct, null, examStruct.Questions);
|
GetSeqRecursive(dto.ExamStruct, null, examStruct.Questions);
|
||||||
@@ -64,7 +64,7 @@ namespace TechHelper.Client.Exam
|
|||||||
/// <param name="parentSequence">当前题目组的父级序号(例如:"1", "2.1")。如果为空,则表示顶级题目组。</param>
|
/// <param name="parentSequence">当前题目组的父级序号(例如:"1", "2.1")。如果为空,则表示顶级题目组。</param>
|
||||||
/// <param name="allQuestions">用于收集所有生成题目项的列表。</param>
|
/// <param name="allQuestions">用于收集所有生成题目项的列表。</param>
|
||||||
private static void GetSeqRecursive(
|
private static void GetSeqRecursive(
|
||||||
QuestionGroupDto currentGroup,
|
AssignmentQuestionDto currentGroup,
|
||||||
string? parentSequence,
|
string? parentSequence,
|
||||||
List<ExamStruct.QuestionItem> allQuestions)
|
List<ExamStruct.QuestionItem> allQuestions)
|
||||||
{
|
{
|
||||||
@@ -72,18 +72,7 @@ namespace TechHelper.Client.Exam
|
|||||||
? $"{parentSequence}.{currentGroup.Index}"
|
? $"{parentSequence}.{currentGroup.Index}"
|
||||||
: currentGroup.Index.ToString();
|
: currentGroup.Index.ToString();
|
||||||
|
|
||||||
foreach (var subQuestion in currentGroup.SubQuestions)
|
foreach (var subGroup in currentGroup.ChildrenAssignmentQuestion)
|
||||||
{
|
|
||||||
string fullSequence = $"{currentGroupSequence}.{subQuestion.Index}";
|
|
||||||
allQuestions.Add(new ExamStruct.QuestionItem
|
|
||||||
{
|
|
||||||
Sequence = fullSequence,
|
|
||||||
QuestionText = subQuestion.Stem ?? string.Empty,
|
|
||||||
Score = subQuestion.Score
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var subGroup in currentGroup.SubQuestionGroups)
|
|
||||||
{
|
{
|
||||||
GetSeqRecursive(subGroup, currentGroupSequence, allQuestions);
|
GetSeqRecursive(subGroup, currentGroupSequence, allQuestions);
|
||||||
}
|
}
|
||||||
|
@@ -4,7 +4,7 @@
|
|||||||
@page "/exam/check/{ExamID}"
|
@page "/exam/check/{ExamID}"
|
||||||
|
|
||||||
|
|
||||||
<MudText Typo="Typo.h4" Class="mb-4">试卷批改预览: @ExamDto.AssignmentTitle</MudText>
|
<MudText Typo="Typo.h4" Class="mb-4">试卷批改预览: @Assignment.Title</MudText>
|
||||||
<MudDivider Class="my-4" />
|
<MudDivider Class="my-4" />
|
||||||
|
|
||||||
@if (_isLoading)
|
@if (_isLoading)
|
||||||
@@ -74,36 +74,36 @@ else
|
|||||||
|
|
||||||
@code {
|
@code {
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public string ExamId { get; set; } // 从路由获取的试卷ID
|
public string ExamId { get; set; }
|
||||||
|
|
||||||
[Inject]
|
[Inject]
|
||||||
public IExamService ExamService { get; set; } // 注入试卷服务
|
public IExamService ExamService { get; set; }
|
||||||
|
|
||||||
[Inject]
|
[Inject]
|
||||||
private ISnackbar Snackbar { get; set; } // 注入 Snackbar 用于消息提示
|
private ISnackbar Snackbar { get; set; }
|
||||||
|
|
||||||
[Inject]
|
[Inject]
|
||||||
private NavigationManager Navigation { get; set; } // 注入导航管理器
|
private NavigationManager Navigation { get; set; }
|
||||||
|
|
||||||
private MudTable<QuestionRowData> _table = new(); // MudTable 实例引用
|
private MudTable<QuestionRowData> _table = new();
|
||||||
private ExamDto ExamDto { get; set; } = new ExamDto(); // 原始试卷数据
|
private AssignmentDto Assignment { get; set; } = new AssignmentDto();
|
||||||
private ExamStruct _examStruct = new ExamStruct(); // 处理后的试卷结构,包含带序号的题目
|
private ExamStruct _examStruct = new ExamStruct();
|
||||||
|
|
||||||
private List<Student> _students = new List<Student>(); // 临时生成的学生列表
|
private List<Student> _students = new List<Student>();
|
||||||
private List<QuestionRowData> _questionsForTable = new List<QuestionRowData>(); // 用于 MudTable 的数据源
|
private List<QuestionRowData> _questionsForTable = new List<QuestionRowData>();
|
||||||
|
|
||||||
|
private bool _isLoading = true;
|
||||||
|
|
||||||
private bool _isLoading = true; // 加载状态
|
|
||||||
|
|
||||||
// 在组件初始化时加载数据
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
_isLoading = true;
|
_isLoading = true;
|
||||||
await LoadExamData();
|
await LoadExamData();
|
||||||
GenerateTemporaryStudentsAndAnswers(); // 生成学生和初始作答数据
|
GenerateTemporaryStudentsAndAnswers();
|
||||||
_isLoading = false;
|
_isLoading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 加载试卷数据的方法
|
|
||||||
private async Task LoadExamData()
|
private async Task LoadExamData()
|
||||||
{
|
{
|
||||||
if (Guid.TryParse(ExamId, out Guid parsedExamId))
|
if (Guid.TryParse(ExamId, out Guid parsedExamId))
|
||||||
@@ -113,13 +113,13 @@ else
|
|||||||
var result = await ExamService.GetExam(parsedExamId);
|
var result = await ExamService.GetExam(parsedExamId);
|
||||||
if (result.Status)
|
if (result.Status)
|
||||||
{
|
{
|
||||||
ExamDto = result.Result as ExamDto ?? new ExamDto();
|
Assignment = result.Result as AssignmentDto ?? new AssignmentDto();
|
||||||
_examStruct = ExamDto.GetStruct(); // 将 ExamDto 转换为 ExamStruct
|
_examStruct = Assignment.GetStruct();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Snackbar?.Add($"获取试卷失败: {result.Message}", Severity.Error);
|
Snackbar?.Add($"获取试卷失败: {result.Message}", Severity.Error);
|
||||||
Navigation.NavigateTo("/exam/manager"); // 导航回管理页
|
Navigation.NavigateTo("/exam/manager");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
@@ -23,50 +23,30 @@ namespace TechHelper.Context
|
|||||||
public AutoMapperProFile()
|
public AutoMapperProFile()
|
||||||
{
|
{
|
||||||
CreateMap<UserForRegistrationDto, User>()
|
CreateMap<UserForRegistrationDto, User>()
|
||||||
.ForMember(dest => dest.Id, opt => opt.Ignore()) // ID由IdentityUser生成
|
.ForMember(dest => dest.Id, opt => opt.Ignore())
|
||||||
.ForMember(dest => dest.UserName, opt => opt.MapFrom(src => src.Name)) // 或者 MapFrom(src => src.Name)
|
.ForMember(dest => dest.UserName, opt => opt.MapFrom(src => src.Name))
|
||||||
.ForMember(dest => dest.Email, opt => opt.MapFrom(src => src.Email))
|
.ForMember(dest => dest.Email, opt => opt.MapFrom(src => src.Email))
|
||||||
.ForMember(dest => dest.PhoneNumber, opt => opt.MapFrom(src => src.PhoneNumber))
|
.ForMember(dest => dest.PhoneNumber, opt => opt.MapFrom(src => src.PhoneNumber))
|
||||||
.ForMember(dest => dest.Address, opt => opt.MapFrom(src => src.HomeAddress)) // 映射到 IdentityUser 的 Address 属性
|
.ForMember(dest => dest.Address, opt => opt.MapFrom(src => src.HomeAddress))
|
||||||
.ForMember(dest => dest.PasswordHash, opt => opt.Ignore()) // 密码哈希由 UserManager 处理
|
.ForMember(dest => dest.PasswordHash, opt => opt.Ignore())
|
||||||
.ForMember(dest => dest.EmailConfirmed, opt => opt.Ignore()); // 邮箱确认状态由服务层处理
|
.ForMember(dest => dest.EmailConfirmed, opt => opt.Ignore());
|
||||||
|
|
||||||
CreateMap<ClassDto, Class>()
|
CreateMap<ClassDto, Class>()
|
||||||
.ForMember(d => d.Number, o => o.MapFrom(src => src.Class)).ReverseMap();
|
.ForMember(d => d.Number, o => o.MapFrom(src => src.Class)).ReverseMap();
|
||||||
|
|
||||||
CreateMap<SubQuestionDto, Question>()
|
|
||||||
.ForMember(dest => dest.Id, opt => opt.Ignore())
|
|
||||||
.ForMember(dest => dest.Title, opt => opt.MapFrom(src => src.Stem))
|
|
||||||
.ForMember(dest => dest.Answer, opt => opt.MapFrom(src => src.SampleAnswer))
|
|
||||||
.ForMember(dest => dest.Type, opt => opt.MapFrom(src => EnumMappingHelpers.ParseEnumSafe(src.QuestionType, QuestionType.Unknown)))
|
|
||||||
.ForMember(dest => dest.DifficultyLevel, opt => opt.MapFrom(src => EnumMappingHelpers.ParseEnumSafe(src.DifficultyLevel, DifficultyLevel.easy)))
|
|
||||||
.ForMember(dest => dest.SubjectArea, opt => opt.MapFrom(src => EnumMappingHelpers.ParseEnumSafe(src.DifficultyLevel, SubjectAreaEnum.Unknown)))
|
|
||||||
.ForMember(dest => dest.CreatorId, opt => opt.Ignore())
|
|
||||||
.ForMember(dest => dest.CreatedAt, opt => opt.Ignore())
|
|
||||||
.ForMember(dest => dest.UpdatedAt, opt => opt.Ignore())
|
|
||||||
.ForMember(dest => dest.IsDeleted, opt => opt.Ignore());
|
|
||||||
|
|
||||||
|
|
||||||
// =============================================================
|
|
||||||
// ENTITY -> DTO Mappings (用于读取/查询)
|
|
||||||
// =============================================================
|
|
||||||
CreateMap<Assignment, AssignmentDto>();
|
CreateMap<Assignment, AssignmentDto>();
|
||||||
|
|
||||||
CreateMap<QuestionContext, QuestionContextDto>().ReverseMap();
|
CreateMap<QuestionContext, QuestionContextDto>().ReverseMap();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 新增!从实体到新的 DTO 的映射
|
|
||||||
CreateMap<AssignmentQuestion, AssignmentQuestionDto>();
|
CreateMap<AssignmentQuestion, AssignmentQuestionDto>();
|
||||||
|
|
||||||
CreateMap<Question, QuestionDto>();
|
CreateMap<Question, QuestionDto>();
|
||||||
|
|
||||||
// =================================================================
|
|
||||||
// DTO -> ENTITY Mappings (用于创建/更新) - 现在变得极其简单!
|
|
||||||
// =================================================================
|
|
||||||
CreateMap<AssignmentDto, Assignment>();
|
CreateMap<AssignmentDto, Assignment>();
|
||||||
|
|
||||||
// 新增!从新的 DTO 到实体的映射
|
|
||||||
CreateMap<AssignmentQuestionDto, AssignmentQuestion>();
|
CreateMap<AssignmentQuestionDto, AssignmentQuestion>();
|
||||||
|
|
||||||
CreateMap<QuestionDto, Question>();
|
CreateMap<QuestionDto, Question>();
|
||||||
|
@@ -79,15 +79,6 @@ namespace TechHelper.Server.Repositories
|
|||||||
await _assignmentRepo.InsertAsync(assignment);
|
await _assignmentRepo.InsertAsync(assignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public async Task AddAsync(QuestionGroupDto qg)
|
|
||||||
{
|
|
||||||
if (qg.ValidQuestionGroup)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task AddAsync(AssignmentQuestion assignment)
|
public async Task AddAsync(AssignmentQuestion assignment)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@@ -127,6 +127,11 @@ namespace TechHelper.Services
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Task<ApiResponse> GetClassStudents(ClassDto classDto)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<ApiResponse> GetUserClass(Guid id)
|
public async Task<ApiResponse> GetUserClass(Guid id)
|
||||||
{
|
{
|
||||||
var tch = await _work.GetRepository<ClassTeacher>().GetAllAsync(predicate: user => user.TeacherId == id, include: i => i
|
var tch = await _work.GetRepository<ClassTeacher>().GetAllAsync(predicate: user => user.TeacherId == id, include: i => i
|
||||||
|
Reference in New Issue
Block a user