feat: wire admin workflows to real APIs
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { useMemo, useState } from 'react';
|
||||
import { CalendarDays, Download, FileText, Search } from 'lucide-react';
|
||||
import { Breadcrumb, Button, Input, Select, Table, Tag, type TableColumn } from '@/components/ui';
|
||||
import { Button, Input, Pagination, Select, Table, Tag, type TableColumn } from '@/components/ui';
|
||||
|
||||
type LogLevel = 'info' | 'success' | 'warning' | 'error';
|
||||
|
||||
@@ -44,6 +44,8 @@ export function AdminSystemLogsPage() {
|
||||
const [level, setLevel] = useState('all');
|
||||
const [module, setModule] = useState('all');
|
||||
const [range, setRange] = useState('today');
|
||||
const [page, setPage] = useState(1);
|
||||
const pageSize = 5;
|
||||
|
||||
const moduleOptions = useMemo(() => {
|
||||
const modules = Array.from(new Set(logsSeed.map((item) => item.module)));
|
||||
@@ -57,6 +59,9 @@ export function AdminSystemLogsPage() {
|
||||
const matchesModule = module === 'all' || item.module === module;
|
||||
return matchesKeyword && matchesLevel && matchesModule;
|
||||
});
|
||||
const totalPages = Math.max(1, Math.ceil(filteredLogs.length / pageSize));
|
||||
const currentPage = Math.min(page, totalPages);
|
||||
const pagedLogs = filteredLogs.slice((currentPage - 1) * pageSize, currentPage * pageSize);
|
||||
|
||||
const columns = useMemo<Array<TableColumn<AdminSystemLog>>>(() => [
|
||||
{ key: 'time', title: '时间', width: '180px', render: (record) => <span className="muted">{record.time}</span> },
|
||||
@@ -66,7 +71,18 @@ export function AdminSystemLogsPage() {
|
||||
{ key: 'operator', title: '操作人', width: '120px', render: (record) => <strong>{record.operator}</strong> },
|
||||
{ key: 'action', title: '动作', width: '140px', render: (record) => record.action },
|
||||
{ key: 'resourceId', title: '资源ID', width: '150px', render: (record) => <span className="muted">{record.resourceId}</span> },
|
||||
{ key: 'detail', title: '详情', render: (record) => <span className="system-log-detail">{record.detail}</span> },
|
||||
{
|
||||
key: 'detail',
|
||||
title: '详情',
|
||||
width: '320px',
|
||||
render: (record) => (
|
||||
<div className="system-log-detail-card">
|
||||
<strong>{record.action}</strong>
|
||||
<span>{record.detail}</span>
|
||||
<small>{record.resourceId}</small>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{ key: 'ip', title: 'IP', width: '120px', render: (record) => <span className="muted">{record.ip}</span> },
|
||||
], []);
|
||||
|
||||
@@ -75,23 +91,20 @@ export function AdminSystemLogsPage() {
|
||||
<div className="system-page-toolbar">
|
||||
<div className="sms-send-title">
|
||||
<span className="sms-send-title__icon"><FileText size={22} /></span>
|
||||
<div>
|
||||
<Breadcrumb items={['系统管理', '系统日志']} />
|
||||
<h1>系统日志</h1>
|
||||
</div>
|
||||
<h1>系统日志</h1>
|
||||
</div>
|
||||
<Button icon={<Download size={17} />} variant="secondary">导出日志</Button>
|
||||
</div>
|
||||
|
||||
<div className="system-log-filters">
|
||||
<Input
|
||||
onChange={(event) => setKeyword(event.target.value)}
|
||||
onChange={(event) => { setKeyword(event.target.value); setPage(1); }}
|
||||
placeholder="搜索企业、操作人、动作、资源ID或详情"
|
||||
prefix={<Search size={16} />}
|
||||
value={keyword}
|
||||
/>
|
||||
<Select
|
||||
onChange={(event) => setLevel(event.target.value)}
|
||||
onChange={(event) => { setLevel(event.target.value); setPage(1); }}
|
||||
options={[
|
||||
{ label: '全部级别', value: 'all' },
|
||||
{ label: '信息', value: 'info' },
|
||||
@@ -101,7 +114,7 @@ export function AdminSystemLogsPage() {
|
||||
]}
|
||||
value={level}
|
||||
/>
|
||||
<Select onChange={(event) => setModule(event.target.value)} options={moduleOptions} value={module} />
|
||||
<Select onChange={(event) => { setModule(event.target.value); setPage(1); }} options={moduleOptions} value={module} />
|
||||
</div>
|
||||
|
||||
<div className="system-log-range">
|
||||
@@ -124,9 +137,16 @@ export function AdminSystemLogsPage() {
|
||||
</div>
|
||||
|
||||
<div className="surface system-table-card">
|
||||
<Table columns={columns} data={filteredLogs} emptyText="暂无系统日志" rowKey="id" />
|
||||
<Table columns={columns} data={pagedLogs} emptyText="暂无系统日志" rowKey="id" />
|
||||
<Pagination
|
||||
nextDisabled={currentPage >= totalPages}
|
||||
onNext={() => setPage((value) => Math.min(totalPages, value + 1))}
|
||||
onPrevious={() => setPage((value) => Math.max(1, value - 1))}
|
||||
page={currentPage}
|
||||
previousDisabled={currentPage <= 1}
|
||||
total={filteredLogs.length}
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user