Przeglądaj źródła

Merge branch 'master' of http://39.97.59.228:8013/hrx/hsq-pro

hongrunxia 5 dni temu
rodzic
commit
d3d88faa65
31 zmienionych plików z 2515 dodań i 619 usunięć
  1. 20 15
      LongList.vue
  2. 1 2
      package.json
  3. 419 12
      pnpm-lock.yaml
  4. BIN
      src/assets/images/home-container/configurable/hsq/4-1bg.png
  5. BIN
      src/assets/images/home-container/configurable/hsq/4-2.png
  6. BIN
      src/assets/images/home-container/configurable/hsq/4-3.png
  7. 9 0
      src/assets/images/home-container/configurable/hsq/4-cf.svg
  8. 9 0
      src/assets/images/home-container/configurable/hsq/4-jy.svg
  9. 9 0
      src/assets/images/home-container/configurable/hsq/4-qy.svg
  10. 14 0
      src/assets/images/home-container/configurable/hsq/4-total.svg
  11. 3 0
      src/assets/images/home-container/configurable/hsq/arrow.svg
  12. BIN
      src/assets/images/home-container/configurable/hsq/bjcf.png
  13. BIN
      src/assets/images/home-container/configurable/hsq/czgz.png
  14. BIN
      src/assets/images/home-container/configurable/hsq/jlrz.png
  15. BIN
      src/assets/images/home-container/configurable/hsq/tjpd.png
  16. BIN
      src/assets/images/home-container/configurable/hsq/zxdz.png
  17. 78 78
      src/views/vent/home/configurable/components/ModuleCommonHsq.vue
  18. 347 331
      src/views/vent/home/configurable/components/content.vue
  19. 56 59
      src/views/vent/home/configurable/components/preset/RuleList.vue
  20. 243 0
      src/views/vent/home/configurable/components/preset/linkLog.vue
  21. 528 0
      src/views/vent/home/configurable/components/preset/linkRuleEdit.vue
  22. 149 0
      src/views/vent/home/configurable/components/preset/ruleNum.vue
  23. 191 0
      src/views/vent/home/configurable/components/preset/ruleTable.vue
  24. 216 11
      src/views/vent/home/configurable/configurable.data.ts
  25. 24 23
      src/views/vent/home/configurable/deviceManger.vue
  26. 22 19
      src/views/vent/home/configurable/fireMonitor.vue
  27. 17 18
      src/views/vent/home/configurable/gasInjection.vue
  28. 101 0
      src/views/vent/home/configurable/linkConfiguration.vue
  29. 32 25
      src/views/vent/home/configurable/systemManger.vue
  30. 26 25
      src/views/vent/home/configurable/warnMonitor.vue
  31. 1 1
      tsconfig.json

+ 20 - 15
src/views/vent/home/configurable/components/preset/LongList.vue → LongList.vue

@@ -2,7 +2,7 @@
   <div class="long-list">
   <div class="long-list">
     <div class="list-title">
     <div class="list-title">
       <span>设备列表</span>
       <span>设备列表</span>
-      <span style="margin-left: 5px;">{{ count }}</span>
+      <span style="margin-left: 5px">{{ count }}</span>
     </div>
     </div>
     <div class="list-content">
     <div class="list-content">
       <div class="list-search">
       <div class="list-search">
@@ -10,28 +10,32 @@
       </div>
       </div>
       <div class="content-container">
       <div class="content-container">
         <div class="content-nav">
         <div class="content-nav">
-          <div :class="activeIndex == index ? 'nav-item-active' : 'nav-item'" v-for="(item, index) in navList"
-            :key="index" @click="changeNav(item, index)">{{ item.label }}</div>
+          <div
+            :class="activeIndex == index ? 'nav-item-active' : 'nav-item'"
+            v-for="(item, index) in navList"
+            :key="index"
+            @click="changeNav(item, index)"
+            >{{ item.label }}</div
+          >
         </div>
         </div>
         <div class="content-box">
         <div class="content-box">
-          <basicDevice v-for="(item,index) in 10" :key="index"></basicDevice>
+          <basicDevice v-for="(item, index) in 10" :key="index"></basicDevice>
         </div>
         </div>
       </div>
       </div>
     </div>
     </div>
-
   </div>
   </div>
 </template>
 </template>
 
 
 <script setup lang="ts">
 <script setup lang="ts">
-import { ref } from 'vue'
-import basicDevice from '../basicDevice.vue'
+import { ref } from 'vue';
+import basicDevice from './src/views/vent/home/configurable/components/basicDevice.vue';
 
 
 //设备列表数量
 //设备列表数量
-let count = ref(0)
+let count = ref(0);
 //搜索条件
 //搜索条件
-let searchData = ref('')
+let searchData = ref('');
 //当前激活nav选项
 //当前激活nav选项
-let activeIndex = ref(0)
+let activeIndex = ref(0);
 let navList = ref<any[]>([
 let navList = ref<any[]>([
   { label: '全部', value: '0' },
   { label: '全部', value: '0' },
   { label: 'xxx', value: '1' },
   { label: 'xxx', value: '1' },
@@ -39,11 +43,11 @@ let navList = ref<any[]>([
   { label: 'xxx', value: '3' },
   { label: 'xxx', value: '3' },
   { label: 'xxx', value: '4' },
   { label: 'xxx', value: '4' },
   { label: 'xxx', value: '5' },
   { label: 'xxx', value: '5' },
-])
+]);
 
 
 //nav选项切换
 //nav选项切换
 function changeNav(item, index) {
 function changeNav(item, index) {
-  activeIndex.value = index
+  activeIndex.value = index;
 }
 }
 </script>
 </script>
 
 
@@ -51,7 +55,8 @@ function changeNav(item, index) {
 @import '/@/design/theme.less';
 @import '/@/design/theme.less';
 
 
 @{theme-deepblue} {
 @{theme-deepblue} {
-  .long-list {}
+  .long-list {
+  }
 }
 }
 
 
 .long-list {
 .long-list {
@@ -118,7 +123,7 @@ function changeNav(item, index) {
     background-color: #1d73a8;
     background-color: #1d73a8;
     border-bottom: 2px solid #36c7ff;
     border-bottom: 2px solid #36c7ff;
   }
   }
-  .content-box{
+  .content-box {
     height: calc(100% - 42px);
     height: calc(100% - 42px);
     overflow-y: auto;
     overflow-y: auto;
   }
   }
@@ -135,7 +140,7 @@ function changeNav(item, index) {
   .zxm-input-sm {
   .zxm-input-sm {
     padding: 0px 20px;
     padding: 0px 20px;
   }
   }
-  ::-webkit-scrollbar{
+  ::-webkit-scrollbar {
     display: none;
     display: none;
   }
   }
 }
 }

+ 1 - 2
package.json

@@ -219,6 +219,5 @@
         "three/examples/jsm/postprocessing/UnrealBloomPass.js"
         "three/examples/jsm/postprocessing/UnrealBloomPass.js"
       ]
       ]
     }
     }
-  },
-  "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
+  }
 }
 }

+ 419 - 12
pnpm-lock.yaml

@@ -53,6 +53,9 @@ importers:
       '@vueuse/shared':
       '@vueuse/shared':
         specifier: ^10.4.1
         specifier: ^10.4.1
         version: 10.11.1(vue@3.5.24(typescript@4.9.5))
         version: 10.11.1(vue@3.5.24(typescript@4.9.5))
+      '@x-viewer/core':
+        specifier: ^0.21.23
+        version: 0.21.23
       '@zxcvbn-ts/core':
       '@zxcvbn-ts/core':
         specifier: ^3.0.3
         specifier: ^3.0.3
         version: 3.0.4
         version: 3.0.4
@@ -87,8 +90,8 @@ importers:
         specifier: ^7.8.5
         specifier: ^7.8.5
         version: 7.9.0
         version: 7.9.0
       dayjs:
       dayjs:
-        specifier: ^1.11.9
-        version: 1.11.19
+        specifier: ^1.11.20
+        version: 1.11.21
       dexie:
       dexie:
         specifier: ^3.2.2
         specifier: ^3.2.2
         version: 3.2.7
         version: 3.2.7
@@ -144,7 +147,7 @@ importers:
         specifier: ^1.1.0
         specifier: ^1.1.0
         version: 1.1.0
         version: 1.1.0
       moment:
       moment:
-        specifier: ^2.29.4
+        specifier: ^2.30.1
         version: 2.30.1
         version: 2.30.1
       nprogress:
       nprogress:
         specifier: ^0.2.0
         specifier: ^0.2.0
@@ -519,6 +522,20 @@ importers:
 
 
 packages:
 packages:
 
 
+  2d-polygon-area@1.0.0:
+    resolution: {integrity: sha512-CAjFfFDX+a7qvr6qA8Cvn9HYOZM/nktEDQzSNZRzvH0rd9L/JHp+xXc1iAppVkUIqz4+bqRDArk8coVdirtNHA==}
+
+  2d-polygon-boolean@1.0.1:
+    resolution: {integrity: sha512-MCOjlgnRtBq3uOf5IO1aOW9izttFHjQXETYjEQIa3bbdwtdBjc0eiAOuxPfve6gHOr6JrcRm+s/+uyCmkYN5gQ==}
+
+  2d-polygon-self-intersections@1.3.1:
+    resolution: {integrity: sha512-5zBVP8+aN8T88FyZ4SD9WR/5lAASlLKSS6NCZYQR7aHwwHjXtBsF0Gpcq2a3S+jpMLxa+ct1iYWxGNo2kLcz+w==}
+
+  3d-tiles-renderer@0.3.32:
+    resolution: {integrity: sha512-QM8j7UDH22rS6ibyyz1g5vJl9d3FSBMPXU8oNOl8OHVkQKeQ8eFWkrtJ3dJ7mD8GBxj8IfZWPzXmXi0MmzUHew==}
+    peerDependencies:
+      three: '>=0.123.0'
+
   '@aesoper/normal-utils@0.1.5':
   '@aesoper/normal-utils@0.1.5':
     resolution: {integrity: sha512-LFF/6y6h5mfwhnJaWqqxuC8zzDaHCG62kMRkd8xhDtq62TQj9dM17A9DhE87W7DhiARJsHLgcina/9P4eNCN1w==}
     resolution: {integrity: sha512-LFF/6y6h5mfwhnJaWqqxuC8zzDaHCG62kMRkd8xhDtq62TQj9dM17A9DhE87W7DhiARJsHLgcina/9P4eNCN1w==}
 
 
@@ -1820,6 +1837,9 @@ packages:
   '@logicflow/extension@1.2.28':
   '@logicflow/extension@1.2.28':
     resolution: {integrity: sha512-OHaO57SxjNwDDYVAqrJp/fq9g0NDc4elHmZnWGIqLbkbOMJhiU9IUT2WWK6DctUoYzxhGzTR4Ai5S/TFZ9JjGA==}
     resolution: {integrity: sha512-OHaO57SxjNwDDYVAqrJp/fq9g0NDc4elHmZnWGIqLbkbOMJhiU9IUT2WWK6DctUoYzxhGzTR4Ai5S/TFZ9JjGA==}
 
 
+  '@mlightcad/libredwg-web@0.7.2':
+    resolution: {integrity: sha512-MPbVtnuUokzvCS4pdibiNw7PLdnSJo9R1pZcBnzRCyzWQqMHuZOxLVwtsV9aGk1SBmJ2186Hbu3Umt2B7hFS4Q==}
+
   '@nodelib/fs.scandir@2.1.5':
   '@nodelib/fs.scandir@2.1.5':
     resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
     resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
     engines: {node: '>= 8'}
     engines: {node: '>= 8'}
@@ -1849,6 +1869,33 @@ packages:
   '@popperjs/core@2.11.8':
   '@popperjs/core@2.11.8':
     resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==}
     resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==}
 
 
+  '@protobufjs/aspromise@1.1.2':
+    resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==}
+
+  '@protobufjs/base64@1.1.2':
+    resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==}
+
+  '@protobufjs/codegen@2.0.5':
+    resolution: {integrity: sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==}
+
+  '@protobufjs/eventemitter@1.1.1':
+    resolution: {integrity: sha512-vW1GmwMZNnL+gMRaovlh9yZX74kc+TTU3FObkkurpMaRtBfLP3ldjS9KQWlwZgraRE0+dheEEoAxdzcJQ8eXZg==}
+
+  '@protobufjs/fetch@1.1.1':
+    resolution: {integrity: sha512-GpptLrs57adMSuHi3VNj0mAF8dwh36LMaYF6XyJ6JMWlVsc+t42tm1HSEDmOs3A8fC9yyeisgLhsTVQokOZ0zw==}
+
+  '@protobufjs/float@1.0.2':
+    resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==}
+
+  '@protobufjs/path@1.1.2':
+    resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==}
+
+  '@protobufjs/pool@1.1.0':
+    resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==}
+
+  '@protobufjs/utf8@1.1.1':
+    resolution: {integrity: sha512-oOAWABowe8EAbMyWKM0tYDKi8Yaox52D+HWZhAIJqQXbqe0xI/GV7FhLWqlEKreMkfDjshR5FKgi3mnle0h6Eg==}
+
   '@purge-icons/core@0.9.1':
   '@purge-icons/core@0.9.1':
     resolution: {integrity: sha512-sx8/a30MbbqQVEqhuMPE1wJpdVRRbEmwEPZpFzVkcDixzX4p+R2A0WVxqkb0xfHUBAVQwrSE2SeAyniIQLqbLw==}
     resolution: {integrity: sha512-sx8/a30MbbqQVEqhuMPE1wJpdVRRbEmwEPZpFzVkcDixzX4p+R2A0WVxqkb0xfHUBAVQwrSE2SeAyniIQLqbLw==}
 
 
@@ -1926,28 +1973,24 @@ packages:
     engines: {node: '>=10'}
     engines: {node: '>=10'}
     cpu: [arm64]
     cpu: [arm64]
     os: [linux]
     os: [linux]
-    libc: [glibc]
 
 
   '@swc/core-linux-arm64-musl@1.15.2':
   '@swc/core-linux-arm64-musl@1.15.2':
     resolution: {integrity: sha512-5av6VYZZeneiYIodwzGMlnyVakpuYZryGzFIbgu1XP8wVylZxduEzup4eP8atiMDFmIm+s4wn8GySJmYqeJC0A==}
     resolution: {integrity: sha512-5av6VYZZeneiYIodwzGMlnyVakpuYZryGzFIbgu1XP8wVylZxduEzup4eP8atiMDFmIm+s4wn8GySJmYqeJC0A==}
     engines: {node: '>=10'}
     engines: {node: '>=10'}
     cpu: [arm64]
     cpu: [arm64]
     os: [linux]
     os: [linux]
-    libc: [musl]
 
 
   '@swc/core-linux-x64-gnu@1.15.2':
   '@swc/core-linux-x64-gnu@1.15.2':
     resolution: {integrity: sha512-1nO/UfdCLuT/uE/7oB3EZgTeZDCIa6nL72cFEpdegnqpJVNDI6Qb8U4g/4lfVPkmHq2lvxQ0L+n+JdgaZLhrRA==}
     resolution: {integrity: sha512-1nO/UfdCLuT/uE/7oB3EZgTeZDCIa6nL72cFEpdegnqpJVNDI6Qb8U4g/4lfVPkmHq2lvxQ0L+n+JdgaZLhrRA==}
     engines: {node: '>=10'}
     engines: {node: '>=10'}
     cpu: [x64]
     cpu: [x64]
     os: [linux]
     os: [linux]
-    libc: [glibc]
 
 
   '@swc/core-linux-x64-musl@1.15.2':
   '@swc/core-linux-x64-musl@1.15.2':
     resolution: {integrity: sha512-Ksfrb0Tx310kr+TLiUOvB/I80lyZ3lSOp6cM18zmNRT/92NB4mW8oX2Jo7K4eVEI2JWyaQUAFubDSha2Q+439A==}
     resolution: {integrity: sha512-Ksfrb0Tx310kr+TLiUOvB/I80lyZ3lSOp6cM18zmNRT/92NB4mW8oX2Jo7K4eVEI2JWyaQUAFubDSha2Q+439A==}
     engines: {node: '>=10'}
     engines: {node: '>=10'}
     cpu: [x64]
     cpu: [x64]
     os: [linux]
     os: [linux]
-    libc: [musl]
 
 
   '@swc/core-win32-arm64-msvc@1.15.2':
   '@swc/core-win32-arm64-msvc@1.15.2':
     resolution: {integrity: sha512-IzUb5RlMUY0r1A9IuJrQ7Tbts1wWb73/zXVXT8VhewbHGoNlBKE0qUhKMED6Tv4wDF+pmbtUJmKXDthytAvLmg==}
     resolution: {integrity: sha512-IzUb5RlMUY0r1A9IuJrQ7Tbts1wWb73/zXVXT8VhewbHGoNlBKE0qUhKMED6Tv4wDF+pmbtUJmKXDthytAvLmg==}
@@ -2482,6 +2525,9 @@ packages:
       vue:
       vue:
         optional: true
         optional: true
 
 
+  '@x-viewer/core@0.21.23':
+    resolution: {integrity: sha512-I6TILvUHmGzxOFi5P2HMZtUaiF1rnXgoai+2w7nw2dMI0jnzvA432ItEkWJCXJ4PUUhoFFoQ1XVRY+SR6jDynQ==}
+
   '@xmldom/xmldom@0.8.11':
   '@xmldom/xmldom@0.8.11':
     resolution: {integrity: sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw==}
     resolution: {integrity: sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw==}
     engines: {node: '>=10.0.0'}
     engines: {node: '>=10.0.0'}
@@ -2814,6 +2860,9 @@ packages:
     resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
     resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
     engines: {node: '>=8'}
     engines: {node: '>=8'}
 
 
+  binary-search-bounds@2.0.5:
+    resolution: {integrity: sha512-H0ea4Fd3lS1+sTEB2TgcLoK21lLhwEJzlQv3IN47pJS976Gx4zoWe0ak3q+uYh60ppQxg9F16Ri4tS1sfD4+jA==}
+
   bl@4.1.0:
   bl@4.1.0:
     resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==}
     resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==}
 
 
@@ -2915,6 +2964,11 @@ packages:
     resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==}
     resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==}
     engines: {node: '>=10'}
     engines: {node: '>=10'}
 
 
+  camera-controls@1.38.2:
+    resolution: {integrity: sha512-EfzbovxLssyWpJVG9uKcazSDDIEcd1hUsPhPF/OWWnICsKY9WbLY/2S4UPW73HHbvnVeR/Z9wsWaQKtANy/2Yg==}
+    peerDependencies:
+      three: '>=0.126.1'
+
   caniuse-lite@1.0.30001755:
   caniuse-lite@1.0.30001755:
     resolution: {integrity: sha512-44V+Jm6ctPj7R52Na4TLi3Zri4dWUljJd+RDm+j8LtNCc/ihLCT+X1TzoOAkRETEWqjuLnh9581Tl80FvK7jVA==}
     resolution: {integrity: sha512-44V+Jm6ctPj7R52Na4TLi3Zri4dWUljJd+RDm+j8LtNCc/ihLCT+X1TzoOAkRETEWqjuLnh9581Tl80FvK7jVA==}
 
 
@@ -3020,6 +3074,9 @@ packages:
   clipboard@2.0.11:
   clipboard@2.0.11:
     resolution: {integrity: sha512-C+0bbOqkezLIsmWSvlsXS0Q0bmkugu7jcfMIACB+RDEntIzQIkdr148we28AfSloQLRdZlYL/QYyrq05j/3Faw==}
     resolution: {integrity: sha512-C+0bbOqkezLIsmWSvlsXS0Q0bmkugu7jcfMIACB+RDEntIzQIkdr148we28AfSloQLRdZlYL/QYyrq05j/3Faw==}
 
 
+  clipper-lib@6.4.2:
+    resolution: {integrity: sha512-knglhjQX5ihNj/XCIs6zCHrTemdvHY3LPZP9XB2nq2/3igyYMFueFXtfp84baJvEE+f8pO1ZS4UVeEgmLnAprQ==}
+
   cliui@6.0.0:
   cliui@6.0.0:
     resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==}
     resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==}
 
 
@@ -3131,6 +3188,9 @@ packages:
     engines: {node: '>=0.10.0'}
     engines: {node: '>=0.10.0'}
     deprecated: 'WARNING: This package has been renamed to typed-array-concat.'
     deprecated: 'WARNING: This package has been renamed to typed-array-concat.'
 
 
+  concaveman@1.2.1:
+    resolution: {integrity: sha512-PwZYKaM/ckQSa8peP5JpVr7IMJ4Nn/MHIaWUjP4be+KoZ7Botgs8seAZGpmaOM+UZXawcdYRao/px9ycrCihHw==}
+
   confbox@0.1.8:
   confbox@0.1.8:
     resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==}
     resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==}
 
 
@@ -3568,8 +3628,8 @@ packages:
   dateformat@3.0.3:
   dateformat@3.0.3:
     resolution: {integrity: sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==}
     resolution: {integrity: sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==}
 
 
-  dayjs@1.11.19:
-    resolution: {integrity: sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==}
+  dayjs@1.11.21:
+    resolution: {integrity: sha512-98IT+HOahAisibz/yjKbzuOBwYcjJ7BCLPzARyHiyEBmRz4fatF+KPJszEHXsGYjUG234aH/cOjW1wwTbKUZlA==}
 
 
   de-indent@1.0.2:
   de-indent@1.0.2:
     resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==}
     resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==}
@@ -3806,6 +3866,9 @@ packages:
   duplexer@0.1.2:
   duplexer@0.1.2:
     resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==}
     resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==}
 
 
+  earcut@2.2.4:
+    resolution: {integrity: sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ==}
+
   eastasianwidth@0.2.0:
   eastasianwidth@0.2.0:
     resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
     resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
 
 
@@ -3847,6 +3910,9 @@ packages:
   element-resize-detector@1.2.4:
   element-resize-detector@1.2.4:
     resolution: {integrity: sha512-Fl5Ftk6WwXE0wqCgNoseKWndjzZlDCwuPTcoVZfCP9R3EHQF8qUtr3YUPNETegRBOKqQKPW3n4kiIWngGi8tKg==}
     resolution: {integrity: sha512-Fl5Ftk6WwXE0wqCgNoseKWndjzZlDCwuPTcoVZfCP9R3EHQF8qUtr3YUPNETegRBOKqQKPW3n4kiIWngGi8tKg==}
 
 
