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

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 # typescript
*.tsbuildinfo *.tsbuildinfo
next-env.d.ts next-env.d.ts
# public files
/public/files

View File

@ -66,56 +66,126 @@ function extractImageUrlsFromHtml(html) {
export async function processDataItem(item, downloadFiles) { export async function processDataItem(item, downloadFiles) {
if (!downloadFiles) return item; if (!downloadFiles) return item;
// 收集所有需要下载的文件URL
const downloadTasks = [];
const downloadMap = new Map(); // 用于存储下载结果
// 主表字段下载任务
if (item.image) { if (item.image) {
item.image = await downloadToLocal(item.image); downloadTasks.push(downloadToLocal(item.image).then(url => downloadMap.set('image', url)));
} }
if (item.image_1) { 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) { 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) { 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) { 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)) { 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) { 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)) { 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) { 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) { 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) { 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']) { for (const key of ['content', 'additional_content', 'description', 'p1', 'p2', 'p3']) {
if (item[key]) { if (item[key]) {
const urls = extractImageUrlsFromHtml(item[key]); const urls = extractImageUrlsFromHtml(item[key]);
let html = item[key]; if (urls.length > 0) {
for (const url of urls) { htmlTasks.push(
const localUrl = await downloadToLocal(url); Promise.all(urls.map(url => downloadToLocal(url))).then(localUrls => ({
html = html.replaceAll(url, localUrl); key,
} urls,
item[key] = html; 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; return item;
} }