feat:组网配置
This commit is contained in:
@@ -8,9 +8,9 @@ import {
|
||||
EditOutlined,
|
||||
DeleteOutlined
|
||||
} from '@ant-design/icons-vue';
|
||||
import { getDashboardSiteList, addSite, deleteSite, getSiteConfig, updateSite } from '@/service/api/auth';
|
||||
import { getDashboardSiteList, addSite, deleteSite, getSiteConfig, updateSite, getMeshConfig, updateMeshConfig, getRoamingConfig, updateRoamingConfig } from '@/service/api/auth';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { Form, Modal } from 'ant-design-vue';
|
||||
import { Form, Modal, Divider, Checkbox, Select, Input, Button } from 'ant-design-vue';
|
||||
import { message } from 'ant-design-vue';
|
||||
import { regionOptions, timeZoneOptions } from '@/constants/site-options';
|
||||
const { t } = useI18n();
|
||||
@@ -250,6 +250,13 @@ const editFormData = ref({
|
||||
region: '',
|
||||
timeZone: '',
|
||||
scenario: '',
|
||||
meshEnable: false,
|
||||
autoFailoverEnable: false,
|
||||
defGatewayEnable: true,
|
||||
gateway: '',
|
||||
fastRoamingEnable: false,
|
||||
nonStickRoamingEnable: false,
|
||||
aiRoamingEnable: false
|
||||
});
|
||||
|
||||
// 当前编辑的站点ID
|
||||
@@ -269,18 +276,53 @@ const { validate: validateEdit, validateInfos: validateEditInfos } = useForm(edi
|
||||
scenario: [{ required: true, message: t('page.carddata.scenarioRequired') }]
|
||||
});
|
||||
|
||||
// IP分段输入
|
||||
const gatewayIpParts = ref(['', '', '', '']);
|
||||
|
||||
// 拆分IP到4段
|
||||
function splitGatewayIp(ip: string) {
|
||||
if (!ip) return ['', '', '', ''];
|
||||
const parts = ip.split('.');
|
||||
return [parts[0] || '', parts[1] || '', parts[2] || '', parts[3] || ''];
|
||||
}
|
||||
// 拼接4段为IP
|
||||
function joinGatewayIp(parts: string[]) {
|
||||
return parts.map(p => p.trim()).join('.');
|
||||
}
|
||||
|
||||
// 弹窗打开时同步分段
|
||||
watch(() => editFormData.value.gateway, (val) => {
|
||||
gatewayIpParts.value = splitGatewayIp(val);
|
||||
}, { immediate: true });
|
||||
// 分段输入时同步到gateway
|
||||
watch(gatewayIpParts, (val) => {
|
||||
editFormData.value.gateway = joinGatewayIp(val);
|
||||
}, { deep: true });
|
||||
|
||||
// 处理编辑按钮点击
|
||||
const handleEdit = async (record: Api.DashboardSite) => {
|
||||
try {
|
||||
currentEditSiteId.value = record.siteId;
|
||||
const response = await getSiteConfig(record.siteId);
|
||||
if (response.data) {
|
||||
const [siteRes, meshRes, roamingRes] = await Promise.all([
|
||||
getSiteConfig(record.siteId),
|
||||
getMeshConfig(record.siteId),
|
||||
getRoamingConfig(record.siteId)
|
||||
]);
|
||||
if (siteRes.data) {
|
||||
editFormData.value = {
|
||||
name: response.data.name,
|
||||
region: response.data.region,
|
||||
timeZone: response.data.timeZone,
|
||||
scenario: response.data.scenario
|
||||
name: siteRes.data.name,
|
||||
region: siteRes.data.region,
|
||||
timeZone: siteRes.data.timeZone,
|
||||
scenario: siteRes.data.scenario,
|
||||
meshEnable: meshRes.data?.mesh?.meshEnable ?? false,
|
||||
autoFailoverEnable: meshRes.data?.mesh?.autoFailoverEnable ?? false,
|
||||
defGatewayEnable: meshRes.data?.mesh?.defGatewayEnable ?? true,
|
||||
gateway: meshRes.data?.mesh?.gateway ?? '',
|
||||
fastRoamingEnable: roamingRes.data?.roaming?.fastRoamingEnable ?? false,
|
||||
nonStickRoamingEnable: roamingRes.data?.roaming?.nonStickRoamingEnable ?? false,
|
||||
aiRoamingEnable: roamingRes.data?.roaming?.aiRoamingEnable ?? false
|
||||
};
|
||||
gatewayIpParts.value = splitGatewayIp(editFormData.value.gateway);
|
||||
showEditDialog.value = true;
|
||||
}
|
||||
} catch (error) {
|
||||
@@ -293,7 +335,32 @@ const handleEdit = async (record: Api.DashboardSite) => {
|
||||
const handleUpdateSite = async () => {
|
||||
try {
|
||||
await validateEdit();
|
||||
await updateSite(currentEditSiteId.value, editFormData.value);
|
||||
// 先保存基础配置
|
||||
await updateSite(currentEditSiteId.value, {
|
||||
name: editFormData.value.name,
|
||||
region: editFormData.value.region,
|
||||
timeZone: editFormData.value.timeZone,
|
||||
scenario: editFormData.value.scenario
|
||||
});
|
||||
// mesh 配置为嵌套结构,meshEnable为true时才携带defGatewayEnable和gateway
|
||||
const meshData: any = { mesh: { meshEnable: editFormData.value.meshEnable } };
|
||||
if (editFormData.value.meshEnable) {
|
||||
meshData.mesh.autoFailoverEnable = editFormData.value.autoFailoverEnable;
|
||||
meshData.mesh.defGatewayEnable = editFormData.value.defGatewayEnable;
|
||||
if (editFormData.value.defGatewayEnable === false) {
|
||||
meshData.mesh.gateway = editFormData.value.gateway;
|
||||
}
|
||||
}
|
||||
// roaming 配置为嵌套结构
|
||||
const roamingData: any = { roaming: { fastRoamingEnable: editFormData.value.fastRoamingEnable } };
|
||||
if (editFormData.value.fastRoamingEnable) {
|
||||
roamingData.roaming.nonStickRoamingEnable = editFormData.value.nonStickRoamingEnable;
|
||||
roamingData.roaming.aiRoamingEnable = editFormData.value.aiRoamingEnable;
|
||||
}
|
||||
await Promise.all([
|
||||
updateMeshConfig(currentEditSiteId.value, meshData),
|
||||
updateRoamingConfig(currentEditSiteId.value, roamingData)
|
||||
]);
|
||||
message.success(t('page.carddata.updateSuccess'));
|
||||
showEditDialog.value = false;
|
||||
fetchSiteList(); // 刷新列表
|
||||
@@ -478,6 +545,7 @@ const handleUpdateSite = async () => {
|
||||
@ok="handleUpdateSite"
|
||||
@cancel="showEditDialog = false"
|
||||
:maskClosable="false"
|
||||
:width="700"
|
||||
>
|
||||
<AForm
|
||||
:model="editFormData"
|
||||
@@ -530,6 +598,36 @@ const handleUpdateSite = async () => {
|
||||
:options="scenarioOptions"
|
||||
/>
|
||||
</AFormItem>
|
||||
|
||||
<a-divider />
|
||||
<div style="margin-bottom: 8px; font-weight: bold;">组网配置</div>
|
||||
<AFormItem>
|
||||
<a-checkbox v-model:checked="editFormData.meshEnable">Mesh</a-checkbox>
|
||||
</AFormItem>
|
||||
<AFormItem v-if="editFormData.meshEnable" style="margin-left: 24px;">
|
||||
<ASelect v-model:value="editFormData.defGatewayEnable" style="width: 200px;">
|
||||
<ASelectOption :value="true">Auto(Recommended)</ASelectOption>
|
||||
<ASelectOption :value="false">Custom</ASelectOption>
|
||||
</ASelect>
|
||||
<template v-if="editFormData.defGatewayEnable === false">
|
||||
<div style="display: inline-flex; align-items: center; margin-left: 12px;">
|
||||
<AInput v-for="(part, idx) in gatewayIpParts" :key="idx" v-model:value="gatewayIpParts[idx]" maxlength="3" style="width: 48px; text-align: center; margin-right: 4px;" />
|
||||
<span v-if="idx < 3" v-for="idx in 3" :key="'dot'+idx">.</span>
|
||||
</div>
|
||||
</template>
|
||||
</AFormItem>
|
||||
<AFormItem v-if="editFormData.meshEnable" style="margin-left: 24px;">
|
||||
<a-checkbox v-model:checked="editFormData.autoFailoverEnable">Auto Failover</a-checkbox>
|
||||
</AFormItem>
|
||||
<AFormItem>
|
||||
<a-checkbox v-model:checked="editFormData.fastRoamingEnable">Fast Roaming</a-checkbox>
|
||||
</AFormItem>
|
||||
<AFormItem v-if="editFormData.fastRoamingEnable" style="margin-left: 24px;">
|
||||
<a-checkbox v-model:checked="editFormData.nonStickRoamingEnable">Non-Stick Roaming</a-checkbox>
|
||||
</AFormItem>
|
||||
<AFormItem v-if="editFormData.fastRoamingEnable" style="margin-left: 24px;">
|
||||
<a-checkbox v-model:checked="editFormData.aiRoamingEnable">AI Roaming</a-checkbox>
|
||||
</AFormItem>
|
||||
</AForm>
|
||||
</AModal>
|
||||
</ACard>
|
||||
|
||||
Reference in New Issue
Block a user