Procházet zdrojové kódy

Merge branch 'feature/exam' into test
合并冲突

guqiang před 1 dnem
rodič
revize
2e3840f433

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

@@ -67,6 +67,17 @@ namespace Hotline.Api.Controllers.Exam
             return await _userExamService.GetExamQuestionViewResponses(examQuestionGroupRequest);
         }
 
+        /// <summary>
+        /// 获取用户列表
+        /// </summary>
+        /// <param name="examUserQueryRequest"></param>
+        /// <returns></returns>
+        [HttpGet(UserExamApiRoute.GetUserList)]
+        public async Task<List<ExamUserViewResponse>> GetUserList([FromQuery] ExamUserQueryRequest examUserQueryRequest)
+        {
+            return await _userExamService.GetUserListAsync(examUserQueryRequest);
+        }
+
         /// <summary>
         /// 获取试题详情
         /// </summary>

+ 2 - 0
src/Hotline.Application/Exam/Constants/ApiRoutes/UserExamApiRoute.cs

@@ -40,5 +40,7 @@ namespace Hotline.Application.Exam.Constants.ApiRoutes
         public const string GetUserExamResults = "GetUserExamResults";
 
         public const string GetGradingPagedList = "GetGradingPagedList";
+
+        public const string GetUserList = "GetUserList";
     }
 }

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

@@ -110,5 +110,12 @@ namespace Hotline.Application.Exam.Interface.ExamManages
         /// <param name="requestAborted"></param>
         /// <returns></returns>
         Task BatchGradingAsync(BatchGradingExamItemDto batchGradingExamItemDto, CancellationToken requestAborted);
+
+        /// <summary>
+        /// 获取用户列表
+        /// </summary>
+        /// <param name="examUserQueryRequest"></param>
+        /// <returns></returns>
+        Task<List<ExamUserViewResponse>> GetUserListAsync(ExamUserQueryRequest examUserQueryRequest);
     }
 }

+ 9 - 9
src/Hotline.Application/Exam/Service/ExamManages/ExamManageService.cs

