Compare commits

6 Commits

Author SHA1 Message Date
SpecialX
ac900159ba 重构项目结构,移除Assignment相关功能,优化Submission模块
Some checks failed
TechAct / explore-gitea-actions (push) Failing after 12s
2025-10-09 18:57:28 +08:00
SpecialX
403b34a098 添加学校表和年级表,修改班级表结构 2025-09-12 14:32:14 +08:00
SpecialX
0d19ec6bb6 更新班级和学生相关功能
Some checks failed
TechAct / explore-gitea-actions (push) Failing after 6s
2025-09-12 11:31:50 +08:00
SpecialX
439c8a2421 feat: 添加学生提交系统功能
Some checks failed
TechAct / explore-gitea-actions (push) Failing after 30s
- 添加学生提交管理服务 (StudentSubmissionService, StudentSubmissionDetailService)
- 新增学生提交相关控制器 (StudentSubmissionController, StudentSubmissionDetailController)
- 添加学生提交数据传输对象 (StudentSubmissionDetailDto, StudentSubmissionSummaryDto)
- 新增学生提交相关页面组件 (StudentExamView, ExamDetailView, StudentCard等)
- 添加学生提交信息卡片组件 (SubmissionInfoCard, TeacherSubmissionInfoCard)
- 更新数据库迁移文件以支持提交系统
2025-09-09 15:42:31 +08:00
SpecialX
6a65281850 重构作业结构:优化实体模型、DTO映射和前端界面
Some checks failed
TechAct / explore-gitea-actions (push) Failing after 13s
- 重构AppMainStruct、AssignmentQuestion、Question等实体模型
- 更新相关DTO以匹配新的数据结构
- 优化前端页面布局和组件
- 添加全局信息和笔记功能相关代码
- 更新数据库迁移和程序配置
2025-09-04 15:43:33 +08:00
SpecialX
730b0ba04b Update ci.yaml
Some checks failed
TechAct / explore-gitea-actions (push) Failing after 6m0s
2025-08-31 11:35:41 +08:00
308 changed files with 14209 additions and 11561 deletions

View File

@@ -1,10 +1,10 @@
name: Tech
name: TechAct
on: [push] # 当有新的push事件发生时触发此工作流程
jobs:
explore-gitea-actions:
runs-on: Tech
runs-on: TechAct
steps:
- uses: actions/checkout@v4 # 使用actions/checkout来克隆您的仓库代码
- run: echo "💡 The ${{ gitea.repository }} repository has been cloned to the runner."

7
.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,7 @@
{
// 使用 IntelliSense 了解相关属性。
// 悬停以查看现有属性的描述。
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": []
}

View File

@@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
@@ -34,68 +36,133 @@ namespace Entities.Contracts
public enum DifficultyLevel : byte
{
simple,
easy,
medium,
hard
hard,
veryHard
}
public enum QuestionType : byte
public enum TypeNameType : byte
{
Unknown = 0,
Spelling, // 拼写
Pronunciation, // 给带点字选择正确读音
WordFormation, // 组词
FillInTheBlanks, // 选词填空 / 补充词语
SentenceDictation, // 默写句子
SentenceRewriting, // 仿句 / 改写句子
ReadingComprehension, // 阅读理解
Composition // 作文
Subject = 0,
QuestionType = 1,
ExamType = 2,
}
public enum SubjectAreaEnum : byte
{
[Display(Name = "未知", Description = "未知")]
Unknown = 0,
Mathematics, // 数学
Physics, // 物理
Chemistry, //
Biology, // 生物
History, // 历史
Geography, //
[Display(Name = "数学", Description = "数")]
Mathematics, //
[Display(Name = "物理", Description = "物")]
Physics, //
[Display(Name = "化学", Description = "化")]
Chemistry, // 化学
[Display(Name = "生物", Description = "生")]
Biology, // 生物
[Display(Name = "历史", Description = "史")]
History, // 历史
[Display(Name = "地理", Description = "地")]
Geography, // 地理
[Display(Name = "语文", Description = "语")]
Literature, // 语文/文学
English, // 英语
ComputerScience, // 计算机科学
[Display(Name = "英语", Description = "英")]
English, // 英语
[Display(Name = "计算机科学", Description = "计")]
ComputerScience // 计算机科学
}
public enum AssignmentStructType : byte
public enum ExamStructType : byte
{
[Display(Name = "根节点", Description = "根")]
Root,
[Display(Name = "单个问题", Description = "问")]
Question,
[Display(Name = "问题组", Description = "组")]
Group,
[Display(Name = "结构", Description = "结")]
Struct,
[Display(Name = "子问题", Description = "子")]
SubQuestion,
[Display(Name = "选项", Description = "选")]
Option
}
public enum ExamType : byte
public enum UserRoles
{
MidtermExam, // 期中
FinalExam, // 期末
MonthlyExam, // 月考
WeeklyExam, // 周考
DailyTest, // 平时测试
AITest, // AI测试
Student,
Teacher,
Admin
}
public enum SubmissionStatus
{
Pending, // 待提交/未开始
Submitted, // 已提交
Graded, // 已批改
Resubmission, // 待重新提交 (如果允许)
Late, // 迟交
Draft, // 草稿
[Display(Name = "待提交/未开始", Description = "待")]
Pending,
[Display(Name = "已提交", Description = "提")]
Submitted,
[Display(Name = "已批改", Description = "批")]
Graded,
[Display(Name = "待重新提交", Description = "重")]
Resubmission,
[Display(Name = "迟交", Description = "迟")]
Late,
[Display(Name = "草稿", Description = "草")]
Draft,
}
public static class EnumExtensions
{
public static string GetDisplayName(this Enum enumValue)
{
var fieldInfo = enumValue.GetType().GetField(enumValue.ToString());
if (fieldInfo == null)
{
return enumValue.ToString();
}
var displayAttribute = fieldInfo.GetCustomAttribute<DisplayAttribute>();
if (displayAttribute != null)
{
return displayAttribute.Name;
}
return enumValue.ToString();
}
public static string GetShortName(this Enum enumValue)
{
var memberInfo = enumValue.GetType().GetMember(enumValue.ToString()).FirstOrDefault();
if (memberInfo != null)
{
var displayAttribute = memberInfo.GetCustomAttribute<DisplayAttribute>();
if (displayAttribute != null && !string.IsNullOrEmpty(displayAttribute.Description))
{
return displayAttribute.Description;
}
}
return enumValue.ToString();
}
}
}

View File

@@ -1,36 +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("assignment_class")]
public class AssignmentClass
{
[Key]
[Column("assignment_id", Order = 0)]
[ForeignKey("Assignment")]
public Guid AssignmentId { get; set; }
[Key]
[Column("class_id", Order = 1)]
[ForeignKey("Class")]
public Guid ClassId { get; set; }
[Column("assigned_at")]
public DateTime AssignedAt { get; set; }
[Column("deleted")]
public bool IsDeleted { get; set; }
// Navigation Properties
public Assignment Assignment { get; set; }
public Class Class { get; set; }
}
}

View File

@@ -1,72 +0,0 @@
using Microsoft.EntityFrameworkCore;
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;
using Entities.DTO;
namespace Entities.Contracts
{
[Table("assignment_questions")]
public class AssignmentQuestion
{
[Key]
[Column("id")]
public Guid Id { get; set; }
[Column("question_id")]
public Guid? QuestionId { get; set; }
[Column("title")]
[MaxLength(1024)]
public string? Title { get; set; }
[Column("description")]
public Guid? QuestionContextId { get; set; }
[Required]
[Column("question_number")]
public byte Index { get; set; }
[Column("sequence")]
public string Sequence { get; set; } = string.Empty;
[Column("parent_question_group_id")]
public Guid? ParentAssignmentQuestionId { get; set; }
[Column("group_state")]
public AssignmentStructType StructType { get; set; } = AssignmentStructType.Question;
[Column("created_at")]
public DateTime CreatedAt { get; set; }
[Column("score")]
public float? Score { get; set; }
[Column("deleted")]
public bool IsDeleted { get; set; }
public Question? Question { get; set; }
public Assignment? Assignment { get; set; }
[ForeignKey(nameof(QuestionContextId))]
public QuestionContext? QuestionContext { get; set; }
public ICollection<SubmissionDetail> SubmissionDetails { get; set; }
[ForeignKey(nameof(ParentAssignmentQuestionId))]
public AssignmentQuestion? ParentAssignmentQuestion { get; set; }
public ICollection<AssignmentQuestion> ChildrenAssignmentQuestion { get; set; } = new List<AssignmentQuestion>();
public AssignmentQuestion()
{
Id = Guid.NewGuid();
SubmissionDetails = new HashSet<SubmissionDetail>();
}
}
}

