from sqlalchemy import Column, Integer, String, Boolean, DateTime, Text, ForeignKey, Enum from sqlalchemy.orm import relationship from sqlalchemy.sql import func from app.database import Base import enum class MembershipType(str, enum.Enum): FREE = "free" PRO = "pro" class AccountStatus(str, enum.Enum): ACTIVE = "active" # 可用 IN_USE = "in_use" # 使用中 DISABLED = "disabled" # 禁用 EXPIRED = "expired" # 过期 class KeyStatus(str, enum.Enum): ACTIVE = "active" DISABLED = "disabled" EXPIRED = "expired" class CursorAccount(Base): """Cursor 账号池""" __tablename__ = "cursor_accounts" id = Column(Integer, primary_key=True, autoincrement=True) email = Column(String(255), unique=True, nullable=False, comment="邮箱") access_token = Column(Text, nullable=False, comment="访问令牌") refresh_token = Column(Text, nullable=True, comment="刷新令牌") workos_session_token = Column(Text, nullable=True, comment="WorkOS会话令牌") membership_type = Column(Enum(MembershipType), default=MembershipType.PRO, comment="会员类型") status = Column(Enum(AccountStatus), default=AccountStatus.ACTIVE, comment="状态") # 使用统计 usage_count = Column(Integer, default=0, comment="使用次数") last_used_at = Column(DateTime, nullable=True, comment="最后使用时间") current_key_id = Column(Integer, ForeignKey("activation_keys.id"), nullable=True, comment="当前使用的激活码") # 备注 remark = Column(String(500), nullable=True, comment="备注") created_at = Column(DateTime, server_default=func.now()) updated_at = Column(DateTime, server_default=func.now(), onupdate=func.now()) class ActivationKey(Base): """激活码""" __tablename__ = "activation_keys" id = Column(Integer, primary_key=True, autoincrement=True) key = Column(String(64), unique=True, nullable=False, index=True, comment="激活码") status = Column(Enum(KeyStatus), default=KeyStatus.ACTIVE, comment="状态") # 套餐类型 membership_type = Column(Enum(MembershipType), default=MembershipType.PRO, comment="套餐类型: free=无限auto, pro=高级模型") # 额度系统 quota = Column(Integer, default=500, comment="总额度") quota_used = Column(Integer, default=0, comment="已用额度") # 有效期设置 valid_days = Column(Integer, default=30, comment="有效天数(0表示永久)") first_activated_at = Column(DateTime, nullable=True, comment="首次激活时间") expire_at = Column(DateTime, nullable=True, comment="过期时间(首次激活时计算)") # 设备限制 max_devices = Column(Integer, default=2, comment="最大设备数") # 换号频率限制(已废弃,现由全局设置控制) switch_interval_minutes = Column(Integer, default=30, comment="[已废弃]换号间隔(分钟)") switch_limit_per_interval = Column(Integer, default=2, comment="[已废弃]间隔内最大换号次数") # 当前绑定的账号 current_account_id = Column(Integer, ForeignKey("cursor_accounts.id"), nullable=True) current_account = relationship("CursorAccount", foreign_keys=[current_account_id]) # 统计 switch_count = Column(Integer, default=0, comment="总换号次数") last_switch_at = Column(DateTime, nullable=True, comment="最后换号时间") # 备注 remark = Column(String(500), nullable=True, comment="备注") created_at = Column(DateTime, server_default=func.now()) updated_at = Column(DateTime, server_default=func.now(), onupdate=func.now()) class KeyDevice(Base): """激活码绑定的设备""" __tablename__ = "key_devices" id = Column(Integer, primary_key=True, autoincrement=True) key_id = Column(Integer, ForeignKey("activation_keys.id"), nullable=False) device_id = Column(String(255), nullable=False, comment="设备标识") device_name = Column(String(255), nullable=True, comment="设备名称") last_active_at = Column(DateTime, nullable=True, comment="最后活跃时间") created_at = Column(DateTime, server_default=func.now()) key = relationship("ActivationKey") class GlobalSettings(Base): """全局设置""" __tablename__ = "global_settings" id = Column(Integer, primary_key=True, autoincrement=True) key = Column(String(100), unique=True, nullable=False, comment="设置键") value = Column(String(500), nullable=False, comment="设置值") description = Column(String(500), nullable=True, comment="描述") updated_at = Column(DateTime, server_default=func.now(), onupdate=func.now()) class UsageLog(Base): """使用日志""" __tablename__ = "usage_logs" id = Column(Integer, primary_key=True, autoincrement=True) key_id = Column(Integer, ForeignKey("activation_keys.id"), nullable=False) account_id = Column(Integer, ForeignKey("cursor_accounts.id"), nullable=True) action = Column(String(50), nullable=False, comment="操作类型: verify/switch/seamless") ip_address = Column(String(50), nullable=True) user_agent = Column(String(500), nullable=True) success = Column(Boolean, default=True) message = Column(String(500), nullable=True) created_at = Column(DateTime, server_default=func.now()) key = relationship("ActivationKey") account = relationship("CursorAccount")