From bb175f417a29f1e9b41533df9e8239f25ab071b8 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期四, 25 九月 2025 14:22:44 +0800
Subject: [PATCH] 部署修改

---
 multiple/assets/favicon/JLMYico.ico                |    0 
 multiple/assets/favicon/JLSNico.ico                |    0 
 multiple/assets/logo/JLSNLogo.png                  |    0 
 multiple/assets/screen/JLSNView.png                |    0 
 multiple/config.json                               |   10 +
 multiple/assets/logo/JLMYLogo.png                  |    0 
 src/views/equipmentManagement/kplMonitor/index.vue |  485 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 7 files changed, 495 insertions(+), 0 deletions(-)

diff --git a/multiple/assets/favicon/JLMYico.ico b/multiple/assets/favicon/JLMYico.ico
new file mode 100644
index 0000000..c41fc33
--- /dev/null
+++ b/multiple/assets/favicon/JLMYico.ico
Binary files differ
diff --git a/multiple/assets/favicon/JLSNico.ico b/multiple/assets/favicon/JLSNico.ico
new file mode 100644
index 0000000..ea7aed7
--- /dev/null
+++ b/multiple/assets/favicon/JLSNico.ico
Binary files differ
diff --git a/multiple/assets/logo/JLMYLogo.png b/multiple/assets/logo/JLMYLogo.png
new file mode 100644
index 0000000..4a09b97
--- /dev/null
+++ b/multiple/assets/logo/JLMYLogo.png
Binary files differ
diff --git a/multiple/assets/logo/JLSNLogo.png b/multiple/assets/logo/JLSNLogo.png
new file mode 100644
index 0000000..ff94cd7
--- /dev/null
+++ b/multiple/assets/logo/JLSNLogo.png
Binary files differ
diff --git a/multiple/assets/screen/JLSNView.png b/multiple/assets/screen/JLSNView.png
new file mode 100644
index 0000000..663b5d5
--- /dev/null
+++ b/multiple/assets/screen/JLSNView.png
Binary files differ
diff --git a/multiple/config.json b/multiple/config.json
index 60cc61c..4b07b48 100644
--- a/multiple/config.json
+++ b/multiple/config.json
@@ -187,6 +187,16 @@
     "logo": "logo/HCKXLogo.png",
     "favicon": "favicon/HCKXico.ico"
   },
