定时刷新5分

This commit is contained in:
龚皓 2024-11-26 16:25:47 +08:00
parent 7551409394
commit 056c1c95bf
5 changed files with 461 additions and 293 deletions

View File

@ -26,34 +26,46 @@
</el-tab-pane>
</el-tabs>
</div>
</template>
</template>
<script setup>
import { ref, onMounted, nextTick } from 'vue';
import * as echarts from 'echarts';
import { BoxApi } from '@/utils/boxApi.ts';
import dayjs from 'dayjs';
import { debounce } from 'lodash';
<script setup>
import { ref, onMounted, nextTick, onBeforeUnmount } from 'vue';
import * as echarts from 'echarts';
import { BoxApi } from '@/utils/boxApi.ts';
import dayjs from 'dayjs';
import { debounce } from 'lodash';
import { useGlobalTimerStore } from '@/stores/globalTimerStore';
const activeName = ref('first');
const hourlyCounts = ref(Array(24).fill(0));
const dailyCounts = ref(Array(7).fill(0));
const monthlyCounts = ref(Array(30).fill(0));
const todayLineChartDom = ref(null);
const weekLineChartDom = ref(null);
const monthLineChartDom = ref(null);
const activeName = ref('first');
const hourlyCounts = ref(Array(24).fill(0));
const dailyCounts = ref(Array(7).fill(0));
const monthlyCounts = ref(Array(30).fill(0));
const chartInstance = ref(null);
const todayLineChartDom = ref(null);
const weekLineChartDom = ref(null);
const monthLineChartDom = ref(null);
const weekDates = ref([]);
const monthDates = ref([]);
const chartInstance = ref(null);
const apiInstance = new BoxApi();
const weekDates = ref([]);
const monthDates = ref([]);
//
const getEventCount = async (timeBefore, timeAfter) => {
const apiInstance = new BoxApi();
const globalTimerStore = useGlobalTimerStore();
const updateChartData = async () => {
const range =
activeName.value === 'first' ? 'day' :
activeName.value === 'second' ? 'week' : 'month';
await updateCounts(range);
};
//
const getEventCount = async (timeBefore, timeAfter) => {
try {
const token = localStorage.getItem('alertToken');
const response = await apiInstance.getEventsByParams(token, 1, 1, timeBefore, timeAfter);
@ -62,10 +74,10 @@
console.error("Error fetching event count:", error);
return 0;
}
};
};
//
const createChartOption = (title, xAxisData, seriesData) => ({
//
const createChartOption = (title, xAxisData, seriesData) => ({
// title: {
// text: title,
// left: 'center',
@ -98,7 +110,7 @@
},
grid: {
top: '10%',
left: '5%',
left: '7%',
right: '5%',
bottom: '20%',
},
@ -124,10 +136,10 @@
lineStyle: { color: 'rgb(60,178,239)', width: 2 },
},
],
});
});
//
const updateCounts = async (range) => {
//
const updateCounts = async (range) => {
let timeAfter, timeBefore = dayjs().format();
if (range === 'day') {
@ -158,103 +170,118 @@
}
delayedInitChart(monthLineChartDom, createChartOption('近30天告警趋势', monthDates.value, monthlyCounts.value));
}
};
};
//
const handleClick = async (tab) => {
//
const handleClick = async (tab) => {
const range = tab.props.name === 'first' ? 'day' : tab.props.name === 'second' ? 'week' : 'month';
await updateCounts(range);
};
};
//
const calculateWeekDates = () => {
//
const calculateWeekDates = () => {
weekDates.value = Array.from({ length: 7 }, (_, i) => dayjs().subtract(i, 'day').format('YYYY-MM-DD')).reverse();
};
const calculateMonthDates = () => {
};
const calculateMonthDates = () => {
monthDates.value = Array.from({ length: 30 }, (_, i) => dayjs().subtract(i, 'day').format('YYYY-MM-DD')).reverse();
};
};
//
const delayedInitChart = debounce((domRef, option) => {
//
const delayedInitChart = debounce((domRef, option) => {
nextTick(() => {
if (domRef.value) {
chartInstance.value = echarts.init(domRef.value);
chartInstance.value.setOption(option);
}
});
}, 300);
}, 300);
//
onMounted(async () => {
//
onMounted(async () => {
calculateWeekDates();
calculateMonthDates();
await handleClick({ props: { name: 'first' } });
//
globalTimerStore.registerCallback(updateChartData);
//
globalTimerStore.startTimer();
window.addEventListener('resize', debounce(() => {
if (chartInstance.value) chartInstance.value.resize();
}, 300));
});
</script>
});
onBeforeUnmount(() => {
globalTimerStore.unregisterCallback(updateChartData);
globalTimerStore.stopTimer();
window.removeEventListener('resize', debounce(() => {
if (chartInstance.value) chartInstance.value.resize();
}));
});
</script>
<style scoped>
.alert-card {
<style scoped>
.alert-card {
background-color: #001529;
color: #fff;
border-radius: 8px;
/* padding: 10px; */
/* margin: 10px; */
}
}
.alert-container {
.alert-container {
background-color: #001529;
margin: 0vh 1vw 1vh 1vw;
/* margin-top: 0; */
}
}
/* .alert-header {
/* .alert-header {
font-size: 18px;
font-weight: bold;
border-bottom: 1px solid #3a4b5c;
} */
.chart-container {
.chart-container {
/* min-height: 350px; */
width: 100%;
height: 15vh;
}
}
::v-deep .el-tabs__item {
::v-deep .el-tabs__item {
color: #fff;
font-size: 13px;
padding: 0;
margin-left: 1vh;
height: 20px;
}
}
::v-deep .el-tabs__item.is-active {
::v-deep .el-tabs__item.is-active {
color: #2ea0ec;
}
}
/* ::v-deep .el-tabs___nav-wrap.is-top::after{
/* ::v-deep .el-tabs___nav-wrap.is-top::after{
border: none;
} */
/* ::v-deep .el-tabs__active-bar.is-top{
/* ::v-deep .el-tabs__active-bar.is-top{
padding: 0 204px;
box-sizing: border-box !important;
background-clip: content-box !important;
} */
.el-tabs__active-bar {
.el-tabs__active-bar {
background-color: transparent !important;
}
}
::v-deep .el-tabs__nav-wrap::after {
::v-deep .el-tabs__nav-wrap::after {
/* width: 15vw; */
position: static !important;
}
</style>
}
</style>

