| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677 |
- /**
- * T19 预警处置模式面板纯逻辑检查。
- * 按仓库约定为零依赖 Node 断言脚本;本文件只描述验收闸门,不启动应用。
- */
- import { readFileSync } from 'node:fs'
- import {
- EVENT_RANGES,
- WARNING_RESPONSE_PANEL_IDS,
- eventAnalysisPanel,
- historyAnalysisPanel,
- responseEfficiencyPanel,
- toEventAnalysis,
- toEventHistory,
- toHandlingEfficiency,
- } from '../../../src/modules/cockpit/domain/warningResponsePanels.js'
- import { section, SECTION_STATE } from '../../../src/modules/cockpit/domain/sectionState.js'
- import { panelsForMode } from '../../../src/modules/cockpit/domain/panelCatalog.js'
- import { hasPanelView, implementedPanelIds, panelView } from '../../../src/modules/cockpit/domain/panelViews.js'
- import { eventListSwitchView } from '../../../src/modules/cockpit/domain/eventList.js'
- const checks = []
- function check(name, pass, evidence = '') {
- checks.push(pass)
- console.log(`${pass ? 'PASS' : 'FAIL'} ${name}${evidence ? ` — ${evidence}` : ''}`)
- }
- const ready = (data) => ({ ...section(SECTION_STATE.SUCCESS, { data }), loaded: true })
- const historyPayload = {
- mode: 'WARNING',
- range: { type: 'LAST_7_DAYS', startTime: '2026-08-26', endTime: '2026-09-02' },
- trend: [{ bucket: '2026-09-01', count: 4 }],
- sections: { events: { state: 'SUCCESS', data: [{ eventNo: 'H-1', eventName: '燃气预警', level: 1, status: 'ACTIVE', eventTime: 'T', deviceCode: 'D-1' }] } },
- }
- check('A1-four-warning-panels-match-catalog', panelsForMode('warningResponse').join(',') === 'currentEvents,historyAnalysis,responseEfficiency,eventAnalysis')
- check('A2-three-aggregates-registered', WARNING_RESPONSE_PANEL_IDS.every(hasPanelView) && hasPanelView('currentEvents') === false, `implemented=${implementedPanelIds().length}`)
- check('A3-range-options-cover-7-30-90', EVENT_RANGES.map((item) => item.key).join(',') === '7d,30d,90d')
- const history = toEventHistory(historyPayload)
- check('B1-history-adapter-keeps-events-and-range', history.events.length === 1 && history.events[0].code === 'H-1' && history.range.key === '7d')
- const efficiency = toHandlingEfficiency({
- handlingEfficiency: { value: 0.5, totalEvents: 10, handledEvents: 5 },
- averageResponseSeconds: 60,
- averageCloseSeconds: 3600,
- // 票 20:键为后端 0–7(共 8 个码,6 是「延期中」)。
- workOrderStates: { 0: 1, 1: 2, 2: 3, 3: 4, 4: 5, 5: 6, 6: 7, 7: 8 },
- })
- check('B2-efficiency-adapter-keeps-rate-durations-and-eight-states', efficiency.handlingRate === 0.5 && efficiency.responseDuration.value === 60 && efficiency.closeDuration.value === 3600 && efficiency.workOrderStates.length === 8)
- const analysis = toEventAnalysis({ dimensions: { types: [{ code: 'GAS', count: 2 }], levels: [{ level: 1, count: 3 }], industries: [{ code: 'GAS', count: 2 }], regions: [{ code: '城区A', count: 2 }] }, highlights: [{ title: '重点', detail: '高等级', count: 3 }] })
- check('B3-analysis-adapter-keeps-multiple-dimensions', analysis.types.length === 1 && analysis.levels[0].label === '1级' && analysis.industries.length === 1 && analysis.regions.length === 1 && analysis.highlights.length === 1)
- const currentSection = ready(history)
- const historyView = historyAnalysisPanel(history, currentSection)
- const efficiencyView = responseEfficiencyPanel(efficiency, ready(efficiency))
- const analysisView = eventAnalysisPanel(analysis, ready(analysis))
- check('C1-history-view-has-trend-and-event-list', historyView.blocks.some((block) => block.kind === 'trend') && historyView.blocks.some((block) => block.kind === 'list'))
- check('C2-efficiency-view-has-rate-durations-and-state-bars', efficiencyView.blocks[0].items.some((item) => item.key === 'handlingRate') && efficiencyView.blocks.some((block) => block.label === '工单状态分布'))
- check('C3-analysis-view-has-four-distributions-and-highlights', analysisView.blocks.filter((block) => block.kind === 'bars').length === 4 && analysisView.blocks.some((block) => block.label === '重点识别'))
- const emptyView = historyAnalysisPanel(null, { ...section(SECTION_STATE.EMPTY), loaded: true })
- check('C4-empty-panel-is-explicit', emptyView.hasContent === false && emptyView.placeholder.includes('没有'))
- const staleView = historyAnalysisPanel(history, { ...section(SECTION_STATE.STALE, { data: history, retained: true }), loaded: true })
- check('C5-stale-panel-retains-content', staleView.hasContent === true)
- check('D1-mode-view-is-single-source', eventListSwitchView('WARNING').codeLabel !== eventListSwitchView('ALARM').codeLabel && eventListSwitchView('WARNING').statusLabel !== eventListSwitchView('ALARM').statusLabel)
- check('D2-panel-view-dispatches-warning-builders', panelView('historyAnalysis', history, currentSection).name === 'historyAnalysis' && panelView('responseEfficiency', efficiency, ready(efficiency)).name === 'responseEfficiency' && panelView('eventAnalysis', analysis, ready(analysis)).name === 'eventAnalysis')
- const moduleRoot = new URL('../../../src/modules/cockpit/', import.meta.url)
- const read = (path) => readFileSync(new URL(path, moduleRoot), 'utf8')
- const shell = read('CockpitShell.vue')
- const pane = read('components/WarningResponsePane.vue')
- check('E1-shared-mode-and-range-controls-are-visible', pane.includes('eventStore.setMode') && pane.includes('eventStore.setRange') && shell.includes('WarningResponsePane'))
- check('E2-components-do-not-build-api-paths', !pane.includes('/events/') && !pane.includes('fetch('))
- check('E3-current-event-location-remains-detail-flow', read('components/EventDetailCard.vue').includes('定位关联设备') && read('stores/eventStore.js').includes('planEventLocate'))
- const passed = checks.filter(Boolean).length
- console.log(`\\nT19 warning-response: ${passed}/${checks.length}`)
- if (passed !== checks.length) process.exitCode = 1
|