perf: 优化下载工具

This commit is contained in:
kuaifan 2025-08-15 06:25:07 +08:00
parent eecc6c9e53
commit b05046af29
8 changed files with 55 additions and 42 deletions

2
electron/build.js vendored
View File

@ -8,7 +8,7 @@ const yauzl = require('yauzl');
const axios = require('axios');
const FormData =require('form-data');
const tar = require('tar');
const utils = require('./utils');
const utils = require('./lib/utils');
const config = require('../package.json')
const env = require('dotenv').config({ path: './.env' })
const argv = process.argv;

View File

@ -1,15 +1,15 @@
const {BrowserWindow, screen, shell, ipcMain} = require('electron')
const fs = require('fs');
const path = require('path');
const Store = require("electron-store");
const loger = require("electron-log");
const {default: electronDl, download} = require("@dootask/electron-dl");
const utils = require("./utils");
const {DownloadManager} = require("./utils/download");
const utils = require("./lib/utils");
const {DownloadManager, DownloadStore} = require("./lib/download-manager");
const store = new Store();
const downloadManager = new DownloadManager();
let downloadWindow = null;
let downloadWindow = null,
downloadLanguageCode = 'zh';
function initialize(onStarted= null) {
// 下载配置
@ -32,7 +32,9 @@ function initialize(onStarted= null) {
downloadManager.refresh(item.getSavePath());
syncDownloadItems();
// 尝试更新下载项的错误信息
downloadManager.updateError(item).then(success => {
downloadManager.updateError(item, {
language: downloadLanguageCode,
}).then(success => {
if (success) {
syncDownloadItems();
}
@ -112,11 +114,7 @@ function syncDownloadItems() {
}
}
function getLanguagePack(codeOrPack) {
if (codeOrPack && typeof codeOrPack === 'object') {
return codeOrPack;
}
const code = (codeOrPack || 'zh').toString();
function getLanguageData(code) {
const packs = {
zh: {
// 语言设置
@ -516,12 +514,13 @@ function getLanguagePack(codeOrPack) {
showFailed: 'Ошибка отображения файла: ',
}
};
downloadLanguageCode = code;
return packs[code] || packs.zh;
}
async function open(language = 'zh', theme = 'light') {
// 获取语言包
const finalLanguage = getLanguagePack(language);
const finalLanguage = getLanguageData(language);
// 如果窗口已存在,直接显示
if (downloadWindow) {
@ -553,7 +552,7 @@ async function open(language = 'zh', theme = 'light') {
}
// 恢复窗口位置
const downloadWindowBounds = store.get('downloadWindowBounds', {});
const downloadWindowBounds = DownloadStore.get('downloadWindowBounds', {});
if (
downloadWindowBounds.width !== undefined &&
downloadWindowBounds.height !== undefined &&
@ -585,9 +584,9 @@ async function open(language = 'zh', theme = 'light') {
downloadWindowBounds.width = Math.min(downloadWindowBounds.width, primaryArea.width - 100);
downloadWindowBounds.height = Math.min(downloadWindowBounds.height, primaryArea.height - 100);
}
downloadWindowOptions.center = false;
downloadWindowOptions.width = downloadWindowBounds.width;
downloadWindowOptions.height = downloadWindowBounds.height;
downloadWindowOptions.center = false;
downloadWindowOptions.x = downloadWindowBounds.x;
downloadWindowOptions.y = downloadWindowBounds.y;
}
@ -603,7 +602,7 @@ async function open(language = 'zh', theme = 'light') {
// 监听窗口关闭保存窗口位置
downloadWindow.on('close', () => {
const bounds = downloadWindow.getBounds();
store.set('downloadWindowBounds', bounds);
DownloadStore.set('downloadWindowBounds', bounds);
});
// 监听窗口关闭事件
@ -642,7 +641,7 @@ function destroy() {
async function updateWindow(language, theme) {
if (downloadWindow) {
try {
const finalLanguage = getLanguagePack(language);
const finalLanguage = getLanguageData(language);
downloadWindow.setTitle(finalLanguage.title);
downloadWindow.webContents.send('download-theme', theme);
downloadWindow.webContents.send('download-language', finalLanguage);

View File

@ -9,7 +9,7 @@ const {
const fs = require('fs')
const url = require('url')
const request = require("request");
const utils = require('./utils')
const utils = require('./lib/utils')
const MAILTO_PREFIX = "mailto:";

10
electron/electron.js vendored
View File

@ -38,7 +38,7 @@ const Screenshots = require("electron-screenshots-tool").Screenshots;
const PDFDocument = require('pdf-lib').PDFDocument;
// 本地模块和配置
const utils = require('./utils');
const utils = require('./lib/utils');
const config = require('./package.json');
const electronDown = require("./electron-down");
const electronMenu = require("./electron-menu");
@ -305,7 +305,7 @@ function createMainWindow() {
webSecurity: true,
nodeIntegration: true,
contextIsolation: true,
nativeWindowOpen: true
backgroundThrottling: false,
}
})
@ -456,7 +456,6 @@ function preCreateChildWindow() {
webSecurity: true,
nodeIntegration: true,
contextIsolation: true,
nativeWindowOpen: true
}
});
@ -514,7 +513,6 @@ function createChildWindow(args) {
webSecurity: true,
nodeIntegration: true,
contextIsolation: true,
nativeWindowOpen: true
}, webPreferences),
}, config)
if (options.parent) {
@ -763,9 +761,8 @@ function createWebTabWindow(args) {
webSecurity: true,
nodeIntegration: true,
contextIsolation: true,
nativeWindowOpen: true
},
}, userConf.get('webTabWindow', {})))
}, userConf.get('webTabWindow') || {}))
const originalClose = webTabWindow.close;
webTabWindow.close = function() {
@ -1869,7 +1866,6 @@ function exportVsdx(event, args, directFinalize) {
webSecurity: true,
nodeIntegration: true,
contextIsolation: true,
nativeWindowOpen: true
},
})

View File

@ -1,7 +1,7 @@
const path = require("path");
const loger = require("electron-log");
const Store = require('electron-store');
const utils = require("./index");
const utils = require("./utils");
const store = new Store({
name: 'download-manager',
defaults: {
@ -9,9 +9,20 @@ const store = new Store({
}
});
const DownloadStore = {
get(key, defaultValue) {
return store.get(key, defaultValue);
},
set(key, value) {
store.set(key, value);
},
};
class DownloadManager {
static key = 'downloadHistory';
constructor() {
const history = store.get('downloadHistory', []);
const history = DownloadStore.get(DownloadManager.key, []);
if (utils.isArray(history)) {
this.downloadHistory = history.map(item => ({
...item,
@ -66,7 +77,7 @@ class DownloadManager {
if (this.downloadHistory.length > 1000) {
this.downloadHistory = this.downloadHistory.slice(0, 1000);
}
store.set('downloadHistory', this.downloadHistory);
DownloadStore.set(DownloadManager.key, this.downloadHistory);
}
/**
@ -99,14 +110,15 @@ class DownloadManager {
return;
}
Object.assign(item, this.convert(downloadItem))
store.set('downloadHistory', this.downloadHistory);
DownloadStore.set(DownloadManager.key, this.downloadHistory);
}
/**
* 尝试更新下载项的错误信息
* @param {Electron.DownloadItem} downloadItem
* @param {Object} headers
*/
async updateError(downloadItem) {
async updateError(downloadItem, headers = {}) {
const urls = downloadItem.getURLChain()
const url = urls.length > 0 ? urls[0] : downloadItem.getURL()
const path = downloadItem.getSavePath()
@ -119,6 +131,7 @@ class DownloadManager {
try {
const res = await fetch(url, {
method: 'HEAD',
headers,
})
let error = null
if (res.headers.get('X-Error-Message-Base64')) {
@ -128,7 +141,7 @@ class DownloadManager {
}
if (error) {
Object.assign(item, {error});
store.set('downloadHistory', this.downloadHistory);
DownloadStore.set(DownloadManager.key, this.downloadHistory);
return true;
}
} catch {
@ -209,7 +222,7 @@ class DownloadManager {
if (index > -1) {
this.cancel(path);
this.downloadHistory.splice(index, 1);
store.set('downloadHistory', this.downloadHistory);
DownloadStore.set(DownloadManager.key, this.downloadHistory);
}
}
@ -219,8 +232,8 @@ class DownloadManager {
removeAll() {
this.cancelAll();
this.downloadHistory = [];
store.set('downloadHistory', []);
DownloadStore.set(DownloadManager.key, []);
}
}
module.exports = {DownloadManager};
module.exports = {DownloadStore, DownloadManager};

View File

@ -77,9 +77,9 @@
"output": "dist"
},
"files": [
"lib/**/*",
"render/**/*",
"public/**/*",
"utils/**/*",
"electron-down.js",
"electron-menu.js",
"electron-preload.js",

View File

@ -226,6 +226,18 @@
},
methods: {
async sendAsync(action, args = {}) {
try {
return await electron?.sendAsync("downloadManager", {
action,
...args
});
} catch (e) {
e.message = `${e.message}`.replace(/Error invoking remote method 'downloadManager': Error:\s+/, '');
throw e;
}
},
async copyUrl({url, urls}) {
try {
await navigator.clipboard.writeText(urls.length > 0 ? urls[0] : url);
@ -446,13 +458,6 @@
});
},
sendAsync(action, args = {}) {
return electron?.sendAsync("downloadManager", {
action,
...args
});
},
showToast(message, type = 'success') {
if (this.toast.timer) {
clearTimeout(this.toast.timer);