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:
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user