Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
236f2665a6 | ||
|
|
e80d463bbc | ||
|
|
a90c240b5a | ||
|
|
d70705e7fe | ||
|
|
ee468216cb |
+15
-14
@@ -3,6 +3,7 @@ from core.database import get_db
|
|||||||
from models.employment import Employment
|
from models.employment import Employment
|
||||||
from models.student import Student
|
from models.student import Student
|
||||||
from models.score import Score
|
from models.score import Score
|
||||||
|
from schemas.statistics import *
|
||||||
from dao.statistics import *
|
from dao.statistics import *
|
||||||
from schemas.common import SuccessResponse
|
from schemas.common import SuccessResponse
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
@@ -11,34 +12,34 @@ from sqlalchemy.orm import Session
|
|||||||
statistics_router=APIRouter(tags=['统计接口'])
|
statistics_router=APIRouter(tags=['统计接口'])
|
||||||
|
|
||||||
|
|
||||||
@statistics_router.get("/students/age-over-30",response_model=SuccessResponse)
|
@statistics_router.post("/students/age-over-30",response_model=SuccessResponse)
|
||||||
def api_age_over_thirty(db:Session=Depends(get_db)):
|
def api_age_over_thirty(input_age:GenderCount,db:Session=Depends(get_db)):
|
||||||
try:
|
try:
|
||||||
age_over_thirty_list=age_over_thirty(Student,db)
|
age_over_thirty_list=age_over_thirty(Student,input_age.input_class,db)
|
||||||
return SuccessResponse(status_code=200,msg=age_over_thirty_list)
|
return SuccessResponse(status_code=200,msg=age_over_thirty_list)
|
||||||
except NoExist as e:
|
except NoExist as e:
|
||||||
raise HTTPException(status_code=404,detail=str(e))
|
raise HTTPException(status_code=404,detail=str(e))
|
||||||
# 这边功能函数返回的是一个字典
|
# 这边功能函数返回的是一个字典
|
||||||
@statistics_router.get("/classes/gender-count",response_model=SuccessResponse)
|
@statistics_router.get("/classes/gender-count",response_model=SuccessResponse)
|
||||||
def api_gender_count(db:Session=Depends(get_db)):
|
def api_gender_count(input_class:int|None= None,db:Session=Depends(get_db)):
|
||||||
try:
|
try:
|
||||||
result = gender_count(Student,db)
|
result = gender_count(Student,db,input_class)
|
||||||
return SuccessResponse(status_code=200,msg=result)
|
return SuccessResponse(status_code=200,msg=result)
|
||||||
except NoExist as e:
|
except NoExist as e:
|
||||||
raise HTTPException(status_code=404,detail=str(e))
|
raise HTTPException(status_code=404,detail=str(e))
|
||||||
|
|
||||||
@statistics_router.get("/scores/all-above-80",response_model=SuccessResponse)
|
@statistics_router.post("/scores/all-above-80",response_model=SuccessResponse)
|
||||||
def all_above_eighty(db:Session=Depends(get_db)):
|
def all_above_eighty(page:int,score:StudentScore,db:Session=Depends(get_db)):
|
||||||
try:
|
try:
|
||||||
result = score_over_eighty(Score,Student,db)
|
result = score_over_eighty(score.score,page,Score,Student,db)
|
||||||
return SuccessResponse(status_code=200,msg=result)
|
return SuccessResponse(status_code=200,msg=result)
|
||||||
except NoExist as e:
|
except NoExist as e:
|
||||||
raise HTTPException(status_code=404,detail=str(e))
|
raise HTTPException(status_code=404,detail=str(e))
|
||||||
|
|
||||||
@statistics_router.get("/scores/fail-more-than-two",response_model=SuccessResponse)
|
@statistics_router.get("/scores/fail-more-than-two",response_model=SuccessResponse)
|
||||||
def fail_two(db:Session=Depends(get_db)):
|
def fail_two(num:int,offset_set:int,db:Session=Depends(get_db)):
|
||||||
try:
|
try:
|
||||||
result = twice_error(Score,Student,db)
|
result = twice_error(num,offset_set,Score,Student,db)
|
||||||
return SuccessResponse(status_code=200,msg=result)
|
return SuccessResponse(status_code=200,msg=result)
|
||||||
except NoExist as e:
|
except NoExist as e:
|
||||||
raise HTTPException(status_code=404,detail=str(e))
|
raise HTTPException(status_code=404,detail=str(e))
|
||||||
@@ -53,17 +54,17 @@ def class_average(db:Session=Depends(get_db)):
|
|||||||
|
|
||||||
|
|
||||||
@statistics_router.get("/employments/top5-salary",response_model=SuccessResponse)
|
@statistics_router.get("/employments/top5-salary",response_model=SuccessResponse)
|
||||||
def top_salary(db:Session=Depends(get_db)):
|
def top_salary(limit_set:int,db:Session=Depends(get_db)):
|
||||||
try:
|
try:
|
||||||
result=max_salary(Student,Employment,db)
|
result=max_salary(limit_set,Student,Employment,db)
|
||||||
return SuccessResponse(status_code=200,msg=result)
|
return SuccessResponse(status_code=200,msg=result)
|
||||||
except NoExist as e:
|
except NoExist as e:
|
||||||
raise HTTPException(status_code=404,detail=str(e))
|
raise HTTPException(status_code=404,detail=str(e))
|
||||||
|
|
||||||
@statistics_router.get("/employments/student-duration",response_model=SuccessResponse)
|
@statistics_router.get("/employments/student-duration",response_model=SuccessResponse)
|
||||||
def employ_time(db:Session=Depends(get_db)):
|
def employ_time(limit_set,db:Session=Depends(get_db)):
|
||||||
try:
|
try:
|
||||||
result = student_market(Employment,db)
|
result = student_market(limit_set,Employment,db)
|
||||||
return SuccessResponse(status_code=200,msg=result)
|
return SuccessResponse(status_code=200,msg=result)
|
||||||
except NoExist as e:
|
except NoExist as e:
|
||||||
raise HTTPException(status_code=404,detail=str(e))
|
raise HTTPException(status_code=404,detail=str(e))
|
||||||
|
|||||||
+22
-16
@@ -3,9 +3,8 @@ from sqlalchemy import func
|
|||||||
|
|
||||||
#`GET /statistics/students/age-over-30`
|
#`GET /statistics/students/age-over-30`
|
||||||
#查询所有超过 30 岁的学员信息
|
#查询所有超过 30 岁的学员信息
|
||||||
|
def age_over_thirty(Student,input_age,db):
|
||||||
def age_over_thirty(Student,db):
|
student_list=db.query(Student).filter(Student.age>input_age,Student.is_deleted==0).all()
|
||||||
student_list=db.query(Student).filter(Student.age>30,Student.is_deleted==0).all()
|
|
||||||
if not student_list :
|
if not student_list :
|
||||||
raise NoExist('无目标年龄大于30岁')
|
raise NoExist('无目标年龄大于30岁')
|
||||||
# 把每个学生对象需要返回的字段,明确放进普通字典。
|
# 把每个学生对象需要返回的字段,明确放进普通字典。
|
||||||
@@ -30,9 +29,13 @@ def age_over_thirty(Student,db):
|
|||||||
"is_deleted": student.is_deleted,
|
"is_deleted": student.is_deleted,
|
||||||
})
|
})
|
||||||
return result
|
return result
|
||||||
|
#统计男、女、总人数
|
||||||
def gender_count(Student,db):
|
def gender_count(Student,db,input_class=None):
|
||||||
result=db.query(Student.class_id,Student.gender,func.count(Student.id)).filter(Student.is_deleted==0).group_by(Student.class_id,Student.gender).all()
|
if input_class :
|
||||||
|
result = db.query(Student.class_id, Student.gender, func.count(Student.id)).filter(
|
||||||
|
Student.class_id == input_class, Student.is_deleted == 0).group_by(Student.class_id, Student.gender).all()
|
||||||
|
else:
|
||||||
|
result=db.query(Student.class_id,Student.gender,func.count(Student.id)).filter(Student.is_deleted==0).group_by(Student.class_id,Student.gender).all()
|
||||||
if not result :
|
if not result :
|
||||||
raise NoExist('班里招点人吧,要倒闭了')
|
raise NoExist('班里招点人吧,要倒闭了')
|
||||||
dict1 = {}
|
dict1 = {}
|
||||||
@@ -43,10 +46,11 @@ def gender_count(Student,db):
|
|||||||
dict1[i]['总人数']+=k
|
dict1[i]['总人数']+=k
|
||||||
return dict1
|
return dict1
|
||||||
#查询每次考试成绩都在 80 分以上的学生编号、姓名和成绩
|
#查询每次考试成绩都在 80 分以上的学生编号、姓名和成绩
|
||||||
def score_over_eighty(Score,Student,db):
|
#首先,拿到最低值>80的人的列表,row。然后,遍历元素拿到符合条件的id的属性。
|
||||||
|
def score_over_eighty(score,offset_set,Score,Student,db):
|
||||||
student_list=db.query(Student.id, Student.student_name)\
|
student_list=db.query(Student.id, Student.student_name)\
|
||||||
.join(Score,Score.student_id==Student.id).filter(Student.is_deleted==0,Score.is_deleted==0).group_by(Student.id,Student.student_name)\
|
.join(Score,Score.student_id==Student.id).filter(Student.is_deleted==0,Score.is_deleted==0).group_by(Student.id,Student.student_name)\
|
||||||
.having(func.min(Score.score)>80).all()
|
.having(func.min(Score.score)>score).all()
|
||||||
if not student_list :
|
if not student_list :
|
||||||
raise NoExist('全是学渣')
|
raise NoExist('全是学渣')
|
||||||
list1 = []
|
list1 = []
|
||||||
@@ -59,10 +63,11 @@ def score_over_eighty(Score,Student,db):
|
|||||||
"student_name": student_name,
|
"student_name": student_name,
|
||||||
"score": float(score) if score is not None else None,
|
"score": float(score) if score is not None else None,
|
||||||
})
|
})
|
||||||
return list1
|
list2=list1[5*(offset_set-1):5*offset_set]
|
||||||
|
return list2
|
||||||
#查询有两次以上不及格的学生姓名、班级和不及格成绩
|
#查询有两次以上不及格的学生姓名、班级和不及格成绩
|
||||||
def twice_error(Score,Student,db):
|
def twice_error(num,offset_set,Score,Student,db):
|
||||||
student_list=db.query(Score.student_id).filter(Score.score<60,Score.is_deleted==0).group_by(Score.student_id).having(func.count(Score.id)>2).all()
|
student_list=db.query(Score.student_id).filter(Score.score<60,Score.is_deleted==0).group_by(Score.student_id).having(func.count(Score.id)>num).all()
|
||||||
if not student_list :
|
if not student_list :
|
||||||
raise NoExist('全是学霸')
|
raise NoExist('全是学霸')
|
||||||
list1=[]
|
list1=[]
|
||||||
@@ -75,7 +80,8 @@ def twice_error(Score,Student,db):
|
|||||||
"class_id": class_id,
|
"class_id": class_id,
|
||||||
"score": float(score) if score is not None else None,
|
"score": float(score) if score is not None else None,
|
||||||
})
|
})
|
||||||
return list1
|
list2 = list1[5 * (offset_set - 1):5 * offset_set]
|
||||||
|
return list2
|
||||||
|
|
||||||
#统计每次考试每个班级的平均分,并按照平均分从高到低排序
|
#统计每次考试每个班级的平均分,并按照平均分从高到低排序
|
||||||
def avg_class(Score,Student,db):
|
def avg_class(Score,Student,db):
|
||||||
@@ -92,8 +98,8 @@ def avg_class(Score,Student,db):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
#统计就业薪资最高的前五名学生姓名、班级、就业时间、就业公司
|
#统计就业薪资最高的前五名学生姓名、班级、就业时间、就业公司
|
||||||
def max_salary(Student,Employment,db):
|
def max_salary(limit_set,Student,Employment,db):
|
||||||
student_list = db.query(Student.student_name,Student.class_id,Employment.offer_date,Employment.company_name).join(Employment, Student.id == Employment.student_id).filter(Student.is_deleted==0,Employment.is_deleted==0).order_by(Employment.salary.desc()).limit(5).all()
|
student_list = db.query(Student.student_name,Student.class_id,Employment.offer_date,Employment.company_name).join(Employment, Student.id == Employment.student_id).filter(Student.is_deleted==0,Employment.is_deleted==0).order_by(Employment.salary.desc()).limit(limit_set).all()
|
||||||
if not student_list :
|
if not student_list :
|
||||||
raise NoExist('没就业的啊兄弟?')
|
raise NoExist('没就业的啊兄弟?')
|
||||||
result = []
|
result = []
|
||||||
@@ -108,8 +114,8 @@ def max_salary(Student,Employment,db):
|
|||||||
|
|
||||||
# - 统计每个学生的就业时长
|
# - 统计每个学生的就业时长
|
||||||
# - 就业时长 = `offer_date - employment_open_date`
|
# - 就业时长 = `offer_date - employment_open_date`
|
||||||
def student_market(Employment,db):
|
def student_market(limit_set,Employment,db):
|
||||||
student_list = db.query(Employment.student_id,func.datediff(Employment.offer_date,Employment.employment_open_date)).filter(Employment.is_deleted==0).all()
|
student_list = db.query(Employment.student_id,func.datediff(Employment.offer_date,Employment.employment_open_date)).filter(Employment.is_deleted==0).limit(limit_set).all()
|
||||||
result = []
|
result = []
|
||||||
for student_id, duration_days in student_list:
|
for student_id, duration_days in student_list:
|
||||||
result.append({
|
result.append({
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
|
from fastapi.responses import RedirectResponse
|
||||||
|
from fastapi.staticfiles import StaticFiles
|
||||||
|
from pathlib import Path
|
||||||
from api.example import example_router
|
from api.example import example_router
|
||||||
from middleware import log_middleware
|
from middleware import log_middleware
|
||||||
from api.statistics import statistics_router
|
from api.statistics import statistics_router
|
||||||
@@ -8,6 +11,12 @@ from api.teacher import router as teacher_router,class_teacher_router
|
|||||||
from api.magic import magic_router
|
from api.magic import magic_router
|
||||||
|
|
||||||
app = FastAPI(title='学生管理系统')
|
app = FastAPI(title='学生管理系统')
|
||||||
|
app.mount("/ui", StaticFiles(directory=Path(__file__).resolve().parent / "frontend", html=True), name="frontend")
|
||||||
|
|
||||||
|
@app.get("/", include_in_schema=False)
|
||||||
|
def home():
|
||||||
|
return RedirectResponse("/ui/")
|
||||||
|
|
||||||
app.middleware("http")(log_middleware)
|
app.middleware("http")(log_middleware)
|
||||||
app.include_router(magic_router)
|
app.include_router(magic_router)
|
||||||
|
|
||||||
@@ -25,7 +34,6 @@ from api import consultant
|
|||||||
app.include_router(consultant.router)
|
app.include_router(consultant.router)
|
||||||
#-------------张昕浩---------------
|
#-------------张昕浩---------------
|
||||||
app.include_router(example_router)
|
app.include_router(example_router)
|
||||||
app.include_router(magic_router)
|
|
||||||
app.include_router(statistics_router, prefix="/statistics")
|
app.include_router(statistics_router, prefix="/statistics")
|
||||||
|
|
||||||
#-------------曾凯---------------
|
#-------------曾凯---------------
|
||||||
|
|||||||
+10
-1
@@ -1,4 +1,13 @@
|
|||||||
|
from pydantic import BaseModel,Field
|
||||||
|
|
||||||
class NoExist(Exception):
|
class NoExist(Exception):
|
||||||
def __init__(self,value):
|
def __init__(self,value):
|
||||||
self.value = value
|
self.value = value
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class GenderCount(BaseModel):
|
||||||
|
input_class:int|None = None
|
||||||
|
|
||||||
|
class StudentScore(BaseModel):
|
||||||
|
score:int = Field(default = 80, ge = 0, le = 100)
|
||||||
|
|||||||
Reference in New Issue
Block a user