diff --git a/README.md b/README.md index ce17611..29e39b2 100644 --- a/README.md +++ b/README.md @@ -267,3 +267,6 @@ export default router; ![image-20241031164625119](https://gitee.com/gonghao_git/draw-bed/raw/master/img/%E5%A4%A7%E5%B1%8F%E9%A1%B5%E9%9D%A2%E5%88%9D%E7%A8%BF-20241031164625119.png) + + + diff --git a/SScode.md b/SScode.md new file mode 100644 index 0000000..0508ab9 --- /dev/null +++ b/SScode.md @@ -0,0 +1,220 @@ +## 分批请求函数 + +- 入参方式 + - 1. (页码 + 页面大小) + - 2. (偏移量 + 页面大小) + +### 1》页码 + 页面大小 + +``` +const fetchCameras = async () => { + try { + const token = localStorage.getItem('alertToken'); + const limit = 20; // 每次请求 20 条数据 + let offset = 0; // 从 0 开始 + let allCameras = []; + + // 第一次请求,用于获取总数 + const firstResponse = await apiInstance.getCameras(limit, offset, token); + cameraCount.value = firstResponse.count; + 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); + } + cameras.value = allCameras; + } catch (error) { + console.error('Error fetching cameras:', error); + } +}; +``` + + + +### 2》 偏移量 + 页面大小 + +- .length + +``` +const fetchEvents = async () => { + try { + const token = localStorage.getItem('alertToken'); + const limit = 2; + let currentPage = 1; + let allEvents = []; + let total = 0; + + // 先请求一次以获取总条数 + const firstResponse = await apiInstance.getEvents(token, limit, currentPage); + total = firstResponse.totalItems; // 总条数 + allEvents = firstResponse.tableData; // 第一次请求的数据 + + // 使用 while 循环来请求后续的数据 + while (allEvents.length < total) { + currentPage += 1; + const offset = (currentPage - 1) * limit; + const response = await apiInstance.getEvents(token, limit, currentPage); + + allEvents = allEvents.concat(response.tableData); // 追加数据 + } + + tableData.value = allEvents; // 将所有数据赋值给 tableData + } catch (error) { + console.error("Error fetching events data:", error); + } +}; +``` + + + +- offset + limit计算(初稿备份) + +``` +const fetchEvents = async () => { + try { + const token = localStorage.getItem('alertToken'); + const limit = 2000; + let currentPage = 1; + let allEvents = []; + let total = 0; + let offset = (currentPage - 1) * limit; + + // 先请求一次以获取总条数 + const firstResponse = await apiInstance.getEvents(token, limit, currentPage); + total = firstResponse.totalItems; // 总条数 + allEvents = firstResponse.tableData; // 第一次请求的数据 + + // 使用 while 循环来请求后续的数据 + while (offset+limit < total) { + currentPage += 1; + offset = (currentPage - 1) * limit; + const response = await apiInstance.getEvents(token, limit, currentPage); + + allEvents = allEvents.concat(response.tableData); // 追加数据 + } + + tableData.value = allEvents; // 将所有数据赋值给 tableData + } catch (error) { + console.error("Error fetching events data:", error); + } +}; +``` + + + +## 数组并行处理和排序 + +- 更改前(分两个数组直接存) + +``` +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); + const cameraCount = firstResponse.count; + allCameras = firstResponse.results; + + while (offset + limit < cameraCount) { + offset += limit; + const response = await apiInstance.getCameras(limit, offset, token); + allCameras = allCameras.concat(response.results); + } + + // 提取摄像头名称和对应的告警数量 + const cameraNames = []; + const cameraCounts = []; + + for (const camera of allCameras) { + cameraNames.push(camera.name); + + // 获取该摄像头的告警数量 + const eventsResponse = await apiInstance.getEventsByParams(token, 20, 1, null, null, null, camera.id); + const count = eventsResponse.count || 0; // 确保即使没有事件也返回 0 + cameraCounts.push(count); + } + + // 更新图表的 Y 轴标签和系列数据 + option.value.yAxis[0].data = cameraNames; + option.value.yAxis[1].data = cameraCounts.map(count => `${count}`); + option.value.series[0].data = cameraCounts; + option.value.series[1].data = cameraCounts; + + // 设置图表选项并启动轮播 + myChart.setOption(option.value); + startMoveDataZoom(); // 重新启动轮播效果 + } catch (error) { + console.error("Error fetching cameras or events:", error); + } +}; + +``` + + + +- 更改后 + +``` +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); + const cameraCount = firstResponse.count; + allCameras = firstResponse.results; + + while (offset + limit < cameraCount) { + offset += limit; + const response = await apiInstance.getCameras(limit, offset, token); + allCameras = allCameras.concat(response.results); + } + + // 提取摄像头名称和对应的告警数量并存储在对象数组中 + const cameraData = []; + + for (const camera of allCameras) { + // 获取该摄像头的告警数量 + const eventsResponse = await apiInstance.getEventsByParams(token, 20, 1, null, null, null, camera.id); + const count = eventsResponse.count || 0; // 确保即使没有事件也返回 0 + cameraData.push({ name: camera.name, count }); // 将数据存储为对象以便排序 + } + + // 按照告警数量降序排序 + cameraData.sort((a, b) => b.count - a.count); + + // 提取排序后的名称和数量 + const cameraNames = cameraData.map(item => item.name); + const cameraCounts = cameraData.map(item => item.count); + + // 更新图表的 Y 轴标签和系列数据 + option.value.yAxis[0].data = cameraNames; + option.value.yAxis[1].data = cameraCounts.map(count => `${count}`); + option.value.series[0].data = cameraCounts; + option.value.series[1].data = cameraCounts; + + // 设置图表选项并启动轮播 + myChart.setOption(option.value); + startMoveDataZoom(); // 重新启动轮播效果 + } catch (error) { + console.error("Error fetching cameras or events:", error); + } +}; + +``` + + + diff --git a/package-lock.json b/package-lock.json index d90a87c..1fa7778 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,6 +23,8 @@ "@types/node": "^20.14.5", "@vitejs/plugin-vue": "^5.0.5", "@vue/tsconfig": "^0.5.1", + "less": "^4.2.0", + "less-loader": "^12.2.0", "npm-run-all2": "^6.2.0", "typescript": "~5.4.0", "vite": "^5.3.1", @@ -1193,6 +1195,18 @@ "integrity": "sha512-7CEBgcMjVmitjYo5q8JTJVra6X5mQ20uTThdK+0kR7UEaDrAWEQcRiBtWJzga4eRpP6afNwwLsX2SET2JhVB1Q==", "dev": true }, + "node_modules/copy-anything": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/copy-anything/-/copy-anything-2.0.6.tgz", + "integrity": "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==", + "dev": true, + "dependencies": { + "is-what": "^3.14.1" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -1276,6 +1290,19 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/errno": { + "version": "0.1.8", + "resolved": "https://registry.npmmirror.com/errno/-/errno-0.1.8.tgz", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "dev": true, + "optional": true, + "dependencies": { + "prr": "~1.0.1" + }, + "bin": { + "errno": "cli.js" + } + }, "node_modules/esbuild": { "version": "0.21.5", "resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.21.5.tgz", @@ -1370,6 +1397,13 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "optional": true + }, "node_modules/he": { "version": "1.2.0", "resolved": "https://registry.npmmirror.com/he/-/he-1.2.0.tgz", @@ -1379,6 +1413,38 @@ "he": "bin/he" } }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/image-size": { + "version": "0.5.5", + "resolved": "https://registry.npmmirror.com/image-size/-/image-size-0.5.5.tgz", + "integrity": "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==", + "dev": true, + "optional": true, + "bin": { + "image-size": "bin/image-size.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-what": { + "version": "3.14.1", + "resolved": "https://registry.npmmirror.com/is-what/-/is-what-3.14.1.tgz", + "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==", + "dev": true + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmmirror.com/isexe/-/isexe-2.0.0.tgz", @@ -1399,6 +1465,58 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "node_modules/less": { + "version": "4.2.0", + "resolved": "https://registry.npmmirror.com/less/-/less-4.2.0.tgz", + "integrity": "sha512-P3b3HJDBtSzsXUl0im2L7gTO5Ubg8mEN6G8qoTS77iXxXX4Hvu4Qj540PZDvQ8V6DmX6iXo98k7Md0Cm1PrLaA==", + "dev": true, + "dependencies": { + "copy-anything": "^2.0.1", + "parse-node-version": "^1.0.1", + "tslib": "^2.3.0" + }, + "bin": { + "lessc": "bin/lessc" + }, + "engines": { + "node": ">=6" + }, + "optionalDependencies": { + "errno": "^0.1.1", + "graceful-fs": "^4.1.2", + "image-size": "~0.5.0", + "make-dir": "^2.1.0", + "mime": "^1.4.1", + "needle": "^3.1.0", + "source-map": "~0.6.0" + } + }, + "node_modules/less-loader": { + "version": "12.2.0", + "resolved": "https://registry.npmmirror.com/less-loader/-/less-loader-12.2.0.tgz", + "integrity": "sha512-MYUxjSQSBUQmowc0l5nPieOYwMzGPUaTzB6inNW/bdPEG9zOL3eAAD1Qw5ZxSPk7we5dMojHwNODYMV1hq4EVg==", + "dev": true, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "less": "^3.5.0 || ^4.0.0", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz", @@ -1427,6 +1545,30 @@ "@jridgewell/sourcemap-codec": "^1.5.0" } }, + "node_modules/make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "optional": true, + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmmirror.com/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "optional": true, + "bin": { + "semver": "bin/semver" + } + }, "node_modules/memoize-one": { "version": "6.0.0", "resolved": "https://registry.npmmirror.com/memoize-one/-/memoize-one-6.0.0.tgz", @@ -1441,6 +1583,19 @@ "node": ">= 0.10.0" } }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmmirror.com/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "optional": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz", @@ -1498,6 +1653,23 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/needle": { + "version": "3.3.1", + "resolved": "https://registry.npmmirror.com/needle/-/needle-3.3.1.tgz", + "integrity": "sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==", + "dev": true, + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.3", + "sax": "^1.2.4" + }, + "bin": { + "needle": "bin/needle" + }, + "engines": { + "node": ">= 4.4.x" + } + }, "node_modules/normalize-wheel-es": { "version": "1.2.0", "resolved": "https://registry.npmmirror.com/normalize-wheel-es/-/normalize-wheel-es-1.2.0.tgz", @@ -1537,6 +1709,15 @@ "npm": ">= 8" } }, + "node_modules/parse-node-version": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/parse-node-version/-/parse-node-version-1.0.1.tgz", + "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/path-browserify": { "version": "1.0.1", "resolved": "https://registry.npmmirror.com/path-browserify/-/path-browserify-1.0.1.tgz", @@ -1569,6 +1750,16 @@ "node": ">=0.10" } }, + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmmirror.com/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "optional": true, + "engines": { + "node": ">=6" + } + }, "node_modules/postcss": { "version": "8.4.41", "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.4.41.tgz", @@ -1601,6 +1792,13 @@ "resolved": "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" }, + "node_modules/prr": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/prr/-/prr-1.0.1.tgz", + "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", + "dev": true, + "optional": true + }, "node_modules/read-package-json-fast": { "version": "3.0.2", "resolved": "https://registry.npmmirror.com/read-package-json-fast/-/read-package-json-fast-3.0.2.tgz", @@ -1654,6 +1852,20 @@ "fsevents": "~2.3.2" } }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "optional": true + }, + "node_modules/sax": { + "version": "1.4.1", + "resolved": "https://registry.npmmirror.com/sax/-/sax-1.4.1.tgz", + "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", + "dev": true, + "optional": true + }, "node_modules/semver": { "version": "7.6.3", "resolved": "https://registry.npmmirror.com/semver/-/semver-7.6.3.tgz", @@ -1696,6 +1908,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map-js": { "version": "1.2.0", "resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.0.tgz", diff --git a/package.json b/package.json index a8e6a43..3d8e8db 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,8 @@ "@types/node": "^20.14.5", "@vitejs/plugin-vue": "^5.0.5", "@vue/tsconfig": "^0.5.1", + "less": "^4.2.0", + "less-loader": "^12.2.0", "npm-run-all2": "^6.2.0", "typescript": "~5.4.0", "vite": "^5.3.1", diff --git a/src/bk/CenterBottom告警分布.vue b/src/bk/CenterBottom告警分布.vue new file mode 100644 index 0000000..74aa09c --- /dev/null +++ b/src/bk/CenterBottom告警分布.vue @@ -0,0 +1,408 @@ + + + + + + + + \ No newline at end of file diff --git a/src/bk/CenterTop警戒点位.vue b/src/bk/CenterTop警戒点位.vue new file mode 100644 index 0000000..443637b --- /dev/null +++ b/src/bk/CenterTop警戒点位.vue @@ -0,0 +1,347 @@ + + + + + + \ No newline at end of file diff --git a/src/bk/LeftMiddle点位告警数量.vue b/src/bk/LeftMiddle点位告警数量.vue new file mode 100644 index 0000000..36fffa7 --- /dev/null +++ b/src/bk/LeftMiddle点位告警数量.vue @@ -0,0 +1,310 @@ + + + + + \ No newline at end of file diff --git a/src/bk/LeftTop告警数据统计.vue b/src/bk/LeftTop告警数据统计.vue new file mode 100644 index 0000000..d7f6969 --- /dev/null +++ b/src/bk/LeftTop告警数据统计.vue @@ -0,0 +1,366 @@ + + + + + + + \ No newline at end of file diff --git a/src/bk/RightTop类型分布.vue b/src/bk/RightTop类型分布.vue new file mode 100644 index 0000000..8d5a072 --- /dev/null +++ b/src/bk/RightTop类型分布.vue @@ -0,0 +1,308 @@ + + + + + diff --git a/src/bk/告警列表(letf-bottom).vue b/src/bk/告警列表(letf-bottom).vue new file mode 100644 index 0000000..00c7d69 --- /dev/null +++ b/src/bk/告警列表(letf-bottom).vue @@ -0,0 +1,424 @@ + + + + + + + \ No newline at end of file diff --git a/src/bk/时间段内告警类型数量.vue b/src/bk/时间段内告警类型数量.vue new file mode 100644 index 0000000..019b76b --- /dev/null +++ b/src/bk/时间段内告警类型数量.vue @@ -0,0 +1,111 @@ + + + + + + \ No newline at end of file diff --git a/src/components/Layout.vue b/src/components/Layout.vue index a15c71f..0021c48 100644 --- a/src/components/Layout.vue +++ b/src/components/Layout.vue @@ -42,7 +42,7 @@ - + --> + diff --git a/src/components/Max/CenterBottom.vue b/src/components/Max/CenterBottom.vue new file mode 100644 index 0000000..1a51348 --- /dev/null +++ b/src/components/Max/CenterBottom.vue @@ -0,0 +1,408 @@ + + + + + + + + \ No newline at end of file diff --git a/src/components/Max/CenterTop.vue b/src/components/Max/CenterTop.vue new file mode 100644 index 0000000..55491c7 --- /dev/null +++ b/src/components/Max/CenterTop.vue @@ -0,0 +1,347 @@ + + + + + + \ No newline at end of file diff --git a/src/components/Max/LeftBottom.vue b/src/components/Max/LeftBottom.vue new file mode 100644 index 0000000..b16e44d --- /dev/null +++ b/src/components/Max/LeftBottom.vue @@ -0,0 +1,431 @@ + + + + + + + \ No newline at end of file diff --git a/src/components/Max/LeftMiddle.vue b/src/components/Max/LeftMiddle.vue new file mode 100644 index 0000000..65d8a48 --- /dev/null +++ b/src/components/Max/LeftMiddle.vue @@ -0,0 +1,310 @@ + + + + + \ No newline at end of file diff --git a/src/components/Max/LeftTop.vue b/src/components/Max/LeftTop.vue index 013dbc9..987c932 100644 --- a/src/components/Max/LeftTop.vue +++ b/src/components/Max/LeftTop.vue @@ -1,55 +1,377 @@ - - + + + .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; + } + + \ No newline at end of file diff --git a/src/components/Max/RightTop.vue b/src/components/Max/RightTop.vue new file mode 100644 index 0000000..9416630 --- /dev/null +++ b/src/components/Max/RightTop.vue @@ -0,0 +1,308 @@ + + + + + diff --git a/src/html/Home.vue b/src/html/Home.vue index 74c8997..9e535bb 100644 --- a/src/html/Home.vue +++ b/src/html/Home.vue @@ -215,6 +215,7 @@ onBeforeUnmount(() => { box-sizing: border-box; border-right: 1px solid #1E2E4A; padding-right: 10px; + padding-bottom: 10vh; } .search-input { diff --git a/src/html/Test.vue b/src/html/Test.vue index 5cb0902..b224b4c 100644 --- a/src/html/Test.vue +++ b/src/html/Test.vue @@ -1,355 +1,365 @@ - - - - - \ No newline at end of file +}; + +watch(activeTab, (newTab) => { + fetchEvents(); +}); + + + +onMounted(() => { + // getTodayData(); + // getWeekData(); + // getMonthData(); + fetchCameras(); + fetchEvents(); + + +}); + + + + + diff --git a/src/html/ViewList.vue b/src/html/ViewList.vue index 088c2ba..9a5735e 100644 --- a/src/html/ViewList.vue +++ b/src/html/ViewList.vue @@ -19,8 +19,8 @@
-
-  本地告警大屏  +
+  告警数据面板 
@@ -57,32 +57,43 @@ - 点位告警数量(不同点位的数量) - 今日告警列表(告警详情) + 不同点位告警的数量 + + +
- 警戒画面 + +
- 警戒点位列表 + 告警数量分布情况 + +
- 告警类型概览 - 告警数量分布 - 告警种类划分 + 时间段告警总数分布 + + + + 告警种类划分 + +
@@ -95,6 +106,11 @@ import { ref, onMounted, onBeforeUnmount, nextTick, computed } from 'vue'; import { BoxApi } from '@/utils/boxApi.ts'; import { VideoPlay, VideoPause, VideoCameraFilled } from '@element-plus/icons-vue'; import LeftTop from '@/components/Max/LeftTop.vue'; +import LeftBottom from '@/components/Max/LeftBottom.vue'; +import LeftMiddle from '@/components/Max/LeftMiddle.vue'; +import RightTop from '@/components/Max/RightTop.vue'; +import CenterBottom from '@/components/Max/CenterBottom.vue'; +import CenterTop from '@/components/Max/CenterTop.vue'; // import '/src/assets/viewListStyle.css' @@ -106,38 +122,41 @@ import LeftTop from '@/components/Max/LeftTop.vue'; margin: 0; height: 100vh; width: 100vw; - padding: 4vh 10vw 10vh 1vw; + padding: 4vh 10vw 10vh 7vw; /* background-color: rgb(121, 184, 243); */ + background-color: #001529; /* background-image: url('/bg05.png'); */ background-size: cover; background-position: center; background-repeat: no-repeat; - background: radial-gradient(circle, rgb(24, 64, 197), rgb(0, 7, 60)); + /* background: radial-gradient(circle, rgb(24, 64, 197), rgb(0, 7, 60)); */ position: relative; color: black; box-sizing: border-box; } -/* .custom-decoration{ - color:white; -} */ +.custom-decoration{ + color: #70e5fa;; + font-weight: bold; + font-size: 25px; +} -.background-overlay { +/* .background-overlay { position: absolute; - /* 绝对定位 */ + top: 0; left: 0; right: 0; bottom: 0; - /* background-image: url('/bg01.png'); */ + background-image: url('/bg01.png'); background-size: cover; background-position: center; background-repeat: no-repeat; opacity: 0.8; z-index: 0; -} +} */ .container { display: flex; @@ -206,11 +225,11 @@ import LeftTop from '@/components/Max/LeftTop.vue'; } -.top-left, -.middle-left, + + .bottom-left, .top-right, -.middle-right, +/* .middle-right, */ .bottom-right { color: white; text-align: center; @@ -225,13 +244,39 @@ import LeftTop from '@/components/Max/LeftTop.vue'; position: relative; padding: 1vh 1vw; display: flex; - justify-content: center; /* 水平居中 */ - align-items: center; /* 垂直居中 */ + justify-content: center; + align-items: center; flex-grow: 1; width: 20vw; height: 20vh; } +.middle-left{ + color: white; + text-align: center; + width: 22vw; + height: 46vh; + display: flex; +} + +.top-right{ + width: 22vw; + height: 46vh; + display: flex; + /* padding: 1.5vh; */ +} + +.bottom-left{ + /* color: white; */ + /* position: relative; */ + padding-left: 0.5vw; + display: flex; + /* justify-content: center; */ + /* align-items: center; */ + /* width: 20vw; */ + /* height: 20vh; */ +} + /* .top-left, .top-right { margin-bottom: 1vh; } @@ -257,17 +302,14 @@ import LeftTop from '@/components/Max/LeftTop.vue'; flex-direction: column; } -.center-top-header { +/* .center-top-header { height: 3vh; width: 35vw; text-align: center; line-height: 3vh; margin-bottom: 1vh; - /* background-color: rgba(0, 51, 102, 0.8); */ border-radius: 3px; - /* 圆角 */ box-shadow: 0 4px 10px rgba(0, 0, 0, 0.5); - /* 添加阴影 */ } .center-top-grids { @@ -275,16 +317,15 @@ import LeftTop from '@/components/Max/LeftTop.vue'; grid-template-columns: 17vw 17vw; gap: 2vh 1vw; } - .grid-item { width: 17vw; height: 20vh; - /* background-color: #777; */ + background-color: #777; color: white; display: flex; align-items: center; justify-content: center; -} +} */ .center-bottom { display: flex; diff --git a/src/icons/CameraAll.vue b/src/icons/CameraAll.vue new file mode 100644 index 0000000..0df5e15 --- /dev/null +++ b/src/icons/CameraAll.vue @@ -0,0 +1,28 @@ + + + diff --git a/src/icons/CameraOffline.vue b/src/icons/CameraOffline.vue new file mode 100644 index 0000000..21b8a84 --- /dev/null +++ b/src/icons/CameraOffline.vue @@ -0,0 +1,30 @@ + + + \ No newline at end of file diff --git a/src/icons/CameraOnline.vue b/src/icons/CameraOnline.vue new file mode 100644 index 0000000..480847c --- /dev/null +++ b/src/icons/CameraOnline.vue @@ -0,0 +1,30 @@ + + + \ No newline at end of file diff --git a/src/icons/EventAll.vue b/src/icons/EventAll.vue new file mode 100644 index 0000000..fef8021 --- /dev/null +++ b/src/icons/EventAll.vue @@ -0,0 +1,29 @@ + + \ No newline at end of file diff --git a/src/icons/EventClosed.vue b/src/icons/EventClosed.vue new file mode 100644 index 0000000..a6a85b5 --- /dev/null +++ b/src/icons/EventClosed.vue @@ -0,0 +1,29 @@ + + \ No newline at end of file diff --git a/src/icons/EventPending.vue b/src/icons/EventPending.vue new file mode 100644 index 0000000..f641c02 --- /dev/null +++ b/src/icons/EventPending.vue @@ -0,0 +1,29 @@ + + diff --git a/src/main.ts b/src/main.ts index 929e653..8e55a98 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,4 +1,4 @@ -import {createApp} from 'vue' +import { createApp,ref, onBeforeUnmount} from 'vue' import App from './App.vue' import router from './router'; import ElementPlus from 'element-plus'; @@ -13,11 +13,11 @@ import '@kjgl77/datav-vue3/dist/style.css'; const app = createApp(App) -const globalWebSocket = useGlobalWebSocket(); -app.provide('globalWebSocket',globalWebSocket); +const globalWebSocket = useGlobalWebSocket(); +app.provide('globalWebSocket', globalWebSocket); // app.provide('axios', axiosInstance); app.use(ElementPlus, { locale: zhCn }); -app.use (router); +app.use(router); app.use(DataVVue3); // 导航守卫,检查登录状态 @@ -41,4 +41,37 @@ router.beforeEach((to, from, next) => { } }); +// 定义转换函数 +app.config.globalProperties.xToh = (px: number): string => { + const vh = (px / window.innerHeight) * 100; + return `${vh}vh`; +}; + +app.config.globalProperties.xTow = (px: number): string => { + const vw = (px / window.innerWidth) * 100; + return `${vw}vw`; +}; + +app.config.globalProperties.vhToPx = (vh: number): number => { + return (vh / 100) * window.innerHeight; +}; + +app.config.globalProperties.vwToPx = (vw: number): number => { + return (vw / 100) * window.innerWidth; +}; + +// 响应式处理 +const updateDimensions = () => { + app.config.globalProperties.windowHeight = window.innerHeight; + app.config.globalProperties.windowWidth = window.innerWidth; +}; + +window.addEventListener('resize', updateDimensions); +updateDimensions(); // 初始化 + +// 清理事件监听器 +onBeforeUnmount(() => { + window.removeEventListener('resize', updateDimensions); +}); + app.mount('#app') diff --git a/src/utils/boxApi.ts b/src/utils/boxApi.ts index 153d282..fbc3eee 100644 --- a/src/utils/boxApi.ts +++ b/src/utils/boxApi.ts @@ -320,7 +320,8 @@ class BoxApi { timeBefore: string | null = null, timeAfter: string | null = null, types: string | null = null, - camera_id: number | null = null + camera_id: number | null = null, + status?: 'pending' | 'closed' | null ): Promise { // 计算 offset const offset = (currentPage - 1) * pageSize; @@ -340,6 +341,9 @@ class BoxApi { if(camera_id){ url += `&camera_id=${camera_id}`; } + if (status) { + url += `&status=${encodeURIComponent(status)}`; + } try { // 发送 GET 请求 diff --git a/src/utils/useGlobalWebSocket.ts b/src/utils/useGlobalWebSocket.ts index a481c27..636971b 100644 --- a/src/utils/useGlobalWebSocket.ts +++ b/src/utils/useGlobalWebSocket.ts @@ -9,7 +9,7 @@ const rememberedAddress = localStorage.getItem('rememberedAddress') || '127.0.0. // 连接 WebSocket const connectWebSocket = () => { - websocket.value = new WebSocket(`ws://${rememberedAddress}:8080/event/ws`); + websocket.value = new WebSocket(`ws://${rememberedAddress}:8080/ws/event`); websocket.value.onopen = () => { ElMessage.success('全局 WebSocket 连接成功'); isWebSocketConnected.value = true;