+  emitter-component@1.1.2:
+    resolution: {integrity: sha512-QdXO3nXOzZB4pAjM0n6ZE+R9/+kPpECA/XSELIcc54NeYVnBqIk+4DFiBgK+8QbV3mdvTG6nedl7dTYgO+5wDw==}
+
   emittery@0.13.1:
   emittery@0.13.1:
     resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==}
     resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==}
     engines: {node: '>=12'}
     engines: {node: '>=12'}
@@ -4215,6 +4281,9 @@ packages:
   eventemitter3@5.0.1:
   eventemitter3@5.0.1:
     resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==}
     resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==}
 
 
+  exact-segment-intersect@2.0.0:
+    resolution: {integrity: sha512-Qq3Rt+PJkWnqo26QcNk5VKmdqYEgvGRhsfs/o0D4jGWJkrRjFDhC7CCRg7omXwOPcrHDOv0vKV0BrCVOdyz5Wg==}
+
   execa@4.1.0:
   execa@4.1.0:
     resolution: {integrity: sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==}
     resolution: {integrity: sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==}
     engines: {node: '>=10'}
     engines: {node: '>=10'}
@@ -4431,6 +4500,9 @@ packages:
     resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==}
     resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==}
     engines: {node: '>= 0.4'}
     engines: {node: '>= 0.4'}
 
 
+  functional-red-black-tree@1.0.1:
+    resolution: {integrity: sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==}
+
   functions-have-names@1.2.3:
   functions-have-names@1.2.3:
     resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==}
     resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==}
 
 
@@ -4743,6 +4815,9 @@ packages:
     engines: {node: '>=14'}
     engines: {node: '>=14'}
     hasBin: true
     hasBin: true
 
 
+  i18next@21.10.0:
+    resolution: {integrity: sha512-YeuIBmFsGjUfO3qBmMOc0rQaun4mIpGKET5WDwvu8lU7gvwpcariZLNtL0Fzj+zazcHUrlXHiptcFhBMFaxzfg==}
+
   iconv-lite@0.4.24:
   iconv-lite@0.4.24:
     resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==}
     resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==}
     engines: {node: '>=0.10.0'}
     engines: {node: '>=0.10.0'}
@@ -4828,6 +4903,9 @@ packages:
     resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==}
     resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==}
     engines: {node: '>=12'}
     engines: {node: '>=12'}
 
 
+  intl-pluralrules@1.3.1:
+    resolution: {integrity: sha512-sNYPls1Q4fyN0EGLFVJ7TIuaMWln01LupLozfIBt69rHK0DHehghMSz6ejfnSklgRddnyQSEaQPIU6d9TCKH3w==}
+
   intro.js@7.2.0:
   intro.js@7.2.0:
     resolution: {integrity: sha512-qbMfaB70rOXVBceIWNYnYTpVTiZsvQh/MIkfdQbpA9di9VBfj1GigUPfcCv3aOfsbrtPcri8vTLTA4FcEDcHSQ==}
     resolution: {integrity: sha512-qbMfaB70rOXVBceIWNYnYTpVTiZsvQh/MIkfdQbpA9di9VBfj1GigUPfcCv3aOfsbrtPcri8vTLTA4FcEDcHSQ==}
 
 
@@ -5375,6 +5453,9 @@ packages:
   js-base64@2.6.4:
   js-base64@2.6.4:
     resolution: {integrity: sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==}
     resolution: {integrity: sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==}
 
 
+  js-base64@3.7.8:
+    resolution: {integrity: sha512-hNngCeKxIUQiEUN3GPJOkz4wF/YvdUdbNL9hsBcMQTkKzboD7T/q3OYOuuPZLUE6dBxSGpwhk5mwuDud7JVAow==}
+
   js-beautify@1.15.4:
   js-beautify@1.15.4:
     resolution: {integrity: sha512-9/KXeZUKKJwqCXUdBxFJ3vPh467OCckSBmYDwSK/EtV090K+iMJ7zx2S3HLVDIWFQdqMIsZWbnaGiba18aWhaA==}
     resolution: {integrity: sha512-9/KXeZUKKJwqCXUdBxFJ3vPh467OCckSBmYDwSK/EtV090K+iMJ7zx2S3HLVDIWFQdqMIsZWbnaGiba18aWhaA==}
     engines: {node: '>=14'}
     engines: {node: '>=14'}
@@ -5398,6 +5479,9 @@ packages:
     resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==}
     resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==}
     hasBin: true
     hasBin: true
 
 
+  jsbi@4.3.2:
+    resolution: {integrity: sha512-9fqMSQbhJykSeii05nxKl4m6Eqn2P6rOlYiS+C5Dr/HPIU/7yZxu5qzbs40tgaFORiw2Amd0mirjxatXYMkIew==}
+
   jsdom@16.7.0:
   jsdom@16.7.0:
     resolution: {integrity: sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==}
     resolution: {integrity: sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==}
     engines: {node: '>=10'}
     engines: {node: '>=10'}
@@ -5609,6 +5693,13 @@ packages:
     resolution: {integrity: sha512-5UtUDQ/6edw4ofyljDNcOVJQ4c7OjDro4h3y8e1GQL5iYElYclVHJ3zeWchylvMaKnDbDilC8irOVyexnA/Slw==}
     resolution: {integrity: sha512-5UtUDQ/6edw4ofyljDNcOVJQ4c7OjDro4h3y8e1GQL5iYElYclVHJ3zeWchylvMaKnDbDilC8irOVyexnA/Slw==}
     engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
     engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
 
 
+  loglevel@1.9.2:
+    resolution: {integrity: sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==}
+    engines: {node: '>= 0.6.0'}
+
+  long@5.3.2:
+    resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==}
+
   longest@2.0.1:
   longest@2.0.1:
     resolution: {integrity: sha512-Ajzxb8CM6WAnFjgiloPsI3bF+WCxcvhdIG3KNA2KN962+tdBsHcuQ4k4qX/EcS/2CRkcc0iAkR956Nib6aXU/Q==}
     resolution: {integrity: sha512-Ajzxb8CM6WAnFjgiloPsI3bF+WCxcvhdIG3KNA2KN962+tdBsHcuQ4k4qX/EcS/2CRkcc0iAkR956Nib6aXU/Q==}
     engines: {node: '>=0.10.0'}
     engines: {node: '>=0.10.0'}
@@ -6015,6 +6106,11 @@ packages:
     resolution: {integrity: sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==}
     resolution: {integrity: sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==}
     hasBin: true
     hasBin: true
 
 
+  opentype.js@1.3.4:
+    resolution: {integrity: sha512-d2JE9RP/6uagpQAVtJoF0pJJA/fgai89Cc50Yp0EJHk+eLp6QQ7gBoblsnubRULNY132I0J1QKMJ+JTbMqz4sw==}
+    engines: {node: '>= 8.0.0'}
+    hasBin: true
+
   optionator@0.9.4:
   optionator@0.9.4:
     resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
     resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
     engines: {node: '>= 0.8.0'}
     engines: {node: '>= 0.8.0'}
@@ -6069,6 +6165,9 @@ packages:
   package-manager-detector@1.5.0:
   package-manager-detector@1.5.0:
     resolution: {integrity: sha512-uBj69dVlYe/+wxj8JOpr97XfsxH/eumMt6HqjNTmJDf/6NO9s+0uxeOneIz3AsPt2m6y9PqzDzd3ATcU17MNfw==}
     resolution: {integrity: sha512-uBj69dVlYe/+wxj8JOpr97XfsxH/eumMt6HqjNTmJDf/6NO9s+0uxeOneIz3AsPt2m6y9PqzDzd3ATcU17MNfw==}
 
 
+  pako@2.1.0:
+    resolution: {integrity: sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==}
+
   param-case@3.0.4:
   param-case@3.0.4:
     resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==}
     resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==}
 
 
@@ -6243,6 +6342,21 @@ packages:
     resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==}
     resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==}
     engines: {node: '>=10.13.0'}
     engines: {node: '>=10.13.0'}
 
 
+  point-in-big-polygon@1.0.0:
+    resolution: {integrity: sha512-4ndmlqCakU2K3hskeJpgMp10RJubHfDbdhJpk09cwTLs5eHVDurq8etTSI5x5ITVKLIpHRLkAhaMHXsV7nluqw==}
+
+  point-in-polygon@1.1.0:
+    resolution: {integrity: sha512-3ojrFwjnnw8Q9242TzgXuTD+eKiutbzyslcq1ydfu82Db2y+Ogbmyrkpv0Hgj31qwT3lbS9+QAAO/pIQM35XRw==}
+
+  poly-extrude@0.2.0:
+    resolution: {integrity: sha512-Lt3wIDk4adSooYNZQMvyzjw52S1M2Dhs0XAfzpdWBu0aWGkoy558EQX9iTRq39aX0tAK2kI/gDm1yhGfdntYag==}
+
+  polybooljs@1.2.2:
+    resolution: {integrity: sha512-ziHW/02J0XuNuUtmidBc6GXE8YohYydp3DWPWXYsd7O721TjcmN+k6ezjdwkDqep+gnWnFY+yqZHvzElra2oCg==}
+
+  polygon-clipping@0.15.7:
+    resolution: {integrity: sha512-nhfdr83ECBg6xtqOAJab1tbksbBAOMUltN60bU+llHVOL0e5Onm1WpAXXWXVB39L8AJFssoIhEVuy/S90MmotA==}
+
   portfinder@1.0.38:
   portfinder@1.0.38:
     resolution: {integrity: sha512-rEwq/ZHlJIKw++XtLAO8PPuOQA/zaPJOZJ37BVuN97nLpMJeuDVLVGRwbFoBgLudgdTMP2hdRJP++H+8QOA3vg==}
     resolution: {integrity: sha512-rEwq/ZHlJIKw++XtLAO8PPuOQA/zaPJOZJ37BVuN97nLpMJeuDVLVGRwbFoBgLudgdTMP2hdRJP++H+8QOA3vg==}
     engines: {node: '>= 10.12'}
     engines: {node: '>= 10.12'}
@@ -6369,6 +6483,10 @@ packages:
   proto-list@1.2.4:
   proto-list@1.2.4:
     resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==}
     resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==}
 
 
+  protobufjs@7.6.4:
+    resolution: {integrity: sha512-RJJPTTpvFfHcWLkIa2JFWK4XvtSzS0yEWDmunqHXli1h3JlkbcQZXDZdcWxv+JK3Xsl5/UFDPZ0iGm7DAengYw==}
+    engines: {node: '>=12.0.0'}
+
   proxy-from-env@1.1.0:
   proxy-from-env@1.1.0:
     resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
     resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
 
 
@@ -6424,12 +6542,18 @@ packages:
     resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==}
     resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==}
     engines: {node: '>=10'}
     engines: {node: '>=10'}
 
 
+  quickselect@2.0.0:
+    resolution: {integrity: sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw==}
+
   raf@3.4.1:
   raf@3.4.1:
     resolution: {integrity: sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==}
     resolution: {integrity: sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==}
 
 
   rangetouch@2.0.1:
   rangetouch@2.0.1:
     resolution: {integrity: sha512-sln+pNSc8NGaHoLzwNBssFSf/rSYkqeBXzX1AtJlkJiUaVSJSbRAWJk+4omsXkN+EJalzkZhWQ3th1m0FpR5xA==}
     resolution: {integrity: sha512-sln+pNSc8NGaHoLzwNBssFSf/rSYkqeBXzX1AtJlkJiUaVSJSbRAWJk+4omsXkN+EJalzkZhWQ3th1m0FpR5xA==}
 
 
+  rbush@3.0.1:
+    resolution: {integrity: sha512-XRaVO0YecOpEuIvbhbpTrZgoiI6xBlz6hnlr6EHhd+0x9ase6EmeN+hdwwUaJvLcsFFQ8iWVF1GAK1yB0BWi0w==}
+
   react-is@17.0.2:
   react-is@17.0.2:
     resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==}
     resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==}
 
 
@@ -6616,9 +6740,33 @@ packages:
     resolution: {integrity: sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==}
     resolution: {integrity: sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==}
     hasBin: true
     hasBin: true
 
 
+  robust-compress@1.0.0:
+    resolution: {integrity: sha512-E8btSpQ6zZr7LvRLrLvb+N5rwQ0etUbsXFKv5NQj6TVK6RYT00Qg9iVFvIWR+GxXUvpes7FDN0WfXa3l7wtGOw==}
+
+  robust-estimate-float@1.0.0:
+    resolution: {integrity: sha512-TsNo0eQen8Lt1bqo1Jh1rlz88iejZV57zKAmFzbOem9eQxQnOj3yWdX0e2bLHGu9TJRieyzLG2mN94WQwOsZ1w==}
+
+  robust-orientation@1.2.1:
+    resolution: {integrity: sha512-FuTptgKwY6iNuU15nrIJDLjXzCChWB+T4AvksRtwPS/WZ3HuP1CElCm1t+OBfgQKfWbtZIawip+61k7+buRKAg==}
+
+  robust-predicates@2.0.4:
+    resolution: {integrity: sha512-l4NwboJM74Ilm4VKfbAtFeGq7aEjWL+5kVFcmgFA2MrdnQWx9iE/tUGvxY5HyMI7o/WpSIUFLbC5fbeaHgSCYg==}
+
   robust-predicates@3.0.2:
   robust-predicates@3.0.2:
     resolution: {integrity: sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==}
     resolution: {integrity: sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==}
 
 
+  robust-scale@1.0.2:
+    resolution: {integrity: sha512-jBR91a/vomMAzazwpsPTPeuTPPmWBacwA+WYGNKcRGSh6xweuQ2ZbjRZ4v792/bZOhRKXRiQH0F48AvuajY0tQ==}
+
+  robust-segment-intersect@1.0.1:
+    resolution: {integrity: sha512-QWngxcL7rCRLK7nTMcTNBPi/q+fecrOo6aOtTPnXjT/Dve5AK20DzUSq2fznUS+rCAxyir6OdPgDCzcUxFtJoQ==}
+
+  robust-subtract@1.0.0:
+    resolution: {integrity: sha512-xhKUno+Rl+trmxAIVwjQMiVdpF5llxytozXJOdoT4eTIqmqsndQqFb1A0oiW3sZGlhMRhOi6pAD4MF1YYW6o/A==}
+
+  robust-sum@1.0.0:
+    resolution: {integrity: sha512-AvLExwpaqUqD1uwLU6MwzzfRdaI6VEZsyvQ3IAQ0ZJ08v1H+DTyqskrf2ZJyh0BDduFVLN7H04Zmc+qTiahhAw==}
+
   rollup-plugin-purge-icons@0.9.1:
   rollup-plugin-purge-icons@0.9.1:
     resolution: {integrity: sha512-hRDKBsPUz47UMdBufki2feTmBF2ClEJlYqL7N6vpVAHSLd7V2BJUaNKOF7YYbLMofVVF+9hm44YSkYO6k9hUgg==}
     resolution: {integrity: sha512-hRDKBsPUz47UMdBufki2feTmBF2ClEJlYqL7N6vpVAHSLd7V2BJUaNKOF7YYbLMofVVF+9hm44YSkYO6k9hUgg==}
     engines: {node: '>= 12'}
     engines: {node: '>= 12'}
@@ -6689,12 +6837,19 @@ packages:
     resolution: {integrity: sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==}
     resolution: {integrity: sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==}
     engines: {node: '>=10'}
     engines: {node: '>=10'}
 
 
+  screenfull@6.0.2:
+    resolution: {integrity: sha512-AQdy8s4WhNvUZ6P8F6PB21tSPIYKniic+Ogx0AacBMjKP1GUHN2E9URxQHtCusiwxudnCKkdy4GrHXPPJSkCCw==}
+    engines: {node: ^14.13.1 || >=16.0.0}
+
   scroll-into-view-if-needed@2.2.31:
   scroll-into-view-if-needed@2.2.31:
     resolution: {integrity: sha512-dGCXy99wZQivjmjIqihaBQNjryrz5rueJY7eHfTdyWEiR4ttYpsajb14rn9s5d4DY4EcY6+4+U/maARBXJedkA==}
     resolution: {integrity: sha512-dGCXy99wZQivjmjIqihaBQNjryrz5rueJY7eHfTdyWEiR4ttYpsajb14rn9s5d4DY4EcY6+4+U/maARBXJedkA==}
 
 
   secure-compare@3.0.1:
   secure-compare@3.0.1:
     resolution: {integrity: sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==}
     resolution: {integrity: sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==}
 
 
+  segseg@0.2.2:
+    resolution: {integrity: sha512-eEJ61YUpiq60wmp+o2SlmS3swgSc66QLzAlLBBUoMeEld/eekmSM4k+2f5Q2vb4QeDYkO0QFp9XSKycUGjRBYQ==}
+
   select@1.1.2:
   select@1.1.2:
     resolution: {integrity: sha512-OwpTSOfy6xSs1+pwcNrv0RBMOzI39Lp3qQKUTPVVPRjCdNa5JH/oPRiqsesIskK8TVgmRiHwO4KXlV2Li9dANA==}
     resolution: {integrity: sha512-OwpTSOfy6xSs1+pwcNrv0RBMOzI39Lp3qQKUTPVVPRjCdNa5JH/oPRiqsesIskK8TVgmRiHwO4KXlV2Li9dANA==}
 
 
@@ -6788,6 +6943,9 @@ packages:
     resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
     resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
     engines: {node: '>=14'}
     engines: {node: '>=14'}
 
 
+  signum@1.0.0:
+    resolution: {integrity: sha512-yodFGwcyt59XRh7w5W3jPcIQb3Bwi21suEfT7MAWnBX3iCdklJpgDgvGT9o04UonglZN5SNMfJFkHIR/jO8GHw==}
+
   single-spa@5.9.5:
   single-spa@5.9.5:
     resolution: {integrity: sha512-9SQdmsyz4HSP+3gs6PJzhkaMEg+6zTlu9oxIghnwUX3eq+ajq4ft5egl0iyR55LAmO/UwvU8NgIWs/ZyQMa6dw==}
     resolution: {integrity: sha512-9SQdmsyz4HSP+3gs6PJzhkaMEg+6zTlu9oxIghnwUX3eq+ajq4ft5egl0iyR55LAmO/UwvU8NgIWs/ZyQMa6dw==}
 
 
@@ -6798,6 +6956,9 @@ packages:
   sisteransi@1.0.5:
   sisteransi@1.0.5:
     resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==}
     resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==}
 
 
+  slab-decomposition@1.0.3:
+    resolution: {integrity: sha512-1EfR304JHvX9vYQkUi4AKqN62mLsjk6W45xTk/TxwN8zd3HGwS7PVj9zj0I6fgCZqfGlimDEY+RzzASHn97ZmQ==}
+
   slash@3.0.0:
   slash@3.0.0:
     resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
     resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
     engines: {node: '>=8'}
     engines: {node: '>=8'}
@@ -6877,6 +7038,10 @@ packages:
   spdx-license-ids@3.0.22:
   spdx-license-ids@3.0.22:
     resolution: {integrity: sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==}
     resolution: {integrity: sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==}
 
 
+  splaytree@3.2.3:
+    resolution: {integrity: sha512-7OXrNWzy6CK+r7Ch9OLPBDTKfB6XlWHjX4P0RU5B3IgFuWPeYN0XtRtlexGRjgbQxpfaUve6jTAwBGWuGntz/w==}
+    engines: {node: '>=18.20 || >=20'}
+
   split-string@3.1.0:
   split-string@3.1.0:
     resolution: {integrity: sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==}
     resolution: {integrity: sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==}
     engines: {node: '>=0.10.0'}
     engines: {node: '>=0.10.0'}
@@ -6918,6 +7083,9 @@ packages:
     resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==}
     resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==}
     engines: {node: '>= 0.4'}
     engines: {node: '>= 0.4'}
 
 
+  stream@0.0.2:
+    resolution: {integrity: sha512-gCq3NDI2P35B2n6t76YJuOp7d6cN/C7Rt0577l91wllh0sY9ZBuw9KaSGqH/b0hzn3CWWJbpbW0W0WvQ1H/Q7g==}
+
   strict-uri-encode@1.1.0:
   strict-uri-encode@1.1.0:
     resolution: {integrity: sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==}
     resolution: {integrity: sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==}
     engines: {node: '>=0.10.0'}
     engines: {node: '>=0.10.0'}
@@ -6938,6 +7106,9 @@ packages:
     resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
     resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
     engines: {node: '>=12'}
     engines: {node: '>=12'}
 
 
+  string.prototype.codepointat@0.2.1:
+    resolution: {integrity: sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg==}
+
   string.prototype.padend@3.1.6:
   string.prototype.padend@3.1.6:
     resolution: {integrity: sha512-XZpspuSB7vJWhvJc9DLSlrXl1mcA2BdoY5jjnS135ydXqLoqhs96JjDtCkjJEQHvfqZIp9hBuBMgI589peyx9Q==}
     resolution: {integrity: sha512-XZpspuSB7vJWhvJc9DLSlrXl1mcA2BdoY5jjnS135ydXqLoqhs96JjDtCkjJEQHvfqZIp9hBuBMgI589peyx9Q==}
     engines: {node: '>= 0.4'}
     engines: {node: '>= 0.4'}
@@ -7138,6 +7309,11 @@ packages:
   text-table@0.2.0:
   text-table@0.2.0:
     resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
     resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
 
 
+  three-mesh-bvh@0.9.10:
+    resolution: {integrity: sha512-UOlTgPIeqUURcwaG8knxvBaruwZlC4X3/WSHEFO7rYvMVv/YNUrkfFEszvfj36pXV88dCHoHNnIp0PifkirnTQ==}
+    peerDependencies:
+      three: '>= 0.159.0'
+
   three.path@1.0.1:
   three.path@1.0.1:
     resolution: {integrity: sha512-YZGPv75s65V0JMCPqG+DBq72YEb7bzQES3lFWggjoJZ9zbTd/f5ukN+yolIqIkQTm9FWelQ367VhbMihQUq59Q==}
     resolution: {integrity: sha512-YZGPv75s65V0JMCPqG+DBq72YEb7bzQES3lFWggjoJZ9zbTd/f5ukN+yolIqIkQTm9FWelQ367VhbMihQUq59Q==}
 
 
@@ -7147,6 +7323,9 @@ packages:
   three@0.162.0:
   three@0.162.0:
     resolution: {integrity: sha512-xfCYj4RnlozReCmUd+XQzj6/5OjDNHBy5nT6rVwrOKGENAvpXe2z1jL+DZYaMu4/9pNsjH/4Os/VvS9IrH7IOQ==}
     resolution: {integrity: sha512-xfCYj4RnlozReCmUd+XQzj6/5OjDNHBy5nT6rVwrOKGENAvpXe2z1jL+DZYaMu4/9pNsjH/4Os/VvS9IrH7IOQ==}
 
 
