Jelajahi Sumber

Merge branch 'master' of http://182.92.126.35:3000/hrx/mky-vent-base

lxh 1 Minggu lalu
induk
melakukan
932edf0614
64 mengubah file dengan 5768 tambahan dan 2262 penghapusan
  1. TEMPAT SAMPAH
      src/assets/images/home-warn/8-1.png
  2. TEMPAT SAMPAH
      src/assets/images/home-warn/8-2.png
  3. TEMPAT SAMPAH
      src/assets/images/home-warn/8-3.png
  4. TEMPAT SAMPAH
      src/assets/images/home-warn/8-4.png
  5. TEMPAT SAMPAH
      src/assets/images/home-warn/8-5.png
  6. 2 2
      src/views/vent/home/configurable/bule/components/ModuleFireNew.vue
  7. 2 2
      src/views/vent/home/configurable/bule/components/ModuleFireNewDual.vue
  8. 1 1
      src/views/vent/home/configurable/bule/components/ModuleNew.vue
  9. 11 5
      src/views/vent/home/configurable/bule/components/ModuleWarnMonitor.vue
  10. 33 0
      src/views/vent/home/configurable/bule/components/center-area-warn.vue
  11. 18 18
      src/views/vent/home/configurable/bule/components/content-FireNew.vue
  12. 14 12
      src/views/vent/home/configurable/bule/components/content-warn.vue
  13. 537 0
      src/views/vent/home/configurable/bule/components/content.vue
  14. 0 0
      src/views/vent/home/configurable/bule/components/detail/MiniBoard-Warn.vue
  15. 109 0
      src/views/vent/home/configurable/bule/components/header.vue
  16. 0 0
      src/views/vent/home/configurable/bule/components/moduleBottom-warn.vue
  17. 17 3
      src/views/vent/home/configurable/bule/components/moduleLeft-warn.vue
  18. 283 0
      src/views/vent/home/configurable/bule/components/originalNew/NewNav.vue
  19. 319 0
      src/views/vent/home/configurable/bule/components/originalNew/NewNavFire.vue
  20. 295 0
      src/views/vent/home/configurable/bule/components/originalNew/NewNavWarn.vue
  21. 95 0
      src/views/vent/home/configurable/bule/components/originalNew/leftHeader1.vue
  22. 89 0
      src/views/vent/home/configurable/bule/components/originalNew/leftHeader2.vue
  23. 133 0
      src/views/vent/home/configurable/bule/components/originalNew/moduleBottom.vue
  24. 95 0
      src/views/vent/home/configurable/bule/components/originalNew/moduleLeft.vue
  25. 104 0
      src/views/vent/home/configurable/bule/components/originalNew/moduleLeftBottom.vue
  26. 103 0
      src/views/vent/home/configurable/bule/components/originalNew/moduleLeftCenter.vue
  27. 104 0
      src/views/vent/home/configurable/bule/components/originalNew/moduleLeftTop.vue
  28. 102 0
      src/views/vent/home/configurable/bule/components/originalNew/moduleRightBottom.vue
  29. 103 0
      src/views/vent/home/configurable/bule/components/originalNew/moduleRightCenter.vue
  30. 104 0
      src/views/vent/home/configurable/bule/components/originalNew/moduleRightTop.vue
  31. 122 0
      src/views/vent/home/configurable/bule/components/originalNew/moduleTop.vue
  32. 161 0
      src/views/vent/home/configurable/bule/components/originalNew/moduleTopFire.vue
  33. 97 0
      src/views/vent/home/configurable/bule/components/originalNew/rightHeader1.vue
  34. 90 0
      src/views/vent/home/configurable/bule/components/originalNew/rightHeader2.vue
  35. 90 0
      src/views/vent/home/configurable/bule/components/originalNew/rightHeader3.vue
  36. 46 9
      src/views/vent/home/configurable/bule/components/yj_chart.vue
  37. 0 0
      src/views/vent/home/configurable/bule/components/yj_gasWarn.vue
  38. 16 25
      src/views/vent/home/configurable/bule/components/yj_risk.vue
  39. 1 1
      src/views/vent/home/configurable/bule/components/yj_ventWarn.vue
  40. 223 0
      src/views/vent/home/configurable/bule/fireNew.vue
  41. 166 0
      src/views/vent/home/configurable/bule/ventNew.vue
  42. 36 9
      src/views/vent/home/configurable/bule/warnMonitor.vue
  43. 311 311
      src/views/vent/home/configurable/components/content-New.vue
  44. 57 57
      src/views/vent/home/configurable/configurable.data.ts
  45. 0 223
      src/views/vent/home/configurable/fireNew.vue
  46. 242 148
      src/views/vent/home/configurable/green/components/dz-card.vue
  47. 162 106
      src/views/vent/home/configurable/green/components/dz-list.vue
  48. 0 166
      src/views/vent/home/configurable/ventNew.vue
  49. 266 266
      src/views/vent/monitorManager/AllDeviceMonitor/index.vue
  50. 38 31
      src/views/vent/monitorManager/deviceMonitor/components/device/index.vue
  51. 504 552
      src/views/vent/monitorManager/fanLocalMonitor1/index.vue
  52. 5 5
      src/views/vent/monitorManager/gateMonitor/components/gateDualSVG.vue
  53. 3 3
      src/views/vent/monitorManager/gateMonitor/components/gateSVG.vue
  54. 4 4
      src/views/vent/monitorManager/gateMonitor/components/gateTripleSVG.vue
  55. 2 1
      src/views/vent/monitorManager/gateMonitor/gate.data.ts
  56. 282 138
      src/views/vent/monitorManager/safetyMonitor/HistoryTable.vue
  57. 34 26
      src/views/vent/monitorManager/safetyMonitor/index.vue
  58. 1 1
      src/views/vent/monitorManager/safetyMonitor/safety.data.ts
  59. 5 5
      src/views/vent/monitorManager/windowMonitor/components/windowDualSVG.vue
  60. 5 5
      src/views/vent/monitorManager/windowMonitor/components/windowSVG.vue
  61. 18 19
      src/views/vent/monitorManager/windowMonitor/dandaoFcBd1.threejs.ts
  62. 2 0
      src/views/vent/monitorManager/windowMonitor/index.vue
  63. 105 107
      src/views/vent/monitorManager/windowMonitor/window.threejs.ts
  64. 1 1
      src/views/vent/monitorManager/windrectMonitor/index.vue

TEMPAT SAMPAH
src/assets/images/home-warn/8-1.png


TEMPAT SAMPAH
src/assets/images/home-warn/8-2.png


TEMPAT SAMPAH
src/assets/images/home-warn/8-3.png


TEMPAT SAMPAH
src/assets/images/home-warn/8-4.png


TEMPAT SAMPAH
src/assets/images/home-warn/8-5.png


+ 2 - 2
src/views/vent/home/configurable/components/ModuleFireNew.vue → src/views/vent/home/configurable/bule/components/ModuleFireNew.vue

@@ -33,8 +33,8 @@
 <script setup lang="ts">
 import ContentFireNew from './content-FireNew.vue';
 import { defineProps, defineEmits, computed, watch } from 'vue';
-import { useInitModule } from '../hooks/useInit';
-import { getFormattedText } from '../hooks/helper';
+import { useInitModule } from '../../hooks/useInit';
+import { getFormattedText } from '../../hooks/helper';
 import { openWindow } from '/@/utils';
 // import { ModuleProps } from '../types';
 

+ 2 - 2
src/views/vent/home/configurable/components/ModuleFireNewDual.vue → src/views/vent/home/configurable/bule/components/ModuleFireNewDual.vue

@@ -49,8 +49,8 @@
 <script setup lang="ts">
 import Content from './content-FireNew.vue';
 import { defineProps, defineEmits, computed, ref, watch } from 'vue';
-import { ModuleData, ShowStyle } from '../../../deviceManager/configurationTable/types';
-import { useInitModule } from '../hooks/useInit';
+import { ModuleData, ShowStyle } from '../../../../deviceManager/configurationTable/types';
+import { useInitModule } from '../../hooks/useInit';
 
 const props = defineProps<{
   moduleDataA: ModuleData;

+ 1 - 1
src/views/vent/home/configurable/components/ModuleNew.vue → src/views/vent/home/configurable/bule/components/ModuleNew.vue

@@ -36,7 +36,7 @@ import ModuleBottom from './originalNew/moduleBottom.vue';
 import ModuleTop from './originalNew/moduleTop.vue';
 import { computed, ref } from 'vue';
 import { openWindow } from '/@/utils';
-import { getFormattedText } from '../hooks/helper';
+import { getFormattedText } from '../../hooks/helper';
 import LeftHeader1 from './originalNew/leftHeader1.vue';
 import LeftHeader2 from './originalNew/leftHeader2.vue';
 import RightHeader1 from './originalNew/rightHeader1.vue';

+ 11 - 5
src/views/vent/home/configurable/components/ModuleWarnMonitor.vue → src/views/vent/home/configurable/bule/components/ModuleWarnMonitor.vue

@@ -8,21 +8,27 @@
     :class="{ 'cursor-pointer': !!moduleData.to }"
     @close="$emit('close')"
     @click="redirectTo"
+    :deviceType="deviceType"
   >
     <slot>
       <Header :deviceType="deviceType" :moduleData="moduleData" :data="data" @select="selectedData = $event" />
-      <Content :style="{ height: header.show ? 'calc(100% - 30px)' : '100%' }" :moduleData="moduleData" :data="selectedData" />
+      <Content
+        :deviceType="deviceType"
+        :style="{ height: header.show ? 'calc(100% - 30px)' : '100%' }"
+        :moduleData="moduleData"
+        :data="selectedData"
+      />
     </slot>
   </component>
 </template>
 <script lang="ts" setup>
-import Header from './header.vue';
+import Header from '../../components/header.vue';
 import Content from './content-warn.vue';
-import ModuleLeft from './original/moduleLeft-warn.vue';
-import ModuleBottom from './original/moduleBottom-warn.vue';
+import ModuleLeft from './moduleLeft-warn.vue';
+import ModuleBottom from './moduleBottom-warn.vue';
 import { computed, ref } from 'vue';
 import { openWindow } from '/@/utils';
-import { getFormattedText } from '../hooks/helper';
+import { getFormattedText } from '../../hooks/helper';
 // import { ModuleProps } from '../types';
 
 const props = defineProps<{

+ 33 - 0
src/views/vent/home/configurable/components/center-area-warn.vue → src/views/vent/home/configurable/bule/components/center-area-warn.vue

@@ -57,11 +57,37 @@
         </div>
       </div>
     </div>
+    <div class="risk-echartbox">
+      <yjRisk :echartData="paramData.riskData"></yjRisk>
+    </div>
   </div>
 </template>
 
 <script lang="ts" setup>
 import { ref } from 'vue';
+import yjRisk from './yj_risk.vue';
+import { reactive, watch } from 'vue';
+import { useGlobSetting } from '/@/hooks/setting';
+import { param } from '../../../../monitorManager/compreMonitor/compre.data';
+let props = defineProps({
+  echartData: {
+    type: Object,
+    default: () => {
+      return {};
+    },
+  },
+});
+let paramData = reactive<any>({});
+const { sysOrgCode, sysDataType } = useGlobSetting();
+
+watch(
+  () => props.echartData,
+  (newV, oldV) => {
+    paramData = newV;
+    console.log(paramData, '中间区域数据');
+  },
+  { immediate: true, deep: true }
+);
 </script>
 
 <style lang="less" scoped>
@@ -206,5 +232,12 @@ import { ref } from 'vue';
     font-size: 22px;
     color: #fafafb;
   }
+  .risk-echartbox {
+    position: absolute;
+    left: 18px;
+    top: 60px;
+    width: 220px;
+    height: 170px;
+  }
 }
 </style>

+ 18 - 18
src/views/vent/home/configurable/components/content-FireNew.vue → src/views/vent/home/configurable/bule/components/content-FireNew.vue

@@ -117,26 +117,26 @@ import {
   // ModuleDataList,
   // ModuleDataPreset,
   // ModuleDataTable,
-} from '../../../deviceManager/configurationTable/types';
-import MiniBoard from './detail/MiniBoard-FireNew.vue';
-import TimelineList from './detail/TimelineList.vue';
-import TimelineListNew from './detail/TimelineListNew.vue';
-import CustomList from './detail/CustomList-fire.vue';
-import ModuleTopFire from './originalNew/moduleTopFire.vue';
-import CustomGallery from './detail/CustomGallery.vue';
-import ComplexList from './detail/ComplexList-FireNew.vue';
-import GalleryList from './detail/GalleryList.vue';
-import CustomTable from './detail/CustomTable-fire.vue';
-import CustomChart from './detail/CustomChart.vue';
+} from '../../../../deviceManager/configurationTable/types';
+import MiniBoard from '../../components/detail/MiniBoard-FireNew.vue';
+import TimelineList from '../../components/detail/TimelineList.vue';
+import TimelineListNew from '../../components/detail/TimelineListNew.vue';
+import CustomList from '../../components/detail/CustomList-fire.vue';
+import ModuleTopFire from '../../components/originalNew/moduleTopFire.vue';
+import CustomGallery from '../../components/detail/CustomGallery.vue';
+import ComplexList from '../../components/detail/ComplexList-FireNew.vue';
+import GalleryList from '../../components/detail/GalleryList.vue';
+import CustomTable from '../../components/detail/CustomTable-fire.vue';
+import CustomChart from '../../components/detail/CustomChart.vue';
 import { clone } from 'lodash-es';
-import { getData, getFormattedText } from '../hooks/helper';
-import BlastDelta from '../../../monitorManager/deviceMonitor/components/device/modal/blastDelta.vue';
-import QHCurve from './preset/QHCurve.vue';
-import MeasureDetail from './preset/MeasureDetail.vue';
-import CustomTabs from './preset/CustomTabs.vue';
+import { getData, getFormattedText } from '../../hooks/helper';
+import BlastDelta from '../../../../monitorManager/deviceMonitor/components/device/modal/blastDelta.vue';
+import QHCurve from '../../components/preset/QHCurve.vue';
+import MeasureDetail from '../../components/preset/MeasureDetail.vue';
+import CustomTabs from '../../components/preset/CustomTabs.vue';
 import AIChat from '/@/components/AIChat/MiniChat.vue';
-import DeviceAlarm from './preset/DeviceAlarm.vue';
-import MiniBoardNew from './detail/MiniBoard-New.vue';
+import DeviceAlarm from '../../components/preset/DeviceAlarm.vue';
+import MiniBoardNew from '../../components/detail/MiniBoard-New.vue';
 // import FIreWarn from './preset/FIreWarn.vue';
 // import FIreControl from './preset/FIreControl.vue';
 

+ 14 - 12
src/views/vent/home/configurable/components/content-warn.vue → src/views/vent/home/configurable/bule/components/content-warn.vue

@@ -34,14 +34,19 @@
           </div>
         </template>
         <template v-if="config.name === 'dz_list'">
-          <DzList :listOption="config.config.listOption" :listData="config.data"></DzList>
+          <DzList :deviceType="deviceType" :listOption="config.config.listOption" :listData="config.data"></DzList>
         </template>
         <template v-if="config.name === 'dz_card'">
-          <DzCard :titleLeft="config.config.leftTitle" :titleRight="config.config.rightTitle" :paramData="config.data"></DzCard>
+          <DzCard
+            :deviceType="deviceType"
+            :titleLeft="config.config.leftTitle"
+            :titleRight="config.config.rightTitle"
+            :paramData="config.data"
+          ></DzCard>
         </template>
-        <template v-if="config.name === 'yj_risk'">
+        <!-- <template v-if="config.name === 'yj_risk'">
           <yjRisk :riskData="config.data"></yjRisk>
-        </template>
+        </template> -->
         <template v-if="config.name === 'yj_chart'">
           <yjChart :paramData="config.data"></yjChart>
         </template>
@@ -65,20 +70,21 @@ import {
   ModuleDataList,
   ModuleDataPreset,
   ModuleDataTable,
-} from '../../../deviceManager/configurationTable/types';
-import DzList from '../green/components/dz-list.vue';
-import DzCard from '../green/components/dz-card.vue';
+} from '../../../../deviceManager/configurationTable/types';
+import DzList from '../../green/components/dz-list.vue';
+import DzCard from '../../green/components/dz-card.vue';
 import yjRisk from './yj_risk.vue';
 import yjChart from './yj_chart.vue';
 import yjGas from './yj_gasWarn.vue';
 import MiniBoard from './detail/MiniBoard-Warn.vue';
 import yjVentWarn from './yj_ventWarn.vue';
 import { clone } from 'lodash-es';
-import { getData, getFormattedText } from '../hooks/helper';
+import { getData, getFormattedText } from '../../hooks/helper';
 
 const props = defineProps<{
   data: any;
   moduleData: Config['moduleData'];
+  deviceType: string;
 }>();
 
 const { background, layout } = props.moduleData;
@@ -331,13 +337,9 @@ const layoutConfig = computed(() => {
 }
 
 .content__module {
-  // margin-top: 5px;
-  // margin-bottom: 5px;
   width: 100%;
   height: 100%;
-  overflow-y: auto;
 }
-
 // .content__module:first-of-type {
 //   margin-top: 0;
 // }

+ 537 - 0
src/views/vent/home/configurable/bule/components/content.vue

@@ -0,0 +1,537 @@
+<!-- eslint-disable vue/multi-word-component-names -->
+<template>
+  <!-- 主体内容部分 -->
+  <div class="content">
+    <!-- 背景 -->
+    <img v-if="background.show && background.type === 'image'" class="content__background image__background" :src="background.link" />
+    <video
+      v-if="background.show && background.type === 'video'"
+      class="content__background content__background_video"
+      width="100%"
+      autoplay
+      loop
+      muted
+      disablepictureinpicture
+      playsinline
+    >
+      <source :src="background.link" />
+      Not Supportted Link Or Browser
+    </video>
+    <div class="flex w-full h-full" :style="{ flexDirection: layout.direction }">
+      <div v-for="config in layoutConfig" :key="config.name" :style="{ flexBasis: config.basis, overflow: config.overflow ? 'auto' : 'none' }">
+        <!-- 告示板部分 -->
+        <template v-if="config.name === 'board'">
+          <div
+            v-if="config.pageType == 'vent_New'"
+            style="padding-top: 11%"
+            class="content__module content__module1 flex flex-justify-around flex-items-center flex-wrap"
+          >
+            <MiniBoard
+              v-for="item in config.items"
+              :key="item.prop"
+              :label="item.label"
+              :value="item.value"
+              :type="config.type"
+              :layout="config.layout"
+            />
+          </div>
+          <div v-else-if="config.pageType == 'New_fire'" class="content__module flex flex-justify-around flex-items-center flex-wrap">
+            <MiniBoardNew
+              v-for="item in config.items"
+              :key="item.prop"
+              :label="item.label"
+              :value="item.value"
+              :type="config.type"
+              :layout="config.layout"
+            />
+          </div>
+          <div v-else class="content__module flex flex-justify-around flex-items-center flex-wrap">
+            <MiniBoard
+              v-for="item in config.items"
+              :key="item.prop"
+              :label="item.label"
+              :value="item.value"
+              :type="config.type"
+              :layout="config.layout"
+            />
+          </div>
+        </template>
+        <!-- 图表部分,这部分通常需要填充,有告示板、Header等内容需要填充父级 -->
+        <template v-if="config.name === 'chart'">
+          <CustomChart v-if="config.pageType == 'New_dust'" class="content__module_dust" :chart-config="config.config" :chart-data="config.data" />
+          <CustomChart v-else class="content__module" :chart-config="config.config" :chart-data="config.data" />
+        </template>
+        <!-- 通常列表部分 -->
+        <template v-if="config.name === 'list'">
+          <template v-if="config.type === 'timeline'">
+            <TimelineList class="content__module" :list-config="config.items" />
+          </template>
+          <template v-else-if="config.type === 'timelineNew'">
+            <TimelineListNew class="content__module" :list-config="config.items" />
+          </template>
+          <template v-else>
+            <CustomList class="content__module" :type="config.type" :list-config="config.items" />
+          </template>
+        </template>
+        <template v-if="config.name === 'fireList'">
+          <CustomList class="content__module" :type="config.type" :list-config="config.items" />
+        </template>
+        <!-- 画廊部分 -->
+        <template v-if="config.name === 'gallery'">
+          <CustomGallery class="content__module" :type="config.type" :gallery-config="config.items" />
+        </template>
+        <!-- 复杂列表部分 -->
+        <template v-if="config.name === 'gallery_list'">
+          <GalleryList class="content__module" :type="config.type" :list-config="config.items" :gallery-config="config.galleryItems" />
+        </template>
+        <!-- 复杂列表部分 -->
+        <template v-if="config.name === 'complex_list'">
+          <ComplexList class="content__module" :type="config.type" :list-config="config.items" />
+        </template>
+        <!-- 表格部分,这部分通常是占一整个模块的 -->
+        <template v-if="config.name === 'table'">
+          <CustomTable class="content__module text-center overflow-auto" :type="config.type" :columns="config.columns" :data="config.data" />
+        </template>
+        <template v-if="config.name === 'tabs'">
+          <CustomTabs class="content__module" :type="config.type" :tab-config="config.items" :overflow="config.overflow" />
+        </template>
+        <template v-if="config.name === 'blast_delta'">
+          <BlastDelta
+            v-if="config.pageType === 'New_fire'"
+            class="content__moduleFire"
+            :pos-monitor="config.data"
+            :canvasSize="{ width: 250, height: 200 }"
+          />
+          <BlastDelta v-else class="content__module" :pos-monitor="config.data" :canvasSize="{ width: 250, height: 200 }" />
+        </template>
+        <template v-if="config.name === 'qh_curve'">
+          <QHCurve class="content__module" :mainfan="config.data" :fan1-prop="config.config.fan1Prop" :fan2-prop="config.config.fan2Prop" />
+        </template>
+        <template v-if="config.name === 'ai_chat'">
+          <AIChat class="content__module" />
+        </template>
+        <template v-if="config.name === 'device_alarm'">
+          <DeviceAlarm class="content__module" :devicedata="config.data" />
+        </template>
+        <!-- lxh -->
+        <template v-if="config.name === 'select_cs'">
+          <SelectCs :devicedata="config.data" :setLabelData="config.config.setLabelConfig" />
+        </template>
+        <template v-if="config.name === 'measure_detail'">
+          <MeasureDetail
+            class="content__module"
+            :show-title="false"
+            :composite-data="config.data"
+            :topconfig="config.config.topconfig"
+            :btnconfig="config.config.btnconfig"
+          />
+        </template>
+        <template v-if="config.name === 'partition'">
+          <Partition class="content__module" :type="config.type" :label="config.label" :icon="config.icon" />
+        </template>
+        <template v-if="config.name === 'selector_dual_chart'">
+          <SelectorDualChart :data="config.data" :moduleData="props.moduleData" :config="config" />
+        </template>
+        <template v-if="config.name === 'radio_label'">
+          <RadioLabel class="content__module" :type="config.config.type" :config="config.config" />
+        </template>
+        <template v-if="config.name === 'button_list'">
+          <ButtonList class="content__module" :type="config.config.type" :config="config.config" :buttonList="config.config.buttonList" />
+        </template>
+        <!-- <template v-if="config.key === 'fire_control'">
+        <FIreControl class="content__module" />
+      </template>
+      <template v-if="config.key === 'fire_warn'">
+        <FIreWarn class="content__module" />
+      </template> -->
+      </div>
+    </div>
+  </div>
+</template>
+<script lang="ts" setup>
+import { computed } from 'vue';
+import {
+  CommonItem,
+  Config,
+  // ModuleDataBoard,
+  // ModuleDataChart,
+  // ModuleDataList,
+  // ModuleDataPreset,
+  // ModuleDataTable,
+} from '../../../deviceManager/configurationTable/types';
+import MiniBoard from '../../components/detail/MiniBoard.vue';
+import TimelineList from '../../components/detail/TimelineList.vue';
+import TimelineListNew from '../../components/detail/TimelineListNew.vue';
+import CustomList from '../../components/detail/CustomList.vue';
+import CustomGallery from '../../components/detail/CustomGallery.vue';
+import ComplexList from '../../components/detail/ComplexList.vue';
+import GalleryList from '../../components/detail/GalleryList.vue';
+import CustomTable from '../../components/detail/CustomTable.vue';
+import CustomChart from '../../components/detail/CustomChart.vue';
+import { clone } from 'lodash-es';
+import { getData, getFormattedText } from '../../hooks/helper';
+import BlastDelta from '../../../../monitorManager/deviceMonitor/components/device/modal/blastDelta.vue';
+import QHCurve from '../../components/preset/QHCurve.vue';
+import MeasureDetail from '../../components/preset/MeasureDetail.vue';
+import CustomTabs from '../../components/preset/CustomTabs.vue';
+import AIChat from '/@/components/AIChat/MiniChat.vue';
+import DeviceAlarm from '../../components/preset/DeviceAlarm.vue';
+import SelectCs from '../../components/preset/SelectCs.vue';
+import MiniBoardNew from '../../components/detail/MiniBoard-New.vue';
+import Partition from '../../components/preset/partition.vue';
+import SelectorDualChart from '../../components/preset/selectorDualChart.vue';
+import RadioLabel from '../../components/preset/radioLabel.vue';
+import ButtonList from '../../components/preset/buttonList.vue';
+// import FIreWarn from './preset/FIreWarn.vue';
+// import FIreControl from './preset/FIreControl.vue';
+
+const props = defineProps<{
+  data: any;
+  moduleData: Config['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),
+    };
+  });
+}
+
+// 获取当 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 {
+        ...item,
+        label: getFormattedText(data, item.label, item.trans),
+        value: getFormattedText(data, item.value, item.trans),
+      };
+    });
+  }
+  return getItems(raw, items);
+}
+
+/** 根据配置里的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) || [];
+
+  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: getItems(data, cfg.items),
+        });
+        break;
+      }
+      case 'list': {
+        const cfg = list.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({
+            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);
+
+        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({
+            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) break;
+        const data = getData(refData, cfg.readFrom, cfg.parser);
+
+        arr.push({
+          ...item,
+          config: cfg,
+          data,
+        });
+        break;
+      }
+      case 'table': {
+        const cfg = table.shift();
+        if (!cfg) break;
+        const data = getData(refData, cfg.readFrom, cfg.parser);
+
+        arr.push({
+          ...cfg,
+          ...item,
+          columns: cfg.columns,
+          data,
+        });
+        break;
+      }
+      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>
+<style lang="less" scoped>
+@import '@/design/theme.less';
+
+.content {
+  height: calc(100% - 30px);
+  position: relative;
+  // z-index: -2;
+  display: flex;
+  flex-direction: column;
+  overflow-y: auto; // 这里会导致样式无故添加滚动条
+}
+
+.content__background {
+  width: 100%;
+  height: 100%;
+  position: absolute;
+  top: 0;
+  left: 0;
+  z-index: 0;
+  object-fit: fill;
+}
+
+.image__background {
+  width: 35%;
+  height: 61%;
+  left: 30%;
+}
+
+.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__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: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;
+}
+
+: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-selection-item) {
+  color: #fff !important;
+}
+
+:deep(.zxm-select-selection-placeholder) {
+  color: #fff !important;
+}
+
+:deep(.dialog-overlay) {
+  width: 100%;
+  height: 100%;
+  position: unset;
+  box-shadow: unset;
+}
+
+::-webkit-scrollbar {
+  width: 5px !important;
+}
+
+::-webkit-scrollbar-thumb {
+  width: 5px !important;
+}
+</style>

+ 0 - 0
src/views/vent/home/configurable/components/detail/MiniBoard-Warn.vue → src/views/vent/home/configurable/bule/components/detail/MiniBoard-Warn.vue


+ 109 - 0
src/views/vent/home/configurable/bule/components/header.vue

@@ -0,0 +1,109 @@
+<!-- eslint-disable vue/multi-word-component-names -->
+<template>
+  <!-- Header部分 -->
+  <div v-if="headerConfig.show" class="w-100% flex costume-header">
+    <!-- 选择下拉框,自动填充剩余空间,这种实现是因为 Select 不支持 suffix -->
+    <Dropdown
+      v-if="headerConfig.selector.show"
+      class="flex-grow-1 costume-header_left"
+      :trigger="['click']"
+      :bordered="false"
+      @open-change="visible = $event"
+    >
+      <div class="flex-basis-100% flex flex-items-center" @click.prevent>
+        <SwapOutlined class="w-30px" />
+        <div class="w-100px flex-grow-1 overflow-hidden whitespace-nowrap text-ellipsis">
+          {{ selectedDeviceLabel }}
+        </div>
+        <CaretUpOutlined class="w-30px" v-if="visible" />
+        <CaretDownOutlined class="w-30px" v-else />
+      </div>
+      <template #overlay>
+        <Menu :selected-keys="[selectedDeviceID]" @click="selectHandler">
+          <MenuItem v-for="item in options" :key="item.value" :title="item.label">
+            {{ item.label }}
+          </MenuItem>
+        </Menu>
+      </template>
+    </Dropdown>
+    <template v-if="headerConfig.slot.show">
+      <div class="flex-basis-50% flex flex-items-center flex-grow-1 costume-header_right">
+        <SwapOutlined class="w-30px" />
+        <div class="flex-grow-1">
+          {{ selectedDeviceSlot }}
+        </div>
+      </div>
+    </template>
+  </div>
+</template>
+<script lang="ts" setup>
+import { ref, watch } from 'vue';
+import { Config } from '../../../../deviceManager/configurationTable/types';
+import { useInitModule } from '../../hooks/useInit';
+import { MenuItem, Menu, Dropdown } from 'ant-design-vue';
+import { SwapOutlined, CaretUpOutlined, CaretDownOutlined } from '@ant-design/icons-vue';
+
+const props = defineProps<{
+  moduleData: Config['moduleData'];
+  deviceType: Config['deviceType'];
+  data: any;
+}>();
+
+const emit = defineEmits(['select']);
+
+const visible = ref(false);
+const headerConfig = props.moduleData.header;
+const { selectedDeviceID, selectedDevice, selectedDeviceSlot, selectedDeviceLabel, options, init } = useInitModule(
+  props.deviceType,
+  props.moduleData
+);
+
+function selectHandler({ key }) {
+  selectedDeviceID.value = key;
+  emit('select', selectedDevice.value);
+}
+
+watch(
+  () => props.data,
+  (d) => {
+    init(d);
+    emit('select', selectedDevice.value);
+  },
+  {
+    immediate: true,
+  }
+);
+</script>
+<style scoped>
+@import '/@/design/theme.less';
+
+.costume-header {
+  height: 30px;
+  background-image: linear-gradient(90deg, var(--vent-base-light-bg-opcity), transparent 20%, transparent 80%, var(--vent-base-light-bg-opcity));
+}
+.costume-header_left {
+  border-left: 3px solid;
+  border-right: 3px solid;
+  border-image-source: linear-gradient(to top, #00000033, var(--vent-base-light-bg), #00000033);
+  border-image-slice: 1;
+}
+.costume-header_right {
+  border-right: 3px solid;
+  border-image-source: linear-gradient(to top, #00000033, var(--vent-base-light-bg), #00000033);
+  border-image-slice: 1;
+}
+
+::v-deep .zxm-select:not(.zxm-select-customize-input) .zxm-select-selector {
+  /* background-color: transparent; */
+  color: #fff;
+}
+::v-deep .zxm-select-arrow {
+  color: #fff;
+}
+::v-deep .zxm-select-selection-item {
+  color: #fff !important;
+}
+::v-deep .zxm-select-selection-placeholder {
+  color: #fff !important;
+}
+</style>

