/* 系统设置页 */ let curSettings = null; async function loadSettings() { try { curSettings = await api('/api/settings'); const mail = curSettings.mail, mono = curSettings.monitor, llm = curSettings.llm; $('#emailEnabled').checked = !!mail.email_enabled; $('#smtpHost').value = mail.smtp_host; $('#smtpPort').value = mail.smtp_port; $('#smtpMode').value = mail.smtp_mode || 'plain'; $('#smtpUser').value = mail.smtp_user; $('#smtpPass').value = mail.smtp_pass; $('#senderName').value = mail.sender_name; $('#emailTo').value = mail.email_to; $('#llmBaseUrl').value = llm.base_url; $('#llmApiKey').value = llm.api_key; $('#llmModel').value = llm.model; $('#monitorEnabled').checked = !!mono.enabled; $('#monitorInterval').value = mono.interval_min; $('#monitorImportance').value = mono.importance_threshold; $('#monitorSentiment').value = mono.sentiment_weight; $('#monitorKeywords').value = (mono.keywords || []).join(','); // 分类勾选 const cats = mono.categories || []; $$('#monitorCats input').forEach(c => c.checked = cats.includes(c.value)); renderState(curSettings.state); // 持仓跟踪 const tr = curSettings.tracking || {}; $('#trackingEnabled').checked = !!tr.enabled; $('#trackingInterval').value = tr.interval_min; $('#trackingImpact').value = tr.impact_threshold; $('#trackingNotify').checked = !!tr.notify; renderTrackingState(tr); loadLog(); } catch (e) { toast('设置加载失败'); } } function renderState(state) { $('#monitorState').innerHTML = `
已处理新闻水位
#${state.last_news_id || 0}
上次扫描
${state.last_scan || '—'}
上次通知
${state.last_sent_count || 0} 条
`; } function renderTrackingState(tr) { $('#trackingState').innerHTML = `
上次运行
${tr.last_run || '—'}
最近跟踪
${tr.last_stock || '—'}
最近告警影响度
${tr.last_alert ? tr.last_alert + '/100' : '—'}
`; } function collectMail() { return { smtp_host: $('#smtpHost').value.trim(), smtp_port: $('#smtpPort').value, smtp_mode: $('#smtpMode').value, smtp_user: $('#smtpUser').value.trim(), smtp_pass: $('#smtpPass').value, sender_name: $('#senderName').value.trim(), email_to: $('#emailTo').value.trim(), email_enabled: $('#emailEnabled').checked }; } function collectMonitor() { const cats = $$('#monitorCats input:checked').map(c => c.value); return { monitor_enabled: $('#monitorEnabled').checked, monitor_interval: $('#monitorInterval').value, monitor_importance: $('#monitorImportance').value, monitor_sentiment: $('#monitorSentiment').value, monitor_categories: cats.join(','), monitor_keywords: $('#monitorKeywords').value }; } async function save(which) { try { const body = {}; if (which === 'mail') body.mail = collectMail(); if (which === 'llm') body.llm = { llm_base_url: $('#llmBaseUrl').value.trim(), llm_api_key: $('#llmApiKey').value.trim(), llm_model: $('#llmModel').value.trim() }; if (which === 'monitor') body.monitor = collectMonitor(); if (which === 'tracking') body.tracking = { tracking_enabled: $('#trackingEnabled').checked, tracking_interval: $('#trackingInterval').value, tracking_impact_threshold: $('#trackingImpact').value, tracking_notify: $('#trackingNotify').checked }; const r = await api('/api/settings', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) }); toast(r.msg || '已保存'); } catch (e) { toast('保存失败:' + e.message); } } async function testEmail() { const btn = event.target; btn.disabled = true; btn.textContent = '发送中…'; try { await api('/api/settings', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ mail: collectMail() }) }); const r = await api('/api/settings/test-email', { method: 'POST' }); toast(r.msg || '发送成功'); } catch (e) { toast('发送失败:' + e.message); } btn.disabled = false; btn.textContent = '📨 发送测试邮件'; } async function testLlm() { const btn = event.target; btn.disabled = true; btn.textContent = '测试中…'; try { await api('/api/settings', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ llm: { llm_base_url: $('#llmBaseUrl').value.trim(), llm_api_key: $('#llmApiKey').value.trim(), llm_model: $('#llmModel').value.trim() } }) }); const r = await api('/api/settings/test-llm', { method: 'POST' }); toast(r.msg || '连接正常'); } catch (e) { toast('连接失败:' + e.message); } btn.disabled = false; btn.textContent = '🔌 测试连接'; } async function scanNow() { const btn = event.target; btn.disabled = true; try { const r = await api('/api/monitor/scan', { method: 'POST' }); toast(`扫描完成:检查 ${r.checked} 条,重要 ${r.important} 条,发送 ${r.sent} 条` + (r.error ? '(' + r.error + ')' : '')); loadSettings(); } catch (e) { toast('扫描失败:' + e.message); } btn.disabled = false; } async function loadLog() { try { const d = await api('/api/monitor/log'); const items = d.items || []; if (!items.length) return; $('#logTb').innerHTML = items.map(n => ` ${n.sent_at} ${escapeHtml(n.title)} ${n.category} ${n.sentiment > 0 ? '利好' : n.sentiment < 0 ? '利空' : '中性'} (${Number(n.sentiment).toFixed(2)}) ${n.importance} ${n.status} `).join(''); } catch (e) {} } loadSettings();