@@ -110,7 +110,7 @@ namespace Hotline.Application.Exam.Service.ExamManages
             if (questionDto != null)
             {
                 questionDto.ExamQuestionScoreDtos = await GetExamQuestionScores(entityQueryRequest, entity);
-                if (entity.Mode == Share.Enums.Exams.EExamMode.Random)
+                if (entity.Mode == Share.Enums.Exams.EMethod.Random)
                 {
                     questionDto.TestPaperId = entity.ExtractRuleId;
 
@@ -169,8 +169,8 @@ namespace Hotline.Application.Exam.Service.ExamManages
 
             await GenerateExamQuestion(new GenerateExamTestPaperRequest
             {
-                TestPaperId = actionRequest.Mode == Share.Enums.Exams.EExamMode.Manual ? actionRequest.TestPaperId : null,
-                ExtractRuleId = actionRequest.Mode == Share.Enums.Exams.EExamMode.Random ? actionRequest.TestPaperId : null,
+                TestPaperId = actionRequest.Mode == Share.Enums.Exams.EMethod.Unified ? actionRequest.TestPaperId : null,
+                ExtractRuleId = actionRequest.Mode == Share.Enums.Exams.EMethod.Random ? actionRequest.TestPaperId : null,
                 ExamManageId = id
             }, cancellationToken);
 
@@ -179,7 +179,7 @@ namespace Hotline.Application.Exam.Service.ExamManages
 
         private void ResolveRandomExtractRuleId(AddExamManageDto actionRequest)
         {
-            if (actionRequest.Mode == Share.Enums.Exams.EExamMode.Random)
+            if (actionRequest.Mode == Share.Enums.Exams.EMethod.Random)
             {
                 base.Entity.ExtractRuleId = actionRequest.TestPaperId;
                 base.Entity.TestPaperId = string.Empty;
@@ -207,8 +207,8 @@ namespace Hotline.Application.Exam.Service.ExamManages
             await base.Complete(base.Entity, OperationConstant.Update);
 
             await GenerateExamQuestion(new GenerateExamTestPaperRequest { 
-                TestPaperId = actionRequest.Mode == Share.Enums.Exams.EExamMode.Manual? actionRequest.TestPaperId:null,
-                ExtractRuleId = actionRequest.Mode == Share.Enums.Exams.EExamMode.Random ? actionRequest.TestPaperId : null,
+                TestPaperId = actionRequest.Mode == Share.Enums.Exams.EMethod.Unified? actionRequest.TestPaperId:null,
+                ExtractRuleId = actionRequest.Mode == Share.Enums.Exams.EMethod.Random ? actionRequest.TestPaperId : null,
                 ExamManageId = actionRequest.Id
             }, cancellationToken);
 
@@ -300,7 +300,7 @@ namespace Hotline.Application.Exam.Service.ExamManages
             if (examManage != null)
             {
                 var questions = new List<ExamQuestion>();
-                if (examManage.Mode == Share.Enums.Exams.EExamMode.Random)
+                if (examManage.Mode == Share.Enums.Exams.EMethod.Random)
                 {
                     var tagQuestionCounts = await GetTagQuestions(examManage);
                     questions = await GetQuestions(tagQuestionCounts);
@@ -570,7 +570,7 @@ namespace Hotline.Application.Exam.Service.ExamManages
                 Score = q.Score
             });
 
-            if(examManage.Mode == Share.Enums.Exams.EExamMode.Random)
+            if(examManage.Mode == Share.Enums.Exams.EMethod.Random)
             {
                 var tagQuestionRepository = new ExamRepository<ExamTagQuestion>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
                 var tagQuestionTable = tagQuestionRepository.Queryable().Where(x => x.RuleId == examManage.ExtractRuleId);
@@ -663,7 +663,7 @@ namespace Hotline.Application.Exam.Service.ExamManages
                 var questionQuerables = new List<ISugarQueryable<ExamQuestion>>();
                 tagQuestionCounts.ForEach(item =>
                 {
-                    ISugarQueryable<ExamQuestion> queryable = questionTable.InnerJoin(questionTagTable, (q, t) => t.Id == t.QuestionId)
+                    ISugarQueryable<ExamQuestion> queryable = questionRepository.Queryable().InnerJoin(questionTagTable, (q, t) => q.Id == t.QuestionId)
                         .Where((q, t) => q.QuestionType == item.QuestionType && t.TagId == item.TagId).Take(item.Count).Select((q, t) => q);
 
                     questionQuerables.Add(queryable);

+ 15 - 0
src/Hotline.Application/Exam/Service/ExamManages/UserExamService.cs

@@ -40,6 +40,7 @@ using SqlSugar;
 using System.Threading;
 using DocumentFormat.OpenXml.Office2013.Excel;
 using Hotline.Share.Enums.Exams;
+using DocumentFormat.OpenXml.Wordprocessing;
 
 namespace Hotline.Application.Exam.Service.ExamManages
 {
@@ -685,6 +686,20 @@ namespace Hotline.Application.Exam.Service.ExamManages
                 await _userExamItemRepository.ValidateUpdateAsync(userExamItems, cancellationToken);
             }
         }
+
+        public async Task<List<ExamUserViewResponse>> GetUserListAsync(ExamUserQueryRequest examUserQueryRequest)
+        {
+            var userExamTable =  _repository.Queryable().Where(x => x.ExamId == examUserQueryRequest.ExamId);
+            var queryable = await userExamTable.InnerJoin<User>((ux, u) => ux.UserId == u.Id).Select((ux,u) => new ExamUserViewResponse
+            {
+                ExamId = ux.ExamId,
+                UserId = ux.UserId,
+                UserName = u.Name,
+                Id = ux.Id
+            }).ToListAsync();
+
+            return queryable;
+        }
         #endregion
 
         #region private method

+ 20 - 15
src/Hotline.Application/Exam/Service/Trains/TrainRecordService.cs

@@ -144,6 +144,7 @@ namespace Hotline.Application.Exam.Service.Trains
             if (trainPracticeKnowladge != null)
             {
                 addTrainDto.TrainKnowladgeId = trainPracticeKnowladge.Id;
+                addTrainDto.QuestionId = trainPracticeKnowladge.QuestionId;
             }
         }
 
@@ -275,7 +276,7 @@ namespace Hotline.Application.Exam.Service.Trains
 
             trainRecordItem.ToInsert(_sessionContext);
 
-            await _trainRecordItemRepository.ValidateAddAsync(trainRecordItem, cancellationToken);
+            await _trainRecordItemRepository.AddWithValidateAsync(trainRecordItem, cancellationToken);
         }
 
         private SqlSugar.ISugarQueryable<TrainRecordViewResponse> QueryResult(TrainRecordPagedRequest queryRequest)
@@ -363,27 +364,29 @@ namespace Hotline.Application.Exam.Service.Trains
         }
        
 
-        private async Task AddTrainRecordAnswer(AddTrainDto addTrainRecordDto, CancellationToken cancellationToken)
+        private async Task AddTrainRecordAnswer(AddTrainDto addTrainDto, CancellationToken cancellationToken)
         {
-            if (addTrainRecordDto.AddTrainRecordOptionDtos == null && addTrainRecordDto.AddTrainRecordAnswerDto == null) return;
+            if (addTrainDto.AddTrainRecordOptionDtos == null && addTrainDto.AddTrainRecordAnswerDto == null) return;
 
             var trainRecordAnswers = new List<ExamTrainRecordAnswer>();
 
-            addTrainRecordDto.AddTrainRecordOptionDtos?.ForEach(item =>
+            addTrainDto.AddTrainRecordOptionDtos?.ForEach(item =>
             {
-                item.TrainRecordId = addTrainRecordDto.TrainRecordId;
-                trainRecordAnswers.Add(_mapper.Map<ExamTrainRecordAnswer>(item));
+                item.TrainRecordId = addTrainDto.TrainRecordId;
+                var traiRecordAnswer = _mapper.Map<ExamTrainRecordAnswer>(item);
+                traiRecordAnswer.QuestionId = addTrainDto.QuestionId;
+                trainRecordAnswers.Add(traiRecordAnswer);
             });
 
-            if (addTrainRecordDto.AddTrainRecordAnswerDto != null)
+            if (addTrainDto.AddTrainRecordAnswerDto != null)
             {
-                addTrainRecordDto.AddTrainRecordAnswerDto.TrainRecordId = addTrainRecordDto.TrainRecordId;
-                trainRecordAnswers.Add(_mapper.Map<ExamTrainRecordAnswer>(addTrainRecordDto.AddTrainRecordAnswerDto));
+                addTrainDto.AddTrainRecordAnswerDto.TrainRecordId = addTrainDto.TrainRecordId;
+                trainRecordAnswers.Add(_mapper.Map<ExamTrainRecordAnswer>(addTrainDto.AddTrainRecordAnswerDto));
             }
 
             trainRecordAnswers.ToInsert(_sessionContext);
 
-            await _trainRecordAnswerRepository.ValidateAddAsync(trainRecordAnswers,cancellationToken);
+            await _trainRecordAnswerRepository.AddWithValidateAsync(trainRecordAnswers,cancellationToken);
         }
 
         //private async Task<TrainPracticeDto> GetTrainQuestionOptions(AddTrainDto addTrainDto)
@@ -441,12 +444,14 @@ namespace Hotline.Application.Exam.Service.Trains
                 .Where((tpo, tp)=> tp.Id == trainPracticeRequest.TrainPracticeId)
                 .Select((tpo, tp) => tpo).ToListAsync();
 
-            var trainRecordOptions = await trainRecordAnswerRepository.Queryable()
-                .InnerJoin<ExamTrainRecord>((t,x)=>t.TrainRecordId == x.Id)
-                .InnerJoin<ExamTrainPlanTemplate>((t,x,p)=> x.TrainPlanId == p.TrainPlanId)
-                .InnerJoin<ExamTrainPractice>((t,x,p,tp)=> x.Id == tp.TrainTemplateId)
+            var queryable = trainRecordAnswerRepository.Queryable()
+                .InnerJoin<ExamTrainRecord>((t, x) => t.TrainRecordId == x.Id)
+                .InnerJoin<ExamTrainPlanTemplate>((t, x, p) => x.TrainPlanId == p.TrainPlanId)
+                .InnerJoin<ExamTrainPractice>((t, x, p, tp) => p.TrainTemplateId == tp.TrainTemplateId)
                 .Where((t, x, p, tp) => tp.Id == trainPracticeRequest.TrainPracticeId)
-                .Select((t, x, p, tp) => t)
+                .Select((t, x, p, tp) => t);
+
+            var trainRecordOptions = await queryable
                 .ToListAsync();
 
             var trainPracticeOptionsDtos = new List<SimpleTrainPracticeOptionsDto>();

+ 1 - 1
src/Hotline.Share/Dtos/ExamManages/ExamManageDto.cs

@@ -52,7 +52,7 @@ namespace Exam.Share
         /// 组卷方式
         /// </summary>
         [Description("组卷方式")]
-        public EExamMode Mode { get; set; }
+        public EMethod Mode { get; set; }
 
         /// <summary>
         /// 考核方式

+ 1 - 1
src/Hotline.Share/Dtos/ExamManages/ExamQuestionDto.cs

@@ -26,7 +26,7 @@ namespace Hotline.Share.Dtos.ExamManages
         /// 分数
         /// </summary>
         [Description("分数")]
-        public int Score { get; set; }
+        public int? Score { get; set; }
 
         /// <summary>
         /// 考试选项

+ 1 - 1
src/Hotline.Share/Dtos/ExamManages/GradingExamQuestionDto.cs

@@ -95,7 +95,7 @@ namespace Exam.Application.Interface.Exam
         /// 分数
         /// </summary>
         [Description("分数")]
-        public int Score { get; set; }
+        public int? Score { get; set; }
     }
 
     public class UserExamQuestionDto:IActionRequest

+ 7 - 0
src/Hotline.Share/Dtos/Trains/TrainRecordDto.cs

@@ -128,6 +128,13 @@ namespace Hotline.Share.Dtos.Trains
         [Description("培训记录Id")]
         public string TrainRecordId { get; set; }
 
+        /// <summary>
+        /// 试题Id
+        /// </summary>
+        [Description("试题Id")]
+        [JsonIgnore]
+        public string QuestionId { get; set; }
+
         /// <summary>
         /// 培训习题Id
         /// </summary>

+ 1 - 1
src/Hotline.Share/Enums/Exams/EDifficultyLevel.cs

@@ -16,7 +16,7 @@ namespace Hotline.Share.Enums.Exams
         /// <summary>
         /// 正常
         /// </summary>
-        [Description("正常")]
+        [Description("适中")]
         Normal=1,
         /// <summary>
         /// 难

+ 7 - 2
src/Hotline.Share/Enums/Exams/EMethod.cs

@@ -8,9 +8,14 @@ namespace Hotline.Share.Enums.Exams
     public enum EMethod
     {
         /// <summary>
-        /// 统一
+        /// 统一
         /// </summary>
         [Description("统一阅卷")]
-        Unified=0
+        Unified = 0,
+        /// <summary>
+        /// 随机试题
+        /// </summary>
+        [Description("随机试题")]
+        Random = 1,
     }
 }

+ 1 - 1
src/Hotline.Share/Requests/Exam/ExamManagePagedRequest.cs

@@ -16,7 +16,7 @@ namespace Hotline.Share.Requests.Exam
         /// 考核方式
         /// </summary>
         [Description("考核方式")]
-        public EExamMode? Mode { get; set; }
+        public EMethod? Mode { get; set; }
 
         /// <summary>
         /// 考试编号

+ 9 - 0
src/Hotline.Share/Requests/Exam/ExamQuestionGroupRequest.cs

@@ -17,4 +17,13 @@ namespace Hotline.Share.Requests.Exam
         [Description("用户ID")]
         public string UserId { get; set; }
     }
+
+    public class ExamUserQueryRequest : IQueryRequest
+    {
+        /// <summary>
+        /// 考试Id
+        /// </summary>
+        [Description("考试Id")]
+        public string ExamId { get; set; }
+    }
 }

