# 沃林学生管理系统 基于 **FastAPI + SQLAlchemy(同步)+ MySQL + Pydantic v2** 的学生管理系统,提供学生信息、考核成绩、就业管理、班级/老师管理与统计分析能力,内置 JWT 认证(RBAC 角色权限)与 Vue3 前端管理页面,附 Docker / Nginx 生产部署配置。 ## 目录结构 ``` walin_student_system/ ├── main.py # 项目入口:创建应用、注册路由、建表、挂载前端 ├── config.py # 全局配置(环境变量可覆盖) ├── database.py # 数据库连接 / 会话 / 依赖注入 ├── core/ │ ├── security.py # 密码哈希(PBKDF2) + JWT 签发/校验 │ └── deps.py # 认证依赖 + 角色级 RBAC ├── model/ # Model 层:SQLAlchemy 表模型 ├── scheme/ # Pydantic 请求/响应模型 ├── dao/ # 数据访问层(含统计动态查询、高级筛选器) ├── api/ # 路由层:auth/classes/teachers/students/scores/employment/statistics ├── static/ # Vue3 前端管理页面(index.html + app.js + style.css) ├── sql/init.sql # 修正版建表语句 + 种子数据(含初始账号) ├── Dockerfile # gunicorn + uvicorn worker 生产镜像 ├── docker-compose.yml # MySQL + API + Nginx 一键部署 └── nginx.conf # 反向代理配置 ``` ## 本地运行 1. 准备 MySQL,执行初始化脚本(建库建表 + 种子数据 + 初始账号): ```bash mysql -uroot -p < sql/init.sql ``` 2. 安装依赖并启动(Python 3.10): ```bash pip install -r requirements.txt python main.py # 或 uvicorn main:app --reload --port 8000 ``` 3. 访问: - 前端管理页面:(自动跳转到 /static/index.html) - Swagger 文档: 4. 默认账号(见 `sql/init.sql`): | 账号 | 密码 | 角色 | |---|---|---| | admin | admin123 | 管理员(全部权限) | | teacher1 | teacher123 | 教师(班级1,可管理本班学生) | | s2026010003 | student123 | 学生(只读本人信息) | 本地默认数据库连接为 `root:123456@localhost:3306/walin_db`,与 compose 不同;可用环境变量 `DATABASE_URL` 覆盖。 ## Docker 一键部署 ```bash docker compose up -d --build ``` - Nginx 监听 80 端口反向代理 API 容器; - MySQL 数据持久化在 `mysql_data` 卷,首次启动自动执行 `sql/init.sql`; - 访问 `http://服务器IP/`。 生产环境注意: - 修改 `docker-compose.yml` 中的 `MYSQL_ROOT_PASSWORD` 与 `SECRET_KEY`; - 建议在 Nginx 层配置 HTTPS(证书挂载后改 `listen 443 ssl`)。 ## 认证与权限(RBAC) - 登录:`POST /api/auth/login`,返回 JWT;后续请求携带 `Authorization: Bearer `。 - 角色权限: - **admin**:全部接口; - **teacher**:查询类接口 + 本班学生的成绩/就业/学生信息管理(资源归属校验:`teacher.class_id == student.class_id`); - **student**:只读本人信息与成绩。 ## 主要接口一览 | 模块 | 路径前缀 | 说明 | |---|---|---| | 认证 | /api/auth | login / register(仅admin) / me | | 班级 | /api/classes | add / total_query / single_query / update / delete | | 老师 | /api/teachers | teacher/add、teacher/delete、teacher/update、teacher/total_query、teacher/single_query | | 学生 | /api/students | add(学号自动生成)/ total_query(多条件分页)/ single_query / update / delete | | 成绩 | /api/scores | add(60分红线预警)/ query / update / delete | | 就业 | /api/employment | open(状态联动→进入就业)/ offer(状态联动→已就业)/ students/{id} / class/{id} / total_query / update / delete | | 统计 | /api/statistics | 见下 | ### 统计分析接口 | 接口 | 说明 | |---|---| | GET /statistics/students/by-age | 动态年龄查询(gt/lt/eq/gte/lte/between) | | GET /statistics/class/gender-stats | 每班总人数 + 男女分布 | | GET /statistics/score/all-above?line=80 | 每次考试都在分数线以上的学生 | | GET /statistics/score/fail?times=2 | 不及格次数 ≥ N 的学生(含明细) | | GET /statistics/score/class-avg?order=desc | 每次考试每班平均分(动态排序) | | GET /statistics/employment/top-salary?n=10 | 薪资 Top N | | GET /statistics/employment/duration | 每个学生就业时长(offer时间-开放时间) | | GET /statistics/employment/class-avg-duration | 每班平均就业时长 | | GET /statistics/score/volatility?top_n=5 | 成绩波动最大 Top N(最大分差) | | GET /statistics/employment/funnel | 班级就业漏斗(总人数→已就业→高薪→就业率) | | POST /statistics/filter | 通用高级筛选器(AND/OR 嵌套规则,见下) | ### 高级筛选器示例 ```json POST /api/statistics/filter { "model": "student", "rules": [ { "field": "age", "operator": ">", "value": 20 }, { "logic": "OR", "sub_rules": [ { "field": "salary", "operator": ">=", "value": 10000 }, { "field": "class_name", "operator": "like", "value": "Java" } ]} ] } ``` 支持字段:`stu_id, stu_name, age, gender, education, major, native_place, status, class_id, class_name, salary, company_name`;操作符:`> < = != >= <= like in`。 ## 设计说明(对原始建表语句的修正) 1. `c_lass` 补充 `class_name`(原表无班级名称,展示/统计都需要); 2. `student` 补充 `status`(在读/进入就业/已就业),就业联动依赖该字段; 3. `score` 补充 `is_deleted`,统一逻辑删除风格; 4. `employment_base` 补充冗余字段 `stu_name / class_name`(需求 2.3 设计提示),登记时从 student/class 同步写入保证一致性; 5. 新增 `user` 表支撑 JWT 登录与 RBAC(原建表语句缺失); 6. 学号生成规则:`入学年份(4位) + 班级号(2位) + 序号(4位)`,如 2026010001。 ## 待扩展(需求文档第 5 节) - Excel 批量导入学生(python-multipart 已装,可加 pandas/openpyxl) - 部门管理、顾问管理独立模块 - 强制下线/单点登录管控(需引入 Redis Session)