'use client'; import { useState, useEffect } from 'react'; import api from '@/lib/api'; import { Server, Play, RotateCw, FileText, Settings, Search, RefreshCw, CheckCircle2, AlertCircle } from 'lucide-react'; import DockerControl from './DockerControl'; import LogViewer from './LogViewer'; import ConfigManager from './ConfigManager'; interface ServerConfig { host: string; port: number; username: string; password?: string; key_file?: string; project_path: string; } interface PreConfiguredServer { id: string; name: string; host: string; } export default function RemoteServerControl() { const [activeTab, setActiveTab] = useState<'docker' | 'logs' | 'config'>('docker'); const [usePreConfigured, setUsePreConfigured] = useState(true); const [preConfiguredServers, setPreConfiguredServers] = useState([]); const [selectedServerId, setSelectedServerId] = useState(''); const [serverConfig, setServerConfig] = useState({ host: '', port: 22, username: 'root', password: '', key_file: '', project_path: '/root/troov-asyncio', }); const [isConnected, setIsConnected] = useState(false); const [connecting, setConnecting] = useState(false); const [connectionError, setConnectionError] = useState(null); useEffect(() => { const fetchServers = async () => { try { const response = await api.get('/api/remote/servers'); if (response.data.code === 0) { const servers = response.data.data.servers || []; setPreConfiguredServers(servers); if (servers.length > 0) setSelectedServerId(servers[0].id); } } catch (err) { console.error('获取服务器列表失败:', err); } }; fetchServers(); }, []); const handleConnect = async () => { setConnecting(true); setConnectionError(null); try { let response; if (usePreConfigured) { if (!selectedServerId) { setConnectionError('请选择服务器'); setConnecting(false); return; } response = await api.post('/api/remote/server/docker/status', { server_id: selectedServerId }); } else { if (!serverConfig.host || !serverConfig.username) { setConnectionError('请填写服务器地址和用户名'); setConnecting(false); return; } response = await api.post('/api/remote/docker/status', serverConfig); } if (response.data.code === 0) { setIsConnected(true); setConnectionError(null); } else { setConnectionError(response.data.message || '连接失败'); setIsConnected(false); } } catch (err: any) { console.error('连接错误详情:', err); let errorMsg = '连接失败,请检查配置'; if (err.response) { const status = err.response.status; if (status === 404) errorMsg = 'API 路由未找到 (404)'; else if (status === 401) errorMsg = '未授权 (401)'; else if (err.response.data?.message) errorMsg = err.response.data.message; } setConnectionError(errorMsg); setIsConnected(false); } finally { setConnecting(false); } }; const handleDisconnect = () => { setIsConnected(false); setConnectionError(null); }; return (
{/* === 卡片 1: 服务器连接配置 === */}
{/* 卡片头部 */}

服务器连接

{/* 切换开关:移动端全宽 */}
{/* 卡片内容 */}
{usePreConfigured ? (
) : ( // 手动输入模式:移动端单列,桌面端双列
setServerConfig({ ...serverConfig, host: e.target.value })} placeholder="192.168.1.100" className="w-full px-3 py-2.5 border border-slate-300 rounded-lg text-sm focus:ring-2 focus:ring-blue-500 outline-none" disabled={isConnected} />
setServerConfig({ ...serverConfig, port: parseInt(e.target.value) || 22 })} className="w-full px-3 py-2.5 border border-slate-300 rounded-lg text-sm focus:ring-2 focus:ring-blue-500 outline-none" disabled={isConnected} />
{/* 其他字段同理... */}
setServerConfig({ ...serverConfig, username: e.target.value })} placeholder="root" className="w-full px-3 py-2.5 border border-slate-300 rounded-lg text-sm focus:ring-2 focus:ring-blue-500 outline-none" disabled={isConnected} />
setServerConfig({ ...serverConfig, password: e.target.value })} className="w-full px-3 py-2.5 border border-slate-300 rounded-lg text-sm focus:ring-2 focus:ring-blue-500 outline-none" disabled={isConnected} />
)} {/* 状态反馈区 */} {connectionError && (
{connectionError}
)} {isConnected && (
已成功连接到服务器
)} {/* 操作按钮:移动端垂直排列全宽,桌面端水平 */}
{!isConnected ? ( <> ) : ( )}
{/* === 卡片 2: 功能控制区 (连接后显示) === */} {isConnected && (
{/* Tab 导航:移动端支持横向滚动 */}
{activeTab === 'docker' && ( )} {activeTab === 'logs' && ( )} {activeTab === 'config' && ( )}
)}
); }