diff --git a/agent/app/dto/request/file.go b/agent/app/dto/request/file.go index 71605836a..78a982b3c 100644 --- a/agent/app/dto/request/file.go +++ b/agent/app/dto/request/file.go @@ -92,11 +92,12 @@ type FileWget struct { } type FileMove struct { - Type string `json:"type" validate:"required"` - OldPaths []string `json:"oldPaths" validate:"required"` - NewPath string `json:"newPath" validate:"required"` - Name string `json:"name"` - Cover bool `json:"cover"` + Type string `json:"type" validate:"required"` + OldPaths []string `json:"oldPaths" validate:"required"` + NewPath string `json:"newPath" validate:"required"` + Name string `json:"name"` + Cover bool `json:"cover"` + CoverPaths []string `json:"coverPaths"` } type FileDownload struct { diff --git a/agent/app/dto/response/file.go b/agent/app/dto/response/file.go index 1f4c0e9d7..a85366219 100644 --- a/agent/app/dto/response/file.go +++ b/agent/app/dto/response/file.go @@ -53,6 +53,7 @@ type ExistFileInfo struct { Path string `json:"path"` Size int64 `json:"size"` ModTime time.Time `json:"modTime"` + IsDir bool `json:"isDir"` } type UserInfo struct { diff --git a/agent/app/service/file.go b/agent/app/service/file.go index 74a3ee8ba..321a6fbee 100644 --- a/agent/app/service/file.go +++ b/agent/app/service/file.go @@ -394,10 +394,18 @@ func (f *FileService) MvFile(m request.FileMove) error { return buserr.New("ErrMovePathFailed") } } + var errs []error if m.Type == "cut" { + if len(m.CoverPaths) > 0 { + for _, src := range m.CoverPaths { + if err := fo.CopyAndReName(src, m.NewPath, "", true); err != nil { + errs = append(errs, err) + global.LOG.Errorf("cut copy file [%s] to [%s] failed, err: %s", src, m.NewPath, err.Error()) + } + } + } return fo.Cut(m.OldPaths, m.NewPath, m.Name, m.Cover) } - var errs []error if m.Type == "copy" { for _, src := range m.OldPaths { if err := fo.CopyAndReName(src, m.NewPath, m.Name, m.Cover); err != nil { @@ -569,6 +577,7 @@ func (f *FileService) BatchCheckFiles(req request.FilePathsCheck) []response.Exi Name: info.Name(), Path: filePath, ModTime: info.ModTime(), + IsDir: info.IsDir(), }) } } diff --git a/agent/utils/files/file_op.go b/agent/utils/files/file_op.go index 43716771f..c6d3df772 100644 --- a/agent/utils/files/file_op.go +++ b/agent/utils/files/file_op.go @@ -329,25 +329,30 @@ func (f FileOp) DownloadFile(url, dst string) error { } func (f FileOp) Cut(oldPaths []string, dst, name string, cover bool) error { - for _, p := range oldPaths { - var dstPath string - if name != "" { - dstPath = filepath.Join(dst, name) - if f.Stat(dstPath) { - dstPath = dst - } - } else { - base := filepath.Base(p) - dstPath = filepath.Join(dst, base) + if len(oldPaths) == 0 { + return nil + } + var dstPath string + coverFlag := "" + if name != "" { + dstPath = filepath.Join(dst, name) + if f.Stat(dstPath) { + dstPath = dst } - coverFlag := "" if cover { coverFlag = "-f" } - - if err := cmd.RunDefaultBashCf(`mv %s '%s' '%s'`, coverFlag, p, dstPath); err != nil { - return err - } + } else { + dstPath = dst + coverFlag = "-f" + } + var quotedPaths []string + for _, p := range oldPaths { + quotedPaths = append(quotedPaths, fmt.Sprintf("'%s'", p)) + } + mvCommand := fmt.Sprintf("mv %s %s '%s'", coverFlag, strings.Join(quotedPaths, " "), dstPath) + if err := cmd.RunDefaultBashCf(mvCommand); err != nil { + return err } return nil } diff --git a/frontend/src/api/interface/file.ts b/frontend/src/api/interface/file.ts index c929e217c..cec78b235 100644 --- a/frontend/src/api/interface/file.ts +++ b/frontend/src/api/interface/file.ts @@ -168,6 +168,7 @@ export namespace File { size: number; uploadSize: number; modTime: string; + isDir: boolean; } export interface RecycleBin { diff --git a/frontend/src/lang/modules/en.ts b/frontend/src/lang/modules/en.ts index 9e32c6e97..d47483a41 100644 --- a/frontend/src/lang/modules/en.ts +++ b/frontend/src/lang/modules/en.ts @@ -1467,7 +1467,8 @@ const message = { existFileTitle: 'Same name file prompt', existFileHelper: 'The uploaded file contains a file with the same name, do you want to overwrite it?', existFileSize: 'File size (new -> old)', - existFileDirHelper: 'The selected file/folder has a duplicate name. Please proceed with caution!', + existFileDirHelper: 'The selected file/folder has a duplicate name. Please proceed with caution! \n', + coverDirHelper: 'The selected folders to be replaced will be copied to the destination path!', noSuchFile: 'The file or directory was not found. Please check and try again.', setting: 'Setting', showHide: 'Show hidden files', diff --git a/frontend/src/lang/modules/ja.ts b/frontend/src/lang/modules/ja.ts index 529dcd162..850aca521 100644 --- a/frontend/src/lang/modules/ja.ts +++ b/frontend/src/lang/modules/ja.ts @@ -1411,6 +1411,7 @@ const message = { existFileHelper: 'アップロードしたファイルに同じ名前のファイルが含まれています。上書きしますか?', existFileSize: 'ファイルサイズ(新しい -> 古い)', existFileDirHelper: '選択したファイル/フォルダーには同じ名前のものが既に存在します。慎重に操作してください!', + coverDirHelper: '上書きするフォルダを選択すると、対象パスにコピーされます!', noSuchFile: 'ファイルまたはディレクトリが見つかりませんでした。確認して再試行してください。', setting: '設定', showHide: '隠しファイルを表示', diff --git a/frontend/src/lang/modules/ko.ts b/frontend/src/lang/modules/ko.ts index d7f828949..c9a9eedb2 100644 --- a/frontend/src/lang/modules/ko.ts +++ b/frontend/src/lang/modules/ko.ts @@ -1397,6 +1397,7 @@ const message = { existFileHelper: '업로드한 파일에 동일한 이름의 파일이 포함되어 있습니다. 덮어쓰시겠습니까?', existFileSize: '파일 크기 (새로운 -> 오래된)', existFileDirHelper: '선택한 파일/폴더에 동일한 이름이 이미 존재합니다. 신중하게 작업하세요!', + coverDirHelper: '덮어쓸 폴더를 선택하면 대상 경로로 복사됩니다!', noSuchFile: '파일 또는 디렉터리를 찾을 수 없습니다. 확인 후 다시 시도하세요.', setting: '설정', showHide: '숨김 파일 표시', diff --git a/frontend/src/lang/modules/ms.ts b/frontend/src/lang/modules/ms.ts index e937fc6b4..fa74ece73 100644 --- a/frontend/src/lang/modules/ms.ts +++ b/frontend/src/lang/modules/ms.ts @@ -1453,7 +1453,8 @@ const message = { existFileTitle: 'Amaran fail dengan nama yang sama', existFileHelper: 'Fail yang dimuat naik mengandungi fail dengan nama yang sama. Adakah anda mahu menimpanya?', existFileSize: 'Saiz fail (baru -> lama)', - existFileDirHelper: 'Fail/folder yang dipilih mempunyai nama yang sama. Sila berhati-hati!', + existFileDirHelper: 'Fail/folder yang dipilih mempunyai nama yang sama. Sila berhati-hati!\n', + coverDirHelper: 'Folder yang dipilih untuk ditimpa akan disalin ke laluan destinasi!', noSuchFile: 'Fail atau direktori tidak ditemui. Sila periksa dan cuba lagi.', setting: 'tetapan', showHide: 'Tunjukkan fail tersembunyi', diff --git a/frontend/src/lang/modules/pt-br.ts b/frontend/src/lang/modules/pt-br.ts index a962b0d0f..f18a85908 100644 --- a/frontend/src/lang/modules/pt-br.ts +++ b/frontend/src/lang/modules/pt-br.ts @@ -1439,7 +1439,8 @@ const message = { existFileTitle: 'Aviso de arquivo com o mesmo nome', existFileHelper: 'O arquivo enviado contém um arquivo com o mesmo nome. Deseja substituí-lo?', existFileSize: 'Tamanho do arquivo (novo -> antigo)', - existFileDirHelper: 'O arquivo/pasta selecionado tem um nome duplicado. Por favor, prossiga com cautela!', + existFileDirHelper: 'O arquivo/pasta selecionado tem um nome duplicado. Por favor, prossiga com cautela!\n', + coverDirHelper: 'As pastas selecionadas para substituição serão copiadas para o caminho de destino!', noSuchFile: 'O arquivo ou diretório não foi encontrado. Por favor, verifique e tente novamente.', setting: 'configuração', showHide: 'Mostrar arquivos ocultos', diff --git a/frontend/src/lang/modules/ru.ts b/frontend/src/lang/modules/ru.ts index ca8129e12..923cc558e 100644 --- a/frontend/src/lang/modules/ru.ts +++ b/frontend/src/lang/modules/ru.ts @@ -1440,7 +1440,8 @@ const message = { existFileTitle: 'Предупреждение о файле с тем же именем', existFileHelper: 'Загруженный файл содержит файл с таким же именем. Заменить его?', existFileSize: 'Размер файла (новый -> старый)', - existFileDirHelper: 'Выбранный файл/папка имеет дублирующееся имя. Пожалуйста, действуйте осторожно!', + existFileDirHelper: 'Выбранный файл/папка имеет дублирующееся имя. Пожалуйста, действуйте осторожно!\n', + coverDirHelper: 'При выборе перезаписываемой папки она будет скопирована в целевой путь!', noSuchFile: 'Файл или каталог не найдены. Пожалуйста, проверьте и повторите попытку.', setting: 'настройка', showHide: 'Показывать скрытые файлы', diff --git a/frontend/src/lang/modules/zh-Hant.ts b/frontend/src/lang/modules/zh-Hant.ts index 745c1af6a..99b47064a 100644 --- a/frontend/src/lang/modules/zh-Hant.ts +++ b/frontend/src/lang/modules/zh-Hant.ts @@ -1401,6 +1401,7 @@ const message = { existFileHelper: '上傳的檔案存在同名檔案,是否覆蓋?', existFileSize: '文件大小(新->舊)', existFileDirHelper: '選擇的檔案/資料夾存在同名,請謹慎操作!', + coverDirHelper: '選取要覆蓋的資料夾,將複製到目標路徑!', noSuchFile: '找不到該檔案或目錄,請檢查後重試。', setting: '设置', showHide: '顯示隱藏檔案', diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts index b448b1c00..a6466bf66 100644 --- a/frontend/src/lang/modules/zh.ts +++ b/frontend/src/lang/modules/zh.ts @@ -1395,6 +1395,7 @@ const message = { existFileHelper: '上传的文件存在同名文件,是否覆盖?', existFileSize: '文件大小 (新 -> 旧)', existFileDirHelper: '选择的文件/文件夹存在同名,请谨慎操作!', + coverDirHelper: '选中覆盖的文件夹,将复制到目标路径!', noSuchFile: '未能找到该文件或目录,请检查后重试', setting: '设置', showHide: '显示隐藏文件', diff --git a/frontend/src/views/host/file-management/move/index.vue b/frontend/src/views/host/file-management/move/index.vue index 1d9798f28..207552c4c 100644 --- a/frontend/src/views/host/file-management/move/index.vue +++ b/frontend/src/views/host/file-management/move/index.vue @@ -1,5 +1,5 @@