From 7d5d50d0c80738d56c2e6e0a643c45849c796d5b Mon Sep 17 00:00:00 2001
From: yaowanxin <3588231647@qq.com>
Date: 星期五, 26 九月 2025 15:40:03 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev' into dev

---
 multiple/assets/logo/HXGYLogo.png                  |    0 
 multiple/config.json                               |   20 +
 multiple/assets/favicon/HXGYico.ico                |    0 
 multiple/assets/logo/BDSMLogo.png                  |    0 
 multiple/assets/screen/BDSMView.png                |    0 
 multiple/assets/favicon/BDSMico.ico                |    0 
 multiple/assets/screen/HXGYView.png                |    0 
 src/views/equipmentManagement/kplMonitor/index.vue |  699 ++++++++++++++++++++++++++++++++++++++-------------------
 8 files changed, 484 insertions(+), 235 deletions(-)

diff --git a/multiple/assets/favicon/BDSMico.ico b/multiple/assets/favicon/BDSMico.ico
new file mode 100644
index 0000000..890782c
--- /dev/null
+++ b/multiple/assets/favicon/BDSMico.ico
Binary files differ
diff --git a/multiple/assets/favicon/HXGYico.ico b/multiple/assets/favicon/HXGYico.ico
new file mode 100644
index 0000000..6182687
--- /dev/null
+++ b/multiple/assets/favicon/HXGYico.ico
Binary files differ
diff --git a/multiple/assets/logo/BDSMLogo.png b/multiple/assets/logo/BDSMLogo.png
new file mode 100644
index 0000000..07d0fe9
--- /dev/null
+++ b/multiple/assets/logo/BDSMLogo.png
Binary files differ
diff --git a/multiple/assets/logo/HXGYLogo.png b/multiple/assets/logo/HXGYLogo.png
new file mode 100644
index 0000000..d21365d
--- /dev/null
+++ b/multiple/assets/logo/HXGYLogo.png
Binary files differ
diff --git a/multiple/assets/screen/BDSMView.png b/multiple/assets/screen/BDSMView.png
new file mode 100644
index 0000000..3822931
--- /dev/null
+++ b/multiple/assets/screen/BDSMView.png
Binary files differ
diff --git a/multiple/assets/screen/HXGYView.png b/multiple/assets/screen/HXGYView.png
new file mode 100644
index 0000000..a1094e8
--- /dev/null
+++ b/multiple/assets/screen/HXGYView.png
Binary files differ
diff --git a/multiple/config.json b/multiple/config.json
index 4b07b48..2fad122 100644
--- a/multiple/config.json
+++ b/multiple/config.json
@@ -197,6 +197,26 @@
     "logo": "logo/JLSNLogo.png",
     "favicon": "favicon/JLSNico.ico"
   },
+  "BDSM": {
+    "env": {
+      "VITE_APP_TITLE": "鍗氳揪鍟嗚锤淇℃伅绠$悊绯荤粺",
+      "VITE_BASE_API": "http://114.132.189.42:9096",
+      "VITE_JAVA_API": "http://114.132.189.42:9095"
+    },
+    "screen": "screen/BDSMView.png",
+    "logo": "logo/BDSMLogo.png",
+    "favicon": "favicon/BDSMico.ico"
+  },
+  "HXGY": {
+    "env": {
+      "VITE_APP_TITLE": "姹囨槦閽欎笟淇℃伅绠$悊绯荤粺",
+      "VITE_BASE_API": "http://114.132.189.42:9098",
+      "VITE_JAVA_API": "http://114.132.189.42:9097"
+    },
+    "screen": "screen/HXGYView.png",
+    "logo": "logo/HXGYLogo.png",
+    "favicon": "favicon/HXGYico.ico"
+  },
   "screen": "/src/assets/images/login-background.png",
   "logo": "/src/assets/logo/logo.png",
   "favicon": "/public/favicon.ico"
