Files
ClassManager/backend/main.py
2026-05-28 15:38:32 +08:00

142 lines
4.3 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ===========================================
# 班级操行分管理系统 - 主入口
#
# 开发者: Canglan
# 联系方式: admin@sea-studio.top
# 版权归属: Sea Network Technology Studio
# 许可证: MIT License
#
# 版权所有 © Sea Network Technology Studio
# ===========================================
from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from contextlib import asynccontextmanager
import traceback
import uvicorn
from config import settings
from utils.logger import setup_logger, log_access
from utils.database import init_db_pool, close_db_pool
from utils.redis_client import init_redis_pool, close_redis_pool
from middleware.auth_middleware import AuthMiddleware
from routes import auth, student, parent, admin, subject, semester, debug, upgrade
from routes.config import router as config_router
# 设置日志
logger = setup_logger()
@asynccontextmanager
async def lifespan(app: FastAPI):
"""应用生命周期管理"""
logger.info("正在启动应用...")
await init_db_pool()
await init_redis_pool()
logger.info(f"CORS 允许域名: {settings.CORS_ORIGINS}")
logger.info(f"{settings.APP_NAME} 启动完成")
yield
logger.info("正在关闭应用...")
await close_db_pool()
await close_redis_pool()
logger.info("应用已关闭")
# 创建FastAPI应用
app = FastAPI(
title=settings.APP_NAME,
version=settings.API_VERSION,
debug=settings.DEBUG,
lifespan=lifespan
)
# 访问日志中间件
@app.middleware("http")
async def access_log_middleware(request: Request, call_next):
log_access(request)
response = await call_next(request)
return response
# 认证中间件(先注册,后执行)
app.add_middleware(AuthMiddleware)
# CORS中间件后注册先执行- 从环境变量读取允许的域名
cors_origins = settings.CORS_ORIGINS
if not cors_origins:
logger.warning("CORS_ORIGINS 未配置或为空,跨域请求将被拒绝!请检查 .env 文件中的 CORS_ORIGINS 配置")
app.add_middleware(
CORSMiddleware,
allow_origins=cors_origins,
allow_credentials=True,
allow_methods=["GET", "POST", "PUT", "DELETE", "OPTIONS"],
allow_headers=["*"],
expose_headers=["*"],
)
# 全局异常处理器
@app.exception_handler(Exception)
async def global_exception_handler(request: Request, exc: Exception):
"""全局异常处理器 - 捕获所有未处理异常"""
logger.error(f"未处理异常: {exc}", exc_info=True)
# 获取origin用于CORS头
origin = request.headers.get("origin", "")
allowed_origins = settings.CORS_ORIGINS or []
# 使用HTTP 200 + 业务错误码返回避免CORS头丢失问题
# FastAPI exception_handler返回的500响应可能不经过CORS中间件导致跨域读取失败
headers = {}
if origin in allowed_origins:
headers["access-control-allow-origin"] = origin
headers["access-control-allow-credentials"] = "true"
headers["access-control-expose-headers"] = "*"
return JSONResponse(
status_code=200,
content={
"success": False,
"code": 500,
"message": f"服务器内部错误: {str(exc)}",
"detail": traceback.format_exc() if settings.DEBUG else None
},
headers=headers
)
# 注册路由
app.include_router(auth.router, prefix="/api/auth", tags=["认证"])
app.include_router(student.router, prefix="/api/student", tags=["学生端"])
app.include_router(parent.router, prefix="/api/parent", tags=["家长端"])
app.include_router(admin.router, prefix="/api/admin", tags=["管理端"])
app.include_router(subject.router, prefix="/api/subject", tags=["科目管理"])
app.include_router(semester.router, prefix="/api/semester", tags=["学期管理"])
app.include_router(config_router, prefix="/api/config", tags=["配置"])
app.include_router(upgrade.router, prefix="/api/upgrade", tags=["升级管理"])
app.include_router(debug.router, tags=["调试"])
@app.get("/")
async def root():
return {"status": "ok", "message": f"{settings.APP_NAME} API 运行中"}
@app.get("/health")
async def health_check():
return {"status": "healthy"}
if __name__ == "__main__":
uvicorn.run(
"main:app",
host="0.0.0.0",
port=8000,
reload=settings.DEBUG
)