122 lines
3.7 KiB
Python
122 lines
3.7 KiB
Python
from flask import Flask, redirect, url_for
|
|
from flask_login import LoginManager, current_user # 添加 current_user 导入
|
|
from config.config import config
|
|
from app.models import db, User, Student # 添加 Student 导入
|
|
import os
|
|
import json # 添加 json 导入
|
|
from datetime import datetime, timedelta # 添加 datetime 和 timedelta 导入
|
|
|
|
|
|
def create_app(config_name=None):
|
|
if config_name is None:
|
|
config_name = os.environ.get('FLASK_ENV', 'default')
|
|
|
|
app = Flask(__name__)
|
|
app.config.from_object(config[config_name])
|
|
|
|
# 初始化扩展
|
|
db.init_app(app)
|
|
|
|
# 初始化Flask-Login
|
|
login_manager = LoginManager()
|
|
login_manager.init_app(app)
|
|
login_manager.login_view = 'auth.login'
|
|
login_manager.login_message = '请先登录后访问此页面。'
|
|
login_manager.login_message_category = 'info'
|
|
|
|
@app.template_filter('fromjson')
|
|
def from_json(value):
|
|
try:
|
|
return json.loads(value)
|
|
except:
|
|
return {}
|
|
|
|
@app.template_filter('strptime')
|
|
def strptime_filter(value, format_string):
|
|
try:
|
|
return datetime.strptime(value, format_string)
|
|
except:
|
|
return None
|
|
|
|
@app.template_filter('calculate_duration')
|
|
def calculate_duration(start_time, end_time, date_str):
|
|
try:
|
|
if not start_time or not end_time:
|
|
return None
|
|
|
|
start_datetime = datetime.strptime(f"{date_str} {start_time}", '%Y-%m-%d %H:%M:%S')
|
|
end_datetime = datetime.strptime(f"{date_str} {end_time}", '%Y-%m-%d %H:%M:%S')
|
|
|
|
# 如果结束时间小于开始时间,说明跨天了
|
|
if end_datetime < start_datetime:
|
|
end_datetime += timedelta(days=1)
|
|
|
|
duration = (end_datetime - start_datetime).total_seconds() / 3600
|
|
return round(duration, 1)
|
|
except:
|
|
return None
|
|
|
|
@app.context_processor
|
|
def utility_processor():
|
|
def get_current_student():
|
|
# 添加安全检查
|
|
if not current_user.is_authenticated:
|
|
return None
|
|
if current_user.is_admin():
|
|
return None
|
|
return Student.query.filter_by(student_number=current_user.student_number).first()
|
|
|
|
return dict(get_current_student=get_current_student)
|
|
|
|
# 注册Python内置函数到Jinja2环境
|
|
app.jinja_env.globals.update(
|
|
max=max,
|
|
min=min,
|
|
abs=abs,
|
|
round=round,
|
|
len=len,
|
|
int=int,
|
|
float=float,
|
|
str=str,
|
|
sum=sum,
|
|
enumerate=enumerate,
|
|
zip=zip
|
|
)
|
|
|
|
@login_manager.user_loader
|
|
def load_user(user_id):
|
|
return User.query.get(int(user_id))
|
|
|
|
# 注册蓝图
|
|
from app.routes.auth import auth_bp
|
|
from app.routes.student import student_bp
|
|
from app.routes.admin import admin_bp
|
|
|
|
app.register_blueprint(auth_bp, url_prefix='/auth')
|
|
app.register_blueprint(student_bp, url_prefix='/student')
|
|
app.register_blueprint(admin_bp, url_prefix='/admin')
|
|
|
|
# 注册模板全局函数
|
|
from app.utils import get_pending_leaves_count
|
|
app.jinja_env.globals.update(
|
|
get_pending_leaves_count=get_pending_leaves_count,
|
|
# 移除这行,因为我们已经通过 context_processor 注册了
|
|
# get_current_student=get_current_student
|
|
)
|
|
|
|
# 主页路由
|
|
@app.route('/')
|
|
def index():
|
|
if current_user.is_authenticated:
|
|
if current_user.is_admin():
|
|
return redirect(url_for('admin.dashboard'))
|
|
else:
|
|
return redirect(url_for('student.dashboard'))
|
|
return redirect(url_for('auth.login'))
|
|
|
|
# 创建数据库表
|
|
with app.app_context():
|
|
db.create_all()
|
|
|
|
return app
|