From 1fb3a45d59718c6017ffe8ce34456668eda73c1a Mon Sep 17 00:00:00 2001 From: Hommy <16620803786@163.com> Date: Thu, 14 May 2026 21:33:11 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A7=A3=E5=86=B3=E6=9D=83=E9=99=90=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- desktop-client/nodeapi/download.js | 46 ++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/desktop-client/nodeapi/download.js b/desktop-client/nodeapi/download.js index 891564a..66d14dd 100644 --- a/desktop-client/nodeapi/download.js +++ b/desktop-client/nodeapi/download.js @@ -67,11 +67,49 @@ async function downloadRemoteMaterialFile(fileUrl, localPath) { const writer = response.data.pipe(createWriteStream(localPath, { flags: "w", mode: 0o666 })); await new Promise((resolve, reject) => { writer.on("close", resolve); - writer.on("error", (err) => reject(err)); - response.data.on("error", (err) => reject(err)); + writer.on("error", (err) => { + fs.unlink(localPath).catch(() => { }); + reject(err); + }); + response.data.on("error", (err) => { + writer.destroy(); + fs.unlink(localPath).catch(() => { }); + reject(err); + }); }); } +/** + * Windows 上“权限异常”多与只读属性有关;Node 对文件的 fs.chmod(0o666) 会清除只读位。 + * 下载完成后统一处理,避免 copyFile / 外部软件间歇性带上只读导致剪映无法改写素材。 + */ +async function ensureWindowsDraftFilesWritable(rootDir) { + if (process.platform !== "win32" || !rootDir) return; + const stack = [rootDir]; + while (stack.length) { + const current = stack.pop(); + let entries; + try { + entries = await fs.readdir(current, { withFileTypes: true }); + } catch { + continue; + } + for (const ent of entries) { + const full = path.join(current, ent.name); + if (ent.isSymbolicLink()) continue; + try { + if (ent.isDirectory()) { + stack.push(full); + } else if (ent.isFile()) { + await fs.chmod(full, 0o666); + } + } catch (e) { + logger.warn(`[perm] 无法调整文件权限(已跳过): ${full} — ${e.message}`); + } + } + } +} + const MAX_DOWNLOAD_ATTEMPTS = 6; async function retryDownloadTask(task, options = {}) { @@ -573,7 +611,7 @@ async function downloadJsonFile( // 4. 将修改后的 JSON 对象转换为格式化的字符串并写入本地文件 const jsonString = JSON.stringify(jsonData, null, 2); // 使用 2 个空格进行缩进,美化输出 - await fs.writeFile(filePath, jsonString, "utf8"); // 指定编码为 utf8 + await fs.writeFile(filePath, jsonString, { encoding: "utf8", mode: 0o666 }); } catch (error) { logger.error(`下载JSON文件失败: ${fileUrl}`, error); throw error; @@ -938,6 +976,8 @@ async function downloadFiles( const jointPath = path.join(baseTargetDir, targetId); logger.info(`[finish] all download: ${jointPath}`); + await ensureWindowsDraftFilesWritable(jointPath); + // 触发剪映目录扫描,使剪映无需重启即可识别新草稿 await triggerDirectoryScan(jointPath);