Procházet zdrojové kódy

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

lxh před 8 měsíci
rodič
revize
8dce7db724

+ 38 - 38
src/views/vent/deviceManager/configurationTable/options.ts

@@ -1,47 +1,47 @@
 import _ from 'lodash-es';
 
 export const ModuleSizeMap = {
-  'width:450px;height:280px;': '标准尺寸(450*280)',
-  'width:450px;height:570px;': '纵向拉伸(450*570)',
-  'width:450px;height:860px;': '纵向填充(450*860)',
-  'width:1000px;height:280px;': '横向拉伸(1000*280)',
-  'width:1920px;height:280px;': '横向填充(1920*280)',
+  '标准尺寸(450*280)': 'width:450px;height:280px;',
+  '纵向拉伸(450*570)': 'width:450px;height:570px;',
+  '纵向填充(450*860)': 'width:450px;height:860px;',
+  '横向拉伸(1000*280)': 'width:1000px;height:280px;',
+  '横向填充(1920*280)': 'width:1920px;height:280px;',
 };
-export const ModuleSizeOptions = _.map(ModuleSizeMap, (v, k) => ({
-  value: k,
-  label: v,
-}));
+// export const ModuleSizeOptions = _.map(ModuleSizeMap, (v, k) => ({
+//   value: k,
+//   label: v,
+// }));
 
-export const ModuleVersionMap = {
-  original: '原版',
-  enhanced: '新版',
-};
-export const ModuleVersionOptions = _.map(ModuleVersionMap, (v, k) => ({
-  value: k,
-  label: v,
-}));
+// export const ModuleVersionMap = {
+//   original: '原版',
+//   enhanced: '新版',
+// };
+// export const ModuleVersionOptions = _.map(ModuleVersionMap, (v, k) => ({
+//   value: k,
+//   label: v,
+// }));
 
 export const ModulePositionMap = {
-  'display:none;': '不展示',
-  'top:60px;left:0;': '左上',
-  'top:350px;left:0;': '左中',
-  'top:640px;left:0;': '左下',
-  'top:60px;right:0;': '右上',
-  'top:350px;right:0;': '右中',
-  'top:640px;right:0;': '右下',
-  'top:640px;left:460px;': '中下',
+  不展示: 'display:none;',
+  左上: 'top:60px;left:0;',
+  左中: 'top:350px;left:0;',
+  左下: 'top:640px;left:0;',
+  右上: 'top:60px;right:0;',
+  右中: 'top:350px;right:0;',
+  右下: 'top:640px;right:0;',
+  中下: 'top:640px;left:460px;',
 };
-export const ModulePositionOptions = _.map(ModulePositionMap, (v, k) => ({
-  value: k,
-  label: v,
-}));
+// export const ModulePositionOptions = _.map(ModulePositionMap, (v, k) => ({
+//   value: k,
+//   label: v,
+// }));
 
-export const ModuleChartTypeMap = {
-  pie: '饼状图',
-  bar: '柱状图',
-  line: '折线图',
-};
-export const ModuleChartTypeOptions = _.map(ModuleChartTypeMap, (v, k) => ({
-  value: k,
-  label: v,
-}));
+// export const ModuleChartTypeMap = {
+//   pie: '饼状图',
+//   bar: '柱状图',
+//   line: '折线图',
+// };
+// export const ModuleChartTypeOptions = _.map(ModuleChartTypeMap, (v, k) => ({
+//   value: k,
+//   label: v,
+// }));

+ 68 - 52
src/views/vent/deviceManager/configurationTable/types.ts

@@ -1,3 +1,5 @@
+import { ModulePositionMap, ModuleSizeMap } from './options';
+
 export interface Config {
   moduleName: string;
   pageType: string;
@@ -5,6 +7,64 @@ export interface Config {
   moduleData: ModuleData;
   showStyle: ShowStyle;
 }
+
+export interface ModuleDataBoard {
+  /** 展示牌预设的背景类型 */
+  type: 'A' | 'B' | 'C' | 'D';
+  /** 展示牌布局,决定是哪部分内容在上方 */
+  layout: 'val-top' | 'label-top';
+  items: {
+    /** 展示牌说明内容 */
+    label: string;
+    formatter?: string;
+    prop: string;
+  }[];
+}
+export interface ModuleDataList {
+  /** 列表项预设的背景类型 */
+  type: 'timeline' | 'A' | 'B';
+  items: {
+    /** 列表项说明内容 */
+    label: string;
+    formatter?: string;
+    prop: string;
+    color: string;
+  }[];
+}
+export interface ModuleDataChart {
+  /** 图表通用类型,一个类型对应一种图表预设 */
+  type: 'pie' | 'bar' | 'line' | 'line_area';
+  /** 读取数据时的基础路径,例如如果图表依赖一个数组,那么该项应设置能读取到该数组的路径。例如:readData.history */
+  readFrom: string;
+  /** 排序依据,该项应配置为`readFrom`指向的数据中的可读项。例如:createTime */
+  sortBy?: string;
+  /** 排序规则,desc降序,asc升序 */
+  order?: 'desc' | 'asc';
+  /** 图表x轴配置(若有),例如:{ prop: 'strInstallPos' } */
+  xAxis: {
+    formatter?: string;
+    prop: string;
+  }[];
+  /** 图表y轴配置(若有),例如:['风量', '风速'] */
+  yAxis: {
+    label: string;
+    align: 'left' | 'right';
+  }[];
+  /** 图表各系列配置,一个系列应对应一个数据维度,例如:[{ label: '风量', prop: 'f1Val' }] */
+  series: { label: string; prop: string }[];
+}
+export interface ModuleDataTable {
+  /** 表格的预设样式 */
+  type: 'A' | 'B';
+  columns: { label: string; prop: string }[];
+  /** 读取数据时的基础路径,例如如果表格依赖一个数组,那么该项应设置能读取到该数组的路径。例如:readData.history */
+  readFrom: string;
+}
+export interface ModuleDataPreset {
+  /** 表格的预设样式 */
+  [key: string]: any;
+}
+
 /**
  * 模块的配置
  *
@@ -48,64 +108,20 @@ export interface ModuleData {
     /** 背景资源的链接 */
     link: string;
   };
+  // layout: (ModuleDataBoard | ModuleDataChart | ModuleDataList | ModuleDataTable | ModuleDataPreset)[];
   /** 模块的布局,使用规定的枚举组合为一个数组,代表着从上到下所应展示的元素 */
   layout: ('board' | 'list' | 'chart' | 'table' | 'blast_delta' | 'fire_control' | 'fire_warn')[];
