From 4e53cc813b09f4845ab5f1c2852c8eddf6fa8b23 Mon Sep 17 00:00:00 2001 From: chenghh-9609 <1159096025@qq.com> Date: Thu, 23 Oct 2025 16:56:36 +0800 Subject: [PATCH] feat: Enhance CardView and DatasetManagement with loading state and pagination updates --- frontend/src/components/CardView.tsx | 55 ++++--------------- frontend/src/hooks/useFetchData.ts | 6 +- .../Create/components/CreateTaskStepOne.tsx | 2 +- .../Detail/components/Overview.tsx | 1 + .../DataManagement/Home/DataManagement.tsx | 11 ++-- frontend/src/utils/request.ts | 1 - 6 files changed, 22 insertions(+), 54 deletions(-) diff --git a/frontend/src/components/CardView.tsx b/frontend/src/components/CardView.tsx index a3e934e..d3d8dc3 100644 --- a/frontend/src/components/CardView.tsx +++ b/frontend/src/components/CardView.tsx @@ -5,8 +5,6 @@ import { Tooltip, Empty, Popover, - Menu, - Popconfirm, } from "antd"; import { ClockCircleOutlined, StarFilled } from "@ant-design/icons"; import type { ItemType } from "antd/es/menu/interface"; @@ -47,6 +45,7 @@ interface CardViewProps { onClick?: (item: T) => void; }[] | ((item: T) => ItemType[]); + loading?: boolean; onView?: (item: T) => void; onFavorite?: (item: T) => void; isFavorite?: (item: T) => boolean; @@ -160,8 +159,15 @@ const TagsRenderer = ({ tags }: { tags?: any[] }) => { }; function CardView(props: CardViewProps) { - const { data, pagination, operations, onView, onFavorite, isFavorite } = - props; + const { + data, + pagination, + operations, + loading, + onView, + onFavorite, + isFavorite, + } = props; if (data.length === 0) { return ( @@ -174,47 +180,6 @@ function CardView(props: CardViewProps) { const ops = (item) => typeof operations === "function" ? operations(item) : operations; - const menu = (item) => { - const ops = - typeof operations === "function" ? operations(item) : operations; - - {ops.map((op) => { - if (op?.danger) { - return ( - - op.onClick(item) : undefined} - okText="确定" - cancelText="取消" - // 阻止事件冒泡,避免 Dropdown 关闭 - onClick={(e) => e.stopPropagation()} - > -
e.stopPropagation()} - > - {op.icon} - {op.label} -
-
-
- ); - } else { - return ( - - {op?.label} - - ); - } - })} -
; - }; return (
diff --git a/frontend/src/hooks/useFetchData.ts b/frontend/src/hooks/useFetchData.ts index 6042ad4..b0d7ff5 100644 --- a/frontend/src/hooks/useFetchData.ts +++ b/frontend/src/hooks/useFetchData.ts @@ -23,7 +23,8 @@ export default function useFetchData( mapDataFunc: (data: AnyObject) => T = (data) => data as T, pollingInterval: number = 30000, // 默认30秒轮询一次 autoRefresh: boolean = true, - additionalPollingFuncs: (() => Promise)[] = [] // 额外的轮询函数 + additionalPollingFuncs: (() => Promise)[] = [], // 额外的轮询函数 + pageOffset: number = 1 ) { const { message } = App.useApp(); @@ -88,7 +89,6 @@ export default function useFetchData( const fetchData = useCallback( async (extraParams = {}, skipPollingRestart = false) => { const { keyword, filter, current, pageSize } = searchParams; - if (!skipPollingRestart) { Loading.show(); setLoading(true); @@ -110,7 +110,7 @@ export default function useFetchData( type: getFirstOfArray(filter?.type) || undefined, status: getFirstOfArray(filter?.status) || undefined, tags: filter?.tags?.length ? filter.tags.join(",") : undefined, - page: current - 1, + page: current - pageOffset, size: pageSize, }), ...additionalPollingFuncs.map((func) => func()), diff --git a/frontend/src/pages/DataCleansing/Create/components/CreateTaskStepOne.tsx b/frontend/src/pages/DataCleansing/Create/components/CreateTaskStepOne.tsx index 976a678..7fa6595 100644 --- a/frontend/src/pages/DataCleansing/Create/components/CreateTaskStepOne.tsx +++ b/frontend/src/pages/DataCleansing/Create/components/CreateTaskStepOne.tsx @@ -29,7 +29,7 @@ export default function CreateTaskStepOne({ const [datasets, setDatasets] = useState([]); const fetchDatasets = async () => { - const { data } = await queryDatasetsUsingGet({ page: 0, size: 1000 }); + const { data } = await queryDatasetsUsingGet({ page: 1, size: 1000 }); setDatasets(data.content.map(mapDataset) || []); }; diff --git a/frontend/src/pages/DataManagement/Detail/components/Overview.tsx b/frontend/src/pages/DataManagement/Detail/components/Overview.tsx index f5466e7..7964da7 100644 --- a/frontend/src/pages/DataManagement/Detail/components/Overview.tsx +++ b/frontend/src/pages/DataManagement/Detail/components/Overview.tsx @@ -179,6 +179,7 @@ export default function Overview({ dataset, filesOperation }) { dataSource={fileList} // rowSelection={rowSelection} scroll={{ x: "max-content", y: 600 }} + pagination={{ showTotal: (total) => `共 ${total} 条` }} />
diff --git a/frontend/src/pages/DataManagement/Home/DataManagement.tsx b/frontend/src/pages/DataManagement/Home/DataManagement.tsx index ec81a64..4b00667 100644 --- a/frontend/src/pages/DataManagement/Home/DataManagement.tsx +++ b/frontend/src/pages/DataManagement/Home/DataManagement.tsx @@ -51,7 +51,7 @@ export default function DatasetManagementPage() { }, { title: "文件总数", - value: data?.totalFiles?.image || "0 MB", + value: data?.totalFiles || "0 MB", }, { title: "总大小", @@ -113,6 +113,7 @@ export default function DatasetManagementPage() { ); const { + loading, tableData, searchParams, pagination, @@ -124,7 +125,8 @@ export default function DatasetManagementPage() { mapDataset, 30000, // 30秒轮询间隔 true, // 自动刷新 - [fetchStatistics] // 额外的轮询函数 + [fetchStatistics], // 额外的轮询函数 + 0 ); const handleDownloadDataset = async (dataset: Dataset) => { @@ -135,7 +137,7 @@ export default function DatasetManagementPage() { const handleDeleteDataset = async (id: number) => { if (!id) return; await deleteDatasetByIdUsingDelete(id); - fetchData(); + fetchData({ pageOffset: 0 }); message.success("数据删除成功"); }; @@ -145,7 +147,7 @@ export default function DatasetManagementPage() { }; const handleRefresh = async (showMessage = true) => { - await fetchData(); + await fetchData({ pageOffset: 0 }); if (showMessage) { message.success("数据已刷新"); } @@ -295,6 +297,7 @@ export default function DatasetManagementPage() { const renderCardView = () => (