feat(annotation): 添加 labelConfig 字段并优化配置解析逻辑

- 在 DatasetMappingResponse 模型中新增 label_config 字段
- 修改前端获取 labelConfig 的逻辑,优先使用任务自身配置
- 移除模板配置的 condition 分支,统一从 XML 解析配置
- 更新后端服务从 configuration JSON 字段中提取 label_config 和 description
- 优化前后端配置解析的一致性处理
This commit is contained in:
2026-01-19 21:39:00 +08:00
parent 85b8513b43
commit f4a86b4af1
3 changed files with 33 additions and 31 deletions

View File

@@ -121,24 +121,13 @@ export default function CreateAnnotationTask({
}); });
setSelectedDatasetId(taskDetail.datasetId); setSelectedDatasetId(taskDetail.datasetId);
// 配置可能在 template.configuration 或 taskDetail.configuration // 获取实际的 labelConfig(优先使用任务自身的配置,回退到模板配置)
const configuration = taskDetail.template?.configuration || taskDetail.configuration; const labelConfig = taskDetail.labelConfig || taskDetail.template?.labelConfig;
const labelConfig = taskDetail.template?.labelConfig || taskDetail.labelConfig;
// 设置 XML 配置用于预览 // 设置 XML 配置用于预览
if (labelConfig) { if (labelConfig) {
setCustomXml(labelConfig); setCustomXml(labelConfig);
} // 始终从 XML 解析配置,确保数据一致性
// 填充模板配置:优先使用 configuration,否则从 labelConfig 解析
if (configuration && configuration.objects?.length > 0) {
const { objects, labels } = configuration;
manualForm.setFieldsValue({
objects: objects || [],
labels: labels || [],
});
} else if (labelConfig) {
// 从 XML 解析配置
const parsed = parseXmlToConfig(labelConfig); const parsed = parseXmlToConfig(labelConfig);
manualForm.setFieldsValue({ manualForm.setFieldsValue({
objects: parsed.objects, objects: parsed.objects,

View File

@@ -48,6 +48,7 @@ class DatasetMappingResponse(BaseModel):
description: Optional[str] = Field(None, description="标注项目描述") description: Optional[str] = Field(None, description="标注项目描述")
template_id: Optional[str] = Field(None, alias="templateId", description="关联的模板ID") template_id: Optional[str] = Field(None, alias="templateId", description="关联的模板ID")
template: Optional['AnnotationTemplateResponse'] = Field(None, description="关联的标注模板详情") template: Optional['AnnotationTemplateResponse'] = Field(None, description="关联的标注模板详情")
label_config: Optional[str] = Field(None, alias="labelConfig", description="实际使用的 Label Studio XML 配置")
created_at: datetime = Field(..., alias="createdAt", description="创建时间") created_at: datetime = Field(..., alias="createdAt", description="创建时间")
updated_at: Optional[datetime] = Field(None, alias="updatedAt", description="更新时间") updated_at: Optional[datetime] = Field(None, alias="updatedAt", description="更新时间")
deleted_at: Optional[datetime] = Field(None, alias="deletedAt", description="删除时间") deleted_at: Optional[datetime] = Field(None, alias="deletedAt", description="删除时间")

View File

@@ -52,6 +52,11 @@ class DatasetMappingService:
# Get template_id from mapping # Get template_id from mapping
template_id = getattr(mapping, 'template_id', None) template_id = getattr(mapping, 'template_id', None)
# 从 configuration JSON 字段中提取 label_config 和 description
configuration = getattr(mapping, 'configuration', None) or {}
label_config = configuration.get('label_config') if isinstance(configuration, dict) else None
description = configuration.get('description') if isinstance(configuration, dict) else None
# Optionally fetch full template details # Optionally fetch full template details
template_response = None template_response = None
if include_template and template_id: if include_template and template_id:
@@ -66,9 +71,10 @@ class DatasetMappingService:
"dataset_name": dataset_name, "dataset_name": dataset_name,
"labeling_project_id": mapping.labeling_project_id, "labeling_project_id": mapping.labeling_project_id,
"name": mapping.name, "name": mapping.name,
"description": getattr(mapping, 'description', None), "description": description,
"template_id": template_id, "template_id": template_id,
"template": template_response, "template": template_response,
"label_config": label_config,
"created_at": mapping.created_at, "created_at": mapping.created_at,
"updated_at": mapping.updated_at, "updated_at": mapping.updated_at,
"deleted_at": mapping.deleted_at, "deleted_at": mapping.deleted_at,
@@ -100,6 +106,11 @@ class DatasetMappingService:
# Get template_id from mapping # Get template_id from mapping
template_id = getattr(mapping, 'template_id', None) template_id = getattr(mapping, 'template_id', None)
# 从 configuration JSON 字段中提取 label_config 和 description
configuration = getattr(mapping, 'configuration', None) or {}
label_config = configuration.get('label_config') if isinstance(configuration, dict) else None
description = configuration.get('description') if isinstance(configuration, dict) else None
# Optionally fetch full template details # Optionally fetch full template details
template_response = None template_response = None
if include_template and template_id: if include_template and template_id:
@@ -115,9 +126,10 @@ class DatasetMappingService:
"dataset_name": dataset_name, "dataset_name": dataset_name,
"labeling_project_id": mapping.labeling_project_id, "labeling_project_id": mapping.labeling_project_id,
"name": mapping.name, "name": mapping.name,
"description": getattr(mapping, 'description', None), "description": description,
"template_id": template_id, "template_id": template_id,
"template": template_response, "template": template_response,
"label_config": label_config,
"created_at": mapping.created_at, "created_at": mapping.created_at,
"updated_at": mapping.updated_at, "updated_at": mapping.updated_at,
"deleted_at": mapping.deleted_at, "deleted_at": mapping.deleted_at,