diff --git a/src/views/equipmentManagement/kplMonitor/index.vue b/src/views/equipmentManagement/kplMonitor/index.vue
index 4d305f3..178b658 100644
--- a/src/views/equipmentManagement/kplMonitor/index.vue
+++ b/src/views/equipmentManagement/kplMonitor/index.vue
@@ -1,7 +1,11 @@
 <template>
   <div class="kpl-monitor-container">
+    <!-- 椤甸潰澶撮儴 -->
     <div class="page-header">
-      <h1>KPL鐩戞帶鍒嗘瀽</h1>
+      <div class="header-content">
+        <h1>KPL鐩戞帶鍒嗘瀽</h1>
+        <p>璁惧鍏抽敭鎬ц兘鎸囨爣鐩戞帶涓庣淮淇濈瓥鐣ヤ紭鍖�</p>
+      </div>
       <div class="time-range">
         <el-date-picker
           v-model="timeRange"
@@ -15,89 +19,90 @@
       </div>
     </div>
 
-    <!-- 鍏抽敭鎸囨爣鍗$墖 -->
-    <div class="metrics-cards">
-      <div class="metric-card">
-        <div class="metric-header">
-          <span class="metric-title">MTBF</span>
-          <span class="metric-trend" :class="mtbfTrendClass">
-            {{ mtbfTrendText }}
-          </span>
-        </div>
-        <div class="metric-value">{{ currentMTBF }} 灏忔椂</div>
-        <div class="metric-change">
-          杈冧笂鏈�: {{ mtbfChange }}%
+    <!-- 鍏抽敭鎸囨爣姒傝 -->
+    <div class="metrics-overview">
+      <div class="metric-card mtbf-card">
+        <div class="metric-icon">鈴憋笍</div>
+        <div class="metric-content">
+          <div class="metric-title">MTBF</div>
+          <div class="metric-subtitle">骞冲潎鏃犳晠闅滄椂闂�</div>
+          <div class="metric-value">{{ currentMTBF }}<span class="unit">灏忔椂</span></div>
+          <div class="metric-trend" :class="mtbfTrendClass">
+            <span class="trend-icon">{{ mtbfTrendText }}</span>
+            <span class="trend-text">{{ Math.abs(mtbfChange) }}%</span>
+          </div>
         </div>
       </div>
 
-      <div class="metric-card">
-        <div class="metric-header">
-          <span class="metric-title">MTTR</span>
-          <span class="metric-trend" :class="mttrTrendClass">
-            {{ mttrTrendText }}
-          </span>
-        </div>
-        <div class="metric-value">{{ currentMTTR }} 灏忔椂</div>
-        <div class="metric-change">
-          杈冧笂鏈�: {{ mttrChange }}%
+      <div class="metric-card mttr-card">
+        <div class="metric-icon">馃敡</div>
+        <div class="metric-content">
+          <div class="metric-title">MTTR</div>
+          <div class="metric-subtitle">骞冲潎淇鏃堕棿</div>
+          <div class="metric-value">{{ currentMTTR }}<span class="unit">灏忔椂</span></div>
+          <div class="metric-trend" :class="mttrTrendClass">
+            <span class="trend-icon">{{ mttrTrendText }}</span>
+            <span class="trend-text">{{ Math.abs(mttrChange) }}%</span>
+          </div>
         </div>
       </div>
 
-      <div class="metric-card">
-        <div class="metric-header">
-          <span class="metric-title">璁惧鍙敤鐜�</span>
-          <span class="metric-trend" :class="availabilityTrendClass">
-            {{ availabilityTrendText }}
-          </span>
-        </div>
-        <div class="metric-value">{{ currentAvailability }}%</div>
-        <div class="metric-change">
-          杈冧笂鏈�: {{ availabilityChange }}%
-        </div>
-      </div>
-
-      <div class="metric-card">
-        <div class="metric-header">
-          <span class="metric-title">鏁呴殰娆℃暟</span>
-          <span class="metric-trend" :class="failureTrendClass">
-            {{ failureTrendText }}
-          </span>
-        </div>
-        <div class="metric-value">{{ currentFailures }} 娆�</div>
-        <div class="metric-change">
-          杈冧笂鏈�: {{ failureChange }}%
+      <div class="metric-card availability-card">
+        <div class="metric-icon">馃搳</div>
+        <div class="metric-content">
+          <div class="metric-title">璁惧鍙敤鐜�</div>
+          <div class="metric-subtitle">杩愯鏁堢巼鎸囨爣</div>
+          <div class="metric-value">{{ currentAvailability }}<span class="unit">%</span></div>
+          <div class="metric-trend" :class="availabilityTrendClass">
+            <span class="trend-icon">{{ availabilityTrendText }}</span>
+            <span class="trend-text">{{ Math.abs(availabilityChange) }}%</span>
+          </div>
         </div>
       </div>
     </div>
 
