refactor: 拆分两个独立菜单(页面配置+风险规则)+CRUD完整+删除接口
This commit is contained in:
118
web/src/views/SitePages.vue
Normal file
118
web/src/views/SitePages.vue
Normal file
@@ -0,0 +1,118 @@
|
||||
<template>
|
||||
<div>
|
||||
<h2>页面配置</h2>
|
||||
<el-card style="margin-top:20px">
|
||||
<div style="margin-bottom:12px;display:flex;gap:8px">
|
||||
<el-button @click="fetchAll" :loading="loading">刷新</el-button>
|
||||
<el-button type="primary" @click="showEditor(null, null)">新建</el-button>
|
||||
</div>
|
||||
|
||||
<el-table :data="sites" stripe size="small" v-loading="loading" empty-text="暂无配置">
|
||||
<el-table-column prop="siteId" label="站点" width="140" />
|
||||
<el-table-column prop="version" label="版本" width="80" />
|
||||
<el-table-column label="页面入口" min-width="200">
|
||||
<template #default="s">
|
||||
<el-tag v-for="e in getEntries(s.row)" :key="e.key" size="small" style="margin:1px">{{ e.label || e.key }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="更新时间" width="160">
|
||||
<template #default="s">{{ fmt(s.row.updatedAt) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="140">
|
||||
<template #default="s">
|
||||
<el-button size="small" @click="showEditor(s.row.siteId, s.row)">编辑</el-button>
|
||||
<el-button size="small" type="danger" text @click="deletePages(s.row.siteId)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
|
||||
<el-dialog v-model="editorVisible" :title="editorTitle" width="800px" destroy-on-close>
|
||||
<div style="margin-bottom:8px;color:#909399">
|
||||
<span v-if="!isNewSite">版本: {{ editorData?.version }} | {{ editorData?.entries?.length || 0 }} 个入口</span>
|
||||
</div>
|
||||
<el-table :data="editingEntries" stripe size="small" style="margin-bottom:12px">
|
||||
<el-table-column prop="key" label="标识" width="100">
|
||||
<template #default="s"><el-input v-model="s.row.key" size="small" /></template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="label" label="名称" width="100">
|
||||
<template #default="s"><el-input v-model="s.row.label" size="small" /></template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="url" label="URL" min-width="180">
|
||||
<template #default="s"><el-input v-model="s.row.url" size="small" /></template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="method" label="方法" width="80">
|
||||
<template #default="s"><el-select v-model="s.row.method" size="small"><el-option label="GET" value="GET" /><el-option label="POST" value="POST" /></el-select></template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="60">
|
||||
<template #default="s"><el-button size="small" type="danger" text @click="editingEntries.splice(s.$index,1)">删除</el-button></template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div style="display:flex;gap:8px">
|
||||
<el-button size="small" @click="editingEntries.push({key:'',label:'',url:'{base}',method:'GET'})">+ 添加入口</el-button>
|
||||
<el-button size="small" type="primary" @click="savePages" :loading="saving">保存</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import api from '../api'
|
||||
|
||||
const loading = ref(false), saving = ref(false), sites = ref([])
|
||||
const editorVisible = ref(false), editorSiteId = ref(''), editorTitle = ref(''), isNewSite = ref(false)
|
||||
const editorData = ref(null), editingEntries = ref([])
|
||||
|
||||
const fmt = (t) => t ? t.substring(0,19).replace('T',' ') : '-'
|
||||
const getEntries = (row) => { try { return JSON.parse(row.entriesJson || '[]') } catch { return [] } }
|
||||
|
||||
const fetchAll = async () => {
|
||||
loading.value = true
|
||||
try { sites.value = (await api.get('/admin/site-pages')).data || [] }
|
||||
catch { ElMessage.error('加载失败') }
|
||||
finally { loading.value = false }
|
||||
}
|
||||
|
||||
const showEditor = (siteId, row) => {
|
||||
editorSiteId.value = siteId
|
||||
isNewSite.value = !siteId
|
||||
if (!siteId) {
|
||||
// 新建:选站点
|
||||
editorTitle.value = '新建页面配置'
|
||||
editorData.value = null
|
||||
editingEntries.value = [{key:'home',label:'首页',url:'{base}',method:'GET'}]
|
||||
editSiteInput.value = ''
|
||||
} else {
|
||||
editorTitle.value = '编辑: ' + siteId
|
||||
editorData.value = row
|
||||
editingEntries.value = JSON.parse(JSON.stringify(getEntries(row)))
|
||||
}
|
||||
editorVisible.value = true
|
||||
}
|
||||
|
||||
const editSiteInput = ref('')
|
||||
|
||||
const savePages = async () => {
|
||||
const sid = editorSiteId.value || editSiteInput.value
|
||||
if (!sid) { ElMessage.warning('请输入站点ID'); return }
|
||||
saving.value = true
|
||||
try {
|
||||
await api.put('/sites/' + sid + '/pages', { entries: editingEntries.value })
|
||||
ElMessage.success('已保存')
|
||||
editorVisible.value = false
|
||||
fetchAll()
|
||||
} catch { ElMessage.error('保存失败') }
|
||||
finally { saving.value = false }
|
||||
}
|
||||
|
||||
const deletePages = async (siteId) => {
|
||||
if (!await ElMessageBox.confirm('确认删除 ' + siteId + ' 的页面配置?', '删除', { type: 'warning', confirmButtonText: '确定' }).catch(() => null)) return
|
||||
try {
|
||||
await api.delete('/admin/site-pages/' + siteId)
|
||||
ElMessage.success('已删除')
|
||||
fetchAll()
|
||||
} catch { ElMessage.error('删除失败') }
|
||||
}
|
||||
|
||||
onMounted(fetchAll)
|
||||
</script>
|
||||
Reference in New Issue
Block a user