| 
					
				 | 
			
			
				@@ -1,1231 +1,1972 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 <template> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   <div class="device-management-system"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     <!-- 查询条件区域 --> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    <el-card class="filter-card"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      <el-form :model="queryParams" ref="searchForm" :inline="true" class="search-form"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <el-form-item label="设备ID"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <el-input v-model="queryParams.deviceId" placeholder="请输入设备ID" clearable /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        </el-form-item> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <el-form-item label="设备名称"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <el-input v-model="queryParams.deviceName" placeholder="请输入设备名称" clearable /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        </el-form-item> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    <div class="search-form"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      <el-form :model="queryParams" ref="searchForm" :inline="true"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         <el-form-item label="设备类型"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <el-select v-model="queryParams.deviceType" placeholder="请选择设备类型" clearable style="width: 180px;"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-option label="全部" value="" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-option label="控制器" value="CONTROLLER" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-option label="传感器" value="SENSOR" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-option label="执行器" value="ACTUATOR" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-option label="广播设备" value="BROADCASTER" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-option label="监控设备" value="MONITOR" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-option label="报警设备" value="ALARM" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-option label="输入设备" value="INPUT" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          <el-select 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              v-model="queryParams.device_type" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              placeholder="请选择设备类型" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              clearable 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              style="width: 240px;" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              @change="handleDeviceTypeChange" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              size="large" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          > 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            <el-option 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                v-for="(label, value) in deviceTypes" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                :key="value" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                :label="`${label}(${value})`" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                :value="value" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           </el-select> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         </el-form-item> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <el-form-item label="楼层"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <el-select v-model="queryParams.floor" placeholder="请选择楼层" clearable style="width: 180px;"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-option label="全部" value="" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-option label="1楼" value="1F" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-option label="2楼" value="2F" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-option label="3楼" value="3F" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-option label="4楼" value="4F" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-option label="5楼" value="5F" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          </el-select> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        <el-form-item> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          <el-button 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              type="primary" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              :icon="Search" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              @click="handleSearch" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              :loading="isLoading" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              size="large" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          > 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            搜索 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          </el-button> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          <el-button 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              :icon="Refresh" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              @click="resetSearch" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              size="large" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          > 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            重置 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          </el-button> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         </el-form-item> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      </el-form> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <el-form-item label="区域"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <el-input v-model="queryParams.area" placeholder="请输入区域" clearable /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        </el-form-item> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    <!-- 数据表格区域 --> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    <div class="table-container"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      <!-- 表格头部 --> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      <div class="table-header"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        <div class="header-left"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          <el-icon class="header-icon"><Monitor /></el-icon> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          <span class="header-title">设备列表</span> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        <div class="header-actions"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          <el-tooltip content="刷新数据" placement="top"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            <el-button 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                size="default" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                :icon="Refresh" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                @click="getList" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                :loading="isLoading" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                circle 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          </el-tooltip> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          <el-tooltip :content="isCardView ? '切换到表格视图' : '切换到卡片视图'" placement="top"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            <el-button 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                type="primary" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                size="default" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                :icon="View" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                @click="toggleTableView" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                circle 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          </el-tooltip> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <el-form-item label="运行状态"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <el-select v-model="queryParams.status" placeholder="请选择运行状态" clearable style="width: 180px;"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-option label="全部" value="" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-option label="正常" value="正常" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-option label="警告" value="警告" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-option label="故障" value="故障" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-option label="离线" value="离线" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          </el-select> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        </el-form-item> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      <!-- 默认空状态 --> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      <div v-if="!queryParams.device_type" class="empty-state"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        <div class="empty-content"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          <div class="empty-icon"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            <el-icon size="120"><Monitor /></el-icon> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          <h3 class="empty-title">欢迎使用设备管理系统</h3> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          <p class="empty-description">请选择设备类型开始查询设备信息</p> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <el-form-item> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <el-button type="primary" :icon="Search" @click="handleSearch">搜索</el-button> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <el-button :icon="Refresh" @click="resetSearch">重置</el-button> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <el-button type="success" :icon="Download" @click="exportData">导出</el-button> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        </el-form-item> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      </el-form> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    </el-card> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    <!-- 统计卡片 --> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    <el-row :gutter="20" class="stats-row"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      <el-col :span="6"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <el-card class="stats-card"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <el-statistic title="设备总数" :value="statsData.total"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <template #prefix> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              <el-icon><Monitor /></el-icon> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            </template> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          </el-statistic> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        </el-card> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      </el-col> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      <el-col :span="6"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <el-card class="stats-card normal"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <el-statistic title="正常运行" :value="statsData.normal"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <template #prefix> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              <el-icon><CircleCheck /></el-icon> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      <!-- 表格视图 --> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      <div v-else-if="!isCardView" class="table-view"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        <el-table 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            :data="deviceList" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            v-loading="isLoading" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            :height="tableHeight" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            style="width: 100%" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            @row-click="handleRowClick" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            empty-text="暂无设备数据" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            border 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            :row-class-name="tableRowClassName" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            highlight-current-row 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        > 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          <el-table-column label="设备名称" width="200" fixed="left"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            <template #default="scope"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              <div class="device-info"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                <div class="device-name"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  <el-link 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      type="primary" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      @click.stop="handleRowClick(scope.row)" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  > 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    {{ scope.row.deviceName }} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  </el-link> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                <div class="device-type">{{ deviceTypes[queryParams.device_type] }}</div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             </template> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          </el-statistic> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        </el-card> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      </el-col> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      <el-col :span="6"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <el-card class="stats-card warning"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <el-statistic title="警告设备" :value="statsData.warning"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <template #prefix> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              <el-icon><Warning /></el-icon> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          </el-table-column> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          <!-- 动态列 --> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          <el-table-column 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              v-for="column in dynamicColumns" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              :key="column.prop" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              :label="column.label" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              :prop="column.prop" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              :width="column.width" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              align="center" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              show-overflow-tooltip 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          > 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            <template #default="scope"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              <div class="cell-content"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                <div 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    :class="['status-indicator', getCellClass(column.prop, scope.row[column.prop])]" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    v-if="column.type === 'status'" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                > 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  <el-tag 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      :type="scope.row[column.prop] === '是' ? 'success' : 'info'" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      size="small" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  > 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    <el-icon v-if="scope.row[column.prop] === '是'"><CircleCheck /></el-icon> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    <el-icon v-else><CircleClose /></el-icon> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    {{ scope.row[column.prop] }} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  </el-tag> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                <div 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    v-else-if="column.type === 'number'" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    :class="['number-display', getNumberClass(column.prop, scope.row[column.prop])]" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                > 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  <span class="number-value">{{ formatNumber(scope.row[column.prop]) }}</span> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  <span class="unit" v-if="column.unit">{{ column.unit }}</span> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                <span v-else class="text-value">{{ scope.row[column.prop] }}</span> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             </template> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          </el-statistic> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        </el-card> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      </el-col> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      <el-col :span="6"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <el-card class="stats-card error"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <el-statistic title="故障设备" :value="statsData.fault"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <template #prefix> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              <el-icon><CircleClose /></el-icon> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          </el-table-column> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          <el-table-column label="操作" width="200" fixed="right" align="center"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            <template #default="scope"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              <el-button 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  type="primary" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  size="small" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  @click.stop="handleView(scope.row)" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  icon="View" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              > 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                详情 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              </el-button> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              <el-button 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  type="success" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  size="small" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  @click.stop="handleViewConfiguration(scope.row)" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  icon="Setting" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              > 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                组态信息 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              </el-button> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             </template> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          </el-statistic> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        </el-card> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      </el-col> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    </el-row> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          </el-table-column> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        </el-table> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    <!-- 数据表格区域 --> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    <el-card class="data-table"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      <template #header> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <div class="card-header"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <span>设备列表</span> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <div class="header-actions"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-button type="primary" size="small" :icon="Plus" @click="handleAdd">新增设备</el-button> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-button size="small" :icon="Refresh" @click="getList" :loading="isLoading">刷新</el-button> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      <!-- 卡片视图 --> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      <div v-else class="card-view"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        <div class="cards-grid"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          <div 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              v-for="device in deviceList" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              :key="device.deviceName" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              class="device-card-wrapper" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          > 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            <el-card class="device-card" @click="handleRowClick(device)"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              <template #header> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                <div class="device-card-header"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  <div class="device-title"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    <div class="device-avatar-large"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      <el-icon class="device-type-icon"><Monitor /></el-icon> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    <div class="device-info"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      <h4 class="device-name">{{ device.deviceName }}</h4> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      <p class="device-type">{{ deviceTypes[queryParams.device_type] }}</p> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  <el-tag 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      :type="getDeviceStatusType(device)" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      size="large" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      effect="dark" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  > 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    {{ getDeviceStatus(device) }} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  </el-tag> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              </template> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              <div class="device-card-content"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                <div class="parameters-grid"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  <div 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      v-for="(value, key) in getCardDisplayData(device)" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      :key="key" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      class="parameter-item" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  > 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    <div class="parameter-label">{{ key }}</div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    <div class="parameter-value" :class="getCellClass(key, value)"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      {{ formatCardValue(key, value) }} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              <template #footer> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                <div class="device-card-actions"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  <el-button 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      type="primary" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      size="default" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      @click.stop="handleView(device)" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  > 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    <el-icon><View /></el-icon> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    查看详情 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  </el-button> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  <el-button 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      type="success" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      size="default" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      @click.stop="handleViewConfiguration(device)" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  > 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    <el-icon><Setting /></el-icon> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    组态信息 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  </el-button> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              </template> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            </el-card> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      </template> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      <el-table 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          :data="deviceList" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          border 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          v-loading="isLoading" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          row-key="deviceId" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          @row-click="handleRowClick" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          :height="tableHeight" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          style="width: 100%" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      > 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <el-table-column type="selection" width="55" align="center" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <el-table-column label="设备ID" prop="deviceId" align="center" width="140" fixed> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <template #default="scope"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-link type="primary" @click.stop="handleRowClick(scope.row)"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              {{ scope.row.deviceId }} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            </el-link> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          </template> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        </el-table-column> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <el-table-column label="设备名称" prop="deviceName" align="center" width="160" show-overflow-tooltip /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <el-table-column label="设备类型" prop="deviceType" align="center" width="120"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <template #default="scope"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-tag :type="getDeviceTypeTag(scope.row.deviceType)"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              {{ mapDeviceType(scope.row.deviceType) }} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            </el-tag> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          </template> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        </el-table-column> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <el-table-column label="型号" prop="model" align="center" width="140" show-overflow-tooltip /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <el-table-column label="安装位置" align="center" min-width="200"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <template #default="scope"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <div class="location-info"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              <el-icon><Location /></el-icon> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              <span>{{ scope.row.floor }}-{{ scope.row.area }}</span> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <div class="location-detail">{{ scope.row.location }}</div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          </template> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        </el-table-column> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <el-table-column label="运行状态" align="center" width="120"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <template #default="scope"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <div class="status-wrapper"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              <span class="status-dot" :class="getStatusClass(scope.row.status)"></span> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              <span>{{ scope.row.status }}</span> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          </template> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        </el-table-column> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <el-table-column label="当前告警" align="center" width="180"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <template #default="scope"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-tooltip v-if="scope.row.alarmCode" :content="scope.row.alarmDescription" placement="top"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              <el-tag type="danger" size="small"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                <el-icon><Warning /></el-icon> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                {{ scope.row.alarmCode }} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              </el-tag> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            </el-tooltip> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <span v-else class="no-alarm">无告警</span> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          </template> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        </el-table-column> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <el-table-column label="最后更新" prop="lastUpdateTime" align="center" width="160"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <template #default="scope"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            {{ formatTime(scope.row.lastUpdateTime) }} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          </template> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        </el-table-column> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <el-table-column label="操作" align="center" width="200" fixed="right"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <template #default="scope"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-button type="primary" link size="small" @click.stop="handleView3D(scope.row)"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              <el-icon><View /></el-icon> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              3D查看 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            </el-button> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-button type="warning" link size="small" @click.stop="handleControl(scope.row)"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              <el-icon><Operation /></el-icon> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              控制 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            </el-button> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-button type="danger" link size="small" @click.stop="handleDelete(scope.row)"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              <el-icon><Delete /></el-icon> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              删除 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            </el-button> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          </template> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        </el-table-column> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      </el-table> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        <div v-if="deviceList.length === 0 && !isLoading" class="empty-result"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          <el-empty description="暂无设备数据"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            <template #image> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              <div class="empty-image"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                <el-icon size="80"><Monitor /></el-icon> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            </template> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          </el-empty> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       <!-- 分页组件 --> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      <el-pagination 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          v-show="total > 0" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          v-model:current-page="queryParams.pageNum" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          v-model:page-size="queryParams.pageSize" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          :page-sizes="[10, 20, 50, 100]" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          :total="total" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          layout="total, sizes, prev, pager, next, jumper" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          @size-change="handleSizeChange" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          @current-change="handlePageChange" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          class="pagination-container" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    </el-card> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    <!-- 详情弹窗 --> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      <div v-show="total > 0" class="pagination-container"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        <el-pagination 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            v-model:current-page="queryParams.pageNum" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            v-model:page-size="queryParams.pageSize" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            :page-sizes="[10, 20, 50, 100]" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            :total="total" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            layout="total, sizes, prev, pager, next, jumper" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            @size-change="handleSizeChange" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            @current-change="handlePageChange" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            background 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    <!-- 设备详情弹窗 --> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     <el-dialog 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         v-model="detailDialogOpen" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         title="设备详情" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         width="900px" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        top="5vh" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         destroy-on-close 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        class="detail-dialog" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     > 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      <el-tabs v-model="activeTab" type="card"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      <div v-if="currentDevice" class="device-detail"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         <!-- 基本信息 --> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <el-tab-pane label="基本信息" name="basic"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <el-descriptions :column="2" border> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-descriptions-item label="设备ID"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              <el-tag>{{ detailDevice.deviceId }}</el-tag> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        <div class="detail-section"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          <h3>基本信息</h3> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          <el-descriptions :column="3" border> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            <el-descriptions-item label="设备名称" :span="2"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              <el-tag type="primary" size="large" effect="dark"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                {{ currentDevice.deviceName }} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              </el-tag> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             </el-descriptions-item> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-descriptions-item label="设备名称">{{ detailDevice.deviceName }}</el-descriptions-item> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             <el-descriptions-item label="设备类型"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              <el-tag :type="getDeviceTypeTag(detailDevice.deviceType)"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                {{ mapDeviceType(detailDevice.deviceType) }} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              </el-tag> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              <span>{{ deviceTypes[queryParams.device_type] || '未知' }}</span> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             </el-descriptions-item> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-descriptions-item label="型号">{{ detailDevice.model }}</el-descriptions-item> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-descriptions-item label="制造商">{{ detailDevice.manufacturer || '未知' }}</el-descriptions-item> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-descriptions-item label="序列号">{{ detailDevice.serialNumber || '未知' }}</el-descriptions-item> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-descriptions-item label="安装位置" :span="2"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              <el-icon><Location /></el-icon> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              {{ detailDevice.floor }}-{{ detailDevice.area }} ({{ detailDevice.location }}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            <el-descriptions-item label="设备状态" :span="3"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              <el-tag :type="getDeviceStatusType(currentDevice)" size="large" effect="dark"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                <el-icon style="margin-right: 4px;"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  <CircleCheck v-if="getDeviceStatus(currentDevice) === '运行中'" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  <Warning v-else-if="getDeviceStatus(currentDevice) === '故障'" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  <Monitor v-else /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                </el-icon> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                {{ getDeviceStatus(currentDevice) }} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              </el-tag> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             </el-descriptions-item> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-descriptions-item label="安装日期">{{ formatDate(detailDevice.installDate) }}</el-descriptions-item> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-descriptions-item label="维保到期">{{ formatDate(detailDevice.maintenanceDate) }}</el-descriptions-item> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           </el-descriptions> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        </el-tab-pane> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <!-- 运行状态 --> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <el-tab-pane label="运行状态" name="status"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <el-row :gutter="20"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-col :span="12"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              <el-card> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                <template #header> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  <span>当前状态</span> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                </template> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                <div class="status-display"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  <div class="status-item"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    <span class="label">运行状态:</span> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    <div class="status-wrapper"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                      <span class="status-dot" :class="getStatusClass(detailDevice.status)"></span> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                      <span>{{ detailDevice.status }}</span> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  <div class="status-item"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    <span class="label">在线状态:</span> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    <el-tag :type="detailDevice.isOnline ? 'success' : 'danger'"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                      {{ detailDevice.isOnline ? '在线' : '离线' }} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    </el-tag> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  <div class="status-item"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    <span class="label">最后更新:</span> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    <span>{{ formatTime(detailDevice.lastUpdateTime) }}</span> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              </el-card> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            </el-col> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-col :span="12"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              <el-card> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                <template #header> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  <span>告警信息</span> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                </template> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                <div v-if="detailDevice.alarmCode" class="alarm-info"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  <el-alert 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                      :title="detailDevice.alarmDescription" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                      type="error" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                      :closable="false" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                      show-icon 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  <div class="alarm-details"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    <div>告警代码: {{ detailDevice.alarmCode }}</div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    <div>触发时间: {{ formatTime(detailDevice.triggerTime) }}</div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    <div>告警级别: {{ detailDevice.alarmLevel || '高' }}</div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                <el-empty v-else description="暂无告警" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              </el-card> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            </el-col> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          </el-row> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        </el-tab-pane> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <!-- 3D模型 --> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <el-tab-pane label="3D模型" name="model"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <div class="model-viewer"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <div class="model-preview" ref="modelContainer"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              <!-- 这里可以集成 Three.js 或其他3D库来显示模型 --> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              <el-empty description="3D模型预览区域"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                <el-button type="primary" @click="load3DModel">加载3D模型</el-button> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              </el-empty> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <div class="model-info"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              <el-descriptions :column="1" border size="small"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                <el-descriptions-item label="模型文件"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  <el-link type="primary" @click="downloadModel"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    {{ detailDevice.modelPath || '暂无模型文件' }} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  </el-link> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                </el-descriptions-item> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                <el-descriptions-item label="动画参数"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  <pre class="json-display">{{ formatJson(detailDevice.animationParams) }}</pre> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                </el-descriptions-item> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              </el-descriptions> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        </el-tab-pane> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <!-- 控制面板 --> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <el-tab-pane label="控制面板" name="control"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <el-card> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-descriptions :column="2" border class="mb-4"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              <el-descriptions-item label="控制协议">{{ detailDevice.controlProtocol }}</el-descriptions-item> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              <el-descriptions-item label="指令集">{{ detailDevice.commandSet }}</el-descriptions-item> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              <el-descriptions-item label="通信地址">{{ detailDevice.commAddress || '192.168.1.100' }}</el-descriptions-item> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              <el-descriptions-item label="通信端口">{{ detailDevice.commPort || '8080' }}</el-descriptions-item> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            </el-descriptions> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <div class="control-panel"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              <h4>快速控制</h4> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              <el-row :gutter="20"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                <el-col :span="8" v-for="cmd in quickCommands" :key="cmd.id"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  <el-button 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                      :type="cmd.type" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                      :icon="cmd.icon" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                      @click="sendCommand(cmd)" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                      :loading="cmd.loading" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                      class="control-btn" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  > 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    {{ cmd.name }} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  </el-button> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                </el-col> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              </el-row> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              <el-divider /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              <h4>参数调节</h4> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              <el-form :model="controlParams" label-width="100px"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                <el-form-item label="运行模式"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  <el-select v-model="controlParams.mode" @change="handleModeChange"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    <el-option label="自动" value="auto" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    <el-option label="手动" value="manual" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    <el-option label="定时" value="timer" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  </el-select> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                </el-form-item> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                <el-form-item label="功率调节"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  <el-slider 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                      v-model="controlParams.power" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                      :min="0" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                      :max="100" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                      :marks="{ 0: '0%', 50: '50%', 100: '100%' }" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                      @change="handlePowerChange" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                </el-form-item> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                <el-form-item label="温度设定" v-if="detailDevice.deviceType === 'CONTROLLER'"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  <el-input-number 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                      v-model="controlParams.temperature" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                      :min="16" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                      :max="30" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                      @change="handleTempChange" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  <span class="unit">°C</span> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                </el-form-item> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              </el-form> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          </el-card> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        </el-tab-pane> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <!-- 历史记录 --> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <el-tab-pane label="历史记录" name="history"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <el-table :data="historyData" border size="small" max-height="400"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-table-column label="时间" prop="time" width="180"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        <!-- 参数表格 --> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        <div class="detail-section"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          <h3>设备参数</h3> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          <el-table 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              :data="getDetailTableData(currentDevice)" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              border 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              max-height="450" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          > 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            <el-table-column label="参数名称" prop="name" width="200"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				               <template #default="scope"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                {{ formatTime(scope.row.time) }} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                <div class="param-name"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  <el-icon class="param-icon"><Setting /></el-icon> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  <span>{{ scope.row.name }}</span> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				               </template> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             </el-table-column> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-table-column label="操作类型" prop="type" width="120"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            <el-table-column label="当前值" prop="value" align="center"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				               <template #default="scope"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                <el-tag :type="getHistoryTypeTag(scope.row.type)" size="small"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  {{ scope.row.type }} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                </el-tag> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                <div class="param-value-cell"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              <span :class="['param-value', getCellClass(scope.row.name, scope.row.value)]"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                {{ formatDetailValue(scope.row.name, scope.row.value) }} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              </span> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  <span v-if="scope.row.unit" class="param-unit">{{ scope.row.unit }}</span> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				               </template> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             </el-table-column> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-table-column label="操作内容" prop="content" show-overflow-tooltip /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-table-column label="操作人" prop="operator" width="120" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-table-column label="结果" prop="result" width="100"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            <el-table-column label="状态" prop="status" width="120" align="center"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				               <template #default="scope"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                <el-tag :type="scope.row.result === '成功' ? 'success' : 'danger'" size="small"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  {{ scope.row.result }} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                <el-tag 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    :type="scope.row.status === '正常' ? 'success' : 'warning'" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    size="default" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    effect="dark" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                > 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  <el-icon style="margin-right: 4px;"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    <CircleCheck v-if="scope.row.status === '正常'" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    <Warning v-else /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  </el-icon> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  {{ scope.row.status }} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 </el-tag> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				               </template> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             </el-table-column> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           </el-table> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        </el-tab-pane> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      </el-tabs> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       <template #footer> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <el-button @click="detailDialogOpen = false">关闭</el-button> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <el-button type="primary" @click="saveDeviceInfo">保存</el-button> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        <div class="dialog-footer"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          <el-button @click="detailDialogOpen = false">关闭</el-button> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       </template> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     </el-dialog> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    <!-- 3D查看弹窗 --> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    <!-- 组态信息弹窗 --> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     <el-dialog 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        v-model="view3DDialogOpen" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        :title="`3D视图 - ${current3DDevice.deviceName}`" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        width="90%" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        top="5vh" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        destroy-on-close 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        v-model="configurationDialogOpen" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        :title="`组态信息 - ${currentConfigDevice?.deviceName || ''}`" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        top="16vh" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     > 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      <div class="three-d-viewer"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <div class="viewer-toolbar"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <el-button-group> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-button @click="resetView" :icon="Refresh">重置视角</el-button> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-button @click="toggleRotation" :icon="rotationEnabled ? VideoPause : VideoPlay"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              {{ rotationEnabled ? '停止' : '开始' }}旋转 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            </el-button> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-button @click="toggleWireframe" :icon="View"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              {{ wireframeMode ? '实体' : '线框' }}模式 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            </el-button> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          </el-button-group> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <el-button type="primary" @click="fullscreen3D" :icon="FullScreen">全屏</el-button> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <div class="viewer-container" ref="viewer3D"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <!-- Three.js 渲染容器 --> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <canvas ref="canvas3D"></canvas> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <div class="viewer-info"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <el-descriptions :column="4" size="small"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-descriptions-item label="设备ID">{{ current3DDevice.deviceId }}</el-descriptions-item> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-descriptions-item label="当前状态"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              <el-tag :type="getStatusTagType(current3DDevice.status)"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                {{ current3DDevice.status }} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              </el-tag> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            </el-descriptions-item> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-descriptions-item label="温度">{{ current3DDevice.temperature || 25 }}°C</el-descriptions-item> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-descriptions-item label="运行时长">{{ current3DDevice.runTime || '120' }}小时</el-descriptions-item> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          </el-descriptions> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      <div class="configuration-iframe-container"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        <iframe 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            v-if="currentVideoUrl" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            :src="currentVideoUrl" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            class="configuration-iframe" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            frameborder="0" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            allowfullscreen 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ></iframe> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    </el-dialog> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    <!-- 控制弹窗 --> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    <el-dialog 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        v-model="controlDialogOpen" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        :title="`设备控制 - ${currentControlDevice.deviceName}`" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        width="600px" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    > 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      <el-alert 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          title="请谨慎操作,错误的控制指令可能导致设备损坏" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          type="warning" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          show-icon 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          :closable="false" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          class="mb-4" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      <el-form :model="remoteControlForm" label-width="120px"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <el-form-item label="控制指令"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <el-select v-model="remoteControlForm.command" placeholder="请选择控制指令"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-option label="开机" value="POWER_ON" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-option label="关机" value="POWER_OFF" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-option label="重启" value="RESTART" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-option label="复位" value="RESET" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-option label="紧急停止" value="EMERGENCY_STOP" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          </el-select> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        </el-form-item> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <el-form-item label="执行延时"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <el-input-number v-model="remoteControlForm.delay" :min="0" :max="60" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <span class="unit">秒</span> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        </el-form-item> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <el-form-item label="备注"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <el-input 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              v-model="remoteControlForm.remark" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              type="textarea" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              :rows="3" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              placeholder="请输入操作备注" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        </el-form-item> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      </el-form> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       <template #footer> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <el-button @click="controlDialogOpen = false">取消</el-button> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <el-button type="primary" @click="executeControl" :loading="controlLoading"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          执行控制 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        </el-button> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        <div class="dialog-footer"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          <el-button @click="configurationDialogOpen = false">关闭</el-button> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          <el-button type="primary" @click="refreshConfiguration"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            <el-icon><Refresh /></el-icon> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            刷新 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          </el-button> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       </template> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     </el-dialog> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 </template> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-<script setup> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import { ref, reactive, computed, onMounted, onUnmounted } from 'vue'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import { ElMessage, ElMessageBox } from 'element-plus'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+<script setup name="BuildingEquipmentMonitoring"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import { ref, reactive, onMounted } from 'vue'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import { ElMessage } from 'element-plus'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   Search, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   Refresh, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  Download, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   Monitor, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   CircleCheck, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  Warning, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   CircleClose, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  Plus, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   View, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  Operation, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  Delete, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  Location, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  VideoPlay, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  VideoPause, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  FullScreen 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Setting, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Warning, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Close 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } from '@element-plus/icons-vue'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import { getBuildingEquipmentMonitoringList } from "@/api/buildingEquipmentMonitoring/buildingEquipmentMonitoring"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// import * as THREE from 'three'; // 如果使用Three.js 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 状态管理 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const queryParams = reactive({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  deviceId: '', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  deviceName: '', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  deviceType: '', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  floor: '', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  area: '', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  status: '', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  pageNum: 1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  pageSize: 10, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  interfaceName: "三维设备监控中心" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import axios from 'axios'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 响应式数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const deviceTypes = ref({}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 const deviceList = ref([]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 const total = ref(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 const isLoading = ref(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 const detailDialogOpen = ref(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const view3DDialogOpen = ref(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const controlDialogOpen = ref(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const detailDevice = ref({}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const current3DDevice = ref({}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const currentControlDevice = ref({}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const activeTab = ref('basic'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const currentDevice = ref({}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const dynamicColumns = ref([]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 const tableHeight = ref(600); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const rotationEnabled = ref(true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const wireframeMode = ref(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const controlLoading = ref(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 统计数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const statsData = computed(() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  const stats = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    total: deviceList.value.length, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    normal: 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    warning: 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    fault: 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  deviceList.value.forEach(device => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (device.status === '正常') stats.normal++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    else if (device.status === '警告') stats.warning++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    else if (device.status === '故障') stats.fault++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const isCardView = ref(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  return stats; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 组态信息相关 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const configurationDialogOpen = ref(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const currentConfigDevice = ref(null); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const currentVideoUrl = ref(''); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 快速控制命令 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const quickCommands = ref([ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  { id: 1, name: '启动', type: 'success', icon: VideoPlay, loading: false }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  { id: 2, name: '停止', type: 'danger', icon: VideoPause, loading: false }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  { id: 3, name: '重启', type: 'warning', icon: Refresh, loading: false } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 控制参数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const controlParams = reactive({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  mode: 'auto', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  power: 50, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  temperature: 25 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 查询参数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const queryParams = reactive({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  pageNum: 1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  pageSize: 10, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  device_type: '' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 远程控制表单 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const remoteControlForm = reactive({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  command: '', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  delay: 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  remark: '' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 生命周期 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+onMounted(() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  loadDeviceTypes(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  calculateTableHeight(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  window.addEventListener('resize', calculateTableHeight); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 历史记录数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const historyData = ref([ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  { time: new Date(), type: '状态变更', content: '设备启动', operator: '系统', result: '成功' }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  { time: new Date(Date.now() - 3600000), type: '参数调整', content: '温度设定从23°C调整到25°C', operator: '张开阳', result: '成功' }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  { time: new Date(Date.now() - 7200000), type: '告警处理', content: '清除温度过高告警', operator: '李中仁', result: '成功' } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 // 计算表格高度 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 const calculateTableHeight = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   const windowHeight = window.innerHeight; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  tableHeight.value = windowHeight - 420; // 考虑统计卡片的高度 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tableHeight.value = windowHeight - 400; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-onMounted(() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  calculateTableHeight(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  window.addEventListener('resize', calculateTableHeight); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  getList(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // 初始化3D场景 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // init3DScene(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-onUnmounted(() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  window.removeEventListener('resize', calculateTableHeight); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // 清理3D资源 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // cleanup3DScene(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 获取数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const getList = async () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  isLoading.value = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 加载设备类型 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const loadDeviceTypes = async () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const response = await getBuildingEquipmentMonitoringList(queryParams); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    let filteredData = response.data.list || []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // 应用过滤条件 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (queryParams.deviceId) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      filteredData = filteredData.filter(item => 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          item.deviceId.toLowerCase().includes(queryParams.deviceId.toLowerCase()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (queryParams.deviceName) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      filteredData = filteredData.filter(item => 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          item.deviceName.toLowerCase().includes(queryParams.deviceName.toLowerCase()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (queryParams.deviceType) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      filteredData = filteredData.filter(item => item.deviceType === queryParams.deviceType); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (queryParams.floor) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      filteredData = filteredData.filter(item => item.floor === queryParams.floor); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const response = await axios.get(`${__LOCAL_API__}/intell/deviceType`); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (response.data.code === 200) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      deviceTypes.value = response.data.data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } catch (error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ElMessage.error('加载设备类型失败'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    console.error(error); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (queryParams.area) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      filteredData = filteredData.filter(item => 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          item.area.toLowerCase().includes(queryParams.area.toLowerCase()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 获取设备列表 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const getList = async () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (!queryParams.device_type) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ElMessage.warning('请先选择设备类型'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (queryParams.status) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      filteredData = filteredData.filter(item => item.status === queryParams.status); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  isLoading.value = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const params = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      pageNum: queryParams.pageNum, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      pageSize: queryParams.pageSize, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      device_type: queryParams.device_type 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const response = await axios.get(`${__LOCAL_API__}/intell/getDevices`, { params }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (response.data.code === 200) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      const { data, total: totalCount } = response.data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      total.value = totalCount; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // 转换数据格式 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      const convertedData = Object.entries(data).map(([deviceName, deviceData]) => ({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        deviceName, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ...deviceData 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      })); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      deviceList.value = convertedData; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      generateDynamicColumns(convertedData); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // 添加额外的模拟数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    filteredData = filteredData.map(item => ({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ...item, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      isOnline: Math.random() > 0.1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      lastUpdateTime: new Date(Date.now() - Math.random() * 3600000), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      temperature: 20 + Math.random() * 10, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      runTime: Math.floor(Math.random() * 1000), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      manufacturer: ['西门子', '施耐德', 'ABB', '霍尼韦尔'][Math.floor(Math.random() * 4)], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      serialNumber: `SN${Date.now().toString().slice(-8)}`, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      installDate: new Date(Date.now() - Math.random() * 365 * 24 * 3600000), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      maintenanceDate: new Date(Date.now() + Math.random() * 365 * 24 * 3600000), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      commAddress: `192.168.1.${Math.floor(Math.random() * 255)}`, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      commPort: 8080 + Math.floor(Math.random() * 100) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    })); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    total.value = filteredData.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // 分页处理 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const start = (queryParams.pageNum - 1) * queryParams.pageSize; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const end = start + queryParams.pageSize; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    deviceList.value = filteredData.slice(start, end); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } catch (error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     ElMessage.error('获取设备数据失败'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    console.error(error); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } finally { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     isLoading.value = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 搜索 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const handleSearch = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  queryParams.pageNum = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  getList(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 获取组态信息 - 简化版本,只设置URL 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const getConfigurationInfo = async (device) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // 构建组态信息URL 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  currentVideoUrl.value = `${__LOCAL_API__}/intell/configurationDiagram?id=${queryParams.device_type}-${device.deviceName}`; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 重置 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const resetSearch = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  Object.keys(queryParams).forEach(key => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (key !== 'pageNum' && key !== 'pageSize' && key !== 'interfaceName') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      queryParams[key] = ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 刷新组态信息 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const refreshConfiguration = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (currentConfigDevice.value && currentVideoUrl.value) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 通过重新设置src来刷新iframe 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const iframe = document.querySelector('.configuration-iframe'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (iframe) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      const currentSrc = iframe.src; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      iframe.src = ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      setTimeout(() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        iframe.src = currentSrc; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }, 100); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  queryParams.pageNum = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  getList(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 分页 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const handlePageChange = (newPage) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  queryParams.pageNum = newPage; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  getList(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 生成动态表格列 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const generateDynamicColumns = (data) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (data.length === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    dynamicColumns.value = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const handleSizeChange = (newSize) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  queryParams.pageSize = newSize; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  queryParams.pageNum = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  getList(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const columns = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const firstDevice = data[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 行点击事件 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const handleRowClick = (row) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  detailDevice.value = JSON.parse(JSON.stringify(row)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  detailDialogOpen.value = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  activeTab.value = 'basic'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Object.keys(firstDevice).forEach(key => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (key === 'deviceName') return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const column = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      prop: key, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      label: key, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      width: getColumnWidth(key), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      type: getColumnType(key), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      unit: getColumnUnit(key) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    columns.push(column); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  dynamicColumns.value = columns; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 新增设备 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const handleAdd = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  ElMessage.info('新增设备功能开发中...'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 获取列宽度 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const getColumnWidth = (columnName) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const widthMap = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    '冬夏季模式': 120, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    '运行状态': 120, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    '自动状态': 120, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    '故障报警': 120, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    '过滤网压差': 120, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    '防冻开关': 120, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    '风机压差': 120, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    '送风温度': 120, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    '回风温度': 120, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    '新风温度': 120, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    '送风湿度': 120, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    '回风二氧化碳': 140, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    '水阀反馈': 120, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    '回风阀反馈': 120, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    '新风阀反馈': 120 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return widthMap[columnName] || 130; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 查看3D 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const handleView3D = (row) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  current3DDevice.value = row; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  view3DDialogOpen.value = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // 初始化3D模型 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  setTimeout(() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    init3DModel(row); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  }, 100); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 获取列类型 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const getColumnType = (columnName) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const statusColumns = ['冬夏季模式', '运行状态', '自动状态', '故障报警', '过滤网压差', '防冻开关', '风机压差']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const numberColumns = ['送风温度', '回风温度', '新风温度', '送风湿度', '回风二氧化碳', '水阀反馈', '回风阀反馈', '新风阀反馈']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (statusColumns.includes(columnName)) return 'status'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (numberColumns.includes(columnName)) return 'number'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return 'text'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 控制设备 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const handleControl = (row) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  currentControlDevice.value = row; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  controlDialogOpen.value = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  remoteControlForm.command = ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  remoteControlForm.delay = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  remoteControlForm.remark = ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 获取列单位 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const getColumnUnit = (columnName) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const unitMap = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    '送风温度': '°C', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    '回风温度': '°C', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    '新风温度': '°C', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    '送风湿度': '%', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    '回风二氧化碳': 'ppm', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    '水阀反馈': '%', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    '回风阀反馈': '%', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    '新风阀反馈': '%' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return unitMap[columnName] || ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 删除设备 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const handleDelete = async (row) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    await ElMessageBox.confirm( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        `确定要删除设备 "${row.deviceName}" 吗?`, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        '删除确认', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          confirmButtonText: '确定', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          cancelButtonText: '取消', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          type: 'warning', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // 模拟删除操作 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ElMessage.success('删除成功'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    getList(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } catch { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ElMessage.info('已取消删除'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 获取单元格样式类 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const getCellClass = (columnName, value) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const type = getColumnType(columnName); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (type === 'status') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return value === '是' ? 'status-active' : 'status-inactive'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (type === 'number') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const numValue = parseFloat(value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (isNaN(numValue)) return 'value-invalid'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (numValue === 0) return 'value-zero'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (columnName.includes('温度') && (numValue < 18 || numValue > 35)) return 'value-warning'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (columnName.includes('湿度') && (numValue < 30 || numValue > 80)) return 'value-warning'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (columnName.includes('反馈') && numValue > 95) return 'value-high'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return 'value-normal'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 导出数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const exportData = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  ElMessage.success('正在导出数据...'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // 实际导出逻辑 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 设备类型映射 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const mapDeviceType = (type) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  const typeMap = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    'CONTROLLER': '控制器', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    'SENSOR': '传感器', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    'ACTUATOR': '执行器', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    'BROADCASTER': '广播设备', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    'MONITOR': '监控设备', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    'ALARM': '报警设备', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    'INPUT': '输入设备', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  return typeMap[type] || type; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 获取数字样式类 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const getNumberClass = (columnName, value) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const numValue = parseFloat(value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (isNaN(numValue)) return 'number-invalid'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (numValue === 0) return 'number-zero'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (numValue > 90) return 'number-high'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return 'number-normal'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 获取设备类型标签样式 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const getDeviceTypeTag = (type) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  const tagMap = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    'CONTROLLER': 'primary', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    'SENSOR': 'success', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    'ACTUATOR': 'warning', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    'BROADCASTER': 'info', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    'MONITOR': '', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    'ALARM': 'danger', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    'INPUT': '' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  return tagMap[type] || ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 格式化数字 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const formatNumber = (value) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const num = parseFloat(value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (isNaN(num)) return value; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return num.toFixed(2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 获取状态样式类 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const getStatusClass = (status) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  const classMap = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    '正常': 'status-normal', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    '警告': 'status-warning', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    '故障': 'status-error', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    '离线': 'status-offline' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  return classMap[status] || 'status-offline'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 获取设备状态 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const getDeviceStatus = (device) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (device.故障报警 === '是') return '故障'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (device.运行状态 === '是') return '运行中'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (device.自动状态 === '是') return '自动'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return '待机'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 获取状态标签类型 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const getStatusTagType = (status) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 获取设备状态类型 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const getDeviceStatusType = (device) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const status = getDeviceStatus(device); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   const typeMap = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    '正常': 'success', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    '警告': 'warning', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     '故障': 'danger', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    '离线': 'info' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    '运行中': 'success', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    '自动': 'primary', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    '待机': 'info' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   return typeMap[status] || 'info'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 获取历史记录类型标签 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const getHistoryTypeTag = (type) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  const typeMap = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    '状态变更': 'primary', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    '参数调整': 'warning', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    '告警处理': 'danger', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    '维护记录': 'success' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  return typeMap[type] || ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 获取卡片显示数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const getCardDisplayData = (device) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const importantKeys = ['运行状态', '故障报警', '送风温度', '水阀反馈', '自动状态', '过滤网压差']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const result = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 格式化时间 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const formatTime = (time) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if (!time) return '-'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  const date = new Date(time); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  return date.toLocaleString('zh-CN'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  importantKeys.forEach(key => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (device[key] !== undefined) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      result[key] = device[key]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 格式化日期 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const formatDate = (date) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if (!date) return '-'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  const d = new Date(date); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  return d.toLocaleDateString('zh-CN'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const allKeys = Object.keys(device).filter(key => key !== 'deviceName'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  let count = Object.keys(result).length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 格式化JSON 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const formatJson = (json) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const obj = JSON.parse(json || '{}'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return JSON.stringify(obj, null, 2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } catch { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return json || '{}'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  for (const key of allKeys) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (count >= 6) break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (!result[key]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      result[key] = device[key]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      count++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return result; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 发送控制命令 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const sendCommand = async (cmd) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  cmd.loading = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // 模拟发送命令 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    await new Promise(resolve => setTimeout(resolve, 1000)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ElMessage.success(`${cmd.name}命令执行成功`); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // 更新历史记录 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    historyData.value.unshift({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      time: new Date(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      type: '设备控制', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      content: `执行${cmd.name}操作`, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      operator: '当前用户', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      result: '成功' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } catch (error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ElMessage.error(`${cmd.name}命令执行失败`); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } finally { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    cmd.loading = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 格式化卡片值 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const formatCardValue = (key, value) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const type = getColumnType(key); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (type === 'number') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const unit = getColumnUnit(key); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return `${formatNumber(value)}${unit}`; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return value; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 处理模式变更 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const handleModeChange = (value) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  ElMessage.info(`已切换到${value === 'auto' ? '自动' : value === 'manual' ? '手动' : '定时'}模式`); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 获取详情表格数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const getDetailTableData = (device) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const data = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Object.entries(device).forEach(([key, value]) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (key === 'deviceName') return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const type = getColumnType(key); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    let status = '正常'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (type === 'status' && value === '是' && (key.includes('故障') || key.includes('压差'))) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      status = '异常'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } else if (type === 'number') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      const numValue = parseFloat(value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (isNaN(numValue) || numValue === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        status = '异常'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 处理功率调节 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const handlePowerChange = (value) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  ElMessage.info(`功率已调节至${value}%`); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    data.push({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      name: key, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      value: value, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      unit: getColumnUnit(key), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      status: status 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 处理温度调节 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const handleTempChange = (value) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  ElMessage.info(`温度已设定为${value}°C`); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 执行远程控制 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const executeControl = async () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if (!remoteControlForm.command) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ElMessage.warning('请选择控制指令'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  controlLoading.value = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // 模拟控制执行 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    await new Promise(resolve => setTimeout(resolve, 2000)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ElMessage.success('控制指令执行成功'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    controlDialogOpen.value = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // 刷新数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    getList(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } catch (error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ElMessage.error('控制指令执行失败'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } finally { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    controlLoading.value = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 格式化详情值 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const formatDetailValue = (name, value) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const type = getColumnType(name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (type === 'number') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return formatNumber(value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return value; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 保存设备信息 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const saveDeviceInfo = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  ElMessage.success('设备信息保存成功'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  detailDialogOpen.value = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 表格行样式 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const tableRowClassName = ({ row }) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (row.故障报警 === '是') return 'warning-row'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (row.运行状态 !== '是') return 'offline-row'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 3D模型相关方法 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const init3DModel = (device) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // 这里可以初始化Three.js场景 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  console.log('初始化3D模型:', device.deviceId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 事件处理 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const handleSearch = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  queryParams.pageNum = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  getList(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const load3DModel = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  ElMessage.info('正在加载3D模型...'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // 加载3D模型逻辑 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const resetSearch = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  queryParams.device_type = ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  queryParams.pageNum = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  deviceList.value = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  dynamicColumns.value = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  total.value = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const downloadModel = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if (detailDevice.value.modelPath) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ElMessage.success('开始下载模型文件'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // 下载逻辑 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const handleDeviceTypeChange = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  queryParams.pageNum = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (queryParams.device_type) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    getList(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ElMessage.warning('暂无模型文件'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    deviceList.value = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    dynamicColumns.value = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    total.value = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const resetView = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  ElMessage.info('视角已重置'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // 重置3D视角 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const handlePageChange = (newPage) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  queryParams.pageNum = newPage; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  getList(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const handleSizeChange = (newSize) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  queryParams.pageSize = newSize; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  queryParams.pageNum = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  getList(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const toggleTableView = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  isCardView.value = !isCardView.value; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const toggleRotation = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  rotationEnabled.value = !rotationEnabled.value; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // 切换旋转状态 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const handleRowClick = (row) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  currentDevice.value = row; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  detailDialogOpen.value = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const toggleWireframe = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  wireframeMode.value = !wireframeMode.value; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  ElMessage.info(`已切换到${wireframeMode.value ? '线框' : '实体'}模式`); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // 切换渲染模式 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const handleView = (device) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  currentDevice.value = device; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  detailDialogOpen.value = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const fullscreen3D = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  const viewer = document.querySelector('.three-d-viewer'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if (viewer.requestFullscreen) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    viewer.requestFullscreen(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 查看组态信息 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const handleViewConfiguration = (device) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  currentConfigDevice.value = device; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  configurationDialogOpen.value = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  getConfigurationInfo(device); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 </script> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 <style scoped> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* ===== 基础样式 ===== */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 .device-management-system { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   padding: 20px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  background-color: #f5f7fa; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  min-height: 100vh; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.filter-card { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  margin-bottom: 20px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  background: #f5f7fa; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  min-height: 90vh; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  line-height: 1.6; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  animation: fadeIn 0.5s ease-in-out; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* ===== 搜索表单样式 ===== */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 .search-form { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  padding: 10px 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-/* 统计卡片 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.stats-row { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  background: #fff; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  padding: 20px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  border-radius: 12px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   margin-bottom: 20px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  border: 1px solid #e4e7ed; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  transition: box-shadow 0.3s ease; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.stats-card { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  transition: all 0.3s; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.search-form:hover { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.stats-card:hover { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  transform: translateY(-2px); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  box-shadow: 0 4px 20px 0 rgba(0, 0, 0, 0.15); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.search-form .el-form { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  margin-bottom: 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.stats-card.normal :deep(.el-statistic__number) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  color: #67c23a; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.search-form .el-form-item { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  margin-bottom: 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.stats-card.warning :deep(.el-statistic__number) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  color: #e6a23c; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.search-form .el-form-item__label { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  font-weight: 600; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  color: #303133; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.stats-card.error :deep(.el-statistic__number) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  color: #f56c6c; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* ===== 表格容器样式 ===== */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.table-container { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  background: #fff; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  border-radius: 12px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  overflow: hidden; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  margin-bottom: 20px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  transition: box-shadow 0.3s ease; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.data-table { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.table-container:hover { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.12); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.card-header { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* ===== 表格头部样式 ===== */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.table-header { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   display: flex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   justify-content: space-between; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   align-items: center; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  padding: 16px 20px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  border-bottom: 1px solid #e4e7ed; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  background: linear-gradient(135deg, #f8f9fa 0%, #ffffff 100%); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.header-actions { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  display: flex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  gap: 10px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-/* 位置信息样式 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.location-info { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.header-left { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   display: flex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   align-items: center; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  justify-content: center; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  gap: 5px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  font-weight: 500; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gap: 8px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.location-detail { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  font-size: 12px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  color: #909399; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  margin-top: 4px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.header-icon { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  font-size: 20px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  color: #409eff; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-/* 状态样式 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.status-wrapper { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.header-title { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  font-size: 18px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  font-weight: 600; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  color: #303133; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.header-actions { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   display: flex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  align-items: center; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  justify-content: center; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  gap: 6px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gap: 8px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.status-dot { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  width: 8px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  height: 8px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  border-radius: 50%; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  display: inline-block; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  animation: blink 2s infinite; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* ===== 表格样式优化 ===== */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.table-view { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  padding: 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 表格基础样式 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-table) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  border-radius: 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  overflow: hidden; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 表格头部样式 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-table th) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  background: linear-gradient(135deg, #f8f9fa 0%, #ffffff 100%); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  color: #303133; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  font-weight: 600; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  padding: 14px 12px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  border-bottom: 2px solid #e4e7ed; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 表格单元格样式 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-table td) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  padding: 12px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  border-bottom: 1px solid #f0f2f5; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 去掉隔行变色,统一背景色 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-table__row) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  background-color: #ffffff; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  transition: all 0.3s ease; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 悬停效果 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-table__row:hover) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  background-color: #f0f9ff !important; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  transform: translateY(-1px); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 选中行样式 - 加深颜色便于区分 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-table__row.current-row) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  background-color: #e6f4ff !important; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  border-left: 4px solid #409eff; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-table__row.current-row:hover) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  background-color: #d4edff !important; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 表格行状态样式 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.warning-row) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  background-color: #fef0f0 !important; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  border-left: 4px solid #f56c6c; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.warning-row:hover) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  background-color: #fde2e2 !important; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.status-normal { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  background-color: #67c23a; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.offline-row) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  background-color: #f5f7fa !important; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  color: #909399; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.status-warning { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  background-color: #e6a23c; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.offline-row:hover) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  background-color: #ebeef5 !important; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.status-error { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  background-color: #f56c6c; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* ===== 设备信息样式 ===== */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.device-info { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  display: flex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  flex-direction: column; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gap: 4px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  padding: 8px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  border-radius: 6px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  transition: all 0.3s ease; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.status-offline { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  background-color: #909399; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  animation: none; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.device-info:hover { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  background: rgba(64, 158, 255, 0.05); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  transform: translateY(-2px); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-@keyframes blink { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  0%, 100% { opacity: 1; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  50% { opacity: 0.5; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.device-name { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  font-weight: 600; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  color: #303133; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  font-size: 14px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.no-alarm { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.device-type { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   color: #909399; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   font-size: 12px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  background: #f0f2f5; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  padding: 2px 6px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  border-radius: 4px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  display: inline-block; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  width: fit-content; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.pagination-container { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  margin-top: 20px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* ===== 单元格内容样式 ===== */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.cell-content { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   display: flex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  justify-content: flex-end; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  align-items: center; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  justify-content: center; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gap: 4px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-/* 详情弹窗样式 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.status-display { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  padding: 20px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.status-indicator { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  display: flex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  align-items: center; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gap: 4px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.status-item { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.number-display { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   display: flex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   align-items: center; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  margin-bottom: 15px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  font-size: 14px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gap: 2px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.status-item .label { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  width: 80px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  color: #606266; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.number-value { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  font-weight: 600; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  transition: all 0.3s ease; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.alarm-info { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  padding: 10px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.number-value:hover { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  transform: scale(1.05); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.alarm-details { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  margin-top: 15px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  font-size: 14px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  line-height: 1.8; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  color: #606266; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.unit { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  font-size: 11px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  color: #909399; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* ===== 数值状态样式 ===== */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.value-normal .number-value { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  color: #67c23a; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.value-warning .number-value { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  color: #e6a23c; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.value-high .number-value { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  color: #f56c6c; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.value-zero .number-value { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  color: #909399; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.value-invalid .number-value { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  color: #f56c6c; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* ===== 卡片视图样式 ===== */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.card-view { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  padding: 20px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-/* 3D模型查看器 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.model-viewer { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.cards-grid { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   display: grid; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  grid-template-columns: 2fr 1fr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grid-template-columns: repeat(auto-fill, minmax(350px, 1fr)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   gap: 20px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  height: 500px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  margin-bottom: 20px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.model-preview { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  background-color: #1a1a1a; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  border-radius: 4px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.device-card-wrapper { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  animation: cardFadeIn 0.6s ease-out; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.device-card { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  border-radius: 12px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  transition: all 0.3s ease; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  cursor: pointer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  border: 1px solid #e4e7ed; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  overflow: hidden; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.device-card:hover { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  transform: translateY(-4px); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  border-color: #409eff; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.device-card-header { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  display: flex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  justify-content: space-between; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  align-items: center; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  padding: 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.device-title { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  display: flex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  align-items: center; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gap: 12px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.device-avatar-large { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  width: 48px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  height: 48px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  border-radius: 50%; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  background: linear-gradient(135deg, #409eff 0%, #3a8ee6 100%); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   display: flex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   align-items: center; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   justify-content: center; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  position: relative; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  overflow: hidden; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  color: #fff; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  font-size: 20px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.device-card-header .device-info { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  flex: 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.model-info { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  overflow-y: auto; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.device-card-header .device-name { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  font-size: 16px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  font-weight: 600; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  color: #303133; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  margin: 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.json-display { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  font-family: 'Consolas', 'Monaco', monospace; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.device-card-header .device-type { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   font-size: 12px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  line-height: 1.5; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  color: #606266; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  background-color: #f5f7fa; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  padding: 10px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  border-radius: 4px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  overflow: auto; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  max-height: 200px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  color: #909399; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  margin: 4px 0 0 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-/* 控制面板 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.control-panel { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  padding: 20px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.device-card-content { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  padding: 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.control-panel h4 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  margin-bottom: 15px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  color: #303133; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.parameters-grid { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  display: grid; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grid-template-columns: repeat(2, 1fr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gap: 12px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.control-btn { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  width: 100%; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  margin-bottom: 10px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.parameter-item { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  display: flex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  flex-direction: column; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gap: 4px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  padding: 12px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  background: #f8f9fa; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  border-radius: 8px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  transition: all 0.3s ease; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.unit { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  margin-left: 10px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.parameter-item:hover { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  background: #e3f2fd; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  transform: translateY(-2px); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.parameter-label { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  font-size: 12px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   color: #909399; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  font-weight: 500; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-/* 3D查看器 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.three-d-viewer { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  height: 70vh; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.parameter-value { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  font-size: 14px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  font-weight: 600; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  color: #303133; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.device-card-actions { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   display: flex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  flex-direction: column; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  justify-content: center; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gap: 8px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  padding: 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.viewer-toolbar { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  padding: 10px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  background-color: #f5f7fa; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  border-bottom: 1px solid #e4e7ed; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* ===== 空状态样式 ===== */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.empty-state { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  text-align: center; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  padding: 80px 20px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  color: #909399; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.empty-content { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  max-width: 400px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  margin: 0 auto; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.empty-icon { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  color: #c0c4cc; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  margin-bottom: 24px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  animation: float 3s ease-in-out infinite; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.empty-title { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  font-size: 20px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  color: #303133; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  margin: 0 0 12px 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  font-weight: 600; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.empty-description { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  font-size: 14px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  color: #909399; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  margin: 0 0 24px 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  line-height: 1.6; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.empty-result { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  padding: 40px 20px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  text-align: center; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.empty-image { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  color: #c0c4cc; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* ===== 分页样式 ===== */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.pagination-container { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   display: flex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  justify-content: space-between; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  align-items: center; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  justify-content: flex-end; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  padding: 20px 24px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  background-color: #fff; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  border-top: 1px solid #f0f2f5; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.viewer-container { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  flex: 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  background-color: #1a1a1a; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  position: relative; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* ===== 组态信息弹窗样式 ===== */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.configuration-iframe-container { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  width: 100%; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  height: 70vh; /* 调整高度 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  border: 1px solid #e4e7ed; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  border-radius: 8px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   overflow: hidden; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  background: #f5f7fa; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.viewer-container canvas { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.configuration-iframe { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   width: 100%; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   height: 100%; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  border: none; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  display: block; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 弹窗样式覆盖 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-dialog) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  margin: 0 auto !important; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  border-radius: 12px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  overflow: hidden; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-dialog__header) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  color: #fff; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  padding: 20px 24px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  margin: 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-dialog__title) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  color: #fff; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  font-weight: 600; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  font-size: 18px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-dialog__headerbtn .el-dialog__close) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  color: #fff; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  font-size: 20px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 组态弹窗特殊处理 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-dialog__body) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  padding: 16px !important; /* 减少内边距 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  max-height: none; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  overflow: hidden; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 响应式调整 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@media (max-width: 1200px) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .configuration-iframe-container { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    height: 80vh; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@media (max-width: 768px) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .configuration-iframe-container { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    height: 75vh; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  :deep(.el-dialog) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    width: 98% !important; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    top: 1vh !important; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@media (max-width: 480px) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .configuration-iframe-container { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    height: 70vh; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  :deep(.el-dialog) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    width: 100% !important; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    top: 0 !important; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    margin: 0 !important; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* ===== 设备详情弹窗内容样式 ===== */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.device-detail { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  display: flex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  flex-direction: column; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gap: 24px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.detail-section { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  background: #f8f9fa; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  padding: 20px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  border-radius: 8px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  border-left: 4px solid #409eff; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.detail-section h3 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  margin: 0 0 16px 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  color: #303133; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  font-size: 16px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  font-weight: 600; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  display: flex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  align-items: center; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gap: 8px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.detail-section h3::before { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  content: ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  width: 4px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  height: 16px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  background: #409eff; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  border-radius: 2px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* ===== 参数表格样式 ===== */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.param-name { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  display: flex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  align-items: center; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gap: 8px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.param-icon { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  color: #409eff; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  font-size: 14px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.param-value-cell { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  display: flex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  align-items: center; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gap: 4px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  justify-content: center; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.param-value { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  font-weight: 600; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.param-unit { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  font-size: 12px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  color: #909399; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* ===== 按钮样式优化 ===== */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.el-button { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  border-radius: 6px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  font-weight: 500; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  transition: all 0.3s ease; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.el-button--primary { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  background: linear-gradient(135deg, #409eff 0%, #3a8ee6 100%); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  border: none; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  box-shadow: 0 2px 8px rgba(64, 158, 255, 0.3); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.el-button--primary:hover { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  background: linear-gradient(135deg, #3a8ee6 0%, #337ecc 100%); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  box-shadow: 0 4px 12px rgba(64, 158, 255, 0.4); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  transform: translateY(-1px); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.el-button--success { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  background: linear-gradient(135deg, #67c23a 0%, #5daf34 100%); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  border: none; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  box-shadow: 0 2px 8px rgba(103, 194, 58, 0.3); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.el-button--success:hover { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  background: linear-gradient(135deg, #5daf34 0%, #529b2e 100%); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  box-shadow: 0 4px 12px rgba(103, 194, 58, 0.4); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  transform: translateY(-1px); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.el-button[circle] { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  transition: all 0.3s ease; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.el-button[circle]:hover { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  transform: rotate(180deg) scale(1.1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* ===== 标签样式优化 ===== */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.el-tag { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  border-radius: 4px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  font-weight: 500; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  border: none; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  font-size: 11px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  padding: 4px 8px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  transition: all 0.3s ease; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.el-tag:hover { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  transform: scale(1.05); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.el-tag--success { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  background: linear-gradient(135deg, #4CAF50 0%, #009688 100%); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  color: #fff; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.el-tag--danger { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  background: linear-gradient(135deg, #f56c6c 0%, #f25c5c 100%); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  color: #fff; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.el-tag--warning { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  background: linear-gradient(135deg, #e6a23c 0%, #d19e3c 100%); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  color: #fff; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.el-tag--info { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  background: linear-gradient(135deg, #673AB7 0%, #9E9E9E 100%); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  color: #fff; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.viewer-info { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  padding: 10px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  background-color: #f5f7fa; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  border-top: 1px solid #e4e7ed; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.el-tag--primary { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  background: linear-gradient(135deg, #409eff 0%, #3a8ee6 100%); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  color: #fff; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.mb-4 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  margin-bottom: 16px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* ===== 动画定义 ===== */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@keyframes fadeIn { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  from { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    opacity: 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    transform: translateY(20px); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  to { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    opacity: 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    transform: translateY(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@keyframes cardFadeIn { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  from { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    opacity: 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    transform: translateY(20px) scale(0.95); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  to { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    opacity: 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    transform: translateY(0) scale(1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@keyframes dialogSlideIn { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  from { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    opacity: 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    transform: scale(0.8) translateY(-50px); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  to { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    opacity: 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    transform: scale(1) translateY(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@keyframes float { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  0%, 100% { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    transform: translateY(0px); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  50% { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    transform: translateY(-10px); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-/* 响应式设计 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* ===== 响应式设计 ===== */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 @media (max-width: 1200px) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  .stats-row { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    margin-bottom: 10px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .device-management-system { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    padding: 16px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .cards-grid { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    gap: 16px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .configuration-iframe-container { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    height: 70vh; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@media (max-width: 768px) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .device-management-system { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    padding: 12px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .search-form { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    padding: 16px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .table-header { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    padding: 16px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    flex-direction: column; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    gap: 12px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    align-items: flex-start; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .header-actions { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    align-self: flex-end; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .cards-grid { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    grid-template-columns: 1fr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    gap: 12px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  .model-viewer { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .parameters-grid { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     grid-template-columns: 1fr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    height: auto; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    gap: 8px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .parameter-item { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    padding: 8px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .device-card-actions { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    flex-direction: column; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    gap: 8px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  :deep(.el-table td) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    padding: 8px 4px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    font-size: 12px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  :deep(.el-table th) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    padding: 8px 4px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    font-size: 12px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .device-info, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .cell-content { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    font-size: 11px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .pagination-container { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    padding: 16px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    justify-content: center; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  :deep(.el-dialog) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    width: 95% !important; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    margin: 0 auto; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .detail-section { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    padding: 16px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .configuration-iframe-container { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    height: 60vh; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@media (max-width: 480px) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .device-management-system { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    padding: 8px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .search-form { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    padding: 12px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .search-form .el-form { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    display: flex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    flex-direction: column; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .search-form .el-form-item { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    width: 100%; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .search-form .el-input, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .search-form .el-select { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    width: 100% !important; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .table-header { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    padding: 12px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .header-title { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    font-size: 16px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .empty-state { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    padding: 40px 12px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .empty-title { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    font-size: 18px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .empty-description { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    font-size: 13px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .device-card { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    margin: 0 4px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .device-card-header { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    flex-direction: column; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    gap: 12px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    align-items: flex-start; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .configuration-iframe-container { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    height: 50vh; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .dialog-footer { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    flex-direction: column; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    gap: 8px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .dialog-footer .el-button { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    width: 100%; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* ===== 滚动条样式 ===== */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-dialog__body)::-webkit-scrollbar, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-table__body-wrapper)::-webkit-scrollbar { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  width: 6px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  height: 6px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-dialog__body)::-webkit-scrollbar-track, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-table__body-wrapper)::-webkit-scrollbar-track { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  background: #f1f1f1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  border-radius: 3px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-dialog__body)::-webkit-scrollbar-thumb, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  background: #c1c1c1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  border-radius: 3px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-dialog__body)::-webkit-scrollbar-thumb:hover, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb:hover { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  background: #a8a8a8; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* ===== 输入框和选择器样式优化 ===== */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-input__wrapper) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  border-radius: 6px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  transition: all 0.3s ease; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-input__wrapper:hover) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-input__wrapper.is-focus) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-select .el-input__wrapper) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  border-radius: 6px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* ===== 分页样式优化 ===== */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-pagination) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  --el-pagination-button-color: #606266; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  --el-pagination-hover-color: #409eff; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-pagination .el-pager li) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  border-radius: 6px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  margin: 0 2px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  transition: all 0.3s ease; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-pagination .el-pager li:hover) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  transform: translateY(-2px); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-pagination .el-pager li.is-active) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  background: linear-gradient(135deg, #409eff 0%, #3a8ee6 100%); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  color: #fff; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  box-shadow: 0 4px 12px rgba(64, 158, 255, 0.4); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-pagination__total) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  margin-right: 16px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  color: #606266; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  font-weight: 500; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-pagination__sizes) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  margin-right: 16px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* ===== 描述列表样式优化 ===== */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-descriptions) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  background: #fff; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  border-radius: 8px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  overflow: hidden; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-descriptions__label) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  background: #fafbfc !important; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  font-weight: 600; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  color: #303133; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  border-right: 1px solid #e4e7ed; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-descriptions__content) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  background: #fff !important; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  color: #606266; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* ===== 表格固定列阴影 ===== */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-table__fixed-right) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  box-shadow: -2px 0 8px rgba(0, 0, 0, 0.1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-table__fixed-left) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  box-shadow: 2px 0 8px rgba(0, 0, 0, 0.1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* ===== 工具提示样式 ===== */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-tooltip__popper) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  background: rgba(0, 0, 0, 0.8); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  border-radius: 6px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  backdrop-filter: blur(10px); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* ===== 加载动画优化 ===== */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-loading-mask) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  background-color: rgba(255, 255, 255, 0.9); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  backdrop-filter: blur(2px); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-loading-spinner) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  animation: loadingRotate 1.5s linear infinite; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@keyframes loadingRotate { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  from { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    transform: rotate(0deg); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  to { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    transform: rotate(360deg); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* ===== 表格边框优化 ===== */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-table--border) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  border: 1px solid #ebeef5; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  border-radius: 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-table--border::after) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  display: none; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* ===== 空数据状态优化 ===== */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-table__empty-block) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  padding: 60px 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-table__empty-text) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  color: #909399; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  font-size: 14px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* ===== 焦点样式增强 ===== */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.el-button:focus, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.el-input:focus, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.el-select:focus { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  outline: 2px solid #409eff; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  outline-offset: 2px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* ===== 选择状态样式 ===== */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+::selection { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  background: rgba(64, 158, 255, 0.3); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  color: #303133; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* ===== 表单验证样式 ===== */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-form-item.is-error .el-input__wrapper) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  box-shadow: 0 0 0 1px #f56c6c inset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-form-item.is-success .el-input__wrapper) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  box-shadow: 0 0 0 1px #67c23a inset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* ===== 性能优化 ===== */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.device-management-system * { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  box-sizing: border-box; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.device-card:hover, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-table__row:hover), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.parameter-item:hover { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  will-change: transform; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* ===== 无障碍支持 ===== */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@media (prefers-reduced-motion: reduce) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  *, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  *::before, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  *::after { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    animation-duration: 0.01ms !important; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    animation-iteration-count: 1 !important; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    transition-duration: 0.01ms !important; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* ===== 高对比度模式 ===== */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@media (prefers-contrast: high) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .device-management-system { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    background: #fff; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    color: #000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .search-form, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .table-container, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .device-card { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    border: 2px solid #000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    background: #fff; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  .model-preview { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    height: 300px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .el-button--primary { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    background: #000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    color: #fff; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    border: 2px solid #000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .el-button--success { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    background: #006400; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    color: #fff; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    border: 2px solid #006400; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .el-tag { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    border: 1px solid #000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    color: #000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    background: #fff; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  :deep(.el-table__row.current-row) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    background-color: #000 !important; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    color: #fff; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .configuration-iframe-container { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    border: 2px solid #000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-/* 暗色主题支持 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-@media (prefers-color-scheme: dark) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* ===== 打印样式 ===== */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@media print { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .search-form, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .pagination-container, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .header-actions, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .el-button, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .dialog-footer { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    display: none !important; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   .device-management-system { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    background-color: #1a1a1a; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    background: #fff; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    padding: 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .table-container { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    box-shadow: none; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    border: 1px solid #000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .table-header { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    background: #f5f7fa !important; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    color: #000 !important; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    border-bottom: 2px solid #000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  :deep(.el-table th) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    background: #f5f7fa !important; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    color: #000 !important; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    border: 1px solid #000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  :deep(.el-table td) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    background: #fff !important; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    color: #000 !important; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    border: 1px solid #000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  :deep(.el-table__row) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    background-color: #fff !important; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .device-card { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    break-inside: avoid; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    margin-bottom: 20px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    border: 1px solid #000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* ===== 最终样式确保 ===== */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.device-management-system { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  position: relative; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  z-index: 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 确保表格行选中状态优先级最高 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-table tbody tr.current-row > td) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  background-color: #e6f4ff !important; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-table tbody tr.current-row:hover > td) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  background-color: #d4edff !important; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 确保警告行状态 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-table tbody tr.warning-row > td) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  background-color: #fef0f0 !important; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-table tbody tr.warning-row:hover > td) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  background-color: #fde2e2 !important; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 确保离线行状态 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-table tbody tr.offline-row > td) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  background-color: #f5f7fa !important; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  color: #909399; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-table tbody tr.offline-row:hover > td) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  background-color: #ebeef5 !important; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 确保弹窗层级正确 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:deep(.el-overlay-dialog) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  z-index: 2000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  top: 10vh; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 确保按钮组在小屏幕上的布局 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@media (max-width: 600px) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .device-card-actions { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    flex-direction: column; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    gap: 8px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  .json-display { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    background-color: #2a2a2a; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    color: #e0e0e0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .device-card-actions .el-button { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    width: 100%; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    margin: 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 最终确保所有交互元素的可访问性 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.el-button, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.el-link, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.device-card, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.parameter-item { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  cursor: pointer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  user-select: none; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.el-button:disabled, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.el-link:disabled { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  cursor: not-allowed; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  opacity: 0.6; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 确保文本选择的一致性 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.device-name, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.parameter-label, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.parameter-value { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  user-select: text; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 最终的全局重置确保 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+* { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  box-sizing: border-box; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+*:focus { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  outline: none; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+*:focus-visible { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  outline: 2px solid #409eff; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  outline-offset: 2px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 </style> 
			 |