-    <!-- 瓒嬪娍鍥捐〃 -->
+    <!-- 瓒嬪娍鍒嗘瀽鍥捐〃 -->
     <div class="charts-section">
-      <div class="chart-card">
-        <div class="chart-header">MTBF瓒嬪娍鍒嗘瀽</div>
-        <div class="chart-container">
-          <div ref="mtbfChart" class="chart"></div>
+      <div class="chart-container">
+        <div class="chart-header">
+          <h3>MTBF & MTTR 瓒嬪娍鍒嗘瀽</h3>
+          <div class="chart-legend">
+            <span class="legend-item mtbf-legend">
+              <span class="legend-color"></span>
+              MTBF (骞冲潎鏃犳晠闅滄椂闂�)
+            </span>
+            <span class="legend-item mttr-legend">
+              <span class="legend-color"></span>
+              MTTR (骞冲潎淇鏃堕棿)
+            </span>
+          </div>
         </div>
-      </div>
-
-      <div class="chart-card">
-        <div class="chart-header">MTTR瓒嬪娍鍒嗘瀽</div>
-        <div class="chart-container">
-          <div ref="mttrChart" class="chart"></div>
+        <div class="chart-wrapper">
+          <div ref="trendChart" class="chart"></div>
         </div>
       </div>
     </div>
 
-    <!-- 浼樺寲寤鸿 -->
-    <div class="recommendation-card">
-      <div class="card-header">缁翠繚绛栫暐浼樺寲寤鸿</div>
-      <div class="recommendation-content">
+    <!-- 缁翠繚绛栫暐寤鸿 -->
+    <div class="recommendations-section">
+      <div class="section-header">
+        <h3>缁翠繚绛栫暐浼樺寲寤鸿</h3>
+        <p>鍩轰簬褰撳墠鎸囨爣鍒嗘瀽锛屼负鎮ㄦ彁渚涢拡瀵规�х殑浼樺寲寤鸿</p>
+      </div>
+      <div class="recommendations-grid">
         <div 
           v-for="(recommendation, index) in recommendations" 
           :key="index"
-          class="recommendation-item"
+          class="recommendation-card"
         >
-          <div class="recommendation-icon">馃挕</div>
-          <div class="recommendation-text">{{ recommendation }}</div>
+          <div class="recommendation-icon">{{ recommendation.icon }}</div>
+          <div class="recommendation-content">
+            <h4>{{ recommendation.title }}</h4>
+            <p>{{ recommendation.description }}</p>
+            <div class="recommendation-priority" :class="recommendation.priority">
+              {{ recommendation.priorityText }}
+            </div>
+          </div>
         </div>
       </div>
     </div>
@@ -108,7 +113,7 @@
 import { ref, reactive, onMounted, computed, nextTick } from 'vue'
 import * as echarts from 'echarts'
 
