""" 新闻文章数据库模型 """ from datetime import datetime from sqlalchemy import Column, Integer, String, Text, DateTime, JSON, Boolean, Float from sqlalchemy.orm import relationship from app.models.database import Base class NewsArticle(Base): """新闻文章表""" __tablename__ = "news_articles" id = Column(Integer, primary_key=True, index=True) # 新闻基本信息 title = Column(String(500), nullable=False) content = Column(Text, nullable=True) # 完整内容或摘要 content_hash = Column(String(64), nullable=False, index=True) # 内容哈希,用于去重 url = Column(String(1000), nullable=False, unique=True) # 原文链接 source = Column(String(100), nullable=False, index=True) # 来源网站 author = Column(String(200), nullable=True) # 作者 # 新闻分类 category = Column(String(50), nullable=False, index=True) # 'crypto', 'stock', 'forex', 'commodity' tags = Column(JSON, nullable=True) # 标签列表 # 时间信息 published_at = Column(DateTime, nullable=True, index=True) # 发布时间 crawled_at = Column(DateTime, default=datetime.utcnow, index=True) # 爬取时间 # LLM 分析结果 llm_analyzed = Column(Boolean, default=False, index=True) # 是否已分析 market_impact = Column(String(20), nullable=True, index=True) # 'high', 'medium', 'low' impact_type = Column(String(50), nullable=True) # 'bullish', 'bearish', 'neutral' relevant_symbols = Column(JSON, nullable=True) # 相关的币种/股票代码 # LLM 分析详情 sentiment = Column(String(20), nullable=True) # 'positive', 'negative', 'neutral' summary = Column(Text, nullable=True) # LLM 生成的摘要 key_points = Column(JSON, nullable=True) # 关键点列表 trading_advice = Column(Text, nullable=True) # 交易建议 # 优先级队列 priority = Column(Float, default=0.0, index=True) # 优先级分数 priority_reason = Column(Text, nullable=True) # 优先级原因 # 通知状态 notified = Column(Boolean, default=False, index=True) # 是否已发送通知 notification_sent_at = Column(DateTime, nullable=True) notification_channel = Column(String(50), nullable=True) # 'feishu', 'telegram', etc. # 质量控制 quality_score = Column(Float, nullable=True) # 质量分数 0-1 duplicate_of = Column(Integer, nullable=True) # 如果是重复,指向原始文章ID # 状态 is_active = Column(Boolean, default=True, index=True) # 是否有效 # 时间戳 created_at = Column(DateTime, default=datetime.utcnow, index=True) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) def __repr__(self): return f"" def to_dict(self): """转换为字典""" return { 'id': self.id, 'title': self.title, 'content': self.content, 'url': self.url, 'source': self.source, 'author': self.author, 'category': self.category, 'tags': self.tags, 'published_at': self.published_at.isoformat() if self.published_at else None, 'crawled_at': self.crawled_at.isoformat() if self.crawled_at else None, 'llm_analyzed': self.llm_analyzed, 'market_impact': self.market_impact, 'impact_type': self.impact_type, 'relevant_symbols': self.relevant_symbols, 'sentiment': self.sentiment, 'summary': self.summary, 'key_points': self.key_points, 'trading_advice': self.trading_advice, 'priority': self.priority, 'priority_reason': self.priority_reason, 'notified': self.notified, 'notification_sent_at': self.notification_sent_at.isoformat() if self.notification_sent_at else None, 'notification_channel': self.notification_channel, 'quality_score': self.quality_score, 'duplicate_of': self.duplicate_of, 'is_active': self.is_active, 'created_at': self.created_at.isoformat() if self.created_at else None, 'updated_at': self.updated_at.isoformat() if self.updated_at else None, }