refactor: 默认模板服务端+统一导出导入+页面配置版本历史+前端
This commit is contained in:
@@ -36,8 +36,12 @@
|
||||
<el-table-column label="更新时间" width="150">
|
||||
<template #default="s">{{ fmt(s.row.updatedAt) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="180" fixed="right">
|
||||
<el-table-column label="操作" width="220" fixed="right">
|
||||
<template #default="s">
|
||||
<el-select v-model="viewVer" placeholder="历史" size="small" style="width:70px" clearable
|
||||
@change="v=>loadVersion(s.row,v)" @click.stop>
|
||||
<el-option v-for="v in s.row.versions||[]" :key="v" :label="'v'+v" :value="v" />
|
||||
</el-select>
|
||||
<el-button size="small" @click="toggleEdit(s.row)" :type="editSiteId===s.row.siteId?'warning':''">
|
||||
{{ editSiteId===s.row.siteId ? '收起' : '编辑' }}
|
||||
</el-button>
|
||||
@@ -73,35 +77,18 @@
|
||||
import api from '../api'
|
||||
|
||||
const loading = ref(false), saving = ref(false)
|
||||
const sites = ref([]), pagesMap = ref({})
|
||||
const sites = ref([]), pagesMap = ref({}), defaultMap = ref({}), viewVer = ref('')
|
||||
const editSiteId = ref(''), editorJson = ref('')
|
||||
|
||||
const defaultPages = {
|
||||
nexusphp: [
|
||||
{key:'home', label:'首页', url:'{base}', method:'GET'},
|
||||
{key:'search', label:'搜索页', url:'{base}/torrents.php', method:'GET'},
|
||||
{key:'detail', label:'种子详情', url:'{base}/details.php?id=', method:'GET'},
|
||||
{key:'signIn', label:'签到页', url:'{base}/attendance.php', method:'POST'},
|
||||
{key:'user', label:'用户详情', url:'{base}/userdetails.php?id=', method:'GET'},
|
||||
],
|
||||
mtorrent: [
|
||||
{key:'home', label:'首页', url:'{base}/api/member/profile', method:'GET'},
|
||||
{key:'search',label:'搜索页', url:'{base}/api/torrent/search', method:'POST'},
|
||||
],
|
||||
gazelle: [
|
||||
{key:'home', label:'首页', url:'{base}/index.php', method:'GET'},
|
||||
{key:'search',label:'搜索', url:'{base}/torrents.php', method:'GET'},
|
||||
],
|
||||
unit3d: [
|
||||
{key:'home', label:'首页', url:'{base}/api/torrents/filter', method:'GET'},
|
||||
{key:'search',label:'搜索', url:'{base}/api/torrents/filter?name=', method:'GET'},
|
||||
],
|
||||
}
|
||||
const fallbackPages = { nexusphp: [{key:'home',label:'首页',url:'{base}',method:'GET'}] }
|
||||
|
||||
const defaults = computed(() => {
|
||||
const types = [...new Set((Array.isArray(sites.value)?sites.value:[]).map(s=>s.siteType).filter(Boolean))]
|
||||
const base = ['nexusphp','mtorrent','gazelle','unit3d']
|
||||
return [...new Set([...types,...base])].map(t => ({type:t, label:t, entries: (defaultPages[t]||[]) }))
|
||||
return [...new Set([...types,...base])].map(t => ({
|
||||
type:t, label:t,
|
||||
entries: defaultMap.value[t] || fallbackPages[t] || [{key:'home',label:'首页',url:'{base}',method:'GET'}]
|
||||
}))
|
||||
})
|
||||
|
||||
const fmt = (t) => t ? (t.substring(0,19)||'').replace('T',' ') : '-'
|
||||
@@ -114,6 +101,7 @@ const merged = computed(() => {
|
||||
entryCount: pagesMap.value[s.siteId]?.entryCount || 0,
|
||||
updatedAt: pagesMap.value[s.siteId]?.updatedAt || null,
|
||||
entriesJson: pagesMap.value[s.siteId]?.entriesJson || null,
|
||||
versions: pagesMap.value[s.siteId]?.versions || [],
|
||||
}))
|
||||
})
|
||||
|
||||
@@ -126,18 +114,41 @@ const fetchAll = async () => {
|
||||
])
|
||||
sites.value = (sr.status==='fulfilled' ? (sr.value?.data || sr.value || []) : [])
|
||||
const pages = pr.status==='fulfilled' ? (pr.value?.data || pr.value || []) : []
|
||||
const map = {}
|
||||
const map = {}, verMap = {}
|
||||
for (const p of pages) {
|
||||
const entries = (() => { try { return JSON.parse(p.entriesJson||'[]') } catch {return []} })()
|
||||
map[p.siteId] = { version: p.version, entryCount: entries.length, updatedAt: p.updatedAt, entriesJson: p.entriesJson }
|
||||
const v = p.version
|
||||
if (!map[p.siteId] || v > map[p.siteId].version) {
|
||||
map[p.siteId] = { version: v, entryCount: entries.length, updatedAt: p.updatedAt, entriesJson: p.entriesJson }
|
||||
}
|
||||
if (!verMap[p.siteId]) verMap[p.siteId] = new Set()
|
||||
verMap[p.siteId].add(v)
|
||||
}
|
||||
for (const k in verMap) map[k].versions = [...verMap[k]].sort((a,b)=>parseInt(b)-parseInt(a))
|
||||
pagesMap.value = map
|
||||
// 加载默认模板
|
||||
for (const t of ['nexusphp','mtorrent','gazelle','unit3d']) {
|
||||
try {
|
||||
const r = await api.raw.get('/admin/default-pages/'+t)
|
||||
const data = r?.data || r
|
||||
if (data?.entries) defaultMap.value[t] = data.entries
|
||||
} catch {}
|
||||
}
|
||||
} finally { loading.value = false }
|
||||
}
|
||||
|
||||
const loadVersion = async (row, ver) => {
|
||||
if (!ver) return
|
||||
try {
|
||||
const r = await api.raw.get('/admin/site-pages/'+row.siteId+'/version/'+ver)
|
||||
editorJson.value = JSON.stringify(JSON.parse((r?.data||r)?.content||'[]'), null, 2)
|
||||
} catch { ElMessage.error('加载版本失败') }
|
||||
}
|
||||
|
||||
const loadDefault = (row) => {
|
||||
editSiteId.value = row.siteId
|
||||
editorJson.value = JSON.stringify(defaultPages[row.siteType] || defaultPages['nexusphp'], null, 2)
|
||||
const entries = defaultMap.value[row.siteType] || fallbackPages[row.siteType] || [{key:'home',label:'首页',url:'{base}',method:'GET'}]
|
||||
editorJson.value = JSON.stringify(entries, null, 2)
|
||||
window.scrollTo({top: document.body.scrollHeight, behavior:'smooth'})
|
||||
}
|
||||
|
||||
@@ -165,7 +176,10 @@ const toggleEdit = (row) => {
|
||||
const savePages = async () => {
|
||||
saving.value = true
|
||||
try {
|
||||
await api.raw.put('/sites/'+editSiteId.value+'/pages', { entries: JSON.parse(editorJson.value) })
|
||||
const url = editSiteId.value.startsWith('default:')
|
||||
? '/admin/default-pages/'+editSiteId.value.replace('default:','')
|
||||
: '/sites/'+editSiteId.value+'/pages'
|
||||
await api.raw.put(url, { entries: JSON.parse(editorJson.value) })
|
||||
ElMessage.success('已保存'); editSiteId.value = ''; fetchAll()
|
||||
} catch { ElMessage.error('保存失败') }
|
||||
finally { saving.value = false }
|
||||
|
||||
Reference in New Issue
Block a user