+ 0 - 0
src/views/vent/home/configurable/components/original/moduleBottom-warn.vue → src/views/vent/home/configurable/bule/components/moduleBottom-warn.vue


+ 17 - 3
src/views/vent/home/configurable/components/original/moduleLeft-warn.vue → src/views/vent/home/configurable/bule/components/moduleLeft-warn.vue

@@ -1,5 +1,5 @@
 <template>
-  <div v-if="visible" class="module-content">
+  <div v-if="visible" :class="deviceType === 'warnInfo' ? 'module-content1' : 'module-content'">
     <div v-if="title" class="module-content__title__expand">
       <span class="action-btn close-btn" @click="closeModel"></span>
       <span @click="clickHandler">{{ title }}</span>
@@ -10,8 +10,13 @@
   </div>
 </template>
 <script lang="ts" setup>
-defineProps<{ title: string; visible: boolean }>();
+const props = defineProps<{
+  deviceType: string;
+  title: string;
+  visible: boolean;
+}>();
 const emit = defineEmits(['close', 'click']);
+const deviceType = props.deviceType;
 
 function closeModel() {
   emit('close');
@@ -28,7 +33,16 @@ function clickHandler() {
     --image-model_original_title_bg: url('@/assets/images/themify/deepblue/home-container/configurable/model_original_title_bg.png');
   }
 }
