فهرست منبع

增加查看考试接口

guqiang 3 روز پیش
والد
کامیت
d34730a4d8

+ 2 - 2
src/Hotline.Api/Controllers/Exam/QuestionController.cs

@@ -117,9 +117,9 @@ namespace Hotline.Api.Controllers.Exam
         /// </summary>
         /// <returns></returns>
         [HttpPost(ExamManageApiRoute.ImportExcel)]
-        public async Task ImportExcel(IFormFile files)
+        public async Task ImportExcel(IFormFile file)
         {
-            await _questionService.ImportExcel(files, HttpContext.RequestAborted);
+            await _questionService.ImportExcel(file, HttpContext.RequestAborted);
         }
 
         /// <summary>

+ 11 - 0
src/Hotline.Api/Controllers/Exam/UserExamController.cs

@@ -199,5 +199,16 @@ namespace Hotline.Api.Controllers.Exam
 
             return await _userExamService.GetUserExamResults(userExamResultReportPagedRequest); 
         }
+
+        /// <summary>
+        /// 查看考试试题
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpGet(UserExamApiRoute.View)]
+        public async Task<List<ViewExamQuestionDto>> View([FromQuery] string id)
+        {
+            return await _userExamService.View(id);
+        }
     }
 }

+ 7 - 0
src/Hotline.Application/Exam/Interface/ExamManages/IUserExamService.cs

@@ -117,5 +117,12 @@ namespace Hotline.Application.Exam.Interface.ExamManages
         /// <param name="examUserQueryRequest"></param>
         /// <returns></returns>
         Task<List<ExamUserViewResponse>> GetUserListAsync(ExamUserQueryRequest examUserQueryRequest);
+        
+        /// <summary>
+        /// 查看考试
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        Task<List<ViewExamQuestionDto>> View(string id);
     }
 }

+ 140 - 1
src/Hotline.Application/Exam/Service/ExamManages/UserExamService.cs

@@ -43,6 +43,9 @@ 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
 {
@@ -1306,10 +1309,146 @@ namespace Hotline.Application.Exam.Service.ExamManages
                 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
 
     }

+ 45 - 0
src/Hotline.Share/Dtos/ExamManages/ExamQuestionDto.cs

@@ -1,6 +1,8 @@
 using Exam.Infrastructure.Data.Entity;
+using Hotline.Share.Dtos.Questions;
 using Hotline.Share.Enums.Exams;
 using System.ComponentModel;
+using System.Runtime.CompilerServices;
 
 namespace Hotline.Share.Dtos.ExamManages
 {
@@ -40,4 +42,47 @@ namespace Hotline.Share.Dtos.ExamManages
         [Description("答案")]
         public string Answer { get; set; }
     }
+
+    /// <summary>
+    /// 查看考试试题
+    /// </summary>
+    [Description("查看考试试题")]
+    public class ViewExamQuestionDto : ExamQuestionDto
+    {
+        /// <summary>
+        /// 实际得分
+        /// </summary>
+        [Description("实际得分")]
+        public int? RealScore { get; set; }
+
+        /// <summary>
+        /// 试题Id
+        /// </summary>
+        [Description("试题Id")]
+        public string QuestionId { get; set; }
+
+        /// <summary>
+        /// 试题关联知识
+        /// </summary>
+        [Description("试题关联知识")]
+        public List<QuestionKnowladgeDto> QuestionKnowladgeDtos { get; set; }
+
+        /// <summary>
+        /// 试题课件
+        /// </summary>
+        [Description("试题课件")]
+        public List<QuestionSourcewareDto> QuestionSourcewareDtos { get; set; }
+
+        /// <summary>
+        /// 查看试题选项
+        /// </summary>
+        [Description("查看试题选项")]
+        public new List<ViewQuestionOptionDto> QuestionOptions { get; set; }
+
+        /// <summary>
+        /// 参考答案
+        /// </summary>
+        [Description("参考答案")]
+        public string CorrectAnswer { get; set; }
+    }
 }

+ 13 - 0
src/Hotline.Share/Dtos/Questions/QuestionAnswerDto.cs

@@ -15,6 +15,19 @@ namespace Hotline.Share.Dtos.Questions
 
     }
 
+    /// <summary>
+    /// 查看试题参考答案
+    /// </summary>
+    [Description("查看试题参考答案")]
+    public class ViewQuestionAnswerDto : QuestionAnswerDto
+    {
+        /// <summary>
+        /// 正确答案
+        /// </summary>
+        [Description("正确答案")]
+        public string CorrectAnswer { get; set; }
+    }
+
     /// <summary>
     /// 试题参考答案
     /// </summary>

+ 9 - 0
src/Hotline.Share/Dtos/Questions/QuestionOptionsDto.cs

@@ -22,6 +22,15 @@ namespace Hotline.Share.Dtos.Questions
         }
     }
 
+    /// <summary>
+    /// 查看试题选项
+    /// </summary>
+    [Description("查看试题选项")]
+    public class ViewQuestionOptionDto : QuestionOptionsDto
+    {
+        public bool IsSelected { get; set; }
+    }
+
     /// <summary>
     /// 试题选项
     /// </summary>

+ 12 - 0
src/Hotline.Share/ViewResponses/Exam/UserExamResultViewResponse.cs

@@ -121,6 +121,18 @@ namespace Exam.Share.ViewResponses.Exam
         /// </summary>
         [Description("是否阅卷")]
         public bool IsCheck { get; set; }
+
+        /// <summary>
+        /// 是否重考
+        /// </summary>
+        [Description("是否重考")]
+        public bool? IsReExam { get; set; }
+
+        /// <summary>
+        /// 能否重考
+        /// </summary>
+        [Description("能否重考")]
+        public bool CanReExam { get; set; }
     }
 
     public class GradingResultViewResponse : IViewResponse