refactor(dataset): 优化数据集路径管理和关联关系处理

- 移除Dataset类中initCreateParam方法的parentPath参数
- 简化handleParentChange方法中的路径构建逻辑
- 更新错误消息将"子数据集"改为"关联数据集"
- 修改前端界面将"父数据集"相关术语统一为"关联数据集"
- 在导入配置组件中添加类型定义和改进文件处理逻辑
- 限制数据源选项排除COLLECTION类型避免错误选择
This commit is contained in:
2026-01-30 16:48:39 +08:00
parent accaa47a83
commit bd37858ccc
7 changed files with 101 additions and 71 deletions

View File

@@ -96,7 +96,7 @@ export default function EditDataset({
<BasicInformation
data={newDataset}
setData={setNewDataset}
hidden={["datasetType"]}
hidden={["datasetType", "dataSource"]}
/>
</Form>
</Modal>

View File

@@ -74,7 +74,7 @@ export default function BasicInformation({
value: dataset.id,
}));
setParentDatasetOptions([
{ label: "数据集", value: "" },
{ label: "无关联数据集", value: "" },
...options,
]);
} catch (error) {
@@ -102,11 +102,11 @@ export default function BasicInformation({
</Form.Item>
)}
{!hidden.includes("parentDatasetId") && (
<Form.Item name="parentDatasetId" label="数据集">
<Form.Item name="parentDatasetId" label="关联数据集">
<Select
className="w-full"
options={parentDatasetOptions}
placeholder="选择数据集(仅支持一层)"
placeholder="选择关联数据集(仅支持一层)"
/>
</Form.Item>
)}

View File

@@ -127,7 +127,7 @@ export default function DatasetDetail() {
if (!dataset?.parentDatasetId) {
items.push({
key: "children",
label: "数据集",
label: "关联数据集",
});
}
return items;
@@ -266,7 +266,7 @@ export default function DatasetDetail() {
? [
{
key: "create-child",
label: "创建数据集",
label: "创建关联数据集",
icon: <PlusOutlined />,
onClick: handleCreateChildDataset,
},
@@ -415,7 +415,7 @@ export default function DatasetDetail() {
{activeTab === "children" && (
<div className="pt-4">
<div className="flex items-center justify-between mb-3">
<h2 className="text-base font-semibold"></h2>
<h2 className="text-base font-semibold"></h2>
<span className="text-xs text-gray-500">
{childDatasets.length}
</span>
@@ -426,7 +426,7 @@ export default function DatasetDetail() {
dataSource={childDatasets}
loading={childDatasetsLoading}
pagination={false}
locale={{ emptyText: "暂无数据集" }}
locale={{ emptyText: "暂无关联数据集" }}
/>
</div>
)}

View File

@@ -13,11 +13,11 @@ import Dragger from "antd/es/upload/Dragger";
* @param file 原始文件
* @returns 分割后的文件列表,每行一个文件
*/
async function splitFileByLines(file: UploadFile): Promise<UploadFile[]> {
const originFile = (file as any).originFileObj || file;
if (!originFile || typeof originFile.text !== "function") {
return [file];
}
async function splitFileByLines(file: UploadFile): Promise<UploadFile[]> {
const originFile = file.originFileObj ?? file;
if (!(originFile instanceof File) || typeof originFile.text !== "function") {
return [file];
}
const text = await originFile.text();
if (!text) return [file];
@@ -36,17 +36,37 @@ async function splitFileByLines(file: UploadFile): Promise<UploadFile[]> {
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({
return {
uid: `${file.uid}-${index}`,
name: newFileName,
size: newFile.size,
type: "text/plain",
originFileObj: newFile as UploadFile["originFileObj"],
} as UploadFile;
});
}
type SelectOption = {
label: string;
value: string;
};
type CollectionTask = {
id: string;
name: string;
};
type ImportConfig = {
source: DataSource;
hasArchive: boolean;
splitByLine: boolean;
files?: UploadFile[];
dataSource?: string;
target?: DataSource;
[key: string]: unknown;
};
export default function ImportConfiguration({
data,
open,
onClose,
@@ -59,19 +79,23 @@ export default function ImportConfiguration({
updateEvent?: string;
prefix?: string;
}) {
const [form] = Form.useForm();
const [collectionOptions, setCollectionOptions] = useState([]);
const [importConfig, setImportConfig] = useState<any>({
source: DataSource.UPLOAD,
hasArchive: true,
splitByLine: false,
});
const [form] = Form.useForm();
const [collectionOptions, setCollectionOptions] = useState<SelectOption[]>([]);
const availableSourceOptions = dataSourceOptions.filter(
(option) => option.value !== DataSource.COLLECTION
);
const [importConfig, setImportConfig] = useState<ImportConfig>({
source: DataSource.UPLOAD,
hasArchive: true,
splitByLine: false,
});
const [currentPrefix, setCurrentPrefix] = useState<string>("");
// 本地上传文件相关逻辑
const handleUpload = async (dataset: Dataset) => {
let filesToUpload = form.getFieldValue("files") || [];
let filesToUpload =
(form.getFieldValue("files") as UploadFile[] | undefined) || [];
// 如果启用分行分割,处理文件
if (importConfig.splitByLine) {
@@ -83,14 +107,14 @@ export default function ImportConfiguration({
// 计算分片列表
const sliceList = filesToUpload.map((file) => {
const originFile = (file as any).originFileObj || file;
const slices = sliceFile(originFile);
return {
originFile: originFile, // 传入真正的 File/Blob 对象
slices,
name: file.name,
size: originFile.size || 0,
};
const originFile = (file.originFileObj ?? file) as Blob;
const slices = sliceFile(originFile);
return {
originFile: originFile, // 传入真正的 File/Blob 对象
slices,
name: file.name,
size: originFile.size || 0,
};
});
console.log("[ImportConfiguration] Uploading with currentPrefix:", currentPrefix);
@@ -111,10 +135,13 @@ export default function ImportConfiguration({
if (importConfig.source !== DataSource.COLLECTION) return;
try {
const res = await queryTasksUsingGet({ page: 0, size: 100 });
const options = res.data.content.map((task: any) => ({
label: task.name,
value: task.id,
}));
const tasks = Array.isArray(res?.data?.content)
? (res.data.content as CollectionTask[])
: [];
const options = tasks.map((task) => ({
label: task.name,
value: task.id,
}));
setCollectionOptions(options);
} catch (error) {
console.error("Error fetching collection tasks:", error);
@@ -123,13 +150,13 @@ export default function ImportConfiguration({
const resetState = () => {
console.log('[ImportConfiguration] resetState called, preserving currentPrefix:', currentPrefix);
form.resetFields();
form.setFieldsValue({ files: null });
setImportConfig({
source: importConfig.source ? importConfig.source : DataSource.UPLOAD,
hasArchive: true,
splitByLine: false,
});
form.resetFields();
form.setFieldsValue({ files: null });
setImportConfig({
source: DataSource.UPLOAD,
hasArchive: true,
splitByLine: false,
});
console.log('[ImportConfiguration] resetState done, currentPrefix still:', currentPrefix);
};
@@ -196,12 +223,12 @@ export default function ImportConfiguration({
name="source"
rules={[{ required: true, message: "请选择数据源" }]}
>
<Radio.Group
buttonStyle="solid"
options={dataSourceOptions}
optionType="button"
/>
</Form.Item>
<Radio.Group
buttonStyle="solid"
options={availableSourceOptions}
optionType="button"
/>
</Form.Item>
{importConfig?.source === DataSource.COLLECTION && (
<Form.Item name="dataSource" label="归集任务" required>
<Select placeholder="请选择归集任务" options={collectionOptions} />
@@ -277,12 +304,14 @@ export default function ImportConfiguration({
label="上传文件"
name="files"
valuePropName="fileList"
getValueFromEvent={(e: any) => {
if (Array.isArray(e)) {
return e;
}
return e && e.fileList;
}}
getValueFromEvent={(
event: { fileList?: UploadFile[] } | UploadFile[]
) => {
if (Array.isArray(event)) {
return event;
}
return event?.fileList;
}}
rules={[
{
required: true,