Files
drl_2/xuexiao/app.py

164 lines
5.9 KiB
Python
Raw Normal View History

2026-05-29 10:28:07 +08:00
"""学生课程管理系统 - Flask主应用入口"""
import os
from flask import Flask
from config import Config, write_engine
from models import db
def create_app():
"""应用工厂函数"""
app = Flask(__name__)
app.config.from_object(Config)
app.config['TEMPLATES_AUTO_RELOAD'] = True
# 初始化数据库
2026-05-29 10:28:07 +08:00
db.init_app(app)
# 仅当存在有效的 write_engine非 None时才复用
if write_engine is not None:
if app in db._app_engines:
old_engine = db._app_engines[app].get(None)
if old_engine is not None and old_engine is not write_engine:
old_engine.dispose()
db._app_engines[app][None] = write_engine
2026-05-29 10:28:07 +08:00
# 注入模板上下文变量
@app.context_processor
def inject_globals():
from flask import session
from datetime import date
from models import User, ConsumptionRecord, Student
from sqlalchemy import func
user_id = session.get('user_id')
user = db.session.get(User, user_id) if user_id else None
panel_progress = 0
if user:
month_start = date.today().replace(day=1)
month_h = db.session.query(
func.coalesce(func.sum(ConsumptionRecord.hours_consumed), 0)
).filter(ConsumptionRecord.consume_date >= month_start).scalar() or 0
students = Student.query.filter_by(status=1).count() or 1
target = max(students * 4, 20)
panel_progress = min(100, int(float(month_h) / target * 100))
return {'current_user': user, 'panel_progress': panel_progress}
# 注册路由直接注册到app不使用蓝图
with app.app_context():
from routes import register_all_routes
register_all_routes(app)
# 建表 + 自动迁移Doris / MySQL / SQLite
from db_bootstrap import bootstrap_database
bootstrap_database()
_init_default_data()
_sync_account_original_prices()
return app
def _sync_account_original_prices():
"""未录原价时:课程表单价 → 最新月度快照单价"""
from models import db, StudentAccount, Course, MonthlySnapshot
from sqlalchemy import func
try:
accounts = StudentAccount.query.filter(
db.or_(
StudentAccount.original_price_per_lesson.is_(None),
StudentAccount.original_price_per_lesson == 0,
)
).all()
n = 0
for acc in accounts:
if acc.original_price_per_lesson and float(acc.original_price_per_lesson or 0) > 0:
continue
crs = db.session.get(Course, acc.course_id)
if crs and float(crs.price_per_hour or 0) > 0:
acc.original_price_per_lesson = crs.price_per_hour
n += 1
continue
row = (
db.session.query(MonthlySnapshot.unit_price)
.filter(
MonthlySnapshot.account_id == acc.id,
MonthlySnapshot.unit_price > 0,
)
.order_by(
MonthlySnapshot.year.desc(),
MonthlySnapshot.month.desc(),
)
.first()
)
if row and float(row[0] or 0) > 0:
acc.original_price_per_lesson = row[0]
n += 1
if n:
db.session.commit()
except Exception:
db.session.rollback()
def _init_default_data():
"""初始化默认数据: 确保admin用户和管理员角色存在"""
from models import User, Role
from utils import PERMISSIONS
# §八 默认角色层级
default_roles = [
('超级管理员', 'all', '全部权限'),
('校区管理员', ','.join(PERMISSIONS.keys()), '本校区全部业务'),
(
'财务',
'recharge_view,recharge_add,recharge_export,recharge_activity_view,'
'recharge_activity_add,recharge_activity_edit,refund_view,refund_add,'
'refund_export,statistics_view,statistics_export,log_view',
'充值退费与报表',
),
(
'授课老师',
'student_view,course_view,class_view,class_add,attendance_view,'
'attendance_add,consumption_view,consumption_add,schedule_view',
'消课考勤与班级',
),
]
for name, perms, remark in default_roles:
if not Role.query.filter_by(name=name).first():
db.session.add(Role(name=name, permissions=perms, remark=remark))
db.session.commit()
# 校区管理员:补齐后续新增的权限项(如课时核对表)
campus = Role.query.filter_by(name='校区管理员').first()
if campus and campus.permissions != 'all':
all_keys = sorted(PERMISSIONS.keys())
campus.permissions = ','.join(all_keys)
db.session.commit()
admin_role = Role.query.filter_by(name='超级管理员').first()
if not admin_role:
admin_role = Role(name='超级管理员', permissions='all', remark='系统默认管理员角色')
db.session.add(admin_role)
db.session.commit()
admin_role = Role.query.filter_by(name='超级管理员').first()
# 确保admin用户存在且密码正确
admin = User.query.filter_by(username='admin').first()
default_password = 'admin123'
if not admin:
admin = User(
username='admin', real_name='系统管理员',
role_id=admin_role.id, status=1, remark='默认管理员'
)
admin.set_password(default_password)
db.session.add(admin)
db.session.commit()
elif not admin.check_password(default_password):
admin.set_password(default_password)
db.session.commit()
app = create_app()
if __name__ == '__main__':
port = int(os.environ.get('DEPLOY_RUN_PORT', 5000))
app.run(host='0.0.0.0', port=port, debug=True, use_reloader=True)