458 lines
9.9 KiB
Vue
458 lines
9.9 KiB
Vue
<template>
|
|
<view class="container">
|
|
<!-- 设备统计卡片 -->
|
|
<view class="stat-card">
|
|
<view class="card-header">
|
|
<view class="header-left">
|
|
<u-icon name="grid" size="34" color="#666"></u-icon>
|
|
<text class="header-title">设备统计</text>
|
|
</view>
|
|
<view class="header-right" @click="viewDeviceDetails">
|
|
<text class="detail-text">查看详情</text>
|
|
<u-icon name="arrow-right" size="28" color="#999"></u-icon>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 设备数量统计 -->
|
|
<view class="stat-row">
|
|
<view class="stat-item">
|
|
<text class="stat-value blue">{{deviceInfo.deviceNum || 0}}</text>
|
|
<text class="stat-label">设备数量</text>
|
|
</view>
|
|
<view class="stat-item">
|
|
<text class="stat-value blue">{{deviceInfo.deviceOnlineNum || 0}}</text>
|
|
<text class="stat-label">在线数</text>
|
|
</view>
|
|
<view class="stat-item">
|
|
<text class="stat-value blue">{{deviceInfo.deviceOfflineNum || 0}}</text>
|
|
<text class="stat-label">离线数</text>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 设备消息量统计 -->
|
|
<view class="stat-row">
|
|
<view class="stat-item">
|
|
<text class="stat-value blue">{{deviceInfo.todayMessageNum || 0}}</text>
|
|
<text class="stat-label">今日设备消息量</text>
|
|
</view>
|
|
<view class="stat-item">
|
|
<text class="stat-value blue">{{deviceInfo.thisMonthMessageNum || 0}}</text>
|
|
<text class="stat-label">当月设备消息量</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 告警统计卡片 -->
|
|
<view class="stat-card">
|
|
<view class="card-header">
|
|
<view class="header-left">
|
|
<u-icon name="bell" size="34" color="#666"></u-icon>
|
|
<text class="header-title">告警统计</text>
|
|
</view>
|
|
<view class="header-right" @click="viewAlarmDetails">
|
|
<text class="detail-text">查看详情</text>
|
|
<u-icon name="arrow-right" size="28" color="#999"></u-icon>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 告警数量统计 -->
|
|
<view class="stat-row">
|
|
<view class="stat-item">
|
|
<text class="stat-value red">{{alarmInfo.todayMessageNum || 0}}</text>
|
|
<text class="stat-label">今日告警数</text>
|
|
</view>
|
|
<view class="stat-item">
|
|
<text class="stat-value red">{{alarmInfo.thisMonthMessageNum || 0}}</text>
|
|
<text class="stat-label">当月告警数</text>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 最新告警列表 -->
|
|
<view class="alarm-list">
|
|
<view class="alarm-list-title">最新告警列表</view>
|
|
|
|
<!-- 告警项 -->
|
|
<u-empty v-if="alarmList.length == 0" margin-top="50" text="告警列表为空" mode="list"></u-empty>
|
|
<view v-else class="alarm-item" v-for="(item, index) in alarmList" :key="index">
|
|
<view class="alarm-info">
|
|
<text class="alarm-name">{{ item.alarmName }}</text>
|
|
<text class="alarm-status">{{ item.state.text }}</text>
|
|
</view>
|
|
<view class="alarm-detail">
|
|
<view :class="['alarm-level', 'alarm-level-' + item.level]">{{ getAlarmName(item.level) }}</view>
|
|
<text class="alarm-time">{{$u.timeFormat(item.time, 'yyyy-mm-dd hh:MM:ss')}}</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
data() {
|
|
return {
|
|
deviceInfo:{
|
|
deviceNum:0,
|
|
deviceOnlineNum:0,
|
|
deviceOfflineNum:0,
|
|
todayMessageNum:0,
|
|
thisMonthMessageNum:0,
|
|
},
|
|
alarmInfo:{
|
|
todayMessageNum:0,
|
|
thisMonthMessageNum:0,
|
|
},
|
|
alarmLevelList:[
|
|
{
|
|
level: 1,
|
|
title: "超紧急"
|
|
},
|
|
{
|
|
level: 2,
|
|
title: "紧急"
|
|
},
|
|
{
|
|
level: 3,
|
|
title: "严重"
|
|
},
|
|
{
|
|
level: 4,
|
|
title: "一般"
|
|
},
|
|
{
|
|
level: 5,
|
|
title: "提醒"
|
|
}
|
|
],
|
|
alarmList: []
|
|
};
|
|
},
|
|
onLoad() {
|
|
this.getAlarmLevelList();
|
|
},
|
|
onShow() {
|
|
this.getDeviceInfo();
|
|
this.getDeviceMessageCount();
|
|
this.getAlarmMessageCount();
|
|
this.getAlarmList();
|
|
},
|
|
methods: {
|
|
getAlarmName(level) {
|
|
const foundItem = this.alarmLevelList.find(item => item.level === level);
|
|
return foundItem ? foundItem.title : '';
|
|
},
|
|
getAlarmLevelList(){
|
|
this.$api.iotsApi.getAlarmLevelList().then(res => {
|
|
if(res.status == 200){
|
|
this.alarmLevelList = res.result.levels || [];
|
|
}else{
|
|
this.$u.toast(res.message);
|
|
}
|
|
}, error => {
|
|
this.$u.toast('服务器开小差了呢,请您稍后再试')
|
|
})
|
|
},
|
|
getDeviceInfo(){
|
|
this.getDeviceCount('deviceNum',{})
|
|
this.getDeviceCount('deviceOnlineNum',{'terms[0].column':'state','terms[0].value':'online'})
|
|
this.getDeviceCount('deviceOfflineNum',{'terms[0].column':'state','terms[0].value':'offline'})
|
|
},
|
|
viewDeviceDetails() {
|
|
uni.switchTab({
|
|
url: '/pages/tabbar/device'
|
|
});
|
|
},
|
|
viewAlarmDetails() {
|
|
uni.navigateTo({
|
|
url: '/pages/alarm/statistics-detail'
|
|
});
|
|
},
|
|
getDeviceCount(type,params){
|
|
this.$api.iotsApi.getDeviceInstanceCount(params).then(res => {
|
|
if(res.status == 200){
|
|
this.deviceInfo[type] = res.result;
|
|
}else{
|
|
this.$u.toast(res.message);
|
|
}
|
|
}, error => {
|
|
this.$u.toast('服务器开小差了呢,请您稍后再试')
|
|
})
|
|
},
|
|
getDeviceMessageCount(){
|
|
this.$api.getDashboardSelect([
|
|
{
|
|
"dashboard": "device",
|
|
"object": "message",
|
|
"measurement": "quantity",
|
|
"dimension": "agg",
|
|
"group": "oneday",
|
|
"params": {
|
|
"time": "1d",
|
|
"format": "yyyy-MM-dd",
|
|
"from": "now-1d"
|
|
}
|
|
},
|
|
{
|
|
"dashboard": "device",
|
|
"object": "message",
|
|
"measurement": "quantity",
|
|
"dimension": "agg",
|
|
"group": "thisMonth",
|
|
"params": {
|
|
"time": "1M",
|
|
"format": "yyyy-MM",
|
|
"limit": 1,
|
|
"from": "now-1M"
|
|
}
|
|
}
|
|
]).then(res => {
|
|
if(res.status == 200){
|
|
if(res.result && Array.isArray(res.result)){
|
|
res.result.forEach((item)=>{
|
|
if(item.group === 'oneday'){
|
|
this.deviceInfo.todayMessageNum = item.data.value || 0;
|
|
}else if(item.group === 'thisMonth'){
|
|
this.deviceInfo.thisMonthMessageNum = item.data.value || 0;
|
|
}
|
|
})
|
|
}
|
|
}else{
|
|
this.$u.toast(res.message);
|
|
}
|
|
}, error => {
|
|
this.$u.toast('服务器开小差了呢,请您稍后再试')
|
|
})
|
|
},
|
|
getAlarmMessageCount(){
|
|
this.$api.getDashboardSelect([
|
|
{
|
|
"dashboard": "alarm",
|
|
"object": "record",
|
|
"measurement": "trend",
|
|
"dimension": "agg",
|
|
"group": "today",
|
|
"params": {
|
|
"time": "1d",
|
|
"format": "HH:mm:ss",
|
|
"from": "2025-04-24 00:00:00",
|
|
"to": "now"
|
|
}
|
|
},
|
|
{
|
|
"dashboard": "alarm",
|
|
"object": "record",
|
|
"measurement": "trend",
|
|
"dimension": "agg",
|
|
"group": "thisMonth",
|
|
"params": {
|
|
"time": "1M",
|
|
"format": "yyyy-MM",
|
|
"limit": 1,
|
|
"from": "now-1M"
|
|
}
|
|
}
|
|
]).then(res => {
|
|
if(res.status == 200){
|
|
if(res.result && Array.isArray(res.result)){
|
|
res.result.forEach((item)=>{
|
|
if(item.group === 'today'){
|
|
this.alarmInfo.todayMessageNum = item.data.value || 0;
|
|
}else if(item.group === 'thisMonth'){
|
|
this.alarmInfo.thisMonthMessageNum = item.data.value || 0;
|
|
}
|
|
})
|
|
}
|
|
}else{
|
|
this.$u.toast(res.message);
|
|
}
|
|
}, error => {
|
|
this.$u.toast('服务器开小差了呢,请您稍后再试')
|
|
})
|
|
},
|
|
getAlarmList(){
|
|
this.$api.iotsApi.getAlarmList({
|
|
"pageIndex": 0,
|
|
"pageSize": 5,
|
|
"sorts": [
|
|
{
|
|
"name": "alarmTime",
|
|
"order": "desc"
|
|
}
|
|
],
|
|
"terms": [
|
|
{
|
|
"terms": [
|
|
{
|
|
"type": "and",
|
|
"value": "%warning%",
|
|
"termType": "like",
|
|
"column": "state"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}).then(res => {
|
|
if(res.status == 200){
|
|
this.alarmList = res.result.data || [];
|
|
}else{
|
|
this.$u.toast(res.message);
|
|
}
|
|
}, error => {
|
|
this.$u.toast('服务器开小差了呢,请您稍后再试')
|
|
})
|
|
},
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.container {
|
|
background-color: #f5f5f5;
|
|
padding: 20rpx;
|
|
min-height: 100%;
|
|
}
|
|
|
|
.stat-card {
|
|
background-color: #fff;
|
|
border-radius: 16rpx;
|
|
margin-bottom: 20rpx;
|
|
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
|
}
|
|
|
|
.card-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: 30rpx;
|
|
border-bottom: 2px solid #F9F9F9;
|
|
|
|
.header-left {
|
|
display: flex;
|
|
align-items: center;
|
|
|
|
.header-title {
|
|
font-size: 32rpx;
|
|
font-weight: 500;
|
|
margin-left: 10rpx;
|
|
color: #333;
|
|
}
|
|
}
|
|
|
|
.header-right {
|
|
display: flex;
|
|
align-items: center;
|
|
|
|
.detail-text {
|
|
font-size: 26rpx;
|
|
color: #999;
|
|
margin-right: 6rpx;
|
|
}
|
|
}
|
|
}
|
|
|
|
.stat-row {
|
|
display: flex;
|
|
justify-content: space-around;
|
|
margin-bottom: 20rpx;
|
|
padding: 30rpx;
|
|
.stat-item {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
flex: 1;
|
|
|
|
.stat-value {
|
|
font-size: 40rpx;
|
|
font-weight: bold;
|
|
margin-bottom: 10rpx;
|
|
|
|
&.blue {
|
|
color: #2979ff;
|
|
}
|
|
|
|
&.red {
|
|
color: #ff5252;
|
|
}
|
|
}
|
|
|
|
.stat-label {
|
|
font-size: 24rpx;
|
|
color: #666;
|
|
}
|
|
}
|
|
}
|
|
|
|
.alarm-list {
|
|
padding: 30rpx;
|
|
.alarm-list-title {
|
|
font-size: 28rpx;
|
|
font-weight: 500;
|
|
color: #333;
|
|
margin-bottom: 20rpx;
|
|
}
|
|
|
|
.alarm-item {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
padding: 20rpx 0;
|
|
border-bottom: 1px solid #f0f0f0;
|
|
|
|
&:last-child {
|
|
border-bottom: none;
|
|
}
|
|
|
|
.alarm-info {
|
|
.alarm-name {
|
|
font-size: 28rpx;
|
|
color: #333;
|
|
margin-bottom: 10rpx;
|
|
display: block;
|
|
}
|
|
|
|
.alarm-status {
|
|
font-size: 24rpx;
|
|
color: #999;
|
|
}
|
|
}
|
|
|
|
.alarm-detail {
|
|
text-align: right;
|
|
|
|
.alarm-level {
|
|
display: inline-block;
|
|
padding: 4rpx 16rpx;
|
|
border-radius: 6rpx;
|
|
font-size: 22rpx;
|
|
margin-bottom: 10rpx;
|
|
color: #fff;
|
|
&.alarm-level-1 {
|
|
background-color: #E50012;
|
|
}
|
|
|
|
&.alarm-level-2 {
|
|
background-color: #FF9457;
|
|
}
|
|
|
|
&.alarm-level-3 {
|
|
background-color: #FABD47;
|
|
}
|
|
|
|
&.alarm-level-4 {
|
|
background-color: #999999;
|
|
}
|
|
|
|
&.alarm-level-5 {
|
|
background-color: #BBBBBB;
|
|
}
|
|
}
|
|
|
|
.alarm-time {
|
|
font-size: 22rpx;
|
|
color: #999;
|
|
display: block;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style> |