From 5078d4d0c9d6d605e4798e9c53d82188f8187f65 Mon Sep 17 00:00:00 2001 From: jianqi Date: Sat, 12 Sep 2026 13:59:38 +0800 Subject: [PATCH 1/5] =?UTF-8?q?=E5=9F=BA=E7=A1=80=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E4=B8=80=E4=B8=8B=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- database.py | 2 +- main.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/database.py b/database.py index 5c789e5..79aaa9b 100644 --- a/database.py +++ b/database.py @@ -8,7 +8,7 @@ from sqlalchemy.orm import sessionmaker # 1. 配置 MySQL 数据库连接 URL # 格式:mysql+pymysql://用户名:密码@主机:端口/数据库名?编码 # 请将下面的 'root', '123456', 'localhost', '3306', 'test_db' 替换为你自己的实际信息 -SQLALCHEMY_DATABASE_URL = "mysql+pymysql://root:123456@localhost:3306/test_db" +SQLALCHEMY_DATABASE_URL = "mysql+pymysql://root:123456@localhost:3306/max_code_sms" # 2. 创建数据库引擎 # - pool_pre_ping=True 表示每次从连接池取出连接前先 ping 一下,防止使用已断开的连接 diff --git a/main.py b/main.py index 8a0fc97..ca611b0 100644 --- a/main.py +++ b/main.py @@ -41,7 +41,7 @@ async def root(): if __name__ == "__main__": import uvicorn uvicorn.run( - "main6:app", # 指定应用位置(模块名:应用变量名) + "main:app", # 指定应用位置(模块名:应用变量名) host="localhost", # 监听所有网络接口 port=8001, # 端口 reload=True # 开发模式,代码变动自动重启 From e7175958c75d360e93eaf4bed879bc38c7a64997 Mon Sep 17 00:00:00 2001 From: jianqi Date: Sat, 12 Sep 2026 14:32:31 +0800 Subject: [PATCH 2/5] =?UTF-8?q?=E4=BF=AE=E6=94=B9main=E6=96=87=E4=BB=B6=20?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E7=BB=9F=E8=AE=A1api=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E7=BB=9F=E8=AE=A1=E8=AF=B7=E6=B1=82=E6=A8=A1=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api1/statistics_api.py | 18 ++++++++++++++++++ main.py | 4 +++- scheme/statistics_scheme.py | 22 ++++++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 api1/statistics_api.py create mode 100644 scheme/statistics_scheme.py diff --git a/api1/statistics_api.py b/api1/statistics_api.py new file mode 100644 index 0000000..17573ab --- /dev/null +++ b/api1/statistics_api.py @@ -0,0 +1,18 @@ +# api/stats +# 本文件定义统计分析相关的所有 API 路由(Controller 层) +from itertools import count + +from fastapi import APIRouter, Depends, HTTPException, Query +from sqlalchemy.orm import Session +from typing import List + +from database import get_db +from dao.users_dao import UserDAO +from scheme.statistics_scheme import StatsResponse +from scheme.users import UserCreate, UserUpdate, UserResponse + +router = APIRouter() +# **多维度班级统计**:统计每个班级的总人数,以及按性别(男、女)细分的人数分布。 +@router.get("/class/stats/gender", response_model=List[StatsResponse]) +def get_class_stats(db: Session = Depends(get_db)): + sbg = db.query(StuInfo.cls_id, count(StuInfo.id)).group_by(StuInfo.cls_id, StuInfo.gender).all() \ No newline at end of file diff --git a/main.py b/main.py index ca611b0..25daeed 100644 --- a/main.py +++ b/main.py @@ -5,7 +5,7 @@ from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from database import engine, Base -from api1 import users # 导入 users 子路由 +from api1 import users, statistics_api # 导入 users 子路由 # 1. 创建数据库表(如果表不存在) # Base.metadata.create_all 会扫描所有继承 Base 的模型,生成对应的 CREATE TABLE 语句 @@ -32,6 +32,8 @@ app.add_middleware( # prefix 为路由前缀,所有用户接口都以 /api/users 开头 app.include_router(users.router, prefix="/api/users", tags=["用户管理"]) +app.include_router(statistics_api.router, prefix="/api/stats", tags=["统计分析"]) + # 5. 根路径 @app.get("/") async def root(): diff --git a/scheme/statistics_scheme.py b/scheme/statistics_scheme.py new file mode 100644 index 0000000..79d950b --- /dev/null +++ b/scheme/statistics_scheme.py @@ -0,0 +1,22 @@ +# scheme/statistics_scheme.py +from pydantic import BaseModel, Field, EmailStr +from datetime import datetime +from typing import Optional + +# ---------- 请求模型 ---------- +# class UserCreate(BaseModel): +# username: str = Field(..., min_length=3, max_length=50) +# email: EmailStr +# full_name: Optional[str] = Field(None, max_length=100) +# +# class UserUpdate(BaseModel): +# username: Optional[str] = Field(None, min_length=3, max_length=50) +# email: Optional[EmailStr] = None +# full_name: Optional[str] = Field(None, max_length=100) + +# ---------- 响应模型 ---------- +# 多维度班级统计 +class StatsResponse(BaseModel): + total_count: int + man_count: int + female_count: int \ No newline at end of file From 77ce48310aa6d75590f090588e070755d3d0b932 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=A9=E5=A4=A9?= <1423904024@qq.com> Date: Sat, 12 Sep 2026 14:42:26 +0800 Subject: [PATCH 3/5] =?UTF-8?q?=E5=88=9B=E5=BB=BAteacher=5Fmodel?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- model/teacher_model.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 model/teacher_model.py diff --git a/model/teacher_model.py b/model/teacher_model.py new file mode 100644 index 0000000..dbddb7b --- /dev/null +++ b/model/teacher_model.py @@ -0,0 +1,17 @@ +#教师建表语句 +from sqlalchemy import Column, String, Integer + +from database import Base + + +class Teacher(Base): + __tablename__ = "ted_info" # 表名 + + # 字段定义 + id = Column(Integer, primary_key=True, index=True) # 主键,索引 + name = Column(String(20),nullable=False) # 用户名,非空 + phone = Column(String(20),unique=True,nullable=False) # 电话,唯一,非空 + type = Column(String(20), nullable=False) # 教师职位,非空 + is_deleted = Column(Integer, default=0) # 逻辑删除(软删除),0是未删除,1是删除,默认为0 + + From bd1a9c2fdcad020bb51bd357b684ff702ab64ddd Mon Sep 17 00:00:00 2001 From: hzh <1400113776@qq.com> Date: Sat, 12 Sep 2026 14:46:58 +0800 Subject: [PATCH 4/5] =?UTF-8?q?=E6=96=B0=E5=A2=9Ecls=5Fmgmt=5Fmodel?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- model/cls_mgmt_model.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 model/cls_mgmt_model.py diff --git a/model/cls_mgmt_model.py b/model/cls_mgmt_model.py new file mode 100644 index 0000000..1456ed6 --- /dev/null +++ b/model/cls_mgmt_model.py @@ -0,0 +1,22 @@ +from sqlalchemy import Column, Integer, String, DateTime, Date +from sqlalchemy.sql import func +from database import Base + +class ClsMgmt(Base): + """ + 班级管理表模型 + 对应 MySQL 中的 cls_mgmt 表 + """ + __tablename__ = "cls_mgmt" # 表名 + + # 字段定义 + id = Column(String(15), primary_key=True, nullable=False) # 班级编号,主键,非空 + cls_start_date= Column(Date, nullable=False) #开课时间 + head_tea_id =Column(String(15),nullable=False) # 班主任id + lecturer_id=Column(String(15),nullable=False) # 主讲老师id + is_deleted=Column(Integer,nullable=False) + # created_at:创建时间,自动设置为当前时间(服务器时间) + # server_default=func.now() 表示由数据库生成默认值 + created_at = Column(DateTime(timezone=True), server_default=func.now()) + # updated_at:更新时间,当记录更新时自动设置为当前时间(由 SQLAlchemy 的 onupdate 触发) + updated_at = Column(DateTime(timezone=True), onupdate=func.now()) \ No newline at end of file From 3e4cdee9bed50757eb77a0c69ffbff5293bd6830 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B2=83=E6=9E=97=E9=A1=B9=E7=9B=AE1?= <3032475625@qq.com> Date: Sat, 12 Sep 2026 14:46:12 +0800 Subject: [PATCH 5/5] =?UTF-8?q?=E5=AD=A6=E7=94=9F=E6=88=90=E7=BB=A9?= =?UTF-8?q?=E6=A8=A1=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- model/stu_score_model.py | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 model/stu_score_model.py diff --git a/model/stu_score_model.py b/model/stu_score_model.py new file mode 100644 index 0000000..0713662 --- /dev/null +++ b/model/stu_score_model.py @@ -0,0 +1,34 @@ +# model/users_api.py +# 本文件定义 User 表的结构,映射到 MySQL 数据库 + +from sqlalchemy import Column, Integer, String, DateTime, Boolean, ForeignKey +from sqlalchemy.orm import relationship +from sqlalchemy.sql import func +from database import Base + +class Stu_score(Base): + """ + 用户表模型 + 对应 MySQL 中的 users 表 + """ + __tablename__ = "stu_score" # 表名 + + # 字段定义 + id = Column(Integer,primary_key=True, nullable=False,autoincrement=True) # + # stu_id = Column(String(10),ForeignKey(stu_info.id),nullable=False) #学生id,非空 + exam_attempt = Column(Integer, nullable=False) # 考试轮次,非空 + exam_score = Column(Integer, nullable=False,) # 成绩,非空,设置范围 + score_level=Column(String(10),nullable=False) #成绩评级 + is_deleted=Column(Boolean,default=False,nullable=False) #软删除: 0-正常 1-已删除 + name = relationship("Stu_info", back_populates="score") + + def __repr__(self): + return (f"") + # created_at:创建时间,自动设置为当前时间(服务器时间) + # server_default=func.now() 表示由数据库生成默认值 + created_at = Column(DateTime(timezone=True), server_default=func.now()) + + # updated_at:更新时间,当记录更新时自动设置为当前时间(由 SQLAlchemy 的 onupdate 触发) + updated_at = Column(DateTime(timezone=True), onupdate=func.now()) \ No newline at end of file