import type { BacktestRequest, BacktestResponse, ScreenerRunRequest, ScreenerRunResponse, ScreenerSyncRequest, ScreenerSyncStatus, SyncRequest, SyncResponse, } from './types'; // dev 用 Vite 代理(/api -> :8000);生产构建设 VITE_API_BASE 指向后端地址。 const BASE = import.meta.env.VITE_API_BASE ?? ''; export async function postBacktest(req: BacktestRequest): Promise { const res = await fetch(`${BASE}/api/backtest`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(req), }); if (!res.ok) { throw new Error(`回测请求失败 (HTTP ${res.status}): ${await res.text()}`); } return (await res.json()) as BacktestResponse; } export async function syncData(req: SyncRequest): Promise { const res = await fetch(`${BASE}/api/data/sync`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(req), }); if (!res.ok) { throw new Error(`数据拉取失败 (HTTP ${res.status}): ${await res.text()}`); } return (await res.json()) as SyncResponse; } // ---------- 智能选股 ---------- export async function runScreener(req: ScreenerRunRequest): Promise { const res = await fetch(`${BASE}/api/screener/run`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(req), }); if (!res.ok) { // 后端 detail 字段携带可读中文原因(503 未配 key / 409 未同步 / 502 LLM 错) let detail = ''; try { detail = (await res.json())?.detail ?? ''; } catch { detail = await res.text(); } throw new Error(detail || `选股失败 (HTTP ${res.status})`); } return (await res.json()) as ScreenerRunResponse; } export async function startScreenerSync(req: ScreenerSyncRequest = {}): Promise { const res = await fetch(`${BASE}/api/screener/sync`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(req), }); if (!res.ok) { let detail = ''; try { detail = (await res.json())?.detail ?? ''; } catch { detail = await res.text(); } throw new Error(detail || `启动同步失败 (HTTP ${res.status})`); } return (await res.json()) as ScreenerSyncStatus; } export async function getScreenerSyncStatus(): Promise { const res = await fetch(`${BASE}/api/screener/sync/status`); if (!res.ok) throw new Error(`获取同步状态失败 (HTTP ${res.status})`); return (await res.json()) as ScreenerSyncStatus; }