|
|
|
@ -18,6 +18,26 @@
|
|
|
|
|
<div class="stat-label">设备总数</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="stat-card alarm-rule">
|
|
|
|
|
<div class="stat-icon">
|
|
|
|
|
<i class="el-icon-warning"></i>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="stat-content">
|
|
|
|
|
<div class="stat-number">{{ alarmRuleTotalCount }}</div>
|
|
|
|
|
<div class="stat-label">异常规则数量</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="stat-card alarm-data">
|
|
|
|
|
<div class="stat-icon">
|
|
|
|
|
<i class="el-icon-bell"></i>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="stat-content">
|
|
|
|
|
<div class="stat-number">{{ alarmDataTotalCount }}</div>
|
|
|
|
|
<div class="stat-label">异常数据数量</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
@ -135,6 +155,8 @@
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
import { getLatestRecords } from '@/api/ems/record/recordIotenvInstant'
|
|
|
|
|
import {getAlarmDataTotalCount} from "@/api/ems/record/recordAlarmData";
|
|
|
|
|
import {getEmsRecordAlarmRuleTotalCount} from "@/api/ems/record/recordAlarmRule";
|
|
|
|
|
|
|
|
|
|
export default {
|
|
|
|
|
name: 'Dashboard',
|
|
|
|
@ -142,7 +164,9 @@ export default {
|
|
|
|
|
return {
|
|
|
|
|
loading: false,
|
|
|
|
|
deviceList: [],
|
|
|
|
|
refreshTimer: null
|
|
|
|
|
refreshTimer: null,
|
|
|
|
|
alarmRuleTotalCount:0,
|
|
|
|
|
alarmDataTotalCount:0
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
computed: {
|
|
|
|
@ -166,6 +190,8 @@ export default {
|
|
|
|
|
async loadDeviceData() {
|
|
|
|
|
this.loading = true
|
|
|
|
|
try {
|
|
|
|
|
this.alarmDataTotalCount = await getAlarmDataTotalCount();
|
|
|
|
|
this.alarmRuleTotalCount = await getEmsRecordAlarmRuleTotalCount();
|
|
|
|
|
const response = await getLatestRecords()
|
|
|
|
|
if (response.code === 200) {
|
|
|
|
|
// 过滤掉异常数据
|
|
|
|
@ -267,7 +293,8 @@ export default {
|
|
|
|
|
console.error('时间格式化失败:', error)
|
|
|
|
|
return '--'
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</script>
|
|
|
|
@ -303,17 +330,18 @@ export default {
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
gap: 20px;
|
|
|
|
|
flex-wrap: wrap;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.stat-card {
|
|
|
|
|
background: white;
|
|
|
|
|
border-radius: 12px;
|
|
|
|
|
padding: 24px;
|
|
|
|
|
padding: 20px;
|
|
|
|
|
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
|
|
|
|
min-width: 250px;
|
|
|
|
|
min-width: 220px;
|
|
|
|
|
|
|
|
|
|
&:hover {
|
|
|
|
|
transform: translateY(-2px);
|
|
|
|
@ -321,16 +349,16 @@ export default {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.stat-icon {
|
|
|
|
|
width: 60px;
|
|
|
|
|
height: 60px;
|
|
|
|
|
border-radius: 12px;
|
|
|
|
|
width: 50px;
|
|
|
|
|
height: 50px;
|
|
|
|
|
border-radius: 10px;
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
margin-right: 16px;
|
|
|
|
|
margin-right: 14px;
|
|
|
|
|
|
|
|
|
|
i {
|
|
|
|
|
font-size: 24px;
|
|
|
|
|
font-size: 20px;
|
|
|
|
|
color: white;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -339,7 +367,7 @@ export default {
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
|
|
|
|
.stat-number {
|
|
|
|
|
font-size: 32px;
|
|
|
|
|
font-size: 28px;
|
|
|
|
|
font-weight: 700;
|
|
|
|
|
line-height: 1;
|
|
|
|
|
margin-bottom: 4px;
|
|
|
|
@ -359,6 +387,24 @@ export default {
|
|
|
|
|
color: #409eff;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
&.alarm-rule {
|
|
|
|
|
.stat-icon {
|
|
|
|
|
background: linear-gradient(135deg, #e6a23c, #f0c040);
|
|
|
|
|
}
|
|
|
|
|
.stat-number {
|
|
|
|
|
color: #e6a23c;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
&.alarm-data {
|
|
|
|
|
.stat-icon {
|
|
|
|
|
background: linear-gradient(135deg, #f56c6c, #ff8080);
|
|
|
|
|
}
|
|
|
|
|
.stat-number {
|
|
|
|
|
color: #f56c6c;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -379,17 +425,18 @@ export default {
|
|
|
|
|
|
|
|
|
|
.device-grid {
|
|
|
|
|
display: grid;
|
|
|
|
|
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
|
|
|
|
|
gap: 20px;
|
|
|
|
|
grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
|
|
|
|
|
gap: 10px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.device-card {
|
|
|
|
|
background: white;
|
|
|
|
|
border-radius: 12px;
|
|
|
|
|
padding: 20px;
|
|
|
|
|
border-radius: 10px;
|
|
|
|
|
padding: 10px;
|
|
|
|
|
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
|
|
|
|
transition: all 0.3s ease;
|
|
|
|
|
border-left: 4px solid #e9ecef;
|
|
|
|
|
font-size: 0.92em;
|
|
|
|
|
|
|
|
|
|
&:hover {
|
|
|
|
|
transform: translateY(-2px);
|
|
|
|
@ -475,7 +522,7 @@ export default {
|
|
|
|
|
|
|
|
|
|
.device-data {
|
|
|
|
|
.data-row {
|
|
|
|
|
margin-bottom: 12px;
|
|
|
|
|
margin-bottom: 8px;
|
|
|
|
|
|
|
|
|
|
&:last-child {
|
|
|
|
|
margin-bottom: 0;
|
|
|
|
@ -485,7 +532,7 @@ export default {
|
|
|
|
|
.data-item {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
padding: 8px 0;
|
|
|
|
|
padding: 6px 0;
|
|
|
|
|
|
|
|
|
|
.data-icon {
|
|
|
|
|
width: 20px;
|
|
|
|
@ -520,12 +567,12 @@ export default {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.device-footer {
|
|
|
|
|
margin-top: 16px;
|
|
|
|
|
padding-top: 16px;
|
|
|
|
|
margin-top: 8px;
|
|
|
|
|
padding-top: 8px;
|
|
|
|
|
border-top: 1px solid #f0f0f0;
|
|
|
|
|
|
|
|
|
|
.update-time {
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
font-size: 11px;
|
|
|
|
|
color: #7f8c8d;
|
|
|
|
|
|
|
|
|
|
i {
|
|
|
|
|