From 879da760c79b8454991d77e2403152895ef2bb09 Mon Sep 17 00:00:00 2001 From: Jerry Yan <792602257@qq.com> Date: Mon, 19 Jan 2026 16:55:12 +0800 Subject: [PATCH] =?UTF-8?q?feat(DataManagement):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E6=8C=89=E8=A1=8C=E5=88=86=E5=89=B2=E6=96=87=E4=BB=B6=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 引入 Tooltip 和 QuestionCircleOutlined 组件用于提示信息 - 移除未使用的 useMemo 钩子和 fileSliceList 变量 - 新增 splitFileByLines 函数实现文件按行分割逻辑 - 在 handleUpload 函数中集成分行分割功能 - 添加 splitByLine 开关配置项到表单中 - 实现文本文件每行分割成独立文件的功能 - 优化文件上传处理流程以支持分割后的文件列表 --- .../Detail/components/ImportConfiguration.tsx | 94 ++++++++++++++++--- 1 file changed, 79 insertions(+), 15 deletions(-) diff --git a/frontend/src/pages/DataManagement/Detail/components/ImportConfiguration.tsx b/frontend/src/pages/DataManagement/Detail/components/ImportConfiguration.tsx index b18274b..aa6607b 100644 --- a/frontend/src/pages/DataManagement/Detail/components/ImportConfiguration.tsx +++ b/frontend/src/pages/DataManagement/Detail/components/ImportConfiguration.tsx @@ -1,13 +1,51 @@ -import { Select, Input, Form, Radio, Modal, Button, UploadFile, Switch } from "antd"; -import { InboxOutlined } from "@ant-design/icons"; +import { Select, Input, Form, Radio, Modal, Button, UploadFile, Switch, Tooltip } from "antd"; +import { InboxOutlined, QuestionCircleOutlined } from "@ant-design/icons"; import { dataSourceOptions } from "../../dataset.const"; import { Dataset, DataSource } from "../../dataset.model"; -import { useEffect, useMemo, useState } from "react"; +import { useEffect, useState } from "react"; import { queryTasksUsingGet } from "@/pages/DataCollection/collection.apis"; import { updateDatasetByIdUsingPut } from "../../dataset.api"; import { sliceFile } from "@/utils/file.util"; import Dragger from "antd/es/upload/Dragger"; +/** + * 按行分割文件 + * @param file 原始文件 + * @returns 分割后的文件列表,每行一个文件 + */ +async function splitFileByLines(file: UploadFile): Promise { + const originFile = (file as any).originFileObj || file; + if (!originFile || typeof originFile.text !== "function") { + return [file]; + } + + const text = await originFile.text(); + if (!text) return [file]; + + // 按行分割并过滤空行 + const lines = text.split(/\r?\n/).filter((line: string) => line.trim() !== ""); + if (lines.length === 0) return []; + + // 生成文件名:原文件名_序号.扩展名 + const nameParts = file.name.split("."); + const ext = nameParts.length > 1 ? "." + nameParts.pop() : ""; + const baseName = nameParts.join("."); + const padLength = String(lines.length).length; + + return lines.map((line: string, index: number) => { + const newFileName = `${baseName}_${String(index + 1).padStart(padLength, "0")}${ext}`; + const blob = new Blob([line], { type: "text/plain" }); + const newFile = new File([blob], newFileName, { type: "text/plain" }); + return { + uid: `${file.uid}-${index}`, + name: newFileName, + size: newFile.size, + type: "text/plain", + originFileObj: newFile as any, + } as UploadFile; + }); +} + export default function ImportConfiguration({ data, open, @@ -29,13 +67,6 @@ export default function ImportConfiguration({ const [currentPrefix, setCurrentPrefix] = useState(""); 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]); // 本地上传文件相关逻辑 @@ -44,16 +75,34 @@ export default function ImportConfiguration({ }; const handleUpload = async (dataset: Dataset) => { - const formData = new FormData(); - fileList.forEach((file) => { - formData.append("file", file); + let filesToUpload = fileList; + + // 如果启用分行分割,处理文件 + if (importConfig.splitByLine) { + const splitResults = await Promise.all( + fileList.map((file) => splitFileByLines(file)) + ); + filesToUpload = splitResults.flat(); + } + + // 计算分片列表 + const sliceList = filesToUpload.map((file) => { + const originFile = (file as any).originFileObj || file; + const slices = sliceFile(originFile); + return { + originFile: file, + slices, + name: file.name, + size: (file as any).size || originFile.size || 0, + }; }); - console.log('[ImportConfiguration] Uploading with currentPrefix:', currentPrefix); + + console.log("[ImportConfiguration] Uploading with currentPrefix:", currentPrefix); window.dispatchEvent( new CustomEvent("upload:dataset", { detail: { dataset, - files: fileSliceList, + files: sliceList, updateEvent, hasArchive: importConfig.hasArchive, prefix: currentPrefix, @@ -222,6 +271,21 @@ export default function ImportConfiguration({ > + + 按分行分割{" "} + + + + + } + name="splitByLine" + valuePropName="checked" + initialValue={false} + > + +