diff --git a/src/App.tsx b/src/App.tsx index 98e9702..c611988 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -10,6 +10,7 @@ import PageLoading from './components/PageLoading' import AdminLayout from './layouts/AdminLayout' const Login = lazy(() => import('./pages/Login')) +const AuditLogPage = lazy(() => import("./pages/AuditLog")) const Dashboard = lazy(() => import('./pages/Dashboard')) const UserManagement = lazy(() => import('./pages/UserManagement')) const TaskAssistant = lazy(() => import('./pages/TaskAssistant')) @@ -83,7 +84,7 @@ function App() { path="audit" element={ - + }> } /> diff --git a/src/pages/AuditLog.tsx b/src/pages/AuditLog.tsx new file mode 100644 index 0000000..259ca3c --- /dev/null +++ b/src/pages/AuditLog.tsx @@ -0,0 +1,24 @@ +import { useState } from 'react' +import { useQuery } from '@tanstack/react-query' +import AuditLogTable from '@/components/AuditLogTable' +import { getAuditLogs } from '@/services/admin-api' + +export default function AuditLogPage() { + const [page, setPage] = useState(1) + const [pageSize, setPageSize] = useState(20) + + const { data, isLoading } = useQuery({ + queryKey: ['audit-logs', page, pageSize], + queryFn: () => getAuditLogs({ page, limit: pageSize }), + }) + + return ( + { setPage(p); setPageSize(ps) }} + /> + ) +} diff --git a/src/pages/Dashboard.tsx b/src/pages/Dashboard.tsx index b51556f..b3ef42a 100644 --- a/src/pages/Dashboard.tsx +++ b/src/pages/Dashboard.tsx @@ -1,4 +1,4 @@ -import { useMemo, useState } from 'react' +import { useMemo } from 'react' import { Row, Col, Typography } from 'antd' import { useQuery } from '@tanstack/react-query' import ReactEChartsCore from 'echarts-for-react/esm/core' @@ -6,14 +6,11 @@ import * as echarts from 'echarts/core' import { LineChart, BarChart } from 'echarts/charts' import { GridComponent, TooltipComponent, TitleComponent, LegendComponent } from 'echarts/components' import { CanvasRenderer } from 'echarts/renderers' -import { - UserOutlined, BookOutlined, CloudOutlined, FileOutlined, -} from '@ant-design/icons' +import { UserOutlined, BookOutlined, CloudOutlined, FileOutlined } from '@ant-design/icons' import dayjs from 'dayjs' import MetricCard from '@/components/MetricCard' import EChartsChartContainer from '@/components/EChartsChartContainer' -import AuditLogTable from '@/components/AuditLogTable' -import { getDashboardStats, getAuditLogs } from '@/services/admin-api' +import { getDashboardStats } from '@/services/admin-api' echarts.use([LineChart, BarChart, GridComponent, TooltipComponent, TitleComponent, LegendComponent, CanvasRenderer]) @@ -24,105 +21,41 @@ function formatStorage(bytes: number): string { } export default function Dashboard() { - const [auditPage, setAuditPage] = useState(1) - const [auditPageSize, setAuditPageSize] = useState(10) - const { data: stats, isLoading: statsLoading } = useQuery({ queryKey: ['dashboard', 'stats'], queryFn: getDashboardStats, staleTime: 60_000, }) - const { data: auditData, isLoading: auditLoading } = useQuery({ - queryKey: ['dashboard', 'audit-logs', auditPage, auditPageSize], - queryFn: () => getAuditLogs({ page: auditPage, limit: auditPageSize }), - staleTime: 30_000, - }) - const userTrendOption = useMemo(() => ({ grid: { top: 20, right: 20, bottom: 20, left: 40 }, tooltip: { trigger: 'axis' as const }, - xAxis: { - type: 'category' as const, - data: stats?.userTrend.map((p) => dayjs(p.date).format('MM-DD')) || [], - axisLabel: { fontSize: 11 }, - }, + xAxis: { type: 'category' as const, data: stats?.userTrend.map(p => dayjs(p.date).format('MM-DD')) || [], axisLabel: { fontSize: 11 } }, yAxis: { type: 'value' as const, axisLabel: { fontSize: 11 } }, - series: [{ - name: '日活用户', type: 'line', - data: stats?.userTrend.map((p) => p.value) || [], - smooth: true, symbol: 'none', - lineStyle: { color: '#1677ff', width: 2 }, - areaStyle: { color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ - { offset: 0, color: 'rgba(22,119,255,0.15)' }, - { offset: 1, color: 'rgba(22,119,255,0)' }, - ])}, - }], + series: [{ name: '日活用户', type: 'line', data: stats?.userTrend.map(p => p.value) || [], smooth: true, symbol: 'none', lineStyle: { color: '#1677ff', width: 2 }, areaStyle: { color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ offset: 0, color: 'rgba(22,119,255,0.15)' }, { offset: 1, color: 'rgba(22,119,255,0)' }]) } }], }), [stats]) const aiCallTrendOption = useMemo(() => ({ grid: { top: 20, right: 20, bottom: 20, left: 40 }, tooltip: { trigger: 'axis' as const }, - xAxis: { - type: 'category' as const, - data: stats?.aiCallTrend.map((p) => dayjs(p.date).format('MM-DD')) || [], - axisLabel: { fontSize: 11 }, - }, + xAxis: { type: 'category' as const, data: stats?.aiCallTrend.map(p => dayjs(p.date).format('MM-DD')) || [], axisLabel: { fontSize: 11 } }, yAxis: { type: 'value' as const, axisLabel: { fontSize: 11 } }, - series: [{ - name: 'AI 调用', type: 'bar', - data: stats?.aiCallTrend.map((p) => p.value) || [], - itemStyle: { - color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ - { offset: 0, color: '#52c41a' }, { offset: 1, color: '#b7eb8f' }, - ]), - borderRadius: [4, 4, 0, 0], - }, - }], + series: [{ name: 'AI 调用', type: 'bar', data: stats?.aiCallTrend.map(p => p.value) || [], itemStyle: { color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ offset: 0, color: '#52c41a' }, { offset: 1, color: '#b7eb8f' }]), borderRadius: [4, 4, 0, 0] } }], }), [stats]) return (
数据概览 - - } trend="up" trendValue={`+${stats?.newUsersToday ?? 0}`} trendLabel="今日新增" /> - - - } trend="up" trendValue={`+${stats?.newKbsToday ?? 0}`} trendLabel="今日新增" /> - - - } /> - - - } suffix={`${stats?.totalFiles ?? 0} 个文件`} /> - + } trend="up" trendValue={`+${stats?.newUsersToday ?? 0}`} trendLabel="今日新增" /> + } trend="up" trendValue={`+${stats?.newKbsToday ?? 0}`} trendLabel="今日新增" /> + } /> + } suffix={`${stats?.totalFiles ?? 0} 个文件`} /> - - - - - - - - - - + + -
- { setAuditPage(page); setAuditPageSize(pageSize) }} - /> -
) }