+  three@0.184.0:
+    resolution: {integrity: sha512-wtTRjG92pM5eUg/KuUnHsqSAlPM296brTOcLgMRqEeylYTh/CdtvKUvCyyCQTzFuStieWxvZb8mVTMvdPyUpxg==}
+
   throat@6.0.2:
   throat@6.0.2:
     resolution: {integrity: sha512-WKexMoJj3vEuK0yFEapj8y64V0A6xcuPuK9Gt1d0R+dzCSJc0lHqQytAbSB4cDAK0dWh4T0E2ETkoLE2WZ41OQ==}
     resolution: {integrity: sha512-WKexMoJj3vEuK0yFEapj8y64V0A6xcuPuK9Gt1d0R+dzCSJc0lHqQytAbSB4cDAK0dWh4T0E2ETkoLE2WZ41OQ==}
 
 
@@ -7166,6 +7345,9 @@ packages:
   tiny-emitter@2.1.0:
   tiny-emitter@2.1.0:
     resolution: {integrity: sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==}
     resolution: {integrity: sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==}
 
 
+  tiny-inflate@1.0.3:
+    resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==}
+
   tinycolor2@1.6.0:
   tinycolor2@1.6.0:
     resolution: {integrity: sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==}
     resolution: {integrity: sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==}
 
 
@@ -7176,6 +7358,9 @@ packages:
   tinymce@5.10.9:
   tinymce@5.10.9:
     resolution: {integrity: sha512-5bkrors87X9LhYX2xq8GgPHrIgJYHl87YNs+kBcjQ5I3CiUgzo/vFcGvT3MZQ9QHsEeYMhYO6a5CLGGffR8hMg==}
     resolution: {integrity: sha512-5bkrors87X9LhYX2xq8GgPHrIgJYHl87YNs+kBcjQ5I3CiUgzo/vFcGvT3MZQ9QHsEeYMhYO6a5CLGGffR8hMg==}
 
 
+  tinyqueue@2.0.3:
+    resolution: {integrity: sha512-ppJZNDuKGgxzkHihX8v9v9G5f+18gzaTfrukGrq6ueg0lmH4nqVnA2IPG0AEH3jKEk2GRJCUhDoqpoiw3PHLBA==}
+
   tmp@0.0.33:
   tmp@0.0.33:
     resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==}
     resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==}
     engines: {node: '>=0.6.0'}
     engines: {node: '>=0.6.0'}
@@ -7292,6 +7477,12 @@ packages:
     resolution: {integrity: sha512-xHtFaKtHxM9LOklMmJdI3BEnQq/D5F73Of2E1GDrITi9sgoVkvIsrQUTY1G8FlmGtA+awCI4EBlTRRYxkL2sRg==}
     resolution: {integrity: sha512-xHtFaKtHxM9LOklMmJdI3BEnQq/D5F73Of2E1GDrITi9sgoVkvIsrQUTY1G8FlmGtA+awCI4EBlTRRYxkL2sRg==}
     hasBin: true
     hasBin: true
 
 
+  two-product@1.0.2:
+    resolution: {integrity: sha512-vOyrqmeYvzjToVM08iU52OFocWT6eB/I5LUWYnxeAPGXAhAxXYU/Yr/R2uY5/5n4bvJQL9AQulIuxpIsMoT8XQ==}
+
+  two-sum@1.0.0:
+    resolution: {integrity: sha512-phP48e8AawgsNUjEY2WvoIWqdie8PoiDZGxTDv70LDr01uX5wLEQbOgSP7Z/B6+SW5oLtbe8qaYX2fKJs3CGTw==}
+
   type-check@0.4.0:
   type-check@0.4.0:
     resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
     resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
     engines: {node: '>= 0.8.0'}
     engines: {node: '>= 0.8.0'}
@@ -7996,6 +8187,24 @@ packages:
 
 
 snapshots:
 snapshots:
 
 
+  2d-polygon-area@1.0.0: {}
+
+  2d-polygon-boolean@1.0.1:
+    dependencies:
+      2d-polygon-area: 1.0.0
+      point-in-big-polygon: 1.0.0
+      segseg: 0.2.2
+      signum: 1.0.0
+
+  2d-polygon-self-intersections@1.3.1:
+    dependencies:
+      exact-segment-intersect: 2.0.0
+      robust-estimate-float: 1.0.0
+
+  3d-tiles-renderer@0.3.32(three@0.184.0):
+    dependencies:
+      three: 0.184.0
+
   '@aesoper/normal-utils@0.1.5': {}
   '@aesoper/normal-utils@0.1.5': {}
 
 
   '@ampproject/remapping@2.3.0':
   '@ampproject/remapping@2.3.0':
@@ -9760,6 +9969,8 @@ snapshots:
       - ts-node
       - ts-node
       - utf-8-validate
       - utf-8-validate
 
 
+  '@mlightcad/libredwg-web@0.7.2': {}
+
   '@nodelib/fs.scandir@2.1.5':
   '@nodelib/fs.scandir@2.1.5':
     dependencies:
     dependencies:
       '@nodelib/fs.stat': 2.0.5
       '@nodelib/fs.stat': 2.0.5
@@ -9783,6 +9994,26 @@ snapshots:
 
 
   '@popperjs/core@2.11.8': {}
   '@popperjs/core@2.11.8': {}
 
 
+  '@protobufjs/aspromise@1.1.2': {}
+
+  '@protobufjs/base64@1.1.2': {}
+
+  '@protobufjs/codegen@2.0.5': {}
+
+  '@protobufjs/eventemitter@1.1.1': {}
+
+  '@protobufjs/fetch@1.1.1':
+    dependencies:
+      '@protobufjs/aspromise': 1.1.2
+
+  '@protobufjs/float@1.0.2': {}
+
+  '@protobufjs/path@1.1.2': {}
+
+  '@protobufjs/pool@1.1.0': {}
+
+  '@protobufjs/utf8@1.1.1': {}
+
   '@purge-icons/core@0.9.1':
   '@purge-icons/core@0.9.1':
     dependencies:
     dependencies:
       '@iconify/iconify': 2.1.2
       '@iconify/iconify': 2.1.2
@@ -9814,7 +10045,7 @@ snapshots:
       codemirror: 5.65.20
       codemirror: 5.65.20
       core-js: 3.46.0
       core-js: 3.46.0
       crypto-js: 4.2.0
       crypto-js: 4.2.0
-      dayjs: 1.11.19
+      dayjs: 1.11.21
       echarts: 5.6.0
       echarts: 5.6.0
       echarts-gl: 2.0.9(echarts@5.6.0)
       echarts-gl: 2.0.9(echarts@5.6.0)
       echarts-liquidfill: 3.1.0(echarts@5.6.0)
       echarts-liquidfill: 3.1.0(echarts@5.6.0)
@@ -10594,6 +10825,34 @@ snapshots:
     optionalDependencies:
     optionalDependencies:
       vue: 3.5.24(typescript@4.9.5)
       vue: 3.5.24(typescript@4.9.5)
 
 
+  '@x-viewer/core@0.21.23':
+    dependencies:
+      2d-polygon-boolean: 1.0.1
+      2d-polygon-self-intersections: 1.3.1
+      3d-tiles-renderer: 0.3.32(three@0.184.0)
+      '@mlightcad/libredwg-web': 0.7.2
+      camera-controls: 1.38.2(three@0.184.0)
+      clipper-lib: 6.4.2
+      concaveman: 1.2.1
+      core-js: 3.46.0
+      i18next: 21.10.0
+      intl-pluralrules: 1.3.1
+      js-base64: 3.7.8
+      jsbi: 4.3.2
+      loglevel: 1.9.2
+      mitt: 3.0.1
+      opentype.js: 1.3.4
+      pako: 2.1.0
+      poly-extrude: 0.2.0
+      polybooljs: 1.2.2
+      polygon-clipping: 0.15.7
+      protobufjs: 7.6.4
+      regenerator-runtime: 0.13.11
+      screenfull: 6.0.2
+      stream: 0.0.2
+      three: 0.184.0
+      three-mesh-bvh: 0.9.10(three@0.184.0)
+
   '@xmldom/xmldom@0.8.11': {}
   '@xmldom/xmldom@0.8.11': {}
 
 
   '@zxcvbn-ts/core@3.0.4':
   '@zxcvbn-ts/core@3.0.4':
@@ -10703,7 +10962,7 @@ snapshots:
       '@simonwep/pickr': 1.8.2
       '@simonwep/pickr': 1.8.2
       array-tree-filter: 2.1.0
       array-tree-filter: 2.1.0
       async-validator: 4.2.5
       async-validator: 4.2.5
-      dayjs: 1.11.19
+      dayjs: 1.11.21
       dom-align: 1.12.4
       dom-align: 1.12.4
       dom-scroll-into-view: 2.0.1
       dom-scroll-into-view: 2.0.1
       lodash: 4.17.21
       lodash: 4.17.21
@@ -10955,6 +11214,8 @@ snapshots:
 
 
   binary-extensions@2.3.0: {}
   binary-extensions@2.3.0: {}
 
 
+  binary-search-bounds@2.0.5: {}
+
   bl@4.1.0:
   bl@4.1.0:
     dependencies:
     dependencies:
       buffer: 5.7.1
       buffer: 5.7.1
@@ -11085,6 +11346,10 @@ snapshots:
 
 
   camelcase@6.3.0: {}
   camelcase@6.3.0: {}
 
 
+  camera-controls@1.38.2(three@0.184.0):
+    dependencies:
+      three: 0.184.0
+
   caniuse-lite@1.0.30001755: {}
   caniuse-lite@1.0.30001755: {}
 
 
   caniuse-lite@1.0.30001780: {}
   caniuse-lite@1.0.30001780: {}
@@ -11215,6 +11480,8 @@ snapshots:
       select: 1.1.2
       select: 1.1.2
       tiny-emitter: 2.1.0
       tiny-emitter: 2.1.0
 
 
+  clipper-lib@6.4.2: {}
+
   cliui@6.0.0:
   cliui@6.0.0:
     dependencies:
     dependencies:
       string-width: 4.2.3
       string-width: 4.2.3
@@ -11319,6 +11586,13 @@ snapshots:
 
 
   concat-typed-array@1.0.2: {}
   concat-typed-array@1.0.2: {}
 
 
+  concaveman@1.2.1:
+    dependencies:
+      point-in-polygon: 1.1.0
+      rbush: 3.0.1
+      robust-predicates: 2.0.4
+      tinyqueue: 2.0.3
+
   confbox@0.1.8: {}
   confbox@0.1.8: {}
 
 
   confbox@0.2.2: {}
   confbox@0.2.2: {}
@@ -11807,7 +12081,7 @@ snapshots:
 
 
   dateformat@3.0.3: {}
   dateformat@3.0.3: {}
 
 
-  dayjs@1.11.19: {}
+  dayjs@1.11.21: {}
 
 
   de-indent@1.0.2: {}
   de-indent@1.0.2: {}
 
 
@@ -12003,6 +12277,8 @@ snapshots:
 
 
   duplexer@0.1.2: {}
   duplexer@0.1.2: {}
 
 
+  earcut@2.2.4: {}
+
   eastasianwidth@0.2.0: {}
   eastasianwidth@0.2.0: {}
 
 
   echarts-gl@2.0.9(echarts@5.6.0):
   echarts-gl@2.0.9(echarts@5.6.0):
@@ -12046,6 +12322,8 @@ snapshots:
     dependencies:
     dependencies:
       batch-processor: 1.0.0
       batch-processor: 1.0.0
 
 
+  emitter-component@1.1.2: {}
+
   emittery@0.13.1: {}
   emittery@0.13.1: {}
 
 
   emittery@0.8.1: {}
   emittery@0.8.1: {}
@@ -12458,6 +12736,14 @@ snapshots:
 
 
   eventemitter3@5.0.1: {}
   eventemitter3@5.0.1: {}
 
 
+  exact-segment-intersect@2.0.0:
+    dependencies:
+      robust-compress: 1.0.0
+      robust-scale: 1.0.2
+      robust-segment-intersect: 1.0.1
+      robust-sum: 1.0.0
+      two-product: 1.0.2
+
   execa@4.1.0:
   execa@4.1.0:
     dependencies:
     dependencies:
       cross-spawn: 7.0.6
       cross-spawn: 7.0.6
@@ -12744,6 +13030,8 @@ snapshots:
       hasown: 2.0.2
       hasown: 2.0.2
       is-callable: 1.2.7
       is-callable: 1.2.7
 
 
+  functional-red-black-tree@1.0.1: {}
+
   functions-have-names@1.2.3: {}
   functions-have-names@1.2.3: {}
 
 
   generator-function@2.0.1: {}
   generator-function@2.0.1: {}
@@ -13103,6 +13391,10 @@ snapshots:
 
 
   husky@8.0.3: {}
   husky@8.0.3: {}
 
 
+  i18next@21.10.0:
+    dependencies:
+      '@babel/runtime': 7.28.4
+
   iconv-lite@0.4.24:
   iconv-lite@0.4.24:
     dependencies:
     dependencies:
       safer-buffer: 2.1.2
       safer-buffer: 2.1.2
@@ -13201,6 +13493,8 @@ snapshots:
 
 
   internmap@2.0.3: {}
   internmap@2.0.3: {}
 
 
+  intl-pluralrules@1.3.1: {}
+
   intro.js@7.2.0: {}
   intro.js@7.2.0: {}
 
 
   is-accessor-descriptor@1.0.1:
   is-accessor-descriptor@1.0.1:
@@ -14141,6 +14435,8 @@ snapshots:
 
 
   js-base64@2.6.4: {}
   js-base64@2.6.4: {}
 
 
+  js-base64@3.7.8: {}
+
   js-beautify@1.15.4:
   js-beautify@1.15.4:
     dependencies:
     dependencies:
       config-chain: 1.1.13
       config-chain: 1.1.13
@@ -14164,6 +14460,8 @@ snapshots:
     dependencies:
     dependencies:
       argparse: 2.0.1
       argparse: 2.0.1
 
 
+  jsbi@4.3.2: {}
+
   jsdom@16.7.0:
   jsdom@16.7.0:
     dependencies:
     dependencies:
       abab: 2.0.6
       abab: 2.0.6
@@ -14399,6 +14697,10 @@ snapshots:
       strip-ansi: 7.1.2
       strip-ansi: 7.1.2
       wrap-ansi: 8.1.0
       wrap-ansi: 8.1.0
 
 
+  loglevel@1.9.2: {}
+
+  long@5.3.2: {}
+
   longest@2.0.1: {}
   longest@2.0.1: {}
 
 
   loose-envify@1.4.0:
   loose-envify@1.4.0:
@@ -14821,6 +15123,11 @@ snapshots:
 
 
   opener@1.5.2: {}
   opener@1.5.2: {}
 
 
+  opentype.js@1.3.4:
+    dependencies:
+      string.prototype.codepointat: 0.2.1
+      tiny-inflate: 1.0.3
+
   optionator@0.9.4:
   optionator@0.9.4:
     dependencies:
     dependencies:
       deep-is: 0.1.4
       deep-is: 0.1.4
@@ -14882,6 +15189,8 @@ snapshots:
 
 
   package-manager-detector@1.5.0: {}
   package-manager-detector@1.5.0: {}
 
 
+  pako@2.1.0: {}
+
   param-case@3.0.4:
   param-case@3.0.4:
     dependencies:
     dependencies:
       dot-case: 3.0.4
       dot-case: 3.0.4
@@ -15022,6 +15331,24 @@ snapshots:
 
 
   pngjs@5.0.0: {}
   pngjs@5.0.0: {}
 
 
+  point-in-big-polygon@1.0.0:
+    dependencies:
+      robust-orientation: 1.2.1
+      slab-decomposition: 1.0.3
+
+  point-in-polygon@1.1.0: {}
+
+  poly-extrude@0.2.0:
+    dependencies:
+      earcut: 2.2.4
+
+  polybooljs@1.2.2: {}
+
+  polygon-clipping@0.15.7:
+    dependencies:
+      robust-predicates: 3.0.2
+      splaytree: 3.2.3
+
   portfinder@1.0.38:
   portfinder@1.0.38:
     dependencies:
     dependencies:
       async: 3.2.6
       async: 3.2.6
@@ -15149,6 +15476,20 @@ snapshots:
 
 
   proto-list@1.2.4: {}
   proto-list@1.2.4: {}
 
 
+  protobufjs@7.6.4:
+    dependencies:
+      '@protobufjs/aspromise': 1.1.2
+      '@protobufjs/base64': 1.1.2
+      '@protobufjs/codegen': 2.0.5
+      '@protobufjs/eventemitter': 1.1.1
+      '@protobufjs/fetch': 1.1.1
+      '@protobufjs/float': 1.0.2
+      '@protobufjs/path': 1.1.2
+      '@protobufjs/pool': 1.1.0
+      '@protobufjs/utf8': 1.1.1
+      '@types/node': 20.19.25
+      long: 5.3.2
+
   proxy-from-env@1.1.0: {}
   proxy-from-env@1.1.0: {}
 
 
   prr@1.0.1:
   prr@1.0.1:
@@ -15201,6 +15542,8 @@ snapshots:
 
 
   quick-lru@5.1.1: {}
   quick-lru@5.1.1: {}
 
 
+  quickselect@2.0.0: {}
+
   raf@3.4.1:
   raf@3.4.1:
     dependencies:
     dependencies:
       performance-now: 2.1.0
       performance-now: 2.1.0
@@ -15208,6 +15551,10 @@ snapshots:
 
 
   rangetouch@2.0.1: {}
   rangetouch@2.0.1: {}
 
 
+  rbush@3.0.1:
+    dependencies:
+      quickselect: 2.0.0
+
   react-is@17.0.2: {}
   react-is@17.0.2: {}
 
 
   react-is@18.3.1: {}
   react-is@18.3.1: {}
@@ -15403,8 +15750,34 @@ snapshots:
     dependencies:
     dependencies:
       glob: 10.4.5
       glob: 10.4.5
 
 
+  robust-compress@1.0.0: {}
+
+  robust-estimate-float@1.0.0: {}
+
+  robust-orientation@1.2.1:
+    dependencies:
+      robust-scale: 1.0.2
+      robust-subtract: 1.0.0
+      robust-sum: 1.0.0
+      two-product: 1.0.2
+
+  robust-predicates@2.0.4: {}
+
   robust-predicates@3.0.2: {}
   robust-predicates@3.0.2: {}
 
 
+  robust-scale@1.0.2:
+    dependencies:
+      two-product: 1.0.2
+      two-sum: 1.0.0
+
+  robust-segment-intersect@1.0.1:
+    dependencies:
+      robust-orientation: 1.2.1
+
+  robust-subtract@1.0.0: {}
+
+  robust-sum@1.0.0: {}
+
   rollup-plugin-purge-icons@0.9.1:
   rollup-plugin-purge-icons@0.9.1:
     dependencies:
     dependencies:
       '@purge-icons/core': 0.9.1
       '@purge-icons/core': 0.9.1
@@ -15476,12 +15849,16 @@ snapshots:
     dependencies:
     dependencies:
       xmlchars: 2.2.0
       xmlchars: 2.2.0
 
 
+  screenfull@6.0.2: {}
+
   scroll-into-view-if-needed@2.2.31:
   scroll-into-view-if-needed@2.2.31:
     dependencies:
     dependencies:
       compute-scroll-into-view: 1.0.20
       compute-scroll-into-view: 1.0.20
 
 
   secure-compare@3.0.1: {}
   secure-compare@3.0.1: {}
 
 
+  segseg@0.2.2: {}
+
   select@1.1.2: {}
   select@1.1.2: {}
 
 
   semver@5.7.2: {}
   semver@5.7.2: {}
@@ -15583,6 +15960,8 @@ snapshots:
 
 
   signal-exit@4.1.0: {}
   signal-exit@4.1.0: {}
 
 
+  signum@1.0.0: {}
+
   single-spa@5.9.5: {}
   single-spa@5.9.5: {}
 
 
   sirv@2.0.4:
   sirv@2.0.4:
@@ -15593,6 +15972,12 @@ snapshots:
 
 
   sisteransi@1.0.5: {}
   sisteransi@1.0.5: {}
 
 
+  slab-decomposition@1.0.3:
+    dependencies:
+      binary-search-bounds: 2.0.5
+      functional-red-black-tree: 1.0.1
+      robust-orientation: 1.2.1
+
   slash@3.0.0: {}
   slash@3.0.0: {}
 
 
   slice-ansi@4.0.0:
   slice-ansi@4.0.0:
@@ -15682,6 +16067,8 @@ snapshots:
 
 
   spdx-license-ids@3.0.22: {}
   spdx-license-ids@3.0.22: {}
 
 
+  splaytree@3.2.3: {}
+
   split-string@3.1.0:
   split-string@3.1.0:
     dependencies:
     dependencies:
       extend-shallow: 3.0.2
       extend-shallow: 3.0.2
@@ -15721,6 +16108,10 @@ snapshots:
       es-errors: 1.3.0
       es-errors: 1.3.0
       internal-slot: 1.1.0
       internal-slot: 1.1.0
 
 
+  stream@0.0.2:
+    dependencies:
+      emitter-component: 1.1.2
+
   strict-uri-encode@1.1.0: {}
   strict-uri-encode@1.1.0: {}
 
 
   string-argv@0.3.2: {}
   string-argv@0.3.2: {}
@@ -15742,6 +16133,8 @@ snapshots:
       emoji-regex: 9.2.2
       emoji-regex: 9.2.2
       strip-ansi: 7.1.2
       strip-ansi: 7.1.2
 
 
+  string.prototype.codepointat@0.2.1: {}
+
   string.prototype.padend@3.1.6:
   string.prototype.padend@3.1.6:
     dependencies:
     dependencies:
       call-bind: 1.0.8
       call-bind: 1.0.8
@@ -16000,6 +16393,10 @@ snapshots:
 
 
   text-table@0.2.0: {}
   text-table@0.2.0: {}
 
 
+  three-mesh-bvh@0.9.10(three@0.184.0):
+    dependencies:
+      three: 0.184.0
+
   three.path@1.0.1:
   three.path@1.0.1:
     dependencies:
     dependencies:
       three: 0.132.2
       three: 0.132.2
@@ -16008,6 +16405,8 @@ snapshots:
 
 
   three@0.162.0: {}
   three@0.162.0: {}
 
 
+  three@0.184.0: {}
+
   throat@6.0.2: {}
   throat@6.0.2: {}
 
 
   throttle-debounce@5.0.0: {}
   throttle-debounce@5.0.0: {}
@@ -16025,12 +16424,16 @@ snapshots:
 
 
   tiny-emitter@2.1.0: {}
   tiny-emitter@2.1.0: {}
 
 
