import { useState } from 'react'; import { toast } from 'sonner'; import { useUserStore } from '@/store'; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, } from '@/components/ui/dialog'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; import { Button } from '@/components/ui/button'; import { Copy, Check, Terminal, Download, Settings, Play, Cpu } from 'lucide-react'; interface AgentWizardProps { open: boolean; onOpenChange: (open: boolean) => void; } /** 自动检测服务器地址:使用当前浏览器访问的地址(协议+主机+端口) */ function detectServerAddress(): string { if (typeof window !== 'undefined' && window.location) { // 直接用当前浏览器的 origin(如 http://10.10.10.150), // Nginx 会将 /agent/ 请求代理到后端 return window.location.origin; } return 'http://127.0.0.1:8080'; } export function AgentWizard({ open, onOpenChange }: AgentWizardProps) { const token = useUserStore((s) => s.token) || ''; const serverUrl = detectServerAddress(); const [copied, setCopied] = useState(false); const [showManualInput, setShowManualInput] = useState(false); const installCommand = `curl -fsSL ${serverUrl.replace(/^http:/, 'http:')}/agent/install.sh | bash -s -- --server ${serverUrl} --token ${token}`; const fallbackCopy = (text: string): boolean => { const textArea = document.createElement('textarea'); textArea.value = text; textArea.style.position = 'fixed'; textArea.style.left = '-9999px'; textArea.style.top = '-9999px'; document.body.appendChild(textArea); textArea.focus(); textArea.select(); let success = false; try { <<<<<<< HEAD // 优先使用现代 Clipboard API(需要 HTTPS 或 localhost) if (navigator.clipboard && window.isSecureContext) { await navigator.clipboard.writeText(installCommand); } else { // 降级方案:用隐藏 textarea + execCommand('copy'),兼容 HTTP 环境 const textarea = document.createElement('textarea'); textarea.value = installCommand; textarea.style.position = 'fixed'; textarea.style.opacity = '0'; textarea.style.pointerEvents = 'none'; document.body.appendChild(textarea); textarea.select(); const ok = document.execCommand('copy'); document.body.removeChild(textarea); if (!ok) throw new Error('execCommand failed'); } setCopied(true); toast.success('安装命令已复制'); setTimeout(() => setCopied(false), 2000); } catch { toast.error('复制失败,请手动选中复制'); ======= success = document.execCommand('copy'); } catch { // execCommand also failed } document.body.removeChild(textArea); return success; }; const handleCopy = async () => { const cmd = installCommand; let success = false; // 方式1: Clipboard API(HTTPS / localhost) try { await navigator.clipboard.writeText(cmd); success = true; } catch { // Clipboard API 不可用 } // 方式2: execCommand fallback(HTTP 也可用) if (!success) { success = fallbackCopy(cmd); } if (success) { setCopied(true); toast.success('安装命令已复制到剪贴板,粘贴到目标主机执行'); setTimeout(() => setCopied(false), 3000); } else { toast.error('自动复制失败,请在下方代码框中手动全选复制 (Ctrl+A → Ctrl+C)'); // 切换到手选模式,展示可编辑文本框 setShowManualInput(true); >>>>>>> ca18ead (feat: run.sh四模式(dev/docker/build/binary) + CLI flags + Redka内嵌Redis + Agent复制修复 + 服务器编辑IP字段 + 安装Agent按钮) } }; const binaryUrl = `${serverUrl}/agent/aiops-agent-linux-amd64`; const manualSteps = [ { icon: Download, title: '1. 下载二进制', commands: [ `curl -fsSL ${binaryUrl} -o /usr/local/bin/aiops-agent`, ], }, { icon: Settings, title: '2. 赋予执行权限', commands: ['chmod +x /usr/local/bin/aiops-agent'], }, { icon: Cpu, title: '3. 创建 systemd 服务', commands: [ `cat > /etc/systemd/system/aiops-agent.service << 'EOF'`, `[Unit]`, `Description=AIOps Agent`, `After=network.target`, ``, `[Service]`, `Type=simple`, `ExecStart=/usr/local/bin/aiops-agent --server ${serverUrl} --token ${token}`, `Restart=always`, `RestartSec=5`, ``, `[Install]`, `WantedBy=multi-user.target`, `EOF`, ], }, { icon: Play, title: '4. 启动并设置开机自启', commands: [ 'systemctl daemon-reload', 'systemctl enable --now aiops-agent', 'systemctl status aiops-agent', ], }, ]; return ( 部署 Agent 在目标主机上执行以下命令即可完成 Agent 安装与注册 安装Agent 手动安装 {/* 自动安装 */}

在目标主机执行以下命令,Agent 将自动下载、安装并启动:

                {installCommand}
              
{/* 手动复制模式:当自动复制失败时展示可全选的文本域 */} {showManualInput && (

⚠️ 自动复制失败。请点击下方输入框全选 (Ctrl+A) 后复制 (Ctrl+C):