/** * API Client Service * 統一的 API 請求處理 */ const API_BASE_URL = import.meta.env.VITE_API_URL || 'http://localhost:3001'; class ApiClient { constructor() { this.baseURL = API_BASE_URL; } async request(endpoint, options = {}) { const url = `${this.baseURL}${endpoint}`; const config = { credentials: 'include', // 重要: 發送 cookies (session) headers: { 'Content-Type': 'application/json', ...options.headers, }, ...options, }; try { const response = await fetch(url, config); const data = await response.json(); if (!response.ok) { throw new Error(data.error || data.message || 'Request failed'); } return data; } catch (error) { // 只對非認證錯誤顯示控制台訊息 if (!endpoint.includes('/auth/me') || !error.message.includes('未登入')) { console.error('API Error:', error); } throw error; } } // GET request get(endpoint, options = {}) { return this.request(endpoint, { method: 'GET', ...options, }); } // POST request post(endpoint, data, options = {}) { return this.request(endpoint, { method: 'POST', body: JSON.stringify(data), ...options, }); } // PUT request put(endpoint, data, options = {}) { return this.request(endpoint, { method: 'PUT', body: JSON.stringify(data), ...options, }); } // DELETE request delete(endpoint, options = {}) { return this.request(endpoint, { method: 'DELETE', ...options, }); } // ============================================ // Authentication APIs // ============================================ async login(identifier, password) { return this.post('/api/auth/login', { identifier, password }); } async logout() { return this.post('/api/auth/logout'); } async getCurrentUser() { return this.get('/api/auth/me'); } async changePassword(oldPassword, newPassword) { return this.post('/api/auth/change-password', { oldPassword, newPassword }); } // ============================================ // Analysis APIs // ============================================ async createAnalysis(finding, jobContent, outputLanguage = 'zh-TW') { return this.post('/api/analyze', { finding, jobContent, outputLanguage }); } async translateAnalysis(analysisId, targetLanguage) { return this.post('/api/analyze/translate', { analysisId, targetLanguage }); } async getAnalysisHistory(page = 1, limit = 10, filters = {}) { const params = new URLSearchParams({ page: page.toString(), limit: limit.toString(), ...filters, }); return this.get(`/api/analyze/history?${params}`); } async getAnalysisDetail(id) { return this.get(`/api/analyze/${id}`); } async deleteAnalysis(id) { return this.delete(`/api/analyze/${id}`); } // ============================================ // Admin APIs // ============================================ async getDashboard() { return this.get('/api/admin/dashboard'); } async getUsers(page = 1, limit = 10, filters = {}) { const params = new URLSearchParams({ page: page.toString(), limit: limit.toString(), ...filters, }); return this.get(`/api/admin/users?${params}`); } async createUser(userData) { return this.post('/api/admin/users', userData); } async updateUser(id, userData) { return this.put(`/api/admin/users/${id}`, userData); } async deleteUser(id) { return this.delete(`/api/admin/users/${id}`); } async getAllAnalyses(page = 1, limit = 10, filters = {}) { const params = new URLSearchParams({ page: page.toString(), limit: limit.toString(), ...filters, }); return this.get(`/api/admin/analyses?${params}`); } async getAuditLogs(page = 1, limit = 10, filters = {}) { const params = new URLSearchParams({ page: page.toString(), limit: limit.toString(), ...filters, }); return this.get(`/api/admin/audit-logs?${params}`); } async getStatistics() { return this.get('/api/admin/statistics'); } // ============================================ // LLM Configuration APIs // ============================================ async getLLMConfigs() { return this.get('/api/llm-config'); } async getActiveLLMConfig() { return this.get('/api/llm-config/active'); } async createLLMConfig(configData) { return this.post('/api/llm-config', configData); } async updateLLMConfig(id, configData) { return this.put(`/api/llm-config/${id}`, configData); } async activateLLMConfig(id) { return this.put(`/api/llm-config/${id}/activate`, {}); } async deleteLLMConfig(id) { return this.delete(`/api/llm-config/${id}`); } async testLLMConfig(configData) { return this.post('/api/llm-config/test', configData); } // ============================================ // Health Check // ============================================ async healthCheck() { return this.get('/health'); } async dbHealthCheck() { return this.get('/health/db'); } } // 建立單例 const api = new ApiClient(); export default api;