火山人像审核状态此前三处文案各异(已审核/通过/审核✓…)。统一成一个共享 ReviewBadge: 全色填充盾(无对勾叉)+ 文案 + hover 气泡说明,4 态: 🟢已过审(active) / 🔴未过审(failed) / 🟠审核中(processing,橙盾光扫动画) / ⚪待审核(空) 灰盾(未送审)可点 → 提交审核(兜底,不加固定按钮):后端新增 POST /api/assets/{id}/submit-review/ (团队级,仅送审三类),前端点击乐观置 processing。气泡组件顺带成为全站首个统一 tooltip。 - 后端 submit-review 端点 + 单测(送审类 200 / 非送审类 400) - 共享 components/review-badge.{tsx,css}(盾用 SVG 蒙版填色 + 橙态 rv-sweep 光扫) - 资产库详情弹窗 / 商品详情素材组弹窗 / 视频流程基础资产 三处全换成它(各自接 onSubmit) 验收:assets 16 测绿;tsc+build 绿;无头核对四态(灰可点+气泡/绿已过审/橙审核中不可点)、0 console error Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
21 lines
1.5 KiB
JavaScript
21 lines
1.5 KiB
JavaScript
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/rv"); 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(2500);
|
|
await p.locator(".pd-group-card",{hasText:"角色"}).first().click(); await p.waitForTimeout(1200);
|
|
r.badgeCount=await p.locator(".review-badge").count();
|
|
r.badgeText=await p.locator(".review-badge .rv-label").first().innerText().catch(()=>"");
|
|
r.badgeClickable=await p.locator(".review-badge.clickable").count();
|
|
// hover 看气泡
|
|
await p.locator(".review-badge").first().hover(); await p.waitForTimeout(400);
|
|
r.popVisible=await p.locator(".review-pop").first().isVisible().catch(()=>false);
|
|
await p.screenshot({path:path.join(OUT,"rv-modal.png")});
|
|
await b.close(); console.log(JSON.stringify(r,null,2));
|