From 9c9e51d68f5e7cc1d93abbc878de18b43cc59691 Mon Sep 17 00:00:00 2001 From: geyuan <2732801331@qq.com> Date: Tue, 22 Sep 2026 22:55:17 +0800 Subject: [PATCH 01/19] =?UTF-8?q?=E6=94=B9=E6=8F=90=E4=BA=A4=E4=B8=8D?= =?UTF-8?q?=E4=B8=8A=E7=9A=84bud?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Teachers/dao/tea_dao.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Teachers/dao/tea_dao.py b/Teachers/dao/tea_dao.py index 0b3e152..1820930 100644 --- a/Teachers/dao/tea_dao.py +++ b/Teachers/dao/tea_dao.py @@ -50,8 +50,8 @@ def get_tea_dao(t,db): query = query.filter(Tea.sex == t.get('sex') ) if t.get('class_id'): query = query.filter(Tea.class_id == t.get('class_id') ) - if t.get('sub'): - query = query.filter(Tea.sub == t.get('sub') ) + if t.get('subject_id'): + query = query.filter(Tea.subject_id == t.get('subject_id') ) if t.get('home_place'): query = query.filter(Tea.home_place == t.get('home_place') ) if t.get('specialty'): @@ -67,7 +67,7 @@ def get_tea_dao(t,db): if t.get('phone'): query = query.filter(Tea.phone == t.get('phone') ) r = query.all() - return [{'id':i.id,'name':i.name,'class_id':i.class_id,'sub':i.sub,'sex':i.sex,'home_place':i.home_place + return [{'id':i.id,'name':i.name,'class_id':i.class_id,'sub':i.subject_id,'sex':i.sex,'home_place':i.home_place ,'specialty':i.specialty,'start_time':i.start_time,'work_experience':i.work_experience ,'collage':i.collage,'phone':i.phone} for i in r] @@ -98,8 +98,8 @@ def delete_other_tea_dao(t,db): query1 = query1.filter(Tea.sex == t.get('sex')) if t.get('class_id'): query1 = query1.filter(Tea.class_id == t.get('class_id')) - if t.get('sub'): - query1 = query1.filter(Tea.sub == t.get('sub')) + if t.get('subject_id'): + query1 = query1.filter(Tea.subject_id == t.get('subject_id')) if t.get('home_place'): query1 = query1.filter(Tea.home_place == t.get('home_place')) if t.get('collage'): From c0880f9a4463299bf91e3a2ee7600d0c2df62d10 Mon Sep 17 00:00:00 2001 From: Orangeeee Date: Tue, 22 Sep 2026 19:47:02 +0800 Subject: [PATCH 02/19] =?UTF-8?q?=E7=BB=9F=E8=AE=A1=E5=88=86=E6=9E=90?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E6=9B=B4=E6=96=B0=EF=BC=8C=E5=BE=85=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=EF=BC=8C=E4=BC=98=E5=8C=96=E6=89=80=E6=9C=89=E6=A8=A1?= =?UTF-8?q?=E5=9D=97main.py=E6=96=87=E4=BB=B6=EF=BC=8C=E4=BF=AE=E5=A4=8Dbu?= =?UTF-8?q?g=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- StatCalc/api/statcalc_api.py | 2 +- StatCalc/dao/statcalc_dao.py | 8 +++++--- StatCalc/main.py | 1 - Teachers/main.py | 4 ++-- class_management/main.py | 2 -- main.py | 3 ++- scores/main.py | 10 ++++++---- stu_jiuye/main.py | 5 +++-- students/main.py | 21 +++++++++++---------- 9 files changed, 30 insertions(+), 26 deletions(-) diff --git a/StatCalc/api/statcalc_api.py b/StatCalc/api/statcalc_api.py index d34051e..e2e4b35 100644 --- a/StatCalc/api/statcalc_api.py +++ b/StatCalc/api/statcalc_api.py @@ -35,7 +35,7 @@ def get_students(g:get_student_dao = Depends() ,description=f'查询每次考试成绩都在80分以上的学生的编号,姓名和成绩。' ) def get_students(db=Depends(get_db)): - result = get_student_dao( db=db ) + result = get_score_80( db=db ) if result: return result raise HTTPException(status_code=404, detail="没有找到符合条件的学生") diff --git a/StatCalc/dao/statcalc_dao.py b/StatCalc/dao/statcalc_dao.py index 2d2d1a5..97bd011 100644 --- a/StatCalc/dao/statcalc_dao.py +++ b/StatCalc/dao/statcalc_dao.py @@ -39,9 +39,11 @@ def get_class_count(g , db): from scores.model.score_model import Score def get_score_80(db): - q = (db.query(Score) - .filter(Score.score>=80) - .all()) + q = ( db.query(Score) + .group_by(Score.score) + .having( min(Score.score) >= 80) + .all() + ) return q diff --git a/StatCalc/main.py b/StatCalc/main.py index f47a322..21cf54b 100644 --- a/StatCalc/main.py +++ b/StatCalc/main.py @@ -1,7 +1,6 @@ from fastapi import FastAPI,APIRouter from StatCalc.api.statcalc_api import statcalc_api from databases import * -from StatCalc.model import statcalc_model from contextlib import asynccontextmanager StatCalc_API = APIRouter() diff --git a/Teachers/main.py b/Teachers/main.py index 583ea6b..ffe9558 100644 --- a/Teachers/main.py +++ b/Teachers/main.py @@ -11,9 +11,9 @@ Teachers_API.include_router(tea_api) app = FastAPI() app.include_router(tea_api,tags=["老师"]) -Base.metadata.create_all(engine1) - if __name__ == "__main__": + Base.metadata.create_all(engine1) + import uvicorn uvicorn.run('main:app', host='0.0.0.0', port=57000) """ diff --git a/class_management/main.py b/class_management/main.py index 991457d..780a49b 100644 --- a/class_management/main.py +++ b/class_management/main.py @@ -12,8 +12,6 @@ app = FastAPI() app.include_router(class_api) - - if __name__ =='__main__': Base.metadata.create_all(engine) diff --git a/main.py b/main.py index 6432ac7..ab6c36d 100644 --- a/main.py +++ b/main.py @@ -17,9 +17,10 @@ app.include_router(Teachers_API,tags=["teachers"]) # app.include_router(StatCalc_API,tags=["StatCalc"]) -Base_all.metadata.create_all(bind=engine_all) if __name__ == "__main__": + Base_all.metadata.create_all(bind=engine_all) + def main(): print("Hello from student-manage-system!") diff --git a/scores/main.py b/scores/main.py index 20ffca5..fcc4d02 100644 --- a/scores/main.py +++ b/scores/main.py @@ -6,12 +6,14 @@ from scores.database import engine,Base Scores_API = APIRouter() Scores_API.include_router(score_api) -# 自测接口 -app = FastAPI(tags=['成绩'],title='成绩管理系统') -app.include_router(score_api) -Base.metadata.create_all(engine) if __name__ == '__main__': + # 自测接口 + app = FastAPI(tags=['成绩'], title='成绩管理系统') + app.include_router(score_api) + + Base.metadata.create_all(engine) + import uvicorn uvicorn.run('main:app',host='127.0.0.1',port=12346) \ No newline at end of file diff --git a/stu_jiuye/main.py b/stu_jiuye/main.py index de85ae5..191dd09 100644 --- a/stu_jiuye/main.py +++ b/stu_jiuye/main.py @@ -11,12 +11,13 @@ Shtudent_Jiuye.include_router(CURD) app=FastAPI() -Base.metadata.create_all(engine) + app.include_router(CURD,tags=['就业管理系统']) - if __name__=='__main__': + Base.metadata.create_all(engine) + import uvicorn uvicorn.run('main:app', host='127.0.0.1', port=12395) diff --git a/students/main.py b/students/main.py index b6fd5f9..d3aa661 100644 --- a/students/main.py +++ b/students/main.py @@ -8,18 +8,19 @@ from contextlib import asynccontextmanager Students_API = APIRouter() Students_API.include_router(s_api) -# 自测接口 -@asynccontextmanager -async def S_Fastapi(app: FastAPI): - Base.metadata.create_all(engine1) - yield - engine1.dispose() - -app = FastAPI(title="学生管理系统",lifespan=S_Fastapi) # 这里必须把上面写的加上 -app.include_router(s_api,tags=["students"]) - if __name__ == "__main__": + # 自测接口 + @asynccontextmanager + async def S_Fastapi(app: FastAPI): + Base.metadata.create_all(engine1) + yield + engine1.dispose() + + + app = FastAPI(title="学生管理系统", lifespan=S_Fastapi) # 这里必须把上面写的加上 + app.include_router(s_api, tags=["students"]) + def main(): print("Hello from student-manage-system!") From 65d67e7cf6030d5c7821022d097e0b63b2f200be Mon Sep 17 00:00:00 2001 From: cyf <15271199537@163.com> Date: Tue, 22 Sep 2026 19:33:36 +0800 Subject: [PATCH 03/19] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BA=86num=E7=9A=84?= =?UTF-8?q?=E5=94=AF=E4=B8=80=E9=94=AE=EF=BC=8C=E4=BF=AE=E6=94=B9=E4=BA=86?= =?UTF-8?q?dao=E5=92=8Capi?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- class_management/api/class_management_api.py | 71 ++++++++------ class_management/dao/class_management_dao.py | 98 ++++++++----------- class_management/database.py | 5 +- class_management/main.py | 1 + .../model/class_management_model.py | 15 +-- .../schema/class_management_request.py | 7 +- 6 files changed, 88 insertions(+), 109 deletions(-) diff --git a/class_management/api/class_management_api.py b/class_management/api/class_management_api.py index 02e95b6..bc448e2 100644 --- a/class_management/api/class_management_api.py +++ b/class_management/api/class_management_api.py @@ -7,24 +7,52 @@ from class_management.schema.class_management_request import ClassCreate, ClassR class_api = APIRouter(prefix='/classes') # ,tags=['班级管理模块'] - +#新增接口 @class_api.post("",summary='新增班级') def add_class(cla:ClassCreate,db=Depends(get_db)): c_dict = cla.model_dump() - r = add_class_dao(c=c_dict,db=db) - if not r: - raise HTTPException(status_code=500,detail='服务器繁忙,请稍后添加!') - return ClassResponse(totals=1,data=c_dict) + res = add_class_dao(c=c_dict,db=db) + if not res: + raise HTTPException(status_code=400,detail='新增失败,班级已存在') + return ClassResponse(detail='新增成功',totals=1,data=c_dict) -@class_api.get('/{id}',summary='根据id查询班级') -def get_one_class(id:int,db=Depends(get_db)): - res = get_class_dao(c={'id':id},db=db) +#更新接口 +@class_api.put("/{class_id}",summary='修改班级信息') +def update_class(class_id:int + ,update_info:ClassUpdate + ,db=Depends(get_db) + ): + update_dict=update_info.model_dump(exclude_unset=True) + if not update_dict: + raise HTTPException(status_code=400, detail="没有传入要修改的字段") + row_count = update_class_dao(cid=class_id, update_data=update_dict, db=db) + if not row_count : + raise HTTPException(status_code=404, detail="班级不存在,修改失败") + return ClassResponse(detail="修改成功", data={"id": class_id}) + + +#删除接口 +@class_api.delete('/{class_id}',summary='逻辑删除班级') +def remove_class(class_id:int,db=Depends(get_db)): + del_rows = delete_class_dao(cid = class_id,db=db) + if not del_rows: + raise HTTPException(status_code=404, detail="班级不存在,删除失败") + return ClassResponse(detail='删除成功',data={'id':class_id}) + + + +#单条查询接口 +@class_api.get('/{class_id}',summary='根据id查询班级') +def get_one_class(class_id:int,db=Depends(get_db)): + res = get_class_dao(c={'id':class_id},db=db) if not res: raise HTTPException(status_code=404, detail="该班级不存在或已删除") return ClassResponse(totals=1,data=res[0]) -@class_api.get('',summary='多字段查询班级') + +#分类查询 +@class_api.get('',summary='多字段分页查询班级') def get_some_classes( num:str|None = Query(None,description='班级编号') ,name:str|None = Query(None,description='班级名称') ,head_teacher_id:int|None = Query(None,description='班主任') @@ -33,10 +61,9 @@ def get_some_classes( num:str|None = Query(None,description='班级编号') ,class_start_time:date|None = Query(None, description="开班日期,格式YYYY‑MM‑DD") ,class_end_time: date|None = Query(None, description="结课日期,格式YYYY‑MM‑DD") ,page:int = Query(1,ge=1,description='页码,从1开始') - ,page_size:int = Query(5,ge=1,le=50,description='每页信息条数') + ,page_size:int = Query(5,ge=1,le=20,description='每页信息条数') ,db=Depends(get_db) ): - c_dict = { 'num': num, 'name': name, @@ -52,7 +79,7 @@ def get_some_classes( num:str|None = Query(None,description='班级编号') res = get_class_dao(c=c_dict,db=db) total = len(res) - #内存分页 + #分页 start_index = (page-1)*page_size page_data = res[start_index:start_index + page_size] @@ -61,23 +88,3 @@ def get_some_classes( num:str|None = Query(None,description='班级编号') -@class_api.put("/{class_id}",summary='修改班级信息') -def update_class(class_id:int - ,update_info:ClassUpdate - ,db=Depends(get_db) - ): - update_dict=update_info.model_dump(exclude_unset=True) - if not update_dict: - raise HTTPException(status_code=400, detail="没有传入要修改的字段") - row_count = update_class_dao(cid=class_id, update_data=update_dict, db=db) - if row_count <= 0: - raise HTTPException(status_code=404, detail="班级不存在,修改失败") - return ClassResponse(detail="修改成功", data={"class_id": id}) - - -@class_api.delete('/{id}',summary='逻辑删除班级') -def remove_class(id:int,db=Depends(get_db)): - del_rows = delete_class_dao(id,db) - if del_rows <= 0: - raise HTTPException(status_code=404, detail="班级不存在,删除失败") - return ClassResponse(detail='删除成功',data={'id':id}) diff --git a/class_management/dao/class_management_dao.py b/class_management/dao/class_management_dao.py index fdc056d..7b4450b 100644 --- a/class_management/dao/class_management_dao.py +++ b/class_management/dao/class_management_dao.py @@ -1,6 +1,46 @@ from class_management.model.class_management_model import ClassInfo from sqlalchemy.orm import Session +#新增班级 +def add_class_dao(c,db): + try: + c1 = ClassInfo(**c) + db.add(c1) + except: + db.rollback() + return False + else: + db.commit() + return True + + +#更新班级信息 +def update_class_dao(cid,update_data,db): + try: + rows = db.query(ClassInfo)\ + .filter(ClassInfo.id == cid + ,ClassInfo.is_delete==0)\ + .update(update_data) + except : + db.rollback() + return False + else: + db.commit() + return rows + + +#删除(逻辑删除) +def delete_class_dao(cid,db): + try: + rows = db.query(ClassInfo)\ + .filter(ClassInfo.id == cid,ClassInfo.is_delete==0)\ + .update({'is_delete':1}) + db.commit() + return rows + except Exception as e: + db.rollback() + print('删除失败',e) + return 0 #查询 @@ -34,64 +74,6 @@ def get_class_dao(c:dict,db:Session) : ,'tutor_teacher_id':i.tutor_teacher_id ,'class_start_time':i.class_start_time ,'class_end_time':i.class_end_time - ,"is_delete": i.is_delete - ,"create_time": i.create_time - ,"update_time": i.update_time } for i in res ] - -#新增班级 -def add_class_dao(c:dict,db:Session): - try: - exist_class = db.query(ClassInfo)\ - .filter(ClassInfo.name == c['name'] - ,ClassInfo.is_delete == 0)\ - .first() - if exist_class: - msg = '班级名称已存在' - print(msg) - return (False,msg) - c1 = ClassInfo(**c) - db.add(c1) - db.commit() - db.refresh(c1) - return (True,None) - - except Exception as e: - db.rollback() - err_msg = f'数据库异常:{str(e)}' - print(err_msg) - return (False,err_msg) - - -#修改 -def update_class_dao(cid:int,update_data,db): - try: - rows = db.query(ClassInfo)\ - .filter(ClassInfo.id == cid - ,ClassInfo.is_delete==0)\ - .update(update_data) - db.commit() - return rows - - except Exception as e: - db.rollback() - print(f"update_class_dao异常:{e}") - return 0 - - - -#删除(逻辑删除) -def delete_class_dao(cid,db): - try: - rows = db.query(ClassInfo)\ - .filter(ClassInfo.id == cid,ClassInfo.is_delete==0)\ - .update({'is_delete':1}) - db.commit() - return rows - except Exception as e: - db.rollback() - print(f"delete_class_dao异常:{e}") - rows = 0 - diff --git a/class_management/database.py b/class_management/database.py index e3b772a..d546110 100644 --- a/class_management/database.py +++ b/class_management/database.py @@ -11,14 +11,13 @@ DB_HOST = os.getenv("DB_HOST", "localhost") DB_PORT = os.getenv("DB_PORT", "3306") DB_NAME = os.getenv("DB_NAME", "student_manage_system") -class_management_rul = f"mysql+pymysql://{DB_USER}:{DB_PASSWORD}@{DB_HOST}:{DB_PORT}/{DB_NAME}?charset=utf8mb4" +class_management_url = "mysql+pymysql://root:123456@localhost:3306/student_manage_system?charset=utf8mb4" -engine = create_engine(class_management_rul) +engine = create_engine(class_management_url) SessionLocal = sessionmaker(bind=engine,autocommit=False, autoflush=False) Base = declarative_base() # 获取数据库会话依赖 - def get_db(): db = SessionLocal() try : diff --git a/class_management/main.py b/class_management/main.py index 780a49b..8010e2e 100644 --- a/class_management/main.py +++ b/class_management/main.py @@ -3,6 +3,7 @@ from class_management.api.class_management_api import class_api from class_management.model.class_management_model import ClassInfo from class_management.database import Base,engine + # 合并接口 Classes_API = APIRouter() Classes_API.include_router(class_api) diff --git a/class_management/model/class_management_model.py b/class_management/model/class_management_model.py index cacb649..af66fa6 100644 --- a/class_management/model/class_management_model.py +++ b/class_management/model/class_management_model.py @@ -14,6 +14,7 @@ class ClassInfo(Base_all): ) num = Column(String(50) ,nullable=False + ,unique=True ,comment='班级编号' ) name = Column(String(50) @@ -21,26 +22,18 @@ class ClassInfo(Base_all): ,comment='班级名称' ) head_teacher_id = Column(Integer - # ,ForeignKey('teacher.id') + ,ForeignKey('teacher.id') ,comment='班主任编号' ) coach_teacher_id = Column(Integer - # ,ForeignKey('teacher.id') + ,ForeignKey('teacher.id') ,comment='授课老师编号' ) tutor_teacher_id = Column(Integer - # ,ForeignKey('teacher.id') + ,ForeignKey('teacher.id') ,comment='助教老师编号' ) - # class_teacher = Column(String(50) - # ,nullable=False - # ,comment='班主任' - # ) - # class_lecturer = Column(String(50) - # ,nullable=False - # ,comment='授课老师' - # ) class_start_time = Column(Date ,comment='开班日期' ) diff --git a/class_management/schema/class_management_request.py b/class_management/schema/class_management_request.py index 8e50e31..4bb6a7b 100644 --- a/class_management/schema/class_management_request.py +++ b/class_management/schema/class_management_request.py @@ -12,17 +12,14 @@ class ClassBase(BaseModel): class_start_time:date|None = Field(None,description='开班日期 YYYY‑MM‑DD') class_end_time:date|None = Field(None,description='结课日期 YYYY‑MM‑DD') -#新增班级请求体:num,name必填,其余继承父类ClassBase +#新增班级请求体:继承父类ClassBase class ClassCreate(ClassBase): - num:str = Field(...,description='班级编号') - name:str = Field(...,description='班级名称') + pass #修改班级请求体,继承ClassBase,全部字段可选,传哪个就更新哪个 class ClassUpdate(ClassBase): pass - - class ClassResponse(BaseModel): code:int = 200 detail:str = 'OK' From c1813ae70008ce9769444f4ce5bba9b52c010128 Mon Sep 17 00:00:00 2001 From: longtrying Date: Tue, 22 Sep 2026 19:53:43 +0800 Subject: [PATCH 04/19] =?UTF-8?q?=E5=88=A0=E9=99=A4=20.env?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 以免频繁重新覆盖修改。 --- .env | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 .env diff --git a/.env b/.env deleted file mode 100644 index 30b7315..0000000 --- a/.env +++ /dev/null @@ -1,7 +0,0 @@ -# .env(放项目根目录,每个人自己建,不提交 Git) - # 用来修改数据库账户密码 -DB_USER=root -DB_PASSWORD=420821 -DB_HOST=localhost -DB_PORT=3306 -DB_NAME=student_manage_system \ No newline at end of file From 75f23e39becb4c014c414eb5339c1193e7ec06f9 Mon Sep 17 00:00:00 2001 From: chen <2966418553@qq.com> Date: Tue, 22 Sep 2026 19:56:12 +0800 Subject: [PATCH 05/19] =?UTF-8?q?dao=E6=94=B9=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scores/dao/score_dao.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/scores/dao/score_dao.py b/scores/dao/score_dao.py index b972d62..1f499cf 100644 --- a/scores/dao/score_dao.py +++ b/scores/dao/score_dao.py @@ -19,7 +19,7 @@ def get_scores_dao(s,db): if aa: return [{'id':i.id,'sid':i.sid ,'cid':i.cid,'num':i.num - ,'score': i.score,'t_subject':i.tsub + ,'score': i.score,'t_subject':i.t_subject ,'create_date':i.create_date,'update_date':i.update_date ,'is_deleted': i.is_deleted,'deleted_date': i.deleted_date }for i in aa] @@ -28,8 +28,7 @@ def get_scores_dao(s,db): def add_scores_dao(b,db): try: - aa = db.query(Score).filter(Score.sid==b['sid'] - ,Score.t_subject==b['t_subject']).all() + aa = db.query(Score).filter(Score.t_subject==b['t_subject']).all() if aa: raise ValueError else: From ffcb40db41feda070a729793223cd72df305006a Mon Sep 17 00:00:00 2001 From: Orangeeee Date: Tue, 22 Sep 2026 20:28:02 +0800 Subject: [PATCH 06/19] =?UTF-8?q?=E7=BB=9F=E8=AE=A1=E5=88=86=E6=9E=90?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E6=9B=B4=E6=96=B0=EF=BC=8C=E5=BE=85=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=EF=BC=8C=E7=BB=9F=E8=AE=A1=E5=88=86=E6=9E=90=E6=A8=A1?= =?UTF-8?q?=E5=9D=97=E6=9B=B4=E6=96=B0=EF=BC=8C=E5=B0=B1=E4=B8=9A3?= =?UTF-8?q?=E4=B8=AA=E6=A8=A1=E5=9D=97=E6=9B=B4=E6=96=B0=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- StatCalc/api/statcalc_api.py | 60 ++++++++---------------------------- StatCalc/dao/statcalc_dao.py | 17 ++++++++-- 2 files changed, 26 insertions(+), 51 deletions(-) diff --git a/StatCalc/api/statcalc_api.py b/StatCalc/api/statcalc_api.py index e2e4b35..908a76a 100644 --- a/StatCalc/api/statcalc_api.py +++ b/StatCalc/api/statcalc_api.py @@ -44,11 +44,8 @@ def get_students(db=Depends(get_db)): ,summary='不及格成绩查询' ,description=f'查询有两次以上不及格的学生的姓名,班级和不及格成绩。' ) -def get_students( stu:StudentsQuery = Depends() - , db=Depends(get_db) - ): - s_dict = stu.model_dump(exclude_unset=True) # 没值的不要 - result = get_student_dao( s=s_dict , db=db ) +def get_students( db=Depends(get_db) ): + result = get_score_80( db=db ) if result: return result raise HTTPException(status_code=404, detail="没有找到符合条件的学生") @@ -66,47 +63,10 @@ def get_students( stu:StudentsQuery = Depends() return result raise HTTPException(status_code=404, detail="没有找到符合条件的学生") -@statcalc_api.get("/statcalc" - ,summary='排名前五的学生信息' - ,description=f'统计就业薪资最高的前五名学生的姓名,班级和就业时间,就业公司。' - ) -def get_students( stu:StudentsQuery = Depends() - , db=Depends(get_db) - ): - s_dict = stu.model_dump(exclude_unset=True) # 没值的不要 - result = get_student_dao( s=s_dict , db=db ) - if result: - return result - raise HTTPException(status_code=404, detail="没有找到符合条件的学生") -@statcalc_api.get("/statcalc" - ,summary='就业时长统计' - ,description=f'统计每个学生的就业时长(offer下发时间-就业开放时间)。' - ) -def get_students( stu:StudentsQuery = Depends() - , db=Depends(get_db) - ): - s_dict = stu.model_dump(exclude_unset=True) # 没值的不要 - result = get_student_dao( s=s_dict , db=db ) - if result: - return result - raise HTTPException(status_code=404, detail="没有找到符合条件的学生") +from stu_jiuye.model import * -@statcalc_api.get("/statcalc" - ,summary='班级的平均就业时长' - ,description=f'统计每个班级的平均就业时长(只统计进入就业阶段的学生,也就是有就业开放时间)' - ) -def get_students( stu:StudentsQuery = Depends() - , db=Depends(get_db) - ): - s_dict = stu.model_dump(exclude_unset=True) # 没值的不要 - result = get_student_dao( s=s_dict , db=db ) - if result: - return result - raise HTTPException(status_code=404, detail="没有找到符合条件的学生") - - -@CURD.get('/Top5',summary='就业薪资Top5') +@statcalc_api.get('/Top5',summary='就业薪资Top5') def salarytop5(db=Depends(get_db)): q = db.query(Employments,Company.employment_company) \ .join(Company, Employments.company_id == Company.id) \ @@ -115,16 +75,19 @@ def salarytop5(db=Depends(get_db)): .limit(5) .all() return [{'学生姓名':i.sname,'学生班级编号':i.class_num,'就业时间':i.offer_recived_time,'公司':employment_company} for i,employment_company in q] -@CURD.get('/worktime',summary='学生就业时常') +@statcalc_api.get('/worktime',summary='学生就业时长') def worktime(db=Depends(get_db)): q = db.query(Employments)\ .filter(Employments.is_deleted==0)\ .all() - return [{'学生姓名':i.sname,'就业时常':f'{i.offer_recived_time-i.employment_open_time}' if i.offer_recived_time and i.employment_open_time else '暂无数据'} for i in q] + return [ + {'学生姓名':i.sname + ,'就业时常':f'{i.offer_recived_time-i.employment_open_time}' + if i.offer_recived_time and i.employment_open_time else '暂无数据'} for i in q + ] - -@CURD.get('/avgworktime',summary='学生平均就业时常') +@statcalc_api.get('/avgworktime',summary='学生平均就业时长') def avgworktime(db=Depends(get_db)): q = db.query(Employments)\ .filter(Employments.employment_open_time.isnot(None) @@ -139,3 +102,4 @@ def avgworktime(db=Depends(get_db)): '人数': len(q), '平均就业时常(天)': round(avg_days, 2) } + diff --git a/StatCalc/dao/statcalc_dao.py b/StatCalc/dao/statcalc_dao.py index 97bd011..8c58f79 100644 --- a/StatCalc/dao/statcalc_dao.py +++ b/StatCalc/dao/statcalc_dao.py @@ -39,12 +39,23 @@ def get_class_count(g , db): from scores.model.score_model import Score def get_score_80(db): - q = ( db.query(Score) - .group_by(Score.score) - .having( min(Score.score) >= 80) + sq = ( db.query(Students.id) + .join(Score, Score.sid == Students.id) + .filer(Score.score < 80 ) + .group_by(Students.id) + .having(func.count(Score.id) > 2 ) + .sq() + ) + + q = ( db.query(Students.name,ClassInfo.name,Score.score ) + .join(ClassInfo, ClassInfo.id == Students.class_id) + .join(Score, Score.sid == Students.id) + .filer(Students.id.in_(sq),Score.score < 80) .all() ) return q + + From 7d5f352c6986ba05a10c920b912dec5c2e629aa2 Mon Sep 17 00:00:00 2001 From: chen <2966418553@qq.com> Date: Tue, 22 Sep 2026 20:39:18 +0800 Subject: [PATCH 07/19] =?UTF-8?q?=E7=BB=9F=E8=AE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scores/api/score_api.py | 2 +- scores/api/statistic_api.py | 26 +++++++++++++ scores/dao/statistic_dao.py | 78 +++++++++++++++++++++++++++++++++++++ scores/main.py | 9 +++-- 4 files changed, 110 insertions(+), 5 deletions(-) create mode 100644 scores/api/statistic_api.py create mode 100644 scores/dao/statistic_dao.py diff --git a/scores/api/score_api.py b/scores/api/score_api.py index ec1429d..02aaf1a 100644 --- a/scores/api/score_api.py +++ b/scores/api/score_api.py @@ -37,7 +37,7 @@ def update_scores(score:ScoreRequest,sid:int,cid:int,num:int,t_subject:int,db=De @score_api.delete('/Score',summary='成绩删除',description=f'查询条件为学号,班级号,考试科目,然后进行删除') def delete_scores(sid:int,cid:int,t_subject:int,db=Depends(get_db)): aaa = delete_scores_dao(sid,cid,t_subject,db) - if aaa==1: + if aaa==-1: raise HTTPException(status_code=500,detail='删除失败') if aaa==0: raise HTTPException(status_code=404,detail='记录不存在') diff --git a/scores/api/statistic_api.py b/scores/api/statistic_api.py new file mode 100644 index 0000000..e5c7f04 --- /dev/null +++ b/scores/api/statistic_api.py @@ -0,0 +1,26 @@ +from fastapi import APIRouter, Depends, HTTPException +from scores.database import get_db +from scores.dao.statistic_dao import get_top_students_dao,get_failing_students_dao,get_class_avg_dao + +statistic_api = APIRouter() + +@statistic_api.get('/statistic', summary='查询每次考试都在80分以上的学生') +def get_top_students(db=Depends(get_db)): + q = get_top_students_dao(db) + if not q: + return [] + return q + +@statistic_api.get('/Score/failing', summary='查询两次以上不及格的学生') +def get_failing_students(db=Depends(get_db)): + result = get_failing_students_dao(db) + if not result: + return [] + return result + +@statistic_api.get('/Score/class-avg', summary='统计每次考试每个班级的平均分') +def get_class_avg(db=Depends(get_db)): + result = get_class_avg_dao(db) + if not result: + return [] + return result \ No newline at end of file diff --git a/scores/dao/statistic_dao.py b/scores/dao/statistic_dao.py new file mode 100644 index 0000000..335124f --- /dev/null +++ b/scores/dao/statistic_dao.py @@ -0,0 +1,78 @@ +from sqlalchemy import func +from scores.model.score_model import Score +from students.model.students_model import Students +from class_management.model.class_management_model import ClassInfo + +def get_top_students_dao(db): + top_sids = (db.query(Score.sid) + .filter(Score.is_deleted == 0) + .group_by(Score.sid, Score.num) + .having(func.min(Score.score) >= 80) + .subquery() ) + + results = (db.query(Students.id, + Students.name, + Score.num, + Score.t_subject, + Score.score,) + .join(Score, Students.id == Score.sid) + .filter( Score.sid.in_(top_sids), + Score.is_deleted == 0,) + .order_by(Students.id, Score.num) + .all()) + + return [{"sid": r.sid, + "name": r.name, + "score": r.score,} + for r in results] + + +def get_failing_students_dao(db): + failing_sids = (db.query(Score.sid) + .filter(Score.score < 60, + Score.is_deleted == 0,) + .group_by(Score.sid) + .having(func.count() >= 2) + .subquery()) + + results = (db.query( + Students.sid, + Students.name, + ClassInfo.name.label("class_name"), + Score.num, + Score.t_subject, + Score.score,) + .join(Score, Students.id == Score.sid) + .join(ClassInfo, Score.cid == ClassInfo.id) + .filter(Score.sid.in_(failing_sids), + Score.score < 60, + Score.is_deleted == 0,) + .order_by(ClassInfo.id, Score.num) + .all()) + + return [{"sid": r.sid, + "name": r.name, + "class_name": r.class_name, + "num": r.num, + "t_subject": r.tsub, + "score": r.score,} + for r in results] + + + +def get_class_avg_dao(db): + results = (db.query(Score.num, + Score.cid, + ClassInfo.name.label("class_name"), + func.avg(Score.score).label("avg_score")) + .join(ClassInfo, Score.cid == ClassInfo.id) + .filter(Score.is_deleted == 0) + .group_by(Score.num, Score.cid, ClassInfo.name) + .order_by(func.avg(Score.score).desc()) + .all()) + + return [ {"num": r.num, + "cid": r.cid, + "class_name": r.class_name, + "avg_score": round(float(r.avg_score), 2),} + for r in results] \ No newline at end of file diff --git a/scores/main.py b/scores/main.py index fcc4d02..dfd161e 100644 --- a/scores/main.py +++ b/scores/main.py @@ -1,19 +1,20 @@ from fastapi import FastAPI,APIRouter from scores.api.score_api import score_api from scores.database import engine,Base +from scores.api.score_api import score_api # 合并接口 Scores_API = APIRouter() Scores_API.include_router(score_api) - +# 自测接口 +app = FastAPI(tags=['成绩'], title='成绩管理系统') if __name__ == '__main__': - # 自测接口 - app = FastAPI(tags=['成绩'], title='成绩管理系统') + app.include_router(score_api) Base.metadata.create_all(engine) import uvicorn - uvicorn.run('main:app',host='127.0.0.1',port=12346) \ No newline at end of file + uvicorn.run('scores.main:app',host='127.0.0.1',port=12346) \ No newline at end of file From a1d7adba94b440227855916e8d1d5c4c9d86886b Mon Sep 17 00:00:00 2001 From: Orangeeee Date: Tue, 22 Sep 2026 21:05:09 +0800 Subject: [PATCH 08/19] =?UTF-8?q?=E5=85=A8=E9=83=A8=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E7=A1=AE=E8=AE=A4=EF=BC=8C=E6=97=A0=E5=9F=BA=E7=A1=80=E9=94=99?= =?UTF-8?q?=E8=AF=AF=EF=BC=8C=E5=90=84=E8=87=AA=E6=B5=8B=E8=AF=95=E5=90=84?= =?UTF-8?q?=E8=87=AA=E7=AB=AF=E5=8F=A3bug=EF=BC=8C=E6=9A=82=E6=97=B6?= =?UTF-8?q?=E6=B2=A1=E6=9C=89=E8=87=AA=E5=8A=A8=E5=AF=BC=E5=85=A5=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- StatCalc/api/statcalc_api.py | 37 ++++++++++++----------------- StatCalc/dao/statcalc_dao.py | 15 ++++++++++++ StatCalc/schema/statcalc_request.py | 2 +- Teachers/main.py | 2 +- main.py | 5 ++-- scores/dao/statistic_dao.py | 2 +- stu_jiuye/main.py | 6 +---- students/main.py | 18 +++++++------- students/schema/students_request.py | 4 ++-- 9 files changed, 47 insertions(+), 44 deletions(-) diff --git a/StatCalc/api/statcalc_api.py b/StatCalc/api/statcalc_api.py index 908a76a..0f58740 100644 --- a/StatCalc/api/statcalc_api.py +++ b/StatCalc/api/statcalc_api.py @@ -2,13 +2,12 @@ from fastapi import APIRouter , Depends , HTTPException from StatCalc.dao.statcalc_dao import * -from StatCalc.model.statcalc_model import * from StatCalc.schema.statcalc_request import * from databases import * statcalc_api = APIRouter() -@statcalc_api.get("/statcalc" +@statcalc_api.get("/statcalc/age" ,summary='人员信息查询' ,description=f'查询所有超过30岁的学员的信息。' ) @@ -18,19 +17,19 @@ def get_students(db=Depends(get_db)): return result raise HTTPException(status_code=404, detail="没有找到符合条件的学生") -@statcalc_api.get("/statcalc" +@statcalc_api.get("/statcalc/students" ,summary='人数统计' ,description=f'统计每个班级的人数以及男生女生的人数。' ) -def get_students(g:get_student_dao = Depends() +def get_students(headcount:get_student_dao ,db=Depends(get_db) ): - result = get_class_count( g=g , db=db ) + result = get_class_count( g=headcount , db=db ) if result: return result raise HTTPException(status_code=404, detail="没有找到符合条件的学生") -@statcalc_api.get("/statcalc" +@statcalc_api.get("/statcalc/scores" ,summary='80分以上成绩学生信息查询' ,description=f'查询每次考试成绩都在80分以上的学生的编号,姓名和成绩。' ) @@ -40,7 +39,7 @@ def get_students(db=Depends(get_db)): return result raise HTTPException(status_code=404, detail="没有找到符合条件的学生") -@statcalc_api.get("/statcalc" +@statcalc_api.get("/statcalc/fail" ,summary='不及格成绩查询' ,description=f'查询有两次以上不及格的学生的姓名,班级和不及格成绩。' ) @@ -50,23 +49,17 @@ def get_students( db=Depends(get_db) ): return result raise HTTPException(status_code=404, detail="没有找到符合条件的学生") -@statcalc_api.get("/statcalc" - ,summary='班级平均分查询' - ,description=f'统计每次考试每个班级的平均分,按照从高到低排序。' - ) -def get_students( stu:StudentsQuery = Depends() - , db=Depends(get_db) - ): - s_dict = stu.model_dump(exclude_unset=True) # 没值的不要 - result = get_student_dao( s=s_dict , db=db ) - if result: - return result - raise HTTPException(status_code=404, detail="没有找到符合条件的学生") +@statcalc_api.get('/statcalc/average', summary='统计每次考试每个班级的平均分') +def get_class_avg(db=Depends(get_db)): + result = get_class_avg_dao(db) + if not result: + return [] + return result from stu_jiuye.model import * -@statcalc_api.get('/Top5',summary='就业薪资Top5') +@statcalc_api.get('/statcalc/top',summary='就业薪资Top5') def salarytop5(db=Depends(get_db)): q = db.query(Employments,Company.employment_company) \ .join(Company, Employments.company_id == Company.id) \ @@ -75,7 +68,7 @@ def salarytop5(db=Depends(get_db)): .limit(5) .all() return [{'学生姓名':i.sname,'学生班级编号':i.class_num,'就业时间':i.offer_recived_time,'公司':employment_company} for i,employment_company in q] -@statcalc_api.get('/worktime',summary='学生就业时长') +@statcalc_api.get('/statcalc/job',summary='学生就业时长') def worktime(db=Depends(get_db)): q = db.query(Employments)\ .filter(Employments.is_deleted==0)\ @@ -87,7 +80,7 @@ def worktime(db=Depends(get_db)): if i.offer_recived_time and i.employment_open_time else '暂无数据'} for i in q ] -@statcalc_api.get('/avgworktime',summary='学生平均就业时长') +@statcalc_api.get('/statcalc/avgjob',summary='学生平均就业时长') def avgworktime(db=Depends(get_db)): q = db.query(Employments)\ .filter(Employments.employment_open_time.isnot(None) diff --git a/StatCalc/dao/statcalc_dao.py b/StatCalc/dao/statcalc_dao.py index 8c58f79..6d23b76 100644 --- a/StatCalc/dao/statcalc_dao.py +++ b/StatCalc/dao/statcalc_dao.py @@ -55,7 +55,22 @@ def get_score_80(db): ) return q +def get_class_avg_dao(db): + results = (db.query(Score.num, + Score.cid, + ClassInfo.name.label("class_name"), + func.avg(Score.score).label("avg_score")) + .join(ClassInfo, Score.cid == ClassInfo.id) + .filter(Score.is_deleted == 0) + .group_by(Score.num, Score.cid, ClassInfo.name) + .order_by(func.avg(Score.score).desc()) + .all()) + return [ {"num": r.num, + "cid": r.cid, + "class_name": r.class_name, + "avg_score": round(float(r.avg_score), 2),} + for r in results] diff --git a/StatCalc/schema/statcalc_request.py b/StatCalc/schema/statcalc_request.py index c1c4c7b..727486d 100644 --- a/StatCalc/schema/statcalc_request.py +++ b/StatCalc/schema/statcalc_request.py @@ -4,7 +4,7 @@ from pydantic import BaseModel , Field , field_validator from datetime import datetime import enum -class get_student_dao(enum.Enum): +class get_student_dao(str , enum.Enum): get_class = "班级人数" get_sex = "男女人数" get_class_sex = "班级中男女人数" diff --git a/Teachers/main.py b/Teachers/main.py index ffe9558..bd87a8d 100644 --- a/Teachers/main.py +++ b/Teachers/main.py @@ -9,9 +9,9 @@ Teachers_API.include_router(tea_api) # 自测接口 app = FastAPI() -app.include_router(tea_api,tags=["老师"]) if __name__ == "__main__": + app.include_router(tea_api, tags=["老师"]) Base.metadata.create_all(engine1) import uvicorn diff --git a/main.py b/main.py index ab6c36d..bbc63d7 100644 --- a/main.py +++ b/main.py @@ -4,7 +4,7 @@ from scores.main import Scores_API from stu_jiuye.main import Shtudent_Jiuye from students.main import Students_API from Teachers.main import Teachers_API -# from StatCalc.main import StatCalc_API +from StatCalc.main import StatCalc_API from databases import * app = FastAPI(title="学生管理系统") @@ -14,8 +14,7 @@ app.include_router(Scores_API,tags=["scores"]) app.include_router(Shtudent_Jiuye,tags=["Employments"]) app.include_router(Students_API,tags=["students"]) app.include_router(Teachers_API,tags=["teachers"]) -# app.include_router(StatCalc_API,tags=["StatCalc"]) - +app.include_router(StatCalc_API,tags=["StatCalc"]) if __name__ == "__main__": diff --git a/scores/dao/statistic_dao.py b/scores/dao/statistic_dao.py index 335124f..3590c17 100644 --- a/scores/dao/statistic_dao.py +++ b/scores/dao/statistic_dao.py @@ -36,7 +36,7 @@ def get_failing_students_dao(db): .subquery()) results = (db.query( - Students.sid, + Students.id, Students.name, ClassInfo.name.label("class_name"), Score.num, diff --git a/stu_jiuye/main.py b/stu_jiuye/main.py index 191dd09..0f42c8f 100644 --- a/stu_jiuye/main.py +++ b/stu_jiuye/main.py @@ -8,14 +8,10 @@ Shtudent_Jiuye = APIRouter() Shtudent_Jiuye.include_router(CURD) # 自测接口 - - app=FastAPI() -app.include_router(CURD,tags=['就业管理系统']) - - if __name__=='__main__': + app.include_router(CURD, tags=['就业管理系统']) Base.metadata.create_all(engine) import uvicorn diff --git a/students/main.py b/students/main.py index d3aa661..3bbb3ae 100644 --- a/students/main.py +++ b/students/main.py @@ -9,16 +9,16 @@ Students_API = APIRouter() Students_API.include_router(s_api) +# 自测接口 +@asynccontextmanager +async def S_Fastapi(app: FastAPI): + Base.metadata.create_all(engine1) + yield + engine1.dispose() + +app = FastAPI(title="学生管理系统", lifespan=S_Fastapi) # 这里必须把上面写的加上 + if __name__ == "__main__": - # 自测接口 - @asynccontextmanager - async def S_Fastapi(app: FastAPI): - Base.metadata.create_all(engine1) - yield - engine1.dispose() - - - app = FastAPI(title="学生管理系统", lifespan=S_Fastapi) # 这里必须把上面写的加上 app.include_router(s_api, tags=["students"]) def main(): diff --git a/students/schema/students_request.py b/students/schema/students_request.py index baf6066..a92453c 100644 --- a/students/schema/students_request.py +++ b/students/schema/students_request.py @@ -4,7 +4,7 @@ from pydantic import BaseModel , Field , field_validator from datetime import datetime import enum -class SexEnum(enum.Enum): +class SexEnum(str , enum.Enum): m = '男' f = '女' @@ -27,7 +27,7 @@ class StudentsQuery(BaseModel): # 额外字段 phone:str | None = None -class EducationEnum(enum.Enum): +class EducationEnum(str , enum.Enum): z = '专科' ben = '本科' s = '硕士' From f2e525b5a52d7394893fb29ae520a6769e08c0ab Mon Sep 17 00:00:00 2001 From: chen <2966418553@qq.com> Date: Tue, 22 Sep 2026 21:03:15 +0800 Subject: [PATCH 09/19] =?UTF-8?q?=E7=BB=9F=E8=AE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scores/main.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/scores/main.py b/scores/main.py index dfd161e..aaebcdc 100644 --- a/scores/main.py +++ b/scores/main.py @@ -1,7 +1,7 @@ from fastapi import FastAPI,APIRouter from scores.api.score_api import score_api from scores.database import engine,Base -from scores.api.score_api import score_api +from scores.api.statistic_api import statistic_api # 合并接口 Scores_API = APIRouter() @@ -9,11 +9,12 @@ Scores_API.include_router(score_api) # 自测接口 app = FastAPI(tags=['成绩'], title='成绩管理系统') +app.include_router(score_api) +app.include_router(statistic_api) + if __name__ == '__main__': - app.include_router(score_api) - Base.metadata.create_all(engine) import uvicorn From 6e189d0c65e8dcd3a7d02bec0d0571c3c7bbd0bb Mon Sep 17 00:00:00 2001 From: cyf <15271199537@163.com> Date: Tue, 22 Sep 2026 21:23:24 +0800 Subject: [PATCH 10/19] =?UTF-8?q?=E6=9B=B4=E6=94=B9=E6=96=B0=E5=A2=9Edao?= =?UTF-8?q?=20=20bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- class_management/dao/class_management_dao.py | 7 +++++++ class_management/model/class_management_model.py | 6 +++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/class_management/dao/class_management_dao.py b/class_management/dao/class_management_dao.py index 7b4450b..4df3f09 100644 --- a/class_management/dao/class_management_dao.py +++ b/class_management/dao/class_management_dao.py @@ -4,6 +4,12 @@ from sqlalchemy.orm import Session #新增班级 def add_class_dao(c,db): try: + exist_class = db.query(ClassInfo).filter( + ClassInfo.num == c["num"], + ClassInfo.is_delete == 0 + ).first() + if exist_class: + return False c1 = ClassInfo(**c) db.add(c1) except: @@ -11,6 +17,7 @@ def add_class_dao(c,db): return False else: db.commit() + db.refresh(c1) return True diff --git a/class_management/model/class_management_model.py b/class_management/model/class_management_model.py index af66fa6..fb6c2aa 100644 --- a/class_management/model/class_management_model.py +++ b/class_management/model/class_management_model.py @@ -22,16 +22,16 @@ class ClassInfo(Base_all): ,comment='班级名称' ) head_teacher_id = Column(Integer - ,ForeignKey('teacher.id') + ,ForeignKey('teachers.id') ,comment='班主任编号' ) coach_teacher_id = Column(Integer - ,ForeignKey('teacher.id') + ,ForeignKey('teachers.id') ,comment='授课老师编号' ) tutor_teacher_id = Column(Integer - ,ForeignKey('teacher.id') + ,ForeignKey('teachers.id') ,comment='助教老师编号' ) class_start_time = Column(Date From dc243fb33f3bd8d29d11f69a3722ff0c9a7b75a0 Mon Sep 17 00:00:00 2001 From: yb <739325183@qq.com> Date: Tue, 22 Sep 2026 20:51:20 +0800 Subject: [PATCH 11/19] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=A4=96=E9=94=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- stu_jiuye/dao.py | 13 +++++-------- stu_jiuye/model.py | 14 +++++++------- stu_jiuye/request.py | 6 +++--- 3 files changed, 15 insertions(+), 18 deletions(-) diff --git a/stu_jiuye/dao.py b/stu_jiuye/dao.py index 9bf5d69..7d0a32b 100644 --- a/stu_jiuye/dao.py +++ b/stu_jiuye/dao.py @@ -83,10 +83,10 @@ def get_emp_dao( #获取学生 # ,page_size ): #根据选择条件获取信息 q = db.query(Employments,Company.employment_company,Address.somewhere) \ - .outerjoin(Company, Students.id == Employments.stuid) \ - .outerjoin(Company, ClassInfo.id == Employments.class_id)\ + .outerjoin(Students, Students.id == Employments.stuid) \ + .outerjoin(ClassInfo, ClassInfo.id == Employments.class_id)\ .outerjoin(Company,Employments.company_id==Company.id)\ - .outerjoin(Address,Company.address_id==Address.id)\ + .outerjoin(Address,Employments.address_id==Address.id)\ .filter(Employments.is_deleted == 0) #连接公司表和地址表,筛选未被删除信息 # if stuid: # q = q.filter( Employments.id == stuid ) @@ -99,7 +99,6 @@ def get_emp_dao( #获取学生 q = q.filter(Address.somewhere.like(f'%{somewhere}%')) if employment_company: #根据公司姓名筛选 q=q.filter(Company.employment_company.like(f'%{employment_company}%')) - # r = q.offset( (page-1)*page_size ).limit( page_size ).all() if min_salary is not None: #根据最小薪资筛选 q = q.filter(Employments.employment_salary >= min_salary) if max_salary is not None: ##根据最大薪资筛选 @@ -116,13 +115,11 @@ def get_emp_dao( #获取学生 r= q.all() if r: return [ {"id": i.id, - '学生姓名':i.sname, - '学生班级编号':i.class_id, + '学生姓名':sname, + '学生班级编号':class_id, "公司": employment_company or '未就业', "公司区域":somewhere or '-', - # "company_id": i.company_id, "薪资":i.employment_salary or '-', - # "address_id": i.address_id, "就业开放时间":i.employment_open_time.strftime('%Y-%m-%d') , "offer下发时间":i.offer_recived_time.strftime('%Y-%m-%d') # , "创建时间": i.create_time, diff --git a/stu_jiuye/model.py b/stu_jiuye/model.py index 3939295..0e9f44c 100644 --- a/stu_jiuye/model.py +++ b/stu_jiuye/model.py @@ -19,12 +19,14 @@ class Employments(Base_all): #学生 class_id = Column(Integer , ForeignKey('classes.id') ) #学生班级,冗余字段 - company_id = Column(Integer #公司id,外键匹配公司表 + company_id = Column(Integer # 公司id,外键匹配公司表 , ForeignKey('Company.id') , nullable=True - ) - + address_id = Column(Integer # 地址id,匹配地址表 + , ForeignKey('Address.id') # 外键地址表id + , nullable=False # 非空约束 + ) employment_salary = Column(Integer, nullable=True) #薪资 employment_open_time = Column(DATE, nullable=True) #就业开放时间 @@ -49,10 +51,7 @@ class Company(Base_all): #公司 employment_company = Column(String(50) #公司姓名 , nullable=False #非空约束 ) - address_id = Column(Integer #地址id,匹配地址表 - , ForeignKey('Address.id') #外键地址表id - , nullable=False #非空约束 - ) + create_time = Column(DATETIME , default=datetime.now ) @@ -71,6 +70,7 @@ class Address(Base_all): somewhere=Column(String(50) #地址区域 , nullable=False ) + create_time = Column(DATETIME , default=datetime.now ) diff --git a/stu_jiuye/request.py b/stu_jiuye/request.py index 4e3833f..288acd5 100644 --- a/stu_jiuye/request.py +++ b/stu_jiuye/request.py @@ -4,10 +4,10 @@ from pydantic import BaseModel class PostRequest(BaseModel): #学生就业信息请求体模型 # compname: str|None=None - sname: str|None=None + stuid: int|None=None class_id: int|None=None company_id:int|None=None - # address_id: int|None=None + address_id: int|None=None employment_salary: int|None=None employment_open_time:date|None=None offer_recived_time:date|None=None @@ -21,7 +21,7 @@ class EmpResponse(BaseModel): #学生就 class CompRequest(BaseModel): #公司信息请求体模型 employment_company:str - address_id: int + # address_id: int class CompResponse(BaseModel): #公司信息响应体 code: int = 200 From b5883e450d3819423b9c31e27d71d4bb3c7fb80d Mon Sep 17 00:00:00 2001 From: yb <739325183@qq.com> Date: Tue, 22 Sep 2026 19:44:35 +0800 Subject: [PATCH 12/19] =?UTF-8?q?=E6=9B=B4=E6=96=B0debug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- stu_jiuye/CURD_api.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/stu_jiuye/CURD_api.py b/stu_jiuye/CURD_api.py index 3d90172..c08b0fd 100644 --- a/stu_jiuye/CURD_api.py +++ b/stu_jiuye/CURD_api.py @@ -15,10 +15,10 @@ def get_stuinfo( #查询学生就业信息 ,min_salary:int|None=Query(None,description='最小薪资范围') ,max_salary:int|None=Query(None,description='最大薪资范围') ,somewhere:str|None=Query(None,description='公司地区') - ,employment_open_start: date | None = Query(None,description='就业开放起始时间') - ,employment_open_end: date | None = Query(None,description='就业开放结束时间') - ,offer_recived_start: date | None = Query(None,description='offer下发起始时间') - ,offer_recived_end: date | None = Query(None,description='offer下发结束时间') + ,employment_open_start: date|None = Query(None,description='就业开放起始时间') + ,employment_open_end: date|None = Query(None,description='就业开放结束时间') + ,offer_recived_start: date|None = Query(None,description='offer下发起始时间') + ,offer_recived_end: date|None = Query(None,description='offer下发结束时间') ,db=Depends(get_db) ): #查询条件 r=get_emp_dao( #调用函数 From 5fddb78c271415eeacd3e508d353ee13afd4798e Mon Sep 17 00:00:00 2001 From: yb <739325183@qq.com> Date: Tue, 22 Sep 2026 21:23:40 +0800 Subject: [PATCH 13/19] =?UTF-8?q?=E6=9B=B4=E6=96=B0db.refresh?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- stu_jiuye/dao.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/stu_jiuye/dao.py b/stu_jiuye/dao.py index 7d0a32b..96ac30e 100644 --- a/stu_jiuye/dao.py +++ b/stu_jiuye/dao.py @@ -18,6 +18,7 @@ def add_employment_dao(o,db): #新增就业信息函数 return False else: db.commit() #提交事务,永久保存 + db.refresh(o1) return True def add_company_dao(o,db): #添加公司信息函数 @@ -34,6 +35,7 @@ def add_company_dao(o,db): #添加公司信息函数 return False else: db.commit() #提交事务,永久保存 + db.refresh(o1) return True def add_address_dao(o,db): #添加地址区域信息函数 try: @@ -49,6 +51,7 @@ def add_address_dao(o,db): #添加地址区域信息函数 return False else: db.commit() #提交事务,永久保存 + db.refresh(o1) return True From fa571a13dab9abe6c9e6a073e438a99146738e08 Mon Sep 17 00:00:00 2001 From: Orangeeee Date: Tue, 22 Sep 2026 21:42:44 +0800 Subject: [PATCH 14/19] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BA=86students=5Fdao?= =?UTF-8?q?=E9=87=8Cadd=5Fstudent=5Fdao=E7=9A=84=E6=8A=A5=E9=94=99?= =?UTF-8?q?=E9=80=BB=E8=BE=91=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.py | 12 ++++++------ students/api/students_api.py | 6 +++--- students/dao/students_dao.py | 12 +++++++++--- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/main.py b/main.py index bbc63d7..1994f12 100644 --- a/main.py +++ b/main.py @@ -9,12 +9,12 @@ from databases import * app = FastAPI(title="学生管理系统") -app.include_router(Classes_API,tags=["classes"]) -app.include_router(Scores_API,tags=["scores"]) -app.include_router(Shtudent_Jiuye,tags=["Employments"]) -app.include_router(Students_API,tags=["students"]) -app.include_router(Teachers_API,tags=["teachers"]) -app.include_router(StatCalc_API,tags=["StatCalc"]) +app.include_router(Classes_API,tags=["班级管理模块"]) +app.include_router(Scores_API,tags=["学生考核成绩管理模块"]) +app.include_router(Shtudent_Jiuye,tags=["学生就业管理模块"]) +app.include_router(Students_API,tags=["学生管理模块"]) +app.include_router(Teachers_API,tags=["老师管理模块"]) +app.include_router(StatCalc_API,tags=["统计分析模块"]) if __name__ == "__main__": diff --git a/students/api/students_api.py b/students/api/students_api.py index d7c4186..9dec3db 100644 --- a/students/api/students_api.py +++ b/students/api/students_api.py @@ -27,15 +27,15 @@ def get_students( stu:StudentsQuery = Depends() @s_api.post("/students" ,summary='新增学生资料' ,description=f'学生ID自动分配,学生姓名、学生手机号和班级是必填项,不能为空。\n ' - f'时间格式:YYYY-MM-DD' + f'注意事项:\n' + f'时间格式:YYYY-MM-DD\n' + f'班级ID和顾问ID必须已经存在才可以绑定' ,response_model=StudentsResponse ) def add_student( stu:StudentsResponse = Depends() , db=Depends(get_db) ): s_dict = stu.model_dump(exclude_unset=True) result = add_student_dao( s=s_dict , db=db ) - if not result: - raise HTTPException(status_code=500, detail='手机号已有学生使用或必填项为空。') return result @s_api.put("/students" diff --git a/students/dao/students_dao.py b/students/dao/students_dao.py index 4d1ac7e..7b80c76 100644 --- a/students/dao/students_dao.py +++ b/students/dao/students_dao.py @@ -62,9 +62,11 @@ def add_student_dao( s , db): phone = s.get("phone") s1_deleted = db.query( Students ).filter( Students.phone == phone ).first() if s1_deleted and s1_deleted.is_deleted == False: - return False + raise ValueError("该手机号已存在有效学生记录,请勿重复添加") if not phone: - return False + raise ValueError("手机号不能为空") + if not s.get("class_id") or not s.get("advisor_id"): + raise ValueError("班级ID和顾问ID必须已经存在才可以绑定") if s1_deleted and s1_deleted.is_deleted == True: s1_deleted.name = s.get("name") s1_deleted.age = s.get("age") @@ -90,10 +92,14 @@ def add_student_dao( s , db): return s1_deleted s1 = Students( **s ) db.add(s1) + except ValueError as e: + # 业务校验异常:回滚并返回错误信息 + db.rollback() + return {"code": 400, "msg": str(e)} except Exception: # 这里可以加日志 db.rollback() - return False + return {"code": 500, "msg": f"系统异常: {str(e)}"} else: db.commit() db.refresh(s1) From 699867b0af75c0fe365643e09bdb367997fbb058 Mon Sep 17 00:00:00 2001 From: Orangeeee Date: Tue, 22 Sep 2026 21:57:56 +0800 Subject: [PATCH 15/19] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BA=86students=5Fdao?= =?UTF-8?q?=E9=87=8Cadd=5Fstudent=5Fdao=E7=9A=84=E6=8A=A5=E9=94=99?= =?UTF-8?q?=E9=80=BB=E8=BE=91=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- students/api/students_api.py | 2 +- students/dao/students_dao.py | 16 +++++++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/students/api/students_api.py b/students/api/students_api.py index 9dec3db..5072dcc 100644 --- a/students/api/students_api.py +++ b/students/api/students_api.py @@ -30,7 +30,7 @@ def get_students( stu:StudentsQuery = Depends() f'注意事项:\n' f'时间格式:YYYY-MM-DD\n' f'班级ID和顾问ID必须已经存在才可以绑定' - ,response_model=StudentsResponse ) + ) def add_student( stu:StudentsResponse = Depends() , db=Depends(get_db) ): diff --git a/students/dao/students_dao.py b/students/dao/students_dao.py index 7b80c76..79888e6 100644 --- a/students/dao/students_dao.py +++ b/students/dao/students_dao.py @@ -66,7 +66,13 @@ def add_student_dao( s , db): if not phone: raise ValueError("手机号不能为空") if not s.get("class_id") or not s.get("advisor_id"): - raise ValueError("班级ID和顾问ID必须已经存在才可以绑定") + raise ValueError("班级ID和顾问ID不能为空") + s1_class_id = db.query(Students).filter(Students.phone == phone).first() + s1_advisor_id = db.query(Students).filter(Students.phone == phone).first() + if not s1_class_id: + raise ValueError(f"班级ID {s.get("class_id")} 不存在,请先创建班级") + if not s1_advisor_id: + raise ValueError(f"顾问ID {s.get("advisor_id")} 不存在,请先创建顾问") if s1_deleted and s1_deleted.is_deleted == True: s1_deleted.name = s.get("name") s1_deleted.age = s.get("age") @@ -92,16 +98,16 @@ def add_student_dao( s , db): return s1_deleted s1 = Students( **s ) db.add(s1) + db.commit() except ValueError as e: # 业务校验异常:回滚并返回错误信息 db.rollback() return {"code": 400, "msg": str(e)} - except Exception: + except Exception as e: # 这里可以加日志 db.rollback() return {"code": 500, "msg": f"系统异常: {str(e)}"} else: - db.commit() db.refresh(s1) return s1 @@ -147,14 +153,14 @@ def update_student_dao( s , db): # 额外字段 if s.get("phone") is not None: s1_id.student_phone = s.get("phone") + s1_id.update_date = datetime.now() + db.commit() except HTTPException: raise except Exception: db.rollback() raise else: - s1_id.update_date = datetime.now() - db.commit() db.refresh(s1_id) # 从数据库再拉一次数据 return s1_id From 566747b320ed120b3c9c2267c3b0397e00b1498e Mon Sep 17 00:00:00 2001 From: Orangeeee Date: Tue, 22 Sep 2026 22:56:19 +0800 Subject: [PATCH 16/19] =?UTF-8?q?=E6=9B=B4=E6=96=B0Student=E7=9A=84README?= =?UTF-8?q?=5Fstudents.md=E6=A8=A1=E5=9D=97=E8=A7=A3=E9=87=8A=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- students/README_students.md | 175 ++++++++++++++++++++++++++++--- students/model/students_model.py | 4 +- 2 files changed, 163 insertions(+), 16 deletions(-) diff --git a/students/README_students.md b/students/README_students.md index 8f6ed3c..eccfd85 100644 --- a/students/README_students.md +++ b/students/README_students.md @@ -16,48 +16,195 @@ ORM:sqlalchemy ## main:学生管理系统的主程序文件、测试接口 1. 下面所有配置文件的接口全部导入并建表 -2. 创建fastapi接口并本地运行 +2. 创建合并接口APIRouter +3. 创建fastapi接口并本地运行 ## databases:链接数据库配置文件 1. 链接本地mysql,实例化mysql,创建引擎,创建基类,实例化数据库会话 2. 创建函数,调用数据库会话 +3. 因为后期多代码合并,每个人的databases都不同链接也不同,所以导入了.env文件 + 1. 这样在每个人有差异的数据可以直接保存在本地,不用反复同步相互覆盖了 + 2. 另外一个原因就是model层大家建表要使用同一个基类 + 1. 所以接入了.env文件随时入参 + 2. 这样更加方便,而且高频同步和拉取也不用重新配置 + +## 分层代码书写顺序: +1. model层: + 1. 确认你的业务需要哪些字段 + 2. 确认小组的字段名、表名、库名一致 + 3. 确认主键、唯一键、字段数据类型、外键等关键字内容 +2. 请求体 + 1. 搞清楚业务需求,需要用到哪些字段 + 2. 增删改查的具体逻辑 +3. api + 1. 写好接收变量 + 2. 装饰器设定 + 3. 输出规则 + 4. 一次写好基本上就不会再改了 +4. dao + 1. 工作量最大的层,所有的业务逻辑都写在这里面 + 2. 所有的业务逻辑都在这个层里 ## api.students_api:接口文件 ### 学生表students的功能接口: 1. 学生信息的查询 + 1. 仅保存入参标量,代码都在逻辑层,建好了基本不用修改,方便维护 2. 学生信息的新增 + 1. 仅保存入参标量,代码都在逻辑层,建好了基本不用修改,方便维护 3. 学生信息的更新 + 1. 仅保存入参标量,代码都在逻辑层,建好了基本不用修改,方便维护 4. 学生信息的逻辑删除 + 1. 仅保存入参标量,代码都在逻辑层,建好了基本不用修改,方便维护 ## dao.students_dao:数据筛选文件 ### 数据库的逻辑筛选文件: 1. 查询:get_student_dao + 1. 筛选所有非空内容,过滤逻辑删除数据,输出学生完整字段 2. 新增:add_student_dao + 1. 关键字段限制 + 2. 过滤各种报错,反馈报错问题 + 3. 无报错即可全部插入 + 4. 注意逻辑删除的数据,其实也会占用唯一键,所以有唯一键重复时,直接拉出旧数据进行清空翻新。 3. 更新:update_student_dao + 1. 主要过滤掉没有输入的字段,除非输入才可以被覆盖,不能每次更新清空全部内容 + 2. 唯一字段过滤,比如电话号码,在业务逻辑上电话号码不能重复 4. 逻辑删除:delete_student_dao + 1. 逻辑删除可以用所有字段进行精确或者范围删除 + 2. 但是不可以全为空删除我的整个库 ## model.students_model:数据库建表文件 1. 数据表建表代码 -2. 字段信息: sid **PK** - , student_name - , student_phone - , class_name - , job_open_time - , offer_issue_time - , company_name - , salary - , create_date - , update_date - , is_deleted - , deleted_date - , **待建FK:** class_id/teacher_id/score_id/company_id/ +2. 字段信息: `id`:***PK*** + `num`:***UNI*** + `name` + `age` + `sex`:*ENUM* + `home_Place` + `college` + `specialty` + `enrollment_time` + `graduate_time` + `education`:*ENUM* + ***外键字段*** + `class_id`:***FK*** + `advisor_id`:***FK*** + ***额外字段*** + `phone`:***UNI*** + ***通用字段*** + `create_date` + `update_date` + `is_deleted` + `deleted_date` ## schema.students_request:请求体、数据过滤 请求体根据业务要求有不同调整,方便后续维护和更改需求 1. 查询:StudentsQuery + 1. 所有字段都可以进行查询 + 2. 随便填哪个都可以进行精确查询或者范围查询 + 3. 全为空即查询全部 2. 新增:StudentsResponse + 1. 新增有必填项、不可重复项等,保证数据干净 3. 更新:StudentsUpdate + 1. 以ID作为查询字段,更新其他内容 + 2. 会过滤掉重复值 4. 逻辑删除:StudentsDelete + 1. 所有字段都可以进行删除 + 2. 随便填哪个都可以进行精确删除或者范围删除 + 3. 不可全字段为空 + +## StatCalc:统计分析模块 +除了没有model以外没有什么太大的区别 +## 学生管理系统修改报错记录 +### 1. 合并修改记录: +1. main.py + 1. 所有子模块中的main新增了APIRouter,用来拉到主main进行运行 + 2. stu_jiuye + 1. stu_jiuye\main.py + 1. 新增为加粗倾斜处 + 2. from ***sut_jiuye***.文件名 import 调用名 + 2. CURD_api.py + 1. 新增为加粗倾斜处 + 2. from ***sut_jiuye***.文件名 import 调用名 +2. databases.py + 1. 所有人的db_url账号密码IP端口和名称全部存入了.env文件 + 2. 导入了load_dotenv进行调用 + 1. from dotenv import load_dotenv + 2. load_dotenv( ) + 3. DB_USER = os.getenv("DB_USER", "root") + 4. DB_PASSWORD = os.getenv("DB_PASSWORD", "") + 5. DB_HOST = os.getenv("DB_HOST", "localhost") + 6. DB_PORT = os.getenv("DB_PORT", "3306") + 7. DB_NAME = os.getenv("DB_NAME", "student_manage_system") + 3. 修改了部分url名称,自行检查 +3. class文件夹下导入修改 + 1. 新增为加粗倾斜处 + 1. from ***class_management***.文件名 import 调用名 + 1. 改动文件: + 1. class_management_api.py + 2. class_management_dao.py + 3. class_management_model.py + +### 2. 合并完成 +1. 新增.env文件,设置好账号密码等 + 1. 可以一次运行创建好所有表格 + 2. 但是注意,没办法创建库,也就是student_manage_system + 3. 如果没有建库的话会报错 +2. 表外键写完之后,可以用SQL语句删除所有表 + 1. 再重新运行***main.py***文件 + 1. 这个main.py特指最外层的运行主程序main.py + +### 3. 分支测试 +1. 阶段完成后 + 1. 如果不擅长保存版本,可以在自己的分支下面再建新分支 + 2. 方便切换版本和查询bug,理解逻辑,以免修改后bug更多了 + 3. 完成后可以将子分支变基到主线 + 4. 变基(覆盖)完成后可以继续使用子分支进行修改整合 +2. 注意云端仓库,没有修改的文件是不会反复上传的 + 1. 所以看距离时间最近的基本都是被修改过的 + 2. 可以用来进行版本对比 + +### 4. 外键创建 +1. 外键必须要来自同一个基类,不然会报错 + 1. 新增主程序的databases.py文件,统一基类 + +### 5. 外键报错 +1. 在新建字段时,依赖主表的外键必须要已经建立,不然在提交时都会报错 +2. 所以新增接口的报错逻辑需要特别优化,将各个阶段可能报错的内容都捕获下来 + + +## hermes agent协作内容: +### 1. 测试数据脚本 — init_test_data.py +向数据库插入了完整的测试数据,没有修改任何原有项目文件: +数据类型 +数量 +科目 6 门(Python程序设计、数据结构、数据库原理等) +教师 6 位(张伟、李芳、王强、陈静、刘洋、赵敏) +班级 3 个(CS2401、CS2402、AI2501) +学生 20 名(涵盖3个班级,男女各半) +成绩 120 条(每名学生6门课,含部分不及格记录) +公司 5 家(字节跳动、阿里巴巴、腾讯、华为、百度) +就业信息 8 条(含薪资、offer时间等) + +### 2. 前端页面 — frontend/index.html +单文件完整前端,包含: + +首页:问候 Banner + 快捷卡片(查课表/查成绩/校园卡/报修)+ 校园动态信息流 +学生管理:表格列表、搜索过滤、新增/编辑/删除(含二次确认弹窗) +成绩查询:学期切换 Tab、成绩卡片展示、Chart.js 柱状图 +教师管理:教师列表、搜索、新增 +就业管理:就业信息列表、状态标签(已就业/待就业) +个人中心:蓝色背景头像区 + 功能菜单列表 + +交互特性: +✅ 卡片点击缩放反馈(95% 回弹,150ms) +✅ 页面切换从右侧滑入(300ms) +✅ 删除二次确认弹窗 +✅ Toast 提示(成功/失败/信息) +✅ 鼠标悬停按钮/卡片颜色加深、阴影加深 +✅ 隔行变色表格 + 表头排序 + +启动后端后直接浏览器打开 frontend/index.html 即可使用。 + diff --git a/students/model/students_model.py b/students/model/students_model.py index f5c5e52..7b6abcd 100644 --- a/students/model/students_model.py +++ b/students/model/students_model.py @@ -30,7 +30,7 @@ class Students(Base_all): , comment='年龄' , nullable=False) - sex = Column(Enum(SexEnum, values_callable=lambda e: [i.value for i in e]) + sex = Column(Enum(SexEnum) , comment='性别' , nullable=False) @@ -49,7 +49,7 @@ class Students(Base_all): graduate_time = Column(DATETIME , comment='毕业时间') - education = Column(Enum(EducationEnum, values_callable=lambda e: [i.value for i in e]) + education = Column(Enum(EducationEnum) , comment='学历' , nullable=True) From 2dca7c7f768d135bf32bd1cd64fbfa3c440126cd Mon Sep 17 00:00:00 2001 From: yb <739325183@qq.com> Date: Tue, 22 Sep 2026 22:40:48 +0800 Subject: [PATCH 17/19] =?UTF-8?q?=E6=9B=B4=E6=96=B0debug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- stu_jiuye/CURD_api.py | 2 +- stu_jiuye/dao.py | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/stu_jiuye/CURD_api.py b/stu_jiuye/CURD_api.py index c08b0fd..f47efae 100644 --- a/stu_jiuye/CURD_api.py +++ b/stu_jiuye/CURD_api.py @@ -93,7 +93,7 @@ def delete_stuinfo( #删除模块 ): #根据id选择对象 rows = delete_emp_dao(id, db) #调用删除函数 if not rows: - raise HTTPException(status_code=500, detail='没有删除!') #失败返回错误信息 + raise HTTPException(status_code=404, detail='未找到该就业记录!') #失败返回错误信息 return {'code': 200, 'totals': rows, 'detail': '删除成功'} #成功返回信息 ''' diff --git a/stu_jiuye/dao.py b/stu_jiuye/dao.py index 96ac30e..fa60fa6 100644 --- a/stu_jiuye/dao.py +++ b/stu_jiuye/dao.py @@ -85,19 +85,19 @@ def get_emp_dao( #获取学生 # ,page # ,page_size ): #根据选择条件获取信息 - q = db.query(Employments,Company.employment_company,Address.somewhere) \ - .outerjoin(Students, Students.id == Employments.stuid) \ - .outerjoin(ClassInfo, ClassInfo.id == Employments.class_id)\ - .outerjoin(Company,Employments.company_id==Company.id)\ - .outerjoin(Address,Employments.address_id==Address.id)\ - .filter(Employments.is_deleted == 0) #连接公司表和地址表,筛选未被删除信息 + q = (db.query(Employments,Company.employment_company,Address.somewhere) + .outerjoin(Students, Students.id == Employments.stuid) + .outerjoin(ClassInfo, ClassInfo.id == Employments.class_id) + .outerjoin(Company,Employments.company_id==Company.id) + .outerjoin(Address,Employments.address_id==Address.id) + .filter(Employments.is_deleted == 0)) #连接公司表和地址表,筛选未被删除信息 # if stuid: # q = q.filter( Employments.id == stuid ) if sname: #根据学生姓名筛选 q = q.filter( Students.name == sname ) if class_id: - q = q.filter(ClassInfo.id == class_id) + q = q.filter(Employments.class_id == class_id) if somewhere: q = q.filter(Address.somewhere.like(f'%{somewhere}%')) if employment_company: #根据公司姓名筛选 @@ -119,7 +119,7 @@ def get_emp_dao( #获取学生 if r: return [ {"id": i.id, '学生姓名':sname, - '学生班级编号':class_id, + '学生班级编号':i.class_id, "公司": employment_company or '未就业', "公司区域":somewhere or '-', "薪资":i.employment_salary or '-', @@ -128,8 +128,8 @@ def get_emp_dao( #获取学生 # , "创建时间": i.create_time, # "更新时间": i.update_time, # "是否删除":i.is_deleted - } for i,sname,class_id,employment_company,somewhere in r ] #返回信息列表 - + } for i,sname,employment_company,somewhere in r ] #返回信息列表 + return {"code": 200, "totals": len(r), "data": r} def delete_emp_dao(id,db): #删除函数 try: From 079a7cf351281415fc7ab0728ed935a42fc60c4f Mon Sep 17 00:00:00 2001 From: chen <2966418553@qq.com> Date: Tue, 22 Sep 2026 22:07:46 +0800 Subject: [PATCH 18/19] =?UTF-8?q?=E6=A8=A1=E5=9D=97=E8=A7=A3=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scores/README_scores.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 scores/README_scores.md diff --git a/scores/README_scores.md b/scores/README_scores.md new file mode 100644 index 0000000..4c31e95 --- /dev/null +++ b/scores/README_scores.md @@ -0,0 +1,33 @@ +#scores模块解释 + +##项目层 +web框架:FastAPI(生成接口) +ORM:sqlalchemy +校验:MYSQL(通过PyMysql驱动) +运行:uvicorn,端口12346 + +用FastAPI显露HTTP接口 ,对MysQL的scores表进行一个增,删,改,查的动作,删除是软删除, +api是接口层,成绩信息的增加,删除,更新,查询 +dao是数据操作层,查询get_scores_dao + 更新add_scores_dao + 增加update_scores_dao + 删除delete_scores_dao +统计查询80分以上的get_top_students_dao + 查询连续两次不及格的get_failing_students_dao + 班级平均分get_class_avg_dao +model是数据库表模型层,字段信息 id *pk* + sid 链接学生表的学生ID + cid 链接班级表的班级ID + num 考试序次 + score 考试成绩 + t_subject 链接科目表的科目ID + create_date 创建数据的时间 + update_date 更新数据的是时间 + is_deleted 逻辑删除 + deleted_date 删除的时间 +schema是请求体和响应体模型层, 查询的ScoreQuery + 更新,增加,删除的ScoreRequest +databases是数据库定义配置文件, 链接引擎对象db_url,链接地址engine, + 建表的基类Base,数据库会话管理Session + 会话实例def get_db() +main是主程序文件,将配置文件的接口导入,创建接口运行 \ No newline at end of file From b67e3cd547213566ba3de8f6a2f75ba5ed0b0fc6 Mon Sep 17 00:00:00 2001 From: geyuan <2732801331@qq.com> Date: Wed, 23 Sep 2026 00:50:59 +0800 Subject: [PATCH 19/19] =?UTF-8?q?=E4=BF=AE=E6=9B=B4=E6=96=B0=E7=9A=84bud?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Teachers/api/tea_api.py | 18 +++++++++++------- Teachers/dao/tea_dao.py | 21 ++++++++++++++------- Teachers/main.py | 2 +- 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/Teachers/api/tea_api.py b/Teachers/api/tea_api.py index 26715bb..7d86fc8 100644 --- a/Teachers/api/tea_api.py +++ b/Teachers/api/tea_api.py @@ -28,13 +28,17 @@ def delete_tea(id:int|None,db=Depends(get_db)): raise HTTPException(status_code=500,detail='删除失败!') return {'detail':'删除成功!'} -@tea_api.put('/tea/{id}',summary='更新老师信息',description='输入更改的信息,可以为空') -def update_tea(id:int,tea:NewTeaRequest,db=Depends(get_db)): - t = tea.model_dump(exclude_unset= True) - r = update_tea_dao(id=id,t=t,db=db) - if not r: - raise HTTPException(status_code=404,detail='老师不存在') - return {'detail':'更新成功'} +@tea_api.put('/tea/{id}', summary='更新老师信息', description='输入更改的信息,可以为空') +def update_tea(id: int, tea: NewTeaRequest = Depends(), db=Depends(get_db)): + t = tea.model_dump(exclude_unset=True) + r = update_tea_dao(id=id, t=t, db=db) + if r == 'NOT_FOUND': + raise HTTPException(status_code=404, detail='老师不存在') + if r == 'NO_CHANGE': + raise HTTPException(status_code=400, detail='没有要更新的内容') + if isinstance(r, str) and r.startswith('ERROR'): + raise HTTPException(status_code=400, detail=r) + return {'detail': '更新成功'} #根据任意信息删除 @tea_api.delete('/tea',summary='根据任意信息逻辑删除',description='输入任意信息删除') diff --git a/Teachers/dao/tea_dao.py b/Teachers/dao/tea_dao.py index 1820930..655bc9d 100644 --- a/Teachers/dao/tea_dao.py +++ b/Teachers/dao/tea_dao.py @@ -29,15 +29,22 @@ def add_tea_dao(t,db): #更新 -def update_tea_dao(id,t, db): +def update_tea_dao(id, t, db): try: - row = db.query(Tea).filter(Tea.id == id,Tea.is_delete ==False ).update(t) - except: - db.rollback() - return False - else: + if not t: + return 'NO_CHANGE' + obj = db.query(Tea).filter(Tea.id == id, Tea.is_delete == False).first() + if not obj: + return 'NOT_FOUND' + for k, v in t.items(): + if hasattr(obj, k): + setattr(obj, k, v) db.commit() - return row + return 'OK' + except Exception as e: + db.rollback() + print('更新失败原因', repr(e)) + return f'ERROR: {e}' #查询 def get_tea_dao(t,db): diff --git a/Teachers/main.py b/Teachers/main.py index bd87a8d..cb1251b 100644 --- a/Teachers/main.py +++ b/Teachers/main.py @@ -15,7 +15,7 @@ if __name__ == "__main__": Base.metadata.create_all(engine1) import uvicorn - uvicorn.run('main:app', host='0.0.0.0', port=57000) + uvicorn.run('main:app', host='0.0.0.0', port=56000) """ IPv4 地址 . . . . . . . . . . . . : 192.168.1.51 子网掩码 . . . . . . . . . . . . : 255.255.255.0