diff --git a/package.json b/package.json index 53412f1..fc9d9b6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tallynote", - "version": "1.1.40", + "version": "1.1.41", "private": true, "type": "module", "packageManager": "pnpm@9.0.6", diff --git a/server/update-service.ts b/server/update-service.ts index 8fd14cb..adc235c 100644 --- a/server/update-service.ts +++ b/server/update-service.ts @@ -84,12 +84,22 @@ export function triggerInProcessDownload( try { const currentRelease = realpathSync(config.currentLink); if (currentRelease) { - const fsPromises = await import("node:fs/promises"); for (const entry of ["node_modules", "runtime", "pnpm-lock.yaml"] as const) { const source = path.join(currentRelease, entry); - const sourceInfo = await fsPromises.lstat(source).catch(() => null); - if (sourceInfo && !sourceInfo.isSymbolicLink()) { - await fsPromises.cp(source, path.join(stagedDir, entry), { recursive: sourceInfo.isDirectory(), errorOnExist: true, force: false }).catch(() => {}); + const target = path.join(stagedDir, entry); + let copied = false; + try { + const { execFile } = await import("node:child_process"); + const { promisify } = await import("node:util"); + await promisify(execFile)("cp", ["-a", source, target]); + copied = true; + } catch {} + if (!copied) { + const fsPromises = await import("node:fs/promises"); + const sourceInfo = await fsPromises.lstat(source).catch(() => null); + if (sourceInfo && !sourceInfo.isSymbolicLink()) { + await fsPromises.cp(source, target, { recursive: sourceInfo.isDirectory(), errorOnExist: true, force: false }).catch(() => {}); + } } } } diff --git a/web-next/src/pages/update/UpdatePage.tsx b/web-next/src/pages/update/UpdatePage.tsx index baa30ab..0c2a5dd 100644 --- a/web-next/src/pages/update/UpdatePage.tsx +++ b/web-next/src/pages/update/UpdatePage.tsx @@ -929,6 +929,22 @@ export default function UpdatePage({ )} + {/* 场景 B2: 校验与环境就绪中 (verifying) */} + {job?.status === "verifying" && ( +
+
+
+ 正在比对安全指纹并解压更新包... +
+
+ SHA-256 指纹核验通过,正在将生产环境就绪至版本暂存区... +
+

+ 系统正在核对发布包完整性与解压 dist 生产运行结构,校验就绪后将立即亮起“立即应用”按钮。 +

+
+ )} + {/* 场景 C: 校验通过准备就绪 (staged) (Exact ASCII) */} {job?.status === "staged" && (