feat(accounts): 添加CPA上传功能及相关字段

- 在Account模型和响应中添加cpa_uploaded和cpa_uploaded_at字段
- 新增批量导出和CPA上传API端点
- 实现数据库迁移功能自动添加缺失列
- 扩展账号管理API支持CPA相关操作
This commit is contained in:
cnlimiter
2026-03-15 00:42:48 +08:00
parent 9af9dc77a8
commit 59b8ced3ba
3 changed files with 152 additions and 28 deletions

View File

@@ -50,6 +50,8 @@ class Account(Base):
expires_at = Column(DateTime) # Token 过期时间
status = Column(String(20), default='active') # 'active', 'expired', 'banned', 'failed'
extra_data = Column(JSONEncodedDict) # 额外信息存储
cpa_uploaded = Column(Boolean, default=False) # 是否已上传到 CPA
cpa_uploaded_at = Column(DateTime) # 上传时间
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
@@ -68,6 +70,8 @@ class Account(Base):
'expires_at': self.expires_at.isoformat() if self.expires_at else None,
'status': self.status,
'proxy_used': self.proxy_used,
'cpa_uploaded': self.cpa_uploaded,
'cpa_uploaded_at': self.cpa_uploaded_at.isoformat() if self.cpa_uploaded_at else None,
'created_at': self.created_at.isoformat() if self.created_at else None,
'updated_at': self.updated_at.isoformat() if self.updated_at else None
}

View File

@@ -4,13 +4,16 @@
from contextlib import contextmanager
from typing import Generator
from sqlalchemy import create_engine
from sqlalchemy import create_engine, text
from sqlalchemy.orm import sessionmaker, Session
from sqlalchemy.exc import SQLAlchemyError
import os
import logging
from .models import Base
logger = logging.getLogger(__name__)
class DatabaseSessionManager:
"""数据库会话管理器"""
@@ -77,6 +80,40 @@ class DatabaseSessionManager:
"""删除所有表(谨慎使用)"""
Base.metadata.drop_all(bind=self.engine)
def migrate_tables(self):
"""
数据库迁移 - 添加缺失的列
用于在不删除数据的情况下更新表结构
"""
if not self.database_url.startswith("sqlite"):
logger.info("非 SQLite 数据库,跳过自动迁移")
return
# 需要检查和添加的新列
migrations = [
# (表名, 列名, 列类型)
("accounts", "cpa_uploaded", "BOOLEAN DEFAULT 0"),
("accounts", "cpa_uploaded_at", "DATETIME"),
]
with self.engine.connect() as conn:
for table_name, column_name, column_type in migrations:
try:
# 检查列是否存在
result = conn.execute(text(
f"SELECT * FROM pragma_table_info('{table_name}') WHERE name='{column_name}'"
))
if result.fetchone() is None:
# 列不存在,添加它
logger.info(f"添加列 {table_name}.{column_name}")
conn.execute(text(
f"ALTER TABLE {table_name} ADD COLUMN {column_name} {column_type}"
))
conn.commit()
logger.info(f"成功添加列 {table_name}.{column_name}")
except Exception as e:
logger.warning(f"迁移列 {table_name}.{column_name} 时出错: {e}")
# 全局数据库会话管理器实例
_db_manager: DatabaseSessionManager = None
@@ -90,6 +127,8 @@ def init_database(database_url: str = None) -> DatabaseSessionManager:
if _db_manager is None:
_db_manager = DatabaseSessionManager(database_url)
_db_manager.create_tables()
# 执行数据库迁移
_db_manager.migrate_tables()
return _db_manager