import { useState, useEffect } from 'react'; import { Card, CardContent } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Badge } from '@/components/ui/badge'; import { Search, RefreshCw } from 'lucide-react'; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from '@/components/ui/table'; import { auditApi } from '@/services/api'; import type { OperationLog } from '@/types'; interface SystemLogsTabProps { searchQuery: string; setSearchQuery: (v: string) => void; } // 将后端审计日志规范化为前端 OperationLog 类型 // Logan.Li function normalizeLog(raw: any): OperationLog { return { id: String(raw.id ?? ''), userId: String(raw.user_id ?? raw.userId ?? ''), username: raw.username ?? '', module: raw.module ?? raw.resource ?? '', action: raw.action ?? '', resource: raw.resource ?? '', ip: raw.ip ?? '', userAgent: raw.user_agent ?? raw.userAgent ?? '', result: raw.result === 'failure' ? 'failure' : 'success', message: raw.message ?? raw.detail, createdAt: raw.createdAt ?? raw.created_at ?? '', }; } export function SystemLogsTab({ searchQuery, setSearchQuery }: SystemLogsTabProps) { const [logs, setLogs] = useState([]); const [loading, setLoading] = useState(true); const fetchLogs = async () => { setLoading(true); try { const resp = await auditApi.getLogs({ page: 1, page_size: 50 }); const list = resp?.list ?? []; setLogs(list.map(normalizeLog)); } catch { setLogs([]); } finally { setLoading(false); } }; useEffect(() => { fetchLogs(); }, []); const filteredLogs = logs.filter( (log) => log.username.toLowerCase().includes(searchQuery.toLowerCase()) || log.module.toLowerCase().includes(searchQuery.toLowerCase()) || log.action.toLowerCase().includes(searchQuery.toLowerCase()) ); const getLogResultBadge = (result: OperationLog['result']) => { return result === 'success' ? ( 成功 ) : ( 失败 ); }; return ( <> {/* Filters */}
setSearchQuery(e.target.value)} className="pl-9 h-9 bg-slate-800/50 border-slate-700 text-slate-200 placeholder:text-slate-500" />
{/* Logs Table */}
{loading ? (
) : filteredLogs.length === 0 ? (

暂无操作日志

) : ( 时间 用户 模块 操作 资源 IP地址 结果 {filteredLogs.map((log) => ( {log.createdAt ? new Date(log.createdAt).toLocaleString() : '--'} {log.username || '--'} {log.module || '--'} {log.action || '--'} {log.resource || '--'} {log.ip || '--'} {getLogResultBadge(log.result)} ))}
)}
); }