Ver Fonte

[Feat 0000]新增除尘装置控制系统

wangkeyi há 14 horas atrás
pai
commit
83f5a28a5a

BIN
src/assets/images/home-container/configurable/minehome/button-bg-a.png


BIN
src/assets/images/home-container/configurable/minehome/list-bg-n1.png


BIN
src/assets/images/home-container/configurable/minehome/list-bg-n2.png


BIN
src/assets/images/home-container/configurable/minehome/list-bg-n3.png


BIN
src/assets/images/home-container/configurable/minehome/list-bg-n4.png


+ 4 - 2
src/views/vent/deviceManager/configurationTable/types.ts

@@ -95,7 +95,9 @@ export interface ModuleData {
         | 'ai_chat'
         | 'device_alarm'
         | 'partition'
-        | 'selector_dual_chart';
+        | 'selector_dual_chart'
+        | 'radio_label'
+        | 'button_list';
       /** 分区大小 */
       basis: string;
       overflow?: boolean;
@@ -159,7 +161,7 @@ export interface ModuleDataBoard extends ReadFrom {
 
 export interface ModuleDataList extends ReadFrom {
   /** 列表预设的背景类型 */
-  type: 'timeline' | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'timelineNew' | 'fireList' | 'L' | 'M';
+  type: 'timeline' | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'timelineNew' | 'fireList' | 'L' | 'M' | 'N';
   /** 是否需要根据数据来决定所展示的项目数量,需要确保 items 至少有一项,且 readFrom 指向数组 */
   mapFromData?: boolean;
   /** 核心配置,每个列表项对应一项 */

+ 114 - 132
src/views/vent/home/configurable/components/ModuleCommonDual.vue

@@ -12,27 +12,9 @@
     </template>
     <template #container>
       <slot>
-        <Header
-          v-if="index === 0"
-          :deviceType="deviceTypeA"
-          :moduleData="moduleDataA"
-          :data="data"
-          @select="selectedDataA = $event"
-        />
-        <Header
-          v-if="index === 1"
-          :deviceType="deviceTypeB"
-          :moduleData="moduleDataB"
-          :data="data"
-          @select="selectedDataB = $event"
-        />
-        <Header
-          v-if="index === 2"
-          :deviceType="deviceTypeC"
-          :moduleData="moduleDataC"
-          :data="data"
-          @select="selectedDataC = $event"
-        />
+        <Header v-if="index === 0" :deviceType="deviceTypeA" :moduleData="moduleDataA" :data="data" @select="selectedDataA = $event" />
+        <Header v-if="index === 1" :deviceType="deviceTypeB" :moduleData="moduleDataB" :data="data" @select="selectedDataB = $event" />
+        <Header v-if="index === 2" :deviceType="deviceTypeC" :moduleData="moduleDataC" :data="data" @select="selectedDataC = $event" />
         <Content
           v-if="index === 0"
           :style="{ height: moduleDataA.header?.show ? 'calc(100% - 30px)' : '100%' }"
@@ -57,134 +39,134 @@
 </template>
 
 <script lang="ts" setup>
-import Header from './header.vue';
-import Content from './content.vue';
-import { computed, ref } from 'vue';
-import ventBox1 from '/@/components/vent/ventBox1.vue';
-import { openWindow } from '/@/utils';
-import { getFormattedText } from '../hooks/helper';
+  import Header from './header.vue';
+  import Content from './content.vue';
+  import { computed, ref } from 'vue';
+  import ventBox1 from '/@/components/vent/ventBox1.vue';
+  import { openWindow } from '/@/utils';
+  import { getFormattedText } from '../hooks/helper';
+
+  const props = defineProps<{
+    moduleDataA: any;
+    moduleNameA: string;
+    deviceTypeA: string;
+    moduleDataB: any;
+    moduleNameB: string;
+    deviceTypeB: string;
+    moduleDataC: any;
+    moduleNameC: string;
+    deviceTypeC: string;
+    showStyle: any;
+    visible: boolean;
+    data: any;
+    commonTitle: string;
+  }>();
+  defineEmits(['close', 'click']);
 
-const props = defineProps<{
-  moduleDataA: any;
-  moduleNameA: string;
-  deviceTypeA: string;
-  moduleDataB: any;
-  moduleNameB: string;
-  deviceTypeB: string;
-  moduleDataC: any;
-  moduleNameC: string;
-  deviceTypeC: string;
-  showStyle: any;
-  visible: boolean;
-  data: any;
-  commonTitle: string;
-}>();
-defineEmits(['close', 'click']);
+  const index = ref(0);
 
-const index = ref(0);
+  const selectedDataA = ref();
+  const selectedDataB = ref();
+  const selectedDataC = ref();
 
-const selectedDataA = ref();
-const selectedDataB = ref();
-const selectedDataC = ref();
+  const style = computed(() => {
+    const size = props.showStyle.size;
+    const position = props.showStyle.position;
 
-const style = computed(() => {
-  const size = props.showStyle.size;
-  const position = props.showStyle.position;
-  
-  return size + position + ';position: absolute; pointer-events: auto;';
-});
+    return size + position + ';position: absolute; pointer-events: auto;';
+  });
 
-// 根据配置里的定位判断应该使用哪个class
-function getModuleClass({ size, position }) {
-  const [_, width] = size.match(/width:([0-9]+)px/) || [];
-  if (position.includes('bottom') || parseInt(width) > 800) {
-    return 'module-common-dual module-common-dual-longer';
+  // 根据配置里的定位判断应该使用哪个class
+  function getModuleClass({ size, position }) {
+    const [_, width] = size.match(/width:([0-9]+)px/) || [];
+    if (position.includes('bottom') || parseInt(width) > 800) {
+      return 'module-common-dual module-common-dual-longer';
+    }
+    return 'module-common-dual';
   }
-  return 'module-common-dual';
-}
 
-// 跳转
-function redirectToA() {
-  const { to } = props.moduleDataA;
-  if (!to) return;
-  openWindow(getFormattedText(selectedDataA.value, to));
-}
-function redirectToB() {
-  const { to } = props.moduleDataB;
-  if (!to) return;
-  openWindow(getFormattedText(selectedDataB.value, to));
-}
-function redirectToC() {
-  const { to } = props.moduleDataC;
-  if (!to) return;
-  openWindow(getFormattedText(selectedDataC.value, to));
-}
+  // 跳转
+  function redirectToA() {
+    const { to } = props.moduleDataA;
+    if (!to) return;
+    openWindow(getFormattedText(selectedDataA.value, to));
+  }
+  function redirectToB() {
+    const { to } = props.moduleDataB;
+    if (!to) return;
+    openWindow(getFormattedText(selectedDataB.value, to));
+  }
+  function redirectToC() {
+    const { to } = props.moduleDataC;
+    if (!to) return;
+    openWindow(getFormattedText(selectedDataC.value, to));
+  }
 </script>
 
 <style lang="less" scoped>
-@import '/@/design/theme.less';
+  @import '/@/design/theme.less';
 
-.module-common-dual .box1-center {
-  height: calc(100% - 48px);
-}
+  .module-common-dual .box1-center {
+    height: calc(100% - 48px);
+  }
 
-:deep(.box1-center) {
-  height: calc(100% - 48px);
-}
-:deep(.box1-center > .box-container) {
-  height: 100%;
-  padding: 0 !important;
-  width: 100% !important;
-}
-.dual-title {
-  position: relative;
-  width: 100%;
-  height: 100%;
-  align-items: center;
-  display: flex;
-  font-size: 14px;
-  .title-center {
-    position: absolute;
-    left: 50%;
-    transform: translateX(-50%);
+  :deep(.box1-center) {
+    height: calc(100% - 48px);
+  }
+  :deep(.box1-center > .box-container) {
+    height: 100%;
+    padding: 0 !important;
+    width: 100% !important;
   }
-  .title-left {
+  .dual-title {
+    position: relative;
+    width: 100%;
     height: 100%;
-    margin-left: 30px;
+    align-items: center;
     display: flex;
-    div {
-      display: flex;
-      align-items: center;
+    font-size: 14px;
+    .title-center {
+      position: absolute;
+      left: 50%;
+      transform: translateX(-50%);
+    }
+    .title-left {
       height: 100%;
-      cursor: pointer;
-      padding: 0 12px;
-      color: #8087a1;
+      margin-left: 30px;
+      display: flex;
+      div {
+        display: flex;
+        align-items: center;
+        height: 100%;
+        cursor: pointer;
+        padding: 0 12px;
+        color: #8087a1;
+      }
     }
-  }
 
-  .deactived {
-    color: #fff !important;
-    background: linear-gradient(to top, #2bafc6 0%, rgba(44, 255, 221, 0.1) 50%,rgba(44, 255, 221, 0) 90%);
-  }
-}
-// @{theme-deepblue} {
-//   .module-common-dual-longer {
-//     :deep(.box1-top) {
-//       --image-box1-top: url('/@/assets/images/themify/deepblue/vent/border/box2-top-long.png');
-//     }
-//     :deep(.box1-bottom) {
-//       --image-box1-bottom: none;
-//     }
-//   }
-// }
-.module-common-dual-longer {
-  :deep(.box1-top) {
-    --image-box1-top: url('/@/assets/images/vent/box-top-bg.png');
-    background-image: var(--image-box1-top);
+    .deactived {
+      color: #fff !important;
+      background: linear-gradient(to top, #2bafc6 0%, rgba(44, 255, 221, 0.1) 50%, rgba(44, 255, 221, 0) 90%);
+    }
   }
-  :deep(.box1-bottom) {
-    --image-box1-bottom: url('/@/assets/images/vent/box-bottom-bg.png');
-    background-image: var(--image-box1-bottom);
+  // @{theme-deepblue} {
+  //   .module-common-dual-longer {
+  //     :deep(.box1-top) {
+  //       --image-box1-top: url('/@/assets/images/themify/deepblue/vent/border/box2-top-long.png');
+  //     }
+  //     :deep(.box1-bottom) {
+  //       --image-box1-bottom: none;
+  //     }
+  //   }
+  // }
+  .module-common-dual-longer {
+    :deep(.box1-top) {
+      --image-box1-top: url('/@/assets/images/vent/box-top-bg.png');
+      background-image: var(--image-box1-top);
+    }
+    :deep(.box1-bottom) {
+      --image-box1-bottom: url('/@/assets/images/vent/box-bottom-bg.png');
+      background-image: var(--image-box1-bottom);
+    }
   }
-}
-</style>
+</style>

+ 398 - 366
src/views/vent/home/configurable/components/content.vue

@@ -3,37 +3,62 @@
   <!-- 主体内容部分 -->
   <div class="content">
     <!-- 背景 -->
-    <img v-if="background.show && background.type === 'image'" class="content__background image__background"
-      :src="background.link" />
-    <video v-if="background.show && background.type === 'video'" class="content__background content__background_video"
-      width="100%" autoplay loop muted disablepictureinpicture playsinline>
+    <img v-if="background.show && background.type === 'image'" class="content__background image__background" :src="background.link" />
+    <video
+      v-if="background.show && background.type === 'video'"
+      class="content__background content__background_video"
+      width="100%"
+      autoplay
+      loop
+      muted
+      disablepictureinpicture
+      playsinline
+    >
       <source :src="background.link" />
       Not Supportted Link Or Browser
     </video>
     <div class="flex w-full h-full" :style="{ flexDirection: layout.direction }">
-      <div v-for="config in layoutConfig" :key="config.name"
-        :style="{ flexBasis: config.basis, overflow: config.overflow ? 'auto' : 'none' }">
+      <div v-for="config in layoutConfig" :key="config.name" :style="{ flexBasis: config.basis, overflow: config.overflow ? 'auto' : 'none' }">
         <!-- 告示板部分 -->
         <template v-if="config.name === 'board'">
-          <div v-if="config.pageType == 'vent_New'" style="padding-top: 11%"
-            class="content__module content__module1 flex flex-justify-around flex-items-center flex-wrap">
-            <MiniBoard v-for="item in config.items" :key="item.prop" :label="item.label" :value="item.value"
-              :type="config.type" :layout="config.layout" />
+          <div
+            v-if="config.pageType == 'vent_New'"
+            style="padding-top: 11%"
+            class="content__module content__module1 flex flex-justify-around flex-items-center flex-wrap"
+          >
+            <MiniBoard
+              v-for="item in config.items"
+              :key="item.prop"
+              :label="item.label"
+              :value="item.value"
+              :type="config.type"
+              :layout="config.layout"
+            />
           </div>
-          <div v-else-if="config.pageType == 'New_fire'"
-            class="content__module flex flex-justify-around flex-items-center flex-wrap">
-            <MiniBoardNew v-for="item in config.items" :key="item.prop" :label="item.label" :value="item.value"
-              :type="config.type" :layout="config.layout" />
+          <div v-else-if="config.pageType == 'New_fire'" class="content__module flex flex-justify-around flex-items-center flex-wrap">
+            <MiniBoardNew
+              v-for="item in config.items"
+              :key="item.prop"
+              :label="item.label"
+              :value="item.value"
+              :type="config.type"
+              :layout="config.layout"
+            />
           </div>
           <div v-else class="content__module flex flex-justify-around flex-items-center flex-wrap">
-            <MiniBoard v-for="item in config.items" :key="item.prop" :label="item.label" :value="item.value"
-              :type="config.type" :layout="config.layout" />
+            <MiniBoard
+              v-for="item in config.items"
+              :key="item.prop"
+              :label="item.label"
+              :value="item.value"
+              :type="config.type"
+              :layout="config.layout"
+            />
           </div>
         </template>
         <!-- 图表部分,这部分通常需要填充,有告示板、Header等内容需要填充父级 -->
         <template v-if="config.name === 'chart'">
-          <CustomChart v-if="config.pageType == 'New_dust'" class="content__module_dust" :chart-config="config.config"
-            :chart-data="config.data" />
+          <CustomChart v-if="config.pageType == 'New_dust'" class="content__module_dust" :chart-config="config.config" :chart-data="config.data" />
           <CustomChart v-else class="content__module" :chart-config="config.config" :chart-data="config.data" />
         </template>
         <!-- 通常列表部分 -->
@@ -57,8 +82,7 @@
         </template>
         <!-- 复杂列表部分 -->
         <template v-if="config.name === 'gallery_list'">
-          <GalleryList class="content__module" :type="config.type" :list-config="config.items"
-            :gallery-config="config.galleryItems" />
+          <GalleryList class="content__module" :type="config.type" :list-config="config.items" :gallery-config="config.galleryItems" />
         </template>
         <!-- 复杂列表部分 -->
         <template v-if="config.name === 'complex_list'">
@@ -66,22 +90,22 @@
         </template>
         <!-- 表格部分,这部分通常是占一整个模块的 -->
         <template v-if="config.name === 'table'">
-          <CustomTable class="content__module text-center overflow-auto" :type="config.type" :columns="config.columns"
-            :data="config.data" />
+          <CustomTable class="content__module text-center overflow-auto" :type="config.type" :columns="config.columns" :data="config.data" />
         </template>
         <template v-if="config.name === 'tabs'">
-          <CustomTabs class="content__module" :type="config.type" :tab-config="config.items"
-            :overflow="config.overflow" />
+          <CustomTabs class="content__module" :type="config.type" :tab-config="config.items" :overflow="config.overflow" />
         </template>
         <template v-if="config.name === 'blast_delta'">
-          <BlastDelta v-if="config.pageType === 'New_fire'" class="content__moduleFire" :pos-monitor="config.data"
-            :canvasSize="{ width: 250, height: 200 }" />
-          <BlastDelta v-else class="content__module" :pos-monitor="config.data"
-            :canvasSize="{ width: 250, height: 200 }" />
+          <BlastDelta
+            v-if="config.pageType === 'New_fire'"
+            class="content__moduleFire"
+            :pos-monitor="config.data"
+            :canvasSize="{ width: 250, height: 200 }"
+          />
+          <BlastDelta v-else class="content__module" :pos-monitor="config.data" :canvasSize="{ width: 250, height: 200 }" />
         </template>
         <template v-if="config.name === 'qh_curve'">
-          <QHCurve class="content__module" :mainfan="config.data" :fan1-prop="config.config.fan1Prop"
-            :fan2-prop="config.config.fan2Prop" />
+          <QHCurve class="content__module" :mainfan="config.data" :fan1-prop="config.config.fan1Prop" :fan2-prop="config.config.fan2Prop" />
         </template>
         <template v-if="config.name === 'ai_chat'">
           <AIChat class="content__module" />
@@ -91,21 +115,28 @@
         </template>
         <!-- lxh -->
         <template v-if="config.name === 'select_cs'">
-          <SelectCs :devicedata="config.data" :setLabelData="config.config.setLabelConfig"  ></SelectCs>
+          <SelectCs :devicedata="config.data" :setLabelData="config.config.setLabelConfig" />
         </template>
         <template v-if="config.name === 'measure_detail'">
-          <MeasureDetail class="content__module" :show-title="false" :composite-data="config.data"
-            :topconfig="config.config.topconfig" :btnconfig="config.config.btnconfig" />
+          <MeasureDetail
+            class="content__module"
+            :show-title="false"
+            :composite-data="config.data"
+            :topconfig="config.config.topconfig"
+            :btnconfig="config.config.btnconfig"
+          />
         </template>
         <template v-if="config.name === 'partition'">
           <Partition class="content__module" :type="config.type" :label="config.label" :icon="config.icon" />
         </template>
         <template v-if="config.name === 'selector_dual_chart'">
-          <SelectorDualChart
-            :data="config.data"
-            :moduleData="props.moduleData"
-            :config="config"
-          />
+          <SelectorDualChart :data="config.data" :moduleData="props.moduleData" :config="config" />
+        </template>
+        <template v-if="config.name === 'radio_label'">
+          <RadioLabel class="content__module" :type="config.config.type" :config="config.config" />
+        </template>
+        <template v-if="config.name === 'button_list'">
+          <ButtonList class="content__module" :type="config.config.type" :config="config.config" :buttonList="config.config.buttonList" />
         </template>
         <!-- <template v-if="config.key === 'fire_control'">
         <FIreControl class="content__module" />
@@ -118,389 +149,390 @@
   </div>
 </template>
 <script lang="ts" setup>
-import { computed } from 'vue';
-import {
-  CommonItem,
-  Config,
-  // ModuleDataBoard,
-  // ModuleDataChart,
-  // ModuleDataList,
-  // ModuleDataPreset,
-  // ModuleDataTable,
-} from '../../../deviceManager/configurationTable/types';
-import MiniBoard from './detail/MiniBoard.vue';
-import TimelineList from './detail/TimelineList.vue';
-import TimelineListNew from './detail/TimelineListNew.vue';
-import CustomList from './detail/CustomList.vue';
-import CustomGallery from './detail/CustomGallery.vue';
-import ComplexList from './detail/ComplexList.vue';
-import 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 CustomTabs from './preset/CustomTabs.vue';
-import AIChat from '/@/components/AIChat/MiniChat.vue';
-import DeviceAlarm from './preset/DeviceAlarm.vue';
-import SelectCs from './preset/SelectCs.vue';
-import MiniBoardNew from './detail/MiniBoard-New.vue';
-import Partition from './detail/partition.vue';
-import SelectorDualChart from './preset/selectorDualChart.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 CustomTabs from './preset/CustomTabs.vue';
+  import AIChat from '/@/components/AIChat/MiniChat.vue';
+  import DeviceAlarm from './preset/DeviceAlarm.vue';
+  import SelectCs from './preset/SelectCs.vue';
+  import MiniBoardNew from './detail/MiniBoard-New.vue';
+  import Partition from './preset/partition.vue';
+  import SelectorDualChart from './preset/selectorDualChart.vue';
+  import RadioLabel from './preset/radioLabel.vue';
+  import ButtonList from './preset/buttonList.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),
-    };
-  });
-}
-
-// 获取当 List 组件配置带 items 项时的最终 items 配置
-function getListItems(raw: any, items: CommonItem[], mapFromData?: boolean) {
-  if (mapFromData && Array.isArray(raw)) {
-    return raw.map((data) => {
-      const item = items[0];
+  // 获取当原始配置带 items 项时的最终 items 配置
+  function getItems(raw, items: CommonItem[]) {
+    return items.map((i) => {
       return {
-        ...item,
-        label: getFormattedText(data, item.label, item.trans),
-        value: getFormattedText(data, item.value, item.trans),
+        ...i,
+        label: getFormattedText(raw, i.label, i.trans),
+        value: getFormattedText(raw, i.value, i.trans),
       };
     });
   }
-  return getItems(raw, items);
-}
-
-/** 根据配置里的layout将配置格式化为带 key 的具体配置,例如:[{ key: 'list', value: any, ...ModuleDataList }] */
-const layoutConfig = computed(() => {
-  const refData = props.data;
-  const board = clone(props.moduleData.board) || [];
-  const list = clone(props.moduleData.list) || [];
-  const gallery = clone(props.moduleData.gallery) || [];
-  const complex_list = clone(props.moduleData.complex_list) || [];
-  const gallery_list = clone(props.moduleData.gallery_list) || [];
-  const tabs = clone(props.moduleData.tabs) || [];
-  const chart = clone(props.moduleData.chart) || [];
-  const table = clone(props.moduleData.table) || [];
-  const preset = clone(props.moduleData.preset) || [];
-  const partition = clone(props.moduleData.partition) || [];
 
-  return layout.items.reduce((arr: any[], item) => {
-    // console.log(item.name,'name---')
-    switch (item.name) {
-      case 'board': {
-        const cfg = board.shift();
-        if (!cfg) break;
-        const data = getData(refData, cfg.readFrom, cfg.parser);
-
-        arr.push({
-          overflow: true,
+  // 获取当 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,
-          ...cfg,
-          items: getItems(data, cfg.items),
-        });
-        break;
-      }
-      case 'list': {
-        const cfg = list.shift();
-        if (!cfg) break;
-        const data = getData(refData, cfg.readFrom, cfg.parser);
+          label: getFormattedText(data, item.label, item.trans),
+          value: getFormattedText(data, item.value, item.trans),
+        };
+      });
+    }
+    return getItems(raw, items);
+  }
 
-        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);
+  /** 根据配置里的layout将配置格式化为带 key 的具体配置,例如:[{ key: 'list', value: any, ...ModuleDataList }] */
+  const layoutConfig = computed(() => {
+    const refData = props.data;
+    const board = clone(props.moduleData.board) || [];
+    const list = clone(props.moduleData.list) || [];
+    const gallery = clone(props.moduleData.gallery) || [];
+    const complex_list = clone(props.moduleData.complex_list) || [];
+    const gallery_list = clone(props.moduleData.gallery_list) || [];
+    const tabs = clone(props.moduleData.tabs) || [];
+    const chart = clone(props.moduleData.chart) || [];
+    const table = clone(props.moduleData.table) || [];
+    const preset = clone(props.moduleData.preset) || [];
+    const partition = clone(props.moduleData.partition) || [];
 
-        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);
+    return layout.items.reduce((arr: any[], item) => {
+      // console.log(item.name,'name---')
+      switch (item.name) {
+        case 'board': {
+          const cfg = board.shift();
+          if (!cfg) break;
+          const data = getData(refData, cfg.readFrom, cfg.parser);
 
-        if (cfg.mapFromData) {
-          const firstListItem = cfg.items[0];
           arr.push({
             overflow: true,
             ...item,
             ...cfg,
-            items: (data || []).map((d) => {
-              return {
-                title: getFormattedText(d, firstListItem.title, firstListItem.trans),
-                contents: firstListItem.contents.map((e) => {
-                  return {
-                    ...e,
-                    label: getFormattedText(d, e.label, e.trans),
-                    value: getFormattedText(d, e.value, e.trans),
-                  };
-                }),
-              };
-            }),
+            items: getItems(data, cfg.items),
           });
-        } else {
+          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: cfg.items.map((i) => {
-              return {
-                title: getFormattedText(data, i.title, i.trans),
-                contents: i.contents.map((e) => {
-                  return {
-                    ...e,
-                    label: getFormattedText(data, e.label, e.trans),
-                    value: getFormattedText(data, e.value, e.trans),
-                  };
-                }),
-              };
-            }),
+            items: getListItems(data, cfg.items, cfg.mapFromData),
           });
+          break;
         }
-        break;
-      }
-      case 'gallery_list': {
-        const cfg = gallery_list.shift();
-        if (!cfg) break;
-        const data = getData(refData, cfg.readFrom, cfg.parser);
+        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),
-          galleryItems: getItems(data, cfg.galleryItems),
-        });
-        break;
-      }
-      case 'tabs': {
-        const cfg = tabs.shift();
-        if (!cfg) break;
-        const data = getData(refData, cfg.readFrom, cfg.parser);
-
-        if (cfg.mapFromData) {
-          const firstListItem = cfg.items[0];
           arr.push({
             overflow: true,
             ...item,
             ...cfg,
-            items: (data || []).map((d) => {
-              return {
-                title: getFormattedText(d, firstListItem.title, firstListItem.trans),
-                contents: firstListItem.contents.map((e) => {
-                  return {
-                    ...e,
-                    label: getFormattedText(d, e.label, e.trans),
-                    value: getFormattedText(d, e.value, e.trans),
-                  };
-                }),
-              };
-            }),
+            items: getItems(data, cfg.items),
           });
-        } else {
+          break;
+        }
+        case 'complex_list': {
+          const cfg = complex_list.shift();
+          if (!cfg) break;
+          const data = getData(refData, cfg.readFrom, cfg.parser);
+
+          if (cfg.mapFromData) {
+            const firstListItem = cfg.items[0];
+            arr.push({
+              overflow: true,
+              ...item,
+              ...cfg,
+              items: (data || []).map((d) => {
+                return {
+                  title: getFormattedText(d, firstListItem.title, firstListItem.trans),
+                  contents: firstListItem.contents.map((e) => {
+                    return {
+                      ...e,
+                      label: getFormattedText(d, e.label, e.trans),
+                      value: getFormattedText(d, e.value, e.trans),
+                    };
+                  }),
+                };
+              }),
+            });
+          } else {
+            arr.push({
+              overflow: true,
+              ...item,
+              ...cfg,
+              items: cfg.items.map((i) => {
+                return {
+                  title: getFormattedText(data, i.title, i.trans),
+                  contents: i.contents.map((e) => {
+                    return {
+                      ...e,
+                      label: getFormattedText(data, e.label, e.trans),
+                      value: getFormattedText(data, e.value, e.trans),
+                    };
+                  }),
+                };
+              }),
+            });
+          }
+          break;
+        }
+        case 'gallery_list': {
+          const cfg = gallery_list.shift();
+          if (!cfg) break;
+          const data = getData(refData, cfg.readFrom, cfg.parser);
+
           arr.push({
             overflow: true,
             ...item,
             ...cfg,
-            items: cfg.items.map((i) => {
-              return {
-                title: getFormattedText(data, i.title, i.trans),
-                contents: i.contents.map((e) => {
-                  return {
-                    ...e,
-                    label: getFormattedText(data, e.label, e.trans),
-                    value: getFormattedText(data, e.value, e.trans),
-                  };
-                }),
-              };
-            }),
+            items: getItems(data, cfg.items),
+            galleryItems: getItems(data, cfg.galleryItems),
           });
+          break;
         }
-        break;
-      }
-      case 'chart': {
-        const cfg = chart.shift();
-        if (!cfg) break;
-        const data = getData(refData, cfg.readFrom, cfg.parser);
+        case 'tabs': {
+          const cfg = tabs.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);
+          if (cfg.mapFromData) {
+            const firstListItem = cfg.items[0];
+            arr.push({
+              overflow: true,
+              ...item,
+              ...cfg,
+              items: (data || []).map((d) => {
+                return {
+                  title: getFormattedText(d, firstListItem.title, firstListItem.trans),
+                  contents: firstListItem.contents.map((e) => {
+                    return {
+                      ...e,
+                      label: getFormattedText(d, e.label, e.trans),
+                      value: getFormattedText(d, e.value, e.trans),
+                    };
+                  }),
+                };
+              }),
+            });
+          } else {
+            arr.push({
+              overflow: true,
+              ...item,
+              ...cfg,
+              items: cfg.items.map((i) => {
+                return {
+                  title: getFormattedText(data, i.title, i.trans),
+                  contents: i.contents.map((e) => {
+                    return {
+                      ...e,
+                      label: getFormattedText(data, e.label, e.trans),
+                      value: getFormattedText(data, e.value, e.trans),
+                    };
+                  }),
+                };
+              }),
+            });
+          }
+          break;
+        }
+        case 'chart': {
+          const cfg = chart.shift();
+          if (!cfg) break;
+          const data = getData(refData, cfg.readFrom, cfg.parser);
 
-        arr.push({
-          ...cfg,
-          ...item,
-          columns: cfg.columns,
-          data,
-        });
-        break;
-      }
-      case 'partition': {
-        const cfg = partition.shift();
-        if (!cfg) break;
-        const data = getData(refData, cfg.readFrom, cfg.parser);
-        // console.log(data, 'partition data-----------------------------------------------------------')
-        arr.push({
-          overflow: true,
-          ...item,
-          data,
-          ...cfg,
-        });
-        break;
-      }
-      default: {
-        const cfg = preset.shift();
-        if (!cfg) break;
-        const data = getData(refData, cfg.readFrom, cfg.parser);
+          arr.push({
+            ...item,
+            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;
+        }
+        case 'partition': {
+          const cfg = partition.shift();
+          if (!cfg) break;
+          const data = getData(refData, cfg.readFrom, cfg.parser);
+          arr.push({
+            overflow: true,
+            ...item,
+            data,
+            ...cfg,
+          });
+          break;
+        }
+        default: {
+          const cfg = preset.shift();
+          if (!cfg) break;
+          const data = getData(refData, cfg.readFrom, cfg.parser);
+
+          arr.push({
+            ...item,
+            data,
+            config: cfg,
+          });
+          break;
+        }
       }
-    }
-    // console.log(arr,'arr---')
-    return arr;
-  }, []);
-});
+      // console.log(arr,'arr---')
+      return arr;
+    }, []);
+  });
 </script>
 <style lang="less" scoped>
