/** * Protocol Agent 页面 * * V2: 支持动态布局 + 文档预览 * - 要素收集阶段: Chat 65% : Context 35% * - 方案生成阶段: Chat 35% : Document 65% */ import React, { useState, useEffect, useRef, useCallback } from 'react'; import { useNavigate, useParams } from 'react-router-dom'; import { Bot, Settings, ChevronLeft, Menu, Plus, MessageSquare, Trash2 } from 'lucide-react'; import { ChatArea } from './components/ChatArea'; import { StatePanel } from './components/StatePanel'; import { DocumentPanel } from './components/DocumentPanel'; import { ResizableSplitPane } from '@/shared/components/Layout'; import { ViewSwitcher } from './components/ViewSwitcher'; import { useProtocolContext } from './hooks/useProtocolContext'; import { useProtocolConversations } from './hooks/useProtocolConversations'; import { useProtocolGeneration } from './hooks/useProtocolGeneration'; import { getAccessToken } from '../../../framework/auth/api'; import './styles/protocol-agent.css'; // 布局比例配置 const LAYOUT_RATIOS = { context: 65, // 要素收集阶段:Chat 65% document: 35, // 方案生成阶段:Chat 35% }; export const ProtocolAgentPage: React.FC = () => { const navigate = useNavigate(); const { conversationId } = useParams<{ conversationId?: string }>(); // 侧边栏折叠状态 const [sidebarCollapsed, setSidebarCollapsed] = useState(true); // 会话管理 const { conversations, currentConversation, createConversation, selectConversation, deleteConversation, updateConversationTitle, } = useProtocolConversations(conversationId); // 上下文状态 const { context, refreshContext } = useProtocolContext(currentConversation?.id); // 方案生成状态 const { generatedContent, currentSection, isGenerating, hasGeneratedContent, viewMode, setViewMode, startGeneration, exportWord, } = useProtocolGeneration({ conversationId: currentConversation?.id }); // Word 导出状态 const [isExporting, setIsExporting] = useState(false); // 处理阶段数据编辑更新 const handleStageUpdate = useCallback(async (stageCode: string, data: Record) => { if (!currentConversation?.id) return; const token = getAccessToken(); const response = await fetch('/api/v1/aia/protocol-agent/sync', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}`, }, body: JSON.stringify({ conversationId: currentConversation.id, stageCode, data, }), }); if (!response.ok) { throw new Error('更新失败'); } // 刷新上下文 await refreshContext(); }, [currentConversation?.id, refreshContext]); // 自动创建会话(首次进入时) const hasAutoCreated = useRef(false); useEffect(() => { // 如果已有 conversationId 或 currentConversation,无需创建 if (conversationId || currentConversation || hasAutoCreated.current) { return; } hasAutoCreated.current = true; console.log('[ProtocolAgentPage] 自动创建新对话...'); createConversation().then(newConv => { if (newConv) { console.log('[ProtocolAgentPage] 新对话创建成功:', newConv.id); navigate(`/ai-qa/protocol-agent/${newConv.id}`, { replace: true }); } }); }, [conversationId, currentConversation, createConversation, navigate]); // 获取当前阶段信息 const currentStageName = context?.stageName || '科学问题梳理'; const currentStageIndex = context?.stages?.findIndex(s => s.status === 'current') ?? 0; // 创建新对话(立即创建,保证功能正常) const handleNewConversation = async () => { const newConv = await createConversation(); if (newConv) { navigate(`/ai-qa/protocol-agent/${newConv.id}`); setSidebarCollapsed(true); } }; // 选择对话 const handleSelectConversation = (id: string) => { selectConversation(id); navigate(`/ai-qa/protocol-agent/${id}`); setSidebarCollapsed(true); }; // 返回AgentHub const handleBack = () => { navigate('/ai-qa'); }; // 更新对话标题 const handleTitleUpdate = (title: string) => { if (currentConversation?.id) { updateConversationTitle(currentConversation.id, title); } }; // 处理 Word 导出 const handleExportWord = async () => { setIsExporting(true); try { await exportWord(); } catch (error) { alert(`导出失败: ${error instanceof Error ? error.message : '未知错误'}`); } finally { setIsExporting(false); } }; // 处理章节讨论(Phase 2) const handleSectionDiscuss = (sectionId: string, sectionTitle: string) => { // TODO: 实现章节讨论模式 console.log('讨论章节:', sectionId, sectionTitle); alert(`"讨论与优化" 功能将在 Phase 2 实现\n\n章节: ${sectionTitle}`); }; // 计算当前布局比例 const currentLayoutRatio = LAYOUT_RATIOS[viewMode]; // 如果没有conversationId,显示等待状态 if (!conversationId) { return (

正在初始化...

); } return (
{/* 可折叠侧边栏 - Gemini风格 */} {/* 主工作区 */}
{/* 顶部导航 */}

研究方案制定 Agent

Orchestrator Online
{/* 视图切换器 */}
当前阶段: Step {currentStageIndex + 1}: {currentStageName}
{/* 聊天 + 右侧面板(动态切换) */}
} rightPanel={ viewMode === 'context' ? ( ) : ( ) } />
); }; export default ProtocolAgentPage;