Make aksrt_settings the sole theme settings store for get_all(), remove aksrt_seo_settings/aksrt_basic_settings merge paths, point global.logo schema at aksrt_settings, and delete the retired settings migration page, route, REST endpoint, and related SPA surface.
266 lines
8.0 KiB
Vue
266 lines
8.0 KiB
Vue
<template>
|
|
<div class="aksrt-page-container">
|
|
<PageHeader title="主题信息" desc="主题版本、运行环境、已启用模块和关键系统信息。" />
|
|
|
|
<div v-if="loading" class="aksrt-theme-info__loading">
|
|
<n-spin size="medium" />
|
|
</div>
|
|
|
|
<template v-else>
|
|
<!-- Version Card -->
|
|
<n-card class="aksrt-theme-info__card" title="版本信息" size="small">
|
|
<n-descriptions :column="2" bordered label-placement="left" size="small">
|
|
<n-descriptions-item label="主题版本">
|
|
<n-tag type="success" size="small">{{ info.themeVersion }}</n-tag>
|
|
</n-descriptions-item>
|
|
<n-descriptions-item label="WordPress 版本">
|
|
{{ info.wpVersion }}
|
|
</n-descriptions-item>
|
|
<n-descriptions-item label="PHP 版本">
|
|
<n-tag :type="info.phpVersion >= '8.1' ? 'success' : 'warning'" size="small">
|
|
{{ info.phpVersion }}
|
|
</n-tag>
|
|
</n-descriptions-item>
|
|
<n-descriptions-item label="数据库 Schema">
|
|
<n-tag type="info" size="small">{{ info.dbSchemaVersion }}</n-tag>
|
|
</n-descriptions-item>
|
|
<n-descriptions-item label="邮箱验证回填">
|
|
<n-tag :type="info.emailBackfillDone ? 'success' : 'default'" size="small">
|
|
{{ info.emailBackfillDone ? '已完成' : '未触发' }}
|
|
</n-tag>
|
|
</n-descriptions-item>
|
|
</n-descriptions>
|
|
</n-card>
|
|
|
|
<!-- Environment Card -->
|
|
<n-card class="aksrt-theme-info__card" title="运行环境" size="small">
|
|
<n-descriptions :column="2" bordered label-placement="left" size="small">
|
|
<n-descriptions-item label="站点地址">
|
|
<n-text code>{{ info.siteUrl }}</n-text>
|
|
</n-descriptions-item>
|
|
<n-descriptions-item label="REST API">
|
|
<n-text code>{{ info.apiUrl }}</n-text>
|
|
</n-descriptions-item>
|
|
<n-descriptions-item label="主题目录">
|
|
<n-text code>{{ info.themeDir }}</n-text>
|
|
</n-descriptions-item>
|
|
<n-descriptions-item label="上传目录">
|
|
<n-text code>{{ info.uploadDir }}</n-text>
|
|
</n-descriptions-item>
|
|
<n-descriptions-item label="多站点">
|
|
<n-tag :type="info.isMultisite ? 'warning' : 'default'" size="small">
|
|
{{ info.isMultisite ? '是' : '否' }}
|
|
</n-tag>
|
|
</n-descriptions-item>
|
|
<n-descriptions-item label="调试模式">
|
|
<n-tag :type="info.debugMode ? 'warning' : 'default'" size="small">
|
|
{{ info.debugMode ? '开启' : '关闭' }}
|
|
</n-tag>
|
|
</n-descriptions-item>
|
|
</n-descriptions>
|
|
</n-card>
|
|
|
|
<!-- Modules Card -->
|
|
<n-card class="aksrt-theme-info__card" title="已启用模块" size="small">
|
|
<div class="aksrt-theme-info__modules">
|
|
<n-tag
|
|
v-for="mod in info.modules"
|
|
:key="mod.key"
|
|
:type="mod.enabled ? 'success' : 'default'"
|
|
size="small"
|
|
class="aksrt-theme-info__module-tag"
|
|
>
|
|
<FaIcon :icon="mod.enabled ? 'fas fa-check-circle' : 'fas fa-circle'" :size="10" />
|
|
{{ mod.label }}
|
|
</n-tag>
|
|
</div>
|
|
<n-text v-if="!info.modules.length" depth="3" style="font-size: 13px;">
|
|
暂无模块信息
|
|
</n-text>
|
|
</n-card>
|
|
|
|
<!-- Data Tables Card -->
|
|
<n-card class="aksrt-theme-info__card" title="数据表状态" size="small">
|
|
<n-data-table
|
|
:columns="tableColumns"
|
|
:data="info.tables"
|
|
:bordered="true"
|
|
size="small"
|
|
:max-height="300"
|
|
/>
|
|
</n-card>
|
|
|
|
<!-- Docs Links Card -->
|
|
<n-card class="aksrt-theme-info__card" title="快速入口" size="small">
|
|
<div class="aksrt-theme-info__links">
|
|
<router-link to="/docs" class="aksrt-theme-info__link">
|
|
<FaIcon icon="fas fa-book" :size="16" />
|
|
<span>文档中心</span>
|
|
</router-link>
|
|
<router-link to="/tools/update" class="aksrt-theme-info__link">
|
|
<FaIcon icon="fas fa-cloud-arrow-down" :size="16" />
|
|
<span>更新中心</span>
|
|
</router-link>
|
|
<router-link to="/tools/backup" class="aksrt-theme-info__link">
|
|
<FaIcon icon="fas fa-box-archive" :size="16" />
|
|
<span>数据备份</span>
|
|
</router-link>
|
|
<router-link to="/tools/health" class="aksrt-theme-info__link">
|
|
<FaIcon icon="fas fa-heartbeat" :size="16" />
|
|
<span>健康检查</span>
|
|
</router-link>
|
|
<router-link to="/tools/import-export" class="aksrt-theme-info__link">
|
|
<FaIcon icon="fas fa-exchange-alt" :size="16" />
|
|
<span>导入导出</span>
|
|
</router-link>
|
|
</div>
|
|
</n-card>
|
|
</template>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, onMounted, h } from 'vue'
|
|
import { NTag, NText } from 'naive-ui'
|
|
import PageHeader from '@/components/PageHeader.vue'
|
|
import FaIcon from '@/components/form/FaIcon.vue'
|
|
import api from '@/api/index.js'
|
|
|
|
const loading = ref(true)
|
|
const info = ref({
|
|
themeVersion: '',
|
|
wpVersion: '',
|
|
phpVersion: '',
|
|
dbSchemaVersion: '',
|
|
emailBackfillDone: false,
|
|
siteUrl: '',
|
|
apiUrl: '',
|
|
themeDir: '',
|
|
uploadDir: '',
|
|
isMultisite: false,
|
|
debugMode: false,
|
|
modules: [],
|
|
tables: [],
|
|
})
|
|
|
|
const tableColumns = [
|
|
{ title: '数据表', key: 'name', width: 220 },
|
|
{
|
|
title: '状态',
|
|
key: 'exists',
|
|
width: 100,
|
|
render(row) {
|
|
return h(NTag, {
|
|
type: row.exists ? 'success' : 'error',
|
|
size: 'small',
|
|
bordered: false,
|
|
}, { default: () => row.exists ? '正常' : '缺失' })
|
|
},
|
|
},
|
|
{
|
|
title: '行数',
|
|
key: 'rows',
|
|
width: 100,
|
|
render(row) {
|
|
return row.exists ? row.rows.toLocaleString() : '—'
|
|
},
|
|
},
|
|
]
|
|
|
|
onMounted(async () => {
|
|
try {
|
|
const res = await api.getHealthCheck()
|
|
const data = res?.data || res || {}
|
|
|
|
info.value = {
|
|
themeVersion: window.aksrtAdminData?.themeVersion || data.theme_version || '3.4.0-dev',
|
|
wpVersion: data.wp_version || '',
|
|
phpVersion: data.php_version || '',
|
|
dbSchemaVersion: data.db_schema_version || '',
|
|
emailBackfillDone: !!data.email_backfill_done,
|
|
siteUrl: data.site_url || window.aksrtAdminData?.siteUrl || '',
|
|
apiUrl: data.api_url || window.aksrtAdminData?.apiUrl || '',
|
|
themeDir: data.theme_dir || '',
|
|
uploadDir: data.upload_dir || '',
|
|
isMultisite: !!data.is_multisite,
|
|
debugMode: !!data.debug_mode,
|
|
modules: normalizeModules(data.modules || []),
|
|
tables: normalizeTables(data.tables || []),
|
|
}
|
|
} catch (err) {
|
|
console.error('[ThemeInfo] Failed to load health data:', err)
|
|
// Fallback with minimal info
|
|
info.value.themeVersion = '3.4.0-dev'
|
|
info.value.siteUrl = window.aksrtAdminData?.siteUrl || ''
|
|
info.value.apiUrl = window.aksrtAdminData?.apiUrl || ''
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
})
|
|
|
|
function normalizeModules(raw) {
|
|
if (!Array.isArray(raw)) return []
|
|
return raw.map(m => ({
|
|
key: m.key || m.name || '',
|
|
label: m.label || m.name || m.key || '',
|
|
enabled: !!m.enabled,
|
|
}))
|
|
}
|
|
|
|
function normalizeTables(raw) {
|
|
if (!Array.isArray(raw)) return []
|
|
return raw.map(t => ({
|
|
name: t.name || '',
|
|
exists: !!t.exists,
|
|
rows: t.rows || 0,
|
|
}))
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.aksrt-theme-info__loading {
|
|
display: flex;
|
|
justify-content: center;
|
|
padding: 60px 0;
|
|
}
|
|
|
|
.aksrt-theme-info__card {
|
|
margin-bottom: 16px;
|
|
}
|
|
|
|
.aksrt-theme-info__modules {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 8px;
|
|
}
|
|
|
|
.aksrt-theme-info__module-tag {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 5px;
|
|
}
|
|
|
|
.aksrt-theme-info__links {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 12px;
|
|
}
|
|
|
|
.aksrt-theme-info__link {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
padding: 8px 16px;
|
|
border-radius: 6px;
|
|
background: #f5f7fa;
|
|
color: #333;
|
|
text-decoration: none;
|
|
font-size: 13px;
|
|
transition: background 0.2s;
|
|
}
|
|
|
|
.aksrt-theme-info__link:hover {
|
|
background: #e8eaed;
|
|
}
|
|
</style>
|