From fd75d299ec095c9e80dfc129bc8c168f216881f6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=BE=9A=E7=9A=93?= <1736436516@qq.com>
Date: Thu, 14 Nov 2024 16:07:42 +0800
Subject: [PATCH] =?UTF-8?q?DataStatistics=E6=95=B0=E6=8D=AE=E6=98=BE?=
=?UTF-8?q?=E7=A4=BA=E9=A1=B5=E9=9D=A2---test.vue=E4=B8=AD=E6=B5=8B?=
=?UTF-8?q?=E8=AF=95=E5=85=A8=E5=B1=80=E5=BC=B9=E7=AA=97=E6=8F=90=E7=A4=BA?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
package-lock.json | 59 +++
package.json | 5 +
src/App.vue | 94 +++-
src/bk/DataStatics新数据统计.vue | 0
src/bk/DataStatistics原始版.vue | 127 +++++
src/bk/告警数量分布问题代码.vue | 410 +++++++++++++++
src/bk/时间段告警数量分布.vue | 514 +++++++++++++++++++
src/bk/点播页面原版.vue | 411 +++++++++++++++
src/components/AlertChart.vue | 626 +++++++----------------
src/components/Channel.vue | 350 +++++++++++++
src/components/Max/CenterBottom.vue | 388 +++++----------
src/components/Max/LeftBottom.vue | 9 +-
src/components/Max/LeftTop.vue | 10 +-
src/components/Max/RightTop.vue | 8 +-
src/components/Settings.vue | 33 +-
src/html/AlertManagement.vue | 167 +++++--
src/html/DataStatistics.vue | 740 +++++++++++++++++++++++++---
src/html/Home.vue | 684 ++++++++++++-------------
src/html/Test.vue | 489 ++++++------------
src/main.ts | 4 +
src/utils/boxApi.ts | 22 +
src/utils/eventBus.ts | 5 +
src/utils/useGlobalWebSocket.ts | 54 +-
tsconfig.json | 10 +-
24 files changed, 3637 insertions(+), 1582 deletions(-)
create mode 100644 src/bk/DataStatics新数据统计.vue
create mode 100644 src/bk/DataStatistics原始版.vue
create mode 100644 src/bk/告警数量分布问题代码.vue
create mode 100644 src/bk/时间段告警数量分布.vue
create mode 100644 src/bk/点播页面原版.vue
create mode 100644 src/components/Channel.vue
create mode 100644 src/utils/eventBus.ts
diff --git a/package-lock.json b/package-lock.json
index 1fa7778..5300fa3 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -14,7 +14,12 @@
"dayjs": "^1.11.13",
"echarts": "^5.5.1",
"element-plus": "^2.7.8",
+ "file-saver": "^2.0.5",
"jsmpeg": "^1.0.0",
+ "json2csv": "^5.0.7",
+ "lodash": "^4.17.21",
+ "mitt": "^3.0.1",
+ "papaparse": "^5.4.1",
"vue": "^3.4.29",
"vue-router": "^4.4.0"
},
@@ -1189,6 +1194,14 @@
"node": ">= 0.8"
}
},
+ "node_modules/commander": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmmirror.com/commander/-/commander-6.2.1.tgz",
+ "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/computeds": {
"version": "0.0.1",
"resolved": "https://registry.npmmirror.com/computeds/-/computeds-0.0.1.tgz",
@@ -1351,6 +1364,11 @@
"resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz",
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
},
+ "node_modules/file-saver": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmmirror.com/file-saver/-/file-saver-2.0.5.tgz",
+ "integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA=="
+ },
"node_modules/follow-redirects": {
"version": "1.15.6",
"resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.6.tgz",
@@ -1465,6 +1483,32 @@
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
},
+ "node_modules/json2csv": {
+ "version": "5.0.7",
+ "resolved": "https://registry.npmmirror.com/json2csv/-/json2csv-5.0.7.tgz",
+ "integrity": "sha512-YRZbUnyaJZLZUJSRi2G/MqahCyRv9n/ds+4oIetjDF3jWQA7AG7iSeKTiZiCNqtMZM7HDyt0e/W6lEnoGEmMGA==",
+ "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.",
+ "dependencies": {
+ "commander": "^6.1.0",
+ "jsonparse": "^1.3.1",
+ "lodash.get": "^4.4.2"
+ },
+ "bin": {
+ "json2csv": "bin/json2csv.js"
+ },
+ "engines": {
+ "node": ">= 10",
+ "npm": ">= 6.13.0"
+ }
+ },
+ "node_modules/jsonparse": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmmirror.com/jsonparse/-/jsonparse-1.3.1.tgz",
+ "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==",
+ "engines": [
+ "node >= 0.2.0"
+ ]
+ },
"node_modules/less": {
"version": "4.2.0",
"resolved": "https://registry.npmmirror.com/less/-/less-4.2.0.tgz",
@@ -1537,6 +1581,11 @@
"lodash-es": "*"
}
},
+ "node_modules/lodash.get": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmmirror.com/lodash.get/-/lodash.get-4.4.2.tgz",
+ "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ=="
+ },
"node_modules/magic-string": {
"version": "0.30.11",
"resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.11.tgz",
@@ -1630,6 +1679,11 @@
"url": "https://github.com/sponsors/isaacs"
}
},
+ "node_modules/mitt": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmmirror.com/mitt/-/mitt-3.0.1.tgz",
+ "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw=="
+ },
"node_modules/muggle-string": {
"version": "0.4.1",
"resolved": "https://registry.npmmirror.com/muggle-string/-/muggle-string-0.4.1.tgz",
@@ -1709,6 +1763,11 @@
"npm": ">= 8"
}
},
+ "node_modules/papaparse": {
+ "version": "5.4.1",
+ "resolved": "https://registry.npmmirror.com/papaparse/-/papaparse-5.4.1.tgz",
+ "integrity": "sha512-HipMsgJkZu8br23pW15uvo6sib6wne/4woLZPlFf3rpDyMe9ywEXUsuD7+6K9PRkJlVT51j/sCOYDKGGS3ZJrw=="
+ },
"node_modules/parse-node-version": {
"version": "1.0.1",
"resolved": "https://registry.npmmirror.com/parse-node-version/-/parse-node-version-1.0.1.tgz",
diff --git a/package.json b/package.json
index 3d8e8db..284f717 100644
--- a/package.json
+++ b/package.json
@@ -17,7 +17,12 @@
"dayjs": "^1.11.13",
"echarts": "^5.5.1",
"element-plus": "^2.7.8",
+ "file-saver": "^2.0.5",
"jsmpeg": "^1.0.0",
+ "json2csv": "^5.0.7",
+ "lodash": "^4.17.21",
+ "mitt": "^3.0.1",
+ "papaparse": "^5.4.1",
"vue": "^3.4.29",
"vue-router": "^4.4.0"
},
diff --git a/src/App.vue b/src/App.vue
index bc7bc45..5166ceb 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -1,26 +1,102 @@
-
+
+
+
+ 告警编号:{{ globalDialogContent.id }}
+ 摄像头名称:{{ globalDialogContent.camera?.name }}
+ 告警类型:{{ algorithmMap.get(globalDialogContent.types) || '未知类型' }}
+
+
+
+
\ No newline at end of file
+
diff --git a/src/bk/DataStatics新数据统计.vue b/src/bk/DataStatics新数据统计.vue
new file mode 100644
index 0000000..e69de29
diff --git a/src/bk/DataStatistics原始版.vue b/src/bk/DataStatistics原始版.vue
new file mode 100644
index 0000000..98d6208
--- /dev/null
+++ b/src/bk/DataStatistics原始版.vue
@@ -0,0 +1,127 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/bk/告警数量分布问题代码.vue b/src/bk/告警数量分布问题代码.vue
new file mode 100644
index 0000000..c5f3665
--- /dev/null
+++ b/src/bk/告警数量分布问题代码.vue
@@ -0,0 +1,410 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/bk/时间段告警数量分布.vue b/src/bk/时间段告警数量分布.vue
new file mode 100644
index 0000000..7597a84
--- /dev/null
+++ b/src/bk/时间段告警数量分布.vue
@@ -0,0 +1,514 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/bk/点播页面原版.vue b/src/bk/点播页面原版.vue
new file mode 100644
index 0000000..6365a5b
--- /dev/null
+++ b/src/bk/点播页面原版.vue
@@ -0,0 +1,411 @@
+
+
+
+
+
+
+
+
+
![camera-preview]()
+
{{ camera.name }}
+
+
+
+
+
+
+
+
+
+
{{ camera.name }}
+
X
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/components/AlertChart.vue b/src/components/AlertChart.vue
index 1335681..58f215e 100644
--- a/src/components/AlertChart.vue
+++ b/src/components/AlertChart.vue
@@ -1,513 +1,263 @@
-
-
+
+
+
-
+
-
-
+
+
-
+ -->
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/Channel.vue b/src/components/Channel.vue
new file mode 100644
index 0000000..4efba4e
--- /dev/null
+++ b/src/components/Channel.vue
@@ -0,0 +1,350 @@
+
+
+
+
+
+
+
+
+
{{ camera.name }}
+
×
+
+
+
+
+
+
+
+
+ 播放摄像头: {{ currentCamera?.name }}
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/components/Max/CenterBottom.vue b/src/components/Max/CenterBottom.vue
index 1a51348..966afb3 100644
--- a/src/components/Max/CenterBottom.vue
+++ b/src/components/Max/CenterBottom.vue
@@ -35,6 +35,7 @@
import dayjs from 'dayjs';
import { debounce } from 'lodash';
+
const activeName = ref('first');
const hourlyCounts = ref(Array(24).fill(0));
const dailyCounts = ref(Array(7).fill(0));
@@ -44,38 +45,128 @@
const weekLineChartDom = ref(null);
const monthLineChartDom = ref(null);
- const chartInstanceToday = ref(null);
- const chartInstanceWeek = ref(null);
- const chartInstanceMonth = ref(null);
+ const chartInstance = ref(null);
const weekDates = ref([]);
const monthDates = ref([]);
- let isTodayChartInitialized = false;
- let isWeekChartInitialized = false;
- let isMonthChartInitialized = false;
-
const apiInstance = new BoxApi();
- const allEvents = ref([]);
- // 日期格式化函数
- const formatDateTime = (date) => dayjs(date).format('YYYY-MM-DD HH:mm:ss');
-
- // 获取时间参数
- const getDayParams = () => {
- const today = dayjs();
- return { timeAfter: today.startOf('day').format(), timeBefore: today.endOf('day').format() };
- };
- const getWeeklyParams = () => {
- const today = dayjs();
- return { timeAfter: today.subtract(7, 'day').format(), timeBefore: today.endOf('day').format() };
- };
- const getMonthlyParams = () => {
- const today = dayjs();
- return { timeAfter: today.subtract(30, 'day').format(), timeBefore: today.endOf('day').format() };
+ // 设置时间范围获取计数
+ 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 `时间:${date}
告警数量: ${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();
};
@@ -83,8 +174,8 @@
monthDates.value = Array.from({ length: 30 }, (_, i) => dayjs().subtract(i, 'day').format('YYYY-MM-DD')).reverse();
};
- // 延迟初始化图表函数
- const delayedInitChart = debounce((chartInstance, domRef, option) => {
+ // 图表延迟初始化
+ const delayedInitChart = debounce((domRef, option) => {
nextTick(() => {
if (domRef.value) {
chartInstance.value = echarts.init(domRef.value);
@@ -93,253 +184,14 @@
});
}, 300);
- // 初始化图表选项配置
- const createTodayChartOption = () => ({
- tooltip: {
- trigger: 'item',
- axisPointer: { type: 'line' },
- formatter: (params) => {
- console.log('Tooltip params:', params);
- const date = params.name;
- const value = params.value;
- return `时间:${date}
告警数量: ${value}`; // 使用 标签作为小标题
- },
- backgroundColor: 'rgba(50, 50, 50, 0.3)',
- borderWidth: 1,
- textStyle: {
- color: '#fff',
- fontStyle: 'italic', // 字体样式,可以是 'normal', 'italic', 'oblique'
- fontWeight: 'bold',
- fontFamily: 'Arial, sans-serif', // 字体
- fontSize: 12
- },
- padding: 10
- },
- grid: {
- top: '10%',
- left: '5%',
- right: '5%',
- bottom: '20%',
- },
- xAxis: {
- type: 'category',
- data: Array.from({ length: 24 }, (_, i) => `${i}:00`),
- 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: hourlyCounts.value,
- smooth: true,
- areaStyle: { color: 'rgba(74, 172, 178, 0.3)' },
- lineStyle: { color: 'rgb(60,178,239)', width: 2 },
- },
- ],
- });
-
- const createWeekChartOption = () => ({
- tooltip: {
- trigger: 'item',
- axisPointer: { type: 'line' },
- formatter: (params) => {
- console.log('Tooltip params:', params);
- const date = params.name;
- const value = params.value;
- return `时间:${date}
告警数量: ${value}`; // 使用 标签作为小标题
- },
- backgroundColor: 'rgba(50, 50, 50, 0.3)',
- borderWidth: 1,
- textStyle: {
- color: '#fff',
- fontStyle: 'italic', // 字体样式,可以是 'normal', 'italic', 'oblique'
- fontWeight: 'bold',
- fontFamily: 'Arial, sans-serif', // 字体
- fontSize: 12
- },
- padding: 10
- },
- grid: {
- top: '10%',
- left: '5%',
- right: '5%',
- bottom: '20%',
- },
- xAxis: {
- type: 'category',
- data: weekDates.value,
- 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: dailyCounts.value,
- smooth: true,
- areaStyle: { color: 'rgba(74, 172, 178, 0.3)' },
- lineStyle: { color: 'rgb(60,178,239)', width: 2 },
- },
- ],
- });
-
- const createMonthChartOption = () => ({
- tooltip: {
- trigger: 'item',
- axisPointer: { type: 'line' },
- formatter: (params) => {
- console.log('Tooltip params:', params);
- const date = params.name;
- const value = params.value;
- return `时间:${date}
告警数量: ${value}`; // 使用 标签作为小标题
- },
- backgroundColor: 'rgba(50, 50, 50, 0.3)',
- borderWidth: 1,
- textStyle: {
- color: '#fff',
- fontStyle: 'italic', // 字体样式,可以是 'normal', 'italic', 'oblique'
- fontWeight: 'bold',
- fontFamily: 'Arial, sans-serif', // 字体
- fontSize: 12
- },
- padding: 10
- },
- grid: {
- top: '10%',
- left: '5%',
- right: '5%',
- bottom: '20%',
- },
- xAxis: {
- type: 'category',
- data: monthDates.value,
- 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: monthlyCounts.value,
- smooth: true,
- areaStyle: { color: 'rgba(74, 172, 178, 0.3)' },
- lineStyle: { color: 'rgb(60,178,239)', width: 2 },
- },
- ],
- });
-
- // 获取和处理事件数据
- const fetchAndProcessEvents = async (timeParams) => {
- try {
- let currentPage = 1;
- const pageSize = 1000;
- const token = localStorage.getItem('alertToken');
- allEvents.value = [];
-
- const firstResponse = await apiInstance.getEventsByParams(token, pageSize, currentPage, timeParams.timeBefore, timeParams.timeAfter);
- const totalItems = firstResponse.count;
- allEvents.value.push(...firstResponse.results);
-
- const totalPages = Math.ceil(totalItems / pageSize);
- while (currentPage < totalPages) {
- currentPage++;
- const response = await apiInstance.getEventsByParams(token, pageSize, currentPage, timeParams.timeBefore, timeParams.timeAfter);
- allEvents.value.push(...response.results);
- }
-
- processEventData(allEvents.value);
- } catch (error) {
- console.error("Error fetching events:", error);
- }
- };
-
- // 处理事件数据
- const processEventData = (events) => {
- hourlyCounts.value.fill(0);
- dailyCounts.value.fill(0);
- monthlyCounts.value.fill(0);
- events.forEach((event) => {
- const hour = dayjs(event.ended_at).hour();
- const dayDiff = dayjs().diff(dayjs(event.ended_at), 'day');
- if (dayDiff < 1) hourlyCounts.value[hour] += 1;
- if (dayDiff < 7) dailyCounts.value[6 - dayDiff] += 1;
- if (dayDiff < 30) monthlyCounts.value[29 - dayDiff] += 1;
- });
- updateCharts();
- };
-
- // 更新图表
- const updateCharts = () => {
- if (chartInstanceToday.value) chartInstanceToday.value.setOption({ series: [{ data: hourlyCounts.value }] });
- if (chartInstanceWeek.value) chartInstanceWeek.value.setOption({ series: [{ data: dailyCounts.value }] });
- if (chartInstanceMonth.value) chartInstanceMonth.value.setOption({ series: [{ data: monthlyCounts.value }] });
- };
-
- // 处理选项卡切换
- const handleClick = async (tab) => {
- let timeParams;
- if (tab.props.name === 'first' && !isTodayChartInitialized) {
- timeParams = getDayParams();
- await fetchAndProcessEvents(timeParams);
- delayedInitChart(chartInstanceToday, todayLineChartDom, createTodayChartOption());
- isTodayChartInitialized = true;
- } else if (tab.props.name === 'second' && !isWeekChartInitialized) {
- timeParams = getWeeklyParams();
- await fetchAndProcessEvents(timeParams);
- delayedInitChart(chartInstanceWeek, weekLineChartDom, createWeekChartOption());
- isWeekChartInitialized = true;
- } else if (tab.props.name === 'third' && !isMonthChartInitialized) {
- timeParams = getMonthlyParams();
- await fetchAndProcessEvents(timeParams);
- delayedInitChart(chartInstanceMonth, monthLineChartDom, createMonthChartOption());
- isMonthChartInitialized = true;
- }
- };
-
- // 窗口调整时重新渲染图表
- const resizeCharts = debounce(() => {
- if (chartInstanceToday.value) chartInstanceToday.value.resize();
- if (chartInstanceWeek.value) chartInstanceWeek.value.resize();
- if (chartInstanceMonth.value) chartInstanceMonth.value.resize();
- }, 300);
-
// 组件挂载时调用
onMounted(async () => {
calculateWeekDates();
calculateMonthDates();
await handleClick({ props: { name: 'first' } });
- window.addEventListener('resize', resizeCharts);
+ window.addEventListener('resize', debounce(() => {
+ if (chartInstance.value) chartInstance.value.resize();
+ }, 300));
});
diff --git a/src/components/Max/LeftBottom.vue b/src/components/Max/LeftBottom.vue
index b16e44d..d9194c5 100644
--- a/src/components/Max/LeftBottom.vue
+++ b/src/components/Max/LeftBottom.vue
@@ -146,6 +146,11 @@ const originalWidths = [97, 150, 160]; // 默认宽度
const adjustedWidths = ref([...originalWidths]);
const baseWidth = 2150;
+const formatDateTimeToISO = (datetime) => {
+ return new Date(datetime).toISOString().replace('.000', '');
+};
+
+
const adjustColumnWidths = () => {
const currentWidth = window.innerWidth;
// console.log(">>>>>>>>>>", currentWidth);
@@ -192,8 +197,8 @@ const fetchEvents = async () => {
const { endOfToday, startOfToday } = getDateParams();
- const timeBefore = formatDateTime(endOfToday);
- const timeAfter = formatDateTime(startOfToday);
+ const timeBefore = formatDateTimeToISO(endOfToday);
+ const timeAfter = formatDateTimeToISO(startOfToday);
// console.log("Start of today:", timeAfter);
// const firstResponse = await apiInstance.getEventsByParams(token, limit, currentPage);
const firstResponse = await apiInstance.getEventsByParams(token, limit, currentPage,timeBefore, timeAfter);
diff --git a/src/components/Max/LeftTop.vue b/src/components/Max/LeftTop.vue
index 987c932..960a2f6 100644
--- a/src/components/Max/LeftTop.vue
+++ b/src/components/Max/LeftTop.vue
@@ -141,7 +141,7 @@
- {{ pendintingEventCount }}
+ {{ pendingEventCount }}
@@ -169,7 +169,7 @@
const cameraOfflineCount = ref(0);
const cameraOnlineCount = ref(0);
const eventCount = ref(0);
- const pendintingEventCount = ref(0);
+ const pendingEventCount = ref(0);
const closedEventCount = ref(0);
const activeTab = ref('all');
@@ -227,7 +227,7 @@
const firstResponse = await apiInstance.getCameras(limit, offset, token);
cameraCount.value = firstResponse.count;
- console.log("总数》》》》》》》》》》》》》", cameraCount.value)
+ // console.log("总数》》》》》》》》》》》》》", cameraCount.value)
allCameras = firstResponse.results;
@@ -261,7 +261,7 @@
// eventCount.value = totalResponse.count;
// const pendingResponse = await apiInstance.getEventsByParams(token, 1, 1, timeBefore, timeAfter, null, null, 'pending');
- // pendintingEventCount.value = pendingResponse.count;
+ // pendingEventCount.value = pendingResponse.count;
// const closedResponse = await apiInstance.getEventsByParams(token, 1, 1, timeBefore, timeAfter, null, null, 'closed');
// closedEventCount.value = closedResponse.count;
@@ -292,7 +292,7 @@
// 获取状态为 pending 的告警数量
const pendingResponse = await apiInstance.getEventsByParams(token, 1, 1, timeRange.timeBefore, timeRange.timeAfter, null, null, 'pending');
- pendintingEventCount.value = pendingResponse.count;
+ pendingEventCount.value = pendingResponse.count;
// 获取状态为 closed 的告警数量
const closedResponse = await apiInstance.getEventsByParams(token, 1, 1, timeRange.timeBefore, timeRange.timeAfter, null, null, 'closed');
diff --git a/src/components/Max/RightTop.vue b/src/components/Max/RightTop.vue
index 9416630..5e2ff9c 100644
--- a/src/components/Max/RightTop.vue
+++ b/src/components/Max/RightTop.vue
@@ -38,6 +38,10 @@ import * as echarts from 'echarts';
const apiInstance = new BoxApi();
const typeMapping = reactive({});
const typeCounts = reactive({}); // 存储每种类型的数量
+const formatDateTimeToISO = (datetime) => {
+ return new Date(datetime).toISOString().replace('.000', '');
+};
+
const filterParams = reactive({
timeAfter: null,
@@ -195,8 +199,8 @@ const fetchTypeCounts = async (timeAfter = null, timeBefore = null) => {
// 点击查询按钮时,添加时间条件并重新统计
const handleFilter = () => {
- const timeAfter = filterParams.timeAfter ? formatDateTime(new Date(filterParams.timeAfter)) : null;
- const timeBefore = filterParams.timeBefore ? formatDateTime(new Date(filterParams.timeBefore)) : null;
+ const timeAfter = filterParams.timeAfter ? formatDateTimeToISO(new Date(filterParams.timeAfter)) : null;
+ const timeBefore = filterParams.timeBefore ? formatDateTimeToISO(new Date(filterParams.timeBefore)) : null;
fetchTypeCounts(timeAfter, timeBefore); // 重新统计数量,添加时间条件
};
diff --git a/src/components/Settings.vue b/src/components/Settings.vue
index 9669600..954990e 100644
--- a/src/components/Settings.vue
+++ b/src/components/Settings.vue
@@ -1,17 +1,23 @@
+
+
+
+
+
diff --git a/src/html/Home.vue b/src/html/Home.vue
index 9e535bb..fb15516 100644
--- a/src/html/Home.vue
+++ b/src/html/Home.vue
@@ -1,411 +1,345 @@
-
-
-
-
-
-
-
-
![camera-preview]()
-
{{ camera.name }}
-
-
-
+