Pārlūkot izejas kodu

Merge branch 'monitor_fix' of shuzhihua/pms-iot-vue into master

yanghao 6 stundas atpakaļ
vecāks
revīzija
fea20e3c8d

BIN
src/assets/imgs/border-title.png


BIN
src/assets/imgs/bottom.png


BIN
src/assets/imgs/green.png


BIN
src/assets/imgs/red.png


BIN
src/assets/imgs/导航按钮.png


BIN
src/assets/imgs/顶部导航背景.png


+ 3 - 1
src/router/modules/remaining.ts

@@ -1847,7 +1847,9 @@ const remainingRouter: AppRouteRecordRaw[] = [
         meta: {
           title: '设备看板',
           noCache: true,
-          hidden: true
+          hidden: true,
+          canTo: true,
+          activeMenu: '/kanban/monitor/kanban'
         },
         component: () => import('@/views/pms/monitor/kanban.vue')
       },

+ 56 - 4
src/views/pms/monitor/data-row.vue

@@ -1,14 +1,21 @@
 <template>
   <div
-    style="border-bottom: 0.5px solid rgba(255, 255, 255, 0.1); border-radius: 5px"
+    style="border-radius: 5px"
     :class="[
-      'flex items-center justify-between border-b border-cyan-500/20 hover:bg-cyan-500/10 transition-colors px-2 -mx-2 rounded',
+      'flex text-[#00d9df] items-center justify-between border-b border-cyan-500/20 hover:bg-cyan-500/10 transition-colors px-2 -mx-2 rounded gap-5',
       compact ? 'py-1' : 'py-2'
     ]"
   >
     <span class="text-cyan-200">{{ label }}</span>
     <div class="flex items-center gap-2">
-      <span class="font-mono text-white font-bold">{{ value }}</span>
+      <!-- 对于运行状态类的字段,显示状态指示器 -->
+      <template v-if="isStatusField(label)">
+        <span class="flex items-center">
+          <!-- 使用图片作为状态指示器 -->
+          <img :src="getStatusImage(value)" :alt="getStatusText(value)" class="w-5 h-5 mr-1" />
+        </span>
+      </template>
+      <span v-else class="font-mono text-white font-bold">{{ formattedValue }}</span>
       <button
         v-if="button"
         style="border-radius: 5px"
@@ -26,6 +33,8 @@
 </template>
 
 <script setup lang="ts">
