|
@@ -18,26 +18,57 @@
|
|
|
</div>
|
|
</div>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
- <el-table :data="deviceList" style="width: 100%">
|
|
|
|
|
- <el-table-column prop="name" label="设备名称" />
|
|
|
|
|
- <el-table-column prop="model" label="设备型号" />
|
|
|
|
|
- <el-table-column prop="systemVersion" label="系统版本" />
|
|
|
|
|
- <el-table-column prop="status" label="状态">
|
|
|
|
|
- <template #default="{ row }">
|
|
|
|
|
- <el-tag :type="row.status === '在线' ? 'success' : 'danger'">
|
|
|
|
|
- {{ row.status }}
|
|
|
|
|
- </el-tag>
|
|
|
|
|
- </template>
|
|
|
|
|
- </el-table-column>
|
|
|
|
|
- <el-table-column label="操作">
|
|
|
|
|
- <template #default="{ row }">
|
|
|
|
|
- <el-button size="small" @click="checkDeviceUpdate(row)">
|
|
|
|
|
- 检查更新
|
|
|
|
|
- </el-button>
|
|
|
|
|
- </template>
|
|
|
|
|
- </el-table-column>
|
|
|
|
|
- </el-table>
|
|
|
|
|
- </el-card>
|
|
|
|
|
|
|
+<el-table
|
|
|
|
|
+ :data="deviceList"
|
|
|
|
|
+ style="width: 100%"
|
|
|
|
|
+ v-loading="loading"
|
|
|
|
|
+ element-loading-text="设备列表加载中..."
|
|
|
|
|
+ element-loading-background="rgba(255, 255, 255, 0.8)"
|
|
|
|
|
+>
|
|
|
|
|
+ <el-table-column prop="name" label="设备名称" />
|
|
|
|
|
+ <el-table-column prop="model" label="设备型号" />
|
|
|
|
|
+ <el-table-column prop="systemVersion" label="系统版本" />
|
|
|
|
|
+ <el-table-column prop="status" label="状态">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ <el-tag :type="row.status === '在线' ? 'success' : 'danger'">
|
|
|
|
|
+ {{ row.status }}
|
|
|
|
|
+ </el-tag>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column label="操作">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ <el-button size="small" @click="checkDeviceUpdate(row)">
|
|
|
|
|
+ 检查更新
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+
|
|
|
|
|
+ <template #empty>
|
|
|
|
|
+ <div class="empty-tips">
|
|
|
|
|
+ {{ loading ? '数据加载中...' : '暂无设备数据' }}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </template>
|
|
|
|
|
+</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> -->
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -169,9 +200,12 @@
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script setup>
|
|
<script setup>
|
|
|
-import { ref, reactive, computed } from 'vue'
|
|
|
|
|
|
|
+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 dayjs from 'dayjs'
|
|
|
|
|
|
|
|
// 响应式数据
|
|
// 响应式数据
|
|
|
const showUpload = ref(false)
|
|
const showUpload = ref(false)
|
|
@@ -242,171 +276,103 @@ const showDetail = (row) => {
|
|
|
}
|
|
}
|
|
|
console.log('查看版本详情:', row.version)
|
|
console.log('查看版本详情:', row.version)
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
-// 其他方法
|
|
|
|
|
-const checkUpdates = async () => {
|
|
|
|
|
- // 调用API检查更新
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-const startUpgrade = async () => {
|
|
|
|
|
- // 调用推送API
|
|
|
|
|
|
|
+</script>
|
|
|
|
|
+<style >
|
|
|
|
|
+.ota-container {
|
|
|
|
|
+ padding: 20px;
|
|
|
|
|
+ max-width: 1200px;
|
|
|
|
|
+ margin: 0 auto;
|
|
|
|
|
+ height: calc(100vh - 60px);
|
|
|
|
|
+ overflow-y: auto;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
-const handleUpload = (file) => {
|
|
|
|
|
- // 处理文件上传
|
|
|
|
|
|
|
+.version-card,
|
|
|
|
|
+.push-control,
|
|
|
|
|
+.status-card {
|
|
|
|
|
+ margin-bottom: 20px;
|
|
|
|
|
+ min-height: 300px;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
-const confirmUpload = () => {
|
|
|
|
|
- showUpload.value = false
|
|
|
|
|
|
|
+.el-table {
|
|
|
|
|
+ max-height: 400px;
|
|
|
|
|
+ overflow-y: auto;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
-// 当前设备信息
|
|
|
|
|
-const currentDevice = reactive({
|
|
|
|
|
- name: '主控设备',
|
|
|
|
|
- model: 'X-200',
|
|
|
|
|
- systemVersion: 'v2.1.0',
|
|
|
|
|
- status: '在线'
|
|
|
|
|
-})
|
|
|
|
|
-
|
|
|
|
|
-// 设备列表
|
|
|
|
|
-const deviceList = ref([
|
|
|
|
|
- {
|
|
|
|
|
- name: '设备1',
|
|
|
|
|
- model: 'X-200',
|
|
|
|
|
- systemVersion: 'v2.0.3',
|
|
|
|
|
- status: '在线'
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- name: '设备2',
|
|
|
|
|
- model: 'X-200',
|
|
|
|
|
- systemVersion: 'v2.1.0',
|
|
|
|
|
- status: '离线'
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- name: '设备3',
|
|
|
|
|
- model: 'X-200',
|
|
|
|
|
- systemVersion: 'v2.0.5',
|
|
|
|
|
- status: '在线'
|
|
|
|
|
|
|
+.stat-item {
|
|
|
|
|
+ &.success {
|
|
|
|
|
+ background-color: #f6ffed;
|
|
|
|
|
+ border: 1px solid #b7eb8f;
|
|
|
}
|
|
}
|
|
|
-])
|
|
|
|
|
-
|
|
|
|
|
-// 刷新设备列表
|
|
|
|
|
-const refreshDeviceList = async () => {
|
|
|
|
|
- ElMessage.info('正在刷新设备列表...')
|
|
|
|
|
- // 模拟 API 调用
|
|
|
|
|
- setTimeout(() => {
|
|
|
|
|
- deviceList.value = [
|
|
|
|
|
- ...deviceList.value,
|
|
|
|
|
- {
|
|
|
|
|
- name: '设备4',
|
|
|
|
|
- model: 'X-200',
|
|
|
|
|
- systemVersion: 'v2.1.0',
|
|
|
|
|
- status: '在线'
|
|
|
|
|
- }
|
|
|
|
|
- ]
|
|
|
|
|
- ElMessage.success('设备列表已刷新')
|
|
|
|
|
- }, 1000)
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-// 检查设备更新
|
|
|
|
|
-const checkDeviceUpdate = (device) => {
|
|
|
|
|
- ElMessage.info(`正在检查 ${device.name} 的更新...`)
|
|
|
|
|
- // 模拟检查更新逻辑
|
|
|
|
|
- setTimeout(() => {
|
|
|
|
|
- if (device.systemVersion !== currentDevice.systemVersion) {
|
|
|
|
|
- ElMessage.warning(`${device.name} 有可用更新`)
|
|
|
|
|
- } else {
|
|
|
|
|
- ElMessage.success(`${device.name} 已是最新版本`)
|
|
|
|
|
- }
|
|
|
|
|
- }, 500)
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-</script>
|
|
|
|
|
-
|
|
|
|
|
-<style scoped>
|
|
|
|
|
-
|
|
|
|
|
|
|
+ &.failure {
|
|
|
|
|
+ background-color: #fff2f0;
|
|
|
|
|
+ border: 1px solid #ffccc7;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+</style>
|
|
|
|
|
+<style>
|
|
|
.device-info-card {
|
|
.device-info-card {
|
|
|
margin-bottom: 20px;
|
|
margin-bottom: 20px;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
.device-info-content {
|
|
.device-info-content {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
flex-direction: column;
|
|
|
gap: 10px;
|
|
gap: 10px;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
.info-item {
|
|
.info-item {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
align-items: center;
|
|
align-items: center;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
.info-item label {
|
|
.info-item label {
|
|
|
font-weight: bold;
|
|
font-weight: bold;
|
|
|
min-width: 100px;
|
|
min-width: 100px;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
.device-list-card {
|
|
.device-list-card {
|
|
|
margin-bottom: 20px;
|
|
margin-bottom: 20px;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
.ota-container {
|
|
.ota-container {
|
|
|
padding: 20px;
|
|
padding: 20px;
|
|
|
max-width: 1200px;
|
|
max-width: 1200px;
|
|
|
margin: 0 auto;
|
|
margin: 0 auto;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
.header {
|
|
.header {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
justify-content: space-between;
|
|
justify-content: space-between;
|
|
|
align-items: center;
|
|
align-items: center;
|
|
|
margin-bottom: 20px;
|
|
margin-bottom: 20px;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
.version-card, .push-control, .status-card {
|
|
.version-card, .push-control, .status-card {
|
|
|
margin-bottom: 20px;
|
|
margin-bottom: 20px;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
.control-group {
|
|
.control-group {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
gap: 15px;
|
|
gap: 15px;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
.status-group {
|
|
.status-group {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
align-items: center;
|
|
align-items: center;
|
|
|
gap: 30px;
|
|
gap: 30px;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
.stats {
|
|
.stats {
|
|
|
flex: 1;
|
|
flex: 1;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
.stat-item {
|
|
.stat-item {
|
|
|
padding: 10px;
|
|
padding: 10px;
|
|
|
border-radius: 4px;
|
|
border-radius: 4px;
|
|
|
margin-bottom: 10px;
|
|
margin-bottom: 10px;
|
|
|
-
|
|
|
|
|
&.success {
|
|
&.success {
|
|
|
background-color: #f6ffed;
|
|
background-color: #f6ffed;
|
|
|
border: 1px solid #b7eb8f;
|
|
border: 1px solid #b7eb8f;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
&.failure {
|
|
&.failure {
|
|
|
background-color: #fff2f0;
|
|
background-color: #fff2f0;
|
|
|
border: 1px solid #ffccc7;
|
|
border: 1px solid #ffccc7;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
.log-container {
|
|
.log-container {
|
|
|
max-height: 200px;
|
|
max-height: 200px;
|
|
|
overflow-y: auto;
|
|
overflow-y: auto;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
.log-content pre {
|
|
.log-content pre {
|
|
|
margin: 0;
|
|
margin: 0;
|
|
|
font-family: monospace;
|
|
font-family: monospace;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
/* 空状态提示 */
|
|
/* 空状态提示 */
|
|
|
.el-table__empty-block {
|
|
.el-table__empty-block {
|
|
|
padding: 20px;
|
|
padding: 20px;
|