latest-V.1

This commit is contained in:
龚皓
2024-12-05 16:05:29 +08:00
parent 62a7971f7a
commit 3e4e455dbe
14 changed files with 801 additions and 871 deletions

View File

@@ -0,0 +1,220 @@
<template>
<el-dialog title="告警提示" v-model="globalDialogVisible" width="50%" @close="handleDialogClose">
<el-row style="margin-bottom: 2vh;">
<el-col :span="17" style="text-align: center;">
<img :src="globalDialogContent.snapshotUrl" alt="告警图片" v-if="globalDialogContent.snapshotUrl"
style="max-width: 100%;" />
<!-- 可选的视频展示 -->
<!-- <video v-if="globalDialogContent.videoUrl" :src="globalDialogContent.videoUrl" controls style="max-width: 100%;"></video> -->
</el-col>
<el-col :span="7">
<el-row class="dialog-event-col">
<el-col :span="24"><strong>告警编号</strong>{{ globalDialogContent.id }}</el-col>
<el-col :span="24"><strong>告警点位</strong>{{ globalDialogContent.camera?.name }}</el-col>
<el-col :span="24"><strong>告警类型</strong>{{ globalDialogContent.types }}</el-col>
<el-col :span="24"><strong>告警时间</strong>{{ globalDialogContent.started_at }}</el-col>
</el-row>
</el-col>
</el-row>
</el-dialog>
</template>
<script lang="ts" setup>
import { ref, onMounted, onUnmounted,watch } from 'vue';
import eventBus from '@/utils/eventBus';
import { BoxApi } from '@/utils/boxApi';
import dayjs from 'dayjs';
interface GlobalDialogContent {
id: number | null;
camera_id: number | null;
camera: { name: string };
types: string | null;
started_at: string | null; // 支持 null 或字符串类型
snapshotUrl: string;
videoUrl: string;
}
const apiInstance = new BoxApi();
const globalDialogVisible = ref(false); // 控制全局对话框的可见性
const globalDialogContent = ref<GlobalDialogContent>({
id: null,
camera_id: null,
camera: { name: '' },
types: null,
started_at: null,
snapshotUrl: '',
videoUrl: ''
});
const algorithmMap = ref(new Map()); // 算法类型映射表
const requestQueue: any[] = []; // 消息队列
let isProcessing = false; // 标志是否正在处理队列
// 加载算法映射表
const loadAlgorithms = async () => {
const token = localStorage.getItem('alertToken');
if (token) {
const algorithms = await apiInstance.getAlgorithms(token);
algorithmMap.value = new Map(
algorithms.map((algo: { code_name: string; name: string }) => [algo.code_name, algo.name])
);
} else {
console.error('Token 未找到,请登录');
}
};
const fetchWithRetry = async (fetchFn: () => Promise<any>, retries = 5, delay = 2000): Promise<any> => {
for (let i = 0; i < retries; i++) {
try {
return await fetchFn();
} catch (error) {
console.error(`Retry ${i + 1} failed:`, error);
if (i < retries - 1) await new Promise((resolve) => setTimeout(resolve, delay));
}
}
throw new Error('All retries failed');
};
// const showDialog = async (data: any) => {
// const token = localStorage.getItem('alertToken');
// if (!token) {
// console.error('Token 未找到,请登录');
// return;
// }
// console.log('弹窗接收>>>>>>>>>>>>>', data);
// const eventDetails = await apiInstance.getEventById(data.id, token);
// console.log('showDialog>>>>>>>>>>>>>', eventDetails);
// const snapshot = eventDetails.mediums.find((item: any) => item.name === 'snapshot');
// const video = eventDetails.mediums.find((item: any) => item.name === 'video');
// globalDialogContent.value = {
// id: eventDetails.id,
// camera_id: eventDetails.camera_id,
// camera: eventDetails.camera,
// types: algorithmMap.value.get(eventDetails.types),
// started_at: formatDateTime(eventDetails.started_at),
// snapshotUrl: snapshot?.file || '',
// videoUrl: video?.file || ''
// };
// globalDialogVisible.value = true;
// };
const processQueue = async () => {
if (isProcessing || requestQueue.length === 0) return; // 正在处理或队列为空时不执行
isProcessing = true; // 标记正在处理
const data = requestQueue.shift(); // 从队列中取出数据
try {
const token = localStorage.getItem('alertToken');
if (!token) throw new Error('Token 未找到,请登录');
// 使用延时重试获取数据
const eventDetails = await fetchWithRetry(() => apiInstance.getEventById(data.id, token));
// console.log('processQueue>>>>>>>>>>>>>', eventDetails);
if (!eventDetails || !eventDetails.mediums) {
console.error('Event details or mediums not found:', eventDetails);
return;
}
const snapshot = eventDetails.mediums.find((item: any) => item.name === 'snapshot');
const video = eventDetails.mediums.find((item: any) => item.name === 'video');
globalDialogContent.value = {
id: eventDetails.id,
camera_id: eventDetails.camera_id,
camera: eventDetails.camera,
types: algorithmMap.value.get(eventDetails.types) || '未知类型',
started_at: formatDateTime(eventDetails.started_at),
snapshotUrl: snapshot?.file || '',
videoUrl: video?.file || ''
};
globalDialogVisible.value = true; // 显示对话框
} catch (error) {
console.error('Error processing data in queue:', error);
} finally {
isProcessing = false;
processQueue(); // 处理队列中的下一个请求
}
};
const enqueueRequest = (data: any) => {
requestQueue.push(data);
processQueue();
};
const formatDateTime = (isoString: string): string => dayjs(isoString).format('YYYY-MM-DD HH:mm:ss');
// 关闭对话框并重置内容
const handleDialogClose = () => {
globalDialogVisible.value = false;
globalDialogContent.value = {
id: null,
camera_id: null,
camera: { name: '' },
types: null,
started_at: null,
snapshotUrl: '',
videoUrl: ''
};
};
watch(globalDialogContent, (newValue, oldValue) => {
if (newValue !== oldValue) {
const dialogElement = document.querySelector('.dialog-event-col');
if (dialogElement) {
dialogElement.classList.add('border-blink');
setTimeout(() => {
dialogElement.classList.remove('border-blink');
}, 3000);
}
}
});
onMounted(async () => {
await loadAlgorithms();
// eventBus.on('showDialog', showDialog);
eventBus.on('showDialog', enqueueRequest);
});
onUnmounted(() => {
// eventBus.off('showDialog', showDialog);
eventBus.off('showDialog', enqueueRequest);
});
</script>
<style scoped>
.dialog-event-col {
font-size: 14px;
gap: 30px;
padding: 20px;
/* transition: border 0.3s ease-in-out; */
}
.border-blink {
animation: borderBlink 1s infinite;
}
@keyframes borderBlink {
0% {
border: 2px solid red;
}
50% {
border: 2px solid transparent;
}
100% {
border: 2px solid red;
}
}
</style>