const uploadArea = document.getElementById('upload-area'); const fileInput = document.getElementById('file-input'); const documentList = document.getElementById('document-list'); const chatMessages = document.getElementById('chat-messages'); const questionInput = document.getElementById('question-input'); const docCount = document.getElementById('doc-count'); const charCount = document.getElementById('char-count'); const toast = document.getElementById('toast'); function showToast(message, duration = 3000) { toast.textContent = message; toast.classList.add('show'); setTimeout(() => { toast.classList.remove('show'); }, duration); } uploadArea.addEventListener('click', () => fileInput.click()); uploadArea.addEventListener('dragover', (e) => { e.preventDefault(); uploadArea.style.borderColor = '#1e3c72'; uploadArea.style.background = '#e8f0fe'; }); uploadArea.addEventListener('dragleave', () => { uploadArea.style.borderColor = '#cbd5e0'; uploadArea.style.background = 'transparent'; }); uploadArea.addEventListener('drop', (e) => { e.preventDefault(); uploadArea.style.borderColor = '#cbd5e0'; uploadArea.style.background = 'transparent'; const files = e.dataTransfer.files; if (files.length > 0) { uploadFile(files[0]); } }); fileInput.addEventListener('change', (e) => { if (e.target.files.length > 0) { uploadFile(e.target.files[0]); } }); async function uploadFile(file) { const formData = new FormData(); formData.append('file', file); try { showToast('⏳ 正在上传文档...'); const response = await fetch('/api/upload', { method: 'POST', body: formData }); const data = await response.json(); if (data.error) { showToast(`❌ ${data.error}`); return; } loadDocuments(); showToast(`✅ 文档 "${data.name}" 上传成功,正在处理中...`); addMessage('bot', `📄 文档 "${data.name}" 已上传,系统正在智能解析文档内容...`); setTimeout(() => { loadDocuments(); }, 2000); } catch (error) { showToast('❌ 上传失败,请重试'); console.error(error); } } async function loadDocuments() { try { const response = await fetch('/api/documents'); const documents = await response.json(); docCount.textContent = `${documents.length} 个文档`; if (documents.length === 0) { documentList.innerHTML = `
📭

暂无文档

上传文档后即可开始问答

`; return; } documentList.innerHTML = documents.map(doc => `
📄 ${doc.name}
${doc.status === 'processing' ? '⏳ 处理中...' : '✅ 已完成'}
`).join(''); } catch (error) { console.error(error); showToast('❌ 加载文档列表失败'); } } async function deleteDocument(docId) { if (!confirm('确定要删除这个文档吗?')) { return; } try { showToast('⏳ 正在删除文档...'); await fetch(`/api/documents/${docId}`, { method: 'DELETE' }); loadDocuments(); showToast('✅ 文档已删除'); addMessage('bot', '🗑️ 文档已从知识库中删除'); } catch (error) { showToast('❌ 删除失败,请重试'); console.error(error); } } async function askQuestion() { const question = questionInput.value.trim(); if (!question) { showToast('⚠️ 请输入问题'); questionInput.focus(); return; } if (question.length < 3) { showToast('⚠️ 问题太短,请输入至少3个字符'); questionInput.focus(); return; } addMessage('user', question); questionInput.value = ''; updateCharCount(); try { showToast('🤖 正在思考中...'); const response = await fetch('/api/ask', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ question }) }); const data = await response.json(); if (data.error) { showToast(`❌ ${data.error}`); addMessage('bot', `❌ 抱歉,${data.error}`); return; } let answerHtml = `

${data.answer}

`; if (data.sources && data.sources.length > 0) { answerHtml += `
📚 参考来源:
${data.sources.map(source => `
📄 ${source.name} (第${source.page}页)
`).join('')}
`; } showToast('✅ 回答完成'); addMessage('bot', answerHtml); } catch (error) { showToast('❌ 回答问题时出错了,请重试'); addMessage('bot', '❌ 抱歉,回答问题时出错了,请重试'); console.error(error); } } function addMessage(type, content) { const messageDiv = document.createElement('div'); messageDiv.className = `message ${type}`; messageDiv.innerHTML = `
${content}
`; chatMessages.appendChild(messageDiv); chatMessages.scrollTop = chatMessages.scrollHeight; } function updateCharCount() { const length = questionInput.value.length; charCount.textContent = `${length} 字`; if (length > 500) { charCount.style.color = '#e53e3e'; } else if (length > 300) { charCount.style.color = '#d69e2e'; } else { charCount.style.color = '#718096'; } } async function loadConversationHistory() { try { const response = await fetch('/api/conversations'); const conversations = await response.json(); if (conversations.length === 0) { addMessage('bot', '👋 欢迎使用智能知识库问答系统!上传文档后,您可以向我提问任何与文档相关的问题。'); return; } conversations.forEach(conv => { addMessage('user', conv.question); let answerHtml = `

${conv.answer}

`; if (conv.sources && conv.sources.length > 0) { answerHtml += `
📚 参考来源:
${conv.sources.map(source => `
📄 ${source.name} (第${source.page}页)
`).join('')}
`; } addMessage('bot', answerHtml); }); } catch (error) { console.error(error); addMessage('bot', '👋 欢迎使用智能知识库问答系统!上传文档后,您可以向我提问任何与文档相关的问题。'); } } questionInput.addEventListener('input', updateCharCount); questionInput.addEventListener('keydown', (e) => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); askQuestion(); } }); loadDocuments(); loadConversationHistory();