diff --git a/backend/app/api/v1/backup.go b/backend/app/api/v1/backup.go index 92349c890..f10c8dc64 100644 --- a/backend/app/api/v1/backup.go +++ b/backend/app/api/v1/backup.go @@ -162,6 +162,29 @@ func (b *BaseApi) SearchBackupRecords(c *gin.Context) { }) } +// @Tags Backup Account +// @Summary Load backup records size +// @Accept json +// @Param request body dto.RecordSearch true "request" +// @Success 200 {array} dto.dto.BackupFile +// @Security ApiKeyAuth +// @Security Timestamp +// @Router /settings/backup/record/size [post] +func (b *BaseApi) LoadBackupSize(c *gin.Context) { + var req dto.RecordSearch + if err := helper.CheckBindAndValidate(&req, c); err != nil { + return + } + + list, err := backupService.LoadSize(req) + if err != nil { + helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) + return + } + + helper.SuccessWithData(c, list) +} + // @Tags Backup Account // @Summary Page backup records by cronjob // @Accept json @@ -188,6 +211,29 @@ func (b *BaseApi) SearchBackupRecordsByCronjob(c *gin.Context) { }) } +// @Tags Backup Account +// @Summary Load backup records size for cronjob +// @Accept json +// @Param request body dto.RecordSearchByCronjob true "request" +// @Success 200 {array} dto.dto.BackupFile +// @Security ApiKeyAuth +// @Security Timestamp +// @Router /settings/backup/record/size/bycronjob [post] +func (b *BaseApi) LoadBackupSizeByCronjob(c *gin.Context) { + var req dto.RecordSearchByCronjob + if err := helper.CheckBindAndValidate(&req, c); err != nil { + return + } + + list, err := backupService.LoadSizeByCronjob(req) + if err != nil { + helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) + return + } + + helper.SuccessWithData(c, list) +} + // @Tags Backup Account // @Summary Download backup record // @Accept json diff --git a/backend/app/dto/backup.go b/backend/app/dto/backup.go index 48db32351..9bdd9c27a 100644 --- a/backend/app/dto/backup.go +++ b/backend/app/dto/backup.go @@ -21,6 +21,12 @@ type BackupInfo struct { Vars string `json:"vars"` } +type BackupFile struct { + ID uint `json:"id"` + Name string `json:"name"` + Size int64 `json:"size"` +} + type OneDriveInfo struct { ClientID string `json:"client_id"` ClientSecret string `json:"client_secret"` @@ -66,7 +72,6 @@ type BackupRecords struct { BackupType string `json:"backupType"` FileDir string `json:"fileDir"` FileName string `json:"fileName"` - Size int64 `json:"size"` } type DownloadRecord struct { diff --git a/backend/app/service/backup.go b/backend/app/service/backup.go index 09ac0afce..bb6f261b5 100644 --- a/backend/app/service/backup.go +++ b/backend/app/service/backup.go @@ -8,7 +8,6 @@ import ( "fmt" "os" "path" - "sort" "strings" "sync" "time" @@ -30,7 +29,9 @@ type BackupService struct{} type IBackupService interface { List() ([]dto.BackupInfo, error) SearchRecordsWithPage(search dto.RecordSearch) (int64, []dto.BackupRecords, error) + LoadSize(req dto.RecordSearch) ([]dto.BackupFile, error) SearchRecordsByCronjobWithPage(search dto.RecordSearchByCronjob) (int64, []dto.BackupRecords, error) + LoadSizeByCronjob(req dto.RecordSearchByCronjob) ([]dto.BackupFile, error) LoadOneDriveInfo() (dto.OneDriveInfo, error) DownloadRecord(info dto.DownloadRecord) (string, error) Create(backupDto dto.BackupOperate) error @@ -94,11 +95,29 @@ func (u *BackupService) SearchRecordsWithPage(search dto.RecordSearch) (int64, [ return 0, nil, err } - datas, err := u.loadRecordSize(records) - sort.Slice(datas, func(i, j int) bool { - return datas[i].CreatedAt.After(datas[j].CreatedAt) - }) - return total, datas, err + var list []dto.BackupRecords + for _, item := range records { + var itemRecord dto.BackupRecords + if err := copier.Copy(&itemRecord, &item); err != nil { + continue + } + list = append(list, itemRecord) + } + return total, list, err +} + +func (u *BackupService) LoadSize(req dto.RecordSearch) ([]dto.BackupFile, error) { + _, records, err := backupRepo.PageRecord( + req.Page, req.PageSize, + commonRepo.WithOrderBy("created_at desc"), + commonRepo.WithByName(req.Name), + commonRepo.WithByType(req.Type), + backupRepo.WithByDetailName(req.DetailName), + ) + if err != nil { + return nil, err + } + return u.loadRecordSize(records) } func (u *BackupService) ListAppRecords(name, detailName, fileName string) ([]model.BackupRecord, error) { @@ -125,11 +144,27 @@ func (u *BackupService) SearchRecordsByCronjobWithPage(search dto.RecordSearchBy return 0, nil, err } - datas, err := u.loadRecordSize(records) - sort.Slice(datas, func(i, j int) bool { - return datas[i].CreatedAt.After(datas[j].CreatedAt) - }) - return total, datas, err + var list []dto.BackupRecords + for _, item := range records { + var itemRecord dto.BackupRecords + if err := copier.Copy(&itemRecord, &item); err != nil { + continue + } + list = append(list, itemRecord) + } + return total, list, err +} + +func (u *BackupService) LoadSizeByCronjob(req dto.RecordSearchByCronjob) ([]dto.BackupFile, error) { + _, records, err := backupRepo.PageRecord( + req.Page, req.PageSize, + commonRepo.WithOrderBy("created_at desc"), + backupRepo.WithByCronID(req.CronjobID), + ) + if err != nil { + return nil, err + } + return u.loadRecordSize(records) } type loadSizeHelper struct { @@ -482,15 +517,14 @@ func (u *BackupService) loadAccessToken(backup *model.BackupAccount) error { return nil } -func (u *BackupService) loadRecordSize(records []model.BackupRecord) ([]dto.BackupRecords, error) { - var datas []dto.BackupRecords +func (u *BackupService) loadRecordSize(records []model.BackupRecord) ([]dto.BackupFile, error) { + var datas []dto.BackupFile clientMap := make(map[string]loadSizeHelper) var wg sync.WaitGroup for i := 0; i < len(records); i++ { - var item dto.BackupRecords - if err := copier.Copy(&item, &records[i]); err != nil { - return nil, errors.WithMessage(constant.ErrStructTransform, err.Error()) - } + var item dto.BackupFile + item.ID = records[i].ID + item.Name = records[i].FileName itemPath := path.Join(records[i].FileDir, records[i].FileName) if _, ok := clientMap[records[i].Source]; !ok { backup, err := backupRepo.Get(commonRepo.WithByType(records[i].Source)) diff --git a/backend/router/ro_setting.go b/backend/router/ro_setting.go index dc19dc935..f23c8dda1 100644 --- a/backend/router/ro_setting.go +++ b/backend/router/ro_setting.go @@ -56,7 +56,9 @@ func (s *SettingRouter) InitRouter(Router *gin.RouterGroup) { settingRouter.POST("/backup/del", baseApi.DeleteBackup) settingRouter.POST("/backup/update", baseApi.UpdateBackup) settingRouter.POST("/backup/record/search", baseApi.SearchBackupRecords) + settingRouter.POST("/backup/record/size", baseApi.LoadBackupSize) settingRouter.POST("/backup/record/search/bycronjob", baseApi.SearchBackupRecordsByCronjob) + settingRouter.POST("/backup/record/size/bycronjob", baseApi.LoadBackupSizeByCronjob) settingRouter.POST("/backup/record/download", baseApi.DownloadRecord) settingRouter.POST("/backup/record/del", baseApi.DeleteBackupRecord) diff --git a/frontend/src/api/interface/backup.ts b/frontend/src/api/interface/backup.ts index c29c5e1fd..d4cfc7fa7 100644 --- a/frontend/src/api/interface/backup.ts +++ b/frontend/src/api/interface/backup.ts @@ -40,6 +40,11 @@ export namespace Backup { fileDir: string; fileName: string; } + export interface BackupFile { + id: number; + name: string; + size: number; + } export interface ForBucket { type: string; accessKey: string; diff --git a/frontend/src/api/modules/setting.ts b/frontend/src/api/modules/setting.ts index 321f490fd..59d44147a 100644 --- a/frontend/src/api/modules/setting.ts +++ b/frontend/src/api/modules/setting.ts @@ -124,9 +124,15 @@ export const deleteBackupRecord = (params: { ids: number[] }) => { export const searchBackupRecords = (params: Backup.SearchBackupRecord) => { return http.post>(`/settings/backup/record/search`, params, TimeoutEnum.T_5M); }; +export const loadBackupSize = (param: Backup.SearchBackupRecord) => { + return http.post>(`/settings/backup/record/size`, param); +}; export const searchBackupRecordsByCronjob = (params: Backup.SearchBackupRecordByCronjob) => { return http.post>(`/settings/backup/record/search/bycronjob`, params, TimeoutEnum.T_5M); }; +export const loadCronjobBackupSize = (param: Backup.SearchBackupRecordByCronjob) => { + return http.post>(`/settings/backup/record/size/bycronjob`, param); +}; export const getBackupList = () => { return http.get>(`/settings/backup/search`); diff --git a/frontend/src/components/backup/index.vue b/frontend/src/components/backup/index.vue index 34ec991a8..25f57509b 100644 --- a/frontend/src/components/backup/index.vue +++ b/frontend/src/components/backup/index.vue @@ -48,10 +48,15 @@ @@ -110,7 +115,7 @@ import { computeSize, dateFormat, downloadFile } from '@/utils/util'; import { getBackupList, handleBackup, handleRecover } from '@/api/modules/setting'; import i18n from '@/lang'; import DrawerHeader from '@/components/drawer-header/index.vue'; -import { deleteBackupRecord, downloadBackupRecord, searchBackupRecords } from '@/api/modules/setting'; +import { deleteBackupRecord, downloadBackupRecord, searchBackupRecords, loadBackupSize } from '@/api/modules/setting'; import { Backup } from '@/api/interface/backup'; import router from '@/routers'; import { MsgSuccess } from '@/utils/message'; @@ -197,6 +202,31 @@ const search = async () => { loading.value = false; data.value = res.data.items || []; paginationConfig.total = res.data.total; + if (paginationConfig.total !== 0) { + loadSize(params); + } + }) + .catch(() => { + loading.value = false; + }); +}; + +const loadSize = async (params: any) => { + await loadBackupSize(params) + .then((res) => { + let stats = res.data || []; + if (stats.length === 0) { + return; + } + for (const backup of data.value) { + for (const item of stats) { + if (backup.id === item.id) { + backup.hasLoad = true; + backup.size = item.size; + break; + } + } + } }) .catch(() => { loading.value = false; diff --git a/frontend/src/views/cronjob/backup/index.vue b/frontend/src/views/cronjob/backup/index.vue index 4683c6ab1..a51076997 100644 --- a/frontend/src/views/cronjob/backup/index.vue +++ b/frontend/src/views/cronjob/backup/index.vue @@ -26,10 +26,15 @@ @@ -57,7 +62,7 @@ import { reactive, ref } from 'vue'; import { computeSize, dateFormat, downloadFile } from '@/utils/util'; import i18n from '@/lang'; import DrawerHeader from '@/components/drawer-header/index.vue'; -import { downloadBackupRecord, searchBackupRecordsByCronjob } from '@/api/modules/setting'; +import { downloadBackupRecord, loadCronjobBackupSize, searchBackupRecordsByCronjob } from '@/api/modules/setting'; import { Backup } from '@/api/interface/backup'; const selects = ref([]); @@ -101,6 +106,31 @@ const search = async () => { loading.value = false; data.value = res.data.items || []; paginationConfig.total = res.data.total; + if (paginationConfig.total !== 0) { + loadSize(params); + } + }) + .catch(() => { + loading.value = false; + }); +}; + +const loadSize = async (params: any) => { + await loadCronjobBackupSize(params) + .then((res) => { + let stats = res.data || []; + if (stats.length === 0) { + return; + } + for (const backup of data.value) { + for (const item of stats) { + if (backup.id === item.id) { + backup.hasLoad = true; + backup.size = item.size; + break; + } + } + } }) .catch(() => { loading.value = false;