diff --git a/app/admin/connection-monitor/page.tsx b/app/admin/connection-monitor/page.tsx deleted file mode 100644 index 48cc42f..0000000 --- a/app/admin/connection-monitor/page.tsx +++ /dev/null @@ -1,371 +0,0 @@ -'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, Trash2, Settings, Activity, Clock, Users } from 'lucide-react'; - -interface ConnectionStats { - totalConnections: number; - idleConnections: number; - oldConnections: number; - maxIdleTime: number; - maxConnectionAge: number; - connections: Array<{ - createdAt: string; - lastUsed: string; - idleTime: number; - age: number; - userId?: string; - sessionId?: string; - }>; -} - -export default function ConnectionMonitorPage() { - const [stats, setStats] = useState(null); - const [loading, setLoading] = useState(false); - const [message, setMessage] = useState(''); - const [error, setError] = useState(''); - const [maxIdleTime, setMaxIdleTime] = useState(300000); // 5分鐘 - const [maxConnectionAge, setMaxConnectionAge] = useState(1800000); // 30分鐘 - - // 獲取連線統計 - const fetchStats = async () => { - try { - setLoading(true); - const response = await fetch('/api/connection-monitor?action=stats'); - const data = await response.json(); - - if (data.success) { - setStats(data.data); - setMessage('統計更新成功'); - setError(''); - } else { - setError(data.error || '獲取統計失敗'); - } - } catch (err) { - setError('網路錯誤: ' + (err instanceof Error ? err.message : '未知錯誤')); - } finally { - setLoading(false); - } - }; - - // 強制清理連線 - const forceCleanup = async () => { - if (!confirm('確定要強制清理所有連線嗎?這可能會影響正在進行的操作!')) { - return; - } - - try { - setLoading(true); - const response = await fetch('/api/connection-monitor?action=cleanup'); - const data = await response.json(); - - if (data.success) { - setMessage('連線清理完成'); - setError(''); - await fetchStats(); // 重新獲取統計 - } else { - setError(data.error || '清理失敗'); - } - } catch (err) { - setError('清理錯誤: ' + (err instanceof Error ? err.message : '未知錯誤')); - } finally { - setLoading(false); - } - }; - - // 測試智能連線 - const testConnection = async () => { - try { - setLoading(true); - const response = await fetch('/api/connection-monitor?action=test'); - const data = await response.json(); - - if (data.success) { - setMessage('智能連線測試成功'); - setError(''); - await fetchStats(); // 重新獲取統計 - } else { - setError(data.error || '測試失敗'); - } - } catch (err) { - setError('測試錯誤: ' + (err instanceof Error ? err.message : '未知錯誤')); - } finally { - setLoading(false); - } - }; - - // 更新清理配置 - const updateConfig = async () => { - try { - setLoading(true); - const response = await fetch('/api/connection-monitor', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - action: 'config', - maxIdleTime, - maxConnectionAge - }), - }); - - const data = await response.json(); - - if (data.success) { - setMessage('清理配置更新成功'); - setError(''); - await fetchStats(); // 重新獲取統計 - } else { - setError(data.error || '配置更新失敗'); - } - } catch (err) { - setError('配置更新錯誤: ' + (err instanceof Error ? err.message : '未知錯誤')); - } finally { - setLoading(false); - } - }; - - // 格式化時間 - const formatTime = (ms: number) => { - const seconds = Math.floor(ms / 1000); - const minutes = Math.floor(seconds / 60); - const hours = Math.floor(minutes / 60); - - if (hours > 0) return `${hours}h ${minutes % 60}m`; - if (minutes > 0) return `${minutes}m ${seconds % 60}s`; - return `${seconds}s`; - }; - - // 組件載入時獲取統計 - useEffect(() => { - fetchStats(); - - // 每30秒自動更新統計 - const interval = setInterval(fetchStats, 30000); - return () => clearInterval(interval); - }, []); - - return ( -
-
-
-

連線監控管理

-

- 監控和管理資料庫連線的生命週期 -

