- WindoorCanvas: 点击玻璃格选中并输入格W/格H(自动平移边界中梃, 共线多段组移动) - 选中中梃可输入距边位置精确移动; 中梃拖动改组移动修复多段错位 - CombineView: 编辑细节对话框(复用 WindoorCanvas), 保存原位写回对应单元并驱动 3D 重建 - CombineCanvas: 中梃按各自裁剪 bbox 绘制, 与真实分格一致 - 验证: 格尺寸/梃位/组合写回真实浏览器截图全通过
133 lines
5.9 KiB
JavaScript
133 lines
5.9 KiB
JavaScript
// 细节编辑验证: ①样板编辑对话框选中玻璃格→格W/H输入→边界梃平移 ②组合页编辑细节对话框→改格→保存写回
|
|
// 用法: node verify-detail.mjs <token>
|
|
import puppeteer from 'puppeteer-core'
|
|
const EDGE = 'C:/Program Files (x86)/Microsoft/Edge/Application/msedge.exe'
|
|
const token = process.argv[2]
|
|
const sleep = ms => new Promise(r => setTimeout(r, ms))
|
|
const browser = await puppeteer.launch({
|
|
executablePath: EDGE, headless: 'new',
|
|
args: ['--window-size=1440,900', '--enable-unsafe-swiftshader'],
|
|
defaultViewport: { width: 1440, height: 900 },
|
|
})
|
|
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"(选中玻璃格)
|
|
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) {
|
|
await page.mouse.click(canvasBox.x + canvasBox.width * fx, canvasBox.y + canvasBox.height * fy)
|
|
await sleep(350)
|
|
const ok = await page.evaluate(() => {
|
|
const inputs = [...document.querySelectorAll('.hud .dim-input')]
|
|
return inputs.some(d => d.textContent.includes('格W'))
|
|
})
|
|
if (ok) return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
// 设置指定 dim-input 的数值(按标签文本查找)
|
|
async function setDim(label, value) {
|
|
await page.evaluate((label, value) => {
|
|
const wrap = [...document.querySelectorAll('.hud .dim-input, .el-dialog .dim-input')]
|
|
.find(d => d.textContent.includes(label))
|
|
if (!wrap) throw new Error('未找到输入: ' + label)
|
|
const input = wrap.querySelector('input')
|
|
input.value = String(value)
|
|
input.dispatchEvent(new Event('input', { bubbles: true }))
|
|
input.dispatchEvent(new Event('change', { bubbles: true }))
|
|
}, label, value)
|
|
await sleep(500)
|
|
}
|
|
|
|
const hasDim = label => page.evaluate((label) => {
|
|
return [...document.querySelectorAll('.hud .dim-input')].some(d => d.textContent.includes(label))
|
|
}, label)
|
|
|
|
// ============ ① 样板库编辑模式: 格尺寸编辑 ============
|
|
await page.goto(`http://localhost:8000/templates?token=${encodeURIComponent(token)}`, { waitUntil: 'networkidle2' })
|
|
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'))
|
|
return Number(wrap.querySelector('input').value)
|
|
})
|
|
await setDim('格H', 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 sleep(350)
|
|
if (await hasDim('梃位')) {
|
|
await setDim('梃位', 900)
|
|
await page.screenshot({ path: `${shots}/detail-4-mullion-moved.png`, clip: cv })
|
|
console.log('✓ 梃位编辑完成')
|
|
} else {
|
|
console.log('△ 未命中中梃(点击位置在格上), 跳过梃位编辑截图')
|
|
}
|
|
console.log(`✓ 格尺寸编辑完成 (格W ${beforeW} → 调格H=800)`)
|
|
await page.close()
|
|
|
|
// ============ ② 组合页: 细节编辑对话框 + 保存写回 ============
|
|
const page2 = await browser.newPage()
|
|
page2.on('pageerror', e => console.log(`[JS异常2] ${String(e).slice(0, 200)}`))
|
|
await page2.goto(`http://localhost:8000/combine?token=${encodeURIComponent(token)}`, { waitUntil: 'networkidle2' })
|
|
await sleep(1000)
|
|
await page2.waitForSelector('.lib-item')
|
|
await page2.click('.lib-item')
|
|
await sleep(600)
|
|
// 点击画布中心选中单元(编辑细节按钮依赖选中态)
|
|
const mbox = await (await page2.$('.canvas-box canvas')).boundingBox()
|
|
await page2.mouse.click(mbox.x + mbox.width / 2, mbox.y + mbox.height / 2)
|
|
await sleep(400)
|
|
await page2.evaluate(() => {
|
|
const btn = [...document.querySelectorAll('button')].find(b => b.textContent.includes('编辑细节'))
|
|
btn?.click()
|
|
})
|
|
await sleep(1200)
|
|
const dcv = await (await page2.$('.el-dialog canvas')).boundingBox()
|
|
if (!(await (async () => {
|
|
// clickUntilRegion 绑定的是 page(已关闭), 这里内联同逻辑
|
|
const candidates = [[0.35, 0.30], [0.30, 0.25], [0.40, 0.35], [0.32, 0.22]]
|
|
for (const [fx, fy] of candidates) {
|
|
await page2.mouse.click(dcv.x + dcv.width * fx, dcv.y + dcv.height * fy)
|
|
await sleep(350)
|
|
const ok = await page2.evaluate(() => {
|
|
const inputs = [...document.querySelectorAll('.hud .dim-input')]
|
|
return inputs.some(d => d.textContent.includes('格W'))
|
|
})
|
|
if (ok) return true
|
|
}
|
|
return false
|
|
})())) { 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 input = wrap.querySelector('input')
|
|
input.value = '900'
|
|
input.dispatchEvent(new Event('input', { bubbles: true }))
|
|
input.dispatchEvent(new Event('change', { bubbles: true }))
|
|
})
|
|
await sleep(500)
|
|
await page2.evaluate(() => {
|
|
const btn = [...document.querySelectorAll('.el-dialog__footer button')].find(b => b.textContent.includes('保存到单元'))
|
|
btn?.click()
|
|
})
|
|
await sleep(900)
|
|
await page2.screenshot({ path: `${shots}/detail-6-combine-saved.png` })
|
|
console.log('✓ 组合细节编辑+保存写回完成')
|
|
await browser.close()
|