import sys import os sys.path.insert(0, os.path.dirname(__file__)) from fastapi import FastAPI, Request from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import FileResponse from contextlib import asynccontextmanager import uvicorn from starlette.staticfiles import StaticFiles from app.database import init_db from core.security import SECRET_KEY from api import auth, topics, system, publishing, articles, logs, admin @asynccontextmanager async def lifespan(app: FastAPI): """应用生命周期管理""" print("正在初始化数据库...") init_db() print("数据库初始化完成") yield print("应用关闭") app = FastAPI( title="宇之然内容创作平台 API", description="企业级内容创作管理系统", version="1.0.0", lifespan=lifespan ) # CORS配置 app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # API 路由(必须先于静态文件注册) app.include_router(auth.router, prefix="/api/auth", tags=["认证"]) app.include_router(topics.router, prefix="/api/topics", tags=["选题管理"]) app.include_router(system.router, prefix="/api/system", tags=["系统状态"]) app.include_router(publishing.router, prefix="/api/publishing", tags=["文章发布"]) app.include_router(articles.router, prefix="/api/articles", tags=["文章预览"]) app.include_router(logs.router, prefix="/api/logs", tags=["日志系统"]) app.include_router(admin.router, prefix="/api/admin", tags=["管理员"]) # 健康检查 @app.get("/health") async def health_check(): return {"status": "healthy", "timestamp": __import__('datetime').datetime.now().isoformat()} # 独立页面路由(必须在 SPA catch-all 之前) @app.get("/topics.html") async def topics_page(): return FileResponse("static/topics.html") @app.get("/logs.html") async def logs_page(): return FileResponse("static/logs.html") @app.get("/users.html") async def users_page(): return FileResponse("static/users.html") # 静态文件(不干扰API) app.mount("/static", StaticFiles(directory="static"), name="static") # SPA:所有非 API 路径返回 index.html(最后注册) @app.get("/{full_path:path}") async def serve_spa(full_path: str): return FileResponse("static/index.html") @app.exception_handler(Exception) async def global_exception_handler(request: Request, exc: Exception): import traceback print(f"全局异常: {exc}") print(f"堆栈跟踪:\n{traceback.format_exc()}") return { "error": "服务器内部错误", "message": str(exc), "path": request.url.path } if __name__ == "__main__": uvicorn.run("main:app", host="0.0.0.0", port=8001, reload=True, log_level="info")