优化产品图片下载为并发下载

This commit is contained in:
jingrow 2025-09-23 13:45:49 +08:00
parent e20e51d5af
commit f52cb5f6a8
2 changed files with 92 additions and 19 deletions

3
.gitignore vendored
View File

@ -39,3 +39,6 @@ yarn-error.log*
# typescript
*.tsbuildinfo
next-env.d.ts
# public files
/public/files

View File

@ -66,56 +66,126 @@ function extractImageUrlsFromHtml(html) {
export async function processDataItem(item, downloadFiles) {
if (!downloadFiles) return item;
// 收集所有需要下载的文件URL
const downloadTasks = [];
const downloadMap = new Map(); // 用于存储下载结果
// 主表字段下载任务
if (item.image) {
item.image = await downloadToLocal(item.image);
downloadTasks.push(downloadToLocal(item.image).then(url => downloadMap.set('image', url)));
}
if (item.image_1) {
item.image_1 = await downloadToLocal(item.image_1);
downloadTasks.push(downloadToLocal(item.image_1).then(url => downloadMap.set('image_1', url)));
}
if (item.image_2) {
item.image_2 = await downloadToLocal(item.image_2);
downloadTasks.push(downloadToLocal(item.image_2).then(url => downloadMap.set('image_2', url)));
}
if (item.video_src) {
item.video_src = await downloadToLocal(item.video_src);
downloadTasks.push(downloadToLocal(item.video_src).then(url => downloadMap.set('video_src', url)));
}
if (item.file_src) {
item.file_src = await downloadToLocal(item.file_src);
downloadTasks.push(downloadToLocal(item.file_src).then(url => downloadMap.set('file_src', url)));
}
// 处理attachments字段
// 处理attachments字段 - 并发下载
if (item.attachments && Array.isArray(item.attachments)) {
for (const attachment of item.attachments) {
const attachmentTasks = item.attachments.map(async (attachment, index) => {
if (attachment.file_url) {
attachment.file_url = await downloadToLocal(attachment.file_url);
}
const url = await downloadToLocal(attachment.file_url);
return { index, url };
}
return null;
});
downloadTasks.push(...attachmentTasks.filter(task => task !== null));
}
// 处理items字段 - 并发下载
if (item.items && Array.isArray(item.items)) {
for (const subItem of item.items) {
const itemTasks = item.items.map(async (subItem, itemIndex) => {
const subItemDownloads = [];
if (subItem.item_image) {
subItem.item_image = await downloadToLocal(subItem.item_image);
subItemDownloads.push(downloadToLocal(subItem.item_image).then(url => ({ field: 'item_image', url })));
}
if (subItem.item_video_src) {
subItem.item_video_src = await downloadToLocal(subItem.item_video_src);
subItemDownloads.push(downloadToLocal(subItem.item_video_src).then(url => ({ field: 'item_video_src', url })));
}
if (subItem.item_icon) {
subItem.item_icon = await downloadToLocal(subItem.item_icon);
}
subItemDownloads.push(downloadToLocal(subItem.item_icon).then(url => ({ field: 'item_icon', url })));
}
const results = await Promise.all(subItemDownloads);
return { itemIndex, results };
});
downloadTasks.push(...itemTasks);
}
// 处理HTML内容中的图片 - 并发下载
const htmlTasks = [];
for (const key of ['content', 'additional_content', 'description', 'p1', 'p2', 'p3']) {
if (item[key]) {
const urls = extractImageUrlsFromHtml(item[key]);
let html = item[key];
for (const url of urls) {
const localUrl = await downloadToLocal(url);
html = html.replaceAll(url, localUrl);
}
item[key] = html;
if (urls.length > 0) {
htmlTasks.push(
Promise.all(urls.map(url => downloadToLocal(url))).then(localUrls => ({
key,
urls,
localUrls
}))
);
}
}
}
downloadTasks.push(...htmlTasks);
// 并发执行所有下载任务
await Promise.all(downloadTasks);
// 更新主表字段
if (downloadMap.has('image')) item.image = downloadMap.get('image');
if (downloadMap.has('image_1')) item.image_1 = downloadMap.get('image_1');
if (downloadMap.has('image_2')) item.image_2 = downloadMap.get('image_2');
if (downloadMap.has('video_src')) item.video_src = downloadMap.get('video_src');
if (downloadMap.has('file_src')) item.file_src = downloadMap.get('file_src');
// 更新attachments字段
if (item.attachments && Array.isArray(item.attachments)) {
const attachmentResults = downloadTasks.filter(task =>
task && typeof task === 'object' && 'index' in task
);
for (const result of attachmentResults) {
if (result && item.attachments[result.index]) {
item.attachments[result.index].file_url = result.url;
}
}
}
// 更新items字段
if (item.items && Array.isArray(item.items)) {
const itemResults = downloadTasks.filter(task =>
task && typeof task === 'object' && 'itemIndex' in task
);
for (const result of itemResults) {
if (result && item.items[result.itemIndex]) {
for (const fieldResult of result.results) {
item.items[result.itemIndex][fieldResult.field] = fieldResult.url;
}
}
}
}
// 更新HTML内容
const htmlResults = downloadTasks.filter(task =>
task && typeof task === 'object' && 'key' in task
);
for (const result of htmlResults) {
if (result) {
let html = item[result.key];
for (let i = 0; i < result.urls.length; i++) {
html = html.replaceAll(result.urls[i], result.localUrls[i]);
}
item[result.key] = html;
}
}
return item;
}