-
- -
- - {/* 統計概覽 */} - {stats && ( -
- - -
- -
-

總連線數

-

{stats.totalConnections}

-
-
-
-
- - - -
- -
-

空閒連線

-

{stats.idleConnections}

-
-
-
-
- - - -
- -
-

舊連線

-

{stats.oldConnections}

-
-
-
-
- - - -
- -
-

健康狀態

-

- {stats.idleConnections + stats.oldConnections === 0 ? '良好' : '需清理'} -

-
-
-
-
-
- )} - - {/* 操作按鈕 */} - - - - - 連線管理 - - - 管理和清理資料庫連線 - - - -
- - - - - -
- - {/* 配置設定 */} -
-
- - setMaxIdleTime(Number(e.target.value))} - placeholder="300000 (5分鐘)" - /> -
-
- - setMaxConnectionAge(Number(e.target.value))} - placeholder="1800000 (30分鐘)" - /> -
-
-
-
- - {/* 連線詳情 */} - {stats && stats.connections.length > 0 && ( - - - 連線詳情 - - 當前活躍的資料庫連線列表 - - - -
- {stats.connections.map((conn, index) => ( -
-
- #{index + 1} -
-

- 創建時間: {new Date(conn.createdAt).toLocaleString()} -

-

- 最後使用: {new Date(conn.lastUsed).toLocaleString()} -

-
-
-
- stats.maxIdleTime ? "destructive" : "default"}> - 空閒: {formatTime(conn.idleTime)} - - stats.maxConnectionAge ? "destructive" : "default"}> - 年齡: {formatTime(conn.age)} - - {conn.userId && ( - 用戶: {conn.userId} - )} -
-
- ))} -
-
-
- )} - - {/* 訊息顯示 */} - {message && ( - - - {message} - - )} - - {error && ( - - - {error} - - )} - - {/* 說明資訊 */} - - - 智能連線管理說明 - - -

自動清理: 系統每30秒自動檢查並清理空閒或過期的連線

-

智能追蹤: 追蹤每個連線的創建時間、最後使用時間和用戶信息

-

即時監控: 實時顯示連線狀態,幫助識別連線洩漏問題

-

自動釋放: 查詢完成後自動釋放連線,避免連線累積

-

用戶關閉網頁: 空閒連線會在設定的時間後自動清理

-
-
-
- ); -} diff --git a/app/admin/database-shutdown/page.tsx b/app/admin/database-shutdown/page.tsx deleted file mode 100644 index 9b9ea18..0000000 --- a/app/admin/database-shutdown/page.tsx +++ /dev/null @@ -1,267 +0,0 @@ -'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 { Loader2, Database, Power, AlertTriangle, CheckCircle } from 'lucide-react'; - -interface ShutdownStatus { - isShuttingDown: boolean; - handlerCount: number; - registeredHandlers: string[]; -} - -export default function DatabaseShutdownPage() { - const [status, setStatus] = useState(null); - const [loading, setLoading] = useState(false); - const [message, setMessage] = useState(''); - const [error, setError] = useState(''); - - // 獲取關閉狀態 - const fetchStatus = async () => { - try { - setLoading(true); - const response = await fetch('/api/test-shutdown?action=status'); - const data = await response.json(); - - if (data.success) { - setStatus(data.data); - setMessage('狀態更新成功'); - setError(''); - } else { - setError(data.error || '獲取狀態失敗'); - } - } catch (err) { - setError('網路錯誤: ' + (err instanceof Error ? err.message : '未知錯誤')); - } finally { - setLoading(false); - } - }; - - // 測試關閉機制 - const testShutdown = async () => { - try { - setLoading(true); - const response = await fetch('/api/test-shutdown?action=test'); - const data = await response.json(); - - if (data.success) { - setMessage('關閉機制測試成功'); - setError(''); - await fetchStatus(); // 重新獲取狀態 - } else { - setError(data.error || '測試失敗'); - } - } catch (err) { - setError('測試錯誤: ' + (err instanceof Error ? err.message : '未知錯誤')); - } finally { - setLoading(false); - } - }; - - // 強制關閉測試 - const forceShutdown = async () => { - if (!confirm('確定要執行強制關閉測試嗎?這可能會影響應用程式運行!')) { - return; - } - - try { - setLoading(true); - const response = await fetch('/api/test-shutdown?action=force'); - const data = await response.json(); - - if (data.success) { - setMessage('強制關閉測試完成'); - setError(''); - await fetchStatus(); // 重新獲取狀態 - } else { - setError(data.error || '強制關閉測試失敗'); - } - } catch (err) { - setError('強制關閉錯誤: ' + (err instanceof Error ? err.message : '未知錯誤')); - } finally { - setLoading(false); - } - }; - - // 優雅關閉測試 - const gracefulShutdown = async () => { - if (!confirm('確定要執行優雅關閉測試嗎?這會關閉所有資料庫連線!')) { - return; - } - - try { - setLoading(true); - const response = await fetch('/api/test-shutdown', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ action: 'graceful' }), - }); - - const data = await response.json(); - - if (data.success) { - setMessage('優雅關閉測試完成'); - setError(''); - await fetchStatus(); // 重新獲取狀態 - } else { - setError(data.error || '優雅關閉測試失敗'); - } - } catch (err) { - setError('優雅關閉錯誤: ' + (err instanceof Error ? err.message : '未知錯誤')); - } finally { - setLoading(false); - } - }; - - // 組件載入時獲取狀態 - useEffect(() => { - fetchStatus(); - }, []); - - return ( -
-
-
-

