|
|
@@ -0,0 +1,142 @@
|
|
|
+<template>
|
|
|
+ <el-card class="risk-ip-segments" shadow="never">
|
|
|
+ <div class="header">
|
|
|
+ <h3 class="title">IP封禁说明</h3>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="description">
|
|
|
+ <p>1.屏蔽数据中心</p>
|
|
|
+ <p class="indent">勾选后,如果来访IP属于数据中心类型,将被屏蔽,无法连接。由于IPV4的地址经常调整,任何IP库均无法保证100%的准确度但。但数据中心的IP相对固定,准确度在99.5%以上,请知悉。</p>
|
|
|
+
|
|
|
+ <p>2.每个实例可以设置500组封禁IP(支持IP段)</p>
|
|
|
+ <p class="indent">45.45.45.45/32 (D类地址) 对应45.45.45.45 共涉及1个IP</p>
|
|
|
+ <p class="indent">45.45.45.0/24 (C类地址) 对应45.45.45.xx共涉及256个IP</p>
|
|
|
+ <p class="indent">45.45.0.0/16 (B类地址) 对应45.45.xx.xx共涉及65535个IP</p>
|
|
|
+ <p class="indent">45.0.0.0/8 (A类地址) 对应45.xx.xx.xx共涉及1677万个IP</p>
|
|
|
+ <p class="indent">封禁措施:禁止该IP访问节点,并立刻阻断已建立的连接。</p>
|
|
|
+
|
|
|
+ <p>3.封禁模式</p>
|
|
|
+ <p class="indent">弹窗模式:被封禁IP段的用户会有明确的提示进入黑名单。 静默模式:不做任何提示。</p>
|
|
|
+
|
|
|
+ <p>4.API封禁阈值</p>
|
|
|
+ <p class="indent">每分钟同个IP触发封禁的数值,可通过sp_flg传递高倍值迅速提高数值。</p>
|
|
|
+ <p class="indent">静默模式:不做任何提示。</p>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="divider"></div>
|
|
|
+
|
|
|
+ <el-form class="setting-form" label-position="top">
|
|
|
+ <el-row :gutter="40">
|
|
|
+ <el-col :span="12" v-for="(item, index) in ipSegments" :key="item.id">
|
|
|
+ <el-form-item :label="`封禁IP段(${index + 1})`">
|
|
|
+ <div class="input-with-delete">
|
|
|
+ <el-input v-model="item.value" :placeholder="`封禁段IP(${index + 1})`" />
|
|
|
+ <el-button type="danger" class="btn-delete" @click="handleRemove(index)">
|
|
|
+ ×
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+ <div class="form-actions">
|
|
|
+ <el-button @click="handleAdd">添加IP段</el-button>
|
|
|
+ <el-button type="primary" class="is-gradient" @click="handleUpdate">更新设置</el-button>
|
|
|
+ </div>
|
|
|
+ </el-form>
|
|
|
+ </el-card>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup lang="ts">
|
|
|
+
|
|
|
+const ipSegments = ref([
|
|
|
+ { id: 1, value: '' },
|
|
|
+])
|
|
|
+
|
|
|
+const handleAdd = () => {
|
|
|
+ ipSegments.value.push({ id: Date.now(), value: '' })
|
|
|
+}
|
|
|
+
|
|
|
+const handleRemove = (index: number) => {
|
|
|
+ ipSegments.value.splice(index, 1)
|
|
|
+}
|
|
|
+
|
|
|
+const handleUpdate = () => {
|
|
|
+ console.log('Update settings:', ipSegments.value)
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+.risk-ip-segments {
|
|
|
+ background-color: var(--admin-card-bg);
|
|
|
+ border: 1px solid var(--admin-border-color);
|
|
|
+ border-radius: 8px;
|
|
|
+ color: var(--admin-text-primary);
|
|
|
+
|
|
|
+ :deep(.el-card__body) {
|
|
|
+ padding: 32px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .header {
|
|
|
+ margin-bottom: 24px;
|
|
|
+
|
|
|
+ .title {
|
|
|
+ font-size: 16px;
|
|
|
+ font-weight: 500;
|
|
|
+ margin: 0;
|
|
|
+ color: var(--admin-text-primary);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .description {
|
|
|
+ font-size: 13px;
|
|
|
+ color: var(--admin-text-secondary);
|
|
|
+ line-height: 1.8;
|
|
|
+
|
|
|
+ p {
|
|
|
+ margin: 0 0 4px 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .indent {
|
|
|
+ padding-left: 12px;
|
|
|
+ margin-bottom: 8px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .divider {
|
|
|
+ height: 1px;
|
|
|
+ background-color: var(--admin-border-color);
|
|
|
+ margin: 32px 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .setting-form {
|
|
|
+ :deep(.el-form-item__label) {
|
|
|
+ color: var(--admin-text-secondary);
|
|
|
+ padding-bottom: 8px;
|
|
|
+ font-size: 13px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .input-with-delete {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 12px;
|
|
|
+ width: 100%;
|
|
|
+
|
|
|
+ .btn-delete {
|
|
|
+ padding: 8px 12px;
|
|
|
+ font-size: 18px;
|
|
|
+ line-height: 1;
|
|
|
+ background-color: #f56c6c;
|
|
|
+ border-color: #f56c6c;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .form-actions {
|
|
|
+ display: flex;
|
|
|
+ justify-content: flex-end;
|
|
|
+ gap: 16px;
|
|
|
+ margin-top: 24px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|