-
{{ outputDsc }}
设备已合格 {{ qualified }} 台/共 {{ total }}
台
-
@@ -942,9 +938,6 @@ const initializeTableData = (templates: ChannelsTest.CoefficientVO[], index: num
height: 470px;
}
-/* .el-icon svg {
- color: #ff7171;
-} */
.icon-style {
color: #ff7171;
diff --git a/frontend/src/views/home/components/test.vue b/frontend/src/views/home/components/test.vue
index f16ce62..c42c3c7 100644
--- a/frontend/src/views/home/components/test.vue
+++ b/frontend/src/views/home/components/test.vue
@@ -685,31 +685,34 @@ const updatePercentage = async () => {
} else {
// 所有检测项完成
percentage.value = 100
- emit('update:testStatus', 'success')
-
- // 检查是否需要自动生成报告
- let { data: autoGenerate } = await getAutoGenerate()
- if (autoGenerate == 1) {
- // 自动生成报告
- let devIdList = checkStore.devices.map(item => {
- return item.deviceId
- })
-
- await generateDevReport({
- 'planId': checkStore.plan.id,
- 'devIdList': devIdList,
- 'scriptId': checkStore.plan.scriptId,
- 'planCode': checkStore.plan.code + '',
- 'pageNum': 1,
- 'pageSize': 999,
+ // 先完成所有后续操作,再emit success
+ try {
+ // 检查是否需要自动生成报告
+ let { data: autoGenerate } = await getAutoGenerate()
+ if (autoGenerate == 1) {
+ // 自动生成报告
+ let devIdList = checkStore.devices.map(item => {
+ return item.deviceId
+ })
+ await generateDevReport({
+ 'planId': checkStore.plan.id,
+ 'devIdList': devIdList,
+ 'scriptId': checkStore.plan.scriptId,
+ 'planCode': checkStore.plan.code + '',
+ 'pageNum': 1,
+ 'pageSize': 999,
+ })
+ }
+ // 提示检测完成
+ await ElMessageBox.alert('检测全部结束,你可以停留在此页面查看检测结果,或返回首页进行复检、报告生成和归档等操作', '检测完成', {
+ confirmButtonText: '确定',
})
+ // 关闭WebSocket连接
+ emit('closeWebSocket')
+ } finally {
+ // 最后才emit success,避免中断后续操作
+ emit('update:testStatus', 'success')
}
- // 提示检测完成
- ElMessageBox.alert('检测全部结束,你可以停留在此页面查看检测结果,或返回首页进行复检、报告生成和归档等操作', '检测完成', {
- confirmButtonText: '确定',
- })
- // 关闭WebSocket连接
- emit('closeWebSocket')
}
}
@@ -1176,12 +1179,25 @@ const secondToTime = (second: number) => {
return h + ':' + m + ':' + s
}
-// 组件卸载前清理定时器
+// 组件卸载前清理定时器和响应式引用
onBeforeUnmount(() => {
+ // 清理定时器
if (timer) {
clearInterval(timer)
timer = null
}
+
+ // 清理响应式数组引用,防止内存泄漏
+ deviceList.splice(0)
+ checkResult.splice(0)
+ testLogList.splice(0)
+ errorCheckItem.splice(0)
+
+ // 重置其他状态
+ scriptData.splice(0)
+ activeIndex = 0
+ checkTotal = 0
+ count = 0
})
// 暴露给父组件的方法
diff --git a/frontend/src/views/home/components/testPopup.vue b/frontend/src/views/home/components/testPopup.vue
index 5ac8c24..5444bd8 100644
--- a/frontend/src/views/home/components/testPopup.vue
+++ b/frontend/src/views/home/components/testPopup.vue
@@ -144,8 +144,8 @@ const nextStepText = ref('下一步') // 下一步按钮文本
const dialogVisible = ref(false) // 弹窗显示状态
const dialogTitle = ref('') // 弹窗标题
const showComponent = ref(true) // 是否显示检测组件
-const preTestRef = ref(null) // 预检测组件引用
-const testRef = ref(null) // 正式检测组件引用
+const preTestRef = ref<{ initializeParameters: () => void } | null>(null) // 预检测组件引用
+const testRef = ref<{ handlePause: () => void } | null>(null) // 正式检测组件引用
// ====================== 步骤控制相关变量 ======================
const showSteps = ref(false) // 是否显示步骤条
@@ -163,7 +163,9 @@ const TestStatus = ref('waiting') // 正式检测执行状态
const webMsgSend = ref() // webSocket推送的数据,用于组件间通信
// ====================== WebSocket 相关 ======================
-const dataSocket = reactive({
+const dataSocket = reactive<{
+ socketServe: typeof socketClient.Instance | null
+}>({
socketServe: socketClient.Instance, // WebSocket客户端实例
})
@@ -241,18 +243,33 @@ const open = (title: string) => {
// 如果预检测组件存在,初始化其参数
if (preTestRef.value) {
- preTestRef.value.initializeParameters()
+ preTestRef.value?.initializeParameters()
}
- // 创建WebSocket连接
- socketClient.Instance.connect()
- dataSocket.socketServe = socketClient.Instance
-
- // 注册WebSocket消息回调处理
- dataSocket.socketServe.registerCallBack('aaa', (res) => {
- // 将接收到的数据传递给子组件
- webMsgSend.value = res
- })
+ // 改进:无论什么状态,都先清理再重新建立连接
+ try {
+ // 先强制清理现有连接
+ if (dataSocket.socketServe) {
+ if (dataSocket.socketServe.connected) {
+ dataSocket.socketServe.closeWs()
+ }
+ // 清理回调
+ dataSocket.socketServe.unRegisterCallBack?.('aaa')
+ }
+
+ // 重新建立连接
+ socketClient.Instance.connect()
+ dataSocket.socketServe = socketClient.Instance
+
+ // 注册新的回调
+ dataSocket.socketServe.registerCallBack('aaa', (res) => {
+ // 将接收到的数据传递给子组件
+ webMsgSend.value = res
+ })
+ } catch (error) {
+ console.error('WebSocket连接处理失败:', error)
+ ElMessage.error('连接建立失败,请重试')
+ }
}
// ====================== 开始检测处理 ======================
@@ -505,9 +522,23 @@ const sendResume = () => {
* 关闭WebSocket连接
*/
const closeWebSocket = () => {
- // 检查连接状态,避免重复关闭WebSocket连接
- if (dataSocket.socketServe.connected) {
- dataSocket.socketServe.closeWs()
+ try {
+ if (dataSocket.socketServe) {
+ // 先清理回调
+ dataSocket.socketServe.unRegisterCallBack?.('aaa')
+
+ // 再关闭连接
+ if (dataSocket.socketServe.connected) {
+ dataSocket.socketServe.closeWs()
+ }
+
+ // 清空引用
+ dataSocket.socketServe = null
+ }
+ } catch (error) {
+ console.error('WebSocket关闭失败:', error)
+ // 强制清空引用,确保下次能正常重新连接
+ dataSocket.socketServe = null
}
}
@@ -531,13 +562,13 @@ const nextStep = () => {
// 遍历检测项,找到下一个需要执行的步骤
for (let selectTestItemsKey in checkStore.selectTestItems) {
- if (tempStep == 0 && checkStore.selectTestItems[selectTestItemsKey]) {
+ if (tempStep == 0 && checkStore.selectTestItems[selectTestItemsKey as keyof typeof checkStore.selectTestItems]) {
// 找到下一个要执行的检测项
stepsActiveView.value = idx // 设置显示的组件
stepsActive.value = idx // 设置业务逻辑步骤
return
}
- if (checkStore.selectTestItems[selectTestItemsKey] && tempStep != 0) {
+ if (checkStore.selectTestItems[selectTestItemsKey as keyof typeof checkStore.selectTestItems] && tempStep != 0) {
tempStep-- // 跳过已选择的检测项
}
idx++