Эх сурвалжийг харах

Merge branch 'test' into lib/test

libin 3 долоо хоног өмнө
parent
commit
85ef12bccc

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

@@ -83,7 +83,7 @@ namespace Hotline.Application.Exam.Service.ExamManages
 
                 extractRuleDto.TagQuestionDtos.ForEach(item =>
                 {
-                    var tagQuestionCount = tagQuestionCounts.FirstOrDefault(m => m.TagId == item.TagId);
+                    var tagQuestionCount = tagQuestionCounts.FirstOrDefault(m => m.TagId == item.TagId && m.QuestionType == item.QuestionType);
 
                     item.TotalCount = tagQuestionCount?.TotalCount ?? 0;
                 });

+ 162 - 23
src/Hotline.Application/Exam/Service/ExamManages/UserExamService.cs

@@ -41,6 +41,7 @@ using System.Threading;
 using DocumentFormat.OpenXml.Office2013.Excel;
 using Hotline.Share.Enums.Exams;
 using DocumentFormat.OpenXml.Wordprocessing;
+using Hotline.Repository.SqlSugar.Exam.Repositories.ExamManages;
 
 namespace Hotline.Application.Exam.Service.ExamManages
 {
@@ -50,6 +51,7 @@ namespace Hotline.Application.Exam.Service.ExamManages
         private readonly IUserExamItemRepository _userExamItemRepository;
         private readonly IUserExamItemOptionRepository _userExamItemOptionRepository;
         private readonly IExamAnswerRepository _examAnswerRepository;
+        private readonly IExamManageRepository _examManageRepository;
         private readonly IDataPermissionFilterBuilder _dataPermissionFilterBuilder;
         private readonly IServiceProvider _serviceProvider;
         private readonly IMapper _mapper;
@@ -60,6 +62,7 @@ namespace Hotline.Application.Exam.Service.ExamManages
             IUserExamItemRepository userExamItemRepository,
             IUserExamItemOptionRepository userExamItemOptionRepository,
             IExamAnswerRepository examAnswerRepository,
+            IExamManageRepository examManageRepository,
             IDataPermissionFilterBuilder dataPermissionFilterBuilder, IServiceProvider serviceProvider,
             IMapper mapper, ISessionContext sessionContext) : base(repository, mapper, sessionContext)
         {
@@ -67,6 +70,7 @@ namespace Hotline.Application.Exam.Service.ExamManages
             this._userExamItemRepository = userExamItemRepository;
             this._userExamItemOptionRepository = userExamItemOptionRepository;
             this._examAnswerRepository = examAnswerRepository;
+            this._examManageRepository = examManageRepository;
             this._dataPermissionFilterBuilder = dataPermissionFilterBuilder;
             this._serviceProvider = serviceProvider;
             this._mapper = mapper;
@@ -193,7 +197,7 @@ namespace Hotline.Application.Exam.Service.ExamManages
         public async Task<List<GradingQuestionViewResponce>> GetGradingQuestionViewResponces(ExamQuestionGroupRequest examQuestionGroupRequest)
         {
             var expression = examQuestionGroupRequest.GetExpression();
-            var examManageTable = new ExamRepository<ExamManage>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable().Where(expression);
+            var examManageTable = _examManageRepository.Queryable().Where(expression);
             var testPaperItemTable = new ExamRepository<Exams.ExamManages.ExamQuestionBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable();
 
             var queryable = await examManageTable.InnerJoin(testPaperItemTable, (e, i) => e.Id == i.ExamId)
@@ -256,7 +260,7 @@ namespace Hotline.Application.Exam.Service.ExamManages
             {
                 userExamItem = _mapper.Map<GradingExamItemDto, ExamUserExamItem>(gradingExtamItemDto, userExamItem);
 
-                await _userExamItemRepository.ValidateUpdateAsync(userExamItem, cancellationToken);
+                await _userExamItemRepository.UpdateWithValidateAsync(userExamItem, cancellationToken);
             }
 
             return await GetNextExamQuestion(gradingExtamItemDto);
@@ -270,7 +274,25 @@ namespace Hotline.Application.Exam.Service.ExamManages
             {
                 userExam = _mapper.Map<SubmitExamDto, ExamUserExam>(submitExamDto, userExam);
 
-                await _repository.ValidateUpdateAsync(userExam, cancellationToken);
+                userExam.ExamStatus = EExamStatus.Complete;
+
+                await _repository.UpdateWithValidateAsync(userExam, cancellationToken);
+
+                await CompleteExamManage(userExam.ExamId, cancellationToken);
+            }
+        }
+
+        private async Task CompleteExamManage(string examId, CancellationToken cancellationToken)
+        {
+            var userExams = await _repository.Queryable().Where(x => x.ExamId == examId).ToListAsync();
+
+            if (userExams.All(x => x.IsSubmit))
+            {
+                var examManage = await _examManageRepository.GetAsync(x=>x.Id == examId);
+
+                examManage.ExamStatus = EExamStatus.Complete;
+
+                await _examManageRepository.UpdateWithValidateAsync(examManage, cancellationToken);
             }
         }
 
@@ -278,7 +300,7 @@ namespace Hotline.Application.Exam.Service.ExamManages
         {
             var userExam = await new ExamRepository<ExamUserExam>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable().Where(x => x.Id == addUserExamItemDto.UserExamId).FirstAsync();
 
-            var startExamViewResponse = await CheckExamValid(userExam);
+            var startExamViewResponse = await CheckExamValid(userExam, cancellationToken);
 
             if (!startExamViewResponse.CheckValidate())
             {
@@ -312,20 +334,23 @@ namespace Hotline.Application.Exam.Service.ExamManages
             if (userExam.StartTime == null)
                 userExam.StartTime = DateTime.Now;
 
-            var startExamViewResponse = await CheckExamValid(userExam);
+            var startExamViewResponse = await CheckExamValid(userExam, cancellationToken);
 
             if (!startExamViewResponse.CheckValidate())
             {
                 return startExamViewResponse;
             }
 
-            userExam.ExamStatus = Share.Enums.Exams.EExamStatus.Executing;
+            if (userExam.ExamStatus == EExamStatus.NoStart)
+            {
+                userExam.ExamStatus = Share.Enums.Exams.EExamStatus.Executing;
 
-            userExam.ToUpdate(_sessionContext);
+                userExam.ToUpdate(_sessionContext);
 
-            await _repository.UpdateWithValidateAsync(userExam, cancellationToken);
+                await _repository.UpdateWithValidateAsync(userExam, cancellationToken);
 
-            var examManage = await new ExamRepository<ExamManage>(_uow, _dataPermissionFilterBuilder, _serviceProvider).GetAsync(x => x.Id == userExam.ExamId);
+            }
+            var examManage = await _examManageRepository.GetAsync(x => x.Id == userExam.ExamId);
 
             return new StartExamViewResponse
             {
@@ -335,11 +360,10 @@ namespace Hotline.Application.Exam.Service.ExamManages
             };
         }
 
-        private async Task<StartExamViewResponse> CheckExamValid(ExamUserExam examUserExam)
+        private async Task<StartExamViewResponse> CheckExamValid(ExamUserExam examUserExam, CancellationToken cancellationToken)
         {
-            var examManageRepository = new ExamRepository<ExamManage>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
 
-            var examManage = await examManageRepository.Queryable().Where(x => x.Id == examUserExam.ExamId).FirstAsync();
+            var examManage = await _examManageRepository.Queryable().Where(x => x.Id == examUserExam.ExamId).FirstAsync();            
 
             var startExamViewResponse = new StartExamViewResponse
             {
@@ -366,11 +390,25 @@ namespace Hotline.Application.Exam.Service.ExamManages
 
             startExamViewResponse.IsStart = true;
 
-            startExamViewResponse.TimeSpan = (int)(examManage.EndTime - examManage.StartTime).TotalMinutes;
-            startExamViewResponse.StartTime = examManage.StartTime;
+            if (examManage.ExamStatus== EExamStatus.NoStart)
+            {
+                await UpdateExamStatus(examManage, cancellationToken);
+            }
+
+            startExamViewResponse.TimeSpan = examManage?.TimeSpan ?? 0;
+            startExamViewResponse.StartTime = examManage?.StartTime;
             return startExamViewResponse;
         }
 
+        private async Task UpdateExamStatus(ExamManage? examManage, CancellationToken cancellationToken)
+        {
+            examManage.ExamStatus = EExamStatus.Executing;
+
+            examManage.ToUpdate(_sessionContext);
+
+            await _examManageRepository.UpdateWithValidateAsync(examManage, cancellationToken);
+        }
+
         private StartExamViewResponse AddCheckValidateCountStrategy(ExamUserExam examUserExam, ExamManage examManage, StartExamViewResponse startExamViewResponse, List<IExamStrategy> examStrategys)
         {
             if (examManage.ExamType == Share.Enums.Exams.EExamType.Simulate)
@@ -492,7 +530,7 @@ namespace Hotline.Application.Exam.Service.ExamManages
 
                 userExam.ToUpdate(_sessionContext);
 
-                await _repository.ValidateUpdateAsync(userExam, cancellationToken);
+                await _repository.UpdateWithValidateAsync(userExam, cancellationToken);
             }
         }
 
@@ -512,13 +550,13 @@ namespace Hotline.Application.Exam.Service.ExamManages
             var questionScoreTable = questionScoreRepository.Queryable();
 
             var queryable = userExamTable.InnerJoin(userExamItemTable, (e, i) => e.Id == i.UserExamId)
-                .InnerJoin(questionTable, (e, i, q) => i.QuestionId == q.Id)
+                .InnerJoin(questionTable, (e, i, q) => i.QuestionId == q.QuestionId)
                 .LeftJoin(userExamItemOptionTable, (e, i, q, o) => i.Id == o.UserExamItemId)
                 .LeftJoin(quesitonOptionTable, (e, i, q, o, qo) => o.QuestionOptionId == qo.Id)
                 .LeftJoin(examAnswerTable, (e, i, q, o, qo, a) => i.Id == a.UserExamItemId)
                 .LeftJoin(testPaperItemAnswerTable, (e, i, q, o, qo, a, ta) => ta.QuestionId == qo.QuestionId)
                 .InnerJoin(questionScoreTable, (e, i, q, o, qo, a, ta, s) => q.QuestionType == s.QuestionType && e.ExamId == s.ExamManageId)
-            .Where((e, i, q, o, qo, a, ta, s) => q.QuestionType == EQuestionType.Single || q.QuestionType == EQuestionType.Multi || q.QuestionType == EQuestionType.Judge)
+            .Where((e, i, q, o, qo, a, ta, s) => !(q.QuestionType == EQuestionType.Single || q.QuestionType == EQuestionType.Multi || q.QuestionType == EQuestionType.Judge))
             .Select(
             (e, i, q, o, qo, a, ta, s) => new GradingExamQuestionTempDto
             {
@@ -550,7 +588,7 @@ namespace Hotline.Application.Exam.Service.ExamManages
                 Id = g.Key.Id,
                 Score = g.FirstOrDefault().Score,
                 Title = g.FirstOrDefault().Title,
-                CorrectAnswer = g.Key.QuestionType.CheckSelectType() ? string.Join(",", g.Where(i => i.IsAnswer).Select(n => n.Label)) : g.FirstOrDefault()?.CorrectAnswer
+                CorrectAnswer = g.Key.QuestionType.CheckSelectType() ? string.Join(",", g.Where(i => i.IsAnswer).Select(n => n.Label).Distinct()) : g.FirstOrDefault()?.CorrectAnswer
             }).ToList();
 
             return gradingExamQuestionDtos;
@@ -683,10 +721,37 @@ namespace Hotline.Application.Exam.Service.ExamManages
 
             if (userExamItems != null && userExamItemIds.Any())
             {
-                userExamItems = _mapper.Map<List<GradingExamItemDto>, List<ExamUserExamItem>>(batchGradingExamItemDto.Items, userExamItems);
+                var updateUserExamItems = new List<ExamUserExamItem>();
+                userExamItems.ForEach(x =>
+                {
+                    var gradingExamItemDto = batchGradingExamItemDto.Items.Find(m => m.UserExamItemId == x.Id);
+
+                    var updateUserExamItem = _mapper.Map<GradingExamItemDto, ExamUserExamItem>(gradingExamItemDto,x);
+
+                    updateUserExamItems.Add(updateUserExamItem);
+                });
+
+                updateUserExamItems.ToUpdate(_sessionContext);
+
+                await _userExamItemRepository.UpdateWithValidateAsync(updateUserExamItems, cancellationToken);
+
+                var userExamId = userExamItems.FirstOrDefault()?.UserExamId;
+                // 计算本次考试得分
+                var userExamItemsInCheck = await _userExamItemRepository.Queryable().Where(x => x.UserExamId == userExamId).ToListAsync();
+                var updateExamItemDTOs = new List<UpdateUserExamItemDto>();
+                userExamItemsInCheck.ForEach(x =>
+                {
+                    var updateUserExamItem = _mapper.Map<ExamUserExamItem, UpdateUserExamItemDto>(x);
+
+                    updateExamItemDTOs.Add(updateUserExamItem);
+                });
+                await CalcuteExamItemScore(_userExamItemRepository, updateExamItemDTOs,cancellationToken);
+
+                await CalcuteTotalScore(_userExamItemRepository, userExamId, cancellationToken);
 
-                await _userExamItemRepository.ValidateUpdateAsync(userExamItems, cancellationToken);
             }
+
+            
         }
 
         public async Task<List<ExamUserViewResponse>> GetUserListAsync(ExamUserQueryRequest examUserQueryRequest)
@@ -737,6 +802,80 @@ namespace Hotline.Application.Exam.Service.ExamManages
             await userExamRepository.UpdateWithValidateAsync(userExamItem, cancellationToken);
         }
 
