569 lines
15 KiB
TypeScript
569 lines
15 KiB
TypeScript
/**
|
||
* UI_DTO.ts
|
||
* 前端数据传输对象(DTO)定义文件
|
||
* 包含所有前端与后端交互的接口定义
|
||
*/
|
||
|
||
// ============================================================
|
||
// 0. Common / 通用
|
||
// ============================================================
|
||
|
||
export interface ResultDto {
|
||
success: boolean;
|
||
message: string;
|
||
data?: any;
|
||
}
|
||
|
||
export interface PagedResult<T> {
|
||
items: T[];
|
||
totalCount: number;
|
||
pageIndex: number;
|
||
pageSize: number;
|
||
}
|
||
|
||
// ============================================================
|
||
// 1. Auth & User / 认证与用户
|
||
// ============================================================
|
||
|
||
export interface UserProfileDto {
|
||
id: string;
|
||
realName: string;
|
||
studentId: string;
|
||
avatarUrl: string;
|
||
gender: string;
|
||
schoolId: string;
|
||
role: 'Admin' | 'Teacher' | 'Student';
|
||
email?: string;
|
||
phone?: string;
|
||
bio?: string;
|
||
}
|
||
|
||
export interface RegisterDto {
|
||
realName: string;
|
||
studentId: string; // 学号/工号
|
||
password: string;
|
||
role: 'Teacher' | 'Student';
|
||
}
|
||
|
||
export interface UpdateProfileDto {
|
||
realName?: string;
|
||
email?: string;
|
||
phone?: string;
|
||
bio?: string;
|
||
}
|
||
|
||
export interface ChangePasswordDto {
|
||
oldPassword: string;
|
||
newPassword: string;
|
||
}
|
||
|
||
export interface LoginResultDto {
|
||
token: string;
|
||
user: UserProfileDto;
|
||
}
|
||
|
||
// ============================================================
|
||
// 2. Org / 组织架构
|
||
// ============================================================
|
||
|
||
export interface SchoolDto {
|
||
id: string;
|
||
name: string;
|
||
regionCode: string;
|
||
address: string;
|
||
}
|
||
|
||
/**
|
||
* 年级DTO
|
||
*/
|
||
export interface GradeDto {
|
||
id: string;
|
||
schoolId: string; // 所属学校ID
|
||
name: string; // 年级名称(如"2024级"或"初一")
|
||
sortOrder: number; // 排序序号(1=初一,2=初二)
|
||
enrollmentYear: number; // 入学年份
|
||
}
|
||
|
||
|
||
export interface ClassDto {
|
||
id: string;
|
||
name: string;
|
||
inviteCode: string;
|
||
gradeName: string;
|
||
teacherName: string;
|
||
studentCount: number;
|
||
}
|
||
|
||
export interface CreateClassDto {
|
||
name: string;
|
||
gradeName: string;
|
||
}
|
||
|
||
export interface ClassMemberDto {
|
||
id: string;
|
||
studentId: string;
|
||
realName: string;
|
||
avatarUrl: string;
|
||
gender: 'Male' | 'Female';
|
||
role: 'Student' | 'Monitor' | 'Committee'; // 班长/委员等
|
||
recentTrend: number[]; // Last 5 scores/performances
|
||
status: 'Active' | 'AtRisk' | 'Excellent';
|
||
attendanceRate: number;
|
||
}
|
||
|
||
export interface SchoolStructureDto {
|
||
school: SchoolDto;
|
||
grades: GradeNodeDto[];
|
||
}
|
||
|
||
export interface GradeNodeDto {
|
||
id: string;
|
||
name: string;
|
||
classes: ClassDto[];
|
||
}
|
||
|
||
// ============================================================
|
||
// 3. Curriculum / 课程体系
|
||
// ============================================================
|
||
|
||
export interface SubjectDto {
|
||
id: string;
|
||
name: string;
|
||
code: string;
|
||
icon?: string;
|
||
}
|
||
|
||
export interface TextbookDto {
|
||
id: string;
|
||
name: string;
|
||
publisher: string;
|
||
versionYear: string;
|
||
coverUrl: string;
|
||
}
|
||
|
||
/**
|
||
* 教材单元DTO
|
||
*/
|
||
export interface TextbookUnitDto {
|
||
id: string;
|
||
textbookId: string; // 所属教材ID
|
||
name: string; // 单元名称(如"第十一章 三角形")
|
||
sortOrder: number; // 排序序号
|
||
}
|
||
|
||
/**
|
||
* 课/小节DTO
|
||
*/
|
||
export interface TextbookLessonDto {
|
||
id: string;
|
||
unitId: string; // 所属单元ID
|
||
name: string; // 课名称(如"11.1 全等三角形")
|
||
sortOrder: number; // 排序序号
|
||
}
|
||
|
||
/**
|
||
* 知识点DTO(可嵌套)
|
||
*/
|
||
export interface KnowledgePointDto {
|
||
id: string;
|
||
lessonId: string; // 挂载课节ID
|
||
parentKnowledgePointId?: string; // 父知识点ID(支持大点套小点)
|
||
name: string; // 知识点名称
|
||
difficulty: number; // 难度系数(1-5星)
|
||
description?: string; // 描述/口诀
|
||
children?: KnowledgePointDto[]; // 子知识点
|
||
}
|
||
|
||
/**
|
||
* 课程树DTO(用于前端展示完整层级)
|
||
*/
|
||
export interface CurriculumTreeDto {
|
||
textbook: TextbookDto;
|
||
units: (TextbookUnitDto & {
|
||
lessons: (TextbookLessonDto & {
|
||
knowledgePoints: KnowledgePointDto[];
|
||
})[];
|
||
})[];
|
||
}
|
||
|
||
/**
|
||
* @deprecated 旧的通用节点定义,保留用于向后兼容
|
||
*/
|
||
export interface UnitNodeDto {
|
||
id: string;
|
||
name: string;
|
||
type: 'unit' | 'lesson' | 'point';
|
||
children?: UnitNodeDto[];
|
||
difficulty?: number;
|
||
}
|
||
|
||
// ============================================================
|
||
// 4. Question / 题库
|
||
// ============================================================
|
||
|
||
export interface QuestionSummaryDto {
|
||
id: string;
|
||
content: string; // HTML
|
||
type: string;
|
||
difficulty: number;
|
||
knowledgePoints: string[];
|
||
}
|
||
|
||
export interface ParsedQuestionDto {
|
||
content: string;
|
||
type: string;
|
||
options?: string[];
|
||
answer?: string;
|
||
parse?: string;
|
||
}
|
||
|
||
export interface QuestionFilterDto {
|
||
subjectId?: string;
|
||
type?: number;
|
||
difficulty?: number;
|
||
keyword?: string;
|
||
}
|
||
|
||
/**
|
||
* 题目-知识点关联DTO
|
||
*/
|
||
export interface QuestionKnowledgeDto {
|
||
id: string;
|
||
questionId: string; // 关联题目ID
|
||
knowledgePointId: string; // 关联知识点ID
|
||
weight: number; // 考察权重(0-100)
|
||
}
|
||
|
||
|
||
// ============================================================
|
||
// 5. Exam / 考试
|
||
// ============================================================
|
||
|
||
export interface ExamDto {
|
||
id: string;
|
||
subjectId: string; // 所属学科
|
||
title: string;
|
||
totalScore: number;
|
||
duration: number; // 建议时长(分钟)
|
||
questionCount: number; // 总题数
|
||
status: 'Draft' | 'Published';
|
||
createdAt: string;
|
||
}
|
||
|
||
/**
|
||
* 试卷节点DTO(可嵌套)
|
||
* 支持树形结构,既可以是分组节点(Group),也可以是题目节点(Question)
|
||
*/
|
||
export interface ExamNodeDto {
|
||
id: string; // 节点ID
|
||
nodeType: 'Group' | 'Question'; // 节点类型
|
||
|
||
// === 如果是Group节点 ===
|
||
title?: string; // 分组标题(如"第一部分 选择题")
|
||
description?: string; // 分组说明
|
||
|
||
// === 如果是Question节点 ===
|
||
questionId?: string; // 关联的题目ID
|
||
questionContent?: string; // 题干内容(冗余字段,方便显示)
|
||
questionType?: string; // 题目类型
|
||
|
||
// === 通用字段 ===
|
||
score: number; // 本节点分数(Group为子节点分数总和,Question为本题分数)
|
||
sortOrder: number; // 排序序号
|
||
|
||
// === 递归子节点 ===
|
||
children?: ExamNodeDto[]; // 子节点(支持无限嵌套)
|
||
}
|
||
|
||
/**
|
||
* 试卷详情DTO
|
||
* 使用树形结构代替固定的sections二层结构
|
||
*/
|
||
export interface ExamDetailDto extends ExamDto {
|
||
rootNodes: ExamNodeDto[]; // 根节点列表(树形结构)
|
||
}
|
||
|
||
export interface WrongQuestionAnalysisDto {
|
||
id: string;
|
||
content: string;
|
||
errorRate: number; // 0-100
|
||
difficulty: number;
|
||
type: string;
|
||
}
|
||
|
||
export interface ExamStatsDto {
|
||
averageScore: number;
|
||
passRate: number;
|
||
maxScore: number;
|
||
minScore: number;
|
||
scoreDistribution: { range: string; count: number }[];
|
||
wrongQuestions: WrongQuestionAnalysisDto[];
|
||
}
|
||
|
||
// ============================================================
|
||
// 6. Assignment / 作业
|
||
// ============================================================
|
||
|
||
export interface AssignmentTeacherViewDto {
|
||
id: string;
|
||
title: string;
|
||
className: string;
|
||
submittedCount: number;
|
||
totalCount: number;
|
||
status: 'Active' | 'Ended' | 'Scheduled';
|
||
dueDate: string;
|
||
examTitle: string;
|
||
}
|
||
|
||
export interface AssignmentStudentViewDto {
|
||
id: string;
|
||
title: string;
|
||
examTitle: string;
|
||
endTime: string;
|
||
status: 'Pending' | 'Graded' | 'Submitted';
|
||
score?: number;
|
||
}
|
||
|
||
// ============================================================
|
||
// 7. Submission / Student Exam / 提交与学生答题
|
||
// ============================================================
|
||
|
||
/**
|
||
* 学生答题卷DTO
|
||
* 使用ExamNode树形结构
|
||
*/
|
||
export interface StudentExamPaperDto {
|
||
examId: string;
|
||
title: string;
|
||
duration: number; // 分钟
|
||
totalScore: number;
|
||
rootNodes: ExamNodeDto[]; // 使用树形结构
|
||
}
|
||
|
||
/**
|
||
* 提交答案DTO
|
||
*/
|
||
export interface SubmitExamDto {
|
||
assignmentId: string;
|
||
answers: Record<string, any>; // key: examNodeId, value: 学生答案
|
||
timeSpent?: number; // 耗时(秒)
|
||
}
|
||
|
||
/**
|
||
* 答题详情DTO
|
||
* 记录学生对每个题目的作答和批改情况
|
||
*/
|
||
export interface SubmissionDetailDto {
|
||
id: string;
|
||
submissionId: string; // 所属提交ID
|
||
examNodeId: string; // 对应试卷节点ID
|
||
studentAnswer?: string; // 学生答案(文本或图片URL)
|
||
gradingData?: string; // 批改数据(JSON格式,Canvas画板数据)
|
||
score?: number; // 本题得分
|
||
judgement?: 'Correct' | 'Incorrect' | 'Partial'; // 判题结果
|
||
teacherComment?: string; // 老师评语
|
||
}
|
||
|
||
|
||
// ============================================================
|
||
// 8. Grading & Results / 批阅与结果
|
||
// ============================================================
|
||
|
||
export interface StudentSubmissionSummaryDto {
|
||
id: string; // submissionId
|
||
studentName: string;
|
||
studentId: string;
|
||
avatarUrl: string;
|
||
status: 'Submitted' | 'Graded' | 'Late';
|
||
score?: number;
|
||
submitTime: string;
|
||
}
|
||
|
||
export interface GradingPaperDto {
|
||
submissionId: string;
|
||
studentName: string;
|
||
nodes: GradingNodeDto[];
|
||
}
|
||
|
||
export interface GradingNodeDto {
|
||
examNodeId: string;
|
||
questionId: string;
|
||
questionContent: string;
|
||
questionType: string;
|
||
score: number; // max score
|
||
studentScore?: number; // current score
|
||
studentAnswer?: string; // Text or Image URL
|
||
teacherAnnotation?: string; // JSON for canvas
|
||
autoCheckResult?: boolean;
|
||
}
|
||
|
||
export interface StudentResultDto extends GradingPaperDto {
|
||
totalScore: number;
|
||
rank: number;
|
||
beatRate: number;
|
||
}
|
||
|
||
// ============================================================
|
||
// 9. Analytics / 分析统计
|
||
// ============================================================
|
||
|
||
export interface ChartDataDto {
|
||
labels: string[];
|
||
datasets: {
|
||
label: string;
|
||
data: number[];
|
||
borderColor?: string;
|
||
backgroundColor?: string;
|
||
fill?: boolean;
|
||
}[];
|
||
}
|
||
|
||
export interface RadarChartDto {
|
||
indicators: string[];
|
||
values: number[];
|
||
}
|
||
|
||
export interface ScoreDistributionDto {
|
||
range: string; // e.g. "90-100"
|
||
count: number;
|
||
}
|
||
|
||
// ============================================================
|
||
// 10. Common / Dashboard / 通用/仪表板
|
||
// ============================================================
|
||
|
||
export interface ScheduleDto {
|
||
id: string;
|
||
startTime: string;
|
||
endTime: string;
|
||
className: string;
|
||
subject: string;
|
||
room: string;
|
||
isToday: boolean;
|
||
dayOfWeek?: number; // 1 = Monday, 7 = Sunday
|
||
period?: number; // 1-8
|
||
}
|
||
|
||
export interface CreateScheduleDto {
|
||
subject: string;
|
||
className: string;
|
||
room: string;
|
||
dayOfWeek: number;
|
||
period: number;
|
||
startTime: string;
|
||
endTime: string;
|
||
}
|
||
|
||
// ============================================================
|
||
// 11. Messages / 消息
|
||
// ============================================================
|
||
|
||
export interface MessageDto {
|
||
id: string;
|
||
title: string;
|
||
content: string;
|
||
type: 'Announcement' | 'Notification' | 'Alert';
|
||
senderName: string;
|
||
senderAvatar?: string;
|
||
createdAt: string;
|
||
isRead: boolean;
|
||
}
|
||
|
||
export interface CreateMessageDto {
|
||
title: string;
|
||
content: string;
|
||
type: 'Announcement' | 'Notification';
|
||
targetClassIds?: string[]; // Optional: if empty, broadcast to all managed classes
|
||
}
|
||
|
||
// ============================================================
|
||
// 12. Services Interfaces / 服务接口定义
|
||
// ============================================================
|
||
|
||
export interface IAuthService {
|
||
login(username: string): Promise<LoginResultDto>;
|
||
register(data: RegisterDto): Promise<LoginResultDto>;
|
||
me(): Promise<UserProfileDto>;
|
||
updateProfile(data: UpdateProfileDto): Promise<UserProfileDto>;
|
||
changePassword(data: ChangePasswordDto): Promise<void>;
|
||
}
|
||
|
||
export interface IOrgService {
|
||
getClasses(role?: string): Promise<ClassDto[]>;
|
||
getClassMembers(classId: string): Promise<ClassMemberDto[]>;
|
||
joinClass(inviteCode: string): Promise<void>;
|
||
createClass(data: CreateClassDto): Promise<ClassDto>;
|
||
}
|
||
|
||
export interface ICurriculumService {
|
||
getSubjects(): Promise<SubjectDto[]>;
|
||
getTree(id: string): Promise<CurriculumTreeDto>;
|
||
getUnits(textbookId: string): Promise<TextbookUnitDto[]>;
|
||
getLessons(unitId: string): Promise<TextbookLessonDto[]>;
|
||
getKnowledgePoints(lessonId: string): Promise<KnowledgePointDto[]>;
|
||
}
|
||
|
||
export interface IQuestionService {
|
||
search(filter: any): Promise<PagedResult<QuestionSummaryDto & { answer?: string, parse?: string }>>;
|
||
parseText(rawText: string): Promise<ParsedQuestionDto[]>;
|
||
getQuestionKnowledges(questionId: string): Promise<QuestionKnowledgeDto[]>;
|
||
}
|
||
|
||
export interface IExamService {
|
||
getMyExams(): Promise<PagedResult<ExamDto>>;
|
||
getExamDetail(id: string): Promise<ExamDetailDto>;
|
||
saveExam(exam: ExamDetailDto): Promise<void>;
|
||
getStats(id: string): Promise<ExamStatsDto>;
|
||
}
|
||
|
||
export interface IAssignmentService {
|
||
getTeachingAssignments(): Promise<PagedResult<AssignmentTeacherViewDto>>;
|
||
getStudentAssignments(): Promise<PagedResult<AssignmentStudentViewDto>>;
|
||
publishAssignment(data: any): Promise<void>;
|
||
getAssignmentStats(id: string): Promise<ExamStatsDto>;
|
||
}
|
||
|
||
export interface IAnalyticsService {
|
||
getClassPerformance(): Promise<ChartDataDto>;
|
||
getStudentGrowth(): Promise<ChartDataDto>;
|
||
getRadar(): Promise<RadarChartDto>;
|
||
getStudentRadar(): Promise<RadarChartDto>;
|
||
getScoreDistribution(): Promise<ScoreDistributionDto[]>;
|
||
}
|
||
|
||
export interface IGradingService {
|
||
getSubmissions(assignmentId: string): Promise<StudentSubmissionSummaryDto[]>;
|
||
getPaper(submissionId: string): Promise<GradingPaperDto>;
|
||
saveGrading(submissionId: string, details: SubmissionDetailDto[]): Promise<void>;
|
||
}
|
||
|
||
export interface ISubmissionService {
|
||
getStudentPaper(assignmentId: string): Promise<StudentExamPaperDto>;
|
||
submitExam(data: SubmitExamDto): Promise<void>;
|
||
getSubmissionResult(assignmentId: string): Promise<StudentResultDto>;
|
||
getSubmissionDetails(submissionId: string): Promise<SubmissionDetailDto[]>;
|
||
}
|
||
|
||
|
||
export interface ICommonService {
|
||
getSchedule(): Promise<ScheduleDto[]>;
|
||
}
|
||
|
||
export interface IMessageService {
|
||
getMessages(): Promise<MessageDto[]>;
|
||
markAsRead(id: string): Promise<void>;
|
||
createMessage(data: CreateMessageDto): Promise<void>;
|
||
}
|
||
|
||
export interface IScheduleService {
|
||
getWeekSchedule(): Promise<ScheduleDto[]>;
|
||
addEvent(data: CreateScheduleDto): Promise<void>;
|
||
deleteEvent(id: string): Promise<void>;
|
||
}
|
||
|
||
// ============================================================
|
||
// 13. UI Types / UI类型定义
|
||
// ============================================================
|
||
|
||
export type ViewState = 'login' | 'dashboard' | 'curriculum' | 'questions' | 'classes' | 'exams' | 'assignments' | 'settings' | 'grading' | 'student-exam' | 'student-result' | 'messages' | 'schedule';
|