改用element

增加acme多配置
This commit is contained in:
2026-07-18 23:17:53 +08:00
parent ca957385f2
commit 226f6a76dd
26 changed files with 1572 additions and 1922 deletions
+56 -43
View File
@@ -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>