feat(template): 添加模板搜索功能和优化数据获取

- 添加 keyword 参数支持模板名称和描述模糊搜索
- 在 useFetchData hook 中添加 filterParamMapper 参数用于过滤参数映射
- 为模板列表页面实现内置标志过滤器映射功能
- 优化模板配置更新逻辑,改进数据验证和转换流程
- 完善模板服务中的条件查询,支持多字段模糊匹配
- 更新数据获取 hook 的依赖数组以正确处理轮询逻辑
This commit is contained in:
2026-01-22 21:25:04 +08:00
parent d22d677efe
commit ccb581d501
4 changed files with 305 additions and 245 deletions

View File

@@ -67,6 +67,7 @@ async def get_template(
async def list_template(
page: int = Query(1, ge=1, description="页码"),
size: int = Query(10, ge=1, le=100, description="每页大小"),
keyword: Optional[str] = Query(None, description="关键词"),
category: Optional[str] = Query(None, description="分类筛选"),
dataType: Optional[str] = Query(None, alias="dataType", description="数据类型筛选"),
labelingType: Optional[str] = Query(None, alias="labelingType", description="标注类型筛选"),
@@ -78,6 +79,7 @@ async def list_template(
- **page**: 页码(从1开始)
- **size**: 每页大小(1-100)
- **keyword**: 关键词(匹配名称/描述)
- **category**: 模板分类筛选
- **dataType**: 数据类型筛选
- **labelingType**: 标注类型筛选
@@ -90,7 +92,8 @@ async def list_template(
category=category,
data_type=dataType,
labeling_type=labelingType,
built_in=builtIn
built_in=builtIn,
keyword=keyword
)
return StandardResponse(code=200, message="success", data=templates)

View File

@@ -3,7 +3,7 @@ Annotation Template Service
"""
from typing import Optional, List
from datetime import datetime
from sqlalchemy import select, func
from sqlalchemy import select, func, or_
from sqlalchemy.ext.asyncio import AsyncSession
from uuid import uuid4
from fastapi import HTTPException
@@ -185,7 +185,8 @@ class AnnotationTemplateService:
category: Optional[str] = None,
data_type: Optional[str] = None,
labeling_type: Optional[str] = None,
built_in: Optional[bool] = None
built_in: Optional[bool] = None,
keyword: Optional[str] = None
) -> AnnotationTemplateListResponse:
"""
获取模板列表
@@ -213,6 +214,14 @@ class AnnotationTemplateService:
conditions.append(AnnotationTemplate.labeling_type == labeling_type) # type: ignore
if built_in is not None:
conditions.append(AnnotationTemplate.built_in == built_in) # type: ignore
if keyword:
like_keyword = f"%{keyword}%"
conditions.append(
or_(
AnnotationTemplate.name.ilike(like_keyword), # type: ignore
AnnotationTemplate.description.ilike(like_keyword) # type: ignore
)
)
# 查询总数
count_result = await db.execute(
@@ -273,13 +282,14 @@ class AnnotationTemplateService:
for field, value in update_data.items():
if field == 'configuration' and value is not None:
# 验证配置JSON
config_dict = value.model_dump(mode='json', by_alias=False)
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 not valid:
raise HTTPException(status_code=400, detail=f"Invalid configuration: {error}")
# 重新生成Label Studio XML配置(用于验证)
label_config = self.generate_label_studio_config(value)
label_config = self.generate_label_studio_config(config)
# 验证生成的XML
valid, error = LabelStudioConfigValidator.validate_xml(label_config)