+        private async Task CalcuteExamItemScore(IUserExamItemRepository userExamItemRepository, List<UpdateUserExamItemDto> addUserExamItemDtos, CancellationToken cancellationToken)
+        {
+            var questionIds = addUserExamItemDtos.Select(x => x.QuestionId).ToList();
+            var userExamIds = addUserExamItemDtos.Select(x => x.UserExamId).ToList();
+            var questionTypes = addUserExamItemDtos.Select(x => x.QuestionType).ToList();
+
+            var testPaperItemOptionsRepository = new ExamRepository<ExamQuestionOptionsBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
+            var userExamItemOptionRepository = new ExamRepository<ExamUserExamItemOptions>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
+            var examManageRepository = new ExamRepository<ExamManage>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
+            var testPaperItemRepository = new ExamRepository<Exams.ExamManages.ExamQuestionBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
+            var examQuestionScoreRepository = new ExamRepository<ExamQuestionScoreBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
+            var testPaperOptionsTable = testPaperItemOptionsRepository.Queryable().Where(x => questionIds.Contains( x.QuestionId ) && x.IsAnswer);
+            var testPaperItemTable = testPaperItemRepository.Queryable().Where(x => x.QuestionType== EQuestionType.Single || x.QuestionType == EQuestionType.Multi || x.QuestionType == EQuestionType.Judge);
+            var userExamTable = _repository.Queryable().Where(x => userExamIds.Contains(x.Id));
+            var examManageTable = examManageRepository.Queryable();
+            var testPaperOptionIds = await testPaperOptionsTable.InnerJoin(testPaperItemTable, (t, i) => t.ExamQuestionId == i.Id)
+                .InnerJoin(examManageTable, (t, i, e) => i.ExamId == e.Id)
+                .InnerJoin(userExamTable, (t, i, e, u) => e.Id == u.ExamId)
+                .Select((t, i, e, u) => t.Id).ToListAsync();
+
+            var userExamItems = await userExamItemRepository.Queryable().Where(x => userExamIds.Contains(x.UserExamId)).ToListAsync();
+            var userExamItemIds = userExamItems.Select(x => x.Id).ToList();
+            var userExamItemOptions = await userExamItemOptionRepository.Queryable().Where(x => userExamItemIds.Contains(x.UserExamItemId)).ToListAsync();
+            var examQuesiontScores = await examQuestionScoreRepository.Queryable().Where(x => questionTypes.Contains(x.QuestionType))
+                .InnerJoin(userExamTable, (e, u) => e.Id == u.ExamId)
+                .Select((e, u) => e).ToListAsync();
+
+
+            foreach (var addUserExamItemDto in addUserExamItemDtos)
+            {              
+                var isCorrect = userExamItemOptions.Select(x => x.QuestionOptionId).OrderBy(x => x).SequenceEqual(testPaperOptionIds.OrderBy(x => x));
+                var userExamItem = userExamItems.FirstOrDefault(x => x.QuestionId == addUserExamItemDto.QuestionId);
+                if (userExamItem != null)
+                {
+                    userExamItem.IsCheck = true;
+                    userExamItem.Score = isCorrect ? examQuesiontScores.FirstOrDefault(x => x.QuestionType == addUserExamItemDto.QuestionType)?.Score : 0;
+                    userExamItem.ToUpdate(_sessionContext);
+                }               
+            }
+
+          
+            await userExamItemRepository.UpdateWithValidateAsync(userExamItems, cancellationToken);
+        }
+
+        private async Task CalcuteTotalScore(IUserExamItemRepository userExamItemRepository, string userExamId, CancellationToken cancellationToken)
+        {
+            var userExam = await _repository.GetAsync(x => x.Id == userExamId);
+
+            if (userExam != null)
+            {
+                var userExamItems = await userExamItemRepository.Queryable().Where(x => x.UserExamId == userExamId).ToListAsync();
+                var examManageRepository = new ExamRepository<ExamManage>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
+                var examManage = await examManageRepository.GetAsync(x => x.Id == userExam.ExamId);
+
+                var totalScore = userExamItems.Sum(x => x.Score);
+
+                userExam.Score = totalScore;
+
+                userExam.IsCheck = true;
+
+                userExam.ExamStatus = EExamStatus.Complete;
+
+
+                if (examManage != null)
+                {
+                    userExam.IsSuccess = userExam.Score > examManage.CutoffScore;
+                }               
+
+                userExam.ToUpdate(_sessionContext);
+
+                await _repository.UpdateWithValidateAsync(userExam,cancellationToken);
+            }
+        }
+
         private async Task AddExamAsync(IRepository<ExamUserExamItem> userExamItemRepository, AddUserExamItemDto addUserExamItemDto, CancellationToken cancellationToken)
         {
             var userExamItem = await AddUserExamItem(addUserExamItemDto, cancellationToken);
@@ -898,7 +1037,7 @@ namespace Hotline.Application.Exam.Service.ExamManages
 
                     examAnswer.ToUpdate(_sessionContext);
 
-                    await _examAnswerRepository.ValidateUpdateAsync(examAnswer, cancellationToken);
+                    await _examAnswerRepository.UpdateWithValidateAsync(examAnswer, cancellationToken);
 
                     examAnswers.Add(examAnswer);
                 }
