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
@@ -7,7 +7,7 @@ import {
|
||||
import { Card, CardContent } from '@/components/ui/card';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { toast } from 'sonner';
|
||||
import { http } from '@/services/http';
|
||||
import { approvalWorkflowApi, userApi } from '@/services/api';
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Types */
|
||||
@@ -80,16 +80,7 @@ const STEP_TYPES = [
|
||||
{ value: 'execute' as const, label: '执行阶段', desc: '执行人员操作' },
|
||||
];
|
||||
|
||||
// API helpers
|
||||
const workflowApi = {
|
||||
list: (params?: { category?: string }) => http.get('/approval-workflows', params),
|
||||
get: (id: number) => http.get(`/approval-workflows/${id}`),
|
||||
create: (data: any) => http.post('/approval-workflows', data),
|
||||
update: (id: number, data: any) => http.put(`/approval-workflows/${id}`, data),
|
||||
delete: (id: number) => http.delete(`/approval-workflows/${id}`),
|
||||
setDefault: (id: number) => http.put(`/approval-workflows/${id}/default`),
|
||||
};
|
||||
const userListApi = () => http.get('/admin/users');
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* UserSelectInline */
|
||||
@@ -299,9 +290,9 @@ function WorkflowEditorModal({ workflow, users, onClose, onSaved }: EditorProps)
|
||||
})),
|
||||
};
|
||||
if (isEdit && workflow) {
|
||||
await workflowApi.update(workflow.id, payload);
|
||||
await approvalWorkflowApi.update(workflow.id, payload);
|
||||
} else {
|
||||
await workflowApi.create(payload);
|
||||
await approvalWorkflowApi.create(payload);
|
||||
}
|
||||
onSaved();
|
||||
} catch (e: unknown) {
|
||||
@@ -459,7 +450,7 @@ export default function ApprovalWorkflowPage() {
|
||||
try {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
const res: any = await workflowApi.list();
|
||||
const res: any = await approvalWorkflowApi.list();
|
||||
const data = Array.isArray(res?.list) ? res.list : (Array.isArray(res) ? res : []);
|
||||
const normalized = data.map((w: any) => ({ ...w, steps: w.steps || [] }));
|
||||
setItems(normalized);
|
||||
@@ -472,7 +463,7 @@ export default function ApprovalWorkflowPage() {
|
||||
|
||||
const fetchUsers = useCallback(async () => {
|
||||
try {
|
||||
const res: any = await userListApi();
|
||||
const res: any = await userApi.getUsers();
|
||||
const data = Array.isArray(res?.list) ? res.list : (Array.isArray(res) ? res : []);
|
||||
// Normalize: extract role code from roles array
|
||||
const normalized = data.map((u: any) => ({
|
||||
@@ -490,7 +481,7 @@ export default function ApprovalWorkflowPage() {
|
||||
|
||||
const toggleActive = useCallback(async (wf: WorkflowItem) => {
|
||||
try {
|
||||
await workflowApi.update(wf.id, { is_active: !wf.is_active });
|
||||
await approvalWorkflowApi.update(wf.id, { is_active: !wf.is_active });
|
||||
setItems((prev) => prev.map((w) => (w.id === wf.id ? { ...w, is_active: !w.is_active } : w)));
|
||||
toast.success(wf.is_active ? '已停用' : '已启用');
|
||||
} catch { toast.error('操作失败'); }
|
||||
@@ -499,7 +490,7 @@ export default function ApprovalWorkflowPage() {
|
||||
const handleDelete = useCallback(async (id: number, name: string) => {
|
||||
if (!window.confirm(`确定删除审批流程「${name}」?删除后不可恢复。`)) return;
|
||||
try {
|
||||
await workflowApi.delete(id);
|
||||
await approvalWorkflowApi.delete(id);
|
||||
setItems((prev) => prev.filter((w) => w.id !== id));
|
||||
toast.success('已删除');
|
||||
} catch { toast.error('删除失败'); }
|
||||
@@ -507,7 +498,7 @@ export default function ApprovalWorkflowPage() {
|
||||
|
||||
const setDefault = useCallback(async (id: number) => {
|
||||
try {
|
||||
await workflowApi.setDefault(id);
|
||||
await approvalWorkflowApi.setDefault(id);
|
||||
setItems((prev) => prev.map((w) => ({ ...w, is_default: w.id === id })));
|
||||
toast.success('已设为默认');
|
||||
} catch { toast.error('操作失败'); }
|
||||
|
||||
@@ -5,7 +5,7 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Activity, Search, Filter, BarChart3, Cpu, HardDrive, Network, Database, Plus } from 'lucide-react';
|
||||
import { http } from '@/services/http';
|
||||
import { metricsApi } from '@/services/api';
|
||||
|
||||
interface _MetricName {
|
||||
name: string;
|
||||
@@ -51,7 +51,7 @@ export function MetricsExplorer() {
|
||||
// Load targets
|
||||
const loadTargets = useCallback(async () => {
|
||||
try {
|
||||
const res: Record<string, any> = await http.get('/metrics/targets?page_size=200');
|
||||
const res: Record<string, any> = await metricsApi.getTargets({ page_size: 200 });
|
||||
setTargets(res?.list || []);
|
||||
} catch { /* empty */ }
|
||||
finally { setLoading(false); }
|
||||
@@ -60,7 +60,7 @@ export function MetricsExplorer() {
|
||||
// Load metric names
|
||||
const loadMetricNames = useCallback(async () => {
|
||||
try {
|
||||
const names: any = await http.get('/metrics/names');
|
||||
const names: any = await metricsApi.getNames();
|
||||
setMetricNames(names || []);
|
||||
} catch { /* empty */ }
|
||||
}, []);
|
||||
@@ -78,7 +78,7 @@ export function MetricsExplorer() {
|
||||
|
||||
Promise.all(
|
||||
selectedMetrics.map(mn =>
|
||||
http.get('/metrics/query', { target_id: selectedTarget, metric_name: mn, from: String(from), to: String(to), limit: 200 })
|
||||
metricsApi.query({ target_id: selectedTarget, metric_name: mn, from: String(from), to: String(to), limit: 200 })
|
||||
.then(( data: any) => (Array.isArray(data) ? data : []))
|
||||
.catch(() => [])
|
||||
)
|
||||
|
||||
@@ -3,7 +3,7 @@ import { useState, useEffect, useCallback } from 'react';
|
||||
import { Card, CardContent } from '@/components/ui/card';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { Database, Server, Activity, Loader2, Circle } from 'lucide-react';
|
||||
import { http } from '@/services/http';
|
||||
import { metricsApi } from '@/services/api';
|
||||
|
||||
interface TargetInfo {
|
||||
id: number;
|
||||
@@ -68,7 +68,7 @@ export function MiddlewareMonitor() {
|
||||
try {
|
||||
setLoading(true);
|
||||
setError('');
|
||||
const data = await http.get<TargetsResponse>('/metrics/targets', { type: 'middleware', page_size: 200 });
|
||||
const data = await metricsApi.getTargets({ type: 'middleware', page_size: 200 }) as TargetsResponse;
|
||||
setTargets(data?.list || []);
|
||||
} catch (err: any) {
|
||||
setError((err as Record<string, any>).message || '加载失败');
|
||||
|
||||
@@ -30,7 +30,7 @@ import {
|
||||
TableRow,
|
||||
} from '@/components/ui/table';
|
||||
import { Radio, Router, HardDrive, Plus, Trash2 } from 'lucide-react';
|
||||
import http from '@/services/http';
|
||||
import { snmpApi } from '@/services/api';
|
||||
|
||||
// ---------- types ----------
|
||||
interface SnmpStats {
|
||||
@@ -81,7 +81,7 @@ export function SNMPMonitor() {
|
||||
// ---------- data fetching ----------
|
||||
const loadStats = useCallback(async () => {
|
||||
try {
|
||||
const data = await http.get<SnmpStats>('/snmp/stats');
|
||||
const data = await snmpApi.getStats() as SnmpStats;
|
||||
setStats(data);
|
||||
} catch {
|
||||
// backend unavailable — leave defaults
|
||||
@@ -90,7 +90,7 @@ export function SNMPMonitor() {
|
||||
|
||||
const loadDevices = useCallback(async () => {
|
||||
try {
|
||||
const data = await http.get<DeviceListResponse>('/snmp/devices');
|
||||
const data = await snmpApi.getDevices() as DeviceListResponse;
|
||||
setDevices(data.list ?? []);
|
||||
} catch {
|
||||
setDevices([]);
|
||||
@@ -113,7 +113,7 @@ export function SNMPMonitor() {
|
||||
if (!form.name.trim() || !form.ip.trim()) return;
|
||||
setSubmitting(true);
|
||||
try {
|
||||
await http.post('/snmp/devices', {
|
||||
await snmpApi.createDevice({
|
||||
name: form.name.trim(),
|
||||
ip: form.ip.trim(),
|
||||
port: Number(form.port),
|
||||
@@ -133,7 +133,7 @@ export function SNMPMonitor() {
|
||||
|
||||
const handleDelete = async (id: number) => {
|
||||
try {
|
||||
await http.delete(`/snmp/devices/${id}`);
|
||||
await snmpApi.deleteDevice(id);
|
||||
refresh();
|
||||
} catch {
|
||||
// silently fail
|
||||
|
||||
Reference in new issue
Block a user