2026-06-03 23:20:57 +08:00
|
|
|
|
import { CloudUploadOutlined, LoadingOutlined, QuestionCircleOutlined } from "@ant-design/icons";
|
|
|
|
|
|
import type { ChangeEvent, RefObject } from "react";
|
|
|
|
|
|
import { EcommerceProgressBar } from "../EcommerceProgressBar";
|
|
|
|
|
|
|
|
|
|
|
|
interface EcommerceDetailPanelProps {
|
|
|
|
|
|
detailInputRef: RefObject<HTMLInputElement>;
|
|
|
|
|
|
detailProductImages: Array<{ id: string; src: string; name: string }>;
|
|
|
|
|
|
detailPlatform: string;
|
|
|
|
|
|
detailMarket: string;
|
|
|
|
|
|
detailLanguage: string;
|
|
|
|
|
|
detailType: string;
|
|
|
|
|
|
detailRequirement: string;
|
|
|
|
|
|
selectedDetailModules: string[];
|
|
|
|
|
|
detailStatus: string;
|
|
|
|
|
|
canGenerateDetail: boolean;
|
|
|
|
|
|
detailPrimaryLabel: string;
|
|
|
|
|
|
platformOptions: string[];
|
|
|
|
|
|
marketOptions: string[];
|
|
|
|
|
|
detailLanguageOptions: string[];
|
|
|
|
|
|
detailTypeOptions: string[];
|
|
|
|
|
|
detailModules: Array<{ id: string; title: string; desc: string }>;
|
|
|
|
|
|
handleDetailUpload: (event: ChangeEvent<HTMLInputElement>) => void;
|
|
|
|
|
|
handleDetailPlatformChange: (value: string) => void;
|
|
|
|
|
|
handleDetailMarketChange: (value: string) => void;
|
|
|
|
|
|
setDetailLanguage: (value: string) => void;
|
|
|
|
|
|
setDetailType: (value: string) => void;
|
|
|
|
|
|
setDetailRequirement: (value: string) => void;
|
|
|
|
|
|
handleDetailAiWrite: () => void;
|
|
|
|
|
|
toggleDetailModule: (id: string) => void;
|
|
|
|
|
|
handleDetailGenerate: () => void;
|
2026-06-05 00:37:38 +08:00
|
|
|
|
onCancelGenerate: () => void;
|
2026-06-03 23:20:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export default function EcommerceDetailPanel({
|
|
|
|
|
|
detailInputRef,
|
|
|
|
|
|
detailProductImages,
|
|
|
|
|
|
detailPlatform,
|
|
|
|
|
|
detailMarket,
|
|
|
|
|
|
detailLanguage,
|
|
|
|
|
|
detailType,
|
|
|
|
|
|
detailRequirement,
|
|
|
|
|
|
selectedDetailModules,
|
|
|
|
|
|
detailStatus,
|
|
|
|
|
|
canGenerateDetail,
|
|
|
|
|
|
detailPrimaryLabel,
|
|
|
|
|
|
platformOptions,
|
|
|
|
|
|
marketOptions,
|
|
|
|
|
|
detailLanguageOptions,
|
|
|
|
|
|
detailTypeOptions,
|
|
|
|
|
|
detailModules,
|
|
|
|
|
|
handleDetailUpload,
|
|
|
|
|
|
handleDetailPlatformChange,
|
|
|
|
|
|
handleDetailMarketChange,
|
|
|
|
|
|
setDetailLanguage,
|
|
|
|
|
|
setDetailType,
|
|
|
|
|
|
setDetailRequirement,
|
|
|
|
|
|
handleDetailAiWrite,
|
|
|
|
|
|
toggleDetailModule,
|
|
|
|
|
|
handleDetailGenerate,
|
2026-06-05 00:37:38 +08:00
|
|
|
|
onCancelGenerate,
|
2026-06-03 23:20:57 +08:00
|
|
|
|
}: EcommerceDetailPanelProps) {
|
|
|
|
|
|
return (
|
|
|
|
|
|
<>
|
|
|
|
|
|
<div className="product-clone-panel__scroll">
|
|
|
|
|
|
<section className="product-clone-field">
|
|
|
|
|
|
<h2>
|
|
|
|
|
|
商品原图
|
|
|
|
|
|
<QuestionCircleOutlined />
|
|
|
|
|
|
</h2>
|
|
|
|
|
|
<button type="button" className="product-clone-upload-zone product-detail-upload" onClick={() => detailInputRef.current?.click()}>
|
|
|
|
|
|
<strong>
|
|
|
|
|
|
<CloudUploadOutlined />
|
|
|
|
|
|
上传图片
|
|
|
|
|
|
</strong>
|
|
|
|
|
|
<span>同一产品,最多3张。</span>
|
|
|
|
|
|
</button>
|
|
|
|
|
|
<input ref={detailInputRef} type="file" accept="image/*" multiple onChange={handleDetailUpload} />
|
|
|
|
|
|
{detailProductImages.length ? (
|
|
|
|
|
|
<div className="product-clone-thumb-row" aria-label="已上传商品原图">
|
|
|
|
|
|
{detailProductImages.map((item) => (
|
|
|
|
|
|
<figure key={item.id} className="product-clone-uploaded-thumb">
|
|
|
|
|
|
<img src={item.src} alt={item.name} />
|
|
|
|
|
|
<span className="uploaded-image-zoom" aria-hidden="true">
|
|
|
|
|
|
<img src={item.src} alt="" />
|
|
|
|
|
|
</span>
|
|
|
|
|
|
</figure>
|
|
|
|
|
|
))}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
) : null}
|
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
|
|
<section className="product-clone-field">
|
|
|
|
|
|
<h2>生成设置</h2>
|
|
|
|
|
|
<div className="product-detail-settings-grid">
|
|
|
|
|
|
<select value={detailPlatform} onChange={(event) => handleDetailPlatformChange(event.target.value)}>
|
|
|
|
|
|
{platformOptions.map((item) => (
|
|
|
|
|
|
<option key={item}>{item}</option>
|
|
|
|
|
|
))}
|
|
|
|
|
|
</select>
|
|
|
|
|
|
<select value={detailMarket} onChange={(event) => handleDetailMarketChange(event.target.value)}>
|
|
|
|
|
|
{marketOptions.map((item) => (
|
|
|
|
|
|
<option key={item}>{item}</option>
|
|
|
|
|
|
))}
|
|
|
|
|
|
</select>
|
|
|
|
|
|
<select value={detailLanguage} onChange={(event) => setDetailLanguage(event.target.value)}>
|
|
|
|
|
|
{detailLanguageOptions.map((item) => (
|
|
|
|
|
|
<option key={item}>{item}</option>
|
|
|
|
|
|
))}
|
|
|
|
|
|
</select>
|
|
|
|
|
|
<select value={detailType} onChange={(event) => setDetailType(event.target.value)}>
|
|
|
|
|
|
{detailTypeOptions.map((item) => (
|
|
|
|
|
|
<option key={item}>{item}</option>
|
|
|
|
|
|
))}
|
|
|
|
|
|
</select>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
|
|
<section className="product-clone-field product-detail-requirement">
|
|
|
|
|
|
<h2>
|
|
|
|
|
|
商品卖点&要求
|
|
|
|
|
|
<QuestionCircleOutlined />
|
|
|
|
|
|
<button
|
|
|
|
|
|
type="button"
|
|
|
|
|
|
onClick={(event) => {
|
|
|
|
|
|
event.preventDefault();
|
|
|
|
|
|
event.stopPropagation();
|
|
|
|
|
|
handleDetailAiWrite();
|
|
|
|
|
|
}}
|
|
|
|
|
|
>
|
|
|
|
|
|
AI 帮写
|
|
|
|
|
|
</button>
|
|
|
|
|
|
</h2>
|
|
|
|
|
|
<textarea
|
|
|
|
|
|
value={detailRequirement}
|
|
|
|
|
|
onChange={(event) => setDetailRequirement(event.target.value)}
|
|
|
|
|
|
placeholder={"建议包含以下信息生成更精准:\n1.产品名称\n2.核心卖点\n3.适用人群\n4.期望场景\n5.具体参数"}
|
|
|
|
|
|
/>
|
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
|
|
<section className="product-clone-field">
|
|
|
|
|
|
<h2>
|
|
|
|
|
|
包含模块(多选)
|
|
|
|
|
|
<QuestionCircleOutlined />
|
|
|
|
|
|
</h2>
|
|
|
|
|
|
<div className="product-detail-module-grid">
|
|
|
|
|
|
{detailModules.map((module) => (
|
|
|
|
|
|
<button
|
|
|
|
|
|
key={module.id}
|
|
|
|
|
|
type="button"
|
|
|
|
|
|
className={selectedDetailModules.includes(module.id) ? "is-active" : ""}
|
|
|
|
|
|
onClick={() => toggleDetailModule(module.id)}
|
|
|
|
|
|
>
|
|
|
|
|
|
<strong>{module.title}</strong>
|
|
|
|
|
|
<span>{module.desc}</span>
|
|
|
|
|
|
</button>
|
|
|
|
|
|
))}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</section>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<footer className="product-clone-panel__footer">
|
|
|
|
|
|
{detailStatus === "generating" ? <EcommerceProgressBar status="generating" label="A+详情页" /> : null}
|
|
|
|
|
|
<button type="button" className="product-clone-primary" disabled={!canGenerateDetail} onClick={handleDetailGenerate}>
|
|
|
|
|
|
{detailStatus === "generating" ? <LoadingOutlined /> : null}
|
|
|
|
|
|
{detailPrimaryLabel}
|
|
|
|
|
|
</button>
|
2026-06-05 00:37:38 +08:00
|
|
|
|
{detailStatus === "generating" ? (
|
|
|
|
|
|
<button type="button" className="product-clone-primary product-clone-primary--cancel" onClick={onCancelGenerate}>
|
|
|
|
|
|
{"\u53d6\u6d88\u751f\u6210"}
|
|
|
|
|
|
</button>
|
|
|
|
|
|
) : null}
|
2026-06-03 23:20:57 +08:00
|
|
|
|
</footer>
|
|
|
|
|
|
</>
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|