From bfed2369be7d603cbc1008185006daaeedb95721 Mon Sep 17 00:00:00 2001 From: qyyfw Date: Thu, 2 Jul 2026 23:06:24 +0800 Subject: [PATCH] fix: properly add KB admin API methods to api/index.ts --- frontend/src/api/index.ts | 1126 +++++++++++++++++++------------------ 1 file changed, 579 insertions(+), 547 deletions(-) diff --git a/frontend/src/api/index.ts b/frontend/src/api/index.ts index ab7e15f..5ab6548 100644 --- a/frontend/src/api/index.ts +++ b/frontend/src/api/index.ts @@ -1,547 +1,579 @@ -/** - * AIFlow API 客户端 - * 统一管理所有前后端API请求 - */ -const API_BASE = '/app/api'; - -// 从localStorage获取token -function getToken(): string | null { - return localStorage.getItem('aiflow_token'); -} - -// 通用请求方法 -async function request( - endpoint: string, - options: RequestInit = {} -): Promise<{ code: number; data: T; message: string }> { - const token = getToken(); - const headers: Record = { - 'Content-Type': 'application/json', - ...(options.headers as Record || {}), - }; - if (token) { - headers['Authorization'] = `Bearer ${token}`; - } - const res = await fetch(`${API_BASE}${endpoint}`, { - ...options, - headers, - }); - if (res.status === 401) { - // 登录接口的401需要精确提示(用户名不存在 / 密码错误) - if (endpoint === '/auth/login') { - const err = await res.json().catch(() => ({ detail: '登录失败' })); - const error: any = new Error(err.detail || '登录失败'); - error.status = 401; - error.detail = err.detail; - throw error; - } - // 其他接口的401 = token过期/未登录,清除状态并跳转 - localStorage.removeItem('aiflow_token'); - localStorage.removeItem('aiflow_user'); - window.location.hash = '#/login'; - throw new Error('未登录'); - } - if (!res.ok) { - const err = await res.json().catch(() => ({ detail: '请求失败' })); - const error: any = new Error(err.detail || err.message || '请求失败'); - error.status = res.status; - error.response = { status: res.status, data: err }; - error.detail = err.detail; - throw error; - } - return res.json(); -} - -// GET请求 -function get(endpoint: string): Promise<{ code: number; data: T; message: string }> { - return request(endpoint); -} - -// POST请求 -function post(endpoint: string, body?: any): Promise<{ code: number; data: T; message: string }> { - return request(endpoint, { - method: 'POST', - body: body ? JSON.stringify(body) : undefined, - }); -} - -// PUT请求 -function put(endpoint: string, body?: any): Promise<{ code: number; data: T; message: string }> { - return request(endpoint, { - method: 'PUT', - body: body ? JSON.stringify(body) : undefined, - }); -} - -// DELETE请求 -function del(endpoint: string): Promise<{ code: number; data: T; message: string }> { - return request(endpoint, { method: 'DELETE' }); -} - -// ============================================================ -// 认证相关API -// ============================================================ -export const authAPI = { - login: (username: string, password: string) => - post('/auth/login', { username, password }), - register: (data: { username: string; password: string; email?: string; phone?: string }) => - post('/auth/register', data), - getMe: () => get('/auth/me'), - logout: () => post('/auth/logout'), - getSettings: () => get('/auth/settings'), -}; - -// ============================================================ -// 聊天相关API -// ============================================================ -export const chatAPI = { - getConversations: (status?: string) => - get(`/chat/conversations${status ? `?status=${status}` : ''}`), - createConversation: (data: { title: string; model_id?: string }) => - post('/chat/conversations', data), - updateConversation: (id: string, data: any) => - put(`/chat/conversations/${id}`, data), - deleteConversation: (id: string) => - del(`/chat/conversations/${id}`), - getMessages: (convId: string) => - get(`/chat/conversations/${convId}/messages`), - sendMessage: (convId: string, data: { content: string; model_id?: string; agent_ids?: string[]; skill_ids?: string[]; knowledge_ids?: string[]; use_tools?: boolean }) => - post(`/chat/conversations/${convId}/messages`, data), - clearContext: (convId: string) => - post(`/chat/conversations/${convId}/clear`), - convertToKnowledgeGraph: (convId: string) => - post(`/chat/conversations/${convId}/to-knowledge-graph`), - getModels: () => get('/chat/models'), -}; - -// ============================================================ -// 频道相关API -// ============================================================ -export const channelAPI = { - getChannels: () => get('/channels/'), - createChannel: (data: any) => post('/channels/', data), - getChannel: (id: string) => get(`/channels/${id}`), - updateChannel: (id: string, data: any) => put(`/channels/${id}`, data), - deleteChannel: (id: string) => del(`/channels/${id}`), - connectChannel: (id: string) => post(`/channels/${id}/connect`), - disconnectChannel: (id: string) => post(`/channels/${id}/disconnect`), - getPlatformConfigs: () => get('/channels/platforms/config'), - webhookMessage: (id: string, data: { from_user: string; content: string; message_type?: string }) => - post(`/channels/${id}/webhook`, data), - getMembers: (id: string) => get(`/channels/${id}/members`), - addMember: (id: string, userId: string) => post(`/channels/${id}/members`, { user_id: userId }), - removeMember: (id: string, userId: string) => del(`/channels/${id}/members/${userId}`), - getMessages: (id: string, params?: { limit?: number; offset?: number }) => { - const sp = new URLSearchParams(); - if (params?.limit) sp.set('limit', String(params.limit)); - if (params?.offset) sp.set('offset', String(params.offset)); - const qs = sp.toString(); - return get(`/channels/${id}/messages${qs ? `?${qs}` : ''}`); - }, - sendMessage: (id: string, content: string) => post(`/channels/${id}/messages`, { content }), - authorize: (platform: string) => post('/channels/authorize', { platform }), - scanAuthorize: (platform: string, credentials?: Record) => post(`/channels/authorize/scan?platform=${platform}`, credentials ? { credentials } : {}), - scanAuthorizeStatus: (platform: string) => post(`/channels/authorize/scan/status?platform=${platform}`), -}; - -// ============================================================ -// 知识库相关API -// ============================================================ -export const knowledgeAPI = { - getBases: () => get('/knowledge/bases'), - createBase: (data: any) => post('/knowledge/bases', data), - getBase: (id: string) => get(`/knowledge/bases/${id}`), - updateBase: (id: string, data: any) => put(`/knowledge/bases/${id}`, data), - deleteBase: (id: string) => del(`/knowledge/bases/${id}`), - getDocuments: (baseId: string) => get(`/knowledge/bases/${baseId}/documents`), - getDocument: (baseId: string, docId: string) => get(`/knowledge/bases/${baseId}/documents/${docId}`), - uploadDocument: (baseId: string, data: any) => post(`/knowledge/bases/${baseId}/documents`, data), - deleteDocument: (baseId: string, docId: string) => del(`/knowledge/bases/${baseId}/documents/${docId}`), - getDirectories: () => get('/knowledge/directories'), - createDirectory: (data: any) => post('/knowledge/directories', data), - buildGraph: (baseId: string) => post(`/knowledge/bases/${baseId}/build-graph`), - getGraph: (baseId: string) => get(`/knowledge/bases/${baseId}/graph`), - searchQA: (baseId: string, question: string) => post('/knowledge/qa', { base_id: baseId, question }), - searchDocuments: (baseId: string, keyword: string) => get(`/knowledge/bases/${baseId}/search?keyword=${encodeURIComponent(keyword)}`), -}; - -// ============================================================ -// 应用市场相关API -// ============================================================ -export const marketAPI = { - getApps: (params?: { type?: string; source?: string; search?: string; page?: number; page_size?: number }) => { - const searchParams = new URLSearchParams(); - if (params?.type) searchParams.set('type', params.type); - if (params?.source) searchParams.set('source', params.source); - if (params?.search) searchParams.set('search', params.search); - if (params?.page) searchParams.set('page', String(params.page)); - if (params?.page_size) searchParams.set('page_size', String(params.page_size)); - const qs = searchParams.toString(); - return get(`/market/apps${qs ? `?${qs}` : ''}`); - }, - getApp: (id: string) => get(`/market/apps/${id}`), - createApp: (data: any) => post('/market/apps', data), - purchaseApp: (id: string) => post(`/market/apps/${id}/purchase`), - installApp: (id: string) => post(`/market/apps/${id}/install`), - uninstallApp: (id: string) => del(`/market/apps/${id}/uninstall`), - reviewApp: (id: string, data: { rating: number; content?: string }) => - post(`/market/apps/${id}/review`, data), - getMyApps: () => get('/market/my-apps'), - getReviews: (appId: string) => get(`/market/reviews/${appId}`), -}; - -// ============================================================ -// Token相关API -// ============================================================ -export const tokenAPI = { - getOverview: () => get('/token/overview'), - getRankings: () => get('/token/rankings'), - getLogs: (params?: any) => { - const sp = new URLSearchParams(); - if (params) Object.entries(params).forEach(([k, v]) => { if (v) sp.set(k, String(v)); }); - const qs = sp.toString(); - return get(`/token/logs${qs ? `?${qs}` : ''}`); - }, - getBalance: () => get('/token/balance'), - recharge: (amount: number) => post('/token/recharge', { amount }), -}; - -// ============================================================ -// 付费相关API -// ============================================================ -export const paymentAPI = { - getPlans: () => get('/payment/plans'), - createOrder: (data: any) => post('/payment/orders', data), - getOrders: (status?: string) => get(`/payment/orders${status ? `?status=${status}` : ''}`), - getOrder: (id: string) => get(`/payment/orders/${id}`), - payOrder: (id: string, method?: string) => post(`/payment/orders/${id}/pay`, { payment_method: method }), - getCoupons: () => get('/payment/coupons'), - useCoupon: (code: string) => post('/payment/coupons/use', { code }), - getServices: () => get('/payment/services'), - createCustomOrder: (data: any) => post('/payment/custom-services', data), - createServiceRequest: (data: any) => post('/payment/service-requests', data), -}; - -// ============================================================ -// 个人中心相关API -// ============================================================ -export const profileAPI = { - getProfile: () => get('/profile/'), - updateProfile: (data: any) => put('/profile/', data), - updatePassword: (data: { old_password: string; new_password: string }) => - put('/profile/password', data), - getLoginLogs: () => get('/profile/login-logs'), - getApiKeys: () => get('/profile/api-keys'), - createApiKey: (name?: string) => post('/profile/api-keys', { name }), - updateApiKey: (id: string, status: string) => put(`/profile/api-keys/${id}`, { status }), - getMembership: () => get('/profile/membership'), - getPurchasedApps: () => get('/profile/purchased-apps'), -}; - -// ============================================================ -// 通知相关API -// ============================================================ -export const notificationAPI = { - getNotifications: (params?: { type?: string; page?: number }) => { - const sp = new URLSearchParams(); - if (params?.type) sp.set('type', params.type); - if (params?.page) sp.set('page', String(params.page)); - const qs = sp.toString(); - return get(`/notifications/${qs ? `?${qs}` : ''}`); - }, - markRead: (id: string) => put(`/notifications/${id}/read`), - markAllRead: () => put('/notifications/read-all'), - getUnreadCount: () => get('/notifications/unread-count'), -}; - -// ============================================================ -// 资产管理相关API -// ============================================================ -export const assetsAPI = { - getAssets: (category?: string) => - get(`/assets/${category ? `?category=${category}` : ''}`), - createAsset: (data: any) => post('/assets/', data), - getAsset: (id: string) => get(`/assets/${id}`), - updateAsset: (id: string, data: any) => put(`/assets/${id}`, data), - deleteAsset: (id: string) => del(`/assets/${id}`), - getCategories: () => get('/assets/categories'), - getNovelChapters: (novelId: string) => get(`/assets/novels/${novelId}/chapters`), - addChapter: (novelId: string, data: any) => post(`/assets/novels/${novelId}/chapters`, data), -}; - -// ============================================================ -// 后台管理API -// ============================================================ -export const adminAPI = { - // 仪表盘 - getStats: () => get('/admin/dashboard/stats'), - getRecentLogs: () => get('/admin/dashboard/recent-logs'), - getRecentAudit: () => get('/admin/dashboard/recent-audit'), - // 用户管理 - getUsers: (params?: any) => { - const sp = new URLSearchParams(); - if (params) Object.entries(params).forEach(([k, v]) => { if (v) sp.set(k, String(v)); }); - return get(`/admin/users/${sp.toString() ? `?${sp.toString()}` : ''}`); - }, - getUser: (id: string) => get(`/admin/users/${id}`), - banUser: (id: string) => put(`/admin/users/${id}/ban`), - unbanUser: (id: string) => put(`/admin/users/${id}/unban`), - getRegisterSettings: () => get('/admin/users/register-settings'), - updateRegisterSettings: (data: any) => put('/admin/users/register-settings', data), - // 模型管理 - getProviders: () => get('/admin/models/providers'), - addProvider: (data: any) => post('/admin/models/providers', data), - updateProvider: (id: string, data: any) => put(`/admin/models/providers/${id}`, data), - deleteProvider: (id: string) => del(`/admin/models/providers/${id}`), - fetchModels: (id: string) => post(`/admin/models/providers/${id}/fetch-models`), - addModels: (id: string, modelIds: string[]) => post(`/admin/models/providers/${id}/add-models`, { model_ids: modelIds }), - getProtocols: () => get('/admin/models/protocols'), - getAdminModels: (params?: any) => { - const sp = new URLSearchParams(); - if (params) Object.entries(params).forEach(([k, v]) => { if (v) sp.set(k, String(v)); }); - return get(`/admin/models/${sp.toString() ? `?${sp.toString()}` : ''}`); - }, - addModel: (data: any) => post('/admin/models/', data), - updateModel: (id: string, data: any) => put(`/admin/models/${id}`, data), - deleteModel: (id: string) => del(`/admin/models/${id}`), - toggleModel: (id: string, isEnabled: boolean) => put(`/admin/models/${id}/toggle?is_enabled=${isEnabled}`), - setDefaultModel: (id: string) => put(`/admin/models/${id}/set-default`), - // Phase 2: Enhanced model management - testModelConnection: (id: string) => post(`/admin/models/${id}/test-connection`), - fetchProviderModels: (id: string) => post(`/admin/models/providers/${id}/fetch-models`), - createAdminModel: (data: any) => post('/admin/models/', data), - updateAdminModel: (id: string, data: any) => put(`/admin/models/${id}`, data), - deleteAdminModel: (id: string) => del(`/admin/models/${id}`), - getModelStats: () => get('/admin/models/stats'), - // 网站设置 - getSiteSettings: () => get('/admin/settings/site'), - updateSiteSettings: (data: any) => put('/admin/settings/site', data), - getEmailConfig: () => get('/admin/settings/email'), - updateEmailConfig: (data: any) => put('/admin/settings/email', data), - testEmail: (params?: { test_to?: string; test_subject?: string; test_body?: string }) => { - const qs = new URLSearchParams(); - if (params?.test_to) qs.set('test_to', params.test_to); - if (params?.test_subject) qs.set('test_subject', params.test_subject); - if (params?.test_body) qs.set('test_body', params.test_body); - const qstr = qs.toString(); - return post(`/admin/settings/email/test${qstr ? `?${qstr}` : ''}`); - }, - generateEmailContent: (topic: string) => post(`/admin/settings/email/generate-content?topic=${encodeURIComponent(topic)}`), - getSmsConfig: () => get('/admin/settings/sms'), - updateSmsConfig: (data: any) => put('/admin/settings/sms', data), - testSms: () => post('/admin/settings/sms/test'), - // 支付配置 - getPaymentConfigs: () => get('/admin/payment/configs'), - updatePaymentConfig: (id: string, data: any) => put(`/admin/payment/configs/${id}`, data), - getAdminOrders: (params?: any) => { - const sp = new URLSearchParams(); - if (params) Object.entries(params).forEach(([k, v]) => { if (v) sp.set(k, String(v)); }); - return get(`/admin/payment/orders${sp.toString() ? `?${sp.toString()}` : ''}`); - }, - refundOrder: (id: string) => put(`/admin/payment/orders/${id}/refund`), - // 增值服务 - getServices: (params?: any) => { - const sp = new URLSearchParams(); - if (params) Object.entries(params).forEach(([k, v]) => { if (v) sp.set(k, String(v)); }); - return get(`/admin/services/${sp.toString() ? `?${sp.toString()}` : ''}`); - }, - addService: (data: any) => post('/admin/services/', data), - updateService: (id: string, data: any) => put(`/admin/services/${id}`, data), - deleteService: (id: string) => del(`/admin/services/${id}`), - getCustomOrders: (status?: string) => get(`/admin/services/custom-orders${status ? `?status=${status}` : ''}`), - updateCustomOrder: (id: string, data: any) => put(`/admin/services/custom-orders/${id}`, data), - getCustomRequests: (params?: any) => { - const sp = new URLSearchParams(); - if (params) Object.entries(params).forEach(([k, v]) => { if (v) sp.set(k, String(v)); }); - return get(`/admin/services/custom-requests${sp.toString() ? `?${sp.toString()}` : ''}`); - }, - updateCustomRequest: (id: string, data: any) => put(`/admin/services/custom-requests/${id}`, data), - getAvailableAgents: () => get('/admin/services/agents'), - assignAgentToService: (id: string, agentId: string) => put(`/admin/services/${id}/agent?agent_id=${agentId}`), - // 会员管理 - getPlans: () => get('/admin/membership/plans'), - addPlan: (data: any) => post('/admin/membership/plans', data), - updatePlan: (id: string, data: any) => put(`/admin/membership/plans/${id}`, data), - deletePlan: (id: string) => del(`/admin/membership/plans/${id}`), - getSubscriptions: () => get('/admin/membership/subscriptions'), - getAutomationRules: () => get('/admin/membership/automation-rules'), - // 广告管理 - getAds: () => get('/admin/ads/'), - addAd: (data: any) => post('/admin/ads/', data), - updateAd: (id: string, data: any) => put(`/admin/ads/${id}`, data), - deleteAd: (id: string) => del(`/admin/ads/${id}`), - toggleAd: (id: string) => put(`/admin/ads/${id}/toggle`), - // 应用市场审核 - getPendingApps: () => get('/admin/market/apps/pending'), - approveApp: (id: string) => put(`/admin/market/apps/${id}/approve`), - rejectApp: (id: string) => put(`/admin/market/apps/${id}/reject`), - getAdminApps: () => get('/admin/market/apps'), - updateApp: (id: string, data: any) => put(`/admin/market/apps/${id}`, data), - getCoupons: () => get('/admin/market/coupons'), - addCoupon: (data: any) => post('/admin/market/coupons', data), - updateCoupon: (id: string, data: any) => put(`/admin/market/coupons/${id}`, data), - deleteCoupon: (id: string) => del(`/admin/market/coupons/${id}`), - assignCoupon: (id: string, userId: string) => post(`/admin/market/coupons/${id}/assign`, { user_id: userId }), - // 日志与风控 - getOperationLogs: (params?: any) => { - const sp = new URLSearchParams(); - if (params) Object.entries(params).forEach(([k, v]) => { if (v) sp.set(k, String(v)); }); - return get(`/admin/logs/operations${sp.toString() ? `?${sp.toString()}` : ''}`); - }, - getTokenLogs: (params?: any) => { - const sp = new URLSearchParams(); - if (params) Object.entries(params).forEach(([k, v]) => { if (v) sp.set(k, String(v)); }); - return get(`/admin/logs/token-logs${sp.toString() ? `?${sp.toString()}` : ''}`); - }, - getPaymentLogs: (params?: any) => { - const sp = new URLSearchParams(); - if (params) Object.entries(params).forEach(([k, v]) => { if (v) sp.set(k, String(v)); }); - return get(`/admin/logs/payment-logs${sp.toString() ? `?${sp.toString()}` : ''}`); - }, - getAuditLogs: (params?: any) => { - const sp = new URLSearchParams(); - if (params) Object.entries(params).forEach(([k, v]) => { if (v) sp.set(k, String(v)); }); - return get(`/admin/logs/audit-logs${sp.toString() ? `?${sp.toString()}` : ''}`); - }, - // 新增:日志统计 - getLogStats: () => get('/admin/logs/stats'), - // 新增:API调用统计 - getApiStats: (params?: any) => { - const sp = new URLSearchParams(); - if (params) Object.entries(params).forEach(([k, v]) => { if (v) sp.set(k, String(v)); }); - return get(`/admin/logs/api-stats${sp.toString() ? `?${sp.toString()}` : ''}`); - }, - // 新增:慢请求记录 - getSlowRequests: (params?: any) => { - const sp = new URLSearchParams(); - if (params) Object.entries(params).forEach(([k, v]) => { if (v) sp.set(k, String(v)); }); - return get(`/admin/logs/slow-requests${sp.toString() ? `?${sp.toString()}` : ''}`); - }, - // 新增:操作类型枚举 - getActionTypes: () => get('/admin/logs/action-types'), - // 新增:审计日志导出 - exportAuditLogs: (params?: any) => { - const sp = new URLSearchParams(); - if (params) Object.entries(params).forEach(([k, v]) => { if (v) sp.set(k, String(v)); }); - return get(`/admin/logs/export/audit-logs${sp.toString() ? `?${sp.toString()}` : ''}`); - }, - exportOperationLogs: (params?: any) => { - const sp = new URLSearchParams(); - if (params) Object.entries(params).forEach(([k, v]) => { if (v) sp.set(k, String(v)); }); - return get(`/admin/logs/export/operations${sp.toString() ? `?${sp.toString()}` : ''}`); - }, - exportTokenLogs: (params?: any) => { - const sp = new URLSearchParams(); - if (params) Object.entries(params).forEach(([k, v]) => { if (v) sp.set(k, String(v)); }); - return get(`/admin/logs/export/token-logs${sp.toString() ? `?${sp.toString()}` : ''}`); - }, - getRiskRules: () => get('/admin/logs/risk-rules'), - addRiskRule: (data: any) => post('/admin/logs/risk-rules', data), - updateRiskRule: (id: string, data: any) => put(`/admin/logs/risk-rules/${id}`, data), - deleteRiskRule: (id: string) => del(`/admin/logs/risk-rules/${id}`), - // 技能管理 (Phase 2.2) - getAdminSkills: (params?: any) => { - const sp = new URLSearchParams(); - if (params) Object.entries(params).forEach(([k, v]) => { if (v !== undefined && v !== null && v !== '') sp.set(k, String(v)); }); - return get(`/admin/skills/${sp.toString() ? `?${sp.toString()}` : ''}`); - }, - getAdminSkill: (id: string) => get(`/admin/skills/${id}`), - createAdminSkill: (data: any) => post('/admin/skills/', data), - updateAdminSkill: (id: string, data: any) => put(`/admin/skills/${id}`, data), - deleteAdminSkill: (id: string) => del(`/admin/skills/${id}`), - changeAdminSkillState: (id: string, data: any) => put(`/admin/skills/${id}/state`, data), - getAdminSkillVersions: (id: string) => get(`/admin/skills/${id}/versions`), - rollbackAdminSkill: (id: string, data: any) => post(`/admin/skills/${id}/rollback`, data), - publishAdminSkill: (id: string, data: any) => post(`/admin/skills/${id}/publish`, data), - unpublishAdminSkill: (id: string) => post(`/admin/skills/${id}/unpublish`), - getAdminSkillsStats: () => get('/admin/skills/stats/overview'), - // Agent管理 (Phase 2.3) - getAdminAgents: (params?: any) => { - const sp = new URLSearchParams(); - if (params) Object.entries(params).forEach(([k, v]) => { if (v !== undefined && v !== null && v !== '') sp.set(k, String(v)); }); - return get(`/admin/agents/${sp.toString() ? `?${sp.toString()}` : ''}`); - }, - getAdminAgent: (id: string) => get(`/admin/agents/${id}`), - createAdminAgent: (data: any) => post('/admin/agents/', data), - updateAdminAgent: (id: string, data: any) => put(`/admin/agents/${id}`, data), - deleteAdminAgent: (id: string) => del(`/admin/agents/${id}`), - toggleAdminAgent: (id: string, isActive: boolean) => put(`/admin/agents/${id}/toggle`, { is_active: isActive }), - getAdminAgentsStats: () => get('/admin/agents/stats/overview'), - getAdminAgentReviews: (id: string) => get(`/admin/agents/${id}/reviews`), - getAdminAvailableSkills: (params?: any) => { - const sp = new URLSearchParams(); - if (params) Object.entries(params).forEach(([k, v]) => { if (v !== undefined && v !== null && v !== '') sp.set(k, String(v)); }); - return get(`/admin/agents/available/skills${sp.toString() ? `?${sp.toString()}` : ''}`); - }, - getAdminAvailableModels: () => get('/admin/agents/available/models'), -}; -// ===== AI自进化API ===== -export const evolutionAPI = { - // 驾驶舱面板 - getSkillTree: () => get('/evolution/dashboard/skill-tree'), - getTimeline: (eventType?: string) => - get('/evolution/dashboard/timeline' + (eventType ? `?event_type=${eventType}` : '')), - getStatistics: () => get('/evolution/dashboard/statistics'), - getProfile: () => get('/evolution/dashboard/profile'), - - // 技能管理 - getSkills: (params?: { state?: string; keyword?: string; sort_by?: string; order?: string }) => { - const query = new URLSearchParams(); - if (params?.state) query.append('state', params.state); - if (params?.keyword) query.append('keyword', params.keyword); - if (params?.sort_by) query.append('sort_by', params.sort_by); - if (params?.order) query.append('order', params.order); - const qs = query.toString(); - return get('/evolution/skills' + (qs ? `?${qs}` : '')); - }, - getSkillDetail: (name: string) => get(`/evolution/skills/${encodeURIComponent(name)}`), - updateSkill: (name: string, data: { description?: string; tags?: string[]; category?: string }) => - put(`/evolution/skills/${encodeURIComponent(name)}`, data), - deleteSkill: (name: string) => del(`/evolution/skills/${encodeURIComponent(name)}`), - freezeSkill: (name: string) => post(`/evolution/skills/${encodeURIComponent(name)}/freeze`), - unfreezeSkill: (name: string) => post(`/evolution/skills/${encodeURIComponent(name)}/unfreeze`), - getSkillHistory: (name: string) => get(`/evolution/skills/${encodeURIComponent(name)}/history`), - getSkillTrajectories: (name: string) => get(`/evolution/skills/${encodeURIComponent(name)}/trajectories`), - - // 事件 - getEvents: (params?: { event_type?: string; skill_name?: string; limit?: number }) => { - const query = new URLSearchParams(); - if (params?.event_type) query.append('event_type', params.event_type); - if (params?.skill_name) query.append('skill_name', params.skill_name); - if (params?.limit) query.append('limit', String(params.limit)); - const qs = query.toString(); - return get('/evolution/events' + (qs ? `?${qs}` : '')); - }, - - // 轨迹提交 - submitTrajectory: (data: { conversation_id: string; messages: any[] }) => - post('/evolution/trajectory/submit', data), - - // v2: 技能回滚 - rollbackSkill: (skillName: string, version: number) => - post(`/evolution/skills/${encodeURIComponent(skillName)}/rollback/${version}`), - - // v2: 发布到市场 - publishSkill: (skillName: string, data: { price: number; market_description: string }) => - post(`/evolution/skills/${encodeURIComponent(skillName)}/publish`, data), - - // v2: 团队共享 - shareToTeam: (skillName: string, teamId: string) => - post(`/evolution/skills/${encodeURIComponent(skillName)}/share-to-team`, { team_id: teamId }), - - // v2: 流水线状态 - getPipelineStatus: () => get('/evolution/pipeline/status'), - - // v2: 手动触发流水线 - triggerPipeline: () => post('/evolution/pipeline/trigger'), - - // v2: Watcher状态 - getWatcherStatus: () => get('/evolution/watcher/status'), - - // v2: 进化报告 - getReports: (reportType?: string) => { - const qs = reportType ? `?report_type=${reportType}` : ''; - return get(`/evolution/reports${qs}`); - }, - getReportDetail: (reportId: string) => get(`/evolution/reports/${reportId}`), -}; +/** + * AIFlow API 客户端 + * 统一管理所有前后端API请求 + */ +const API_BASE = '/app/api'; + +// 从localStorage获取token +function getToken(): string | null { + return localStorage.getItem('aiflow_token'); +} + +// 通用请求方法 +async function request( + endpoint: string, + options: RequestInit = {} +): Promise<{ code: number; data: T; message: string }> { + const token = getToken(); + const headers: Record = { + 'Content-Type': 'application/json', + ...(options.headers as Record || {}), + }; + if (token) { + headers['Authorization'] = `Bearer ${token}`; + } + const res = await fetch(`${API_BASE}${endpoint}`, { + ...options, + headers, + }); + if (res.status === 401) { + // 登录接口的401需要精确提示(用户名不存在 / 密码错误) + if (endpoint === '/auth/login') { + const err = await res.json().catch(() => ({ detail: '登录失败' })); + const error: any = new Error(err.detail || '登录失败'); + error.status = 401; + error.detail = err.detail; + throw error; + } + // 其他接口的401 = token过期/未登录,清除状态并跳转 + localStorage.removeItem('aiflow_token'); + localStorage.removeItem('aiflow_user'); + window.location.hash = '#/login'; + throw new Error('未登录'); + } + if (!res.ok) { + const err = await res.json().catch(() => ({ detail: '请求失败' })); + const error: any = new Error(err.detail || err.message || '请求失败'); + error.status = res.status; + error.response = { status: res.status, data: err }; + error.detail = err.detail; + throw error; + } + return res.json(); +} + +// GET请求 +function get(endpoint: string): Promise<{ code: number; data: T; message: string }> { + return request(endpoint); +} + +// POST请求 +function post(endpoint: string, body?: any): Promise<{ code: number; data: T; message: string }> { + return request(endpoint, { + method: 'POST', + body: body ? JSON.stringify(body) : undefined, + }); +} + +// PUT请求 +function put(endpoint: string, body?: any): Promise<{ code: number; data: T; message: string }> { + return request(endpoint, { + method: 'PUT', + body: body ? JSON.stringify(body) : undefined, + }); +} + +// DELETE请求 +function del(endpoint: string): Promise<{ code: number; data: T; message: string }> { + return request(endpoint, { method: 'DELETE' }); +} + +// ============================================================ +// 认证相关API +// ============================================================ +export const authAPI = { + login: (username: string, password: string) => + post('/auth/login', { username, password }), + register: (data: { username: string; password: string; email?: string; phone?: string }) => + post('/auth/register', data), + getMe: () => get('/auth/me'), + logout: () => post('/auth/logout'), + getSettings: () => get('/auth/settings'), +}; + +// ============================================================ +// 聊天相关API +// ============================================================ +export const chatAPI = { + getConversations: (status?: string) => + get(`/chat/conversations${status ? `?status=${status}` : ''}`), + createConversation: (data: { title: string; model_id?: string }) => + post('/chat/conversations', data), + updateConversation: (id: string, data: any) => + put(`/chat/conversations/${id}`, data), + deleteConversation: (id: string) => + del(`/chat/conversations/${id}`), + getMessages: (convId: string) => + get(`/chat/conversations/${convId}/messages`), + sendMessage: (convId: string, data: { content: string; model_id?: string; agent_ids?: string[]; skill_ids?: string[]; knowledge_ids?: string[]; use_tools?: boolean }) => + post(`/chat/conversations/${convId}/messages`, data), + clearContext: (convId: string) => + post(`/chat/conversations/${convId}/clear`), + convertToKnowledgeGraph: (convId: string) => + post(`/chat/conversations/${convId}/to-knowledge-graph`), + getModels: () => get('/chat/models'), +}; + +// ============================================================ +// 频道相关API +// ============================================================ +export const channelAPI = { + getChannels: () => get('/channels/'), + createChannel: (data: any) => post('/channels/', data), + getChannel: (id: string) => get(`/channels/${id}`), + updateChannel: (id: string, data: any) => put(`/channels/${id}`, data), + deleteChannel: (id: string) => del(`/channels/${id}`), + connectChannel: (id: string) => post(`/channels/${id}/connect`), + disconnectChannel: (id: string) => post(`/channels/${id}/disconnect`), + getPlatformConfigs: () => get('/channels/platforms/config'), + webhookMessage: (id: string, data: { from_user: string; content: string; message_type?: string }) => + post(`/channels/${id}/webhook`, data), + getMembers: (id: string) => get(`/channels/${id}/members`), + addMember: (id: string, userId: string) => post(`/channels/${id}/members`, { user_id: userId }), + removeMember: (id: string, userId: string) => del(`/channels/${id}/members/${userId}`), + getMessages: (id: string, params?: { limit?: number; offset?: number }) => { + const sp = new URLSearchParams(); + if (params?.limit) sp.set('limit', String(params.limit)); + if (params?.offset) sp.set('offset', String(params.offset)); + const qs = sp.toString(); + return get(`/channels/${id}/messages${qs ? `?${qs}` : ''}`); + }, + sendMessage: (id: string, content: string) => post(`/channels/${id}/messages`, { content }), + authorize: (platform: string) => post('/channels/authorize', { platform }), + scanAuthorize: (platform: string, credentials?: Record) => post(`/channels/authorize/scan?platform=${platform}`, credentials ? { credentials } : {}), + scanAuthorizeStatus: (platform: string) => post(`/channels/authorize/scan/status?platform=${platform}`), +}; + +// ============================================================ +// 知识库相关API +// ============================================================ +export const knowledgeAPI = { + getBases: () => get('/knowledge/bases'), + createBase: (data: any) => post('/knowledge/bases', data), + getBase: (id: string) => get(`/knowledge/bases/${id}`), + updateBase: (id: string, data: any) => put(`/knowledge/bases/${id}`, data), + deleteBase: (id: string) => del(`/knowledge/bases/${id}`), + getDocuments: (baseId: string) => get(`/knowledge/bases/${baseId}/documents`), + getDocument: (baseId: string, docId: string) => get(`/knowledge/bases/${baseId}/documents/${docId}`), + uploadDocument: (baseId: string, data: any) => post(`/knowledge/bases/${baseId}/documents`, data), + deleteDocument: (baseId: string, docId: string) => del(`/knowledge/bases/${baseId}/documents/${docId}`), + getDirectories: () => get('/knowledge/directories'), + createDirectory: (data: any) => post('/knowledge/directories', data), + buildGraph: (baseId: string) => post(`/knowledge/bases/${baseId}/build-graph`), + getGraph: (baseId: string) => get(`/knowledge/bases/${baseId}/graph`), + searchQA: (baseId: string, question: string) => post('/knowledge/qa', { base_id: baseId, question }), + searchDocuments: (baseId: string, keyword: string) => get(`/knowledge/bases/${baseId}/search?keyword=${encodeURIComponent(keyword)}`), +}; + +// ============================================================ +// 应用市场相关API +// ============================================================ +export const marketAPI = { + getApps: (params?: { type?: string; source?: string; search?: string; page?: number; page_size?: number }) => { + const searchParams = new URLSearchParams(); + if (params?.type) searchParams.set('type', params.type); + if (params?.source) searchParams.set('source', params.source); + if (params?.search) searchParams.set('search', params.search); + if (params?.page) searchParams.set('page', String(params.page)); + if (params?.page_size) searchParams.set('page_size', String(params.page_size)); + const qs = searchParams.toString(); + return get(`/market/apps${qs ? `?${qs}` : ''}`); + }, + getApp: (id: string) => get(`/market/apps/${id}`), + createApp: (data: any) => post('/market/apps', data), + purchaseApp: (id: string) => post(`/market/apps/${id}/purchase`), + installApp: (id: string) => post(`/market/apps/${id}/install`), + uninstallApp: (id: string) => del(`/market/apps/${id}/uninstall`), + reviewApp: (id: string, data: { rating: number; content?: string }) => + post(`/market/apps/${id}/review`, data), + getMyApps: () => get('/market/my-apps'), + getReviews: (appId: string) => get(`/market/reviews/${appId}`), +}; + +// ============================================================ +// Token相关API +// ============================================================ +export const tokenAPI = { + getOverview: () => get('/token/overview'), + getRankings: () => get('/token/rankings'), + getLogs: (params?: any) => { + const sp = new URLSearchParams(); + if (params) Object.entries(params).forEach(([k, v]) => { if (v) sp.set(k, String(v)); }); + const qs = sp.toString(); + return get(`/token/logs${qs ? `?${qs}` : ''}`); + }, + getBalance: () => get('/token/balance'), + recharge: (amount: number) => post('/token/recharge', { amount }), +}; + +// ============================================================ +// 付费相关API +// ============================================================ +export const paymentAPI = { + getPlans: () => get('/payment/plans'), + createOrder: (data: any) => post('/payment/orders', data), + getOrders: (status?: string) => get(`/payment/orders${status ? `?status=${status}` : ''}`), + getOrder: (id: string) => get(`/payment/orders/${id}`), + payOrder: (id: string, method?: string) => post(`/payment/orders/${id}/pay`, { payment_method: method }), + getCoupons: () => get('/payment/coupons'), + useCoupon: (code: string) => post('/payment/coupons/use', { code }), + getServices: () => get('/payment/services'), + createCustomOrder: (data: any) => post('/payment/custom-services', data), + createServiceRequest: (data: any) => post('/payment/service-requests', data), +}; + +// ============================================================ +// 个人中心相关API +// ============================================================ +export const profileAPI = { + getProfile: () => get('/profile/'), + updateProfile: (data: any) => put('/profile/', data), + updatePassword: (data: { old_password: string; new_password: string }) => + put('/profile/password', data), + getLoginLogs: () => get('/profile/login-logs'), + getApiKeys: () => get('/profile/api-keys'), + createApiKey: (name?: string) => post('/profile/api-keys', { name }), + updateApiKey: (id: string, status: string) => put(`/profile/api-keys/${id}`, { status }), + getMembership: () => get('/profile/membership'), + getPurchasedApps: () => get('/profile/purchased-apps'), +}; + +// ============================================================ +// 通知相关API +// ============================================================ +export const notificationAPI = { + getNotifications: (params?: { type?: string; page?: number }) => { + const sp = new URLSearchParams(); + if (params?.type) sp.set('type', params.type); + if (params?.page) sp.set('page', String(params.page)); + const qs = sp.toString(); + return get(`/notifications/${qs ? `?${qs}` : ''}`); + }, + markRead: (id: string) => put(`/notifications/${id}/read`), + markAllRead: () => put('/notifications/read-all'), + getUnreadCount: () => get('/notifications/unread-count'), +}; + +// ============================================================ +// 资产管理相关API +// ============================================================ +export const assetsAPI = { + getAssets: (category?: string) => + get(`/assets/${category ? `?category=${category}` : ''}`), + createAsset: (data: any) => post('/assets/', data), + getAsset: (id: string) => get(`/assets/${id}`), + updateAsset: (id: string, data: any) => put(`/assets/${id}`, data), + deleteAsset: (id: string) => del(`/assets/${id}`), + getCategories: () => get('/assets/categories'), + getNovelChapters: (novelId: string) => get(`/assets/novels/${novelId}/chapters`), + addChapter: (novelId: string, data: any) => post(`/assets/novels/${novelId}/chapters`, data), +}; + +// ============================================================ +// 后台管理API +// ============================================================ +export const adminAPI = { + // 仪表盘 + getStats: () => get('/admin/dashboard/stats'), + getRecentLogs: () => get('/admin/dashboard/recent-logs'), + getRecentAudit: () => get('/admin/dashboard/recent-audit'), + // 用户管理 + getUsers: (params?: any) => { + const sp = new URLSearchParams(); + if (params) Object.entries(params).forEach(([k, v]) => { if (v) sp.set(k, String(v)); }); + return get(`/admin/users/${sp.toString() ? `?${sp.toString()}` : ''}`); + }, + getUser: (id: string) => get(`/admin/users/${id}`), + banUser: (id: string) => put(`/admin/users/${id}/ban`), + unbanUser: (id: string) => put(`/admin/users/${id}/unban`), + getRegisterSettings: () => get('/admin/users/register-settings'), + updateRegisterSettings: (data: any) => put('/admin/users/register-settings', data), + // 模型管理 + getProviders: () => get('/admin/models/providers'), + addProvider: (data: any) => post('/admin/models/providers', data), + updateProvider: (id: string, data: any) => put(`/admin/models/providers/${id}`, data), + deleteProvider: (id: string) => del(`/admin/models/providers/${id}`), + fetchModels: (id: string) => post(`/admin/models/providers/${id}/fetch-models`), + addModels: (id: string, modelIds: string[]) => post(`/admin/models/providers/${id}/add-models`, { model_ids: modelIds }), + getProtocols: () => get('/admin/models/protocols'), + getAdminModels: (params?: any) => { + const sp = new URLSearchParams(); + if (params) Object.entries(params).forEach(([k, v]) => { if (v) sp.set(k, String(v)); }); + return get(`/admin/models/${sp.toString() ? `?${sp.toString()}` : ''}`); + }, + addModel: (data: any) => post('/admin/models/', data), + updateModel: (id: string, data: any) => put(`/admin/models/${id}`, data), + deleteModel: (id: string) => del(`/admin/models/${id}`), + toggleModel: (id: string, isEnabled: boolean) => put(`/admin/models/${id}/toggle?is_enabled=${isEnabled}`), + setDefaultModel: (id: string) => put(`/admin/models/${id}/set-default`), + // Phase 2: Enhanced model management + testModelConnection: (id: string) => post(`/admin/models/${id}/test-connection`), + fetchProviderModels: (id: string) => post(`/admin/models/providers/${id}/fetch-models`), + createAdminModel: (data: any) => post('/admin/models/', data), + updateAdminModel: (id: string, data: any) => put(`/admin/models/${id}`, data), + deleteAdminModel: (id: string) => del(`/admin/models/${id}`), + getModelStats: () => get('/admin/models/stats'), + // 网站设置 + getSiteSettings: () => get('/admin/settings/site'), + updateSiteSettings: (data: any) => put('/admin/settings/site', data), + getEmailConfig: () => get('/admin/settings/email'), + updateEmailConfig: (data: any) => put('/admin/settings/email', data), + testEmail: (params?: { test_to?: string; test_subject?: string; test_body?: string }) => { + const qs = new URLSearchParams(); + if (params?.test_to) qs.set('test_to', params.test_to); + if (params?.test_subject) qs.set('test_subject', params.test_subject); + if (params?.test_body) qs.set('test_body', params.test_body); + const qstr = qs.toString(); + return post(`/admin/settings/email/test${qstr ? `?${qstr}` : ''}`); + }, + generateEmailContent: (topic: string) => post(`/admin/settings/email/generate-content?topic=${encodeURIComponent(topic)}`), + getSmsConfig: () => get('/admin/settings/sms'), + updateSmsConfig: (data: any) => put('/admin/settings/sms', data), + testSms: () => post('/admin/settings/sms/test'), + // 支付配置 + getPaymentConfigs: () => get('/admin/payment/configs'), + updatePaymentConfig: (id: string, data: any) => put(`/admin/payment/configs/${id}`, data), + getAdminOrders: (params?: any) => { + const sp = new URLSearchParams(); + if (params) Object.entries(params).forEach(([k, v]) => { if (v) sp.set(k, String(v)); }); + return get(`/admin/payment/orders${sp.toString() ? `?${sp.toString()}` : ''}`); + }, + refundOrder: (id: string) => put(`/admin/payment/orders/${id}/refund`), + // 增值服务 + getServices: (params?: any) => { + const sp = new URLSearchParams(); + if (params) Object.entries(params).forEach(([k, v]) => { if (v) sp.set(k, String(v)); }); + return get(`/admin/services/${sp.toString() ? `?${sp.toString()}` : ''}`); + }, + addService: (data: any) => post('/admin/services/', data), + updateService: (id: string, data: any) => put(`/admin/services/${id}`, data), + deleteService: (id: string) => del(`/admin/services/${id}`), + getCustomOrders: (status?: string) => get(`/admin/services/custom-orders${status ? `?status=${status}` : ''}`), + updateCustomOrder: (id: string, data: any) => put(`/admin/services/custom-orders/${id}`, data), + getCustomRequests: (params?: any) => { + const sp = new URLSearchParams(); + if (params) Object.entries(params).forEach(([k, v]) => { if (v) sp.set(k, String(v)); }); + return get(`/admin/services/custom-requests${sp.toString() ? `?${sp.toString()}` : ''}`); + }, + updateCustomRequest: (id: string, data: any) => put(`/admin/services/custom-requests/${id}`, data), + getAvailableAgents: () => get('/admin/services/agents'), + assignAgentToService: (id: string, agentId: string) => put(`/admin/services/${id}/agent?agent_id=${agentId}`), + // 会员管理 + getPlans: () => get('/admin/membership/plans'), + addPlan: (data: any) => post('/admin/membership/plans', data), + updatePlan: (id: string, data: any) => put(`/admin/membership/plans/${id}`, data), + deletePlan: (id: string) => del(`/admin/membership/plans/${id}`), + getSubscriptions: () => get('/admin/membership/subscriptions'), + getAutomationRules: () => get('/admin/membership/automation-rules'), + // 广告管理 + getAds: () => get('/admin/ads/'), + addAd: (data: any) => post('/admin/ads/', data), + updateAd: (id: string, data: any) => put(`/admin/ads/${id}`, data), + deleteAd: (id: string) => del(`/admin/ads/${id}`), + toggleAd: (id: string) => put(`/admin/ads/${id}/toggle`), + // 应用市场审核 + getPendingApps: () => get('/admin/market/apps/pending'), + approveApp: (id: string) => put(`/admin/market/apps/${id}/approve`), + rejectApp: (id: string) => put(`/admin/market/apps/${id}/reject`), + getAdminApps: () => get('/admin/market/apps'), + updateApp: (id: string, data: any) => put(`/admin/market/apps/${id}`, data), + getCoupons: () => get('/admin/market/coupons'), + addCoupon: (data: any) => post('/admin/market/coupons', data), + updateCoupon: (id: string, data: any) => put(`/admin/market/coupons/${id}`, data), + deleteCoupon: (id: string) => del(`/admin/market/coupons/${id}`), + assignCoupon: (id: string, userId: string) => post(`/admin/market/coupons/${id}/assign`, { user_id: userId }), + // 日志与风控 + getOperationLogs: (params?: any) => { + const sp = new URLSearchParams(); + if (params) Object.entries(params).forEach(([k, v]) => { if (v) sp.set(k, String(v)); }); + return get(`/admin/logs/operations${sp.toString() ? `?${sp.toString()}` : ''}`); + }, + getTokenLogs: (params?: any) => { + const sp = new URLSearchParams(); + if (params) Object.entries(params).forEach(([k, v]) => { if (v) sp.set(k, String(v)); }); + return get(`/admin/logs/token-logs${sp.toString() ? `?${sp.toString()}` : ''}`); + }, + getPaymentLogs: (params?: any) => { + const sp = new URLSearchParams(); + if (params) Object.entries(params).forEach(([k, v]) => { if (v) sp.set(k, String(v)); }); + return get(`/admin/logs/payment-logs${sp.toString() ? `?${sp.toString()}` : ''}`); + }, + getAuditLogs: (params?: any) => { + const sp = new URLSearchParams(); + if (params) Object.entries(params).forEach(([k, v]) => { if (v) sp.set(k, String(v)); }); + return get(`/admin/logs/audit-logs${sp.toString() ? `?${sp.toString()}` : ''}`); + }, + // 新增:日志统计 + getLogStats: () => get('/admin/logs/stats'), + // 新增:API调用统计 + getApiStats: (params?: any) => { + const sp = new URLSearchParams(); + if (params) Object.entries(params).forEach(([k, v]) => { if (v) sp.set(k, String(v)); }); + return get(`/admin/logs/api-stats${sp.toString() ? `?${sp.toString()}` : ''}`); + }, + // 新增:慢请求记录 + getSlowRequests: (params?: any) => { + const sp = new URLSearchParams(); + if (params) Object.entries(params).forEach(([k, v]) => { if (v) sp.set(k, String(v)); }); + return get(`/admin/logs/slow-requests${sp.toString() ? `?${sp.toString()}` : ''}`); + }, + // 新增:操作类型枚举 + getActionTypes: () => get('/admin/logs/action-types'), + // 新增:审计日志导出 + exportAuditLogs: (params?: any) => { + const sp = new URLSearchParams(); + if (params) Object.entries(params).forEach(([k, v]) => { if (v) sp.set(k, String(v)); }); + return get(`/admin/logs/export/audit-logs${sp.toString() ? `?${sp.toString()}` : ''}`); + }, + exportOperationLogs: (params?: any) => { + const sp = new URLSearchParams(); + if (params) Object.entries(params).forEach(([k, v]) => { if (v) sp.set(k, String(v)); }); + return get(`/admin/logs/export/operations${sp.toString() ? `?${sp.toString()}` : ''}`); + }, + exportTokenLogs: (params?: any) => { + const sp = new URLSearchParams(); + if (params) Object.entries(params).forEach(([k, v]) => { if (v) sp.set(k, String(v)); }); + return get(`/admin/logs/export/token-logs${sp.toString() ? `?${sp.toString()}` : ''}`); + }, + getRiskRules: () => get('/admin/logs/risk-rules'), + addRiskRule: (data: any) => post('/admin/logs/risk-rules', data), + updateRiskRule: (id: string, data: any) => put(`/admin/logs/risk-rules/${id}`, data), + deleteRiskRule: (id: string) => del(`/admin/logs/risk-rules/${id}`), + // 技能管理 (Phase 2.2) + getAdminSkills: (params?: any) => { + const sp = new URLSearchParams(); + if (params) Object.entries(params).forEach(([k, v]) => { if (v !== undefined && v !== null && v !== '') sp.set(k, String(v)); }); + return get(`/admin/skills/${sp.toString() ? `?${sp.toString()}` : ''}`); + }, + getAdminSkill: (id: string) => get(`/admin/skills/${id}`), + createAdminSkill: (data: any) => post('/admin/skills/', data), + updateAdminSkill: (id: string, data: any) => put(`/admin/skills/${id}`, data), + deleteAdminSkill: (id: string) => del(`/admin/skills/${id}`), + changeAdminSkillState: (id: string, data: any) => put(`/admin/skills/${id}/state`, data), + getAdminSkillVersions: (id: string) => get(`/admin/skills/${id}/versions`), + rollbackAdminSkill: (id: string, data: any) => post(`/admin/skills/${id}/rollback`, data), + publishAdminSkill: (id: string, data: any) => post(`/admin/skills/${id}/publish`, data), + unpublishAdminSkill: (id: string) => post(`/admin/skills/${id}/unpublish`), + getAdminSkillsStats: () => get('/admin/skills/stats/overview'), + // Agent管理 (Phase 2.3) + getAdminAgents: (params?: any) => { + const sp = new URLSearchParams(); + if (params) Object.entries(params).forEach(([k, v]) => { if (v !== undefined && v !== null && v !== '') sp.set(k, String(v)); }); + return get(`/admin/agents/${sp.toString() ? `?${sp.toString()}` : ''}`); + }, + getAdminAgent: (id: string) => get(`/admin/agents/${id}`), + createAdminAgent: (data: any) => post('/admin/agents/', data), + updateAdminAgent: (id: string, data: any) => put(`/admin/agents/${id}`, data), + deleteAdminAgent: (id: string) => del(`/admin/agents/${id}`), + toggleAdminAgent: (id: string, isActive: boolean) => put(`/admin/agents/${id}/toggle`, { is_active: isActive }), + getAdminAgentsStats: () => get('/admin/agents/stats/overview'), + getAdminAgentReviews: (id: string) => get(`/admin/agents/${id}/reviews`), + getAdminAvailableSkills: (params?: any) => { + const sp = new URLSearchParams(); + if (params) Object.entries(params).forEach(([k, v]) => { if (v !== undefined && v !== null && v !== '') sp.set(k, String(v)); }); + return get(`/admin/agents/available/skills${sp.toString() ? `?${sp.toString()}` : ''}`); + }, + getAdminAvailableModels: () => get('/admin/agents/available/models'), +}; +// ===== AI自进化API ===== +export const evolutionAPI = { + // 驾驶舱面板 + getSkillTree: () => get('/evolution/dashboard/skill-tree'), + getTimeline: (eventType?: string) => + get('/evolution/dashboard/timeline' + (eventType ? `?event_type=${eventType}` : '')), + getStatistics: () => get('/evolution/dashboard/statistics'), + getProfile: () => get('/evolution/dashboard/profile'), + + // 技能管理 + getSkills: (params?: { state?: string; keyword?: string; sort_by?: string; order?: string }) => { + const query = new URLSearchParams(); + if (params?.state) query.append('state', params.state); + if (params?.keyword) query.append('keyword', params.keyword); + if (params?.sort_by) query.append('sort_by', params.sort_by); + if (params?.order) query.append('order', params.order); + const qs = query.toString(); + return get('/evolution/skills' + (qs ? `?${qs}` : '')); + }, + getSkillDetail: (name: string) => get(`/evolution/skills/${encodeURIComponent(name)}`), + updateSkill: (name: string, data: { description?: string; tags?: string[]; category?: string }) => + put(`/evolution/skills/${encodeURIComponent(name)}`, data), + deleteSkill: (name: string) => del(`/evolution/skills/${encodeURIComponent(name)}`), + freezeSkill: (name: string) => post(`/evolution/skills/${encodeURIComponent(name)}/freeze`), + unfreezeSkill: (name: string) => post(`/evolution/skills/${encodeURIComponent(name)}/unfreeze`), + getSkillHistory: (name: string) => get(`/evolution/skills/${encodeURIComponent(name)}/history`), + getSkillTrajectories: (name: string) => get(`/evolution/skills/${encodeURIComponent(name)}/trajectories`), + + // 事件 + getEvents: (params?: { event_type?: string; skill_name?: string; limit?: number }) => { + const query = new URLSearchParams(); + if (params?.event_type) query.append('event_type', params.event_type); + if (params?.skill_name) query.append('skill_name', params.skill_name); + if (params?.limit) query.append('limit', String(params.limit)); + const qs = query.toString(); + return get('/evolution/events' + (qs ? `?${qs}` : '')); + }, + + // 轨迹提交 + submitTrajectory: (data: { conversation_id: string; messages: any[] }) => + post('/evolution/trajectory/submit', data), + + // v2: 技能回滚 + rollbackSkill: (skillName: string, version: number) => + post(`/evolution/skills/${encodeURIComponent(skillName)}/rollback/${version}`), + + // v2: 发布到市场 + publishSkill: (skillName: string, data: { price: number; market_description: string }) => + post(`/evolution/skills/${encodeURIComponent(skillName)}/publish`, data), + + // v2: 团队共享 + shareToTeam: (skillName: string, teamId: string) => + post(`/evolution/skills/${encodeURIComponent(skillName)}/share-to-team`, { team_id: teamId }), + + // v2: 流水线状态 + getPipelineStatus: () => get('/evolution/pipeline/status'), + + // v2: 手动触发流水线 + triggerPipeline: () => post('/evolution/pipeline/trigger'), + + // v2: Watcher状态 + getWatcherStatus: () => get('/evolution/watcher/status'), + + // v2: 进化报告 + getReports: (reportType?: string) => { + const qs = reportType ? `?report_type=${reportType}` : ''; + return get(`/evolution/reports${qs}`); + }, + getReportDetail: (reportId: string) => get(`/evolution/reports/${reportId}`), +// 知识库管理 (Phase 2.4) + getAdminKnowledgeStats: () => get('/admin/knowledge/stats/overview'), + getAdminKnowledge: (params?: any) => { + const sp = new URLSearchParams(); + if (params?.keyword) sp.append('keyword', params.keyword); + if (params?.status) sp.append('status', params.status); + if (params?.is_official !== undefined) sp.append('is_official', String(params.is_official)); + if (params?.page) sp.append('page', String(params.page)); + if (params?.page_size) sp.append('page_size', String(params.page_size)); + return get(`/admin/knowledge/?${sp.toString()}`); + }, + getAdminKnowledgeDetail: (id: string) => get(`/admin/knowledge/${id}`), + createAdminKnowledge: (data: any) => post('/admin/knowledge/', data), + updateAdminKnowledge: (id: string, data: any) => put(`/admin/knowledge/${id}`, data), + deleteAdminKnowledge: (id: string) => del(`/admin/knowledge/${id}`), + toggleAdminKnowledge: (id: string, isActive: boolean) => put(`/admin/knowledge/${id}/toggle`, { is_active: isActive }), + getAdminKnowledgeDocs: (kbId: string, params?: any) => { + const sp = new URLSearchParams(); + if (params?.page) sp.append('page', String(params.page)); + if (params?.page_size) sp.append('page_size', String(params.page_size)); + if (params?.status) sp.append('status', params.status); + if (params?.file_type) sp.append('file_type', params.file_type); + return get(`/admin/knowledge/${kbId}/documents?${sp.toString()}`); + }, + deleteAdminKnowledgeDoc: (kbId: string, docId: string) => del(`/admin/knowledge/${kbId}/documents/${docId}`), + getAdminKnowledgeExtServices: () => get('/admin/knowledge/external/services'), + createAdminKnowledgeExtService: (data: any) => post('/admin/knowledge/external/services', data), + updateAdminKnowledgeExtService: (id: string, data: any) => put(`/admin/knowledge/external/services/${id}`, data), + deleteAdminKnowledgeExtService: (id: string) => del(`/admin/knowledge/external/services/${id}`), + checkAdminKnowledgeExtStatus: (id: string) => get(`/admin/knowledge/external/services/${id}/status`), + syncAdminKnowledge: (kbId: string, data: any) => post(`/admin/knowledge/external/sync/${kbId}`, data), + batchDeleteAdminKnowledge: (ids: string[]) => post('/admin/knowledge/batch/delete', ids), +};