# 虚拟化平台管理 — 页面关系图谱

## 一、目录结构

```
src/
├── views/virtualization/           ← 页面组件（19个）
│   ├── KvmService.vue              # 主控服务管理（入口列表页）
│   ├── KvmServiceDetail.vue        # 主控服务详情（核心容器页）
│   ├── HostTreeManage.vue          # 宿主机树形管理
│   ├── HostManage.vue              # 宿主机列表管理（独立路由）
│   ├── HostDetail.vue              # 宿主机详情（容器页）
│   ├── HostGroupMapping.vue        # 宿主机组映射管理
│   ├── RemoteHostGroupManage.vue   # 远程宿主机组管理
│   ├── ImageManage.vue             # 镜像管理
│   ├── ImageDetail.vue             # 镜像详情
│   ├── NetworkManage.vue           # 网络管理
│   ├── VolumeManage.vue            # 数据卷管理
│   ├── VmManage.vue                # 虚拟机管理
│   ├── VmDetail.vue                # 虚拟机详情（容器页）
│   ├── SecurityGroupManage.vue     # 安全组管理
│   ├── SecurityGroupDetail.vue     # 安全组详情
│   ├── VncNodeManage.vue           # VNC节点管理
│   ├── SnapshotManage.vue          # 快照管理
│   ├── BackupManage.vue            # 备份管理
│   └── UserNetworkingManage.vue    # 用户组网管理
│
└── components/admin/               ← 公共弹窗选择组件（6个）
    ├── VmSelectorPopup.vue         # 虚拟机选择器
    ├── VolumeSelectorPopup.vue     # 数据卷选择器
    ├── NetworkSelectorPopup.vue    # 网络选择器
    ├── ImageSelectorPopup.vue      # 镜像选择器
    ├── SecurityGroupSelectorPopup.vue # 安全组选择器
    └── HostGroupSelectorPopup.vue  # 宿主机组选择器
```

---

## 二、路由结构

所有页面都在 `/virtualization` 路由下，层级扁平（非嵌套路由），通过 `query` 参数传递上下文。

```
/virtualization
├── /kvm-service                    → KvmService.vue              （菜单入口）
├── /kvm-service-detail             → KvmServiceDetail.vue        （hidden）
├── /host-group-mapping             → HostGroupMapping.vue        （菜单可见）
├── /host-manage                    → HostManage.vue              （hidden）
├── /image-manage                   → ImageManage.vue             （hidden）
├── /network-manage                 → NetworkManage.vue           （hidden）
├── /volume-manage                  → VolumeManage.vue            （hidden）
├── /vm-manage                      → VmManage.vue                （hidden）
├── /security-group                 → SecurityGroupManage.vue     （hidden）
├── /vnc-node                       → VncNodeManage.vue           （hidden）
├── /host-detail                    → HostDetail.vue              （hidden）
├── /image-detail                   → ImageDetail.vue             （hidden）
├── /vm-detail                      → VmDetail.vue                （hidden）
└── /security-group-detail          → SecurityGroupDetail.vue     （hidden）
```

> 标记 `hidden` 的路由不在侧边菜单显示，用户通过页面内操作跳转进入。

---

## 三、页面嵌套机制：`provide / inject` 上下文注入

嵌套不通过路由嵌套实现，而是通过 **父页面直接引入子组件** + **Vue3 `provide/inject`** 传递上下文。

### 3.1 provide 注入方

| 父页面 | provide 的 key | 说明 |
|---|---|---|
| `KvmServiceDetail.vue` | `embedded`, `serviceId`, `serviceName` | 主控服务详情作为容器 |
| `HostDetail.vue` | `embedded`, `serviceId`, `serviceName`, `hostId` | 宿主机详情作为容器，额外注入 `hostId` |

### 3.2 inject 接收方

以下组件都同时支持 **独立路由访问** 和 **被嵌入到父页面的标签页中**：

| 组件 | inject 的 key | 嵌入后行为变化 |
|---|---|---|
| `HostTreeManage.vue` | `embedded`, `serviceId`, `serviceName` | 隐藏返回按钮/主控选择器 |
| `HostManage.vue` | `embedded`, `serviceId`, `serviceName` | 隐藏返回按钮/主控选择器 |
| `ImageManage.vue` | `embedded`, `serviceId`, `serviceName`, `hostId` | 隐藏返回按钮；有 hostId 时隐藏宿主机筛选 |
| `NetworkManage.vue` | `embedded`, `serviceId`, `serviceName`, `hostId` | 隐藏返回按钮；有 hostId 时隐藏宿主机筛选 |
| `VolumeManage.vue` | `embedded`, `serviceId`, `serviceName`, `hostId` | 隐藏返回按钮；有 hostId 时隐藏宿主机筛选 |
| `VmManage.vue` | `embedded`, `serviceId`, `serviceName`, `hostId` | 隐藏返回按钮；有 hostId 时筛选该宿主机下的虚拟机 |
| `SecurityGroupManage.vue` | `embedded`, `serviceId`, `serviceName` | 隐藏返回按钮/主控选择器 |
| `VncNodeManage.vue` | `embedded`, `serviceId`, `serviceName` | 隐藏返回按钮/主控选择器 |
| `SnapshotManage.vue` | `serviceId` | 仅嵌入使用，依赖父级 serviceId |
| `BackupManage.vue` | `serviceId` | 仅嵌入使用，依赖父级 serviceId |
| `UserNetworkingManage.vue` | `embedded`, `serviceId`, `serviceName` | 隐藏返回按钮/主控选择器 |
| `RemoteHostGroupManage.vue` | `embedded`, `serviceId`, `serviceName` | 隐藏返回按钮/主控选择器 |
| `HostGroupMapping.vue` | `embedded`, `serviceId`, `serviceName` | 隐藏返回按钮/主控选择器 |

