From 1999b8e5d9ae726d7646f4d6b7c1ade69870a237 Mon Sep 17 00:00:00 2001 From: hwj Date: Tue, 31 Mar 2026 17:20:26 +0800 Subject: [PATCH] =?UTF-8?q?feat=EF=BC=9A=E8=AE=BE=E5=A4=87=E5=9C=B0?= =?UTF-8?q?=E5=9B=BE=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 1 + pnpm-lock.yaml | 159 ++++++ src/api/iot/device/index.ts | 4 + src/views/iot/device/management/index.vue | 157 +++--- src/views/iot/map/components/DeviceMap.vue | 254 +++++++++ src/views/iot/map/index.vue | 615 +++++++++++++++++++++ 6 files changed, 1109 insertions(+), 81 deletions(-) create mode 100644 src/views/iot/map/components/DeviceMap.vue create mode 100644 src/views/iot/map/index.vue diff --git a/package.json b/package.json index 606c728..073a3d1 100644 --- a/package.json +++ b/package.json @@ -62,6 +62,7 @@ "min-dash": "^4.1.1", "mitt": "^3.0.1", "nprogress": "^0.2.0", + "ol": "^10.8.0", "pinia": "^2.1.7", "pinia-plugin-persistedstate": "^3.2.1", "qrcode": "^1.5.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 902bb89..13de095 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -119,6 +119,9 @@ importers: nprogress: specifier: ^0.2.0 version: 0.2.0 + ol: + specifier: ^10.8.0 + version: 10.8.0 pinia: specifier: ^2.1.7 version: 2.2.8(typescript@5.3.3)(vue@3.5.12(typescript@5.3.3)) @@ -1468,6 +1471,9 @@ packages: resolution: {integrity: sha512-i0GV1yJnm2n3Yq1qw6QrUrd/LI9bE8WEBOTtOkpCXHHdyN3TAGgqAK/DAT05z4fq2x04cARXt2pDmjWjL92iTQ==} engines: {node: '>= 10.0.0'} + '@petamoriken/float16@3.9.3': + resolution: {integrity: sha512-8awtpHXCx/bNpFt4mt2xdkgtgVvKqty8VbjHI/WWWQuEw+KLzFot3f4+LkQY9YmOtq7A5GdOnqoIC8Pdygjk2g==} + '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} @@ -1846,6 +1852,9 @@ packages: '@types/qs@6.9.17': resolution: {integrity: sha512-rX4/bPcfmvxHDv0XjfJELTTr+iB+tn032nPILqHm5wbthUUUuVtNGGqzhya9XUxjTP8Fpr0qYgSZZKxGY++svQ==} + '@types/rbush@4.0.0': + resolution: {integrity: sha512-+N+2H39P8X+Hy1I5mC6awlTX54k3FhiUmvt7HWzGJZvF+syUAAxP/stwppS8JE84YHqFgRMv6fCy31202CMFxQ==} + '@types/semver@7.5.8': resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} @@ -2352,6 +2361,9 @@ packages: resolution: {integrity: sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==} engines: {node: '>=10.0.0'} + '@zarrita/storage@0.1.4': + resolution: {integrity: sha512-qURfJAQcQGRfDQ4J9HaCjGaj3jlJKc66bnRk6G/IeLUsM7WKyG7Bzsuf1EZurSXyc0I4LVcu6HaeQQ4d3kZ16g==} + '@zxcvbn-ts/core@3.0.4': resolution: {integrity: sha512-aQeiT0F09FuJaAqNrxynlAwZ2mW/1MdXakKWNmGM1Qp/VaY6CnB/GfnMS2T8gB2231Esp1/maCWd8vTG4OuShw==} @@ -3035,6 +3047,9 @@ packages: duplexer@0.1.2: resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} + earcut@3.0.2: + resolution: {integrity: sha512-X7hshQbLyMJ/3RPhyObLARM2sNxxmRALLKx1+NVFFnQ9gKzmCrxm9+uLIAdBcvc8FNLpctqlQ2V6AE92Ol9UDQ==} + eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} @@ -3278,6 +3293,9 @@ packages: feelin@3.2.0: resolution: {integrity: sha512-GFDbHsTYk7YXO1tyw1dOjb7IODeAZvNIosdGZThUwPx5XcD/XhO0hnPZXsIbAzSsIdrgGlTEEdby9fZ2gixysA==} + fflate@0.8.2: + resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==} + file-entry-cache@6.0.1: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} @@ -3362,6 +3380,10 @@ packages: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} + geotiff@3.0.5: + resolution: {integrity: sha512-OWcL9S9+yDZ6iAlXMt32T1iwUApJM8UiD47xbm6ZP1h33d10fqkPs14EG/ttT5EnefpZSx3G15iDFC5FxUNUwA==} + engines: {node: '>=10.19'} + get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} @@ -3729,6 +3751,9 @@ packages: lang-feel@2.2.0: resolution: {integrity: sha512-Ebo5nftYsMfJzB3Ny8Oy4oaDXZXb5x61qtVVmKv6aImvAZUbT76mD60ZbEilizjZQzsR2CcU1iMK5sacIa1NVA==} + lerc@3.0.0: + resolution: {integrity: sha512-Rm4J/WaHhRa93nCN2mwWDZFoRVF18G1f47C+kvQWyHGEZxFpTUi73p7lMVSAndyxGt6lJ2/CFbOcf9ra5p8aww==} + levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} @@ -4075,6 +4100,9 @@ packages: nth-check@2.1.1: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + numcodecs@0.3.2: + resolution: {integrity: sha512-6YSPnmZgg0P87jnNhi3s+FVLOcIn3y+1CTIgUulA3IdASzK9fJM87sUFkpyA+be9GibGRaST2wCgkD+6U+fWKw==} + object-inspect@1.13.3: resolution: {integrity: sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==} engines: {node: '>= 0.4'} @@ -4088,6 +4116,9 @@ packages: ofetch@1.4.1: resolution: {integrity: sha512-QZj2DfGplQAr2oj9KzceK9Hwz6Whxazmn85yYeVuS3u9XTMOGMRx0kO95MQ+vLsj/S/NwBDMMLU5hpxvI6Tklw==} + ol@10.8.0: + resolution: {integrity: sha512-kLk7jIlJvKyhVMAjORTXKjzlM6YIByZ1H/d0DBx3oq8nSPCG6/gbLr5RxukzPgwbhnAqh+xHNCmrvmFKhVMvoQ==} + once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} @@ -4137,10 +4168,16 @@ packages: package-manager-detector@0.2.5: resolution: {integrity: sha512-3dS7y28uua+UDbRCLBqltMBrbI+A5U2mI9YuxHRxIWYmLj3DwntEBmERYzIAQ4DMeuCUOBSak7dBHHoXKpOTYQ==} + pako@2.1.0: + resolution: {integrity: sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==} + parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} + parse-headers@2.0.6: + resolution: {integrity: sha512-Tz11t3uKztEW5FEVZnj1ox8GKblWn+PvHY9TmJV5Mll2uHEwRdR/5Li1OlXoECjLYkApdhWy44ocONwXLiKO5A==} + parse-json@5.2.0: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} @@ -4198,6 +4235,10 @@ packages: pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + pbf@4.0.1: + resolution: {integrity: sha512-SuLdBvS42z33m8ejRbInMapQe8n0D3vN/Xd5fmWM3tufNgRQFBpaW2YVJxQZV4iPNqb0vEFvssMEo5w9c6BTIA==} + hasBin: true + perfect-debounce@1.0.0: resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} @@ -4337,6 +4378,9 @@ packages: resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} engines: {node: '>=0.4.0'} + protocol-buffers-schema@3.6.0: + resolution: {integrity: sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==} + proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} @@ -4366,9 +4410,19 @@ packages: queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + quick-lru@6.1.2: + resolution: {integrity: sha512-AAFUA5O1d83pIHEhJwWCq/RQcRukCkn/NSm2QsTEMle5f2hP0ChI2+3Xb051PZCkLryI/Ir1MVKviT2FIloaTQ==} + engines: {node: '>=12'} + + quickselect@3.0.0: + resolution: {integrity: sha512-XdjUArbK4Bm5fLLvlm5KpTFOiOThgfWWI4axAZDWg4E/0mKdZyI9tNEfds27qCi1ze/vwTR16kvmmGhRra3c2g==} + randomcolor@0.6.2: resolution: {integrity: sha512-Mn6TbyYpFgwFuQ8KJKqf3bqqY9O1y37/0jgSK/61PUxV4QfIMv0+K2ioq8DfOjkBslcjwSzRfIDEXfzA9aCx7A==} + rbush@4.0.1: + resolution: {integrity: sha512-IP0UpfeWQujYC8Jg162rMNc01Rf0gWMMAb2Uxus/Q0qOFw4lCcq6ZnQEZwUoJqWyUGJ9th7JjwI4yIWo+uvoAQ==} + rd@2.0.1: resolution: {integrity: sha512-/XdKU4UazUZTXFmI0dpABt8jSXPWcEyaGdk340KdHnsEOdkTctlX23aAK7ChQDn39YGNlAJr1M5uvaKt4QnpNw==} @@ -4383,6 +4437,9 @@ packages: resolution: {integrity: sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==} engines: {node: '>= 14.16.0'} + reference-spec-reader@0.2.0: + resolution: {integrity: sha512-q0mfCi5yZSSHXpCyxjgQeaORq3tvDsxDyzaadA/5+AbAUwRyRuuTh0aRQuE/vAOt/qzzxidJ5iDeu1cLHaNBlQ==} + regenerate-unicode-properties@10.2.0: resolution: {integrity: sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==} engines: {node: '>=4'} @@ -4437,6 +4494,9 @@ packages: resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} engines: {node: '>=8'} + resolve-protobuf-schema@2.1.0: + resolution: {integrity: sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==} + resolve@1.22.8: resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} hasBin: true @@ -4884,6 +4944,10 @@ packages: resolution: {integrity: sha512-5liCNPuJW8dqh3+DM6uNM2EI3MLLpCKp/KY+9pB5M2S2SR2qvvDHhKgBOaTWEbZTAws3CXfB0rKTIolWKL05VQ==} engines: {node: '>=14.0.0'} + unzipit@1.4.3: + resolution: {integrity: sha512-gsq2PdJIWWGhx5kcdWStvNWit9FVdTewm4SEG7gFskWs+XCVaULt9+BwuoBtJiRE8eo3L1IPAOrbByNLtLtIlg==} + engines: {node: '>=12'} + update-browserslist-db@1.1.1: resolution: {integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==} hasBin: true @@ -4907,6 +4971,9 @@ packages: resolution: {integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==} hasBin: true + uzip-module@1.0.3: + resolution: {integrity: sha512-AMqwWZaknLM77G+VPYNZLEruMGWGzyigPK3/Whg99B3S6vGHuqsyl5ZrOv1UUF3paGK1U6PM0cnayioaryg/fA==} + vanilla-picker@2.12.3: resolution: {integrity: sha512-qVkT1E7yMbUsB2mmJNFmaXMWE2hF8ffqzMMwe9zdAikd8u2VfnsVY2HQcOUi2F38bgbxzlJBEdS1UUhOXdF9GQ==} @@ -5070,6 +5137,9 @@ packages: web-storage-cache@1.1.1: resolution: {integrity: sha512-D0MieGooOs8RpsrK+vnejXnvh4OOv/+lTFB35JRkJJQt+uOjPE08XpaE0QBLMTRu47B1KGT/Nq3Gbag3Orinzw==} + web-worker@1.5.0: + resolution: {integrity: sha512-RiMReJrTAiA+mBjGONMnjVDP2u3p9R1vkcGz6gDIrOMT3oGuYwX2WRMYI9ipkphSuE5XKEhydbhNEJh4NY9mlw==} + webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} @@ -5129,6 +5199,9 @@ packages: resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} engines: {node: '>=12'} + xml-utils@1.10.2: + resolution: {integrity: sha512-RqM+2o1RYs6T8+3DzDSoTRAUfrvaejbVHcp3+thnAtDKo8LskR+HomLajEy5UjTz24rpka7AxVBRR3g2wTUkJA==} + y18n@4.0.3: resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} @@ -5177,12 +5250,18 @@ packages: resolution: {integrity: sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==} engines: {node: '>=12.20'} + zarrita@0.6.2: + resolution: {integrity: sha512-8IV+2bWt5yiHNVK9GVEVK1tscpqDcJj8iz5cIKFOiWiWYUsK4V5njgMtnpkvKu6L7K+Og6zUShd8f+dwb6LvTA==} + zeebe-bpmn-moddle@1.7.0: resolution: {integrity: sha512-eZ6OXSt0c4n9V/oN/46gTlwDIS3GhWQLt9jbM5uS/YryB4yN8wdrrKrtw+TpyNy0SSKWXNDHyC83nCA2blPO3Q==} zrender@5.6.0: resolution: {integrity: sha512-uzgraf4njmmHAbEUxMJ8Oxg+P3fT04O+9p7gY+wJRVxo8Ge+KmYv0WJev945EH4wFuc4OY2NLXz46FZrWS9xJg==} + zstddec@0.2.0: + resolution: {integrity: sha512-oyPnDa1X5c13+Y7mA/FDMNJrn4S8UNBe0KCqtDmor40Re7ALrPN6npFwyYVRRh+PqozZQdeg23QtbcamZnG5rA==} + snapshots: '@ampproject/remapping@2.3.0': @@ -6502,6 +6581,8 @@ snapshots: '@parcel/watcher-win32-x64': 2.5.0 optional: true + '@petamoriken/float16@3.9.3': {} + '@pkgjs/parseargs@0.11.0': optional: true @@ -6826,6 +6907,8 @@ snapshots: '@types/qs@6.9.17': {} + '@types/rbush@4.0.0': {} + '@types/semver@7.5.8': {} '@types/trusted-types@2.0.7': @@ -7600,6 +7683,11 @@ snapshots: '@xmldom/xmldom@0.8.10': {} + '@zarrita/storage@0.1.4': + dependencies: + reference-spec-reader: 0.2.0 + unzipit: 1.4.3 + '@zxcvbn-ts/core@3.0.4': dependencies: fastest-levenshtein: 1.0.16 @@ -8337,6 +8425,8 @@ snapshots: duplexer@0.1.2: {} + earcut@3.0.2: {} + eastasianwidth@0.2.0: {} echarts-wordcloud@2.1.0(echarts@5.5.1): @@ -8663,6 +8753,8 @@ snapshots: lezer-feel: 1.4.0 luxon: 3.5.0 + fflate@0.8.2: {} + file-entry-cache@6.0.1: dependencies: flat-cache: 3.2.0 @@ -8750,6 +8842,17 @@ snapshots: gensync@1.0.0-beta.2: {} + geotiff@3.0.5: + dependencies: + '@petamoriken/float16': 3.9.3 + lerc: 3.0.0 + pako: 2.1.0 + parse-headers: 2.0.6 + quick-lru: 6.1.2 + web-worker: 1.5.0 + xml-utils: 1.10.2 + zstddec: 0.2.0 + get-caller-file@2.0.5: {} get-east-asian-width@1.3.0: {} @@ -9075,6 +9178,8 @@ snapshots: '@lezer/common': 1.2.3 lezer-feel: 1.4.0 + lerc@3.0.0: {} + levn@0.4.1: dependencies: prelude-ls: 1.2.1 @@ -9420,6 +9525,10 @@ snapshots: dependencies: boolbase: 1.0.0 + numcodecs@0.3.2: + dependencies: + fflate: 0.8.2 + object-inspect@1.13.3: {} object-refs@0.3.0: {} @@ -9432,6 +9541,15 @@ snapshots: node-fetch-native: 1.6.4 ufo: 1.5.4 + ol@10.8.0: + dependencies: + '@types/rbush': 4.0.0 + earcut: 3.0.2 + geotiff: 3.0.5 + pbf: 4.0.1 + rbush: 4.0.1 + zarrita: 0.6.2 + once@1.4.0: dependencies: wrappy: 1.0.2 @@ -9483,10 +9601,14 @@ snapshots: package-manager-detector@0.2.5: {} + pako@2.1.0: {} + parent-module@1.0.1: dependencies: callsites: 3.1.0 + parse-headers@2.0.6: {} + parse-json@5.2.0: dependencies: '@babel/code-frame': 7.26.2 @@ -9532,6 +9654,10 @@ snapshots: pathe@2.0.3: {} + pbf@4.0.1: + dependencies: + resolve-protobuf-schema: 2.1.0 + perfect-debounce@1.0.0: {} picocolors@1.1.1: {} @@ -9650,6 +9776,8 @@ snapshots: progress@2.0.3: {} + protocol-buffers-schema@3.6.0: {} + proxy-from-env@1.1.0: {} punycode.js@2.3.1: {} @@ -9672,8 +9800,16 @@ snapshots: queue-microtask@1.2.3: {} + quick-lru@6.1.2: {} + + quickselect@3.0.0: {} + randomcolor@0.6.2: {} + rbush@4.0.1: + dependencies: + quickselect: 3.0.0 + rd@2.0.1: dependencies: '@types/node': 10.17.60 @@ -9686,6 +9822,8 @@ snapshots: readdirp@4.0.2: {} + reference-spec-reader@0.2.0: {} + regenerate-unicode-properties@10.2.0: dependencies: regenerate: 1.4.2 @@ -9732,6 +9870,10 @@ snapshots: resolve-from@5.0.0: {} + resolve-protobuf-schema@2.1.0: + dependencies: + protocol-buffers-schema: 3.6.0 + resolve@1.22.8: dependencies: is-core-module: 2.15.1 @@ -10256,6 +10398,10 @@ snapshots: acorn: 8.14.0 webpack-virtual-modules: 0.6.2 + unzipit@1.4.3: + dependencies: + uzip-module: 1.0.3 + update-browserslist-db@1.1.1(browserslist@4.24.2): dependencies: browserslist: 4.24.2 @@ -10277,6 +10423,8 @@ snapshots: uuid@10.0.0: {} + uzip-module@1.0.3: {} + vanilla-picker@2.12.3: dependencies: '@sphinxxxx/color-conversion': 2.2.2 @@ -10471,6 +10619,8 @@ snapshots: web-storage-cache@1.1.1: {} + web-worker@1.5.0: {} + webidl-conversions@3.0.1: {} webpack-virtual-modules@0.6.2: {} @@ -10531,6 +10681,8 @@ snapshots: xml-name-validator@4.0.0: {} + xml-utils@1.10.2: {} + y18n@4.0.3: {} y18n@5.0.8: {} @@ -10582,8 +10734,15 @@ snapshots: yocto-queue@1.1.1: {} + zarrita@0.6.2: + dependencies: + '@zarrita/storage': 0.1.4 + numcodecs: 0.3.2 + zeebe-bpmn-moddle@1.7.0: {} zrender@5.6.0: dependencies: tslib: 2.3.0 + + zstddec@0.2.0: {} diff --git a/src/api/iot/device/index.ts b/src/api/iot/device/index.ts index 185cdce..fae6a27 100644 --- a/src/api/iot/device/index.ts +++ b/src/api/iot/device/index.ts @@ -154,6 +154,10 @@ export const DeviceApi = { }) }, + getDeviceRunStatusStats: async () => { + return await request.get({ url: `/iot/device/device-run-status-stats` }) + }, + devicePointList: async () => { return await request.get({ url: `/iot/device/devicePointList` }) }, diff --git a/src/views/iot/device/management/index.vue b/src/views/iot/device/management/index.vue index bb5228e..fb2a701 100644 --- a/src/views/iot/device/management/index.vue +++ b/src/views/iot/device/management/index.vue @@ -11,7 +11,23 @@ class="device-mgmt__search" /> - +
+
+ 客户: {{ customerNodeTotal }} +
+
+ 设备: {{ deviceNodeTotal }} +
+ + + 刷新 + +
-
-
设备类型
-
{{ - selectedDeviceDetail?.deviceType || '-' - }}
-
-
-
关联设备模型
-
{{ - selectedDeviceDetail?.deviceModelId || '-' - }}
-
-
-
状态
-
{{ - selectedDeviceDetail?.status || '-' - }}
-
运行状态
{{ @@ -190,21 +188,21 @@ }}
-
关联组织
+
客户ID
{{ - selectedDeviceDetail?.org || '-' + selectedDeviceDetail?.customerId || '-' }}
-
客户ID
+
客户名称
{{ - selectedDeviceDetail?.customerId || '-' + selectedDeviceDetail?.customerName || '-' }}
-
组织节点ID
+
组织名称
{{ - selectedDeviceDetail?.orgNodeId || '-' + selectedDeviceDetail?.orgNodeName || '-' }}
@@ -220,48 +218,6 @@ selectedDeviceDetail?.protocol || '-' }} -
-
端点url
-
{{ - selectedDeviceDetail?.url || '-' - }}
-
-
-
采集周期
-
{{ - selectedDeviceDetail?.sampleCycle || '-' - }}
-
-
-
用户名
-
{{ - selectedDeviceDetail?.username || '-' - }}
-
-
-
密码
-
{{ - selectedDeviceDetail?.password ? '******' : '-' - }}
-
-
-
网关id
-
{{ - selectedDeviceDetail?.gatewayId || '-' - }}
-
-
-
读主题
-
{{ - selectedDeviceDetail?.readTopic || '-' - }}
-
-
-
写主题
-
{{ - selectedDeviceDetail?.writeTopic || '-' - }}
-
mqtt订阅主题
{{ @@ -297,12 +253,6 @@ : '-' }}
-
-
离线间隔
-
{{ - selectedDeviceDetail?.offLineDuration || '-' - }}
-
最后上线时间
{{ @@ -311,12 +261,6 @@ : '-' }}
-
-
设备品牌id
-
{{ - selectedDeviceDetail?.deviceBrandId || '-' - }}
-
备注
{{ @@ -506,7 +450,7 @@ import { useRoute } from 'vue-router' import NodeForm from './NodeForm.vue' import DeviceForm from '../DeviceForm.vue' import { formatDate } from '@/utils/formatTime' - +import { OfficeBuilding, Monitor, Refresh } from '@element-plus/icons-vue' defineOptions({ name: 'IoTDeviceManagement' }) type TreeNodeType = 'company' | 'line' | 'device' @@ -567,6 +511,7 @@ const deviceFormRef = ref() const rightMode = ref<'list' | 'detail'>('list') const nodeDeviceLoading = ref(false) const nodeDeviceList = ref([]) +const treeRefreshing = ref(false) const flattenDevices = (nodes: TreeNode[]) => { const devices: TreeNode[] = [] @@ -583,6 +528,28 @@ const flattenDevices = (nodes: TreeNode[]) => { const deviceList = computed(() => flattenDevices(treeData.value)) const deviceTotal = computed(() => deviceList.value.length) const deviceOnline = computed(() => deviceList.value.filter((d) => !!d.online).length) +const customerNodeTotal = computed(() => { + let total = 0 + const walk = (nodes: TreeNode[]) => { + nodes.forEach((node) => { + if (Number(node.nodeType) === 1) total += 1 + if (node.children?.length) walk(node.children) + }) + } + walk(treeData.value) + return total +}) +const deviceNodeTotal = computed(() => { + let total = 0 + const walk = (nodes: TreeNode[]) => { + nodes.forEach((node) => { + if (Number(node.nodeType) === 4) total += 1 + if (node.children?.length) walk(node.children) + }) + } + walk(treeData.value) + return total +}) const filterTreeNode = (value: string, data: TreeNode) => { if (!value) return true @@ -610,7 +577,7 @@ const getNodeTypeLabel = (nodeType?: number | string) => { if (value === 2) return '车间' if (value === 3) return '产线' if (value === 4) return '设备' - return '组织' + return '客户' } const getNodeTypeClass = (nodeType?: number | string) => { @@ -745,6 +712,15 @@ const getTreeData = async () => { } } +const refreshTreeData = async () => { + treeRefreshing.value = true + try { + await getTreeData() + } finally { + treeRefreshing.value = false + } +} + const getDefaultParentNode = () => { if (selectedNode.value && Number(selectedNode.value.nodeType) !== 4) return selectedNode.value const device = @@ -1377,4 +1353,23 @@ watch([() => activeTab.value, () => selectedDeviceDetail.value.id], ([tab, devic border-radius: 4px; font-family: monospace; } +.left-panel__stats { + display: flex; + gap: 12px; + margin-bottom: 16px; + align-items: center; + .stat-item { + background-color: var(--el-fill-color-light); + padding: 6px 12px; + border-radius: 6px; + font-size: 12px; + color: var(--el-text-color-secondary); + display: flex; + align-items: center; + gap: 6px; + } + .stat-refresh-btn { + margin-left: auto; + } +} diff --git a/src/views/iot/map/components/DeviceMap.vue b/src/views/iot/map/components/DeviceMap.vue new file mode 100644 index 0000000..a2d5a3e --- /dev/null +++ b/src/views/iot/map/components/DeviceMap.vue @@ -0,0 +1,254 @@ + + + + + diff --git a/src/views/iot/map/index.vue b/src/views/iot/map/index.vue new file mode 100644 index 0000000..89e231b --- /dev/null +++ b/src/views/iot/map/index.vue @@ -0,0 +1,615 @@ + + + + +