fix: 解决拖拽上传文件夹文件上传不全的问题 (#3865)

Refs https://github.com/1Panel-dev/1Panel/issues/3848
This commit is contained in:
zhengkunwang 2024-02-08 16:00:09 +08:00 committed by GitHub
parent 6a903b7fdf
commit 3fd7aa17a8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 55 additions and 12 deletions

View file

@ -2,6 +2,7 @@ package docker
import ( import (
"context" "context"
"github.com/docker/docker/api/types/container"
"github.com/1Panel-dev/1Panel/backend/app/model" "github.com/1Panel-dev/1Panel/backend/app/model"
"github.com/1Panel-dev/1Panel/backend/global" "github.com/1Panel-dev/1Panel/backend/global"
@ -45,7 +46,7 @@ func NewDockerClient() (*client.Client, error) {
} }
func (c Client) ListAllContainers() ([]types.Container, error) { func (c Client) ListAllContainers() ([]types.Container, error) {
var options types.ContainerListOptions var options container.ListOptions
containers, err := c.cli.ContainerList(context.Background(), options) containers, err := c.cli.ContainerList(context.Background(), options)
if err != nil { if err != nil {
return nil, err return nil, err
@ -55,7 +56,7 @@ func (c Client) ListAllContainers() ([]types.Container, error) {
func (c Client) ListContainersByName(names []string) ([]types.Container, error) { func (c Client) ListContainersByName(names []string) ([]types.Container, error) {
var ( var (
options types.ContainerListOptions options container.ListOptions
res []types.Container res []types.Container
) )
options.All = true options.All = true

View file

@ -1127,6 +1127,7 @@ const message = {
ignoreCertificate: 'Ignore Certificate', ignoreCertificate: 'Ignore Certificate',
ignoreCertificateHelper: 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.', '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: { ssh: {
autoStart: 'Auto Start', autoStart: 'Auto Start',

View file

@ -1071,6 +1071,7 @@ const message = {
ignoreCertificate: '忽略不可信證書', ignoreCertificate: '忽略不可信證書',
ignoreCertificateHelper: ignoreCertificateHelper:
'下載時忽略不可信證書可能導致數據洩露或篡改請謹慎使用此選項僅在信任下載源的情況下啟用', '下載時忽略不可信證書可能導致數據洩露或篡改請謹慎使用此選項僅在信任下載源的情況下啟用',
uploadOverLimit: '文件數量超過 1000 請壓縮後上傳',
}, },
ssh: { ssh: {
autoStart: '開機自啟', autoStart: '開機自啟',

View file

@ -1072,6 +1072,7 @@ const message = {
ignoreCertificate: '忽略不可信证书', ignoreCertificate: '忽略不可信证书',
ignoreCertificateHelper: ignoreCertificateHelper:
'下载时忽略不可信证书可能导致数据泄露或篡改请谨慎使用此选项仅在信任下载源的情况下启用', '下载时忽略不可信证书可能导致数据泄露或篡改请谨慎使用此选项仅在信任下载源的情况下启用',
uploadOverLimit: '文件数量超过 1000请压缩后上传',
}, },
ssh: { ssh: {
autoStart: '开机自启', autoStart: '开机自启',

View file

@ -92,7 +92,7 @@ import { UploadFile, UploadFiles, UploadInstance, UploadProps, UploadRawFile } f
import { ChunkUploadFileData, UploadFileData } from '@/api/modules/files'; import { ChunkUploadFileData, UploadFileData } from '@/api/modules/files';
import i18n from '@/lang'; import i18n from '@/lang';
import DrawerHeader from '@/components/drawer-header/index.vue'; 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 { Close } from '@element-plus/icons-vue';
import { TimeoutEnum } from '@/enums/http-enum'; import { TimeoutEnum } from '@/enums/http-enum';
@ -120,6 +120,8 @@ const uploaderFiles = ref<UploadFiles>([]);
const isUploadFolder = ref(false); const isUploadFolder = ref(false);
const hoverIndex = ref(null); const hoverIndex = ref(null);
const uploadType = ref('file'); const uploadType = ref('file');
const tmpFiles = ref<UploadFiles>([]);
const breakFlag = ref(false);
const upload = (commnad: string) => { const upload = (commnad: string) => {
uploadType.value = commnad; uploadType.value = commnad;
@ -140,7 +142,13 @@ const handleDragover = (event: DragEvent) => {
event.preventDefault(); event.preventDefault();
}; };
const handleDrop = (event: DragEvent) => { const initTempFiles = () => {
tmpFiles.value = [];
breakFlag.value = false;
};
const handleDrop = async (event: DragEvent) => {
initTempFiles();
event.preventDefault(); event.preventDefault();
const items = event.dataTransfer.items; const items = event.dataTransfer.items;
@ -148,9 +156,15 @@ const handleDrop = (event: DragEvent) => {
for (let i = 0; i < items.length; i++) { for (let i = 0; i < items.length; i++) {
const entry = items[i].webkitGetAsEntry(); const entry = items[i].webkitGetAsEntry();
if (entry) { 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 || ''; path = path || '';
if (item.isFile) { if (item.isFile) {
item.file((file: File) => { if (tmpFiles.value.length > 1000) {
uploaderFiles.value.push(convertFileToUploadFile(file, path)); breakFlag.value = true;
return;
}
await new Promise<void>((resolve) => {
item.file((file: File) => {
if (!breakFlag.value) {
tmpFiles.value.push(convertFileToUploadFile(file, path));
}
resolve();
});
}); });
} else if (item.isDirectory) { } else if (item.isDirectory) {
const dirReader = item.createReader(); const dirReader = item.createReader();
dirReader.readEntries((entries) => { const readEntries = async () => {
for (let i = 0; i < entries.length; i++) { const entries = await new Promise<any[]>((resolve) => {
traverseFileTree(entries[i], path + item.name + '/'); 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();
} }
}; };