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
}
}