refactor: 站点列表和站点审核拆分为两个独立页面
- Sites.vue: 精简为纯站点列表(编辑/配置/变更) - SiteReview.vue: 新文件,站点审核队列(通过/拒绝/匹配) - router: 新增 /sites/review 路由 - Layout: 导航栏新增「站点审核」菜单项
This commit is contained in:
91
web/src/views/SiteReview.vue
Normal file
91
web/src/views/SiteReview.vue
Normal file
@@ -0,0 +1,91 @@
|
||||
<template>
|
||||
<div>
|
||||
<h2>站点审核</h2>
|
||||
<el-card style="margin-top: 20px" v-if="submissions.length === 0">
|
||||
<div style="text-align:center;padding:40px;color:#909399">暂无待审核提交</div>
|
||||
</el-card>
|
||||
<el-card style="margin-top: 20px" v-else>
|
||||
<el-table :data="submissions" stripe size="small">
|
||||
<el-table-column prop="siteId" label="站点ID" width="120" />
|
||||
<el-table-column label="名称" width="180">
|
||||
<template #default="scope"><div v-for="(n,i) in scope.row.names" :key="i" class="text-xs">{{ n }}</div></template>
|
||||
</el-table-column>
|
||||
<el-table-column label="地址" min-width="200">
|
||||
<template #default="scope"><div v-for="(u,i) in scope.row.urls" :key="i" class="text-xs">{{ u }}</div></template>
|
||||
</el-table-column>
|
||||
<el-table-column label="站点状态" width="90">
|
||||
<template #default="scope">
|
||||
<el-tag size="small" :type="scope.row.siteStatus==='正常'?'success':scope.row.siteStatus==='关停'?'danger':'warning'">{{ scope.row.siteStatus }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="备注" min-width="120">
|
||||
<template #default="scope"><span class="text-xs text-muted">{{ scope.row.notes||'-' }}</span></template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createdAt" label="提交时间" width="160" />
|
||||
<el-table-column label="操作" width="210">
|
||||
<template #default="scope">
|
||||
<el-button size="small" type="success" @click="handleApprove(scope.row)">通过</el-button>
|
||||
<el-button size="small" type="danger" @click="handleReject(scope.row)">拒绝</el-button>
|
||||
<el-button size="small" @click="handleMatch(scope.row)">匹配</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
|
||||
<el-dialog v-model="matchVisible" title="关联到已有站点" width="500px">
|
||||
<el-input v-model="matchQuery" placeholder="搜索站点名称或URL..." clearable @input="handleSearch" style="margin-bottom:12px" />
|
||||
<el-table :data="matchResults" stripe size="small" v-loading="matchSearching" max-height="300" @row-click="handleLinkSite" highlight-current-row>
|
||||
<el-table-column prop="siteId" label="站点ID" width="120" />
|
||||
<el-table-column label="名称" min-width="150"><template #default="scope"><div v-for="(n,i) in scope.row.names" :key="i" class="text-xs">{{ n }}</div></template></el-table-column>
|
||||
<el-table-column label="地址" min-width="150"><template #default="scope"><div v-for="(u,i) in scope.row.urls" :key="i" class="text-xs">{{ u }}</div></template></el-table-column>
|
||||
</el-table>
|
||||
<template #footer><el-button @click="matchVisible = false">取消</el-button></template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import api from '../api'
|
||||
|
||||
const submissions = ref([])
|
||||
const matchVisible = ref(false), matchQuery = ref(''), matchResults = ref([]), matchSearching = ref(false)
|
||||
let matchTargetId = null
|
||||
|
||||
const fetch = async () => {
|
||||
try { const r = await api.sites.pendingChanges(); submissions.value = r.data || [] }
|
||||
catch { ElMessage.error('获取待审核列表失败') }
|
||||
}
|
||||
|
||||
const handleApprove = async (row) => {
|
||||
try { await api.sites.approveChange(row.id); ElMessage.success('已通过'); fetch() }
|
||||
catch (e) { ElMessage.error(e.response?.data?.message||'操作失败') }
|
||||
}
|
||||
|
||||
const handleReject = async (row) => {
|
||||
try {
|
||||
await ElMessageBox.confirm(`确认拒绝 "${(row.names||[])[0]||row.siteId}" 的提交?`, '警告', { type: 'warning' })
|
||||
await api.sites.rejectChange(row.id); ElMessage.success('已拒绝'); fetch()
|
||||
} catch (e) { if (e !== 'cancel') ElMessage.error(e.response?.data?.message||'操作失败') }
|
||||
}
|
||||
|
||||
const handleMatch = (row) => { matchTargetId = row.id; matchQuery.value = (row.names||[])[0]||''; matchVisible.value = true; handleSearch() }
|
||||
|
||||
const handleSearch = async () => {
|
||||
if (!matchQuery.value.trim()) { matchResults.value = []; return }
|
||||
matchSearching.value = true
|
||||
try { const r = await api.sites.search(matchQuery.value.trim()); matchResults.value = r.data||[] }
|
||||
catch { matchResults.value = [] }
|
||||
finally { matchSearching.value = false }
|
||||
}
|
||||
|
||||
const handleLinkSite = async (row) => {
|
||||
try { await api.sites.linkChange(matchTargetId, row.siteId); ElMessage.success(`已关联到 ${row.siteId}`); matchVisible.value = false; fetch() }
|
||||
catch (e) { ElMessage.error(e.response?.data?.message||'关联失败') }
|
||||
}
|
||||
|
||||
onMounted(fetch)
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.text-muted { color: #909399; }
|
||||
</style>
|
||||
Reference in New Issue
Block a user