535 lines
16 KiB
Vue
535 lines
16 KiB
Vue
<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 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>
|
||
<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" v-model:testStatus="TestStatus"
|
||
:stepsActive="stepsActive"/>
|
||
</keep-alive>
|
||
|
||
<template #footer>
|
||
<div>
|
||
<el-button type="primary" :icon="VideoPlay" v-if="ActiveStatue === 'waiting'" @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')"
|
||
@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, reactive, ref, watch} from 'vue';
|
||
import {ElMessage, ElMessageBox} from 'element-plus'
|
||
import {Coin, Edit, Key, Odometer, Refresh, Right, SuccessFilled, UploadFilled, VideoPause, VideoPlay} from '@element-plus/icons-vue'
|
||
import ComparePreTest from './comparePreTest.vue'
|
||
import CompareTest from './compareTest.vue'
|
||
import socketClient from '@/utils/webSocketClient';
|
||
import {useCheckStore} from "@/stores/modules/check";
|
||
import {pauseTest, resumeTest, startPreTest,contrastTest,getContrastTestNumInfo} from '@/api/socket/socket'
|
||
import {useUserStore} from "@/stores/modules/user";
|
||
import {JwtUtil} from "@/utils/jwtUtil";
|
||
|
||
|
||
const userStore = useUserStore()
|
||
const checkStore = useCheckStore();
|
||
const nextStepText = ref('下一步');
|
||
const dialogVisible = ref(false)
|
||
|
||
const showSteps = ref(false)
|
||
const stepsTotalNum = ref(-1);//步骤总数
|
||
const stepsActiveIndex = ref(1); //当前正在执行的步骤索引
|
||
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 = ref(null)
|
||
|
||
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 = 1
|
||
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 = 1
|
||
stepsActive.value = 1
|
||
return
|
||
}
|
||
if (testSelected.value) {
|
||
stepsActiveView.value = 2
|
||
stepsActive.value = 2
|
||
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 open = async (title: string,mapping:any,plan: string,login: string,devIdsArray: [],standardDevIdsArray: [],pair:any) => {
|
||
if(checkStore.selectTestItems.preTest && !checkStore.selectTestItems.test){
|
||
testAgain.value = true
|
||
}
|
||
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 () => {
|
||
stepsActiveIndex.value = 1
|
||
stepsActiveView.value = 1
|
||
stepsActive.value = 1
|
||
let count = 0
|
||
for (let key in checkStore.selectTestItems) {
|
||
if (checkStore.selectTestItems[key]) {
|
||
count++
|
||
}
|
||
}
|
||
stepsTotalNum.value = count + 1
|
||
|
||
// 通知子组件清空并重新初始化
|
||
if (preTestRef.value) {
|
||
preTestRef.value.initializeParameters();
|
||
}
|
||
|
||
// 重置状态
|
||
ActiveStatue.value = 'waiting'
|
||
preTestStatus.value = 'waiting'
|
||
|
||
const checkNum = await mapValue()
|
||
|
||
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],
|
||
num: checkNum
|
||
})
|
||
|
||
preTestStatus.value = 'start'
|
||
};
|
||
|
||
//开始检测
|
||
const handleSubmitFast = async () => {
|
||
if (!dataSocket.socketServe.connected) {
|
||
ElMessage.error('webSocket连接中断!')
|
||
return
|
||
}
|
||
|
||
const checkNum = await mapValue()
|
||
|
||
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],
|
||
num: checkNum
|
||
})
|
||
preTestStatus.value = 'start'
|
||
}
|
||
}
|
||
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],
|
||
num: checkNum
|
||
})
|
||
}
|
||
TestStatus.value = 'start'
|
||
} else if (TestStatus.value == 'paused') {
|
||
// 发送继续指令
|
||
//sendResume()
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
const mapValue = (async () => {
|
||
const data = await getContrastTestNumInfo(checkStore.plan.id)
|
||
// 解析返回的数据,现在是 map 类型 {99: 1}
|
||
const dataMap = data.data as Record<string, number>
|
||
// 获取键值对
|
||
const entries = Object.entries(dataMap)
|
||
// 获取第一对键值
|
||
const [key, value] = entries[0]
|
||
|
||
return value
|
||
})
|
||
|
||
|
||
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) {
|
||
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: "cdf",
|
||
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
|
||
console.log('stepsActiveView.value999', stepsActiveView.value)
|
||
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> |