改用element
增加acme多配置
This commit is contained in:
+56
-43
@@ -1,45 +1,51 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="flex justify-between items-center mb-6">
|
||||
<h2 class="text-2xl font-bold">部署日志</h2>
|
||||
<select v-model="statusFilter" @change="load"
|
||||
class="px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 outline-none text-sm">
|
||||
<option value="">全部状态</option>
|
||||
<option value="success">成功</option>
|
||||
<option value="failed">失败</option>
|
||||
<option value="skipped">跳过</option>
|
||||
</select>
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 24px;">
|
||||
<h2 style="font-size: 20px; font-weight: 700; margin: 0;">部署日志</h2>
|
||||
<el-select v-model="statusFilter" style="width: 160px;" @change="load">
|
||||
<el-option label="全部状态" value="" />
|
||||
<el-option label="成功" value="success" />
|
||||
<el-option label="失败" value="failed" />
|
||||
<el-option label="跳过" value="skipped" />
|
||||
</el-select>
|
||||
</div>
|
||||
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 overflow-hidden">
|
||||
<table class="w-full text-sm">
|
||||
<thead class="bg-gray-50">
|
||||
<tr>
|
||||
<th class="px-6 py-3 text-left text-gray-500 font-medium">时间</th>
|
||||
<th class="px-6 py-3 text-left text-gray-500 font-medium">服务器</th>
|
||||
<th class="px-6 py-3 text-left text-gray-500 font-medium">域名</th>
|
||||
<th class="px-6 py-3 text-left text-gray-500 font-medium">状态</th>
|
||||
<th class="px-6 py-3 text-left text-gray-500 font-medium">消息</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-50">
|
||||
<tr v-for="log in logs" :key="log.id">
|
||||
<td class="px-6 py-3 text-gray-500">{{ formatTime(log.created_at) }}</td>
|
||||
<td class="px-6 py-3">{{ log.server }}</td>
|
||||
<td class="px-6 py-3">{{ log.domain }}</td>
|
||||
<td class="px-6 py-3">
|
||||
<span :class="statusClass(log.status)" class="px-2 py-0.5 rounded-full text-xs">
|
||||
{{ log.status }}
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-6 py-3 text-gray-500">{{ log.message }}</td>
|
||||
</tr>
|
||||
<tr v-if="!logs.length">
|
||||
<td colspan="5" class="px-6 py-8 text-center text-gray-400">暂无日志</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<el-card>
|
||||
<el-table :data="logs" stripe style="width: 100%;">
|
||||
<el-table-column prop="created_at" label="时间" width="170">
|
||||
<template #default="{ row }">{{ formatTime(row.created_at) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="server" label="服务器" width="140" />
|
||||
<el-table-column prop="domain" label="域名" width="200" />
|
||||
<el-table-column prop="status" label="状态" width="100">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="statusType(row.status)" size="small">{{ row.status }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="message" label="消息" show-overflow-tooltip />
|
||||
<el-table-column label="详情" width="80" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-button type="primary" link size="small" @click="showDetail(row)">查看</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
|
||||
<el-dialog v-model="showDialog" title="日志详情" width="520px">
|
||||
<template v-if="detailLog">
|
||||
<el-descriptions :column="1" border size="small">
|
||||
<el-descriptions-item label="时间">{{ formatTime(detailLog.created_at) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="服务器">{{ detailLog.server || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="域名">{{ detailLog.domain || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="状态">
|
||||
<el-tag :type="statusType(detailLog.status)" size="small">{{ detailLog.status }}</el-tag>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="消息">
|
||||
<span style="white-space: pre-wrap; word-break: break-all;">{{ detailLog.message || '-' }}</span>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -49,22 +55,29 @@ import { getLogs } from '../api'
|
||||
|
||||
const logs = ref([])
|
||||
const statusFilter = ref('')
|
||||
const detailLog = ref(null)
|
||||
const showDialog = ref(false)
|
||||
|
||||
const formatTime = (iso) => {
|
||||
if (!iso) return '-'
|
||||
return new Date(iso).toLocaleString('zh-CN')
|
||||
}
|
||||
|
||||
const statusClass = (status) => ({
|
||||
'bg-green-100 text-green-700': status === 'success',
|
||||
'bg-red-100 text-red-700': status === 'failed',
|
||||
'bg-gray-100 text-gray-700': status === 'skipped',
|
||||
})
|
||||
const statusType = (status) => ({
|
||||
success: 'success',
|
||||
failed: 'danger',
|
||||
skipped: 'info',
|
||||
}[status] || 'info')
|
||||
|
||||
const load = async () => {
|
||||
const { data } = await getLogs(statusFilter.value || undefined)
|
||||
logs.value = data
|
||||
}
|
||||
|
||||
const showDetail = (row) => {
|
||||
detailLog.value = row
|
||||
showDialog.value = true
|
||||
}
|
||||
|
||||
onMounted(load)
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user