資料庫關閉管理

-

- 監控和管理資料庫連線的關閉機制 -

-
- -
- - {/* 狀態顯示 */} - {status && ( - - - - - 關閉狀態 - - - 當前資料庫關閉管理器的運行狀態 - - - -
-
- 關閉狀態: - - {status.isShuttingDown ? "關閉中" : "正常"} - -
-
- 處理器數量: - {status.handlerCount} -
-
- 狀態: - - {status.isShuttingDown ? "異常" : "正常"} - -
-
- -
- 已註冊的處理器: -
- {status.registeredHandlers.map((handler, index) => ( - - {handler} - - ))} -
-
-
-
- )} - - {/* 操作按鈕 */} - - - - - 關閉操作 - - - 測試和管理資料庫關閉機制 - - - -
- - - - - -
-
-
- - {/* 訊息顯示 */} - {message && ( - - - {message} - - )} - - {error && ( - - - {error} - - )} - - {/* 說明資訊 */} - - - 使用說明 - - -

測試關閉機制: 檢查關閉處理器是否正常註冊,不會實際關閉連線

-

強制關閉測試: 模擬強制關閉所有資料庫連線(用於測試)

-

優雅關閉測試: 執行完整的優雅關閉流程(會實際關閉連線)

-

• 當應用程式收到 SIGINT 或 SIGTERM 信號時,會自動執行優雅關閉

-

• 關閉管理器會確保所有資料庫連線池都被正確關閉

-
-
-
- ); -} diff --git a/app/admin/emergency-cleanup/page.tsx b/app/admin/emergency-cleanup/page.tsx deleted file mode 100644 index eb5124d..0000000 --- a/app/admin/emergency-cleanup/page.tsx +++ /dev/null @@ -1,281 +0,0 @@ -'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 { Loader2, Database, AlertTriangle, Trash2, Eye, Zap } from 'lucide-react'; - -interface ConnectionDetail { - ID: number; - USER: string; - HOST: string; - DB: string; - COMMAND: string; - TIME: number; - STATE: string; - INFO?: string; -} - -interface ConnectionData { - connectionCount: number; - connections: ConnectionDetail[]; -} - -export default function EmergencyCleanupPage() { - const [connectionData, setConnectionData] = useState(null); - const [loading, setLoading] = useState(false); - const [message, setMessage] = useState(''); - const [error, setError] = useState(''); - - // 獲取連線詳情 - const fetchConnectionDetails = async () => { - try { - setLoading(true); - const response = await fetch('/api/emergency-cleanup?action=details'); - const data = await response.json(); - - if (data.success) { - setConnectionData(data.data); - setMessage('連線詳情更新成功'); - setError(''); - } else { - setError(data.error || '獲取連線詳情失敗'); - } - } catch (err) { - setError('網路錯誤: ' + (err instanceof Error ? err.message : '未知錯誤')); - } finally { - setLoading(false); - } - }; - - // 執行緊急清理 - const executeEmergencyCleanup = async () => { - if (!confirm('確定要執行緊急清理嗎?這會關閉所有資料庫連線!')) { - return; - } - - try { - setLoading(true); - const response = await fetch('/api/emergency-cleanup', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ action: 'cleanup' }), - }); - - const data = await response.json(); - - if (data.success) { - setMessage('緊急清理完成'); - setError(''); - await fetchConnectionDetails(); // 重新獲取詳情 - } else { - setError(data.error || '緊急清理失敗'); - } - } catch (err) { - setError('緊急清理錯誤: ' + (err instanceof Error ? err.message : '未知錯誤')); - } finally { - setLoading(false); - } - }; - - // 強制殺死所有連線 - const forceKillAllConnections = async () => { - if (!confirm('確定要強制殺死所有連線嗎?這會立即終止所有資料庫連線!')) { - return; - } - - try { - setLoading(true); - const response = await fetch('/api/emergency-cleanup', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ action: 'kill-all' }), - }); - - const data = await response.json(); - - if (data.success) { - setMessage('強制殺死連線完成'); - setError(''); - await fetchConnectionDetails(); // 重新獲取詳情 - } else { - setError(data.error || '強制殺死連線失敗'); - } - } catch (err) { - setError('強制殺死連線錯誤: ' + (err instanceof Error ? err.message : '未知錯誤')); - } finally { - setLoading(false); - } - }; - - // 組件載入時獲取連線詳情 - useEffect(() => { - fetchConnectionDetails(); - }, []); - - return ( -
-
-
-

緊急連線清理

-

