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
+19 -10
View File
@@ -981,9 +981,9 @@ const cloneSetCountOptions: Array<{
];
const cloneSetCountKeys = cloneSetCountOptions.map((option) => option.key);
const defaultCloneSetCounts: Record<CloneSetCountKey, number> = {
selling: 3,
selling: 1,
white: 1,
scene: 3,
scene: 1,
};
const minCloneSetTotal = 1;
const maxCloneSetTotal = 16;
@@ -1674,9 +1674,9 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
const [selectedScenes, setSelectedScenes] = useState<string[]>([]);
useEffect(() => {
if (status === "done") {
if (status === "done" || status === "generating") {
setIsCommandComposerCompact(true);
} else if (status === "generating" || status === "idle") {
} else if (status === "idle") {
setIsCommandComposerCompact(false);
}
}, [status]);
@@ -2623,6 +2623,12 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
if (next.length === 0) {
setStatus("idle");
setResults([]);
setCanvasNodes([]);
setIsCommandComposerCompact(false);
setPreviewOffset({ x: 0, y: 0 });
previewOffsetRef.current = { x: 0, y: 0 };
setPreviewZoom(1);
setActiveHistoryRecordId(null);
}
return next;
});
@@ -3013,7 +3019,7 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
const composer = commandComposerWrapRef.current;
if (composer?.contains(target)) return;
if (composerMenu && composerMenu !== "settings") setComposerMenu(null);
if (composerMenu) setComposerMenu(null);
if (status === "done" && !isCommandComposerCompact) setIsCommandComposerCompact(true);
};
@@ -3629,6 +3635,7 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
setDetailRequirement("");
setSelectedDetailModules(defaultDetailModuleIds);
setDetailStatus("idle");
setIsCommandComposerCompact(false);
};
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>
{node.sourceImage ? (
<div className="clone-ai-main-result-wrap">
<button
type="button"
className="clone-ai-main-result"
onClick={() => openProductSetPreview({ src: node.sourceImage!, label: "原图素材" })}
>
<img src={node.sourceImage} alt="原图素材" />
<span></span>
<span className="clone-ai-img-tag"></span>
</button>
</div>
) : null}
<div className="clone-ai-flow-arrow" aria-hidden="true" />
<div className="clone-ai-result-grid result-reveal">
{node.results.map((card) => (
<button key={card.id} type="button" style={{ aspectRatio: parseRatioToAspectCss(ratio) }} onClick={() => openProductSetPreview(card)}>
{node.results.map((card, cardIndex) => (
<div key={card.id} className="clone-ai-result-item">
<button type="button" style={{ aspectRatio: parseRatioToAspectCss(ratio) }} onClick={() => openProductSetPreview(card)}>
<img src={card.src} alt={card.label} />
<span>{card.label}</span>
</button>
</div>
))}
</div>
</article>
+92 -51
View File
@@ -2830,9 +2830,14 @@
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;
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;
overflow: hidden;
border: 1px solid rgba(30, 189, 219, 0.12);
@@ -2846,22 +2851,19 @@
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 {
display: flex;
gap: 12px;
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;
}
.ecommerce-standalone .product-clone-page[data-tool="clone"] .clone-ai-canvas-node .clone-ai-result-item button {
position: relative;
width: 100%;
border-radius: 12px;
overflow: hidden;
border: 1px solid rgba(30, 189, 219, 0.12);
@@ -2870,7 +2872,7 @@
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);
}
@@ -2880,21 +2882,31 @@
display: block;
}
.ecommerce-standalone .product-clone-page[data-tool="clone"] .clone-ai-canvas-node .clone-ai-result-grid 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-img-tag {
position: absolute;
top: 6px;
right: 6px;
padding: 2px 7px;
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 {
font-size: 11px;
font-weight: 600;
color: rgba(30, 189, 219, 0.8);
background: rgba(30, 189, 219, 0.08);
padding: 2px 8px;
color: rgba(255, 255, 255, 0.92);
background: rgba(24, 28, 33, 0.72);
padding: 3px 10px;
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 {
@@ -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:has(.ecom-command-asset-popover) {
grid-template-rows: 44px 22px 34px !important;
row-gap: 4px !important;
min-height: 118px !important;
max-height: 126px !important;
padding: 10px 18px 10px !important;
grid-template-rows: 44px 36px 38px !important;
row-gap: 6px !important;
min-height: 156px !important;
max-height: 186px !important;
padding: 14px 20px 12px !important;
overflow: visible !important;
border-radius: 22px !important;
border-radius: 24px !important;
border: 1px solid rgba(30, 189, 219, 0.14) !important;
background: rgba(254, 255, 255, 0.94) !important;
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 .clone-ai-input-wrapper.ecom-command-composer:has(.ecom-command-asset-popover) > textarea {
grid-row: 2 !important;
min-height: 22px !important;
max-height: 22px !important;
padding: 0 !important;
min-height: 36px !important;
max-height: 36px !important;
padding: 6px 0 0 !important;
overflow: hidden !important;
font-size: 14px !important;
line-height: 22px !important;
line-height: 24px !important;
white-space: nowrap !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 .clone-ai-input-wrapper.ecom-command-composer:has(.ecom-command-asset-popover) .ecom-command-toolbar {
grid-row: 3 !important;
min-height: 34px !important;
padding-top: 2px !important;
min-height: 38px !important;
padding-top: 4px !important;
}
.ecommerce-standalone .product-clone-page[data-tool="clone"] .clone-ai-preview[data-status="done"] {
@@ -3885,31 +3897,32 @@
grid-row: 1 !important;
z-index: 2 !important;
align-self: center !important;
width: 28px !important;
height: 28px !important;
min-height: 28px !important;
margin-right: 6px !important;
width: 26px !important;
height: 26px !important;
min-height: 26px !important;
margin-right: 8px !important;
padding: 0 !important;
border: none !important;
border-radius: 6px !important;
color: #99a8b2 !important;
background: rgba(255, 255, 255, 0.92) !important;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08) !important;
font-size: 13px !important;
border-radius: 7px !important;
color: #8a9aa6 !important;
background: transparent !important;
font-size: 12px !important;
cursor: pointer !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;
}
.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;
pointer-events: auto !important;
}
.ecommerce-standalone .product-clone-page[data-tool="clone"] .ecom-command-history__item .ecom-command-history__item-delete:hover {
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 {
@@ -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 {
grid-template-columns: repeat(auto-fit, minmax(154px, 1fr)) !important;
grid-template-columns: repeat(auto-fit, minmax(140px, max-content)) !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;
border-radius: 18px !important;
}
@@ -10795,6 +10809,33 @@ html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[d
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 {
width: 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. */
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) {
min-height: 118px !important;
max-height: 126px !important;
min-height: 156px !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 {
min-height: 22px !important;
max-height: 22px !important;
min-height: 36px !important;
max-height: 36px !important;
}