From 33e6e77746eaea0fc06adb9b359b02e355887061 Mon Sep 17 00:00:00 2001
From: spring <2396852758@qq.com>
Date: 星期四, 14 八月 2025 11:03:33 +0800
Subject: [PATCH] 完成动态节能
---
src/views/energyManagement/dynamicEnergySaving/index.vue | 659 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 659 insertions(+), 0 deletions(-)
diff --git a/src/views/energyManagement/dynamicEnergySaving/index.vue b/src/views/energyManagement/dynamicEnergySaving/index.vue
new file mode 100644
index 0000000..eb6f0b1
--- /dev/null
+++ b/src/views/energyManagement/dynamicEnergySaving/index.vue
@@ -0,0 +1,659 @@
+<template>
+ <div class="app-container">
+ <!-- 杈圭紭璁$畻鐘舵�佺洃鎺� -->
+ <el-row :gutter="20" class="status-section">
+ <el-col :span="8">
+ <el-card class="status-card">
+ <div class="status-item">
+ <div class="status-icon">
+ <el-icon><Monitor /></el-icon>
+ </div>
+ <div class="status-info">
+ <div class="status-title">杈圭紭鏈嶅姟鍣ㄧ姸鎬�</div>
+ <div class="status-value" :class="edgeServerStatus.status">
+ {{ edgeServerStatus.status === 'online' ? '鍦ㄧ嚎' : '绂荤嚎' }}
+ </div>
+ <div class="status-detail">鏈�鍚庡績璺�: {{ formatTime(edgeServerStatus.lastHeartbeat) }}</div>
+ </div>
+ </div>
+ </el-card>
+ </el-col>
+ <el-col :span="8">
+ <el-card class="status-card">
+ <div class="status-item">
+ <div class="status-icon">
+ <el-icon><Cpu /></el-icon>
+ </div>
+ <div class="status-info">
+ <div class="status-title">妯″瀷杩愯鐘舵��</div>
+ <div class="status-value" :class="modelStatus.status">
+ {{ modelStatus.status === 'running' ? '杩愯涓�' : '宸插仠姝�' }}
+ </div>
+ <div class="status-detail">杩愯妯″瀷: {{ modelStatus.modelCount }}涓�</div>
+ </div>
+ </div>
+ </el-card>
+ </el-col>
+ <el-col :span="8">
+ <el-card class="status-card">
+ <div class="status-item">
+ <div class="status-icon">
+ <el-icon><TrendCharts /></el-icon>
+ </div>
+ <div class="status-info">
+ <div class="status-title">鑺傝兘鏁堟灉</div>
+ <div class="status-value success">{{ energySavingRate.toFixed(1) }}%</div>
+ <div class="status-detail">绱鑺傝兘: {{ totalEnergySaved.toFixed(1) }}kWh</div>
+ </div>
+ </div>
+ </el-card>
+ </el-col>
+ </el-row>
+
+ <!-- 娉ㄦ按娉甸鐜囦紭鍖栨帶鍒� -->
+ <el-card class="control-section">
+ <template #header>
+ <span>娉ㄦ按娉甸鐜囦紭鍖栨帶鍒�</span>
+ </template>
+
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <div class="pump-control">
+ <h4>瀹炴椂鍙傛暟鐩戞帶</h4>
+ <el-form label-width="120px">
+ <el-form-item label="鍦板眰鍘嬪姏 (MPa)">
+ <el-input v-model="pumpData.formationPressure" readonly>
+ <template #append>MPa</template>
+ </el-input>
+ </el-form-item>
+ <el-form-item label="褰撳墠娉甸�� (Hz)">
+ <el-input v-model="pumpData.currentFrequency" readonly>
+ <template #append>Hz</template>
+ </el-input>
+ </el-form-item>
+ <el-form-item label="浼樺寲鍚庢车閫� (Hz)">
+ <el-input v-model="pumpData.optimizedFrequency" readonly>
+ <template #append>Hz</template>
+ </el-input>
+ </el-form-item>
+ <el-form-item label="鑳借�楅檷浣�">
+ <el-progress
+ :percentage="pumpData.energyReduction"
+ :color="getProgressColor"
+ :format="format => `${format}%`"
+ />
+ </el-form-item>
+ <el-form-item label="娴侀噺 (m鲁/h)">
+ <el-input v-model="pumpData.flowRate" readonly>
+ <template #append>m鲁/h</template>
+ </el-input>
+ </el-form-item>
+ <el-form-item label="鍔熺巼 (kW)">
+ <el-input v-model="pumpData.power" readonly>
+ <template #append>kW</template>
+ </el-input>
+ </el-form-item>
+ </el-form>
+ </div>
+ </el-col>
+
+ <el-col :span="12">
+ <div class="pump-chart">
+ <h4>棰戠巼浼樺寲瓒嬪娍</h4>
+ <div ref="frequencyChart" style="height: 300px;"></div>
+ </div>
+ </el-col>
+ </el-row>
+
+ <el-row :gutter="20" class="control-buttons">
+ <el-col :span="24">
+ <el-button
+ type="primary"
+ :disabled="!canControl"
+ @click="applyOptimization"
+ >
+ 搴旂敤浼樺寲璁剧疆
+ </el-button>
+ <el-button
+ type="warning"
+ :disabled="!canControl"
+ @click="emergencyStop"
+ >
+ 绱ф�ュ仠姝�
+ </el-button>
+ <el-button
+ type="info"
+ @click="showOptimizationHistory"
+ >
+ 浼樺寲鍘嗗彶
+ </el-button>
+ <el-button
+ type="success"
+ @click="toggleAutoRefresh"
+ >
+ {{ autoRefreshStatus ? '鍋滄鑷姩鍒锋柊' : '寮�鍚嚜鍔ㄥ埛鏂�' }}
+ </el-button>
+ </el-col>
+ </el-row>
+ </el-card>
+
+ <!-- 杈圭紭璁$畻妯″瀷閰嶇疆 -->
+ <el-card class="model-section">
+ <template #header>
+ <span>杈圭紭璁$畻妯″瀷閰嶇疆</span>
+ </template>
+
+ <el-table :data="modelConfigs" style="width: 100%">
+ <el-table-column prop="modelName" label="妯″瀷鍚嶇О" />
+ <el-table-column prop="version" label="鐗堟湰" />
+ <el-table-column prop="status" label="鐘舵��">
+ <template #default="scope">
+ <el-tag :type="scope.row.status === 'active' ? 'success' : 'info'">
+ {{ scope.row.status === 'active' ? '婵�娲�' : '寰呮満' }}
+ </el-tag>
+ </template>
+ </el-table-column>
+ <el-table-column prop="accuracy" label="鍑嗙‘鐜�" />
+ <el-table-column prop="lastUpdate" label="鏈�鍚庢洿鏂�" />
+ <el-table-column label="鎿嶄綔">
+ <template #default="scope">
+ <el-button
+ size="small"
+ @click="updateModel(scope.row)"
+ >
+ 鏇存柊妯″瀷
+ </el-button>
+ <el-button
+ size="small"
+ type="danger"
+ @click="deleteModel(scope.row)"
+ >
+ 鍒犻櫎
+ </el-button>
+ </template>
+ </el-table-column>
+ </el-table>
+ </el-card>
+
+ <!-- 鑳借�楀垎鏋愬浘琛� -->
+ <el-card class="analysis-section">
+ <template #header>
+ <span>鑳借�楀垎鏋�</span>
+ </template>
+
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <div ref="energyChart" style="height: 400px;"></div>
+ </el-col>
+ <el-col :span="12">
+ <div ref="savingChart" style="height: 400px;"></div>
+ </el-col>
+ </el-row>
+ </el-card>
+
+ <!-- 浼樺寲鍘嗗彶瀵硅瘽妗� -->
+ <el-dialog v-model="historyDialogVisible" title="浼樺寲鍘嗗彶璁板綍" width="80%">
+ <el-table :data="optimizationHistory" style="width: 100%">
+ <el-table-column prop="timestamp" label="鏃堕棿" />
+ <el-table-column prop="formationPressure" label="鍦板眰鍘嬪姏 (MPa)" />
+ <el-table-column prop="oldFrequency" label="鍘熼鐜� (Hz)" />
+ <el-table-column prop="newFrequency" label="鏂伴鐜� (Hz)" />
+ <el-table-column prop="energySaved" label="鑺傝兘 (kWh)" />
+ <el-table-column prop="status" label="鐘舵��">
+ <template #default="scope">
+ <el-tag :type="scope.row.status === 'success' ? 'success' : 'warning'">
+ {{ scope.row.status === 'success' ? '鎴愬姛' : '澶辫触' }}
+ </el-tag>
+ </template>
+ </el-table-column>
+ </el-table>
+ </el-dialog>
+ </div>
+</template>
+
+<script setup>
+import { ref, onMounted, onUnmounted, computed } from 'vue'
+import { ElMessage, ElMessageBox } from 'element-plus'
+import { Monitor, Cpu, TrendCharts } from '@element-plus/icons-vue'
+import * as echarts from 'echarts'
+
+// 鍝嶅簲寮忔暟鎹�
+const edgeServerStatus = ref({ status: 'online', lastHeartbeat: Date.now() })
+const modelStatus = ref({ status: 'running', modelCount: 3 })
+const energySavingRate = ref(15.8)
+const totalEnergySaved = ref(1250.5)
+const pumpData = ref({
+ formationPressure: 25.6,
+ currentFrequency: 45.2,
+ optimizedFrequency: 42.1,
+ energyReduction: 23,
+ flowRate: 180.5,
+ power: 85.3
+})
+
+const modelConfigs = ref([
+ {
+ modelName: '娉ㄦ按娉甸鐜囦紭鍖栨ā鍨�',
+ version: 'v2.1.0',
+ status: 'active',
+ accuracy: '94.2%',
+ lastUpdate: '2024-01-15 14:30:00'
+ },
+ {
+ modelName: '鍦板眰鍘嬪姏棰勬祴妯″瀷',
+ version: 'v1.8.5',
+ status: 'active',
+ accuracy: '91.7%',
+ lastUpdate: '2024-01-14 09:15:00'
+ },
+ {
+ modelName: '鑳借�楀垎鏋愭ā鍨�',
+ version: 'v2.0.3',
+ status: 'standby',
+ accuracy: '89.3%',
+ lastUpdate: '2024-01-13 16:45:00'
+ }
+])
+
+const historyDialogVisible = ref(false)
+const optimizationHistory = ref([])
+
+// 鍥捐〃寮曠敤
+const frequencyChart = ref(null)
+const energyChart = ref(null)
+const savingChart = ref(null)
+
+// 鑷姩鍒锋柊鐩稿叧
+const autoRefreshStatus = ref(true)
+const autoRefreshTimer = ref(null)
+const chartInstances = ref([])
+
+// 璁$畻灞炴��
+const canControl = computed(() => {
+ return edgeServerStatus.value.status === 'online' && modelStatus.value.status === 'running'
+})
+
+const getProgressColor = computed(() => {
+ return (percentage) => {
+ if (percentage < 20) return '#909399'
+ if (percentage < 40) return '#E6A23C'
+ if (percentage < 60) return '#409EFF'
+ return '#67C23A'
+ }
+})
+
+// 鐢熸垚妯℃嫙鏁版嵁
+const generateMockData = () => {
+ // 鐢熸垚闅忔満鍦板眰鍘嬪姏 (20-30 MPa)
+ const formationPressure = 20 + Math.random() * 10
+
+ // 鏍规嵁鍦板眰鍘嬪姏璁$畻浼樺寲棰戠巼
+ const baseFrequency = 40 + (formationPressure - 25) * 2
+ const currentFrequency = baseFrequency + (Math.random() - 0.5) * 4
+ const optimizedFrequency = Math.max(35, baseFrequency - Math.random() * 3)
+
+ // 璁$畻鑳借�楅檷浣�
+ const energyReduction = Math.round((currentFrequency - optimizedFrequency) / currentFrequency * 100)
+
+ // 璁$畻娴侀噺鍜屽姛鐜�
+ const flowRate = 150 + Math.random() * 60
+ const power = 70 + Math.random() * 30
+
+ // 鏇存柊娉垫暟鎹�
+ pumpData.value = {
+ formationPressure: parseFloat(formationPressure.toFixed(1)),
+ currentFrequency: parseFloat(currentFrequency.toFixed(1)),
+ optimizedFrequency: parseFloat(optimizedFrequency.toFixed(1)),
+ energyReduction: Math.min(energyReduction, 35),
+ flowRate: parseFloat(flowRate.toFixed(1)),
+ power: parseFloat(power.toFixed(1))
+ }
+
+ // 鏇存柊鑺傝兘鏁堟灉
+ energySavingRate.value = 12 + Math.random() * 8
+ totalEnergySaved.value += Math.random() * 2
+
+ // 鏇存柊杈圭紭鏈嶅姟鍣ㄧ姸鎬�
+ edgeServerStatus.value.lastHeartbeat = Date.now()
+
+ // 闅忔満鏇存柊妯″瀷鐘舵��
+ if (Math.random() > 0.95) {
+ modelStatus.value.modelCount = Math.max(1, modelStatus.value.modelCount + (Math.random() > 0.5 ? 1 : -1))
+ }
+
+ // 娣诲姞浼樺寲鍘嗗彶璁板綍
+ if (Math.random() > 0.7) {
+ addOptimizationHistory()
+ }
+
+ // 鏇存柊鍥捐〃鏁版嵁
+ updateCharts()
+}
+
+// 娣诲姞浼樺寲鍘嗗彶璁板綍
+const addOptimizationHistory = () => {
+ const timestamp = new Date().toLocaleString()
+ const record = {
+ timestamp,
+ formationPressure: pumpData.value.formationPressure,
+ oldFrequency: pumpData.value.currentFrequency,
+ newFrequency: pumpData.value.optimizedFrequency,
+ energySaved: parseFloat((Math.random() * 5 + 1).toFixed(2)),
+ status: Math.random() > 0.1 ? 'success' : 'failed'
+ }
+
+ optimizationHistory.value.unshift(record)
+
+ // 淇濇寔鏈�澶�100鏉¤褰�
+ if (optimizationHistory.value.length > 100) {
+ optimizationHistory.value = optimizationHistory.value.slice(0, 100)
+ }
+}
+
+// 鏇存柊鍥捐〃鏁版嵁
+const updateCharts = () => {
+ chartInstances.value.forEach(instance => {
+ if (instance && instance.setOption) {
+ // 杩欓噷鍙互鏇存柊鍥捐〃鏁版嵁
+ // 涓轰簡绠�鍖栵紝鎴戜滑鍙槸閲嶆柊鍒濆鍖栧浘琛�
+ }
+ })
+}
+
+// 鏂规硶
+const refreshData = () => {
+ generateMockData()
+ ElMessage.success('鏁版嵁鍒锋柊鎴愬姛')
+}
+
+const applyOptimization = async () => {
+ try {
+ await ElMessageBox.confirm('纭畾瑕佸簲鐢ㄥ綋鍓嶇殑浼樺寲璁剧疆鍚楋紵', '纭鎿嶄綔', {
+ confirmButtonText: '纭畾',
+ cancelButtonText: '鍙栨秷',
+ type: 'warning'
+ })
+
+ // 搴旂敤浼樺寲璁剧疆
+ pumpData.value.currentFrequency = pumpData.value.optimizedFrequency
+ ElMessage.success('浼樺寲璁剧疆搴旂敤鎴愬姛')
+ refreshData()
+ } catch (error) {
+ if (error !== 'cancel') {
+ ElMessage.error('搴旂敤浼樺寲璁剧疆澶辫触')
+ }
+ }
+}
+
+const emergencyStop = async () => {
+ try {
+ await ElMessageBox.confirm('纭畾瑕佺揣鎬ュ仠姝㈡墍鏈夋敞姘存车鍚楋紵', '绱ф�ユ搷浣�', {
+ confirmButtonText: '纭畾',
+ cancelButtonText: '鍙栨秷',
+ type: 'error'
+ })
+
+ // 鎵ц绱ф�ュ仠姝㈤�昏緫
+ pumpData.value.currentFrequency = 0
+ pumpData.value.optimizedFrequency = 0
+ ElMessage.success('绱ф�ュ仠姝㈡墽琛屾垚鍔�')
+ } catch (error) {
+ if (error !== 'cancel') {
+ ElMessage.error('绱ф�ュ仠姝㈡墽琛屽け璐�')
+ }
+ }
+}
+
+const showOptimizationHistory = () => {
+ historyDialogVisible.value = true
+}
+
+const updateModel = (model) => {
+ ElMessage.info(`鏇存柊妯″瀷: ${model.modelName}`)
+}
+
+const deleteModel = async (model) => {
+ try {
+ await ElMessageBox.confirm(`纭畾瑕佸垹闄ゆā鍨� ${model.modelName} 鍚楋紵`, '纭鍒犻櫎', {
+ confirmButtonText: '纭畾',
+ cancelButtonText: '鍙栨秷',
+ type: 'warning'
+ })
+
+ const index = modelConfigs.value.findIndex(m => m.modelName === model.modelName)
+ if (index > -1) {
+ modelConfigs.value.splice(index, 1)
+ ElMessage.success('妯″瀷鍒犻櫎鎴愬姛')
+ }
+ } catch (error) {
+ if (error !== 'cancel') {
+ ElMessage.error('妯″瀷鍒犻櫎澶辫触')
+ }
+ }
+}
+
+const toggleAutoRefresh = () => {
+ autoRefreshStatus.value = !autoRefreshStatus.value
+ if (autoRefreshStatus.value) {
+ startAutoRefresh()
+ ElMessage.success('鑷姩鍒锋柊宸插紑鍚�')
+ } else {
+ stopAutoRefresh()
+ ElMessage.info('鑷姩鍒锋柊宸插叧闂�')
+ }
+}
+
+const startAutoRefresh = () => {
+ stopAutoRefresh() // 鍏堝仠姝箣鍓嶇殑瀹氭椂鍣�
+ autoRefreshTimer.value = setInterval(() => {
+ generateMockData()
+ }, 60000) // 1鍒嗛挓 = 60000姣
+}
+
+const stopAutoRefresh = () => {
+ if (autoRefreshTimer.value) {
+ clearInterval(autoRefreshTimer.value)
+ autoRefreshTimer.value = null
+ }
+}
+
+const formatTime = (timestamp) => {
+ return new Date(timestamp).toLocaleTimeString()
+}
+
+// 鍒濆鍖栧浘琛�
+const initCharts = () => {
+ // 棰戠巼浼樺寲瓒嬪娍鍥�
+ const frequencyChartInstance = echarts.init(frequencyChart.value)
+ const frequencyOption = {
+ title: { text: '娉甸鐜囦紭鍖栬秼鍔�' },
+ tooltip: { trigger: 'axis' },
+ legend: { data: ['褰撳墠棰戠巼', '浼樺寲棰戠巼', '鍦板眰鍘嬪姏'] },
+ xAxis: { type: 'category', data: ['00:00', '04:00', '08:00', '12:00', '16:00', '20:00'] },
+ yAxis: [
+ { type: 'value', name: '棰戠巼 (Hz)' },
+ { type: 'value', name: '鍘嬪姏 (MPa)' }
+ ],
+ series: [
+ {
+ name: '褰撳墠棰戠巼',
+ type: 'line',
+ data: [45.2, 44.8, 45.5, 45.1, 44.9, 45.2]
+ },
+ {
+ name: '浼樺寲棰戠巼',
+ type: 'line',
+ data: [42.1, 41.8, 42.3, 41.9, 41.7, 42.1]
+ },
+ {
+ name: '鍦板眰鍘嬪姏',
+ type: 'line',
+ yAxisIndex: 1,
+ data: [25.6, 25.8, 26.1, 25.9, 25.7, 25.6]
+ }
+ ]
+ }
+ frequencyChartInstance.setOption(frequencyOption)
+ chartInstances.value.push(frequencyChartInstance)
+
+ // 鑳借�楀垎鏋愬浘
+ const energyChartInstance = echarts.init(energyChart.value)
+ const energyOption = {
+ title: { text: '鏃ヨ兘鑰楀姣�' },
+ tooltip: { trigger: 'item' },
+ legend: { orient: 'vertical', left: 'left',top: 'center' },
+ series: [
+ {
+ name: '鑳借�楀垎甯�',
+ type: 'pie',
+ radius: '50%',
+ data: [
+ { value: 45, name: '娉ㄦ按娉�' },
+ { value: 25, name: '鐓ф槑绯荤粺' },
+ { value: 20, name: '閫氶绯荤粺' },
+ { value: 10, name: '鍏朵粬璁惧' }
+ ]
+ }
+ ]
+ }
+ energyChartInstance.setOption(energyOption)
+ chartInstances.value.push(energyChartInstance)
+
+ // 鑺傝兘鏁堟灉鍥�
+ const savingChartInstance = echarts.init(savingChart.value)
+ const savingOption = {
+ title: { text: '鑺傝兘鏁堟灉瓒嬪娍' },
+ tooltip: { trigger: 'axis' },
+ xAxis: { type: 'category', data: ['鍛ㄤ竴', '鍛ㄤ簩', '鍛ㄤ笁', '鍛ㄥ洓', '鍛ㄤ簲', '鍛ㄥ叚', '鍛ㄦ棩'] },
+ yAxis: { type: 'value', name: '鑺傝兘鐜� (%)' },
+ series: [
+ {
+ name: '鑺傝兘鐜�',
+ type: 'bar',
+ data: [12.5, 15.2, 18.7, 16.3, 19.1, 17.8, 15.8]
+ }
+ ]
+ }
+ savingChartInstance.setOption(savingOption)
+ chartInstances.value.push(savingChartInstance)
+}
+
+// 鐢熸垚鍒濆鍘嗗彶鏁版嵁
+const generateInitialHistory = () => {
+ for (let i = 0; i < 20; i++) {
+ const timestamp = new Date(Date.now() - i * 3600000).toLocaleString()
+ const record = {
+ timestamp,
+ formationPressure: parseFloat((20 + Math.random() * 10).toFixed(1)),
+ oldFrequency: parseFloat((40 + Math.random() * 10).toFixed(1)),
+ newFrequency: parseFloat((35 + Math.random() * 8).toFixed(1)),
+ energySaved: parseFloat((Math.random() * 5 + 1).toFixed(2)),
+ status: Math.random() > 0.1 ? 'success' : 'failed'
+ }
+ optimizationHistory.value.push(record)
+ }
+}
+
+// 鐢熷懡鍛ㄦ湡
+onMounted(() => {
+ initCharts()
+ generateInitialHistory()
+ refreshData()
+ if (autoRefreshStatus.value) {
+ startAutoRefresh()
+ }
+})
+
+onUnmounted(() => {
+ stopAutoRefresh()
+ chartInstances.value.forEach(instance => {
+ if (instance && instance.dispose) {
+ instance.dispose()
+ }
+ })
+})
+</script>
+
+<style scoped>
+.app-container {
+ padding: 20px;
+}
+
+
+
+.status-section {
+ margin-bottom: 20px;
+}
+
+.status-card {
+ height: 140px;
+}
+
+.status-item {
+ display: flex;
+ align-items: center;
+ height: 100%;
+}
+
+.status-icon {
+ font-size: 48px;
+ margin-right: 20px;
+ color: #409EFF;
+}
+
+.status-info {
+ flex: 1;
+}
+
+.status-title {
+ font-size: 14px;
+ color: #909399;
+ margin-bottom: 8px;
+}
+
+.status-value {
+ font-size: 24px;
+ font-weight: bold;
+ margin-bottom: 8px;
+}
+
+.status-detail {
+ font-size: 12px;
+ color: #909399;
+}
+
+.status-value.online,
+.status-value.running {
+ color: #67C23A;
+}
+
+.status-value.offline,
+.status-value.stopped {
+ color: #F56C6C;
+}
+
+.status-value.success {
+ color: #67C23A;
+}
+
+.control-section,
+.model-section,
+.analysis-section {
+ margin-bottom: 20px;
+}
+
+.pump-control h4,
+.pump-chart h4 {
+ margin-bottom: 20px;
+ color: #303133;
+}
+
+.control-buttons {
+ margin-top: 20px;
+ text-align: center;
+}
+
+.control-buttons .el-button {
+ margin: 0 10px;
+}
+</style>
--
Gitblit v1.9.3