diff --git a/backend/utils/docker/docker.go b/backend/utils/docker/docker.go index c4532e43a..4d6179954 100644 --- a/backend/utils/docker/docker.go +++ b/backend/utils/docker/docker.go @@ -2,6 +2,7 @@ package docker import ( "context" + "github.com/docker/docker/api/types/container" "github.com/1Panel-dev/1Panel/backend/app/model" "github.com/1Panel-dev/1Panel/backend/global" @@ -45,7 +46,7 @@ func NewDockerClient() (*client.Client, error) { } func (c Client) ListAllContainers() ([]types.Container, error) { - var options types.ContainerListOptions + var options container.ListOptions containers, err := c.cli.ContainerList(context.Background(), options) if err != nil { return nil, err @@ -55,7 +56,7 @@ func (c Client) ListAllContainers() ([]types.Container, error) { func (c Client) ListContainersByName(names []string) ([]types.Container, error) { var ( - options types.ContainerListOptions + options container.ListOptions res []types.Container ) options.All = true diff --git a/frontend/src/lang/modules/en.ts b/frontend/src/lang/modules/en.ts index 74701d640..ccf374788 100644 --- a/frontend/src/lang/modules/en.ts +++ b/frontend/src/lang/modules/en.ts @@ -1127,6 +1127,7 @@ const message = { ignoreCertificate: 'Ignore Certificate', ignoreCertificateHelper: 'Ignoring untrusted certificates during downloads may lead to data leakage or tampering. Please use this option with caution, only when trusting the download source.', + uploadOverLimit: 'The number of files exceeds 1000! Please compress and upload', }, ssh: { autoStart: 'Auto Start', diff --git a/frontend/src/lang/modules/tw.ts b/frontend/src/lang/modules/tw.ts index 015ac663c..97152c8b0 100644 --- a/frontend/src/lang/modules/tw.ts +++ b/frontend/src/lang/modules/tw.ts @@ -1071,6 +1071,7 @@ const message = { ignoreCertificate: '忽略不可信證書', ignoreCertificateHelper: '下載時忽略不可信證書可能導致數據洩露或篡改。請謹慎使用此選項,僅在信任下載源的情況下啟用', + uploadOverLimit: '文件數量超過 1000! 請壓縮後上傳', }, ssh: { autoStart: '開機自啟', diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts index 726059487..7f3e88ab8 100644 --- a/frontend/src/lang/modules/zh.ts +++ b/frontend/src/lang/modules/zh.ts @@ -1072,6 +1072,7 @@ const message = { ignoreCertificate: '忽略不可信证书', ignoreCertificateHelper: '下载时忽略不可信证书可能导致数据泄露或篡改。请谨慎使用此选项,仅在信任下载源的情况下启用', + uploadOverLimit: '文件数量超过 1000!请压缩后上传', }, ssh: { autoStart: '开机自启', diff --git a/frontend/src/views/host/file-management/upload/index.vue b/frontend/src/views/host/file-management/upload/index.vue index 3aa421b39..2b7873645 100644 --- a/frontend/src/views/host/file-management/upload/index.vue +++ b/frontend/src/views/host/file-management/upload/index.vue @@ -92,7 +92,7 @@ import { UploadFile, UploadFiles, UploadInstance, UploadProps, UploadRawFile } f import { ChunkUploadFileData, UploadFileData } from '@/api/modules/files'; import i18n from '@/lang'; import DrawerHeader from '@/components/drawer-header/index.vue'; -import { MsgError, MsgSuccess } from '@/utils/message'; +import { MsgError, MsgSuccess, MsgWarning } from '@/utils/message'; import { Close } from '@element-plus/icons-vue'; import { TimeoutEnum } from '@/enums/http-enum'; @@ -120,6 +120,8 @@ const uploaderFiles = ref([]); const isUploadFolder = ref(false); const hoverIndex = ref(null); const uploadType = ref('file'); +const tmpFiles = ref([]); +const breakFlag = ref(false); const upload = (commnad: string) => { uploadType.value = commnad; @@ -140,7 +142,13 @@ const handleDragover = (event: DragEvent) => { event.preventDefault(); }; -const handleDrop = (event: DragEvent) => { +const initTempFiles = () => { + tmpFiles.value = []; + breakFlag.value = false; +}; + +const handleDrop = async (event: DragEvent) => { + initTempFiles(); event.preventDefault(); const items = event.dataTransfer.items; @@ -148,9 +156,15 @@ const handleDrop = (event: DragEvent) => { for (let i = 0; i < items.length; i++) { const entry = items[i].webkitGetAsEntry(); if (entry) { - traverseFileTree(entry); + await traverseFileTree(entry); } } + if (!breakFlag.value) { + uploaderFiles.value = uploaderFiles.value.concat(tmpFiles.value); + } else { + MsgWarning(i18n.global.t('file.uploadOverLimit')); + } + initTempFiles(); } }; @@ -176,19 +190,44 @@ const convertFileToUploadFile = (file: File, path: string): UploadFile => { }; }; -const traverseFileTree = (item: any, path = '') => { +const traverseFileTree = async (item: any, path = '') => { path = path || ''; + if (item.isFile) { - item.file((file: File) => { - uploaderFiles.value.push(convertFileToUploadFile(file, path)); + if (tmpFiles.value.length > 1000) { + breakFlag.value = true; + return; + } + await new Promise((resolve) => { + item.file((file: File) => { + if (!breakFlag.value) { + tmpFiles.value.push(convertFileToUploadFile(file, path)); + } + resolve(); + }); }); } 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 readEntries = async () => { + const entries = await new Promise((resolve) => { + dirReader.readEntries((entries) => { + resolve(entries); + }); + }); + + if (entries.length === 0) { + return; } - }); + + for (let i = 0; i < entries.length; i++) { + await traverseFileTree(entries[i], path + item.name + '/'); + if (breakFlag.value) { + return; + } + } + await readEntries(); + }; + await readEntries(); } };