添加总览功能

This commit is contained in:
砂糖
2025-10-15 16:29:00 +08:00
parent b843776a7f
commit e59767375f
11 changed files with 688 additions and 533 deletions

View File

@@ -0,0 +1,184 @@
<template>
<div class="left-monitor-card">
<h3>实时监测 <span class="refresh-time">(最后更新: {{ lastRefreshTime }})</span></h3>
<!-- 消防安全板块 -->
<div class="section">
<p class="alarm-total">报警设备<span class="alarm-num">{{ alarmCount }}</span> / {{ totalDevices }}</p>
<div class="table-container">
<table>
<thead>
<tr>
<th>位置</th>
<th>报警数量</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, index) in alarmList" :key="index">
<td>{{ item.location }}</td>
<td class="red">{{ item.count }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
// 设备总数
totalDevices: 424,
// 报警设备数量
alarmCount: 115,
// 报警列表数据
alarmList: [
{ location: '3#开关站2层', count: 24 },
{ location: '3#罩式炉电气室2层', count: 22 },
{ location: '3#罩式炉电气室1层', count: 13 }
],
// 最后刷新时间
lastRefreshTime: '',
// 定时器ID
timer: null,
// 刷新间隔(毫秒)
refreshInterval: 5000
}
},
mounted() {
// 初始化最后刷新时间
this.updateRefreshTime();
// 启动定时刷新
this.startRefresh();
},
beforeUnmount() {
// 组件销毁前清除定时器
if (this.timer) {
clearTimeout(this.timer);
}
},
methods: {
// 启动定时刷新
startRefresh() {
// 清除可能存在的定时器
if (this.timer) {
clearTimeout(this.timer);
}
// 设置新的定时器
this.timer = setTimeout(() => {
// 刷新数据
this.refreshData();
// 更新刷新时间
this.updateRefreshTime();
// 递归调用,实现定时循环
this.startRefresh();
}, this.refreshInterval);
},
// 模拟数据刷新
refreshData() {
// 随机更新报警设备总数(在一定范围内波动)
const minChange = -5;
const maxChange = 5;
const change = Math.floor(Math.random() * (maxChange - minChange + 1)) + minChange;
this.alarmCount = Math.max(0, Math.min(this.totalDevices, this.alarmCount + change));
// 随机更新每个位置的报警数量
this.alarmList = this.alarmList.map(item => {
const itemChange = Math.floor(Math.random() * 5) - 2; // -2到2之间的随机变化
return {
...item,
count: Math.max(0, item.count + itemChange)
};
});
},
// 更新最后刷新时间
updateRefreshTime() {
const now = new Date();
this.lastRefreshTime = `${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}:${now.getSeconds().toString().padStart(2, '0')}`;
}
}
}
</script>
<style scoped>
.left-monitor-card {
background: rgba(255, 255, 255, 0.8);
border-radius: 4px;
padding: 4px;
width: 280px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
h3 {
font-size: 14px;
font-weight: bold;
margin-bottom: 16px;
border-bottom: 1px solid #eee;
padding-bottom: 4px;
display: flex;
justify-content: space-between;
}
.refresh-time {
font-size: 12px;
font-weight: normal;
color: #666;
}
h4 {
font-size: 14px;
margin: 12px 0 8px;
}
.alarm-total {
font-size: 14px;
margin-bottom: 8px;
}
.alarm-num {
color: #e53935;
font-weight: bold;
}
.normal-num {
color: #43a047;
font-weight: bold;
}
.table-container {
max-height: 200px;
overflow-y: auto;
}
table {
width: 100%;
border-collapse: collapse;
font-size: 14px;
}
th, td {
padding: 8px;
text-align: left;
border-bottom: 1px solid #eee;
}
th {
background: #f5f5f5;
}
.red {
color: #e53935;
}
.normal-dot {
display: inline-block;
width: 10px;
height: 10px;
border-radius: 50%;
background: #43a047;
}
</style>

View File

@@ -0,0 +1,85 @@
<template>
<div class="bottom-records-card">
<div style="display: flex; justify-content: space-between; align-items: center;">
<h3>报警记录</h3>
<el-button type="text" @click="handleMore">查看更多</el-button>
</div>
<el-table v-loading="loading" :data="list">
<el-table-column label="告警设备" align="center" prop="deviceName" />
<el-table-column label="警报类型" align="center" prop="alarmType">
<template slot-scope="scope">
<dict-tag :options="dict.type.alarm_record_type" :value="scope.row.alarmType"/>
</template>
</el-table-column>
<el-table-column label="警报级别" align="center" prop="alarmLevel">
<template slot-scope="scope">
<dict-tag :options="dict.type.alarm_record_level" :value="scope.row.alarmLevel"/>
</template>
</el-table-column>
<el-table-column label="警报内容" align="center" prop="alarmContent">
<template slot-scope="scope">
<div v-html="scope.row.alarmContent" style="max-width: 150px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;"></div>
</template>
</el-table-column>
<el-table-column label="发生时间" align="center" prop="alarmTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.alarmTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="处理状态" align="center" prop="handleStatus" />
<el-table-column label="处理人" align="center" prop="handleUser" />
<el-table-column label="处理时间" align="center" prop="handleTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.handleTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="处理备注" align="center" prop="handleNotes" />
<el-table-column label="备注" align="center" prop="remark" />
</el-table>
</div>
</template>
<script>
import { listAlarmRecord } from '@/api/ems/alarmRecord'
export default {
dicts: ['alarm_record_type', 'alarm_record_level'],
data() {
return {
list: [],
loading: true,
}
},
created() {
this.getList()
},
methods: {
getList() {
listAlarmRecord({ pageNum: 1, pageSize: 3 }).then(res => {
this.list = res.rows
this.loading = false
})
},
handleMore() {
this.$router.push('/system/env/alarmRecord')
}
}
}
</script>
<style scoped>
.bottom-records-card {
background: rgba(255, 255, 255, 0.8);
border-radius: 4px;
padding: 4px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
h3 {
font-size: 18px;
font-weight: bold;
margin-bottom: 16px;
border-bottom: 1px solid #eee;
padding-bottom: 8px;
}
</style>

View File

@@ -0,0 +1,59 @@
<template>
<div class="right-statistics-card">
<h3>今年安全生产天数: 30</h3>
<div class="section">
<h4>报警统计</h4>
<div class="alarm-item green-border">
<span>近一月</span>
<span>0</span>
</div>
<div class="alarm-item green-border">
<span>近一季</span>
<span>0</span>
</div>
<div class="alarm-item green-border">
<span>近一年</span>
<span>0</span>
</div>
</div>
</div>
</template>
<style scoped>
.right-statistics-card {
background: rgba(255, 255, 255, 0.8);
border-radius: 8px;
padding: 16px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
h3 {
font-size: 18px;
font-weight: bold;
margin-bottom: 16px;
border-bottom: 1px solid #eee;
padding-bottom: 8px;
}
h4 {
font-size: 16px;
margin-bottom: 12px;
}
.alarm-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px;
margin-bottom: 8px;
border-radius: 4px;
}
.green-border {
border: 1px solid #43a047;
}
.red-border {
border: 1px solid #e53935;
}
</style>