|
|
@@ -16,13 +16,13 @@ const Logs: React.FC = () => {
|
|
|
const [form] = Form.useForm();
|
|
|
|
|
|
// 获取日志列表数据
|
|
|
- const fetchLogs = async ({
|
|
|
- page = 1,
|
|
|
- pageSize = 10,
|
|
|
- searchText = '',
|
|
|
- filters = {}
|
|
|
- }: {
|
|
|
- page?: number;
|
|
|
+ const fetchLogs = async ({
|
|
|
+ page = 1,
|
|
|
+ pageSize = 10,
|
|
|
+ searchText = '',
|
|
|
+ filters = {}
|
|
|
+ }: {
|
|
|
+ page?: number;
|
|
|
pageSize?: number;
|
|
|
searchText?: string;
|
|
|
filters?: Record<string, any>;
|
|
|
@@ -30,9 +30,14 @@ const Logs: React.FC = () => {
|
|
|
const queryParams: Record<string, any> = { page, pageSize };
|
|
|
|
|
|
if (searchText) queryParams.keyword = searchText;
|
|
|
- if (filters.class) queryParams.class = filters.class;
|
|
|
+ if (filters.resourceType) queryParams.resourceType = filters.resourceType;
|
|
|
if (filters.action) queryParams.action = filters.action;
|
|
|
+ if (filters.method) queryParams.method = filters.method;
|
|
|
+ if (filters.endpoint) queryParams.endpoint = filters.endpoint;
|
|
|
if (filters.userId) queryParams.userId = filters.userId;
|
|
|
+ if (filters.username) queryParams.username = filters.username;
|
|
|
+ if (filters.ipAddress) queryParams.ipAddress = filters.ipAddress;
|
|
|
+ if (filters.status) queryParams.status = filters.status;
|
|
|
if (filters.dateRange?.[0]) queryParams.startDate = filters.dateRange[0].format('YYYY-MM-DD');
|
|
|
if (filters.dateRange?.[1]) queryParams.endDate = filters.dateRange[1].format('YYYY-MM-DD');
|
|
|
|
|
|
@@ -47,37 +52,86 @@ const Logs: React.FC = () => {
|
|
|
title: '日志ID',
|
|
|
dataIndex: 'id',
|
|
|
key: 'id',
|
|
|
+ width: 80,
|
|
|
},
|
|
|
{
|
|
|
- title: '关联记录ID',
|
|
|
- dataIndex: 'relatedId',
|
|
|
- key: 'relatedId',
|
|
|
+ title: '资源类型',
|
|
|
+ dataIndex: 'resourceType',
|
|
|
+ key: 'resourceType',
|
|
|
+ width: 120,
|
|
|
},
|
|
|
{
|
|
|
- title: '类别',
|
|
|
- dataIndex: 'class',
|
|
|
- key: 'class',
|
|
|
+ title: '资源ID',
|
|
|
+ dataIndex: 'resourceId',
|
|
|
+ key: 'resourceId',
|
|
|
+ width: 120,
|
|
|
},
|
|
|
{
|
|
|
title: '操作',
|
|
|
dataIndex: 'action',
|
|
|
key: 'action',
|
|
|
+ width: 100,
|
|
|
},
|
|
|
{
|
|
|
- title: '操作用户',
|
|
|
+ title: 'HTTP方法',
|
|
|
+ dataIndex: 'method',
|
|
|
+ key: 'method',
|
|
|
+ width: 100,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: 'API端点',
|
|
|
+ dataIndex: 'endpoint',
|
|
|
+ key: 'endpoint',
|
|
|
+ width: 200,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '状态',
|
|
|
+ dataIndex: 'status',
|
|
|
+ key: 'status',
|
|
|
+ width: 100,
|
|
|
+ render: (status: string) => {
|
|
|
+ switch (status) {
|
|
|
+ case 'success':
|
|
|
+ return <span style={{ color: '#52c41a' }}>成功</span>;
|
|
|
+ case 'failed':
|
|
|
+ return <span style={{ color: '#ff4d4f' }}>失败</span>;
|
|
|
+ case 'permission_denied':
|
|
|
+ return <span style={{ color: '#faad14' }}>权限拒绝</span>;
|
|
|
+ default:
|
|
|
+ return status;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '耗时(ms)',
|
|
|
+ dataIndex: 'duration',
|
|
|
+ key: 'duration',
|
|
|
+ width: 100,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '操作用户ID',
|
|
|
dataIndex: 'userId',
|
|
|
key: 'userId',
|
|
|
+ width: 100,
|
|
|
},
|
|
|
{
|
|
|
- title: '操作时间',
|
|
|
- dataIndex: 'logTime',
|
|
|
- key: 'logTime',
|
|
|
- render: (time: string) => time ? dayjs(time).format('YYYY-MM-DD HH:mm:ss') : '-',
|
|
|
+ title: '用户名',
|
|
|
+ dataIndex: 'username',
|
|
|
+ key: 'username',
|
|
|
+ width: 120,
|
|
|
},
|
|
|
{
|
|
|
- title: '操作原因',
|
|
|
- dataIndex: 'reason',
|
|
|
- key: 'reason',
|
|
|
+ title: 'IP地址',
|
|
|
+ dataIndex: 'ipAddress',
|
|
|
+ key: 'ipAddress',
|
|
|
+ width: 150,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '创建时间',
|
|
|
+ dataIndex: 'createdAt',
|
|
|
+ key: 'createdAt',
|
|
|
+ width: 180,
|
|
|
+ render: (time: string) => time ? dayjs(time).format('YYYY-MM-DD HH:mm:ss') : '-',
|
|
|
},
|
|
|
];
|
|
|
|
|
|
@@ -93,9 +147,14 @@ const Logs: React.FC = () => {
|
|
|
pageSize: values.pagination?.pageSize || 10,
|
|
|
searchText,
|
|
|
filters: {
|
|
|
- class: values.class,
|
|
|
+ resourceType: values.resourceType,
|
|
|
action: values.action,
|
|
|
+ method: values.method,
|
|
|
+ endpoint: values.endpoint,
|
|
|
userId: values.userId,
|
|
|
+ username: values.username,
|
|
|
+ ipAddress: values.ipAddress,
|
|
|
+ status: values.status,
|
|
|
dateRange: values.dateRange
|
|
|
}
|
|
|
});
|
|
|
@@ -144,15 +203,35 @@ const Logs: React.FC = () => {
|
|
|
}
|
|
|
}}
|
|
|
>
|
|
|
- <Form.Item name="class" label="日志类别">
|
|
|
- <Input placeholder="请输入日志类别" style={{ width: 150 }} />
|
|
|
+ <Form.Item name="resourceType" label="资源类型">
|
|
|
+ <Input placeholder="请输入资源类型" style={{ width: 150 }} />
|
|
|
</Form.Item>
|
|
|
<Form.Item name="action" label="操作动作">
|
|
|
<Input placeholder="请输入操作动作" style={{ width: 150 }} />
|
|
|
</Form.Item>
|
|
|
+ <Form.Item name="method" label="HTTP方法">
|
|
|
+ <Input placeholder="请输入HTTP方法" style={{ width: 150 }} />
|
|
|
+ </Form.Item>
|
|
|
+ <Form.Item name="endpoint" label="API端点">
|
|
|
+ <Input placeholder="请输入API端点" style={{ width: 150 }} />
|
|
|
+ </Form.Item>
|
|
|
<Form.Item name="userId" label="操作用户ID">
|
|
|
<Input placeholder="请输入用户ID" style={{ width: 150 }} />
|
|
|
</Form.Item>
|
|
|
+ <Form.Item name="username" label="用户名">
|
|
|
+ <Input placeholder="请输入用户名" style={{ width: 150 }} />
|
|
|
+ </Form.Item>
|
|
|
+ <Form.Item name="ipAddress" label="IP地址">
|
|
|
+ <Input placeholder="请输入IP地址" style={{ width: 150 }} />
|
|
|
+ </Form.Item>
|
|
|
+ <Form.Item name="status" label="状态">
|
|
|
+ <select style={{ width: 150, height: 32, borderRadius: 6, border: '1px solid #d9d9d9' }}>
|
|
|
+ <option value="">全部</option>
|
|
|
+ <option value="success">成功</option>
|
|
|
+ <option value="failed">失败</option>
|
|
|
+ <option value="permission_denied">权限拒绝</option>
|
|
|
+ </select>
|
|
|
+ </Form.Item>
|
|
|
<Form.Item name="dateRange" label="操作时间">
|
|
|
<RangePicker format="YYYY-MM-DD" />
|
|
|
</Form.Item>
|