Files
TechHelper/TechHelper.Server/Services/Submission/SubmissionDetailService.cs
SpecialX ac900159ba
Some checks failed
TechAct / explore-gitea-actions (push) Failing after 12s
重构项目结构,移除Assignment相关功能,优化Submission模块
2025-10-09 18:57:28 +08:00

458 lines
18 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using AutoMapper;
using Entities.Contracts;
using Entities.DTO;
using Microsoft.EntityFrameworkCore;
using SharedDATA.Api;
using SharedDATA.Context;
using TechHelper.Services;
namespace TechHelper.Services.Beta
{
/// <summary>
/// 提交详情服务实现Beta版本
/// 实现提交详情相关的业务逻辑操作
/// </summary>
public class SubmissionDetailService : ISubmissionDetailService
{
private readonly IUnitOfWork _unitOfWork;
private readonly IMapper _mapper;
private readonly IRepository<SubmissionDetail> _submissionDetailRepository;
private readonly IRepository<Submission> _submissionRepository;
/// <summary>
/// 初始化提交详情服务
/// </summary>
/// <param name="mapper">AutoMapper实例</param>
/// <param name="unitOfWork">工作单元</param>
public SubmissionDetailService(IMapper mapper, IUnitOfWork unitOfWork)
{
_mapper = mapper;
_unitOfWork = unitOfWork;
_submissionDetailRepository = _unitOfWork.GetRepository<SubmissionDetail>();
_submissionRepository = _unitOfWork.GetRepository<Submission>();
}
#region CRUD操作
/// <summary>
/// 获取所有提交详情
/// </summary>
/// <param name="query">查询参数</param>
/// <returns>提交详情列表</returns>
public async Task<ApiResponse> GetAllAsync(QueryParameter query)
{
try
{
var pagedDetails = await _submissionDetailRepository.GetPagedListAsync(
pageIndex: query.PageIndex,
pageSize: query.PageSize,
orderBy: sd => sd.OrderByDescending(sd => sd.CreatedAt),
predicate: sd => !sd.IsDeleted,
include: i => i.Include(sd => sd.Student)
.Include(sd => sd.ExamQuestion)
.ThenInclude(aq => aq.Question));
var detailDtos = _mapper.Map<List<SubmissionDetailDto>>(pagedDetails.Items);
return ApiResponse.Success("获取所有提交详情成功。", new PagedList<SubmissionDetailDto>
{
PageIndex = pagedDetails.PageIndex,
PageSize = pagedDetails.PageSize,
TotalCount = pagedDetails.TotalCount,
TotalPages = pagedDetails.TotalPages,
Items = detailDtos
});
}
catch (Exception ex)
{
return ApiResponse.Error($"获取所有提交详情失败: {ex.Message}");
}
}
/// <summary>
/// 根据ID获取提交详情
/// </summary>
/// <param name="id">提交详情ID</param>
/// <returns>提交详情详情</returns>
public async Task<ApiResponse> GetAsync(Guid id)
{
try
{
var detail = await _submissionDetailRepository.GetFirstOrDefaultAsync(
predicate: sd => sd.Id == id && !sd.IsDeleted,
include: i => i.Include(sd => sd.Student)
.Include(sd => sd.ExamQuestion)
.ThenInclude(aq => aq.Question));
if (detail == null)
{
return ApiResponse.Error("未找到提交详情。", 404);
}
var detailDto = _mapper.Map<SubmissionDetailDto>(detail);
return ApiResponse.Success("获取提交详情成功。", detailDto);
}
catch (Exception ex)
{
return ApiResponse.Error($"获取提交详情失败: {ex.Message}");
}
}
/// <summary>
/// 创建提交详情
/// </summary>
/// <param name="model">提交详情数据传输对象</param>
/// <returns>创建结果</returns>
public async Task<ApiResponse> AddAsync(SubmissionDetailDto model)
{
try
{
if(await _unitOfWork.GetRepository<SubmissionDetail>().GetFirstOrDefaultAsync(predicate: sd => sd.Id == model.Id ) != null)
{
return ApiResponse.Error("提交详情已存在。", 400);
}
var detail = _mapper.Map<SubmissionDetail>(model);
detail.CreatedAt = DateTime.Now;
detail.UpdatedAt = DateTime.Now;
detail.IsDeleted = false;
await _submissionDetailRepository.InsertAsync(detail);
await _unitOfWork.SaveChangesAsync();
var result = _mapper.Map<SubmissionDetailDto>(detail);
return ApiResponse.Success("创建提交详情成功。", result);
}
catch (Exception ex)
{
return ApiResponse.Error($"创建提交详情失败: {ex.Message}");
}
}
/// <summary>
/// 更新提交详情
/// </summary>
/// <param name="model">提交详情数据传输对象</param>
/// <returns>更新结果</returns>
public async Task<ApiResponse> UpdateAsync(SubmissionDetailDto model)
{
try
{
var existingDetail = await _submissionDetailRepository.GetFirstOrDefaultAsync(predicate: sd => sd.Id == model.Id && !sd.IsDeleted);
if (existingDetail == null)
{
return ApiResponse.Error("未找到要更新的提交详情。", 404);
}
_mapper.Map(model, existingDetail);
existingDetail.UpdatedAt = DateTime.Now;
_submissionDetailRepository.Update(existingDetail);
await _unitOfWork.SaveChangesAsync();
var result = _mapper.Map<SubmissionDetailDto>(existingDetail);
return ApiResponse.Success("更新提交详情成功。", result);
}
catch (Exception ex)
{
return ApiResponse.Error($"更新提交详情失败: {ex.Message}");
}
}
/// <summary>
/// 删除提交详情
/// </summary>
/// <param name="id">提交详情ID</param>
/// <returns>删除结果</returns>
public async Task<ApiResponse> DeleteAsync(Guid id)
{
try
{
var detail = await _submissionDetailRepository.GetFirstOrDefaultAsync(predicate: sd => sd.Id == id && !sd.IsDeleted);
if (detail == null)
{
return ApiResponse.Error("未找到要删除的提交详情。", 404);
}
detail.IsDeleted = true;
_submissionDetailRepository.Update(detail);
await _unitOfWork.SaveChangesAsync();
return ApiResponse.Success("删除提交详情成功。", null);
}
catch (Exception ex)
{
return ApiResponse.Error($"删除提交详情失败: {ex.Message}");
}
}
#endregion
#region
/// <summary>
/// 获取提交详情列表
/// </summary>
/// <param name="submissionId">提交ID</param>
/// <returns>提交详情列表</returns>
public async Task<ApiResponse> GetBySubmissionIdAsync(Guid submissionId)
{
try
{
var details = await _submissionDetailRepository.GetPagedListAsync(
predicate: sd => sd.SubmissionId == submissionId && !sd.IsDeleted,
include: i => i.Include(sd => sd.Student)
.Include(sd => sd.ExamQuestion)
.ThenInclude(aq => aq.Question));
var detailDtos = _mapper.Map<List<SubmissionDetailDto>>(details.Items);
return ApiResponse.Success("获取提交详情列表成功。", detailDtos);
}
catch (Exception ex)
{
return ApiResponse.Error($"获取提交详情列表失败: {ex.Message}");
}
}
/// <summary>
/// 获取学生的提交详情
/// </summary>
/// <param name="studentId">学生ID</param>
/// <param name="examId">考试ID</param>
/// <returns>提交详情列表</returns>
public async Task<ApiResponse> GetByStudentAndExamAsync(Guid studentId, Guid examId)
{
try
{
var details = await _submissionDetailRepository.GetPagedListAsync(
predicate: sd => sd.StudentId == studentId &&
sd.Submission.ExamId == examId &&
!sd.IsDeleted,
include: i => i.Include(sd => sd.ExamQuestion)
.ThenInclude(aq => aq.Question));
var detailDtos = _mapper.Map<List<SubmissionDetailDto>>(details.Items);
return ApiResponse.Success("获取学生提交详情成功。", detailDtos);
}
catch (Exception ex)
{
return ApiResponse.Error($"获取学生提交详情失败: {ex.Message}");
}
}
/// <summary>
/// 批量创建提交详情
/// </summary>
/// <param name="submissionId">提交ID</param>
/// <param name="details">提交详情列表</param>
/// <returns>创建结果</returns>
public async Task<ApiResponse> BatchCreateAsync(Guid submissionId, List<SubmissionDetailDto> details)
{
try
{
var detailEntities = _mapper.Map<List<SubmissionDetail>>(details);
foreach (var detail in detailEntities)
{
detail.SubmissionId = submissionId;
detail.CreatedAt = DateTime.Now;
detail.UpdatedAt = DateTime.Now;
detail.IsDeleted = false;
await _submissionDetailRepository.InsertAsync(detail);
}
await _unitOfWork.SaveChangesAsync();
var result = _mapper.Map<List<SubmissionDetailDto>>(detailEntities);
return ApiResponse.Success("批量创建提交详情成功。", result);
}
catch (Exception ex)
{
return ApiResponse.Error($"批量创建提交详情失败: {ex.Message}");
}
}
/// <summary>
/// 批量更新提交详情
/// </summary>
/// <param name="details">提交详情列表</param>
/// <returns>更新结果</returns>
public async Task<ApiResponse> BatchUpdateAsync(List<SubmissionDetailDto> details)
{
try
{
var detailIds = details.Select(d => d.Id).ToList();
var existingDetails = await _submissionDetailRepository.GetAllAsync(
predicate: sd => detailIds.Contains(sd.Id) && !sd.IsDeleted);
foreach (var detail in details)
{
var existingDetail = existingDetails.FirstOrDefault(sd => sd.Id == detail.Id);
if (existingDetail != null)
{
_mapper.Map(detail, existingDetail);
existingDetail.UpdatedAt = DateTime.Now;
_submissionDetailRepository.Update(existingDetail);
}
}
await _unitOfWork.SaveChangesAsync();
return ApiResponse.Success("批量更新提交详情成功。", null);
}
catch (Exception ex)
{
return ApiResponse.Error($"批量更新提交详情失败: {ex.Message}");
}
}
/// <summary>
/// 更新提交详情评分
/// </summary>
/// <param name="detailId">提交详情ID</param>
/// <param name="points">分数</param>
/// <param name="feedback">反馈</param>
/// <returns>更新结果</returns>
public async Task<ApiResponse> UpdateScoreAsync(Guid detailId, float? points, string? feedback)
{
try
{
var detail = await _submissionDetailRepository.GetFirstOrDefaultAsync(
predicate: sd => sd.Id == detailId && !sd.IsDeleted);
if (detail == null)
{
return ApiResponse.Error("未找到提交详情。", 404);
}
detail.PointsAwarded = points;
detail.TeacherFeedback = feedback;
detail.UpdatedAt = DateTime.Now;
_submissionDetailRepository.Update(detail);
await _unitOfWork.SaveChangesAsync();
var result = _mapper.Map<SubmissionDetailDto>(detail);
return ApiResponse.Success("更新评分成功。", result);
}
catch (Exception ex)
{
return ApiResponse.Error($"更新评分失败: {ex.Message}");
}
}
/// <summary>
/// 获取错题详情
/// </summary>
/// <param name="studentId">学生ID</param>
/// <param name="examId">考试ID</param>
/// <returns>错题详情列表</returns>
public async Task<ApiResponse> GetErrorDetailsAsync(Guid studentId, Guid examId)
{
try
{
var details = await _submissionDetailRepository.GetPagedListAsync(
predicate: sd => sd.StudentId == studentId &&
sd.Submission.ExamId == examId &&
sd.IsCorrect == false &&
!sd.IsDeleted,
include: i => i.Include(sd => sd.ExamQuestion)
.ThenInclude(aq => aq.Question));
var detailDtos = _mapper.Map<List<SubmissionDetailDto>>(details.Items);
return ApiResponse.Success("获取错题详情成功。", detailDtos);
}
catch (Exception ex)
{
return ApiResponse.Error($"获取错题详情失败: {ex.Message}");
}
}
/// <summary>
/// 获取正确题详情
/// </summary>
/// <param name="studentId">学生ID</param>
/// <param name="examId">考试ID</param>
/// <returns>正确题详情列表</returns>
public async Task<ApiResponse> GetCorrectDetailsAsync(Guid studentId, Guid examId)
{
try
{
var details = await _submissionDetailRepository.GetPagedListAsync(
predicate: sd => sd.StudentId == studentId &&
sd.Submission.ExamId == examId &&
sd.IsCorrect == true &&
!sd.IsDeleted,
include: i => i.Include(sd => sd.ExamQuestion)
.ThenInclude(aq => aq.Question));
var detailDtos = _mapper.Map<List<SubmissionDetailDto>>(details.Items);
return ApiResponse.Success("获取正确题详情成功。", detailDtos);
}
catch (Exception ex)
{
return ApiResponse.Error($"获取正确题详情失败: {ex.Message}");
}
}
/// <summary>
/// 获取未批改的提交详情
/// </summary>
/// <param name="teacherId">教师ID</param>
/// <returns>未批改的提交详情列表</returns>
public async Task<ApiResponse> GetUngradedDetailsAsync(Guid teacherId)
{
try
{
var submissions = await _submissionRepository.GetPagedListAsync(
predicate: s => s.GraderId == teacherId &&
s.Status == SubmissionStatus.Submitted &&
!s.IsDeleted);
var submissionIds = submissions.Items.Select(s => s.Id).ToList();
var details = await _submissionDetailRepository.GetPagedListAsync(
predicate: sd => submissionIds.Contains(sd.SubmissionId) &&
sd.PointsAwarded == null &&
!sd.IsDeleted,
include: i => i.Include(sd => sd.Student)
.Include(sd => sd.ExamQuestion)
.ThenInclude(aq => aq.Question));
var detailDtos = _mapper.Map<List<SubmissionDetailDto>>(details.Items);
return ApiResponse.Success("获取未批改的提交详情成功。", detailDtos);
}
catch (Exception ex)
{
return ApiResponse.Error($"获取未批改的提交详情失败: {ex.Message}");
}
}
/// <summary>
/// 批量更新提交详情状态
/// </summary>
/// <param name="submissionId">提交ID</param>
/// <param name="status">状态</param>
/// <returns>更新结果</returns>
public async Task<ApiResponse> UpdateStatusAsync(Guid submissionId, SubmissionStatus status)
{
try
{
var details = await _submissionDetailRepository.GetAllAsync(
predicate: sd => sd.SubmissionId == submissionId && !sd.IsDeleted);
foreach (var detail in details)
{
detail.UpdatedAt = DateTime.Now;
_submissionDetailRepository.Update(detail);
}
await _unitOfWork.SaveChangesAsync();
return ApiResponse.Success("批量更新状态成功。", null);
}
catch (Exception ex)
{
return ApiResponse.Error($"批量更新状态失败: {ex.Message}");
}
}
#endregion
}
}