Quellcode durchsuchen

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

wangkeyi vor 1 Woche
Ursprung
Commit
d721ca1643
100 geänderte Dateien mit 4517 neuen und 1200 gelöschten Zeilen
  1. BIN
      src/assets/images/home-green/db-green.png
  2. BIN
      src/assets/images/home-green/sz-green.png
  3. BIN
      src/assets/images/home-warn/8-1.png
  4. BIN
      src/assets/images/home-warn/8-2.png
  5. BIN
      src/assets/images/home-warn/8-3.png
  6. BIN
      src/assets/images/home-warn/8-4.png
  7. BIN
      src/assets/images/home-warn/8-5.png
  8. BIN
      src/assets/images/themify/deepblue/home-container/configurable/db-green.png
  9. BIN
      src/assets/images/themify/deepblue/home-container/configurable/sz-green.png
  10. BIN
      src/assets/images/vent/alarm-icons/FangHuo_2.png
  11. BIN
      src/assets/images/vent/alarm-icons/FenZhan158_1.png
  12. BIN
      src/assets/images/vent/alarm-icons/FengChuang_2.png
  13. BIN
      src/assets/images/vent/alarm-icons/JuBuFengJi_2.png
  14. BIN
      src/assets/images/vent/alarm-icons/LED.png
  15. BIN
      src/assets/images/vent/alarm-icons/ccb-green.png
  16. BIN
      src/assets/images/vent/alarm-icons/cf-green.png
  17. BIN
      src/assets/images/vent/alarm-icons/cgq-green.png
  18. BIN
      src/assets/images/vent/alarm-icons/dscf-green.png
  19. BIN
      src/assets/images/vent/alarm-icons/fc-green.png
  20. BIN
      src/assets/images/vent/alarm-icons/fm-green.png
  21. BIN
      src/assets/images/vent/alarm-icons/jbfj-db.png
  22. BIN
      src/assets/images/vent/alarm-icons/jbfj.png
  23. BIN
      src/assets/images/vent/alarm-icons/pf-green.png
  24. BIN
      src/assets/images/vent/alarm-icons/pl-green.png
  25. BIN
      src/assets/images/vent/alarm-icons/pw-green.png
  26. BIN
      src/assets/images/vent/alarm-icons/sgjc.png
  27. BIN
      src/assets/images/vent/alarm-icons/yf-green.png
  28. BIN
      src/assets/images/vent/alarm-icons/zd-green.png
  29. BIN
      src/assets/images/vent/alarm-icons/zfj.png
  30. BIN
      src/assets/images/vent/alarm-icons/zj-green.png
  31. BIN
      src/assets/images/vent/alarm-icons/传感器_1.png
  32. BIN
      src/assets/images/vent/alarm-icons/光纤测温.png
  33. BIN
      src/assets/images/vent/alarm-icons/双风门.png
  34. BIN
      src/assets/images/vent/alarm-icons/安全监控.png
  35. BIN
      src/assets/images/vent/alarm-icons/密闭_1.png
  36. BIN
      src/assets/images/vent/alarm-icons/对射测风.png
  37. BIN
      src/assets/images/vent/alarm-icons/干式除尘机.png
  38. BIN
      src/assets/images/vent/alarm-icons/球阀.png
  39. BIN
      src/assets/images/vent/alarm-icons/瓦斯巡检.png
  40. BIN
      src/assets/images/vent/alarm-icons/瓦斯巡检_3.png
  41. BIN
      src/assets/images/vent/alarm-icons/瓦斯监测.png
  42. BIN
      src/assets/images/vent/alarm-icons/瓦斯管道04.png
  43. BIN
      src/assets/images/vent/alarm-icons/矿用球阀.png
  44. BIN
      src/assets/images/vent/alarm-icons/粉尘监测.png
  45. BIN
      src/assets/images/vent/alarm-icons/评价单元.png
  46. BIN
      src/assets/images/vent/alarm-icons/语音扩波.png
  47. BIN
      src/assets/images/vent/alarm-icons/防火门.png
  48. BIN
      src/assets/images/vent/alarm-icons/防火门_1.png
  49. BIN
      src/assets/images/vent/alarm-icons/风门1.png
  50. BIN
      src/assets/images/vent/alarm-icons/风门2.png
  51. BIN
      src/assets/images/vent/alarm-icons/风门带窗.png
  52. 7 22
      src/views/vent/home/colliery/components/wind-monitor.vue
  53. 2 2
      src/views/vent/home/configurable/bule/components/ModuleFireNew.vue
  54. 2 2
      src/views/vent/home/configurable/bule/components/ModuleFireNewDual.vue
  55. 1 1
      src/views/vent/home/configurable/bule/components/ModuleNew.vue
  56. 11 5
      src/views/vent/home/configurable/bule/components/ModuleWarnMonitor.vue
  57. 33 0
      src/views/vent/home/configurable/bule/components/center-area-warn.vue
  58. 18 18
      src/views/vent/home/configurable/bule/components/content-FireNew.vue
  59. 14 12
      src/views/vent/home/configurable/bule/components/content-warn.vue
  60. 537 0
      src/views/vent/home/configurable/bule/components/content.vue
  61. 0 0
      src/views/vent/home/configurable/bule/components/detail/MiniBoard-Warn.vue
  62. 109 0
      src/views/vent/home/configurable/bule/components/header.vue
  63. 0 0
      src/views/vent/home/configurable/bule/components/moduleBottom-warn.vue
  64. 17 3
      src/views/vent/home/configurable/bule/components/moduleLeft-warn.vue
  65. 283 0
      src/views/vent/home/configurable/bule/components/originalNew/NewNav.vue
  66. 319 0
      src/views/vent/home/configurable/bule/components/originalNew/NewNavFire.vue
  67. 295 0
      src/views/vent/home/configurable/bule/components/originalNew/NewNavWarn.vue
  68. 95 0
      src/views/vent/home/configurable/bule/components/originalNew/leftHeader1.vue
  69. 89 0
      src/views/vent/home/configurable/bule/components/originalNew/leftHeader2.vue
  70. 133 0
      src/views/vent/home/configurable/bule/components/originalNew/moduleBottom.vue
  71. 95 0
      src/views/vent/home/configurable/bule/components/originalNew/moduleLeft.vue
  72. 104 0
      src/views/vent/home/configurable/bule/components/originalNew/moduleLeftBottom.vue
  73. 103 0
      src/views/vent/home/configurable/bule/components/originalNew/moduleLeftCenter.vue
  74. 104 0
      src/views/vent/home/configurable/bule/components/originalNew/moduleLeftTop.vue
  75. 102 0
      src/views/vent/home/configurable/bule/components/originalNew/moduleRightBottom.vue
  76. 103 0
      src/views/vent/home/configurable/bule/components/originalNew/moduleRightCenter.vue
  77. 104 0
      src/views/vent/home/configurable/bule/components/originalNew/moduleRightTop.vue
  78. 122 0
      src/views/vent/home/configurable/bule/components/originalNew/moduleTop.vue
  79. 161 0
      src/views/vent/home/configurable/bule/components/originalNew/moduleTopFire.vue
  80. 97 0
      src/views/vent/home/configurable/bule/components/originalNew/rightHeader1.vue
  81. 90 0
      src/views/vent/home/configurable/bule/components/originalNew/rightHeader2.vue
  82. 90 0
      src/views/vent/home/configurable/bule/components/originalNew/rightHeader3.vue
  83. 46 9
      src/views/vent/home/configurable/bule/components/yj_chart.vue
  84. 0 0
      src/views/vent/home/configurable/bule/components/yj_gasWarn.vue
  85. 16 25
      src/views/vent/home/configurable/bule/components/yj_risk.vue
  86. 1 1
      src/views/vent/home/configurable/bule/components/yj_ventWarn.vue
  87. 223 0
      src/views/vent/home/configurable/bule/fireNew.vue
  88. 166 0
      src/views/vent/home/configurable/bule/ventNew.vue
  89. 36 9
      src/views/vent/home/configurable/bule/warnMonitor.vue
  90. 311 311
      src/views/vent/home/configurable/components/content-New.vue
  91. 2 10
      src/views/vent/home/configurable/configurable.api.ts
  92. 85 222
      src/views/vent/home/configurable/configurable.data.ts
  93. 0 223
      src/views/vent/home/configurable/fireNew.vue
  94. 4 92
      src/views/vent/home/configurable/green/common-green.vue
  95. 2 2
      src/views/vent/home/configurable/green/components/CustomTable-green.vue
  96. 115 62
      src/views/vent/home/configurable/green/components/center-area-green.vue
  97. 0 3
      src/views/vent/home/configurable/green/components/content-green.vue
  98. 242 149
      src/views/vent/home/configurable/green/components/dz-card.vue
  99. 7 15
      src/views/vent/home/configurable/green/components/dz-chart.vue
  100. 21 2
      src/views/vent/home/configurable/green/components/dz-dust.vue

