diff --git a/CHANGELOG b/CHANGELOG index 753d710..50abdc0 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,7 @@ # CHANGELOG +- [2026-09-23 07:00] FIX: v2.16 样板库画布每块可编辑+模型框污染根治。①TemplatesView 预览对话框打开即编辑态(去掉"编辑分格/尺寸"门槛, 报价/下单入口保留); ②格尺寸调整死角修复: 格两边均贴外框时联动等比缩放整窗(原直接拒绝→"只能编辑外框"的体感根源), 任意格任意方向均可编辑; ③根因修复: computeModelBox 误将扇 bd 退化点(如 x=24.4)计入模型框→W/H 显示 2231 而非 1800、梃位/缩放参考边全被污染, 改为仅由基底多边形决定; ④悬停格淡高亮+pointer 光标(可发现性), HUD 标签改"格宽/格高"; 验证: 真实浏览器四项全过(格尺寸 663→格高800 边界梃平移/梃位900 精确移动/贴边格格高1200→整窗 1800×1200 等比/组合写回), ui-shots 6 页无报错 (Files: frontend/src/components/WindoorCanvas.vue, frontend/src/views/TemplatesView.vue, frontend/scripts/verify-detail.mjs, shots/*) + - [2026-09-23 06:30] FEAT: v2.15 图纸封面图一致性收尾——官方 PNG 剩余元素补齐。①分段尺寸标注: 按重放区域分割点生成蓝色分段(每格宽/高)+总尺寸双排标注(端部刻度, 左侧文字旋转), 替换原仅总宽高文本; ②玻璃配置第二行: fl.spet.sp(如 5+12+5)画于编号下方(704 无配置不画, 与官方一致); ③中梃与外框交点白色连接件方块; 修复 spIdx 遍历变量; 验证: 704 画布与官方封面图逐元素一致(分段 663/1137/393/1207+总 1800/1600), ui-shots 6 页无报错 (Files: frontend/src/components/WindoorCanvas.vue, shots/*) - [2026-09-23 06:05] FEAT: v2.14 2D 图纸样式对齐源站设计图(官方 PNG 逐元素比对)。WindoorCanvas 绘制层重写: ①玻璃 teal 渐变(官方配色)+深色细描边; ②型材立体三段线(深轮廓+紫灰主体+白高光, 宽度=60mm 料宽映射限幅), 外框/中梃/扇料框统一; ③四角白色角码; ④开向符号对齐官方: 平开=虚线大三角(apex 按 hm.openDirection 指铰链侧, wtf 同样画三角), 推拉=水平滑行箭头(成对反向); ⑤把手(铰链对面侧白条)+锁点小方块; ⑥玻璃编号标签(frame/sash 的 mm.fls[].ser.text 经 polyId 树寻址定位到格中心); ⑦尺寸标注改官方蓝色带端部刻度; CombineCanvas 玻璃/型材配色同步; 验证: 设计图纸 704 画布与官方平面图逐元素一致, ui-shots 6 页无报错 (Files: frontend/src/components/WindoorCanvas.vue, frontend/src/components/CombineCanvas.vue, shots/*) diff --git a/frontend/scripts/verify-detail.mjs b/frontend/scripts/verify-detail.mjs index 442cbea..18fb836 100644 --- a/frontend/scripts/verify-detail.mjs +++ b/frontend/scripts/verify-detail.mjs @@ -13,7 +13,7 @@ const page = await browser.newPage() page.on('pageerror', e => console.log(`[JS异常] ${String(e).slice(0, 200)}`)) const shots = 'D:/Code/huamenchuang/shots' -// 在画布内依次尝试点击候选点, 直到 HUD 出现"格W"(选中玻璃格) +// 在画布内依次尝试点击候选点, 直到 HUD 出现"格宽"(选中玻璃格) async function clickUntilRegion(canvasBox) { const candidates = [[0.35, 0.30], [0.30, 0.25], [0.40, 0.35], [0.32, 0.22]] for (const [fx, fy] of candidates) { @@ -21,7 +21,7 @@ async function clickUntilRegion(canvasBox) { await sleep(350) const ok = await page.evaluate(() => { const inputs = [...document.querySelectorAll('.hud .dim-input')] - return inputs.some(d => d.textContent.includes('格W')) + return inputs.some(d => d.textContent.includes('格宽')) }) if (ok) return true } @@ -51,25 +51,21 @@ await page.goto(`http://localhost:8000/templates?token=${encodeURIComponent(toke await sleep(1500) await page.click('.sample-card .cap, .card .cap, .cap') await sleep(1200) -await page.evaluate(() => { - const btn = [...document.querySelectorAll('.el-dialog button')].find(b => b.textContent.includes('编辑分格')) - btn?.click() -}) -await sleep(900) +// 打开即编辑态(无需再点编辑按钮) let cv = await (await page.$('.el-dialog .canvas-box canvas')).boundingBox() await page.screenshot({ path: `${shots}/detail-1-editor.png`, clip: cv }) if (!(await clickUntilRegion(cv))) { console.error('✗ 未能选中玻璃格'); process.exit(1) } await page.screenshot({ path: `${shots}/detail-2-region-selected.png`, clip: cv }) const beforeW = await page.evaluate(() => { - const wrap = [...document.querySelectorAll('.hud .dim-input')].find(d => d.textContent.includes('格W')) + const wrap = [...document.querySelectorAll('.hud .dim-input')].find(d => d.textContent.includes('格宽')) return Number(wrap.querySelector('input').value) }) -await setDim('格H', 800) // 亮子高度调到 800 → 横梃下移 +await setDim('格高', 800) // 亮子高度调到 800 → 横梃下移 await page.screenshot({ path: `${shots}/detail-3-region-resized.png`, clip: cv }) // 梃位编辑: 点击中央竖梃(画布中线附近) -await page.mouse.click(cv.x + cv.width * 0.50, cv.y + cv.height * 0.55) +await page.mouse.click(cv.x + cv.width * 0.433, cv.y + cv.height * 0.55) await sleep(350) if (await hasDim('梃位')) { await setDim('梃位', 900) @@ -78,7 +74,23 @@ if (await hasDim('梃位')) { } else { console.log('△ 未命中中梃(点击位置在格上), 跳过梃位编辑截图') } -console.log(`✓ 格尺寸编辑完成 (格W ${beforeW} → 调格H=800)`) +// 贴边格等比缩放: 选中右侧整列格(高贴外框) → 改格高 → 整窗等比缩放 +await page.mouse.click(cv.x + cv.width * 0.684, cv.y + cv.height * 0.5) +await sleep(350) +if (await hasDim('格宽')) { + await setDim('格高', 1200) + const wh = await page.evaluate(() => { + const wraps = [...document.querySelectorAll('.hud .dim-input')] + const w = wraps.find(d => d.textContent.trim().startsWith('W')) + const h = wraps.find(d => d.textContent.trim().startsWith('H')) + return { w: w?.querySelector('input')?.value, h: h?.querySelector('input')?.value } + }) + await page.screenshot({ path: `${shots}/detail-4b-edge-scale.png`, clip: cv }) + console.log(`✓ 贴边格等比缩放: 整窗 ${wh.w} × ${wh.h} (期望 1800 × 1200)`) +} else { + console.log('△ 未选中贴边格, 跳过等比缩放验证') +} +console.log(`✓ 格尺寸编辑完成 (格W ${beforeW} → 调格高=800)`) await page.close() // ============ ② 组合页: 细节编辑对话框 + 保存写回 ============ @@ -107,7 +119,7 @@ if (!(await (async () => { await sleep(350) const ok = await page2.evaluate(() => { const inputs = [...document.querySelectorAll('.hud .dim-input')] - return inputs.some(d => d.textContent.includes('格W')) + return inputs.some(d => d.textContent.includes('格宽')) }) if (ok) return true } @@ -115,7 +127,7 @@ if (!(await (async () => { })())) { console.error('✗ 组合细节编辑未能选中玻璃格'); process.exit(1) } await page2.screenshot({ path: `${shots}/detail-5-combine-dialog.png` }) await page2.evaluate(() => { - const wrap = [...document.querySelectorAll('.hud .dim-input')].find(d => d.textContent.includes('格H')) + const wrap = [...document.querySelectorAll('.hud .dim-input')].find(d => d.textContent.includes('格高')) const input = wrap.querySelector('input') input.value = '900' input.dispatchEvent(new Event('input', { bubbles: true })) diff --git a/frontend/src/components/WindoorCanvas.vue b/frontend/src/components/WindoorCanvas.vue index 6b3e3b3..5c6f763 100644 --- a/frontend/src/components/WindoorCanvas.vue +++ b/frontend/src/components/WindoorCanvas.vue @@ -10,9 +10,9 @@ H @@ -108,7 +110,8 @@ async function load() { async function preview(t: any) { current.value = await api('get', `/api/windoor/templates/${t.id}`) - editing.value = false + // 点击进入即编辑: 每一块(玻璃格/中梃)都可直接编辑 + editing.value = true dirty.value = false liveTotal.value = null previewVisible.value = true diff --git a/shots/02-combine-two.png b/shots/02-combine-two.png index 77caa25..c7e982b 100644 Binary files a/shots/02-combine-two.png and b/shots/02-combine-two.png differ diff --git a/shots/04-combine-3d.png b/shots/04-combine-3d.png index 17646b1..20c98fa 100644 Binary files a/shots/04-combine-3d.png and b/shots/04-combine-3d.png differ diff --git a/shots/detail-1-editor.png b/shots/detail-1-editor.png index 4206cf2..164c1b3 100644 Binary files a/shots/detail-1-editor.png and b/shots/detail-1-editor.png differ diff --git a/shots/detail-2-region-selected.png b/shots/detail-2-region-selected.png index 09ab8bf..1e90700 100644 Binary files a/shots/detail-2-region-selected.png and b/shots/detail-2-region-selected.png differ diff --git a/shots/detail-3-region-resized.png b/shots/detail-3-region-resized.png index 7b992e2..5fd76bb 100644 Binary files a/shots/detail-3-region-resized.png and b/shots/detail-3-region-resized.png differ diff --git a/shots/detail-4-mullion-moved.png b/shots/detail-4-mullion-moved.png index a0e11a9..5338a3e 100644 Binary files a/shots/detail-4-mullion-moved.png and b/shots/detail-4-mullion-moved.png differ diff --git a/shots/detail-4b-edge-scale.png b/shots/detail-4b-edge-scale.png new file mode 100644 index 0000000..929ea1d Binary files /dev/null and b/shots/detail-4b-edge-scale.png differ diff --git a/shots/detail-5-combine-dialog.png b/shots/detail-5-combine-dialog.png index a697712..b2c3511 100644 Binary files a/shots/detail-5-combine-dialog.png and b/shots/detail-5-combine-dialog.png differ diff --git a/shots/detail-6-combine-saved.png b/shots/detail-6-combine-saved.png index 0bc4778..33c1644 100644 Binary files a/shots/detail-6-combine-saved.png and b/shots/detail-6-combine-saved.png differ