fix(ecommerce): show generated images in all tool previews

The set/detail preview areas were using static placeholder images
instead of the API-generated results. Fix:

- Add productSetResultImages state for set tool results
- Add detailResultUrl state for detail tool results
- Create setPreviewCards (like clonePreviewCards) that overlays
  generated URLs onto static card templates
- Replace setPreview JSX references from productSetPreviewCards
  to setPreviewCards so generated URLs are displayed
- Replace detailPreview longPage image with detailResultUrl fallback
- Update handleSetGenerate setResultFn to save URLs via
  setProductSetResultImages
- Update handleDetailGenerate setResultFn to save URL via
  setDetailResultUrl

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-06-02 21:31:43 +08:00
parent b07ff439f3
commit 51b711226e
+13 -7
View File
@@ -773,6 +773,7 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
const [productSetRequirement, setProductSetRequirement] = useState("");
const [productSetOutput, setProductSetOutput] = useState<ProductSetOutputKey>("video");
const [productSetStatus, setProductSetStatus] = useState<ProductSetStatus>("idle");
const [productSetResultImages, setProductSetResultImages] = useState<string[]>([]);
const [isSetUploadDragging, setIsSetUploadDragging] = useState(false);
const [selectedProductSetPreview, setSelectedProductSetPreview] = useState<{ src: string; label: string } | null>(null);
const [showHostingModal, setShowHostingModal] = useState(false);
@@ -843,6 +844,7 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
const [detailRequirement, setDetailRequirement] = useState("");
const [selectedDetailModules, setSelectedDetailModules] = useState<string[]>(defaultDetailModuleIds);
const [detailStatus, setDetailStatus] = useState<DetailStatus>("idle");
const [detailResultUrl, setDetailResultUrl] = useState<string | null>(null);
const productSetRatioOptions = getPlatformRatioOptions(productSetPlatform, productSetOutput);
const hotUploadedRatioOption = cloneOutput === "hot" ? formatUploadedImageRatio(cloneReferenceImages[0]) : null;
const baseCloneRatioOptions = getPlatformRatioOptions(platform, cloneOutput);
@@ -1705,7 +1707,7 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
"set", setImages, productSetRequirement,
productSetPlatform, productSetRatio, productSetLanguage, productSetMarket,
(s) => setProductSetStatus(s as ProductSetStatus),
(res) => { setProductSetStatus("done"); },
(res) => setProductSetResultImages(res.map((r) => r.src).filter(Boolean)),
);
};
@@ -1726,7 +1728,7 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
"detail", detailProductImages, detailRequirement,
detailPlatform, getPlatformDefaultRatio(detailPlatform), detailLanguage, detailMarket,
(s) => setDetailStatus(s as DetailStatus),
(res) => { setDetailStatus("done"); },
(res) => setDetailResultUrl(res[0]?.src ?? null),
);
};
@@ -1795,6 +1797,10 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
detailProductImages.length === 0 ? "请上传产品图" : detailStatus === "generating" ? "生成中..." : "生成A+详情页";
const clonePrimaryLabel =
productImages.length === 0 ? "请先上传商品原图" : status === "generating" ? "生成中..." : `生成${selectedCloneOutput.label}`;
const setPreviewCards = productSetPreviewCards.map((card, index) => ({
...card,
src: productSetResultImages[index] ?? card.src,
}));
const clonePreviewCards = productSetPreviewCards.map((card, index) => ({
...card,
src: results[index]?.src ?? card.src,
@@ -2717,14 +2723,14 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
<button
type="button"
className="product-set-main-card"
onClick={() => openProductSetPreview(productSetPreviewCards[0])}
onClick={() => openProductSetPreview(setPreviewCards[0])}
>
<img src={productSetPreviewCards[0].src} alt="01 主图" />
<span>{productSetPreviewCards[0].label}</span>
<img src={setPreviewCards[0].src} alt="01 主图" />
<span>{setPreviewCards[0].label}</span>
</button>
<div className="product-set-flow-arrow" aria-hidden="true" />
<div className="product-set-card-grid result-reveal">
{productSetPreviewCards.slice(1).map((card) => (
{setPreviewCards.slice(1).map((card) => (
<button key={card.id} type="button" onClick={() => openProductSetPreview(card)}>
<img src={card.src} alt={card.label} />
<span>{card.label}</span>
@@ -2854,7 +2860,7 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
</div>
<div className="product-detail-flow-arrow" aria-hidden="true" />
<div className="product-detail-long-result">
<img src={detailAssets.longPage} alt="生成电商长图" />
<img src={detailResultUrl ?? detailAssets.longPage} alt="生成电商长图" />
<span>{detailStatus === "done" ? "已生成电商长图" : "生成电商长图"}</span>
</div>
<div className="product-detail-grid-result">