You've already forked DataMate
refactor(dataset): 优化数据集路径管理和关联关系处理
- 移除Dataset类中initCreateParam方法的parentPath参数 - 简化handleParentChange方法中的路径构建逻辑 - 更新错误消息将"子数据集"改为"关联数据集" - 修改前端界面将"父数据集"相关术语统一为"关联数据集" - 在导入配置组件中添加类型定义和改进文件处理逻辑 - 限制数据源选项排除COLLECTION类型避免错误选择
This commit is contained in:
@@ -73,7 +73,7 @@ public class DatasetApplicationService {
|
||||
Dataset dataset = DatasetConverter.INSTANCE.convertToDataset(createDatasetRequest);
|
||||
Dataset parentDataset = resolveParentDataset(createDatasetRequest.getParentDatasetId(), dataset.getId());
|
||||
dataset.setParentDatasetId(parentDataset == null ? null : parentDataset.getId());
|
||||
dataset.initCreateParam(datasetBasePath, parentDataset == null ? null : parentDataset.getPath());
|
||||
dataset.initCreateParam(datasetBasePath);
|
||||
// 处理标签
|
||||
Set<Tag> processedTags = Optional.ofNullable(createDatasetRequest.getTags())
|
||||
.filter(CollectionUtils::isNotEmpty)
|
||||
@@ -291,7 +291,9 @@ public class DatasetApplicationService {
|
||||
|
||||
private void handleParentChange(Dataset dataset, String parentDatasetId) {
|
||||
String normalized = normalizeParentId(parentDatasetId);
|
||||
if (Objects.equals(dataset.getParentDatasetId(), normalized)) {
|
||||
String expectedPath = buildDatasetPath(datasetBasePath, dataset.getId());
|
||||
if (Objects.equals(dataset.getParentDatasetId(), normalized)
|
||||
&& Objects.equals(dataset.getPath(), expectedPath)) {
|
||||
return;
|
||||
}
|
||||
long childCount = datasetRepository.countByParentId(dataset.getId());
|
||||
@@ -299,8 +301,7 @@ public class DatasetApplicationService {
|
||||
throw BusinessException.of(DataManagementErrorCode.DATASET_HAS_CHILDREN);
|
||||
}
|
||||
Dataset parent = normalized == null ? null : resolveParentDataset(normalized, dataset.getId());
|
||||
String newPath = buildDatasetPath(parent == null ? datasetBasePath : parent.getPath(), dataset.getId());
|
||||
moveDatasetPath(dataset, newPath);
|
||||
moveDatasetPath(dataset, expectedPath);
|
||||
dataset.setParentDatasetId(parent == null ? null : parent.getId());
|
||||
}
|
||||
|
||||
|
||||
@@ -114,9 +114,9 @@ public class Dataset extends BaseEntity<String> {
|
||||
this.updatedAt = LocalDateTime.now();
|
||||
}
|
||||
|
||||
public void initCreateParam(String datasetBasePath, String parentPath) {
|
||||
public void initCreateParam(String datasetBasePath) {
|
||||
this.id = UUID.randomUUID().toString();
|
||||
String basePath = normalizeBasePath(parentPath != null && !parentPath.isBlank() ? parentPath : datasetBasePath);
|
||||
String basePath = normalizeBasePath(datasetBasePath);
|
||||
this.path = basePath + File.separator + this.id;
|
||||
if (this.status == null) {
|
||||
this.status = DatasetStatusType.DRAFT;
|
||||
|
||||
@@ -42,9 +42,9 @@ public enum DataManagementErrorCode implements ErrorCode {
|
||||
*/
|
||||
DIRECTORY_NOT_FOUND("data_management.0007", "目录不存在"),
|
||||
/**
|
||||
* 存在子数据集
|
||||
* 存在关联数据集
|
||||
*/
|
||||
DATASET_HAS_CHILDREN("data_management.0008", "存在子数据集,禁止删除或移动"),
|
||||
DATASET_HAS_CHILDREN("data_management.0008", "存在关联数据集,禁止删除或移动"),
|
||||
/**
|
||||
* 数据集文件不存在
|
||||
*/
|
||||
|
||||
@@ -96,7 +96,7 @@ export default function EditDataset({
|
||||
<BasicInformation
|
||||
data={newDataset}
|
||||
setData={setNewDataset}
|
||||
hidden={["datasetType"]}
|
||||
hidden={["datasetType", "dataSource"]}
|
||||
/>
|
||||
</Form>
|
||||
</Modal>
|
||||
|
||||
@@ -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>
|
||||
)}
|
||||
|
||||
@@ -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>
|
||||
)}
|
||||
|
||||
@@ -14,8 +14,8 @@ import Dragger from "antd/es/upload/Dragger";
|
||||
* @returns 分割后的文件列表,每行一个文件
|
||||
*/
|
||||
async function splitFileByLines(file: UploadFile): Promise<UploadFile[]> {
|
||||
const originFile = (file as any).originFileObj || file;
|
||||
if (!originFile || typeof originFile.text !== "function") {
|
||||
const originFile = file.originFileObj ?? file;
|
||||
if (!(originFile instanceof File) || typeof originFile.text !== "function") {
|
||||
return [file];
|
||||
}
|
||||
|
||||
@@ -41,11 +41,31 @@ async function splitFileByLines(file: UploadFile): Promise<UploadFile[]> {
|
||||
name: newFileName,
|
||||
size: newFile.size,
|
||||
type: "text/plain",
|
||||
originFileObj: newFile as any,
|
||||
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,
|
||||
@@ -60,8 +80,11 @@ export default function ImportConfiguration({
|
||||
prefix?: string;
|
||||
}) {
|
||||
const [form] = Form.useForm();
|
||||
const [collectionOptions, setCollectionOptions] = useState([]);
|
||||
const [importConfig, setImportConfig] = useState<any>({
|
||||
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,
|
||||
@@ -71,7 +94,8 @@ export default function ImportConfiguration({
|
||||
// 本地上传文件相关逻辑
|
||||
|
||||
const handleUpload = async (dataset: Dataset) => {
|
||||
let filesToUpload = form.getFieldValue("files") || [];
|
||||
let filesToUpload =
|
||||
(form.getFieldValue("files") as UploadFile[] | undefined) || [];
|
||||
|
||||
// 如果启用分行分割,处理文件
|
||||
if (importConfig.splitByLine) {
|
||||
@@ -83,7 +107,7 @@ export default function ImportConfiguration({
|
||||
|
||||
// 计算分片列表
|
||||
const sliceList = filesToUpload.map((file) => {
|
||||
const originFile = (file as any).originFileObj || file;
|
||||
const originFile = (file.originFileObj ?? file) as Blob;
|
||||
const slices = sliceFile(originFile);
|
||||
return {
|
||||
originFile: originFile, // 传入真正的 File/Blob 对象
|
||||
@@ -111,7 +135,10 @@ 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) => ({
|
||||
const tasks = Array.isArray(res?.data?.content)
|
||||
? (res.data.content as CollectionTask[])
|
||||
: [];
|
||||
const options = tasks.map((task) => ({
|
||||
label: task.name,
|
||||
value: task.id,
|
||||
}));
|
||||
@@ -126,7 +153,7 @@ export default function ImportConfiguration({
|
||||
form.resetFields();
|
||||
form.setFieldsValue({ files: null });
|
||||
setImportConfig({
|
||||
source: importConfig.source ? importConfig.source : DataSource.UPLOAD,
|
||||
source: DataSource.UPLOAD,
|
||||
hasArchive: true,
|
||||
splitByLine: false,
|
||||
});
|
||||
@@ -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,11 +304,13 @@ export default function ImportConfiguration({
|
||||
label="上传文件"
|
||||
name="files"
|
||||
valuePropName="fileList"
|
||||
getValueFromEvent={(e: any) => {
|
||||
if (Array.isArray(e)) {
|
||||
return e;
|
||||
getValueFromEvent={(
|
||||
event: { fileList?: UploadFile[] } | UploadFile[]
|
||||
) => {
|
||||
if (Array.isArray(event)) {
|
||||
return event;
|
||||
}
|
||||
return e && e.fileList;
|
||||
return event?.fileList;
|
||||
}}
|
||||
rules={[
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user