fix: 站点列表改为单站编辑+全量可视化表格
This commit is contained in:
@@ -9,23 +9,27 @@
|
||||
</div>
|
||||
<div style="display:flex;gap:8px">
|
||||
<el-button size="small" @click="refresh" :loading="loading">刷新</el-button>
|
||||
<el-button size="small" @click="addSite">+ 新建</el-button>
|
||||
<el-button size="small" type="primary" @click="saveAll" :loading="saving">保存</el-button>
|
||||
<el-button size="small" @click="newSite">新建</el-button>
|
||||
<el-button size="small" type="primary" @click="saveSite" :loading="saving" v-if="editSiteId">保存</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="display:flex;gap:12px;flex:1;min-height:0">
|
||||
<!-- 左侧:JSON 编辑器 -->
|
||||
<div style="flex:0 0 460px;display:flex;flex-direction:column;min-height:0">
|
||||
<div style="font-size:13px;font-weight:500;margin-bottom:4px">pt-sites.json</div>
|
||||
<!-- 左侧:编辑器(当前选中站点) -->
|
||||
<div style="flex:0 0 420px;display:flex;flex-direction:column;min-height:0">
|
||||
<div style="font-size:13px;font-weight:500;margin-bottom:4px;display:flex;justify-content:space-between;align-items:center">
|
||||
<span>{{ editSiteId ? '编辑: '+editSiteId : '选择站点编辑' }}</span>
|
||||
</div>
|
||||
<div style="flex:1;min-height:0;border-radius:4px;overflow:hidden">
|
||||
<CodeEditor v-model="editorJson" language="json" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 右侧:可视化表格 -->
|
||||
<!-- 右侧:所有站点可视化 -->
|
||||
<div style="flex:1;overflow:auto;min-height:0">
|
||||
<el-table :data="parsed" stripe v-loading="loading" border empty-text="暂无站点" style="font-size:13px" :row-style="{height:'48px'}">
|
||||
<el-table :data="sites" stripe v-loading="loading" border empty-text="暂无站点"
|
||||
style="font-size:13px" :row-style="{height:'44px'}" @row-click="editSite" highlight-current-row
|
||||
:row-class-name="rowClass">
|
||||
<el-table-column prop="siteId" label="站点ID" width="110" />
|
||||
<el-table-column label="名称" min-width="130">
|
||||
<template #default="s">{{ (s.row.names||[]).join(' / ') || '-' }}</template>
|
||||
@@ -39,15 +43,16 @@
|
||||
<el-tag size="small" :type="s.row.status==='active'?'success':'info'">{{ s.row.status||'active' }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="适配版本" width="100">
|
||||
<el-table-column label="适配" width="90">
|
||||
<template #default="s">
|
||||
<el-tag v-if="s.row.latestVersion" size="small" type="primary">v{{ s.row.latestVersion }}</el-tag>
|
||||
<span v-else style="color:#909399">-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="80">
|
||||
<el-table-column label="操作" width="120">
|
||||
<template #default="s">
|
||||
<el-button size="small" type="danger" text @click="removeSite(s.$index)">删除</el-button>
|
||||
<el-button size="small" @click.stop="editSite(s.row)">编辑</el-button>
|
||||
<el-button size="small" type="danger" text @click.stop="deleteSite(s.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -60,50 +65,49 @@
|
||||
import api from '../api'
|
||||
|
||||
const loading = ref(false), saving = ref(false), pendingCount = ref(0)
|
||||
const editorJson = ref('[]')
|
||||
const sites = ref([]), editSiteId = ref(''), editorJson = ref('{}')
|
||||
|
||||
const parsed = computed(() => {
|
||||
try { return JSON.parse(editorJson.value) } catch { return [] }
|
||||
})
|
||||
const rowClass = ({row}) => row.siteId === editSiteId.value ? 'current-row' : ''
|
||||
|
||||
const refresh = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const r = await api.raw.get('/admin/sites')
|
||||
const sites = Array.isArray(r?.data) ? r.data : r || []
|
||||
editorJson.value = JSON.stringify(sites, null, 2)
|
||||
sites.value = Array.isArray(r?.data) ? r.data : r || []
|
||||
try { pendingCount.value = ((await api.sites.pendingChanges()).data || []).length } catch { pendingCount.value = 0 }
|
||||
} catch { ElMessage.error('加载失败') }
|
||||
finally { loading.value = false }
|
||||
}
|
||||
|
||||
const addSite = () => {
|
||||
const arr = parsed.value
|
||||
arr.push({ siteId: '', names: [''], urls: [''], siteType: 'nexusphp', status: 'active' })
|
||||
editorJson.value = JSON.stringify(arr, null, 2)
|
||||
const editSite = (row) => {
|
||||
editSiteId.value = row.siteId
|
||||
editorJson.value = JSON.stringify({siteId: row.siteId, names: row.names, urls: row.urls, siteType: row.siteType, status: row.status||'active'}, null, 2)
|
||||
}
|
||||
|
||||
const removeSite = (idx) => {
|
||||
const arr = parsed.value
|
||||
if (arr.length <= 1) { ElMessage.warning('至少保留一个站点'); return }
|
||||
arr.splice(idx, 1)
|
||||
editorJson.value = JSON.stringify(arr, null, 2)
|
||||
const newSite = () => {
|
||||
editSiteId.value = ''
|
||||
editorJson.value = JSON.stringify({siteId:'',names:[''],urls:[''],siteType:'nexusphp',status:'active'}, null, 2)
|
||||
}
|
||||
|
||||
const saveAll = async () => {
|
||||
const deleteSite = async (row) => {
|
||||
try { await ElMessageBox.confirm('确认删除 '+row.siteId+' ?','删除',{type:'warning'}) } catch { return }
|
||||
try {
|
||||
await api.raw.put('/admin/sites/'+row.siteId, {siteId:row.siteId,names:row.names,urls:row.urls,siteType:row.siteType,status:'deprecated'})
|
||||
ElMessage.success('已弃用')
|
||||
refresh()
|
||||
if (editSiteId.value === row.siteId) editSiteId.value = ''
|
||||
} catch { ElMessage.error('操作失败') }
|
||||
}
|
||||
|
||||
const saveSite = async () => {
|
||||
saving.value = true
|
||||
try {
|
||||
let ok = 0, fail = 0
|
||||
for (const site of parsed.value) {
|
||||
if (!site.siteId) { fail++; continue }
|
||||
try {
|
||||
await api.raw.put('/admin/sites/'+site.siteId, {
|
||||
names: site.names, urls: site.urls, siteType: site.siteType, status: site.status,
|
||||
})
|
||||
ok++
|
||||
} catch { fail++ }
|
||||
}
|
||||
ElMessage.success('保存: '+ok+' 成功, '+fail+' 失败')
|
||||
const site = JSON.parse(editorJson.value)
|
||||
if (!site.siteId) { ElMessage.warning('siteId不能为空'); return }
|
||||
await api.raw.put('/admin/sites/'+site.siteId, {
|
||||
names: site.names||[], urls: site.urls||[], siteType: site.siteType||'unknown', status: site.status||'active',
|
||||
})
|
||||
ElMessage.success('已保存')
|
||||
refresh()
|
||||
} catch { ElMessage.error('保存失败') }
|
||||
finally { saving.value = false }
|
||||
@@ -111,3 +115,7 @@ const saveAll = async () => {
|
||||
|
||||
onMounted(refresh)
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
:deep(.current-row) { background-color: #ecf5ff !important }
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user