diff --git a/src/views/AgentChat/index.js b/src/views/AgentChat/index.js index c79e70c6..bd9f4737 100644 --- a/src/views/AgentChat/index.js +++ b/src/views/AgentChat/index.js @@ -1,6 +1,6 @@ // src/views/AgentChat/index.js -// 超炫酷的 AI 投研助手 - Chakra UI 深色模式版本 -// 使用 Framer Motion 物理动画引擎 +// 超炫酷的 AI 投研助手 - HeroUI v3 现代深色主题版本 +// 使用 Framer Motion 物理动画引擎 + 毛玻璃效果 import React, { useState, useEffect, useRef } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; @@ -366,7 +366,7 @@ const TOOL_CATEGORIES = { }; /** - * Agent Chat - 主组件(深色模式) + * Agent Chat - 主组件(HeroUI v3 深色主题) */ const AgentChat = () => { const { user } = useAuth(); @@ -674,715 +674,1058 @@ const AgentChat = () => { ]; return ( - - {/* 左侧栏 - 深色毛玻璃 */} - - {isLeftSidebarOpen && ( - - - - - - - 对话历史 - - - - } - onClick={createNewSession} - /> - - - } - onClick={() => setIsLeftSidebarOpen(false)} - /> - - - + + {/* 背景渐变层 */} + - - - - - setSearchQuery(e.target.value)} - size="sm" - variant="outline" - pl={10} - borderColor="gray.600" - bg="rgba(31, 41, 55, 0.5)" - color="gray.100" - _hover={{ borderColor: 'gray.500' }} - _focus={{ borderColor: 'blue.500', boxShadow: '0 0 0 1px var(--chakra-colors-blue-500)' }} - /> - - + {/* 背景装饰光效 */} + + - - {/* 按日期分组显示会话 */} - {sessionGroups.today.length > 0 && ( - - 今天 - - {sessionGroups.today.map((session) => ( - switchSession(session.session_id)} - /> - ))} - - - )} - - {sessionGroups.yesterday.length > 0 && ( - - 昨天 - - {sessionGroups.yesterday.map((session) => ( - switchSession(session.session_id)} - /> - ))} - - - )} - - {sessionGroups.thisWeek.length > 0 && ( - - 本周 - - {sessionGroups.thisWeek.map((session) => ( - switchSession(session.session_id)} - /> - ))} - - - )} - - {sessionGroups.older.length > 0 && ( - - 更早 - - {sessionGroups.older.map((session) => ( - switchSession(session.session_id)} - /> - ))} - - - )} - - {isLoadingSessions && ( - - - - )} - - {sessions.length === 0 && !isLoadingSessions && ( - - - 还没有对话历史 - 开始一个新对话吧! - - )} - - - - - - - - {user?.nickname || '未登录'} - - - {user?.subscription_type || 'free'} 用户 - - - - - - - )} - - - {/* 中间主聊天区域 */} - - {/* 顶部标题栏 - 深色 */} - - - - {!isLeftSidebarOpen && ( - } - onClick={() => setIsLeftSidebarOpen(true)} - color="gray.400" - /> - )} - - - } - bgGradient="linear(to-br, purple.500, pink.500)" - /> - - - - - 价小前投研 AI - - - - - 智能分析 - - - {AVAILABLE_MODELS.find((m) => m.id === selectedModel)?.name} - - - - - - - - } - onClick={createNewSession} - color="gray.400" - _hover={{ color: 'gray.200' }} - /> - - {!isRightSidebarOpen && ( - } - onClick={() => setIsRightSidebarOpen(true)} - color="gray.400" - _hover={{ color: 'gray.200' }} - /> - )} - - - - - {/* 消息列表 */} - - - - - {messages.map((message) => ( - - - - ))} - -
- - - - - {/* 快捷问题 */} + + {/* 左侧栏 - 深色毛玻璃 */} - {messages.length <= 2 && !isProcessing && ( + {isLeftSidebarOpen && ( - - - - - 快速开始 + + + + + + + 对话历史 + + + + + + } + onClick={createNewSession} + bg="rgba(255, 255, 255, 0.05)" + color="gray.300" + backdropFilter="blur(10px)" + border="1px solid" + borderColor="rgba(255, 255, 255, 0.1)" + _hover={{ + bg: "rgba(59, 130, 246, 0.2)", + borderColor: "blue.400", + color: "blue.300", + boxShadow: "0 0 12px rgba(59, 130, 246, 0.3)" + }} + /> + + + + + } + onClick={() => setIsLeftSidebarOpen(false)} + bg="rgba(255, 255, 255, 0.05)" + color="gray.300" + backdropFilter="blur(10px)" + border="1px solid" + borderColor="rgba(255, 255, 255, 0.1)" + _hover={{ + bg: "rgba(255, 255, 255, 0.1)", + borderColor: "purple.400", + color: "white" + }} + /> + + + - - {quickQuestions.map((question, idx) => ( - - - - ))} + + + + + + setSearchQuery(e.target.value)} + size="sm" + variant="outline" + pl={10} + bg="rgba(255, 255, 255, 0.05)" + backdropFilter="blur(10px)" + border="1px solid" + borderColor="rgba(255, 255, 255, 0.1)" + color="white" + _placeholder={{ color: "gray.500" }} + _hover={{ + borderColor: "rgba(255, 255, 255, 0.2)" + }} + _focus={{ + borderColor: "purple.400", + boxShadow: "0 0 0 1px var(--chakra-colors-purple-400), 0 0 12px rgba(139, 92, 246, 0.3)", + bg: "rgba(255, 255, 255, 0.08)" + }} + /> + + + {/* 按日期分组显示会话 */} + {sessionGroups.today.length > 0 && ( + + 今天 + + {sessionGroups.today.map((session, idx) => ( + + switchSession(session.session_id)} + /> + + ))} + + + )} + + {sessionGroups.yesterday.length > 0 && ( + + 昨天 + + {sessionGroups.yesterday.map((session) => ( + switchSession(session.session_id)} + /> + ))} + + + )} + + {sessionGroups.thisWeek.length > 0 && ( + + 本周 + + {sessionGroups.thisWeek.map((session) => ( + switchSession(session.session_id)} + /> + ))} + + + )} + + {sessionGroups.older.length > 0 && ( + + 更早 + + {sessionGroups.older.map((session) => ( + switchSession(session.session_id)} + /> + ))} + + + )} + + {isLoadingSessions && ( + + + + )} + + {sessions.length === 0 && !isLoadingSessions && ( + + + 还没有对话历史 + 开始一个新对话吧! + + )} + + + + + + + + {user?.nickname || '未登录'} + + + {user?.subscription_type || 'free'} + + + + )} - {/* 输入栏 - 深色 */} - - - {/* 已上传文件预览 */} - {uploadedFiles.length > 0 && ( - - {uploadedFiles.map((file, idx) => ( - - {file.name} - removeFile(idx)} /> - - ))} - - )} - - - - - - } - onClick={() => fileInputRef.current?.click()} - bg="gray.700" - color="gray.300" - _hover={{ bg: 'gray.600' }} - /> - - - - } - onClick={() => { - fileInputRef.current?.setAttribute('accept', 'image/*'); - fileInputRef.current?.click(); - }} - bg="gray.700" - color="gray.300" - _hover={{ bg: 'gray.600' }} - /> - - - setInputValue(e.target.value)} - onKeyDown={handleKeyPress} - placeholder="输入你的问题... (Enter 发送, Shift+Enter 换行)" - isDisabled={isProcessing} - size="lg" - variant="outline" - borderWidth={2} - borderColor="gray.600" - bg="rgba(31, 41, 55, 0.5)" - color="gray.100" - _hover={{ borderColor: 'blue.500' }} - _focus={{ borderColor: 'blue.500', boxShadow: '0 0 0 1px var(--chakra-colors-blue-500)' }} - /> - - - } - onClick={handleSendMessage} - isLoading={isProcessing} - isDisabled={!inputValue.trim() || isProcessing} - bgGradient="linear(to-r, blue.600, purple.600)" - _hover={{ bgGradient: 'linear(to-r, blue.500, purple.500)' }} - /> - - - - - - Enter - 发送 - - - Shift - + - Enter - 换行 - - - - - - - {/* 右侧栏 - 深色配置中心 */} - - {isRightSidebarOpen && ( - + {/* 顶部标题栏 - 深色毛玻璃 */} + - - - - - - 配置中心 - - + + + {!isLeftSidebarOpen && ( + } - onClick={() => setIsRightSidebarOpen(false)} + icon={} + onClick={() => setIsLeftSidebarOpen(true)} + bg="rgba(255, 255, 255, 0.05)" color="gray.400" - _hover={{ color: 'gray.200' }} + backdropFilter="blur(10px)" + border="1px solid" + borderColor="rgba(255, 255, 255, 0.1)" + _hover={{ + bg: "rgba(255, 255, 255, 0.1)", + color: "white" + }} /> - - - + + )} - - - - - - - 模型 - - - - - - 工具 - {selectedTools.length > 0 && ( - - {selectedTools.length} - - )} - - - - - - 统计 - - - + + } + bgGradient="linear(to-br, purple.500, pink.500)" + boxShadow="0 0 20px rgba(236, 72, 153, 0.5)" + /> + - - {/* 模型选择 */} - - - {AVAILABLE_MODELS.map((model) => ( - setSelectedModel(model.id)} - bg={selectedModel === model.id ? 'rgba(59, 130, 246, 0.2)' : 'rgba(31, 41, 55, 0.5)'} - borderWidth={2} - borderColor={selectedModel === model.id ? 'blue.500' : 'gray.600'} - _hover={{ borderColor: selectedModel === model.id ? 'blue.500' : 'gray.500' }} - transition="all 0.2s" - > - - - - {model.icon} - - - - {model.name} - - - {model.description} - - - {selectedModel === model.id && ( - - )} - - - - ))} - - + + + 价小前投研 AI + + + + + 智能分析 + + + {AVAILABLE_MODELS.find((m) => m.id === selectedModel)?.name} + + + + - {/* 工具选择 */} - - - {Object.entries(TOOL_CATEGORIES).map(([category, tools]) => ( - + + + } + onClick={createNewSession} + bg="rgba(255, 255, 255, 0.05)" + color="gray.400" + backdropFilter="blur(10px)" + border="1px solid" + borderColor="rgba(255, 255, 255, 0.1)" + _hover={{ + bg: "rgba(255, 255, 255, 0.1)", + color: "white", + borderColor: "purple.400", + boxShadow: "0 0 12px rgba(139, 92, 246, 0.3)" + }} + /> + + + {!isRightSidebarOpen && ( + + } + onClick={() => setIsRightSidebarOpen(true)} + bg="rgba(255, 255, 255, 0.05)" + color="gray.400" + backdropFilter="blur(10px)" + border="1px solid" + borderColor="rgba(255, 255, 255, 0.1)" + _hover={{ + bg: "rgba(255, 255, 255, 0.1)", + color: "white" + }} + /> + + )} + + + + + {/* 消息列表 */} + + + + + {messages.map((message) => ( + + + + ))} + +
+ + + + + {/* 快捷问题 */} + + {messages.length <= 2 && !isProcessing && ( + + + + + + 快速开始 + + + {quickQuestions.map((question, idx) => ( + + + + ))} + + + + + )} + + + {/* 输入栏 - 深色毛玻璃 */} + + + {/* 已上传文件预览 */} + {uploadedFiles.length > 0 && ( + + {uploadedFiles.map((file, idx) => ( + + + {file.name} + removeFile(idx)} color="gray.400" /> + + + ))} + + )} + + + + + + + } + onClick={() => fileInputRef.current?.click()} + bg="rgba(255, 255, 255, 0.05)" + color="gray.300" + backdropFilter="blur(10px)" + border="1px solid" + borderColor="rgba(255, 255, 255, 0.1)" + _hover={{ + bg: "rgba(255, 255, 255, 0.1)", + borderColor: "purple.400", + color: "white", + boxShadow: "0 0 12px rgba(139, 92, 246, 0.3)" + }} + /> + + + + + + } + onClick={() => { + fileInputRef.current?.setAttribute('accept', 'image/*'); + fileInputRef.current?.click(); + }} + bg="rgba(255, 255, 255, 0.05)" + color="gray.300" + backdropFilter="blur(10px)" + border="1px solid" + borderColor="rgba(255, 255, 255, 0.1)" + _hover={{ + bg: "rgba(255, 255, 255, 0.1)", + borderColor: "purple.400", + color: "white", + boxShadow: "0 0 12px rgba(139, 92, 246, 0.3)" + }} + /> + + + + setInputValue(e.target.value)} + onKeyDown={handleKeyPress} + placeholder="输入你的问题... (Enter 发送, Shift+Enter 换行)" + isDisabled={isProcessing} + size="lg" + variant="outline" + borderWidth={2} + bg="rgba(255, 255, 255, 0.05)" + backdropFilter="blur(10px)" + border="1px solid" + borderColor="rgba(255, 255, 255, 0.1)" + color="white" + _placeholder={{ color: "gray.500" }} + _hover={{ + borderColor: "rgba(255, 255, 255, 0.2)" + }} + _focus={{ + borderColor: "purple.400", + boxShadow: "0 0 0 1px var(--chakra-colors-purple-400), 0 0 12px rgba(139, 92, 246, 0.3)", + bg: "rgba(255, 255, 255, 0.08)" + }} + /> + + + } + onClick={handleSendMessage} + isLoading={isProcessing} + isDisabled={!inputValue.trim() || isProcessing} + bgGradient="linear(to-r, blue.500, purple.600)" + color="white" + _hover={{ + bgGradient: "linear(to-r, blue.600, purple.700)", + boxShadow: "0 8px 20px rgba(139, 92, 246, 0.4)" + }} + _active={{ + transform: "translateY(0)", + boxShadow: "0 4px 12px rgba(139, 92, 246, 0.3)" + }} + /> + + + + + + Enter + 发送 + + + Shift + + + Enter + 换行 + + + + + + + {/* 右侧栏 - 深色配置中心 */} + + {isRightSidebarOpen && ( + + + + + + + + 配置中心 + + + + + } + onClick={() => setIsRightSidebarOpen(false)} + bg="rgba(255, 255, 255, 0.05)" + color="gray.300" + backdropFilter="blur(10px)" + border="1px solid" + borderColor="rgba(255, 255, 255, 0.1)" + _hover={{ + bg: "rgba(255, 255, 255, 0.1)", + borderColor: "purple.400", + color: "white" + }} + /> + + + + + + + + + + + + 模型 + + + + + + 工具 + {selectedTools.length > 0 && ( + + {selectedTools.length} + + )} + + + + + + 统计 + + + + + + {/* 模型选择 */} + + + {AVAILABLE_MODELS.map((model, idx) => ( + + setSelectedModel(model.id)} + bg={selectedModel === model.id + ? 'rgba(139, 92, 246, 0.15)' + : 'rgba(255, 255, 255, 0.05)'} + backdropFilter="blur(12px)" + borderWidth={2} + borderColor={selectedModel === model.id + ? 'purple.400' + : 'rgba(255, 255, 255, 0.1)'} + _hover={{ + borderColor: selectedModel === model.id + ? 'purple.400' + : 'rgba(255, 255, 255, 0.2)', + boxShadow: selectedModel === model.id + ? "0 8px 20px rgba(139, 92, 246, 0.4)" + : "0 4px 12px rgba(0, 0, 0, 0.3)" + }} + transition="all 0.3s" > - - {tools.map((tool) => ( - + + - - {tool.icon} - - {tool.name} - {tool.description} - - - - ))} - - - - - ))} - + {model.icon} + + + + {model.name} + + + {model.description} + + + {selectedModel === model.id && ( + + + + )} + + + + + ))} + + - - - - - + {/* 工具选择 */} + + + {Object.entries(TOOL_CATEGORIES).map(([category, tools], catIdx) => ( + + + + + {category} + + {tools.filter(t => selectedTools.includes(t.id)).length}/{tools.length} + + + + + + + + {tools.map((tool) => ( + + + + {tool.icon} + + {tool.name} + {tool.description} + + + + + ))} + + + + + + ))} + - {/* 统计信息 */} - - - - - - - 对话数 - - {sessions.length} - - - - - - + + + + + + + + + - - - - - 消息数 - - {messages.length} - - - - - - + {/* 统计信息 */} + + + + + + + + 对话数 + + {sessions.length} + + + + + + + - - - - - 已选工具 - - {selectedTools.length} - - - - - - - - - - + + + + + + 消息数 + + {messages.length} + + + + + + + + + + + + + + 已选工具 + + {selectedTools.length} + + + + + + + + + + + + - - - )} - - + + )} + + + ); }; @@ -1393,46 +1736,68 @@ export default AgentChat; */ const SessionCard = ({ session, isActive, onPress }) => { return ( - - - - - - {session.title || '新对话'} - - - {new Date(session.created_at || session.timestamp).toLocaleString('zh-CN', { - month: 'numeric', - day: 'numeric', - hour: '2-digit', - minute: '2-digit', - })} - - - {session.message_count && ( - - {session.message_count} - - )} - - - + + + + + + {session.title || '新对话'} + + + {new Date(session.created_at || session.timestamp).toLocaleString('zh-CN', { + month: 'numeric', + day: 'numeric', + hour: '2-digit', + minute: '2-digit', + })} + + + {session.message_count && ( + + {session.message_count} + + )} + + + + ); }; @@ -1445,28 +1810,45 @@ const MessageRenderer = ({ message, userAvatar }) => { return ( - - - - {message.content} - - {message.files && message.files.length > 0 && ( - - {message.files.map((file, idx) => ( - - - {file.name} - - ))} - - )} - - + + + + + {message.content} + + {message.files && message.files.length > 0 && ( + + {message.files.map((file, idx) => ( + + + {file.name} + + ))} + + )} + + + } size="sm" bgGradient="linear(to-br, blue.500, purple.600)" + boxShadow="0 0 12px rgba(139, 92, 246, 0.4)" /> @@ -1480,15 +1862,27 @@ const MessageRenderer = ({ message, userAvatar }) => { icon={} size="sm" bgGradient="linear(to-br, purple.500, pink.500)" + boxShadow="0 0 12px rgba(236, 72, 153, 0.4)" /> - - - - - {message.content} - - - + + + + + + {message.content} + + + + ); @@ -1501,63 +1895,90 @@ const MessageRenderer = ({ message, userAvatar }) => { icon={} size="sm" bgGradient="linear(to-br, purple.500, pink.500)" + boxShadow="0 0 12px rgba(236, 72, 153, 0.4)" /> - - - - {message.content} - - - {message.stepResults && message.stepResults.length > 0 && ( - - - - )} - - - - } - onClick={() => navigator.clipboard.writeText(message.content)} - color="gray.400" - _hover={{ color: 'gray.200' }} - /> - - - } - color="gray.400" - _hover={{ color: 'green.400' }} - /> - - - } - color="gray.400" - _hover={{ color: 'red.400' }} - /> - - - {new Date(message.timestamp).toLocaleTimeString('zh-CN', { - hour: '2-digit', - minute: '2-digit', - })} + + + + {message.content} - - - + + {message.stepResults && message.stepResults.length > 0 && ( + + + + )} + + + + + } + onClick={() => navigator.clipboard.writeText(message.content)} + bg="rgba(255, 255, 255, 0.05)" + color="gray.400" + _hover={{ + color: "white", + bg: "rgba(255, 255, 255, 0.1)" + }} + /> + + + + + } + bg="rgba(255, 255, 255, 0.05)" + color="gray.400" + _hover={{ + color: "green.400", + bg: "rgba(16, 185, 129, 0.1)", + boxShadow: "0 0 12px rgba(16, 185, 129, 0.3)" + }} + /> + + + + + } + bg="rgba(255, 255, 255, 0.05)" + color="gray.400" + _hover={{ + color: "red.400", + bg: "rgba(239, 68, 68, 0.1)", + boxShadow: "0 0 12px rgba(239, 68, 68, 0.3)" + }} + /> + + + + {new Date(message.timestamp).toLocaleTimeString('zh-CN', { + hour: '2-digit', + minute: '2-digit', + })} + + + + + ); @@ -1565,11 +1986,22 @@ const MessageRenderer = ({ message, userAvatar }) => { case MessageTypes.ERROR: return ( - - - {message.content} - - + + + + {message.content} + + + ); @@ -1586,16 +2018,25 @@ const ExecutionStepsDisplay = ({ steps, plan }) => { 执行详情 - + {steps.length} 步骤 @@ -1604,27 +2045,45 @@ const ExecutionStepsDisplay = ({ steps, plan }) => { {steps.map((result, idx) => ( - - - - - 步骤 {idx + 1}: {result.tool_name} + + + + + + 步骤 {idx + 1}: {result.tool_name} + + + {result.status} + + + + {result.execution_time?.toFixed(2)}s - - {result.status} - - - - {result.execution_time?.toFixed(2)}s - - {result.error && ( - ⚠️ {result.error} - )} - - + {result.error && ( + ⚠️ {result.error} + )} + + + ))}