+ 4 - 4
src/Hotline.Share/ViewResponses/Exam/ExamManageViewResponse.cs

@@ -48,13 +48,13 @@ namespace Exam.Share.ViewResponses.Exam
                 return Mode.GetDescription();
             }
         }
-       
+
 
         /// <summary>
-        /// 组卷方式
+        /// 考核方式
         /// </summary>
-        [Description("组卷方式")]
-        public EExamMode Mode { get; set; }
+        [Description("考核方式")]
+        public EMethod Mode { get; set; }
 
         /// <summary>
         /// 试卷Id

+ 28 - 0
src/Hotline.Share/ViewResponses/Exam/UnExamUserViewResponse.cs

@@ -30,4 +30,32 @@ namespace Exam.Share.ViewResponses.Exam
 
         public string Id { get; set; }
     }
+
+    public class ExamUserViewResponse : IViewResponse
+    {
+        /// <summary>
+        /// 缺考人员
+        /// </summary>
+        [Description("缺考人员")]
+        public string UserName { get; set; }
+
+        /// <summary>
+        /// 考试Id
+        /// </summary>
+        [Description("考试Id")]
+        public string ExamId { get; set; }
+
+        /// <summary>
+        /// 用户Id
+        /// </summary>
+        [Description("用户Id")]
+        public string UserId { get; set; }
+
+        /// <summary>
+        /// 主键
+        /// </summary>
+        [Description("主键")]
+
+        public string Id { get; set; }
+    }
 }

+ 1 - 1
src/Hotline/Exams/ExamManages/ExamManage.cs

@@ -44,7 +44,7 @@ namespace Hotline.Exams.ExamManages
         /// </summary>
         [SugarColumn(ColumnDescription = "组卷方式")]
         [Description("组卷方式")]
-        public EExamMode Mode { get; set; }
+        public EMethod Mode { get; set; }
 
         /// <summary>
         /// 试卷Id