|
@@ -0,0 +1,73 @@
|
|
|
|
|
+/**
|
|
|
|
|
+ * 票 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)
|