models.py 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. from . import db, login_manager
  2. from flask_login import UserMixin
  3. from werkzeug.security import generate_password_hash, check_password_hash
  4. from datetime import datetime
  5. class User(UserMixin, db.Model):
  6. id = db.Column(db.Integer, primary_key=True)
  7. username = db.Column(db.String(64), index=True, unique=True)
  8. password_hash = db.Column(db.String(128))
  9. def set_password(self, password):
  10. self.password_hash = generate_password_hash(password)
  11. def check_password(self, password):
  12. return check_password_hash(self.password_hash, password)
  13. @login_manager.user_loader
  14. def load_user(id):
  15. return User.query.get(int(id))
  16. class SpiderSource(db.Model):
  17. id = db.Column(db.Integer, primary_key=True)
  18. name = db.Column(db.String(100), nullable=False, unique=True)
  19. code_identifier = db.Column(db.String(100), nullable=False, unique=True) # e.g. 'baidusearch' or 'generic_custom'
  20. description = db.Column(db.Text)
  21. status = db.Column(db.String(20), default='active') # active, disabled
  22. created_at = db.Column(db.DateTime, default=datetime.utcnow)
  23. # Generic Spider Configuration
  24. type = db.Column(db.String(20), default='script') # 'script', 'generic'
  25. url = db.Column(db.String(500)) # Base URL for generic spider
  26. method = db.Column(db.String(10), default='GET')
  27. headers = db.Column(db.Text) # JSON string for headers
  28. params = db.Column(db.Text) # JSON string for default params
  29. search_param_key = db.Column(db.String(50), default='q') # The query parameter key for keyword
  30. selectors = db.Column(db.Text) # JSON string for parsing rules: list, title, link, abstract, source, cover
  31. # Pagination Configuration
  32. has_pagination = db.Column(db.Boolean, default=False)
  33. pagination_param = db.Column(db.String(50)) # e.g. 'pn'
  34. pagination_step = db.Column(db.Integer, default=10) # e.g. 10
  35. pagination_start = db.Column(db.Integer, default=0) # e.g. 0
  36. tasks = db.relationship('SpiderTask', backref='spider_source', lazy='dynamic')
  37. class SpiderTask(db.Model):
  38. __tablename__ = 'collection_task'
  39. id = db.Column(db.Integer, primary_key=True)
  40. keyword = db.Column(db.String(100), nullable=False)
  41. spider_source_id = db.Column(db.Integer, db.ForeignKey('spider_source.id'), nullable=False)
  42. pages = db.Column(db.Integer, default=1) # Number of pages to crawl
  43. status = db.Column(db.String(20), default='pending') # pending, running, completed, failed
  44. created_at = db.Column(db.DateTime, default=datetime.utcnow)
  45. finished_at = db.Column(db.DateTime)
  46. results = db.relationship('SpiderResult', backref='task', lazy='dynamic')
  47. class SpiderResult(db.Model):
  48. id = db.Column(db.Integer, primary_key=True)
  49. task_id = db.Column(db.Integer, db.ForeignKey('collection_task.id'))
  50. title = db.Column(db.String(500))
  51. abstract = db.Column(db.Text)
  52. source = db.Column(db.String(200))
  53. cover = db.Column(db.String(500))
  54. link = db.Column(db.String(500))
  55. published_at = db.Column(db.String(50)) # Date extracted from source
  56. has_deep_collection = db.Column(db.Boolean, default=False)
  57. created_at = db.Column(db.DateTime, default=datetime.utcnow)
  58. class DeepCollection(db.Model):
  59. id = db.Column(db.Integer, primary_key=True)
  60. title = db.Column(db.String(500)) # Title from spider result
  61. url = db.Column(db.String(500), nullable=False, unique=True)
  62. content = db.Column(db.Text) # Extracted content
  63. summary = db.Column(db.Text) # AI Summary (optional)
  64. status = db.Column(db.String(20), default='pending') # pending, running, completed, failed
  65. progress = db.Column(db.Integer, default=0)
  66. progress_msg = db.Column(db.String(200), default='')
  67. error_msg = db.Column(db.Text)
  68. created_at = db.Column(db.DateTime, default=datetime.utcnow)
  69. updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
  70. class AIModel(db.Model):
  71. id = db.Column(db.Integer, primary_key=True)
  72. name = db.Column(db.String(100), nullable=False) # e.g. "SiliconFlow Qwen"
  73. provider = db.Column(db.String(50), default='openai') # e.g. openai, siliconflow, etc.
  74. api_base = db.Column(db.String(500), nullable=False) # URL
  75. api_key = db.Column(db.String(500), nullable=False)
  76. model_name = db.Column(db.String(200), nullable=False) # e.g. "Qwen/Qwen3-Next-80B-A3B-Instruct"
  77. system_prompt = db.Column(db.Text)
  78. is_active = db.Column(db.Boolean, default=True)
  79. total_tokens = db.Column(db.BigInteger, default=0)
  80. created_at = db.Column(db.DateTime, default=datetime.utcnow)
  81. updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
  82. logs = db.relationship('TokenUsageLog', backref='model', lazy='dynamic')
  83. class TokenUsageLog(db.Model):
  84. id = db.Column(db.Integer, primary_key=True)
  85. model_id = db.Column(db.Integer, db.ForeignKey('ai_model.id'))
  86. prompt_tokens = db.Column(db.Integer, default=0)
  87. completion_tokens = db.Column(db.Integer, default=0)
  88. total_tokens = db.Column(db.Integer, default=0)
  89. request_type = db.Column(db.String(50), default='test') # test, deep_collect
  90. created_at = db.Column(db.DateTime, default=datetime.utcnow)
  91. class AIConversation(db.Model):
  92. id = db.Column(db.Integer, primary_key=True)
  93. title = db.Column(db.String(200), default='New Chat')
  94. user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
  95. created_at = db.Column(db.DateTime, default=datetime.utcnow)
  96. updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
  97. messages = db.relationship('AIMessage', backref='conversation', lazy='dynamic', cascade='all, delete-orphan')
  98. class AIMessage(db.Model):
  99. id = db.Column(db.Integer, primary_key=True)
  100. conversation_id = db.Column(db.Integer, db.ForeignKey('ai_conversation.id'), nullable=False)
  101. role = db.Column(db.String(20), nullable=False) # user, assistant, system
  102. content = db.Column(db.Text)
  103. meta_data = db.Column(db.Text) # JSON string for charts, tool calls, etc.
  104. created_at = db.Column(db.DateTime, default=datetime.utcnow)
  105. CollectionTask = SpiderTask