新增对象存储/账单/保留IP页面,成本今天视图与样式收敛
CI / test (push) Successful in 42s

This commit is contained in:
2026-07-21 12:11:22 +08:00
parent d813225ac4
commit ac457282ce
91 changed files with 6672 additions and 652 deletions
+24 -42
View File
@@ -3,7 +3,6 @@ import {
NButton,
NDataTable,
NDropdown,
NPopconfirm,
NSpin,
useDialog,
type DataTableColumns,
@@ -14,7 +13,6 @@ import { RouterLink, useRoute, useRouter } from 'vue-router'
import { getBootVolume } from '@/api/bootVolumes'
import { getConfig } from '@/api/configs'
import {
changePublicIp,
deleteConsoleConnection,
detachBootVolume,
detachVolume,
@@ -27,6 +25,7 @@ import {
terminateInstance,
updateInstance,
} from '@/api/instances'
import EmptyCard from '@/components/EmptyCard.vue'
import FootNote from '@/components/FootNote.vue'
import AttachVolumeModal from '@/components/instance/AttachVolumeModal.vue'
import ConsoleConnModal from '@/components/instance/ConsoleConnModal.vue'
@@ -36,6 +35,7 @@ import ReplaceBootVolumeModal from '@/components/instance/ReplaceBootVolumeModal
import ResizeModal from '@/components/instance/ResizeModal.vue'
import VnicPanel from '@/components/instance/VnicPanel.vue'
import { useConsoleStore } from '@/stores/console'
import ConfirmPop from '@/components/ConfirmPop.vue'
import LifecycleBadge from '@/components/LifecycleBadge.vue'
import OcidText from '@/components/OcidText.vue'
import RenameModal from '@/components/RenameModal.vue'
@@ -221,9 +221,6 @@ async function act(fn: () => Promise<unknown>, ok: string) {
}
}
// 换 IP 请求期间的按钮 loading,操作发出立即有反馈
const changeIpBusy = ref(false)
function power(action: PowerAction) {
void act(
() => instanceAction(cfgId.value, instanceId.value, action, region.value),
@@ -255,12 +252,6 @@ function terminate() {
})
}
async function doChangeIp() {
changeIpBusy.value = true
await act(() => changePublicIp(cfgId.value, instanceId.value, region.value), '公网 IP 已更换')
changeIpBusy.value = false
}
const volColumns: DataTableColumns<VolumeAttachment> = [
{
title: '块卷',
@@ -302,14 +293,15 @@ const volColumns: DataTableColumns<VolumeAttachment> = [
width: 90,
render: (r) =>
h(
NPopconfirm,
ConfirmPop,
{
onPositiveClick: () =>
act(() => detachVolume(cfgId.value, r.id, region.value), '分离请求已提交'),
title: '分离该块卷?',
content: 'OS 内请先卸载文件系统。',
confirmText: '分离',
onConfirm: () => act(() => detachVolume(cfgId.value, r.id, region.value), '分离请求已提交'),
},
{
trigger: () => h(NButton, { size: 'tiny', quaternary: true }, { default: () => '分离' }),
default: () => '分离该块卷?OS 内请先卸载文件系统',
},
),
},
@@ -378,8 +370,12 @@ const consoleColumns: DataTableColumns<ConsoleConnection> = [
width: 90,
render: (r) =>
h(
NPopconfirm,
{ onPositiveClick: () => doDeleteConsoleConn(r.id) },
ConfirmPop,
{
title: '删除控制台连接?',
confirmText: '删除',
onConfirm: () => doDeleteConsoleConn(r.id),
},
{
trigger: () =>
h(
@@ -393,7 +389,6 @@ const consoleColumns: DataTableColumns<ConsoleConnection> = [
},
{ default: () => '删除' },
),
default: () => '删除该控制台连接?',
},
),
},
@@ -408,11 +403,8 @@ const consoleColumns: DataTableColumns<ConsoleConnection> = [
>
<NSpin size="small" />
</div>
<div
v-else-if="instance.error.value"
class="panel px-5 py-10 text-center text-[13px] text-ink-3"
>
{{ instance.error.value }}
<div v-else-if="instance.error.value" class="panel">
<EmptyCard title="实例加载失败" :note="instance.error.value" />
</div>
<div v-if="instance.data.value" class="panel px-5 py-4">
@@ -562,21 +554,9 @@ const consoleColumns: DataTableColumns<ConsoleConnection> = [
<div class="w-22 flex-none text-xs text-ink-3 max-md:w-auto">公网 IP</div>
<div class="min-w-0 flex-1">
<span class="mono">{{ instance.data.value.publicIp || '—' }}</span>
<NPopconfirm @positive-click="doChangeIp">
<template #trigger>
<NButton
size="tiny"
quaternary
type="primary"
:disabled="isEnded"
:loading="changeIpBusy"
>
更换
</NButton>
</template>
更换即删除旧临时公网 IP 再分配新的保留 IP 会被拒绝确认
</NPopconfirm>
<div class="mt-0.5 text-xs text-ink-3">临时 IP · 更换即删旧分新</div>
<div class="mt-0.5 text-xs text-ink-3">
IP 在下方网卡(VNIC)对应行操作
</div>
</div>
</div>
<div class="flex gap-3 border-b border-line-soft py-2.5 max-md:flex-col max-md:gap-0.5">
@@ -666,14 +646,16 @@ const consoleColumns: DataTableColumns<ConsoleConnection> = [
>
调整大小 / VPU
</NButton>
<NPopconfirm
@positive-click="act(() => detachBootVolume(cfgId, att.id, region), '分离请求已提交')"
<ConfirmPop
title="分离引导卷?"
content="实例将无法启动,直到挂载新引导卷。"
confirm-text="分离"
:on-confirm="() => act(() => detachBootVolume(cfgId, att.id, region), '分离请求已提交')"
>
<template #trigger>
<NButton size="tiny" quaternary :disabled="!isStopped || isEnded">分离</NButton>
</template>
分离引导卷?实例将无法启动直到挂载新引导卷
</NPopconfirm>
</ConfirmPop>
</div>
<div
v-if="!(bvAtts.data.value ?? []).length"