From 64adb432af57444f42c6b6b8236dad80d05927dd Mon Sep 17 00:00:00 2001
From: spring <2396852758@qq.com>
Date: 星期三, 13 八月 2025 16:19:52 +0800
Subject: [PATCH] 完成用气管理
---
src/views/energyManagement/gasManagement/index.vue | 624 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 624 insertions(+), 0 deletions(-)
diff --git a/src/views/energyManagement/gasManagement/index.vue b/src/views/energyManagement/gasManagement/index.vue
new file mode 100644
index 0000000..fbbd9f4
--- /dev/null
+++ b/src/views/energyManagement/gasManagement/index.vue
@@ -0,0 +1,624 @@
+<template>
+ <div class="app-container">
+ <!-- 椤甸潰鏍囬 -->
+ <div class="page-header">
+ <h2>鐢ㄦ皵绠$悊绯荤粺</h2>
+ <div class="header-info">
+ <span class="update-time">鏈�鍚庢洿鏂帮細{{ lastUpdateTime }}</span>
+ <el-button type="primary" size="small" @click="refreshData">
+ <el-icon><Refresh /></el-icon>
+ 鍒锋柊鏁版嵁
+ </el-button>
+ </div>
+ </div>
+
+ <!-- 缁熻鍗$墖鍖哄煙 -->
+ <div class="stats-cards">
+ <el-row :gutter="20">
+ <el-col :span="6">
+ <el-card class="stat-card">
+ <div class="stat-content">
+ <div class="stat-icon gas-device">
+ <el-icon size="32"><Box /></el-icon>
+ </div>
+ <div class="stat-info">
+ <div class="stat-value">{{ totalDevices }}</div>
+ <div class="stat-label">鍦ㄧ敤璁惧</div>
+ </div>
+ </div>
+ </el-card>
+ </el-col>
+ <el-col :span="6">
+ <el-card class="stat-card">
+ <div class="stat-content">
+ <div class="stat-icon daily-consumption">
+ <el-icon size="32"><TrendCharts /></el-icon>
+ </div>
+ <div class="stat-info">
+ <div class="stat-value">{{ dailyConsumption }} m鲁</div>
+ <div class="stat-label">鏃ヨ�楅噺</div>
+ </div>
+ </div>
+ </el-card>
+ </el-col>
+ <el-col :span="6">
+ <el-card class="stat-card">
+ <div class="stat-content">
+ <div class="stat-icon monthly-consumption">
+ <el-icon size="32"><DataLine /></el-icon>
+ </div>
+ <div class="stat-info">
+ <div class="stat-value">{{ monthlyConsumption }} m鲁</div>
+ <div class="stat-label">鏈堣�楅噺</div>
+ </div>
+ </div>
+ </el-card>
+ </el-col>
+ <el-col :span="6">
+ <el-card class="stat-card">
+ <div class="stat-content">
+ <div class="stat-icon gas-price">
+ <el-icon size="32"><Money /></el-icon>
+ </div>
+ <div class="stat-info">
+ <div class="stat-value">楼{{ gasUnitPrice }}</div>
+ <div class="stat-label">姘斾綋鍗曚环</div>
+ </div>
+ </div>
+ </el-card>
+ </el-col>
+ </el-row>
+ </div>
+
+ <!-- 璐圭敤缁熻鍖哄煙 -->
+ <div class="cost-stats">
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-card class="cost-card">
+ <template #header>
+ <div class="card-header">
+ <span>鏃ヨ垂鐢ㄧ粺璁�</span>
+ <el-tag type="success" size="small">浠婃棩</el-tag>
+ </div>
+ </template>
+ <div class="cost-content">
+ <div class="cost-main">
+ <span class="cost-amount">楼{{ dailyTotalCost.toFixed(2) }}</span>
+ <span class="cost-unit">鍏�</span>
+ </div>
+ <div class="cost-details">
+ <div class="cost-item">
+ <span>娑堣�楅噺锛�</span>
+ <span>{{ dailyConsumption }} m鲁</span>
+ </div>
+ <div class="cost-item">
+ <span>鍗曚环锛�</span>
+ <span>楼{{ gasUnitPrice }}/m鲁</span>
+ </div>
+ </div>
+ </div>
+ </el-card>
+ </el-col>
+ <el-col :span="12">
+ <el-card class="cost-card">
+ <template #header>
+ <div class="card-header">
+ <span>鏈堣垂鐢ㄧ粺璁�</span>
+ <el-tag type="primary" size="small">鏈湀</el-tag>
+ </div>
+ </template>
+ <div class="cost-content">
+ <div class="cost-main">
+ <span class="cost-amount">楼{{ monthlyTotalCost.toFixed(2) }}</span>
+ <span class="cost-unit">鍏�</span>
+ </div>
+ <div class="cost-details">
+ <div class="cost-item">
+ <span>娑堣�楅噺锛�</span>
+ <span>{{ monthlyConsumption }} m鲁</span>
+ </div>
+ <div class="cost-item">
+ <span>骞冲潎鍗曚环锛�</span>
+ <span>楼{{ gasUnitPrice }}/m鲁</span>
+ </div>
+ </div>
+ </div>
+ </el-card>
+ </el-col>
+ </el-row>
+ </div>
+
+ <!-- 璁惧鍒楄〃鍖哄煙 -->
+ <div class="device-section">
+ <el-card>
+ <template #header>
+ <div class="card-header">
+ <span>璁惧鐩戞帶</span>
+ <div class="header-actions">
+ <el-button type="primary" size="small" @click="addDevice">
+ <el-icon><Plus /></el-icon>
+ 娣诲姞璁惧
+ </el-button>
+ </div>
+ </div>
+ </template>
+
+ <el-table :data="deviceList" border style="width: 100%" v-loading="tableLoading">
+ <el-table-column align="center" label="搴忓彿" type="index" width="60" />
+ <el-table-column label="璁惧缂栧彿" prop="deviceCode" width="120" show-overflow-tooltip />
+ <el-table-column label="璁惧鍚嶇О" prop="deviceName" width="150" show-overflow-tooltip />
+ <el-table-column label="璁惧绫诲瀷" prop="deviceType" width="120" show-overflow-tooltip />
+ <el-table-column label="瑙勬牸鍨嬪彿" prop="specification" width="150" show-overflow-tooltip />
+ <el-table-column label="褰撳墠鍘嬪姏(MPa)" prop="currentPressure" width="130" show-overflow-tooltip>
+ <template #default="scope">
+ <span :class="getPressureClass(scope.row.currentPressure)">
+ {{ scope.row.currentPressure }}
+ </span>
+ </template>
+ </el-table-column>
+ <el-table-column label="褰撳墠娓╁害(鈩�)" prop="currentTemperature" width="130" show-overflow-tooltip>
+ <template #default="scope">
+ <span :class="getTemperatureClass(scope.row.currentTemperature)">
+ {{ scope.row.currentTemperature }}
+ </span>
+ </template>
+ </el-table-column>
+ <el-table-column label="姘斾綋娴撳害(ppm)" prop="gasConcentration" width="140" show-overflow-tooltip>
+ <template #default="scope">
+ <span :class="getConcentrationClass(scope.row.gasConcentration)">
+ {{ scope.row.gasConcentration }}
+ </span>
+ </template>
+ </el-table-column>
+ <el-table-column label="杩愯鐘舵��" prop="status" width="100" show-overflow-tooltip>
+ <template #default="scope">
+ <el-tag :type="getStatusType(scope.row.status)" size="small">
+ {{ getStatusText(scope.row.status) }}
+ </el-tag>
+ </template>
+ </el-table-column>
+ <el-table-column label="鏈�鍚庢洿鏂�" prop="lastUpdate" width="160" show-overflow-tooltip />
+ <el-table-column label="鎿嶄綔" align="center" width="100" fixed="right">
+ <template #default="scope">
+ <el-button link size="small" @click="editDevice(scope.row)">
+ 缂栬緫
+ </el-button>
+ </template>
+ </el-table-column>
+ </el-table>
+ </el-card>
+ </div>
+
+ <!-- 娣诲姞/缂栬緫璁惧寮圭獥 -->
+ <el-dialog v-model="deviceDialogVisible" :title="dialogTitle" width="600px">
+ <el-form :model="deviceForm" :rules="deviceRules" ref="deviceFormRef" label-width="120px">
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="璁惧缂栧彿" prop="deviceCode">
+ <el-input v-model="deviceForm.deviceCode" placeholder="璇疯緭鍏ヨ澶囩紪鍙�" />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="璁惧鍚嶇О" prop="deviceName">
+ <el-input v-model="deviceForm.deviceName" placeholder="璇疯緭鍏ヨ澶囧悕绉�" />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="璁惧绫诲瀷" prop="deviceType">
+ <el-select v-model="deviceForm.deviceType" placeholder="璇烽�夋嫨璁惧绫诲瀷" style="width: 100%">
+ <el-option label="娑插寲姘斿偍缃�" value="娑插寲姘斿偍缃�" />
+ <el-option label="鍘嬬缉姘斿偍缃�" value="鍘嬬缉姘斿偍缃�" />
+ <el-option label="澶╃劧姘斿偍缃�" value="澶╃劧姘斿偍缃�" />
+ <el-option label="姘ф皵鍌ㄧ綈" value="姘ф皵鍌ㄧ綈" />
+ <el-option label="鍏朵粬" value="鍏朵粬" />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="瑙勬牸鍨嬪彿" prop="specification">
+ <el-input v-model="deviceForm.specification" placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�" />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="璁捐鍘嬪姏(MPa)" prop="designPressure">
+ <el-input-number v-model="deviceForm.designPressure" :min="0" :precision="2" style="width: 100%" />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="瀹圭Н(m鲁)" prop="volume">
+ <el-input-number v-model="deviceForm.volume" :min="0" :precision="2" style="width: 100%" />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ </el-form>
+ <template #footer>
+ <el-button @click="deviceDialogVisible = false">鍙栨秷</el-button>
+ <el-button type="primary" @click="saveDevice">淇濆瓨</el-button>
+ </template>
+ </el-dialog>
+ </div>
+</template>
+
+<script setup>
+import { ref, reactive, onMounted, onUnmounted } from 'vue'
+import { ElMessage, ElMessageBox } from 'element-plus'
+import {
+ Refresh,
+ Box,
+ TrendCharts,
+ DataLine,
+ Money,
+ Plus
+} from '@element-plus/icons-vue'
+
+// 鍝嶅簲寮忔暟鎹�
+const lastUpdateTime = ref('')
+const totalDevices = ref(0)
+const dailyConsumption = ref(0)
+const monthlyConsumption = ref(0)
+const gasUnitPrice = ref(0)
+const dailyTotalCost = ref(0)
+const monthlyTotalCost = ref(0)
+const deviceList = ref([])
+const tableLoading = ref(false)
+const deviceDialogVisible = ref(false)
+const dialogTitle = ref('')
+const deviceFormRef = ref()
+
+// 璁惧琛ㄥ崟鏁版嵁
+const deviceForm = reactive({
+ deviceCode: '',
+ deviceName: '',
+ deviceType: '',
+ specification: '',
+ designPressure: 0,
+ volume: 0
+})
+
+// 琛ㄥ崟楠岃瘉瑙勫垯
+const deviceRules = {
+ deviceCode: [{ required: true, message: '璇疯緭鍏ヨ澶囩紪鍙�', trigger: 'blur' }],
+ deviceName: [{ required: true, message: '璇疯緭鍏ヨ澶囧悕绉�', trigger: 'blur' }],
+ deviceType: [{ required: true, message: '璇烽�夋嫨璁惧绫诲瀷', trigger: 'change' }],
+ specification: [{ required: true, message: '璇疯緭鍏ヨ鏍煎瀷鍙�', trigger: 'blur' }],
+ designPressure: [{ required: true, message: '璇疯緭鍏ヨ璁″帇鍔�', trigger: 'blur' }],
+ volume: [{ required: true, message: '璇疯緭鍏ュ绉�', trigger: 'blur' }]
+}
+
+// 瀹氭椂鍣�
+let updateTimer = null
+
+// 妯℃嫙鏁版嵁鐢熸垚
+const generateMockData = () => {
+ // 鏇存柊缁熻鏁版嵁
+ totalDevices.value = Math.floor(Math.random() * 10) + 15 // 15-25鍙拌澶�
+ dailyConsumption.value = Math.floor(Math.random() * 100) + 200 // 200-300 m鲁
+ monthlyConsumption.value = Math.floor(Math.random() * 2000) + 5000 // 5000-7000 m鲁
+ gasUnitPrice.value = (Math.random() * 2 + 3).toFixed(2) // 3-5鍏�/m鲁
+
+ // 璁$畻璐圭敤
+ dailyTotalCost.value = dailyConsumption.value * gasUnitPrice.value
+ monthlyTotalCost.value = monthlyConsumption.value * gasUnitPrice.value
+
+ // 鏇存柊璁惧鍒楄〃鏁版嵁
+ deviceList.value = Array.from({ length: totalDevices.value }, (_, index) => ({
+ id: index + 1,
+ deviceCode: `GT${String(index + 1).padStart(3, '0')}`,
+ deviceName: `鍌ㄦ皵缃�${index + 1}`,
+ deviceType: ['娑插寲姘斿偍缃�', '鍘嬬缉姘斿偍缃�', '澶╃劧姘斿偍缃�', '姘ф皵鍌ㄧ綈'][Math.floor(Math.random() * 4)],
+ specification: `${Math.floor(Math.random() * 50) + 50}m鲁`,
+ currentPressure: (Math.random() * 2 + 0.5).toFixed(2),
+ currentTemperature: (Math.random() * 20 + 15).toFixed(1),
+ gasConcentration: (Math.random() * 10).toFixed(2),
+ status: ['running', 'stopped', 'warning', 'error'][Math.floor(Math.random() * 4)],
+ lastUpdate: new Date().toLocaleString()
+ }))
+
+ // 鏇存柊鏈�鍚庢洿鏂版椂闂�
+ lastUpdateTime.value = new Date().toLocaleString()
+}
+
+// 鑾峰彇鍘嬪姏鐘舵�佹牱寮�
+const getPressureClass = (pressure) => {
+ const p = parseFloat(pressure)
+ if (p < 0.8) return 'pressure-low'
+ if (p > 1.5) return 'pressure-high'
+ return 'pressure-normal'
+}
+
+// 鑾峰彇娓╁害鐘舵�佹牱寮�
+const getTemperatureClass = (temperature) => {
+ const t = parseFloat(temperature)
+ if (t < 10 || t > 35) return 'temperature-warning'
+ return 'temperature-normal'
+}
+
+// 鑾峰彇娴撳害鐘舵�佹牱寮�
+const getConcentrationClass = (concentration) => {
+ const c = parseFloat(concentration)
+ if (c > 5) return 'concentration-warning'
+ return 'concentration-normal'
+}
+
+// 鑾峰彇鐘舵�佺被鍨�
+const getStatusType = (status) => {
+ const statusMap = {
+ running: 'success',
+ stopped: 'info',
+ warning: 'warning',
+ error: 'danger'
+ }
+ return statusMap[status] || 'info'
+}
+
+// 鑾峰彇鐘舵�佹枃鏈�
+const getStatusText = (status) => {
+ const statusMap = {
+ running: '杩愯涓�',
+ stopped: '宸插仠姝�',
+ warning: '璀﹀憡',
+ error: '鏁呴殰'
+ }
+ return statusMap[status] || '鏈煡'
+}
+
+// 鍒锋柊鏁版嵁
+const refreshData = () => {
+ generateMockData()
+ ElMessage.success('鏁版嵁宸插埛鏂�')
+}
+
+// 娣诲姞璁惧
+const addDevice = () => {
+ dialogTitle.value = '娣诲姞璁惧'
+ Object.keys(deviceForm).forEach(key => {
+ deviceForm[key] = key === 'designPressure' || key === 'volume' ? 0 : ''
+ })
+ deviceDialogVisible.value = true
+}
+
+// 缂栬緫璁惧
+const editDevice = (row) => {
+ dialogTitle.value = '缂栬緫璁惧'
+ Object.keys(deviceForm).forEach(key => {
+ if (row[key] !== undefined) {
+ deviceForm[key] = row[key]
+ }
+ })
+ deviceDialogVisible.value = true
+}
+
+
+
+// 淇濆瓨璁惧
+const saveDevice = () => {
+ deviceFormRef.value.validate((valid) => {
+ if (valid) {
+ ElMessage.success('淇濆瓨鎴愬姛')
+ deviceDialogVisible.value = false
+ refreshData()
+ }
+ })
+}
+
+
+
+// 鍚姩瀹氭椂鏇存柊
+const startAutoUpdate = () => {
+ updateTimer = setInterval(() => {
+ generateMockData()
+ }, 60000) // 姣忓垎閽熸洿鏂颁竴娆�
+}
+
+// 鍋滄瀹氭椂鏇存柊
+const stopAutoUpdate = () => {
+ if (updateTimer) {
+ clearInterval(updateTimer)
+ updateTimer = null
+ }
+}
+
+// 缁勪欢鎸傝浇
+onMounted(() => {
+ generateMockData()
+ startAutoUpdate()
+})
+
+// 缁勪欢鍗歌浇
+onUnmounted(() => {
+ stopAutoUpdate()
+})
+</script>
+
+<style lang="scss" scoped>
+.app-container {
+ padding: 20px;
+ background: #f5f5f5;
+ min-height: 100vh;
+}
+
+.page-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 20px;
+ padding: 20px;
+ background: white;
+ border-radius: 8px;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+
+ h2 {
+ margin: 0;
+ color: #303133;
+ font-size: 24px;
+ }
+
+ .header-info {
+ display: flex;
+ align-items: center;
+ gap: 15px;
+
+ .update-time {
+ color: #909399;
+ font-size: 14px;
+ }
+ }
+}
+
+.stats-cards {
+ margin-bottom: 20px;
+
+ .stat-card {
+ .stat-content {
+ display: flex;
+ align-items: center;
+ padding: 10px;
+
+ .stat-icon {
+ width: 60px;
+ height: 60px;
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ margin-right: 15px;
+
+ &.gas-device {
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+ color: white;
+ }
+
+ &.daily-consumption {
+ background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
+ color: white;
+ }
+
+ &.monthly-consumption {
+ background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
+ color: white;
+ }
+
+ &.gas-price {
+ background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
+ color: white;
+ }
+ }
+
+ .stat-info {
+ .stat-value {
+ font-size: 24px;
+ font-weight: bold;
+ color: #303133;
+ line-height: 1;
+ }
+
+ .stat-label {
+ font-size: 14px;
+ color: #909399;
+ margin-top: 5px;
+ }
+ }
+ }
+ }
+}
+
+.cost-stats {
+ margin-bottom: 20px;
+
+ .cost-card {
+ .card-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ }
+
+ .cost-content {
+ text-align: center;
+ padding: 20px 0;
+
+ .cost-main {
+ margin-bottom: 15px;
+
+ .cost-amount {
+ font-size: 36px;
+ font-weight: bold;
+ color: #409eff;
+ }
+
+ .cost-unit {
+ font-size: 16px;
+ color: #909399;
+ margin-left: 5px;
+ }
+ }
+
+ .cost-details {
+ .cost-item {
+ display: flex;
+ justify-content: space-between;
+ margin-bottom: 8px;
+ font-size: 14px;
+ color: #606266;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+ }
+ }
+ }
+ }
+}
+
+.device-section {
+ .card-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+
+ .header-actions {
+ display: flex;
+ gap: 10px;
+ }
+ }
+}
+
+// 鐘舵�佹牱寮�
+.pressure-low {
+ color: #e6a23c;
+ font-weight: bold;
+}
+
+.pressure-normal {
+ color: #67c23a;
+ font-weight: bold;
+}
+
+.pressure-high {
+ color: #f56c6c;
+ font-weight: bold;
+}
+
+.temperature-normal {
+ color: #67c23a;
+ font-weight: bold;
+}
+
+.temperature-warning {
+ color: #e6a23c;
+ font-weight: bold;
+}
+
+.concentration-normal {
+ color: #67c23a;
+ font-weight: bold;
+}
+
+.concentration-warning {
+ color: #f56c6c;
+ font-weight: bold;
+}
+</style>
--
Gitblit v1.9.3