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)
+
+
+
+
+
+
+
+