Skip to main content
Glama
liuguoping1024

SWLC MCP Server

app.js18.6 kB
// 全局变量 let currentLotteryType = 'ssq'; let chartInstance = null; // 页面加载完成后初始化 document.addEventListener('DOMContentLoaded', function() { initializeApp(); }); // 初始化应用 function initializeApp() { // 绑定导航事件 bindNavigationEvents(); // 绑定彩票类型选择事件 bindLotteryTypeEvents(); // 加载初始数据 loadDashboardData(); // 启动健康检查 startHealthCheck(); // 初始化图表 initializeCharts(); } // 绑定导航事件 function bindNavigationEvents() { const navButtons = document.querySelectorAll('.nav-btn'); const tabContents = document.querySelectorAll('.tab-content'); navButtons.forEach(button => { button.addEventListener('click', function() { const targetTab = this.getAttribute('data-tab'); // 更新导航按钮状态 navButtons.forEach(btn => btn.classList.remove('active')); this.classList.add('active'); // 更新标签页内容 tabContents.forEach(content => content.classList.remove('active')); document.getElementById(targetTab).classList.add('active'); // 加载对应标签页的数据 loadTabData(targetTab); }); }); } // 绑定彩票类型选择事件 function bindLotteryTypeEvents() { const lotterySelect = document.getElementById('lotteryType'); lotterySelect.addEventListener('change', function() { currentLotteryType = this.value; loadDashboardData(); }); } // 加载仪表板数据 async function loadDashboardData() { await Promise.all([ loadLatestResult(), loadHistoricalData(), loadNumberStats() ]); } // 加载标签页数据 function loadTabData(tabName) { switch(tabName) { case 'dashboard': loadDashboardData(); break; case 'prediction': // 预测页面不需要预加载数据 break; case 'backtest': // 回测页面不需要预加载数据 break; case 'settings': loadSettings(); break; } } // 加载最新开奖结果 async function loadLatestResult() { const resultDiv = document.getElementById('latestResult'); resultDiv.innerHTML = '<div class="loading">加载中...</div>'; try { const response = await fetch(`/api/latest/${currentLotteryType}`); const data = await response.json(); if (data.success) { const result = data.data; resultDiv.innerHTML = ` <div class="lottery-info"> <div class="period">第${result.period}期</div> <div class="date">${result.draw_date}</div> </div> <div class="lottery-numbers"> ${result.numbers.map(num => `<div class="number-ball red-ball">${num}</div>` ).join('')} ${result.special_numbers ? result.special_numbers.map(num => `<div class="number-ball blue-ball">${num}</div>` ).join('') : ''} </div> <div class="lottery-details"> <div>奖池: ${formatMoney(result.prize_pool)}</div> <div>销售额: ${formatMoney(result.sales_amount)}</div> </div> `; } else { resultDiv.innerHTML = '<div class="error">获取数据失败</div>'; } } catch (error) { console.error('加载最新开奖失败:', error); resultDiv.innerHTML = '<div class="error">网络错误</div>'; } } // 加载历史数据 async function loadHistoricalData() { const dataDiv = document.getElementById('historicalData'); const periods = document.getElementById('periods').value; dataDiv.innerHTML = '<div class="loading">加载中...</div>'; try { const response = await fetch(`/api/draws?lottery_type=${currentLotteryType}&periods=${periods}`); const data = await response.json(); if (data.success && data.data) { const historyData = data.data; let html = '<table class="history-table">'; html += '<thead><tr><th>期号</th><th>开奖日期</th><th>开奖号码</th></tr></thead><tbody>'; historyData.forEach(item => { html += ` <tr> <td>${item.period}</td> <td>${item.draw_date}</td> <td> <div class="lottery-numbers"> ${item.numbers.map(num => `<div class="number-ball red-ball">${num}</div>` ).join('')} ${item.special_numbers ? item.special_numbers.map(num => `<div class="number-ball blue-ball">${num}</div>` ).join('') : ''} </div> </td> </tr> `; }); html += '</tbody></table>'; dataDiv.innerHTML = html; // 历史数据刷新后,重新计算号码统计 await loadNumberStats(); } else { dataDiv.innerHTML = '<div class="error">获取历史数据失败</div>'; } } catch (error) { console.error('加载历史数据失败:', error); dataDiv.innerHTML = '<div class="error">网络错误</div>'; } } // 加载号码统计 async function loadNumberStats() { const statsDiv = document.getElementById('numberStats'); statsDiv.innerHTML = '<div class="loading">加载中...</div>'; try { const periodsInput = document.getElementById('periods'); const periods = periodsInput ? periodsInput.value : 30; const response = await fetch(`/api/analysis/${currentLotteryType}?periods=${periods}`); const data = await response.json(); if (data.success && data.data) { const stats = data.data; const hotMap = stats.hot_numbers || {}; const coldMap = stats.cold_numbers || {}; // 排序:热门(降序),冷门(升序) const hotEntries = Object.entries(hotMap).sort((a, b) => Number(b[1]) - Number(a[1]) || Number(a[0]) - Number(b[0])); const coldEntries = Object.entries(coldMap).sort((a, b) => Number(a[1]) - Number(b[1]) || Number(a[0]) - Number(b[0])); // 计算最大频次用于热度条 const maxFreq = Math.max(1, ...hotEntries.map(([, c]) => Number(c)), ...coldEntries.map(([, c]) => Number(c))); let html = ''; // 热门号码 if (hotEntries.length) { html += '<div class="stat-section">'; html += `<h4>热门号码(最近${stats.analysis_periods}期)</h4>`; html += '<div class="number-grid">'; hotEntries.forEach(([num, cnt]) => { const pct = Math.round((Number(cnt) / maxFreq) * 100); html += ` <div> <span class="number-chip hot"> <span>${num}</span> <span class="badge">${cnt}</span> </span> <div class="heat-bar"><span style="width:${pct}%"></span></div> </div> `; }); html += '</div>'; html += '<div class="note">徽章=出现次数,蓝色条=相对热度</div>'; html += '</div>'; } // 冷门号码 if (coldEntries.length) { html += '<div class="stat-section">'; html += `<h4>冷门号码(最近${stats.analysis_periods}期)</h4>`; html += '<div class="number-grid">'; coldEntries.forEach(([num, cnt]) => { const pct = Math.round((Number(cnt) / maxFreq) * 100); html += ` <div> <span class="number-chip cold"> <span>${num}</span> <span class="badge">${cnt}</span> </span> <div class="heat-bar"><span style="width:${pct}%"></span></div> </div> `; }); html += '</div>'; html += '</div>'; } // 连号分析 if (stats.consecutive_analysis) { const ca = stats.consecutive_analysis; html += '<div class="stat-section">'; html += `<h4>连号分析</h4>`; html += `<div class="note">统计期数:${ca.total_periods};最高频:${Array.isArray(ca.most_frequent)? ca.most_frequent.join(' / ') : ''};最低频:${Array.isArray(ca.least_frequent)? ca.least_frequent.join(' / ') : ''}</div>`; html += '</div>'; } statsDiv.innerHTML = html || '<div class="note">暂无统计数据</div>'; } else { statsDiv.innerHTML = '<div class="error">获取统计数据失败</div>'; } } catch (error) { console.error('加载号码统计失败:', error); statsDiv.innerHTML = '<div class="error">网络错误</div>'; } } // 生成预测 async function generatePrediction() { const resultsDiv = document.getElementById('predictionResults'); const method = document.getElementById('predictionMethod') ? document.getElementById('predictionMethod').value : 'rule'; const count = document.getElementById('predictionCount').value; const strategy = document.getElementById('predictionStrategy') ? document.getElementById('predictionStrategy').value : 'all'; const ptype = document.getElementById('predictLotteryType') ? document.getElementById('predictLotteryType').value : currentLotteryType; resultsDiv.innerHTML = '<div class="loading">生成预测中...</div>'; try { const response = await fetch(`/api/predict/${ptype}?method=${method}&count=${count}&strategy=${strategy}`); const data = await response.json(); if (data.success && data.data) { const predictions = data.data; let html = ''; predictions.forEach((prediction, index) => { html += ` <div class="prediction-item"> <h4>预测组合 ${index + 1}(${prediction.method})</h4> <div class="lottery-numbers"> ${prediction.numbers.map(num => `<div class="number-ball red-ball">${num}</div>` ).join('')} ${prediction.special_numbers ? prediction.special_numbers.map(num => `<div class="number-ball blue-ball">${num}</div>` ).join('') : ''} </div> ${prediction.metadata && prediction.metadata.strategy ? `<div class="note">策略: ${prediction.metadata.strategy}</div>` : ''} </div> `; }); resultsDiv.innerHTML = html; } else { resultsDiv.innerHTML = '<div class="error">生成预测失败</div>'; } } catch (error) { console.error('生成预测失败:', error); resultsDiv.innerHTML = '<div class="error">网络错误</div>'; } } // 运行回测 async function runBacktest() { const resultsDiv = document.getElementById('backtestResults'); const windowSize = document.getElementById('windowSize').value; const stepSize = document.getElementById('stepSize').value; resultsDiv.innerHTML = '<div class="loading">运行回测中...</div>'; try { const response = await fetch(`/api/backtest/${currentLotteryType}?window_size=${windowSize}&step=${stepSize}`); const data = await response.json(); if (data.success && data.data) { const backtestResults = data.data; let html = ` <div class="backtest-summary"> <h3>回测结果摘要</h3> <div class="summary-stats"> <div class="stat-item"> <span class="stat-label">总测试期数:</span> <span class="stat-value">${backtestResults.total_periods}</span> </div> <div class="stat-item"> <span class="stat-label">平均命中率:</span> <span class="stat-value">${backtestResults.average_accuracy}%</span> </div> <div class="stat-item"> <span class="stat-label">最佳策略:</span> <span class="stat-value">${backtestResults.best_strategy}</span> </div> </div> </div> `; resultsDiv.innerHTML = html; // 如果有图表数据,绘制图表 if (backtestResults.chart_data) { drawBacktestChart(backtestResults.chart_data); } } else { resultsDiv.innerHTML = '<div class="error">回测失败</div>'; } } catch (error) { console.error('运行回测失败:', error); resultsDiv.innerHTML = '<div class="error">网络错误</div>'; } } // 保存设置 async function saveSettings() { const deepseekKey = document.getElementById('deepseekKey').value; const openaiKey = document.getElementById('openaiKey').value; try { const response = await fetch('/api/settings', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ deepseek_key: deepseekKey, openai_key: openaiKey }) }); const data = await response.json(); if (data.success) { showMessage('设置保存成功', 'success'); } else { showMessage('设置保存失败', 'error'); } } catch (error) { console.error('保存设置失败:', error); showMessage('网络错误', 'error'); } } // 加载设置 async function loadSettings() { try { const response = await fetch('/api/settings'); const data = await response.json(); if (data.success) { document.getElementById('deepseekKey').value = data.data.deepseek_key || ''; document.getElementById('openaiKey').value = data.data.openai_key || ''; } } catch (error) { console.error('加载设置失败:', error); } } // 初始化图表 function initializeCharts() { const chartContainer = document.getElementById('chartContainer'); if (chartContainer) { chartInstance = echarts.init(chartContainer); } } // 绘制回测图表 function drawBacktestChart(chartData) { if (!chartInstance) return; const option = { title: { text: '回测结果趋势', left: 'center' }, tooltip: { trigger: 'axis' }, legend: { data: ['命中率', '预测准确度'], top: 30 }, xAxis: { type: 'category', data: chartData.periods }, yAxis: { type: 'value', min: 0, max: 100 }, series: [ { name: '命中率', type: 'line', data: chartData.accuracy, smooth: true }, { name: '预测准确度', type: 'line', data: chartData.precision, smooth: true } ] }; chartInstance.setOption(option); } // 启动健康检查 function startHealthCheck() { checkHealth(); setInterval(checkHealth, 30000); // 每30秒检查一次 } // 检查健康状态 async function checkHealth() { try { const response = await fetch('/api/health'); const data = await response.json(); const statusElement = document.getElementById('serverStatus'); const serverOk = (typeof data.mcp_server === 'string' && data.mcp_server === 'healthy') || (data.mcp_server && data.mcp_server.status === 'healthy'); if (serverOk) { statusElement.innerHTML = '🟢 服务器正常'; statusElement.className = 'status-item'; } else { statusElement.innerHTML = '🔴 服务器异常'; statusElement.className = 'status-item error'; } document.getElementById('lastUpdate').textContent = `最后更新: ${data.timestamp || ''}`; } catch (error) { const statusElement = document.getElementById('serverStatus'); statusElement.innerHTML = '🔴 连接失败'; statusElement.className = 'status-item error'; } } // 显示消息 function showMessage(message, type = 'info') { const messageDiv = document.createElement('div'); messageDiv.className = `message ${type}`; messageDiv.textContent = message; document.body.appendChild(messageDiv); setTimeout(() => { messageDiv.remove(); }, 3000); } // 格式化金额 function formatMoney(amount) { if (!amount) return '0'; return new Intl.NumberFormat('zh-CN', { style: 'currency', currency: 'CNY' }).format(amount); } // 全局函数,供HTML调用 window.loadHistoricalData = loadHistoricalData; window.generatePrediction = generatePrediction; window.runBacktest = runBacktest; window.saveSettings = saveSettings;

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/liuguoping1024/swlc-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server