<template>
|
<div class="app-container">
|
<!-- 页面标题 -->
|
<div class="page-header">
|
<h2>重型罐式货车监控</h2>
|
<div class="header-actions">
|
<!-- <el-button type="primary" @click="addTank">新增储罐</el-button>-->
|
<!-- <el-button @click="exportData">导出数据</el-button>-->
|
</div>
|
</div>
|
|
<!-- 四个主要模块 -->
|
<div class="modules-container">
|
<!-- 1. 基本信息模块 -->
|
<el-card class="module-card">
|
<template #header>
|
<div class="card-header">
|
<span>1. 基本信息</span>
|
<el-button type="text" @click="handleEditBasicInfo">编辑</el-button>
|
</div>
|
</template>
|
<div class="info-grid">
|
<div class="info-item">
|
<label>储罐编号:</label>
|
<span>{{ basicInfo.tankCode }}</span>
|
</div>
|
<div class="info-item">
|
<label>储罐名称:</label>
|
<span>{{ basicInfo.tankName }}</span>
|
</div>
|
<div class="info-item">
|
<label>储罐类型:</label>
|
<span>{{ basicInfo.tankType }}</span>
|
</div>
|
<div class="info-item">
|
<label>设计压力:</label>
|
<span>{{ basicInfo.designPressure }} MPa</span>
|
</div>
|
<div class="info-item">
|
<label>工作压力:</label>
|
<span>{{ basicInfo.workingPressure }} MPa</span>
|
</div>
|
<div class="info-item">
|
<label>容积:</label>
|
<span>{{ basicInfo.volume }} m³</span>
|
</div>
|
</div>
|
</el-card>
|
|
<!-- 2. 监测参数模块 -->
|
<el-card class="module-card">
|
<template #header>
|
<div class="card-header">
|
<span>2. 监测参数</span>
|
<el-button type="text" @click="refreshMonitoring">刷新</el-button>
|
</div>
|
</template>
|
<div class="monitoring-grid">
|
<div class="monitor-item">
|
<div class="monitor-label">压力</div>
|
<div class="monitor-value" :class="getStatusClass(monitoringData.pressureStatus)">
|
{{ monitoringData.pressure }} MPa
|
</div>
|
<div class="monitor-status">{{ monitoringData.pressureStatus === 'normal' ? '正常' : '异常' }}</div>
|
</div>
|
<div class="monitor-item">
|
<div class="monitor-label">温度</div>
|
<div class="monitor-value" :class="getStatusClass(monitoringData.temperatureStatus)">
|
{{ monitoringData.temperature }} ℃
|
</div>
|
<div class="monitor-status">{{ monitoringData.temperatureStatus === 'normal' ? '正常' : '异常' }}</div>
|
</div>
|
<div class="monitor-item">
|
<div class="monitor-label">气体浓度</div>
|
<div class="monitor-value" :class="getStatusClass(monitoringData.gasStatus)">
|
{{ monitoringData.gasConcentration }} ppm
|
</div>
|
<div class="monitor-status">{{ monitoringData.gasStatus === 'normal' ? '正常' : '异常' }}</div>
|
</div>
|
<div class="monitor-item">
|
<div class="monitor-label">流量</div>
|
<div class="monitor-value" :class="getStatusClass(monitoringData.flowStatus)">
|
{{ monitoringData.flow }} m³/h
|
</div>
|
<div class="monitor-status">{{ monitoringData.flowStatus === 'normal' ? '正常' : '异常' }}</div>
|
</div>
|
</div>
|
</el-card>
|
|
<!-- 3. 安全装置模块 -->
|
<el-card class="module-card">
|
<template #header>
|
<div class="card-header">
|
<span>3. 安全装置</span>
|
<el-button type="text" @click="checkSafetyDevices">检查</el-button>
|
</div>
|
</template>
|
<div class="safety-grid">
|
<div class="safety-item" v-for="device in safetyDevices" :key="device.name">
|
|
<div class="device-info">
|
<div class="device-name">{{ device.name }}</div>
|
<div class="device-status" :class="device.status">
|
{{ device.status === 'normal' ? '正常' : '异常' }}
|
</div>
|
</div>
|
</div>
|
</div>
|
</el-card>
|
|
<!-- 4. 维护记录模块 -->
|
<el-card class="module-card">
|
<template #header>
|
<div class="card-header">
|
<span>4. 维护记录</span>
|
<el-button type="text" @click="addMaintenanceRecord">添加记录</el-button>
|
</div>
|
</template>
|
<div class="maintenance-list">
|
<div class="maintenance-item" v-for="record in maintenanceRecords" :key="record.id">
|
<div class="record-header">
|
<span class="record-date">{{ record.date }}</span>
|
<el-tag :type="record.type === 'inspection' ? 'primary' : 'success'" size="small">
|
{{ record.type === 'inspection' ? '检验' : '维护' }}
|
</el-tag>
|
</div>
|
<div class="record-content">
|
<div class="record-title">{{ record.title }}</div>
|
<div class="record-desc">{{ record.description }}</div>
|
<div class="record-operator">操作人:{{ record.operator }}</div>
|
</div>
|
</div>
|
</div>
|
</el-card>
|
</div>
|
|
<!-- 编辑基本信息弹窗 -->
|
<el-dialog v-model="basicInfoDialogVisible" title="编辑基本信息" width="600px">
|
<el-form :model="editBasicInfo" label-width="120px">
|
<el-form-item label="储罐编号">
|
<el-input v-model="editBasicInfo.tankCode" />
|
</el-form-item>
|
<el-form-item label="储罐名称">
|
<el-input v-model="editBasicInfo.tankName" />
|
</el-form-item>
|
<el-form-item label="储罐类型">
|
<el-select v-model="editBasicInfo.tankType" style="width: 100%">
|
<el-option label="液化气体储罐" value="液化气体储罐" />
|
<el-option label="压力容器" value="压力容器" />
|
<el-option label="常压储罐" value="常压储罐" />
|
</el-select>
|
</el-form-item>
|
<el-form-item label="设计压力">
|
<el-input-number v-model="editBasicInfo.designPressure" :precision="2" style="width: 100%" />
|
</el-form-item>
|
<el-form-item label="工作压力">
|
<el-input-number v-model="editBasicInfo.workingPressure" :precision="2" style="width: 100%" />
|
</el-form-item>
|
<el-form-item label="容积">
|
<el-input-number v-model="editBasicInfo.volume" :precision="2" style="width: 100%" />
|
</el-form-item>
|
</el-form>
|
<template #footer>
|
<el-button @click="basicInfoDialogVisible = false">取消</el-button>
|
<el-button type="primary" @click="saveBasicInfo">保存</el-button>
|
</template>
|
</el-dialog>
|
|
<!-- 添加维护记录弹窗 -->
|
<el-dialog v-model="maintenanceDialogVisible" title="添加维护记录" width="600px">
|
<el-form :model="newMaintenanceRecord" label-width="120px">
|
<el-form-item label="记录类型">
|
<el-select v-model="newMaintenanceRecord.type" style="width: 100%">
|
<el-option label="检验" value="inspection" />
|
<el-option label="维护" value="maintenance" />
|
</el-select>
|
</el-form-item>
|
<el-form-item label="标题">
|
<el-input v-model="newMaintenanceRecord.title" />
|
</el-form-item>
|
<el-form-item label="描述">
|
<el-input type="textarea" v-model="newMaintenanceRecord.description" :rows="3" />
|
</el-form-item>
|
<el-form-item label="操作人">
|
<el-input v-model="newMaintenanceRecord.operator" />
|
</el-form-item>
|
</el-form>
|
<template #footer>
|
<el-button @click="maintenanceDialogVisible = false">取消</el-button>
|
<el-button type="primary" @click="saveMaintenanceRecord">保存</el-button>
|
</template>
|
</el-dialog>
|
</div>
|
</template>
|
|
<script setup>
|
import { ref, reactive, onMounted } from 'vue'
|
import { ElMessage } from 'element-plus'
|
|
// 基本信息
|
const basicInfo = reactive({
|
tankCode: 'GT001',
|
tankName: '液化气储罐A',
|
tankType: '液化气体储罐',
|
designPressure: 1.6,
|
workingPressure: 0.8,
|
volume: 100.5
|
})
|
|
// 监测参数
|
const monitoringData = reactive({
|
pressure: 0.8,
|
pressureStatus: 'normal',
|
temperature: 25.5,
|
temperatureStatus: 'normal',
|
gasConcentration: 0.1,
|
gasStatus: 'normal',
|
flow: 15.2,
|
flowStatus: 'normal'
|
})
|
|
// 安全装置
|
const safetyDevices = ref([
|
{ name: '安全阀', status: 'normal' },
|
{ name: '压力传感器', status: 'normal' },
|
{ name: '温度传感器', status: 'normal' },
|
{ name: '气体检测器', status: 'normal' },
|
{ name: '爆破片', status: 'normal' },
|
{ name: '泄压装置', status: 'normal' }
|
])
|
|
// 维护记录
|
const maintenanceRecords = ref([
|
{
|
id: 1,
|
date: '2024-01-15',
|
type: 'inspection',
|
title: '年度检验',
|
description: '按照TSG 21-2016标准进行年度检验,设备状态良好',
|
operator: '张工程师'
|
},
|
{
|
id: 2,
|
date: '2024-02-20',
|
type: 'maintenance',
|
title: '安全阀维护',
|
description: '更换安全阀密封圈,校准压力设定值',
|
operator: '李技师'
|
},
|
{
|
id: 3,
|
date: '2024-03-10',
|
type: 'inspection',
|
title: '压力测试',
|
description: '进行压力容器水压试验,符合设计要求',
|
operator: '王检验员'
|
}
|
])
|
|
// 弹窗控制
|
const basicInfoDialogVisible = ref(false)
|
const maintenanceDialogVisible = ref(false)
|
|
// 编辑表单数据
|
const editBasicInfo = reactive({ ...basicInfo })
|
const newMaintenanceRecord = reactive({
|
type: 'inspection',
|
title: '',
|
description: '',
|
operator: ''
|
})
|
|
// 获取状态样式类
|
const getStatusClass = (status) => {
|
return status === 'normal' ? 'status-normal' : 'status-warning'
|
}
|
|
// 新增储罐
|
const addTank = () => {
|
ElMessage.success('新增储罐功能')
|
}
|
|
// 导出数据
|
const exportData = () => {
|
ElMessage.success('导出成功')
|
}
|
|
// 编辑基本信息
|
const handleEditBasicInfo = () => {
|
Object.assign(editBasicInfo, basicInfo)
|
basicInfoDialogVisible.value = true
|
}
|
|
// 保存基本信息
|
const saveBasicInfo = () => {
|
Object.assign(basicInfo, editBasicInfo)
|
basicInfoDialogVisible.value = false
|
ElMessage.success('保存成功')
|
}
|
|
// 刷新监测数据
|
const refreshMonitoring = () => {
|
// 模拟数据更新
|
monitoringData.pressure = (Math.random() * 0.5 + 0.6).toFixed(2)
|
monitoringData.temperature = (Math.random() * 10 + 20).toFixed(1)
|
monitoringData.gasConcentration = (Math.random() * 0.2).toFixed(2)
|
monitoringData.flow = (Math.random() * 10 + 10).toFixed(1)
|
ElMessage.success('数据已刷新')
|
}
|
|
// 检查安全装置
|
const checkSafetyDevices = () => {
|
// 模拟检查过程
|
safetyDevices.value.forEach(device => {
|
device.status = Math.random() > 0.1 ? 'normal' : 'warning'
|
})
|
ElMessage.success('安全装置检查完成')
|
}
|
|
// 添加维护记录
|
const addMaintenanceRecord = () => {
|
newMaintenanceRecord.type = 'inspection'
|
newMaintenanceRecord.title = ''
|
newMaintenanceRecord.description = ''
|
newMaintenanceRecord.operator = ''
|
maintenanceDialogVisible.value = true
|
}
|
|
// 保存维护记录
|
const saveMaintenanceRecord = () => {
|
const record = {
|
id: Date.now(),
|
date: new Date().toISOString().split('T')[0],
|
...newMaintenanceRecord
|
}
|
maintenanceRecords.value.unshift(record)
|
maintenanceDialogVisible.value = false
|
ElMessage.success('记录添加成功')
|
}
|
|
// 模拟实时数据更新
|
onMounted(() => {
|
setInterval(() => {
|
monitoringData.pressure = (Math.random() * 0.5 + 0.6).toFixed(2)
|
monitoringData.temperature = (Math.random() * 10 + 20).toFixed(1)
|
monitoringData.gasConcentration = (Math.random() * 0.2).toFixed(2)
|
monitoringData.flow = (Math.random() * 10 + 10).toFixed(1)
|
}, 5000)
|
})
|
</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;
|
}
|
|
.header-actions {
|
display: flex;
|
gap: 10px;
|
}
|
}
|
|
.modules-container {
|
display: grid;
|
grid-template-columns: repeat(2, 1fr);
|
gap: 20px;
|
}
|
|
.module-card {
|
.card-header {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
font-weight: bold;
|
color: #303133;
|
}
|
}
|
|
.info-grid {
|
display: grid;
|
grid-template-columns: repeat(2, 1fr);
|
gap: 15px;
|
|
.info-item {
|
display: flex;
|
justify-content: space-between;
|
padding: 10px;
|
background: #f8f9fa;
|
border-radius: 4px;
|
|
label {
|
font-weight: bold;
|
color: #606266;
|
}
|
|
span {
|
color: #303133;
|
}
|
}
|
}
|
|
.monitoring-grid {
|
display: grid;
|
grid-template-columns: repeat(2, 1fr);
|
gap: 15px;
|
|
.monitor-item {
|
text-align: center;
|
padding: 15px;
|
background: #f8f9fa;
|
border-radius: 8px;
|
border: 2px solid transparent;
|
|
.monitor-label {
|
font-size: 14px;
|
color: #606266;
|
margin-bottom: 8px;
|
}
|
|
.monitor-value {
|
font-size: 20px;
|
font-weight: bold;
|
margin-bottom: 5px;
|
|
&.status-normal {
|
color: #67c23a;
|
}
|
|
&.status-warning {
|
color: #e6a23c;
|
}
|
}
|
|
.monitor-status {
|
font-size: 12px;
|
color: #909399;
|
}
|
}
|
}
|
|
.safety-grid {
|
display: grid;
|
grid-template-columns: repeat(2, 1fr);
|
gap: 15px;
|
|
.safety-item {
|
display: flex;
|
align-items: center;
|
padding: 15px;
|
background: #f8f9fa;
|
border-radius: 8px;
|
border: 2px solid transparent;
|
|
.device-icon {
|
margin-right: 15px;
|
}
|
|
.device-info {
|
flex: 1;
|
|
.device-name {
|
font-weight: bold;
|
color: #303133;
|
margin-bottom: 5px;
|
}
|
|
.device-status {
|
font-size: 12px;
|
padding: 2px 8px;
|
border-radius: 10px;
|
display: inline-block;
|
|
&.normal {
|
background: #f0f9ff;
|
color: #409eff;
|
}
|
|
&.warning {
|
background: #fef7e0;
|
color: #e6a23c;
|
}
|
}
|
}
|
}
|
}
|
|
.maintenance-list {
|
max-height: 300px;
|
overflow-y: auto;
|
|
.maintenance-item {
|
padding: 15px;
|
border-bottom: 1px solid #ebeef5;
|
margin-bottom: 10px;
|
|
&:last-child {
|
border-bottom: none;
|
margin-bottom: 0;
|
}
|
|
.record-header {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
margin-bottom: 8px;
|
|
.record-date {
|
font-size: 14px;
|
color: #909399;
|
}
|
}
|
|
.record-content {
|
.record-title {
|
font-weight: bold;
|
color: #303133;
|
margin-bottom: 5px;
|
}
|
|
.record-desc {
|
font-size: 14px;
|
color: #606266;
|
margin-bottom: 5px;
|
line-height: 1.4;
|
}
|
|
.record-operator {
|
font-size: 12px;
|
color: #909399;
|
}
|
}
|
}
|
}
|
|
// 响应式设计
|
@media (max-width: 1200px) {
|
.modules-container {
|
grid-template-columns: 1fr;
|
}
|
}
|
|
@media (max-width: 768px) {
|
.info-grid,
|
.monitoring-grid,
|
.safety-grid {
|
grid-template-columns: 1fr;
|
}
|
}
|
</style>
|