# APIRouter:路由对象,用来分组接口 from fastapi import APIRouter, Depends, HTTPException, Query # Session:数据库会话类型注解 from sqlalchemy.orm import Session # 类型提示:可选参数 from typing import Optional # 导入get_db,数据库会话依赖函数,每次请求生成/释放数据库连接 from core.database import get_db # 导入dao层全部数据库操作函数 from dao.employment import ( create_employment, get_employment_by_id, get_employment_by_student_id, get_employment_list, update_employment, delete_employment_logic ) # 导入pydantic请求体、响应体模型 from schemas.employment import ( EmploymentCreate, EmploymentUpdate, EmploymentResponse, EmploymentListResponse ) employment_router = APIRouter(prefix="/employments", tags=["就业管理模块"]) @employment_router.post("", response_model=EmploymentResponse, summary="新增就业信息") def add_employment(body: EmploymentCreate, db: Session = Depends(get_db)): """ 新增就业信息 - 一个学生只能保存一条就业记录(数据库唯一约束控制) - student_id必须在学生表student_info_detail中真实存在,否则外键报错 :param body:POST请求的JSON请求体,自动解析为EmploymentCreate对象 :param db: Depends(get_db),依赖注入,自动获取数据库会话,请求结束自动关闭连接 :return: 返回EmploymentResponse结构数据给前端 """ # 调用dao层新增函数 res = create_employment(db, body) # dao返回None,代表新增出错(外键不存在/学生重复/数据库异常) if res is None: # 抛出HTTP异常,500状态码,返回提示信息给前端/Swagger raise HTTPException(status_code=500, detail="新增失败,学生id不存在或该学生已有就业记录") # 成功,直接返回ORM对象,FastAPI会按照response_model自动转为json返回 return res @employment_router.get("/students/{student_id}", response_model=EmploymentResponse, summary="查询指定学生的就业信息") def query_student_employment(student_id: int, db: Session = Depends(get_db)): """ 根据学生id查询该学生的就业记录 :param student_id: url路径中的路径参数,学生id :param db:数据库会话 """ # 调用dao,按学生id查询 record = get_employment_by_student_id(db, student_id) # 如果查询结果为空,抛出404找不到资源 if not record: raise HTTPException(status_code=404, detail="未找到该学生的就业信息") return record @employment_router.get("", response_model=EmploymentListResponse, summary="就业信息列表,支持筛选") def query_employment_list( # Query:获取url中?后面的查询参数;description显示在Swagger文档 company_name: Optional[str] = Query(None, description="公司名称模糊查询"), salary_min: Optional[float] = Query(None, description="最低薪资"), salary_max: Optional[float] = Query(None, description="最高薪资"), skip: int = Query(0, ge=0, description="偏移量"), # ge=0参数校验,不能传负数 limit: int = Query(20, ge=1, le=100, description="每页条数"), # 1‑100条限制,防止一次性查大量数据 db: Session = Depends(get_db) ): """就业分页列表接口,支持公司名模糊,薪资区间筛选""" # 调用dao层列表查询,拿到记录列表和总条数 data_list, total = get_employment_list(db, company_name, salary_min, salary_max, skip, limit) # 返回符合EmploymentListResponse格式的字典,FastAPI自动序列化 return {"total": total, "data": data_list} @employment_router.get("/{eid}", response_model=EmploymentResponse, summary="根据id查询就业详情") def query_employment_detail(eid: int, db: Session = Depends(get_db)): """ 根据就业主键id查询单条就业详情 :param eid: url路径参数,就业记录主键 """ record = get_employment_by_id(db, eid) if not record: raise HTTPException(status_code=404, detail="就业记录不存在或已被逻辑删除") return record @employment_router.put("/{eid}", response_model=EmploymentResponse, summary="修改就业信息") def edit_employment(eid: int, body: EmploymentUpdate, db: Session = Depends(get_db)): """ 修改就业信息;请求体只传需要修改的字段即可,不需要全部传 :param eid:待修改记录id,路径参数 :param body:PUT请求的JSON请求体 """ res = update_employment(db, eid, body) if res is None: raise HTTPException(status_code=404, detail="修改失败,记录不存在") return res @employment_router.delete("/{eid}", summary="逻辑删除就业记录") def logic_delete_employment(eid: int, db: Session = Depends(get_db)): """ 逻辑删除接口:不会物理删除数据库行,只设置is_deleted=1 DELETE请求,RESTful风格 """ ok = delete_employment_logic(db, eid) if not ok: raise HTTPException(status_code=404, detail="删除失败,记录不存在") # 返回简单json提示成功 return {"code": 200, "msg": "逻辑删除成功"}