| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273 |
- /**
- * 票 71 部署后真实复验(2026-10-23)。
- *
- * 对照 verify/artifacts/t71/expected-after-deploy.md 的部署前预演表,逐项判 PASS/FAIL:
- * 1. map-snapshot 里「预警未解决 + 未结束工单、无报警」的两台设备应已翻为 WORK_ORDER;
- * 2. 只有预警、没有工单的设备仍 WARNING;
- * 3. 报警设备 21119740 的点位仍 ALARM(票 52 分支不受改序影响);
- * 4. 未关联设备业务轴计数:预警 3→1、工单 3→5;
- * 5. Q3 留档:monitoring/situation 的 metricStatus 不跟随(两台仍是 WARNING)。
- *
- * 用法:node verify-after-deploy.mjs
- */
- import fs from 'node:fs'
- const BASE = 'http://192.168.110.96:8301/api/cockpit/v1'
- const OUT = 'after-deploy'
- fs.mkdirSync(OUT, { recursive: true })
- const get = async (path, file) => {
- const res = await fetch(BASE + path)
- const text = await res.text()
- fs.writeFileSync(`${OUT}/${file}`, text)
- return JSON.parse(text)
- }
- const snap = (await get('/map-snapshot?page=1&pageSize=1000', 'map-snapshot.json')).data
- const situation = (await get('/monitoring/situation', 'situation.json')).data
- const devices = new Map(snap.unassociatedEquipment.map((d) => [d.deviceCode, d.deviceStatus]))
- const sortKeys = (o) => Object.fromEntries(Object.entries(o).sort(([a], [b]) => a.localeCompare(b)))
- const counts = {}
- for (const status of devices.values()) counts[status] = (counts[status] || 0) + 1
- const checks = []
- const check = (name, actual, expected) => {
- const ok = JSON.stringify(actual) === JSON.stringify(expected)
- checks.push({ name, ok, actual, expected })
- console.log(`${ok ? 'PASS' : 'FAIL'} | ${name} | 实测 ${JSON.stringify(actual)} | 预期 ${JSON.stringify(expected)}`)
- }
- console.log('snapshotAt:', snap.snapshotAt)
- check('41010500001320000002 应翻 WORK_ORDER', devices.get('41010500001320000002'), 'WORK_ORDER')
- check('TEST-CBYL5432168 应翻 WORK_ORDER', devices.get('TEST-CBYL5432168'), 'WORK_ORDER')
- check('TEST-TCLLJ002215 无工单应仍 WARNING', devices.get('TEST-TCLLJ002215'), 'WARNING')
- check('860347065467627 有工单无预警应仍 WORK_ORDER', devices.get('860347065467627'), 'WORK_ORDER')
- check('41010500001320000001 应仍 NORMAL', devices.get('41010500001320000001'), 'NORMAL')
- check('8652052334 应仍 OFFLINE', devices.get('8652052334'), 'OFFLINE')
- const alarmPoint = snap.monitoringPoints.find((p) => (p.deviceCodes || []).includes('21119740'))
- check('21119740 所在点位应仍 ALARM', alarmPoint && alarmPoint.pointStatus, 'ALARM')
- check('未关联设备业务轴计数', sortKeys(counts), sortKeys({ NORMAL: 1, WARNING: 1, WORK_ORDER: 5, OFFLINE: 2 }))
- // Q3:situation 按事实判,不跟随业务序 —— 该端点的设备状态只在异常设备清单里(status 字段)
- const abnormal = situation.abnormalEquipment || []
- const statusInSituation = (code) => {
- const row = abnormal.find((d) => d.deviceCode === code)
- return row ? row.status : 'NOT_LISTED'
- }
- // 「不跟随」的判据是**不出现 WORK_ORDER**(situation 没有这个桶,按事实落 WARNING/ALARM/OFFLINE),
- // 不钉死具体是 WARNING:设备在线态是独立事实,会随现网漂移(CBYL 今日即被判 OFFLINE)。
- const checkNotFollowing = (name, code) => {
- const actual = statusInSituation(code)
- const ok = actual !== 'WORK_ORDER'
- checks.push({ name, ok, actual, expected: '≠ WORK_ORDER' })
- console.log(`${ok ? 'PASS' : 'FAIL'} | ${name} | 实测 ${actual} | 预期 ≠ WORK_ORDER`)
- }
- checkNotFollowing('Q3: 41010500001320000002 的 situation 状态不跟随业务序', '41010500001320000002')
- checkNotFollowing('Q3: TEST-CBYL5432168 的 situation 状态不跟随业务序', 'TEST-CBYL5432168')
- const failed = checks.filter((c) => !c.ok)
- console.log(`\n复验 ${checks.length - failed.length}/${checks.length} 通过`)
- process.exit(failed.length === 0 ? 0 : 1)
|