From 93981b9aad7a1664fda816a11300429418ad1696 Mon Sep 17 00:00:00 2001 From: mac Date: Tue, 28 Jul 2026 17:56:58 +0800 Subject: [PATCH] feat: update delivery and resource frontends --- frontend/components.d.ts | 1 + frontend/src/api/containerService.ts | 36 +++ frontend/src/api/delivery.ts | 18 ++ frontend/src/api/machine.ts | 144 ++++++++++++ frontend/src/views/cluster/ClusterList.vue | 139 ++++++----- frontend/src/views/resource/Management.vue | 259 ++++++++++++++++----- frontend/src/views/service/Management.vue | 97 ++++++-- 7 files changed, 561 insertions(+), 133 deletions(-) create mode 100644 frontend/src/api/machine.ts diff --git a/frontend/components.d.ts b/frontend/components.d.ts index 379b92d..b9d9b5d 100644 --- a/frontend/components.d.ts +++ b/frontend/components.d.ts @@ -20,6 +20,7 @@ declare module 'vue' { ElInput: typeof import('element-plus/es')['ElInput'] ElInputNumber: typeof import('element-plus/es')['ElInputNumber'] ElOption: typeof import('element-plus/es')['ElOption'] + ElPagination: typeof import('element-plus/es')['ElPagination'] ElSelect: typeof import('element-plus/es')['ElSelect'] ElTable: typeof import('element-plus/es')['ElTable'] ElTableColumn: typeof import('element-plus/es')['ElTableColumn'] diff --git a/frontend/src/api/containerService.ts b/frontend/src/api/containerService.ts index 0dd6808..647ed81 100644 --- a/frontend/src/api/containerService.ts +++ b/frontend/src/api/containerService.ts @@ -34,6 +34,33 @@ export interface ContainerWorkload { statusClass: string } +export interface ContainerCluster { + name: string + zone: string + zoneClass: string + status: string + statusClass: string + nodes: number + readyNodes: number + cpu: number + cpuClass: string + version: string + calico: string +} + +export interface ContainerNode { + cluster: string + name: string + ip: string + label: string + taint: string + spec: string + cpu: number + cpuClass: string + status: string + statusClass: string +} + export const emptyContainerServiceSummary: ContainerServiceSummary = { businessLineId: 0, businessLineName: '', @@ -65,6 +92,15 @@ export const containerServiceApi = { summary: data.summary || emptyContainerServiceSummary, } }, + + async listClusters(businessLineId: number): Promise<{ items: ContainerCluster[]; nodes: ContainerNode[]; summary: ContainerServiceSummary }> { + const data = await authRequest(`/auth/api/v1/container-services/business-lines/${businessLineId}/clusters`) + return { + items: Array.isArray(data.items) ? data.items : [], + nodes: Array.isArray(data.nodes) ? data.nodes : [], + summary: data.summary || emptyContainerServiceSummary, + } + }, } async function authRequest(path: string, init: RequestInit = {}) { diff --git a/frontend/src/api/delivery.ts b/frontend/src/api/delivery.ts index 21aca13..62d3f57 100644 --- a/frontend/src/api/delivery.ts +++ b/frontend/src/api/delivery.ts @@ -83,6 +83,19 @@ export interface DeliveryTaskSnapshot { events: TaskEvent[] } +export interface MySQLServiceLedgerItem { + name: string + datacenter: string + business_tag: string + instances: number + healthy: number + address: string + status: string + status_class: string + version: string + namespace: string +} + export const deliveryApi = { async listTargets(): Promise { const data = await authRequest('/auth/api/v1/delivery/targets?component=mysql') @@ -115,6 +128,11 @@ export const deliveryApi = { return Array.isArray(data.items) ? data.items : [] }, + async listMySQLServices(businessLineId: number): Promise { + const data = await authRequest(`/auth/api/v1/delivery/business-lines/${businessLineId}/mysql-services`) + return Array.isArray(data.items) ? data.items : [] + }, + async getTask(taskId: string): Promise<{ task: DeliveryTask; events: TaskEvent[] }> { const data = await authRequest(`/auth/api/v1/delivery/tasks/${encodeURIComponent(taskId)}`) return { diff --git a/frontend/src/api/machine.ts b/frontend/src/api/machine.ts new file mode 100644 index 0000000..4e8c237 --- /dev/null +++ b/frontend/src/api/machine.ts @@ -0,0 +1,144 @@ +import { getToken } from '@/utils/auth' + +export interface MachineOverview { + total: number + physical: number + virtual: number + cmdb: { + total: number + physical: number + virtual: number + } + aliyun: { + total: number + label: string + } + awsQiniu: { + total: number + aws: number + qiniu: number + } + lastSync: { + status: string + time: string + created: number + error?: string + } +} + +export interface MachineResource { + hostname: string + assetNumber: string + type: string + location: string + ip: string + spec: string + businessLine: string + source: string + status: string +} + +export interface MachineResourceList { + total: number + items: MachineResource[] +} + +export interface MachineResourceQuery { + page: number + size: number + hostname?: string + assetNumber?: string + type?: string + location?: string + ip?: string + spec?: string + businessLine?: string + source?: string + status?: string +} + +export const emptyMachineOverview: MachineOverview = { + total: 0, + physical: 0, + virtual: 0, + cmdb: { + total: 0, + physical: 0, + virtual: 0, + }, + aliyun: { + total: 0, + label: 'ECS · 增量同步', + }, + awsQiniu: { + total: 0, + aws: 0, + qiniu: 0, + }, + lastSync: { + status: 'unknown', + time: '—', + created: 0, + }, +} + +export const machineApi = { + async getOverview(): Promise { + return authRequest('/auth/api/v1/machines/overview') + }, + + async listResources(query: MachineResourceQuery): Promise { + const params = new URLSearchParams() + params.set('page', String(query.page)) + params.set('size', String(query.size)) + if (query.hostname) params.set('hostname', query.hostname) + if (query.assetNumber) params.set('assetNumber', query.assetNumber) + if (query.type) params.set('type', query.type) + if (query.location) params.set('location', query.location) + if (query.ip) params.set('ip', query.ip) + if (query.spec) params.set('spec', query.spec) + if (query.businessLine) params.set('businessLine', query.businessLine) + if (query.source) params.set('source', query.source) + if (query.status) params.set('status', query.status) + const data = await authRequest(`/auth/api/v1/machines/resources?${params.toString()}`) + return { + total: Number(data.total || 0), + items: Array.isArray(data.items) ? data.items : [], + } + }, + + async sync(): Promise { + await authRequest('/auth/api/v1/machines/sync', { method: 'POST' }) + }, +} + +async function authRequest(path: string, init: RequestInit = {}) { + const token = getToken() + const response = await fetch(path, { + ...init, + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token ? { Authorization: `Bearer ${token}` } : {}), + ...init.headers, + }, + }) + const text = await response.text() + const data = parseResponseBody(text) + if (!response.ok) { + const message = data?.error || data?.message || text || `HTTP ${response.status}` + throw new Error(message) + } + return data || {} +} + +function parseResponseBody(text: string) { + if (!text.trim()) { + return {} + } + try { + return JSON.parse(text) + } catch { + return { error: text } + } +} diff --git a/frontend/src/views/cluster/ClusterList.vue b/frontend/src/views/cluster/ClusterList.vue index 7f945fe..adfe783 100644 --- a/frontend/src/views/cluster/ClusterList.vue +++ b/frontend/src/views/cluster/ClusterList.vue @@ -3,14 +3,15 @@

集群与容器

-

统一建设容器池 · RKE2 上建 Wayne 后新服务的标准发布流程 · Calico BGP 扁平网络

+

统一建设容器池 · RKE2 上建 Wayne 后新服务的标准发布流程 · 数据源:Wayne 原生接口

- 同步 + 同步
- +
{{ error }}
+
@@ -24,7 +25,15 @@ - + + + + @@ -43,11 +52,11 @@
-

{{ businessLineClusters[0]?.name }} · 节点列表(节选)

+

{{ selectedCluster || businessLineClusters[0]?.name || '未选择集群' }} · 节点列表

node-label 多租户隔离
-
集群
当前业务线暂无 Wayne 集群数据
{{ cluster.name }} {{ cluster.zone }} ● {{ cluster.status }}
+
@@ -60,13 +69,21 @@ + + + - + - + @@ -77,61 +94,77 @@ diff --git a/frontend/src/views/service/Management.vue b/frontend/src/views/service/Management.vue index 5a796f1..6664250 100644 --- a/frontend/src/views/service/Management.vue +++ b/frontend/src/views/service/Management.vue @@ -3,16 +3,16 @@

服务管理

-

同步全部机房 Consul 注册中心服务目录,统一查看服务名 / 服务 IP / 业务标签 / 实例数

+

同步基础服务实例台账,统一查看服务名 / 服务 IP / 业务标签 / 实例数

- 同步 + 同步
-
接入 Consul Datacenter
-
7
-
国内 3 · 海外 4
+
接入 Datacenter
+
{{ serviceDatacenters }}
+
来自基础服务实例台账
服务总数
@@ -22,17 +22,17 @@
服务实例总数
{{ serviceInstances }}
-
所有机房注册 IP 汇总
+
当前业务线实例汇总
健康实例占比
-
98.6%
-
12 个实例 critical
+
{{ serviceHealthPercent }}%
+
{{ unhealthyInstances }} 个实例异常
最近同步
-
● 正常
-
07:41:05 · 间隔 30s
+
● {{ serviceError ? '异常' : '正常' }}
+
{{ serviceMetaText }}
@@ -66,7 +66,7 @@

服务台账 · 按 Consul Datacenter 同步

- 数据源:Consul Catalog API + {{ serviceLoading ? '同步中...' : serviceMetaText }}
节点
当前集群暂无 Wayne 节点数据
{{ node.name }} {{ node.ip }}{{ node.label }}{{ node.label }} {{ node.taint }} {{ node.spec }}{{ node.cpu }}% + + - + ● {{ node.status }}
@@ -82,6 +82,9 @@ + + + @@ -154,28 +157,45 @@
当前业务线暂无基础服务实例
{{ service.name }} {{ service.dc }}