// 如果设置了VITE_API_URL环境变量,使用它;否则在开发环境使用相对路径(通过vite代理),生产环境使用默认值 const API_BASE_URL = import.meta.env.VITE_API_URL || (import.meta.env.DEV ? '' : 'http://localhost:8000'); // 构建API URL的辅助函数,避免双斜杠和格式问题 const buildUrl = (path) => { const baseUrl = API_BASE_URL.endsWith('/') ? API_BASE_URL.slice(0, -1) : API_BASE_URL; const cleanPath = path.startsWith('/') ? path : `/${path}`; return baseUrl ? `${baseUrl}${cleanPath}` : cleanPath; }; export const api = { // 配置管理 getConfigs: async () => { const response = await fetch(buildUrl('/api/config')); if (!response.ok) { const error = await response.json().catch(() => ({ detail: '获取配置失败' })); throw new Error(error.detail || '获取配置失败'); } return response.json(); }, getConfig: async (key) => { const response = await fetch(buildUrl(`/api/config/${key}`)); if (!response.ok) { const error = await response.json().catch(() => ({ detail: '获取配置失败' })); throw new Error(error.detail || '获取配置失败'); } return response.json(); }, updateConfig: async (key, data) => { const response = await fetch(buildUrl(`/api/config/${key}`), { method: 'PUT', headers: {'Content-Type': 'application/json'}, body: JSON.stringify(data) }); if (!response.ok) { const error = await response.json(); throw new Error(error.detail || '更新配置失败'); } return response.json(); }, updateConfigsBatch: async (configs) => { const response = await fetch(buildUrl('/api/config/batch'), { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify(configs) }); if (!response.ok) { const error = await response.json().catch(() => ({ detail: '批量更新配置失败' })); throw new Error(error.detail || '批量更新配置失败'); } return response.json(); }, // 检查配置可行性 checkConfigFeasibility: async () => { const response = await fetch(buildUrl('/api/config/feasibility-check')); if (!response.ok) { const error = await response.json().catch(() => ({ detail: '检查配置可行性失败' })); throw new Error(error.detail || '检查配置可行性失败'); } return response.json(); }, // 交易记录 getTrades: async (params = {}) => { const query = new URLSearchParams(params).toString(); const url = query ? `${buildUrl('/api/trades')}?${query}` : buildUrl('/api/trades'); const response = await fetch(url, { method: 'GET', headers: { 'Content-Type': 'application/json', }, }); if (!response.ok) { const error = await response.json().catch(() => ({ detail: '获取交易记录失败' })); throw new Error(error.detail || '获取交易记录失败'); } return response.json(); }, getTradeStats: async (params = {}) => { const query = new URLSearchParams(params).toString(); const url = query ? `${buildUrl('/api/trades/stats')}?${query}` : buildUrl('/api/trades/stats'); const response = await fetch(url, { method: 'GET', headers: { 'Content-Type': 'application/json', }, }); if (!response.ok) { const error = await response.json().catch(() => ({ detail: '获取交易统计失败' })); throw new Error(error.detail || '获取交易统计失败'); } return response.json(); }, // 统计 getPerformance: async (days = 7) => { const response = await fetch(buildUrl(`/api/stats/performance?days=${days}`)); if (!response.ok) { const error = await response.json().catch(() => ({ detail: '获取性能统计失败' })); throw new Error(error.detail || '获取性能统计失败'); } return response.json(); }, getDashboard: async () => { const response = await fetch(buildUrl('/api/dashboard')); if (!response.ok) { const error = await response.json().catch(() => ({ detail: '获取仪表板数据失败' })); throw new Error(error.detail || '获取仪表板数据失败'); } return response.json(); }, // 平仓操作 closePosition: async (symbol) => { const response = await fetch(buildUrl(`/api/account/positions/${symbol}/close`), { method: 'POST', headers: { 'Content-Type': 'application/json', }, }); if (!response.ok) { const error = await response.json().catch(() => ({ detail: '平仓失败' })); throw new Error(error.detail || '平仓失败'); } return response.json(); }, // 同步持仓状态 syncPositions: async () => { const response = await fetch(buildUrl('/api/account/positions/sync'), { method: 'POST', headers: { 'Content-Type': 'application/json', }, }); if (!response.ok) { const error = await response.json().catch(() => ({ detail: '同步失败' })); throw new Error(error.detail || '同步失败'); } return response.json(); }, // 交易推荐 getRecommendations: async (params = {}) => { // 默认使用实时推荐 if (!params.type) { params.type = 'realtime' } const query = new URLSearchParams(params).toString(); const url = query ? `${buildUrl('/api/recommendations')}?${query}` : buildUrl('/api/recommendations'); const response = await fetch(url); if (!response.ok) { const error = await response.json().catch(() => ({ detail: '获取推荐失败' })); throw new Error(error.detail || '获取推荐失败'); } return response.json(); }, bookmarkRecommendation: async (recommendationData) => { const response = await fetch(buildUrl('/api/recommendations/bookmark'), { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify(recommendationData) }); if (!response.ok) { const error = await response.json().catch(() => ({ detail: '标记推荐失败' })); throw new Error(error.detail || '标记推荐失败'); } return response.json(); }, getActiveRecommendations: async () => { const response = await fetch(buildUrl('/api/recommendations/active')); if (!response.ok) { const error = await response.json().catch(() => ({ detail: '获取有效推荐失败' })); throw new Error(error.detail || '获取有效推荐失败'); } return response.json(); }, getRecommendation: async (id) => { const response = await fetch(buildUrl(`/api/recommendations/${id}`)); if (!response.ok) { const error = await response.json().catch(() => ({ detail: '获取推荐详情失败' })); throw new Error(error.detail || '获取推荐详情失败'); } return response.json(); }, generateRecommendations: async (minSignalStrength = 5, maxRecommendations = 20) => { const response = await fetch( buildUrl(`/api/recommendations/generate?min_signal_strength=${minSignalStrength}&max_recommendations=${maxRecommendations}`), { method: 'POST', headers: { 'Content-Type': 'application/json', }, } ); if (!response.ok) { const error = await response.json().catch(() => ({ detail: '生成推荐失败' })); throw new Error(error.detail || '生成推荐失败'); } return response.json(); }, markRecommendationExecuted: async (id, tradeId = null) => { const response = await fetch(buildUrl(`/api/recommendations/${id}/execute`), { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ trade_id: tradeId }), }); if (!response.ok) { const error = await response.json().catch(() => ({ detail: '标记执行失败' })); throw new Error(error.detail || '标记执行失败'); } return response.json(); }, cancelRecommendation: async (id, notes = null) => { const response = await fetch(buildUrl(`/api/recommendations/${id}/cancel`), { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ notes }), }); if (!response.ok) { const error = await response.json().catch(() => ({ detail: '取消推荐失败' })); throw new Error(error.detail || '取消推荐失败'); } return response.json(); }, // 系统控制(supervisor) clearSystemCache: async () => { const response = await fetch(buildUrl('/api/system/clear-cache'), { method: 'POST', headers: { 'Content-Type': 'application/json' }, }); if (!response.ok) { const error = await response.json().catch(() => ({ detail: '清理缓存失败' })); throw new Error(error.detail || '清理缓存失败'); } return response.json(); }, getTradingSystemStatus: async () => { const response = await fetch(buildUrl('/api/system/trading/status')); if (!response.ok) { const error = await response.json().catch(() => ({ detail: '获取交易系统状态失败' })); throw new Error(error.detail || '获取交易系统状态失败'); } return response.json(); }, startTradingSystem: async () => { const response = await fetch(buildUrl('/api/system/trading/start'), { method: 'POST', headers: { 'Content-Type': 'application/json' }, }); if (!response.ok) { const error = await response.json().catch(() => ({ detail: '启动交易系统失败' })); throw new Error(error.detail || '启动交易系统失败'); } return response.json(); }, stopTradingSystem: async () => { const response = await fetch(buildUrl('/api/system/trading/stop'), { method: 'POST', headers: { 'Content-Type': 'application/json' }, }); if (!response.ok) { const error = await response.json().catch(() => ({ detail: '停止交易系统失败' })); throw new Error(error.detail || '停止交易系统失败'); } return response.json(); }, restartTradingSystem: async () => { const response = await fetch(buildUrl('/api/system/trading/restart'), { method: 'POST', headers: { 'Content-Type': 'application/json' }, }); if (!response.ok) { const error = await response.json().catch(() => ({ detail: '重启交易系统失败' })); throw new Error(error.detail || '重启交易系统失败'); } return response.json(); }, };