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

[Feat 0000]数据中心操作记录页面、皮带防灭火功能优化

bobo04052021@163.com 3 дней назад
Родитель
Сommit
a1bf694714

+ 19 - 20
src/views/monitor/log/index.vue

@@ -5,8 +5,7 @@
     <a-tab-pane tab="浏览日志" key="3" />
     <a-tab-pane tab="登录统计" key="4" />
   </a-tabs>
-  <BasicTable :key="searchInfo.logType" @register="registerTable" :api="logApi" :searchInfo="searchInfo"
-    :scroll="{ y: 660, x: true }">
+  <BasicTable :key="searchInfo.logType" @register="registerTable" :api="logApi" :searchInfo="searchInfo" :scroll="{ y: 660, x: true }">
     <template #expandedRowRender="{ record }">
       <div v-if="searchInfo.logType == 2">
         <div style="margin-bottom: 5px">
@@ -22,7 +21,7 @@
   </BasicTable>
 </template>
 <script lang="ts" name="monitor-log" setup>
-import { ref,reactive } from 'vue';
+import { ref, reactive } from 'vue';
 import { BasicTable, useTable, TableAction } from '/@/components/Table';
 import { getLogList, getUserLoginStats } from './log.api';
 import { columns, searchFormSchema, searchFormSchema1, operationLogColumn, browserColumn, loginTjColumn } from './log.data';
@@ -30,10 +29,10 @@ import { useListPage } from '/@/hooks/system/useListPage';
 const checkedKeys = ref<Array<string | number>>([]);
 
 const logColumns = ref<any>(columns);
