# scheme/employ.py # 本文件定义 学生就业信息 接口层所用到的 请求体、响应体 # author:王博 from datetime import date from decimal import Decimal from typing import List from pydantic import Field, model_validator, BaseModel # ---------- -------------------------------请求模型 ------------------------------------------------ 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