/** * LLM Index RAG - 前端交互脚本 */ // 搜索表单处理 document.getElementById('searchForm')?.addEventListener('submit', async function(e) { e.preventDefault(); const query = document.getElementById('queryInput').value.trim(); const mode = document.querySelector('input[name="mode"]:checked').value; if (!query) { alert('请输入查询内容'); return; } // 显示加载状态 const resultsSection = document.getElementById('resultsSection'); const ragSection = document.getElementById('ragSection'); const resultsContainer = document.getElementById('resultsContainer'); const ragAnswer = document.getElementById('ragAnswer'); const ragSources = document.getElementById('ragSources'); const resultCount = document.getElementById('resultCount'); resultsSection.style.display = 'none'; ragSection.style.display = 'none'; resultsContainer.innerHTML = '

正在检索...

'; resultsSection.style.display = 'block'; try { if (mode === 'search') { // 文档检索模式 const response = await fetch('/api/search', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({query: query, top_k: 10}) }); const data = await response.json(); if (data.error) { resultsContainer.innerHTML = `
${data.error}
`; return; } resultCount.textContent = data.total; if (data.results && data.results.length > 0) { resultsContainer.innerHTML = data.results.map(r => `
${r.title || r.document_title || '文档'}

${r.summary || r.content?.substring(0, 200) + '...' || ''}

${r.source || '本地文档'} ${(r.score * 100).toFixed(1)}%
`).join(''); } else { resultsContainer.innerHTML = `

未找到相关结果

请尝试其他关键词,或先上传并索引文档

`; } } else { // RAG问答模式 resultsContainer.innerHTML = '

正在生成回答...

'; const response = await fetch('/api/rag/answer', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({query: query, top_k: 5}) }); const data = await response.json(); if (data.error) { resultsContainer.innerHTML = `
${data.error}
`; return; } resultsSection.style.display = 'none'; ragSection.style.display = 'block'; // 显示回答 ragAnswer.innerHTML = `
${data.answer || '抱歉,无法生成回答。'}
`; // 显示来源 if (data.sources && data.sources.length > 0) { ragSources.innerHTML = data.sources.map(s => `
${s.title || s.document_title || '参考文档'}

${s.content?.substring(0, 150) + '...' || ''}

`).join(''); } else { ragSources.innerHTML = '

无参考来源

'; } } } catch (err) { resultsContainer.innerHTML = `
请求失败: ${err.message}
`; } }); // 文档上传 document.getElementById('uploadForm')?.addEventListener('submit', async function(e) { e.preventDefault(); const formData = new FormData(this); const fileInput = document.getElementById('fileInput'); if (!fileInput.files.length) { alert('请选择文件'); return; } const uploadBtn = document.getElementById('uploadBtn'); uploadBtn.disabled = true; uploadBtn.innerHTML = ' 上传中...'; try { const response = await fetch('/api/documents', { method: 'POST', body: formData }); const data = await response.json(); if (data.success) { alert('上传成功!'); location.reload(); } else { alert('上传失败: ' + (data.error || '未知错误')); } } catch (err) { alert('上传失败: ' + err.message); } finally { uploadBtn.disabled = false; uploadBtn.innerHTML = ' 上传'; } }); // 索引文档 async function indexDocument(docId) { if (!confirm('确定要索引此文档吗?这可能需要一些时间。')) return; try { const response = await fetch(`/api/index/${docId}`, {method: 'POST'}); const data = await response.json(); if (data.success) { alert('索引完成!'); location.reload(); } else { alert('索引失败: ' + (data.error || '未知错误')); } } catch (err) { alert('索引失败: ' + err.message); } } // 删除文档 async function deleteDocument(docId) { if (!confirm('确定要删除此文档吗?此操作不可恢复。')) return; try { const response = await fetch(`/api/documents/${docId}`, {method: 'DELETE'}); const data = await response.json(); if (data.success) { alert('删除成功!'); location.reload(); } else { alert('删除失败: ' + (data.error || '未知错误')); } } catch (err) { alert('删除失败: ' + err.message); } } // 批量索引 async function batchIndex() { if (!confirm('确定要索引所有待处理文档吗?')) return; try { const response = await fetch('/api/index/batch', {method: 'POST'}); const data = await response.json(); alert(`索引完成!成功: ${data.success}, 失败: ${data.failed}`); location.reload(); } catch (err) { alert('批量索引失败: ' + err.message); } } // 重建索引 async function rebuildIndex() { if (!confirm('重建索引将清除所有现有索引,确定继续吗?')) return; try { const response = await fetch('/api/index/rebuild', {method: 'POST'}); const data = await response.json(); alert(`重建完成!成功: ${data.success}, 失败: ${data.failed}`); location.reload(); } catch (err) { alert('重建索引失败: ' + err.message); } } // 加载统计信息 async function loadStats() { try { const response = await fetch('/api/stats'); const stats = await response.json(); document.getElementById('statDocs').textContent = stats.total_documents || 0; document.getElementById('statChunks').textContent = stats.total_chunks || 0; document.getElementById('statTerms').textContent = stats.total_terms || 0; document.getElementById('statWords').textContent = (stats.total_words || 0).toLocaleString(); } catch (err) { console.error('加载统计失败:', err); } } // 页面加载时刷新统计 document.addEventListener('DOMContentLoaded', function() { // 如果在首页,定时刷新统计 if (document.getElementById('statDocs')) { loadStats(); setInterval(loadStats, 30000); // 每30秒刷新 } });