第一版_完整
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
# scheme/employ.py
|
||||
from datetime import date
|
||||
from decimal import Decimal
|
||||
from typing import List
|
||||
|
||||
from pydantic import Field, field_validator, model_validator, ValidationError, BaseModel
|
||||
from database import Base
|
||||
|
||||
# ---------- -------------------------------请求模型 ------------------------------------------------
|
||||
class YearMonthDay(BaseModel):
|
||||
year : int | None = Field(None,description="年份")
|
||||
month: int | None = Field(None, le=12,ge=1 ,description="月份")
|
||||
day: int | None = Field(None,ge=1 ,description="日期")
|
||||
@model_validator(mode='after')
|
||||
def check_year_month_day(self):
|
||||
having_none = (self.year and self.month and self.day)
|
||||
all_none= (not self.year and not self.month and not self.day)
|
||||
all_has = (self.year and self.month and self.day and len(str(self.year))==4)
|
||||
# if not having_none:
|
||||
# raise ValueError("年月日必须全部填写或者全部为空")
|
||||
if all_none:
|
||||
return None
|
||||
if all_has:
|
||||
if self.month==2:
|
||||
if (self.year % 4 == 0 and self.year % 100 != 0) or (self.year % 400 == 0):
|
||||
if self.day>29:
|
||||
raise ValueError("闰年2月最多29天")
|
||||
return self
|
||||
else:
|
||||
if self.day > 28:
|
||||
raise ValueError("平年2月最多28天")
|
||||
return self
|
||||
elif self.month in (1,3,5,7,8,10,12):
|
||||
if self.day > 31:
|
||||
raise ValueError("大月最多31天")
|
||||
return self
|
||||
else:
|
||||
if self.day > 30:
|
||||
raise ValueError("小月最多30天")
|
||||
return self
|
||||
|
||||
raise ValueError("年月日必须全部填写或者全部为空,且年份必须为4位数")
|
||||
|
||||
|
||||
# 定义 记录学生就业状态 请求体模型
|
||||
class EmployStatusCreate(BaseModel):
|
||||
"""
|
||||
记录学生就业状态接口,需要传入的请求体
|
||||
"""
|
||||
stu_id: str = Field(..., description="学号,非空唯一")
|
||||
emp_open_time: YearMonthDay | None = Field(None, description="就业开放时间,可更改学生就业状态")
|
||||
send_offer_time: YearMonthDay | None = Field(None, description="offer下发时间,可更改学生就业状态")
|
||||
emp_company: str | None = Field(None, description="就业公司名称")
|
||||
salary: Decimal | None = Field(None, decimal_places=2,description="就业薪资,默认为空") # 薪资精确到2小数
|
||||
|
||||
|
||||
@model_validator(mode='after')
|
||||
def check_offer_and_open_time(self):
|
||||
"""
|
||||
自定义校验,就业开放时间必须 早于等于 offer下发时间,否则抛出422参数异常状态码;
|
||||
并且返回 就业状态记录 对象 自己
|
||||
:return:
|
||||
"""
|
||||
s, e = self.send_offer_time, self.emp_open_time
|
||||
if s and e:
|
||||
send_offer_time = date(s.year,s.month,s.day)
|
||||
emp_open_time = date(e.year,e.month,e.day)
|
||||
if send_offer_time < emp_open_time: # offer下发时间不能早于就业开放时间
|
||||
raise ValueError("offer下发时间不能早于就业开放时间")
|
||||
return self
|
||||
if not e:
|
||||
if s and self.emp_company and self.salary: # 就业开放时间为null,offer下发时间、就业公司、薪水不能填写
|
||||
raise ValueError("学生在读,无法添加就业信息")
|
||||
return self
|
||||
else:
|
||||
if not s:
|
||||
if self.emp_company and self.salary: # offer下发时间为null,就业公司、薪水不能填写
|
||||
raise ValueError("学生进入就业中,无法添加已就业信息")
|
||||
return self
|
||||
if not self.emp_company and not self.salary:
|
||||
raise ValueError("学生已就业,必须填写已就业信息") # 学生已就业,就业公司、薪水必须填写
|
||||
return self
|
||||
|
||||
# 定义 查询学生就业状态 请求体模型
|
||||
class EmployStatusQuery(BaseModel):
|
||||
"""
|
||||
请求体传入学生编号(可选)、就业公司(可选)、薪资范围(可选)
|
||||
可多条件查询 学生就业信息
|
||||
"""
|
||||
stu_id: str | None = Field(None, description="根据学生编号查询")
|
||||
emp_company: str | None = Field(None, description="根据就业公司名称查询")
|
||||
min_salary: Decimal | None = Field(None, decimal_places=2,description="查询的就业薪资范围最小值") # 薪资精确到2小数
|
||||
max_salary: Decimal | None = Field(None, decimal_places=2, description="查询的就业薪资范围最大值") # 薪资精确到2小数
|
||||
skip:int = Field(1, description="页码")
|
||||
limit: int = Field(10, description="每页条数")
|
||||
|
||||
# 定义 删除学生就业状态 请求体模型
|
||||
class EmployStatusDelete(BaseModel):
|
||||
"""
|
||||
请求体传入学生编号(可选)、就业公司(可选)、薪资范围(可选)
|
||||
可多条件查询 学生就业信息
|
||||
"""
|
||||
stu_id: str = Field(..., description="根据学生编号查询")
|
||||
|
||||
# ------------------------------------------ 响应模型 ------------------------------------------------
|
||||
class EmployStatusResponse(BaseModel):
|
||||
stu_id: str
|
||||
emp_open_time: YearMonthDay | None
|
||||
send_offer_time: YearMonthDay | None
|
||||
emp_company: str | None
|
||||
salary: Decimal | None = Field(None, decimal_places=2,description="就业薪资,默认为空") # 薪资精确到2小数
|
||||
|
||||
class EmployDateResponse(BaseModel):
|
||||
stu_id: str
|
||||
emp_open_time: date | None
|
||||
send_offer_time: date | None
|
||||
emp_company: str | None
|
||||
salary: Decimal | None = Field(None, decimal_places=2,description="就业薪资,默认为空") # 薪资精确到2小数
|
||||
|
||||
class EmployQueryResponse(BaseModel):
|
||||
employ_info : List[EmployDateResponse] | None
|
||||
total:int
|
||||
@@ -1,22 +0,0 @@
|
||||
# scheme/statistics_scheme.py
|
||||
from pydantic import BaseModel, Field, EmailStr
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
|
||||
# ---------- 请求模型 ----------
|
||||
# class UserCreate(BaseModel):
|
||||
# username: str = Field(..., min_length=3, max_length=50)
|
||||
# email: EmailStr
|
||||
# full_name: Optional[str] = Field(None, max_length=100)
|
||||
#
|
||||
# class UserUpdate(BaseModel):
|
||||
# username: Optional[str] = Field(None, min_length=3, max_length=50)
|
||||
# email: Optional[EmailStr] = None
|
||||
# full_name: Optional[str] = Field(None, max_length=100)
|
||||
|
||||
# ---------- 响应模型 ----------
|
||||
# 多维度班级统计
|
||||
class StatsResponse(BaseModel):
|
||||
total_count: int
|
||||
man_count: int
|
||||
female_count: int
|
||||
@@ -0,0 +1,80 @@
|
||||
from pydantic import BaseModel, Field, model_validator, field_validator, ConfigDict
|
||||
from datetime import date, datetime
|
||||
from typing import Optional
|
||||
|
||||
#id用cls_id来拼接生成,不用请求体过滤
|
||||
#------------新增请求体-------------
|
||||
class StudentCreate(BaseModel):
|
||||
cls_id: int | str = Field(..., description="班级ID,6位数字")
|
||||
name: str = Field(..., min_length=1, max_length=20, description="姓名")
|
||||
gender: str = Field(..., min_length=1, max_length=1, description="性别")
|
||||
age: int = Field(..., ge=1, le=100, description="年龄")
|
||||
hometown: Optional[str] = Field(None, min_length=3, max_length=50, description="籍贯")
|
||||
grad_school: str = Field(..., min_length=1, max_length=50, description="毕业院校")
|
||||
major: str = Field(..., min_length=1, max_length=50, description="专业名称")
|
||||
education: str = Field(..., min_length=1, max_length=20, description="学历")
|
||||
enr_date: date = Field(..., description="入学日期")
|
||||
grad_date: date = Field(..., description="毕业日期")
|
||||
advisor_id: str = Field(..., min_length=1, max_length=15, description="顾问编号")
|
||||
#校验入学时间必须比毕业时间小
|
||||
@model_validator(mode='after')
|
||||
def check_dates(self):
|
||||
if self.grad_date <= self.enr_date:
|
||||
raise ValueError("毕业日期必须晚于入学日期")
|
||||
return self
|
||||
# 校验传入的6位数是不是都是数字/都转化为字符串判断
|
||||
@field_validator("cls_id", mode="before")
|
||||
def convert_str(cls, v):
|
||||
# 不管前端传数字还是字符串,统一转字符串
|
||||
v = str(v)
|
||||
if len(v) != 6 or not v.isdigit():
|
||||
raise ValueError("班级ID必须是6位纯数字")
|
||||
return v
|
||||
#------------修改请求体-------------
|
||||
class StudentUpdate(BaseModel):
|
||||
cls_id: Optional[int|str] = Field(None, description="班级ID,6位数字")
|
||||
name: Optional[str] = Field(None, min_length=1, max_length=20, description="姓名")
|
||||
gender: Optional[str] = Field(None, min_length=1, max_length=1, description="性别")
|
||||
age: Optional[int] = Field(None, ge=1, le=100, description="年龄")
|
||||
hometown: Optional[str] = Field(None, min_length=3, max_length=50, description="籍贯")
|
||||
grad_school: Optional[str] = Field(None, min_length=1, max_length=50, description="毕业院校")
|
||||
major: Optional[str] = Field(None, min_length=1, max_length=50, description="专业名称")
|
||||
education: Optional[str] = Field(None, min_length=1, max_length=20, description="学历")
|
||||
enr_date: Optional[date]= Field(None, description="入学日期")
|
||||
grad_date: Optional[date]= Field(None, description="毕业日期")
|
||||
advisor_id: Optional[str] = Field(None, min_length=1, max_length=15, description="顾问编号")
|
||||
|
||||
@field_validator("cls_id", mode="before")
|
||||
def convert_str(cls, v):
|
||||
# 更新:不传cls_id(v=None)直接返回,跳过校验
|
||||
if v is None:
|
||||
return v
|
||||
v = str(v)
|
||||
if len(v) != 6 or not v.isdigit():
|
||||
raise ValueError("班级ID必须是6位纯数字")
|
||||
return v
|
||||
|
||||
@model_validator(mode='after')
|
||||
def check_dates(self):
|
||||
# 只在两个日期【都传了,不为None】的时候,才校验大小,传单个时在api层校验
|
||||
if self.grad_date is not None and self.enr_date is not None:
|
||||
if self.grad_date <= self.enr_date:
|
||||
raise ValueError("毕业日期必须晚于入学日期")
|
||||
return self
|
||||
#--------------响应体模型--------------
|
||||
class StudentResponse(BaseModel):
|
||||
id: str
|
||||
cls_id: str
|
||||
name: str
|
||||
gender: str
|
||||
age: int
|
||||
hometown: Optional[str]
|
||||
grad_school: Optional[str]
|
||||
major: Optional[str]
|
||||
education: Optional[str]
|
||||
enr_date: Optional[date]
|
||||
grad_date: Optional[date]
|
||||
advisor_id: Optional[str]
|
||||
state: Optional[str]
|
||||
|
||||
model_config = ConfigDict(from_attributes=True) # 支持 ORM 对象转换
|
||||
@@ -0,0 +1,28 @@
|
||||
# scheme/stu_score_scheme.py
|
||||
import decimal
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
# from datetime import datetime
|
||||
# from typing import Optional
|
||||
|
||||
|
||||
|
||||
# ---------- 请求模型 ----------
|
||||
|
||||
|
||||
# ---------- 响应模型 ----------
|
||||
class StuScoreResponse(BaseModel):
|
||||
stu_id: str
|
||||
exam_attempt: int
|
||||
exam_score: decimal.Decimal = Field(max_digits=5, decimal_places=2)
|
||||
score_level:str
|
||||
class StuScoreCreateResponse(BaseModel):
|
||||
stu_id: str
|
||||
exam_attempt: int
|
||||
exam_score: decimal.Decimal = Field(max_digits=5, decimal_places=2)
|
||||
score_level: str
|
||||
warnings:str|None= None
|
||||
|
||||
|
||||
class Config:
|
||||
from_attributes = True # 支持 ORM 对象转换
|
||||
@@ -0,0 +1,46 @@
|
||||
#老师表请求体模型
|
||||
from http.client import HTTPException
|
||||
from typing import Optional
|
||||
|
||||
from fastapi.openapi.utils import status_code_ranges
|
||||
from pydantic import Field, BaseModel, field_validator
|
||||
from database import Base # Base 在 database.py 中
|
||||
|
||||
#添加教师信息请求体
|
||||
class TeacherAdd(BaseModel):
|
||||
name : str = Field(..., max_length=50,description="姓名")
|
||||
phone : str = Field(..., description="手机号")
|
||||
type : str = Field(..., max_length=50, description="教师类型")
|
||||
|
||||
# 校验器 输入手机号必须为11位
|
||||
@field_validator("phone")
|
||||
@classmethod #类方法
|
||||
def phone_length(cls, v:str):
|
||||
if len(v) != 11:
|
||||
raise ValueError('手机号必须为11位')
|
||||
return v
|
||||
|
||||
class TeacherUpdate(BaseModel):
|
||||
name: Optional[str] = Field(None,max_length=50, description="姓名")
|
||||
phone: Optional[str] = Field(None,description="手机号")
|
||||
type: Optional[str] = Field(None,max_length=50, description="教师类型")
|
||||
|
||||
#校验器 输入手机号必须为11位
|
||||
@field_validator("phone")
|
||||
@classmethod #类方法
|
||||
def phone_length(cls, v: Optional[str]):
|
||||
if v is not None and len(v) != 11:
|
||||
raise ValueError('手机号必须为11位')
|
||||
return v
|
||||
|
||||
|
||||
|
||||
#教师响应体模型
|
||||
class TeacherResponse(BaseModel):
|
||||
id: str
|
||||
name: str
|
||||
phone: str
|
||||
type: str
|
||||
|
||||
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
# scheme/users.py
|
||||
from pydantic import BaseModel, Field, EmailStr
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
|
||||
# ---------- 请求模型 ----------
|
||||
class UserCreate(BaseModel):
|
||||
username: str = Field(..., min_length=3, max_length=50)
|
||||
email: EmailStr
|
||||
full_name: Optional[str] = Field(None, max_length=100)
|
||||
|
||||
class UserUpdate(BaseModel):
|
||||
username: Optional[str] = Field(None, min_length=3, max_length=50)
|
||||
email: Optional[EmailStr] = None
|
||||
full_name: Optional[str] = Field(None, max_length=100)
|
||||
|
||||
# ---------- 响应模型 ----------
|
||||
class UserResponse(BaseModel):
|
||||
id: int
|
||||
username: str
|
||||
email: str
|
||||
full_name: Optional[str]
|
||||
created_at: datetime
|
||||
updated_at: Optional[datetime]
|
||||
|
||||
class Config:
|
||||
from_attributes = True # 支持 ORM 对象转换
|
||||
Reference in New Issue
Block a user