BIN
src/assets/images/home-green/db-green.png


BIN
src/assets/images/home-green/sz-green.png


BIN
src/assets/images/home-warn/8-1.png


BIN
src/assets/images/home-warn/8-2.png


BIN
src/assets/images/home-warn/8-3.png


BIN
src/assets/images/home-warn/8-4.png


BIN
src/assets/images/home-warn/8-5.png


BIN
src/assets/images/themify/deepblue/home-container/configurable/db-green.png


BIN
src/assets/images/themify/deepblue/home-container/configurable/sz-green.png


BIN
src/assets/images/vent/alarm-icons/FangHuo_2.png


BIN
src/assets/images/vent/alarm-icons/FenZhan158_1.png


BIN
src/assets/images/vent/alarm-icons/FengChuang_2.png


BIN
src/assets/images/vent/alarm-icons/JuBuFengJi_2.png


BIN
src/assets/images/vent/alarm-icons/LED.png


BIN
src/assets/images/vent/alarm-icons/ccb-green.png


BIN
src/assets/images/vent/alarm-icons/cf-green.png


BIN
src/assets/images/vent/alarm-icons/cgq-green.png


BIN
src/assets/images/vent/alarm-icons/dscf-green.png


BIN
src/assets/images/vent/alarm-icons/fc-green.png


BIN
src/assets/images/vent/alarm-icons/fm-green.png


BIN
src/assets/images/vent/alarm-icons/jbfj-db.png


BIN
src/assets/images/vent/alarm-icons/jbfj.png


BIN
src/assets/images/vent/alarm-icons/pf-green.png


BIN
src/assets/images/vent/alarm-icons/pl-green.png


BIN
src/assets/images/vent/alarm-icons/pw-green.png


BIN
src/assets/images/vent/alarm-icons/sgjc.png


BIN
src/assets/images/vent/alarm-icons/yf-green.png


BIN
src/assets/images/vent/alarm-icons/zd-green.png


BIN
src/assets/images/vent/alarm-icons/zfj.png


BIN
src/assets/images/vent/alarm-icons/zj-green.png


BIN
src/assets/images/vent/alarm-icons/传感器_1.png


BIN
src/assets/images/vent/alarm-icons/光纤测温.png


BIN
src/assets/images/vent/alarm-icons/双风门.png


BIN
src/assets/images/vent/alarm-icons/安全监控.png


BIN
src/assets/images/vent/alarm-icons/密闭_1.png


BIN
src/assets/images/vent/alarm-icons/对射测风.png


BIN
src/assets/images/vent/alarm-icons/干式除尘机.png


BIN
src/assets/images/vent/alarm-icons/球阀.png


BIN
src/assets/images/vent/alarm-icons/瓦斯巡检.png


BIN
src/assets/images/vent/alarm-icons/瓦斯巡检_3.png


BIN
src/assets/images/vent/alarm-icons/瓦斯监测.png


BIN
src/assets/images/vent/alarm-icons/瓦斯管道04.png


BIN
src/assets/images/vent/alarm-icons/矿用球阀.png


BIN
src/assets/images/vent/alarm-icons/粉尘监测.png


BIN
src/assets/images/vent/alarm-icons/评价单元.png


