diff --git a/Entities/Contracts/AppMainStruct.cs b/Entities/Contracts/AppMainStruct.cs new file mode 100644 index 0000000..97b856a --- /dev/null +++ b/Entities/Contracts/AppMainStruct.cs @@ -0,0 +1,77 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Entities.Contracts +{ + public enum Layout : byte + { + horizontal = 0, + vertical = 1, + + Auto = 2 + } + + public enum Publisher : byte + { + Unknown = 0, + 统编版, + 部编版, + } + + public enum Grade : byte + { + Unknown = 0, + 一年级 = 1, + 二年级 = 2, + 三年级 = 3, + 四年级 = 4, + 五年级 = 5, + 六年级 = 6 + } + + public enum DifficultyLevel : byte + { + easy, + medium, + hard + } + + public enum QuestionType : byte + { + Unknown = 0, + Spelling, // 拼写 + Pronunciation, // 给带点字选择正确读音 + WordFormation, // 组词 + FillInTheBlanks, // 选词填空 / 补充词语 + SentenceDictation, // 默写句子 + SentenceRewriting, // 仿句 / 改写句子 + ReadingComprehension, // 阅读理解 + Composition // 作文 + + } + + public enum SubjectAreaEnum : byte + { + Unknown = 0, + Mathematics, // 数学 + Physics, // 物理 + Chemistry, // 化学 + Biology, // 生物 + History, // 历史 + Geography, // 地理 + Literature, // 语文/文学 + English, // 英语 + ComputerScience, // 计算机科学 + } + + public enum QuestionGroupState : byte + { + Standalone, + Group, + Subquestion + } + +} diff --git a/Entities/Contracts/Assignment.cs b/Entities/Contracts/Assignment.cs index 7e7d8a2..36e3742 100644 --- a/Entities/Contracts/Assignment.cs +++ b/Entities/Contracts/Assignment.cs @@ -24,32 +24,36 @@ namespace Entities.Contracts public string Description { get; set; } [Column("subject_area")] - public string SubjectArea { get; set; } + public SubjectAreaEnum SubjectArea { get; set; } [Required] [Column("due_date")] public DateTime DueDate { get; set; } [Column("total_points")] - public float? TotalPoints { get; set; } + public byte TotalQuestions { get; set; } + + [Column("score")] + public float Score { get; set; } [Column("created_by")] - [ForeignKey("Creator")] - public Guid CreatedBy { get; set; } + public Guid CreatorId { get; set; } [Column("created_at")] public DateTime CreatedAt { get; set; } [Column("updated_at")] - public DateTime UpdatedAt { get; set; } + public DateTime UpdatedAt { get; set; } = DateTime.UtcNow; [Column("deleted")] - public bool IsDeleted { get; set; } + public bool IsDeleted { get; set; } = false; // Navigation Properties + + [ForeignKey(nameof(CreatorId))] public User Creator { get; set; } public ICollection AssignmentClasses { get; set; } - public ICollection AssignmentGroups { get; set; } + public AssignmentStruct ExamStruct { get; set; } public ICollection AssignmentAttachments { get; set; } public ICollection Submissions { get; set; } @@ -58,7 +62,6 @@ namespace Entities.Contracts Id = Guid.NewGuid(); Submissions = new HashSet(); - AssignmentGroups = new HashSet(); AssignmentClasses = new HashSet(); AssignmentAttachments = new HashSet(); } diff --git a/Entities/Contracts/AssignmentQuestion.cs b/Entities/Contracts/AssignmentQuestion.cs index 0b9d1cd..a7b836b 100644 --- a/Entities/Contracts/AssignmentQuestion.cs +++ b/Entities/Contracts/AssignmentQuestion.cs @@ -6,6 +6,7 @@ using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text; using System.Threading.Tasks; +using Entities.DTO; namespace Entities.Contracts { @@ -17,41 +18,43 @@ namespace Entities.Contracts public Guid Id { get; set; } [Column("question_id")] - public Guid? QuestionId { get; set; } // 设为可空 - - // 当 IsGroup 为 true 时,此为 QuestionGroup 的外键 - [Column("question_group_id")] // 新增一个外键列 - public Guid? QuestionGroupId { get; set; } // 设为可空 + public Guid QuestionId { get; set; } [Required] [Column("group_id")] [ForeignKey("AssignmentGroup")] - public Guid AssignmentGroupId { get; set; } - + public Guid AssignmentStructId { get; set; } [Required] [Column("question_number")] - public byte QuestionNumber { get; set; } + public byte Index { get; set; } + [Column("parent_question_group_id")] + public Guid? ParentAssignmentQuestionId { get; set; } + + [Column("group_state")] + public QuestionGroupState GroupState { get; set; } = QuestionGroupState.Standalone; + [Column("created_at")] public DateTime CreatedAt { get; set; } [Column("score")] public float? Score { get; set; } - [Required] - [Column("bgroup")] - public bool IsGroup { get; set; } [Column("deleted")] public bool IsDeleted { get; set; } public Question Question { get; set; } - public QuestionGroup QuestionGroup { get; set; } + public AssignmentStruct AssignmentStruct { get; set; } public ICollection SubmissionDetails { get; set; } - public AssignmentGroup AssignmentGroup { get; set; } + + [ForeignKey(nameof(ParentAssignmentQuestionId))] + public AssignmentQuestion? ParentAssignmentQuestion { get; set; } + public ICollection ChildrenAssignmentQuestion { get; set; } = new List(); + public AssignmentQuestion() { diff --git a/Entities/Contracts/AssignmentGroup.cs b/Entities/Contracts/AssignmentStruct.cs similarity index 61% rename from Entities/Contracts/AssignmentGroup.cs rename to Entities/Contracts/AssignmentStruct.cs index 623fa7d..4b61e9c 100644 --- a/Entities/Contracts/AssignmentGroup.cs +++ b/Entities/Contracts/AssignmentStruct.cs @@ -5,11 +5,12 @@ using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text; using System.Threading.Tasks; +using System.Runtime.InteropServices; namespace Entities.Contracts { [Table("assignment_group")] - public class AssignmentGroup + public class AssignmentStruct { [Key] [Column("id")] @@ -26,35 +27,34 @@ namespace Entities.Contracts [Column("descript")] [MaxLength(65535)] - public string Descript { get; set; } + public string Description { get; set; } + [Column("layout")] + public Layout Layout { get; set; } [Column("total_points")] - public float? TotalPoints { get; set; } + public float? Score { get; set; } - [Column("number")] - public byte Number { get; set; } + [Column("index")] + public byte Index { get; set; } [Column("parent_group")] - public Guid? ParentGroup { get; set; } + public Guid? ParentStructId { get; set; } [Column("deleted")] - public bool IsDeleted { get; set; } - - [Column("valid_question_group")] - public bool ValidQuestionGroup { get; set; } + public bool IsDeleted { get; set; } = false; // Navigation Properties public Assignment? Assignment { get; set; } - public AssignmentGroup? ParentAssignmentGroup { get; set;} - public ICollection ChildAssignmentGroups { get; set; } + public AssignmentStruct? ParentStruct { get; set;} + public ICollection ChildrenGroups { get; set; } public ICollection AssignmentQuestions { get; set; } - public AssignmentGroup() + public AssignmentStruct() { Id = Guid.NewGuid(); - ChildAssignmentGroups = new HashSet(); + ChildrenGroups = new HashSet(); AssignmentQuestions = new HashSet(); } } diff --git a/Entities/Contracts/ClassTeacher.cs b/Entities/Contracts/ClassTeacher.cs index 7974b37..3434624 100644 --- a/Entities/Contracts/ClassTeacher.cs +++ b/Entities/Contracts/ClassTeacher.cs @@ -22,6 +22,6 @@ namespace Entities.Contracts public User Teacher { get; set; } [Column("subject_taught")] - public string SubjectTaught { get; set; } + public SubjectAreaEnum SubjectTaught { get; set; } } } diff --git a/Entities/Contracts/Question.cs b/Entities/Contracts/Question.cs index a51e91d..16f80c9 100644 --- a/Entities/Contracts/Question.cs +++ b/Entities/Contracts/Question.cs @@ -16,36 +16,43 @@ namespace Entities.Contracts public Guid Id { get; set; } [Required] - [Column("question_text")] + [Column("title")] [MaxLength(65535)] - public string QuestionText { get; set; } + public string Title { get; set; } + + [Column("answer")] + [MaxLength(65535)] + public string? Answer { get; set; } + + [Column("description")] + public Guid? DescriptionId { get; set; } [Required] - [Column("question_type")] + [Column("type")] [MaxLength(20)] - public QuestionType QuestionType { get; set; } - - [Column("correct_answer")] - [MaxLength(65535)] - public string CorrectAnswer { get; set; } - - [Column("question_group_id")] - public Guid? QuestionGroupId { get; set; } + public QuestionType Type { get; set; } = QuestionType.Unknown; [Column("difficulty_level")] [MaxLength(10)] - public DifficultyLevel DifficultyLevel { get; set; } + public DifficultyLevel DifficultyLevel { get; set; } = DifficultyLevel.easy; [Column("subject_area")] - public SubjectAreaEnum SubjectArea { get; set; } + public SubjectAreaEnum SubjectArea { get; set; } = SubjectAreaEnum.Unknown; + [Column("options")] public string? Options { get; set; } + [Column("key_point")] + public Guid? KeyPointId { get; set; } + + [Column("lesson")] + public Guid? LessonId { get; set; } + + [Required] [Column("created_by")] - [ForeignKey("Creator")] - public Guid CreatedBy { get; set; } + public Guid CreatorId { get; set; } [Column("created_at")] public DateTime CreatedAt { get; set; } @@ -56,54 +63,30 @@ namespace Entities.Contracts [Column("deleted")] public bool IsDeleted { get; set; } - [Column("valid_question")] - public bool ValidQuestion { get; set; } // Navigation Properties + [ForeignKey(nameof(CreatorId))] public User Creator { get; set; } - public QuestionGroup QuestionGroup { get; set; } - public ICollection AssignmentQuestions { get; set; } + + [ForeignKey(nameof(DescriptionId))] + public QuestionContext Description { get; set; } + public Question? ParentQuestion { get; set; } + public ICollection? ChildrenQuestion { get; set; } + + [ForeignKey(nameof(KeyPointId))] + public KeyPoint? KeyPoint { get; set; } + [ForeignKey(nameof(LessonId))] + public Lesson? Lesson { get; set; } + + public ICollection? AssignmentQuestions { get; set; } public Question() { Id = Guid.NewGuid(); AssignmentQuestions = new HashSet(); + ChildrenQuestion = new HashSet(); } } - public enum DifficultyLevel - { - easy, - medium, - hard - } - public enum QuestionType - { - Unknown, // 可以有一个未知类型或作为默认 - Spelling, // 拼写 - Pronunciation, // 给带点字选择正确读音 - WordFormation, // 组词 - FillInTheBlanks, // 选词填空 / 补充词语 - SentenceDictation, // 默写句子 - SentenceRewriting, // 仿句 / 改写句子 - ReadingComprehension, // 阅读理解 - Composition // 作文 - // ... 添加您其他题目类型 - } - - public enum SubjectAreaEnum // 建议命名为 SubjectAreaEnum 以避免与属性名冲突 - { - Unknown, // 未知或默认 - Mathematics, // 数学 - Physics, // 物理 - Chemistry, // 化学 - Biology, // 生物 - History, // 历史 - Geography, // 地理 - Literature, // 语文/文学 - English, // 英语 - ComputerScience, // 计算机科学 - // ... 你可以根据需要添加更多科目 - } } diff --git a/Entities/Contracts/QuestionContext.cs b/Entities/Contracts/QuestionContext.cs new file mode 100644 index 0000000..ce4e7fc --- /dev/null +++ b/Entities/Contracts/QuestionContext.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Entities.Contracts +{ + public class QuestionContext + { + public Guid Id { get; set; } + + public string Description { get; set; } = string.Empty; + + [InverseProperty(nameof(Question.Description))] + public ICollection Questions { get; set; } = new List(); + + + public QuestionContext() + { + Questions = new HashSet(); + } + } +} diff --git a/Entities/Contracts/QuestionGroup.cs b/Entities/Contracts/QuestionGroup.cs deleted file mode 100644 index df6f656..0000000 --- a/Entities/Contracts/QuestionGroup.cs +++ /dev/null @@ -1,79 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations.Schema; -using System.ComponentModel.DataAnnotations; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Entities.Contracts -{ - [Table("question_groups")] - public class QuestionGroup - { - [Key] - [Column("id")] - public Guid Id { get; set; } - - [Column("title")] - [MaxLength(255)] - public string Title { get; set; } - - [Required] - [Column("description")] - [MaxLength(65535)] - public string Description { get; set; } - - [Column("type")] - [MaxLength(50)] - public string Type { get; set; } - - [Column("difficulty_level")] - [MaxLength(10)] - public DifficultyLevel DifficultyLevel { get; set; } - - [Column("subject_area")] - public SubjectAreaEnum SubjectArea { get; set; } - - [Column("total_questions")] - public int TotalQuestions { get; set; } = 0; - - [Column("parent_question_group")] - public Guid? ParentQG { get; set; } - - [Required] - [Column("created_by")] - [ForeignKey("Creator")] - public Guid CreatedBy { get; set; } - - [Column("created_at")] - public DateTime CreatedAt { get; set; } - - [Column("updated_at")] - public DateTime UpdatedAt { get; set; } - - [Column("deleted")] - public bool IsDeleted { get; set; } - - [Column("valid_group")] - public bool ValidGroup { get; set; } - - - - public User Creator { get; set; } - public QuestionGroup ParentQuestionGroup { get; set; } - public ICollection ChildQuestionGroups { get; set; } - public ICollection AssignmentQuestions { get; set; } - public ICollection Questions { get; set; } - - public QuestionGroup() - { - Id = Guid.NewGuid(); - Questions = new HashSet(); - CreatedAt = DateTime.UtcNow; - UpdatedAt = DateTime.UtcNow; - IsDeleted = false; - ValidGroup = true; - } - } -} diff --git a/Entities/Contracts/Submission.cs b/Entities/Contracts/Submission.cs index 30affba..832da6f 100644 --- a/Entities/Contracts/Submission.cs +++ b/Entities/Contracts/Submission.cs @@ -41,7 +41,7 @@ namespace Entities.Contracts [Column("graded_by")] [ForeignKey("Grader")] - public Guid? GradedBy { get; set; } + public Guid? GraderId { get; set; } [Column("graded_at")] public DateTime? GradedAt { get; set; } @@ -74,6 +74,5 @@ namespace Entities.Contracts Resubmission, // 待重新提交 (如果允许) Late, // 迟交 Draft, // 草稿 - // ... 添加你需要的其他状态 } } diff --git a/Entities/Contracts/SubmissionDetail.cs b/Entities/Contracts/SubmissionDetail.cs index eae0e4c..121b78f 100644 --- a/Entities/Contracts/SubmissionDetail.cs +++ b/Entities/Contracts/SubmissionDetail.cs @@ -23,7 +23,6 @@ namespace Entities.Contracts [Required] [Column("student_id")] - [ForeignKey("User")] public Guid StudentId { get; set; } [Required] @@ -52,8 +51,11 @@ namespace Entities.Contracts [Column("deleted")] public bool IsDeleted { get; set; } + [ForeignKey(nameof(StudentId))] + public User Student { get; set; } + public Submission Submission { get; set; } - public User User { get; set; } + public AssignmentQuestion AssignmentQuestion { get; set; } public SubmissionDetail() diff --git a/Entities/Contracts/Textbook/KeyPoint.cs b/Entities/Contracts/Textbook/KeyPoint.cs new file mode 100644 index 0000000..4f58dae --- /dev/null +++ b/Entities/Contracts/Textbook/KeyPoint.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Entities.Contracts +{ + [Table("key_point")] + public class KeyPoint + { + [Key] + public Guid Id { get; set; } + + [StringLength(255)] + public string Key { get; set; } = string.Empty; + + + [Required] + public Guid LessonID { get; set; } + + [ForeignKey(nameof(LessonID))] + public Lesson Lesson { get; set; } + + + public ICollection Questions { get; set; } + + public KeyPoint() + { + Id = Guid.NewGuid(); + Questions = new HashSet(); + } + } +} diff --git a/Entities/Contracts/Textbook/Lesson.cs b/Entities/Contracts/Textbook/Lesson.cs new file mode 100644 index 0000000..339689a --- /dev/null +++ b/Entities/Contracts/Textbook/Lesson.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Entities.Contracts +{ + [Table("lesson")] + public class Lesson + { + [Key] + public Guid Id { get; set; } + + [StringLength(255)] + public string Title { get; set; } = string.Empty; + + public string Description { get; set; } = string.Empty; + + [Required] + public Guid TextbookID { get; set; } + + + [ForeignKey(nameof(TextbookID))] + public Textbook Textbook { get; set; } + + [InverseProperty(nameof(KeyPoint.Lesson))] + public ICollection? KeyPoints { get; set; } + + [InverseProperty(nameof(Question.Lesson))] + public ICollection? Questions { get; set; } + + [InverseProperty(nameof(LessonQuestion.Lesson))] + public ICollection? LessonQuestions { get; set; } + + + + public Lesson() + { + Id = Guid.NewGuid(); + KeyPoints = new HashSet(); + Questions = new HashSet(); + LessonQuestions = new HashSet(); + } + } +} diff --git a/Entities/Contracts/Textbook/LessonQuestion.cs b/Entities/Contracts/Textbook/LessonQuestion.cs new file mode 100644 index 0000000..a498317 --- /dev/null +++ b/Entities/Contracts/Textbook/LessonQuestion.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Entities.Contracts +{ + [Table("lesson_question")] + public class LessonQuestion + { + [Key] + public Guid Id { get; set; } + + [MaxLength(65535)] + public string Question { get; set; } + + [Required] + public Guid LessonID { get; set; } + + [ForeignKey(nameof(LessonID))] + public Lesson Lesson { get; set; } + + public LessonQuestion() + { + Id = Guid.NewGuid(); + } + + } +} diff --git a/Entities/Contracts/Textbook/Textbook.cs b/Entities/Contracts/Textbook/Textbook.cs new file mode 100644 index 0000000..952f45b --- /dev/null +++ b/Entities/Contracts/Textbook/Textbook.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Entities.Contracts +{ + [Table("textbook")] + public class Textbook + { + [Key] + public Guid Id { get; set; } + + public Grade Grade { get; set; } = Grade.Unknown; + + public string Title { get; set; } = string.Empty; + + public Publisher Publisher { get; set; } = Publisher.部编版; + + public SubjectAreaEnum SubjectArea { get; set; } = SubjectAreaEnum.Unknown; + + [InverseProperty(nameof(Lesson.Textbook))] + public ICollection Lessons { get; set; } + + public Textbook() + { + Id = Guid.NewGuid(); + Lessons = new HashSet(); + } + } + +} diff --git a/Entities/DTO/AssignmentDto.cs b/Entities/DTO/AssignmentDto.cs new file mode 100644 index 0000000..9a9af91 --- /dev/null +++ b/Entities/DTO/AssignmentDto.cs @@ -0,0 +1,9 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Entities.DTO +{ +} diff --git a/Entities/DTO/AssignmentQuestionDto.cs b/Entities/DTO/AssignmentQuestionDto.cs new file mode 100644 index 0000000..c4f7980 --- /dev/null +++ b/Entities/DTO/AssignmentQuestionDto.cs @@ -0,0 +1,25 @@ +using Entities.Contracts; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Entities.DTO +{ + public class AssignmentQuestionDto + { + public float Score { get; set; } = 0; + public byte Index { get; set; } = 0; + public QuestionGroupState GroupState { get; set; } = QuestionGroupState.Standalone; + + + + public AssignmentQuestionDto? ParentAssignmentQuestion { get; set; } + public ICollection ChildrenAssignmentQuestion { get; set; } = new List(); + + + + public QuestionDto Question { get; set; } + } +} diff --git a/Entities/DTO/ExamDto.cs b/Entities/DTO/ExamDto.cs index c5b82d3..bda651c 100644 --- a/Entities/DTO/ExamDto.cs +++ b/Entities/DTO/ExamDto.cs @@ -1,4 +1,5 @@ -using System; +using Entities.Contracts; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -7,36 +8,88 @@ using System.Xml.Serialization; namespace Entities.DTO { + + public class AssignmentStructDto + { + public Guid Id { get; set; } = Guid.Empty; + public string Title { get; set; } = string.Empty; + public string Description { get; set; } = string.Empty; + public float Score { get; set; } = 0; + public byte Index { get; set; } = 0; + public Layout Layout { get; set; } = Layout.horizontal; + + + + + public ICollection AssignmentQuestions { get; set; } = new List(); + + public AssignmentStructDto? ParentStruct { get; set; } + public ICollection ChildrenGroups { get; set; } = new List(); + } + + public class AssignmentDto + { + public Guid Id { get; set; } = Guid.Empty; + public string Title { get; set; } = string.Empty; + public string Description { get; set; } = string.Empty; + + public byte TotalQuestions { get; set; } + public float Score { get; set; } = 0; + public SubjectAreaEnum SubjectArea { get; set; } = SubjectAreaEnum.Unknown; + public DateTime CreatedAt { get; set; } + public DateTime UpdatedAt { get; set; } + public DateTime DueDate { get; set; } + public Guid CreatorId { get; set; } + + public AssignmentStructDto ExamStruct { get; set; } = new AssignmentStructDto(); + } + + public class AssignmentClassDto + { + public AssignmentDto Assignment { get; set; } + public Class ClassId { get; set; } + public DateTime AssignedAt { get; set; } + } + + public class QuestionContextDto + { + public Guid Id { get; set; } = Guid.Empty; + public string Description { get; set; } = string.Empty; + } + + + + + public class ExamDto { public Guid? AssignmentId { get; set; } - public string CreaterEmail { get; set; } + public string CreaterEmail { get; set; } public string AssignmentTitle { get; set; } = string.Empty; public string Description { get; set; } public string SubjectArea { get; set; } - public QuestionGroupDto QuestionGroups { get; set; } = new QuestionGroupDto(); + public QuestionGroupDto ExamStruct { get; set; } = new QuestionGroupDto(); } public class QuestionGroupDto { - public byte Index { get; set; } + public byte Index { get; set; } public string? Title { get; set; } public float Score { get; set; } - public string? Descript { get; set; } + public string? Descript { get; set; } public List SubQuestions { get; set; } = new List(); public List SubQuestionGroups { get; set; } = new List(); - // 标记是否是一个具有上下文的单独问题 public bool ValidQuestionGroup { get; set; } = false; } public class SubQuestionDto { - public byte Index { get; set; } + public byte Index { get; set; } public string? Stem { get; set; } @@ -44,12 +97,11 @@ namespace Entities.DTO public List Options { get; set; } = new List(); - public string? SampleAnswer { get; set; } + public string? SampleAnswer { get; set; } - public string? QuestionType { get; set; } + public string? QuestionType { get; set; } public string? DifficultyLevel { get; set; } - // 标记是否是一个独立的问题 public bool ValidQuestion { get; set; } = false; } @@ -64,13 +116,13 @@ namespace Entities.DTO { public static void Convert(this ExamDto examDto) { - var qg = examDto.QuestionGroups; + var qg = examDto.ExamStruct; } public static void Convert(this QuestionGroupDto examDto) { - if(examDto.ValidQuestionGroup) + if (examDto.ValidQuestionGroup) { } diff --git a/Entities/DTO/QuestionDto.cs b/Entities/DTO/QuestionDto.cs new file mode 100644 index 0000000..ca2d4fe --- /dev/null +++ b/Entities/DTO/QuestionDto.cs @@ -0,0 +1,41 @@ +using Entities.Contracts; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Entities.DTO +{ + public class QuestionDto + { + public Guid Id { get; set; } = Guid.Empty; + + public string Title { get; set; } = string.Empty; + + public QuestionContextDto? Description { get; set; } + + public QuestionType Type { get; set; } = QuestionType.Unknown; + + public string? Answer { get; set; } = string.Empty; + + public string? Options { get; set; } + + public DifficultyLevel DifficultyLevel { get; set; } = DifficultyLevel.easy; + + public SubjectAreaEnum SubjectArea { get; set; } = SubjectAreaEnum.Unknown; + + public Guid CreatorId { get; set; } + + public Guid? KeyPointId { get; set; } + + public Guid? LessonId { get; set; } + + public DateTime CreatedAt { get; set; } + + public DateTime UpdatedAt { get; set; } = DateTime.Now; + + } +} diff --git a/TechHelper.Client/Exam/ExamPaperExtensions .cs b/TechHelper.Client/Exam/ExamPaperExtensions .cs index d4cb2e9..bea31f6 100644 --- a/TechHelper.Client/Exam/ExamPaperExtensions .cs +++ b/TechHelper.Client/Exam/ExamPaperExtensions .cs @@ -1,67 +1,173 @@ using Entities.DTO; using System.Text.Json.Serialization; using System.Text.Json; +using Entities.Contracts; +using Microsoft.Extensions.Options; namespace TechHelper.Client.Exam { + public class ParentStructInfo + { + public string Number { get; set; } + public SubjectAreaEnum SubjectArea { get; set; } + public byte Index { get; set; } + } + public static class ExamPaperExtensions { - public static ExamDto ConvertToExamDTO(this ExamPaper examPaper) + public static AssignmentDto ConvertToExamDTO(this ExamPaper examPaper) { - ExamDto dto = new ExamDto(); + AssignmentDto dto = new AssignmentDto(); - dto.AssignmentTitle = examPaper.AssignmentTitle; + dto.Title = examPaper.AssignmentTitle; dto.Description = examPaper.Description; - dto.SubjectArea = examPaper.SubjectArea; - dto.QuestionGroups.Title = examPaper.AssignmentTitle; - dto.QuestionGroups.Descript = examPaper.Description; + + var SubjectArea = SubjectAreaEnum.Literature; + Enum.TryParse(examPaper.SubjectArea, out SubjectArea); + dto.SubjectArea = SubjectArea; + + AssignmentStructDto examStruct = new AssignmentStructDto(); foreach (var qg in examPaper.QuestionGroups) { - var qgd = new QuestionGroupDto(); - ParseMajorQuestionGroup(qg, qgd, false); - dto.QuestionGroups.SubQuestionGroups.Add(qgd); + examStruct.ChildrenGroups.Add(ParseMajorQuestionGroup(qg)); + examStruct.ChildrenGroups.Last().Index = (byte)(examStruct.ChildrenGroups.Count()); } - - foreach (var question in examPaper.TopLevelQuestions) - { - if (question.SubQuestions != null && question.SubQuestions.Any()) - { - var qgDto = new QuestionGroupDto - { - Title = question.Stem, - Score = (int)question.Score, - Descript = "", - }; - - qgDto.ValidQuestionGroup = !string.IsNullOrEmpty(qgDto.Descript); - - - ParseQuestionWithSubQuestions(question, qgDto, qgDto.ValidQuestionGroup); - dto.QuestionGroups.SubQuestionGroups.Add(qgDto); - } - else - { - var qgDto = new QuestionGroupDto - { - Title = question.Stem, - Score = (int)question.Score, - Descript = "", - }; - - qgDto.ValidQuestionGroup = !string.IsNullOrEmpty(qgDto.Descript); - - var subQuestionDto = new SubQuestionDto(); - ParseSingleQuestion(question, subQuestionDto, !qgDto.ValidQuestionGroup); - qgDto.SubQuestions.Add(subQuestionDto); - dto.QuestionGroups.SubQuestionGroups.Add(qgDto); - } - } + dto.ExamStruct = examStruct; return dto; } + private static AssignmentStructDto ParseMajorQuestionGroup(MajorQuestionGroup sqg) + { + var examStruct = new AssignmentStructDto(); + + if (sqg.SubQuestionGroups != null) + { + + examStruct.Title = sqg.Title; + examStruct.Score = sqg.Score; + examStruct.ChildrenGroups = new List(); + sqg.SubQuestionGroups?.ForEach(ssqg => + { + if (string.IsNullOrEmpty(ssqg.Descript)) + { + examStruct.ChildrenGroups.Add(ParseMajorQuestionGroup(ssqg)); + examStruct.ChildrenGroups.Last().Index = (byte)(examStruct.ChildrenGroups.Count()); + } + else + { + examStruct.AssignmentQuestions.Add(ParseGroupToAssignmentQuestion(ssqg, false)); + examStruct.AssignmentQuestions.Last().Index = (byte)(examStruct.AssignmentQuestions.Count()); + } + + }); + + } + + + if (sqg.SubQuestions != null) + { + + sqg.SubQuestions?.ForEach(sq => + { + if(sq.SubQuestions.Any()) + { + + } + examStruct.AssignmentQuestions.Add(ParseAssignmentQuestion(sq)); + examStruct.AssignmentQuestions.Last().Index = (byte)(examStruct.AssignmentQuestions.Count()); + }); + } + + return examStruct; + } + + + public static List ParseOptionsFromText(this string optionsText) + { + return optionsText.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None) + .Where(line => !string.IsNullOrWhiteSpace(line)).ToList(); + } + + private static QuestionDto ParseGroupToQuestion(MajorQuestionGroup qg, bool subQ = true) + { + var dq = new QuestionDto(); + dq.Title = qg.Title + Environment.NewLine + qg.Descript; + + if (subQ) dq.GroupState = QuestionGroupState.Subquestion; + else dq.GroupState = QuestionGroupState.Group; + + qg.SubQuestions?.ForEach(ssq => + { + dq.ChildrenQuestion.Add(ParseQuestion(ssq)); + }); + + qg.SubQuestionGroups?.ForEach(sqg => + { + dq.ChildrenQuestion.Add(ParseGroupToQuestion(sqg)); + }); + + return dq; + } + + private static AssignmentQuestionDto ParseGroupToAssignmentQuestion(MajorQuestionGroup qg, bool subQ = true) + { + var aq = new AssignmentQuestionDto(); + aq.Score = qg.Score; + + qg.SubQuestions?.ForEach(ssq => + { + aq.Question.ChildrenQuestion.Add(ParseQuestion(ssq)); + aq.Question.ChildrenQuestion.Last().Index = (byte)aq.Question.ChildrenQuestion.Count; + }); + + qg.SubQuestionGroups?.ForEach(sqg => + { + aq.Question.ChildrenQuestion.Add(ParseGroupToQuestion(sqg)); + aq.Question.ChildrenQuestion.Last().Index = (byte)aq.Question.ChildrenQuestion.Count; + }); + + return aq; + } + + + private static AssignmentQuestionDto ParseAssignmentQuestion(PaperQuestion sq) + { + var aq = new AssignmentQuestionDto(); + aq.Score = sq.Score; + + aq.Question = ParseQuestion(sq); + + sq.SubQuestions?.ForEach(ssq => + { + + aq.Question.ChildrenQuestion.Add(ParseQuestion(ssq)); + aq.Question.ChildrenQuestion.Last().Index = (byte)aq.Question.ChildrenQuestion.Count; + + }); + + return aq; + } + + private static QuestionDto ParseQuestion(PaperQuestion sq) + { + var dq = new QuestionDto(); + dq.Title = sq.Stem; + dq.Options = string.Join(Environment.NewLine, sq.Options.Select(opt => $"{opt.Label} {opt.Text}")); + dq.Score = sq.Score; + + + sq.SubQuestions?.ForEach(ssq => + { + dq.ChildrenQuestion.Add(ParseQuestion(ssq)); + dq.ChildrenQuestion.Last().Index = (byte)dq.ChildrenQuestion.Count; + }); + + return dq; + } + private static void ParseMajorQuestionGroup(MajorQuestionGroup qg, QuestionGroupDto qgd, bool isParentGroupValidChain) { qgd.Title = qg.Title; @@ -86,12 +192,10 @@ namespace TechHelper.Client.Exam }); } - // 处理 MajorQuestionGroup 下的 SubQuestions if (qg.SubQuestions != null) { qg.SubQuestions.ForEach(sq => { - // 如果 MajorQuestionGroup 下的 Question 包含子问题,则转为 QuestionGroupDto if (sq.SubQuestions != null && sq.SubQuestions.Any()) { var subQgd = new QuestionGroupDto @@ -101,7 +205,6 @@ namespace TechHelper.Client.Exam Score = (int)sq.Score, Descript = "" // 默认为空 }; - // 判断当前组是否有效:如果有描述,并且其父级链中没有任何一个组是有效组,则当前组有效 subQgd.ValidQuestionGroup = !string.IsNullOrEmpty(subQgd.Descript) && !nextIsParentGroupValidChain; ParseQuestionWithSubQuestions(sq, subQgd, subQgd.ValidQuestionGroup || nextIsParentGroupValidChain); @@ -121,7 +224,7 @@ namespace TechHelper.Client.Exam // 解析包含子问题的 Question,将其转换为 QuestionGroupDto // isParentGroupValidChain 参数表示从顶层到当前组的任一父组是否已经是“有效组” - private static void ParseQuestionWithSubQuestions(Question question, QuestionGroupDto qgd, bool isParentGroupValidChain) + private static void ParseQuestionWithSubQuestions(PaperQuestion question, QuestionGroupDto qgd, bool isParentGroupValidChain) { qgd.Title = question.Stem; qgd.Score = (int)question.Score; @@ -165,7 +268,7 @@ namespace TechHelper.Client.Exam } // 解析单个 Question (没有子问题) 为 SubQuestionDto - private static void ParseSingleQuestion(Question question, SubQuestionDto subQd, bool validQ) + private static void ParseSingleQuestion(PaperQuestion question, SubQuestionDto subQd, bool validQ) { subQd.Stem = question.Stem; subQd.Score = (int)question.Score; @@ -187,7 +290,7 @@ namespace TechHelper.Client.Exam public static void SeqIndex(this ExamDto dto) { - dto.QuestionGroups.SeqQGroupIndex(); + dto.ExamStruct.SeqQGroupIndex(); } diff --git a/TechHelper.Client/Exam/ExamParse.cs b/TechHelper.Client/Exam/ExamParse.cs index a69c391..9aa9e1d 100644 --- a/TechHelper.Client/Exam/ExamParse.cs +++ b/TechHelper.Client/Exam/ExamParse.cs @@ -51,7 +51,7 @@ namespace TechHelper.Client.Exam public string Description { get; set; } = "未识别试卷描述"; public string SubjectArea { get; set; } = "试卷类别"; public List QuestionGroups { get; set; } = new List(); - public List TopLevelQuestions { get; set; } = new List(); + public List TopLevelQuestions { get; set; } = new List(); public List Errors { get; set; } = new List(); } @@ -61,17 +61,18 @@ namespace TechHelper.Client.Exam public string Descript { get; set; } = string.Empty; public float Score { get; set; } public List SubQuestionGroups { get; set; } = new List(); - public List SubQuestions { get; set; } = new List(); + public List SubQuestions { get; set; } = new List(); public int Priority { get; set; } + public bool bGroup { get; set; } = true; } - public class Question + public class PaperQuestion { public string Number { get; set; } = string.Empty; public string Stem { get; set; } = string.Empty; public float Score { get; set; } public List