Files
pqs-9100_client/frontend/src/views/home/components/compareTestPopup.vue
sjl c88128b63b 1.被检设备监测点新增是否参与检测
2.调整通道配对只显示绑定和参与检测的通道数
2025-09-17 14:08:58 +08:00

698 lines
22 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<el-dialog
:title="dialogTitle"
width="1550px"
:model-value="dialogVisible"
:before-close="beforeClose"
@close="handleClose"
height="1000px"
draggable
>
<div class="steps-container">
<el-steps
v-if="showSteps"
class="test-head-steps"
simple
:active="stepsActiveIndex"
process-status="finish"
finish-status="success"
>
<el-step
title="通道配对"
:icon="stepsActive > 0 || stepsActiveIndex > stepsTotalNum - 1 ? SuccessFilled : Switch"
@click="handleStepClick(0)"
/>
<el-step
v-if="preTestSelected"
title="预检测"
:icon="stepsActive > 1 || stepsActiveIndex > stepsTotalNum - 1 ? SuccessFilled : Edit"
@click="handleStepClick(1)"
/>
<el-step
v-if="testSelected"
title="正式检测"
:icon="stepsActive > 2 || stepsActiveIndex > stepsTotalNum - 1 ? SuccessFilled : Coin"
@click="handleStepClick(2)"
/>
<el-step title="检测完成" :icon="stepsActiveIndex > stepsTotalNum - 1 ? SuccessFilled : Key" />
</el-steps>
</div>
<keep-alive>
<ChannelPairing
v-if="stepsActiveView == 0"
ref="channelPairingRef"
:devIdList="prop.devIdList"
:pqStandardDevList="prop.pqStandardDevList"
:planIdKey="prop.planIdKey"
:deviceMonitor="deviceMonitor2"
/>
</keep-alive>
<keep-alive>
<ComparePreTest
v-if="preTestSelected && stepsActiveView == 1"
ref="preTestRef"
v-model:testStatus="preTestStatus"
:webMsgSend="webMsgSend"
:mapping="channelMapping"
/>
</keep-alive>
<keep-alive>
<CompareTest
v-if="testSelected && stepsActiveView == 2"
ref="testRef"
:webMsgSend="webMsgSend"
v-model:testStatus="TestStatus"
:stepsActive="stepsActive"
/>
</keep-alive>
<template #footer>
<div>
<el-button
type="primary"
:icon="VideoPlay"
v-if="ActiveStatue === 'waiting' && !(testSelected && stepsActiveIndex == 2)"
@click="handleSubmitFast"
>
开始检测
</el-button>
<!-- <el-button type="primary" v-if="TestStatus === 'test_init'" disabled>
<el-icon class="loading-box" style="color: #fff; margin-right: 8px">
<component :is="Refresh" />
</el-icon>
初始化中
</el-button> -->
<el-button type="primary" v-if="TestStatus == 'process'" :icon="VideoPause" @click="handlePause()">
停止检测
</el-button>
<el-button type="warning" v-if="TestStatus === 'paused_ing'" disabled>
<el-icon class="loading-box" style="color: #fff; margin-right: 8px">
<component :is="Refresh" />
</el-icon>
暂停中
</el-button>
<el-button type="warning" v-if="TestStatus == 'paused'" :icon="VideoPlay" @click="sendResume">
继续检测
</el-button>
<el-button
type="warning"
:icon="VideoPlay"
v-if="
nextStepText !== '下一步' &&
(ActiveStatue === 'success' ||
ActiveStatue === 'error' ||
ActiveStatue === 'test_init_fail' ||
ActiveStatue === 'connect_timeout' ||
ActiveStatue === 'pause_timeout' ||
ActiveStatue === 'waiting')
"
@click="handleSubmitAgain"
>
重新检测
</el-button>
<el-button
:type="ActiveStatue === 'success' ? 'primary' : 'danger'"
:icon="Right"
v-if="
nextStepText !== '下一步' &&
(ActiveStatue === 'success' ||
ActiveStatue === 'error' ||
ActiveStatue === 'test_init_fail' ||
ActiveStatue === 'connect_timeout' ||
ActiveStatue === 'pause_timeout')
"
@click="nextStep"
>
{{ nextStepText }}
</el-button>
<el-button type="primary" @click="handleQuit" v-else>退出检测</el-button>
</div>
</template>
</el-dialog>
</template>
<script lang="tsx" setup name="testPopup">
import { nextTick, PropType, reactive, ref, watch } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import {
Coin,
Edit,
Key,
Switch,
Refresh,
Right,
SuccessFilled,
UploadFilled,
VideoPause,
VideoPlay
} from '@element-plus/icons-vue'
import ComparePreTest from './comparePreTest.vue'
import ChannelPairing from './channelPairing.vue'
import { Device } from '@/api/device/interface/device'
import CompareTest from './compareTest.vue'
import socketClient from '@/utils/webSocketClient'
import { useCheckStore } from '@/stores/modules/check'
import { pauseTest, resumeTest, startPreTest, contrastTest } from '@/api/socket/socket'
import { useUserStore } from '@/stores/modules/user'
import { JwtUtil } from '@/utils/jwtUtil'
import { StandardDevice } from '@/api/device/interface/standardDevice'
const userStore = useUserStore()
const checkStore = useCheckStore()
const nextStepText = ref('下一步')
const dialogVisible = ref(false)
const channelPairingRef = ref()
const showSteps = ref(false)
const stepsTotalNum = ref(-1) //步骤总数
const stepsActiveIndex = ref(0) //当前正在执行的步骤索引
const stepsActiveView = ref(1) //当前正在执行的步骤在(预处理、守时校验、系数校准、正式检测)中的排序,仅用于页面显示
const stepsActive = ref(-1) //当前正在执行的步骤在(预处理、守时校验、系数校准、正式检测)中的排序,实际记录步骤的状态,用于切换步骤
const ActiveStatue = ref('waiting') //当前步骤状态
const preTestStatus = ref('waiting') //预检测执行状态
const TestStatus = ref('waiting') //正式检测执行状态
const webMsgSend = ref() //webSocket推送的数据
const dialogTitle = ref('')
const showComponent = ref(true)
const preTestRef = ref<InstanceType<typeof ComparePreTest> | null>(null)
const testRef: any = ref(null)
const prop = defineProps({
devIdList: {
type: Array as any,
default: []
},
pqStandardDevList: {
type: Array as any,
default: []
},
planIdKey: {
type: String,
default: ''
}
})
const dataSocket = reactive({
socketServe: socketClient.Instance
})
// 勾选的检测内容
const preTestSelected = ref(true)
const testSelected = ref(false)
const initOperate = () => {
ActiveStatue.value = 'waiting'
preTestStatus.value = 'waiting'
TestStatus.value = 'waiting'
stepsActiveIndex.value = 0
showComponent.value = true
// 初始化勾选的检测内容
preTestSelected.value = checkStore.selectTestItems.preTest
testSelected.value = checkStore.selectTestItems.test
let count = 0
for (let key in checkStore.selectTestItems) {
if (checkStore.selectTestItems[key]) {
count++
}
}
stepsTotalNum.value = count + 1
if (preTestSelected.value) {
stepsActiveView.value = 0
stepsActive.value = 0
return
}
if (testSelected.value) {
stepsActiveView.value = 0
stepsActive.value = 0
return
}
}
const channelMapping = ref<Record<string, Record<string, string>>>({})
const planId = ref('')
const loginName = ref('')
const devIds = ref<[]>()
const standardDevIds = ref<[]>()
const pairs = ref<any>()
const testAgain = ref(false) //重新检测按钮是否显示
const checkNumber = ref(0) //检测次数
const deviceMonitor2= ref<Map<string, any[]>>();
const open = async (
title: string,
mapping: any,
plan: string,
login: string,
devIdsArray: [],
standardDevIdsArray: [],
pair: any,
deviceMonitor:Map<string, any[]>
) => {
if (checkStore.selectTestItems.preTest && !checkStore.selectTestItems.test) {
testAgain.value = true
}
deviceMonitor2.value = deviceMonitor;
console.log('deviceMonitor:',deviceMonitor2.value)
checkStore.setNodesConnectable(true)
dialogTitle.value = title
channelMapping.value = mapping
planId.value = plan
loginName.value = login
devIds.value = devIdsArray
standardDevIds.value = standardDevIdsArray
pairs.value = pair
showSteps.value = true
initOperate()
dialogTitle.value = title
dialogVisible.value = true
// 等待组件渲染完成
await nextTick()
if (preTestRef.value) {
preTestRef.value.initializeParameters()
}
//开始创建webSocket客户端
socketClient.Instance.connect()
dataSocket.socketServe = socketClient.Instance
dataSocket.socketServe.registerCallBack('aaa', (res: { code: number }) => {
// console.log('Received message:', res)
// 处理来自服务器的消息
if (res.code === 20000) {
//ElMessage.error(message.message)
// loading.close()
} else {
webMsgSend.value = res
}
})
}
//预检测-重新检测
const handleSubmitAgain = async () => {
if (checkStore.selectTestItems.preTest) {
stepsActiveIndex.value = 1
stepsActiveView.value = 1
stepsActive.value = 1
} else {
stepsActiveIndex.value = 1
stepsActiveView.value = 2
stepsActive.value = 2
}
let count = 0
for (let key in checkStore.selectTestItems) {
if (checkStore.selectTestItems[key]) {
count++
}
}
stepsTotalNum.value = count + 1
// 通知子组件清空并重新初始化
if (preTestRef.value) {
preTestRef.value.initializeParameters()
}
testRef.value && testRef.value.initializeParameters()
// 重置状态
nextStepText.value = '下一步'
ActiveStatue.value = 'waiting'
preTestStatus.value = 'waiting'
TestStatus.value = 'waiting'
await contrastTest({
planId: planId.value,
loginName: loginName.value,
devIds: devIds.value,
standardDevIds: standardDevIds.value,
pairs: pairs.value,
testItemList: [checkStore.selectTestItems.preTest, false, checkStore.selectTestItems.test],
userId: userStore.userInfo.id
})
preTestStatus.value = 'start'
}
//开始检测
const handleSubmitFast = async () => {
if (channelPairingRef.value) {
const res = await channelPairingRef.value.handleNext()
if (!res) return
dialogTitle.value = res.title
channelMapping.value = res.mapping
planId.value = res.plan
loginName.value = res.login
devIds.value = res.devIdsArray
standardDevIds.value = res.standardDevIdsArray
pairs.value = res.pair
checkStore.setNodesConnectable(false)
// nodesConnectable.value = false
}
if (!dataSocket.socketServe.connected) {
ElMessage.error('webSocket连接中断')
return
}
if (checkStore.selectTestItems.preTest) {
stepsActiveIndex.value = 1
stepsActiveView.value = 1
stepsActive.value = 1
} else {
stepsActiveIndex.value = 1
stepsActiveView.value = 2
stepsActive.value = 2
}
switch (stepsActive.value) {
case 1:
if (preTestStatus.value == 'waiting') {
if (checkStore.selectTestItems.preTest) {
await contrastTest({
planId: planId.value,
loginName: loginName.value,
devIds: devIds.value,
standardDevIds: standardDevIds.value,
pairs: pairs.value,
testItemList: [checkStore.selectTestItems.preTest, false, checkStore.selectTestItems.test],
userId: userStore.userInfo.id
})
preTestStatus.value = 'start'
if (checkStore.selectTestItems.test) {
console.log(111111)
testRef.value.initializeParameters()
testRef.value.showTestLog()
}
}
}
break
case 2:
if (TestStatus.value == 'waiting') {
// 如果没有预检测,直接进行正式检测需要先初始化
if (!checkStore.selectTestItems.preTest && checkStore.selectTestItems.test) {
await contrastTest({
planId: planId.value,
loginName: loginName.value,
devIds: devIds.value,
standardDevIds: standardDevIds.value,
pairs: pairs.value,
testItemList: [checkStore.selectTestItems.preTest, false, checkStore.selectTestItems.test],
userId: userStore.userInfo.id
})
}
TestStatus.value = 'start'
} else if (TestStatus.value == 'paused') {
// 发送继续指令
//sendResume()
}
break
default:
break
}
}
const emit = defineEmits<{
(e: 'quitClicked'): void
}>()
watch(preTestStatus, function (newValue, oldValue) {
console.log('预检测状态', newValue, oldValue)
ActiveStatue.value = newValue
})
watch(TestStatus, function (newValue, oldValue) {
console.log('正式检测状态', newValue, oldValue)
ActiveStatue.value = newValue
})
watch(stepsActiveIndex, function (newValue, oldValue) {
if (checkStore.selectTestItems.test && checkStore.selectTestItems.preTest && newValue == 2) {
setTimeout(() => {
testRef.value.initializeParameters()
testRef.value.showTestLog()
testRef.value.startTimeCount()
}, 500)
}
console.log('步骤索引', newValue, oldValue)
})
watch(ActiveStatue, function (newValue, oldValue) {
console.log('当前步骤状态-----', newValue)
console.log('stepsActiveIndex-----', stepsActiveIndex.value)
console.log('stepsTotalNum----', stepsTotalNum.value)
if (newValue === 'error') {
stepsActiveIndex.value = stepsTotalNum.value + 1
nextStepText.value = '检测失败'
}
if (newValue === 'success' && stepsActiveIndex.value === stepsTotalNum.value - 1) {
stepsActiveIndex.value += 2
nextStepText.value = '检测完成'
}
if (newValue === 'test_init_fail') {
stepsActiveIndex.value += 2
nextStepText.value = '初始化失败'
}
if (newValue === 'connect_timeout') {
stepsActiveIndex.value += 2
nextStepText.value = '连接超时'
}
if (newValue === 'pause_timeout') {
stepsActiveIndex.value += 2
// nextStepText.value = '结束测试'
nextStepText.value = '暂停超时'
}
if (newValue === 'success' && stepsActiveIndex.value < stepsTotalNum.value - 1) {
nextStep() // 实现自动点击,进入下一个测试内容
//handleSubmitFast()
}
})
const handleQuit = () => {
console.log('handleQuit', ActiveStatue.value)
if (
ActiveStatue.value !== 'success' &&
ActiveStatue.value !== 'waiting' &&
ActiveStatue.value !== 'paused' &&
ActiveStatue.value !== 'test_init_fail' &&
ActiveStatue.value !== 'connect_timeout' &&
ActiveStatue.value !== 'pause_timeout'
) {
beforeClose(() => {})
} else {
handleClose()
}
}
const handlePause = () => {
sendPause()
testRef.value?.handlePause()
}
const sendPause = () => {
console.log('发起暂停请求')
TestStatus.value = 'paused_ing'
pauseTest()
}
const sendResume = () => {
console.log('发起继续检测请求')
resumeTest({
userPageId: JwtUtil.getLoginName(),
devIds: checkStore.devices.map(item => item.deviceId),
planId: checkStore.plan.id,
reCheckType: '2', // 0:'系数校验''1'为预检测、2为正式检测、'8'为不合格项复检
userId: userStore.userInfo.id,
temperature: checkStore.temperature,
humidity: checkStore.humidity
})
Object.assign(webMsgSend.value, {
requestId: 'Resume_Success'
})
}
const sendReCheck = () => {
console.log('发送重新检测指令')
startPreTest({
userPageId: JwtUtil.getLoginName(),
devIds: checkStore.devices.map(item => item.deviceId),
planId: checkStore.plan.id,
reCheckType: '2', // 0:'系数校验''1'为预检测、2为正式检测、'8'为不合格项复检
userId: userStore.userInfo.id,
temperature: checkStore.temperature,
humidity: checkStore.humidity,
testItemList: [
checkStore.selectTestItems.preTest,
checkStore.selectTestItems.channelsTest,
checkStore.selectTestItems.test
]
}).then(res => {
console.log(res)
if (res.code === 'A001014') {
ElMessageBox.alert('装置配置异常', '初始化失败', {
confirmButtonText: '确定',
type: 'error'
})
TestStatus.value = 'test_init_fail'
}
})
TestStatus.value = 'start'
}
const closeWebSocket = () => {
dataSocket.socketServe.closeWs()
}
const nextStep = () => {
if (
stepsActiveIndex.value == stepsTotalNum.value + 1 ||
ActiveStatue.value === 'error' ||
ActiveStatue.value === 'test_init_fail' ||
ActiveStatue.value === 'connect_timeout' ||
ActiveStatue.value === 'pause_timeout'
) {
handleClose()
return
}
if (ActiveStatue.value != 'error') {
ActiveStatue.value = 'waiting'
let tempStep = stepsActiveIndex.value
let idx = -1
stepsActiveIndex.value++
for (let selectTestItemsKey in checkStore.selectTestItems) {
if (tempStep == 0 && checkStore.selectTestItems[selectTestItemsKey]) {
console.log('selectTestItemsKey1')
stepsActiveView.value = idx
stepsActive.value = idx
return
}
if (checkStore.selectTestItems[selectTestItemsKey] && tempStep != 0) {
console.log('selectTestItemsKey2')
tempStep--
}
console.log('selectTestItemsKey3', idx)
idx++
}
}
}
const handleStepClick = (step: number) => {
if (step > stepsActive.value) {
return
} else {
stepsActiveView.value = step
}
}
function clearData() {
stepsTotalNum.value = -1
stepsActiveIndex.value = 1
stepsActiveView.value = -1
preTestStatus.value = 'waiting'
TestStatus.value = 'waiting'
ActiveStatue.value = 'waiting'
nextStepText.value = '下一步'
}
const beforeClose = (done: () => void) => {
if (stepsActiveIndex.value < stepsTotalNum.value && ActiveStatue.value != 'error') {
ElMessageBox.confirm('检测未完成,是否退出当前检测流程?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
handleClose()
})
} else {
handleClose()
}
}
const handleClose = () => {
showSteps.value = false
dataSocket.socketServe.closeWs()
dialogVisible.value = false
clearData()
showComponent.value = false
emit('quitClicked') // 触发事件
}
// 对外映射
defineExpose({ open })
</script>
<style scoped lang="scss">
.test-head-steps {
::v-deep .el-step {
.el-step__head.is-success {
color: #91cc75;
}
.el-step__title.is-success {
color: #91cc75;
}
}
}
:deep(.dialog-big .el-dialog__body) {
max-height: 840px !important;
}
.steps-container :deep(.test-head-steps) {
height: 80px;
margin-bottom: 10px;
}
.steps-container :deep(.el-step__title) {
font-size: 20px !important;
/* 设置标题字体大小 */
vertical-align: baseline !important;
display: inline-block;
/* 确保文字和图标在同一行 */
line-height: 1;
/* 调整行高以确保底部对齐 */
}
.steps-container :deep(.el-step__icon-inner) {
font-size: 18px !important;
vertical-align: baseline !important;
display: inline-block;
/* 确保文字和图标在同一行 */
line-height: 1;
/* 调整行高以确保底部对齐 */
}
.steps-container :deep(.el-step__icon) {
font-size: 18px !important;
vertical-align: baseline !important;
display: inline-block;
/* 确保文字和图标在同一行 */
line-height: 1;
/* 调整行高以确保底部对齐 */
}
.loading-box {
animation: loading 1.5s linear infinite;
}
@keyframes loading {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
</style>