فهرست منبع

feat(sdk): 添加多开限制与IP封禁组件并调整主题色

- 新增 MultiOpenRestriction 组件用于配置连接数限制
- 新增 RiskIpSegments 组件用于管理IP封禁规则
- 更新 componentMap 以使用新增组件而非SDKDetail占位
- 调整 UsageAnalysis 组件中单选按钮的绑定方式
- 修改主题色中 Success 相关变量为更明亮的色系
piks 3 روز پیش
والد
کامیت
288fe6a02c

+ 12 - 14
src/styles/theme.scss

@@ -18,20 +18,18 @@
   // ---- 暗色(按下/激活:与黑色混合 20%) ----
   --el-color-primary-dark-2: #665fcc;
 
-  // ---- Success 色 ----
-  --el-color-success: #35ffdd;
-  --el-color-success-light-3: #2bb9a1; /* 混合 30% 暗色 */
-  --el-color-success-light-5: #258a79; /* 混合 50% 暗色 (Plain按钮的默认边框色) */
-  --el-color-success-light-7: #1e5b50; /* 混合 70% 暗色 */
-  --el-color-success-light-8: #1b433c; /* 混合 80% 暗色 */
-  --el-color-success-light-9: #172c28; /* 混合 90% 暗色 (Plain按钮的默认背景色) */
-  --el-color-success-light-1: #32e8c9;
-  --el-color-success-light-2: #2ed0b5;
-  --el-color-success-light-4: #28a18d;
-  --el-color-success-light-6: #217264;
-  /* ---- Success 按压色(与纯白 #ffffff 混合产生) ---- */
-  /* 主要用于按钮按下 Active 时的状态反馈 */
-  --el-color-success-dark-2: #5dffe4;
+  // ---- Success 色 (亮色模式) ----
+  --el-color-success: #10b981; // Base: Emerald 500
+  --el-color-success-light-1: #28c08d; // 10%
+  --el-color-success-light-2: #40c799; // 20%
+  --el-color-success-light-3: #58cea6; // 30%
+  --el-color-success-light-4: #70d5b2; // 40%
+  --el-color-success-light-5: #88dcbf; // 50%
+  --el-color-success-light-6: #a0e3cb; // 60%
+  --el-color-success-light-7: #b8ead8; // 70%
+  --el-color-success-light-8: #d0f1e4; // 80%
+  --el-color-success-light-9: #e8f8f1; // 90%
+  --el-color-success-dark-2: #0d9467;  // 20% 混合黑色
 
   // 自定义渐变按钮变量
   --btn-primary-gradient: linear-gradient(91deg, #5f53ff -40.99%, #8d53ff 88.34%);

+ 106 - 0
src/views/sdk/components/MultiOpenRestriction.vue

@@ -0,0 +1,106 @@
+<template>
+  <el-card class="multi-open-restriction" shadow="never">
+    <div class="header">
+      <h3 class="title">限制多开说明</h3>
+    </div>
+
+    <div class="description">
+      <p>开启后游戏盾会在本地进行连接数限制。可抵御传统的修改窗口IP,机器码等方式绕过多开限制。当连接数达到预设上限后,游戏盾会弹出提示并阻止其新建连接。</p>
+      <br />
+      <p>限制模式说明:</p>
+      <p>1、全局模式:限制所有过盾连接的总数(适合多开类型游戏)</p>
+      <p>2、单IP模式:限制对每个本地IP(例127.0.12.10)的连接数上限数量</p>
+      <p>3、规则模式:限制单条转发规则的连接数上限(适合单区类型游戏)</p>
+      <p>4、独立模式:指定单独的盾IP进行限制(适合单窗口多连接的游戏,只限公用的端口)</p>
+      <p>特别注意:部分游戏会同时连接多个端口,可通过火绒或其他TCP查看工具进行溯源。</p>
+    </div>
+
+    <div class="divider"></div>
+
+    <el-form class="setting-form" label-position="top">
+      <el-row :gutter="40">
+        <el-col :span="12">
+          <el-form-item label="限制模式">
+            <el-select v-model="form.mode" placeholder="请选择限制模式" style="width: 100%">
+              <el-option label="全局模式" value="global" />
+              <el-option label="单IP模式" value="single_ip" />
+              <el-option label="规则模式" value="rule" />
+              <el-option label="独立模式" value="independent" />
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="限制数量">
+            <el-input v-model="form.count" type="number" placeholder="0" />
+          </el-form-item>
+        </el-col>
+      </el-row>
+
+      <div class="form-actions">
+        <el-button type="primary" class="is-gradient" @click="handleUpdate">更新设置</el-button>
+      </div>
+    </el-form>
+  </el-card>
+</template>
+
+<script setup lang="ts">
+import { reactive } from 'vue'
+
+const form = reactive({
+  mode: 'global',
+  count: 0
+})
+
+const handleUpdate = () => {
+  console.log('Update settings:', form)
+}
+</script>
+
+<style lang="scss" scoped>
+.multi-open-restriction {
+  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;
+    }
+  }
+
+  .divider {
+    height: 1px;
+    background-color: var(--admin-border-color);
+    margin: 32px 0;
+  }
+
+  .setting-form {
+    .form-actions {
+      display: flex;
+      justify-content: flex-end;
+      margin-top: 24px;
+
+    }
+  }
+}
+</style>

+ 142 - 0
src/views/sdk/components/RiskIpSegments.vue

@@ -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>

+ 6 - 12
src/views/sdk/components/UsageAnalysis.vue

@@ -15,20 +15,14 @@
 
     <div class="filter-bar">
       <el-radio-group v-model="timeRange" class="dark-radio-group">
-        <el-radio-button label="3h">3小时</el-radio-button>
-        <el-radio-button label="12h">12小时</el-radio-button>
-        <el-radio-button label="1d">1天</el-radio-button>
-        <el-radio-button label="7d">7天</el-radio-button>
+        <el-radio-button value="3h">3小时</el-radio-button>
+        <el-radio-button value="12h">12小时</el-radio-button>
+        <el-radio-button value="1d">1天</el-radio-button>
+        <el-radio-button value="7d">7天</el-radio-button>
       </el-radio-group>
 
-      <el-date-picker
-        v-model="dateRange"
-        type="datetimerange"
-        range-separator="至"
-        start-placeholder="开始日期"
-        end-placeholder="结束日期"
-        class="dark-date-picker"
-      />
+      <el-date-picker v-model="dateRange" type="datetimerange" range-separator="至" start-placeholder="开始日期"
+        end-placeholder="结束日期" class="dark-date-picker" />
     </div>
 
     <div class="charts-wrapper">

+ 4 - 2
src/views/sdk/detail.vue

@@ -18,14 +18,16 @@ import ForwardRules from './components/ForwardRules.vue'
 import SDKDetail from './components/SDKDetail.vue'
 import ConnectionList from './components/ConnectionList.vue'
 import UsageAnalysis from './components/UsageAnalysis.vue'
+import MultiOpenRestriction from './components/MultiOpenRestriction.vue'
+import RiskIpSegments from './components/RiskIpSegments.vue'
 
 const componentMap = {
   sdkDetail: SDKDetail,
   forwardRules: ForwardRules,
   connectionList: ConnectionList,
   usageAnalysis: UsageAnalysis,
-  multiOpenRestriction: SDKDetail,
-  riskIpSegments: SDKDetail,
+  multiOpenRestriction: MultiOpenRestriction,
+  riskIpSegments: RiskIpSegments,
   blockedIpSegments: SDKDetail,
   generateSdk: SDKDetail,
 }