重构项目结构,移除Assignment相关功能,优化Submission模块
Some checks failed
TechAct / explore-gitea-actions (push) Failing after 12s

This commit is contained in:
SpecialX
2025-10-09 18:57:28 +08:00
parent 403b34a098
commit ac900159ba
289 changed files with 11948 additions and 20150 deletions

View File

@@ -1,4 +1,4 @@
namespace TechHelper.Services
namespace Entities.DTO
{
public class ApiResponse
{
@@ -50,4 +50,4 @@
public object Result { get; set; }
}
}
}

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,33 +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 QuestionType Type { get; set; } = QuestionType.Unknown;
public string QType { get; set; } = string.Empty;
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

@@ -1,23 +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 GlobalDto
{
public SubjectAreaEnum SubjectArea { get; set; } = SubjectAreaEnum.Unknown;
public string Data { get; set; } = string.Empty;
}
public class QuestionDisplayTypeData
{
public string Color { get; set; }
public string DisplayName { 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,49 +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 QType { get; set; } = string.Empty;
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,21 +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<string, UInt32> ErrorQuestionTypes { get; set; } = new Dictionary<string, UInt32>();
public Dictionary<SubjectAreaEnum, UInt32> SubjectAreaErrorQuestionDis { get; set; } = new Dictionary<SubjectAreaEnum, UInt32>();
public Dictionary<byte, UInt32> LessonErrorDis { get; set; } = new Dictionary<byte, UInt32>();
public float Score { get; set; }
}
}

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

@@ -1,14 +0,0 @@
using System.ComponentModel.DataAnnotations;
using System.Collections.Generic;
using Entities.Contracts;
namespace Entities.DTO
{
public class SubjectTypeMetadataDto
{
public SubjectAreaEnum SubjectArea { get; set; } = SubjectAreaEnum.Unknown;
//public Dictionary<string, (string Color, string DisplayName)> Data = new Dictionary<string, (string Color, string DisplayName)>();
public string Data = string.Empty;
}
}

View File

@@ -16,7 +16,7 @@ namespace Entities.DTO
public SubmissionStatus Status { get; set; }
// Assignment信息
public AssignmentDto Assignment { get; set; } = new AssignmentDto();
public ExamDto Assignment { get; set; } = new ExamDto();
// 错误分析
public Dictionary<string, int> ErrorTypeDistribution { get; set; } = new Dictionary<string, int>();

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);
}

View File

@@ -0,0 +1,129 @@
using Entities.Contracts;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Entities.DTO
{
/// <summary>
/// 用户信息数据传输对象
/// 用于在API调用中传输用户的基本信息
/// </summary>
public record UserDto
{
/// <summary>
/// 用户唯一标识符
/// </summary>
public Guid Id { get; init; }
/// <summary>
/// 用户名
/// </summary>
public string? UserName { get; init; }
/// <summary>
/// 电子邮箱
/// </summary>
[EmailAddress]
public string? Email { get; init; }
/// <summary>
/// 手机号码
/// </summary>
[Phone]
public string? PhoneNumber { get; init; }
/// <summary>
/// 显示名称
/// </summary>
public string? DisplayName { get; init; }
/// <summary>
/// 家庭住址
/// </summary>
public string? HomeAddress { get; init; }
/// <summary>
/// 用户角色
/// </summary>
public UserRoles? Role { get; init; }
/// <summary>
/// 教授科目ID
/// </summary>
public Guid? TeachSubjectId { get; init; }
/// <summary>
/// 教授科目信息
/// </summary>
public SubjectDto? TeachSubject { get; init; }
/// <summary>
/// 用户加入的班级数量
/// </summary>
public int JoinedClassCount { get; init; }
/// <summary>
/// 创建的问题数量
/// </summary>
public int CreatedQuestionsCount { get; init; }
/// <summary>
/// 创建的考试数量
/// </summary>
public int CreatedExamsCount { get; init; }
/// <summary>
/// 提交的作业数量
/// </summary>
public int SubmittedAssignmentsCount { get; init; }
/// <summary>
/// 批改的作业数量
/// </summary>
public int GradedAssignmentsCount { get; init; }
/// <summary>
/// 用户创建时间
/// </summary>
public DateTime CreatedAt { get; init; }
/// <summary>
/// 用户最后更新时间
/// </summary>
public DateTime UpdatedAt { get; init; }
/// <summary>
/// 用户是否已验证邮箱
/// </summary>
public bool EmailConfirmed { get; init; }
/// <summary>
/// 用户是否已锁定
/// </summary>
public bool LockoutEnabled { get; init; }
/// <summary>
/// 用户锁定结束时间
/// </summary>
public DateTime? LockoutEnd { get; init; }
/// <summary>
/// 获取用户角色的显示名称
/// </summary>
public string? RoleDisplayName => Role?.GetDisplayName();
/// <summary>
/// 获取用户角色的简短名称
/// </summary>
public string? RoleShortName => Role?.GetShortName();
/// <summary>
/// 获取用户的基本信息字符串
/// </summary>
public string? UserInfoString => $"{DisplayName ?? UserName} ({Email})";
}
}

View File

