![]()
<script setup lang="ts">
import useMqttStore from '@/stores/modules/mqtt';
import imganimation1 from '@/assets/images/fly_test_01.png';
import imganimation2 from '@/assets/images/fly_test_02.png';
import imganimation3 from '@/assets/images/fly_test_03.png';
import imgstatic1 from '@/assets/images/fly_test_static_01.png';
import imgstatic2 from '@/assets/images/fly_test_static_02.png';
import imgstatic3 from '@/assets/images/fly_test_static_03.png';
defineOptions({
name: 'FlySelfTest',
});
const mqttStore = useMqttStore();
const styleObj = reactive({
width: '40rem',
top: '20%',
left: '40%',
});
const title = ref('飞行自检');
const flySelfTestRef = ref();
const isSuccess = ref(false);
// 获取当前飞机的实时信息
const uavData = computed(() => {
return mqttStore.CURRENT_INFO?.uav;
});
const interval = ref(null) as any;
const allStatus = ref({
status1: 'pedding',
status2: 'pedding',
status3: 'pedding',
status4: 'pedding',
status5: 'pedding',
status6: 'pedding',
status7: 'pedding',
status8: 'pedding',
status9: 'pedding',
}) as any;
const tests = ref([
{
category: '飞行器状态检测',
items: [
{ name: '健康信息检测', statusKey: 'status1' },
{ name: '电池电量检测', statusKey: 'status2' },
{ name: '搜星状态检测', statusKey: 'status3' },
],
success: false,
imgUrl: imganimation1,
imgUrlStatic: imgstatic1,
},
{
category: '飞行安全设置项检测',
items: [
{ name: 'RTK检测', statusKey: 'status4' },
{ name: '安全高度检测', statusKey: 'status5' },
{ name: '返航设置检测', statusKey: 'status6' },
],
success: false,
imgUrl: imganimation2,
imgUrlStatic: imgstatic2,
},
{
category: '起飞环境检测',
items: [
{ name: '雨量检测', statusKey: 'status7' },
{ name: '风速检测', statusKey: 'status8' },
{ name: '网络检测', statusKey: 'status9' },
],
success: false,
imgUrl: imganimation3,
imgUrlStatic: imgstatic3,
},
]);
// 检查所有类别的状态,若每个类别内的项都为 'success',则更新该类别的 success 状态
function checkCategorySuccess() {
tests.value.forEach((test) => {
// 检查当前类别下的所有项的状态
const allItemsSuccess = test.items.every(item => allStatus.value[item.statusKey] === 'success');
test.success = allItemsSuccess;
});
}
function changeStyle() {
if (isSuccess.value) {
styleObj.width = '20rem';
styleObj.top = '20%';
styleObj.left = '45%';
return;
}
styleObj.width = '40rem';
styleObj.top = '20%';
styleObj.left = '40%';
}
function initData() {
isSuccess.value = false;
title.value = '飞行自检';
changeStyle();
for (const key in allStatus.value) {
allStatus.value[key] = 'pedding';
}
checkCategorySuccess();
}
function openDialog() {
initData();
flySelfTestRef.value.open();
startTesting();
}
function startTesting() {
const statusKeys = Object.keys(allStatus.value);
let index = 0;
interval.value = setInterval(() => {
// if (interval.value) {
// clearInterval(interval.value);
// }
if (index === statusKeys.length - 1 && (uavData.value?.modeCode === undefined || uavData.value?.modeCode === 0)) {
return;
}
if (index < statusKeys.length) {
const key = statusKeys[index];
allStatus.value[key] = 'success';
index++;
checkCategorySuccess();
}
else {
clearInterval(interval.value);
const key = statusKeys[index];
allStatus.value[key] = 'success';
title.value = '';
isSuccess.value = true;
changeStyle();
checkCategorySuccess();
setTimeout(() => {
flySelfTestRef.value?.close();
}, 2000);
}
}, 6 * 1000);
watch(() => uavData.value, (newVal) => {
if (newVal?.modeCode === 1) {
title.value = '';
// 所有状态都为成功
for (const key in allStatus.value) {
allStatus.value[key] = 'success';
}
clearInterval(interval.value);
checkCategorySuccess();
setTimeout(() => {
changeStyle();
isSuccess.value = true;
}, 100);
setTimeout(() => {
flySelfTestRef.value?.close();
}, 2000);
}
}, { immediate: true, deep: true });
}
function closeDialog(bool?: boolean) {
initData();
clearInterval(interval.value);
if (!bool) {
flySelfTestRef.value?.close();
}
}
// onMounted(() => {
// setTimeout(() => {
// uavData.value.modeCode = 1;
// }, 8000);
// })
defineExpose({
openDialog,
closeDialog,
});
</script>
<template>
<Dialog
ref="flySelfTestRef"
:footer="false"
:title="title"
:dialog-style="{ width: styleObj.width, top: styleObj.top, left: styleObj.left }"
:is-close="true"
@close="closeDialog(true)"
>
<div class="w-full f-full">
<div v-if="!isSuccess" class="flex items-center justify-between pl-10 pr-10">
<div v-for="test in tests" :key="test.category" class="flex flex-col gap-[0.5rem] justify-center items-center">
<div class="img">
<img v-if="!test.success" :src="test.imgUrl" alt="">
<img v-else :src="test.imgUrlStatic" alt="">
<div v-if="!test.success" class="loading-bg" />
<div class="inner-bg" />
</div>
<div class="inline-flex flex-col gap-[0.5rem]">
<div class="title">
<span>{{ test.category }}</span>
</div>
<div v-for="item in test.items" :key="item.name" class="flex items-center gap-[0.4rem]">
<div v-if="allStatus[item.statusKey] === 'pedding'" class="loading" />
<div v-else class="flex items-center">
<PubSvgIcon name="fly_test_succ" size="1rem" />
</div>
<span class="content">{{ item.name }}</span>
</div>
</div>
</div>
</div>
<div v-else class="flex items-center">
<PubSvgIcon name="fly_test_success" size="1.5rem" class="mr-2" />
<span style="font-size: 1rem;">一切正常,准备起飞</span>
</div>
</div>
</Dialog>
</template>
<style lang="less" scoped>
.success-img {
width: 18px;
height: 18px;
margin-right: 3px;
background: url(@/assets/images/fly_test_success.png) no-repeat;
background-size: 100% 100%;
}
.title {
font-size: 16px;
font-weight: 500;
color: #f7f7f7;
}
.content {
font-size: 15px;
font-weight: 400;
color: #ffffffb3;
}
.img {
position: relative;
display: flex;
align-items: center;
justify-content: center;
width: 133px;
height: 121px;
img {
position: absolute;
top: 50%;
left: 50%;
width: 88px;
height: 88px;
transform: translate(-50%, -50%);
}
.loading-bg {
z-index: 1;
width: 88px;
height: 88px;
background: url(@/assets/images/fly_test_outer.png) no-repeat;
background-size: 100% 100%;
animation: spin 3s linear infinite;
}
.inner-bg {
position: absolute;
top: 50%;
left: 50%;
width: 100%;
height: 100%;
background: url(@/assets/images/fly_test_inner.png) no-repeat;
background-size: 100% 100%;
transform: translate(-50%, -50%);
}
}
.loading {
width: 16px;
height: 16px;
background: url(@/assets/images/fly_test_loading.png) no-repeat;
background-size: 100% 100%;
animation: spin 2s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
</style>