From e0a70106c198e683c2612639a05f2bb6f33f3cc1 Mon Sep 17 00:00:00 2001 From: wonder Date: Mon, 25 May 2026 18:34:46 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E7=AE=A1=E7=BA=BF?= =?UTF-8?q?=E9=98=B6=E6=AE=B5=E5=8F=AF=E8=A7=86=E5=8C=96=E5=B1=95=E7=A4=BA?= =?UTF-8?q?=E5=B9=B6=E6=94=B9=E8=BF=9B=E4=BB=BB=E5=8A=A1=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加 PipelineStages 组件,用圆角矩形和箭头展示管线阶段 - 三色方案:已完成为浅绿、进行中为浅橙、未完成为灰色 - 任务列表中显示进度百分比和管线阶段 - 增强后端日志输出,添加任务启动、进度更新和管线完成日志 - 用于诊断任务卡在 running 状态的问题 --- backend/internal/handler/generate.go | 4 ++ frontend/src/components/PipelineStages.tsx | 71 ++++++++++++++++++++++ frontend/src/components/TaskListPanel.tsx | 15 ++++- 3 files changed, 87 insertions(+), 3 deletions(-) create mode 100644 frontend/src/components/PipelineStages.tsx diff --git a/backend/internal/handler/generate.go b/backend/internal/handler/generate.go index 7994a52..b5fb767 100755 --- a/backend/internal/handler/generate.go +++ b/backend/internal/handler/generate.go @@ -74,9 +74,11 @@ func Generate(c *gin.Context) { // runPipelineBg 后台执行生成管线,更新任务状态。 func runPipelineBg(ctx context.Context, projectID, taskID string, req GenerateRequest) { l := logger.With("task_id", taskID, "project_id", projectID) + l.Info("task started", "asset_type", req.AssetType, "prompt", req.Prompt) // 注入进度上报回调 ctx = service.WithProgressReporter(ctx, func(stage string, progress int) { + l.Info("progress update", "stage", stage, "progress", progress) updateTaskInDB(ctx, taskID, "running", stage, "", progress) }) @@ -101,12 +103,14 @@ func runPipelineBg(ctx context.Context, projectID, taskID string, req GenerateRe }, } + l.Info("calling pipeline", "input_tags", in.Tags, "user_note", in.UserNote) output, err := service.RunPipeline(ctx, in) if err != nil { l.Error("task pipeline failed", "error", err) updateTaskInDB(ctx, taskID, "failed", "", err.Error(), 0) return } + l.Info("pipeline completed", "asset_count", len(output.Assets)) updateTaskInDB(ctx, taskID, "saving", "format_adapter", "", 90) diff --git a/frontend/src/components/PipelineStages.tsx b/frontend/src/components/PipelineStages.tsx new file mode 100644 index 0000000..1fc166d --- /dev/null +++ b/frontend/src/components/PipelineStages.tsx @@ -0,0 +1,71 @@ +const STAGES = [ + { key: 'prompt_builder', label: '提示词' }, + { key: 'asset_generator', label: '生成中' }, + { key: 'quality_supervisor', label: '质检中' }, + { key: 'format_adapter', label: '格式转换' }, +] as const + +type Stage = typeof STAGES[number]['key'] + +interface PipelineStagesProps { + currentStage: Stage | null + status: string +} + +export default function PipelineStages({ currentStage, status }: PipelineStagesProps) { + if (!currentStage || status !== 'running') { + return null + } + + const currentIndex = STAGES.findIndex(s => s.key === currentStage) + + return ( +
+ {STAGES.map((stage, index) => { + let bgColor: string + let textColor: string + + if (index < currentIndex) { + bgColor = 'rgba(74, 222, 128, 0.15)' + textColor = '#4ade80' + } else if (index === currentIndex) { + bgColor = 'rgba(251, 146, 60, 0.15)' + textColor = '#fb923c' + } else { + bgColor = 'rgba(156, 163, 175, 0.1)' + textColor = '#9ca3af' + } + + return ( +
+ + {stage.label} + + {index < STAGES.length - 1 && ( + + → + + )} +
+ ) + })} +
+ ) +} diff --git a/frontend/src/components/TaskListPanel.tsx b/frontend/src/components/TaskListPanel.tsx index 32347fe..61f55f4 100644 --- a/frontend/src/components/TaskListPanel.tsx +++ b/frontend/src/components/TaskListPanel.tsx @@ -3,6 +3,7 @@ import { useParams } from 'react-router-dom' import { getTasks } from '../api/project' import type { Task } from '../api/types' import StatusBadge from './StatusBadge' +import PipelineStages from './PipelineStages' import Skeleton from './Skeleton' const ASSET_TYPE_LABELS: Record = { @@ -103,9 +104,17 @@ export default function TaskListPanel() { > {task.prompt}

- - {formatRelativeTime(task.createdAt)} - +
+ + {formatRelativeTime(task.createdAt)} + + {task.progress !== undefined && task.status === 'running' && ( + + {task.progress}% + + )} +
+ )) )}