From f52cb5f6a802be07461a8279ca0a21670ac28606 Mon Sep 17 00:00:00 2001 From: jingrow Date: Tue, 23 Sep 2025 13:45:49 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BA=A7=E5=93=81=E5=9B=BE?= =?UTF-8?q?=E7=89=87=E4=B8=8B=E8=BD=BD=E4=B8=BA=E5=B9=B6=E5=8F=91=E4=B8=8B?= =?UTF-8?q?=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 ++ utils/data.js | 108 +++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 92 insertions(+), 19 deletions(-) diff --git a/.gitignore b/.gitignore index 5ef6a52..1cd138b 100644 --- a/.gitignore +++ b/.gitignore @@ -39,3 +39,6 @@ yarn-error.log* # typescript *.tsbuildinfo next-env.d.ts + +# public files +/public/files diff --git a/utils/data.js b/utils/data.js index 8189248..b2eccf1 100644 --- a/utils/data.js +++ b/utils/data.js @@ -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); + if (urls.length > 0) { + htmlTasks.push( + Promise.all(urls.map(url => downloadToLocal(url))).then(localUrls => ({ + key, + urls, + localUrls + })) + ); } - item[key] = html; } } + 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; }