Quellcode durchsuchen

红沙泉代码-更新

lxh vor 1 Tag
Ursprung
Commit
db1b17938c

BIN
src/assets/images/gasInjection/login-bg.png


BIN
src/assets/images/themify/deepblue/home-container/configurable/gasInjection/login-bg.png


+ 3 - 3
src/views/sys/login/Login.vue

@@ -103,18 +103,18 @@
 
   @{theme-deepblue} {
     .Login {
-      // --image-login-bg: url('@/assets/images/themify/deepblue/home-container/configurable/gasInjection/login-bg.png');
+      --image-login-bg: url('@/assets/images/themify/deepblue/home-container/configurable/gasInjection/login-bg.png');
       --image-login-bd: url('@/assets/images/themify/deepblue/home-container/configurable/gasInjection/login-border.png');
     }
   }
 
   .Login {
-    // --image-login-bg: url('@/assets/images/gasInjection/login-bg.png');
+    --image-login-bg: url('@/assets/images/gasInjection/login-bg.png');
     --image-login-bd: url('@/assets/images/gasInjection/login-border.png');
     position: relative;
     width: 100%;
     height: 100%;
-    // background: var(--image-login-bg) no-repeat;
+    background: var(--image-login-bg) no-repeat;
     background-size: 100% 100%;
 
     .login-container {

+ 28 - 19
src/views/vent/cad/dwgViewer.vue

@@ -19,8 +19,8 @@
         <a-table :columns="columns" :data-source="devices" :pagination="false" row-key="id" size="small" :scroll="{ y: 360 }">
           <template #bodyCell="{ column, record }">
             <template v-if="column.key === 'index'">{{ devices.indexOf(record) + 1 }}</template>
-            <template v-if="column.key === 'status'">
-              <a-tag :color="statusColor(record.status)">{{ statusText(record.status) }}</a-tag>
+            <template v-if="column.key === 'netStatus'">
+              <a-tag :color="statusColor(record.netStatus)">{{ statusText(record.netStatus) }}</a-tag>
             </template>
             <template v-if="column.key === 'action'">
               <a-button type="primary" size="small" :disabled="placingMode" @click="enterPlacingMode(record)">布点</a-button>
@@ -71,6 +71,13 @@
   import { useAppStoreWithOut } from '/@/store/modules/app';
   import dayjs from 'dayjs';
 
+
+  let props=defineProps({
+    devices: {
+      type: Array,
+      default: () => [],
+    },
+  })
   // ==================== 类型 ====================
 
   interface DeviceInfo {
@@ -99,30 +106,32 @@
   // 设备列表表格列
   const columns = [
     { title: '#', key: 'index', width: 36 },
-    { title: '设备名称', dataIndex: 'name', ellipsis: true },
-    { title: '类型', dataIndex: 'type', width: 56 },
-    { title: '状态', key: 'status', width: 54 },
+    { title: '设备名称', dataIndex: 'strname', ellipsis: true },
+    { title: '类型', dataIndex: 'typeName', width: 56 },
+    { title: '状态', key: 'netStatus', width: 54 },
     { title: '操作', key: 'action', width: 56 },
     { title: '布点', key: 'markerStatus', width: 48 },
   ];
   // 设备列表数据
-  const devices = ref<DeviceInfo[]>([
-    // { id: 'd001', name: '1#瓦斯传感器', type: '传感器', status: 'online', markerId: null },
-    // { id: 'd002', name: '2#瓦斯传感器', type: '传感器', status: 'online', markerId: null },
-    // { id: 'd003', name: '主通风机', type: '风机', status: 'online', markerId: null },
-    // { id: 'd004', name: '局部通风机', type: '风机', status: 'offline', markerId: null },
-    // { id: 'd005', name: '风门A', type: '风门', status: 'online', markerId: null },
-    // { id: 'd006', name: '风速传感器-1', type: '传感器', status: 'alarm', markerId: null },
-    // { id: 'd007', name: '温度传感器-1', type: '传感器', status: 'online', markerId: null },
-    // { id: 'd008', name: '风窗B', type: '风窗', status: 'online', markerId: null },
-  ]);
+  // const devices = ref<DeviceInfo[]>([
+  //   // { id: 'd001', name: '1#瓦斯传感器', type: '传感器', status: 'online', markerId: null },
+  //   // { id: 'd002', name: '2#瓦斯传感器', type: '传感器', status: 'online', markerId: null },
+  //   // { id: 'd003', name: '主通风机', type: '风机', status: 'online', markerId: null },
+  //   // { id: 'd004', name: '局部通风机', type: '风机', status: 'offline', markerId: null },
+  //   // { id: 'd005', name: '风门A', type: '风门', status: 'online', markerId: null },
+  //   // { id: 'd006', name: '风速传感器-1', type: '传感器', status: 'alarm', markerId: null },
+  //   // { id: 'd007', name: '温度传感器-1', type: '传感器', status: 'online', markerId: null },
+  //   // { id: 'd008', name: '风窗B', type: '风窗', status: 'online', markerId: null },
+  // ]);
   // 状态颜色映射
   function statusColor(s: string) {
-    return { online: 'green', offline: 'gray', alarm: 'red' }[s] || 'default';
+    // return { online: 'green', offline: 'gray', alarm: 'red' }[s] || 'default';
+    return { 1: 'green', 0: 'gray', }[s] || 'default';
   }
   // 状态文本映射
   function statusText(s: string) {
-    return { online: '在线', offline: '离线', alarm: '报警' }[s] || s;
+    // return { online: '在线', offline: '离线', alarm: '报警' }[s] || s;
+    return { 1: '在线', 0: '离线',  }[s] || s;
   }
   // 模拟监测数据
   function getMockMonitoring(deviceId: string) {
@@ -422,7 +431,7 @@
 
         viewer.renderer.render(viewer.scene, viewer.camera);
         viewer.getCssRender().render(viewer.scene, viewer.camera);
-        css3DRenderer?.render(viewer.scene, viewer.camera);
+        // css3DRenderer?.render(viewer.scene, viewer.camera);
       });
 
       // === 鼠标移动:实时更新坐标 + 浮动圆点跟随 ===
@@ -444,7 +453,7 @@
             currentCoord.z = wp.z;
           }
 
-          css3DRenderer?.render(viewer.scene, viewer.camera);
+          // css3DRenderer?.render(viewer.scene, viewer.camera);
         });
       }
 

+ 28 - 37
src/views/vent/home/configurable/components/content.vue

@@ -1,8 +1,26 @@
-<!-- eslint-disable vue/multi-word-component-names -->
 <template>
-  <!-- 主体内容部分 -->
+  <div>
+
+  </div>
+</template>
+
+<script>
+export default {
+  setup () {
+    
+
+    return {}
+  }
+}
+</script>
+
+<style lang="less" scoped>
+
+</style>
+<!-- 
+<template>
   <div class="content">
-    <!-- 背景 -->
+   
     <img v-if="background.show && background.type === 'image'" class="content__background" :src="background.link" />
     <video
       v-if="background.show && background.type === 'video' && background.isBoard"
@@ -32,7 +50,6 @@
     </video>
     <div class="flex w-full h-full" :style="{ flexDirection: layout.direction }">
       <div v-for="config in layoutConfig" :key="config.name" :style="{ flexBasis: config.basis, overflow: config.overflow ? 'auto' : 'hidden' }">
-        <!-- 告示板部分 -->
         <template v-if="config.name === 'board'">
           <div
             v-if="config.pageType == 'vent_New'"
@@ -70,12 +87,10 @@
             />
           </div>
         </template>
-        <!-- 图表部分,这部分通常需要填充,有告示板、Header等内容需要填充父级 -->
         <template v-if="config.name === 'chart'">
           <CustomChart v-if="config.pageType == 'New_dust'" class="content__module_dust" :chart-config="config.config" :chart-data="config.data" />
           <CustomChart v-else class="content__module" :chart-config="config.config" :chart-data="config.data" />
         </template>