@@ -979,7 +1118,7 @@ namespace Hotline.Application.Exam.Service.ExamManages
 
                 entities.ToUpdate(_sessionContext);
 
-                await _userExamItemOptionRepository.ValidateUpdateAsync(entities, cancellationToken);
+                await _userExamItemOptionRepository.UpdateWithValidateAsync(entities, cancellationToken);
             }
 
 
@@ -995,7 +1134,7 @@ namespace Hotline.Application.Exam.Service.ExamManages
 
             userExamItem.ToUpdate(_sessionContext);
 
-            await _userExamItemRepository.ValidateUpdateAsync(userExamItem, cancellationToken);
+            await _userExamItemRepository.UpdateWithValidateAsync(userExamItem, cancellationToken);
 
             if (updateUserExamItemDto.QuestionType.CheckSelectType())
             {

+ 1 - 1
src/Hotline.Application/Exam/Service/Questions/QuestionService.cs

@@ -627,7 +627,7 @@ namespace Hotline.Application.Exam.Service.Questions
 
             actionRequest.QuestionKnowladgeDtos.ResolveOperationStatus();
 
-            var questionKnowladgeDtos = actionRequest.QuestionKnowladgeDtos.Where(x => x.OperationStatus == EEOperationStatus.Add).ToList();
+            var questionKnowladgeDtos = actionRequest.QuestionKnowladgeDtos.Where(x => x.OperationStatus == EEOperationStatus.Update).ToList();
 
             var ids = questionKnowladgeDtos.Select(x => x.Id);
 

+ 5 - 5
src/Hotline.Application/Exam/Service/TestPapers/TestPaperService.cs

@@ -825,14 +825,14 @@ namespace Hotline.Application.Exam.Service.TestPapers
             var tagQuestionTable = tagQuestionRepository.Queryable();
 
 
-            var testPaperRules = await exatractTable.InnerJoin(ruleTagTable,(e,rt)=>e.Id == rt.RuleId)
-                .InnerJoin(tagQuestionTable,(e,rt,tq)=>rt.RuleId == tq.RuleId && rt.TagId == tq.TagId)
-                .GroupBy((e, rt, tq)=> tq.QuestionType)
-                .Select((e,rt,tq)=> new ExamTagQuestion
+            var testPaperRules = await exatractTable.InnerJoin(ruleTagTable, (e, rt) => e.Id == rt.RuleId)
+                .InnerJoin(tagQuestionTable, (e, rt, tq) => rt.RuleId == tq.RuleId && rt.TagId == tq.TagId)
+                .GroupBy((e, rt, tq) => tq.QuestionType)
+                .Select((e, rt, tq) => new ExamTagQuestion
                 {
                     QuestionType = tq.QuestionType,
                     Count = SqlFunc.AggregateSum(tq.Count)
-                })
+                }).MergeTable().Where(m => m.Count > 0)
                 .ToListAsync();
 
             if (testPaperRules != null)

