初始提交:OCI 面板前端(含 GenAI 网关一期)

This commit is contained in:
Wang Defa
2026-07-09 15:31:29 +08:00
commit db45a669e3
135 changed files with 25220 additions and 0 deletions
@@ -0,0 +1,105 @@
<script setup lang="ts">
import { NInput, useMessage } 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'
/** 租户 / 区间 / 区域直接使用父页面当前值,不在表单中出现 */
const props = defineProps<{
show: boolean
cfgId: number | null
compartmentId?: string
region?: string
}>()
const emit = defineEmits<{ 'update:show': [boolean]; created: [] }>()
const message = useMessage()
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>