-// 妯℃嫙鏁版嵁
+// 鐢熸垚妯℃嫙鏁版嵁
 const generateMockData = () => {
   const months = ['1鏈�', '2鏈�', '3鏈�', '4鏈�', '5鏈�', '6鏈�', '7鏈�', '8鏈�', '9鏈�', '10鏈�', '11鏈�', '12鏈�']
   const mtbfData = months.map(() => Math.floor(Math.random() * 200 + 300)) // 300-500灏忔椂
@@ -128,13 +133,12 @@
 
 const mockData = reactive(generateMockData())
 
-// 璁$畻褰撳墠鍊硷紙鏈�鏂版湀浠界殑鏁版嵁锛�
+// 璁$畻褰撳墠鎸囨爣鍊�
 const currentMTBF = computed(() => mockData.mtbfData[mockData.mtbfData.length - 1])
 const currentMTTR = computed(() => mockData.mttrData[mockData.mttrData.length - 1])
 const currentAvailability = computed(() => 
   Math.round((currentMTBF.value / (currentMTBF.value + currentMTTR.value)) * 100)
 )
-const currentFailures = computed(() => Math.floor(Math.random() * 10 + 5))
 
 // 璁$畻鍙樺寲瓒嬪娍
 const mtbfChange = computed(() => {
@@ -158,114 +162,177 @@
   return Math.round(((current - previous) / previous) * 100)
 })
 
-const failureChange = computed(() => {
-  const current = currentFailures.value
-  const previous = Math.floor(Math.random() * 10 + 5)
-  return Math.round(((current - previous) / previous) * 100)
-})
-
-// 瓒嬪娍鍒ゆ柇
+// 瓒嬪娍鏍峰紡鍜屾枃鏈�
 const mtbfTrendClass = computed(() => mtbfChange.value >= 0 ? 'trend-up' : 'trend-down')
 const mttrTrendClass = computed(() => mttrChange.value <= 0 ? 'trend-up' : 'trend-down')
 const availabilityTrendClass = computed(() => availabilityChange.value >= 0 ? 'trend-up' : 'trend-down')
-const failureTrendClass = computed(() => failureChange.value <= 0 ? 'trend-up' : 'trend-down')
 
-const mtbfTrendText = computed(() => mtbfChange.value >= 0 ? '鈫�' : '鈫�')
-const mttrTrendText = computed(() => mttrChange.value <= 0 ? '鈫�' : '鈫�')
-const availabilityTrendText = computed(() => availabilityChange.value >= 0 ? '鈫�' : '鈫�')
-const failureTrendText = computed(() => failureChange.value <= 0 ? '鈫�' : '鈫�')
+const mtbfTrendText = computed(() => mtbfChange.value >= 0 ? '鈫�' : '鈫�')
+const mttrTrendText = computed(() => mttrChange.value <= 0 ? '鈫�' : '鈫�')
+const availabilityTrendText = computed(() => availabilityChange.value >= 0 ? '鈫�' : '鈫�')
 
-// 浼樺寲寤鸿
+// 鏅鸿兘缁翠繚寤鸿
 const recommendations = computed(() => {
   const suggestions = []
   
+  // MTBF鐩稿叧寤鸿
   if (currentMTBF.value < 400) {
-    suggestions.push('MTBF杈冧綆锛屽缓璁姞寮洪闃叉�х淮鎶わ紝瀹氭湡妫�鏌ュ叧閿儴浠�')
+    suggestions.push({
+      icon: '馃敡',
+      title: '鎻愬崌MTBF',
+      description: '褰撳墠MTBF杈冧綆锛屽缓璁姞寮洪闃叉�х淮鎶わ紝瀹氭湡妫�鏌ュ叧閿儴浠讹紝寤堕暱璁惧鏃犳晠闅滆繍琛屾椂闂�',
+      priority: 'high',
+      priorityText: '楂樹紭鍏堢骇'
+    })
   }
   
+  // MTTR鐩稿叧寤鸿
   if (currentMTTR.value > 8) {
-    suggestions.push('MTTR杈冮珮锛屽缓璁紭鍖栫淮淇祦绋嬶紝鎻愰珮缁翠慨鏁堢巼')
+    suggestions.push({
+      icon: '鈿�',
+      title: '浼樺寲MTTR',
+      description: '褰撳墠MTTR杈冮珮锛屽缓璁紭鍖栫淮淇祦绋嬶紝鎻愰珮缁翠慨浜哄憳鎶�鑳斤紝缂╃煭鏁呴殰淇鏃堕棿',
+      priority: 'high',
+      priorityText: '楂樹紭鍏堢骇'
+    })
   }
   
+  // 鍙敤鐜囩浉鍏冲缓璁�
   if (currentAvailability.value < 95) {
-    suggestions.push('璁惧鍙敤鐜囨湁寰呮彁鍗囷紝寤鸿浼樺寲缁翠繚璁″垝瀹夋帓')
+    suggestions.push({
+      icon: '馃搱',
+      title: '鎻愬崌鍙敤鐜�',
+      description: '璁惧鍙敤鐜囨湁寰呮彁鍗囷紝寤鸿浼樺寲缁翠繚璁″垝瀹夋帓锛屽噺灏戣鍒掑鍋滄満鏃堕棿',
+      priority: 'medium',
+      priorityText: '涓紭鍏堢骇'
+    })
   }
   
-  if (currentFailures.value > 8) {
-    suggestions.push('鏁呴殰娆℃暟杈冨锛屽缓璁姞寮鸿澶囨棩甯稿贰妫�')
+  // 缁煎悎寤鸿
+  if (currentMTBF.value >= 400 && currentMTTR.value <= 8 && currentAvailability.value >= 95) {
+    suggestions.push({
+      icon: '鉁�',
+      title: '杩愯鐘跺喌鑹ソ',
+      description: '褰撳墠璁惧杩愯鐘跺喌鑹ソ锛屽悇椤规寚鏍囧潎杈惧埌棰勬湡锛屽缓璁户缁繚鎸佺幇鏈夌淮淇濈瓥鐣�',
+      priority: 'low',
+      priorityText: '浣庝紭鍏堢骇'
+    })
   }
   
-  if (suggestions.length === 0) {
-    suggestions.push('褰撳墠璁惧杩愯鐘跺喌鑹ソ锛岀户缁繚鎸佺幇鏈夌淮淇濈瓥鐣�')
-  }
+  // 棰勯槻鎬у缓璁�
+  suggestions.push({
+    icon: '馃搵',
+    title: '棰勯槻鎬х淮鎶�',
+    description: '寤鸿寤虹珛璁惧鍋ュ悍妗f锛屽畾鏈熷垎鏋愯澶囪繍琛屾暟鎹紝鎻愬墠璇嗗埆娼滃湪鏁呴殰椋庨櫓',
+    priority: 'medium',
+    priorityText: '涓紭鍏堢骇'
+  })
   
   return suggestions
 })
 
 // 鍥捐〃瀹炰緥
-let mtbfChart = null
-let mttrChart = null
+let trendChart = null
 
-const initCharts = () => {
+const initChart = () => {
   nextTick(() => {
-    // MTBF鍥捐〃
-    mtbfChart = echarts.init(document.querySelector('.chart-card:first-child .chart'))
-    mtbfChart.setOption({
+    trendChart = echarts.init(document.querySelector('.chart'))
+    trendChart.setOption({
       tooltip: {
-        trigger: 'axis'
+        trigger: 'axis',
+        axisPointer: {
+          type: 'cross'
+        }
+      },
+      legend: {
+        data: ['MTBF', 'MTTR'],
+        top: 10
+      },
+      grid: {
+        left: '3%',
+        right: '4%',
+        bottom: '3%',
+        containLabel: true
       },
       xAxis: {
         type: 'category',
-        data: mockData.months
-      },
-      yAxis: {
-        type: 'value',
-        name: '灏忔椂'
-      },
-      series: [{
-        data: mockData.mtbfData,
-        type: 'line',
-        smooth: true,
-        lineStyle: {
-          color: '#1890ff'
-        },
-        areaStyle: {
-          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
-            { offset: 0, color: 'rgba(24, 144, 255, 0.3)' },
-            { offset: 1, color: 'rgba(24, 144, 255, 0.1)' }
-          ])
+        data: mockData.months,
+        axisLine: {
+          lineStyle: {
+            color: '#e0e0e0'
+          }
         }
-      }]
-    })
-
-    // MTTR鍥捐〃
-    mttrChart = echarts.init(document.querySelector('.chart-card:last-child .chart'))
-    mttrChart.setOption({
-      tooltip: {
-        trigger: 'axis'
       },
-      xAxis: {
-        type: 'category',
-        data: mockData.months
-      },
-      yAxis: {
-        type: 'value',
-        name: '灏忔椂'
-      },
-      series: [{
-        data: mockData.mttrData,
-        type: 'line',
-        smooth: true,
-        lineStyle: {
-          color: '#52c41a'
+      yAxis: [
+        {
+          type: 'value',
+          name: 'MTBF (灏忔椂)',
+          position: 'left',
+          axisLine: {
+            lineStyle: {
+              color: '#1890ff'
+            }
+          },
+          axisLabel: {
+            formatter: '{value}h'
+          }
         },
-        areaStyle: {
-          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
-            { offset: 0, color: 'rgba(82, 196, 26, 0.3)' },
-            { offset: 1, color: 'rgba(82, 196, 26, 0.1)' }
-          ])
+        {
+          type: 'value',
+          name: 'MTTR (灏忔椂)',
+          position: 'right',
+          axisLine: {
+            lineStyle: {
+              color: '#52c41a'
+            }
+          },
+          axisLabel: {
+            formatter: '{value}h'
+          }
         }
-      }]
+      ],
+      series: [
+        {
+          name: 'MTBF',
+          type: 'line',
+          yAxisIndex: 0,
+          data: mockData.mtbfData,
+          smooth: true,
+          lineStyle: {
+            color: '#1890ff',
+            width: 3
+          },
+          itemStyle: {
+            color: '#1890ff'
+          },
+          areaStyle: {
+            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+              { offset: 0, color: 'rgba(24, 144, 255, 0.3)' },
+              { offset: 1, color: 'rgba(24, 144, 255, 0.1)' }
+            ])
+          }
+        },
+        {
+          name: 'MTTR',
+          type: 'line',
+          yAxisIndex: 1,
+          data: mockData.mttrData,
+          smooth: true,
+          lineStyle: {
+            color: '#52c41a',
+            width: 3
+          },
+          itemStyle: {
+            color: '#52c41a'
+          },
+          areaStyle: {
+            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+              { offset: 0, color: 'rgba(82, 196, 26, 0.3)' },
+              { offset: 1, color: 'rgba(82, 196, 26, 0.1)' }
+            ])
+          }
+        }
+      ]
     })
   })
 }
