From d88bdfb1f466af9fba9254ec287bdb296e204628 Mon Sep 17 00:00:00 2001 From: Jerry Yan <792602257@qq.com> Date: Wed, 21 Jan 2026 13:50:18 +0800 Subject: [PATCH] =?UTF-8?q?feat(dataset):=20=E6=B7=BB=E5=8A=A0=E5=AD=90?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E9=9B=86=E5=B1=95=E7=A4=BA=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在 DatasetDetail 页面引入 Table 和 Tag 组件用于子数据集展示 - 新增 queryDatasetsUsingGet 接口调用方法用于获取子数据集列表 - 添加 childDatasets 和 childDatasetsLoading 状态管理 - 实现 tabList 动态渲染,父数据集显示子数据集选项卡 - 添加 fetchChildDatasets 方法异步获取子数据集数据 - 实现子数据集表格列定义,包含名称、类型、状态、文件数等信息 - 在子数据集选项卡中展示表格并添加加载状态和空数据提示 - 添加子数据集数量统计显示 - 优化标签颜色显示和数据映射逻辑 --- .../DataManagement/Detail/DatasetDetail.tsx | 161 ++++++++++++++---- 1 file changed, 130 insertions(+), 31 deletions(-) diff --git a/frontend/src/pages/DataManagement/Detail/DatasetDetail.tsx b/frontend/src/pages/DataManagement/Detail/DatasetDetail.tsx index af9c00e..1dc55a8 100644 --- a/frontend/src/pages/DataManagement/Detail/DatasetDetail.tsx +++ b/frontend/src/pages/DataManagement/Detail/DatasetDetail.tsx @@ -1,5 +1,5 @@ import { useEffect, useMemo, useState } from "react"; -import { Breadcrumb, App, Tabs } from "antd"; +import { Breadcrumb, App, Tabs, Table, Tag } from "antd"; import { ReloadOutlined, DownloadOutlined, @@ -13,14 +13,15 @@ import { mapDataset, datasetTypeMap } from "../dataset.const"; import type { Dataset } from "@/pages/DataManagement/dataset.model"; import { Link, useNavigate, useParams } from "react-router"; import { useFilesOperation } from "./useFilesOperation"; -import { - createDatasetTagUsingPost, - deleteDatasetByIdUsingDelete, - downloadDatasetUsingGet, - queryDatasetByIdUsingGet, - queryDatasetTagsUsingGet, - updateDatasetByIdUsingPut, -} from "../dataset.api"; +import { + createDatasetTagUsingPost, + deleteDatasetByIdUsingDelete, + downloadDatasetUsingGet, + queryDatasetByIdUsingGet, + queryDatasetsUsingGet, + queryDatasetTagsUsingGet, + updateDatasetByIdUsingPut, +} from "../dataset.api"; import DataQuality from "./components/DataQuality"; import DataLineageFlow from "./components/DataLineageFlow"; import Overview from "./components/Overview"; @@ -28,22 +29,17 @@ import { Activity, Clock, File, FileType } from "lucide-react"; import EditDataset from "../Create/EditDataset"; import ImportConfiguration from "./components/ImportConfiguration"; -const tabList = [ - { - key: "overview", - label: "概览", - }, -]; - -export default function DatasetDetail() { - const { id } = useParams(); // 获取动态路由参数 - const navigate = useNavigate(); +export default function DatasetDetail() { + const { id } = useParams(); // 获取动态路由参数 + const navigate = useNavigate(); const [activeTab, setActiveTab] = useState("overview"); const { message } = App.useApp(); const [showEditDialog, setShowEditDialog] = useState(false); const [dataset, setDataset] = useState({} as Dataset); const [parentDataset, setParentDataset] = useState(null); + const [childDatasets, setChildDatasets] = useState([]); + const [childDatasetsLoading, setChildDatasetsLoading] = useState(false); const filesOperation = useFilesOperation(dataset); const [showUploadDialog, setShowUploadDialog] = useState(false); @@ -67,6 +63,21 @@ export default function DatasetDetail() { }); return items; }, [dataset, parentDataset]); + const tabList = useMemo(() => { + const items = [ + { + key: "overview", + label: "概览", + }, + ]; + if (!dataset?.parentDatasetId) { + items.push({ + key: "children", + label: "子数据集", + }); + } + return items; + }, [dataset?.parentDatasetId]); const handleCreateChildDataset = () => { if (!dataset?.id) { return; @@ -75,6 +86,24 @@ export default function DatasetDetail() { state: { parentDatasetId: dataset.id }, }); }; + const fetchChildDatasets = async (parentId?: string) => { + if (!parentId) { + setChildDatasets([]); + return; + } + setChildDatasetsLoading(true); + try { + const { data: res } = await queryDatasetsUsingGet({ + parentDatasetId: parentId, + page: 1, + size: 1000, + }); + const list = res?.content || res?.data || []; + setChildDatasets(list.map((item) => mapDataset(item))); + } finally { + setChildDatasetsLoading(false); + } + }; const fetchDataset = async () => { if (!id) { return; @@ -87,15 +116,22 @@ export default function DatasetDetail() { data.parentDatasetId ); setParentDataset(mapDataset(parentData)); + setChildDatasets([]); } else { setParentDataset(null); + await fetchChildDatasets(data?.id); } }; - useEffect(() => { + useEffect(() => { fetchDataset(); filesOperation.fetchFiles('', 1, 10); // 从根目录开始,第一页 - }, []); + }, []); + useEffect(() => { + if (dataset?.parentDatasetId && activeTab === "children") { + setActiveTab("overview"); + } + }, [activeTab, dataset?.parentDatasetId]); const handleRefresh = async (showMessage = true, prefixOverride?: string) => { fetchDataset(); @@ -226,7 +262,52 @@ export default function DatasetDetail() { icon: , onClick: handleDeleteDataset, }, - ]; + ]; + const childColumns = [ + { + title: "名称", + dataIndex: "name", + key: "name", + render: (_: string, record: Dataset) => ( + {record.name} + ), + }, + { + title: "类型", + dataIndex: "datasetType", + key: "datasetType", + width: 120, + render: (value: string) => datasetTypeMap[value]?.label || "未知", + }, + { + title: "状态", + dataIndex: "status", + key: "status", + width: 120, + render: (status) => + status ? {status.label} : "-", + }, + { + title: "文件数", + dataIndex: "fileCount", + key: "fileCount", + width: 120, + render: (value?: number) => value ?? 0, + }, + { + title: "大小", + dataIndex: "size", + key: "size", + width: 140, + render: (value?: string) => value || "0 B", + }, + { + title: "更新时间", + dataIndex: "updatedAt", + key: "updatedAt", + width: 180, + }, + ]; return (
@@ -266,15 +347,33 @@ export default function DatasetDetail() { }} />
- -
- {activeTab === "overview" && ( - - )} - {activeTab === "lineage" && } - {activeTab === "quality" && } -
-
+ +
+ {activeTab === "overview" && ( + + )} + {activeTab === "children" && ( +
+
+

子数据集

+ + 共 {childDatasets.length} 个 + +
+ + + )} + {activeTab === "lineage" && } + {activeTab === "quality" && } + +