@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Entities.DTO
{
public record UserForAdmin
{
public string Email { get; init; }
public string SchoolName { get; init; }
public string Password { get; init; }
public string DisplayName { get; init; }
public string Address { get; init; }
}
}

View File

@@ -0,0 +1,43 @@
using Entities.Contracts;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Entities.DTO
{
public class UserForRegistrationDto
{
[Required(ErrorMessage = "姓名是必填项。")]
[StringLength(50, MinimumLength = 2, ErrorMessage = "姓名长度必须在 2 到 50 个字符之间。")]
public string DisplayName { get; set; }
[Required(ErrorMessage = "电子邮件是必填项。")]
[EmailAddress(ErrorMessage = "电子邮件格式不正确。")]
public string Email { get; set; }
[Required(ErrorMessage = "密码是必填项。")]
[StringLength(100, MinimumLength = 6, ErrorMessage = "密码长度至少为 6 个字符。")]
[RegularExpression(@"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&.])[A-Za-z\d@$!%*?&.]{6,}$",
ErrorMessage = " @$!%*?&. ")]
public string Password { get; set; }
[Compare(nameof(Password), ErrorMessage = "密码和确认密码不匹配。")]
[Required(ErrorMessage = "确认密码是必填项。")]
public string ConfirmPassword { get; set; }
[Required(ErrorMessage = "至少选择一个角色。")]
public UserRoles Roles { get; set; } = UserRoles.Student;
[Phone(ErrorMessage = "电话号码格式不正确。")]
[StringLength(11, MinimumLength = 11, ErrorMessage = "电话号码必须是 11 位数字。")]
public string? PhoneNumber { get; set; }
[StringLength(200, ErrorMessage = "家庭住址不能超过 200 个字符。")]
public string? HomeAddress { get; set; }
public RegisterUserToClassDto RegisterUserToClassDto { get; set; } = new RegisterUserToClassDto();
}
}

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 UserListDto (Guid Id, string DisplayName, UserRoles Role, string Email, SubjectDto TeachSubject);
}

View File

@@ -0,0 +1,18 @@
using Entities.Contracts;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Entities.DTO
{
public class UserRegistrationToClassDto
{
public string User { get; set; } = string.Empty;
public byte ClassId { get; set; }
public byte GradeId { get; set; }
public UserRoles Roles { get; set; } = UserRoles.Student;
public SubjectAreaEnum SubjectArea { get; set; } = SubjectAreaEnum.Unknown;
}
}

View File

@@ -1,14 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Entities.DTO
{
public class UserClassRoleDto
{
public List<(byte, byte)> ClassInfo { get; set; } = new List<(byte, byte)> ();
public string Role { get; set; } = string.Empty;
}
}

View File

@@ -1,51 +0,0 @@
using Entities.Contracts;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Entities.DTO
{
public class UserForRegistrationDto
{
[Required(ErrorMessage = "姓名是必填项。")]
[StringLength(50, MinimumLength = 2, ErrorMessage = "姓名长度必须在 2 到 50 个字符之间。")]
public string Name { get; set; }
[Required(ErrorMessage = "电子邮件是必填项。")]
[EmailAddress(ErrorMessage = "电子邮件格式不正确。")] // 添加 Email 格式验证
public string Email { get; set; }
[Required(ErrorMessage = "密码是必填项。")]
[StringLength(100, MinimumLength = 6, ErrorMessage = "密码长度至少为 6 个字符。")] // 确保长度验证
[RegularExpression(@"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&.])[A-Za-z\d@$!%*?&.]{6,}$",
ErrorMessage = " @$!%*?&. ")]
public string Password { get; set; }
[Compare(nameof(Password), ErrorMessage = "密码和确认密码不匹配。")]
[Required(ErrorMessage = "确认密码是必填项。")] // 确保确认密码也必须填写
public string ConfirmPassword { get; set; }
[Required(ErrorMessage = "至少选择一个角色。")]
public UserRoles Roles { get; set; } = UserRoles.Student; // 根据你当前的 MudRadioGroup 设定,这里是单选
[Required(ErrorMessage = "班级是必填项。")]
[Range(1, 14, ErrorMessage = "班级编号必须在 1 到 14 之间。")] // 班级范围已调整为 1-14
public int Class { get; set; } = 1;
[Required(ErrorMessage = "年级是必填项。")]
[Range(1, 6, ErrorMessage = "年级编号必须在 1 到 6 之间。")] // 年级范围已调整为 1-6
public int Grade { get; set; } = 1;
[Phone(ErrorMessage = "电话号码格式不正确。")]
[StringLength(11, MinimumLength = 11, ErrorMessage = "电话号码必须是 11 位数字。")] // 电话号码长度已调整为固定 11 位
public string PhoneNumber { get; set; }
[StringLength(200, ErrorMessage = "家庭住址不能超过 200 个字符。")]
public string HomeAddress { get; set; }
public string ClientURI { get; set; }
}
}

View File

@@ -1,18 +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 UserRegistrationToClassDto
{
public string User { get; set; }
public byte ClassId { get; set; }
public byte GradeId { get; set; }
public UserRoles Roles { get; set; } = UserRoles.Student;
public SubjectAreaEnum SubjectArea { get; set; } = SubjectAreaEnum.Unknown;
}
}