/** * API 调用日志页面 */ 'use client'; import { useState, useEffect } from 'react'; import { useSession } from 'next-auth/react'; import { useRouter } from 'next/navigation'; interface ApiLog { id: string; apiKeyName: string; endpoint: string; method: string; statusCode: number; responseTime: number; requestBody: any; responseBody: any; taskNo: string | null; createdAt: string; } export default function ApiLogsPage() { const { data: session, status } = useSession(); const router = useRouter(); const [logs, setLogs] = useState([]); const [loading, setLoading] = useState(true); const [selectedLog, setSelectedLog] = useState(null); // 筛选条件 const [taskNo, setTaskNo] = useState(''); const [startDate, setStartDate] = useState(''); const [endDate, setEndDate] = useState(''); const [offset, setOffset] = useState(0); const [total, setTotal] = useState(0); const limit = 50; // 权限检查 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]); // 加载日志 useEffect(() => { if (status === 'authenticated') { fetchLogs(); } }, [status, offset]); const fetchLogs = async () => { try { setLoading(true); const params = new URLSearchParams({ limit: limit.toString(), offset: offset.toString(), }); if (taskNo) params.append('taskNo', taskNo); if (startDate) params.append('startDate', startDate); if (endDate) params.append('endDate', endDate); const response = await fetch(`/api/admin/api-logs?${params}`); if (response.ok) { const result = await response.json(); setLogs(result.data.logs); setTotal(result.data.total); } } catch (error) { console.error('加载失败:', error); } finally { setLoading(false); } }; const handleSearch = () => { setOffset(0); fetchLogs(); }; const handleReset = () => { setTaskNo(''); setStartDate(''); setEndDate(''); setOffset(0); setTimeout(fetchLogs, 0); }; const getStatusColor = (statusCode: number) => { if (statusCode >= 200 && statusCode < 300) return 'text-green-600'; if (statusCode >= 400 && statusCode < 500) return 'text-yellow-600'; return 'text-red-600'; }; if (loading && logs.length === 0) { return
加载中...
; } const totalPages = Math.ceil(total / limit); const currentPage = Math.floor(offset / limit) + 1; return (

API 调用日志

{/* 筛选条件 */}
setTaskNo(e.target.value)} placeholder="输入任务号" className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" />
setStartDate(e.target.value)} className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" />
setEndDate(e.target.value)} className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" />
{/* 统计信息 */}
共 {total} 条记录,当前显示第 {offset + 1} - {Math.min(offset + limit, total)} 条
{/* 日志列表 */}
{logs.map((log) => ( ))}
时间 API Key 任务号 接口 方法 状态码 响应时间 操作
{new Date(log.createdAt).toLocaleString('zh-CN')} {log.apiKeyName} {log.taskNo || '-'} {log.endpoint} {log.method} {log.statusCode} {log.responseTime}ms
{/* 分页 */} {totalPages > 1 && (
第 {currentPage} / {totalPages} 页
)} {/* 详情模态框 */} {selectedLog && (

调用详情

时间: {new Date(selectedLog.createdAt).toLocaleString('zh-CN')}
API Key: {selectedLog.apiKeyName}
任务号: {selectedLog.taskNo || '-'}
接口: {selectedLog.endpoint}
方法: {selectedLog.method}
状态码: {selectedLog.statusCode}
响应时间: {selectedLog.responseTime}ms
{selectedLog.requestBody && (

请求体

                      {JSON.stringify(selectedLog.requestBody, null, 2)}
                    
)} {selectedLog.responseBody && (

响应体

                      {JSON.stringify(selectedLog.responseBody, null, 2)}
                    
)}
)}
); }