You've already forked DataMate
fix: 配比任务能够跳转到目标数据集 (#59)
* fix:配比任务需要能够跳转到目标数据集 * feature:增加配比任务详情接口 * fix:删除不存在的配比详情页面
This commit is contained in:
@@ -60,6 +60,9 @@ export default function RatioTasksPage() {
|
|||||||
title: "任务名称",
|
title: "任务名称",
|
||||||
dataIndex: "name",
|
dataIndex: "name",
|
||||||
key: "name",
|
key: "name",
|
||||||
|
render: (text: string, record: RatioTaskItem) => (
|
||||||
|
<a onClick={() => navigate(`/data/synthesis/ratio-task/detail/${record.id}`)}>{text}</a>
|
||||||
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "状态",
|
title: "状态",
|
||||||
@@ -81,6 +84,9 @@ export default function RatioTasksPage() {
|
|||||||
title: "目标数据集",
|
title: "目标数据集",
|
||||||
dataIndex: "target_dataset_name",
|
dataIndex: "target_dataset_name",
|
||||||
key: "target_dataset_name",
|
key: "target_dataset_name",
|
||||||
|
render: (text: string, task: RatioTaskItem) => (
|
||||||
|
<a onClick={() => navigate(`/data/management/detail/${task.target_dataset_id}`)}>{text}</a>
|
||||||
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "创建时间",
|
title: "创建时间",
|
||||||
@@ -173,6 +179,17 @@ export default function RatioTasksPage() {
|
|||||||
label: "目标数量",
|
label: "目标数量",
|
||||||
value: (task.totals ?? 0).toLocaleString(),
|
value: (task.totals ?? 0).toLocaleString(),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: "目标数据集",
|
||||||
|
value: task.target_dataset_name ? (
|
||||||
|
<a onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
navigate(`/data/management/detail/${task.target_dataset_id}`);
|
||||||
|
}}>
|
||||||
|
{task.target_dataset_name}
|
||||||
|
</a>
|
||||||
|
) : '无',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: "创建时间",
|
label: "创建时间",
|
||||||
value: task.created_at || "-",
|
value: task.created_at || "-",
|
||||||
@@ -182,6 +199,7 @@ export default function RatioTasksPage() {
|
|||||||
}))}
|
}))}
|
||||||
pagination={pagination}
|
pagination={pagination}
|
||||||
operations={operations}
|
operations={operations}
|
||||||
|
onView={(task) => {navigate(`/data/synthesis/ratio-task/detail/${task.id}`)}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,11 @@ export function queryRatioTasksUsingGet(params?: any) {
|
|||||||
return get("/api/synthesis/ratio-task", params);
|
return get("/api/synthesis/ratio-task", params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 查询配比任务详情
|
||||||
|
export function getRatioTaskByIdUsingGet(id: string) {
|
||||||
|
return get(`/api/synthesis/ratio-task/${id}`);
|
||||||
|
}
|
||||||
|
|
||||||
// 创建配比任务
|
// 创建配比任务
|
||||||
export function createRatioTaskUsingPost(data: any) {
|
export function createRatioTaskUsingPost(data: any) {
|
||||||
return post("/api/synthesis/ratio-task", data);
|
return post("/api/synthesis/ratio-task", data);
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ export interface RatioTaskItem {
|
|||||||
ratio_method?: RatioMethod
|
ratio_method?: RatioMethod
|
||||||
target_dataset_id?: string
|
target_dataset_id?: string
|
||||||
target_dataset_name?: string
|
target_dataset_name?: string
|
||||||
|
config: RatioConfigItem[]
|
||||||
created_at?: string
|
created_at?: string
|
||||||
updated_at?: string
|
updated_at?: string
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,9 +18,10 @@ from app.module.synthesis.schema.ratio_task import (
|
|||||||
PagedRatioTaskResponse,
|
PagedRatioTaskResponse,
|
||||||
RatioTaskItem,
|
RatioTaskItem,
|
||||||
TargetDatasetInfo,
|
TargetDatasetInfo,
|
||||||
|
RatioTaskDetailResponse,
|
||||||
)
|
)
|
||||||
from app.module.synthesis.service.ratio_task import RatioTaskService
|
from app.module.synthesis.service.ratio_task import RatioTaskService
|
||||||
from app.db.models.ratio_task import RatioInstance, RatioRelation
|
from app.db.models.ratio_task import RatioInstance, RatioRelation, RatioRelation as RatioRelationModel
|
||||||
|
|
||||||
router = APIRouter(
|
router = APIRouter(
|
||||||
prefix="/ratio-task",
|
prefix="/ratio-task",
|
||||||
@@ -251,3 +252,78 @@ def get_target_dataset_type(source_types: Set[str]) -> str:
|
|||||||
# 仅有一种介质类型且无其它类型
|
# 仅有一种介质类型且无其它类型
|
||||||
target_type = next(iter(media_involved))
|
target_type = next(iter(media_involved))
|
||||||
return target_type
|
return target_type
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/{task_id}", response_model=StandardResponse[RatioTaskDetailResponse], status_code=200)
|
||||||
|
async def get_ratio_task(
|
||||||
|
task_id: str,
|
||||||
|
db: AsyncSession = Depends(get_db),
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
获取配比任务详情
|
||||||
|
|
||||||
|
Path: /api/synthesis/ratio-task/{task_id}
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
# 查询任务实例
|
||||||
|
instance_res = await db.execute(
|
||||||
|
select(RatioInstance).where(RatioInstance.id == task_id)
|
||||||
|
)
|
||||||
|
instance = instance_res.scalar_one_or_none()
|
||||||
|
if not instance:
|
||||||
|
raise HTTPException(status_code=404, detail="Ratio task not found")
|
||||||
|
|
||||||
|
# 查询关联的配比关系
|
||||||
|
relations_res = await db.execute(
|
||||||
|
select(RatioRelationModel).where(RatioRelationModel.ratio_instance_id == task_id)
|
||||||
|
)
|
||||||
|
relations = list(relations_res.scalars().all())
|
||||||
|
|
||||||
|
# 查询目标数据集
|
||||||
|
target_ds = None
|
||||||
|
if instance.target_dataset_id:
|
||||||
|
ds_res = await db.execute(
|
||||||
|
select(Dataset).where(Dataset.id == instance.target_dataset_id)
|
||||||
|
)
|
||||||
|
target_ds = ds_res.scalar_one_or_none()
|
||||||
|
|
||||||
|
# 构建响应
|
||||||
|
config = [
|
||||||
|
{
|
||||||
|
"dataset_id": rel.source_dataset_id,
|
||||||
|
"counts": str(rel.counts) if rel.counts is not None else "0",
|
||||||
|
"filter_conditions": rel.filter_conditions or "",
|
||||||
|
}
|
||||||
|
for rel in relations
|
||||||
|
]
|
||||||
|
|
||||||
|
target_dataset_info = {
|
||||||
|
"id": str(target_ds.id) if target_ds else None,
|
||||||
|
"name": target_ds.name if target_ds else None,
|
||||||
|
"type": target_ds.dataset_type if target_ds else None,
|
||||||
|
"status": target_ds.status if target_ds else None,
|
||||||
|
"file_count": target_ds.file_count if target_ds else 0,
|
||||||
|
"size_bytes": target_ds.size_bytes if target_ds else 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
return StandardResponse(
|
||||||
|
code=200,
|
||||||
|
message="success",
|
||||||
|
data=RatioTaskDetailResponse(
|
||||||
|
id=instance.id,
|
||||||
|
name=instance.name or "",
|
||||||
|
description=instance.description,
|
||||||
|
status=instance.status or "UNKNOWN",
|
||||||
|
totals=instance.totals or 0,
|
||||||
|
ratio_method=instance.ratio_method or "",
|
||||||
|
config=config,
|
||||||
|
target_dataset=target_dataset_info,
|
||||||
|
created_at=instance.created_at,
|
||||||
|
updated_at=instance.updated_at,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
except HTTPException:
|
||||||
|
raise
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Failed to get ratio task {task_id}: {e}")
|
||||||
|
raise HTTPException(status_code=500, detail="Internal server error")
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
from typing import List, Optional
|
from typing import List, Optional, Dict, Any
|
||||||
|
from datetime import datetime
|
||||||
from pydantic import BaseModel, Field, field_validator
|
from pydantic import BaseModel, Field, field_validator
|
||||||
|
|
||||||
class RatioConfigItem(BaseModel):
|
class RatioConfigItem(BaseModel):
|
||||||
@@ -84,3 +85,22 @@ class PagedRatioTaskResponse(BaseModel):
|
|||||||
totalPages: int
|
totalPages: int
|
||||||
page: int
|
page: int
|
||||||
size: int
|
size: int
|
||||||
|
|
||||||
|
|
||||||
|
class RatioTaskDetailResponse(BaseModel):
|
||||||
|
"""Detailed response for a ratio task."""
|
||||||
|
id: str = Field(..., description="任务ID")
|
||||||
|
name: str = Field(..., description="任务名称")
|
||||||
|
description: Optional[str] = Field(None, description="任务描述")
|
||||||
|
status: str = Field(..., description="任务状态")
|
||||||
|
totals: int = Field(..., description="目标总数")
|
||||||
|
ratio_method: str = Field(..., description="配比方式")
|
||||||
|
config: List[Dict[str, Any]] = Field(..., description="配比配置")
|
||||||
|
target_dataset: Dict[str, Any] = Field(..., description="目标数据集信息")
|
||||||
|
created_at: Optional[datetime] = Field(None, description="创建时间")
|
||||||
|
updated_at: Optional[datetime] = Field(None, description="更新时间")
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
json_encoders = {
|
||||||
|
datetime: lambda v: v.isoformat() if v else None
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user