三页面重设计与移动端适配;接入 PWA 与构建分包
CI / test (push) Successful in 47s

This commit is contained in:
2026-07-21 19:26:22 +08:00
parent ac457282ce
commit 6129173fe6
64 changed files with 6243 additions and 549 deletions
+50 -24
View File
@@ -40,6 +40,7 @@ import LifecycleBadge from '@/components/LifecycleBadge.vue'
import OcidText from '@/components/OcidText.vue'
import RenameModal from '@/components/RenameModal.vue'
import { fmtTime, shortAd, truncOcid, vpusLabel } from '@/composables/useFormat'
import { useIsMobile } from '@/composables/useIsMobile'
import { useRegionAlias } from '@/composables/useRegionAlias'
import { useAsync } from '@/composables/useAsync'
import {
@@ -56,6 +57,10 @@ const message = useToast()
const dialog = useDialog()
const { alias: regionAlias } = useRegionAlias()
/** 移动端 hero 元信息默认收起省首屏 */
const isMobile = useIsMobile()
const heroExpanded = ref(false)
const cfgId = computed(() => Number(route.params.cfgId))
const instanceId = computed(() => String(route.params.instanceId))
/** 实例所在区域:列表页跳转时经 query 传入,缺失时回退实例对象上的短名(后端已归一化) */
@@ -419,24 +424,47 @@ const consoleColumns: DataTableColumns<ConsoleConnection> = [
<h1 class="page-title">{{ instance.data.value.displayName }}</h1>
<LifecycleBadge :state="instance.data.value.lifecycleState" />
<div class="flex-1" />
<NButton v-if="isStopped" size="small" :disabled="isEnded" @click="power('START')">
启动
</NButton>
<NButton v-else size="small" :disabled="isEnded" @click="power('STOP')">停止</NButton>
<NButton size="small" :disabled="isEnded" @click="power('RESET')">重启</NButton>
<NButton size="small" type="error" ghost :disabled="isEnded" @click="terminate">
终止
</NButton>
<NDropdown
:options="moreOptions"
:disabled="isEnded"
@select="(key: string) => power(key as PowerAction)"
>
<NButton size="small" quaternary :disabled="isEnded"></NButton>
</NDropdown>
<!-- 操作按钮组:移动端整组独立成行,不随标题换行散落 -->
<div class="flex items-center gap-2 max-md:w-full">
<NButton v-if="isStopped" size="small" :disabled="isEnded" @click="power('START')">
启动
</NButton>
<NButton v-else size="small" :disabled="isEnded" @click="power('STOP')">停止</NButton>
<NButton size="small" :disabled="isEnded" @click="power('RESET')">重启</NButton>
<NButton size="small" type="error" ghost :disabled="isEnded" @click="terminate">
终止
</NButton>
<NDropdown
:options="moreOptions"
:disabled="isEnded"
@select="(key: string) => power(key as PowerAction)"
>
<NButton size="small" quaternary :disabled="isEnded"></NButton>
</NDropdown>
</div>
</div>
<div class="mt-3 grid grid-cols-5 gap-4 max-lg:grid-cols-3 max-md:grid-cols-1">
<button
v-if="isMobile"
class="mt-2 flex cursor-pointer items-center gap-1 text-xs text-ink-3"
@click="heroExpanded = !heroExpanded"
>
{{ heroExpanded ? '收起详情' : '展开详情' }}
<svg
class="h-3 w-3 transition-transform"
:class="heroExpanded ? 'rotate-180' : ''"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<path d="m6 9 6 6 6-6" />
</svg>
</button>
<div
v-if="!isMobile || heroExpanded"
class="mt-3 grid grid-cols-5 gap-4 max-lg:grid-cols-3 max-md:grid-cols-1"
>
<div class="min-w-0">
<div class="text-xs text-ink-3">租户</div>
<div class="mt-0.5 truncate text-[13px]" :title="config.data.value?.tenancyName">
@@ -470,7 +498,7 @@ const consoleColumns: DataTableColumns<ConsoleConnection> = [
<div class="grid grid-cols-2 items-start gap-4 max-lg:grid-cols-1">
<!-- 基本信息 -->
<div v-if="instance.data.value" class="panel">
<div class="flex items-center justify-between border-b border-line-soft px-4.5 py-3.5">
<div class="flex flex-wrap items-center justify-between gap-y-2 border-b border-line-soft px-4.5 py-3.5">
<div class="text-sm font-semibold">基本信息</div>
<NButton size="tiny" quaternary :disabled="isEnded" @click="showRename = true">
重命名
@@ -546,7 +574,7 @@ const consoleColumns: DataTableColumns<ConsoleConnection> = [
<div class="border-b border-line-soft px-4.5 py-3.5">
<div class="text-sm font-semibold">网络</div>
<div class="mt-0.5 text-xs text-ink-3">
主网卡地址快捷视图全部网卡与各卡 IPv6 管理见下方网卡VNIC
主网卡地址快捷视图
</div>
</div>
<div class="flex flex-col px-4.5 py-1.5">
@@ -599,7 +627,7 @@ const consoleColumns: DataTableColumns<ConsoleConnection> = [
<!-- 引导卷 -->
<div class="panel">
<div class="flex items-center justify-between border-b border-line-soft px-4.5 py-3.5">
<div class="flex flex-wrap items-center justify-between gap-y-2 border-b border-line-soft px-4.5 py-3.5">
<div class="text-sm font-semibold">引导卷</div>
<NButton
size="small"
@@ -671,7 +699,7 @@ const consoleColumns: DataTableColumns<ConsoleConnection> = [
<!-- 块存储卷 -->
<div class="panel">
<div class="flex items-center justify-between border-b border-line-soft px-4.5 py-3.5">
<div class="flex flex-wrap items-center justify-between gap-y-2 border-b border-line-soft px-4.5 py-3.5">
<div class="text-sm font-semibold">块存储卷</div>
<NButton
size="small"
@@ -696,7 +724,7 @@ const consoleColumns: DataTableColumns<ConsoleConnection> = [
<!-- 控制台连接 -->
<div class="panel">
<div class="flex items-center justify-between border-b border-line-soft px-4.5 py-3.5">
<div class="flex flex-wrap items-center justify-between gap-y-2 border-b border-line-soft px-4.5 py-3.5">
<div class="text-sm font-semibold">控制台连接(VNC / 串口)</div>
<div class="flex items-center gap-2">
<NButton
@@ -723,9 +751,7 @@ const consoleColumns: DataTableColumns<ConsoleConnection> = [
:row-key="(r: ConsoleConnection) => r.id"
/>
<FootNote>
串行终端 / 网页 VNC 浏览器内直连(创建会话时自动清理旧连接,二者同时只能开一个)·
「创建连接」用于本地 ssh / VNC 客户端:公钥仅支持 RSA,串口直接执行串口连接串,VNC
执行后客户端连 localhost:5900 · 串口登录需实例本地账户密码
串行终端 / 网页 VNC 浏览器内直连,同时只能开一个 · 「创建连接」供本地 ssh / VNC 客户端使用(公钥仅支持 RSA)
</FootNote>
</div>