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,52 +1,119 @@
|
||||
from sqlalchemy import Column, String, Integer, Float, DateTime, Index
|
||||
from sqlalchemy import Column, String, Integer, Float, DateTime, BigInteger, Boolean, Date, Text
|
||||
from sqlalchemy.dialects.postgresql import JSONB
|
||||
from app.database import Base
|
||||
|
||||
|
||||
class KolVideo(Base):
|
||||
"""KOL 视频数据模型."""
|
||||
"""KOL 视频数据模型 - 映射真实数据库表 yuntu_industry_kol_records."""
|
||||
|
||||
__tablename__ = "kol_videos"
|
||||
__tablename__ = "yuntu_industry_kol_records"
|
||||
|
||||
# 主键
|
||||
item_id = Column(String, primary_key=True)
|
||||
|
||||
# 基础信息
|
||||
title = Column(String, nullable=True)
|
||||
viral_type = Column(String, nullable=True)
|
||||
video_url = Column(String, nullable=True)
|
||||
video_url = Column(Text, nullable=True)
|
||||
vid = Column(String, nullable=True)
|
||||
video_duration = Column(Float, nullable=True)
|
||||
create_date = Column(Date, nullable=True)
|
||||
data_date = Column(Date, nullable=True)
|
||||
|
||||
# 达人信息
|
||||
star_id = Column(String, nullable=False)
|
||||
star_unique_id = Column(String, nullable=False)
|
||||
star_nickname = Column(String, nullable=False)
|
||||
publish_time = Column(DateTime, nullable=True)
|
||||
star_uid = Column(String, nullable=True)
|
||||
star_fans_cnt = Column(BigInteger, nullable=True)
|
||||
star_mcn = Column(String, nullable=True)
|
||||
|
||||
# 热度类型
|
||||
hot_type = Column(String, nullable=True) # 映射为 viral_type
|
||||
is_hot = Column(Boolean, nullable=True)
|
||||
has_cart = Column(Boolean, nullable=True)
|
||||
|
||||
# 曝光指标
|
||||
natural_play_cnt = Column(Integer, default=0)
|
||||
heated_play_cnt = Column(Integer, default=0)
|
||||
total_play_cnt = Column(Integer, default=0)
|
||||
natural_play_cnt = Column(BigInteger, default=0)
|
||||
heated_play_cnt = Column(BigInteger, default=0)
|
||||
total_play_cnt = Column(BigInteger, default=0)
|
||||
|
||||
# 互动指标
|
||||
total_interact = Column(Integer, default=0)
|
||||
like_cnt = Column(Integer, default=0)
|
||||
share_cnt = Column(Integer, default=0)
|
||||
comment_cnt = Column(Integer, default=0)
|
||||
total_interaction_cnt = Column(BigInteger, default=0) # 映射为 total_interact
|
||||
natural_interaction_cnt = Column(BigInteger, default=0)
|
||||
heated_interaction_cnt = Column(BigInteger, default=0)
|
||||
digg_cnt = Column(BigInteger, default=0) # 映射为 like_cnt
|
||||
share_cnt = Column(BigInteger, default=0)
|
||||
comment_cnt = Column(BigInteger, default=0)
|
||||
play_over_cnt = Column(BigInteger, default=0)
|
||||
play_over_rate = Column(Float, nullable=True)
|
||||
|
||||
# 效果指标
|
||||
# 搜索效果指标
|
||||
back_search_cnt = Column(BigInteger, default=0) # 映射为 return_search_cnt
|
||||
back_search_uv = Column(BigInteger, default=0)
|
||||
after_view_search_cnt = Column(BigInteger, default=0)
|
||||
after_view_search_uv = Column(BigInteger, default=0)
|
||||
after_view_search_rate = Column(Float, nullable=True)
|
||||
|
||||
# A3 指标
|
||||
new_a3_rate = Column(Float, nullable=True)
|
||||
after_view_search_uv = Column(Integer, default=0)
|
||||
return_search_cnt = Column(Integer, default=0)
|
||||
total_new_a3_cnt = Column(BigInteger, default=0)
|
||||
natural_new_a3_cnt = Column(BigInteger, default=0)
|
||||
heated_new_a3_cnt = Column(BigInteger, default=0)
|
||||
|
||||
# 成本指标
|
||||
total_cost = Column(Float, nullable=True)
|
||||
heated_cost = Column(Float, nullable=True)
|
||||
star_task_cost = Column(Float, nullable=True)
|
||||
search_cost = Column(Float, nullable=True)
|
||||
ad_hot_roi = Column(Float, nullable=True)
|
||||
estimated_video_cost = Column(Float, default=0)
|
||||
price_under_20s = Column(BigInteger, nullable=True)
|
||||
price_20_60s = Column(BigInteger, nullable=True)
|
||||
price_over_60s = Column(BigInteger, nullable=True)
|
||||
|
||||
# 商业信息
|
||||
industry_id = Column(String, nullable=True)
|
||||
industry_name = Column(String, nullable=True)
|
||||
brand_id = Column(String, nullable=True)
|
||||
estimated_video_cost = Column(Float, default=0)
|
||||
order_id = Column(String, nullable=True)
|
||||
|
||||
# 索引定义
|
||||
__table_args__ = (
|
||||
Index("idx_star_id", "star_id"),
|
||||
Index("idx_star_unique_id", "star_unique_id"),
|
||||
Index("idx_star_nickname", "star_nickname"),
|
||||
)
|
||||
# JSON 字段
|
||||
content_type = Column(JSONB, nullable=True)
|
||||
industry_tags = Column(JSONB, nullable=True)
|
||||
ad_hot_type = Column(JSONB, nullable=True)
|
||||
trend = Column(JSONB, nullable=True)
|
||||
trend_daily = Column(JSONB, nullable=True)
|
||||
trend_total = Column(JSONB, nullable=True)
|
||||
component_metric_list = Column(JSONB, nullable=True)
|
||||
key_word_after_search_infos = Column(JSONB, nullable=True)
|
||||
index_map = Column(JSONB, nullable=True)
|
||||
search_keywords = Column(JSONB, nullable=True)
|
||||
keywords = Column(JSONB, nullable=True)
|
||||
|
||||
# 时间戳
|
||||
created_at = Column(DateTime, nullable=True)
|
||||
updated_at = Column(DateTime, nullable=True)
|
||||
|
||||
def __repr__(self):
|
||||
return f"<KolVideo(item_id={self.item_id}, title={self.title})>"
|
||||
|
||||
# 兼容属性 - 映射旧字段名到新字段名
|
||||
@property
|
||||
def viral_type(self):
|
||||
return self.hot_type
|
||||
|
||||
@property
|
||||
def total_interact(self):
|
||||
return self.total_interaction_cnt
|
||||
|
||||
@property
|
||||
def like_cnt(self):
|
||||
return self.digg_cnt
|
||||
|
||||
@property
|
||||
def return_search_cnt(self):
|
||||
return self.back_search_cnt
|
||||
|
||||
@property
|
||||
def publish_time(self):
|
||||
return self.create_date
|
||||
|
||||
Reference in New Issue
Block a user