统一各个页面的分页查询
This commit is contained in:
1 parent
d6d8d2e9ef
commit
cb948eaee3
10 files changed
+224
-274
No files matched your search
@@ -82,8 +82,13 @@ const AgentDetail = () => {
|
||||
|
||||
useEffect(() => {
|
||||
// 同步 activeTab 到 URL
|
||||
setSearchParams({tab: activeTab});
|
||||
}, [activeTab]);
|
||||
const nextParams = new URLSearchParams(searchParams);
|
||||
if (nextParams.get('tab') === activeTab) {
|
||||
return;
|
||||
}
|
||||
nextParams.set('tab', activeTab);
|
||||
setSearchParams(nextParams);
|
||||
}, [activeTab, searchParams, setSearchParams]);
|
||||
|
||||
if (loading && !agent) {
|
||||
return (
|
||||
|
||||
@@ -44,7 +44,7 @@ const AgentList = () => {
|
||||
status: status || undefined,
|
||||
};
|
||||
|
||||
const {data: tags = [], isError: tagsError, error: tagsErrorDetail} = useQuery({
|
||||
const {data: tags = []} = useQuery({
|
||||
queryKey: ['admin', 'agents', 'tags'],
|
||||
queryFn: async () => {
|
||||
const response = await getTags();
|
||||
@@ -56,8 +56,6 @@ const AgentList = () => {
|
||||
data: agentPaging,
|
||||
isLoading,
|
||||
isFetching,
|
||||
isError: agentsError,
|
||||
error: agentsErrorDetail,
|
||||
refetch,
|
||||
} = useQuery({
|
||||
queryKey: ['admin', 'agents', pageIndex, pageSize, filters.keyword, filters.status],
|
||||
@@ -83,18 +81,6 @@ const AgentList = () => {
|
||||
},
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (tagsError && tagsErrorDetail) {
|
||||
messageApi.error(getErrorMessage(tagsErrorDetail, '加载标签失败'));
|
||||
}
|
||||
}, [tagsError, tagsErrorDetail, messageApi]);
|
||||
|
||||
useEffect(() => {
|
||||
if (agentsError && agentsErrorDetail) {
|
||||
messageApi.error(getErrorMessage(agentsErrorDetail, '获取探针列表失败'));
|
||||
}
|
||||
}, [agentsError, agentsErrorDetail, messageApi]);
|
||||
|
||||
useEffect(() => {
|
||||
searchForm.setFieldsValue({
|
||||
keyword: keyword || undefined,
|
||||
@@ -137,7 +123,7 @@ const AgentList = () => {
|
||||
|
||||
const handleTableChange = (nextPagination: TablePaginationConfig) => {
|
||||
const nextParams = new URLSearchParams(searchParams);
|
||||
nextParams.set('page', String(nextPagination.current || 1));
|
||||
nextParams.set('pageIndex', String(nextPagination.current || 1));
|
||||
nextParams.set('pageSize', String(nextPagination.pageSize || pageSize));
|
||||
setSearchParams(nextParams);
|
||||
};
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import React, {useState, useEffect} from 'react';
|
||||
import React from 'react';
|
||||
import {useSearchParams} from 'react-router-dom';
|
||||
import {App, Button, Table, Tag, Tooltip} from 'antd';
|
||||
import type {ColumnsType} from 'antd/es/table';
|
||||
import type {ColumnsType, TablePaginationConfig} from 'antd/es/table';
|
||||
import {Terminal} from 'lucide-react';
|
||||
import {useMutation} from '@tanstack/react-query';
|
||||
import {useMutation, useQuery, useQueryClient} from '@tanstack/react-query';
|
||||
import type {SSHLoginEvent} from '@/types';
|
||||
import {deleteSSHLoginEvents, getSSHLoginEvents} from '@/api/agent';
|
||||
import {getErrorMessage} from '@/lib/utils';
|
||||
@@ -14,18 +15,11 @@ interface SSHLoginEventsProps {
|
||||
|
||||
const SSHLoginEvents: React.FC<SSHLoginEventsProps> = ({agentId}) => {
|
||||
const {message, modal} = App.useApp();
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [dataSource, setDataSource] = useState<SSHLoginEvent[]>([]);
|
||||
const [pagination, setPagination] = useState({
|
||||
current: 1,
|
||||
pageSize: 20,
|
||||
total: 0,
|
||||
});
|
||||
const [searchParams, setSearchParams] = useState({
|
||||
username: '',
|
||||
ip: '',
|
||||
status: '',
|
||||
});
|
||||
const queryClient = useQueryClient();
|
||||
const [searchParams, setSearchParams] = useSearchParams();
|
||||
|
||||
const pageIndex = Number(searchParams.get('pageIndex')) || 1;
|
||||
const pageSize = Number(searchParams.get('pageSize')) || 20;
|
||||
|
||||
// 定义表格列
|
||||
const columns: ColumnsType<SSHLoginEvent> = [
|
||||
@@ -99,42 +93,33 @@ const SSHLoginEvents: React.FC<SSHLoginEventsProps> = ({agentId}) => {
|
||||
},
|
||||
];
|
||||
|
||||
// 加载数据
|
||||
const loadData = async (page: number = pagination.current, pageSize: number = pagination.pageSize) => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const response = await getSSHLoginEvents(agentId, {
|
||||
pageIndex: page,
|
||||
pageSize: pageSize,
|
||||
username: searchParams.username || undefined,
|
||||
ip: searchParams.ip || undefined,
|
||||
status: searchParams.status || undefined,
|
||||
sortField: 'createdAt',
|
||||
sortOrder: 'descend',
|
||||
});
|
||||
setDataSource(response.items || []);
|
||||
setPagination({
|
||||
current: page,
|
||||
pageSize: pageSize,
|
||||
total: response.total || 0,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Failed to load SSH login events:', error);
|
||||
message.error(getErrorMessage(error, '加载失败'));
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
// 初始加载
|
||||
useEffect(() => {
|
||||
loadData();
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [agentId]);
|
||||
const {
|
||||
data: eventsPaging,
|
||||
isLoading,
|
||||
isFetching,
|
||||
} = useQuery({
|
||||
queryKey: [
|
||||
'admin',
|
||||
'agents',
|
||||
'ssh-login-events',
|
||||
agentId,
|
||||
pageIndex,
|
||||
pageSize,
|
||||
],
|
||||
queryFn: () => getSSHLoginEvents(agentId, {
|
||||
pageIndex,
|
||||
pageSize,
|
||||
sortField: 'createdAt',
|
||||
sortOrder: 'descend',
|
||||
}),
|
||||
});
|
||||
|
||||
// 处理表格变化
|
||||
const handleTableChange = (newPagination: any) => {
|
||||
loadData(newPagination.current, newPagination.pageSize);
|
||||
const handleTableChange = (newPagination: TablePaginationConfig) => {
|
||||
const nextParams = new URLSearchParams(searchParams);
|
||||
nextParams.set('pageIndex', String(newPagination.current || 1));
|
||||
nextParams.set('pageSize', String(newPagination.pageSize || pageSize));
|
||||
setSearchParams(nextParams);
|
||||
};
|
||||
|
||||
// 删除所有事件 mutation
|
||||
@@ -142,7 +127,11 @@ const SSHLoginEvents: React.FC<SSHLoginEventsProps> = ({agentId}) => {
|
||||
mutationFn: () => deleteSSHLoginEvents(agentId),
|
||||
onSuccess: () => {
|
||||
message.success('所有事件已删除');
|
||||
loadData(1);
|
||||
const nextParams = new URLSearchParams(searchParams);
|
||||
nextParams.set('pageIndex', '1');
|
||||
nextParams.set('pageSize', String(pageSize));
|
||||
setSearchParams(nextParams);
|
||||
queryClient.invalidateQueries({queryKey: ['admin', 'agents', 'ssh-login-events', agentId]});
|
||||
},
|
||||
onError: (error: unknown) => {
|
||||
console.error('Failed to delete SSH login events:', error);
|
||||
@@ -175,11 +164,13 @@ const SSHLoginEvents: React.FC<SSHLoginEventsProps> = ({agentId}) => {
|
||||
|
||||
<Table<SSHLoginEvent>
|
||||
columns={columns}
|
||||
dataSource={dataSource}
|
||||
loading={loading}
|
||||
dataSource={eventsPaging?.items || []}
|
||||
loading={isLoading || isFetching}
|
||||
rowKey="id"
|
||||
pagination={{
|
||||
...pagination,
|
||||
current: pageIndex,
|
||||
pageSize,
|
||||
total: eventsPaging?.total || 0,
|
||||
showSizeChanger: true,
|
||||
showTotal: (total) => `共 ${total} 条`,
|
||||
}}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import React, {useState, useEffect} from 'react';
|
||||
import React from 'react';
|
||||
import {useSearchParams} from 'react-router-dom';
|
||||
import {App, Button, Table, Tag, Tooltip} from 'antd';
|
||||
import type {ColumnsType} from 'antd/es/table';
|
||||
import type {ColumnsType, TablePaginationConfig} from 'antd/es/table';
|
||||
import {FileWarning} from 'lucide-react';
|
||||
import {useMutation} from '@tanstack/react-query';
|
||||
import {useMutation, useQuery, useQueryClient} from '@tanstack/react-query';
|
||||
import {deleteTamperEvents, getTamperEvents, type TamperEvent} from '@/api/tamper';
|
||||
import {getErrorMessage} from '@/lib/utils';
|
||||
import dayjs from 'dayjs';
|
||||
@@ -13,13 +14,11 @@ interface TamperProtectionEventsProps {
|
||||
|
||||
const TamperProtectionEvents: React.FC<TamperProtectionEventsProps> = ({agentId}) => {
|
||||
const {message, modal} = App.useApp();
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [dataSource, setDataSource] = useState<TamperEvent[]>([]);
|
||||
const [pagination, setPagination] = useState({
|
||||
current: 1,
|
||||
pageSize: 20,
|
||||
total: 0,
|
||||
});
|
||||
const queryClient = useQueryClient();
|
||||
const [searchParams, setSearchParams] = useSearchParams();
|
||||
|
||||
const pageIndex = Number(searchParams.get('pageIndex')) || 1;
|
||||
const pageSize = Number(searchParams.get('pageSize')) || 20;
|
||||
|
||||
// 定义表格列
|
||||
const columns: ColumnsType<TamperEvent> = [
|
||||
@@ -80,39 +79,26 @@ const TamperProtectionEvents: React.FC<TamperProtectionEventsProps> = ({agentId}
|
||||
},
|
||||
];
|
||||
|
||||
// 加载数据
|
||||
const loadData = async (page: number = pagination.current, pageSize: number = pagination.pageSize) => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const response = await getTamperEvents(agentId, {
|
||||
pageIndex: page,
|
||||
pageSize: pageSize,
|
||||
sortField: 'createdAt',
|
||||
sortOrder: 'descend',
|
||||
});
|
||||
setDataSource(response.data.items || []);
|
||||
setPagination({
|
||||
current: page,
|
||||
pageSize: pageSize,
|
||||
total: response.data.total || 0,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Failed to load tamper events:', error);
|
||||
message.error(getErrorMessage(error, '加载失败'));
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
// 初始加载
|
||||
useEffect(() => {
|
||||
loadData();
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [agentId]);
|
||||
const {
|
||||
data: eventsPaging,
|
||||
isLoading,
|
||||
isFetching,
|
||||
} = useQuery({
|
||||
queryKey: ['admin', 'agents', 'tamper-events', agentId, pageIndex, pageSize],
|
||||
queryFn: () => getTamperEvents(agentId, {
|
||||
pageIndex,
|
||||
pageSize,
|
||||
sortField: 'createdAt',
|
||||
sortOrder: 'descend',
|
||||
}),
|
||||
});
|
||||
|
||||
// 处理表格变化
|
||||
const handleTableChange = (newPagination: any) => {
|
||||
loadData(newPagination.current, newPagination.pageSize);
|
||||
const handleTableChange = (newPagination: TablePaginationConfig) => {
|
||||
const nextParams = new URLSearchParams(searchParams);
|
||||
nextParams.set('pageIndex', String(newPagination.current || 1));
|
||||
nextParams.set('pageSize', String(newPagination.pageSize || pageSize));
|
||||
setSearchParams(nextParams);
|
||||
};
|
||||
|
||||
// 删除所有事件 mutation
|
||||
@@ -120,7 +106,11 @@ const TamperProtectionEvents: React.FC<TamperProtectionEventsProps> = ({agentId}
|
||||
mutationFn: () => deleteTamperEvents(agentId),
|
||||
onSuccess: () => {
|
||||
message.success('所有事件已删除');
|
||||
loadData(1);
|
||||
const nextParams = new URLSearchParams(searchParams);
|
||||
nextParams.set('pageIndex', '1');
|
||||
nextParams.set('pageSize', String(pageSize));
|
||||
setSearchParams(nextParams);
|
||||
queryClient.invalidateQueries({queryKey: ['admin', 'agents', 'tamper-events', agentId]});
|
||||
},
|
||||
onError: (error: unknown) => {
|
||||
console.error('Failed to delete tamper events:', error);
|
||||
@@ -153,11 +143,13 @@ const TamperProtectionEvents: React.FC<TamperProtectionEventsProps> = ({agentId}
|
||||
|
||||
<Table<TamperEvent>
|
||||
columns={columns}
|
||||
dataSource={dataSource}
|
||||
loading={loading}
|
||||
dataSource={eventsPaging?.data.items || []}
|
||||
loading={isLoading || isFetching}
|
||||
rowKey="id"
|
||||
pagination={{
|
||||
...pagination,
|
||||
current: pageIndex,
|
||||
pageSize,
|
||||
total: eventsPaging?.data.total || 0,
|
||||
showSizeChanger: true,
|
||||
showTotal: (total) => `共 ${total} 条`,
|
||||
}}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, {useState, useEffect} from 'react';
|
||||
import React, {useState} from 'react';
|
||||
import {useSearchParams} from 'react-router-dom';
|
||||
import {App, Divider, Select, Space, Table, Tag} from 'antd';
|
||||
import type {ColumnsType} from 'antd/es/table';
|
||||
import type {ColumnsType, TablePaginationConfig} from 'antd/es/table';
|
||||
import {Trash2} from 'lucide-react';
|
||||
import {clearAlertRecords, getAlertRecords} from '@/api/alert.ts';
|
||||
import type {AlertRecord} from '@/types';
|
||||
@@ -8,18 +9,16 @@ import dayjs from 'dayjs';
|
||||
import {getErrorMessage} from '@/lib/utils';
|
||||
import {PageHeader} from '@admin/components';
|
||||
import {getAgentPaging} from '@/api/agent.ts';
|
||||
import {useQuery} from '@tanstack/react-query';
|
||||
import {useQuery, useQueryClient} from '@tanstack/react-query';
|
||||
|
||||
const AlertRecordList = () => {
|
||||
const {message: messageApi, modal} = App.useApp();
|
||||
const queryClient = useQueryClient();
|
||||
const [searchParams, setSearchParams] = useSearchParams();
|
||||
const [selectedAgentId, setSelectedAgentId] = useState<string>('');
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [dataSource, setDataSource] = useState<AlertRecord[]>([]);
|
||||
const [pagination, setPagination] = useState({
|
||||
current: 1,
|
||||
pageSize: 20,
|
||||
total: 0,
|
||||
});
|
||||
|
||||
const pageIndex = Number(searchParams.get('pageIndex')) || 1;
|
||||
const pageSize = Number(searchParams.get('pageSize')) || 20;
|
||||
|
||||
// 使用 react-query 获取探针列表
|
||||
const {data: agentsData} = useQuery({
|
||||
@@ -96,33 +95,30 @@ const AlertRecordList = () => {
|
||||
value: agent.id,
|
||||
})) || [];
|
||||
|
||||
// 加载数据
|
||||
const loadData = async (page: number = pagination.current, pageSize: number = pagination.pageSize, agentId: string = selectedAgentId) => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const result = await getAlertRecords(page, pageSize, agentId || undefined);
|
||||
setDataSource(result.items || []);
|
||||
setPagination({
|
||||
current: page,
|
||||
pageSize: pageSize,
|
||||
total: result.total || 0,
|
||||
});
|
||||
} catch (error) {
|
||||
messageApi.error(getErrorMessage(error, '获取告警记录失败'));
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
const {
|
||||
data: alertPaging,
|
||||
isLoading,
|
||||
isFetching,
|
||||
} = useQuery({
|
||||
queryKey: ['admin', 'alert-records', pageIndex, pageSize, selectedAgentId],
|
||||
queryFn: () => getAlertRecords(pageIndex, pageSize, selectedAgentId || undefined),
|
||||
});
|
||||
|
||||
// 处理表格变化
|
||||
const handleTableChange = (newPagination: any) => {
|
||||
loadData(newPagination.current, newPagination.pageSize);
|
||||
const handleTableChange = (newPagination: TablePaginationConfig) => {
|
||||
const nextParams = new URLSearchParams(searchParams);
|
||||
nextParams.set('pageIndex', String(newPagination.current || 1));
|
||||
nextParams.set('pageSize', String(newPagination.pageSize || pageSize));
|
||||
setSearchParams(nextParams);
|
||||
};
|
||||
|
||||
// 处理探针筛选变化
|
||||
const handleAgentChange = (value: string) => {
|
||||
setSelectedAgentId(value || '');
|
||||
loadData(1, pagination.pageSize, value || '');
|
||||
const nextParams = new URLSearchParams(searchParams);
|
||||
nextParams.set('pageIndex', '1');
|
||||
nextParams.set('pageSize', String(pageSize));
|
||||
setSearchParams(nextParams);
|
||||
};
|
||||
|
||||
// 清空记录
|
||||
@@ -139,7 +135,7 @@ const AlertRecordList = () => {
|
||||
try {
|
||||
await clearAlertRecords(selectedAgentId || undefined);
|
||||
messageApi.success('清空成功');
|
||||
loadData();
|
||||
queryClient.invalidateQueries({queryKey: ['admin', 'alert-records']});
|
||||
} catch (error: unknown) {
|
||||
messageApi.error(getErrorMessage(error, '清空失败'));
|
||||
}
|
||||
@@ -147,12 +143,6 @@ const AlertRecordList = () => {
|
||||
});
|
||||
};
|
||||
|
||||
// 初始加载
|
||||
useEffect(() => {
|
||||
loadData();
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
const columns: ColumnsType<AlertRecord> = [
|
||||
{
|
||||
title: 'ID',
|
||||
@@ -267,15 +257,15 @@ const AlertRecordList = () => {
|
||||
<Select
|
||||
placeholder="选择探针"
|
||||
allowClear
|
||||
showSearch
|
||||
showSearch={{
|
||||
filterOption: (inputValue, option) =>
|
||||
(option?.label?.toString() ?? '')
|
||||
.toLowerCase()
|
||||
.includes(inputValue.toLowerCase()),
|
||||
}}
|
||||
style={{width: 200}}
|
||||
value={selectedAgentId || undefined}
|
||||
onChange={handleAgentChange}
|
||||
filterOption={(input, option) =>
|
||||
(option?.label?.toString() ?? '')
|
||||
.toLowerCase()
|
||||
.includes(input.toLowerCase())
|
||||
}
|
||||
options={agentOptions}
|
||||
/>
|
||||
</Space>
|
||||
@@ -283,11 +273,14 @@ const AlertRecordList = () => {
|
||||
|
||||
<Table<AlertRecord>
|
||||
columns={columns}
|
||||
dataSource={dataSource}
|
||||
loading={loading}
|
||||
dataSource={alertPaging?.items || []}
|
||||
loading={isLoading || isFetching}
|
||||
rowKey="id"
|
||||
size={'small'}
|
||||
pagination={{
|
||||
...pagination,
|
||||
current: pageIndex,
|
||||
pageSize,
|
||||
total: alertPaging?.total || 0,
|
||||
showSizeChanger: true,
|
||||
showQuickJumper: true,
|
||||
pageSizeOptions: ['10', '20', '50', '100'],
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import {useState, useEffect} from 'react';
|
||||
import {useEffect, useState} from 'react';
|
||||
import {useSearchParams} from 'react-router-dom';
|
||||
import {App, Button, Divider, Input, Popconfirm, Space, Table, Tag} from 'antd';
|
||||
import type {ColumnsType} from 'antd/es/table';
|
||||
import type {ColumnsType, TablePaginationConfig} from 'antd/es/table';
|
||||
import {Copy, Edit, Eye, EyeOff, Plus, Power, PowerOff, RefreshCw, Trash2} from 'lucide-react';
|
||||
import {deleteApiKey, disableApiKey, enableApiKey, listApiKeys} from '@/api/apiKey.ts';
|
||||
import type {ApiKey} from '@/types';
|
||||
@@ -11,13 +11,12 @@ import {PageHeader} from '@admin/components';
|
||||
import copy from 'copy-to-clipboard';
|
||||
import ApiKeyModal from './ApiKeyModal';
|
||||
import ShowApiKeyModal from './ShowApiKeyModal';
|
||||
import {useMutation, useQuery, useQueryClient} from '@tanstack/react-query';
|
||||
|
||||
const ApiKeyList = () => {
|
||||
const {message: messageApi} = App.useApp();
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [dataSource, setDataSource] = useState<ApiKey[]>([]);
|
||||
const queryClient = useQueryClient();
|
||||
const [searchParams, setSearchParams] = useSearchParams();
|
||||
const [total, setTotal] = useState(0);
|
||||
const [searchValue, setSearchValue] = useState('');
|
||||
const [isModalVisible, setIsModalVisible] = useState(false);
|
||||
const [editingApiKeyId, setEditingApiKeyId] = useState<string | undefined>(undefined);
|
||||
@@ -25,37 +24,59 @@ const ApiKeyList = () => {
|
||||
const [showApiKeyModal, setShowApiKeyModal] = useState(false);
|
||||
const [visibleKeys, setVisibleKeys] = useState<Record<string, boolean>>({});
|
||||
|
||||
// 加载数据
|
||||
const current = Number(searchParams.get('page')) || 1;
|
||||
const pageIndex = Number(searchParams.get('pageIndex')) || 1;
|
||||
const pageSize = Number(searchParams.get('pageSize')) || 10;
|
||||
const name = searchParams.get('name') ?? '';
|
||||
|
||||
const loadData = async (page: number, size: number, keyword: string) => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const response = await listApiKeys(page, size, keyword || undefined);
|
||||
setDataSource(response.data.items || []);
|
||||
setTotal(response.data.total || 0);
|
||||
} catch (error: unknown) {
|
||||
messageApi.error(getErrorMessage(error, '获取API密钥列表失败'));
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
const {
|
||||
data: apiKeyPaging,
|
||||
isLoading,
|
||||
isFetching,
|
||||
refetch,
|
||||
} = useQuery({
|
||||
queryKey: ['admin', 'api-keys', pageIndex, pageSize, name],
|
||||
queryFn: async () => {
|
||||
const response = await listApiKeys(pageIndex, pageSize, name || undefined);
|
||||
return response.data;
|
||||
},
|
||||
});
|
||||
|
||||
const toggleMutation = useMutation({
|
||||
mutationFn: async (apiKey: ApiKey) => {
|
||||
if (apiKey.enabled) {
|
||||
await disableApiKey(apiKey.id);
|
||||
} else {
|
||||
await enableApiKey(apiKey.id);
|
||||
}
|
||||
},
|
||||
onSuccess: (_, apiKey) => {
|
||||
messageApi.success(apiKey.enabled ? 'API密钥已禁用' : 'API密钥已启用');
|
||||
queryClient.invalidateQueries({queryKey: ['admin', 'api-keys']});
|
||||
},
|
||||
onError: (error: unknown) => {
|
||||
messageApi.error(getErrorMessage(error, '操作失败'));
|
||||
},
|
||||
});
|
||||
|
||||
const deleteMutation = useMutation({
|
||||
mutationFn: (id: string) => deleteApiKey(id),
|
||||
onSuccess: () => {
|
||||
messageApi.success('删除成功');
|
||||
queryClient.invalidateQueries({queryKey: ['admin', 'api-keys']});
|
||||
},
|
||||
onError: (error: unknown) => {
|
||||
messageApi.error(getErrorMessage(error, '删除失败'));
|
||||
},
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
setSearchValue(name);
|
||||
}, [name]);
|
||||
|
||||
useEffect(() => {
|
||||
loadData(current, pageSize, name);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [current, pageSize, name]);
|
||||
|
||||
// 处理表格变化
|
||||
const handleTableChange = (newPagination: any) => {
|
||||
const handleTableChange = (newPagination: TablePaginationConfig) => {
|
||||
const nextParams = new URLSearchParams(searchParams);
|
||||
nextParams.set('page', String(newPagination.current || 1));
|
||||
nextParams.set('pageIndex', String(newPagination.current || 1));
|
||||
nextParams.set('pageSize', String(newPagination.pageSize || pageSize));
|
||||
setSearchParams(nextParams);
|
||||
};
|
||||
@@ -70,7 +91,7 @@ const ApiKeyList = () => {
|
||||
} else {
|
||||
nextParams.delete('name');
|
||||
}
|
||||
nextParams.set('page', '1');
|
||||
nextParams.set('pageIndex', '1');
|
||||
nextParams.set('pageSize', String(pageSize));
|
||||
setSearchParams(nextParams);
|
||||
};
|
||||
@@ -85,29 +106,12 @@ const ApiKeyList = () => {
|
||||
setIsModalVisible(true);
|
||||
};
|
||||
|
||||
const handleToggleEnabled = async (apiKey: ApiKey) => {
|
||||
try {
|
||||
if (apiKey.enabled) {
|
||||
await disableApiKey(apiKey.id);
|
||||
messageApi.success('API密钥已禁用');
|
||||
} else {
|
||||
await enableApiKey(apiKey.id);
|
||||
messageApi.success('API密钥已启用');
|
||||
}
|
||||
loadData(current, pageSize, name);
|
||||
} catch (error: unknown) {
|
||||
messageApi.error(getErrorMessage(error, '操作失败'));
|
||||
}
|
||||
const handleToggleEnabled = (apiKey: ApiKey) => {
|
||||
toggleMutation.mutate(apiKey);
|
||||
};
|
||||
|
||||
const handleDelete = async (id: string) => {
|
||||
try {
|
||||
await deleteApiKey(id);
|
||||
messageApi.success('删除成功');
|
||||
loadData(current, pageSize, name);
|
||||
} catch (error: unknown) {
|
||||
messageApi.error(getErrorMessage(error, '删除失败'));
|
||||
}
|
||||
const handleDelete = (id: string) => {
|
||||
deleteMutation.mutate(id);
|
||||
};
|
||||
|
||||
const handleModalSuccess = (apiKey?: ApiKey) => {
|
||||
@@ -117,7 +121,7 @@ const ApiKeyList = () => {
|
||||
setNewApiKeyData(apiKey);
|
||||
setShowApiKeyModal(true);
|
||||
}
|
||||
loadData(current, pageSize, name);
|
||||
queryClient.invalidateQueries({queryKey: ['admin', 'api-keys']});
|
||||
};
|
||||
|
||||
const handleCopyApiKey = (key: string) => {
|
||||
@@ -207,9 +211,7 @@ const ApiKeyList = () => {
|
||||
key="edit"
|
||||
type="link"
|
||||
size="small"
|
||||
icon={<Edit size={14}/>}
|
||||
onClick={() => handleEdit(record)}
|
||||
style={{padding: 0, margin: 0}}
|
||||
>
|
||||
编辑
|
||||
</Button>,
|
||||
@@ -217,9 +219,7 @@ const ApiKeyList = () => {
|
||||
key="toggle"
|
||||
type="link"
|
||||
size="small"
|
||||
icon={record.enabled ? <PowerOff size={14}/> : <Power size={14}/>}
|
||||
onClick={() => handleToggleEnabled(record)}
|
||||
style={{padding: 0, margin: 0}}
|
||||
>
|
||||
{record.enabled ? '禁用' : '启用'}
|
||||
</Button>,
|
||||
@@ -233,8 +233,7 @@ const ApiKeyList = () => {
|
||||
>
|
||||
<Button type="link"
|
||||
size="small"
|
||||
danger icon={<Trash2 size={14}/>}
|
||||
style={{padding: 0, margin: 0}}
|
||||
danger
|
||||
>
|
||||
删除
|
||||
</Button>
|
||||
@@ -260,7 +259,7 @@ const ApiKeyList = () => {
|
||||
key: 'refresh',
|
||||
label: '刷新',
|
||||
icon: <RefreshCw size={16}/>,
|
||||
onClick: () => loadData(current, pageSize, name),
|
||||
onClick: () => refetch(),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
@@ -286,13 +285,13 @@ const ApiKeyList = () => {
|
||||
|
||||
<Table<ApiKey>
|
||||
columns={columns}
|
||||
dataSource={dataSource}
|
||||
loading={loading}
|
||||
dataSource={apiKeyPaging?.items || []}
|
||||
loading={isLoading || isFetching}
|
||||
rowKey="id"
|
||||
pagination={{
|
||||
current,
|
||||
current: pageIndex,
|
||||
pageSize,
|
||||
total,
|
||||
total: apiKeyPaging?.total || 0,
|
||||
showSizeChanger: true,
|
||||
}}
|
||||
onChange={handleTableChange}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {useState, useEffect} from 'react';
|
||||
import {useEffect, useState} from 'react';
|
||||
import {useSearchParams} from 'react-router-dom';
|
||||
import {App, Button, Divider, Input, Space, Table, Tag, Tooltip} from 'antd';
|
||||
import type {ColumnsType} from 'antd/es/table';
|
||||
@@ -11,13 +11,12 @@ import {getErrorMessage} from '@/lib/utils';
|
||||
import DDNSModal from './DDNSModal.tsx';
|
||||
import RecordsDrawer from './RecordsDrawer.tsx';
|
||||
import DNSProviderModal from './DNSProviderModal.tsx';
|
||||
import {useQuery, useQueryClient} from '@tanstack/react-query';
|
||||
|
||||
const DDNSPage = () => {
|
||||
const {message, modal} = App.useApp();
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [dataSource, setDataSource] = useState<DDNSConfig[]>([]);
|
||||
const queryClient = useQueryClient();
|
||||
const [searchParams, setSearchParams] = useSearchParams();
|
||||
const [total, setTotal] = useState(0);
|
||||
const [searchValue, setSearchValue] = useState('');
|
||||
const [modalOpen, setModalOpen] = useState(false);
|
||||
const [recordsDrawerOpen, setRecordsDrawerOpen] = useState(false);
|
||||
@@ -31,37 +30,30 @@ const DDNSPage = () => {
|
||||
huaweicloud: '华为云',
|
||||
};
|
||||
|
||||
const current = Number(searchParams.get('page')) || 1;
|
||||
const pageIndex = Number(searchParams.get('pageIndex')) || 1;
|
||||
const pageSize = Number(searchParams.get('pageSize')) || 10;
|
||||
const keyword = searchParams.get('keyword') ?? '';
|
||||
|
||||
// 加载数据
|
||||
const loadData = async (page: number, size: number, kw: string) => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const response = await getDDNSConfigs(page, size, kw || undefined);
|
||||
setDataSource(response.data.items || []);
|
||||
setTotal(response.data.total || 0);
|
||||
} catch (error: unknown) {
|
||||
message.error(getErrorMessage(error, '获取 DDNS 配置列表失败'));
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
const {
|
||||
data: ddnsPaging,
|
||||
isLoading,
|
||||
isFetching,
|
||||
} = useQuery({
|
||||
queryKey: ['admin', 'ddns', pageIndex, pageSize, keyword],
|
||||
queryFn: async () => {
|
||||
const response = await getDDNSConfigs(pageIndex, pageSize, keyword || undefined);
|
||||
return response.data;
|
||||
},
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
setSearchValue(keyword);
|
||||
}, [keyword]);
|
||||
|
||||
useEffect(() => {
|
||||
loadData(current, pageSize, keyword);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [current, pageSize, keyword]);
|
||||
|
||||
// 处理表格变化
|
||||
const handleTableChange = (newPagination: any) => {
|
||||
const nextParams = new URLSearchParams(searchParams);
|
||||
nextParams.set('page', String(newPagination.current || 1));
|
||||
nextParams.set('pageIndex', String(newPagination.current || 1));
|
||||
nextParams.set('pageSize', String(newPagination.pageSize || pageSize));
|
||||
setSearchParams(nextParams);
|
||||
};
|
||||
@@ -76,7 +68,7 @@ const DDNSPage = () => {
|
||||
} else {
|
||||
nextParams.delete('keyword');
|
||||
}
|
||||
nextParams.set('page', '1');
|
||||
nextParams.set('pageIndex', '1');
|
||||
nextParams.set('pageSize', String(pageSize));
|
||||
setSearchParams(nextParams);
|
||||
};
|
||||
@@ -105,7 +97,7 @@ const DDNSPage = () => {
|
||||
await enableDDNSConfig(config.id);
|
||||
message.success('已启用');
|
||||
}
|
||||
loadData(current, pageSize, keyword);
|
||||
queryClient.invalidateQueries({queryKey: ['admin', 'ddns']});
|
||||
} catch (error: unknown) {
|
||||
message.error(getErrorMessage(error, '操作失败'));
|
||||
}
|
||||
@@ -120,7 +112,7 @@ const DDNSPage = () => {
|
||||
try {
|
||||
await deleteDDNSConfig(config.id);
|
||||
message.success('删除成功');
|
||||
loadData(current, pageSize, keyword);
|
||||
queryClient.invalidateQueries({queryKey: ['admin', 'ddns']});
|
||||
} catch (error: unknown) {
|
||||
message.error(getErrorMessage(error, '删除失败'));
|
||||
}
|
||||
@@ -306,13 +298,13 @@ const DDNSPage = () => {
|
||||
|
||||
<Table<DDNSConfig>
|
||||
columns={columns}
|
||||
dataSource={dataSource}
|
||||
loading={loading}
|
||||
dataSource={ddnsPaging?.items || []}
|
||||
loading={isLoading || isFetching}
|
||||
rowKey="id"
|
||||
pagination={{
|
||||
current,
|
||||
current: pageIndex,
|
||||
pageSize,
|
||||
total,
|
||||
total: ddnsPaging?.total || 0,
|
||||
showSizeChanger: true,
|
||||
}}
|
||||
onChange={handleTableChange}
|
||||
@@ -328,7 +320,7 @@ const DDNSPage = () => {
|
||||
onSuccess={() => {
|
||||
setModalOpen(false);
|
||||
setSelectedConfig(null);
|
||||
loadData(current, pageSize, keyword);
|
||||
queryClient.invalidateQueries({queryKey: ['admin', 'ddns']});
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -347,7 +339,7 @@ const DDNSPage = () => {
|
||||
open={providerModalOpen}
|
||||
onCancel={() => setProviderModalOpen(false)}
|
||||
onSuccess={() => {
|
||||
loadData(current, pageSize, keyword);
|
||||
queryClient.invalidateQueries({queryKey: ['admin', 'ddns']});
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -20,7 +20,7 @@ const MonitorList = () => {
|
||||
const [searchParams, setSearchParams] = useSearchParams();
|
||||
const [searchValue, setSearchValue] = useState('');
|
||||
|
||||
const current = Number(searchParams.get('page')) || 1;
|
||||
const pageIndex = Number(searchParams.get('pageIndex')) || 1;
|
||||
const pageSize = Number(searchParams.get('pageSize')) || 10;
|
||||
const keyword = searchParams.get('keyword') ?? '';
|
||||
|
||||
@@ -28,14 +28,12 @@ const MonitorList = () => {
|
||||
data: monitorPaging,
|
||||
isLoading,
|
||||
isFetching,
|
||||
isError: monitorError,
|
||||
error: monitorErrorDetail,
|
||||
refetch,
|
||||
} = useQuery({
|
||||
queryKey: ['admin', 'monitors', current, pageSize, keyword],
|
||||
queryKey: ['admin', 'monitors', pageIndex, pageSize, keyword],
|
||||
queryFn: async () => {
|
||||
const response = await listMonitors(
|
||||
current,
|
||||
pageIndex,
|
||||
pageSize,
|
||||
keyword || undefined,
|
||||
);
|
||||
@@ -54,12 +52,6 @@ const MonitorList = () => {
|
||||
},
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (monitorError && monitorErrorDetail) {
|
||||
message.error(getErrorMessage(monitorErrorDetail, '获取监控列表失败'));
|
||||
}
|
||||
}, [monitorError, monitorErrorDetail, message]);
|
||||
|
||||
useEffect(() => {
|
||||
setSearchValue(keyword);
|
||||
}, [keyword]);
|
||||
@@ -91,7 +83,7 @@ const MonitorList = () => {
|
||||
|
||||
const handleTableChange = (nextPagination: TablePaginationConfig) => {
|
||||
const nextParams = new URLSearchParams(searchParams);
|
||||
nextParams.set('page', String(nextPagination.current || 1));
|
||||
nextParams.set('pageIndex', String(nextPagination.current || 1));
|
||||
nextParams.set('pageSize', String(nextPagination.pageSize || pageSize));
|
||||
setSearchParams(nextParams);
|
||||
};
|
||||
@@ -105,7 +97,7 @@ const MonitorList = () => {
|
||||
} else {
|
||||
nextParams.delete('keyword');
|
||||
}
|
||||
nextParams.set('page', '1');
|
||||
nextParams.set('pageIndex', '1');
|
||||
nextParams.set('pageSize', String(pageSize));
|
||||
setSearchParams(nextParams);
|
||||
};
|
||||
@@ -278,7 +270,7 @@ const MonitorList = () => {
|
||||
loading={isLoading || isFetching}
|
||||
rowKey="id"
|
||||
pagination={{
|
||||
current,
|
||||
current: pageIndex,
|
||||
pageSize,
|
||||
total,
|
||||
showSizeChanger: true,
|
||||
|
||||
@@ -12,9 +12,9 @@ export const generateApiKey = (data: GenerateApiKeyRequest) => {
|
||||
};
|
||||
|
||||
// 获取 API Key 列表
|
||||
export const listApiKeys = (page: number = 1, pageSize: number = 10, name?: string) => {
|
||||
export const listApiKeys = (pageIndex: number = 1, pageSize: number = 10, name?: string) => {
|
||||
const params = new URLSearchParams();
|
||||
params.append('page', page.toString());
|
||||
params.append('pageIndex', pageIndex.toString());
|
||||
params.append('pageSize', pageSize.toString());
|
||||
if (name) {
|
||||
params.append('name', name);
|
||||
|
||||
+3
-3
@@ -12,10 +12,10 @@ export interface DDNSRecordListResponse {
|
||||
}
|
||||
|
||||
// 获取 DDNS 配置列表(分页)
|
||||
export const getDDNSConfigs = (page: number, size: number, name?: string, agentId?: string) => {
|
||||
export const getDDNSConfigs = (pageIndex: number, pageSize: number, name?: string, agentId?: string) => {
|
||||
const params = new URLSearchParams();
|
||||
params.append('page', page.toString());
|
||||
params.append('size', size.toString());
|
||||
params.append('pageIndex', pageIndex.toString());
|
||||
params.append('pageSize', pageSize.toString());
|
||||
if (name) {
|
||||
params.append('name', name);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user