mirror of
				https://github.com/1Panel-dev/1Panel.git
				synced 2025-10-28 01:36:56 +08:00 
			
		
		
		
	feat: 实现同时拖拽上传文件和文件夹 (#3135)
Refs https://github.com/1Panel-dev/1Panel/issues/3084
This commit is contained in:
		
							parent
							
								
									bcc89f4d99
								
							
						
					
					
						commit
						762a572c40
					
				
					 4 changed files with 81 additions and 11 deletions
				
			
		|  | @ -1086,7 +1086,7 @@ const message = { | ||||||
|         clearList: 'Clear list', |         clearList: 'Clear list', | ||||||
|         deleteRecycleHelper: 'Are you sure you want to permanently delete the following files?', |         deleteRecycleHelper: 'Are you sure you want to permanently delete the following files?', | ||||||
|         typeErrOrEmpty: '[{0}] file type is wrong or empty folder', |         typeErrOrEmpty: '[{0}] file type is wrong or empty folder', | ||||||
|         dropHelper: 'Drag [{0}] here, or', |         dropHelper: 'Drag the files you want to upload here', | ||||||
|     }, |     }, | ||||||
|     ssh: { |     ssh: { | ||||||
|         autoStart: 'Auto Start', |         autoStart: 'Auto Start', | ||||||
|  |  | ||||||
|  | @ -1035,7 +1035,7 @@ const message = { | ||||||
|         clearList: '清空列表', |         clearList: '清空列表', | ||||||
|         deleteRecycleHelper: '確定永久刪除以下文件?', |         deleteRecycleHelper: '確定永久刪除以下文件?', | ||||||
|         typeErrOrEmpty: '【{0}】 檔案類型錯誤或為空資料夾', |         typeErrOrEmpty: '【{0}】 檔案類型錯誤或為空資料夾', | ||||||
|         dropHelper: '將【{0}】拖曳到此處,或', |         dropHelper: '將需要上傳的文件拖曳到此處', | ||||||
|     }, |     }, | ||||||
|     ssh: { |     ssh: { | ||||||
|         autoStart: '開機自啟', |         autoStart: '開機自啟', | ||||||
|  |  | ||||||
|  | @ -1036,7 +1036,7 @@ const message = { | ||||||
|         clearList: '清空列表', |         clearList: '清空列表', | ||||||
|         deleteRecycleHelper: '确定永久删除以下文件?', |         deleteRecycleHelper: '确定永久删除以下文件?', | ||||||
|         typeErrOrEmpty: '【{0}】 文件类型错误或为空文件夹', |         typeErrOrEmpty: '【{0}】 文件类型错误或为空文件夹', | ||||||
|         dropHelper: '将【{0}】拖拽到此处,或者', |         dropHelper: '将需要上传的文件拖曳到此处', | ||||||
|     }, |     }, | ||||||
|     ssh: { |     ssh: { | ||||||
|         autoStart: '开机自启', |         autoStart: '开机自启', | ||||||
|  |  | ||||||
|  | @ -19,9 +19,21 @@ | ||||||
|             <el-button @click="clearFiles">{{ $t('file.clearList') }}</el-button> |             <el-button @click="clearFiles">{{ $t('file.clearList') }}</el-button> | ||||||
|         </div> |         </div> | ||||||
| 
 | 
 | ||||||
|  |         <div> | ||||||
|  |             <div class="el-upload-dragger" @dragover="handleDragover" @drop="handleDrop" @dragleave="handleDragleave"> | ||||||
|  |                 <div class="flex items-center justify-center h-52"> | ||||||
|  |                     <div> | ||||||
|  |                         <el-icon class="el-icon--upload"><upload-filled /></el-icon> | ||||||
|  |                         <div class="el-upload__text"> | ||||||
|  |                             {{ $t('file.dropHelper') }} | ||||||
|  |                         </div> | ||||||
|  |                     </div> | ||||||
|  |                 </div> | ||||||
|  |             </div> | ||||||
|  |         </div> | ||||||
|  | 
 | ||||||
|         <el-upload |         <el-upload | ||||||
|             action="#" |             action="#" | ||||||
|             drag |  | ||||||
|             :auto-upload="false" |             :auto-upload="false" | ||||||
|             ref="uploadRef" |             ref="uploadRef" | ||||||
|             :on-change="fileOnChange" |             :on-change="fileOnChange" | ||||||
|  | @ -30,17 +42,14 @@ | ||||||
|             :show-file-list="false" |             :show-file-list="false" | ||||||
|             multiple |             multiple | ||||||
|             v-model:file-list="uploaderFiles" |             v-model:file-list="uploaderFiles" | ||||||
|  |             :limit="10" | ||||||
|         > |         > | ||||||
|             <el-icon class="el-icon--upload"><upload-filled /></el-icon> |  | ||||||
|             <div class="el-upload__text"> |  | ||||||
|                 {{ $t('file.dropHelper', [$t('file.' + uploadType)]) }} |  | ||||||
|                 <em>{{ $t('database.clickHelper') }}</em> |  | ||||||
|             </div> |  | ||||||
|             <template #tip> |             <template #tip> | ||||||
|                 <el-text>{{ uploadHelper }}</el-text> |                 <el-text>{{ uploadHelper }}</el-text> | ||||||
|                 <el-progress v-if="loading" text-inside :stroke-width="20" :percentage="uploadPrecent"></el-progress> |                 <el-progress v-if="loading" text-inside :stroke-width="20" :percentage="uploadPrecent"></el-progress> | ||||||
|             </template> |             </template> | ||||||
|         </el-upload> |         </el-upload> | ||||||
|  | 
 | ||||||
|         <div> |         <div> | ||||||
|             <p |             <p | ||||||
|                 v-for="(item, index) in uploaderFiles" |                 v-for="(item, index) in uploaderFiles" | ||||||
|  | @ -126,6 +135,66 @@ const removeFile = (index: number) => { | ||||||
|     uploaderFiles.value.splice(index, 1); |     uploaderFiles.value.splice(index, 1); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | const handleDragover = (event: DragEvent) => { | ||||||
|  |     event.preventDefault(); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | const handleDrop = (event: DragEvent) => { | ||||||
|  |     event.preventDefault(); | ||||||
|  |     const items = event.dataTransfer.items; | ||||||
|  | 
 | ||||||
|  |     if (items) { | ||||||
|  |         for (let i = 0; i < items.length; i++) { | ||||||
|  |             const entry = items[i].webkitGetAsEntry(); | ||||||
|  |             if (entry) { | ||||||
|  |                 traverseFileTree(entry); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | const convertFileToUploadFile = (file: File, path: string): UploadFile => { | ||||||
|  |     const uid = Date.now(); | ||||||
|  | 
 | ||||||
|  |     const uploadRawFile: UploadRawFile = new File([file], file.name, { | ||||||
|  |         type: file.type, | ||||||
|  |         lastModified: file.lastModified, | ||||||
|  |     }) as UploadRawFile; | ||||||
|  |     uploadRawFile.uid = uid; | ||||||
|  | 
 | ||||||
|  |     let fileName = file.name; | ||||||
|  |     if (path != '') { | ||||||
|  |         fileName = path + file.name; | ||||||
|  |     } | ||||||
|  |     return { | ||||||
|  |         name: fileName, | ||||||
|  |         size: file.size, | ||||||
|  |         status: 'ready', | ||||||
|  |         uid: uid, | ||||||
|  |         raw: uploadRawFile, | ||||||
|  |     }; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | const traverseFileTree = (item: any, path = '') => { | ||||||
|  |     path = path || ''; | ||||||
|  |     if (item.isFile) { | ||||||
|  |         item.file((file: File) => { | ||||||
|  |             uploaderFiles.value.push(convertFileToUploadFile(file, path)); | ||||||
|  |         }); | ||||||
|  |     } else if (item.isDirectory) { | ||||||
|  |         const dirReader = item.createReader(); | ||||||
|  |         dirReader.readEntries((entries) => { | ||||||
|  |             for (let i = 0; i < entries.length; i++) { | ||||||
|  |                 traverseFileTree(entries[i], path + item.name + '/'); | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | const handleDragleave = (event) => { | ||||||
|  |     event.preventDefault(); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| const fileOnChange = (_uploadFile: UploadFile, uploadFiles: UploadFiles) => { | const fileOnChange = (_uploadFile: UploadFile, uploadFiles: UploadFiles) => { | ||||||
|     if (_uploadFile.size == 64 || _uploadFile.size == 0) { |     if (_uploadFile.size == 64 || _uploadFile.size == 0) { | ||||||
|         uploaderFiles.value = uploadFiles; |         uploaderFiles.value = uploadFiles; | ||||||
|  | @ -172,8 +241,9 @@ const submit = async () => { | ||||||
|             if (file.raw.webkitRelativePath != '') { |             if (file.raw.webkitRelativePath != '') { | ||||||
|                 formData.append('path', path.value + '/' + getPathWithoutFilename(file.raw.webkitRelativePath)); |                 formData.append('path', path.value + '/' + getPathWithoutFilename(file.raw.webkitRelativePath)); | ||||||
|             } else { |             } else { | ||||||
|                 formData.append('path', path.value); |                 formData.append('path', path.value + '/' + getPathWithoutFilename(file.name)); | ||||||
|             } |             } | ||||||
|  |             uploadPrecent.value = 0; | ||||||
|             await UploadFileData(formData, { |             await UploadFileData(formData, { | ||||||
|                 onUploadProgress: (progressEvent) => { |                 onUploadProgress: (progressEvent) => { | ||||||
|                     const progress = Math.round((progressEvent.loaded / progressEvent.total) * 100); |                     const progress = Math.round((progressEvent.loaded / progressEvent.total) * 100); | ||||||
|  | @ -197,7 +267,7 @@ const submit = async () => { | ||||||
|                 if (file.raw.webkitRelativePath != '') { |                 if (file.raw.webkitRelativePath != '') { | ||||||
|                     formData.append('path', path.value + '/' + getPathWithoutFilename(file.raw.webkitRelativePath)); |                     formData.append('path', path.value + '/' + getPathWithoutFilename(file.raw.webkitRelativePath)); | ||||||
|                 } else { |                 } else { | ||||||
|                     formData.append('path', path.value); |                     formData.append('path', path.value + '/' + getPathWithoutFilename(file.name)); | ||||||
|                 } |                 } | ||||||
|                 formData.append('chunk', chunk); |                 formData.append('chunk', chunk); | ||||||
|                 formData.append('chunkIndex', c.toString()); |                 formData.append('chunkIndex', c.toString()); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue