bobo04052021@163.com 1 месяц назад
Родитель
Сommit
48f70e8e99

+ 3 - 6
src/views/vent/home/configurable/belt/belt-new.vue

@@ -83,12 +83,9 @@ const readData = {
       warningLevel: '一般风险',
       sysList: [
         {
-          time: '2026-03-21 13:23:34',
-          area: '3#皮带区域',
-          type: 'CO浓度异常',
-          status: '三级预警',
-          advice: '立即检查该区域设备,启动应急预案',
-          action: '启动喷淋',
+          pos: '1#皮带区域',
+          vehicle: '车辆23425',
+          status: '0',
         },
         {
           time: '2026-03-21 13:23:34',

+ 144 - 60
src/views/vent/home/configurable/belt/belt.vue

@@ -28,10 +28,8 @@ import { onMounted, ref } from 'vue';
 import customHeader from './components/customHeader-belt.vue';
 import { useInitConfigs, useInitPage } from '../hooks/useInit';
 import { testBeltLaneFire } from './configurable.data';
-import ModuleCommon from './components/ModuleCommon.vue';
+import ModuleCommon from './components/ModuleCommonBelt.vue';
 import SubApp from '/@/components/vent/micro/createSubApp.vue';
-import { getSystem } from './configurable.api';
-import { read } from 'fs';
 // import { BDFireMock } from './mock';
 const { configs, fetchConfigs } = useInitConfigs();
 const { updateEnhancedConfigs, updateData } = useInitPage('皮带巷三级防灭火系统');
@@ -174,58 +172,122 @@ const readData = {
   ],
   yjkfArray: [
     {
-      deviceName: '风门1',
-      frontDoorStatus: '关闭',
-      backDoorStatus: '开启',
-      netStatus: '在线',
-    },
-    {
-      deviceName: '风门2',
-      frontDoorStatus: '关闭',
-      backDoorStatus: '开启',
-      netStatus: '在线',
-    },
-    {
-      deviceName: '风门3',
-      frontDoorStatus: '关闭',
-      backDoorStatus: '开启',
-      netStatus: '在线',
-    },
-    {
-      deviceName: '风门4',
-      frontDoorStatus: '开启',
-      backDoorStatus: '开启',
-      netStatus: '在线',
-    },
-    {
-      deviceName: '风门5',
-      frontDoorStatus: '开启',
-      backDoorStatus: '开启',
-      netStatus: '在线',
-    },
-    {
-      deviceName: '风门6',
-      frontDoorStatus: '开启',
-      backDoorStatus: '开启',
-      netStatus: '在线',
-    },
-    {
-      deviceName: '风门7',
-      frontDoorStatus: '关闭',
-      backDoorStatus: '关闭',
-      netStatus: '在线',
-    },
-    {
-      deviceName: '风门8',
-      frontDoorStatus: '关闭',
-      backDoorStatus: '关闭',
-      netStatus: '在线',
+      beltName: '测试1',
+      aqjkData: [
+        {
+          deviceName: '风门1',
+          frontDoorStatus: '关闭',
+          backDoorStatus: '开启',
+          netStatus: '在线',
+        },
+        {
+          deviceName: '风门2',
+          frontDoorStatus: '关闭',
+          backDoorStatus: '开启',
+          netStatus: '在线',
+        },
+        {
+          deviceName: '风门3',
+          frontDoorStatus: '关闭',
+          backDoorStatus: '开启',
+          netStatus: '在线',
+        },
+        {
+          deviceName: '风门4',
+          frontDoorStatus: '开启',
+          backDoorStatus: '开启',
+          netStatus: '在线',
+        },
+        {
+          deviceName: '风门5',
+          frontDoorStatus: '开启',
+          backDoorStatus: '开启',
+          netStatus: '在线',
+        },
+        {
+          deviceName: '风门6',
+          frontDoorStatus: '开启',
+          backDoorStatus: '开启',
+          netStatus: '在线',
+        },
+        {
+          deviceName: '风门7',
+          frontDoorStatus: '关闭',
+          backDoorStatus: '关闭',
+          netStatus: '在线',
+        },
+        {
+          deviceName: '风门8',
+          frontDoorStatus: '关闭',
+          backDoorStatus: '关闭',
+          netStatus: '在线',
+        },
+        {
+          deviceName: '风门9',
+          frontDoorStatus: '关闭',
+          backDoorStatus: '关闭',
+          netStatus: '在线',
+        },
+      ],
     },
     {
-      deviceName: '风门9',
-      frontDoorStatus: '关闭',
-      backDoorStatus: '关闭',
-      netStatus: '在线',
+      beltName: '测试2',
+      aqjkData: [
+        {
+          deviceName: '风门1',
+          frontDoorStatus: '关闭',
+          backDoorStatus: '开启',
+          netStatus: '在线',
+        },
+        {
+          deviceName: '风门2',
+          frontDoorStatus: '关闭',
+          backDoorStatus: '开启',
+          netStatus: '在线',
+        },
+        {
+          deviceName: '风门3',
+          frontDoorStatus: '关闭',
+          backDoorStatus: '开启',
+          netStatus: '在线',
+        },
+        {
+          deviceName: '风门4',
+          frontDoorStatus: '开启',
+          backDoorStatus: '开启',
+          netStatus: '在线',
+        },
+        {
+          deviceName: '风门5',
+          frontDoorStatus: '开启',
+          backDoorStatus: '开启',
+          netStatus: '在线',
+        },
+        {
+          deviceName: '风门6',
+          frontDoorStatus: '开启',
+          backDoorStatus: '开启',
+          netStatus: '在线',
+        },
+        {
+          deviceName: '风门7',
+          frontDoorStatus: '关闭',
+          backDoorStatus: '关闭',
+          netStatus: '在线',
+        },
+        {
+          deviceName: '风门8',
+          frontDoorStatus: '关闭',
+          backDoorStatus: '关闭',
+          netStatus: '在线',
+        },
+        {
+          deviceName: '风门9',
+          frontDoorStatus: '关闭',
+          backDoorStatus: '关闭',
+          netStatus: '在线',
+        },
+      ],
     },
   ],
 };
@@ -233,16 +295,38 @@ const readData = {
 function refresh() {
   fetchConfigs('belt').then(() => {
     configs.value = testBeltLaneFire;
-    const params = {
-      systemID: '2028657172566073346',
-      type: 'all',
-      devicetype: 'sys',
-    };
-    Promise.resolve(getSystem(params)).then(updateData);
-    updateEnhancedConfigs(configs.value);
+    Promise.resolve(readData).then(updateData);
+    // updateEnhancedConfigs(configs.value);
     // getDataSource();
   });
 }
+// async function getDataSource() {
+//   const res = await list({ devicetype: 'belt', pagetype: 'normal' });
+//   let dataSource: any = [];
+//   dataSource = res.msgTxt[0] && res.msgTxt[0].datalist ? res.msgTxt[0].datalist[0] : {};
+//   if (dataSource) {
+//     readData.value = Object.assign(dataSource, dataSource.readData);
+//   }
+// }
+
+// 查询关联设备列表
+// async function getDeviceList() {
+//   const res = await systemList({ devicetype: 'sys', systemID: optionValue.value });
+//   const result = res.msgTxt;
+//   const deviceArr = <DeviceType[]>[];
+//   result.forEach((item) => {
+//     const data = item['datalist'].filter((data: any) => {
+//       const readData = data.readData;
+//       return Object.assign(data, readData);
+//     });
+//     if (item.type != 'sys') {
+//       deviceArr.unshift({ deviceType: item.type, deviceName: item['typeName'] ? item['typeName'] : item['datalist'][0]['typeName'], datalist: data });
+//     }
+//   });
+//   deviceList.value = deviceArr;
+//   deviceActive.value = deviceArr[0].deviceType;
+//   deviceChange(0);
+// }
 
 function initInterval() {
   setInterval(() => {

+ 65 - 65
src/views/vent/home/configurable/belt/components/headerBelt.vue

@@ -6,89 +6,89 @@
   </div>
 </template>
 <script lang="ts">
-import { defineComponent, computed } from 'vue';
-import { Decoration5 } from '@kjgl77/datav-vue3';
-export default defineComponent({
-  name: 'CustomHeader',
-  components: { Decoration5 },
-  props: {},
-  emits: ['change'],
-});
+  import { defineComponent, computed } from 'vue';
+  import { Decoration5 } from '@kjgl77/datav-vue3';
+  export default defineComponent({
+    name: 'CustomHeader',
+    components: { Decoration5 },
+    props: {},
+    emits: ['change'],
+  });
 </script>
 <style lang="less">
-@import '/@/design/vent/modal.less';
+  @import '/@/design/vent/modal.less';
 
-.@{ventSpace}-select-dropdown.drop {
-  background-color: transparent !important;
+  .@{ventSpace}-select-dropdown.drop {
+    background-color: transparent !important;
 
-  .@{ventSpace}-select-item-option-selected,
-  .@{ventSpace}-select-item-option-active {
-    background-color: #ffffff33 !important;
-  }
-  .@{ventSpace}-select-item {
-    color: inherit;
-    &:hover {
+    .@{ventSpace}-select-item-option-selected,
+    .@{ventSpace}-select-item-option-active {
       background-color: #ffffff33 !important;
     }
-  }
-  .@{ventSpace}-select-tree {
-    .@{ventSpace}-select-tree-treenode {
+    .@{ventSpace}-select-item {
       color: inherit;
+      &:hover {
+        background-color: #ffffff33 !important;
+      }
     }
-    .@{ventSpace}-select-tree-switcher-icon {
-      color: inherit;
+    .@{ventSpace}-select-tree {
+      .@{ventSpace}-select-tree-treenode {
+        color: inherit;
+      }
+      .@{ventSpace}-select-tree-switcher-icon {
+        color: inherit;
+      }
     }
   }
-}
 </style>
 <style lang="less" scoped>
-@import '/@/design/theme.less';
-@ventSpace: zxm;
+  @import '/@/design/theme.less';
+  @ventSpace: zxm;
 
-.vent-custom-header {
-  --image-vent-header1: url('/@/assets/images/beltFire/top.png');
-  width: 100%;
-  position: relative;
-  z-index: 9999;
-  pointer-events: none;
-  .vent-home-header {
+  .vent-custom-header {
+    --image-vent-header1: url('/@/assets/images/beltFire/top.png');
     width: 100%;
-    position: fixed;
-    top: 0;
-    // background: url('/@/assets/images/vent/new-home/header-bg.png') no-repeat;
-    // height: 100px;
-    height: 89px;
-    background-size: contain;
-    display: flex;
-    justify-content: center;
-    .header-icon {
-      margin-top: 45px;
-    }
-    .header-text {
+    position: relative;
+    z-index: 9999;
+    pointer-events: none;
+    .vent-home-header {
+      width: 100%;
       position: fixed;
-      top: 5px;
-      color: #fff;
-      font-size: 32px;
-      font-family: 'ysbtFont';
-      background-image: linear-gradient(#ffffff 50%, @vent-base-light-bg);
-      -webkit-background-clip: text;
-      color: transparent;
+      top: 0;
+      // background: url('/@/assets/images/vent/new-home/header-bg.png') no-repeat;
+      // height: 100px;
+      height: 89px;
+      background-size: contain;
+      display: flex;
+      justify-content: center;
+      .header-icon {
+        margin-top: 45px;
+      }
+      .header-text {
+        position: fixed;
+        top: 5px;
+        color: #fff;
+        font-size: 32px;
+        font-family: 'ysbtFont';
+        background-image: linear-gradient(#ffffff 50%, @vent-base-light-bg);
+        -webkit-background-clip: text;
+        color: transparent;
+      }
     }
   }
-}
-:deep(.zxm-select) {
-  width: 300px;
-  .@{ventSpace}-select-selector {
-    background: transparent !important;
-    border: none !important;
-    box-shadow: none !important;
-    .zxm-select-selection-item {
+  :deep(.zxm-select) {
+    width: 300px;
+    .@{ventSpace}-select-selector {
+      background: transparent !important;
+      border: none !important;
+      box-shadow: none !important;
+      .zxm-select-selection-item {
+        color: #fff !important;
+        font-size: 20px;
+      }
+    }
+    .@{ventSpace}-select-arrow {
       color: #fff !important;
-      font-size: 20px;
     }
   }
-  .@{ventSpace}-select-arrow {
-    color: #fff !important;
-  }
-}
 </style>

+ 300 - 292
src/views/vent/home/configurable/belt/configurable.data.ts

@@ -458,206 +458,206 @@ export const testBeltNew: Config[] = [
       gallery_list: [],
       table: [],
       complex_list: [],
-      list: [
-        {
-          title: '微震测声传感器',
-          readFrom: 'wz',
-          contentTop: [
-            {
-              label: '平均值',
-              code: 'avg',
-              color: 'white',
-            },
-            {
-              label: '最大值',
-              code: 'max',
-              color: 'white',
-            },
-            {
-              label: '最小值',
-              code: 'min',
-              color: 'white',
-            },
-          ],
-          contents: [
-            {
-              label: '是否报警',
-              code: 'alarm',
-              trans: {
-                true: '报警',
-                false: '正常',
-              },
-              color: 'green',
-            },
-            {
-              label: '最大值产生于',
-              code: 'maxTime',
-              color: 'white',
-            },
-          ],
-        },
-        {
-          title: 'HCl传感器',
-          readFrom: 'hcl',
-          contentTop: [
-            {
-              label: '平均值',
-              code: 'avg',
-              color: 'white',
-            },
-            {
-              label: '最大值',
-              code: 'max',
-              color: 'white',
-            },
-            {
-              label: '最小值',
-              code: 'min',
-              color: 'white',
-            },
-          ],
-          contents: [
-            {
-              label: '是否报警',
-              code: 'alarm',
-              trans: {
-                true: '报警',
-                false: '正常',
-              },
-              color: 'green',
-            },
-            {
-              label: '最大值产生于',
-              code: 'maxTime',
-              color: 'white',
-              info: {
-                code: 'pos',
-              },
-            },
-          ],
-        },
-        {
-          title: '光纤测温传感器',
-          readFrom: 'gx',
-          contentTop: [
-            {
-              label: '平均值',
-              code: 'avg',
-              color: 'white',
-            },
-            {
-              label: '最大值',
-              code: 'max',
-              color: 'white',
-            },
-            {
-              label: '最小值',
-              code: 'min',
-              color: 'white',
-            },
-          ],
-          contents: [
-            {
-              label: '是否报警',
-              code: 'alarm',
-              trans: {
-                true: '报警',
-                false: '正常',
-              },
-              color: 'green',
-            },
-            {
-              label: '最大值产生于',
-              code: 'maxTime',
-              color: 'white',
-              info: {
-                code: 'pos',
-              },
-            },
-          ],
-        },
-        {
-          title: 'CO传感器',
-          readFrom: 'co',
-          contentTop: [
-            {
-              label: '平均值',
-              code: 'avg',
-              color: 'white',
-            },
-            {
-              label: '最大值',
-              code: 'max',
-              color: 'white',
-            },
-            {
-              label: '最小值',
-              code: 'min',
-              color: 'white',
-            },
-          ],
-          contents: [
-            {
-              label: '是否报警',
-              code: 'alarm',
-              trans: {
-                true: '报警',
-                false: '正常',
-              },
-              color: 'green',
-            },
-            {
-              label: '最大值产生于',
-              code: 'maxTime',
-              color: 'white',
-              info: {
-                code: 'pos',
-              },
-            },
-          ],
-        },
+      list: [],
+      preset: [
         {
-          title: '温度传感器',
-          readFrom: 'wd',
-          contentTop: [
+          readFrom: 'fmhjcInfo[0]',
+          list: [
             {
-              label: '平均值',
-              code: 'avg',
-              color: 'white',
+              title: '微震测声传感器',
+              contentTop: [
+                {
+                  label: '平均值',
+                  code: '${wz.avg}',
+                  color: 'white',
+                },
+                {
+                  label: '最大值',
+                  code: 'max',
+                  color: 'white',
+                },
+                {
+                  label: '最小值',
+                  code: 'min',
+                  color: 'white',
+                },
+              ],
+              contents: [
+                {
+                  label: '是否报警',
+                  code: 'alarm',
+                  trans: {
+                    true: '报警',
+                    false: '正常',
+                  },
+                  color: 'green',
+                },
+                {
+                  label: '最大值产生于',
+                  code: 'maxTime',
+                  color: 'white',
+                },
+              ],
             },
             {
-              label: '最大值',
-              code: 'max',
-              color: 'white',
+              title: 'HCl传感器',
+              contentTop: [
+                {
+                  label: '平均值',
+                  code: '${avg}',
+                  color: 'white',
+                },
+                {
+                  label: '最大值',
+                  code: 'max',
+                  color: 'white',
+                },
+                {
+                  label: '最小值',
+                  code: 'min',
+                  color: 'white',
+                },
+              ],
+              contents: [
+                {
+                  label: '是否报警',
+                  code: 'alarm',
+                  trans: {
+                    true: '报警',
+                    false: '正常',
+                  },
+                  color: 'green',
+                },
+                {
+                  label: '最大值产生于',
+                  code: 'maxTime',
+                  color: 'white',
+                  info: {
+                    code: 'pos',
+                  },
+                },
+              ],
             },
             {
-              label: '最小值',
-              code: 'min',
-              color: 'white',
+              title: '光纤测温传感器',
+              contentTop: [
+                {
+                  label: '平均值',
+                  code: 'avg',
+                  color: 'white',
+                },
+                {
+                  label: '最大值',
+                  code: 'max',
+                  color: 'white',
+                },
+                {
+                  label: '最小值',
+                  code: 'min',
+                  color: 'white',
+                },
+              ],
+              contents: [
+                {
+                  label: '是否报警',
+                  code: 'alarm',
+                  trans: {
+                    true: '报警',
+                    false: '正常',
+                  },
+                  color: 'green',
+                },
+                {
+                  label: '最大值产生于',
+                  code: 'maxTime',
+                  color: 'white',
+                  info: {
+                    code: 'pos',
+                  },
+                },
+              ],
             },
-          ],
-          contents: [
             {
-              label: '是否报警',
-              code: 'alarm',
-              trans: {
-                true: '报警',
-                false: '正常',
-              },
-              color: 'green',
+              title: 'CO传感器',
+              contentTop: [
+                {
+                  label: '平均值',
+                  code: 'avg',
+                  color: 'white',
+                },
+                {
+                  label: '最大值',
+                  code: 'max',
+                  color: 'white',
+                },
+                {
+                  label: '最小值',
+                  code: 'min',
+                  color: 'white',
+                },
+              ],
+              contents: [
+                {
+                  label: '是否报警',
+                  code: 'alarm',
+                  trans: {
+                    true: '报警',
+                    false: '正常',
+                  },
+                  color: 'green',
+                },
+                {
+                  label: '最大值产生于',
+                  code: 'maxTime',
+                  color: 'white',
+                  info: {
+                    code: 'pos',
+                  },
+                },
+              ],
             },
             {
-              label: '最大值产生于',
-              code: 'maxTime',
-              color: 'white',
-              info: {
-                code: 'pos',
-              },
+              title: '温度传感器',
+              contentTop: [
+                {
+                  label: '平均值',
+                  code: 'avg',
+                  color: 'white',
+                },
+                {
+                  label: '最大值',
+                  code: 'max',
+                  color: 'white',
+                },
+                {
+                  label: '最小值',
+                  code: 'min',
+                  color: 'white',
+                },
+              ],
+              contents: [
+                {
+                  label: '是否报警',
+                  code: 'alarm',
+                  trans: {
+                    true: '报警',
+                    false: '正常',
+                  },
+                  color: 'green',
+                },
+                {
+                  label: '最大值产生于',
+                  code: 'maxTime',
+                  color: 'white',
+                  info: {
+                    code: 'pos',
+                  },
+                },
+              ],
             },
           ],
         },
       ],
-      preset: [],
     },
     showStyle: {
       size: 'width:400px;height:790px;',
@@ -702,8 +702,12 @@ export const testBeltNew: Config[] = [
       chart: [],
       gallery: [],
       gallery_list: [],
-      table: [
+      table: [],
+      list: [],
+      complex_list: [],
+      preset: [
         {
+          readFrom: '',
           type: 'C',
           tableReadFrom: 'sysList',
           columns: [
@@ -743,9 +747,6 @@ export const testBeltNew: Config[] = [
           },
         },
       ],
-      list: [],
-      complex_list: [],
-      preset: [],
     },
     showStyle: {
       size: 'width:1030px;height:300px;',
@@ -763,7 +764,7 @@ export const testBeltNew: Config[] = [
         show: false,
         readFrom: '',
         selector: {
-          show: true,
+          show: false,
           value: '${beltName}',
         },
         slot: {
@@ -790,58 +791,60 @@ export const testBeltNew: Config[] = [
       gallery: [],
       gallery_list: [],
       table: [],
-      list: [
-        {
-          title: '火焰传感器', // 对应 UI 图中的组标题
-          readFrom: 'hy',
-          items: [
-            {
-              label: '是否报警',
-              code: 'isAlarm', // 占位符
-              status: 'isAlarm', // 状态映射逻辑 (0:正常, 1:报警)
-            },
-            {
-              label: '最大值产生于',
-              code: 'maxTime',
-              info: '1521胶运顺槽600m',
-            },
-          ],
-        },
+      list: [],
+      complex_list: [],
+      preset: [
         {
-          title: '温度传感器',
-          readFrom: 'wd',
-          items: [
+          readFrom: 'sensorAnalysis',
+          config: [
             {
-              label: '是否报警',
-              code: 'isAlarm', // 占位符
-              status: 'isAlarm', // 状态映射逻辑 (0:正常, 1:报警)
-            },
-            {
-              label: '最大值产生于',
-              code: 'maxTime',
-              info: '1521胶运顺槽600m',
+              title: '火焰传感器', // 对应 UI 图中的组标题
+              items: [
+                {
+                  label: '是否报警',
+                  code: '${hy.alarm}', // 占位符
+                  status: '1', // 状态映射逻辑 (0:正常, 1:报警)
+                },
+                {
+                  label: '最大值产生于',
+                  code: 'maxTime',
+                  info: '1521胶运顺槽600m',
+                },
+              ],
             },
-          ],
-        },
-        {
-          title: '烟雾传感器',
-          readFrom: 'yw',
-          items: [
             {
-              label: '是否报警',
-              code: 'isAlarm', // 占位符
-              status: 'isAlarm', // 状态映射逻辑 (0:正常, 1:报警)
+              title: '温度传感器',
+              items: [
+                {
+                  label: '是否报警',
+                  code: 'isAlarm', // 占位符
+                  status: 'isAlarm', // 状态映射逻辑 (0:正常, 1:报警)
+                },
+                {
+                  label: '最大值产生于',
+                  code: 'maxTime',
+                  info: '1521胶运顺槽600m',
+                },
+              ],
             },
             {
-              label: '最大值产生于',
-              code: 'maxTime',
-              info: '1521胶运顺槽600m',
+              title: '烟雾传感器',
+              items: [
+                {
+                  label: '是否报警',
+                  code: 'isAlarm', // 占位符
+                  status: 'isAlarm', // 状态映射逻辑 (0:正常, 1:报警)
+                },
+                {
+                  label: '最大值产生于',
+                  code: 'maxTime',
+                  info: '1521胶运顺槽600m',
+                },
+              ],
             },
           ],
         },
       ],
-      complex_list: [],
-      preset: [],
     },
     showStyle: {
       size: 'width:400px;height:400px;',
@@ -860,7 +863,7 @@ export const testBeltNew: Config[] = [
         show: false,
         readFrom: '',
         selector: {
-          show: true,
+          show: false,
           value: '${beltName}',
         },
         slot: {
@@ -887,75 +890,80 @@ export const testBeltNew: Config[] = [
       gallery: [],
       gallery_list: [],
       table: [],
-      list: [
-        {
-          type: 'control',
-          title: '车辆干扰排除',
-          layout: 'horizontal',
-          readFrom: '',
-          items: [
-            {
-              label: '状态',
-              code: 'isRisk',
-              trans: {
-                true: '开启',
-                false: '关闭',
-              },
-            },
-          ],
-        },
-        {
-          type: 'activity',
-          title: '最近车辆活动',
-          readFrom: 'activityList',
-          items: [
-            {
-              label: '',
-              code: 'pos',
-            },
-            {
-              label: '',
-              code: 'vehicle',
-            },
-            {
-              label: '',
-              code: 'status', // 状态映射逻辑 (0:已排除, 1:预警)
-            },
-          ],
-        },
+      list: [],
+      complex_list: [],
+      preset: [
         {
-          type: 'analysis',
-          title: 'CO浓度异常分析',
-          readFrom: 'analysisList',
-          items: [
-            {
-              label: '',
-              code: 'pos',
+          readFrom: 'vehicleCOAnalysis',
+          list: [
+            {
+              type: 'control',
+              title: '车辆干扰排除',
+              layout: 'horizontal',
+              readFrom: '',
+              items: [
+                {
+                  label: '状态',
+                  code: 'isRisk',
+                  trans: {
+                    true: '开启',
+                    false: '关闭',
+                  },
+                },
+              ],
             },
             {
-              label: '',
-              code: 'analysisText',
+              type: 'activity',
+              title: '最近车辆活动',
+              readFrom: 'activityList',
+              items: [
+                {
+                  label: '',
+                  code: 'pos',
+                },
+                {
+                  label: '',
+                  code: 'vehicle',
+                },
+                {
+                  label: '',
+                  code: 'status', // 状态映射逻辑 (0:已排除, 1:预警)
+                },
+              ],
             },
-          ],
-        },
-        {
-          type: 'reasonAnalysis',
-          title: '',
-          readFrom: '',
-          items: [
             {
-              label: '可能原因',
-              code: 'possibleCause',
+              type: 'analysis',
+              title: 'CO浓度异常分析',
+              readFrom: 'analysisList',
+              items: [
+                {
+                  label: '',
+                  code: 'pos',
+                },
+                {
+                  label: '',
+                  code: 'analysisText',
+                },
+              ],
             },
             {
-              label: '建议',
-              code: 'recommendation',
+              type: 'reasonAnalysis',
+              title: '',
+              readFrom: '',
+              items: [
+                {
+                  label: '可能原因',
+                  code: 'possibleCause',
+                },
+                {
+                  label: '建议',
+                  code: 'recommendation',
+                },
+              ],
             },
           ],
         },
       ],
-      complex_list: [],
-      preset: [],
     },
     showStyle: {
       size: 'width:400px;height:410px;',

+ 365 - 365
src/views/vent/home/configurable/blue/components/content.vue

@@ -168,406 +168,406 @@
   </div>
 </template>
 <script lang="ts" setup>
-import { computed } from 'vue';
-import {
-  CommonItem,
-  Config,
-  // ModuleDataBoard,
-  // ModuleDataChart,
-  // ModuleDataList,
-  // ModuleDataPreset,
-  // ModuleDataTable,
-} from '../../../deviceManager/configurationTable/types';
-import MiniBoard from '../../components/detail/MiniBoard.vue';
-import TimelineList from '../../components/detail/TimelineList.vue';
-import TimelineListNew from '../../components/detail/TimelineListNew.vue';
-import CustomList from '../../components/detail/CustomList.vue';
-import CustomGallery from '../../components/detail/CustomGallery.vue';
-import CustomGalleryNew from '../../components/preset/CustomGalleryNew.vue';
-import ComplexList from '../../components/detail/ComplexList.vue';
-import ComplexListNew from '../../components/preset/ComplexListNew.vue';
-import GalleryList from '../../components/detail/GalleryList.vue';
-import CustomTable from '../../components/detail/CustomTable.vue';
-import CustomTableNew from '../../components/preset/CustomTableNew.vue';
-import CustomChart from '../../components/detail/CustomChart.vue';
-import { clone } from 'lodash-es';
-import { getData, getFormattedText } from '../../hooks/helper';
-import BlastDelta from '../../../../monitorManager/deviceMonitor/components/device/modal/blastDelta.vue';
-import QHCurve from '../../components/preset/QHCurve.vue';
-import MeasureDetail from '../../components/preset/MeasureDetail.vue';
-import CustomTabs from '../../components/preset/CustomTabs.vue';
-import AIChat from '/@/components/AIChat/MiniChat.vue';
-import DeviceAlarm from '../../components/preset/DeviceAlarm.vue';
-import SelectCs from '../../components/preset/SelectCs.vue';
-import MiniBoardNew from '../../components/detail/MiniBoard-New.vue';
-import Partition from '../../components/preset/partition.vue';
-import SelectorDualChart from '../../components/preset/selectorDualChart.vue';
-import RadioLabel from '../../components/preset/radioLabel.vue';
-import ButtonList from '../../components/preset/buttonList.vue';
-import VentRoute from '../../components/preset/ventRoute.vue';
-import EarlyWarnMonitor from '../../components/preset/earlyWarnMonitor.vue';
-import CoalSeam from '../../components/preset/CoalSeam.vue';
-// import FIreWarn from './preset/FIreWarn.vue';
-// import FIreControl from './preset/FIreControl.vue';
-
-const props = defineProps<{
-  data: any;
-  moduleData: Config['moduleData'];
-}>();
-
-const { background, layout } = props.moduleData;
-
-// 获取当原始配置带 items 项时的最终 items 配置
-function getItems(raw, items: CommonItem[]) {
-  return items.map((i) => {
-    return {
-      ...i,
-      label: getFormattedText(raw, i.label, i.trans),
-      value: getFormattedText(raw, i.value, i.trans),
-    };
-  });
-}
-
-// 获取当 List 组件配置带 items 项时的最终 items 配置
-function getListItems(raw: any, items: CommonItem[], mapFromData?: boolean) {
-  if (mapFromData && Array.isArray(raw)) {
-    return raw.map((data) => {
-      const item = items[0];
+  import { computed } from 'vue';
+  import {
+    CommonItem,
+    Config,
+    // ModuleDataBoard,
+    // ModuleDataChart,
+    // ModuleDataList,
+    // ModuleDataPreset,
+    // ModuleDataTable,
+  } from '../../../deviceManager/configurationTable/types';
+  import MiniBoard from '../../components/detail/MiniBoard.vue';
+  import TimelineList from '../../components/detail/TimelineList.vue';
+  import TimelineListNew from '../../components/detail/TimelineListNew.vue';
+  import CustomList from '../../components/detail/CustomList.vue';
+  import CustomGallery from '../../components/detail/CustomGallery.vue';
+  import CustomGalleryNew from '../../components/preset/CustomGalleryNew.vue';
+  import ComplexList from '../../components/detail/ComplexList.vue';
+  import ComplexListNew from '../../components/preset/ComplexListNew.vue';
+  import GalleryList from '../../components/detail/GalleryList.vue';
+  import CustomTable from '../../components/detail/CustomTable.vue';
+  import CustomTableNew from '../../components/preset/CustomTableNew.vue';
+  import CustomChart from '../../components/detail/CustomChart.vue';
+  import { clone } from 'lodash-es';
+  import { getData, getFormattedText } from '../../hooks/helper';
+  import BlastDelta from '../../../../monitorManager/deviceMonitor/components/device/modal/blastDelta.vue';
+  import QHCurve from '../../components/preset/QHCurve.vue';
+  import MeasureDetail from '../../components/preset/MeasureDetail.vue';
+  import CustomTabs from '../../components/preset/CustomTabs.vue';
+  import AIChat from '/@/components/AIChat/MiniChat.vue';
+  import DeviceAlarm from '../../components/preset/DeviceAlarm.vue';
+  import SelectCs from '../../components/preset/SelectCs.vue';
+  import MiniBoardNew from '../../components/detail/MiniBoard-New.vue';
+  import Partition from '../../components/preset/partition.vue';
+  import SelectorDualChart from '../../components/preset/selectorDualChart.vue';
+  import RadioLabel from '../../components/preset/radioLabel.vue';
+  import ButtonList from '../../components/preset/buttonList.vue';
+  import VentRoute from '../../components/preset/ventRoute.vue';
+  import EarlyWarnMonitor from '../../components/preset/earlyWarnMonitor.vue';
+  import CoalSeam from '../../components/preset/CoalSeam.vue';
+  // import FIreWarn from './preset/FIreWarn.vue';
+  // import FIreControl from './preset/FIreControl.vue';
+
+  const props = defineProps<{
+    data: any;
+    moduleData: Config['moduleData'];
+  }>();
+
+  const { background, layout } = props.moduleData;
+
+  // 获取当原始配置带 items 项时的最终 items 配置
+  function getItems(raw, items: CommonItem[]) {
+    return items.map((i) => {
       return {
-        ...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) => {
-    switch (item.name) {
-      case 'board': {
-        const cfg = board.shift();
-        if (!cfg) break;
-        const data = getData(refData, cfg.readFrom, cfg.parser);
-
-        arr.push({
-          overflow: true,
-          ...item,
-          ...cfg,
-          items: getItems(data, cfg.items),
-        });
-        break;
-      }
-      case 'list': {
-        const cfg = list.shift();
-        if (!cfg) break;
-        const data = getData(refData, cfg.readFrom, cfg.parser);
 
-        arr.push({
-          overflow: true,
+  // 获取当 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: getListItems(data, cfg.items, cfg.mapFromData),
-        });
-        break;
-      }
-      case 'gallery': {
-        const cfg = gallery.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: getItems(data, cfg.items),
-        });
-        break;
-      }
-      case 'complex_list': {
-        const cfg = complex_list.shift();
-        if (!cfg) break;
-        const data = getData(refData, cfg.readFrom, cfg.parser);
+  /** 根据配置里的layout将配置格式化为带 key 的具体配置,例如:[{ key: 'list', value: any, ...ModuleDataList }] */
+  const layoutConfig = computed(() => {
+    const refData = props.data;
+    const board = clone(props.moduleData.board) || [];
+    const list = clone(props.moduleData.list) || [];
+    const gallery = clone(props.moduleData.gallery) || [];
+    const complex_list = clone(props.moduleData.complex_list) || [];
+    const gallery_list = clone(props.moduleData.gallery_list) || [];
+    const tabs = clone(props.moduleData.tabs) || [];
+    const chart = clone(props.moduleData.chart) || [];
+    const table = clone(props.moduleData.table) || [];
+    const preset = clone(props.moduleData.preset) || [];
+    const partition = clone(props.moduleData.partition) || [];
+
+    return layout.items.reduce((arr: any[], item) => {
+      switch (item.name) {
+        case 'board': {
+          const cfg = board.shift();
+          if (!cfg) break;
+          const data = getData(refData, cfg.readFrom, cfg.parser);
 
-        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);
+
+          if (cfg.mapFromData) {
+            const firstListItem = cfg.items[0];
+            arr.push({
+              overflow: true,
+              ...item,
+              ...cfg,
+              items: (data || []).map((d) => {
+                return {
+                  title: getFormattedText(d, firstListItem.title, firstListItem.trans),
+                  contents: firstListItem.contents.map((e) => {
+                    return {
+                      ...e,
+                      label: getFormattedText(d, e.label, e.trans),
+                      value: getFormattedText(d, e.value, e.trans),
+                    };
+                  }),
+                };
+              }),
+            });
+          } else {
+            arr.push({
+              overflow: true,
+              ...item,
+              ...cfg,
+              items: cfg.items.map((i) => {
+                return {
+                  title: getFormattedText(data, i.title, i.trans),
+                  contents: i.contents.map((e) => {
+                    return {
+                      ...e,
+                      label: getFormattedText(data, e.label, e.trans),
+                      value: getFormattedText(data, e.value, e.trans),
+                    };
+                  }),
+                };
+              }),
+            });
+          }
+          break;
+        }
+        case 'chart': {
+          const cfg = chart.shift();
+          if (!cfg) break;
+          const data = getData(refData, cfg.readFrom, cfg.parser);
 
-        arr.push({
-          ...item,
-          config: cfg,
-          data,
-        });
-        break;
-      }
-      case 'table': {
-        const cfg = table.shift();
-        if (!cfg) break;
-        const data = getData(refData, cfg.readFrom, cfg.parser);
+          arr.push({
+            ...item,
+            config: cfg,
+            data,
+          });
+          break;
+        }
+        case 'table': {
+          const cfg = table.shift();
+          if (!cfg) break;
+          const data = getData(refData, cfg.readFrom, cfg.parser);
 
-        arr.push({
-          ...cfg,
-          ...item,
-          columns: cfg.columns,
-          data,
-        });
-        break;
-      }
-      case 'partition': {
-        const cfg = partition.shift();
-        if (!cfg) break;
-        const data = getData(refData, cfg.readFrom, cfg.parser);
-        arr.push({
-          overflow: true,
-          ...item,
-          data,
-          ...cfg,
-        });
-        break;
-      }
-      default: {
-        const cfg = preset.shift();
-        if (!cfg) break;
-        const data = getData(refData, cfg.readFrom, cfg.parser);
+          arr.push({
+            ...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;
+          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';
-
-.content {
-  height: calc(100% - 30px);
-  position: relative;
-  // z-index: -2;
-  display: flex;
-  flex-direction: column;
-  overflow-y: auto; // 这里会导致样式无故添加滚动条
-  overflow-x: hidden;
-}
-
-.content__background {
-  width: 100%;
-  height: 100%;
-  position: absolute;
-  top: 0;
-  left: 0;
-  z-index: 0;
-  object-fit: fill;
-}
-
-.content__background_1 {
-  width: 100%;
-  height: calc(100% - 10px);
-  position: absolute;
-  top: 10px;
-  left: 0;
-  z-index: 0;
-  object-fit: fill;
-}
-
-.image__background {
-  width: 35%;
-  height: 61%;
-  left: 30%;
-}
-
-.content__module {
-  // margin-top: 5px;
-  // margin-bottom: 5px;
-  width: 100%;
-  height: 100%;
-}
-
-.content__module1 {
-  background: url('@/assets/images/vent/homeNew/databg/4.png');
-  background-repeat: no-repeat;
-  background-size: 100% 100%;
-  height: 129px;
-  margin-top: 20%;
-}
-
-.content__moduleFire {
-  width: 100%;
-  height: 100%;
-  margin-left: -24% !important;
-}
-
-.content__module_dust {
-  // background: url('@/assets/images/vent/homeNew/bottomBg.png');
-  // background-repeat: no-repeat;
-  // background-size: 100% 100%;
-  width: 100%;
-  height: 100%;
-}
-
-// .content__module:first-of-type {
-//   margin-top: 0;
-// }
-// .content__module:last-of-type {
-//   margin-bottom: 0;
-// }
-::-webkit-scrollbar {
-  width: 5px !important;
-}
-
-::-webkit-scrollbar-thumb {
-  width: 5px !important;
-}
-
-:deep(.zxm-select:not(.zxm-select-customize-input) .zxm-select-selector) {
-  /* background-color: transparent; */
-  color: #fff;
-}
-
-:deep(.zxm-select-arrow) {
-  color: #fff;
-}
-
-:deep(.zxm-select-selection-item) {
-  color: #fff !important;
-}
-
-:deep(.zxm-select-selection-placeholder) {
-  color: #fff !important;
-}
-
-:deep(.dialog-overlay) {
-  width: 100%;
-  height: 100%;
-  position: unset;
-  box-shadow: unset;
-}
-
-::-webkit-scrollbar {
-  width: 5px !important;
-}
-
-::-webkit-scrollbar-thumb {
-  width: 5px !important;
-}
+  @import '@/design/theme.less';
+
+  .content {
+    height: calc(100% - 30px);
+    position: relative;
+    // z-index: -2;
+    display: flex;
+    flex-direction: column;
+    overflow-y: auto; // 这里会导致样式无故添加滚动条
+    overflow-x: hidden;
+  }
+
+  .content__background {
+    width: 100%;
+    height: 100%;
+    position: absolute;
+    top: 0;
+    left: 0;
+    z-index: 0;
+    object-fit: fill;
+  }
+
+  .content__background_1 {
+    width: 100%;
+    height: calc(100% - 10px);
+    position: absolute;
+    top: 10px;
+    left: 0;
+    z-index: 0;
+    object-fit: fill;
+  }
+
+  .image__background {
+    width: 35%;
+    height: 61%;
+    left: 30%;
+  }
+
+  .content__module {
+    // margin-top: 5px;
+    // margin-bottom: 5px;
+    width: 100%;
+    height: 100%;
+  }
+
+  .content__module1 {
+    background: url('@/assets/images/vent/homeNew/databg/4.png');
+    background-repeat: no-repeat;
+    background-size: 100% 100%;
+    height: 129px;
+    margin-top: 20%;
+  }
+
+  .content__moduleFire {
+    width: 100%;
+    height: 100%;
+    margin-left: -24% !important;
+  }
+
+  .content__module_dust {
+    // background: url('@/assets/images/vent/homeNew/bottomBg.png');
+    // background-repeat: no-repeat;
+    // background-size: 100% 100%;
+    width: 100%;
+    height: 100%;
+  }
+
+  // .content__module:first-of-type {
+  //   margin-top: 0;
+  // }
+  // .content__module:last-of-type {
+  //   margin-bottom: 0;
+  // }
+  ::-webkit-scrollbar {
+    width: 5px !important;
+  }
+
+  ::-webkit-scrollbar-thumb {
+    width: 5px !important;
+  }
+
+  :deep(.zxm-select:not(.zxm-select-customize-input) .zxm-select-selector) {
+    /* background-color: transparent; */
+    color: #fff;
+  }
+
+  :deep(.zxm-select-arrow) {
+    color: #fff;
+  }
+
+  :deep(.zxm-select-selection-item) {
+    color: #fff !important;
+  }
+
+  :deep(.zxm-select-selection-placeholder) {
+    color: #fff !important;
+  }
+
+  :deep(.dialog-overlay) {
+    width: 100%;
+    height: 100%;
+    position: unset;
+    box-shadow: unset;
+  }
+
+  ::-webkit-scrollbar {
+    width: 5px !important;
+  }
+
+  ::-webkit-scrollbar-thumb {
+    width: 5px !important;
+  }
 </style>

+ 16 - 52
src/views/vent/home/configurable/components/belt/FireSensorAnalysis.vue

@@ -3,7 +3,7 @@
     <!-- 数据列表容器 -->
     <div class="sensor-list">
       <!-- 循环渲染分组 -->
-      <div v-for="(group, index) in config.list" :key="index" class="sensor-group">
+      <div v-for="(group, index) in config" :key="index" class="sensor-group">
         <!-- 组标题 -->
         <div class="group-title">{{ group.title }}</div>
 
@@ -17,7 +17,7 @@
             <div class="item-label">{{ item.label }}:</div>
             <div class="item-content">
               <!-- 主要数值/状态 -->
-              <span class="item-value">{{ parseValue(item.code, group.readFrom) }} 时刻 {{ item.info }} </span>
+              <span class="item-value">{{ getFormattedText(data, item.code) }} 时刻 {{ getFormattedText(data, item.info!) }} </span>
             </div>
           </template>
         </div>
@@ -27,66 +27,30 @@
 </template>
 
 <script setup lang="ts">
-  import { defineProps, computed } from 'vue';
+  import { computed } from 'vue';
+  import { getFormattedText } from '../../hooks/helper';
 
   const props = defineProps<{
-    config: {
-      list: Array<{
-        title: string;
-        readFrom: string;
-        items: Array<{
-          label: string;
-          code: string;
-          status?: string;
-          info?: string;
-        }>;
+    config: Array<{
+      title: string;
+      readFrom: string;
+      items: Array<{
+        label: string;
+        code: string;
+        status?: string;
+        info?: string;
       }>;
-      data: {
-        [key: string]: any;
-      };
+    }>;
+    data: {
+      [key: string]: any;
     };
   }>();
 
-  /**
-   * 解析 ${} 占位符的函数
-   * @param str - 原始字符串,如 "${[0].avg}"
-   */
-  const parseValue = (str: string, readFrom: string) => {
-    try {
-      // 简单的字符串替换逻辑
-      // 匹配 ${[索引].属性名} 格式
-      if (str.includes('${')) {
-        const regex = /\$\{\[(\d+)\]\.(\w+)\}/;
-
-        const match = str.match(regex);
-        if (match) {
-          const index = match[1]; // 获取索引,例如 "0"
-          const key = match[2]; // 获取属性名,例如 "max"
-          // 安全读取数据
-          if (props.config.data[index] !== undefined) {
-            return props.config.data[index][key];
-          }
-        }
-      } else {
-        if (readFrom) {
-          return props.config.data[readFrom][str];
-        } else {
-          return props.config.data[str];
-        }
-      }
-
-      return '数据未找到';
-      return 'N/A';
-    } catch (e) {
-      return 'Error';
-    }
-  };
-
   /**
    * 解析状态并返回对应的 CSS 类名
    */
   const parseStatus = (statusStr: string) => {
-    const statusVal = parseValue(statusStr);
+    const statusVal = getFormattedText(props.data, statusStr);
     // 假设 0 为正常,1 为报警
     return statusVal === '1' ? 'status-danger' : 'status-normal';
   };

+ 11 - 45
src/views/vent/home/configurable/components/belt/SensorStatusPanel.vue

@@ -13,19 +13,19 @@
           <div class="value-item">
             <span class="label">{{ sensor.contentTop[0].label }}</span>
             <span class="value" :style="{ color: sensor.contentTop[0].color }">
-              {{ parseTemplate(sensor.contentTop[0].code, sensor.readFrom) }}
+              {{ getFormattedText(data, sensor.contentTop[0].code) }}
             </span>
           </div>
           <div class="value-item">
             <span class="label">{{ sensor.contentTop[1].label }}</span>
             <span class="value" :style="{ color: sensor.contentTop[1].color }">
-              {{ parseTemplate(sensor.contentTop[1].code, sensor.readFrom) }}
+              {{ getFormattedText(data, sensor.contentTop[1].code) }}
             </span>
           </div>
           <div class="value-item">
             <span class="label">{{ sensor.contentTop[2].label }}</span>
             <span class="value" :style="{ color: sensor.contentTop[2].color }">
-              {{ parseTemplate(sensor.contentTop[2].code, sensor.readFrom) }}
+              {{ getFormattedText(data, sensor.contentTop[2].code) }}
             </span>
           </div>
         </div>
@@ -40,10 +40,10 @@
             <div
               class="row-value"
               :style="{
-                color: getAlarmColor(parseTemplate(sensor.contents[0].code, sensor.readFrom)),
+                color: getAlarmColor(getFormattedText(data, sensor.contents[0].code)),
               }"
             >
-              {{ getAlarmText(parseTemplate(sensor.contents[0].code, sensor.readFrom)) }}
+              {{ getAlarmText(getFormattedText(data, sensor.contents[0].code)) }}
             </div>
           </div>
 
@@ -53,8 +53,8 @@
               <div class="detail-row">
                 <span class="row-label">{{ sensor.contents[1].label }}: </span>
                 <div class="row-value" :style="{ color: sensor.contents[1].color }">
-                  <span>{{ parseTemplate(sensor.contents[1].code, sensor.readFrom) }} 时刻</span>
-                  <span v-if="sensor.contents[1].info" class="info">{{ parseTemplate(sensor.contents[1].info['code'], sensor.readFrom) }}</span>
+                  <span>{{ getFormattedText(data, sensor.contents[1].code) }} 时刻</span>
+                  <span v-if="sensor.contents[1].info" class="info">{{ getFormattedText(data, sensor.contents[1].code) }}</span>
                 </div>
               </div>
             </div>
@@ -67,6 +67,7 @@
 
 <script lang="ts" setup>
 import { ref, computed } from 'vue';
+import { getFormattedText } from '../../hooks/helper';
 
 const props = defineProps<{
   config: {
@@ -85,47 +86,12 @@ const props = defineProps<{
         info?: string;
       }[];
     }>;
-    data: {
-      [key: string]: any;
-    };
+  };
+  data: {
+    [key: string]: any;
   };
 }>();
 
-/**
- * 解析模板字符串并返回值
- * @param {String} templateStr - 例如: '${[0].max}'
- */
-function parseTemplate(str, readFrom) {
-  try {
-    // 简单的字符串替换逻辑
-    // 匹配 ${[索引].属性名} 格式
-    if (str.includes('${')) {
-      const regex = /\$\{\[(\d+)\]\.(\w+)\}/;
-
-      const match = str.match(regex);
-      if (match) {
-        const index = match[1]; // 获取索引,例如 "0"
-        const key = match[2]; // 获取属性名,例如 "max"
-        // 安全读取数据
-        if (props.config.data[index] !== undefined) {
-          return props.config.data[index][key];
-        }
-      }
-    } else {
-      if (readFrom) {
-        return props.config.data[readFrom][str];
-      } else {
-        return props.config.data[str];
-      }
-    }
-
-    return '数据未找到';
-    return 'N/A';
-  } catch (e) {
-    return 'Error';
-  }
-}
-
 // --- 3. 交互逻辑 ---
 const collapsedIndex = ref(null);
 

+ 6 - 6
src/views/vent/home/configurable/components/belt/WarningResultList.vue

@@ -16,14 +16,14 @@
           <svg class="icon-dot" viewBox="0 0 16 16" width="10" height="10">
             <circle cx="8" cy="8" r="8" fill="red" />
           </svg>
-          <span class="risk-text">{{ config.data[config.otherProps.prop] }}</span>
+          <span v-if="!!data" class="risk-text">{{ data[config.otherProps.prop] }}</span>
         </div>
       </div>
     </div>
 
     <!-- 表格主体 -->
     <div class="table-container">
-      <table class="warning-table">
+      <table v-if="!!data" class="warning-table">
         <thead>
           <tr>
             <th v-for="col in config.columns" :key="col.prop" :style="{ width: col.width }">
@@ -32,7 +32,7 @@
           </tr>
         </thead>
         <tbody>
-          <tr v-for="(row, index) in config.data[config.tableReadFrom]" :key="index" class="table-row">
+          <tr v-for="(row, index) in data[config.tableReadFrom]" :key="index" class="table-row">
             <td v-for="col in config.columns" :key="col.prop" class="table-cell">
               <!-- 如果是 render 函数,且需要渲染 HTML,使用 v-html -->
               <span v-if="col.render" v-html="col.render(row)"></span>
@@ -59,9 +59,9 @@
         title: string;
         prop: string;
       };
-      data: {
-        [key: string]: any;
-      };
+    };
+    data: {
+      [key: string]: any;
     };
   }>();
 </script>

+ 4 - 48
src/views/vent/home/configurable/components/content.vue

@@ -204,22 +204,22 @@
         <!-- ==================== 新增皮带巷火灾监测模块 ==================== -->
         <!-- 1. 传感器状态面板 -->
         <template v-if="config.name === 'sensor_status'">
-          <SensorStatusPanel class="content__module" :config="config" />
+          <SensorStatusPanel class="content__module" :config="config.config" :data="config.data" />
         </template>
 
         <!-- 3. 火灾监测设备分析 -->
         <template v-if="config.name === 'fire_sensor_analysis'">
-          <FireSensorAnalysis class="content__module" :config="config" />
+          <FireSensorAnalysis class="content__module" :config="config.config.config" :data="config.data" />
         </template>
 
         <!-- 4. 预警结果列表 -->
         <template v-if="config.name === 'warning_result'">
-          <WarningResultList class="content__module" :config="config" />
+          <WarningResultList class="content__module" :config="config.config" :data="config.data" />
         </template>
 
         <!-- 5. 车辆定位与 CO 浓度关联分析 -->
         <template v-if="config.name === 'vehicle_co_analysis'">
-          <VehicleCOAnalysis class="content__module" :list="config.list" :data="config.data" />
+          <VehicleCOAnalysis class="content__module" :list="config.config.list" :data="config.data" />
         </template>
       </div>
     </div>
@@ -495,50 +495,6 @@ const layoutConfig = computed(() => {
         });
         break;
       }
-      // ==================== 新增皮带巷模块配置处理 ====================
-      // 火灾监测设备报警与分析
-      case 'sensor_status': {
-        arr.push({
-          overflow: true,
-          ...item,
-          list: list,
-          data: refData,
-        });
-        break;
-      }
-      //火灾监测设备状态
-      case 'fire_sensor_analysis': {
-        arr.push({
-          overflow: true,
-          ...item,
-          list: list,
-          data: refData,
-        });
-        break;
-      }
-
-      case 'warning_result': {
-        const cfg = table.shift();
-        if (!cfg) break;
-        arr.push({
-          overflow: true,
-          ...item,
-          ...cfg,
-          columns: cfg.columns,
-          data: refData,
-        });
-        break;
-      }
-
-      case 'vehicle_co_analysis': {
-        arr.push({
-          overflow: true,
-          ...item,
-          list: list,
-          data: refData,
-        });
-        break;
-      }
 
       default: {
         const cfg = preset.shift();

+ 3 - 3
src/views/vent/home/configurable/components/header.vue

@@ -41,11 +41,11 @@
   </div>
 </template>
 <script lang="ts" setup>
-import { ref, watch } from 'vue';
+import { nextTick, ref, watch } from 'vue';
 import { Config } from '../../../deviceManager/configurationTable/types';
-import { useInitModule } from '../../../home/configurable/hooks/useInit';
+import { useInitModule } from '../hooks/useInit';
 import { MenuItem, Menu, Dropdown } from 'ant-design-vue';
-import { CaretUpOutlined, CaretDownOutlined } from '@ant-design/icons-vue';
+import { SwapOutlined, CaretUpOutlined, CaretDownOutlined } from '@ant-design/icons-vue';
 const props = defineProps<{
   moduleData: Config['moduleData'];
   deviceType: Config['deviceType'];

+ 15 - 21
src/views/vent/home/configurable/hooks/useInit.ts

@@ -1,4 +1,4 @@
-import { computed, ref } from 'vue';
+import { computed, MaybeRef, ref, unref } from 'vue';
 import { list as cfgList } from '@/views/vent/deviceManager/configurationTable/configuration.api';
 // import { list } from '@/views/vent/deviceManager/deviceTable/device.api';
 import { Config } from '@/views/vent/deviceManager/configurationTable/types';
@@ -243,29 +243,23 @@ export function useInitModule(deviceType: Config['deviceType'], moduleData: Conf
     return getFormattedText(selectedDevice.value, header.slot.value, header.slot.trans);
   });
 
-  function init(data) {
-    const result = mock || data;
+  function init(data: MaybeRef) {
+    const result = mock || unref(data);
     if (header.show && header.selector.show) {
       // 如果配置里指明需要 header,检验后初始化设备信息
       const records: Record<string, any>[] | Record<string, any> = getData(get(result, deviceType, []), header.readFrom) || [];
-      debugger;
-
-      if (Array.isArray(devices.value)) {
-        devices.value = records.map((e, i) => {
-          return {
-            id: i,
-            ...e,
-          };
-        });
-        options.value = devices.value.map((e) => {
-          return {
-            label: getFormattedText(e, header.selector.value, header.selector.trans),
-            value: e.id,
-          };
-        });
-      } else {
-        devices.value = records;
-      }
+      devices.value = records.map((e, i) => {
+        return {
+          id: i,
+          ...e,
+        };
+      });
+      options.value = devices.value.map((e) => {
+        return {
+          label: getFormattedText(e, header.selector.value, header.selector.trans),
+          value: e.id,
+        };
+      });
     } else {
       // 没有的话按默认的,将返回结果直接作为一整个设备信息供模块使用
       const record = {