import uuid from fastapi import APIRouter, Depends, HTTPException, Query, status from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from app.api.deps import get_current_user from app.database import get_db from app.models.user import User from app.models.brand import Brand from app.models.trend_insight import TrendInsight from app.schemas.trend_insight import ( TrendInsightRequest, TrendInsightResponse, TrendInsightList, TrendSummary, ) from app.services.trend.trend_analyzer_service import TrendAnalyzerService router = APIRouter() async def _get_brand_with_access( brand_id: uuid.UUID, db: AsyncSession, current_user: User, ) -> Brand: stmt = select(Brand).where( Brand.id == brand_id, Brand.user_id == current_user.id, ) result = await db.execute(stmt) brand = result.scalar_one_or_none() if not brand: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="品牌不存在", ) return brand @router.post("/insight", response_model=TrendInsightResponse) async def create_trend_insight( request: TrendInsightRequest, current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), ): await _get_brand_with_access(request.brand_id, db, current_user) service = TrendAnalyzerService(db) result = await service.analyze_trends( brand_id=request.brand_id, days=request.period_days, platforms=request.platforms, keywords=request.keywords, ) if result.get("status") == "insufficient_data": raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=result.get("message", "数据不足"), ) insight_id = uuid.UUID(result["insight_id"]) insight = await service.get_insight_by_id(insight_id) if insight is None: raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="洞察创建失败", ) return insight @router.get("/brand/{brand_id}", response_model=TrendInsightList) async def list_trend_insights( brand_id: uuid.UUID, skip: int = Query(0, ge=0), limit: int = Query(20, ge=1, le=100), current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), ): await _get_brand_with_access(brand_id, db, current_user) service = TrendAnalyzerService(db) items, total = await service.get_insights( brand_id=brand_id, skip=skip, limit=limit, ) return TrendInsightList(items=items, total=total) @router.get("/brand/{brand_id}/summary", response_model=TrendSummary) async def get_trend_summary( brand_id: uuid.UUID, period_days: int = Query(30, ge=7, le=365), current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), ): await _get_brand_with_access(brand_id, db, current_user) service = TrendAnalyzerService(db) summary = await service.get_summary( brand_id=brand_id, days=period_days, ) return TrendSummary(**summary) @router.get("/{insight_id}", response_model=TrendInsightResponse) async def get_trend_insight_detail( insight_id: uuid.UUID, current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), ): service = TrendAnalyzerService(db) insight = await service.get_insight_by_id(insight_id) if insight is None: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="洞察不存在", ) return insight