导入 AKSRT 主题开发源码
This commit is contained in:
1 parent
9681dd3d48
commit
1268a55dd0
595 files changed
+127705
No files matched your search
@@ -0,0 +1,111 @@
|
||||
<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>
|
||||
Reference in new issue
Block a user