---

## 四、完整关系图谱

```
┌─────────────────────────────────────────────────────────────────────────┐
│                        KvmService.vue（主控服务列表）                      │
│                        路由: /virtualization/kvm-service                  │
│                                                                         │
│  点击「查看详情」 ──router.push──→ KvmServiceDetail                       │
└─────────────────────────────────────────────────────────────────────────┘
                                     │
                                     ▼
┌─────────────────────────────────────────────────────────────────────────┐
│              KvmServiceDetail.vue（主控服务详情 · 容器页）                  │
│              路由: /virtualization/kvm-service-detail                     │
│              provide: embedded, serviceId, serviceName                    │
│                                                                         │
│  ┌─ Tabs ─────────────────────────────────────────────────────────┐     │
│  │ 宿主机管理 │ 镜像管理 │ 网络管理 │ 数据卷管理 │ 虚拟机管理 │       │     │
│  │ 安全组管理 │ VNC节点 │ 快照管理 │ 备份管理 │ 用户组网 │          │     │
│  └─────────────────────────────────────────────────────────────────┘     │
│                                                                         │
│  标签页内嵌组件（defineAsyncComponent 懒加载）：                          │
│  ├── HostTreeManage.vue ─── 点击宿主机 ──router.push──→ HostDetail      │
│  ├── ImageManage.vue ────── 点击镜像 ──router.push──→ ImageDetail       │
│  ├── NetworkManage.vue                                                  │
│  ├── VolumeManage.vue                                                   │
│  ├── VmManage.vue ──────── 点击虚拟机 ──router.push──→ VmDetail         │
│  ├── SecurityGroupManage.vue ── 点击安全组 ──router.push──→ SGDetail    │
│  ├── VncNodeManage.vue                                                  │
│  ├── SnapshotManage.vue                                                 │
│  ├── BackupManage.vue                                                   │
│  └── UserNetworkingManage.vue                                           │
└─────────────────────────────────────────────────────────────────────────┘
           │                           │                    │
           ▼                           ▼                    ▼
┌──────────────────────┐ ┌──────────────────┐ ┌──────────────────────────┐
│  HostDetail.vue      │ │ ImageDetail.vue  │ │ SecurityGroupDetail.vue  │
│  (宿主机详情·容器页) │ │ (镜像详情)       │ │ (安全组详情)             │
│  provide: embedded,  │ │                  │ │                          │
│  serviceId,          │ │  ← 返回主控详情  │ │  ← 返回主控详情          │
│  serviceName, hostId │ └──────────────────┘ └──────────────────────────┘
│                      │
│  ┌─ Tabs ──────────────────────────────────┐
│  │ 基本信息 │ 监控 │ 镜像管理 │ 网络管理 │  │
│  │ 数据卷管理 │ 虚拟机管理 │ 快照 │ 备份 │  │
│  └──────────────────────────────────────────┘
│                      │
│  标签页内嵌组件（直接 import）：
│  ├── ImageManage.vue       ← 同一组件，inject hostId 后隐藏宿主机筛选
│  ├── NetworkManage.vue     ← 同一组件，inject hostId 后隐藏宿主机筛选
│  ├── VolumeManage.vue      ← 同一组件，inject hostId 后隐藏宿主机筛选
│  ├── VmManage.vue          ← 同一组件，inject hostId 后筛选范围缩小
│  ├── SnapshotManage.vue
│  └── BackupManage.vue
│                      │
│  VmManage 内点击「查看详情」──router.push──→ VmDetail
└──────────────────────┘
                       │
                       ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                    VmDetail.vue（虚拟机详情 · 容器页）                     │
│                    路由: /virtualization/vm-detail                        │
│                                                                         │
│  ┌─ Tabs ─────────────────────────────────────────────────────────┐     │
│  │ 实例详情 │ 网络信息 │ 磁盘卷信息 │ 安全组 │ 快照 │ 备份 │ 监控 │     │
│  └─────────────────────────────────────────────────────────────────┘     │
│                                                                         │
│  不嵌入外部页面组件，内联自行管理所有标签页内容                            │
│  使用弹窗选择组件：                                                       │
│  ├── ImageSelectorPopup        （重建虚拟机时选择镜像）                   │
│  ├── VolumeSelectorPopup       （挂载已有数据卷）                         │
│  ├── NetworkSelectorPopup      （添加已有网络 / 重构时选择网络）          │
│  └── SecurityGroupSelectorPopup（绑定安全组）                             │
└─────────────────────────────────────────────────────────────────────────┘
```

