|
|
@ -1,49 +1,23 @@ |
|
|
|
<script setup lang="ts"> |
|
|
|
import { deviceSelfTestFinish, getDeviceSelfTest } from 'apis/system' |
|
|
|
import FtDialog from 'components/common/FTDialog/index.vue' |
|
|
|
import { FtMessage } from 'libs/message' |
|
|
|
import { ElMessageBox } from 'element-plus' |
|
|
|
import { socket } from 'libs/socket' |
|
|
|
import { sendControl } from 'libs/utils' |
|
|
|
import { onMounted, ref, watch } from 'vue' |
|
|
|
|
|
|
|
const emits = defineEmits(['ok', 'cancel']) |
|
|
|
|
|
|
|
const okLoading = ref(false) |
|
|
|
const okHandle = () => { |
|
|
|
okLoading.value = true |
|
|
|
|
|
|
|
setTimeout(() => { |
|
|
|
okLoading.value = false |
|
|
|
FtMessage.success('保存成功') |
|
|
|
emits('ok') |
|
|
|
}, 300) |
|
|
|
} |
|
|
|
|
|
|
|
const list = ['x轴是否在原点', 'y轴是否在原点', 'z轴是否在原点'] |
|
|
|
const list = ['x轴回原点', 'y轴回原点', 'z轴回原点'] |
|
|
|
const status = ref<any>({}) |
|
|
|
onMounted(async () => { |
|
|
|
socket.init(receiveMessage, 'cmd_response') |
|
|
|
await change() |
|
|
|
socket.init(receiveMessage, 'cmd_response') // 注册socket监听 |
|
|
|
socket.init(receiveMessageSelfMove, 'self_move_test') // 注册socket监听 |
|
|
|
status.value = await getDeviceSelfTest() // 获取自检状态 |
|
|
|
list.forEach((item, index) => { // 添加自检列表 |
|
|
|
addTextToCheckList(item, index) |
|
|
|
}) |
|
|
|
}) |
|
|
|
|
|
|
|
const change = async () => { |
|
|
|
let num = 0 |
|
|
|
// await nextTick(() => { |
|
|
|
// buttonCloseRef.value?.setLoading(true) |
|
|
|
// }) |
|
|
|
status.value = await getDeviceSelfTest() |
|
|
|
|
|
|
|
const interval = async () => { |
|
|
|
if (num < list.length) { |
|
|
|
await addTextToCheckList(list[num], num) |
|
|
|
num++ |
|
|
|
await interval() // 递归调用 interval 处理下一条数据 |
|
|
|
} |
|
|
|
} |
|
|
|
await interval() |
|
|
|
// buttonCloseRef.value?.setLoading(false) |
|
|
|
} |
|
|
|
|
|
|
|
const receiveMessage = (data: any) => { |
|
|
|
if (data.status === 'success') { |
|
|
|
for (const cmdIdsKey in cmdIds) { |
|
|
@ -60,31 +34,17 @@ const receiveMessage = (data: any) => { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
const cancel = async () => { |
|
|
|
await deviceSelfTestFinish() |
|
|
|
emits('cancel') |
|
|
|
const receiveMessageSelfMove = (data: any) => { |
|
|
|
checkTextList.value.push(data) |
|
|
|
percentage.value = data.schedule |
|
|
|
if (data.type === 'error') { |
|
|
|
selfAgain.value = true |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
let cmdId = '' |
|
|
|
// const motorXYZOrigin = async () => { |
|
|
|
// buttonRef.value.setLoading(true) |
|
|
|
// cmdId = Date.now().toString() |
|
|
|
// const params = { |
|
|
|
// cmdCode: 'device_self_test', |
|
|
|
// cmdId, |
|
|
|
// params: {}, |
|
|
|
// } |
|
|
|
// |
|
|
|
// await sendControl(params) |
|
|
|
// } |
|
|
|
|
|
|
|
const cmdIds: any = {} |
|
|
|
|
|
|
|
const toHomeButtonRefs = ref() |
|
|
|
|
|
|
|
const toHome = async (index: number) => { |
|
|
|
cmdId = Date.now().toString() |
|
|
|
const cmdId = Date.now().toString() |
|
|
|
cmdIds[index] = cmdId |
|
|
|
const params = { |
|
|
|
cmdCode: ['motor_x_to_home', 'motor_y_to_home', 'motor_z_to_home'][index], |
|
|
@ -96,13 +56,9 @@ const toHome = async (index: number) => { |
|
|
|
} |
|
|
|
|
|
|
|
const checkList = ref<any>([]) |
|
|
|
// const buttonRef = ref() |
|
|
|
|
|
|
|
const closeVisible = ref(true) |
|
|
|
|
|
|
|
const addTextToCheckList = async (text: string, id: number) => { |
|
|
|
// 检查 checkList 中是否存在该 id 的对象,如果不存在则初始化 |
|
|
|
if (!checkList.value.some(item => item.id === id)) { |
|
|
|
if (!checkList.value.some((item: any) => item.id === id)) { |
|
|
|
checkList.value.push({ id, title: '', result: 'padding' }) |
|
|
|
} |
|
|
|
|
|
|
@ -111,7 +67,7 @@ const addTextToCheckList = async (text: string, id: number) => { |
|
|
|
const interval = setInterval(() => { |
|
|
|
if (displayedText.length < text.length) { |
|
|
|
displayedText += text[displayedText.length] |
|
|
|
const itemIndex = checkList.value.findIndex(item => item.id === id) |
|
|
|
const itemIndex = checkList.value.findIndex((item: any) => item.id === id) |
|
|
|
if (itemIndex !== -1) { |
|
|
|
checkList.value[itemIndex].title = displayedText |
|
|
|
} |
|
|
@ -119,7 +75,7 @@ const addTextToCheckList = async (text: string, id: number) => { |
|
|
|
else { |
|
|
|
clearInterval(interval) |
|
|
|
// 文字显示完毕后,设置 result 为 'success' 或 'failed' 以显示成功或失败图标 |
|
|
|
const itemIndex = checkList.value.findIndex(item => item.id === id) |
|
|
|
const itemIndex = checkList.value.findIndex((item: any) => item.id === id) |
|
|
|
if (itemIndex !== -1) { |
|
|
|
setTimeout(() => { |
|
|
|
checkList.value[itemIndex].result = status.value[['xAxisAtOrigin', 'yAxisAtOrigin', 'zAxisAtOrigin'][itemIndex]] ? 'success' : 'failed' |
|
|
@ -130,54 +86,118 @@ const addTextToCheckList = async (text: string, id: number) => { |
|
|
|
}, Math.random() * 100) // 修改为随机数延时 |
|
|
|
}) |
|
|
|
} |
|
|
|
const activeStep = ref(0) |
|
|
|
const percentage = ref(0) |
|
|
|
const checkTextList = ref<{ title: string, type: 'success' | 'error' }[]>([]) |
|
|
|
const selfAgain = ref(false) |
|
|
|
|
|
|
|
watch(() => checkList.value, () => { |
|
|
|
if (checkList.value.every(item => item.result === 'success')) { |
|
|
|
closeVisible.value = false |
|
|
|
let currentCommandId = '' |
|
|
|
const checkHandle = async () => { |
|
|
|
activeStep.value = 1 |
|
|
|
await ElMessageBox.confirm( |
|
|
|
'设备即将开始自检', |
|
|
|
'提示', |
|
|
|
{ |
|
|
|
confirmButtonText: '确认', |
|
|
|
showClose: false, |
|
|
|
showCancelButton: false, |
|
|
|
closeOnClickModal: false, |
|
|
|
closeOnPressEscape: false, |
|
|
|
type: 'warning', |
|
|
|
customClass: 'init-message', |
|
|
|
}, |
|
|
|
) |
|
|
|
currentCommandId = Date.now().toString() |
|
|
|
const params = { |
|
|
|
cmdId: currentCommandId, |
|
|
|
cmdCode: 'move_test', |
|
|
|
params: {}, |
|
|
|
} |
|
|
|
}, { deep: true }) |
|
|
|
await sendControl(params) |
|
|
|
} |
|
|
|
watch(percentage, (newValue) => { |
|
|
|
if (newValue === 100) { |
|
|
|
const timer = setTimeout(() => { |
|
|
|
selfAgain.value = true |
|
|
|
clearTimeout(timer) |
|
|
|
}, 300) |
|
|
|
} |
|
|
|
else { |
|
|
|
selfAgain.value = false |
|
|
|
} |
|
|
|
}) |
|
|
|
const checkAgain = async () => { |
|
|
|
checkTextList.value = [] |
|
|
|
currentCommandId = Date.now().toString() |
|
|
|
const params = { |
|
|
|
cmdId: currentCommandId, |
|
|
|
cmdCode: 'move_test', |
|
|
|
params: {}, |
|
|
|
} |
|
|
|
await sendControl(params) |
|
|
|
} |
|
|
|
const onClose = async () => { |
|
|
|
await deviceSelfTestFinish() |
|
|
|
emits('ok') |
|
|
|
} |
|
|
|
</script> |
|
|
|
|
|
|
|
<template> |
|
|
|
<FtDialog visible title="自检" width="40%" :ok-handle="okHandle" @cancel="cancel"> |
|
|
|
<div v-for="(item, index) in checkList" :key="item.id" class="mask-box"> |
|
|
|
<el-tag> {{ item.title }}</el-tag> |
|
|
|
<el-icon v-show="item.result === 'success'" color="green"> |
|
|
|
<SuccessFilled /> |
|
|
|
</el-icon> |
|
|
|
<el-icon v-show="item.result === 'failed'" color="red"> |
|
|
|
<CircleCloseFilled /> |
|
|
|
</el-icon> |
|
|
|
<el-icon v-show="item.result === 'padding'" color="gray" class="el-icon--loading"> |
|
|
|
<Loading /> |
|
|
|
</el-icon> |
|
|
|
<ft-button ref="toHomeButtonRefs" class="check-button" type="primary" :disabled="item.result === 'success'" @click="() => toHome(index)"> |
|
|
|
回原点 |
|
|
|
</ft-button> |
|
|
|
<FtDialog visible title="设备初始化" width="600px"> |
|
|
|
<el-steps style="max-width: 600px;margin-bottom: 10px" :active="activeStep" finish-status="success" align-left> |
|
|
|
<el-step title="初始化" /> |
|
|
|
<el-step title="自检" /> |
|
|
|
</el-steps> |
|
|
|
<div v-if="activeStep === 0" class="check-main"> |
|
|
|
<div v-for="(item, index) in checkList" :key="item.id" class="check-item"> |
|
|
|
<el-tag> {{ item.title }}</el-tag> |
|
|
|
<el-icon v-show="item.result === 'success'" color="green"> |
|
|
|
<SuccessFilled /> |
|
|
|
</el-icon> |
|
|
|
<el-icon v-show="item.result === 'failed'" color="red"> |
|
|
|
<CircleCloseFilled /> |
|
|
|
</el-icon> |
|
|
|
<el-icon v-show="item.result === 'padding'" color="gray" class="el-icon--loading"> |
|
|
|
<Loading /> |
|
|
|
</el-icon> |
|
|
|
<ft-button ref="toHomeButtonRefs" class="check-button" type="primary" :disabled="item.result === 'success'" @click="() => toHome(index)"> |
|
|
|
回原点 |
|
|
|
</ft-button> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div v-if="activeStep === 1" class="check-box"> |
|
|
|
<div class="progress-box"> |
|
|
|
<p> |
|
|
|
自检进度: |
|
|
|
</p> |
|
|
|
<el-progress |
|
|
|
:stroke-width="20" |
|
|
|
:percentage="percentage" |
|
|
|
/> |
|
|
|
</div> |
|
|
|
<ul> |
|
|
|
<li v-for="(item, index) in checkTextList" :key="index"> |
|
|
|
<span :style="{ color: item.type === 'success' ? '#14A656' : '#DF1515' }">{{ item.title }}</span> |
|
|
|
</li> |
|
|
|
</ul> |
|
|
|
</div> |
|
|
|
<template #footer> |
|
|
|
<ft-button :disabled="closeVisible" @click="cancel"> |
|
|
|
关闭 |
|
|
|
</ft-button> |
|
|
|
<!-- <ft-button v-else ref="buttonRef" type="primary" @click="motorXYZOrigin"> --> |
|
|
|
<!-- 回原点 --> |
|
|
|
<!-- </ft-button> --> |
|
|
|
<div style="height: 40px"> |
|
|
|
<FtButton v-if="activeStep === 0 && checkList.every((item:any) => ['success', 'ignore'].includes(item.result))" type="primary" :click-handle="checkHandle"> |
|
|
|
下一步 |
|
|
|
</FtButton> |
|
|
|
<FtButton v-if="activeStep === 1 && selfAgain" type="primary" :click-handle="checkAgain"> |
|
|
|
重新自检 |
|
|
|
</FtButton> |
|
|
|
<FtButton v-if="activeStep === 1" :click-handle="onClose"> |
|
|
|
关闭 |
|
|
|
</FtButton> |
|
|
|
</div> |
|
|
|
</template> |
|
|
|
</FtDialog> |
|
|
|
</template> |
|
|
|
|
|
|
|
<style scoped lang="scss"> |
|
|
|
.mask-box { |
|
|
|
display: flex; |
|
|
|
font-size: 35px; |
|
|
|
align-items: center; |
|
|
|
margin-bottom: 40px; |
|
|
|
.el-tag { |
|
|
|
margin-right: 20px; |
|
|
|
width: 100%; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 添加旋转动画 |
|
|
|
@keyframes spin { |
|
|
|
0% { |
|
|
@ -187,7 +207,12 @@ watch(() => checkList.value, () => { |
|
|
|
transform: rotate(360deg); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
:deep(.el-step__title) { |
|
|
|
font-size: 30px; |
|
|
|
} |
|
|
|
:deep(.el-tag__content){ |
|
|
|
font-size: 30px; |
|
|
|
} |
|
|
|
.el-icon.el-icon--loading { |
|
|
|
animation: spin 1s linear infinite; // 确保 Loading 图标应用 spin 动画 |
|
|
|
} |
|
|
@ -197,8 +222,54 @@ watch(() => checkList.value, () => { |
|
|
|
:deep(.check-button) { |
|
|
|
margin-left: 10px; |
|
|
|
.my-button { |
|
|
|
width: 230px; |
|
|
|
font-size: 30px; |
|
|
|
width: 200px; |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
.check-box { |
|
|
|
height: 20vh; |
|
|
|
font-size: 30px; |
|
|
|
ul { |
|
|
|
li { |
|
|
|
margin: 3px 0; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
.progress-box { |
|
|
|
width: 100%; |
|
|
|
height: 40px; |
|
|
|
display: flex; |
|
|
|
align-items: center; |
|
|
|
p { |
|
|
|
margin-right: 25px; |
|
|
|
font-weight: bold; |
|
|
|
} |
|
|
|
span { |
|
|
|
margin-left: 10px; |
|
|
|
} |
|
|
|
.el-progress { |
|
|
|
width: 85%; |
|
|
|
} |
|
|
|
} |
|
|
|
.check-main{ |
|
|
|
height: 20vh; |
|
|
|
overflow: auto; |
|
|
|
display: flex; // 新增 |
|
|
|
flex-direction: column; // 新增 |
|
|
|
align-items: center; // 新增 |
|
|
|
} |
|
|
|
.check-item { |
|
|
|
width: 75%; |
|
|
|
display: flex; |
|
|
|
align-items: center; |
|
|
|
margin-bottom: 10px; |
|
|
|
.el-tag { |
|
|
|
width: 50%; |
|
|
|
} |
|
|
|
.el-icon { |
|
|
|
margin: 0 10px; |
|
|
|
font-size: 18px; |
|
|
|
} |
|
|
|
} |
|
|
|
</style> |