66 lines
3.3 KiB
Python
66 lines
3.3 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(timezone=True), nullable=True)
|
|
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), 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(timezone=True), 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(timezone=True), server_default=func.now())
|
|
|
|
|