+  "JLSN": {
+    "env": {
+      "VITE_APP_TITLE": "閿﹂緳姘存偿淇℃伅绠$悊绯荤粺",
+      "VITE_BASE_API": "http://114.132.189.42:9094",
+      "VITE_JAVA_API": "http://114.132.189.42:9093"
+    },
+    "screen": "screen/JLSNView.png",
+    "logo": "logo/JLSNLogo.png",
+    "favicon": "favicon/JLSNico.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
new file mode 100644
index 0000000..4d305f3
--- /dev/null
+++ b/src/views/equipmentManagement/kplMonitor/index.vue
@@ -0,0 +1,485 @@
+<template>
+  <div class="kpl-monitor-container">
+    <div class="page-header">
+      <h1>KPL鐩戞帶鍒嗘瀽</h1>
+      <div class="time-range">
+        <el-date-picker
+          v-model="timeRange"
+          type="daterange"
+          range-separator="鑷�"
+          start-placeholder="寮�濮嬫棩鏈�"
+          end-placeholder="缁撴潫鏃ユ湡"
+          value-format="YYYY-MM-DD"
+          @change="fetchKPLData"
+        />
+      </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>
+      </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>
+      </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>
+      </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>
+      </div>
+
+      <div class="chart-card">
+        <div class="chart-header">MTTR瓒嬪娍鍒嗘瀽</div>
+        <div class="chart-container">
+          <div ref="mttrChart" class="chart"></div>
+        </div>
+      </div>
+    </div>
+
+    <!-- 浼樺寲寤鸿 -->
+    <div class="recommendation-card">
+      <div class="card-header">缁翠繚绛栫暐浼樺寲寤鸿</div>
+      <div class="recommendation-content">
+        <div 
+          v-for="(recommendation, index) in recommendations" 
+          :key="index"
+          class="recommendation-item"
+        >
+          <div class="recommendation-icon">馃挕</div>
+          <div class="recommendation-text">{{ recommendation }}</div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup>
+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灏忔椂
+  const mttrData = months.map(() => Math.floor(Math.random() * 8 + 4)) // 4-12灏忔椂
+  
+  return {
+    months,
+    mtbfData,
+    mttrData
+  }
+}
+
+const timeRange = ref([
+  new Date(new Date().getFullYear(), 0, 1).toISOString().split('T')[0],
+  new Date().toISOString().split('T')[0]
+])
+
+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(() => {
+  const current = currentMTBF.value
+  const previous = mockData.mtbfData[mockData.mtbfData.length - 2] || current
+  return Math.round(((current - previous) / previous) * 100)
+})
+
+const mttrChange = computed(() => {
+  const current = currentMTTR.value
+  const previous = mockData.mttrData[mockData.mttrData.length - 2] || current
+  return Math.round(((current - previous) / previous) * 100)
+})
+
+const availabilityChange = computed(() => {
+  const current = currentAvailability.value
+  const previous = Math.round(
+    (mockData.mtbfData[mockData.mtbfData.length - 2] / 
+    (mockData.mtbfData[mockData.mtbfData.length - 2] + mockData.mttrData[mockData.mttrData.length - 2])) * 100
+  ) || current
+  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 recommendations = computed(() => {
+  const suggestions = []
+  
+  if (currentMTBF.value < 400) {
+    suggestions.push('MTBF杈冧綆锛屽缓璁姞寮洪闃叉�х淮鎶わ紝瀹氭湡妫�鏌ュ叧閿儴浠�')
+  }
+  
+  if (currentMTTR.value > 8) {
+    suggestions.push('MTTR杈冮珮锛屽缓璁紭鍖栫淮淇祦绋嬶紝鎻愰珮缁翠慨鏁堢巼')
+  }
+  
+  if (currentAvailability.value < 95) {
+    suggestions.push('璁惧鍙敤鐜囨湁寰呮彁鍗囷紝寤鸿浼樺寲缁翠繚璁″垝瀹夋帓')
+  }
+  
+  if (currentFailures.value > 8) {
+    suggestions.push('鏁呴殰娆℃暟杈冨锛屽缓璁姞寮鸿澶囨棩甯稿贰妫�')
+  }
+  
+  if (suggestions.length === 0) {
+    suggestions.push('褰撳墠璁惧杩愯鐘跺喌鑹ソ锛岀户缁繚鎸佺幇鏈夌淮淇濈瓥鐣�')
+  }
+  
+  return suggestions
+})
+
+// 鍥捐〃瀹炰緥
+let mtbfChart = null
+let mttrChart = null
+
+const initCharts = () => {
+  nextTick(() => {
+    // MTBF鍥捐〃
+    mtbfChart = echarts.init(document.querySelector('.chart-card:first-child .chart'))
+    mtbfChart.setOption({
+      tooltip: {
+        trigger: 'axis'
+      },
+      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)' }
+          ])
+        }
+      }]
+    })
+
+    // 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'
+        },
+        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)' }
+          ])
+        }
+      }]
+    })
+  })
+}
+
+const fetchKPLData = () => {
+  // 妯℃嫙鏁版嵁鍒锋柊
+  Object.assign(mockData, generateMockData())
+  
+  // 閲嶆柊娓叉煋鍥捐〃
+  if (mtbfChart && mttrChart) {
+    mtbfChart.setOption({
+      xAxis: {
+        data: mockData.months
+      },
+      series: [{
+        data: mockData.mtbfData
+      }]
+    })
+    
+    mttrChart.setOption({
+      xAxis: {
+        data: mockData.months
+      },
+      series: [{
+        data: mockData.mttrData
+      }]
+    })
+  }
+}
+
+onMounted(() => {
+  initCharts()
+  
+  // 鐩戝惉绐楀彛澶у皬鍙樺寲锛岄噸鏂拌皟鏁村浘琛ㄥぇ灏�
+  window.addEventListener('resize', () => {
+    if (mtbfChart) mtbfChart.resize()
+    if (mttrChart) mttrChart.resize()
+  })
+})
+</script>
+
+<style scoped>
+.kpl-monitor-container {
+  min-height: 100vh;
+  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+  padding: 20px;
+  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;
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+
+.page-header h1 {
+  margin: 0;
+  color: #2c3e50;
+  font-size: 24px;
+}
+
+.time-range {
+  display: flex;
+  align-items: center;
+  gap: 10px;
+}
+
+.metrics-cards {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
+  gap: 20px;
+  margin-bottom: 20px;
+}
+
+.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);
+}
+
+.metric-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 15px;
+}
+
+.metric-title {
+  font-size: 16px;
+  color: #666;
+  font-weight: 500;
+}
+
+.metric-trend {
+  font-size: 14px;
+  font-weight: 600;
+}
+
+.trend-up {
+  color: #52c41a;
+}
+
+.trend-down {
+  color: #ff4d4f;
+}
+
+.metric-value {
+  font-size: 32px;
+  font-weight: 700;
+  color: #2c3e50;
+  margin-bottom: 8px;
+}
+
+.metric-change {
+  font-size: 14px;
+  color: #666;
+}
+
+.charts-section {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(500px, 1fr));
+  gap: 20px;
+  margin-bottom: 20px;
+}
+
+.chart-card {
+  background: rgba(255, 255, 255, 0.95);
+  border-radius: 16px;
+  overflow: hidden;
+}
+
+.chart-header {
+  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+  color: white;
+  padding: 16px 20px;
+  font-weight: 500;
+  font-size: 16px;
+}
+
+.chart-container {
+  padding: 20px;
+  height: 300px;
+}
+
+.chart {
+  width: 100%;
+  height: 100%;
+}
+
+.recommendation-card {
+  background: rgba(255, 255, 255, 0.95);
+  border-radius: 16px;
+  overflow: hidden;
+}
+
+.card-header {
+  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+  color: white;
+  padding: 16px 20px;
+  font-weight: 500;
+  font-size: 16px;
+}
+
+.recommendation-content {
+  padding: 20px;
+}
+
+.recommendation-item {
+  display: flex;
+  align-items: flex-start;
+  margin-bottom: 15px;
+  padding: 12px;
+  background: #f8f9fa;
+  border-radius: 8px;
+}
+
+.recommendation-icon {
+  font-size: 18px;
+  margin-right: 12px;
+  margin-top: 2px;
+}
+
+.recommendation-text {
+  flex: 1;
+  color: #2c3e50;
+  line-height: 1.5;
+}
+
+@media (max-width: 768px) {
+  .kpl-monitor-container {
+    padding: 16px;
+  }
+  
+  .page-header {
+    flex-direction: column;
+    gap: 15px;
+    align-items: stretch;
+  }
+  
+  .metrics-cards {
+    grid-template-columns: 1fr;
+  }
+  
+  .charts-section {
+    grid-template-columns: 1fr;
+  }
+  
+  .chart-container {
+    height: 250px;
+  }
+}
+</style>
\ No newline at end of file

--
Gitblit v1.9.3