// Ai模型接口 //const API_KEY = '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'; const API_KEY = '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'; const API_URL = 'https://openrouter.ai/api/v1/chat/completions'; let messages = []; // 逐字输出 Markdown 并渲染 async function typeMarkdownEffect(fullText, container) { let currentText = ''; const length = fullText.length; const delay = Math.max(5, 40 - Math.min(length / 1.5, 35)); // 根据长度自动调整速度 for (let i = 0; i < length; i++) { currentText += fullText[i]; const sanitizedHtml = DOMPurify.sanitize(marked.parse(currentText)); container.innerHTML = sanitizedHtml; // 滚动到底部 container.parentElement.scrollTop = container.parentElement.scrollHeight; await new Promise(resolve => setTimeout(resolve, delay)); } } // 修改后的 appendMessage:支持逐字输出 + Markdown function appendMessage(content, sender, isMarkdown = false, withTyping = false) { const chatContainer = document.getElementById('chatContainer'); const messageDiv = document.createElement('div'); messageDiv.classList.add('message', sender); chatContainer.appendChild(messageDiv); chatContainer.scrollTop = chatContainer.scrollHeight; // 处理 AI 打字效果 if (isMarkdown && sender === 'bot' && withTyping) { // 先显示“正在输入中...”提示 messageDiv.innerHTML = `正在输入中...`; // 稍等一下再逐字渲染(比如 50ms) setTimeout(() => { typeMarkdownEffect(content, messageDiv); }, 50); } else if (isMarkdown) { const html = DOMPurify.sanitize(marked.parse(content)); messageDiv.innerHTML = html; } else { messageDiv.textContent = content; } } // 发送消息(主函数) async function sendMessage() { const inputElem = document.getElementById('userInput'); const userMessage = inputElem.value.trim(); if (!userMessage) return; appendMessage(userMessage, 'user'); messages.push({ role: 'user', content: userMessage }); inputElem.value = ''; // 👉 提前显示“正在输入中...”并保存 messageDiv 元素引用 const chatContainer = document.getElementById('chatContainer'); const botMessageDiv = document.createElement('div'); botMessageDiv.classList.add('message', 'bot'); botMessageDiv.innerHTML = `正在输入中...`; chatContainer.appendChild(botMessageDiv); chatContainer.scrollTop = chatContainer.scrollHeight; const payload = { //model: 'deepseek/deepseek-r1:free', model: 'deepseek/deepseek-chat-v3-0324:free', messages: messages }; try { const response = await fetch(API_URL, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + API_KEY }, body: JSON.stringify(payload) }); const data = await response.json(); if (data.choices && data.choices.length > 0) { const botMessage = data.choices[0].message.content; // ✅ 拿到内容后替换 messageDiv 的内容,逐字打字渲染 typeMarkdownEffect(botMessage, botMessageDiv); messages.push({ role: 'assistant', content: botMessage }); } else { botMessageDiv.textContent = '没有收到有效响应,请检查 API 设置。'; } } catch (error) { console.error('请求错误:', error); botMessageDiv.textContent = '请求出错:' + error.message; } }