fix(core): 测试清单 行4-15 — 记住我7天/工作台布局/商品创建选择弹窗/上传图持久化/清空筛选
- 记住我7天:勾选才持久化token+预填用户名,7天过期强制重登(localStorage vs sessionStorage) - 工作台:最近项目进度/状态列对齐、快捷&提示卡片圆角边框、余额按钮金额左对齐 - 商品创建成功改为复用弹窗,选择 继续创建/去新建项目;主图随创建上传持久化 - 商品卡显示真实主图、点视频进详情视频项目tab - 商品库/视频项目补 清空筛选 按钮 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -461,7 +461,8 @@ export function ImageWorkbenchPage({
|
||||
modelConfigs,
|
||||
onBack,
|
||||
navigate,
|
||||
onGenerate
|
||||
onGenerate,
|
||||
onResume
|
||||
}: {
|
||||
mode: WorkMode;
|
||||
products: Product[];
|
||||
@@ -470,6 +471,7 @@ export function ImageWorkbenchPage({
|
||||
onBack: () => void;
|
||||
navigate?: (page: Page) => void;
|
||||
onGenerate: (payload: { prompt: string; mode?: "image" | "model" | "cover"; count?: number }) => Promise<{ assets: Asset[] } | null>;
|
||||
onResume?: (mode: "image" | "model" | "cover", ids: string[]) => Promise<{ assets: Asset[] } | null>;
|
||||
}) {
|
||||
const meta = MODE_META[mode];
|
||||
const [productId, setProductId] = useState(products[0]?.id || "");
|
||||
@@ -532,6 +534,37 @@ export function ImageWorkbenchPage({
|
||||
}
|
||||
}
|
||||
|
||||
/* 跨刷新恢复:读本地残留(由 App.generateImages 落盘),先回显已出的图,
|
||||
再对还在跑的任务继续轮询——刷新页面不再丢"生成中"与已出结果。 */
|
||||
useEffect(() => {
|
||||
let cancelled = false;
|
||||
try {
|
||||
const raw = localStorage.getItem(`airshelf:imgwb:${mode}`);
|
||||
if (!raw) return;
|
||||
const saved = JSON.parse(raw) as { pending?: string[]; results?: Asset[]; ts?: number };
|
||||
if (saved.ts && Date.now() - saved.ts > 60 * 60 * 1000) return; // 1 小时前的残留不恢复
|
||||
if (saved.results && saved.results.length) setResults(saved.results);
|
||||
const pending = saved.pending || [];
|
||||
if (pending.length && onResume) {
|
||||
setGenerating(true);
|
||||
onResume(mode, pending)
|
||||
.then((res) => {
|
||||
if (!cancelled && res?.assets) setResults(res.assets);
|
||||
})
|
||||
.finally(() => {
|
||||
if (!cancelled) setGenerating(false);
|
||||
});
|
||||
}
|
||||
} catch {
|
||||
/* 残留解析失败则忽略,按初始态渲染 */
|
||||
}
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
// 仅在挂载/切换 mode 时恢复一次
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [mode]);
|
||||
|
||||
const hasResults = !!(results && results.length > 0);
|
||||
|
||||
/* ── 共享:生成结果网格(§4.18 .gen-card · 三 mode 统一渲染真图)── */
|
||||
@@ -1002,15 +1035,15 @@ export function ImageWorkbenchPage({
|
||||
</div>
|
||||
<div className="gen-card">{renderResultGrid()}</div>
|
||||
<div className="gen-card-actions">
|
||||
<button className="btn btn-sm" type="button">
|
||||
<button className="btn btn-sm" type="button" disabled={generating} onClick={() => runGenerate()}>
|
||||
<RefreshCw size={13} />
|
||||
重跑
|
||||
</button>
|
||||
<button className="btn btn-sm" type="button">
|
||||
<button className="btn btn-sm" type="button" onClick={() => navigate?.("library")}>
|
||||
<Check size={13} />
|
||||
采用并入资产库
|
||||
</button>
|
||||
<button className="btn btn-sm btn-ghost" type="button" title="更多">
|
||||
<button className="btn btn-sm btn-ghost" type="button" title="下载全部" onClick={() => results?.forEach((asset, i) => { const u = asset.files?.[0]?.preview_url; if (u) downloadImage(u, `${meta.title}-${i + 1}.png`); })}>
|
||||
<MoreHorizontal size={13} />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user