fix(core): 修复nwjs下server端文件下载异常

This commit is contained in:
王立帮
2025-09-30 08:39:23 +08:00
parent f9d9c4c7ae
commit 5651def093
2 changed files with 71 additions and 32 deletions

View File

@@ -172,72 +172,106 @@ router.get('/download', async (req, res) => {
try {
const { url, cloudVersion } = req.query;
if(fs.existsSync(TEMP_FOLDER_PATH)) {
// 清理临时文件夹
if (fs.existsSync(TEMP_FOLDER_PATH)) {
deleteFolderRecursive(TEMP_FOLDER_PATH);
}
fs.mkdirSync(TEMP_FOLDER_PATH);
fs.mkdirSync(TEMP_FOLDER_PATH, { recursive: true });
const filePath = path.resolve(TEMP_FOLDER_PATH, 'mixly.zip');
const fileStream = fs.createWriteStream(filePath);
// 设置响应头
// 设置 SSE 响应头
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Transfer-Encoding', 'chunked');
res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Connection', 'keep-alive');
res.flushHeaders();
// 发起下载请求
// 发起下载请求 - 添加 NW.js 特定配置
const response = await axios({
method: 'GET',
url: url,
responseType: 'stream'
responseType: 'stream',
timeout: 60000,
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
},
adapter: require('axios/lib/adapters/http')
});
const totalSize = parseInt(response.headers['content-length'], 10);
const totalSize = parseInt(response.headers['content-length'], 10) || 0;
let downloadedSize = 0;
let lastProgress = 0;
// 发送进度信息
const sendProgress = (progress) => {
if(progress !== lastProgress) {
res.write('data:' + JSON.stringify({ type: 'progress', progress }) + '\n\n');
if (progress !== lastProgress) {
const data = JSON.stringify({ type: 'progress', progress });
res.write(`data: ${data}\n\n`);
lastProgress = progress;
}
};
// 发送解压信息
const sendUnzip = () => {
res.write('data:' + JSON.stringify({ type: 'unzip' }) + '\n\n');
};
// 发送完成信息
const sendComplete = (version) => {
res.write('data:' + JSON.stringify({ type: 'complete', version }) + '\n\n');
res.end();
};
// 管道流处理
response.data.pipe(fileStream);
// 处理数据流
// 进度监控
response.data.on('data', (chunk) => {
downloadedSize += chunk.length;
const progress = Math.round((downloadedSize / totalSize) * 100);
sendProgress(progress);
if (totalSize > 0) {
const progress = Math.round((downloadedSize / totalSize) * 100);
sendProgress(progress);
}
});
// 文件流完成
fileStream.on('finish', async () => {
// 获取版本信息并保存
saveVersionInfo(cloudVersion);
sendUnzip();
console.log('文件下载完成,开始解压');
// 发送解压信息
res.write(`data: ${JSON.stringify({ type: 'unzip' })}\n\n`);
try {
const asyncZip = new AsyncAdmZip(filePath);
await asyncZip.extractAllTo(path.resolve(__dirname, '../'));
sendComplete(cloudVersion);
if(fs.existsSync(TEMP_FOLDER_PATH)) {
// 保存版本信息
saveVersionInfo(cloudVersion);
// 发送完成信息
res.write(`data: ${JSON.stringify({ type: 'complete', version: cloudVersion })}\n\n`);
// 清理临时文件
if (fs.existsSync(TEMP_FOLDER_PATH)) {
deleteFolderRecursive(TEMP_FOLDER_PATH);
}
res.end();
} catch (error) {
console.log(error);
res.status(500).json({ error: '解压失败' });
console.error('解压失败:', error);
res.write(`data: ${JSON.stringify({ type: 'error', message: '解压失败' })}\n\n`);
res.end();
}
});
// 错误处理
response.data.on('error', (error) => {
console.error('下载流错误:', error);
res.write(`data: ${JSON.stringify({ type: 'error', message: '下载流错误' })}\n\n`);
res.end();
});
fileStream.on('error', (error) => {
console.error('文件流错误:', error);
res.write(`data: ${JSON.stringify({ type: 'error', message: '文件保存错误' })}\n\n`);
res.end();
});
} catch (error) {
console.log(error.message);
res.status(500).json({ error: '下载失败' });
console.error('下载过程错误:', error);
res.write(`data: ${JSON.stringify({ type: 'error', message: '下载失败: ' + error.message })}\n\n`);
res.end();
}
});