+ 3 - 2
src/Hotline.Repository.SqlSugar/Exam/Validators/ExamManages/ExamManageValidator.cs

@@ -45,16 +45,17 @@ namespace Exam.Application
 
             RuleFor(m => m.Name).NotEmpty().WithMessage(x=>string.Format(ExamErrorMessage.IsRequired,x.GetType().GetDescription(nameof(ExamManage.Name))));
             RuleFor(m => m.Code).NotEmpty().WithMessage(x => string.Format(ExamErrorMessage.IsRequired, x.GetType().GetDescription(nameof(ExamManage.Code))));
-            RuleFor(m => m.CutoffScore).NotNull().WithMessage(x => string.Format(ExamErrorMessage.IsRequired, x.GetType().GetDescription(nameof(ExamManage.CutoffScore))));
+            RuleFor(m => m.CutoffScore).NotEmpty().WithMessage(x => string.Format(ExamErrorMessage.IsRequired, x.GetType().GetDescription(nameof(ExamManage.CutoffScore))));
             RuleFor(m => m.ExamType).NotNull().WithMessage(x => string.Format(ExamErrorMessage.IsRequired, x.GetType().GetDescription(nameof(ExamManage.ExamType))));
             RuleFor(m => m.Method).NotNull().WithMessage(x => string.Format(ExamErrorMessage.IsRequired, x.GetType().GetDescription(nameof(ExamManage.Method))));
