from fastapi import FastAPI, HTTPException, Request from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import JSONResponse import logging import dashscope 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") 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"), }