View File

@ -13,7 +13,9 @@ import { ref, onMounted, onBeforeUnmount } from 'vue';
import * as echarts from 'echarts';
import { BoxApi } from '@/utils/boxApi.ts';
import { DCaret } from '@element-plus/icons-vue';
import { useGlobalTimerStore } from '@/stores/globalTimerStore';
const globalTimerStore = useGlobalTimerStore();
const chartContainer = ref(null);
let myChart = null;
const cameras = ref([]);
@ -98,7 +100,7 @@ const option = ref({
data: [], //
type: "bar",
barWidth: 10,
padding:[0],
padding: [0],
showBackground: true,
barBorderRadius: [30, 0, 0, 30],
backgroundStyle: { color: 'rgba(9, 68, 131, .2)' },
@ -236,18 +238,14 @@ const fetchCameras = async () => {
}
};
//
onBeforeUnmount(() => {
if (dataZoomMoveTimer) {
clearInterval(dataZoomMoveTimer);
dataZoomMoveTimer = null; //
const resizeChart = () => {
if (myChart && !myChart.isDisposed()) {
myChart.resize();
} else {
console.warn('Attempted to resize a disposed ECharts instance.');
}
if (myChart) {
window.removeEventListener('resize', resizeChart); //
myChart.dispose();
myChart = null;
}
});
};
@ -259,16 +257,26 @@ onMounted(async () => {
//
window.addEventListener('resize', resizeChart);
globalTimerStore.registerCallback(fetchCameras);
globalTimerStore.startTimer();
});
const resizeChart = () => {
if (myChart && !myChart.isDisposed()) {
myChart.resize();
} else {
console.warn('Attempted to resize a disposed ECharts instance.');
//
onBeforeUnmount(() => {
if (dataZoomMoveTimer) {
clearInterval(dataZoomMoveTimer);
dataZoomMoveTimer = null; //
}
};
if (myChart) {
window.removeEventListener('resize', resizeChart); //
myChart.dispose();
myChart = null;
}
globalTimerStore.unregisterCallback(fetchCameras);
globalTimerStore.stopTimer();
});
// const resizeChart = () => {
@ -283,23 +291,25 @@ const resizeChart = () => {
</script>
<style scoped>
.leftMiddle-box{
.leftMiddle-box {
display: flex;
flex-direction: column;
height: 41vh;
margin: 20px;
}
.show-bt{
.show-bt {
background-color: #001529;
border: #001529;
width: 6vw;
height: 4vh;
width: 79px;
height: 30px;
border-radius: 6px;
color: white;
font-weight: bolder;
font-size: 15px;
font-size: 0.9rem;
padding: 0;
}
.chart-container {
/* margin: 0 1vw 0 1vw; */
padding-top: 0;

View File

@ -18,7 +18,7 @@
<!-- 右侧分为两行 -->
<el-col :sm="24" :md="16">
<el-row>
<el-col :sm="24" :md="24">
<el-col :sm="24" :md="24" class="inner-title-text">
通道总数
</el-col>
</el-row>
@ -41,7 +41,7 @@
<!-- 右侧分为两行 -->
<el-col :sm="24" :md="16">
<el-row>
<el-col :sm="24" :md="24">
<el-col :sm="24" :md="24" class="inner-title-text">
在线
</el-col>
</el-row>
@ -64,7 +64,7 @@
<!-- 右侧分为两行 -->
<el-col :sm="24" :md="16">
<el-row>
<el-col :sm="24" :md="24">
<el-col :sm="24" :md="24" class="inner-title-text">
离线:
</el-col>
</el-row>
@ -89,7 +89,7 @@
<!-- 右侧分为两行 -->
<el-col :sm="24" :md="16">
<el-row>
<el-col :sm="24" :md="24">
<el-col :sm="24" :md="24" class="inner-title-text">
事件总数
</el-col>
</el-row>
@ -112,7 +112,7 @@
<!-- 右侧分为两行 -->
<el-col :sm="24" :md="16">
<el-row>
<el-col :sm="24" :md="24">
<el-col :sm="24" :md="24" class="inner-title-text">
已处理:
</el-col>
</el-row>
@ -135,7 +135,7 @@
<!-- 右侧分为两行 -->
<el-col :sm="24" :md="16">
<el-row>
<el-col :sm="24" :md="24">
<el-col :sm="24" :md="24" class="inner-title-text">
未处理:
</el-col>
</el-row>
@ -163,6 +163,7 @@ import CameraOffline from '@/icons/CameraOffline.vue';
import EventAll from '@/icons/EventAll.vue';
import EventClosed from '@/icons/EventClosed.vue';
import EventPending from '@/icons/EventPending.vue';
import { useGlobalTimerStore } from '@/stores/globalTimerStore';
const apiInstance = new BoxApi();
const cameraCount = ref(0);
@ -320,8 +321,19 @@ onMounted(() => {
// getMonthData();
fetchCameras();
fetchEvents();
const globalTimerStore = useGlobalTimerStore();
globalTimerStore.registerCallback(fetchCameras);
globalTimerStore.registerCallback(fetchEvents);
globalTimerStore.startTimer();
});
onBeforeUnmount(() => {
const globalTimerStore = useGlobalTimerStore();
//
globalTimerStore.unregisterCallback(fetchCameras);
globalTimerStore.unregisterCallback(fetchEvents);
});
@ -333,7 +345,11 @@ onMounted(() => {
height: 100%;
margin: 1vh;
padding: 2vh 0;
overflow-y: scroll;
scrollbar-width:none;
}
.count-container::-webkit-scrollbar {
display: none;
}
@ -341,14 +357,19 @@ onMounted(() => {
.bottom-row {
background-color: #001529;
color: aliceblue;
padding: 0;
padding: 0.5vh;
margin: 0;
}
.inner-title-text{
font-size: 0.9rem;
}
.inner-count-text {
color: rgb(91, 224, 241);
font-size: 1rem;
}
.tab-div {
@ -357,7 +378,7 @@ onMounted(() => {
::v-deep .el-tabs__item {
color: #fff;
font-size: 13px;
font-size: 0.8rem;
padding: 0;
margin-left: 1vh;
height: 20px;

View File

@ -3,18 +3,18 @@
<div class="search-row">
<div class="bt-search">
<el-button type="primary" @click="handleFilter" class="alert-bt">点击查询</el-button>
<el-button type="primary" @click="handleFilter" class="alert-bt"><el-icon><Search /></el-icon></el-button>
</div>
<div class="start-col">
<el-date-picker v-model="filterParams.timeAfter" :teleported="false" type="datetime" placeholder="请选择开始时间" prefix-icon="CaretBottom" popper-class="popperClass" ></el-date-picker>
<el-date-picker v-model="filterParams.timeAfter" :teleported="false" type="datetime" placeholder="请选择开始时间"
prefix-icon="CaretBottom" popper-class="popperClass"></el-date-picker>
</div>
<div class="end-col">
<el-date-picker v-model="filterParams.timeBefore" :teleported="false" type="datetime" placeholder="请选择结束时间" prefix-icon="CaretBottom" popper-class="popperClass" ></el-date-picker>
<el-date-picker v-model="filterParams.timeBefore" :teleported="false" type="datetime" placeholder="请选择结束时间"
prefix-icon="CaretBottom" popper-class="popperClass"></el-date-picker>
</div>
</div>
<div id="3d-bar-chart" class="myPanChart" ></div>
<div id="3d-bar-chart" class="myPanChart"></div>
<!-- <el-row>
<el-col :span="24">
@ -31,9 +31,13 @@
</template>
<script setup>
import { ref, reactive, onMounted,onBeforeUnmount,computed} from 'vue';
import { ref, reactive, onMounted, onBeforeUnmount, computed } from 'vue';
import { BoxApi } from '@/utils/boxApi.ts';
import * as echarts from 'echarts';
import { Search } from '@element-plus/icons-vue';
import { useGlobalTimerStore } from '@/stores/globalTimerStore';
const globalTimerStore = useGlobalTimerStore();
const apiInstance = new BoxApi();
const typeMapping = reactive({});
@ -60,22 +64,118 @@ const renderChart = () => {
const chartInstance = echarts.init(chartDom);
const colorList = [
// new echarts.graphic.LinearGradient(0, 0, 1, 0, [
// { offset: 0, color: "rgba(69,233,254,1)" },
// { offset: 1, color: "rgba(69,233,254,0.3)" }
// ]),
new echarts.graphic.LinearGradient(1, 0, 0, 0, [
{ offset: 0, color: "rgba(255,181,111,1)" },
{ offset: 1, color: "rgba(255,181,111,0.3)" }
{ offset: 0, color: "rgba(135, 206, 250,0.7)" },
{ offset: 1, color: "rgba(135, 206, 250,0.3)" }
]),
new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{ offset: 0, color: "rgba(101,122,250,1)" },
{ offset: 1, color: "rgba(101,122,250,0.3)" }
{ offset: 0, color: "rgba(95, 158, 160,0.8)" },
{ offset: 1, color: "rgba(95, 158, 160,0.3)" }
]),
new echarts.graphic.LinearGradient(1, 0, 0, 0, [
{ offset: 0, color: "rgba(255, 99, 71, 1)" },
{ offset: 1, color: "rgba(255, 99, 71, 0.3)" }
]),
new echarts.graphic.LinearGradient(1, 0, 0, 0, [
{ offset: 0, color: "rgba(218, 112, 214,0.6)" },
{ offset: 1, color: "rgba(218, 112, 214,0.3)" }
]),
new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{ offset: 0, color: "rgba(138, 43, 226,0.7)" },
{ offset: 1, color: "rgba(138, 43, 226,0.3)" }
]),
new echarts.graphic.LinearGradient(0, 0, 1, 0, [
{ offset: 0, color: "rgba(45,190,146,1)" },
{ offset: 1, color: "rgba(45,190,146,0.3)" }
{ offset: 0, color: "rgba(75, 0, 130,0.8)" },
{ offset: 1, color: "rgba(75, 0, 130,0.3)" }
]),
new echarts.graphic.LinearGradient(1, 0, 0, 0, [
{ offset: 0, color: "rgba(173, 216, 230,0.7)" },
{ offset: 1, color: "rgba(173, 216, 230,0.3)" }
]),
new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{ offset: 0, color: "rgba(100, 149, 237,0.8)" },
{ offset: 1, color: "rgba(100, 149, 237,0.3)" }
]),
new echarts.graphic.LinearGradient(0, 0, 1, 0, [
{ offset: 0, color: "rgba(25, 25, 112,0.9)" },
{ offset: 1, color: "rgba(25, 25, 112,0.3)" }
]),
new echarts.graphic.LinearGradient(1, 0, 0, 0, [
{ offset: 0, color: "rgba(64, 224, 208,0.7)" },
{ offset: 1, color: "rgba(64, 224, 208,0.3)" }
]),
new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{ offset: 0, color: "rgba(32, 178, 170,0.8)" },
{ offset: 1, color: "rgba(32, 178, 170,0.3)" }
]),
new echarts.graphic.LinearGradient(0, 0, 1, 0, [
{ offset: 0, color: "rgba(47, 79, 79,0.9)" },
{ offset: 1, color: "rgba(47, 79, 79,0.3)" }
]),
//绿 // // // // // // // // // // //
new echarts.graphic.LinearGradient(0, 0, 1, 0, [
{ offset: 0, color: "rgba(123, 104, 238,0.7)" },
{ offset: 1, color: "rgba(123, 104, 238,0.3)" }
]),
new echarts.graphic.LinearGradient(0, 0, 1, 0, [
{ offset: 0, color: "rgba(255, 165, 0, 1)" },
{ offset: 1, color: "rgba(255, 165, 0, 0.3)" }
]), //
new echarts.graphic.LinearGradient(1, 0, 0, 0, [
{ offset: 0, color: "rgba(255, 182, 193, 1)" },
{ offset: 1, color: "rgba(255, 182, 193, 0.3)" }
]), //
new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{ offset: 0, color: "rgba(250, 128, 114, 1)" },
{ offset: 1, color: "rgba(250, 128, 114, 0.3)" }
]), //
new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{ offset: 0, color: "rgba(240, 128, 128, 1)" },
{ offset: 1, color: "rgba(240, 128, 128, 0.3)" }
]), //
new echarts.graphic.LinearGradient(0, 0, 1, 0, [
{ offset: 0, color: "rgba(255, 140, 0, 1)" },
{ offset: 1, color: "rgba(255, 140, 0, 0.3)" }
]), //
new echarts.graphic.LinearGradient(1, 0, 0, 0, [
{ offset: 0, color: "rgba(255, 215, 0, 1)" },
{ offset: 1, color: "rgba(255, 215, 0, 0.3)" }
]), //
new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{ offset: 0, color: "rgba(255, 228, 181, 1)" },
{ offset: 1, color: "rgba(255, 228, 181, 0.3)" }
]), //
new echarts.graphic.LinearGradient(0, 0, 1, 0, [
{ offset: 0, color: "rgba(255, 160, 122, 1)" },
{ offset: 1, color: "rgba(255, 160, 122, 0.3)" }
]), //
new echarts.graphic.LinearGradient(1, 0, 0, 0, [
{ offset: 0, color: "rgba(250, 250, 210, 1)" },
{ offset: 1, color: "rgba(250, 250, 210, 0.3)" }
]), //
new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{ offset: 0, color: "rgba(255, 223, 186, 1)" },
{ offset: 1, color: "rgba(255, 223, 186, 0.3)" }
]), //
new echarts.graphic.LinearGradient(0, 0, 1, 0, [
{ offset: 0, color: "rgba(245, 222, 179, 1)" },
{ offset: 1, color: "rgba(245, 222, 179, 0.3)" }
]), //
];
@ -134,7 +234,7 @@ const renderChart = () => {
radius: ['10%', '90%'],
center: ['50%', '50%'],
avoidLabelOverlap: true,
padding:[0,10],
padding: [0, 10],
label: {
show: true,
position: 'inside',
@ -202,9 +302,9 @@ const handleFilter = () => {
const timeAfter = filterParams.timeAfter ? formatDateTimeToISO(new Date(filterParams.timeAfter)) : null;
const timeBefore = filterParams.timeBefore ? formatDateTimeToISO(new Date(filterParams.timeBefore)) : null;
fetchTypeCounts(timeAfter, timeBefore); //
};
const formatDateTime = (datetime) => {
const date = new Date(datetime);
const year = date.getFullYear();
@ -238,10 +338,14 @@ onMounted(async () => {
await fetchTypeCounts(); //
window.addEventListener('resize', handleResize);
await renderChart();
globalTimerStore.registerCallback(handleFilter);
globalTimerStore.startTimer();
});
onBeforeUnmount(() => {
window.removeEventListener('resize', handleResize);
globalTimerStore.unregisterCallback(handleFilter);
globalTimerStore.stopTimer();
});
</script>
@ -249,7 +353,7 @@ onBeforeUnmount(() => {
/* .statistics-container {
margin-top: 20px;
} */
.alert-container{
.alert-container {
height: auto;
display: flex;
flex-direction: column;
@ -262,7 +366,7 @@ onBeforeUnmount(() => {
width: 100%;
height: 5vh;
} */
.search-row{
.search-row {
width: 95%;
padding: 0;
background-color: #001529;
@ -271,11 +375,13 @@ onBeforeUnmount(() => {
align-items: left;
flex-direction: column;
box-sizing: border-box;
gap:1vh;
gap: 1vh;
}
.start-col,.end-col,.bt-search{
.start-col,
.end-col,
.bt-search {
display: flex;
justify-content: left;
align-items: center;
@ -289,18 +395,18 @@ onBeforeUnmount(() => {
border-radius: 5px;
}
.myPanChart{
.myPanChart {
width: 95%;
height: 25vh;
}
::v-deep .search-row .el-input__wrapper{
::v-deep .search-row .el-input__wrapper {
background-color: transparent;
border-radius: 0px;
box-shadow: none;
}
.alert-bt{
.alert-bt {
background-color: #001529;
/* background-color: #4a4a4a; */
border: #001529;

View File

@ -13,16 +13,20 @@ import '@kjgl77/datav-vue3/dist/style.css';
import mitt from 'mitt';
import Antd from 'ant-design-vue';
import 'ant-design-vue/dist/reset.css';
import { createPinia } from 'pinia';
const app = createApp(App)
const globalWebSocket = useGlobalWebSocket();
const pinia = createPinia();
app.provide('globalWebSocket', globalWebSocket);
// app.provide('axios', axiosInstance);
app.use(ElementPlus, { locale: zhCn });
app.use(router);
app.use(DataVVue3);
app.use(Antd);
app.use(pinia)
// 导航守卫,检查登录状态
router.beforeEach((to, from, next) => {