models.py 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  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(512))
  9. # SSO 相关字段
  10. sso_sub = db.Column(db.String(256), unique=True, nullable=True)
  11. real_name = db.Column(db.String(100), nullable=True)
  12. roles = db.Column(db.Text, nullable=True) # JSON 字符串,如 ["super_admin", "sam_sys_admin"]
  13. email = db.Column(db.String(120), nullable=True)
  14. phone = db.Column(db.String(30), nullable=True)
  15. avatar_url = db.Column(db.String(500), nullable=True)
  16. def set_password(self, password):
  17. self.password_hash = generate_password_hash(password)
  18. def check_password(self, password):
  19. return check_password_hash(self.password_hash, password)
  20. @login_manager.user_loader
  21. def load_user(id):
  22. return User.query.get(int(id))
  23. class SpiderSource(db.Model):
  24. id = db.Column(db.Integer, primary_key=True)
  25. name = db.Column(db.String(100), nullable=False, unique=True)
  26. code_identifier = db.Column(db.String(100), nullable=False, unique=True) # e.g. 'baidusearch' or 'generic_custom'
  27. description = db.Column(db.Text)
  28. status = db.Column(db.String(20), default='active') # active, disabled
  29. created_at = db.Column(db.DateTime, default=datetime.utcnow)
  30. # Generic Spider Configuration
  31. type = db.Column(db.String(20), default='script') # 'script', 'generic'
  32. url = db.Column(db.String(500)) # Base URL for generic spider
  33. method = db.Column(db.String(10), default='GET')
  34. headers = db.Column(db.Text) # JSON string for headers
  35. params = db.Column(db.Text) # JSON string for default params
  36. search_param_key = db.Column(db.String(50), default='q') # The query parameter key for keyword
  37. selectors = db.Column(db.Text) # JSON string for parsing rules: list, title, link, abstract, source, cover
  38. # Pagination Configuration
  39. has_pagination = db.Column(db.Boolean, default=False)
  40. pagination_param = db.Column(db.String(50)) # e.g. 'pn'
  41. pagination_step = db.Column(db.Integer, default=10) # e.g. 10
  42. pagination_start = db.Column(db.Integer, default=0) # e.g. 0
  43. tasks = db.relationship('SpiderTask', backref='spider_source', lazy='dynamic')
  44. class SpiderTask(db.Model):
  45. __tablename__ = 'collection_task'
  46. id = db.Column(db.Integer, primary_key=True)
  47. keyword = db.Column(db.String(100), nullable=False)
  48. spider_source_id = db.Column(db.Integer, db.ForeignKey('spider_source.id'), nullable=False)
  49. pages = db.Column(db.Integer, default=1) # Number of pages to crawl
  50. status = db.Column(db.String(20), default='pending') # pending, running, completed, failed
  51. created_at = db.Column(db.DateTime, default=datetime.utcnow)
  52. finished_at = db.Column(db.DateTime)
  53. results = db.relationship('SpiderResult', backref='task', lazy='dynamic')
  54. class SpiderResult(db.Model):
  55. id = db.Column(db.Integer, primary_key=True)
  56. task_id = db.Column(db.Integer, db.ForeignKey('collection_task.id'))
  57. title = db.Column(db.String(500))
  58. abstract = db.Column(db.Text)
  59. source = db.Column(db.String(200))
  60. cover = db.Column(db.String(500))
  61. link = db.Column(db.Text)
  62. published_at = db.Column(db.String(50)) # Date extracted from source
  63. has_deep_collection = db.Column(db.Boolean, default=False)
  64. created_at = db.Column(db.DateTime, default=datetime.utcnow)
  65. class DeepCollection(db.Model):
  66. id = db.Column(db.Integer, primary_key=True)
  67. title = db.Column(db.String(500)) # Title from spider result
  68. url = db.Column(db.String(500), nullable=False, unique=True)
  69. content = db.Column(db.Text) # Extracted content
  70. summary = db.Column(db.Text) # AI Summary (optional)
  71. status = db.Column(db.String(20), default='pending') # pending, running, completed, failed
  72. progress = db.Column(db.Integer, default=0)
  73. progress_msg = db.Column(db.String(200), default='')
  74. error_msg = db.Column(db.Text)
  75. created_at = db.Column(db.DateTime, default=datetime.utcnow)
  76. updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
  77. class AIModel(db.Model):
  78. id = db.Column(db.Integer, primary_key=True)
  79. name = db.Column(db.String(100), nullable=False) # e.g. "SiliconFlow Qwen"
  80. provider = db.Column(db.String(50), default='openai') # e.g. openai, siliconflow, etc.
  81. api_base = db.Column(db.String(500), nullable=False) # URL
  82. api_key = db.Column(db.String(500), nullable=False)
  83. model_name = db.Column(db.String(200), nullable=False) # e.g. "Qwen/Qwen3-Next-80B-A3B-Instruct"
  84. system_prompt = db.Column(db.Text)
  85. is_active = db.Column(db.Boolean, default=True)
  86. is_default = db.Column(db.Boolean, default=False)
  87. total_tokens = db.Column(db.BigInteger, default=0)
  88. created_at = db.Column(db.DateTime, default=datetime.utcnow)
  89. updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
  90. logs = db.relationship('TokenUsageLog', backref='model', lazy='dynamic')
  91. class TokenUsageLog(db.Model):
  92. id = db.Column(db.Integer, primary_key=True)
  93. model_id = db.Column(db.Integer, db.ForeignKey('ai_model.id'))
  94. prompt_tokens = db.Column(db.Integer, default=0)
  95. completion_tokens = db.Column(db.Integer, default=0)
  96. total_tokens = db.Column(db.Integer, default=0)
  97. request_type = db.Column(db.String(50), default='test') # test, deep_collect
  98. created_at = db.Column(db.DateTime, default=datetime.utcnow)
  99. class AIConversation(db.Model):
  100. id = db.Column(db.Integer, primary_key=True)
  101. title = db.Column(db.String(200), default='New Chat')
  102. user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
  103. created_at = db.Column(db.DateTime, default=datetime.utcnow)
  104. updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
  105. messages = db.relationship('AIMessage', backref='conversation', lazy='dynamic', cascade='all, delete-orphan')
  106. class AIMessage(db.Model):
  107. id = db.Column(db.Integer, primary_key=True)
  108. conversation_id = db.Column(db.Integer, db.ForeignKey('ai_conversation.id'), nullable=False)
  109. role = db.Column(db.String(20), nullable=False) # user, assistant, system
  110. content = db.Column(db.Text)
  111. meta_data = db.Column(db.Text) # JSON string for charts, tool calls, etc.
  112. created_at = db.Column(db.DateTime, default=datetime.utcnow)
  113. CollectionTask = SpiderTask
  114. class KnowledgeImportTask(db.Model):
  115. """样本中心批量入库任务本地记录。"""
  116. __tablename__ = 'knowledge_import_task'
  117. id = db.Column(db.Integer, primary_key=True)
  118. task_no = db.Column(db.String(64), unique=True, nullable=False, index=True)
  119. sample_task_id = db.Column(db.String(64), nullable=True, index=True)
  120. kb_id = db.Column(db.String(64), nullable=False, index=True)
  121. kb_name = db.Column(db.String(200), nullable=True)
  122. callback_url = db.Column(db.String(500), nullable=True)
  123. status = db.Column(db.String(20), default='pending', index=True) # pending/processing/success/failed
  124. status_detail = db.Column(db.Text, nullable=True) # JSON
  125. progress = db.Column(db.Text, nullable=True) # JSON: {total, processed, succeeded, failed}
  126. poll_count = db.Column(db.Integer, default=0)
  127. last_poll_at = db.Column(db.DateTime, nullable=True)
  128. next_poll_at = db.Column(db.DateTime, nullable=True, index=True)
  129. error_message = db.Column(db.Text, nullable=True)
  130. created_by = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=True)
  131. created_at = db.Column(db.DateTime, default=datetime.utcnow)
  132. updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)