From caec48c827058fd0a91bbb8667b20e7259b80f56 Mon Sep 17 00:00:00 2001 From: seaislee1209 Date: Sun, 21 Jun 2026 21:26:28 +0800 Subject: [PATCH] =?UTF-8?q?fix(asset-factory):=20=E5=9B=BE=E7=89=87?= =?UTF-8?q?=E5=B7=A5=E5=85=B7=E5=8D=A1=E5=86=85=E5=AE=B9=E8=B4=B4=E5=B7=A6?= =?UTF-8?q?=20=E2=80=94=20=E7=9B=96=E6=8E=89=E6=AE=8B=E7=95=99=E5=85=A8?= =?UTF-8?q?=E5=B1=80=20.factory-body=20=E6=BC=8F=E8=BF=9B=E7=9A=84?= =?UTF-8?q?=E5=B1=85=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 旧全局 .factory-body(styles.css)是老两栏 grid 带 align-items:center;新的 .asset-factory .factory-body 特异性更高但没写 align-items,导致 center 漏进来把 标签/标题/按钮整块水平居中。卡越宽偏越多(2列卡内容离左边 ~167px)。 显式补 align-items:stretch 盖掉 → 内容左对齐贴 30px 内边距(无头实测 31px,不随卡宽漂移)。 Co-Authored-By: Claude Opus 4.8 --- core/frontend/src/ai-tools-page.css | 2 ++ core/qa/visual-parity/_measure-factory.mjs | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 core/qa/visual-parity/_measure-factory.mjs diff --git a/core/frontend/src/ai-tools-page.css b/core/frontend/src/ai-tools-page.css index f8c871b..3450a01 100644 --- a/core/frontend/src/ai-tools-page.css +++ b/core/frontend/src/ai-tools-page.css @@ -38,6 +38,8 @@ flex-direction: column; gap: 18px; height: 100%; + /* 盖掉旧全局 .factory-body(styles.css) 漏进来的 align-items:center —— 否则内容被居中、宽卡里偏离左边老远 */ + align-items: stretch; } .asset-factory .factory-text { display: flex; flex-direction: column; min-width: 0; } diff --git a/core/qa/visual-parity/_measure-factory.mjs b/core/qa/visual-parity/_measure-factory.mjs new file mode 100644 index 0000000..f3ede2d --- /dev/null +++ b/core/qa/visual-parity/_measure-factory.mjs @@ -0,0 +1,19 @@ +import { chromium } from "playwright"; +const b=await chromium.launch({headless:true}); +async function measure(w){ + const ctx=await b.newContext({viewport:{width:w,height:900}}); + const p=await ctx.newPage(); + 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/asset-factory"); await p.waitForTimeout(1500); + const card=await p.locator(".factory-card").first().boundingBox(); + const tag=await p.locator(".factory-card").first().locator(".factory-tag").boundingBox(); + const title=await p.locator(".factory-card").first().locator(".factory-title").boundingBox(); + if(w===1200) await p.locator(".factory-card").first().screenshot({path:"../../../_qa_shots/factory-fixed.png"}); + await ctx.close(); + return {viewport:w, cardW:Math.round(card.width), tag_offset:Math.round(tag.x-card.x), title_offset:Math.round(title.x-card.x)}; +} +console.log(JSON.stringify(await measure(1440))); +console.log(JSON.stringify(await measure(1200))); +await b.close();