diff --git a/api/class_api.py b/api/class_api.py index f71e3f4..38b75e6 100644 --- a/api/class_api.py +++ b/api/class_api.py @@ -51,6 +51,6 @@ def get_classes( id:int|None = None # id参数接收前端输 @classes_router.delete('/{id}',response_model=ClassResponse,summary='删除班级信息') # delete删除请求,指定返回数据格式为 ClassResponse def delete_classes(id:int,db=Depends(get_db)): # 定义删除接口函数,id参数接收前端输入的数据,参数db依赖于数据库会话的上下文管理器 r = delete_classes_dao( id , db ) # 变量r用来接收dao层delete_classes_dao函数的返回值,执行函数时以以前端输入的id 数据、db依赖函数入参 - if r : # 判断 DAO 层的返回结果,如果是True + if r!=0 : # 判断 DAO 层的返回结果,如果是True return ClassResponse( total=1,data='已成功删除班级信息' ) # 返回成功响应和提示给前端 # 如果是False raise HTTPException(status_code=500, detail='删除失败,该班级信息已不存在或服务器繁忙,请稍后更新!') # 如果为False,抛出 500 内部服务器错误 和提示 \ No newline at end of file diff --git a/api/employment.py b/api/employment.py index f0d112f..63fd9ff 100644 --- a/api/employment.py +++ b/api/employment.py @@ -6,7 +6,8 @@ from dao.employment import (create_employment, get_employment_by_student_id, get_employment_list, update_employment, - delete_employment_logic) + delete_employment_logic, + recover_employment_delete) from schemas.employment import (EmploymentCreate, EmploymentUpdate, @@ -28,17 +29,21 @@ def add_employment(body: EmploymentCreate, db: Session = Depends(get_db)): 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获取对应就业记录""" - record = get_employment_by_student_id(db, student_id) - if not record: - raise HTTPException(status_code=404, detail="未找到该学生的就业信息") - return record +# + +# @employment_router.get("/students/{student_id}", response_model=EmploymentResponse, summary="查询指定学生的就业信息") +# def query_student_employment(student_id: int, db: Session = Depends(get_db)): +# """根据学生id获取对应就业记录""" +# record = get_employment_by_student_id(db, student_id) +# if not record: +# raise HTTPException(status_code=404, detail="未找到该学生的就业信息") +# return record @employment_router.get("/", summary="就业信息列表,支持筛选") -def query_employment_list(company_name: str | None = Query(None, description="公司名称模糊查询"), +def query_employment_list(eid:int| None = Query(None, description="就业编号"), + student_id:int| None = Query(None,description="学生id"), + company_name: str | None = Query(None, description="公司名称模糊查询"), salary_min: float | None = Query(None, description="最低薪资"), salary_max: float | None = Query(None, description="最高薪资"), skip: int = Query(0, ge=0, description="偏移量"), @@ -49,13 +54,13 @@ def query_employment_list(company_name: str | None = Query(None, description=" 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查询单条就业记录""" - record = get_employment_by_id(db, eid) - if not record: - raise HTTPException(status_code=404, detail="就业记录不存在或已被逻辑删除") - return record +# @employment_router.get("/{eid}", response_model=EmploymentResponse, summary="根据id查询就业详情") +# def query_employment_detail(eid: int, db: Session = Depends(get_db)): +# """根据就业主键id查询单条就业记录""" +# 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="修改就业信息") @@ -75,3 +80,12 @@ def logic_delete_employment(eid: int, db: Session = Depends(get_db)): raise HTTPException(status_code=404, detail="删除失败,记录不存在") # 删除成功返回提示字典 return {"code": 200, "msg": "逻辑删除成功"} + +@employment_router.get("/{eid}", summary="回档逻辑删除就业记录") +def recover_delete_employment(eid: int, db: Session = Depends(get_db)): + """执行逻辑删除,is_deleted置1,不会真正删除数据库行""" + ok = recover_employment_delete(db, eid) + if not ok: + raise HTTPException(status_code=404, detail="回档失败,记录已经存在") + # 删除成功返回提示字典 + return {"code": 200, "msg": "回档成功"} \ No newline at end of file diff --git a/api/score.py b/api/score.py index 7302b5e..31d1ed8 100644 --- a/api/score.py +++ b/api/score.py @@ -1,7 +1,7 @@ from fastapi import APIRouter, Depends, HTTPException, Query from sqlalchemy.orm import Session from core.database import get_db -from dao.score import post_score_dao, update_score_dao, get_score_dao, get_all_scores_dao,delete_score_dao, exist_student_exam_dao +from dao.score import post_score_dao, update_score_dao, get_score_dao,delete_score_dao, exist_student_exam_dao from schemas.score import ScoreCreate, ScoreUpdate, ScorePageResp scores_router = APIRouter(prefix="/scores", tags=["成绩接口"]) @@ -32,14 +32,6 @@ def list_score( -@scores_router.get("/all", response_model=ScorePageResp, - summary="所有学生成绩接口", - ) -def list_all_scores(page: int = Query(1, ge=1), - page_size: int = Query(10, ge=1, le=100), - db: Session = Depends(get_db)): - total, data_list = get_all_scores_dao(page, page_size, db) - return {"total": total, "data": data_list} @scores_router.put("{score_id}", summary="更新成绩接口") def modify_score(score_id: int, req: ScoreUpdate, db: Session = Depends(get_db)): diff --git a/dao/class_dao.py b/dao/class_dao.py index 6fed146..4001308 100644 --- a/dao/class_dao.py +++ b/dao/class_dao.py @@ -73,10 +73,10 @@ def get_classes_dao( class_id, class_no , class_name , page , page_size , db ): # ————定义班级表"删除"信息的函数———— def delete_classes_dao( class_id , db ): # 定义函数,设置两个个形参class_id,db try : # 执行以下可能报错的代码 - db.query( Classes ).filter( Classes.id == class_id , Classes.is_deleted == 0 ).update( {"is_deleted": 1} ) # 将未删除且前端输入的id和数据库id可以匹配上的数据更新is_deleted字段为1,表示已逻辑删除 + r = db.query( Classes ).filter( Classes.id == class_id , Classes.is_deleted == 0 ).update( {"is_deleted": 1} ) # 将未删除且前端输入的id和数据库id可以匹配上的数据更新is_deleted字段为1,表示已逻辑删除 + if r !=0: + db.commit() + return r except : # 捕获异常: db.rollback() # 如果中间出错,回滚事务,防止产生脏数据 return False # 返回 False,返回接口,表示操作失败 - else : # 执行成功: - db.commit() # 提交事务:更新is_deleted字段为1,表示已逻辑删除,前端无法查询到已逻辑删除的数据 - return True # 返回 True,返回接口,表示操作成功 diff --git a/dao/employment.py b/dao/employment.py index 7261d86..1fc4e47 100644 --- a/dao/employment.py +++ b/dao/employment.py @@ -1,13 +1,12 @@ -from sqlalchemy.orm import Session from models.employment import Employment -from schemas.employment import EmploymentCreate, EmploymentUpdate, EmploymentResponse +from schemas.employment import EmploymentResponse -def create_employment(db, obj_in): +def create_employment(db, e): # obj_in是Pydantic对象(EmploymentCreate) """新增就业信息:一个学生只能存在一条就业记录""" try: - db_obj = Employment(**obj_in.model_dump()) + db_obj = Employment(**e.model_dump()) db.add(db_obj) db.commit() db.refresh(db_obj) @@ -75,10 +74,14 @@ def get_employment_by_student_id(db, student_id): return None -def get_employment_list(db, company_name=None, salary_min=None, salary_max=None, skip=0, limit=20): +def get_employment_list(db, id=None,student_id=None,company_name=None, salary_min=None, salary_max=None, skip=0, limit=20): """就业列表查询;支持公司名模糊、薪资范围筛选;只查询is_deleted=0""" try: query = db.query(Employment).filter(Employment.is_deleted == 0) + if id is not None: + query = query.filter(Employment.id >= id) + if student_id is not None: + query = query.filter(Employment.student_id >= student_id) if company_name: query = query.filter(Employment.company_name.like(f"%{company_name}%")) if salary_min is not None: @@ -108,48 +111,62 @@ def get_employment_list(db, company_name=None, salary_min=None, salary_max=None, return [], 0 -def update_employment(db, eid, obj_in): +def update_employment(db, eid, e): """修改就业信息,只更新传入的字段""" try: - db_obj_raw = db.query(Employment).filter(Employment.id == eid + x = db.query(Employment).filter(Employment.id == eid ,Employment.is_deleted == 0).first() - if db_obj_raw is None: + if x is None: return None - update_dict = obj_in.model_dump(exclude_unset=True) + update_dict = e.model_dump(exclude_unset=True) db.query(Employment).filter(Employment.id == eid ,Employment.is_deleted == 0).update(update_dict) db.commit() - db.refresh(db_obj_raw) + db.refresh(x) - resp = EmploymentResponse(id=db_obj_raw.id - ,student_id=db_obj_raw.student_id - ,employment_status=db_obj_raw.employment_status - ,employment_open_date=db_obj_raw.employment_open_date - ,offer_date=db_obj_raw.offer_date - ,company_name=db_obj_raw.company_name - ,salary=db_obj_raw.salary - ,remark=db_obj_raw.remark - ,created_at=db_obj_raw.created_at - ,updated_at=db_obj_raw.updated_at) + resp = EmploymentResponse(id=x.id + ,student_id=x.student_id + ,employment_status=x.employment_status + ,employment_open_date=x.employment_open_date + ,offer_date=x.offer_date + ,company_name=x.company_name + ,salary=x.salary + ,remark=x.remark + ,created_at=x.created_at + ,updated_at=x.updated_at) return resp.model_dump() except Exception: db.rollback() - return None + return + def delete_employment_logic(db, eid): """逻辑删除,只修改is_deleted=1,不做物理删除""" try: - db_obj_raw = db.query(Employment).filter(Employment.id == eid + y = db.query(Employment).filter(Employment.id == eid ,Employment.is_deleted == 0).first() - if db_obj_raw is None: + if y is None: return False - db_obj_raw.is_deleted = 1 + y.is_deleted = 1 db.commit() return True except Exception: db.rollback() return False + +def recover_employment_delete(db, eid): + """逻辑删除,只修改is_deleted=1,不做物理删除""" + try: + y = db.query(Employment).filter(Employment.id == eid).first() + if y is None: + return False + y.is_deleted = 0 + db.commit() + return True + except Exception: + db.rollback() + return False \ No newline at end of file diff --git a/dao/score.py b/dao/score.py index e0b53e5..5fb2138 100644 --- a/dao/score.py +++ b/dao/score.py @@ -5,23 +5,27 @@ def post_score_dao(data_dict, db): try: obj = Score(**data_dict) db.add(obj) + db.commit() except Exception as e: print("新增成绩异常:", e) db.rollback() return False else: - db.commit() return True def update_score_dao(score_id, db, updates): """修改成绩,query.update方式""" try: - db.query(Score).filter( + cnt = db.query(Score).filter( Score.id == score_id, Score.is_deleted == 0 ).update(updates) - except Exception: + if cnt == 0: + db.rollback() + return False + except Exception as e: + print("修改成绩异常:", e) db.rollback() return False else: @@ -30,14 +34,25 @@ def update_score_dao(score_id, db, updates): def get_score_dao(score_id, student_id, exam_seq, page, page_size, db): - """分页查询成绩,多条件过滤,只查未删除""" + """分页查询成绩,多条件过滤,只查未删除 + 规则: + - score_id == 0 → 查所有学生成绩(仅分页,不加 id 过滤) + - 三个筛选条件全为空(None) → 直接返回空,不查库 + - 其他情况 → 按传入条件过滤 + """ q = db.query(Score).filter(Score.is_deleted == 0) - if score_id: - q = q.filter(Score.id == score_id) - if student_id: - q = q.filter(Score.student_id == student_id) - if exam_seq: - q = q.filter(Score.exam_seq == exam_seq) + + if score_id == 0: + pass # score_id=0 → 查全部(分页) + elif score_id is None and not student_id and not exam_seq: + return 0, [] # 三个参数都没传 → 返回空 + else: + if score_id: + q = q.filter(Score.id == score_id) + if student_id: + q = q.filter(Score.student_id == student_id) + if exam_seq: + q = q.filter(Score.exam_seq == exam_seq) total = q.count() rows = q.offset((page - 1) * page_size).limit(page_size).all() @@ -58,36 +73,20 @@ def get_score_dao(score_id, student_id, exam_seq, page, page_size, db): ] return total, res_list -def get_all_scores_dao(page, page_size, db): - r = db.query(Score).filter(Score.is_deleted == 0)\ - .order_by(Score.student_id, Score.exam_seq) - total = r.count() # 总条数 - rows = r.offset((page-1)*page_size).limit(page_size).all()# 分页 - res_list_all = [ - { - "id": i.id, - "student_id": i.student_id, - "score": i.score, - "exam_seq": i.exam_seq, - "exam_date": i.exam_date, - "remark": i.remark, - "created_at": i.created_at, - "updated_at": i.updated_at, - "is_deleted": i.is_deleted - } - for i in rows - ] - return total,res_list_all + + def delete_score_dao(score_id, db): - """逻辑删除,更新is_deleted=1""" try: - db.query(Score).filter( + cnt = db.query(Score).filter( Score.id == score_id, Score.is_deleted == 0 - ).update({"is_deleted": 1}) + ).update({"is_deleted": 1}) # ← 接住返回值 + if cnt == 0: # ← 关键:一行都没匹配到 + db.rollback() + return False except Exception as err: print("删除成绩异常:", err) db.rollback() diff --git a/models/class_model.py b/models/class_model.py index 23c9bc1..b92eded 100644 --- a/models/class_model.py +++ b/models/class_model.py @@ -5,7 +5,7 @@ from core.database import Base # 从core软件包下的database模块导入B from sqlalchemy.dialects.mysql import TINYINT class Classes( Base ): # 在python里的名字 - __tablename__ = 'class_info_detail' # 在数据库中表的名字 + __tablename__ = 'class_info_detail' # 在数据库中表的名字 #————创建班级"主键"的字段名———— id = Column( Integer # 声明字段的数据类型是"整数" , primary_key = True # 声明是"主键" diff --git a/schemas/employment.py b/schemas/employment.py index d5fbb33..425e286 100644 --- a/schemas/employment.py +++ b/schemas/employment.py @@ -1,4 +1,4 @@ -from pydantic import BaseModel, Field,ConfigDict#专门存放模型配置参数的字典类。把各种开关配置放里面。 +from pydantic import BaseModel, Field from datetime import date, datetime from decimal import Decimal