@@ -66,7 +66,7 @@ const system = { | |||
}); | |||
watchSocket.on('message', fileChangeHandler); | |||
watchSocket.on('error', errorHandler); | |||
return watchSocket | |||
return watchSocket; | |||
}), | |||
/** | |||
* todo | |||
@@ -100,16 +100,178 @@ const system = { | |||
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); | |||
}); | |||
}), | |||
/** | |||
* 上传文件到工作空间 | |||
* issue: | |||
* + 浏览器的文件上传不会带有本地的文件路径,本地服务是否可以唤起一个选择文件的弹窗? | |||
* 程序步骤: | |||
* + 用户选择本地文件 | |||
* + 用户选择本地文件/文件夹 | |||
* + 文件上传至本地ipfs节点 | |||
* + 将文件的ipfsCid连同文件信息发送到远端服务器 | |||
*/ | |||
uploadFile: safeCall(async (projectId, projectName, folderId, folderName, levelId, fileList, onSuccessHandler, onProgressHandler = identity, onErrorHandler = identity) => { | |||
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); | |||
@@ -23,11 +23,18 @@ | |||
<div class="dragareaBox"> | |||
<div | |||
class="dragarea_top uploadBtn" | |||
@click="clientUpload(), isShowNewFiledialog = false" | |||
@click="selectSystemFiles(), isShowNewFiledialog = false" | |||
> | |||
<img src="static\img\upload.png" alt class="uploadBtnImg" /> | |||
<span class="uploadText">点击上传本地文件</span> | |||
</div> | |||
<div | |||
class="dragarea_top uploadBtn" | |||
@click="selectSystemFolders(), isShowNewFiledialog = false" | |||
> | |||
<img src="static\img\upload.png" alt class="uploadBtnImg" /> | |||
<span class="uploadText">点击上传本地文件夹</span> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
@@ -37,7 +44,8 @@ | |||
export default { | |||
props: { | |||
onButtnClick: Function, | |||
clientUpload: Function, | |||
selectSystemFiles: Function, | |||
selectSystemFolders: Function, | |||
}, | |||
data() { | |||
return { | |||
@@ -190,7 +190,7 @@ | |||
<script> | |||
import system from "@/services/system"; | |||
import LottieSvg from '@/components/lottieSvg'; | |||
import { FileWorkStatus, LoadingEnum } from '../helper'; | |||
import { FileWorkStatus, getFileStoreKey, LoadingEnum } from '../helper'; | |||
const imgExtensionList = ["jpg", "png", "bmp", "gif", "jpeg"]; | |||
const oneOf = (target, list) => list.indexOf(target) !== -1 | |||
@@ -259,13 +259,13 @@ export default { | |||
}, | |||
computed: { | |||
fileStoreKey() { | |||
const { nodeName, extension, archName } = this.file; | |||
const { nodeName, extension, archName, relativePath } = this.file; | |||
const folderName = nodeName ? `${nodeName}\\协作文件` : this.nodeFolder.folderName; | |||
return `${folderName}\\${archName}${extension ? `.${extension}` : ''}`; | |||
return getFileStoreKey(this.file, this.nodeFolder); | |||
}, | |||
isInWorkFolder() { | |||
const { file, currentFolder } = this; | |||
return file.folderId === currentFolder.id; | |||
return file.folderId === this.nodeFolder.id; | |||
}, | |||
localIpfsCid() { | |||
return this.localFileHashMap[this.fileStoreKey]; | |||
@@ -60,7 +60,16 @@ export const FileStatus = { | |||
* @param {*} nodeFolder | |||
*/ | |||
export const getFileStoreKey = (file, nodeFolder) => { | |||
const { nodeName, extension, archName } = file; | |||
const { nodeName, extension, archName, relativePath } = file; | |||
const folderName = nodeName ? `${nodeName}\\协作文件` : nodeFolder.folderName; | |||
return `${folderName}\\${archName}${extension ? `.${extension}` : ''}`; | |||
return `${folderName}\\${relativePath ? `${relativePath.replace(/\//g, '\\')}\\`:''}${archName}${extension ? `.${extension}` : ''}`; | |||
} | |||
export class VirtualFolder { | |||
constructor(id, folderName, parentFolderPath){ | |||
this.id = id; | |||
this.folderPath = id; | |||
this.folderName = folderName; | |||
this.parentFolderPath = parentFolderPath; | |||
} | |||
} |
@@ -1,6 +1,6 @@ | |||
import { fetchApi, wrapErrorHint } from '@/utils/request'; | |||
import { firstCharToLowerCase, firstCharToUpperCase } from '@/utils/tool'; | |||
import { VirtualFolder } from './helper'; | |||
export async function fetchWorkFlow(projectId, userId) { | |||
const res = await fetchApi('folder/queryNodeFolderListByProjectIdAndUserId', { projectId, userId }); | |||
@@ -23,15 +23,33 @@ export async function fetchFolderFileList(folderId, userId, commonFolderId) { | |||
wrapErrorHint(res); | |||
if (res.Code !== 0) return null; | |||
const data = res.Data || {}; | |||
const injectFileBasicValue = upperCaseFile => { | |||
const file = firstCharToLowerCase(upperCaseFile); | |||
return file; | |||
} | |||
const folderList = []; | |||
const folderMap = {}; | |||
const fileList = (data.myFile || []).concat(data.workFile || []) | |||
.map(uppercaseFile => { | |||
const file = firstCharToLowerCase(uppercaseFile); | |||
const relativePath = file.relativePath; | |||
if(relativePath) { | |||
const paths = relativePath.split('/'); | |||
paths.forEach((folderName, idx) => { | |||
const fullRelativePath = paths.slice(0, idx + 1).join('/'); | |||
if(folderMap[fullRelativePath]) return; | |||
const parentRelativePath = paths.slice(0, idx).join('/'); | |||
const folder = new VirtualFolder(fullRelativePath, folderName, parentRelativePath); | |||
folderList.push(folder); | |||
folderMap[fullRelativePath] = folder; | |||
// todo 增加文件夹内的数量检测 | |||
}); | |||
} | |||
return file; | |||
}); | |||
const outputObj = { | |||
folder: (data.folder || []).map(firstCharToLowerCase), | |||
myFile: (data.myFile || []).map(injectFileBasicValue), | |||
workFile: (data.workFile || []).map(injectFileBasicValue), | |||
coordinationFiles: (data.coordinationFiles || []).map(injectFileBasicValue), | |||
folder: folderList, | |||
folderMap, | |||
file: fileList, | |||
// myFile: (data.myFile || []).map(injectFileBasicValue), | |||
// workFile: (data.workFile || []).map(injectFileBasicValue), | |||
coordinationFiles: (data.coordinationFiles || []).map(firstCharToLowerCase), | |||
// public: (data.public || []).map(firstCharToLowerCase), | |||
} | |||
return outputObj; | |||
@@ -63,7 +63,8 @@ | |||
> | |||
<AddFileButton | |||
v-if="isClient" | |||
:clientUpload="clientUpload" | |||
:selectSystemFiles="selectSystemFiles" | |||
:selectSystemFolders="selectSystemFolders" | |||
/> | |||
<!-- 文件上传队列 --> | |||
<div class="list-group"> | |||
@@ -115,7 +116,7 @@ | |||
<div class="list-group"> | |||
<FileItem | |||
class="lisy-group-item" | |||
v-for="file in removeMilestone(workFileList)" | |||
v-for="file in filterFiles(workFileList)" | |||
:key="file.id" | |||
:file="file" | |||
:clientDownLoad="clientDownLoad" | |||
@@ -138,10 +139,10 @@ | |||
<!--显示文件夹组 --> | |||
<div class="list-group"> | |||
<FolderItem | |||
v-for="folder in workSubFolderList" | |||
v-for="folder in filterFolders(subFolderList)" | |||
:key="folder.id" | |||
:folder="folder" | |||
@dblclick.native="infoSubFolder(folder)" | |||
@dblclick.native="intoSubFolder(folder)" | |||
:rightShowMenu="rightShowMenu" | |||
/> | |||
</div> | |||
@@ -262,13 +263,13 @@ | |||
<el-form-item> | |||
<el-input | |||
v-model="folderGroupData.FolderName" | |||
@keyup.enter.native="createFolder" | |||
@keyup.enter.native="createSubFolder" | |||
></el-input> | |||
</el-form-item> | |||
</el-form> | |||
<div slot="footer" class="dialog-footer"> | |||
<el-button @click="dialogNewFolderGroup = false">取 消</el-button> | |||
<el-button @click="createFolder()" type="primary">确 定</el-button> | |||
<el-button @click="createSubFolder()" type="primary">确 定</el-button> | |||
</div> | |||
</el-dialog> | |||
</div> | |||
@@ -295,8 +296,8 @@ import * as services from './service'; | |||
import { firstCharToLowerCase, firstCharToUpperCase, notify } from '@/utils/tool'; | |||
import FileItem from './components/file-item'; | |||
import FolderItem from './components/folder-item'; | |||
import { FileWorkStatus, getFileStoreKey, injectionFileLocalStatus, LoadingEnum } from './helper'; | |||
import { propertyOf } from 'lodash'; | |||
import { FileWorkStatus, getFileStoreKey, injectionFileLocalStatus, LoadingEnum, VirtualFolder } from './helper'; | |||
import { propertyOf, uniqBy } from 'lodash'; | |||
const $ = window.jQuery; | |||
const Velocity = window.Velocity; | |||
@@ -373,12 +374,14 @@ export default { | |||
localWorkspacePrefix: '', // 本地工作目录前缀 | |||
socketIns: null, // 监听文件变化的socket实例 | |||
timerIns: null, // 文件定时任务实例 | |||
folderMap: {}, // 文件夹id哈希: { [folderId]: folder } | |||
folderMap: {}, // 节点文件夹id哈希: { [folderId]: folder } | |||
subFolderMap: {}, // 子文件夹哈希: { [folderPath]: VirtualFolder } | |||
breadcrumbFolderList: [], // 面包屑导航对应的文件夹队列 | |||
uploadFileList: [], // 上传文件的队列 | |||
workFileList: [], // 工作文件队列 | |||
workSubFolderList: [], // 工作文件夹队列 | |||
tempWorkSubFolderList: [], // 临时的工作文件夹队列 | |||
cooperationFileList: [], // 协作文件队列 | |||
neibianju: "neibianju", // 协作文件槽样式 | |||
@@ -435,6 +438,10 @@ export default { | |||
// 当前节点文件夹的名称 | |||
nowFolderName() { | |||
return this.currentNodeFolder.folderName; | |||
}, | |||
subFolderList() { | |||
const uniqSubFolderList = uniqBy(this.workSubFolderList.concat(this.tempWorkSubFolderList), folder => folder.id); | |||
return uniqSubFolderList | |||
} | |||
}, | |||
methods: { | |||
@@ -442,11 +449,30 @@ export default { | |||
oneFileRightBtnClick(id) { | |||
this.tempRightFileId = id; | |||
}, | |||
removeMilestone(filesList){ | |||
return filesList.filter(file=>{ | |||
return file.milestone != 2; | |||
}) | |||
// 文件展示过滤 | |||
filterFiles(fileList) { | |||
// 子文件会有这个属性,节点文件夹不会有 | |||
const { folderPath = '' } = this.currentFolder; | |||
return fileList.filter(file => { | |||
if(file.relativePath !== folderPath) return false; | |||
return true; | |||
}); | |||
}, | |||
// 文件展示过滤 | |||
filterFolders(folderList) { | |||
// 子文件会有这个属性,节点文件夹不会有 | |||
const { folderPath = '' } = this.currentFolder; | |||
return folderList.filter(folder => { | |||
if(folder.parentFolderPath !== folderPath) return false; | |||
return true; | |||
}); | |||
}, | |||
// removeMilestone(filesList){ | |||
// return filesList.filter(file=>{ | |||
// return file.milestone != 2; | |||
// }) | |||
// }, | |||
oneOf(target, list) { | |||
return list.indexOf(target) !== -1; | |||
}, | |||
@@ -628,11 +654,11 @@ export default { | |||
/** | |||
* 进入子文件夹 | |||
*/ | |||
infoSubFolder(folder) { | |||
intoSubFolder(folder) { | |||
this.currentFolder = folder; | |||
this.breadcrumbFolderList.push(folder); | |||
this.clearCurrentFolderFiles(); | |||
this.fetchFolderFiles(); | |||
// this.clearCurrentFolderFiles(); | |||
// this.fetchFolderFiles(); | |||
}, | |||
/** | |||
* 当前工作点击 | |||
@@ -667,18 +693,19 @@ export default { | |||
* 查询当前文件夹内容 | |||
*/ | |||
async fetchFolderFiles() { | |||
const currentFolder = this.currentFolder; | |||
const nodeFolder = this.currentNodeFolder; | |||
const userId = this.userId; | |||
if(!currentFolder || !currentFolder.id) return; | |||
if(!nodeFolder || !nodeFolder.id) return; | |||
// 先清空当前的文件队列 在这清空队列会有闪烁问题,得放在切换显示文件夹内容的地方触发 | |||
// this.uploadFileList = []; | |||
// this.workFileList = []; | |||
// this.workSubFolderList = []; | |||
// this.cooperationFileList = []; | |||
// todo 接口去除公共文件夹配置 | |||
const folderResInfo = await services.fetchFolderFileList(currentFolder.id, userId, currentFolder.id); | |||
const folderResInfo = await services.fetchFolderFileList(nodeFolder.id, userId, nodeFolder.id); | |||
if(!folderResInfo) return; | |||
this.workFileList = folderResInfo.myFile.concat(folderResInfo.workFile); | |||
this.workFileList = folderResInfo.file; | |||
this.subFolderMap = { ...this.subFolderMap, ...folderResInfo.folderMap }; | |||
this.resolveUploadFileList(this.workFileList); | |||
this.workSubFolderList = folderResInfo.folder; | |||
this.cooperationFileList = folderResInfo.coordinationFiles; | |||
@@ -696,35 +723,23 @@ export default { | |||
/** | |||
* 点击确定 保存文件夹组 | |||
*/ | |||
async createFolder(){ | |||
async createSubFolder(){ | |||
if (!this.folderGroupData.FolderName) { | |||
notify.error('请输入文件夹名称!'); | |||
return; | |||
} | |||
this.folderGroupData = { | |||
Id: this.userId, | |||
ProjId:this.projectId, | |||
SuperId:this.currentFolder.id, //this.dbClickSelectedFolderGroupData.id,//this.nowFolder.id, | |||
FirstFolderId: this.currentNodeFolder.firstFolderId, | |||
FolderName: this.folderGroupData.FolderName, | |||
TemplateId: this.currentNodeFolder.templateId, | |||
SysCode: this.currentNodeFolder.sysCode, | |||
FileCount:0, | |||
ChildCount:0, | |||
Deleted:0, | |||
Customed:2, | |||
CreateUserId:this.userId, | |||
CreateTime: new Date(), | |||
ModifyUserId:this.userId, | |||
ModifyTime: new Date(), | |||
} | |||
const Res = await services.createSubFolder(this.folderGroupData); | |||
if (Res.Code != -1) { | |||
this.fetchFolderFiles(); | |||
notify.success('文件夹创建成功!'); | |||
const folderName = this.folderGroupData.FolderName; | |||
const parentFolderPath = this.currentFolder.folderPath || ''; | |||
const folderPath = parentFolderPath ? `${parentFolderPath}/${folderName}` : folderName; | |||
if(this.subFolderMap[folderPath]) { | |||
notify.error('创建失败,已存在同名文件夹!'); | |||
return; | |||
} | |||
const newVirtualFolder = new VirtualFolder(folderPath, folderName, parentFolderPath); | |||
this.subFolderMap[folderPath] = newVirtualFolder; | |||
this.tempWorkSubFolderList.push(newVirtualFolder); | |||
notify.success('文件夹创建成功!'); | |||
this.dialogNewFolderGroup = false; | |||
}, | |||
/** | |||
* 新建文件夹显示弹窗 | |||
@@ -752,23 +767,60 @@ export default { | |||
this.breadcrumbFolderList = this.breadcrumbFolderList.slice(0, breadFolderIdx + 1); | |||
}, | |||
/** | |||
* 客户端上传文件 | |||
* 客户端选择文件列表并上传 | |||
*/ | |||
clientUpload() { | |||
async selectSystemFiles() { | |||
if(!this.isClient) return; | |||
const { folderName, levelId, id: folderId } = this.currentFolder; | |||
// console.log(folderName, levelId, folderId); | |||
system.uploadFile( | |||
this.projectId, this.projectName, folderId, folderName, levelId, this.workFileList, | |||
(file) => { // onSuccess | |||
const {ArchName, IpfsCid, Extension} = file; | |||
const filePaths = await system.chooseFiles(); | |||
if(!filePaths) return; | |||
filePaths.forEach(async fullPath => { | |||
const maybeTasks = await system.analyzeSystemPath(fullPath); | |||
const tasks = maybeTasks || []; | |||
tasks.forEach(uploadTask => this.clientUpload(uploadTask)); | |||
}); | |||
}, | |||
/** | |||
* 客户端选择文件夹列表并上传 | |||
*/ | |||
async selectSystemFolders() { | |||
if(!this.isClient) return; | |||
const folderPaths = await system.chooseFolders(); | |||
if(!folderPaths) return; | |||
// todo 检测文件夹内容 | |||
// check folders Data | |||
// c://dowload | |||
// c://dowload/a/1.jpg | |||
// | |||
// c://dowload/b/1.jpg | |||
}, | |||
/** | |||
* 客户端上传文件 | |||
* uploadTask: { | |||
* fullPath: 本地完整路径 | |||
* fileName: 文件名 | |||
* extension: 扩展名 | |||
* relativePath: 相对路径 | |||
* } | |||
*/ | |||
clientUpload(uploadTask) { | |||
const { folderName, levelId, id: folderId } = this.currentNodeFolder; | |||
const { folderPath = '' } = this.currentFolder; | |||
const { fullPath: sourceFilePath, fileName, extension: fileExtension, } = uploadTask; | |||
const params = { | |||
projectId: this.projectId, | |||
projectName: this.projectName, | |||
folderId, folderName, folderLevelId: levelId, distFileRelativePath: folderPath, | |||
fileName, fileExtension, sourceFilePath, | |||
fileList: this.workFileList, | |||
onSuccess: (file) => { // onSuccess | |||
const {ArchName, IpfsCid, Extension, RelativePath} = file; | |||
// 注入到文件下载检测表中 | |||
const key = `${folderName}\\${ArchName}${Extension ? `.${Extension}`: ''}`; | |||
const key = `${folderName}\\${RelativePath ? `${RelativePath.replace(/\//g, '\\')}\\`: ''}${ArchName}${Extension ? `.${Extension}`: ''}`; | |||
this.addLocalFileRecord(key, IpfsCid); | |||
this.removeFileLoadingState(file.Id); | |||
this.fetchFolderFiles(); | |||
}, | |||
(progressData, upperUploadFile) => { // onLoading | |||
onProgress: (progressData, upperUploadFile) => { // onLoading | |||
const { process, hash, size, currentSize, currentUnit, unit } = progressData; | |||
const uploadFile = firstCharToLowerCase(upperUploadFile); | |||
// 避免使用最后一次progreessData中size被修正为Kb的数据 | |||
@@ -784,11 +836,13 @@ export default { | |||
this.uploadFileList.push(uploadFile); | |||
} | |||
}, | |||
(e, upperFile) => { | |||
onError: (e, upperFile) => { | |||
this.removeFileLoadingState(upperFile.Id); | |||
this.uploadFileList = this.uploadFileList.filter(iFile => iFile.id !== upperFile.Id); | |||
} | |||
); | |||
}, | |||
} | |||
// console.log(folderName, levelId, folderId); | |||
system.uploadFile(params); | |||
}, | |||
/** | |||
* 客户端下载方法 | |||
@@ -803,7 +857,8 @@ export default { | |||
const extensionedFileName = `${fileName}${extension ? `.${extension}`:''}`; | |||
const isCooperateFile = !!nodeName; | |||
const targetFolderName = `${nodeFolderName}${isCooperateFile ? '\\协作文件': ''}`; | |||
const fileStoreKey = `${targetFolderName}\\${extensionedFileName}`; | |||
// const fileStoreKey = `${targetFolderName}\\${extensionedFileName}`; | |||
const fileStoreKey = getFileStoreKey(file, this.currentNodeFolder); | |||
const errorHandler = () => { | |||
this.removeFileLoadingState(file.id); | |||
} | |||
@@ -847,7 +902,8 @@ export default { | |||
this.removeFileLoadingState(file.id); | |||
} | |||
// const fileList = this.currentPageType === 0 ? this.folderFileList.listMyFiles : this.folderFileList.listOtherFiles; | |||
const fileKey = `${folderName}\\${archName}${extension ? `.${extension}`:''}`; | |||
// const fileKey = `${folderName}\\${archName}${extension ? `.${extension}`:''}`; | |||
const fileKey = getFileStoreKey(file, this.currentNodeFolder); | |||
system.updateFile( | |||
file, this.localWorkspacePrefix, | |||
this.projectName, folderName, | |||
@@ -881,7 +937,8 @@ export default { | |||
const folderName = nodeName || this.currentFolder.folderName; | |||
const localWorkspacePrefix = this.localWorkspacePrefix; | |||
const isCooperationFile = !!nodeName; | |||
const fileStoreKey = `${folderName}${isCooperationFile ? '\\协作文件': ''}\\${archName}${extension ? `.${extension}` : ''}`; | |||
// const fileStoreKey = `${folderName}${isCooperationFile ? '\\协作文件': ''}\\${archName}${extension ? `.${extension}` : ''}`; | |||
const fileStoreKey = getFileStoreKey(this.file, this.currentNodeFolder); | |||
if(!this.localFileHashMap[fileStoreKey]) return; | |||
const filePath = `${localWorkspacePrefix}\\${fileStoreKey}`; | |||
if(!isCooperationFile && (file.workStatus === 2 && sessionStorage.userId !== file.modifyUserId)) { | |||