from fastapi import FastAPI, HTTPException, Request from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import JSONResponse from fastapi.staticfiles import StaticFiles import logging import dashscope from pathlib import Path from .routers import config as config_router from .routers import lover as lover_router from .response import ApiResponse from .routers import outfit as outfit_router from .routers import chat as chat_router from .routers import voice_call as voice_call_router from .routers import dance as dance_router from .routers import dynamic as dynamic_router from .routers import sing as sing_router from .task_queue import start_sing_workers from .config import settings # 初始化 DashScope API Key if settings.DASHSCOPE_API_KEY: dashscope.api_key = settings.DASHSCOPE_API_KEY app = FastAPI(title="LOVER API") # 创建 TTS 文件目录 tts_dir = Path("public/tts") tts_dir.mkdir(parents=True, exist_ok=True) # 挂载静态文件服务(用于提供 TTS 音频文件) app.mount("/tts", StaticFiles(directory=str(tts_dir)), name="tts") app.add_middleware( CORSMiddleware, allow_origins=[ "http://localhost", "http://localhost:5173", "http://localhost:8080", "http://127.0.0.1", "http://127.0.0.1:5173", "http://127.0.0.1:8080", ], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) app.include_router(config_router.router) app.include_router(lover_router.router) app.include_router(outfit_router.router) app.include_router(chat_router.router) app.include_router(voice_call_router.router) app.include_router(dance_router.router) app.include_router(dynamic_router.router) app.include_router(sing_router.router) @app.on_event("startup") async def startup_tasks(): start_sing_workers() @app.exception_handler(HTTPException) async def http_exception_handler(request: Request, exc: HTTPException): # 统一错误响应结构,便于前端通过 code 判定 detail = exc.detail msg = detail if isinstance(detail, str) else str(detail) return JSONResponse( status_code=exc.status_code, content={"code": exc.status_code, "msg": msg, "data": None}, ) @app.exception_handler(Exception) async def generic_exception_handler(request: Request, exc: Exception): logging.exception("Unhandled error", exc_info=exc) return JSONResponse( status_code=500, content={"code": 500, "msg": "服务器内部错误", "data": None}, ) @app.get("/health", response_model=ApiResponse[dict]) async def health(): return ApiResponse(code=1, msg="ok", data={"status": "ok"}) @app.get("/debug/auth") async def debug_auth(request: Request): """调试认证信息""" headers = dict(request.headers) return { "app_env": settings.APP_ENV, "debug": settings.DEBUG, "headers": headers, "token": headers.get("token"), "authorization": headers.get("authorization"), }