refactor(frontend): P0 API 层收口与 http 统一
- 统一 http.ts baseURL:get/post/download/upload 均走 resolveApiUrl - agentUtils 下沉至 lib/agent-utils,API 层移除对 components 的依赖 - 扩展 metricsApi/snmpApi/prometheusProxyApi/zabbixProxyApi - 扩展 pipelineApi/credentialApi 覆盖流水线与凭证场景 - 14 个组件/页面禁止直连 http,统一走 @/services/api
This commit is contained in:
1 parent
bfd6431b9d
commit
7fb2236b4d
27 files changed
+194
-150
No files matched your search
@@ -8,8 +8,7 @@ import { Label } from '@/components/ui/label';
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
|
||||
import { Plus, Key, Globe, Container } from 'lucide-react';
|
||||
import { toast } from 'sonner';
|
||||
import { deployApi } from '@/services/api';
|
||||
import http from '@/services/http';
|
||||
import { credentialApi, deployApi } from '@/services/api';
|
||||
|
||||
interface Repo {
|
||||
id: number; name: string; url: string; credential_id: number | null;
|
||||
@@ -48,7 +47,7 @@ export default function CredentialFormDialog({ open, onOpenChange, type, editId,
|
||||
|
||||
const loadCredentials = async () => {
|
||||
try {
|
||||
const res: Record<string, any> = await http.get('/credentials?page_size=100');
|
||||
const res: Record<string, any> = await credentialApi.list({ page_size: 100 });
|
||||
setCredentials(res?.list || []);
|
||||
} catch { /* silent */ }
|
||||
};
|
||||
|
||||
@@ -34,7 +34,7 @@ import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, Di
|
||||
|
||||
import { toast } from 'sonner';
|
||||
import { useConfirm } from '@/components/ui/confirm-dialog';
|
||||
import http from '@/services/http';
|
||||
import { credentialApi } from '@/services/api';
|
||||
|
||||
// ────── Types ──────
|
||||
|
||||
@@ -85,7 +85,7 @@ function CredDetailDialog({ open, onClose, credId }: { open: boolean; onClose: (
|
||||
useEffect(() => {
|
||||
if (!credId || !open) return;
|
||||
setLoading(true);
|
||||
http.get(`/credentials/${credId}`).then(( res: any) => {
|
||||
credentialApi.get(credId).then(( res: any) => {
|
||||
setDetail(res);
|
||||
}).catch(() => toast.error('加载详情失败')).finally(() => setLoading(false));
|
||||
}, [credId, open]);
|
||||
@@ -372,10 +372,10 @@ function CredFormDialog({ open, onClose, onSaved, editData }: {
|
||||
}
|
||||
|
||||
if (isEdit) {
|
||||
await http.put(`/credentials/${editData!.id}`, payload);
|
||||
await credentialApi.update(editData!.id, payload);
|
||||
toast.success('已更新');
|
||||
} else {
|
||||
await http.post('/credentials', payload);
|
||||
await credentialApi.create(payload);
|
||||
toast.success('已创建');
|
||||
}
|
||||
onSaved();
|
||||
@@ -643,11 +643,11 @@ export default function CredentialManager() {
|
||||
const fetchAll = useCallback(async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const params = new URLSearchParams();
|
||||
if (filterType) params.set('secret_type', filterType);
|
||||
if (filterSearch) params.set('search', filterSearch);
|
||||
params.set('page_size', '100');
|
||||
const res: Record<string, any> = await http.get(`/credentials?${params.toString()}`);
|
||||
const res: Record<string, any> = await credentialApi.list({
|
||||
page_size: 100,
|
||||
...(filterType ? { secret_type: filterType } : {}),
|
||||
...(filterSearch ? { search: filterSearch } : {}),
|
||||
});
|
||||
setCredentials(res?.list || []);
|
||||
} catch { toast.error('获取凭证列表失败'); }
|
||||
finally { setLoading(false); }
|
||||
@@ -664,7 +664,7 @@ export default function CredentialManager() {
|
||||
});
|
||||
if (!ok) return;
|
||||
try {
|
||||
await http.delete(`/credentials/${cred.id}`);
|
||||
await credentialApi.delete(cred.id);
|
||||
toast.success('已删除');
|
||||
fetchAll();
|
||||
} catch { toast.error('删除失败'); }
|
||||
@@ -672,7 +672,7 @@ export default function CredentialManager() {
|
||||
|
||||
const handleToggleActive = async (cred: Credential) => {
|
||||
try {
|
||||
await http.put(`/credentials/${cred.id}`, { is_active: !cred.is_active });
|
||||
await credentialApi.toggleActive(cred.id, !cred.is_active);
|
||||
toast.success(cred.is_active ? '已禁用' : '已启用');
|
||||
fetchAll();
|
||||
} catch { toast.error('操作失败'); }
|
||||
|
||||
@@ -17,7 +17,7 @@ import {
|
||||
Minimize2,
|
||||
} from 'lucide-react';
|
||||
import { cn } from '@/lib/utils';
|
||||
import http from '@/services/http';
|
||||
import { pipelineApi } from '@/services/api';
|
||||
import { useUserStore } from '@/store';
|
||||
|
||||
interface FileItem {
|
||||
@@ -69,8 +69,7 @@ export function FileBrowserDialog({
|
||||
setLoading(true);
|
||||
setError('');
|
||||
try {
|
||||
const params = path ? `?path=${encodeURIComponent(path)}` : '';
|
||||
const data = await http.get(`/pipelines/runs/${runId}/files${params}`);
|
||||
const data = await pipelineApi.listRunFiles(runId, path || undefined);
|
||||
setListing(data);
|
||||
setCurrentPath(data?.current || '');
|
||||
} catch (err: any) {
|
||||
|
||||
@@ -40,8 +40,7 @@ import {
|
||||
Package,
|
||||
} from 'lucide-react';
|
||||
|
||||
import { pipelineApi, deployApi } from '@/services/api';
|
||||
import http from '@/services/http';
|
||||
import { credentialApi, deployApi, pipelineApi } from '@/services/api';
|
||||
import { useConfirm } from '@/components/ui/confirm-dialog';
|
||||
import { toast } from 'sonner';
|
||||
import { nameToCode, getStatusBadge } from './pipeline-helpers';
|
||||
@@ -140,7 +139,7 @@ export function PipelineManager() {
|
||||
deployApi.getRepos().catch(() => ({ list: [] })),
|
||||
deployApi.getRegistries().catch(() => ({ list: [] })),
|
||||
deployApi.getEnvironments().catch(() => ({ list: [] })),
|
||||
http.get('/credentials', { page_size: 100 }).catch(() => ({ list: [] })),
|
||||
credentialApi.list({ page_size: 100 }).catch(() => ({ list: [] })),
|
||||
] as const);
|
||||
setRepos(Array.isArray((rR as Record<string, any>)?.list) ? (rR as Record<string, any>).list : []);
|
||||
setRegistries(Array.isArray((rReg as Record<string, any>)?.list) ? (rReg as Record<string, any>).list : []);
|
||||
@@ -891,7 +890,7 @@ function PipelineQueuePanel({ pipeline, clusterId: _cid }: { pipeline: any; clus
|
||||
if (!code) return;
|
||||
setLoading(true);
|
||||
try {
|
||||
const res: Record<string, any> = await http.get(`/pipelines/${code}/queue`);
|
||||
const res: Record<string, any> = await pipelineApi.getQueue(code);
|
||||
setQueue(res?.data || res);
|
||||
} catch { setQueue(null); }
|
||||
finally { setLoading(false); }
|
||||
@@ -901,7 +900,7 @@ function PipelineQueuePanel({ pipeline, clusterId: _cid }: { pipeline: any; clus
|
||||
|
||||
const handleCancel = async (runId: number) => {
|
||||
try {
|
||||
await http.delete(`/pipelines/${code}/queue/${runId}`);
|
||||
await pipelineApi.removeFromQueue(code, runId);
|
||||
toast.success('已取消');
|
||||
loadQueue();
|
||||
} catch { toast.error('取消失败'); }
|
||||
|
||||
@@ -10,7 +10,7 @@ import { Button } from '@/components/ui/button';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
import { toast } from 'sonner';
|
||||
import http from '@/services/http';
|
||||
import { pipelineApi } from '@/services/api';
|
||||
import { FileBrowserDialog } from './FileBrowserDialog';
|
||||
|
||||
// ═══════════ 阶段定义 (与 PipelineManager 共用) ═══════════
|
||||
@@ -147,7 +147,7 @@ export default function PipelineRunDetail() {
|
||||
// 加载流水线详情
|
||||
const fetchPipeline = useCallback(async () => {
|
||||
try {
|
||||
const data: Record<string, any> = await http.get(`/pipelines/${pipelineCode}`);
|
||||
const data: Record<string, any> = await pipelineApi.getByCode(pipelineCode);
|
||||
setPipeline(data?.data || data);
|
||||
} catch { /* silent, pipeline info optional */ }
|
||||
}, [pipelineCode]);
|
||||
@@ -156,7 +156,7 @@ export default function PipelineRunDetail() {
|
||||
const fetchRuns = useCallback(async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const data: Record<string, any> = await http.get(`/pipelines/${pipelineCode}/runs?page_size=${pageSize}`);
|
||||
const data: Record<string, any> = await pipelineApi.getRunsByCode(pipelineCode, pageSize);
|
||||
const list = data?.list || [];
|
||||
setRuns(list);
|
||||
if (!selectedRun && list.length > 0) {
|
||||
@@ -180,7 +180,7 @@ export default function PipelineRunDetail() {
|
||||
// 加载日志
|
||||
const fetchLogs = useCallback(async (run: PipelineRun) => {
|
||||
try {
|
||||
const data: Record<string, any> = await http.get(`/pipelines/runs/${run.id}/log-stream`);
|
||||
const data: Record<string, any> = await pipelineApi.getRunLogStream(run.id);
|
||||
if (data?.logs) {
|
||||
const parsed = typeof data.logs === 'string' ? JSON.parse(data.logs) : data.logs;
|
||||
setLogs(Array.isArray(parsed) ? parsed : []);
|
||||
@@ -232,7 +232,7 @@ export default function PipelineRunDetail() {
|
||||
// 触发
|
||||
const triggerRun = async () => {
|
||||
try {
|
||||
await http.post(`/pipelines/${pipelineCode}/trigger`, {});
|
||||
await pipelineApi.triggerByCode(pipelineCode);
|
||||
toast.success('已触发');
|
||||
fetchRuns();
|
||||
} catch { toast.error('触发失败'); }
|
||||
@@ -241,7 +241,7 @@ export default function PipelineRunDetail() {
|
||||
// 停止
|
||||
const stopRun = async (runId: number) => {
|
||||
try {
|
||||
await http.post(`/pipelines/${pipelineCode}/runs/${runId}/stop`, {});
|
||||
await pipelineApi.stopRunByCode(pipelineCode, runId);
|
||||
toast.success('已停止');
|
||||
fetchRuns();
|
||||
} catch { toast.error('停止失败'); }
|
||||
@@ -252,7 +252,7 @@ export default function PipelineRunDetail() {
|
||||
if (selectedIds.size === 0) return;
|
||||
setDeleting(true);
|
||||
try {
|
||||
await http.post(`/pipelines/${pipelineCode}/runs/batch-delete`, { ids: Array.from(selectedIds) });
|
||||
await pipelineApi.batchDeleteRuns(pipelineCode, Array.from(selectedIds));
|
||||
toast.success(`已删除 ${selectedIds.size} 条记录`);
|
||||
setSelectedIds(new Set());
|
||||
fetchRuns();
|
||||
|
||||
@@ -11,7 +11,7 @@ import 'xterm/css/xterm.css';
|
||||
import { Maximize2, Minimize2, X, FolderOpen } from 'lucide-react';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { useUserStore } from '@/store';
|
||||
import http from '@/services/http';
|
||||
import { pipelineApi } from '@/services/api';
|
||||
|
||||
interface WorkspaceTermDialogProps {
|
||||
open: boolean;
|
||||
@@ -40,7 +40,7 @@ export function WorkspaceTermDialog({
|
||||
// 获取 workspace 路径
|
||||
useEffect(() => {
|
||||
if (!open || !runId) return;
|
||||
http.get(`/pipelines/runs/${runId}/workspace`)
|
||||
pipelineApi.getWorkspace(runId)
|
||||
.then(( data: any) => setWorkspace(data?.workspace_path || ''))
|
||||
.catch(() => {});
|
||||
}, [open, runId]);
|
||||
|
||||
Reference in new issue
Block a user