From b7f0aac6ae4c31d7a85f36ac179f1c9035cb9a0c Mon Sep 17 00:00:00 2001 From: "LUOJIE\\coolp" Date: Thu, 10 Jul 2025 17:58:26 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E4=B8=8B=E8=BD=BD=E6=96=87?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/ipc.js | 86 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/src/main/ipc.js b/src/main/ipc.js index 1ba9168..2a96145 100644 --- a/src/main/ipc.js +++ b/src/main/ipc.js @@ -4,6 +4,9 @@ import { createNewWindow, createWindow, getMainWindow, getDrageWindow, closeApiC import { difyRetryRequestTimer } from './dify.js' import axios from 'axios' import log from 'electron-log/main'; +import fs from 'fs'; +import os from 'os'; +import path from 'path'; log.initialize(); import {checkForUpdates} from "./utils/updateUtils" import logger from './utils/logger' @@ -239,4 +242,87 @@ export function setupIPC() { ipcMain.handle('updateToNewVersion', async (event) => { checkForUpdates({},false) }); + + // 下载文件并打开下载目录 + ipcMain.handle('downloadFile', async (event, { fileUrl }) => { + + logger.info("=============================开始下载文件:",fileUrl) + + try { + // 从URL中提取文件名 + const url = new URL(fileUrl); + const pathname = url.pathname; + let fileName = path.basename(pathname); + + // 如果URL中没有文件名或文件名为空,使用默认名称 + if (!fileName || fileName === '' || fileName === '/') { + fileName = `downloaded_file_${Date.now()}`; + } + + // 如果文件名没有扩展名,尝试从Content-Disposition头获取 + const response = await axios({ + method: "head", + url: fileUrl + }); + + const contentDisposition = response.headers["content-disposition"]; + if (contentDisposition) { + const filenameMatch = contentDisposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/); + if (filenameMatch && filenameMatch[1]) { + const extractedFileName = filenameMatch[1].replace(/['"]/g, ''); + if (extractedFileName && path.extname(extractedFileName)) { + fileName = extractedFileName; + } + } + } + + const outputLocationPath = path.join(os.tmpdir(), fileName); + const writer = fs.createWriteStream(outputLocationPath); + let receivedBytes = 0; + + logger.info(`开始下载文件: ${fileUrl}`); + logger.info(`提取的文件名: ${fileName}`); + logger.info(`保存路径: ${outputLocationPath}`); + + const downloadResponse = await axios({ + method: "get", + url: fileUrl, + responseType: "stream" + }); + + const totalBytes = downloadResponse.headers["content-length"]; + + downloadResponse.data.on("data", (chunk) => { + receivedBytes += chunk.length; + if (totalBytes) { + let progress = Math.floor((receivedBytes / totalBytes) * 100); + // 发送进度给渲染进程 + event.sender.send("download-progress", progress); + } + }); + + downloadResponse.data.pipe(writer); + + return new Promise((resolve, reject) => { + writer.on("finish", async () => { + logger.info(`文件下载完成: ${outputLocationPath}`); + try { + // 打开文件所在目录 + await shell.showItemInFolder(outputLocationPath); + resolve({ success: true, filePath: outputLocationPath, fileName: fileName }); + } catch (error) { + logger.error(`打开目录失败: ${error.message}`); + reject(error); + } + }); + writer.on("error", (error) => { + logger.error(`文件写入失败: ${error.message}`); + reject(error); + }); + }); + } catch (error) { + logger.error(`下载文件失败: ${error.message}`); + throw error; + } + }); }