#统计分析模块 入参/出参定义 from datetime import datetime from enum import Enum from typing import Optional, List from pydantic import BaseModel, ConfigDict from model.wl_score_model import Score # ---- 入参:动态查询的比较条件 ---- class AgeCompareOp(str, Enum): """年龄比较条件:大于/大于等于/小于/小于等于/等于/区间""" gt = "gt" ge = "ge" lt = "lt" le = "le" eq = "eq" between = "between" class SortOrder(str, Enum): """排序方向:升序/降序""" asc = "asc" desc = "desc" # ---- 出参:后续统计接口的聚合结果 DTO 放这里 ---- class ClassGenderStatOut(BaseModel): """班级多维度统计:总人数 + 男女分布""" class_id: Optional[int] = None total: int = 0 male_count: int = 0 female_count: int = 0 class ScoreShow(BaseModel): exam_order:int=0 score:float=0 class ScoreOutLine(BaseModel): stu_no:str='' stu_name:str='' scores:List[ScoreShow]=[] class FailCountModel(BaseModel): stu_name:str='' class_id:int=0 scores:List[ScoreShow]=[] class ClassAvgScoreOut(BaseModel): """每次考试每个班级的平均分""" # DAO 返回的是 SQLAlchemy Row 对象,必须开 from_attributes 才能按属性名读取 model_config = ConfigDict(from_attributes=True) class_id:Optional[int]=None exam_order:Optional[int]=None avg_score:Optional[float]=None class EmpTopOut(BaseModel): """就业薪资排名 Top N""" # 同样是 Row 对象,必须开 from_attributes model_config = ConfigDict(from_attributes=True) stu_name:Optional[str]=None class_id:Optional[int]=None offer_time:Optional[datetime]=None company_name:Optional[str]=None # 接口是按薪资排序取前 N 名的,薪资也得一起给出来, # 否则前端只能看到"谁排前面"却看不出差了多少钱 salary:Optional[int]=None class ClassAvgEmpTimeOut(BaseModel): """每个班级的平均就业时长""" class_id: Optional[int] = None # 单位:天,保留 1 位小数;为 None 表示该班无就业学生,前端展示"无就业学生" avg_emp_time: Optional[float] = None # 参与统计的人数(平均值的分母),为 0 同样表示该班无就业学生 emp_stu_count: int = 0 class EmpTimeOut(BaseModel): model_config = ConfigDict(from_attributes=True) stu_name:str='' emp_total_time:int=0 # 单位为天