feat(dataset): 添加子数据集展示功能

- 在 DatasetDetail 页面引入 Table 和 Tag 组件用于子数据集展示
- 新增 queryDatasetsUsingGet 接口调用方法用于获取子数据集列表
- 添加 childDatasets 和 childDatasetsLoading 状态管理
- 实现 tabList 动态渲染,父数据集显示子数据集选项卡
- 添加 fetchChildDatasets 方法异步获取子数据集数据
- 实现子数据集表格列定义,包含名称、类型、状态、文件数等信息
- 在子数据集选项卡中展示表格并添加加载状态和空数据提示
- 添加子数据集数量统计显示
- 优化标签颜色显示和数据映射逻辑
This commit is contained in:
2026-01-21 13:50:18 +08:00
parent ec27e2fa3e
commit d88bdfb1f4

View File

@@ -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,
@@ -18,6 +18,7 @@ import {
deleteDatasetByIdUsingDelete,
downloadDatasetUsingGet,
queryDatasetByIdUsingGet,
queryDatasetsUsingGet,
queryDatasetTagsUsingGet,
updateDatasetByIdUsingPut,
} from "../dataset.api";
@@ -28,13 +29,6 @@ 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();
@@ -44,6 +38,8 @@ export default function DatasetDetail() {
const [dataset, setDataset] = useState<Dataset>({} as Dataset);
const [parentDataset, setParentDataset] = useState<Dataset | null>(null);
const [childDatasets, setChildDatasets] = useState<Dataset[]>([]);
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,8 +116,10 @@ export default function DatasetDetail() {
data.parentDatasetId
);
setParentDataset(mapDataset(parentData));
setChildDatasets([]);
} else {
setParentDataset(null);
await fetchChildDatasets(data?.id);
}
};
@@ -96,6 +127,11 @@ export default function DatasetDetail() {
fetchDataset();
filesOperation.fetchFiles('', 1, 10); // 从根目录开始,第一页
}, []);
useEffect(() => {
if (dataset?.parentDatasetId && activeTab === "children") {
setActiveTab("overview");
}
}, [activeTab, dataset?.parentDatasetId]);
const handleRefresh = async (showMessage = true, prefixOverride?: string) => {
fetchDataset();
@@ -227,6 +263,51 @@ export default function DatasetDetail() {
onClick: handleDeleteDataset,
},
];
const childColumns = [
{
title: "名称",
dataIndex: "name",
key: "name",
render: (_: string, record: Dataset) => (
<Link to={`/data/management/detail/${record.id}`}>{record.name}</Link>
),
},
{
title: "类型",
dataIndex: "datasetType",
key: "datasetType",
width: 120,
render: (value: string) => datasetTypeMap[value]?.label || "未知",
},
{
title: "状态",
dataIndex: "status",
key: "status",
width: 120,
render: (status) =>
status ? <Tag color={status.color}>{status.label}</Tag> : "-",
},
{
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 (
<div className="h-full flex flex-col gap-4">
@@ -271,6 +352,24 @@ export default function DatasetDetail() {
{activeTab === "overview" && (
<Overview dataset={dataset} filesOperation={filesOperation} fetchDataset={fetchDataset}/>
)}
{activeTab === "children" && (
<div className="pt-4">
<div className="flex items-center justify-between mb-3">
<h2 className="text-base font-semibold"></h2>
<span className="text-xs text-gray-500">
{childDatasets.length}
</span>
</div>
<Table
rowKey="id"
columns={childColumns}
dataSource={childDatasets}
loading={childDatasetsLoading}
pagination={false}
locale={{ emptyText: "暂无子数据集" }}
/>
</div>
)}
{activeTab === "lineage" && <DataLineageFlow dataset={dataset} />}
{activeTab === "quality" && <DataQuality />}
</div>