feat:IP格式校验
This commit is contained in:
@@ -939,6 +939,9 @@ const local: any = {
|
||||
deletetitle:'Delete',
|
||||
deletebody:'Are you sure you want to delete this record?',
|
||||
ok:'confirm',
|
||||
plenumber:'Please enter a valid number',
|
||||
subnetMask:'Subnet mask must be between 0-32',
|
||||
iperror:'ip is not right'
|
||||
|
||||
},
|
||||
terminal:{
|
||||
|
||||
@@ -940,6 +940,10 @@ const local:any = {
|
||||
deletetitle:'确认删除',
|
||||
deletebody:'确定要删除这条记录吗?',
|
||||
ok:'确认',
|
||||
plenumber:'请输入有效数字',
|
||||
subnetMask:'子网掩码必须在0-32之间',
|
||||
iperror:'ip地址格式不正确'
|
||||
|
||||
},
|
||||
terminal:{
|
||||
title:'终端设备',
|
||||
|
||||
@@ -130,15 +130,48 @@
|
||||
</a-form-item>
|
||||
<a-form-item v-if="addPreAuthType === 1" label="IP">
|
||||
<div style="display: flex; align-items: center; gap: 4px;">
|
||||
<a-input v-model:value="addPreAuthIpParts[0]" style="width: 56px;" :maxlength="3" />
|
||||
<a-input
|
||||
v-model:value="addPreAuthIpParts[0]"
|
||||
style="width: 56px;"
|
||||
:maxlength="3"
|
||||
@input="validateIpPart(0)"
|
||||
placeholder="0-255"
|
||||
/>
|
||||
<span>.</span>
|
||||
<a-input v-model:value="addPreAuthIpParts[1]" style="width: 56px;" :maxlength="3" />
|
||||
<a-input
|
||||
v-model:value="addPreAuthIpParts[1]"
|
||||
style="width: 56px;"
|
||||
:maxlength="3"
|
||||
@input="validateIpPart(1)"
|
||||
placeholder="0-255"
|
||||
/>
|
||||
<span>.</span>
|
||||
<a-input v-model:value="addPreAuthIpParts[2]" style="width: 56px;" :maxlength="3" />
|
||||
<a-input
|
||||
v-model:value="addPreAuthIpParts[2]"
|
||||
style="width: 56px;"
|
||||
:maxlength="3"
|
||||
@input="validateIpPart(2)"
|
||||
placeholder="0-255"
|
||||
/>
|
||||
<span>.</span>
|
||||
<a-input v-model:value="addPreAuthIpParts[3]" style="width: 56px;" :maxlength="3" />
|
||||
<a-input
|
||||
v-model:value="addPreAuthIpParts[3]"
|
||||
style="width: 56px;"
|
||||
:maxlength="3"
|
||||
@input="validateIpPart(3)"
|
||||
placeholder="0-255"
|
||||
/>
|
||||
<span>/</span>
|
||||
<a-input v-model:value="addPreAuthIpParts[4]" style="width: 56px;" :maxlength="2" />
|
||||
<a-input
|
||||
v-model:value="addPreAuthIpParts[4]"
|
||||
style="width: 56px;"
|
||||
:maxlength="2"
|
||||
@input="validateMaskPart"
|
||||
placeholder="0-32"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="ipValidationError" style="color: #ff4d4f; font-size: 12px; margin-top: 4px;">
|
||||
{{ ipValidationError }}
|
||||
</div>
|
||||
</a-form-item>
|
||||
<a-form-item v-if="addPreAuthType === 2" label="URL">
|
||||
@@ -166,13 +199,40 @@
|
||||
</a-form-item>
|
||||
<a-form-item v-if="addFreeClientType === 3" label="IP">
|
||||
<div style="display: flex; align-items: center; gap: 4px;">
|
||||
<a-input v-model:value="addFreeClientIpParts[0]" style="width: 56px;" :maxlength="3" />
|
||||
<a-input
|
||||
v-model:value="addFreeClientIpParts[0]"
|
||||
style="width: 56px;"
|
||||
:maxlength="3"
|
||||
@input="validateFreeClientIpPart(0)"
|
||||
placeholder="0-255"
|
||||
/>
|
||||
<span>.</span>
|
||||
<a-input v-model:value="addFreeClientIpParts[1]" style="width: 56px;" :maxlength="3" />
|
||||
<a-input
|
||||
v-model:value="addFreeClientIpParts[1]"
|
||||
style="width: 56px;"
|
||||
:maxlength="3"
|
||||
@input="validateFreeClientIpPart(1)"
|
||||
placeholder="0-255"
|
||||
/>
|
||||
<span>.</span>
|
||||
<a-input v-model:value="addFreeClientIpParts[2]" style="width: 56px;" :maxlength="3" />
|
||||
<a-input
|
||||
v-model:value="addFreeClientIpParts[2]"
|
||||
style="width: 56px;"
|
||||
:maxlength="3"
|
||||
@input="validateFreeClientIpPart(2)"
|
||||
placeholder="0-255"
|
||||
/>
|
||||
<span>.</span>
|
||||
<a-input v-model:value="addFreeClientIpParts[3]" style="width: 56px;" :maxlength="3" />
|
||||
<a-input
|
||||
v-model:value="addFreeClientIpParts[3]"
|
||||
style="width: 56px;"
|
||||
:maxlength="3"
|
||||
@input="validateFreeClientIpPart(3)"
|
||||
placeholder="0-255"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="freeClientIpValidationError" style="color: #ff4d4f; font-size: 12px; margin-top: 4px;">
|
||||
{{ freeClientIpValidationError }}
|
||||
</div>
|
||||
</a-form-item>
|
||||
<a-form-item v-if="addFreeClientType === 4" label="MAC">
|
||||
@@ -217,12 +277,14 @@ const addPreAuthVisible = ref(false)
|
||||
const addPreAuthType = ref(1) // 1: IP, 2: URL
|
||||
const addPreAuthValue = ref('')
|
||||
const addPreAuthIpParts = ref(['', '', '', '', '']) // [ip1, ip2, ip3, ip4, mask]
|
||||
const ipValidationError = ref('')
|
||||
|
||||
// 新增:添加免认证白名单弹窗相关变量
|
||||
const addFreeClientVisible = ref(false)
|
||||
const addFreeClientType = ref(3) // 3: IP, 4: MAC
|
||||
const addFreeClientIpParts = ref(['', '', '', ''])
|
||||
const addFreeClientMacParts = ref(['', '', '', '', '', ''])
|
||||
const freeClientIpValidationError = ref('')
|
||||
|
||||
// 定义表格列配置
|
||||
const preAuthColumns = [
|
||||
@@ -241,7 +303,10 @@ const preAuthColumns = [
|
||||
dataIndex: 'url',
|
||||
key: 'url',
|
||||
customRender: ({ record }: { record: any }) => {
|
||||
if (record.type === 1) return record.ip
|
||||
if (record.type === 1) {
|
||||
const ipDisplay = record.subnetMask ? `${record.ip}/${record.subnetMask}` : record.ip
|
||||
return ipDisplay
|
||||
}
|
||||
if (record.type === 2) return record.url
|
||||
return '-'
|
||||
}
|
||||
@@ -341,6 +406,7 @@ const getAccessControl = async () => {
|
||||
key: String(item.idInt),
|
||||
type: item.type,
|
||||
ip: item.ip,
|
||||
subnetMask: item.subnetMask,
|
||||
url: item.url,
|
||||
...item
|
||||
}))
|
||||
@@ -368,6 +434,7 @@ const onAddPreAuth = () => {
|
||||
addPreAuthType.value = 1
|
||||
addPreAuthValue.value = ''
|
||||
addPreAuthIpParts.value = ['', '', '', '', '']
|
||||
ipValidationError.value = ''
|
||||
addPreAuthVisible.value = true
|
||||
}
|
||||
|
||||
@@ -376,11 +443,29 @@ const handleAddPreAuthOk = () => {
|
||||
// 拼接IP
|
||||
const ip = addPreAuthIpParts.value.slice(0, 4).join('.')
|
||||
const mask = addPreAuthIpParts.value[4]
|
||||
const ipValue = mask ? `${ip}/${mask}` : ip
|
||||
|
||||
// IP地址格式校验
|
||||
const ipRegex = /\b((?!\d\d\d)\d+|1\d\d|2[0-4]\d|25[0-5])\.((?!\d\d\d)\d+|1\d\d|2[0-4]\d|25[0-5])\.((?!\d\d\d)\d+|1\d\d|2[0-4]\d|25[0-5])\.((?!\d\d\d)\d+|1\d\d|2[0-4]\d|25[0-5])\b/
|
||||
|
||||
if (!ipRegex.test(ip)) {
|
||||
message.error(t('page.access.iperror'))
|
||||
return
|
||||
}
|
||||
|
||||
// 子网掩码校验(如果输入了掩码)
|
||||
if (mask) {
|
||||
const maskNum = parseInt(mask)
|
||||
if (isNaN(maskNum) || maskNum < 0 || maskNum > 32) {
|
||||
message.error(t('page.access.subnetMask'))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
preAuthList.value.push({
|
||||
key: Date.now() + Math.random(), // 简单唯一key
|
||||
type: 1,
|
||||
ip: ipValue,
|
||||
ip: ip,
|
||||
subnetMask: mask || undefined,
|
||||
url: null
|
||||
})
|
||||
} else {
|
||||
@@ -389,6 +474,7 @@ const handleAddPreAuthOk = () => {
|
||||
key: Date.now() + Math.random(),
|
||||
type: 2,
|
||||
ip: null,
|
||||
subnetMask: undefined,
|
||||
url: addPreAuthValue.value
|
||||
})
|
||||
}
|
||||
@@ -399,6 +485,7 @@ const onAddFreeClient = () => {
|
||||
addFreeClientType.value = 3
|
||||
addFreeClientIpParts.value = ['', '', '', '']
|
||||
addFreeClientMacParts.value = ['', '', '', '', '', '']
|
||||
freeClientIpValidationError.value = ''
|
||||
addFreeClientVisible.value = true
|
||||
}
|
||||
|
||||
@@ -406,6 +493,15 @@ const handleAddFreeClientOk = () => {
|
||||
if (addFreeClientType.value === 3) {
|
||||
// 拼接IP
|
||||
const ip = addFreeClientIpParts.value.join('.')
|
||||
|
||||
// IP地址格式校验
|
||||
const ipRegex = /\b((?!\d\d\d)\d+|1\d\d|2[0-4]\d|25[0-5])\.((?!\d\d\d)\d+|1\d\d|2[0-4]\d|25[0-5])\.((?!\d\d\d)\d+|1\d\d|2[0-4]\d|25[0-5])\.((?!\d\d\d)\d+|1\d\d|2[0-4]\d|25[0-5])\b/
|
||||
|
||||
if (!ipRegex.test(ip)) {
|
||||
message.error(t('page.access.iperror'))
|
||||
return
|
||||
}
|
||||
|
||||
freeClientList.value.push({
|
||||
key: Date.now() + Math.random(),
|
||||
type: 3,
|
||||
@@ -470,6 +566,7 @@ const handleApply = async () => {
|
||||
preAuthAccessPolicies: preAuthList.value.map(item => ({
|
||||
type: item.type,
|
||||
ip: item.type === 1 ? item.ip : undefined,
|
||||
subnetMask: item.type === 1 ? item.subnetMask : undefined,
|
||||
url: item.type === 2 ? item.url : undefined
|
||||
})),
|
||||
freeAuthClientPolicies: freeClientList.value.map(item => ({
|
||||
@@ -510,6 +607,63 @@ const handleCancel = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
const validateIpPart = (index: number) => {
|
||||
const value = addPreAuthIpParts.value[index]
|
||||
if (value && !/^\d+$/.test(value)) {
|
||||
ipValidationError.value = t('page.access.plenumber')
|
||||
return
|
||||
}
|
||||
|
||||
if (value) {
|
||||
const num = parseInt(value)
|
||||
if (num < 0 || num > 255) {
|
||||
ipValidationError.value = `IP${index + 1}must between 0-255`
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 清除错误信息
|
||||
ipValidationError.value = ''
|
||||
}
|
||||
|
||||
const validateMaskPart = () => {
|
||||
const value = addPreAuthIpParts.value[4]
|
||||
if (value && !/^\d+$/.test(value)) {
|
||||
ipValidationError.value = t('page.access.plenumber')
|
||||
return
|
||||
}
|
||||
|
||||
if (value) {
|
||||
const num = parseInt(value)
|
||||
if (num < 0 || num > 32) {
|
||||
ipValidationError.value = t('page.access.subnetMask')
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 清除错误信息
|
||||
ipValidationError.value = ''
|
||||
}
|
||||
|
||||
const validateFreeClientIpPart = (index: number) => {
|
||||
const value = addFreeClientIpParts.value[index]
|
||||
if (value && !/^\d+$/.test(value)) {
|
||||
freeClientIpValidationError.value = t('page.access.plenumber')
|
||||
return
|
||||
}
|
||||
|
||||
if (value) {
|
||||
const num = parseInt(value)
|
||||
if (num < 0 || num > 255) {
|
||||
freeClientIpValidationError.value = `IP${index + 1}must in 0-255`
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 清除错误信息
|
||||
freeClientIpValidationError.value = ''
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
console.log('onMounted执行')
|
||||
await getSiteList()
|
||||
|
||||
Reference in New Issue
Block a user