+  tiny-inflate@1.0.3: {}
+
   tinycolor2@1.6.0: {}
   tinycolor2@1.6.0: {}
 
 
   tinyexec@1.0.2: {}
   tinyexec@1.0.2: {}
 
 
   tinymce@5.10.9: {}
   tinymce@5.10.9: {}
 
 
+  tinyqueue@2.0.3: {}
+
   tmp@0.0.33:
   tmp@0.0.33:
     dependencies:
     dependencies:
       os-tmpdir: 1.0.2
       os-tmpdir: 1.0.2
@@ -16167,6 +16570,10 @@ snapshots:
     optionalDependencies:
     optionalDependencies:
       fsevents: 2.3.3
       fsevents: 2.3.3
 
 
+  two-product@1.0.2: {}
+
+  two-sum@1.0.0: {}
+
   type-check@0.4.0:
   type-check@0.4.0:
     dependencies:
     dependencies:
       prelude-ls: 1.2.1
       prelude-ls: 1.2.1

BIN
src/assets/images/home-container/configurable/hsq/4-1bg.png


BIN
src/assets/images/home-container/configurable/hsq/4-2.png


BIN
src/assets/images/home-container/configurable/hsq/4-3.png


+ 9 - 0
src/assets/images/home-container/configurable/hsq/4-cf.svg

@@ -0,0 +1,9 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="14.464" height="23.677" viewBox="0 0 14.464 23.677">
+  <defs>
+    <linearGradient id="linear-gradient" x1="0.5" x2="0.5" y2="1" gradientUnits="objectBoundingBox">
+      <stop offset="0" stop-color="#2cc1ff"/>
+      <stop offset="1" stop-color="#ccedff"/>
+    </linearGradient>
+  </defs>
+  <path id="路径_58007" data-name="路径 58007" d="M213.448,10.386V.2l-3.7,6.3,0,.006L207,11.178h6.114V21.539h.05l6.552-11.153Z" transform="translate(-206.126 1.639)" stroke="rgba(0,0,0,0)" stroke-miterlimit="10" stroke-width="1" fill="url(#linear-gradient)"/>
+</svg>

+ 9 - 0
src/assets/images/home-container/configurable/hsq/4-jy.svg

@@ -0,0 +1,9 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="19.111" height="19.111" viewBox="0 0 19.111 19.111">
+  <defs>
+    <linearGradient id="linear-gradient" x1="0.5" x2="0.5" y2="1" gradientUnits="objectBoundingBox">
+      <stop offset="0" stop-color="#2cfff1"/>
+      <stop offset="1" stop-color="#ccedff"/>
+    </linearGradient>
+  </defs>
+  <path id="路径_58006" data-name="路径 58006" d="M9.056,0A9.056,9.056,0,1,1,0,9.056,9.056,9.056,0,0,1,9.056,0ZM14.23,7.762H3.881v2.587H14.23V7.762Z" transform="translate(0.5 0.5)" stroke="rgba(0,0,0,0)" stroke-miterlimit="10" stroke-width="1" fill="url(#linear-gradient)"/>
+</svg>

+ 9 - 0
src/assets/images/home-container/configurable/hsq/4-qy.svg

@@ -0,0 +1,9 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="19.114" height="19.114" viewBox="0 0 19.114 19.114">
+  <defs>
+    <linearGradient id="linear-gradient" x1="0.5" x2="0.5" y2="1" gradientUnits="objectBoundingBox">
+      <stop offset="0" stop-color="#2cfff1"/>
+      <stop offset="1" stop-color="#ccedff"/>
+    </linearGradient>
+  </defs>
+  <path id="路径_58005" data-name="路径 58005" d="M17.057,26.114a9.057,9.057,0,1,1,9.057-9.057A9.057,9.057,0,0,1,17.057,26.114Zm5.032-13.083L16.05,19.07l-3.018-3.02L11.522,17.5l4.529,4.591,7.579-7.611Z" transform="translate(-7.5 -7.5)" stroke="rgba(0,0,0,0)" stroke-miterlimit="10" stroke-width="1" fill="url(#linear-gradient)"/>
+</svg>

+ 14 - 0
src/assets/images/home-container/configurable/hsq/4-total.svg

@@ -0,0 +1,14 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="20.264" height="19.885" viewBox="0 0 20.264 19.885">
+  <defs>
+    <linearGradient id="linear-gradient" x1="0.5" x2="0.5" y2="1" gradientUnits="objectBoundingBox">
+      <stop offset="0" stop-color="#2cc1ff"/>
+      <stop offset="1" stop-color="#ccedff"/>
+    </linearGradient>
+  </defs>
+  <g id="组_16864" data-name="组 16864" transform="translate(-13.092 -27.144)">
+    <path id="路径_58001" data-name="路径 58001" d="M212.072,260.015v-4.3c0-.1-.312-.173-.7-.173s-.7.078-.7.173v4.3c0,.1.312.173.7.173S212.072,260.111,212.072,260.015Zm.647,3.162,3.787,2.044c.083.045.3-.193.482-.531s.264-.651.18-.7l-3.787-2.044c-.084-.045-.3.194-.483.532S212.634,263.132,212.718,263.177Zm-6.915,1.589,3.909-1.8c.086-.04.026-.354-.135-.7s-.363-.6-.449-.562l-3.909,1.8c-.087.039-.026.355.135.7S205.717,264.805,205.8,264.766Z" transform="translate(-188.15 -223.713)" fill="url(#linear-gradient)"/>
+    <path id="路径_58002" data-name="路径 58002" d="M24.285,27.354a2.781,2.781,0,1,0,1.708,2.839A2.78,2.78,0,0,0,24.285,27.354Zm-.589,3.7a1.211,1.211,0,1,1-.456-2.326,1.2,1.2,0,0,1,1.195,1.195,1.213,1.213,0,0,1-.739,1.131ZM16.935,38.8A2.782,2.782,0,1,0,18.6,41.9a2.779,2.779,0,0,0-1.669-3.1Zm-.59,3.7a1.21,1.21,0,1,1-.455-2.325,1.2,1.2,0,0,1,1.194,1.194,1.211,1.211,0,0,1-.739,1.131Zm15.29-3.369a2.782,2.782,0,1,0,1.669,3.1,2.781,2.781,0,0,0-1.669-3.1Zm-.59,3.7a1.211,1.211,0,1,1-.454-2.326,1.2,1.2,0,0,1,1.194,1.2,1.212,1.212,0,0,1-.74,1.131Z" fill="url(#linear-gradient)"/>
+    <path id="路径_58003" data-name="路径 58003" d="M88.274,141A8.91,8.91,0,0,0,81.4,130.023l-.479,1.545a7.312,7.312,0,0,1,5.833,8.925l1.522.507ZM72.259,138.8a7.362,7.362,0,0,1,5.847-7.194l.056-1.63a8.908,8.908,0,0,0-7.269,10.835l1.564-.342a7.325,7.325,0,0,1-.2-1.668Zm13.323,4.266a7.327,7.327,0,0,1-11.744.272l-1.064,1.233a8.935,8.935,0,0,0,14.208-.7l-1.4-.8Z" transform="translate(-56.384 -100.719)" fill="url(#linear-gradient)"/>
+    <path id="路径_58004" data-name="路径 58004" d="M375.442,424.845a2.781,2.781,0,1,0,1.7,2.928A2.78,2.78,0,0,0,375.442,424.845Zm-.589,3.7a1.211,1.211,0,1,1-.456-2.325,1.2,1.2,0,0,1,1.195,1.195A1.211,1.211,0,0,1,374.853,428.548Z" transform="translate(-351.157 -389.341)" fill="url(#linear-gradient)"/>
+  </g>
+</svg>

+ 3 - 0
src/assets/images/home-container/configurable/hsq/arrow.svg

@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="18.666" height="6.617" viewBox="0 0 18.666 6.617">
+  <path id="路径_58016" data-name="路径 58016" d="M402.711,323.868l-18.666-3.309v6.617l18.666-3.308Z" transform="translate(-384.045 -320.56)" fill="#2cb6ff"/>
+</svg>

BIN
src/assets/images/home-container/configurable/hsq/bjcf.png


BIN
src/assets/images/home-container/configurable/hsq/czgz.png


BIN
src/assets/images/home-container/configurable/hsq/jlrz.png


BIN
src/assets/images/home-container/configurable/hsq/tjpd.png


BIN
src/assets/images/home-container/configurable/hsq/zxdz.png


+ 78 - 78
src/views/vent/home/configurable/components/ModuleCommonHsq.vue

@@ -23,102 +23,102 @@
   </Transition>
   </Transition>
 </template>
 </template>
 <script lang="ts" setup>
 <script lang="ts" setup>
-  import Header from './header.vue';
-  import Content from './content.vue';
-  // import ModuleLeft from './original/moduleLeft.vue';
-  // import ModuleBottom from './original/moduleBottom.vue';
-  import { computed, ref } from 'vue';
-  import ventBox1 from '/@/components/vent/ventBoxHsq.vue';
-  import { openWindow } from '/@/utils';
-  import { getFormattedText } from '../hooks/helper.js';
-  // import { ModuleProps } from '../types';
+import Header from './header.vue';
+import Content from './content.vue';
+// import ModuleLeft from './original/moduleLeft.vue';
+// import ModuleBottom from './original/moduleBottom.vue';
+import { computed, ref } from 'vue';
+import ventBox1 from '/@/components/vent/ventBoxHsq.vue';
+import { openWindow } from '/@/utils';
+import { getFormattedText } from '../hooks/helper.js';
+// import { ModuleProps } from '../types';
 
 
-  const props = defineProps<{
-    /** 配置的详细模块信息 */
-    moduleData: any;
-    /** 配置的详细样式信息 */
-    showStyle: any;
-    /** 该模块配置中的设备标识符 */
-    deviceType: string;
-    /** api返回的数据 */
-    data: any;
-    moduleName: string;
-    visible: boolean;
-    chartData?: any;
-  }>();
-  defineEmits(['close', 'click']);
+const props = defineProps<{
+  /** 配置的详细模块信息 */
+  moduleData: any;
+  /** 配置的详细样式信息 */
+  showStyle: any;
+  /** 该模块配置中的设备标识符 */
+  deviceType: string;
+  /** api返回的数据 */
+  data: any;
+  moduleName: string;
+  visible: boolean;
+  chartData?: any;
+}>();
+defineEmits(['close', 'click']);
 
 
-  const { header } = props.moduleData;
-  const selectedData = ref();
+const { header } = props.moduleData;
+const selectedData = ref();
 
 
-  const style = computed(() => {
-    const size = props.showStyle.size;
-    const position = props.showStyle.position;
-    return size + position + 'position: absolute; pointer-events: auto; z-index: 1';
-  });
+const style = computed(() => {
+  const size = props.showStyle.size;
+  const position = props.showStyle.position;
+  return size + position + 'position: absolute; pointer-events: auto; z-index: 1';
+});
 
 
-  const capitalizedPosition = computed(() => {
-    return props.showStyle.position.includes('left') ? 'Left' : 'Right';
-  });
+const capitalizedPosition = computed(() => {
+  return props.showStyle.position.includes('left') ? 'Left' : 'Right';
+});
 
 
-  // 根据配置里的定位判断应该使用哪个class
-  function getModuleClass({ size, position }) {
-    const [_, width] = size.match(/width:([0-9]+)px/) || [];
-    if (position.includes('bottom') || parseInt(width) > 800) {
-      return 'module-common module-common-longer';
-    }
-    return 'module-common';
+// 根据配置里的定位判断应该使用哪个class
+function getModuleClass({ size, position }) {
+  const [_, width] = size.match(/width:([0-9]+)px/) || [];
+  if (position.includes('bottom') || parseInt(width) > 800) {
+    return 'module-common module-common-longer';
   }
   }
+  return 'module-common';
+}
 
 
-  function redirectTo() {
-    const { to } = props.moduleData;
-    if (!to) return;
-    openWindow(getFormattedText(selectedData.value, to));
-  }
+function redirectTo() {
+  const { to } = props.moduleData;
+  if (!to) return;
+  openWindow(getFormattedText(selectedData.value, to));
+}
 </script>
 </script>
 <style lang="less" scoped>
 <style lang="less" scoped>
-  @import '/@/design/theme.less';
+@import '/@/design/theme.less';
 
 
-  .module-common .box1-center {
-    height: calc(100% - 48px);
-  }
+.module-common .box1-center {
+  height: calc(100% - 48px);
+}
 
 
-  :deep(.box1-center) {
-    height: calc(100% - 48px);
-  }
-  :deep(.box1-center > .box-container) {
-    height: 100%;
-    padding: 0 !important;
-    width: 100% !important;
-  }
-  @{theme-green} {
-    .module-common-longer {
-      :deep(.box1-top) {
-        --image-box1-top: url('/@/assets/images/themify/green/vent/border/box-top.png');
-      }
-      :deep(.box1-bottom) {
-        --image-box1-bottom: url('/@/assets/images/themify/green/vent/border/box-bottom.png');
-      }
+:deep(.box1-center) {
+  height: calc(100% - 48px);
+}
+:deep(.box1-center > .box-container) {
+  height: 100%;
+  padding: 0 !important;
+  width: 100% !important;
+}
+@{theme-green} {
+  .module-common-longer {
+    :deep(.box1-top) {
+      --image-box1-top: url('/@/assets/images/themify/green/vent/border/box-top.png');
     }
     }
-  }
-  @{theme-deepblue} {
-    .module-common-longer {
-      :deep(.box1-top) {
-        --image-box1-top: url('/@/assets/images/themify/deepblue/vent/border/box2-top-long.png');
-      }
-      :deep(.box1-bottom) {
-        --image-box1-bottom: none;
-      }
+    :deep(.box1-bottom) {
+      --image-box1-bottom: url('/@/assets/images/themify/green/vent/border/box-bottom.png');
     }
     }
   }
   }
+}
+@{theme-deepblue} {
   .module-common-longer {
   .module-common-longer {
     :deep(.box1-top) {
     :deep(.box1-top) {
-      --image-box1-top: url('/@/assets/images/vent/box-top-bg.png');
-      background-image: var(--image-box1-top);
+      --image-box1-top: url('/@/assets/images/themify/deepblue/vent/border/box2-top-long.png');
     }
     }
     :deep(.box1-bottom) {
     :deep(.box1-bottom) {
-      --image-box1-bottom: url('/@/assets/images/vent/box-bottom-bg.png');
-      background-image: var(--image-box1-bottom);
+      --image-box1-bottom: none;
     }
     }
   }
   }
+}
+.module-common-longer {
+  :deep(.box1-top) {
+    --image-box1-top: url('/@/assets/images/vent/box-top-bg.png');
+    background-image: var(--image-box1-top);
+  }
+  :deep(.box1-bottom) {
+    --image-box1-bottom: url('/@/assets/images/vent/box-bottom-bg.png');
+    background-image: var(--image-box1-bottom);
+  }
+}
 </style>
 </style>

+ 347 - 331
src/views/vent/home/configurable/components/content.vue

@@ -225,10 +225,22 @@
         <template v-if="config.name === 'mixed_warn'">
         <template v-if="config.name === 'mixed_warn'">
           <MixedWarn></MixedWarn>
           <MixedWarn></MixedWarn>
         </template>
         </template>
-         <template v-if="config.name === 'rule_list'">
+        <template v-if="config.name === 'rule_table'">
+          <RuleTable></RuleTable>
+        </template>
+        <template v-if="config.name === 'link_log'">
+          <LinkLog></LinkLog>
+        </template>
+        <template v-if="config.name === 'rule_num'">
+          <RuleNum></RuleNum>
+        </template>
+        <template v-if="config.name === 'link_edit'">
+          <LinkRuleEdit></LinkRuleEdit>
+        </template>
+        <template v-if="config.name === 'rule_list'">
           <RuleList></RuleList>
           <RuleList></RuleList>
         </template>
         </template>
-          <template v-if="config.name === 'echart_bar_new'">
+        <template v-if="config.name === 'echart_bar_new'">
           <EchartBarNew></EchartBarNew>
           <EchartBarNew></EchartBarNew>
         </template>
         </template>
       </div>
       </div>
@@ -271,405 +283,409 @@ import RadioLabel from './preset/radioLabel.vue';
 import ButtonList from './preset/buttonList.vue';
 import ButtonList from './preset/buttonList.vue';
 import cardList from './preset/cardList.vue';
 import cardList from './preset/cardList.vue';
 import generalList from './preset/generalList.vue';
 import generalList from './preset/generalList.vue';
-import upDown from './preset/upDown.vue'
-import gasInjectChart from './preset/gasInjectChart.vue'
-import gasInjectList from './preset/gasInjectList.vue'
-import gasZyChart from './preset/gasZyChart.vue'
-import gasZyList from './preset/gasZyList.vue'
-import gasWarnChart from './preset/gasWarnChart.vue'
-import gasWarnList from './preset/gasWarnList.vue'
-import gasDeviceStatusControl from './preset/gasDeviceStatusControl.vue'
-import gasBoard from './preset/gasBoard.vue'
-import gasInjectCard from './preset/gasInjectCard.vue'
-import cameraModal from './preset/cameraModal.vue'
-import echartLine from './preset/echartLine.vue'
-import CustomGalleryNew from './preset/CustomGalleryNew.vue'
-import ImageCardNew from './preset/ImageCardNew.vue'
-import BtnListNew from './preset/BtnListNew.vue'
-import OperateNew from './preset/OperateNew.vue'
-import LongList from './preset/LongList.vue'
-import LongList1 from './preset/LongList1.vue'
-import LongList2 from './preset/LongList2.vue'
-import SearchTable from './preset/SearchTable.vue'
-import MixedWarn from './preset/MixedWarn.vue'
-import RuleList from './preset/RuleList.vue'
-import EchartBarNew from './preset/EchartBarNew.vue'
+import upDown from './preset/upDown.vue';
+import gasInjectChart from './preset/gasInjectChart.vue';
+import gasInjectList from './preset/gasInjectList.vue';
+import gasZyChart from './preset/gasZyChart.vue';
+import gasZyList from './preset/gasZyList.vue';
+import gasWarnChart from './preset/gasWarnChart.vue';
+import gasWarnList from './preset/gasWarnList.vue';
+import gasDeviceStatusControl from './preset/gasDeviceStatusControl.vue';
+import gasBoard from './preset/gasBoard.vue';
+import gasInjectCard from './preset/gasInjectCard.vue';
+import cameraModal from './preset/cameraModal.vue';
+import echartLine from './preset/echartLine.vue';
+import CustomGalleryNew from './preset/CustomGalleryNew.vue';
+import ImageCardNew from './preset/ImageCardNew.vue';
+import BtnListNew from './preset/BtnListNew.vue';
+import OperateNew from './preset/OperateNew.vue';
+import LongList from '../../../../../../LongList.vue';
+import LongList1 from './preset/LongList1.vue';
+import LongList2 from './preset/LongList2.vue';
+import SearchTable from './preset/SearchTable.vue';
+import RuleTable from './preset/ruleTable.vue';
+import MixedWarn from './preset/MixedWarn.vue';
+import LinkLog from './preset/linkLog.vue';
+import RuleNum from './preset/ruleNum.vue';
+import LinkRuleEdit from './preset/linkRuleEdit.vue';
+import RuleList from './preset/RuleList.vue';
+import EchartBarNew from './preset/EchartBarNew.vue';
 // import FIreWarn from './preset/FIreWarn.vue';
 // import FIreWarn from './preset/FIreWarn.vue';
 // import FIreControl from './preset/FIreControl.vue';
 // import FIreControl from './preset/FIreControl.vue';
 
 
