// ============================================================ // 操作日志 // ============================================================ import { useState } from 'react' import { useQuery } from '@tanstack/react-query' import { Tag, Select, Typography } from 'antd' import type { ProColumns } from '@ant-design/pro-components' import { ProTable } from '@ant-design/pro-components' import { logService } from '@/services/logs' import { actionLabels, actionColors } from '@/constants/status' import type { OperationLog } from '@/types' const { Title } = Typography const actionOptions = Object.entries(actionLabels).map(([value, label]) => ({ value, label })) export default function Logs() { const [page, setPage] = useState(1) const [actionFilter, setActionFilter] = useState(undefined) const { data, isLoading } = useQuery({ queryKey: ['logs', page, actionFilter], queryFn: ({ signal }) => logService.list({ page, page_size: 20, action: actionFilter }, signal), }) const columns: ProColumns[] = [ { title: '操作类型', dataIndex: 'action', width: 140, render: (_, r) => ( {actionLabels[r.action] || r.action} ), }, { title: '目标类型', dataIndex: 'target_type', width: 100, render: (_, r) => r.target_type || '-' }, { title: '目标 ID', dataIndex: 'target_id', width: 120, render: (_, r) => r.target_id ? {r.target_id.substring(0, 8)}... : '-' }, { title: '详情', dataIndex: 'details', width: 250, ellipsis: true, render: (_, r) => { if (!r.details) return '-' if (typeof r.details === 'string') return r.details return JSON.stringify(r.details) }, }, { title: 'IP 地址', dataIndex: 'ip_address', width: 130, render: (_, r) => {r.ip_address || '-'} }, { title: '时间', dataIndex: 'created_at', width: 180, render: (_, r) => new Date(r.created_at).toLocaleString('zh-CN'), }, ] return (
操作日志