feat: add EXEMPT type for rank-based immunity rules
- Opposite of kill rules: protects users instead of deleting them - permRank: users at/above this rank permanently immune from all cleanups - sealExemptRank: users at/above this rank won't be killed when sealed - Green left border + green '\u4fdd\u53f7' label to visually distinguish from kill rules - Template: Elite User for perm, Power User for seal exemption
This commit is contained in:
@@ -76,6 +76,7 @@
|
||||
<div v-if="parsed.length" style="display:flex;flex-direction:column;gap:10px">
|
||||
<div v-for="(rule, idx) in parsed" :key="idx"
|
||||
class="rule-card"
|
||||
:style="rule.type==='EXEMPT'?'border-left-color:#67c23a':''"
|
||||
:draggable="true"
|
||||
@dragstart="onDragStart($event, idx)"
|
||||
@dragover.prevent="onDragOver($event, idx)"
|
||||
@@ -91,9 +92,10 @@
|
||||
</el-select>
|
||||
<span v-if="rule.type==='TASK'" class="rule-fixed-text">考核周期 {{ rule.threshold }}天</span>
|
||||
<span v-else-if="rule.type==='DRATIO'" class="rule-fixed-text">下载量 ≥ {{ rule.threshold }}GB 时分享率 ≥ {{ rule.minRatio }}</span>
|
||||
<span v-else-if="rule.type==='EXEMPT'" class="rule-fixed-text">永久保留 ≥ {{ rule.permRank || '—' }} / 封存豁免 ≥ {{ rule.sealExemptRank || '—' }}</span>
|
||||
<span v-else class="rule-fixed-text">{{ metricLabel(rule.metric) }} {{ condLabel(rule.condition) }} {{ rule.threshold }}{{ rule.unit || '' }}</span>
|
||||
<span class="then-arrow">→</span>
|
||||
<span style="color:#f56c6c;font-weight:600;font-size:13px">封号/删除账号</span>
|
||||
<span class="then-arrow" :style="rule.type==='EXEMPT'?'color:#67c23a':''">→</span>
|
||||
<span :style="rule.type==='EXEMPT'?'color:#67c23a;font-weight:600;font-size:13px':'color:#f56c6c;font-weight:600;font-size:13px'">{{ rule.type==='EXEMPT' ? '保号' : '封号/删除账号' }}</span>
|
||||
</div>
|
||||
<div class="card-header-right">
|
||||
<span class="rule-index">#{{ idx + 1 }}</span>
|
||||
@@ -137,6 +139,20 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- EXEMPT 等级豁免 -->
|
||||
<template v-else-if="rule.type==='EXEMPT'">
|
||||
<div class="field-row">
|
||||
<span class="field-label">永久保留等级</span>
|
||||
<el-input v-model="rule.permRank" size="small" placeholder="如:Elite User" @input="sync" style="width:200px" />
|
||||
<span class="field-hint">该等级及以上用户永久保留,不受任何清理规则影响</span>
|
||||
</div>
|
||||
<div class="field-row">
|
||||
<span class="field-label">封存豁免等级</span>
|
||||
<el-input v-model="rule.sealExemptRank" size="small" placeholder="如:Power User" @input="sync" style="width:200px" />
|
||||
<span class="field-hint">该等级及以上用户封存后不会被删除</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 非 TASK:普通规则 -->
|
||||
<template v-else>
|
||||
<div class="field-row">
|
||||
@@ -163,7 +179,7 @@
|
||||
<!-- 预设规则导入对话框 -->
|
||||
<el-dialog v-model="showPresets" title="PT 站点管理规则模板" width="700px" :close-on-click-modal="false">
|
||||
<div style="margin-bottom:12px;padding:10px 14px;background:#f0f9ff;border-radius:6px;font-size:13px;color:#606266">
|
||||
<p style="margin:0 0 4px;font-weight:500">规则体系:等级豁免 → 账号存活 → 流量监控 → H&R 惩罚 → 分享率检查</p>
|
||||
<p style="margin:0 0 4px;font-weight:500">规则体系:等级豁免 → 账号存活 → 新人考核 → 流量监控 → H&R 惩罚 → 分享率</p>
|
||||
<p style="margin:0;font-size:12px;color:#909399">满足豁免条件的用户不受任何规则影响。系统会自动根据风险百分比触发告警(riskPct > 80%)。</p>
|
||||
</div>
|
||||
<div v-for="cat in presetCategories" :key="cat.title" style="margin-bottom:12px">
|
||||
@@ -174,7 +190,7 @@
|
||||
<el-checkbox :value="p.name" :label="p.name" style="margin-right:0;height:auto">
|
||||
<span style="font-weight:500;font-size:13px">{{ p.name }}</span>
|
||||
</el-checkbox>
|
||||
<span style="color:#f56c6c;font-size:11px;font-weight:500">封号</span>
|
||||
<span :style="p.type==='EXEMPT'?'color:#67c23a;font-size:11px;font-weight:500':'color:#f56c6c;font-size:11px;font-weight:500'">{{ p.type==='EXEMPT' ? '保号' : '封号' }}</span>
|
||||
<span style="color:#909399;font-size:11px;flex:1">{{ presetDesc(p) }}</span>
|
||||
</div>
|
||||
</el-checkbox-group>
|
||||
@@ -200,6 +216,7 @@ const typeOptions = [
|
||||
{ value: 'RATIO', label: '分享率' },
|
||||
{ value: 'TASK', label: '新人考核' },
|
||||
{ value: 'DRATIO', label: '动态分享率' },
|
||||
{ value: 'EXEMPT', label: '等级豁免' },
|
||||
]
|
||||
const condOptions = [
|
||||
{ value: 'GT', label: '大于' },
|
||||
@@ -257,6 +274,9 @@ const onTypeChange = (rule) => {
|
||||
rule.threshold = rule.threshold || 100
|
||||
rule.minRatio = rule.minRatio || 1.0
|
||||
rule.unit = 'GB'
|
||||
} else if (rule.type === 'EXEMPT') {
|
||||
rule.permRank = rule.permRank || ''
|
||||
rule.sealExemptRank = rule.sealExemptRank || ''
|
||||
} else {
|
||||
const d = typeDefaults[rule.type]
|
||||
if (d) { rule.metric = d.metric; rule.condition = d.condition; rule.unit = d.unit }
|
||||
@@ -281,6 +301,8 @@ const presets = [
|
||||
{ name:'新人考核', type:'TASK', threshold:30, unit:'天', description:'新注册用户需在考核周期内完成各项要求' },
|
||||
// 动态分享率
|
||||
{ name:'动态分享率', type:'DRATIO', threshold:100, minRatio:1.0, unit:'GB', description:'下载量达到阈值时分享率不低于要求值' },
|
||||
// 等级豁免
|
||||
{ name:'等级豁免', type:'EXEMPT', permRank:'Elite User', sealExemptRank:'Power User', description:'达到等级的账号可豁免清理' },
|
||||
]
|
||||
|
||||
const presetCategories = [
|
||||
@@ -290,11 +312,13 @@ const presetCategories = [
|
||||
{ title:'H&R 惩罚', items: presets.filter(p => p.type === 'HD') },
|
||||
{ title:'新人考核', items: presets.filter(p => p.type === 'TASK') },
|
||||
{ title:'分享率', items: presets.filter(p => p.type === 'DRATIO') },
|
||||
{ title:'等级豁免', items: presets.filter(p => p.type === 'EXEMPT') },
|
||||
]
|
||||
|
||||
const presetDesc = (p) => {
|
||||
if (p.type === 'TASK') return `考核周期 ${p.threshold||30} 天,需满足上传/下载/魔力值/做种积分/做种时间要求`
|
||||
if (p.type === 'DRATIO') return `下载量 ≥ ${p.threshold||100}GB 时分享率 ≥ ${p.minRatio||1.0}`
|
||||
if (p.type === 'EXEMPT') return `永久保留 ≥ ${p.permRank||'—'} / 封存豁免 ≥ ${p.sealExemptRank||'—'}`
|
||||
const condLabel = condOptions.find(c => c.value === p.condition)?.label || p.condition
|
||||
const appLabel = applicableOptions.find(a => a.value === p.applicable)?.label || ''
|
||||
return `${metricOptions.find(m=>m.value===p.metric)?.label||p.metric} ${condLabel} ${p.threshold}${p.unit||''}${appLabel?' ('+appLabel+')':''}`
|
||||
|
||||
Reference in New Issue
Block a user