from typing import Optional, List from datetime import datetime from decimal import Decimal from pydantic import BaseModel, Field # ===== Common ===== class DeletedAt(BaseModel): is_deleted: bool = False delete_time: Optional[datetime] = None # ===== Teacher ===== class TeacherCreate(BaseModel): num: str name: str age: int = 18 sex: int = 0 home_place: Optional[str] = None college: Optional[str] = None specialty: Optional[str] = None enrollment_time: Optional[datetime] = None graduate_time: Optional[datetime] = None education: Optional[str] = None work_experience: Optional[str] = None coach_area: Optional[str] = None class TeacherUpdate(BaseModel): name: Optional[str] = None age: Optional[int] = None sex: Optional[int] = None home_place: Optional[str] = None college: Optional[str] = None specialty: Optional[str] = None enrollment_time: Optional[datetime] = None graduate_time: Optional[datetime] = None education: Optional[str] = None work_experience: Optional[str] = None coach_area: Optional[str] = None class TeacherBase(TeacherCreate): id: int create_time: datetime update_time: datetime # ===== Class ===== class ClassCreate(BaseModel): num: str name: str class_start_time: Optional[datetime] = None head_teacher_id: Optional[int] = None coach_teacher_id: Optional[int] = None tutor_teacher_id: Optional[int] = None class ClassUpdate(BaseModel): name: Optional[str] = None class_start_time: Optional[datetime] = None head_teacher_id: Optional[int] = None coach_teacher_id: Optional[int] = None tutor_teacher_id: Optional[int] = None class ClassBase(ClassCreate): id: int create_time: datetime update_time: datetime head_teacher: Optional[TeacherBase] = None coach_teacher: Optional[TeacherBase] = None tutor_teacher: Optional[TeacherBase] = None # ===== Student ===== class StudentCreate(BaseModel): num: str name: str age: int = 18 sex: int = 0 home_place: Optional[str] = None college: Optional[str] = None specialty: Optional[str] = None enrollment_time: Optional[datetime] = None graduate_time: Optional[datetime] = None education: Optional[str] = None class_id: int advisor_id: Optional[int] = None class StudentUpdate(BaseModel): name: Optional[str] = None age: Optional[int] = None sex: Optional[int] = None home_place: Optional[str] = None college: Optional[str] = None specialty: Optional[str] = None enrollment_time: Optional[datetime] = None graduate_time: Optional[datetime] = None education: Optional[str] = None class_id: Optional[int] = None advisor_id: Optional[int] = None class StudentBase(StudentCreate): id: int create_time: datetime update_time: datetime class_info: Optional[ClassBase] = None advisor_info: Optional[TeacherBase] = None # ===== Score ===== class ScoreCreate(BaseModel): sid: int num: str score: Decimal class ScoreUpdate(BaseModel): score: Decimal class ScoreBase(ScoreCreate): id: int create_time: datetime update_time: datetime # ===== Employment ===== class EmploymentCreate(BaseModel): sid: int class_id: int employment_open_time: Optional[datetime] = None offer_recived_time: Optional[datetime] = None employment_company: Optional[str] = None employment_salary: Optional[Decimal] = None class EmploymentUpdate(BaseModel): employment_open_time: Optional[datetime] = None offer_recived_time: Optional[datetime] = None employment_company: Optional[str] = None employment_salary: Optional[Decimal] = None class EmploymentBase(EmploymentCreate): id: int create_time: datetime update_time: datetime student_info: Optional[StudentBase] = None # ===== Stats ===== class ClassStats(BaseModel): class_id: int class_name: str total_students: int male_count: int female_count: int class ScoreStats(BaseModel): score_num: str class_id: Optional[int] avg_score: float max_score: float min_score: float count: int class EmploymentStats(BaseModel): class_id: int class_name: str employed_count: int total_count: int avg_salary: Optional[float] avg_duration_days: Optional[float]