-const logApi = ref<any>(getLogList)
-const logSchemas = ref<any[]>(searchFormSchema)
-const paramTime = ref<any[]>(['createTime_begin', 'createTime_end'])
-let searchInfo =reactive( { logType: '1' });
+const logApi = ref<any>(getLogList);
+const logSchemas = ref<any[]>(searchFormSchema);
+const paramTime = ref<any[]>(['createTime_begin', 'createTime_end']);
+let searchInfo = reactive({ logType: '1' });
 // 列表页面公共参数、方法
 const { prefixCls, tableContext } = useListPage({
   designScope: 'user-list',
@@ -60,28 +59,28 @@ function tabChange(key) {
   switch (key) {
     case '1':
       logColumns.value = columns;
-      logSchemas.value = searchFormSchema
-      paramTime.value = [['fieldTime', ['createTime_begin', 'createTime_end'], 'YYYY-MM-DD']]
-      logApi.value = getLogList
+      logSchemas.value = searchFormSchema;
+      paramTime.value = [['fieldTime', ['createTime_begin', 'createTime_end'], 'YYYY-MM-DD']];
+      logApi.value = getLogList;
       break;
     case '2':
       logColumns.value = operationLogColumn;
-      logSchemas.value = searchFormSchema
-      paramTime.value = [['fieldTime', ['createTime_begin', 'createTime_end'], 'YYYY-MM-DD']]
-      logApi.value = getLogList
+      logSchemas.value = searchFormSchema;
+      paramTime.value = [['fieldTime', ['createTime_begin', 'createTime_end'], 'YYYY-MM-DD']];
+      logApi.value = getLogList;
       break;
     case '3':
       logColumns.value = browserColumn;
-      logSchemas.value = searchFormSchema
-      paramTime.value = [['fieldTime', ['createTime_begin', 'createTime_end'], 'YYYY-MM-DD']]
-      logApi.value = getLogList
+      logSchemas.value = searchFormSchema;
+      paramTime.value = [['fieldTime', ['createTime_begin', 'createTime_end'], 'YYYY-MM-DD']];
+      logApi.value = getLogList;
       break;
     case '4':
       logColumns.value = loginTjColumn;
-      logSchemas.value = searchFormSchema1
-      paramTime.value = [['fieldTime', ['dayStart', 'dayEnd'], 'YYYY-MM-DD']]
-      logApi.value = getUserLoginStats
-      searchInfo={}
+      logSchemas.value = searchFormSchema1;
+      paramTime.value = [['fieldTime', ['dayStart', 'dayEnd'], 'YYYY-MM-DD']];
+      logApi.value = getUserLoginStats;
+      searchInfo = {};
       break;
   }
   //update-end---author:wangshuai ---date:20220506  for:[VUEN-943]vue3日志管理列表翻译不对--------------

+ 46 - 0
src/views/vent/dataCenter/operation/index.vue

@@ -0,0 +1,46 @@
+<template>
+  <BasicTable @register="registerTable" :api="logApi" :scroll="{ y: 660, x: true }"> </BasicTable>
+</template>
+<script lang="ts" name="monitor-log" setup>
+import { ref, reactive } from 'vue';
+import { BasicTable, useTable, TableAction } from '/@/components/Table';
+import { getLogList, getUserLoginStats } from './operation.api';
+import { searchFormSchema, operationColumn } from './log.data';
+import { useListPage } from '/@/hooks/system/useListPage';
+const logApi = ref<any>(getLogList);
+const logSchemas = ref<any[]>(searchFormSchema);
+const paramTime = ref<any[]>(['createTime_begin', 'createTime_end']);
+let searchInfo = reactive({ logType: '1' });
+// 列表页面公共参数、方法
+const { prefixCls, tableContext } = useListPage({
+  designScope: 'user-list',
+  tableProps: {
+    title: '',
+    columns: operationColumn,
+    showActionColumn: false,
+    rowSelection: {
+      columnWidth: 20,
+    },
+    formConfig: {
+      schemas: logSchemas as any,
+      fieldMapToTime: paramTime as any,
+    },
+  },
+});
+
+const [registerTable, { reload }] = tableContext;
+</script>
+<style lang="less" scoped>
+::v-deep .table-form {
+  padding: 0 !important;
+  margin: 0 !important;
+}
+
+::v-deep .zxm-table-title {
+  display: none !important;
+}
+
+::v-deep .zxm-tabs-nav-wrap {
+  padding: 0px 15px !important;
+}
+</style>

+ 99 - 0
src/views/vent/dataCenter/operation/log.data.ts

@@ -0,0 +1,99 @@
+import { BasicColumn, FormSchema } from '/@/components/Table';
+import { getUSerInfo, getDeviceKind } from './operation.api';
+export const searchFormSchema: FormSchema[] = [
+  {
+    label: '设备类型',
+    field: 'devicetype',
+    component: 'ApiSelect',
+    colProps: { span: 5 },
+    componentProps: () => {
+      return {
+        api: async () => {
+          const res = await getDeviceKind();
+          console.log('接口原始返回数据:', res); // 确认接口是否返回了数据
+
+          const arr = Object.entries(res.result || {}).map(([key, value]) => ({
+            id: key,
+            name: value,
+          }));
+          console.log('转换后的数组:', arr); // 确认转换后的数组格式对不对
+          return arr;
+        },
+        labelField: 'name',
+        valueField: 'id',
+        showSearch: true,
+      };
+    },
+  },
+  {
+    label: '操作用户账户',
+    field: 'username',
+    component: 'ApiSelect',
+    colProps: { span: 5 },
+    componentProps: {
+      api: getUSerInfo,
+      labelField: 'realname',
+      valueField: 'username',
+    },
+  },
+  {
+    field: 'createTime_begin',
+    label: '开始时间',
+    component: 'DatePicker',
+    componentProps: {
+      showTime: true,
+      valueFormat: 'YYYY-MM-DD HH:mm:ss',
+    },
+    colProps: { span: 4 },
+  },
+  {
+    field: 'createTime_end',
+    label: '结束时间',
+    component: 'DatePicker',
+    componentProps: {
+      showTime: true,
+      valueFormat: 'YYYY-MM-DD HH:mm:ss',
+    },
+    colProps: { span: 4 },
+  },
+];
+
+export const operationColumn: BasicColumn[] = [
+  {
+    title: '用户',
+    dataIndex: 'realname',
+    width: 100,
+    align: 'left',
+  },
+  {
+    title: '操作设备',
+    dataIndex: 'devicename',
+    width: 80,
+  },
+  {
+    title: '操作ip',
+    dataIndex: 'ip',
+    width: 80,
+  },
+  {
+    title: '操作记录',
+    dataIndex: 'strremark',
+    width: 80,
+  },
+  {
+    title: '下发信息',
+    dataIndex: 'content',
+    width: 80,
+  },
+  {
+    title: '是否成功',
+    dataIndex: 'successflag_dictText',
+    width: 80,
+  },
+  {
+    title: '时间',
+    dataIndex: 'createTime',
+    sorter: true,
+    width: 80,
+  },
+];

+ 23 - 0
src/views/vent/dataCenter/operation/operation.api.ts

@@ -0,0 +1,23 @@
+import { defHttp } from '/@/utils/http/axios';
+
+enum Api {
+  getLogList = '/collect/dpsDevicesetLog/list',
+  getUSerInfo = '/collect/dpsDevicesetLog/getAllUserInfo',
+  getDeviceKind = '/collect/ventanalyShowColum/queryDeviceKindAll',
+}
+//日志列表查询
+export const getLogList = (params) =>
+  defHttp.get({
+    url: Api.getLogList,
+    params,
+  });
+// 用户列表查询
+export const getUSerInfo = () =>
+  defHttp.get({
+    url: Api.getUSerInfo,
+  });
+// 查询设备种类
+export const getDeviceKind = () =>
+  defHttp.get({
+    url: Api.getLogList,
+  });

+ 23 - 31
src/views/vent/home/configurable/belt/belt-new.vue

@@ -2,7 +2,7 @@
 <template>
   <div class="company-home">
     <customHeader
-      :fieldNames="{ label: 'systemname', value: 'sys_id', options: 'children' }"
+      :fieldNames="{ label: 'systemname', value: 'sys_id' }"
       :options="options"
       :optionValue="optionValue"
       @change="changeSelectRow"
@@ -81,7 +81,7 @@ async function getSysDataSource() {
 // 切换检测数据
 function changeSelectRow(deviceID) {
   optionValue.value = deviceID;
-  // getDeviceList();
+  refresh();
 }
 function goToHistory() {
   if (pageType.value === 'history') {
@@ -141,15 +141,14 @@ async function refresh() {
   const modalRes = {};
   const systemParams = {
     devicetype: 'sys',
-    systemID: '2028657172566073346',
+    systemID: optionValue.value,
   };
   const resSys = await getSystem(systemParams);
   Object.assign(modalRes, resSys);
   if (pageType.value == 'fire_risk_warn') {
     configs.value = [...testBeltNew];
     const params = {
-      // sysId: optionValue.value,
-      sysId: '2028657172566073346',
+      sysId: optionValue.value,
       dataList: 'fire_risk_warn,warn_result,vehicle_co_correlate',
       alarmLevel: '102,103,104',
     };
@@ -160,7 +159,7 @@ async function refresh() {
     updateData(resSys);
     configs.value = [...testYjkf];
     const alarmParams = {
-      sysId: '2028657172566073346',
+      sysId: optionValue.value,
       alarmLevel: '104',
     };
     const alarmRes = await getWarnResult(alarmParams);
@@ -169,34 +168,27 @@ async function refresh() {
     }
     updateData(data.value);
   } else if (pageType.value == 'sprayControl') {
-    const params = {
-      devicetype: 'sys',
-      systemID: '2028657172566073346',
-    };
+    updateData(resSys);
     const params1 = {
-      sysId: '2028657172566073346',
+      sysId: optionValue.value,
       alarmLevel: '103,104',
     };
-    Promise.all([getDevice(params), getWarnResult(params1)]).then(([originalData, alarmRes]) => {
-      updateData(originalData);
-      const sprayData: any[] = [];
-      if (data.value?.msgTxt) {
-        data.value.msgTxt.forEach((item) => {
-          const hasSprayAuto = item.type && item.type.toLowerCase().includes('spray_auto');
-          if (hasSprayAuto) {
-            sprayData.push({ ...item, ...item.readData });
-          }
-        });
-      }
-      data.value.sprayData = sprayData;
-      if (alarmRes.warn_result) {
-        data.value.warn_result = alarmRes.warn_result;
-      } else {
-        console.log('❌ 没有获取到 warn_result');
-      }
-      updateData(data.value);
-    });
-
+    const sprayData = [];
+    console.log(data.value, '=======');
+    if (data.value?.deviceInfo) {
+      // 遍历对象的所有 value
+      Object.values(data.value.deviceInfo).forEach((item) => {
+        const hasSprayAuto = item.type && item.type.toLowerCase().includes('spray');
+        if (hasSprayAuto) {
+          sprayData.push({ ...item, ...item.readData });
+        }
+      });
+    }
+    data.value.sprayData = sprayData;
+    const alarmRes = await getWarnResult(params1);
+    if (alarmRes.warn_result) {
+      data.value.warn_result = alarmRes.warn_result;
+    }
     configs.value = [...testSpary];
   } else {
     configs.value = testBeltNew;

+ 73 - 287
src/views/vent/home/configurable/belt/belt.vue

@@ -3,9 +3,7 @@
   <div class="company-home">
     <div class="border">
       <customHeader @open-history="goToHistory">矿井全域皮带巷三级防灭火系统</customHeader>
-      <!-- <div class="test" style="width: 100%; height: 100%; position: absolute; left: 0; top: 0; z-index: 0"> -->
       <SubApp />
-      <!-- </div> -->
       <div class="box-container">
         <template v-if="showHistory">
           <History />
@@ -22,10 +20,10 @@
             :data="data"
             :visible="true"
             @clickItem="handleItemClick"
+            :active-id="currentSelectedId"
           />
         </template>
       </div>
-      <!-- 巷道模型组件 -->
     </div>
   </div>
 </template>
@@ -38,316 +36,104 @@ import ModuleCommon from './components/ModuleCommon.vue';
 import SubApp from '/@/components/vent/micro/createSubApp.vue';
 import History from './components/detail/history.vue';
 import { getDataHome } from './configurable.api';
+
 const { configs, devicesTypes, fetchConfigs } = useInitConfigs();
 const { updateEnhancedConfigs, updateData, data } = useInitPage('矿井全域皮带巷三级防灭火系统');
-const readData = ref({
-  monitor_alert: [
-    {
-      sysId: '2028657172566073300',
-      devJSONAarry: [
-        {
-          name: '光纤测温',
-          value: 0,
-        },
-        {
-          name: 'CO传感器',
-          value: 0,
-        },
-        {
-          name: '烟雾传感器',
-          value: 103,
-        },
-        {
-          name: '火焰传感器',
-          value: 0,
-        },
-        {
-          name: 'HCl传感器',
-          value: 0,
-        },
-        {
-          name: '微震测声传感器',
-          value: 0,
-        },
-        {
-          name: '温度传感器',
-          value: 0,
-        },
-        {
-          name: '多参数传感器',
-          value: 0,
-        },
-      ],
-      sysName: '东翼胶带运输大巷',
-    },
-    {
-      sysId: '2028657172566073301',
-      devJSONAarry: [
-        {
-          name: '光纤测温',
-          value: 103,
-        },
-        {
-          name: 'CO传感器',
-          value: 103,
-        },
-        {
-          name: '烟雾传感器',
-          value: 103,
-        },
-        {
-          name: '火焰传感器',
-          value: 103,
-        },
-        {
-          name: 'HCl传感器',
-          value: 103,
-        },
-        {
-          name: '微震测声传感器',
-          value: 103,
-        },
-        {
-          name: '温度传感器',
-          value: 103,
-        },
-        {
-          name: '多参数传感器',
-          value: 103,
-        },
-      ],
-      sysName: '1101胶带运输顺槽',
-    },
-  ],
-  spray_control: [
-    {
-      systemName: '东翼胶带运输大巷',
-      sysId: '2028657172566073300',
-      sysList: [
-        {
-          netstatus: '1',
-          deviceStatus: '1',
-          plsy: '1#区域 1.4MPa',
-          kzms: '手动',
-        },
-      ],
-    },
-    {
-      sysId: '2028657172566073301',
-      systemName: '1101胶带运输顺槽',
-      sysList: [
-        {
-          netstatus: '1',
-          deviceStatus: '1',
-          plsy: '1#区域 1.4MPa',
-          kzms: '自动',
-        },
-      ],
-    },
-  ],
-  gate_control: [
-    {
-      sysId: '2028657172566073300',
-      systemName: '东翼胶带运输大巷',
-      gateArray: [
-        {
-          rearGateOpen: '0',
-          positon: '风门1',
-          frontGateOpen: '0',
-          status: 1,
-        },
-        {
-          rearGateOpen: '1',
-          positon: '五盘区402辅运大巷风门',
-          frontGateOpen: '1',
-          status: 1,
-        },
-        {
-          rearGateOpen: '1',
-          positon: '风门3',
-          frontGateOpen: '1',
-          status: 1,
-        },
-        {
-          rearGateOpen: '0',
-          positon: '风门4',
-          frontGateOpen: '0',
-          status: 1,
-        },
-        {
-          rearGateOpen: '0',
-          positon: '风门5',
-          frontGateOpen: '0',
-          status: 1,
-        },
-        {
-          rearGateOpen: '1',
-          positon: '风门6',
-          frontGateOpen: '1',
-          status: 1,
-        },
-      ],
-    },
-    {
-      sysId: '2028657172566073301',
-      systemName: '1101胶带运输顺槽',
-      gateArray: [
-        {
-          rearGateOpen: '1',
-          positon: '风门1#',
-          frontGateOpen: '1',
-          status: 1,
-        },
-        {
-          rearGateOpen: '1',
-          positon: '五盘区402辅运大巷风门',
-          frontGateOpen: '1',
-          status: 1,
-        },
-        {
-          rearGateOpen: '0',
-          positon: '风门3#',
-          frontGateOpen: '0',
-          status: 1,
-        },
-        {
-          rearGateOpen: '1',
-          positon: '风门4#',
-          frontGateOpen: '0',
-          status: 1,
-        },
-        {
-          rearGateOpen: '0',
-          positon: '风门5#',
-          frontGateOpen: '1',
-          status: 1,
-        },
-        {
-          rearGateOpen: '1',
-          positon: '风门6#',
-          frontGateOpen: '0',
-          status: 1,
-        },
-      ],
-    },
-  ],
-  risk_evaluator: [
-    {
-      sys_id: '2028657172566073300',
-      systemname: '东翼胶带运输大巷',
-      alarm_level: 103,
-    },
-    {
-      sys_id: '2028657172566073301',
-      systemname: '1101胶带运输顺槽',
-      alarm_level: null,
-    },
-    {
-      sys_id: '2028657172566073302',
-      systemname: '1102辅运顺槽',
-      alarm_level: null,
-    },
-  ],
-});
-// function refresh() {
-//   fetchConfigs('Leather').then(() => {
-//     configs.value = testBeltLaneFire;
-//     Promise.resolve(
-//       getDataHome({
-//         dataList: configs.value
-//           .filter((e) => e.deviceType)
-//           .map((e) => e.deviceType)
-//           .join(','),
-//       })
-//     ).then((res: any) => {
-//       res.spray_control = [
-//         {
-//           systemName: '东翼胶带运输大巷',
-//           sysId: 2028657172566073300,
-//           sysList: [
-//             {
-//               netstatus: '1',
-//               deviceStatus: '1',
-//               plsy: '1#区域 1.4MPa',
-//               kzms: '手动',
-//             },
-//           ],
-//         },
-//         {
-//           sysId: 2028657172566073301,
-//           systemName: '1101胶带运输顺槽',
-//           sysList: [
-//             {
-//               netstatus: '1',
-//               deviceStatus: '1',
-//               plqy: '2#区域',
-//               plsy: '1.6MPa',
-//               kzms: '自动',
-//             },
-//           ],
-//         },
-//       ];
-//       updateData(res);
-//     });
-//     updateEnhancedConfigs(configs.value);
-//   });
-// }
+
+const currentSelectedId = ref<string | number>('');
+
 let timer = null;
 const showHistory = ref(false);
-const handleItemClick = (data) => {
-  const clickId = data.id;
+// 接收子组件上报的点击事件,更新全局选中状态
+const handleItemClick = (item) => {
+  const clickId = item.id;
   if (!clickId) return;
-  filterDataById(clickId);
+  currentSelectedId.value = clickId;
+  console.log('爷组件已更新选中ID:', clickId);
 };
 function goToHistory() {
   showHistory.value = !showHistory.value;
 }
-// 抽离公共筛选方法,初始化 + 点击共用
-const filterDataById = (clickId: string | number) => {
-  const source = readData.value;
-  const monitor = source.monitor_alert.find((item) => String(item.sysId) === String(clickId));
-  const spray = source.spray_control.find((item) => String(item.sysId) === String(clickId));
-  const gate = source.gate_control.find((item) => String(item.sysId) === String(clickId));
 
-  const newData = {
-    ...data.value,
+// 数据筛选
+const filterDataById = (sourceData, clickId: string | number) => {
+  if (!sourceData || !clickId) return sourceData;
+  const id = String(clickId);
+  const monitor = sourceData.monitor_alert?.find((item) => String(item.sysId) === id);
+  const spray = sourceData.spray_control?.find((item) => String(item.sysId) === id);
+  const gate = sourceData.gate_control?.find((item) => String(item.sysId) === id);
+  return {
+    ...sourceData,
     monitor_alert: monitor ? [monitor] : [],
     spray_control: spray ? [spray] : [],
     gate_control: gate ? [gate] : [],
-    risk_evaluator: source.risk_evaluator,
   };
-  updateData(newData);
 };
 
+// ==============================
+// 🔥 修复:正常拉取config,但不覆盖!保证 dataList 正常传参
+// ==============================
 function refresh() {
   fetchConfigs('belt').then(() => {
-    configs.value = testBeltLaneFire;
-    const firstId = readData.value.monitor_alert?.[0]?.sysId;
-    if (firstId) {
-      filterDataById(firstId);
-    } else {
-      Promise.resolve(readData).then(updateData);
+    // 🔥 关键:只有为空时才赋值,不重复覆盖!
+    if (!configs.value || configs.value.length === 0) {
+      configs.value = testBeltLaneFire;
     }
+
+    const dataListStr = configs.value
+      .filter((e) => e.deviceType)
+      .map((e) => e.deviceType)
+      .join(',');
+
+    getDataHome({ dataList: dataListStr }).then((res: any) => {
+      res.spray_control = [
+        {
+          systemName: '东翼胶带运输大巷',
+          sysId: '2028657172566073346',
+          sysList: [{ netstatus: '1', deviceStatus: '1', plsy: '1#区域 1.4MPa', kzms: '手动' }],
+        },
+        {
+          sysId: '2046500718274756609',
+          systemName: '1101胶带运输顺槽',
+          sysList: [{ netstatus: '1', deviceStatus: '1', plqy: '2#区域', plsy: '1.6MPa', kzms: '自动' }],
+        },
+      ];
+      let showData = res;
+
+      // 只要用户选过,就永远保持选中,绝不自动切走
+      if (currentSelectedId.value) {
+        showData = filterDataById(res, currentSelectedId.value);
+      }
+      // 从未选过 → 默认第一个
+      else {
+        const firstId = res.monitor_alert?.[0]?.sysId;
+        if (firstId) {
+          currentSelectedId.value = firstId;
+          showData = filterDataById(res, firstId);
+        }
+      }
+
+      updateData(showData);
+    });
   });
 }
-// function initInterval() {
-//   if (timer) clearInterval(timer);
-//   timer = setInterval(() => {
-//     refresh();
-//   }, 5000);
-// }
+// 轮询
+function initInterval() {
+  if (timer) clearInterval(timer);
+  timer = setInterval(() => {
+    refresh();
+  }, 5000);
+}
 onMounted(() => {
   refresh();
-  // initInterval();
+  initInterval();
 });
+
 onUnmounted(() => {
-  if (timer) {
-    clearInterval(timer);
-    timer = null;
-  }
+  clearInterval(timer);
+  timer = null;
 });
 </script>
-
 <style lang="less" scoped>
 .spray-wrapper {
   width: 100%;
@@ -387,4 +173,4 @@ onUnmounted(() => {
     }
   }
 }
-</style>
+</style>

+ 2 - 0
src/views/vent/home/configurable/belt/components/ModuleCommon.vue

@@ -18,6 +18,7 @@
             :data="selectedDevice"
             :chartData="chartData"
             @clickItem="(data) => emit('clickItem', data)"
+            :active-id="activeId"
           />
           <Content
             v-else
@@ -56,6 +57,7 @@ const props = defineProps<{
   moduleName: string;
   visible: boolean;
   chartData?: any;
+  activeId?: [String, Number]; // 接收ID
 }>();
 // defineEmits(['close', 'click']);
 const emit = defineEmits<{

+ 4 - 1
src/views/vent/home/configurable/belt/components/customHeader-belt.vue

@@ -147,9 +147,12 @@ const handleTitleChange = (value: string) => {
 
   .@{ventSpace}-select-item-option-selected,
   .@{ventSpace}-select-item-option-active {
+    width: 100% !important;
+
     background-color: #ffffff33 !important;
   }
   .@{ventSpace}-select-item {
+    font-size: 20px !important;
     color: inherit;
     &:hover {
       background-color: #ffffff33 !important;
@@ -281,7 +284,7 @@ const handleTitleChange = (value: string) => {
 }
 
 :deep(.zxm-select) {
-  width: 400px;
+  width: 100%;
 
   .@{ventSpace}-select-selector {
     background: transparent !important;

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

@@ -8,8 +8,8 @@
           v-for="(ctx, j) in item.contents"
           :key="`vvhccdclc${j}`"
           style="cursor: pointer"
-          @click="handleItemClick(i, j)"
-          :class="[`list-item__content_${type}`, getBgClass(ctx.value), { active: activeGroup === i && activeItem === j }]"
+          @click="handleItemClick(ctx)"
+          :class="[`list-item__content_${type}`, getBgClass(ctx.value), { active: ctx.id === activeId }]"
         >
           <div class="list-item__label"> {{ ctx.label }}</div>
           <div class="list-item__value" :class="`list-item__value_${type}`"> {{ getAlertName(ctx.value) }} </div>
@@ -36,10 +36,12 @@ const props = withDefaults(
       }[];
     }[];
     type: string;
+    activeId: string | number | '';
   }>(),
   {
     listConfig: () => [],
     type: 'C',
+    activeId: '',
   }
 );
 
@@ -86,11 +88,8 @@ const getBgClass = (riskLevel: string | number | null) => {
 };
 
 // 点击事件
-const handleItemClick = (groupIndex: number, itemIndex: number) => {
-  activeGroup.value = groupIndex;
-  activeItem.value = itemIndex;
-  const rawData = props.listConfig[groupIndex].contents[itemIndex];
-  emit('clickItem', rawData);
+const handleItemClick = (ctx) => {
+  emit('clickItem', ctx);
 };
 
 // 获取预警名称(核心修复)

+ 20 - 9
src/views/vent/home/configurable/components/belt/ComplexListBelt.vue

@@ -2,18 +2,22 @@
 <template>
   <div class="list flex items-center" :class="`list_${type}`">
     <div class="flex-grow" :class="`list_wrapper_${type}`">
-      <!-- 遍历每一组传感器数据 -->
-      <div v-for="(item, i) in listConfig" :key="`customlist${i}`" class="list-item" :class="`list-item_${type}`">
-        <div v-for="(ctx, j) in item.contents" :key="`vvhccdclc${j}`" :class="`list-item__content_${type}`">
-          <div class="item-top">
-            <div class="sensor-icon"></div>
-            <div class="risk-text">{{ getAlertName(ctx.value) }}</div>
-          </div>
-          <div class="item-bottom">
-            {{ ctx.label }}
+      <!-- 👇 核心修改点:增加 v-if 判断 -->
+      <div v-if="listConfig && listConfig.length > 0">
+        <!-- 遍历每一组传感器数据 -->
+        <div v-for="(item, i) in listConfig" :key="`customlist${i}`" class="list-item" :class="`list-item_${type}`">
+          <div v-for="(ctx, j) in item.contents" :key="`vvhccdclc${j}`" :class="`list-item__content_${type}`">
+            <div class="item-top">
+              <div class="sensor-icon"></div>
+              <div class="risk-text">{{ getAlertName(ctx.value) }}</div>
+            </div>
+            <div class="item-bottom">
+              {{ ctx.label }}
+            </div>
           </div>
         </div>
       </div>
+      <div v-else class="no-data"> 暂无数据 </div>
     </div>
   </div>
 </template>
@@ -155,4 +159,11 @@ onMounted(() => {});
   line-height: 1.2;
   width: 100%;
 }
+.no-data {
+  padding: 20px;
+  width: 100%;
+  text-align: center;
+  color: #999;
+  font-size: 16px;
+}
 </style>

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

@@ -4,7 +4,12 @@
       <div class="label-t" v-for="(item, index) in columns" :key="`svvhbcth-${index}`" :style="{ flexBasis }">{{ item.name }}</div>
     </div>
     <div ref="scrollRef" class="table__content_list" :class="`table__content_list_${type}`">
-      <div class="table__content_list_row" v-for="(item, index) in data.data.gate_control[0].gateArray" :key="`svvhbct-${index}`">
+      <!-- 🔥 修复:空数据时依然渲染一行 -->
+      <div class="table__content_list_row" v-if="tableList.length === 0">
+        <div class="empty-text" :style="{ flexBasis: '100%' }"> 暂无数据 </div>
+      </div>
+
+      <div class="table__content_list_row" v-else v-for="(item, index) in tableList" :key="`svvhbct-${index}`">
         <div v-for="(t, i) in columns" :key="`svvhbctr-${i}`" :style="{ flexBasis }" :class="`table__content__list_item_${type}`">
           <slot :name="t.prop" :scope="item">
             <span>
@@ -20,6 +25,7 @@
     </div>
   </div>
 </template>
+
 <script lang="ts" setup>
 import { computed, onMounted, ref } from 'vue';
 import _ from 'lodash';
@@ -30,14 +36,14 @@ let props = withDefaults(
     type: string;
     autoScroll: boolean;
     columns: { prop: string; name: string }[];
-    data: any; // 1. 将类型从 any[] 改为 any,允许接收对象
+    data: any;
     defaultValue: string;
   }>(),
   {
     type: 'B',
     autoScroll: false,
     columns: () => [],
-    data: () => ({}), // 2. 默认值改为空对象
+    data: () => ({}),
     defaultValue: '-',
   }
 );
@@ -46,6 +52,14 @@ const scrollRef = ref(null);
 if (props.autoScroll) {
   useAutoScroll(scrollRef);
 }
+
+// 🔥 核心修复:安全获取 gateArray,永远不会报错/空白
+const tableList = computed(() => {
+  const gateControl = _.get(props, 'data.data.gate_control', []);
+  const firstItem = gateControl[0] || {};
+  return firstItem.gateArray || []; // 不存在就返回空数组
+});
+
 const getStatusClass = (status) => {
   switch (status) {
     case 1:
@@ -58,6 +72,7 @@ const getStatusClass = (status) => {
       return '';
   }
 };
+
 const flexBasis = computed(() => {
   return Math.fround(100 / props.columns.length) + '%';
 });
@@ -66,9 +81,9 @@ function get(o, p) {
   const d = _.get(o, p);
   return _.isNil(d) ? props.defaultValue : d === '' ? props.defaultValue : d;
 }
+
 function formatValue(obj, path) {
   const value = _.get(obj, path);
-  console.log(value, '111111');
   if (_.isNil(value) || value === '') {
     return props.defaultValue;
   }
@@ -82,8 +97,8 @@ function formatValue(obj, path) {
       return value;
   }
 }
-onMounted(() => {});
 </script>
+
 <style lang="less" scoped>
 @import '/@/design/theme.less';
 @import '@/design/theme.less';
@@ -177,5 +192,13 @@ onMounted(() => {});
     background-color: gray;
     box-shadow: 0 0 6px 2px rgba(105, 105, 105, 0.6);
   }
+
+  /* 空状态样式(保持表格行高度,不塌陷) */
+  .empty-text {
+    text-align: center;
+    color: #999;
+    line-height: 50px;
+    font-size: 14px;
+  }
 }
-</style>
+</style>

+ 8 - 1
src/views/vent/home/configurable/components/content.vue

@@ -106,7 +106,13 @@
             <ComplexListBelt class="content__module" :type="config.type" :list-config="config.items" />
           </template>
           <template v-else-if="config.pagetype === 'complex_list1'">
-            <ComplexList1Belt class="content__module" :type="config.type" :list-config="config.items" @clickItem="handleClickItem" />
+            <ComplexList1Belt
+              class="content__module"
+              :type="config.type"
+              :list-config="config.items"
+              @clickItem="handleClickItem"
+              :active-id="activeId"
+            />
           </template>
           <template v-else>
             <ComplexList class="content__module" :type="config.type" :list-config="config.items" />
@@ -293,6 +299,7 @@ const props = defineProps<{
   data: any;
   moduleData: Config['moduleData'];
   chartData: any;
+  activeId?: [String, Number];
 }>();
 
 const emit = defineEmits<{