<template>
|
<div class="machine-monitor-container">
|
<!-- 页面头部 -->
|
<div class="monitor-header">
|
<h1>设备状态监控中心</h1>
|
<div class="header-actions">
|
<el-button type="success" @click="startElevator()">
|
<span class="text">启动提升机</span>
|
</el-button>
|
<el-button type="danger" @click="stopElevator()">
|
<span class="text">停止提升机</span>
|
</el-button>
|
<el-button type="warning" @click="resetElevator()">
|
<span class="text">复位提升机</span>
|
</el-button>
|
<el-button type="primary" @click="initializationElevator()">
|
<span class="text">初始化提升机</span>
|
</el-button>
|
<el-button type="primary" @click="refreshData" :loading="refreshing" icon="Refresh">
|
手动刷新
|
</el-button>
|
<el-switch v-model="autoRefresh" active-text="自动刷新开启" inactive-text="自动刷新关闭"
|
@change="toggleAutoRefresh" />
|
</div>
|
</div>
|
|
<!-- 统计卡片 -->
|
<div class="stat-cards">
|
<el-card class="stat-card" :class="getStatusClass('normal')">
|
<div class="stat-content">
|
<span class="stat-label">运行设备</span>
|
<span class="stat-value">{{ normalCount }}</span>
|
</div>
|
</el-card>
|
<el-card class="stat-card" :class="getStatusClass('warning')">
|
<div class="stat-content">
|
<span class="stat-label">空闲设备</span>
|
<span class="stat-value">{{ warningCount }}</span>
|
</div>
|
</el-card>
|
<el-card class="stat-card" :class="getStatusClass('error')">
|
<div class="stat-content">
|
<span class="stat-label">报警设备</span>
|
<span class="stat-value">{{ errorCount }}</span>
|
</div>
|
</el-card>
|
<el-card class="stat-card" :class="getStatusClass('offline')">
|
<div class="stat-content">
|
<span class="stat-label">离线设备</span>
|
<span class="stat-value">{{ offlineCount }}</span>
|
</div>
|
</el-card>
|
<el-card class="stat-card">
|
<div class="stat-content">
|
<span class="stat-label">总计设备</span>
|
<span class="stat-value">{{ totalCount }}</span>
|
</div>
|
</el-card>
|
</div>
|
|
<!-- 设备列表 -->
|
<div class="machine-list">
|
<el-table :data="filteredMachines" border stripe v-loading="tableLoading" style="width: 100%"
|
:empty-text="tableEmptyText">
|
<el-table-column prop="id" label="设备编号" width="120" />
|
<el-table-column prop="name" label="设备名称" width="150" />
|
<el-table-column prop="type" label="设备类型" width="240" />
|
<el-table-column prop="status" label="运行状态" min-width="150" />
|
<el-table-column prop="alarmInformation" label="报警信息" min-width="250" />
|
<el-table-column prop="lastUpdate" label="最后更新" width="200" />
|
</el-table>
|
</div>
|
</div>
|
</template>
|
|
<script setup>
|
import { ref, computed, onMounted, onUnmounted } from 'vue'
|
import { ElMessage } from 'element-plus' // 正确导入Element Plus消息组件
|
import axios from 'axios' // 导入axios
|
|
const requestElevator = async (url, actionName) => {
|
try {
|
// 发起POST请求(替换为你的实际接口地址)
|
const res = await axios.post(`http://10.31.3.241:9291/api/Elevator/${url}`)
|
// 接口返回逻辑:假设res.data.status为true表示成功
|
if (!res.data.status) {
|
ElMessage.error(res.data.message || `${actionName}失败`)
|
} else {
|
ElMessage.success(`${actionName}成功`)
|
// 刷新设备数据
|
await refreshData()
|
}
|
} catch (error) {
|
console.error(`${actionName}接口异常:`, error)
|
ElMessage.error(`${actionName}失败,接口请求异常`)
|
}
|
}
|
|
const machines = ref([])
|
const searchKeyword = ref('')
|
const statusFilter = ref('')
|
const autoRefresh = ref(true)
|
const refreshing = ref(false)
|
const tableLoading = ref(false)
|
const detailVisible = ref(false)
|
const currentMachine = ref(null)
|
const refreshTimer = ref(null)
|
|
const filteredMachines = computed(() => {
|
let result = machines.value
|
return result
|
})
|
|
const normalCount = computed(() => machines.value.filter(item => item.status == '运行中').length)
|
const warningCount = computed(() => machines.value.filter(item => item.status === '空闲' || item.status == '待机').length)
|
const errorCount = computed(() => machines.value.filter(item => item.alarmInformation != null && item.alarmInformation != "").length)
|
const offlineCount = computed(() => machines.value.filter(item => item.status === 'offline').length)
|
const totalCount = computed(() => machines.value.length)
|
|
const tableEmptyText = computed(() => {
|
if (searchKeyword.value || statusFilter.value) {
|
return '暂无匹配的设备数据'
|
}
|
return '暂无设备数据'
|
})
|
|
const getStatusClass = (status) => {
|
const classMap = {
|
normal: 'stat-normal',
|
warning: 'stat-warning',
|
error: 'stat-error',
|
offline: 'stat-offline'
|
}
|
return classMap[status] || ''
|
}
|
|
const refreshData = async () => {
|
refreshing.value = true
|
tableLoading.value = true
|
try {
|
const newData = await fetchEquipmentData()
|
machines.value = newData
|
// ElMessage.success('数据刷新成功')
|
} catch (error) {
|
ElMessage.error('数据刷新失败')
|
} finally {
|
refreshing.value = false
|
tableLoading.value = false
|
}
|
}
|
|
const toggleAutoRefresh = () => {
|
if (autoRefresh.value) {
|
startAutoRefresh()
|
ElMessage.success('自动刷新已开启(每10秒)')
|
} else {
|
stopAutoRefresh()
|
ElMessage.info('自动刷新已关闭')
|
}
|
}
|
|
const startAutoRefresh = () => {
|
if (refreshTimer.value) clearInterval(refreshTimer.value)
|
refreshTimer.value = setInterval(refreshData, 10000)
|
}
|
|
const stopAutoRefresh = () => {
|
if (refreshTimer.value) {
|
clearInterval(refreshTimer.value)
|
refreshTimer.value = null
|
}
|
}
|
|
const fetchEquipmentData = async () => {
|
try {
|
const res = await axios.post('http://localhost:9291/api/EquipmentStatus/GetData')
|
if (!res.data || !Array.isArray(res.data.data)) {
|
return generateFallbackData()
|
}
|
const equipmentList = res.data.data.map(item => ({
|
id: item.deviceCode,
|
name: item.deviceName,
|
type: item.deviceType,
|
status: item.deviceRunStatus || ['normal', 'warning', 'error', 'offline'][Math.floor(Math.random() * 4)],
|
alarmInformation: item.alarmInformation,
|
lastUpdate: item.lastUpdate || new Date(Date.now() - Math.random() * 3600000 * 24).toLocaleString()
|
}))
|
return equipmentList
|
} catch (error) {
|
console.error('获取设备数据失败:', error)
|
ElMessage.error('获取设备数据失败,使用备用数据')
|
return generateFallbackData()
|
}
|
}
|
|
const generateFallbackData = () => {
|
return [
|
{
|
id: 'TEST001',
|
name: '测试提升机01',
|
type: '提升机',
|
status: '运行中',
|
alarmInformation: '',
|
lastUpdate: new Date().toLocaleString()
|
},
|
{
|
id: 'TEST002',
|
name: '测试提升机02',
|
type: '提升机',
|
status: '空闲',
|
alarmInformation: '',
|
lastUpdate: new Date().toLocaleString()
|
}
|
]
|
}
|
// 启动提升机
|
const startElevator = () => {
|
requestElevator('startElevator', '启动提升机')
|
}
|
|
// 停止提升机
|
const stopElevator = () => {
|
requestElevator('stopElevator', '停止提升机')
|
}
|
|
// 复位提升机(注意方法名小写开头,符合JS规范)
|
const resetElevator = () => {
|
requestElevator('ResetElevator', '复位提升机')
|
}
|
|
// 初始化提升机
|
const initializationElevator = () => {
|
requestElevator('initialization', '初始化提升机')
|
}
|
|
onMounted(async () => {
|
tableLoading.value = true
|
try {
|
const initData = await fetchEquipmentData()
|
machines.value = initData
|
} finally {
|
tableLoading.value = false
|
}
|
if (autoRefresh.value) {
|
startAutoRefresh()
|
}
|
})
|
|
onUnmounted(() => {
|
stopAutoRefresh()
|
})
|
</script>
|
|
<style scoped>
|
/* 原有样式保留 */
|
.machine-monitor-container {
|
padding: 20px;
|
background-color: #f5f7fa;
|
min-height: 100vh;
|
}
|
|
.monitor-header {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
margin-bottom: 20px;
|
flex-wrap: wrap;
|
gap: 10px;
|
}
|
|
.monitor-header h1 {
|
margin: 0;
|
color: #1989fa;
|
}
|
|
.header-actions {
|
display: flex;
|
align-items: center;
|
flex-wrap: wrap;
|
gap: 10px;
|
}
|
|
.stat-cards {
|
display: flex;
|
gap: 20px;
|
margin-bottom: 20px;
|
flex-wrap: wrap;
|
}
|
|
.stat-card {
|
flex: 1;
|
min-width: 180px;
|
}
|
|
.stat-content {
|
text-align: center;
|
padding: 10px 0;
|
}
|
|
.stat-label {
|
display: block;
|
font-size: 14px;
|
color: #666;
|
margin-bottom: 5px;
|
}
|
|
.stat-value {
|
font-size: 24px;
|
font-weight: bold;
|
}
|
|
.stat-normal .stat-value {
|
color: #67c23a;
|
}
|
|
.stat-warning .stat-value {
|
color: #e6a23c;
|
}
|
|
.stat-error .stat-value {
|
color: #f56c6c;
|
}
|
|
.stat-offline .stat-value {
|
color: #909399;
|
}
|
|
.machine-list {
|
background: #fff;
|
padding: 20px;
|
border-radius: 8px;
|
}
|
|
@media (max-width: 768px) {
|
.stat-cards {
|
flex-direction: column;
|
}
|
|
.monitor-header {
|
flex-direction: column;
|
align-items: flex-start;
|
}
|
|
.header-actions {
|
width: 100%;
|
}
|
|
.el-input {
|
width: 100% !important;
|
}
|
}
|
</style>
|