View File

@@ -2,9 +2,6 @@
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
{
@@ -12,21 +9,25 @@ namespace Entities.Contracts
public class Class
{
[Key]
[Column("id")]
[Column("class_id")]
public Guid Id { get; set; }
[Column("grade")]
public byte Grade { get; set; }
[Column("grade_id")]
public Guid GradeId { get; set; }
[ForeignKey(nameof(GradeId))]
public virtual Grade Grade { get; set; }
[Column("class")]
public byte Number { get; set; }
[Column("index")]
public byte Index { get; set; }
[Column("description")]
public string Description { get; set; }
[Column("class_name")]
[MaxLength(30)]
public string ClassName { get; set; }
[Column("head_teacher_id")]
public Guid? HeadTeacherId { get; set; }
public User HeadTeacher { get; set; }
[ForeignKey(nameof(HeadTeacherId))]
public virtual User HeadTeacher { get; set; }
[Column("created_at")]
public DateTime CreatedAt { get; set; }
@@ -38,18 +39,22 @@ namespace Entities.Contracts
public bool IsDeleted { get; set; }
// Navigation Properties
public ICollection<ClassTeacher> ClassTeachers { get; set; }
public ICollection<ClassStudent> ClassStudents { get; set; }
public ICollection<AssignmentClass> AssignmentClasses { get; set; }
[NotMapped]
public ICollection<ClassUser> Techers => ClassUsers.Where(cu => cu.User.Role == UserRoles.Teacher).ToList();
[NotMapped]
public ICollection<ClassUser> Students => ClassUsers.Where(cu => cu.User.Role == UserRoles.Student).ToList();
[InverseProperty(nameof(ClassUser.Class))]
public virtual ICollection<ClassUser> ClassUsers { get; set; }
public Class()
{
Id = Guid.NewGuid();
Grade = 0;
Number = 0;
ClassStudents = new HashSet<ClassStudent>();
ClassTeachers = new HashSet<ClassTeacher>();
AssignmentClasses = new HashSet<AssignmentClass>();
ClassUsers = new HashSet<ClassUser>();
CreatedAt = DateTime.Now;
UpdatedAt = DateTime.Now;
}
}
}

View File

@@ -1,34 +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("class_student")]
public class ClassStudent
{
[Key]
[Column("class_id", Order = 0)]
[ForeignKey("Class")]
public Guid ClassId { get; set; }
[Key]
[Column("student_id", Order = 1)]
[ForeignKey("Student")]
public Guid StudentId { get; set; }
[Column("enrollment_date")]
public DateTime EnrollmentDate { get; set; }
[Column("deleted")]
public bool IsDeleted { get; set; }
// Navigation Properties
public Class Class { get; set; }
public User Student { get; set; }
}
}

View File

@@ -1,29 +0,0 @@
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("class_teachers")]
public class ClassTeacher
{
[Key]
[Column("class_id")]
public Guid ClassId { get; set; }
[ForeignKey(nameof(ClassId))]
public Class Class { get; set; }
[Key]
[Column("teacher_id")]
public Guid TeacherId { get; set; }
[ForeignKey(nameof(TeacherId))]
public User Teacher { get; set; }
[Column("subject_taught")]
public SubjectAreaEnum SubjectTaught { get; set; }
}
}

View File

@@ -0,0 +1,56 @@
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;
using Microsoft.EntityFrameworkCore;
namespace Entities.Contracts
{
/// <summary>
/// 班级用户关联实体类
/// 表示用户与班级之间的多对多关系
/// </summary>
[Table("class_user")]
[PrimaryKey(nameof(ClassId), nameof(UserId))]
public class ClassUser
{
/// <summary>
/// 班级ID复合主键的一部分外键
/// 关联到Class表中的班级
/// </summary>
[Key]
[Column("class_id", Order = 0)]
public Guid ClassId { get; set; }
[ForeignKey(nameof(ClassId))]
public virtual Class Class { get; set; }
/// <summary>
/// 用户ID复合主键的一部分外键
/// 关联到User表中的用户用户
/// </summary>
[Key]
[Column("student_id", Order = 1)]
public Guid UserId { get; set; }
[ForeignKey(nameof(UserId))]
public virtual User User { get; set; }
/// <summary>
/// 入学日期
/// 记录用户加入该班级的日期
/// </summary>
[Column("enrollment_date")]
public DateTime EnrollmentDate { get; set; }
/// <summary>
/// 是否已删除
/// 软删除标记true表示已删除
/// </summary>
[Column("deleted")]
public bool IsDeleted { get; set; }
}
}

View File

