/* ===== 云大阁网站JavaScript - 修复版 ===== */ // 全局变量 let chatCounter = 0; let isDeepSearchActive = false; let currentChatId = null; let chatHistoryData = new Map(); // 存储聊天历史数据 let isOnlineMode = false; // 是否使用在线模式(连接后端),默认false使用本地存储 // DOM加载完成后执行 document.addEventListener('DOMContentLoaded', function() { // 添加ESC键监听,用于中断流式响应 document.addEventListener('keydown', function(e) { if (e.key === 'Escape') { // 如果正在发送中,执行停止操作 if (window.isSubmitting) { console.log('用户按下ESC,中断请求'); // 中断请求 if (window.currentAbortController) { window.currentAbortController.abort(); window.currentAbortController = null; } // 重置状态 window.isSubmitting = false; // 更新UI if (typeof updateSendUI === 'function') { updateSendUI(false); } else if (window.updateSendUI) { window.updateSendUI(false); } // 显示提示 const statusText = document.querySelector('.status-text'); if (statusText) { statusText.textContent = '已通过ESC取消请求'; setTimeout(() => { statusText.textContent = ''; }, 3000); } // 添加系统提示到聊天窗口 const chatMessages = document.getElementById('chatMessages'); if (chatMessages) { const cancelMsg = document.createElement('div'); cancelMsg.className = 'message-item mb-4'; cancelMsg.innerHTML = `
⚠️ 已通过ESC键取消请求。注意:后端可能仍在处理,建议稍等片刻再发送新请求。
`; chatMessages.appendChild(cancelMsg); // 5秒后自动移除提示 setTimeout(() => { if (cancelMsg.parentNode) { cancelMsg.remove(); } }, 5000); } } } }); // 只初始化核心功能,避免冲突 initSidebar(); initChat(); // initUserDropdown(); // 注释掉,由auth-integration.js处理 initSearch(); initChatHistoryActions(); initTextRotator(); init3DTicker(); initDownloadModal(); initBackground(); // 初始化背景动画 initToolsDropdown(); // 初始化工具下拉菜单 // 确保初始状态下3D图片是显示的 const tickerSection = document.querySelector('.ticker-section'); const ticker3D = document.getElementById('ticker3D'); console.log('检查ticker-section:', tickerSection); console.log('检查ticker3D:', ticker3D); console.log('body是否有chat-mode类:', document.body.classList.contains('chat-mode')); if (tickerSection) { tickerSection.style.display = 'block'; tickerSection.style.visibility = 'visible'; tickerSection.style.opacity = '1'; console.log('设置ticker-section显示'); // 检查computed style const computedStyle = window.getComputedStyle(tickerSection); console.log('ticker-section computed display:', computedStyle.display); console.log('ticker-section computed visibility:', computedStyle.visibility); console.log('ticker-section computed height:', computedStyle.height); } else { console.error('未找到ticker-section元素'); } // 设置侧边栏默认状态 - 默认折叠 const sidebar = document.getElementById('sidebar'); if (sidebar) { // 所有设备默认折叠状态 sidebar.classList.add('collapsed'); } // 页面加载完自动聚焦到输入框 const messageInput = document.getElementById('messageInput'); if (messageInput) { setTimeout(() => { messageInput.focus(); }, 500); } // 初始化聊天管理器监听器 initChatManagerListeners(); // 等待 ChatManager 初始化完成后再加载 const waitForChatManager = () => { if (window.chatManager && window.chatManager.initialized) { console.log('[Main] ChatManager 已初始化,开始加载聊天历史'); // 加载用户的聊天历史 loadUserChatHistory(); // 恢复当前对话 setTimeout(() => { console.log('[Main] 检查是否需要恢复对话...'); console.log('[Main] chatManager.currentChatId:', window.chatManager.currentChatId); if (window.chatManager.currentChatId) { console.log('[Main] 开始恢复上次的对话:', window.chatManager.currentChatId); loadChatHistory(window.chatManager.currentChatId); // 高亮侧边栏中的当前对话 const chatItem = document.querySelector(`[data-chat-id="${window.chatManager.currentChatId}"]`); if (chatItem) { chatItem.classList.add('active'); console.log('[Main] 已高亮当前对话项'); } else { console.log('[Main] ⚠️ 未找到对应的侧边栏对话项'); } } else { console.log('[Main] 没有需要恢复的对话'); } }, 50); } else { console.log('[Main] 等待 ChatManager 初始化...'); setTimeout(waitForChatManager, 100); } }; waitForChatManager(); // 监听用户登录状态变化 initUserChangeListener(); // 初始化Markdown渲染器和工具栏 if (window.markdownRenderer) { window.markdownRenderer.initCodeCopyButtons(); // 确保工具栏被初始化 const welcomeToolbar = document.getElementById('markdownToolbar'); const welcomeInput = document.getElementById('messageInput'); if (welcomeToolbar && welcomeInput) { welcomeToolbar.innerHTML = window.markdownRenderer.createToolbar(); welcomeToolbar.style.display = 'flex'; window.markdownRenderer.attachToolbarEvents(welcomeToolbar, welcomeInput); } } // 初始化工具下拉菜单 initToolsDropdown(); console.log('云大阁网站已加载完成'); }); /* ===== 侧边栏功能 - 复刻duijie.html简单逻辑 + yundage-keyong1的tooltip ===== */ function toggleSidebar() { document.getElementById('sidebar').classList.toggle('collapsed'); } function initSidebar() { // Logo点击切换事件 const logoMenuItem = document.getElementById('logoMenuItem'); if (logoMenuItem) { logoMenuItem.addEventListener('click', function(e) { toggleSidebar(); e.stopPropagation(); }); } // 新建对话按钮事件 const newChatBtn = document.getElementById('newChatBtn'); if (newChatBtn) { newChatBtn.addEventListener('click', function() { console.log('新建对话按钮被点击'); startNewChat(); }); } // 下载APP按钮事件 const downloadAppBtn = document.getElementById('downloadAppBtn'); if (downloadAppBtn) { downloadAppBtn.addEventListener('click', function() { console.log('下载APP按钮被点击'); initDownloadModal(); }); } // 初始化tooltip定位 initTooltipPositioning(); } // ChatGPT风格的tooltip定位 - 将tooltip移动到body避免遮挡 function initTooltipPositioning() { const sidebar = document.getElementById('sidebar'); if (!sidebar) return; // 如果sidebar不存在,直接返回 const tooltipWrappers = sidebar.querySelectorAll('.tooltip-wrapper'); tooltipWrappers.forEach(wrapper => { const tooltipText = wrapper.querySelector('.tooltip-text'); if (!tooltipText) return; let floatingTooltip = null; wrapper.addEventListener('mouseenter', function() { if (sidebar.classList.contains('collapsed')) { // 创建独立的tooltip元素添加到body floatingTooltip = document.createElement('div'); floatingTooltip.textContent = tooltipText.textContent; floatingTooltip.className = 'floating-tooltip'; floatingTooltip.style.cssText = ` position: fixed; background-color: #333; color: #fff; text-align: center; padding: 6px 10px; border-radius: 6px; white-space: nowrap; font-size: 13px; z-index: 999999; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); border: 1px solid rgba(255, 255, 255, 0.1); pointer-events: none; `; // 获取wrapper的位置 const rect = wrapper.getBoundingClientRect(); // 设置tooltip位置 floatingTooltip.style.left = (rect.right + 10) + 'px'; floatingTooltip.style.top = (rect.top + rect.height / 2) + 'px'; floatingTooltip.style.transform = 'translateY(-50%)'; // 添加到body document.body.appendChild(floatingTooltip); } }); wrapper.addEventListener('mouseleave', function() { if (floatingTooltip) { document.body.removeChild(floatingTooltip); floatingTooltip = null; } }); }); } /* ===== 聊天功能相关全局函数 ===== */ // 更新发送UI状态 - 移到全局作用域,同时更新两个界面 function updateSendUI(isLoading) { // 首页元素 const sendIcon = document.getElementById('sendIcon'); const loadingSpinner = document.getElementById('loadingSpinner'); const statusText = document.querySelector('.status-text'); const messageInput = document.getElementById('messageInput'); const sendBtn = document.getElementById('sendBtn'); // 聊天模式元素 const chatModeSendIcon = document.getElementById('chatModeSendIcon'); const chatModeLoadingSpinner = document.getElementById('chatModeLoadingSpinner'); const chatModeMessageInput = document.getElementById('chatModeMessageInput'); const chatModeSendBtn = document.getElementById('chatModeSendBtn'); if (isLoading) { // 强制隐藏loading spinner if (loadingSpinner) { loadingSpinner.style.setProperty('display', 'none', 'important'); loadingSpinner.style.visibility = 'hidden'; } // 显示停止图标 if (sendIcon) { sendIcon.style.display = 'block'; sendIcon.style.visibility = 'visible'; // 将SVG图标改为停止图标(红色正方形) sendIcon.innerHTML = ''; sendIcon.style.color = '#dc3545'; // 确保按钮可点击 if (sendBtn) { sendBtn.style.cursor = 'pointer'; sendBtn.disabled = false; // 确保按钮不被禁用 } } if (statusText) statusText.textContent = 'AI is thinking...'; if (messageInput) messageInput.disabled = true; // 更新聊天模式UI - 同样显示停止图标 if (chatModeLoadingSpinner) { chatModeLoadingSpinner.style.setProperty('display', 'none', 'important'); chatModeLoadingSpinner.style.visibility = 'hidden'; } if (chatModeSendIcon) { chatModeSendIcon.style.display = 'block'; chatModeSendIcon.style.visibility = 'visible'; // 对于SVG元素,设置停止图标(红色方块) chatModeSendIcon.innerHTML = ''; chatModeSendIcon.style.color = '#dc3545'; // 确保SVG的fill属性生效 chatModeSendIcon.setAttribute('fill', '#dc3545'); chatModeSendIcon.setAttribute('stroke', 'none'); } if (chatModeSendBtn) { chatModeSendBtn.style.cursor = 'pointer'; chatModeSendBtn.disabled = false; // 确保按钮可点击以便停止 } if (chatModeMessageInput) chatModeMessageInput.disabled = true; } else { // 恢复发送图标 if (sendIcon) { sendIcon.style.display = 'block'; // 恢复原始的SVG发送图标 sendIcon.innerHTML = ''; sendIcon.style.color = '#999'; } if (loadingSpinner) { loadingSpinner.style.setProperty('display', 'none', 'important'); } if (statusText) statusText.textContent = 'Ready to submit!'; if (messageInput) messageInput.disabled = false; // 更新发送按钮状态 const hasText = messageInput && messageInput.value.trim().length > 0; if (sendIcon) { sendIcon.style.opacity = hasText && !window.isSubmitting ? '1' : '0.3'; } // 更新聊天模式UI - 恢复发送图标 if (chatModeLoadingSpinner) { chatModeLoadingSpinner.style.setProperty('display', 'none', 'important'); } if (chatModeSendIcon) { chatModeSendIcon.style.display = 'block'; // 恢复原始的发送图标 chatModeSendIcon.innerHTML = ''; chatModeSendIcon.style.color = '#999'; // 恢复SVG的默认属性 chatModeSendIcon.setAttribute('fill', 'none'); chatModeSendIcon.setAttribute('stroke', 'currentColor'); } if (chatModeSendBtn) { chatModeSendBtn.style.cursor = 'pointer'; } if (chatModeMessageInput) chatModeMessageInput.disabled = false; // 更新聊天模式按钮状态 const chatHasText = chatModeMessageInput && chatModeMessageInput.value.trim().length > 0; if (chatModeSendIcon) { chatModeSendIcon.style.opacity = chatHasText && !window.isSubmitting ? '1' : '0.3'; } } } // 将updateSendUI暴露到全局 window.updateSendUI = updateSendUI; /* ===== 聊天功能 ===== */ function initChat() { const sendBtn = document.getElementById('sendBtn'); const messageInput = document.getElementById('messageInput'); const chatMessages = document.getElementById('chatMessages'); const deepSearchToggle = document.getElementById('deepSearchToggle'); const newChatBtn = document.getElementById('newChatBtn'); const voiceBtn = document.getElementById('voiceBtn'); // 聊天模式元素 const chatModeSendBtn = document.getElementById('chatModeSendBtn'); const chatModeMessageInput = document.getElementById('chatModeMessageInput'); if (!sendBtn || !messageInput || !chatMessages) { console.error('关键聊天元素未找到'); return; } // 初始化发送按钮状态 updateSendButtonState(); // 发送消息 - 支持停止功能 sendBtn.addEventListener('click', function(e) { e.preventDefault(); e.stopPropagation(); console.log('发送按钮被点击,当前状态:', window.isSubmitting); // 如果正在发送中,执行停止操作 if (window.isSubmitting) { console.log('正在发送中,尝试停止...'); // 中断请求 if (window.currentAbortController) { console.log('找到AbortController,执行中断'); window.currentAbortController.abort(); window.currentAbortController = null; } // 更新状态显示为已取消 if (window.currentStatusDisplay) { window.currentStatusDisplay.updateStatus({ type: 'cancelled' }); // 清除引用 window.currentStatusDisplay = null; } // 重置状态 window.isSubmitting = false; updateSendUI(false); // 显示提示 const statusText = document.querySelector('.status-text'); if (statusText) { statusText.textContent = '已取消请求'; setTimeout(() => { statusText.textContent = ''; }, 3000); } // 添加系统提示到聊天窗口 const chatMessages = document.getElementById('chatMessages'); if (chatMessages) { const cancelMsg = document.createElement('div'); cancelMsg.className = 'message-item mb-4'; cancelMsg.innerHTML = `
⚠️ 请求已取消。注意:后端可能仍在处理,建议稍等片刻再发送新请求。
`; chatMessages.appendChild(cancelMsg); // 5秒后自动移除提示 setTimeout(() => { if (cancelMsg.parentNode) { cancelMsg.remove(); } }, 5000); } } else { // 正常发送消息 console.log('发送按钮被点击'); sendMessage(); } }); // 回车发送消息(Shift+Enter换行) messageInput.addEventListener('keydown', function(e) { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); sendMessage(); } }); // 监听输入框变化,更新发送按钮状态和自动调整高度 messageInput.addEventListener('input', function() { updateSendButtonState(); autoResizeTextarea(this); }); // 深度检索切换 if (deepSearchToggle) { deepSearchToggle.addEventListener('click', function() { console.log('深度检索按钮被点击'); toggleDeepSearch(); }); } // 删除重复的事件监听器绑定,前面已经绑定过了 // 语音按钮(暂时无功能) if (voiceBtn) { voiceBtn.addEventListener('click', function() { console.log('语音按钮被点击'); // 这里可以添加语音功能 }); } // 聊天模式输入框事件监听器 if (chatModeSendBtn && chatModeMessageInput) { // 发送消息 - 支持停止功能 chatModeSendBtn.addEventListener('click', function(e) { e.preventDefault(); e.stopPropagation(); console.log('聊天模式发送按钮被点击,当前状态:', window.isSubmitting); // 如果正在发送中,执行停止操作 if (window.isSubmitting) { console.log('聊天模式:正在发送中,尝试停止...'); // 中断请求 if (window.currentAbortController) { console.log('聊天模式:找到AbortController,执行中断'); window.currentAbortController.abort(); window.currentAbortController = null; } // 更新状态显示为已取消 if (window.currentStatusDisplay) { window.currentStatusDisplay.updateStatus({ type: 'cancelled' }); // 清除引用 window.currentStatusDisplay = null; } // 重置状态 window.isSubmitting = false; updateSendUI(false); // 添加系统提示到聊天窗口 const chatMessages = document.getElementById('chatMessages'); if (chatMessages) { const cancelMsg = document.createElement('div'); cancelMsg.className = 'message-item mb-4'; cancelMsg.innerHTML = `
⚠️ 请求已取消。注意:后端可能仍在处理,建议稍等片刻再发送新请求。
`; chatMessages.appendChild(cancelMsg); // 5秒后自动移除提示 setTimeout(() => { if (cancelMsg.parentNode) { cancelMsg.remove(); } }, 5000); } } else { // 正常发送消息 sendChatModeMessage(); } }); // 回车发送消息 chatModeMessageInput.addEventListener('keydown', function(e) { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); sendChatModeMessage(); } }); // 监听输入框变化 chatModeMessageInput.addEventListener('input', function() { updateChatModeSendButtonState(); autoResizeTextarea(this); }); } // 更新发送按钮状态 function updateSendButtonState() { const messageInput = document.getElementById('messageInput'); const sendBtn = document.getElementById('sendBtn'); const sendIcon = document.getElementById('sendIcon'); if (messageInput && sendBtn && sendIcon) { const hasText = messageInput.value.trim().length > 0; sendIcon.style.opacity = hasText && !window.isSubmitting ? '1' : '0.3'; } } // 聊天模式按钮状态管理 function updateChatModeSendButtonState() { const chatModeMessageInput = document.getElementById('chatModeMessageInput'); const chatModeSendIcon = document.getElementById('chatModeSendIcon'); if (chatModeMessageInput && chatModeSendIcon) { const hasText = chatModeMessageInput.value.trim().length > 0; chatModeSendIcon.style.opacity = hasText && !window.isSubmitting ? '1' : '0.3'; } } // 聊天模式发送消息 async function sendChatModeMessage() { const chatModeMessageInput = document.getElementById('chatModeMessageInput'); const message = chatModeMessageInput.value.trim(); if (!message || window.isSubmitting) { console.log('消息为空或正在发送中,不发送'); return; } console.log('聊天模式发送消息:', message); // 设置发送状态 window.isSubmitting = true; updateChatModeSendUI(true); // 如果是第一条消息且没有当前聊天ID,创建新聊天 if (!currentChatId) { // 立即创建新的聊天会话 if (window.chatManager) { currentChatId = window.chatManager.createChat(message); window.chatManager.currentChatId = currentChatId; // 立即添加到侧边栏 const chatTitle = message.length > 20 ? message.substring(0, 20) + '...' : message; addChatToSidebar(currentChatId, chatTitle, true); } } // 保存当前聊天ID,避免切换聊天记录时被改变 const targetChatId = currentChatId; // 添加用户消息 await addMessage(message, 'user'); // 清空输入框 chatModeMessageInput.value = ''; autoResizeTextarea(chatModeMessageInput); updateChatModeSendButtonState(); // 调用后端API获取AI回复 try { // 判断是否使用流式响应 const useStream = true; // 可以根据需要调整 if (useStream) { // 流式响应 let aiMessageId = null; let aiContent = ''; // 获取工具设置 const toolsSettings = window.getToolsSettings ? window.getToolsSettings() : { deepResearch: false, showThinking: false }; const isDeepResearch = toolsSettings.deepResearch; const showThinking = toolsSettings.showThinking; // 创建状态显示组件 let statusDisplay = null; if (window.StreamStatusDisplay) { // 在消息区域之前创建状态显示容器 const statusContainer = document.createElement('div'); statusContainer.id = `status-${targetChatId}-${Date.now()}`; chatMessages.appendChild(statusContainer); statusDisplay = new window.StreamStatusDisplay(statusContainer); // 保存到全局,以便停止时可以更新状态 window.currentStatusDisplay = statusDisplay; } // 保存AbortController到全局,以便中断 window.currentAbortController = window.ChatAPIService.sendMessageStream( { message: message, conversationId: targetChatId, // 使用保存的targetChatId mode: isDeepSearchActive ? 'research' : 'chat', deepResearch: isDeepResearch, showThinking: showThinking }, // onMessage: 接收消息片段 (content) => { // 只有当前聊天ID与目标ID一致时才更新UI if (currentChatId === targetChatId) { aiContent += content; if (aiMessageId) { // 更新已存在的消息 updateMessageContent(aiMessageId, aiContent); } else { // 创建新消息 aiMessageId = Date.now().toString(); addStreamMessage(aiContent, 'ai', aiMessageId); } } else { // 如果已切换到其他聊天,仅累积内容但不更新UI aiContent += content; } }, // onComplete: 完成回调 async (data) => { console.log('流式响应完成:', data); // 使用保存的targetChatId保存AI回复到正确的聊天记录 if (window.chatManager && targetChatId) { // 保存到目标聊天记录 const originalChatId = window.chatManager.currentChatId; window.chatManager.currentChatId = targetChatId; window.chatManager.addMessage(aiContent, 'ai'); // 如果当前聊天已切换,不需要恢复 if (currentChatId !== targetChatId) { window.chatManager.currentChatId = originalChatId; } } // 恢复发送状态 window.isSubmitting = false; updateChatModeSendUI(false); }, // onError: 错误回调 (error) => { console.error('流式响应错误:', error); addMessage(`抱歉,发生了错误:${error.message}`, 'ai'); window.isSubmitting = false; updateChatModeSendUI(false); }, // onThinking: 思考过程回调 showThinking ? (thinking) => { console.log('思考过程:', thinking); // 显示思考过程 if (!document.getElementById('thinking-message')) { const thinkingDiv = document.createElement('div'); thinkingDiv.id = 'thinking-message'; thinkingDiv.className = 'thinking-process'; thinkingDiv.innerHTML = `
🤔 思考过程:
`; chatMessages.appendChild(thinkingDiv); chatMessages.scrollTop = chatMessages.scrollHeight; } const thinkingContent = document.querySelector('#thinking-message .thinking-content'); if (thinkingContent) { thinkingContent.textContent += thinking; } } : null, // onStatus: 状态更新回调(新增) (status) => { if (statusDisplay) { statusDisplay.updateStatus(status); } } ); } else { // 同步响应 const response = await window.ChatAPIService.sendMessage({ message: message, conversationId: targetChatId, // 使用保存的targetChatId mode: isDeepSearchActive ? 'research' : 'chat' }); if (response.success) { // 更新会话ID(如果是新会话) if (response.conversationId && !targetChatId) { const newChatId = response.conversationId; // 只有当前聊天与目标一致时才更新全局变量 if (currentChatId === targetChatId) { currentChatId = newChatId; } if (window.chatManager) { window.chatManager.currentChatId = newChatId; } // 添加新会话到侧边栏 const chatTitle = message.length > 20 ? message.substring(0, 20) + '...' : message; addChatToSidebar(newChatId, chatTitle, true); } // 使用addMessageToChat统一处理AI回复 await addMessageToChat(response.answer, 'ai', targetChatId); } else { // 使用addMessageToChat统一处理错误消息 await addMessageToChat('抱歉,获取回复时出现错误。', 'ai', targetChatId); } // 恢复发送状态 window.isSubmitting = false; updateChatModeSendUI(false); } } catch (error) { console.error('发送消息失败:', error); // 使用addMessageToChat统一处理错误消息 await addMessageToChat(`抱歉,发生了错误:${error.message}`, 'ai', targetChatId); window.isSubmitting = false; updateChatModeSendUI(false); } // 重新聚焦输入框 chatModeMessageInput.focus(); } // 聊天模式UI状态更新 - 直接调用全局的updateSendUI function updateChatModeSendUI(isLoading) { updateSendUI(isLoading); } // 自动调整输入框高度(参考ChatGPT/DeepSeek) function autoResizeTextarea(textarea) { // 检查是否是欢迎模式的输入框(有特殊的最小高度) if (textarea.id === 'messageInput') { // 欢迎模式输入框保持固定高度124px,不自动调整 return; } // 聊天模式输入框自动调整高度 // 重置高度以获取正确的scrollHeight textarea.style.height = '40px'; // 计算新高度 const newHeight = Math.min(textarea.scrollHeight, 120); // 最大120px textarea.style.height = newHeight + 'px'; // 如果内容超过最大高度,显示滚动条 if (textarea.scrollHeight > 120) { textarea.style.overflowY = 'auto'; } else { textarea.style.overflowY = 'hidden'; } } async function sendMessage() { const message = messageInput.value.trim(); if (!message || window.isSubmitting) { console.log('消息为空或正在发送中,不发送'); return; } console.log('发送消息:', message); // 设置发送状态 window.isSubmitting = true; updateSendUI(true); // 显示聊天容器 showChatContainer(); // 如果是第一条消息且没有当前聊天ID,创建新聊天 if (!currentChatId) { // 立即创建新的聊天会话 if (window.chatManager) { currentChatId = window.chatManager.createChat(message); window.chatManager.currentChatId = currentChatId; // 立即添加到侧边栏 const chatTitle = message.length > 20 ? message.substring(0, 20) + '...' : message; addChatToSidebar(currentChatId, chatTitle, true); } } // 保存当前聊天ID,避免切换聊天记录时被改变 const targetChatId = currentChatId; // 添加用户消息(使用固定的chatId) await addMessageToChat(message, 'user', targetChatId); // 清空输入框并重置高度 messageInput.value = ''; // 欢迎模式输入框保持124px高度 if (messageInput.id === 'messageInput') { messageInput.style.height = '124px'; } else { messageInput.style.height = '40px'; } updateSendButtonState(); // 调用后端API获取AI回复 try { // 判断是否使用流式响应 const useStream = true; // 可以根据需要调整 if (useStream) { // 流式响应 let aiMessageId = null; let aiContent = ''; // 获取工具设置 const toolsSettings = window.getToolsSettings ? window.getToolsSettings() : { deepResearch: false, showThinking: false }; const isDeepResearch = toolsSettings.deepResearch; const showThinking = toolsSettings.showThinking; // 创建状态显示组件 let statusDisplay = null; if (window.StreamStatusDisplay) { // 在消息区域之前创建状态显示容器 const statusContainer = document.createElement('div'); statusContainer.id = `status-${targetChatId}-${Date.now()}`; chatMessages.appendChild(statusContainer); statusDisplay = new window.StreamStatusDisplay(statusContainer); // 保存到全局,以便停止时可以更新状态 window.currentStatusDisplay = statusDisplay; } // 保存AbortController到全局,以便中断 window.currentAbortController = window.ChatAPIService.sendMessageStream( { message: message, conversationId: targetChatId, // 使用保存的targetChatId mode: isDeepSearchActive ? 'research' : 'chat', deepResearch: isDeepResearch, showThinking: showThinking }, // onMessage: 接收消息片段 (content) => { // 只有当前聊天ID与目标ID一致时才更新UI if (currentChatId === targetChatId) { aiContent += content; if (aiMessageId) { // 更新已存在的消息 updateMessageContent(aiMessageId, aiContent); } else { // 创建新消息 aiMessageId = Date.now().toString(); addStreamMessage(aiContent, 'ai', aiMessageId); } } else { // 如果已切换到其他聊天,仅累积内容但不更新UI aiContent += content; } }, // onComplete: 完成回调 async (data) => { console.log('流式响应完成:', data); // 使用保存的targetChatId保存AI回复到正确的聊天记录 if (window.chatManager && targetChatId) { // 保存到目标聊天记录 const originalChatId = window.chatManager.currentChatId; window.chatManager.currentChatId = targetChatId; window.chatManager.addMessage(aiContent, 'ai'); // 如果当前聊天已切换,不需要恢复 if (currentChatId !== targetChatId) { window.chatManager.currentChatId = originalChatId; } } // 恢复发送状态 window.isSubmitting = false; updateSendUI(false); // 清除状态显示引用 window.currentStatusDisplay = null; }, // onError: 错误回调 (error) => { console.error('流式响应错误:', error); addMessage(`抱歉,发生了错误:${error.message}`, 'ai'); window.isSubmitting = false; updateSendUI(false); // 清除状态显示引用 window.currentStatusDisplay = null; }, // onThinking: 思考过程回调 showThinking ? (thinking) => { console.log('思考过程:', thinking); // 显示思考过程 if (!document.getElementById('thinking-message')) { const thinkingDiv = document.createElement('div'); thinkingDiv.id = 'thinking-message'; thinkingDiv.className = 'thinking-process'; thinkingDiv.innerHTML = `
🤔 思考过程:
`; chatMessages.appendChild(thinkingDiv); chatMessages.scrollTop = chatMessages.scrollHeight; } const thinkingContent = document.querySelector('#thinking-message .thinking-content'); if (thinkingContent) { thinkingContent.textContent += thinking; } } : null, // onStatus: 状态更新回调(新增) (status) => { if (statusDisplay) { statusDisplay.updateStatus(status); } } ); } else { // 同步响应 const response = await window.ChatAPIService.sendMessage({ message: message, conversationId: targetChatId, // 使用保存的targetChatId mode: isDeepSearchActive ? 'research' : 'chat' }); if (response.success) { // 更新会话ID(如果是新会话) if (response.conversationId && !targetChatId) { const newChatId = response.conversationId; // 只有当前聊天与目标一致时才更新全局变量 if (currentChatId === targetChatId) { currentChatId = newChatId; } if (window.chatManager) { window.chatManager.currentChatId = newChatId; } // 添加新会话到侧边栏 const chatTitle = message.length > 20 ? message.substring(0, 20) + '...' : message; addChatToSidebar(newChatId, chatTitle, true); } // 使用addMessageToChat统一处理AI回复 await addMessageToChat(response.answer, 'ai', targetChatId); } else { // 使用addMessageToChat统一处理错误消息 await addMessageToChat('抱歉,获取回复时出现错误。', 'ai', targetChatId); } // 恢复发送状态 window.isSubmitting = false; updateSendUI(false); } } catch (error) { console.error('发送消息失败:', error); // 使用addMessageToChat统一处理错误消息 await addMessageToChat(`抱歉,发生了错误:${error.message}`, 'ai', targetChatId); window.isSubmitting = false; updateSendUI(false); } // 重新聚焦输入框 messageInput.focus(); } // 新增: 添加消息到指定的聊天记录 async function addMessageToChat(content, type, chatId) { // 确保聊天容器已显示 showChatContainer(); // 使用新的聊天管理器 if (window.chatManager && chatId) { // 只有登录用户才保存聊天记录 if (window.chatManager.getCurrentUser()) { // 临时切换到目标聊天ID const originalChatId = window.chatManager.currentChatId; window.chatManager.currentChatId = chatId; const message = window.chatManager.addMessage(content, type); // 恢复原来的聊天ID window.chatManager.currentChatId = originalChatId; } // 如果启用了在线模式,同步到服务器 if (isOnlineMode && window.ChatAPIService) { try { await window.ChatAPIService.addMessage(chatId, { content, type, metadata: {} }); } catch (error) { console.error('同步消息到服务器失败:', error); } } } else { // 兼容旧的存储方式 if (chatId && chatHistoryData.has(chatId)) { const chatHistory = chatHistoryData.get(chatId); chatHistory.push({ content: content, type: type, timestamp: new Date().toISOString() }); chatHistoryData.set(chatId, chatHistory); } } // 只有当前聊天ID与目标ID一致时才更新UI(不保存数据,避免重复) if (chatId === currentChatId) { await addMessageToUI(content, type); } } // 新增: 只更新UI的函数(不保存数据) async function addMessageToUI(content, type) { // 确保聊天容器已显示 showChatContainer(); // 获取聊天消息容器 const chatMessages = document.getElementById('chatMessages'); if (!chatMessages) { console.error('聊天消息容器未找到'); return; } const messageItem = document.createElement('div'); messageItem.className = 'message-item mb-4'; const isUser = type === 'user'; const currentTime = new Date().toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' }); // 渲染内容(支持Markdown) let renderedContent = content; if (window.markdownRenderer) { renderedContent = window.markdownRenderer.render(content); } if (isUser) { messageItem.innerHTML = `
${renderedContent}
${currentTime}
`; } else { messageItem.innerHTML = `
${renderedContent}
${currentTime}
`; } chatMessages.appendChild(messageItem); chatMessages.scrollTop = chatMessages.scrollHeight; } async function addMessage(content, type) { // 确保聊天容器已显示 showChatContainer(); // 使用新的聊天管理器 if (window.chatManager && currentChatId) { // 只有登录用户才保存聊天记录 if (window.chatManager.getCurrentUser()) { const message = window.chatManager.addMessage(content, type); } // 如果启用了在线模式,同步到服务器 if (isOnlineMode && window.ChatAPIService) { try { await window.ChatAPIService.addMessage(currentChatId, { content, type, metadata: {} }); } catch (error) { console.error('同步消息到服务器失败:', error); } } } else { // 兼容旧的存储方式 if (currentChatId && chatHistoryData.has(currentChatId)) { const chatHistory = chatHistoryData.get(currentChatId); chatHistory.push({ content: content, type: type, timestamp: new Date().toISOString() }); chatHistoryData.set(currentChatId, chatHistory); } } // 获取聊天消息容器 const chatMessages = document.getElementById('chatMessages'); if (!chatMessages) { console.error('聊天消息容器未找到'); return; } const messageItem = document.createElement('div'); messageItem.className = 'message-item mb-4'; const isUser = type === 'user'; const currentTime = new Date().toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' }); // 渲染内容(支持Markdown) let renderedContent = content; if (window.markdownRenderer) { renderedContent = window.markdownRenderer.render(content); } if (isUser) { messageItem.innerHTML = `
${renderedContent}
${currentTime}
`; } else { messageItem.innerHTML = `
${renderedContent}
${currentTime}
`; } chatMessages.appendChild(messageItem); chatMessages.scrollTop = chatMessages.scrollHeight; } } // 添加流式消息(用于实时更新) function addStreamMessage(content, type, messageId) { const chatMessages = document.getElementById('chatMessages'); if (!chatMessages) { console.error('聊天消息容器未找到'); return; } let messageItem = document.getElementById(`message-${messageId}`); if (!messageItem) { // 创建新消息元素 messageItem = document.createElement('div'); messageItem.id = `message-${messageId}`; messageItem.className = 'message-item mb-4'; chatMessages.appendChild(messageItem); } const currentTime = new Date().toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' }); // 渲染内容(支持Markdown) let renderedContent = content; if (window.markdownRenderer) { renderedContent = window.markdownRenderer.render(content); } messageItem.innerHTML = `
${renderedContent}
${currentTime}
`; chatMessages.scrollTop = chatMessages.scrollHeight; } // 更新消息内容(用于流式更新) function updateMessageContent(messageId, content) { const messageItem = document.getElementById(`message-${messageId}`); if (!messageItem) return; const contentDiv = messageItem.querySelector('.markdown-content'); if (!contentDiv) return; // 渲染内容(支持Markdown) let renderedContent = content; if (window.markdownRenderer) { renderedContent = window.markdownRenderer.render(content); } contentDiv.innerHTML = renderedContent; // 保持滚动在底部 const chatMessages = document.getElementById('chatMessages'); if (chatMessages) { chatMessages.scrollTop = chatMessages.scrollHeight; } } /* ===== 深度检索功能 ===== */ function toggleDeepSearch() { isDeepSearchActive = !isDeepSearchActive; const deepSearchToggle = document.getElementById('deepSearchToggle'); if (deepSearchToggle) { if (isDeepSearchActive) { deepSearchToggle.classList.add('active'); deepSearchToggle.style.backgroundColor = '#dbeafe'; deepSearchToggle.style.borderColor = '#3b82f6'; deepSearchToggle.style.color = '#1d4ed8'; } else { deepSearchToggle.classList.remove('active'); deepSearchToggle.style.backgroundColor = ''; deepSearchToggle.style.borderColor = ''; deepSearchToggle.style.color = ''; } } console.log('深度检索状态:', isDeepSearchActive); } /* ===== 用户下拉菜单 ===== */ function initUserDropdown() { const userMenuToggle = document.getElementById('userMenuToggle'); const userDropdown = document.getElementById('userDropdown'); if (!userMenuToggle || !userDropdown) return; userMenuToggle.addEventListener('click', function(e) { e.stopPropagation(); console.log('用户菜单被点击'); toggleDropdown(); }); // 点击其他地方关闭下拉菜单 document.addEventListener('click', function(e) { if (!userDropdown.contains(e.target)) { closeDropdown(); } }); function toggleDropdown() { if (userDropdown.classList.contains('hidden')) { userDropdown.classList.remove('hidden'); console.log('打开用户下拉菜单'); } else { userDropdown.classList.add('hidden'); console.log('关闭用户下拉菜单'); } } function closeDropdown() { userDropdown.classList.add('hidden'); } } /* ===== 下载弹窗功能 ===== */ function initDownloadModal() { const downloadBtn = document.getElementById('downloadBtn'); const downloadAppBtn = document.getElementById('downloadAppBtn'); const downloadModal = document.getElementById('downloadModal'); const closeDownloadModal = document.getElementById('closeDownloadModal'); if (!downloadModal || !closeDownloadModal) return; // 折叠栏下载按钮点击事件 if (downloadBtn) { downloadBtn.addEventListener('click', function(e) { e.preventDefault(); downloadModal.classList.remove('hidden'); }); } // 侧边栏下载APP按钮点击事件 if (downloadAppBtn) { downloadAppBtn.addEventListener('click', function(e) { e.preventDefault(); downloadModal.classList.remove('hidden'); }); } // 关闭下载弹窗 closeDownloadModal.addEventListener('click', function(e) { e.preventDefault(); downloadModal.classList.add('hidden'); }); // 点击遮罩层关闭弹窗 downloadModal.addEventListener('click', function(e) { if (e.target === downloadModal) { downloadModal.classList.add('hidden'); } }); } /* ===== 搜索功能 ===== */ function initSearch() { const searchInput = document.getElementById('searchInput'); if (!searchInput) return; searchInput.addEventListener('input', function() { const searchTerm = this.value.toLowerCase().trim(); const chatItems = document.querySelectorAll('.chat-item'); chatItems.forEach(item => { const text = item.textContent.toLowerCase(); if (text.includes(searchTerm) || searchTerm === '') { item.style.display = ''; } else { item.style.display = 'none'; } }); console.log('搜索:', searchTerm); }); } /* ===== 聊天历史功能 ===== */ function initChatHistoryActions() { const chatItems = document.querySelectorAll('.chat-item'); chatItems.forEach(item => { // 点击聊天项 item.addEventListener('click', function(e) { if (!e.target.classList.contains('delete-chat')) { selectChatItem(this); console.log('选择聊天记录:', this.textContent.trim()); } }); // 删除按钮 const deleteBtn = item.querySelector('.delete-chat'); if (deleteBtn) { deleteBtn.addEventListener('click', function(e) { e.stopPropagation(); deleteChatSession(item); console.log('删除聊天记录'); }); } }); } function selectChatItem(item) { // 移除其他active状态 document.querySelectorAll('.chat-history-item').forEach(chatItem => { chatItem.classList.remove('active'); }); // 添加active状态 item.classList.add('active'); // 获取聊天ID const chatId = item.getAttribute('data-chat-id'); // 显示聊天容器 showChatContainer(); // 加载对话内容 if (chatId) { loadChatHistory(chatId); console.log('加载聊天历史:', chatId); } } function deleteChatSession(item) { if (confirm('确定要删除这个对话吗?')) { item.remove(); } } /* ===== 新建对话 ===== */ function startNewChat() { // 清除active状态 document.querySelectorAll('.chat-history-item').forEach(item => { item.classList.remove('active'); }); // 移除聊天模式类 document.body.classList.remove('chat-mode'); // 切换回欢迎模式 const chatContainer = document.getElementById('chatContainer'); const welcomeMode = document.getElementById('welcomeMode'); const chatModeInput = document.getElementById('chatModeInput'); const tickerSection = document.querySelector('.ticker-section'); // 3D新闻卡片区域 if (chatContainer) { chatContainer.style.display = 'none'; // 恢复动画和轮播 if (window.chatModeOptimizer) { window.chatModeOptimizer.resume(); } } if (welcomeMode) { welcomeMode.style.display = 'flex'; // 使用flex保持居中布局 } if (chatModeInput) { chatModeInput.classList.add('hidden'); chatModeInput.style.display = 'none'; // 确保完全隐藏 } // 显示3D新闻卡片区域 if (tickerSection) { tickerSection.style.display = 'block'; } // 如果当前正在等待中,保持等待状态 if (window.isSubmitting) { // 确保首页也显示等待状态 updateSendUI(true); console.log('返回首页,保持等待状态'); } // 重置当前聊天ID currentChatId = null; // 使用聊天管理器开始新聊天 if (window.chatManager) { window.chatManager.startNewChat(); } // 聚焦输入框 const messageInput = document.getElementById('messageInput'); if (messageInput) { messageInput.focus(); } console.log('开始新对话,恢复欢迎界面和3D图片'); // 重新初始化文字轮播(延迟执行确保DOM已更新) setTimeout(() => { console.log('重新初始化文字轮播...'); initTextRotator(); }, 300); } /* ===== 辅助函数 ===== */ function showChatContainer() { const chatContainer = document.getElementById('chatContainer'); const welcomeMode = document.getElementById('welcomeMode'); const chatModeInput = document.getElementById('chatModeInput'); const chatMessages = document.getElementById('chatMessages'); const bottomFunctionArea = document.querySelector('.flex-shrink-0'); // 底部功能区 const tickerSection = document.querySelector('.ticker-section'); // 3D新闻卡片区域 if (chatContainer && welcomeMode && chatModeInput) { // 添加聊天模式类到body document.body.classList.add('chat-mode'); // 隐藏欢迎模式 welcomeMode.style.display = 'none'; // 隐藏底部功能区 if (bottomFunctionArea) { bottomFunctionArea.style.display = 'none'; } // 隐藏3D新闻卡片区域 if (tickerSection) { tickerSection.style.display = 'none'; console.log('showChatContainer: 隐藏3D图片'); } else { console.log('showChatContainer: 未找到ticker-section'); } // 显示聊天容器(全屏) chatContainer.style.display = 'block'; // 优化聊天模式性能 - 暂停动画和轮播 if (window.chatModeOptimizer) { window.chatModeOptimizer.pause(); } // 确保聊天消息容器可见 if (chatMessages) { chatMessages.classList.remove('hidden'); } // 显示底部固定输入框 chatModeInput.classList.remove('hidden'); chatModeInput.style.display = 'block'; // 确保显示 // 如果当前正在提交消息,确保聊天模式也显示等待状态 if (window.isSubmitting) { // 使用统一的updateSendUI函数来同步两个界面的状态 updateSendUI(true); } console.log('切换到聊天模式:隐藏欢迎区、3D图片和底部功能区,输入框下沉到底部,聊天窗口全屏显示'); } } async function createNewChatSession(firstMessage) { // 使用后端会话管理,不再创建本地会话ID // 会话ID将在第一次发送消息后由后端返回 console.log('准备创建新会话,等待后端返回会话ID'); // 清空当前会话ID,让后端创建新会话 currentChatId = null; // 如果使用本地聊天管理器(离线模式) if (window.chatManager && !window.ChatAPIService) { const chatId = window.chatManager.createChat(firstMessage); const chat = window.chatManager.getChat(chatId); const chatTitle = chat ? chat.title : '新对话'; // 添加到侧边栏 addChatToSidebar(chatId, chatTitle); return chatId; } // 使用后端API时,返回null,会话ID将在第一次消息响应时获得 return null; } function addChatToSidebar(chatId, title, shouldSelect = false) { const chatHistory = document.querySelector('.chat-history-list'); if (!chatHistory) return; // 检查会话是否已经存在于侧边栏 const existingItem = chatHistory.querySelector(`[data-chat-id="${chatId}"]`); if (existingItem) { console.log(`会话 ${chatId} 已存在于侧边栏,跳过添加`); // 如果需要选中,直接选中现有项 if (shouldSelect) { existingItem.click(); } return; } // 创建新的聊天项 const chatItem = document.createElement('div'); chatItem.className = 'chat-history-item'; chatItem.setAttribute('data-chat-id', chatId); chatItem.innerHTML = `
${title}
`; // 添加鼠标悬停显示删除按钮 chatItem.addEventListener('mouseenter', function() { const deleteBtn = this.querySelector('.delete-chat'); if (deleteBtn) deleteBtn.style.display = 'block'; }); chatItem.addEventListener('mouseleave', function() { const deleteBtn = this.querySelector('.delete-chat'); if (deleteBtn) deleteBtn.style.display = 'none'; }); // 添加事件监听器 chatItem.addEventListener('click', function(e) { if (!e.target.classList.contains('delete-chat') && !e.target.closest('.delete-chat')) { selectChatItem(this); console.log('选择聊天记录:', title); // 切换到选中的聊天 if (window.chatManager) { const switched = window.chatManager.switchToChat(chatId); console.log('切换聊天结果:', switched); if (!switched) { console.error('聊天切换失败,聊天ID不存在:', chatId); } } else { // 兼容旧方式 loadChatHistory(chatId); } } }); const deleteBtn = chatItem.querySelector('.delete-chat'); if (deleteBtn) { deleteBtn.addEventListener('click', function(e) { e.stopPropagation(); // 使用新的聊天管理器删除 if (window.chatManager) { const confirmDelete = confirm('确定要删除这个聊天记录吗?'); if (confirmDelete) { window.chatManager.deleteChat(chatId); console.log('删除聊天记录:', chatId); } } else { // 兼容旧方式 deleteChatSession(chatItem); console.log('删除聊天记录'); } }); } // 将新聊天添加到"今天"分组的第一项 const todaySection = chatHistory; todaySection.insertBefore(chatItem, todaySection.firstChild); // 只在需要时选中聊天(比如新创建时) if (shouldSelect) { selectChatItem(chatItem); } } function generateAIResponse(message) { // 根据用户输入生成包含Markdown格式的响应 const markdownResponses = [ `感谢您的提问!我正在为您分析这个问题。 ## 主要观点 1. **第一点**:这是一个重要的考虑因素 2. **第二点**:需要注意相关的细节 3. **第三点**:可以从多个角度来理解 ### 补充说明 > 这是一段引用,包含了一些额外的信息。 您还有其他问题吗?`, `这是一个很有趣的话题,让我为您详细解答。 ### 关键概念 - **概念A**:基础定义和说明 - **概念B**:深入理解的要点 - **概念C**:实际应用场景 \`\`\`javascript // 示例代码 function example() { console.log("Hello, World!"); } \`\`\` 希望这些信息对您有所帮助!`, `根据您的问题,我建议从以下几个方面来考虑: 1. **技术层面** - 考虑点1 - 考虑点2 2. **实践层面** - 实施步骤A - 实施步骤B ### 相关资源 - [参考链接1](https://example.com) - [参考链接2](https://example.com) *注意*:请根据实际情况调整方案。`, `我理解您的需求,这里有一些相关的信息可能对您有帮助。 ## 解决方案 ### 方案一:快速实现 \`\`\`bash # 命令行示例 npm install package-name npm run start \`\`\` ### 方案二:完整配置 1. 首先,创建配置文件 2. 然后,设置必要的参数 3. 最后,运行测试验证 **提示**:记得检查兼容性问题。`, `让我为您提供一些相关的建议和解决方案。 ## 核心要点 | 特性 | 描述 | 优先级 | |------|------|--------| | 性能 | 优化响应速度 | 高 | | 安全 | 加强数据保护 | 高 | | 易用 | 改善用户体验 | 中 | ### 实施建议 > 💡 **最佳实践**:始终遵循行业标准和规范。 --- 如需更多帮助,请随时告诉我!` ]; // 检查用户消息是否包含代码相关关键词 const codeKeywords = ['代码', 'code', '函数', 'function', '编程', 'programming', 'bug', '错误', 'error']; const hasCodeContext = codeKeywords.some(keyword => message.toLowerCase().includes(keyword)); if (hasCodeContext) { // 如果是代码相关问题,返回包含代码块的响应 return markdownResponses[1]; // 返回包含代码示例的响应 } // 随机返回一个Markdown格式的响应 return markdownResponses[Math.floor(Math.random() * markdownResponses.length)]; } // 删除旧的loadChatHistory函数,使用后面定义的新版本 /* ===== 文字轮播技术 ===== */ function initTextRotator() { // 文字轮播功能 class TextRotator { constructor(options) { this.element = document.querySelector(options.selector); this.words = options.words || ['资料', '专家', '活动', '标准', '合作']; this.interval = options.interval || 2500; this.currentIndex = 0; this.isAnimating = false; if (this.element) { this.init(); } } init() { // 开始时显示第一个词 this.element.textContent = this.words[0]; console.log('文字轮播初始化:', this.words[0]); // 等待一段时间后开始轮播 setTimeout(() => { this.startRotation(); console.log('开始文字轮播'); }, 1000); } startRotation() { setInterval(() => { this.rotateText(); }, this.interval); } rotateText() { if (this.isAnimating) return; this.isAnimating = true; const nextWord = this.words[(this.currentIndex + 1) % this.words.length]; console.log('轮播切换到:', nextWord); // 同时获取倒影元素 const reflectionElement = document.querySelector('#rotating-word-reflection'); // 退出动画 this.element.style.transition = 'all 0.2s ease-out'; this.element.style.opacity = '0'; this.element.style.transform = 'translateY(-10px) scale(1.02)'; if (reflectionElement) { reflectionElement.style.transition = 'all 0.2s ease-out'; reflectionElement.style.opacity = '0'; reflectionElement.style.transform = 'translateY(10px) scale(1.02)'; } setTimeout(() => { // 更换文字 this.currentIndex = (this.currentIndex + 1) % this.words.length; this.element.textContent = this.words[this.currentIndex]; if (reflectionElement) { reflectionElement.textContent = this.words[this.currentIndex]; } console.log('文字已更换为:', this.words[this.currentIndex]); // 重置位置准备进入动画 this.element.style.transition = 'none'; this.element.style.transform = 'translateY(10px) scale(0.98)'; this.element.style.opacity = '0'; if (reflectionElement) { reflectionElement.style.transition = 'none'; reflectionElement.style.transform = 'translateY(-10px) scale(0.98)'; reflectionElement.style.opacity = '0'; } // 强制重绘 requestAnimationFrame(() => { // 进入动画 this.element.style.transition = 'all 0.3s ease-out'; this.element.style.opacity = '1'; this.element.style.transform = 'translateY(0) scale(1)'; if (reflectionElement) { reflectionElement.style.transition = 'all 0.3s ease-out'; reflectionElement.style.opacity = '0.7'; reflectionElement.style.transform = 'translateY(0) scale(1)'; } setTimeout(() => { this.isAnimating = false; console.log('动画完成'); }, 300); }); }, 200); } } // 初始化文字轮播 const rotatingElement = document.querySelector('#rotating-word'); console.log('轮播元素查找结果:', rotatingElement); if (rotatingElement) { const textRotator = new TextRotator({ selector: '#rotating-word', words: ['资料', '专家', '活动', '标准', '合作'], interval: 2500 }); // 添加点击跳转功能和波纹效果 rotatingElement.addEventListener('click', function(e) { console.log('点击轮播文字:', this.textContent); // 创建波纹效果 const ripple = document.createElement('div'); const rect = this.getBoundingClientRect(); const size = Math.max(rect.width, rect.height); const x = e.clientX - rect.left - size / 2; const y = e.clientY - rect.top - size / 2; ripple.style.cssText = ` position: absolute; width: ${size}px; height: ${size}px; left: ${x}px; top: ${y}px; background: radial-gradient(circle, rgba(30, 64, 175, 0.3) 0%, transparent 70%); border-radius: 50%; transform: scale(0); animation: ripple 0.6s ease-out; pointer-events: none; z-index: 1; `; this.style.position = 'relative'; this.appendChild(ripple); setTimeout(() => { ripple.remove(); }, 600); // 跳转到新窗口 window.open('https://yundage.com/home', '_blank'); }); // 3D鼠标跟随效果已移除,保持静态显示 } else { console.error('未找到轮播元素 #rotating-word'); } } /* ===== 鼠标跟随翻转卡片新闻跑马灯功能 ===== */ function init3DTicker() { const ticker3D = document.getElementById('ticker3D'); const tickerCarousel = document.getElementById('tickerCarousel'); const tickerParticles = document.getElementById('tickerParticles'); if (!ticker3D || !tickerCarousel || !tickerParticles) { console.log('翻转卡片跑马灯元素未找到'); return; } console.log('初始化鼠标跟随翻转卡片新闻跑马灯'); let newsIndex = 0; // 新闻图片数据,对应images目录下的新闻1-10.png const newsData = [ { image: '新闻1.png', alt: '新闻1' }, { image: '新闻2.png', alt: '新闻2' }, { image: '新闻3.png', alt: '新闻3' }, { image: '新闻4.png', alt: '新闻4' }, { image: '新闻5.png', alt: '新闻5' }, { image: '新闻6.png', alt: '新闻6' }, { image: '新闻7.png', alt: '新闻7' }, { image: '新闻8.png', alt: '新闻8' }, { image: '新闻9.png', alt: '新闻9' }, { image: '新闻10.png', alt: '新闻10' } ]; // 创建背景粒子 function createTickerParticles() { tickerParticles.innerHTML = ''; for (let i = 0; i < 8; i++) { const particle = document.createElement('div'); particle.className = 'ticker-particle'; particle.style.left = Math.random() * 100 + '%'; particle.style.animationDelay = Math.random() * 8 + 's'; particle.style.animationDuration = (Math.random() * 4 + 6) + 's'; tickerParticles.appendChild(particle); } } // 双向鼠标跟随翻转效果 function initMouseFollowFlip() { const cards = tickerCarousel.querySelectorAll('.ticker-flip-card'); let lastMouseX = 0; let lastDirection = 0; // -1左,1右,0静止 // 鼠标移动事件 ticker3D.addEventListener('mousemove', function(e) { const rect = ticker3D.getBoundingClientRect(); const mouseX = e.clientX - rect.left; // 计算鼠标移动方向 const direction = mouseX > lastMouseX ? 1 : mouseX < lastMouseX ? -1 : 0; if (direction !== 0) { lastDirection = direction; } lastMouseX = mouseX; // 为每个卡片计算翻转角度 cards.forEach((card, index) => { const cardRect = card.getBoundingClientRect(); const cardLeft = cardRect.left - rect.left; const cardRight = cardLeft + cardRect.width; const cardWidth = cardRect.width; const cardCenter = cardLeft + cardWidth / 2; // 计算鼠标到卡片中心的距离 const distanceToCenter = Math.abs(mouseX - cardCenter); const maxDistance = cardWidth * 2; // 影响范围扩大到卡片宽度的2倍 // 基础翻转进度(基于鼠标在卡片中的位置) let baseProgress = 0; if (mouseX >= cardLeft && mouseX <= cardRight) { // 鼠标在卡片范围内 baseProgress = (mouseX - cardLeft) / cardWidth; } else if (mouseX < cardLeft) { // 鼠标在卡片左侧 const distanceFromLeft = cardLeft - mouseX; baseProgress = Math.max(0, 1 - (distanceFromLeft / cardWidth)); } else { // 鼠标在卡片右侧 const distanceFromRight = mouseX - cardRight; baseProgress = Math.max(0, 1 - (distanceFromRight / cardWidth)); } // 邻近卡片的影响(双向) let neighborInfluence = 0; // 检查相邻卡片的影响 for (let i = 0; i < cards.length; i++) { if (i === index) continue; const neighborCard = cards[i]; const neighborRect = neighborCard.getBoundingClientRect(); const neighborLeft = neighborRect.left - rect.left; const neighborRight = neighborLeft + neighborRect.width; const neighborCenter = neighborLeft + neighborRect.width / 2; // 如果鼠标在相邻卡片上,计算对当前卡片的影响 if (mouseX >= neighborLeft && mouseX <= neighborRight) { const neighborProgress = (mouseX - neighborLeft) / neighborRect.width; const distance = Math.abs(index - i); const influence = neighborProgress * Math.pow(0.6, distance); // 距离越远影响越小 // 根据方向确定影响方式 if ((i < index && lastDirection === 1) || (i > index && lastDirection === -1)) { neighborInfluence = Math.max(neighborInfluence, influence); } } } // 计算最终翻转进度 const finalProgress = Math.min(1, Math.max(0, baseProgress + neighborInfluence)); // 根据鼠标方向和位置决定翻转角度 let rotationAngle = 0; if (finalProgress > 0) { // 基础翻转角度 rotationAngle = finalProgress * 180; // 考虑方向性:从右往左时可能需要反向翻转 if (lastDirection === -1 && mouseX < cardCenter) { // 从右往左且鼠标在卡片左侧时,使用反向翻转 rotationAngle = (1 - finalProgress) * 180; } } // 应用真正的3D翻转效果 const inner = card.querySelector('.flip-card-inner'); if (inner) { inner.style.transform = `rotateY(${rotationAngle}deg)`; } // 调试信息(只显示第一张卡片) if (index === 0) { console.log(`Card ${index}: mouseX=${mouseX.toFixed(0)}, direction=${lastDirection}, baseProgress=${baseProgress.toFixed(2)}, neighborInfluence=${neighborInfluence.toFixed(2)}, rotation=${rotationAngle.toFixed(1)}°`); } }); }); // 鼠标离开时重置 ticker3D.addEventListener('mouseleave', function() { cards.forEach(card => { const inner = card.querySelector('.flip-card-inner'); if (inner) { inner.style.transform = 'rotateY(0deg)'; } }); lastMouseX = 0; lastDirection = 0; }); // 鼠标进入时记录初始位置 ticker3D.addEventListener('mouseenter', function(e) { const rect = ticker3D.getBoundingClientRect(); lastMouseX = e.clientX - rect.left; lastDirection = 0; }); } // 新闻轮播功能 - 更新卡片内容 function rotateNews() { const cards = tickerCarousel.querySelectorAll('.ticker-flip-card'); cards.forEach((card, index) => { const currentNewsIndex = (newsIndex + index) % newsData.length; const newsItem = newsData[currentNewsIndex]; // 更新正面图片 const frontImage = card.querySelector('.flip-card-front .news-image'); if (frontImage) { frontImage.src = `images/${newsItem.image}`; frontImage.alt = newsItem.alt; } // 更新背面图片(保持一致) const backImage = card.querySelector('.flip-card-back .news-image'); if (backImage) { backImage.src = `images/${newsItem.image}`; backImage.alt = newsItem.alt; } // 更新data属性 card.setAttribute('data-news', newsItem.alt); card.setAttribute('data-image', newsItem.image); }); newsIndex = (newsIndex + 1) % newsData.length; } // 卡片点击事件 function addCardListeners() { const cards = tickerCarousel.querySelectorAll('.ticker-flip-card'); cards.forEach(card => { card.addEventListener('click', function() { const newsText = this.getAttribute('data-news'); console.log('点击新闻卡片:', newsText); // 点击后跳转到微信文章,在新窗口中打开 window.open('https://mp.weixin.qq.com/s/QfUgaORgErymzezvSISlJQ', '_blank'); }); // 悬停时暂停轮播 card.addEventListener('mouseenter', function() { clearInterval(newsRotationInterval); }); // 离开时恢复轮播 card.addEventListener('mouseleave', function() { startNewsRotation(); }); }); } function showNewsInChat(newsText) { const messageInput = document.getElementById('messageInput'); if (messageInput) { const cleanText = newsText.replace(/[🔥📚👥🎯🤝🚀💡🌟]/g, '').trim(); messageInput.value = `告诉我更多关于"${cleanText}"的信息`; messageInput.focus(); } } // 启动新闻轮播 let newsRotationInterval; function startNewsRotation() { clearInterval(newsRotationInterval); newsRotationInterval = setInterval(rotateNews, 5000); // 每5秒轮换一次 } // 响应式处理 function handleResize() { createTickerParticles(); } // 初始化 createTickerParticles(); addCardListeners(); startNewsRotation(); initMouseFollowFlip(); // 初始化鼠标跟随翻转 window.addEventListener('resize', handleResize); console.log('鼠标跟随翻转卡片新闻跑马灯初始化完成'); } /* ===== 聊天管理器相关功能 ===== */ function initChatManagerListeners() { if (!window.chatManager) return; // 监听聊天切换事件 window.addEventListener('chatManager:chatSwitched', (e) => { const { chatId, chat } = e.detail; console.log('切换到聊天:', chatId); currentChatId = chatId; loadChatHistory(chatId); }); // 监听聊天删除事件 window.addEventListener('chatManager:chatDeleted', (e) => { const { chatId } = e.detail; console.log('删除聊天:', chatId); // 从侧边栏移除 const chatItem = document.querySelector(`[data-chat-id="${chatId}"]`); if (chatItem) { chatItem.remove(); } }); // 监听新聊天创建事件 window.addEventListener('chatManager:newChatStarted', () => { console.log('新聊天事件已触发'); // 不要在这里调用 startNewChat(),避免递归 }); // 监听聊天标题更新事件 window.addEventListener('chatManager:chatTitleUpdated', (e) => { const { chatId, title } = e.detail; console.log('更新聊天标题:', chatId, title); // 更新侧边栏中的标题 const chatItem = document.querySelector(`[data-chat-id="${chatId}"]`); if (chatItem) { const chatTitle = chatItem.querySelector('.chat-title'); if (chatTitle) { chatTitle.textContent = title; } } }); } async function loadUserChatHistory() { // 如果有后端API,从后端加载会话列表 if (window.ChatAPIService) { try { const result = await window.ChatAPIService.getConversations(); if (result.success) { // 清空现有的聊天历史显示 const chatHistoryList = document.querySelector('.chat-history-list'); if (chatHistoryList) { chatHistoryList.innerHTML = ''; // 添加每个会话到侧边栏 result.conversations.forEach(conversation => { // 后端返回的会话格式可能是 {id, userId, title, mode, createdAt, updatedAt} addChatToSidebar(conversation.id, conversation.title || '新对话'); }); } console.log(`从后端加载了 ${result.conversations.length} 个会话`); } } catch (error) { console.error('加载会话列表失败:', error); // 降级到本地存储 loadLocalChatHistory(); } } else { // 没有后端API,使用本地存储 loadLocalChatHistory(); } } // 从本地存储加载聊天历史 function loadLocalChatHistory() { if (!window.chatManager) return; // 获取所有聊天 const chats = window.chatManager.getAllChats(); // 清空现有的聊天历史显示 const chatHistoryList = document.querySelector('.chat-history-list'); if (chatHistoryList) { chatHistoryList.innerHTML = ''; // 添加每个聊天到侧边栏 chats.forEach(chat => { addChatToSidebar(chat.id, chat.title); }); } console.log(`从本地加载了 ${chats.length} 个聊天历史`); } // 监听用户登录状态变化 function initUserChangeListener() { let previousUser = localStorage.getItem('yundage_current_user'); // 监听 storage 事件(其他标签页的变化) window.addEventListener('storage', function(e) { if (e.key === 'yundage_current_user') { handleUserChange(e.oldValue, e.newValue); } }); // 定期检查当前标签页的用户变化 setInterval(() => { const currentUser = localStorage.getItem('yundage_current_user'); if (currentUser !== previousUser) { handleUserChange(previousUser, currentUser); previousUser = currentUser; } }, 1000); // 监听聊天管理器的用户变化事件 window.addEventListener('chatManager:userChanged', () => { loadUserChatHistory(); }); } // 处理用户变化 function handleUserChange(oldUserStr, newUserStr) { console.log('检测到用户变化'); const oldUser = oldUserStr ? JSON.parse(oldUserStr) : null; const newUser = newUserStr ? JSON.parse(newUserStr) : null; if (oldUser?.id !== newUser?.id) { console.log(`用户从 ${oldUser?.username || '未登录'} 切换到 ${newUser?.username || '未登录'}`); // 重新加载聊天记录 if (window.chatManager) { window.chatManager.reloadForUser(); } // 清空当前显示的聊天内容 const chatMessages = document.getElementById('chatMessages'); if (chatMessages) { chatMessages.innerHTML = ''; } // 切回欢迎界面 startNewChat(); } } // 更新loadChatHistory函数以使用新的聊天管理器 async function loadChatHistory(chatId) { // 清空当前聊天显示 const chatMessages = document.getElementById('chatMessages'); if (chatMessages) { chatMessages.innerHTML = ''; } // 设置当前聊天ID currentChatId = chatId; // 直接使用本地存储加载消息 // 因为HippoDeepService的getConversationMessages实际上也是从本地chatManager加载的 // 避免重复加载导致消息显示两次 loadLocalChatMessages(chatId); // 显示聊天容器 showChatContainer(); // 高亮当前聊天项 highlightActiveChatItem(chatId); // 强制触发一次布局重新计算,确保输入框宽度正确 setTimeout(() => { const chatModeInput = document.getElementById('chatModeInput'); if (chatModeInput) { // 触发重新渲染 chatModeInput.style.display = 'none'; void chatModeInput.offsetHeight; // 强制重排 chatModeInput.style.display = 'block'; } // 如果有视口处理器,也触发重新计算 if (window.viewportHandler) { window.viewportHandler.forceRecalculate(); } }, 50); } // 高亮当前活动的聊天项 function highlightActiveChatItem(chatId) { // 移除所有聊天项的active类 document.querySelectorAll('.chat-history-item').forEach(item => { item.classList.remove('active'); }); // 添加active类到当前聊天项 const activeItem = document.querySelector(`[data-chat-id="${chatId}"]`); if (activeItem) { activeItem.classList.add('active'); } } // 从本地存储加载聊天消息 function loadLocalChatMessages(chatId) { // 从聊天管理器加载消息 if (window.chatManager) { console.log(`[loadChatHistory] 从本地加载聊天: ${chatId}`); console.log(`[loadChatHistory] 当前chatManager.currentChatId: ${window.chatManager.currentChatId}`); // 如果不是当前聊天,才需要切换 if (window.chatManager.currentChatId !== chatId) { console.log(`[loadChatHistory] 切换到聊天: ${chatId}`); window.chatManager.switchToChat(chatId); } const chat = window.chatManager.getChat(chatId); if (chat && chat.messages) { const chatMessages = document.getElementById('chatMessages'); chat.messages.forEach(message => { // 直接创建消息元素,不调用addMessage以避免重复保存 const messageItem = document.createElement('div'); messageItem.className = 'message-item mb-4'; const isUser = message.type === 'user'; const messageTime = new Date(message.timestamp).toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' }); // 渲染内容(支持Markdown) let renderedContent = message.content; if (window.markdownRenderer) { renderedContent = window.markdownRenderer.render(message.content); } if (isUser) { messageItem.innerHTML = `
${renderedContent}
${messageTime}
`; } else { messageItem.innerHTML = `
${renderedContent}
${messageTime}
`; } chatMessages.appendChild(messageItem); }); // 滚动到底部 chatMessages.scrollTop = chatMessages.scrollHeight; // 切换到聊天模式 showChatContainer(); // 强制重新计算布局,确保对齐 setTimeout(() => { if (window.viewportHandler) { window.viewportHandler.forceRecalculate(); } }, 100); } else { // 即使没有消息也要切换到聊天模式 showChatContainer(); } } else { // 兼容旧的加载方式 loadChatHistoryLegacy(chatId); } } // 保留旧的加载方式作为后备 function loadChatHistoryLegacy(chatId) { // 原来的loadChatHistory实现 if (chatHistoryData.has(chatId)) { const messages = chatHistoryData.get(chatId); const chatMessages = document.getElementById('chatMessages'); messages.forEach(message => { const messageItem = document.createElement('div'); messageItem.className = 'message-item mb-4'; const isUser = message.type === 'user'; const messageTime = new Date(message.timestamp).toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' }); if (isUser) { messageItem.innerHTML = `

