diff --git a/agent/app/api/v2/backup.go b/agent/app/api/v2/backup.go index 31c6bee9a..dc298ea37 100644 --- a/agent/app/api/v2/backup.go +++ b/agent/app/api/v2/backup.go @@ -133,6 +133,28 @@ func (b *BaseApi) UpdateBackup(c *gin.Context) { helper.Success(c) } +// @Tags Backup Account +// @Summary Upload file for recover +// @Accept json +// @Param request body dto.UploadForRecover true "request" +// @Success 200 +// @Security ApiKeyAuth +// @Security Timestamp +// @Router /backups/upload [post] +// @x-panel-log {"bodyKeys":["filePath"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"上传备份文件 [filePath]","formatEN":"upload backup file [filePath]"} +func (b *BaseApi) UploadForRecover(c *gin.Context) { + var req dto.UploadForRecover + if err := helper.CheckBindAndValidate(&req, c); err != nil { + return + } + + if err := backupService.UploadForRecover(req); err != nil { + helper.InternalServer(c, err) + return + } + helper.Success(c) +} + // @Tags Backup Account // @Summary Load backup account options // @Accept json diff --git a/agent/app/dto/backup.go b/agent/app/dto/backup.go index 30b58d289..31aa9e021 100644 --- a/agent/app/dto/backup.go +++ b/agent/app/dto/backup.go @@ -53,6 +53,11 @@ type BackupOption struct { IsPublic bool `json:"isPublic"` } +type UploadForRecover struct { + FilePath string `json:"filePath"` + TargetDir string `json:"targetDir"` +} + type CommonBackup struct { Type string `json:"type" validate:"required,oneof=app mysql mariadb redis website postgresql mysql-cluster postgresql-cluster redis-cluster"` Name string `json:"name"` diff --git a/agent/app/service/backup.go b/agent/app/service/backup.go index 038355e52..e49d0c8f3 100644 --- a/agent/app/service/backup.go +++ b/agent/app/service/backup.go @@ -39,6 +39,7 @@ type IBackupService interface { Delete(id uint) error RefreshToken(req dto.OperateByID) error GetLocalDir() (string, error) + UploadForRecover(req dto.UploadForRecover) error MysqlBackup(db dto.CommonBackup) error PostgresqlBackup(db dto.CommonBackup) error @@ -309,6 +310,16 @@ func (u *BackupService) RefreshToken(req dto.OperateByID) error { return backupRepo.Save(&backup) } +func (u *BackupService) UploadForRecover(req dto.UploadForRecover) error { + fileOp := files.NewFileOp() + if !fileOp.Stat(req.TargetDir) { + if err := fileOp.CreateDir(req.TargetDir, constant.DirPerm); err != nil { + return err + } + } + return fileOp.Copy(req.FilePath, req.TargetDir) +} + func (u *BackupService) checkBackupConn(backup *model.BackupAccount) (bool, error) { client, err := newClient(backup, false) if err != nil { diff --git a/agent/router/backup.go b/agent/router/backup.go index 5be78fe79..02337fc38 100644 --- a/agent/router/backup.go +++ b/agent/router/backup.go @@ -21,6 +21,7 @@ func (s *BackupRouter) InitRouter(Router *gin.RouterGroup) { backupRouter.POST("", baseApi.CreateBackup) backupRouter.POST("/del", baseApi.DeleteBackup) backupRouter.POST("/update", baseApi.UpdateBackup) + backupRouter.POST("/upload", baseApi.UploadForRecover) backupRouter.POST("/backup", baseApi.Backup) backupRouter.POST("/recover", baseApi.Recover) diff --git a/frontend/src/api/modules/backup.ts b/frontend/src/api/modules/backup.ts index 68494d1c7..a7d02f1ab 100644 --- a/frontend/src/api/modules/backup.ts +++ b/frontend/src/api/modules/backup.ts @@ -35,6 +35,9 @@ export const deleteBackupRecord = (params: { ids: number[] }) => { export const updateRecordDescription = (id: Number, description: String) => { return http.post(`/backups/record/description/update`, { id: id, description: description }); }; +export const uploadByRecover = (filePath: string, targetDir: String) => { + return http.post(`/backups/upload`, { filePath: filePath, targetDir: targetDir }); +}; export const searchBackupRecords = (params: Backup.SearchBackupRecord) => { return http.post>(`/backups/record/search`, params, TimeoutEnum.T_5M); }; diff --git a/frontend/src/components/file-list/index.vue b/frontend/src/components/file-list/index.vue index 037a53b9c..3fe6944be 100644 --- a/frontend/src/components/file-list/index.vue +++ b/frontend/src/components/file-list/index.vue @@ -46,37 +46,54 @@
- - + + + + + @@ -107,11 +124,12 @@ - -