using AutoMapper; using Entities.Contracts; using Entities.DTO; using Microsoft.EntityFrameworkCore; using SharedDATA.Api; using SharedDATA.Context; using TechHelper.Services.Beta; namespace TechHelper.Services.Beta { /// /// 提交服务实现(Beta版本) /// 实现提交相关的业务逻辑操作 /// public class SubmissionService : ISubmissionService { private readonly IUnitOfWork _unitOfWork; private readonly IMapper _mapper; private readonly IRepository _submissionRepository; private readonly IRepository _submissionDetailRepository; /// /// 初始化提交服务 /// /// AutoMapper实例 /// 工作单元 public SubmissionService(IMapper mapper, IUnitOfWork unitOfWork) { _mapper = mapper; _unitOfWork = unitOfWork; _submissionRepository = _unitOfWork.GetRepository(); _submissionDetailRepository = _unitOfWork.GetRepository(); } #region 基本CRUD操作 /// /// 获取所有提交记录 /// /// 查询参数 /// 提交记录列表 public async Task GetAllAsync(QueryParameter query) { try { var pagedSubmissions = await _submissionRepository.GetPagedListAsync( pageIndex: query.PageIndex, pageSize: query.PageSize, orderBy: s => s.OrderByDescending(s => s.SubmissionTime), predicate: s => !s.IsDeleted); var submissionDtos = _mapper.Map>(pagedSubmissions.Items); return ApiResponse.Success("获取所有提交成功。", submissionDtos); } catch (Exception ex) { return ApiResponse.Error($"获取所有提交失败: {ex.Message}"); } } /// /// 根据ID获取提交记录 /// /// 提交ID /// 提交记录详情 public async Task GetAsync(Guid id) { try { var submission = await _submissionRepository.GetFirstOrDefaultAsync( predicate: s => s.Id == id && !s.IsDeleted); if (submission == null) { return ApiResponse.Error("未找到提交记录。", 404); } var submissionDto = _mapper.Map(submission); return ApiResponse.Success("获取提交记录成功。", submissionDto); } catch (Exception ex) { return ApiResponse.Error($"获取提交记录失败: {ex.Message}"); } } /// /// 创建提交记录 /// /// 提交数据传输对象 /// 创建结果 public async Task AddAsync(SubmissionDto model) { try { var submission = _mapper.Map(model); submission.SubmissionTime = DateTime.Now; submission.IsDeleted = false; await _submissionRepository.InsertAsync(submission); await _unitOfWork.SaveChangesAsync(); var result = _mapper.Map(submission); return ApiResponse.Success("提交成功。", result); } catch (Exception ex) { return ApiResponse.Error($"创建提交失败: {ex.Message}"); } } /// /// 更新提交记录 /// /// 提交数据传输对象 /// 更新结果 public async Task UpdateAsync(SubmissionDto model) { try { var existingSubmission = await _submissionRepository.GetFirstOrDefaultAsync(predicate: s => s.Id == model.Id && !s.IsDeleted); if (existingSubmission == null) { return ApiResponse.Error("未找到要更新的提交记录。", 404); } _mapper.Map(model, existingSubmission); _submissionRepository.Update(existingSubmission); await _unitOfWork.SaveChangesAsync(); var result = _mapper.Map(existingSubmission); return ApiResponse.Success("更新提交记录成功。", result); } catch (Exception ex) { return ApiResponse.Error($"更新提交记录失败: {ex.Message}"); } } /// /// 删除提交记录 /// /// 提交ID /// 删除结果 public async Task DeleteAsync(Guid id) { try { var submission = await _submissionRepository.GetFirstOrDefaultAsync(predicate: s => s.Id == id && !s.IsDeleted); if (submission == null) { return ApiResponse.Error("未找到要删除的提交记录。", 404); } submission.IsDeleted = true; _submissionRepository.Update(submission); var submissionDetails = await _submissionDetailRepository.GetPagedListAsync(predicate: sd => sd.SubmissionId == id); foreach (var detail in submissionDetails.Items) { detail.IsDeleted = true; _submissionDetailRepository.Update(detail); } await _unitOfWork.SaveChangesAsync(); return ApiResponse.Success("提交记录及相关详情删除成功。", null); } catch (Exception ex) { return ApiResponse.Error($"删除提交记录失败: {ex.Message}"); } } #endregion #region 错题相关操作 /// /// 获取用户的错题列表 /// /// 用户ID /// 错题列表 public async Task GetAllErrorQuestionsAsync(Guid userId) { try { var errorSDs = await _submissionDetailRepository.GetPagedListAsync( predicate: sd => sd.StudentId == userId && sd.IsCorrect == false, include: i => i .Include(s => s.ExamQuestion) .ThenInclude(aq => aq.Question)); var errorQuestions = errorSDs.Items.Select(sd => sd.ExamQuestion.Question) .Where(q => q != null) .DistinctBy(q => q.Id) .ToList(); var result = _mapper.Map>(errorQuestions); return ApiResponse.Success("获取所有错题成功。", result); } catch (Exception ex) { return ApiResponse.Error($"获取所有错题失败: {ex.Message}"); } } /// /// 获取指定作业的错题列表 /// /// 作业ID /// 用户ID /// 错题列表 public async Task GetAssignmentErrorQuestionsAsync(Guid assignmentId, Guid userId) { try { var errorSDs = await _submissionDetailRepository.GetPagedListAsync( predicate: sd => sd.Submission.ExamId == assignmentId && sd.StudentId == userId && sd.IsCorrect == false, include: i => i .Include(s => s.ExamQuestion) .ThenInclude(aq => aq.Question)); var errorQuestions = errorSDs.Items.Select(sd => sd.ExamQuestion.Question) .Where(q => q != null) .DistinctBy(q => q.Id) .ToList(); var result = _mapper.Map>(errorQuestions); return ApiResponse.Success("获取指定作业错题成功。", result); } catch (Exception ex) { return ApiResponse.Error($"获取指定作业错题失败: {ex.Message}"); } } /// /// 获取错题类型分布 /// /// 作业ID /// 用户ID /// 错题类型分布 public async Task GetAssignmentErrorQuestionTypeDisAsync(Guid assignmentId, Guid userId) { try { var errorSDs = await _submissionDetailRepository.GetPagedListAsync( predicate: sd => sd.Submission.ExamId == assignmentId && sd.StudentId == userId && sd.IsCorrect == false, include: i => i .Include(s => s.ExamQuestion) .ThenInclude(aq => aq.Question)); var errorTypeDistribution = errorSDs.Items .Where(sd => sd.ExamQuestion?.Question?.QuestionType != null) .GroupBy(sd => sd.ExamQuestion.Question.QuestionType.Name) .Select(g => new { QuestionType = g.Key.ToString(), Count = g.Count() }) .ToList(); return ApiResponse.Success("获取指定作业错题类型分布成功。", errorTypeDistribution); } catch (Exception ex) { return ApiResponse.Error($"获取指定作业错题类型分布失败: {ex.Message}"); } } /// /// 获取所有错题类型分布 /// /// 作业ID /// 用户ID /// 错题类型分布 public async Task GetAllErrorQuestionTypeDisAsync(Guid assignmentId, Guid userId) { try { var errorSDs = await _submissionDetailRepository.GetPagedListAsync( predicate: sd => sd.Submission.ExamId == assignmentId && sd.StudentId == userId && sd.IsCorrect == false, include: i => i .Include(s => s.ExamQuestion) .ThenInclude(aq => aq.Question)); var errorTypeDistribution = errorSDs.Items .Where(sd => sd.ExamQuestion?.Question?.QuestionType != null) .GroupBy(sd => sd.ExamQuestion.Question.QuestionType.Name) .Select(g => new { QuestionType = g.Key.ToString(), Count = g.Count() }) .ToList(); return ApiResponse.Success("获取错题类型分布成功。", errorTypeDistribution); } catch (Exception ex) { return ApiResponse.Error($"获取错题类型分布失败: {ex.Message}"); } } /// /// 获取作业中所有学生的错题情况 /// /// 作业ID /// 教师ID /// 学生错题情况 public async Task GetAssignmentAllStudentsError(Guid assignmentId, Guid teacherId) { try { var submissionDetails = await _submissionDetailRepository.GetPagedListAsync( predicate: sd => sd.Submission.ExamId == assignmentId && sd.IsCorrect == false, include: i => i.Include(sd => sd.Student)); var studentsErrorSummary = submissionDetails.Items .Where(sd => sd.Student != null) .GroupBy(sd => new { sd.StudentId, sd.Student.UserName }) .Select(g => new { StudentId = g.Key.StudentId, StudentName = g.Key.UserName, ErrorQuestionCount = g.Count() }) .ToList(); return ApiResponse.Success("获取作业中所有学生的错题情况成功。", studentsErrorSummary); } catch (Exception ex) { return ApiResponse.Error($"获取作业中所有学生的错题情况失败: {ex.Message}"); } } /// /// 获取出现错题的学生列表 /// /// 作业题目ID /// 错题学生列表 public async Task GetQuestionErrorStudents(Guid assignmentQuestionId) { try { var errorSubmissionDetails = await _submissionDetailRepository.GetPagedListAsync( predicate: sd => sd.ExamQuestionId == assignmentQuestionId && sd.IsCorrect == false, include: i => i .Include(sd => sd.Student) .Include(sd => sd.ExamQuestion) .ThenInclude(aq => aq.Question)); var errorStudentsByQuestion = errorSubmissionDetails.Items .Where(sd => sd.ExamQuestion?.Question != null && sd.Student != null) .GroupBy(sd => new { sd.ExamQuestionId, sd.ExamQuestion.Question.Title }) .Select(g => new { AssignmentQuestionId = g.Key.ExamQuestionId, QuestionTitle = g.Key.Title, ErrorStudents = g.Select(sd => new { StudentId = sd.StudentId, StudentName = sd.Student.UserName }).Distinct().ToList() }) .ToList(); return ApiResponse.Success("获取出现错题的学生成功。", errorStudentsByQuestion); } catch (Exception ex) { return ApiResponse.Error($"获取出现错题的学生失败: {ex.Message}"); } } #endregion #region 特殊操作 /// /// 判断是否已经存在提交记录 /// /// 作业ID /// 学生ID /// 提交记录数量 public async Task IsHasSubmissionAsync(Guid assignmentId, Guid studentId) { try { var result = await _unitOfWork.GetRepository().GetAllAsync(predicate: s => s.ExamId == assignmentId && s.StudentId == studentId); return (byte)result.Count; } catch (Exception ex) { throw; } } /// /// 获取学生提交摘要 /// /// 用户ID /// 学生提交摘要列表 public async Task GetStudentSubmissionSummariesAsync(Guid userId) { try { var submissions = await _submissionRepository.GetPagedListAsync( predicate: s => s.StudentId == userId && !s.IsDeleted, orderBy: s => s.OrderByDescending(s => s.SubmissionTime)); var summaries = submissions.Items.Select(s => new StudentSubmissionSummaryDto { Id = s.Id, AssignmentName = s.Exam?.Title ?? "未知作业", CreatedDate = s.SubmissionTime, Score = s.OverallGrade, StudentName = s.Student?.UserName ?? "未知学生", Status = s.Status.GetDisplayName() }).ToList(); return ApiResponse.Success("获取学生提交摘要成功。", new StudentSubmissionSummaryResponseDto { Submissions = summaries, TotalCount = submissions.TotalCount }); } catch (Exception ex) { return ApiResponse.Error($"获取学生提交摘要失败: {ex.Message}"); } } /// /// 获取学生提交详情 /// /// 提交ID /// 学生提交详情 public async Task GetStudentSubmissionDetailAsync(Guid submissionId) { try { var submission = await _submissionRepository.GetFirstOrDefaultAsync( predicate: s => s.Id == submissionId && !s.IsDeleted); if (submission == null) { return ApiResponse.Error("未找到提交记录。", 404); } var detail = _mapper.Map(submission); return ApiResponse.Success("获取学生提交详情成功。", detail); } catch (Exception ex) { return ApiResponse.Error($"获取学生提交详情失败: {ex.Message}"); } } public async Task GradeExam(SubmissionTeacherUpdateDto model) { try { var existingSubmission = await _submissionRepository.GetFirstOrDefaultAsync(predicate: s => s.Id == model.Id && !s.IsDeleted); if (existingSubmission == null) { return ApiResponse.Error("未找到要批改的试卷记录。", 404); } _mapper.Map(model, existingSubmission); foreach (var item in existingSubmission.SubmissionDetails) { var sdd = model.SubmissionUpdateDetails.FirstOrDefault(d => d.Id == item.Id); if (sdd == null) continue; _mapper.Map(sdd, item); } _submissionRepository.Update(existingSubmission); await _unitOfWork.SaveChangesAsync(); var result = _mapper.Map(existingSubmission); return ApiResponse.Success("批改试卷记录成功。", result); } catch (Exception ex) { return ApiResponse.Error($"批改试卷记录失败: {ex.Message}"); } } #endregion } }