Просмотр исходного кода

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

lxh 1 день назад
Родитель
Сommit
2c92d21d64
36 измененных файлов с 1772 добавлено и 347 удалено
  1. BIN
      src/assets/images/vent/homeNew/Alarm.png
  2. BIN
      src/assets/images/vent/homeNew/Bottom-left.png
  3. BIN
      src/assets/images/vent/homeNew/Bottom_right.png
  4. BIN
      src/assets/images/vent/homeNew/Top-left.png
  5. BIN
      src/assets/images/vent/homeNew/jihua.png
  6. BIN
      src/assets/images/vent/homeNew/warn-dot.png
  7. BIN
      src/assets/images/vent/homeNew/warn_icon_1.png
  8. BIN
      src/assets/images/vent/homeNew/warn_icon_2.png
  9. BIN
      src/assets/images/vent/homeNew/warn_icon_3.png
  10. BIN
      src/assets/images/vent/homeNew/warn_icon_4.png
  11. BIN
      src/assets/images/vent/homeNew/zonghui.png
  12. BIN
      src/assets/images/vent/homeNew/zongjin.png
  13. 1 0
      src/design/theme.less
  14. 1 0
      src/design/themify/dark.less
  15. 1 0
      src/design/themify/deepblue.less
  16. 4 0
      src/design/themify/default.less
  17. 3 14
      src/design/themify/light.less
  18. 2 2
      src/layouts/default/header/components/VoiceBroadcast.vue
  19. 11 6
      src/views/vent/home/colliery/index.vue
  20. 78 0
      src/views/vent/home/configurable/components/ModuleNew.vue
  21. 250 246
      src/views/vent/home/configurable/components/content.vue
  22. 110 0
      src/views/vent/home/configurable/components/detail/TimelineListNew.vue
  23. 94 0
      src/views/vent/home/configurable/components/originalNew/moduleBottom.vue
  24. 97 0
      src/views/vent/home/configurable/components/originalNew/moduleLeft.vue
  25. 66 55
      src/views/vent/home/configurable/configurable.api.ts
  26. 518 0
      src/views/vent/home/configurable/configurable.data.ts
  27. 6 0
      src/views/vent/home/configurable/hooks/useInit.ts
  28. 157 0
      src/views/vent/home/configurable/ventNew.vue
  29. 304 0
      src/views/vent/home/configurable/ventSDG.vue
  30. 2 4
      src/views/vent/monitorManager/balancePressMonitor/balancePress.threejs.ts
  31. 47 10
      src/views/vent/monitorManager/balancePressMonitor/components/balancePressHome1.vue
  32. 7 1
      src/views/vent/monitorManager/balancePressMonitor/index1.vue
  33. 1 2
      src/views/vent/monitorManager/balancePressMonitor/index2.vue
  34. 1 1
      src/views/vent/monitorManager/comment/HistoryTable.vue
  35. 1 1
      src/views/vent/monitorManager/comment/MonitorTable.vue
  36. 10 5
      src/views/vent/monitorManager/sensorMonitor/index.vue

BIN
src/assets/images/vent/homeNew/Alarm.png


BIN
src/assets/images/vent/homeNew/Bottom-left.png


BIN
src/assets/images/vent/homeNew/Bottom_right.png


BIN
src/assets/images/vent/homeNew/Top-left.png


BIN
src/assets/images/vent/homeNew/jihua.png


BIN
src/assets/images/vent/homeNew/warn-dot.png


BIN
src/assets/images/vent/homeNew/warn_icon_1.png


BIN
src/assets/images/vent/homeNew/warn_icon_2.png


BIN
src/assets/images/vent/homeNew/warn_icon_3.png


BIN
src/assets/images/vent/homeNew/warn_icon_4.png


BIN
src/assets/images/vent/homeNew/zonghui.png


BIN
src/assets/images/vent/homeNew/zongjin.png


+ 1 - 0
src/design/theme.less