-
+.module-content1 {
+  --bg-height: 28px;
+  color: #fff;
+  box-sizing: border-box;
+  position: absolute;
+  width: 100%;
+  height: 100%;
+  z-index: 999;
+  padding: 15px 15px 0px 15px;
+}
 .module-content {
   --bg-height: 28px;
   color: #fff;

+ 283 - 0
src/views/vent/home/configurable/bule/components/originalNew/NewNav.vue

@@ -0,0 +1,283 @@
+<!-- eslint-disable vue/multi-word-component-names -->
+<template>
+  <div class="New-nav">
+    <div class="main-title">{{ Title }}</div>
+    <!-- menu区域 -->
+    <div class="nav-menu">
+      <div class="nav-menu-left">
+        <div v-for="(item, index) in leftMenus" :key="index">
+          <div :class="activeIndex == index ? 'nav-menu-active' : 'nav-menu-unactive'" :key="index" @click="menuClick({ item, index })">
+            <div style="color: #ddd">{{ item.name }}</div>
+
+            <div v-if="activeIndex == index && isShowMenuItem" class="nav-menu-item">
+              <div class="nav-menu-content">
+                <div class="nav-menu-List">
+                  <div
+                    :class="menuItemActive == ind ? 'menu-item-active' : 'menu-item-unactive'"
+                    v-for="(ite, ind) in item.MenuItemList"
+                    :key="ind"
+                    @click.stop="menuItemClick(ind)"
+                    >{{ ite.name }}</div
+                  >
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+      <div class="nav-menu-right">
+        <div v-for="(item, index) in rightMenus" :key="index + 4">
+          <div
+            :class="activeIndex == index + 4 ? 'nav-menu-active' : 'nav-menu-unactive'"
+            :key="index + 4"
+            @click="menuClick({ item, index: index + 4 })"
+          >
+            <div style="color: #ddd">{{ item.name }}</div>
+            <div v-if="activeIndex == index + 4 && isShowMenuItem" class="nav-menu-item">
+              <div class="nav-menu-content">
+                <div class="nav-menu-List">
+                  <div
+                    :class="menuItemActive == ind ? 'menu-item-active' : 'menu-item-unactive'"
+                    v-for="(ite, ind) in item.MenuItemList"
+                    :key="ind"
+                    @click.stop="menuItemClick(ind)"
+                    >{{ ite.name }}</div
+                  >
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+<script lang="ts" setup>
+import { onMounted, onUnmounted, ref, watch, computed } from 'vue';
+import { useRouter, useRoute } from 'vue-router';
+let props = defineProps({
+  Title: {
+    type: String,
+    default: '',
+  },
+});
+
+let menuList = ref<any[]>([
+  {
+    name: '智能通风',
+    targatUrl: '/micro-vent-3dModal/configurable/ventNew/home',
+  },
+  {
+    name: '火灾监控',
+    targatUrl: '/micro-vent-3dModal/configurable/fireNew/home',
+  },
+  {
+    name: '粉尘监控',
+    targatUrl: '/micro-vent-3dModal/configurable/dustNew/home',
+  },
+  {
+    name: '瓦斯监控',
+    MenuItemList: [{ name: '多灾融合预警' }, { name: '通风监测预警' }, { name: '火灾监测预警' }, { name: '粉尘监测预警' }, { name: '瓦斯监测预警' }],
+  },
+  {
+    name: '灾害预警',
+    MenuItemList: [{ name: '多灾融合预警' }, { name: '通风监测预警' }, { name: '火灾监测预警' }, { name: '粉尘监测预警' }, { name: '瓦斯监测预警' }],
+  },
+]); //一级菜单列表
+let activeIndex = ref(0); //当前激活menu索引
+const router = useRouter();
+const route = useRoute();
+let isShowMenuItem = ref(false); //是否显示menuItem下拉选项菜单
+let menuItemActive = ref(0); //menuItem当前激活选项
+const leftMenus = computed(() => menuList.value.slice(0, 4));
+const rightMenus = computed(() => menuList.value.slice(4));
+function menuClick(data) {
+  activeIndex.value = data.index;
+  isShowMenuItem.value = !isShowMenuItem.value;
+  router.push({ path: data.item.targatUrl });
+}
+function menuItemClick(index) {
+  menuItemActive.value = index;
+  isShowMenuItem.value = false;
+}
+function updateActiveState(path: string) {
+  menuList.value.forEach((menu, index) => {
+    // 处理有直接链接的菜单项
+    if (menu.targatUrl === path) {
+      activeIndex.value = index;
+      isShowMenuItem.value = false;
+      return;
+    }
+    // 处理有子菜单的菜单项
+    if (menu.MenuItemList) {
+      const itemIndex = menu.MenuItemList.findIndex((item) => item.targatUrl === path);
+      if (itemIndex !== -1) {
+        activeIndex.value = index;
+        menuItemActive.value = itemIndex;
+        isShowMenuItem.value = true;
+      }
+    }
+  });
+}
+watch(
+  () => route.path,
+  (newPath) => {
+    updateActiveState(newPath);
+  }
+);
+onMounted(() => {
+  updateActiveState(route.path);
+});
+</script>
+<style lang="less" scoped>
+@import '/@/design/theme.less';
+
+@font-face {
+  font-family: 'douyuFont';
+  src: url('/@/assets/font/douyuFont.otf');
+}
+
+.New-nav {
+  position: relative;
+  width: 100%;
+  height: 100%;
+
+  .main-title {
+    width: 518px;
+    height: 100%;
+    display: flex;
+    align-items: center;
+    font-family: 'douyuFont';
+    font-size: 25px;
+    position: absolute;
+    left: 50%;
+    transform: translateX(-50%);
+    width: auto;
+    padding: 0;
+  }
+
+  .nav-menu {
+    position: absolute;
+    top: 0;
+    left: 675px;
+    height: 100%;
+    display: flex;
+    position: static; // 移除绝对定位
+    display: flex;
+    width: auto;
+    .nav-menu-left {
+      display: flex;
+      flex-direction: row;
+      align-items: center;
+      float: left;
+    }
+    .nav-menu-right {
+      display: flex;
+      flex-direction: row;
+      align-items: center;
+      float: left;
+      margin-left: 40%;
+    }
+    .nav-menu-active {
+      position: relative;
+      cursor: pointer;
+      width: 120px;
+      height: 60px;
+      margin-top: 20px;
+      line-height: 45px;
+      text-align: center;
+      font-size: 16px;
+      letter-spacing: 2px;
+      background: url('@/assets/images/vent/homeNew/Select-btn.png') no-repeat;
+      background-size: 100% 100%;
+    }
+
+    .nav-menu-unactive {
+      position: relative;
+      width: 120px;
+      height: 60px;
+      line-height: 65px;
+      text-align: center;
+      margin: 0px 10px;
+      font-size: 16px;
+      letter-spacing: 2px;
+      background-size: 100% 100%;
+      cursor: pointer;
+    }
+
+    .nav-menu-item {
+      position: absolute;
+      top: 23px;
+      width: 130px;
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      box-sizing: border-box;
+
+      .nav-menu-content {
+        width: 100%;
+        height: 100%;
+        overflow-y: auto;
+        margin-top: 25%;
+        .nav-menu-List {
+          background: url('@/assets/images/vent/homeNew/menuList.png') no-repeat;
+          background-size: 100% 100%;
+        }
+        .menu-item-active {
+          color: #ddd;
+          z-index: 999;
+          width: 100%;
+          height: 36px;
+          line-height: 36px;
+          font-size: 14px;
+          background: url('@/assets/images/vent/homeNew/selectActive.png') no-repeat;
+          background-size: 100% 100%;
+        }
+
+        .menu-item-unactive {
+          color: #ddd;
+          width: 100%;
+          height: 40px;
+          line-height: 40px;
+          font-size: 14px;
+        }
+      }
+    }
+
+    @keyframes fadeIn {
+      from {
+        opacity: 0;
+      }
+
+      to {
+        opacity: 1;
+      }
+    }
+
+    /* 定义淡出动画 */
+    @keyframes fadeOut {
+      from {
+        opacity: 1;
+      }
+
+      to {
+        opacity: 0;
+      }
+    }
+  }
+
+  .userInfo {
+    width: 120px;
+    float: right;
+    background: url(/src/assets/images/vent/homeNew/user.png) no-repeat;
+    background-size: 100% 100%;
+    position: absolute;
+    top: 14px;
+    right: 0;
+    .userName {
+      margin-left: 40px;
+      font-size: 20px;
+    }
+  }
+}
+</style>

+ 319 - 0
src/views/vent/home/configurable/bule/components/originalNew/NewNavFire.vue

@@ -0,0 +1,319 @@
+<!-- eslint-disable vue/multi-word-component-names -->
+<template>
+  <div class="New-nav">
+    <div class="main-title">{{ Title }}</div>
+    <!-- menu区域 -->
+    <div class="nav-menu">
+      <div v-if="!disabled" class="nav-menu-left">
+        <div v-for="(item, index) in leftMenus" :key="index">
+          <div :class="activeIndex == index ? 'nav-menu-active' : 'nav-menu-unactive'" :key="index" @click="menuClick({ item, index })">
+            <div style="color: #ddd">{{ item.name }}</div>
+
+            <div v-if="activeIndex == index && isShowMenuItem" class="nav-menu-item">
+              <div class="nav-menu-content">
+                <div class="nav-menu-List">
+                  <div
+                    :class="menuItemActive == ind ? 'menu-item-active' : 'menu-item-unactive'"
+                    v-for="(ite, ind) in item.MenuItemList"
+                    :key="ind"
+                    @click.stop="menuItemClick(ind)"
+                    >{{ ite.name }}</div
+                  >
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+      <div v-if="!disabled" class="nav-menu-right">
+        <div v-for="(item, index) in rightMenus" :key="index + 4">
+          <div
+            :class="activeIndex == index + 4 ? 'nav-menu-active' : 'nav-menu-unactive'"
+            :key="index + 4"
+            @click="menuClick({ item, index: index + 4 })"
+          >
+            <div style="color: #ddd">{{ item.name }}</div>
+            <div v-if="activeIndex == index + 4 && isShowMenuItem && !disabled" class="nav-menu-item">
+              <div class="nav-menu-content">
+                <div class="nav-menu-List">
+                  <div
+                    :class="menuItemActive == ind ? 'menu-item-active' : 'menu-item-unactive'"
+                    v-for="(ite, ind) in item.MenuItemList"
+                    :key="ind"
+                    @click.stop="menuItemClick(ind)"
+                    >{{ ite.name }}</div
+                  >
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+<script lang="ts" setup>
+import { onMounted, onUnmounted, ref, watch, computed } from 'vue';
+import { useRouter, useRoute } from 'vue-router';
+let props = defineProps({
+  Title: {
+    type: String,
+    default: '',
+  },
+  disabled: {
+    type: Boolean,
+    default: false,
+  },
+});
+
+let menuList = ref<any[]>([
+  {
+    name: '智能通风',
+    targatUrl: '/micro-vent-3dModal/configurable/ventNew/home',
+  },
+  {
+    name: '火灾监控',
+    targatUrl: '/micro-vent-3dModal/configurable/fireNew/home',
+  },
+  {
+    name: '粉尘监控',
+    targatUrl: '/micro-vent-3dModal/configurable/dustNew/home',
+  },
+  {
+    name: '瓦斯监控',
+    MenuItemList: [{ name: '多灾融合预警' }, { name: '通风监测预警' }, { name: '火灾监测预警' }, { name: '粉尘监测预警' }, { name: '瓦斯监测预警' }],
+  },
+  {
+    name: '灾害预警',
+    MenuItemList: [{ name: '多灾融合预警' }, { name: '通风监测预警' }, { name: '火灾监测预警' }, { name: '粉尘监测预警' }, { name: '瓦斯监测预警' }],
+  },
+]); //一级菜单列表
+let activeIndex = ref(0); //当前激活menu索引
+const router = useRouter();
+const route = useRoute();
+let isShowMenuItem = ref(false); //是否显示menuItem下拉选项菜单
+let menuItemActive = ref(0); //menuItem当前激活选项
+const leftMenus = computed(() => menuList.value.slice(0, 4));
+const rightMenus = computed(() => menuList.value.slice(4));
+function menuClick(data) {
+  activeIndex.value = data.index;
+  isShowMenuItem.value = !isShowMenuItem.value;
+  router.push({ path: data.item.targatUrl });
+}
+function menuItemClick(index) {
+  menuItemActive.value = index;
+  isShowMenuItem.value = false;
+}
+function updateActiveState(path: string) {
+  menuList.value.forEach((menu, index) => {
+    // 处理有直接链接的菜单项
+    if (menu.targatUrl === path) {
+      activeIndex.value = index;
+      isShowMenuItem.value = false;
+      return;
+    }
+    // 处理有子菜单的菜单项
+    if (menu.MenuItemList) {
+      const itemIndex = menu.MenuItemList.findIndex((item) => item.targatUrl === path);
+      if (itemIndex !== -1) {
+        activeIndex.value = index;
+        menuItemActive.value = itemIndex;
+        isShowMenuItem.value = true;
+      }
+    }
+  });
+}
+watch(
+  () => route.path,
+  (newPath) => {
+    updateActiveState(newPath);
+  },
+  {
+    immediate: true,
+  }
+);
+onMounted(() => {
+  updateActiveState(route.path);
+});
+</script>
+<style lang="less" scoped>
+@import '/@/design/theme.less';
+
+@font-face {
+  font-family: 'douyuFont';
+  src: url('/@/assets/font/douyuFont.otf');
+}
+
+.New-nav {
+  position: relative;
+  width: 100%;
+  height: 100%;
+
+  .main-title {
+    width: 518px;
+    height: 100%;
+    display: flex;
+    align-items: center;
+    font-family: 'douyuFont';
+    font-size: 25px;
+    position: absolute;
+    left: 50%;
+    transform: translateX(-50%);
+    width: auto;
+    padding: 0;
+    color: #fff;
+  }
+
+  .nav-menu {
+    position: absolute;
+    top: 0;
+    left: 675px;
+    height: 100%;
+    display: flex;
+    position: static; // 移除绝对定位
+    display: flex;
+    width: auto;
+    .nav-menu-left {
+      display: flex;
+      flex-direction: row;
+      align-items: center;
+      float: left;
+      .nav-menu-active {
+        position: relative;
+        cursor: pointer;
+        width: 100px;
+        height: 40px;
+        margin-top: 10px;
+        margin-right: 40px;
+        line-height: 35px;
+        text-align: center;
+        font-size: 16px;
+        background: url(/src/assets/images/fireNew/2-1.png) no-repeat;
+        background-size: 100% 100%;
+      }
+
+      .nav-menu-unactive {
+        position: relative;
+        cursor: pointer;
+        width: 100px;
+        height: 40px;
+        margin-top: 10px;
+        margin-right: 40px;
+        line-height: 35px;
+        text-align: center;
+        font-size: 16px;
+        background: url(/src/assets/images/fireNew/2-2.png) no-repeat;
+        background-size: 100% 100%;
+      }
+    }
+    .nav-menu-right {
+      display: flex;
+      flex-direction: row;
+      align-items: center;
+      float: left;
+      margin-left: 42%;
+      .nav-menu-active {
+        position: relative;
+        cursor: pointer;
+        width: 100px;
+        height: 40px;
+        margin-top: 10px;
+        margin-right: 40px;
+        line-height: 35px;
+        text-align: center;
+        font-size: 16px;
+        background: url(/src/assets/images/fireNew/2-3.png) no-repeat;
+        background-size: 100% 100%;
+      }
+
+      .nav-menu-unactive {
+        position: relative;
+        cursor: pointer;
+        width: 100px;
+        height: 40px;
+        margin-top: 10px;
+        margin-right: 40px;
+        line-height: 35px;
+        text-align: center;
+        font-size: 16px;
+        background: url(/src/assets/images/fireNew/2-4.png) no-repeat;
+        background-size: 100% 100%;
+      }
+    }
+
+    .nav-menu-item {
+      position: absolute;
+      top: 23px;
+      width: 130px;
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      box-sizing: border-box;
+
+      .nav-menu-content {
+        width: 100%;
+        height: 100%;
+        overflow-y: auto;
+        margin-top: 25%;
+        .nav-menu-List {
+          background: url('@/assets/images/vent/homeNew/menuList.png') no-repeat;
+          background-size: 100% 100%;
+        }
+        .menu-item-active {
+          color: #ddd;
+          z-index: 999;
+          width: 100%;
+          height: 36px;
+          line-height: 36px;
+          font-size: 14px;
+          background: url('@/assets/images/fireNew/2-2.png') no-repeat;
+          background-size: 100% 100%;
+        }
+
+        .menu-item-unactive {
+          color: #ddd;
+          width: 100%;
+          height: 40px;
+          line-height: 40px;
+          font-size: 14px;
+        }
+      }
+    }
+
+    @keyframes fadeIn {
+      from {
+        opacity: 0;
+      }
+
+      to {
+        opacity: 1;
+      }
+    }
+
+    /* 定义淡出动画 */
+    @keyframes fadeOut {
+      from {
+        opacity: 1;
+      }
+
+      to {
+        opacity: 0;
+      }
+    }
+  }
+
+  .userInfo {
+    width: 120px;
+    float: right;
+    background: url(/src/assets/images/vent/homeNew/user.png) no-repeat;
+    background-size: 100% 100%;
+    position: absolute;
+    top: 14px;
+    right: 0;
+    .userName {
+      margin-left: 40px;
+      font-size: 20px;
+    }
+  }
+}
+</style>

+ 295 - 0
src/views/vent/home/configurable/bule/components/originalNew/NewNavWarn.vue

@@ -0,0 +1,295 @@
+<!-- eslint-disable vue/multi-word-component-names -->
+<template>
+  <div class="New-nav">
+    <div class="main-title">{{ Title }}</div>
+    <!-- menu区域 -->
+    <div class="nav-menu">
+      <div class="nav-menu-left">
+        <div v-for="(item, index) in leftMenus" :key="index">
+          <div :class="activeIndex == index ? 'nav-menu-active' : 'nav-menu-unactive'" :key="index" @click="menuClick({ item, index })">
+            <div style="color: #ddd">{{ item.name }}</div>
+
+            <div v-if="activeIndex == index && isShowMenuItem" class="nav-menu-item">
+              <div class="nav-menu-content">
+                <div class="nav-menu-List">
+                  <div
+                    :class="menuItemActive == ind ? 'menu-item-active' : 'menu-item-unactive'"
+                    v-for="(ite, ind) in item.MenuItemList"
+                    :key="ind"
+                    @click.stop="menuItemClick(ind)"
+                    >{{ ite.name }}</div
+                  >
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+      <div class="nav-menu-right">
+        <div v-for="(item, index) in rightMenus" :key="index + 4">
+          <div
+            :class="activeIndex == index + 4 ? 'nav-menu-active' : 'nav-menu-unactive'"
+            :key="index + 4"
+            @click="menuClick({ item, index: index + 4 })"
+          >
+            <div style="color: #ddd">{{ item.name }}</div>
+            <div v-if="activeIndex == index + 4 && isShowMenuItem" class="nav-menu-item">
+              <div class="nav-menu-content">
+                <div class="nav-menu-List">
+                  <div
+                    :class="menuItemActive == ind ? 'menu-item-active' : 'menu-item-unactive'"
+                    v-for="(ite, ind) in item.MenuItemList"
+                    :key="ind"
+                    @click.stop="menuItemClick(ind)"
+                    >{{ ite.name }}</div
+                  >
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+<script lang="ts" setup>
+  import { onMounted, onUnmounted, ref, watch, computed } from 'vue';
+  import { useRouter, useRoute } from 'vue-router';
+  let props = defineProps({
+    Title: {
+      type: String,
+      default: '',
+    },
+  });
+
+  let menuList = ref<any[]>([
+    {
+      name: '智能通风',
+      targatUrl: '/micro-vent-3dModal/configurable/ventNew/home',
+    },
+    {
+      name: '火灾监控',
+      targatUrl: '/micro-vent-3dModal/configurable/fireNew/home',
+    },
+    {
+      name: '粉尘监控',
+      targatUrl: '/micro-vent-3dModal/configurable/dustNew/home',
+    },
+    {
+      name: '瓦斯监控',
+      MenuItemList: [
+        { name: '多灾融合预警' },
+        { name: '通风监测预警' },
+        { name: '火灾监测预警' },
+        { name: '粉尘监测预警' },
+        { name: '瓦斯监测预警' },
+      ],
+    },
+    {
+      name: '灾害预警',
+      MenuItemList: [
+        { name: '多灾融合预警' },
+        { name: '通风监测预警' },
+        { name: '火灾监测预警' },
+        { name: '粉尘监测预警' },
+        { name: '瓦斯监测预警' },
+      ],
+    },
+  ]); //一级菜单列表
+  let activeIndex = ref(0); //当前激活menu索引
+  const router = useRouter();
+  const route = useRoute();
+  let isShowMenuItem = ref(false); //是否显示menuItem下拉选项菜单
+  let menuItemActive = ref(0); //menuItem当前激活选项
+  const leftMenus = computed(() => menuList.value.slice(0, 4));
+  const rightMenus = computed(() => menuList.value.slice(4));
+  function menuClick(data) {
+    activeIndex.value = data.index;
+    isShowMenuItem.value = !isShowMenuItem.value;
+    router.push({ path: data.item.targatUrl });
+  }
+  function menuItemClick(index) {
+    menuItemActive.value = index;
+    isShowMenuItem.value = false;
+  }
+  function updateActiveState(path: string) {
+    menuList.value.forEach((menu, index) => {
+      // 处理有直接链接的菜单项
+      if (menu.targatUrl === path) {
+        activeIndex.value = index;
+        isShowMenuItem.value = false;
+        return;
+      }
+      // 处理有子菜单的菜单项
+      if (menu.MenuItemList) {
+        const itemIndex = menu.MenuItemList.findIndex((item) => item.targatUrl === path);
+        if (itemIndex !== -1) {
+          activeIndex.value = index;
+          menuItemActive.value = itemIndex;
+          isShowMenuItem.value = true;
+        }
+      }
+    });
+  }
+  watch(
+    () => route.path,
+    (newPath) => {
+      updateActiveState(newPath);
+    }
+  );
+  onMounted(() => {
+    updateActiveState(route.path);
+  });
+</script>
+<style lang="less" scoped>
+  @import '/@/design/theme.less';
+
+  @font-face {
+    font-family: 'douyuFont';
+    src: url('/@/assets/font/douyuFont.otf');
+  }
+
+  .New-nav {
+    position: relative;
+    width: 100%;
+    height: 100%;
+
+    .main-title {
+      width: 518px;
+      height: 100%;
+      display: flex;
+      align-items: center;
+      font-family: 'douyuFont';
+      font-size: 25px;
+      position: absolute;
+      left: 50%;
+      transform: translateX(-50%);
+      width: auto;
+      padding: 0;
+    }
+
+    .nav-menu {
+      position: absolute;
+      top: 0;
+      left: 675px;
+      height: 100%;
+      display: flex;
+      position: static; // 移除绝对定位
+      display: flex;
+      width: auto;
+      .nav-menu-left {
+        display: flex;
+        flex-direction: row;
+        align-items: center;
+        float: left;
+      }
+      .nav-menu-right {
+        display: flex;
+        flex-direction: row;
+        align-items: center;
+        float: left;
+        margin-left: 40%;
+      }
+      .nav-menu-active {
+        position: relative;
+        cursor: pointer;
+        width: 120px;
+        height: 60px;
+        margin-top: 20px;
+        line-height: 45px;
+        text-align: center;
+        font-size: 16px;
+        letter-spacing: 2px;
+        background: url('@/assets/images/vent/homeNew/Select-btn.png') no-repeat;
+        background-size: 100% 100%;
+      }
+
+      .nav-menu-unactive {
+        position: relative;
+        width: 120px;
+        height: 60px;
+        line-height: 65px;
+        text-align: center;
+        margin: 0px 10px;
+        font-size: 16px;
+        letter-spacing: 2px;
+        background-size: 100% 100%;
+        cursor: pointer;
+      }
+
+      .nav-menu-item {
+        position: absolute;
+        top: 23px;
+        width: 130px;
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        box-sizing: border-box;
+
+        .nav-menu-content {
+          width: 100%;
+          height: 100%;
+          overflow-y: auto;
+          margin-top: 25%;
+          .nav-menu-List {
+            background: url('@/assets/images/vent/homeNew/menuList.png') no-repeat;
+            background-size: 100% 100%;
+          }
+          .menu-item-active {
+            color: #ddd;
+            z-index: 999;
+            width: 100%;
+            height: 36px;
+            line-height: 36px;
+            font-size: 14px;
+            background: url('@/assets/images/vent/homeNew/selectActive.png') no-repeat;
+            background-size: 100% 100%;
+          }
+
+          .menu-item-unactive {
+            color: #ddd;
+            width: 100%;
+            height: 40px;
+            line-height: 40px;
+            font-size: 14px;
+          }
+        }
+      }
+
+      @keyframes fadeIn {
+        from {
+          opacity: 0;
+        }
+
+        to {
+          opacity: 1;
+        }
+      }
+
+      /* 定义淡出动画 */
+      @keyframes fadeOut {
+        from {
+          opacity: 1;
+        }
+
+        to {
+          opacity: 0;
+        }
+      }
+    }
+
+    .userInfo {
+      width: 120px;
+      float: right;
+      background: url(/src/assets/images/vent/homeNew/user.png) no-repeat;
+      background-size: 100% 100%;
+      position: absolute;
+      top: 14px;
+      right: 0;
+      .userName {
+        margin-left: 40px;
+        font-size: 20px;
+      }
+    }
+  }
+</style>

+ 95 - 0
src/views/vent/home/configurable/bule/components/originalNew/leftHeader1.vue

@@ -0,0 +1,95 @@
+<!-- eslint-disable vue/multi-word-component-names -->
+<template>
+  <!-- Header部分 -->
+  <div v-if="headerConfig.show" class="w-100% flex costume-header">
+    <!-- 选择下拉框,自动填充剩余空间,这种实现是因为 Select 不支持 suffix -->
+    <Dropdown
+      v-if="headerConfig.selector.show"
+      class="flex-grow-1 costume-header_left"
+      :trigger="['click']"
+      :bordered="false"
+      @open-change="visible = $event"
+    >
+      <div class="flex-basis-100% flex flex-items-center" @click.prevent>
+        <div class="headerType w-100px flex-grow-1 overflow-hidden whitespace-nowrap text-ellipsis">
+          {{ selectedDeviceLabel }}
+        </div>
+        <CaretUpOutlined class="w-30px" v-if="visible" />
+        <CaretDownOutlined class="w-30px" v-else />
+      </div>
+      <template #overlay>
+        <Menu :selected-keys="[selectedDeviceID]" @click="selectHandler">
+          <MenuItem v-for="item in options" :key="item.value" :title="item.label">
+            {{ item.label }}
+          </MenuItem>
+        </Menu>
+      </template>
+    </Dropdown>
+    <template v-if="headerConfig.slot.show">
+      <div class="divider"> </div>
+      <div class="headerType flex-basis-80% flex flex-items-center flex-grow-1 costume-header_right">
+        <div class="flex-grow-1">
+          {{ selectedDeviceSlot }}
+        </div>
+      </div>
+    </template>
+  </div>
+</template>
+<script lang="ts" setup>
+import { ref, watch } from 'vue';
+import { Config } from '../../../../../deviceManager/configurationTable/types';
+import { useInitModule } from '../../../hooks/useInit';
+import { MenuItem, Menu, Dropdown } from 'ant-design-vue';
+import { SwapOutlined, CaretUpOutlined, CaretDownOutlined } from '@ant-design/icons-vue';
+
+const props = defineProps<{
+  moduleData: Config['moduleData'];
+  deviceType: Config['deviceType'];
+  data: any;
+}>();
+
+const emit = defineEmits(['select']);
+
+const visible = ref(false);
+const headerConfig = props.moduleData.header;
+const { selectedDeviceID, selectedDevice, selectedDeviceSlot, selectedDeviceLabel, options, init } = useInitModule(
+  props.deviceType,
+  props.moduleData
+);
+
+function selectHandler({ key }) {
+  selectedDeviceID.value = key;
+  emit('select', selectedDevice.value);
+}
+
+watch(
+  () => props.data,
+  (d) => {
+    init(d);
+    emit('select', selectedDevice.value);
+  },
+  {
+    immediate: true,
+  }
+);
+</script>
+<style scoped>
+@import '/@/design/theme.less';
+
+.costume-header {
+  height: 30px;
+  margin-bottom: 10px;
+  width: 111%;
+  background: url('@/assets/images/vent/homeNew/Left-top.png') no-repeat;
+  background-size: 100% 100%;
+}
+.costume-header_left {
+}
+.costume-header_right {
+}
+.divider {
+  width: 40px;
+  background: url('@/assets/images/vent/homeNew/left-divider.png') no-repeat;
+  background-size: 100% 100%;
+}
+</style>

+ 89 - 0
src/views/vent/home/configurable/bule/components/originalNew/leftHeader2.vue

@@ -0,0 +1,89 @@
+<!-- eslint-disable vue/multi-word-component-names -->
+<template>
+  <!-- Header部分 -->
+  <div v-if="headerConfig.show" class="w-100% flex costume-header">
+    <!-- 选择下拉框,自动填充剩余空间,这种实现是因为 Select 不支持 suffix -->
+    <Dropdown
+      v-if="headerConfig.selector.show"
+      class="flex-grow-1 costume-header_left"
+      :trigger="['click']"
+      :bordered="false"
+      @open-change="visible = $event"
+    >
+      <div class="flex-basis-100% flex flex-items-center" @click.prevent>
+        <div class="headerType w-100px flex-grow-1 overflow-hidden whitespace-nowrap text-ellipsis">
+          {{ selectedDeviceLabel }}
+        </div>
+        <CaretUpOutlined class="w-30px" v-if="visible" />
+        <CaretDownOutlined class="w-30px" v-else />
+      </div>
+      <template #overlay>
+        <Menu :selected-keys="[selectedDeviceID]" @click="selectHandler">
+          <MenuItem v-for="item in options" :key="item.value" :title="item.label">
+            {{ item.label }}
+          </MenuItem>
+        </Menu>
+      </template>
+    </Dropdown>
+    <template v-if="headerConfig.slot.show">
+      <div class="headerType flex-basis-50% flex flex-items-center flex-grow-1 costume-header_right">
+        <div class="flex-grow-1">
+          {{ selectedDeviceSlot }}
+        </div>
+      </div>
+    </template>
+  </div>
+</template>
+<script lang="ts" setup>
+import { ref, watch } from 'vue';
+import { Config } from '../../../../../deviceManager/configurationTable/types';
+import { useInitModule } from '../../../hooks/useInit';
+import { MenuItem, Menu, Dropdown } from 'ant-design-vue';
+import { SwapOutlined, CaretUpOutlined, CaretDownOutlined } from '@ant-design/icons-vue';
+
+const props = defineProps<{
+  moduleData: Config['moduleData'];
+  deviceType: Config['deviceType'];
+  data: any;
+}>();
+
+const emit = defineEmits(['select']);
+
+const visible = ref(false);
+const headerConfig = props.moduleData.header;
+const { selectedDeviceID, selectedDevice, selectedDeviceSlot, selectedDeviceLabel, options, init } = useInitModule(
+  props.deviceType,
+  props.moduleData
+);
+
+function selectHandler({ key }) {
+  selectedDeviceID.value = key;
+  emit('select', selectedDevice.value);
+}
+
+watch(
+  () => props.data,
+  (d) => {
+    init(d);
+    emit('select', selectedDevice.value);
+  },
+  {
+    immediate: true,
+  }
+);
+</script>
+<style scoped>
+@import '/@/design/theme.less';
+
+.costume-header {
+  width: 100%;
+  height: 30px;
+  margin-bottom: 10px;
+  background: url('@/assets/images/vent/homeNew/Left-bottom.png') no-repeat;
+  background-size: 100% 100%;
+}
+.costume-header_left {
+}
+.costume-header_right {
+}
+</style>

+ 133 - 0
src/views/vent/home/configurable/bule/components/originalNew/moduleBottom.vue

@@ -0,0 +1,133 @@
+<template>
+  <div v-if="visible" class="module-content">
+    <div class="left-solt" @click="scrollLeft"></div>
+    <div class="center-solt">
+      <div v-for="(item, index) in visibleTabs" :key="index" class="tab-item" :class="{ active: activeIndex === index }" @click="selectTab(index)">
+        <span class="tab-name">{{ item }}</span>
+      </div>
+    </div>
+    <div class="right-solt" @click="scrollRight"></div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+  import { ref, computed } from 'vue';
+
+  defineProps<{ title: string; visible: boolean }>();
+  const emit = defineEmits(['close', 'click']);
+
+  const tabList = ['Tab标题名称 1', 'Tab标题名称 2', 'Tab标题名称 3', 'Tab标题名称 4', 'Tab标题名称 5', 'Tab标题名称 6'];
+  const activeIndex = ref(0);
+  const currentStart = ref(0);
+  const visibleCount = 4;
+
+  const visibleTabs = computed(() => {
+    return tabList.slice(currentStart.value, currentStart.value + visibleCount);
+  });
+
+  function closeModel() {
+    emit('close');
+  }
+
+  function clickHandler() {
+    emit('click');
+  }
+
+  function selectTab(index: number) {
+    activeIndex.value = index;
+  }
+
+  function scrollLeft() {
+    if (currentStart.value > 0) {
+      currentStart.value--;
+    }
+  }
+
+  function scrollRight() {
+    if (currentStart.value + visibleCount < tabList.length) {
+      currentStart.value++;
+    }
+  }
+</script>
+
+<style lang="less" scoped>
+  @import '/@/design/theme.less';
+
+  .module-content {
+    color: #fff;
+    box-sizing: border-box;
+    position: absolute;
+    width: 100%;
+    height: 100%;
+    display: flex;
+    align-items: center;
+  }
+
+  .left-solt,
+  .right-solt {
+    width: 15%;
+    height: 60%;
+    cursor: pointer;
+    position: relative;
+    z-index: 1;
+  }
+
+  .left-solt {
+    background: url('@/assets/images/vent/homeNew/Bottom-left.png') no-repeat;
+    background-size: 100% 100%;
+  }
+
+  .right-solt {
+    background: url('@/assets/images/vent/homeNew/Bottom_right.png') no-repeat;
+    background-size: 100% 100%;
+  }
+
+  .center-solt {
+    display: flex;
+    width: 70%;
+    height: 60%;
+    justify-content: space-between;
+  }
+
+  .tab-item {
+    flex: 1;
+    text-align: center;
+    line-height: 60px;
+    cursor: pointer;
+    background: url('@/assets/images/vent/homeNew/tab-defult.png') no-repeat;
+    background-size: 100% 100%;
+    transition: all 0.3s;
+    margin: 0 5px;
+    color: #999;
+  }
+  .tab-name {
+    font-size: 14px;
+    display: inline-block;
+    float: right;
+    margin-right: 13px;
+  }
+  .tab-item.active {
+    background: url('@/assets/images/vent/homeNew/tab-active.png') no-repeat;
+    background-size: 100% 100%;
+    font-weight: bold;
+    color: #fff;
+    transform: translateY(-5px);
+  }
+
+  .module-slot {
+    height: calc(100% - 33px);
+    width: calc(100% - 15px);
+    margin-left: 10px;
+  }
+
+  .v-enter-active,
+  .v-leave-active {
+    transition: all 0.3s ease;
+  }
+
+  .v-enter-from,
+  .v-leave-to {
+    opacity: 0;
+    transform: translateY(-33px);
+  }
+</style>

+ 95 - 0
src/views/vent/home/configurable/bule/components/originalNew/moduleLeft.vue

@@ -0,0 +1,95 @@
+<template>
+  <div v-if="visible" class="module-content">
+    <div v-if="title" class="module-content__title__expand">
+      <span class="action-btn close-btn" @click="closeModel"></span>
+      <span @click="clickHandler">{{ title }}</span>
+    </div>
+    <div class="module-slot">
+      <slot></slot>
+    </div>
+  </div>
+</template>
+<script lang="ts" setup>
+defineProps<{ title: string; visible: boolean }>();
+const emit = defineEmits(['close', 'click']);
+
+function closeModel() {
+  emit('close');
+}
+function clickHandler() {
+  emit('click');
+}
+</script>
+<style lang="less" scoped>
+@import '/@/design/theme.less';
+
+@{theme-deepblue} {
+  .module-content {
+    --image-model_original_title_bg: url('@/assets/images/vent/homeNew/Lefttop.png');
+  }
+}
+
+.module-content {
+  --image-model_original_title_bg: url('@/assets/images/vent/homeNew/Lefttop.png');
+  --bg-height: 33px;
+  color: #fff;
+  box-sizing: border-box;
+  position: absolute;
+  width: 100%;
+  height: 100%;
+}
+
+.module-content__title__expand {
+  width: 100%;
+  height: var(--bg-height);
+  background: var(--image-model_original_title_bg) no-repeat;
+  background-size: 100% 100%;
+  position: relative;
+  text-align: center;
+  line-height: var(--bg-height);
+}
+
+// .module-content__title {
+//   width: 50%;
+//   height: var(--bg-height);
+//   background: url('@/assets/images/home-container/configurable/model_left_title_bg.png') no-repeat;
+//   background-size: 100% 100%;
+//   position: relative;
+//   text-align: right;
+//   padding: 4px 10% 0 0;
+// }
+
+// 固定在父容器右上角的按钮图标
+// .action-btn {
+//   width: 18px;
+//   height: 18px;
+//   background: url('@/assets/images/home-container/configurable/expand.svg') no-repeat center;
+//   position: absolute;
+//   right: 0;
+//   top: 0;
+// }
+// .close-btn {
+//   transform: rotate(-90deg);
+// }
+
+.module-slot {
+  height: calc(100% - 33px);
+  width: calc(100% - 20px);
+  backdrop-filter: blur(5px);
+  margin-left: 10px;
+}
+
+// Transition动画相关
+.v-enter-active,
+.v-leave-active {
+  transition: all 0.3s ease;
+}
+
+.v-enter-from,
+.v-leave-to {
+  // opacity: 1;
+  transform: translateX(-100%);
+  // transform: scaleY(0);
+  // transform-origin: center top;
+}
+</style>

+ 104 - 0
src/views/vent/home/configurable/bule/components/originalNew/moduleLeftBottom.vue

@@ -0,0 +1,104 @@
+<template>
+  <div v-if="visible" class="module-content">
+    <div v-if="title" class="module-content__title__expand">
+      <span class="action-btn close-btn" @click="closeModel"></span>
+      <span @click="clickHandler" class="title">{{ title }}</span>
+    </div>
+    <div class="module-slot">
+      <slot></slot>
+    </div>
+  </div>
+</template>
+<script lang="ts" setup>
+  defineProps<{ title: string; visible: boolean }>();
+  const emit = defineEmits(['close', 'click']);
+
+  function closeModel() {
+    emit('close');
+  }
+  function clickHandler() {
+    emit('click');
+  }
+</script>
+<style lang="less" scoped>
+  @import '/@/design/theme.less';
+
+  @{theme-deepblue} {
+    .module-content {
+      --image-model_original_title_bg: url('@/assets/images/vent/homeNew/left3.png');
+    }
+  }
+
+  .module-content {
+    --image-model_original_title_bg: url('@/assets/images/vent/homeNew/left3.png');
+    --bg-height: 40px;
+    color: #fff;
+    box-sizing: border-box;
+    position: absolute;
+    width: 100%;
+    height: 100%;
+  }
+  .title {
+    font-size: 14px;
+    font-weight: 500;
+    color: #fff;
+    float: right;
+    padding-right: 25px;
+    font-family: 'douyuFont';
+    line-height: 30px;
+  }
+  .module-content__title__expand {
+    width: 100%;
+    height: var(--bg-height);
+    background: var(--image-model_original_title_bg) no-repeat;
+    background-size: 100% 100%;
+    position: relative;
+    text-align: center;
+
+    line-height: var(--bg-height);
+  }
+
+  // .module-content__title {
+  //   width: 50%;
+  //   height: var(--bg-height);
+  //   background: url('@/assets/images/home-container/configurable/model_left_title_bg.png') no-repeat;
+  //   background-size: 100% 100%;
+  //   position: relative;
+  //   text-align: right;
+  //   padding: 4px 10% 0 0;
+  // }
+
+  // 固定在父容器右上角的按钮图标
+  // .action-btn {
+  //   width: 18px;
+  //   height: 18px;
+  //   background: url('@/assets/images/home-container/configurable/expand.svg') no-repeat center;
+  //   position: absolute;
+  //   right: 0;
+  //   top: 0;
+  // }
+  // .close-btn {
+  //   transform: rotate(-90deg);
+  // }
+
+  .module-slot {
+    height: calc(100% - 33px);
+    width: calc(100% - 20px);
+    backdrop-filter: blur(5px);
+    margin-left: 10px;
+  }
+
+  // Transition动画相关
+  .v-enter-active,
+  .v-leave-active {
+    transition: all 0.3s ease;
+  }
+
+  .v-enter-from,
+  .v-leave-to {
+    // opacity: 1;
+    transform: translateX(-100%);
+    // transform: scaleY(0);
+    // transform-origin: center top;
+  }
+</style>

+ 103 - 0
src/views/vent/home/configurable/bule/components/originalNew/moduleLeftCenter.vue

@@ -0,0 +1,103 @@
+<template>
+  <div v-if="visible" class="module-content">
+    <div v-if="title" class="module-content__title__expand">
+      <span class="action-btn close-btn" @click="closeModel"></span>
+      <span @click="clickHandler" class="title">{{ title }}</span>
+    </div>
+    <div class="module-slot">
+      <slot></slot>
+    </div>
+  </div>
+</template>
+<script lang="ts" setup>
+  defineProps<{ title: string; visible: boolean }>();
+  const emit = defineEmits(['close', 'click']);
+
+  function closeModel() {
+    emit('close');
+  }
+  function clickHandler() {
+    emit('click');
+  }
+</script>
+<style lang="less" scoped>
+  @import '/@/design/theme.less';
+
+  @{theme-deepblue} {
+    .module-content {
+      --image-model_original_title_bg: url('@/assets/images/vent/homeNew/left2.png');
+    }
+  }
+
+  .module-content {
+    --image-model_original_title_bg: url('@/assets/images/vent/homeNew/left2.png');
+    --bg-height: 40px;
+    color: #fff;
+    box-sizing: border-box;
+    position: absolute;
+    width: 100%;
+    height: 100%;
+  }
+  .title {
+    font-size: 14px;
+    font-weight: 500;
+    color: #fff;
+    float: right;
+    padding-right: 25px;
+    line-height: 30px;
+    font-family: 'douyuFont';
+  }
+  .module-content__title__expand {
+    width: 100%;
+    height: var(--bg-height);
+    background: var(--image-model_original_title_bg) no-repeat;
+    background-size: 100% 100%;
+    position: relative;
+    text-align: center;
+    line-height: var(--bg-height);
+  }
+
+  // .module-content__title {
+  //   width: 50%;
+  //   height: var(--bg-height);
+  //   background: url('@/assets/images/home-container/configurable/model_left_title_bg.png') no-repeat;
+  //   background-size: 100% 100%;
+  //   position: relative;
+  //   text-align: right;
+  //   padding: 4px 10% 0 0;
+  // }
+
+  // 固定在父容器右上角的按钮图标
+  // .action-btn {
+  //   width: 18px;
+  //   height: 18px;
+  //   background: url('@/assets/images/home-container/configurable/expand.svg') no-repeat center;
+  //   position: absolute;
+  //   right: 0;
+  //   top: 0;
+  // }
+  // .close-btn {
+  //   transform: rotate(-90deg);
+  // }
+
+  .module-slot {
+    height: calc(100% - 33px);
+    width: calc(100% - 20px);
+    backdrop-filter: blur(5px);
+    margin-left: 10px;
+  }
+
+  // Transition动画相关
+  .v-enter-active,
+  .v-leave-active {
+    transition: all 0.3s ease;
+  }
+
+  .v-enter-from,
+  .v-leave-to {
+    // opacity: 1;
+    transform: translateX(-100%);
+    // transform: scaleY(0);
+    // transform-origin: center top;
+  }
+</style>

+ 104 - 0
src/views/vent/home/configurable/bule/components/originalNew/moduleLeftTop.vue

@@ -0,0 +1,104 @@
+<template>
+  <div v-if="visible" class="module-content">
+    <div v-if="title" class="module-content__title__expand">
+      <span class="action-btn close-btn" @click="closeModel"></span>
+      <span @click="clickHandler" class="title">{{ title }}</span>
+    </div>
+    <div class="module-slot">
+      <slot></slot>
+    </div>
+  </div>
+</template>
+<script lang="ts" setup>
+defineProps<{ title: string; visible: boolean }>();
+const emit = defineEmits(['close', 'click']);
+
+function closeModel() {
+  emit('close');
+}
+function clickHandler() {
+  emit('click');
+}
+</script>
+<style lang="less" scoped>
+@import '/@/design/theme.less';
+
+@{theme-deepblue} {
+  .module-content {
+    --image-model_original_title_bg: url('@/assets/images/vent/homeNew/left1.png');
+  }
+}
+
+.module-content {
+  --image-model_original_title_bg: url('@/assets/images/vent/homeNew/left1.png');
+  --bg-height: 40px;
+  color: #fff;
+  box-sizing: border-box;
+  position: absolute;
+  width: 100%;
+  height: 100%;
+}
+.title {
+  font-size: 14px;
+  font-weight: 500;
+  color: #fff;
+  float: right;
+  padding-right: 25px;
+  font-family: 'douyuFont';
+  line-height: 30px;
+}
+.module-content__title__expand {
+  width: 100%;
+  height: var(--bg-height);
+  background: var(--image-model_original_title_bg) no-repeat;
+  background-size: 100% 100%;
+  position: relative;
+  text-align: center;
+  margin-left: 70px;
+  line-height: var(--bg-height);
+}
+
+// .module-content__title {
+//   width: 50%;
+//   height: var(--bg-height);
+//   background: url('@/assets/images/home-container/configurable/model_left_title_bg.png') no-repeat;
+//   background-size: 100% 100%;
+//   position: relative;
+//   text-align: right;
+//   padding: 4px 10% 0 0;
+// }
+
+// 固定在父容器右上角的按钮图标
+// .action-btn {
+//   width: 18px;
+//   height: 18px;
+//   background: url('@/assets/images/home-container/configurable/expand.svg') no-repeat center;
+//   position: absolute;
+//   right: 0;
+//   top: 0;
+// }
+// .close-btn {
+//   transform: rotate(-90deg);
+// }
+
+.module-slot {
+  height: calc(100% - 33px);
+  width: calc(100% - 20px);
+  backdrop-filter: blur(5px);
+  margin-left: 10px;
+}
+
+// Transition动画相关
+.v-enter-active,
+.v-leave-active {
+  transition: all 0.3s ease;
+}
+
+.v-enter-from,
+.v-leave-to {
+  // opacity: 1;
+  transform: translateX(-100%);
+  // transform: scaleY(0);
+  // transform-origin: center top;
+}
+</style>

+ 102 - 0
src/views/vent/home/configurable/bule/components/originalNew/moduleRightBottom.vue

@@ -0,0 +1,102 @@
+<template>
+  <div v-if="visible" class="module-content">
+    <div v-if="title" class="module-content__title__expand">
+      <span class="action-btn close-btn" @click="closeModel"></span>
+      <span @click="clickHandler" class="title">{{ title }}</span>
+    </div>
+    <div class="module-slot">
+      <slot></slot>
+    </div>
+  </div>
+</template>
+<script lang="ts" setup>
+defineProps<{ title: string; visible: boolean }>();
+const emit = defineEmits(['close', 'click']);
+
+function closeModel() {
+  emit('close');
+}
+function clickHandler() {
+  emit('click');
+}
+</script>
+<style lang="less" scoped>
+@import '/@/design/theme.less';
+
+@{theme-deepblue} {
+  .module-content {
+    --image-model_original_title_bg: url('@/assets/images/vent/homeNew/right3.png');
+  }
+}
+
+.module-content {
+  --image-model_original_title_bg: url('@/assets/images/vent/homeNew/right3.png');
+  --bg-height: 40px;
+  color: #fff;
+  box-sizing: border-box;
+  position: absolute;
+  width: 100%;
+  height: 100%;
+}
+
+.module-content__title__expand {
+  width: 100%;
+  height: var(--bg-height);
+  background: var(--image-model_original_title_bg) no-repeat;
+  background-size: 100% 100%;
+  position: relative;
+  text-align: center;
+  line-height: var(--bg-height);
+}
+.title {
+  font-size: 14px;
+  font-weight: 500;
+  color: #fff;
+  float: left;
+  padding-left: 23px;    font-family: 'douyuFont';
+  line-height: 30px;
+}
+// .module-content__title {
+//   width: 50%;
+//   height: var(--bg-height);
+//   background: url('@/assets/images/home-container/configurable/model_left_title_bg.png') no-repeat;
+//   background-size: 100% 100%;
+//   position: relative;
+//   text-align: right;
+//   padding: 4px 10% 0 0;
+// }
+
+// 固定在父容器右上角的按钮图标
+// .action-btn {
+//   width: 18px;
+//   height: 18px;
+//   background: url('@/assets/images/home-container/configurable/expand.svg') no-repeat center;
+//   position: absolute;
+//   right: 0;
+//   top: 0;
+// }
+// .close-btn {
+//   transform: rotate(-90deg);
+// }
+
+.module-slot {
+  height: calc(100% - 33px);
+  width: calc(100% - 20px);
+  backdrop-filter: blur(5px);
+  margin-left: 10px;
+}
+
+// Transition动画相关
+.v-enter-active,
+.v-leave-active {
+  transition: all 0.3s ease;
+}
+
+.v-enter-from,
+.v-leave-to {
+  // opacity: 1;
+  transform: translateX(-100%);
+  // transform: scaleY(0);
+  // transform-origin: center top;
+}
+</style>

+ 103 - 0
src/views/vent/home/configurable/bule/components/originalNew/moduleRightCenter.vue

@@ -0,0 +1,103 @@
+<template>
+  <div v-if="visible" class="module-content">
+    <div v-if="title" class="module-content__title__expand">
+      <span class="action-btn close-btn" @click="closeModel"></span>
+      <span @click="clickHandler" class="title">{{ title }}</span>
+    </div>
+    <div class="module-slot">
+      <slot></slot>
+    </div>
+  </div>
+</template>
+<script lang="ts" setup>
+defineProps<{ title: string; visible: boolean }>();
+const emit = defineEmits(['close', 'click']);
+
+function closeModel() {
+  emit('close');
+}
+function clickHandler() {
+  emit('click');
+}
+</script>
+<style lang="less" scoped>
+@import '/@/design/theme.less';
+
+@{theme-deepblue} {
+  .module-content {
+    --image-model_original_title_bg: url('@/assets/images/vent/homeNew/right2.png');
+  }
+}
+
+.module-content {
+  --image-model_original_title_bg: url('@/assets/images/vent/homeNew/right2.png');
+  --bg-height: 40px;
+  color: #fff;
+  box-sizing: border-box;
+  position: absolute;
+  width: 100%;
+  height: 100%;
+}
+
+.module-content__title__expand {
+  width: 100%;
+  height: var(--bg-height);
+  background: var(--image-model_original_title_bg) no-repeat;
+  background-size: 100% 100%;
+  position: relative;
+  text-align: center;
+  line-height: var(--bg-height);
+}
+.title {
+  font-size: 14px;
+  font-weight: 500;
+  color: #fff;
+  float: left;
+  padding-left: 23px;
+  font-family: 'douyuFont';
+  line-height: 30px;
+}
+// .module-content__title {
+//   width: 50%;
+//   height: var(--bg-height);
+//   background: url('@/assets/images/home-container/configurable/model_left_title_bg.png') no-repeat;
+//   background-size: 100% 100%;
+//   position: relative;
+//   text-align: right;
+//   padding: 4px 10% 0 0;
+// }
+
+// 固定在父容器右上角的按钮图标
+// .action-btn {
+//   width: 18px;
+//   height: 18px;
+//   background: url('@/assets/images/home-container/configurable/expand.svg') no-repeat center;
+//   position: absolute;
+//   right: 0;
+//   top: 0;
+// }
+// .close-btn {
+//   transform: rotate(-90deg);
+// }
+
+.module-slot {
+  height: calc(100% - 33px);
+  width: calc(100% - 20px);
+  backdrop-filter: blur(5px);
+  margin-left: 10px;
+}
+
+// Transition动画相关
+.v-enter-active,
+.v-leave-active {
+  transition: all 0.3s ease;
+}
+
+.v-enter-from,
+.v-leave-to {
+  // opacity: 1;
+  transform: translateX(-100%);
+  // transform: scaleY(0);
+  // transform-origin: center top;
+}
+</style>

+ 104 - 0
src/views/vent/home/configurable/bule/components/originalNew/moduleRightTop.vue

@@ -0,0 +1,104 @@
+<template>
+  <div v-if="visible" class="module-content">
+    <div v-if="title" class="module-content__title__expand">
+      <span class="action-btn close-btn" @click="closeModel"></span>
+      <span @click="clickHandler" class="title">{{ title }}</span>
+    </div>
+    <div class="module-slot">
+      <slot></slot>
+    </div>
+  </div>
+</template>
+<script lang="ts" setup>
+defineProps<{ title: string; visible: boolean }>();
+const emit = defineEmits(['close', 'click']);
+
+function closeModel() {
+  emit('close');
+}
+function clickHandler() {
+  emit('click');
+}
+</script>
+<style lang="less" scoped>
+@import '/@/design/theme.less';
+
+@{theme-deepblue} {
+  .module-content {
+    --image-model_original_title_bg: url('@/assets/images/vent/homeNew/right1.png');
+  }
+}
+
+.module-content {
+  --image-model_original_title_bg: url('@/assets/images/vent/homeNew/right1.png');
+  --bg-height: 40px;
+  color: #fff;
+  box-sizing: border-box;
+  position: absolute;
+  width: 100%;
+  height: 100%;
+}
+
+.module-content__title__expand {
+  width: 100%;
+  height: var(--bg-height);
+  background: var(--image-model_original_title_bg) no-repeat;
+  background-size: 100% 100%;
+  position: relative;
+  text-align: center;
+  margin-left: -70px;
+  line-height: var(--bg-height);
+}
+.title {
+  font-size: 14px;
+  font-weight: 500;
+  color: #fff;
+  float: left;
+  font-family: 'douyuFont';
+  padding-left: 25px;
+  line-height: 30px;
+}
+// .module-content__title {
+//   width: 50%;
+//   height: var(--bg-height);
+//   background: url('@/assets/images/home-container/configurable/model_left_title_bg.png') no-repeat;
+//   background-size: 100% 100%;
+//   position: relative;
+//   text-align: right;
+//   padding: 4px 10% 0 0;
+// }
+
+// 固定在父容器右上角的按钮图标
+// .action-btn {
+//   width: 18px;
+//   height: 18px;
+//   background: url('@/assets/images/home-container/configurable/expand.svg') no-repeat center;
+//   position: absolute;
+//   right: 0;
+//   top: 0;
+// }
+// .close-btn {
+//   transform: rotate(-90deg);
+// }
+
+.module-slot {
+  height: calc(100% - 33px);
+  width: calc(100% - 20px);
+  backdrop-filter: blur(5px);
+  margin-left: 10px;
+}
+
+// Transition动画相关
+.v-enter-active,
+.v-leave-active {
+  transition: all 0.3s ease;
+}
+
+.v-enter-from,
+.v-leave-to {
+  // opacity: 1;
+  transform: translateX(-100%);
+  // transform: scaleY(0);
+  // transform-origin: center top;
+}
+</style>

+ 122 - 0
src/views/vent/home/configurable/bule/components/originalNew/moduleTop.vue

@@ -0,0 +1,122 @@
+<template>
+  <div v-if="visible" class="module-content">
+    <div class="left-solt"></div>
+    <div class="center-solt">
+      <div class="data-item">
+        <img class="data-icon" src="@/assets/images/vent/homeNew/zonghui.png" />
+        <div class="data-content">
+          <div class="title">总回风量(m³/min)</div>
+          <div class="air-num air-num1">25870</div>
+        </div>
+      </div>
+      <div class="divider"></div>
+      <div class="data-item">
+        <img class="data-icon" src="@/assets/images/vent/homeNew/zongjin.png" />
+        <div class="data-content">
+          <div class="title">总进风量(m³/min)</div>
+          <div class="air-num air-num2">24989</div>
+        </div>
+      </div>
+      <div class="divider"></div>
+      <div class="data-item">
+        <img class="data-icon" src="@/assets/images/vent/homeNew/jihua.png" />
+        <div class="data-content">
+          <div class="title">计划风量(m³/min)</div>
+          <div class="air-num air-num3">348</div>
+        </div>
+      </div>
+    </div>
+    <div class="right-solt"></div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+  defineProps<{ title: string; visible: boolean }>();
+  const emit = defineEmits(['close', 'click']);
+</script>
+
+<style lang="less" scoped>
+  @import '/@/design/theme.less';
+
+  .module-content {
+    background: url('@/assets/images/vent/homeNew/content.png') no-repeat;
+    background-size: 100% 100%;
+    color: #fff;
+    box-sizing: border-box;
+    position: absolute;
+    width: 100%;
+    height: 100%;
+    display: flex;
+    align-items: center;
+  }
+
+  .left-solt {
+    left: 8%;
+    top: 13%;
+    width: 30px;
+    height: 30px;
+    cursor: pointer;
+    position: absolute;
+    background: url('@/assets/images/vent/homeNew/Top-left.png') no-repeat;
+    background-size: 100% 100%;
+  }
+
+  .right-solt {
+    right: 8%;
+    top: 13%;
+    width: 30px;
+    height: 30px;
+    cursor: pointer;
+    position: absolute;
+    background: url('@/assets/images/vent/homeNew/Top-right.png') no-repeat;
+    background-size: 100% 100%;
+  }
+
+  .center-solt {
+    display: flex;
+    position: absolute;
+    left: 15%;
+    bottom: 50%;
+    width: 70%;
+    height: 60%;
+    align-items: center;
+    justify-content: space-around;
+  }
+
+  .data-item {
+    left: 10%;
+    display: flex;
+    align-items: center;
+    gap: 5px;
+    .data-icon {
+      width: 60px;
+      height: 100%;
+    }
+    .data-content {
+      display: flex;
+      flex-direction: column;
+      .title {
+        font-size: 16px;
+        font-weight: bold;
+        color: #999999;
+      }
+      .air-num {
+        font-size: 25px;
+      }
+    }
+  }
+  .air-num1 {
+    color: #4ca8d5;
+  }
+  .air-num2 {
+    color: #b9f3fc;
+  }
+  .air-num3 {
+    color: #4ad1cc;
+  }
+  .divider {
+    width: 1px;
+    height: 40px;
+    background: url('@/assets/images/vent/homeNew/Top-divider.png') no-repeat;
+  }
+</style>

+ 161 - 0
src/views/vent/home/configurable/bule/components/originalNew/moduleTopFire.vue

@@ -0,0 +1,161 @@
+
+<template>
+  <div v-if="visible" class="module-content">
+    <div class="left-solt">
+      <div class="left-img"></div>
+      <div class="left-title">智能注浆系统</div>
+    </div>
+    <div class="center-solt">
+      <div class="left-content">
+        <div class="img-left"></div>
+        <div class="title-left">监测区域</div>
+      </div>
+      <div class="center-content">
+        <div class="center-top">自燃倾向性等级:容易自燃</div>
+        <div class="center-bottom">低风险</div>
+      </div>
+      <div class="right-content">
+        <div class="title-right">火灾风险</div>
+        <div class="img-right"></div>
+      </div>
+    </div>
+    <div class="right-solt">
+      <div class="right-img"></div>
+      <div class="right-title">智能注氮系统</div>
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+defineProps<{ title: string; visible: boolean }>();
+const emit = defineEmits(['close', 'click']);
+</script>
+
+<style lang="less" scoped>
+@import '/@/design/theme.less';
+
+.module-content {
+  background: url('@/assets/images/fireNew/3-1.png') no-repeat;
+  background-size: 100% 100%;
+  color: #fff;
+  box-sizing: border-box;
+  position: absolute;
+  width: 100%;
+  height: 100%;
+  display: flex;
+  align-items: center;
+}
+
+.left-solt {
+  width: 100%;
+  width: 100%;
+  display: flex;
+  flex-direction: column;
+  .left-img {
+    left: 4%;
+    top: 2%;
+    width: 75px;
+    height: 75px;
+    cursor: pointer;
+    position: absolute;
+    background: url('@/assets/images/fireNew/3-4.png') no-repeat;
+    background-size: 100% 100%;
+  }
+  .left-title {
+    left: 3%;
+    top: 85px;
+    font-size: 13px;
+    font-family: 'douyuFont';
+    font-weight: bold;
+    color: #fff;
+    position: absolute;
+  }
+}
+
+.right-solt {
+  width: 100%;
+  width: 100%;
+  display: flex;
+  flex-direction: column;
+  .right-img {
+    right: 4%;
+    top: 2%;
+    width: 75px;
+    height: 75px;
+    cursor: pointer;
+    position: absolute;
+    background: url('@/assets/images/fireNew/3-5.png') no-repeat;
+    background-size: 100% 100%;
+  }
+  .right-title {
+    right: 3%;
+    top: 85px;
+    font-size: 13px;
+    font-family: 'douyuFont';
+    font-weight: bold;
+    color: #fff;
+    position: absolute;
+  }
+}
+.center-solt {
+  display: flex;
+  align-items: center;
+  width: 100%;
+}
+
+/* 左侧区域 */
+.left-content {
+  display: flex;
+  align-items: center; /* 垂直居中对齐 */
+}
+.img-left {
+  width: 50px; /* 图片尺寸 */
+  height: 50px;
+  margin-right: 8px; /* 图片文字间距 */
+  background: url('@/assets/images/fireNew/3-3.png') no-repeat center; /* 替换为实际图片路径 */
+  background-size: contain;
+}
+
+/* 右侧区域 */
+.right-content {
+  display: flex;
+  align-items: center;
+}
+.img-right {
+  width: 50px;
+  height: 50px;
+  margin-left: -10px;
+  background: url('@/assets/images/fireNew/3-2.png') no-repeat center; /* 替换为实际图片路径 */
+  background-size: contain;
+}
+
+/* 中间区域 */
+.center-content {
+  text-align: center;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  width: 330px;
+}
+/* 文字样式 */
+.title-left {
+  width: 100px;
+  font-size: 20px;
+}
+.title-right {
+  width: 100px;
+  font-size: 20px;
+}
+.center-top {
+  margin-bottom: 14px;
+  font-size: 20px;
+  margin-left: -18px;
+}
+.center-bottom {
+  font-size: 30px;
+  color: #52b4e5; /* 红色字体 */
+  font-weight: bold;
+  letter-spacing: 15px;
+  margin-bottom: 18px;
+}
+</style>

+ 97 - 0
src/views/vent/home/configurable/bule/components/originalNew/rightHeader1.vue

@@ -0,0 +1,97 @@
+<!-- eslint-disable vue/multi-word-component-names -->
+<template>
+  <!-- Header部分 -->
+  <div v-if="headerConfig.show" class="w-100% flex costume-header">
+    <!-- 选择下拉框,自动填充剩余空间,这种实现是因为 Select 不支持 suffix -->
+    <Dropdown
+      v-if="headerConfig.selector.show"
+      class="flex-grow-1 costume-header_left"
+      :trigger="['click']"
+      :bordered="false"
+      @open-change="visible = $event"
+    >
+      <div class="flex-basis-100% flex flex-items-center" @click.prevent>
+        <div class="headerType w-100px flex-grow-1 overflow-hidden whitespace-nowrap text-ellipsis">
+          {{ selectedDeviceLabel }}
+        </div>
+        <CaretUpOutlined class="w-30px" v-if="visible" />
+        <CaretDownOutlined class="w-30px" v-else />
+      </div>
+      <template #overlay>
+        <Menu :selected-keys="[selectedDeviceID]" @click="selectHandler">
+          <MenuItem v-for="item in options" :key="item.value" :title="item.label">
+            {{ item.label }}
+          </MenuItem>
+        </Menu>
+      </template>
+    </Dropdown>
+    <template v-if="headerConfig.slot.show">
+      <div class="divider"> </div>
+      <div class="headerType flex-basis-80% flex flex-items-center flex-grow-1 costume-header_right">
+        <div class="flex-grow-1">
+          {{ selectedDeviceSlot }}
+        </div>
+      </div>
+    </template>
+  </div>
+</template>
+<script lang="ts" setup>
+import { ref, watch } from 'vue';
+import { Config } from '../../../../../deviceManager/configurationTable/types';
+import { useInitModule } from '../../../hooks/useInit';
+import { MenuItem, Menu, Dropdown } from 'ant-design-vue';
+import { SwapOutlined, CaretUpOutlined, CaretDownOutlined } from '@ant-design/icons-vue';
+
+const props = defineProps<{
+  moduleData: Config['moduleData'];
+  deviceType: Config['deviceType'];
+  data: any;
+}>();
+
+const emit = defineEmits(['select']);
+
+const visible = ref(false);
+const headerConfig = props.moduleData.header;
+const { selectedDeviceID, selectedDevice, selectedDeviceSlot, selectedDeviceLabel, options, init } = useInitModule(
+  props.deviceType,
+  props.moduleData
+);
+
+function selectHandler({ key }) {
+  selectedDeviceID.value = key;
+  emit('select', selectedDevice.value);
+}
+
+watch(
+  () => props.data,
+  (d) => {
+    init(d);
+    emit('select', selectedDevice.value);
+  },
+  {
+    immediate: true,
+  }
+);
+</script>
+<style scoped>
+@import '/@/design/theme.less';
+
+.costume-header {
+  height: 30px;
+  margin-bottom: 10px;
+  width: 111%;
+  background: url('@/assets/images/vent/homeNew/Right-top.png') no-repeat;
+  background-size: 100% 100%;
+  margin-left: -40px;
+}
+.costume-header_left {
+  margin-left: 20px;
+}
+.costume-header_right {
+}
+.divider {
+  width: 40px;
+  background: url('@/assets/images/vent/homeNew/right-divider.png') no-repeat;
+  background-size: 100% 100%;
+}
+</style>

+ 90 - 0
src/views/vent/home/configurable/bule/components/originalNew/rightHeader2.vue

@@ -0,0 +1,90 @@
+<!-- eslint-disable vue/multi-word-component-names -->
+<template>
+  <!-- Header部分 -->
+  <div v-if="headerConfig.show" class="w-100% flex costume-header">
+    <!-- 选择下拉框,自动填充剩余空间,这种实现是因为 Select 不支持 suffix -->
+    <Dropdown
+      v-if="headerConfig.selector.show"
+      class="flex-grow-1 costume-header_left"
+      :trigger="['click']"
+      :bordered="false"
+      @open-change="visible = $event"
+    >
+      <div class="flex-basis-100% flex flex-items-center" @click.prevent>
+        <div class="headerType w-100px flex-grow-1 overflow-hidden whitespace-nowrap text-ellipsis">
+          {{ selectedDeviceLabel }}
+        </div>
+        <CaretUpOutlined class="w-30px" v-if="visible" />
+        <CaretDownOutlined class="w-30px" v-else />
+      </div>
+      <template #overlay>
+        <Menu :selected-keys="[selectedDeviceID]" @click="selectHandler">
+          <MenuItem v-for="item in options" :key="item.value" :title="item.label">
+            {{ item.label }}
+          </MenuItem>
+        </Menu>
+      </template>
+    </Dropdown>
+    <template v-if="headerConfig.slot.show">
+      <div class="headerType flex-basis-50% flex flex-items-center flex-grow-1 costume-header_right">
+        <div class="flex-grow-1">
+          {{ selectedDeviceSlot }}
+        </div>
+      </div>
+    </template>
+  </div>
+</template>
+<script lang="ts" setup>
+import { ref, watch } from 'vue';
+import { Config } from '../../../../../deviceManager/configurationTable/types';
+import { useInitModule } from '../../../hooks/useInit';
+import { MenuItem, Menu, Dropdown } from 'ant-design-vue';
+import { SwapOutlined, CaretUpOutlined, CaretDownOutlined } from '@ant-design/icons-vue';
+
+const props = defineProps<{
+  moduleData: Config['moduleData'];
+  deviceType: Config['deviceType'];
+  data: any;
+}>();
+
+const emit = defineEmits(['select']);
+
+const visible = ref(false);
+const headerConfig = props.moduleData.header;
+const { selectedDeviceID, selectedDevice, selectedDeviceSlot, selectedDeviceLabel, options, init } = useInitModule(
+  props.deviceType,
+  props.moduleData
+);
+
+function selectHandler({ key }) {
+  selectedDeviceID.value = key;
+  emit('select', selectedDevice.value);
+}
+
+watch(
+  () => props.data,
+  (d) => {
+    init(d);
+    emit('select', selectedDevice.value);
+  },
+  {
+    immediate: true,
+  }
+);
+</script>
+<style scoped>
+@import '/@/design/theme.less';
+
+.costume-header {
+  width: 100%;
+  height: 30px;
+  margin-bottom: 10px;
+  background: url('@/assets/images/vent/homeNew/Right-mid.png') no-repeat;
+  background-size: 100% 100%;
+}
+.costume-header_left {
+  margin-left: 20px;
+}
+.costume-header_right {
+}
+</style>

+ 90 - 0
src/views/vent/home/configurable/bule/components/originalNew/rightHeader3.vue

@@ -0,0 +1,90 @@
+<!-- eslint-disable vue/multi-word-component-names -->
+<template>
+  <!-- Header部分 -->
+  <div v-if="headerConfig.show" class="w-100% flex costume-header">
+    <!-- 选择下拉框,自动填充剩余空间,这种实现是因为 Select 不支持 suffix -->
+    <Dropdown
+      v-if="headerConfig.selector.show"
+      class="flex-grow-1 costume-header_left"
+      :trigger="['click']"
+      :bordered="false"
+      @open-change="visible = $event"
+    >
+      <div class="flex-basis-100% flex flex-items-center" @click.prevent>
+        <div class="headerType w-100px flex-grow-1 overflow-hidden whitespace-nowrap text-ellipsis">
+          {{ selectedDeviceLabel }}
+        </div>
+        <CaretUpOutlined class="w-30px" v-if="visible" />
+        <CaretDownOutlined class="w-30px" v-else />
+      </div>
+      <template #overlay>
+        <Menu :selected-keys="[selectedDeviceID]" @click="selectHandler">
+          <MenuItem v-for="item in options" :key="item.value" :title="item.label">
+            {{ item.label }}
+          </MenuItem>
+        </Menu>
+      </template>
+    </Dropdown>
+    <template v-if="headerConfig.slot.show">
+      <div class="headerType flex-basis-50% flex flex-items-center flex-grow-1 costume-header_right">
+        <div class="flex-grow-1">
+          {{ selectedDeviceSlot }}
+        </div>
+      </div>
+    </template>
+  </div>
+</template>
+<script lang="ts" setup>
+import { ref, watch } from 'vue';
+import { Config } from '../../../../../deviceManager/configurationTable/types';
+import { useInitModule } from '../../../hooks/useInit';
+import { MenuItem, Menu, Dropdown } from 'ant-design-vue';
+import { SwapOutlined, CaretUpOutlined, CaretDownOutlined } from '@ant-design/icons-vue';
+
+const props = defineProps<{
+  moduleData: Config['moduleData'];
+  deviceType: Config['deviceType'];
+  data: any;
+}>();
+
+const emit = defineEmits(['select']);
+
+const visible = ref(false);
+const headerConfig = props.moduleData.header;
+const { selectedDeviceID, selectedDevice, selectedDeviceSlot, selectedDeviceLabel, options, init } = useInitModule(
+  props.deviceType,
+  props.moduleData
+);
+
+function selectHandler({ key }) {
+  selectedDeviceID.value = key;
+  emit('select', selectedDevice.value);
+}
+
+watch(
+  () => props.data,
+  (d) => {
+    init(d);
+    emit('select', selectedDevice.value);
+  },
+  {
+    immediate: true,
+  }
+);
+</script>
+<style scoped>
+@import '/@/design/theme.less';
+
+.costume-header {
+  width: 100%;
+  height: 30px;
+  margin-bottom: 10px;
+  background: url('@/assets/images/vent/homeNew/Right-bottom.png') no-repeat;
+  background-size: 100% 100%;
+}
+.costume-header_left {
+  margin-left: 20px;
+}
+.costume-header_right {
+}
+</style>

+ 46 - 9
src/views/vent/home/configurable/components/yj_chart.vue → src/views/vent/home/configurable/bule/components/yj_chart.vue

@@ -1,6 +1,9 @@
 <template>
-  <div class="dz-dust">
-    <div ref="chartDust" class="chartDust"></div>
+  <div class="yj-fire">
+    <div class="icon-fire">
+      <div class="fire-icon" v-for="(item, index) in yData" :key="index">{{ item }}</div>
+    </div>
+    <div ref="chartFire" class="chartFire"></div>
   </div>
 </template>
 
@@ -24,13 +27,13 @@ let props = defineProps({
 });
 
 //获取dom元素节点
-let chartDust = ref<any>();
+let chartFire = ref<any>();
 let xData = ref<any[]>([]);
 let yData = ref<any[]>([]);
 
 function getOption() {
   nextTick(() => {
-    let myChart = echarts.init(chartDust.value);
+    let myChart = echarts.init(chartFire.value);
 
     const colorList = [
       ['rgba(78, 8, 10, 1)', 'rgba(255, 0, 0, 1)'],
@@ -39,7 +42,7 @@ function getOption() {
       ['rgba(78, 73, 10, 1)', 'rgba(255, 214, 0, 1)'],
       ['rgba(24, 60, 76, 1)', 'rgba(78, 171, 217, 1)'],
     ];
-    const totalBlocks = 25;
+    const totalBlocks = 20;
     let option = {
       tooltip: {},
       grid: {
@@ -145,13 +148,47 @@ watch(
 </script>
 
 <style lang="less" scoped>
-.dz-dust {
+.yj-fire {
   position: relative;
   height: 100%;
-
-  .chartDust {
+  .icon-fire {
+    position: absolute;
+    width: 100%;
+    height: 40px;
+    top: 50px;
+    display: flex;
+    justify-content: flex-start;
+    .fire-icon {
+      text-align: center;
+      width: 40px;
+      height: 32px;
+      margin-left: 32px;
+    }
+    .fire-icon:nth-child(1) {
+      background: url('@/assets/images/home-warn/8-1.png') no-repeat center;
+      background-size: 100% 100%;
+    }
+    .fire-icon:nth-child(2) {
+      background: url('@/assets/images/home-warn/8-2.png') no-repeat center;
+      background-size: 100% 100%;
+    }
+    .fire-icon:nth-child(3) {
+      background: url('@/assets/images/home-warn/8-3.png') no-repeat center;
+      background-size: 100% 100%;
+    }
+    .fire-icon:nth-child(4) {
+      background: url('@/assets/images/home-warn/8-4.png') no-repeat center;
+      background-size: 100% 100%;
+    }
+    .fire-icon:nth-child(5) {
+      background: url('@/assets/images/home-warn/8-5.png') no-repeat center;
+      background-size: 100% 100%;
+    }
+  }
+  .chartFire {
+    top: 65px;
     width: 100%;
-    height: 100%;
+    height: calc(100% - 50px);
   }
 }
 </style>

+ 0 - 0
src/views/vent/home/configurable/components/yj_gasWarn.vue → src/views/vent/home/configurable/bule/components/yj_gasWarn.vue


+ 16 - 25
src/views/vent/home/configurable/components/yj_risk.vue → src/views/vent/home/configurable/bule/components/yj_risk.vue

@@ -12,14 +12,13 @@ import { ref, nextTick, onMounted, watch } from 'vue';
 import * as echarts from 'echarts';
 
 let props = defineProps({
-  riskData: {
+  echartData: {
     type: Array,
     default: () => {
       return [];
     },
   },
 });
-
 let riskPie = ref(null);
 let echartData = ref<any[]>([]);
 
@@ -93,20 +92,16 @@ function getOption() {
         {
           type: 'pie',
           center: ['50%', '50%'],
-          radius: ['48%', '70%'],
-          // clockwise: false,
-          // avoidLabelOverlap: true,
+          radius: ['30%', '50%'],
           emphasis: {
             label: {
               show: true,
             },
-            itemStyle: {
-              color: function (params) {
-                return colorList[params.dataIndex];
-              },
+            opacity: 1,
+            color: function (params) {
+              return colorList[params.dataIndex];
             },
           },
-          // hoverOffset: 0,
           itemStyle: {
             normal: {
               color: function (params) {
@@ -119,17 +114,10 @@ function getOption() {
             position: 'outside',
             textStyle: {
               color: '#fff',
-              fontSize: 12,
+              fontSize: 10,
             },
-            formatter: '{a|{b}:{d}%}\n{hr|}',
+            formatter: '{b}:{c}',
             rich: {
-              hr: {
-                backgroundColor: 't',
-                borderRadius: 3,
-                width: 3,
-                height: 3,
-                padding: [3, 3, 0, -12],
-              },
               a: {
                 padding: [-10, 5, -15, 5],
               },
@@ -138,8 +126,8 @@ function getOption() {
 
           labelLine: {
             normal: {
-              length: 20,
-              length2: 20,
+              length: 10,
+              length2: 5,
               lineStyle: {
                 width: 1,
               },
@@ -157,7 +145,7 @@ function getOption() {
 }
 
 watch(
-  () => props.riskData,
+  () => props.echartData,
   (newV, oldV) => {
     echartData.value = newV;
     getOption();
@@ -186,14 +174,17 @@ watch(
       top: 50%;
       transform: translate(-50%, -50%);
       width: 100%;
-      height: 80px;
+      height: 60px;
       background: var(--image-model_risk-center) no-repeat center;
       background-size: auto 100%;
     }
 
     .risk-pie {
-      width: 100%;
-      height: 100%;
+      left: -28px;
+      top: -17px;
+      position: absolute;
+      width: 276px;
+      height: 205px;
     }
   }
 }

+ 1 - 1
src/views/vent/home/configurable/components/yj_ventWarn.vue → src/views/vent/home/configurable/bule/components/yj_ventWarn.vue

@@ -30,7 +30,7 @@ const colorMap = {
 };
 
 const getProgressStyle = (item) => {
-  const maxValue = 5;
+  const maxValue = 10;
   const [startColor, endColor] = colorMap[item.name];
 
   return {

+ 223 - 0
src/views/vent/home/configurable/bule/fireNew.vue

@@ -0,0 +1,223 @@
+<!-- eslint-disable vue/multi-word-component-names -->
+<template>
+  <div class="company-home">
+    <div style="width: 100%; height: 100%; position: absolute; left: 0; top: 0; z-index: 0">
+      <VentModal />
+      <a-button
+        type="primary"
+        shape="circle"
+        style="width: 34px; height: 34px; position: absolute; right: 5px; bottom: 5px; z-index: 5"
+        @click="redirectTo('/micro-vent-3dModal/dashboard/analysis?type=model3D&deviceType=model3D')"
+      >
+        <!-- <EyeFilled /> -->
+      </a-button>
+    </div>
+    <div class="top-bg">
+      <!-- <img style="width: 300px; height: 40px; position: fixed; left: 5px; top: 5px" src="./meeee.png" /> -->
+      <!-- <div class="main-title">{{ mainTitle }}</div> -->
+      <NewNav :Title="mainTitle" />
+    </div>
+    <ModuleFireNew
+      v-for="cfg in cfgs"
+      :key="cfg.deviceType"
+      :show-style="cfg.showStyle"
+      :module-data="cfg.moduleData"
+      :module-name="cfg.moduleName"
+      :device-type="cfg.deviceType"
+      :data="data"
+      :visible="true"
+    />
+    <ModuleNew
+      v-if="cfgTop"
+      :show-style="cfgTop.showStyle"
+      :module-data="cfgTop.moduleData"
+      :module-name="cfgTop.moduleName"
+      :device-type="cfgTop.deviceType"
+      :data="data"
+      :visible="true"
+    />
+    <ModuleFireNewDual
+      v-if="cfgA && cfgB"
+      :show-style="cfgA.showStyle"
+      :module-data-a="cfgA.moduleData"
+      :module-name-a="cfgA.moduleName"
+      :device-type-a="cfgA.deviceType"
+      :module-data-b="cfgB.moduleData"
+      :module-name-b="cfgB.moduleName"
+      :device-type-b="cfgB.deviceType"
+      :data="data"
+      :visible="true"
+    />
+  </div>
+</template>
+<script lang="ts" setup>
+import { computed, onMounted, onUnmounted } from 'vue';
+// import { CaretDownOutlined } from '@ant-design/icons-vue';
+import NewNav from './components/originalNew/NewNavFire.vue';
+import { useInitConfigs, useInitPage } from '../hooks/useInit';
+import ModuleNew from './components/ModuleNew.vue';
+import ModuleFireNew from './components/ModuleFireNew.vue';
+import ModuleFireNewDual from './components/ModuleFireNewDual.vue';
+import VentModal from '/@/components/vent/micro/ventModal.vue';
+// import { BDFireMock } from './mock';
+import { getDisHome } from '../configurable.api';
+// import { EyeFilled } from '@ant-design/icons-vue';
+import { testConfigNewFire } from '../configurable.data.New';
+const cfgs = computed(() =>
+  configs.value.filter((_, index) => {
+    return index !== 4 && index !== 3 && index !== 5;
+  })
+);
+const cfgA = computed<any>(() =>
+  configs.value.find((_, index) => {
+    return index === 3;
+  })
+);
+const cfgB = computed<any>(() =>
+  configs.value.find((_, index) => {
+    return index === 4;
+  })
+);
+const cfgTop = computed<any>(() =>
+  configs.value.find((_, index) => {
+    return index === 5;
+  })
+);
+const { configs, devicesTypes, fetchConfigs } = useInitConfigs();
+const { mainTitle, data, updateData /** updateEnhancedConfigs */ } = useInitPage('火灾预警系统');
+let interval: number | undefined;
+onMounted(() => {
+  // fetchConfigs('New_fire').then(() => {
+  //   configs.value = testConfigNewFire;
+  //   Promise.resolve(BDFireMock).then(updateData);
+  // });
+  // setInterval(() => {
+  //   Promise.resolve(BDFireMock).then(updateData);
+  // }, 2000);
+  fetchConfigs('New_fire').then(() => {
+    configs.value = testConfigNewFire;
+    getDisHome({
+      dataList: devicesTypes.value.concat('fireAllMineWarn').join(','),
+    }).then(updateData);
+  });
+  setInterval(() => {
+    getDisHome({
+      dataList: devicesTypes.value.concat('fireAllMineWarn').join(','),
+    }).then(updateData);
+  }, 2000);
+});
+
+onUnmounted(() => {
+  clearInterval(interval);
+});
+
+function redirectTo(url) {
+  window.open(url);
+}
+</script>
+<style lang="less" scoped>
+@import '/@/design/theme.less';
+
+@font-face {
+  font-family: 'douyuFont';
+  src: url('../../../../assets/font/douyuFont.otf');
+}
+
+@{theme-deepblue} {
+  .company-home {
+    --image-modal-top: url('@/assets/images/fireNew/1.png');
+  }
+}
+
+.company-home {
+  --image-modal-top: url('@/assets/images/fireNew/1.png');
+  width: 100%;
+  height: 100%;
+  color: @white;
+  position: relative;
+  background: url('@/assets/images/fireNew/FireBj.png') no-repeat center;
+
+  .top-bg {
+    width: 100%;
+    height: 56px;
+    background: var(--image-modal-top) no-repeat center;
+    position: absolute;
+    z-index: 1;
+    .main-title {
+      height: 56px;
+      font-family: 'douyuFont';
+      font-size: 20px;
+      letter-spacing: 2px;
+      display: flex;
+      justify-content: center;
+      align-items: center;
+    }
+    .top-nav {
+      position: absolute;
+      top: 0;
+      width: 880px;
+      height: 100%;
+      display: flex;
+      justify-content: flex-start;
+    }
+  }
+  .left-t {
+    position: absolute;
+    width: 28%;
+    height: 100%;
+    background: url('@/assets/images/vent/homeNew/leftContent.png') no-repeat center;
+    z-index: 0;
+  }
+  .right-t {
+    position: absolute;
+    width: 172%;
+    height: 100%;
+    background: url('@/assets/images/vent/homeNew/rightContent.png') no-repeat center;
+    z-index: 0;
+  }
+  // .module-left {
+  //   position: absolute;
+  //   width: 450px;
+  //   height: 280px;
+  //   left: 0;
+  // }
+  // .module-right {
+  //   position: absolute;
+  //   width: 450px;
+  //   height: 280px;
+  //   right: 0;
+  // }
+  // .module-bottom {
+  //   position: absolute;
+  //   width: 1000px;
+  //   height: 280px;
+  // }
+  .module-dropdown {
+    padding: 10px;
+    background-image: @vent-configurable-dropdown;
+    border-bottom: 2px solid @vent-configurable-home-light-border;
+    color: @vent-font-color;
+    position: absolute;
+    top: 70px;
+    right: 460px;
+  }
+  .module-dropdown-original {
+    padding: 10px;
+    background-image: @vent-configurable-dropdown;
+    border-bottom: 2px solid @vent-configurable-home-light-border;
+    color: @vent-font-color;
+    position: absolute;
+    top: 70px;
+    right: 460px;
+  }
+  .module-trigger-button {
+    color: @vent-font-color;
+    background-image: @vent-configurable-dropdown;
+    border: none;
+    border-bottom: 2px solid @vent-configurable-home-light-border;
+  }
+}
+:deep(.loading-box) {
+  position: unset;
+}
+</style>

+ 166 - 0
src/views/vent/home/configurable/bule/ventNew.vue

@@ -0,0 +1,166 @@
+<!-- eslint-disable vue/multi-word-component-names -->
+<template>
+  <div class="company-home">
+    <div style="width: 100%; height: 100%; position: absolute; left: 0; top: 0; z-index: 0">
+      <!-- <VentModal /> -->
+    </div>
+    <div class="top-bg">
+      <!-- <img style="width: 300px; height: 40px; position: fixed; left: 5px; top: 5px" src="./meeee.png" /> -->
+      <!-- <div class="main-title">{{ mainTitle }}</div> -->
+      <NewNav :Title="mainTitle" />
+    </div>
+    <div class="left-t"> </div>
+    <div class="right-t"> </div>
+    <template v-if="isNew">
+      <ModuleNew
+        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"
+      />
+    </template>
+  </div>
+</template>
+<script lang="ts" setup>
+import { onMounted, onUnmounted } from 'vue';
+// import { CaretDownOutlined } from '@ant-design/icons-vue';
+// import MonitorCenter from './components/MonitorCenter.vue';
+import NewNav from './components/originalNew/NewNav.vue';
+import { useInitConfigs, useInitPage } from '../hooks/useInit';
+import ModuleNew from './components/ModuleNew.vue';
+// import { useRoute } from 'vue-router';
+import VentModal from '/@/components/vent/micro/ventModal.vue';
+import { getHomeData } from '../configurable.api';
+// import { useRoute } from 'vue-router';
+import { testConfigVentNew } from '../configurable.data';
+const { configs, isNew, fetchConfigs } = useInitConfigs();
+const { mainTitle, data, updateData, updateEnhancedConfigs } = useInitPage('一通三防智能管控平台');
+// const route = useRoute();
+let interval: number | undefined;
+
+onMounted(() => {
+  fetchConfigs('vent').then(() => {
+    configs.value = testConfigVentNew;
+    updateEnhancedConfigs(configs.value);
+
+    getHomeData({}).then(updateData);
+  });
+  setInterval(() => {
+    getHomeData({}).then(updateData);
+  }, 60000);
+});
+
+onUnmounted(() => {
+  clearInterval(interval);
+});
+</script>
+<style lang="less" scoped>
+@import '/@/design/theme.less';
+
+@font-face {
+  font-family: 'douyuFont';
+  src: url('../../../../assets/font/douyuFont.otf');
+}
+
+@{theme-deepblue} {
+  .company-home {
+    --image-modal-top: url('@/assets/images/vent/homeNew/modaltop.png');
+  }
+}
+
+.company-home {
+  --image-modal-top: url('@/assets/images/vent/homeNew/modaltop.png');
+  width: 100%;
+  height: 100%;
+  color: @white;
+  position: relative;
+  background: url('@/assets/images/vent/homeNew/bg.png') no-repeat center;
+
+  .top-bg {
+    width: 100%;
+    height: 56px;
+    background: var(--image-modal-top) no-repeat center;
+    position: absolute;
+    z-index: 1;
+    .main-title {
+      height: 56px;
+      font-family: 'douyuFont';
+      font-size: 20px;
+      letter-spacing: 2px;
+      display: flex;
+      justify-content: center;
+      align-items: center;
+    }
+    .top-nav {
+      position: absolute;
+      top: 0;
+      width: 880px;
+      height: 100%;
+      display: flex;
+      justify-content: flex-start;
+    }
+  }
+  .left-t {
+    position: absolute;
+    width: 28%;
+    height: 100%;
+    background: url('@/assets/images/vent/homeNew/leftContent.png') no-repeat center;
+    z-index: 0;
+  }
+  .right-t {
+    position: absolute;
+    width: 172%;
+    height: 100%;
+    background: url('@/assets/images/vent/homeNew/rightContent.png') no-repeat center;
+    z-index: 0;
+  }
+  // .module-left {
+  //   position: absolute;
+  //   width: 450px;
+  //   height: 280px;
+  //   left: 0;
+  // }
+  // .module-right {
+  //   position: absolute;
+  //   width: 450px;
+  //   height: 280px;
+  //   right: 0;
+  // }
+  // .module-bottom {
+  //   position: absolute;
+  //   width: 1000px;
+  //   height: 280px;
+  // }
+  .module-dropdown {
+    padding: 10px;
+    background-image: @vent-configurable-dropdown;
+    border-bottom: 2px solid @vent-configurable-home-light-border;
+    color: @vent-font-color;
+    position: absolute;
+    top: 70px;
+    right: 460px;
+  }
+  .module-dropdown-original {
+    padding: 10px;
+    background-image: @vent-configurable-dropdown;
+    border-bottom: 2px solid @vent-configurable-home-light-border;
+    color: @vent-font-color;
+    position: absolute;
+    top: 70px;
+    right: 460px;
+  }
+  .module-trigger-button {
+    color: @vent-font-color;
+    background-image: @vent-configurable-dropdown;
+    border: none;
+    border-bottom: 2px solid @vent-configurable-home-light-border;
+  }
+}
+:deep(.loading-box) {
+  position: unset;
+}
+</style>

+ 36 - 9
src/views/vent/home/configurable/warnMonitor.vue → src/views/vent/home/configurable/bule/warnMonitor.vue

@@ -19,31 +19,32 @@
     </template>
 
     <div class="center-area">
-      <CenterAreaWarn></CenterAreaWarn>
+      <CenterAreaWarn :echartData="paramData"></CenterAreaWarn>
     </div>
   </div>
 </template>
 <script lang="ts" setup>
-import { onMounted, onUnmounted } from 'vue';
-import { useInitConfigs, useInitPage } from './hooks/useInit';
+import { onMounted, onUnmounted, reactive, ref } from 'vue';
+import { useInitConfigs, useInitPage } from '../hooks/useInit';
 import ModuleOriginal from './components/ModuleWarnMonitor.vue';
 import CenterAreaWarn from './components/center-area-warn.vue';
 import { useRoute } from 'vue-router';
 import { useGlobSetting } from '/@/hooks/setting';
-import { testConfigWarnMonitor } from './configurable.data';
-import NewNav from './components/originalNew/NewNavFire.vue';
-import { getTotal } from './configurable.api';
+import { testConfigWarnMonitor } from '../configurable.data';
+import NewNav from '../components/originalNew/NewNavFire.vue';
+import { getTotal, getDisasterProportion } from '../configurable.api';
 const { title = '智能通风管控系统' } = useGlobSetting();
 const { configs, fetchConfigs } = useInitConfigs();
 const { data, updateData } = useInitPage(title);
 const route = useRoute();
-
+const paramData = reactive<any>({});
 // https获取监测数据
 let timer: null | NodeJS.Timeout = null;
 function getMonitor(flag = false) {
   timer = setTimeout(
     async () => {
       getTotal({}).then(updateData);
+      getCenterList();
       if (timer) {
         timer = null;
       }
@@ -52,6 +53,32 @@ function getMonitor(flag = false) {
     flag ? 0 : 20000
   );
 }
+async function getCenterList() {
+  let res = await getTotal({});
+  paramData.fire = res.info.sysInfo.fireS.maxLevel;
+  paramData.tf = res.info.sysInfo.ventS.maxLevel;
+  paramData.ws = res.info.sysInfo.gasS.maxLevel;
+  paramData.sb = res.info.deviceWarnInfo.maxLevel;
+  paramData.fc = res.info.sysInfo.dustS.maxLevel;
+  paramData.riskLevel = res.info.riskLevel;
+  let Levels = Object.assign({}, await getDisasterProportion({}));
+  paramData.levels =
+    Levels.level > 0 && Levels.level <= 1
+      ? 101
+      : Levels.level > 1 && Levels.level <= 2
+      ? 102
+      : Levels.level > 2 && Levels.level <= 3
+      ? 103
+      : Levels.level > 3 && Levels.level <= 4
+      ? 104
+      : 0;
+  paramData.riskData = [
+    { name: '通风', value: Levels.vent },
+    { name: '火灾', value: Levels.fire },
+    { name: '瓦斯', value: Levels.gas },
+    { name: '粉尘', value: Levels.dust },
+  ];
+}
 onMounted(() => {
   fetchConfigs('fusion-warn-green').then(() => {
     configs.value = testConfigWarnMonitor;
@@ -82,7 +109,7 @@ onUnmounted(() => {
   .top-bg {
     width: 100%;
     height: 56px;
-    background: url('../../../../assets/images/home-warn/1-1.png') no-repeat center;
+    background: url('@/assets/images/home-warn/1-1.png') no-repeat center;
     position: absolute;
     z-index: 1;
     .main-title {
@@ -107,7 +134,7 @@ onUnmounted(() => {
   .main-container {
     width: 100%;
     height: 100%;
-    background: url('../../../../assets/images/home-warn/bg.png') no-repeat;
+    background: url('@/assets/images/home-warn/bg.png') no-repeat;
     background-size: 100% 100%;
     .left-area {
       position: absolute;

+ 311 - 311
src/views/vent/home/configurable/components/content-New.vue

@@ -141,359 +141,359 @@
   </div>
 </template>
 <script lang="ts" setup>
-  import { computed } from 'vue';
-  import {
-    CommonItem,
-    Config,
-    // ModuleDataBoard,
-    // ModuleDataChart,
-    // ModuleDataList,
-    // ModuleDataPreset,
-    // ModuleDataTable,
-  } from '../../../deviceManager/configurationTable/types';
-  import MiniBoard from './detail/MiniBoard.vue';
-  import TimelineList from './detail/TimelineList.vue';
-  import TimelineListNew from './detail/TimelineListNew.vue';
-  import CustomList from './detail/CustomList.vue';
-  import CustomGallery from './detail/CustomGallery.vue';
-  import ComplexList from './detail/ComplexList.vue';
-  import ComplexListNew from './detail/ComplexList-New.vue';
-  import GalleryList from './detail/GalleryList.vue';
-  import CustomTable from './detail/CustomTable-New.vue';
-  import CustomChart from './detail/CustomChart.vue';
-  import { clone } from 'lodash-es';
-  import { getData, getFormattedText } from '../hooks/helper';
-  import BlastDelta from '../../../monitorManager/deviceMonitor/components/device/modal/blastDelta.vue';
-  import QHCurve from './preset/QHCurve.vue';
-  import MeasureDetail from './preset/MeasureDetail.vue';
-  import CustomTabs from './preset/CustomTabs.vue';
-  import AIChat from '/@/components/AIChat/MiniChat.vue';
-  import DeviceAlarm from './preset/DeviceAlarm.vue';
-  import MiniBoardNew from './detail/MiniBoard-New.vue';
-  import CustomTableNew from './detail/CustomTable-New.vue';
-  // import FIreWarn from './preset/FIreWarn.vue';
-  // import FIreControl from './preset/FIreControl.vue';
+import { computed } from 'vue';
+import {
+  CommonItem,
+  Config,
+  // ModuleDataBoard,
+  // ModuleDataChart,
+  // ModuleDataList,
+  // ModuleDataPreset,
+  // ModuleDataTable,
+} from '../../../deviceManager/configurationTable/types';
+import MiniBoard from './detail/MiniBoard.vue';
+import TimelineList from './detail/TimelineList.vue';
+import TimelineListNew from './detail/TimelineListNew.vue';
+import CustomList from './detail/CustomList.vue';
+import CustomGallery from './detail/CustomGallery.vue';
+import ComplexList from './detail/ComplexList.vue';
+import ComplexListNew from './detail/ComplexList-New.vue';
+import GalleryList from './detail/GalleryList.vue';
+import CustomTable from './detail/CustomTable-New.vue';
+import CustomChart from './detail/CustomChart.vue';
+import { clone } from 'lodash-es';
+import { getData, getFormattedText } from '../hooks/helper';
+import BlastDelta from '../../../monitorManager/deviceMonitor/components/device/modal/blastDelta.vue';
+import QHCurve from './preset/QHCurve.vue';
+import MeasureDetail from './preset/MeasureDetail.vue';
+import CustomTabs from './preset/CustomTabs.vue';
+import AIChat from '/@/components/AIChat/MiniChat.vue';
+import DeviceAlarm from './preset/DeviceAlarm.vue';
+import MiniBoardNew from './detail/MiniBoard-New.vue';
+import CustomTableNew from './detail/CustomTable-New.vue';
+// import FIreWarn from './preset/FIreWarn.vue';
+// import FIreControl from './preset/FIreControl.vue';
 
-  const props = defineProps<{
-    data: any;
-    moduleData: Config['moduleData'];
-  }>();
+const props = defineProps<{
+  data: any;
+  moduleData: Config['moduleData'];
+}>();
 
-  const { background, layout } = props.moduleData;
+const { background, layout } = props.moduleData;
 
-  // 获取当原始配置带 items 项时的最终 items 配置
-  function getItems(raw, items: CommonItem[]) {
-    return items.map((i) => {
+// 获取当原始配置带 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),
+    };
+  });
+}
+
+// 获取当 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 {
-        ...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);
+}
+
+/** 根据配置里的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) || [];
+
+  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);
 
-  // 获取当 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 {
+        arr.push({
+          overflow: true,
           ...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) || [];
+        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);
 
-    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: 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({
             overflow: true,
             ...item,
             ...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({
             overflow: true,
             ...item,
             ...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({
             overflow: true,
             ...item,
             ...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({
             overflow: true,
             ...item,
             ...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) break;
-          const data = getData(refData, cfg.readFrom, cfg.parser);
+        break;
+      }
+      case 'chart': {
+        const cfg = chart.shift();
+        if (!cfg) break;
+        const data = getData(refData, cfg.readFrom, cfg.parser);
 
-          arr.push({
-            ...item,
-            config: cfg,
-            data,
-          });
-          break;
-        }
-        case 'table': {
-          const cfg = table.shift();
-          if (!cfg) break;
-          const data = getData(refData, cfg.readFrom, cfg.parser);
+        arr.push({
+          ...item,
+          config: cfg,
+          data,
+        });
+        break;
+      }
+      case 'table': {
+        const cfg = table.shift();
+        if (!cfg) break;
+        const data = getData(refData, cfg.readFrom, cfg.parser);
 
-          arr.push({
-            ...cfg,
-            ...item,
-            columns: cfg.columns,
-            data,
-          });
-          break;
-        }
-        default: {
-          const cfg = preset.shift();
-          if (!cfg) break;
-          const data = getData(refData, cfg.readFrom, cfg.parser);
+        arr.push({
+          ...cfg,
+          ...item,
+          columns: cfg.columns,
+          data,
+        });
+        break;
+      }
+      default: {
+        const cfg = preset.shift();
+        if (!cfg) break;
+        const data = getData(refData, cfg.readFrom, cfg.parser);
 
-          arr.push({
-            ...item,
-            data,
-            config: cfg,
-          });
-          break;
-        }
+        arr.push({
+          ...item,
+          data,
+          config: cfg,
+        });
+        break;
       }
-      return arr;
-    }, []);
-  });
+    }
+    return arr;
+  }, []);
+});
 </script>
 <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;
-  }
-  .content__background {
-    width: 100%;
-    height: 100%;
-    position: absolute;
-    top: 0;
-    left: 0;
-    z-index: 0;
-    object-fit: fill;
-  }
-  .image__background {
-    width: 35%;
-    height: 61%;
-    left: 30%;
-  }
-  .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__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%;
-    padding: 0 34px;
-  }
-  // .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;
-  }
+.content {
+  height: calc(100% - 30px);
+  position: relative;
+  // z-index: -2;
+  display: flex;
+  flex-direction: column;
+}
+.content__background {
+  width: 100%;
+  height: 100%;
+  position: absolute;
+  top: 0;
+  left: 0;
+  z-index: 0;
+  object-fit: fill;
+}
+.image__background {
+  width: 35%;
+  height: 61%;
+  left: 30%;
+}
+.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__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%;
+  padding: 0 34px;
+}
+// .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;
+}
 
-  :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-selection-item) {
-    color: #fff !important;
-  }
-  :deep(.zxm-select-selection-placeholder) {
-    color: #fff !important;
-  }
-  :deep(.dialog-overlay) {
-    width: 100%;
-    height: 100%;
-    position: unset;
-    box-shadow: unset;
-  }
+: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-selection-item) {
+  color: #fff !important;
+}
+:deep(.zxm-select-selection-placeholder) {
+  color: #fff !important;
+}
+:deep(.dialog-overlay) {
+  width: 100%;
+  height: 100%;
+  position: unset;
+  box-shadow: unset;
+}
 
-  ::-webkit-scrollbar {
-    width: 5px !important;
-  }
-  ::-webkit-scrollbar-thumb {
-    width: 5px !important;
-  }
+::-webkit-scrollbar {
+  width: 5px !important;
+}
+::-webkit-scrollbar-thumb {
+  width: 5px !important;
+}
 </style>

+ 57 - 57
src/views/vent/home/configurable/configurable.data.ts

@@ -3937,7 +3937,7 @@ export const testConfigWarnMonitor: Config[] = [
     },
   },
   {
-    deviceType: 'fusionManageInfo',
+    deviceType: 'fireWarnInfo',
     moduleName: '火灾监测预警',
     pageType: 'fusion-warn-green',
     moduleData: {
@@ -3963,11 +3963,11 @@ export const testConfigWarnMonitor: Config[] = [
         items: [
           {
             name: 'board',
-            basis: '35%',
+            basis: '30%',
           },
           {
             name: 'dz_card',
-            basis: '65%',
+            basis: '70%',
           },
         ],
       },
@@ -4086,59 +4086,59 @@ export const testConfigWarnMonitor: Config[] = [
       position: 'top:70px;right:15px',
     },
   },
+  // {
+  //   deviceType: 'warnInfo',
+  //   moduleName: '风险权重比例',
+  //   pageType: '',
+  //   moduleData: {
+  //     header: {
+  //       show: false,
+  //       readFrom: '',
+  //       selector: {
+  //         show: false,
+  //         value: '',
+  //       },
+  //       slot: {
+  //         show: false,
+  //         value: '',
+  //       },
+  //     },
+  //     background: {
+  //       show: false,
+  //       type: 'video',
+  //       link: '',
+  //     },
+  //     layout: {
+  //       direction: 'column',
+  //       items: [
+  //         {
+  //           name: 'yj_risk',
+  //           basis: '100%',
+  //         },
+  //       ],
+  //     },
+  //     board: [],
+  //     chart: [],
+  //     gallery: [],
+  //     gallery_list: [],
+  //     table: [],
+  //     list: [],
+  //     complex_list: [],
+  //     preset: [
+  //       {
+  //         readFrom: 'riskData',
+  //       },
+  //     ],
+  //     // mock: BDfireMock,
+  //   },
+  //   showStyle: {
+  //     size: 'width:180px;height:180px;',
+  //     version: '原版',
+  //     position: 'top:70px;left:450px',
+  //   },
+  // },
   {
-    deviceType: 'fusionManageInfo',
-    moduleName: '风险权重比例',
-    pageType: '',
-    moduleData: {
-      header: {
-        show: false,
-        readFrom: '',
-        selector: {
-          show: false,
-          value: '',
-        },
-        slot: {
-          show: false,
-          value: '',
-        },
-      },
-      background: {
-        show: false,
-        type: 'video',
-        link: '',
-      },
-      layout: {
-        direction: 'column',
-        items: [
-          {
-            name: 'yj_risk',
-            basis: '100%',
-          },
-        ],
-      },
-      board: [],
-      chart: [],
-      gallery: [],
-      gallery_list: [],
-      table: [],
-      list: [],
-      complex_list: [],
-      preset: [
-        {
-          readFrom: 'riskData',
-        },
-      ],
-      // mock: BDfireMock,
-    },
-    showStyle: {
-      size: 'width:360px;height:240px;',
-      version: '原版',
-      position: 'top:50px;left:450px',
-    },
-  },
-  {
-    deviceType: 'fusionManageInfo',
+    deviceType: 'deviceManageInfo',
     moduleName: '设备监测预警',
     pageType: 'fusion-warn-green',
     moduleData: {
@@ -4230,7 +4230,7 @@ export const testConfigWarnMonitor: Config[] = [
               closeCount: 'gate_close',
             },
             window: {
-              url: getThemifyImagesURL(''),
+              url: getThemifyImagesURL('fc'),
               text: '',
               allText: '总数',
               warnText: '报警数',
@@ -4387,7 +4387,7 @@ export const testConfigWarnMonitor: Config[] = [
         items: [
           {
             name: 'yj_chart',
-            basis: '100%',
+            basis: '90%',
           },
         ],
       },

+ 0 - 223
src/views/vent/home/configurable/fireNew.vue

@@ -1,223 +0,0 @@
-<!-- eslint-disable vue/multi-word-component-names -->
-<template>
-  <div class="company-home">
-    <div style="width: 100%; height: 100%; position: absolute; left: 0; top: 0; z-index: 0">
-      <VentModal />
-      <a-button
-        type="primary"
-        shape="circle"
-        style="width: 34px; height: 34px; position: absolute; right: 5px; bottom: 5px; z-index: 5"
-        @click="redirectTo('/micro-vent-3dModal/dashboard/analysis?type=model3D&deviceType=model3D')"
-      >
-        <!-- <EyeFilled /> -->
-      </a-button>
-    </div>
-    <div class="top-bg">
-      <!-- <img style="width: 300px; height: 40px; position: fixed; left: 5px; top: 5px" src="./meeee.png" /> -->
-      <!-- <div class="main-title">{{ mainTitle }}</div> -->
-      <NewNav :Title="mainTitle" />
-    </div>
-    <ModuleFireNew
-      v-for="cfg in cfgs"
-      :key="cfg.deviceType"
-      :show-style="cfg.showStyle"
-      :module-data="cfg.moduleData"
-      :module-name="cfg.moduleName"
-      :device-type="cfg.deviceType"
-      :data="data"
-      :visible="true"
-    />
-    <ModuleNew
-      v-if="cfgTop"
-      :show-style="cfgTop.showStyle"
-      :module-data="cfgTop.moduleData"
-      :module-name="cfgTop.moduleName"
-      :device-type="cfgTop.deviceType"
-      :data="data"
-      :visible="true"
-    />
-    <ModuleFireNewDual
-      v-if="cfgA && cfgB"
-      :show-style="cfgA.showStyle"
-      :module-data-a="cfgA.moduleData"
-      :module-name-a="cfgA.moduleName"
-      :device-type-a="cfgA.deviceType"
-      :module-data-b="cfgB.moduleData"
-      :module-name-b="cfgB.moduleName"
-      :device-type-b="cfgB.deviceType"
-      :data="data"
-      :visible="true"
-    />
-  </div>
-</template>
-<script lang="ts" setup>
-  import { computed, onMounted, onUnmounted } from 'vue';
-  // import { CaretDownOutlined } from '@ant-design/icons-vue';
-  import NewNav from './components/originalNew/NewNavFire.vue';
-  import { useInitConfigs, useInitPage } from './hooks/useInit';
-  import ModuleNew from './components/ModuleNew.vue';
-  import ModuleFireNew from './components/ModuleFireNew.vue';
-  import ModuleFireNewDual from './components/ModuleFireNewDual.vue';
-  import VentModal from '/@/components/vent/micro/ventModal.vue';
-  // import { BDFireMock } from './mock';
-  import { getDisHome } from './configurable.api';
-  // import { EyeFilled } from '@ant-design/icons-vue';
-  import { testConfigNewFire } from './configurable.data.New';
-  const cfgs = computed(() =>
-    configs.value.filter((_, index) => {
-      return index !== 4 && index !== 3 && index !== 5;
-    })
-  );
-  const cfgA = computed<any>(() =>
-    configs.value.find((_, index) => {
-      return index === 3;
-    })
-  );
-  const cfgB = computed<any>(() =>
-    configs.value.find((_, index) => {
-      return index === 4;
-    })
-  );
-  const cfgTop = computed<any>(() =>
-    configs.value.find((_, index) => {
-      return index === 5;
-    })
-  );
-  const { configs, devicesTypes, fetchConfigs } = useInitConfigs();
-  const { mainTitle, data, updateData /** updateEnhancedConfigs */ } = useInitPage('火灾预警系统');
-  let interval: number | undefined;
-  onMounted(() => {
-    // fetchConfigs('New_fire').then(() => {
-    //   configs.value = testConfigNewFire;
-    //   Promise.resolve(BDFireMock).then(updateData);
-    // });
-    // setInterval(() => {
-    //   Promise.resolve(BDFireMock).then(updateData);
-    // }, 2000);
-    fetchConfigs('New_fire').then(() => {
-      configs.value = testConfigNewFire;
-      getDisHome({
-        dataList: devicesTypes.value.concat('fireAllMineWarn').join(','),
-      }).then(updateData);
-    });
-    setInterval(() => {
-      getDisHome({
-        dataList: devicesTypes.value.concat('fireAllMineWarn').join(','),
-      }).then(updateData);
-    }, 2000);
-  });
-
-  onUnmounted(() => {
-    clearInterval(interval);
-  });
-
-  function redirectTo(url) {
-    window.open(url);
-  }
-</script>
-<style lang="less" scoped>
-  @import '/@/design/theme.less';
-
-  @font-face {
-    font-family: 'douyuFont';
-    src: url('../../../../assets/font/douyuFont.otf');
-  }
-
-  @{theme-deepblue} {
-    .company-home {
-      --image-modal-top: url('@/assets/images/fireNew/1.png');
-    }
-  }
-
-  .company-home {
-    --image-modal-top: url('@/assets/images/fireNew/1.png');
-    width: 100%;
-    height: 100%;
-    color: @white;
-    position: relative;
-    background: url('@/assets/images/fireNew/FireBj.png') no-repeat center;
-
-    .top-bg {
-      width: 100%;
-      height: 56px;
-      background: var(--image-modal-top) no-repeat center;
-      position: absolute;
-      z-index: 1;
-      .main-title {
-        height: 56px;
-        font-family: 'douyuFont';
-        font-size: 20px;
-        letter-spacing: 2px;
-        display: flex;
-        justify-content: center;
-        align-items: center;
-      }
-      .top-nav {
-        position: absolute;
-        top: 0;
-        width: 880px;
-        height: 100%;
-        display: flex;
-        justify-content: flex-start;
-      }
-    }
-    .left-t {
-      position: absolute;
-      width: 28%;
-      height: 100%;
-      background: url('@/assets/images/vent/homeNew/leftContent.png') no-repeat center;
-      z-index: 0;
-    }
-    .right-t {
-      position: absolute;
-      width: 172%;
-      height: 100%;
-      background: url('@/assets/images/vent/homeNew/rightContent.png') no-repeat center;
-      z-index: 0;
-    }
-    // .module-left {
-    //   position: absolute;
-    //   width: 450px;
-    //   height: 280px;
-    //   left: 0;
-    // }
-    // .module-right {
-    //   position: absolute;
-    //   width: 450px;
-    //   height: 280px;
-    //   right: 0;
-    // }
-    // .module-bottom {
-    //   position: absolute;
-    //   width: 1000px;
-    //   height: 280px;
-    // }
-    .module-dropdown {
-      padding: 10px;
-      background-image: @vent-configurable-dropdown;
-      border-bottom: 2px solid @vent-configurable-home-light-border;
-      color: @vent-font-color;
-      position: absolute;
-      top: 70px;
-      right: 460px;
-    }
-    .module-dropdown-original {
-      padding: 10px;
-      background-image: @vent-configurable-dropdown;
-      border-bottom: 2px solid @vent-configurable-home-light-border;
-      color: @vent-font-color;
-      position: absolute;
-      top: 70px;
-      right: 460px;
-    }
-    .module-trigger-button {
-      color: @vent-font-color;
-      background-image: @vent-configurable-dropdown;
-      border: none;
-      border-bottom: 2px solid @vent-configurable-home-light-border;
-    }
-  }
-  :deep(.loading-box) {
-    position: unset;
-  }
-</style>

+ 242 - 148
src/views/vent/home/configurable/green/components/dz-card.vue

@@ -1,184 +1,278 @@
 <template>
-    <div class="dzCard">
-        <div class="gas-box">
-            <div class="gas-item">
-                <div class="detail-box">
-                    <div class="detail-container">
-                        <div class="detail-item" v-for="(item, index) in infoData.dataOn" :key="index">
-                            <div class="item-box">
-                                <div class="item-box-label">{{ titleLeft.address }}</div>
-                                <div class="item-box-val">{{ item.value1 || '-' }}</div>
-                            </div>
-                            <div class="item-box">
-                                <div class="item-box-label">{{ titleLeft.gradewarn }}</div>
-                                <div class="item-box-val">{{ item.warnLevel || '-' }}</div>
-                            </div>
-                            <div class="item-box">
-                                <div class="item-box-label">{{ titleLeft.smoke }}</div>
-                                <div class="item-box-val">{{ item.smokeJd || '-' }}</div>
-                            </div>
-                        </div>
-                    </div>
-                </div>
+  <div :class="props.deviceType == 'fireWarnInfo' ? 'dzCard1' : 'dzCard'">
+    <div class="gas-box">
+      <div class="gas-item">
+        <div class="detail-box">
+          <div class="detail-container">
+            <div class="detail-item" v-for="(item, index) in infoData.dataOn" :key="index">
+              <div class="item-box">
+                <div class="item-box-label">{{ titleLeft.address }}</div>
+                <div class="item-box-val">{{ item.value1 || '-' }}</div>
+              </div>
+              <div class="item-box">
+                <div class="item-box-label">{{ titleLeft.gradewarn }}</div>
+                <div class="item-box-val">{{ item.warnLevel || '-' }}</div>
+              </div>
+              <div class="item-box">
+                <div class="item-box-label">{{ titleLeft.smoke }}</div>
+                <div class="item-box-val">{{ item.smokeJd || '-' }}</div>
+              </div>
             </div>
-            <div class="gas-item">
-                <div class="detail-box">
-                    <div class="detail-container">
-                        <div class="detail-item">
-                            <div class="item-box1">
-                                <div class="item-box-label">{{ titleRight.temp }}</div>
-                                <div class="item-box-val1">{{ infoData.tempVal }}</div>
-                            </div>
-                            <div class="item-box1">
-                                <div class="item-box-label">{{ titleRight.smokeing }}</div>
-                                <div class="item-box-val1">{{ infoData.smokeVal }}</div>
-                            </div>
-                            <div class="item-box1">
-                                <div class="item-box-label">{{ titleRight.fire }}</div>
-                                <div class="item-box-val1">{{ infoData.fireVal }}</div>
-                            </div>
-                            <div class="item-box1">
-                                <div class="item-box-label">{{ titleRight.comax }}</div>
-                                <div class="item-box-val1">{{ infoData.coVal }}</div>
-                            </div>
-                        </div>
-                    </div>
-                </div>
+          </div>
+        </div>
+      </div>
+      <div class="gas-item">
+        <div class="detail-box">
+          <div class="detail-container">
+            <div class="detail-item">
+              <div class="item-box1">
+                <div class="item-box-label">{{ titleRight.temp }}</div>
+                <div class="item-box-val1">{{ infoData.tempVal }}</div>
+              </div>
+              <div class="item-box1">
+                <div class="item-box-label">{{ titleRight.smokeing }}</div>
+                <div class="item-box-val1">{{ infoData.smokeVal }}</div>
+              </div>
+              <div class="item-box1">
+                <div class="item-box-label">{{ titleRight.fire }}</div>
+                <div class="item-box-val1">{{ infoData.fireVal }}</div>
+              </div>
+              <div class="item-box1">
+                <div class="item-box-label">{{ titleRight.comax }}</div>
+                <div class="item-box-val1">{{ infoData.coVal }}</div>
+              </div>
             </div>
+          </div>
         </div>
+      </div>
     </div>
+  </div>
 </template>
 
 <script lang="ts" setup>
-import { ref, reactive, watch } from 'vue'
+import { ref, reactive, watch } from 'vue';
 
 let props = defineProps({
-    titleLeft: {
-        type: Object,
-        default: () => {
-            return {}
-        }
+  titleLeft: {
+    type: Object,
+    default: () => {
+      return {};
     },
-    titleRight: {
-        type: Object,
-        default: () => {
-            return {}
-        }
+  },
+  titleRight: {
+    type: Object,
+    default: () => {
+      return {};
     },
-    paramData: {
-        type: Object,
-        default: () => {
-            return {}
-        }
-    }
-})
+  },
+  paramData: {
+    type: Object,
+    default: () => {
+      return {};
+    },
+  },
+  deviceType: {
+    type: String,
+    default: '',
+  },
+});
 
-let infoData = reactive({})
+let infoData = reactive({});
 
-watch(() => props.paramData, (newV, oldV) => {
-    infoData = Object.assign({}, newV)
-}, { immediate: true })
+watch(
+  () => props.paramData,
+  (newV, oldV) => {
+    infoData = Object.assign({}, newV);
+  },
+  { immediate: true }
+);
 </script>
 
 <style lang="less" scoped>
 @import '/@/design/theme.less';
 
 @{theme-deepblue} {
-    .dzCard {
-        --image-model_gas_item: url('@/assets/images/themify/deepblue/home-container/configurable/900.png');
-        --image-model_gas_item1: url('@/assets/images/themify/deepblue/home-container/configurable/1100.png');
-    }
+  .dzCard {
+    --image-model_gas_item: url('@/assets/images/themify/deepblue/home-container/configurable/900.png');
+    --image-model_gas_item1: url('@/assets/images/themify/deepblue/home-container/configurable/1100.png');
+  }
 }
 
 .dzCard {
-    --image-model_gas_item: url('@/assets/images/home-green/900.png');
-    --image-model_gas_item1: url('@/assets/images/home-green/1100.png');
-    width: 100%;
-    height: 72%;
-    position: absolute;
-    left: 0;
-    top: 86px;
-
-    .gas-box {
-        display: flex;
-        justify-content: center;
+  --image-model_gas_item: url('@/assets/images/home-green/900.png');
+  --image-model_gas_item1: url('@/assets/images/home-green/1100.png');
+  --image-model_fire_item: url('@/assets/images/home-warn/4-2.png');
+  width: 100%;
+  height: 72%;
+  position: absolute;
+  left: 0;
+  top: 86px;
+  .gas-box {
+    display: flex;
+    justify-content: center;
+    height: 100%;
+
+    .gas-item {
+      position: relative;
+      width: 50%;
+      height: 100%;
+      margin: 0px 5px;
+
+      &:nth-child(1) {
+        background: var(--image-model_gas_item) no-repeat;
+        background-size: 100% 100%;
+      }
+
+      &:nth-child(2) {
+        background: var(--image-model_gas_item1) no-repeat;
+        background-size: 100% 100%;
+      }
+
+      .detail-box {
+        position: relative;
+        height: 100%;
+        padding-top: 68px;
+
+        .detail-container {
+          height: 100%;
+          overflow-y: auto;
+
+          .detail-item {
+            width: 100%;
+            height: 100%;
+
+            .item-box {
+              width: 100%;
+              padding: 0px 10px;
+              height: 60px;
+              display: flex;
+              justify-content: space-between;
+              align-items: center;
+            }
+
+            .item-box1 {
+              width: 100%;
+              padding: 0px 10px;
+              height: 42px;
+              display: flex;
+              justify-content: space-between;
+              align-items: center;
+            }
+
+            .item-box-label {
+              flex-shrink: 0;
+              width: 60px;
+              font-size: 12px;
+              text-align: left;
+              margin-right: 10px;
+            }
+
+            .item-box-val {
+              text-align: right;
+              color: #b9ffe5;
+              font-family: 'douyuFont';
+              font-size: 12px;
+            }
+
+            .item-box-val1 {
+              text-align: right;
+              color: #b9f1ff;
+              font-family: 'douyuFont';
+              font-size: 12px;
+            }
+          }
+        }
+      }
+    }
+  }
+}
+.dzCard1 {
+  --image-model_gas_item: url('@/assets/images/home-green/900.png');
+  --image-model_gas_item1: url('@/assets/images/home-green/1100.png');
+  --image-model_fire_item: url('@/assets/images/home-warn/4-2.png');
+  width: 100%;
+  height: 72%;
+  position: absolute;
+  left: 0;
+
+  .gas-box {
+    display: flex;
+    justify-content: center;
+    height: 100%;
+
+    .gas-item {
+      position: relative;
+      width: 50%;
+      height: 100%;
+      margin: 0px 5px;
+      &:nth-child(1) {
+        background: var(--image-model_fire_item) no-repeat;
+        background-size: 100% 100%;
+      }
+
+      &:nth-child(2) {
+        background: var(--image-model_fire_item) no-repeat;
+        background-size: 100% 100%;
+      }
+      .detail-box {
+        position: relative;
         height: 100%;
+        padding-top: 15px;
+
+        .detail-container {
+          height: 100%;
+          overflow-y: hidden;
+          &:hover {
+            overflow-y: auto;
+          }
 
-        .gas-item {
-            position: relative;
-            width: 50%;
+          .detail-item {
+            width: 100%;
             height: 100%;
-            margin: 0px 5px;
 
-            &:nth-child(1) {
-                background: var(--image-model_gas_item) no-repeat;
-                background-size: 100% 100%;
+            .item-box {
+              width: 100%;
+              padding: 0px 10px;
+              height: 60px;
+              display: flex;
+              justify-content: space-between;
+              align-items: center;
+            }
+
+            .item-box1 {
+              width: 100%;
+              padding: 0px 10px;
+              height: 42px;
+              display: flex;
+              justify-content: space-between;
+              align-items: center;
+            }
+
+            .item-box-label {
+              flex-shrink: 0;
+              width: 60px;
+              font-size: 12px;
+              text-align: left;
+              margin-right: 10px;
             }
 
-            &:nth-child(2) {
-                background: var(--image-model_gas_item1) no-repeat;
-                background-size: 100% 100%;
+            .item-box-val {
+              text-align: right;
+              color: #c0fbff;
+              font-family: 'douyuFont';
+              font-size: 12px;
             }
 
-            .detail-box {
-                position: relative;
-                height: 100%;
-                padding-top: 68px;
-
-                .detail-container {
-                    height: 100%;
-                    overflow-y: auto;
-
-                    .detail-item {
-                        width: 100%;
-                        height: 100%;
-
-                        .item-box {
-                            width: 100%;
-                            padding: 0px 10px;
-                            height: 60px;
-                            display: flex;
-                            justify-content: space-between;
-                            align-items: center;
-
-                        }
-
-                        .item-box1 {
-                            width: 100%;
-                            padding: 0px 10px;
-                            height: 42px;
-                            display: flex;
-                            justify-content: space-between;
-                            align-items: center;
-
-                        }
-
-                        .item-box-label {
-                            flex-shrink: 0;
-                            width: 60px;
-                            font-size: 12px;
-                            text-align: left;
-                            margin-right: 10px;
-                        }
-
-                        .item-box-val {
-                            text-align: right;
-                            color: #b9ffe5;
-                            font-family: 'douyuFont';
-                            font-size: 12px;
-                        }
-
-                        .item-box-val1 {
-                            text-align: right;
-                            color: #b9f1ff;
-                            font-family: 'douyuFont';
-                            font-size: 12px;
-
-                        }
-                    }
-                }
+            .item-box-val1 {
+              text-align: right;
+              color: #53f696;
+              font-family: 'douyuFont';
+              font-size: 12px;
             }
+          }
         }
+      }
     }
+  }
 }
 </style>

+ 162 - 106
src/views/vent/home/configurable/green/components/dz-list.vue

@@ -1,137 +1,193 @@
 <template>
-    <div class="dz-list">
-        <div class="icons-box" @mouseleave="resetScroll">
-            <template v-for="(item, key) in listOption" :key="key">
-                <div class="icon-item">
-                    <img :src="item.url" :alt="item.text" />
-                    <div class="level-text">
-                        <div class="all-count">
-                            <span>{{ `${item.allText}&nbsp:&nbsp` }}</span>
-                            <span class="num-count">{{ listData[item.allCount] || 0 }}</span>
-                        </div>
-                        <div class="warn-count">
-                            <span>{{ `${item.warnText}&nbsp:&nbsp` }}</span>
-                            <span :class="item.warnCount ? 'num-count1' : 'num-count'">{{ listData[item.warnCount] || 0
-                                }}</span>
-                        </div>
-                        <div class="close-count">
-                            <span> {{ `${item.closeText}&nbsp:&nbsp` }}</span>
-                            <span :class="item.closeCount ? 'num-count1' : 'num-count'">{{ listData[item.closeCount] ||
-                                0
-                                }}</span>
-                        </div>
-                    </div>
-                </div>
-            </template>
+  <div class="dz-list">
+    <div :class="deviceType == 'deviceManageInfo' ? 'icons-box1' : 'icons-box'" @mouseleave="resetScroll">
+      <template v-for="(item, key) in listOption" :key="key">
+        <div class="icon-item">
+          <!-- <img :src="item.url" :alt="item.text" /> -->
+          <div class="level-text">
+            <div class="all-count">
+              <span>{{ `${item.allText}&nbsp:&nbsp` }}</span>
+              <span class="num-count">{{ listData[item.allCount] || 0 }}</span>
+            </div>
+            <div class="warn-count">
+              <span>{{ `${item.warnText}&nbsp:&nbsp` }}</span>
+              <span :class="item.warnCount ? 'num-count1' : 'num-count'">{{ listData[item.warnCount] || 0 }}</span>
+            </div>
+            <div class="close-count">
+              <span> {{ `${item.closeText}&nbsp:&nbsp` }}</span>
+              <span :class="item.closeCount ? 'num-count1' : 'num-count'">{{ listData[item.closeCount] || 0 }}</span>
+            </div>
+          </div>
         </div>
+      </template>
     </div>
+  </div>
 </template>
 
 <script setup lang="ts">
-import { ref, reactive, watch } from 'vue'
+import { ref, reactive, watch } from 'vue';
 
 let props = defineProps({
-    listOption: {
-        type: Object,
-        default: () => {
-            return {}
-        }
+  listOption: {
+    type: Object,
+    default: () => {
+      return {};
     },
-    listData: {
-        type: Object,
-        default: () => {
-            return {}
-        }
-    }
-})
-
+  },
+  listData: {
+    type: Object,
+    default: () => {
+      return {};
+    },
+  },
+  deviceType: {
+    type: String,
+    default: '',
+  },
+});
 
 const resetScroll = (e: Event) => {
-    if (e.target && e.target) (e.target as Element).scrollTop = 0;
+  if (e.target && e.target) (e.target as Element).scrollTop = 0;
 };
 
-watch(() => props.listData, (newV, oldV) => {
-    console.log(newV, '设备')
-}, { immediate: true, deep: true })
+watch(
+  () => props.listData,
+  (newV, oldV) => {
+    console.log(newV, '设备');
+  },
+  { immediate: true, deep: true }
+);
 </script>
 
 <style lang="less" scoped>
 @import '/@/design/theme.less';
 
 @{theme-deepblue} {
-    .dz-list {
-        --image-model_icon-item: url('@/assets/images/themify/deepblue/home-container/configurable/1600.png');
-    }
+  .dz-list {
+    --image-model_icon-item: url('@/assets/images/themify/deepblue/home-container/configurable/1600.png');
+  }
 }
-
 .dz-list {
-    --image-model_icon-item: url('@/assets/images/home-green/1600.png');
+  --image-model_icon-item: url('@/assets/images/home-green/1600.png');
+  width: 100%;
+  height: 100%;
+}
+
+.icons-box {
+  height: 100%;
+  overflow-y: hidden;
 
+  &:hover {
+    overflow-y: auto;
+    overflow-x: auto;
+  }
+
+  .icon-item {
+    position: relative;
     width: 100%;
-    height: 100%;
+    height: 46px;
+    background: var(--image-model_icon-item) no-repeat;
+    background-size: 100% 100%;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    margin: 5px auto;
+
+    &:nth-child(even) {
+      padding-right: 0px;
+    }
 
-    .icons-box {
-        height: 100%;
-        overflow-y: hidden;
+    .level-text {
+      width: 76%;
+      display: flex;
+      justify-content: space-around;
+      position: absolute;
+      top: 10px;
+      left: 76px;
+      color: #ffffffe0;
+      font-size: 14px;
+      text-align: center;
+      letter-spacing: 1px;
+
+      .num-count,
+      .num-count1 {
+        font-family: 'douyuFont';
+        font-size: 12px;
+      }
+
+      .warn-count,
+      .close-count {
+        .num-count {
+          color: #ffffffe0;
+        }
 
-        &:hover {
-            overflow-y: auto;
-            overflow-x: auto;
+        .num-count1 {
+          color: #ff0000;
         }
+      }
+    }
 
-        .icon-item {
-            position: relative;
-            width: 100%;
-            height: 46px;
-            background: var(--image-model_icon-item) no-repeat;
-            background-size: 100% 100%;
-            display: flex;
-            align-items: center;
-            justify-content: center;
-            margin: 5px auto;
-
-            &:nth-child(even) {
-                padding-right: 0px;
-            }
-
-            .level-text {
-                width: 76%;
-                display: flex;
-                justify-content: space-around;
-                position: absolute;
-                top: 10px;
-                left: 76px;
-                color: #ffffffe0;
-                font-size: 14px;
-                text-align: center;
-                letter-spacing: 1px;
-
-                .num-count,
-                .num-count1 {
-                    font-family: 'douyuFont';
-                    font-size: 12px;
-                }
-
-                .warn-count,
-                .close-count {
-                    .num-count {
-                        color: #ffffffe0;
-                    }
-
-                    .num-count1 {
-                        color: #ff0000;
-                    }
-                }
-            }
-
-            img {
-                width: 50px;
-                height: 50px;
-                position: absolute;
-                left: 16px;
-                top: -18px;
-            }
+    img {
+      width: 100%;
+      height: 60px;
+    }
+  }
+}
+.icons-box1 {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  flex-wrap: wrap;
+  gap: 10px;
+  overflow-y: hidden;
+  padding: 5px;
+  box-sizing: border-box;
+  &:hover {
+    overflow-y: auto;
+  }
+
+  .icon-item {
+    flex: 0 0 calc(50% - 5px);
+    height: 46px;
+    background: var(--image-model_icon-item) no-repeat;
+    background-size: 100% 100%;
+    position: relative;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+
+    .level-text {
+      width: 76%;
+      display: flex;
+      justify-content: space-around;
+      position: absolute;
+      top: 10px;
+      left: 76px;
+      color: #ffffffe0;
+      font-size: 14px;
+      text-align: center;
+      letter-spacing: 1px;
+      .num-count,
+      .num-count1 {
+        font-family: 'douyuFont';
+        font-size: 12px;
+      }
+
+      .warn-count,
+      .close-count {
+        .num-count {
+          color: #ffffffe0;
+        }
+
+        .num-count1 {
+          color: #ff0000;
         }
+      }
+    }
+    img {
+      width: 100%;
+      height: 60px;
     }
+  }
 }
 </style>

+ 0 - 166
src/views/vent/home/configurable/ventNew.vue

@@ -1,166 +0,0 @@
-<!-- eslint-disable vue/multi-word-component-names -->
-<template>
-  <div class="company-home">
-    <div style="width: 100%; height: 100%; position: absolute; left: 0; top: 0; z-index: 0">
-      <VentModal />
-    </div>
-    <div class="top-bg">
-      <!-- <img style="width: 300px; height: 40px; position: fixed; left: 5px; top: 5px" src="./meeee.png" /> -->
-      <!-- <div class="main-title">{{ mainTitle }}</div> -->
-      <NewNav :Title="mainTitle" />
-    </div>
-    <div class="left-t"> </div>
-    <div class="right-t"> </div>
-    <template v-if="isNew">
-      <ModuleNew
-        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"
-      />
-    </template>
-  </div>
-</template>
-<script lang="ts" setup>
-  import { onMounted, onUnmounted } from 'vue';
-  // import { CaretDownOutlined } from '@ant-design/icons-vue';
-  // import MonitorCenter from './components/MonitorCenter.vue';
-  import NewNav from './components/originalNew/NewNav.vue';
-  import { useInitConfigs, useInitPage } from './hooks/useInit';
-  import ModuleNew from './components/ModuleNew.vue';
-  // import { useRoute } from 'vue-router';
-  import VentModal from '/@/components/vent/micro/ventModal.vue';
-  import { getHomeData } from './configurable.api';
-  // import { useRoute } from 'vue-router';
-  import { testConfigVentNew } from './configurable.data';
-  const { configs, isNew, fetchConfigs } = useInitConfigs();
-  const { mainTitle, data, updateData, updateEnhancedConfigs } = useInitPage('一通三防智能管控平台');
-  // const route = useRoute();
-  let interval: number | undefined;
-
-  onMounted(() => {
-    fetchConfigs('vent').then(() => {
-      configs.value = testConfigVentNew;
-      updateEnhancedConfigs(configs.value);
-
-      getHomeData({}).then(updateData);
-    });
-    setInterval(() => {
-      getHomeData({}).then(updateData);
-    }, 60000);
-  });
-
-  onUnmounted(() => {
-    clearInterval(interval);
-  });
-</script>
-<style lang="less" scoped>
-  @import '/@/design/theme.less';
-
-  @font-face {
-    font-family: 'douyuFont';
-    src: url('../../../../assets/font/douyuFont.otf');
-  }
-
-  @{theme-deepblue} {
-    .company-home {
-      --image-modal-top: url('@/assets/images/vent/homeNew/modaltop.png');
-    }
-  }
-
-  .company-home {
-    --image-modal-top: url('@/assets/images/vent/homeNew/modaltop.png');
-    width: 100%;
-    height: 100%;
-    color: @white;
-    position: relative;
-    background: url('@/assets/images/vent/homeNew/bg.png') no-repeat center;
-
-    .top-bg {
-      width: 100%;
-      height: 56px;
-      background: var(--image-modal-top) no-repeat center;
-      position: absolute;
-      z-index: 1;
-      .main-title {
-        height: 56px;
-        font-family: 'douyuFont';
-        font-size: 20px;
-        letter-spacing: 2px;
-        display: flex;
-        justify-content: center;
-        align-items: center;
-      }
-      .top-nav {
-        position: absolute;
-        top: 0;
-        width: 880px;
-        height: 100%;
-        display: flex;
-        justify-content: flex-start;
-      }
-    }
-    .left-t {
-      position: absolute;
-      width: 28%;
-      height: 100%;
-      background: url('@/assets/images/vent/homeNew/leftContent.png') no-repeat center;
-      z-index: 0;
-    }
-    .right-t {
-      position: absolute;
-      width: 172%;
-      height: 100%;
-      background: url('@/assets/images/vent/homeNew/rightContent.png') no-repeat center;
-      z-index: 0;
-    }
-    // .module-left {
-    //   position: absolute;
-    //   width: 450px;
-    //   height: 280px;
-    //   left: 0;
-    // }
-    // .module-right {
-    //   position: absolute;
-    //   width: 450px;
-    //   height: 280px;
-    //   right: 0;
-    // }
-    // .module-bottom {
-    //   position: absolute;
-    //   width: 1000px;
-    //   height: 280px;
-    // }
-    .module-dropdown {
-      padding: 10px;
-      background-image: @vent-configurable-dropdown;
-      border-bottom: 2px solid @vent-configurable-home-light-border;
-      color: @vent-font-color;
-      position: absolute;
-      top: 70px;
-      right: 460px;
-    }
-    .module-dropdown-original {
-      padding: 10px;
-      background-image: @vent-configurable-dropdown;
-      border-bottom: 2px solid @vent-configurable-home-light-border;
-      color: @vent-font-color;
-      position: absolute;
-      top: 70px;
-      right: 460px;
-    }
-    .module-trigger-button {
-      color: @vent-font-color;
-      background-image: @vent-configurable-dropdown;
-      border: none;
-      border-bottom: 2px solid @vent-configurable-home-light-border;
-    }
-  }
-  :deep(.loading-box) {
-    position: unset;
-  }
-</style>

+ 266 - 266
src/views/vent/monitorManager/AllDeviceMonitor/index.vue

@@ -172,310 +172,310 @@
 </template>
 
 <script setup lang="ts">
-import { onBeforeUnmount, onUnmounted, onMounted, ref, reactive, nextTick, inject, unref } from 'vue';
-import MonitorTable from '../comment/MonitorTable.vue';
-import HistoryTable from '../comment/HistoryTable.vue';
-import AlarmHistoryTable from '../comment/AlarmHistoryTable.vue';
-import HandlerHistoryTable from '../comment/HandlerHistoryTable.vue';
-import HandleModal from './modal.vue';
-import DeviceBaseInfo from '../comment/components/DeviceBaseInfo.vue';
-import { deviceControlApi } from '/@/api/vent/index';
-import { message } from 'ant-design-vue';
-import { list, getTableList } from './deviceMonitor.api';
-import lodash from 'lodash';
-import { setDivHeight } from '/@/utils/event';
-import { BorderBox8 as DvBorderBox8 } from '@kjgl77/datav-vue3';
-import { useRouter } from 'vue-router';
-import { useModal } from '/@/components/Modal';
-import { useCamera } from '/@/hooks/system/useCamera';
-import { usePermission } from '/@/hooks/web/usePermission';
-import { getDictItems } from '/@/api/common/api';
+  import { onBeforeUnmount, onUnmounted, onMounted, ref, reactive, nextTick, inject, unref } from 'vue';
+  import MonitorTable from '../comment/MonitorTable.vue';
+  import HistoryTable from '../comment/HistoryTable.vue';
+  import AlarmHistoryTable from '../comment/AlarmHistoryTable.vue';
+  import HandlerHistoryTable from '../comment/HandlerHistoryTable.vue';
+  import HandleModal from './modal.vue';
+  import DeviceBaseInfo from '../comment/components/DeviceBaseInfo.vue';
+  import { deviceControlApi } from '/@/api/vent/index';
+  import { message } from 'ant-design-vue';
+  import { list, getTableList } from './deviceMonitor.api';
+  import lodash from 'lodash';
+  import { setDivHeight } from '/@/utils/event';
+  import { BorderBox8 as DvBorderBox8 } from '@kjgl77/datav-vue3';
+  import { useRouter } from 'vue-router';
+  import { useModal } from '/@/components/Modal';
+  import { useCamera } from '/@/hooks/system/useCamera';
+  import { usePermission } from '/@/hooks/web/usePermission';
+  import { getDictItems } from '/@/api/common/api';
 
-const { hasPermission } = usePermission();
+  const { hasPermission } = usePermission();
 
-const globalConfig = inject('globalConfig');
+  const globalConfig = inject('globalConfig');
 
-const { currentRoute } = useRouter();
-const MonitorDataTable = ref();
-let contrlValue = '';
-const playerRef = ref();
-const deviceType = ref('door');
-// const deviceType = ref('firedoor');
-const activeKey = ref('1'); // tab
+  const { currentRoute } = useRouter();
+  const MonitorDataTable = ref();
+  let contrlValue = '';
+  const playerRef = ref();
+  const deviceType = ref('door');
+  // const deviceType = ref('firedoor');
+  const activeKey = ref('1'); // tab
 
-const scroll = reactive({
-  y: 230,
-});
-const modelList = ref<{ text: string; value: string }[]>([]);
-const doorIsOpen = ref(false); //前门是否开启
-const modalIsShow = ref<boolean>(false); // 是否显示模态框
-const modalTitle = ref(''); // 模态框标题显示内容,根据设备操作类型决定
-const modalType = ref(''); // 模态框内容显示类型,设备操作类型
+  const scroll = reactive({
+    y: 230,
+  });
+  const modelList = ref<{ text: string; value: string }[]>([]);
+  const doorIsOpen = ref(false); //前门是否开启
+  const modalIsShow = ref<boolean>(false); // 是否显示模态框
+  const modalTitle = ref(''); // 模态框标题显示内容,根据设备操作类型决定
+  const modalType = ref(''); // 模态框内容显示类型,设备操作类型
 
-const selectRowIndex = ref(-1); // 选中行
-const dataSource = ref([]);
+  const selectRowIndex = ref(-1); // 选中行
+  const dataSource = ref([]);
 
-const deviceBaseList = ref([]); // 设备基本信息
-const [registerModal, { openModal, closeModal }] = useModal();
+  const deviceBaseList = ref([]); // 设备基本信息
+  const [registerModal, { openModal, closeModal }] = useModal();
 
-const { getCamera, removeCamera } = useCamera();
+  const { getCamera, removeCamera } = useCamera();
 
-const tabChange = (activeKeyVal) => {
-  activeKey.value = activeKeyVal;
-  if (activeKeyVal == 1) {
-    nextTick(() => {
-      if (MonitorDataTable.value) MonitorDataTable.value.setSelectedRowKeys([selectData.deviceID]);
-    });
-  }
-};
+  const tabChange = (activeKeyVal) => {
+    activeKey.value = activeKeyVal;
+    if (activeKeyVal == 1) {
+      nextTick(() => {
+        if (MonitorDataTable.value) MonitorDataTable.value.setSelectedRowKeys([selectData.deviceID]);
+      });
+    }
+  };
 
-const initData = {
-  deviceID: '',
-  deviceType: '',
-  strname: '',
-  frontRearDP: '-', //压差
-  // sourcePressure: '-', //气源压力
-  runRoRecondition: null,
-  autoRoManual: null,
-  netStatus: '0', //通信状态
-  frontGateOpen: '0',
-  frontGateClose: '1',
-  rearGateOpen: '0',
-  rearGateClose: '1',
-  midGateOpen: '0',
-  midGateClose: '1',
-  fault: '气源压力超限',
-  masterComputer: 0,
-  frontGateOpenCtrl: false,
-  rearGateOpenCtrl: false,
-  cameras: [],
-};
+  const initData = {
+    deviceID: '',
+    deviceType: '',
+    strname: '',
+    frontRearDP: '-', //压差
+    // sourcePressure: '-', //气源压力
+    runRoRecondition: null,
+    autoRoManual: null,
+    netStatus: '0', //通信状态
+    frontGateOpen: '0',
+    frontGateClose: '1',
+    rearGateOpen: '0',
+    rearGateClose: '1',
+    midGateOpen: '0',
+    midGateClose: '1',
+    fault: '气源压力超限',
+    masterComputer: 0,
+    frontGateOpenCtrl: false,
+    rearGateOpenCtrl: false,
+    cameras: [],
+  };
 
-// 监测数据
-const selectData = reactive(lodash.cloneDeep(initData));
-function deviceEdit(e: Event, type: string, record) {
-  e.stopPropagation();
-  openModal(true, {
-    type,
-    deviceId: record['deviceID'],
-  });
-}
-// 获取设备基本信息列表
-function getDeviceBaseList() {
-  getTableList({ pageSize: 1000 }).then((res) => {
-    deviceBaseList.value = res.records;
-  });
-}
+  // 监测数据
+  const selectData = reactive(lodash.cloneDeep(initData));
+  function deviceEdit(e: Event, type: string, record) {
+    e.stopPropagation();
+    openModal(true, {
+      type,
+      deviceId: record['deviceID'],
+    });
+  }
+  // 获取设备基本信息列表
+  function getDeviceBaseList() {
+    getTableList({ pageSize: 1000 }).then((res) => {
+      deviceBaseList.value = res.records;
+    });
+  }
 
-// https获取监测数据
-let timer: null | NodeJS.Timeout = null;
-async function getMonitor(flag?) {
-  if (Object.prototype.toString.call(timer) === '[object Null]') {
-    timer = await setTimeout(
-      async () => {
-        const res = await list({ devicetype: deviceType.value, pagetype: 'normal' });
-        if (res.msgTxt && res.msgTxt[0]) {
-          dataSource.value = res.msgTxt[0].datalist || [];
-          dataSource.value.forEach((data: any) => {
-            const readData = data.readData;
-            data = Object.assign(data, readData);
-          });
-          if (dataSource.value.length > 0 && selectRowIndex.value == -1 && MonitorDataTable.value) {
-            // 初始打开页面
-            if (currentRoute.value && currentRoute.value['query'] && currentRoute.value['query']['id']) {
-              MonitorDataTable.value.setSelectedRowKeys([currentRoute.value['query']['id']]);
-            } else {
-              MonitorDataTable.value.setSelectedRowKeys([dataSource.value[0]['deviceID']]);
+  // https获取监测数据
+  let timer: null | NodeJS.Timeout = null;
+  async function getMonitor(flag?) {
+    if (Object.prototype.toString.call(timer) === '[object Null]') {
+      timer = await setTimeout(
+        async () => {
+          const res = await list({ devicetype: deviceType.value, pagetype: 'normal' });
+          if (res.msgTxt && res.msgTxt[0]) {
+            dataSource.value = res.msgTxt[0].datalist || [];
+            dataSource.value.forEach((data: any) => {
+              const readData = data.readData;
+              data = Object.assign(data, readData);
+            });
+            if (dataSource.value.length > 0 && selectRowIndex.value == -1 && MonitorDataTable.value) {
+              // 初始打开页面
+              if (currentRoute.value && currentRoute.value['query'] && currentRoute.value['query']['id']) {
+                MonitorDataTable.value.setSelectedRowKeys([currentRoute.value['query']['id']]);
+              } else {
+                MonitorDataTable.value.setSelectedRowKeys([dataSource.value[0]['deviceID']]);
+              }
             }
+            Object.assign(selectData, dataSource.value[selectRowIndex.value]);
+            monitorAnimation(selectData);
+            if (timer) {
+              timer = null;
+            }
+            getMonitor();
           }
-          Object.assign(selectData, dataSource.value[selectRowIndex.value]);
-          monitorAnimation(selectData);
-          if (timer) {
-            timer = null;
-          }
-          getMonitor();
-        }
-      },
-      flag ? 0 : 1000
-    );
+        },
+        flag ? 0 : 1000
+      );
+    }
   }
-}
 
-// 切换检测数据
-async function getSelectRow(selectRow, index) {
-  if (!selectRow) return;
-  selectRowIndex.value = index;
-  const baseData: any = deviceBaseList.value.find((baseData: any) => baseData.id === selectRow.deviceID);
-  Object.assign(selectData, initData, selectRow, baseData);
-  doorDeviceState = 1; //记录设备状态,为了与下一次监测数据做比较
-  isdoorOpenRunning = true; //开关门动作是否在进行
-  await getCamera(selectRow.deviceID, playerRef.value);
-}
-
-function playAnimation(handlerState, data: any = null) {
-  const value = data;
-  switch (handlerState) {
-    case 1: // 打开前门
-      modalTitle.value = '打开';
-      modalType.value = '1';
-      modalIsShow.value = true;
-      break;
-    case 2: // 关闭前门
-      modalTitle.value = '关闭';
-      modalType.value = '2';
-      modalIsShow.value = true;
-      break;
-    case 7: // 控制模式切换
-      modalTitle.value = '控制模式切换';
-      modalType.value = '7';
-      modalIsShow.value = true;
-      break;
+  // 切换检测数据
+  async function getSelectRow(selectRow, index) {
+    if (!selectRow) return;
+    selectRowIndex.value = index;
+    const baseData: any = deviceBaseList.value.find((baseData: any) => baseData.id === selectRow.deviceID);
+    Object.assign(selectData, initData, selectRow, baseData);
+    doorDeviceState = 1; //记录设备状态,为了与下一次监测数据做比较
+    isdoorOpenRunning = true; //开关门动作是否在进行
+    await getCamera(selectRow.deviceID, playerRef.value);
   }
 
-  if (globalConfig?.simulatedPassword) {
-    handleOK('', handlerState + '');
-  }
-  contrlValue = value;
-}
+  function playAnimation(handlerState, data: any = null) {
+    const value = data;
+    switch (handlerState) {
+      case 1: // 打开前门
+        modalTitle.value = '打开';
+        modalType.value = '1';
+        modalIsShow.value = true;
+        break;
+      case 2: // 关闭前门
+        modalTitle.value = '关闭';
+        modalType.value = '2';
+        modalIsShow.value = true;
+        break;
+      case 7: // 控制模式切换
+        modalTitle.value = '控制模式切换';
+        modalType.value = '7';
+        modalIsShow.value = true;
+        break;
+    }
 
-function handleOK(passWord, handlerState) {
-  if (!passWord && !globalConfig?.simulatedPassword) {
-    message.warning('请输入密码');
-    return;
-  }
-  if (isOpenRunning) {
-    return;
-  }
-  const data = {
-    deviceid: selectData.deviceID,
-    devicetype: selectData.deviceType,
-    paramcode: '',
-    value: contrlValue,
-    password: passWord || globalConfig?.simulatedPassword,
-    masterComputer: selectData.masterComputer,
-  };
-  switch (handlerState) {
-    case '1': // 打开前门
-      if (selectData.doorOpen == '0' && selectData.doorClose == '1') {
-        data.paramcode = 'frontGateOpen_S';
-      }
-      break;
-    case '2': // 关闭前门
-      if (selectData.doorOpen == '1' && selectData.doorClose == '0') {
-        data.paramcode = 'frontGateClose_S';
-      }
-      break;
-    case '7': // 远程与就地
-      data.paramcode = 'autoRoManualControl';
-      data.value = selectData.contrlMod != 'loopCtrl' ? contrlValue : '';
-      selectData.autoRoManual = null;
+    if (globalConfig?.simulatedPassword) {
+      handleOK('', handlerState + '');
+    }
+    contrlValue = value;
   }
 
-  if (data.paramcode) {
-    deviceControlApi(data).then((res) => {
-      // 模拟时开启
-      if (res.success) {
-        modalIsShow.value = false;
-        if (globalConfig.History_Type == 'remote') {
-          message.success('指令已下发至生产管控平台成功!');
+  function handleOK(passWord, handlerState) {
+    if (!passWord && !globalConfig?.simulatedPassword) {
+      message.warning('请输入密码');
+      return;
+    }
+    if (isOpenRunning) {
+      return;
+    }
+    const data = {
+      deviceid: selectData.deviceID,
+      devicetype: selectData.deviceType,
+      paramcode: '',
+      value: contrlValue,
+      password: passWord || globalConfig?.simulatedPassword,
+      masterComputer: selectData.masterComputer,
+    };
+    switch (handlerState) {
+      case '1': // 打开前门
+        if (selectData.doorOpen == '0' && selectData.doorClose == '1') {
+          data.paramcode = 'frontGateOpen_S';
+        }
+        break;
+      case '2': // 关闭前门
+        if (selectData.doorOpen == '1' && selectData.doorClose == '0') {
+          data.paramcode = 'frontGateClose_S';
+        }
+        break;
+      case '7': // 远程与就地
+        data.paramcode = 'autoRoManualControl';
+        data.value = selectData.contrlMod != 'loopCtrl' ? contrlValue : '';
+        selectData.autoRoManual = null;
+    }
+
+    if (data.paramcode) {
+      deviceControlApi(data).then((res) => {
+        // 模拟时开启
+        if (res.success) {
+          modalIsShow.value = false;
+          if (globalConfig.History_Type == 'remote') {
+            message.success('指令已下发至生产管控平台成功!');
+          } else {
+            message.success('指令已下发成功!');
+          }
         } else {
-          message.success('指令已下发成功!');
+          message.error(res.message);
         }
-      } else {
-        message.error(res.message);
-      }
-    });
-  }
-}
-let isOpenRunning = false; //开关门动作是否在进行
-/** 开关门动画调用 */
-let isdoorOpenRunning = false; //开关门动作是否在进行
-// let isMidCloseRunning = false; //中间门动作是否在进行
-// 0 关闭 1 正在打开 2 打开 3正在关闭
-let doorDeviceState = 1; //记录设备状态,为了与下一次监测数据做比较
-function monitorAnimation(selectData) {
-  const timeScale = 0.005;
-  // 打开
-  if (selectData.frontGateOpen == '1' && !isdoorOpenRunning) {
-    isdoorOpenRunning = true;
-    if (doorDeviceState != 1) {
-      doorDeviceState = 1;
-      doorIsOpen.value = true;
+      });
     }
   }
-  // 关闭
-  if (selectData.frontGateOpen == '0' && isdoorOpenRunning) {
-    isdoorOpenRunning = false;
-    if (doorDeviceState != 0) {
-      doorDeviceState = 0;
-      doorIsOpen.value = false;
+  let isOpenRunning = false; //开关门动作是否在进行
+  /** 开关门动画调用 */
+  let isdoorOpenRunning = false; //开关门动作是否在进行
+  // let isMidCloseRunning = false; //中间门动作是否在进行
+  // 0 关闭 1 正在打开 2 打开 3正在关闭
+  let doorDeviceState = 1; //记录设备状态,为了与下一次监测数据做比较
+  function monitorAnimation(selectData) {
+    const timeScale = 0.005;
+    // 打开
+    if (selectData.frontGateOpen == '1' && !isdoorOpenRunning) {
+      isdoorOpenRunning = true;
+      if (doorDeviceState != 1) {
+        doorDeviceState = 1;
+        doorIsOpen.value = true;
+      }
+    }
+    // 关闭
+    if (selectData.frontGateOpen == '0' && isdoorOpenRunning) {
+      isdoorOpenRunning = false;
+      if (doorDeviceState != 0) {
+        doorDeviceState = 0;
+        doorIsOpen.value = false;
+      }
     }
   }
-}
 
-function handleCancel() {
-  modalIsShow.value = false;
-  modalTitle.value = '';
-  modalType.value = '';
-  selectData.autoRoManual = null;
-}
+  function handleCancel() {
+    modalIsShow.value = false;
+    modalTitle.value = '';
+    modalType.value = '';
+    selectData.autoRoManual = null;
+  }
 
-onMounted(async () => {
-  const { query } = unref(currentRoute);
-  if (query['deviceType']) deviceType.value = query['deviceType'] as string;
-  modelList.value = await getDictItems('fireDoorModel');
-});
+  onMounted(async () => {
+    const { query } = unref(currentRoute);
+    if (query['deviceType']) deviceType.value = query['deviceType'] as string;
+    modelList.value = await getDictItems('fireDoorModel');
+  });
 
-onBeforeUnmount(() => {
-  getDeviceBaseList();
-});
+  onBeforeUnmount(() => {
+    getDeviceBaseList();
+  });
 
-onUnmounted(() => {
-  removeCamera();
-  if (timer) {
-    clearTimeout(timer);
-    timer = undefined;
-  }
-});
+  onUnmounted(() => {
+    removeCamera();
+    if (timer) {
+      clearTimeout(timer);
+      timer = undefined;
+    }
+  });
 </script>
 ,
 <style lang="less" scoped>
-@import '/@/design/vent/modal.less';
-.scene-box {
-  .bottom-tabs-box {
-    height: 300px;
+  @import '/@/design/vent/modal.less';
+  .scene-box {
+    .bottom-tabs-box {
+      height: 300px;
+    }
   }
-}
-.button-box {
-  border: none !important;
-  height: 34px !important;
+  .button-box {
+    border: none !important;
+    height: 34px !important;
 
-  &:hover {
-    background: linear-gradient(#2cd1ff55, #1eb0ff55) !important;
-  }
+    &:hover {
+      background: linear-gradient(#2cd1ff55, #1eb0ff55) !important;
+    }
 
-  &::before {
-    height: 27px !important;
-    background: linear-gradient(#1fa6cb, #127cb5) !important;
-  }
+    &::before {
+      height: 27px !important;
+      background: linear-gradient(#1fa6cb, #127cb5) !important;
+    }
 
-  &::after {
-    top: 35px !important;
+    &::after {
+      top: 35px !important;
+    }
   }
-}
 
-:deep(.@{ventSpace}-tabs-tabpane-active) {
-  height: 100%;
-}
+  :deep(.@{ventSpace}-tabs-tabpane-active) {
+    height: 100%;
+  }
 
-::-webkit-scrollbar-thumb {
-  -webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
-  background: #4288a444;
-}
-:deep(.zxm-radio-disabled + span) {
-  color: #fff !important;
-}
-:deep(.zxm-radio-disabled .zxm-radio-inner::after) {
-  background-color: #127cb5 !important;
-}
+  ::-webkit-scrollbar-thumb {
+    -webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
+    background: #4288a444;
+  }
+  :deep(.zxm-radio-disabled + span) {
+    color: #fff !important;
+  }
+  :deep(.zxm-radio-disabled .zxm-radio-inner::after) {
+    background-color: #127cb5 !important;
+  }
 </style>

+ 38 - 31
src/views/vent/monitorManager/deviceMonitor/components/device/index.vue

@@ -20,7 +20,7 @@
       </div>
     </div>
     <!-- 瓦斯巡检弹窗信息 -->
-    <div v-if="deviceType.startsWith('gasDay_normal') && activeKey == '1'" class="inspect-info-xj">
+    <div v-if="deviceType.startsWith('gasDay_normal') && activeKey == 'monitor'" class="inspect-info-xj">
       <gasInspectDialog :gasSearch="gasSearch"></gasInspectDialog>
     </div>
     <div
@@ -140,7 +140,7 @@
         </div>
         <!-- 是人员定位表单代码,由于放在tab中,表格对已知刷新,导致表单数据也在刷寻,造成输入一半的中文时会清空输入框的内容,导致的输入不上数据 -->
         <div
-          v-if="(deviceType.startsWith('location') || deviceType.startsWith('vehicle')) && activeKey == '1'"
+          v-if="(deviceType.startsWith('location') || deviceType.startsWith('vehicle')) && activeKey == 'monitor'"
           class="location-form"
           style="position: absolute; z-index: 9999; top: 50px"
         >
@@ -166,7 +166,7 @@
         </div>
         <a-tabs class="tabs-box" v-model:activeKey="activeKey" @change="tabChange" id="tabsBox">
           <a-tab-pane
-            key="1"
+            key="monitor"
             :tab="
               deviceType.startsWith('gasDay_normal')
                 ? '当日巡检监测'
@@ -178,7 +178,7 @@
                 : '实时监测'
             "
           >
-            <template v-if="(deviceType.startsWith('fanlocal') || deviceType.startsWith('fanmain')) && activeKey == '1'">
+            <template v-if="(deviceType.startsWith('fanlocal') || deviceType.startsWith('fanmain')) && activeKey == 'monitor'">
               <GroupMonitorTable
                 ref="MonitorDataTable"
                 :dataSource="dataSource"
@@ -212,10 +212,10 @@
                 </template>
               </GroupMonitorTable>
             </template>
-            <template v-else-if="deviceType == 'majorpath' && activeKey == '1'">
+            <template v-else-if="deviceType == 'majorpath' && activeKey == 'monitor'">
               <a-table :columns="majorColumns" :data-source="dataSource" bordered :scroll="{ y: scroll.y - 30 }" :pagination="false"></a-table>
             </template>
-            <template v-else-if="deviceType.startsWith('safetymonitor') && activeKey == '1'">
+            <template v-else-if="deviceType.startsWith('safetymonitor') && activeKey == 'monitor'">
               <MonitorTable
                 ref="monitorTable"
                 :columnsType="`${deviceType}_monitor`"
@@ -264,7 +264,7 @@
                 </template>
               </MonitorTable>
             </template>
-            <template v-else-if="deviceType.startsWith('location') && activeKey == '1'">
+            <template v-else-if="deviceType.startsWith('location') && activeKey == 'monitor'">
               <MonitorTable
                 ref="monitorTable"
                 :columnsType="`${deviceType}_monitor`"
@@ -289,7 +289,7 @@
                 </template>
               </MonitorTable>
             </template>
-            <template v-else-if="deviceType.startsWith('vehicle') && activeKey == '1'">
+            <template v-else-if="deviceType.startsWith('vehicle') && activeKey == 'monitor'">
               <MonitorTable
                 ref="monitorTable"
                 :columnsType="`${deviceType}_monitor`"
@@ -314,7 +314,7 @@
                 </template>
               </MonitorTable>
             </template>
-            <!-- <template v-else-if="deviceType.startsWith('gasmonitor') && activeKey == '1'">
+            <!-- <template v-else-if="deviceType.startsWith('gasmonitor') && activeKey == 'monitor'">
               <MonitorTable
                 ref="monitorTable"
                 :columnsType="`${deviceType}_monitor`"
@@ -356,41 +356,41 @@
               </MonitorTable>
             </template> -->
             <!-- 瓦斯人工巡检 -->
-            <template v-else-if="deviceType.startsWith('gasDay_normal') && activeKey == '1'">
+            <template v-else-if="deviceType.startsWith('gasDay_normal') && activeKey == 'monitor'">
               <gaspatrolTable ref="gaspatrol" @getSearch="getSearch" @locate="goLocation"> </gaspatrolTable>
             </template>
             <!-- 瓦斯日报 -->
-            <template v-else-if="deviceType.startsWith('gasDayReport') && activeKey == '1' && glob.sysOrgCode != 'sdmtjtbetmk'">
+            <template v-else-if="deviceType.startsWith('gasDayReport') && activeKey == 'monitor' && glob.sysOrgCode != 'sdmtjtbetmk'">
               <gasReport ref="gasreport" @locate="goLocation"> </gasReport>
             </template>
-            <template v-else-if="deviceType.startsWith('gasDayReport') && activeKey == '1' && glob.sysOrgCode == 'sdmtjtbetmk'">
+            <template v-else-if="deviceType.startsWith('gasDayReport') && activeKey == 'monitor' && glob.sysOrgCode == 'sdmtjtbetmk'">
               <gasReportCount ref="gasreportcount" @locate="goLocation"> </gasReportCount>
             </template>
             <!-- 粉尘监测报表-->
-            <template v-else-if="deviceType.startsWith('dustDayReport') && activeKey == '1'">
+            <template v-else-if="deviceType.startsWith('dustDayReport') && activeKey == 'monitor'">
               <dustMonitorTable @locate="goLocation" :isShowAction="true"></dustMonitorTable>
             </template>
-            <template v-else-if="deviceType.startsWith('bundleDayReport') && activeKey == '1'">
+            <template v-else-if="deviceType.startsWith('bundleDayReport') && activeKey == 'monitor'">
               <bundleMonitorTable @locate="goLocation" :isShowAction="true"></bundleMonitorTable>
             </template>
-            <template v-else-if="deviceType.startsWith('bundleSpyDayReport') && activeKey == '1'">
+            <template v-else-if="deviceType.startsWith('bundleSpyDayReport') && activeKey == 'monitor'">
               <bundleSpyMonitorTable @locate="goLocation" :isShowAction="true"></bundleSpyMonitorTable>
             </template>
-            <template v-else-if="deviceType.startsWith('dusting') && activeKey == '1'">
+            <template v-else-if="deviceType.startsWith('dusting') && activeKey == 'monitor'">
               <DustingTable :dataSource="dataSource" :deviceType="deviceType" :scroll="scroll" @locate="goLocation" />
             </template>
             <!-- 设备分站 -->
-            <template v-else-if="deviceType.startsWith('substation_normal') && activeKey == '1'">
+            <template v-else-if="deviceType.startsWith('substation_normal') && activeKey == 'monitor'">
               <stationTable ref="station" @locate="goLocation" @stationDetail="stationDetail"> </stationTable>
             </template>
             <!-- 瓦斯管网 -->
-            <template v-else-if="deviceType.startsWith('gaspipe') && activeKey == '1'">
+            <template v-else-if="deviceType.startsWith('gaspipe') && activeKey == 'monitor'">
               <GasPipeTable :showDetailButton="true" :scroll="scroll" @detail="goDetail($event)" @locate="goLocation" />
             </template>
             <template v-else>
               <!-- 工作面echarts图标 -->
               <BarAndLine
-                v-if="activeKey == '1' && deviceType == 'surface_history'"
+                v-if="activeKey == 'monitor' && deviceType == 'surface_history'"
                 class="echarts-line"
                 xAxisPropType="time"
                 :dataSource="surfaceEchartsData"
@@ -399,7 +399,7 @@
                 :option="echatsOption"
               />
               <MonitorTable
-                v-else-if="activeKey == '1'"
+                v-else-if="activeKey == 'monitor'"
                 ref="monitorTable"
                 :columnsType="`${deviceType}_monitor`"
                 :dataSource="dataSource"
@@ -541,8 +541,8 @@
               </MonitorTable>
             </template>
           </a-tab-pane>
-          <a-tab-pane key="2" tab="历史数据" v-if="!noHistoryArr().find((item) => deviceType.startsWith(item))">
-            <div class="tab-item" v-if="activeKey == '2'">
+          <a-tab-pane key="history" tab="历史数据" v-if="!noHistoryArr().find((item) => deviceType.startsWith(item))">
+            <div class="tab-item" v-if="activeKey == 'history'">
               <template v-if="deviceType.startsWith('firemon_normal')">
                 <HistoryBall :dataSource="dataSource"></HistoryBall>
               </template>
@@ -588,11 +588,15 @@
               />
             </div>
           </a-tab-pane>
-          <a-tab-pane key="3" tab="报警历史" v-if="!noWarningArr.find((item) => deviceType.startsWith(item)) || !hasPermission('safety:hideWarning')">
+          <a-tab-pane
+            key="alarm"
+            tab="报警历史"
+            v-if="!noWarningArr.find((item) => deviceType.startsWith(item)) || !hasPermission('safety:hideWarning')"
+          >
             <div class="tab-item">
               <AlarmHistoryTable
                 ref="alarmHistoryTable"
-                v-if="activeKey == '3'"
+                v-if="activeKey == 'alarm'"
                 :sysId="systemID"
                 columns-type="alarm"
                 :device-type="deviceType"
@@ -654,7 +658,7 @@
   import { TableAction } from '/@/components/Table';
   import { SvgIcon } from '/@/components/Icon';
   import { getActions } from '/@/qiankun/state';
-  import { useRouter } from 'vue-router';
+  import { useRouter, useRoute } from 'vue-router';
   import { setDivHeight } from '/@/utils/event';
   import { render } from '/@/utils/common/renderUtils';
   import {
@@ -680,7 +684,7 @@
   import { useMethods } from '/@/hooks/system/useMethods';
   import { useGo } from '/@/hooks/web/usePage';
   import { useGlobSetting } from '/@/hooks/setting';
-   import { usePermission } from '/@/hooks/web/usePermission';
+  import { usePermission } from '/@/hooks/web/usePermission';
 
   type DeviceType = { deviceType: string; deviceName: string; datalist: any[] };
   const glob = useGlobSetting();
@@ -695,7 +699,7 @@
     },
   });
 
-   const { hasPermission } = usePermission();
+  const { hasPermission } = usePermission();
   const { handleExportXls } = useMethods();
   const go = useGo();
   const echatsOption = {
@@ -711,6 +715,7 @@
     },
   };
   const router = useRouter();
+  const route = useRoute();
   const actions = getActions();
   const locationForm = reactive({
     strname: '',
@@ -738,7 +743,7 @@
   const locationList = ref([]); //巷道定位图标显示列表
   const deviceList = ref<DeviceType[]>([]); //关联设备列表
   const deviceActive = ref('');
-  const activeKey = ref('1'); // tab key
+  const activeKey = ref('monitor'); // tab key
   const dataSource = shallowRef([]); // 实时监测数据
   const majorPathEchartsData = ref({}); // 关键路线echarts数据
   const surfaceEchartsData = ref<any[]>(); // 工作面历史记录,echarts数据
@@ -804,6 +809,7 @@
 
   function tabChange(activeKeyVal) {
     activeKey.value = activeKeyVal;
+    router.push({ path: route.path, query: { ...route.query, tabtype: activeKey.value } });
   }
 
   function showTree(flag, value) {
@@ -1294,14 +1300,14 @@
     dataSource.value = [];
     deviceActive.value = deviceList.value[index].deviceType;
     if (deviceType.value != deviceActive.value) deviceType.value = deviceActive.value;
-    if (activeKey.value == '1' && monitorTable.value) {
+    if (activeKey.value == 'monitor' && monitorTable.value) {
       monitorTable.value.setLoading(true);
       dataSource.value = deviceList.value[index].datalist;
     }
-    if (activeKey.value == '2' && historyTable.value) {
+    if (activeKey.value == 'history' && historyTable.value) {
       historyTable.value.setLoading(true);
     }
-    if (activeKey.value == '3' && alarmHistoryTable.value) {
+    if (activeKey.value == 'alarm' && alarmHistoryTable.value) {
       alarmHistoryTable.value.setLoading(true);
     }
     if (activeKey.value == '4' && handlerHistoryTable.value) {
@@ -1366,6 +1372,7 @@
       locationList.value = await devPosition({});
     }
 
+    router.push({ path: route.path, query: { ...route.query, tabtype: activeKey.value } });
     // safetyOption.value = await safetyDeviceList(null, { devicetype: 'safetymonitor', code: 'dataTypeName' })
   });
 

File diff ditekan karena terlalu besar
+ 504 - 552
src/views/vent/monitorManager/fanLocalMonitor1/index.vue


+ 5 - 5
src/views/vent/monitorManager/gateMonitor/components/gateDualSVG.vue

@@ -6,9 +6,9 @@
     preserveAspectRatio="none"
     x="0px"
     y="0px"
-    width="1536px"
-    height="100%"
-    style="margin-left: calc(50% - 768px)"
+    width="1980px"
+    height="1080"
+    style="position: relative; left: -30px; top: -180px"
     viewBox="0 0 1920 1080"
   >
     <defs>
@@ -1255,12 +1255,12 @@
           <use xlink:href="#KongZhiGui1_0_Layer0_0_1_STROKES" />
         </g>
       </g>
-      <g transform="matrix( 1, 0, 0, 1, 613.65,31.8) ">
+      <!-- <g transform="matrix( 1, 0, 0, 1, 613.65,31.8) ">
         <g transform="matrix( 1, 0, 0, 1, 0,0) ">
           <use xlink:href="#Led_0_Layer0_0_FILL" />
           <use xlink:href="#Led_0_Layer0_0_1_STROKES" />
         </g>
-      </g>
+      </g> -->
       <g transform="matrix( 1, 0, 0, 1, -123.35,-61.2) ">
         <g transform="matrix( 1, 0, 0, 1, 0,0) ">
           <use xlink:href="#KongZhiGui1_0_Layer0_0_FILL" />

+ 3 - 3
src/views/vent/monitorManager/gateMonitor/components/gateSVG.vue

@@ -6,9 +6,9 @@
     preserveAspectRatio="none"
     x="0px"
     y="0px"
-    width="1536px"
-    height="100%"
-    style="margin-left: calc(50% - 768px)"
+    width="1980px"
+    height="1080"
+    style="position: relative; left: -20px; top: -150px"
     viewBox="0 0 1920 1080"
   >
     <defs>

+ 4 - 4
src/views/vent/monitorManager/gateMonitor/components/gateTripleSVG.vue

@@ -6,9 +6,9 @@
     preserveAspectRatio="none"
     x="0px"
     y="0px"
-    width="1536px"
-    height="100%"
-    style="margin-left: calc(50% - 768px)"
+    width="1980px"
+    height="1080"
+    style="position: relative; left: -20px; top: -150px"
     viewBox="0 0 1920 1080"
   >
     <defs>
@@ -1378,7 +1378,7 @@
           <use xlink:href="#KongZhiGui1_0_Layer0_0_1_STROKES" />
         </g>
       </g>
-      <g transform="matrix( 1, 0, 0, 1, 613.65,31.8) ">
+      <g transform="matrix( 1, 0, 0, 1, 613.65,31.8) " style="display: none">
         <g transform="matrix( 1, 0, 0, 1, 0,0) ">
           <use xlink:href="#Led_0_Layer0_0_FILL" />
           <use xlink:href="#Led_0_Layer0_0_1_STROKES" />

+ 2 - 1
src/views/vent/monitorManager/gateMonitor/gate.data.ts

@@ -326,7 +326,8 @@ export function getModelComponent(is2DModel: boolean = false, sysOrgCode?: strin
       //   双道风门
       //   return import('./components/gateDualSVG.vue');
       default:
-        return import('./components/gateTripleSVG.vue');
+        // return import('./components/gateTripleSVG.vue');
+        return import('./components/gateDualSVG.vue');
     }
   });
 }

+ 282 - 138
src/views/vent/monitorManager/safetyMonitor/HistoryTable.vue

@@ -238,165 +238,309 @@
   }
 
   // 列表页面公共参数、方法
-  const { tableContext, onExportXls } = useListPage({
-    tableProps: {
-      // api: list,
-      columns: props.columnsType ? columns : (props.columns as any[]),
-      canResize: true,
-      showTableSetting: false,
-      showActionColumn: false,
-      bordered: false,
-      size: 'small',
-      scroll: tableScroll,
-      showIndexColumn: true,
-      tableLayout: 'auto',
-      formConfig: {
-        labelAlign: 'left',
-        showAdvancedButton: false,
-        showSubmitButton: false,
-        showResetButton: false,
-        baseColProps: {
-          xs: 24,
-          sm: 24,
-          md: 24,
-          lg: 9,
-          xl: 7,
-          xxl: 4,
-        },
-        schemas: [
-          {
-            field: 'ttime_begin',
-            label: '开始时间',
-            component: 'DatePicker',
-            defaultValue: dayjs().startOf('date'),
-            required: true,
-            componentProps: {
-              showTime: true,
-              valueFormat: 'YYYY-MM-DD HH:mm:ss',
-              getPopupContainer: getAutoScrollContainer,
-            },
-            colProps: {
-              span: 4,
-            },
-          },
-          {
-            field: 'ttime_end',
-            label: '结束时间',
-            component: 'DatePicker',
-            defaultValue: dayjs(),
-            required: true,
-            componentProps: {
-              showTime: true,
-              valueFormat: 'YYYY-MM-DD HH:mm:ss',
-              getPopupContainer: getAutoScrollContainer,
-            },
-            colProps: {
-              span: 4,
-            },
-          },
-          {
-            label: '设备类型',
-            field: 'dataTypeName',
-            component: 'ApiSelect',
-            componentProps: {
-              api: safetyDeviceList.bind(null, { devicetype: 'safetymonitor', code: 'dataTypeName' }),
-              labelField: 'name',
-              valueField: 'code',
-              onChange: async (e, option) => {
-                console.log('1111', e, option);
-                dataTypeName.value = e;
-                await getDeviceList();
+  const { tableContext, onExportXls } = useListPage(
+    props.columnsType == 'safetymonitor'
+      ? {
+          tableProps: {
+            // api: list,
+            columns: props.columnsType ? columns : (props.columns as any[]),
+            canResize: true,
+            showTableSetting: false,
+            showActionColumn: false,
+            bordered: false,
+            size: 'small',
+            scroll: tableScroll,
+            showIndexColumn: true,
+            tableLayout: 'auto',
+            formConfig: {
+              labelAlign: 'left',
+              showAdvancedButton: false,
+              showSubmitButton: false,
+              showResetButton: false,
+              baseColProps: {
+                xs: 24,
+                sm: 24,
+                md: 24,
+                lg: 9,
+                xl: 7,
+                xxl: 4,
               },
-            },
-            colProps: {
-              span: 4,
-            },
-          },
-          {
-            label: '查询设备',
-            field: 'gdeviceid',
-            component: 'Select',
-            defaultValue: deviceOptions.value[0] ? deviceOptions.value[0]['value'] : '',
-            required: true,
-            componentProps: {
-              showSearch: true,
-              filterOption: (input: string, option: any) => {
-                return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0;
-              },
-              options: deviceOptions,
-              onChange: (e, option) => {
-                if (option && (option['strinstallpos'] || option['strtype'] || option['devicekind']))
-                  historyType.value = option['strtype'] || option['devicekind'];
-                if (option['strtype']) deviceTypeStr.value = option['strtype'];
-                stationType.value = option['stationtype'];
-                nextTick(async () => {
-                  await getDataSource();
-                });
-              },
-            },
-            colProps: {
-              span: 4,
-            },
-          },
-          {
-            label: '间隔时间',
-            field: 'skip',
-            component: 'Select',
-            defaultValue: '8',
-            componentProps: {
-              options: [
+              schemas: [
                 {
-                  label: '1秒',
-                  value: '1',
+                  field: 'ttime_begin',
+                  label: '开始时间',
+                  component: 'DatePicker',
+                  defaultValue: dayjs().startOf('date'),
+                  required: true,
+                  componentProps: {
+                    showTime: true,
+                    valueFormat: 'YYYY-MM-DD HH:mm:ss',
+                    getPopupContainer: getAutoScrollContainer,
+                  },
+                  colProps: {
+                    span: 4,
+                  },
                 },
                 {
-                  label: '5秒',
-                  value: '2',
+                  field: 'ttime_end',
+                  label: '结束时间',
+                  component: 'DatePicker',
+                  defaultValue: dayjs(),
+                  required: true,
+                  componentProps: {
+                    showTime: true,
+                    valueFormat: 'YYYY-MM-DD HH:mm:ss',
+                    getPopupContainer: getAutoScrollContainer,
+                  },
+                  colProps: {
+                    span: 4,
+                  },
                 },
                 {
-                  label: '10秒',
-                  value: '3',
+                  label: '设备类型',
+                  field: 'dataTypeName',
+                  component: 'ApiSelect',
+                  componentProps: {
+                    api: safetyDeviceList.bind(null, { devicetype: 'safetymonitor', code: 'dataTypeName' }),
+                    labelField: 'name',
+                    valueField: 'code',
+                    onChange: async (e, option) => {
+                      console.log('1111', e, option);
+                      dataTypeName.value = e;
+                      await getDeviceList();
+                    },
+                  },
+                  colProps: {
+                    span: 4,
+                  },
                 },
                 {
-                  label: '30秒',
-                  value: '4',
+                  label: '查询设备',
+                  field: 'gdeviceid',
+                  component: 'Select',
+                  defaultValue: deviceOptions.value[0] ? deviceOptions.value[0]['value'] : '',
+                  required: true,
+                  componentProps: {
+                    showSearch: true,
+                    filterOption: (input: string, option: any) => {
+                      return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0;
+                    },
+                    options: deviceOptions,
+                    onChange: (e, option) => {
+                      if (option && (option['strinstallpos'] || option['strtype'] || option['devicekind']))
+                        historyType.value = option['strtype'] || option['devicekind'];
+                      if (option['strtype']) deviceTypeStr.value = option['strtype'];
+                      stationType.value = option['stationtype'];
+                      nextTick(async () => {
+                        await getDataSource();
+                      });
+                    },
+                  },
+                  colProps: {
+                    span: 4,
+                  },
                 },
                 {
-                  label: '1分钟',
-                  value: '5',
+                  label: '间隔时间',
+                  field: 'skip',
+                  component: 'Select',
+                  defaultValue: '8',
+                  componentProps: {
+                    options: [
+                      {
+                        label: '1秒',
+                        value: '1',
+                      },
+                      {
+                        label: '5秒',
+                        value: '2',
+                      },
+                      {
+                        label: '10秒',
+                        value: '3',
+                      },
+                      {
+                        label: '30秒',
+                        value: '4',
+                      },
+                      {
+                        label: '1分钟',
+                        value: '5',
+                      },
+                      {
+                        label: '10分钟',
+                        value: '6',
+                      },
+                      {
+                        label: '30分钟',
+                        value: '7',
+                      },
+                      {
+                        label: '1小时',
+                        value: '8',
+                      },
+                    ],
+                  },
+                  colProps: {
+                    span: 4,
+                  },
+                },
+              ],
+            },
+            pagination: {
+              current: 1,
+              pageSize: 10,
+              pageSizeOptions: ['10', '30', '50', '100'],
+              showQuickJumper: false,
+            },
+          },
+          exportConfig: {
+            name: '历史列表',
+            url: getExportXlsUrl(),
+          },
+        }
+      : {
+          tableProps: {
+            // api: list,
+            columns: props.columnsType ? columns : (props.columns as any[]),
+            canResize: true,
+            showTableSetting: false,
+            showActionColumn: false,
+            bordered: false,
+            size: 'small',
+            scroll: tableScroll,
+            showIndexColumn: true,
+            tableLayout: 'auto',
+            formConfig: {
+              labelAlign: 'left',
+              showAdvancedButton: false,
+              showSubmitButton: false,
+              showResetButton: false,
+              baseColProps: {
+                xs: 24,
+                sm: 24,
+                md: 24,
+                lg: 9,
+                xl: 7,
+                xxl: 4,
+              },
+              schemas: [
+                {
+                  field: 'ttime_begin',
+                  label: '开始时间',
+                  component: 'DatePicker',
+                  defaultValue: dayjs().startOf('date'),
+                  required: true,
+                  componentProps: {
+                    showTime: true,
+                    valueFormat: 'YYYY-MM-DD HH:mm:ss',
+                    getPopupContainer: getAutoScrollContainer,
+                  },
+                  colProps: {
+                    span: 4,
+                  },
                 },
                 {
-                  label: '10分钟',
-                  value: '6',
+                  field: 'ttime_end',
+                  label: '结束时间',
+                  component: 'DatePicker',
+                  defaultValue: dayjs(),
+                  required: true,
+                  componentProps: {
+                    showTime: true,
+                    valueFormat: 'YYYY-MM-DD HH:mm:ss',
+                    getPopupContainer: getAutoScrollContainer,
+                  },
+                  colProps: {
+                    span: 4,
+                  },
                 },
                 {
-                  label: '30分钟',
-                  value: '7',
+                  label: '查询设备',
+                  field: 'gdeviceid',
+                  component: 'Select',
+                  defaultValue: deviceOptions.value[0] ? deviceOptions.value[0]['value'] : '',
+                  required: true,
+                  componentProps: {
+                    showSearch: true,
+                    filterOption: (input: string, option: any) => {
+                      return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0;
+                    },
+                    options: deviceOptions,
+                    onChange: (e, option) => {
+                      if (option && (option['strinstallpos'] || option['strtype'] || option['devicekind']))
+                        historyType.value = option['strtype'] || option['devicekind'];
+                      if (option['strtype']) deviceTypeStr.value = option['strtype'];
+                      stationType.value = option['stationtype'];
+                      nextTick(async () => {
+                        await getDataSource();
+                      });
+                    },
+                  },
+                  colProps: {
+                    span: 4,
+                  },
                 },
                 {
-                  label: '1小时',
-                  value: '8',
+                  label: '间隔时间',
+                  field: 'skip',
+                  component: 'Select',
+                  defaultValue: '8',
+                  componentProps: {
+                    options: [
+                      {
+                        label: '1秒',
+                        value: '1',
+                      },
+                      {
+                        label: '5秒',
+                        value: '2',
+                      },
+                      {
+                        label: '10秒',
+                        value: '3',
+                      },
+                      {
+                        label: '30秒',
+                        value: '4',
+                      },
+                      {
+                        label: '1分钟',
+                        value: '5',
+                      },
+                      {
+                        label: '10分钟',
+                        value: '6',
+                      },
+                      {
+                        label: '30分钟',
+                        value: '7',
+                      },
+                      {
+                        label: '1小时',
+                        value: '8',
+                      },
+                    ],
+                  },
+                  colProps: {
+                    span: 4,
+                  },
                 },
               ],
             },
-            colProps: {
-              span: 4,
+            pagination: {
+              current: 1,
+              pageSize: 10,
+              pageSizeOptions: ['10', '30', '50', '100'],
+              showQuickJumper: false,
             },
           },
-        ],
-      },
-      pagination: {
-        current: 1,
-        pageSize: 10,
-        pageSizeOptions: ['10', '30', '50', '100'],
-        showQuickJumper: false,
-      },
-    },
-    exportConfig: {
-      name: '历史列表',
-      url: getExportXlsUrl(),
-    },
-  });
+          exportConfig: {
+            name: '历史列表',
+            url: getExportXlsUrl(),
+          },
+        }
+  );
 
   //注册table数据
   const [registerTable, { reload, setLoading, getForm, setColumns, getPaginationRef, setPagination }] = tableContext;

+ 34 - 26
src/views/vent/monitorManager/safetyMonitor/index.vue

@@ -13,7 +13,7 @@
               :dataSource="dataSource"
               design-scope="device_monitor"
               :isShowPagination="false"
-              :isShowActionColumn="isHaveNoAction.includes(deviceType.split('_')[0]) ? false : true"
+              :isShowActionColumn="false"
               :is-show-select="false"
               :form-config="deviceType == 'safetymonitor' && sysOrgCode != 'zjtzqctmk' ? formConfig : undefined"
               title="设备监测"
@@ -49,10 +49,10 @@
               :dataSource="dataSource"
               design-scope="device_monitor"
               :isShowPagination="false"
-              :isShowActionColumn="isHaveNoAction.includes(deviceType.split('_')[0]) ? false : true"
+              :isShowActionColumn="false"
               :is-show-select="false"
-              title="设备监测"
               :form-config="deviceType == 'safetymonitor' && sysOrgCode != 'zjtzqctmk' ? formConfig : undefined"
+              title="设备监测"
               :scroll="{ y: 650 }"
               :defSort="defSort"
               sortDataIndex="strinstallpos"
@@ -138,28 +138,35 @@
             :chartsColumns="chartsColumnsreal" chartsType="" :option="echartsOption" />
         </div> -->
       </a-tab-pane>
+      <template v-if="!hasPermission('safety:hideWarning')">
+        <a-tab-pane key="3" tab="报警历史">
+          <div class="tab-item">
+            <AlarmHistoryTable
+              ref="alarmHistoryTable"
+              v-if="activeKey == '3' && deviceType == 'safetymonitor'"
+              columns-type="alarm"
+              :list="safetyList"
+              :device-type="deviceType"
+              :device-list-api="getDeviceList.bind(null, { devicekind: deviceType, pageSize: 10000 })"
+              designScope="alarm-history"
+            />
+          </div>
+        </a-tab-pane>
+      </template>
+      <template v-else>
+        <a-tab-pane key="3" tab="报警历史">
+          <div class="tab-item">
+            <AlarmHistoryCommentTable
+              v-if="activeKey == '3' && deviceType != 'safetymonitor'"
+              columns-type="alarm"
+              :device-type="deviceType"
+              :device-list-api="getDeviceList.bind(null, { devicekind: deviceType, pageSize: 10000 })"
+              designScope="alarm-history"
+            />
+          </div>
+        </a-tab-pane>
+      </template>
 
-      <a-tab-pane key="3" tab="报警历史" v-if="!hasPermission('safety:hideWarning')">
-        <div class="tab-item">
-          <AlarmHistoryTable
-            ref="alarmHistoryTable"
-            v-if="activeKey == '3'"
-            columns-type="alarm"
-            :list="safetyList"
-            :device-type="deviceType"
-            :device-list-api="getDeviceList.bind(null, { devicekind: deviceType, pageSize: 10000 })"
-            designScope="alarm-history"
-          />
-          <!-- <AlarmHistoryCommentTable
-            ref="alarmHistoryTable"
-            v-else-if="activeKey == '3'"
-            columns-type="alarm"
-            :device-type="deviceType"
-            :device-list-api="getDeviceList.bind(null, { devicekind: deviceType, pageSize: 10000 })"
-            designScope="alarm-history"
-          /> -->
-        </div>
-      </a-tab-pane>
       <a-tab-pane key="4" tab="操作历史" v-if="deviceType !== 'safetymonitor' && deviceType !== 'wasichoufang'">
         <div class="tab-item">
           <HandlerHistoryTable
@@ -172,7 +179,7 @@
           />
         </div>
       </a-tab-pane>
-      <a-tab-pane key="5" tab="报警分析" v-if="!hasPermission('safety:hideWarning')">
+      <a-tab-pane key="5" tab="报警分析" v-if="!hasPermission('safety:hideWarning') && deviceType == 'safetymonitor'">
         <div class="tab-item">
           <safetyWarnAnalysis :device-type="deviceType" />
         </div>
@@ -202,7 +209,7 @@
 <script setup lang="ts">
   import { ref, onMounted, onUnmounted, shallowRef, defineProps, watch, inject, unref } from 'vue';
   import { list, getDeviceList, safetyList, getExportUrl, subStationList, initSubStation } from './safety.api';
-  // import AlarmHistoryCommentTable from '../comment/AlarmHistoryTable.vue';
+  import AlarmHistoryCommentTable from '../comment/AlarmHistoryTable.vue';
   import safetyWarnAnalysis from '../comment/safetyWarnAnalysis.vue';
   import AlarmHistoryTable from './AlarmHistoryTable.vue';
   import HistoryTable from './HistoryTable.vue';
@@ -217,6 +224,7 @@
   import { useMethods } from '/@/hooks/system/useMethods';
   import { message } from 'ant-design-vue';
   import { SendOutlined } from '@ant-design/icons-vue';
+  import { template } from 'lodash-es';
 
   const { sysOrgCode } = useGlobSetting();
   const { hasPermission } = usePermission();

+ 1 - 1
src/views/vent/monitorManager/safetyMonitor/safety.data.ts

@@ -223,4 +223,4 @@ export const chartsColumnsreal = [
     dataIndex: 'sourcePressure',
   },
 ];
-export const isHaveNoAction = ['safetymonitor', 'wasichoufang', 'atomizing'];
+export const isHaveNoAction = ['safetymonitor', 'wasichoufang', 'atomizing', ''];

+ 5 - 5
src/views/vent/monitorManager/windowMonitor/components/windowDualSVG.vue

@@ -6,9 +6,9 @@
     preserveAspectRatio="none"
     x="0px"
     y="0px"
-    width="1536px"
-    height="100%"
-    style="margin-left: calc(50% - 768px)"
+    width="1980px"
+    height="1080"
+    style="position: relative; left: -30px; top: -180px"
     viewBox="0 0 1920 1080"
   >
     <defs>
@@ -1073,12 +1073,12 @@
           <use xlink:href="#____0_Layer0_0_1_STROKES" />
         </g>
       </g>
-      <g transform="matrix( 1, 0, 0, 1, 613.65,31.8) ">
+      <!-- <g transform="matrix( 1, 0, 0, 1, 613.65,31.8) ">
         <g transform="matrix( 1, 0, 0, 1, 0,0) ">
           <use xlink:href="#Led_0_Layer0_0_FILL" />
           <use xlink:href="#Led_0_Layer0_0_1_STROKES" />
         </g>
-      </g>
+      </g> -->
       <g transform="matrix( 1, 0, 0, 1, -155.25,-67.45) ">
         <g transform="matrix( 1, 0, 0, 1, 0,0) ">
           <use xlink:href="#____0_Layer0_0_FILL_FL" />

+ 5 - 5
src/views/vent/monitorManager/windowMonitor/components/windowSVG.vue

@@ -6,9 +6,9 @@
     preserveAspectRatio="none"
     x="0px"
     y="0px"
-    width="1536px"
-    height="100%"
-    style="margin-left: calc(50% - 768px)"
+    width="1980px"
+    height="1080"
+    style="position: relative; left: -30px; top: -180px"
     viewBox="0 0 1920 1080"
   >
     <defs>
@@ -1013,12 +1013,12 @@
           <use xlink:href="#____0_Layer0_0_1_STROKES" />
         </g>
       </g>
-      <g transform="matrix( 1, 0, 0, 1, 613.65,31.8) ">
+      <!-- <g transform="matrix( 1, 0, 0, 1, 613.65,31.8) ">
         <g transform="matrix( 1, 0, 0, 1, 0,0) ">
           <use xlink:href="#Led_0_Layer0_0_FILL" />
           <use xlink:href="#Led_0_Layer0_0_1_STROKES" />
         </g>
-      </g>
+      </g> -->
     </g>
     <g transform="matrix( 1, 0, 0, 1, 978.2,554.7) ">
       <g transform="matrix( 1, 0, 0, 1, 0,0) ">

+ 18 - 19
src/views/vent/monitorManager/windowMonitor/dandaoFcBd1.threejs.ts

@@ -48,7 +48,6 @@ class ddFc_4 {
     this.group?.scale.set(22, 22, 22);
     this.group?.position.set(-35, 25, 15);
   }
-
   addMonitorText(selectData) {
     if (!this.group) {
       return;
@@ -70,7 +69,7 @@ class ddFc_4 {
         y: 95,
       },
       {
-        text: `${selectData.OpenDegree ? '开度值(°)' : selectData.forntArea ? '过风面积(㎡)' : '过风面积(㎡)'}:`,
+        text: `最大面积(㎡):`,
         font: 'normal 30px Arial',
         color: '#009900',
         strokeStyle: '#002200',
@@ -78,11 +77,7 @@ class ddFc_4 {
         y: 145,
       },
       {
-        text: selectData.OpenDegree
-          ? Number(`${selectData.OpenDegree}`).toFixed(2)
-          : selectData.forntArea
-          ? Number(`${selectData.forntArea}`).toFixed(2)
-          : '-',
+        text: selectData.maxarea ? Number(`${selectData.maxarea}`).toFixed(2) : '-',
         font: 'normal 30px Arial',
         color: '#009900',
         strokeStyle: '#002200',
@@ -90,7 +85,7 @@ class ddFc_4 {
         y: 145,
       },
       {
-        text: `${selectData.frontRearDP ? '风窗压差(Pa)' : selectData.windSpeed ? '风速(m/s)' : '通信状态:'}:`,
+        text: `${selectData.OpenDegree ? '开度值(°)' : selectData.forntArea ? '过风面积(㎡)' : '过风面积(㎡)'}:`,
         font: 'normal 30px Arial',
         color: '#009900',
         strokeStyle: '#002200',
@@ -98,15 +93,11 @@ class ddFc_4 {
         y: 200,
       },
       {
-        text: `${
-          selectData.frontRearDP
-            ? selectData.frontRearDP
-            : selectData.windSpeed
-            ? selectData.windSpeed
-            : selectData.netStatus == '0'
-            ? '断开'
-            : '连接'
-        }`,
+        text: selectData.OpenDegree
+          ? Number(`${selectData.OpenDegree}`).toFixed(2)
+          : selectData.forntArea
+          ? Number(`${selectData.forntArea}`).toFixed(2)
+          : '-',
         font: 'normal 30px Arial',
         color: '#009900',
         strokeStyle: '#002200',
@@ -114,7 +105,7 @@ class ddFc_4 {
         y: 200,
       },
       {
-        text: `${selectData.fWindowM3 ? '过风量(m³/min)' : '风窗道数'}: `,
+        text: `${selectData.frontRearDP ? '风窗压差(Pa)' : selectData.windSpeed ? '风速(m/s)' : '通信状态:'}:`,
         font: 'normal 30px Arial',
         color: '#009900',
         strokeStyle: '#002200',
@@ -122,7 +113,15 @@ class ddFc_4 {
         y: 250,
       },
       {
-        text: `${selectData.fWindowM3 ? selectData.fWindowM3 : selectData.nwindownum}`,
+        text: `${
+          selectData.frontRearDP
+            ? selectData.frontRearDP
+            : selectData.windSpeed
+            ? selectData.windSpeed
+            : selectData.netStatus == '0'
+            ? '断开'
+            : '连接'
+        }`,
         font: 'normal 30px Arial',
         color: '#009900',
         strokeStyle: '#002200',

+ 2 - 0
src/views/vent/monitorManager/windowMonitor/index.vue

@@ -33,6 +33,8 @@
           <div v-if="hasPermission('window:AreaControl')" class="button-box" @click="setArea(1)">设定风窗面积</div>
           <div v-if="hasPermission('window:showAngle')" class="button-box" @click="setAngle(1)">设定风窗角度</div>
           <div v-if="hasPermission('window:showAngleArea')" class="button-box" @click="setAngle(1)">设定风窗面积</div>
+          <div v-if="hasPermission('window:showAddArea')" class="button-box" @click="setControl('addSetValue', '增加面积设置')">增加面积</div>
+          <div v-if="hasPermission('window:showAddArea')" class="button-box" @click="setControl('deSetValue', '减少面积设置')">减少面积</div>
         </div>
         <div v-if="hasPermission('window:sameSet')" class="button-box" @click="setControl('sameSetValue', '风窗面积设置')">设定风窗面积</div>
         <div v-if="hasPermission('window:COTest')" class="button-box" @click="setControl('COTest', 'CO调控预测')">CO调控预测</div>

+ 105 - 107
src/views/vent/monitorManager/windowMonitor/window.threejs.ts

@@ -301,121 +301,119 @@ export const play = (rotationParam, flag) => {
 
 // 切换风窗类型
 export const setModelType = (type) => {
-  if (!model) return;
-  // if (!model || !model.scene) return;
-  windowType = type;
-  const windowConfigurations = {
-    sdFc1: {
-      render: sdFc1 ? () => sdFc1.render() : null,
-      group: sdFc1 ? sdFc1.group : null,
-      newP: { x: 66.257, y: 57.539, z: 94.313 },
-      newT: { x: 0, y: 0, z: 0 },
-    },
-    ddFc5: {
-      render: ddFc5 ? () => ddFc5.render() : null,
-      group: ddFc5 ? ddFc5.group : null,
-      newP: { x: 66.257, y: 57.539, z: 94.313 },
-      newT: { x: 0, y: 0, z: 0 },
-    },
-    ddFc6: {
-      render: ddFc6 ? () => ddFc6.render() : null,
-      group: ddFc6 ? ddFc6.group : null,
-      newP: { x: 66.257, y: 57.539, z: 94.313 },
-      newT: { x: 0, y: 0, z: 0 },
-    },
-    ddFc7: {
-      render: ddFc7 ? () => ddFc7.render() : null,
-      group: ddFc7 ? ddFc7.group : null,
-      newP: { x: 66.257, y: 57.539, z: 94.313 },
-      newT: { x: 0, y: 0, z: 0 },
-    },
-    ddFc8: {
-      render: ddFc8 ? () => ddFc8.render() : null,
-      group: ddFc8 ? ddFc8.group : null,
-      newP: { x: 32.78, y: 64.88, z: 106.78 },
-      newT: { x: -6.12, y: 13.27, z: -4.64 },
-    },
-    ddFc1: {
-      render: ddFc1 ? () => ddFc1.render() : null,
-      group: ddFc1 ? ddFc1.group : null,
-      newP: { x: 34.294433107431956, y: 19.284123769585108, z: 47.717286013509835 },
-      newT: { x: 12.311816240141978, y: -5.691930035759495, z: -5.57302688985693 },
-    },
-    ddFc2: {
-      render: ddFc2 ? () => ddFc2.render() : null,
-      group: ddFc2 ? ddFc2.group : null,
-      newP: { x: 66.257, y: 57.539, z: 94.313 },
-      newT: { x: 0, y: 0, z: 0 },
-    },
-    ddFc4: {
-      render: ddFc4 ? () => ddFc4.render() : null,
-      group: ddFc4 ? ddFc4.group : null,
-      newP: { x: 66.257, y: 57.539, z: 94.313 },
-      newT: { x: 0, y: 0, z: 0 },
-    },
-    sdFc3: {
-      render: sdFc3 ? () => sdFc3.render() : null,
-      group: sdFc3 ? sdFc3.group : null,
-      newP: { x: 66.257, y: 57.539, z: 94.313 },
-      newT: { x: 0, y: 0, z: 0 },
-    },
-    sdFc4: {
-      render: sdFc4 ? () => sdFc4.render() : null,
-      group: sdFc4 ? sdFc4.group : null,
-      newP: { x: 66.257, y: 57.539, z: 94.313 },
-      newT: { x: 0, y: 0, z: 0 },
-    },
-    sdFc2: {
-      render: sdFc2 ? () => sdFc2.render() : null,
-      group: sdFc2 ? sdFc2.group : null,
-      newP: { x: 66.257, y: 57.539, z: 94.313 },
-      newT: { x: 0, y: 0, z: 0 },
-    },
-    sdFc5: {
-      render: sdFc5 ? () => sdFc5.render() : null,
-      group: sdFc5 ? sdFc5.group : null,
-      newP: { x: 34.294433107431956, y: 19.284123769585108, z: 47.717286013509835 },
-      newT: { x: 12.311816240141978, y: -5.691930035759495, z: -5.57302688985693 },
-    },
-    threeFc8: {
-      render: threeFc8 ? () => threeFc8.render() : null,
-      group: threeFc8 ? threeFc8.group : null,
-      newP: { x: 70.79925059068043, y: 61.89235869996884, z: 107.07997293517579 },
-      newT: { x: 15.353809053159333, y: 8.712511207091119, z: -13.223119892513122 },
-    },
-    singleXkWindow: {
-      render: singleWindowXkObj ? () => singleWindowXkObj.render() : null,
-      group: singleWindowXkObj ? singleWindowXkObj.group : null,
-      newP: { x: 116.08531358656566, y: 81.45510733175816, z: 193.00752046594465 },
-      newT: { x: 23.446366480086372, y: -12.335134633777185, z: -5.63294282643405 },
-    },
-    sdFcZhq: {
-      render: sdFcZhq ? () => sdFcZhq.render() : null,
-      group: sdFcZhq ? sdFcZhq.group : null,
-      newP: { x: 66.257, y: 57.539, z: 94.313 },
-      newT: { x: -2.28, y: -0.91, z: -5.68 },
-    },
-  };
-  const oldCameraPosition = { x: 100, y: 0, z: 10 };
-  model.scene?.remove(group);
-  function handleWindowType(windowType: string, model: any) {
+  return new Promise((resolve) => {
+    if (!model) resolve(null);
+    windowType = type;
+    const windowConfigurations = {
+      sdFc1: {
+        render: sdFc1 ? () => sdFc1.render() : null,
+        group: sdFc1 ? sdFc1.group : null,
+        newP: { x: 66.257, y: 57.539, z: 94.313 },
+        newT: { x: 0, y: 0, z: 0 },
+      },
+      ddFc5: {
+        render: ddFc5 ? () => ddFc5.render() : null,
+        group: ddFc5 ? ddFc5.group : null,
+        newP: { x: 66.257, y: 57.539, z: 94.313 },
+        newT: { x: 0, y: 0, z: 0 },
+      },
+      ddFc6: {
+        render: ddFc6 ? () => ddFc6.render() : null,
+        group: ddFc6 ? ddFc6.group : null,
+        newP: { x: 66.257, y: 57.539, z: 94.313 },
+        newT: { x: 0, y: 0, z: 0 },
+      },
+      ddFc7: {
+        render: ddFc7 ? () => ddFc7.render() : null,
+        group: ddFc7 ? ddFc7.group : null,
+        newP: { x: 66.257, y: 57.539, z: 94.313 },
+        newT: { x: 0, y: 0, z: 0 },
+      },
+      ddFc8: {
+        render: ddFc8 ? () => ddFc8.render() : null,
+        group: ddFc8 ? ddFc8.group : null,
+        newP: { x: 32.78, y: 64.88, z: 106.78 },
+        newT: { x: -6.12, y: 13.27, z: -4.64 },
+      },
+      ddFc1: {
+        render: ddFc1 ? () => ddFc1.render() : null,
+        group: ddFc1 ? ddFc1.group : null,
+        newP: { x: 34.294433107431956, y: 19.284123769585108, z: 47.717286013509835 },
+        newT: { x: 12.311816240141978, y: -5.691930035759495, z: -5.57302688985693 },
+      },
+      ddFc2: {
+        render: ddFc2 ? () => ddFc2.render() : null,
+        group: ddFc2 ? ddFc2.group : null,
+        newP: { x: 66.257, y: 57.539, z: 94.313 },
+        newT: { x: 0, y: 0, z: 0 },
+      },
+      ddFc4: {
+        render: ddFc4 ? () => ddFc4.render() : null,
+        group: ddFc4 ? ddFc4.group : null,
+        newP: { x: 66.257, y: 57.539, z: 94.313 },
+        newT: { x: 0, y: 0, z: 0 },
+      },
+      sdFc3: {
+        render: sdFc3 ? () => sdFc3.render() : null,
+        group: sdFc3 ? sdFc3.group : null,
+        newP: { x: 66.257, y: 57.539, z: 94.313 },
+        newT: { x: 0, y: 0, z: 0 },
+      },
+      sdFc4: {
+        render: sdFc4 ? () => sdFc4.render() : null,
+        group: sdFc4 ? sdFc4.group : null,
+        newP: { x: 66.257, y: 57.539, z: 94.313 },
+        newT: { x: 0, y: 0, z: 0 },
+      },
+      sdFc2: {
+        render: sdFc2 ? () => sdFc2.render() : null,
+        group: sdFc2 ? sdFc2.group : null,
+        newP: { x: 66.257, y: 57.539, z: 94.313 },
+        newT: { x: 0, y: 0, z: 0 },
+      },
+      sdFc5: {
+        render: sdFc5 ? () => sdFc5.render() : null,
+        group: sdFc5 ? sdFc5.group : null,
+        newP: { x: 34.294433107431956, y: 19.284123769585108, z: 47.717286013509835 },
+        newT: { x: 12.311816240141978, y: -5.691930035759495, z: -5.57302688985693 },
+      },
+      threeFc8: {
+        render: threeFc8 ? () => threeFc8.render() : null,
+        group: threeFc8 ? threeFc8.group : null,
+        newP: { x: 70.79925059068043, y: 61.89235869996884, z: 107.07997293517579 },
+        newT: { x: 15.353809053159333, y: 8.712511207091119, z: -13.223119892513122 },
+      },
+      singleXkWindow: {
+        render: singleWindowXkObj ? () => singleWindowXkObj.render() : null,
+        group: singleWindowXkObj ? singleWindowXkObj.group : null,
+        newP: { x: 116.08531358656566, y: 81.45510733175816, z: 193.00752046594465 },
+        newT: { x: 23.446366480086372, y: -12.335134633777185, z: -5.63294282643405 },
+      },
+      sdFcZhq: {
+        render: sdFcZhq ? () => sdFcZhq.render() : null,
+        group: sdFcZhq ? sdFcZhq.group : null,
+        newP: { x: 66.257, y: 57.539, z: 94.313 },
+        newT: { x: -2.28, y: -0.91, z: -5.68 },
+      },
+    };
+    const oldCameraPosition = { x: 100, y: 0, z: 10 };
+    model.scene?.remove(group);
     const config = windowConfigurations[windowType];
 
     if (config && config.group) {
       model.startAnimation = config.render;
       group = config.group;
-      return new Promise((resolve) => {
-        setTimeout(async () => {
-          await animateCamera(oldCameraPosition, { x: 0, y: 0, z: 0 }, config.newP, config.newT, model);
-          model.scene?.add(config.group);
-          resolve(null);
-        }, 1000);
-      });
+
+      setTimeout(async () => {
+        await animateCamera(oldCameraPosition, { x: 0, y: 0, z: 0 }, config.newP, config.newT, model);
+        model.scene?.add(config.group);
+        resolve(null);
+      }, 1000);
     } else {
+      resolve(null);
       throw new Error(`Unsupported windowType: ${windowType}`);
     }
-  }
-  return handleWindowType(windowType, model);
+  });
 };
 
 export const mountedThree = () => {

+ 1 - 1
src/views/vent/monitorManager/windrectMonitor/index.vue

@@ -350,7 +350,7 @@ async function getMonitor(flag?: boolean) {
           console.error('Error', error);
         } finally {
           timer = null;
-          getMonitor(flag);
+          getMonitor(false);
         }
       },
       flag ? 0 : 1000

Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini