geo/backend/app/models/analytics.py

64 lines
3.2 KiB
Python

"""监测优化数据模型"""
from sqlalchemy import Column, String, Integer, Float, Boolean, DateTime, ForeignKey, Text, func
from sqlalchemy.orm import Mapped, mapped_column, relationship
from app.database import Base
import uuid
from datetime import datetime
class PublishRecord(Base):
__tablename__ = "publish_records"
id: Mapped[str] = mapped_column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
organization_id: Mapped[str] = mapped_column(String(36), index=True)
content_title: Mapped[str] = mapped_column(String(200))
content_id: Mapped[str | None] = mapped_column(String(36), nullable=True) # 关联内容生产的ID
platform: Mapped[str] = mapped_column(String(50)) # wechat/zhihu/xiaohongshu...
published_url: Mapped[str | None] = mapped_column(String(500), nullable=True)
status: Mapped[str] = mapped_column(String(20), default="draft") # draft/published/archived
published_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)
created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now())
metrics: Mapped[list["ContentMetrics"]] = relationship(back_populates="publish_record")
class ContentMetrics(Base):
__tablename__ = "content_metrics"
id: Mapped[str] = mapped_column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
publish_record_id: Mapped[str] = mapped_column(String(36), ForeignKey("publish_records.id"))
recorded_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now())
# 互动指标
views: Mapped[int] = mapped_column(Integer, default=0)
likes: Mapped[int] = mapped_column(Integer, default=0)
comments: Mapped[int] = mapped_column(Integer, default=0)
shares: Mapped[int] = mapped_column(Integer, default=0)
bookmarks: Mapped[int] = mapped_column(Integer, default=0)
# GEO核心指标
ai_citation_count: Mapped[int] = mapped_column(Integer, default=0) # 被AI模型引用次数
search_impressions: Mapped[int] = mapped_column(Integer, default=0) # 搜索曝光
search_clicks: Mapped[int] = mapped_column(Integer, default=0) # 搜索点击
# 阅读指标
avg_read_duration: Mapped[float] = mapped_column(Float, default=0.0) # 平均阅读时长(秒)
read_completion_rate: Mapped[float] = mapped_column(Float, default=0.0) # 完读率
publish_record: Mapped["PublishRecord"] = relationship(back_populates="metrics")
class OptimizationInsight(Base):
__tablename__ = "optimization_insights"
id: Mapped[str] = mapped_column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
organization_id: Mapped[str] = mapped_column(String(36), index=True)
content_id: Mapped[str | None] = mapped_column(String(36), nullable=True)
insight_type: Mapped[str] = mapped_column(String(30)) # trend/anomaly/opportunity/suggestion
title: Mapped[str] = mapped_column(String(200))
description: Mapped[str] = mapped_column(Text)
recommendation: Mapped[str] = mapped_column(Text)
severity: Mapped[str] = mapped_column(String(20), default="info") # info/warning/success
applied: Mapped[bool] = mapped_column(Boolean, default=False)
created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now())