This commit is contained in:
薇薇安 2026-01-23 20:35:11 +08:00
parent 150eea7a28
commit fad8a1d6fd
5 changed files with 67 additions and 17 deletions

View File

@ -90,9 +90,13 @@ def get_account_id(
) -> int: ) -> int:
import logging import logging
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
# 注意x_account_id 可能是 None需要处理
raw_header_value = x_account_id
aid = int(x_account_id or 1) aid = int(x_account_id or 1)
logger.info(f"get_account_id: X-Account-Id header={x_account_id}, parsed account_id={aid}, user_id={user.get('id')}") logger.info(f"get_account_id: X-Account-Id header={raw_header_value}, parsed account_id={aid}, user_id={user.get('id')}, username={user.get('username')}")
return require_account_access(aid, user) result = require_account_access(aid, user)
logger.info(f"get_account_id: 最终返回 account_id={result}")
return result
def require_system_admin( def require_system_admin(

View File

@ -398,15 +398,25 @@ async def get_realtime_account_data(account_id: int = 1):
# 创建客户端 # 创建客户端
logger.info("步骤3: 创建BinanceClient实例...") logger.info("步骤3: 创建BinanceClient实例...")
client = BinanceClient(
api_key=api_key,
api_secret=api_secret,
testnet=use_testnet
)
logger.info(f" - 使用的 account_id: {account_id}") logger.info(f" - 使用的 account_id: {account_id}")
logger.info(f" - API Key 前4位: {api_key[:4] if api_key and len(api_key) >= 4 else 'N/A'}...") logger.info(f" - API Key 前4位: {api_key[:4] if api_key and len(api_key) >= 4 else 'N/A'}...")
logger.info(f" - API Key 后4位: ...{api_key[-4:] if api_key and len(api_key) >= 4 else 'N/A'}")
logger.info(f" - API Secret 前4位: {api_secret[:4] if api_secret and len(api_secret) >= 4 else 'N/A'}...") logger.info(f" - API Secret 前4位: {api_secret[:4] if api_secret and len(api_secret) >= 4 else 'N/A'}...")
logger.info(f" ✓ 客户端创建成功 (testnet={use_testnet})") logger.info(f" - API Secret 后4位: ...{api_secret[-4:] if api_secret and len(api_secret) >= 4 else 'N/A'}")
logger.info(f" - testnet: {use_testnet}")
# 确保传递了正确的 api_key 和 api_secret避免 BinanceClient 从 config 读取
if not api_key or not api_secret:
error_msg = f"API密钥为空 (account_id={account_id})无法创建BinanceClient"
logger.error(f"{error_msg}")
raise HTTPException(status_code=400, detail=error_msg)
client = BinanceClient(
api_key=api_key, # 明确传递,避免从 config 读取
api_secret=api_secret, # 明确传递,避免从 config 读取
testnet=use_testnet
)
logger.info(f" ✓ 客户端创建成功 (testnet={use_testnet}, account_id={account_id})")
# 连接币安API # 连接币安API
logger.info("步骤4: 连接币安API...") logger.info("步骤4: 连接币安API...")
@ -562,8 +572,8 @@ async def get_realtime_account_data(account_id: int = 1):
} }
logger.info("=" * 60) logger.info("=" * 60)
logger.info("账户数据获取成功!") logger.info(f"账户数据获取成功! (account_id={account_id})")
logger.info(f"最终结果: {result}") logger.info(f"最终结果 - total_balance={result.get('total_balance', 'N/A')}, available_balance={result.get('available_balance', 'N/A')}, open_positions={result.get('open_positions', 'N/A')}")
logger.info("=" * 60) logger.info("=" * 60)
return result return result
@ -596,6 +606,7 @@ async def get_realtime_positions(account_id: int = Depends(get_account_id)):
logger.info(f"get_realtime_positions: 请求的 account_id={account_id}") logger.info(f"get_realtime_positions: 请求的 account_id={account_id}")
api_key, api_secret, use_testnet, status = Account.get_credentials(account_id) api_key, api_secret, use_testnet, status = Account.get_credentials(account_id)
logger.info(f"get_realtime_positions: 获取到的 account_id={account_id}, status={status}, api_key exists={bool(api_key)}") logger.info(f"get_realtime_positions: 获取到的 account_id={account_id}, status={status}, api_key exists={bool(api_key)}")
logger.info(f"get_realtime_positions: API Key 前4位={api_key[:4] if api_key and len(api_key) >= 4 else 'N/A'}, 后4位=...{api_key[-4:] if api_key and len(api_key) >= 4 else 'N/A'}")
logger.info(f"尝试获取实时持仓数据 (testnet={use_testnet}, account_id={account_id})") logger.info(f"尝试获取实时持仓数据 (testnet={use_testnet}, account_id={account_id})")
@ -615,11 +626,13 @@ async def get_realtime_positions(account_id: int = Depends(get_account_id)):
sys.path.insert(0, str(trading_system_path)) sys.path.insert(0, str(trading_system_path))
from binance_client import BinanceClient from binance_client import BinanceClient
# 确保传递了正确的 api_key 和 api_secret避免 BinanceClient 从 config 读取
client = BinanceClient( client = BinanceClient(
api_key=api_key, api_key=api_key, # 明确传递,避免从 config 读取
api_secret=api_secret, api_secret=api_secret, # 明确传递,避免从 config 读取
testnet=use_testnet testnet=use_testnet
) )
logger.info(f"BinanceClient 创建成功 (account_id={account_id})")
logger.info("连接币安API获取持仓...") logger.info("连接币安API获取持仓...")
await client.connect() await client.connect()

