From 686b5facf8ddd6e24268a0dcc489895b0047862b Mon Sep 17 00:00:00 2001 From: 6666 <2855471171@qq.com> Date: Sun, 16 Mar 2025 00:52:48 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E4=BE=9D=E8=B5=96=E7=89=88?= =?UTF-8?q?=E6=9C=AC=EF=BC=8C=E6=B7=BB=E5=8A=A0=E9=9F=B3=E6=95=88=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=EF=BC=8C=E4=BC=98=E5=8C=96WebSocket=E8=BF=9E=E6=8E=A5?= =?UTF-8?q?=E5=8F=8A=E5=9B=BE=E8=A1=A8=E6=98=BE=E7=A4=BA=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 858 +++++++++--------- src/router/index.js | 4 +- src/utils/SoundEffect.js | 35 + src/views/AIPatrol/drone/index.vue | 264 +++++- src/views/AIPatrol/sensor/index.vue | 464 +++++++++- .../components/CenterPanel/VideoMonitor.vue | 299 ++++-- vite.config.js | 1 + 7 files changed, 1358 insertions(+), 567 deletions(-) create mode 100644 src/utils/SoundEffect.js diff --git a/package-lock.json b/package-lock.json index ae913fe..dc9f4ac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -63,8 +63,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.26.9", - "integrity": "sha512-aA63XwOkcl4xxQa3HjPMqOP6LiK0ZDv3mUPYEFXkpHbaFjtGggE1A61FjFzJnB+p7/oy2gA8E+rcBNl/zC1tMg==", + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.10.tgz", + "integrity": "sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -116,9 +117,394 @@ "vue": "^3.2.0" } }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.1.tgz", + "integrity": "sha512-kfYGy8IdzTGy+z0vFGvExZtxkFlA4zAxgKEahG9KE1ScBjpQnFsNOX8KTU5ojNru5ed5CVoJYXFtoxaq5nFbjQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.1.tgz", + "integrity": "sha512-dp+MshLYux6j/JjdqVLnMglQlFu+MuVeNrmT5nk6q07wNhCdSnB7QZj+7G8VMUGh1q+vj2Bq8kRsuyA00I/k+Q==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.1.tgz", + "integrity": "sha512-50tM0zCJW5kGqgG7fQ7IHvQOcAn9TKiVRuQ/lN0xR+T2lzEFvAi1ZcS8DiksFcEpf1t/GYOeOfCAgDHFpkiSmA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.1.tgz", + "integrity": "sha512-GCj6WfUtNldqUzYkN/ITtlhwQqGWu9S45vUXs7EIYf+7rCiiqH9bCloatO9VhxsL0Pji+PF4Lz2XXCES+Q8hDw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.1.tgz", + "integrity": "sha512-5hEZKPf+nQjYoSr/elb62U19/l1mZDdqidGfmFutVUjjUZrOazAtwK+Kr+3y0C/oeJfLlxo9fXb1w7L+P7E4FQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.1.tgz", + "integrity": "sha512-hxVnwL2Dqs3fM1IWq8Iezh0cX7ZGdVhbTfnOy5uURtao5OIVCEyj9xIzemDi7sRvKsuSdtCAhMKarxqtlyVyfA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.1.tgz", + "integrity": "sha512-1MrCZs0fZa2g8E+FUo2ipw6jw5qqQiH+tERoS5fAfKnRx6NXH31tXBKI3VpmLijLH6yriMZsxJtaXUyFt/8Y4A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.1.tgz", + "integrity": "sha512-0IZWLiTyz7nm0xuIs0q1Y3QWJC52R8aSXxe40VUxm6BB1RNmkODtW6LHvWRrGiICulcX7ZvyH6h5fqdLu4gkww==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.1.tgz", + "integrity": "sha512-NdKOhS4u7JhDKw9G3cY6sWqFcnLITn6SqivVArbzIaf3cemShqfLGHYMx8Xlm/lBit3/5d7kXvriTUGa5YViuQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.1.tgz", + "integrity": "sha512-jaN3dHi0/DDPelk0nLcXRm1q7DNJpjXy7yWaWvbfkPvI+7XNSc/lDOnCLN7gzsyzgu6qSAmgSvP9oXAhP973uQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.1.tgz", + "integrity": "sha512-OJykPaF4v8JidKNGz8c/q1lBO44sQNUQtq1KktJXdBLn1hPod5rE/Hko5ugKKZd+D2+o1a9MFGUEIUwO2YfgkQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.1.tgz", + "integrity": "sha512-nGfornQj4dzcq5Vp835oM/o21UMlXzn79KobKlcs3Wz9smwiifknLy4xDCLUU0BWp7b/houtdrgUz7nOGnfIYg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.1.tgz", + "integrity": "sha512-1osBbPEFYwIE5IVB/0g2X6i1qInZa1aIoj1TdL4AaAb55xIIgbg8Doq6a5BzYWgr+tEcDzYH67XVnTmUzL+nXg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.1.tgz", + "integrity": "sha512-/6VBJOwUf3TdTvJZ82qF3tbLuWsscd7/1w+D9LH0W/SqUgM5/JJD0lrJ1fVIfZsqB6RFmLCe0Xz3fmZc3WtyVg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.1.tgz", + "integrity": "sha512-nSut/Mx5gnilhcq2yIMLMe3Wl4FK5wx/o0QuuCLMtmJn+WeWYoEGDN1ipcN72g1WHsnIbxGXd4i/MF0gTcuAjQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.1.tgz", + "integrity": "sha512-cEECeLlJNfT8kZHqLarDBQso9a27o2Zd2AQ8USAEoGtejOrCYHNtKP8XQhMDJMtthdF4GBmjR2au3x1udADQQQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.1.tgz", + "integrity": "sha512-xbfUhu/gnvSEg+EGovRc+kjBAkrvtk38RlerAzQxvMzlB4fXpCFCeUAYzJvrnhFtdeyVCDANSjJvOvGYoeKzFA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.1.tgz", + "integrity": "sha512-O96poM2XGhLtpTh+s4+nP7YCCAfb4tJNRVZHfIE7dgmax+yMP2WgMd2OecBuaATHKTHsLWHQeuaxMRnCsH8+5g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.1.tgz", + "integrity": "sha512-X53z6uXip6KFXBQ+Krbx25XHV/NCbzryM6ehOAeAil7X7oa4XIq+394PWGnwaSQ2WRA0KI6PUO6hTO5zeF5ijA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.1.tgz", + "integrity": "sha512-Na9T3szbXezdzM/Kfs3GcRQNjHzM6GzFBeU1/6IV/npKP5ORtp9zbQjvkDJ47s6BCgaAZnnnu/cY1x342+MvZg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.1.tgz", + "integrity": "sha512-T3H78X2h1tszfRSf+txbt5aOp/e7TAz3ptVKu9Oyir3IAOFPGV6O9c2naym5TOriy1l0nNf6a4X5UXRZSGX/dw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.1.tgz", + "integrity": "sha512-2H3RUvcmULO7dIE5EWJH8eubZAI4xw54H1ilJnRNZdeo8dTADEZ21w6J22XBkXqGJbe0+wnNJtw3UXRoLJnFEg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.1.tgz", + "integrity": "sha512-GE7XvrdOzrb+yVKB9KsRMq+7a2U/K5Cf/8grVFRAGJmfADr/e/ODQ134RK2/eeHqYV5eQRFxb1hY7Nr15fv1NQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.1.tgz", + "integrity": "sha512-uOxSJCIcavSiT6UnBhBzE8wy3n0hOkJsBOzy7HDAuTDE++1DJMRRVCPGisULScHL+a/ZwdXPpXD3IyFKjA7K8A==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, "node_modules/@esbuild/win32-x64": { - "version": "0.24.2", - "integrity": "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.1.tgz", + "integrity": "sha512-Y1EQdcfwMSeQN/ujR5VayLOJ1BHaK+ssyk0AEzPjC+t1lITgsnccPqFjb6V+LsTp/9Iov4ysfjxLaGJ9RPtkVg==", "cpu": [ "x64" ], @@ -1176,8 +1562,9 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/axios": { - "version": "1.7.9", - "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==", + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.3.tgz", + "integrity": "sha512-iP4DebzoNlP/YN2dpwCgb8zoCmhtkajzS48JvwmkSkXvPI3DHc7m+XYL5tGnSlJtR6nImXZmdCuN5aP8dh1d8A==", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -1474,8 +1861,9 @@ } }, "node_modules/esbuild": { - "version": "0.24.2", - "integrity": "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.1.tgz", + "integrity": "sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ==", "dev": true, "hasInstallScript": true, "bin": { @@ -1485,415 +1873,31 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.24.2", - "@esbuild/android-arm": "0.24.2", - "@esbuild/android-arm64": "0.24.2", - "@esbuild/android-x64": "0.24.2", - "@esbuild/darwin-arm64": "0.24.2", - "@esbuild/darwin-x64": "0.24.2", - "@esbuild/freebsd-arm64": "0.24.2", - "@esbuild/freebsd-x64": "0.24.2", - "@esbuild/linux-arm": "0.24.2", - "@esbuild/linux-arm64": "0.24.2", - "@esbuild/linux-ia32": "0.24.2", - "@esbuild/linux-loong64": "0.24.2", - "@esbuild/linux-mips64el": "0.24.2", - "@esbuild/linux-ppc64": "0.24.2", - "@esbuild/linux-riscv64": "0.24.2", - "@esbuild/linux-s390x": "0.24.2", - "@esbuild/linux-x64": "0.24.2", - "@esbuild/netbsd-arm64": "0.24.2", - "@esbuild/netbsd-x64": "0.24.2", - "@esbuild/openbsd-arm64": "0.24.2", - "@esbuild/openbsd-x64": "0.24.2", - "@esbuild/sunos-x64": "0.24.2", - "@esbuild/win32-arm64": "0.24.2", - "@esbuild/win32-ia32": "0.24.2", - "@esbuild/win32-x64": "0.24.2" - } - }, - "node_modules/esbuild/node_modules/@esbuild/aix-ppc64": { - "version": "0.24.2", - "resolved": "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz", - "integrity": "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/esbuild/node_modules/@esbuild/android-arm": { - "version": "0.24.2", - "resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.24.2.tgz", - "integrity": "sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/esbuild/node_modules/@esbuild/android-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.24.2.tgz", - "integrity": "sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/esbuild/node_modules/@esbuild/android-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.24.2.tgz", - "integrity": "sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/esbuild/node_modules/@esbuild/darwin-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.24.2.tgz", - "integrity": "sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/esbuild/node_modules/@esbuild/darwin-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.24.2.tgz", - "integrity": "sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/esbuild/node_modules/@esbuild/freebsd-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.2.tgz", - "integrity": "sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/esbuild/node_modules/@esbuild/freebsd-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.24.2.tgz", - "integrity": "sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/esbuild/node_modules/@esbuild/linux-arm": { - "version": "0.24.2", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.24.2.tgz", - "integrity": "sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/esbuild/node_modules/@esbuild/linux-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.24.2.tgz", - "integrity": "sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/esbuild/node_modules/@esbuild/linux-ia32": { - "version": "0.24.2", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.24.2.tgz", - "integrity": "sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/esbuild/node_modules/@esbuild/linux-loong64": { - "version": "0.24.2", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.24.2.tgz", - "integrity": "sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/esbuild/node_modules/@esbuild/linux-mips64el": { - "version": "0.24.2", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.24.2.tgz", - "integrity": "sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/esbuild/node_modules/@esbuild/linux-ppc64": { - "version": "0.24.2", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.24.2.tgz", - "integrity": "sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/esbuild/node_modules/@esbuild/linux-riscv64": { - "version": "0.24.2", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.24.2.tgz", - "integrity": "sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/esbuild/node_modules/@esbuild/linux-s390x": { - "version": "0.24.2", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.24.2.tgz", - "integrity": "sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/esbuild/node_modules/@esbuild/linux-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.24.2.tgz", - "integrity": "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/esbuild/node_modules/@esbuild/netbsd-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmmirror.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.24.2.tgz", - "integrity": "sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/esbuild/node_modules/@esbuild/netbsd-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.24.2.tgz", - "integrity": "sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/esbuild/node_modules/@esbuild/openbsd-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmmirror.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.2.tgz", - "integrity": "sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/esbuild/node_modules/@esbuild/openbsd-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.24.2.tgz", - "integrity": "sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/esbuild/node_modules/@esbuild/sunos-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.24.2.tgz", - "integrity": "sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/esbuild/node_modules/@esbuild/win32-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.24.2.tgz", - "integrity": "sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/esbuild/node_modules/@esbuild/win32-ia32": { - "version": "0.24.2", - "resolved": "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.24.2.tgz", - "integrity": "sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" + "@esbuild/aix-ppc64": "0.25.1", + "@esbuild/android-arm": "0.25.1", + "@esbuild/android-arm64": "0.25.1", + "@esbuild/android-x64": "0.25.1", + "@esbuild/darwin-arm64": "0.25.1", + "@esbuild/darwin-x64": "0.25.1", + "@esbuild/freebsd-arm64": "0.25.1", + "@esbuild/freebsd-x64": "0.25.1", + "@esbuild/linux-arm": "0.25.1", + "@esbuild/linux-arm64": "0.25.1", + "@esbuild/linux-ia32": "0.25.1", + "@esbuild/linux-loong64": "0.25.1", + "@esbuild/linux-mips64el": "0.25.1", + "@esbuild/linux-ppc64": "0.25.1", + "@esbuild/linux-riscv64": "0.25.1", + "@esbuild/linux-s390x": "0.25.1", + "@esbuild/linux-x64": "0.25.1", + "@esbuild/netbsd-arm64": "0.25.1", + "@esbuild/netbsd-x64": "0.25.1", + "@esbuild/openbsd-arm64": "0.25.1", + "@esbuild/openbsd-x64": "0.25.1", + "@esbuild/sunos-x64": "0.25.1", + "@esbuild/win32-arm64": "0.25.1", + "@esbuild/win32-ia32": "0.25.1", + "@esbuild/win32-x64": "0.25.1" } }, "node_modules/escape-html": { @@ -2402,8 +2406,9 @@ } }, "node_modules/postcss": { - "version": "8.5.1", - "integrity": "sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==", + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", + "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", "funding": [ { "type": "opencollective", @@ -2437,9 +2442,9 @@ } }, "node_modules/prismjs": { - "version": "1.29.0", - "resolved": "https://registry.npmmirror.com/prismjs/-/prismjs-1.29.0.tgz", - "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==", + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz", + "integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==", "engines": { "node": ">=6" } @@ -2905,12 +2910,13 @@ "dev": true }, "node_modules/vite": { - "version": "6.1.0", - "integrity": "sha512-RjjMipCKVoR4hVfPY6GQTgveinjNuyLw+qruksLDvA5ktI1150VmcMBKmQaEWJhg/j6Uaf6dNCNA0AfdzUb/hQ==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.1.tgz", + "integrity": "sha512-n2GnqDb6XPhlt9B8olZPrgMD/es/Nd1RdChF6CBD/fHW6pUyUTt2sQW2fPRX5GiD9XEa6+8A6A4f2vT6pSsE7Q==", "dev": true, "dependencies": { - "esbuild": "^0.24.2", - "postcss": "^8.5.1", + "esbuild": "^0.25.0", + "postcss": "^8.5.3", "rollup": "^4.30.1" }, "bin": { diff --git a/src/router/index.js b/src/router/index.js index f0dc892..c176ef6 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -1,4 +1,4 @@ -import { createRouter, createWebHistory } from 'vue-router' +import { createRouter, createWebHashHistory } from 'vue-router' import AdminLayout from '../layout/AdminLayout.vue' import { useUserStore } from '../stores/user' @@ -24,7 +24,7 @@ Promise.all([ ]) const router = createRouter({ - history: createWebHistory(), + history: createWebHashHistory(), routes: [ { path: '/', diff --git a/src/utils/SoundEffect.js b/src/utils/SoundEffect.js new file mode 100644 index 0000000..213b117 --- /dev/null +++ b/src/utils/SoundEffect.js @@ -0,0 +1,35 @@ +class SoundEffect { + constructor() { + this.SOUND_CONNECT = new Audio('/src/assets/harmonyos-sound/notification_accomplished_08.wav'); + this.SOUND_DISCONNECT = new Audio('/src/assets/harmonyos-sound/notification_wrong_04.wav'); + } + + // 播放连接成功音效 + playConnectSound() { + this.SOUND_CONNECT.currentTime = 0; + this.SOUND_CONNECT.play().catch(error => { + console.error('音效播放失败:', error); + }); + } + + // 播放断开连接音效 + playDisconnectSound() { + this.SOUND_DISCONNECT.currentTime = 0; + this.SOUND_DISCONNECT.play().catch(error => { + console.error('音效播放失败:', error); + }); + } + + // 根据状态播放对应音效 + playStatusSound(isOnline) { + if (isOnline) { + this.playConnectSound(); + } else { + this.playDisconnectSound(); + } + } +} + +// 创建单例实例 +const soundEffect = new SoundEffect(); +export default soundEffect; \ No newline at end of file diff --git a/src/views/AIPatrol/drone/index.vue b/src/views/AIPatrol/drone/index.vue index b28f3d9..d5adcd8 100644 --- a/src/views/AIPatrol/drone/index.vue +++ b/src/views/AIPatrol/drone/index.vue @@ -1,10 +1,36 @@ diff --git a/src/views/AIPatrol/sensor/index.vue b/src/views/AIPatrol/sensor/index.vue index 4180982..e1e5d17 100644 --- a/src/views/AIPatrol/sensor/index.vue +++ b/src/views/AIPatrol/sensor/index.vue @@ -3,10 +3,285 @@ import { ref, onMounted, onUnmounted } from "vue"; import { Plus, Monitor, Timer } from "@element-plus/icons-vue"; import { ElMessage, ElNotification } from "element-plus"; import { getDeviceList, deleteDevice } from "@/api/device"; +import * as echarts from 'echarts'; +import soundEffect from '@/utils/SoundEffect'; // 加载状态 const loading = ref(false); +// 图表相关 +const chartDialogVisible = ref(false); +const chartInstance = ref(null); +const chartData = ref([]); +const currentSensor = ref(null); + +// 初始化图表 +const initChart = () => { + if (!chartInstance.value) { + const chartDom = document.getElementById('sensorChart'); + if (!chartDom) return; + + chartInstance.value = echarts.init(chartDom); + } + + const option = { + backgroundColor: '#ffffff', + title: { + text: 'TDS值实时监测趋势', + left: 'center', + top: 10, + textStyle: { + fontSize: 18, + fontWeight: 500, + color: '#333' + } + }, + tooltip: { + trigger: 'axis', + backgroundColor: 'rgba(255, 255, 255, 0.9)', + borderColor: '#409EFF', + borderWidth: 1, + padding: [10, 15], + textStyle: { + color: '#666' + }, + axisPointer: { + type: 'line', + lineStyle: { + color: '#409EFF', + opacity: 0.2, + width: 2 + } + }, + formatter: (params) => { + const data = params[0]; + return ` +
+
${data.name}
+
+ TDS值:${data.value} mg/L +
+
+ `; + } + }, + grid: { + top: 80, + left: 60, + right: 40, + bottom: 60, + containLabel: true + }, + xAxis: { + type: 'category', + data: chartData.value.map(item => item.time), + axisLabel: { + rotate: 45, + formatter: (value) => { + const [hour, minute, second] = value.split(':'); + return `${hour}:${minute}:${second}`; + }, + color: '#666', + fontSize: 12 + }, + axisTick: { + show: false + }, + axisLine: { + lineStyle: { + color: '#eee' + } + }, + splitLine: { + show: true, + lineStyle: { + color: '#f5f5f5', + type: 'dashed' + } + } + }, + yAxis: { + type: 'value', + name: 'TDS值 (mg/L)', + nameLocation: 'middle', + nameGap: 45, + nameTextStyle: { + color: '#666', + fontSize: 13, + fontWeight: 500, + padding: [0, 0, 10, 0] + }, + axisLine: { + show: true, + lineStyle: { + color: '#eee' + } + }, + axisTick: { + show: false + }, + axisLabel: { + color: '#666', + fontSize: 12, + formatter: '{value}' + }, + splitLine: { + lineStyle: { + color: '#f5f5f5', + type: 'dashed' + } + } + }, + series: [{ + name: 'TDS值', + type: 'line', + data: chartData.value.map(item => item.value), + smooth: true, + symbol: 'circle', + symbolSize: 8, + lineStyle: { + width: 4, + color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ + { offset: 0, color: '#409EFF' }, + { offset: 1, color: '#36CE9E' } + ]), + shadowColor: 'rgba(64,158,255,0.3)', + shadowBlur: 10 + }, + itemStyle: { + color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ + { offset: 0, color: '#409EFF' }, + { offset: 1, color: '#36CE9E' } + ]), + borderColor: '#fff', + borderWidth: 2, + shadowColor: 'rgba(64,158,255,0.5)', + shadowBlur: 5 + }, + areaStyle: { + color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ + { offset: 0, color: 'rgba(64,158,255,0.3)' }, + { offset: 0.5, color: 'rgba(64,158,255,0.15)' }, + { offset: 1, color: 'rgba(64,158,255,0.05)' } + ]) + }, + emphasis: { + itemStyle: { + borderWidth: 3, + borderColor: '#fff', + shadowColor: 'rgba(64,158,255,0.8)', + shadowBlur: 10 + } + }, + animationDuration: 1000, + animationEasing: 'cubicOut' + }] + }; + + // 根据不同的监测类型设置不同的y轴范围和渐变色 + if (currentSensor.value?.monitoringType === 'h') { + option.yAxis.min = 1180; + option.yAxis.max = 1190; + option.series[0].lineStyle.color = new echarts.graphic.LinearGradient(0, 0, 0, 1, [ + { offset: 0, color: '#36CE9E' }, + { offset: 1, color: '#3B7FFF' } + ]); + option.series[0].itemStyle.color = option.series[0].lineStyle.color; + option.series[0].areaStyle.color = new echarts.graphic.LinearGradient(0, 0, 0, 1, [ + { offset: 0, color: 'rgba(54,206,158,0.3)' }, + { offset: 1, color: 'rgba(59,127,255,0.05)' } + ]); + } else if (currentSensor.value?.monitoringType === 'c') { + option.yAxis.min = 220; + option.yAxis.max = 228; + option.series[0].lineStyle.color = new echarts.graphic.LinearGradient(0, 0, 0, 1, [ + { offset: 0, color: '#FF9F43' }, + { offset: 1, color: '#FF6B6B' } + ]); + option.series[0].itemStyle.color = option.series[0].lineStyle.color; + option.series[0].areaStyle.color = new echarts.graphic.LinearGradient(0, 0, 0, 1, [ + { offset: 0, color: 'rgba(255,159,67,0.3)' }, + { offset: 1, color: 'rgba(255,107,107,0.05)' } + ]); + } else if (currentSensor.value?.monitoringType === 'f') { + option.yAxis.min = 466; + option.yAxis.max = 474; + option.series[0].lineStyle.color = new echarts.graphic.LinearGradient(0, 0, 0, 1, [ + { offset: 0, color: '#845EF7' }, + { offset: 1, color: '#BE4BDB' } + ]); + option.series[0].itemStyle.color = option.series[0].lineStyle.color; + option.series[0].areaStyle.color = new echarts.graphic.LinearGradient(0, 0, 0, 1, [ + { offset: 0, color: 'rgba(132,94,247,0.3)' }, + { offset: 1, color: 'rgba(190,75,219,0.05)' } + ]); + } + + chartInstance.value.setOption(option); +} + +// 窗口大小改变时重绘图表 +const handleResize = () => { + if (chartInstance.value) { + chartInstance.value.resize(); + } +} + +// 显示图表 +const showChart = (sensor) => { + // 深拷贝传感器数据,确保不会相互影响 + currentSensor.value = JSON.parse(JSON.stringify(sensor)); + chartDialogVisible.value = true; + + // 生成模拟数据 + const now = new Date(); + chartData.value = Array.from({ length: 10 }, (_, i) => { + const time = new Date(now - (9 - i) * 1000); + let value; + + // 根据不同的监测类型生成不同范围的数据 + if (sensor.monitoringType === 'h') { + // 海水 (1000-1370) + value = 1185 + (Math.random() * 6 - 3); + } else if (sensor.monitoringType === 'c') { + // 茶水 (200-248) + value = 224 + (Math.random() * 4 - 2); + } else if (sensor.monitoringType === 'f') { + // 芬达 (450-490) + value = 470 + (Math.random() * 4 - 2); + } else { + value = sensor.data?.tds || 0; + } + + return { + time: time.toLocaleTimeString('zh-CN', { + hour12: false, + hour: '2-digit', + minute: '2-digit', + second: '2-digit' + }), + value: Number(value.toFixed(2)) + }; + }); + + // 在下一个 tick 初始化图表 + setTimeout(() => { + initChart(); + }, 100); +} + +// 监听窗口大小变化 +onMounted(() => { + window.addEventListener('resize', handleResize); +}); + +onUnmounted(() => { + window.removeEventListener('resize', handleResize); + if (chartInstance.value) { + chartInstance.value.dispose(); + } +}); + // 传感器列表数据 const sensorList = ref([ { @@ -168,6 +443,53 @@ const dataRefreshTimers = ref({ f: null, }); +// 更新图表数据 +const updateChartData = (value) => { + if (!chartDialogVisible.value) return; + + const now = new Date(); + const time = now.toLocaleTimeString('zh-CN', { + hour12: false, + hour: '2-digit', + minute: '2-digit', + second: '2-digit' + }); + + // 添加新数据点 + chartData.value.push({ + time, + value: Number(value.toFixed(2)) + }); + + // 保持最多显示30个数据点 + if (chartData.value.length > 30) { + chartData.value.shift(); + } + + // 更新图表 + if (chartInstance.value) { + chartInstance.value.setOption({ + xAxis: { + data: chartData.value.map(item => item.time) + }, + series: [{ + data: chartData.value.map(item => item.value) + }] + }); + } + + // 更新当前传感器数据 + if (currentSensor.value) { + currentSensor.value = { + ...currentSensor.value, + data: { + ...currentSensor.value.data, + tds: value + } + }; + } +}; + // 添加键盘事件处理函数 const handleKeyPress = (event) => { const key = event.key.toLowerCase(); @@ -184,6 +506,17 @@ const handleKeyPress = (event) => { }, })); + // 更新当前传感器状态 + if (currentSensor.value) { + currentSensor.value = { + ...currentSensor.value, + status: isOnline ? 0 : 1, + data: { + tds: null + } + }; + } + // 清理所有定时器 Object.entries(dataRefreshTimers.value).forEach(([timerKey, timer]) => { if (timer) { @@ -192,6 +525,9 @@ const handleKeyPress = (event) => { } }); + // 播放对应的音效 + soundEffect.playStatusSound(!isOnline); + ElNotification({ title: isOnline ? "设备离线" : "设备上线", message: isOnline ? "设备已停止工作" : "设备开始工作", @@ -211,14 +547,17 @@ const handleKeyPress = (event) => { h: { // 海水参考值 (1000-1370) tds: 1185, + monitoringType: 'h' }, c: { // 茶水参考值 (200-248) tds: 224, + monitoringType: 'c' }, f: { // 芬达参考值 (450-490) tds: 470, + monitoringType: 'f' }, }; @@ -233,7 +572,19 @@ const handleKeyPress = (event) => { data: { tds: null, }, + monitoringType: null })); + + // 更新当前传感器状态 + if (currentSensor.value) { + currentSensor.value = { + ...currentSensor.value, + data: { + tds: null + }, + monitoringType: null + }; + } return; } @@ -247,6 +598,19 @@ const handleKeyPress = (event) => { // 开始新的数据刷新 const startData = substanceData[key]; + sensorList.value = sensorList.value.map(sensor => ({ + ...sensor, + monitoringType: key + })); + + // 更新当前传感器监测类型 + if (currentSensor.value) { + currentSensor.value = { + ...currentSensor.value, + monitoringType: key + }; + } + dataRefreshTimers.value[key] = setInterval(() => { // 生成随机波动值,根据不同液体设置不同的波动范围 let randomValue; @@ -278,6 +642,9 @@ const handleKeyPress = (event) => { tds: randomValue, }, })); + + // 更新图表数据 + updateChartData(randomValue); }, 1000); // 每秒更新一次 } }; @@ -313,6 +680,7 @@ onUnmounted(() => { :key="sensor.id" class="sensor-card" :class="{ offline: sensor.status === 0 }" + @click="showChart(sensor)" >
@@ -404,6 +772,41 @@ onUnmounted(() => { @current-change="handleCurrentChange" />
+ + + +
+ +
+
+ 实时TDS值 + + {{ formatValue(currentSensor?.data?.tds, 'mg/L') }} + +
+
+ + {{ currentSensor?.status === 1 ? '在线监测中' : '设备离线' }} + + + + 更新时间: {{ new Date().toLocaleTimeString('zh-CN', { hour12: false }) }} + +
+
+ +
+
+
@@ -450,10 +853,11 @@ onUnmounted(() => { overflow: hidden; transition: all 0.3s; box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05); - + cursor: pointer; + &:hover { - transform: translateY(-2px); - box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08); + transform: translateY(-4px); + box-shadow: 0 6px 16px rgba(0, 0, 0, 0.12); } .card-header { @@ -628,4 +1032,58 @@ onUnmounted(() => { align-items: center; } } + +// 添加图表相关样式 +.chart-container { + .tds-display { + background: #f8f9fb; + border-radius: 8px; + padding: 20px; + margin-bottom: 20px; + box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05); + + .tds-value { + display: flex; + flex-direction: column; + align-items: center; + margin-bottom: 16px; + + .label { + font-size: 16px; + color: #606266; + margin-bottom: 8px; + } + + .value { + font-size: 48px; + font-weight: 600; + color: #409EFF; + font-family: "DIN Alternate", sans-serif; + + &.offline { + color: #909399; + } + } + } + + .tds-info { + display: flex; + justify-content: center; + align-items: center; + gap: 20px; + + .update-time { + color: #909399; + font-size: 14px; + display: flex; + align-items: center; + gap: 4px; + + .el-icon { + font-size: 16px; + } + } + } + } +} diff --git a/src/views/dashboard/screen/components/CenterPanel/VideoMonitor.vue b/src/views/dashboard/screen/components/CenterPanel/VideoMonitor.vue index b6ee8f1..03a0fd6 100644 --- a/src/views/dashboard/screen/components/CenterPanel/VideoMonitor.vue +++ b/src/views/dashboard/screen/components/CenterPanel/VideoMonitor.vue @@ -10,10 +10,7 @@ import { Connection, Loading } from '@element-plus/icons-vue' - -// 音效资源 -const SOUND_CONNECT = new Audio('/src/assets/harmonyos-sound/notification_accomplished_08.wav') -const SOUND_DISCONNECT = new Audio('/src/assets/harmonyos-sound/notification_wrong_04.wav') +import soundEffect from '@/utils/SoundEffect' // 添加用户交互标记 let hasUserInteracted = false @@ -26,17 +23,6 @@ const handleUserInteraction = () => { document.removeEventListener('keydown', handleUserInteraction) } -// 播放音效 -const playSound = (status) => { - if (!hasUserInteracted) return - - const sound = status === 'online' ? SOUND_CONNECT : SOUND_DISCONNECT - sound.currentTime = 0 // 重置音频播放位置 - sound.play().catch(error => { - console.error('音效播放失败:', error) - }) -} - // 无人机数据 const drone = ref(null) const loading = ref(false) @@ -55,101 +41,228 @@ let wsRetryCount = 0 const MAX_RETRY_COUNT = 3 let wsRetryTimer = null +// 存储键名常量 +const CHART_DATA_STORAGE_KEY = 'wetland_ph_chart_data' +const CHART_DATA_TIMESTAMP_KEY = 'wetland_ph_chart_timestamp' +const CHART_DATA_EXPIRE_TIME = 24 * 60 * 60 * 1000 // 24小时过期 + +// 保存图表数据到本地存储 +const saveChartDataToStorage = (data) => { + try { + localStorage.setItem(CHART_DATA_STORAGE_KEY, JSON.stringify(data)) + localStorage.setItem(CHART_DATA_TIMESTAMP_KEY, Date.now().toString()) + } catch (error) { + console.error('保存图表数据到本地存储失败:', error) + } +} + +// 从本地存储获取图表数据 +const getChartDataFromStorage = () => { + try { + const timestamp = localStorage.getItem(CHART_DATA_TIMESTAMP_KEY) + if (!timestamp) return null + + // 检查数据是否过期 + if (Date.now() - parseInt(timestamp) > CHART_DATA_EXPIRE_TIME) { + localStorage.removeItem(CHART_DATA_STORAGE_KEY) + localStorage.removeItem(CHART_DATA_TIMESTAMP_KEY) + return null + } + + const data = localStorage.getItem(CHART_DATA_STORAGE_KEY) + return data ? JSON.parse(data) : null + } catch (error) { + console.error('从本地存储获取图表数据失败:', error) + return null + } +} + // 获取图表数据 const getChartData = async () => { try { const res = await generateChartData({ message: "ph柱状图" }) + if (res.success) { - initChart(res.data) + console.log('完整的响应数据:', res); + console.log('图表配置数据:', res.data?.echart_options); + + if (!res.data?.echart_options) { + console.error('图表配置数据结构不完整'); + // 尝试使用本地存储的数据 + const storageData = getChartDataFromStorage() + if (storageData) { + console.log('使用本地存储的图表数据'); + initChart(storageData) + } else { + initChart(getDefaultChartData().echart_options) + } + return; + } + + // 保存新数据到本地存储 + saveChartDataToStorage(res.data.echart_options) + initChart(res.data.echart_options) } else { console.error('获取图表数据失败:', res.message) - initChart(getDefaultChartData()) + // 尝试使用本地存储的数据 + const storageData = getChartDataFromStorage() + if (storageData) { + console.log('使用本地存储的图表数据'); + initChart(storageData) + } else { + initChart(getDefaultChartData().echart_options) + } } } catch (error) { console.error('获取图表数据失败:', error) - initChart(getDefaultChartData()) + // 尝试使用本地存储的数据 + const storageData = getChartDataFromStorage() + if (storageData) { + console.log('使用本地存储的图表数据'); + initChart(storageData) + } else { + initChart(getDefaultChartData().echart_options) + } } } // 初始化图表 -const initChart = (data) => { - if (!chartRef.value) return - - if (chart) { - chart.dispose() +const initChart = (options) => { + + if (!chartRef.value) { + console.error('图表DOM引用未找到'); + return; } - chart = echarts.init(chartRef.value) + try { + if (chart) { + chart.dispose() + } - // 直接使用后端返回的配置,只添加必要的样式 - const option = { - backgroundColor: 'transparent', - title: { - ...data.echart_options.title, - textStyle: { - color: '#fff' - } - }, - tooltip: data.echart_options.tooltip, - legend: { - ...data.echart_options.legend, - textStyle: { - color: '#fff' - } - }, - xAxis: { - type: 'category', - data: data.echart_options.series[0].xAxis.data, - axisLine: { - lineStyle: { - color: 'rgba(255, 255, 255, 0.3)' + chart = echarts.init(chartRef.value) + + // 检查必要的数据结构 + if (!options.xAxis?.data && !options.series?.[0]?.data) { + console.error('数据结构不正确,使用默认配置'); + options = getDefaultChartData().echart_options; + } + + // 确保 yAxis 配置正确 + const yAxisConfig = Array.isArray(options.yAxis) ? options.yAxis[0] : options.yAxis; + + const option = { + backgroundColor: 'transparent', + title: { + ...(options.title || { text: 'pH值变化趋势' }), + textStyle: { + color: '#fff' } }, - axisLabel: { - color: 'rgba(255, 255, 255, 0.7)' - } - }, - yAxis: { - type: 'value', - name: 'pH值', - max: 8, - axisLine: { - lineStyle: { - color: 'rgba(255, 255, 255, 0.3)' + tooltip: options.tooltip || { + trigger: 'axis', + axisPointer: { + type: 'shadow' } }, - axisLabel: { - color: 'rgba(255, 255, 255, 0.7)' - }, - splitLine: { - lineStyle: { - color: 'rgba(255, 255, 255, 0.1)' + legend: { + ...(options.legend || {}), + textStyle: { + color: '#fff' } - } - }, - series: [{ - name: '酸性指数', - type: 'line', - smooth: true, - data: data.echart_options.series[0].xAxis.data.map(() => (Math.random() * 2 + 6).toFixed(1)), // 临时随机数据 - areaStyle: { - color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ - { offset: 0, color: 'rgba(64, 158, 255, 0.7)' }, - { offset: 1, color: 'rgba(64, 158, 255, 0.1)' } - ]) }, - itemStyle: { - color: '#409EFF' + grid: { + left: '3%', + right: '4%', + bottom: '3%', + containLabel: true + }, + xAxis: { + type: 'category', + data: options.xAxis?.data || [], + axisLine: { + lineStyle: { + color: 'rgba(255, 255, 255, 0.3)' + } + }, + axisLabel: { + color: 'rgba(255, 255, 255, 0.7)' + } + }, + yAxis: { + type: 'value', + name: 'pH值', + max: 8, + ...(yAxisConfig || {}), + axisLine: { + lineStyle: { + color: 'rgba(255, 255, 255, 0.3)' + } + }, + axisLabel: { + color: 'rgba(255, 255, 255, 0.7)' + }, + splitLine: { + lineStyle: { + color: 'rgba(255, 255, 255, 0.1)' + } + } + }, + series: Array.isArray(options.series) ? options.series.map(series => ({ + ...series, + yAxisIndex: 0, // 确保所有系列都使用同一个 yAxis + areaStyle: series.areaStyle || { + color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ + { offset: 0, color: 'rgba(64, 158, 255, 0.7)' }, + { offset: 1, color: 'rgba(64, 158, 255, 0.1)' } + ]) + } + })) : [ + { + name: 'pH值', + type: 'line', + smooth: true, + yAxisIndex: 0, + data: [], + areaStyle: { + color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ + { offset: 0, color: 'rgba(64, 158, 255, 0.7)' }, + { offset: 1, color: 'rgba(64, 158, 255, 0.1)' } + ]) + } + } + ] + } + + // 设置配置前确保数据结构完整 + if (!option.yAxis || !option.xAxis || !option.series) { + throw new Error('图表配置数据结构不完整'); + } + + chart.setOption(option) + + // 确保图表正确渲染 + nextTick(() => { + if (chart) { + chart.resize() } - }] + }) + } catch (error) { + console.error('图表初始化失败:', error); + // 尝试使用完全默认的配置重新初始化 + try { + if (chart) { + const defaultOption = getDefaultChartData().echart_options; + chart.setOption(defaultOption); + } + } catch (retryError) { + console.error('使用默认配置重试失败:', retryError); + } } - - chart.setOption(option) } -// 生成默认图表数据 +// 修改默认图表数据的结构 const getDefaultChartData = () => { return { echart_options: { @@ -169,18 +282,17 @@ const getDefaultChartData = () => { type: "category", data: [] }, - yAxis: [ - { - type: "value", - name: "pH值", - max: 8 - } - ], + yAxis: { + type: "value", + name: "pH值", + max: 8 + }, series: [ { name: "pH值", type: "line", smooth: true, + yAxisIndex: 0, areaStyle: {}, data: [] } @@ -192,7 +304,7 @@ const getDefaultChartData = () => { // 显示设备状态通知 const showDeviceStatusNotification = (status) => { // 播放对应音效 - playSound(status) + soundEffect.playStatusSound(status === 'online') ElNotification({ title: status === 'online' ? '设备已接入' : '设备已接出', @@ -222,7 +334,6 @@ const initWebSocket = () => { ws = new WebSocket('ws://127.0.0.1:6894') ws.onopen = () => { - console.log('WebSocket连接成功') wsConnected.value = true wsRetryCount = 0 // 重置重试次数 if (wsRetryTimer) { @@ -300,6 +411,7 @@ const initWebSocket = () => { } else { // 否则尝试重连 wsRetryTimer = setTimeout(() => { + console.log(`尝试WebSocket重连 (${wsRetryCount}/${MAX_RETRY_COUNT})...`) initWebSocket() }, 5000 * Math.min(wsRetryCount, 3)) // 重试间隔随次数增加但最多15秒 @@ -579,6 +691,13 @@ onMounted(() => { document.addEventListener('click', handleUserInteraction) document.addEventListener('keydown', handleUserInteraction) + // 初始化时先尝试使用本地存储的数据 + const storageData = getChartDataFromStorage() + if (storageData) { + console.log('使用本地存储的图表数据初始化'); + initChart(storageData) + } + // 初始化WebSocket连接 initWebSocket() // 获取无人机信息 diff --git a/vite.config.js b/vite.config.js index 3877f37..599db79 100644 --- a/vite.config.js +++ b/vite.config.js @@ -4,6 +4,7 @@ import path from 'path' // https://vitejs.dev/config/ export default defineConfig({ + base: './', plugins: [vue()], resolve: { alias: {