<template>
|
<div class="app-container">
|
<!-- 搜索表单 -->
|
<div class="search_form">
|
<el-form :model="searchForm" :inline="true">
|
<el-form-item label="储气罐名称:">
|
<el-input v-model="searchForm.tankName" placeholder="请输入储气罐名称" clearable style="width: 200px" />
|
</el-form-item>
|
<el-form-item label="储气罐类型:">
|
<el-select v-model="searchForm.tankType" placeholder="请选择储气罐类型" clearable style="width: 200px">
|
<el-option label="液化气储罐" value="液化气储罐" />
|
<el-option label="压缩气储罐" value="压缩气储罐" />
|
<el-option label="天然气储罐" value="天然气储罐" />
|
<el-option label="氧气储罐" value="氧气储罐" />
|
</el-select>
|
</el-form-item>
|
<el-form-item label="预警类型:">
|
<el-select v-model="searchForm.warningType" placeholder="请选择预警类型" clearable style="width: 200px">
|
<el-option label="气体不足" value="气体不足" />
|
<el-option label="压力异常" value="压力异常" />
|
<el-option label="温度异常" value="温度异常" />
|
<el-option label="泄漏预警" value="泄漏预警" />
|
</el-select>
|
</el-form-item>
|
<el-form-item label="预警级别:">
|
<el-select v-model="searchForm.warningLevel" placeholder="请选择预警级别" clearable style="width: 200px">
|
<el-option label="紧急" value="紧急" />
|
<el-option label="重要" value="重要" />
|
<el-option label="一般" value="一般" />
|
</el-select>
|
</el-form-item>
|
<el-form-item>
|
<el-button type="primary" @click="handleQuery">搜索</el-button>
|
<el-button @click="resetQuery">重置</el-button>
|
</el-form-item>
|
</el-form>
|
</div>
|
|
<!-- 数据表格 -->
|
<div class="table_list">
|
<!-- 操作按钮 -->
|
<div class="table-operations">
|
<el-button type="primary" @click="handleAdd">新增预警规则</el-button>
|
<el-button type="success" @click="handleBatchProcess">批量处理</el-button>
|
<el-button @click="handleExport">导出</el-button>
|
</div>
|
<el-table
|
:data="tableData"
|
border
|
v-loading="tableLoading"
|
@selection-change="handleSelectionChange"
|
style="width: 100%"
|
height="calc(100vh - 280px)"
|
>
|
<el-table-column align="center" type="selection" width="55" />
|
<el-table-column align="center" label="序号" type="index" width="60" />
|
|
<!-- 基础信息字段 -->
|
<el-table-column label="储气罐编码" prop="tankCode" width="120" show-overflow-tooltip />
|
<el-table-column label="储气罐名称" prop="tankName" width="200" show-overflow-tooltip />
|
<el-table-column label="储气罐类型" prop="tankType" width="120" show-overflow-tooltip />
|
<el-table-column label="规格型号" prop="specificationModel" width="150" show-overflow-tooltip />
|
<el-table-column label="容积(m³)" prop="volume" width="100" show-overflow-tooltip />
|
|
<!-- 库存相关字段 -->
|
<el-table-column label="当前气体量" prop="currentGasLevel" width="120" show-overflow-tooltip>
|
<template #default="scope">
|
<span :class="getGasLevelClass(scope.row)">{{ scope.row.currentGasLevel }}%</span>
|
</template>
|
</el-table-column>
|
<el-table-column label="安全气体量" prop="safetyGasLevel" width="120" show-overflow-tooltip />
|
<el-table-column label="最低气体量" prop="minGasLevel" width="120" show-overflow-tooltip />
|
<el-table-column label="最高气体量" prop="maxGasLevel" width="120" show-overflow-tooltip />
|
<el-table-column label="当前压力(MPa)" prop="currentPressure" width="140" show-overflow-tooltip />
|
|
<!-- 预警规则字段 -->
|
<el-table-column label="预警类型" prop="warningType" width="100" show-overflow-tooltip>
|
<template #default="scope">
|
<el-tag :type="getWarningTypeTag(scope.row.warningType)">
|
{{ scope.row.warningType }}
|
</el-tag>
|
</template>
|
</el-table-column>
|
<el-table-column label="预警级别" prop="warningLevel" width="100" show-overflow-tooltip>
|
<template #default="scope">
|
<el-tag :type="getWarningLevelTag(scope.row.warningLevel)">
|
{{ scope.row.warningLevel }}
|
</el-tag>
|
</template>
|
</el-table-column>
|
<el-table-column label="预警阈值" prop="warningThreshold" width="100" show-overflow-tooltip />
|
<el-table-column label="是否启用" prop="isEnabled" width="100" show-overflow-tooltip>
|
<template #default="scope">
|
<el-switch v-model="scope.row.isEnabled" @change="handleEnableChange(scope.row)" />
|
</template>
|
</el-table-column>
|
|
<!-- 时间相关字段 -->
|
<el-table-column label="预警时间" prop="warningTime" width="150" show-overflow-tooltip />
|
<el-table-column label="预警持续天数" prop="warningDuration" width="120" show-overflow-tooltip />
|
<el-table-column label="最后更新时间" prop="lastUpdateTime" width="150" show-overflow-tooltip />
|
<el-table-column label="预计充装时间" prop="expectedRefillTime" width="150" show-overflow-tooltip />
|
<el-table-column label="预计缺气时间" prop="expectedShortageTime" width="150" show-overflow-tooltip>
|
<template #default="scope">
|
<div v-if="scope.row.expectedShortageTime">
|
<div v-if="getCountdown(scope.row.expectedShortageTime).isExpired" class="countdown-expired">
|
<el-tag type="danger">已缺气</el-tag>
|
</div>
|
<div v-else class="countdown-timer">
|
<span :class="getCountdownClass(scope.row.expectedShortageTime)">
|
{{ getCountdown(scope.row.expectedShortageTime).text }}
|
</span>
|
</div>
|
</div>
|
<span v-else>-</span>
|
</template>
|
</el-table-column>
|
|
<!-- 操作列 -->
|
<el-table-column fixed="right" label="操作" width="200" align="center">
|
<template #default="scope">
|
<el-button link type="primary" size="small" @click="handleEdit(scope.row)">编辑</el-button>
|
<el-button link type="success" size="small" @click="handleProcess(scope.row)">处理</el-button>
|
<el-button link type="danger" size="small" @click="handleDelete(scope.row)">删除</el-button>
|
</template>
|
</el-table-column>
|
</el-table>
|
|
<!-- 分页 -->
|
<pagination
|
v-show="total > 0"
|
:total="total"
|
layout="total, sizes, prev, pager, next, jumper"
|
:page="page.current"
|
:limit="page.size"
|
@pagination="paginationChange"
|
/>
|
</div>
|
|
<!-- 新增/编辑预警规则弹窗 -->
|
<el-dialog
|
v-model="dialogFormVisible"
|
:title="operationType === 'add' ? '新增预警规则' : '编辑预警规则'"
|
width="50%"
|
@close="closeDialog"
|
>
|
<el-form :model="form" :rules="rules" ref="formRef" label-width="140px">
|
<el-row :gutter="20">
|
<!-- 基础信息 -->
|
<el-col :span="12">
|
<el-form-item label="储气罐编码:" prop="tankCode">
|
<el-input v-model="form.tankCode" placeholder="请输入储气罐编码" />
|
</el-form-item>
|
</el-col>
|
<el-col :span="12">
|
<el-form-item label="储气罐名称:" prop="tankName">
|
<el-input v-model="form.tankName" placeholder="请输入储气罐名称" />
|
</el-form-item>
|
</el-col>
|
</el-row>
|
|
<el-row :gutter="20">
|
<el-col :span="12">
|
<el-form-item label="储气罐类型:" prop="tankType">
|
<el-select v-model="form.tankType" placeholder="请选择储气罐类型" style="width: 100%">
|
<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="specificationModel">
|
<el-input v-model="form.specificationModel" placeholder="请输入规格型号" />
|
</el-form-item>
|
</el-col>
|
</el-row>
|
|
<el-row :gutter="20">
|
<el-col :span="12">
|
<el-form-item label="容积(m³):" prop="volume">
|
<el-input-number v-model="form.volume" :min="0" :precision="2" style="width: 100%" />
|
</el-form-item>
|
</el-col>
|
<el-col :span="12">
|
<el-form-item label="当前气体量(%):" prop="currentGasLevel">
|
<el-input-number v-model="form.currentGasLevel" :min="0" :max="100" :precision="1" style="width: 100%" />
|
</el-form-item>
|
</el-col>
|
</el-row>
|
|
<!-- 库存相关 -->
|
<el-row :gutter="20">
|
<el-col :span="12">
|
<el-form-item label="安全气体量(%):" prop="safetyGasLevel">
|
<el-input-number v-model="form.safetyGasLevel" :min="0" :max="100" :precision="1" style="width: 100%" />
|
</el-form-item>
|
</el-col>
|
<el-col :span="12">
|
<el-form-item label="最低气体量(%):" prop="minGasLevel">
|
<el-input-number v-model="form.minGasLevel" :min="0" :max="100" :precision="1" style="width: 100%" />
|
</el-form-item>
|
</el-col>
|
</el-row>
|
|
<el-row :gutter="20">
|
<el-col :span="12">
|
<el-form-item label="最高气体量(%):" prop="maxGasLevel">
|
<el-input-number v-model="form.maxGasLevel" :min="0" :max="100" :precision="1" style="width: 100%" />
|
</el-form-item>
|
</el-col>
|
<el-col :span="12">
|
<el-form-item label="当前压力(MPa):" prop="currentPressure">
|
<el-input-number v-model="form.currentPressure" :min="0" :precision="2" style="width: 100%" />
|
</el-form-item>
|
</el-col>
|
</el-row>
|
|
<!-- 预警规则 -->
|
<el-row :gutter="20">
|
<el-col :span="12">
|
<el-form-item label="预警类型:" prop="warningType">
|
<el-select v-model="form.warningType" placeholder="请选择预警类型" style="width: 100%">
|
<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="warningLevel">
|
<el-select v-model="form.warningLevel" placeholder="请选择预警级别" style="width: 100%">
|
<el-option label="紧急" value="紧急" />
|
<el-option label="重要" value="重要" />
|
<el-option label="一般" value="一般" />
|
</el-select>
|
</el-form-item>
|
</el-col>
|
</el-row>
|
|
<el-row :gutter="20">
|
<el-col :span="12">
|
<el-form-item label="预警阈值:" prop="warningThreshold">
|
<el-input-number v-model="form.warningThreshold" :min="0" :precision="2" style="width: 100%" />
|
</el-form-item>
|
</el-col>
|
<el-col :span="12">
|
<el-form-item label="是否启用:" prop="isEnabled">
|
<el-switch v-model="form.isEnabled" />
|
</el-form-item>
|
</el-col>
|
</el-row>
|
|
<!-- 时间相关 -->
|
<el-row :gutter="20">
|
<el-col :span="12">
|
<el-form-item label="预警时间:" prop="warningTime">
|
<el-date-picker
|
v-model="form.warningTime"
|
type="datetime"
|
placeholder="请选择预警时间"
|
style="width: 100%"
|
value-format="YYYY-MM-DD HH:mm:ss"
|
/>
|
</el-form-item>
|
</el-col>
|
<el-col :span="12">
|
<el-form-item label="预计充装时间:" prop="expectedRefillTime">
|
<el-date-picker
|
v-model="form.expectedRefillTime"
|
type="datetime"
|
placeholder="请选择预计充装时间"
|
style="width: 100%"
|
value-format="YYYY-MM-DD HH:mm:ss"
|
/>
|
</el-form-item>
|
</el-col>
|
</el-row>
|
|
<el-row :gutter="20">
|
<el-col :span="12">
|
<el-form-item label="预计缺气时间:" prop="expectedShortageTime">
|
<el-date-picker
|
v-model="form.expectedShortageTime"
|
type="datetime"
|
placeholder="请选择预计缺气时间"
|
style="width: 100%"
|
value-format="YYYY-MM-DD HH:mm:ss"
|
/>
|
</el-form-item>
|
</el-col>
|
<el-col :span="12">
|
<el-form-item label="预警规则描述:" prop="warningRule">
|
<el-input
|
v-model="form.warningRule"
|
type="textarea"
|
:rows="3"
|
placeholder="请输入预警规则描述"
|
/>
|
</el-form-item>
|
</el-col>
|
</el-row>
|
</el-form>
|
|
<template #footer>
|
<div class="dialog-footer">
|
<el-button @click="closeDialog">取消</el-button>
|
<el-button type="primary" @click="submitForm">确认</el-button>
|
</div>
|
</template>
|
</el-dialog>
|
|
<!-- 缺气预警弹框 -->
|
<el-dialog
|
v-model="shortageWarningVisible"
|
title="⚠️ 缺气预警"
|
width="400px"
|
:close-on-click-modal="false"
|
:close-on-press-escape="false"
|
:show-close="false"
|
>
|
<div class="shortage-warning-content">
|
<div class="warning-icon">
|
<el-icon size="48" color="#f56c6c"><WarningFilled /></el-icon>
|
</div>
|
<div class="warning-message">
|
<h3>{{ currentWarningTank.tankName }}</h3>
|
<p>储气罐已缺气,请及时处理!</p>
|
<p class="warning-details">
|
储气罐编码:{{ currentWarningTank.tankCode }}<br>
|
储气罐类型:{{ currentWarningTank.tankType }}<br>
|
当前气体量:{{ currentWarningTank.currentGasLevel }}%
|
</p>
|
</div>
|
</div>
|
<template #footer>
|
<div class="dialog-footer">
|
<el-button type="primary" @click="handleShortageWarning">立即处理</el-button>
|
<el-button @click="closeShortageWarning">稍后处理</el-button>
|
</div>
|
</template>
|
</el-dialog>
|
|
<!-- 缺气预警弹框 -->
|
<el-dialog
|
v-model="shortageWarningVisible"
|
title="⚠️ 缺气预警"
|
width="400px"
|
:close-on-click-modal="false"
|
:close-on-press-escape="false"
|
:show-close="false"
|
>
|
<div class="shortage-warning-content">
|
<div class="warning-icon">
|
<el-icon size="48" color="#f56c6c"><WarningFilled /></el-icon>
|
</div>
|
<div class="warning-message">
|
<h3>{{ currentWarningTank.tankName }}</h3>
|
<p>储气罐已缺气,请及时处理!</p>
|
<p class="warning-details">
|
储气罐编码:{{ currentWarningTank.tankCode }}<br>
|
储气罐类型:{{ currentWarningTank.tankType }}<br>
|
当前气体量:{{ currentWarningTank.currentGasLevel }}%
|
</p>
|
</div>
|
</div>
|
<template #footer>
|
<div class="dialog-footer">
|
<el-button type="primary" @click="handleShortageWarning">立即处理</el-button>
|
<el-button @click="closeShortageWarning">稍后处理</el-button>
|
</div>
|
</template>
|
</el-dialog>
|
</div>
|
</template>
|
|
<script setup>
|
import { ref, reactive, onMounted, onUnmounted } from 'vue'
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
import { WarningFilled } from '@element-plus/icons-vue'
|
import pagination from '@/components/PIMTable/Pagination.vue'
|
// 注释掉API导入,使用假数据
|
// import {
|
// getStockWarningPage,
|
// addStockWarning,
|
// updateStockWarning,
|
// deleteStockWarning,
|
// batchProcessStockWarning,
|
// exportStockWarning,
|
// toggleStockWarningStatus
|
// } from '@/api/inventoryManagement/stockWarning.js'
|
|
const { proxy } = getCurrentInstance()
|
|
// 响应式数据
|
const tableData = ref([])
|
const tableLoading = ref(false)
|
const selectedRows = ref([])
|
const dialogFormVisible = ref(false)
|
const operationType = ref('add')
|
const total = ref(0)
|
|
// 缺气预警相关
|
const shortageWarningVisible = ref(false)
|
const currentWarningTank = ref({})
|
const countdownTimer = ref(null)
|
|
// 分页参数
|
const page = reactive({
|
current: 1,
|
size: 10
|
})
|
|
// 搜索表单
|
const searchForm = reactive({
|
tankName: '',
|
tankType: '',
|
warningType: '',
|
warningLevel: ''
|
})
|
|
// 表单数据
|
const form = reactive({
|
id: null,
|
tankCode: '',
|
tankName: '',
|
tankType: '',
|
specificationModel: '',
|
volume: 0,
|
currentGasLevel: 0,
|
safetyGasLevel: 0,
|
minGasLevel: 0,
|
maxGasLevel: 0,
|
currentPressure: 0,
|
warningType: '',
|
warningLevel: '',
|
warningThreshold: 0,
|
isEnabled: true,
|
warningTime: '',
|
warningDuration: 0,
|
lastUpdateTime: '',
|
expectedRefillTime: '',
|
expectedShortageTime: '',
|
warningRule: ''
|
})
|
|
// 表单验证规则
|
const rules = {
|
tankCode: [{ required: true, message: '请输入储气罐编码', trigger: 'blur' }],
|
tankName: [{ required: true, message: '请输入储气罐名称', trigger: 'blur' }],
|
tankType: [{ required: true, message: '请选择储气罐类型', trigger: 'change' }],
|
warningType: [{ required: true, message: '请选择预警类型', trigger: 'change' }],
|
warningLevel: [{ required: true, message: '请选择预警级别', trigger: 'change' }],
|
warningThreshold: [{ required: true, message: '请输入预警阈值', trigger: 'blur' }]
|
}
|
|
// 获取倒计时信息
|
const getCountdown = (expectedTime) => {
|
if (!expectedTime) return { text: '-', isExpired: false }
|
|
const now = new Date().getTime()
|
const expected = new Date(expectedTime).getTime()
|
const diff = expected - now
|
|
if (diff <= 0) {
|
return { text: '已缺气', isExpired: true }
|
}
|
|
const days = Math.floor(diff / (1000 * 60 * 60 * 24))
|
const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60))
|
const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60))
|
|
if (days > 0) {
|
return { text: `${days}天${hours}小时`, isExpired: false }
|
} else if (hours > 0) {
|
return { text: `${hours}小时${minutes}分钟`, isExpired: false }
|
} else {
|
return { text: `${minutes}分钟`, isExpired: false }
|
}
|
}
|
|
// 获取倒计时样式类
|
const getCountdownClass = (expectedTime) => {
|
if (!expectedTime) return ''
|
|
const now = new Date().getTime()
|
const expected = new Date(expectedTime).getTime()
|
const diff = expected - now
|
|
if (diff <= 0) {
|
return 'countdown-expired'
|
} else if (diff <= 24 * 60 * 60 * 1000) { // 24小时内
|
return 'countdown-urgent'
|
} else if (diff <= 7 * 24 * 60 * 60 * 1000) { // 7天内
|
return 'countdown-warning'
|
} else {
|
return 'countdown-normal'
|
}
|
}
|
|
// 检查缺气预警
|
const checkShortageWarnings = () => {
|
tableData.value.forEach(tank => {
|
if (tank.expectedShortageTime) {
|
const countdown = getCountdown(tank.expectedShortageTime)
|
if (countdown.isExpired && !tank.warningShown) {
|
// 标记已显示预警,避免重复弹框
|
tank.warningShown = true
|
showShortageWarning(tank)
|
}
|
}
|
})
|
}
|
|
// 显示缺气预警弹框
|
const showShortageWarning = (tank) => {
|
currentWarningTank.value = tank
|
shortageWarningVisible.value = true
|
|
// 播放提示音(可选)
|
// const audio = new Audio('/path/to/warning-sound.mp3')
|
// audio.play()
|
}
|
|
// 处理缺气预警
|
const handleShortageWarning = () => {
|
ElMessage.success(`正在处理储气罐 ${currentWarningTank.value.tankName} 的缺气问题`)
|
shortageWarningVisible.value = false
|
// 这里可以调用处理API
|
}
|
// 处理缺气预警
|
const closeShortageWarning = () => {
|
// ElMessage.success(`正在处理储气罐 ${currentWarningTank.value.tankName} 的缺气问题`)
|
shortageWarningVisible.value = false
|
// 这里可以调用处理API
|
}
|
|
|
|
// 生成假数据
|
const generateMockData = () => {
|
const mockData = [
|
{
|
id: 1,
|
tankCode: 'TANK001',
|
tankName: '液化气储罐A',
|
tankType: '液化气储罐',
|
specificationModel: 'LPG-5000L',
|
volume: 5000,
|
currentGasLevel: 15,
|
safetyGasLevel: 30,
|
minGasLevel: 10,
|
maxGasLevel: 95,
|
currentPressure: 2.5,
|
warningType: '气体不足',
|
warningLevel: '紧急',
|
warningThreshold: 20,
|
isEnabled: true,
|
warningTime: '2024-01-15 08:30:00',
|
warningDuration: 3,
|
lastUpdateTime: '2024-01-15 10:00:00',
|
expectedRefillTime: '2024-01-16 14:00:00',
|
expectedShortageTime: '2024-01-15 18:30:00', // 今天下午6:30缺气
|
warningRule: '当气体量低于20%时触发预警'
|
},
|
{
|
id: 2,
|
tankCode: 'TANK002',
|
tankName: '压缩气储罐B',
|
tankType: '压缩气储罐',
|
specificationModel: 'COMP-3000L',
|
volume: 3000,
|
currentGasLevel: 45,
|
safetyGasLevel: 25,
|
minGasLevel: 15,
|
maxGasLevel: 90,
|
currentPressure: 8.2,
|
warningType: '压力异常',
|
warningLevel: '重要',
|
warningThreshold: 10,
|
isEnabled: true,
|
warningTime: '2024-01-14 16:20:00',
|
warningDuration: 2,
|
lastUpdateTime: '2024-01-15 09:15:00',
|
expectedRefillTime: '2024-01-17 09:00:00',
|
expectedShortageTime: '2024-01-18 12:00:00', // 3天后缺气
|
warningRule: '当压力超过8MPa时触发预警'
|
},
|
{
|
id: 3,
|
tankCode: 'TANK003',
|
tankName: '天然气储罐C',
|
tankType: '天然气储罐',
|
specificationModel: 'NG-8000L',
|
volume: 8000,
|
currentGasLevel: 75,
|
safetyGasLevel: 20,
|
minGasLevel: 10,
|
maxGasLevel: 95,
|
currentPressure: 4.8,
|
warningType: '温度异常',
|
warningLevel: '一般',
|
warningThreshold: 5,
|
isEnabled: true,
|
warningTime: '2024-01-13 11:45:00',
|
warningDuration: 1,
|
lastUpdateTime: '2024-01-15 08:45:00',
|
expectedRefillTime: '2024-01-20 10:00:00',
|
expectedShortageTime: '2024-01-22 15:30:00', // 7天后缺气
|
warningRule: '当温度超过60°C时触发预警'
|
},
|
{
|
id: 4,
|
tankCode: 'TANK004',
|
tankName: '氧气储罐D',
|
tankType: '氧气储罐',
|
specificationModel: 'O2-2000L',
|
volume: 2000,
|
currentGasLevel: 8,
|
safetyGasLevel: 25,
|
minGasLevel: 5,
|
maxGasLevel: 90,
|
currentPressure: 6.5,
|
warningType: '泄漏预警',
|
warningLevel: '紧急',
|
warningThreshold: 15,
|
isEnabled: true,
|
warningTime: '2024-01-15 07:15:00',
|
warningDuration: 4,
|
lastUpdateTime: '2024-01-15 11:30:00',
|
expectedRefillTime: '2024-01-15 16:00:00',
|
expectedShortageTime: '2024-01-15 14:00:00', // 今天下午2点缺气
|
warningRule: '当检测到气体泄漏时触发预警'
|
},
|
{
|
id: 5,
|
tankCode: 'TANK005',
|
tankName: '液化气储罐E',
|
tankType: '液化气储罐',
|
specificationModel: 'LPG-6000L',
|
volume: 6000,
|
currentGasLevel: 35,
|
safetyGasLevel: 30,
|
minGasLevel: 15,
|
maxGasLevel: 95,
|
currentPressure: 3.2,
|
warningType: '气体不足',
|
warningLevel: '重要',
|
warningThreshold: 20,
|
isEnabled: false,
|
warningTime: '2024-01-14 14:30:00',
|
warningDuration: 2,
|
lastUpdateTime: '2024-01-15 09:00:00',
|
expectedRefillTime: '2024-01-19 08:00:00',
|
expectedShortageTime: '2024-01-21 10:00:00', // 6天后缺气
|
warningRule: '当气体量低于20%时触发预警'
|
},
|
{
|
id: 6,
|
tankCode: 'TANK006',
|
tankName: '压缩气储罐F',
|
tankType: '压缩气储罐',
|
specificationModel: 'COMP-4000L',
|
volume: 4000,
|
currentGasLevel: 85,
|
safetyGasLevel: 20,
|
minGasLevel: 10,
|
maxGasLevel: 90,
|
currentPressure: 7.8,
|
warningType: '压力异常',
|
warningLevel: '一般',
|
warningThreshold: 8,
|
isEnabled: true,
|
warningTime: '2024-01-12 09:20:00',
|
warningDuration: 1,
|
lastUpdateTime: '2024-01-15 08:30:00',
|
expectedRefillTime: '2024-01-25 14:00:00',
|
expectedShortageTime: '2024-01-28 16:00:00', // 13天后缺气
|
warningRule: '当压力超过8MPa时触发预警'
|
},
|
{
|
id: 7,
|
tankCode: 'TANK007',
|
tankName: '天然气储罐G',
|
tankType: '天然气储罐',
|
specificationModel: 'NG-10000L',
|
volume: 10000,
|
currentGasLevel: 92,
|
safetyGasLevel: 15,
|
minGasLevel: 8,
|
maxGasLevel: 95,
|
currentPressure: 5.2,
|
warningType: '温度异常',
|
warningLevel: '重要',
|
warningThreshold: 6,
|
isEnabled: true,
|
warningTime: '2024-01-11 16:45:00',
|
warningDuration: 1,
|
lastUpdateTime: '2024-01-15 07:45:00',
|
expectedRefillTime: '2024-01-30 09:00:00',
|
expectedShortageTime: '2024-02-05 12:00:00', // 21天后缺气
|
warningRule: '当温度超过60°C时触发预警'
|
},
|
{
|
id: 8,
|
tankCode: 'TANK008',
|
tankName: '氧气储罐H',
|
tankType: '氧气储罐',
|
specificationModel: 'O2-1500L',
|
volume: 1500,
|
currentGasLevel: 12,
|
safetyGasLevel: 30,
|
minGasLevel: 8,
|
maxGasLevel: 90,
|
currentPressure: 4.5,
|
warningType: '泄漏预警',
|
warningLevel: '紧急',
|
warningThreshold: 12,
|
isEnabled: true,
|
warningTime: '2024-01-15 06:30:00',
|
warningDuration: 5,
|
lastUpdateTime: '2024-01-15 12:15:00',
|
expectedRefillTime: '2024-01-15 20:00:00',
|
expectedShortageTime: '2024-01-15 17:30:00', // 今天下午5:30缺气
|
warningRule: '当检测到气体泄漏时触发预警'
|
}
|
]
|
|
// 根据搜索条件过滤数据
|
let filteredData = mockData.filter(item => {
|
if (searchForm.tankName && !item.tankName.includes(searchForm.tankName)) return false
|
if (searchForm.tankType && item.tankType !== searchForm.tankType) return false
|
if (searchForm.warningType && item.warningType !== searchForm.warningType) return false
|
if (searchForm.warningLevel && item.warningLevel !== searchForm.warningLevel) return false
|
return true
|
})
|
|
// 分页处理
|
const start = (page.current - 1) * page.size
|
const end = start + page.size
|
const paginatedData = filteredData.slice(start, end)
|
|
return {
|
records: paginatedData,
|
total: filteredData.length
|
}
|
}
|
|
// 获取列表数据
|
const getList = async () => {
|
tableLoading.value = true
|
try {
|
// 模拟网络延迟
|
await new Promise(resolve => setTimeout(resolve, 500))
|
|
const result = generateMockData()
|
tableData.value = result.records
|
total.value = result.total
|
|
// 检查缺气预警
|
checkShortageWarnings()
|
} catch (error) {
|
console.error('获取列表失败:', error)
|
ElMessage.error('获取列表失败')
|
} finally {
|
tableLoading.value = false
|
}
|
}
|
|
// 搜索
|
const handleQuery = () => {
|
page.current = 1
|
getList()
|
}
|
|
// 重置搜索
|
const resetQuery = () => {
|
Object.keys(searchForm).forEach(key => {
|
searchForm[key] = ''
|
})
|
handleQuery()
|
}
|
|
// 分页变化
|
const paginationChange = (obj) => {
|
page.current = obj.page
|
page.size = obj.limit
|
getList()
|
}
|
|
// 表格选择变化
|
const handleSelectionChange = (selection) => {
|
selectedRows.value = selection
|
}
|
|
// 新增
|
const handleAdd = () => {
|
operationType.value = 'add'
|
resetForm()
|
dialogFormVisible.value = true
|
}
|
|
// 编辑
|
const handleEdit = (row) => {
|
operationType.value = 'edit'
|
Object.assign(form, row)
|
dialogFormVisible.value = true
|
}
|
|
// 处理预警
|
const handleProcess = async (row) => {
|
try {
|
// 模拟API调用延迟
|
await new Promise(resolve => setTimeout(resolve, 300))
|
ElMessage.success(`正在处理预警:${row.tankName}`)
|
getList()
|
} catch (error) {
|
ElMessage.error('处理预警失败')
|
}
|
}
|
|
// 删除
|
const handleDelete = async (row) => {
|
try {
|
await ElMessageBox.confirm(`确定要删除预警规则:${row.tankName}吗?`, '提示', {
|
confirmButtonText: '确定',
|
cancelButtonText: '取消',
|
type: 'warning'
|
})
|
|
// 模拟API调用延迟
|
await new Promise(resolve => setTimeout(resolve, 300))
|
ElMessage.success('删除成功')
|
getList()
|
} catch (error) {
|
if (error !== 'cancel') {
|
ElMessage.error('删除失败')
|
}
|
}
|
}
|
|
// 批量处理
|
const handleBatchProcess = async () => {
|
if (selectedRows.value.length === 0) {
|
ElMessage.warning('请选择要处理的预警')
|
return
|
}
|
|
try {
|
// 模拟API调用延迟
|
await new Promise(resolve => setTimeout(resolve, 500))
|
ElMessage.success(`批量处理了 ${selectedRows.value.length} 条预警`)
|
getList()
|
} catch (error) {
|
ElMessage.error('批量处理失败')
|
}
|
}
|
|
// 导出
|
const handleExport = async () => {
|
try {
|
// 模拟API调用延迟
|
await new Promise(resolve => setTimeout(resolve, 800))
|
|
// 生成导出数据
|
const exportData = generateMockData().records
|
const csvContent = generateCSV(exportData)
|
|
// 创建下载链接
|
const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' })
|
const url = window.URL.createObjectURL(blob)
|
const link = document.createElement('a')
|
link.href = url
|
link.download = `储气罐预警数据_${new Date().getTime()}.csv`
|
link.click()
|
window.URL.revokeObjectURL(url)
|
|
ElMessage.success('导出成功')
|
} catch (error) {
|
ElMessage.error('导出失败')
|
}
|
}
|
|
// 生成CSV内容
|
const generateCSV = (data) => {
|
const headers = [
|
'储气罐编码', '储气罐名称', '储气罐类型', '规格型号', '容积(m³)',
|
'当前气体量(%)', '安全气体量(%)', '最低气体量(%)', '最高气体量(%)',
|
'当前压力(MPa)', '预警类型', '预警级别', '预警阈值', '是否启用',
|
'预警时间', '预警持续天数', '最后更新时间', '预计充装时间', '预计缺气时间', '预警规则描述'
|
]
|
|
const csvRows = [headers.join(',')]
|
|
data.forEach(item => {
|
const row = [
|
item.tankCode,
|
item.tankName,
|
item.tankType,
|
item.specificationModel,
|
item.volume,
|
item.currentGasLevel,
|
item.safetyGasLevel,
|
item.minGasLevel,
|
item.maxGasLevel,
|
item.currentPressure,
|
item.warningType,
|
item.warningLevel,
|
item.warningThreshold,
|
item.isEnabled ? '是' : '否',
|
item.warningTime,
|
item.warningDuration,
|
item.lastUpdateTime,
|
item.expectedRefillTime,
|
item.expectedShortageTime,
|
item.warningRule
|
]
|
csvRows.push(row.join(','))
|
})
|
|
return csvRows.join('\n')
|
}
|
|
// 启用状态变化
|
const handleEnableChange = async (row) => {
|
try {
|
// 模拟API调用延迟
|
await new Promise(resolve => setTimeout(resolve, 200))
|
ElMessage.success(`${row.tankName} 的启用状态已更新`)
|
} catch (error) {
|
ElMessage.error('状态更新失败')
|
// 恢复原状态
|
row.isEnabled = !row.isEnabled
|
}
|
}
|
|
// 提交表单
|
const submitForm = async () => {
|
try {
|
await proxy.$refs.formRef.validate()
|
|
// 模拟API调用延迟
|
await new Promise(resolve => setTimeout(resolve, 500))
|
|
if (operationType.value === 'add') {
|
ElMessage.success('新增成功')
|
} else {
|
ElMessage.success('编辑成功')
|
}
|
|
closeDialog()
|
getList()
|
} catch (error) {
|
if (!error.errors) {
|
ElMessage.error(operationType.value === 'add' ? '新增失败' : '编辑失败')
|
}
|
}
|
}
|
|
// 关闭弹窗
|
const closeDialog = () => {
|
dialogFormVisible.value = false
|
resetForm()
|
}
|
|
// 重置表单
|
const resetForm = () => {
|
Object.keys(form).forEach(key => {
|
if (key === 'isEnabled') {
|
form[key] = true
|
} else if (typeof form[key] === 'number') {
|
form[key] = 0
|
} else {
|
form[key] = ''
|
}
|
})
|
proxy.$refs.formRef?.resetFields()
|
}
|
|
// 获取气体量样式类
|
const getGasLevelClass = (row) => {
|
if (row.currentGasLevel < row.minGasLevel) {
|
return 'text-danger'
|
} else if (row.currentGasLevel > row.maxGasLevel) {
|
return 'text-warning'
|
}
|
return 'text-success'
|
}
|
|
// 获取预警类型标签样式
|
const getWarningTypeTag = (type) => {
|
const typeMap = {
|
'气体不足': 'danger',
|
'压力异常': 'warning',
|
'温度异常': 'info',
|
'泄漏预警': 'danger'
|
}
|
return typeMap[type] || 'info'
|
}
|
|
// 获取预警级别标签样式
|
const getWarningLevelTag = (level) => {
|
const levelMap = {
|
'紧急': 'danger',
|
'重要': 'warning',
|
'一般': 'info'
|
}
|
return levelMap[level] || 'info'
|
}
|
|
// 启动倒计时定时器
|
const startCountdownTimer = () => {
|
countdownTimer.value = setInterval(() => {
|
checkShortageWarnings()
|
}, 60000) // 每分钟检查一次
|
}
|
|
// 停止倒计时定时器
|
const stopCountdownTimer = () => {
|
if (countdownTimer.value) {
|
clearInterval(countdownTimer.value)
|
countdownTimer.value = null
|
}
|
}
|
|
// 页面加载
|
onMounted(() => {
|
getList()
|
startCountdownTimer()
|
})
|
|
// 页面卸载
|
onUnmounted(() => {
|
stopCountdownTimer()
|
})
|
</script>
|
|
<style scoped lang="scss">
|
.app-container {
|
padding: 20px;
|
|
.table-operations {
|
text-align: right;
|
margin-bottom: 20px;
|
|
.el-button {
|
margin-right: 10px;
|
}
|
}
|
|
.table_list {
|
background: #fff;
|
border-radius: 4px;
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
}
|
|
.text-danger {
|
color: #f56c6c;
|
font-weight: bold;
|
}
|
|
.text-warning {
|
color: #e6a23c;
|
font-weight: bold;
|
}
|
|
.text-success {
|
color: #67c23a;
|
font-weight: bold;
|
}
|
|
.dialog-footer {
|
text-align: right;
|
}
|
|
// 倒计时样式
|
.countdown-timer {
|
font-weight: bold;
|
}
|
|
.countdown-normal {
|
color: #67c23a;
|
}
|
|
.countdown-warning {
|
color: #e6a23c;
|
}
|
|
.countdown-urgent {
|
color: #f56c6c;
|
animation: blink 1s infinite;
|
}
|
|
.countdown-expired {
|
color: #f56c6c;
|
font-weight: bold;
|
}
|
|
@keyframes blink {
|
0%, 50% { opacity: 1; }
|
51%, 100% { opacity: 0.5; }
|
}
|
|
// 缺气预警弹框样式
|
.shortage-warning-content {
|
text-align: center;
|
padding: 20px 0;
|
|
.warning-icon {
|
margin-bottom: 20px;
|
}
|
|
.warning-message {
|
h3 {
|
color: #f56c6c;
|
margin-bottom: 10px;
|
}
|
|
p {
|
margin-bottom: 10px;
|
color: #606266;
|
}
|
|
.warning-details {
|
background: #f5f7fa;
|
padding: 15px;
|
border-radius: 4px;
|
text-align: left;
|
font-size: 14px;
|
line-height: 1.6;
|
}
|
}
|
}
|
}
|
</style>
|