-        <!-- 通常列表部分 -->
         <template v-if="config.name === 'list'">
           <template v-if="config.type === 'timeline'">
             <TimelineList class="content__module" :list-config="config.items" />
@@ -90,19 +105,15 @@
         <template v-if="config.name === 'fireList'">
           <CustomList class="content__module" :type="config.type" :list-config="config.items" />
         </template>
-        <!-- 画廊部分 -->
         <template v-if="config.name === 'gallery'">
           <CustomGallery class="content__module" :type="config.type" :gallery-config="config.items" />
         </template>
-        <!-- 复杂列表部分 -->
         <template v-if="config.name === 'gallery_list'">
           <GalleryList class="content__module" :type="config.type" :list-config="config.items" :gallery-config="config.galleryItems" />
         </template>
-        <!-- 复杂列表部分 -->
         <template v-if="config.name === 'complex_list'">
           <ComplexList class="content__module" :type="config.type" :list-config="config.items" />
         </template>
-        <!-- 表格部分,这部分通常是占一整个模块的 -->
         <template v-if="config.name === 'table'">
           <CustomTable
             class="content__module text-center overflow-auto"
@@ -133,7 +144,6 @@
         <template v-if="config.name === 'device_alarm'">
           <DeviceAlarm class="content__module" :devicedata="config.data" :config="config.config" />
         </template>
-        <!-- lxh -->
         <template v-if="config.name === 'select_cs'">
           <SelectCs :devicedata="config.data" :config="config.config" />
         </template>
@@ -152,25 +162,6 @@
         <template v-if="config.name === 'selector_dual_chart'">
           <SelectorDualChart :data="config.data" :moduleData="props.moduleData" :config="config" />
         </template>
-        <template v-if="config.name === 'radio_label'">
-          <RadioLabel class="content__module" :type="config.config.type" :config="config.config" />
-        </template>
-        <template v-if="config.name === 'button_list'">
-          <ButtonList class="content__module" :type="config.config.type" :config="config.config" :buttonList="config.config.buttonList" />
-        </template>
-        <template v-if="config.name === 'card_list'">
-          <cardList class="content__module" :cardData="config.data" />
-        </template>
-        <template v-else-if="config.name === 'generalist'">
-          <generalList class="content__module" :generalData="config.data" />
-        </template>
-
-        <template v-else-if="config.name === 'jk-video'">
-          <cameraModal class="content__module" :deviceId="config.data" />
-        </template>
-        <template v-if="config.name === 'gallery_new'">
-          <CustomGalleryNew class="content__module" :type="config.config.type" :option="config.config.items" :galleryData="config.data" />
-        </template>
         <template v-if="config.name === 'card_new'">
           <ImageCardNew :option="config.config.items" :cardData="config.data"></ImageCardNew>
         </template>
@@ -257,13 +248,13 @@ import DeviceAlarm from './preset/DeviceAlarm.vue';
 import MiniBoardNew from './detail/MiniBoard-New.vue';
 import Partition from './preset/partition.vue';
 import SelectorDualChart from './preset/selectorDualChart.vue';
-import RadioLabel from './preset/radioLabel.vue';
-import ButtonList from './preset/buttonList.vue';
-import cardList from './preset/cardList.vue';
-import generalList from './preset/generalList.vue';
+// import RadioLabel from './preset/radioLabel.vue';
+// import ButtonList from './preset/buttonList.vue';
+// import cardList from './preset/cardList.vue';
+// import generalList from './preset/generalList.vue';
 
-import cameraModal from './preset/cameraModal.vue';
-import CustomGalleryNew from './preset/CustomGalleryNew.vue';
+// import cameraModal from './preset/cameraModal.vue';
+// import CustomGalleryNew from './preset/CustomGalleryNew.vue';
 import ImageCardNew from './preset/ImageCardNew.vue';
 import BtnListNew from './preset/BtnListNew.vue';
 import OperateNew from './preset/OperateNew.vue';
