feat: GEO/SEO structured data + search ranking tracker
This commit is contained in:
@@ -282,6 +282,8 @@ class Article(Base):
|
||||
topic_id = Column(String, ForeignKey("topics.id"), nullable=False)
|
||||
platform = Column(String, nullable=False)
|
||||
file_path = Column(String, nullable=False)
|
||||
title = Column(String, nullable=True)
|
||||
content = Column(Text, nullable=True)
|
||||
status = Column(String, default="draft")
|
||||
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
||||
compliance_score = Column(Integer)
|
||||
@@ -410,6 +412,7 @@ class MediaAsset(Base):
|
||||
topic_ids = Column(JSON, default=list)
|
||||
usage_count = Column(Integer, default=0)
|
||||
uploaded_by = Column(String, nullable=True)
|
||||
org_id = Column(String, default="default", nullable=True)
|
||||
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
||||
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
|
||||
|
||||
@@ -853,4 +856,36 @@ class CollectorSource(Base):
|
||||
"sort_order": self.sort_order,
|
||||
"created_at": self.created_at.isoformat() if self.created_at else None,
|
||||
"updated_at": self.updated_at.isoformat() if self.updated_at else None,
|
||||
}
|
||||
|
||||
|
||||
class SearchRanking(Base):
|
||||
"""搜索排名追踪"""
|
||||
__tablename__ = "search_rankings"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True, autoincrement=True)
|
||||
article_id = Column(String, ForeignKey("articles.id"), nullable=True)
|
||||
topic_id = Column(String, ForeignKey("topics.id"), nullable=True)
|
||||
keyword = Column(String, nullable=False, index=True)
|
||||
platform = Column(String, nullable=True)
|
||||
search_engine = Column(String, default="bing") # bing / baidu / google
|
||||
position = Column(Integer, nullable=True) # 搜索排名位置(null = 未上榜)
|
||||
url_found = Column(String, nullable=True) # 被找到的具体 URL
|
||||
ai_cited = Column(Boolean, default=False) # 是否被 AI 搜索引用
|
||||
ai_source = Column(String, nullable=True) # AI 搜索来源名称
|
||||
checked_at = Column(DateTime(timezone=True), server_default=func.now())
|
||||
|
||||
def to_dict(self):
|
||||
return {
|
||||
"id": self.id,
|
||||
"article_id": self.article_id,
|
||||
"topic_id": self.topic_id,
|
||||
"keyword": self.keyword,
|
||||
"platform": self.platform,
|
||||
"search_engine": self.search_engine,
|
||||
"position": self.position,
|
||||
"url_found": self.url_found,
|
||||
"ai_cited": self.ai_cited,
|
||||
"ai_source": self.ai_source,
|
||||
"checked_at": self.checked_at.isoformat() if self.checked_at else None,
|
||||
}
|
||||
Reference in New Issue
Block a user