307 lines
9.1 KiB
Vue
307 lines
9.1 KiB
Vue
<template>
|
||
<div class="device-test">
|
||
<!-- 系统信息 -->
|
||
<a-card class="test-card" title="系统信息">
|
||
<a-space direction="vertical" :size="16" style="width: 100%">
|
||
<a-button type="primary" @click="refreshSystemInfo">刷新系统信息</a-button>
|
||
<a-row :gutter="16">
|
||
<a-col :span="8">
|
||
<a-card size="small" title="CPU 信息">
|
||
<div v-if="cpuInfo">
|
||
<p>核心数: {{ cpuInfo.cores }}</p>
|
||
<p>型号: {{ cpuInfo.model }}</p>
|
||
<p>使用率: {{ cpuInfo.usage }}</p>
|
||
</div>
|
||
<div v-else>加载中...</div>
|
||
</a-card>
|
||
</a-col>
|
||
<a-col :span="8">
|
||
<a-card size="small" title="内存信息">
|
||
<div v-if="memoryInfo">
|
||
<p>总内存: {{ memoryInfo.total_str }}</p>
|
||
<p>已用: {{ memoryInfo.used_str }}</p>
|
||
<p>可用: {{ memoryInfo.available_str }}</p>
|
||
<p>使用率: {{ memoryInfo.usage }}</p>
|
||
</div>
|
||
<div v-else>加载中...</div>
|
||
</a-card>
|
||
</a-col>
|
||
<a-col :span="8">
|
||
<a-card size="small" title="系统信息">
|
||
<div v-if="systemInfo">
|
||
<p>操作系统: {{ systemInfo.os }}</p>
|
||
<p>架构: {{ systemInfo.arch }}</p>
|
||
<p>主机名: {{ systemInfo.hostname }}</p>
|
||
<p>平台: {{ systemInfo.platform }}</p>
|
||
</div>
|
||
<div v-else>加载中...</div>
|
||
</a-card>
|
||
</a-col>
|
||
</a-row>
|
||
<a-card size="small" title="磁盘信息" v-if="diskInfo && diskInfo.length > 0">
|
||
<a-table
|
||
:columns="diskColumns"
|
||
:data="diskInfo"
|
||
:pagination="false"
|
||
size="small"
|
||
/>
|
||
</a-card>
|
||
</a-space>
|
||
</a-card>
|
||
|
||
<!-- 文件系统操作 -->
|
||
<a-card class="test-card" title="文件系统操作">
|
||
<a-space direction="vertical" :size="16" style="width: 100%">
|
||
<a-input-group>
|
||
<a-input
|
||
v-model="filePath"
|
||
placeholder="输入文件或目录路径"
|
||
style="flex: 1"
|
||
/>
|
||
<a-button @click="browseDirectory">浏览</a-button>
|
||
<a-button type="primary" @click="listDirectory">列出目录</a-button>
|
||
</a-input-group>
|
||
<a-row :gutter="16">
|
||
<a-col :span="12">
|
||
<a-card size="small" title="文件列表">
|
||
<a-list
|
||
:data="fileList"
|
||
:loading="fileLoading"
|
||
style="max-height: 300px; overflow-y: auto"
|
||
>
|
||
<template #item="{ item }">
|
||
<a-list-item>
|
||
<a-list-item-meta>
|
||
<template #title>
|
||
<a-space>
|
||
<span>{{ item.is_dir ? '📁' : '📄' }}</span>
|
||
<a @click="selectFile(item.path)">{{ item.name }}</a>
|
||
</a-space>
|
||
</template>
|
||
<template #description>
|
||
<span v-if="!item.is_dir">大小: {{ formatBytes(item.size) }}</span>
|
||
<span>修改时间: {{ item.mod_time }}</span>
|
||
</template>
|
||
</a-list-item-meta>
|
||
</a-list-item>
|
||
</template>
|
||
</a-list>
|
||
</a-card>
|
||
</a-col>
|
||
<a-col :span="12">
|
||
<a-card size="small" title="文件内容">
|
||
<a-space direction="vertical" :size="8" style="width: 100%">
|
||
<a-textarea
|
||
v-model="fileContent"
|
||
:rows="10"
|
||
placeholder="文件内容将显示在这里"
|
||
/>
|
||
<a-space>
|
||
<a-button type="primary" @click="readFile" :loading="fileLoading">读取文件</a-button>
|
||
<a-button @click="writeFile" :loading="fileLoading">写入文件</a-button>
|
||
<a-button danger @click="deleteFile" :loading="fileLoading">删除</a-button>
|
||
</a-space>
|
||
</a-space>
|
||
</a-card>
|
||
</a-col>
|
||
</a-row>
|
||
</a-space>
|
||
</a-card>
|
||
|
||
<!-- 环境变量 -->
|
||
<a-card class="test-card" title="环境变量">
|
||
<a-button @click="loadEnvVars" :loading="envLoading">加载环境变量</a-button>
|
||
<a-table
|
||
v-if="envVars"
|
||
:columns="envColumns"
|
||
:data="envTableData"
|
||
:pagination="{ pageSize: 20 }"
|
||
style="margin-top: 16px"
|
||
size="small"
|
||
/>
|
||
</a-card>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref, computed, onMounted } from 'vue'
|
||
import { Message } from '@arco-design/web-vue'
|
||
|
||
const systemInfo = ref(null)
|
||
const cpuInfo = ref(null)
|
||
const memoryInfo = ref(null)
|
||
const diskInfo = ref(null)
|
||
const filePath = ref('')
|
||
const fileContent = ref('')
|
||
const fileList = ref([])
|
||
const fileLoading = ref(false)
|
||
const envVars = ref(null)
|
||
const envLoading = ref(false)
|
||
|
||
const diskColumns = [
|
||
{ title: '设备', dataIndex: 'device', width: 120 },
|
||
{ title: '挂载点', dataIndex: 'mountpoint', width: 200 },
|
||
{ title: '总容量', dataIndex: 'total_str', width: 100 },
|
||
{ title: '已用', dataIndex: 'used_str', width: 100 },
|
||
{ title: '可用', dataIndex: 'free_str', width: 100 },
|
||
{ title: '使用率', dataIndex: 'usage', width: 80 }
|
||
]
|
||
|
||
const envColumns = [
|
||
{ title: '变量名', dataIndex: 'key', width: 200 },
|
||
{ title: '值', dataIndex: 'value' }
|
||
]
|
||
|
||
const envTableData = computed(() => {
|
||
if (!envVars.value) return []
|
||
return Object.keys(envVars.value).map(key => ({
|
||
key,
|
||
value: envVars.value[key]
|
||
}))
|
||
})
|
||
|
||
const refreshSystemInfo = async () => {
|
||
try {
|
||
if (window.go?.main?.App) {
|
||
systemInfo.value = await window.go.main.App.GetSystemInfo()
|
||
cpuInfo.value = await window.go.main.App.GetCPUInfo()
|
||
memoryInfo.value = await window.go.main.App.GetMemoryInfo()
|
||
diskInfo.value = await window.go.main.App.GetDiskInfo()
|
||
}
|
||
} catch (error) {
|
||
console.error('获取系统信息失败:', error)
|
||
Message.error('获取系统信息失败: ' + (error.message || error))
|
||
}
|
||
}
|
||
|
||
const listDirectory = async () => {
|
||
if (!filePath.value) {
|
||
Message.error('请输入目录路径')
|
||
return
|
||
}
|
||
fileLoading.value = true
|
||
try {
|
||
if (window.go?.main?.App) {
|
||
fileList.value = await window.go.main.App.ListDir(filePath.value)
|
||
}
|
||
} catch (error) {
|
||
console.error('列出目录失败:', error)
|
||
Message.error('列出目录失败: ' + (error.message || error))
|
||
} finally {
|
||
fileLoading.value = false
|
||
}
|
||
}
|
||
|
||
const readFile = async () => {
|
||
if (!filePath.value) {
|
||
Message.error('请输入文件路径')
|
||
return
|
||
}
|
||
fileLoading.value = true
|
||
try {
|
||
if (window.go?.main?.App) {
|
||
fileContent.value = await window.go.main.App.ReadFile(filePath.value)
|
||
}
|
||
} catch (error) {
|
||
console.error('读取文件失败:', error)
|
||
Message.error('读取文件失败: ' + (error.message || error))
|
||
} finally {
|
||
fileLoading.value = false
|
||
}
|
||
}
|
||
|
||
const writeFile = async () => {
|
||
if (!filePath.value) {
|
||
Message.error('请输入文件路径')
|
||
return
|
||
}
|
||
fileLoading.value = true
|
||
try {
|
||
if (window.go?.main?.App) {
|
||
await window.go.main.App.WriteFile(filePath.value, fileContent.value)
|
||
Message.success('文件写入成功')
|
||
}
|
||
} catch (error) {
|
||
console.error('写入文件失败:', error)
|
||
Message.error('写入文件失败: ' + (error.message || error))
|
||
} finally {
|
||
fileLoading.value = false
|
||
}
|
||
}
|
||
|
||
const deleteFile = async () => {
|
||
if (!filePath.value) {
|
||
Message.error('请输入文件路径')
|
||
return
|
||
}
|
||
if (!confirm('确定要删除 ' + filePath.value + ' 吗?')) {
|
||
return
|
||
}
|
||
fileLoading.value = true
|
||
try {
|
||
if (window.go?.main?.App) {
|
||
await window.go.main.App.DeletePath(filePath.value)
|
||
Message.success('删除成功')
|
||
filePath.value = ''
|
||
fileContent.value = ''
|
||
fileList.value = []
|
||
}
|
||
} catch (error) {
|
||
console.error('删除失败:', error)
|
||
Message.error('删除失败: ' + (error.message || error))
|
||
} finally {
|
||
fileLoading.value = false
|
||
}
|
||
}
|
||
|
||
const selectFile = (path) => {
|
||
filePath.value = path
|
||
}
|
||
|
||
const browseDirectory = () => {
|
||
const path = prompt('请输入目录路径(例如: C:\\Users)')
|
||
if (path) {
|
||
filePath.value = path
|
||
listDirectory()
|
||
}
|
||
}
|
||
|
||
const loadEnvVars = async () => {
|
||
envLoading.value = true
|
||
try {
|
||
if (window.go?.main?.App) {
|
||
envVars.value = await window.go.main.App.GetEnvVars()
|
||
}
|
||
} catch (error) {
|
||
console.error('加载环境变量失败:', error)
|
||
Message.error('加载环境变量失败: ' + (error.message || error))
|
||
} finally {
|
||
envLoading.value = false
|
||
}
|
||
}
|
||
|
||
const formatBytes = (bytes) => {
|
||
if (!bytes) return '0 B'
|
||
const unit = 1024
|
||
if (bytes < unit) return bytes + ' B'
|
||
const exp = Math.floor(Math.log(bytes) / Math.log(unit))
|
||
return (bytes / Math.pow(unit, exp)).toFixed(2) + ' ' + 'KMGTPE'[exp - 1] + 'B'
|
||
}
|
||
|
||
onMounted(() => {
|
||
refreshSystemInfo()
|
||
})
|
||
</script>
|
||
|
||
<style scoped>
|
||
.device-test {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 16px;
|
||
}
|
||
|
||
.test-card {
|
||
margin-bottom: 16px;
|
||
}
|
||
</style>
|