feat:【IoT 物联网】初始化 IoT 固件详情页 60%

pull/789/MERGE
YunaiV 2025-07-02 12:41:12 +08:00
parent 4cecafb4b1
commit 5be7dde543
5 changed files with 44 additions and 71 deletions

View File

@ -16,12 +16,11 @@ export interface OtaTaskRecord {
// IoT OTA 任务记录 API // IoT OTA 任务记录 API
export const IoTOtaTaskRecordApi = { export const IoTOtaTaskRecordApi = {
// 获取 OTA 升级记录状态统计 getOtaTaskRecordStatusStatistics: async (firmwareId?: number, taskId?: number) => {
getOtaTaskRecordStatusCount: async (firmwareId?: number, taskId?: number) => {
const params: any = {} const params: any = {}
if (firmwareId) params.firmwareId = firmwareId if (firmwareId) params.firmwareId = firmwareId
if (taskId) params.taskId = taskId if (taskId) params.taskId = taskId
return await request.get({ url: `/iot/ota/task/record/get-status-count`, params }) return await request.get({ url: `/iot/ota/task/record/get-status-statistics`, params })
}, },
// 查询 OTA 任务记录分页 // 查询 OTA 任务记录分页

View File

@ -735,7 +735,7 @@ const remainingRouter: AppRouteRecordRaw[] = [
component: () => import('@/views/iot/device/device/detail/index.vue') component: () => import('@/views/iot/device/device/detail/index.vue')
}, },
{ {
path: 'ota/firmware/detail/:id', path: 'ota/operation/firmware/detail/:id',
name: 'IoTOtaFirmwareDetail', name: 'IoTOtaFirmwareDetail',
meta: { meta: {
title: '固件详情', title: '固件详情',

View File

@ -23,31 +23,37 @@
<!-- 固件升级设备统计 --> <!-- 固件升级设备统计 -->
<ContentWrap title="固件升级设备统计" class="mb-20px"> <ContentWrap title="固件升级设备统计" class="mb-20px">
<el-row :gutter="20" class="py-20px" v-loading="statisticsLoading"> <el-row :gutter="20" class="py-20px" v-loading="firmwareStatisticsLoading">
<el-col :span="6"> <el-col :span="6">
<div class="text-center p-20px border border-solid border-gray-200 rounded bg-gray-50"> <div class="text-center p-20px border border-solid border-gray-200 rounded bg-gray-50">
<div class="text-32px font-bold mb-8px text-blue-500">{{ statistics.total || 0 }}</div> <div class="text-32px font-bold mb-8px text-blue-500">
{{
Object.values(firmwareStatistics).reduce((sum, count) => sum + (count || 0), 0) || 0
}}
</div>
<div class="text-14px text-gray-600">升级设备总数</div> <div class="text-14px text-gray-600">升级设备总数</div>
</div> </div>
</el-col> </el-col>
<el-col :span="3"> <el-col :span="3">
<div class="text-center p-20px border border-solid border-gray-200 rounded bg-gray-50"> <div class="text-center p-20px border border-solid border-gray-200 rounded bg-gray-50">
<div class="text-32px font-bold mb-8px text-gray-400"> <div class="text-32px font-bold mb-8px text-gray-400">
{{ statistics.pending || 0 }} {{ firmwareStatistics[IoTOtaTaskRecordStatusEnum.PENDING.value] || 0 }}
</div> </div>
<div class="text-14px text-gray-600">待推送</div> <div class="text-14px text-gray-600">待推送</div>
</div> </div>
</el-col> </el-col>
<el-col :span="3"> <el-col :span="3">
<div class="text-center p-20px border border-solid border-gray-200 rounded bg-gray-50"> <div class="text-center p-20px border border-solid border-gray-200 rounded bg-gray-50">
<div class="text-32px font-bold mb-8px text-blue-400">{{ statistics.pushed || 0 }}</div> <div class="text-32px font-bold mb-8px text-blue-400">{{
firmwareStatistics[IoTOtaTaskRecordStatusEnum.PUSHED.value] || 0
}}</div>
<div class="text-14px text-gray-600">已推送</div> <div class="text-14px text-gray-600">已推送</div>
</div> </div>
</el-col> </el-col>
<el-col :span="3"> <el-col :span="3">
<div class="text-center p-20px border border-solid border-gray-200 rounded bg-gray-50"> <div class="text-center p-20px border border-solid border-gray-200 rounded bg-gray-50">
<div class="text-32px font-bold mb-8px text-yellow-500"> <div class="text-32px font-bold mb-8px text-yellow-500">
{{ statistics.inProgress || 0 }} {{ firmwareStatistics[IoTOtaTaskRecordStatusEnum.UPGRADING.value] || 0 }}
</div> </div>
<div class="text-14px text-gray-600">正在升级</div> <div class="text-14px text-gray-600">正在升级</div>
</div> </div>
@ -55,21 +61,23 @@
<el-col :span="3"> <el-col :span="3">
<div class="text-center p-20px border border-solid border-gray-200 rounded bg-gray-50"> <div class="text-center p-20px border border-solid border-gray-200 rounded bg-gray-50">
<div class="text-32px font-bold mb-8px text-green-500"> <div class="text-32px font-bold mb-8px text-green-500">
{{ statistics.success || 0 }} {{ firmwareStatistics[IoTOtaTaskRecordStatusEnum.SUCCESS.value] || 0 }}
</div> </div>
<div class="text-14px text-gray-600">升级成功</div> <div class="text-14px text-gray-600">升级成功</div>
</div> </div>
</el-col> </el-col>
<el-col :span="3"> <el-col :span="3">
<div class="text-center p-20px border border-solid border-gray-200 rounded bg-gray-50"> <div class="text-center p-20px border border-solid border-gray-200 rounded bg-gray-50">
<div class="text-32px font-bold mb-8px text-red-500">{{ statistics.failed || 0 }}</div> <div class="text-32px font-bold mb-8px text-red-500">{{
firmwareStatistics[IoTOtaTaskRecordStatusEnum.FAILURE.value] || 0
}}</div>
<div class="text-14px text-gray-600">升级失败</div> <div class="text-14px text-gray-600">升级失败</div>
</div> </div>
</el-col> </el-col>
<el-col :span="3"> <el-col :span="3">
<div class="text-center p-20px border border-solid border-gray-200 rounded bg-gray-50"> <div class="text-center p-20px border border-solid border-gray-200 rounded bg-gray-50">
<div class="text-32px font-bold mb-8px text-gray-400"> <div class="text-32px font-bold mb-8px text-gray-400">
{{ statistics.cancelled || 0 }} {{ firmwareStatistics[IoTOtaTaskRecordStatusEnum.CANCELED.value] || 0 }}
</div> </div>
<div class="text-14px text-gray-600">升级取消</div> <div class="text-14px text-gray-600">升级取消</div>
</div> </div>
@ -78,7 +86,7 @@
</ContentWrap> </ContentWrap>
<!-- 任务管理 --> <!-- 任务管理 -->
<OtaTaskList ref="otaTaskListRef" :firmware-id="firmwareId" /> <OtaTaskList :firmware-id="firmwareId" />
</div> </div>
</template> </template>
@ -100,19 +108,8 @@ const firmwareLoading = ref(false)
const firmware = ref<IoTOtaFirmware>({} as IoTOtaFirmware) const firmware = ref<IoTOtaFirmware>({} as IoTOtaFirmware)
// //
const statisticsLoading = ref(false) const firmwareStatisticsLoading = ref(false)
const statistics = ref({ const firmwareStatistics = ref<Record<string, number>>({})
total: 0,
pending: 0,
pushed: 0,
inProgress: 0,
success: 0,
failed: 0,
cancelled: 0
})
//
const otaTaskListRef = ref()
/** 获取固件信息 */ /** 获取固件信息 */
const getFirmwareInfo = async () => { const getFirmwareInfo = async () => {
@ -126,28 +123,13 @@ const getFirmwareInfo = async () => {
/** 获取升级统计 */ /** 获取升级统计 */
const getStatistics = async () => { const getStatistics = async () => {
statisticsLoading.value = true firmwareStatisticsLoading.value = true
try { try {
const data = await IoTOtaTaskRecordApi.getOtaTaskRecordStatusCount(firmwareId.value) firmwareStatistics.value = await IoTOtaTaskRecordApi.getOtaTaskRecordStatusStatistics(
statistics.value = { firmwareId.value
pending: data[IoTOtaTaskRecordStatusEnum.PENDING.value] || 0, )
pushed: data[IoTOtaTaskRecordStatusEnum.PUSHED.value] || 0,
inProgress: data[IoTOtaTaskRecordStatusEnum.IN_PROGRESS.value] || 0,
success: data[IoTOtaTaskRecordStatusEnum.SUCCESS.value] || 0,
failed: data[IoTOtaTaskRecordStatusEnum.FAILED.value] || 0,
cancelled: data[IoTOtaTaskRecordStatusEnum.CANCELLED.value] || 0,
total: 0
}
//
statistics.value.total =
statistics.value.pending +
statistics.value.pushed +
statistics.value.inProgress +
statistics.value.success +
statistics.value.failed +
statistics.value.cancelled
} finally { } finally {
statisticsLoading.value = false firmwareStatisticsLoading.value = false
} }
} }

View File

@ -1,5 +1,5 @@
<template> <template>
<ContentWrap title="任务管理" class="mb-20px"> <ContentWrap title="固件任务管理" class="mb-20px">
<!-- 搜索栏 --> <!-- 搜索栏 -->
<el-form <el-form
class="-mb-15px" class="-mb-15px"
@ -59,7 +59,7 @@
<el-table-column label="操作" align="center" width="80"> <el-table-column label="操作" align="center" width="80">
<template #default="scope"> <template #default="scope">
<el-button <el-button
v-if="scope.row.status === IoTOtaTaskStatusEnum.PENDING.value" v-if="scope.row.status === IoTOtaTaskStatusEnum.IN_PROGRESS.value"
link link
type="primary" type="primary"
@click="handleCancelTask(scope.row.id)" @click="handleCancelTask(scope.row.id)"

View File

@ -162,25 +162,17 @@ export const IoTOtaTaskDeviceScopeEnum = {
// IoT OTA 任务状态枚举 // IoT OTA 任务状态枚举
export const IoTOtaTaskStatusEnum = { export const IoTOtaTaskStatusEnum = {
PENDING: {
label: '待执行',
value: 1
},
IN_PROGRESS: { IN_PROGRESS: {
label: '行中', label: '进行中',
value: 2 value: 10
}, },
COMPLETED: { COMPLETED: {
label: '已完成', label: '已完成',
value: 3 value: 20
}, },
CANCELLED: { CANCELED: {
label: '已取消', label: '已取消',
value: 4 value: 30
},
FAILED: {
label: '执行失败',
value: 5
} }
} as const } as const
@ -188,26 +180,26 @@ export const IoTOtaTaskStatusEnum = {
export const IoTOtaTaskRecordStatusEnum = { export const IoTOtaTaskRecordStatusEnum = {
PENDING: { PENDING: {
label: '待推送', label: '待推送',
value: 1 value: 0
}, },
PUSHED: { PUSHED: {
label: '已推送', label: '已推送',
value: 2 value: 10
}, },
IN_PROGRESS: { UPGRADING: {
label: '正在升级', label: '升级',
value: 3 value: 20
}, },
SUCCESS: { SUCCESS: {
label: '升级成功', label: '升级成功',
value: 4 value: 30
}, },
FAILED: { FAILURE: {
label: '升级失败', label: '升级失败',
value: 5 value: 40
}, },
CANCELLED: { CANCELED: {
label: '升级取消', label: '升级取消',
value: 6 value: 50
} }
} as const } as const