From c52702b073115d05493733f3a7292834e55c4d7d Mon Sep 17 00:00:00 2001 From: chenghh-9609 <55340429+chenghh-9609@users.noreply.github.com> Date: Thu, 23 Oct 2025 16:48:42 +0800 Subject: [PATCH] =?UTF-8?q?feat=EF=BC=9A=E4=BF=AE=E5=A4=8D=E4=B8=8B?= =?UTF-8?q?=E8=BD=BD=E6=95=B0=E6=8D=AE=E9=9B=86=E9=97=AE=E9=A2=98=E3=80=81?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=95=B0=E6=8D=AE=E7=A1=AE=E8=AE=A4=E6=A1=86?= =?UTF-8?q?=E3=80=81=E4=BF=AE=E6=94=B9=E6=A0=87=E9=A2=98=E3=80=81=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E5=88=97=E8=A1=A8=E8=BD=AE=E8=AF=A2=E5=88=B7=E6=96=B0?= =?UTF-8?q?=20(#16)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: clean up tag management and dataset handling, update API endpoints * feat: add showTime prop to DevelopmentInProgress component across multiple pages * refactor: update component styles and improve layout with new utility classes * feat: enhance useFetchData hook with polling functionality and improve task progress tracking * feat: enhance dataset management features with improved tag handling, download functionality, and UI updates * feat: Enhance DatasetDetail component with delete functionality and improved download handling feat: Add automatic data refresh and improved user feedback in DatasetManagementPage fix: Update dataset API to streamline download functionality and improve error handling * feat: Clear new tag input after successful addition in TagManager --- frontend/src/components/ActionDropdown.tsx | 115 +++++ frontend/src/components/AddTagPopover.tsx | 41 +- frontend/src/components/CardView.tsx | 210 +++++---- frontend/src/components/DetailHeader.tsx | 47 +- frontend/src/components/TagManagement.tsx | 1 + frontend/src/hooks/useFetchData.ts | 179 ++++++-- frontend/src/mock/cleansing.tsx | 56 --- .../src/mock/mock-seed/data-cleansing.cjs | 14 +- .../pages/DataCleansing/Create/DragDrop.css | 411 ----------------- .../DataCleansing/Create/DragExample.tsx | 430 ------------------ .../Create/components/CreateTaskStepOne.tsx | 9 +- .../Home/components/TaskList.tsx | 76 +++- .../Home/components/TemplateList.tsx | 3 +- .../pages/DataCleansing/cleansing.const.tsx | 11 +- .../DataManagement/Create/CreateDataset.tsx | 12 +- .../DataManagement/Create/EditDataset.tsx | 6 +- .../DataManagement/Detail/DatasetDetail.tsx | 35 +- .../Detail/components/ImportConfiguration.tsx | 95 +++- .../Detail/components/Overview.tsx | 5 - .../{hooks => Detail}/useFilesOperation.ts | 4 +- .../DataManagement/Home/DataManagement.tsx | 63 ++- .../src/pages/DataManagement/dataset.api.ts | 21 +- .../pages/DataManagement/dataset.const.tsx | 5 +- .../src/pages/DataManagement/hooks/index.ts | 2 - .../DataManagement/hooks/useImportFile.tsx | 61 --- frontend/src/pages/Layout/Sidebar.tsx | 2 +- frontend/src/utils/request.ts | 16 +- frontend/src/utils/unit.ts | 1 + 28 files changed, 715 insertions(+), 1216 deletions(-) create mode 100644 frontend/src/components/ActionDropdown.tsx delete mode 100644 frontend/src/mock/cleansing.tsx delete mode 100644 frontend/src/pages/DataCleansing/Create/DragDrop.css delete mode 100644 frontend/src/pages/DataCleansing/Create/DragExample.tsx rename frontend/src/pages/DataManagement/{hooks => Detail}/useFilesOperation.ts (97%) delete mode 100644 frontend/src/pages/DataManagement/hooks/index.ts delete mode 100644 frontend/src/pages/DataManagement/hooks/useImportFile.tsx diff --git a/frontend/src/components/ActionDropdown.tsx b/frontend/src/components/ActionDropdown.tsx new file mode 100644 index 0000000..ae4e039 --- /dev/null +++ b/frontend/src/components/ActionDropdown.tsx @@ -0,0 +1,115 @@ +import { Dropdown, Popconfirm, Button, Space } from "antd"; +import { EllipsisOutlined } from "@ant-design/icons"; +import { useState } from "react"; + +interface ActionItem { + key: string; + label: string; + icon?: React.ReactNode; + danger?: boolean; + confirm?: { + title: string; + description?: string; + okText?: string; + cancelText?: string; + }; +} + +interface ActionDropdownProps { + actions?: ActionItem[]; + onAction?: (key: string, action: ActionItem) => void; + placement?: + | "bottomRight" + | "topLeft" + | "topCenter" + | "topRight" + | "bottomLeft" + | "bottomCenter" + | "top" + | "bottom"; +} + +const ActionDropdown = ({ + actions = [], + onAction, + placement = "bottomRight", +}: ActionDropdownProps) => { + const [open, setOpen] = useState(false); + const handleActionClick = (action: ActionItem) => { + if (action.confirm) { + // 如果有确认框,不立即执行,等待确认 + return; + } + // 执行操作 + onAction?.(action.key, action); + // 如果没有确认框,则立即关闭 Dropdown + setOpen(false); + }; + + const dropdownContent = ( +
+ + {actions.map((action) => { + if (action.confirm) { + return ( + { + onAction?.(action.key, action); + setOpen(false); + }} + okText={action.confirm.okText || "确定"} + cancelText={action.confirm.cancelText || "取消"} + okType={action.danger ? "danger" : "primary"} + styles={{ root: { zIndex: 9999 } }} + > + + + ); + } + + return ( + + ); + })} + +
+ ); + + return ( + + - )} - - -
- {rightItems.length === 0 ? ( -
-

📥 暂无进行中的任务

- 从左侧拖拽项目过来开始工作 -
- ) : ( - rightItems.map((item, index) => ( -
handleDragStart(e, item, "right")} - onDragEnd={handleDragEnd} - onDragOver={(e) => handleItemDragOver(e, item.id)} - onDragLeave={handleItemDragLeave} - onDrop={(e) => handleDropToRightItem(e, item.id)} - style={{ "--item-color": item.color }} - > -
- {index + 1} - {getTypeIcon(item.type)} -
- {item.title} - - {getPriorityLabel(item.priority).label} - -
-
-
- ⋮⋮ -
-
- )) - )} -
- - - -
-