@@ -133,6 +133,7 @@ html[data-theme='light'] {
 @vent-device-manager-control-btn: var(--vent-device-manager-control-btn);
 @vent-device-manager-control-btn-hover: var(--vent-device-manager-control-btn-hover);
 
+
 // 下面的代码负责将主题相关的选择器、图片前缀等 less 变量声明
 @theme-dark: ~"html[data-theme='dark2']";
 @theme-light: ~"html[data-theme='light']";

+ 1 - 0
src/design/themify/dark.less

@@ -49,4 +49,5 @@ html[data-theme='dark2'] {
   --vent-warn-tab-bg: #0f376ccc;
   --vent-warn-tab-border: #166ab5;
   --vent-warn-tab-bg-actived: #209dfc;
+
 }

+ 1 - 0
src/design/themify/deepblue.less

@@ -63,4 +63,5 @@ html[data-theme='deepblue'] {
   --vent-warn-tab-bg: #0f376c;
   --vent-warn-tab-border: #107eec;
   --vent-warn-tab-bg-actived: #0963c1;
+
 }

+ 4 - 0
src/design/themify/default.less

@@ -62,4 +62,8 @@ html {
   --vent-warn-tab-bg: #0f376ccc;
   --vent-warn-tab-border: #166ab5;
   --vent-warn-tab-bg-actived: #209dfc;
+
+  --vent-balancePress-fan-bg-default: linear-gradient( to right, #071D3C22, #035EA266);
+  --vent-balancePress-fan-bg-select: linear-gradient(to right, #21A6CE99, #052d3d99);
+
 }

+ 3 - 14
src/design/themify/light.less

@@ -1,40 +1,32 @@
 html[data-theme='light'] {
   --vent-primary-color: #1580cc;
-
   --vent-header-bg-color: linear-gradient(#005177, #0a344c);
-
   --vent-btn-primary-hover-color: #389bd9;
   --vent-btn-primary-focus-color: #1c638a99;
   --vent-btn-primary-color: #1c638a;
   --vent-btn-primary-border-color: #56b3c96b;
-
   --vent-table-thead: #3d9dd45d;
   --vent-table-thead-border: #91e9fe;
   --vent-table-hover: #0dc3ff22;
   --vent-table-no-hover: #00bfff10;
   --vent-table-action-link: #00e7ff;
-
   --vent-modal-title: #39e9fe;
   --vent-modal-border: #04bdaa;
   --vent-modal-bg: #0042ab22;
   --vent-modal-box-shadow: #2b87ff;
   --vent-modal-bg2: linear-gradient(#2cd1ff55, #1eb0ff55);
-
   --vent-tabs-bg: linear-gradient(#0091aa33, #2081ff11);
   --vent-tabs-table-thead: #3d9dd433;
   --vent-tabs-action-link: #28f3f3;
-
   --vent-form-item-border: #3ad8ff77;
-
   --vent-text-base: #ddd;
   --vent-base-color: #09172c;
   --vent-base-border: #5cfaff;
   --vent-base-light-bg: #60f4ff;
   --vent-base-light-bg-opcity: #60f4ff55;
-  --vent-transparent: #ffffff00;
-  --vent-font-color: #ffffff;
+  --vent-transparent: #fff0;
+  --vent-font-color: #fff;
   --vent-font-action-link: #7af5ff;
-
   --vent-configurable-bg: #09316a;
   --vent-configurable-module-bg: #3df6ff11;
   --vent-configurable-original-module-bg: #3df6ff15;
@@ -43,7 +35,6 @@ html[data-theme='light'] {
   --vent-configurable-home-bg-img: linear-gradient(to top, #39a3ff00, #0091ff99);
   --vent-configurable-home-timeline: linear-gradient(to top, #39a3ff00, #0091ff99, #39a3ff00);
   --vent-configurable-home-light-border: #3df6ff;
-
   --vent-gas-list-item-bg-img: linear-gradient(to right, #39a3ff55, #3977e500);
   --vent-gas-tab-bg: #10427a;
   --vent-gas-tab-bg-avtived: #166ab5;
@@ -51,12 +42,10 @@ html[data-theme='light'] {
   --vent-gas-primary-text: #00c8d9;
   --vent-gas-primary-bg: #1673bf;
   --vent-gas-primary-trasparent-bg: #0091ff12;
-
   --vent-device-manager-box-border: #44d3ff70;
-  --vent-device-manager-box-bg: #ffffff11;
+  --vent-device-manager-box-bg: #fff1;
   --vent-device-manager-control-btn: linear-gradient(#1fa6cb, #127cb5);
   --vent-device-manager-control-btn-hover: linear-gradient(#2cd1ff55, #1eb0ff55);
-
   --vent-warn-tab-bg: #0f376ccc;
   --vent-warn-tab-border: #166ab5;
   --vent-warn-tab-bg-actived: #209dfc;

+ 2 - 2
src/layouts/default/header/components/VoiceBroadcast.vue

@@ -91,14 +91,14 @@ export default defineComponent({
     }
 
     async function clearInfo() {
-      cleanAlarm();
+      await cleanAlarm();
       const res = await list({ pageSize: 20, devicetype: '', sort: 'createTime', delFlag: 0 });
       broadcastList.value = res['records'];
     }
 
     async function toSelectList(key) {
       activeKey.value = key;
-      const res = await list({ pageSize: 20, devicetype: '', isok: key == 1 ? 0 : key == 2 ? 1 : null, sort: 'createTime' });
+      const res = await list({ pageSize: 20, devicetype: '', isok: key == 1 ? 0 : key == 2 ? 1 : null, sort: 'createTime', delFlag: 0 });
       broadcastList.value = res['records'];
       const isHasWarning = broadcastList.value.findIndex((item) => !item['isok']);
       if (key !== 2) isWarningDot.value = isHasWarning > -1 ? true : false;

+ 11 - 6
src/views/vent/home/colliery/index.vue

@@ -34,10 +34,12 @@
                 <div class="nav-item" v-if="(item.valList && item.valList.length > 0) || item.val">
                   <div class="item-label">{{ item.name }}</div>
                   <div class="item-value">
-                    <div v-if="item.isShow" class="bg-box" v-for="(ite, ind) in item.valList" :key="ind">
-                      <div class="box-line"></div>
-                      <div class="value-text">{{ ite.val }}</div>
-                    </div>
+                    <template v-if="item.isShow">
+                      <div class="bg-box" v-for="(ite, ind) in item.valList" :key="ind">
+                        <div class="box-line"></div>
+                        <div class="value-text">{{ ite.val }}</div>
+                      </div>
+                    </template>
                     <div v-else class="value-text1">{{ item.val }}</div>
                   </div>
                 </div>
@@ -136,7 +138,6 @@
   const centerModalRef = ref();
   const fullModalRef = ref();
 
-  const globSetting = useGlobSetting();
   const pageType = ref('');
   let router = useRouter();
   const pageResult = ref({});
@@ -164,7 +165,6 @@
 
   function getList() {
     list({}).then((res) => {
-      console.log(res, 'res-----------');
       fanLocalList.length = 0;
       fanLocalList.push(res.fanlocal);
       mainList.value = res.fanmain || [];
@@ -225,6 +225,11 @@
       }
       warnData.value = res.warn || [];
       deviceData.value = res.device || {};
+
+      // 大海则不需要漏风率
+      if (sysOrgCode === 'sdtljtdhzmk') {
+        navList[4].val = 0;
+      }
     });
   }
 

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

@@ -0,0 +1,78 @@
+<template>
+  <!-- 原版模块 -->
+  <component
+    :is="getModuleComponent(showStyle)"
+    :style="style"
+    :title="moduleName"
+    :visible="visible"
+    :class="{ 'cursor-pointer': !!moduleData.to }"
+    @close="$emit('close')"
+    @click="redirectTo"
+    class="component-module"
+  >
+    <slot>
+      <Header :deviceType="deviceType" :moduleData="moduleData" :data="data" @select="selectedData = $event" />
+      <Content :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 Content from './content.vue';
+import ModuleLeft from './originalNew/moduleLeft.vue';
+import ModuleBottom from './originalNew/moduleBottom.vue';
+import { computed, ref } from 'vue';
+import { openWindow } from '/@/utils';
+import { getFormattedText } from '../hooks/helper';
+// import { ModuleProps } from '../types';
+
+const props = defineProps<{
+  /** 配置的详细模块信息 */
+  moduleData: any;
+  /** 配置的详细样式信息 */
+  showStyle: any;
+  /** 该模块配置中的设备标识符 */
+  deviceType: string;
+  /** api返回的数据 */
+  data: any;
+  moduleName: string;
+  visible: boolean;
+}>();
+defineEmits(['close', 'click']);
+
+const { header } = props.moduleData;
+const selectedData = ref();
+
+const style = computed(() => {
+  const size = props.showStyle.size;
+  const position = props.showStyle.position;
+  return size + position;
+});
+
+// 根据配置里的定位判断应该使用哪个module组件
+function getModuleComponent({ size, position }) {
+  const [_, width] = size.match(/width:([0-9]+)px/) || [];
+  if (position.includes('bottom') || parseInt(width) > 800) {
+    return ModuleBottom;
+  }
+  if (position.includes('left')) {
+    return ModuleLeft;
+  }
+  if (position.includes('right')) {
+    return ModuleLeft;
+  }
+  return ModuleBottom;
+}
+
+function redirectTo() {
+  const { to } = props.moduleData;
+  if (!to) return;
+  openWindow(getFormattedText(selectedData.value, to));
+}
+</script>
+<style scoped>
+.component-module {
+  background: url('@/assets/images/vent/homeNew/leftContent.png') no-repeat;
+  background-size: 100% 100%;
+}
+</style>>

+ 250 - 246
src/views/vent/home/configurable/components/content.vue

@@ -41,6 +41,9 @@
           <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>
@@ -93,283 +96,284 @@
   </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 CustomList from './detail/CustomList.vue';
-  import CustomGallery from './detail/CustomGallery.vue';
-  import ComplexList from './detail/ComplexList.vue';
-  import GalleryList from './detail/GalleryList.vue';
-  import CustomTable from './detail/CustomTable.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 AIChat from '/@/components/AIChat/MiniChat.vue';
-  import DeviceAlarm from './preset/DeviceAlarm.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 GalleryList from './detail/GalleryList.vue';
+import CustomTable from './detail/CustomTable.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 AIChat from '/@/components/AIChat/MiniChat.vue';
+import DeviceAlarm from './preset/DeviceAlarm.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) => {
+    return {
+      ...i,
+      label: getFormattedText(raw, i.label, i.trans),
+      value: getFormattedText(raw, i.value, i.trans),
+    };
+  });
+}
 
-  // 获取当原始配置带 items 项时的最终 items 配置
-  function getItems(raw, items: CommonItem[]) {
-    return items.map((i) => {
+// 获取当 List 组件配置带 items 项时的最终 items 配置
+function getListItems(raw: any, items: CommonItem[], mapFromData?: boolean) {
+  if (mapFromData && Array.isArray(raw)) {
+    return raw.map((data) => {
+      const item = items[0];
       return {
-        ...i,
-        label: getFormattedText(raw, i.label, i.trans),
-        value: getFormattedText(raw, i.value, i.trans),
+        ...item,
+        label: getFormattedText(data, item.label, item.trans),
+        value: getFormattedText(data, item.value, item.trans),
       };
     });
   }
+  return getItems(raw, items);
+}
 
-  // 获取当 List 组件配置带 items 项时的最终 items 配置
-  function getListItems(raw: any, items: CommonItem[], mapFromData?: boolean) {
-    if (mapFromData && Array.isArray(raw)) {
-      return raw.map((data) => {
-        const item = items[0];
-        return {
-          ...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 chart = clone(props.moduleData.chart) || [];
+  const table = clone(props.moduleData.table) || [];
+  const preset = clone(props.moduleData.preset) || [];
 
-  /** 根据配置里的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 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);
 
-    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: 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: 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: getItems(data, cfg.items),
+            items: (data || []).map((d) => {
+              return {
+                title: getFormattedText(d, firstListItem.title),
+                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),
-                  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),
-                  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),
+                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 'gallery_list': {
+        const cfg = gallery_list.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({
+          overflow: true,
+          ...item,
+          ...cfg,
+          items: getItems(data, cfg.items),
+          galleryItems: getItems(data, cfg.galleryItems),
+        });
+        break;
+      }
+      case 'chart': {
+        const cfg = chart.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,
+          config: cfg,
+          data,
+        });
+        break;
+      }
+      case 'table': {
+        const cfg = table.shift();
+        if (!cfg) break;
+        const data = getData(refData, cfg.readFrom, cfg.parser);
 
-          arr.push({
-            ...item,
-            data,
-            config: cfg,
-          });
-          break;
-        }
+        arr.push({
+          ...cfg,
+          ...item,
+          columns: cfg.columns,
+          data,
+        });
+        break;
       }
-      return arr;
-    }, []);
-  });
+      default: {
+        const cfg = preset.shift();
+        if (!cfg) break;
+        const data = getData(refData, cfg.readFrom, cfg.parser);
+
+        arr.push({
+          ...item,
+          data,
+          config: cfg,
+        });
+        break;
+      }
+    }
+    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;
-  }
-  .content__module {
-    // margin-top: 5px;
-    // margin-bottom: 5px;
-    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;
-  }
+.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;
+}
+.content__module {
+  // margin-top: 5px;
+  // margin-bottom: 5px;
+  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;
-  }
+: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>

+ 110 - 0
src/views/vent/home/configurable/components/detail/TimelineListNew.vue

@@ -0,0 +1,110 @@
+<!-- eslint-disable vue/multi-word-component-names -->
+<template>
+  <div class="timeline">
+    <div v-for="item in listConfig" :key="item.prop" class="flex items-center timeline-item">
+      <div class="timeline-item__icon" :class="`timeline-item__icon_${item.color}`"></div> <div class="timeline-item__dot"></div>
+      <div class="timeline-item__label">{{ item.label }}</div>
+      <div :class="`timeline-item__value_${item.color}`">
+        {{ item.value }}
+      </div>
+    </div>
+    <div class="timeline-item__dot"></div>
+  </div>
+</template>
+<script lang="ts" setup>
+withDefaults(
+  defineProps<{
+    listConfig: {
+      value: string;
+      color: string;
+      label: string;
+      prop: string;
+    }[];
+  }>(),
+  {
+    listConfig: () => [],
+  }
+);
+</script>
+<style lang="less" scoped>
+@import '/@/design/theme.less';
+@import '@/design/theme.less';
+/* Timeline 相关的样式 */
+
+@{theme-deepblue} {
+  .timeline-item {
+    --image-warn_icon_4: url('/@/assets/images/vent/homeNew/warn_icon_1.png');
+    --image-warn_icon_3: url('/@/assets/images/vent/homeNew/warn_icon_2.png');
+    --image-warn_icon_2: url('/@/assets/images/vent/homeNew/warn_icon_3.png');
+    --image-warn_icon_1: url('/@/assets/images/vent/homeNew/warn_icon_4.png');
+  }
+}
+
+.timeline-item {
+  --image-warn_icon_4: url('/@/assets/images/vent/homeNew/warn_icon_1.png');
+  --image-warn_icon_3: url('/@/assets/images/vent/homeNew/warn_icon_2.png');
+  --image-warn_icon_2: url('/@/assets/images/vent/homeNew/warn_icon_3.png');
+  --image-warn_icon_1: url('/@/assets/images/vent/homeNew/warn_icon_4.png');
+  height: 20%;
+}
+.timeline-item__icon_red {
+  background-image: var(--image-warn_icon_4);
+}
+.timeline-item__icon_orange {
+  background-image: var(--image-warn_icon_3);
+}
+.timeline-item__icon_yellow {
+  background-image: var(--image-warn_icon_2);
+}
+.timeline-item__icon_blue {
+  background-image: var(--image-warn_icon_1);
+}
+.timeline-item__icon {
+  width: 33px;
+  height: 35px;
+  margin-left: 50px;
+  background-repeat: no-repeat;
+  background-position: center center;
+}
+.timeline-item__dot {
+  width: 10px;
+  height: 10px;
+  margin-left: 70px;
+  border-radius: 5px;
+  position: relative;
+}
+.timeline-item__label {
+  width: 100px;
+  margin-left: 70px;
+}
+.timeline-item__value_red {
+  color: red;
+}
+.timeline-item__value_orange {
+  color: orange;
+}
+.timeline-item__value_yellow {
+  color: yellow;
+}
+.timeline-item__value_green {
+  color: yellowgreen;
+}
+.timeline-item__value_blue {
+  color: lightblue;
+}
+
+.timeline {
+  height: 220px;
+  padding: 5px;
+  position: relative;
+}
+.timeline-component {
+  position: absolute;
+  width: 2px;
+  height: 180px;
+  top: 20px;
+  left: 162px;
+  background-image: url('/@/assets/images/vent/homeNew/warn-dot.png') no-repeat;
+  background-size: 100% 100%;
+}
+</style>

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

@@ -0,0 +1,94 @@
+<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_expand: url('@/assets/images/themify/deepblue/home-container/configurable/model_original_title_bg_expand.png');
+    }
+  }
+
+  .module-content {
+    --image-model_original_title_bg_expand: url('@/assets/images/home-container/configurable/model_original_title_bg_expand.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_expand) 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_bottom_title_bg.png') no-repeat;
+  //   background-size: 100% 100%;
+  //   position: relative;
+  //   text-align: left;
+  //   padding-left: 5%;
+  // }
+
+  // 固定在父容器右上角的按钮图标
+  // .action-btn {
+  //   width: 18px;
+  //   height: 18px;
+  //   background: url('../../../../../assets/images/home-container/configurable/expand.svg') no-repeat center;
+  //   position: absolute;
+  //   left: 0;
+  //   top: 0;
+  // }
+  // .show-btn {
+  //   transform: rotate(-90deg);
+  // }
+
+  .module-slot {
+    height: calc(100% - 33px);
+    width: calc(100% - 15px);
+    backdrop-filter: blur(5px);
+    background-color: var(--vent-configurable-original-module-bg);
+    margin-left: 5px;
+  }
+
+  // Transition动画相关
+  .v-enter-active,
+  .v-leave-active {
+    transition: all 0.3s ease;
+  }
+
+  .v-enter-from,
+  .v-leave-to {
+    opacity: 0;
+    transform: translateY(-33px);
+  }
+</style>

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

@@ -0,0 +1,97 @@
+<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);
+  // #182d47
+  background-color: var(--vent-configurable-original-module-bg);
+  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>

+ 66 - 55
src/views/vent/home/configurable/configurable.api.ts

@@ -29,62 +29,73 @@ export const list = (params) => {
     );
   }
   return (cache.get(key) as Promise<any>).then((res) => {
-    res.fanmain.forEach((e) => {
-      if (e.readData.Fan2StartStatus === '1') {
-        e.current = '二号';
-        e.readData.FanFreqHz = e.readData.Fan2FreqHz;
-      } else {
-        e.current = '一号';
-        e.readData.FanFreqHz = e.readData.Fan1FreqHz;
-      }
-    });
-    res.fanlocal.forEach((e) => {
-      e.chartData = [
-        {
-          x: '吸风量',
-          yRealtime: e.readData.windQuantity1,
-          yMock: floor(parseFloat(e.inletAirVolume_merge) * random(0.98, 1, false), 2),
-          y: e.inletAirVolume_merge,
-        },
-        {
-          x: '供风量',
-          yRealtime: e.readData.windQuantity2,
-          yMock: floor(parseFloat(e.ductOutletAirVolume_merge) * random(0.98, 1, false), 2),
-          y: e.ductOutletAirVolume_merge,
-        },
-      ];
-      if (e.readData.Fan2StartStatus === '1') {
-        e.current = '二号';
-        e.readData.FanfHz = e.readData.Fan2fHz;
-      } else {
-        e.current = '一号';
-        e.readData.FanfHz = e.readData.Fan1fHz;
-      }
-    });
-    res.sys_majorpath.forEach((e) => {
-      const { drag_1, drag_2, drag_3, drag_total } = e.majorpath;
-      const { fy_merge = { value: '1' } } = e.readData;
-      const drag_merge = parseInt(fy_merge.value);
-      // const m3_merge = parseInt(retM3_merge.value);
+    if (res.fanmain) {
+      // 处理频率字段,为了兼容旧版保留,现配置项已支持一级动态字段
+      res.fanmain.forEach((e) => {
+        if (e.readData.Fan2StartStatus === '1') {
+          e.current = '二号';
+          e.readData.FanFreqHz = e.readData.Fan2FreqHz;
+        } else {
+          e.current = '一号';
+          e.readData.FanFreqHz = e.readData.Fan1FreqHz;
+        }
+      });
+    }
+    if (res.fanlocal) {
+      res.fanlocal.forEach((e) => {
+        e.chartData = [
+          {
+            x: '吸风量',
+            yRealtime: e.readData.windQuantity1,
+            yMock: floor(parseFloat(e.inletAirVolume_merge) * random(0.98, 1, false), 2),
+            y: e.inletAirVolume_merge,
+          },
+          {
+            x: '供风量',
+            yRealtime: e.readData.windQuantity2,
+            yMock: floor(parseFloat(e.ductOutletAirVolume_merge) * random(0.98, 1, false), 2),
+            y: e.ductOutletAirVolume_merge,
+          },
+        ];
+        if (e.readData.Fan2StartStatus === '1') {
+          e.current = '二号';
+          e.readData.FanfHz = e.readData.Fan2fHz;
+        } else {
+          e.current = '一号';
+          e.readData.FanfHz = e.readData.Fan1fHz;
+        }
+      });
+    }
+    if (res.sys_majorpath) {
+      res.sys_majorpath.forEach((e) => {
+        const { drag_1, drag_2, drag_3, drag_total } = e.majorpath;
+        const { fy_merge = { value: '1' } } = e.readData;
+        const drag_merge = parseInt(fy_merge.value);
+        // const m3_merge = parseInt(retM3_merge.value);
 
-      e.piechart = [
-        { val: drag_1, valMock: floor((drag_1 / drag_total) * drag_merge), label: '进风区(Pa)' },
-        { val: drag_2, valMock: floor((drag_2 / drag_total) * drag_merge), label: '用风区(Pa)' },
-        { val: drag_3, valMock: floor((drag_3 / drag_total) * drag_merge), label: '回风区(Pa)' },
-      ];
-      e.readData.dengjikong_merge = get(res, 'midinfo[0].sysinfo.equalarea');
-      e.readData.fy_merge_int = drag_merge;
-      // e.dengjikong_merge = floor((1.19 * (m3_merge / 60)) / Math.sqrt(drag_merge), 2);
-    });
-    res.sys_surface_caimei.forEach((e) => {
-      if (isArray(e.history)) {
-        e.history = slice(e.history, e.history.length - 30, e.history.length);
-      }
-      if (isArray(e.history_report)) {
-        e.history_report = slice(e.history_report, e.history_report.length - 30, e.history_report.length);
-      }
-    });
-    res.device_arr = Object.values(res.device);
+        e.piechart = [
+          { val: drag_1, valMock: floor((drag_1 / drag_total) * drag_merge), label: '进风区(Pa)' },
+          { val: drag_2, valMock: floor((drag_2 / drag_total) * drag_merge), label: '用风区(Pa)' },
+          { val: drag_3, valMock: floor((drag_3 / drag_total) * drag_merge), label: '回风区(Pa)' },
+        ];
+        e.readData.dengjikong_merge = get(res, 'midinfo[0].sysinfo.equalarea');
+        e.readData.fy_merge_int = drag_merge;
+        // e.dengjikong_merge = floor((1.19 * (m3_merge / 60)) / Math.sqrt(drag_merge), 2);
+      });
+    }
+    if (res.sys_surface_caimei) {
+      res.sys_surface_caimei.forEach((e) => {
+        if (isArray(e.history)) {
+          e.history = slice(e.history, e.history.length - 30, e.history.length);
+        }
+        if (isArray(e.history_report)) {
+          e.history_report = slice(e.history_report, e.history_report.length - 30, e.history_report.length);
+        }
+      });
+    }
+    if (res.device_arr) {
+      res.device_arr = Object.values(res.device);
+    }
 
     return res;
   });

+ 518 - 0
src/views/vent/home/configurable/configurable.data.ts

@@ -2066,3 +2066,521 @@ export const testConfigVentRealtime: Config[] = [
 //     position: 'top:350px;left:0;',
 //   },
 // },
+export const testConfigVentNew: Config[] = [
+  {
+    deviceType: 'fanmain',
+    moduleName: '主通风机系统',
+    pageType: 'vent',
+    moduleData: {
+      header: {
+        show: true,
+        readFrom: '',
+        selector: {
+          show: true,
+          value: '${strinstallpos}',
+        },
+        slot: {
+          show: true,
+          value: '运行风机:${readData.Fan1StartStatus}',
+          trans: {
+            '1': '一号',
+            '0': '二号',
+          },
+        },
+      },
+      background: {
+        show: false,
+        type: 'image',
+        link: '',
+      },
+      layout: {
+        direction: 'column',
+        items: [
+          {
+            name: 'qh_curve',
+            basis: '67%',
+          },
+          {
+            name: 'board',
+            basis: '33%',
+          },
+        ],
+      },
+      board: [
+        {
+          type: 'D',
+          readFrom: '',
+          layout: 'label-top',
+          items: [
+            {
+              label: '风量(m³/min)',
+              value: '${flow_merge}',
+            },
+            {
+              label: '负压(Pa)',
+              value: '${fy_merge}',
+            },
+            {
+              label: '漏风率(%)',
+              value: '${leakage}',
+            },
+          ],
+        },
+      ],
+      list: [],
+      chart: [],
+      table: [],
+      gallery: [],
+      complex_list: [],
+      gallery_list: [],
+      preset: [
+        {
+          readFrom: '',
+          fan1Prop: ['flow_merge', 'fy_merge'],
+          fan2Prop: ['flow_merge', 'fy_merge'],
+        },
+      ],
+      to: '/micro-vent-3dModal/dashboard/analysis?type=tunMonitor&deviceType=fanmain',
+    },
+    showStyle: {
+      size: 'width:377px;height:280px;',
+      version: '新版',
+      position: 'top:60px;left:0;',
+    },
+  },
+  {
+    deviceType: '',
+    moduleName: '通风设施远程控制',
+    pageType: 'vent',
+    moduleData: {
+      header: {
+        show: false,
+        readFrom: '',
+        selector: {
+          show: false,
+          value: '',
+        },
+        slot: {
+          show: false,
+          value: '',
+        },
+      },
+      background: {
+        // show: true,
+        show: false,
+        type: 'video',
+        link: '/video/gate.mp4',
+      },
+      layout: {
+        direction: 'row',
+        items: [
+          {
+            name: 'device_alarm',
+            basis: '100%',
+          },
+        ],
+      },
+      board: [],
+      list: [],
+      chart: [],
+      table: [],
+      gallery: [],
+      complex_list: [],
+      gallery_list: [],
+      preset: [
+        {
+          readFrom: 'device',
+        },
+      ],
+      to: '/micro-vent-3dModal/dashboard/analysis?type=tunMonitor&deviceType=gate_xinJianFuXieJin',
+    },
+    showStyle: {
+      size: 'width:377px;height:280px;',
+      version: '新版',
+      position: 'top:350px;left:0;',
+    },
+  },
+  {
+    deviceType: 'warn',
+    moduleName: '预警监测',
+    pageType: 'vent_realtime',
+    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',
+            basis: '100%',
+          },
+        ],
+      },
+      board: [],
+      list: [
+        {
+          type: 'timelineNew',
+          readFrom: 'warn[0]',
+          items: [
+            {
+              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: [],
+      table: [],
+      gallery: [],
+      chart: [],
+      gallery_list: [],
+      complex_list: [],
+      to: '/monitorChannel/monitor-alarm-home',
+    },
+    showStyle: {
+      size: 'width:377px;height:280px;',
+      version: '新版',
+      position: 'top:640px;left:0;',
+    },
+  },
+  {
+    deviceType: 'fanlocal',
+    moduleName: '局部通风机系统',
+    pageType: 'vent',
+    moduleData: {
+      header: {
+        show: true,
+        readFrom: '',
+        selector: {
+          show: true,
+          value: '${strinstallpos}',
+        },
+        slot: {
+          show: false,
+          value: '运行风机:${readData.Fan1StartStatus}',
+          trans: {
+            '1': '一号',
+            '0': '二号',
+          },
+        },
+      },
+      background: {
+        show: false,
+        type: 'image',
+        link: '',
+      },
+      layout: {
+        direction: 'column',
+        items: [
+          {
+            name: 'chart',
+            basis: '100%',
+          },
+        ],
+      },
+      board: [],
+      list: [],
+      chart: [
+        {
+          type: 'bar_cylinder_wide',
+          readFrom: '',
+          legend: { show: false },
+          xAxis: [{ show: true }],
+          yAxis: [{ show: true, name: '(m³/min)', position: 'left' }],
+          series: [{ readFrom: 'chartData', xprop: 'x', yprop: 'y', label: '风量' }],
+        },
+      ],
+      table: [],
+      gallery: [],
+      complex_list: [],
+      gallery_list: [],
+      preset: [],
+      to: '/micro-vent-3dModal/dashboard/analysis?type=tunMonitor&deviceType=fanlocal',
+    },
+    showStyle: {
+      size: 'width:377px;height:280px;',
+      version: '原版',
+      position: 'top:60px;right:0;',
+    },
+  },
+
+  {
+    deviceType: 'sys_majorpath',
+    moduleName: '关键通风路线',
+    pageType: 'vent',
+    moduleData: {
+      header: {
+        show: true,
+        readFrom: '',
+        selector: {
+          show: true,
+          value: '${devicePos}',
+        },
+        slot: {
+          show: false,
+          value: '',
+        },
+      },
+      background: {
+        show: false,
+        type: 'video',
+        link: '',
+      },
+      layout: {
+        direction: 'column',
+        items: [
+          {
+            name: 'chart',
+            basis: '67%',
+          },
+          {
+            name: 'board',
+            basis: '33%',
+          },
+        ],
+      },
+      board: [
+        {
+          type: 'D',
+          readFrom: 'readData',
+          layout: 'label-top',
+          items: [
+            {
+              label: '风量(m³/min)',
+              value: '${retM3_merge.value}',
+            },
+            {
+              label: '矿井阻力(Pa)',
+              value: '${fy_merge.value}',
+            },
+            {
+              label: '等积孔',
+              value: '${dengjikong_merge}',
+            },
+          ],
+        },
+      ],
+      complex_list: [],
+      gallery: [],
+      list: [],
+      table: [],
+      chart: [
+        {
+          type: 'pie_halo',
+          readFrom: '',
+          legend: { show: false, formatter: '{b}:{c}\n{d}%' },
+          xAxis: [{ show: false }],
+          yAxis: [{ show: false, name: '风量', position: 'left' }],
+          series: [{ readFrom: 'piechart', xprop: 'label', yprop: 'valMock', label: '' }],
+        },
+      ],
+      gallery_list: [],
+      preset: [],
+      to: '/micro-vent-3dModal/dashboard/analysis?type=tunMonitor&deviceType=sys_majorpath&deviceid=${deviceID}',
+    },
+    showStyle: {
+      size: 'width:377px;height:280px;',
+      version: '新版',
+      position: 'top:350px;right:0;',
+    },
+  },
+  {
+    deviceType: 'sys_surface_caimei',
+    moduleName: '工作面智能监控',
+    pageType: 'vent',
+    moduleData: {
+      header: {
+        show: true,
+        readFrom: '',
+        selector: {
+          show: true,
+          value: '${devicePos}',
+        },
+        slot: {
+          show: false,
+          value: '',
+        },
+      },
+      background: {
+        show: false,
+        type: 'video',
+        link: '',
+      },
+      layout: {
+        direction: 'column',
+        items: [
+          {
+            name: 'chart',
+            basis: '65%',
+          },
+          {
+            name: 'board',
+            basis: '35%',
+          },
+        ],
+      },
+      board: [
+        {
+          type: 'B',
+          readFrom: '',
+          layout: 'label-top',
+          items: [
+            {
+              label: '进风(m³/min)',
+              value: '${faceIntM3}',
+            },
+            {
+              label: '回风(m³/min)',
+              value: '${faceRetM3}',
+            },
+            {
+              label: '需风量(m³/min)',
+              value: '${facePlanM3}',
+            },
+          ],
+        },
+      ],
+      list: [],
+      preset: [],
+      table: [],
+      gallery: [],
+      chart: [
+        {
+          type: 'line',
+          readFrom: '',
+          legend: { show: true },
+          xAxis: [{ show: true }],
+          yAxis: [{ show: true, name: '风量(m³/min)', position: 'left' }],
+          series: [
+            { readFrom: 'history_report', xprop: 'time', yprop: 'faceIntM3', label: '进风' },
+            { readFrom: 'history_report', xprop: 'time', yprop: 'faceRetM3', label: '回风' },
+          ],
+        },
+      ],
+      gallery_list: [],
+      complex_list: [],
+      to: '/micro-vent-3dModal/dashboard/analysis?type=tunMonitor&deviceType=sys_surface_caimei&deviceid=${deviceID}',
+    },
+    showStyle: {
+      size: 'width:377px;height:280px;',
+      version: '新版',
+      position: 'top:640px;right:0;',
+    },
+  },
+  {
+    deviceType: 'fanmain',
+    moduleName: '主通风机系统',
+    pageType: 'vent',
+    moduleData: {
+      header: {
+        show: true,
+        readFrom: '',
+        selector: {
+          show: true,
+          value: '${strinstallpos}',
+        },
+        slot: {
+          show: true,
+          value: '运行风机:${readData.Fan1StartStatus}',
+          trans: {
+            '1': '一号',
+            '0': '二号',
+          },
+        },
+      },
+      background: {
+        show: false,
+        type: 'image',
+        link: '',
+      },
+      layout: {
+        direction: 'column',
+        items: [
+          {
+            name: 'qh_curve',
+            basis: '67%',
+          },
+          {
+            name: 'board',
+            basis: '33%',
+          },
+        ],
+      },
+      board: [
+        {
+          type: 'D',
+          readFrom: '',
+          layout: 'label-top',
+          items: [
+            {
+              label: '风量(m³/min)',
+              value: '${flow_merge}',
+            },
+            {
+              label: '负压(Pa)',
+              value: '${fy_merge}',
+            },
+            {
+              label: '漏风率(%)',
+              value: '${leakage}',
+            },
+          ],
+        },
+      ],
+      list: [],
+      chart: [],
+      table: [],
+      gallery: [],
+      complex_list: [],
+      gallery_list: [],
+      preset: [
+        {
+          readFrom: '',
+          fan1Prop: ['flow_merge', 'fy_merge'],
+          fan2Prop: ['flow_merge', 'fy_merge'],
+        },
+      ],
+      to: '/micro-vent-3dModal/dashboard/analysis?type=tunMonitor&deviceType=fanmain',
+    },
+    showStyle: {
+      size: 'width:377px;height:280px;',
+      version: '新版',
+      position: 'top:60px;left:0;',
+    },
+  },
+];

+ 6 - 0
src/views/vent/home/configurable/hooks/useInit.ts

@@ -45,6 +45,11 @@ export function useInitConfigs() {
       return c.showStyle.version === '保德';
     });
   });
+  const isNew = computed(() => {
+    return configs.value.some((c) => {
+      return c.showStyle.version === '新版';
+    });
+  });
   const devicesTypes = computed(() => {
     return configs.value
       .map((e) => e.deviceType)
@@ -68,6 +73,7 @@ export function useInitConfigs() {
     isOriginal,
     isCommon,
     isBD,
+    isNew,
   };
 }
 

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

@@ -0,0 +1,157 @@
+<!-- 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>
+    </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 { 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;
+    console.log('configs', configs.value);
+    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;
+    }
+  }
+  .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>

+ 304 - 0
src/views/vent/home/configurable/ventSDG.vue

@@ -0,0 +1,304 @@
+<!-- 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>
+    <!-- 如果是有 deviceType、type 等 query,认为是详情页,不需要展示普通模块,只需要模型 -->
+    <template v-if="!route.query.deviceType">
+      <div v-if="!route.query.embed" class="top-bg">
+        <div class="main-title">{{ mainTitle }}</div>
+      </div>
+      <a class="ant-dropdown-link module-dropdown" @click.prevent="showBar = !showBar">
+        全矿井通风检测
+        <CaretDownOutlined />
+      </a>
+      <MonitorBar v-if="showBar" class="module-monitor-bar" :is-data-real-time="isDataRealTime" :data="data" />
+      <!-- <a-dropdown class="module-dropdown" :class="{ 'module-dropdown-original': isOriginal }" :trigger="['click']" placement="bottomRight">
+        <template #overlay>
+        </template>
+      </a-dropdown> -->
+
+      <!-- 采用定位方式以避免出现各个模块隐藏时其他模块下移的问题 -->
+      <template v-if="isOriginal">
+        <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"
+        />
+      </template>
+      <template v-else-if="isCommon">
+        <ModuleCommon
+          v-for="cfg in configs"
+          :key="cfg.deviceType"
+          :show-style="cfg.showStyle"
+          :module-data="cfg.moduleData"
+          :module-name="cfg.moduleName"
+          :device-type="cfg.deviceType"
+          :data="data"
+          :visible="true"
+        />
+      </template>
+      <template v-else>
+        <!-- 下面是正常展示的各新版模块 -->
+        <ModuleEnhanced
+          v-for="cfg in enhancedConfigs"
+          :key="cfg.deviceType"
+          :visible="cfg.visible"
+          :show-style="cfg.showStyle"
+          :module-data="cfg.moduleData"
+          :module-name="cfg.moduleName"
+          :device-type="cfg.deviceType"
+          :data="data"
+          @close="cfg.visible = false"
+        />
+        <!-- 下面是用于呼出已隐藏的模块的按钮 -->
+        <div class="pos-absolute top-70px left-460px z-3">
+          <div v-for="(item, i) in hiddenList" :key="`vvhchg${i}`">
+            <AButton class="module-trigger-button" @click="item.visible = true">{{ item.moduleName }}</AButton>
+          </div>
+        </div>
+      </template>
+      <div
+        v-if="sysDataType === 'all'"
+        :class="{ 'realtime-mode': isDataRealTime }"
+        alt="切换数据模式"
+        class="switch-button report-mode right-525px"
+        @click="switchDataMode"
+      ></div>
+      <div class="switch-button icon-goto right-475px" @click="goMicroApp()"></div>
+    </template>
+  </div>
+</template>
+<script lang="ts" setup>
+  import { onMounted, onUnmounted, ref, watch } from 'vue';
+  // import { CaretDownOutlined } from '@ant-design/icons-vue';
+  import MonitorBar from './components/MonitorBar.vue';
+  import { useInitConfigs, useInitPage } from './hooks/useInit';
+  import ModuleEnhanced from './components/ModuleEnhanced.vue';
+  import ModuleOriginal from './components/ModuleOriginal.vue';
+  import ModuleCommon from './components/ModuleCommon.vue';
+  // import { useRoute } from 'vue-router';
+  import VentModal from '/@/components/vent/micro/ventModal.vue';
+  import { list } from './configurable.api';
+  import { useRoute, useRouter } from 'vue-router';
+  import { useGlobSetting } from '/@/hooks/setting';
+  // import { testConfigVent, testConfigVentRealtime } from './configurable.data';
+
+  const { sysDataType = 'monitor', title = '智能通风管控系统' } = useGlobSetting();
+  const { configs, isOriginal, isCommon, fetchConfigs } = useInitConfigs();
+  const { mainTitle, enhancedConfigs, hiddenList, data, updateData, updateEnhancedConfigs } = useInitPage(title);
+  const route = useRoute();
+  const router = useRouter();
+  const isDataRealTime = ref(sysDataType === 'monitor');
+  const showBar = ref(true);
+  let interval: number | undefined;
+
+  function switchDataMode() {
+    isDataRealTime.value = !isDataRealTime.value;
+    refresh();
+  }
+
+  function refresh() {
+    fetchConfigs(isDataRealTime.value ? 'vent_realtime' : 'vent').then(() => {
+      // configs.value = isDataRealTime.value ? testConfigVentRealtime : testConfigVent;
+      updateEnhancedConfigs(configs.value);
+
+      // 测风装置	windrect
+      // 自动风窗	window
+      // 自动风门	gate
+      // 传感器	modelsensor
+      // 局部通风机	fanlocal
+      // 主通风机	fanmain
+      // 密闭	obfurage
+      // 安全监控	safetymonitor
+      // 光纤测温	fiber
+      // 束管监测	bundletube
+      // 制氮	nitrogen
+      // 制浆	pulping
+      // 喷淋	spray
+      // 喷粉	dustdev
+      // 喷雾设备	atomizing
+      // 除尘风机	dedustefan
+      // 粉尘传感器	dustsensor
+      // 转载点	transferpoint
+      // 瓦斯抽采泵	pump
+      // 粉尘	dusting
+      // 瓦斯监测	gasmonitor
+      // 球阀	ballvalve
+      // 压风机	forcFan
+      // 瓦斯巡检	gaspatrol
+      // 防火门	firedoor
+      // 隔爆设施	explosionProof
+      // 瓦斯管道阀门	gasvalve
+      list({
+        types: configs.value
+          .filter((e) => e.deviceType)
+          .map((e) => e.deviceType)
+          .join(','),
+      }).then(updateData);
+    });
+  }
+
+  function initInterval() {
+    setInterval(() => {
+      list({}).then(updateData);
+    }, 60000);
+  }
+
+  function goMicroApp() {
+    router.push({
+      path: route.path,
+      query: {
+        ...route.query,
+        type: 'model3D',
+        deviceType: 'model3D',
+      },
+    });
+  }
+
+  watch(
+    () => route.query,
+    () => {
+      if (route.query.deviceType) {
+        // 仅需要展示子应用,模拟 unmounted
+        clearInterval(interval);
+      } else {
+        // 模拟 mounted
+        refresh();
+        initInterval();
+      }
+    }
+  );
+
+  onMounted(() => {
+    refresh();
+    initInterval();
+  });
+
+  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/themify/deepblue/vent/home/modal-top.png');
+    }
+  }
+
+  .company-home {
+    --image-modal-top: url('/@/assets/images/vent/home/modal-top.png');
+    --image-monitor-realtime: url('/@/assets/images/company/monitor-realtime.png');
+    --image-monitor-doc: url('/@/assets/images/company/monitor-doc.png');
+    --image-monitor-goto: url('/@/assets/images/company/monitor-goto.png');
+
+    width: 100%;
+    height: 100%;
+    color: @white;
+    position: relative;
+    // background: url('@/assets/images/home-container/configurable/firehome/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;
+      }
+    }
+
+    // .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: 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;
+    }
+
+    .switch-button {
+      width: 34px;
+      height: 34px;
+      position: absolute;
+      // right: 5px;
+      bottom: 300px;
+      z-index: 5;
+      background-repeat: no-repeat;
+      background-size: 100% 100%;
+    }
+    .report-mode {
+      background-image: var(--image-monitor-doc);
+    }
+    .realtime-mode {
+      background-image: var(--image-monitor-realtime);
+    }
+    .icon-goto {
+      background-image: var(--image-monitor-goto);
+    }
+
+    .module-monitor-bar {
+      position: absolute;
+      top: 100px;
+      width: 1000px;
+      height: 200px;
+      left: calc(50% - 500px);
+    }
+  }
+  :deep(.loading-box) {
+    position: unset;
+  }
+</style>

+ 2 - 4
src/views/vent/monitorManager/balancePressMonitor/balancePress.threejs.ts

@@ -49,8 +49,6 @@ export const play = (controlType, deviceType, frequency, state, duration?) => {
 export const updateText = (selectData) => {
   if (balancePressType === 'balancePressBase') {
     return balancePressBaseObj?.addText.call(balancePressBaseObj, selectData);
-  } else if (balancePressType === 'balancePressTun') {
-    return balancePressTunObj?.addText.call(balancePressTunObj, selectData);
   }
 };
 
@@ -86,8 +84,8 @@ export const setModelType = (type) => {
           await animateCamera(
             oldCameraPosition,
             { x: 3.9025, y: 0.7782, z: 6.6307 },
-            { x: 1.4763946591400468, y: 28.41203761378685, z: 14.142784066252352 },
-            { x: 1.334507975656787, y: 1.6848765189635717, z: -1.5733583795572064 },
+            { x: 0.30694425126412234, y: 6.664533888402769, z: 3.7879281016804667 },
+            { x: 0.27488693515931245, y: 0.6259183086723961, z: 0.23709305659449886 },
             model,
             0.8
           );

+ 47 - 10
src/views/vent/monitorManager/balancePressMonitor/components/balancePressHome1.vue

@@ -77,6 +77,20 @@
                     ><SvgIcon class="icon" size="14" name="fiber-title" />
                     <span>局扇:{{ monitor.strinstallpos }}</span>
                   </div>
+                  <div class="vent-flex-row">
+                    <div
+                      class="fan-btn"
+                      :class="{ 'fan-btn-active': get(fanBtnData, monitor.deviceId) == 'Fan1' }"
+                      @click="changeFanBtn(monitor.deviceId, 'Fan1')"
+                      >主机</div
+                    >
+                    <div
+                      class="fan-btn"
+                      :class="{ 'fan-btn-active': get(fanBtnData, monitor.deviceId) == 'Fan2' }"
+                      @click="changeFanBtn(monitor.deviceId, 'Fan2')"
+                      >备机</div
+                    >
+                  </div>
                   <div class="input-box">
                     <div class="input-item">
                       <div class="title">运行风机</div>
@@ -85,17 +99,10 @@
                     <div v-for="(item, index) in fanlocalColumn" class="input-item" :key="index">
                       <div class="title">{{ item.title }}</div>
                       <div class="value">{{
-                        get(
-                          monitor,
-                          item.dataIndex.startsWith('Fan')
-                            ? get(monitor, 'Fan1StartStatus') == 1
-                              ? item.dataIndex.replace('Fan', 'Fan1')
-                              : item.dataIndex.replace('Fan', 'Fan2')
-                            : get(monitor, item.dataIndex),
-                          '-'
-                        )
+                        item.dataIndex.startsWith('Fan')
+                          ? get(monitor, item.dataIndex.replace('Fan', fanBtnData[monitor.deviceId]))
+                          : get(monitor, item.dataIndex)
                       }}</div>
-                      <!-- <div class="unit">{{ item.unit }}</div> -->
                     </div>
                   </div>
                 </template>
@@ -192,6 +199,7 @@
 
   const safetyMonitorData = ref<any[]>([]);
   const fanlocalMonitorData = ref<any[]>([]);
+  const fanBtnData = reactive({});
   const windowMonitorData = ref<any[]>([]);
   const windrectMonitorData = ref<any[]>([]);
   const fanlocalColumn = ref<any[]>([]);
@@ -215,6 +223,7 @@
           const f1Run = e.readData.Fan1StartStatus == '1';
           e.FanfHz = f1Run ? e.readData.Fan1_Frequency : e.readData.Fan2_Frequency;
           e.FanRun = f1Run ? '1#风机' : '2#风机';
+          if (!fanBtnData[e.deviceId]) fanBtnData[e.deviceId] = 'Fan1';
         });
         fanlocalMonitorData.value.push(...item.datalist);
       }
@@ -227,6 +236,9 @@
     });
   }
 
+  function changeFanBtn(deviceId, fan) {
+    fanBtnData[deviceId] = fan;
+  }
   // 喷粉操作
   function onSubmit() {
     sessionStorage.setItem('lalance-press-formdata', JSON.stringify(formData.value));
@@ -286,6 +298,7 @@
 <style lang="less" scoped>
   @import '/@/design/vent/modal.less';
   @import '../../comment/less/workFace.less';
+
   @ventSpace: zxm;
   .monitor-container {
     margin-top: 60px;
@@ -338,6 +351,30 @@
       padding: 4px 0;
     }
   }
+  .fan-btn {
+    flex: 1;
+    text-align: center;
+    background: var(--vent-balancePress-fan-bg-default);
+    cursor: pointer;
+    &:hover {
+      color: var(--vent-font-action-link);
+      background: var(--vent-balancePress-fan-bg-select);
+    }
+    &:first-child {
+      border-left: 1px solid;
+      border-radius: 4px;
+      border-color: var(--vent-configurable-home-light-border);
+    }
+    &:last-child {
+      border-right: 1px solid;
+      border-radius: 4px;
+      border-color: var(--vent-configurable-home-light-border);
+    }
+  }
+  .fan-btn-active {
+    color: var(--vent-font-action-link);
+    background: var(--vent-balancePress-fan-bg-select);
+  }
 
   :deep(.@{ventSpace}-tabs-tabpane-active) {
     overflow: auto;

+ 7 - 1
src/views/vent/monitorManager/balancePressMonitor/index1.vue

@@ -17,7 +17,7 @@
     </div>
     <BottomMenu @change="changeActive"/>
   </div>
-  <Vent2dModal style="width: 100vw; height: 100vh; position: absolute; top: 0; left: 0;" />
+  <Vent2dModal v-if="activeKey == 'monitor'" style="width: 100vw; height: 100vh; position: absolute; top: 0; left: 0;" />
 </template>
 
 <script setup lang="ts">
@@ -136,6 +136,12 @@ onBeforeUnmount(() => {
   margin-top: 20px;
   pointer-events: none;
   position: relative;
+  :deep(.left-box){
+    margin-top: 0px;
+  }
+  :deep(.right-box){
+    margin-top: 0px;
+  }
   .history-group{
     padding: 0 20px;
     .history-container{

+ 1 - 2
src/views/vent/monitorManager/balancePressMonitor/index2.vue

@@ -34,7 +34,6 @@ import balancePressHistory from './components/balancePressHistory.vue';
 import balancePressHandleHistoryVue from './components/balancePressHandleHistory.vue';
 import balancePressAlarmHistory from './components/balancePressAlarmHistory.vue';
 import { useRouter } from 'vue-router';
-import { setModelType } from './balancePress.threejs';
 
 type DeviceType = { deviceType: string, deviceName: string, datalist: any[] };
 
@@ -103,7 +102,7 @@ function getSelectRow(deviceID){
   // })
   optionValue.value = deviceID
   getDeviceList()
-  setModelType('balancePressTun')
+  // setModelType('balancePressTun')
 }
 
 onBeforeMount(() => {

+ 1 - 1
src/views/vent/monitorManager/comment/HistoryTable.vue

@@ -286,7 +286,7 @@
     formData['pageNo'] = pagination['current'];
     formData['pageSize'] = pagination['pageSize'];
     formData['column'] = 'createTime';
-    if (stationType.value !== 'redis') {
+    if (stationType.value !== 'redis' && deviceOptions.value[0]) {
       formData['strtype'] = deviceTypeStr.value
         ? deviceTypeStr.value
         : deviceOptions.value[0]['strtype']

+ 1 - 1
src/views/vent/monitorManager/comment/MonitorTable.vue

@@ -120,7 +120,7 @@
       pagination: props.isShowPagination
         ? {
             current: 1,
-            pageSize: 50,
+            pageSize: 30,
             pageSizeOptions: ['10', '30', '50', '100', '500'],
             showQuickJumper: false,
           }

+ 10 - 5
src/views/vent/monitorManager/sensorMonitor/index.vue

@@ -21,7 +21,7 @@
               </template>
               <MonitorTable
                 ref="SensorMonitorRef"
-                :is-show-select="false"
+                :is-show-select="true"
                 :columnsType="deviceKind + '_monitor'"
                 :dataSource="dataSource"
                 design-scope="modelsensor_monitor"
@@ -87,7 +87,7 @@
         </a-tab-pane>
         <a-tab-pane key="4" tab="报警分析">
           <div class="tab-item box-bg" v-if="activeKey == '4'">
-           <warnAnalysis  device-type="modelsensor"></warnAnalysis>
+            <warnAnalysis device-type="modelsensor" />
           </div>
         </a-tab-pane>
         <!-- <a-tab-pane key="4" tab="操作历史">
@@ -110,7 +110,7 @@
   import MonitorTable from '../comment/MonitorTable.vue';
   import HistoryTable from '../comment/HistoryTable.vue';
   import AlarmHistoryTable from '../comment/AlarmHistoryTable.vue';
-  import warnAnalysis from '../comment/warnAnalysis.vue'
+  import warnAnalysis from '../comment/warnAnalysis.vue';
   import { list, getTableList } from './sensor.api';
   import { deviceList } from '../../deviceManager/comment/pointTabel/point.api';
   import { getTableHeaderColumns } from '/@/hooks/web/useWebColumns';
@@ -371,8 +371,13 @@
       background-color: #ffffff11;
       overflow-y: auto;
     }
+    .table-box-content {
+      height: 430px;
+      background-color: #ffffff03;
+      border-bottom: 1px solid #44d3ff70;
+    }
     .charts-box {
-      height: calc(40% - 80px);
+      height: 300px;
       padding: 5px 10px;
       margin-top: 10px;
     }
@@ -397,7 +402,7 @@
     }
     .@{ventSpace}-picker,
     .@{ventSpace}-select-selector {
-      width: 100% ;
+      width: 100%;
       background: #00000017 !important;
       border: 1px solid @vent-form-item-border !important;
       input,