diff --git a/furniture-3d-system/src/app/intake/non-integrated/workspaces/ai-white-background/NonIntegratedAiWhiteBackgroundPanel.tsx b/furniture-3d-system/src/app/intake/non-integrated/workspaces/ai-white-background/NonIntegratedAiWhiteBackgroundPanel.tsx index 92e362f1..9f6c3490 100644 --- a/furniture-3d-system/src/app/intake/non-integrated/workspaces/ai-white-background/NonIntegratedAiWhiteBackgroundPanel.tsx +++ b/furniture-3d-system/src/app/intake/non-integrated/workspaces/ai-white-background/NonIntegratedAiWhiteBackgroundPanel.tsx @@ -1,15 +1,24 @@ "use client"; import { useState } from "react"; -import { AlertCircle, ImageIcon, Sparkles, UploadCloud, X } from "lucide-react"; +import { + AlertCircle, + CheckCircle2, + ImageIcon, + Maximize2, + RefreshCcw, + Sparkles, + UploadCloud, + X, +} from "lucide-react"; import Button from "@/components/ui/Button"; import Select from "@/components/ui/Select"; import { cn } from "@/lib/utils"; import { AI_WHITE_BACKGROUND_VIEW_KEYS, AI_WHITE_BACKGROUND_VIEW_LABELS, - type AiWhiteBackgroundTargetFinishOption, type AiWhiteBackgroundSessionStatus, + type AiWhiteBackgroundTargetFinishOption, type AiWhiteBackgroundUploadManifest, type AiWhiteBackgroundViewKey, } from "./nonIntegratedAiWhiteBackground"; @@ -74,31 +83,36 @@ function getSessionStatusMeta(status: AiWhiteBackgroundSessionStatus | null) { if (status === "uploaded") { return { label: "已上传", - className: "bg-[#eef7f2] text-[#2f6b51]", + className: "bg-[#e6f3fb] text-[#39565d]", + dotClassName: "bg-[#47646b]", }; } if (status === "generated") { return { label: "已生成", - className: "bg-black/[0.035] text-apple-label-primary", + className: "bg-[#eef7f2] text-[#2f6b51]", + dotClassName: "bg-[#2f6b51]", }; } if (status === "upload_failed") { return { label: "上传失败", - className: "bg-[#fff3f5] text-[#a5485a]", + className: "bg-[#fff1ef] text-[#9a403d]", + dotClassName: "bg-[#a83836]", }; } if (status === "draft") { return { label: "待生成", - className: "bg-black/[0.035] text-apple-label-secondary", + className: "bg-[#f1f4f5] text-[#5a6062]", + dotClassName: "bg-[#8a9496]", }; } return { label: "未开始", - className: "bg-black/[0.035] text-apple-label-secondary", + className: "bg-[#f1f4f5] text-[#5a6062]", + dotClassName: "bg-[#adb3b5]", }; } @@ -106,7 +120,8 @@ function getManifestStatusMeta(manifest: AiWhiteBackgroundUploadManifest | null) if (!manifest) { return { label: "未上传素材库", - className: "bg-black/[0.035] text-apple-label-secondary", + className: "bg-[#f1f4f5] text-[#5a6062]", + dotClassName: "bg-[#adb3b5]", }; } @@ -114,30 +129,35 @@ function getManifestStatusMeta(manifest: AiWhiteBackgroundUploadManifest | null) return { label: "素材库生效中", className: "bg-[#eef7f2] text-[#2f6b51]", + dotClassName: "bg-[#2f6b51]", }; } if (manifest.status === "cleanup_pending") { return { label: "清理中", - className: "bg-[#fff7e8] text-[#8a6538]", + className: "bg-[#fff7e8] text-[#725737]", + dotClassName: "bg-[#b6905d]", }; } if (manifest.status === "cleaned") { return { label: "已清理", - className: "bg-black/[0.035] text-apple-label-secondary", + className: "bg-[#f1f4f5] text-[#5a6062]", + dotClassName: "bg-[#8a9496]", }; } if (manifest.status === "cleanup_failed") { return { label: "清理失败", - className: "bg-[#fff3f5] text-[#a5485a]", + className: "bg-[#fff1ef] text-[#9a403d]", + dotClassName: "bg-[#a83836]", }; } return { label: "待人工复核", - className: "bg-[#fff7e8] text-[#8a6538]", + className: "bg-[#fff7e8] text-[#725737]", + dotClassName: "bg-[#b6905d]", }; } @@ -156,6 +176,62 @@ function getTargetFinishLabel(finish: AiWhiteBackgroundTargetFinishOption) { .join(" · "); } +function StatChip({ + label, + value, + tone = "neutral", +}: { + label: string; + value: string; + tone?: "neutral" | "success" | "warning"; +}) { + return ( +
+ + {label} {value} + + + {label} + + + {value} + +
+ ); +} + +function StatusPill({ + label, + value, + className, + dotClassName, +}: { + label: string; + value: string; + className: string; + dotClassName: string; +}) { + return ( + + + {label} + {value} + + ); +} + function AiWhiteBackgroundImagePreviewDialog({ src, alt, @@ -167,29 +243,34 @@ function AiWhiteBackgroundImagePreviewDialog({ }) { return (
event.stopPropagation()} > -
-

- {alt} -

+
+
+

+ Source Preview +

+

+ {alt} +

+
-
+
{src.trim() ? ( <> {/* eslint-disable-next-line @next/next/no-img-element */} @@ -200,7 +281,7 @@ function AiWhiteBackgroundImagePreviewDialog({ /> ) : ( -
+
原图加载失败
)} @@ -221,7 +302,7 @@ function AiWhiteBackgroundCardImage({ }) { if (!file.dataUrl.trim()) { return ( -
+
源图加载失败
); @@ -304,153 +385,148 @@ export default function NonIntegratedAiWhiteBackgroundPanel({ : null; return ( -
-
- - {styleLabel} - - - {styleKey} - - - 会话:{sessionMeta.label} - - - 素材库:{manifestMeta.label} - - - 可生成 {availableSourceViewCount}/8 - - - 已生成 {generatedCount}/8 - - - 已上传 {uploadedCount}/8 - -
+
+
+
+
+
+ + AI White Studio + + + +
+
+

+ AI 白底图工坊 +

+ + {styleLabel} + + + {styleKey} + +
+
-
- {AI_WHITE_BACKGROUND_VIEW_KEYS.map((viewKey) => { - const generatedFile = generatedFiles[viewKey]; - const sourceFile = sourceFilesByView[viewKey]; - const sourceReady = sourceReadyByView[viewKey]; - const displayedImageFile = isImageUploadFile(generatedFile) - ? generatedFile - : isImageUploadFile(sourceFile) - ? sourceFile - : null; - const isShowingGeneratedFile = - generatedFile != null && displayedImageFile?.id === generatedFile.id; - const previewLabel = isShowingGeneratedFile - ? `${AI_WHITE_BACKGROUND_VIEW_LABELS[viewKey]}原图` - : `${AI_WHITE_BACKGROUND_VIEW_LABELS[viewKey]}源图`; - const hoverPreviewLabel = isShowingGeneratedFile - ? "点击查看原图" - : "点击查看源图"; - const cardStatusLabel = generatedFile - ? "已生成" - : sourceReady - ? "可生成" - : "缺源图"; - const isViewGenerating = generatingViewKeySet.has(viewKey); +
+ 0 ? "success" : "warning"} + /> + 0 ? "success" : "neutral"} + /> + 0 ? "success" : "neutral"} + /> +
+
+
- return ( -
-
-

- {AI_WHITE_BACKGROUND_VIEW_LABELS[viewKey]} -

- - {cardStatusLabel} - -
+
+
+
+
+

+ Generated Views +

+

+ 九视图生成面板 +

+
+ + {generatedCount}/8 + +
-
+ {AI_WHITE_BACKGROUND_VIEW_KEYS.map((viewKey) => { + const generatedFile = generatedFiles[viewKey]; + const sourceFile = sourceFilesByView[viewKey]; + const sourceReady = sourceReadyByView[viewKey]; + const displayedImageFile = isImageUploadFile(generatedFile) + ? generatedFile + : isImageUploadFile(sourceFile) + ? sourceFile + : null; + const isShowingGeneratedFile = + generatedFile != null && displayedImageFile?.id === generatedFile.id; + const previewLabel = isShowingGeneratedFile + ? `${AI_WHITE_BACKGROUND_VIEW_LABELS[viewKey]}原图` + : `${AI_WHITE_BACKGROUND_VIEW_LABELS[viewKey]}源图`; + const hoverPreviewLabel = isShowingGeneratedFile + ? "点击查看原图" + : "点击查看源图"; + const cardStatusLabel = generatedFile + ? "已生成" + : sourceReady + ? "可生成" + : "缺源图"; + const isViewGenerating = generatingViewKeySet.has(viewKey); + + return ( +
- {displayedImageFile ? ( - - ) : ( -
-
- {sourceReady ? ( - - ) : ( - - )} -
+
+
+

+ {AI_WHITE_BACKGROUND_VIEW_LABELS[viewKey]} +

+

+ {isShowingGeneratedFile ? "Generated output" : "Source reference"} +

- )} -
+ + {cardStatusLabel} + +
- {displayedImageFile ? ( -
- {displayedImageFile.name} - {isShowingGeneratedFile ? ( +
+ {displayedImageFile ? ( ) : ( - - 源图 - +
+
+
+ {sourceReady ? ( + + ) : ( + + )} +
+

+ {sourceReady ? "等待生成" : "等待补源图"} +

+
+
)}
- ) : ( -
- )} - -
- ); - })} +
+ {displayedImageFile ? ( +
+ + {displayedImageFile.name} + + {isShowingGeneratedFile ? ( + + ) : ( + + 源图 + + )} +
+ ) : null} +
+ + +
+ ); + })} +
+