diff --git a/core/frontend/src/routes/products.tsx b/core/frontend/src/routes/products.tsx index c62891c..a7cb6b5 100644 --- a/core/frontend/src/routes/products.tsx +++ b/core/frontend/src/routes/products.tsx @@ -545,9 +545,22 @@ function pdAssetPreview(asset?: Asset): string { if (!asset) return ""; return asset.files?.find((file) => file.is_primary)?.preview_url || asset.files?.[0]?.preview_url || ""; } -// AI 素材分类 → 中文类型标签(用于缩图左上角 type-pill) +// 送审类(火山人像审核真实作用的只有视频流程人脸三类):只有这几类才显审核态 +const PD_REVIEW_CATS = new Set(["person", "tri_view", "storyboard"]); +// AI 素材分类 → 中文类型标签(用于缩图左上角 type-pill)。与资产库 CATEGORY_LABELS 保持一致。 const PD_ASSET_TYPE_LABEL: Record = { - product_image: "商品图", person: "模特上身图", scene: "平台套图", tri_view: "三视图", background: "背景图" + product_image: "商品图", + person: "角色", + model_portrait: "模特形象图", + tri_view: "三视图", + model_tryon: "模特上身图", + platform_kit: "平台套图", + free_create: "自由创作", + scene: "场景", + storyboard: "分镜图", + video_clip: "视频素材", + final_video: "最终成片", + background: "背景图" }; function pdAssetTypeLabel(asset: Asset): string { return PD_ASSET_TYPE_LABEL[asset.category] || PD_ASSET_TYPE_LABEL[asset.asset_type] || asset.category || "素材"; @@ -1086,8 +1099,11 @@ export function ProductDetailPage({ product, projects, initialTab = "assets", na {url ? null : 3:4}
- {/* 审核状态(只读):团队审核给出 通过 / 不通过,未定论显示 待审核 —— 不再是可点切换的按钮 */} - {PD_ASSET_STATUS_LABEL[status]} + {/* 审核状态(只读):仅视频流程人脸三类(角色/三视图/分镜)才真送火山审核 → 才显审核态; + 其余素材无需审核,不显(此前一律标「待审核」是误导)。 */} + {PD_REVIEW_CATS.has(asset.category) && ( + {PD_ASSET_STATUS_LABEL[status]} + )} {(asset.created_at || "").slice(0, 10)}
diff --git a/core/qa/visual-parity/_pd-labels.mjs b/core/qa/visual-parity/_pd-labels.mjs new file mode 100644 index 0000000..fd76179 --- /dev/null +++ b/core/qa/visual-parity/_pd-labels.mjs @@ -0,0 +1,23 @@ +import { chromium } from "playwright"; +import path from "node:path"; import fs from "node:fs"; +const PID="53d7a7c3-2f41-431b-82d3-3acc97900310"; +const OUT=path.resolve("../../../_qa_shots/pd"); fs.mkdirSync(OUT,{recursive:true}); +const b=await chromium.launch({headless:true}); const r={consoleErrors:[]}; +const p=await (await b.newContext({viewport:{width:1440,height:1000}})).newPage(); +p.on("console",m=>{if(m.type()==="error")r.consoleErrors.push(m.text())}); p.on("pageerror",e=>r.consoleErrors.push("PE:"+e.message)); +await p.goto("http://localhost:5200/login"); await p.waitForTimeout(300); +await p.fill("#auth-username","airshelf"); await p.fill("#auth-pwd","Restraint2026"); +await p.click("button.btn-cta"); await p.waitForFunction(()=>!location.pathname.startsWith("/login"),{timeout:12000}); +await p.goto("http://localhost:5200/products/"+PID); await p.waitForTimeout(3000); +// 收集每张素材卡的 类型标签 + 是否有审核态 +const cards=await p.locator(".asset-card").count(); +const rows=[]; +for(let i=0;i""); + const status=await c.locator(".meta .pill").innerText().catch(()=>""); + rows.push({type, status: status||"(无)"}); +} +r.cards=cards; r.sample=rows; +await p.locator("#asset-grid, .asset-grid").first().screenshot({path:path.join(OUT,"pd-materials.png")}).catch(()=>p.screenshot({path:path.join(OUT,"pd-full.png"),fullPage:true})); +await b.close(); console.log(JSON.stringify(r,null,2));