+import green from '@/assets/imgs/green.png'
+import red from '@/assets/imgs/red.png'
 interface Props {
   label: string
   value: string
@@ -34,7 +43,50 @@ interface Props {
   compact?: boolean
 }
 
-withDefaults(defineProps<Props>(), {
+const props = withDefaults(defineProps<Props>(), {
   compact: false
 })
+
+// 判断是否为状态字段
+const isStatusField = (label: string) => {
+  return (
+    label.includes('运行状态') ||
+    label.includes('加载状态') ||
+    label.includes('PSA运行状态') ||
+    label.toLowerCase().includes('status')
+  )
+}
+
+// 获取状态文本
+const getStatusText = (statusValue: string | number) => {
+  return statusValue === '1' || statusValue === 1 || statusValue === 'true' ? '运行中' : '停止'
+}
+
+// 获取状态图片路径
+const getStatusImage = (statusValue: string | number) => {
+  return statusValue === '1' || statusValue === 1 || statusValue === 'true'
+    ? green // 绿色状态使用green.png
+    : red // 红色状态使用red.png
+}
+
+// 格式化非状态字段的值
+const formattedValue = computed(() => {
+  // 如果是状态字段,则不显示原始值
+  if (isStatusField(props.label)) {
+    return ''
+  }
+  return props.value
+})
 </script>
+
+<style scoped>
+.status-active {
+  background: rgb(34, 197, 94); /* 绿色 */
+  box-shadow: 0 0 8px rgba(34, 197, 94, 0.8);
+}
+
+.status-inactive {
+  background: rgb(239, 68, 68); /* 红色 */
+  box-shadow: 0 0 8px rgba(239, 68, 68, 0.8);
+}
+</style>

+ 1 - 1
src/views/pms/monitor/index.vue

@@ -119,7 +119,7 @@ const deptList = ref<Tree[]>([]) // 树形结构
 import { useRouter } from 'vue-router'
 const router = useRouter()
 
-defineOptions({ name: 'IotDeviceComplete' })
+defineOptions({ name: 'IotDeviceMonitor' })
 
 const loading = ref(true) // 列表的加载中
 

+ 176 - 135
src/views/pms/monitor/kanban.vue

@@ -1,36 +1,33 @@
 <template>
   <div
-    class="bg-gradient-to-br from-slate-950 via-blue-950 to-slate-900 text-cyan-100 p-6 relative"
+    class="bg-[#08092d] text-cyan-100 p-4 pt-0 relative h-screen overflow-hidden flex flex-col font-mono"
     :class="{ 'fullscreen-layout': isFullscreen }"
   >
-    <!-- Animated background grid -->
-    <div class="absolute inset-0 opacity-20">
-      <div class="absolute inset-0 grid-pattern"></div>
-    </div>
-
-    <!-- Scanning line effect -->
-    <div class="absolute inset-0 pointer-events-none">
-      <div class="scan-line"></div>
-    </div>
-
     <!-- Header -->
-    <div class="relative z-10 mb-6">
-      <div class="flex items-center justify-center border-b-2 border-cyan-500/30 pb-4 gap-8">
-        <h1 class="text-2xl font-bold text-cyan-300 flex-6 tracking-wider">
+    <!-- Header -->
+    <div class="relative z-10 mb-2 flex-shrink-0">
+      <div class="header-bg relative flex items-center justify-center py-3">
+        <div class="absolute left-10 top-1/2 -translate-y-1/2 flex items-center gap-4 text-sm pt-2">
+          <div class="return-btn" @click="goBack">
+            <Icon icon="ep:back" /> <span class="pl-2 font-bold">返回</span>
+          </div>
+        </div>
+        <!-- 标题居中 -->
+        <h1 class="text-3xl font-bold text-[#ffac31] tracking-wider text-center">
           {{ dataInfo.groupName }}
         </h1>
 
-        <div class="flex flex-4 items-center gap-8 text-sm">
+        <!-- 操作按钮绝对定位到右侧 -->
+        <div class="absolute right-4 top-1/2 -translate-y-1/2 flex items-center gap-4 text-sm pt-1">
           <div
-            style="border: 0.5px solid #085b77"
-            class="px-4 py-2 bg-cyan-500/10 border border-cyan-500/30 skew-x-[-12deg] hover:bg-cyan-500/20 transition-all cursor-pointer"
+            class="px-4 py-1.5 bg-cyan-500/10 border border-cyan-500/30 skew-x-[-12deg] hover:bg-cyan-500/20 transition-all cursor-pointer"
           >
             <span class="pr-4">部门名称</span>
             <span class="inline-block skew-x-[12deg]">{{ dataInfo.deptName }}</span>
           </div>
           <div
             style="border: 0.5px solid #085b77"
-            class="px-4 py-2 bg-cyan-500/10 border border-cyan-500/30 skew-x-[-12deg] hover:bg-cyan-500/20 transition-all cursor-pointer"
+            class="px-4 py-1.5 bg-cyan-500/10 border border-cyan-500/30 skew-x-[-12deg] hover:bg-cyan-500/20 transition-all cursor-pointer"
           >
             <span class="pr-4">井号</span>
             <span class="inline-block skew-x-[12deg]">{{ dataInfo.wellName }}</span>
@@ -38,7 +35,7 @@
           <div
             @click="toggleFullscreen"
             style="border: 0.5px solid #085b77"
-            class="px-4 py-2 bg-cyan-500/10 border border-cyan-500/30 skew-x-[-12deg] hover:bg-cyan-500/20 transition-all cursor-pointer"
+            class="px-4 py-1.5 bg-cyan-500/10 border border-cyan-500/30 skew-x-[-12deg] hover:bg-cyan-500/20 transition-all cursor-pointer"
           >
             <span class="inline-block skew-x-[12deg]">{{
               isFullscreen ? '退出全屏' : '全屏'
@@ -48,91 +45,89 @@
       </div>
     </div>
 
-    <div class="relative z-10 grid grid-cols-12 gap-4 mt-5 p-6">
-      <!-- Left panels - 合并为一个大面板 -->
-      <div class="col-span-3">
-        <div class="panel h-full flex flex-col">
-          <!-- PSA核心参数 -->
-          <div class="flex-1 border-b border-cyan-500/30 pb-2 mb-2">
-            <div class="flex justify-between items-center panel-title mb-2">
-              <h4>PSA核心参数</h4>
-              <dv-decoration3 style="width: 120px; height: 30px" />
-            </div>
+    <div class="relative z-10 grid grid-cols-12 gap-3 p-2 flex-1 min-h-0">
+      <!-- Left panels - 三个独立面板 -->
+      <div class="col-span-3 min-h-0 flex flex-col gap-2">
+        <!-- PSA核心参数 -->
 
-            <div class="space-y-3 overflow-y-auto overflow-x-hidden flex-grow">
-              <DataRow
-                v-for="item in psaData"
-                :key="item.modelName"
-                :label="item.modelName"
-                :value="formatValue(item.value, getUnitFromModelName(item.modelName))"
-              />
-            </div>
+        <div class="flex-1 min-h-0 flex flex-col">
+          <div
+            class="flex bg-[#08092d] justify-between items-center panel-title mb-1 flex-shrink-0 pl-[5%]"
+          >
+            <h4 class="text-sm pt-1">PSA核心参数</h4>
           </div>
-
-          <!-- 空气处理参数 -->
-          <div class="flex-1 border-b border-cyan-500/30 pb-2 mb-2">
-            <div class="flex justify-between items-center panel-title mb-2">
-              <h4>空气处理撬参数</h4>
-              <dv-decoration3 style="width: 120px; height: 30px" />
-            </div>
-            <div class="space-y-3 overflow-y-auto overflow-x-hidden flex-grow">
-              <DataRow
-                v-for="item in airTreatmentData"
-                :key="item.modelName"
-                :label="item.modelName"
-                :value="formatValue(item.value, getUnitFromModelName(item.modelName))"
-              />
-            </div>
+          <div class="space-y-1 panel overflow-y-auto overflow-x-hidden flex-1 min-h-0">
+            <DataRow
+              v-for="item in psaData"
+              :key="item.modelName"
+              :label="item.modelName"
+              :value="formatValue(item.value, getUnitFromModelName(item.modelName))"
+              :compact="true"
+            />
           </div>
+        </div>
 
-          <!-- 1800中压机参数 -->
-          <div class="flex-1">
-            <div class="flex justify-between items-center panel-title mb-2">
-              <h4>中压机参数</h4>
-              <dv-decoration3 style="width: 120px; height: 30px" />
-            </div>
+        <!-- 空气处理参数 -->
+        <div class="flex-1 min-h-0 flex flex-col">
+          <div class="flex justify-between items-center panel-title mb-1 flex-shrink-0 pl-[5%]">
+            <h4 class="text-sm pt-1">空气处理撬参数</h4>
+          </div>
+          <div class="space-y-1 panel overflow-y-auto overflow-x-hidden flex-1 min-h-0">
+            <DataRow
+              v-for="item in airTreatmentData"
+              :key="item.modelName"
+              :label="item.modelName"
+              :value="formatValue(item.value, getUnitFromModelName(item.modelName))"
+              :compact="true"
+            />
+          </div>
+        </div>
 
-            <div class="space-y-5 overflow-y-auto overflow-x-hidden flex-grow">
-              <DataRow
-                v-for="item in mediumPressureData"
-                :key="item.modelName"
-                :label="item.modelName"
-                :value="formatValue(item.value, getUnitFromModelName(item.modelName))"
-              />
-            </div>
+        <!-- 1800中压机参数 -->
+        <div class="flex-1 min-h-0 flex flex-col">
+          <div class="flex justify-between items-center panel-title flex-shrink-0 pl-[5%]">
+            <h4 class="text-sm pt-1">中压机参数</h4>
+          </div>
+          <div class="space-y-1 panel px-6 overflow-y-auto overflow-x-hidden flex-1 min-h-0">
+            <DataRow
+              v-for="item in mediumPressureData"
+              :key="item.modelName"
+              :label="item.modelName"
+              :value="formatValue(item.value, getUnitFromModelName(item.modelName))"
+              :compact="true"
+            />
           </div>
         </div>
       </div>
 
-      <div class="col-span-6 space-y-4">
-        <div class="panel relative overflow-hidden">
-          <div class="relative h-[450px] flex items-center justify-center">
+      <div class="col-span-6 flex flex-col gap-3 min-h-0">
+        <!-- 模型查看器 - 固定高度 -->
+        <div
+          class="panel relative overflow-hidden flex-shrink-0"
+          style="height: 30vh; border-top: 1px solid #30459c"
+        >
+          <div class="relative h-full flex items-center justify-center">
             <ModelViewer />
           </div>
         </div>
 
-        <!-- 1050空压机参数 -->
-        <div class="panel">
-          <div class="mb-2">
-            <dv-decoration7>
-              <h3 class="text-cyan-300 text-lg font-bold px-1"> 空压机参数 </h3>
-            </dv-decoration7>
+        <!-- 空压机参数 - 占满剩余空间 -->
+        <div class="flex-1 flex flex-col min-h-0" style="min-height: 0">
+          <div class="flex justify-between items-center panel-title flex-shrink-0 pl-[5%]">
+            <h4 class="text-sm pt-1">空压机参数</h4>
           </div>
-          <div class="grid grid-cols-5 gap-4">
-            <div v-for="(compressor, i) in compressorData" :key="i" class="space-y-2 text-center">
-              <div class="text-cyan-300 font-bold mb-2">{{ `空压机${i + 1}` }}</div>
-              <div class="text-sm" v-for="item in compressor" :key="item.modelName">
-                <div class="text-cyan-200">{{ item.modelName }}</div>
+          <div class="grid panel grid-cols-5 gap-2 flex-1 min-h-0" style="overflow-y: auto">
+            <div v-for="(compressor, i) in compressorData" :key="i" class="space-y-0.5 text-center">
+              <div class="text-cyan-300 font-bold text-xs mb-1">{{ `空压机${i + 1}` }}</div>
+              <div class="text-xs" v-for="item in compressor" :key="item.modelName">
+                <div class="text-cyan-200 text-xs">{{ item.modelName }}</div>
                 <div
                   v-if="item.modelName.includes('运行状态') || item.modelName.includes('加载状态')"
-                  class="text-white font-mono flex items-center justify-center"
+                  class="text-white font-mono flex items-center justify-center text-xs"
                 >
-                  <span
-                    :class="['w-3 h-3 rounded-full inline-block mr-2', getStatusClass(item.value)]"
-                  ></span>
-                  {{ getStatusText(item.value) }}
+                  <img :src="getStatusImage(item.value)" alt="状态图标" class="w-5 h-5 mr-1" />
                 </div>
-                <div v-else class="text-white font-mono">
+                <div v-else class="text-white font-mono text-xs">
                   {{ formatValue(item.value, getUnitFromModelName(item.modelName)) }}
                 </div>
               </div>
@@ -142,13 +137,16 @@
       </div>
 
       <!-- Right panel -->
-      <div class="col-span-3">
-        <div class="panel h-full">
-          <div class="flex items-center justify-between mb-4 border-b border-cyan-500/30 pb-2">
-            <h3 class="text-cyan-300 text-lg font-bold">液驱压缩机参数</h3>
-            <dv-decoration8 :reverse="true" style="width: 110px; height: 20px" />
+      <div class="col-span-3 min-h-0">
+        <div class="h-full flex flex-col">
+          <div
+            class="flex panel-title items-center justify-between border-b border-cyan-500/30 pb-1 flex-shrink-0 pl-[5%]"
+          >
+            <h3 class="text-cyan-300 text-sm font-bold pt-1">液驱压缩机参数</h3>
           </div>
-          <div class="space-y-2 text-sm overflow-y-auto overflow-x-hidden">
+          <div
+            class="space-y-1 panel text-[15px] px-3 text-[#00d9df] overflow-y-auto overflow-x-hidden flex-1 min-h-0"
+          >
             <DataRow
               v-for="item in liquidDrivenData"
               :key="item.modelName"
@@ -164,13 +162,15 @@
 </template>
 
 <script setup lang="ts">
-import { ref, onMounted, nextTick } from 'vue'
+import { ref, onMounted, nextTick, onUnmounted } from 'vue'
 import DataRow from './data-row.vue'
 import ModelViewer from './ModelViewer.vue'
 import { IotDeviceApi } from '@/api/pms/device'
-import { useRoute } from 'vue-router'
-
+import { useRoute, useRouter } from 'vue-router'
+import greenImg from '@/assets/imgs/green.png'
+import redImg from '@/assets/imgs/red.png'
 const route = useRoute()
+const router = useRouter()
 
 defineOptions({
   name: 'Kanban'
@@ -184,6 +184,9 @@ let liquidDrivenData = ref<any[]>([])
 let compressorData = ref<any[][]>([])
 const isFullscreen = ref(false)
 
+const getStatusImage = (statusValue: string | number) => {
+  return statusValue === '1' || statusValue === 1 || statusValue === 'true' ? greenImg : redImg
+}
 // 从modelName中提取单位
 const getUnitFromModelName = (modelName: string) => {
   if (!modelName) return ''
@@ -221,12 +224,6 @@ const formatValue = (value: string, unit: string) => {
   return unit ? `${value} ${unit}` : value
 }
 
-// 根据modelName获取值
-const getValueByModelName = (data: any[], modelName: string) => {
-  const item = data.find((i) => i.modelName === modelName)
-  return item ? item.value : '0'
-}
-
 const toggleFullscreen = async () => {
   if (!document.fullscreenElement) {
     // 进入全屏
@@ -256,20 +253,11 @@ const handleFullscreenChange = () => {
   }
 }
 
-onMounted(() => {
-  document.addEventListener('fullscreenchange', handleFullscreenChange)
-})
-
-// 添加 onUnmounted 来清理事件监听器
-onUnmounted(() => {
-  document.removeEventListener('fullscreenchange', handleFullscreenChange)
-})
-
 const getStatusText = (statusValue: string | number) => {
   return statusValue === '1' || statusValue === 1 || statusValue === 'true' ? '运行中' : '停止'
 }
 
-onMounted(async () => {
+const fetchData = async () => {
   try {
     const res = await IotDeviceApi.getDeviceSetParams(route.query.deviceSetId)
 
@@ -299,6 +287,22 @@ onMounted(async () => {
   } catch (error) {
     console.error('获取设备参数失败:', error)
   }
+}
+
+const goBack = () => {
+  router.push({
+    name: 'IotDeviceMonitor'
+  })
+}
+
+onMounted(async () => {
+  document.addEventListener('fullscreenchange', handleFullscreenChange)
+  await fetchData()
+})
+
+// 添加 onUnmounted 来清理事件监听器
+onUnmounted(() => {
+  document.removeEventListener('fullscreenchange', handleFullscreenChange)
 })
 </script>
 
@@ -321,11 +325,19 @@ onMounted(async () => {
   }
 }
 
-.grid-pattern {
+/* .grid-pattern {
   background-image: linear-gradient(rgba(6, 182, 212, 0.3) 1px, transparent 1px),
     linear-gradient(90deg, rgba(6, 182, 212, 0.3) 1px, transparent 1px);
   background-size: 50px 50px;
   animation: gridMove 20s linear infinite;
+} */
+
+.header-bg {
+  background-image: url('https://hebbkx1anhila5yf.public.blob.vercel-storage.com/image-94sPHckfYzuaReFVWlt6620hJz4EKF.png');
+  background-size: 100% 100%;
+  background-repeat: no-repeat;
+  background-position: center;
+  min-height: 50px;
 }
 
 .scan-line {
@@ -346,26 +358,24 @@ onMounted(async () => {
 }
 
 .panel {
-  background: linear-gradient(to bottom right, rgba(15, 23, 42, 0.8), rgba(30, 58, 138, 0.5));
-  backdrop-filter: blur(4px);
-  border: 2px solid rgba(6, 182, 212, 0.4);
-  padding: 1rem;
-  border-radius: 0.5rem;
-  box-shadow: 0 0 20px rgba(6, 182, 212, 0.3);
+  border: 1px solid #30459c;
+  padding: 0.75rem;
+  border-top: none;
   transition: all 0.3s;
   min-height: 0; /* 允许flex项目收缩到其内容以下 */
-}
-
-.panel:hover {
-  box-shadow: 0 0 30px rgba(6, 182, 212, 0.5);
+  overflow: hidden;
 }
 
 .panel-title {
   color: rgb(103, 232, 249);
-  font-size: 1.125rem;
+  font-size: 0.875rem;
   font-weight: bold;
-  border-bottom: 1px solid rgba(6, 182, 212, 0.3);
-  padding-bottom: 0.5rem;
+
+  padding-bottom: 0.25rem;
+  background-image: url('../../../assets/imgs/border-title.png');
+  background-repeat: no-repeat;
+  /* 修改这里 */
+  background-size: 100% 100%; /* 宽高都填满 */
   flex-shrink: 0;
 }
 
@@ -414,7 +424,7 @@ onMounted(async () => {
 
 .btn-red:hover {
   background: rgb(239, 68, 68);
-  box-shadow: 0 0 20px rgba(220, 38, 38, 0.8);
+  box-shadow: 0 0 20px rgba(124, 10, 10, 0.8);
   transform: translateY(-1px);
 }
 
@@ -423,20 +433,51 @@ onMounted(async () => {
   height: 100vh !important;
   width: 100vw !important;
   margin: 0 !important;
-  padding: 0 !important;
-  padding-top: 20px !important;
-  padding-left: 10px !important;
-  padding-right: 10px !important;
-  padding-bottom: 150px !important;
+  padding: 1rem !important;
+  padding-top: 0 !important;
   position: fixed !important;
   top: 0 !important;
   left: 0 !important;
-  overflow: auto !important;
-  overflow-x: hidden !important;
+  overflow: hidden !important;
   max-width: 100vw !important;
   max-height: 100vh !important;
+}
+
+.return-btn {
+  background-image: url('../../../assets/imgs/导航按钮.png');
+  background-size: 100% 100%;
+  background-position: center;
+  padding: 0.75rem 1rem;
+
+  cursor: pointer;
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: 150px;
+  height: 36px;
+  line-height: 46px;
+}
+
+/* 修改垂直滚动条 */
+::-webkit-scrollbar {
+  width: 5px; /* 修改宽度 */
+}
+::-webkit-scrollbar-thumb {
+  border-radius: 5px;
+}
+
+/* 修改滚动条轨道背景色 */
+::-webkit-scrollbar-track {
+  background-color: transparent;
+}
+
+/* 修改滚动条滑块颜色 */
+::-webkit-scrollbar-thumb {
+  background-color: #0a5f73;
+}
 
-  scrollbar-width: none; /* Firefox */
-  -ms-overflow-style: none; /* Internet Explorer 10+ */
+/* 修改滚动条滑块悬停时的颜色 */
+::-webkit-scrollbar-thumb:hover {
+  background-color: #30459c;
 }
 </style>

+ 136 - 128
src/views/pms/monitor/kanban2.vue

@@ -1,51 +1,40 @@
 <template>
   <div
-    class="bg-gradient-to-br from-slate-950 via-blue-950 to-slate-900 text-cyan-100 p-6 relative"
+    class="bg-[#08092d] text-cyan-100 p-4 pt-0 relative h-screen overflow-hidden flex flex-col font-mono"
     :class="{ 'fullscreen-layout': isFullscreen }"
   >
-    <!-- Animated background grid -->
-    <div class="absolute inset-0 opacity-20">
-      <div class="absolute inset-0 grid-pattern"></div>
-    </div>
-
-    <!-- Scanning line effect -->
-    <div class="absolute inset-0 pointer-events-none">
-      <div class="scan-line"></div>
-    </div>
-
     <!-- Header -->
-    <div class="relative z-10 mb-6">
-      <div class="flex items-center justify-center border-b-2 border-cyan-500/30 pb-4 gap-8">
-        <h1 class="text-2xl font-bold text-cyan-300 flex-6 tracking-wider">
+    <div class="relative z-10 mb-2 flex-shrink-0">
+      <div class="header-bg relative flex items-center justify-center py-3">
+        <div class="absolute left-10 top-1/2 -translate-y-1/2 flex items-center gap-4 text-sm pt-2">
+          <div class="return-btn" @click="goBack">
+            <Icon icon="ep:back" /> <span class="pl-2 font-bold">返回</span>
+          </div>
+        </div>
+        <!-- 标题居中 -->
+        <h1 class="text-3xl font-bold text-[#ffac31] tracking-wider text-center">
           {{ dataInfo.groupName }}
         </h1>
 
-        <div class="flex flex-4 items-center gap-8 text-sm">
+        <!-- 操作按钮绝对定位到右侧 -->
+        <div class="absolute right-4 top-1/2 -translate-y-1/2 flex items-center gap-4 text-sm pt-1">
           <div
-            style="border: 0.5px solid #085b77"
-            class="px-4 py-2 bg-cyan-500/10 border border-cyan-500/30 skew-x-[-12deg] hover:bg-cyan-500/20 transition-all cursor-pointer"
+            class="px-4 py-1.5 bg-cyan-500/10 border border-cyan-500/30 skew-x-[-12deg] hover:bg-cyan-500/20 transition-all cursor-pointer"
           >
             <span class="pr-4">部门名称</span>
             <span class="inline-block skew-x-[12deg]">{{ dataInfo.deptName }}</span>
           </div>
           <div
             style="border: 0.5px solid #085b77"
-            class="px-4 py-2 bg-cyan-500/10 border border-cyan-500/30 skew-x-[-12deg] hover:bg-cyan-500/20 transition-all cursor-pointer"
+            class="px-4 py-1.5 bg-cyan-500/10 border border-cyan-500/30 skew-x-[-12deg] hover:bg-cyan-500/20 transition-all cursor-pointer"
           >
             <span class="pr-4">井号</span>
             <span class="inline-block skew-x-[12deg]">{{ dataInfo.wellName }}</span>
           </div>
-          <div
-            style="border: 0.5px solid #085b77"
-            class="px-4 py-2 bg-cyan-500/10 border border-cyan-500/30 skew-x-[-12deg] hover:bg-cyan-500/20 transition-all cursor-pointer"
-          >
-            <span class="pr-4">增加机编号</span>
-            <span class="inline-block skew-x-[12deg]">{{ dataInfo.deviceCode }}</span>
-          </div>
           <div
             @click="toggleFullscreen"
             style="border: 0.5px solid #085b77"
-            class="px-4 py-2 bg-cyan-500/10 border border-cyan-500/30 skew-x-[-12deg] hover:bg-cyan-500/20 transition-all cursor-pointer"
+            class="px-4 py-1.5 bg-cyan-500/10 border border-cyan-500/30 skew-x-[-12deg] hover:bg-cyan-500/20 transition-all cursor-pointer"
           >
             <span class="inline-block skew-x-[12deg]">{{
               isFullscreen ? '退出全屏' : '全屏'
@@ -55,18 +44,20 @@
       </div>
     </div>
 
-    <div class="relative z-10 grid grid-cols-12 gap-4 mt-5 p-6">
+    <div class="relative z-10 grid grid-cols-12 gap-3 flex-1 min-h-0 p-2">
       <!-- Left panels - 固定高度 -->
-      <div class="col-span-3">
-        <div class="panel h-full flex flex-col">
+      <div class="col-span-3 flex flex-col min-h-0">
+        <div class="flex-1 flex flex-col min-h-0">
           <!-- 增压机参数 -->
-          <div class="flex-1 border-b border-cyan-500/30 pb-2 mb-2">
-            <div class="flex justify-between items-center panel-title mb-2">
-              <h4>增压机参数</h4>
-              <dv-decoration3 style="width: 120px; height: 30px" />
+          <div class="flex-[3] border-b border-cyan-500/30 pb-1 mb-1 flex flex-col min-h-0">
+            <div class="flex justify-between items-center panel-title flex-shrink-0 pl-[5%]">
+              <h4 class="pt-1">增压机参数</h4>
             </div>
 
-            <div class="space-y-3 overflow-y-auto overflow-x-hidden flex-grow">
+            <div
+              style="overflow-y: auto"
+              class="space-y-1 panel text-xs overflow-y-auto overflow-x-hidden flex-1 min-h-0 px-3"
+            >
               <DataRow
                 v-for="item in psaData"
                 :key="item.modelName"
@@ -77,12 +68,11 @@
           </div>
 
           <!-- 累计运行时间 -->
-          <div class="flex-1">
-            <div class="flex justify-between items-center panel-title mb-2">
-              <h4>累计运行时间</h4>
-              <dv-decoration3 style="width: 120px; height: 30px" />
+          <div class="flex-1 flex flex-col min-h-0">
+            <div class="flex justify-between items-center panel-title flex-shrink-0 pl-[5%]">
+              <h4 class="pt-1">累计运行时间</h4>
             </div>
-            <div class="space-y-3 overflow-y-auto overflow-x-hidden flex-grow">
+            <div class="space-y-1 panel overflow-y-auto overflow-x-hidden flex-1 min-h-0">
               <DataRow
                 v-for="item in airTreatmentData"
                 :key="item.modelName"
@@ -94,34 +84,32 @@
         </div>
       </div>
 
-      <div class="col-span-6 space-y-4">
+      <div class="col-span-6 flex flex-col gap-2 min-h-0">
         <!-- 3D模型面板 -->
-        <div class="panel h-[60%] relative overflow-hidden">
+        <div
+          class="panel relative overflow-hidden flex-shrink-0"
+          style="height: 30vh; border-top: 1px solid #30459c"
+        >
           <div class="relative h-full flex items-center justify-center">
             <ModelViewer />
           </div>
         </div>
 
         <!-- 状态参数面板 -->
-        <div class="panel h-[40%]">
-          <div class="mb-2">
-            <dv-decoration7>
-              <h3 class="text-cyan-300 text-lg font-bold px-1"> 状态参数 </h3>
-            </dv-decoration7>
+        <div class="flex-[4] flex flex-col min-h-0">
+          <div class="flex justify-between items-center panel-title flex-shrink-0 pl-[5%]">
+            <h4 class="text-cyan-300 text-base font-bold px-1 pt-1"> 状态参数 </h4>
           </div>
-          <div class="grid grid-cols-5 gap-4 h-[calc(100%-2rem)]">
+          <div class="grid panel grid-cols-5 gap-2 flex-1 min-h-0 overflow-hidden">
             <div
               v-for="(group, i) in compressorData"
               :key="i"
-              class="space-y-2 text-center h-full overflow-y-auto"
+              class="space-y-1 text-center overflow-y-auto"
             >
-              <div class="text-sm" v-for="item in group" :key="item.modelName">
+              <div class="text-lg pt-3" v-for="item in group" :key="item.modelName">
                 <div class="text-cyan-200">{{ item.modelName }}</div>
                 <div class="text-white font-mono flex items-center justify-center">
-                  <span
-                    :class="['w-3 h-3 rounded-full inline-block mr-2', getStatusClass(item.value)]"
-                  ></span>
-                  {{ getStatusDisplayText(item.modelName, item.value) }}
+                  <img :src="getStatusImage(item.value)" alt="状态图标" class="w-5 h-5 mr-1" />
                 </div>
               </div>
             </div>
@@ -130,13 +118,14 @@
       </div>
 
       <!-- Right panel - 氮气参数和井口参数平分高度 -->
-      <div class="col-span-3">
-        <div class="panel h-[50%] mb-2">
-          <div class="flex items-center justify-between mb-4 border-b border-cyan-500/30 pb-2">
-            <h3 class="text-cyan-300 text-lg font-bold">氮气参数</h3>
-            <dv-decoration8 :reverse="true" style="width: 110px; height: 20px" />
+      <div class="col-span-3 flex flex-col gap-2 min-h-0">
+        <div class="flex-1 flex flex-col min-h-0">
+          <div
+            class="flex panel-title items-center justify-between border-b border-cyan-500/30 pb-1 flex-shrink-0 pl-[5%]"
+          >
+            <h3 class="text-cyan-300 text-base font-bold pt-1">氮气参数</h3>
           </div>
-          <div class="space-y-2 text-sm overflow-y-auto overflow-x-hidden h-[calc(100%-3rem)]">
+          <div class="space-y-1 panel text-sm overflow-y-auto overflow-x-hidden flex-1 min-h-0">
             <DataRow
               v-for="item in liquidDrivenData"
               :key="item.modelName"
@@ -146,12 +135,13 @@
             />
           </div>
         </div>
-        <div class="panel h-[50%]">
-          <div class="flex items-center justify-between mb-4 border-b border-cyan-500/30 pb-2">
-            <h3 class="text-cyan-300 text-lg font-bold">井口参数 </h3>
-            <dv-decoration8 :reverse="true" style="width: 110px; height: 20px" />
+        <div class="flex-1 flex flex-col min-h-0">
+          <div
+            class="flex panel-title items-center justify-between border-b border-cyan-500/30 pb-1 flex-shrink-0 pl-[5%]"
+          >
+            <h3 class="text-cyan-300 text-base font-bold">井口参数</h3>
           </div>
-          <div class="space-y-2 text-sm overflow-y-auto overflow-x-hidden h-[calc(100%-3rem)]">
+          <div class="space-y-1 panel text-sm overflow-y-auto overflow-x-hidden flex-1 min-h-0">
             <DataRow
               v-for="item in wellheadData"
               :key="item.modelName"
@@ -167,11 +157,13 @@
 </template>
 
 <script setup lang="ts">
-import { ref, onMounted, nextTick } from 'vue'
+import { ref, onMounted, nextTick, onUnmounted } from 'vue'
 import DataRow from './data-row.vue'
 import ModelViewer from './ModelViewer2.vue'
 import { IotDeviceApi } from '@/api/pms/device'
 import { useRoute } from 'vue-router'
+import greenImg from '@/assets/imgs/green.png'
+import redImg from '@/assets/imgs/red.png'
 
 const route = useRoute()
 
@@ -188,6 +180,9 @@ let wellheadData = ref<any[]>([]) // 井口参数
 let compressorData = ref<any[][]>([])
 const isFullscreen = ref(false)
 
+const getStatusImage = (statusValue: string | number) => {
+  return statusValue === '1' || statusValue === 1 || statusValue === 'true' ? greenImg : redImg
+}
 // 从modelName中提取单位
 const getUnitFromModelName = (modelName: string) => {
   if (!modelName) return ''
@@ -287,20 +282,11 @@ const handleFullscreenChange = () => {
   }
 }
 
-onMounted(() => {
-  document.addEventListener('fullscreenchange', handleFullscreenChange)
-})
-
-// 添加 onUnmounted 来清理事件监听器
-onUnmounted(() => {
-  document.removeEventListener('fullscreenchange', handleFullscreenChange)
-})
-
 const getStatusText = (statusValue: string | number) => {
   return statusValue === '1' || statusValue === 1 || statusValue === 'true' ? '运行中' : '停止'
 }
 
-onMounted(async () => {
+const fetchData = async () => {
   try {
     const res = await IotDeviceApi.getDeviceSetParams(route.query.deviceSetId)
 
@@ -385,6 +371,16 @@ onMounted(async () => {
   } catch (error) {
     console.error('获取设备参数失败:', error)
   }
+}
+
+onMounted(() => {
+  document.addEventListener('fullscreenchange', handleFullscreenChange)
+  fetchData()
+})
+
+// 添加 onUnmounted 来清理事件监听器
+onUnmounted(() => {
+  document.removeEventListener('fullscreenchange', handleFullscreenChange)
 })
 </script>
 
@@ -407,51 +403,33 @@ onMounted(async () => {
   }
 }
 
-.grid-pattern {
-  background-image: linear-gradient(rgba(6, 182, 212, 0.3) 1px, transparent 1px),
-    linear-gradient(90deg, rgba(6, 182, 212, 0.3) 1px, transparent 1px);
-  background-size: 50px 50px;
-  animation: gridMove 20s linear infinite;
-}
-
-.scan-line {
-  position: absolute;
-  width: 100%;
-  height: 2px;
-  background: linear-gradient(to right, transparent, rgb(6, 182, 212), transparent);
-  opacity: 0.3;
-  animation: scan 4s linear infinite;
-}
-
-.scan-line-fast {
-  position: absolute;
-  width: 100%;
-  height: 4px;
-  background: linear-gradient(to right, transparent, rgba(6, 182, 212, 0.6), transparent);
-  animation: scan 3s linear infinite;
+.header-bg {
+  background-image: url('https://hebbkx1anhila5yf.public.blob.vercel-storage.com/image-94sPHckfYzuaReFVWlt6620hJz4EKF.png');
+  background-size: 100% 100%;
+  background-repeat: no-repeat;
+  background-position: center;
+  min-height: 50px;
 }
 
 .panel {
-  background: linear-gradient(to bottom right, rgba(15, 23, 42, 0.8), rgba(30, 58, 138, 0.5));
-  backdrop-filter: blur(4px);
-  border: 2px solid rgba(6, 182, 212, 0.4);
-  padding: 1rem;
-  border-radius: 0.5rem;
-  box-shadow: 0 0 20px rgba(6, 182, 212, 0.3);
+  border: 1px solid #30459c;
+  padding: 0.75rem;
+  border-top: none;
   transition: all 0.3s;
   min-height: 0; /* 允许flex项目收缩到其内容以下 */
-}
-
-.panel:hover {
-  box-shadow: 0 0 30px rgba(6, 182, 212, 0.5);
+  overflow: hidden;
 }
 
 .panel-title {
   color: rgb(103, 232, 249);
-  font-size: 1.125rem;
+  font-size: 0.875rem;
   font-weight: bold;
-  border-bottom: 1px solid rgba(6, 182, 212, 0.3);
-  padding-bottom: 0.5rem;
+
+  padding-bottom: 0.25rem;
+  background-image: url('../../../assets/imgs/border-title.png');
+  background-repeat: no-repeat;
+  /* 修改这里 */
+  background-size: 100% 100%; /* 宽高都填满 */
   flex-shrink: 0;
 }
 
@@ -504,37 +482,67 @@ onMounted(async () => {
   transform: translateY(-1px);
 }
 
-/* 全屏模式下组件特定样式 */
+/* 在现有样式中添加 */
+.panel-container {
+  display: flex;
+  flex-direction: column;
+  height: 100%;
+}
+
+.panel-content {
+  flex: 1;
+  overflow-y: auto;
+}
+
 .fullscreen-layout {
   height: 100vh !important;
   width: 100vw !important;
   margin: 0 !important;
-  padding: 0 !important;
-  padding-top: 20px !important;
-  padding-left: 10px !important;
-  padding-right: 10px !important;
-  padding-bottom: 150px !important;
+  padding: 1rem !important;
+  padding-top: 0 !important;
   position: fixed !important;
   top: 0 !important;
   left: 0 !important;
-  overflow: auto !important;
-  overflow-x: hidden !important;
+  overflow: hidden !important;
   max-width: 100vw !important;
   max-height: 100vh !important;
+}
+
+.return-btn {
+  background-image: url('../../../assets/imgs/导航按钮.png');
+  background-size: 100% 100%;
+  background-position: center;
+  padding: 0.75rem 1rem;
 
-  scrollbar-width: none; /* Firefox */
-  -ms-overflow-style: none; /* Internet Explorer 10+ */
+  cursor: pointer;
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: 150px;
+  height: 36px;
+  line-height: 46px;
 }
 
-/* 在现有样式中添加 */
-.panel-container {
-  display: flex;
-  flex-direction: column;
-  height: 100%;
+/* 修改垂直滚动条 */
+::-webkit-scrollbar {
+  width: 5px; /* 修改宽度 */
+}
+::-webkit-scrollbar-thumb {
+  border-radius: 5px;
 }
 
-.panel-content {
-  flex: 1;
-  overflow-y: auto;
+/* 修改滚动条轨道背景色 */
+::-webkit-scrollbar-track {
+  background-color: transparent;
+}
+
+/* 修改滚动条滑块颜色 */
+::-webkit-scrollbar-thumb {
+  background-color: #0a5f73;
+}
+
+/* 修改滚动条滑块悬停时的颜色 */
+::-webkit-scrollbar-thumb:hover {
+  background-color: #30459c;
 }
 </style>