yeg
2026-09-03 e194edb10bf5839b77dc423300b5efb841bb8406
修正暂停停止后的实时异常提示

暂停接收和检测完成后不再把实时流断开显示为连接异常;保留设备状态重连并补充生命周期回归契约。
1个文件已添加
1个文件已修改
26 ■■■■■ 已修改文件
src/views/TestConsole.vue 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
tests/test-console-live-lifecycle.contract.test.mjs 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/TestConsole.vue
@@ -60,6 +60,10 @@
const timer = window.setInterval(() => { if (state.value === '检测中') elapsedSeconds.value += 1 }, 1000)
onBeforeUnmount(() => window.clearInterval(timer))
function shouldShowLiveConnectionError() {
  return state.value === '检测中' && receptionState.value === '接收中'
}
function applyLiveState(next: TestLiveState) {
  liveState.value = next
  liveConnection.value = next.sources.some(source => Boolean(source.latestSnapshot?.observedAt)
@@ -99,11 +103,12 @@
    else if (event === 'exception' && Array.isArray(data) && liveState.value) {
      const current = (data as TestLiveState['exceptions']).filter(item => !item.status || item.status === 'OPEN')
      liveState.value = { ...liveState.value, exceptions: current }
      liveError.value = current.length ? '检测来源存在异常' : ''
      // 来源异常和测试预警由下方告警面板展示,不能把正常暂停/完成误报成连接错误。
      liveError.value = ''
    }
  }, error => {
    liveConnection.value = error.message.includes('权限') ? '权限不足' : '已断开'
    liveError.value = error.message
    liveError.value = shouldShowLiveConnectionError() ? error.message : ''
    scheduleLiveReconnect()
  })
}
@@ -133,7 +138,8 @@
    }
    try { applyLiveState(await getTestLiveState(testId.value)) } catch (error) {
      liveConnection.value = '已断开'
      liveError.value = error instanceof Error ? error.message : '实时状态加载失败'
      liveError.value = shouldShowLiveConnectionError()
        ? (error instanceof Error ? error.message : '实时状态加载失败') : ''
    }
    connectLiveStream()
    if (activeTab.value === 'project-chart') await loadProjectChartData()
@@ -404,6 +410,7 @@
      : await resumeTestReception(testId.value)
    state.value = pausing ? '暂停' : '检测中'
    receptionState.value = pausing ? '暂停接收' : '接收中'
    liveError.value = ''
    ElMessage.success(pausing ? '已暂停接收,系统已停止请求新数据' : '已继续接收,系统已恢复数据请求')
  } catch (error) {
    if (error === 'cancel' || error === 'close') return
@@ -431,6 +438,7 @@
    backendDetail.value = await endTestReception(testId.value)
    state.value = '检测完成'
    receptionState.value = '已结束接收'
    liveError.value = ''
    testStatusLabel.value = ({ WAITING: '待测试', RUNNING: '检测中', PAUSED: '暂停', RUNNING_ABNORMAL: '检测中', COMPLETION_PENDING: '检测完成', COMPLETED: '检测完成', TERMINATED: '检测完成' } as Record<string, string>)[backendDetail.value.testStatus || 'COMPLETED'] || '检测完成'
    ElMessage.success('测试已停止,系统不再请求数据')
  } catch (error) {
tests/test-console-live-lifecycle.contract.test.mjs
New file
@@ -0,0 +1,12 @@
import assert from 'node:assert/strict'
import { readFile } from 'node:fs/promises'
const view = await readFile(new URL('../src/views/TestConsole.vue', import.meta.url), 'utf8')
assert.match(view, /function shouldShowLiveConnectionError\(\)/)
assert.match(view, /state\.value === '检测中' && receptionState\.value === '接收中'/)
assert.match(view, /liveError\.value = shouldShowLiveConnectionError\(\) \? error\.message : ''/)
assert.match(view, /receptionState\.value = pausing \? '暂停接收' : '接收中'[\s\S]{0,180}liveError\.value = ''/)
assert.match(view, /receptionState\.value = '已结束接收'[\s\S]{0,220}liveError\.value = ''/)
console.log('测试控制台暂停/停止生命周期契约通过')