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] =?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