You've already forked DataMate
feat(annotation): 支持音频和视频数据类型的标注任务
- 添加了音频和视频数据类型常量定义 - 实现了音频和视频标注模板的内置配置 - 扩展前端组件以支持按数据类型过滤标注模板 - 重构后端编辑器服务以处理音频和视频任务构建 - 更新数据库初始化脚本包含音频和视频标注模板 - 添加音频和视频数据类型的预览URL映射逻辑
This commit is contained in:
@@ -13,7 +13,7 @@ import {
|
||||
queryAnnotationTemplatesUsingGet,
|
||||
} from "../../annotation.api";
|
||||
import { DatasetType, type Dataset } from "@/pages/DataManagement/dataset.model";
|
||||
import type { AnnotationTemplate, AnnotationTask } from "../../annotation.model";
|
||||
import { DataType, type AnnotationTemplate, type AnnotationTask } from "../../annotation.model";
|
||||
import LabelStudioEmbed from "@/components/business/LabelStudioEmbed";
|
||||
import TemplateConfigurationTreeEditor from "../../components/TemplateConfigurationTreeEditor";
|
||||
import { useTagConfig } from "@/hooks/useTagConfig";
|
||||
@@ -57,6 +57,22 @@ const SEGMENTATION_OPTIONS = [
|
||||
{ label: "需要切片段", value: true },
|
||||
{ label: "不需要切片段", value: false },
|
||||
];
|
||||
const resolveTemplateDataType = (datasetType?: DatasetType) => {
|
||||
switch (datasetType) {
|
||||
case DatasetType.TEXT:
|
||||
return DataType.TEXT;
|
||||
case DatasetType.IMAGE:
|
||||
return DataType.IMAGE;
|
||||
case DatasetType.AUDIO:
|
||||
return DataType.AUDIO;
|
||||
case DatasetType.VIDEO:
|
||||
return DataType.VIDEO;
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
const resolveDefaultTemplate = (items: AnnotationTemplate[]) =>
|
||||
items.find((template) => template.builtIn) || items[0];
|
||||
|
||||
export default function CreateAnnotationTask({
|
||||
open,
|
||||
@@ -112,19 +128,6 @@ export default function CreateAnnotationTask({
|
||||
});
|
||||
setDatasets(datasetData.content.map(mapDataset) || []);
|
||||
|
||||
// Fetch templates
|
||||
const templateResponse = await queryAnnotationTemplatesUsingGet({
|
||||
page: 1,
|
||||
size: 100,
|
||||
});
|
||||
|
||||
if (templateResponse.code === 200 && templateResponse.data) {
|
||||
const fetchedTemplates = templateResponse.data.content || [];
|
||||
setTemplates(fetchedTemplates);
|
||||
} else {
|
||||
console.error("Failed to fetch templates:", templateResponse);
|
||||
setTemplates([]);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error fetching data:", error);
|
||||
setTemplates([]);
|
||||
@@ -133,6 +136,66 @@ export default function CreateAnnotationTask({
|
||||
fetchData();
|
||||
}, [open]);
|
||||
|
||||
const fetchTemplates = async (dataType?: string) => {
|
||||
if (!dataType) {
|
||||
setTemplates([]);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const templateResponse = await queryAnnotationTemplatesUsingGet({
|
||||
page: 1,
|
||||
size: 200,
|
||||
dataType,
|
||||
});
|
||||
|
||||
if (templateResponse.code === 200 && templateResponse.data) {
|
||||
const fetchedTemplates = templateResponse.data.content || [];
|
||||
setTemplates(fetchedTemplates);
|
||||
} else {
|
||||
console.error("Failed to fetch templates:", templateResponse);
|
||||
setTemplates([]);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error fetching templates:", error);
|
||||
setTemplates([]);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!open || isEditMode) {
|
||||
return;
|
||||
}
|
||||
if (!selectedDataset) {
|
||||
setTemplates([]);
|
||||
manualForm.setFieldsValue({ templateId: undefined });
|
||||
setLabelConfig("");
|
||||
return;
|
||||
}
|
||||
const dataType = resolveTemplateDataType(selectedDataset.datasetType);
|
||||
fetchTemplates(dataType);
|
||||
}, [isEditMode, manualForm, open, selectedDataset]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!open || isEditMode || configMode !== "template" || !selectedDataset) {
|
||||
return;
|
||||
}
|
||||
if (templates.length === 0) {
|
||||
manualForm.setFieldsValue({ templateId: undefined });
|
||||
setLabelConfig("");
|
||||
return;
|
||||
}
|
||||
const currentTemplateId = manualForm.getFieldValue("templateId");
|
||||
const currentTemplate = templates.find((template) => template.id === currentTemplateId);
|
||||
if (currentTemplate) {
|
||||
return;
|
||||
}
|
||||
const defaultTemplate = resolveDefaultTemplate(templates);
|
||||
if (defaultTemplate) {
|
||||
manualForm.setFieldsValue({ templateId: defaultTemplate.id });
|
||||
setLabelConfig(defaultTemplate.labelConfig || "");
|
||||
}
|
||||
}, [configMode, isEditMode, manualForm, open, selectedDataset, templates]);
|
||||
|
||||
// Reset form and manual-edit flag when modal opens, or load task data in edit mode
|
||||
useEffect(() => {
|
||||
if (open) {
|
||||
@@ -587,6 +650,10 @@ export default function CreateAnnotationTask({
|
||||
})}
|
||||
onChange={(value) => {
|
||||
setSelectedDatasetId(value);
|
||||
if (!isEditMode) {
|
||||
manualForm.setFieldsValue({ templateId: undefined });
|
||||
setLabelConfig("");
|
||||
}
|
||||
const dataset = datasets.find((item) => item.id === value);
|
||||
if (dataset?.datasetType === DatasetType.TEXT) {
|
||||
const currentValue = manualForm.getFieldValue("segmentationEnabled");
|
||||
|
||||
Reference in New Issue
Block a user