---

## 五、组件复用关系汇总

### 5.1 同一页面组件在多个容器中被嵌入

| 管理组件 | 独立路由 | 嵌入 KvmServiceDetail | 嵌入 HostDetail |
|---|:---:|:---:|:---:|
| `HostTreeManage.vue` | ✗ | ✔ | ✗ |
| `HostManage.vue` | ✔ | ✗ | ✗ |
| `ImageManage.vue` | ✔ | ✔ | ✔ |
| `NetworkManage.vue` | ✔ | ✔ | ✔ |
| `VolumeManage.vue` | ✔ | ✔ | ✔ |
| `VmManage.vue` | ✔ | ✔ | ✔ |
| `SecurityGroupManage.vue` | ✔ | ✔ | ✗ |
| `VncNodeManage.vue` | ✔ | ✔ | ✗ |
| `SnapshotManage.vue` | ✗ | ✔ | ✔ |
| `BackupManage.vue` | ✗ | ✔ | ✔ |
| `UserNetworkingManage.vue` | ✗ | ✔ | ✗ |
| `RemoteHostGroupManage.vue` | ✗ | ✗（独立路由可能存在） | ✗ |
| `HostGroupMapping.vue` | ✔ | ✗ | ✗ |

### 5.2 弹窗选择组件使用关系

| 选择组件 | 被哪些页面使用 |
|---|---|
| `VmSelectorPopup` | VolumeManage、VncNodeManage、UserNetworkingManage、SecurityGroupManage、SecurityGroupDetail |
| `ImageSelectorPopup` | VmManage、VolumeManage、VmDetail |
| `HostGroupSelectorPopup` | VmManage、HostManage、HostDetail |
| `VolumeSelectorPopup` | VmDetail |
| `NetworkSelectorPopup` | VmDetail |
| `SecurityGroupSelectorPopup` | VmDetail |

---

## 六、页面跳转路径总览

```
KvmService（列表）
  └──→ KvmServiceDetail（详情）
         ├──→ HostDetail（宿主机详情）──→ 返回 KvmServiceDetail
         │       └──→ VmDetail（虚拟机详情）──→ 返回 KvmServiceDetail
         ├──→ ImageDetail（镜像详情）──→ 返回 KvmServiceDetail
         ├──→ VmDetail（虚拟机详情）──→ 返回 KvmServiceDetail
         └──→ SecurityGroupDetail（安全组详情）──→ 返回 KvmServiceDetail
```

---

## 七、嵌入机制核心代码模式

### 父级容器 provide（以 KvmServiceDetail 为例）

```javascript
provide('embedded', true)
provide('serviceId', serviceId)      // ref<number>
provide('serviceName', serviceName)  // ref<string>
```

### 子组件 inject + 自适应

```javascript
const embedded = inject('embedded', false)
const injectedServiceId = inject('serviceId', null)
const injectedHostId = inject('hostId', null)  // 仅 HostDetail 下有

// 根据 embedded 控制 UI
// - 隐藏顶部返回栏和主控选择器
// - 自动使用注入的 serviceId / hostId 替代手动选择
```

### KvmServiceDetail 使用 defineAsyncComponent 懒加载

```javascript
const HostTreeManage = defineAsyncComponent(() => import('./HostTreeManage.vue'))
const ImageManage = defineAsyncComponent(() => import('./ImageManage.vue'))
// ... 其余同理
```

### HostDetail 使用直接 import

```javascript
import ImageManage from '@/views/virtualization/ImageManage.vue'
import NetworkManage from '@/views/virtualization/NetworkManage.vue'
// ... 其余同理
```

---

## 八、设计特点总结

1. **双模式组件**：ImageManage、NetworkManage、VolumeManage、VmManage 等组件同时支持独立路由和嵌入模式，通过 `inject('embedded')` 判断当前上下文，动态调整 UI 和数据来源。

2. **扁平路由 + 组件嵌入**：路由层级扁平，页面间嵌套关系通过组件引入（import）实现，而非路由嵌套（children）。

3. **上下文逐层传递**：KvmServiceDetail 传递 `serviceId`，HostDetail 在此基础上追加 `hostId`，子组件根据可用 key 自动收窄数据范围。

4. **弹窗选择组件解耦**：选择器作为独立的 Popup 组件放在 `components/admin/` 下，通过 `v-model` 控制显隐、`emit('confirm')` 回传选中数据，各页面按需引用。
