优化设备状态页面,调整统计信息展示,新增设备分类统计,提升用户体验

This commit is contained in:
yahaozhang
2025-09-16 02:05:49 +08:00
parent e1b3049053
commit 65e6d94f00

View File

@@ -15,22 +15,20 @@
</template>
<div class="stats">
<el-statistic title="设备总数" :value="stats.totalDevices" />
<el-statistic title="可分配数量" :value="stats.availableCount" />
<el-tag type="success" class="inline-tag" v-if="stats.availableCount > 0">可用: {{ stats.availableCount }}</el-tag>
<el-tag type="info" class="inline-tag" v-if="availableDevices.length">{{ availableDevices.join(', ') }}</el-tag>
<el-statistic title="已占用" :value="stats.runningCount" />
<el-statistic title="使用中" :value="stats.usingCount" />
<el-statistic title="冷却空闲" :value="stats.idleCooldownCount" />
<el-statistic title="空闲" :value="stats.idleFreeCount" />
</div>
</el-card>
<el-card class="table-card">
<el-table :data="tableData" v-loading="loading" border style="width: 100%">
<el-table-column prop="deviceId" label="设备编号" width="120" />
<el-table-column prop="series" label="系列" width="100" />
<el-table-column prop="index" label="序号" width="80" />
<el-table-column prop="val" label="原始状态" min-width="160" />
<el-table-column prop="time" label="时间" width="180" />
<el-table-column label="可用" width="100">
<el-table :data="categoryRows" v-loading="loading" border style="width: 100%">
<el-table-column prop="label" label="类别" width="140" />
<el-table-column prop="count" label="数量" width="100" />
<el-table-column label="设备列表" min-width="300">
<template #default="{ row }">
<el-tag :type="row.available ? 'success' : 'danger'">{{ row.available ? '是' : '否' }}</el-tag>
<div class="devices-list" :title="row.devices.join(', ')">{{ row.preview }}</div>
</template>
</el-table-column>
</el-table>
@@ -52,15 +50,17 @@ const loading = ref(false)
const autoRefresh = ref(true)
const timer = ref(null)
const stats = reactive({ totalDevices: 0, availableCount: 0 })
const availableDevices = ref([])
const devicesMap = ref({})
const stats = reactive({ totalDevices: 0, runningCount: 0, usingCount: 0, idleCooldownCount: 0, idleFreeCount: 0 })
const categoryToDevices = ref({})
const tableData = computed(() => {
const map = devicesMap.value || {}
return Object.values(map).sort((a, b) => {
if (a.series === b.series) return a.index - b.index
return String(a.series).localeCompare(String(b.series))
const categoryOrder = ['RUNNING', 'USING', 'IDLE_COOLDOWN', 'IDLE_FREE']
const categoryLabelMap = { RUNNING: '已占用', USING: '使用中', IDLE_COOLDOWN: '冷却空闲', IDLE_FREE: '空闲' }
const categoryRows = computed(() => {
const map = categoryToDevices.value || {}
return categoryOrder.map(key => {
const devices = Array.isArray(map[key]) ? map[key] : []
const preview = devices.join(', ')
return { key, label: categoryLabelMap[key] || key, count: devices.length, devices, preview }
})
})
@@ -69,10 +69,12 @@ async function fetchData() {
try {
loading.value = true
const data = await getAllDeviceStatus()
devicesMap.value = data?.devices || {}
availableDevices.value = data?.availableDevices || []
stats.totalDevices = data?.totalDevices || Object.keys(devicesMap.value).length
stats.availableCount = data?.availableCount || availableDevices.value.length
categoryToDevices.value = data?.categoryToDevices || {}
stats.totalDevices = data?.totalDevices ?? 0
stats.runningCount = data?.runningCount ?? (categoryToDevices.value['RUNNING']?.length || 0)
stats.usingCount = data?.usingCount ?? (categoryToDevices.value['USING']?.length || 0)
stats.idleCooldownCount = data?.idleCooldownCount ?? (categoryToDevices.value['IDLE_COOLDOWN']?.length || 0)
stats.idleFreeCount = data?.idleFreeCount ?? (categoryToDevices.value['IDLE_FREE']?.length || 0)
} finally {
loading.value = false
}
@@ -113,7 +115,7 @@ onUnmounted(() => {
.actions { display: flex; gap: 12px; align-items: center; }
.stats { display: flex; gap: 16px; align-items: center; flex-wrap: wrap; }
.inline-tag { height: 24px; align-items: center; }
.table-card { }
.devices-list { white-space: normal; word-break: break-all; line-height: 1.6; }
@media (max-width: 768px) {
.title { font-size: 20px; }