From 58e11d1b470f3f12d6fe237a83a24d27951b01ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BC=8D=E6=BD=9C?= <1620556043@qq.com> Date: Sat, 22 Mar 2025 18:08:17 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E6=AD=A5=E5=AE=8C=E5=96=84=E5=88=9B?= =?UTF-8?q?=E5=BB=BA=E5=9B=BA=E5=AE=9A=E8=AF=95=E5=8D=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/ExamPapersController.cs | 1 + .../Controllers/QuestionsController.cs | 12 ++++++++ .../Dtos/ExamPaper/CreateExamPaperDto.cs | 26 +++++++++------- .../Dtos/Question/QuestionSelectListDto.cs | 15 ++++++++++ .../Question/QuestionSelectListQueryDto.cs | 24 +++++++++++++++ .../MappingProfiles/ExamPaperProfile.cs | 8 +++++ .../Implementations/ExamPaperService.cs | 30 ++++++++++--------- .../Implementations/QuestionService.cs | 24 +++++++++++++++ .../Services/Interfaces/IQuestionService.cs | 7 +++++ 9 files changed, 123 insertions(+), 24 deletions(-) create mode 100644 Src/CodeSpirit.ExamApi/Dtos/Question/QuestionSelectListDto.cs create mode 100644 Src/CodeSpirit.ExamApi/Dtos/Question/QuestionSelectListQueryDto.cs diff --git a/Src/CodeSpirit.ExamApi/Controllers/ExamPapersController.cs b/Src/CodeSpirit.ExamApi/Controllers/ExamPapersController.cs index 79ec679..29aa81f 100644 --- a/Src/CodeSpirit.ExamApi/Controllers/ExamPapersController.cs +++ b/Src/CodeSpirit.ExamApi/Controllers/ExamPapersController.cs @@ -58,6 +58,7 @@ public class ExamPapersController : ApiControllerBase /// 创建试卷DTO /// 创建的试卷 [HttpPost] + [HeaderOperation("生成固定试卷", "form")] public async Task>> CreateExamPaper(CreateExamPaperDto createDto) { var result = await _examPaperService.CreateAsync(createDto); diff --git a/Src/CodeSpirit.ExamApi/Controllers/QuestionsController.cs b/Src/CodeSpirit.ExamApi/Controllers/QuestionsController.cs index 92890b0..9077288 100644 --- a/Src/CodeSpirit.ExamApi/Controllers/QuestionsController.cs +++ b/Src/CodeSpirit.ExamApi/Controllers/QuestionsController.cs @@ -44,6 +44,18 @@ public class QuestionsController : ApiControllerBase return SuccessResponse(questions); } + /// + /// 获取题目选择列表 + /// + /// + /// + [HttpGet("select-list")] + public async Task>>> GetSelectList([FromQuery] QuestionSelectListQueryDto queryDto) + { + List questions = await _questionService.GetQuestionSelectListAsync(queryDto); + return SuccessResponse(questions); + } + /// /// 获取题目详情 /// diff --git a/Src/CodeSpirit.ExamApi/Dtos/ExamPaper/CreateExamPaperDto.cs b/Src/CodeSpirit.ExamApi/Dtos/ExamPaper/CreateExamPaperDto.cs index e5e8988..b033c2b 100644 --- a/Src/CodeSpirit.ExamApi/Dtos/ExamPaper/CreateExamPaperDto.cs +++ b/Src/CodeSpirit.ExamApi/Dtos/ExamPaper/CreateExamPaperDto.cs @@ -1,4 +1,5 @@ -using CodeSpirit.ExamApi.Data.Models; +using CodeSpirit.Amis.Attributes.FormFields; +using CodeSpirit.ExamApi.Data.Models; namespace CodeSpirit.ExamApi.Dtos.ExamPaper; @@ -28,6 +29,7 @@ public class CreateExamPaperDto /// [DisplayName("试卷类型")] [Required(ErrorMessage = "试卷类型不能为空")] + [AmisFormField(VisibleOn = "false")] public ExamPaperType Type { get; set; } = ExamPaperType.Fixed; /// @@ -52,16 +54,20 @@ public class CreateExamPaperDto [Range(1, 1440, ErrorMessage = "考试时长必须在1-1440分钟之间")] public int Duration { get; set; } = 120; - /// - /// 随机试卷规则 - /// - [DisplayName("随机试卷规则")] - [StringLength(2000, ErrorMessage = "随机规则不能超过2000个字符")] - public string? RandomRules { get; set; } - /// /// 题目列表 /// - [DisplayName("题目列表")] - public List? Questions { get; set; } + [AmisSelectField( + Source = "${ROOT_API}/api/exam/Questions/select-list", + ValueField = "id", + LabelField = "content", + Multiple = true, + JoinValues = false, + ExtractValue = true, + Searchable = true, + Clearable = true, + Required = true, + Placeholder = "请选择题目" + )] + public List QuestionIds { get; set; } } diff --git a/Src/CodeSpirit.ExamApi/Dtos/Question/QuestionSelectListDto.cs b/Src/CodeSpirit.ExamApi/Dtos/Question/QuestionSelectListDto.cs new file mode 100644 index 0000000..a8d3bc6 --- /dev/null +++ b/Src/CodeSpirit.ExamApi/Dtos/Question/QuestionSelectListDto.cs @@ -0,0 +1,15 @@ +namespace CodeSpirit.ExamApi.Dtos.Question +{ + public class QuestionSelectListDto + { + /// + /// Id + /// + public long Id { get; set; } + + /// + /// 题目内容 + /// + public string Content { get; set; } + } +} diff --git a/Src/CodeSpirit.ExamApi/Dtos/Question/QuestionSelectListQueryDto.cs b/Src/CodeSpirit.ExamApi/Dtos/Question/QuestionSelectListQueryDto.cs new file mode 100644 index 0000000..4bcd1f0 --- /dev/null +++ b/Src/CodeSpirit.ExamApi/Dtos/Question/QuestionSelectListQueryDto.cs @@ -0,0 +1,24 @@ +using CodeSpirit.ExamApi.Data.Models; + +namespace CodeSpirit.ExamApi.Dtos.Question +{ + public class QuestionSelectListQueryDto + { + /// + /// 题目类型 + /// + [DisplayName("题目类型")] + public QuestionType? Type { get; set; } + + /// + /// 题目难度 + /// + [DisplayName("难度")] + public QuestionDifficulty? Difficulty { get; set; } + + /// + /// 题目分类 + /// + public List? CategoryIds { get; set; } + } +} diff --git a/Src/CodeSpirit.ExamApi/MappingProfiles/ExamPaperProfile.cs b/Src/CodeSpirit.ExamApi/MappingProfiles/ExamPaperProfile.cs index 7176a77..0c4bb82 100644 --- a/Src/CodeSpirit.ExamApi/MappingProfiles/ExamPaperProfile.cs +++ b/Src/CodeSpirit.ExamApi/MappingProfiles/ExamPaperProfile.cs @@ -34,5 +34,13 @@ public class ExamPaperProfile : Profile // 创建试卷题目映射 CreateMap(); + + // 题目版本映射考题 + CreateMap() + .ForMember(dest => dest.QuestionId, opt => opt.MapFrom(src => src.QuestionId)) + .ForMember(dest => dest.QuestionVersionId, opt => opt.MapFrom(src => src.Id)) + .ForMember(dest => dest.Score, opt => opt.MapFrom(src => src.DefaultScore)) + .ForMember(dest => dest.QuestionVersion, opt => opt.Ignore()) + ; } } \ No newline at end of file diff --git a/Src/CodeSpirit.ExamApi/Services/Implementations/ExamPaperService.cs b/Src/CodeSpirit.ExamApi/Services/Implementations/ExamPaperService.cs index 4d397aa..e304851 100644 --- a/Src/CodeSpirit.ExamApi/Services/Implementations/ExamPaperService.cs +++ b/Src/CodeSpirit.ExamApi/Services/Implementations/ExamPaperService.cs @@ -125,32 +125,34 @@ namespace CodeSpirit.ExamApi.Services.Implementations examPaper.UsageCount = 0; examPaper.AverageScore = 0; examPaper.PassRate = 0; - + + var lastVersionQuestions = await _questionVersionRepository.CreateQuery().Include(s => s.Question) + .Where(s => createDto.QuestionIds.Select(i => long.Parse(i)).ToList().Contains(s.QuestionId)) + .GroupBy(s => s.QuestionId) + .Select(g => g.OrderByDescending(s => s.Version).First()) + .ToListAsync(); + + var questions = lastVersionQuestions.Select(s => s.Question).ToList(); + // 计算难度系数 - if (createDto.Questions != null && createDto.Questions.Any()) + if (questions != null && questions.Count != 0) { - var questionIds = createDto.Questions.Select(q => q.QuestionId).ToList(); - var questions = await _questionRepository - .Find(q => questionIds.Contains(q.Id)) - .ToListAsync(); - - if (questions.Any()) - { - // 根据题目难度计算试卷难度系数 - examPaper.DifficultyLevel = CalculateDifficultyLevel(questions); - } + // 根据题目难度计算试卷难度系数 + examPaper.DifficultyLevel = CalculateDifficultyLevel(questions); } await _examPaperRepository.AddAsync(examPaper); // 添加试卷题目 - if (createDto.Questions != null && createDto.Questions.Any()) + if (lastVersionQuestions != null && lastVersionQuestions.Count != 0) { var examPaperQuestions = new List(); - foreach (var questionDto in createDto.Questions) + var order = 1; + foreach (var questionDto in lastVersionQuestions) { var examPaperQuestion = _mapper.Map(questionDto); examPaperQuestion.ExamPaperId = examPaper.Id; + examPaperQuestion.OrderNumber = order++; examPaperQuestions.Add(examPaperQuestion); } diff --git a/Src/CodeSpirit.ExamApi/Services/Implementations/QuestionService.cs b/Src/CodeSpirit.ExamApi/Services/Implementations/QuestionService.cs index dac8568..05f76ee 100644 --- a/Src/CodeSpirit.ExamApi/Services/Implementations/QuestionService.cs +++ b/Src/CodeSpirit.ExamApi/Services/Implementations/QuestionService.cs @@ -88,6 +88,30 @@ namespace CodeSpirit.ExamApi.Services.Implementations ); } + /// + /// 获取选择题选项列表 + /// + /// + /// + public async Task> GetQuestionSelectListAsync(QuestionSelectListQueryDto queryDto) + { + var query = _repository.CreateQuery(); + if (queryDto.CategoryIds != null && queryDto.CategoryIds.Any()) + query = query.Where(s => queryDto.CategoryIds.Contains(s.CategoryId)); + + if (queryDto.Difficulty.HasValue) + query = query.Where(s => s.Difficulty == queryDto.Difficulty.Value); + + if (queryDto.Type.HasValue) + query = query.Where(s => s.Type == queryDto.Type.Value); + + return await query.Select(s => new QuestionSelectListDto() + { + Id = s.Id, + Content = s.Content + }).ToListAsync(); + } + /// /// 获取题目详情 /// diff --git a/Src/CodeSpirit.ExamApi/Services/Interfaces/IQuestionService.cs b/Src/CodeSpirit.ExamApi/Services/Interfaces/IQuestionService.cs index 4df4d76..b0c967a 100644 --- a/Src/CodeSpirit.ExamApi/Services/Interfaces/IQuestionService.cs +++ b/Src/CodeSpirit.ExamApi/Services/Interfaces/IQuestionService.cs @@ -13,6 +13,13 @@ public interface IQuestionService /// 题目分页列表 Task> GetQuestionsAsync(QuestionQueryDto queryDto); + /// + /// 获取题目选项列表 + /// + /// 查询条件 + /// + Task> GetQuestionSelectListAsync(QuestionSelectListQueryDto queryDto); + /// /// 获取题目详情 /// -- Gitee