-@import '@/design/theme.less';
+  @import '@/design/theme.less';
 
-.content {
-  height: calc(100% - 30px);
-  position: relative;
-  // z-index: -2;
-  display: flex;
-  flex-direction: column;
-  overflow-y: auto;
-}
+  .content {
+    height: calc(100% - 30px);
+    position: relative;
+    // z-index: -2;
+    display: flex;
+    flex-direction: column;
+    overflow-y: auto;
+  }
 
-.content__background {
-  width: 100%;
-  height: 100%;
-  position: absolute;
-  top: 0;
-  left: 0;
-  z-index: 0;
-  object-fit: fill;
-}
+  .content__background {
+    width: 100%;
+    height: 100%;
+    position: absolute;
+    top: 0;
+    left: 0;
+    z-index: 0;
+    object-fit: fill;
+  }
 
-.image__background {
-  width: 35%;
-  height: 61%;
-  left: 30%;
-}
+  .image__background {
+    width: 35%;
+    height: 61%;
+    left: 30%;
+  }
 
-.content__module {
-  // margin-top: 5px;
-  // margin-bottom: 5px;
-  width: 100%;
-  height: 100%;
-}
+  .content__module {
+    // margin-top: 5px;
+    // margin-bottom: 5px;
+    width: 100%;
+    height: 100%;
+  }
 
