重构: sendMessage复用批量生成逻辑,并添加generateImageWithRetry方法实现API请求重试
This commit is contained in:
205
script.js
205
script.js
@@ -1318,62 +1318,18 @@ const app = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 发送消息 - 生成一张图像
|
// 发送消息 - 生成一张图像(使用批量生成方法)
|
||||||
sendMessage: async function() {
|
sendMessage: async function() {
|
||||||
const messageInput = document.getElementById('messageInput');
|
// 临时设置批量数量为1
|
||||||
const message = messageInput.value.trim();
|
const batchCountInput = document.getElementById('batchCount');
|
||||||
|
const originalBatchCount = batchCountInput.value;
|
||||||
|
batchCountInput.value = 1;
|
||||||
|
|
||||||
if (!message) {
|
// 调用批量生成方法
|
||||||
utils.showNotification('请输入消息', 'warning');
|
await this.sendBatchMessage();
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const apiKey = document.getElementById('apiKey').value;
|
// 恢复原始批量数量
|
||||||
if (!apiKey) {
|
batchCountInput.value = originalBatchCount;
|
||||||
utils.showNotification(ERROR_MESSAGES.NO_API_KEY, 'warning');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 显示加载状态
|
|
||||||
uiController.showLoading(true);
|
|
||||||
|
|
||||||
// 添加用户消息到聊天历史
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// 批量发送消息
|
// 批量发送消息
|
||||||
@@ -1424,38 +1380,46 @@ const app = {
|
|||||||
const promises = [];
|
const promises = [];
|
||||||
for (let i = 0; i < batchCount; i++) {
|
for (let i = 0; i < batchCount; i++) {
|
||||||
promises.push(
|
promises.push(
|
||||||
apiService.generateImage(message, uploadedImages, currentSettings)
|
this.generateImageWithRetry(message, uploadedImages, currentSettings, i, batchCount)
|
||||||
.then(response => {
|
.then(result => {
|
||||||
// 保存第一个响应用于添加聊天消息
|
if (result.success) {
|
||||||
if (!firstResponse) {
|
// 保存第一个响应用于添加聊天消息
|
||||||
firstResponse = response;
|
if (!firstResponse) {
|
||||||
uiController.addChatMessage('assistant', response.content);
|
firstResponse = result.response;
|
||||||
}
|
uiController.addChatMessage('assistant', result.response.content);
|
||||||
|
}
|
||||||
// 显示生成的图像
|
|
||||||
if (response.images && response.images.length > 0) {
|
// 显示生成的图像
|
||||||
// 如果返回多个图像,为每个图像创建新的占位符
|
if (result.response.images && result.response.images.length > 0) {
|
||||||
if (response.images.length > 1) {
|
// 如果返回多个图像,为每个图像创建新的占位符
|
||||||
// 移除原始占位符
|
if (result.response.images.length > 1) {
|
||||||
const originalPlaceholder = document.getElementById(`placeholder-${i}`);
|
// 移除原始占位符
|
||||||
if (originalPlaceholder) {
|
const originalPlaceholder = document.getElementById(`placeholder-${i}`);
|
||||||
originalPlaceholder.remove();
|
if (originalPlaceholder) {
|
||||||
}
|
originalPlaceholder.remove();
|
||||||
|
}
|
||||||
// 为每个图像添加新的图像项
|
|
||||||
response.images.forEach((img, imgIndex) => {
|
// 为每个图像添加新的图像项
|
||||||
uiController.addGeneratedImage(img);
|
result.response.images.forEach((img, imgIndex) => {
|
||||||
});
|
uiController.addGeneratedImage(img);
|
||||||
} else {
|
});
|
||||||
// 只有一个图像,直接替换占位符
|
} else {
|
||||||
uiController.replacePlaceholderWithImage(`placeholder-${i}`, response.images[0]);
|
// 只有一个图像,直接替换占位符
|
||||||
|
uiController.replacePlaceholderWithImage(`placeholder-${i}`, result.response.images[0]);
|
||||||
|
}
|
||||||
|
successCount++;
|
||||||
|
} else {
|
||||||
|
// 没有图像数据,但请求成功,这种情况应该不会发生,因为generateImageWithRetry已经检查了
|
||||||
|
failCount++;
|
||||||
}
|
}
|
||||||
successCount++;
|
|
||||||
} else {
|
} else {
|
||||||
// 移除占位符
|
// 生成失败,检查是否需要保留占位符
|
||||||
const placeholder = document.getElementById(`placeholder-${i}`);
|
if (!result.keepPlaceholder) {
|
||||||
if (placeholder) {
|
// 移除占位符(旧的行为)
|
||||||
placeholder.remove();
|
const placeholder = document.getElementById(`placeholder-${i}`);
|
||||||
|
if (placeholder) {
|
||||||
|
placeholder.remove();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
failCount++;
|
failCount++;
|
||||||
}
|
}
|
||||||
@@ -1464,24 +1428,7 @@ const app = {
|
|||||||
completedCount++;
|
completedCount++;
|
||||||
uiController.showBatchStatus(`已完成 ${completedCount}/${batchCount} 张图像...`);
|
uiController.showBatchStatus(`已完成 ${completedCount}/${batchCount} 张图像...`);
|
||||||
|
|
||||||
return { index: i, response };
|
return { index: i, success: result.success };
|
||||||
})
|
|
||||||
.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 };
|
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -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) {
|
removeImage: function(imageId) {
|
||||||
uploadedImages = uploadedImages.filter(img => img.id !== imageId);
|
uploadedImages = uploadedImages.filter(img => img.id !== imageId);
|
||||||
|
|||||||
Reference in New Issue
Block a user