feat(annotation): 替换模板配置表单为树形编辑器组件

- 移除 TemplateConfigurationForm 组件并引入 TemplateConfigurationTreeEditor
- 使用 useTagConfig Hook 获取标签配置
- 将自定义XML状态 customXml 替换为 labelConfig
- 删除模板编辑标签页和选择模板状态管理
- 更新XML解析逻辑支持更多对象和标注控件类型
- 添加配置验证功能确保至少包含数据对象和标注控件
- 在模板详情页面使用树形编辑器显示配置详情
- 更新任务创建页面集成新的树形配置编辑器
- 调整预览数据生成功能适配新的XML解析方式
This commit is contained in:
2026-01-23 16:11:59 +08:00
parent 76d06b9809
commit 3f566a0b08
14 changed files with 1383 additions and 900 deletions

View File

@@ -114,28 +114,20 @@ class AnnotationTemplateService:
Returns:
创建的模板响应
"""
# 验证配置JSON
config_dict = request.configuration.model_dump(mode='json', by_alias=False)
valid, error = LabelStudioConfigValidator.validate_configuration_json(config_dict)
if not valid:
raise HTTPException(status_code=400, detail=f"Invalid configuration: {error}")
# 生成Label Studio XML配置(用于验证,但不存储)
label_config = self.generate_label_studio_config(request.configuration)
# 验证生成的XML
label_config = request.label_config
valid, error = LabelStudioConfigValidator.validate_xml(label_config)
if not valid:
raise HTTPException(status_code=400, detail=f"Generated XML is invalid: {error}")
# 创建模板对象(不包含label_config字段)
raise HTTPException(status_code=400, detail=f"Invalid labelConfig: {error}")
# 创建模板对象
template = AnnotationTemplate(
id=str(uuid4()),
name=request.name,
description=request.description,
data_type=request.data_type,
labeling_type=request.labeling_type,
configuration=config_dict,
configuration=None,
label_config=label_config,
style=request.style,
category=request.category,
built_in=False,
@@ -280,24 +272,11 @@ class AnnotationTemplateService:
update_data = request.model_dump(exclude_unset=True, by_alias=False)
for field, value in update_data.items():
if field == 'configuration' and value is not None:
# 验证配置JSON
config = value if isinstance(value, TemplateConfiguration) else TemplateConfiguration.model_validate(value)
config_dict = config.model_dump(mode='json', by_alias=False)
valid, error = LabelStudioConfigValidator.validate_configuration_json(config_dict)
if field == "label_config" and value is not None:
valid, error = LabelStudioConfigValidator.validate_xml(value)
if not valid:
raise HTTPException(status_code=400, detail=f"Invalid configuration: {error}")
# 重新生成Label Studio XML配置(用于验证)
label_config = self.generate_label_studio_config(config)
# 验证生成的XML
valid, error = LabelStudioConfigValidator.validate_xml(label_config)
if not valid:
raise HTTPException(status_code=400, detail=f"Generated XML is invalid: {error}")
# 只更新configuration字段,不存储label_config
setattr(template, field, config_dict)
raise HTTPException(status_code=400, detail=f"Invalid labelConfig: {error}")
setattr(template, field, value)
else:
setattr(template, field, value)
@@ -350,20 +329,17 @@ class AnnotationTemplateService:
Returns:
模板响应对象
"""
# 将配置JSON转换为TemplateConfiguration对象
from typing import cast, Dict, Any
config_dict = cast(Dict[str, Any], template.configuration)
config = TemplateConfiguration(**config_dict)
config = None
if template.configuration:
try:
from typing import cast, Dict, Any
config_dict = cast(Dict[str, Any], template.configuration)
config = TemplateConfiguration(**config_dict)
except Exception:
config = None
# 优先使用预定义的 label_config,否则动态生成
if template.label_config:
label_config = template.label_config
else:
label_config = self.generate_label_studio_config(config)
# 使用model_validate从ORM对象创建响应对象
response = AnnotationTemplateResponse.model_validate(template)
response.configuration = config
response.label_config = label_config # type: ignore
response.label_config = template.label_config # type: ignore
return response