@@ -9,8 +9,8 @@ using Entities.DTO;
namespace Entities.Contracts
{
[Table("assignments")]
public class Assignment
[Table("exams")]
public class Exam
{
[Key]
[Column("id")]
@@ -24,12 +24,26 @@ namespace Entities.Contracts
[Column("description")]
public string Description { get; set; }
[Column("subject_area")]
public SubjectAreaEnum SubjectArea { get; set; }
[Column("subject_id")]
public Guid SubjectId { get; set; }
[ForeignKey(nameof(SubjectId))]
public virtual Subject Subject { get; set; }
[Required]
[Column("exam_struct_id")]
[ForeignKey(nameof(ExamStruct))]
public Guid ExamStructId { get; set; }
public virtual ExamQuestion ExamStruct { get; set; }
[Column("exam_type_id")]
public Guid ExamTypeId { get; set; }
[ForeignKey(nameof(ExamTypeId))]
public virtual ExamType ExamType { get; set; }
[Column("created_by")]
public Guid CreatorId { get; set; }
[ForeignKey(nameof(CreatorId))]
public virtual User Creator { get; set; }
[Required]
[Column("due_date")]
@@ -41,13 +55,9 @@ namespace Entities.Contracts
[Column("score")]
public float Score { get; set; }
[Column("name")]
public string Name { get; set; } = string.Empty;
public ExamType ExamType { get; set; } = ExamType.DailyTest;
[Column("created_by")]
public Guid CreatorId { get; set; }
[Column("created_at")]
public DateTime CreatedAt { get; set; }
@@ -57,61 +67,53 @@ namespace Entities.Contracts
[Column("deleted")]
public bool IsDeleted { get; set; } = false;
// Navigation Properties
[ForeignKey(nameof(CreatorId))]
public User Creator { get; set; }
public ICollection<AssignmentClass> AssignmentClasses { get; set; }
[InverseProperty(nameof(ExamAttachment.Exam))]
public virtual ICollection<ExamAttachment> ExamAttachments { get; set; }
[InverseProperty(nameof(Submission.Exam))]
public virtual ICollection<Submission> Submissions { get; set; }
[ForeignKey(nameof(ExamStructId))]
public AssignmentQuestion ExamStruct { get; set; }
public ICollection<AssignmentAttachment> AssignmentAttachments { get; set; }
public ICollection<Submission> Submissions { get; set; }
public Assignment()
public Exam()
{
Id = Guid.NewGuid();
ExamAttachments = new HashSet<ExamAttachment>();
Submissions = new HashSet<Submission>();
AssignmentClasses = new HashSet<AssignmentClass>();
AssignmentAttachments = new HashSet<AssignmentAttachment>();
}
}
public static class AssignmentExt
public static class examExt
{
public static Submission ConvertToSubmission(this Assignment assignment, Guid studentId, Guid GraderId)
public static Submission ConvertToSubmission(this Exam exam, Guid studentId, Guid GraderId, Guid classId)
{
if (assignment == null) return new Submission();
if (exam == null) return new Submission();
var submission = new Submission();
submission.StudentId = studentId;
submission.SubmissionTime = DateTime.Now;
submission.Status = SubmissionStatus.Pending;
submission.GraderId = GraderId;
submission.AssignmentId = assignment.Id;
ConvertExamSturctToSubmissionDetails(assignment.ExamStruct, studentId, submission.SubmissionDetails);
submission.ExamId = exam.Id;
submission.ClassId = classId;
ConvertExamSturctToSubmissionDetails(exam.ExamStruct, studentId, submission.SubmissionDetails);
return submission;
}
public static void ConvertExamSturctToSubmissionDetails(AssignmentQuestion examStruct, Guid studentId, ICollection<SubmissionDetail> submissions)
public static void ConvertExamSturctToSubmissionDetails(ExamQuestion examStruct, Guid studentId, ICollection<SubmissionDetail> submissions)
{
if (examStruct == null) return;
submissions.Add(new SubmissionDetail
{
StudentId = studentId,
AssignmentQuestionId = examStruct.Id,
IsCorrect = true,
ExamQuestionId = examStruct.Id,
CreatedAt = DateTime.Now,
UpdatedAt = DateTime.Now,
Status = SubmissionStatus.Pending,
});
examStruct.ChildrenAssignmentQuestion?.ToList().ForEach(s =>
examStruct.ChildExamQuestions?.ToList().ForEach(s =>
{
ConvertExamSturctToSubmissionDetails(s, studentId, submissions);
});

View File

@@ -9,17 +9,18 @@ using System.Diagnostics.CodeAnalysis;
namespace Entities.Contracts
{
[Table("assignment_attachments")]
public class AssignmentAttachment
[Table("exam_attachments")]
public class ExamAttachment
{
[Key]
[Column("id")]
public Guid Id { get; set; }
[Required]
[Column("assignment_id")]
[ForeignKey("Assignment")]
public Guid AssignmentId { get; set; }
[Column("exam_id")]
public Guid ExamId { get; set; }
[ForeignKey(nameof(ExamId))]
public virtual Exam Exam { get; set; }
[Required]
[Column("file_path")]
@@ -37,10 +38,7 @@ namespace Entities.Contracts
[Column("deleted")]
public bool IsDeleted { get; set; }
// Navigation Properties
public Assignment Assignment { get; set; }
public AssignmentAttachment()
public ExamAttachment()
{
Id = Guid.NewGuid();
}

View File

@@ -0,0 +1,71 @@
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;
using Entities.DTO;
namespace Entities.Contracts
{
[Table("exam_questions")]
public class ExamQuestion
{
[Key]
[Column("id")]
public Guid Id { get; set; }
[Column("title")]
[MaxLength(1024)]
public string? Title { get; set; }
[Column("question_id")]
public Guid? QuestionId { get; set; }
[ForeignKey(nameof(QuestionId))]
public virtual Question? Question { get; set; }
[Column("description")]
public Guid? QuestionContextId { get; set; }
[ForeignKey(nameof(QuestionContextId))]
public virtual QuestionContext? QuestionContext { get; set; }
[Required]
[Column("question_number")]
public byte Index { get; set; }
[Column("sequence")]
public string Sequence { get; set; } = string.Empty;
[Column("parent_question_group_id")]
public Guid? ParentExamQuestionId { get; set; }
[ForeignKey(nameof(ParentExamQuestionId))]
public virtual ExamQuestion? ParentExamQuestion { get; set; }
public Guid QuestionTypeId { get;set; }
[ForeignKey(nameof(QuestionTypeId))]
public virtual QuestionType Type { get; set; }
[Column("created_at")]
public DateTime CreatedAt { get; set; }
[Column("exam_struct_type")]
public ExamStructType ExamStructType { get; set; }
[Column("score")]
public float? Score { get; set; }
[Column("deleted")]
public bool IsDeleted { get; set; }
public virtual Exam? Exam { get; set; }
[InverseProperty(nameof(SubmissionDetail.ExamQuestion))]
public virtual ICollection<SubmissionDetail> SubmissionDetails { get; set; }
[InverseProperty(nameof(ParentExamQuestion))]
public virtual ICollection<ExamQuestion> ChildExamQuestions { get; set; } = new List<ExamQuestion>();
public ExamQuestion()
{
Id = Guid.NewGuid();
SubmissionDetails = new HashSet<SubmissionDetail>();
}
}
}

View File

@@ -0,0 +1,30 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Entities.Contracts
{
[Table("exam_type")]
public class ExamType
{
[Key]
[Column("id")]
public Guid Id { get; set; }
[Column("name")]
[MaxLength(20)]
public string Name { get; set; }
[Column("description")]
public string Description { get; set; }
[InverseProperty(nameof(Exam.ExamType))]
public virtual ICollection<Exam> Exams { get; set; }
public ExamType()
{
Id = Guid.NewGuid();
Exams = new HashSet<Exam>();
}
}
}

View File

@@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Entities.Contracts
{
[Table("grades")]
public class Grade
{
[Key]
[Column("grade_id")]
public Guid Id { get; set; }
[Column("school_id")]
public Guid SchoolId { get; set; }
public virtual School School { get; set; }
[Column("grade_name")]
[MaxLength(20)]
public string GradeName { get; set; }
[Column("grade_level")]
public byte GradeLevel { get; set; }
[InverseProperty(nameof(Class.Grade))]
public virtual ICollection<Class> Classes { get; set; }
public Grade()
{
Id = Guid.NewGuid();
Classes = new HashSet<Class>();
}
}
}

View File

@@ -24,34 +24,38 @@ namespace Entities.Contracts
[MaxLength(65535)]
public string? Answer { get; set; }
[Required]
[Column("type")]
[MaxLength(20)]
public QuestionType Type { get; set; } = QuestionType.Unknown;
[Column("difficulty_level")]
[MaxLength(10)]
public DifficultyLevel DifficultyLevel { get; set; } = DifficultyLevel.easy;
public Guid QuestioTypeId { get; set; }
[ForeignKey(nameof(QuestioTypeId))]
public virtual QuestionType QuestionType { get; set; }
[Column("subject_area")]
public SubjectAreaEnum SubjectArea { get; set; } = SubjectAreaEnum.Unknown;
[Column("options")]
public string? Options { get; set; }
public Guid SubjectId { get; set; }
[ForeignKey(nameof(SubjectId))]
public virtual Subject Subject { get; set; }
[Column("key_point")]
public Guid? KeyPointId { get; set; }
[ForeignKey(nameof(KeyPointId))]
public virtual KeyPoint? KeyPoint { get; set; }
[Column("lesson")]
public Guid? LessonId { get; set; }
[ForeignKey(nameof(LessonId))]
public virtual Lesson? Lesson { get; set; }
//[Required]
//[Column("created_by")]
//public Guid CreatorId { get; set; }
//[ForeignKey(nameof(CreatorId))]
//public virtual User Creator { get; set; }
[Required]
[Column("created_by")]
public Guid CreatorId { get; set; }
//[Column("difficulty_level")]
//public DifficultyLevel DifficultyLevel { get; set; } = DifficultyLevel.easy;
[Column("options")]
public string? Options { get; set; }
[Column("created_at")]
public DateTime CreatedAt { get; set; }
@@ -62,22 +66,13 @@ namespace Entities.Contracts
[Column("deleted")]
public bool IsDeleted { get; set; }
// Navigation Properties
[ForeignKey(nameof(CreatorId))]
public User Creator { get; set; }
[ForeignKey(nameof(KeyPointId))]
public KeyPoint? KeyPoint { get; set; }
[ForeignKey(nameof(LessonId))]
public Lesson? Lesson { get; set; }
public ICollection<AssignmentQuestion>? AssignmentQuestions { get; set; }
[InverseProperty(nameof(ExamQuestion.Question))]
public virtual ICollection<ExamQuestion>? ExamQuestions { get; set; }
public Question()
{
Id = Guid.NewGuid();
AssignmentQuestions = new HashSet<AssignmentQuestion>();
ExamQuestions = new HashSet<ExamQuestion>();
}
}

View File

@@ -13,13 +13,13 @@ namespace Entities.Contracts
public string Description { get; set; } = string.Empty;
[InverseProperty(nameof(AssignmentQuestion.QuestionContext))]
public ICollection<AssignmentQuestion>? Questions { get; set; } = new List<AssignmentQuestion>();
[InverseProperty(nameof(ExamQuestion.QuestionContext))]
public virtual ICollection<ExamQuestion>? Questions { get; set; } = new List<ExamQuestion>();
public QuestionContext()
{
Questions = new HashSet<AssignmentQuestion>();
Questions = new HashSet<ExamQuestion>();
}
}
}

View File

@@ -0,0 +1,40 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Entities.Contracts
{
[Table("question_types")]
public class QuestionType
{
[Key]
[Column("id")]
public Guid Id { get; set; }
[Column("name")]
[MaxLength(20)]
public string Name { get; set; }
[Column("subject_id")]
public Guid SubjectId { get; set; }
[ForeignKey(nameof(SubjectId))]
public virtual Subject Subject { get; set; }
[Column("description")]
public string Description { get; set; }
[Column("score_rule")]
[MaxLength(20)]
public string ScoreRule { get; set; }
[InverseProperty(nameof(Question.QuestionType))]
public virtual IEnumerable<Question> Questions { get; set; }
public QuestionType()
{
Id = Guid.NewGuid();
Questions = new HashSet<Question>();
}
}
}

View File

@@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Entities.Contracts
{
[Table("schools")]
public class School
{
[Key]
[Column("id")]
public Guid Id { get; set; }
[Column("school_name")]
[MaxLength(50)]
public string SchoolName { get; set; }
[Column("address")]
[MaxLength(100)]
public string Address { get; set; }
[Column("create_time")]
public DateTime CreateTime { get; set; }
[InverseProperty(nameof(Grade.School))]
public virtual ICollection<Grade> Grades { get; set; }
public School()
{
Id = Guid.NewGuid();
Grades = new HashSet<Grade>();
CreateTime = DateTime.Now;
}
}
}

View File

@@ -0,0 +1,36 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Entities.Contracts
{
[Table("subjects")]
public class Subject
{
[Key]
[Column("id")]
public Guid Id { get; set; }
[Column("name")]
[MaxLength(20)]
public string Name { get; set; }
[Column("description")]
public string Description { get; set; }
[InverseProperty(nameof(QuestionType.Subject))]
public virtual IEnumerable<QuestionType> QuestionTypes { get; set; }
[InverseProperty(nameof(Question.Subject))]
public virtual IEnumerable<Question> Questions { get; set; }
[InverseProperty(nameof(User.TeachSubject))]
public virtual IEnumerable<User> SubjectTeachers { get; set; }
public Subject()
{
Id = Guid.NewGuid();
QuestionTypes = new HashSet<QuestionType>();
Questions = new HashSet<Question>();
}
}
}

View File

@@ -17,53 +17,70 @@ namespace Entities.Contracts
public Guid Id { get; set; }
[Required]
[Column("assignment_id")]
[ForeignKey("Assignment")]
public Guid AssignmentId { get; set; }
[Column("exam_id")]
public Guid ExamId { get; set; }
[ForeignKey(nameof(ExamId))]
public virtual Exam Exam { get; set; }
[Required]
[Column("student_id")]
[ForeignKey("Student")]
public Guid StudentId { get; set; }
[ForeignKey(nameof(StudentId))]
public virtual User Student { get; set; }
[Column("graded_by")]
public Guid? GraderId { get; set; }
[ForeignKey(nameof(GraderId))]
public virtual User Grader { get; set; }
[Column("class_id")]
public Guid ClassId { get; set; }
[ForeignKey(nameof(ClassId))]
public virtual Class Class { get; set; }
[Required]
[Column("attempt_number")]
public byte AttemptNumber { get; set; }
public byte AttemptNumber { get; set; } // 第几次提交
[Column("submission_time")]
public DateTime SubmissionTime { get; set; }
[Column("overall_grade")]
public float? OverallGrade { get; set; }
public float OverallGrade { get; set; } = 0;
[Column("overall_feedback")]
public string? OverallFeedback { get; set; }
[Column("graded_by")]
[ForeignKey("Grader")]
public Guid? GraderId { get; set; }
[Column("graded_at")]
public DateTime? GradedAt { get; set; }
[Column("deleted")]
public bool IsDeleted { get; set; }
public byte TotalQuesNum { get; set; }
public byte ErrorQuesNum { get; set; }
public byte TotalScore { get; set; }
[Required]
[Column("status")]
public SubmissionStatus Status { get; set; }
[Column("deleted")]
public bool IsDeleted { get; set; }
// Navigation Properties
public Assignment Assignment { get; set; }
public User Student { get; set; }
public User Grader { get; set; }
public ICollection<SubmissionDetail> SubmissionDetails { get; set; }
[NotMapped]
public int ErrorCount => SubmissionDetails.Where(sd => sd?.IsCorrect == false && sd.IsCorrect != null).Count();
[NotMapped]
public Dictionary<string, int> ErrorQuestionTypeDistribution => SubmissionDetails
.Where(sd => sd?.IsCorrect == false)
.GroupBy(sd => sd.ExamQuestion.Type.Name)
.ToDictionary(g => g.Key, g => g.Count());
[NotMapped]
public Dictionary<string, int> ErrorQuestionLessonDistribution => SubmissionDetails
.Where(sd => sd?.IsCorrect == false && sd.ExamQuestion.Question?.Lesson != null)
.GroupBy(sd => sd.ExamQuestion.Question.Lesson.Title)
.ToDictionary(g => g.Key, g => g.Count());
[InverseProperty(nameof(SubmissionDetail.Submission))]
public virtual ICollection<SubmissionDetail> SubmissionDetails { get; set; }
public Submission()
{

View File

@@ -20,15 +20,20 @@ namespace Entities.Contracts
[Column("submission_id")]
[ForeignKey("Submission")]
public Guid SubmissionId { get; set; }
[ForeignKey(nameof(SubmissionId))]
public virtual Submission Submission { get; set; }
[Required]
[Column("student_id")]
public Guid StudentId { get; set; }
[ForeignKey(nameof(StudentId))]
public virtual User Student { get; set; }
[Required]
[Column("assignment_question_id")]
[ForeignKey("AssignmentQuestion")]
public Guid AssignmentQuestionId { get; set; }
[Column("exam_question_id")]
public Guid ExamQuestionId { get; set; }
[ForeignKey(nameof(ExamQuestionId))]
public virtual ExamQuestion ExamQuestion { get; set; }
[Column("student_answer")]
public string? StudentAnswer { get; set; }
@@ -37,7 +42,7 @@ namespace Entities.Contracts
public bool? IsCorrect { get; set; }
[Column("points_awarded")]
public float? PointsAwarded { get; set; } // score
public float? PointsAwarded { get; set; } // 得分
[Column("teacher_feedback")]
public string? TeacherFeedback { get; set; }
@@ -51,20 +56,6 @@ namespace Entities.Contracts
[Column("deleted")]
public bool IsDeleted { get; set; }
[Required]
[Column("status")]
public SubmissionStatus Status { get; set; }
[ForeignKey(nameof(StudentId))]
public User Student { get; set; }
[ForeignKey(nameof(SubmissionId))]
public Submission Submission { get; set; }
[ForeignKey(nameof(AssignmentQuestionId))]
public AssignmentQuestion AssignmentQuestion { get; set; }
public SubmissionDetail()
{

View File

@@ -18,14 +18,14 @@ namespace Entities.Contracts
public string Key { get; set; } = string.Empty;
[Required]
public Guid LessonID { get; set; }
[ForeignKey(nameof(LessonID))]
public Lesson Lesson { get; set; }
public virtual Lesson Lesson { get; set; }
public ICollection<Question> Questions { get; set; }
public virtual ICollection<Question> Questions { get; set; }
public KeyPoint()
{

View File

@@ -21,19 +21,19 @@ namespace Entities.Contracts
[Required]
public Guid TextbookID { get; set; }
[ForeignKey(nameof(TextbookID))]
public Textbook Textbook { get; set; }
public virtual Textbook Textbook { get; set; }
[InverseProperty(nameof(KeyPoint.Lesson))]
public ICollection<KeyPoint>? KeyPoints { get; set; }
public virtual ICollection<KeyPoint>? KeyPoints { get; set; }
[InverseProperty(nameof(Question.Lesson))]
public ICollection<Question>? Questions { get; set; }
public virtual ICollection<Question>? Questions { get; set; }
[InverseProperty(nameof(LessonQuestion.Lesson))]
public ICollection<LessonQuestion>? LessonQuestions { get; set; }
public virtual ICollection<LessonQuestion>? LessonQuestions { get; set; }

View File

@@ -19,9 +19,9 @@ namespace Entities.Contracts
[Required]
public Guid LessonID { get; set; }
[ForeignKey(nameof(LessonID))]
public Lesson Lesson { get; set; }
public virtual Lesson Lesson { get; set; }
public LessonQuestion()
{

View File

@@ -24,7 +24,7 @@ namespace Entities.Contracts
public SubjectAreaEnum SubjectArea { get; set; } = SubjectAreaEnum.Unknown;
[InverseProperty(nameof(Lesson.Textbook))]
public ICollection<Lesson> Lessons { get; set; }
public virtual ICollection<Lesson> Lessons { get; set; }
public Textbook()
{

View File

@@ -3,47 +3,57 @@ using System.ComponentModel.DataAnnotations.Schema;
namespace Entities.Contracts
{
public enum UserRoles
{
Student,
Teacher,
Administrator
}
public class User : IdentityUser<Guid>
{
public string? RefreshToken { get; set; }
public DateTime? RefreshTokenExpiryTime { get; set; }
public string? Address { get; set; }
public string? HomeAddress { get; set; }
public string? DisplayName { get; set; }
public UserRoles? Role { get; set; }
public Guid? TeachSubjectId { get; set; }
[ForeignKey(nameof(TeachSubjectId))]
public virtual Subject? TeachSubject { get; set; }
[Column("deleted")]
public bool IsDeleted { get; set; }
[InverseProperty(nameof(ClassTeacher.Teacher))]
public ICollection<ClassTeacher> TaughtClassesLink { get; set; }
[InverseProperty(nameof(ClassStudent.Student))]
public ICollection<ClassStudent> EnrolledClassesLink { get; set; }
[InverseProperty(nameof(ClassUser.User))]
public virtual ICollection<ClassUser> UserInjoinedClass { get; set; }
//[InverseProperty(nameof(Question.Creator))]
//public virtual ICollection<Question> CreatedQuestions { get; set; }
[InverseProperty(nameof(Exam.Creator))]
public virtual ICollection<Exam> CreatedExams { get; set; }
[InverseProperty(nameof(SubmissionDetail.Student))]
public virtual ICollection<SubmissionDetail> SubmissionDetails { get; set; }
[InverseProperty(nameof(Submission.Student))]
public virtual ICollection<Submission> StudentSubmissions { get; set; }
[InverseProperty(nameof(Submission.Grader))]
public virtual ICollection<Submission> GradedSubmissions { get; set; }
public ICollection<Question> CreatedQuestions { get; set; }
public ICollection<Assignment> CreatedAssignments { get; set; }
public ICollection<SubmissionDetail> SubmissionDetails { get; set; }
public ICollection<Submission> SubmissionsAsStudent { get; set; }
public ICollection<Submission> GradedSubmissions { get; set; }
public User()
{
Id = Guid.NewGuid();
SecurityStamp = Guid.NewGuid().ToString();
CreatedQuestions = new HashSet<Question>();
TaughtClassesLink = new HashSet<ClassTeacher>();
EnrolledClassesLink = new HashSet<ClassStudent>();
CreatedAssignments = new HashSet<Assignment>();
//CreatedQuestions = new HashSet<Question>();
UserInjoinedClass = new HashSet<ClassUser>();
CreatedExams = new HashSet<Exam>();
GradedSubmissions = new HashSet<Submission>();
SubmissionsAsStudent = new HashSet<Submission>();
StudentSubmissions = new HashSet<Submission>();
SubmissionDetails = new HashSet<SubmissionDetail>();
}
}
}

View File

@@ -1,4 +1,4 @@
namespace TechHelper.Services
namespace Entities.DTO
{
public class ApiResponse
{

View File

@@ -1,29 +0,0 @@
using Entities.Contracts;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Entities.DTO
{
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 string Name { get; set; } = string.Empty;
public ExamType ExamType { get; set; } = ExamType.DailyTest;
public AssignmentQuestionDto ExamStruct { get; set; } = new AssignmentQuestionDto();
}
}

View File

@@ -1,31 +0,0 @@
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 Guid Id { get; set; } = Guid.Empty;
public string Title { get; set; } = string.Empty;
public QuestionContextDto? Description { get; set; }
public byte Index { get; set; } = 0;
public float Score { get; set; } = 0;
public string Sequence { get; set; } = string.Empty;
public bool BCorrect { get; set; } = true;
public Layout Layout { get; set; } = Layout.horizontal;
public AssignmentStructType StructType { get; set; } = AssignmentStructType.Question;
public AssignmentQuestionDto? ParentAssignmentQuestion { get; set; }
public List<AssignmentQuestionDto> ChildrenAssignmentQuestion { get; set; } = new List<AssignmentQuestionDto>();
public QuestionDto? Question { get; set; }
}
}

View File

@@ -2,7 +2,7 @@
namespace Entities.DTO
{
public class UserForAuthenticationDto
public class UserForAuthenticationDto
{
[Required(ErrorMessage = "Email is required")]
public string? Email { get; set; }

View File

@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Entities.DTO.Class
{
public record ClassCreateDto
{
public CreateGradeDto Grade { get; init; }
[Required(ErrorMessage = "年级名称是必填项。")]
[StringLength(20, ErrorMessage = "年级名称不能超过 20 个字符。")]
public string ClassName { get; init; }
[Required(ErrorMessage = "年级级别是必填项。")]
public byte Index { get; init; }
}
}

View File

@@ -0,0 +1,25 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace Entities.DTO
{
public class ClassDto
{
public Guid Id { get; set; }
public Guid GradeId { get; set; }
public GradeDto Grade { get; set; }
[Required(ErrorMessage = "班级名称是必填项。")]
[StringLength(30, ErrorMessage = "班级名称不能超过 30 个字符。")]
public string ClassName { get; set; }
public byte Index { get; set; }
public Guid? HeadTeacherId { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
}
}

View File

@@ -0,0 +1,22 @@
using Entities.Contracts;
using System;
using System.Collections.Generic;
namespace Entities.DTO
{
public class ClassResponseDto
{
public Guid Id { get; set; }
public Guid GradeId { get; set; }
public string GradeName { get; set; }
public string ClassName { get; set; }
public Guid? HeadTeacherId { get; set; }
public string HeadTeacherName { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
public bool IsDeleted { get; set; }
// Navigation properties for response
public ICollection<ClassUserDto> ClassStudents { get; set; }
}
}

View File

@@ -0,0 +1,15 @@
using System;
namespace Entities.DTO
{
public class ClassUserDto
{
public Guid StudentId { get; set; }
public string? Email { get; set; }
public string? DisplayName { get; set; }
public string? PhoneNumber { get; set; }
public string? Address { get; set; }
public bool TwoFactorEnabled { get; set; }
public bool EmailConfirmed { get; set; }
}
}

View File

@@ -6,10 +6,5 @@ using System.Threading.Tasks;
namespace Entities.DTO
{
public class UserDto
{
public Guid Id { get; set; }
public string? DisplayName { get; set; }
}
public record ClassValidDto(string SchoolName, byte Grade, byte Class);
}

View File

@@ -0,0 +1,19 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace Entities.DTO
{
public class CreateClassDto
{
[Required(ErrorMessage = "年级ID是必填项。")]
public Guid GradeId { get; set; }
[Required(ErrorMessage = "班级名称是必填项。")]
[StringLength(30, ErrorMessage = "班级名称不能超过 30 个字符。")]
public string ClassName { get; set; }
public byte Index { get; set; }
public Guid? HeadTeacherId { get; set; }
}
}

View File

@@ -0,0 +1,18 @@
using Entities.Contracts;
using System;
using System.ComponentModel.DataAnnotations;
namespace Entities.DTO
{
public class RegisterUserToClassDto
{
public Guid UserId { get; set; }
public Guid ClassId { get; set; }
public UserRoles Role { get; set; } = UserRoles.Student;
public Guid? SubjectArea { get; set; }
}
}

View File

@@ -0,0 +1,20 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace Entities.DTO
{
public class UpdateClassDto
{
[Required(ErrorMessage = "班级ID是必填项。")]
public Guid ClassId { get; set; }
[Required(ErrorMessage = "年级ID是必填项。")]
public Guid GradeId { get; set; }
[Required(ErrorMessage = "班级名称是必填项。")]
[StringLength(30, ErrorMessage = "班级名称不能超过 30 个字符。")]
public string ClassName { get; set; }
public Guid? HeadTeacherId { get; set; }
}
}

View File

@@ -1,21 +0,0 @@
using System.ComponentModel.DataAnnotations;
namespace Entities.DTO
{
public class ClassDto
{
public byte Class { get; set; }
[StringLength(50, ErrorMessage = "班级名称不能超过 50 个字符。")]
public string Name { get; set; }
[Required(ErrorMessage = "年级是必填项。")]
[Range(1, 12, ErrorMessage = "年级编号必须在 1 到 12 之间。")]
public byte Grade { get; set; }
public string Description { get; set; } = "HELLO WORLD";
public int? HeadTeacherId { get; set; }
}
}

View File

@@ -6,10 +6,10 @@ using System.Threading.Tasks;
namespace Entities.DTO
{
public class QuestionContextDto
public class QueryParameterDto
{
public Guid Id { get; set; } = Guid.Empty;
public string Description { get; set; } = string.Empty;
public int PageIndex { get; set; }
public int PageSize { get; set; }
public string Search { get; set; }
}
}

View File

@@ -0,0 +1,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Entities.DTO
{
public record TypeCommonDto(Guid Id, string Name);
}

View File

@@ -0,0 +1,11 @@
using Entities.Contracts;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Entities.DTO
{
public record TypeCommonRequest(TypeNameType Type, Guid? SubjectId);
}

View File

@@ -9,7 +9,10 @@ namespace Entities.DTO
public class AssigExamToStudentsDto
{
public Guid CreaterId { get; set; }
public Guid AssignmentId { get; set; }
public Guid ExamId { get; set; }
public Guid ClassId { get; set; }
public List<Guid> StudentIds { get; set; } = new List<Guid>();
}
public record AssigExamToClassDto(Guid examId, Guid classId);
}

View File

@@ -12,8 +12,8 @@ namespace Entities.DTO
public class AssignmentClassDto
{
public AssignmentDto Assignment { get; set; }
public Class ClassId { get; set; }
public ExamDto Assignment { get; set; }
public ClassDto ClassId { get; set; }
public DateTime AssignedAt { get; set; }
}

View File

@@ -0,0 +1,35 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace Entities.DTO
{
public class CreateExamDto
{
[Required(ErrorMessage = "考试标题是必填项。")]
[StringLength(255, ErrorMessage = "考试标题不能超过 255 个字符。")]
public string Title { get; set; }
public string Description { get; set; }
[Required(ErrorMessage = "科目ID是必填项。")]
public Guid SubjectId { get; set; }
[Required(ErrorMessage = "考试结构ID是必填项。")]
public Guid ExamStructId { get; set; }
[Required(ErrorMessage = "考试类型ID是必填项。")]
public Guid ExamTypeId { get; set; }
[Required(ErrorMessage = "创建者ID是必填项。")]
public Guid CreatorId { get; set; }
[Required(ErrorMessage = "截止日期是必填项。")]
public DateTime DueDate { get; set; }
public byte TotalQuestions { get; set; }
public float Score { get; set; }
public string Name { get; set; }
}
}

View File

@@ -0,0 +1,44 @@
using Entities.Contracts;
using System;
using System.ComponentModel.DataAnnotations;
namespace Entities.DTO
{
public class ExamDto
{
public Guid Id { get; set; } = Guid.NewGuid();
[Required(ErrorMessage = "考试标题是必填项。")]
[StringLength(255, ErrorMessage = "考试标题不能超过 255 个字符。")]
public string Title { get; set; }
public string Description { get; set; }
public byte TotalQuestions { get; set; }
public float Score { get; set; }
public string Name { get; set; }
[Required(ErrorMessage = "截止日期是必填项。")]
public DateTime DueDate { get; set; }
public Guid SubjectId { get; set; }
public Guid ExamTypeId { get; set; }
public Guid CreatorId { get; set; }
//public Guid ExamStructId { get; set; }
public ExamQuestionDto ExamStruct { get; set; } = new ExamQuestionDto();
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
}
}

View File

@@ -0,0 +1,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Entities.DTO
{
public record ExamListDto(Guid Id, string Name);
}

View File

@@ -0,0 +1,33 @@
using Entities.Contracts;
namespace Entities.DTO
{
public class ExamQuestionDto
{
public Guid Id { get; set; } = Guid.NewGuid();
public string Title { get; set; } = string.Empty;
public float Score { get; set; } = 0;
public byte Index { get; set; } = 0;
public string Sequence { get; set; } = string.Empty;
public Guid QuestionTypeId { get; set; }
//public Guid? QuestionId { get; set; }
//public Guid? ParentExamQuestionId { get; set; }
public QuestionDto? Question { get; set; }
//public ExamQuestionDto? ParentExamQuestion { get; set; }
public ICollection<ExamQuestionDto> ChildExamQuestions { get; set; } = new List<ExamQuestionDto>();
// public Layout Layout { get; set; } = Layout.horizontal;
// public QuestionContextDto? Description { get; set; }
}
}

View File

@@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
namespace Entities.DTO
{
public class ExamResponseDto
{
public Guid Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public Guid SubjectId { get; set; }
public string SubjectName { get; set; }
public Guid ExamStructId { get; set; }
public string ExamStructName { get; set; }
public Guid ExamTypeId { get; set; }
public string ExamTypeName { get; set; }
public Guid CreatorId { get; set; }
public string CreatorName { get; set; }
public DateTime DueDate { get; set; }
public byte TotalQuestions { get; set; }
public float Score { get; set; }
public string Name { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
public bool IsDeleted { get; set; }
// Navigation properties for response
public int AttachmentCount { get; set; }
public int SubmissionCount { get; set; }
public List<string> AttachmentNames { get; set; } = new List<string>();
public List<string> StudentNames { get; set; } = new List<string>();
public List<DateTime> SubmissionTimes { get; set; } = new List<DateTime>();
}
}

View File

@@ -0,0 +1,38 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace Entities.DTO
{
public class UpdateExamDto
{
[Required(ErrorMessage = "考试ID是必填项。")]
public Guid Id { get; set; }
[Required(ErrorMessage = "考试标题是必填项。")]
[StringLength(255, ErrorMessage = "考试标题不能超过 255 个字符。")]
public string Title { get; set; }
public string Description { get; set; }
[Required(ErrorMessage = "科目ID是必填项。")]
public Guid SubjectId { get; set; }
[Required(ErrorMessage = "考试结构ID是必填项。")]
public Guid ExamStructId { get; set; }
[Required(ErrorMessage = "考试类型ID是必填项。")]
public Guid ExamTypeId { get; set; }
[Required(ErrorMessage = "创建者ID是必填项。")]
public Guid CreatorId { get; set; }
[Required(ErrorMessage = "截止日期是必填项。")]
public DateTime DueDate { get; set; }
public byte TotalQuestions { get; set; }
public float Score { get; set; }
public string Name { get; set; }
}
}

View File

@@ -0,0 +1,13 @@
using System.ComponentModel.DataAnnotations;
namespace Entities.DTO
{
public class CreateExamTypeDto
{
[Required(ErrorMessage = "考试类型名称是必填项。")]
[StringLength(20, ErrorMessage = "考试类型名称不能超过 20 个字符。")]
public string ExamTypeName { get; set; }
public string Description { get; set; }
}
}

View File

@@ -0,0 +1,16 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace Entities.DTO
{
public class ExamTypeDto
{
public Guid Id { get; set; }
[Required(ErrorMessage = "考试类型名称是必填项。")]
[StringLength(20, ErrorMessage = "考试类型名称不能超过 20 个字符。")]
public string Name { get; set; }
public string Description { get; set; }
}
}

View File

@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
namespace Entities.DTO
{
public class ExamTypeResponseDto
{
public Guid ExamId { get; set; }
public string ExamTypeName { get; set; }
public string Description { get; set; }
// Navigation properties for response
public int ExamCount { get; set; }
public List<string> ExamTitles { get; set; } = new List<string>();
}
}

View File

@@ -0,0 +1,17 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace Entities.DTO
{
public class UpdateExamTypeDto
{
[Required(ErrorMessage = "考试类型ID是必填项。")]
public Guid ExamTypeId { get; set; }
[Required(ErrorMessage = "考试类型名称是必填项。")]
[StringLength(20, ErrorMessage = "考试类型名称不能超过 20 个字符。")]
public string ExamTypeName { get; set; }
public string Description { get; set; }
}
}

View File

@@ -0,0 +1,17 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace Entities.DTO
{
public record CreateGradeDto
{
public Guid SchoolId { get; init; }
[Required(ErrorMessage = "年级名称是必填项。")]
[StringLength(20, ErrorMessage = "年级名称不能超过 20 个字符。")]
public string GradeName { get; init; }
[Required(ErrorMessage = "年级级别是必填项。")]
public byte GradeLevel { get; init; }
}
}

View File

@@ -0,0 +1,19 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace Entities.DTO
{
public class GradeDto
{
public Guid Id { get; set; }
public Guid SchoolId { get; set; }
[Required(ErrorMessage = "年级名称是必填项。")]
[StringLength(20, ErrorMessage = "年级名称不能超过 20 个字符。")]
public string GradeName { get; set; }
[Required(ErrorMessage = "年级级别是必填项。")]
public byte GradeLevel { get; set; }
}
}

View File

@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
namespace Entities.DTO
{
public class GradeResponseDto
{
public int Id { get; set; }
public int SchoolId { get; set; }
public string SchoolName { get; set; }
public string GradeName { get; set; }
public int GradeLevel { get; set; }
// Navigation properties for response
public ICollection<ClassDto> Responses { get; set; }
}
}

View File

@@ -0,0 +1,21 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace Entities.DTO
{
public class UpdateGradeDto
{
[Required(ErrorMessage = "年级ID是必填项。")]
public Guid Id { get; set; }
[Required(ErrorMessage = "学校ID是必填项。")]
public Guid SchoolId { get; set; }
[Required(ErrorMessage = "年级名称是必填项。")]
[StringLength(20, ErrorMessage = "年级名称不能超过 20 个字符。")]
public string GradeName { get; set; }
[Required(ErrorMessage = "年级级别是必填项。")]
public byte GradeLevel { get; set; }
}
}

View File

@@ -0,0 +1,14 @@
using System.ComponentModel.DataAnnotations;
namespace Entities.DTO
{
public record CreateKeyPointDto
{
[Required]
[StringLength(255)]
public string Key { get; init; } = string.Empty;
[Required]
public Guid LessonID { get; init; }
}
}

View File

@@ -0,0 +1,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Entities.DTO
{
public record KeyPointDto(Guid Id, string Key, Guid LessonId);
}

View File

@@ -0,0 +1,13 @@
using System;
namespace Entities.DTO
{
public record KeyPointResponseDto
{
public Guid Id { get; init; }
public string Key { get; init; } = string.Empty;
public Guid LessonID { get; init; }
public DateTime CreatedAt { get; init; }
public DateTime? UpdatedAt { get; init; }
}
}

View File

@@ -0,0 +1,17 @@
using System.ComponentModel.DataAnnotations;
namespace Entities.DTO
{
public record UpdateKeyPointDto
{
[Required]
public Guid Id { get; init; }
[Required]
[StringLength(255)]
public string Key { get; init; } = string.Empty;
[Required]
public Guid LessonID { get; init; }
}
}

View File

@@ -0,0 +1,17 @@
using System.ComponentModel.DataAnnotations;
namespace Entities.DTO
{
public class CreateLessonDto
{
[Required(ErrorMessage = "课程标题是必填项")]
[StringLength(255, ErrorMessage = "课程标题长度不能超过255个字符")]
public string Title { get; set; } = string.Empty;
[StringLength(1000, ErrorMessage = "课程描述长度不能超过1000个字符")]
public string Description { get; set; } = string.Empty;
[Required(ErrorMessage = "教材ID是必填项")]
public Guid TextbookID { get; set; }
}
}

View File

@@ -0,0 +1,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Entities.DTO
{
public record LessonDto(Guid Id, string Title, string Description, Guid TextBookId);
}

View File

@@ -0,0 +1,14 @@
using System;
namespace Entities.DTO
{
public class LessonResponseDto
{
public Guid Id { get; set; }
public string Title { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
public Guid TextbookID { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime? UpdatedAt { get; set; }
}
}

View File

@@ -0,0 +1,20 @@
using System.ComponentModel.DataAnnotations;
namespace Entities.DTO
{
public class UpdateLessonDto
{
[Required(ErrorMessage = "课程ID是必填项")]
public Guid Id { get; set; }
[Required(ErrorMessage = "课程标题是必填项")]
[StringLength(255, ErrorMessage = "课程标题长度不能超过255个字符")]
public string Title { get; set; } = string.Empty;
[StringLength(1000, ErrorMessage = "课程描述长度不能超过1000个字符")]
public string Description { get; set; } = string.Empty;
[Required(ErrorMessage = "教材ID是必填项")]
public Guid TextbookID { get; set; }
}
}

View File

@@ -0,0 +1,36 @@
using Entities.Contracts;
namespace Entities.DTO
{
public class QuestionDto
{
public Guid Id { get; set; } = Guid.NewGuid();
public string Title { get; set; } = string.Empty;
public string? Answer { get; set; } = string.Empty;
public string? Options { get; set; }
//public DifficultyLevel DifficultyLevel { get; set; } = DifficultyLevel.easy;
public Guid QuestioTypeId { get; set; }
public Guid SubjectId { get; set; }
//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;
}
}

View File

@@ -1,48 +0,0 @@
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 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;
}
/// <summary>
/// Can be removed because the class isn't used
/// </summary>
public class OptionDto
{
public string? Value { get; set; } = string.Empty;
}
}

View File

@@ -0,0 +1,19 @@
using System.ComponentModel.DataAnnotations;
namespace Entities.DTO
{
public class CreateQuestionTypeDto
{
[Required(ErrorMessage = "题型名称是必填项。")]
[StringLength(20, ErrorMessage = "题型名称不能超过 20 个字符。")]
public string TypeName { get; set; }
[Required(ErrorMessage = "科目ID是必填项。")]
public Guid SubjectId { get; set; }
public string Description { get; set; }
[StringLength(20, ErrorMessage = "评分规则不能超过 20 个字符。")]
public string ScoreRule { get; set; }
}
}

View File

@@ -0,0 +1,22 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace Entities.DTO
{
public class QuestionTypeDto
{
public Guid Id { get; set; }
[Required(ErrorMessage = "题型名称是必填项。")]
[StringLength(20, ErrorMessage = "题型名称不能超过 20 个字符。")]
public string Name { get; set; }
[Required(ErrorMessage = "科目ID是必填项。")]
public Guid SubjectId { get; set; }
public string Description { get; set; }
[StringLength(20, ErrorMessage = "评分规则不能超过 20 个字符。")]
public string ScoreRule { get; set; }
}
}

View File

@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
namespace Entities.DTO
{
public class QuestionTypeResponseDto
{
public Guid TypeId { get; set; }
public string TypeName { get; set; }
public Guid SubjectId { get; set; }
public string SubjectName { get; set; }
public string Description { get; set; }
public string ScoreRule { get; set; }
// Navigation properties for response
public int QuestionCount { get; set; }
public List<string> QuestionTitles { get; set; } = new List<string>();
}
}

View File

@@ -0,0 +1,23 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace Entities.DTO
{
public class UpdateQuestionTypeDto
{
[Required(ErrorMessage = "题型ID是必填项。")]
public Guid TypeId { get; set; }
[Required(ErrorMessage = "题型名称是必填项。")]
[StringLength(20, ErrorMessage = "题型名称不能超过 20 个字符。")]
public string TypeName { get; set; }
[Required(ErrorMessage = "科目ID是必填项。")]
public Guid SubjectId { get; set; }
public string Description { get; set; }
[StringLength(20, ErrorMessage = "评分规则不能超过 20 个字符。")]
public string ScoreRule { get; set; }
}
}

View File

@@ -0,0 +1,14 @@
using System.ComponentModel.DataAnnotations;
namespace Entities.DTO
{
public class CreateSchoolDto
{
[Required(ErrorMessage = "学校名称是必填项。")]
[StringLength(50, ErrorMessage = "学校名称不能超过 50 个字符。")]
public string SchoolName { get; set; }
[StringLength(100, ErrorMessage = "地址不能超过 100 个字符。")]
public string Address { get; set; }
}
}

View File

@@ -0,0 +1,19 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace Entities.DTO
{
public class SchoolDto
{
public Guid Id { get; set; }
[Required(ErrorMessage = "学校名称是必填项。")]
[StringLength(50, ErrorMessage = "学校名称不能超过 50 个字符。")]
public string SchoolName { get; set; }
[StringLength(100, ErrorMessage = "地址不能超过 100 个字符。")]
public string Address { get; set; }
public DateTime CreateTime { get; set; }
}
}

View File

@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
namespace Entities.DTO
{
public class SchoolResponseDto
{
public int SchoolId { get; set; }
public string SchoolName { get; set; }
public string Address { get; set; }
public DateTime CreateTime { get; set; }
// Navigation properties for response
public ICollection<GradeDto> Grades { get; set; }
}
}

View File

@@ -0,0 +1,18 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace Entities.DTO
{
public class UpdateSchoolDto
{
[Required(ErrorMessage = "学校ID是必填项。")]
public Guid SchoolId { get; set; }
[Required(ErrorMessage = "学校名称是必填项。")]
[StringLength(50, ErrorMessage = "学校名称不能超过 50 个字符。")]
public string SchoolName { get; set; }
[StringLength(100, ErrorMessage = "地址不能超过 100 个字符。")]
public string Address { get; set; }
}
}

View File

@@ -1,20 +0,0 @@
using Entities.Contracts;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Entities.DTO
{
public class StudentDto
{
public Guid Id { get; set; }
public string? DisplayName { get; set; }
public UInt32 ErrorQuestionNum { get; set; }
public Dictionary<QuestionType, UInt32> ErrorQuestionTypes { get; set; } = new Dictionary<QuestionType, UInt32>();
public Dictionary<SubjectAreaEnum, UInt32> SubjectAreaErrorQuestionDis { get; set; } = new Dictionary<SubjectAreaEnum, UInt32>();
public Dictionary<byte, UInt32> LessonErrorDis { get; set; } = new Dictionary<byte, UInt32>();
}
}

View File

@@ -0,0 +1,13 @@
using System.ComponentModel.DataAnnotations;
namespace Entities.DTO
{
public class CreateSubjectDto
{
[Required(ErrorMessage = "科目名称是必填项。")]
[StringLength(20, ErrorMessage = "科目名称不能超过 20 个字符。")]
public string SubjectName { get; set; }
public string Description { get; set; }
}
}

View File

@@ -0,0 +1,16 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace Entities.DTO
{
public class SubjectDto
{
public Guid Id { get; set; }
[Required(ErrorMessage = "科目名称是必填项。")]
[StringLength(20, ErrorMessage = "科目名称不能超过 20 个字符。")]
public string Name { get; set; }
public string Description { get; set; }
}
}

View File

@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
namespace Entities.DTO
{
public class SubjectResponseDto
{
public Guid Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
// Navigation properties for response
public int QuestionTypeCount { get; set; }
public int QuestionCount { get; set; }
public int TeacherCount { get; set; }
public List<string> QuestionTypeNames { get; set; } = new List<string>();
public List<string> TeacherNames { get; set; } = new List<string>();
}
}

View File

@@ -0,0 +1,17 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace Entities.DTO
{
public class UpdateSubjectDto
{
[Required(ErrorMessage = "科目ID是必填项。")]
public Guid SubjectId { get; set; }
[Required(ErrorMessage = "科目名称是必填项。")]
[StringLength(20, ErrorMessage = "科目名称不能超过 20 个字符。")]
public string SubjectName { get; set; }
public string Description { get; set; }
}
}

View File

@@ -0,0 +1,41 @@
using Entities.Contracts;
using System;
using System.Collections.Generic;
namespace Entities.DTO
{
public class StudentSubmissionDetailDto
{
// 基本信息
public Guid Id { get; set; }
public Guid AssignmentId { get; set; }
public Guid StudentId { get; set; }
public DateTime SubmissionTime { get; set; }
public float OverallGrade { get; set; }
public string OverallFeedback { get; set; } = string.Empty;
public SubmissionStatus Status { get; set; }
// Assignment信息
public ExamDto Assignment { get; set; } = new ExamDto();
// 错误分析
public Dictionary<string, int> ErrorTypeDistribution { get; set; } = new Dictionary<string, int>();
public Dictionary<string, float> ErrorTypeScoreDistribution { get; set; } = new Dictionary<string, float>();
// 成绩统计
public int TotalRank { get; set; }
public List<float> AllScores { get; set; } = new List<float>();
public float AverageScore { get; set; }
public float ClassAverageScore { get; set; }
// 课文分布
public Dictionary<string, int> LessonErrorDistribution { get; set; } = new Dictionary<string, int>();
public Dictionary<string, int> KeyPointErrorDistribution { get; set; } = new Dictionary<string, int>();
// 基础统计
public int TotalQuestions { get; set; }
public int CorrectCount { get; set; }
public int ErrorCount { get; set; }
public float AccuracyRate { get; set; }
}
}

View File

@@ -0,0 +1,22 @@
using System;
namespace Entities.DTO
{
public class StudentSubmissionSummaryDto
{
public Guid Id { get; set; }
public string AssignmentName { get; set; }
public int ErrorCount { get; set; }
public DateTime CreatedDate { get; set; }
public float Score { get; set; }
public int TotalQuestions { get; set; }
public string StudentName { get; set; }
public string Status { get; set; }
}
public class StudentSubmissionSummaryResponseDto
{
public List<StudentSubmissionSummaryDto> Submissions { get; set; }
public int TotalCount { get; set; }
}
}

View File

@@ -10,12 +10,12 @@ namespace Entities.DTO
public class SubmissionDetailDto
{
public Guid Id { get; set; } = Guid.Empty;
public Guid SubmissionId { get; set; }
public Guid StudentId { get; set; }
public Guid AssignmentQuestionId { get; set; }
public Guid ExamQuestionId { get; set; }
public string? StudentAnswer { get; set; }
public bool? IsCorrect { get; set; }
public float? PointsAwarded { get; set; }
public string? TeacherFeedback { get; set; }
public SubmissionStatus Status { get; set; } = SubmissionStatus.Graded;
}
}

View File

@@ -10,7 +10,7 @@ namespace Entities.DTO
public class SubmissionDto
{
public Guid Id { get; set; } = Guid.Empty;
public Guid AssignmentId { get; set; }
public Guid ExamId { get; set; }
public Guid StudentId { get; set; }
public DateTime SubmissionTime { get; set; }
public float OverallGrade { get; set; } = 0;

View File

@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Entities.DTO
{
public record SubmissionListDto
{
public Guid Id { get; init; }
public float OverallGrade { get; init; }
public int ErrorCount { get; init; }
public Dictionary<string, int>? ErrorQuestionTypeDistribution { get; init; }
public Dictionary<string, int>? ErrorQuestionLessonDistribution { get; init; }
public byte AttemptNumber { get; init; }
}
}

View File

@@ -0,0 +1,12 @@
using Entities.Contracts;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Entities.DTO
{
public record SubmissionDetailTeacherUpdateDto(Guid Id, bool IsCorrect, float? PointsAwarded);
public record SubmissionTeacherUpdateDto(Guid Id, float OverallGrade, string? OverallFeedback, SubmissionStatus Status, ICollection<SubmissionDetailTeacherUpdateDto> SubmissionUpdateDetails);
}

View File

@@ -0,0 +1,26 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace Entities.DTO
{
/// <summary>
/// 创建教材数据传输对象
/// </summary>
public class CreateTextbookDto
{
[Required(ErrorMessage = "教材标题是必填项。")]
[StringLength(100, ErrorMessage = "教材标题不能超过 100 个字符。")]
public string Title { get; set; }
[Required(ErrorMessage = "年级是必选项。")]
public string Grade { get; set; }
[Required(ErrorMessage = "出版社是必选项。")]
public string Publisher { get; set; }
[Required(ErrorMessage = "学科领域是必选项。")]
public string SubjectArea { get; set; }
public string Description { get; set; }
}
}

View File

@@ -0,0 +1,28 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace Entities.DTO
{
/// <summary>
/// 教材数据传输对象
/// </summary>
public class TextbookDto
{
public Guid Id { get; set; }
[Required(ErrorMessage = "教材标题是必填项。")]
[StringLength(100, ErrorMessage = "教材标题不能超过 100 个字符。")]
public string Title { get; set; }
[Required(ErrorMessage = "年级是必选项。")]
public string Grade { get; set; }
[Required(ErrorMessage = "出版社是必选项。")]
public string Publisher { get; set; }
[Required(ErrorMessage = "学科领域是必选项。")]
public string SubjectArea { get; set; }
public string Description { get; set; }
}
}

View File

@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
namespace Entities.DTO
{
/// <summary>
/// 教材响应数据传输对象
/// </summary>
public class TextbookResponseDto
{
public Guid Id { get; set; }
public string Title { get; set; }
public string Grade { get; set; }
public string Publisher { get; set; }
public string SubjectArea { get; set; }
public string Description { get; set; }
// 导航属性
public int LessonCount { get; set; }
public List<string> LessonTitles { get; set; } = new List<string>();
}
}

View File

@@ -0,0 +1,29 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace Entities.DTO
{
/// <summary>
/// 更新教材数据传输对象
/// </summary>
public class UpdateTextbookDto
{
[Required(ErrorMessage = "教材ID是必填项。")]
public Guid Id { get; set; }
[Required(ErrorMessage = "教材标题是必填项。")]
[StringLength(100, ErrorMessage = "教材标题不能超过 100 个字符。")]
public string Title { get; set; }
[Required(ErrorMessage = "年级是必选项。")]
public string Grade { get; set; }
[Required(ErrorMessage = "出版社是必选项。")]
public string Publisher { get; set; }
[Required(ErrorMessage = "学科领域是必选项。")]
public string SubjectArea { get; set; }
public string Description { get; set; }
}
}

View File

@@ -0,0 +1,21 @@
using Entities.Contracts;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Entities.DTO
{
public record StudentExamDetailDto
{
public Guid Id { get; init; }
public string? DisplayName { get; init; }
public uint ErrorQuestionNum { get; init; }
public Dictionary<string, uint> ErrorQuestionTypes { get; init; } = new Dictionary<string, uint>();
public Dictionary<SubjectAreaEnum, uint> SubjectAreaErrorQuestionDis { get; init; } = new Dictionary<SubjectAreaEnum, uint>();
public Dictionary<byte, uint> LessonErrorDis { get; init; } = new Dictionary<byte, uint>();
public float Score { get; init; }
}
}

View File

@@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Entities.DTO
{
public record UserClassDetailInfoDto(IEnumerable<UserClassInfoDto> UserClassInfos, string School);
public record UserClassInfoDto(Guid Id, byte Class, byte Grade);
}

Some files were not shown because too many files have changed in this diff Show More