View File

@ -45,7 +45,9 @@ async def get_performance_stats(
@router.get("/dashboard") @router.get("/dashboard")
async def get_dashboard_data(account_id: int = Depends(get_account_id)): async def get_dashboard_data(account_id: int = Depends(get_account_id)):
"""获取仪表板数据""" """获取仪表板数据"""
logger.info(f"获取仪表板数据 (account_id={account_id})") logger.info("=" * 60)
logger.info(f"获取仪表板数据 - account_id={account_id}")
logger.info("=" * 60)
try: try:
account_data = None account_data = None
account_error = None account_error = None
@ -53,8 +55,9 @@ async def get_dashboard_data(account_id: int = Depends(get_account_id)):
# 优先尝试获取实时账户数据 # 优先尝试获取实时账户数据
try: try:
from api.routes.account import get_realtime_account_data from api.routes.account import get_realtime_account_data
logger.info(f"调用 get_realtime_account_data(account_id={account_id})")
account_data = await get_realtime_account_data(account_id=account_id) account_data = await get_realtime_account_data(account_id=account_id)
logger.info("成功获取实时账户数据") logger.info(f"成功获取实时账户数据,返回的 total_balance={account_data.get('total_balance', 'N/A') if account_data else 'N/A'}")
except HTTPException as e: except HTTPException as e:
# HTTPException 需要特殊处理,提取错误信息 # HTTPException 需要特殊处理,提取错误信息
account_error = e.detail account_error = e.detail
@ -98,10 +101,11 @@ async def get_dashboard_data(account_id: int = Depends(get_account_id)):
positions_error = None positions_error = None
try: try:
from api.routes.account import get_realtime_positions from api.routes.account import get_realtime_positions
logger.info(f"调用 get_realtime_positions(account_id={account_id})")
positions = await get_realtime_positions(account_id=account_id) positions = await get_realtime_positions(account_id=account_id)
# 转换为前端需要的格式 # 转换为前端需要的格式
open_trades = positions open_trades = positions
logger.info(f"成功获取实时持仓数据: {len(open_trades)} 个持仓") logger.info(f"成功获取实时持仓数据: {len(open_trades)} 个持仓 (account_id={account_id})")
except HTTPException as e: except HTTPException as e:
positions_error = e.detail positions_error = e.detail
logger.warning(f"获取实时持仓失败 (HTTP {e.status_code}): {positions_error}") logger.warning(f"获取实时持仓失败 (HTTP {e.status_code}): {positions_error}")
@ -257,7 +261,12 @@ async def get_dashboard_data(account_id: int = Depends(get_account_id)):
"recent_scans": recent_scans, "recent_scans": recent_scans,
"recent_signals": recent_signals, "recent_signals": recent_signals,
"position_stats": position_stats, "position_stats": position_stats,
"trading_config": trading_config # 添加交易配置 "trading_config": trading_config, # 添加交易配置
"_debug": { # 添加调试信息
"account_id": account_id,
"account_data_total_balance": account_data.get('total_balance', 'N/A') if account_data else 'N/A',
"open_trades_count": len(open_trades),
}
} }
# 如果有错误,在响应中包含错误信息(但不影响返回) # 如果有错误,在响应中包含错误信息(但不影响返回)
@ -268,6 +277,14 @@ async def get_dashboard_data(account_id: int = Depends(get_account_id)):
if positions_error: if positions_error:
result["warnings"]["positions"] = positions_error result["warnings"]["positions"] = positions_error
logger.info(f"返回仪表板数据:")
logger.info(f" - account_id: {account_id}")
logger.info(f" - total_balance: {account_data.get('total_balance', 'N/A') if account_data else 'N/A'}")
logger.info(f" - available_balance: {account_data.get('available_balance', 'N/A') if account_data else 'N/A'}")
logger.info(f" - open_trades count: {len(open_trades)}")
if open_trades and len(open_trades) > 0:
logger.info(f" - 第一个持仓: {open_trades[0].get('symbol', 'N/A')}")
logger.info("=" * 60)
return result return result
except Exception as e: except Exception as e:
logger.error(f"获取仪表板数据失败: {e}", exc_info=True) logger.error(f"获取仪表板数据失败: {e}", exc_info=True)

