| from sqlalchemy import Column, String, Float, Integer, DateTime, Text, Boolean, JSON, ForeignKey, Index |
| from sqlalchemy.sql import func |
| from sqlalchemy.orm import relationship |
| import uuid |
| from datetime import datetime |
| from typing import Optional, Dict, Any |
| from enum import Enum |
|
|
| from app.core.db_selector import Base |
|
|
|
|
| class UserRole(str, Enum): |
| """用户角色枚举""" |
| ADMIN = "admin" |
| USER = "user" |
| VIP = "vip" |
| ANALYST = "analyst" |
| GUEST = "guest" |
|
|
|
|
| class UserStatus(str, Enum): |
| """用户状态枚举""" |
| ACTIVE = "active" |
| INACTIVE = "inactive" |
| SUSPENDED = "suspended" |
| BANNED = "banned" |
|
|
|
|
| class SubscriptionType(str, Enum): |
| """订阅类型枚举""" |
| FREE = "free" |
| BASIC = "basic" |
| PRO = "pro" |
| ENTERPRISE = "enterprise" |
|
|
|
|
| class User(Base): |
| """用户表""" |
| __tablename__ = "users" |
|
|
| id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4())) |
| username = Column(String(50), unique=True, nullable=False, comment="用户名") |
| email = Column(String(100), unique=True, nullable=False, comment="邮箱") |
| phone = Column(String(20), comment="手机号") |
|
|
| |
| hashed_password = Column(String(255), nullable=False, comment="密码哈希") |
| salt = Column(String(50), comment="密码盐值") |
|
|
| |
| full_name = Column(String(100), comment="真实姓名") |
| nickname = Column(String(50), comment="昵称") |
| avatar = Column(String(255), comment="头像URL") |
| bio = Column(Text, comment="个人简介") |
|
|
| |
| role = Column(String(20), default=UserRole.USER, comment="用户角色") |
| status = Column(String(20), default=UserStatus.ACTIVE, comment="账户状态") |
| is_verified = Column(Boolean, default=False, comment="是否已验证") |
|
|
| |
| subscription_type = Column( |
| String(20), |
| default=SubscriptionType.FREE, |
| comment="订阅类型") |
| subscription_start = Column(DateTime, comment="订阅开始时间") |
| subscription_end = Column(DateTime, comment="订阅结束时间") |
|
|
| |
| login_count = Column(Integer, default=0, comment="登录次数") |
| last_login = Column(DateTime, comment="最后登录时间") |
| last_login_ip = Column(String(50), comment="最后登录IP") |
|
|
| |
| strategy_count = Column(Integer, default=0, comment="策略数量") |
| backtest_count = Column(Integer, default=0, comment="回测次数") |
| portfolio_count = Column(Integer, default=0, comment="投资组合数量") |
|
|
| |
| preferences = Column(JSON, comment="用户偏好") |
| notification_settings = Column(JSON, comment="通知设置") |
|
|
| |
| risk_tolerance = Column(String(20), comment="风险承受能力") |
| investment_experience = Column(String(20), comment="投资经验") |
|
|
| |
| created_at = Column(DateTime, default=func.now(), comment="创建时间") |
| updated_at = Column( |
| DateTime, |
| default=func.now(), |
| onupdate=func.now(), |
| comment="更新时间") |
|
|
| |
| __table_args__ = ( |
| Index('idx_user_username', 'username'), |
| Index('idx_user_email', 'email'), |
| Index('idx_user_role', 'role'), |
| Index('idx_user_status', 'status'), |
| Index('idx_user_subscription', 'subscription_type'), |
| ) |
|
|
| def __repr__(self): |
| return f"<User(username='{self.username}', email='{self.email}', role='{self.role}')>" |
|
|
|
|
| class UserStrategy(Base): |
| """用户策略关联表""" |
| __tablename__ = "user_strategies" |
|
|
| id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4())) |
| user_id = Column(String(36), ForeignKey('users.id'), nullable=False) |
| strategy_id = Column(String(36), ForeignKey('strategies.id'), nullable=False) |
|
|
| |
| permission = Column( |
| String(20), |
| nullable=False, |
| comment="权限类型") |
| is_favorite = Column(Boolean, default=False, comment="是否收藏") |
|
|
| |
| view_count = Column(Integer, default=0, comment="查看次数") |
| run_count = Column(Integer, default=0, comment="运行次数") |
| last_viewed = Column(DateTime, comment="最后查看时间") |
| last_run = Column(DateTime, comment="最后运行时间") |
|
|
| |
| personal_config = Column(JSON, comment="个人配置") |
| notes = Column(Text, comment="个人备注") |
|
|
| |
| created_at = Column(DateTime, default=func.now(), comment="创建时间") |
| updated_at = Column( |
| DateTime, |
| default=func.now(), |
| onupdate=func.now(), |
| comment="更新时间") |
|
|
| |
| user = relationship("User", backref="user_strategies") |
| strategy = relationship("Strategy", backref="user_strategies") |
|
|
| |
| __table_args__ = ( |
| Index('idx_user_strategy_user', 'user_id'), |
| Index('idx_user_strategy_strategy', 'strategy_id'), |
| Index('idx_user_strategy_permission', 'permission'), |
| Index('idx_user_strategy_favorite', 'is_favorite'), |
| ) |
|
|
| def __repr__(self): |
| return f"<UserStrategy(user_id='{self.user_id}', strategy_id='{self.strategy_id}', permission='{self.permission}')>" |
|
|
|
|
| class UserSession(Base): |
| """用户会话表""" |
| __tablename__ = "user_sessions" |
|
|
| id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4())) |
| user_id = Column(String(36), ForeignKey('users.id'), nullable=False) |
|
|
| |
| session_token = Column(String(255), unique=True, nullable=False, comment="会话令牌") |
| refresh_token = Column(String(255), comment="刷新令牌") |
|
|
| |
| device_type = Column(String(50), comment="设备类型") |
| device_id = Column(String(100), comment="设备ID") |
| user_agent = Column(Text, comment="用户代理") |
| ip_address = Column(String(50), comment="IP地址") |
| location = Column(String(100), comment="地理位置") |
|
|
| |
| login_time = Column(DateTime, default=func.now(), comment="登录时间") |
| last_activity = Column(DateTime, default=func.now(), comment="最后活动时间") |
| expires_at = Column(DateTime, nullable=False, comment="过期时间") |
|
|
| |
| is_active = Column(Boolean, default=True, comment="是否活跃") |
|
|
| |
| user = relationship("User", backref="sessions") |
|
|
| |
| __table_args__ = ( |
| Index('idx_session_user', 'user_id'), |
| Index('idx_session_token', 'session_token'), |
| Index('idx_session_active', 'is_active'), |
| Index('idx_session_expires', 'expires_at'), |
| ) |
|
|
| def __repr__(self): |
| return f"<UserSession(user_id='{self.user_id}', device='{self.device_type}', active={self.is_active})>" |
|
|
|
|
| class UserActivity(Base): |
| """用户活动日志表""" |
| __tablename__ = "user_activities" |
|
|
| id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4())) |
| user_id = Column(String(36), ForeignKey('users.id'), nullable=False) |
|
|
| |
| activity_type = Column(String(50), nullable=False, comment="活动类型") |
| activity_name = Column(String(100), comment="活动名称") |
| description = Column(Text, comment="活动描述") |
|
|
| |
| object_type = Column(String(50), comment="对象类型") |
| object_id = Column(String(36), comment="对象ID") |
|
|
| |
| activity_data = Column(JSON, comment="活动数据") |
|
|
| |
| ip_address = Column(String(50), comment="IP地址") |
| user_agent = Column(Text, comment="用户代理") |
|
|
| |
| created_at = Column(DateTime, default=func.now(), comment="创建时间") |
|
|
| |
| user = relationship("User", backref="activities") |
|
|
| |
| __table_args__ = ( |
| Index('idx_activity_user_type', 'user_id', 'activity_type'), |
| Index('idx_activity_type', 'activity_type'), |
| Index('idx_activity_object', 'object_type', 'object_id'), |
| Index('idx_activity_time', 'created_at'), |
| ) |
|
|
| def __repr__(self): |
| return f"<UserActivity(user_id='{self.user_id}', type='{self.activity_type}', time='{self.created_at}')>" |
|
|
|
|
| class UserNotification(Base): |
| """用户通知表""" |
| __tablename__ = "user_notifications" |
|
|
| id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4())) |
| user_id = Column(String(36), ForeignKey('users.id'), nullable=False) |
|
|
| |
| title = Column(String(200), nullable=False, comment="通知标题") |
| content = Column(Text, comment="通知内容") |
| notification_type = Column(String(50), comment="通知类型") |
|
|
| |
| related_object_type = Column(String(50), comment="相关对象类型") |
| related_object_id = Column(String(36), comment="相关对象ID") |
|
|
| |
| is_read = Column(Boolean, default=False, comment="是否已读") |
| read_at = Column(DateTime, comment="阅读时间") |
|
|
| |
| priority = Column(String(20), default="normal", comment="优先级") |
|
|
| |
| created_at = Column(DateTime, default=func.now(), comment="创建时间") |
|
|
| |
| user = relationship("User", backref="notifications") |
|
|
| |
| __table_args__ = ( |
| Index('idx_notification_user_read', 'user_id', 'is_read'), |
| Index('idx_notification_type', 'notification_type'), |
| Index('idx_notification_priority', 'priority'), |
| Index('idx_notification_time', 'created_at'), |
| ) |
|
|
| def __repr__(self): |
| return f"<UserNotification(user_id='{self.user_id}', title='{self.title}', read={self.is_read})>" |
|
|