-  /** 展示牌元素 */
-  board: {
-    /** 展示牌说明内容 */
-    label: string;
-    /** 展示牌预设的背景类型 */
-    type: 'A' | 'B' | 'C' | 'D';
-    /** 展示牌布局,决定是哪部分内容在上方 */
-    layout: 'val-top' | 'label-top';
-    formatter?: string;
-    prop: string;
-  }[];
-  /** 列表元素 */
-  list: {
-    color: string;
-    /** 列表项说明内容 */
-    label: string;
-    formatter?: string;
-    prop: string;
-    /** 列表预设的背景类型,仅第一个type生效,即第一个type决定了列表整体的类型 */
-    type: 'timeline' | 'A' | 'B';
-  }[];
-  /** 图表元素,仅第一个配置项将生效 */
-  chart: {
-    /** 图表通用类型,一个类型对应一种图表预设 */
-    type: 'pie' | 'bar' | 'line' | 'line_area';
-    /** 读取数据时的基础路径,例如如果图表依赖一个数组,那么该项应设置能读取到该数组的路径。例如:readData.history */
-    readFrom: string;
-    /** 排序依据,该项应配置为`readFrom`指向的数据中的可读项。例如:createTime */
-    sortBy?: string;
-    /** 排序规则,desc降序,asc升序 */
-    order?: 'desc' | 'asc';
-    /** 图表x轴配置(若有),例如:{ prop: 'strInstallPos' } */
-    xAxis: {
-      formatter?: string;
-      prop: string;
-    }[];
-    /** 图表y轴配置(若有),例如:['风量', '风速'] */
-    yAxis: {
-      label: string;
-      align: 'left' | 'right';
-    }[];
-    /** 图表各系列配置,一个系列应对应一个数据维度,例如:[{ label: '风量', prop: 'f1Val' }] */
-    series: { label: string; prop: string }[];
-  }[];
-  /** 表格元素,仅第一个配置项将生效 */
-  table: {
-    columns: { label: string; prop: string }[];
-    /** 读取数据时的基础路径,例如如果表格依赖一个数组,那么该项应设置能读取到该数组的路径。例如:readData.history */
-    readFrom: string;
-  }[];
+  preset: ModuleDataPreset[];
+  board: ModuleDataBoard[];
+  chart: ModuleDataChart[];
+  list: ModuleDataList[];
+  table: ModuleDataTable[];
 }
 export interface ShowStyle {
   /** 模块的宽高 */
-  size: string;
+  size: keyof typeof ModuleSizeMap;
   /** 模块的版本,分新版及旧版,只要有一个模块指定为旧版,那么整个页面风格将变更为旧版 */
   version: 'original' | 'enhanced';
   /** 模块的位置,即定位 */
-  position: string;
+  position: keyof typeof ModulePositionMap;
 }

+ 0 - 1
src/views/vent/home/configurable/components/CustomChart.vue

@@ -284,7 +284,6 @@
 
   function initCharts() {
     const o = genChartOption();
-    console.log('debug', o);
     setOptions(o as EChartsOption, false);
   }
 </script>

+ 10 - 10
src/views/vent/home/configurable/components/CustomList.vue

@@ -42,6 +42,9 @@
   .list-item {
     height: 20%;
   }
+  .list__A {
+    padding-left: 5px;
+  }
   .list-item__content__A {
     background-repeat: no-repeat;
     background-image: @vent-gas-list-item-bg-img;
@@ -49,6 +52,13 @@
     display: flex;
     justify-content: space-between;
   }
+  .list-item__icon__A {
+    background-repeat: no-repeat;
+    width: 25px;
+    height: 29px;
+    background-image: url(/@/assets/images/home-container/configurable/triangle_icon.png);
+  }
+
   .list-item__content__B {
     background-repeat: no-repeat;
     padding: 5px 10px 10px 10px;
@@ -66,12 +76,6 @@
     background-size: auto;
     margin-right: 20px;
   }
-  .list-item__icon__A {
-    background-repeat: no-repeat;
-    width: 25px;
-    height: 29px;
-    background-image: url(/@/assets/images/home-container/configurable/triangle_icon.png);
-  }
   // .list-item__icon_red {
   //   background-image: url('@/assets/images/home-container/configurable/warn_icon_5.png');
   // }
@@ -139,8 +143,4 @@
     background-size: auto 100%;
     background-image: url(/@/assets/images/home-container/configurable/list_bg_default.png);
   }
-
-  .list__A {
-    padding-left: 5px;
-  }
 </style>

+ 10 - 12
src/views/vent/home/configurable/components/ModuleEnhanced.vue

@@ -1,11 +1,5 @@
 <template>
-  <component
-    :is="getModuleComponent(showStyle.position)"
-    :style="style"
-    :title="moduleName"
-    :visible="visible"
-    @update:visible="$emit('update:visible', $event)"
-  >
+  <component :is="getModuleComponent(showStyle.position)" :style="style" :title="moduleName" :visible="visible" @close="$emit('close')">
     <slot></slot>
   </component>
 </template>
@@ -15,27 +9,31 @@
   import ModuleBottom from './enhanced/moduleBottom.vue';
   import { computed } from 'vue';
   import { ShowStyle } from '../../../deviceManager/configurationTable/types';
+  import { ModulePositionMap, ModuleSizeMap } from '../../../deviceManager/configurationTable/options';
+  import { get } from 'lodash-es';
 
   const props = defineProps<{
     showStyle: ShowStyle;
     moduleName: string;
     visible: boolean;
   }>();