🎯 操作指南

-
-
- 🎯 -
- 精确插入 -

拖拽时悬停在项目上方或下方选择插入位置

-
-
-
- 🔄 -
- 重新排序 -

在右侧容器内拖拽调整任务顺序

-
-
-
- 📤 -
- 移回待办 -

从右侧拖拽任务回左侧容器

-
-
-
- 🧹 -
- 批量操作 -

使用"清空所有"按钮快速重置

-
-
-
-
- - ); -}; - -export default PreciseDragDrop; diff --git a/frontend/src/pages/DataCleansing/Create/components/CreateTaskStepOne.tsx b/frontend/src/pages/DataCleansing/Create/components/CreateTaskStepOne.tsx index 564d6e4..976a678 100644 --- a/frontend/src/pages/DataCleansing/Create/components/CreateTaskStepOne.tsx +++ b/frontend/src/pages/DataCleansing/Create/components/CreateTaskStepOne.tsx @@ -1,10 +1,6 @@ import RadioCard from "@/components/RadioCard"; import { queryDatasetsUsingGet } from "@/pages/DataManagement/dataset.api"; -import { - datasetTypeMap, - datasetTypes, - mapDataset, -} from "@/pages/DataManagement/dataset.const"; +import { datasetTypes, mapDataset } from "@/pages/DataManagement/dataset.const"; import { Dataset, DatasetSubType, @@ -12,8 +8,7 @@ import { } from "@/pages/DataManagement/dataset.model"; import { Input, Select, Form } from "antd"; import TextArea from "antd/es/input/TextArea"; -import { Database } from "lucide-react"; -import { useEffect, useMemo, useState } from "react"; +import { useEffect, useState } from "react"; export default function CreateTaskStepOne({ form, diff --git a/frontend/src/pages/DataCleansing/Home/components/TaskList.tsx b/frontend/src/pages/DataCleansing/Home/components/TaskList.tsx index 873456b..ef446a2 100644 --- a/frontend/src/pages/DataCleansing/Home/components/TaskList.tsx +++ b/frontend/src/pages/DataCleansing/Home/components/TaskList.tsx @@ -65,7 +65,7 @@ export default function TaskList() { fetchData(); }; - const taskOperations = (record) => { + const taskOperations = (record: CleansingTask) => { const isRunning = record.status?.value === TaskStatus.RUNNING; const showStart = [ TaskStatus.PENDING, @@ -91,7 +91,8 @@ export default function TaskList() { { key: "delete", label: "删除", - icon: , + danger: true, + icon: , onClick: deleteTask, // implement delete logic }, ]; @@ -104,12 +105,21 @@ export default function TaskList() { key: "name", fixed: "left", width: 150, + ellipsis: true, + }, + { + title: "任务ID", + dataIndex: "id", + key: "id", + width: 150, + ellipsis: true, }, { title: "源数据集", dataIndex: "srcDatasetId", key: "srcDatasetId", width: 150, + ellipsis: true, render: (_, record: CleansingTask) => { return ( - diff --git a/frontend/src/pages/DataManagement/Create/EditDataset.tsx b/frontend/src/pages/DataManagement/Create/EditDataset.tsx index 0847372..f43ba7f 100644 --- a/frontend/src/pages/DataManagement/Create/EditDataset.tsx +++ b/frontend/src/pages/DataManagement/Create/EditDataset.tsx @@ -5,7 +5,7 @@ import { } from "../dataset.api"; import { useEffect, useState } from "react"; import { Dataset, DatasetType } from "../dataset.model"; -import { App, Button, Drawer, Form, Modal } from "antd"; +import { App, Button, Form, Modal } from "antd"; export default function EditDataset({ open, @@ -16,7 +16,7 @@ export default function EditDataset({ open: boolean; data: Dataset | null; onClose: () => void; - onRefresh?: () => void; + onRefresh?: (showMessage?: boolean) => void; }) { const [form] = Form.useForm(); const { message } = App.useApp(); @@ -60,7 +60,7 @@ export default function EditDataset({ await updateDatasetByIdUsingPut(data?.id, params); onClose(); message.success("数据集更新成功"); - onRefresh?.(); + onRefresh?.(false); } catch (error) { console.error(error); message.error("数据集更新失败,请重试"); diff --git a/frontend/src/pages/DataManagement/Detail/DatasetDetail.tsx b/frontend/src/pages/DataManagement/Detail/DatasetDetail.tsx index 6a6442e..23546d2 100644 --- a/frontend/src/pages/DataManagement/Detail/DatasetDetail.tsx +++ b/frontend/src/pages/DataManagement/Detail/DatasetDetail.tsx @@ -5,15 +5,17 @@ import { DownloadOutlined, UploadOutlined, EditOutlined, + DeleteOutlined, } from "@ant-design/icons"; import DetailHeader from "@/components/DetailHeader"; import { mapDataset, datasetTypeMap } from "../dataset.const"; import type { Dataset } from "@/pages/DataManagement/dataset.model"; -import { Link, useParams } from "react-router"; -import { useFilesOperation } from "../hooks"; +import { Link, useNavigate, useParams } from "react-router"; +import { useFilesOperation } from "./useFilesOperation"; import { createDatasetTagUsingPost, - downloadFile, + deleteDatasetByIdUsingDelete, + downloadDatasetUsingGet, queryDatasetByIdUsingGet, queryDatasetTagsUsingGet, updateDatasetByIdUsingPut, @@ -42,6 +44,7 @@ const tabList = [ export default function DatasetDetail() { const { id } = useParams(); // 获取动态路由参数 + const navigate = useNavigate(); const [activeTab, setActiveTab] = useState("overview"); const { message } = App.useApp(); const [showEditDialog, setShowEditDialog] = useState(false); @@ -77,11 +80,17 @@ export default function DatasetDetail() { if (showMessage) message.success({ content: "数据刷新成功" }); }; - const handleExportFormat = async ({ type }) => { - await downloadFile(dataset.id, type, `${dataset.name}-${type}.zip`); + const handleDownload = async () => { + await downloadDatasetUsingGet(dataset.id); message.success("文件下载成功"); }; + const handleDeleteDataset = async () => { + await deleteDatasetByIdUsingDelete(dataset.id); + navigate("/data/management"); + message.success("数据集删除成功"); + }; + useEffect(() => { const refreshDataset = () => { fetchDataset(); @@ -153,7 +162,7 @@ export default function DatasetDetail() { // { key: "csv", label: "CSV 格式", icon: }, // { key: "coco", label: "COCO 格式", icon: }, // ], - onMenuClick: handleExportFormat, + onClick: () => handleDownload(), }, { key: "refresh", @@ -161,6 +170,20 @@ export default function DatasetDetail() { icon: , onClick: handleRefresh, }, + { + key: "delete", + label: "删除", + danger: true, + confirm: { + title: "确认删除该数据集?", + description: "删除后该数据集将无法恢复,请谨慎操作。", + okText: "删除", + cancelText: "取消", + okType: "danger", + }, + icon: , + onClick: handleDeleteDataset, + }, ]; return ( diff --git a/frontend/src/pages/DataManagement/Detail/components/ImportConfiguration.tsx b/frontend/src/pages/DataManagement/Detail/components/ImportConfiguration.tsx index a35deed..ebb710f 100644 --- a/frontend/src/pages/DataManagement/Detail/components/ImportConfiguration.tsx +++ b/frontend/src/pages/DataManagement/Detail/components/ImportConfiguration.tsx @@ -1,10 +1,21 @@ -import { Select, Input, Form, Radio, Modal, Button } from "antd"; +import { + Select, + Input, + Form, + Radio, + Modal, + Button, + App, + UploadFile, +} from "antd"; +import { InboxOutlined } from "@ant-design/icons"; import { dataSourceOptions } from "../../dataset.const"; import { Dataset, DataSource } from "../../dataset.model"; -import { useEffect, useState } from "react"; +import { useEffect, useMemo, useState } from "react"; import { queryTasksUsingGet } from "@/pages/DataCollection/collection.apis"; -import { useImportFile } from "../../hooks"; import { updateDatasetByIdUsingPut } from "../../dataset.api"; +import { sliceFile } from "@/utils/file.util"; +import Dragger from "antd/es/upload/Dragger"; export default function ImportConfiguration({ data, @@ -15,16 +26,52 @@ export default function ImportConfiguration({ data?: Dataset; open: boolean; onClose: () => void; - onRefresh?: () => void; + onRefresh?: (showMessage?: boolean) => void; }) { + const { message } = App.useApp(); const [form] = Form.useForm(); const [collectionOptions, setCollectionOptions] = useState([]); const [importConfig, setImportConfig] = useState({ source: DataSource.UPLOAD, }); - const { importFileRender, handleUpload } = useImportFile(); - // 获取归集任务列表 + const [fileList, setFileList] = useState([]); + const fileSliceList = useMemo(() => { + const sliceList = fileList.map((file) => { + const slices = sliceFile(file); + return { originFile: file, slices, name: file.name, size: file.size }; + }); + return sliceList; + }, [fileList]); + + // 本地上传文件相关逻辑 + + const resetFiles = () => { + setFileList([]); + }; + + const handleUpload = async (dataset: Dataset) => { + const formData = new FormData(); + fileList.forEach((file) => { + formData.append("file", file); + }); + window.dispatchEvent( + new CustomEvent("upload:dataset", { + detail: { dataset, files: fileSliceList }, + }) + ); + resetFiles(); + }; + + const handleBeforeUpload = (_, files: UploadFile[]) => { + setFileList([...fileList, ...files]); + return false; + }; + + const handleRemoveFile = (file: UploadFile) => { + setFileList((prev) => prev.filter((f) => f.uid !== file.uid)); + }; + const fetchCollectionTasks = async () => { try { const res = await queryTasksUsingGet({ page: 0, size: 100 }); @@ -40,6 +87,8 @@ export default function ImportConfiguration({ const resetState = () => { form.resetFields(); + setFileList([]); + form.setFieldsValue({ files: null }); setImportConfig({ source: DataSource.UPLOAD }); }; @@ -51,13 +100,16 @@ export default function ImportConfiguration({ ...importConfig, }); } - resetState(); - onRefresh?.(); + message.success("数据已更新"); + onRefresh?.(false); onClose(); }; useEffect(() => { - if (open) fetchCollectionTasks(); + if (open) { + resetState(); + fetchCollectionTasks(); + } }, [open]); return ( @@ -65,12 +117,19 @@ export default function ImportConfiguration({ title="导入数据" open={open} width={600} - onCancel={onClose} + onCancel={() => { + onClose(); + resetState(); + }} maskClosable={false} footer={ <> - @@ -132,6 +191,7 @@ export default function ImportConfiguration({ )} + {/* obs import */} {importConfig?.source === DataSource.OBS && (
@@ -185,7 +245,18 @@ export default function ImportConfiguration({ }, ]} > - {importFileRender()} + +

+ +

+

本地文件上传

+

拖拽文件到此处或点击选择文件

+
)} diff --git a/frontend/src/pages/DataManagement/Detail/components/Overview.tsx b/frontend/src/pages/DataManagement/Detail/components/Overview.tsx index ed3754b..f5466e7 100644 --- a/frontend/src/pages/DataManagement/Detail/components/Overview.tsx +++ b/frontend/src/pages/DataManagement/Detail/components/Overview.tsx @@ -82,11 +82,6 @@ export default function Overview({ dataset, filesOperation }) { label: "更新时间", children: dataset.updatedAt, }, - { - key: "dataSource", - label: "数据源", - children: dataset.dataSource || "未知", - }, { key: "description", label: "描述", diff --git a/frontend/src/pages/DataManagement/hooks/useFilesOperation.ts b/frontend/src/pages/DataManagement/Detail/useFilesOperation.ts similarity index 97% rename from frontend/src/pages/DataManagement/hooks/useFilesOperation.ts rename to frontend/src/pages/DataManagement/Detail/useFilesOperation.ts index 17ca811..1c58b19 100644 --- a/frontend/src/pages/DataManagement/hooks/useFilesOperation.ts +++ b/frontend/src/pages/DataManagement/Detail/useFilesOperation.ts @@ -6,7 +6,7 @@ import { App } from "antd"; import { useState } from "react"; import { deleteDatasetFileUsingDelete, - downloadFile, + downloadFileByIdUsingGet, exportDatasetUsingPost, queryDatasetFilesUsingGet, } from "../dataset.api"; @@ -51,7 +51,7 @@ export function useFilesOperation(dataset: Dataset) { const handleDownloadFile = async (file: DatasetFile) => { console.log("批量下载文件:", selectedFiles); // 实际导出逻辑 - await downloadFile(dataset.id, file.id, file.fileName); + await downloadFileByIdUsingGet(dataset.id, file.id, file.fileName); // 假设导出成功 message.success({ content: `已导出 1 个文件`, diff --git a/frontend/src/pages/DataManagement/Home/DataManagement.tsx b/frontend/src/pages/DataManagement/Home/DataManagement.tsx index a5a66fa..ec81a64 100644 --- a/frontend/src/pages/DataManagement/Home/DataManagement.tsx +++ b/frontend/src/pages/DataManagement/Home/DataManagement.tsx @@ -4,6 +4,7 @@ import { EditOutlined, DeleteOutlined, PlusOutlined, + UploadOutlined, } from "@ant-design/icons"; import TagManager from "@/components/TagManagement"; import { Link, useNavigate } from "react-router"; @@ -25,6 +26,7 @@ import { } from "../dataset.api"; import { formatBytes } from "@/utils/unit"; import EditDataset from "../Create/EditDataset"; +import ImportConfiguration from "../Detail/components/ImportConfiguration"; export default function DatasetManagementPage() { const navigate = useNavigate(); @@ -32,7 +34,7 @@ export default function DatasetManagementPage() { const [viewMode, setViewMode] = useState<"card" | "list">("card"); const [editDatasetOpen, setEditDatasetOpen] = useState(false); const [currentDataset, setCurrentDataset] = useState(null); - + const [showUploadDialog, setShowUploadDialog] = useState(false); const [statisticsData, setStatisticsData] = useState({ count: {}, size: {}, @@ -117,7 +119,13 @@ export default function DatasetManagementPage() { fetchData, setSearchParams, handleFiltersChange, - } = useFetchData(queryDatasetsUsingGet, mapDataset); + } = useFetchData( + queryDatasetsUsingGet, + mapDataset, + 30000, // 30秒轮询间隔 + true, // 自动刷新 + [fetchStatistics] // 额外的轮询函数 + ); const handleDownloadDataset = async (dataset: Dataset) => { await downloadDatasetUsingGet(dataset.id, dataset.name); @@ -131,9 +139,17 @@ export default function DatasetManagementPage() { message.success("数据删除成功"); }; - useEffect(() => { - fetchStatistics(); - }, []); + const handleImportData = (dataset: Dataset) => { + setCurrentDataset(dataset); + setShowUploadDialog(true); + }; + + const handleRefresh = async (showMessage = true) => { + await fetchData(); + if (showMessage) { + message.success("数据已刷新"); + } + }; const operations = [ { @@ -141,11 +157,18 @@ export default function DatasetManagementPage() { label: "编辑", icon: , onClick: (item: Dataset) => { - console.log(item); setCurrentDataset(item); setEditDatasetOpen(true); }, }, + { + key: "import", + label: "导入", + icon: , + onClick: (item: Dataset) => { + handleImportData(item); + }, + }, { key: "download", label: "下载", @@ -158,6 +181,14 @@ export default function DatasetManagementPage() { { key: "delete", label: "删除", + danger: true, + confirm: { + title: "确认删除该数据集?", + description: "删除后该数据集将无法恢复,请谨慎操作。", + okText: "删除", + cancelText: "取消", + okType: "danger", + }, icon: , onClick: (item: Dataset) => handleDeleteDataset(item.id), }, @@ -291,7 +322,7 @@ export default function DatasetManagementPage() { {/* Header */}

数据管理

-
+
{/* tasks */} {viewMode === "card" ? renderCardView() : renderListView()} setEditDatasetOpen(false)} - onRefresh={fetchData} + onClose={() => { + setCurrentDataset(null); + setEditDatasetOpen(false); + }} + onRefresh={handleRefresh} + /> + { + setCurrentDataset(null); + setShowUploadDialog(false); + }} + onRefresh={handleRefresh} />
); diff --git a/frontend/src/pages/DataManagement/dataset.api.ts b/frontend/src/pages/DataManagement/dataset.api.ts index c800b82..e2cb656 100644 --- a/frontend/src/pages/DataManagement/dataset.api.ts +++ b/frontend/src/pages/DataManagement/dataset.api.ts @@ -1,4 +1,4 @@ -import { get, post, put, del, download, upload } from "@/utils/request"; +import { get, post, put, del, download } from "@/utils/request"; // 数据集统计接口 export function getDatasetStatisticsUsingGet() { @@ -35,15 +35,8 @@ export function deleteDatasetByIdUsingDelete(id: string | number) { } // 下载数据集 -export function downloadDatasetUsingGet( - id: string | number, - filename?: string -) { - return download( - `/api/data-management/datasets/${id}/download`, - null, - filename - ); +export function downloadDatasetUsingGet(id: string | number) { + return download(`/api/data-management/datasets/${id}/files/download`); } // 验证数据集 @@ -61,15 +54,15 @@ export function uploadDatasetFileUsingPost(id: string | number, data: any) { return post(`/api/data-management/datasets/${id}/files`, data); } -export function downloadFile( +export function downloadFileByIdUsingGet( id: string | number, fileId: string | number, - filename?: string + fileName: string ) { return download( - `/api/data-management/datasets/${id}/files/download`, + `/api/data-management/datasets/${id}/files/${fileId}/download`, null, - filename + fileName ); } diff --git a/frontend/src/pages/DataManagement/dataset.const.tsx b/frontend/src/pages/DataManagement/dataset.const.tsx index ecee1cc..8950506 100644 --- a/frontend/src/pages/DataManagement/dataset.const.tsx +++ b/frontend/src/pages/DataManagement/dataset.const.tsx @@ -12,6 +12,7 @@ import { CloseCircleOutlined, FileOutlined, } from "@ant-design/icons"; +import { AnyObject } from "antd/es/_util/type"; import { FileImage, FileText, @@ -186,7 +187,7 @@ export const datasetStatusMap = { export const dataSourceMap: Record = { [DataSource.UPLOAD]: { label: "本地上传", value: DataSource.UPLOAD }, - [DataSource.COLLECTION]: { label: "本地归集 ", value: DataSource.COLLECTION }, + // [DataSource.COLLECTION]: { label: "本地归集 ", value: DataSource.COLLECTION }, // [DataSource.DATABASE]: { label: "数据库导入", value: DataSource.DATABASE }, // [DataSource.NAS]: { label: "NAS导入", value: DataSource.NAS }, // [DataSource.OBS]: { label: "OBS导入", value: DataSource.OBS }, @@ -194,7 +195,7 @@ export const dataSourceMap: Record = { export const dataSourceOptions = Object.values(dataSourceMap); -export function mapDataset(dataset: Dataset) { +export function mapDataset(dataset: AnyObject): Dataset { const { icon: IconComponent, iconColor } = datasetTypeMap[dataset?.datasetType] || {}; return { diff --git a/frontend/src/pages/DataManagement/hooks/index.ts b/frontend/src/pages/DataManagement/hooks/index.ts deleted file mode 100644 index dda61af..0000000 --- a/frontend/src/pages/DataManagement/hooks/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { useFilesOperation } from "./useFilesOperation"; -export { useImportFile } from "./useImportFile"; \ No newline at end of file diff --git a/frontend/src/pages/DataManagement/hooks/useImportFile.tsx b/frontend/src/pages/DataManagement/hooks/useImportFile.tsx deleted file mode 100644 index 8b8b7b9..0000000 --- a/frontend/src/pages/DataManagement/hooks/useImportFile.tsx +++ /dev/null @@ -1,61 +0,0 @@ -import { Upload, type UploadFile } from "antd"; -import { InboxOutlined } from "@ant-design/icons"; -import { useMemo, useState } from "react"; -import type { Dataset } from "@/pages/DataManagement/dataset.model"; -import { sliceFile } from "@/utils/file.util"; - -const { Dragger } = Upload; - -export const useImportFile = () => { - const [fileList, setFileList] = useState([]); - const fileSliceList = useMemo(() => { - const sliceList = fileList.map((file) => { - const slices = sliceFile(file); - return { originFile: file, slices, name: file.name, size: file.size }; - }); - return sliceList; - }, [fileList]); - - const resetFiles = () => { - setFileList([]); - }; - - const handleUpload = async (dataset: Dataset) => { - const formData = new FormData(); - fileList.forEach((file) => { - formData.append("file", file); - }); - window.dispatchEvent( - new CustomEvent("upload:dataset", { - detail: { dataset, files: fileSliceList }, - }) - ); - resetFiles(); - }; - - const handleBeforeUpload = (_, files: UploadFile[]) => { - setFileList([...fileList, ...files]); - return false; - }; - - const handleRemoveFile = (file: UploadFile) => { - setFileList((prev) => prev.filter((f) => f.uid !== file.uid)); - }; - - const importFileRender = () => ( - -

- -

-

本地文件上传

-

拖拽文件到此处或点击选择文件

-
- ); - - return { fileList, resetFiles, handleUpload, importFileRender }; -}; diff --git a/frontend/src/pages/Layout/Sidebar.tsx b/frontend/src/pages/Layout/Sidebar.tsx index a63a6ed..f881d80 100644 --- a/frontend/src/pages/Layout/Sidebar.tsx +++ b/frontend/src/pages/Layout/Sidebar.tsx @@ -71,7 +71,7 @@ const AsiderAndHeaderLayout = () => {
- ModelEngine + DataMate )} { + if (seconds < 0) return "--"; if (seconds < 60) { return `${seconds} 秒`; } else if (seconds < 3600) {