feat(widgets): add phase 4 validation and accessibility
This commit is contained in:
1 parent
8cad3c2d3d
commit
e1723a8f08
117 files changed
+6
-17338
No files matched your search
@@ -1,42 +0,0 @@
|
||||
<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/update')">更新中心</n-button>
|
||||
</n-space>
|
||||
</template>
|
||||
</PageHeader>
|
||||
|
||||
<n-card class="aksrt-section-card">
|
||||
<n-alert type="info" title="按设计省略" :show-icon="true">
|
||||
本主题当前不实现 zibll 风格的授权码校验、域名绑定、撤销授权、本地免授权等机制。
|
||||
`AKSRT_Update_Checker` 仅负责匿名版本检测与更新提示,不与授权系统耦合。
|
||||
</n-alert>
|
||||
</n-card>
|
||||
|
||||
<n-card class="aksrt-section-card" title="当前策略" size="small">
|
||||
<n-list bordered>
|
||||
<n-list-item>不提供授权码输入框或“立即授权”按钮</n-list-item>
|
||||
<n-list-item>不提供“已授权 / 未授权 / 本地免授权”三态逻辑</n-list-item>
|
||||
<n-list-item>更新能力统一收口到“更新中心”与“主题信息”页</n-list-item>
|
||||
<n-list-item>若未来恢复授权体系,应单独立项,不与现有更新检测器混接</n-list-item>
|
||||
</n-list>
|
||||
</n-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useRouter } from 'vue-router'
|
||||
import PageHeader from '@/components/PageHeader.vue'
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
function go(path) {
|
||||
router.push(path)
|
||||
}
|
||||
</script>
|
||||
@@ -1,265 +0,0 @@
|
||||
<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>
|
||||
Reference in new issue
Block a user