|
@@ -17,7 +17,6 @@
|
|
|
<el-button type="text" @click="refreshDeviceList">刷新列表</el-button>
|
|
<el-button type="text" @click="refreshDeviceList">刷新列表</el-button>
|
|
|
</div>
|
|
</div>
|
|
|
</template>
|
|
</template>
|
|
|
-
|
|
|
|
|
<el-table
|
|
<el-table
|
|
|
:data="deviceList"
|
|
:data="deviceList"
|
|
|
style="width: 100%"
|
|
style="width: 100%"
|
|
@@ -26,8 +25,8 @@
|
|
|
element-loading-background="rgba(255, 255, 255, 0.8)"
|
|
element-loading-background="rgba(255, 255, 255, 0.8)"
|
|
|
>
|
|
>
|
|
|
<el-table-column prop="name" label="设备名称" />
|
|
<el-table-column prop="name" label="设备名称" />
|
|
|
- <el-table-column prop="model" label="设备型号" />
|
|
|
|
|
- <el-table-column prop="systemVersion" label="系统版本" />
|
|
|
|
|
|
|
+ <el-table-column prop="model" label="设备ID" />
|
|
|
|
|
+ <el-table-column prop="systemVersion" label="固件版本" />
|
|
|
<el-table-column prop="status" label="状态">
|
|
<el-table-column prop="status" label="状态">
|
|
|
<template #default="{ row }">
|
|
<template #default="{ row }">
|
|
|
<el-tag :type="row.status === '在线' ? 'success' : 'danger'">
|
|
<el-tag :type="row.status === '在线' ? 'success' : 'danger'">
|
|
@@ -37,8 +36,23 @@
|
|
|
</el-table-column>
|
|
</el-table-column>
|
|
|
<el-table-column label="操作">
|
|
<el-table-column label="操作">
|
|
|
<template #default="{ row }">
|
|
<template #default="{ row }">
|
|
|
- <el-button size="small" @click="checkDeviceUpdate(row)">
|
|
|
|
|
- 检查更新
|
|
|
|
|
|
|
+ <el-button
|
|
|
|
|
+ size="small"
|
|
|
|
|
+ @click="checkDeviceUpdate(row)"
|
|
|
|
|
+ :loading="row.checking"
|
|
|
|
|
+ >
|
|
|
|
|
+ {{ row.checking ? '检查中...' : '检查更新' }}
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column label="操作">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ <el-button
|
|
|
|
|
+ size="small"
|
|
|
|
|
+ @click="checkDeviceUpdate(row)"
|
|
|
|
|
+ :loading="row.checking" <!-- 添加加载状态 -->
|
|
|
|
|
+ >
|
|
|
|
|
+ {{ row.checking ? '检查中...' : '检查更新' }}
|
|
|
</el-button>
|
|
</el-button>
|
|
|
</template>
|
|
</template>
|
|
|
</el-table-column>
|
|
</el-table-column>
|
|
@@ -49,23 +63,6 @@
|
|
|
</div>
|
|
</div>
|
|
|
</template>
|
|
</template>
|
|
|
</el-table>
|
|
</el-table>
|
|
|
-
|
|
|
|
|
-<!-- <style >
|
|
|
|
|
-/* 合并所有scoped样式 */
|
|
|
|
|
-.empty-tips {
|
|
|
|
|
- padding: 20px;
|
|
|
|
|
- color: #888;
|
|
|
|
|
- text-align: center;
|
|
|
|
|
-}
|
|
|
|
|
-.device-list-card {
|
|
|
|
|
- margin-bottom: 20px;
|
|
|
|
|
- position: relative;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-:deep(.el-loading-mask) {
|
|
|
|
|
- background-color: rgba(255, 255, 255, 0.8);
|
|
|
|
|
-}
|
|
|
|
|
-</style> -->
|
|
|
|
|
</el-card> <!-- 确保正确闭合el-card标签 -->
|
|
</el-card> <!-- 确保正确闭合el-card标签 -->
|
|
|
|
|
|
|
|
<!-- </el-card> -->
|
|
<!-- </el-card> -->
|
|
@@ -204,9 +201,38 @@ import { ref, reactive, computed, onMounted } from 'vue' // 添加 onMounted
|
|
|
import { ElMessage } from 'element-plus'
|
|
import { ElMessage } from 'element-plus'
|
|
|
import { UploadFilled } from '@element-plus/icons-vue'
|
|
import { UploadFilled } from '@element-plus/icons-vue'
|
|
|
import axios from 'axios'
|
|
import axios from 'axios'
|
|
|
-// 在现有导入中添加
|
|
|
|
|
-import dayjs from 'dayjs'
|
|
|
|
|
-
|
|
|
|
|
|
|
+// 新增设备列表相关代码
|
|
|
|
|
+const deviceList = ref([])
|
|
|
|
|
+const loading = ref(true)
|
|
|
|
|
+// 修复后的数据获取方法
|
|
|
|
|
+const fetchDevices = async () => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const response = await axios.get('/api/devices')
|
|
|
|
|
+ console.log('API响应数据:', response.data)
|
|
|
|
|
+
|
|
|
|
|
+ deviceList.value = response.data.map(device => ({
|
|
|
|
|
+ name: device.name,
|
|
|
|
|
+ model: device.device_id,
|
|
|
|
|
+ systemVersion: device.firmware_version || '未记录',
|
|
|
|
|
+ status: device.status === 'online' ? '在线' : '离线'
|
|
|
|
|
+ }))
|
|
|
|
|
+
|
|
|
|
|
+ console.log('映射后数据:', deviceList.value)
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ ElMessage.error('设备列表加载失败')
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ loading.value = false
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+// 初始化调用
|
|
|
|
|
+onMounted(() => {
|
|
|
|
|
+ fetchDevices()
|
|
|
|
|
+})
|
|
|
|
|
+// 刷新方法
|
|
|
|
|
+const refreshDeviceList = () => {
|
|
|
|
|
+ loading.value = true
|
|
|
|
|
+ fetchDevices()
|
|
|
|
|
+}
|
|
|
// 响应式数据
|
|
// 响应式数据
|
|
|
const showUpload = ref(false)
|
|
const showUpload = ref(false)
|
|
|
const selectedVersions = ref([])
|
|
const selectedVersions = ref([])
|
|
@@ -216,7 +242,6 @@ const strategies = [
|
|
|
{ value: 'schedule', label: '定时推送' },
|
|
{ value: 'schedule', label: '定时推送' },
|
|
|
{ value: 'gradual', label: '分阶段推送' }
|
|
{ value: 'gradual', label: '分阶段推送' }
|
|
|
]
|
|
]
|
|
|
-
|
|
|
|
|
const state = reactive({
|
|
const state = reactive({
|
|
|
successRate: 0,
|
|
successRate: 0,
|
|
|
successCount: 0,
|
|
successCount: 0,
|
|
@@ -243,7 +268,6 @@ const state = reactive({
|
|
|
{ color: '#f56c6c', percentage: 80 }
|
|
{ color: '#f56c6c', percentage: 80 }
|
|
|
]
|
|
]
|
|
|
})
|
|
})
|
|
|
-
|
|
|
|
|
// 计算属性过滤无效数据
|
|
// 计算属性过滤无效数据
|
|
|
const filteredVersions = computed(() => {
|
|
const filteredVersions = computed(() => {
|
|
|
return (state.versions || [])
|
|
return (state.versions || [])
|
|
@@ -255,19 +279,16 @@ const filteredVersions = computed(() => {
|
|
|
...item
|
|
...item
|
|
|
}))
|
|
}))
|
|
|
})
|
|
})
|
|
|
-
|
|
|
|
|
// 验证行数据有效性
|
|
// 验证行数据有效性
|
|
|
const isValidRow = (row) => {
|
|
const isValidRow = (row) => {
|
|
|
return row && typeof row === 'object' && 'version' in row
|
|
return row && typeof row === 'object' && 'version' in row
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
// 处理选择变化
|
|
// 处理选择变化
|
|
|
const handleSelectionChange = (selection) => {
|
|
const handleSelectionChange = (selection) => {
|
|
|
selectedVersions.value = (selection || [])
|
|
selectedVersions.value = (selection || [])
|
|
|
.filter(v => isValidRow(v))
|
|
.filter(v => isValidRow(v))
|
|
|
.map(v => v?.version || '')
|
|
.map(v => v?.version || '')
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
// 显示详情
|
|
// 显示详情
|
|
|
const showDetail = (row) => {
|
|
const showDetail = (row) => {
|
|
|
if (!isValidRow(row)) {
|
|
if (!isValidRow(row)) {
|
|
@@ -276,6 +297,45 @@ const showDetail = (row) => {
|
|
|
}
|
|
}
|
|
|
console.log('查看版本详情:', row.version)
|
|
console.log('查看版本详情:', row.version)
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+// 在现有方法后添加(约250行)
|
|
|
|
|
+const checkDeviceUpdate = async (device) => {
|
|
|
|
|
+ device.checking = true
|
|
|
|
|
+ try {
|
|
|
|
|
+ const response = await axios.post('/api/check-update', {
|
|
|
|
|
+ deviceId: device.model, // 使用设备ID作为标识
|
|
|
|
|
+ currentVersion: device.systemVersion
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ if (response.data.hasUpdate) {
|
|
|
|
|
+ ElMessage.success(`发现新版本:${response.data.latestVersion}`)
|
|
|
|
|
+ // 自动跳转到版本选择卡片
|
|
|
|
|
+ document.querySelector('.version-card').scrollIntoView({
|
|
|
|
|
+ behavior: 'smooth'
|
|
|
|
|
+ })
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ElMessage.info('当前已是最新版本')
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ ElMessage.error('检查更新失败')
|
|
|
|
|
+ console.error('检查更新错误:', error)
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ device.checking = false
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 已有版本检查方法需要完善(约200行)
|
|
|
|
|
+const checkUpdates = async () => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const response = await axios.get('/api/firmware/versions')
|
|
|
|
|
+ state.versions = response.data
|
|
|
|
|
+ ElMessage.success('版本列表已更新')
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ ElMessage.error('获取版本失败')
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
</script>
|
|
</script>
|
|
|
<style >
|
|
<style >
|
|
|
.ota-container {
|
|
.ota-container {
|
|
@@ -378,4 +438,4 @@ const showDetail = (row) => {
|
|
|
padding: 20px;
|
|
padding: 20px;
|
|
|
color: #666;
|
|
color: #666;
|
|
|
}
|
|
}
|
|
|
-</style>
|
|
|
|
|
|
|
+</style>
|