import { Card, Table, Tabs, Tag, Input, Space, Button, DatePicker, Select, Typography, Modal, Descriptions } from "antd"; import { useEffect, useState, useMemo } from "react"; import { useTranslation } from "react-i18next"; import { fetchLogs } from "../api"; import { SearchOutlined, ReloadOutlined, InfoCircleOutlined, EyeOutlined, UserOutlined } from "@ant-design/icons"; import { SysLog, UserProfile } from "../types"; const { RangePicker } = DatePicker; const { Text, Title } = Typography; export default function Logs() { const { t } = useTranslation(); const [activeTab, setActiveTab] = useState("OPERATION"); const [loading, setLoading] = useState(false); const [data, setData] = useState([]); const [total, setTotal] = useState(0); const [params, setParams] = useState({ current: 1, size: 10, username: "", status: undefined, startDate: "", endDate: "", operation: "", sortField: "createdAt", sortOrder: "descend" as any }); // Get user profile to check platform admin const userProfile = useMemo(() => { const stored = sessionStorage.getItem("userProfile"); if (!stored) return null; try { return JSON.parse(stored) as UserProfile; } catch (e) { return null; } }, []); const isPlatformAdmin = userProfile?.isPlatformAdmin && userProfile?.tenantId === 0; // Modal for detail view const [detailModalVisible, setDetailModalVisible] = useState(false); const [selectedLog, setSelectedLog] = useState(null); const loadData = async (currentParams = params) => { setLoading(true); try { // Use logType for precise filtering const result = await fetchLogs({ ...currentParams, logType: activeTab }); setData(result.records || []); setTotal(result.total || 0); } finally { setLoading(false); } }; useEffect(() => { loadData(); }, [activeTab, params.current, params.size, params.sortField, params.sortOrder]); const handleTableChange = (pagination: any, filters: any, sorter: any) => { setParams({ ...params, current: pagination.current, size: pagination.pageSize, sortField: sorter.field || "createdAt", sortOrder: sorter.order || "descend" }); }; const handleSearch = () => { setParams({ ...params, current: 1 }); loadData({ ...params, current: 1 }); }; const handleReset = () => { const resetParams = { current: 1, size: 10, username: "", status: undefined, startDate: "", endDate: "", operation: "", sortField: "createdAt", sortOrder: "descend" as any }; setParams(resetParams); loadData(resetParams); }; const showDetail = (record: SysLog) => { setSelectedLog(record); setDetailModalVisible(true); }; const renderDuration = (ms: number) => { if (!ms && ms !== 0) return "-"; let color = ""; if (ms > 1000) color = "#ff4d4f"; // 红色 (慢) else if (ms > 300) color = "#faad14"; // 橘色 (中) return ( 300 ? 600 : 400 }}> {ms}ms ); }; const columns = [ ...(isPlatformAdmin ? [{ title: t('users.tenant'), dataIndex: "tenantName", key: "tenantName", width: 150, render: (text: string) => {text || "系统平台"} }] : []), { title: t('logs.opAccount'), dataIndex: "username", key: "username", width: 120, render: (text: string) => {text || "系统"} }, { title: t('logs.opDetail'), dataIndex: "operation", key: "operation", ellipsis: true, render: (text: string) => {text} }, { title: t('logs.ip'), dataIndex: "ip", key: "ip", width: 130, className: "tabular-nums" }, { title: t('logs.duration'), dataIndex: "duration", key: "duration", width: 100, sorter: true, sortOrder: params.sortField === 'duration' ? params.sortOrder : null, render: renderDuration }, { title: t('common.status'), dataIndex: "status", key: "status", width: 90, render: (status: number) => ( {status === 1 ? "成功" : "失败"} ) }, { title: t('logs.time'), dataIndex: "createdAt", key: "createdAt", width: 180, sorter: true, sortOrder: params.sortField === 'createdAt' ? params.sortOrder : null, className: "tabular-nums", render: (text: string) => text?.replace('T', ' ').substring(0, 19) }, { title: t('common.action'), key: "action", width: 60, fixed: "right" as const, render: (_: any, record: SysLog) => (