-.content__module1 {
-  background: url('@/assets/images/vent/homeNew/databg/4.png');
-  background-repeat: no-repeat;
-  background-size: 100% 100%;
-  height: 129px;
-  margin-top: 20%;
-}
+  .content__module1 {
+    background: url('@/assets/images/vent/homeNew/databg/4.png');
+    background-repeat: no-repeat;
+    background-size: 100% 100%;
+    height: 129px;
+    margin-top: 20%;
+  }
 
-.content__moduleFire {
-  width: 100%;
-  height: 100%;
-  margin-left: -24% !important;
-}
+  .content__moduleFire {
+    width: 100%;
+    height: 100%;
+    margin-left: -24% !important;
+  }
 
-.content__module_dust {
-  background: url('@/assets/images/vent/homeNew/bottomBg.png');
-  background-repeat: no-repeat;
-  background-size: 100% 100%;
-  width: 100%;
-  height: 100%;
-}
+  .content__module_dust {
+    background: url('@/assets/images/vent/homeNew/bottomBg.png');
+    background-repeat: no-repeat;
+    background-size: 100% 100%;
+    width: 100%;
+    height: 100%;
+  }
 
-// .content__module:first-of-type {
-//   margin-top: 0;
-// }
-// .content__module:last-of-type {
-//   margin-bottom: 0;
-// }
-::-webkit-scrollbar {
-  width: 5px !important;
-}
+  // .content__module:first-of-type {
+  //   margin-top: 0;
+  // }
+  // .content__module:last-of-type {
+  //   margin-bottom: 0;
+  // }
+  ::-webkit-scrollbar {
+    width: 5px !important;
+  }
 
-::-webkit-scrollbar-thumb {
-  width: 5px !important;
-}
+  ::-webkit-scrollbar-thumb {
+    width: 5px !important;
+  }
 
-:deep(.zxm-select:not(.zxm-select-customize-input) .zxm-select-selector) {
-  /* background-color: transparent; */
-  color: #fff;
-}
+  :deep(.zxm-select:not(.zxm-select-customize-input) .zxm-select-selector) {
+    /* background-color: transparent; */
+    color: #fff;
+  }
 
-:deep(.zxm-select-arrow) {
-  color: #fff;
-}
+  :deep(.zxm-select-arrow) {
+    color: #fff;
+  }
 
-:deep(.zxm-select-selection-item) {
-  color: #fff !important;
-}
+  :deep(.zxm-select-selection-item) {
+    color: #fff !important;
+  }
 
-:deep(.zxm-select-selection-placeholder) {
-  color: #fff !important;
-}
+  :deep(.zxm-select-selection-placeholder) {
+    color: #fff !important;
+  }
 
-:deep(.dialog-overlay) {
-  width: 100%;
-  height: 100%;
-  position: unset;
-  box-shadow: unset;
-}
+  :deep(.dialog-overlay) {
+    width: 100%;
+    height: 100%;
+    position: unset;
+    box-shadow: unset;
+  }
 
-::-webkit-scrollbar {
-  width: 5px !important;
-}
+  ::-webkit-scrollbar {
+    width: 5px !important;
+  }
 
-::-webkit-scrollbar-thumb {
-  width: 5px !important;
-}
+  ::-webkit-scrollbar-thumb {
+    width: 5px !important;
+  }
 </style>

+ 653 - 610
src/views/vent/home/configurable/components/detail/CustomList.vue

@@ -20,651 +20,694 @@
   </div>
 </template>
 <script lang="ts" setup>
-withDefaults(
-  defineProps<{
-    listConfig: {
-      value: string;
-      color: string;
-      label: string;
-      info: string;
-    }[];
-    /** A B C D E F G */
-    type: string;
-  }>(),
-  {
-    listConfig: () => [],
-    type: 'A',
-  }
-);
+  withDefaults(
+    defineProps<{
+      listConfig: {
+        value: string;
+        color: string;
+        label: string;
+        info: string;
+      }[];
+      /** A B C D E F G */
+      type: string;
+    }>(),
+    {
+      listConfig: () => [],
+      type: 'A',
+    }
+  );
 
-//   defineEmits(['click']);
+  //   defineEmits(['click']);
 </script>
 <style lang="less" scoped>
-@import '/@/design/theme.less';
-@import '/@/design/theme.less';
-/* Timeline 相关的样式 */
+  @import '/@/design/theme.less';
+  @import '/@/design/theme.less';
+  /* Timeline 相关的样式 */
 
