From e6e3c48524c0d7f75d6484d02405bef6b365a1b9 Mon Sep 17 00:00:00 2001 From: zyc <1439655764@qq.com> Date: Sat, 27 Jun 2026 17:15:04 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20PMC=20=E5=9B=BE=E7=89=87=E5=B7=A5?= =?UTF-8?q?=E4=BD=9C=E5=8F=B0=20=E2=80=94=20=E5=8E=BB=E5=A4=9A=E4=BD=99toa?= =?UTF-8?q?st=20+=20=E8=B4=B9=E7=94=A8=E9=A2=84=E4=BC=B0=E5=AF=B9=E9=BD=90?= =?UTF-8?q?=E5=AE=9E=E6=89=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PMC#23 删除批次后仍弹「图片已生成」: - 生图成功不再弹全局 toast(批次卡已就地显示结果),也就不会在「生成中删掉该批次」后 延迟弹出让人误以为删了又生成。 PMC#20 费用预估跟实扣有差别: - 预估由写死的 ¥0.1/¥0.3/¥0.5 改为按「当前选的生图模型」真实 unit_price 计算 (后端 estimate_cost=unit_price,如 gpt-image-2=¥2),预估与实扣一致。 - ModelConfig 序列化本就含 unit_price,前端类型补上并据此计算。 附注(同批已在早前提交内生效):PMC#5/#10 多批各自续轮询、PMC#8 并发重跑、 PMC#14/#15/#22 生成后自动滚动+清输入。 Co-Authored-By: Claude Opus 4.8 --- core/frontend/src/App.tsx | 4 +++- core/frontend/src/routes/ai-tools.tsx | 13 +++++++++++-- core/frontend/src/types.ts | 1 + 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/core/frontend/src/App.tsx b/core/frontend/src/App.tsx index 669d026..a3d3030 100644 --- a/core/frontend/src/App.tsx +++ b/core/frontend/src/App.tsx @@ -523,8 +523,10 @@ export function App() { const res = await pollImageTasks(payload.mode, ids); // 回传后端归属/新建的对话 id,供工作室把它登记进左栏会话列表并设为 active return { ...res, conversation_id }; + // successText 留空:工作台的批次卡已就地显示出图结果(生成中→已完成),全局右下角「图片已生成」toast 多余, + // 且会在「生成中删掉该批次」后才弹出来,让人以为删了又生成(PMC#23)。靠批次卡反馈即可。 // concurrent:生图支持多批并行,不占全局单飞锁(否则并发重跑被拒成 null→标失败,PMC#8) - }, "图片已生成", { concurrent: true }); + }, "", { concurrent: true }); } // 轮询一批已提交的生图任务直到全部出图/超时;每出一张就回写本地,刷新后可恢复。 diff --git a/core/frontend/src/routes/ai-tools.tsx b/core/frontend/src/routes/ai-tools.tsx index d25320b..0207601 100644 --- a/core/frontend/src/routes/ai-tools.tsx +++ b/core/frontend/src/routes/ai-tools.tsx @@ -703,6 +703,15 @@ export function ImageWorkbenchPage({ } const imageModels = modelConfigs.filter((model) => model.capability.includes("image")); + // 每张图实扣单价:取「当前选的生图模型」的 unit_price(火山/gpt-image),没匹配上用第一个图像模型, + // 再兜底 ¥2(后端 estimate_cost=unit_price,默认模型 gpt-image-2=¥2)。前端预估据此算,和后端实扣一致(PMC#20)。 + const perImagePrice = (() => { + const want = genModel === "gpt-image" ? "gpt-image" : genModel === "volcano" ? "seedream" : genModel; + const m = imageModels.find((x) => x.name.toLowerCase().includes(want)) || imageModels[0]; + const p = Number(m?.unit_price); + return Number.isFinite(p) && p > 0 ? p : 2; + })(); + const estimateFee = (n: number) => `¥${(n * perImagePrice).toFixed(2)}`; /* 模特卡数据来源:期2 改为「模特库」(顶级实体,引用其形象图当上身图参考)。 映射 ModelEntity→Asset 形:id=形象图资产 id(选中即作 model_id 参考图),metadata 记 model_entity_id 溯源。 @@ -1581,7 +1590,7 @@ export function ImageWorkbenchPage({ onSelect={setCount} /> - 预估 ¥{(candidateCount * 0.1).toFixed(2)} + 预估 {estimateFee(candidateCount)} {/* YYX#9:去掉生成按钮下方那行说明文字 */} diff --git a/core/frontend/src/types.ts b/core/frontend/src/types.ts index 8a08d3a..69c254f 100644 --- a/core/frontend/src/types.ts +++ b/core/frontend/src/types.ts @@ -525,6 +525,7 @@ export type ModelConfig = { display_name: string; capability: string; status: string; + unit_price?: string; // 单位价(每张图/每次调用),前端据此算「预估扣费」与后端实扣一致(PMC#20) }; export type AITask = {