fix: 测试清单(7) 第7轮修复 — ZWQ/PMC/团队 8处真bug

- ZWQ-1 商品库: 编辑删图真生效 + 刷新后悬停垃圾桶图标恢复 (products.tsx/css)
- ZWQ-2 工作台: 最近项目进度条 5→4 段对齐视频项目, 完成态末段红→绿 (dashboard.tsx)
- PMC-4 消息中心: 收件箱文字错位修正 (messages-page.css)
- PMC-5 图片生成: 平台套图费用预估漏乘平台数, 改为 平台数×候选数×单价 对齐实扣(仅改展示, 不动扣费) (ai-tools.tsx)
- PMC-10 火山生图: 失败不再吞 response body, 错误体上抛便于定位 (volcano.py)
- PMC-11 团队: 创建账户弹窗禁止点遮罩误关 (overlays.tsx + team.tsx)

构建: npm run build EXIT=0 (1754 模块); volcano.py AST OK
注: PMC-10/YYX-8角标 等后端项需部署生效

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
zyc
2026-06-29 11:41:00 +08:00
co-authored by Claude Opus 4.8
parent 6e7425048c
commit f3b89f3d49
9 changed files with 150 additions and 32 deletions
+32 -15
View File
@@ -550,20 +550,34 @@ const FALLBACK_MODELS = [
{ id: "m4", name: "Zoe", tag: "亚洲·30岁·健身" }
];
/* 平台套图 · 平台卡(基线 platform-cover · logo 配色用 token 化 className) */
/* 平台套图 · 平台卡(YYX#row10:用真平台 logo,素材在 public/assets/svg;
logo 留作图加载失败时的兜底字符,img 为真 logo) */
const PLATFORM_OPTIONS = [
{ id: "dy", name: "抖音电商", logo: "抖" },
{ id: "tb", name: "淘宝", logo: "淘" },
{ id: "tm", name: "天猫", logo: "猫" },
{ id: "jd", name: "京东", logo: "京" },
{ id: "pdd", name: "拼多多", logo: "拼" },
{ id: "xhs", name: "小红书", logo: "红" },
{ id: "ks", name: "快手", logo: "快" },
{ id: "sph", name: "视频号", logo: "视" },
{ id: "amz", name: "亚马逊", logo: "a" },
{ id: "al", name: "1688", logo: "阿" }
{ id: "dy", name: "抖音电商", logo: "抖", img: "/assets/svg/icon-platform-douyin.svg" },
{ id: "tb", name: "淘宝", logo: "淘", img: "/assets/svg/icon-platform-taobao.svg" },
{ id: "tm", name: "天猫", logo: "猫", img: "/assets/svg/icon-platform-tmall.svg" },
{ id: "jd", name: "京东", logo: "京", img: "/assets/svg/icon-platform-jd.svg" },
{ id: "pdd", name: "拼多多", logo: "拼", img: "/assets/svg/icon-platform-pdd.svg" },
{ id: "xhs", name: "小红书", logo: "红", img: "/assets/svg/icon-platform-xiaohongshu.svg" },
{ id: "ks", name: "快手", logo: "快", img: "/assets/svg/icon-platform-kuaishou.svg" },
{ id: "sph", name: "视频号", logo: "视", img: "/assets/svg/icon-platform-wechat-video.svg" },
{ id: "amz", name: "亚马逊", logo: "a", img: "/assets/svg/icon-platform-amazon.svg" },
{ id: "al", name: "1688", logo: "阿", img: "/assets/svg/icon-platform-1688.svg" }
];
/* YYX#row10:平台 logo —— 优先真 logo 图(public/assets/svg),加载失败回退到品牌色块+字符。
className 默认 p-logo(平台卡/筛选弹窗),分组头传 cg-logo。 */
function PlatformLogo({ p, className }: { p: { id: string; name: string; logo: string; img?: string }; className?: string }) {
const [err, setErr] = useState(false);
return (
<span className={`${className || "p-logo"} p-logo-${p.id}${p.img && !err ? " has-img" : ""}`}>
{p.img && !err
? <img className="p-logo-img" src={p.img} alt={p.name} loading="lazy" decoding="async" onError={() => setErr(true)} />
: p.logo}
</span>
);
}
/* 一次生成/重跑 = 一个批次:各自独立展示自己的图、状态、加入资产库切换;支持多批并行跑。
行31(并发提交) / 行32(重跑追加新批次 + 气泡菜单 + 加入/取消切换) / 行33(多批次持久化恢复)。 */
type GenBatch = {
@@ -784,6 +798,9 @@ export function ImageWorkbenchPage({
const ratioVar = ratio.replace(":", " / ");
const candidateCount = Math.max(1, Number(count) || 4);
// PMC#5:平台套图(cover)对每个选中平台各起一批,实扣 = 平台数 × candidateCount × 单价。
// 预估必须乘平台数才与实扣口径一致(model/image 模式只生成 candidateCount 张,不乘)。
const estimateCount = mode === "cover" ? Math.max(1, pickedIds.length) * candidateCount : candidateCount;
// 行31:并发提交——只要 prompt 非空就能再次提交,不再因"有批次在跑"被禁用
// 模特上身图需结合「商品图 + 模特图」合成,故必须先选商品且选一个模特,否则只是凭文字脑补
const canGenerate =
@@ -1412,7 +1429,7 @@ export function ImageWorkbenchPage({
<div className="iw-cover-group-h">
{plat ? (
<>
<span className={`cg-logo p-logo-${plat.id}`}>{plat.logo}</span>
<PlatformLogo p={plat} className="cg-logo" />
<span className="cg-name">{plat.name}</span>
</>
) : (
@@ -1778,7 +1795,7 @@ export function ImageWorkbenchPage({
className={`iw-filter-opt${platformFilter.includes(p.id) ? " on" : ""}`}
onClick={() => setPlatformFilter((prev) => (prev.includes(p.id) ? prev.filter((x) => x !== p.id) : [...prev, p.id]))}
>
<span className={`p-logo p-logo-${p.id}`}>{p.logo}</span>
<PlatformLogo p={p} />
<span className="nm">{p.name}</span>
<Check className="ck" size={12} />
</button>
@@ -1894,7 +1911,7 @@ export function ImageWorkbenchPage({
onClick={() => togglePick(item.id)}
>
<span className="p-check" />
<span className={`p-logo p-logo-${item.id}`}>{item.logo}</span>
<PlatformLogo p={item} />
<span className="p-name">{item.name}</span>
</button>
))}
@@ -2012,7 +2029,7 @@ export function ImageWorkbenchPage({
{/* 行31:并发提交——有批次在跑时仍可再次提交,只在提交瞬间不重复触发 */}
<button className="btn btn-primary" type="button" onClick={runGenerate} disabled={!canGenerate}>
<WandSparkles size={13} />
立即生成 (预估 {estimateFee(candidateCount)})
立即生成 (预估 {estimateFee(estimateCount)})
</button>
{/* YYX#9:去掉生成按钮下方那行说明文字 */}
</div>