feat:白名单界面
This commit is contained in:
523
src/views/device/access/index.vue
Normal file
523
src/views/device/access/index.vue
Normal file
@@ -0,0 +1,523 @@
|
|||||||
|
<template>
|
||||||
|
<SimpleScrollbar>
|
||||||
|
<a-card
|
||||||
|
:bordered="false"
|
||||||
|
style="box-shadow: 0 2px 8px #f0f1f2; border-radius: 8px; padding: 0 24px; margin: 24px;"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<!-- 标题 -->
|
||||||
|
<h2 style="font-weight: bold; font-size: 22px; margin-bottom: 8px;">Access Control</h2>
|
||||||
|
<!-- 站点选择框 -->
|
||||||
|
<div style="display: flex; align-items: center; margin-bottom: 24px;">
|
||||||
|
<a-select
|
||||||
|
v-model:value="selectedSiteId"
|
||||||
|
:loading="siteLoading"
|
||||||
|
placeholder="请选择站点"
|
||||||
|
style="width: 200px; margin-right: 16px;"
|
||||||
|
@change="handleSiteChange"
|
||||||
|
>
|
||||||
|
<a-select-option v-for="site in siteList" :key="site.siteId" :value="site.siteId">
|
||||||
|
{{ site.name }}
|
||||||
|
</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Pre-Authentication Access -->
|
||||||
|
<div style="margin-bottom: 16px; display: flex; align-items: center; gap: 12px;">
|
||||||
|
<span>Pre-Authentication Access</span>
|
||||||
|
<a-switch v-model:checked="preAuthEnabled" />
|
||||||
|
<span>Enable</span>
|
||||||
|
<a-tooltip title="Pre-Authentication Access 说明">
|
||||||
|
<i class="anticon anticon-info-circle" style="color: #13c2c2; margin-left: 4px;"></i>
|
||||||
|
</a-tooltip>
|
||||||
|
</div>
|
||||||
|
<div v-if="preAuthEnabled">
|
||||||
|
<div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px;">
|
||||||
|
<span>Pre-Authentication Access List</span>
|
||||||
|
<a-button type="link" style="color: #13c2c2; font-weight: bold;" @click="onAddPreAuth"><i class="anticon anticon-plus-circle" /> Add</a-button>
|
||||||
|
</div>
|
||||||
|
<a-table
|
||||||
|
:columns="preAuthColumns"
|
||||||
|
:dataSource="preAuthList"
|
||||||
|
:pagination="false"
|
||||||
|
bordered
|
||||||
|
size="middle"
|
||||||
|
rowKey="key"
|
||||||
|
>
|
||||||
|
<template #bodyCell="{ column, record }">
|
||||||
|
<template v-if="column.key === 'action'">
|
||||||
|
<a-tooltip title="删除">
|
||||||
|
<a-button
|
||||||
|
type="link"
|
||||||
|
size="small"
|
||||||
|
style="color: #ff4d4f"
|
||||||
|
@click="() => handleDeletePreAuth(record)"
|
||||||
|
>
|
||||||
|
<template #icon>
|
||||||
|
<DeleteOutlined />
|
||||||
|
</template>
|
||||||
|
</a-button>
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</a-table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Authentication-Free Client -->
|
||||||
|
<div style="margin: 32px 0 16px 0; display: flex; align-items: center; gap: 12px;">
|
||||||
|
<span>Authentication-Free Client</span>
|
||||||
|
<a-switch v-model:checked="freeClientEnabled" />
|
||||||
|
<span>Enable</span>
|
||||||
|
<a-tooltip title="Authentication-Free Client 说明">
|
||||||
|
<i class="anticon anticon-info-circle" style="color: #13c2c2; margin-left: 4px;"></i>
|
||||||
|
</a-tooltip>
|
||||||
|
</div>
|
||||||
|
<div v-if="freeClientEnabled">
|
||||||
|
<div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px;">
|
||||||
|
<span>Authentication-Free Client List</span>
|
||||||
|
<a-button type="link" style="color: #13c2c2; font-weight: bold;" @click="onAddFreeClient"><i class="anticon anticon-plus-circle" /> Add</a-button>
|
||||||
|
</div>
|
||||||
|
<a-table
|
||||||
|
:columns="freeClientColumns"
|
||||||
|
:dataSource="freeClientList"
|
||||||
|
:pagination="false"
|
||||||
|
bordered
|
||||||
|
size="middle"
|
||||||
|
rowKey="key"
|
||||||
|
>
|
||||||
|
<template #bodyCell="{ column, record }">
|
||||||
|
<template v-if="column.key === 'action'">
|
||||||
|
<a-tooltip title="删除">
|
||||||
|
<a-button
|
||||||
|
type="link"
|
||||||
|
size="small"
|
||||||
|
style="color: #ff4d4f"
|
||||||
|
@click="() => handleDeleteFreeClient(record)"
|
||||||
|
>
|
||||||
|
<template #icon>
|
||||||
|
<DeleteOutlined />
|
||||||
|
</template>
|
||||||
|
</a-button>
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</a-table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 操作按钮 -->
|
||||||
|
<div style="margin-top: 32px; display: flex; gap: 16px;">
|
||||||
|
<a-button type="primary" @click="handleApply">Apply</a-button>
|
||||||
|
<a-button @click="handleCancel">Cancel</a-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a-card>
|
||||||
|
<!-- 新增:添加预认证白名单弹窗 -->
|
||||||
|
<a-modal
|
||||||
|
v-model:visible="addPreAuthVisible"
|
||||||
|
title="Add Pre-Authentication Access"
|
||||||
|
@ok="handleAddPreAuthOk"
|
||||||
|
@cancel="() => addPreAuthVisible = false"
|
||||||
|
destroyOnClose
|
||||||
|
>
|
||||||
|
<a-form layout="vertical">
|
||||||
|
<a-form-item label="TYPE">
|
||||||
|
<a-select v-model:value="addPreAuthType" style="width: 100%;">
|
||||||
|
<a-select-option :value="1">IP</a-select-option>
|
||||||
|
<a-select-option :value="2">URL</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
</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" />
|
||||||
|
<span>.</span>
|
||||||
|
<a-input v-model:value="addPreAuthIpParts[1]" style="width: 56px;" :maxlength="3" />
|
||||||
|
<span>.</span>
|
||||||
|
<a-input v-model:value="addPreAuthIpParts[2]" style="width: 56px;" :maxlength="3" />
|
||||||
|
<span>.</span>
|
||||||
|
<a-input v-model:value="addPreAuthIpParts[3]" style="width: 56px;" :maxlength="3" />
|
||||||
|
<span>/</span>
|
||||||
|
<a-input v-model:value="addPreAuthIpParts[4]" style="width: 56px;" :maxlength="2" />
|
||||||
|
</div>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item v-if="addPreAuthType === 2" label="URL">
|
||||||
|
<a-input-group compact>
|
||||||
|
<span style="display: inline-block; width: 90px; text-align: center; background: #f5f5f5; border: 1px solid #d9d9d9; border-right: none; border-radius: 6px 0 0 6px; line-height: 32px;">http(s)://</span>
|
||||||
|
<a-input v-model:value="addPreAuthValue" style="width: calc(100% - 90px); border-radius: 0 6px 6px 0;" placeholder="请输入URL" />
|
||||||
|
</a-input-group>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</a-modal>
|
||||||
|
<!-- 新增:添加免认证白名单弹窗 -->
|
||||||
|
<a-modal
|
||||||
|
v-model:visible="addFreeClientVisible"
|
||||||
|
title="Add Authentication-Free Client"
|
||||||
|
@ok="handleAddFreeClientOk"
|
||||||
|
@cancel="() => addFreeClientVisible = false"
|
||||||
|
destroyOnClose
|
||||||
|
>
|
||||||
|
<a-form layout="vertical">
|
||||||
|
<a-form-item label="TYPE">
|
||||||
|
<a-select v-model:value="addFreeClientType" style="width: 100%;">
|
||||||
|
<a-select-option :value="3">IP</a-select-option>
|
||||||
|
<a-select-option :value="4">MAC</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
</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" />
|
||||||
|
<span>.</span>
|
||||||
|
<a-input v-model:value="addFreeClientIpParts[1]" style="width: 56px;" :maxlength="3" />
|
||||||
|
<span>.</span>
|
||||||
|
<a-input v-model:value="addFreeClientIpParts[2]" style="width: 56px;" :maxlength="3" />
|
||||||
|
<span>.</span>
|
||||||
|
<a-input v-model:value="addFreeClientIpParts[3]" style="width: 56px;" :maxlength="3" />
|
||||||
|
</div>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item v-if="addFreeClientType === 4" label="MAC">
|
||||||
|
<div style="display: flex; align-items: center; gap: 4px;">
|
||||||
|
<a-input v-model:value="addFreeClientMacParts[0]" style="width: 40px;" :maxlength="2" />
|
||||||
|
<span>-</span>
|
||||||
|
<a-input v-model:value="addFreeClientMacParts[1]" style="width: 40px;" :maxlength="2" />
|
||||||
|
<span>-</span>
|
||||||
|
<a-input v-model:value="addFreeClientMacParts[2]" style="width: 40px;" :maxlength="2" />
|
||||||
|
<span>-</span>
|
||||||
|
<a-input v-model:value="addFreeClientMacParts[3]" style="width: 40px;" :maxlength="2" />
|
||||||
|
<span>-</span>
|
||||||
|
<a-input v-model:value="addFreeClientMacParts[4]" style="width: 40px;" :maxlength="2" />
|
||||||
|
<span>-</span>
|
||||||
|
<a-input v-model:value="addFreeClientMacParts[5]" style="width: 40px;" :maxlength="2" />
|
||||||
|
</div>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</a-modal>
|
||||||
|
</SimpleScrollbar>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, onMounted, watch, h } from 'vue'
|
||||||
|
import { fetchSiteList, fetchAccessControl, updateAccessControl } from '@/service/api/auth'
|
||||||
|
import { DeleteOutlined } from '@ant-design/icons-vue'
|
||||||
|
import { message, Modal } from 'ant-design-vue'
|
||||||
|
import { SimpleScrollbar } from '~/packages/materials/src';
|
||||||
|
const preAuthEnabled = ref(true)
|
||||||
|
const freeClientEnabled = ref(true)
|
||||||
|
const preAuthList = ref([]) // 预认证白名单列表
|
||||||
|
const freeClientList = ref([]) // 免认证白名单列表
|
||||||
|
|
||||||
|
const siteList = ref<{ siteId: string, name: string }[]>([])
|
||||||
|
const selectedSiteId = ref('')
|
||||||
|
const siteLoading = ref(false)
|
||||||
|
|
||||||
|
// 新增:添加预认证白名单弹窗相关变量
|
||||||
|
const addPreAuthVisible = ref(false)
|
||||||
|
const addPreAuthType = ref(1) // 1: IP, 2: URL
|
||||||
|
const addPreAuthValue = ref('')
|
||||||
|
const addPreAuthIpParts = ref(['', '', '', '', '']) // [ip1, ip2, ip3, ip4, mask]
|
||||||
|
|
||||||
|
// 新增:添加免认证白名单弹窗相关变量
|
||||||
|
const addFreeClientVisible = ref(false)
|
||||||
|
const addFreeClientType = ref(3) // 3: IP, 4: MAC
|
||||||
|
const addFreeClientIpParts = ref(['', '', '', ''])
|
||||||
|
const addFreeClientMacParts = ref(['', '', '', '', '', ''])
|
||||||
|
|
||||||
|
// 定义表格列配置
|
||||||
|
const preAuthColumns = [
|
||||||
|
{
|
||||||
|
title: 'TYPE',
|
||||||
|
dataIndex: 'type',
|
||||||
|
key: 'type',
|
||||||
|
customRender: ({ record }: { record: any }) => {
|
||||||
|
if (record.type === 1) return 'IP'
|
||||||
|
if (record.type === 2) return 'URL'
|
||||||
|
return record.type
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'INFORMATION',
|
||||||
|
dataIndex: 'url',
|
||||||
|
key: 'url',
|
||||||
|
customRender: ({ record }: { record: any }) => {
|
||||||
|
if (record.type === 1) return record.ip
|
||||||
|
if (record.type === 2) return record.url
|
||||||
|
return '-'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'ACTION',
|
||||||
|
key: 'action',
|
||||||
|
width: 120,
|
||||||
|
fixed: 'right',
|
||||||
|
align: 'center',
|
||||||
|
customRender: ({ record }: { record: any }) => {
|
||||||
|
return h(
|
||||||
|
'a-button',
|
||||||
|
{
|
||||||
|
type: 'link',
|
||||||
|
size: 'small',
|
||||||
|
style: { color: '#ff4d4f' },
|
||||||
|
onClick: () => handleDeletePreAuth(record)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: () => h(DeleteOutlined)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const freeClientColumns = [
|
||||||
|
{
|
||||||
|
title: 'TYPE',
|
||||||
|
dataIndex: 'type',
|
||||||
|
key: 'type',
|
||||||
|
customRender: ({ record }: { record: any }) => {
|
||||||
|
if (record.type === 3) return 'IP'
|
||||||
|
if (record.type === 4) return 'MAC'
|
||||||
|
return record.type
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'INFORMATION',
|
||||||
|
dataIndex: 'clientIp',
|
||||||
|
key: 'clientIp',
|
||||||
|
customRender: ({ record }: { record: any }) => {
|
||||||
|
if (record.type === 3) return record.clientIp
|
||||||
|
if (record.type === 4) return record.clientMac
|
||||||
|
return '-'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'ACTION',
|
||||||
|
key: 'action',
|
||||||
|
width: 120,
|
||||||
|
fixed: 'right',
|
||||||
|
align: 'center',
|
||||||
|
customRender: ({ record }: { record: any }) => {
|
||||||
|
return h(
|
||||||
|
'a-button',
|
||||||
|
{
|
||||||
|
type: 'link',
|
||||||
|
size: 'small',
|
||||||
|
style: { color: '#ff4d4f' },
|
||||||
|
onClick: () => handleDeleteFreeClient(record)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: () => h(DeleteOutlined)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const getSiteList = async () => {
|
||||||
|
siteLoading.value = true
|
||||||
|
const { data, error } = await fetchSiteList({ pageNum: 1, pageSize: 100 })
|
||||||
|
console.log('siteList接口返回', data, error)
|
||||||
|
if (!error) {
|
||||||
|
siteList.value = data.rows || []
|
||||||
|
console.log('siteList.value', siteList.value)
|
||||||
|
if (siteList.value.length > 0) {
|
||||||
|
selectedSiteId.value = siteList.value[0].siteId
|
||||||
|
console.log('getSiteList设置selectedSiteId', selectedSiteId.value)
|
||||||
|
await getAccessControl()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
siteLoading.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
const getAccessControl = async () => {
|
||||||
|
console.log('getAccessControl调用,selectedSiteId', selectedSiteId.value)
|
||||||
|
if (!selectedSiteId.value) return
|
||||||
|
const { data, error } = await fetchAccessControl(selectedSiteId.value)
|
||||||
|
console.log('accessControl接口返回', data, error)
|
||||||
|
if (!error && data) {
|
||||||
|
preAuthEnabled.value = !!data.preAuthAccessEnable
|
||||||
|
freeClientEnabled.value = !!data.freeAuthClientEnable
|
||||||
|
preAuthList.value = (data.preAuthAccessPolicies || []).map((item: any) => ({
|
||||||
|
key: String(item.idInt),
|
||||||
|
type: item.type,
|
||||||
|
ip: item.ip,
|
||||||
|
url: item.url,
|
||||||
|
...item
|
||||||
|
}))
|
||||||
|
freeClientList.value = (data.freeAuthClientPolicies || []).map((item: any) => ({
|
||||||
|
key: String(item.idInt),
|
||||||
|
type: item.type,
|
||||||
|
clientIp: item.clientIp,
|
||||||
|
clientMac: item.clientMac,
|
||||||
|
...item
|
||||||
|
}))
|
||||||
|
console.log('preAuthList', preAuthList.value)
|
||||||
|
console.log('freeClientList', freeClientList.value)
|
||||||
|
} else {
|
||||||
|
console.log('getAccessControl未进入赋值分支', { error, data })
|
||||||
|
}
|
||||||
|
console.log('getAccessControl结束', preAuthList.value, freeClientList.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSiteChange = async (value: string) => {
|
||||||
|
selectedSiteId.value = value
|
||||||
|
// 不需要手动调用 getAccessControl,watch 会自动触发
|
||||||
|
}
|
||||||
|
|
||||||
|
const onAddPreAuth = () => {
|
||||||
|
addPreAuthType.value = 1
|
||||||
|
addPreAuthValue.value = ''
|
||||||
|
addPreAuthIpParts.value = ['', '', '', '', '']
|
||||||
|
addPreAuthVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleAddPreAuthOk = () => {
|
||||||
|
if (addPreAuthType.value === 1) {
|
||||||
|
// 拼接IP
|
||||||
|
const ip = addPreAuthIpParts.value.slice(0, 4).join('.')
|
||||||
|
const mask = addPreAuthIpParts.value[4]
|
||||||
|
const ipValue = mask ? `${ip}/${mask}` : ip
|
||||||
|
preAuthList.value.push({
|
||||||
|
key: Date.now() + Math.random(), // 简单唯一key
|
||||||
|
type: 1,
|
||||||
|
ip: ipValue,
|
||||||
|
url: null
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// 只保存输入框内容,不带http(s)://
|
||||||
|
preAuthList.value.push({
|
||||||
|
key: Date.now() + Math.random(),
|
||||||
|
type: 2,
|
||||||
|
ip: null,
|
||||||
|
url: addPreAuthValue.value
|
||||||
|
})
|
||||||
|
}
|
||||||
|
addPreAuthVisible.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
const onAddFreeClient = () => {
|
||||||
|
addFreeClientType.value = 3
|
||||||
|
addFreeClientIpParts.value = ['', '', '', '']
|
||||||
|
addFreeClientMacParts.value = ['', '', '', '', '', '']
|
||||||
|
addFreeClientVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleAddFreeClientOk = () => {
|
||||||
|
if (addFreeClientType.value === 3) {
|
||||||
|
// 拼接IP
|
||||||
|
const ip = addFreeClientIpParts.value.join('.')
|
||||||
|
freeClientList.value.push({
|
||||||
|
key: Date.now() + Math.random(),
|
||||||
|
type: 3,
|
||||||
|
clientIp: ip,
|
||||||
|
clientMac: null
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// 拼接MAC
|
||||||
|
const mac = addFreeClientMacParts.value.map(x => x.padStart(2, '0')).join('-')
|
||||||
|
freeClientList.value.push({
|
||||||
|
key: Date.now() + Math.random(),
|
||||||
|
type: 4,
|
||||||
|
clientIp: null,
|
||||||
|
clientMac: mac
|
||||||
|
})
|
||||||
|
}
|
||||||
|
addFreeClientVisible.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleDeletePreAuth = (record: any) => {
|
||||||
|
Modal.confirm({
|
||||||
|
title: '确认删除',
|
||||||
|
content: '确定要删除该条记录吗?',
|
||||||
|
okText: '确认',
|
||||||
|
cancelText: '取消',
|
||||||
|
onOk: () => {
|
||||||
|
preAuthList.value = preAuthList.value.filter(item => item.key !== record.key)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleDeleteFreeClient = (record: any) => {
|
||||||
|
Modal.confirm({
|
||||||
|
title: '确认删除',
|
||||||
|
content: '确定要删除该条记录吗?',
|
||||||
|
okText: '确认',
|
||||||
|
cancelText: '取消',
|
||||||
|
onOk: () => {
|
||||||
|
freeClientList.value = freeClientList.value.filter(item => item.key !== record.key)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听 selectedSiteId,变化时自动拉取白名单数据
|
||||||
|
watch(selectedSiteId, (val) => {
|
||||||
|
console.log('watch触发,selectedSiteId变为', val)
|
||||||
|
if (val) getAccessControl()
|
||||||
|
})
|
||||||
|
|
||||||
|
// 在 script setup 中添加提交函数
|
||||||
|
const handleApply = async () => {
|
||||||
|
if (!selectedSiteId.value) {
|
||||||
|
message.warning('请先选择站点')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 组装提交数据
|
||||||
|
const submitData = {
|
||||||
|
preAuthAccessEnable: preAuthEnabled.value,
|
||||||
|
freeAuthClientEnable: freeClientEnabled.value,
|
||||||
|
preAuthAccessPolicies: preAuthList.value.map(item => ({
|
||||||
|
type: item.type,
|
||||||
|
ip: item.type === 1 ? item.ip : undefined,
|
||||||
|
url: item.type === 2 ? item.url : undefined
|
||||||
|
})),
|
||||||
|
freeAuthClientPolicies: freeClientList.value.map(item => ({
|
||||||
|
type: item.type,
|
||||||
|
clientIp: item.type === 3 ? item.clientIp : undefined,
|
||||||
|
clientMac: item.type === 4 ? item.clientMac : undefined
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 调用更新接口
|
||||||
|
const { error } = await updateAccessControl(selectedSiteId.value, submitData)
|
||||||
|
if (error) {
|
||||||
|
message.error('提交失败')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
message.success('提交成功')
|
||||||
|
// 重新获取最新数据
|
||||||
|
await getAccessControl()
|
||||||
|
} catch (e) {
|
||||||
|
console.error('提交出错:', e)
|
||||||
|
message.error('提交失败')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 在 script setup 中添加 Cancel 处理函数
|
||||||
|
const handleCancel = async () => {
|
||||||
|
if (!selectedSiteId.value) {
|
||||||
|
message.warning('请先选择站点')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
await getAccessControl()
|
||||||
|
message.success('已刷新数据')
|
||||||
|
} catch (e) {
|
||||||
|
console.error('刷新数据出错:', e)
|
||||||
|
message.error('刷新数据失败')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
console.log('onMounted执行')
|
||||||
|
await getSiteList()
|
||||||
|
console.log('onMounted后selectedSiteId', selectedSiteId.value)
|
||||||
|
if (selectedSiteId.value) {
|
||||||
|
await getAccessControl()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.anticon-info-circle {
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user