Files
oci-portal-dash/src/components/instance/CreateInstanceModal.vue
T
Wang Defa 5464d2dfea
CI / test (push) Successful in 27s
Release / release (push) Successful in 26s
发布 0.1.0:通知渠道、告警规则与多项体验修复
2026-07-10 17:31:19 +08:00

107 lines
3.4 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup lang="ts">
import { NInput } from 'naive-ui'
import { computed, reactive, ref, watch } from 'vue'
import { createInstances } from '@/api/instances'
import AppInputNumber from '@/components/AppInputNumber.vue'
import FormField from '@/components/FormField.vue'
import FormModal from '@/components/FormModal.vue'
import InstanceSpecForm from '@/components/instance/InstanceSpecForm.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 specForm = ref<InstanceType<typeof InstanceSpecForm> | null>(null)
const form = reactive({ displayName: '', count: 1 })
watch(
() => props.show,
(v) => {
if (!v) return
form.displayName = defaultResourceName('instance')
form.count = 1
specForm.value?.reset()
},
)
const canSubmit = computed(
() =>
props.cfgId !== null &&
Boolean(form.displayName.trim()) &&
(specForm.value?.valid ?? false),
)
async function submit() {
if (props.cfgId === null || !specForm.value) return
submitting.value = true
try {
const result = await createInstances(props.cfgId, {
region: props.region || undefined,
compartmentId: props.compartmentId || undefined,
displayName: form.displayName.trim(),
count: form.count,
...specForm.value.buildSpec(),
})
// 后端 errors / instances 为空时序列化为 null,判空防炸
const ok = result.instances?.length ?? 0
const failed = result.errors?.length ?? 0
if (failed) message.warning(`${ok} 台创建成功,${failed} 台失败:${result.errors![0]}`)
else message.success(`已创建 ${ok} 台实例`)
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="创建实例"
:width="600"
: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="instance-20260703-2136" />
</FormField>
<FormField label="数量" hint="批量创建,名称自动追加序号">
<AppInputNumber v-model:value="form.count" :min="1" :max="10" class="w-full" />
</FormField>
</div>
<InstanceSpecForm
ref="specForm"
sectioned
:cfg-id="cfgId"
:region="region"
:compartment-id="compartmentId"
/>
<div
class="mt-3 flex flex-wrap items-center justify-between gap-2 rounded-lg border border-line-soft bg-wash px-3 py-2 text-xs leading-relaxed text-ink-3"
>
<span v-if="specForm?.summary" class="font-medium text-ink-2">
预估规格:{{ form.count }} · {{ specForm.summary }}
</span>
<span>容量不足Out of host capacity时可改用抢机任务反复尝试</span>
</div>
</FormModal>
</template>