'use client'; import React, { useState, useEffect } from 'react'; import { Button } from '@/components/ui/button'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { Badge } from '@/components/ui/badge'; import { Alert, AlertDescription } from '@/components/ui/alert'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Loader2, Database, AlertTriangle, Trash2, Eye, Zap, Globe } from 'lucide-react'; interface ConnectionDetail { ID: number; USER: string; HOST: string; DB: string; COMMAND: string; TIME: number; STATE: string; INFO?: string; } interface ConnectionStatus { ip: string; connectionCount: number; connections: ConnectionDetail[]; } interface LocalStats { clientIP: string; trackedConnections: number; connections: Array<{ connectionId: string; createdAt: string; lastUsed: string; userAgent?: string; }>; } export default function IPCleanupPage() { const [connectionStatus, setConnectionStatus] = useState(null); const [localStats, setLocalStats] = useState(null); const [loading, setLoading] = useState(false); const [message, setMessage] = useState(''); const [error, setError] = useState(''); const [targetIP, setTargetIP] = useState(''); // 獲取當前 IP 的連線狀態 const fetchCurrentIPStatus = async () => { try { setLoading(true); const response = await fetch('/api/ip-cleanup?action=status'); const data = await response.json(); if (data.success) { setConnectionStatus(data.data); setMessage('當前 IP 連線狀態更新成功'); setError(''); } else { setError(data.error || '獲取當前 IP 連線狀態失敗'); } } catch (err) { setError('網路錯誤: ' + (err instanceof Error ? err.message : '未知錯誤')); } finally { setLoading(false); } }; // 獲取指定 IP 的連線狀態 const fetchSpecificIPStatus = async () => { if (!targetIP.trim()) { setError('請輸入目標 IP 地址'); return; } try { setLoading(true); const response = await fetch(`/api/ip-cleanup?action=status-specific&ip=${encodeURIComponent(targetIP)}`); const data = await response.json(); if (data.success) { setConnectionStatus(data.data); setMessage(`指定 IP ${targetIP} 的連線狀態更新成功`); setError(''); } else { setError(data.error || '獲取指定 IP 連線狀態失敗'); } } catch (err) { setError('網路錯誤: ' + (err instanceof Error ? err.message : '未知錯誤')); } finally { setLoading(false); } }; // 獲取本地連線統計 const fetchLocalStats = async () => { try { setLoading(true); const response = await fetch('/api/ip-cleanup?action=local-stats'); const data = await response.json(); if (data.success) { setLocalStats(data.data); setMessage('本地連線統計更新成功'); setError(''); } else { setError(data.error || '獲取本地連線統計失敗'); } } catch (err) { setError('網路錯誤: ' + (err instanceof Error ? err.message : '未知錯誤')); } finally { setLoading(false); } }; // 清理當前 IP 的連線 const cleanupCurrentIP = async () => { if (!confirm('確定要清理當前 IP 的所有連線嗎?')) { return; } try { setLoading(true); const response = await fetch('/api/ip-cleanup', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ action: 'cleanup-current' }), }); const data = await response.json(); if (data.success) { setMessage(data.message || '當前 IP 連線清理完成'); setError(''); await fetchCurrentIPStatus(); // 重新獲取狀態 } else { setError(data.error || '當前 IP 連線清理失敗'); } } catch (err) { setError('當前 IP 連線清理錯誤: ' + (err instanceof Error ? err.message : '未知錯誤')); } finally { setLoading(false); } }; // 清理指定 IP 的連線 const cleanupSpecificIP = async () => { if (!targetIP.trim()) { setError('請輸入目標 IP 地址'); return; } if (!confirm(`確定要清理 IP ${targetIP} 的所有連線嗎?`)) { return; } try { setLoading(true); const response = await fetch('/api/ip-cleanup', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ action: 'cleanup-specific', targetIP: targetIP.trim() }), }); const data = await response.json(); if (data.success) { setMessage(data.message || `IP ${targetIP} 連線清理完成`); setError(''); await fetchSpecificIPStatus(); // 重新獲取狀態 } else { setError(data.error || `IP ${targetIP} 連線清理失敗`); } } catch (err) { setError(`IP ${targetIP} 連線清理錯誤: ` + (err instanceof Error ? err.message : '未知錯誤')); } finally { setLoading(false); } }; // 清理本地追蹤的連線 const cleanupLocalConnections = async () => { try { setLoading(true); const response = await fetch('/api/ip-cleanup', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ action: 'cleanup-local' }), }); const data = await response.json(); if (data.success) { setMessage(data.message || '本地連線清理完成'); setError(''); await fetchLocalStats(); // 重新獲取統計 } else { setError(data.error || '本地連線清理失敗'); } } catch (err) { setError('本地連線清理錯誤: ' + (err instanceof Error ? err.message : '未知錯誤')); } finally { setLoading(false); } }; // 組件載入時獲取狀態 useEffect(() => { fetchCurrentIPStatus(); fetchLocalStats(); }, []); return (

IP 連線管理

基於 IP 地址的智能連線清理和管理

{/* 當前 IP 連線狀態 */} {connectionStatus && ( IP 連線狀態 IP: {connectionStatus.ip} | 連線數: {connectionStatus.connectionCount}
連線數: {connectionStatus.connectionCount} 5 ? "destructive" : "default"} className="text-lg px-3 py-1" > 狀態: {connectionStatus.connectionCount > 5 ? "異常" : "正常"}
)} {/* 本地連線統計 */} {localStats && ( 本地連線統計 客戶端 IP: {localStats.clientIP} | 追蹤連線數: {localStats.trackedConnections}
{localStats.connections.map((conn, index) => (

連線 ID: {conn.connectionId}

創建: {new Date(conn.createdAt).toLocaleString()} | 最後使用: {new Date(conn.lastUsed).toLocaleString()}

))}
)} {/* 操作按鈕 */} IP 連線清理 清理指定 IP 地址的資料庫連線
{/* 指定 IP 清理 */}
setTargetIP(e.target.value)} placeholder="例如: 192.168.1.100" className="flex-1" />
{/* 連線詳情列表 */} {connectionStatus && connectionStatus.connections.length > 0 && ( 連線詳情列表 IP {connectionStatus.ip} 的所有資料庫連線
{connectionStatus.connections.map((conn, index) => (
#{conn.ID}

用戶: {conn.USER} | 主機: {conn.HOST}

資料庫: {conn.DB} | 命令: {conn.COMMAND}

時間: {conn.TIME}s | 狀態: {conn.STATE}

{conn.INFO && (

查詢: {conn.INFO.length > 100 ? conn.INFO.substring(0, 100) + '...' : conn.INFO}

)}
))}
)} {/* 訊息顯示 */} {message && ( {message} )} {error && ( {error} )} {/* 使用說明 */} IP 連線管理說明

當前 IP 連線: 顯示和清理當前訪問者的所有資料庫連線

指定 IP 連線: 輸入特定 IP 地址來查看和清理該 IP 的連線

本地追蹤連線: 清理應用程式內部追蹤的連線記錄

智能清理: 只清理指定 IP 的連線,不影響其他用戶

關閉網站時: 系統會自動清理當前 IP 的所有連線

); }