重构: sendMessage复用批量生成逻辑,并添加generateImageWithRetry方法实现API请求重试
This commit is contained in:
205
script.js
205
script.js
@@ -1318,62 +1318,18 @@ const app = {
|
||||
}
|
||||
},
|
||||
|
||||
// 发送消息 - 生成一张图像
|
||||
// 发送消息 - 生成一张图像(使用批量生成方法)
|
||||
sendMessage: async function() {
|
||||
const messageInput = document.getElementById('messageInput');
|
||||
const message = messageInput.value.trim();
|
||||
// 临时设置批量数量为1
|
||||
const batchCountInput = document.getElementById('batchCount');
|
||||
const originalBatchCount = batchCountInput.value;
|
||||
batchCountInput.value = 1;
|
||||
|
||||
if (!message) {
|
||||
utils.showNotification('请输入消息', 'warning');
|
||||
return;
|
||||
}
|
||||
|
||||
const apiKey = document.getElementById('apiKey').value;
|
||||
if (!apiKey) {
|
||||
utils.showNotification(ERROR_MESSAGES.NO_API_KEY, 'warning');
|
||||
return;
|
||||
}
|
||||
|
||||
// 显示加载状态
|
||||
uiController.showLoading(true);
|
||||
// 调用批量生成方法
|
||||
await this.sendBatchMessage();
|
||||
|
||||
// 添加用户消息到聊天历史
|
||||
uiController.addChatMessage('user', message);
|
||||
|
||||
try {
|
||||
const response = await apiService.generateImage(message, uploadedImages, currentSettings);
|
||||
|
||||
// 添加助手回复到聊天历史
|
||||
uiController.addChatMessage('assistant', response.content);
|
||||
|
||||
// 显示生成的图像
|
||||
if (response.images && response.images.length > 0) {
|
||||
response.images.forEach(img => {
|
||||
uiController.addGeneratedImage(img);
|
||||
});
|
||||
|
||||
// 检查存储空间
|
||||
await utils.checkAndCleanStorage();
|
||||
|
||||
// 提示用户存储空间有限
|
||||
utils.showNotification('已生成图像,但请注意本地存储空间有限,建议及时下载重要图像', 'info');
|
||||
}
|
||||
|
||||
// 清空输入框
|
||||
messageInput.value = '';
|
||||
|
||||
// 显示使用统计
|
||||
if (response.usage) {
|
||||
console.log('API Usage:', response.usage);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('生成图像失败:', error);
|
||||
uiController.addChatMessage('assistant', `生成图像失败: ${error.message}`);
|
||||
utils.showNotification(`生成图像失败: ${error.message}`, 'danger');
|
||||
} finally {
|
||||
uiController.showLoading(false);
|
||||
}
|
||||
// 恢复原始批量数量
|
||||
batchCountInput.value = originalBatchCount;
|
||||
},
|
||||
|
||||
// 批量发送消息
|
||||
@@ -1424,38 +1380,46 @@ const app = {
|
||||
const promises = [];
|
||||
for (let i = 0; i < batchCount; i++) {
|
||||
promises.push(
|
||||
apiService.generateImage(message, uploadedImages, currentSettings)
|
||||
.then(response => {
|
||||
// 保存第一个响应用于添加聊天消息
|
||||
if (!firstResponse) {
|
||||
firstResponse = response;
|
||||
uiController.addChatMessage('assistant', response.content);
|
||||
}
|
||||
|
||||
// 显示生成的图像
|
||||
if (response.images && response.images.length > 0) {
|
||||
// 如果返回多个图像,为每个图像创建新的占位符
|
||||
if (response.images.length > 1) {
|
||||
// 移除原始占位符
|
||||
const originalPlaceholder = document.getElementById(`placeholder-${i}`);
|
||||
if (originalPlaceholder) {
|
||||
originalPlaceholder.remove();
|
||||
}
|
||||
|
||||
// 为每个图像添加新的图像项
|
||||
response.images.forEach((img, imgIndex) => {
|
||||
uiController.addGeneratedImage(img);
|
||||
});
|
||||
} else {
|
||||
// 只有一个图像,直接替换占位符
|
||||
uiController.replacePlaceholderWithImage(`placeholder-${i}`, response.images[0]);
|
||||
this.generateImageWithRetry(message, uploadedImages, currentSettings, i, batchCount)
|
||||
.then(result => {
|
||||
if (result.success) {
|
||||
// 保存第一个响应用于添加聊天消息
|
||||
if (!firstResponse) {
|
||||
firstResponse = result.response;
|
||||
uiController.addChatMessage('assistant', result.response.content);
|
||||
}
|
||||
|
||||
// 显示生成的图像
|
||||
if (result.response.images && result.response.images.length > 0) {
|
||||
// 如果返回多个图像,为每个图像创建新的占位符
|
||||
if (result.response.images.length > 1) {
|
||||
// 移除原始占位符
|
||||
const originalPlaceholder = document.getElementById(`placeholder-${i}`);
|
||||
if (originalPlaceholder) {
|
||||
originalPlaceholder.remove();
|
||||
}
|
||||
|
||||
// 为每个图像添加新的图像项
|
||||
result.response.images.forEach((img, imgIndex) => {
|
||||
uiController.addGeneratedImage(img);
|
||||
});
|
||||
} else {
|
||||
// 只有一个图像,直接替换占位符
|
||||
uiController.replacePlaceholderWithImage(`placeholder-${i}`, result.response.images[0]);
|
||||
}
|
||||
successCount++;
|
||||
} else {
|
||||
// 没有图像数据,但请求成功,这种情况应该不会发生,因为generateImageWithRetry已经检查了
|
||||
failCount++;
|
||||
}
|
||||
successCount++;
|
||||
} else {
|
||||
// 移除占位符
|
||||
const placeholder = document.getElementById(`placeholder-${i}`);
|
||||
if (placeholder) {
|
||||
placeholder.remove();
|
||||
// 生成失败,检查是否需要保留占位符
|
||||
if (!result.keepPlaceholder) {
|
||||
// 移除占位符(旧的行为)
|
||||
const placeholder = document.getElementById(`placeholder-${i}`);
|
||||
if (placeholder) {
|
||||
placeholder.remove();
|
||||
}
|
||||
}
|
||||
failCount++;
|
||||
}
|
||||
@@ -1464,24 +1428,7 @@ const app = {
|
||||
completedCount++;
|
||||
uiController.showBatchStatus(`已完成 ${completedCount}/${batchCount} 张图像...`);
|
||||
|
||||
return { index: i, response };
|
||||
})
|
||||
.catch(error => {
|
||||
console.error(`生成第 ${i + 1} 张图像失败:`, error);
|
||||
|
||||
// 移除占位符
|
||||
const placeholder = document.getElementById(`placeholder-${i}`);
|
||||
if (placeholder) {
|
||||
placeholder.remove();
|
||||
}
|
||||
|
||||
failCount++;
|
||||
|
||||
// 更新完成计数和状态
|
||||
completedCount++;
|
||||
uiController.showBatchStatus(`已完成 ${completedCount}/${batchCount} 张图像...`);
|
||||
|
||||
return { index: i, error };
|
||||
return { index: i, success: result.success };
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -1508,6 +1455,62 @@ const app = {
|
||||
}
|
||||
},
|
||||
|
||||
// 带重试机制的图像生成方法
|
||||
generateImageWithRetry: async function(message, images, settings, imageIndex, totalImages) {
|
||||
const maxRetries = 5;
|
||||
let retryCount = 0;
|
||||
|
||||
while (retryCount <= maxRetries) {
|
||||
try {
|
||||
const response = await apiService.generateImage(message, images, settings);
|
||||
|
||||
// 检查响应中是否包含图像
|
||||
if (!response.images || response.images.length === 0) {
|
||||
throw new Error('生成响应中没有图像数据');
|
||||
}
|
||||
|
||||
return { success: true, response: response };
|
||||
} catch (error) {
|
||||
retryCount++;
|
||||
console.error(`生成第 ${imageIndex + 1} 张图像失败,重试次数 ${retryCount}/${maxRetries}:`, error);
|
||||
|
||||
if (retryCount <= maxRetries) {
|
||||
// 更新占位符状态,显示重试信息
|
||||
const placeholder = document.getElementById(`placeholder-${imageIndex}`);
|
||||
if (placeholder) {
|
||||
const placeholderText = placeholder.querySelector('.image-placeholder-text');
|
||||
if (placeholderText) {
|
||||
placeholderText.textContent = `正在重试生成图像 ${imageIndex + 1}/${totalImages} (${retryCount}/${maxRetries})`;
|
||||
}
|
||||
}
|
||||
|
||||
// 等待一段时间后重试,使用指数退避策略
|
||||
const delayTime = 1000 * Math.pow(2, retryCount - 1);
|
||||
await new Promise(resolve => setTimeout(resolve, delayTime));
|
||||
} else {
|
||||
// 重试次数用完,返回失败,但不要移除占位符
|
||||
// 更新占位符显示最终失败状态
|
||||
const placeholder = document.getElementById(`placeholder-${imageIndex}`);
|
||||
if (placeholder) {
|
||||
const placeholderText = placeholder.querySelector('.image-placeholder-text');
|
||||
if (placeholderText) {
|
||||
placeholderText.textContent = `生成图像 ${imageIndex + 1}/${totalImages} 失败,已重试 ${maxRetries} 次`;
|
||||
}
|
||||
const placeholderIcon = placeholder.querySelector('.image-placeholder-icon');
|
||||
if (placeholderIcon) {
|
||||
placeholderIcon.className = 'fas fa-exclamation-triangle image-placeholder-icon';
|
||||
placeholderIcon.style.color = '#dc3545';
|
||||
}
|
||||
}
|
||||
return { success: false, error: error, keepPlaceholder: true };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 重试次数用完,返回失败,但不要移除占位符
|
||||
return { success: false, error: new Error('重试次数用完'), keepPlaceholder: true };
|
||||
},
|
||||
|
||||
// 移除上传的图像
|
||||
removeImage: function(imageId) {
|
||||
uploadedImages = uploadedImages.filter(img => img.id !== imageId);
|
||||
|
||||
Reference in New Issue
Block a user