Files
wordpress-theme-aksrt/assets/admin/src/pages/tools/ToolsHealth.vue
T

112 lines
3.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="aksrt-page-container">
<PageHeader
title="健康检查"
desc="集中查看运行环境、数据库表、邮箱验证迁移和系统诊断状态。"
>
<template #actions>
<n-space>
<n-button quaternary @click="go('/tools/import-export')">导入导出</n-button>
<n-button quaternary @click="go('/tools/email-rollback')">邮件回滚</n-button>
</n-space>
</template>
</PageHeader>
<n-spin :show="loading" style="width: 100%; min-height: 200px;">
<n-card class="aksrt-section-card">
<div class="aksrt-section-header">
<h3>邮箱验证状态</h3>
</div>
<n-space>
<n-tag round :type="emailHealth.feature_enabled ? 'success' : 'default'">
功能开关:{{ emailHealth.feature_enabled ? '已启用' : '未启用' }}
</n-tag>
<n-tag round :type="emailHealth.rest_blocking_active ? 'warning' : 'default'">
REST 阻断:{{ emailHealth.rest_blocking_active ? '已开启' : '仅记录/关闭' }}
</n-tag>
<n-tag round type="info">
待验证用户:{{ emailHealth.pending_users }}
</n-tag>
</n-space>
</n-card>
<div class="aksrt-health-grid">
<n-card v-for="check in checkItems" :key="check.key" class="aksrt-section-card">
<div class="aksrt-section-header">
<h3>{{ check.label }}</h3>
<n-tag round :type="statusToTag(check.status)">{{ check.status }}</n-tag>
</div>
<p style="margin: 0; color: #4b5565;">{{ check.value }}</p>
</n-card>
</div>
</n-spin>
</div>
</template>
<script setup>
import { computed, onMounted, ref } from 'vue'
import { useRouter } from 'vue-router'
import { useMessage } from 'naive-ui'
import api from '@/api'
import PageHeader from '@/components/PageHeader.vue'
const router = useRouter()
const message = useMessage()
const loading = ref(true)
const healthData = ref({})
const emailHealth = ref({
feature_enabled: false,
pending_users: 0,
rest_blocking_active: false,
})
const checkItems = computed(() => {
return Object.entries(healthData.value || {}).map(([key, value]) => ({
key,
...(value || {}),
}))
})
function go(path) {
router.push(path)
}
function extractData(response) {
return response?.data ?? response ?? {}
}
function statusToTag(status) {
if (status === 'ok') return 'success'
if (status === 'warning') return 'warning'
if (status === 'error') return 'error'
return 'info'
}
async function load() {
loading.value = true
try {
const [healthRes, emailRes] = await Promise.all([
api.getHealthCheck(),
api.getHealthEmailVerification(),
])
healthData.value = extractData(healthRes).checks || {}
emailHealth.value = extractData(emailRes)
} catch (error) {
message.error(error.message || '加载健康检查失败')
} finally {
loading.value = false
}
}
onMounted(load)
</script>
<style scoped>
.aksrt-health-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
gap: 16px;
}
</style>