feat: 编辑器增加版本状态(预览版/正式版)和未保存提示
This commit is contained in:
@@ -7,6 +7,7 @@ import com.par.core.dto.SiteConfigDTO;
|
||||
import com.par.core.entity.Account;
|
||||
import com.par.core.entity.Psk;
|
||||
import com.par.core.entity.SiteConfig;
|
||||
import com.par.core.entity.SiteSnapshot;
|
||||
import com.par.core.enums.ConfigStatus;
|
||||
import com.par.core.enums.TrustLevel;
|
||||
import com.par.core.event.SnapshotUpdateEvent;
|
||||
@@ -14,6 +15,7 @@ import com.par.core.mapper.AccountMapper;
|
||||
import com.par.core.mapper.ConfigReviewMapper;
|
||||
import com.par.core.mapper.SiteConfigMapper;
|
||||
import com.par.core.mapper.SiteMapper;
|
||||
import com.par.core.mapper.SiteSnapshotMapper;
|
||||
import com.par.core.service.AccountService;
|
||||
import com.par.core.service.ConfigService;
|
||||
import com.par.core.service.PskService;
|
||||
@@ -44,6 +46,7 @@ public class AdminController {
|
||||
private final ConfigReviewMapper configReviewMapper;
|
||||
private final AccountMapper accountMapper;
|
||||
private final SiteMapper siteMapper;
|
||||
private final SiteSnapshotMapper snapshotMapper;
|
||||
private final AccountService accountService;
|
||||
private final PskService pskService;
|
||||
private final ConfigService configService;
|
||||
@@ -418,6 +421,47 @@ public class AdminController {
|
||||
}
|
||||
}
|
||||
|
||||
/** 查询站点快照状态(draft / published 版本信息) */
|
||||
@GetMapping("/sites/{siteId}/snapshot-status")
|
||||
public ApiResponse<Map<String, Object>> getSnapshotStatus(@PathVariable("siteId") String siteId,
|
||||
HttpServletRequest request) {
|
||||
checkAdmin(request);
|
||||
SiteSnapshot draft = snapshotMapper.selectLatestDraft(siteId);
|
||||
SiteSnapshot published = snapshotMapper.selectLatestPublished(siteId);
|
||||
|
||||
Map<String, Object> result = new LinkedHashMap<>();
|
||||
result.put("siteId", siteId);
|
||||
|
||||
Map<String, Object> draftInfo = new LinkedHashMap<>();
|
||||
if (draft != null) {
|
||||
draftInfo.put("exists", true);
|
||||
draftInfo.put("version", draft.getVersion());
|
||||
draftInfo.put("checksum", draft.getChecksum() != null ? draft.getChecksum().substring(0, 8) : null);
|
||||
draftInfo.put("updatedAt", draft.getUpdatedAt() != null ? draft.getUpdatedAt().toString() : null);
|
||||
} else {
|
||||
draftInfo.put("exists", false);
|
||||
}
|
||||
result.put("draft", draftInfo);
|
||||
|
||||
Map<String, Object> pubInfo = new LinkedHashMap<>();
|
||||
if (published != null) {
|
||||
pubInfo.put("exists", true);
|
||||
pubInfo.put("version", published.getVersion());
|
||||
pubInfo.put("checksum", published.getChecksum() != null ? published.getChecksum().substring(0, 8) : null);
|
||||
pubInfo.put("publishedAt", published.getPublishedAt() != null ? published.getPublishedAt().toString() : null);
|
||||
} else {
|
||||
pubInfo.put("exists", false);
|
||||
}
|
||||
result.put("published", pubInfo);
|
||||
|
||||
// 是否有新 draft 待发布(draft 存在且与 published 不同)
|
||||
boolean hasPendingPublish = draft != null && (published == null
|
||||
|| (draft.getChecksum() != null && !draft.getChecksum().equals(published.getChecksum())));
|
||||
result.put("hasPendingPublish", hasPendingPublish);
|
||||
|
||||
return ApiResponse.success(result);
|
||||
}
|
||||
|
||||
@GetMapping("/sites")
|
||||
public ApiResponse<List<com.par.core.dto.SiteDTO>> listAllSites(HttpServletRequest request) {
|
||||
checkAdmin(request);
|
||||
|
||||
@@ -2,7 +2,13 @@
|
||||
<div style="display:flex;flex-direction:column;height:calc(100vh - 80px)">
|
||||
<!-- 顶栏 -->
|
||||
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:8px;flex-shrink:0">
|
||||
<h2 style="margin:0">适配校验:{{ siteId }}</h2>
|
||||
<div style="display:flex;align-items:center;gap:10px">
|
||||
<h2 style="margin:0">适配校验:{{ siteId }}</h2>
|
||||
<!-- 快照状态 -->
|
||||
<el-tag v-if="snapshotStatus" size="small" :type="snapshotStatus.hasPendingPublish ? 'warning' : snapshotStatus.draft.exists ? 'info' : 'success'">
|
||||
{{ snapshotStatus.hasPendingPublish ? '预览版 v' + snapshotStatus.draft.version : snapshotStatus.draft.exists ? '预览版 v' + snapshotStatus.draft.version : snapshotStatus.published.exists ? '正式版 v' + snapshotStatus.published.version : '未发布' }}
|
||||
</el-tag>
|
||||
</div>
|
||||
<el-button @click="$router.push('/access-results')">← 返回列表</el-button>
|
||||
</div>
|
||||
|
||||
@@ -49,6 +55,10 @@
|
||||
<el-button size="small" type="danger" @click="rejectConfig" :loading="rejecting">拒绝</el-button>
|
||||
</template>
|
||||
<el-button v-if="selectedConfig?.status!=='pending'" size="small" type="success" @click="approveConfig" :loading="approving">发布</el-button>
|
||||
<!-- 快照发布 -->
|
||||
<el-button size="small" @click="savePreview" :loading="savingPreview" v-if="snapshotStatus">保存预览版</el-button>
|
||||
<el-button size="small" type="success" @click="publishSnapshot" :loading="publishing" v-if="snapshotStatus?.draft.exists || snapshotStatus?.hasPendingPublish">发布正式版</el-button>
|
||||
<el-tag v-if="hasUnsavedChanges" size="small" type="danger" effect="dark">未保存</el-tag>
|
||||
</template>
|
||||
<el-button v-if="!scriptExpanded && selectedConfigId" size="small" type="primary" @click="saveScript" :loading="saving">保存</el-button>
|
||||
</div>
|
||||
@@ -150,11 +160,17 @@ const siteId = route.params.siteId
|
||||
|
||||
const loading = ref(false), parseLoading = ref(false), scriptExpanded = ref(true), historyVersion = ref(null), urlFilter = ref(''), deleting = ref(false)
|
||||
const selectedConfigId = ref(null), selectedConfig = ref(null)
|
||||
const scriptContent = ref(''), saving = ref(false), approving = ref(false), rejecting = ref(false)
|
||||
const scriptContent = ref(''), originalScript = ref(''), saving = ref(false), approving = ref(false), rejecting = ref(false)
|
||||
const savingPreview = ref(false), publishing = ref(false)
|
||||
const snapshotStatus = ref(null)
|
||||
const allConfigVersions = ref([]), allResults = ref([])
|
||||
const pageParsed = ref({}), reparsingUrls = reactive(new Set()), expanded = reactive(new Set())
|
||||
const rawVisible = ref(false), rawLoading = ref(false), rawContent = ref('')
|
||||
|
||||
const hasUnsavedChanges = computed(() => {
|
||||
return originalScript.value !== '' && scriptContent.value !== originalScript.value
|
||||
})
|
||||
|
||||
const totalResults = computed(() => allResults.value.length)
|
||||
|
||||
const filteredPages = computed(() => {
|
||||
@@ -215,8 +231,27 @@ const onConfigChange = () => {
|
||||
|
||||
const loadScript = async () => {
|
||||
if (!selectedConfig.value) return
|
||||
try { const r = await api.adminConfigs.getScript(selectedConfig.value.id); scriptContent.value = r.data?.script||'' }
|
||||
catch { scriptContent.value = '' }
|
||||
try { const r = await api.adminConfigs.getScript(selectedConfig.value.id); scriptContent.value = r.data?.script||''; originalScript.value = scriptContent.value }
|
||||
catch { scriptContent.value = ''; originalScript.value = '' }
|
||||
}
|
||||
|
||||
const fetchSnapshotStatus = async () => {
|
||||
try { snapshotStatus.value = (await api.raw.get('/admin/sites/' + siteId + '/snapshot-status')).data || null }
|
||||
catch { snapshotStatus.value = null }
|
||||
}
|
||||
|
||||
const savePreview = async () => {
|
||||
savingPreview.value = true
|
||||
try { await api.raw.post('/admin/sites/' + siteId + '/save-preview'); ElMessage.success('预览版已保存'); fetchSnapshotStatus() }
|
||||
catch { ElMessage.error('保存预览版失败') }
|
||||
finally { savingPreview.value = false }
|
||||
}
|
||||
|
||||
const publishSnapshot = async () => {
|
||||
publishing.value = true
|
||||
try { await api.raw.post('/admin/sites/' + siteId + '/publish'); ElMessage.success('已发布为正式版'); fetchSnapshotStatus() }
|
||||
catch { ElMessage.error('发布失败') }
|
||||
finally { publishing.value = false }
|
||||
}
|
||||
|
||||
watch(selectedConfig, (v) => { if (v) loadScript() })
|
||||
@@ -240,7 +275,7 @@ const revertScript = async () => {
|
||||
const saveScript = async () => {
|
||||
if (!selectedConfig.value) return
|
||||
saving.value = true
|
||||
try { await api.adminConfigs.updateScript(selectedConfig.value.id, scriptContent.value); ElMessage.success('已保存') }
|
||||
try { await api.adminConfigs.updateScript(selectedConfig.value.id, scriptContent.value); originalScript.value = scriptContent.value; ElMessage.success('已保存') }
|
||||
catch(e) { ElMessage.error(e.response?.data?.message||'保存失败') }
|
||||
finally { saving.value = false }
|
||||
}
|
||||
@@ -333,6 +368,7 @@ const statusTag = (c) => c>=200&&c<300?'success':c>=300&&c<400?'warning':'danger
|
||||
onMounted(async () => {
|
||||
await refresh()
|
||||
await loadConfigs()
|
||||
fetchSnapshotStatus()
|
||||
if (selectedConfigId.value) {
|
||||
selectedConfig.value = allConfigVersions.value.find(v=>v.id===selectedConfigId.value)
|
||||
}
|
||||
|
||||
@@ -32,11 +32,18 @@
|
||||
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:10px;flex-shrink:0">
|
||||
<div style="display:flex;align-items:center;gap:12px">
|
||||
<h2 style="margin:0">编辑: {{ editSiteName }}</h2>
|
||||
<!-- 快照状态 -->
|
||||
<el-tag v-if="snapshotStatus" size="small" :type="snapshotStatus.hasPendingPublish ? 'warning' : snapshotStatus.draft.exists ? 'info' : 'success'">
|
||||
{{ snapshotStatus.hasPendingPublish ? '预览版 v' + snapshotStatus.draft.version : snapshotStatus.draft.exists ? '预览版 v' + snapshotStatus.draft.version : snapshotStatus.published.exists ? '正式版 v' + snapshotStatus.published.version : '未发布' }}
|
||||
</el-tag>
|
||||
<el-tag v-if="hasUnsavedChanges" size="small" type="danger" effect="dark">未保存</el-tag>
|
||||
<el-tag size="small" type="info">{{ parsed.length }} 条规则</el-tag>
|
||||
</div>
|
||||
<div style="display:flex;gap:8px">
|
||||
<el-button size="small" type="primary" @click="saveRules" :loading="saving">保存</el-button>
|
||||
<el-button size="small" @click="uploadRules" :loading="uploading">上传</el-button>
|
||||
<el-button v-if="snapshotStatus" size="small" @click="savePreview" :loading="savingPreview">保存预览版</el-button>
|
||||
<el-button v-if="snapshotStatus?.draft.exists" size="small" type="success" @click="publishSnapshot" :loading="publishing">发布正式版</el-button>
|
||||
<el-button size="small" @click="editType=''">返回列表</el-button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -272,11 +279,18 @@ const presets = [
|
||||
]
|
||||
|
||||
// ============ 状态 ============
|
||||
const loading = ref(false), saving = ref(false), uploading = ref(false)
|
||||
const loading = ref(false), saving = ref(false), uploading = ref(false), savingPreview = ref(false), publishing = ref(false)
|
||||
const sites = ref([]), rulesMap = ref({})
|
||||
const editType = ref(''), editorJson = ref('[]')
|
||||
const editType = ref(''), editorJson = ref('[]'), originalJson = ref('')
|
||||
const snapshotStatus = ref(null)
|
||||
const dragIdx = ref(null)
|
||||
|
||||
const hasUnsavedChanges = computed(() => {
|
||||
if (!editType.value) return false
|
||||
try { return JSON.stringify(JSON.parse(editorJson.value)) !== JSON.stringify(JSON.parse(originalJson.value || '[]')) }
|
||||
catch { return false }
|
||||
})
|
||||
|
||||
const fmt = (t) => t ? (t.substring(0,19)||'').replace('T',' ') : '-'
|
||||
|
||||
const parsed = computed({
|
||||
@@ -366,6 +380,27 @@ const editRule = async (row) => {
|
||||
const r = await api.raw.get('/admin/risk-rules/'+row.siteId)
|
||||
editorJson.value = (r?.data||r)?.rules ? JSON.stringify((r.data||r).rules, null, 2) : '[]'
|
||||
} catch { editorJson.value = '[]' }
|
||||
originalJson.value = editorJson.value
|
||||
fetchSnapshotStatus()
|
||||
}
|
||||
|
||||
const fetchSnapshotStatus = async () => {
|
||||
try { snapshotStatus.value = (await api.raw.get('/admin/sites/' + editType.value + '/snapshot-status')).data || null }
|
||||
catch { snapshotStatus.value = null }
|
||||
}
|
||||
|
||||
const savePreview = async () => {
|
||||
savingPreview.value = true
|
||||
try { await api.raw.post('/admin/sites/' + editType.value + '/save-preview'); ElMessage.success('预览版已保存'); fetchSnapshotStatus() }
|
||||
catch { ElMessage.error('保存预览版失败') }
|
||||
finally { savingPreview.value = false }
|
||||
}
|
||||
|
||||
const publishSnapshot = async () => {
|
||||
publishing.value = true
|
||||
try { await api.raw.post('/admin/sites/' + editType.value + '/publish'); ElMessage.success('已发布为正式版'); fetchSnapshotStatus() }
|
||||
catch { ElMessage.error('发布失败') }
|
||||
finally { publishing.value = false }
|
||||
}
|
||||
|
||||
const sync = () => { editorJson.value = JSON.stringify(parsed.value, null, 2) }
|
||||
@@ -429,6 +464,7 @@ const saveRules = async () => {
|
||||
saving.value = true
|
||||
try {
|
||||
await api.raw.post('/risk-rules/'+editType.value, { rules: parsed.value })
|
||||
originalJson.value = editorJson.value
|
||||
ElMessage.success('已保存')
|
||||
} catch { ElMessage.error('保存失败') }
|
||||
finally { saving.value = false }
|
||||
|
||||
@@ -43,10 +43,19 @@
|
||||
<!-- 编辑模式:全屏双栏 -->
|
||||
<div v-else style="display:flex;flex-direction:column;height:calc(100vh - 80px)">
|
||||
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:8px">
|
||||
<h2 style="margin:0">编辑: {{ editSiteId }}</h2>
|
||||
<div style="display:flex;align-items:center;gap:10px">
|
||||
<h2 style="margin:0">编辑: {{ editSiteId }}</h2>
|
||||
<!-- 快照状态(仅对非默认模板显示) -->
|
||||
<el-tag v-if="!isDefaultEditor && snapshotStatus" size="small" :type="snapshotStatus.hasPendingPublish ? 'warning' : snapshotStatus.draft.exists ? 'info' : 'success'">
|
||||
{{ snapshotStatus.hasPendingPublish ? '预览版 v' + snapshotStatus.draft.version : snapshotStatus.draft.exists ? '预览版 v' + snapshotStatus.draft.version : snapshotStatus.published.exists ? '正式版 v' + snapshotStatus.published.version : '未发布' }}
|
||||
</el-tag>
|
||||
<el-tag v-if="hasUnsavedChanges" size="small" type="danger" effect="dark">未保存</el-tag>
|
||||
</div>
|
||||
<div style="display:flex;gap:8px">
|
||||
<el-button size="small" type="primary" @click="savePages" :loading="saving">保存</el-button>
|
||||
<el-button size="small" @click="uploadPages" :loading="uploading">上传</el-button>
|
||||
<el-button v-if="!isDefaultEditor && snapshotStatus" size="small" @click="savePreview" :loading="savingPreview">保存预览版</el-button>
|
||||
<el-button v-if="!isDefaultEditor && snapshotStatus?.draft.exists" size="small" type="success" @click="publishSnapshot" :loading="publishing">发布正式版</el-button>
|
||||
<el-button size="small" type="danger" @click="deletePages" :loading="deleting">删除</el-button>
|
||||
<el-button size="small" @click="editSiteId=''">返回列表</el-button>
|
||||
</div>
|
||||
@@ -113,8 +122,10 @@
|
||||
<script setup>
|
||||
import api from '../api'; import { Refresh } from '@element-plus/icons-vue'
|
||||
|
||||
const loading = ref(false), saving = ref(false), uploading = ref(false), deleting = ref(false), sites = ref([]), pagesMap = ref({}), sitesList = ref([])
|
||||
const editSiteId = ref(''), editorJson = ref('{}')
|
||||
const loading = ref(false), saving = ref(false), uploading = ref(false), deleting = ref(false), savingPreview = ref(false), publishing = ref(false)
|
||||
const sites = ref([]), pagesMap = ref({}), sitesList = ref([])
|
||||
const editSiteId = ref(''), editorJson = ref('{}'), originalJson = ref('')
|
||||
const snapshotStatus = ref(null)
|
||||
const authType = ref('NONE')
|
||||
const defaultTypes = ['nexusphp','mtorrent','gazelle','unit3d']
|
||||
const isDefaultEditor = computed(() => editSiteId.value.startsWith('default:'))
|
||||
@@ -122,6 +133,12 @@ const pageKeys = ref([])
|
||||
const verifying = ref({})
|
||||
const verifyResults = ref({})
|
||||
|
||||
const hasUnsavedChanges = computed(() => {
|
||||
if (!editSiteId.value) return false
|
||||
try { return JSON.stringify(JSON.parse(editorJson.value)) !== JSON.stringify(JSON.parse(originalJson.value || '{}')) }
|
||||
catch { return false }
|
||||
})
|
||||
|
||||
const loadPageKeys = async () => {
|
||||
try { const r = await api.raw.get('/admin/page-keys'); pageKeys.value = r?.data || r || [] }
|
||||
catch {}
|
||||
@@ -207,6 +224,27 @@ const editPage = async (row) => {
|
||||
authType.value = data?.authType || 'NONE'
|
||||
editorJson.value = JSON.stringify({ authType: authType.value, entries: data?.entries || [] }, null, 2)
|
||||
} catch { editorJson.value = JSON.stringify({ authType:'NONE', entries:[] }, null, 2) }
|
||||
originalJson.value = editorJson.value
|
||||
if (!row.siteId.startsWith('default:')) fetchSnapshotStatus()
|
||||
}
|
||||
|
||||
const fetchSnapshotStatus = async () => {
|
||||
try { snapshotStatus.value = (await api.raw.get('/admin/sites/' + editSiteId.value + '/snapshot-status')).data || null }
|
||||
catch { snapshotStatus.value = null }
|
||||
}
|
||||
|
||||
const savePreview = async () => {
|
||||
savingPreview.value = true
|
||||
try { await api.raw.post('/admin/sites/' + editSiteId.value + '/save-preview'); ElMessage.success('预览版已保存'); fetchSnapshotStatus() }
|
||||
catch { ElMessage.error('保存预览版失败') }
|
||||
finally { savingPreview.value = false }
|
||||
}
|
||||
|
||||
const publishSnapshot = async () => {
|
||||
publishing.value = true
|
||||
try { await api.raw.post('/admin/sites/' + editSiteId.value + '/publish'); ElMessage.success('已发布为正式版'); fetchSnapshotStatus() }
|
||||
catch { ElMessage.error('发布失败') }
|
||||
finally { publishing.value = false }
|
||||
}
|
||||
|
||||
const remove = (idx) => { parsed.value.splice(idx,1); syncToJson() }
|
||||
@@ -240,6 +278,7 @@ const savePages = async () => {
|
||||
? '/admin/default-pages/' + editSiteId.value.replace('default:','')
|
||||
: '/sites/' + editSiteId.value + '/pages'
|
||||
await api.raw.put(url, { entries: parsed.value, authType: authType.value })
|
||||
originalJson.value = editorJson.value
|
||||
ElMessage.success('已保存'); editSiteId.value=''; fetchAll()
|
||||
} catch { ElMessage.error('保存失败') }
|
||||
finally { saving.value = false }
|
||||
|
||||
@@ -53,7 +53,14 @@
|
||||
<!-- 编辑模式:全屏双栏 -->
|
||||
<div v-else style="display:flex;flex-direction:column;height:calc(100vh - 80px)">
|
||||
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:8px">
|
||||
<h2 style="margin:0">站点编辑: {{ editSiteId }}</h2>
|
||||
<div style="display:flex;align-items:center;gap:10px">
|
||||
<h2 style="margin:0">站点编辑: {{ editSiteId }}</h2>
|
||||
<!-- 快照状态 -->
|
||||
<el-tag v-if="snapshotStatus" size="small" :type="snapshotStatus.hasPendingPublish ? 'warning' : snapshotStatus.draft.exists ? 'info' : 'success'">
|
||||
{{ snapshotStatus.hasPendingPublish ? '预览版 v' + snapshotStatus.draft.version : snapshotStatus.draft.exists ? '预览版 v' + snapshotStatus.draft.version : snapshotStatus.published.exists ? '正式版 v' + snapshotStatus.published.version : '未发布' }}
|
||||
</el-tag>
|
||||
<el-tag v-if="hasUnsavedChanges" size="small" type="danger" effect="dark">未保存</el-tag>
|
||||
</div>
|
||||
<div style="display:flex;gap:8px">
|
||||
<el-button size="small" @click="editSiteId=''">返回列表</el-button>
|
||||
<el-button size="small" @click="saveSite" :loading="saving">保存站点</el-button>
|
||||
@@ -109,10 +116,17 @@
|
||||
import api from '../api'
|
||||
|
||||
const loading = ref(false), saving = ref(false), savingPreview = ref(false), publishing = ref(false), pendingCount = ref(0)
|
||||
const sites = ref([]), editSiteId = ref(''), editorJson = ref('{}'), jsonError = ref(false)
|
||||
const sites = ref([]), editSiteId = ref(''), editorJson = ref('{}'), jsonError = ref(false), originalJson = ref('')
|
||||
const snapshotStatus = ref(null)
|
||||
const form = reactive({ siteId:'', namesStr:'', urlsStr:'', tagsStr:'', desc:'', siteType:'nexusphp', status:'active' })
|
||||
let syncing = false
|
||||
|
||||
const hasUnsavedChanges = computed(() => {
|
||||
if (!editSiteId.value) return false
|
||||
try { return JSON.stringify(JSON.parse(editorJson.value)) !== JSON.stringify(JSON.parse(originalJson.value || '{}')) }
|
||||
catch { return false }
|
||||
})
|
||||
|
||||
const jsonToForm = () => {
|
||||
try {
|
||||
const s = JSON.parse(editorJson.value)
|
||||
@@ -148,6 +162,14 @@ const refresh = async () => {
|
||||
const editSite = (row) => {
|
||||
editSiteId.value = row.siteId
|
||||
editorJson.value = JSON.stringify({siteId:row.siteId,names:row.names,urls:row.urls,tags:row.tags||[],description:row.description||'',siteType:row.siteType,status:row.status||'active'}, null, 2)
|
||||
originalJson.value = editorJson.value
|
||||
fetchSnapshotStatus()
|
||||
}
|
||||
|
||||
const fetchSnapshotStatus = async () => {
|
||||
if (!editSiteId.value || editSiteId.value === '(新建)') { snapshotStatus.value = null; return }
|
||||
try { snapshotStatus.value = (await api.raw.get('/admin/sites/' + editSiteId.value + '/snapshot-status')).data || null }
|
||||
catch { snapshotStatus.value = null }
|
||||
}
|
||||
|
||||
const newSite = () => {
|
||||
@@ -160,6 +182,7 @@ const savePreview = async () => {
|
||||
try {
|
||||
await api.raw.post('/admin/sites/' + editSiteId.value + '/save-preview')
|
||||
ElMessage.success('预览版已保存')
|
||||
fetchSnapshotStatus()
|
||||
} catch { ElMessage.error('保存预览版失败') }
|
||||
finally { savingPreview.value = false }
|
||||
}
|
||||
@@ -169,6 +192,7 @@ const publishSite = async () => {
|
||||
try {
|
||||
await api.raw.post('/admin/sites/' + editSiteId.value + '/publish')
|
||||
ElMessage.success('已发布为正式版')
|
||||
fetchSnapshotStatus()
|
||||
} catch { ElMessage.error('发布失败') }
|
||||
finally { publishing.value = false }
|
||||
}
|
||||
@@ -180,6 +204,7 @@ const saveSite = async () => {
|
||||
if (!s.siteId) { ElMessage.warning('siteId不能为空'); return }
|
||||
const r = await api.raw.put('/sites/'+s.siteId, {names:s.names||[],urls:s.urls||[],tags:s.tags||[],description:s.description||'',siteType:s.siteType||'unknown',status:s.status||'active'})
|
||||
if (r.code !== 200) throw new Error(r.message || '保存失败')
|
||||
originalJson.value = editorJson.value
|
||||
ElMessage.success('已保存'); editSiteId.value = ''; refresh()
|
||||
} catch { ElMessage.error('保存失败') }
|
||||
finally { saving.value = false }
|
||||
|
||||
Reference in New Issue
Block a user