feat(update): auto-clean old desktop installer packages

This commit is contained in:
2026-02-18 22:14:26 +08:00
parent af51d74a9f
commit fec2bd37a4

View File

@@ -104,6 +104,8 @@ const DOWNLOAD_SIGNED_URL_EXPIRES_SECONDS = Math.max(
const DEFAULT_DESKTOP_VERSION = process.env.DESKTOP_LATEST_VERSION || '0.1.2';
const DEFAULT_DESKTOP_INSTALLER_URL = process.env.DESKTOP_INSTALLER_URL || '';
const DEFAULT_DESKTOP_RELEASE_NOTES = process.env.DESKTOP_RELEASE_NOTES || '';
const DESKTOP_INSTALLERS_DIR = path.resolve(__dirname, '../frontend/downloads');
const DESKTOP_INSTALLER_FILE_PATTERN = /^wanwan-cloud-desktop_.*_x64-setup\.exe$/i;
const RESUMABLE_UPLOAD_SESSION_TTL_MS = Number(process.env.RESUMABLE_UPLOAD_SESSION_TTL_MS || (24 * 60 * 60 * 1000)); // 24小时
const RESUMABLE_UPLOAD_CHUNK_SIZE_BYTES = Number(process.env.RESUMABLE_UPLOAD_CHUNK_SIZE_BYTES || (4 * 1024 * 1024)); // 4MB
const RESUMABLE_UPLOAD_MAX_CHUNK_SIZE_BYTES = Number(process.env.RESUMABLE_UPLOAD_MAX_CHUNK_SIZE_BYTES || (32 * 1024 * 1024)); // 32MB
@@ -184,6 +186,67 @@ function getDesktopUpdateConfig() {
};
}
function resolveDesktopInstallerFileName(installerUrl) {
const raw = String(installerUrl || '').trim();
if (!raw) return null;
try {
const parsed = new URL(raw, 'http://local.invalid');
const pathname = decodeURIComponent(parsed.pathname || '');
const fileName = path.basename(pathname);
return fileName && fileName !== '.' && fileName !== '/' ? fileName : null;
} catch (error) {
const sanitized = raw.split('?')[0].split('#')[0];
const fileName = path.basename(sanitized);
return fileName && fileName !== '.' && fileName !== '/' ? fileName : null;
}
}
function cleanupDesktopInstallerPackages(installerUrl) {
try {
const keepFileName = resolveDesktopInstallerFileName(installerUrl);
if (!keepFileName || !DESKTOP_INSTALLER_FILE_PATTERN.test(keepFileName)) {
return { executed: false, removed: 0, kept: 0, reason: 'installer_url_not_local_package' };
}
if (!fs.existsSync(DESKTOP_INSTALLERS_DIR)) {
return { executed: false, removed: 0, kept: 0, reason: 'downloads_dir_missing' };
}
const candidates = fs.readdirSync(DESKTOP_INSTALLERS_DIR)
.filter((name) => DESKTOP_INSTALLER_FILE_PATTERN.test(name));
const keepFilePath = path.join(DESKTOP_INSTALLERS_DIR, keepFileName);
if (!fs.existsSync(keepFilePath)) {
return { executed: false, removed: 0, kept: candidates.length, reason: 'keep_package_missing' };
}
let removed = 0;
for (const fileName of candidates) {
if (fileName === keepFileName) continue;
fs.unlinkSync(path.join(DESKTOP_INSTALLERS_DIR, fileName));
removed += 1;
console.log(`[桌面端更新] 已清理旧安装包: ${fileName}`);
}
return {
executed: true,
removed,
kept: candidates.length - removed,
keep_file: keepFileName
};
} catch (error) {
console.error('[桌面端更新] 清理旧安装包失败:', error);
return {
executed: false,
removed: 0,
kept: 0,
reason: 'cleanup_failed',
error: error.message
};
}
}
function getResolvedStorageRoot() {
const configuredRoot = process.env.STORAGE_ROOT;
if (!configuredRoot) {
@@ -8693,6 +8756,7 @@ app.post('/api/admin/settings',
download_security,
desktop_update
} = req.body;
let desktopInstallerCleanup = null;
if (max_upload_size !== undefined) {
const size = parseInt(max_upload_size);
@@ -8759,8 +8823,10 @@ app.post('/api/admin/settings',
SettingsDB.set('desktop_latest_version', normalizeVersion(desktop_update.latest_version, DEFAULT_DESKTOP_VERSION));
}
if (desktop_update.installer_url !== undefined) {
SettingsDB.set('desktop_installer_url', String(desktop_update.installer_url || '').trim());
SettingsDB.set('desktop_installer_url_win_x64', String(desktop_update.installer_url || '').trim());
const normalizedInstallerUrl = String(desktop_update.installer_url || '').trim();
SettingsDB.set('desktop_installer_url', normalizedInstallerUrl);
SettingsDB.set('desktop_installer_url_win_x64', normalizedInstallerUrl);
desktopInstallerCleanup = cleanupDesktopInstallerPackages(normalizedInstallerUrl);
}
if (desktop_update.release_notes !== undefined) {
SettingsDB.set('desktop_release_notes', String(desktop_update.release_notes || '').trim());
@@ -8770,10 +8836,14 @@ app.post('/api/admin/settings',
}
}
res.json({
const payload = {
success: true,
message: '系统设置已更新'
});
};
if (desktopInstallerCleanup) {
payload.desktop_installer_cleanup = desktopInstallerCleanup;
}
res.json(payload);
} catch (error) {
console.error('更新系统设置失败:', error);
res.status(500).json({
@@ -10788,6 +10858,10 @@ app.get("/s/:code", (req, res) => {
// 启动时清理旧临时文件
cleanupOldTempFiles();
const desktopCleanupOnStartup = cleanupDesktopInstallerPackages(getDesktopUpdateConfig().installerUrl);
if (desktopCleanupOnStartup.executed && desktopCleanupOnStartup.removed > 0) {
console.log(`[桌面端更新] 启动时已清理 ${desktopCleanupOnStartup.removed} 个旧安装包`);
}
// 启动服务器
app.listen(PORT, '0.0.0.0', () => {