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

191 lines
5.5 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="导出当前设置快照、执行 dry-run 导入校验,并支持按域重置到 schema 默认值。"
>
<template #actions>
<n-space>
<n-button quaternary @click="go('/tools/backup')">数据备份</n-button>
<n-button quaternary @click="go('/tools/health')">健康检查</n-button>
</n-space>
</template>
</PageHeader>
<n-card class="aksrt-section-card">
<div class="aksrt-section-header">
<h3>导出与导入</h3>
</div>
<n-space style="margin-bottom: 16px;">
<n-button :loading="exporting" @click="handleExport">导出当前配置</n-button>
<n-button :loading="importing" @click="handleDryRun">Dry Run 校验</n-button>
<n-button type="primary" :loading="importing" @click="handleImport">执行导入</n-button>
</n-space>
<n-input
v-model:value="payloadText"
type="textarea"
:autosize="{ minRows: 12, maxRows: 20 }"
placeholder="导出的 JSON 会出现在这里,也可以直接粘贴导入。"
/>
<p class="aksrt-tools-hint">
正式导入前会自动创建一份“导入前自动快照”,与“数据备份”页的快照体系共用,便于回滚。
</p>
</n-card>
<n-card class="aksrt-section-card">
<div class="aksrt-section-header">
<h3>按域重置</h3>
</div>
<n-space align="center" wrap>
<n-select v-model:value="resetDomain" :options="domainOptions" style="width: 220px;" />
<n-button :loading="resetting" @click="handleReset">重置所选域</n-button>
<n-button type="error" tertiary :loading="resettingAll" @click="handleResetAll">重置全部</n-button>
</n-space>
<p class="aksrt-tools-hint">仅支持重置 schema 托管的业务域。健康检查和迁移状态属于运维面板,不参与按域回滚。</p>
</n-card>
<n-card class="aksrt-section-card">
<div class="aksrt-section-header">
<h3>最近结果</h3>
</div>
<pre class="aksrt-tools-output">{{ resultText || '尚未执行操作。' }}</pre>
</n-card>
</div>
</template>
<script setup>
import { 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 exporting = ref(false)
const importing = ref(false)
const resetting = ref(false)
const resettingAll = ref(false)
const payloadText = ref('')
const resultText = ref('')
const resetDomain = ref('global')
const domainOptions = [
{ label: '全局&功能', value: 'global' },
{ label: '页面&显示', value: 'page_display' },
{ label: '文章&列表', value: 'post_list' },
{ label: '用户&互动', value: 'users' },
{ label: '支付&付费', value: 'payment' },
]
function go(path) {
router.push(path)
}
function extractData(response) {
return response?.data ?? response ?? {}
}
function parsePayload() {
try {
return JSON.parse(payloadText.value || '{}')
} catch (error) {
throw new Error('导入 JSON 格式无效')
}
}
async function handleExport() {
exporting.value = true
try {
const data = extractData(await api.exportSettings())
payloadText.value = JSON.stringify(data, null, 2)
resultText.value = `导出完成\n版本: ${data.version || 'unknown'}\n时间: ${data.exported || 'unknown'}`
message.success('导出成功')
} catch (error) {
message.error(error.message || '导出失败')
} finally {
exporting.value = false
}
}
async function handleDryRun() {
importing.value = true
try {
const payload = parsePayload()
const result = await api.importSettings({ ...payload, dry_run: true })
resultText.value = JSON.stringify(result, null, 2)
message.success('Dry Run 校验完成')
} catch (error) {
message.error(error.message || '校验失败')
} finally {
importing.value = false
}
}
async function handleImport() {
importing.value = true
try {
const payload = parsePayload()
const result = await api.importSettings(payload)
resultText.value = JSON.stringify(result, null, 2)
message.success('导入完成')
} catch (error) {
message.error(error.message || '导入失败')
} finally {
importing.value = false
}
}
async function handleReset() {
resetting.value = true
try {
const result = await api.resetDomain(resetDomain.value)
resultText.value = JSON.stringify(result, null, 2)
message.success('域设置已重置')
} catch (error) {
message.error(error.message || '重置失败')
} finally {
resetting.value = false
}
}
async function handleResetAll() {
if (!window.confirm('确认重置全部 schema 托管设置吗?系统会先自动创建一份“重置全部前快照”。')) {
return
}
resettingAll.value = true
try {
const result = await api.resetAllSettings()
resultText.value = JSON.stringify(result, null, 2)
message.success('全部设置已重置')
} catch (error) {
message.error(error.message || '重置全部失败')
} finally {
resettingAll.value = false
}
}
</script>
<style scoped>
.aksrt-tools-output {
margin: 0;
padding: 14px;
border-radius: 12px;
background: #101828;
color: #d0d7e2;
font-size: 12px;
line-height: 1.7;
white-space: pre-wrap;
word-break: break-word;
}
.aksrt-tools-hint {
margin: 12px 0 0;
color: #667085;
font-size: 12px;
line-height: 1.7;
}
</style>