告警大屏完成

This commit is contained in:
龚皓
2024-11-11 15:37:46 +08:00
parent f456cdaa8c
commit a2234922c8
30 changed files with 5551 additions and 440 deletions

View File

@@ -1,55 +1,377 @@
<template>
<div ref="chart" class="left-top-content" :style="style"></div>
<div class="count-container">
<el-tabs v-model="activeTab" class="tab-div">
<el-tab-pane label="所有" name="all"></el-tab-pane>
<el-tab-pane label="今天" name="today"></el-tab-pane>
<el-tab-pane label="7天" name="week"></el-tab-pane>
<el-tab-pane label="30天" name="month"></el-tab-pane>
</el-tabs>
<el-row class="top-row">
<el-col :span="8">
<div>
<el-row>
<!-- 左侧占据一整行 -->
<el-col :sm="24" :md="8">
<CameraAll />
</el-col>
<!-- 右侧分为两行 -->
<el-col :sm="24" :md="16">
<el-row>
<el-col :sm="24" :md="24">
通道总数
</el-col>
</el-row>
<el-row>
<el-col :sm="24" :md="24" class="inner-count-text">
{{ cameraCount }}
</el-col>
</el-row>
</el-col>
</el-row>
</div>
</el-col>
<el-col :span="8">
<div>
<el-row>
<!-- 左侧占据一整行 -->
<el-col :sm="24" :md="8">
<CameraOnline />
</el-col>
<!-- 右侧分为两行 -->
<el-col :sm="24" :md="16">
<el-row>
<el-col :sm="24" :md="24">
在线
</el-col>
</el-row>
<el-row>
<el-col :sm="24" :md="24" class="inner-count-text">
{{ cameraOnlineCount }}
</el-col>
</el-row>
</el-col>
</el-row>
</div>
</el-col>
<el-col :span="8">
<div>
<el-row>
<!-- 左侧占据一整行 -->
<el-col :sm="24" :md="8">
<CameraOffline />
</el-col>
<!-- 右侧分为两行 -->
<el-col :sm="24" :md="16">
<el-row>
<el-col :sm="24" :md="24">
离线:
</el-col>
</el-row>
<el-row>
<el-col :sm="24" :md="24" class="inner-count-text">
{{ cameraOfflineCount }}
</el-col>
</el-row>
</el-col>
</el-row>
</div>
</el-col>
</el-row>
<el-row class="bottom-row">
<el-col :span="8">
<div>
<el-row>
<!-- 左侧占据一整行 -->
<el-col :sm="24" :md="8">
<EventAll />
</el-col>
<!-- 右侧分为两行 -->
<el-col :sm="24" :md="16">
<el-row>
<el-col :sm="24" :md="24">
事件总数
</el-col>
</el-row>
<el-row>
<el-col :sm="24" :md="24" class="inner-count-text">
{{ eventCount }}
</el-col>
</el-row>
</el-col>
</el-row>
</div>
</el-col>
<el-col :span="8">
<div>
<el-row>
<!-- 左侧占据一整行 -->
<el-col :sm="24" :md="8">
<EventClosed />
</el-col>
<!-- 右侧分为两行 -->
<el-col :sm="24" :md="16">
<el-row>
<el-col :sm="24" :md="24">
已处理:
</el-col>
</el-row>
<el-row>
<el-col :sm="24" :md="24" class="inner-count-text">
{{ closedEventCount }}
</el-col>
</el-row>
</el-col>
</el-row>
</div>
</el-col>
<el-col :span="8">
<div>
<el-row>
<!-- 左侧占据一整行 -->
<el-col :sm="24" :md="8">
<EventPending />
</el-col>
<!-- 右侧分为两行 -->
<el-col :sm="24" :md="16">
<el-row>
<el-col :sm="24" :md="24">
未处理:
</el-col>
</el-row>
<el-row>
<el-col :sm="24" :md="24" class="inner-count-text">
{{ pendintingEventCount }}
</el-col>
</el-row>
</el-col>
</el-row>
</div>
</el-col>
</el-row>
</div>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue';
import * as echarts from 'echarts';
const props = defineProps(['style']);
const chart = ref(null);
const myChart = ref(null);
const setupChart = () => {
myChart.value = echarts.init(chart.value);
const option = {
title: {},
tooltip: {},
xAxis: {
data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子']
},
yAxis: {},
series: [{
name: '销量',
type: 'bar',
data: [5, 20, 36, 10, 10, 20]
}]
<script setup>
import { ref, onMounted, onBeforeUnmount, watch } from 'vue';
import * as echarts from 'echarts';
import { BoxApi } from '@/utils/boxApi.ts';
import CameraAll from '@/icons/CameraAll.vue';
import CameraOnline from '@/icons/CameraOnline.vue';
import CameraOffline from '@/icons/CameraOffline.vue';
import EventAll from '@/icons/EventAll.vue';
import EventClosed from '@/icons/EventClosed.vue';
import EventPending from '@/icons/EventPending.vue';
const apiInstance = new BoxApi();
const cameraCount = ref(0);
const cameraOfflineCount = ref(0);
const cameraOnlineCount = ref(0);
const eventCount = ref(0);
const pendintingEventCount = ref(0);
const closedEventCount = ref(0);
const activeTab = ref('all');
const getTodayData = () => {
const today = new Date();
const startOfToday = new Date(today.getFullYear(), today.getMonth(), today.getDate());
const endOfToday = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 1);
return {
timeAfter: formatDateTime(startOfToday),
timeBefore: formatDateTime(endOfToday),
};
};
const getWeekData = () => {
const today = new Date();
const startOfWeek = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 6);
const endOfToday = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 1);
return {
timeAfter: formatDateTime(startOfWeek),
timeBefore: formatDateTime(endOfToday),
};
};
const getMonthData = () => {
const today = new Date();
const startOfMonth = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 29);
const endOfToday = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 1);
return {
timeAfter: formatDateTime(startOfMonth),
timeBefore: formatDateTime(endOfToday),
};
};
const formatDateTime = (datetime) => {
const date = new Date(datetime);
const year = date.getFullYear();
const month = (date.getMonth() + 1).toString().padStart(2, '0');
const day = date.getDate().toString().padStart(2, '0');
const hours = date.getHours().toString().padStart(2, '0');
const minutes = date.getMinutes().toString().padStart(2, '0');
const seconds = date.getSeconds().toString().padStart(2, '0');
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
};
const fetchCameras = async () => {
try {
const token = localStorage.getItem('alertToken');
const limit = 20;
let offset = 0;
let allCameras = [];
const firstResponse = await apiInstance.getCameras(limit, offset, token);
cameraCount.value = firstResponse.count;
console.log("总数》》》》》》》》》》》》》", cameraCount.value)
allCameras = firstResponse.results;
const total = cameraCount.value;
while (offset + limit < total) {
offset += limit;
const response = await apiInstance.getCameras(limit, offset, token);
allCameras = allCameras.concat(response.results);
}
allCameras.forEach((camera) => {
if (camera.status === 'online') {
cameraOnlineCount.value++;
} else if (camera.status === 'offline') {
cameraOfflineCount.value++;
} else {
exceptionCount.value++;
}
});
} catch (error) {
console.error('Error fetching cameras:', error);
}
};
// const fetchEvents = async (timeAfter = null, timeBefore = null) => {
// try {
// const token = localStorage.getItem('alertToken');
// const totalResponse = await apiInstance.getEventsByParams(token, 1, 1, timeBefore, timeAfter);
// eventCount.value = totalResponse.count;
// const pendingResponse = await apiInstance.getEventsByParams(token, 1, 1, timeBefore, timeAfter, null, null, 'pending');
// pendintingEventCount.value = pendingResponse.count;
// const closedResponse = await apiInstance.getEventsByParams(token, 1, 1, timeBefore, timeAfter, null, null, 'closed');
// closedEventCount.value = closedResponse.count;
// } catch (error) {
// console.error('获取事件数据失败:', error);
// }
// };
const fetchEvents = async () => {
try {
const token = localStorage.getItem('alertToken');
let timeRange = { timeAfter: null, timeBefore: null };
// 根据 activeTab 设置时间范围
if (activeTab.value === 'today') {
timeRange = getTodayData();
} else if (activeTab.value === 'week') {
timeRange = getWeekData();
} else if (activeTab.value === 'month') {
timeRange = getMonthData();
}
// 获取告警总数
const totalResponse = await apiInstance.getEventsByParams(token, 1, 1, timeRange.timeBefore, timeRange.timeAfter);
eventCount.value = totalResponse.count;
// 获取状态为 pending 的告警数量
const pendingResponse = await apiInstance.getEventsByParams(token, 1, 1, timeRange.timeBefore, timeRange.timeAfter, null, null, 'pending');
pendintingEventCount.value = pendingResponse.count;
// 获取状态为 closed 的告警数量
const closedResponse = await apiInstance.getEventsByParams(token, 1, 1, timeRange.timeBefore, timeRange.timeAfter, null, null, 'closed');
closedEventCount.value = closedResponse.count;
} catch (error) {
console.error('获取事件数据失败:', error);
}
};
watch(activeTab, (newTab) => {
fetchEvents();
});
onMounted(() => {
// getTodayData();
// getWeekData();
// getMonthData();
fetchCameras();
fetchEvents();
});
</script>
<style scoped>
.count-container{
width:100%;
height:100%;
margin:1vh;
padding: 2vh 0;
}
myChart.value.setOption(option);
};
onMounted(() => {
setupChart();
const resizeObserver = new ResizeObserver(() => {
myChart.value.resize(); // 调整图表大小
});
resizeObserver.observe(chart.value.parentElement); // 观察父元素
onBeforeUnmount(() => {
resizeObserver.disconnect();
myChart.value.dispose(); // 清理 ECharts 实例
});
});
</script>
<style scoped>
.left-top-content {
width: 100%; /* 与父容器宽度匹配 */
height: 100%; /* 与父容器高度匹配 */
position: relative; /* 允许子元素绝对定位 */
}
</style>
.top-row,
.bottom-row {
background-color: #001529;
color: aliceblue;
padding: 0;
margin: 0;
}
.inner-count-text {
color: rgb(91, 224, 241);
}
.tab-div{
background-color: #001529;
}
::v-deep .el-tabs__item {
color: #fff;
font-size: 13px;
padding: 0;
margin-left: 1vh;
height: 20px;
}
::v-deep .el-tabs__item.is-active {
color: #2ea0ec;
}
.el-tabs__active-bar {
background-color: transparent !important;
}
::v-deep .el-tabs__nav-wrap::after {
/* width: 15vw; */
position: static !important;
}
</style>