import { Button, Card, DatePicker, Descriptions, Input, Modal, Select, Space, Tabs, Tag, Typography } from "antd"; import { useEffect, useMemo, useState } from "react"; import { useTranslation } from "react-i18next"; import { EyeOutlined, InfoCircleOutlined, ReloadOutlined, SearchOutlined, UserOutlined } from "@ant-design/icons"; import { fetchLogModules, fetchLogs } from "@/api"; import { useDict } from "@/hooks/useDict"; import PageHeader from "@/components/shared/PageHeader"; import ListTable from "@/components/shared/ListTable/ListTable"; import { getStandardPagination } from "@/utils/pagination"; import type { SysLog, UserProfile } from "@/types"; const { RangePicker } = DatePicker; const { Text } = 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 [moduleOptions, setModuleOptions] = useState([]); const [detailModalVisible, setDetailModalVisible] = useState(false); const [selectedLog, setSelectedLog] = useState(null); const [params, setParams] = useState({ current: 1, size: 20, username: "", moduleName: "", status: undefined as number | undefined, startDate: "", endDate: "", operation: "", sortField: "createdAt", sortOrder: "descend" as any }); const { items: logTypeDict } = useDict("sys_log_type"); const { items: logStatusDict } = useDict("sys_log_status"); const userProfile = useMemo(() => { const stored = sessionStorage.getItem("userProfile"); if (!stored) return null; try { return JSON.parse(stored) as UserProfile; } catch { return null; } }, []); const isPlatformAdmin = Boolean(userProfile?.isPlatformAdmin); const loadData = async (currentParams = params) => { setLoading(true); try { 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]); useEffect(() => { if (activeTab !== "OPERATION") { setModuleOptions([]); return; } fetchLogModules().then((items) => setModuleOptions(items || [])).catch(() => setModuleOptions([])); }, [activeTab]); 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 = () => { const nextParams = { ...params, current: 1 }; setParams(nextParams); loadData(nextParams); }; const handleReset = () => { const resetParams = { current: 1, size: 20, username: "", moduleName: "", status: undefined, startDate: "", endDate: "", operation: "", sortField: "createdAt", sortOrder: "descend" as any }; setParams(resetParams); loadData(resetParams); }; 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: any[] = [ ...(isPlatformAdmin ? [{ title: t("users.tenant"), dataIndex: "tenantName", key: "tenantName", width: 150, render: (text: string) => {text || t("logsExt.platform")} }] : []), { title: t("logs.opAccount"), dataIndex: "username", key: "username", width: 120, render: (text: string) => {text || t("logsExt.system")} }, { title: activeTab === "OPERATION" ? t("logsExt.actionLabel") : t("logs.opDetail"), dataIndex: activeTab === "OPERATION" ? "actionName" : "operation", key: activeTab === "OPERATION" ? "actionName" : "operation", ellipsis: true, render: (_: string, record: SysLog) => {record.actionName || record.operation} }, { 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) => { const item = logStatusDict.find((dictItem) => dictItem.itemValue === String(status)); return {item ? item.itemLabel : status === 1 ? t("logsExt.success") : t("logsExt.failed")}; } }, { 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) => { setActiveTab(key); setParams((prev) => ({ ...prev, current: 1, moduleName: "" })); }} size="large" className="flex-shrink-0"> {logTypeDict.length > 0 ? logTypeDict.map((item) => {item.itemValue === "OPERATION" ?
setDetailModalVisible(false)} footer={[]} width={700}> {selectedLog && ( {isPlatformAdmin && {selectedLog.tenantName || t("logsExt.platform")}} {selectedLog.logType === "OPERATION" && {selectedLog.moduleName || t("logsExt.uncategorized")}} {selectedLog.logType === "OPERATION" && {selectedLog.actionName || selectedLog.operation}} {selectedLog.operation} {selectedLog.method || "N/A"} {selectedLog.username || t("logsExt.system")} {selectedLog.ip} {selectedLog.duration ? `${selectedLog.duration}ms` : "-"} {logStatusDict.find((item) => item.itemValue === String(selectedLog.status))?.itemLabel || (selectedLog.status === 1 ? t("logsExt.success") : t("logsExt.failed"))} {selectedLog.createdAt?.replace("T", " ")}
{selectedLog.params || "-"}
)}
); }