90 lines
2.8 KiB
Vue
90 lines
2.8 KiB
Vue
<script setup lang="ts">
|
||
import { NCheckbox, NInput } from 'naive-ui'
|
||
import { computed, reactive, ref, watch } from 'vue'
|
||
|
||
import { createVcn } from '@/api/networks'
|
||
import FormField from '@/components/FormField.vue'
|
||
import FormModal from '@/components/FormModal.vue'
|
||
import { defaultResourceName } from '@/composables/useFormat'
|
||
import { useToast } from '@/composables/useToast'
|
||
|
||
/** 租户 / 区间 / 区域直接使用父页面当前值,不在表单中出现 */
|
||
const props = defineProps<{
|
||
show: boolean
|
||
cfgId: number | null
|
||
compartmentId?: string
|
||
region?: string
|
||
}>()
|
||
const emit = defineEmits<{ 'update:show': [boolean]; created: [] }>()
|
||
|
||
const message = useToast()
|
||
const submitting = ref(false)
|
||
|
||
const blank = {
|
||
displayName: '',
|
||
cidrBlock: '10.0.0.0/16',
|
||
dnsLabel: '',
|
||
enableIpv6: true,
|
||
}
|
||
const form = reactive({ ...blank })
|
||
|
||
watch(
|
||
() => props.show,
|
||
(v) => {
|
||
if (!v) return
|
||
Object.assign(form, blank)
|
||
form.displayName = defaultResourceName('vcn')
|
||
},
|
||
)
|
||
|
||
const cidrOk = computed(() => /^\d{1,3}(\.\d{1,3}){3}\/\d{1,2}$/.test(form.cidrBlock.trim()))
|
||
const canSubmit = computed(() => props.cfgId !== null && !!form.displayName.trim() && cidrOk.value)
|
||
|
||
async function submit() {
|
||
if (props.cfgId === null) return
|
||
submitting.value = true
|
||
try {
|
||
const created = await createVcn(props.cfgId, {
|
||
region: props.region || undefined,
|
||
compartmentId: props.compartmentId || undefined,
|
||
displayName: form.displayName.trim(),
|
||
cidrBlock: form.cidrBlock.trim(),
|
||
dnsLabel: form.dnsLabel.trim() || undefined,
|
||
enableIpv6: form.enableIpv6,
|
||
})
|
||
message.success(`VCN「${created.displayName}」已创建`)
|
||
emit('update:show', false)
|
||
emit('created')
|
||
} catch (e) {
|
||
message.error(e instanceof Error ? e.message : '创建失败')
|
||
} finally {
|
||
submitting.value = false
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<template>
|
||
<FormModal
|
||
:show="show"
|
||
title="创建 VCN"
|
||
:submitting="submitting"
|
||
:submit-disabled="!canSubmit"
|
||
submit-text="创建"
|
||
@update:show="emit('update:show', $event)"
|
||
@submit="submit"
|
||
>
|
||
<div class="grid grid-cols-2 gap-3 max-md:grid-cols-1">
|
||
<FormField label="名称" required>
|
||
<NInput v-model:value="form.displayName" placeholder="vcn-20260703-2136" />
|
||
</FormField>
|
||
<FormField label="IPv4 CIDR" required :error="cidrOk ? undefined : '格式如 10.0.0.0/16'">
|
||
<NInput v-model:value="form.cidrBlock" class="mono" placeholder="10.0.0.0/16" />
|
||
</FormField>
|
||
</div>
|
||
<FormField label="DNS 标签" hint="留空不启用 VCN 内 DNS;仅小写字母数字,15 字符内">
|
||
<NInput v-model:value="form.dnsLabel" class="mono" placeholder="可选" />
|
||
</FormField>
|
||
<NCheckbox v-model:checked="form.enableIpv6">同时分配 Oracle IPv6 前缀(/56)</NCheckbox>
|
||
</FormModal>
|
||
</template>
|