修复:防止异步响应覆盖与打印资源泄漏

This commit is contained in:
焦龙言
2026-07-27 05:44:20 +08:00
parent 137b2934f7
commit 2d2b3cf6c6
3 changed files with 65 additions and 11 deletions
@@ -657,7 +657,20 @@ test('六个基础资料页面逐页满足 API、权限、分页和安全删除
assert.match(printHandler, /document\.createElement\(['"](?:h1|img|style)['"]\)/)
assert.match(printHandler, /\.textContent\s*=/)
assert.match(printHandler, /['"]load['"][\s\S]*?printWindow\.print\(\)/)
assert.match(printHandler, /['"]afterprint['"][\s\S]*?URL\.revokeObjectURL/)
assert.match(printHandler, /let closeMonitorId;/)
assert.match(printHandler, /let cleanupFinished = false;/)
assert.match(printHandler, /const cleanupPrint = \(\) => \{\s*if \(cleanupFinished\) return;\s*cleanupFinished = true;/)
assert.match(printHandler, /window\.clearInterval\(closeMonitorId\)/)
assert.equal((printHandler.match(/URL\.revokeObjectURL\(objectUrl\)/g) || []).length, 1)
assert.equal((printHandler.match(/setPrinting\(row\.palletId, false\)/g) || []).length, 1)
assert.match(printHandler, /closeMonitorId = window\.setInterval\(\(\) => \{\s*if \(printWindow\.closed\) cleanupPrint\(\);\s*}, \d+\)/)
assert.ok(
printHandler.indexOf('window.setInterval(') < printHandler.indexOf('getPalletQrcode('),
'打印窗口关闭监测必须在异步二维码请求前启动'
)
assert.match(printHandler, /['"]error['"][\s\S]*?cleanupPrint\(\)[\s\S]*?printWindow\.close\(\)/)
assert.match(printHandler, /['"]afterprint['"][\s\S]*?cleanupPrint\(\)[\s\S]*?printWindow\.close\(\)/)
assert.match(printHandler, /\.catch\(\(\) => \{\s*cleanupPrint\(\)/)
assert.doesNotMatch(printHandler, /document\.write|innerHTML|BarcodeDetector|getUserMedia|camera/i)
assert.match(source, /v-if="isEdit"[\s\S]*?v-model="form\.palletCode"[\s\S]*?readonly/)
assert.match(source, /v-if="isEdit"[\s\S]*?v-model="form\.qrToken"[\s\S]*?readonly/)
@@ -682,6 +695,17 @@ test('业务用户分配组件使用固定映射并允许空数组完整替换',
assert.match(source, /const resourceApiMap = Object\.freeze\(\{[\s\S]*?site:\s*Object\.freeze\(\{\s*getUsers:\s*getSiteUsers,\s*assignUsers:\s*assignSiteUsers\s*}\)[\s\S]*?warehouse:\s*Object\.freeze\(\{\s*getUsers:\s*getWarehouseUsers,\s*assignUsers:\s*assignWarehouseUsers\s*}\)[\s\S]*?}\)/)
assert.doesNotMatch(source, /defineProps\(/)
assert.match(source, /function show\(\{ resourceType, resourceId, resourceName }\)/)
assert.match(source, /let loadGeneration = 0;/)
assert.match(source, /function isCurrentUserLoad\(loadContext\)\s*{[\s\S]*?loadContext\.generation === loadGeneration[\s\S]*?loadContext\.resourceType === resourceType\.value[\s\S]*?loadContext\.resourceId === resourceId\.value[\s\S]*?}/)
const loadUsersSource = source.slice(source.indexOf('function loadUsers()'), source.indexOf('function resetDialogState()'))
const staleLoadGuard = 'if \\(!isCurrentUserLoad\\(loadContext\\)\\) \\{\\s*return;\\s*}'
assert.match(loadUsersSource, /const loadContext = \{\s*generation: \+\+loadGeneration,\s*resourceType: resourceType\.value,\s*resourceId: resourceId\.value\s*};/)
assert.match(loadUsersSource, /resourceApi\.getUsers\(loadContext\.resourceId\)/)
assert.match(loadUsersSource, new RegExp(`\\.then\\(\\(response\\) => \\{\\s*${staleLoadGuard}`))
assert.match(loadUsersSource, new RegExp(`\\.catch\\(\\(\\) => \\{\\s*${staleLoadGuard}`))
assert.match(loadUsersSource, new RegExp(`\\.finally\\(\\(\\) => \\{\\s*${staleLoadGuard}`))
const resetDialogSource = source.slice(source.indexOf('function resetDialogState()'), source.indexOf('function show('))
assert.match(resetDialogSource, /loadGeneration \+= 1;/)
assert.match(source, /response\.data/)
assert.match(source, /userId:\s*row\.userId,\s*userName:\s*row\.userName,\s*nickName:\s*row\.nickName,\s*assigned:\s*row\.assigned === true/)
assert.doesNotMatch(source, /\.\.\.row|email:\s*row\.|phonenumber:\s*row\.|status:\s*row\./)