feat(frontend): 重构视频分析页面,支持多种搜索方式
主要更新: - 前端改用 Ant Design 组件(Table、Modal、Select 等) - 支持三种搜索方式:星图ID、达人unique_id、达人昵称模糊匹配 - 列表页实时调用云图 API 获取 A3 数据和成本指标 - 详情弹窗显示完整 6 大类指标,支持文字复制 - 品牌 API URL 格式修复为查询参数形式 - 优化云图 API 参数格式和会话池管理 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,26 +1,55 @@
|
||||
"""
|
||||
视频分析API路由 (T-024)
|
||||
|
||||
GET /api/v1/videos/{item_id}/analysis
|
||||
GET /api/v1/videos/{item_id}/analysis - 单个视频分析
|
||||
POST /api/v1/videos/search - 搜索视频列表(支持 star_id / nickname)
|
||||
"""
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from typing import List, Optional
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query
|
||||
from pydantic import BaseModel
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.database import get_db
|
||||
from app.services.video_analysis import get_video_analysis_data
|
||||
from app.services.video_analysis import (
|
||||
get_video_analysis_data,
|
||||
get_video_base_info,
|
||||
search_videos_by_star_id,
|
||||
search_videos_by_unique_id,
|
||||
search_videos_by_nickname,
|
||||
get_video_list_with_a3,
|
||||
)
|
||||
from app.services.yuntu_api import YuntuAPIError
|
||||
|
||||
router = APIRouter(prefix="/videos", tags=["视频分析"])
|
||||
|
||||
|
||||
class SearchRequest(BaseModel):
|
||||
"""搜索请求"""
|
||||
type: str # "star_id" | "unique_id" | "nickname"
|
||||
value: str
|
||||
|
||||
|
||||
class VideoListItem(BaseModel):
|
||||
"""视频列表项"""
|
||||
item_id: str
|
||||
title: str
|
||||
star_nickname: str
|
||||
star_unique_id: str
|
||||
create_date: Optional[str]
|
||||
hot_type: str
|
||||
total_play_cnt: int
|
||||
total_new_a3_cnt: int
|
||||
total_cost: float
|
||||
|
||||
|
||||
@router.get("/{item_id}/analysis")
|
||||
async def get_video_analysis(
|
||||
item_id: str,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
"""
|
||||
获取视频分析数据。
|
||||
获取单个视频分析数据。
|
||||
|
||||
返回6大类指标:
|
||||
- 基础信息 (8字段)
|
||||
@@ -53,3 +82,94 @@ async def get_video_analysis(
|
||||
raise HTTPException(status_code=500, detail=f"API Error: {e.message}")
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"Internal error: {str(e)}")
|
||||
|
||||
|
||||
@router.post("/search")
|
||||
async def search_videos(
|
||||
request: SearchRequest,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
"""
|
||||
搜索视频列表。
|
||||
|
||||
支持三种搜索方式(均返回列表,点击详情查看完整数据):
|
||||
- star_id: 星图ID精准匹配
|
||||
- unique_id: 达人unique_id精准匹配
|
||||
- nickname: 达人昵称模糊匹配
|
||||
|
||||
Args:
|
||||
request: 搜索请求,包含 type 和 value
|
||||
|
||||
Returns:
|
||||
视频列表(含A3数据和成本指标)
|
||||
"""
|
||||
try:
|
||||
if request.type == "star_id":
|
||||
# 星图ID查询,返回视频列表
|
||||
videos = await search_videos_by_star_id(db, request.value)
|
||||
if not videos:
|
||||
return {
|
||||
"success": True,
|
||||
"type": "list",
|
||||
"data": [],
|
||||
"total": 0,
|
||||
}
|
||||
|
||||
# 获取 A3 数据
|
||||
result = await get_video_list_with_a3(db, videos)
|
||||
return {
|
||||
"success": True,
|
||||
"type": "list",
|
||||
"data": result,
|
||||
"total": len(result),
|
||||
}
|
||||
|
||||
elif request.type == "unique_id":
|
||||
# 达人unique_id查询,返回视频列表
|
||||
videos = await search_videos_by_unique_id(db, request.value)
|
||||
if not videos:
|
||||
return {
|
||||
"success": True,
|
||||
"type": "list",
|
||||
"data": [],
|
||||
"total": 0,
|
||||
}
|
||||
|
||||
# 获取 A3 数据
|
||||
result = await get_video_list_with_a3(db, videos)
|
||||
return {
|
||||
"success": True,
|
||||
"type": "list",
|
||||
"data": result,
|
||||
"total": len(result),
|
||||
}
|
||||
|
||||
elif request.type == "nickname":
|
||||
# 昵称模糊查询,返回视频列表
|
||||
videos = await search_videos_by_nickname(db, request.value)
|
||||
if not videos:
|
||||
return {
|
||||
"success": True,
|
||||
"type": "list",
|
||||
"data": [],
|
||||
"total": 0,
|
||||
}
|
||||
|
||||
# 获取 A3 数据
|
||||
result = await get_video_list_with_a3(db, videos)
|
||||
return {
|
||||
"success": True,
|
||||
"type": "list",
|
||||
"data": result,
|
||||
"total": len(result),
|
||||
}
|
||||
|
||||
else:
|
||||
raise HTTPException(status_code=400, detail=f"Invalid search type: {request.type}")
|
||||
|
||||
except ValueError as e:
|
||||
raise HTTPException(status_code=404, detail=str(e))
|
||||
except YuntuAPIError as e:
|
||||
raise HTTPException(status_code=500, detail=f"API Error: {e.message}")
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"Internal error: {str(e)}")
|
||||
|
||||
Reference in New Issue
Block a user