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:
@@ -773,6 +773,7 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
|||||||
const [productSetRequirement, setProductSetRequirement] = useState("");
|
const [productSetRequirement, setProductSetRequirement] = useState("");
|
||||||
const [productSetOutput, setProductSetOutput] = useState<ProductSetOutputKey>("video");
|
const [productSetOutput, setProductSetOutput] = useState<ProductSetOutputKey>("video");
|
||||||
const [productSetStatus, setProductSetStatus] = useState<ProductSetStatus>("idle");
|
const [productSetStatus, setProductSetStatus] = useState<ProductSetStatus>("idle");
|
||||||
|
const [productSetResultImages, setProductSetResultImages] = useState<string[]>([]);
|
||||||
const [isSetUploadDragging, setIsSetUploadDragging] = useState(false);
|
const [isSetUploadDragging, setIsSetUploadDragging] = useState(false);
|
||||||
const [selectedProductSetPreview, setSelectedProductSetPreview] = useState<{ src: string; label: string } | null>(null);
|
const [selectedProductSetPreview, setSelectedProductSetPreview] = useState<{ src: string; label: string } | null>(null);
|
||||||
const [showHostingModal, setShowHostingModal] = useState(false);
|
const [showHostingModal, setShowHostingModal] = useState(false);
|
||||||
@@ -843,6 +844,7 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
|||||||
const [detailRequirement, setDetailRequirement] = useState("");
|
const [detailRequirement, setDetailRequirement] = useState("");
|
||||||
const [selectedDetailModules, setSelectedDetailModules] = useState<string[]>(defaultDetailModuleIds);
|
const [selectedDetailModules, setSelectedDetailModules] = useState<string[]>(defaultDetailModuleIds);
|
||||||
const [detailStatus, setDetailStatus] = useState<DetailStatus>("idle");
|
const [detailStatus, setDetailStatus] = useState<DetailStatus>("idle");
|
||||||
|
const [detailResultUrl, setDetailResultUrl] = useState<string | null>(null);
|
||||||
const productSetRatioOptions = getPlatformRatioOptions(productSetPlatform, productSetOutput);
|
const productSetRatioOptions = getPlatformRatioOptions(productSetPlatform, productSetOutput);
|
||||||
const hotUploadedRatioOption = cloneOutput === "hot" ? formatUploadedImageRatio(cloneReferenceImages[0]) : null;
|
const hotUploadedRatioOption = cloneOutput === "hot" ? formatUploadedImageRatio(cloneReferenceImages[0]) : null;
|
||||||
const baseCloneRatioOptions = getPlatformRatioOptions(platform, cloneOutput);
|
const baseCloneRatioOptions = getPlatformRatioOptions(platform, cloneOutput);
|
||||||
@@ -1705,7 +1707,7 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
|||||||
"set", setImages, productSetRequirement,
|
"set", setImages, productSetRequirement,
|
||||||
productSetPlatform, productSetRatio, productSetLanguage, productSetMarket,
|
productSetPlatform, productSetRatio, productSetLanguage, productSetMarket,
|
||||||
(s) => setProductSetStatus(s as ProductSetStatus),
|
(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,
|
"detail", detailProductImages, detailRequirement,
|
||||||
detailPlatform, getPlatformDefaultRatio(detailPlatform), detailLanguage, detailMarket,
|
detailPlatform, getPlatformDefaultRatio(detailPlatform), detailLanguage, detailMarket,
|
||||||
(s) => setDetailStatus(s as DetailStatus),
|
(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+详情页";
|
detailProductImages.length === 0 ? "请上传产品图" : detailStatus === "generating" ? "生成中..." : "生成A+详情页";
|
||||||
const clonePrimaryLabel =
|
const clonePrimaryLabel =
|
||||||
productImages.length === 0 ? "请先上传商品原图" : status === "generating" ? "生成中..." : `生成${selectedCloneOutput.label}`;
|
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) => ({
|
const clonePreviewCards = productSetPreviewCards.map((card, index) => ({
|
||||||
...card,
|
...card,
|
||||||
src: results[index]?.src ?? card.src,
|
src: results[index]?.src ?? card.src,
|
||||||
@@ -2717,14 +2723,14 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
|||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="product-set-main-card"
|
className="product-set-main-card"
|
||||||
onClick={() => openProductSetPreview(productSetPreviewCards[0])}
|
onClick={() => openProductSetPreview(setPreviewCards[0])}
|
||||||
>
|
>
|
||||||
<img src={productSetPreviewCards[0].src} alt="01 主图" />
|
<img src={setPreviewCards[0].src} alt="01 主图" />
|
||||||
<span>{productSetPreviewCards[0].label}</span>
|
<span>{setPreviewCards[0].label}</span>
|
||||||
</button>
|
</button>
|
||||||
<div className="product-set-flow-arrow" aria-hidden="true" />
|
<div className="product-set-flow-arrow" aria-hidden="true" />
|
||||||
<div className="product-set-card-grid result-reveal">
|
<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)}>
|
<button key={card.id} type="button" onClick={() => openProductSetPreview(card)}>
|
||||||
<img src={card.src} alt={card.label} />
|
<img src={card.src} alt={card.label} />
|
||||||
<span>{card.label}</span>
|
<span>{card.label}</span>
|
||||||
@@ -2854,7 +2860,7 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
|||||||
</div>
|
</div>
|
||||||
<div className="product-detail-flow-arrow" aria-hidden="true" />
|
<div className="product-detail-flow-arrow" aria-hidden="true" />
|
||||||
<div className="product-detail-long-result">
|
<div className="product-detail-long-result">
|
||||||
<img src={detailAssets.longPage} alt="生成电商长图" />
|
<img src={detailResultUrl ?? detailAssets.longPage} alt="生成电商长图" />
|
||||||
<span>{detailStatus === "done" ? "已生成电商长图" : "生成电商长图"}</span>
|
<span>{detailStatus === "done" ? "已生成电商长图" : "生成电商长图"}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="product-detail-grid-result">
|
<div className="product-detail-grid-result">
|
||||||
|
|||||||
Reference in New Issue
Block a user