diff --git a/frontend/src/api/index.ts b/frontend/src/api/index.ts index fd16a99..7fa162e 100644 --- a/frontend/src/api/index.ts +++ b/frontend/src/api/index.ts @@ -1,513 +1,1013 @@ -/** - * 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}`), -}; - -// ===== 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'); +} + +// 通用请求方法 +export 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_base_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'), + getDailyStats: (days?: number) => get<{ days: number; data: Array<{ date: string; tokens: number }> }>(`/admin/dashboard/daily-stats${days ? `?days=${days}` : ''}`), + // 用户管理 + 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`), + testAllModels: () => post('/admin/models/test-all'), + 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'), + // 能力类型 & 按能力默认模型 + getCapabilities: () => get('/admin/models/capabilities'), + getCapabilityDefaults: () => get('/admin/models/capability-defaults'), + setCapabilityDefault: (capability: string, modelId: string | null) => + put('/admin/models/capability-defaults', { capability, model_id: modelId }), + // 网站设置 + 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: (params: string) => post(`/admin/membership/plans${params}`), + updatePlan: (id: string, params: string) => put(`/admin/membership/plans/${id}${params}`), + deletePlan: (id: string) => del(`/admin/membership/plans/${id}`), + getSubscriptions: (page?: number) => get(`/admin/membership/subscriptions${page ? `?page=${page}` : ''}`), + getAutomationRules: () => get('/admin/membership/automation-rules'), + getBenefitsComparison: () => get('/admin/membership/benefits-comparison'), + getMembershipConfigs: () => get('/admin/membership/global-configs'), + updateMembershipConfig: (key: string, params: string) => put(`/admin/membership/global-configs/${key}${params}`), + getUserMemberships: (page?: number, planId?: string, status?: string) => { + const p = new URLSearchParams(); + if (page) p.append('page', String(page)); + if (planId) p.append('plan_id', planId); + if (status) p.append('status', status); + const qs = p.toString(); + return get(`/admin/membership/user-memberships${qs ? `?${qs}` : ''}`); + }, + assignPlan: (userId: string, planId: string, days: number) => put(`/admin/membership/users/${userId}/assign-plan?plan_id=${planId}&duration_days=${days}`), + 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'), +// 智能体管理 (Phase 2.3) + getAdminAgents: (params?: any) => { + const query = params ? '?' + Object.entries(params).filter(([_, v]) => v !== undefined && v !== '').map(([k, v]) => `${k}=${v}`).join('&') : ''; + return get(`/admin/agents/${query}`); + }, + 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 query = params ? '?' + Object.entries(params).filter(([_, v]) => v !== undefined && v !== '').map(([k, v]) => `${k}=${v}`).join('&') : ''; + return get(`/admin/agents/available/skills${query}`); + }, + getAdminAvailableModels: (params?: any) => { + const query = params ? '?' + Object.entries(params).filter(([_, v]) => v !== undefined && v !== '').map(([k, v]) => `${k}=${v}`).join('&') : ''; + return get(`/admin/agents/available/models${query}`); + }, + // 知识库管理 (Phase 2.4) + getAdminKnowledgeStats: () => get('/admin/knowledge/stats/overview'), + getAdminKnowledge: (params?: any) => { + const query = params ? '?' + Object.entries(params).filter(([_, v]) => v !== undefined && v !== '').map(([k, v]) => `${k}=${v}`).join('&') : ''; + return get(`/admin/knowledge/${query}`); + }, + 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 query = params ? '?' + Object.entries(params).filter(([_, v]) => v !== undefined && v !== '').map(([k, v]) => `${k}=${v}`).join('&') : ''; + return get(`/admin/knowledge/${kbId}/documents${query}`); + }, + 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), + // OSS存储配置 (Phase 3.1) + getAssetStats: () => get('/admin/assets/stats'), + getAdminAssets: (query: string) => get(`/admin/assets/?${query}`), + deleteAdminAsset: (id: string) => del(`/admin/assets/${id}`), + getAssetActivity: () => get('/admin/assets/activity'), + getAdminStorageStats: () => get('/admin/storage/stats/overview'), + getAdminStorageConfigs: (params?: any) => { + const query = params ? '?' + Object.entries(params).filter(([_, v]) => v !== undefined && v !== '').map(([k, v]) => `${k}=${v}`).join('&') : ''; + return get(`/admin/storage/${query}`); + }, + getAdminStorageConfig: (id: string) => get(`/admin/storage/${id}`), + createAdminStorageConfig: (data: any) => post('/admin/storage/', data), + updateAdminStorageConfig: (id: string, data: any) => put(`/admin/storage/${id}`, data), + deleteAdminStorageConfig: (id: string) => del(`/admin/storage/${id}`), + toggleAdminStorageConfig: (id: string) => put(`/admin/storage/${id}/toggle`), + setDefaultAdminStorageConfig: (id: string) => put(`/admin/storage/${id}/set-default`), + testAdminStorageConfig: (data: any) => post('/admin/storage/test', data), + getAdminStorageUsage: (id: string) => get(`/admin/storage/${id}/usage`), + // Storage Quota APIs (Phase C5) + getStorageQuotaOverview: () => get('/admin/storage/quota/overview'), + getStorageQuotaUsers: (params?: any) => { + if (params) { + const query = Object.entries(params).map(([k, v]) => v !== undefined && v !== '' && v !== null ? `${k}=${encodeURIComponent(String(v))}` : '').filter(Boolean).join('&'); + return get(`/admin/storage/quota/users${query ? '?' + query : ''}`); + } + return get('/admin/storage/quota/users'); + }, + getStorageQuotaUser: (userId: string) => get(`/admin/storage/quota/users/${userId}`), + adjustStorageQuota: (userId: string, data: any) => put(`/admin/storage/quota/users/${userId}`, data), + recalcStorageQuota: (userId: string) => post(`/admin/storage/quota/recalculate/${userId}`, {}), + initAllStorageQuotas: () => post('/admin/storage/quota/init-all', {}), + + // 自动化任务调度 (Phase 3.2) + getAdminAutomationStats: () => get('/admin/automation/stats/overview'), + getAdminAutomationTasks: (params?: any) => { + const query = params ? '?' + Object.entries(params).filter(([_, v]) => v !== undefined && v !== '').map(([k, v]) => `${k}=${v}`).join('&') : ''; + return get(`/admin/automation/${query}`); + }, + getAdminAutomationTask: (id: string) => get(`/admin/automation/${id}`), + createAdminAutomationTask: (data: any) => post('/admin/automation/', data), + updateAdminAutomationTask: (id: string, data: any) => put(`/admin/automation/${id}`, data), + deleteAdminAutomationTask: (id: string) => del(`/admin/automation/${id}`), + toggleAdminAutomationTask: (id: string) => put(`/admin/automation/${id}/toggle`), + executeAdminAutomationTask: (id: string) => post(`/admin/automation/${id}/execute`), + getAdminAutomationTaskHistory: (id: string, params?: any) => { + const query = params ? '?' + Object.entries(params).filter(([_, v]) => v !== undefined && v !== '').map(([k, v]) => `${k}=${v}`).join('&') : ''; + return get(`/admin/automation/${id}/history${query}`); + }, + // MCP Server Management + getAdminMcpStats: () => get('/admin/mcp/stats/overview'), + getAdminMcpServers: (params?: any) => { + const query = new URLSearchParams(params).toString(); + return get(`/admin/mcp/${query ? '?' + query : ''}`); + }, + getAdminMcpServer: (id: string) => get(`/admin/mcp/${id}`), + createAdminMcpServer: (data: any) => post('/admin/mcp/', data), + updateAdminMcpServer: (id: string, data: any) => put(`/admin/mcp/${id}`, data), + deleteAdminMcpServer: (id: string) => del(`/admin/mcp/${id}`), + toggleAdminMcpServer: (id: string) => put(`/admin/mcp/${id}/toggle`), + testAdminMcpServer: (id: string, data?: any) => post(`/admin/mcp/${id}/test`, data || {}), + getAdminMcpServerTools: (id: string) => get(`/admin/mcp/${id}/tools`), + getAdminMcpServerResources: (id: string) => get(`/admin/mcp/${id}/resources`), + // Developer API Management + getAdminDeveloperStats: () => get('/admin/developer/stats/overview'), + getAdminApiKeys: (params?: any) => { + const sp = new URLSearchParams(); + if (params) Object.entries(params).forEach(([k, v]) => { if (v) sp.set(k, String(v)); }); + return get(`/admin/developer/api-keys${sp.toString() ? '?' + sp.toString() : ''}`); + }, + createAdminApiKey: (data: any) => post('/admin/developer/api-keys/', data), + updateAdminApiKey: (id: string, data: any) => put(`/admin/developer/api-keys/${id}`, data), + revokeAdminApiKey: (id: string) => post(`/admin/developer/api-keys/${id}/revoke`), + deleteAdminApiKey: (id: string) => del(`/admin/developer/api-keys/${id}`), + getAdminOpenApiClients: (params?: any) => { + const sp = new URLSearchParams(); + if (params) Object.entries(params).forEach(([k, v]) => { if (v) sp.set(k, String(v)); }); + return get(`/admin/developer/openapi-clients${sp.toString() ? '?' + sp.toString() : ''}`); + }, + createAdminOpenApiClient: (data: any) => post('/admin/developer/openapi-clients/', data), + updateAdminOpenApiClient: (id: string, data: any) => put(`/admin/developer/openapi-clients/${id}`, data), + resetAdminOpenApiClientSecret: (id: string) => post(`/admin/developer/openapi-clients/${id}/reset-secret`), + deleteAdminOpenApiClient: (id: string) => del(`/admin/developer/openapi-clients/${id}`), + getAdminCallStats: (params?: any) => { + const sp = new URLSearchParams(); + if (params) Object.entries(params).forEach(([k, v]) => { if (v) sp.set(k, String(v)); }); + return get(`/admin/developer/call-stats${sp.toString() ? '?' + sp.toString() : ''}`); + }, + getAdminCallStatsOverview: () => get('/admin/developer/call-stats/overview'), + getAdminSlowLogs: (params?: any) => { + const sp = new URLSearchParams(); + if (params) Object.entries(params).forEach(([k, v]) => { if (v) sp.set(k, String(v)); }); + return get(`/admin/developer/slow-logs${sp.toString() ? '?' + sp.toString() : ''}`); + }, + clearAdminSlowLogs: () => del('/admin/developer/slow-logs'), + getAdminSlowLogsStats: () => get('/admin/developer/slow-logs/stats'), + // AI App Management + getAIAppStats: () => get('/admin/apps/stats/overview'), + getAIApps: (params?: string) => get('/admin/apps/apps' + (params ? '?' + params : '')), + getAIApp: (id: string) => get('/admin/apps/apps/' + id), + createAIApp: (data: any) => post('/admin/apps/apps', data), + updateAIApp: (id: string, data: any) => put('/admin/apps/apps/' + id, data), + deleteAIApp: (id: string) => del('/admin/apps/apps/' + id), + aiAppLifecycle: (id: string, action: string) => post('/admin/apps/apps/' + id + '/' + action, {}), + getAIAppVersions: (id: string) => get('/admin/apps/apps/' + id + '/versions'), + getAIAppAnalytics: (id: string) => get('/admin/apps/apps/' + id + '/analytics'), + getAIAppTemplates: () => get('/admin/apps/templates'), + createAIAppTemplate: (data: any) => post('/admin/apps/templates', data), + createAIAppFromTemplate: (templateId: string, data: any) => post('/admin/apps/apps/from-template/' + templateId, data), + getAIAppCategories: () => get('/admin/apps/categories'), + // Logo 上传 + uploadLogo: (formData: FormData) => { + const token = localStorage.getItem('access_token'); + return fetch(`/app/api/admin/settings/logo/upload`, { + method: 'POST', + headers: { 'Authorization': `Bearer ${token}` }, + body: formData, + }).then(res => res.json()); + }, + + // MCP Market (Phase G1) + getMcpMarketStats: () => + get('/admin/mcp-market/stats'), + getMcpTools: (params?: Record) => + get('/admin/mcp-market/?' + new URLSearchParams(params || {}).toString()), + getMcpToolDetail: (id: string) => + get('/admin/mcp-market/' + id), + createMcpTool: (data: any) => + post('/admin/mcp-market/', data), + updateMcpTool: (id: string, data: any) => + put('/admin/mcp-market/' + id, data), + deleteMcpTool: (id: string) => + del('/admin/mcp-market/' + id), + scanMcpTool: (id: string) => + post('/admin/mcp-market/' + id + '/security-scan'), + updateMcpToolSecurity: (id: string, data: any) => + put('/admin/mcp-market/' + id + '/security-status', data), + regenMcpDeepLink: (id: string) => + post('/admin/mcp-market/' + id + '/deep-link'), + getMcpManagedServers: () => + get('/admin/mcp-market/managed/servers'), + seedMcpTools: () => + post('/admin/mcp-market/seed'), + + // Code Execution Sandbox (Phase G2) + getCodeExecStats: () => get('/admin/code-exec/stats'), + getCodeExecRuntimes: () => get('/admin/code-exec/runtimes'), + executeCode: (data: { language: string; code: string; stdin?: string; timeout?: number }) => + post('/admin/code-exec/execute', data), + getCodeExecTasks: (params?: any) => { + const sp = new URLSearchParams(); + if (params) Object.entries(params).forEach(([k, v]) => { if (v) sp.set(k, String(v)); }); + return get(`/admin/code-exec/tasks${sp.toString() ? '?' + sp.toString() : ''}`); + }, + getCodeExecTask: (id: string) => get(`/admin/code-exec/tasks/${id}`), + deleteCodeExecTask: (id: string) => del(`/admin/code-exec/tasks/${id}`), + + + // Distribution Builder (Phase G4) + getDistributionStats: () => get('/admin/distributions/stats'), + getDistributions: (params?: any) => { + const sp = new URLSearchParams(); + if (params) Object.entries(params).forEach(([k, v]: [string, any]) => { if (v) sp.set(k, String(v)); }); + return get('/admin/distributions' + (sp.toString() ? '?' + sp.toString() : '')); + }, + getDistributionTemplates: () => get('/admin/distributions/templates'), + createDistribution: (data: any) => post('/admin/distributions', data), + getDistribution: (id: string) => get('/admin/distributions/' + id), + updateDistribution: (id: string, data: any) => put('/admin/distributions/' + id, data), + deleteDistribution: (id: string) => del('/admin/distributions/' + id), + getDistributionLicenses: (params?: any) => { + const sp = new URLSearchParams(); + if (params) Object.entries(params).forEach(([k, v]: [string, any]) => { if (v) sp.set(k, String(v)); }); + return get('/admin/distributions/licenses' + (sp.toString() ? '?' + sp.toString() : '')); + }, + createDistributionLicense: (distroId: string, data: any) => post('/admin/distributions/' + distroId + '/licenses', data), + getDistributionLicense: (id: string) => get('/admin/distributions/licenses/' + id), + revokeDistributionLicense: (id: string) => post('/admin/distributions/licenses/' + id + '/revoke'), + // ===== Ads Management ===== + 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}`), + + // ===== Market Admin (extended) ===== + getMarketOverview: () => get('/admin/market/overview'), + getTopApps: (metric?: string, limit?: number) => get(`/admin/market/top-apps${metric ? '?metric=' + metric : ''}${limit ? (metric ? '&' : '?') + 'limit=' + limit : ''}`), + getAdminMarketApps: (params?: string) => get(`/admin/market/apps${params ? '?' + params : ''}`), + getPendingApps: () => get('/admin/market/pending'), + getCoupons: () => get('/admin/market/coupons'), + getRecentReviews: () => get('/admin/market/reviews'), + approveApp: (id: string) => post(`/admin/market/apps/${id}/approve`), + rejectApp: (id: string) => post(`/admin/market/apps/${id}/reject`), + setFeaturedApp: (id: string, featured: boolean, sortOrder?: number) => put(`/admin/market/apps/${id}/featured`, { featured, sort_order: sortOrder }), + deleteMarketApp: (id: string) => del(`/admin/market/apps/${id}`), + deleteCoupon: (id: string) => del(`/admin/market/coupons/${id}`), + updateMarketApp: (id: string, data: any) => put(`/admin/market/apps/${id}`, data), + updateCoupon: (id: string, data: any) => put(`/admin/market/coupons/${id}`, data), + addCoupon: (data: any) => post('/admin/market/coupons', data), + + // ===== Membership (extended) ===== + getMembershipStats: () => get('/admin/membership/stats'), + revokeMembership: (userId: string) => post(`/admin/membership/users/${userId}/revoke`), + + // ===== Logs (extended) ===== + 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/operation-logs${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() : ''}`); + }, + + // ===== Analytics ===== + getAnalyticsOverview: (days?: number) => get(`/admin/analytics/overview${days ? '?days=' + days : ''}`), + getAnalyticsApiTrends: (days?: number) => get(`/admin/analytics/trends/api-calls${days ? '?days=' + days : ''}`), + getAnalyticsTokenTrends: (days?: number) => get(`/admin/analytics/trends/tokens${days ? '?days=' + days : ''}`), + getAnalyticsUserTrends: (days?: number) => get(`/admin/analytics/trends/users${days ? '?days=' + days : ''}`), + getAnalyticsRevenueTrends: (days?: number) => get(`/admin/analytics/trends/revenue${days ? '?days=' + days : ''}`), + getAnalyticsModelUsage: (days?: number) => get(`/admin/analytics/models/usage${days ? '?days=' + days : ''}`), + + // ===== Billing ===== + getBillingRules: () => get('/admin/billing/rules'), + getBillingPackages: () => get('/admin/billing/packages'), + getBillingTransactions: (page?: number) => get(`/admin/billing/transactions${page ? '?page=' + page : ''}`), + getBillingStats: () => get('/admin/billing/stats/overview'), + + // ===== Tenant ===== + getTenants: (page?: number) => get(`/admin/tenant/list${page ? '?page=' + page : ''}`), + getTenantStats: () => get('/admin/tenant/stats/overview'), + getTenantMembers: (tenantId: string) => get(`/admin/tenant/${tenantId}/members`), + createTenant: (params: string) => post(`/admin/tenant/create${params}`), + toggleAd: (id: string) => put(`/admin/ads/${id}/toggle`), + getAdminApps: () => get('/admin/market/apps'), + updateApp: (id: string, data: any) => put(`/admin/market/apps/${id}`, data), + assignCoupon: (id: string, userId: string) => post(`/admin/market/coupons/${id}/assign`, { user_id: userId }), + +}; +// ===== 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}`), + + + // Workflow (Phase 3.6) + getWorkflows: (params?: Record) => + get('/admin/workflows/?' + new URLSearchParams(params || {}).toString()), + getWorkflow: (id: string) => + get(`/admin/workflows/${id}`), + getWorkflowStats: () => + get('/admin/workflows/stats'), + getWorkflowTemplates: () => + get('/admin/workflows/templates'), + createWorkflow: (data: any) => + post('/admin/workflows/', data), + updateWorkflow: (id: string, data: any) => + put(`/admin/workflows/${id}`, data), + deleteWorkflow: (id: string) => + del(`/admin/workflows/${id}`), + toggleWorkflow: (id: string, isActive: boolean) => + post(`/admin/workflows/${id}/toggle?is_active=${isActive}`), + executeWorkflow: (id: string, inputText: string) => + post(`/admin/workflows/${id}/execute`, { input_text: inputText }), + + + // Privacy & Local Agent (Phase G5) + getPrivacyStats: () => get('/admin/privacy/stats'), + getPrivacyConfig: () => get('/admin/privacy/config'), + updatePrivacyConfig: (params: any) => { + const sp = new URLSearchParams(); + Object.entries(params).forEach(([k, v]) => { if (v != null) sp.append(k, String(v)); }); + return put('/admin/privacy/config?' + sp.toString()); + }, + switchPrivacyMode: (mode: string) => post('/admin/privacy/switch-mode?mode=' + encodeURIComponent(mode)), + getPrivacyLicenses: (params?: any) => { + const sp = new URLSearchParams(); + if (params?.status) sp.append('status', params.status); + return get('/admin/privacy/licenses' + (sp.toString() ? '?' + sp.toString() : '')); + }, + generateOfflineLicense: (data: any) => { + const sp = new URLSearchParams(); + if (data.agent_id) sp.append('agent_id', data.agent_id); + sp.append('max_offline_days', String(data.max_offline_days || 7)); + return post('/admin/privacy/licenses/generate?' + sp.toString()); + }, + revokePrivacyLicense: (id: number) => post('/admin/privacy/licenses/' + id + '/revoke'), + validatePrivacyLicense: (licenseKey: string) => { + const sp = new URLSearchParams(); + sp.append('license_key', licenseKey); + return post('/admin/privacy/licenses/validate?' + sp.toString()); + }, + getKbSyncStates: () => get('/admin/privacy/kb-sync'), + triggerKbSync: (kbId: number, direction: string) => { + const sp = new URLSearchParams(); + sp.append('knowledge_base_id', String(kbId)); + sp.append('sync_direction', direction); + return post('/admin/privacy/kb-sync/trigger?' + sp.toString()); + }, + getLocalAgents: () => get('/admin/privacy/local-agents'), + getPrivacyUsageStats: () => get('/admin/privacy/usage/stats'), + getBridgeConfig: () => get('/admin/privacy/bridge-config'), + + // IM Bot Management (Phase 4) + getImBotStats: () => get('/admin/im-bot/stats'), + getImBotDashboard: () => get('/admin/im-bot/dashboard'), + getImBotChannels: (params?: string) => get(`/admin/im-bot/channels${params || ''}`), + getImBotChannelDetail: (id: string) => get(`/admin/im-bot/channels/${id}`), + testImBotChannel: (id: string) => post(`/admin/im-bot/channels/${id}/test`), + activateImBotChannel: (id: string) => post(`/admin/im-bot/channels/${id}/activate`), + deactivateImBotChannel: (id: string) => post(`/admin/im-bot/channels/${id}/deactivate`), + getImBotRoutes: (params?: string) => get(`/admin/im-bot/routes${params || ''}`), + createImBotRoute: (params: string) => post(`/admin/im-bot/routes${params}`), + deleteImBotRoute: (id: string) => del(`/admin/im-bot/routes/${id}`), + // 个人微信(iLink 协议)原生适配器 + getWechatConfig: () => get('/admin/im-bot/wechat'), + wechatQrcode: () => post('/admin/im-bot/wechat/qrcode'), + wechatQrcodeStatus: (params: string) => post(`/admin/im-bot/wechat/qrcode/status${params}`), + getWechatStatus: () => get('/admin/im-bot/wechat/status'), + disconnectWechat: () => post('/admin/im-bot/wechat/disconnect'), + getImBotPlatforms: () => get('/admin/im-bot/platforms'), + getImBotWebhookUrl: (platform: string) => get(`/admin/im-bot/webhook-url/${platform}`), + getImBotMessages: (params?: string) => get(`/admin/im-bot/messages${params || ''}`), + imBotQuickSetup: (params: string) => post(`/admin/im-bot/quick-setup${params}`), + + // 推广系统 + getPromotionStats: () => get('/admin/promotion/stats'), + getPromotions: (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/promotion/promotions${sp.toString() ? `?${sp.toString()}` : ''}`); + }, + createPromotion: (params: any) => { + const sp = new URLSearchParams(); + Object.entries(params).forEach(([k, v]) => { if (v !== undefined && v !== null && v !== '') sp.set(k, String(v)); }); + return post(`/admin/promotion/promotions${sp.toString() ? `?${sp.toString()}` : ''}`); + }, + updatePromotion: (id: string, params: any) => { + const sp = new URLSearchParams(); + Object.entries(params).forEach(([k, v]) => { if (v !== undefined && v !== null && v !== '') sp.set(k, String(v)); }); + return put(`/admin/promotion/promotions/${id}${sp.toString() ? `?${sp.toString()}` : ''}`); + }, + deletePromotion: (id: string) => del(`/admin/promotion/promotions/${id}`), + togglePromotion: (id: string) => post(`/admin/promotion/promotions/${id}/toggle`), + getReferralLinks: (params?: any) => { + const sp = new URLSearchParams(); + if (params) Object.entries(params).forEach(([k, v]) => { if (v) sp.set(k, String(v)); }); + return get(`/admin/promotion/referral-links${sp.toString() ? `?${sp.toString()}` : ''}`); + }, + generateReferralLink: (params: any) => { + const sp = new URLSearchParams(); + Object.entries(params).forEach(([k, v]) => { if (v) sp.set(k, String(v)); }); + return post(`/admin/promotion/referral-links/generate${sp.toString() ? `?${sp.toString()}` : ''}`); + }, + getReferralRewards: (params?: any) => { + const sp = new URLSearchParams(); + if (params) Object.entries(params).forEach(([k, v]) => { if (v) sp.set(k, String(v)); }); + return get(`/admin/promotion/rewards${sp.toString() ? `?${sp.toString()}` : ''}`); + }, + approveReward: (id: string) => post(`/admin/promotion/rewards/${id}/approve`), + markRewardPaid: (id: string, params: any) => { + const sp = new URLSearchParams(); + Object.entries(params).forEach(([k, v]) => { if (v) sp.set(k, String(v)); }); + return post(`/admin/promotion/rewards/${id}/pay${sp.toString() ? `?${sp.toString()}` : ''}`); + }, + getPromotionLeaderboard: (params?: any) => { + const sp = new URLSearchParams(); + if (params) Object.entries(params).forEach(([k, v]) => { if (v) sp.set(k, String(v)); }); + return get(`/admin/promotion/leaderboard${sp.toString() ? `?${sp.toString()}` : ''}`); + }, + regenerateReferralCode: (id: string) => post(`/admin/promotion/referral-links/${id}/regenerate`), + getMyReferrals: () => get('/admin/promotion/my-referrals'), + getMyRewards: () => get('/admin/promotion/my-rewards'), + + // 成就系统 + getAchievements: (params?: string) => get(`/admin/achievement/achievements${params || ''}`), + getAchievementDetail: (id: string) => get(`/admin/achievement/achievements/${id}`), + createAchievement: (params: string) => post(`/admin/achievement/achievements${params}`), + updateAchievement: (id: string, params: string) => put(`/admin/achievement/achievements/${id}${params}`), + deleteAchievement: (id: string) => del(`/admin/achievement/achievements/${id}`), + getUserAchievements: () => get('/admin/achievement/user/achievements'), + claimAchievementReward: (id: string) => post(`/admin/achievement/user/achievements/${id}/claim`), + checkAchievementProgress: () => post('/admin/achievement/check-progress'), + getAchievementLeaderboard: (params?: string) => get(`/admin/achievement/leaderboard${params || ''}`), + + // 多租户管理 + getTenants: (page?: number, keyword?: string, status?: string) => { + const sp = new URLSearchParams(); + if (page) sp.set('page', String(page)); + if (keyword) sp.set('keyword', keyword); + if (status) sp.set('status', status); + sp.set('page_size', '20'); + return get(`/admin/tenant/list${sp.toString() ? `?${sp.toString()}` : ''}`); + }, + createTenant: (params: string) => post(`/admin/tenant/create${params}`), + getTenantDetail: (id: string) => get(`/admin/tenant/${id}`), + updateTenant: (id: string, params: string) => put(`/admin/tenant/${id}${params}`), + deleteTenant: (id: string) => del(`/admin/tenant/${id}`), + getTenantMembers: (tenantId: string, page?: number) => { + const sp = new URLSearchParams(); + sp.set('page', String(page || 1)); + sp.set('page_size', '100'); + return get(`/admin/tenant/${tenantId}/members?${sp.toString()}`); + }, + addTenantMember: (tenantId: string, params: string) => post(`/admin/tenant/${tenantId}/members/add${params}`), + updateTenantMember: (tenantId: string, memberId: string, params: string) => put(`/admin/tenant/${tenantId}/members/${memberId}${params}`), + removeTenantMember: (tenantId: string, memberId: string) => del(`/admin/tenant/${tenantId}/members/${memberId}`), + getTenantQuotas: (tenantId: string) => get(`/admin/tenant/${tenantId}/quotas`), + updateTenantQuota: (tenantId: string, params: string) => put(`/admin/tenant/${tenantId}/quotas${params}`), + getTenantInvitations: (tenantId: string) => get(`/admin/tenant/${tenantId}/invitations`), + createTenantInvitation: (tenantId: string, params: string) => post(`/admin/tenant/${tenantId}/invitations${params}`), + getTenantStats: () => get('/admin/tenant/stats/overview'), + + // 计费与支付 + getBillingRules: (page?: number) => get(`/admin/billing/rules?page=${page || 1}&page_size=100`), + createBillingRule: (params: string) => post(`/admin/billing/rules/create${params}`), + updateBillingRule: (id: string, params: string) => put(`/admin/billing/rules/${id}${params}`), + deleteBillingRule: (id: string) => del(`/admin/billing/rules/${id}`), + getBillingPackages: () => get('/admin/billing/packages'), + createBillingPackage: (params: string) => post(`/admin/billing/packages/create${params}`), + updateBillingPackage: (id: string, params: string) => put(`/admin/billing/packages/${id}${params}`), + deleteBillingPackage: (id: string) => del(`/admin/billing/packages/${id}`), + getBillingTransactions: (page?: number) => get(`/admin/billing/transactions?page=${page || 1}&page_size=20`), + getInvoices: (page?: number) => get(`/admin/billing/invoices?page=${page || 1}&page_size=20`), + generateInvoice: (params: string) => post(`/admin/billing/invoices/generate${params}`), + getPaymentConfigs: () => get('/admin/billing/payment-configs'), + updatePaymentConfig: (id: string, params: string) => put(`/admin/billing/payment-configs/${id}${params}`), + getBillingStats: () => get('/admin/billing/stats/overview'), + + // 数据分析 + getAnalyticsOverview: (days?: number) => get(`/admin/analytics/overview?days=${days || 30}`), + getAnalyticsApiTrends: (days?: number) => get(`/admin/analytics/trends/api-calls?days=${days || 7}`), + getAnalyticsTokenTrends: (days?: number) => get(`/admin/analytics/trends/tokens?days=${days || 7}`), + getAnalyticsUserTrends: (days?: number) => get(`/admin/analytics/trends/users?days=${days || 30}`), + getAnalyticsRevenueTrends: (days?: number) => get(`/admin/analytics/trends/revenue?days=${days || 30}`), + getAnalyticsModelUsage: (days?: number) => get(`/admin/analytics/models/usage?days=${days || 30}`), + getAnalyticsDashboards: () => get('/admin/analytics/dashboards'), + createAnalyticsDashboard: (params: string) => post(`/admin/analytics/dashboards/create${params}`), + deleteAnalyticsDashboard: (id: string) => del(`/admin/analytics/dashboards/${id}`), + getAnalyticsEvents: (params?: any) => { + const sp = new URLSearchParams(); + if (params) Object.entries(params).forEach(([k, v]) => { if (v) sp.set(k, String(v)); }); + return get(`/admin/analytics/events${sp.toString() ? `?${sp.toString()}` : ''}`); + }, + +}; + + +// ===== 前台用户个人微信 (iLink 协议 / 微信 ClawBot 插件) ===== +export const imUserAPI = { + getStatus: () => get('/im/wechat/status'), + qrcode: () => post('/im/wechat/qrcode'), + qrcodeStatus: (qrcode: string) => post(`/im/wechat/qrcode/status?qrcode=${encodeURIComponent(qrcode)}`), + disconnect: () => post('/im/wechat/disconnect'), + history: () => get('/im/wechat/history'), +};