View File

@ -51,7 +51,15 @@ class Account:
@staticmethod @staticmethod
def get(account_id: int): def get(account_id: int):
return db.execute_one("SELECT * FROM accounts WHERE id = %s", (int(account_id),)) import logging
logger = logging.getLogger(__name__)
logger.info(f"Account.get called with account_id={account_id}")
row = db.execute_one("SELECT * FROM accounts WHERE id = %s", (int(account_id),))
if row:
logger.info(f"Account.get: found account_id={account_id}, name={row.get('name', 'N/A')}, status={row.get('status', 'N/A')}")
else:
logger.warning(f"Account.get: account_id={account_id} not found in database")
return row
@staticmethod @staticmethod
def list_all(): def list_all():

View File

@ -31,6 +31,7 @@ class BinanceClient:
testnet: 是否使用测试网如果为None从config读取 testnet: 是否使用测试网如果为None从config读取
""" """
# 如果未提供参数从config读取确保使用最新值 # 如果未提供参数从config读取确保使用最新值
# 注意:如果明确传递了 api_key 和 api_secret应该使用传递的值而不是从 config 读取
if api_key is None: if api_key is None:
# 尝试从配置管理器直接获取 # 尝试从配置管理器直接获取
if config._config_manager: if config._config_manager:
@ -59,6 +60,13 @@ class BinanceClient:
self.api_key = api_key self.api_key = api_key
self.api_secret = api_secret self.api_secret = api_secret
self.testnet = testnet self.testnet = testnet
# 记录使用的 API Key用于调试只显示前后4位
if api_key:
key_display = f"{api_key[:4]}...{api_key[-4:]}" if len(api_key) > 8 else api_key
logger.info(f"BinanceClient.__init__: 使用 API Key {key_display}, testnet={testnet}")
else:
logger.warning("BinanceClient.__init__: API Key 为空!")
self.client: Optional[AsyncClient] = None self.client: Optional[AsyncClient] = None
self.socket_manager: Optional[BinanceSocketManager] = None self.socket_manager: Optional[BinanceSocketManager] = None
self._symbol_info_cache: Dict[str, Dict] = {} # 缓存交易对信息 self._symbol_info_cache: Dict[str, Dict] = {} # 缓存交易对信息