@using Entities.DTO @using TechHelper.Client.Exam @page "/exam/check/{ExamID}" 试卷批改预览: @ExamDto.AssignmentTitle @if (_isLoading) { 正在加载试卷和学生数据... } else if (_questionsForTable.Any() && _students.Any()) { 序号 分值 @foreach (var student in _students) { @student.Name } @context.QuestionItem.Sequence @context.QuestionItem.Score @foreach (var student in _students) { @if (context.StudentAnswers.ContainsKey(student.Id)) { } else { N/A } } 学生总分预览: @foreach (var student in _students) { @student.Name: @GetStudentTotalScore(student.Id) } 提交批改结果 (模拟) } else { 无法加载试卷或题目信息。 返回试卷列表 } @code { [Parameter] public string ExamId { get; set; } // 从路由获取的试卷ID [Inject] public IExamService ExamService { get; set; } // 注入试卷服务 [Inject] private ISnackbar Snackbar { get; set; } // 注入 Snackbar 用于消息提示 [Inject] private NavigationManager Navigation { get; set; } // 注入导航管理器 private MudTable _table = new(); // MudTable 实例引用 private ExamDto ExamDto { get; set; } = new ExamDto(); // 原始试卷数据 private ExamStruct _examStruct = new ExamStruct(); // 处理后的试卷结构,包含带序号的题目 private List _students = new List(); // 临时生成的学生列表 private List _questionsForTable = new List(); // 用于 MudTable 的数据源 private bool _isLoading = true; // 加载状态 // 在组件初始化时加载数据 protected override async Task OnInitializedAsync() { _isLoading = true; await LoadExamData(); GenerateTemporaryStudentsAndAnswers(); // 生成学生和初始作答数据 _isLoading = false; } // 加载试卷数据的方法 private async Task LoadExamData() { if (Guid.TryParse(ExamId, out Guid parsedExamId)) { try { var result = await ExamService.GetExam(parsedExamId); if (result.Status) { ExamDto = result.Result as ExamDto ?? new ExamDto(); _examStruct = ExamDto.GetStruct(); // 将 ExamDto 转换为 ExamStruct } else { Snackbar?.Add($"获取试卷失败: {result.Message}", Severity.Error); Navigation.NavigateTo("/exam/manager"); // 导航回管理页 } } catch (Exception ex) { Console.Error.WriteLine($"获取试卷时发生错误: {ex.Message}"); Snackbar?.Add($"获取试卷失败: {ex.Message}", Severity.Error); Navigation.NavigateTo("/exam/manager"); } } else { Console.Error.WriteLine($"错误:路由参数 ExamId '{ExamId}' 不是一个有效的 GUID 格式。"); Snackbar?.Add("无效的试卷ID,无法加载。", Severity.Error); Navigation.NavigateTo("/exam/manager"); } } // 生成临时学生和作答数据 private void GenerateTemporaryStudentsAndAnswers() { _students = new List(); // 生成 40 个学生 for (int i = 1; i <= 40; i++) { _students.Add(new Student { Name = $"学生{i}" }); } _questionsForTable = _examStruct.Questions.Select(qItem => { var rowData = new QuestionRowData { QuestionItem = qItem, StudentAnswers = new Dictionary() }; // 为每个学生随机生成初始的对错状态 var random = new Random(); foreach (var student in _students) { // 模拟随机对错,50%的概率 rowData.StudentAnswers[student.Id] = random.Next(0, 2) == 1; } return rowData; }).ToList(); } // 当某个学生的某个题目的作答状态改变时触发 private void OnAnswerChanged(string questionSequence, Guid studentId, bool isCorrect) { // 可以在这里添加额外的逻辑,例如记录更改 Console.WriteLine($"题目 {questionSequence}, 学生 {studentId} 的答案变为: {isCorrect}"); // 由于是 @bind-Checked,数据模型已经自动更新,这里只是日志 } // 计算某个学生的总分 private float GetStudentTotalScore(Guid studentId) { float totalScore = 0; foreach (var row in _questionsForTable) { if (row.StudentAnswers.TryGetValue(studentId, out bool isCorrect) && isCorrect) { totalScore += row.QuestionItem.Score; } } return totalScore; } // 切换某个学生所有题目的对错状态 (用于快速批改) private void ToggleStudentAllAnswers(Guid studentId) { bool allCorrect = _questionsForTable.All(row => row.StudentAnswers.ContainsKey(studentId) && row.StudentAnswers[studentId]); foreach (var row in _questionsForTable) { if (row.StudentAnswers.ContainsKey(studentId)) { row.StudentAnswers[studentId] = !allCorrect; // 全部取反 } } StateHasChanged(); // 手动通知 Blazor 刷新 UI } // 提交批改结果(模拟) private void SubmitGrading() { Console.WriteLine("--- 提交批改结果 ---"); foreach (var student in _students) { Console.WriteLine($"学生: {student.Name}, 总分: {GetStudentTotalScore(student.Id)}"); foreach (var row in _questionsForTable) { if (row.StudentAnswers.TryGetValue(student.Id, out bool isCorrect)) { Console.WriteLine($" - 题目 {row.QuestionItem.Sequence}: {(isCorrect ? "正确" : "错误")}"); } } } Snackbar?.Add("批改结果已提交(模拟)", Severity.Success); // 实际应用中,这里会将 _questionsForTable 和 _students 的数据发送到后端API } }