// API Client for DAEL Lab Backend const API_BASE_URL = 'http://localhost:5001/api'; // 辅助函数:发送请求 async function apiRequest(endpoint, options = {}) { const url = `${API_BASE_URL}${endpoint}`; const config = { credentials: 'include', // 包含cookies headers: { 'Content-Type': 'application/json', ...options.headers }, ...options }; if (config.body && typeof config.body === 'object' && !(config.body instanceof FormData)) { config.body = JSON.stringify(config.body); } try { const response = await fetch(url, config); // 检查响应内容类型 const contentType = response.headers.get('content-type'); let data; if (contentType && contentType.includes('application/json')) { data = await response.json(); } else { const text = await response.text(); try { data = JSON.parse(text); } catch { throw new Error(text || 'Invalid response'); } } if (!response.ok) { throw new Error(data.error || `Request failed with status ${response.status}`); } return data; } catch (error) { console.error('API request failed:', error); console.error('URL:', url); console.error('Config:', config); throw error; } } // 认证API const authAPI = { async login(username, password, remember = false) { return apiRequest('/auth/login', { method: 'POST', body: { username, password, remember } }); }, async logout() { return apiRequest('/auth/logout', { method: 'POST' }); }, async register(username, email, password) { return apiRequest('/auth/register', { method: 'POST', body: { username, email, password } }); }, async checkAuth() { return apiRequest('/auth/check', { method: 'GET' }); }, async getCurrentUser() { return apiRequest('/auth/me', { method: 'GET' }); } }; // 内容API const contentAPI = { async getArticles(category = 'news', publishedOnly = true) { return apiRequest(`/cms/articles?category=${category}&published_only=${publishedOnly}`, { method: 'GET' }); }, async getArticle(articleId) { return apiRequest(`/cms/articles/${articleId}`, { method: 'GET' }); }, async createArticle(articleData) { return apiRequest('/cms/articles', { method: 'POST', body: articleData }); }, async updateArticle(articleId, articleData) { return apiRequest(`/cms/articles/${articleId}`, { method: 'PUT', body: articleData }); }, async deleteArticle(articleId) { return apiRequest(`/cms/articles/${articleId}`, { method: 'DELETE' }); }, async getResources(category = null) { const url = category ? `/cms/resources?category=${category}` : '/cms/resources'; return apiRequest(url, { method: 'GET' }); }, async uploadResource(file, name, description, category, isProtected) { const formData = new FormData(); formData.append('file', file); formData.append('name', name); formData.append('description', description || ''); formData.append('category', category || 'document'); formData.append('is_protected', isProtected ? 'true' : 'false'); return apiRequest('/cms/resources', { method: 'POST', headers: {}, // 让浏览器设置Content-Type body: formData }); }, async getTeam(role = null) { const url = role ? `/cms/team?role=${role}` : '/cms/team'; return apiRequest(url, { method: 'GET' }); }, async createTeamMember(memberData) { return apiRequest('/cms/team', { method: 'POST', body: memberData }); } }; // 其他API const api = { async downloadResource(resourceId) { window.location.href = `${API_BASE_URL}/download/${resourceId}`; }, async getStats() { return apiRequest('/stats', { method: 'GET' }); }, async getProtectedContent() { return apiRequest('/protected-content', { method: 'GET' }); } }; // 组会管理API const meetingsAPI = { async getMeetings(status = null, type = null) { let url = '/meetings/meetings'; const params = []; if (status) params.push(`status=${status}`); if (type) params.push(`type=${type}`); if (params.length > 0) url += '?' + params.join('&'); return apiRequest(url, { method: 'GET' }); }, async getMeeting(meetingId) { return apiRequest(`/meetings/meetings/${meetingId}`, { method: 'GET' }); }, async createMeeting(meetingData) { return apiRequest('/meetings/meetings', { method: 'POST', body: meetingData }); }, async updateMeeting(meetingId, meetingData) { return apiRequest(`/meetings/meetings/${meetingId}`, { method: 'PUT', body: meetingData }); }, async deleteMeeting(meetingId) { return apiRequest(`/meetings/meetings/${meetingId}`, { method: 'DELETE' }); }, async registerMeeting(meetingId) { return apiRequest(`/meetings/meetings/${meetingId}/register`, { method: 'POST' }); }, async checkinMeeting(meetingId) { return apiRequest(`/meetings/meetings/${meetingId}/checkin`, { method: 'POST' }); }, async uploadMeetingFile(meetingId, file, name) { const formData = new FormData(); formData.append('file', file); formData.append('name', name || file.name); return apiRequest(`/meetings/meetings/${meetingId}/files`, { method: 'POST', headers: {}, body: formData }); }, async downloadMeetingFile(meetingId, fileId) { window.location.href = `${API_BASE_URL}/meetings/meetings/${meetingId}/files/${fileId}`; } }; // 研究管理API const researchAPI = { async getProjects(status = null, ownerId = null) { let url = '/research/projects'; const params = []; if (status) params.push(`status=${status}`); if (ownerId) params.push(`owner_id=${ownerId}`); if (params.length > 0) url += '?' + params.join('&'); return apiRequest(url, { method: 'GET' }); }, async getProject(projectId) { return apiRequest(`/research/projects/${projectId}`, { method: 'GET' }); }, async createProject(projectData) { return apiRequest('/research/projects', { method: 'POST', body: projectData }); }, async updateProject(projectId, projectData) { return apiRequest(`/research/projects/${projectId}`, { method: 'PUT', body: projectData }); }, async deleteProject(projectId) { return apiRequest(`/research/projects/${projectId}`, { method: 'DELETE' }); }, async getNotes(projectId, noteType = null) { let url = `/research/projects/${projectId}/notes`; if (noteType) url += `?type=${noteType}`; return apiRequest(url, { method: 'GET' }); }, async createNote(projectId, noteData) { return apiRequest(`/research/projects/${projectId}/notes`, { method: 'POST', body: noteData }); }, async updateNote(noteId, noteData) { return apiRequest(`/research/notes/${noteId}`, { method: 'PUT', body: noteData }); }, async deleteNote(noteId) { return apiRequest(`/research/notes/${noteId}`, { method: 'DELETE' }); }, async getTasks(projectId, status = null, assigneeId = null) { let url = `/research/projects/${projectId}/tasks`; const params = []; if (status) params.push(`status=${status}`); if (assigneeId) params.push(`assignee_id=${assigneeId}`); if (params.length > 0) url += '?' + params.join('&'); return apiRequest(url, { method: 'GET' }); }, async createTask(projectId, taskData) { return apiRequest(`/research/projects/${projectId}/tasks`, { method: 'POST', body: taskData }); }, async updateTask(taskId, taskData) { return apiRequest(`/research/tasks/${taskId}`, { method: 'PUT', body: taskData }); }, async deleteTask(taskId) { return apiRequest(`/research/tasks/${taskId}`, { method: 'DELETE' }); }, async uploadResearchFile(projectId, file, name) { const formData = new FormData(); formData.append('file', file); formData.append('name', name || file.name); return apiRequest(`/research/projects/${projectId}/files`, { method: 'POST', headers: {}, body: formData }); }, async downloadResearchFile(projectId, fileId) { window.location.href = `${API_BASE_URL}/research/projects/${projectId}/files/${fileId}`; }, async deleteResearchFile(projectId, fileId) { return apiRequest(`/research/projects/${projectId}/files/${fileId}`, { method: 'DELETE' }); } }; // 导出API window.DAELAPI = { auth: authAPI, content: contentAPI, api: api, meetings: meetingsAPI, research: researchAPI };