/** * API调用工具类 */ class ApiClient { constructor() { this.baseUrl = ''; } /** * 发送HTTP请求 */ async request(url, options = {}) { const config = { headers: { 'Content-Type': 'application/json', ...options.headers }, ...options }; console.log('=== 前端API请求开始 ==='); console.log('请求URL:', this.baseUrl + url); console.log('请求配置:', config); console.log('请求数据:', options.body); try { const response = await fetch(this.baseUrl + url, config); console.log('响应状态:', response.status); console.log('响应头:', Object.fromEntries(response.headers.entries())); if (!response.ok) { const errorData = await response.json().catch(() => ({})); console.error('API请求失败,错误数据:', errorData); throw new Error(errorData.error || `HTTP ${response.status}: ${response.statusText}`); } // 检查是否是流式响应 if (response.headers.get('content-type')?.includes('text/event-stream')) { console.log('检测到流式响应'); return response; } const jsonData = await response.json(); console.log('响应数据:', jsonData); return jsonData; } catch (error) { console.error('API请求异常:', error); throw error; } } /** * GET请求 */ async get(url, params = {}) { const queryString = new URLSearchParams(params).toString(); const fullUrl = queryString ? `${url}?${queryString}` : url; return this.request(fullUrl, { method: 'GET' }); } /** * POST请求 */ async post(url, data = {}) { return this.request(url, { method: 'POST', body: JSON.stringify(data) }); } /** * DELETE请求 */ async delete(url) { return this.request(url, { method: 'DELETE' }); } /** * 上传文件 */ async uploadFile(url, file) { const formData = new FormData(); formData.append('file', file); return this.request(url, { method: 'POST', body: formData, headers: {} // 让浏览器自动设置Content-Type }); } /** * 处理流式响应 */ async handleStream(response, onData, onComplete, onError) { const reader = response.body.getReader(); const decoder = new TextDecoder(); let buffer = ''; // 用于存储不完整的数据 let chunkCount = 0; console.log('=== 开始处理流式响应 ==='); try { while (true) { const { done, value } = await reader.read(); if (done) { console.log('流式响应结束,处理缓冲区剩余数据...'); // 处理缓冲区中剩余的数据 if (buffer.trim()) { this.processBufferedData(buffer, onData); } onComplete && onComplete(); break; } chunkCount++; const chunk = decoder.decode(value, { stream: true }); console.log(`收到数据块 ${chunkCount}:`, chunk.substring(0, 200) + '...'); // 将新数据添加到缓冲区 buffer += chunk; // 处理完整的行 const lines = buffer.split('\n'); // 保留最后一行(可能不完整) buffer = lines.pop() || ''; // 处理完整的行 for (const line of lines) { if (line.startsWith('data: ')) { const data = line.slice(6).trim(); console.log('处理SSE数据:', data.substring(0, 100) + '...'); if (data === '[DONE]') { console.log('收到结束信号'); onComplete && onComplete(); return; } if (data) { try { const jsonData = JSON.parse(data); console.log('解析的JSON数据:', jsonData); onData && onData(jsonData); } catch (e) { console.error('解析流数据失败:', e); console.error('问题数据:', data.substring(0, 500) + '...'); } } } } } } catch (error) { console.error('流处理错误:', error); onError && onError(error); } } /** * 处理缓冲区中的数据 */ processBufferedData(buffer, onData) { const lines = buffer.split('\n'); for (const line of lines) { if (line.startsWith('data: ')) { const data = line.slice(6).trim(); if (data && data !== '[DONE]') { try { const jsonData = JSON.parse(data); onData && onData(jsonData); } catch (e) { console.warn('处理缓冲数据失败:', e); } } } } } } /** * 图片生成API */ class ImageGenerationApi extends ApiClient { /** * 生成图片 */ async generateImages(params, onProgress) { console.log('=== 开始图片生成请求 ==='); console.log('生成参数:', params); const response = await this.request('/api/generate', { method: 'POST', body: JSON.stringify(params) }); return this.handleStream( response, (data) => { console.log('收到生成进度数据:', data); onProgress && onProgress(data); }, () => { console.log('=== 图片生成完成 ==='); }, (error) => { console.error('=== 图片生成失败 ==='); console.error('错误详情:', error); } ); } } /** * 提示词管理API */ class PromptApi extends ApiClient { /** * 获取所有提示词 */ async getPrompts() { return this.get('/api/prompts'); } /** * 保存提示词 */ async savePrompt(name, content, modelType = 'gemini-3-pro-image-preview') { return this.post('/api/prompts', { name, content, model_type: modelType }); } /** * 删除提示词 */ async deletePrompt(promptId) { return this.delete(`/api/prompts/${promptId}`); } /** * 获取单个提示词 */ async getPrompt(promptId) { return this.get(`/api/prompts/${promptId}`); } } /** * 历史记录API */ class HistoryApi extends ApiClient { /** * 获取生成历史 */ async getHistory(page = 1, limit = 20) { return this.get('/api/history', { page, limit }); } } /** * 文件上传API */ class UploadApi extends ApiClient { /** * 上传图片文件 */ async uploadImage(file) { return this.uploadFile('/api/upload', file); } /** * 验证base64图片 */ async validateBase64Image(base64Data) { return this.post('/api/upload/validate', { base64_data: base64Data }); } } /** * 随机参数配置API */ class RandomOptionsApi extends ApiClient { /** * 获取随机参数配置 */ async getOptions() { return this.get('/api/random-options'); } /** * 保存随机参数配置 */ async saveOptions(data) { return this.post('/api/random-options', { data }); } /** * 添加新类别 */ async addCategory(name, items = []) { return this.post('/api/random-options/category', { name, items }); } /** * 删除类别 */ async deleteCategory(categoryName) { return this.delete(`/api/random-options/category/${encodeURIComponent(categoryName)}`); } /** * 获取勾选状态 */ async getSelection() { return this.get('/api/random-options/selection'); } /** * 保存勾选状态 */ async saveSelection(data) { return this.post('/api/random-options/selection', { data }); } } // 创建全局API实例 window.imageApi = new ImageGenerationApi(); window.promptApi = new PromptApi(); window.historyApi = new HistoryApi(); window.uploadApi = new UploadApi(); window.randomOptionsApi = new RandomOptionsApi();