Skip to content

Commit e3f7962

Browse files
committed
Enhance audit logs with normalized path handling and action filters
- Introduced a function to normalize API paths by replacing numeric IDs with a placeholder. - Updated actionMap to include new actions for app updates, file uploads, and bindings. - Implemented action filters for better user interaction in the audit logs table. - Refined the getActionLabel function to utilize normalized paths for action retrieval.
1 parent 6b1d376 commit e3f7962

File tree

1 file changed

+38
-65
lines changed

1 file changed

+38
-65
lines changed

src/pages/audit-logs.tsx

Lines changed: 38 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,12 @@ export const getUA = (userAgent: string) => {
3737

3838
const { Text } = Typography;
3939

40-
// API 操作语义映射字典(精确匹配,只包含写操作)
40+
// 将 path 中的数字替换为 {id}
41+
const normalizePath = (path: string): string => {
42+
return path.replace(/\/\d+/g, '/{id}');
43+
};
44+
45+
// API 操作语义映射字典(只包含写操作)
4146
const actionMap: Record<string, string> = {
4247
// 用户相关
4348
'POST /user/login': '登录',
@@ -48,77 +53,47 @@ const actionMap: Record<string, string> = {
4853
'POST /user/resetpwd/reset': '重置密码',
4954
// 应用相关
5055
'POST /app/create': '创建应用',
56+
'PUT /app/{id}': '更新应用',
57+
'DELETE /app/{id}': '删除应用',
5158
// 订单相关
5259
'POST /orders': '创建订单',
60+
// 文件相关
5361
'POST /upload': '上传文件',
62+
// 原生包相关
63+
'PUT /app/{id}/package/{id}': '修改原生包设置',
64+
'DELETE /app/{id}/package/{id}': '删除原生包',
65+
// 热更包相关
66+
'POST /app/{id}/version/{id}': '创建热更包',
67+
'PUT /app/{id}/version/{id}': '修改热更包设置',
68+
'DELETE /app/{id}/version/{id}': '删除热更包',
69+
// 绑定相关
70+
'POST /app/{id}/binding/': '创建/更新绑定',
71+
'DELETE /app/{id}/binding/{id}': '删除绑定',
5472
};
5573

56-
// 路径模式匹配(用于动态路径,只包含写操作)
57-
const pathPatterns: Array<{
58-
pattern: RegExp;
59-
getAction: (method: string) => string;
60-
}> = [
61-
{
62-
pattern: /^\/app\/\d+\/package\/\d+$/,
63-
getAction: (method) => {
64-
if (method === 'PUT') return '修改原生包设置';
65-
if (method === 'DELETE') return '删除原生包';
66-
return '';
67-
},
68-
},
69-
{
70-
pattern: /^\/app\/\d+\/version\/\d+$/,
71-
getAction: (method) => {
72-
if (method === 'PUT') return '修改热更包设置';
73-
if (method === 'DELETE') return '删除热更包';
74-
if (method === 'POST') return '创建热更包';
75-
return '';
76-
},
77-
},
78-
{
79-
pattern: /^\/app\/\d+\/binding\/$/,
80-
getAction: () => '创建/更新绑定',
81-
},
82-
{
83-
pattern: /^\/app\/\d+\/binding\/\d+$/,
84-
getAction: () => '删除绑定',
85-
},
86-
{
87-
pattern: /^\/app\/\d+$/,
88-
getAction: (method) => {
89-
if (method === 'PUT') return '更新应用';
90-
if (method === 'DELETE') return '删除应用';
91-
return '';
92-
},
93-
},
94-
];
95-
9674
// 获取操作语义描述
9775
const getActionLabel = (method: string, path: string): string => {
98-
const key = `${method.toUpperCase()} ${path}`;
76+
const normalizedPath = normalizePath(path);
77+
const key = `${method.toUpperCase()} ${normalizedPath}`;
9978

100-
// 先尝试精确匹配
101-
if (actionMap[key]) {
102-
return actionMap[key];
103-
}
104-
105-
// 尝试模式匹配
106-
for (const { pattern, getAction } of pathPatterns) {
107-
if (pattern.test(path)) {
108-
return getAction(method.toUpperCase());
109-
}
110-
}
111-
112-
// 如果没有匹配到,返回原始 method + path
113-
return `${method.toUpperCase()} ${path}`;
79+
return actionMap[key] || `${method.toUpperCase()} ${path}`;
11480
};
11581

82+
// 生成操作类型的 filter
83+
const actionFilters = Object.values(actionMap)
84+
.sort()
85+
.map((value) => ({
86+
text: value,
87+
value,
88+
}));
89+
11690
const columns: ColumnType<AuditLog>[] = [
11791
{
11892
title: '时间',
11993
dataIndex: 'createdAt',
12094
width: 180,
121-
sorter: true,
95+
sorter: (a, b) =>
96+
dayjs(a.createdAt).valueOf() - dayjs(b.createdAt).valueOf(),
12297
render: (createdAt: string) => {
12398
const date = dayjs(createdAt);
12499
return (
@@ -134,6 +109,11 @@ const columns: ColumnType<AuditLog>[] = [
134109
{
135110
title: '操作',
136111
width: 120,
112+
filters: actionFilters,
113+
onFilter: (value, record) => {
114+
const actionLabel = getActionLabel(record.method, record.path);
115+
return actionLabel === value;
116+
},
137117
render: (_, record) => {
138118
const actionLabel = getActionLabel(record.method, record.path);
139119
const isDelete = record.method.toUpperCase() === 'DELETE';
@@ -266,13 +246,6 @@ export const AuditLogs = () => {
266246
});
267247
}, [allAuditLogs, dateRange]);
268248

269-
// 前端分页
270-
const paginatedAuditLogs = useMemo(() => {
271-
const startIndex = offset;
272-
const endIndex = offset + pageSize;
273-
return filteredAuditLogs.slice(startIndex, endIndex);
274-
}, [filteredAuditLogs, offset, pageSize]);
275-
276249
const handleDateRangeChange = (
277250
dates: [Dayjs | null, Dayjs | null] | null,
278251
) => {
@@ -439,7 +412,7 @@ export const AuditLogs = () => {
439412
<Table
440413
rowKey="id"
441414
columns={columns}
442-
dataSource={paginatedAuditLogs}
415+
dataSource={filteredAuditLogs}
443416
loading={isLoading}
444417
pagination={{
445418
showSizeChanger: true,

0 commit comments

Comments
 (0)