diff --git a/.dockerignore b/.dockerignore old mode 100644 new mode 100755 diff --git a/.gitee/ISSUE_TEMPLATE.zh-CN.md b/.gitee/ISSUE_TEMPLATE.zh-CN.md old mode 100644 new mode 100755 diff --git a/.gitee/PULL_REQUEST_TEMPLATE.zh-CN.md b/.gitee/PULL_REQUEST_TEMPLATE.zh-CN.md old mode 100644 new mode 100755 diff --git a/CLAUDE.md b/CLAUDE.md old mode 100644 new mode 100755 diff --git a/LICENSE b/LICENSE old mode 100644 new mode 100755 diff --git a/README.md b/README.md old mode 100644 new mode 100755 diff --git a/backend/.env.example b/backend/.env.example index 402d14b..4926101 100755 --- a/backend/.env.example +++ b/backend/.env.example @@ -24,9 +24,10 @@ GEN2D_LLM_TEMPERATURE=0.7 GEN2D_LLM_MAX_TOKENS=2048 # 文生图模型(OpenAI 兼容 Images API) -GEN2D_IMAGE_BASE_URL=https://api.suchuang.vip/v1 -GEN2D_IMAGE_API_KEY= -GEN2D_IMAGE_MODEL=gpt-image-2-token +# 模型可选: dall-e-2, dall-e-3, gpt-image-1, gpt-image-2 +GEN2D_IMAGE_BASE_URL=https://api.weelinking.com/v1 +GEN2D_IMAGE_API_KEY=sk-your-api-key +GEN2D_IMAGE_MODEL=gpt-image-2 GEN2D_IMAGE_WIDTH=1024 GEN2D_IMAGE_HEIGHT=1024 GEN2D_IMAGE_QUALITY=low diff --git a/backend/Dockerfile b/backend/Dockerfile old mode 100644 new mode 100755 diff --git a/backend/go.mod b/backend/go.mod old mode 100644 new mode 100755 diff --git a/backend/go.sum b/backend/go.sum old mode 100644 new mode 100755 diff --git a/backend/internal/config/config.yml b/backend/internal/config/config.yml index 7f1a7b2..74055ba 100755 --- a/backend/internal/config/config.yml +++ b/backend/internal/config/config.yml @@ -25,9 +25,9 @@ llm: max_tokens: 2048 image_gen: - base_url: "https://api.suchuang.vip/v1" + base_url: "" api_key: "" - model: "gpt-image-2-token" + model: "" width: 1024 height: 1024 quality: "low" diff --git a/backend/internal/db/db.go b/backend/internal/db/db.go old mode 100644 new mode 100755 diff --git a/backend/internal/handler/generate.go b/backend/internal/handler/generate.go index e592b1e..a7cb7dc 100755 --- a/backend/internal/handler/generate.go +++ b/backend/internal/handler/generate.go @@ -47,6 +47,7 @@ type TaskResponse struct { Prompt string `json:"prompt"` AssetType string `json:"assetType"` Status string `json:"status"` + Stage string `json:"stage,omitempty"` Progress int `json:"progress"` RetryCount int `json:"retryCount"` Error string `json:"error,omitempty"` @@ -107,10 +108,15 @@ func Generate(c *gin.Context) { } // runPipelineBg 后台执行生成管线,更新任务状态。 -func runPipelineBg(ctx context.Context, projectID, taskID string, req GenerateRequest) { +func runPipelineBg(projectID, taskID string, req GenerateRequest) { + // 注入进度上报回调 + ctx := service.WithProgressReporter(context.Background(), func(stage string, progress int) { + updateTaskProgress(taskID, "running", stage, progress) + }) + l := logger.With("task_id", taskID, "project_id", projectID) - updateStatus(taskID, "running", 10) + updateTaskProgress(taskID, "running", "prompt_builder", 5) in := service.PipelineInput{ ProjectID: projectID, @@ -138,7 +144,7 @@ func runPipelineBg(ctx context.Context, projectID, taskID string, req GenerateRe return } - updateStatus(taskID, "saving", 80) + updateTaskProgress(taskID, "saving", "format_adapter", 90) assets := make([]AssetResponse, len(output.Assets)) for i, a := range output.Assets { @@ -173,13 +179,14 @@ func runPipelineBg(ctx context.Context, projectID, taskID string, req GenerateRe l.Info("task completed", "asset_count", len(assets)) } -func updateStatus(taskID, status string, progress int) { +func updateTaskProgress(taskID, status, stage string, progress int) { rec, ok := taskStore.Load(taskID) if !ok { return } r := rec.(*taskRecord) r.task.Status = status + r.task.Stage = stage r.task.Progress = progress taskStore.Store(taskID, r) } diff --git a/backend/internal/handler/health.go b/backend/internal/handler/health.go old mode 100644 new mode 100755 diff --git a/backend/internal/handler/login.go b/backend/internal/handler/login.go old mode 100644 new mode 100755 diff --git a/backend/internal/handler/prompt.go b/backend/internal/handler/prompt.go old mode 100644 new mode 100755 diff --git a/backend/internal/handler/register.go b/backend/internal/handler/register.go old mode 100644 new mode 100755 diff --git a/backend/internal/mildware/auth.go b/backend/internal/mildware/auth.go old mode 100644 new mode 100755 diff --git a/backend/internal/model/response.go b/backend/internal/model/response.go old mode 100644 new mode 100755 diff --git a/backend/internal/model/user.go b/backend/internal/model/user.go old mode 100644 new mode 100755 diff --git a/backend/internal/service/auth.go b/backend/internal/service/auth.go old mode 100644 new mode 100755 diff --git a/backend/internal/service/nodes.go b/backend/internal/service/nodes.go old mode 100644 new mode 100755 index 1bac3ed..c64156d --- a/backend/internal/service/nodes.go +++ b/backend/internal/service/nodes.go @@ -57,8 +57,10 @@ var promptOptimizerNode = compose.InvokableLambda(func(ctx context.Context, in P func promptOptimizerPreHandler(ctx context.Context, in PipelineInput, state *PipelineState) (PipelineInput, error) { if state.RetryCount == 0 { state.Input = in + reportProgress(ctx, "prompt_builder", 10) } else if state.RejectReason != "" { in.RejectReason = state.RejectReason + reportProgress(ctx, "prompt_builder", 30+state.RetryCount*10) } return in, nil } @@ -66,6 +68,7 @@ func promptOptimizerPreHandler(ctx context.Context, in PipelineInput, state *Pip // promptOptimizerPostHandler 将最终提示词写入全局状态。 func promptOptimizerPostHandler(ctx context.Context, out string, state *PipelineState) (string, error) { state.FinalPrompt = out + reportProgress(ctx, "asset_generator", 35) return out, nil } @@ -82,6 +85,7 @@ var assetGeneratorNode = compose.InvokableLambda(func(ctx context.Context, promp // assetGeneratorPostHandler 将原始图片写入全局状态。 func assetGeneratorPostHandler(ctx context.Context, out []GeneratedImage, state *PipelineState) ([]GeneratedImage, error) { state.RawImages = out + reportProgress(ctx, "quality_supervisor", 60) return out, nil } @@ -104,11 +108,14 @@ var qualitySupervisorNode = compose.InvokableLambda(func(ctx context.Context, im if pass { state.NextNode = nodeFormatAdapter + reportProgress(ctx, "format_adapter", 85) } else if state.RetryCount >= 3 { state.NextNode = nodeFormatAdapter + reportProgress(ctx, "format_adapter", 85) } else { state.RetryCount++ state.NextNode = nodePromptOptimizer + reportProgress(ctx, "quality_supervisor", 50+state.RetryCount*10) } input = state.Input diff --git a/backend/internal/service/pipeline.go b/backend/internal/service/pipeline.go old mode 100644 new mode 100755 index 9134104..e377b85 --- a/backend/internal/service/pipeline.go +++ b/backend/internal/service/pipeline.go @@ -16,6 +16,25 @@ const ( nodeFormatAdapter = "format_adapter" ) +// ProgressReporter 管线进度回调:stage 为当前节点名,progress 为 0-100。 +type ProgressReporter func(stage string, progress int) + +type progressKeyType struct{} + +var progressCtxKey progressKeyType + +// WithProgressReporter 将进度回调注入 context。 +func WithProgressReporter(ctx context.Context, r ProgressReporter) context.Context { + return context.WithValue(ctx, progressCtxKey, r) +} + +// reportProgress 从 context 取出回调上报进度。 +func reportProgress(ctx context.Context, stage string, progress int) { + if r, ok := ctx.Value(progressCtxKey).(ProgressReporter); ok { + r(stage, progress) + } +} + // NewGenerateGraph 创建生成管线 Graph(PromptOptimizer → AssetGenerator → QualitySupervisor → FormatAdapter)。 // // START → PromptOptimizer → AssetGenerator → QualitySupervisor diff --git a/backend/internal/service/pipeline_test.go b/backend/internal/service/pipeline_test.go old mode 100644 new mode 100755 diff --git a/backend/internal/service/prompt_agent.go b/backend/internal/service/prompt_agent.go old mode 100644 new mode 100755 diff --git a/backend/internal/service/prompt_agent_test.go b/backend/internal/service/prompt_agent_test.go old mode 100644 new mode 100755 diff --git a/backend/pkg/splitsprite/splitsprite.go b/backend/pkg/splitsprite/splitsprite.go old mode 100644 new mode 100755 diff --git a/backend/tools/gentest.go b/backend/tools/gentest.go old mode 100644 new mode 100755 diff --git a/docker-compose.yml b/docker-compose.yml old mode 100644 new mode 100755 diff --git a/docs/_index.md b/docs/_index.md old mode 100644 new mode 100755 diff --git a/docs/api.md b/docs/api.md old mode 100644 new mode 100755 diff --git a/docs/async-tasks.md b/docs/async-tasks.md old mode 100644 new mode 100755 diff --git a/docs/backend.md b/docs/backend.md old mode 100644 new mode 100755 diff --git a/docs/database.md b/docs/database.md old mode 100644 new mode 100755 diff --git a/docs/frontend.md b/docs/frontend.md old mode 100644 new mode 100755 diff --git a/docs/style-keys.md b/docs/style-keys.md old mode 100644 new mode 100755 diff --git a/frontend/.gitignore b/frontend/.gitignore old mode 100644 new mode 100755 diff --git a/frontend/Dockerfile b/frontend/Dockerfile old mode 100644 new mode 100755 diff --git a/frontend/index.html b/frontend/index.html old mode 100644 new mode 100755 diff --git a/frontend/nginx.conf b/frontend/nginx.conf old mode 100644 new mode 100755 diff --git a/frontend/package-lock.json b/frontend/package-lock.json old mode 100644 new mode 100755 diff --git a/frontend/package.json b/frontend/package.json old mode 100644 new mode 100755 diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx old mode 100644 new mode 100755 diff --git a/frontend/src/api/auth.ts b/frontend/src/api/auth.ts old mode 100644 new mode 100755 diff --git a/frontend/src/api/mock.ts b/frontend/src/api/mock.ts old mode 100644 new mode 100755 diff --git a/frontend/src/api/project.ts b/frontend/src/api/project.ts old mode 100644 new mode 100755 diff --git a/frontend/src/api/prompt.ts b/frontend/src/api/prompt.ts old mode 100644 new mode 100755 diff --git a/frontend/src/components/AssetPreview.tsx b/frontend/src/components/AssetPreview.tsx old mode 100644 new mode 100755 diff --git a/frontend/src/components/EmptyState.tsx b/frontend/src/components/EmptyState.tsx old mode 100644 new mode 100755 diff --git a/frontend/src/components/GenerateForm.module.css b/frontend/src/components/GenerateForm.module.css old mode 100644 new mode 100755 diff --git a/frontend/src/components/GenerateForm.tsx b/frontend/src/components/GenerateForm.tsx old mode 100644 new mode 100755 index a0ebad9..e625e43 --- a/frontend/src/components/GenerateForm.tsx +++ b/frontend/src/components/GenerateForm.tsx @@ -173,9 +173,9 @@ export default function GenerateForm({ onSubmit, submitting }: GenerateFormProps type="number" value={params.resolution} onChange={e => setParams({ resolution: Number(e.target.value) })} - min={32} - max={1024} - step={32} + min={1024} + max={1536} + step={512} style={{ width: 100 }} /> px diff --git a/frontend/src/components/Layout.tsx b/frontend/src/components/Layout.tsx old mode 100644 new mode 100755 diff --git a/frontend/src/components/ProgressBar.tsx b/frontend/src/components/ProgressBar.tsx old mode 100644 new mode 100755 diff --git a/frontend/src/components/PromptEditor.tsx b/frontend/src/components/PromptEditor.tsx old mode 100644 new mode 100755 diff --git a/frontend/src/components/Skeleton.module.css b/frontend/src/components/Skeleton.module.css old mode 100644 new mode 100755 diff --git a/frontend/src/components/Skeleton.tsx b/frontend/src/components/Skeleton.tsx old mode 100644 new mode 100755 diff --git a/frontend/src/components/StyleSelector.module.css b/frontend/src/components/StyleSelector.module.css old mode 100644 new mode 100755 diff --git a/frontend/src/components/StyleSelector.tsx b/frontend/src/components/StyleSelector.tsx old mode 100644 new mode 100755 diff --git a/frontend/src/components/Toast.module.css b/frontend/src/components/Toast.module.css old mode 100644 new mode 100755 diff --git a/frontend/src/components/Toast.tsx b/frontend/src/components/Toast.tsx old mode 100644 new mode 100755 diff --git a/frontend/src/hooks/useProjectStyle.ts b/frontend/src/hooks/useProjectStyle.ts old mode 100644 new mode 100755 diff --git a/frontend/src/main.tsx b/frontend/src/main.tsx old mode 100644 new mode 100755 diff --git a/frontend/src/pages/GeneratePage.tsx b/frontend/src/pages/GeneratePage.tsx index 1912994..a5581e6 100755 --- a/frontend/src/pages/GeneratePage.tsx +++ b/frontend/src/pages/GeneratePage.tsx @@ -19,9 +19,12 @@ export default function GeneratePage() { const { style: projectStyle, loadProject } = useProjectStore() const { status, + stage, progress, taskId, statusText, + retryCount, + rejectReason, submit, reset: resetGeneration, } = useGenerationStore() @@ -83,11 +86,11 @@ export default function GeneratePage() { ) : (