-  defineEmits(['update:visible']);
+  defineEmits(['close']);
 
   const style = computed(() => {
-    return props.showStyle.size + props.showStyle.position;
+    const size = get(ModuleSizeMap, props.showStyle.size, ModuleSizeMap['标准尺寸(450*280)']);
+    const position = get(ModulePositionMap, props.showStyle.position, ModulePositionMap['不展示']);
+    return size + position;
   });
 
   // 根据配置里的定位判断应该使用哪个module组件
   function getModuleComponent(position) {
-    if (position.includes('left:0')) {
+    if (position.includes('')) {
       return ModuleLeft;
     }
-    if (position.includes('right:0')) {
+    if (position.includes('')) {
       return ModuleRight;
     }
-    if (position.includes('top:640px;left:460px')) {
+    if (position === '中下') {
       return ModuleBottom;
     }
     return ModuleLeft; //

+ 8 - 10
src/views/vent/home/configurable/components/ModuleOriginal.vue

@@ -1,11 +1,5 @@
 <template>
-  <component
-    :is="getModuleComponent(showStyle.position)"
-    :style="style"
-    :title="moduleName"
-    :visible="visible"
-    @update:visible="$emit('update:visible', $event)"
-  >
+  <component :is="getModuleComponent(showStyle.position)" :style="style" :title="moduleName" :visible="visible" @close="$emit('close')">
     <slot></slot>
   </component>
 </template>
@@ -14,21 +8,25 @@
   import ModuleBottom from './original/moduleBottom.vue';
   import { computed } from 'vue';
   import { ShowStyle } from '../../../deviceManager/configurationTable/types';
+  import { ModulePositionMap, ModuleSizeMap } from '../../../deviceManager/configurationTable/options';
+  import { get } from 'lodash-es';
 
   const props = defineProps<{
     showStyle: ShowStyle;
     moduleName: string;
     visible: boolean;
   }>();
-  defineEmits(['update:visible']);
+  defineEmits(['close']);
 
   const style = computed(() => {
-    return props.showStyle.size + props.showStyle.position;
+    const size = get(ModuleSizeMap, props.showStyle.size, ModuleSizeMap['标准尺寸(450*280)']);
+    const position = get(ModulePositionMap, props.showStyle.position, ModulePositionMap['不展示']);
+    return size + position;
   });
 
   // 根据配置里的定位判断应该使用哪个module组件
   function getModuleComponent(position) {
-    if (position.includes('top:640px;left:460px')) {
+    if (position === '中下') {
       return ModuleBottom;
     }
     return ModuleLeft;

+ 180 - 57
src/views/vent/home/configurable/components/content.vue

@@ -36,7 +36,7 @@
     </template>
   </div>
   <!-- 主体内容部分 -->
-  <div class="content">
+  <div class="content" :class="{ content_without_header: !headerConfig.show }">
     <!-- 背景 -->
     <img v-if="background.show && background.type === 'image'" class="content__background" :src="background.link" />
     <video
@@ -50,35 +50,47 @@
       <source :src="background.link" />
       Not Supportted Link Or Browser
     </video>
-    <template v-for="val in layout" :key="val">
+    <template v-for="config in layoutConfig" :key="config.key">
       <!-- 告示板部分 -->
-      <div v-if="val === 'board'" class="flex flex-justify-around pt-10px pb-10px">
-        <MiniBoard v-for="item in boardConfig" :key="item.prop" :type="item.type" :label="item.label" :layout="item.layout" :value="item.value" />
+      <div v-if="config.key === 'board'" class="flex flex-justify-around pt-10px pb-10px">
+        <MiniBoard
+          v-for="item in config.items"
+          :key="item.prop"
+          :label="item.label"
+          :value="item.value"
+          :type="config.type"
+          :layout="config.layout"
+        />
       </div>
       <!-- 图表部分,这部分通常需要填充,有告示板、Header等内容需要填充父级 -->
-      <template v-if="val === 'chart'">
-        <CustomChart :chart-config="chartConfig" :chart-data="chartData" class="flex-grow" />
+      <template v-if="config.key === 'chart'">
+        <CustomChart :chart-config="config.config" :chart-data="config.data" class="flex-grow" />
       </template>
       <!-- 通常列表部分 -->
-      <template v-if="val === 'list'">
-        <template v-if="listType === 'timeline'">
-          <TimelineList :list-config="listConfig" />
+      <template v-if="config.key === 'list'">
+        <template v-if="config.type === 'timeline'">
+          <TimelineList :list-config="config.items" />
         </template>
         <template v-else>
-          <CustomList :type="listType" :list-config="listConfig" />
+          <CustomList :type="config.type" :list-config="config.items" />
         </template>
       </template>
       <!-- 表格部分,这部分通常是占一整个模块的 -->
-      <template v-if="val === 'table'">
-        <CommonTable :columns="tableConfig.columns" :data="tableData" class="mt-10px mb-10px text-center flex-grow overflow-auto" />
+      <template v-if="config.key === 'table'">
+        <CommonTable
+          v-if="config.type === 'A'"
+          :columns="config.columns"
+          :data="tableData"
+          class="mt-20px mb-10px text-center flex-grow overflow-auto"
+        />
       </template>
-      <template v-if="val === 'blast_delta'">
+      <template v-if="config.key === 'blast_delta'">
         <BlastDelta class="mt-10px mb-10px" :pos-monitor="blastDeltaData" :canvas-size="{ width: 250, height: 147 }" />
       </template>
-      <template v-if="val === 'fire_control'">
+      <template v-if="config.key === 'fire_control'">
         <FIreControl class="mt-10px mb-10px" />
       </template>
-      <template v-if="val === 'fire_warn'">
+      <template v-if="config.key === 'fire_warn'">
         <FIreWarn class="mt-10px mb-10px" />
       </template>
     </template>
@@ -86,7 +98,14 @@
 </template>
 <script lang="ts" setup>
   import { computed, onMounted, ref } from 'vue';
-  import { Config } from '../../../deviceManager/configurationTable/types';
+  import {
+    Config,
+    // ModuleDataBoard,
+    // ModuleDataChart,
+    // ModuleDataList,
+    // ModuleDataPreset,
+    // ModuleDataTable,
+  } from '../../../deviceManager/configurationTable/types';
   import { useInitDevices } from '../hooks/useInit';
   import { MenuItem, Menu, Dropdown } from 'ant-design-vue';
   import { SwapOutlined, CaretUpOutlined, CaretDownOutlined } from '@ant-design/icons-vue';
@@ -95,7 +114,7 @@
   import CustomList from './CustomList.vue';
   import { getFormattedText } from '../../../deviceManager/configurationTable/adapters';
   import CustomChart from './CustomChart.vue';
-  import { get } from 'lodash-es';
+  import { get, clone } from 'lodash-es';
   import CommonTable from '../../billboard/components/CommonTable.vue';
   import BlastDelta from '../../../monitorManager/deviceMonitor/components/device/modal/blastDelta.vue';
   import FIreWarn from './FIreWarn.vue';
@@ -108,7 +127,92 @@
     showStyle: Config['showStyle'];
   }>();
 
-  const { header: headerConfig, background, board, layout, list, chart, table } = props.moduleData;
+  const { header: headerConfig, background, layout } = props.moduleData;
+
+  /** 根据配置里的layout将配置格式化为带 key 的具体配置,例如:[{ key: 'list', value: any, ...ModuleDataList }] */
+  const layoutConfig = computed(() => {
+    const data = selectedDevice.value;
+    const board = clone(props.moduleData.board);
+    const list = clone(props.moduleData.list);
+    const chart = clone(props.moduleData.chart);
+    const table = clone(props.moduleData.table);
+    const preset = clone(props.moduleData.preset);
+
+    return layout.reduce((arr: any[], key) => {
+      switch (key) {
+        case 'board': {
+          const cfg = board[0];
+          if (!cfg) break;
+
+          arr.push({
+            ...cfg,
+            key,
+            items: cfg.items.map((i) => {
+              return {
+                ...i,
+                value: getFormattedText(data, i.prop, i.formatter),
+              };
+            }),
+          });
+          break;
+        }
+        case 'list': {
+          const cfg = list.shift();
+          if (!cfg) break;
+
+          arr.push({
+            ...cfg,
+            key,
+            items: cfg.items.map((i) => {
+              return {
+                ...i,
+                value: getFormattedText(data, i.prop, i.formatter),
+              };
+            }),
+          });
+          break;
+        }
+        case 'chart': {
+          const cfg = chart.shift();
+          if (!cfg) break;
+          arr.push({
+            key,
+            config: cfg,
+            data: get(data, cfg.readFrom, []),
+          });
+          break;
+        }
+        case 'table': {
+          const cfg = table.shift();
+          if (!cfg) break;
+
+          arr.push({
+            ...cfg,
+            key,
+            columns: (cfg.columns || []).map((e) => {
+              return {
+                name: e.label,
+                prop: e.prop,
+              };
+            }),
+            data: get(data, cfg.readFrom, []),
+          });
+          break;
+        }
+        default: {
+          const cfg = preset.shift();
+          if (!cfg) break;
+
+          arr.push({
+            key,
+            config: cfg,
+          });
+          break;
+        }
+      }
+      return arr;
+    }, []);
+  });
 
   // 额外的 header 相关的变量
   const headerVisible = ref(false);
@@ -117,48 +221,48 @@
   }
 
   // 额外的告示牌相关的变量
-  const boardConfig = computed(() => {
-    const data = selectedDevice.value;
-    return (board || []).map((b) => {
-      return {
-        ...b,
-        value: getFormattedText(data, b.prop, b.formatter),
-      };
-    });
-  });
+  // const boardConfig = computed(() => {
+  //   const data = selectedDevice.value;
+  //   return (board || []).map((b) => {
+  //     return {
+  //       ...b.items,
+  //       value: getFormattedText(data, b.prop, b.formatter),
+  //     };
+  //   });
+  // });
 
   // 额外的时间线列表相关的变量
-  const listConfig = computed(() => {
-    const data = selectedDevice.value;
-    return (list || []).map((b) => {
-      return {
-        ...b,
-        value: getFormattedText(data, b.prop, b.formatter),
-      };
-    });
-  });
-  const listType = computed(() => {
-    return list[0]?.type || 'A';
-  });
+  // const listConfig = computed(() => {
+  //   const data = selectedDevice.value;
+  //   return (list || []).map((b) => {
+  //     return {
+  //       ...b,
+  //       value: getFormattedText(data, b.prop, b.formatter),
+  //     };
+  //   });
+  // });
+  // const listType = computed(() => {
+  //   return list[0]?.type || 'A';
+  // });
 
-  const chartConfig = computed(() => {
-    return chart[0];
-  });
-  const chartData = computed(() => {
-    const data = selectedDevice.value;
-    return get(data, chart[0]?.readFrom, []);
-  });
+  // const chartConfig = computed(() => {
+  //   return chart[0];
+  // });
+  // const chartData = computed(() => {
+  //   const data = selectedDevice.value;
+  //   return get(data, chart[0]?.readFrom, []);
+  // });
 
-  const tableConfig = computed(() => {
-    return {
-      columns: (table[0]?.columns || []).map((e) => {
-        return {
-          name: e.label,
-          prop: e.prop,
-        };
-      }),
-    };
-  });
+  // const tableConfig = computed(() => {
+  //   return {
+  //     columns: (table[0]?.columns || []).map((e) => {
+  //       return {
+  //         name: e.label,
+  //         prop: e.prop,
+  //       };
+  //     }),
+  //   };
+  // });
   const tableData = computed(() => {
     // const data = selectedDevice.value;
     return [
@@ -166,21 +270,37 @@
         index: '1',
         time: '2024/07/22 07:00',
         warn: '未知',
+        cate: 'xxx综采工作面',
+        temp: '26',
+        wspd: '2',
+        spst: 'ON',
       },
       {
         index: '2',
         time: '2024/07/22 08:00',
         warn: '未知',
+        cate: 'xxx综采工作面',
+        temp: '26',
+        wspd: '2',
+        spst: 'ON',
       },
       {
         index: '3',
         time: '2024/07/22 09:00',
         warn: '未知',
+        cate: 'xxx综采工作面',
+        temp: '26',
+        wspd: '2',
+        spst: 'ON',
       },
       {
         index: '4',
         time: '2024/07/22 10:00',
         warn: '未知',
+        cate: 'xxx综采工作面',
+        temp: '26',
+        wspd: '2',
+        spst: 'ON',
       },
     ];
     // return get(data, table[0]?.readFrom, []);
@@ -222,10 +342,13 @@
   .content {
     height: calc(100% - 30px);
     position: relative;
-    z-index: -2;
+    // z-index: -2;
     display: flex;
     flex-direction: column;
   }
+  .content_without_header {
+    height: 100%;
+  }
   .content__background {
     width: 100%;
     height: 100%;

+ 8 - 6
src/views/vent/home/configurable/components/enhanced/moduleBottom.vue

@@ -21,10 +21,10 @@
 </template>
 <script lang="ts" setup>
   defineProps<{ title: string; visible: boolean }>();
-  const emit = defineEmits(['update:visible']);
+  const emit = defineEmits(['close']);
 
   function closeModel() {
-    emit('update:visible', false);
+    emit('close');
   }
 </script>
 <style lang="less" scoped>
@@ -42,17 +42,18 @@
     .module-content__title__expand {
       width: 100%;
       height: var(--bg-height);
-      background: url('../../../../../assets/images/home-container/configurable/model_bottom_title_bg_expand.png') no-repeat;
+      line-height: var(--bg-height);
+      background: url('@/assets/images/home-container/configurable/model_bottom_title_bg_expand.png') no-repeat;
       background-size: 100% 100%;
       position: relative;
       text-align: left;
-      padding: 4px 0 0 5%;
+      padding: 0 0 0 5%;
     }
 
     // .module-content__title {
     //   width: 50%;
     //   height: var(--bg-height);
-    //   background: url('../../../../../assets/images/home-container/configurable/model_bottom_title_bg.png') no-repeat;
+    //   background: url('@/assets/images/home-container/configurable/model_bottom_title_bg.png') no-repeat;
     //   background-size: 100% 100%;
     //   position: relative;
     //   text-align: left;
@@ -63,10 +64,11 @@
     .action-btn {
       width: 18px;
       height: 18px;
-      background: url('../../../../../assets/images/home-container/configurable/expand.svg') no-repeat center;
+      background: url('@/assets/images/home-container/configurable/expand.svg') no-repeat center;
       position: absolute;
       left: 0;
       top: 0;
+      cursor: pointer;
     }
     .show-btn {
       transform: rotate(-90deg);

+ 7 - 4
src/views/vent/home/configurable/components/enhanced/moduleLeft.vue

@@ -21,10 +21,10 @@
 </template>
 <script lang="ts" setup>
   defineProps<{ title: string; visible: boolean }>();
-  const emit = defineEmits(['update:visible']);
+  const emit = defineEmits(['close']);
 
   function closeModel() {
-    emit('update:visible', false);
+    emit('close');
   }
 </script>
 <style lang="less" scoped>
@@ -42,21 +42,23 @@
     .module-content__title__expand {
       width: 100%;
       height: var(--bg-height);
+      line-height: var(--bg-height);
       background: url('@/assets/images/home-container/configurable/model_left_title_bg_expand.png') no-repeat;
       background-size: 100% 100%;
       position: relative;
       text-align: right;
-      padding: 4px 10% 0 0;
+      padding: 0 10% 0 0;
     }
 
     .module-content__title {
       width: 50%;
       height: var(--bg-height);
+      line-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;
+      padding: 0 10% 0 0;
     }
 
     // 固定在父容器右上角的按钮图标
@@ -67,6 +69,7 @@
       position: absolute;
       right: 0;
       top: 0;
+      cursor: pointer;
     }
     .close-btn {
       transform: rotate(-90deg);

+ 10 - 7
src/views/vent/home/configurable/components/enhanced/moduleRight.vue

@@ -21,10 +21,10 @@
 </template>
 <script lang="ts" setup>
   defineProps<{ title: string; visible: boolean }>();
-  const emit = defineEmits(['update:visible']);
+  const emit = defineEmits(['close']);
 
   function closeModel() {
-    emit('update:visible', false);
+    emit('close');
   }
 </script>
 <style lang="less" scoped>
@@ -42,32 +42,35 @@
     .module-content__title__expand {
       width: 100%;
       height: var(--bg-height);
-      background: url('../../../../../assets/images/home-container/configurable/model_right_title_bg_expand.png') no-repeat;
+      line-height: var(--bg-height);
+      background: url('@/assets/images/home-container/configurable/model_right_title_bg_expand.png') no-repeat;
       background-size: 100% 100%;
       position: relative;
       text-align: left;
-      padding: 4px 0 0 10%;
+      padding: 0 0 0 10%;
     }
 
     .module-content__title {
       width: 50%;
       height: var(--bg-height);
-      background: url('../../../../../assets/images/home-container/configurable/model_right_title_bg.png') no-repeat;
+      line-height: var(--bg-height);
+      background: url('@/assets/images/home-container/configurable/model_right_title_bg.png') no-repeat;
       background-size: 100% 100%;
       position: relative;
       text-align: left;
       margin-left: 50%;
-      padding: 4px 0 0 10%;
+      padding: 0 0 0 10%;
     }
 
     // 固定在父容器右上角的按钮图标
     .action-btn {
       width: 18px;
       height: 18px;
-      background: url('../../../../../assets/images/home-container/configurable/expand.svg') no-repeat center;
+      background: url('@/assets/images/home-container/configurable/expand.svg') no-repeat center;
       position: absolute;
       left: 0;
       top: 0;
+      cursor: pointer;
     }
     .show-btn {
       transform: rotate(-90deg);

+ 2 - 2
src/views/vent/home/configurable/components/original/moduleBottom.vue

@@ -21,10 +21,10 @@
 </template>
 <script lang="ts" setup>
   defineProps<{ title: string; visible: boolean }>();
-  const emit = defineEmits(['update:visible']);
+  const emit = defineEmits(['close']);
 
   function closeModel() {
-    emit('update:visible', false);
+    emit('close');
   }
 </script>
 <style lang="less" scoped>

+ 2 - 2
src/views/vent/home/configurable/components/original/moduleLeft.vue

@@ -21,10 +21,10 @@
 </template>
 <script lang="ts" setup>
   defineProps<{ title: string; visible: boolean }>();
-  const emit = defineEmits(['update:visible']);
+  const emit = defineEmits(['close']);
 
   function closeModel() {
-    emit('update:visible', false);
+    emit('close');
   }
 </script>
 <style lang="less" scoped>

+ 454 - 327
src/views/vent/home/configurable/configurable.data.ts

@@ -350,26 +350,29 @@ export const testConfigA: Config[] = [
       layout: ['board'],
       board: [
         {
-          label: '风速1',
           type: 'A',
           layout: 'val-top',
-          prop: 'readData.windSpeed1',
-        },
-        {
-          label: '风速2',
-          type: 'B',
-          layout: 'label-top',
-          prop: 'readData.windSpeed2',
+          items: [
+            {
+              prop: 'readData.windSpeed1',
+              label: '风速1',
+            },
+            {
+              label: '风速2',
+              prop: 'readData.windSpeed2',
+            },
+          ],
         },
       ],
       list: [],
       chart: [],
       table: [],
+      preset: [],
     },
     showStyle: {
-      size: 'width:450px;height:280px;',
+      size: '标准尺寸(450*280)',
       version: 'enhanced',
-      position: 'top:60px;left:0;',
+      position: '左上',
     },
   },
   {
@@ -413,11 +416,12 @@ export const testConfigA: Config[] = [
         },
       ],
       table: [],
+      preset: [],
     },
     showStyle: {
-      size: 'width:450px;height:280px;',
+      size: '标准尺寸(450*280)',
       version: 'enhanced',
-      position: 'top:350px;left:0;',
+      position: '左中',
     },
   },
   {
@@ -448,11 +452,12 @@ export const testConfigA: Config[] = [
       chart: [],
       table: [],
       list: [],
+      preset: [{}],
     },
     showStyle: {
-      size: 'width:450px;height:280px;',
+      size: '标准尺寸(450*280)',
       version: 'enhanced',
-      position: 'top:640px;left:0;',
+      position: '左下',
     },
   },
   {
@@ -482,6 +487,7 @@ export const testConfigA: Config[] = [
       board: [],
       list: [],
       table: [],
+      preset: [],
       chart: [
         {
           type: 'bar',
@@ -499,9 +505,9 @@ export const testConfigA: Config[] = [
       ],
     },
     showStyle: {
-      size: 'width:1000px;height:280px;',
+      size: '横向拉伸(1000*280)',
       version: 'enhanced',
-      position: 'top:640px;left:460px;',
+      position: '中下',
     },
   },
   {
@@ -530,13 +536,101 @@ export const testConfigA: Config[] = [
       list: [],
       table: [],
       chart: [],
+      preset: [{}],
     },
     showStyle: {
-      size: 'width:450px;height:280px;',
+      size: '标准尺寸(450*280)',
       version: 'enhanced',
-      position: 'top:60px;right:0;',
+      position: '右上',
     },
   },
+  // {
+  //   deviceType: 'sys_majorpath',
+  //   moduleName: 'unknown-右中',
+  //   pageType: '',
+  //   moduleData: {
+  //     header: {
+  //       show: false,
+  //       showSelector: true,
+  //       showSlot: true,
+  //       selector: {
+  //         prop: 'devicePos',
+  //       },
+  //       slot: {
+  //         prop: 'devicePos',
+  //       },
+  //     },
+  //     background: {
+  //       show: false,
+  //       type: 'video',
+  //       link: '',
+  //     },
+  //     layout: ['table'],
+  //     board: [],
+  //     list: [],
+  //     preset: [],
+  //     table: [
+  //       {
+  //         type: 'A',
+  //         readFrom: 'history',
+  //         columns: [
+  //           {
+  //             prop: 'index',
+  //             label: '编号',
+  //           },
+  //           {
+  //             prop: 'time',
+  //             label: '报警时间',
+  //           },
+  //           {
+  //             prop: 'warn',
+  //             label: '报警内容',
+  //           },
+  //         ],
+  //       },
+  //     ],
+  //     chart: [],
+  //   },
+  //   showStyle: {
+  //     size: '标准尺寸(450*280)',
+  //     version: 'enhanced',
+  //     position: '右中',
+  //   },
+  // },
+  // {
+  //   deviceType: 'sys_majorpath',
+  //   moduleName: 'fire_control-右下预设类',
+  //   pageType: '',
+  //   moduleData: {
+  //     header: {
+  //       show: false,
+  //       showSelector: true,
+  //       showSlot: true,
+  //       selector: {
+  //         prop: 'devicePos',
+  //       },
+  //       slot: {
+  //         prop: 'devicePos',
+  //       },
+  //     },
+  //     background: {
+  //       show: false,
+  //       type: 'video',
+  //       link: '',
+  //     },
+  //     layout: ['fire_control'],
+  //     board: [],
+  //     list: [],
+  //     table: [],
+  //     chart: [],
+  //     preset: [{}],
+  //   },
+  //   showStyle: {
+  //     size: '标准尺寸(450*280)',
+  //     version: 'enhanced',
+  //     position: '右下',
+  //   },
+  // },
   {
     deviceType: 'sys_majorpath',
     moduleName: 'unknown-右中',
@@ -561,21 +655,27 @@ export const testConfigA: Config[] = [
       layout: ['table'],
       board: [],
       list: [],
+      preset: [],
       table: [
         {
+          type: 'A',
           readFrom: 'history',
           columns: [
             {
-              prop: 'index',
-              label: '编号',
+              prop: 'cate',
+              label: '类别',
             },
             {
-              prop: 'time',
-              label: '报警时间',
+              prop: 'temp',
+              label: '温度',
             },
             {
-              prop: 'warn',
-              label: '报警内容',
+              prop: 'wspd',
+              label: '风速',
+            },
+            {
+              prop: 'spst',
+              label: '喷雾状态',
             },
           ],
         },
@@ -583,9 +683,9 @@ export const testConfigA: Config[] = [
       chart: [],
     },
     showStyle: {
-      size: 'width:450px;height:280px;',
+      size: '标准尺寸(450*280)',
       version: 'enhanced',
-      position: 'top:350px;right:0;',
+      position: '右中',
     },
   },
   {
@@ -609,325 +709,352 @@ export const testConfigA: Config[] = [
         type: 'video',
         link: '',
       },
-      layout: ['fire_control'],
-      board: [],
-      list: [],
-      table: [],
-      chart: [],
-    },
-    showStyle: {
-      size: 'width:450px;height:280px;',
-      version: 'enhanced',
-      position: 'top:640px;right:0;',
-    },
-  },
-];
-
-export const testConfigB: Config[] = [
-  {
-    deviceType: 'warn',
-    moduleName: 'warn-左上',
-    pageType: '',
-    moduleData: {
-      header: {
-        show: false,
-        showSelector: false,
-        showSlot: true,
-        selector: {
-          prop: 'strinstallpos',
-        },
-        slot: {
-          prop: 'netstatus.val',
-          formatter: '网络异常:${} 台',
-        },
-      },
-      background: {
-        show: false,
-        type: 'video',
-        link: '',
-      },
       layout: ['list'],
       board: [],
-      chart: [],
-      table: [],
       list: [
         {
-          label: '正常',
-          prop: 'blue.val',
-          color: 'blue',
-          type: 'timeline',
-        },
-        {
-          label: '告警',
-          prop: 'orange.val',
-          color: 'orange',
-          type: 'timeline',
-        },
-        {
-          label: '报警',
-          prop: 'yellow.val',
-          color: 'yellow',
-          type: 'timeline',
-        },
-        {
-          label: '危险',
-          prop: 'red.val',
-          color: 'red',
-          type: 'timeline',
-        },
-        {
-          label: '错误',
-          prop: 'alarm.val',
-          color: 'green',
-          type: 'timeline',
-        },
-      ],
-    },
-    showStyle: {
-      size: 'width:450px;height:280px;',
-      version: 'enhanced',
-      position: 'top:60px;left:0;',
-    },
-  },
-  {
-    deviceType: 'sys_wind',
-    moduleName: 'sys_wind-左中',
-    pageType: '',
-    moduleData: {
-      header: {
-        show: false,
-        showSelector: true,
-        showSlot: false,
-        selector: {
-          prop: 'strinstallpos',
-        },
-        slot: {
-          prop: 'strinstallpos',
-        },
-      },
-      background: {
-        show: false,
-        type: 'video',
-        link: '',
-      },
-      layout: ['board', 'chart', 'table'],
-      board: [
-        {
-          label: 'F1',
-          type: 'C',
-          layout: 'val-top',
-          prop: 'f1Val',
-        },
-        {
-          label: 'F2',
-          type: 'C',
-          layout: 'val-top',
-          prop: 'f2Val',
-        },
-      ],
-      list: [],
-      table: [
-        {
-          readFrom: 'history',
-          columns: [
+          type: 'A',
+          items: [
             {
-              prop: 'index',
-              label: '编号',
+              prop: 'total',
+              label: '设备总数',
+              color: 'blue',
             },
             {
-              prop: 'time',
-              label: '自定义字段A',
+              prop: 'pwkqs',
+              label: '喷雾开启数',
+              color: 'blue',
             },
             {
-              prop: 'warn',
-              label: '自定义字段B',
+              prop: 'online',
+              label: '联网数量',
+              color: 'blue',
+            },
+            {
+              prop: 'offline',
+              label: '断网数量',
+              color: 'blue',
             },
-          ],
-        },
-      ],
-      chart: [
-        {
-          type: 'pie',
-          readFrom: 'readData',
-          xAxis: [{ prop: 'stationname' }],
-          yAxis: [
-            { label: '风量1', align: 'left' },
-            // { label: '回2', align: 'right' },
-          ],
-          series: [
-            { label: '风量1', prop: 'va' },
-            { label: '风量2', prop: 'va2' },
-            // { label: '回2', prop: 'hui2' },
-          ],
-        },
-      ],
-    },
-    showStyle: {
-      size: 'width:450px;height:570px;',
-      version: 'enhanced',
-      position: 'top:350px;left:0;',
-    },
-  },
-  {
-    deviceType: 'midinfo',
-    moduleName: 'midinfo-中间',
-    pageType: '',
-    moduleData: {
-      header: {
-        show: false,
-        showSelector: false,
-        showSlot: false,
-        selector: {
-          icon: 'SwapOutlined',
-          prop: 'strinstallpos',
-        },
-        slot: {
-          icon: 'SwapOutlined',
-          prop: 'strinstallpos',
-        },
-      },
-      background: {
-        show: false,
-        type: 'video',
-        link: '',
-      },
-      layout: ['chart'],
-      board: [],
-      list: [],
-      table: [],
-      chart: [
-        {
-          type: 'bar',
-          readFrom: 'sysdata.history',
-          xAxis: [{ prop: 'time' }],
-          yAxis: [
-            { label: '回1', align: 'left' },
-            // { label: '回2', align: 'right' },
-          ],
-          series: [
-            { label: '回1', prop: 'hui1' },
-            // { label: '回2', prop: 'hui2' },
-          ],
-        },
-      ],
-    },
-    showStyle: {
-      size: 'width:1000px;height:280px;',
-      version: 'enhanced',
-      position: 'top:640px;left:460px;',
-    },
-  },
-  {
-    deviceType: 'sys_majorpath',
-    moduleName: 'sys_majorpath-右上',
-    pageType: '',
-    moduleData: {
-      header: {
-        show: true,
-        showSelector: true,
-        showSlot: true,
-        selector: {
-          prop: 'strinstallpos',
-        },
-        slot: {
-          prop: 'strinstallpos',
-        },
-      },
-      background: {
-        show: false,
-        type: 'video',
-        link: '',
-      },
-      layout: ['chart'],
-      board: [],
-      list: [],
-      chart: [
-        {
-          type: 'line',
-          readFrom: 'majorpath.paths',
-          xAxis: [{ prop: 'name' }],
-          yAxis: [
-            { label: 'Drag', align: 'left' },
-            { label: 'M3', align: 'right' },
-          ],
-          series: [
-            { label: 'Drag', prop: 'drag' },
-            { label: 'M3', prop: 'm3' },
-            // { label: '回2', prop: 'hui2' },
           ],
         },
       ],
       table: [],
-    },
-    showStyle: {
-      size: 'width:450px;height:280px;',
-      version: 'enhanced',
-      position: 'top:60px;right:0;',
-    },
-  },
-  {
-    deviceType: 'warn',
-    moduleName: 'warn-右中',
-    pageType: '',
-    moduleData: {
-      header: {
-        show: false,
-        showSelector: false,
-        showSlot: true,
-        selector: {
-          prop: 'strinstallpos',
-        },
-        slot: {
-          prop: 'netstatus.val',
-          formatter: '网络异常:${} 台',
-        },
-      },
-      background: {
-        show: false,
-        type: 'video',
-        link: '',
-      },
-      layout: ['list'],
-      board: [],
       chart: [],
-      table: [],
-      list: [
-        {
-          label: '正常',
-          prop: 'blue.val',
-          color: 'blue',
-          type: 'B',
-        },
-        {
-          label: '告警',
-          prop: 'orange.val',
-          color: 'orange',
-          type: 'B',
-        },
-        {
-          label: '报警',
-          prop: 'yellow.val',
-          color: 'yellow',
-          type: 'B',
-        },
-        {
-          label: '危险',
-          prop: 'red.val',
-          color: 'red',
-          type: 'B',
-        },
-        {
-          label: '错误',
-          prop: 'alarm.val',
-          color: 'green',
-          type: 'B',
-        },
-      ],
+      preset: [],
     },
     showStyle: {
-      size: 'width:450px;height:280px;',
+      size: '标准尺寸(450*280)',
       version: 'enhanced',
-      position: 'top:350px;right:0;',
+      position: '右下',
     },
   },
 ];
+
+export const testConfigB: Config[] = [
+  // {
+  //   deviceType: 'warn',
+  //   moduleName: 'warn-左上',
+  //   pageType: '',
+  //   moduleData: {
+  //     header: {
+  //       show: false,
+  //       showSelector: false,
+  //       showSlot: true,
+  //       selector: {
+  //         prop: 'strinstallpos',
+  //       },
+  //       slot: {
+  //         prop: 'netstatus.val',
+  //         formatter: '网络异常:${} 台',
+  //       },
+  //     },
+  //     background: {
+  //       show: false,
+  //       type: 'video',
+  //       link: '',
+  //     },
+  //     layout: ['list'],
+  //     board: [],
+  //     chart: [],
+  //     table: [],
+  //     list: [
+  //       {
+  //         label: '正常',
+  //         prop: 'blue.val',
+  //         color: 'blue',
+  //         type: 'timeline',
+  //       },
+  //       {
+  //         label: '告警',
+  //         prop: 'orange.val',
+  //         color: 'orange',
+  //         type: 'timeline',
+  //       },
+  //       {
+  //         label: '报警',
+  //         prop: 'yellow.val',
+  //         color: 'yellow',
+  //         type: 'timeline',
+  //       },
+  //       {
+  //         label: '危险',
+  //         prop: 'red.val',
+  //         color: 'red',
+  //         type: 'timeline',
+  //       },
+  //       {
+  //         label: '错误',
+  //         prop: 'alarm.val',
+  //         color: 'green',
+  //         type: 'timeline',
+  //       },
+  //     ],
+  //   },
+  //   showStyle: {
+  //     size: 'width:450px;height:280px;',
+  //     version: 'enhanced',
+  //     position: 'top:60px;left:0;',
+  //   },
+  // },
+  // {
+  //   deviceType: 'sys_wind',
+  //   moduleName: 'sys_wind-左中',
+  //   pageType: '',
+  //   moduleData: {
+  //     header: {
+  //       show: false,
+  //       showSelector: true,
+  //       showSlot: false,
+  //       selector: {
+  //         prop: 'strinstallpos',
+  //       },
+  //       slot: {
+  //         prop: 'strinstallpos',
+  //       },
+  //     },
+  //     background: {
+  //       show: false,
+  //       type: 'video',
+  //       link: '',
+  //     },
+  //     layout: ['board', 'chart', 'table'],
+  //     board: [
+  //       {
+  //         label: 'F1',
+  //         type: 'C',
+  //         layout: 'val-top',
+  //         prop: 'f1Val',
+  //       },
+  //       {
+  //         label: 'F2',
+  //         type: 'C',
+  //         layout: 'val-top',
+  //         prop: 'f2Val',
+  //       },
+  //     ],
+  //     list: [],
+  //     table: [
+  //       {
+  //         readFrom: 'history',
+  //         columns: [
+  //           {
+  //             prop: 'index',
+  //             label: '编号',
+  //           },
+  //           {
+  //             prop: 'time',
+  //             label: '自定义字段A',
+  //           },
+  //           {
+  //             prop: 'warn',
+  //             label: '自定义字段B',
+  //           },
+  //         ],
+  //       },
+  //     ],
+  //     chart: [
+  //       {
+  //         type: 'pie',
+  //         readFrom: 'readData',
+  //         xAxis: [{ prop: 'stationname' }],
+  //         yAxis: [
+  //           { label: '风量1', align: 'left' },
+  //           // { label: '回2', align: 'right' },
+  //         ],
+  //         series: [
+  //           { label: '风量1', prop: 'va' },
+  //           { label: '风量2', prop: 'va2' },
+  //           // { label: '回2', prop: 'hui2' },
+  //         ],
+  //       },
+  //     ],
+  //   },
+  //   showStyle: {
+  //     size: 'width:450px;height:570px;',
+  //     version: 'enhanced',
+  //     position: 'top:350px;left:0;',
+  //   },
+  // },
+  // {
+  //   deviceType: 'midinfo',
+  //   moduleName: 'midinfo-中间',
+  //   pageType: '',
+  //   moduleData: {
+  //     header: {
+  //       show: false,
+  //       showSelector: false,
+  //       showSlot: false,
+  //       selector: {
+  //         icon: 'SwapOutlined',
+  //         prop: 'strinstallpos',
+  //       },
+  //       slot: {
+  //         icon: 'SwapOutlined',
+  //         prop: 'strinstallpos',
+  //       },
+  //     },
+  //     background: {
+  //       show: false,
+  //       type: 'video',
+  //       link: '',
+  //     },
+  //     layout: ['chart'],
+  //     board: [],
+  //     list: [],
+  //     table: [],
+  //     chart: [
+  //       {
+  //         type: 'bar',
+  //         readFrom: 'sysdata.history',
+  //         xAxis: [{ prop: 'time' }],
+  //         yAxis: [
+  //           { label: '回1', align: 'left' },
+  //           // { label: '回2', align: 'right' },
+  //         ],
+  //         series: [
+  //           { label: '回1', prop: 'hui1' },
+  //           // { label: '回2', prop: 'hui2' },
+  //         ],
+  //       },
+  //     ],
+  //   },
+  //   showStyle: {
+  //     size: 'width:1000px;height:280px;',
+  //     version: 'enhanced',
+  //     position: 'top:640px;left:460px;',
+  //   },
+  // },
+  // {
+  //   deviceType: 'sys_majorpath',
+  //   moduleName: 'sys_majorpath-右上',
+  //   pageType: '',
+  //   moduleData: {
+  //     header: {
+  //       show: true,
+  //       showSelector: true,
+  //       showSlot: true,
+  //       selector: {
+  //         prop: 'strinstallpos',
+  //       },
+  //       slot: {
+  //         prop: 'strinstallpos',
+  //       },
+  //     },
+  //     background: {
+  //       show: false,
+  //       type: 'video',
+  //       link: '',
+  //     },
+  //     layout: ['chart'],
+  //     board: [],
+  //     list: [],
+  //     chart: [
+  //       {
+  //         type: 'line',
+  //         readFrom: 'majorpath.paths',
+  //         xAxis: [{ prop: 'name' }],
+  //         yAxis: [
+  //           { label: 'Drag', align: 'left' },
+  //           { label: 'M3', align: 'right' },
+  //         ],
+  //         series: [
+  //           { label: 'Drag', prop: 'drag' },
+  //           { label: 'M3', prop: 'm3' },
+  //           // { label: '回2', prop: 'hui2' },
+  //         ],
+  //       },
+  //     ],
+  //     table: [],
+  //   },
+  //   showStyle: {
+  //     size: 'width:450px;height:280px;',
+  //     version: 'enhanced',
+  //     position: 'top:60px;right:0;',
+  //   },
+  // },
+  // {
+  //   deviceType: 'warn',
+  //   moduleName: 'warn-右中',
+  //   pageType: '',
+  //   moduleData: {
+  //     header: {
+  //       show: false,
+  //       showSelector: false,
+  //       showSlot: true,
+  //       selector: {
+  //         prop: 'strinstallpos',
+  //       },
+  //       slot: {
+  //         prop: 'netstatus.val',
+  //         formatter: '网络异常:${} 台',
+  //       },
+  //     },
+  //     background: {
+  //       show: false,
+  //       type: 'video',
+  //       link: '',
+  //     },
+  //     layout: ['list'],
+  //     board: [],
+  //     chart: [],
+  //     table: [],
+  //     list: [
+  //       {
+  //         label: '正常',
+  //         prop: 'blue.val',
+  //         color: 'blue',
+  //         type: 'B',
+  //       },
+  //       {
+  //         label: '告警',
+  //         prop: 'orange.val',
+  //         color: 'orange',
+  //         type: 'B',
+  //       },
+  //       {
+  //         label: '报警',
+  //         prop: 'yellow.val',
+  //         color: 'yellow',
+  //         type: 'B',
+  //       },
+  //       {
+  //         label: '危险',
+  //         prop: 'red.val',
+  //         color: 'red',
+  //         type: 'B',
+  //       },
+  //       {
+  //         label: '错误',
+  //         prop: 'alarm.val',
+  //         color: 'green',
+  //         type: 'B',
+  //       },
+  //     ],
+  //   },
+  //   showStyle: {
+  //     size: 'width:450px;height:280px;',
+  //     version: 'enhanced',
+  //     position: 'top:350px;right:0;',
+  //   },
+  // },
+];

+ 43 - 17
src/views/vent/home/configurable/index.vue

@@ -14,28 +14,34 @@
       </template>
     </a-dropdown>
     <!-- 采用定位方式以避免出现各个模块隐藏时其他模块下移的问题 -->
-
-    <!-- <SubVentilate />
-    <Ventilate />
-    <VentilateControl />
-    <AirVolumeMonitor />
-    <VentilateAnalysis />
-    <WorkSurface />
-    <DeviceWarning /> -->
     <template v-if="isOriginal">
-      <ModuleOriginal v-for="cfg in configs" :key="cfg.deviceType" :show-style="cfg.showStyle" :module-name="cfg.moduleName" :visible="visible">
+      <ModuleOriginal v-for="cfg in configs" :key="cfg.deviceType" :show-style="cfg.showStyle" :module-name="cfg.moduleName" :visible="true">
         <Content v-bind="cfg" />
       </ModuleOriginal>
     </template>
     <template v-else>
-      <ModuleEnhanced v-for="cfg in configs" :key="cfg.deviceType" :show-style="cfg.showStyle" :module-name="cfg.moduleName" :visible="visible">
+      <!-- 下面是正常展示的各新版模块 -->
+      <ModuleEnhanced
+        v-for="cfg in enhancedConfigs"
+        :key="cfg.deviceType"
+        :visible="cfg.visible"
+        :show-style="cfg.showStyle"
+        :module-name="cfg.moduleName"
+        @close="cfg.visible = false"
+      >
         <Content v-bind="cfg" />
       </ModuleEnhanced>
+      <!-- 下面是用于呼出已隐藏的模块的按钮 -->
+      <div class="pos-absolute top-70px left-460px">
+        <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>
 </template>
 <script lang="ts" setup>
-  import { onMounted, ref } from 'vue';
+  import { computed, onMounted, ref } from 'vue';
   // import SubVentilate from './components/SubVentilate.vue';
   // import Ventilate from './components/Ventilate.vue';
   import { CaretDownOutlined } from '@ant-design/icons-vue';
@@ -50,23 +56,37 @@
   import ModuleEnhanced from './components/ModuleEnhanced.vue';
   import ModuleOriginal from './components/ModuleOriginal.vue';
   import Content from './components/content.vue';
-  import { testConfigA, testConfigB } from './configurable.data';
+  import { testConfigA } from './configurable.data';
   // import mapComponent from './components/3Dmap/index.vue';
 
+  interface EnhancedConfig extends Config {
+    visible: boolean;
+  }
+
   const mainTitle = ref('智能通风管控系统');
 
   // const moduleCodes = ['fanlocal', 'fanmain' /** 'vc', 'ar', 'va', 'ws', 'dw' */];
 
-  // const configs = ref<Config[]>(testConfigB);
-  const configs = ref<Config[]>(testConfigA);
+  const configs = ref<Config[]>([]);
+  const enhancedConfigs = ref<EnhancedConfig[]>([]);
 
-  const isOriginal = true;
-  // const isOriginal = false;
+  // const isOriginal = true;
+  const isOriginal = false;
 
-  const visible = ref(true);
+  const hiddenList = computed(() => {
+    return enhancedConfigs.value.filter((e) => e.visible === false);
+  });
   // const { configs, isOriginal, fetchConfigs } = useInitConfigs();
 
   onMounted(() => {
+    // configs.value = testConfigB;
+    configs.value = testConfigA;
+    enhancedConfigs.value = configs.value.map((c) => {
+      return {
+        visible: true,
+        ...c,
+      };
+    });
     // fetchConfigs();
   });
 </script>
@@ -134,5 +154,11 @@
       top: 70px;
       right: 460px;
     }
+    .module-trigger-button {
+      color: #fff;
+      background-image: linear-gradient(to bottom, #036886, #072a40);
+      border: none;
+      border-bottom: 2px solid #3df6ff;
+    }
   }
 </style>