-  const props = defineProps<{
-    data: any;
-    moduleData: Config['moduleData'];
-    chartData: any;
-  }>();
+const props = defineProps<{
+  data: any;
+  moduleData: Config['moduleData'];
+  chartData: any;
+}>();
+
+const { background, layout } = props.moduleData;
 
 
-  const { background, layout } = props.moduleData;
+// 获取当原始配置带 items 项时的最终 items 配置
+function getItems(raw, items: CommonItem[]) {
+  return items.map((i) => {
+    return {
+      ...i,
+      label: getFormattedText(raw, i.label, i.trans),
+      value: getFormattedText(raw, i.value, i.trans),
+    };
+  });
+}
 
 
-  // 获取当原始配置带 items 项时的最终 items 配置
-  function getItems(raw, items: CommonItem[]) {
-    return items.map((i) => {
+// 获取当 List 组件配置带 items 项时的最终 items 配置
+function getListItems(raw: any, items: CommonItem[], mapFromData?: boolean) {
+  if (mapFromData && Array.isArray(raw)) {
+    return raw.map((data) => {
+      const item = items[0];
       return {
       return {
-        ...i,
-        label: getFormattedText(raw, i.label, i.trans),
-        value: getFormattedText(raw, i.value, i.trans),
+        ...item,
+        label: getFormattedText(data, item.label, item.trans),
+        value: getFormattedText(data, item.value, item.trans),
       };
       };
     });
     });
   }
   }
+  return getItems(raw, items);
+}
 
 
-  // 获取当 List 组件配置带 items 项时的最终 items 配置
-  function getListItems(raw: any, items: CommonItem[], mapFromData?: boolean) {
-    if (mapFromData && Array.isArray(raw)) {
-      return raw.map((data) => {
-        const item = items[0];
-        return {
+/** 根据配置里的layout将配置格式化为带 key 的具体配置,例如:[{ key: 'list', value: any, ...ModuleDataList }] */
+const layoutConfig = computed(() => {
+  const refData = props.data;
+  const board = clone(props.moduleData.board) || [];
+  const list = clone(props.moduleData.list) || [];
+  const gallery = clone(props.moduleData.gallery) || [];
+  const complex_list = clone(props.moduleData.complex_list) || [];
+  const gallery_list = clone(props.moduleData.gallery_list) || [];
+  const tabs = clone(props.moduleData.tabs) || [];
+  const chart = clone(props.moduleData.chart) || [];
+  const table = clone(props.moduleData.table) || [];
+  const preset = clone(props.moduleData.preset) || [];
+  const partition = clone(props.moduleData.partition) || [];
+  const mockData = clone(props.chartData) || [];
+  return layout.items.reduce((arr: any[], item) => {
+    switch (item.name) {
+      case 'board': {
+        const cfg = board.shift();
+        if (!cfg) break;
+        const data = getData(refData, cfg.readFrom, cfg.parser);
+
+        arr.push({
+          overflow: true,
           ...item,
           ...item,
-          label: getFormattedText(data, item.label, item.trans),
-          value: getFormattedText(data, item.value, item.trans),
-        };
-      });
-    }
-    return getItems(raw, items);
-  }
+          ...cfg,
+          items: getItems(data, cfg.items),
+        });
+        break;
+      }
+      case 'list': {
+        const cfg = list.shift();
+        if (!cfg) break;
+        const data = getData(refData, cfg.readFrom, cfg.parser);
 
 
-  /** 根据配置里的layout将配置格式化为带 key 的具体配置,例如:[{ key: 'list', value: any, ...ModuleDataList }] */
-  const layoutConfig = computed(() => {
-    const refData = props.data;
-    const board = clone(props.moduleData.board) || [];
-    const list = clone(props.moduleData.list) || [];
-    const gallery = clone(props.moduleData.gallery) || [];
-    const complex_list = clone(props.moduleData.complex_list) || [];
-    const gallery_list = clone(props.moduleData.gallery_list) || [];
-    const tabs = clone(props.moduleData.tabs) || [];
-    const chart = clone(props.moduleData.chart) || [];
-    const table = clone(props.moduleData.table) || [];
-    const preset = clone(props.moduleData.preset) || [];
-    const partition = clone(props.moduleData.partition) || [];
-    const mockData = clone(props.chartData) || [];
-    return layout.items.reduce((arr: any[], item) => {
-      switch (item.name) {
-        case 'board': {
-          const cfg = board.shift();
-          if (!cfg) break;
-          const data = getData(refData, cfg.readFrom, cfg.parser);
+        arr.push({
+          overflow: true,
+          ...item,
+          ...cfg,
+          items: getListItems(data, cfg.items, cfg.mapFromData),
+        });
+        break;
+      }
+      case 'gallery': {
+        const cfg = gallery.shift();
+        if (!cfg) break;
+        const data = getData(refData, cfg.readFrom, cfg.parser);
+
+        arr.push({
+          overflow: true,
+          ...item,
+          ...cfg,
+          items: getItems(data, cfg.items),
+        });
+        break;
+      }
+      case 'complex_list': {
+        const cfg = complex_list.shift();
+        if (!cfg) break;
+        const data = getData(refData, cfg.readFrom, cfg.parser);
 
 
+        if (cfg.mapFromData) {
+          const firstListItem = cfg.items[0];
           arr.push({
           arr.push({
             overflow: true,
             overflow: true,
             ...item,
             ...item,
             ...cfg,
             ...cfg,
-            items: getItems(data, cfg.items),
+            items: (data || []).map((d) => {
+              return {
+                title: getFormattedText(d, firstListItem.title, firstListItem.trans),
+                contents: firstListItem.contents.map((e) => {
+                  return {
+                    ...e,
+                    label: getFormattedText(d, e.label, e.trans),
+                    value: getFormattedText(d, e.value, e.trans),
+                  };
+                }),
+              };
+            }),
           });
           });
-          break;
-        }
-        case 'list': {
-          const cfg = list.shift();
-          if (!cfg) break;
-          const data = getData(refData, cfg.readFrom, cfg.parser);
-
+        } else {
           arr.push({
           arr.push({
             overflow: true,
             overflow: true,
             ...item,
             ...item,
             ...cfg,
             ...cfg,
-            items: getListItems(data, cfg.items, cfg.mapFromData),
+            items: cfg.items.map((i) => {
+              return {
+                title: getFormattedText(data, i.title, i.trans),
+                contents: i.contents.map((e) => {
+                  return {
+                    ...e,
+                    label: getFormattedText(data, e.label, e.trans),
+                    value: getFormattedText(data, e.value, e.trans),
+                  };
+                }),
+              };
+            }),
           });
           });
-          break;
         }
         }
-        case 'gallery': {
-          const cfg = gallery.shift();
-          if (!cfg) break;
-          const data = getData(refData, cfg.readFrom, cfg.parser);
+        break;
+      }
+      case 'gallery_list': {
+        const cfg = gallery_list.shift();
+        if (!cfg) break;
+        const data = getData(refData, cfg.readFrom, cfg.parser);
+
+        arr.push({
+          overflow: true,
+          ...item,
+          ...cfg,
+          items: getItems(data, cfg.items),
+          galleryItems: getItems(data, cfg.galleryItems),
+        });
+        break;
+      }
+      case 'tabs': {
+        const cfg = tabs.shift();
+        if (!cfg) break;
+        const data = getData(refData, cfg.readFrom, cfg.parser);
 
 
+        if (cfg.mapFromData) {
+          const firstListItem = cfg.items[0];
           arr.push({
           arr.push({
             overflow: true,
             overflow: true,
             ...item,
             ...item,
             ...cfg,
             ...cfg,
-            items: getItems(data, cfg.items),
+            items: (data || []).map((d) => {
+              return {
+                title: getFormattedText(d, firstListItem.title, firstListItem.trans),
+                contents: firstListItem.contents.map((e) => {
+                  return {
+                    ...e,
+                    label: getFormattedText(d, e.label, e.trans),
+                    value: getFormattedText(d, e.value, e.trans),
+                  };
+                }),
+              };
+            }),
           });
           });
-          break;
-        }
-        case 'complex_list': {
-          const cfg = complex_list.shift();
-          if (!cfg) break;
-          const data = getData(refData, cfg.readFrom, cfg.parser);
-
-          if (cfg.mapFromData) {
-            const firstListItem = cfg.items[0];
-            arr.push({
-              overflow: true,
-              ...item,
-              ...cfg,
-              items: (data || []).map((d) => {
-                return {
-                  title: getFormattedText(d, firstListItem.title, firstListItem.trans),
-                  contents: firstListItem.contents.map((e) => {
-                    return {
-                      ...e,
-                      label: getFormattedText(d, e.label, e.trans),
-                      value: getFormattedText(d, e.value, e.trans),
-                    };
-                  }),
-                };
-              }),
-            });
-          } else {
-            arr.push({
-              overflow: true,
-              ...item,
-              ...cfg,
-              items: cfg.items.map((i) => {
-                return {
-                  title: getFormattedText(data, i.title, i.trans),
-                  contents: i.contents.map((e) => {
-                    return {
-                      ...e,
-                      label: getFormattedText(data, e.label, e.trans),
-                      value: getFormattedText(data, e.value, e.trans),
-                    };
-                  }),
-                };
-              }),
-            });
-          }
-          break;
-        }
-        case 'gallery_list': {
-          const cfg = gallery_list.shift();
-          if (!cfg) break;
-          const data = getData(refData, cfg.readFrom, cfg.parser);
-
+        } else {
           arr.push({
           arr.push({
             overflow: true,
             overflow: true,
             ...item,
             ...item,
             ...cfg,
             ...cfg,
-            items: getItems(data, cfg.items),
-            galleryItems: getItems(data, cfg.galleryItems),
+            items: cfg.items.map((i) => {
+              return {
+                title: getFormattedText(data, i.title, i.trans),
+                contents: i.contents.map((e) => {
+                  return {
+                    ...e,
+                    label: getFormattedText(data, e.label, e.trans),
+                    value: getFormattedText(data, e.value, e.trans),
+                  };
+                }),
+              };
+            }),
           });
           });
-          break;
-        }
-        case 'tabs': {
-          const cfg = tabs.shift();
-          if (!cfg) break;
-          const data = getData(refData, cfg.readFrom, cfg.parser);
-
-          if (cfg.mapFromData) {
-            const firstListItem = cfg.items[0];
-            arr.push({
-              overflow: true,
-              ...item,
-              ...cfg,
-              items: (data || []).map((d) => {
-                return {
-                  title: getFormattedText(d, firstListItem.title, firstListItem.trans),
-                  contents: firstListItem.contents.map((e) => {
-                    return {
-                      ...e,
-                      label: getFormattedText(d, e.label, e.trans),
-                      value: getFormattedText(d, e.value, e.trans),
-                    };
-                  }),
-                };
-              }),
-            });
-          } else {
-            arr.push({
-              overflow: true,
-              ...item,
-              ...cfg,
-              items: cfg.items.map((i) => {
-                return {
-                  title: getFormattedText(data, i.title, i.trans),
-                  contents: i.contents.map((e) => {
-                    return {
-                      ...e,
-                      label: getFormattedText(data, e.label, e.trans),
-                      value: getFormattedText(data, e.value, e.trans),
-                    };
-                  }),
-                };
-              }),
-            });
-          }
-          break;
         }
         }
-        case 'chart': {
-          const cfg = chart.shift();
-          if (cfg?.type == 'scatter') {
-            if (!cfg) break;
-            const data = getData(mockData, cfg.readFrom, cfg.parser);
-
-            arr.push({
-              ...item,
-              config: cfg,
-              data,
-            });
-            break;
-          } else {
-            if (!cfg) break;
-            const data = getData(refData, cfg.readFrom, cfg.parser);
-            arr.push({
-              ...item,
-              config: cfg,
-              data,
-            });
-            break;
-          }
-        }
-        case 'table': {
-          const cfg = table.shift();
+        break;
+      }
+      case 'chart': {
+        const cfg = chart.shift();
+        if (cfg?.type == 'scatter') {
           if (!cfg) break;
           if (!cfg) break;
-          const data = getData(refData, cfg.readFrom, cfg.parser);
+          const data = getData(mockData, cfg.readFrom, cfg.parser);
 
 
           arr.push({
           arr.push({
-            ...cfg,
             ...item,
             ...item,
-            columns: cfg.columns,
+            config: cfg,
             data,
             data,
           });
           });
           break;
           break;
-        }
-        case 'partition': {
-          const cfg = partition.shift();
+        } else {
           if (!cfg) break;
           if (!cfg) break;
           const data = getData(refData, cfg.readFrom, cfg.parser);
           const data = getData(refData, cfg.readFrom, cfg.parser);
           arr.push({
           arr.push({
-            overflow: true,
             ...item,
             ...item,
+            config: cfg,
             data,
             data,
-            ...cfg,
           });
           });
           break;
           break;
         }
         }
-        default: {
-          const cfg = preset.shift();
-          if (!cfg) break;
-          const data = getData(refData, cfg.readFrom, cfg.parser);
+      }
+      case 'table': {
+        const cfg = table.shift();
+        if (!cfg) break;
+        const data = getData(refData, cfg.readFrom, cfg.parser);
 
 
-          arr.push({
-            ...item,
-            data,
-            config: cfg,
-          });
-          break;
-        }
+        arr.push({
+          ...cfg,
+          ...item,
+          columns: cfg.columns,
+          data,
+        });
+        break;
       }
       }
-      // console.log(arr,'arr---')
-      return arr;
-    }, []);
-  });
+      case 'partition': {
+        const cfg = partition.shift();
+        if (!cfg) break;
+        const data = getData(refData, cfg.readFrom, cfg.parser);
+        arr.push({
+          overflow: true,
+          ...item,
+          data,
+          ...cfg,
+        });
+        break;
+      }
+      default: {
+        const cfg = preset.shift();
+        if (!cfg) break;
+        const data = getData(refData, cfg.readFrom, cfg.parser);
+
+        arr.push({
+          ...item,
+          data,
+          config: cfg,
+        });
+        break;
+      }
+    }
+    // console.log(arr,'arr---')
+    return arr;
+  }, []);
+});
 </script>
 </script>
 <style lang="less" scoped>
 <style lang="less" scoped>
-  @import '@/design/theme.less';
+@import '@/design/theme.less';
 
 
-  .content {
-    height: calc(100% - 30px);
-    position: relative;
-    // z-index: -2;
-    display: flex;
-    flex-direction: column;
-    overflow-y: auto; // 这里会导致样式无故添加滚动条
-    overflow-x: hidden;
-  }
+.content {
+  height: calc(100% - 30px);
+  position: relative;
+  // z-index: -2;
+  display: flex;
+  flex-direction: column;
+  overflow-y: auto; // 这里会导致样式无故添加滚动条
+  overflow-x: hidden;
+}
 
 
-  .content__background {
-    width: 100%;
-    // height: 100%;
-    height: calc(100% - 65px);
-    position: absolute;
-    top: 65px;
-    left: 0;
-    z-index: 0;
-    object-fit: fill;
-    padding: 5px;
-    box-sizing: border-box;
-  }
+.content__background {
+  width: 100%;
+  // height: 100%;
+  height: calc(100% - 65px);
+  position: absolute;
+  top: 65px;
+  left: 0;
+  z-index: 0;
+  object-fit: fill;
+  padding: 5px;
+  box-sizing: border-box;
+}
 
 
-  .content__background_1 {
-    width: 100%;
-    height: 100%;
-    position: absolute;
-    top: 0px;
-    left: 0;
-    z-index: 0;
-    object-fit: fill;
-  }
+.content__background_1 {
+  width: 100%;
+  height: 100%;
+  position: absolute;
+  top: 0px;
+  left: 0;
+  z-index: 0;
+  object-fit: fill;
+}
 
 
-  .image__background {
-    width: 35%;
-    height: 61%;
-    left: 30%;
-  }
+.image__background {
+  width: 35%;
+  height: 61%;
+  left: 30%;
+}
 
 
-  .content__module {
-    // margin-top: 5px;
-    // margin-bottom: 5px;
-    width: 100%;
-    height: 100%;
-  }
+.content__module {
+  // margin-top: 5px;
+  // margin-bottom: 5px;
+  width: 100%;
+  height: 100%;
+}
 
 
-  .content__module1 {
-    background: url('@/assets/images/vent/homeNew/databg/4.png');
-    background-repeat: no-repeat;
-    background-size: 100% 100%;
-    height: 129px;
-    margin-top: 20%;
-  }
+.content__module1 {
+  background: url('@/assets/images/vent/homeNew/databg/4.png');
+  background-repeat: no-repeat;
+  background-size: 100% 100%;
+  height: 129px;
+  margin-top: 20%;
+}
 
 
-  .content__moduleFire {
-    width: 100%;
-    height: 100%;
-    margin-left: -24% !important;
-  }
+.content__moduleFire {
+  width: 100%;
+  height: 100%;
+  margin-left: -24% !important;
+}
 
 
-  .content__module_dust {
-    background: url('@/assets/images/vent/homeNew/bottomBg.png');
-    background-repeat: no-repeat;
-    background-size: 100% 100%;
-    width: 100%;
-    height: 100%;
-  }
+.content__module_dust {
+  background: url('@/assets/images/vent/homeNew/bottomBg.png');
+  background-repeat: no-repeat;
+  background-size: 100% 100%;
+  width: 100%;
+  height: 100%;
+}
 
 
-  // .content__module:first-of-type {
-  //   margin-top: 0;
-  // }
-  // .content__module:last-of-type {
-  //   margin-bottom: 0;
-  // }
-  ::-webkit-scrollbar {
-    width: 5px !important;
-  }
+// .content__module:first-of-type {
+//   margin-top: 0;
+// }
+// .content__module:last-of-type {
+//   margin-bottom: 0;
+// }
+::-webkit-scrollbar {
+  width: 5px !important;
+}
 
 
-  ::-webkit-scrollbar-thumb {
-    width: 5px !important;
-  }
+::-webkit-scrollbar-thumb {
+  width: 5px !important;
+}
 
 
-  :deep(.zxm-select:not(.zxm-select-customize-input) .zxm-select-selector) {
-    /* background-color: transparent; */
-    color: #fff;
-  }
+:deep(.zxm-select:not(.zxm-select-customize-input) .zxm-select-selector) {
+  /* background-color: transparent; */
+  color: #fff;
+}
 
 
-  :deep(.zxm-select-arrow) {
-    color: #fff;
-  }
+:deep(.zxm-select-arrow) {
+  color: #fff;
+}
 
 
-  :deep(.zxm-select-selection-item) {
-    color: #fff !important;
-  }
+:deep(.zxm-select-selection-item) {
+  color: #fff !important;
+}
 
 
-  :deep(.zxm-select-selection-placeholder) {
-    color: #fff !important;
-  }
+:deep(.zxm-select-selection-placeholder) {
+  color: #fff !important;
+}
 
 
-  :deep(.dialog-overlay) {
-    width: 100%;
-    height: 100%;
-    position: unset;
-    box-shadow: unset;
-  }
+:deep(.dialog-overlay) {
+  width: 100%;
+  height: 100%;
+  position: unset;
+  box-shadow: unset;
+}
 
 
-  ::-webkit-scrollbar {
-    width: 5px !important;
-  }
+::-webkit-scrollbar {
+  width: 5px !important;
+}
 
 
-  ::-webkit-scrollbar-thumb {
-    width: 5px !important;
-  }
+::-webkit-scrollbar-thumb {
+  width: 5px !important;
+}
 </style>
 </style>

+ 56 - 59
src/views/vent/home/configurable/components/preset/RuleList.vue

@@ -1,8 +1,6 @@
 <template>
 <template>
   <div class="rule-list">
   <div class="rule-list">
-    <div class="list-title">
-      预警规则配置
-    </div>
+    <div class="list-title"> 预警规则配置 </div>
     <div class="list-content">
     <div class="list-content">
       <div class="basic-list-content">
       <div class="basic-list-content">
         <div class="content-title">
         <div class="content-title">
@@ -11,10 +9,9 @@
         <div class="table-content">
         <div class="table-content">
           <div class="content-item" v-for="(item, index) in tableData" :key="index">
           <div class="content-item" v-for="(item, index) in tableData" :key="index">
             <div class="item-text">{{ item.ruleId }}</div>
             <div class="item-text">{{ item.ruleId }}</div>
-            <div class="item-text">{{ item.ruleName }}
-            </div>
+            <div class="item-text">{{ item.ruleName }} </div>
             <div class="item-text item-text1">{{ item.fctj }}</div>
             <div class="item-text item-text1">{{ item.fctj }}</div>
-            <div class="item-text ">
+            <div class="item-text">
               <a-switch v-model:checked="item.status" size="small" />
               <a-switch v-model:checked="item.status" size="small" />
             </div>
             </div>
             <div class="item-text">
             <div class="item-text">
@@ -24,8 +21,8 @@
         </div>
         </div>
       </div>
       </div>
       <div class="basic-list-content">
       <div class="basic-list-content">
-         <basicBorder :widthV="298" colorV="orange" title="【编辑规则】一级温度报警(Rule-001)">
-            <div class="temp-warn">
+        <basicBorder :widthV="298" colorV="orange" title="【编辑规则】一级温度报警(Rule-001)">
+          <div class="temp-warn">
             <div class="warn-item">
             <div class="warn-item">
               <div class="item-label">规则名称 : </div>
               <div class="item-label">规则名称 : </div>
               <a-input class="item-input" v-model:value="rulesData.ruleName" placeholder="请输入" size="small" />
               <a-input class="item-input" v-model:value="rulesData.ruleName" placeholder="请输入" size="small" />
@@ -46,16 +43,16 @@
               <div class="item-label">联动动作 : </div>
               <div class="item-label">联动动作 : </div>
               <a-input class="item-input" v-model:value="rulesData.lddz" placeholder="请输入" size="small" />
               <a-input class="item-input" v-model:value="rulesData.lddz" placeholder="请输入" size="small" />
             </div>
             </div>
-             <div class="warn-item">
+            <div class="warn-item">
               <div class="item-label">通知对象 : </div>
               <div class="item-label">通知对象 : </div>
               <a-input class="item-input" v-model:value="rulesData.person" placeholder="请输入" size="small" />
               <a-input class="item-input" v-model:value="rulesData.person" placeholder="请输入" size="small" />
             </div>
             </div>
-             <div class="btn-box">
-        <div class="baisc-btn">取消</div>
-        <div class="baisc-btn">
-          <div class="btn-item">保存</div>
-        </div>
-      </div>
+            <div class="btn-box">
+              <div class="baisc-btn">取消</div>
+              <div class="baisc-btn">
+                <div class="btn-item">保存</div>
+              </div>
+            </div>
           </div>
           </div>
         </basicBorder>
         </basicBorder>
       </div>
       </div>
@@ -64,9 +61,9 @@
 </template>
 </template>
 
 
 <script setup lang="ts">
 <script setup lang="ts">
