|
|
|
|
@ -1444,7 +1444,12 @@ async function refreshAllSymbols() {
|
|
|
|
|
showToast('info', '开始刷新', '正在同步所有品种数据...');
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
const response = await fetch(`${API_BASE}/refresh-all`, { method: 'POST' });
|
|
|
|
|
const response = await fetch(`${API_BASE}/refresh-all`, {
|
|
|
|
|
method: 'POST',
|
|
|
|
|
headers: {
|
|
|
|
|
'Content-Type': 'application/json'
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
const data = await response.json();
|
|
|
|
|
|
|
|
|
|
if (data.success) {
|
|
|
|
|
@ -1454,7 +1459,6 @@ async function refreshAllSymbols() {
|
|
|
|
|
resetRefreshButton(btn);
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('刷新全部失败:', error);
|
|
|
|
|
showToast('error', '刷新失败', '网络错误,请稍后重试');
|
|
|
|
|
resetRefreshButton(btn);
|
|
|
|
|
}
|
|
|
|
|
@ -1482,12 +1486,15 @@ async function pollRefreshStatus() {
|
|
|
|
|
|
|
|
|
|
showToast('success', '刷新完成', `已同步 ${status.total} 个品种数据`);
|
|
|
|
|
} else {
|
|
|
|
|
btn.innerHTML = `<i class="fas fa-sync-alt"></i><span>刷新中 ${status.progress}/${status.total}</span>`;
|
|
|
|
|
setTimeout(pollRefreshStatus, 2000);
|
|
|
|
|
const progress = status.progress || 0;
|
|
|
|
|
const total = status.total || 0;
|
|
|
|
|
const percentage = total > 0 ? Math.round((progress / total) * 100) : 0;
|
|
|
|
|
btn.innerHTML = `<i class="fas fa-sync-alt fa-spin"></i><span>刷新中 ${progress}/${total} (${percentage}%)</span>`;
|
|
|
|
|
showToast('info', '刷新进度', `${status.message || `正在刷新 ${progress}/${total}`}`);
|
|
|
|
|
setTimeout(pollRefreshStatus, 1000);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('获取刷新状态失败:', error);
|
|
|
|
|
resetRefreshButton(btn);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@ -1592,12 +1599,16 @@ async function analyzeAllSymbols() {
|
|
|
|
|
|
|
|
|
|
const originalContent = allBtn.innerHTML;
|
|
|
|
|
allBtn.disabled = true;
|
|
|
|
|
allBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> 分析中...';
|
|
|
|
|
allBtn.classList.add('spinning');
|
|
|
|
|
|
|
|
|
|
showToast('info', '批量分析', '开始对所有合约进行AI分析...');
|
|
|
|
|
|
|
|
|
|
const symbols = allFuturesData.map(item => item.symbol);
|
|
|
|
|
const batchSize = 3; // 每次并发分析3个合约
|
|
|
|
|
const totalSymbols = symbols.length;
|
|
|
|
|
let completedCount = 0;
|
|
|
|
|
let successCount = 0;
|
|
|
|
|
|
|
|
|
|
const batchSize = 3;
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i < symbols.length; i += batchSize) {
|
|
|
|
|
const batch = symbols.slice(i, i + batchSize);
|
|
|
|
|
@ -1613,24 +1624,28 @@ async function analyzeAllSymbols() {
|
|
|
|
|
return { symbol, success: false, error: data.error };
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error(`${symbol} 分析失败:`, error);
|
|
|
|
|
return { symbol, success: false, error: error.message };
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const results = await Promise.all(promises);
|
|
|
|
|
const successCount = results.filter(r => r.success).length;
|
|
|
|
|
showToast('info', '批量分析进度', `已完成 ${Math.min(i + batchSize, symbols.length)}/${symbols.length} 个合约,本批成功 ${successCount} 个`);
|
|
|
|
|
const batchSuccessCount = results.filter(r => r.success).length;
|
|
|
|
|
completedCount += batch.length;
|
|
|
|
|
successCount += batchSuccessCount;
|
|
|
|
|
|
|
|
|
|
const percentage = Math.round((completedCount / totalSymbols) * 100);
|
|
|
|
|
allBtn.innerHTML = `<i class="fas fa-brain fa-spin"></i> 分析中 ${completedCount}/${totalSymbols} (${percentage}%)`;
|
|
|
|
|
showToast('info', '分析进度', `已完成 ${completedCount}/${totalSymbols},成功 ${successCount} 个 (${percentage}%)`);
|
|
|
|
|
|
|
|
|
|
// 每批之间等待2秒,避免API限流
|
|
|
|
|
if (i + batchSize < symbols.length) {
|
|
|
|
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
showToast('success', '批量分析完成', `所有 ${symbols.length} 个合约AI分析已完成`);
|
|
|
|
|
allBtn.disabled = false;
|
|
|
|
|
allBtn.classList.remove('spinning');
|
|
|
|
|
allBtn.innerHTML = originalContent;
|
|
|
|
|
showToast('success', '批量分析完成', `共分析 ${totalSymbols} 个合约,成功 ${successCount} 个`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function syncAIToSymbolCard(symbol, result) {
|
|
|
|
|
@ -1680,34 +1695,6 @@ function syncAIToSymbolCard(symbol, result) {
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function refreshAllSymbols() {
|
|
|
|
|
const btn = document.getElementById('refresh-all-btn');
|
|
|
|
|
if (!btn) return;
|
|
|
|
|
|
|
|
|
|
const originalContent = btn.innerHTML;
|
|
|
|
|
btn.disabled = true;
|
|
|
|
|
btn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> 刷新中...';
|
|
|
|
|
|
|
|
|
|
showToast('info', '刷新中', '正在刷新所有合约数据...');
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
const response = await fetch(`${API_BASE}/refresh-all`);
|
|
|
|
|
const data = await response.json();
|
|
|
|
|
|
|
|
|
|
if (data.success) {
|
|
|
|
|
showToast('success', '刷新成功', `已刷新 ${data.count} 个合约`);
|
|
|
|
|
loadFuturesData();
|
|
|
|
|
} else {
|
|
|
|
|
showToast('error', '刷新失败', data.error || '未知错误');
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
showToast('error', '刷新失败', '网络错误,请稍后重试');
|
|
|
|
|
} finally {
|
|
|
|
|
btn.disabled = false;
|
|
|
|
|
btn.innerHTML = originalContent;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ==================== AI智能分析功能 ====================
|
|
|
|
|
|
|
|
|
|
let currentAIAnalysis = null;
|
|
|
|
|
|