定时刷新5分
This commit is contained in:
parent
7551409394
commit
056c1c95bf
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="alert-container">
|
<div class="alert-container">
|
||||||
<!-- <el-card class="alert-card">
|
<!-- <el-card class="alert-card">
|
||||||
<div class="alert-header">告警趋势</div>
|
<div class="alert-header">告警趋势</div>
|
||||||
<el-tabs v-model="activeName" @tab-click="handleClick" class="alert-tabs">
|
<el-tabs v-model="activeName" @tab-click="handleClick" class="alert-tabs">
|
||||||
<el-tab-pane label="今日" name="first">
|
<el-tab-pane label="今日" name="first">
|
||||||
|
@ -14,247 +14,274 @@
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
</el-card> -->
|
</el-card> -->
|
||||||
<el-tabs v-model="activeName" @tab-click="handleClick" class="alert-tabs">
|
<el-tabs v-model="activeName" @tab-click="handleClick" class="alert-tabs">
|
||||||
<el-tab-pane label="今日" name="first">
|
<el-tab-pane label="今日" name="first">
|
||||||
<div ref="todayLineChartDom" class="chart-container"></div> <!-- 今日图表 -->
|
<div ref="todayLineChartDom" class="chart-container"></div> <!-- 今日图表 -->
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="本周" name="second">
|
<el-tab-pane label="本周" name="second">
|
||||||
<div ref="weekLineChartDom" class="chart-container"></div> <!-- 本周图表 -->
|
<div ref="weekLineChartDom" class="chart-container"></div> <!-- 本周图表 -->
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="最近30天" name="third"> <!-- 新增最近30天选项卡 -->
|
<el-tab-pane label="最近30天" name="third"> <!-- 新增最近30天选项卡 -->
|
||||||
<div ref="monthLineChartDom" class="chart-container"></div> <!-- 最近30天图表 -->
|
<div ref="monthLineChartDom" class="chart-container"></div> <!-- 最近30天图表 -->
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted, nextTick } from 'vue';
|
import { ref, onMounted, nextTick, onBeforeUnmount } from 'vue';
|
||||||
import * as echarts from 'echarts';
|
import * as echarts from 'echarts';
|
||||||
import { BoxApi } from '@/utils/boxApi.ts';
|
import { BoxApi } from '@/utils/boxApi.ts';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import { debounce } from 'lodash';
|
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 chartInstance = ref(null);
|
|
||||||
|
|
||||||
const weekDates = ref([]);
|
|
||||||
const monthDates = ref([]);
|
|
||||||
|
|
||||||
const apiInstance = new BoxApi();
|
|
||||||
|
|
||||||
// 设置时间范围获取计数
|
|
||||||
const getEventCount = async (timeBefore, timeAfter) => {
|
|
||||||
try {
|
|
||||||
const token = localStorage.getItem('alertToken');
|
|
||||||
const response = await apiInstance.getEventsByParams(token, 1, 1, timeBefore, timeAfter);
|
|
||||||
return response.count;
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Error fetching event count:", error);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 生成图表的配置选项
|
|
||||||
const createChartOption = (title, xAxisData, seriesData) => ({
|
|
||||||
// title: {
|
|
||||||
// text: title,
|
|
||||||
// left: 'center',
|
|
||||||
// top: '0%',
|
|
||||||
// textStyle: {
|
|
||||||
// color: '#ffffff',
|
|
||||||
// fontSize: 16,
|
|
||||||
// fontWeight: 'bold',
|
|
||||||
// fontFamily: 'Arial, sans-serif',
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
tooltip: {
|
|
||||||
trigger: 'item',
|
|
||||||
axisPointer: { type: 'line' },
|
|
||||||
formatter: (params) => {
|
|
||||||
const date = params.name;
|
|
||||||
const value = params.value;
|
|
||||||
return `<strong>时间:${date}</strong><br/>告警数量: ${value}`;
|
|
||||||
},
|
|
||||||
backgroundColor: 'rgba(50, 50, 50, 0.3)',
|
|
||||||
borderWidth: 1,
|
|
||||||
textStyle: {
|
|
||||||
color: '#fff',
|
|
||||||
fontStyle: 'italic',
|
|
||||||
fontWeight: 'bold',
|
|
||||||
fontFamily: 'Arial, sans-serif',
|
|
||||||
fontSize: 12
|
|
||||||
},
|
|
||||||
padding: 10
|
|
||||||
},
|
|
||||||
grid: {
|
|
||||||
top: '10%',
|
|
||||||
left: '5%',
|
|
||||||
right: '5%',
|
|
||||||
bottom: '20%',
|
|
||||||
},
|
|
||||||
xAxis: {
|
|
||||||
type: 'category',
|
|
||||||
data: xAxisData,
|
|
||||||
axisLabel: { color: '#fff' },
|
|
||||||
},
|
|
||||||
yAxis: {
|
|
||||||
type: 'value', minInterval: 1, axisLabel: { color: '#fff' },
|
|
||||||
splitLine: {
|
|
||||||
show: false,
|
|
||||||
lineStyle: { color: '#cccccc', width: 1, type: 'solid' }
|
|
||||||
},
|
|
||||||
},
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
name: '告警数量',
|
|
||||||
type: 'line',
|
|
||||||
data: seriesData,
|
|
||||||
smooth: true,
|
|
||||||
areaStyle: { color: 'rgba(74, 172, 178, 0.3)' },
|
|
||||||
lineStyle: { color: 'rgb(60,178,239)', width: 2 },
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
// 更新计数数据
|
|
||||||
const updateCounts = async (range) => {
|
|
||||||
let timeAfter, timeBefore = dayjs().format();
|
|
||||||
|
|
||||||
if (range === 'day') {
|
|
||||||
// 获取“今日”每小时的事件数量
|
|
||||||
for (let i = 0; i < 24; i++) {
|
|
||||||
timeAfter = dayjs().startOf('day').add(i, 'hour').format();
|
|
||||||
timeBefore = dayjs().startOf('day').add(i + 1, 'hour').format();
|
|
||||||
hourlyCounts.value[i] = await getEventCount(timeBefore, timeAfter);
|
|
||||||
// console.log(`Hour ${i}: ${hourlyCounts.value[i]}`);
|
|
||||||
}
|
|
||||||
delayedInitChart(todayLineChartDom, createChartOption('今日告警趋势', Array.from({ length: 24 }, (_, i) => `${i}:00`), hourlyCounts.value));
|
|
||||||
|
|
||||||
} else if (range === 'week') {
|
|
||||||
// 获取“本周”每天的事件数量
|
|
||||||
for (let i = 0; i < 7; i++) {
|
|
||||||
timeAfter = dayjs().subtract(i + 1, 'day').endOf('day').format();
|
|
||||||
timeBefore = dayjs().subtract(i, 'day').endOf('day').format();
|
|
||||||
dailyCounts.value[6 - i] = await getEventCount(timeBefore, timeAfter);
|
|
||||||
}
|
|
||||||
delayedInitChart(weekLineChartDom, createChartOption('本周告警趋势', weekDates.value, dailyCounts.value));
|
|
||||||
|
|
||||||
} else if (range === 'month') {
|
|
||||||
// 获取“最近30天”每天的事件数量
|
|
||||||
for (let i = 0; i < 30; i++) {
|
|
||||||
timeAfter = dayjs().subtract(i + 1, 'day').endOf('day').format();
|
|
||||||
timeBefore = dayjs().subtract(i, 'day').endOf('day').format();
|
|
||||||
monthlyCounts.value[29 - i] = await getEventCount(timeBefore, timeAfter);
|
|
||||||
}
|
|
||||||
delayedInitChart(monthLineChartDom, createChartOption('近30天告警趋势', monthDates.value, monthlyCounts.value));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 处理选项卡切换
|
|
||||||
const handleClick = async (tab) => {
|
|
||||||
const range = tab.props.name === 'first' ? 'day' : tab.props.name === 'second' ? 'week' : 'month';
|
|
||||||
await updateCounts(range);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 初始化日期
|
|
||||||
const calculateWeekDates = () => {
|
|
||||||
weekDates.value = Array.from({ length: 7 }, (_, i) => dayjs().subtract(i, 'day').format('YYYY-MM-DD')).reverse();
|
|
||||||
};
|
|
||||||
const calculateMonthDates = () => {
|
|
||||||
monthDates.value = Array.from({ length: 30 }, (_, i) => dayjs().subtract(i, 'day').format('YYYY-MM-DD')).reverse();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 图表延迟初始化
|
|
||||||
const delayedInitChart = debounce((domRef, option) => {
|
|
||||||
nextTick(() => {
|
|
||||||
if (domRef.value) {
|
|
||||||
chartInstance.value = echarts.init(domRef.value);
|
|
||||||
chartInstance.value.setOption(option);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, 300);
|
|
||||||
|
|
||||||
// 组件挂载时调用
|
|
||||||
onMounted(async () => {
|
|
||||||
calculateWeekDates();
|
|
||||||
calculateMonthDates();
|
|
||||||
await handleClick({ props: { name: 'first' } });
|
|
||||||
window.addEventListener('resize', debounce(() => {
|
|
||||||
if (chartInstance.value) chartInstance.value.resize();
|
|
||||||
}, 300));
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<style scoped>
|
const activeName = ref('first');
|
||||||
.alert-card {
|
const hourlyCounts = ref(Array(24).fill(0));
|
||||||
background-color: #001529;
|
const dailyCounts = ref(Array(7).fill(0));
|
||||||
color: #fff;
|
const monthlyCounts = ref(Array(30).fill(0));
|
||||||
border-radius: 8px;
|
|
||||||
/* padding: 10px; */
|
const todayLineChartDom = ref(null);
|
||||||
/* margin: 10px; */
|
const weekLineChartDom = ref(null);
|
||||||
|
const monthLineChartDom = ref(null);
|
||||||
|
|
||||||
|
const chartInstance = ref(null);
|
||||||
|
|
||||||
|
const weekDates = ref([]);
|
||||||
|
const monthDates = ref([]);
|
||||||
|
|
||||||
|
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);
|
||||||
|
return response.count;
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error fetching event count:", error);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
.alert-container {
|
// 生成图表的配置选项
|
||||||
background-color: #001529;
|
const createChartOption = (title, xAxisData, seriesData) => ({
|
||||||
margin: 0vh 1vw 1vh 1vw;
|
// title: {
|
||||||
/* margin-top: 0; */
|
// text: title,
|
||||||
|
// left: 'center',
|
||||||
|
// top: '0%',
|
||||||
|
// textStyle: {
|
||||||
|
// color: '#ffffff',
|
||||||
|
// fontSize: 16,
|
||||||
|
// fontWeight: 'bold',
|
||||||
|
// fontFamily: 'Arial, sans-serif',
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'item',
|
||||||
|
axisPointer: { type: 'line' },
|
||||||
|
formatter: (params) => {
|
||||||
|
const date = params.name;
|
||||||
|
const value = params.value;
|
||||||
|
return `<strong>时间:${date}</strong><br/>告警数量: ${value}`;
|
||||||
|
},
|
||||||
|
backgroundColor: 'rgba(50, 50, 50, 0.3)',
|
||||||
|
borderWidth: 1,
|
||||||
|
textStyle: {
|
||||||
|
color: '#fff',
|
||||||
|
fontStyle: 'italic',
|
||||||
|
fontWeight: 'bold',
|
||||||
|
fontFamily: 'Arial, sans-serif',
|
||||||
|
fontSize: 12
|
||||||
|
},
|
||||||
|
padding: 10
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
top: '10%',
|
||||||
|
left: '7%',
|
||||||
|
right: '5%',
|
||||||
|
bottom: '20%',
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: 'category',
|
||||||
|
data: xAxisData,
|
||||||
|
axisLabel: { color: '#fff' },
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
type: 'value', minInterval: 1, axisLabel: { color: '#fff' },
|
||||||
|
splitLine: {
|
||||||
|
show: false,
|
||||||
|
lineStyle: { color: '#cccccc', width: 1, type: 'solid' }
|
||||||
|
},
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: '告警数量',
|
||||||
|
type: 'line',
|
||||||
|
data: seriesData,
|
||||||
|
smooth: true,
|
||||||
|
areaStyle: { color: 'rgba(74, 172, 178, 0.3)' },
|
||||||
|
lineStyle: { color: 'rgb(60,178,239)', width: 2 },
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
// 更新计数数据
|
||||||
|
const updateCounts = async (range) => {
|
||||||
|
let timeAfter, timeBefore = dayjs().format();
|
||||||
|
|
||||||
|
if (range === 'day') {
|
||||||
|
// 获取“今日”每小时的事件数量
|
||||||
|
for (let i = 0; i < 24; i++) {
|
||||||
|
timeAfter = dayjs().startOf('day').add(i, 'hour').format();
|
||||||
|
timeBefore = dayjs().startOf('day').add(i + 1, 'hour').format();
|
||||||
|
hourlyCounts.value[i] = await getEventCount(timeBefore, timeAfter);
|
||||||
|
// console.log(`Hour ${i}: ${hourlyCounts.value[i]}`);
|
||||||
|
}
|
||||||
|
delayedInitChart(todayLineChartDom, createChartOption('今日告警趋势', Array.from({ length: 24 }, (_, i) => `${i}:00`), hourlyCounts.value));
|
||||||
|
|
||||||
|
} else if (range === 'week') {
|
||||||
|
// 获取“本周”每天的事件数量
|
||||||
|
for (let i = 0; i < 7; i++) {
|
||||||
|
timeAfter = dayjs().subtract(i + 1, 'day').endOf('day').format();
|
||||||
|
timeBefore = dayjs().subtract(i, 'day').endOf('day').format();
|
||||||
|
dailyCounts.value[6 - i] = await getEventCount(timeBefore, timeAfter);
|
||||||
|
}
|
||||||
|
delayedInitChart(weekLineChartDom, createChartOption('本周告警趋势', weekDates.value, dailyCounts.value));
|
||||||
|
|
||||||
|
} else if (range === 'month') {
|
||||||
|
// 获取“最近30天”每天的事件数量
|
||||||
|
for (let i = 0; i < 30; i++) {
|
||||||
|
timeAfter = dayjs().subtract(i + 1, 'day').endOf('day').format();
|
||||||
|
timeBefore = dayjs().subtract(i, 'day').endOf('day').format();
|
||||||
|
monthlyCounts.value[29 - i] = await getEventCount(timeBefore, timeAfter);
|
||||||
|
}
|
||||||
|
delayedInitChart(monthLineChartDom, createChartOption('近30天告警趋势', monthDates.value, monthlyCounts.value));
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/* .alert-header {
|
// 处理选项卡切换
|
||||||
|
const handleClick = async (tab) => {
|
||||||
|
const range = tab.props.name === 'first' ? 'day' : tab.props.name === 'second' ? 'week' : 'month';
|
||||||
|
await updateCounts(range);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 初始化日期
|
||||||
|
const calculateWeekDates = () => {
|
||||||
|
weekDates.value = Array.from({ length: 7 }, (_, i) => dayjs().subtract(i, 'day').format('YYYY-MM-DD')).reverse();
|
||||||
|
};
|
||||||
|
const calculateMonthDates = () => {
|
||||||
|
monthDates.value = Array.from({ length: 30 }, (_, i) => dayjs().subtract(i, 'day').format('YYYY-MM-DD')).reverse();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 图表延迟初始化
|
||||||
|
const delayedInitChart = debounce((domRef, option) => {
|
||||||
|
nextTick(() => {
|
||||||
|
if (domRef.value) {
|
||||||
|
chartInstance.value = echarts.init(domRef.value);
|
||||||
|
chartInstance.value.setOption(option);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, 300);
|
||||||
|
|
||||||
|
// 组件挂载时调用
|
||||||
|
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));
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
globalTimerStore.unregisterCallback(updateChartData);
|
||||||
|
globalTimerStore.stopTimer();
|
||||||
|
window.removeEventListener('resize', debounce(() => {
|
||||||
|
if (chartInstance.value) chartInstance.value.resize();
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.alert-card {
|
||||||
|
background-color: #001529;
|
||||||
|
color: #fff;
|
||||||
|
border-radius: 8px;
|
||||||
|
/* padding: 10px; */
|
||||||
|
/* margin: 10px; */
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-container {
|
||||||
|
background-color: #001529;
|
||||||
|
margin: 0vh 1vw 1vh 1vw;
|
||||||
|
/* margin-top: 0; */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* .alert-header {
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
border-bottom: 1px solid #3a4b5c;
|
border-bottom: 1px solid #3a4b5c;
|
||||||
} */
|
} */
|
||||||
|
|
||||||
.chart-container {
|
|
||||||
/* min-height: 350px; */
|
|
||||||
width: 100%;
|
|
||||||
height: 15vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .el-tabs__item {
|
.chart-container {
|
||||||
color: #fff;
|
/* min-height: 350px; */
|
||||||
font-size: 13px;
|
width: 100%;
|
||||||
padding: 0;
|
height: 15vh;
|
||||||
margin-left: 1vh;
|
}
|
||||||
height: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .el-tabs__item.is-active {
|
::v-deep .el-tabs__item {
|
||||||
color: #2ea0ec;
|
color: #fff;
|
||||||
}
|
font-size: 13px;
|
||||||
|
padding: 0;
|
||||||
|
margin-left: 1vh;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
/* ::v-deep .el-tabs___nav-wrap.is-top::after{
|
::v-deep .el-tabs__item.is-active {
|
||||||
|
color: #2ea0ec;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ::v-deep .el-tabs___nav-wrap.is-top::after{
|
||||||
border: none;
|
border: none;
|
||||||
} */
|
} */
|
||||||
|
|
||||||
/* ::v-deep .el-tabs__active-bar.is-top{
|
/* ::v-deep .el-tabs__active-bar.is-top{
|
||||||
padding: 0 204px;
|
padding: 0 204px;
|
||||||
box-sizing: border-box !important;
|
box-sizing: border-box !important;
|
||||||
background-clip: content-box !important;
|
background-clip: content-box !important;
|
||||||
} */
|
} */
|
||||||
|
.el-tabs__active-bar {
|
||||||
|
background-color: transparent !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.el-tabs__active-bar {
|
::v-deep .el-tabs__nav-wrap::after {
|
||||||
background-color: transparent !important;
|
/* width: 15vw; */
|
||||||
}
|
position: static !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
::v-deep .el-tabs__nav-wrap::after {
|
|
||||||
/* width: 15vw; */
|
|
||||||
position: static !important;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -13,7 +13,9 @@ import { ref, onMounted, onBeforeUnmount } from 'vue';
|
||||||
import * as echarts from 'echarts';
|
import * as echarts from 'echarts';
|
||||||
import { BoxApi } from '@/utils/boxApi.ts';
|
import { BoxApi } from '@/utils/boxApi.ts';
|
||||||
import { DCaret } from '@element-plus/icons-vue';
|
import { DCaret } from '@element-plus/icons-vue';
|
||||||
|
import { useGlobalTimerStore } from '@/stores/globalTimerStore';
|
||||||
|
|
||||||
|
const globalTimerStore = useGlobalTimerStore();
|
||||||
const chartContainer = ref(null);
|
const chartContainer = ref(null);
|
||||||
let myChart = null;
|
let myChart = null;
|
||||||
const cameras = ref([]);
|
const cameras = ref([]);
|
||||||
|
@ -98,7 +100,7 @@ const option = ref({
|
||||||
data: [], // 动态填充告警数量
|
data: [], // 动态填充告警数量
|
||||||
type: "bar",
|
type: "bar",
|
||||||
barWidth: 10,
|
barWidth: 10,
|
||||||
padding:[0],
|
padding: [0],
|
||||||
showBackground: true,
|
showBackground: true,
|
||||||
barBorderRadius: [30, 0, 0, 30],
|
barBorderRadius: [30, 0, 0, 30],
|
||||||
backgroundStyle: { color: 'rgba(9, 68, 131, .2)' },
|
backgroundStyle: { color: 'rgba(9, 68, 131, .2)' },
|
||||||
|
@ -236,18 +238,14 @@ const fetchCameras = async () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 清理轮播和事件监听
|
const resizeChart = () => {
|
||||||
onBeforeUnmount(() => {
|
if (myChart && !myChart.isDisposed()) {
|
||||||
if (dataZoomMoveTimer) {
|
myChart.resize();
|
||||||
clearInterval(dataZoomMoveTimer);
|
} else {
|
||||||
dataZoomMoveTimer = null; // 确保计时器被清空
|
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);
|
window.addEventListener('resize', resizeChart);
|
||||||
|
|
||||||
|
globalTimerStore.registerCallback(fetchCameras);
|
||||||
|
globalTimerStore.startTimer();
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 清理轮播和事件监听
|
||||||
const resizeChart = () => {
|
onBeforeUnmount(() => {
|
||||||
if (myChart && !myChart.isDisposed()) {
|
if (dataZoomMoveTimer) {
|
||||||
myChart.resize();
|
clearInterval(dataZoomMoveTimer);
|
||||||
} else {
|
dataZoomMoveTimer = null; // 确保计时器被清空
|
||||||
console.warn('Attempted to resize a disposed ECharts instance.');
|
|
||||||
}
|
}
|
||||||
};
|
if (myChart) {
|
||||||
|
window.removeEventListener('resize', resizeChart); // 确保事件监听器被移除
|
||||||
|
myChart.dispose();
|
||||||
|
myChart = null;
|
||||||
|
}
|
||||||
|
globalTimerStore.unregisterCallback(fetchCameras);
|
||||||
|
globalTimerStore.stopTimer();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
// const resizeChart = () => {
|
// const resizeChart = () => {
|
||||||
|
@ -283,23 +291,25 @@ const resizeChart = () => {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.leftMiddle-box{
|
.leftMiddle-box {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
height: 41vh;
|
height: 41vh;
|
||||||
margin: 20px;
|
margin: 20px;
|
||||||
}
|
}
|
||||||
.show-bt{
|
|
||||||
|
.show-bt {
|
||||||
background-color: #001529;
|
background-color: #001529;
|
||||||
border: #001529;
|
border: #001529;
|
||||||
width: 6vw;
|
width: 79px;
|
||||||
height: 4vh;
|
height: 30px;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
color: white;
|
color: white;
|
||||||
font-weight: bolder;
|
font-weight: bolder;
|
||||||
font-size: 15px;
|
font-size: 0.9rem;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chart-container {
|
.chart-container {
|
||||||
/* margin: 0 1vw 0 1vw; */
|
/* margin: 0 1vw 0 1vw; */
|
||||||
padding-top: 0;
|
padding-top: 0;
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
<!-- 右侧分为两行 -->
|
<!-- 右侧分为两行 -->
|
||||||
<el-col :sm="24" :md="16">
|
<el-col :sm="24" :md="16">
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :sm="24" :md="24">
|
<el-col :sm="24" :md="24" class="inner-title-text">
|
||||||
通道总数:
|
通道总数:
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
@ -41,7 +41,7 @@
|
||||||
<!-- 右侧分为两行 -->
|
<!-- 右侧分为两行 -->
|
||||||
<el-col :sm="24" :md="16">
|
<el-col :sm="24" :md="16">
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :sm="24" :md="24">
|
<el-col :sm="24" :md="24" class="inner-title-text">
|
||||||
在线:
|
在线:
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
@ -64,7 +64,7 @@
|
||||||
<!-- 右侧分为两行 -->
|
<!-- 右侧分为两行 -->
|
||||||
<el-col :sm="24" :md="16">
|
<el-col :sm="24" :md="16">
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :sm="24" :md="24">
|
<el-col :sm="24" :md="24" class="inner-title-text">
|
||||||
离线:
|
离线:
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
@ -89,7 +89,7 @@
|
||||||
<!-- 右侧分为两行 -->
|
<!-- 右侧分为两行 -->
|
||||||
<el-col :sm="24" :md="16">
|
<el-col :sm="24" :md="16">
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :sm="24" :md="24">
|
<el-col :sm="24" :md="24" class="inner-title-text">
|
||||||
事件总数:
|
事件总数:
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
@ -112,7 +112,7 @@
|
||||||
<!-- 右侧分为两行 -->
|
<!-- 右侧分为两行 -->
|
||||||
<el-col :sm="24" :md="16">
|
<el-col :sm="24" :md="16">
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :sm="24" :md="24">
|
<el-col :sm="24" :md="24" class="inner-title-text">
|
||||||
已处理:
|
已处理:
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
@ -135,7 +135,7 @@
|
||||||
<!-- 右侧分为两行 -->
|
<!-- 右侧分为两行 -->
|
||||||
<el-col :sm="24" :md="16">
|
<el-col :sm="24" :md="16">
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :sm="24" :md="24">
|
<el-col :sm="24" :md="24" class="inner-title-text">
|
||||||
未处理:
|
未处理:
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
@ -163,6 +163,7 @@ import CameraOffline from '@/icons/CameraOffline.vue';
|
||||||
import EventAll from '@/icons/EventAll.vue';
|
import EventAll from '@/icons/EventAll.vue';
|
||||||
import EventClosed from '@/icons/EventClosed.vue';
|
import EventClosed from '@/icons/EventClosed.vue';
|
||||||
import EventPending from '@/icons/EventPending.vue';
|
import EventPending from '@/icons/EventPending.vue';
|
||||||
|
import { useGlobalTimerStore } from '@/stores/globalTimerStore';
|
||||||
|
|
||||||
const apiInstance = new BoxApi();
|
const apiInstance = new BoxApi();
|
||||||
const cameraCount = ref(0);
|
const cameraCount = ref(0);
|
||||||
|
@ -320,8 +321,19 @@ onMounted(() => {
|
||||||
// getMonthData();
|
// getMonthData();
|
||||||
fetchCameras();
|
fetchCameras();
|
||||||
fetchEvents();
|
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%;
|
height: 100%;
|
||||||
margin: 1vh;
|
margin: 1vh;
|
||||||
padding: 2vh 0;
|
padding: 2vh 0;
|
||||||
|
overflow-y: scroll;
|
||||||
|
scrollbar-width:none;
|
||||||
|
}
|
||||||
|
.count-container::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -341,14 +357,19 @@ onMounted(() => {
|
||||||
.bottom-row {
|
.bottom-row {
|
||||||
background-color: #001529;
|
background-color: #001529;
|
||||||
color: aliceblue;
|
color: aliceblue;
|
||||||
padding: 0;
|
padding: 0.5vh;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.inner-title-text{
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.inner-count-text {
|
.inner-count-text {
|
||||||
color: rgb(91, 224, 241);
|
color: rgb(91, 224, 241);
|
||||||
|
font-size: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab-div {
|
.tab-div {
|
||||||
|
@ -357,7 +378,7 @@ onMounted(() => {
|
||||||
|
|
||||||
::v-deep .el-tabs__item {
|
::v-deep .el-tabs__item {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
font-size: 13px;
|
font-size: 0.8rem;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin-left: 1vh;
|
margin-left: 1vh;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
|
|
|
@ -3,18 +3,18 @@
|
||||||
|
|
||||||
<div class="search-row">
|
<div class="search-row">
|
||||||
<div class="bt-search">
|
<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>
|
||||||
<div class="start-col">
|
<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>
|
||||||
<div class="end-col">
|
<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>
|
</div>
|
||||||
<div id="3d-bar-chart" class="myPanChart" ></div>
|
<div id="3d-bar-chart" class="myPanChart"></div>
|
||||||
|
|
||||||
<!-- <el-row>
|
<!-- <el-row>
|
||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
|
@ -31,9 +31,13 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<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 { BoxApi } from '@/utils/boxApi.ts';
|
||||||
import * as echarts from 'echarts';
|
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 apiInstance = new BoxApi();
|
||||||
const typeMapping = reactive({});
|
const typeMapping = reactive({});
|
||||||
|
@ -60,22 +64,118 @@ const renderChart = () => {
|
||||||
const chartInstance = echarts.init(chartDom);
|
const chartInstance = echarts.init(chartDom);
|
||||||
|
|
||||||
const colorList = [
|
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, [
|
new echarts.graphic.LinearGradient(1, 0, 0, 0, [
|
||||||
{ offset: 0, color: "rgba(255,181,111,1)" },
|
{ offset: 0, color: "rgba(135, 206, 250,0.7)" },
|
||||||
{ offset: 1, color: "rgba(255,181,111,0.3)" }
|
{ offset: 1, color: "rgba(135, 206, 250,0.3)" }
|
||||||
]),
|
]),
|
||||||
new echarts.graphic.LinearGradient(0, 1, 0, 0, [
|
new echarts.graphic.LinearGradient(0, 1, 0, 0, [
|
||||||
{ offset: 0, color: "rgba(101,122,250,1)" },
|
{ offset: 0, color: "rgba(95, 158, 160,0.8)" },
|
||||||
{ offset: 1, color: "rgba(101,122,250,0.3)" }
|
{ 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, [
|
new echarts.graphic.LinearGradient(0, 0, 1, 0, [
|
||||||
{ offset: 0, color: "rgba(45,190,146,1)" },
|
{ offset: 0, color: "rgba(75, 0, 130,0.8)" },
|
||||||
{ offset: 1, color: "rgba(45,190,146,0.3)" }
|
{ 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%'],
|
radius: ['10%', '90%'],
|
||||||
center: ['50%', '50%'],
|
center: ['50%', '50%'],
|
||||||
avoidLabelOverlap: true,
|
avoidLabelOverlap: true,
|
||||||
padding:[0,10],
|
padding: [0, 10],
|
||||||
label: {
|
label: {
|
||||||
show: true,
|
show: true,
|
||||||
position: 'inside',
|
position: 'inside',
|
||||||
|
@ -202,9 +302,9 @@ const handleFilter = () => {
|
||||||
const timeAfter = filterParams.timeAfter ? formatDateTimeToISO(new Date(filterParams.timeAfter)) : null;
|
const timeAfter = filterParams.timeAfter ? formatDateTimeToISO(new Date(filterParams.timeAfter)) : null;
|
||||||
const timeBefore = filterParams.timeBefore ? formatDateTimeToISO(new Date(filterParams.timeBefore)) : null;
|
const timeBefore = filterParams.timeBefore ? formatDateTimeToISO(new Date(filterParams.timeBefore)) : null;
|
||||||
fetchTypeCounts(timeAfter, timeBefore); // 重新统计数量,添加时间条件
|
fetchTypeCounts(timeAfter, timeBefore); // 重新统计数量,添加时间条件
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const formatDateTime = (datetime) => {
|
const formatDateTime = (datetime) => {
|
||||||
const date = new Date(datetime);
|
const date = new Date(datetime);
|
||||||
const year = date.getFullYear();
|
const year = date.getFullYear();
|
||||||
|
@ -238,10 +338,14 @@ onMounted(async () => {
|
||||||
await fetchTypeCounts(); // 初次加载时不加时间条件
|
await fetchTypeCounts(); // 初次加载时不加时间条件
|
||||||
window.addEventListener('resize', handleResize);
|
window.addEventListener('resize', handleResize);
|
||||||
await renderChart();
|
await renderChart();
|
||||||
|
globalTimerStore.registerCallback(handleFilter);
|
||||||
|
globalTimerStore.startTimer();
|
||||||
});
|
});
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
window.removeEventListener('resize', handleResize);
|
window.removeEventListener('resize', handleResize);
|
||||||
|
globalTimerStore.unregisterCallback(handleFilter);
|
||||||
|
globalTimerStore.stopTimer();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -249,7 +353,7 @@ onBeforeUnmount(() => {
|
||||||
/* .statistics-container {
|
/* .statistics-container {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
} */
|
} */
|
||||||
.alert-container{
|
.alert-container {
|
||||||
height: auto;
|
height: auto;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
@ -262,7 +366,7 @@ onBeforeUnmount(() => {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 5vh;
|
height: 5vh;
|
||||||
} */
|
} */
|
||||||
.search-row{
|
.search-row {
|
||||||
width: 95%;
|
width: 95%;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
background-color: #001529;
|
background-color: #001529;
|
||||||
|
@ -271,11 +375,13 @@ onBeforeUnmount(() => {
|
||||||
align-items: left;
|
align-items: left;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
gap:1vh;
|
gap: 1vh;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.start-col,.end-col,.bt-search{
|
.start-col,
|
||||||
|
.end-col,
|
||||||
|
.bt-search {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: left;
|
justify-content: left;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
@ -289,18 +395,18 @@ onBeforeUnmount(() => {
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.myPanChart{
|
.myPanChart {
|
||||||
width: 95%;
|
width: 95%;
|
||||||
height: 25vh;
|
height: 25vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
::v-deep .search-row .el-input__wrapper{
|
::v-deep .search-row .el-input__wrapper {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
border-radius: 0px;
|
border-radius: 0px;
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.alert-bt{
|
.alert-bt {
|
||||||
background-color: #001529;
|
background-color: #001529;
|
||||||
/* background-color: #4a4a4a; */
|
/* background-color: #4a4a4a; */
|
||||||
border: #001529;
|
border: #001529;
|
||||||
|
|
|
@ -13,16 +13,20 @@ import '@kjgl77/datav-vue3/dist/style.css';
|
||||||
import mitt from 'mitt';
|
import mitt from 'mitt';
|
||||||
import Antd from 'ant-design-vue';
|
import Antd from 'ant-design-vue';
|
||||||
import 'ant-design-vue/dist/reset.css';
|
import 'ant-design-vue/dist/reset.css';
|
||||||
|
import { createPinia } from 'pinia';
|
||||||
|
|
||||||
|
|
||||||
const app = createApp(App)
|
const app = createApp(App)
|
||||||
const globalWebSocket = useGlobalWebSocket();
|
const globalWebSocket = useGlobalWebSocket();
|
||||||
|
const pinia = createPinia();
|
||||||
|
|
||||||
app.provide('globalWebSocket', globalWebSocket);
|
app.provide('globalWebSocket', globalWebSocket);
|
||||||
// app.provide('axios', axiosInstance);
|
// app.provide('axios', axiosInstance);
|
||||||
app.use(ElementPlus, { locale: zhCn });
|
app.use(ElementPlus, { locale: zhCn });
|
||||||
app.use(router);
|
app.use(router);
|
||||||
app.use(DataVVue3);
|
app.use(DataVVue3);
|
||||||
app.use(Antd);
|
app.use(Antd);
|
||||||
|
app.use(pinia)
|
||||||
|
|
||||||
// 导航守卫,检查登录状态
|
// 导航守卫,检查登录状态
|
||||||
router.beforeEach((to, from, next) => {
|
router.beforeEach((to, from, next) => {
|
||||||
|
|
Loading…
Reference in New Issue