|
@@ -42,6 +42,10 @@ using DocumentFormat.OpenXml.Office2013.Excel;
|
|
|
using Hotline.Share.Enums.Exams;
|
|
|
using DocumentFormat.OpenXml.Wordprocessing;
|
|
|
using Hotline.Repository.SqlSugar.Exam.Repositories.ExamManages;
|
|
|
+using Hotline.Exams.Questions;
|
|
|
+using Hotline.Exams.Sourcewares;
|
|
|
+using Hotline.Share.Dtos.Questions;
|
|
|
+using DocumentFormat.OpenXml.Office2010.Excel;
|
|
|
|
|
|
namespace Hotline.Application.Exam.Service.ExamManages
|
|
|
{
|
|
@@ -90,17 +94,24 @@ namespace Hotline.Application.Exam.Service.ExamManages
|
|
|
public async Task<ExamQuestionDto> GetExamQuestionDto(ExamQuestionRequest examQuestionRequest)
|
|
|
{
|
|
|
var expression = examQuestionRequest.GetExpression();
|
|
|
- var quesetion = await new ExamRepository<Exams.ExamManages.ExamQuestionBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable().Where(expression).FirstAsync();
|
|
|
+ var question = await new ExamRepository<Exams.ExamManages.ExamQuestionBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable().Where(expression).FirstAsync();
|
|
|
|
|
|
- if (quesetion != null)
|
|
|
+ if (question != null)
|
|
|
{
|
|
|
- var examQuestionDto = _mapper.Map<ExamQuestionDto>(quesetion);
|
|
|
+ var examQuestionDto = _mapper.Map<ExamQuestionDto>(question);
|
|
|
+
|
|
|
+ var questionScore = await new ExamRepository<ExamQuestionScoreBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider).GetAsync(x=>x.QuestionType == question.QuestionType && x.ExamManageId == examQuestionRequest.ExamId);
|
|
|
+
|
|
|
+ if (questionScore != null)
|
|
|
+ {
|
|
|
+ examQuestionDto.Score = questionScore.Score;
|
|
|
+ }
|
|
|
|
|
|
if (examQuestionDto.QuestionType.CheckSelectType())
|
|
|
{
|
|
|
- var questionOptions = await new ExamRepository<ExamQuestionOptionsBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable().Where(x => x.ExamQuestionId == quesetion.Id).ToListAsync();
|
|
|
+ var questionOptions = await new ExamRepository<ExamQuestionOptionsBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable().Where(x => x.ExamQuestionId == question.Id).ToListAsync();
|
|
|
|
|
|
- List<ExamUserExamItemOptions> userItemItemOptions = await GetUserExteamItemOptios(quesetion);
|
|
|
+ List<ExamUserExamItemOptions> userItemItemOptions = await GetUserExteamItemOptios(question);
|
|
|
|
|
|
if (questionOptions != null)
|
|
|
{
|
|
@@ -163,7 +174,7 @@ namespace Hotline.Application.Exam.Service.ExamManages
|
|
|
var userItemItemOptions = await userExamItemOptionsTable
|
|
|
.InnerJoin(userExamItemTable, (o, u) => o.UserExamItemId == u.Id)
|
|
|
.InnerJoin(userExamTable, (o, u, e) => u.UserExamId == e.Id)
|
|
|
- .Where((o, u, e) => u.QuestionId == quesetion.QuestionId && e.UserId == _sessionContext.UserId).
|
|
|
+ .Where((o, u, e) => u.QuestionId == quesetion.QuestionId && e.UserId == _sessionContext.UserId && e.ExamStatus == EExamStatus.Executing).
|
|
|
Select((o, u, e) => o).ToListAsync();
|
|
|
return userItemItemOptions;
|
|
|
}
|
|
@@ -320,7 +331,7 @@ namespace Hotline.Application.Exam.Service.ExamManages
|
|
|
{
|
|
|
await UpdateExamAsync(_userExamItemRepository, updateUserExamItemDto, cancellationToken);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
await CalcuteExamItemScore(_userExamItemRepository, updateUserExamItemDto, cancellationToken);
|
|
|
|
|
|
return startExamViewResponse;
|
|
@@ -344,7 +355,7 @@ namespace Hotline.Application.Exam.Service.ExamManages
|
|
|
IsJoin = false
|
|
|
};
|
|
|
|
|
|
- if (userExam.StartTime == null)
|
|
|
+ if (userExam.StartTime == null || userExam.ExamStatus == EExamStatus.Complete)
|
|
|
userExam.StartTime = DateTime.Now;
|
|
|
|
|
|
var startExamViewResponse = await CheckExamValid(userExam, cancellationToken);
|
|
@@ -365,6 +376,11 @@ namespace Hotline.Application.Exam.Service.ExamManages
|
|
|
await _repository.UpdateWithValidateAsync(userExam, cancellationToken);
|
|
|
|
|
|
}
|
|
|
+ // TODO: 删除之前选项和答案
|
|
|
+ else if(userExam.ExamStatus == EExamStatus.Complete)
|
|
|
+ {
|
|
|
+ await ReExam(userExam, cancellationToken);
|
|
|
+ }
|
|
|
var examManage = await _examManageRepository.GetAsync(x => x.Id == userExam.ExamId);
|
|
|
|
|
|
return new StartExamViewResponse
|
|
@@ -375,6 +391,29 @@ namespace Hotline.Application.Exam.Service.ExamManages
|
|
|
};
|
|
|
}
|
|
|
|
|
|
+ /// <summary>
|
|
|
+ /// 重考
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="userExam"></param>
|
|
|
+ /// <param name="cancellationToken"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ private async Task ReExam(ExamUserExam userExam, CancellationToken cancellationToken)
|
|
|
+ {
|
|
|
+ //新增重考记录
|
|
|
+ var reExamUserExam = _mapper.Map<ExamUserExam, ExamUserExam>(userExam);
|
|
|
+
|
|
|
+ reExamUserExam.IsCheck = false;
|
|
|
+ reExamUserExam.IsSubmit = false;
|
|
|
+ reExamUserExam.IsSuccess = false;
|
|
|
+ reExamUserExam.IsReExam = true;
|
|
|
+ reExamUserExam.Score = 0;
|
|
|
+ reExamUserExam.ExamStatus = EExamStatus.NoStart;
|
|
|
+
|
|
|
+ reExamUserExam.ToInsert(_sessionContext);
|
|
|
+
|
|
|
+ await _repository.AddWithValidateAsync(reExamUserExam, cancellationToken);
|
|
|
+ }
|
|
|
+
|
|
|
private async Task<StartExamViewResponse> CheckExamValid(ExamUserExam examUserExam, CancellationToken cancellationToken)
|
|
|
{
|
|
|
|
|
@@ -719,7 +758,7 @@ namespace Hotline.Application.Exam.Service.ExamManages
|
|
|
public async Task<GradingResultPageViewResponse> GetGradingResultPagedList(GradingPagedRequest gradingPagedRequest)
|
|
|
{
|
|
|
// 只要有阅卷记录就在已阅卷列表中,已阅卷和未阅卷会有重复数据,只有所有记录都已阅卷才会从未阅卷列表中排除
|
|
|
- var userExamTable = _repository.Queryable().Where(x=>x.IsSubmit);
|
|
|
+ var userExamTable = _repository.Queryable().Where(x => x.IsSubmit);
|
|
|
|
|
|
var examManageTable = new ExamRepository<ExamManage>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable();
|
|
|
|
|
@@ -1264,16 +1303,152 @@ namespace Hotline.Application.Exam.Service.ExamManages
|
|
|
Status = u.Status,
|
|
|
SortIndex = u.SortIndex,
|
|
|
ExamStatus = u.ExamStatus,
|
|
|
- IsSuccess = u.IsCheck? u.IsSuccess:null,
|
|
|
+ IsSuccess = u.IsCheck ? u.IsSuccess : null,
|
|
|
EndTime = e.EndTime,
|
|
|
StartTime = e.StartTime,
|
|
|
TimeSpan = e.TimeSpan,
|
|
|
ExamType = e.ExamType,
|
|
|
ExamId = e.Id,
|
|
|
- IsCheck = u.IsCheck
|
|
|
+ IsCheck = u.IsCheck,
|
|
|
+ IsReExam = u.IsReExam,
|
|
|
+ CanReExam = SqlFunc.Subqueryable<ExamUserExamItem>().Where(x=>x.UserExamId == u.Id).Count()< e.Count
|
|
|
});
|
|
|
return queryable;
|
|
|
}
|
|
|
+
|
|
|
+ public async Task<List<ViewExamQuestionDto>> View(string id)
|
|
|
+ {
|
|
|
+
|
|
|
+ List<ViewExamQuestionDto> viewExamQuestionDtos = await GetViewExamQuestion(id);
|
|
|
+
|
|
|
+ var questionIds = viewExamQuestionDtos.Select(x => x.QuestionId).ToList();
|
|
|
+
|
|
|
+ List<ViewQuestionAnswerDto> questionAnswers = await GetQuestionAnswers(id, questionIds);
|
|
|
+ List<ViewQuestionOptionDto> questionOptions = await GetQuestionOptions( questionIds);
|
|
|
+ List<QuestionKnowladgeDto> questionKnowladges = await GetQuestionKnowladges( questionIds);
|
|
|
+ List<QuestionSourcewareDto> sourcewares = await GetSourcewares(questionIds);
|
|
|
+
|
|
|
+ viewExamQuestionDtos.ForEach(item =>
|
|
|
+ {
|
|
|
+ item.QuestionKnowladgeDtos = questionKnowladges.Where(x => x.QuestionId == item.QuestionId).ToList();
|
|
|
+ item.QuestionSourcewareDtos = sourcewares.Where(x => x.QuestionId == item.QuestionId).ToList();
|
|
|
+ if (!item.QuestionType.CheckSelectType())
|
|
|
+ {
|
|
|
+ var questionAnswer = questionAnswers.FirstOrDefault(x => x.QuestionId == item.QuestionId);
|
|
|
+ item.Answer = questionAnswer?.Answer ?? string.Empty;
|
|
|
+ item.CorrectAnswer = questionAnswer?.CorrectAnswer ?? string.Empty;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ item.QuestionOptions = questionOptions.Where(x => x.QuestionId == item.QuestionId).ToList();
|
|
|
+ item.CorrectAnswer = string.Join(",", item.QuestionOptions.Where(x => x.IsAnswer).Select(x => x.Label));
|
|
|
+ }
|
|
|
+
|
|
|
+ });
|
|
|
+
|
|
|
+
|
|
|
+ return viewExamQuestionDtos;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ private async Task<List<QuestionSourcewareDto>> GetSourcewares(List<string> questionIds)
|
|
|
+ {
|
|
|
+ var questionSourcewareTable = new ExamRepository<ExamQuestionSourcewareBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable();
|
|
|
+ var sourcewareTable = new ExamRepository<ExamSourceware>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable();
|
|
|
+
|
|
|
+ var querable = questionSourcewareTable.InnerJoin<ExamQuestionSourceware>((qsb,qs)=>qsb.SourcewareId == qs.Id).InnerJoin(sourcewareTable, (qsb,qs, s) => qs.SourcewareId == s.Id).Select((qsb, qs, s) => new QuestionSourcewareDto
|
|
|
+ {
|
|
|
+ Id = qs.Id,
|
|
|
+ Name = s.Name,
|
|
|
+ QuestionId = qsb.ExamQuestionId,
|
|
|
+ SourcewareId = s.Id
|
|
|
+ }).MergeTable().Where(x => questionIds.Contains(x.QuestionId));
|
|
|
+
|
|
|
+ return await querable.ToListAsync();
|
|
|
+ }
|
|
|
+
|
|
|
+ private async Task<List<QuestionKnowladgeDto>> GetQuestionKnowladges(List<string> questionIds)
|
|
|
+ {
|
|
|
+ var questionKnowladgeTable = new ExamRepository<ExamQuestionKnowladgeBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable();
|
|
|
+
|
|
|
+ return await questionKnowladgeTable.Where(x => questionIds.Contains(x.ExamQuestionId)).Select(x => new QuestionKnowladgeDto
|
|
|
+ {
|
|
|
+ Id = x.Id,
|
|
|
+ QuestionId = x.ExamQuestionId,
|
|
|
+ KnowladgeId = x.KnowladgeId,
|
|
|
+ Title = x.Title
|
|
|
+ }).ToListAsync();
|
|
|
+ }
|
|
|
+
|
|
|
+ private async Task<List<ViewQuestionOptionDto>> GetQuestionOptions(List<string> questionIds)
|
|
|
+ {
|
|
|
+ var userExamItemOptionTable = _userExamItemOptionRepository.Queryable();
|
|
|
+ var questionOptionTable = new ExamRepository<ExamQuestionOptionsBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable();
|
|
|
+
|
|
|
+ var querable = questionOptionTable.Where(x => questionIds.Contains(x.ExamQuestionId))
|
|
|
+ .LeftJoin(userExamItemOptionTable, (op, uio) => op.Id == uio.QuestionOptionId)
|
|
|
+ .Select((op, uio) => new ViewQuestionOptionDto
|
|
|
+ {
|
|
|
+ Content = op.Content,
|
|
|
+ Id = op.Id,
|
|
|
+ IsAnswer = op.IsAnswer,
|
|
|
+ Label = op.Label,
|
|
|
+ QuestionId = op.ExamQuestionId,
|
|
|
+ IsSelected = uio.Id != null
|
|
|
+ }).MergeTable().OrderBy(x=>x.Label);
|
|
|
+
|
|
|
+ return await querable.Distinct()
|
|
|
+ .ToListAsync();
|
|
|
+ }
|
|
|
+
|
|
|
+ private async Task<List<ViewQuestionAnswerDto>> GetQuestionAnswers(string id, List<string> questionIds)
|
|
|
+ {
|
|
|
+ var userExamTable = _repository.Queryable().Where(x => x.Id == id);
|
|
|
+ var userExamItemTable = _userExamItemRepository.Queryable();
|
|
|
+ var examAnswerTable = _examAnswerRepository.Queryable();
|
|
|
+ var questionTable = new ExamRepository<ExamQuestionBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable();
|
|
|
+ var questionAnswerTable = new ExamRepository<ExamQuestionAnswerBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable();
|
|
|
+
|
|
|
+ var querable = examAnswerTable
|
|
|
+ .InnerJoin(userExamItemTable, (a, ui) => ui.Id == a.UserExamItemId && ui.UserExamId == id)
|
|
|
+ .LeftJoin(questionAnswerTable, (a, ui, qab) => qab.QuestionId == ui.QuestionId )
|
|
|
+ .LeftJoin<ExamQuestionAnswer>((a, ui, qab ,qa) => qab.QuestionAnswerId == qa.Id )
|
|
|
+ .LeftJoin(questionTable, (a, ui, qab, qa,q)=>qab.QuestionId == q.QuestionId && questionIds.Contains(q.Id))
|
|
|
+ .Select((a, ui, qab, qa,q) => new ViewQuestionAnswerDto
|
|
|
+ {
|
|
|
+ Answer = a.Answer,
|
|
|
+ CorrectAnswer = qa.Answer != null ? qa.Answer : string.Empty,
|
|
|
+ QuestionId = q.Id
|
|
|
+ }).MergeTable();
|
|
|
+
|
|
|
+ return await querable.ToListAsync();
|
|
|
+ }
|
|
|
+
|
|
|
+ private async Task<List<ViewExamQuestionDto>> GetViewExamQuestion(string id)
|
|
|
+ {
|
|
|
+ var userExamTable = _repository.Queryable().Where(x => x.Id == id);
|
|
|
+ var userExamItemTable = _userExamItemRepository.Queryable();
|
|
|
+ var examManageTable = _examManageRepository.Queryable();
|
|
|
+ var questionTable = new ExamRepository<ExamQuestionBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable();
|
|
|
+ var questionScoreTable = new ExamRepository<ExamQuestionScoreBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable();
|
|
|
+
|
|
|
+
|
|
|
+ var querable = userExamItemTable.InnerJoin(userExamTable, (ui, u) => ui.UserExamId == u.Id)
|
|
|
+ .InnerJoin(questionTable, (ui, u, q) => ui.QuestionId == q.QuestionId && u.ExamId == q.ExamId)
|
|
|
+ .InnerJoin(examManageTable, (ui, u, q, e) => u.ExamId == e.Id)
|
|
|
+ .InnerJoin(questionScoreTable, (ui, u, q, e, s) => q.QuestionType == s.QuestionType && s.ExamManageId == e.Id)
|
|
|
+ .Select((ui, u, q, e, s) => new ViewExamQuestionDto
|
|
|
+ {
|
|
|
+ Id = ui.Id,
|
|
|
+ Score = s.Score,
|
|
|
+ RealScore = ui.Score,
|
|
|
+ Title = q.Title,
|
|
|
+ QuestionType = q.QuestionType,
|
|
|
+ QuestionId = q.Id,
|
|
|
+ }).MergeTable().OrderBy(x=>x.QuestionType).OrderBy(x=>x.Id);
|
|
|
+
|
|
|
+ return await querable.Distinct().ToListAsync();
|
|
|
+ }
|
|
|
#endregion
|
|
|
|
|
|
}
|