-import { reactive, ref } from 'vue'
-import basicBorder from '../BasicBorder.vue'
-import { rules } from '/@/utils/helper/validator.js'
+import { reactive, ref } from 'vue';
+import basicBorder from '../BasicBorder.vue';
+import { rules } from '/@/utils/helper/validator.js';
 
 
 let titleList = ref<any[]>([
 let titleList = ref<any[]>([
   { label: '规则ID', value: '1' },
   { label: '规则ID', value: '1' },
@@ -74,33 +71,34 @@ let titleList = ref<any[]>([
   { label: '触发条件', value: '3' },
   { label: '触发条件', value: '3' },
   { label: '启用', value: '4' },
   { label: '启用', value: '4' },
   { label: '操作', value: '5' },
   { label: '操作', value: '5' },
-])
+]);
 let tableData = ref<any[]>([
 let tableData = ref<any[]>([
-  { ruleId: 'Rule-001', ruleName: '一级温度报警', fctj: '温度>=60℃', status: true, },
-  { ruleId: 'Rule-001', ruleName: '一级温度报警', fctj: '温度>=60℃', status: true, },
-  { ruleId: 'Rule-001', ruleName: '一级温度报警', fctj: '温度>=60℃', status: false, },
-  { ruleId: 'Rule-001', ruleName: '一级温度报警', fctj: '温度>=60℃', status: true, },
-  { ruleId: 'Rule-001', ruleName: '一级温度报警', fctj: '温度>=60℃', status: true, },
-  { ruleId: 'Rule-001', ruleName: '一级温度报警', fctj: '温度>=60℃', status: true, },
-  { ruleId: 'Rule-001', ruleName: '一级温度报警', fctj: '温度>=60℃', status: true, },
-  { ruleId: 'Rule-001', ruleName: '一级温度报警', fctj: '温度>=60℃', status: true, },
-  { ruleId: 'Rule-001', ruleName: '一级温度报警', fctj: '温度>=60℃', status: true, },
-])
-let rulesData=reactive({
-ruleName:'',
-grade:'',
-temp:'',
-time:'',
-lddz:'',
-person:'',
-})
+  { ruleId: 'Rule-001', ruleName: '一级温度报警', fctj: '温度>=60℃', status: true },
+  { ruleId: 'Rule-001', ruleName: '一级温度报警', fctj: '温度>=60℃', status: true },
+  { ruleId: 'Rule-001', ruleName: '一级温度报警', fctj: '温度>=60℃', status: false },
+  { ruleId: 'Rule-001', ruleName: '一级温度报警', fctj: '温度>=60℃', status: true },
+  { ruleId: 'Rule-001', ruleName: '一级温度报警', fctj: '温度>=60℃', status: true },
+  { ruleId: 'Rule-001', ruleName: '一级温度报警', fctj: '温度>=60℃', status: true },
+  { ruleId: 'Rule-001', ruleName: '一级温度报警', fctj: '温度>=60℃', status: true },
+  { ruleId: 'Rule-001', ruleName: '一级温度报警', fctj: '温度>=60℃', status: true },
+  { ruleId: 'Rule-001', ruleName: '一级温度报警', fctj: '温度>=60℃', status: true },
+]);
+let rulesData = reactive({
+  ruleName: '',
+  grade: '',
+  temp: '',
+  time: '',
+  lddz: '',
+  person: '',
+});
 </script>
 </script>
 
 
 <style lang="less" scoped>
 <style lang="less" scoped>
 @import '/@/design/theme.less';
 @import '/@/design/theme.less';
 
 
 @{theme-deepblue} {
 @{theme-deepblue} {
-  .rule-list {}
+  .rule-list {
+  }
 }
 }
 
 
 .rule-list {
 .rule-list {
@@ -109,19 +107,18 @@ person:'',
   position: relative;
   position: relative;
   width: 100%;
   width: 100%;
   height: 100%;
   height: 100%;
-  padding: 15px;
+  padding: 10px 15px;
   box-sizing: border-box;
   box-sizing: border-box;
 
 
   .list-title {
   .list-title {
     width: 177px;
     width: 177px;
     height: 30px;
     height: 30px;
     line-height: 22px;
     line-height: 22px;
-    padding-left: 16px;
     color: #01fefc;
     color: #01fefc;
     font-weight: bolder;
     font-weight: bolder;
     background: var(--image-box-bg) no-repeat;
     background: var(--image-box-bg) no-repeat;
-    background-size: 100% 100%;
-    margin-bottom: 5px;
+    background-size: 80% 100%;
+    margin-bottom: 10px;
   }
   }
 
 
   .list-content {
   .list-content {
@@ -154,11 +151,11 @@ person:'',
     justify-content: center;
     justify-content: center;
     align-items: center;
     align-items: center;
     color: #01fefc;
     color: #01fefc;
-    &:nth-child(2){
-      flex:1.5
+    &:nth-child(2) {
+      flex: 1.5;
     }
     }
-    &:nth-child(3){
-      flex:1.5
+    &:nth-child(3) {
+      flex: 1.5;
     }
     }
   }
   }
 
 
@@ -188,16 +185,16 @@ person:'',
     flex: 1;
     flex: 1;
     justify-content: center;
     justify-content: center;
     align-items: center;
     align-items: center;
-    &:nth-child(2){
-        flex:1.5
+    &:nth-child(2) {
+      flex: 1.5;
     }
     }
-     &:nth-child(3){
-        flex:1.5
+    &:nth-child(3) {
+      flex: 1.5;
     }
     }
   }
   }
 
 
   .item-text1 {
   .item-text1 {
-     color: orange;
+    color: orange;
   }
   }
   .text-look {
   .text-look {
     padding: 0px 3px;
     padding: 0px 3px;
@@ -206,12 +203,12 @@ person:'',
     background-color: #2484bc;
     background-color: #2484bc;
     cursor: pointer;
     cursor: pointer;
   }
   }
-  .temp-warn{
+  .temp-warn {
     position: relative;
     position: relative;
     height: 100%;
     height: 100%;
   }
   }
-   .warn-item {
-   display: flex;
+  .warn-item {
+    display: flex;
     align-items: center;
     align-items: center;
     height: 30px;
     height: 30px;
     background: linear-gradient(to right, #134c77, transparent);
     background: linear-gradient(to right, #134c77, transparent);
@@ -223,7 +220,7 @@ person:'',
       margin-bottom: 0;
       margin-bottom: 0;
     }
     }
   }
   }
-   .item-label {
+  .item-label {
     width: 100px;
     width: 100px;
     text-align: right;
     text-align: right;
     margin-right: 5px;
     margin-right: 5px;
@@ -233,8 +230,8 @@ person:'',
     border: 1px solid #2792c2;
     border: 1px solid #2792c2;
     color: #fff;
     color: #fff;
   }
   }
-   .btn-box {
-   width: 140px;
+  .btn-box {
+    width: 140px;
     display: flex;
     display: flex;
     justify-content: space-between;
     justify-content: space-between;
     align-items: center;
     align-items: center;
@@ -244,7 +241,7 @@ person:'',
   }
   }
 
 
   .baisc-btn {
   .baisc-btn {
-   display: flex;
+    display: flex;
     justify-content: center;
     justify-content: center;
     align-items: center;
     align-items: center;
     width: 65px;
     width: 65px;
@@ -263,7 +260,7 @@ person:'',
     height: 100%;
     height: 100%;
     background-color: rgba(32, 166, 169);
     background-color: rgba(32, 166, 169);
   }
   }
-   ::-webkit-scrollbar{
+  ::-webkit-scrollbar {
     display: none;
     display: none;
   }
   }
 }
 }

+ 243 - 0
src/views/vent/home/configurable/components/preset/linkLog.vue

@@ -0,0 +1,243 @@
+<template>
+  <div class="search-table">
+    <div class="list-title">
+      <span>联动日志</span>
+    </div>
+    <div class="search-area">
+      <div class="title-top">
+        <a-input v-model:value="searchWarn" placeholder="搜索" size="small" class="zxm-input zxm-input-sm" />
+        <div class="search-btn">
+          <div class="btn-item">筛选</div>
+        </div>
+      </div>
+    </div>
+
+    <div class="time-select">
+      <span class="span">时间范围:</span>
+      <div class="btn" :class="{ active: timeType === 1 }" @click="timeType = 1">今日</div>
+      <div class="btn" :class="{ active: timeType === 2 }" @click="timeType = 2">近三天</div>
+      <div class="btn" :class="{ active: timeType === 3 }" @click="timeType = 3">近七天</div>
+      <div class="btn" :class="{ active: timeType === 4 }" @click="timeType = 4">自定义</div>
+    </div>
+    <div class="content-area">
+      <div class="content-title">
+        <div class="title-item col-time">时间</div>
+        <div class="title-item col-rule">规则</div>
+        <div class="title-item col-grade">动作</div>
+        <div class="title-item col-status">说明</div>
+      </div>
+      <div class="history-content">
+        <div class="content-item" v-for="(item, index) in tableData" :key="index">
+          <div class="item-text col-time">{{ item.time }}</div>
+          <div class="item-text col-rule">{{ item.rule }} </div>
+          <div class="item-text col-grade item-text2">{{ item.grade }}</div>
+          <div class="item-text col-status item-text1">{{ item.status }}</div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ref } from 'vue';
+
+let searchWarn = ref('');
+const timeType = ref(1);
+let tableData = ref<any[]>([
+  { time: '14:31:22', rule: '001', grade: '触发', status: '温度65.3℃超过阈值' },
+  { time: '14:31:22', rule: '001', grade: '触发', status: '温度65.3℃超过阈值' },
+  { time: '14:31:22', rule: '001', grade: '触发', status: '温度65.3℃超过阈值' },
+  { time: '14:31:22', rule: '001', grade: '触发', status: '温度65.3℃超过阈值' },
+  { time: '14:31:22', rule: '001', grade: '触发', status: '温度65.3℃超过阈值' },
+  { time: '14:31:22', rule: '001', grade: '触发', status: '温度65.3℃超过阈值' },
+  { time: '14:31:22', rule: '001', grade: '触发', status: '温度65.3℃超过阈值' },
+  { time: '14:31:22', rule: '001', grade: '触发', status: '温度65.3℃超过阈值' },
+  { time: '14:31:22', rule: '001', grade: '触发', status: '温度65.3℃超过阈值' },
+]);
+</script>
+
+<style lang="less" scoped>
+@import '/@/design/theme.less';
+
+@{theme-deepblue} {
+  .search-table {
+  }
+}
+
+.search-table {
+  --image-box-bg: url('@/assets/images/home-container/configurable/hsq/2-5.png');
+  --image-box-bg1: url('@/assets/images/home-container/configurable/hsq/2-6.png');
+  --image-box-bg2: url('@/assets/images/home-container/configurable/hsq/2-24.png');
+  position: relative;
+  width: 100%;
+  height: 100%;
+  padding: 15px;
+  box-sizing: border-box;
+}
+
+.list-title {
+  width: 177px;
+  height: 30px;
+  line-height: 22px;
+  color: #01fefc;
+  font-weight: bolder;
+  background: var(--image-box-bg) no-repeat;
+  background-size: 80% 100%;
+  margin-bottom: 5px;
+}
+
+/* 搜索区域:内部横向排列 */
+.search-area {
+  margin-bottom: 5px;
+}
+.title-top {
+  display: flex;
+  align-items: center;
+  gap: 10px;
+}
+
+.search-btn {
+  width: 85px;
+  height: 30px;
+  border: 1px solid #01fefc;
+  border-radius: 4px;
+  padding: 3px;
+  cursor: pointer;
+}
+
+.time-select {
+  display: flex;
+  align-items: center;
+  padding-left: 10px;
+  margin-bottom: 8px;
+  gap: 6px;
+  white-space: nowrap;
+
+  .span {
+    color: #fff;
+    font-size: 13px;
+  }
+
+  .btn {
+    padding: 3px 8px;
+    background: #114268;
+    border: 1px solid transparent;
+    border-radius: 4px;
+    color: #fff;
+    cursor: pointer;
+    margin-right: 4px;
+    font-size: 13px;
+    white-space: nowrap;
+    transition: all 0.2s;
+
+    &.active {
+      background-color: #185f8e;
+      border-color: #2084c0;
+    }
+  }
+}
+
+.btn-item {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  width: 100%;
+  height: 100%;
+  background-color: rgba(32, 166, 169);
+}
+
+.content-area {
+  height: calc(100% - 120px);
+}
+
+.content-title {
+  display: flex;
+  align-items: center;
+  height: 34px;
+  background: var(--image-box-bg2) no-repeat;
+  background-size: 100% 100%;
+  margin-bottom: 6px;
+}
+
+.title-item {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  color: #01fefc;
+}
+
+.history-content {
+  height: calc(100% - 40px);
+  overflow-y: auto;
+}
+
+.content-item {
+  display: flex;
+  align-items: center;
+  height: 36px;
+
+  &:nth-child(odd) {
+    background-color: #0e3455;
+  }
+
+  &:nth-child(even) {
+    background-color: #114268;
+  }
+}
+
+.item-text {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+
+.col-time {
+  width: 90px;
+  flex-shrink: 0;
+}
+.col-rule {
+  width: 70px;
+  flex-shrink: 0;
+}
+.col-grade {
+  width: 70px;
+  flex-shrink: 0;
+}
+.col-status {
+  flex: 1;
+  padding: 0 10px;
+  justify-content: center;
+}
+
+.item-text1 {
+  color: #fc002a;
+}
+
+.item-text2 {
+  color: orange;
+}
+
+.text-look {
+  padding: 0px 3px;
+  margin: 0px 2px;
+  border-radius: 2px;
+  background-color: #2484bc;
+  cursor: pointer;
+}
+
+.zxm-input {
+  height: 42px;
+  color: #fff;
+  background-color: transparent;
+  border: none;
+  background: var(--image-box-bg1) no-repeat;
+  background-size: 100% 100%;
+}
+
+.zxm-input-sm {
+  padding: 0px 20px;
+}
+</style>

+ 528 - 0
src/views/vent/home/configurable/components/preset/linkRuleEdit.vue

@@ -0,0 +1,528 @@
+<template>
+  <div class="long-list1">
+    <div class="list-title">
+      <span>联动规则编辑器</span>
+    </div>
+    <div class="basic-box">
+      <basicBorder title="触发条件设置">
+        <div class="edit-wrap">
+          <div class="edit-left">
+            <div class="edit-item">
+              <div class="item-label">规则名称 : </div>
+              <a-input class="item-input" v-model:value="formData.gzmc" placeholder="请输入" size="small" />
+            </div>
+            <div class="edit-item">
+              <div class="item-label">报警级别 : </div>
+              <a-input class="item-input" v-model:value="formData.bjjb" placeholder="请输入" size="small" />
+            </div>
+            <div class="edit-item">
+              <div class="item-label">温度阈值 : </div>
+              <a-input class="item-input" v-model:value="formData.wdyz" placeholder="请输入" size="small" />
+            </div>
+            <div class="edit-item">
+              <div class="item-label">触发设备 : </div>
+              <a-input class="item-input" v-model:value="formData.cfsb" placeholder="请输入" size="small" />
+            </div>
+            <div class="edit-item">
+              <div class="item-label">持续时间 : </div>
+              <a-input class="item-input" v-model:value="formData.time" placeholder="请输入" size="small" />
+            </div>
+            <div class="edit-item">
+              <div class="item-label">时间范围 : </div>
+              <a-input class="item-input" v-model:value="formData.sjfw" placeholder="请输入" size="small" />
+            </div>
+          </div>
+          <div class="edit-right">
+            <div class="right-title">条件逻辑说明</div>
+            <div class="right-content">
+              <div class="right-item">IF 温度≥{{ formData.wdyz || 60 }}℃</div>
+              <div class="right-item">AND 持续时间≥{{ formData.time || 30 }}s</div>
+              <div class="right-item">AND 设备状态-在线</div>
+              <div class="right-item">AND 时间在生效范围内</div>
+              <div class="right-item">THEN 执行联动动作</div>
+              <div class="right-item">【优先级:高】</div>
+              <div class="right-item">此规则触发后将阻断低优先级</div>
+            </div>
+          </div>
+        </div>
+      </basicBorder>
+    </div>
+    <div class="basic-box1">
+      <basicBorder title="联动动作设置">
+        <div class="basic-table">
+          <div class="table-title">
+            <div class="title-item" v-for="(item, index) in titleList" :key="index">{{ item.label }}</div>
+          </div>
+          <div class="table-content">
+            <div class="content-item" v-for="(item, index) in tableData" :key="index">
+              <div class="item-text">{{ item.indnex }}</div>
+              <div class="item-text item-text1">
+                <span>{{ item.actionType }}</span>
+              </div>
+              <div class="item-text">
+                <span> {{ item.action }}</span>
+              </div>
+              <div class="item-text">
+                <div class="switch" :class="{ active: item.qy === 1 }">
+                  <div class="switch-dot"></div>
+                </div>
+              </div>
+              <div class="item-text">{{ item.delayTime }}</div>
+              <div class="item-text">{{ item.duration }}</div>
+              <div class="item-text">
+                <span class="text-look">查看</span>
+              </div>
+            </div>
+          </div>
+        </div>
+      </basicBorder>
+    </div>
+    <div class="basic-box2">
+      <basicBorder title="联动执行流程图">
+        <div class="workflow-container">
+          <div class="steps-wrapper">
+            <div v-for="(step, index) in steps" :key="index" class="step-item">
+              <div class="step-icon" :class="`icon-${step.id}`"></div>
+              <div class="step-frame" :class="`frame-${step.id}`">
+                <span class="step-text">{{ step.name }}</span>
+              </div>
+              <!-- 底部小圆点 -->
+              <div class="step-dot">
+                <div class="dot" :class="{ active: step.status === 1 }"></div>
+              </div>
+              <div class="steps-arrow"></div>
+            </div>
+          </div>
+        </div>
+      </basicBorder>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { reactive, ref, onMounted } from 'vue';
+import basicBorder from '../BasicBorder.vue';
+
+let titleList = ref<any[]>([
+  { label: '序号', value: '1' },
+  { label: '动作类型', value: '2' },
+  { label: '动作说明', value: '3' },
+  { label: '启用', value: '4' },
+  { label: '延迟', value: '5' },
+  { label: '持续', value: '6' },
+  { label: '操作', value: '7' },
+]);
+
+let tableData = ref<any[]>([
+  { indnex: '1', actionType: '声光报警器', action: '触发报警声+红色闪烁', qy: 1, delayTime: '0s', duration: '300s' },
+  { indnex: '2', actionType: '声光报警器', action: '触发报警声', qy: 1, delayTime: '1s', duration: '200s' },
+  { indnex: '3', actionType: '声光报警器', action: '红色闪烁', qy: 0, delayTime: '2s', duration: '180s' },
+]);
+
+// 流程图,添加 status 字段
+const steps = ref([
+  { id: 'alarm', name: '报警触发', status: 0 },
+  { id: 'condition', name: '条件判断', status: 0 },
+  { id: 'search', name: '查找规则', status: 0 },
+  { id: 'action', name: '执行动作', status: 0 },
+  { id: 'log', name: '记录日志', status: 0 },
+]);
+
+// 模拟接口请求获取步骤状态
+const fetchStepStatus = async () => {
+  // 模拟 API 返回的数据,实际使用时替换为真实接口
+  const apiResponse = {
+    alarmTrigger: 1, // 报警触发为 1
+    conditionJudge: 0, // 条件判断为 1
+    searchRule: 0, // 查找规则为 0
+    executeAction: 0, // 执行动作为 0
+    recordLog: 0, // 记录日志为 0
+  };
+
+  // 根据接口返回数据更新状态
+  steps.value[0].status = apiResponse.alarmTrigger;
+  steps.value[1].status = apiResponse.conditionJudge;
+  steps.value[2].status = apiResponse.searchRule;
+  steps.value[3].status = apiResponse.executeAction;
+  steps.value[4].status = apiResponse.recordLog;
+};
+let formData = reactive({
+  gzmc: '一级温度报警',
+  bjjb: '一级(严重)',
+  wdyz: '50',
+  cfsb: '声光报警',
+  time: '≥35',
+  sjfw: '值班人员',
+});
+// const formData = ref({
+//   gzmc: '',
+//   bjjb: '',
+//   wdyz: '',
+//   cfsb: '',
+//   time: '',
+//   sjfw: '',
+// });
+onMounted(() => {
+  fetchStepStatus();
+});
+</script>
+
+<style lang="less" scoped>
+@import '/@/design/theme.less';
+
+.long-list1 {
+  --image-box-bg: url('@/assets/images/home-container/configurable/hsq/2-5.png');
+  --image-box-bg1: url('@/assets/images/home-container/configurable/hsq/2-13.png');
+  --image-box-bg2: url('@/assets/images/home-container/configurable/hsq/2-14.png');
+  --image-box-bg3: url('@/assets/images/home-container/configurable/hsq/2-15.png');
+  --image-box-bg4: url('@/assets/images/home-container/configurable/hsq/2-16.png');
+  --image-box-bg5: url('@/assets/images/home-container/configurable/hsq/2-17.png');
+  --image-box-bg6: url('@/assets/images/home-container/configurable/hsq/2-24.png');
+
+  position: relative;
+  width: 100%;
+  height: 100%;
+  padding: 15px 30px;
+  box-sizing: border-box;
+  display: flex;
+  flex-direction: column;
+  .item-input {
+    background: transparent !important;
+    background: linear-gradient(to right, #114469, #0b2542) !important;
+    color: #fff;
+    border: 1px solid #2690c1 !important;
+    border-radius: 5px;
+    &:hover,
+    &:focus {
+      background: transparent !important;
+    }
+    box-shadow: none !important;
+  }
+  .basic-box1,
+  .basic-box2 {
+    margin-top: 10px;
+  }
+  .edit-wrap {
+    display: flex;
+    width: 100%;
+    height: 100%;
+    gap: 10px;
+    box-sizing: border-box;
+  }
+  .edit-left {
+    flex: 1;
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+    margin: 5px;
+  }
+
+  .edit-item {
+    display: flex;
+    align-items: center;
+    height: 32px;
+    background: linear-gradient(to right, #114469, #0b2542) !important;
+    margin-bottom: 10px;
+    padding: 0 10px;
+    box-sizing: border-box;
+    &:last-child {
+      margin-bottom: 10px;
+    }
+  }
+
+  .item-label {
+    width: 80px;
+    text-align: right;
+    margin-right: 5px;
+  }
+  .edit-right {
+    background: #0e395d;
+    width: 50%;
+    height: 93%;
+    display: flex;
+    flex-direction: column;
+    margin-right: 20px;
+  }
+
+  .right-title {
+    display: flex;
+    align-items: center;
+    width: 146px;
+    height: 30px;
+    color: #fff;
+    padding-left: 15px;
+    background: var(--image-box-bg) no-repeat;
+    background-size: 100% 100%;
+    font-size: 15px;
+    font-weight: bold;
+    line-height: 24px;
+  }
+
+  .right-content {
+    flex: 1;
+    display: flex;
+    flex-direction: column;
+    margin-top: 5px;
+    margin-left: 10px;
+  }
+
+  .right-item {
+    color: #fff;
+    font-size: 14px;
+    line-height: 25px;
+    font-weight: bold;
+    padding: 0 5px;
+  }
+  .right-item:nth-child(1) {
+    color: #fc002a;
+  }
+  .right-item:nth-child(2),
+  .right-item:nth-child(3),
+  .right-item:nth-child(4) {
+    color: #29a1d4;
+  }
+  .right-item:nth-child(5) {
+    color: #46e8a3;
+  }
+  .right-item:nth-child(6) {
+    margin-top: 10px;
+  }
+  .list-title {
+    width: 177px;
+    height: 30px;
+    line-height: 22px;
+    padding-left: 5px;
+    padding-bottom: 5px;
+    color: #01fefc;
+    font-weight: bolder;
+    background: var(--image-box-bg) no-repeat;
+    background-size: 80% 100%;
+    margin-bottom: 5px;
+  }
+
+  .basic-table {
+    height: 100%;
+  }
+
+  .item-label1 {
+    width: 105px;
+    text-align: right;
+    margin-right: 5px;
+  }
+  .table-title {
+    display: flex;
+    align-items: center;
+    height: 34px;
+    background: var(--image-box-bg6) no-repeat;
+    background-size: 100% 100%;
+    margin-bottom: 6px;
+  }
+
+  .title-item {
+    flex: 1;
+    min-width: 60px;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    color: #01fefc;
+    white-space: nowrap;
+    padding: 0 6px;
+  }
+
+  .table-content {
+    height: calc(100% - 40px);
+    overflow-y: auto;
+  }
+
+  .content-item {
+    display: flex;
+    align-items: center;
+    height: 36px;
+    &:nth-child(odd) {
+      background-color: #0e3455;
+    }
+    &:nth-child(even) {
+      background-color: #114268;
+    }
+  }
+
+  .item-text {
+    flex: 1;
+    min-width: 60px;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    color: #fff;
+    white-space: nowrap;
+    padding: 0 6px;
+  }
+
+  .item-text1 {
+    color: #fc002a;
+  }
+  .item-text2 {
+    color: orange;
+  }
+
+  .switch {
+    width: 36px;
+    height: 18px;
+    border-radius: 9px;
+    background: none;
+    position: relative;
+    transition: all 0.2s ease;
+    cursor: pointer;
+    border: 1px solid #35d9e5;
+    .switch-dot {
+      width: 14px;
+      height: 14px;
+      border-radius: 50%;
+      background: #fff;
+      position: absolute;
+      top: 1px;
+      left: 1px;
+      transition: all 0.2s ease;
+    }
+  }
+  .switch.active .switch-dot {
+    left: 20px;
+  }
+
+  .text-look {
+    color: #01fefc;
+    cursor: pointer;
+  }
+}
+
+/*流程图*/
+.workflow-container {
+  width: 100%;
+  padding: 20px 0;
+  position: relative;
+}
+
+.steps-wrapper {
+  display: flex;
+  justify-content: space-between;
+  align-items: flex-end;
+  padding: 0 20px;
+  position: relative;
+  z-index: 2;
+  &::before {
+    content: '';
+    position: absolute;
+    left: 12%;
+    right: calc(50% - 12px);
+    top: 95%;
+    transform: translateY(-50%);
+    height: 2px;
+    background: #4a9eff;
+    z-index: 1;
+  }
+  &::after {
+    content: '';
+    position: absolute;
+    left: calc(50% + 12px);
+    right: 12%;
+    top: 95%;
+    transform: translateY(-50%);
+    height: 2px;
+    background: #4a9eff;
+    z-index: 1;
+  }
+  .steps-arrow {
+    position: absolute;
+    left: 5%;
+    top: 95%;
+    transform: translate(-50%, -50%);
+    width: 24px;
+    height: 24px;
+    background: url('@/assets/images/home-container/configurable/hsq/arrow.svg') center / contain no-repeat;
+    z-index: 2;
+  }
+  .step-item:first-child .steps-arrow {
+    display: none;
+  }
+}
+.step-item {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  flex: 1;
+  position: relative;
+}
+
+.step-icon {
+  width: 56px;
+  height: 56px;
+  background-size: contain;
+  background-repeat: no-repeat;
+  background-position: center;
+  margin-bottom: -6px;
+}
+
+.icon-alarm {
+  background-image: url('@/assets/images/home-container/configurable/hsq/bjcf.png');
+}
+.icon-condition {
+  background-image: url('@/assets/images/home-container/configurable/hsq/tjpd.png');
+}
+.icon-search {
+  background-image: url('@/assets/images/home-container/configurable/hsq/czgz.png');
+}
+.icon-action {
+  background-image: url('@/assets/images/home-container/configurable/hsq/zxdz.png');
+}
+.icon-log {
+  background-image: url('@/assets/images/home-container/configurable/hsq/jlrz.png');
+}
+
+.step-frame {
+  position: relative;
+  width: 100%;
+  max-width: 120px;
+  padding: 2px;
+  background-image: url('@/assets/images/home-container/configurable/hsq/3-6.png');
+  background-size: 100% 100%;
+  background-repeat: no-repeat;
+  background-position: center;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  margin-bottom: 5px;
+}
+
+.step-text {
+  font-size: 14px;
+  font-weight: 500;
+  color: #fff;
+  text-align: center;
+  position: relative;
+  z-index: 1;
+}
+
+.step-dot {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  position: relative;
+  z-index: 3;
+  background: transparent;
+  width: 12px;
+  height: 12px;
+}
+
+.dot {
+  width: 10px;
+  height: 10px;
+  border-radius: 50%;
+  background: #2c5a8c;
+  border: 1px solid #4a9eff;
+  transition: all 0.3s ease;
+}
+.dot.active {
+  background: #4facfe;
+  border-color: #4facfe;
+  box-shadow: 0 0 6px rgba(79, 172, 254, 0.6);
+}
+</style>

+ 149 - 0
src/views/vent/home/configurable/components/preset/ruleNum.vue

@@ -0,0 +1,149 @@
+<template>
+  <div class="long-list">
+    <div class="list-title">
+      <span>规则统计</span>
+    </div>
+    <div class="list-content">
+      <div class="stat-item blue">
+        <div class="icon-wrap icon-1"></div>
+        <div class="label-wrap">
+          <span>总规则</span>
+        </div>
+        <div class="num-wrap">
+          <span>10</span>
+        </div>
+      </div>
+      <div class="stat-item green">
+        <div class="icon-wrap icon-2"></div>
+        <div class="label-wrap">
+          <span>已启用</span>
+        </div>
+        <div class="num-wrap">
+          <span>7</span>
+        </div>
+      </div>
+      <div class="stat-item green">
+        <div class="icon-wrap icon-3"></div>
+        <div class="label-wrap">
+          <span>已禁用</span>
+        </div>
+        <div class="num-wrap">
+          <span>2</span>
+        </div>
+      </div>
+      <div class="stat-item blue">
+        <div class="icon-wrap icon-4"></div>
+        <div class="label-wrap">
+          <span>触发中</span>
+        </div>
+        <div class="num-wrap">
+          <span>2</span>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ref } from 'vue';
+</script>
+
+<style lang="less" scoped>
+@import '/@/design/theme.less';
+
+.long-list {
+  --image-box-bg: url('@/assets/images/home-container/configurable/hsq/2-5.png');
+  --image-box-bg-green: url('@/assets/images/home-container/configurable/hsq/4-2.png');
+  --image-box-bg-blue: url('@/assets/images/home-container/configurable/hsq/4-3.png');
+  --image-box-svg1: url('@/assets/images/home-container/configurable/hsq/4-total.svg');
+  --image-box-svg2: url('@/assets/images/home-container/configurable/hsq/4-cf.svg');
+  --image-box-svg3: url('@/assets/images/home-container/configurable/hsq/4-qy.svg');
+  --image-box-svg4: url('@/assets/images/home-container/configurable/hsq/4-jy.svg');
+
+  position: relative;
+  width: 100%;
+  height: 100%;
+  padding: 15px 15px;
+  box-sizing: border-box;
+  .list-title {
+    width: 177px;
+    height: 30px;
+    line-height: 22px;
+    color: #01fefc;
+    font-weight: bolder;
+    background: var(--image-box-bg) no-repeat;
+    background-size: 80% 100%;
+    margin-bottom: 10px;
+  }
+
+  .list-content {
+    display: flex;
+    flex-wrap: wrap;
+    gap: 20px;
+  }
+
+  .stat-item {
+    width: calc(50% - 10px);
+    display: flex;
+    align-items: center;
+    height: 40px;
+    padding-left: 6px;
+    box-sizing: border-box;
+    background-repeat: no-repeat;
+    background-position: center;
+    background-size: 100% 100%;
+
+    &.blue {
+      background-image: var(--image-box-bg-blue);
+    }
+    &.green {
+      background-image: var(--image-box-bg-green);
+    }
+  }
+
+  .icon-wrap {
+    width: 30px;
+    height: 30px;
+    flex-shrink: 0;
+    background-repeat: no-repeat;
+    background-position: center;
+    background-size: 60% 70%;
+
+    &.icon-1 {
+      background-image: var(--image-box-svg1);
+    }
+    &.icon-2 {
+      background-image: var(--image-box-svg3);
+    }
+    &.icon-3 {
+      background-image: var(--image-box-svg4);
+    }
+    &.icon-4 {
+      background-image: var(--image-box-svg2);
+    }
+  }
+
+  .label-wrap {
+    margin-left: 10px;
+    flex: 1;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    color: #fff;
+    font-size: 14px;
+    white-space: nowrap;
+  }
+
+  .num-wrap {
+    width: 100px;
+    height: 100%;
+    flex-shrink: 0;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    color: #fff;
+    font-size: 16px;
+    font-weight: bold;
+  }
+}
+</style>

+ 191 - 0
src/views/vent/home/configurable/components/preset/ruleTable.vue

@@ -0,0 +1,191 @@
+<template>
+  <div class="search-table">
+    <div class="search-area">
+      <div class="list-title">
+        <span>联动规则列表</span>
+      </div>
+      <div class="search-btn">
+        <div class="btn-item">新增</div>
+      </div>
+    </div>
+    <div class="content-area">
+      <div class="content-title">
+        <div class="title-item" v-for="(item, index) in titleList" :key="index">{{ item.label }}</div>
+      </div>
+      <div class="history-content">
+        <div class="content-item" v-for="(item, index) in tableData" :key="index">
+          <div class="item-text">{{ item.time }}</div>
+          <div class="item-text">{{ item.address }} </div>
+          <div class="item-text item-text1">{{ item.grade }}</div>
+          <div class="item-text">{{ item.action }}</div>
+          <div class="item-text item-text2">{{ item.status }}</div>
+          <div class="item-text">
+            <span class="text-look">确认</span>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ref } from 'vue';
+
+let searchWarn = ref('');
+let titleList = ref<any[]>([
+  { label: '规则ID', value: '1' },
+  { label: '规则名称', value: '2' },
+  { label: '触发条件', value: '3' },
+  { label: '联动动作', value: '4' },
+  { label: '状态', value: '5' },
+  { label: '操作', value: '6' },
+]);
+let tableData = ref<any[]>([
+  { time: 'LINK001', address: '温度报警联动', grade: '温度>60℃', action: '声光报警', status: '启用' },
+  { time: 'LINK001', address: '温度报警联动', grade: '温度>60℃', action: '声光报警', status: '启用' },
+  { time: 'LINK001', address: '温度报警联动', grade: '温度>60℃', action: '声光报警', status: '启用' },
+  { time: 'LINK001', address: '温度报警联动', grade: '温度>60℃', action: '声光报警', status: '启用' },
+  { time: 'LINK001', address: '温度报警联动', grade: '温度>60℃', action: '声光报警', status: '启用' },
+  { time: 'LINK001', address: '温度报警联动', grade: '温度>60℃', action: '声光报警', status: '启用' },
+  { time: 'LINK001', address: '温度报警联动', grade: '温度>60℃', action: '声光报警', status: '启用' },
+]);
+</script>
+
+<style lang="less" scoped>
+@import '/@/design/theme.less';
+
+.search-table {
+  --image-box-bg: url('@/assets/images/home-container/configurable/hsq/2-5.png');
+  --image-box-bg1: url('@/assets/images/home-container/configurable/hsq/2-6.png');
+  --image-box-bg2: url('@/assets/images/home-container/configurable/hsq/2-24.png');
+  position: relative;
+  width: 100%;
+  height: 100%;
+  padding: 10px;
+  box-sizing: border-box;
+}
+.list-title {
+  width: 177px;
+  height: 30px;
+  line-height: 22px;
+  color: #01fefc;
+  font-weight: bolder;
+  background: var(--image-box-bg) no-repeat;
+  background-size: 80% 100%;
+  margin-bottom: 5px;
+}
+.search-area {
+  height: 42px;
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 5px;
+}
+
+.search-btn {
+  width: 85px;
+  height: 30px;
+  border: 1px solid #01fefc;
+  border-radius: 4px;
+  padding: 3px;
+  cursor: pointer;
+}
+
+.btn-item {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  width: 100%;
+  height: 100%;
+  background-color: rgba(32, 166, 169);
+}
+
+.content-area {
+  height: calc(100% - 47px);
+}
+
+.content-title {
+  display: flex;
+  align-items: center;
+  height: 34px;
+  background: var(--image-box-bg2) no-repeat;
+  background-size: 100% 100%;
+  margin-bottom: 6px;
+}
+
+.title-item {
+  display: flex;
+  flex: 1;
+  justify-content: center;
+  align-items: center;
+  color: #01fefc;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+
+.history-content {
+  height: 100%;
+  overflow-y: auto;
+}
+
+.content-item {
+  display: flex;
+  align-items: center;
+  height: 36px;
+  &:nth-child(odd) {
+    background-color: #0e3455;
+  }
+  &:nth-child(even) {
+    background-color: #114268;
+  }
+}
+
+.item-text {
+  display: flex;
+  flex: 1;
+  justify-content: center;
+  align-items: center;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  padding: 0 4px;
+}
+.title-item:nth-child(2),
+.item-text:nth-child(2) {
+  flex: 1.8;
+}
+.title-item:nth-child(3),
+.item-text:nth-child(3) {
+  flex: 1.5;
+}
+.title-item:nth-child(4),
+.item-text:nth-child(4) {
+  flex: 1.5;
+}
+.item-text1 {
+  color: #f4933d;
+}
+.item-text2 {
+  color: #4cf3a6;
+}
+.text-look {
+  padding: 0px 3px;
+  margin: 0px 2px;
+  border-radius: 2px;
+  background-color: #2484bc;
+  cursor: pointer;
+}
+
+.zxm-input {
+  height: 42px;
+  color: #fff;
+  background-color: transparent;
+  border: none;
+  background: var(--image-box-bg1) no-repeat;
+  background-size: 100% 100%;
+}
+.zxm-input-sm {
+  padding: 0px 20px;
+}
+</style>

+ 216 - 11
src/views/vent/home/configurable/configurable.data.ts

@@ -147,7 +147,7 @@ export const testConfigFire: Config[] = [
           },
           },
           legend: { show: false },
           legend: { show: false },
           xAxis: [{ show: true }],
           xAxis: [{ show: true }],
-          yAxis: [{ show: true, name: '(℃)', position: 'left', }],
+          yAxis: [{ show: true, name: '(℃)', position: 'left' }],
           series: [
           series: [
             {
             {
               label: '温度',
               label: '温度',
@@ -158,9 +158,7 @@ export const testConfigFire: Config[] = [
           ],
           ],
         },
         },
       ],
       ],
