'use strict'; (function () { const views = { crawl: document.getElementById('viewCrawl'), gen: document.getElementById('viewGen'), history: document.getElementById('viewHistory'), settings: document.getElementById('viewSettings'), }; const navItems = document.querySelectorAll('.nav-item[data-view]'); let settingsLoaded = false; let logTimer = null; let lastLogSignature = ''; function showSettingsStatus(message, type = 'info') { const status = document.getElementById('settingsStatus'); status.textContent = message; status.className = `badge ${type === 'success' ? 'badge-ok' : type === 'error' ? 'badge-fail' : 'badge-info'}`; } async function loadModels(selectedModel) { const select = document.getElementById('settingsModel'); const response = await fetch('/api/models'); if (!response.ok) throw new Error('模型列表加载失败'); const data = await response.json(); select.innerHTML = ''; for (const model of data.models || []) { const option = document.createElement('option'); option.value = typeof model === 'string' ? model : model.id; option.textContent = typeof model === 'string' ? model : (model.label || model.name || model.id); option.selected = option.value === selectedModel; select.appendChild(option); } } async function loadSettings() { showSettingsStatus('加载中…'); const response = await fetch('/api/settings'); if (!response.ok) throw new Error('设置加载失败'); const settings = await response.json(); document.getElementById('settingsApiKey').value = settings.apiKey || ''; document.getElementById('settingsApiBase').value = settings.apiBase || ''; document.getElementById('settingsRootDir').value = settings.rootDir || ''; document.getElementById('pageSizeInput').value = settings.pageSize || 50; document.getElementById('delayInput').value = settings.delayMs ?? 300; document.getElementById('settingsCookie').value = settings.cookie || ''; await loadModels(settings.model); showSettingsStatus('已同步'); } async function saveSettings() { const button = document.getElementById('btnSaveSettings'); button.disabled = true; showSettingsStatus('保存中…'); try { const response = await fetch('/api/settings', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ apiKey: document.getElementById('settingsApiKey').value.trim(), model: document.getElementById('settingsModel').value, rootDir: document.getElementById('settingsRootDir').value.trim(), pageSize: Number(document.getElementById('pageSizeInput').value), delayMs: Number(document.getElementById('delayInput').value), cookie: document.getElementById('settingsCookie').value.trim(), }), }); const data = await response.json(); if (!response.ok) throw new Error(data.error || `HTTP ${response.status}`); await loadSettings(); showSettingsStatus('已保存', 'success'); } catch (error) { showSettingsStatus(error.message, 'error'); } finally { button.disabled = false; } } async function initSettings() { if (settingsLoaded) return; document.getElementById('btnSaveSettings').addEventListener('click', saveSettings); document.getElementById('btnClearLog').addEventListener('click', () => { clearLogs().catch(() => {}); }); try { await loadSettings(); settingsLoaded = true; } catch (error) { showSettingsStatus(error.message, 'error'); } } function escapeLogText(value) { const div = document.createElement('div'); div.textContent = String(value ?? ''); return div.innerHTML; } function renderLogs(logs) { const panel = document.getElementById('logPanel'); if (!panel) return; const sourceMap = { task: '任务', system: '系统' }; const levelMap = { info: 'INFO', success: 'OK', warn: 'WARN', error: 'FAIL' }; panel.innerHTML = logs.map((log) => { const level = levelMap[log.level] || 'INFO'; const levelClass = log.level === 'success' ? 'ok' : log.level || 'info'; return `