@@ -658,4 +649,4 @@ const layoutConfig = computed(() => {
 ::-webkit-scrollbar-thumb {
   width: 5px !important;
 }
-</style>
+</style> -->

+ 2 - 1
src/views/vent/monitorManager/hsqHome/components/CommonTable.vue

@@ -178,12 +178,13 @@ function get(o, p) {
 
     .table__content_list_row {
       width: 100%;
+      height: 30px;
       display: flex;
       justify-content: space-between;
       align-items: center;
       color: #fff;
       margin-bottom: 5px;
-      background-size: 100% auto;
+      background-size: 100% 100%;
       background-repeat: no-repeat;
       background-position: center bottom;
       background-image: var(--image-content-text);

+ 20 - 20
src/views/vent/monitorManager/hsqHome/components/CustomGalleryNew.vue

@@ -12,17 +12,17 @@
         </div>
       </div>
     </div>
-    <div class="custom-bottom">
+    <!-- <div class="custom-bottom">
       <CommonTable :columns="deviceColumns" :table-data="tableData"></CommonTable>
-    </div>
+    </div> -->
   </div>
 </template>
 
 <script setup lang="ts">
 import { computed, onMounted, ref } from 'vue';
 import { SvgIcon } from '/@/components/Icon';
-import CommonTable from './CommonTable.vue';
-import { deviceColumns } from '../hsqHome.data.js';
+// import CommonTable from './CommonTable.vue';
+// import { deviceColumns } from '../hsqHome.data.js';
 
 let props = defineProps({
   option: {
@@ -31,9 +31,9 @@ let props = defineProps({
   galleryData: {
     type: Object
   },
-  tableData: {
-    type: Array as any
-  },
+  // tableData: {
+  //   type: Array as any
+  // },
 })
 </script>
 
@@ -56,17 +56,17 @@ let props = defineProps({
 
   .custom-top {
     width: 100%;
-    height: 40%;
+    height: 100%;
   }
 
-  .custom-bottom {
-    width: 100%;
-    height: 60%;
-    box-sizing: border-box;
-    display: flex;
-    flex-direction: column;
-    align-items: center;
-  }
+  // .custom-bottom {
+  //   width: 100%;
+  //   height: 60%;
+  //   box-sizing: border-box;
+  //   display: flex;
+  //   flex-direction: column;
+  //   align-items: center;
+  // }
 
   .gallery-new-box {
     position: relative;
@@ -81,7 +81,7 @@ let props = defineProps({
 
     &:nth-child(1) {
       left: 22px;
-      top: 4px;
+      top: 5px;
     }
 
     &:nth-child(2) {
@@ -89,12 +89,12 @@ let props = defineProps({
       flex-direction: column;
       align-items: flex-end;
       right: 24px;
-      top: 4px;
+      top: 5px;
     }
 
     &:nth-child(3) {
       left: 22px;
-      top: 72px;
+      top: 77px;
     }
 
     &:nth-child(4) {
@@ -102,7 +102,7 @@ let props = defineProps({
       flex-direction: column;
       align-items: flex-end;
       right: 24px;
-      top: 72px;
+      top: 77px;
     }
 
     &:nth-child(5) {

+ 451 - 28
src/views/vent/monitorManager/hsqHome/components/DeviceLeft.vue

@@ -1,158 +1,350 @@
+<!-- 设备列表组件(左侧面板):展示光谱摄像机设备列表,支持搜索、分类导航和设备操作 -->
 <template>
+  <!-- 设备列表主容器 -->
   <div class="long-list">
+    <!-- 列表标题栏:显示标题和设备总数 -->
     <div class="list-title">
       <span>设备列表</span>
       <span style="margin-left: 5px;">{{ count }}</span>
     </div>
+
+    <!-- 列表内容区域:包含搜索框、导航栏和设备卡片 -->
     <div class="list-content">
+      <!-- 搜索框区域:支持按设备编号或名称搜索 -->
       <div class="list-search">
         <a-input v-model:value="searchData" placeholder="搜索设备编号,名称" size="small" />
       </div>
+
+      <!-- 内容容器:包含分类导航和设备列表 -->
       <div class="content-container">
+        <!-- 分类导航栏:支持不同类型设备的切换(当前仅支持光谱摄像机) -->
         <div class="content-nav">
+          <!-- 导航项:动态绑定激活状态样式,点击触发切换事件 -->
           <div :class="activeIndex == index ? 'nav-item-active' : 'nav-item'" v-for="(item, index) in navList"
-            :key="index" @click="changeNav(item, index)">{{ item.label }}</div>
+            :key="index" @click="changeNav(item, index)">
+            {{ item.label }}
+          </div>
         </div>
+
+        <!-- 设备列表容器:可滚动区域显示所有设备卡片 -->
         <div class="content-box">
-          <basicDevice v-for="(item, index) in listData" :key="index" :deviceData="item" @detail="handlerDetail">
-          </basicDevice>
+          <!-- 单个设备卡片:遍历listData数组渲染每个设备的信息 -->
+          <div class="basic-device" v-for="(item, index) in listData" :key="index">
+            <!-- 左侧状态指示器区域 -->
+            <div class="icon-left">
+              <!-- 状态指示圆点:根据报警级别显示不同颜色(绿色正常/红色报警) -->
+              <div :class="item.syswarnLevel ? 'icon-item-warn' : 'icon-item'"></div>
+            </div>
+
+            <!-- 设备标题区域:包含序列号和操作按钮 -->
+            <div class="basic-title">
+              <!-- 设备序列号显示 -->
+              <div class="title-text">{{ item.strserno || '-' }}</div>
+              <!-- 操作按钮组:详情、配置、重启三种操作 -->
+              <div class="title-btn">
+                <div :class="active == index ? 'btn-active' : 'btn'" @click="handlerClick('detail', item, index)">详情
+                </div>
+                <div class="btn" @click="handlerClick('config', item, index)">配置</div>
+                <div class="btn" @click="handlerClick('restart', item, index)">重启</div>
+              </div>
+            </div>
+
+            <!-- 设备详细信息区域:2x2网格布局展示关键信息 -->
+            <div class="basic-content">
+              <!-- 第一行左:设备名称 -->
+              <div class="content-item">{{ item.strname || '-' }}</div>
+              <!-- 第一行右:运行状态(带状态图标) -->
+              <div class="content-item">
+                <span class="icon-pie">
+                  <span class="pie-item"></span>
+                </span>
+                <span>{{ item.syswarnLevel ? '报警' : '正常' }}</span>
+              </div>
+              <!-- 第二行左:安装位置 -->
+              <div class="content-item">{{ item.strinstallpos || '-' }}</div>
+              <!-- 第二行右:温度数据 -->
+              <div class="content-item">
+                <span>{{ item.readData.temperature || '-' }}</span>
+                <span>℃</span>
+              </div>
+            </div>
+          </div>
         </div>
       </div>
     </div>
-
   </div>
 </template>
 
 <script setup lang="ts">
+// 导入Vue 3组合式API:生命周期钩子和响应式数据工具
 import { onMounted, onUnmounted, ref } from 'vue'
-import basicDevice from './basicDevice.vue'
+// 导入API接口函数:管理系统列表查询、系统监控数据获取
 import { managesysList, monitorSystem } from '../hsqHome.api.js'
 
-//场景ID
-let systemId = ref('')
-//设备列表数量
-let count = ref(0)
-//搜索条件
-let searchData = ref('')
-//当前激活nav选项
-let activeIndex = ref(0)
-let navList = ref<any[]>([
+let active = ref(0)
+/** 响应式数据:当前场景/系统的唯一标识ID,用于API请求参数 */
+const systemId = ref('')
+
+/** 响应式数据:设备列表总数,显示在标题栏中 */
+const count = ref(0)
+
+/** 响应式数据:搜索框的绑定值,用于过滤设备(当前未实现过滤逻辑) */
+const searchData = ref('')
+
+/** 响应式数据:当前激活的导航项索引,用于控制导航栏高亮状态 */
+const activeIndex = ref(0)
+
+/** 响应式数据:导航栏配置数组,定义可切换的设备类型分类 */
+const navList = ref<any[]>([
   { label: '光谱摄像机', value: '0' },
 ])
-let listData = ref<any[]>([])
-let $emit = defineEmits(['details'])
-// https获取监测数据
+
+/** 响应式数据:设备列表数据源,存储从后端获取的所有设备信息 */
+const listData = ref<any[]>([])
+
+/** 定义组件事件:向父组件传递details事件,用于通信选中设备的操作类型和数据 */
+const $emit = defineEmits(['details'])
+
+/** 定时器变量:用于存储定时获取数据的定时器ID,便于在组件卸载时清理 */
 let timer: null | NodeJS.Timeout = null;
 
 /**
- * 定时获取监测数据
- * 通过定时器循环调用数据获取方法,更新表格数据
+ * 定时轮询获取监测数据的核心函数
+ * 通过递归调用setTimeout实现每30秒自动刷新一次设备数据
+ * 采用异步方式避免阻塞主线程,确保UI响应流畅
  *
- * @param flag - 是否立即执行(首次调用时传true跳过延时)
+ * @param flag - 可选参数,控制是否立即执行
+ *   - true(首次调用):立即执行,不等待延时
+ *   - false/undefined(后续调用):等待30秒后执行
  */
-function getMonitor(flag?: boolean) {
+async function getMonitor(flag?: boolean) {
+  // 设置定时器:根据flag决定是否立即执行
   timer = setTimeout(async () => {
+    // 调用数据获取接口,await确保数据加载完成后再继续
     await getData()
+    // 清空定时器引用,防止内存泄漏
     if (timer) {
       timer = null;
     }
+    // 递归调用自身,形成定时轮询机制
     getMonitor();
-  }, flag ? 0 : 30000);
+  }, flag ? 0 : 30000); // 首次立即执行,之后每隔30秒执行一次
 }
 
-//nav选项切换
-function changeNav(item, index) {
+/**
+ * 导航栏切换处理函数
+ * 当用户点击不同的设备类型标签时触发,更新当前激活的导航索引
+ * (当前实现仅更新UI状态,未实现实际的数据筛选逻辑)
+ *
+ * @param item - 被点击的导航项对象,包含label和value属性
+ * @param index - 被点击导航项在navList数组中的索引位置
+ */
+function changeNav(item: any, index: number) {
+  // 更新激活状态索引,触发导航栏样式重新渲染
   activeIndex.value = index
 }
 
+/**
+ * 设备操作按钮点击事件处理函数
+ * 统一处理详情、配置、重启三种操作按钮的点击事件
+ * 将操作类型和设备数据封装成事件对象传递给父组件
+ *
+ * @param type - 操作类型字符串
+ *   - 'detail': 查看设备详细信息
+ *   - 'config': 查看或修改设备配置
+ *   - 'restart': 执行设备重启操作
+ * @param item - 被操作的目标设备完整数据对象
+ */
+function handlerClick(type: string, item: any, index: number) {
+  // 触发details事件,将操作类型和设备数据传递给父组件(deviceManger.vue)
+  $emit('details', { type: type, value: item })
+  active.value = index
+}
+
+/**
+ * 异步获取设备监控数据的API调用函数
+ * 向后端请求指定系统的所有光谱摄像机设备信息
+ * 成功后将设备列表数据和数量分别赋值给对应的响应式变量
+ */
 async function getData() {
+  // 调用监控系统API,传入查询参数:
+  // - type: 'all' 表示获取全部设备
+  // - systemId: 当前系统ID(从getManagesysList获取)
+  // - devicetype: '' 空字符串表示不限制设备类型
   const res = await monitorSystem({ type: 'all', systemID: systemId.value, devicetype: '' });
+
+  // 控制台输出调试信息,便于开发阶段排查问题
   console.log(res, '设备列表数据')
+
+  // 提取光谱摄像机设备列表数据,使用空数组作为默认值防止undefined错误
   listData.value = res.deviceInfo.duaSpeCamera.datalist || [];
-  count.value = res.deviceInfo.duaSpeCamera.datalist.length;
-}
 
-function handlerDetail(item) {
-  $emit('details', item)
+  // 统计并记录设备总数量,用于标题栏显示
+  count.value = res.deviceInfo.duaSpeCamera.datalist.length;
+  // 初始化时,默认选中第一个设备
+  active.value = 0
+  handlerClick('detail', listData.value[0], 0)
 }
 
+/**
+ * 异步获取管理系统列表的初始化函数
+ * 在组件挂载时首先调用此函数,获取当前用户有权限访问的系统列表
+ * 从返回结果中提取第一个系统的ID作为后续数据查询的基础参数
+ *
+ * API参数说明:
+ * - strtype: 'sys_openair_fire' 系统类型标识(开放空间火灾监测)
+ * - pagetype: 'normal' 页面类型(普通页面模式)
+ */
 async function getManagesysList() {
+  // 调用管理系统列表API,传入系统类型和页面类型参数
   const res = await managesysList({ strtype: 'sys_openair_fire', pagetype: 'normal' });
+
+  // 安全检查:确保返回数据存在且包含records数组
   if (res && res.records) {
+    // 取第一个系统的ID作为当前工作系统ID(通常用户只关注一个主要系统)
     systemId.value = res.records[0].id
   }
 }
+
+
+/**
+ * 组件挂载完成后的生命周期钩子
+ * 执行组件初始化流程:
+ * 1. 先获取系统ID(必须先于数据获取,因为systemId是getData的必要参数)
+ * 2. 然后启动定时数据刷新机制(传true表示首次立即执行)
+ */
 onMounted(async () => {
+  // 等待系统ID获取完成,确保后续API调用有正确的参数
   await getManagesysList()
+  // 启动定时监控,true表示首次立即执行一次
   getMonitor(true)
 })
+
+/**
+ * 组件卸载前的生命周期钩子
+ * 执行资源清理工作,主要是清除定时器以防止内存泄漏
+ * 如果不清除,即使组件已销毁,定时器仍会继续运行并尝试更新已不存在的响应式数据
+ */
 onUnmounted(() => {
+  // 检查定时器是否存在,存在则清除
   if (timer) {
     clearTimeout(timer)
   }
 })
 </script>
+<!-- 样式部分:使用Less预处理器,scoped限制样式作用域仅作用于当前组件 -->
 <style lang="less" scoped>
+// 导入全局主题配置文件,包含颜色变量、主题切换等样式定义
 @import '/@/design/theme.less';
 
+/* 深蓝主题模式下的设备列表样式覆盖(预留扩展) */
 @{theme-deepblue} {
   .long-list {}
 }
 
+/* 设备列表主容器:左侧面板的根元素 */
 .long-list {
+  /* ==================== CSS自定义属性:背景图片资源定义 ==================== */
+  /* 列表标题栏背景图 */
   --image-box-bg: url('@/assets/images/home-container/configurable/hsq/2-5.png');
+  /* 搜索输入框背景图 */
   --image-box-bg1: url('@/assets/images/home-container/configurable/hsq/2-6.png');
+  /* (预留)其他UI元素背景图 */
   --image-box-bg2: url('@/assets/images/home-container/configurable/hsq/2-2.png');
+  /* 设备卡片背景图 */
+  --image-box-bg3: url('@/assets/images/home-container/configurable/hsq/2-7.png');
+  /* 状态指示器外框背景图 */
+  --image-box-bg4: url('@/assets/images/home-container/configurable/hsq/2-8.png');
+  /* 设备标题区域背景图 */
+  --image-box-bg5: url('@/assets/images/home-container/configurable/hsq/2-9.png');
 
+  /* 基础布局样式 */
   position: relative;
+  /* 相对定位:作为内部绝对定位元素的参考容器 */
   width: 100%;
+  /* 宽度撑满父容器(由deviceManger.vue的430px宽度约束) */
   height: 100%;
+  /* 高度撑满父容器 */
   padding: 15px;
+  /* 内边距:内容与容器边缘保持15px间距 */
   box-sizing: border-box;
+  /* 盒模型:padding计入总宽高,避免溢出 */
 
+  /* ========== 标题栏样式:显示"设备列表"文字和数量 ========== */
   .list-title {
     width: 177px;
+    /* 固定宽度:匹配背景图尺寸 */
     height: 30px;
+    /* 固定高度 */
     line-height: 22px;
+    /* 行高:垂直居中文字 */
     padding-left: 16px;
+    /* 左内边距:文字缩进 */
     color: #01fefc;
+    /* 青色字体:科技感配色方案 */
     font-weight: bolder;
+    /* 加粗字体:突出标题重要性 */
     background: var(--image-box-bg) no-repeat;
+    /* 使用标题背景图,不重复平铺 */
     background-size: 100% 100%;
+    /* 背景图完全填充容器 */
     margin-bottom: 5px;
+    /* 底部间距:与下方内容区分离 */
   }
 
+  /* ========== 内容区主容器:包含搜索框、导航和列表 ========== */
   .list-content {
     width: 100%;
+    /* 宽度撑满 */
     height: calc(100% - 35px);
+    /* 高度计算:总高度减去标题栏高度和间距 */
   }
 
+  /* 搜索框容器 */
   .list-search {
     margin-bottom: 5px;
+    /* 底部间距:与导航栏分离 */
   }
 
+  /* 内容容器:包含导航栏和设备列表 */
   .content-container {
     width: 100%;
+    /* 宽度撑满 */
     height: calc(100% - 47px);
+    /* 高度计算:减去搜索框高度和间距 */
   }
 
+  /* ========== 导航栏样式:设备类型分类标签栏 ========== */
   .content-nav {
     display: flex;
+    /* 弹性布局:导航项水平排列 */
     align-items: center;
+    /* 垂直居中对齐 */
     height: 32px;
+    /* 固定高度 */
     margin: 0px 5px 10px 5px;
+    /* 外边距:上下左右各留间距 */
     background-color: #15517b;
+    /* 深蓝色背景:与整体风格统一 */
   }
 
+  /* 导航项默认状态(未激活) */
   .nav-item {
     display: flex;
+    /* 弹性布局 */
     justify-content: center;
+    /* 水平居中 */
     align-items: center;
+    /* 垂直居中 */
     width: 120px;
+    /* 固定宽度:每个标签等宽 */
     height: 100%;
+    /* 高度撑满父容器 */
     cursor: pointer;
+    /* 鼠标指针:提示可点击交互 */
   }
 
+  /* 导航项激活状态(当前选中) */
   .nav-item-active {
     display: flex;
     justify-content: center;
@@ -161,29 +353,260 @@ onUnmounted(() => {
     height: 100%;
     cursor: pointer;
     background-color: #1d73a8;
+    /* 较亮的蓝色背景:视觉上区分选中状态 */
     border-bottom: 2px solid #36c7ff;
+    /* 底部亮蓝色边框:强化选中指示效果 */
   }
 
+  /* ========== 设备列表滚动容器 ========== */
   .content-box {
     height: calc(100% - 42px);
+    /* 高度计算:减去导航栏高度和间距 */
     overflow-y: auto;
+    /* 垂直方向超出时显示滚动条 */
+  }
+
+  /* ========== 单个设备卡片样式 ========== */
+  .basic-device {
+    position: relative;
+    /* 相对定位:作为内部绝对定位元素的参考 */
+    height: 106px;
+    /* 固定高度:每个卡片统一尺寸 */
+    margin-right: 5px;
+    /* 右侧间距 */
+    background: var(--image-box-bg3) no-repeat;
+    /* 设备卡片背景图 */
+    background-size: 100% 100%;
+    margin-bottom: 10px;
+    /* 卡片之间的垂直间距 */
+
+    /* 左上角状态指示器外框容器 */
+    .icon-left {
+      position: absolute;
+      /* 绝对定位:相对于卡片容器 */
+      left: 0;
+      /* 紧贴左边缘 */
+      top: 0;
+      /* 紧贴顶部边缘 */
+      width: 29px;
+      /* 外框尺寸 */
+      height: 29px;
+      background: var(--image-box-bg4) no-repeat;
+      /* 外框装饰背景图 */
+      background-size: 100% 100%;
+    }
+
+    /* 正常状态圆点(绿色):表示设备运行正常 */
+    .icon-item {
+      position: absolute;
+      /* 绝对定位:相对于.icon-left容器 */
+      left: 50%;
+      /* 水平居中 */
+      top: 50%;
+      /* 垂直居中 */
+      transform: translate(-50%, -50%);
+      /* 偏移自身宽高的50%实现完全居中 */
+      width: 10px;
+      /* 圆点直径 */
+      height: 10px;
+      border-radius: 50%;
+      /* 圆形:border-radius设为50%形成正圆 */
+      background-color: #4fffad;
+      /* 荧光绿:正常状态的视觉暗示 */
+    }
+
+    /* 报警状态圆点(红色):表示设备存在告警 */
+    .icon-item-warn {
+      position: absolute;
+      left: 50%;
+      top: 50%;
+      transform: translate(-50%, -50%);
+      width: 10px;
+      height: 10px;
+      border-radius: 50%;
+      background-color: #ff4d4f;
+      /* 警示红:报警状态的强烈视觉提醒 */
+    }
+
+    /* 设备标题行:显示序列号和操作按钮 */
+    .basic-title {
+      height: 30px;
+      /* 固定高度 */
+      margin: 0px 20px 5px 32px;
+      /* 外边距:避开左侧图标区域 */
+      padding-left: 10px;
+      /* 左内边距:文字缩进 */
+      display: flex;
+      /* 弹性布局:序列号和按钮组两端对齐 */
+      justify-content: space-between;
+      /* 两端对齐:序列号靠左,按钮靠右 */
+      align-items: center;
+      /* 垂直居中 */
+      background: var(--image-box-bg5) no-repeat bottom;
+      /* 标题行底部装饰线 */
+      background-size: 100% auto;
+    }
+
+    /* 操作按钮组容器 */
+    .title-btn {
+      height: 100%;
+      /* 高度撑满父容器 */
+      display: flex;
+      /* 弹性布局:按钮水平排列 */
+      align-items: center;
+      /* 垂直居中 */
+    }
+
+    /* 单个操作按钮样式(详情/配置/重启共用) */
+    .btn {
+      width: 40px;
+      /* 固定宽度 */
+      display: flex;
+      /* 弹性布局 */
+      justify-content: center;
+      /* 文字水平居中 */
+      align-items: center;
+      /* 文字垂直居中 */
+      background-color: #1e7db4;
+      /* 深蓝色按钮背景 */
+      margin: 0px 2px;
+      /* 按钮之间的水平间距 */
+      cursor: pointer;
+      /* 鼠标指针:提示可点击 */
+    }
+
+    .btn-active {
+      width: 40px;
+      /* 固定宽度 */
+      display: flex;
+      /* 弹性布局 */
+      justify-content: center;
+      /* 文字水平居中 */
+      align-items: center;
+      /* 文字垂直居中 */
+      margin: 0px 2px;
+      /* 按钮之间的水平间距 */
+      cursor: pointer;
+      background-color: #1e7db4;
+      /* 深蓝色按钮背景 */
+      border: 1px solid #90cff3;
+    }
+
+    /* 设备详细信息区域:2x2网格布局展示四项关键数据 */
+    .basic-content {
+      display: flex;
+      /* 弹性布局 */
+      flex-wrap: wrap;
+      /* 允许换行:实现网格布局 */
+      height: calc(100% - 30px);
+      /* 高度计算:卡片总高度减去标题行高度 */
+      padding-left: 20px;
+      /* 左内边距:与左侧图标对齐 */
+      padding-bottom: 10px;
+      /* 底部内边距:防止内容贴底 */
+    }
+
+    /* 单个信息项:网格中的单元格 */
+    .content-item {
+      display: flex;
+      /* 弹性布局 */
+      align-items: center;
+      /* 垂直居中对齐 */
+      width: 50%;
+      /* 宽度占一半:每行显示两个项目 */
+      height: calc(50% - 10px);
+      /* 高度占一半减去margin:两行布局 */
+      margin: 5px 0px;
+      /* 垂直间距:行与行之间分隔 */
+      padding-left: 15px;
+      /* 左内边距:文字缩进效果 */
+
+      /* 第一个单元格(设备名称):深蓝色渐变背景 */
+      &:nth-child(1) {
+        background: linear-gradient(to right, #0e5183, transparent);
+        /* 从左到右渐变至透明 */
+      }
+
+      /* 第二个单元格(运行状态):稍浅的蓝色渐变 */
+      &:nth-child(2) {
+        background: linear-gradient(to right, #104974, transparent);
+        /* 与第一行形成层次感 */
+      }
+
+      /* 第三个单元格(安装位置):同第一行的深色调 */
+      &:nth-child(3) {
+        background: linear-gradient(to right, #0e5183, transparent);
+        /* 保持奇偶行交替效果 */
+      }
+
+      /* 第四个单元格(温度数据):同第二行的浅色调 */
+      &:nth-child(4) {
+        background: linear-gradient(to right, #104974, transparent);
+      }
+    }
+
+    /* 状态指示图标(正常状态的圆形标记) */
+    .icon-pie {
+      display: inline-block;
+      /* 行内块级元素:与文字同行显示 */
+      position: relative;
+      /* 相对定位:作为内部绝对定位元素的参考 */
+      width: 12px;
+      /* 外圈直径 */
+      height: 12px;
+      border-radius: 50%;
+      /* 圆形 */
+      background-color: rgba(79, 255, 173, .3);
+      /* 半透明绿色:柔和的外圈效果 */
+      margin-right: 5px;
+      /* 右侧间距:与文字分离 */
+    }
+
+    /* 状态指示图标的内圈实心点 */
+    .pie-item {
+      position: absolute;
+      /* 绝对定位:相对于.icon-pie容器 */
+      left: 50%;
+      /* 水平居中 */
+      top: 50%;
+      /* 垂直居中 */
+      transform: translate(-50%, -50%);
+      /* 居中偏移 */
+      width: 6px;
+      /* 内圈直径:比外圈小,形成环形效果 */
+      height: 6px;
+      border-radius: 50%;
+      /* 圆形 */
+      background-color: rgba(79, 255, 173);
+      /* 实心荧光绿:清晰的中心点 */
+    }
   }
 
+  /* 自定义搜索框样式(覆盖Ant Design默认样式) */
   .zxm-input {
     height: 42px;
+    /* 固定高度 */
     color: #fff;
+    /* 白色文字:在深色背景上清晰可见 */
     background-color: transparent;
+    /* 透明背景:使用自定义背景图 */
     border: none;
+    /* 移除默认边框 */
     background: var(--image-box-bg1) no-repeat;
+    /* 搜索框专用背景图 */
     background-size: 100% 100%;
   }
 
+  /* 小号输入框变体 */
   .zxm-input-sm {
     padding: 0px 20px;
+    /* 左右内边距:文字不紧贴边缘 */
   }
 
+  /* 隐藏原生滚动条:使用自定义滚动体验或完全隐藏 */
   ::-webkit-scrollbar {
     display: none;
+    /* 隐藏WebKit内核浏览器的滚动条 */
   }
 }
 </style>

+ 6 - 1
src/views/vent/monitorManager/hsqHome/components/EnvironmentMonitor.vue

@@ -17,7 +17,7 @@ let props = defineProps({
   option: {
     type: Array as any
   },
- environData: {
+  environData: {
     type: Object,
     default: () => {
       return {}
@@ -64,5 +64,10 @@ let props = defineProps({
     font-family: 'douyuFont';
     color: #3df6ff;
   }
+
+}
+
+::-webkit-scrollbar {
+  display: none;
 }
 </style>

+ 19 - 5
src/views/vent/monitorManager/hsqHome/components/QuickAction.vue

@@ -72,7 +72,7 @@ let props = defineProps({
 
   .nav-box {
     position: relative;
-    width: 327px;
+    width: 315px;
     height: 35px;
     display: flex;
     align-items: center;
@@ -139,7 +139,7 @@ let props = defineProps({
 
   .card-box {
     position: relative;
-    width: 327px;
+    width: 315px;
     height: 50px;
     display: flex;
     justify-content: space-between;
@@ -147,13 +147,27 @@ let props = defineProps({
 
     .card-box-text {
       display: flex;
-      justify-content: center;
-      align-items: center;
-      width: 126px;
+      // width: 126px;
+      flex: 1;
       height: 50px;
       background: var(--image-card-bg2) no-repeat;
       background-size: 100% 100%;
       cursor: pointer;
+
+      &:nth-child(1) {
+        justify-content: flex-start;
+        align-items: center;
+      }
+
+      &:nth-child(2) {
+        justify-content: center;
+        align-items: center;
+      }
+
+      &:nth-child(3) {
+        justify-content: flex-end;
+        align-items: center;
+      }
     }
   }
 }

+ 1 - 1
src/views/vent/monitorManager/hsqHome/components/WarnCenTop.vue

@@ -33,7 +33,7 @@
                   102 ? '一般风险' :
                   warnData.alarmLevel == 103 ? '较大风险' : warnData.alarmLevel == 104 ? '重大风险' : warnData.alarmLevel == 201 ?
                     '报警' :
-                '低风险' }}</div>
+                '-' }}</div>
             </div>
             <div class="warn-item">
               <div class="item-label">报警时间 : </div>

+ 27 - 7
src/views/vent/monitorManager/hsqHome/components/WarnLeftTop.vue

@@ -35,10 +35,10 @@
               item[ite.value] === 0 ? '未处理' : '已处理' }}</div>
             <!-- 操作列:点击"详情"触发详情查看 -->
             <div v-if="ite.value == 'operation'">
-              <span class="text-look" @click="handlerDetail(item)">详情</span>
+              <span :class="activeIndex == index ? 'text-look-active' : 'text-look'"
+                @click="handlerDetail(item, index)">详情</span>
             </div>
           </div>
-
         </div>
       </div>
     </div>
@@ -46,7 +46,7 @@
 </template>
 
 <script setup lang="ts">
-import { ref, type PropType } from 'vue'
+import { onMounted, ref, watch, type PropType } from 'vue'
 import { warnTitle } from '../hsqHome.data'
 
 // 接收父组件传入的报警数据列表
@@ -56,15 +56,24 @@ let props = defineProps({
     default: () => [],
   },
 })
+
+let activeIndex = ref(0)
 // 报警搜索关键词
 let searchWarn = ref('')
 // 定义事件:detail - 查看报警详情
 let $emit = defineEmits(['detail'])
 
 // 点击"详情"按钮,向父组件派发 detail 事件并传递当前行数据
-function handlerDetail(item: any) {
+function handlerDetail(item: any, index: number) {
+  activeIndex.value = index
   $emit('detail', item)
 }
+
+watch(() => props.tableData, (newVal) => {
+  if (newVal.length > 0) {
+    handlerDetail(newVal[0], 0)
+  }
+}, { immediate: true })
 </script>
 <style lang="less" scoped>
 @import '/@/design/theme.less';
@@ -169,7 +178,9 @@ function handlerDetail(item: any) {
   display: flex;
   justify-content: space-between;
   align-items: center;
-  height: 36px;
+  //height: 36px;
+  padding: 4px 0px;
+  box-sizing: border-box;
 
   &:nth-child(odd) {
     background-color: #0e3455;
@@ -211,10 +222,19 @@ function handlerDetail(item: any) {
 
 /* "详情"操作按钮样式 */
 .text-look {
-  padding: 0px 3px;
-  margin: 0px 2px;
+  padding: 2px 8px;
+  // margin: 0px 2px;
+  border-radius: 2px;
+  background-color: #2484bc;
+  cursor: pointer;
+}
+
+.text-look-active {
+  padding: 2px 8px;
+  // margin: 0px 2px;
   border-radius: 2px;
   background-color: #2484bc;
+  border: 1px solid #90cff3;
   cursor: pointer;
 }
 

+ 0 - 169
src/views/vent/monitorManager/hsqHome/components/basicDevice.vue

@@ -1,169 +0,0 @@
-<template>
-  <div class="basic-device">
-    <div class="icon-left">
-      <div class="icon-item"></div>
-    </div>
-    <div class="basic-title">
-      <div class="title-text">{{deviceData.strserno || '-' }}</div>
-      <div class="title-btn">
-        <div class="btn" @click="handlerClick('detail')">详情</div>
-        <div class="btn" @click="handlerClick('config')">配置</div>
-        <div class="btn" @click="handlerClick('restart')">重启</div>
-      </div>
-    </div>
-    <div class="basic-content">
-      <div class="content-item">{{deviceData.strname || '-' }}</div>
-      <div class="content-item">
-        <span class="icon-pie">
-          <span class="pie-item"></span>
-        </span>
-        <span>{{deviceData.syswarnLevel ? '报警' : '正常' }}</span>
-      </div>
-      <div class="content-item">{{deviceData.strinstallpos || '-' }}</div>
-      <div class="content-item">
-        <span>{{deviceData.readData.temperature || '-'}}</span>
-        <span>℃</span>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script setup lang="ts">
-import { ref } from 'vue'
-
-let props = defineProps({
-  deviceData: {
-    type: Object,
-    required: true
-  }
-})
-
-let $emit=defineEmits(['detail'])
-
-function handlerClick(type) {
-  $emit('detail', {type:type,value:props.deviceData})
-}
-
-</script>
-
-<style lang="less" scoped>
-@import '/@/design/theme.less';
-
-@{theme-deepblue} {
-  .basic-device {}
-}
-
-.basic-device {
-  --image-box-bg: url('@/assets/images/home-container/configurable/hsq/2-7.png');
-  --image-box-bg1: url('@/assets/images/home-container/configurable/hsq/2-8.png');
-  --image-box-bg2: url('@/assets/images/home-container/configurable/hsq/2-9.png');
-  position: relative;
-  height: 106px;
-  margin-right: 5px;
-  background: var(--image-box-bg) no-repeat;
-  background-size: 100% 100%;
-  margin-bottom: 10px;
-
-  .icon-left {
-    position: absolute;
-    left: 0;
-    top: 0;
-    width: 29px;
-    height: 29px;
-    background: var(--image-box-bg1) no-repeat;
-    background-size: 100% 100%;
-  }
-
-  .icon-item {
-    position: absolute;
-    left: 50%;
-    top: 50%;
-    transform: translate(-50%, -50%);
-    width: 10px;
-    height: 10px;
-    border-radius: 50%;
-    background-color: #4fffad;
-  }
-
-  .basic-title {
-    height: 30px;
-    margin: 0px 20px 5px 32px;
-    padding-left: 10px;
-    display: flex;
-    justify-content: space-between;
-    align-items: center;
-    background: var(--image-box-bg2) no-repeat bottom;
-    background-size: 100% auto;
-  }
-
-  .title-btn {
-    height: 100%;
-    display: flex;
-    align-items: center;
-  }
-
-  .btn {
-    width: 40px;
-    display: flex;
-    justify-content: center;
-    align-items: center;
-    background-color: #1e7db4;
-    margin: 0px 2px;
-    cursor: pointer;
-  }
-
-  .basic-content {
-    display: flex;
-    flex-wrap: wrap;
-    height: calc(100% - 30px);
-    padding-left: 20px;
-    padding-bottom: 10px;
-  }
-
-  .content-item {
-    display: flex;
-    align-items: center;
-    width: 50%;
-    height: calc(50% - 10px);
-    margin: 5px 0px;
-    padding-left: 15px;
-
-    &:nth-child(1) {
-      background: linear-gradient(to right, #0e5183, transparent);
-    }
-
-    &:nth-child(2) {
-      background: linear-gradient(to right, #104974, transparent);
-    }
-
-    &:nth-child(3) {
-      background: linear-gradient(to right, #0e5183, transparent);
-    }
-
-    &:nth-child(4) {
-      background: linear-gradient(to right, #104974, transparent);
-    }
-  }
-
-  .icon-pie {
-    display: inline-block;
-    position: relative;
-    width: 12px;
-    height: 12px;
-    border-radius: 50%;
-    background-color: rgba(79, 255, 173, .3);
-    margin-right: 5px;
-  }
-
-  .pie-item {
-    position: absolute;
-    left: 50%;
-    top: 50%;
-    transform: translate(-50%, -50%);
-    width: 6px;
-    height: 6px;
-    border-radius: 50%;
-    background-color: rgba(79, 255, 173);
-  }
-}
-</style>

+ 76 - 7
src/views/vent/monitorManager/hsqHome/deviceManger.vue

@@ -1,39 +1,60 @@
+<!-- 设备管理器主组件:三栏布局展示设备列表、设备详情和配置信息 -->
 <template>
   <div class="device-manger">
+    <!-- 左侧区域:设备列表 -->
     <div class="basic-box">
+      <!-- DeviceLeft组件:显示设备列表,通过details事件传递选中的设备详情 -->
       <DeviceLeft @details="handlerDetail"></DeviceLeft>
     </div>
+    <!-- 中间区域:设备详细信息展示 -->
     <div class="basic-box">
+      <!-- DeviceCenter组件:接收并展示选中设备的详细数据 -->
       <DeviceCenter :detailData="detailData"></DeviceCenter>
     </div>
+    <!-- 右侧区域:设备配置信息展示 -->
     <div class="basic-box">
+      <!-- DeviceRight组件:接收并展示设备的配置数据 -->
       <DeviceRight :detailData="configData"></DeviceRight>
     </div>
   </div>
 </template>
 <script lang="ts" setup>
+// 导入Vue 3组合式API相关函数和响应式工具
 import { onMounted, onUnmounted, ref, computed, nextTick, onBeforeMount, watch, reactive } from 'vue';
+// 导入子组件:左侧设备列表、中间设备详情、右侧配置信息
 import DeviceLeft from './components/DeviceLeft.vue'
 import DeviceCenter from './components/DeviceCenter.vue'
 import DeviceRight from './components/DeviceRight.vue'
 
-// 设备详情
-let strserno = ref<any>({})
-let detailData = ref<any>({})
-// 配置详情
-let configData = ref<any>({})
+// 设备序列号信息(暂未使用)
+const strserno = ref<any>({})
 
+// 响应式数据:存储选中设备的详细信息,传递给DeviceCenter组件展示
+const detailData = ref<any>({})
 
+// 响应式数据:存储设备的配置信息,传递给DeviceRight组件展示(包括普通配置和重启配置)
+const configData = ref<any>({})
 
+
+/**
+ * 处理设备详情事件回调函数
+ * @param item - 包含type和value的事件对象
+ *   - type: 事件类型 ('detail' | 'config' | 'restart')
+ *   - value: 对应的详细数据
+ * 根据不同的类型将数据分配到对应的响应式变量中
+ */
 function handlerDetail(item: any) {
   console.log(item, '详情--handlerDetail')
   switch (item.type) {
+    // 处理设备详情类型:更新中间区域的设备详细数据
     case 'detail':
       detailData.value = item.value
       break
+    // 处理配置详情类型:更新右侧区域的配置数据
     case 'config':
       configData.value = item.value
       break
+    // 处理重启配置类型:更新右侧区域的配置数据(用于重启操作)
     case 'restart':
       configData.value = item.value
       break
@@ -41,68 +62,116 @@ function handlerDetail(item: any) {
     // 其他 cases 待添加
   }
 }
-/** 初始化页面数据(当前已注释,包含获取配置、系统接口数据及监控信息的逻辑) */
+
+/**
+ * 组件挂载完成后的生命周期钩子
+ * 用于初始化页面数据,包括:
+ * - 获取设备配置信息
+ * - 调用系统接口获取基础数据
+ * - 加载监控相关信息
+ * (当前为空实现,待后续完善业务逻辑)
+ */
 onMounted(() => {
 
 });
 
+/**
+ * 组件卸载前的生命周期钩子
+ * 用于清理资源、移除事件监听器等收尾工作
+ * (当前为空实现,待后续根据实际需求添加清理逻辑)
+ */
 onUnmounted(() => {
 
 });
 </script>
 
+<!-- 样式部分:使用Less预处理器,scoped限制样式作用域 -->
 <style lang="less" scoped>
+// 导入主题配置文件,包含全局样式变量和主题定义
 @import '/@/design/theme.less';
 
+/* 深蓝主题模式下的设备管理器样式覆盖 */
 @{theme-deepblue} {
   .device-manger {}
 }
 
+/* 设备管理器主容器:采用三栏弹性布局 */
 .device-manger {
+  /* CSS自定义属性:左侧和右侧区域的背景图片 */
   --image-box1-bg: url('@/assets/images/home-container/configurable/hsq/2-4.png');
+  /* CSS自定义属性:中间区域(设备详情)的背景图片 */
   --image-box1-bg1: url('@/assets/images/home-container/configurable/hsq/2-10.png');
+
+  /* 弹性布局:子元素水平排列 */
   display: flex;
+  /* 子元素两端对齐,均匀分布 */
   justify-content: space-between;
+  /* 容器宽度占满父元素 */
   width: 100%;
+  /* 高度减去底部间距 */
   height: calc(100% - 10px);
+  /* 文字颜色为白色 */
   color: @white;
+  /* 相对定位:作为中间绝对定位元素的参考容器 */
   position: relative;
+  /* 底部外边距 */
   margin-bottom: 10px;
+  /* 深蓝色背景色 */
   background-color: #09172c;
 
+  /* 基础盒子样式:三个栏目的通用容器 */
   .basic-box {
+    /* 第一个子元素(左侧设备列表区域) */
     &:nth-child(1) {
+      /* 固定宽度430px */
       width: 430px;
+      /* 高度撑满父容器 */
       height: 100%;
+      /* 使用CSS变量设置背景图,不重复显示 */
       background: var(--image-box1-bg) no-repeat;
+      /* 背景图完全填充容器 */
       background-size: 100% 100%;
+      /* 右侧外边距,与中间区域保持间距 */
       margin-right: 10px;
     }
 
+    /* 第二个子元素(中间设备详情区域) */
     &:nth-child(2) {
+      /* 绝对定位:相对于父容器定位 */
       position: absolute;
+      /* 距离顶部63px(为标题栏预留空间) */
       top: 63px;
+      /* 水平居中定位 */
       left: 50%;
+      /* 通过transform实现真正的水平居中 */
       transform: translate(-50%, 0);
+      /* 宽度计算:总宽度减去左右两侧的宽度(430*2=880) */
       width: calc(100% - 880px);
+      /* 高度计算:总高度减去顶部偏移量 */
       height: calc(100% - 63px);
+      /* 使用中间区域的专用背景图 */
       background: var(--image-box1-bg1) no-repeat;
       background-size: 100% 100%;
     }
 
+    /* 第三个子元素(右侧配置信息区域) */
     &:nth-child(3) {
+      /* 固定宽度430px,与左侧对称 */
       width: 430px;
       height: 100%;
+      /* 使用与左侧相同的背景图 */
       background: var(--image-box1-bg) no-repeat;
       background-size: 100% 100%;
+      /* 左侧外边距,与中间区域保持间距 */
       margin-left: 10px;
     }
   }
 }
 
 
-
+/* 深度选择器:穿透组件边界修改loading组件的定位样式 */
 :deep(.loading-box) {
+  /* 重置position为默认值,避免影响布局 */
   position: unset;
 }
 </style>

+ 17 - 7
src/views/vent/monitorManager/hsqHome/fireMonitor.vue

@@ -3,7 +3,7 @@
     <div class="basic-fire-box">
       <div class="box-top">
         <CommonBd title="设备状态总览">
-          <CustomGalleryNew :option="option" :galleryData="galleryData" :tableData="tableData"></CustomGalleryNew>
+          <CustomGalleryNew :option="option" :galleryData="galleryData" ></CustomGalleryNew>
         </CommonBd>
       </div>
       <div class="box-cen">
@@ -20,7 +20,7 @@
     <div class="basic-fire-box1">
       <!-- 模型区域 -->
       <div class="model-box">
-        <dwgViewer />
+        <dwgViewer :devices="tableData"/>
       </div>
       <div class="box1-bot">
         <CommonBd title="快捷操作">
@@ -29,12 +29,12 @@
       </div>
     </div>
     <div class="basic-fire-box">
-      <div class="box-top">
+      <div class="box-top1">
         <CommonBd title="报警监控">
           <AlarmMonitor :option="alarmOption" :cardData="alarmData"></AlarmMonitor>
         </CommonBd>
       </div>
-      <div class="box-cen">
+      <div class="box-cen1">
         <!-- <CommonBd title="区域温度统计">
           <CustomChart :chart-config="chartTempConfig" :chart-data="chartTempData"></CustomChart>
         </CommonBd> -->
@@ -42,7 +42,7 @@
           <CustomChart :chart-config="chartConfig" :chart-data="chartData"></CustomChart>
         </CommonBd>
       </div>
-      <div class="box-bot">
+      <div class="box-bot1">
         <CommonBd title="环境监测数据">
           <EnvironmentMonitor :option="envOption" :environData="envData"></EnvironmentMonitor>
         </CommonBd>
@@ -246,18 +246,28 @@ onUnmounted(() => {
   }
 
   .box-top {
-    height: 360px;
+    height: 185px;
     margin-bottom: 10px;
 
   }
+  .box-top1 {
+    height: 360px;
+    margin-bottom: 10px;
+  }
 
   .box-cen {
+    height: 310px;
+    margin-bottom: 10px;
+  }
+  .box-cen1 {
     height: 220px;
     margin-bottom: 10px;
-
   }
 
   .box-bot {
+    height: 335px;
+  }
+  .box-bot1 {
     height: 250px;
   }
 

+ 28 - 17
src/views/vent/monitorManager/hsqHome/systemManger.vue

@@ -1,5 +1,7 @@
+<!-- 系统管理首页:用户列表、角色统计、登录/浏览日志 -->
 <template>
   <div class="system-manger">
+    <!-- 上部区域:用户列表 + 角色用户数量统计 -->
     <div class="basic-top-box">
       <div class="system-box-t">
         <SystemLeftTop :option="optionUser" :data="listData"></SystemLeftTop>
@@ -8,15 +10,13 @@
         <SystemRightTop :userInfo="userInfo"></SystemRightTop>
       </div>
     </div>
+    <!-- 下部区域:登录日志、浏览日志 -->
     <div class="basic-bot-box">
       <div class="system-box-b">
-        <!-- <SystemLeftBottom :btnOption="logbtnOption" :titleOption="titleOption" :data="logList" @changeTab="changeTab">
-        </SystemLeftBottom> -->
         <SystemLeftBottom title="登录日志"  :titleOption="titleOption" :data="logList" >
         </SystemLeftBottom>
       </div>
       <div class="system-box-b">
-        <!-- <SystemCenBottom :data="dayList"></SystemCenBottom> -->
           <SystemLeftBottom title="浏览日志" :titleOption="titleOption" :data="lookLogList" >
         </SystemLeftBottom>
       </div>
@@ -27,37 +27,43 @@
   </div>
 </template>
 <script lang="ts" setup>
-import { onMounted, onUnmounted, reactive, ref, watch } from 'vue';
+/**
+ * 系统管理页面
+ * 展示用户列表、各角色用户数量、登录日志与浏览日志
+ */
+import { onMounted, ref } from 'vue';
 import SystemLeftTop from './components/SystemLeftTop.vue';
 import SystemRightTop from './components/SystemRightTop.vue';
 import SystemLeftBottom from './components/SystemLeftBottom.vue';
-import SystemCenBottom from './components/SystemCenBottom.vue';
-import SystemRightBot from './components/SystemRightBot.vue';
-import { userList, LongList, getUserLoginStats ,queryRoleAndUserNum} from './hsqHome.api.js'
-import { optionUser, logbtnOption, titleOption } from './hsqHome.data.js'
-import dayjs from 'dayjs';
+import { userList, LongList, queryRoleAndUserNum } from './hsqHome.api.js'
+import { optionUser, titleOption } from './hsqHome.data.js'
 
+/** 用户列表数据,供左上角用户表格展示 */
 let listData = ref([])
-// let logType = ref(1)
+/** 登录日志列表(logType=1) */
 let logList = ref([])
+/** 浏览日志列表(logType=3) */
 let lookLogList = ref([])
 // let searchData = reactive({
 //   dayEnd: dayjs().format('YYYY-MM-DD') ,
 //   dayStart:dayjs().startOf('date').subtract(7, 'day').format('YYYY-MM-DD'),
 // })
-let userInfo=ref<any[]>([])
+/** 角色及对应用户数量,供右上角统计图表展示 */
+let userInfo = ref<any[]>([])
 
-//获取用户列表
+/** 获取用户列表 */
 async function getUserList() {
   let res = await userList({ order: 'desc', pageNo: 1, pageSize: 1000 })
   listData.value = res.records || []
 }
 
-//获取日志列表
+/** 获取登录日志(logType: 1-登录 2-操作 3-浏览) */
 async function getLogList() {
   let res = await LongList({ logType: 1, pageNo: 1, pageSize: 1000 })
   logList.value = res.records || []
 }
+
+/** 获取浏览日志 */
 async function getLookLogList() {
   let res = await LongList({ logType: 3, pageNo: 1, pageSize: 1000 })
   lookLogList.value = res.records || []
@@ -85,11 +91,10 @@ async function getLookLogList() {
 //   console.log(res,'今日统计---')
 //   dayList.value = res.records || []
 // }
-//查询角色和用户数量
+/** 查询各角色下的用户数量,转换为图表所需 { label, value } 格式 */
 async function queryRoleAndUserNumInfo() {
   let res = await queryRoleAndUserNum({})
-  console.log(res,'角色和用户数量---')
-  if(res && res.length){
+  if (res && res.length) {
     userInfo.value = res.map(item => ({
       label: item.roleName,
       value: item.userNum,
@@ -97,11 +102,11 @@ async function queryRoleAndUserNumInfo() {
   }
 }
 
+/** 页面挂载时并行加载全部数据 */
 onMounted(() => {
   getUserList()
   getLogList()
   getLookLogList()
-  // getDayTjList()
   queryRoleAndUserNumInfo()
 });
 
@@ -114,7 +119,9 @@ onMounted(() => {
   .system-manger {}
 }
 
+/* 系统管理页主容器 */
 .system-manger {
+  /* 各区块背景图 CSS 变量 */
   --image-box1-bg: url('@/assets/images/home-container/configurable/hsq/3-2.png');
   --image-box1-bg1: url('@/assets/images/home-container/configurable/hsq/5-3.png');
   --image-box1-bg2: url('@/assets/images/home-container/configurable/hsq/5-4.png');
@@ -128,18 +135,21 @@ onMounted(() => {
   margin-bottom: 10px;
   background-color: #09172c;
 
+  /* 上部:用户列表 + 角色统计,高度自适应剩余空间 */
   .basic-top-box {
     position: relative;
     height: calc(100% - 280px);
     margin-bottom: 10px;
   }
 
+  /* 下部:双列日志区域,固定高度 270px */
   .basic-bot-box {
     display: flex;
     justify-content: space-between;
     height: 270px;
   }
 
+  /* 上部左右两个面板:左侧用户列表(宽),右侧角色统计(430px) */
   .system-box-t {
     &:nth-child(1) {
       position: absolute;
@@ -163,6 +173,7 @@ onMounted(() => {
     }
   }
 
+  /* 下部两个日志面板,各占 50% 宽度 */
   .system-box-b {
     &:nth-child(1) {
       width: calc(50% - 5px);