-      table: [
-
-      ],
+      table: [],
       gallery: [],
       gallery: [],
       complex_list: [],
       complex_list: [],
       gallery_list: [],
       gallery_list: [],
@@ -275,7 +273,7 @@ export const testConfigFire: Config[] = [
           {
           {
             name: 'table',
             name: 'table',
             basis: '75%',
             basis: '75%',
-            overflow: true
+            overflow: true,
           },
           },
         ],
         ],
       },
       },
@@ -440,7 +438,7 @@ export const testConfigFire: Config[] = [
             { label: '粉尘浓度', value: 'fcnd', unit: 'mg/m³' },
             { label: '粉尘浓度', value: 'fcnd', unit: 'mg/m³' },
             { label: '烟雾指数', value: 'ywzs', unit: '' },
             { label: '烟雾指数', value: 'ywzs', unit: '' },
             { label: '地表温度', value: 'tempDb', unit: '℃' },
             { label: '地表温度', value: 'tempDb', unit: '℃' },
-          ]
+          ],
         },
         },
       ],
       ],
       to: '/micro-vent-3dModal/dashboard/analysis?type=tunMonitor&deviceType=fanmain',
       to: '/micro-vent-3dModal/dashboard/analysis?type=tunMonitor&deviceType=fanmain',
@@ -502,7 +500,7 @@ export const testConfigFire: Config[] = [
             { firstLabel: '报警确认', secondLabel: '视屏调取', thirdLabel: '联动控制' },
             { firstLabel: '报警确认', secondLabel: '视屏调取', thirdLabel: '联动控制' },
             { firstLabel: '数据导出', secondLabel: '生成报表', thirdLabel: '定位追踪' },
             { firstLabel: '数据导出', secondLabel: '生成报表', thirdLabel: '定位追踪' },
             { firstLabel: '声光关闭', secondLabel: '应急广播', thirdLabel: '系统设置' },
             { firstLabel: '声光关闭', secondLabel: '应急广播', thirdLabel: '系统设置' },
-          ]
+          ],
         },
         },
       ],
       ],
       to: '/micro-vent-3dModal/dashboard/analysis?type=tunMonitor&deviceType=fanmain',
       to: '/micro-vent-3dModal/dashboard/analysis?type=tunMonitor&deviceType=fanmain',
@@ -650,7 +648,6 @@ export const testConfigDevice: Config[] = [
           {
           {
             name: 'long_list2',
             name: 'long_list2',
             basis: '100%',
             basis: '100%',
-
           },
           },
         ],
         ],
       },
       },
@@ -887,6 +884,217 @@ export const testConfigWarn: Config[] = [
     },
     },
   },
   },
 ];
 ];
+//联动配置
+export const testConfigLink: Config[] = [
+  {
+    deviceType: '',
+    moduleName: '联动规则列表',
+    pageType: 'gas_injection',
+    moduleData: {
+      header: {
+        show: false,
+        readFrom: '',
+        selector: {
+          show: false,
+          value: '${strinstallpos}',
+        },
+        slot: {
+          show: false,
+          value: '',
+          trans: {},
+        },
+      },
+      background: {
+        show: false,
+        type: 'video',
+        link: '',
+      },
+      layout: {
+        direction: 'column',
+        items: [
+          {
+            name: 'rule_table',
+            basis: '100%',
+          },
+        ],
+      },
+      board: [],
+      list: [],
+      chart: [],
+      table: [],
+      gallery: [],
+      complex_list: [],
+      gallery_list: [],
+      preset: [
+        {
+          readFrom: '',
+        },
+      ],
+      to: '',
+    },
+    showStyle: {
+      size: 'width:420px;height:calc(100% - 200px);',
+      version: '普通版',
+      position: 'top:0px;left:10px;',
+    },
+  },
+  {
+    deviceType: '',
+    moduleName: '联动规则编辑器',
+    pageType: 'gas_injection',
+    moduleData: {
+      header: {
+        show: false,
+        readFrom: '',
+        selector: {
+          show: false,
+          value: '${strinstallpos}',
+        },
+        slot: {
+          show: false,
+          value: '',
+          trans: {},
+        },
+      },
+      background: {
+        show: false,
+        type: 'video',
+        link: '',
+      },
+      layout: {
+        direction: 'column',
+        items: [
+          {
+            name: 'link_edit',
+            basis: '100%',
+          },
+        ],
+      },
+      board: [],
+      list: [],
+      chart: [],
+      table: [],
+      gallery: [],
+      complex_list: [],
+      gallery_list: [],
+      preset: [
+        {
+          readFrom: '',
+        },
+      ],
+      to: '',
+    },
+    showStyle: {
+      size: 'width:1020px;height:calc(100% - 76px);',
+      version: '普通版',
+      position: 'top:65px;left:440px;',
+    },
+  },
+  {
+    deviceType: '',
+    moduleName: '联动日志',
+    pageType: 'gas_injection',
+    moduleData: {
+      header: {
+        show: false,
+        readFrom: '',
+        selector: {
+          show: false,
+          value: '${strinstallpos}',
+        },
+        slot: {
+          show: false,
+          value: '',
+          trans: {},
+        },
+      },
+      background: {
+        show: false,
+        type: 'video',
+        link: '',
+      },
+      layout: {
+        direction: 'column',
+        items: [
+          {
+            name: 'link_log',
+            basis: '100%',
+          },
+        ],
+      },
+      board: [],
+      list: [],
+      chart: [],
+      table: [],
+      gallery: [],
+      complex_list: [],
+      gallery_list: [],
+      preset: [
+        {
+          readFrom: '',
+        },
+      ],
+      to: '',
+    },
+    showStyle: {
+      size: 'width:420px;height:calc(100% - 10px);',
+      version: '普通版',
+      position: 'top:0px;right:10px;',
+    },
+  },
+  {
+    deviceType: '',
+    moduleName: '规则统计',
+    pageType: 'gas_injection',
+    moduleData: {
+      header: {
+        show: false,
+        readFrom: '',
+        selector: {
+          show: false,
+          value: '${strinstallpos}',
+        },
+        slot: {
+          show: false,
+          value: '',
+          trans: {},
+        },
+      },
+      background: {
+        show: false,
+        type: 'video',
+        link: '',
+      },
+      layout: {
+        direction: 'column',
+        items: [
+          {
+            name: 'rule_num',
+            basis: '100%',
+          },
+        ],
+      },
+      board: [],
+      list: [],
+      chart: [],
+      table: [],
+      gallery: [],
+      complex_list: [],
+      gallery_list: [],
+      preset: [
+        {
+          readFrom: '',
+        },
+      ],
+      to: '',
+    },
+    showStyle: {
+      size: 'width:420px;height:180px;',
+      version: '普通版',
+      position: 'bottom:10px;bottom:10px;',
+    },
+  },
+];
 //系统管理
 //系统管理
 export const testConfigSystem: Config[] = [
 export const testConfigSystem: Config[] = [
   {
   {
@@ -1202,7 +1410,6 @@ export const testConfigSystem: Config[] = [
     },
     },
   },
   },
 ];
 ];
