'use client'; import { useState } from 'react'; import { PageHeader } from '@/components/layout/page-header'; import { useQuery } from '@tanstack/react-query'; import { apiClient } from '@/lib/api/client'; import { formatDateTime } from '@/lib/utils/date'; import { Card, CardContent } from '@/components/ui/card'; import { Input } from '@/components/ui/input'; import { Button } from '@/components/ui/button'; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; import { Skeleton } from '@/components/ui/skeleton'; import { Search, ChevronLeft, ChevronRight } from 'lucide-react'; import type { PaginatedResponse } from '@/types/api'; interface AuditLog { id: string; adminId: string; adminUsername: string; action: string; resource: string; resourceId: string | null; details: string | null; ipAddress: string; createdAt: string; } const actionLabels: Record = { CREATE: { label: '创建', className: 'bg-green-100 text-green-700' }, UPDATE: { label: '更新', className: 'bg-blue-100 text-blue-700' }, DELETE: { label: '删除', className: 'bg-red-100 text-red-700' }, LOGIN: { label: '登录', className: 'bg-purple-100 text-purple-700' }, LOGOUT: { label: '登出', className: 'bg-gray-100 text-gray-600' }, }; export default function AuditLogsPage() { const [page, setPage] = useState(1); const [action, setAction] = useState('all'); const [keyword, setKeyword] = useState(''); const pageSize = 20; const { data, isLoading, error } = useQuery({ queryKey: ['audit-logs', page, action, keyword], queryFn: async () => { const response = await apiClient.get('/audit', { params: { page, pageSize, action: action === 'all' ? undefined : action, keyword: keyword || undefined }, }); return response.data.data as PaginatedResponse; }, }); const items = data?.items ?? []; return (
setKeyword(e.target.value)} className="pl-10" />
时间 管理员 操作 资源 资源ID 详情 IP地址 {isLoading ? ( [...Array(10)].map((_, i) => ( {[...Array(7)].map((_, j) => ( ))} )) ) : items.length === 0 ? ( 暂无日志 ) : ( items.map((log) => { const actionInfo = actionLabels[log.action] || { label: log.action, className: '' }; return ( {formatDateTime(log.createdAt)} {log.adminUsername} {actionInfo.label} {log.resource} {log.resourceId || '-'} {log.details || '-'} {log.ipAddress} ); }) )}
{data && data.totalPages > 1 && (

共 {data.total} 条,第 {page} / {data.totalPages} 页

)}
); }