初始提交: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,94 @@
<script setup lang="ts">
import { NSelect, useMessage } from 'naive-ui'
import { computed, ref, watch } from 'vue'
import { listBootVolumes } from '@/api/bootVolumes'
import { replaceBootVolume } from '@/api/instances'
import FormField from '@/components/FormField.vue'
import FormModal from '@/components/FormModal.vue'
import { useAsync } from '@/composables/useAsync'
const props = defineProps<{
show: boolean
cfgId: number
instanceId: string
region?: string
availabilityDomain: string
}>()
const emit = defineEmits<{ 'update:show': [boolean]; replaced: [] }>()
const message = useMessage()
const submitting = ref(false)
const bootVolumeId = ref<string | null>(null)
const volumes = useAsync(
() => listBootVolumes(props.cfgId, props.availabilityDomain, undefined, props.region),
false,
)
watch(
() => props.show,
(v) => {
if (v) {
bootVolumeId.value = null
void volumes.run()
}
},
)
const options = computed(
() =>
volumes.data.value
?.filter((v) => !v.attachedInstanceId)
.map((v) => ({ label: `${v.displayName}${v.sizeInGBs} GB`, value: v.id })) ?? [],
)
async function submit() {
if (!bootVolumeId.value) return
submitting.value = true
try {
await replaceBootVolume(props.cfgId, props.instanceId, bootVolumeId.value, props.region)
message.success('替换请求已提交:分离旧引导卷并挂载所选引导卷')
emit('update:show', false)
emit('replaced')
} catch (e) {
message.error(e instanceof Error ? e.message : '替换失败')
} finally {
submitting.value = false
}
}
</script>
<template>
<FormModal
:show="show"
title="替换引导卷"
:submitting="submitting"
:submit-disabled="!bootVolumeId"
submit-text="替换"
@update:show="emit('update:show', $event)"
@submit="submit"
>
<FormField
label="目标引导卷"
required
hint="仅列出同可用域、未挂载的引导卷"
:error="
!volumes.loading.value && !options.length
? '同可用域内没有未挂载的引导卷,无法替换'
: undefined
"
>
<NSelect
v-model:value="bootVolumeId"
:options="options"
:loading="volumes.loading.value"
placeholder="选择未挂载的引导卷"
/>
</FormField>
<div class="text-xs leading-relaxed text-ink-3">
原引导卷分离后保留不会删除实例保持 STOPPED替换完成后可启动
</div>
</FormModal>
</template>