from typing import List, Optional, Literal from pydantic import BaseModel, Field, validator from datetime import datetime class StudentQuery(BaseModel): student_no:str|None=Field(None,min_length=1,max_length=50,description="学生编号") student_name:str|None=Field(None,min_length=1,max_length=50,description="学生姓名") class_id:int|None=Field(None,ge=1,description="班级ID") page:int=Field(1,ge=1,description="页码") size:int=Field(5,ge=1,description="每页查询数量") class StudentCreate(BaseModel): student_no:str=Field(...,min_length=1,max_length=50,description="学生编号") student_name:str=Field(...,min_length=1,max_length=50,description="学生姓名") class_id:int=Field(...,ge=1,description="班级ID") flag: int = Field(..., description="0为已删除,1为存在") advisor_id:int=Field(...,description="顾问编号") native_place: str | None = Field(None, min_length=1, max_length=200) school: str | None = Field(None, min_length=1, max_length=100) major: str | None = Field(None, min_length=1, max_length=50) enrollment_time: datetime | None = Field(None, description="入学时间") graduation_time: datetime | None = Field(None, description="毕业时间") education: str | None = Field(None, min_length=1, max_length=100, description="学历") age: int | None = Field(None, gt=0, le=150, description="年龄") gender: str | None = Field(None, min_length=1, max_length=20, description="性别") state: str | None = Field(None, min_length=2, max_length=20, description="就业状态,状态(在读、进入就业、已就业)") class StudentUpdate(BaseModel): student_name:str=Field(...,min_length=1,max_length=50,description="学生姓名") class_id:int=Field(...,ge=1,description="班级ID") flag: int = Field(..., description="0为已删除,1为存在") advisor_id: int = Field(..., description="顾问编号") native_place:str|None=Field(None,min_length=1,max_length=200) school:str|None=Field(None,min_length=1,max_length=100) major:str|None =Field(None,min_length=1,max_length=50) enrollment_time:datetime|None =Field(None,description="入学时间") graduation_time:datetime|None =Field(None,description="毕业时间") education:str|None =Field(None,min_length=1,max_length=100,description="学历") age:int|None =Field(None,gt=0,le=150,description="年龄") gender:str|None =Field(None,min_length=1,max_length=20,description="性别") state:str|None=Field(None,min_length=2,max_length=20,description="就业状态,状态(在读、进入就业、已就业)") #===============================统计分析模块请求体=========================== #按年龄比较 class AgeQuery(BaseModel): operator: Literal["gt", "lt", "eq", "ge", "le", "between"] #限制值只能是这些 # 单值用 value: Optional[int] = None # 区间用 min_value: Optional[int] = None max_value: Optional[int] = None @validator("value", "min_value", "max_value", always=True) def check(cls, v, values): # 这里能拿到已经校验过的其他字段 op = values.get("operator") if op == "between": if values.get("min_value") is None or values.get("max_value") is None: raise ValueError("between 必须传 min_value 和 max_value") else: if values.get("value") is None: raise ValueError(f"{op} 必须传 value") return v #按照薪资固定排名查询 class TopNSalaryQuery(BaseModel): n: int = Field(10, ge=1, le=100, description="取前 N 名,1~100") #===============================统计分析模块响应体=========================== #按班级返回每个性别人数 class ClassGenderFlatItem(BaseModel): class_name: str class_total: int boys_count: int girls_count: int #每次考试都大于分数线的学生 class higherScoreResponse(BaseModel): stu_id: int stu_name: str stu_score: List[int] #每个学生就业时长 class workTimeResponse(BaseModel): name:str id: int work_time: int # 不及格次数大于指定次数 class failMoreResponse(BaseModel): stu_id: int stu_name: str class_name: str fail_scores: List[int] # 统计平均分,可以切换排序方式 class countAvgOrderResponse(BaseModel): score: int class_id: int class_name: str avg_score: float