diff --git a/src/locales/langs/en-us.ts b/src/locales/langs/en-us.ts index 093ea82..165ae33 100644 --- a/src/locales/langs/en-us.ts +++ b/src/locales/langs/en-us.ts @@ -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:{ diff --git a/src/locales/langs/zh-cn.ts b/src/locales/langs/zh-cn.ts index ffbb592..589df38 100644 --- a/src/locales/langs/zh-cn.ts +++ b/src/locales/langs/zh-cn.ts @@ -940,6 +940,10 @@ const local:any = { deletetitle:'确认删除', deletebody:'确定要删除这条记录吗?', ok:'确认', + plenumber:'请输入有效数字', + subnetMask:'子网掩码必须在0-32之间', + iperror:'ip地址格式不正确' + }, terminal:{ title:'终端设备', diff --git a/src/views/device/access/index.vue b/src/views/device/access/index.vue index 9ab90e3..9898174 100644 --- a/src/views/device/access/index.vue +++ b/src/views/device/access/index.vue @@ -130,15 +130,48 @@
- + . - + . - + . - + / - + +
+
+ {{ ipValidationError }}
@@ -166,13 +199,40 @@
- + . - + . - + . - + +
+
+ {{ freeClientIpValidationError }}
@@ -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()