""" 发布管理 API (支持用户认证) """ from fastapi import APIRouter, HTTPException, BackgroundTasks, Depends, Request from pydantic import BaseModel from typing import List, Optional from datetime import datetime from loguru import logger from app.services.publish_service import PublishService from app.core.deps import get_current_user_optional router = APIRouter() publish_service = PublishService() class PublishRequest(BaseModel): """Video publish request model""" video_path: str platform: str title: str tags: List[str] = [] description: str = "" publish_time: Optional[datetime] = None class PublishResponse(BaseModel): """Video publish response model""" success: bool message: str platform: str url: Optional[str] = None # Supported platforms for validation SUPPORTED_PLATFORMS = {"bilibili", "douyin", "xiaohongshu"} def _get_user_id(request: Request) -> Optional[str]: """从请求中获取用户 ID (兼容未登录场景)""" try: from app.core.security import decode_access_token token = request.cookies.get("access_token") if token: token_data = decode_access_token(token) if token_data: return token_data.user_id except Exception: pass return None @router.post("/", response_model=PublishResponse) async def publish_video(request: PublishRequest, req: Request, background_tasks: BackgroundTasks): """发布视频到指定平台""" # Validate platform if request.platform not in SUPPORTED_PLATFORMS: raise HTTPException( status_code=400, detail=f"不支持的平台: {request.platform}。支持的平台: {', '.join(SUPPORTED_PLATFORMS)}" ) # 获取用户 ID (可选) user_id = _get_user_id(req) try: result = await publish_service.publish( video_path=request.video_path, platform=request.platform, title=request.title, tags=request.tags, description=request.description, publish_time=request.publish_time, user_id=user_id ) return PublishResponse( success=result.get("success", False), message=result.get("message", ""), platform=request.platform, url=result.get("url") ) except Exception as e: logger.error(f"发布失败: {e}") raise HTTPException(status_code=500, detail=str(e)) @router.get("/platforms") async def list_platforms(): return {"platforms": [{**pinfo, "id": pid} for pid, pinfo in publish_service.PLATFORMS.items()]} @router.get("/accounts") async def list_accounts(req: Request): user_id = _get_user_id(req) return {"accounts": publish_service.get_accounts(user_id)} @router.post("/login/{platform}") async def login_platform(platform: str, req: Request): """触发平台QR码登录""" if platform not in SUPPORTED_PLATFORMS: raise HTTPException(status_code=400, detail=f"不支持的平台: {platform}") user_id = _get_user_id(req) result = await publish_service.login(platform, user_id) if result.get("success"): return result else: raise HTTPException(status_code=400, detail=result.get("message")) @router.post("/logout/{platform}") async def logout_platform(platform: str, req: Request): """注销平台登录""" if platform not in SUPPORTED_PLATFORMS: raise HTTPException(status_code=400, detail=f"不支持的平台: {platform}") user_id = _get_user_id(req) result = publish_service.logout(platform, user_id) return result @router.get("/login/status/{platform}") async def get_login_status(platform: str, req: Request): """检查登录状态 (优先检查活跃的扫码会话)""" if platform not in SUPPORTED_PLATFORMS: raise HTTPException(status_code=400, detail=f"不支持的平台: {platform}") user_id = _get_user_id(req) return publish_service.get_login_session_status(platform, user_id) @router.post("/cookies/save/{platform}") async def save_platform_cookie(platform: str, cookie_data: dict, req: Request): """ 保存从客户端浏览器提取的Cookie Args: platform: 平台ID cookie_data: {"cookie_string": "document.cookie的内容"} """ if platform not in SUPPORTED_PLATFORMS: raise HTTPException(status_code=400, detail=f"不支持的平台: {platform}") cookie_string = cookie_data.get("cookie_string", "") if not cookie_string: raise HTTPException(status_code=400, detail="cookie_string 不能为空") user_id = _get_user_id(req) result = await publish_service.save_cookie_string(platform, cookie_string, user_id) if result.get("success"): return result else: raise HTTPException(status_code=400, detail=result.get("message"))