commit 1e302df9edd8039f2b9e26821ed626f2f50b90bf Author: Lys <17608410+lys1359664647@user.noreply.gitee.com> Date: Mon Sep 21 22:13:04 2026 +0800 aaa diff --git a/student_system_final/.idea/.gitignore b/student_system_final/.idea/.gitignore new file mode 100644 index 0000000..b6b1ecf --- /dev/null +++ b/student_system_final/.idea/.gitignore @@ -0,0 +1,10 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# 已忽略包含查询文件的默认文件夹 +/queries/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ diff --git a/student_system_final/.idea/inspectionProfiles/Project_Default.xml b/student_system_final/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..146ab09 --- /dev/null +++ b/student_system_final/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/student_system_final/.idea/inspectionProfiles/profiles_settings.xml b/student_system_final/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/student_system_final/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/student_system_final/.idea/misc.xml b/student_system_final/.idea/misc.xml new file mode 100644 index 0000000..1e700dc --- /dev/null +++ b/student_system_final/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/student_system_final/.idea/modules.xml b/student_system_final/.idea/modules.xml new file mode 100644 index 0000000..ecfe1dc --- /dev/null +++ b/student_system_final/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/student_system_final/.idea/student_system.iml b/student_system_final/.idea/student_system.iml new file mode 100644 index 0000000..95a328c --- /dev/null +++ b/student_system_final/.idea/student_system.iml @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/student_system_final/__pycache__/database.cpython-310.pyc b/student_system_final/__pycache__/database.cpython-310.pyc new file mode 100644 index 0000000..afabe87 Binary files /dev/null and b/student_system_final/__pycache__/database.cpython-310.pyc differ diff --git a/student_system_final/__pycache__/main.cpython-310.pyc b/student_system_final/__pycache__/main.cpython-310.pyc new file mode 100644 index 0000000..cff6978 Binary files /dev/null and b/student_system_final/__pycache__/main.cpython-310.pyc differ diff --git a/student_system_final/aaa.py b/student_system_final/aaa.py new file mode 100644 index 0000000..4c1bbd8 --- /dev/null +++ b/student_system_final/aaa.py @@ -0,0 +1,39 @@ +from minio import Minio +from minio.error import S3Error +import io + +# 1. 创建客户端 +client = Minio( + 'localhost:9100', + access_key='minioadmin', + secret_key='minioadmin', + secure=False, # 本地测试用 HTTP;生产环境请用 True +) + +bucket_name = 'test-bucket' +object_name = 'test-object' +data = b'Hello MinIO' + +try: + # 2. 桶不存在就创建(关键修改) + if not client.bucket_exists(bucket_name): + client.make_bucket(bucket_name) + print(f"已创建桶: {bucket_name}") + + # 3. 上传对象,length 用 len(data) 动态计算 + client.put_object( + bucket_name, + object_name, + io.BytesIO(data), + length=len(data), + ) + print(f"MinIO 连接成功,对象上传完成: {bucket_name}/{object_name}") + + # 4. (可选)验证一下确实传上去了 + stat = client.stat_object(bucket_name, object_name) + print(f"验证: 对象大小 = {stat.size} 字节") + +except S3Error as e: + print(f"S3 错误: code={e.code}, message={e.message}") +except Exception as e: + print(f"其它错误: {type(e).__name__}: {e}") \ No newline at end of file diff --git a/student_system_final/api1/__init__.py b/student_system_final/api1/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/student_system_final/api1/__pycache__/__init__.cpython-310.pyc b/student_system_final/api1/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000..728fc3f Binary files /dev/null and b/student_system_final/api1/__pycache__/__init__.cpython-310.pyc differ diff --git a/student_system_final/api1/__pycache__/classes.cpython-310.pyc b/student_system_final/api1/__pycache__/classes.cpython-310.pyc new file mode 100644 index 0000000..7e2cbe9 Binary files /dev/null and b/student_system_final/api1/__pycache__/classes.cpython-310.pyc differ diff --git a/student_system_final/api1/__pycache__/scores.cpython-310.pyc b/student_system_final/api1/__pycache__/scores.cpython-310.pyc new file mode 100644 index 0000000..ad4c0fd Binary files /dev/null and b/student_system_final/api1/__pycache__/scores.cpython-310.pyc differ diff --git a/student_system_final/api1/__pycache__/statistic.cpython-310.pyc b/student_system_final/api1/__pycache__/statistic.cpython-310.pyc new file mode 100644 index 0000000..b405232 Binary files /dev/null and b/student_system_final/api1/__pycache__/statistic.cpython-310.pyc differ diff --git a/student_system_final/api1/__pycache__/students.cpython-310.pyc b/student_system_final/api1/__pycache__/students.cpython-310.pyc new file mode 100644 index 0000000..caa8f33 Binary files /dev/null and b/student_system_final/api1/__pycache__/students.cpython-310.pyc differ diff --git a/student_system_final/api1/__pycache__/teacher.cpython-310.pyc b/student_system_final/api1/__pycache__/teacher.cpython-310.pyc new file mode 100644 index 0000000..07b36e3 Binary files /dev/null and b/student_system_final/api1/__pycache__/teacher.cpython-310.pyc differ diff --git a/student_system_final/api1/__pycache__/work.cpython-310.pyc b/student_system_final/api1/__pycache__/work.cpython-310.pyc new file mode 100644 index 0000000..42857a7 Binary files /dev/null and b/student_system_final/api1/__pycache__/work.cpython-310.pyc differ diff --git a/student_system_final/api1/classes.py b/student_system_final/api1/classes.py new file mode 100644 index 0000000..607784c --- /dev/null +++ b/student_system_final/api1/classes.py @@ -0,0 +1,60 @@ +from fastapi import APIRouter,HTTPException,Depends +from sqlalchemy.orm import Session + +from dao.class_dao import ClassDao +from database import get_db +from scheme.classes import ClassUpdate, ClassCreate, ClassResponse, ClassListResponse + +router = APIRouter() + +#新增 +@router.post("/class/",response_model=ClassResponse) +async def create_class(data:ClassCreate,db: Session = Depends(get_db)): + if ClassDao.get_class(db, data.cid): + raise HTTPException(status_code=400, detail="班级编号已存在") + return ClassDao.create_class_list(db, data) + +# 条件查询班级 +@router.get("/class/get_list/",response_model=ClassListResponse) +async def get_class_list( + cid :int = None, + class_name: str = None, + headteacher:str = None, + page: int = 1, + size: int = 5, + db: Session = Depends(get_db) +): + total, items = ClassDao.get_class_list(db, cid=cid, class_name=class_name,headteacher=headteacher, page=page, size=size) + return {"total": total, "items": items} + +# 查询单个班级 +# @router.put("/class",response_model=ClassResponse) +# async def list_class(cid:int,db: Session = Depends(get_db)): +# cls = ClassDao.get_class(db,cid) +# if not cls: +# raise HTTPException(status_code=404, detail="班级不存在") +# return cls + +# 更新 +@router.put("/class/{cid}",response_model=ClassResponse) +async def update_class(cid:int,data:ClassUpdate,db: Session = Depends(get_db)): + cls = ClassDao.update_class(db, cid, data) + if not cls: + raise HTTPException(status_code=404, detail="班级不存在") + return cls + +#删除 +@router.delete("/class/{cid}") +async def delete_class(cid:int,db: Session = Depends(get_db)): + c = ClassDao.delete_class(db, cid) + if not c: + raise HTTPException(status_code=404, detail="班级不存在") + return None + + + + + + + + diff --git a/student_system_final/api1/scores.py b/student_system_final/api1/scores.py new file mode 100644 index 0000000..bac1107 --- /dev/null +++ b/student_system_final/api1/scores.py @@ -0,0 +1,35 @@ +# api/scores.py +# 本文件定义成绩相关的所有 API 路由 + +from fastapi import APIRouter, Depends, HTTPException +from sqlalchemy.orm import Session +from database import get_db +from dao.score_dao import ScoreDAO +from scheme.scores import ScoreUpdate, ScoreResponse +# 创建路由器,前缀将在 main.py 中统一添加 +router = APIRouter() +# 根据 学号 + 考核次数 查询单条成绩 +@router.get("/score/{sid}/{exam_num}", response_model=ScoreResponse) +async def get_score( + sid: int, + exam_num: int, + db: Session = Depends(get_db) # 依赖注入获得数据库会话 +): + return ScoreDAO.get_by_id(db, sid, exam_num) +# 根据 学号 + 考核次数 修改成绩 +@router.put("/score/update", response_model=ScoreResponse) +async def update_score( + sid: int, + exam_num: int, + score_data: ScoreUpdate, + db: Session = Depends(get_db) +): + return ScoreDAO.update(db, sid, exam_num, score_data) +# 删除成绩,逻辑删除flag改为0 +@router.post("/score/delete", response_model=ScoreResponse) +async def delete_score( + sid: int, + exam_num: int, + db: Session = Depends(get_db) +): + return ScoreDAO.delete(db, sid, exam_num) diff --git a/student_system_final/api1/statistic.py b/student_system_final/api1/statistic.py new file mode 100644 index 0000000..75be79a --- /dev/null +++ b/student_system_final/api1/statistic.py @@ -0,0 +1,80 @@ +# statistic.py +# 本文件定义statistic相关的所有 API 路由(Controller 层) +from dao.statistic_dao import Statistic +from fastapi import APIRouter, Depends, HTTPException, Query + +from database import get_db + +router = APIRouter() + +@router.get("/ages") +async def get_ages_interface( + age1:int = Query(...,ge=18,lt=30,description="输入年龄"), + age2:int|None = Query(default=None,ge=19,lt=30,description="如果要区间则输入最大年龄"), + condition:int =Query(...,description="输入比较条件:1是大于,2是小于,3是等于,4是区间"), + db = Depends(get_db) + +): + module = Statistic(db) + res = module.get_ages(age1, age2, condition) + return { + "code": 200, + "data": res + } +@router.get("/class/") +async def get_class_interface( + db = Depends(get_db) +): + module = Statistic(db) + res = module.get_class() + return { + "code": 200, + "data": res + } + + + + +@router.get("/grades/") +async def get_grades_interface( + grades:float=Query(80,ge=0,lt=100,description="输入成绩"), + db = Depends(get_db) +): + module = Statistic(db) + res = module.get_grades(grades) + return res +@router.get("/bad_grades/") +async def get_bad_grades_interface( + number:int=Query(...,ge=0,lt=4,description="输入次数"), + db = Depends(get_db) +): + module = Statistic(db) + res = module.get_bad_grades(number) + return res +# +# +@router.get("/avg_grade") +async def get_avg_interface( + sort:int = Query(..., ge=1, le=2, description="1降序高分在前,2升序低分在前"), + db=Depends(get_db) +): + module = Statistic(db) + res = module.get_avg_grades(sort) + return {"code":200,"data":res} + +# +@router.get("/top") +async def get_top_interface( + top:int=Query(...,description="输入排名"), + db = Depends(get_db) +): + module = Statistic(db) + res = module.get_top(top) + return res +# +# +@router.get("/get_time") +async def get_time_interface(db = Depends(get_db)): + module = Statistic(db) + res = module.get_time() + return res diff --git a/student_system_final/api1/students.py b/student_system_final/api1/students.py new file mode 100644 index 0000000..81a886b --- /dev/null +++ b/student_system_final/api1/students.py @@ -0,0 +1,48 @@ +# api/students.py +# 本文件定义学生模块的所有 API 路由(Controller 层) +from fastapi import APIRouter, Depends, HTTPException, Query +from sqlalchemy.orm import Session + +from database import get_db +from dao.student_dao import StudentDAO +from scheme.students import StudentCreate, StudentUpdate, StudentResponse, StudentListResponse + +# 创建路由器 +router = APIRouter(prefix="/students", tags=["学生管理"]) + +# 查询学生列表(支持按编号、姓名、班级等条件筛选) +@router.get("/list/", response_model=StudentListResponse) +async def get_student_list( + sid: int = None, + name: str = Query(None,max_length=4,description='名字的模糊查询'), + cid: int =Query(None,description="根据学生的班级id查询"), + gender: str = Query(None,max_length=1,description="选择项(男\女)根据学生性别查询,查询男同学或者女同学"), + education: str = Query(None,max_length=2,description="选择项(硕士\本科)根据学生学历查询,查询该学历学生"), + page: int = Query(1,description="查看的页数"), + size: int = Query(5,description="查询每一页的数量"), + db: Session = Depends(get_db) +): + total, items = StudentDAO.get_list(db, sid=sid, name=name, cid=cid, + gender=gender, education=education, + page=page, size=size) + return {"total": total, "items": items} + +# 按学号查单个学生 +@router.get("/{sid}", response_model=StudentResponse) +async def get_student_by_id(sid: int, db: Session = Depends(get_db)): + return StudentDAO.get_by_id(db, sid) + +# 按照用户输入新增学生 +@router.post("/create", response_model=StudentResponse) +async def create_student(data: StudentCreate, db: Session = Depends(get_db)): + return StudentDAO.create(db, data) + +# 更新学生信息 +@router.put("/update/{sid}", response_model=StudentResponse) +async def update_student(sid: int, data: StudentUpdate, db: Session = Depends(get_db)): + return StudentDAO.update(db, sid, data) + +# 删除学生 +@router.post("/delete/{sid}", response_model=StudentResponse) +async def delete_student(sid: int, db: Session = Depends(get_db)): + return StudentDAO.delete(db, sid) \ No newline at end of file diff --git a/student_system_final/api1/teacher.py b/student_system_final/api1/teacher.py new file mode 100644 index 0000000..2856199 --- /dev/null +++ b/student_system_final/api1/teacher.py @@ -0,0 +1,46 @@ +# api/teacher.py +# 本文件定义老师模块的所有 API 路由(Controller 层) + +from fastapi import APIRouter, Depends, HTTPException,Query +from sqlalchemy.orm import Session + +from database import get_db +from dao.teacher_dao import TeacherDAO +from scheme.teachers import TeacherCreate, TeacherUpdate, TeacherResponse, TeacherListResponse + +# 创建路由器 +router = APIRouter(prefix="/teachers", tags=["老师管理"]) + +#查询老师列表(支持按姓名模糊查询、是否班主任) +@router.get("/list/", response_model=TeacherListResponse) +async def get_teacher_list( + teacher_name: str = Query(None,), + is_headteacher: int = Query(default=None,ge=0,le=1), + page: int = 1, + size: int = 10, + db: Session = Depends(get_db) +): + total, items = TeacherDAO.get_list(db, teacher_name=teacher_name, + is_headteacher=is_headteacher, + page=page, size=size) + return {"total": total, "items": items} + +#按老师编号查单个老师 +@router.get("/{teacher_id}", response_model=TeacherResponse) +async def get_teacher_by_id(teacher_id: int, db: Session = Depends(get_db)): + return TeacherDAO.get_by_id(db, teacher_id) + +# 新增老师 +@router.post("/create", response_model=TeacherCreate) +async def create_teacher(data: TeacherCreate, db: Session = Depends(get_db)): + return TeacherDAO.create(db, data) + +# 更新老师信息 +@router.put("/update/{teacher_id}", response_model=TeacherResponse) +async def update_teacher(teacher_id: int, data: TeacherUpdate, db: Session = Depends(get_db)): + return TeacherDAO.update(db, teacher_id, data) + +# 逻辑删除老师 +@router.post("/delete/{teacher_id}", response_model=TeacherResponse) +async def delete_teacher(teacher_id: int, db: Session = Depends(get_db)): + return TeacherDAO.delete(db, teacher_id) \ No newline at end of file diff --git a/student_system_final/api1/work.py b/student_system_final/api1/work.py new file mode 100644 index 0000000..e706649 --- /dev/null +++ b/student_system_final/api1/work.py @@ -0,0 +1,31 @@ +#这是学生就业系统的子路由 +from fastapi import APIRouter, Depends, HTTPException, Query +from sqlalchemy.orm import Session +from dao.work_dao import WorkDao +from database import get_db +from scheme.works import StudentWorkCreate,StudentWorkCreate1,StudentWorks +router = APIRouter() +#这是添加学生就业信息接口 +@router.post("/create") +def create_student(student: StudentWorkCreate,db:Session=Depends(get_db)): + u1 = WorkDao.add_s_w(db,student) + return u1 +#这是获取学生就业信息接口 +@router.post("/post") +def get_student(student1: StudentWorkCreate1,db:Session=Depends(get_db)): + u2 = WorkDao.get_s_w(db,student1) + return u2 +#这是更新学生就业信息接口 +@router.put("/put") +def put_student(student2: StudentWorks,db:Session=Depends(get_db)): + u3 = WorkDao.update_s_w(db,student2) + return u3 +#这是删除学生就业信息接口 +@router.delete("/delete") +def delete_student(user_id:int=Query(...,ge=1,le=10000,description="填入合法学生编号"),db:Session=Depends(get_db)): + u4 = WorkDao.delete_s_w(db,user_id) + return u4 + + + + diff --git a/student_system_final/dao/__init__.py b/student_system_final/dao/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/student_system_final/dao/__pycache__/__init__.cpython-310.pyc b/student_system_final/dao/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000..e619966 Binary files /dev/null and b/student_system_final/dao/__pycache__/__init__.cpython-310.pyc differ diff --git a/student_system_final/dao/__pycache__/class_dao.cpython-310.pyc b/student_system_final/dao/__pycache__/class_dao.cpython-310.pyc new file mode 100644 index 0000000..c094e1d Binary files /dev/null and b/student_system_final/dao/__pycache__/class_dao.cpython-310.pyc differ diff --git a/student_system_final/dao/__pycache__/score_dao.cpython-310.pyc b/student_system_final/dao/__pycache__/score_dao.cpython-310.pyc new file mode 100644 index 0000000..5b0e3fb Binary files /dev/null and b/student_system_final/dao/__pycache__/score_dao.cpython-310.pyc differ diff --git a/student_system_final/dao/__pycache__/statistic_dao.cpython-310.pyc b/student_system_final/dao/__pycache__/statistic_dao.cpython-310.pyc new file mode 100644 index 0000000..412b180 Binary files /dev/null and b/student_system_final/dao/__pycache__/statistic_dao.cpython-310.pyc differ diff --git a/student_system_final/dao/__pycache__/student_dao.cpython-310.pyc b/student_system_final/dao/__pycache__/student_dao.cpython-310.pyc new file mode 100644 index 0000000..4e7183c Binary files /dev/null and b/student_system_final/dao/__pycache__/student_dao.cpython-310.pyc differ diff --git a/student_system_final/dao/__pycache__/teacher_dao.cpython-310.pyc b/student_system_final/dao/__pycache__/teacher_dao.cpython-310.pyc new file mode 100644 index 0000000..cf46dac Binary files /dev/null and b/student_system_final/dao/__pycache__/teacher_dao.cpython-310.pyc differ diff --git a/student_system_final/dao/__pycache__/work_dao.cpython-310.pyc b/student_system_final/dao/__pycache__/work_dao.cpython-310.pyc new file mode 100644 index 0000000..370487d Binary files /dev/null and b/student_system_final/dao/__pycache__/work_dao.cpython-310.pyc differ diff --git a/student_system_final/dao/class_dao.py b/student_system_final/dao/class_dao.py new file mode 100644 index 0000000..3311286 --- /dev/null +++ b/student_system_final/dao/class_dao.py @@ -0,0 +1,85 @@ +from sqlalchemy import and_ +from sqlalchemy.orm import Session +from model.classes import Class # ← 必须:操作 ORM 模型 +from scheme.classes import ClassCreate, ClassUpdate # ← 必须:类型注解 + +class ClassDao: +# 新增 + @staticmethod + def create_class_list(db:Session,data:ClassCreate): + cls = Class( + cid=data.cid, + class_name=data.class_name, + start_time=data.start_time, + headteacher=data.headteacher, + flag=1 + ) + db.add(cls) + db.commit() + db.refresh(cls) + return cls + + # 查询,查询单个 + @staticmethod + def get_class(db:Session,class_id:int): + return db.query(Class).filter(and_(Class.cid==class_id,Class.flag==1)).first() + # def get_all_class(db:Session): + # return db.query(Class).filter(Class.flag==1).all() + @staticmethod + def get_class_list(db:Session,cid:None,class_name:None,headteacher:None,page=1, size=10): + query = db.query(Class).filter(Class.flag == 1) + if cid: + query=query.filter(Class.cid == cid) + if class_name: + query=query.filter(Class.class_name == class_name) + if headteacher: + query=query.filter(Class.headteacher == headteacher) + total = query.count() + items=query.order_by(Class.cid).offset((page-1)*size).limit(size).all() + return total, items + + # 查询全部 + @staticmethod + def get_all_class(db:Session): + return db.query(Class).filter(Class.flag==1).all() + # 查询学生 + @staticmethod + def get_class_student(db:Session,class_id:int): + cls = ClassDao.get_class(db,class_id) + if not cls: + return None + return {"id": Class.student.sid, "name": Class.student.name, "age": Class.student.age, "gender": Class.student.gender} + #查询老师 + @staticmethod + def get_class_teacher(db:Session,class_id:int): + cls = ClassDao.get_class(db,class_id) + if not cls: + return None + return {"id":Class.teachers.id,"name":Class.teachers.name} + + # 更新 + @staticmethod + def update_class(db:Session,class_id:int,data:ClassUpdate): + cls = ClassDao.get_class(db,class_id) + if not cls: + return None + if cls.class_name: + cls.class_name = data.class_name + if cls.headteacher: + cls.headteacher = data.headteacher + db.commit() + return cls + + # 删除 + @staticmethod + def delete_class(db:Session,cid:int): + cls = ClassDao.get_class(db,cid) + if not cls: + return False + cls.flag=0 + db.commit() + db.refresh(cls) + return cls + + + diff --git a/student_system_final/dao/score_dao.py b/student_system_final/dao/score_dao.py new file mode 100644 index 0000000..28db88e --- /dev/null +++ b/student_system_final/dao/score_dao.py @@ -0,0 +1,59 @@ +# dao/score_dao.py +# 本文件封装对学生成绩表的所有数据库操作(增、删、改、查) +from fastapi import HTTPException +from sqlalchemy import and_ +from sqlalchemy.orm import Session + +from model.student_score import Score +from scheme.scores import ScoreCreate, ScoreUpdate + + +class ScoreDAO: + + # 根据学生id、考试次数查询有效成绩(flag=1) + @staticmethod + def get_by_id(db: Session, sid: int, exam_num: int): + score = db.query(Score).filter(and_(Score.sid == sid, Score.exam_num == exam_num, Score.flag == 1) + ).first() + if score: + return score + raise HTTPException(status_code=404, detail="学生分数不存在") + + # 查询某个学生的所有考试成绩 + @staticmethod + def get_by_student(db: Session, sid: int): + return (db.query(Score) + .filter(Score.sid == sid, Score.flag == 1).order_by(Score.exam_num).all()) + + # 录入成绩 + @staticmethod + def create(db: Session, data: ScoreCreate): + # 同一个学生同一次考试只能有一条有效成绩 + exist = db.query(Score).filter(and_(Score.sid == data.sid, Score.exam_num == data.exam_num, Score.flag == 1)).first() + if exist: + raise HTTPException(status_code=400, + detail=f"学生 {data.sid} 第 {data.exam_num} 次成绩已存在,请使用修改接口") + score = Score(sid=data.sid, exam_num=data.exam_num, score=data.score, flag=1) + db.add(score) + db.commit() + db.refresh(score) + return score + + # 根据学生id和考试次数更新成绩 + @staticmethod + def update(db: Session, sid: int, exam_num: int, score_data: ScoreUpdate): + update_data = score_data.model_dump() + db.query(Score) \ + .filter(Score.sid == sid) \ + .update(update_data) + db.commit() # 提交事务 + return ScoreDAO.get_by_id(db, sid, exam_num) + + # 根据学生id和考试次数逻辑删除(flag 改为 0) + @staticmethod + def delete(db: Session, sid: int, exam_num: int): + db_score = ScoreDAO.get_by_id(db, sid, exam_num) + db_score.flag = 0 # 标记为已删除 + db.commit() + db.refresh(db_score) + return db_score diff --git a/student_system_final/dao/statistic_dao.py b/student_system_final/dao/statistic_dao.py new file mode 100644 index 0000000..eb7e6e5 --- /dev/null +++ b/student_system_final/dao/statistic_dao.py @@ -0,0 +1,166 @@ + +from typing import Optional +from sqlalchemy import and_, func, desc +from model.classes import Class +from model.student import Student +from model.student_score import Score +from model.work import Work + + +class Statistic: + def __init__(self,db): + self.db = db + + def get_ages(self,age1:int,age2:Optional[int],condition:int): + + stu = self.db.query(Student) + if not age2: + if condition == 1: + q=stu.filter(Student.age > age1).all() + + elif condition == 2: + q=stu.filter(Student.age < age1).all() + + elif condition == 3: + q=stu.filter(Student.age == age1).all() + + else: + return f"输入错误,重新输入" + else: + if condition == 4: + q=stu.filter(and_(Student.age > age1, Student.age < age2)).all() + + else: + return f"输入错误,重新输入" + return q + + def get_class(self): + # 查询所有存在的班级cid(去重) + cid_list = self.db.query(Student.cid).distinct().all() + result = [] + for row in cid_list: + cid = row.cid + # 当前班级全部学生 + all_stu = self.db.query(Student).filter(Student.cid == cid).all() + total = len(all_stu) + if total == 0: + continue + # 男生 + man_list = [s for s in all_stu if s.gender == "男"] + man_count = len(man_list) + # 女生 + woman_list = [s for s in all_stu if s.gender == "女"] + woman_count = len(woman_list) + + man_rate = man_count / total + woman_rate = woman_count / total + + result.append({ + "class_id": cid, + "total": total, + "male_count": man_count, + "male_rate": man_rate, + "female_count": woman_count, + "female_rate": woman_rate + }) + return result + + def get_grades(self, grades): + stu = self.db.query(Score).filter(Score.score > grades).distinct().all() + result = [] + for st in stu: + result.append({ + "sid": st.sid, + "score": st.score + }) + + return result + + def get_bad_grades(self, number: int): + # 第一步:统计每个学生不及格(<60)的记录数量,筛选出不及格次数 >= number 的学生sid + sub_q = self.db.query( + Score.sid, + func.count(Score.score).label("bad_count") + ).filter(Score.score < 60) \ + .group_by(Score.sid) \ + .having(func.count(Score.score) >= number) \ + .subquery() + + # 第二步:关联学生表+子查询,拿到满足条件学生的全部不及格成绩明细 + bad_list = self.db.query( + Student.name, + Student.cid, + Score.score, + Score.exam_num + ).join(sub_q, Student.sid == sub_q.c.sid) \ + .join(Score, Student.sid == Score.sid) \ + .filter(Score.score < 60) \ + .all() + + # 组装结果:按学生分组,一个学生一条,里面放成绩明细 + result = {} + for name, cid, score, exam_num in bad_list: + key = (name, cid) + if key not in result: + result[key] = { + "name": name, + "cid": cid, + "bad_detail": [], + "bad_count": 0 + } + result[key]["bad_detail"].append({"exam_num": exam_num, "score": score}) + result[key]["bad_count"] += 1 + return list(result.values()) + + def get_avg_grades(self, sort: int): + q = self.db.query( + Class.cid, + func.avg(Score.score).label("avg_score") + ).join(Student, + Student.cid == Class.cid) \ + .join(Score, Score.sid == Student.sid) \ + .group_by(Class.cid) + + data = q.all() + result = [] + for item in data: + result.append({ + "班级": item.cid, + "平均分": float(item.avg_score) + }) + + if sort == 1: + result.sort(key=lambda x: x["平均分"], reverse=True) + elif sort == 2: + result.sort(key=lambda x: x["平均分"], reverse=False) + else: + return {"code": 400, "msg": "输入错误,sort只能填1或2"} + return result + # # + def get_top(self,top): + stu=self.db.query(Student.name.label("student_name"), + Student.cid.label("class_id"), + Work.offer_time, + Work.company_name, + Work.salary).join(Student,Student.sid==Work.sid)\ + .order_by(desc(Work.salary)).offset(top - 1).limit(1).first() + if not stu: + return f"错误排名" + name,cid,time,cname,salary = stu + return {"名字":name,"班级":cid,"就业时间":time,"公司名":cname,"薪水":salary} + + def get_time(self): + result = [] + stu=self.db.query(Work.sid, + Work.open_time, + Work.offer_time).all() + for item in stu: + time=item.offer_time-item.open_time + result.append({"学生id":item.sid,"就业时长":time}) + return result + # def get_avg_time(self): + # result = [] + # stu=Query(Class.id.label("class_id"), + # func.datediff(Student_employment.offer_time, Student_employment.open_time).join(Student_employment,Student_employment.sid==Student.sid)\ + # .join(Student,Student.cid==Class.cid).group_by(Class.id).fillter().all() + diff --git a/student_system_final/dao/student_dao.py b/student_system_final/dao/student_dao.py new file mode 100644 index 0000000..f2435de --- /dev/null +++ b/student_system_final/dao/student_dao.py @@ -0,0 +1,65 @@ +# dao/student_dao.py +# 本文件封装对学生表的所有数据库操作(增、删、改、查) +from fastapi import HTTPException +from sqlalchemy.orm import Session +from model.student import Student +from scheme.students import StudentCreate, StudentUpdate + + +class StudentDAO: + # 多条件查询学生列表(编号、姓名、班级等,条件可以叠加) + @staticmethod + def get_list(db: Session, sid=None, name=None, cid=None, + gender=None, education=None, page=1, size=10): + query = db.query(Student).filter(Student.flag == 1) # flag=1 才是有效数据 + # 传了哪个条件就追加哪个过滤条件 + if sid : + query = query.filter(Student.sid == sid) + if name: + query = query.filter(Student.name.like(f"%{name}%")) # 姓名模糊查询 + if cid : + query = query.filter(Student.cid == cid) + if gender: + query=query.filter(Student.gender == gender) + if education: + query=query.filter(Student.education == education) + total = query.count() # 先算总条数(分页要用) + items = query.order_by(Student.sid).offset((page - 1) * size).limit(size).all() + return total, items + + # 按学生id查单个学生 + @staticmethod + def get_by_id(db: Session, sid: int): + student = db.query(Student).filter(Student.sid == sid, Student.flag == 1).first() + if not student: + raise HTTPException(status_code=404, detail=f"学生 {sid} 不存在") + return student + + # 新增学生 + @staticmethod + def create(db: Session, data: StudentCreate): + student = Student(**data.model_dump()) + student.flag = 1 # 新数据默认是正常状态 + db.add(student) + db.commit() + db.refresh(student) # 刷新后能拿到数据库生成的自增学号 + return student + + # 更新学生信息 + @staticmethod + def update(db: Session, sid: int, data: StudentUpdate): + update_data = data.model_dump(exclude_unset=True) + db.query(Student) \ + .filter(Student.sid == sid) \ + .update(update_data) + db.commit() + return StudentDAO.get_by_id(db, sid) + + # 逻辑删除学生(flag 改为 0,不真删数据) + @staticmethod + def delete(db: Session, sid: int): + student = StudentDAO.get_by_id(db, sid) + student.flag = 0 + db.commit() + db.refresh(student) + return student diff --git a/student_system_final/dao/teacher_dao.py b/student_system_final/dao/teacher_dao.py new file mode 100644 index 0000000..2f9d85f --- /dev/null +++ b/student_system_final/dao/teacher_dao.py @@ -0,0 +1,59 @@ +# dao/teache_dao.py +# 本文件封装对老师表的所有数据库操作(增、删、改、查) +from fastapi import HTTPException +from sqlalchemy.orm import Session + +from model.teacher import Teacher +from scheme.teachers import TeacherCreate, TeacherUpdate + + +class TeacherDAO: + + # 多条件查询老师列表 + @staticmethod + def get_list(db: Session, teacher_name=None, is_headteacher=None, page=1, size=10): + query = db.query(Teacher).filter(Teacher.flag == 1) + if teacher_name: + query = query.filter(Teacher.teacher_name.like(f"%{teacher_name}%")) + if is_headteacher: + query = query.filter(Teacher.is_headteacher == is_headteacher) + total = query.count() + items = (query.order_by(Teacher.teacher_id).offset((page - 1) * size).limit(size).all()) + return total, items + + # 按老师编号查单个老师 + @staticmethod + def get_by_id(db: Session, teacher_id: int): + teacher = db.query(Teacher).filter(Teacher.teacher_id == teacher_id, Teacher.flag == 1).first() + if not teacher: + raise HTTPException(status_code=404, detail=f"老师 {teacher_id} 不存在") + return teacher + + # 新增老师 + @staticmethod + def create(db: Session, data: TeacherCreate): + teacher = Teacher(**data.model_dump()) + teacher.flag = 1 + db.add(teacher) + db.commit() + db.refresh(teacher) + return teacher + + # 更新老师信息 + @staticmethod + def update(db: Session, teacher_id: int, data: TeacherUpdate): + update_data = data.model_dump(exclude_unset=True) + db.query(Teacher) \ + .filter(Teacher.teacher_id == teacher_id) \ + .update(update_data) + db.commit() + return TeacherDAO.get_by_id(db, teacher_id) + + # 逻辑删除老师 + @staticmethod + def delete(db: Session, teacher_id: int): + teacher = TeacherDAO.get_by_id(db, teacher_id) + teacher.flag = 0 + db.commit() + db.refresh(teacher) + return teacher diff --git a/student_system_final/dao/work_dao.py b/student_system_final/dao/work_dao.py new file mode 100644 index 0000000..21d9c3c --- /dev/null +++ b/student_system_final/dao/work_dao.py @@ -0,0 +1,80 @@ +from datetime import date + +from fastapi import HTTPException +from pydantic import Field +from sqlalchemy import and_ +from sqlalchemy.orm import Session +#导入表模型 +from model.work import Work +#导入请求模型 StudentWorkCreate,是学生就业信息表的第一个请求模型用于方法一, +# StudentWorkCreate1,是学生就业信息表的第二个请求模型用于方法二 +# StudentWroks,是学生信息表的请求模型 +from scheme.works import StudentWorkCreate,StudentWorks,StudentWorkCreate1 + +class WorkDao: + @staticmethod + #这是一个增加学生就业信息的方法 + def add_s_w(db: Session,student_work_info: StudentWorkCreate ): + u1 = Work(**student_work_info.model_dump()) + db.add(u1) + db.commit() + print("已添加成功") + return u1 + #这是获取学生就业信息(包含学生姓名与学生编号)的方法(三个必填版) + @staticmethod + def get_s_w(db: Session,student_work_info: StudentWorkCreate1): + u2 =db.query(Work).filter(and_(Work.sid == student_work_info.sid, + Work.company_name==student_work_info.company_name, + Work.salary==student_work_info.salary)).first() + + print("信息查询成功") + return {"学生姓名":u2.student.name,"学生班级编号":u2.student.cid, + "学生offer下发时间":u2.offer_time,"学生就业时间":u2.open_time,"公司姓名":u2.company_name, + "月薪":u2.salary} + #这是修改学生就业信息的方法 + @staticmethod + def update_s_w(db:Session,student_work_info: StudentWorks): + i = db.query(Work).filter(Work.sid == student_work_info.sid).first() + if i is not None: + + if student_work_info.company_name!="0": + i.company_name = student_work_info.company_name + db.commit() + if float(student_work_info.salary)!=0: + i.salary = student_work_info.salary + db.commit() + if student_work_info.open_time!=date(1970,1,1): + i.work_time = student_work_info.open_time + db.commit() + if student_work_info.offer_time!=date(1970,1,1): + i.offer_time = student_work_info.offer_time + db.commit() + return {"message": f"{student_work_info.sid}号学生已经修改成功"} + + else: + raise HTTPException(status_code= 422,detail="输入学生学号错误") + + #这是删除学生信息的方法 + @staticmethod + def delete_s_w(db: Session,user_id:int=Field(...,ge=0,le=100000)): + u0 = db.query(Work).all() + for i in u0: + if i.sid == user_id: + u1 = db.query(Work).filter(Work.sid == i.sid).first() + u1.flag = 0 + return {"message":f"{user_id}号学生已经删除成功"} + else: + raise HTTPException(status_code=422,detail="输入的学生编号错误") + + + + + + + + + + + + + diff --git a/student_system_final/database.py b/student_system_final/database.py new file mode 100644 index 0000000..aa92263 --- /dev/null +++ b/student_system_final/database.py @@ -0,0 +1,34 @@ +# database.py +# 本文件负责配置数据库连接、创建引擎、会话工厂,并提供依赖注入函数 + +from sqlalchemy import create_engine +from sqlalchemy.orm import sessionmaker,declarative_base + +# 1. 配置 MySQL 数据库连接 URL +# 格式:mysql+pymysql://用户名:密码@主机:端口/数据库名?编码 +# 请将下面的 'root', '123456', 'localhost', '3306', 'student_system' 替换为你自己的实际信息 +SQLALCHEMY_DATABASE_URL = "mysql+pymysql://root:123456@localhost:3306/student_system" + +# 2. 创建数据库引擎 +# - pool_pre_ping=True 表示每次从连接池取出连接前先 ping 一下,防止使用已断开的连接 +engine = create_engine( + SQLALCHEMY_DATABASE_URL, + pool_size=10, +) +# 3. 创建会话工厂 +SessionLocal = sessionmaker(bind=engine) + +# 4. 创建声明式基类,所有模型类都继承自它 +Base = declarative_base() + +# 5. 依赖注入函数:用于 FastAPI 路由中获取数据库会话 +def get_db(): + """ + 每次请求创建一个数据库会话,请求结束后关闭。 + 这个函数会作为 Depends 的参数注入到路由中。 + """ + db = SessionLocal() # 创建一个会话实例 + try: + yield db # 将会话交给路由函数使用 + finally: + db.close() # 无论是否发生异常,最后都会关闭会话,释放连接 \ No newline at end of file diff --git a/student_system_final/main.py b/student_system_final/main.py new file mode 100644 index 0000000..5926d25 --- /dev/null +++ b/student_system_final/main.py @@ -0,0 +1,43 @@ +# main.py +# 项目入口文件:创建 FastAPI 应用、注册路由、创建数据库表 +from fastapi import FastAPI +from fastapi.middleware.cors import CORSMiddleware +from api1.students import router as students_router +from api1.scores import router as scores_router +from api1.work import router as work_router +from api1.classes import router as classes_router +from api1.teacher import router as teacher_router +from api1.statistic import router as statistic_router +# 2. 创建 FastAPI 实例 +app = FastAPI( + title="沃林学生管理系统", + description="学生信息以及就业信息的增删改查", + version="1.0.0" +) +# 3. 添加跨域中间件(允许前端跨域请求) +app.add_middleware( + CORSMiddleware, + allow_origins=["*"], # 允许所有来源,生产环境应指定具体域名 + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], +) +app.include_router(students_router, prefix="/api/students", tags=["学生管理"]) +app.include_router(scores_router, prefix="/api/scores", tags=["成绩管理"]) +app.include_router(work_router, prefix="/api/works", tags=["就业管理"]) +app.include_router(classes_router, prefix="/api/classes", tags=["班级管理"]) +app.include_router(teacher_router, prefix="/api/teachers", tags=["老师管理"]) +app.include_router(statistic_router, prefix="/api/statistic", tags=["统计分析"]) +# 5. 根路径 +@app.get("/") +async def root(): + return {"message": "学生管理系统!请访问 /docs 查看 API 文档。"} +# 6. 如果直接运行此文件,启动 uvicorn 服务器 +if __name__ == "__main__": + import uvicorn + uvicorn.run( + "main:app", # 指定应用位置(模块名:应用变量名) + host="127.0.0.1", # 监听所有网络接口 + port=8001, # 端口 + reload=True # 开发模式,代码变动自动重启 + ) \ No newline at end of file diff --git a/student_system_final/model/__init__.py b/student_system_final/model/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/student_system_final/model/__pycache__/__init__.cpython-310.pyc b/student_system_final/model/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000..8855a24 Binary files /dev/null and b/student_system_final/model/__pycache__/__init__.cpython-310.pyc differ diff --git a/student_system_final/model/__pycache__/classes.cpython-310.pyc b/student_system_final/model/__pycache__/classes.cpython-310.pyc new file mode 100644 index 0000000..cb78c3f Binary files /dev/null and b/student_system_final/model/__pycache__/classes.cpython-310.pyc differ diff --git a/student_system_final/model/__pycache__/student.cpython-310.pyc b/student_system_final/model/__pycache__/student.cpython-310.pyc new file mode 100644 index 0000000..cf4dbe3 Binary files /dev/null and b/student_system_final/model/__pycache__/student.cpython-310.pyc differ diff --git a/student_system_final/model/__pycache__/student_score.cpython-310.pyc b/student_system_final/model/__pycache__/student_score.cpython-310.pyc new file mode 100644 index 0000000..e38ada0 Binary files /dev/null and b/student_system_final/model/__pycache__/student_score.cpython-310.pyc differ diff --git a/student_system_final/model/__pycache__/teacher.cpython-310.pyc b/student_system_final/model/__pycache__/teacher.cpython-310.pyc new file mode 100644 index 0000000..63473e9 Binary files /dev/null and b/student_system_final/model/__pycache__/teacher.cpython-310.pyc differ diff --git a/student_system_final/model/__pycache__/work.cpython-310.pyc b/student_system_final/model/__pycache__/work.cpython-310.pyc new file mode 100644 index 0000000..28c5fd9 Binary files /dev/null and b/student_system_final/model/__pycache__/work.cpython-310.pyc differ diff --git a/student_system_final/model/classes.py b/student_system_final/model/classes.py new file mode 100644 index 0000000..998d27e --- /dev/null +++ b/student_system_final/model/classes.py @@ -0,0 +1,15 @@ +from sqlalchemy import Column, Integer, String, DateTime, Float, Date +from sqlalchemy.orm import relationship +from database import Base +from model.teacher import class_teacher + + +class Class(Base): + __tablename__ = "student_class" + cid = Column(Integer, primary_key=True) + class_name=Column(String(20),nullable=False) + start_time=Column(Date,nullable=False) + headteacher=Column(String(20),nullable=False) + flag=Column(Integer,nullable=False,default=1) + teachers=relationship("Teacher",secondary=class_teacher,back_populates="classes") + student = relationship("Student", back_populates="classes") \ No newline at end of file diff --git a/student_system_final/model/student.py b/student_system_final/model/student.py new file mode 100644 index 0000000..61a502f --- /dev/null +++ b/student_system_final/model/student.py @@ -0,0 +1,23 @@ +from sqlalchemy import Column, Integer, String, DateTime, Float, Date, ForeignKey +from sqlalchemy.orm import relationship +from database import Base +class Student(Base): + __tablename__ = "student" + sid=Column(Integer,primary_key=True,autoincrement=True) + cid =Column(Integer, ForeignKey("student_class.cid"),nullable=False)#班级编号,外键关联班级表 + name=Column(String(30),nullable=False)#学生姓名,字符串形式,不能为空值(必填) + address=Column(String(50),nullable=False)#籍贯,字符串形式,不能为空值(必填) + school=Column(String(50),nullable=False)#毕业院校,字符串形式,不能为空值(必填) + major=Column(String(50),nullable=False)#专业,字符串形式,不能为空值(必填) + start_time=Column(Date,nullable=False)#入学时间,字符串形式,不能为空值(必填) + end_time=Column(Date,nullable=True)#毕业时间,字符串形式,可以为空值(未毕业学生) + education=Column(String(20),nullable=False)#学历 ,字符串形式,不能为空值(必填) + consultant_id=Column(Integer,nullable=False)#顾问编号,整数 + gender=Column(String(3),nullable=False)#性别,字符串 + age=Column(Integer,nullable=False)#年龄 + flag=Column(Integer,nullable=False)#逻辑删除,当值为1是保留,当值为0时删除 + score=relationship("Score",back_populates="student") + work=relationship("Work",back_populates="student") + classes=relationship("Class",back_populates="student") + + diff --git a/student_system_final/model/student_score.py b/student_system_final/model/student_score.py new file mode 100644 index 0000000..0f2d87e --- /dev/null +++ b/student_system_final/model/student_score.py @@ -0,0 +1,18 @@ +# model/users.py +# 本文件定义 User 表的结构,映射到 MySQL 数据库 + +from sqlalchemy import Column, Integer, String, DateTime, Float, ForeignKey +from sqlalchemy.orm import relationship +from database import Base +from model.student import Student +#建立学生考核表模型 +class Score(Base): + __tablename__ = "student_score" # 表名 + # 字段定义 + score_id = Column(Integer, primary_key=True,autoincrement=True) # 主键,自增,索引 + sid = Column(Integer,ForeignKey("student.sid"),nullable=False) # 用户名,唯一,非空 + exam_num=Column(Integer)#考核次数 + score=Column(Float)#分数 + flag=Column(Integer,default=1)#状态 + #一对多 成绩表 + student=relationship("Student", back_populates="score") diff --git a/student_system_final/model/teacher.py b/student_system_final/model/teacher.py new file mode 100644 index 0000000..2984907 --- /dev/null +++ b/student_system_final/model/teacher.py @@ -0,0 +1,17 @@ +from sqlalchemy import Column, Integer, String, DateTime, Float, Date, Table, ForeignKey +from sqlalchemy.orm import relationship +from database import Base + +class_teacher=Table("class_teacher",Base.metadata, + Column("cid",Integer,ForeignKey("student_class.cid"),primary_key=True), + Column("teacher_id",Integer,ForeignKey("teacher.teacher_id"),primary_key=True)) + +class Teacher(Base): + __tablename__="teacher" + teacher_id=Column(Integer,primary_key=True,autoincrement=True,comment="老师id") + teacher_name=Column(String(50),nullable=False) + gender=Column(String(5),comment="性别") + phone=Column(String(20),comment="联系电话") + is_headteacher=Column(Integer,default=0,comment="数据状态 1-班主任 0-教师") + flag=Column(Integer,default=1,comment="数据状态 1-正常 0-删除") + classes=relationship("Class",secondary=class_teacher,back_populates="teachers") \ No newline at end of file diff --git a/student_system_final/model/work.py b/student_system_final/model/work.py new file mode 100644 index 0000000..6e33388 --- /dev/null +++ b/student_system_final/model/work.py @@ -0,0 +1,17 @@ +from sqlalchemy import Column, Integer, String, Date, Float, Numeric, ForeignKey +from sqlalchemy import create_engine +from sqlalchemy.orm import relationship +SQ_URL = "mysql+pymysql://root:123456@localhost:3306/student_system" +engine = create_engine(SQ_URL,pool_size=5,echo=True) +from database import Base +class Work(Base): + __tablename__ = 'student_work' + # 包含字段:学生编号ID、学生姓名、学生班级、就业开放时间、offer下发时间、就业公司名称、就业薪资 + employment_id = Column(Integer, autoincrement=True,primary_key=True) + sid = Column(Integer,ForeignKey("student.sid"), unique=True) + open_time = Column(Date, default="1970-01-01") + offer_time = Column(Date, default="1970-01-01") + company_name = Column(String(50)) + salary = Column(Numeric(10,2)) + flag = Column(Integer, default=1) + student = relationship("Student", back_populates="work") \ No newline at end of file diff --git a/student_system_final/scheme/__init__.py b/student_system_final/scheme/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/student_system_final/scheme/__pycache__/__init__.cpython-310.pyc b/student_system_final/scheme/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000..62379f1 Binary files /dev/null and b/student_system_final/scheme/__pycache__/__init__.cpython-310.pyc differ diff --git a/student_system_final/scheme/__pycache__/classes.cpython-310.pyc b/student_system_final/scheme/__pycache__/classes.cpython-310.pyc new file mode 100644 index 0000000..35b656a Binary files /dev/null and b/student_system_final/scheme/__pycache__/classes.cpython-310.pyc differ diff --git a/student_system_final/scheme/__pycache__/scores.cpython-310.pyc b/student_system_final/scheme/__pycache__/scores.cpython-310.pyc new file mode 100644 index 0000000..3100fec Binary files /dev/null and b/student_system_final/scheme/__pycache__/scores.cpython-310.pyc differ diff --git a/student_system_final/scheme/__pycache__/students.cpython-310.pyc b/student_system_final/scheme/__pycache__/students.cpython-310.pyc new file mode 100644 index 0000000..38d2e2c Binary files /dev/null and b/student_system_final/scheme/__pycache__/students.cpython-310.pyc differ diff --git a/student_system_final/scheme/__pycache__/teachers.cpython-310.pyc b/student_system_final/scheme/__pycache__/teachers.cpython-310.pyc new file mode 100644 index 0000000..71ffed1 Binary files /dev/null and b/student_system_final/scheme/__pycache__/teachers.cpython-310.pyc differ diff --git a/student_system_final/scheme/__pycache__/works.cpython-310.pyc b/student_system_final/scheme/__pycache__/works.cpython-310.pyc new file mode 100644 index 0000000..da883ac Binary files /dev/null and b/student_system_final/scheme/__pycache__/works.cpython-310.pyc differ diff --git a/student_system_final/scheme/classes.py b/student_system_final/scheme/classes.py new file mode 100644 index 0000000..76b40a1 --- /dev/null +++ b/student_system_final/scheme/classes.py @@ -0,0 +1,27 @@ +from pydantic import BaseModel, Field, field_validator +from typing import Optional, List +from datetime import date + +class ClassCreate(BaseModel): + cid : int= Field(...,description="班级编号") + class_name : str= Field(...,min_length=1, max_length=50, description="班级名称") + start_time:date + headteacher : str=Field(...,min_length=1, max_length=50,description="班主任") + flag:int +class ClassUpdate(BaseModel): + class_name:Optional[str]=Field(None,min_length=1, max_length=50) + start_time: Optional[date] = None + headteacher: Optional[str] = Field(None, min_length=1, max_length=50) +#响应体参数 +class ClassResponse(BaseModel): + cid : int + class_name : str + start_time : date + headteacher : str + flag : int +class Config: + from_attributes = True + +class ClassListResponse(BaseModel): + total: int + items: list[ClassResponse] diff --git a/student_system_final/scheme/scores.py b/student_system_final/scheme/scores.py new file mode 100644 index 0000000..db1fcbf --- /dev/null +++ b/student_system_final/scheme/scores.py @@ -0,0 +1,24 @@ +# scheme/scores.py +from typing import Optional +from pydantic import BaseModel, Field + +#录入成绩的请求体模型 +class ScoreCreate(BaseModel): + sid: int = Field(..., description="学号") + exam_num: int = Field(..., description="考核次数(第几次考试)") + score: float = Field(..., description="分数") + + +# sid、exam_num 作为路径参数在路由中单独传入,更新请求体参数中只放需要更新的字段 +class ScoreUpdate(BaseModel): + score: Optional[float] = Field(None, description="分数") + +# 响应体模型返回学号,考试次数,以及考核分数 +class ScoreResponse(BaseModel): + # score_id: int + sid: int + exam_num: int + score: float + flag: int +class Config: + from_attributes = True # 支持 ORM 对象转换 diff --git a/student_system_final/scheme/students.py b/student_system_final/scheme/students.py new file mode 100644 index 0000000..bc7858b --- /dev/null +++ b/student_system_final/scheme/students.py @@ -0,0 +1,59 @@ +# scheme/students.py +# 本文件定义学生模块用到的 Pydantic 模型(接口的请求参数 / 响应格式) +from typing import Optional,List +from datetime import date +io + +from model.classes import Class + + +# 创建学生的请求体模型 +class StudentCreate(BaseModel): + cid: int = Field(..., description="班级编号") + name: str = Field(..., description="姓名") + address: str = Field(..., description="籍贯") + school: str = Field(..., description="毕业院校") + major: str = Field(..., description="专业") + start_time: date = Field(..., description="入学时间") + end_time: Optional[date] = Field(None, description="毕业时间,未毕业可以不传") + education: str = Field(..., description="学历") + consultant_id: int = Field(..., description="顾问编号") + gender: str = Field(...,max_length=1, description="性别,男/女") + age: int = Field(..., description="年龄") +# +# 更新学生的请求体模型 +class StudentUpdate(BaseModel): + cid: Optional[int] = None + name: Optional[str] = None + address: Optional[str] = None + # school: Optional[str] = None + # major: Optional[str] = None + + # education: Optional[str] = None + # consultant_id: Optional[int] = None + # gender: Optional[str] = None + # age: Optional[int] = None + + +# 响应模型 +class StudentResponse(BaseModel): + sid: int + cid: int + name: str + address: str + school: str + major: str + start_time: date + end_time: Optional[date] = None + education: str + consultant_id: int + gender: str + age: int + flag: int +class Config: + from_attributes = True # 支持 ORM 对象直接转换 + + +class StudentListResponse(BaseModel): + total: int + items: list[StudentResponse] diff --git a/student_system_final/scheme/teachers.py b/student_system_final/scheme/teachers.py new file mode 100644 index 0000000..6e3123a --- /dev/null +++ b/student_system_final/scheme/teachers.py @@ -0,0 +1,37 @@ +# scheme/teachers.py +# 本文件定义老师模块用到的 Pydantic 模型 +from typing import Optional +from pydantic import BaseModel, Field + + +# 新增教师的请求体模型 ---------- +class TeacherCreate(BaseModel): + teacher_name: str = Field(..., description="老师姓名") + gender: Optional[str] = Field(None, description="性别") + phone: Optional[str] = Field(None, min_length=11,description="联系电话") + is_headteacher: int = Field(0, ge=0, le=1, description="1-班主任 0-任课老师") + + +class TeacherUpdate(BaseModel): + teacher_name: Optional[str] = None + gender: Optional[str] = None + phone: Optional[str] = Field(None,min_length=11,description="联系电话") + is_headteacher: Optional[int] = Field(None, ge=0, le=1) + + +# 响应体模型 +class TeacherResponse(BaseModel): + teacher_id: int + teacher_name: str + gender: Optional[str] = None + phone: Optional[str] = None + is_headteacher: int + # flag: int +#响应模型读取 SQLAlchemy ORM 对象属性 的配置 + class Config: + from_attributes = True + + +class TeacherListResponse(BaseModel): + total: int + items: list[TeacherResponse] diff --git a/student_system_final/scheme/works.py b/student_system_final/scheme/works.py new file mode 100644 index 0000000..333f6e8 --- /dev/null +++ b/student_system_final/scheme/works.py @@ -0,0 +1,48 @@ +#这是学生就业管理系统的请求模型 + +from datetime import date + +from fastapi import HTTPException +from pydantic import BaseModel, Field, field_validator, model_validator,ConfigDict + + +class StudentWorkCreate(BaseModel): + sid :int = Field(...,ge=0,le=10000,description="输入0-10000之间的学生编号") + open_time:date = Field(...,description="要写如下格式YYYY-MM-DD ") + offer_time:date = Field(...,description="要写如下格式YYYY-MM-DD ") + company_name: str = Field(...,max_length=50,description="公司名字") + salary :float = Field(...,ge=0.1,le=10000.0,description="月薪") + + @model_validator(mode="after") + def time_available(self): + if self.open_time>self.offer_time: + raise HTTPException(status_code=422,detail="就业时间必须大于offer下发时间") + return self +class StudentWorkCreate1(BaseModel): + sid :int = Field(...,ge=0,le=10000,description="输入0-10000之间的学生编号") + company_name: str = Field(..., max_length=50, description="公司名字") + salary: float = Field(..., ge=0.1, le=1000000.0, description="月薪") +class StudentWorks(BaseModel): + sid: int = Field(...,ge=0,le=10000,description="输入0-10000之间的你想修改的学生编号") + # s_name:str =Field(...,max_length=50,description="学生姓名") + # s_class : int = Field(...,ge = 1,le = 100,description="学生班级编号") + open_time: date = Field(description="输入你修改后的时间,要写如下格式YYYY-MM-DD, ",default=date(1970,1,1)) + offer_time: date = Field( description="输入你修改后的时间,要写如下格式YYYY-MM-DD ",default=date(1970,1,1)) + company_name: str = Field( max_length=50, description="输入你修改后的公司名字",default="0") + salary: float|int = Field( ge=0.1, le=100000.0, description="输入你修改后的月薪",default=0) + + @model_validator(mode="after") + def time_available(self): + if self.open_time > self.offer_time: + raise HTTPException(status_code=422, detail="就业时间必须大于offer下发时间") + return self +# 允许 Pydantic 读取 SQLAlchemy ORM 对象 +model_config = ConfigDict(from_attributes=True) + + + + + + + +