import { useEffect, useState, useCallback } from 'react' import { getAuditLogs } from '../api/audit' import Table, { type TableColumn } from '../components/ui/Table' import Button from '../components/ui/Button' import toast from '../components/ui/Toast' interface AuditRecord { id: string username: string action: string target: string detail: string | null ip_address: string | null created_at: string } const ACTION_OPTIONS = [ '', 'keys.batch_overwrite', 'gateway.toggle', 'cron.trigger', 'user.login', 'user.update_role', 'user.approve', 'keys.generate', 'kaban.create', 'kaban.update', ] export default function AuditLogPage() { const [logs, setLogs] = useState([]) const [page, setPage] = useState(1) const [hasMore, setHasMore] = useState(true) const [loading, setLoading] = useState(false) const [actionFilter, setActionFilter] = useState('') const fetchLogs = useCallback(async (p: number, action?: string) => { setLoading(true) try { const params: Record = { page: p, page_size: 20 } if (action) params.action = action const res = await getAuditLogs(params) const data: AuditRecord[] = res.data setLogs(data) setHasMore(data.length === 20) } catch { toast.error('加载审计日志失败') } finally { setLoading(false) } }, []) useEffect(() => { fetchLogs(page, actionFilter) }, [page, fetchLogs]) const handleFilterChange = (val: string) => { setActionFilter(val) setPage(1) } const columns: TableColumn[] = [ { key: 'created_at', label: '时间', width: 180 }, { key: 'username', label: '用户', width: 100 }, { key: 'action', label: '操作', width: 160 }, { key: 'target', label: '目标', width: 200 }, { key: 'detail', label: '详情' }, { key: 'ip_address', label: 'IP', width: 140 }, ] const data = logs.map((l) => ({ created_at: new Date(l.created_at).toLocaleString('zh-CN'), username: l.username, action: l.action, target: l.target, detail: l.detail ?? '-', ip_address: l.ip_address ?? '-', })) return (

审计日志

操作审计记录

{/* Filter */}
{/* Pagination */}
第 {page} 页
) }