refactor(frontend): P1-P2 续 — API 子模块化、大组件拆分、Query 铺开

- api/server/ 与 api/cloud/ 子目录拆分,保持 @/api 导入不变
- hooks/api 新增 useCredentials、usePromDatasources,增强 useServers
- 拆分 CredentialManager、DeploymentWorkload、PrometheusDatasourceManager
- ServerManager、CredentialManager、PromDs 接入 TanStack Query
This commit is contained in:
Logan.Li committed 2026-06-26 00:22:50 +08:00
1 parent f45e203e21
commit 480e677042
32 files changed
+2280 -1940

No files matched your search

+2 -105
View File
@@ -1,106 +1,3 @@
// 云账号/平台/账单
// 从 services/api.ts 拆分 — Q3 api.ts 模块化
// 云资源 API — 子模块 re-export(保持 @/api 导入路径不变) // Logan.Li
import { http, type ListResponse } from '@/utils/request';
export const cloudApi = {
getAccounts: async () => {
return http.get<ListResponse>('/cloud-accounts');
},
createAccount: async ( data: any) => {
return http.post('/cloud-accounts', data);
},
updateAccount: async (id: number | string, data: any) => {
return http.put(`/cloud-accounts/${id}`, data);
},
deleteAccount: async (id: number | string) => {
return http.delete(`/cloud-accounts/${id}`);
},
// ==================== 云同步 API ====================
// 同步云账号的区域列表到本地
syncRegions: async (id: number | string) => {
return http.post(`/cloud-accounts/${id}/sync-regions`);
},
// 获取云账号的区域列表
getAccountRegions: async (id: number | string) => {
return http.get<ListResponse>(`/cloud-accounts/${id}/regions`);
},
// 发现指定区域的云主机实例
discoverInstances: async (id: number | string, regions: string[]) => {
return http.post<{ list: any[]; total: number; errors: string[] }>(`/cloud-accounts/${id}/discover-instances`, { regions });
},
// 导入选中的云主机实例为本地服务器
importInstances: async (id: number | string, instances: any[], opts?: { default_port?: number; credential_id?: number }) => {
return http.post<{ imported: number; skipped: number }>(`/cloud-accounts/${id}/import-instances`, { instances, ...opts });
},
getDomains: async (params?: { page?: number; page_size?: number; keyword?: string }) => {
return http.get<ListResponse>('/domains', params);
},
createDomain: async ( data: any) => {
return http.post('/domains', data);
},
updateDomain: async (id: number | string, data: any) => {
return http.put(`/domains/${id}`, data);
},
deleteDomain: async (id: number | string) => {
return http.delete(`/domains/${id}`);
},
};
// ==================== 云平台 API ====================
export const platformApi = {
list: async () => {
return http.get<ListResponse>('/platforms');
},
create: async ( data: any) => {
return http.post('/platforms', data);
},
update: async (id: number | string, data: any) => {
return http.put(`/platforms/${id}`, data);
},
delete: async (id: number | string) => {
return http.delete(`/platforms/${id}`);
},
};
// ==================== 云账单 API ====================
export const billingApi = {
getStats: async () => {
return http.get('/cloud-billings/stats');
},
list: async (params?: { provider?: string; start_date?: string; end_date?: string; page?: number; page_size?: number }) => {
return http.get<ListResponse>('/cloud-billings', params);
},
create: async ( data: any) => {
return http.post('/cloud-billings', data);
},
batchCreate: async ( records: any[]) => {
return http.post('/cloud-billings/batch', { records });
},
remove: async (id: number | string) => {
return http.delete(`/cloud-billings/${id}`);
},
getProviders: async () => {
return http.get('/cloud-billings/providers');
},
// 预警规则
listAlertRules: async () => {
return http.get<ListResponse>('/billing-alerts');
},
createAlertRule: async ( data: any) => {
return http.post('/billing-alerts', data);
},
updateAlertRule: async (id: number | string, data: any) => {
return http.put(`/billing-alerts/${id}`, data);
},
deleteAlertRule: async (id: number | string) => {
return http.delete(`/billing-alerts/${id}`);
},
toggleAlertRule: async (id: number | string) => {
return http.post(`/billing-alerts/${id}/toggle`);
},
};
// ==================== Agent 监控 API ====================
export * from './cloud/index';
+42
View File
@@ -0,0 +1,42 @@
// 云账号 / 域名 API // Logan.Li
import { http, type ListResponse } from '@/utils/request';
export const cloudApi = {
getAccounts: async () => {
return http.get<ListResponse>('/cloud-accounts');
},
createAccount: async (data: Record<string, unknown>) => {
return http.post('/cloud-accounts', data);
},
updateAccount: async (id: number | string, data: Record<string, unknown>) => {
return http.put(`/cloud-accounts/${id}`, data);
},
deleteAccount: async (id: number | string) => {
return http.delete(`/cloud-accounts/${id}`);
},
syncRegions: async (id: number | string) => {
return http.post(`/cloud-accounts/${id}/sync-regions`);
},
getAccountRegions: async (id: number | string) => {
return http.get<ListResponse>(`/cloud-accounts/${id}/regions`);
},
discoverInstances: async (id: number | string, regions: string[]) => {
return http.post<{ list: Record<string, unknown>[]; total: number; errors: string[] }>(`/cloud-accounts/${id}/discover-instances`, { regions });
},
importInstances: async (id: number | string, instances: Record<string, unknown>[], opts?: { default_port?: number; credential_id?: number }) => {
return http.post<{ imported: number; skipped: number }>(`/cloud-accounts/${id}/import-instances`, { instances, ...opts });
},
getDomains: async (params?: { page?: number; page_size?: number; keyword?: string }) => {
return http.get<ListResponse>('/domains', params);
},
createDomain: async (data: Record<string, unknown>) => {
return http.post('/domains', data);
},
updateDomain: async (id: number | string, data: Record<string, unknown>) => {
return http.put(`/domains/${id}`, data);
},
deleteDomain: async (id: number | string) => {
return http.delete(`/domains/${id}`);
},
};
+39
View File
@@ -0,0 +1,39 @@
// 云账单 / 预警 API // Logan.Li
import { http, type ListResponse } from '@/utils/request';
export const billingApi = {
getStats: async () => {
return http.get('/cloud-billings/stats');
},
list: async (params?: { provider?: string; start_date?: string; end_date?: string; page?: number; page_size?: number }) => {
return http.get<ListResponse>('/cloud-billings', params);
},
create: async (data: Record<string, unknown>) => {
return http.post('/cloud-billings', data);
},
batchCreate: async (records: Record<string, unknown>[]) => {
return http.post('/cloud-billings/batch', { records });
},
remove: async (id: number | string) => {
return http.delete(`/cloud-billings/${id}`);
},
getProviders: async () => {
return http.get('/cloud-billings/providers');
},
listAlertRules: async () => {
return http.get<ListResponse>('/billing-alerts');
},
createAlertRule: async (data: Record<string, unknown>) => {
return http.post('/billing-alerts', data);
},
updateAlertRule: async (id: number | string, data: Record<string, unknown>) => {
return http.put(`/billing-alerts/${id}`, data);
},
deleteAlertRule: async (id: number | string) => {
return http.delete(`/billing-alerts/${id}`);
},
toggleAlertRule: async (id: number | string) => {
return http.post(`/billing-alerts/${id}/toggle`);
},
};
+5
View File
@@ -0,0 +1,5 @@
// 云资源 API 聚合出口 // Logan.Li
export { cloudApi } from './account';
export { platformApi } from './platform';
export { billingApi } from './billing';
+18
View File
@@ -0,0 +1,18 @@
// 云平台 API // Logan.Li
import { http, type ListResponse } from '@/utils/request';
export const platformApi = {
list: async () => {
return http.get<ListResponse>('/platforms');
},
create: async (data: Record<string, unknown>) => {
return http.post('/platforms', data);
},
update: async (id: number | string, data: Record<string, unknown>) => {
return http.put(`/platforms/${id}`, data);
},
delete: async (id: number | string) => {
return http.delete(`/platforms/${id}`);
},
};
+2 -103
View File
@@ -1,104 +1,3 @@
// 服务器/资产/区域/资源型号
// 从 services/api.ts 拆分 — Q3 api.ts 模块化
// 服务器域 API — 子模块 re-export(保持 @/api 导入路径不变) // Logan.Li
import { http, type ListResponse } from '@/utils/request';
export const serverApi = {
getServers: async (params?: { page?: number; page_size?: number; keyword?: string; status?: string }) => {
return http.get<ListResponse>('/servers', params);
},
getServerDetail: async (id: number | string) => {
return http.get(`/servers/${id}`);
},
getServerStats: async () => {
return http.get('/servers/stats');
},
createServer: async ( data: any) => {
return http.post('/servers', data);
},
updateServer: async (id: number | string, data: any) => {
return http.put(`/servers/${id}`, data);
},
deleteServer: async (id: number | string) => {
return http.delete(`/servers/${id}`);
},
batchDelete: async (ids: number[]) => {
return http.post('/servers/batch-delete', { ids });
},
batchCreate: async (data: { servers: any[]; region_id?: string; auth_type?: string; credential_id?: number; default_port?: number }) => {
return http.post('/servers/batch', data);
},
getMetrics: async (_id: number | string) => {
// 后端暂无单机 metrics,用 dashboard metrics
return http.get('/dashboard/metrics');
},
// 远程安装 Agent(通过 SSH 执行安装脚本),可选传入凭据
installAgent: async (id: number | string, token: string, creds?: { username?: string; password?: string; ssh_key?: string; auth_type?: string }) => {
const body: Record<string, any> = { token };
if (creds) Object.assign(body, creds);
return http.post<{ installed: boolean; arch: string; output: string }>(`/servers/${id}/install-agent`, body);
},
// 批量远程安装 Agent
batchInstallAgent: async (ids: number[], token: string) => {
return http.post<{ total: number; success: number; results: any[] }>(`/servers/install-agent?token=${encodeURIComponent(token)}`, { server_ids: ids });
},
// SFTP 文件浏览
listFiles: async (serverId: number, path: string) => {
return http.get(`/servers/${serverId}/files?path=${encodeURIComponent(path)}`);
},
downloadFile: async (serverId: number, filePath: string) => {
return http.download(`/servers/${serverId}/files/download?path=${encodeURIComponent(filePath)}`);
},
uploadFile: async (serverId: number, dirPath: string, file: File) => {
const formData = new FormData();
formData.append('file', file);
return http.upload(`/servers/${serverId}/files/upload?path=${encodeURIComponent(dirPath)}`, formData);
},
deleteFile: async (serverId: number, filePath: string) => {
return http.delete(`/servers/${serverId}/files?path=${encodeURIComponent(filePath)}`);
},
mkdir: async (serverId: number, dirPath: string) => {
return http.post(`/servers/${serverId}/files/mkdir`, { path: dirPath });
},
};
// ==================== Kubernetes 集群 API ====================
export const regionApi = {
list: async () => {
return http.get<ListResponse>('/regions');
},
create: async ( data: any) => {
return http.post('/regions', data);
},
update: async (id: number | string, data: any) => {
return http.put(`/regions/${id}`, data);
},
delete: async (id: number | string) => {
return http.delete(`/regions/${id}`);
},
// 批量删除 // Logan.Li
batchDelete: async (ids: number[]) => {
return http.delete('/regions/batch-delete', { ids });
},
};
// ==================== 资源模型 API ====================
export const resourceModelApi = {
list: async () => {
return http.get<ListResponse>('/resource-models');
},
create: async ( data: any) => {
return http.post('/resource-models', data);
},
update: async (id: number | string, data: any) => {
return http.put(`/resource-models/${id}`, data);
},
delete: async (id: number | string) => {
return http.delete(`/resource-models/${id}`);
},
};
// ==================== 审计日志 API ====================
export * from './server/index';
+5
View File
@@ -0,0 +1,5 @@
// 服务器域 API 聚合出口 // Logan.Li
export { serverApi } from './server';
export { regionApi } from './region';
export { resourceModelApi } from './resource-model';
+21
View File
@@ -0,0 +1,21 @@
// 区域 API // Logan.Li
import { http, type ListResponse } from '@/utils/request';
export const regionApi = {
list: async () => {
return http.get<ListResponse>('/regions');
},
create: async (data: Record<string, unknown>) => {
return http.post('/regions', data);
},
update: async (id: number | string, data: Record<string, unknown>) => {
return http.put(`/regions/${id}`, data);
},
delete: async (id: number | string) => {
return http.delete(`/regions/${id}`);
},
batchDelete: async (ids: number[]) => {
return http.delete('/regions/batch-delete', { ids });
},
};
+18
View File
@@ -0,0 +1,18 @@
// 资源型号 API // Logan.Li
import { http, type ListResponse } from '@/utils/request';
export const resourceModelApi = {
list: async () => {
return http.get<ListResponse>('/resource-models');
},
create: async (data: Record<string, unknown>) => {
return http.post('/resource-models', data);
},
update: async (id: number | string, data: Record<string, unknown>) => {
return http.put(`/resource-models/${id}`, data);
},
delete: async (id: number | string) => {
return http.delete(`/resource-models/${id}`);
},
};
+58
View File
@@ -0,0 +1,58 @@
// 服务器资产 API // Logan.Li
import { http, type ListResponse } from '@/utils/request';
export const serverApi = {
getServers: async (params?: { page?: number; page_size?: number; keyword?: string; status?: string }) => {
return http.get<ListResponse>('/servers', params);
},
getServerDetail: async (id: number | string) => {
return http.get(`/servers/${id}`);
},
getServerStats: async () => {
return http.get('/servers/stats');
},
createServer: async (data: Record<string, unknown>) => {
return http.post('/servers', data);
},
updateServer: async (id: number | string, data: Record<string, unknown>) => {
return http.put(`/servers/${id}`, data);
},
deleteServer: async (id: number | string) => {
return http.delete(`/servers/${id}`);
},
batchDelete: async (ids: number[]) => {
return http.post('/servers/batch-delete', { ids });
},
batchCreate: async (data: { servers: Record<string, unknown>[]; region_id?: string; auth_type?: string; credential_id?: number; default_port?: number }) => {
return http.post('/servers/batch', data);
},
getMetrics: async (_id: number | string) => {
return http.get('/dashboard/metrics');
},
installAgent: async (id: number | string, token: string, creds?: { username?: string; password?: string; ssh_key?: string; auth_type?: string }) => {
const body: Record<string, unknown> = { token };
if (creds) Object.assign(body, creds);
return http.post<{ installed: boolean; arch: string; output: string }>(`/servers/${id}/install-agent`, body);
},
batchInstallAgent: async (ids: number[], token: string) => {
return http.post<{ total: number; success: number; results: Record<string, unknown>[] }>(`/servers/install-agent?token=${encodeURIComponent(token)}`, { server_ids: ids });
},
listFiles: async (serverId: number, path: string) => {
return http.get(`/servers/${serverId}/files?path=${encodeURIComponent(path)}`);
},
downloadFile: async (serverId: number, filePath: string) => {
return http.download(`/servers/${serverId}/files/download?path=${encodeURIComponent(filePath)}`);
},
uploadFile: async (serverId: number, dirPath: string, file: File) => {
const formData = new FormData();
formData.append('file', file);
return http.upload(`/servers/${serverId}/files/upload?path=${encodeURIComponent(dirPath)}`, formData);
},
deleteFile: async (serverId: number, filePath: string) => {
return http.delete(`/servers/${serverId}/files?path=${encodeURIComponent(filePath)}`);
},
mkdir: async (serverId: number, dirPath: string) => {
return http.post(`/servers/${serverId}/files/mkdir`, { path: dirPath });
},
};