Bläddra i källkod

✨ feat(logs): 增强日志管理页面功能

- 重命名"日志类别"为"资源类型",优化术语一致性
- 添加新的日志筛选条件:HTTP方法、API端点、用户名、IP地址、状态
- 扩展表格列显示:资源类型、HTTP方法、API端点、状态、耗时、用户名、IP地址、创建时间
- 为状态列添加色彩标识:成功(绿色)、失败(红色)、权限拒绝(黄色)
- 调整表格列宽,优化视觉布局
- 支持通过状态下拉框筛选不同操作结果的日志记录
yourname 4 månader sedan
förälder
incheckning
c71d70a585
1 ändrade filer med 104 tillägg och 25 borttagningar
  1. 104 25
      src/client/admin/pages/Logs.tsx

+ 104 - 25
src/client/admin/pages/Logs.tsx

@@ -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>