import { useState, useEffect } from 'react' import { Plus, Trash2, RefreshCw, CheckCircle2, AlertCircle, Search, Play, MoreHorizontal, X, Server, ShieldCheck } from 'lucide-react' import clsx from 'clsx' export default function AccountManager({ config, onRefresh, onMessage, authFetch }) { const [showAddKey, setShowAddKey] = useState(false) const [showAddAccount, setShowAddAccount] = useState(false) const [newKey, setNewKey] = useState('') const [newAccount, setNewAccount] = useState({ email: '', mobile: '', password: '' }) const [loading, setLoading] = useState(false) const [validating, setValidating] = useState({}) const [validatingAll, setValidatingAll] = useState(false) const [testing, setTesting] = useState({}) const [testingAll, setTestingAll] = useState(false) const [batchProgress, setBatchProgress] = useState({ current: 0, total: 0, results: [] }) const [queueStatus, setQueueStatus] = useState(null) const apiFetch = authFetch || fetch const fetchQueueStatus = async () => { try { const res = await apiFetch('/admin/queue/status') if (res.ok) { const data = await res.json() setQueueStatus(data) } } catch (e) { console.error('Failed to fetch queue status:', e) } } useEffect(() => { fetchQueueStatus() const interval = setInterval(fetchQueueStatus, 5000) return () => clearInterval(interval) }, []) const addKey = async () => { if (!newKey.trim()) return setLoading(true) try { const res = await apiFetch('/admin/keys', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ key: newKey.trim() }), }) if (res.ok) { onMessage('success', 'API Key added successfully') setNewKey('') setShowAddKey(false) onRefresh() } else { const data = await res.json() onMessage('error', data.detail || 'Failed to add') } } catch (e) { onMessage('error', 'Network error') } finally { setLoading(false) } } const deleteKey = async (key) => { if (!confirm('Are you sure you want to delete this API Key?')) return try { const res = await apiFetch(`/admin/keys/${encodeURIComponent(key)}`, { method: 'DELETE' }) if (res.ok) { onMessage('success', 'Deleted successfully') onRefresh() } else { onMessage('error', 'Delete failed') } } catch (e) { onMessage('error', 'Network error') } } const addAccount = async () => { if (!newAccount.password || (!newAccount.email && !newAccount.mobile)) { onMessage('error', 'Password and Email/Mobile are required') return } setLoading(true) try { const res = await apiFetch('/admin/accounts', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(newAccount), }) if (res.ok) { onMessage('success', 'Account added successfully') setNewAccount({ email: '', mobile: '', password: '' }) setShowAddAccount(false) onRefresh() } else { const data = await res.json() onMessage('error', data.detail || 'Failed to add') } } catch (e) { onMessage('error', 'Network error') } finally { setLoading(false) } } const deleteAccount = async (id) => { if (!confirm('Are you sure you want to delete this account?')) return try { const res = await apiFetch(`/admin/accounts/${encodeURIComponent(id)}`, { method: 'DELETE' }) if (res.ok) { onMessage('success', 'Deleted successfully') onRefresh() } else { onMessage('error', 'Delete failed') } } catch (e) { onMessage('error', 'Network error') } } const validateAccount = async (identifier) => { setValidating(prev => ({ ...prev, [identifier]: true })) try { const res = await apiFetch('/admin/accounts/validate', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ identifier }), }) const data = await res.json() onMessage(data.valid ? 'success' : 'error', `${identifier}: ${data.message}`) onRefresh() } catch (e) { onMessage('error', 'Validation failed: ' + e.message) } finally { setValidating(prev => ({ ...prev, [identifier]: false })) } } const validateAllAccounts = async () => { if (!confirm('Validate ALL accounts? This might take a while.')) return const accounts = config.accounts || [] if (accounts.length === 0) return setValidatingAll(true) setBatchProgress({ current: 0, total: accounts.length, results: [] }) let validCount = 0 const results = [] for (let i = 0; i < accounts.length; i++) { const acc = accounts[i] const id = acc.email || acc.mobile try { const res = await apiFetch('/admin/accounts/validate', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ identifier: id }), }) const data = await res.json() results.push({ id, success: data.valid, message: data.message }) if (data.valid) validCount++ } catch (e) { results.push({ id, success: false, message: e.message }) } setBatchProgress({ current: i + 1, total: accounts.length, results: [...results] }) } onMessage('success', `Completed: ${validCount}/${accounts.length} valid`) onRefresh() setValidatingAll(false) } const testAccount = async (identifier) => { setTesting(prev => ({ ...prev, [identifier]: true })) try { const res = await apiFetch('/admin/accounts/test', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ identifier }), }) const data = await res.json() onMessage(data.success ? 'success' : 'error', `${identifier}: ${data.success ? `Success (${data.response_time}ms)` : data.message}`) onRefresh() } catch (e) { onMessage('error', 'Test failed: ' + e.message) } finally { setTesting(prev => ({ ...prev, [identifier]: false })) } } const testAllAccounts = async () => { if (!confirm('Test API connectivity for ALL accounts?')) return const accounts = config.accounts || [] if (accounts.length === 0) return setTestingAll(true) setBatchProgress({ current: 0, total: accounts.length, results: [] }) let successCount = 0 const results = [] for (let i = 0; i < accounts.length; i++) { const acc = accounts[i] const id = acc.email || acc.mobile try { const res = await apiFetch('/admin/accounts/test', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ identifier: id }), }) const data = await res.json() results.push({ id, success: data.success, message: data.message, time: data.response_time }) if (data.success) successCount++ } catch (e) { results.push({ id, success: false, message: e.message }) } setBatchProgress({ current: i + 1, total: accounts.length, results: [...results] }) } onMessage('success', `Completed: ${successCount}/${accounts.length} available`) onRefresh() setTestingAll(false) } return (
Available
In Use
Total Pool
管理 API 访问密钥池
管理 DeepSeek 账号池