-            RuleFor(m => m.TestPaperId).NotEmpty().WithMessage(x => string.Format(ExamErrorMessage.IsRequired, typeof(ExamTestPaper).GetDescription()));
+            //RuleFor(m => m.TestPaperId).NotEmpty().WithMessage(x => string.Format(ExamErrorMessage.IsRequired, typeof(ExamTestPaper).GetDescription()));
             RuleFor(m => m.Count).NotNull().WithMessage(x => string.Format(ExamErrorMessage.IsRequired, x.GetType().GetDescription(nameof(ExamManage.Count))));
             RuleFor(m => m.TimeSpan).NotNull().WithMessage(x => string.Format(ExamErrorMessage.IsRequired, x.GetType().GetDescription(nameof(ExamManage.TimeSpan))));
             RuleFor(m => m.StartTime).NotNull().WithMessage(x => string.Format(ExamErrorMessage.IsRequired, x.GetType().GetDescription(nameof(ExamManage.StartTime))));
             RuleFor(m => m.EndTime).NotNull().WithMessage(x => string.Format(ExamErrorMessage.IsRequired, x.GetType().GetDescription(nameof(ExamManage.EndTime))));
             RuleFor(m => m.EndTime).Must((e, v) => e.ExamType == EExamType.Simulate || e.StartTime < v).WithMessage(x => string.Format(ExamErrorMessage.Greater, x.GetType().GetDescription(nameof(ExamManage.EndTime)), x.GetType().GetDescription(nameof(ExamManage.StartTime))));
             RuleFor(m => m.TotalScore).NotNull().WithMessage(x => string.Format(ExamErrorMessage.IsRequired, x.GetType().GetDescription(nameof(ExamManage.TotalScore))));
+            RuleFor(m => m.CutoffScore).Must((e, v)=> e.TotalScore > v).WithMessage(x => string.Format(ExamErrorMessage.Greater, x.GetType().GetDescription(nameof(ExamManage.CutoffScore)), x.GetType().GetDescription(nameof(ExamManage.TotalScore))));
         }
 
         protected override void ValidateRuleWithAdd()