using AutoMapper; using Entities.Contracts; using Entities.DTO; using Microsoft.EntityFrameworkCore; using Microsoft.VisualBasic; using SharedDATA.Api; using System.Linq; using TechHelper.Context; using TechHelper.Server.Repositories; using TechHelper.Services.Beta; using static TechHelper.Services.Beta.IExamService; namespace TechHelper.Services.Beta { public class ExamService : IExamService { private readonly IUnitOfWork _unitOfWork; private readonly ISubmissionService _submissionService; private readonly IClassService _classService; private readonly IMapper _mapper; public ExamService(IUnitOfWork unitOfWork, IMapper mapper, IClassService classService, ISubmissionService submissionService) { _unitOfWork = unitOfWork; _mapper = mapper; _classService = classService; _submissionService = submissionService; } public async Task CreateExamAsync(ExamDto ExamDto) { try { Exam newAssi = _mapper.Map(ExamDto); //var context = _unitOfWork.GetDbContext(); //foreach (var entry in context.ChangeTracker.Entries()) //{ // if (entry.State == Microsoft.EntityFrameworkCore.EntityState.Added) // { // if (entry.Entity is Question newQues) // { // newQues.CreatorId = newAssi.CreatorId; // } // } //} if (await _unitOfWork.SaveChangesAsync() > 0) { return ApiResponse.Success(); } return ApiResponse.Error("保存失败"); } catch (Exception ex) { return ApiResponse.Error(ex.Message); } } public async Task GetAllAsync(QueryParameter query) { try { var repository = _unitOfWork.GetRepository(); if (query.Search != null && !string.IsNullOrWhiteSpace(query.Search)) { var examQuestions = await repository.GetPagedListAsync( predicate: eq => eq.Title.Contains(query.Search), pageSize: query.PageSize, pageIndex: query.PageIndex ); var examQuestionDtosFiltered = _mapper.Map>(examQuestions.Items); return new ApiResponse(true, examQuestionDtosFiltered); } else { var examQuestions = await repository.GetPagedListAsync( pageSize: query.PageSize, pageIndex: query.PageIndex ); var examQuestionDtos = _mapper.Map>(examQuestions.Items); return new ApiResponse(true, examQuestionDtos); } } catch (Exception ex) { return new ApiResponse($"获取所有考试题目时发生错误: {ex.Message}"); } } public async Task GetAsync(Guid id) { try { var assignment = await _unitOfWork.GetRepository().GetFirstOrDefaultAsync(predicate: a => a.Id == id); if (assignment == null) { return ApiResponse.Error("获取失败"); } var result = _mapper.Map(assignment); return ApiResponse.Success(result: result); } catch (Exception ex) { return ApiResponse.Error(ex.Message); } } public async Task AddAsync(ExamDto model) { try { var exam = _mapper.Map(model); await _unitOfWork.GetRepository().InsertAsync(exam); if (await _unitOfWork.SaveChangesAsync() > 0) { return ApiResponse.Success("创建成功", exam.Id); } return ApiResponse.Error("创建失败"); } catch (Exception ex) { return ApiResponse.Error(ex.Message); } } public async Task UpdateAsync(ExamDto model) { try { var existingExam = await _unitOfWork.GetRepository().GetFirstOrDefaultAsync(predicate: a => a.Id == model.Id); if (existingExam == null) return ApiResponse.Error("找不到该试卷"); _mapper.Map(model, existingExam); _unitOfWork.GetRepository().Update(existingExam); if (await _unitOfWork.SaveChangesAsync() > 0) { return ApiResponse.Success("更新成功"); } return ApiResponse.Error("更新失败"); } catch (Exception ex) { return ApiResponse.Error(ex.Message); } } public async Task DeleteAsync(Guid id) { try { var assignment = await _unitOfWork.GetRepository().GetFirstOrDefaultAsync(predicate: a => a.Id == id); if (assignment == null) return ApiResponse.Error("找不到该试卷"); _unitOfWork.GetRepository().Delete(id); _unitOfWork.GetRepository().Delete(assignment.ExamStructId); if (await _unitOfWork.SaveChangesAsync() > 0) { return ApiResponse.Success(); } return ApiResponse.Error("删除失败"); } catch (Exception ex) { return ApiResponse.Error($"内部问题,{ex.Message}, InerException{ex.InnerException}"); } } public async Task AssignmentToAllClassesAsync(AssigExamToClassDto examToClassDto, Guid TeacherId) { try { var result = await _classService.GetUserInjoinedClasses(TeacherId); if (result.Status == false) return ApiResponse.Error(result.Message); var userClass = result.Result as UserClassDetailInfoDto; if (userClass == null || !userClass.UserClassInfos.Any()) return ApiResponse.Error("教师没有管理任何班级"); var assignment = await _unitOfWork.GetRepository().GetFirstOrDefaultAsync(predicate: a => a.Id == examToClassDto.examId); if (assignment == null) return ApiResponse.Error("没有找到该试卷"); foreach (var classId in userClass.UserClassInfos) { await AssignmentToClassAsync(TeacherId, examToClassDto.examId, classId.Id); } if (await _unitOfWork.SaveChangesAsync() > 0) { return ApiResponse.Success("分配成功"); } return ApiResponse.Error("分配失败"); } catch (Exception ex) { return ApiResponse.Error($"内部错误, {ex.Message}"); } } public async Task AssignmentToStudentsAsync(AssigExamToStudentsDto examToStudentsDto) { try { var assignment = await _unitOfWork.GetRepository().GetFirstOrDefaultAsync(predicate: a => a.Id == examToStudentsDto.ExamId); if (assignment == null) { return ApiResponse.Error("获取失败"); } if (assignment == null) return ApiResponse.Error("没有找到该试卷"); if (examToStudentsDto.StudentIds == null || !examToStudentsDto.StudentIds.Any()) { return ApiResponse.Error("没有选择学生"); } foreach (var studentId in examToStudentsDto.StudentIds) { var subCount = await _unitOfWork.GetRepository().GetAll( predicate: su => su.ExamId == examToStudentsDto.ExamId && su.StudentId == studentId ).CountAsync(); var submission = assignment.ConvertToSubmission(studentId, examToStudentsDto.CreaterId, examToStudentsDto.ClassId); submission.AttemptNumber = (byte)(subCount + 1); await _unitOfWork.GetRepository().InsertAsync(submission); } if (await _unitOfWork.SaveChangesAsync() > 0) { return ApiResponse.Success(); } return ApiResponse.Error(); } catch (Exception ex) { return ApiResponse.Error($"内部错误, {ex.Message}"); } } public async Task AssignmentToClassAsync(Guid TeacherId, Guid examId, Guid classId) { try { var classStudents = await _classService.GetClassStudentsAsync(classId); if (!classStudents.Status) return ApiResponse.Error(classStudents.Message); var userlist = classStudents.Result as IEnumerable; if (userlist == null || !userlist.Any()) return ApiResponse.Error("班级没有学生"); var assignment = await _unitOfWork.GetRepository().GetFirstOrDefaultAsync(predicate: a => a.Id == examId); if (assignment == null) return ApiResponse.Error("没有找到该试卷"); foreach (var student in userlist) { var subCount = await _unitOfWork.GetRepository().GetAll( predicate: su => su.ExamId == examId && su.StudentId == student.Id ).CountAsync(); var submission = assignment.ConvertToSubmission(student.Id, TeacherId, classId); submission.AttemptNumber = (byte)(subCount + 1); await _unitOfWork.GetRepository().InsertAsync(submission); } if (await _unitOfWork.SaveChangesAsync() > 0) { return ApiResponse.Success("创建成功"); } return ApiResponse.Error("创建失败"); } catch (Exception ex) { return ApiResponse.Error($"内部错误, {ex.Message}"); } } public async Task GetExamSubmissionDetailInClassAsync(AssigExamToClassDto examToClassDto) { try { var submissions = await _unitOfWork.GetRepository().GetAllAsync(predicate: s => s.ExamId == examToClassDto.examId && s.ClassId == examToClassDto.classId); if (submissions == null || !submissions.Any()) return ApiResponse.Error("没有找到该试卷"); var result = _mapper.Map>(submissions); return ApiResponse.Success(result: result); } catch (Exception ex) { return ApiResponse.Error($"内部错误, {ex.Message}"); } } public async Task GetExamTotalErrorDistributionInClassAsync(AssigExamToClassDto examToClassDto) { try { var submissions = await _unitOfWork.GetRepository(). GetAllAsync(predicate: s => s.ExamId == examToClassDto.examId && s.ClassId == examToClassDto.classId); if (submissions == null || !submissions.Any()) return ApiResponse.Error("没有找到该试卷"); var errorTypeDistribution = submissions .SelectMany(s => s.SubmissionDetails) .Where(d => d.IsCorrect == false) .GroupBy(d => d.ExamQuestion.Type.Name) .ToDictionary(g => g.Key, g => g.Count()); var errorLessonDistribution = submissions .SelectMany(s => s.SubmissionDetails) .Where(d => d.IsCorrect == false) .Where(d => d.ExamQuestion?.Question?.Lesson?.Title != null) .GroupBy(d => d.ExamQuestion.Question?.Lesson?.Title) .ToDictionary(g => g.Key, g => g.Count()); var scores = submissions.Select(s => s.OverallGrade); var result = new ExamDistributionDto(errorTypeDistribution, errorLessonDistribution, scores); return ApiResponse.Success(result: result); } catch (Exception ex) { return ApiResponse.Error($"内部错误, {ex.Message}"); } } } }