|
- /**
- * 模拟客户端back server
- * 目前还不知道back的API及具体实现,暂时先抑制代码报错
- */
- import { fetchApi, wrapErrorHint } from '@/utils/request';
- import { notify, firstCharToUpperCase } from '@/utils/tool';
- import { identity } from 'lodash';
- import Vue from 'vue';
-
- export const isClient = !!global.electron; // process.env.IS_CLIENT;
-
- let socket;
- const noop = () => {};
-
- const io = (path) => {
- const sk = new WebSocket(`ws://127.0.0.1:7777/${path}`);
- sk.on = sk.addEventListener;
- return sk;
- }
-
- const requestBySocket = (socketIns, message) => new Promise((resolve, reject) => {
- socketIns.on('open', () => { socketIns.send(message); });
- socketIns.on('message', e => {resolve(e);socketIns.close();});
- socketIns.on('error', e => reject(e));
- });
-
-
- const safeCall = f => isClient ? f : noop;
- const safeSocket = f => (...args) => socket && f(...args);
-
- const system = {
- isClient,
- init: safeCall(() => {
- console.log('客户端 electron API 检测:', global.electron);
- }),
-
- // initialSocket: () => {
- // socket = io('ws://10.240.5.17:8000');
- // // socket = io('ws://127.0.0.1:3000');
- // debugger;
- // socket.on('connect', () => { console.log('本地socket服务连接成功') });
- // },
- /**
- * todo
- * 通知登录
- */
- login: () => {
-
- },
- /**
- * todo
- * 通知登出
- */
- logout: () => {
-
- },
- /**
- * 通知系统进入当前的工作空间
- */
- entryProject: safeCall((projName, userId, fileChangeHandler, initHandler, errorHandler = identity) => {
- requestBySocket(io('init'), [userId, projName].join('|'))
- .then(response => initHandler(response.data));
- const watchSocket = io('subscriptionFileChange');
- watchSocket.on('open', () => {
- watchSocket.send(projName);
- });
- watchSocket.on('message', fileChangeHandler);
- watchSocket.on('error', errorHandler);
- return watchSocket;
- }),
- /**
- * todo
- * 离开工作空间时注销socket
- */
- leaveProject: safeCall((watchSocket) => {
- watchSocket.close();
- }),
- /**
- * 下载文件到工作空间
- */
- 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('请先关闭本地文件后再下载');
- onErrorHandler(e);
- return;
- }
- onProcessHandler(e, socket);
- });
- socket.on('error', e => {
- onErrorHandler(e);
- });
- }),
- // 解析文件/文件夹路径信息
- // {
- // name: '11-28会议纪要.docx',
- // extension:".docx",
- // relativePath:"协同项目\\分析\\11-28会议纪要.docx",
- // absolutePath:"C:\\Users\\yuan_rh\\easycloud\\332174685636661248\\协同项目\\分析\\11-28会议纪要.docx"
- // }
- analyzeSystemPath: safeCall(async (systemFullpath) => {
- const response = await requestBySocket(io('getFolderFileInfo'), systemFullpath);
- try {
- const obj = JSON.parse(response.data);
- const uploadTasks = Object.values(obj).map((data) => {
- const { name: extensionedFileName, extension: dotExtension, relativePath, absolutePath } = data;
- const extension = dotExtension.indexOf('.') === 0 ? dotExtension.slice(1) : dotExtension;
- const fileName = extensionedFileName.slice(0, -dotExtension.length);
- return {
- fileName,
- extension,
- relativePath: relativePath.replace(/(\\)+/g, '/'),
- fullPath: absolutePath,
- };
- });
- return uploadTasks;
- } catch(e) {
- return [];
- }
- }),
- // 选择文件
- chooseFiles: safeCall(async () => {
- const { ipcRenderer } = global.electron;
- const res = await ipcRenderer.invoke('project-choose-files');
- const { canceled, filePaths } = res;
- if(canceled) return null;
- return filePaths;
- }),
- // 选择文件
- chooseFolders: safeCall(async () => {
- const { ipcRenderer } = global.electron;
- const res = await ipcRenderer.invoke('project-choose-folders');
- const { canceled, filePaths } = res;
- if(canceled) return null;
- return filePaths;
- }),
- /**
- * 上传文件到工作空间
- * 程序步骤:
- * + 用户选择本地文件/文件夹
- * + 文件上传至本地ipfs节点
- * + 将文件的ipfsCid连同文件信息发送到远端服务器
- * @param {params.projectId} 项目Id
- * @param {params.projectName} 项目名称
- * @param {params.folderId} 节点文件夹Id
- * @param {params.folderName} 节点文件夹Id
- * @param {params.folderLevelId} 节点文件夹levelId
- * @param {params.distFileRelativePath} 节点文件夹下的相对路径, 直接在节点文件夹下则为空
- * @param {params.sourceFilePath} 上传文件的完整路径
- * @param {params.fileName} 上传文件名
- * @param {params.fileExtension} 上传文件名
- * @param {params.fileList} 用于对比文件名是否重复的文件队列
- * @param {params.onSuccessHandler} 完成上传时的回调
- * @param {params.onProgressHandler} 上传进度反馈的回调
- * @param {params.onErrorHandler} 上传失败的回调
- *
- */
- uploadFile: safeCall(async (params) => {
- const {
- projectId, projectName,
- folderId, folderName, folderLevelId, distFileRelativePath = '',
- fileName, fileExtension, sourceFilePath,
- fileList, onSuccess: onSuccessHandler, onProgress: onProgressHandler = identity, onError: onErrorHandler = identity
- } = params;
- const extensionedFileName = fileExtension ? `${fileName}.${fileExtension}`: fileName;
- const distFilePath = `${folderName}/${distFileRelativePath}`;
- const maybeFile = fileList.find(iFile => distFileRelativePath === iFile.relativePath && `${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: fileExtension,
- // 文件大小 单位?
- // FileSize: +size,
- // 所处文件夹id
- FolderId: folderId,
- // 所处文件夹层级,拼接符:_
- FolderLevelId: folderLevelId,
- Id: `upload:${`${Math.random()}`.slice(2, 8)}`,
- // IpfsCid: hash,
- // IsShowRecycle: 0,
- // Milestone: 0,
- // ModifyTime: "string",
- // ModifyUserId: 0,
- // 项目id
- ProjId: projectId,
- RelativePath: distFileRelativePath,
- // ShowUrl: "string",
- Status: 2,
- 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;
- }
- 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);
- });
- }),
- /**
- * 上传文件到工作空间
- * 程序步骤:
- * + 用户选择本地文件/文件夹
- * + 文件上传至本地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();
-
- 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 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);
- });
-
- 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);
- });
- }),
- /**
- * 更新本地文件
- */
- updateFile: safeCall((file, localFilePathPrefix, projectName, folderName, onSuccessHandler, onProgressHandler = identity, onErrorHandler = identity) => {
- const socket = io('upload');
- const { archName, extension, id: fileId } = file;
- const extensionedFileName = `${archName}${extension ? `.${extension}` : ''}`;
- const filePath = `${localFilePathPrefix}\\${folderName}\\${extensionedFileName}`;
- socket.on('open', () => {
- const data = [filePath, extensionedFileName, projectName, folderName].join('|');
- socket.send(data);
- });
- socket.on('message', async (e) => {
- if(e.data === '-1') {
- notify.error('文件上传失败');
- onErrorHandler(e);
- return;
- }
- if(e.data === '-2') {
- notify.error('请先关闭本地文件后再上传');
- onErrorHandler(e);
- return;
- }
- try {
- const progressData = JSON.parse(e.data);
- const { size, process, hash } = progressData;
- onProgressHandler(progressData);
- if(process !== 100 || !hash) return;
- socket.close();
- const copyFile = firstCharToUpperCase({ ...file, ipfsCid: hash, size: +size, ModifyUserId: sessionStorage.userId });
-
- const res = await fetchApi('file/updateFile', copyFile);
- wrapErrorHint(res);
- // if(res.Code === 0) { notify.success(`${archName} 更新成功`); }
- onSuccessHandler(copyFile);
- return;
- } catch(err) {
- console.error('socket-update-file parse data have error:', e);
- // todo 上传失败
- }
- });
- socket.on('error', e => {
- onErrorHandler(e, file);
- });
- }),
- /**
- * 系统打开文件
- */
- openFile: safeCall((filePath) => {
- const { shell } = global.electron;
- shell.openPath(filePath);
- }),
- /**
- * 系统打开文件目录
- */
- openFolder: safeCall((filePath) => {
- const { shell } = global.electron;
- shell.showItemInFolder(filePath);
- }),
- }
-
- export default system;
|