feat: 页面配置+风险规则增加站点类型默认模板+读取默认按钮

This commit is contained in:
mediabot-pt
2026-07-05 01:03:03 +08:00
parent f8c55349f4
commit a2b906ffaa
2 changed files with 103 additions and 4 deletions

View File

@@ -1,7 +1,22 @@
<template>
<div>
<h2>风险规则</h2>
<el-card style="margin-top:20px">
<el-card style="margin-top:12px">
<template #header><span style="font-weight:500">站点类型默认模板</span></template>
<div style="display:flex;gap:12px;flex-wrap:wrap">
<div v-for="dt in defaults" :key="dt.type" style="border:1px solid #ebeef5;border-radius:4px;padding:10px 14px;min-width:200px">
<div style="font-weight:500;margin-bottom:4px"><el-tag size="small">{{ dt.type }}</el-tag></div>
<div style="font-size:12px;color:#909399;margin-bottom:8px">{{ dt.ruleCount }} 条规则</div>
<el-popover trigger="click" width="500" placement="bottom">
<pre style="font-size:11px;max-height:300px;overflow:auto">{{ JSON.stringify(dt.rules, null, 2) }}</pre>
<template #reference><el-button size="small">查看</el-button></template>
</el-popover>
</div>
</div>
</el-card>
<el-card style="margin-top:12px">
<div style="margin-bottom:12px;display:flex;gap:8px">
<el-button @click="fetchAll" :loading="loading">刷新</el-button>
</div>
@@ -23,11 +38,12 @@
<el-table-column label="更新时间" width="150">
<template #default="s">{{ fmt(s.row.updatedAt) }}</template>
</el-table-column>
<el-table-column label="操作" width="100" fixed="right">
<el-table-column label="操作" width="180" fixed="right">
<template #default="s">
<el-button size="small" @click="startEdit(s.row)" :type="editSiteId===s.row.siteId?'warning':''">
{{ editSiteId===s.row.siteId ? '收起' : '编辑' }}
</el-button>
<el-button v-if="!s.row.ruleCount" size="small" @click="loadDefaultRules(s.row)">读取默认</el-button>
</template>
</el-table-column>
</el-table>
@@ -76,6 +92,26 @@ const sites = ref([]), rulesMap = ref({})
const editSiteId = ref(''), editSiteType = ref(''), editorMode = ref('table'), editorJson = ref('')
const editingRules = ref([])
const defaultRules = {
nexusphp: [
{type:'KILL', name:'登录间隔超过30天', metric:'daysSinceLastLogin', threshold:30, unit:'DAY', condition:'GT', level:'CRITICAL'},
{type:'RATIO', name:'分享率过低', metric:'shareRatio', threshold:0.3, condition:'LT', level:'CRITICAL', applicable:{daysSinceRegistration:30}},
{type:'TRAFFIC',name:'超过5天无流量', metric:'daysSinceLastTraffic', threshold:5, unit:'DAY', condition:'GT', level:'WARN', applicable:{daysSinceRegistration:30}},
],
mtorrent: [
{type:'KILL', name:'登录过期', metric:'daysSinceLastLogin', threshold:30, unit:'DAY', condition:'GT', level:'CRITICAL'},
],
}
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 => {
const rules = defaultRules[t] || defaultRules['nexusphp'] || []
return {type:t, ruleCount:rules.length, rules}
})
})
const fmt = (t) => t ? (t.substring(0,19)||'').replace('T',' ') : '-'
watch(editorMode, (m) => {
@@ -113,6 +149,15 @@ const fetchAll = async () => {
} finally { loading.value = false }
}
const loadDefaultRules = (row) => {
editSiteId.value = row.siteId
editSiteType.value = row.siteType
editingRules.value = JSON.parse(JSON.stringify(defaultRules[row.siteType] || defaultRules['nexusphp'] || []))
if (editingRules.value.length === 0) editingRules.value.push({type:'KILL',name:'',metric:'',threshold:0,unit:'DAY',condition:'GT',level:'CRITICAL'})
editorMode.value = 'table'
window.scrollTo({top: document.body.scrollHeight, behavior:'smooth'})
}
const startEdit = (row) => {
if (editSiteId.value === row.siteId) { editSiteId.value = ''; return }
editSiteId.value = row.siteId