fix(core): 测试清单 行16-33 — 商品详情/视频项目/新建向导/图片生成 批量修复
商品库+详情(行16-23):AI素材空状态缺省页;三视图16:9+版本历史切换+采用按钮; 详情「生成视频」预勾选商品、快捷生成图带入商品;管理商品编辑态保留底部统计; 删除商品 icon+DELETE ITEM 文案、乐观删除防重复点击;卡片图铺满占位区。 视频项目+新建向导(行24-28):筛选脚本来源按真实数据渲染;新建项目内「创建新商品」 右侧抽屉+创建后自动选中;开始栏 sticky 常驻;默认选中商品即显示卖点、未填完禁用开始; 去掉脚本风格/人物设定区块。 图片生成工作台(行29-33):模特单选;生成中改 spinner 动态图标+按钮间距;多任务并行; 重跑追加批次而非覆盖+更多按钮 hover 气泡菜单+「加入资产库/取消」切换与提示弹窗; 多批次本地持久化恢复。 收尾:App.tsx 接 initialProductId/preselectProductId/onCreateProduct/onAdoptTriView; 全局 toast 自动消失(成功3s/错误5s)修复行17③/22「右上角提示一直挂着」。 tsc -b && vite build 通过。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -121,6 +121,13 @@ export function App() {
|
||||
const [notice, setNotice] = useState<Notice>(null);
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
// 右上角 toast 自动消失:成功/信息 3s,错误 5s(此前 notice 不会自己清,导致「提示一直挂着」)
|
||||
useEffect(() => {
|
||||
if (!notice) return;
|
||||
const timer = setTimeout(() => setNotice(null), notice.type === "error" ? 5000 : 3000);
|
||||
return () => clearTimeout(timer);
|
||||
}, [notice]);
|
||||
|
||||
const activeProject = useMemo(
|
||||
() => projects.find((project) => project.id === activeProjectId) || projects[0],
|
||||
[projects, activeProjectId]
|
||||
@@ -535,6 +542,7 @@ export function App() {
|
||||
onUploadImage={(formData) => action(() => api.uploadProductImage(activeProduct.id, formData), "商品图已上传")}
|
||||
onDeleteImage={(imageId) => action(() => api.deleteProductImage(activeProduct.id, imageId), "商品图已移除")}
|
||||
onGenerateImages={generateImages}
|
||||
onAdoptTriView={(asset) => action(() => api.updateProduct(activeProduct.id, { cover_asset: asset.id }), "三视图已采用为商品图")}
|
||||
/>
|
||||
);
|
||||
case "projects":
|
||||
@@ -553,11 +561,13 @@ export function App() {
|
||||
<ProjectWizardPage
|
||||
products={products}
|
||||
projects={projects}
|
||||
preselectProductId={activeProductId}
|
||||
onBack={() => navigate("projects")}
|
||||
onCreate={async (payload) => {
|
||||
const created = await action(() => api.createProject(payload), "项目已创建");
|
||||
if (created) navigate("pipeline", { projectId: created.id });
|
||||
}}
|
||||
onCreateProduct={(payload) => action(() => api.createProduct(payload), "")}
|
||||
/>
|
||||
);
|
||||
case "pipeline":
|
||||
@@ -618,11 +628,11 @@ export function App() {
|
||||
case "assetFactory":
|
||||
return <AssetFactoryPage navigate={navigate} aiTasks={aiTasks} assets={assets} />;
|
||||
case "imageOptimize":
|
||||
return <ImageWorkbenchPage mode="image" products={products} assets={assets} modelConfigs={modelConfigs} onBack={() => navigate("assetFactory")} navigate={navigate} onGenerate={generateImages} onResume={resumeImages} />;
|
||||
return <ImageWorkbenchPage mode="image" products={products} assets={assets} modelConfigs={modelConfigs} initialProductId={activeProductId} onBack={() => navigate("assetFactory")} navigate={navigate} onGenerate={generateImages} onResume={resumeImages} />;
|
||||
case "modelPhoto":
|
||||
return <ImageWorkbenchPage mode="model" products={products} assets={assets} modelConfigs={modelConfigs} onBack={() => navigate("assetFactory")} navigate={navigate} onGenerate={generateImages} onResume={resumeImages} />;
|
||||
return <ImageWorkbenchPage mode="model" products={products} assets={assets} modelConfigs={modelConfigs} initialProductId={activeProductId} onBack={() => navigate("assetFactory")} navigate={navigate} onGenerate={generateImages} onResume={resumeImages} />;
|
||||
case "platformCover":
|
||||
return <ImageWorkbenchPage mode="cover" products={products} assets={assets} modelConfigs={modelConfigs} onBack={() => navigate("assetFactory")} navigate={navigate} onGenerate={generateImages} onResume={resumeImages} />;
|
||||
return <ImageWorkbenchPage mode="cover" products={products} assets={assets} modelConfigs={modelConfigs} initialProductId={activeProductId} onBack={() => navigate("assetFactory")} navigate={navigate} onGenerate={generateImages} onResume={resumeImages} />;
|
||||
case "modelPhotoDemoA":
|
||||
return <ModelPhotoDemoPage variant="A" products={products} onBack={() => navigate("modelPhoto")} navigate={navigate} />;
|
||||
case "modelPhotoDemoB":
|
||||
|
||||
Reference in New Issue
Block a user