11 KiB
11 KiB
学生课程管理系统 (Student Course Management System)
项目概览
基于 Flask + HTML + MySQL/SQLite 的学生课程管理系统,涵盖学员管理、课程管理、班级管理、充值优惠、消课、退费、转课转赠、停课保号、考勤、统计报表、Excel导出、系统权限等全量功能模块。
技术栈
- 后端: Python 3.12 + Flask + Flask-SQLAlchemy
- 前端: Bootstrap 5.3 + Bootstrap Icons + 自定义 CSS/JS
- 数据库: 默认 SQLite (开发), 支持 MySQL (通过环境变量切换)
- Excel导出: openpyxl
- 端口: 5000
项目结构
/workspace/projects/
├── app.py # Flask主应用入口(create_app工厂模式)
├── config.py # 配置文件(数据库连接等)
├── models.py # SQLAlchemy数据模型(17张表)
├── utils.py # 工具函数(权限体系/导出/迁移/初始化)
├── requirements.txt # Python依赖
├── .coze # Coze配置文件
├── sql/
│ └── mysql_tables.sql # MySQL建表脚本(含初始化数据)
├── routes/ # 模块化路由(Blueprint风格)
│ ├── __init__.py # 路由注册入口
│ ├── auth.py # 登录/登出
│ ├── dashboard.py # 仪表盘首页
│ ├── student.py # 学员管理+导出
│ ├── course.py # 课程管理+导出
│ ├── teacher.py # 老师管理+导出
│ ├── class_.py # 班级管理+考勤+导出
│ ├── recharge.py # 充值+优惠活动+API+导出
│ ├── consumption.py # 消课+导出
│ ├── refund.py # 退费+API+导出
│ ├── transfer.py # 转课转赠+导出
│ ├── stop.py # 停课保号+导出
│ ├── statistics.py # 统计报表+导出
│ └── system.py # 用户/角色/日志/课程安排+导出
├── static/
│ ├── css/style.css # 自定义样式
│ └── js/main.js # 自定义JS(Toast/确认框/导出等)
└── templates/ # Jinja2 HTML模板(30+页面)
├── base.html # 侧边栏布局基模板(权限过滤)
├── login.html # 登录页
├── dashboard.html # 仪表盘首页
├── student_*.html # 学员管理(列表/表单/详情)
├── course_*.html # 课程管理
├── teacher_*.html # 老师管理
├── class_*.html # 班级管理(列表/表单/详情)
├── recharge_activity_*.html # 充值优惠活动
├── recharge_*.html # 充值记录
├── consumption_*.html # 消课管理(单人/批量)
├── refund_*.html # 退费管理
├── transfer_*.html # 转课/转赠
├── stop_*.html # 停课保号
├── attendance_*.html # 考勤
├── statistics.html # 统计报表
├── schedule_*.html # 课程安排
├── user_*.html # 用户管理
├── role_*.html # 角色管理(含权限checkbox分组)
└── log_list.html # 操作日志
核心业务规则
单价计算
- 新签和续费分开计算,不混在一起
- 均不含赠课,只核算正课
- 单价记录在 StudentAccount.unit_price 和 original_price_per_lesson 字段
学员归属
- 学员按班级分配,关联授课老师
- 班级—学员—老师一一对应关系
- 通过 ClassStudent 表维护班级与学员关系
- StudentAccount 记录学员所属班级(from_class_id)和授课老师(from_teacher_id)
消课记录表
- 表格格式展示消课记录
- 支持按日期、班级、老师、学员姓名筛选
- 课时汇总数量手动录入
- API: /api/class_students/<class_id> 获取班级学员列表
转课管理
支持两种转课类型:
1. 班级转课
- 无单价变更转课:仅调整学员所属班级与授课老师,原缴费单价、剩余课时保持不变
- 有单价变更转课:调整班级与老师的同时,同步更新对应计费单价,需备注变更原因及生效时间
2. 课程转课
- 转赠:学员之间课时转移(仅正课)
- 升阶:课程升级,100%正课全额结转
- 换课:不同课程间的课时转换
数据模型 (17+张表)
| 表名 | 说明 |
|---|---|
| roles | 角色表(含permissions字段) |
| users | 用户表(管理员/老师) |
| teachers | 老师表 |
| students | 学员表 |
| courses | 课程表(含total_hours/material_fee/type/remark) |
| classes | 班级表 |
| class_students | 班级学员关联表 |
| student_accounts | 学员课时账户表(含from_class_id/from_teacher_id关联) |
| recharge_activities | 充值优惠活动表(累计/期限/团报/老带新) |
| recharge_records | 充值记录表 |
| consumption_records | 消课记录表(普通/混合/试听) |
| refund_records | 退费记录表(材料费/已消核算) |
| transfer_records | 转课/转赠记录表(含班级转课/单价变更字段) |
| stop_records | 停课保号记录表 |
| attendance_records | 考勤记录表 |
| operation_logs | 操作日志表 |
| schedules | 课程安排表 |
构建和运行
# 安装依赖
pip3 install -r requirements.txt
# 开发环境启动(端口5000)
python3 app.py
# MySQL建表(可选,程序启动时也会自动创建)
mysql -u root -p < sql/mysql_tables.sql
自动迁移机制
程序启动时会自动执行 auto_migrate(),检测 models.py 中定义但数据库中缺失的列,并自动执行 ALTER TABLE ADD COLUMN。这意味着:
- 用
mysql_tables.sql建表后,如果 models.py 新增了字段,无需手动改表,重启程序即可自动补齐 - 对于 MySQL NOT NULL 列,会自动添加合理的默认值
默认账号
- 用户名:
admin - 密码:
admin123
数据库切换
默认使用SQLite。支持三种数据库模式,通过环境变量 DB_TYPE 切换:
方式1 - 自建MySQL
DB_TYPE=mysql
MYSQL_HOST=127.0.0.1
MYSQL_PORT=3306
MYSQL_USER=root
MYSQL_PASSWORD=your_password
MYSQL_DB=student_course
方式2 - 阿里云RDS MySQL
DB_TYPE=aliyun_mysql
ALIYUN_MYSQL_HOST=rm-xxxxx.mysql.rds.aliyuncs.com # RDS内网/外网地址
ALIYUN_MYSQL_PORT=3306
ALIYUN_MYSQL_USER=root
ALIYUN_MYSQL_PASSWORD=your_password
ALIYUN_MYSQL_DB=student_course
ALIYUN_MYSQL_SSL=1 # 可选,设为1启用SSL加密连接
阿里云RDS连接池已针对RDS特性优化:
pool_recycle=1800— 低于RDS默认wait_timeout,避免连接被服务端主动断开pool_pre_ping=True— 每次取连接前探测存活,防止断连报错connect_timeout=10— 建立连接超时10秒- SSL连接: 设置
ALIYUN_MYSQL_SSL=1启用,适用于要求加密传输的场景
MySQL兼容性说明
- 日期函数: 代码已兼容SQLite和MySQL,避免使用
strftime(仅SQLite),改用>=范围查询 - GROUP BY: MySQL严格模式下GROUP BY列必须与SELECT列一致,已按
id分组 - db.case: 使用
db.case((condition, value), else_=0)兼容SQLAlchemy 2.x - 连接池: MySQL配置了pool_size=10, max_overflow=20, pool_recycle=3600
- 字符集: MySQL连接使用charset=utf8mb4
权限体系
权限定义 (utils.py - PERMISSIONS字典)
共54个权限项,按16个模块分组:
| 模块 | 权限项 |
|---|---|
| 学员管理 | student_view, student_add, student_edit, student_delete, student_export |
| 课程管理 | course_view, course_add, course_edit, course_delete, course_export |
| 老师管理 | teacher_view, teacher_add, teacher_edit, teacher_delete, teacher_export |
| 班级管理 | class_view, class_add, class_edit, class_delete, class_export |
| 充值管理 | recharge_view, recharge_add, recharge_export |
| 优惠活动 | recharge_activity_view, recharge_activity_add, recharge_activity_edit |
| 消课管理 | consumption_view, consumption_add, consumption_export |
| 退费管理 | refund_view, refund_add, refund_export |
| 转课转赠 | transfer_view, transfer_add, transfer_export |
| 停课保号 | stop_view, stop_add, stop_export |
| 考勤管理 | attendance_view, attendance_add, attendance_export |
| 统计报表 | statistics_view, statistics_export |
| 课程安排 | schedule_view, schedule_add, schedule_export |
| 用户管理 | user_view, user_add, user_edit |
| 角色管理 | role_view, role_add, role_edit |
| 操作日志 | log_view, log_export |
权限控制机制
- 角色绑定: 每个角色(Role)的
permissions字段存储逗号分隔的权限键(如student_view,student_export) - 超级管理员: 角色名为"超级管理员"或permissions为"all"时,自动拥有所有权限
- User.has_permission(): 用户对象的权限检查方法,用于模板中
current_user.has_permission('xxx') - permission_required装饰器: 后端路由权限检查,无权限时重定向到dashboard
- 侧边栏过滤: base.html中根据
current_user.has_permission()控制菜单显示 - 导出按钮: 列表页根据
current_user.has_permission('xxx_export')控制显示
角色管理
- 在角色编辑页面,权限按模块分组显示为checkbox
- 支持全选/取消/仅选查看快捷操作
- 超级管理员角色不可编辑/删除
Excel导出功能
所有模块均支持导出Excel,使用openpyxl生成:
| 导出路由 | 端点 | 所需权限 |
|---|---|---|
| /students/export | student_export | student_export |
| /courses/export | course_export | course_export |
| /teachers/export | teacher_export | teacher_export |
| /classes/export | class_export | class_export |
| /recharge_activities/export | recharge_activity_export | recharge_activity_export |
| /recharges/export | recharge_export | recharge_export |
| /consumptions/export | consumption_export | consumption_export |
| /refunds/export | refund_export | refund_export |
| /transfers/export | transfer_export | transfer_export |
| /stops/export | stop_export | stop_export |
| /statistics/export | statistics_export | statistics_export |
| /schedules/export | schedule_export | schedule_export |
| /operation_logs/export | log_export | log_export |
导出文件格式: xlsx, 含标题行、表头样式、自动列宽调整。
核心业务逻辑
- 消课规则: 先扣正课,再扣赠课;试听课不扣课;停课保号期间不可消课
- 退费规则: 退费=充值总额-已消课时金额(按原价)-材料费(250元/季度);需扣回赠课
- 转课规则: 按剩余金额换算转入课程课时(剩余课时×转出单价÷转入单价)
- 转赠规则: 同课程下课时转赠给其他学员
- 充值优惠: 自动匹配优惠活动(触发金额/有效期/参与人群/累计充值)
- 停课保号: 最长3年,停课期间不可消课,复课后恢复
API接口
| 路径 | 方法 | 说明 |
|---|---|---|
| /api/student_account/<student_id>/<course_id> | GET | 获取学员课时账户 |
| /api/student_accounts/<student_id> | GET | 获取学员所有账户 |
| /api/calculate_recharge | POST | 计算充值优惠(预览) |
| /api/calculate_refund | POST | 计算退费金额(预览) |