From 7c1ddb5b4c3b75a0d11fe5c878452f4d9bea5ae2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=98=AD?= Date: Wed, 9 Sep 2026 15:33:56 +0800 Subject: [PATCH] fix: add localized message for download records not removed (#13757) --- agent/app/api/v2/file.go | 22 +++ agent/app/dto/request/file.go | 4 + agent/cmd/server/docs/x-log.json | 7 + agent/router/ro_file.go | 1 + agent/utils/files/file_op.go | 42 ++++- core/cmd/server/docs/x-log.json | 7 + frontend/src/api/modules/files.ts | 4 + frontend/src/lang/modules/en.ts | 1 + frontend/src/lang/modules/es-es.ts | 1 + frontend/src/lang/modules/fa.ts | 1 + frontend/src/lang/modules/ja.ts | 1 + frontend/src/lang/modules/ko.ts | 1 + frontend/src/lang/modules/lo.ts | 1 + frontend/src/lang/modules/ms.ts | 1 + frontend/src/lang/modules/pt-br.ts | 1 + frontend/src/lang/modules/ru.ts | 1 + frontend/src/lang/modules/tr.ts | 1 + frontend/src/lang/modules/zh-Hant.ts | 1 + frontend/src/lang/modules/zh.ts | 1 + .../host/file-management/process/index.vue | 156 ++++++++++++++---- 20 files changed, 224 insertions(+), 31 deletions(-) diff --git a/agent/app/api/v2/file.go b/agent/app/api/v2/file.go index db8747ed3..e51abf06f 100644 --- a/agent/app/api/v2/file.go +++ b/agent/app/api/v2/file.go @@ -691,6 +691,28 @@ func (b *BaseApi) StopWget(c *gin.Context) { helper.Success(c) } +// @Tags File +// @Summary Remove finished download progress records without deleting files +// @Accept json +// @Param request body request.FileProcessRemoveReq true "request" +// @Success 200 {object} response.FileProcessKeys +// @Security ApiKeyAuth +// @Security Timestamp +// @Router /files/wget/process/remove [post] +// @x-panel-log {"bodyKeys":["keys"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"移除已结束下载记录 [keys]","formatEN":"Remove finished download records [keys]"} +func (b *BaseApi) RemoveWgetRecords(c *gin.Context) { + var req request.FileProcessRemoveReq + if err := helper.CheckBindAndValidate(&req, c); err != nil { + return + } + keys, err := files.RemoveDownloadRecords(req.Keys) + if err != nil { + helper.BadRequest(c, err) + return + } + helper.SuccessWithData(c, response.FileProcessKeys{Keys: keys}) +} + // @Tags File // @Summary Move file // @Accept json diff --git a/agent/app/dto/request/file.go b/agent/app/dto/request/file.go index a0a9e6c8c..36fe6883a 100644 --- a/agent/app/dto/request/file.go +++ b/agent/app/dto/request/file.go @@ -158,6 +158,10 @@ type FileProcessReq struct { Key string `json:"key"` } +type FileProcessRemoveReq struct { + Keys []string `json:"keys" validate:"required,min=1,max=1000"` +} + type FileRoleUpdate struct { Path string `json:"path" validate:"required"` User string `json:"user" validate:"required"` diff --git a/agent/cmd/server/docs/x-log.json b/agent/cmd/server/docs/x-log.json index 7d46d5134..f48d7aa59 100644 --- a/agent/cmd/server/docs/x-log.json +++ b/agent/cmd/server/docs/x-log.json @@ -3503,6 +3503,13 @@ "formatZH": "下载 url =\u003e [path]/[name]", "formatEN": "Download url =\u003e [path]/[name]" }, + "/files/wget/process/remove": { + "bodyKeys": ["keys"], + "paramKeys": [], + "beforeFunctions": [], + "formatZH": "移除已结束下载记录 [keys]", + "formatEN": "Remove finished download records [keys]" + }, "/files/wget/stop": { "bodyKeys": [ "key" diff --git a/agent/router/ro_file.go b/agent/router/ro_file.go index fe78b5b34..02195ac89 100644 --- a/agent/router/ro_file.go +++ b/agent/router/ro_file.go @@ -43,6 +43,7 @@ func (f *FileRouter) InitRouter(Router *gin.RouterGroup) { fileRouter.POST("/rename", baseApi.ChangeFileName) fileRouter.POST("/wget", baseApi.WgetFile) fileRouter.POST("/wget/stop", baseApi.StopWget) + fileRouter.POST("/wget/process/remove", baseApi.RemoveWgetRecords) fileRouter.POST("/move", baseApi.MoveFile) fileRouter.POST("/move/stop", baseApi.StopMoveFile) fileRouter.GET("/download", baseApi.Download) diff --git a/agent/utils/files/file_op.go b/agent/utils/files/file_op.go index e851ea886..0dad332cf 100644 --- a/agent/utils/files/file_op.go +++ b/agent/utils/files/file_op.go @@ -612,10 +612,50 @@ func CancelDownload(key string) error { return task.cleanupErr } +func RemoveDownloadRecords(keys []string) ([]string, error) { + if len(keys) == 0 || len(keys) > 1000 { + return nil, errors.New("between 1 and 1000 download keys are required") + } + for _, key := range keys { + if !strings.HasPrefix(key, "file-wget-") || len(key) <= len("file-wget-") || len(key) > 128 { + return nil, errors.New("invalid download key") + } + } + downloadMu.Lock() + defer downloadMu.Unlock() + removed := make([]string, 0, len(keys)) + seen := make(map[string]bool, len(keys)) + for _, key := range keys { + if seen[key] { + continue + } + seen[key] = true + if _, active := downloadTasks[key]; active { + continue + } + value := global.CACHE.Get(key) + if value == "" { + removed = append(removed, key) + continue + } + var process Process + if err := json.Unmarshal([]byte(value), &process); err != nil { + continue + } + terminal := process.Status == "Success" || process.Status == "Failed" || process.Status == "Canceled" + legacySuccess := process.Status == "" && process.Percent == 100 + if !terminal && !legacySuccess { + continue + } + global.CACHE.Del(key) + removed = append(removed, key) + } + return removed, nil +} + func downloadErrorDetail(err error) string { var urlErr *url.Error if errors.As(err, &urlErr) { - // Signed URLs and proxy credentials must not appear in progress messages or logs. return urlErr.Err.Error() } return err.Error() diff --git a/core/cmd/server/docs/x-log.json b/core/cmd/server/docs/x-log.json index 7d46d5134..f48d7aa59 100644 --- a/core/cmd/server/docs/x-log.json +++ b/core/cmd/server/docs/x-log.json @@ -3503,6 +3503,13 @@ "formatZH": "下载 url =\u003e [path]/[name]", "formatEN": "Download url =\u003e [path]/[name]" }, + "/files/wget/process/remove": { + "bodyKeys": ["keys"], + "paramKeys": [], + "beforeFunctions": [], + "formatZH": "移除已结束下载记录 [keys]", + "formatEN": "Remove finished download records [keys]" + }, "/files/wget/stop": { "bodyKeys": [ "key" diff --git a/frontend/src/api/modules/files.ts b/frontend/src/api/modules/files.ts index c1063d034..70b83e0f5 100644 --- a/frontend/src/api/modules/files.ts +++ b/frontend/src/api/modules/files.ts @@ -154,6 +154,10 @@ export const stopWgetFile = (key: string, currentNode?: string) => { return http.post('files/wget/stop', { key }, undefined, currentNode ? { CurrentNode: currentNode } : undefined); }; +export const removeWgetRecords = (keys: string[], currentNode: string) => { + return http.post('files/wget/process/remove', { keys }, undefined, { CurrentNode: currentNode }); +}; + export const moveFile = (params: File.FileMove) => { return http.post('files/move', params); }; diff --git a/frontend/src/lang/modules/en.ts b/frontend/src/lang/modules/en.ts index fdbb7881e..d17834422 100644 --- a/frontend/src/lang/modules/en.ts +++ b/frontend/src/lang/modules/en.ts @@ -2494,6 +2494,7 @@ const message = { downloadProcess: 'Download progress', downloading: 'Downloading...', stopWgetConfirm: 'Are you sure you want to stop this download task?', + downloadRecordsNotRemoved: 'Some records were not removed. Refresh and try again.', infoDetail: 'File properties', root: 'Root directory', list: 'File list', diff --git a/frontend/src/lang/modules/es-es.ts b/frontend/src/lang/modules/es-es.ts index eaf104997..04dd13e1a 100644 --- a/frontend/src/lang/modules/es-es.ts +++ b/frontend/src/lang/modules/es-es.ts @@ -2696,6 +2696,7 @@ const message = { panelInstallDir: 'El directorio de instalación de 1Panel no puede eliminarse', wgetTask: 'Tarea de descarga', stopWgetConfirm: '¿Confirmar que desea detener esta tarea de descarga?', + downloadRecordsNotRemoved: 'No se eliminaron algunos registros. Actualice e inténtelo de nuevo.', existFileTitle: 'Archivo con el mismo nombre', existFileHelper: 'El archivo cargado contiene un archivo con el mismo nombre, ¿desea sobrescribirlo?', existFileSize: 'Tamaño del archivo (nuevo -> viejo)', diff --git a/frontend/src/lang/modules/fa.ts b/frontend/src/lang/modules/fa.ts index 0f0823864..1a3bdacaa 100644 --- a/frontend/src/lang/modules/fa.ts +++ b/frontend/src/lang/modules/fa.ts @@ -2471,6 +2471,7 @@ const message = { downloadProcess: 'پیشرفت دانلود', downloading: 'در حال دانلود...', stopWgetConfirm: 'آیا مطمئن هستید که می‌خواهید این وظیفه دانلود را متوقف کنید؟', + downloadRecordsNotRemoved: 'برخی رکوردها حذف نشدند. صفحه را تازه‌سازی کرده و دوباره تلاش کنید.', infoDetail: 'ویژگی‌های فایل', root: 'دایرکتوری ریشه', list: 'لیست فایل', diff --git a/frontend/src/lang/modules/ja.ts b/frontend/src/lang/modules/ja.ts index 928ed12a1..23fea7040 100644 --- a/frontend/src/lang/modules/ja.ts +++ b/frontend/src/lang/modules/ja.ts @@ -2636,6 +2636,7 @@ const message = { panelInstallDir: '1Panelインストールディレクトリは削除できません', wgetTask: 'ダウンロードタスク', stopWgetConfirm: 'このダウンロードタスクを停止しますか?', + downloadRecordsNotRemoved: '一部の記録を削除できませんでした。更新して再試行してください。', existFileTitle: '同名ファイルの警告', existFileHelper: 'アップロードしたファイルに同じ名前のファイルが含まれています。上書きしますか?', existFileSize: 'ファイルサイズ(新しい -> 古い)', diff --git a/frontend/src/lang/modules/ko.ts b/frontend/src/lang/modules/ko.ts index 2cd0fadb1..a54be76ba 100644 --- a/frontend/src/lang/modules/ko.ts +++ b/frontend/src/lang/modules/ko.ts @@ -2599,6 +2599,7 @@ const message = { panelInstallDir: '1Panel 설치 디렉터리는 삭제할 수 없습니다.', wgetTask: '다운로드 작업', stopWgetConfirm: '이 다운로드 작업을 중지하시겠습니까?', + downloadRecordsNotRemoved: '일부 기록을 제거하지 못했습니다. 새로 고침 후 다시 시도하세요.', existFileTitle: '동일한 이름의 파일 경고', existFileHelper: '업로드한 파일에 동일한 이름의 파일이 포함되어 있습니다. 덮어쓰시겠습니까?', existFileSize: '파일 크기 (새로운 -> 오래된)', diff --git a/frontend/src/lang/modules/lo.ts b/frontend/src/lang/modules/lo.ts index 62d0da03e..7be6a13cd 100644 --- a/frontend/src/lang/modules/lo.ts +++ b/frontend/src/lang/modules/lo.ts @@ -2427,6 +2427,7 @@ const message = { downloadProcess: 'ຄວາມຄືບໜ້າການດາວໂຫຼດ', downloading: 'ກຳລັງດາວໂຫຼດ...', stopWgetConfirm: 'ທ່ານແນ່ໃຈບໍວ່າຕ້ອງການຢຸດງານດາວໂຫຼດນີ້?', + downloadRecordsNotRemoved: 'ບາງບັນທຶກບໍ່ຖືກລຶບ. ກະລຸນາໂຫຼດໃໝ່ ແລະລອງອີກຄັ້ງ.', infoDetail: 'ຄຸນສົມບັດໄຟລ໌', root: 'ໄດເຣັກທໍຣີຮາກ (Root)', list: 'ລາຍການໄຟລ໌', diff --git a/frontend/src/lang/modules/ms.ts b/frontend/src/lang/modules/ms.ts index ed6011a3c..16ab3fcb2 100644 --- a/frontend/src/lang/modules/ms.ts +++ b/frontend/src/lang/modules/ms.ts @@ -2695,6 +2695,7 @@ const message = { panelInstallDir: 'Direktori pemasangan 1Panel tidak boleh dipadamkan', wgetTask: 'Tugas Muat Turun', stopWgetConfirm: 'Adakah anda pasti mahu menghentikan tugas muat turun ini?', + downloadRecordsNotRemoved: 'Sesetengah rekod tidak dibuang. Muat semula dan cuba lagi.', 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)', diff --git a/frontend/src/lang/modules/pt-br.ts b/frontend/src/lang/modules/pt-br.ts index 5b99f4522..7ca206fd3 100644 --- a/frontend/src/lang/modules/pt-br.ts +++ b/frontend/src/lang/modules/pt-br.ts @@ -2694,6 +2694,7 @@ const message = { panelInstallDir: 'O diretório de instalação do 1Panel não pode ser excluído', wgetTask: 'Tarefa de Download', stopWgetConfirm: 'Tem certeza de que deseja parar esta tarefa de download?', + downloadRecordsNotRemoved: 'Alguns registros não foram removidos. Atualize e tente novamente.', 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)', diff --git a/frontend/src/lang/modules/ru.ts b/frontend/src/lang/modules/ru.ts index 90eacd8ec..574af9de1 100644 --- a/frontend/src/lang/modules/ru.ts +++ b/frontend/src/lang/modules/ru.ts @@ -2669,6 +2669,7 @@ const message = { panelInstallDir: 'Директорию установки 1Panel нельзя удалить', wgetTask: 'Задача загрузки', stopWgetConfirm: 'Вы уверены, что хотите остановить эту задачу загрузки?', + downloadRecordsNotRemoved: 'Некоторые записи не удалены. Обновите страницу и повторите попытку.', existFileTitle: 'Предупреждение о файле с тем же именем', existFileHelper: 'Загруженный файл содержит файл с таким же именем. Заменить его?', existFileSize: 'Размер файла (новый -> старый)', diff --git a/frontend/src/lang/modules/tr.ts b/frontend/src/lang/modules/tr.ts index 51b3bd945..c33dbeb8c 100644 --- a/frontend/src/lang/modules/tr.ts +++ b/frontend/src/lang/modules/tr.ts @@ -2684,6 +2684,7 @@ const message = { panelInstallDir: '1Panel kurulum dizini silinemez', wgetTask: 'İndirme Görevi', stopWgetConfirm: 'Bu indirme görevini durdurmak istediğinizden emin misiniz?', + downloadRecordsNotRemoved: 'Bazı kayıtlar kaldırılamadı. Yenileyip tekrar deneyin.', existFileTitle: 'Aynı ada sahip dosya uyarısı', existFileHelper: 'Yüklenen dosya, aynı ada sahip bir dosya içeriyor, üzerine yazmak istiyor musunuz?', existFileSize: 'Dosya boyutu (yeni -> eski)', diff --git a/frontend/src/lang/modules/zh-Hant.ts b/frontend/src/lang/modules/zh-Hant.ts index 1759d21c9..3c4e72460 100644 --- a/frontend/src/lang/modules/zh-Hant.ts +++ b/frontend/src/lang/modules/zh-Hant.ts @@ -2358,6 +2358,7 @@ const message = { downloading: '正在下載...', infoDetail: '檔案屬性', stopWgetConfirm: '確認停止該下載任務?', + downloadRecordsNotRemoved: '部分紀錄未移除,請重新整理後重試。', root: '根目錄', list: '檔案列表', sub: '子目錄', diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts index 84aba9230..b14862e1f 100644 --- a/frontend/src/lang/modules/zh.ts +++ b/frontend/src/lang/modules/zh.ts @@ -2388,6 +2388,7 @@ const message = { downloadProcess: '下载进度', downloading: '正在下载...', stopWgetConfirm: '确认停止该下载任务?', + downloadRecordsNotRemoved: '部分记录未移除,请刷新后重试。', infoDetail: '文件属性', root: '根目录', list: '文件列表', diff --git a/frontend/src/views/host/file-management/process/index.vue b/frontend/src/views/host/file-management/process/index.vue index ac5e07448..f0bd7a2e8 100644 --- a/frontend/src/views/host/file-management/process/index.vue +++ b/frontend/src/views/host/file-management/process/index.vue @@ -1,7 +1,7 @@