Add multi-IP binding modes and deployment guide
This commit is contained in:
@@ -33,7 +33,8 @@ const route = useRoute()
|
||||
const router = useRouter()
|
||||
const form = reactive({
|
||||
id: null,
|
||||
bound_ip: '',
|
||||
binding_mode: 'single',
|
||||
allowed_ips_text: '',
|
||||
})
|
||||
const filters = reactive({
|
||||
token_suffix: '',
|
||||
@@ -170,16 +171,6 @@ function statusText(row) {
|
||||
return isDormant(row) ? '沉寂' : '正常'
|
||||
}
|
||||
|
||||
function ipTypeLabel(boundIp) {
|
||||
if (!boundIp) {
|
||||
return '未知'
|
||||
}
|
||||
if (!boundIp.includes('/')) {
|
||||
return '单个 IP'
|
||||
}
|
||||
return boundIp.endsWith('/32') || boundIp.endsWith('/128') ? '单个 IP' : 'CIDR 网段'
|
||||
}
|
||||
|
||||
function rowClassName({ row }) {
|
||||
if (row.status === 2) {
|
||||
return 'binding-row--banned'
|
||||
@@ -238,18 +229,52 @@ async function searchBindings() {
|
||||
|
||||
function openEdit(row) {
|
||||
form.id = row.id
|
||||
form.bound_ip = row.bound_ip
|
||||
form.binding_mode = row.binding_mode
|
||||
form.allowed_ips_text = (row.allowed_ips || []).join('\n')
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
function normalizeAllowedIpText(value) {
|
||||
return value
|
||||
.split(/[\n,]/)
|
||||
.map((item) => item.trim())
|
||||
.filter(Boolean)
|
||||
}
|
||||
|
||||
function bindingModeLabel(mode) {
|
||||
if (mode === 'all') {
|
||||
return '全部放行'
|
||||
}
|
||||
if (mode === 'multiple') {
|
||||
return '多 IP'
|
||||
}
|
||||
return '单地址'
|
||||
}
|
||||
|
||||
function bindingRuleText(row) {
|
||||
if (row.binding_mode === 'all') {
|
||||
return '全部 IP 放行'
|
||||
}
|
||||
return row.bound_ip
|
||||
}
|
||||
|
||||
async function submitEdit() {
|
||||
if (!form.bound_ip) {
|
||||
ElMessage.warning('请输入 CIDR 或单个 IP。')
|
||||
const allowedIps = normalizeAllowedIpText(form.allowed_ips_text)
|
||||
if (form.binding_mode !== 'all' && !allowedIps.length) {
|
||||
ElMessage.warning('请填写至少一个 IP 或 CIDR。')
|
||||
return
|
||||
}
|
||||
try {
|
||||
await run(() => updateBindingIp({ id: form.id, bound_ip: form.bound_ip }), '更新绑定失败。')
|
||||
ElMessage.success('绑定地址已更新。')
|
||||
await run(
|
||||
() =>
|
||||
updateBindingIp({
|
||||
id: form.id,
|
||||
binding_mode: form.binding_mode,
|
||||
allowed_ips: allowedIps,
|
||||
}),
|
||||
'更新绑定失败。',
|
||||
)
|
||||
ElMessage.success('绑定规则已更新。')
|
||||
dialogVisible.value = false
|
||||
await refreshBindings()
|
||||
} catch {}
|
||||
@@ -297,7 +322,7 @@ watch(
|
||||
<PageHero
|
||||
eyebrow="绑定控制"
|
||||
title="围绕绑定表格完成查询、核对与处置"
|
||||
description="按 Token 尾号或绑定地址快速检索,确认最近活跃时间后直接编辑 CIDR、解绑或封禁。"
|
||||
description="按 Token 尾号或绑定地址快速检索,确认最近活跃时间后直接编辑规则、解绑或封禁。"
|
||||
>
|
||||
<template #aside>
|
||||
<div class="hero-stat-pair">
|
||||
@@ -321,7 +346,7 @@ watch(
|
||||
<div class="binding-head-copy">
|
||||
<p class="eyebrow">绑定列表</p>
|
||||
<h3 class="section-title">聚焦表格本身,减少干扰信息</h3>
|
||||
<p class="muted">页面只保留查询、状态和处置动作,方便快速完成 IP 管理。</p>
|
||||
<p class="muted">支持单地址、多个 IP 与全部放行三种规则,页面只保留高频查询与处置动作。</p>
|
||||
</div>
|
||||
<div class="binding-summary-strip" aria-label="Binding summary">
|
||||
<article class="binding-summary-card">
|
||||
@@ -423,7 +448,7 @@ watch(
|
||||
<el-icon><SwitchButton /></el-icon>
|
||||
当前匹配 {{ formatCompactNumber(total) }} 条绑定
|
||||
</span>
|
||||
<span class="binding-table-note">“沉寂”表示 {{ staleWindowDays }} 天及以上没有请求。</span>
|
||||
<span class="binding-table-note">“沉寂”表示 {{ staleWindowDays }} 天及以上没有请求,规则支持单地址、多 IP 与全部放行。</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -445,10 +470,10 @@ watch(
|
||||
<template #default="{ row }">
|
||||
<div class="binding-ip-cell">
|
||||
<div class="binding-ip-line">
|
||||
<code>{{ row.bound_ip }}</code>
|
||||
<el-button text :icon="CopyDocument" @click="copyValue(row.bound_ip, '绑定地址')">复制</el-button>
|
||||
<code>{{ bindingRuleText(row) }}</code>
|
||||
<el-button text :icon="CopyDocument" @click="copyValue(bindingRuleText(row), '绑定规则')">复制</el-button>
|
||||
</div>
|
||||
<span class="muted">{{ ipTypeLabel(row.bound_ip) }}</span>
|
||||
<span class="muted">{{ bindingModeLabel(row.binding_mode) }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -476,7 +501,7 @@ watch(
|
||||
<el-table-column label="操作" min-width="360" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<div class="binding-action-row">
|
||||
<el-button :icon="EditPen" @click="openEdit(row)">编辑 CIDR</el-button>
|
||||
<el-button :icon="EditPen" @click="openEdit(row)">编辑规则</el-button>
|
||||
<el-button
|
||||
:icon="row.status === 1 ? Lock : Unlock"
|
||||
:type="row.status === 1 ? 'warning' : 'success'"
|
||||
@@ -517,17 +542,47 @@ watch(
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<el-dialog v-model="dialogVisible" title="更新绑定地址" width="420px">
|
||||
<el-dialog v-model="dialogVisible" title="更新绑定规则" width="520px">
|
||||
<el-form label-position="top">
|
||||
<el-form-item label="CIDR 或单个 IP">
|
||||
<el-form-item label="规则模式">
|
||||
<el-radio-group v-model="form.binding_mode" class="binding-mode-group">
|
||||
<el-radio-button value="single">单地址</el-radio-button>
|
||||
<el-radio-button value="multiple">多个 IP</el-radio-button>
|
||||
<el-radio-button value="all">全部放行</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item v-if="form.binding_mode === 'single'" label="IP 或 CIDR">
|
||||
<el-input
|
||||
v-model="form.bound_ip"
|
||||
v-model="form.allowed_ips_text"
|
||||
autocomplete="off"
|
||||
name="bound_ip"
|
||||
placeholder="192.168.1.0/24"
|
||||
@keyup.enter="submitEdit"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item v-else-if="form.binding_mode === 'multiple'" label="多个 IP">
|
||||
<el-input
|
||||
v-model="form.allowed_ips_text"
|
||||
type="textarea"
|
||||
:rows="6"
|
||||
autocomplete="off"
|
||||
name="allowed_ips"
|
||||
placeholder="每行一个 IP,例如 192.168.1.10 192.168.1.11"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-alert
|
||||
v-else
|
||||
type="warning"
|
||||
:closable="false"
|
||||
title="全部放行后,这个 Token 不再校验来源 IP。仅建议在确有必要的内部场景中使用。"
|
||||
/>
|
||||
|
||||
<p class="muted">
|
||||
单地址模式支持单个 IP 或一个 CIDR;多 IP 模式按逐行 IP 精确放行;全部放行表示跳过来源地址校验。
|
||||
</p>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
|
||||
Reference in New Issue
Block a user