@@ -275,34 +342,29 @@
   Object.assign(mockData, generateMockData())
   
   // 閲嶆柊娓叉煋鍥捐〃
-  if (mtbfChart && mttrChart) {
-    mtbfChart.setOption({
+  if (trendChart) {
+    trendChart.setOption({
       xAxis: {
         data: mockData.months
       },
-      series: [{
-        data: mockData.mtbfData
-      }]
-    })
-    
-    mttrChart.setOption({
-      xAxis: {
-        data: mockData.months
-      },
-      series: [{
-        data: mockData.mttrData
-      }]
+      series: [
+        {
+          data: mockData.mtbfData
+        },
+        {
+          data: mockData.mttrData
+        }
+      ]
     })
   }
 }
 
 onMounted(() => {
-  initCharts()
+  initChart()
   
   // 鐩戝惉绐楀彛澶у皬鍙樺寲锛岄噸鏂拌皟鏁村浘琛ㄥぇ灏�
   window.addEventListener('resize', () => {
-    if (mtbfChart) mtbfChart.resize()
-    if (mttrChart) mttrChart.resize()
+    if (trendChart) trendChart.resize()
   })
 })
 </script>
@@ -310,109 +372,197 @@
 <style scoped>
 .kpl-monitor-container {
   min-height: 100vh;
-  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
-  padding: 20px;
+  background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
+  padding: 24px;
   font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
 }
 
+/* 椤甸潰澶撮儴 */
 .page-header {
-  background: rgba(255, 255, 255, 0.95);
-  border-radius: 16px;
-  padding: 20px;
-  margin-bottom: 20px;
+  background: white;
+  border-radius: 12px;
+  padding: 24px;
+  margin-bottom: 24px;
+  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
   display: flex;
   justify-content: space-between;
   align-items: center;
 }
 
-.page-header h1 {
+.header-content h1 {
+  margin: 0 0 8px 0;
+  color: #1f2937;
+  font-size: 28px;
+  font-weight: 700;
+}
+
+.header-content p {
   margin: 0;
-  color: #2c3e50;
-  font-size: 24px;
+  color: #6b7280;
+  font-size: 16px;
 }
 
 .time-range {
   display: flex;
   align-items: center;
-  gap: 10px;
+  gap: 12px;
 }
 
-.metrics-cards {
+/* 鎸囨爣姒傝 */
+.metrics-overview {
   display: grid;
-  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
+  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
   gap: 20px;
-  margin-bottom: 20px;
+  margin-bottom: 24px;
 }
 
 .metric-card {
-  background: rgba(255, 255, 255, 0.95);
-  border-radius: 16px;
-  padding: 20px;
-  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
+  background: white;
+  border-radius: 12px;
+  padding: 24px;
+  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+  display: flex;
+  align-items: center;
+  gap: 16px;
+  transition: transform 0.2s ease, box-shadow 0.2s ease;
 }
 
-.metric-header {
+.metric-card:hover {
+  transform: translateY(-2px);
+  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
+}
+
+.metric-icon {
+  font-size: 32px;
+  width: 60px;
+  height: 60px;
   display: flex;
-  justify-content: space-between;
   align-items: center;
-  margin-bottom: 15px;
+  justify-content: center;
+  border-radius: 12px;
+  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+}
+
+.mtbf-card .metric-icon {
+  background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
+}
+
+.mttr-card .metric-icon {
+  background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
+}
+
+.availability-card .metric-icon {
+  background: linear-gradient(135deg, #fa709a 0%, #fee140 100%);
+}
+
+.metric-content {
+  flex: 1;
 }
 
 .metric-title {
-  font-size: 16px;
-  color: #666;
-  font-weight: 500;
-}
-
-.metric-trend {
-  font-size: 14px;
+  font-size: 18px;
   font-weight: 600;
+  color: #1f2937;
+  margin-bottom: 4px;
 }
 
-.trend-up {
-  color: #52c41a;
-}
-
-.trend-down {
-  color: #ff4d4f;
+.metric-subtitle {
+  font-size: 14px;
+  color: #6b7280;
+  margin-bottom: 12px;
 }
 
 .metric-value {
   font-size: 32px;
   font-weight: 700;
-  color: #2c3e50;
+  color: #1f2937;
   margin-bottom: 8px;
 }
 
-.metric-change {
+.unit {
+  font-size: 16px;
+  font-weight: 500;
+  color: #6b7280;
+  margin-left: 4px;
+}
+
+.metric-trend {
+  display: flex;
+  align-items: center;
+  gap: 4px;
   font-size: 14px;
-  color: #666;
+  font-weight: 600;
 }
 
+.trend-up {
+  color: #10b981;
+}
+
+.trend-down {
+  color: #ef4444;
+}
+
+.trend-icon {
+  font-size: 16px;
+}
+
+/* 鍥捐〃鍖哄煙 */
 .charts-section {
-  display: grid;
-  grid-template-columns: repeat(auto-fit, minmax(500px, 1fr));
-  gap: 20px;
-  margin-bottom: 20px;
+  margin-bottom: 24px;
 }
 
-.chart-card {
-  background: rgba(255, 255, 255, 0.95);
-  border-radius: 16px;
+.chart-container {
+  background: white;
+  border-radius: 12px;
+  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
   overflow: hidden;
 }
 
 .chart-header {
-  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
-  color: white;
-  padding: 16px 20px;
-  font-weight: 500;
-  font-size: 16px;
+  padding: 20px 24px;
+  border-bottom: 1px solid #e5e7eb;
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
 }
 
-.chart-container {
+.chart-header h3 {
+  margin: 0;
+  color: #1f2937;
+  font-size: 18px;
+  font-weight: 600;
+}
+
+.chart-legend {
+  display: flex;
+  gap: 20px;
+}
+
+.legend-item {
+  display: flex;
+  align-items: center;
+  gap: 8px;
+  font-size: 14px;
+  color: #6b7280;
+}
+
+.legend-color {
+  width: 12px;
+  height: 12px;
+  border-radius: 2px;
+}
+
+.mtbf-legend .legend-color {
+  background: #1890ff;
+}
+
+.mttr-legend .legend-color {
+  background: #52c41a;
+}
+
+.chart-wrapper {
   padding: 20px;
-  height: 300px;
+  height: 400px;
 }
 
 .chart {
@@ -420,45 +570,107 @@
   height: 100%;
 }
 
-.recommendation-card {
-  background: rgba(255, 255, 255, 0.95);
-  border-radius: 16px;
+/* 寤鸿鍖哄煙 */
+.recommendations-section {
+  background: white;
+  border-radius: 12px;
+  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
   overflow: hidden;
 }
 
-.card-header {
-  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
-  color: white;
-  padding: 16px 20px;
-  font-weight: 500;
-  font-size: 16px;
+.section-header {
+  padding: 24px;
+  border-bottom: 1px solid #e5e7eb;
 }
 
-.recommendation-content {
-  padding: 20px;
+.section-header h3 {
+  margin: 0 0 8px 0;
+  color: #1f2937;
+  font-size: 20px;
+  font-weight: 600;
 }
 
-.recommendation-item {
-  display: flex;
-  align-items: flex-start;
-  margin-bottom: 15px;
-  padding: 12px;
-  background: #f8f9fa;
+.section-header p {
+  margin: 0;
+  color: #6b7280;
+  font-size: 14px;
+}
+
+.recommendations-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
+  gap: 20px;
+  padding: 24px;
+}
+
+.recommendation-card {
+  background: #f8fafc;
   border-radius: 8px;
+  padding: 20px;
+  display: flex;
+  gap: 16px;
+  transition: transform 0.2s ease, box-shadow 0.2s ease;
+}
+
+.recommendation-card:hover {
+  transform: translateY(-1px);
+  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
 }
 
 .recommendation-icon {
-  font-size: 18px;
-  margin-right: 12px;
-  margin-top: 2px;
+  font-size: 24px;
+  width: 40px;
+  height: 40px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  border-radius: 8px;
+  background: white;
+  flex-shrink: 0;
 }
 
-.recommendation-text {
+.recommendation-content {
   flex: 1;
-  color: #2c3e50;
+}
+
+.recommendation-content h4 {
+  margin: 0 0 8px 0;
+  color: #1f2937;
+  font-size: 16px;
+  font-weight: 600;
+}
+
+.recommendation-content p {
+  margin: 0 0 12px 0;
+  color: #6b7280;
+  font-size: 14px;
   line-height: 1.5;
 }
 
+.recommendation-priority {
+  display: inline-block;
+  padding: 4px 8px;
+  border-radius: 4px;
+  font-size: 12px;
+  font-weight: 500;
+}
+
+.priority.high {
+  background: #fef2f2;
+  color: #dc2626;
+}
+
+.priority.medium {
+  background: #fffbeb;
+  color: #d97706;
+}
+
+.priority.low {
+  background: #f0fdf4;
+  color: #16a34a;
+}
+
+/* 鍝嶅簲寮忚璁� */
 @media (max-width: 768px) {
   .kpl-monitor-container {
     padding: 16px;
@@ -466,20 +678,37 @@
   
   .page-header {
     flex-direction: column;
-    gap: 15px;
+    gap: 16px;
     align-items: stretch;
   }
   
-  .metrics-cards {
+  .metrics-overview {
     grid-template-columns: 1fr;
   }
   
-  .charts-section {
+  .recommendations-grid {
     grid-template-columns: 1fr;
   }
   
-  .chart-container {
-    height: 250px;
+  .chart-wrapper {
+    height: 300px;
+  }
+  
+  .chart-legend {
+    flex-direction: column;
+    gap: 8px;
+  }
+}
+
+@media (max-width: 480px) {
+  .metric-card {
+    flex-direction: column;
+    text-align: center;
+  }
+  
+  .recommendation-card {
+    flex-direction: column;
+    text-align: center;
   }
 }
 </style>
\ No newline at end of file

--
Gitblit v1.9.3