fix: 优化 compact 对话框、画布节点标签、删图重置及比例弹窗

- compact 模式尺寸调整,生成按钮不再溢出框外
- 生成时自动进入 compact 状态,idle 时恢复
- 删除所有样图后重置为新对话状态(清除画布、恢复标题)
- 去掉 drag handle 模式标签,原图右上角统一高级黑 tag
- 作品图不再显示重复标识
- 比例弹窗宽度自适应内容,添加 hover/active 交互样式
- 套图模式默认三种各一张
- 设置弹窗点击外部可关闭
- 历史记录删除按钮样式优化

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-06-12 12:37:32 +08:00
parent 863f1f075e
commit e88edbe165
2 changed files with 120 additions and 70 deletions
+28 -19
View File
@@ -981,9 +981,9 @@ const cloneSetCountOptions: Array<{
]; ];
const cloneSetCountKeys = cloneSetCountOptions.map((option) => option.key); const cloneSetCountKeys = cloneSetCountOptions.map((option) => option.key);
const defaultCloneSetCounts: Record<CloneSetCountKey, number> = { const defaultCloneSetCounts: Record<CloneSetCountKey, number> = {
selling: 3, selling: 1,
white: 1, white: 1,
scene: 3, scene: 1,
}; };
const minCloneSetTotal = 1; const minCloneSetTotal = 1;
const maxCloneSetTotal = 16; const maxCloneSetTotal = 16;
@@ -1674,9 +1674,9 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
const [selectedScenes, setSelectedScenes] = useState<string[]>([]); const [selectedScenes, setSelectedScenes] = useState<string[]>([]);
useEffect(() => { useEffect(() => {
if (status === "done") { if (status === "done" || status === "generating") {
setIsCommandComposerCompact(true); setIsCommandComposerCompact(true);
} else if (status === "generating" || status === "idle") { } else if (status === "idle") {
setIsCommandComposerCompact(false); setIsCommandComposerCompact(false);
} }
}, [status]); }, [status]);
@@ -2623,6 +2623,12 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
if (next.length === 0) { if (next.length === 0) {
setStatus("idle"); setStatus("idle");
setResults([]); setResults([]);
setCanvasNodes([]);
setIsCommandComposerCompact(false);
setPreviewOffset({ x: 0, y: 0 });
previewOffsetRef.current = { x: 0, y: 0 };
setPreviewZoom(1);
setActiveHistoryRecordId(null);
} }
return next; return next;
}); });
@@ -3013,7 +3019,7 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
const composer = commandComposerWrapRef.current; const composer = commandComposerWrapRef.current;
if (composer?.contains(target)) return; if (composer?.contains(target)) return;
if (composerMenu && composerMenu !== "settings") setComposerMenu(null); if (composerMenu) setComposerMenu(null);
if (status === "done" && !isCommandComposerCompact) setIsCommandComposerCompact(true); if (status === "done" && !isCommandComposerCompact) setIsCommandComposerCompact(true);
}; };
@@ -3629,6 +3635,7 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
setDetailRequirement(""); setDetailRequirement("");
setSelectedDetailModules(defaultDetailModuleIds); setSelectedDetailModules(defaultDetailModuleIds);
setDetailStatus("idle"); setDetailStatus("idle");
setIsCommandComposerCompact(false);
}; };
const activeToolMeta = sideTools.find((tool) => tool.key === activeTool); const activeToolMeta = sideTools.find((tool) => tool.key === activeTool);
@@ -4655,25 +4662,27 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
} }
}} }}
> >
<span className="clone-ai-node-label">{node.mode === "set" ? "套图" : node.mode === "detail" ? "详情图" : node.mode === "model" ? "模特图" : node.mode === "hot" ? "爆款图" : node.mode}</span>
</div> </div>
{node.sourceImage ? ( {node.sourceImage ? (
<button <div className="clone-ai-main-result-wrap">
type="button" <button
className="clone-ai-main-result" type="button"
onClick={() => openProductSetPreview({ src: node.sourceImage!, label: "原图素材" })} className="clone-ai-main-result"
> onClick={() => openProductSetPreview({ src: node.sourceImage!, label: "原图素材" })}
<img src={node.sourceImage} alt="原图素材" /> >
<span></span> <img src={node.sourceImage} alt="原图素材" />
</button> <span className="clone-ai-img-tag"></span>
</button>
</div>
) : null} ) : null}
<div className="clone-ai-flow-arrow" aria-hidden="true" /> <div className="clone-ai-flow-arrow" aria-hidden="true" />
<div className="clone-ai-result-grid result-reveal"> <div className="clone-ai-result-grid result-reveal">
{node.results.map((card) => ( {node.results.map((card, cardIndex) => (
<button key={card.id} type="button" style={{ aspectRatio: parseRatioToAspectCss(ratio) }} onClick={() => openProductSetPreview(card)}> <div key={card.id} className="clone-ai-result-item">
<img src={card.src} alt={card.label} /> <button type="button" style={{ aspectRatio: parseRatioToAspectCss(ratio) }} onClick={() => openProductSetPreview(card)}>
<span>{card.label}</span> <img src={card.src} alt={card.label} />
</button> </button>
</div>
))} ))}
</div> </div>
</article> </article>
+92 -51
View File
@@ -2830,9 +2830,14 @@
cursor: grabbing; cursor: grabbing;
} }
.ecommerce-standalone .product-clone-page[data-tool="clone"] .clone-ai-canvas-node .clone-ai-main-result { .ecommerce-standalone .product-clone-page[data-tool="clone"] .clone-ai-canvas-node .clone-ai-main-result-wrap {
flex: 0 0 auto; flex: 0 0 auto;
width: 120px; width: 160px;
}
.ecommerce-standalone .product-clone-page[data-tool="clone"] .clone-ai-canvas-node .clone-ai-main-result {
position: relative;
width: 100%;
border-radius: 12px; border-radius: 12px;
overflow: hidden; overflow: hidden;
border: 1px solid rgba(30, 189, 219, 0.12); border: 1px solid rgba(30, 189, 219, 0.12);
@@ -2846,22 +2851,19 @@
display: block; display: block;
} }
.ecommerce-standalone .product-clone-page[data-tool="clone"] .clone-ai-canvas-node .clone-ai-main-result span {
display: block;
text-align: center;
font-size: 11px;
color: #68818f;
padding: 4px;
}
.ecommerce-standalone .product-clone-page[data-tool="clone"] .clone-ai-canvas-node .clone-ai-result-grid { .ecommerce-standalone .product-clone-page[data-tool="clone"] .clone-ai-canvas-node .clone-ai-result-grid {
display: flex; display: flex;
gap: 12px; gap: 12px;
flex-wrap: wrap; flex-wrap: wrap;
} }
.ecommerce-standalone .product-clone-page[data-tool="clone"] .clone-ai-canvas-node .clone-ai-result-grid button { .ecommerce-standalone .product-clone-page[data-tool="clone"] .clone-ai-canvas-node .clone-ai-result-item {
width: 140px; width: 140px;
}
.ecommerce-standalone .product-clone-page[data-tool="clone"] .clone-ai-canvas-node .clone-ai-result-item button {
position: relative;
width: 100%;
border-radius: 12px; border-radius: 12px;
overflow: hidden; overflow: hidden;
border: 1px solid rgba(30, 189, 219, 0.12); border: 1px solid rgba(30, 189, 219, 0.12);
@@ -2870,7 +2872,7 @@
transition: border-color 200ms; transition: border-color 200ms;
} }
.ecommerce-standalone .product-clone-page[data-tool="clone"] .clone-ai-canvas-node .clone-ai-result-grid button:hover { .ecommerce-standalone .product-clone-page[data-tool="clone"] .clone-ai-canvas-node .clone-ai-result-item button:hover {
border-color: rgba(30, 189, 219, 0.4); border-color: rgba(30, 189, 219, 0.4);
} }
@@ -2880,21 +2882,31 @@
display: block; display: block;
} }
.ecommerce-standalone .product-clone-page[data-tool="clone"] .clone-ai-canvas-node .clone-ai-result-grid span { .ecommerce-standalone .product-clone-page[data-tool="clone"] .clone-ai-canvas-node .clone-ai-img-tag {
display: block; position: absolute;
text-align: center; top: 6px;
font-size: 11px; right: 6px;
color: #68818f; padding: 2px 7px;
padding: 4px; border-radius: 6px;
background: rgba(24, 28, 33, 0.72);
color: #fff;
font-size: 10px;
font-weight: 600;
line-height: 1.4;
backdrop-filter: blur(4px);
-webkit-backdrop-filter: blur(4px);
pointer-events: none;
} }
.ecommerce-standalone .product-clone-page[data-tool="clone"] .clone-ai-node-label { .ecommerce-standalone .product-clone-page[data-tool="clone"] .clone-ai-node-label {
font-size: 11px; font-size: 11px;
font-weight: 600; font-weight: 600;
color: rgba(30, 189, 219, 0.8); color: rgba(255, 255, 255, 0.92);
background: rgba(30, 189, 219, 0.08); background: rgba(24, 28, 33, 0.72);
padding: 2px 8px; padding: 3px 10px;
border-radius: 8px; border-radius: 8px;
backdrop-filter: blur(4px);
-webkit-backdrop-filter: blur(4px);
} }
.ecommerce-standalone .product-clone-page[data-tool="clone"] .clone-ai-canvas-node.is-generating { .ecommerce-standalone .product-clone-page[data-tool="clone"] .clone-ai-canvas-node.is-generating {
@@ -3572,13 +3584,13 @@
.ecommerce-standalone .product-clone-page[data-tool="clone"] .ecom-command-composer-wrap.has-generated.is-compact .clone-ai-input-wrapper.ecom-command-composer, .ecommerce-standalone .product-clone-page[data-tool="clone"] .ecom-command-composer-wrap.has-generated.is-compact .clone-ai-input-wrapper.ecom-command-composer,
.ecommerce-standalone .product-clone-page[data-tool="clone"] .ecom-command-composer-wrap.has-generated.is-compact .clone-ai-input-wrapper.ecom-command-composer:has(.ecom-command-asset-popover) { .ecommerce-standalone .product-clone-page[data-tool="clone"] .ecom-command-composer-wrap.has-generated.is-compact .clone-ai-input-wrapper.ecom-command-composer:has(.ecom-command-asset-popover) {
grid-template-rows: 44px 22px 34px !important; grid-template-rows: 44px 36px 38px !important;
row-gap: 4px !important; row-gap: 6px !important;
min-height: 118px !important; min-height: 156px !important;
max-height: 126px !important; max-height: 186px !important;
padding: 10px 18px 10px !important; padding: 14px 20px 12px !important;
overflow: visible !important; overflow: visible !important;
border-radius: 22px !important; border-radius: 24px !important;
border: 1px solid rgba(30, 189, 219, 0.14) !important; border: 1px solid rgba(30, 189, 219, 0.14) !important;
background: rgba(254, 255, 255, 0.94) !important; background: rgba(254, 255, 255, 0.94) !important;
box-shadow: box-shadow:
@@ -3617,12 +3629,12 @@
.ecommerce-standalone .product-clone-page[data-tool="clone"] .ecom-command-composer-wrap.has-generated.is-compact .ecom-command-composer textarea, .ecommerce-standalone .product-clone-page[data-tool="clone"] .ecom-command-composer-wrap.has-generated.is-compact .ecom-command-composer textarea,
.ecommerce-standalone .product-clone-page[data-tool="clone"] .ecom-command-composer-wrap.has-generated.is-compact .clone-ai-input-wrapper.ecom-command-composer:has(.ecom-command-asset-popover) > textarea { .ecommerce-standalone .product-clone-page[data-tool="clone"] .ecom-command-composer-wrap.has-generated.is-compact .clone-ai-input-wrapper.ecom-command-composer:has(.ecom-command-asset-popover) > textarea {
grid-row: 2 !important; grid-row: 2 !important;
min-height: 22px !important; min-height: 36px !important;
max-height: 22px !important; max-height: 36px !important;
padding: 0 !important; padding: 6px 0 0 !important;
overflow: hidden !important; overflow: hidden !important;
font-size: 14px !important; font-size: 14px !important;
line-height: 22px !important; line-height: 24px !important;
white-space: nowrap !important; white-space: nowrap !important;
text-overflow: ellipsis !important; text-overflow: ellipsis !important;
} }
@@ -3630,8 +3642,8 @@
.ecommerce-standalone .product-clone-page[data-tool="clone"] .ecom-command-composer-wrap.has-generated.is-compact .ecom-command-toolbar, .ecommerce-standalone .product-clone-page[data-tool="clone"] .ecom-command-composer-wrap.has-generated.is-compact .ecom-command-toolbar,
.ecommerce-standalone .product-clone-page[data-tool="clone"] .ecom-command-composer-wrap.has-generated.is-compact .clone-ai-input-wrapper.ecom-command-composer:has(.ecom-command-asset-popover) .ecom-command-toolbar { .ecommerce-standalone .product-clone-page[data-tool="clone"] .ecom-command-composer-wrap.has-generated.is-compact .clone-ai-input-wrapper.ecom-command-composer:has(.ecom-command-asset-popover) .ecom-command-toolbar {
grid-row: 3 !important; grid-row: 3 !important;
min-height: 34px !important; min-height: 38px !important;
padding-top: 2px !important; padding-top: 4px !important;
} }
.ecommerce-standalone .product-clone-page[data-tool="clone"] .clone-ai-preview[data-status="done"] { .ecommerce-standalone .product-clone-page[data-tool="clone"] .clone-ai-preview[data-status="done"] {
@@ -3885,31 +3897,32 @@
grid-row: 1 !important; grid-row: 1 !important;
z-index: 2 !important; z-index: 2 !important;
align-self: center !important; align-self: center !important;
width: 28px !important; width: 26px !important;
height: 28px !important; height: 26px !important;
min-height: 28px !important; min-height: 26px !important;
margin-right: 6px !important; margin-right: 8px !important;
padding: 0 !important; padding: 0 !important;
border: none !important; border: none !important;
border-radius: 6px !important; border-radius: 7px !important;
color: #99a8b2 !important; color: #8a9aa6 !important;
background: rgba(255, 255, 255, 0.92) !important; background: transparent !important;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08) !important; font-size: 12px !important;
font-size: 13px !important;
cursor: pointer !important; cursor: pointer !important;
opacity: 0 !important; opacity: 0 !important;
transition: opacity 160ms ease, color 120ms ease, background 120ms ease !important; transition: opacity 160ms ease, color 120ms ease, background 120ms ease, transform 120ms ease !important;
pointer-events: none !important; pointer-events: none !important;
} }
.ecommerce-standalone .product-clone-page[data-tool="clone"] .ecom-command-history__item:hover .ecom-command-history__item-delete { .ecommerce-standalone .product-clone-page[data-tool="clone"] .ecom-command-history__item:hover .ecom-command-history__item-delete,
.ecommerce-standalone .product-clone-page[data-tool="clone"] .ecom-command-history__item.is-active .ecom-command-history__item-delete {
opacity: 1 !important; opacity: 1 !important;
pointer-events: auto !important; pointer-events: auto !important;
} }
.ecommerce-standalone .product-clone-page[data-tool="clone"] .ecom-command-history__item .ecom-command-history__item-delete:hover { .ecommerce-standalone .product-clone-page[data-tool="clone"] .ecom-command-history__item .ecom-command-history__item-delete:hover {
color: #ff4d4f !important; color: #ff4d4f !important;
background: rgba(255, 77, 79, 0.1) !important; background: rgba(255, 77, 79, 0.08) !important;
transform: scale(1.1) !important;
} }
.ecommerce-standalone .product-clone-page[data-tool="clone"] .ecom-command-history__item.is-active .ecom-command-history__item-main { .ecommerce-standalone .product-clone-page[data-tool="clone"] .ecom-command-history__item.is-active .ecom-command-history__item-main {
@@ -10731,9 +10744,10 @@ html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[d
} }
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .clone-ai-input-wrapper.ecom-command-composer > .ecom-command-popover.ecom-command-popover--ratio-picker { html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .clone-ai-input-wrapper.ecom-command-composer > .ecom-command-popover.ecom-command-popover--ratio-picker {
grid-template-columns: repeat(auto-fit, minmax(154px, 1fr)) !important; grid-template-columns: repeat(auto-fit, minmax(140px, max-content)) !important;
gap: 8px !important; gap: 8px !important;
width: min(420px, calc(100vw - 56px)) !important; width: max-content !important;
max-width: min(420px, calc(100vw - 56px)) !important;
padding: 10px !important; padding: 10px !important;
border-radius: 18px !important; border-radius: 18px !important;
} }
@@ -10795,6 +10809,33 @@ html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[d
line-height: 1 !important; line-height: 1 !important;
} }
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-popover--ratio-picker button:hover {
background: linear-gradient(135deg, rgba(235, 251, 254, 0.98), rgba(224, 246, 252, 0.88)) !important;
box-shadow:
inset 0 0 0 1px rgba(30, 189, 219, 0.28),
0 6px 16px rgba(16, 115, 204, 0.08) !important;
transform: translateY(-1px) !important;
}
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-popover--ratio-picker button.is-active {
background: linear-gradient(135deg, rgba(226, 249, 253, 0.98), rgba(210, 243, 250, 0.92)) !important;
box-shadow:
inset 0 0 0 1.5px rgba(30, 189, 219, 0.46),
0 8px 20px rgba(16, 115, 204, 0.1) !important;
}
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-popover--ratio-picker button.is-active .ecom-command-ratio-icon {
color: #fff !important;
background: linear-gradient(135deg, #1ebddb, #1073cc) !important;
}
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-popover--ratio-picker button {
transition:
background 160ms ease,
box-shadow 180ms ease,
transform 160ms ease !important;
}
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .clone-ai-send-button.ecom-command-send { html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .clone-ai-send-button.ecom-command-send {
width: 48px !important; width: 48px !important;
height: 48px !important; height: 48px !important;
@@ -11893,11 +11934,11 @@ html body #root .ecommerce-standalone.web-shell .ecom-watermark-workspace {
/* Compact composer override: force small dimensions when is-compact is active, beating all min-height rules. */ /* Compact composer override: force small dimensions when is-compact is active, beating all min-height rules. */
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-composer-wrap.has-generated.is-compact .clone-ai-input-wrapper.ecom-command-composer, html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-composer-wrap.has-generated.is-compact .clone-ai-input-wrapper.ecom-command-composer,
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-composer-wrap.has-generated.is-compact .clone-ai-input-wrapper.ecom-command-composer:has(.ecom-command-asset-popover) { html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-composer-wrap.has-generated.is-compact .clone-ai-input-wrapper.ecom-command-composer:has(.ecom-command-asset-popover) {
min-height: 118px !important; min-height: 156px !important;
max-height: 126px !important; max-height: 186px !important;
} }
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-composer-wrap.has-generated.is-compact .ecom-command-composer textarea { html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"] .ecom-command-composer-wrap.has-generated.is-compact .ecom-command-composer textarea {
min-height: 22px !important; min-height: 36px !important;
max-height: 22px !important; max-height: 36px !important;
} }