-
 export const testConfigVentSsl: Config[] = [
 export const testConfigVentSsl: Config[] = [
   {
   {
     deviceType: 'fanmain',
     deviceType: 'fanmain',
@@ -2923,8 +3130,6 @@ export const testConfigDustGreen: Config[] = [
   },
   },
 ];
 ];
 
 
-
-
 export const testConfigFireGreen: Config[] = [
 export const testConfigFireGreen: Config[] = [
   {
   {
     deviceType: 'fireManageInfo',
     deviceType: 'fireManageInfo',

+ 24 - 23
src/views/vent/home/configurable/deviceManger.vue

@@ -1,8 +1,15 @@
 <template>
 <template>
   <div class="device-manger">
   <div class="device-manger">
-    <ModuleCommonHsq v-for="cfg in configs" :key="cfg.deviceType" :show-style="cfg.showStyle"
-      :module-data="cfg.moduleData" :module-name="cfg.moduleName" :device-type="cfg.deviceType" :data="data"
-      :visible="true" />
+    <ModuleCommonHsq
+      v-for="cfg in configs"
+      :key="cfg.deviceType"
+      :show-style="cfg.showStyle"
+      :module-data="cfg.moduleData"
+      :module-name="cfg.moduleName"
+      :device-type="cfg.deviceType"
+      :data="data"
+      :visible="true"
+    />
   </div>
   </div>
 </template>
 </template>
 <script lang="ts" setup>
 <script lang="ts" setup>
@@ -13,23 +20,19 @@ import { getSystemApi } from './configurable.api';
 import { testConfigDevice } from './configurable.data';
 import { testConfigDevice } from './configurable.data';
 
 
 const { configs, fetchConfigs } = useInitConfigs();
 const { configs, fetchConfigs } = useInitConfigs();
-const { data, updateData } = useInitPage('红泉露天煤矿系统');
+const { data, updateData } = useInitPage('红泉露天煤矿系统');
 let interval: number | undefined;
 let interval: number | undefined;
 
 
 // https获取监测数据
 // https获取监测数据
 let timer: null | NodeJS.Timeout = null;
 let timer: null | NodeJS.Timeout = null;
 function getMonitor() {
 function getMonitor() {
-  timer = setTimeout(
-    async () => {
-      getSystemApi({ devicetype: 'sys', systemID: '2036323791827165185' }).then(updateData);
-      if (timer) {
-        timer = null;
-      }
-      getMonitor();
-    },
-    10000
-  );
-
+  timer = setTimeout(async () => {
+    getSystemApi({ devicetype: 'sys', systemID: '2036323791827165185' }).then(updateData);
+    if (timer) {
+      timer = null;
+    }
+    getMonitor();
+  }, 10000);
 }
 }
 
 
 onMounted(() => {
 onMounted(() => {
@@ -37,14 +40,12 @@ onMounted(() => {
     configs.value = testConfigDevice;
     configs.value = testConfigDevice;
     getSystemApi({ devicetype: 'sys', systemID: '2036323791827165185' }).then(updateData);
     getSystemApi({ devicetype: 'sys', systemID: '2036323791827165185' }).then(updateData);
   });
   });
-  getMonitor()
+  getMonitor();
 });
 });
 
 
 watch(
 watch(
   () => data.value,
   () => data.value,
-  (newData, oldData) => {
-
-  }
+  (newData, oldData) => {}
 );
 );
 
 
 onUnmounted(() => {
 onUnmounted(() => {
@@ -56,11 +57,12 @@ onUnmounted(() => {
 @import '/@/design/theme.less';
 @import '/@/design/theme.less';
 
 
 @{theme-deepblue} {
 @{theme-deepblue} {
-  .device-manger {}
+  .device-manger {
+  }
 }
 }
 
 
 .device-manger {
 .device-manger {
-    --image-box1-bg: url('@/assets/images/home-container/configurable/hsq/2-4.png');
+  --image-box1-bg: url('@/assets/images/home-container/configurable/hsq/2-4.png');
   --image-box1-bg1: url('@/assets/images/home-container/configurable/hsq/2-10.png');
   --image-box1-bg1: url('@/assets/images/home-container/configurable/hsq/2-10.png');
   width: 100%;
   width: 100%;
   height: 100%;
   height: 100%;
@@ -68,14 +70,13 @@ onUnmounted(() => {
   position: relative;
   position: relative;
   padding: 0px 10px;
   padding: 0px 10px;
   box-sizing: border-box;
   box-sizing: border-box;
-   background-color: #09172c;
+  background-color: #09172c;
 }
 }
 
 
 .vent-box1-bg {
 .vent-box1-bg {
   &:nth-child(1) {
   &:nth-child(1) {
     background: var(--image-box1-bg) no-repeat;
     background: var(--image-box1-bg) no-repeat;
     background-size: 100% 100%;
     background-size: 100% 100%;
-    
   }
   }
 
 
   &:nth-child(2) {
   &:nth-child(2) {

+ 22 - 19
src/views/vent/home/configurable/fireMonitor.vue

@@ -1,7 +1,15 @@
 <template>
 <template>
   <div class="fire-monitor">
   <div class="fire-monitor">
-    <ModuleCommon v-for="cfg in configs" :key="cfg.deviceType" :show-style="cfg.showStyle" :module-data="cfg.moduleData"
-      :module-name="cfg.moduleName" :device-type="cfg.deviceType" :data="data" :visible="true" />
+    <ModuleCommon
+      v-for="cfg in configs"
+      :key="cfg.deviceType"
+      :show-style="cfg.showStyle"
+      :module-data="cfg.moduleData"
+      :module-name="cfg.moduleName"
+      :device-type="cfg.deviceType"
+      :data="data"
+      :visible="true"
+    />
   </div>
   </div>
 </template>
 </template>
 <script lang="ts" setup>
 <script lang="ts" setup>
@@ -12,23 +20,19 @@ import { getSystemApi } from './configurable.api';
 import { testConfigFire } from './configurable.data';
 import { testConfigFire } from './configurable.data';
 
 
 const { configs, fetchConfigs } = useInitConfigs();
 const { configs, fetchConfigs } = useInitConfigs();
-const { data, updateData } = useInitPage('红泉露天煤矿系统');
+const { data, updateData } = useInitPage('红泉露天煤矿系统');
 let interval: number | undefined;
 let interval: number | undefined;
 
 
 // https获取监测数据
 // https获取监测数据
 let timer: null | NodeJS.Timeout = null;
 let timer: null | NodeJS.Timeout = null;
 function getMonitor() {
 function getMonitor() {
-  timer = setTimeout(
-    async () => {
-      getSystemApi({ devicetype: 'sys', systemID: '2036323791827165185' }).then(updateData);
-      if (timer) {
-        timer = null;
-      }
-      getMonitor();
-    },
-    10000
-  );
-
+  timer = setTimeout(async () => {
+    getSystemApi({ devicetype: 'sys', systemID: '2036323791827165185' }).then(updateData);
+    if (timer) {
+      timer = null;
+    }
+    getMonitor();
+  }, 10000);
 }
 }
 
 
 onMounted(() => {
 onMounted(() => {
@@ -36,14 +40,12 @@ onMounted(() => {
     configs.value = testConfigFire;
     configs.value = testConfigFire;
     getSystemApi({ devicetype: 'sys', systemID: '2036323791827165185' }).then(updateData);
     getSystemApi({ devicetype: 'sys', systemID: '2036323791827165185' }).then(updateData);
   });
   });
-  getMonitor()
+  getMonitor();
 });
 });
 
 
 watch(
 watch(
   () => data.value,
   () => data.value,
-  (newData, oldData) => {
-
-  }
+  (newData, oldData) => {}
 );
 );
 
 
 onUnmounted(() => {
 onUnmounted(() => {
@@ -55,7 +57,8 @@ onUnmounted(() => {
 @import '/@/design/theme.less';
 @import '/@/design/theme.less';
 
 
 @{theme-deepblue} {
 @{theme-deepblue} {
-  .fire-monitor {}
+  .fire-monitor {
+  }
 }
 }
 
 
 .fire-monitor {
 .fire-monitor {

+ 17 - 18
src/views/vent/home/configurable/gasInjection.vue

@@ -13,47 +13,48 @@
 </template>
 </template>
 
 
 <script setup lang="ts">
 <script setup lang="ts">
-import { ref } from 'vue'
+import { ref } from 'vue';
 import { useInitConfigs, useInitPage } from './hooks/useInit';
 import { useInitConfigs, useInitPage } from './hooks/useInit';
-import navMenu from './components/navMenu.vue'
-import fireMonitor from './fireMonitor.vue'
-import deviceManger from './deviceManger.vue'
-import warnMonitor from './warnMonitor.vue'
-import systemManger from './systemManger.vue'
-
-const { mainTitle, data, updateData } = useInitPage('红泉露天煤矿系统');
+import navMenu from './components/navMenu.vue';
+import fireMonitor from './fireMonitor.vue';
+import deviceManger from './deviceManger.vue';
+import warnMonitor from './warnMonitor.vue';
+import systemManger from './systemManger.vue';
+import linkConfiguration from './linkConfiguration.vue';
+const { mainTitle, data, updateData } = useInitPage('红泉露天煤矿系统');
 //当前激活界面
 //当前激活界面
-const activeComponente = ref<any>(fireMonitor)
+const activeComponente = ref<any>(fireMonitor);
 
 
 //menu选项切换
 //menu选项切换
 function changeMenu(param) {
 function changeMenu(param) {
   switch (param) {
   switch (param) {
     case 'yzt':
     case 'yzt':
-      activeComponente.value = fireMonitor
+      activeComponente.value = fireMonitor;
       break;
       break;
     case 'jcyj':
     case 'jcyj':
-      activeComponente.value = warnMonitor
+      activeComponente.value = warnMonitor;
       break;
       break;
     case 'sbgl':
     case 'sbgl':
-      activeComponente.value = deviceManger
+      activeComponente.value = deviceManger;
       break;
       break;
     case 'ldpz':
     case 'ldpz':
+      activeComponente.value = linkConfiguration;
       break;
       break;
     case 'xtgl':
     case 'xtgl':
-        activeComponente.value = systemManger
+      activeComponente.value = systemManger;
       break;
       break;
     case 'dpzs':
     case 'dpzs':
       break;
       break;
   }
   }
 }
 }
-
 </script>
 </script>
 
 
 <style lang="less" scoped>
 <style lang="less" scoped>
 @import '/@/design/theme.less';
 @import '/@/design/theme.less';
 
 
 @{theme-deepblue} {
 @{theme-deepblue} {
-  .deviceManger {}
+  .deviceManger {
+  }
 }
 }
 
 
 .deviceManger {
 .deviceManger {
@@ -62,7 +63,7 @@ function changeMenu(param) {
   width: 100%;
   width: 100%;
   height: 100%;
   height: 100%;
   color: #fff;
   color: #fff;
-  background: url('@/assets/images/vent/homeNew/bg.png') no-repeat center;
+  /* background: url('@/assets/images/vent/homeNew/bg.png') no-repeat center; */
 
 
   .top-bg {
   .top-bg {
     width: 100%;
     width: 100%;
@@ -100,8 +101,6 @@ function changeMenu(param) {
     height: calc(100% - 70px);
     height: calc(100% - 70px);
     padding: 0px 10px;
     padding: 0px 10px;
     box-sizing: border-box;
     box-sizing: border-box;
-
-
   }
   }
 }
 }
 </style>
 </style>

+ 101 - 0
src/views/vent/home/configurable/linkConfiguration.vue

@@ -0,0 +1,101 @@
+<template>
+  <div class="device-manger">
+    <ModuleCommonHsq
+      v-for="cfg in configs"
+      :key="cfg.deviceType"
+      :show-style="cfg.showStyle"
+      :module-data="cfg.moduleData"
+      :module-name="cfg.moduleName"
+      :device-type="cfg.deviceType"
+      :data="data"
+      :visible="true"
+    />
+  </div>
+</template>
+<script lang="ts" setup>
+import { onMounted, onUnmounted, ref, computed, nextTick, onBeforeMount, watch } from 'vue';
+import { useInitConfigs, useInitPage } from './hooks/useInit';
+import ModuleCommonHsq from './components/ModuleCommonHsq.vue';
+import { getSystemApi } from './configurable.api';
+import { testConfigLink } from './configurable.data';
+
+const { configs, fetchConfigs } = useInitConfigs();
+const { data, updateData } = useInitPage('红沙泉露天煤矿系统');
+let interval: number | undefined;
+
+// https获取监测数据
+let timer: null | NodeJS.Timeout = null;
+function getMonitor() {
+  // timer = setTimeout(async () => {
+  //   getSystemApi({ devicetype: 'sys', systemID: '2036323791827165185' }).then(updateData);
+  //   if (timer) {
+  //     timer = null;
+  //   }
+  //   getMonitor();
+  // }, 10000);
+}
+
+onMounted(() => {
+  fetchConfigs('gas_injection').then(() => {
+    configs.value = testConfigLink;
+    // getSystemApi({ devicetype: 'sys', systemID: '2036323791827165185' }).then(updateData);
+  });
+  getMonitor();
+});
+
+watch(
+  () => data.value,
+  (newData, oldData) => {}
+);
+
+onUnmounted(() => {
+  clearInterval(interval);
+});
+</script>
+
+<style lang="less" scoped>
+@import '/@/design/theme.less';
+
+@{theme-deepblue} {
+  .device-manger {
+  }
+}
+
+.device-manger {
+  --image-box1-bg: url('@/assets/images/home-container/configurable/hsq/2-4.png');
+  --image-box1-bg1: url('@/assets/images/home-container/configurable/hsq/2-10.png');
+  --image-box1-bg2: url('@/assets/images/home-container/configurable/hsq/4-1bg.png');
+  width: 100%;
+  height: 100%;
+  color: @white;
+  position: relative;
+  padding: 0px 10px;
+  box-sizing: border-box;
+  background-color: #09172c;
+}
+
+.vent-box1-bg {
+  &:nth-child(1) {
+    background: var(--image-box1-bg) no-repeat;
+    background-size: 100% 100%;
+  }
+
+  &:nth-child(2) {
+    background: var(--image-box1-bg1) no-repeat;
+    background-size: 100% 100%;
+  }
+
+  &:nth-child(3) {
+    background: var(--image-box1-bg) no-repeat;
+    background-size: 100% 100%;
+  }
+  &:nth-child(4) {
+    background: var(--image-box1-bg2) no-repeat;
+    background-size: 100% 100%;
+  }
+}
+
+:deep(.loading-box) {
+  position: unset;
+}
+</style>

+ 32 - 25
src/views/vent/home/configurable/systemManger.vue

@@ -1,12 +1,24 @@
 <template>
 <template>
   <div class="system-manger">
   <div class="system-manger">
     <div class="nav-menu">
     <div class="nav-menu">
-      <div :class="activeIndex == index ? 'nav-item-active' : 'nav-item'" v-for="(item, index) in navList" :key="index"
-        @click="handleChange(item, index)">{{ item.label }}</div>
+      <div
+        :class="activeIndex == index ? 'nav-item-active' : 'nav-item'"
+        v-for="(item, index) in navList"
+        :key="index"
+        @click="handleChange(item, index)"
+        >{{ item.label }}</div
+      >
     </div>
     </div>
-    <ModuleCommonHsq v-for="cfg in configs" :key="cfg.deviceType" :show-style="cfg.showStyle"
-      :module-data="cfg.moduleData" :module-name="cfg.moduleName" :device-type="cfg.deviceType" :data="data"
-      :visible="true" />
+    <ModuleCommonHsq
+      v-for="cfg in configs"
+      :key="cfg.deviceType"
+      :show-style="cfg.showStyle"
+      :module-data="cfg.moduleData"
+      :module-name="cfg.moduleName"
+      :device-type="cfg.deviceType"
+      :data="data"
+      :visible="true"
+    />
   </div>
   </div>
 </template>
 </template>
 <script lang="ts" setup>
 <script lang="ts" setup>
@@ -17,8 +29,8 @@ import { getSystemApi } from './configurable.api';
 import { testConfigSystem } from './configurable.data';
 import { testConfigSystem } from './configurable.data';
 
 
 const { configs, fetchConfigs } = useInitConfigs();
 const { configs, fetchConfigs } = useInitConfigs();
-const { data, updateData } = useInitPage('红泉露天煤矿系统');
-let activeIndex = ref(0)
+const { data, updateData } = useInitPage('红泉露天煤矿系统');
+let activeIndex = ref(0);
 let interval: number | undefined;
 let interval: number | undefined;
 let navList = ref<any[]>([
 let navList = ref<any[]>([
   { label: '角色权限', value: '1' },
   { label: '角色权限', value: '1' },
@@ -26,26 +38,23 @@ let navList = ref<any[]>([
   { label: '日志审计', value: '3' },
   { label: '日志审计', value: '3' },
   { label: '系统配置', value: '4' },
   { label: '系统配置', value: '4' },
   { label: '数据备份', value: '5' },
   { label: '数据备份', value: '5' },
-])
+]);
 
 
 // https获取监测数据
 // https获取监测数据
 let timer: null | NodeJS.Timeout = null;
 let timer: null | NodeJS.Timeout = null;
 function getMonitor() {
 function getMonitor() {
-  timer = setTimeout(
-    async () => {
-      getSystemApi({ devicetype: 'sys', systemID: '2036323791827165185' }).then(updateData);
-      if (timer) {
-        timer = null;
-      }
-      getMonitor();
-    },
-    10000
-  );
+  timer = setTimeout(async () => {
+    getSystemApi({ devicetype: 'sys', systemID: '2036323791827165185' }).then(updateData);
+    if (timer) {
+      timer = null;
+    }
+    getMonitor();
+  }, 10000);
 }
 }
 
 
 //nav选项切换
 //nav选项切换
 function handleChange(item, index) {
 function handleChange(item, index) {
-  activeIndex.value = index
+  activeIndex.value = index;
 }
 }
 
 
 onMounted(() => {
 onMounted(() => {
@@ -53,14 +62,12 @@ onMounted(() => {
     configs.value = testConfigSystem;
     configs.value = testConfigSystem;
     getSystemApi({ devicetype: 'sys', systemID: '2036323791827165185' }).then(updateData);
     getSystemApi({ devicetype: 'sys', systemID: '2036323791827165185' }).then(updateData);
   });
   });
-  getMonitor()
+  getMonitor();
 });
 });
 
 
 watch(
 watch(
   () => data.value,
   () => data.value,
-  (newData, oldData) => {
-
-  }
+  (newData, oldData) => {}
 );
 );
 
 
 onUnmounted(() => {
 onUnmounted(() => {
@@ -72,7 +79,8 @@ onUnmounted(() => {
 @import '/@/design/theme.less';
 @import '/@/design/theme.less';
 
 
 @{theme-deepblue} {
 @{theme-deepblue} {
-  .system-manger {}
+  .system-manger {
+  }
 }
 }
 
 
 .system-manger {
 .system-manger {
@@ -95,7 +103,6 @@ onUnmounted(() => {
   &:nth-child(2) {
   &:nth-child(2) {
     background: var(--image-box1-bg) no-repeat;
     background: var(--image-box1-bg) no-repeat;
     background-size: 100% 100%;
     background-size: 100% 100%;
-
   }
   }
 
 
   &:nth-child(3) {
   &:nth-child(3) {

+ 26 - 25
src/views/vent/home/configurable/warnMonitor.vue

@@ -1,8 +1,15 @@
 <template>
 <template>
   <div class="warn-monitor">
   <div class="warn-monitor">
-    <ModuleCommonHsq v-for="cfg in configs" :key="cfg.deviceType" :show-style="cfg.showStyle"
-      :module-data="cfg.moduleData" :module-name="cfg.moduleName" :device-type="cfg.deviceType" :data="data"
-      :visible="true" />
+    <ModuleCommonHsq
+      v-for="cfg in configs"
+      :key="cfg.deviceType"
+      :show-style="cfg.showStyle"
+      :module-data="cfg.moduleData"
+      :module-name="cfg.moduleName"
+      :device-type="cfg.deviceType"
+      :data="data"
+      :visible="true"
+    />
   </div>
   </div>
 </template>
 </template>
 <script lang="ts" setup>
 <script lang="ts" setup>
@@ -13,23 +20,19 @@ import { getSystemApi } from './configurable.api';
 import { testConfigWarn } from './configurable.data';
 import { testConfigWarn } from './configurable.data';
 
 
 const { configs, fetchConfigs } = useInitConfigs();
 const { configs, fetchConfigs } = useInitConfigs();
-const { data, updateData } = useInitPage('红泉露天煤矿系统');
+const { data, updateData } = useInitPage('红泉露天煤矿系统');
 let interval: number | undefined;
 let interval: number | undefined;
 
 
 // https获取监测数据
 // https获取监测数据
 let timer: null | NodeJS.Timeout = null;
 let timer: null | NodeJS.Timeout = null;
 function getMonitor() {
 function getMonitor() {
-  timer = setTimeout(
-    async () => {
-      getSystemApi({ devicetype: 'sys', systemID: '2036323791827165185' }).then(updateData);
-      if (timer) {
-        timer = null;
-      }
-      getMonitor();
-    },
-    10000
-  );
-
+  timer = setTimeout(async () => {
+    getSystemApi({ devicetype: 'sys', systemID: '2036323791827165185' }).then(updateData);
+    if (timer) {
+      timer = null;
+    }
+    getMonitor();
+  }, 10000);
 }
 }
 
 
 onMounted(() => {
 onMounted(() => {
@@ -37,14 +40,12 @@ onMounted(() => {
     configs.value = testConfigWarn;
     configs.value = testConfigWarn;
     getSystemApi({ devicetype: 'sys', systemID: '2036323791827165185' }).then(updateData);
     getSystemApi({ devicetype: 'sys', systemID: '2036323791827165185' }).then(updateData);
   });
   });
-  getMonitor()
+  getMonitor();
 });
 });
 
 
 watch(
 watch(
   () => data.value,
   () => data.value,
-  (newData, oldData) => {
-
-  }
+  (newData, oldData) => {}
 );
 );
 
 
 onUnmounted(() => {
 onUnmounted(() => {
@@ -56,27 +57,27 @@ onUnmounted(() => {
 @import '/@/design/theme.less';
 @import '/@/design/theme.less';
 
 
 @{theme-deepblue} {
 @{theme-deepblue} {
-  .warn-monitor {}
+  .warn-monitor {
+  }
 }
 }
 
 
 .warn-monitor {
 .warn-monitor {
-    --image-box1-bg: url('@/assets/images/home-container/configurable/hsq/2-4.png');
+  --image-box1-bg: url('@/assets/images/home-container/configurable/hsq/2-4.png');
   --image-box1-bg1: url('@/assets/images/home-container/configurable/hsq/2-10.png');
   --image-box1-bg1: url('@/assets/images/home-container/configurable/hsq/2-10.png');
-    --image-box1-bg2: url('@/assets/images/home-container/configurable/hsq/3-3.png');
+  --image-box1-bg2: url('@/assets/images/home-container/configurable/hsq/3-3.png');
   width: 100%;
   width: 100%;
   height: 100%;
   height: 100%;
   color: @white;
   color: @white;
   position: relative;
   position: relative;
   padding: 0px 10px;
   padding: 0px 10px;
   box-sizing: border-box;
   box-sizing: border-box;
-   background-color: #09172c;
+  background-color: #09172c;
 }
 }
 
 
 .vent-box1-bg {
 .vent-box1-bg {
   &:nth-child(1) {
   &:nth-child(1) {
     background: var(--image-box1-bg) no-repeat;
     background: var(--image-box1-bg) no-repeat;
     background-size: 100% 100%;
     background-size: 100% 100%;
-    
   }
   }
 
 
   &:nth-child(2) {
   &:nth-child(2) {
@@ -88,7 +89,7 @@ onUnmounted(() => {
     background: var(--image-box1-bg) no-repeat;
     background: var(--image-box1-bg) no-repeat;
     background-size: 100% 100%;
     background-size: 100% 100%;
   }
   }
-    &:nth-child(4) {
+  &:nth-child(4) {
     background: var(--image-box1-bg2) no-repeat;
     background: var(--image-box1-bg2) no-repeat;
     background-size: 100% 100%;
     background-size: 100% 100%;
   }
   }

+ 1 - 1
tsconfig.json

@@ -44,6 +44,6 @@
     "mock/**/*.ts",
     "mock/**/*.ts",
     "vite.config.ts",
     "vite.config.ts",
     "src/**/*.glsl"
     "src/**/*.glsl"
-, "src/utils/threejs/loadModel.worker.js", "src/utils/threejs/loadModel.worker.js"  ],
+, "src/utils/threejs/loadModel.worker.js", "src/utils/threejs/loadModel.worker.js", "LongList.vue"  ],
   "exclude": ["node_modules", "tests/server/**/*.ts", "dist", "**/*.js"]
   "exclude": ["node_modules", "tests/server/**/*.ts", "dist", "**/*.js"]
 }
 }