/** * API Key 管理页面 */ 'use client'; import { useState, useEffect } from 'react'; import { useSession } from 'next-auth/react'; import { useRouter } from 'next/navigation'; import { parseFetchError, handleError } from '@/lib/error-handler'; import { useToast } from '@/hooks/useToast'; import Toast from '@/components/Toast'; interface ApiKey { id: string; name: string; key: string; isActive: boolean; createdBy: string; lastUsedAt: string | null; createdAt: string; } export default function ApiKeysPage() { const { data: session, status } = useSession(); const router = useRouter(); const { toast, showToast } = useToast(); const [apiKeys, setApiKeys] = useState([]); const [loading, setLoading] = useState(true); const [showCreateModal, setShowCreateModal] = useState(false); const [newKeyName, setNewKeyName] = useState(''); const [createdKey, setCreatedKey] = useState(null); // 权限检查 useEffect(() => { if (status === 'unauthenticated') { router.push('/login'); } else if (status === 'authenticated' && session?.user) { const userRole = (session.user as any).role; if (userRole !== 'ADMIN' && userRole !== 'SYSTEM_ADMIN') { router.push('/'); } } }, [status, session, router]); // 加载 API Keys useEffect(() => { if (status === 'authenticated') { fetchApiKeys(); } }, [status]); const fetchApiKeys = async () => { try { const response = await fetch('/api/admin/api-keys'); if (response.ok) { const data = await response.json(); setApiKeys(data.data); } } catch (error) { console.error('加载失败:', error); } finally { setLoading(false); } }; const handleCreate = async () => { if (!newKeyName.trim()) { showToast('请输入密钥名称', { variant: 'error' }); return; } try { const response = await fetch('/api/admin/api-keys', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name: newKeyName }), }); if (response.ok) { const data = await response.json(); setCreatedKey(data.data.key); setNewKeyName(''); fetchApiKeys(); showToast('API Key 创建成功', { variant: 'success' }); } else { const error = await response.json(); showToast(error.error || '创建失败', { variant: 'error' }); } } catch (error) { console.error('创建失败:', error); showToast('创建失败', { variant: 'error' }); } }; const handleToggleActive = async (id: string, isActive: boolean) => { try { const response = await fetch(`/api/admin/api-keys/${id}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ isActive: !isActive }), }); if (response.ok) { fetchApiKeys(); } } catch (error) { console.error('更新失败:', error); } }; const handleDelete = async (id: string) => { if (!confirm('确定要删除此 API Key 吗?')) return; try { const response = await fetch(`/api/admin/api-keys/${id}`, { method: 'DELETE', }); if (response.ok) { fetchApiKeys(); showToast('API Key 删除成功', { variant: 'success' }); } } catch (error) { console.error('删除失败:', error); const { message } = handleError(error); showToast(message, { variant: 'error' }); } }; if (loading) { return
加载中...
; } return (

API Key 管理

{/* API Keys 列表 */}
{apiKeys.map((key) => ( ))}
名称 密钥 状态 最后使用 创建时间 操作
{key.name} {key.key} {key.isActive ? '启用' : '禁用'} {key.lastUsedAt ? new Date(key.lastUsedAt).toLocaleString('zh-CN') : '从未使用'} {new Date(key.createdAt).toLocaleString('zh-CN')}
{/* 创建模态框 */} {showCreateModal && (

创建 API Key

{createdKey ? (

API Key 已创建,请妥善保存:

{createdKey}

注意:此密钥只显示一次,关闭后将无法再次查看

) : (
setNewKeyName(e.target.value)} placeholder="例如:任务系统" className="w-full px-3 py-2 border rounded mb-4" />
)}
)}
); }