BIN
src/assets/images/vent/alarm-icons/语音扩波.png


BIN
src/assets/images/vent/alarm-icons/防火门.png


BIN
src/assets/images/vent/alarm-icons/防火门_1.png


BIN
src/assets/images/vent/alarm-icons/风门1.png


BIN
src/assets/images/vent/alarm-icons/风门2.png


BIN
src/assets/images/vent/alarm-icons/风门带窗.png


+ 7 - 22
src/views/vent/home/colliery/components/wind-monitor.vue

@@ -10,7 +10,7 @@
 <script lang="ts" setup>
 import { ref, reactive, nextTick, onMounted, defineProps, watch } from 'vue';
 import * as echarts from 'echarts';
-import {getMaxY,getMinY} from '../clique.data'
+import { getMaxY, getMinY } from '../clique.data'
 const emit = defineEmits(['goDetail']);
 
 let props = defineProps({
@@ -21,7 +21,7 @@ let props = defineProps({
 let windBar = ref<any>();
 //坐标轴最大值
 let maxY = ref<any>(0);
-let minY=ref<any>(0)
+let minY = ref<any>(0)
 //echart数据
 let echartData = reactive<any>({ ydata: [], xdata: [] });
 //跳转详情
@@ -258,28 +258,13 @@ watch(
       if (el.readData.m3) {
         echartData.xdata.push(el.strinstallpos);
         echartData.ydata.push(el.readData.m3);
+      } else {
+        echartData.xdata.push(el.strinstallpos);
+        echartData.ydata.push('0');
       }
     });
-    maxY.value = getMaxY( echartData.ydata)
-    minY.value = getMinY( echartData.ydata)
-    // maxY.value = echartData.ydata.reduce((acr, cur) => {
-    //   return parseFloat(acr) > parseFloat(cur) ? parseFloat(acr) : parseFloat(cur);
-    // });
-    // maxY.value =
-    //   maxY.value.toString().indexOf('.') == -1 ? maxY.value.toString() : maxY.value.toString().substring(0, maxY.value.toString().indexOf('.'));
-    // if (maxY.value.length < 2 && Number(maxY.value) < 1) {
-    //   maxY.value = 1
-    // } else if (maxY.value.length < 2 && Number(maxY.value) >= 1) {
-    //   maxY.value = 10
-    // } else if (maxY.value.length < 3) {
-    //   maxY.value = (Number(maxY.value[0]) + 1) * 10
-    // } else if (maxY.value.length < 4) {
-    //   maxY.value = (Number(maxY.value[0]) + 1) * 100
-    // } else if (maxY.value.length < 5) {
-    //   maxY.value = (Number(maxY.value[0]) + 1) * 1000
-    // } else if (maxY.value.length < 6) {
-    //   maxY.value = (Number(maxY.value[0]) + 1) * 10000
-    // }
+    maxY.value = getMaxY(echartData.ydata)
+    minY.value = getMinY(echartData.ydata)
     getOption();
   },
   {

+ 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>

+ 2 - 10
src/views/vent/home/configurable/configurable.api.ts

@@ -518,14 +518,7 @@ export const getTotal = (params) => {
         value1: el.pumpNumber
       }
     })
-    //风险权重比例数据
-    let risk = await getDisasterProportion({})
-    res.riskData = [
-      { name: '通风', value: risk.vent },
-      { name: '火灾', value: risk.fire },
-      { name: '瓦斯', value: risk.gas },
-      { name: '粉尘', value: risk.dust },
-    ]
+   
     //火灾监测预警数据
     res.fireInfos = reactive({})
     res.fireInfos.dataOn = []
@@ -567,7 +560,6 @@ export const getTotal = (params) => {
         ? res.info.sysInfo.fireS.summaryInfo.external.coval.value
         : '-'
       : '';
-      console.log( res.fireInfos,'000-')
     //粉尘监测预警数据
      res.dustInfo = [
           {
@@ -591,7 +583,7 @@ export const getTotal = (params) => {
             value: dataVent.dust ? dataVent.dust : res.info.sysInfo.dustS.levels.blue
           },
         ];
-    console.log(res.dustInfo,'dustdev')
+   
 
     return res;
   });

+ 85 - 222
src/views/vent/home/configurable/configurable.data.ts

@@ -346,9 +346,9 @@ export const testConfigVent: Config[] = [
       to: '/micro-vent-3dModal/dashboard/analysis?type=tunMonitor&deviceType=windrect',
     },
     showStyle: {
-      size: 'width:460px;height:260px;',
+      size: 'width:505px;height:260px;',
       version: '原版',
-      position: 'bottom:0px;left:15px;',
+      position: 'bottom:15px;left:420px;',
     },
   },
   {
@@ -428,7 +428,7 @@ export const testConfigVent: Config[] = [
     showStyle: {
       size: 'width:460px;height:260px;',
       version: '原版',
-      position: 'bottom:0px;left:495px;',
+      position: 'bottom:15px;left:940px;',
     },
   },
   {
@@ -511,96 +511,10 @@ export const testConfigVent: Config[] = [
     showStyle: {
       size: 'width:460px;height:260px;',
       version: '原版',
-      position: 'bottom:0px;left:975px;',
+      position: 'bottom:15px;right:15px;',
     },
   },
-  //  {
-  //     // deviceType: 'warn',
-  //     // moduleName: '预警监测',
-  //     deviceType: '',
-  //     moduleName: '智能通风Deepseek',
-  //     pageType: 'vent',
-  //     moduleData: {
-  //       header: {
-  //         show: true,
-  //         readFrom: '',
-  //         selector: {
-  //           show: false,
-  //           value: '',
-  //         },
-  //         slot: {
-  //           show: true,
-  //           value: '网络异常:${warn[0].netstatus.val}',
-  //         },
-  //       },
-  //       background: {
-  //         show: false,
-  //         type: 'video',
-  //         link: '',
-  //       },
-  //       layout: {
-  //         direction: 'row',
-  //         items: [
-  //           {
-  //             // name: 'list',
-  //             name: 'ai_chat',
-  //             basis: '100%',
-  //           },
-  //         ],
-  //       },
-  //       board: [],
-  //       list: [
-  //         {
-  //           type: 'timeline',
-  //           readFrom: 'warn[0]',
-  //           items: [
-  //             {
-  //               label: '报警',
-  //               value: '${alarm.val}',
-  //               info: '',
-  //               color: 'red',
-  //             },
-  //             {
-  //               label: '重大风险预警',
-  //               value: '${red.val}',
-  //               info: '',
-  //               color: 'red',
-  //             },
-  //             {
-  //               label: '较大风险预警',
-  //               value: '${orange.val}',
-  //               info: '',
-  //               color: 'orange',
-  //             },
-  //             {
-  //               label: '一般风险预警',
-  //               value: '${yellow.val}',
-  //               info: '',
-  //               color: 'yellow',
-  //             },
-  //             {
-  //               label: '低风险预警',
-  //               value: '${blue.val}',
-  //               info: '',
-  //               color: 'blue',
-  //             },
-  //           ],
-  //         },
-  //       ],
-  //       preset: [{ readFrom: '' }],
-  //       table: [],
-  //       gallery: [],
-  //       chart: [],
-  //       gallery_list: [],
-  //       complex_list: [],
-  //       to: '/monitorChannel/monitor-alarm-home',
-  //     },
-  //     showStyle: {
-  //       size: 'width:390px;height:260px;',
-  //       version: '原版',
-  //       position: 'top:855px;left:15px',
-  //     },
-  //   },
+
 ];
 
 export const testConfigDust: Config[] = [
@@ -1088,7 +1002,7 @@ export const testConfigDustGreen: Config[] = [
       // mock: BDdustMock,
     },
     showStyle: {
-      size: 'width:420px;height:780px;',
+      size: 'width:420px;height:815px;',
       version: '新版',
       position: 'top:0px;left:15px',
     },
@@ -2048,7 +1962,7 @@ export const testConfigFireGreen: Config[] = [
       // mock: BDfireMock,
     },
     showStyle: {
-      size: 'width:420px;height:350px;',
+      size: 'width:420px;height:400px;',
       version: '原版',
       position: 'top:415px;left:15px;',
     },
@@ -2966,7 +2880,7 @@ export const testConfigFusionGreen: Config[] = [
           readFrom: 'deviceWarn',
           listOption: {
             fanmain: {
-              url: getThemifyImagesURL(),
+              url: getThemifyImagesURL('vent/alarm-icons/zfj.png'),
               text: '',
               allText: '总数',
               warnText: '报警数',
@@ -2976,7 +2890,7 @@ export const testConfigFusionGreen: Config[] = [
               closeCount: 'fanmain_close',
             },
             fanlocal: {
-              url: getThemifyImagesURL(''),
+              url: getThemifyImagesURL('vent/alarm-icons/jbfj.png'),
               text: '',
               allText: '总数',
               warnText: '报警数',
@@ -2986,7 +2900,7 @@ export const testConfigFusionGreen: Config[] = [
               closeCount: 'fanlocal_close',
             },
             bundletube: {
-              url: getThemifyImagesURL(''),
+              url: getThemifyImagesURL('vent/alarm-icons/sgjc.png'),
               text: '',
               allText: '总数',
               warnText: '报警数',
@@ -2996,7 +2910,7 @@ export const testConfigFusionGreen: Config[] = [
               closeCount: 'bundletube_close',
             },
             fanlocaldp: {
-              url: getThemifyImagesURL(''),
+              url: getThemifyImagesURL('vent/alarm-icons/jbfj-db.png'),
               text: '',
               allText: '总数',
               warnText: '报警数',
@@ -3006,7 +2920,7 @@ export const testConfigFusionGreen: Config[] = [
               closeCount: 'fanlocaldp_close',
             },
             gate: {
-              url: getThemifyImagesURL(''),
+              url: getThemifyImagesURL('vent/alarm-icons/fm-green.png'),
               text: '',
               allText: '总数',
               warnText: '报警数',
@@ -3016,7 +2930,7 @@ export const testConfigFusionGreen: Config[] = [
               closeCount: 'gate_close',
             },
             window: {
-              url: getThemifyImagesURL(''),
+              url: getThemifyImagesURL('vent/alarm-icons/fc-green.png'),
               text: '',
               allText: '总数',
               warnText: '报警数',
@@ -3026,7 +2940,7 @@ export const testConfigFusionGreen: Config[] = [
               closeCount: 'window_close',
             },
             windrect: {
-              url: getThemifyImagesURL(''),
+              url: getThemifyImagesURL('vent/alarm-icons/dscf-green.png'),
               text: '',
               allText: '总数',
               warnText: '报警数',
@@ -3036,7 +2950,7 @@ export const testConfigFusionGreen: Config[] = [
               closeCount: 'windrect_close',
             },
             forcFan: {
-              url: getThemifyImagesURL(''),
+              url: getThemifyImagesURL('vent/alarm-icons/yf-green.png'),
               text: '',
               allText: '总数',
               warnText: '报警数',
@@ -3046,7 +2960,7 @@ export const testConfigFusionGreen: Config[] = [
               closeCount: 'forcFan_close',
             },
             spray: {
-              url: getThemifyImagesURL(''),
+              url: getThemifyImagesURL('vent/alarm-icons/pl-green.png'),
               text: '',
               allText: '总数',
               warnText: '报警数',
@@ -3056,7 +2970,7 @@ export const testConfigFusionGreen: Config[] = [
               closeCount: 'spray_close',
             },
             dustdev: {
-              url: getThemifyImagesURL(''),
+              url: getThemifyImagesURL('vent/alarm-icons/pf-green.png'),
               text: '',
               allText: '总数',
               warnText: '报警数',
@@ -3066,7 +2980,7 @@ export const testConfigFusionGreen: Config[] = [
               closeCount: 'dustdev_close',
             },
             nitrogen: {
-              url: getThemifyImagesURL(''),
+              url: getThemifyImagesURL('vent/alarm-icons/zd-green.png'),
               text: '',
               allText: '总数',
               warnText: '报警数',
@@ -3076,7 +2990,7 @@ export const testConfigFusionGreen: Config[] = [
               closeCount: 'nitrogen_close',
             },
             pulping: {
-              url: getThemifyImagesURL(''),
+              url: getThemifyImagesURL('vent/alarm-icons/zj-green.png'),
               text: '',
               allText: '总数',
               warnText: '报警数',
@@ -3086,7 +3000,7 @@ export const testConfigFusionGreen: Config[] = [
               closeCount: 'pulping_close',
             },
             atomizing: {
-              url: getThemifyImagesURL(''),
+              url: getThemifyImagesURL('vent/alarm-icons/pw-green.png'),
               text: '',
               allText: '总数',
               warnText: '报警数',
@@ -3096,7 +3010,7 @@ export const testConfigFusionGreen: Config[] = [
               closeCount: 'atomizing_close',
             },
             dustsensor: {
-              url: getThemifyImagesURL(''),
+              url: getThemifyImagesURL('vent/alarm-icons/cgq-green.png'),
               text: '',
               allText: '总数',
               warnText: '报警数',
@@ -3106,7 +3020,7 @@ export const testConfigFusionGreen: Config[] = [
               closeCount: 'dustsensor_close',
             },
             gas: {
-              url: getThemifyImagesURL(''),
+              url: getThemifyImagesURL('vent/alarm-icons/ccb-green.png'),
               text: '',
               allText: '总数',
               warnText: '报警数',
@@ -3116,7 +3030,7 @@ export const testConfigFusionGreen: Config[] = [
               closeCount: 'gas_close',
             },
             pump: {
-              url: getThemifyImagesURL('vent/alarm-icons/wasibeng.png'),
+              url: getThemifyImagesURL('vent/alarm-icons/ccb-green.png'),
               text: '',
               allText: '总数',
               warnText: '报警数',
@@ -3126,7 +3040,7 @@ export const testConfigFusionGreen: Config[] = [
               closeCount: 'pump_close',
             },
             modelsensor: {
-              url: getThemifyImagesURL('vent/alarm-icons/cf.png'),
+              url: getThemifyImagesURL('vent/alarm-icons/cf-green.png'),
               text: '',
               allText: '总数',
               warnText: '报警数',
@@ -3141,7 +3055,7 @@ export const testConfigFusionGreen: Config[] = [
       // mock: BDfireMock,
     },
     showStyle: {
-      size: 'width:420px;height:350px;',
+      size: 'width:420px;height:400px;',
       version: '原版',
       position: 'top:415px;left:15px',
     },
@@ -3319,7 +3233,7 @@ export const testConfigFusionGreen: Config[] = [
       // mock: BDfireMock,
     },
     showStyle: {
-      size: 'width:420px;height:350px;',
+      size: 'width:420px;height:400px;',
       version: '原版',
       position: 'top:415px;right:15px',
     },
@@ -3347,7 +3261,7 @@ export const testConfigFusionGreen: Config[] = [
         link: '',
       },
       layout: {
-        direction: 'column',
+        direction: 'row',
         items: [
           {
             name: 'dz_gas',
@@ -3387,62 +3301,11 @@ export const testConfigFusionGreen: Config[] = [
       // mock: BDfireMock,
     },
     showStyle: {
-      size: 'width:614px;height:240px;',
+      size: 'width:990px;height:170px;',
       version: '原版',
       position: 'bottom:15px;left:450px',
     },
   },
-  {
-    deviceType: 'fusionManageInfo',
-    moduleName: '风险权重比例',
-    pageType: 'riskData',
-    moduleData: {
-      header: {
-        show: false,
-        readFrom: '',
-        selector: {
-          show: false,
-          value: '',
-        },
-        slot: {
-          show: false,
-          value: '',
-        },
-      },
-      background: {
-        show: false,
-        type: 'video',
-        link: '',
-      },
-      layout: {
-        direction: 'column',
-        items: [
-          {
-            name: 'dz_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: 'bottom:15px;right:450px',
-    },
-  },
 ];
 
 export const testConfigVentNew: Config[] = [
@@ -4074,7 +3937,7 @@ export const testConfigWarnMonitor: Config[] = [
     },
   },
   {
-    deviceType: 'fusionManageInfo',
+    deviceType: 'fireWarnInfo',
     moduleName: '火灾监测预警',
     pageType: 'fusion-warn-green',
     moduleData: {
@@ -4100,11 +3963,11 @@ export const testConfigWarnMonitor: Config[] = [
         items: [
           {
             name: 'board',
-            basis: '35%',
+            basis: '30%',
           },
           {
             name: 'dz_card',
-            basis: '65%',
+            basis: '70%',
           },
         ],
       },
@@ -4223,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: {
@@ -4367,7 +4230,7 @@ export const testConfigWarnMonitor: Config[] = [
               closeCount: 'gate_close',
             },
             window: {
-              url: getThemifyImagesURL(''),
+              url: getThemifyImagesURL('fc'),
               text: '',
               allText: '总数',
               warnText: '报警数',
@@ -4524,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>

+ 4 - 92
src/views/vent/home/configurable/green/common-green.vue

@@ -3,18 +3,10 @@
     <!-- 如果是有 deviceType、type 等 query,认为是详情页,不需要展示普通模块,只需要模型 -->
     <template v-if="!route.query.deviceType">
       <div class="main-container">
-        <div class="left-area">
-          <!-- 采用定位方式以避免出现各个模块隐藏时其他模块下移的问题 -->
-          <ModuleOriginal v-for="cfg in configsLeft" :key="cfg.deviceType" :show-style="cfg.showStyle"
-            :module-data="cfg.moduleData" :module-name="cfg.moduleName" :device-type="cfg.deviceType" :data="data"
-            :visible="true" />
-        </div>
-        <div class="bottom-area">
-          <!-- 采用定位方式以避免出现各个模块隐藏时其他模块下移的问题 -->
-          <ModuleOriginal v-for="cfg in configsBottom" :key="cfg.deviceType" :show-style="cfg.showStyle"
-            :module-data="cfg.moduleData" :module-name="cfg.moduleName" :device-type="cfg.deviceType" :data="data"
-            :visible="true" />
-        </div>
+        <!-- 采用定位方式以避免出现各个模块隐藏时其他模块下移的问题 -->
+        <ModuleOriginal v-for="cfg in configs" :key="cfg.deviceType" :show-style="cfg.showStyle"
+          :module-data="cfg.moduleData" :module-name="cfg.moduleName" :device-type="cfg.deviceType" :data="data"
+          :visible="true" />
         <div class="right-area">
           <greenRightTag />
         </div>
@@ -45,14 +37,6 @@ const route = useRoute();
 
 let interval: number | undefined;
 let configs = ref<any[]>([]);
-
-let configsLeft = computed(() => {
-  return configs.value.filter((v) => v.showStyle.position.includes('top'));
-});
-let configsBottom = computed(() => {
-  return configs.value.filter((v) => v.showStyle.position.includes('bottom'));
-});
-
 function refresh() {
   fetchConfigs('vent').then(() => {
     configs.value = testConfigVent;
@@ -155,78 +139,6 @@ onUnmounted(() => {
   .main-container {
     width: 100%;
     height: 100%;
-
-    .left-area {
-      position: absolute;
-      left: 0;
-      top: 0;
-      width: 420px;
-      height: 100%;
-      padding: 15px;
-      background: url('../../../../assets/images/home-green/green-bd-left.png') no-repeat;
-      background-size: 100% 100%;
-      box-sizing: border-box;
-      overflow-y: auto;
-    }
-
-    .bottom-area {
-      position: absolute;
-      left: 435px;
-      bottom: 0;
-      width: calc(100% - 435px);
-      height: 290px;
-      padding: 15px;
-      background: url('../../../../assets/images/home-green/green-bd-bottom.png') no-repeat;
-      background-size: 100% 100%;
-      box-sizing: border-box;
-    }
-
-    .right-area {
-      position: absolute;
-      right: 0px;
-      top: 0px;
-      width: 120px;
-      height: calc(100% - 305px);
-    }
-  }
-
-  .module-dropdown {
-    padding: 5px;
-    background-image: @vent-configurable-dropdown;
-    border-bottom: 2px solid @vent-configurable-home-light-border;
-    color: @vent-font-color;
-    position: absolute;
-    top: 60px;
-    right: 480px;
-  }
-
-  .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;
-  }
-
-  .realtime-mode {
-    background-image: var(--image-monitor-realtime);
-  }
-
-  .module-monitor-bar {
-    position: absolute;
-    top: 100px;
-    width: 1000px;
-    height: 200px;
-    left: calc(50% - 500px);
   }
 }
 

+ 2 - 2
src/views/vent/home/configurable/green/components/CustomTable-green.vue

@@ -73,7 +73,7 @@
     padding: 5px 0;
 
     .table__content_label {
-      width: 390px;
+      width: 375px;
       height: 32px;
       display: flex;
       justify-content: space-around;
@@ -112,7 +112,7 @@
 
     .table__content_list {
       height: calc(100% - 32px);
-      width: 390px;
+      width: 375px;
       display: flex;
       flex-direction: column;
       padding: 5px 0;

+ 115 - 62
src/views/vent/home/configurable/green/components/center-area-green.vue

@@ -3,46 +3,46 @@
         <div class="container">
             <div class="risk-score">
                 <div class="item-label">风险得分</div>
-                <div class="item-val">{{ paramData.riskLevel !== undefined && paramData.riskLevel !== null ?
-                    paramData.riskLevel
+                <div class="item-val">{{ paramDatas.riskLevel !== undefined && paramDatas.riskLevel !== null ?
+                    paramDatas.riskLevel
                     : '-' }}</div>
             </div>
             <div class="dust-warn">
                 <div class="dust-icon"></div>
                 <div class="item-content">
                     <div class="ite-label">粉尘监测预警</div>
-                    <div class="ite-val">{{ paramData.fc == 0
+                    <div class="ite-val">{{ paramDatas.fc == 0
                         ? '低风险'
-                        : paramData.fc == 101
+                        : paramDatas.fc == 101
                             ? '低风险'
-                            : paramData.fc == 102
+                            : paramDatas.fc == 102
                                 ? '一般风险'
-                                : paramData.fc == 103
+                                : paramDatas.fc == 103
                                     ? '较大风险'
-                                    : paramData.fc == 104
+                                    : paramDatas.fc == 104
                                         ? '重大风险'
-                                        : paramData.fc == 201
+                                        : paramDatas.fc == 201
                                             ? '报警'
-                                            : paramData.fc }}</div>
+                                            : paramDatas.fc }}</div>
                 </div>
             </div>
             <div class="vent-warn">
                 <div class="vent-icon"></div>
                 <div class="item-content">
                     <div class="ite-label">通风监测预警</div>
-                    <div class="ite-val">{{ paramData.tf == 0
+                    <div class="ite-val">{{ paramDatas.tf == 0
                         ? '低风险'
-                        : paramData.tf == 101
+                        : paramDatas.tf == 101
                             ? '低风险'
-                            : paramData.tf == 102
+                            : paramDatas.tf == 102
                                 ? '一般风险'
-                                : paramData.tf == 103
+                                : paramDatas.tf == 103
                                     ? '较大风险'
-                                    : paramData.tf == 104
+                                    : paramDatas.tf == 104
                                         ? '重大风险'
-                                        : paramData.tf == 201
+                                        : paramDatas.tf == 201
                                             ? '报警'
-                                            : paramData.tf }}</div>
+                                            : paramDatas.tf }}</div>
                 </div>
             </div>
             <div class="gas-warn">
@@ -50,19 +50,19 @@
                 <div class="item-content1">
                     <div class="ite-content">
                         <div class="ite-label">瓦斯监测预警</div>
-                        <div class="ite-val">{{ paramData.ws == 0
+                        <div class="ite-val">{{ paramDatas.ws == 0
                             ? '低风险'
-                            : paramData.ws == 101
+                            : paramDatas.ws == 101
                                 ? '低风险'
-                                : paramData.ws == 102
+                                : paramDatas.ws == 102
                                     ? '一般风险'
-                                    : paramData.ws == 103
+                                    : paramDatas.ws == 103
                                         ? '较大风险'
-                                        : paramData.ws == 104
+                                        : paramDatas.ws == 104
                                             ? '重大风险'
-                                            : paramData.ws == 201
+                                            : paramDatas.ws == 201
                                                 ? '报警'
-                                                : paramData.ws }}</div>
+                                                : paramDatas.ws }}</div>
                     </div>
                     <div class="ite-content">
                         <div class="ite-label">矿井瓦斯等级鉴定</div>
@@ -74,46 +74,65 @@
                 <div class="device-icon"></div>
                 <div class="item-content">
                     <div class="ite-label">设备监测预警</div>
-                    <div class="ite-val">{{ paramData.sb == 0
+                    <div class="ite-val">{{ paramDatas.sb == 0
                         ? '低风险'
-                        : paramData.sb == 101
+                        : paramDatas.sb == 101
                             ? '低风险'
-                            : paramData.sb == 102
+                            : paramDatas.sb == 102
                                 ? '一般风险'
-                                : paramData.sb == 103
+                                : paramDatas.sb == 103
                                     ? '较大风险'
-                                    : paramData.sb == 104
+                                    : paramDatas.sb == 104
                                         ? '重大风险'
-                                        : paramData.sb == 201
+                                        : paramDatas.sb == 201
                                             ? '报警'
-                                            : paramData.sb }}</div>
+                                            : paramDatas.sb }}</div>
                 </div>
             </div>
             <div class="fire-warn">
                 <div class="fire-icon"></div>
                 <div class="item-content">
                     <div class="ite-label">火灾监测预警</div>
-                    <div class="ite-val">{{ paramData.fire == 0
+                    <div class="ite-val">{{ paramDatas.fire == 0
                         ? '低风险'
-                        : paramData.fire == 101
+                        : paramDatas.fire == 101
                             ? '低风险'
-                            : paramData.fire == 102
+                            : paramDatas.fire == 102
                                 ? '一般风险'
-                                : paramData.fire == 103
+                                : paramDatas.fire == 103
                                     ? '较大风险'
-                                    : paramData.fire == 104
+                                    : paramDatas.fire == 104
                                         ? '重大风险'
-                                        : paramData.fire == 201
+                                        : paramDatas.fire == 201
                                             ? '报警'
-                                            : paramData.fire }}</div>
+                                            : paramDatas.fire }}</div>
                 </div>
             </div>
+            <div class="db-warn">
+                <div class="db-icon"></div>
+                <div class="item-content">
+                    <div class="ite-label">顶板</div>
+                    <div class="ite-val">低风险</div>
+                </div>
+            </div>
+            <div class="sz-warn">
+                <div class="sz-icon"></div>
+                <div class="item-content">
+                    <div class="ite-label">水灾</div>
+                    <div class="ite-val">低风险</div>
+                </div>
+            </div>
+            <div class="risk-echartbox">
+                <RiskWarnLevel :echartData="paramDatas.riskData"></RiskWarnLevel>
+            </div>
         </div>
     </div>
 </template>
 
 <script lang="ts" setup>
+import { reactive, watch } from 'vue'
 import { useGlobSetting } from '/@/hooks/setting';
+import RiskWarnLevel from './dz-risk.vue'
 let props = defineProps({
     paramData: {
         type: Object,
@@ -122,8 +141,12 @@ let props = defineProps({
         }
     }
 })
+let paramDatas = reactive<any>({})
 const { sysOrgCode, sysDataType } = useGlobSetting();
 
+watch(() => props.paramData, (newV, oldV) => {
+    paramDatas = newV
+}, { immediate: true, deep: true })
 </script>
 
 <style lang="less" scoped>
@@ -138,6 +161,8 @@ const { sysOrgCode, sysDataType } = useGlobSetting();
         --image-model_gas_warn: url('@/assets/images/themify/deepblue/home-container/configurable/1-3.png');
         --image-model_device_warn: url('@/assets/images/themify/deepblue/home-container/configurable/1-6.png');
         --image-model_fire_warn: url('@/assets/images/themify/deepblue/home-container/configurable/1-4.png');
+        --image-model_db_warn: url('@/assets/images/themify/deepblue/home-container/configurable/db-green.png');
+        --image-model_sz_warn: url('@/assets/images/themify/deepblue/home-container/configurable/sz-green.png');
         --image-model_item_content: url('@/assets/images/themify/deepblue/home-container/configurable/1-8.png');
         --image-model_item_content1: url('@/assets/images/themify/deepblue/home-container/configurable/1-9.png');
     }
@@ -151,6 +176,8 @@ const { sysOrgCode, sysDataType } = useGlobSetting();
     --image-model_gas_warn: url('@/assets/images/home-green/1-3.png');
     --image-model_device_warn: url('@/assets/images/home-green/1-6.png');
     --image-model_fire_warn: url('@/assets/images/home-green/1-4.png');
+    --image-model_db_warn: url('@/assets/images/home-green/db-green.png');
+    --image-model_sz_warn: url('@/assets/images/home-green/sz-green.png');
     --image-model_item_content: url('@/assets/images/home-green/1-8.png');
     --image-model_item_content1: url('@/assets/images/home-green/1-9.png');
     height: 100%;
@@ -158,10 +185,18 @@ const { sysOrgCode, sysDataType } = useGlobSetting();
     .container {
         position: relative;
         width: 100%;
-        height: calc(100% - 25px);
-        margin-top: 25px;
+        height: calc(100% - 30px);
+        margin-top: 30px;
         background: var(--image-model_container_img) no-repeat center;
-        background-size: 95% 100%;
+        background-size: 100% 100%;
+    }
+
+    .risk-echartbox {
+        position: absolute;
+        left: 18px;
+        top: -52px;
+        width: 220px;
+        height: 170px;
     }
 
     .risk-score {
@@ -190,54 +225,74 @@ const { sysOrgCode, sysDataType } = useGlobSetting();
 
     .dust-warn {
         position: absolute;
-        left: 220px;
+        left: 242px;
         top: 52px;
-        width: 120px;
-        height: 106px;
+        width: 132px;
+        height: 108px;
         background: var(--image-model_dust_warn) no-repeat;
         background-size: 100% 100%;
     }
 
     .vent-warn {
         position: absolute;
-        left: 134px;
-        top: 232px;
-        width: 120px;
-        height: 106px;
+        left: 200px;
+        top: 334px;
+        width: 132px;
+        height: 108px;
         background: var(--image-model_vent_warn) no-repeat;
         background-size: 100% 100%;
     }
 
     .gas-warn {
         position: absolute;
-        left: 434px;
-        top: 368px;
-        width: 120px;
-        height: 106px;
+        left: 414px;
+        top: 416px;
+        width: 132px;
+        height: 108px;
         background: var(--image-model_gas_warn) no-repeat;
         background-size: 100% 100%;
     }
 
     .device-warn {
         position: absolute;
-        right: 130px;
-        top: 222px;
-        width: 120px;
-        height: 106px;
+        right: 196px;
+        top: 340px;
+        width: 132px;
+        height: 108px;
         background: var(--image-model_device_warn) no-repeat;
         background-size: 100% 100%;
     }
 
     .fire-warn {
         position: absolute;
-        right: 121px;
-        top: 52px;
-        width: 120px;
-        height: 106px;
+        right: 142px;
+        top: 58px;
+        width: 132px;
+        height: 108px;
         background: var(--image-model_fire_warn) no-repeat;
         background-size: 100% 100%;
     }
 
+    .db-warn {
+        position: absolute;
+        left: 42px;
+        top: 182px;
+        width: 132px;
+        height: 108px;
+        background: var(--image-model_db_warn) no-repeat;
+        background-size: 100% 100%;
+    }
+
+    .sz-warn {
+        position: absolute;
+        right: -2px;
+        top: 136px;
+        width: 132px;
+        height: 108px;
+        background: var(--image-model_sz_warn) no-repeat;
+        background-size: 100% 100%;
+    }
+
     .item-content {
         position: absolute;
         left: -4px;
@@ -261,18 +316,16 @@ const { sysOrgCode, sysDataType } = useGlobSetting();
 
     .ite-label {
         text-align: center;
-        margin-bottom: 8px;
+        margin-bottom: 10px;
         padding-top: 4px;
         font-size: 12px;
     }
 
     .ite-val {
         width: 100%;
-        position: absolute;
         text-align: center;
         font-family: 'douyuFont';
         font-size: 12px;
-        bottom: 2px;
     }
 
     .ite-content {

+ 0 - 3
src/views/vent/home/configurable/green/components/content-green.vue

@@ -88,9 +88,6 @@
         <template v-if="config.name === 'dz_dust'">
           <DzDust :echartOption="config.config" :paramData="config.data"></DzDust>
         </template>
-        <template v-if="config.name === 'dz_risk'">
-          <DzRisk :riskData="config.data"></DzRisk>
-        </template>
         <template v-if="config.name === 'dz_gas'">
           <DzGas :type="config.config.type" :titleData="config.config.titleData" :gasData="config.data"></DzGas>
         </template>

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

@@ -1,185 +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) => {
-    console.log(newV, '火灾---')
-    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>

+ 7 - 15
src/views/vent/home/configurable/green/components/dz-chart.vue

@@ -190,17 +190,17 @@ function getOption() {
                         formatter: (params) => {
                             let text;
                             if (params.dataIndex == 0) {
-                                text = '{a| ' + params.data + '}';
+                                text = '{a| ' + params.data + '}';
                             } else if (params.dataIndex == 1) {
-                                text = '{b| ' + params.data + '}';
+                                text = '{b| ' + params.data + '}';
                             } else if (params.dataIndex == 2) {
-                                text = '{c| ' + params.data + '}';
+                                text = '{c| ' + params.data + '}';
                             } else if (params.dataIndex == 3) {
-                                text = '{d| ' + params.data + '}';
+                                text = '{d| ' + params.data + '}';
                             } else if (params.dataIndex == 4) {
-                                text = '{e| ' + params.data + '}';
+                                text = '{e| ' + params.data + '}';
                             } else {
-                                text = '{f| ' + params.data + '}';
+                                text = '{f| ' + params.data + '}';
                             }
 
                             return text;
@@ -225,7 +225,7 @@ function getOption() {
                                 color: "#fff"
                             },
                         },
-                        position: [330, -12],
+                        position: [350, -12],
                         show: true
                     }
                 },
@@ -277,18 +277,10 @@ function getOption() {
 
 }
 
-
-
-
-
-
-
 watch(() => props.echartData, (newV, oldV) => {
-  console.log(newV,'99900')
   if(newV.length){
     category.value=newV
     echartY.value=newV.map((el:any)=>el.value)
-    console.log(echartY.value,'900')
     getOption()
   }
 }, { immediate: true,  })

+ 21 - 2
src/views/vent/home/configurable/green/components/dz-dust.vue

@@ -94,7 +94,7 @@ function getOption() {
                 trigger: 'item',
             },
             grid: {
-                top: "8%",
+                top: "12%",
                 left: "5%",
                 right: "5%",
                 bottom: "5%",
@@ -236,6 +236,26 @@ function getOption() {
                     },
                     data: yData.value,
                 },
+                {
+                    type: "bar",
+                    label: {
+                        normal: {
+                            show: true,
+                            position: "top",
+                            formatter: (e) => {
+                                return e.value + "次";
+                            },
+                            fontSize: 12,
+                           color:'#fff',
+                            offset: [0, -6],
+                        },
+                    },
+                    itemStyle: {
+                        color: "transparent",
+                    },
+                    tooltip: {},
+                    data: yData.value,
+                },
             ],
         };
         myChart.setOption(option);
@@ -246,7 +266,6 @@ function getOption() {
 }
 
 watch(() => props.paramData, (newV, oldV) => {
-    console.log(newV, '粉尘---')
     xData.value = newV.map((el: any) => el.name)
     yData.value = newV.map((el: any) => el.value)
     getOption()

Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden.