update pay function

This commit is contained in:
2025-11-28 14:49:16 +08:00
parent 18f8f75116
commit 9b7a221315
11 changed files with 2917 additions and 46 deletions

View File

@@ -1,9 +1,12 @@
// src/views/AgentChat/index.js
// 超炫酷的 AI 投研助手 - HeroUI v3 现代深色主题版本
// 使用 Framer Motion 物理动画引擎 + 毛玻璃效果
// 支持两种模式:单一聊天模式 & 投研会议室模式
import React, { useState } from 'react';
import { Box, Flex, useToast } from '@chakra-ui/react';
import { Box, Flex, useToast, HStack, Button, Tooltip } from '@chakra-ui/react';
import { motion, AnimatePresence } from 'framer-motion';
import { MessageSquare, Users } from 'lucide-react';
import { useAuth } from '@contexts/AuthContext';
// 常量配置 - 从 TypeScript 模块导入
@@ -14,10 +17,19 @@ import { DEFAULT_SELECTED_TOOLS } from './constants/tools';
import LeftSidebar from './components/LeftSidebar';
import ChatArea from './components/ChatArea';
import RightSidebar from './components/RightSidebar';
import MeetingRoom from './components/MeetingRoom';
// 自定义 Hooks
import { useAgentSessions, useAgentChat, useFileUpload } from './hooks';
/**
* 聊天模式枚举
*/
const ChatMode = {
SINGLE: 'single', // 单一聊天模式
MEETING: 'meeting', // 投研会议室模式
};
/**
* Agent Chat - 主组件HeroUI v3 深色主题)
*
@@ -28,13 +40,19 @@ import { useAgentSessions, useAgentChat, useFileUpload } from './hooks';
*
* 主组件职责:
* 1. 组合各个自定义 Hooks
* 2. 管理 UI 状态(侧边栏开关、模型选择、工具选择)
* 2. 管理 UI 状态(侧边栏开关、模型选择、工具选择、聊天模式
* 3. 组合渲染子组件
*
* 新增功能2024-11
* - 投研会议室模式:多 AI 角色协作讨论投资议题
*/
const AgentChat = () => {
const { user } = useAuth();
const toast = useToast();
// ==================== 聊天模式状态 ====================
const [chatMode, setChatMode] = useState(ChatMode.SINGLE);
// ==================== UI 状态(主组件管理)====================
const [selectedModel, setSelectedModel] = useState(DEFAULT_MODEL_ID);
const [selectedTools, setSelectedTools] = useState(DEFAULT_SELECTED_TOOLS);
@@ -88,52 +106,129 @@ const AgentChat = () => {
// ==================== 渲染组件 ====================
return (
<Flex h="100%" position="relative" bg="gray.900">
{/* 左侧栏 */}
<LeftSidebar
isOpen={isLeftSidebarOpen}
onClose={() => setIsLeftSidebarOpen(false)}
sessions={sessions}
currentSessionId={currentSessionId}
onSessionSwitch={switchSession}
onNewSession={createNewSession}
isLoadingSessions={isLoadingSessions}
user={user}
/>
<Flex h="100%" position="relative" bg="gray.900" direction="column">
{/* 模式切换栏 */}
<Box
bg="rgba(17, 24, 39, 0.95)"
borderBottom="1px solid"
borderColor="rgba(255, 255, 255, 0.1)"
px={4}
py={2}
>
<HStack spacing={2} justify="center">
<Tooltip label="单一聊天模式:与 AI 助手一对一对话">
<motion.div whileHover={{ scale: 1.02 }} whileTap={{ scale: 0.98 }}>
<Button
size="sm"
leftIcon={<MessageSquare className="w-4 h-4" />}
variant={chatMode === ChatMode.SINGLE ? 'solid' : 'ghost'}
colorScheme={chatMode === ChatMode.SINGLE ? 'purple' : 'gray'}
onClick={() => setChatMode(ChatMode.SINGLE)}
bg={chatMode === ChatMode.SINGLE ? 'purple.500' : 'transparent'}
color={chatMode === ChatMode.SINGLE ? 'white' : 'gray.400'}
_hover={{
bg: chatMode === ChatMode.SINGLE ? 'purple.600' : 'whiteAlpha.100',
}}
>
智能助手
</Button>
</motion.div>
</Tooltip>
{/* 中间聊天区 */}
<ChatArea
messages={messages}
inputValue={inputValue}
onInputChange={setInputValue}
isProcessing={isProcessing}
onSendMessage={handleSendMessage}
onKeyPress={handleKeyPress}
uploadedFiles={uploadedFiles}
onFileSelect={handleFileSelect}
onFileRemove={removeFile}
selectedModel={selectedModel}
isLeftSidebarOpen={isLeftSidebarOpen}
isRightSidebarOpen={isRightSidebarOpen}
onToggleLeftSidebar={() => setIsLeftSidebarOpen(true)}
onToggleRightSidebar={() => setIsRightSidebarOpen(true)}
onNewSession={createNewSession}
userAvatar={user?.avatar}
inputRef={inputRef}
fileInputRef={fileInputRef}
/>
<Tooltip label="投研会议室:多位 AI 分析师协作讨论投资议题">
<motion.div whileHover={{ scale: 1.02 }} whileTap={{ scale: 0.98 }}>
<Button
size="sm"
leftIcon={<Users className="w-4 h-4" />}
variant={chatMode === ChatMode.MEETING ? 'solid' : 'ghost'}
colorScheme={chatMode === ChatMode.MEETING ? 'orange' : 'gray'}
onClick={() => setChatMode(ChatMode.MEETING)}
bg={chatMode === ChatMode.MEETING ? 'orange.500' : 'transparent'}
color={chatMode === ChatMode.MEETING ? 'white' : 'gray.400'}
_hover={{
bg: chatMode === ChatMode.MEETING ? 'orange.600' : 'whiteAlpha.100',
}}
>
投研会议室
</Button>
</motion.div>
</Tooltip>
</HStack>
</Box>
{/* 右侧栏 */}
<RightSidebar
isOpen={isRightSidebarOpen}
onClose={() => setIsRightSidebarOpen(false)}
selectedModel={selectedModel}
onModelChange={setSelectedModel}
selectedTools={selectedTools}
onToolsChange={setSelectedTools}
sessionsCount={sessions.length}
messagesCount={messages.length}
/>
{/* 主内容区 */}
<Flex flex={1} overflow="hidden">
<AnimatePresence mode="wait">
{chatMode === ChatMode.SINGLE ? (
<motion.div
key="single-chat"
initial={{ opacity: 0, x: -20 }}
animate={{ opacity: 1, x: 0 }}
exit={{ opacity: 0, x: 20 }}
transition={{ duration: 0.3 }}
style={{ display: 'flex', flex: 1, height: '100%' }}
>
{/* 左侧栏 */}
<LeftSidebar
isOpen={isLeftSidebarOpen}
onClose={() => setIsLeftSidebarOpen(false)}
sessions={sessions}
currentSessionId={currentSessionId}
onSessionSwitch={switchSession}
onNewSession={createNewSession}
isLoadingSessions={isLoadingSessions}
user={user}
/>
{/* 中间聊天区 */}
<ChatArea
messages={messages}
inputValue={inputValue}
onInputChange={setInputValue}
isProcessing={isProcessing}
onSendMessage={handleSendMessage}
onKeyPress={handleKeyPress}
uploadedFiles={uploadedFiles}
onFileSelect={handleFileSelect}
onFileRemove={removeFile}
selectedModel={selectedModel}
isLeftSidebarOpen={isLeftSidebarOpen}
isRightSidebarOpen={isRightSidebarOpen}
onToggleLeftSidebar={() => setIsLeftSidebarOpen(true)}
onToggleRightSidebar={() => setIsRightSidebarOpen(true)}
onNewSession={createNewSession}
userAvatar={user?.avatar}
inputRef={inputRef}
fileInputRef={fileInputRef}
/>
{/* 右侧栏 */}
<RightSidebar
isOpen={isRightSidebarOpen}
onClose={() => setIsRightSidebarOpen(false)}
selectedModel={selectedModel}
onModelChange={setSelectedModel}
selectedTools={selectedTools}
onToolsChange={setSelectedTools}
sessionsCount={sessions.length}
messagesCount={messages.length}
/>
</motion.div>
) : (
<motion.div
key="meeting-room"
initial={{ opacity: 0, x: 20 }}
animate={{ opacity: 1, x: 0 }}
exit={{ opacity: 0, x: -20 }}
transition={{ duration: 0.3 }}
style={{ flex: 1, height: '100%' }}
>
{/* 投研会议室 */}
<MeetingRoom user={user} onToast={toast} />
</motion.div>
)}
</AnimatePresence>
</Flex>
</Flex>
);
};