feat: 配置审核页展示已审批历史版本,支持点击对比

This commit is contained in:
mediabot-pt
2026-06-29 23:37:01 +08:00
parent 7c7fe0405a
commit 4c9c53d7c8
2 changed files with 48 additions and 3 deletions

View File

@@ -39,6 +39,7 @@ export default {
configs: {
list: () => api.get('/configs'),
pending: () => api.get('/configs/pending'),
bySite: (siteId) => api.get(`/configs/${siteId}`),
download: (siteId, version) => api.get(`/configs/${siteId}/${version}`),
approve: (id, comment) => api.post(`/admin/reviews/${id}/approve`, null, { params: { comment } }),
reject: (id, comment) => api.post(`/admin/reviews/${id}/reject`, null, { params: { comment } })

View File

@@ -21,14 +21,27 @@
</el-table>
</el-card>
<el-dialog v-model="viewVisible" title="配置详情" width="700px" :close-on-click-modal="false">
<el-dialog v-model="viewVisible" title="配置详情" width="900px" :close-on-click-modal="false">
<div class="config-info">
<span class="label">站点:</span> {{ viewing.siteId }} &nbsp;
<span class="label">版本:</span> {{ viewing.version }} &nbsp;
<span class="label">提交者:</span> {{ viewing.submitterId || '-' }}
<span style="margin-left: 16px">
<el-button size="small" @click="toggleHistory">历史版本 ({{ historyConfigs.length }})</el-button>
</span>
</div>
<div style="margin-top: 12px; max-height: 500px; overflow: auto">
<pre class="config-json" v-html="highlightedJson"></pre>
<div style="display: flex; gap: 12px; margin-top: 12px; max-height: 500px">
<div :style="{ flex: showHistory ? '1' : '1' }" style="overflow: auto">
<div class="section-title">待审核配置</div>
<pre class="config-json" v-html="highlightedJson"></pre>
</div>
<div v-if="showHistory && historyConfigs.length" style="flex: none; width: 280px; overflow: auto; border-left: 1px solid #ebeef5; padding-left: 12px">
<div class="section-title">已审批版本</div>
<div v-for="h in historyConfigs" :key="h.id" class="history-item" @click="loadHistoryConfig(h)">
<span class="history-version">v{{ h.version }}</span>
<span class="history-time">{{ h.createdAt }}</span>
</div>
</div>
</div>
<template #footer>
<el-button @click="viewVisible = false">关闭</el-button>
@@ -45,6 +58,9 @@ const loading = ref(false)
const viewVisible = ref(false)
const viewing = ref({})
const configContent = ref('')
const historyConfigs = ref([])
const showHistory = ref(false)
const loadingHistory = ref(false)
const fetchPending = async () => {
loading.value = true
@@ -61,6 +77,8 @@ const fetchPending = async () => {
const handleView = async (row) => {
viewing.value = row
configContent.value = ''
historyConfigs.value = []
showHistory.value = false
viewVisible.value = true
try {
const res = await api.configs.download(row.siteId, row.version)
@@ -70,6 +88,27 @@ const handleView = async (row) => {
}
}
const loadHistoryConfig = async (h) => {
try {
const res = await api.configs.download(h.siteId, h.version)
configContent.value = typeof res === 'string' ? res : JSON.stringify(res, null, 2)
} catch {
configContent.value = '(加载失败)'
}
}
const toggleHistory = async () => {
showHistory.value = !showHistory.value
if (showHistory.value && historyConfigs.value.length === 0 && viewing.value.siteId) {
loadingHistory.value = true
try {
const res = await api.configs.bySite(viewing.value.siteId)
historyConfigs.value = (res.data || []).filter(c => c.status === 'approved').reverse()
} catch {}
loadingHistory.value = false
}
}
const highlightedJson = computed(() => {
try {
const obj = JSON.parse(configContent.value)
@@ -154,4 +193,9 @@ onMounted(fetchPending)
.config-json :deep(.number) { color: #b5cea8; }
.config-json :deep(.boolean) { color: #569cd6; }
.config-json :deep(.null) { color: #569cd6; }
.section-title { font-size: 12px; font-weight: bold; color: #303133; margin-bottom: 8px; }
.history-item { padding: 6px 8px; cursor: pointer; border-radius: 4px; margin-bottom: 4px; }
.history-item:hover { background: #f0f5ff; }
.history-version { font-size: 12px; font-weight: bold; color: #409EFF; }
.history-time { font-size: 11px; color: #909399; margin-left: 8px; }
</style>