- 緊急清理和強制關閉資料庫連線 -

-
- -
- - {/* 警告提示 */} - - - - 警告: 這些操作會立即關閉所有資料庫連線,可能影響正在運行的應用程式。請謹慎使用! - - - - {/* 連線統計 */} - {connectionData && ( - - - - - 當前連線狀態 - - - 資料庫連線的詳細信息 - - - -
- - 總連線數: {connectionData.connectionCount} - - 10 ? "destructive" : "default"} - className="text-lg px-3 py-1" - > - 狀態: {connectionData.connectionCount > 10 ? "異常" : "正常"} - -
-
-
- )} - - {/* 緊急操作 */} - - - - - 緊急操作 - - - 立即清理和關閉資料庫連線 - - - -
- - - -
-
-
- - {/* 連線詳情列表 */} - {connectionData && connectionData.connections.length > 0 && ( - - - 連線詳情列表 - - 當前所有資料庫連線的詳細信息 - - - -
- {connectionData.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} - - )} - - {/* 使用說明 */} - - - 使用說明 - - -

緊急清理連線: 停止監控並關閉所有連線池,這是較溫和的方式

-

強制殺死所有連線: 直接殺死資料庫中的所有連線,這是更激進的方式

-

重新整理: 獲取最新的連線狀態和詳情

-

• 建議先嘗試「緊急清理連線」,如果無效再使用「強制殺死所有連線」

-
-
-
- ); -} diff --git a/app/admin/ip-cleanup/page.tsx b/app/admin/ip-cleanup/page.tsx deleted file mode 100644 index c811651..0000000 --- a/app/admin/ip-cleanup/page.tsx +++ /dev/null @@ -1,442 +0,0 @@ -'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 的所有連線

-
-
-
- ); -} diff --git a/app/admin/scoring-form-test/page.tsx b/app/admin/scoring-form-test/page.tsx deleted file mode 100644 index 5eb433e..0000000 --- a/app/admin/scoring-form-test/page.tsx +++ /dev/null @@ -1,195 +0,0 @@ -"use client" - -import { useState } from "react" -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" -import { Button } from "@/components/ui/button" -import { Label } from "@/components/ui/label" -import { Textarea } from "@/components/ui/textarea" -import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from "@/components/ui/dialog" -import { CheckCircle, Edit, Loader2 } from "lucide-react" - -export default function ScoringFormTestPage() { - const [showScoringForm, setShowScoringForm] = useState(false) - const [manualScoring, setManualScoring] = useState({ - judgeId: "judge1", - participantId: "app1", - scores: { - "創新性": 0, - "技術性": 0, - "實用性": 0, - "展示效果": 0, - "影響力": 0 - }, - comments: "" - }) - const [isLoading, setIsLoading] = useState(false) - - const scoringRules = [ - { name: "創新性", description: "技術創新程度和獨特性", weight: 25 }, - { name: "技術性", description: "技術實現的複雜度和穩定性", weight: 20 }, - { name: "實用性", description: "實際應用價值和用戶體驗", weight: 25 }, - { name: "展示效果", description: "演示效果和表達能力", weight: 15 }, - { name: "影響力", description: "對行業和社會的潛在影響", weight: 15 } - ] - - const calculateTotalScore = (scores: Record): number => { - let totalScore = 0 - let totalWeight = 0 - - scoringRules.forEach(rule => { - const score = scores[rule.name] || 0 - const weight = rule.weight || 1 - totalScore += score * weight - totalWeight += weight - }) - - return totalWeight > 0 ? Math.round(totalScore / totalWeight) : 0 - } - - const handleSubmitScore = async () => { - setIsLoading(true) - // 模擬提交 - setTimeout(() => { - setIsLoading(false) - setShowScoringForm(false) - }, 2000) - } - - return ( -
-
-

評分表單測試

-

測試完整的評分表單功能

-
- - - - 評分表單演示 - 點擊按鈕查看完整的評分表單 - - - - - - - - - - - - 評分表單 - - - 為參賽者進行評分,請根據各項指標進行評分 - - - -
- {/* 評分項目 */} -
-

評分項目

- {scoringRules.map((rule, index) => ( -
-
-
- -

{rule.description}

-

權重:{rule.weight}%

-
-
- - {manualScoring.scores[rule.name] || 0} / 10 - -
-
- - {/* 評分按鈕 */} -
- {Array.from({ length: 10 }, (_, i) => i + 1).map((score) => ( - - ))} -
-
- ))} -
- - {/* 總分顯示 */} -
-
-
- 總分 -

根據權重計算的綜合評分

-
-
- - {calculateTotalScore(manualScoring.scores)} - - / 10 -
-
-
- - {/* 評審意見 */} -
- -