${message.content}

${messageTime}
`; } else { messageItem.innerHTML = `

${message.content}

${messageTime}
`; } chatMessages.appendChild(messageItem); }); chatMessages.scrollTop = chatMessages.scrollHeight; showChatContainer(); // 强制重新计算布局,确保对齐 setTimeout(() => { if (window.viewportHandler) { window.viewportHandler.forceRecalculate(); } }, 100); } } // 全局暴露必要的函数 window.startNewChat = startNewChat; window.toggleDeepSearch = toggleDeepSearch; /* ===== Apple风格背景动画 ===== */ function initBackground() { const gradientElement = document.getElementById('animatedGradient'); if (!gradientElement) return; let time = 0; const animateGradient = () => { // 如果背景动画被暂停,延迟检查是否恢复 if (window.pauseBackgroundAnimation) { setTimeout(() => { requestAnimationFrame(animateGradient); }, 1000); // 每秒检查一次 return; } time += 0.0056; // 减慢动画速度让过渡更平滑 // 柔和、低饱和度的冷色调,包含近白色 const colors = [ { r: 180, g: 205, b: 215, a: 0.5 }, // 柔和蓝 { r: 160, g: 195, b: 220, a: 0.4 }, // 柔和天蓝 { r: 160, g: 220, b: 200, a: 0.35 }, // 柔和海蓝 { r: 240, g: 248, b: 255, a: 0.6 }, // 爱丽丝蓝 (近白) { r: 210, g: 210, b: 230, a: 0.3 }, // 柔和薰衣草 { r: 190, g: 140, b: 200, a: 0.25 } // 柔和紫 ]; // 平滑的颜色插值函数 const lerpColor = (color1, color2, t) => ({ r: Math.round(color1.r + (color2.r - color1.r) * t), g: Math.round(color1.g + (color2.g - color1.g) * t), b: Math.round(color1.b + (color2.b - color1.b) * t), a: color1.a + (color2.a - color1.a) * t }); // 为每个渐变创建平滑的颜色变化 const getInterpolatedColor = (colorIndex, speed) => { const totalColors = colors.length; const colorPhase = (time * speed) % totalColors; const currentIndex = Math.floor(colorPhase) % totalColors; const nextIndex = (currentIndex + 1) % totalColors; const t = colorPhase - Math.floor(colorPhase); return lerpColor(colors[currentIndex], colors[nextIndex], t); }; // 创建多个动画渐变,使用平滑的三角函数 const gradient1Size = 60 + Math.sin(time * 0.8) * 20; const gradient2Size = 50 + Math.cos(time * 1.1) * 15; const gradient3Size = 70 + Math.sin(time * 0.6) * 25; const gradient4Size = 45 + Math.cos(time * 1.3) * 18; // 更平滑的位置变化 const gradient1X = 30 + Math.sin(time * 0.3) * 25; const gradient1Y = 40 + Math.cos(time * 0.4) * 20; const gradient2X = 70 + Math.cos(time * 0.35) * 30; const gradient2Y = 60 + Math.sin(time * 0.25) * 25; const gradient3X = 20 + Math.sin(time * 0.45) * 35; const gradient3Y = 80 + Math.cos(time * 0.2) * 30; const gradient4X = 80 + Math.cos(time * 0.5) * 25; const gradient4Y = 20 + Math.sin(time * 0.3) * 20; // 使用插值后的颜色 const color1 = getInterpolatedColor(0, 0.3); const color2 = getInterpolatedColor(1, 0.4); const color3 = getInterpolatedColor(2, 0.2); const color4 = getInterpolatedColor(3, 0.5); // 添加额外的颜色点以增强流动感 const gradient5Size = 55 + Math.sin(time * 0.9) * 18; const gradient6Size = 65 + Math.cos(time * 0.7) * 22; const gradient5X = 50 + Math.cos(time * 0.4) * 20; const gradient5Y = 30 + Math.sin(time * 0.5) * 15; const gradient6X = 40 + Math.sin(time * 0.6) * 28; const gradient6Y = 70 + Math.cos(time * 0.35) * 22; const color5 = getInterpolatedColor(4, 0.35); const color6 = getInterpolatedColor(5, 0.45); const backgroundStyle = ` radial-gradient(${gradient1Size}% ${gradient1Size}% at ${gradient1X}% ${gradient1Y}%, rgba(${color1.r}, ${color1.g}, ${color1.b}, ${color1.a}) 0%, transparent 60%), radial-gradient(${gradient2Size}% ${gradient2Size}% at ${gradient2X}% ${gradient2Y}%, rgba(${color2.r}, ${color2.g}, ${color2.b}, ${color2.a}) 0%, transparent 65%), radial-gradient(${gradient3Size}% ${gradient3Size}% at ${gradient3X}% ${gradient3Y}%, rgba(${color3.r}, ${color3.g}, ${color3.b}, ${color3.a}) 0%, transparent 70%), radial-gradient(${gradient4Size}% ${gradient4Size}% at ${gradient4X}% ${gradient4Y}%, rgba(${color4.r}, ${color4.g}, ${color4.b}, ${color4.a}) 0%, transparent 55%), radial-gradient(${gradient5Size}% ${gradient5Size}% at ${gradient5X}% ${gradient5Y}%, rgba(${color5.r}, ${color5.g}, ${color5.b}, ${color5.a}) 0%, transparent 75%), radial-gradient(${gradient6Size}% ${gradient6Size}% at ${gradient6X}% ${gradient6Y}%, rgba(${color6.r}, ${color6.g}, ${color6.b}, ${color6.a}) 0%, transparent 68%), linear-gradient(135deg, rgba(248, 250, 252, 0.9) 0%, rgba(241, 245, 249, 0.8) 50%, rgba(226, 232, 240, 0.9) 100%) `; gradientElement.style.background = backgroundStyle; requestAnimationFrame(animateGradient); }; requestAnimationFrame(animateGradient); } // ===== 初始化工具下拉菜单 ===== function initToolsDropdown() { // 存储状态 let isDeepResearchEnabled = false; let isShowThinkingEnabled = false; // 欢迎模式的工具按钮和下拉菜单 const toolsMenuBtn = document.getElementById('toolsMenuBtn'); const toolsDropdown = document.getElementById('toolsDropdown'); const deepResearchItem = document.getElementById('deepResearchItem'); const showThinkingItem = document.getElementById('showThinkingItem'); const deepResearchStatus = document.getElementById('deepResearchStatus'); const showThinkingStatus = document.getElementById('showThinkingStatus'); // 聊天模式的工具按钮和下拉菜单 const chatModeToolsMenuBtn = document.getElementById('chatModeToolsMenuBtn'); const chatModeToolsDropdown = document.getElementById('chatModeToolsDropdown'); const chatModeDeepResearchItem = document.getElementById('chatModeDeepResearchItem'); const chatModeShowThinkingItem = document.getElementById('chatModeShowThinkingItem'); const chatModeDeepResearchStatus = document.getElementById('chatModeDeepResearchStatus'); const chatModeShowThinkingStatus = document.getElementById('chatModeShowThinkingStatus'); // 点击按钮显示/隐藏下拉菜单 if (toolsMenuBtn && toolsDropdown) { toolsMenuBtn.addEventListener('click', function(e) { e.preventDefault(); e.stopPropagation(); const isShowing = toolsDropdown.classList.contains('show'); if (isShowing) { toolsDropdown.classList.remove('show'); toolsMenuBtn.classList.remove('active'); setTimeout(() => { toolsDropdown.style.display = 'none'; }, 200); } else { toolsDropdown.style.display = 'block'; setTimeout(() => { toolsDropdown.classList.add('show'); toolsMenuBtn.classList.add('active'); }, 10); } }); } // 聊天模式工具按钮 if (chatModeToolsMenuBtn && chatModeToolsDropdown) { chatModeToolsMenuBtn.addEventListener('click', function(e) { e.stopPropagation(); const isShowing = chatModeToolsDropdown.classList.contains('show'); if (isShowing) { chatModeToolsDropdown.classList.remove('show'); chatModeToolsMenuBtn.classList.remove('active'); setTimeout(() => { chatModeToolsDropdown.style.display = 'none'; }, 200); } else { chatModeToolsDropdown.style.display = 'block'; setTimeout(() => { chatModeToolsDropdown.classList.add('show'); chatModeToolsMenuBtn.classList.add('active'); }, 10); } }); } // 点击概念感知模式 let isDeepResearchToggling = false; // 防止重复触发 function toggleDeepResearch(e) { // 如果事件存在,阻止冒泡 if (e) { e.stopPropagation(); e.stopImmediatePropagation(); } // 防止重复触发 if (isDeepResearchToggling) return; isDeepResearchToggling = true; isDeepResearchEnabled = !isDeepResearchEnabled; // 更新状态文字 if (deepResearchStatus) { deepResearchStatus.textContent = isDeepResearchEnabled ? '开' : '关'; deepResearchStatus.style.color = isDeepResearchEnabled ? '#2563eb' : '#666'; } if (chatModeDeepResearchStatus) { chatModeDeepResearchStatus.textContent = isDeepResearchEnabled ? '开' : '关'; chatModeDeepResearchStatus.style.color = isDeepResearchEnabled ? '#2563eb' : '#666'; } // 更新菜单项样式 if (isDeepResearchEnabled) { if (deepResearchItem) deepResearchItem.classList.add('active'); if (chatModeDeepResearchItem) chatModeDeepResearchItem.classList.add('active'); } else { if (deepResearchItem) deepResearchItem.classList.remove('active'); if (chatModeDeepResearchItem) chatModeDeepResearchItem.classList.remove('active'); } // 同步更新两个开关的状态 const deepResearchToggle = document.getElementById('deepResearchToggle'); const chatModeDeepResearchToggle = document.getElementById('chatModeDeepResearchToggle'); if (deepResearchToggle && deepResearchToggle.checked !== isDeepResearchEnabled) { deepResearchToggle.checked = isDeepResearchEnabled; } if (chatModeDeepResearchToggle && chatModeDeepResearchToggle.checked !== isDeepResearchEnabled) { chatModeDeepResearchToggle.checked = isDeepResearchEnabled; } console.log('概念感知模式:', isDeepResearchEnabled ? '开启' : '关闭'); // 延迟重置标志 setTimeout(() => { isDeepResearchToggling = false; }, 100); } // 点击显示思考 let isShowThinkingToggling = false; // 防止重复触发 function toggleShowThinking(e) { // 如果事件存在,阻止冒泡 if (e) { e.stopPropagation(); e.stopImmediatePropagation(); } // 防止重复触发 if (isShowThinkingToggling) return; isShowThinkingToggling = true; isShowThinkingEnabled = !isShowThinkingEnabled; // 更新状态文字 if (showThinkingStatus) { showThinkingStatus.textContent = isShowThinkingEnabled ? '开' : '关'; showThinkingStatus.style.color = isShowThinkingEnabled ? '#2563eb' : '#666'; } if (chatModeShowThinkingStatus) { chatModeShowThinkingStatus.textContent = isShowThinkingEnabled ? '开' : '关'; chatModeShowThinkingStatus.style.color = isShowThinkingEnabled ? '#2563eb' : '#666'; } // 更新菜单项样式 if (isShowThinkingEnabled) { if (showThinkingItem) showThinkingItem.classList.add('active'); if (chatModeShowThinkingItem) chatModeShowThinkingItem.classList.add('active'); } else { if (showThinkingItem) showThinkingItem.classList.remove('active'); if (chatModeShowThinkingItem) chatModeShowThinkingItem.classList.remove('active'); } console.log('显示思考:', isShowThinkingEnabled ? '开启' : '关闭'); // 延迟重置标志 setTimeout(() => { isShowThinkingToggling = false; }, 100); } // 绑定点击事件 - 只绑定到开关本身,避免重复触发 const deepResearchToggle = document.getElementById('deepResearchToggle'); const showThinkingToggle = document.getElementById('showThinkingToggle'); const chatModeDeepResearchToggle = document.getElementById('chatModeDeepResearchToggle'); const chatModeShowThinkingToggle = document.getElementById('chatModeShowThinkingToggle'); if (deepResearchToggle) { deepResearchToggle.addEventListener('change', function(e) { e.stopPropagation(); toggleDeepResearch(); }); } if (showThinkingToggle) { showThinkingToggle.addEventListener('change', function(e) { e.stopPropagation(); toggleShowThinking(); }); } if (chatModeDeepResearchToggle) { chatModeDeepResearchToggle.addEventListener('change', function(e) { e.stopPropagation(); toggleDeepResearch(); }); } if (chatModeShowThinkingToggle) { chatModeShowThinkingToggle.addEventListener('change', function(e) { e.stopPropagation(); toggleShowThinking(); }); } // 点击其他地方关闭下拉菜单 document.addEventListener('click', function(e) { if (toolsDropdown && !toolsMenuBtn.contains(e.target) && !toolsDropdown.contains(e.target)) { toolsDropdown.classList.remove('show'); toolsMenuBtn.classList.remove('active'); setTimeout(() => { toolsDropdown.style.display = 'none'; }, 200); } if (chatModeToolsDropdown && !chatModeToolsMenuBtn.contains(e.target) && !chatModeToolsDropdown.contains(e.target)) { chatModeToolsDropdown.classList.remove('show'); chatModeToolsMenuBtn.classList.remove('active'); setTimeout(() => { chatModeToolsDropdown.style.display = 'none'; }, 200); } }); // 导出获取状态的方法 window.getToolsSettings = function() { return { deepResearch: isDeepResearchEnabled, showThinking: isShowThinkingEnabled }; }; }