feat:设备概括模块
parent
e41283295b
commit
6bf11ff41c
@ -0,0 +1,156 @@
|
|||||||
|
<template>
|
||||||
|
<view class="device-section">
|
||||||
|
<view class="section-title">{{ t('deviceOverview.title') }}</view>
|
||||||
|
<view class="trend-stats">
|
||||||
|
<view class="trend-stat-card">
|
||||||
|
<text class="trend-stat-value">{{ deviceData.totalDevices }}</text>
|
||||||
|
<text class="trend-stat-label">{{ t('deviceOverview.totalDevices') }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="trend-stat-card">
|
||||||
|
<text class="trend-stat-value running">{{ deviceData.runningCount }}</text>
|
||||||
|
<text class="trend-stat-label">{{ t('deviceOverview.runningCount') }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="trend-stat-card">
|
||||||
|
<text class="trend-stat-value standby">{{ deviceData.standbyCount }}</text>
|
||||||
|
<text class="trend-stat-label">{{ t('deviceOverview.standbyCount') }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="trend-stat-card">
|
||||||
|
<text class="trend-stat-value fault">{{ deviceData.faultCount }}</text>
|
||||||
|
<text class="trend-stat-label">{{ t('deviceOverview.faultCount') }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="trend-stats">
|
||||||
|
<view class="trend-stat-card">
|
||||||
|
<text class="trend-stat-value offline">{{ deviceData.offlineCount }}</text>
|
||||||
|
<text class="trend-stat-label">{{ t('deviceOverview.offlineCount') }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="trend-stat-card">
|
||||||
|
<text class="trend-stat-value">{{ deviceData.utilizationRate }}</text>
|
||||||
|
<text class="trend-stat-label">{{ t('deviceOverview.utilizationRate') }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="trend-stat-card">
|
||||||
|
<text class="trend-stat-value running">{{ deviceData.bootRate }}</text>
|
||||||
|
<text class="trend-stat-label">{{ t('deviceOverview.bootRate') }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="trend-stat-card">
|
||||||
|
<text class="trend-stat-value fault">{{ deviceData.faultRate }}</text>
|
||||||
|
<text class="trend-stat-label">{{ t('deviceOverview.faultRate') }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { reactive, onMounted } from 'vue'
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
const deviceData = reactive({
|
||||||
|
totalDevices: 0,
|
||||||
|
runningCount: 0,
|
||||||
|
standbyCount: 0,
|
||||||
|
faultCount: 0,
|
||||||
|
offlineCount: 0,
|
||||||
|
utilizationRate: '-',
|
||||||
|
bootRate: '-',
|
||||||
|
faultRate: '-'
|
||||||
|
})
|
||||||
|
|
||||||
|
async function loadDeviceOverview() {
|
||||||
|
const res = await request({ url: '/admin-api/iot/device/getDeviceOverview', method: 'get' })
|
||||||
|
const data = res?.data || {}
|
||||||
|
deviceData.totalDevices = data.totalDevices ?? 0
|
||||||
|
deviceData.runningCount = data.runningCount ?? 0
|
||||||
|
deviceData.standbyCount = data.standbyCount ?? 0
|
||||||
|
deviceData.faultCount = data.faultCount ?? 0
|
||||||
|
deviceData.offlineCount = data.offlineCount ?? 0
|
||||||
|
deviceData.utilizationRate = data.utilizationRate ?? '-'
|
||||||
|
deviceData.bootRate = data.bootRate ?? '-'
|
||||||
|
deviceData.faultRate = data.faultRate ?? '-'
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
loadDeviceOverview()
|
||||||
|
})
|
||||||
|
|
||||||
|
defineExpose({ loadDeviceOverview })
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.device-section {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
background: #ffffff;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
padding: 28rpx;
|
||||||
|
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #1a3a5c;
|
||||||
|
margin-bottom: 24rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.trend-stats {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 24rpx;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.trend-stat-card {
|
||||||
|
flex: 1;
|
||||||
|
background: #f8fafc;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
padding: 20rpx 12rpx;
|
||||||
|
margin: 0 6rpx;
|
||||||
|
text-align: center;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.trend-stat-value {
|
||||||
|
display: block;
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #1a3a5c;
|
||||||
|
margin-bottom: 6rpx;
|
||||||
|
|
||||||
|
&.running {
|
||||||
|
color: #18bc37;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.standby {
|
||||||
|
color: #4a90c2;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.fault {
|
||||||
|
color: #ff4d4f;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.offline {
|
||||||
|
color: #999999;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.trend-stat-label {
|
||||||
|
display: block;
|
||||||
|
font-size: 22rpx;
|
||||||
|
color: #999999;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Loading…
Reference in New Issue