From a4e42abe7f32422e7ad9e27a76a6ffc62684dbc2 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 23 Nov 2020 16:37:13 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=87=E4=BB=B6=E5=A4=B9=E5=8F=B3=E9=94=AE?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=B8=8B=E8=BD=BD=E6=8C=89=E9=92=AE=EF=BC=8C?= =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E4=B8=8B=E8=BD=BD=E5=A2=9E=E5=8A=A0=E9=98=9F?= =?UTF-8?q?=E5=88=97=E9=99=90=E6=B5=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/services/system.js | 393 ++++++++++++++++++++++++----------------- 1 file changed, 230 insertions(+), 163 deletions(-) diff --git a/src/services/system.js b/src/services/system.js index fab9d2eb..4a104f57 100644 --- a/src/services/system.js +++ b/src/services/system.js @@ -9,6 +9,20 @@ import Vue from 'vue'; export const isClient = !!global.electron; // process.env.IS_CLIENT; +const MAX_UPLOAD_ENQUEUE = 5; +const MAX_DOWNLOAD_ENQUEUE = 5; +let uploadingQueue = []; +let uploadQueue = []; +let downloadingQueue = []; +let downloadQueue = []; + +const clearTaskQueue = () => { + uploadingQueue = []; + uploadQueue = []; + downloadingQueue = []; + downloadQueue = []; +} + let socket; const noop = () => {}; @@ -74,31 +88,52 @@ const system = { */ leaveProject: safeCall((watchSocket) => { watchSocket.close(); + clearTaskQueue(); }), /** * 下载文件到工作空间 */ downloadFile: safeCall((fileIpfsId, projectName, fileName, dirName, onProcessHandler, onErrorHandler = identity) => { - const socket = io('download'); - socket.on('open', () => { - socket.send([fileIpfsId, projectName, fileName, dirName].join('|')); - }); - socket.on('message', (e) => { - if(e.data === '-1') { - notify.error('文件下载失败,请检查网络。'); - onErrorHandler(e); - return; - } - if(e.data === '-2') { - notify.error('请先关闭本地文件后再下载'); + + const downloadTask = () => { + const socket = io('download'); + socket.on('open', () => { + socket.send([fileIpfsId, projectName, fileName, dirName].join('|')); + }); + socket.on('message', (e) => { + if(e.data === '-1') { + notify.error('文件下载失败,请检查网络。'); + onErrorHandler(e); + return; + } + if(e.data === '-2') { + notify.error('请先关闭本地文件后再下载'); + onErrorHandler(e); + return; + } + onProcessHandler(e, socket); + }); + socket.on('error', e => { onErrorHandler(e); - return; - } - onProcessHandler(e, socket); - }); - socket.on('error', e => { - onErrorHandler(e); - }); + }); + + socket.on('close', () => { + downloadingQueue = downloadingQueue.filter(iTask => iTask !== downloadTask); + if(downloadQueue.length) { + const nextTask = downloadQueue.shift(); + downloadingQueue.push(nextTask); + nextTask(); + } + }) + } + + if(downloadingQueue.length >= MAX_DOWNLOAD_ENQUEUE) { + downloadQueue.push(downloadTask); + } else { + downloadingQueue.push(downloadTask); + downloadTask(); + } + }), // 解析文件/文件夹路径信息 // { @@ -162,7 +197,6 @@ const system = { * @param {params.onSuccessHandler} 完成上传时的回调 * @param {params.onProgressHandler} 上传进度反馈的回调 * @param {params.onErrorHandler} 上传失败的回调 - * */ uploadFile: safeCall(async (params) => { const { @@ -172,7 +206,7 @@ const system = { fileList, onSuccess: onSuccessHandler, onProgress: onProgressHandler = identity, onError: onErrorHandler = identity } = params; const extensionedFileName = fileExtension ? `${fileName}.${fileExtension}`: fileName; - const distFilePath = `${folderName}/${distFileRelativePath}`; + const distFilePath = `${folderName}${distFileRelativePath ? `/${distFileRelativePath}`: ''}`; const maybeFile = fileList.find(iFile => distFileRelativePath === iFile.relativePath && `${iFile.archName}${iFile.extension ? `.${iFile.extension}` : ''}` === extensionedFileName); // 检测当前工作目录中是否存在同名文件 if(maybeFile) { @@ -215,54 +249,87 @@ const system = { Version: 1, // WorkStatus: 0 }; - - const socket = io('upload'); - socket.on('open', () => { - const data = [sourceFilePath, extensionedFileName, projectName, distFilePath].join('|'); - socket.send(data); - onProgressHandler({ process: 0 }, uploadFile); - }); - - socket.on('message', async (e) => { - console.log('receive download file message:', e); - if(e.data === '-1') { - notify.error('文件上传失败'); - onErrorHandler(e, uploadFile); - return; + + // 预写一条上传信息给页面 + onProgressHandler({ process: 0 }, uploadFile); + + const uploadTask = () => { + const resolveError = (...args) => { + uploadingQueue = uploadingQueue.filter(iTask => iTask !== uploadTask); + if(uploadQueue.length) { + const nextTask = uploadQueue.shift(); + uploadingQueue.push(nextTask); + nextTask(); + } + onErrorHandler(...args); } - if(e.data === '-2') { - notify.error('请先关闭本地文件后再上传'); - onErrorHandler(e, uploadFile); - return; + const resolveSuccess = (...args) => { + uploadingQueue = uploadingQueue.filter(iTask => iTask !== uploadTask); + if(uploadQueue.length) { + const nextTask = uploadQueue.shift(); + uploadingQueue.push(nextTask); + nextTask(); + } + onSuccessHandler(...args); } - try { - const progressData = JSON.parse(e.data); - const { size, process, hash } = progressData; - onProgressHandler(progressData, uploadFile); - if(process !== 100 || !hash) return; - socket.close(); - // {"size":"88.69","currentSize":"88.69","unit":"KiB","process":100,"hash":""} - // {"size":"","currentSize":"","unit":"","process":100,"hash":"QmPJ9i4z5UdoQpLH1DrkhZiTZra2rGicXiPabiLw4LvTmX"} - // const maybeFile = fileList.find(iFile => `${iFile.archName}${iFile.extension ? `.${iFile.extension}` : ''}` === extensionedFileName); - uploadFile.FileSize = +size; - uploadFile.IpfsCid = hash; - if(!maybeFile) { - delete uploadFile.Id; + const socket = io('upload'); + socket.on('open', () => { + const data = [sourceFilePath, extensionedFileName, projectName, distFilePath.replace(/\//g, '\\')].join('|'); + socket.send(data); + onProgressHandler({ process: 0 }, uploadFile); + }); + + socket.on('message', async (e) => { + // console.log('receive download file message:', e); + if(e.data === '-1') { + notify.error('文件上传失败'); + resolveError(e, uploadFile); + return; } - const res = await fetchApi(`file/${maybeFile ? 'updateFile' : 'addFile'}`, uploadFile); - wrapErrorHint(res); - if(res.Code !== 0) return; - //notify.success(maybeFile ? '上传成功, 已覆盖同名文件' : '上传成功'); - notify.success('文件已上传。') - onSuccessHandler(uploadFile); - } catch (e) { - console.error('socket-upload-file parse data have error:', e); + if(e.data === '-2') { + notify.error('请先关闭本地文件后再上传'); + resolveError(e, uploadFile); + return; + } + try { + const progressData = JSON.parse(e.data); + const { size, process, hash } = progressData; + onProgressHandler(progressData, uploadFile); + if(process !== 100 || !hash) return; + socket.close(); + // {"size":"88.69","currentSize":"88.69","unit":"KiB","process":100,"hash":""} + // {"size":"","currentSize":"","unit":"","process":100,"hash":"QmPJ9i4z5UdoQpLH1DrkhZiTZra2rGicXiPabiLw4LvTmX"} + uploadFile.FileSize = +size; + uploadFile.IpfsCid = hash; + if(!maybeFile) { + delete uploadFile.Id; + } + const res = await fetchApi(`file/${maybeFile ? 'updateFile' : 'addFile'}`, uploadFile); + wrapErrorHint(res); + if(res.Code !== 0) { + resolveError(res, uploadFile); + return; + } + //notify.success(maybeFile ? '上传成功, 已覆盖同名文件' : '上传成功'); + notify.success('文件已上传。') + resolveSuccess(uploadFile); + } catch (e) { + console.error('socket-upload-file parse data have error:', e); + resolveError(e, uploadFile); + } + }); + socket.on('error', e => { onErrorHandler(e, uploadFile); - } - }); - socket.on('error', e => { - onErrorHandler(e, uploadFile); - }); + }); + } + + // 处理任务单元 + if(uploadingQueue.length >= MAX_UPLOAD_ENQUEUE) { + uploadQueue.push(uploadTask); + } else { + uploadingQueue.push(uploadTask); + uploadTask(); + } }), /** * 上传文件到工作空间 @@ -271,109 +338,109 @@ const system = { * + 文件上传至本地ipfs节点 * + 将文件的ipfsCid连同文件信息发送到远端服务器 */ - uploadFileOld: safeCall(async (projectId, projectName, folderId, folderName, levelId, fileList, onSuccessHandler, onProgressHandler = identity, onErrorHandler = identity) => { - const { ipcRenderer } = global.electron; - const res = await ipcRenderer.invoke('project-upload-file'); - console.log('ipcRenderer project-selected-upload-file: ', res); - const { canceled, filePaths } = res; - if(canceled) return; - const filePath = filePaths[0]; - const extensionedFileName = filePath.split(/\/|\\/g).pop(); + // uploadFileOld: safeCall(async (projectId, projectName, folderId, folderName, levelId, fileList, onSuccessHandler, onProgressHandler = identity, onErrorHandler = identity) => { + // const { ipcRenderer } = global.electron; + // const res = await ipcRenderer.invoke('project-upload-file'); + // console.log('ipcRenderer project-selected-upload-file: ', res); + // const { canceled, filePaths } = res; + // if(canceled) return; + // const filePath = filePaths[0]; + // const extensionedFileName = filePath.split(/\/|\\/g).pop(); - const tempFilePaths = extensionedFileName.split('.'); - const extension = tempFilePaths.length > 1 ? tempFilePaths.pop() : ''; - const fileName = tempFilePaths.join('.'); + // const tempFilePaths = extensionedFileName.split('.'); + // const extension = tempFilePaths.length > 1 ? tempFilePaths.pop() : ''; + // const fileName = tempFilePaths.join('.'); - const maybeFile = fileList.find(iFile => `${iFile.archName}${iFile.extension ? `.${iFile.extension}` : ''}` === extensionedFileName); - // 检测当前工作目录中是否存在同名文件 - if(maybeFile) { - let confirmRes = false; - try { - await Vue.prototype.$confirm('监测到文件夹存在同名文件,是否继续上传并覆盖同名文件?'); - confirmRes = true; - } catch(e) { console.log('user canceled'); } - if(!confirmRes) return; - } + // const maybeFile = fileList.find(iFile => `${iFile.archName}${iFile.extension ? `.${iFile.extension}` : ''}` === extensionedFileName); + // // 检测当前工作目录中是否存在同名文件 + // if(maybeFile) { + // let confirmRes = false; + // try { + // await Vue.prototype.$confirm('监测到文件夹存在同名文件,是否继续上传并覆盖同名文件?'); + // confirmRes = true; + // } catch(e) { console.log('user canceled'); } + // if(!confirmRes) return; + // } - const uploadFile = maybeFile - ? firstCharToUpperCase({ ...maybeFile, ModifyUserId: sessionStorage.userId }) - : { - // 文件名称 不带扩展名 - ArchName: fileName, - // CommonStatus: 0, - // CreateTime: "string", - // 文件上传者Id - CreateUserId: sessionStorage.userId, - // Deleted: 0, - Extension: extension, - // 文件大小 单位? - // FileSize: +size, - // 所处文件夹id - FolderId: folderId, - // 所处文件夹层级,拼接符:_ - FolderLevelId: levelId, - Id: `upload:${`${Math.random()}`.slice(2, 8)}`, - // IpfsCid: hash, - // IsShowRecycle: 0, - // Milestone: 0, - // ModifyTime: "string", - // ModifyUserId: 0, - // 项目id - ProjId: projectId, - // ShowUrl: "string", - Status: 2, - Version: 1, - // WorkStatus: 0 - }; + // const uploadFile = maybeFile + // ? firstCharToUpperCase({ ...maybeFile, ModifyUserId: sessionStorage.userId }) + // : { + // // 文件名称 不带扩展名 + // ArchName: fileName, + // // CommonStatus: 0, + // // CreateTime: "string", + // // 文件上传者Id + // CreateUserId: sessionStorage.userId, + // // Deleted: 0, + // Extension: extension, + // // 文件大小 单位? + // // FileSize: +size, + // // 所处文件夹id + // FolderId: folderId, + // // 所处文件夹层级,拼接符:_ + // FolderLevelId: levelId, + // Id: `upload:${`${Math.random()}`.slice(2, 8)}`, + // // IpfsCid: hash, + // // IsShowRecycle: 0, + // // Milestone: 0, + // // ModifyTime: "string", + // // ModifyUserId: 0, + // // 项目id + // ProjId: projectId, + // // ShowUrl: "string", + // Status: 2, + // Version: 1, + // // WorkStatus: 0 + // }; - const socket = io('upload'); - socket.on('open', () => { - const data = [filePath, extensionedFileName, projectName, folderName].join('|'); - socket.send(data); - onProgressHandler({ process: 0 }, uploadFile); - }); + // const socket = io('upload'); + // socket.on('open', () => { + // const data = [filePath, extensionedFileName, projectName, folderName].join('|'); + // socket.send(data); + // onProgressHandler({ process: 0 }, uploadFile); + // }); - socket.on('message', async (e) => { - console.log('receive download file message:', e); - if(e.data === '-1') { - notify.error('文件上传失败,请检查网络。'); - onErrorHandler(e, uploadFile); - return; - } - if(e.data === '-2') { - notify.error('请先关闭本地文件后再上传'); - onErrorHandler(e, uploadFile); - return; - } - try { - const progressData = JSON.parse(e.data); - const { size, process, hash } = progressData; - onProgressHandler(progressData, uploadFile); - if(process !== 100 || !hash) return; - socket.close(); - // {"size":"88.69","currentSize":"88.69","unit":"KiB","process":100,"hash":""} - // {"size":"","currentSize":"","unit":"","process":100,"hash":"QmPJ9i4z5UdoQpLH1DrkhZiTZra2rGicXiPabiLw4LvTmX"} - // const maybeFile = fileList.find(iFile => `${iFile.archName}${iFile.extension ? `.${iFile.extension}` : ''}` === extensionedFileName); - uploadFile.FileSize = +size; - uploadFile.IpfsCid = hash; - if(!maybeFile) { - delete uploadFile.Id; - } - const res = await fetchApi(`file/${maybeFile ? 'updateFile' : 'addFile'}`, uploadFile); - wrapErrorHint(res); - if(res.Code !== 0) return; - //notify.success(maybeFile ? '上传成功, 已覆盖同名文件' : '上传成功'); - notify.success('文件已上传。') - onSuccessHandler(uploadFile); - } catch (e) { - console.error('socket-upload-file parse data have error:', e); - onErrorHandler(e, uploadFile); - } - }); - socket.on('error', e => { - onErrorHandler(e, uploadFile); - }); - }), + // socket.on('message', async (e) => { + // console.log('receive download file message:', e); + // if(e.data === '-1') { + // notify.error('文件上传失败,请检查网络。'); + // onErrorHandler(e, uploadFile); + // return; + // } + // if(e.data === '-2') { + // notify.error('请先关闭本地文件后再上传'); + // onErrorHandler(e, uploadFile); + // return; + // } + // try { + // const progressData = JSON.parse(e.data); + // const { size, process, hash } = progressData; + // onProgressHandler(progressData, uploadFile); + // if(process !== 100 || !hash) return; + // socket.close(); + // // {"size":"88.69","currentSize":"88.69","unit":"KiB","process":100,"hash":""} + // // {"size":"","currentSize":"","unit":"","process":100,"hash":"QmPJ9i4z5UdoQpLH1DrkhZiTZra2rGicXiPabiLw4LvTmX"} + // // const maybeFile = fileList.find(iFile => `${iFile.archName}${iFile.extension ? `.${iFile.extension}` : ''}` === extensionedFileName); + // uploadFile.FileSize = +size; + // uploadFile.IpfsCid = hash; + // if(!maybeFile) { + // delete uploadFile.Id; + // } + // const res = await fetchApi(`file/${maybeFile ? 'updateFile' : 'addFile'}`, uploadFile); + // wrapErrorHint(res); + // if(res.Code !== 0) return; + // //notify.success(maybeFile ? '上传成功, 已覆盖同名文件' : '上传成功'); + // notify.success('文件已上传。') + // onSuccessHandler(uploadFile); + // } catch (e) { + // console.error('socket-upload-file parse data have error:', e); + // onErrorHandler(e, uploadFile); + // } + // }); + // socket.on('error', e => { + // onErrorHandler(e, uploadFile); + // }); + // }), /** * 更新本地文件 */