-@{theme-deepblue} {
-  .list {
-    --image-list_bg_default: url(/@/assets/images/themify/deepblue/home-container/configurable/list_bg_default.png);
-    --image-triangle_icon: url(/@/assets/images/themify/deepblue/home-container/configurable/triangle_icon.png);
-    --image-list_bg_b: url(/@/assets/images/themify/deepblue/home-container/configurable/list_bg_b.png);
-    --image-deco_1: url(/@/assets/images/themify/deepblue/home-container/configurable/deco_1.png);
-    --image-list_bg_c: url(/@/assets/images/themify/deepblue/home-container/configurable/list_bg_c.png);
-    --image-list_bg_defflip: url(/@/assets/images/themify/deepblue/home-container/configurable/list_bg_defflip.png);
-    --image-list_bg_d: url(/@/assets/images/themify/deepblue/home-container/configurable/list_bg_d.png);
+  @{theme-deepblue} {
+    .list {
+      --image-list_bg_default: url(/@/assets/images/themify/deepblue/home-container/configurable/list_bg_default.png);
+      --image-triangle_icon: url(/@/assets/images/themify/deepblue/home-container/configurable/triangle_icon.png);
+      --image-list_bg_b: url(/@/assets/images/themify/deepblue/home-container/configurable/list_bg_b.png);
+      --image-deco_1: url(/@/assets/images/themify/deepblue/home-container/configurable/deco_1.png);
+      --image-list_bg_c: url(/@/assets/images/themify/deepblue/home-container/configurable/list_bg_c.png);
+      --image-list_bg_defflip: url(/@/assets/images/themify/deepblue/home-container/configurable/list_bg_defflip.png);
+      --image-list_bg_d: url(/@/assets/images/themify/deepblue/home-container/configurable/list_bg_d.png);
       --image-list_bg_s: url(/@/assets/images/themify/deepblue/home-container/configurable/list_bg_s.png);
-    --image-list_bg_e: url(/@/assets/images/themify/deepblue/home-container/configurable/list_bg_e.png);
-    --image-list: url(/@/assets/images/themify/deepblue/home-container/configurable/firehome/list.png);
-    --image-list_bg_h: url(/@/assets/images/themify/deepblue/home-container/configurable/list_bg_h.png);
-    --image-list_bg_i: url('/@/assets/images/themify/deepblue/home-container/configurable/list_bg_i.png');
-     --image-list_bg_r: url(/@/assets/images/themify/deepblue/home-container/configurable/list_bg_r.png);
+      --image-list_bg_e: url(/@/assets/images/themify/deepblue/home-container/configurable/list_bg_e.png);
+      --image-list: url(/@/assets/images/themify/deepblue/home-container/configurable/firehome/list.png);
+      --image-list_bg_h: url(/@/assets/images/themify/deepblue/home-container/configurable/list_bg_h.png);
+      --image-list_bg_i: url('/@/assets/images/themify/deepblue/home-container/configurable/list_bg_i.png');
+      --image-list_bg_r: url(/@/assets/images/themify/deepblue/home-container/configurable/list_bg_r.png);
+    }
   }
-}
-
-.list {
-  --image-list_bg_default: url(/@/assets/images/home-container/configurable/list_bg_default.png);
-  --image-triangle_icon: url(/@/assets/images/home-container/configurable/triangle_icon.png);
-  --image-list_bg_b: url(/@/assets/images/home-container/configurable/list_bg_b.png);
-  --image-deco_1: url(/@/assets/images/home-container/configurable/deco_1.png);
-  --image-list_bg_c: url(/@/assets/images/home-container/configurable/list_bg_c.png);
-  --image-list_bg_defflip: url(/@/assets/images/home-container/configurable/list_bg_defflip.png);
-  --image-list_bg_d: url(/@/assets/images/home-container/configurable/list_bg_d.png);
-  --image-list_bg_s: url(/@/assets/images/home-container/configurable/list_bg_s.png);
-  --image-list_bg_e: url(/@/assets/images/home-container/configurable/list_bg_e.png);
-  --image-list: url(/@/assets/images/home-container/configurable/firehome/list.png);
-  --image-list_bg_h: url(/@/assets/images/home-container/configurable/list_bg_h.png);
-  --image-list_bg_r: url(/@/assets/images/home-container/configurable/list_bg_r.png);
-  --image-list_bg_r_icon1: url(/@/assets/images/home-container/configurable/list_bg_r_icon1.png);
-  --image-list_bg_r_icon2: url(/@/assets/images/home-container/configurable/list_bg_r_icon2.png);
-  --image-list_bg_i: url('/@/assets/images/home-container/configurable/list_bg_i.png');
-  --image-list_bg_j: url('/@/assets/images/home-container/configurable/list_bg_j.png');
-  --image-linear-gradient-3: linear-gradient(to right, #39deff15, #3977e500);
-  --image-list_icon_l1: url('/@/assets/images/home-container/configurable/minehome/list-icon-wd.png');
-  --image-list_icon_l2: url('/@/assets/images/home-container/configurable/minehome/list-icon-CO.png');
-  --image-list_icon_l3: url('/@/assets/images/home-container/configurable/minehome/list-icon-yw.png');
-  --image-list_icon_l4: url('/@/assets/images/home-container/configurable/minehome/list-icon-hy.png');
-  --image-list_icon_m1: url('/@/assets/images/home-container/configurable/minehome/list-icon-co1.png');
-  --image-list_icon_m2: url('/@/assets/images/home-container/configurable/minehome/list-icon-co2.png');
-  --image-list_icon_m3: url('/@/assets/images/home-container/configurable/minehome/list-icon-ch4.png');
-  --image-list_icon_m4: url('/@/assets/images/home-container/configurable/minehome/list-icon-c2h2.png');
-  --image-list_icon_m5: url('/@/assets/images/home-container/configurable/minehome/list-icon-o2.png');
-  --image-list_icon_m6: url('/@/assets/images/home-container/configurable/minehome/list-icon-c2h4.png');
-  --image-list_icon_m7: url('/@/assets/images/home-container/configurable/minehome/list-icon-n2.png');
-  --image-list_icon_m8: url('/@/assets/images/home-container/configurable/minehome/list-icon-h2.png');
-  --image-list_bg_l1: url('/@/assets/images/home-container/configurable/minehome/list-bg-l1.png');
-  --image-list_bg_l2: url('/@/assets/images/home-container/configurable/minehome/list-bg-l2.png');
-  --image-list_bg_m1: url('/@/assets/images/home-container/configurable/minehome/list-bg-m1.png');
-  --image-list_bg_m2: url('/@/assets/images/home-container/configurable/minehome/list-bg-m2.png');
-  padding: 5px 20px;
-  position: relative;
-  background-repeat: no-repeat;
-  width: 100%;
-  height: 100%;
-  background-size: 100% 100%;
-  background-image: var(--image-list_bg_default);
-}
 
-.list_A {
-  padding-left: 5px;
-}
-.list-item__content_A {
-  background-repeat: no-repeat;
-  background-image: @vent-gas-list-item-bg-img;
-  // padding: 5px 10px;
-  display: flex;
-}
-.list-item__icon_A {
-  background-repeat: no-repeat;
-  width: 25px;
-  height: 29px;
-  background-image: var(--image-triangle_icon);
-}
+  .list {
+    --image-list_bg_default: url(/@/assets/images/home-container/configurable/list_bg_default.png);
+    --image-triangle_icon: url(/@/assets/images/home-container/configurable/triangle_icon.png);
+    --image-list_bg_b: url(/@/assets/images/home-container/configurable/list_bg_b.png);
+    --image-deco_1: url(/@/assets/images/home-container/configurable/deco_1.png);
+    --image-list_bg_c: url(/@/assets/images/home-container/configurable/list_bg_c.png);
+    --image-list_bg_defflip: url(/@/assets/images/home-container/configurable/list_bg_defflip.png);
+    --image-list_bg_d: url(/@/assets/images/home-container/configurable/list_bg_d.png);
+    --image-list_bg_s: url(/@/assets/images/home-container/configurable/list_bg_s.png);
+    --image-list_bg_e: url(/@/assets/images/home-container/configurable/list_bg_e.png);
+    --image-list: url(/@/assets/images/home-container/configurable/firehome/list.png);
+    --image-list_bg_h: url(/@/assets/images/home-container/configurable/list_bg_h.png);
+    --image-list_bg_r: url(/@/assets/images/home-container/configurable/list_bg_r.png);
+    --image-list_bg_r_icon1: url(/@/assets/images/home-container/configurable/list_bg_r_icon1.png);
+    --image-list_bg_r_icon2: url(/@/assets/images/home-container/configurable/list_bg_r_icon2.png);
+    --image-list_bg_i: url('/@/assets/images/home-container/configurable/list_bg_i.png');
+    --image-list_bg_j: url('/@/assets/images/home-container/configurable/list_bg_j.png');
+    --image-linear-gradient-3: linear-gradient(to right, #39deff15, #3977e500);
+    --image-list_icon_l1: url('/@/assets/images/home-container/configurable/minehome/list-icon-wd.png');
+    --image-list_icon_l2: url('/@/assets/images/home-container/configurable/minehome/list-icon-CO.png');
+    --image-list_icon_l3: url('/@/assets/images/home-container/configurable/minehome/list-icon-yw.png');
+    --image-list_icon_l4: url('/@/assets/images/home-container/configurable/minehome/list-icon-hy.png');
+    --image-list_icon_m1: url('/@/assets/images/home-container/configurable/minehome/list-icon-co1.png');
+    --image-list_icon_m2: url('/@/assets/images/home-container/configurable/minehome/list-icon-co2.png');
+    --image-list_icon_m3: url('/@/assets/images/home-container/configurable/minehome/list-icon-ch4.png');
+    --image-list_icon_m4: url('/@/assets/images/home-container/configurable/minehome/list-icon-c2h2.png');
+    --image-list_icon_m5: url('/@/assets/images/home-container/configurable/minehome/list-icon-o2.png');
+    --image-list_icon_m6: url('/@/assets/images/home-container/configurable/minehome/list-icon-c2h4.png');
+    --image-list_icon_m7: url('/@/assets/images/home-container/configurable/minehome/list-icon-n2.png');
+    --image-list_icon_m8: url('/@/assets/images/home-container/configurable/minehome/list-icon-h2.png');
+    --image-list_bg_l1: url('/@/assets/images/home-container/configurable/minehome/list-bg-l1.png');
+    --image-list_bg_l2: url('/@/assets/images/home-container/configurable/minehome/list-bg-l2.png');
+    --image-list_bg_m1: url('/@/assets/images/home-container/configurable/minehome/list-bg-m1.png');
+    --image-list_bg_m2: url('/@/assets/images/home-container/configurable/minehome/list-bg-m2.png');
+    --image-list_bg_n1: url('/@/assets/images/home-container/configurable/minehome/list-bg-n1.png');
+    --image-list_bg_n2: url('/@/assets/images/home-container/configurable/minehome/list-bg-n2.png');
+    --image-list_bg_n3: url('/@/assets/images/home-container/configurable/minehome/list-bg-n3.png');
+    --image-list_bg_n4: url('/@/assets/images/home-container/configurable/minehome/list-bg-n4.png');
+    padding: 5px 20px;
+    position: relative;
+    background-repeat: no-repeat;
+    width: 100%;
+    height: 100%;
+    background-size: 100% 100%;
+    background-image: var(--image-list_bg_default);
+  }
 
-.list-item__content_B {
-  background-repeat: no-repeat;
-  padding: 5px 10px 10px 10px;
-  display: flex;
-  background-position: left bottom;
-  background-size: 100% auto;
-  background-image: var(--image-list_bg_b);
-}
-.list__image_B {
-  width: 77px;
-  height: 77px;
-  background-repeat: no-repeat;
-  background-image: var(--image-deco_1);
-  background-size: auto;
-  margin-right: 20px;
-}
+  .list_A {
+    padding-left: 5px;
+  }
+  .list-item__content_A {
+    background-repeat: no-repeat;
+    background-image: @vent-gas-list-item-bg-img;
+    // padding: 5px 10px;
+    display: flex;
+  }
+  .list-item__icon_A {
+    background-repeat: no-repeat;
+    width: 25px;
+    height: 29px;
+    background-image: var(--image-triangle_icon);
+  }
 
-.list_C {
-  background: none;
-}
-.list-item__content_C {
-  height: 60px;
-  background-repeat: no-repeat;
-  padding: 25px 50px 0 50px;
-  display: flex;
-  background-position: center;
-  background-size: 100% 100%;
-  background-image: var(--image-list_bg_c);
-  margin-bottom: 10px;
-  text-align: center;
-}
-.list-item__content_C > div {
-  flex-basis: 33.3%;
-}
+  .list-item__content_B {
+    background-repeat: no-repeat;
+    padding: 5px 10px 10px 10px;
+    display: flex;
+    background-position: left bottom;
+    background-size: 100% auto;
+    background-image: var(--image-list_bg_b);
+  }
+  .list__image_B {
+    width: 77px;
+    height: 77px;
+    background-repeat: no-repeat;
+    background-image: var(--image-deco_1);
+    background-size: auto;
+    margin-right: 20px;
+  }
 
-.list_D {
-  background-image: var(--image-list_bg_defflip);
-}
-.list__wrapper_D {
-  display: flex;
-  flex-wrap: wrap;
-}
-.list-item__icon_D {
-  display: none;
-}
-.list-item_D {
-  flex-basis: 25%;
-  height: 60px;
-  background-repeat: no-repeat;
-  background-position: center;
-  background-size: auto 100%;
-  background-image: var(--image-list_bg_d);
-  text-align: center;
-  margin-bottom: 10px;
-}
+  .list_C {
+    background: none;
+  }
+  .list-item__content_C {
+    height: 60px;
+    background-repeat: no-repeat;
+    padding: 25px 50px 0 50px;
+    display: flex;
+    background-position: center;
+    background-size: 100% 100%;
+    background-image: var(--image-list_bg_c);
+    margin-bottom: 10px;
+    text-align: center;
+  }
+  .list-item__content_C > div {
+    flex-basis: 33.3%;
+  }
 
-.list-item__content_D {
-  line-height: 30px;
-}
-.list-item__value_D {
-  font-weight: bold;
-}
+  .list_D {
+    background-image: var(--image-list_bg_defflip);
+  }
+  .list__wrapper_D {
+    display: flex;
+    flex-wrap: wrap;
+  }
+  .list-item__icon_D {
+    display: none;
+  }
+  .list-item_D {
+    flex-basis: 25%;
+    height: 60px;
+    background-repeat: no-repeat;
+    background-position: center;
+    background-size: auto 100%;
+    background-image: var(--image-list_bg_d);
+    text-align: center;
+    margin-bottom: 10px;
+  }
 
-.list_S {
-  background: none;
-}
-.list__wrapper_S {
-  display: grid;
-  grid-template-columns: repeat(2, 1fr); /* 2列均等 */
-  gap: 10px;
-}
-.list-item_S {
-  height: 45px;
-  background-repeat: no-repeat;
-  background-position: center;
-  background-size: 100% 100%;
-  background-image: var(--image-list_bg_s);
-  text-align: center;
-  padding: 0 7px;
-}
-.list-item__content_S {
-  display: flex;
-}
-.list-item__value_S {
-  font-family: 'douyuFont';
-  font-size: 13px;
-  color: @vent-gas-primary-text;
-  padding-top: 3px;
-}
-.list_E {
-  background-image: var(--image-list_bg_defflip);
-}
-.list__wrapper_E {
-  display: flex;
-  flex-wrap: wrap;
-}
-.list-item__icon_E {
-  display: none;
-}
-.list-item_E {
-  flex-basis: 25%;
-  height: 70px;
-  background-repeat: no-repeat;
-  background-position: center;
-  background-size: auto 100%;
-  background-image: var(--image-list_bg_e);
-  text-align: center;
-  margin: 5px 0px;
-  padding-top: 32px;
-  font-size: 12px;
-}
+  .list-item__content_D {
+    line-height: 30px;
+  }
+  .list-item__value_D {
+    font-weight: bold;
+  }
 
-.list_F {
-  background: none;
-}
-.list-item__content_F {
-  height: 40px;
-  background-repeat: no-repeat;
-  padding: 0 50px 0 50px;
-  display: flex;
-  background-position: center;
-  background-size: 100% auto;
-  background-image: var(--image-list);
-  margin-top: 10px;
-  text-align: center;
-}
-.list-item__content_F > div {
-  flex-basis: 33.3%;
-}
+  .list_S {
+    background: none;
+  }
+  .list__wrapper_S {
+    display: grid;
+    grid-template-columns: repeat(2, 1fr); /* 2列均等 */
+    gap: 10px;
+  }
+  .list-item_S {
+    height: 45px;
+    background-repeat: no-repeat;
+    background-position: center;
+    background-size: 100% 100%;
+    background-image: var(--image-list_bg_s);
+    text-align: center;
+    padding: 0 7px;
+  }
+  .list-item__content_S {
+    display: flex;
+  }
+  .list-item__value_S {
+    font-family: 'douyuFont';
+    font-size: 13px;
+    color: @vent-gas-primary-text;
+    padding-top: 3px;
+  }
+  .list_E {
+    background-image: var(--image-list_bg_defflip);
+  }
+  .list__wrapper_E {
+    display: flex;
+    flex-wrap: wrap;
+  }
+  .list-item__icon_E {
+    display: none;
+  }
+  .list-item_E {
+    flex-basis: 25%;
+    height: 70px;
+    background-repeat: no-repeat;
+    background-position: center;
+    background-size: auto 100%;
+    background-image: var(--image-list_bg_e);
+    text-align: center;
+    margin: 5px 0px;
+    padding-top: 32px;
+    font-size: 12px;
+  }
 
-.list_G {
-  background: none;
-}
-.list__wrapper_G {
-  display: flex;
-  flex-wrap: wrap;
-  justify-content: space-between;
-}
-.list-item_G {
-  width: 130px;
-  height: 80px;
-  align-items: center;
-  text-align: center;
-  border: 1px solid rgba(25, 237, 255, 0.4);
-  box-shadow: inset 0 0 10px rgba(0, 197, 255, 0.6);
-  background: rgba(0, 0, 0, 0.1);
-  margin: 5px 10px;
-}
-.list-item__content_G {
-  position: relative;
-  width: 100%;
-  height: 100%;
-}
-.list-item__content_G > .list-item__label {
-  width: 60px;
-  height: 100%;
-  left: 0;
-  position: absolute;
-  font-size: 20px;
-  line-height: 80px;
-}
-.list-item__content_G > .list-item__info {
-  width: 70px;
-  height: 30px;
-  line-height: 30px;
-  right: 0;
-  position: absolute;
-}
-.list-item__content_G > .list-item__value {
-  width: 70px;
-  height: 50px;
-  line-height: 50px;
-  top: 30px;
-  right: 0;
-  position: absolute;
-  text-shadow: 0 0 25px #00fbfe;
-  background: linear-gradient(0deg, #45d3fd, #45d3fd, #61ddb1, #61ddb1);
-  font-style: normal;
-  background-size: cover;
-  font-family: electronicFont;
-  font-size: 30px;
-  -webkit-background-clip: text;
-  background-clip: text;
-  -webkit-text-fill-color: transparent;
-  font-family: Arial, Helvetica, sans-serif;
-  font-size: 18px;
-  color: aliceblue;
-}
+  .list_F {
+    background: none;
+  }
+  .list-item__content_F {
+    height: 40px;
+    background-repeat: no-repeat;
+    padding: 0 50px 0 50px;
+    display: flex;
+    background-position: center;
+    background-size: 100% auto;
+    background-image: var(--image-list);
+    margin-top: 10px;
+    text-align: center;
+  }
+  .list-item__content_F > div {
+    flex-basis: 33.3%;
+  }
 
-.list_H {
-  background: none;
-}
-.list-item__content_H {
-  height: 50px;
-  background-repeat: no-repeat;
-  padding: 20px 50px 0 50px;
-  display: flex;
-  background-position: bottom;
-  background-size: 100% auto;
-  background-image: var(--image-list_bg_h);
-  margin-bottom: 10px;
-  text-align: center;
-}
-.list-item__content_H > div {
-  flex-basis: 33.3%;
-}
+  .list_G {
+    background: none;
+  }
+  .list__wrapper_G {
+    display: flex;
+    flex-wrap: wrap;
+    justify-content: space-between;
+  }
+  .list-item_G {
+    width: 130px;
+    height: 80px;
+    align-items: center;
+    text-align: center;
+    border: 1px solid rgba(25, 237, 255, 0.4);
+    box-shadow: inset 0 0 10px rgba(0, 197, 255, 0.6);
+    background: rgba(0, 0, 0, 0.1);
+    margin: 5px 10px;
+  }
+  .list-item__content_G {
+    position: relative;
+    width: 100%;
+    height: 100%;
+  }
+  .list-item__content_G > .list-item__label {
+    width: 60px;
+    height: 100%;
+    left: 0;
+    position: absolute;
+    font-size: 20px;
+    line-height: 80px;
+  }
+  .list-item__content_G > .list-item__info {
+    width: 70px;
+    height: 30px;
+    line-height: 30px;
+    right: 0;
+    position: absolute;
+  }
+  .list-item__content_G > .list-item__value {
+    width: 70px;
+    height: 50px;
+    line-height: 50px;
+    top: 30px;
+    right: 0;
+    position: absolute;
+    text-shadow: 0 0 25px #00fbfe;
+    background: linear-gradient(0deg, #45d3fd, #45d3fd, #61ddb1, #61ddb1);
+    font-style: normal;
+    background-size: cover;
+    font-family: electronicFont;
+    font-size: 30px;
+    -webkit-background-clip: text;
+    background-clip: text;
+    -webkit-text-fill-color: transparent;
+    font-family: Arial, Helvetica, sans-serif;
+    font-size: 18px;
+    color: aliceblue;
+  }
 
-.list-item__icon_R {
-  width: 24px;
-  height: 25px;
-  background-image: var(--image-list_bg_r_icon1);
-  background-repeat: no-repeat;
-  background-position: center;
-  background-size: contain;
-  margin-bottom: 5px;
-  position: absolute;
-  left: 35px;
-}
-.list-item_R:last-of-type .list-item__icon_R{
-  background-image: var(--image-list_bg_r_icon2);
-}
-.list-item__content_R {
-  height: 52px;
-  background-repeat: no-repeat;
-  padding:0 30px;
-  display: flex;
-  background-position: bottom;
-  background-size: 100% 100%;
-  background-image: var(--image-list_bg_r);
-  text-align: center;
-  align-items: center;
-  .list-item__label {
-    font-size: 15px;
+  .list_H {
+    background: none;
+  }
+  .list-item__content_H {
+    height: 50px;
+    background-repeat: no-repeat;
+    padding: 20px 50px 0 50px;
+    display: flex;
+    background-position: bottom;
+    background-size: 100% auto;
+    background-image: var(--image-list_bg_h);
+    margin-bottom: 10px;
+    text-align: center;
+  }
+  .list-item__content_H > div {
+    flex-basis: 33.3%;
   }
-  .list-item__value_R {
-    font-family: 'douyuFont';
-    font-size: 15px;
-    padding-top: 5px;
-    color: #00bfff;
-  }
-}
-.list-item__content_R > div {
-  flex-basis: 33.3%;
-}
 
-.list_fireList {
-  background: none;
-}
-.list__wrapper_fireList {
-  display: flex;
-  flex-wrap: wrap;
-  justify-content: flex-start;
-  margin-left: 86px;
-}
-.list-item_fireList {
-  width: 167px;
-  height: 58px;
-  align-items: center;
-  text-align: center;
-  background-image: var(--image-list_bg_i);
-  background-repeat: no-repeat;
-  background-size: auto 100%;
-  margin: 5px 10px;
-}
-.list-item__content_fireList {
-  position: relative;
-  width: 100%;
-  height: 100%;
-}
-.list-item__content_fireList > .list-item__label {
-  width: 60px;
-  height: 100%;
-  left: 0;
-  position: absolute;
-  font-size: 20px;
-  line-height: 63px;
-  color: #009bff;
-}
-.list-item__content_fireList > .list-item__info {
-  height: 50%;
-  left: 70px;
-  position: absolute;
-}
-.list-item__content_fireList > .list-item__value {
-  top: 50%;
-  height: 50%;
-  left: 70px;
-  position: absolute;
-  font-size: 18px;
-}
-.list_I {
-  background: none;
-}
-.list__wrapper_I {
-  display: flex;
-  flex-wrap: wrap;
-  justify-content: flex-start;
-}
-.list-item_I {
-  width: 160px;
-  height: 63px;
-  align-items: center;
-  text-align: center;
-  background-image: var(--image-list_bg_i);
-  background-repeat: no-repeat;
-  background-size: auto 100%;
-  margin: 5px 10px;
-}
-.list-item__content_I {
-  position: relative;
-  width: 100%;
-  height: 100%;
-}
-.list-item__content_I > .list-item__label {
-  width: 60px;
-  height: 100%;
-  left: 0;
-  position: absolute;
-  font-size: 20px;
-  line-height: 63px;
-  color: #009bff;
-}
-.list-item__content_I > .list-item__info {
-  height: 50%;
-  left: 70px;
-  position: absolute;
-}
-.list-item__content_I > .list-item__value {
-  top: 50%;
-  height: 50%;
-  left: 70px;
-  position: absolute;
-  font-size: 18px;
-}
-.list_J {
-  background: unset;
-  padding: 0 5px 0 10px;
-}
-.list-item_J {
-  width: 312px;
-  height: 57px;
-  align-items: center;
-  text-align: center;
-  background-image: var(--image-list_bg_j);
-  background-repeat: no-repeat;
-  background-size: auto 100%;
-  margin: 5px 10px;
-}
-.list-item__content_J {
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-  padding: 0 20px 0 15px;
-}
-.list_K {
-  background: unset;
-  padding: 0 5px 0 10px;
-}
-.list__wrapper_K {
-  height: 100%;
-}
-.list-item__content_K {
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-  padding: 5px;
-  margin: 4px 0;
-  background-image: var(--image-linear-gradient-3);
+  .list-item__icon_R {
+    width: 24px;
+    height: 25px;
+    background-image: var(--image-list_bg_r_icon1);
+    background-repeat: no-repeat;
+    background-position: center;
+    background-size: contain;
+    margin-bottom: 5px;
+    position: absolute;
+    left: 35px;
+  }
+  .list-item_R:last-of-type .list-item__icon_R {
+    background-image: var(--image-list_bg_r_icon2);
+  }
+  .list-item__content_R {
+    height: 52px;
+    background-repeat: no-repeat;
+    padding: 0 30px;
+    display: flex;
+    background-position: bottom;
+    background-size: 100% 100%;
+    background-image: var(--image-list_bg_r);
+    text-align: center;
+    align-items: center;
+    .list-item__label {
+      font-size: 15px;
+    }
+    .list-item__value_R {
+      font-family: 'douyuFont';
+      font-size: 15px;
+      padding-top: 5px;
+      color: #00bfff;
+    }
+  }
+  .list-item__content_R > div {
+    flex-basis: 33.3%;
+  }
 
-  .list-item__value {
-    flex-basis: unset;
+  .list_fireList {
+    background: none;
   }
-  .list-item__label {
-    flex-basis: unset;
+  .list__wrapper_fireList {
+    display: flex;
+    flex-wrap: wrap;
+    justify-content: flex-start;
+    margin-left: 86px;
   }
-  .list-item__info {
-    display: none;
+  .list-item_fireList {
+    width: 167px;
+    height: 58px;
+    align-items: center;
+    text-align: center;
+    background-image: var(--image-list_bg_i);
+    background-repeat: no-repeat;
+    background-size: auto 100%;
+    margin: 5px 10px;
+  }
+  .list-item__content_fireList {
+    position: relative;
+    width: 100%;
+    height: 100%;
+  }
+  .list-item__content_fireList > .list-item__label {
+    width: 60px;
+    height: 100%;
+    left: 0;
+    position: absolute;
+    font-size: 20px;
+    line-height: 63px;
+    color: #009bff;
+  }
+  .list-item__content_fireList > .list-item__info {
+    height: 50%;
+    left: 70px;
+    position: absolute;
+  }
+  .list-item__content_fireList > .list-item__value {
+    top: 50%;
+    height: 50%;
+    left: 70px;
+    position: absolute;
+    font-size: 18px;
+  }
+  .list_I {
+    background: none;
+  }
+  .list__wrapper_I {
+    display: flex;
+    flex-wrap: wrap;
+    justify-content: flex-start;
+  }
+  .list-item_I {
+    width: 160px;
+    height: 63px;
+    align-items: center;
+    text-align: center;
+    background-image: var(--image-list_bg_i);
+    background-repeat: no-repeat;
+    background-size: auto 100%;
+    margin: 5px 10px;
   }
-}
+  .list-item__content_I {
+    position: relative;
+    width: 100%;
+    height: 100%;
+  }
+  .list-item__content_I > .list-item__label {
+    width: 60px;
+    height: 100%;
+    left: 0;
+    position: absolute;
+    font-size: 20px;
+    line-height: 63px;
+    color: #009bff;
+  }
+  .list-item__content_I > .list-item__info {
+    height: 50%;
+    left: 70px;
+    position: absolute;
+  }
+  .list-item__content_I > .list-item__value {
+    top: 50%;
+    height: 50%;
+    left: 70px;
+    position: absolute;
+    font-size: 18px;
+  }
+  .list_J {
+    background: unset;
+    padding: 0 5px 0 10px;
+  }
+  .list-item_J {
+    width: 312px;
+    height: 57px;
+    align-items: center;
+    text-align: center;
+    background-image: var(--image-list_bg_j);
+    background-repeat: no-repeat;
+    background-size: auto 100%;
+    margin: 5px 10px;
+  }
+  .list-item__content_J {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    padding: 0 20px 0 15px;
+  }
+  .list_K {
+    background: unset;
+    padding: 0 5px 0 10px;
+  }
+  .list__wrapper_K {
+    height: 100%;
+  }
+  .list-item__content_K {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    padding: 5px;
+    margin: 4px 0;
+    background-image: var(--image-linear-gradient-3);
 
-.list_L {
-  background: none;
-  padding: 5px 10px;
-}
-.list-item_L {
-  width: 100%;
-  height: 37px;
-  background-repeat: no-repeat;
-  background-size: auto 100%;
-  margin-bottom: 8px;
-}
-/* 奇数项背景图 */
-.list-item_L:nth-child(odd) {
-  background-image: var(--image-list_bg_l1);
-}
+    .list-item__value {
+      flex-basis: unset;
+    }
+    .list-item__label {
+      flex-basis: unset;
+    }
+    .list-item__info {
+      display: none;
+    }
+  }
 
-/* 偶数项背景图 */
-.list-item_L:nth-child(even) {
-  background-image: var(--image-list_bg_l2);
-}
-.list-item__icon_L {
-  background-repeat: no-repeat;
-  width: 16px;
-  height: 20px;
-  margin-left: 15px;
-  background-position: center;
-  background-size: contain;
-}
-/* 四个图标样式 */
-.list-item_L:nth-child(1) .list-item__icon_L {
-  background-image: var(--image-list_icon_l1);
-}
+  .list_L {
+    background: none;
+    padding: 5px 10px;
+  }
+  .list-item_L {
+    width: 100%;
+    height: 37px;
+    background-repeat: no-repeat;
+    background-size: auto 100%;
+    margin-bottom: 8px;
+  }
+  /* 奇数项背景图 */
+  .list-item_L:nth-child(odd) {
+    background-image: var(--image-list_bg_l1);
+  }
+
+  /* 偶数项背景图 */
+  .list-item_L:nth-child(even) {
+    background-image: var(--image-list_bg_l2);
+  }
+  .list-item__icon_L {
+    background-repeat: no-repeat;
+    width: 16px;
+    height: 20px;
+    margin-left: 15px;
+    background-position: center;
+    background-size: contain;
+  }
+  /* 四个图标样式 */
+  .list-item_L:nth-child(1) .list-item__icon_L {
+    background-image: var(--image-list_icon_l1);
+  }
 
-.list-item_L:nth-child(2) .list-item__icon_L {
-  background-image: var(--image-list_icon_l2);
-}
+  .list-item_L:nth-child(2) .list-item__icon_L {
+    background-image: var(--image-list_icon_l2);
+  }
 
-.list-item_L:nth-child(3) .list-item__icon_L {
-  background-image: var(--image-list_icon_l3);
-}
+  .list-item_L:nth-child(3) .list-item__icon_L {
+    background-image: var(--image-list_icon_l3);
+  }
 
-.list-item_L:nth-child(4) .list-item__icon_L {
-  background-image: var(--image-list_icon_l4);
-}
-.list-item__content_L {
-  display: flex;
-  text-align: center;
-  align-items: center;
-  .list-item__value_L {
-    font-family: 'douyuFont';
+  .list-item_L:nth-child(4) .list-item__icon_L {
+    background-image: var(--image-list_icon_l4);
+  }
+  .list-item__content_L {
+    display: flex;
+    text-align: center;
+    align-items: center;
+    .list-item__value_L {
+      font-family: 'douyuFont';
+    }
+  }
+  .list-item__content_L > div {
+    flex-basis: 33.3%;
   }
 
-}
-.list-item__content_L > div {
-  flex-basis: 33.3%;
-}
+  .list_M {
+    background: none;
+    padding: 0;
+  }
+  .list__wrapper_M {
+    display: grid;
+    grid-template-columns: 1fr 1fr; /* 两列均等 */
+    gap: 18px; /* 统一间距 */
+  }
+  .list-item_M {
+    height: 37px;
+    background-repeat: no-repeat;
+    background-size: 100% 100%;
+  }
+  .list-item_M:nth-child(1),
+  .list-item_M:nth-child(4),
+  .list-item_M:nth-child(5),
+  .list-item_M:nth-child(8) {
+    background-image: var(--image-list_bg_m1);
+  }
 
+  .list-item_M:nth-child(2),
+  .list-item_M:nth-child(3),
+  .list-item_M:nth-child(6),
+  .list-item_M:nth-child(7) {
+    background-image: var(--image-list_bg_m2);
+  }
+  .list-item_M:nth-child(7),
+  .list-item_M:nth-child(8) {
+    margin-bottom: 0;
+  }
+  .list-item__icon_M {
+    background-repeat: no-repeat;
+    height: 16px;
+    margin-left: 5px;
+    background-position: center;
+    background-size: auto 100%;
+    display: inline-block;
+    width: 40px;
+  }
+  /* 八个图标样式 */
+  .list-item_M:nth-child(1) .list-item__icon_M {
+    background-image: var(--image-list_icon_m1);
+  }
+  .list-item_M:nth-child(2) .list-item__icon_M {
+    background-image: var(--image-list_icon_m2);
+  }
+  .list-item_M:nth-child(3) .list-item__icon_M {
+    background-image: var(--image-list_icon_m3);
+  }
+  .list-item_M:nth-child(4) .list-item__icon_M {
+    background-image: var(--image-list_icon_m4);
+  }
+  .list-item_M:nth-child(5) .list-item__icon_M {
+    background-image: var(--image-list_icon_m5);
+  }
+  .list-item_M:nth-child(6) .list-item__icon_M {
+    background-image: var(--image-list_icon_m6);
+  }
+  .list-item_M:nth-child(7) .list-item__icon_M {
+    background-image: var(--image-list_icon_m7);
+  }
+  .list-item_M:nth-child(8) .list-item__icon_M {
+    background-image: var(--image-list_icon_m8);
+  }
 
-.list_M {
-  background: none;
-  padding: 0;
-}
-.list__wrapper_M {
-  display: grid;
-  grid-template-columns: 1fr 1fr; /* 两列均等 */
-  gap: 18px; /* 统一间距 */
-}
-.list-item_M {
-  height: 37px;
-  background-repeat: no-repeat;
-  background-size: 100% 100%;
-}
-.list-item_M:nth-child(1),
-.list-item_M:nth-child(4),
-.list-item_M:nth-child(5),
-.list-item_M:nth-child(8) {
-  background-image: var(--image-list_bg_m1);
-}
+  .list-item__content_M {
+    display: flex;
+    text-align: center;
+    align-items: center;
 
-.list-item_M:nth-child(2),
-.list-item_M:nth-child(3),
-.list-item_M:nth-child(6),
-.list-item_M:nth-child(7) {
-  background-image: var(--image-list_bg_m2);
-}
-.list-item_M:nth-child(7),
-.list-item_M:nth-child(8) {
-  margin-bottom: 0;
-}
-.list-item__icon_M {
-  background-repeat: no-repeat;
-  height: 16px;
-  margin-left: 5px;
-  background-position: center;
-  background-size: auto 100%;
-  display: inline-block;
-  width: 40px;
-}
-/* 八个图标样式 */
-.list-item_M:nth-child(1) .list-item__icon_M {
-  background-image: var(--image-list_icon_m1);
-}
-.list-item_M:nth-child(2) .list-item__icon_M {
-  background-image: var(--image-list_icon_m2);
-}
-.list-item_M:nth-child(3) .list-item__icon_M {
-  background-image: var(--image-list_icon_m3);
-}
-.list-item_M:nth-child(4) .list-item__icon_M {
-  background-image: var(--image-list_icon_m4);
-}
-.list-item_M:nth-child(5) .list-item__icon_M {
-  background-image: var(--image-list_icon_m5);
-}
-.list-item_M:nth-child(6) .list-item__icon_M {
-  background-image: var(--image-list_icon_m6);
-}
-.list-item_M:nth-child(7) .list-item__icon_M {
-  background-image: var(--image-list_icon_m7);
-}
-.list-item_M:nth-child(8) .list-item__icon_M {
-  background-image: var(--image-list_icon_m8);
-}
+    .list-item__value_M {
+      font-family: 'douyuFont';
+      font-size: 12px;
+    }
+  }
+  .list_N {
+    background: none;
+    padding: 5px 10px;
+  }
+  .list-item_N {
+    width: 100%;
+    height: 42px;
+    background-repeat: no-repeat;
+    background-size: 100% 100%;
+    margin-bottom: 15px;
+  }
+  /* 四个背景样式 */
+  .list-item_N:nth-child(1) {
+    background-image: var(--image-list_bg_n1);
+  }
 
-.list-item__content_M {
-  display: flex;
-  text-align: center;
-  align-items: center;
+  .list-item_N:nth-child(2) {
+    background-image: var(--image-list_bg_n2);
+    .list-item__value_N {
+      color: #27cab7;
+    }
+  }
 
-  .list-item__value_M {
-    font-family: 'douyuFont';
-    font-size: 12px;
+  .list-item_N:nth-child(3) {
+    background-image: var(--image-list_bg_n3);
   }
 
-}
+  .list-item_N:nth-child(4) {
+    background-image: var(--image-list_bg_n4);
+    color: #27cab7;
+  }
+  .list-item__content_N {
+    display: flex;
+    text-align: center;
+    align-items: center;
+    .list-item__value_N {
+      font-family: 'douyuFont';
+    }
+  }
+  .list-item__content_N > div:last-child {
+    flex-basis: 60%;
+  }
 
-.list-item__label {
-  flex-basis: 55%;
-}
-.list-item__info {
-  flex-grow: 1;
-}
-.list-item__value {
-  flex-basis: 30%;
-}
-.list-item__value_red {
-  color: red;
-}
-.list-item__value_orange {
-  color: orange;
-}
-.list-item__value_yellow {
-  color: yellow;
-}
-.list-item__value_green {
-  color: yellowgreen;
-}
-.list-item__value_blue {
-  color: @vent-table-action-link;
-}
-.list-item__value_white {
-  color: white;
-}
-.gallery-item__value_lightblue {
-  color: @vent-configurable-home-light-border;
-}
+  .list-item__label {
+    flex-basis: 55%;
+  }
+  .list-item__info {
+    flex-grow: 1;
+  }
+  .list-item__value {
+    flex-basis: 30%;
+  }
+  .list-item__value_red {
+    color: red;
+  }
+  .list-item__value_orange {
+    color: orange;
+  }
+  .list-item__value_yellow {
+    color: yellow;
+  }
+  .list-item__value_green {
+    color: yellowgreen;
+  }
+  .list-item__value_blue {
+    color: @vent-table-action-link;
+  }
+  .list-item__value_white {
+    color: white;
+  }
+  .gallery-item__value_lightblue {
+    color: @vent-configurable-home-light-border;
+  }
 </style>

+ 7 - 5
src/views/vent/home/configurable/components/detail/MiniBoard.vue

@@ -372,10 +372,16 @@ defineEmits(['click']);
   height: 60px;
   background-image: var(--image-board-bg-m1);
   background-size: 100% 100%;
+  margin: 5px 0 15px 0;
 }
 .mini-board_M:nth-child(2),
-.mini-board_M:nth-child(3) {
+.mini-board_M:nth-child(3),
+.mini-board_M:nth-child(6),
+.mini-board_M:nth-child(7) {
   background-image: var(--image-board-bg-m2);
+  .mini-board__value_M {
+    color: #27cab7;
+  }
 }
 
 .mini-board_N {
@@ -585,10 +591,6 @@ defineEmits(['click']);
   height: 23px;
   margin-top: 5px;
 }
-.mini-board__value_M:nth-child(2),
-.mini-board__value_M:nth-child(3) {
-  color: #218a89;
-}
 
 .mini-board__value_O {
   font-family: 'douyuFont';

+ 0 - 70
src/views/vent/home/configurable/components/detail/partition.vue

@@ -1,70 +0,0 @@
-<!-- eslint-disable vue/multi-word-component-names -->
-<template>
-  <div class="partition-block" :class="`partition-block_${type}`">
-      <slot name="icon">
-        <div class="partition-block__icon" :class="`partition-block__icon_${type}`" 
-        :style="{ backgroundImage: iconUrl ? `url(${icon})`: '' }">
-        </div>
-      </slot>
-      <slot name="label">
-        <div class="partition-block__label" :class="`partition-block__label_${type}`">
-          {{ label }}
-        </div>
-      </slot>
-  </div>
-</template>
-<script lang="ts" setup>
-import { computed, defineEmits, defineProps, withDefaults } from 'vue';
-const props = withDefaults(
-  defineProps<{
-    // 分隔条类型,类型为:'A' | 'B' 
-    type?: string;
-    // 分隔条内容
-    label: string;
-    // 分隔条图标
-    icon: string;
-  }>(),
-  {
-    type: 'A',
-    label: '分隔条',
-    icon: ''
-  }
-);
-// 处理 icon 路径,兼容静态资源
-const iconUrl = computed(() => {
-  if (!props.icon) return '';
-  if (props.icon.startsWith('/')) {
-    return props.icon;
-  }
-  return '/' + props.icon;
-});
-
-defineEmits(['click']);
-</script>
-<style lang="less" scoped>
-@import '/@/design/theme.less';
-@import '/@/design/theme.less';
-
-.partition-block {
-  --image-partition-bg: url('/@/assets/images/home-container/configurable/tashanhome/partition-bg-a.png');
-  display: flex;
-  background: var(--image-partition-bg);
-  background-size: 100% 100%;
-  position: relative;
-  .partition-block__icon {
-    width: 14px;
-    height: 14px;
-    background-size: 100% 100%;
-    background-repeat: no-repeat;
-    margin:3px 5px;
-  }
-}
-.partition-block_A {
-  height: 30px !important;
-  width: calc(100% - 30px)!important;
-  margin:5px 0 10px 20px;
-}
-
-
-
-</style>

+ 119 - 0
src/views/vent/home/configurable/components/preset/buttonList.vue

@@ -0,0 +1,119 @@
+<template>
+  <div ref="buttonContainer">
+    <div :class="`button-block_${type}`" v-if="type === 'A'">
+      <div :class="`button-item_${type}`" v-for="button in buttonList" :key="button.value">
+        <div v-if="button.isShowInput" :class="`input-area_${type}`">
+          <a-input v-model:value="inputValue" :placeholder="button.input" />
+          <a-button type="primary">{{ button.label }}</a-button>
+        </div>
+        <div v-else>
+          <a-button type="primary">{{ button.label }}</a-button>
+        </div>
+      </div>
+    </div>
+  </div>
+  <div :class="`button-block_${type}`" v-if="type === 'B'">
+    <!-- 遍历分组后的按钮组 -->
+    <div :class="`button-group_${type}`" v-for="(group, groupIndex) in groupedButtons" :key="groupIndex">
+      <!-- 遍历每组中的按钮 -->
+      <div :class="`button-item_${type}`" v-for="button in group" :key="button.value">
+        <a-button type="primary">{{ button.label }}</a-button>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+  defineOptions({ name: 'ButtonList' });
+
+  import { computed, onMounted, ref, watch } from 'vue';
+  // 定义组件属性
+  const props = defineProps<{
+    type: string;
+    config: any;
+    buttonList: ButtonItem[];
+  }>();
+  // 定义按钮项的类型
+  interface ButtonItem {
+    isShowInput: boolean;
+    input: string;
+    value: string | number;
+    label: string;
+    // 可以根据实际需求添加其他属性
+  }
+  const inputValue = ref<string>('');
+  // 组件挂载时初始化一次
+  onMounted(() => {
+    console.log(props);
+    // 设置默认选中项
+  });
+  const groupedButtons = computed<ButtonItem[][]>(() => {
+    if (props.type !== 'B') return [];
+    const groups: ButtonItem[][] = [];
+    for (let i = 0; i < props.buttonList.length; i += 2) {
+      groups.push(props.buttonList.slice(i, i + 2));
+    }
+    return groups;
+  });
+
+  watch(
+    () => props.config,
+    (newV) => {
+      console.log(newV, 'debuger---');
+    },
+    {
+      deep: true,
+      immediate: true,
+    }
+  );
+</script>
+
+<style lang="less" scoped>
+  .button-block_A {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    padding: 0 15px;
+    flex-wrap: wrap;
+    margin-bottom: 20px;
+    .input-area_A {
+      height: 50px;
+      width: 250px;
+      display: flex;
+      background: url('@/assets/images/vent/homeNew/databg/11.png') no-repeat;
+      background-size: 100% 100%;
+      align-items: center;
+      justify-content: space-between;
+      margin: 5px 0;
+      padding: 3px 18px 3px 13px;
+      input {
+        height: 23px;
+        width: 120px;
+        background-color: #09172c;
+        border: solid 1px #1f7394;
+        color: #fff;
+      }
+      button {
+        height: 24px;
+        width: 50px;
+        padding: 0 10px;
+      }
+    }
+  }
+  .button-block_B {
+    display: flex;
+    justify-content: space-between;
+    padding: 0 10px 10px 10px;
+    .button-group_B {
+      background: url('/@/assets/images/home-container/configurable/minehome/button-bg-a.png') no-repeat;
+      background-size: 100% 100%;
+      width: 130px;
+      height: 100px;
+      display: flex;
+      align-items: center;
+      flex-wrap: wrap;
+      justify-content: center;
+      padding: 10px 0;
+    }
+  }
+</style>

+ 65 - 0
src/views/vent/home/configurable/components/preset/partition.vue

@@ -0,0 +1,65 @@
+<!-- eslint-disable vue/multi-word-component-names -->
+<template>
+  <div class="partition-block" :class="`partition-block_${type}`">
+    <slot name="icon">
+      <div class="partition-block__icon" :class="`partition-block__icon_${type}`" :style="{ backgroundImage: iconUrl ? `url(${icon})` : '' }"> </div>
+    </slot>
+    <slot name="label">
+      <div class="partition-block__label" :class="`partition-block__label_${type}`">
+        {{ label }}
+      </div>
+    </slot>
+  </div>
+</template>
+<script lang="ts" setup>
+  import { computed, defineEmits, defineProps, withDefaults } from 'vue';
+  const props = withDefaults(
+    defineProps<{
+      // 分隔条类型,类型为:'A' | 'B'
+      type?: string;
+      // 分隔条内容
+      label: string;
+      // 分隔条图标
+      icon: string;
+    }>(),
+    {
+      type: 'A',
+      label: '分隔条',
+      icon: '',
+    }
+  );
+  // 处理 icon 路径,兼容静态资源
+  const iconUrl = computed(() => {
+    if (!props.icon) return '';
+    if (props.icon.startsWith('/')) {
+      return props.icon;
+    }
+    return '/' + props.icon;
+  });
+
+  defineEmits(['click']);
+</script>
+<style lang="less" scoped>
+  @import '/@/design/theme.less';
+  @import '/@/design/theme.less';
+
+  .partition-block {
+    --image-partition-bg: url('/@/assets/images/home-container/configurable/tashanhome/partition-bg-a.png');
+    display: flex;
+    background: var(--image-partition-bg);
+    background-size: 100% 100%;
+    position: relative;
+    .partition-block__icon {
+      width: 14px;
+      height: 14px;
+      background-size: 100% 100%;
+      background-repeat: no-repeat;
+      margin: 3px 5px;
+    }
+  }
+  .partition-block_A {
+    height: 30px !important;
+    width: calc(100% - 30px) !important;
+    margin: 5px 0 10px 20px;
+  }
+</style>

+ 95 - 0
src/views/vent/home/configurable/components/preset/radioLabel.vue

@@ -0,0 +1,95 @@
+<template>
+  <div ref="radioContainer">
+    <div :class="`radio-block_${type}`">
+      <div :class="`left-label_${type}`">
+        <span>{{ props.config.leftLabel }}</span>
+      </div>
+      <div :class="`left-label_${type}`" v-if="props.config.isShowRadio">
+        <a-radio-group v-model:value="defaultValue" :options="options" @change="handleRadioChange" />
+      </div>
+      <div :class="`right-label_${type}`" v-else>
+        <span>{{ props.config.rightLbel }}</span>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+  // Set a multi-word component name to follow Vue style guide
+  defineOptions({ name: 'PresetRadio' });
+
+  import { onMounted, ref, watch } from 'vue';
+  import { RadioGroupProps } from 'ant-design-vue';
+  // 定义组件属性
+  const props = defineProps<{
+    type: any;
+    config: any;
+  }>();
+
+  // 获取组件根DOM元素
+  const radioContainer = ref<HTMLDivElement>();
+  // 定义选项数据
+  let options: RadioGroupProps['options'] = [];
+  // 定义各个单选组的默认值
+  const defaultValue = ref('');
+  // 组件挂载时初始化一次
+  onMounted(() => {
+    initData();
+    console.log(props);
+    // 设置默认选中项
+  });
+  // 初始化数据
+  const initData = () => {
+    if (props.config) {
+      // 从数据中获取第一个选择器的选项
+      options = props.config.options || [];
+      // 从数据中获取第二个选择器的选项
+      defaultValue.value = props.config.defaultValue || '';
+    }
+  };
+  // 处理单选框变化,触发原生DOM事件
+  const handleRadioChange = (value: string) => {
+    if (radioContainer.value) {
+      // 创建自定义原生事件,携带选中值(通过event.detail传递)
+      const event = new CustomEvent('radio-value-change', {
+        detail: {
+          value,
+        },
+        bubbles: true, // 允许事件冒泡
+        cancelable: true,
+      });
+      console.log('debuger', event);
+      // 触发事件
+      radioContainer.value.dispatchEvent(event);
+    }
+  };
+
+  watch(
+    () => props.config,
+    (newV) => {
+      console.log(newV, 'debuger---');
+    },
+    {
+      deep: true,
+      immediate: true,
+    }
+  );
+</script>
+
+<style lang="less" scoped>
+  .radio-block_A {
+    height: 50px;
+    display: flex;
+    justify-content: space-between;
+    background: url('@/assets/images/vent/homeNew/databg/11.png') no-repeat;
+    background-size: 100% 100%;
+    align-items: center;
+    padding: 0 15px 0 25px;
+    margin: 10px 8px 5px 8px;
+    .right-label_A {
+      margin-right: 10px;
+      font-family: 'douyuFont';
+      font-size: 12px;
+    }
+  }
+</style>

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

@@ -0,0 +1,334 @@
+import type { Config } from '../../deviceManager/configurationTable/types';
+
+export const testConfigDustControl: Config[] = [
+  // 1. 工作面信息(左上)
+  {
+    deviceType: 'workInfo',
+    moduleName: '工作面信息',
+    pageType: 'dust_control',
+    moduleData: {
+      header: {
+        show: false,
+        readFrom: '',
+        selector: {
+          show: false,
+          value: '',
+        },
+        slot: {
+          show: false,
+          value: '',
+        },
+      },
+      background: {
+        show: false,
+        type: 'video',
+        link: '',
+      },
+      layout: {
+        direction: 'column',
+        items: [
+          {
+            name: 'radio_label',
+            basis: 'auto',
+            overflow: false,
+          },
+          {
+            name: 'board',
+            basis: 'auto',
+            overflow: false,
+          },
+        ],
+      },
+      board: [
+        {
+          type: 'M',
+          readFrom: '',
+          layout: 'val-top',
+          items: [
+            {
+              label: '工作面供风量',
+              value: '467',
+            },
+            {
+              label: '工作面漏风量',
+              value: '27',
+            },
+            {
+              label: 'CH4浓度',
+              value: '0.02',
+            },
+            {
+              label: 'CO2浓度',
+              value: '0.04',
+            },
+            {
+              label: '使用区队',
+              value: '连采2队',
+            },
+            {
+              label: '带班队长',
+              value: '张三',
+            },
+          ],
+        },
+      ],
+      chart: [],
+      gallery: [],
+      gallery_list: [],
+      table: [],
+      list: [],
+      complex_list: [],
+      preset: [
+        {
+          readFrom: '',
+          type: 'A',
+          leftLabel: '地点',
+          rightLbel: 'S1206掘进工作面',
+          isShowRadio: false,
+          options: [],
+          defaultValue: '',
+        },
+      ],
+      mock: {},
+    },
+    showStyle: {
+      size: 'width:440px;height:355px;',
+      version: '原版',
+      position: 'top:65px;left:10px;',
+    },
+  },
+  // 2. 水循环监控(左中)
+  {
+    deviceType: 'WaterMonitor',
+    moduleName: '水循环监控',
+    pageType: 'dust_control',
+    moduleData: {
+      header: { show: false, readFrom: '', selector: { show: false, value: '' }, slot: { show: false, value: '' } },
+      background: { show: false, type: 'video', link: '' },
+      layout: {
+        direction: 'column',
+        items: [
+          {
+            name: 'radio_label',
+            basis: 'auto',
+            overflow: false,
+          },
+          {
+            name: 'button_list',
+            basis: 'auto',
+            overflow: false,
+          },
+          {
+            name: 'board',
+            basis: 'auto',
+            overflow: false,
+          },
+        ],
+      },
+      table: [],
+      board: [
+        {
+          type: 'N',
+          readFrom: '',
+          layout: 'label-top',
+          items: [
+            {
+              label: '流量',
+              value: '${cumulativeFlow}',
+            },
+            {
+              label: '管道温度',
+              value: '${heaterTemperature}',
+            },
+            {
+              label: '氮气压力',
+              value: '${nitrogen}',
+            },
+            {
+              label: '氮含量',
+              value: '${nitrogenContent}',
+            },
+          ],
+        },
+      ],
+      chart: [],
+      gallery: [],
+      gallery_list: [],
+      list: [],
+      complex_list: [],
+      preset: [
+        {
+          readFrom: '',
+          type: 'A',
+          leftLabel: '水循环监控',
+          rightLbel: '',
+          isShowRadio: true,
+          options: [
+            { label: '运行', value: 'run' },
+            { label: '检修', value: 'overhaul' },
+          ],
+          defaultValue: 'run',
+        },
+        {
+          readFrom: '',
+          type: 'A',
+          buttonList: [
+            { isShowInput: true, input: '水位设置', label: '保存', value: 'save' },
+            { label: '自动补水', value: 'zdbs' },
+            { label: '喷头清洁', value: 'ptqj' },
+            { label: '沉淀清洁', value: 'cdqj' },
+            { label: '开启喷雾', value: 'kqpw' },
+            { label: '停止喷雾', value: 'tzpw' },
+          ],
+        },
+      ],
+      partition: [],
+    },
+    showStyle: {
+      size: 'width:440px;height:340px;',
+      version: '原版',
+      position: 'top:440px;left:10px;',
+    },
+  },
+  // 3. 除尘风机(右1)
+  {
+    deviceType: 'DustRemovalFan',
+    moduleName: '除尘风机',
+    pageType: 'dust_control',
+    moduleData: {
+      header: {
+        show: false,
+        readFrom: '',
+        selector: {
+          show: false,
+          value: '',
+        },
+        slot: {
+          show: false,
+          value: '',
+        },
+      },
+      background: {
+        show: false,
+        type: 'video',
+        link: '',
+      },
+      layout: {
+        direction: 'column',
+        items: [
+          {
+            name: 'radio_label',
+            basis: 'auto',
+            overflow: false,
+          },
+          {
+            name: 'button_list',
+            basis: 'auto',
+            overflow: false,
+          },
+          {
+            name: 'list',
+            basis: 'auto',
+            overflow: false,
+          },
+          {
+            name: 'board',
+            basis: 'auto',
+            overflow: false,
+          },
+        ],
+      },
+      board: [
+        {
+          type: 'M',
+          readFrom: '',
+          layout: 'val-top',
+          items: [
+            {
+              label: '运行频率',
+              value: '26Hz',
+            },
+            {
+              label: '输出功率',
+              value: '27kw',
+            },
+            {
+              label: '母线电压',
+              value: '600v',
+            },
+            {
+              label: '轴温',
+              value: '68℃',
+            },
+            {
+              label: '输出电压',
+              value: '590v',
+            },
+            {
+              label: '输出电流',
+              value: '20A',
+            },
+            {
+              label: '[X]振动',
+              value: 'xxx',
+            },
+            {
+              label: '[Y]振动',
+              value: 'xxx',
+            },
+          ],
+        },
+      ],
+      chart: [],
+      gallery: [],
+      gallery_list: [],
+      table: [],
+      list: [
+        {
+          type: 'N',
+          readFrom: '',
+          mapFromData: false,
+          items: [
+            { label: '安装位置', value: '工作面迎头50m', color: 'blue', info: '' },
+            { label: '吸风位置', value: '工作面迎头50m', color: 'blue', info: '' },
+            { label: '额定吸风量', value: '300-700m³/min', color: 'blue', info: '' },
+            { label: '运行吸风量', value: '148m³/min', color: 'blue', info: '' },
+          ],
+        },
+      ],
+      complex_list: [],
+      preset: [
+        {
+          readFrom: '',
+          type: 'A',
+          leftLabel: '除尘风机',
+          rightLbel: '',
+          isShowRadio: true,
+          options: [
+            { label: '运行', value: 'run' },
+            { label: '检修', value: 'overhaul' },
+          ],
+          defaultValue: 'run',
+        },
+        {
+          readFrom: '',
+          type: 'B',
+          buttonList: [
+            { label: '自动运行', value: 'ZDYX' },
+            { label: '手动运行', value: 'SDYX' },
+            { label: '就地控制', value: 'JDKZ' },
+            { label: '远程控制', value: 'YCKZ' },
+            { label: '启动风机', value: 'QDKJ' },
+            { label: '停止风机', value: 'TZFJ' },
+          ],
+        },
+      ],
+      mock: {},
+    },
+    showStyle: {
+      size: 'width:440px;height:785px;',
+      version: '原版',
+      position: 'top:65px;right:10px;',
+    },
+  },
+];

+ 5 - 7
src/views/vent/home/configurable/configurable.data.mine.ts

@@ -195,9 +195,7 @@ export const testConfigMineFire: Config[] = [
       background: { show: false, type: 'video', link: '' },
       layout: {
         direction: 'row',
-        items: [
-          { name: 'chart', basis: '100%' },
-        ],
+        items: [{ name: 'chart', basis: '100%' }],
       },
       board: [],
       chart: [
@@ -281,7 +279,7 @@ export const testConfigMineFire: Config[] = [
     deviceType: 'coalFireFeature',
     moduleName: '开采煤层自燃发火特性',
     pageType: 'mine_fire',
-        moduleData: {
+    moduleData: {
       header: {
         show: false,
         readFrom: '',
@@ -479,7 +477,7 @@ export const testConfigMineFire: Config[] = [
           {
             name: 'list',
             basis: '60%',
-          }
+          },
         ],
       },
       board: [],
@@ -618,5 +616,5 @@ export const testConfigMineFire: Config[] = [
       version: '原版',
       position: 'bottom:8px;left:470px',
     },
-  }
-];
+  },
+];

+ 246 - 0
src/views/vent/home/configurable/dustControl.vue

@@ -0,0 +1,246 @@
+<!-- eslint-disable vue/multi-word-component-names -->
+<template>
+  <div class="company-home" ref="dustControlContainer">
+    <!-- 顶部标题样式块 -->
+    <div class="top-bg">
+      <div class="main-title">{{ mainTitle }}</div>
+    </div>
+    <!-- 渲染所有模块 -->
+    <ModuleCommon
+      v-for="cfg in cfgs"
+      :key="cfg.deviceType + cfg.moduleName"
+      :show-style="cfg.showStyle"
+      :module-data="cfg.moduleData"
+      :module-name="cfg.moduleName"
+      :device-type="cfg.deviceType"
+      :data="data"
+      :visible="true"
+    />
+  </div>
+</template>
+<script lang="ts" setup>
+  import { computed, onMounted, onUnmounted, ref } from 'vue';
+  import { useInitConfigs, useInitPage } from './hooks/useInit';
+  import { testConfigDustControl } from './configurable.data.dustControl';
+  import ModuleCommon from './components/ModuleCommon.vue';
+  const cfgs = computed(() => configs.value);
+  const { configs, fetchConfigs } = useInitConfigs();
+  const { mainTitle, data } = useInitPage('除尘装置控制系统');
+  let interval: ReturnType<typeof setInterval> | undefined;
+  // 新增:获取容器DOM元素
+  const dustControlContainer = ref<HTMLDivElement>();
+  const handleRadioChange = (event: Event) => {
+    // 类型断言,获取事件详情
+    const detail = (event as CustomEvent).detail;
+    if (detail) {
+      console.log('监听到radio切换:', detail.value);
+      // 这里处理业务逻辑
+    }
+  };
+  onMounted(() => {
+    fetchConfigs('mine_fire').then(() => {
+      configs.value = testConfigDustControl;
+      // getDisHome({
+      //   dataList: devicesTypes.value.concat('fireAllMineWarn').join(','),
+      // }).then(updateData);
+    });
+    interval = setInterval(() => {
+      // getDisHome({
+      //   dataList: devicesTypes.value.concat('fireAllMineWarn').join(','),
+      // }).then(updateData);
+    }, 2000);
+    // 监听自定义原生事件
+    // 在容器上监听事件(事件会从radio组件冒泡到这里)
+    if (dustControlContainer.value) {
+      dustControlContainer.value.addEventListener('radio-value-change', handleRadioChange);
+    }
+  });
+
+  onUnmounted(() => {
+    clearInterval(interval);
+    if (dustControlContainer.value) {
+      dustControlContainer.value.removeEventListener('radio-value-change', handleRadioChange);
+    }
+  });
+</script>
+<style lang="less" scoped>
+  @import '/@/design/theme.less';
+
+  @font-face {
+    font-family: 'douyuFont';
+    src: url('../../../../assets/font/douyuFont.otf');
+  }
+
+  .company-home {
+    --image-fire-title: url(/@/assets/images/vent/vent-header1.png);
+    --image-common-border1: url('/@/assets/images/home-container/configurable/minehome/common-border1.png');
+    --image-common-border3: url('/@/assets/images/home-container/configurable/minehome/common-border3.png');
+    width: 100%;
+    height: 100%;
+    color: @white;
+    position: relative;
+    background: #09172c;
+
+    .top-bg {
+      width: 100%;
+      height: 73px;
+      background: var(--image-fire-title) no-repeat top;
+      position: absolute;
+      z-index: 1;
+      .main-title {
+        height: 80px;
+        font-family: 'douyuFont';
+        font-size: 26px;
+        letter-spacing: 2px;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        padding: 0 0 10px 0;
+      }
+    }
+    // 顶部中间样式块
+    .center-info-bar {
+      position: relative;
+      top: 75px;
+      left: 50%;
+      transform: translateX(-50%);
+      width: 900px;
+      height: 160px;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      background: url('@/assets/images/home-container/configurable/tashanhome/center-bar-bg.png') no-repeat center;
+
+      .center-info-content {
+        position: relative;
+        top: 15px;
+        background: url('@/assets/images/home-container/configurable/tashanhome/center-bar-circle.png') no-repeat center;
+        width: 160px;
+        height: 160px;
+        text-align: center;
+        .info-value {
+          position: absolute;
+          top: 34%;
+          left: 50%;
+          transform: translateX(-50%);
+          font-family: 'douyuFont';
+          font-size: 25px;
+          color: #2cffdd;
+        }
+        .info-label {
+          width: 100%;
+          position: absolute;
+          bottom: 25px;
+          font-size: 17px;
+          left: 50%;
+          transform: translateX(-50%);
+        }
+      }
+      .left-info-content {
+        position: relative;
+        text-align: right;
+        .left-block {
+          position: absolute;
+          width: 190px;
+          height: 55px;
+          background: url('@/assets/images/home-container/configurable/tashanhome/leftbar-bg1.png') no-repeat right;
+          padding-right: 52px;
+          .info-value {
+            height: 28px;
+            line-height: 28px;
+            font-family: 'douyuFont';
+            font-size: 12px;
+            color: var(--vent-gas-primary-text);
+          }
+          .info-label {
+            height: 28px;
+            line-height: 28px;
+          }
+        }
+        .block1 {
+          top: -70px;
+          right: -5px;
+        }
+        .block2 {
+          top: -15px;
+          left: -280px;
+          background: url('@/assets/images/home-container/configurable/tashanhome/leftbar-bg2.png') no-repeat right;
+          .info-value {
+            color: #2cffdd;
+          }
+        }
+        .block3 {
+          top: 40px;
+          right: -5px;
+        }
+      }
+      .right-info-content {
+        position: relative;
+        .right-block {
+          position: absolute;
+          width: 190px;
+          height: 55px;
+          background: url('@/assets/images/home-container/configurable/tashanhome/rightbar-bg1.png') no-repeat left;
+          padding-left: 52px;
+          .info-value {
+            height: 28px;
+            line-height: 28px;
+            font-family: 'douyuFont';
+            font-size: 12px;
+            color: var(--vent-gas-primary-text);
+          }
+          .info-label {
+            height: 28px;
+            line-height: 28px;
+          }
+        }
+        .block1 {
+          top: -70px;
+          left: -5px;
+        }
+        .block2 {
+          top: -15px;
+          right: -280px;
+          background: url('@/assets/images/home-container/configurable/tashanhome/rightbar-bg2.png') no-repeat left;
+          .info-value {
+            color: #2cffdd;
+          }
+        }
+        .block3 {
+          top: 40px;
+          left: -5px;
+        }
+      }
+    }
+
+    ::v-deep .dane-bd {
+      background-repeat: no-repeat;
+      background-position: center;
+      background-size: 100% 100%;
+      &.dane-w {
+        background-image: var(--image-common-border3);
+      }
+      .dane-title {
+        justify-content: space-around;
+        padding: 0 50px 0 0;
+
+        .common-navL {
+          font-size: 14px;
+          font-weight: bold;
+          font-family: 'douyuFont';
+        }
+      }
+      .dane-content {
+        border: none;
+        background: none;
+        padding: 10px 35px;
+      }
+    }
+    ::v-deep .table__content .table__content_list {
+      width: 95%;
+    }
+    ::v-deep .table__content .table__content_label {
+      width: 95%;
+    }
+  }
+</style>