diff --git a/agent/app/api/v2/cronjob.go b/agent/app/api/v2/cronjob.go index 4fcecf482..15153a699 100644 --- a/agent/app/api/v2/cronjob.go +++ b/agent/app/api/v2/cronjob.go @@ -270,6 +270,28 @@ func (b *BaseApi) UpdateCronjob(c *gin.Context) { helper.Success(c) } +// @Tags Cronjob +// @Summary Update cronjob group +// @Accept json +// @Param request body dto.ChangeGroup true "request" +// @Success 200 +// @Security ApiKeyAuth +// @Security Timestamp +// @Router /cronjobs/group/update [post] +// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"cronjobs","output_column":"name","output_value":"name"}],"formatZH":"更新计划任务分组 [name]","formatEN":"update cronjob group [name]"} +func (b *BaseApi) UpdateCronjobGroup(c *gin.Context) { + var req dto.ChangeGroup + if err := helper.CheckBindAndValidate(&req, c); err != nil { + return + } + + if err := cronjobService.UpdateGroup(req); err != nil { + helper.InternalServer(c, err) + return + } + helper.Success(c) +} + // @Tags Cronjob // @Summary Update cronjob status // @Accept json diff --git a/agent/app/dto/common_req.go b/agent/app/dto/common_req.go index 311dce14a..576bb447b 100644 --- a/agent/app/dto/common_req.go +++ b/agent/app/dto/common_req.go @@ -79,3 +79,8 @@ type ForceDelete struct { IDs []uint `json:"ids"` ForceDelete bool `json:"forceDelete"` } + +type ChangeGroup struct { + ID uint `json:"id" validate:"required"` + GroupID uint `json:"groupID" validate:"required"` +} diff --git a/agent/app/dto/cronjob.go b/agent/app/dto/cronjob.go index 2e8721687..9be525412 100644 --- a/agent/app/dto/cronjob.go +++ b/agent/app/dto/cronjob.go @@ -6,9 +6,10 @@ import ( type PageCronjob struct { PageInfo - Info string `json:"info"` - OrderBy string `json:"orderBy" validate:"required,oneof=name status createdAt"` - Order string `json:"order" validate:"required,oneof=null ascending descending"` + Info string `json:"info"` + GroupIDs []uint `json:"groupIDs"` + OrderBy string `json:"orderBy" validate:"required,oneof=name status createdAt"` + Order string `json:"order" validate:"required,oneof=null ascending descending"` } type CronjobSpec struct { @@ -19,6 +20,7 @@ type CronjobOperate struct { ID uint `json:"id"` Name string `json:"name" validate:"required"` Type string `json:"type" validate:"required"` + GroupID uint `json:"groupID"` SpecCustom bool `json:"specCustom"` Spec string `json:"spec" validate:"required"` @@ -85,6 +87,7 @@ type CronjobInfo struct { ID uint `json:"id"` Name string `json:"name"` Type string `json:"type"` + GroupID uint `json:"groupID"` SpecCustom bool `json:"specCustom"` Spec string `json:"spec"` @@ -129,6 +132,7 @@ type CronjobImport struct { type CronjobTrans struct { Name string `json:"name"` Type string `json:"type"` + GroupID uint `json:"groupID"` SpecCustom bool `json:"specCustom"` Spec string `json:"spec"` diff --git a/agent/app/model/cronjob.go b/agent/app/model/cronjob.go index d743e903c..0ded2757c 100644 --- a/agent/app/model/cronjob.go +++ b/agent/app/model/cronjob.go @@ -11,6 +11,7 @@ type Cronjob struct { Name string `gorm:"not null" json:"name"` Type string `gorm:"not null" json:"type"` + GroupID uint `json:"groupID"` SpecCustom bool `json:"specCustom"` Spec string `gorm:"not null" json:"spec"` diff --git a/agent/app/repo/common.go b/agent/app/repo/common.go index d9280e6db..2b40e8417 100644 --- a/agent/app/repo/common.go +++ b/agent/app/repo/common.go @@ -104,6 +104,15 @@ func WithByDate(startTime, endTime time.Time) DBOption { } } +func WithByGroups(groupIDs []uint) DBOption { + return func(g *gorm.DB) *gorm.DB { + if len(groupIDs) == 0 { + return g + } + return g.Where("group_id in (?)", groupIDs) + } +} + func WithByCreatedAt(startTime, endTime time.Time) DBOption { return func(g *gorm.DB) *gorm.DB { return g.Where("created_at > ? AND created_at < ?", startTime, endTime) diff --git a/agent/app/service/cronjob.go b/agent/app/service/cronjob.go index 57b42dd2f..db062a6fe 100644 --- a/agent/app/service/cronjob.go +++ b/agent/app/service/cronjob.go @@ -32,6 +32,7 @@ type ICronjobService interface { HandleOnce(id uint) error Update(id uint, req dto.CronjobOperate) error UpdateStatus(id uint, status string) error + UpdateGroup(req dto.ChangeGroup) error Delete(req dto.CronjobBatchDelete) error Download(down dto.CronjobDownload) (string, error) StartJob(cronjob *model.Cronjob, isUpdate bool) (string, error) @@ -50,7 +51,11 @@ func NewICronjobService() ICronjobService { } func (u *CronjobService) SearchWithPage(search dto.PageCronjob) (int64, interface{}, error) { - total, cronjobs, err := cronjobRepo.Page(search.Page, search.PageSize, repo.WithByLikeName(search.Info), repo.WithOrderRuleBy(search.OrderBy, search.Order)) + total, cronjobs, err := cronjobRepo.Page(search.Page, + search.PageSize, + repo.WithByGroups(search.GroupIDs), + repo.WithByLikeName(search.Info), + repo.WithOrderRuleBy(search.OrderBy, search.Order)) var dtoCronjobs []dto.CronjobInfo for _, cronjob := range cronjobs { var item dto.CronjobInfo @@ -116,6 +121,7 @@ func (u *CronjobService) Export(req dto.OperateByIDs) (string, error) { item := dto.CronjobTrans{ Name: cronjob.Name, Type: cronjob.Type, + GroupID: cronjob.GroupID, SpecCustom: cronjob.SpecCustom, Spec: cronjob.Spec, Executor: cronjob.Executor, @@ -211,6 +217,7 @@ func (u *CronjobService) Import(req []dto.CronjobTrans) error { cronjob := model.Cronjob{ Name: item.Name, Type: item.Type, + GroupID: item.GroupID, SpecCustom: item.SpecCustom, Spec: item.Spec, Executor: item.Executor, @@ -774,6 +781,14 @@ func (u *CronjobService) UpdateStatus(id uint, status string) error { return cronjobRepo.Update(cronjob.ID, map[string]interface{}{"status": status, "entry_ids": entryIDs}) } +func (u *CronjobService) UpdateGroup(req dto.ChangeGroup) error { + cronjob, _ := cronjobRepo.Get(repo.WithByID(req.ID)) + if cronjob.ID == 0 { + return buserr.New("ErrRecordNotFound") + } + return cronjobRepo.Update(cronjob.ID, map[string]interface{}{"group_id": req.GroupID}) +} + func (u *CronjobService) AddCronJob(cronjob *model.Cronjob) (int, error) { addFunc := func() { u.HandleJob(cronjob) diff --git a/agent/init/migration/migrations/init.go b/agent/init/migration/migrations/init.go index 3314d9a7e..af465a146 100644 --- a/agent/init/migration/migrations/init.go +++ b/agent/init/migration/migrations/init.go @@ -19,7 +19,7 @@ import ( ) var AddTable = &gormigrate.Migration{ - ID: "20250507-add-table", + ID: "20250729-add-table", Migrate: func(tx *gorm.DB) error { return tx.AutoMigrate( &model.AppDetail{}, diff --git a/agent/router/ro_cronjob.go b/agent/router/ro_cronjob.go index 277938a57..72aa56397 100644 --- a/agent/router/ro_cronjob.go +++ b/agent/router/ro_cronjob.go @@ -19,6 +19,7 @@ func (s *CronjobRouter) InitRouter(Router *gin.RouterGroup) { cmdRouter.GET("/script/options", baseApi.LoadScriptOptions) cmdRouter.POST("/del", baseApi.DeleteCronjob) cmdRouter.POST("/update", baseApi.UpdateCronjob) + cmdRouter.POST("/group/update", baseApi.UpdateCronjobGroup) cmdRouter.POST("/status", baseApi.UpdateCronjobStatus) cmdRouter.POST("/handle", baseApi.HandleOnce) cmdRouter.POST("/download", baseApi.TargetDownload) diff --git a/core/app/service/group.go b/core/app/service/group.go index 84875c04c..3aea01248 100644 --- a/core/app/service/group.go +++ b/core/app/service/group.go @@ -116,8 +116,6 @@ func (u *GroupService) Delete(id uint) error { if err := xpack.UpdateGroup("node", id, defaultGroup.ID); err != nil { return err } - default: - return buserr.New("ErrNotSupportType") } if err != nil { return err diff --git a/core/init/migration/migrate.go b/core/init/migration/migrate.go index 007bc9c6e..cb1fc5502 100644 --- a/core/init/migration/migrate.go +++ b/core/init/migration/migrate.go @@ -22,6 +22,7 @@ func Init() { migrations.UpdateOnedrive, migrations.AddClusterMenu, migrations.DeleteXpackHideMenu, + migrations.AddCronjobGroup, }) if err := m.Migrate(); err != nil { global.LOG.Error(err) diff --git a/core/init/migration/migrations/init.go b/core/init/migration/migrations/init.go index 1b2efa6b8..468daf365 100644 --- a/core/init/migration/migrations/init.go +++ b/core/init/migration/migrations/init.go @@ -531,3 +531,13 @@ var DeleteXpackHideMenu = &gormigrate.Migration{ return tx.Model(&model.Setting{}).Where("key = ?", "HideMenu").Update("value", string(updatedJSON)).Error }, } + +var AddCronjobGroup = &gormigrate.Migration{ + ID: "20250729-add-cronjob-group", + Migrate: func(tx *gorm.DB) error { + if err := tx.Create(&model.Group{Name: "Default", Type: "cronjob", IsDefault: true}).Error; err != nil { + return err + } + return nil + }, +} diff --git a/frontend/src/api/interface/cronjob.ts b/frontend/src/api/interface/cronjob.ts index 4e28c4fff..4dd5ac8ff 100644 --- a/frontend/src/api/interface/cronjob.ts +++ b/frontend/src/api/interface/cronjob.ts @@ -5,6 +5,7 @@ export namespace Cronjob { id: number; name: string; type: string; + groupID: number; specCustom: boolean; spec: string; specs: Array; diff --git a/frontend/src/api/interface/index.ts b/frontend/src/api/interface/index.ts index 411be2e67..fc65b012e 100644 --- a/frontend/src/api/interface/index.ts +++ b/frontend/src/api/interface/index.ts @@ -20,6 +20,7 @@ export interface ReqPage { } export interface SearchWithPage { info: string; + groupIDs: Array; page: number; pageSize: number; orderBy?: string; diff --git a/frontend/src/api/modules/cronjob.ts b/frontend/src/api/modules/cronjob.ts index 92258fcc2..29613ef6e 100644 --- a/frontend/src/api/modules/cronjob.ts +++ b/frontend/src/api/modules/cronjob.ts @@ -3,7 +3,7 @@ import { ResPage, SearchWithPage } from '../interface'; import { Cronjob } from '../interface/cronjob'; import { TimeoutEnum } from '@/enums/http-enum'; -export const getCronjobPage = (params: SearchWithPage) => { +export const searchCronjobPage = (params: SearchWithPage) => { return http.post>(`/cronjobs/search`, params); }; @@ -11,6 +11,10 @@ export const loadNextHandle = (spec: string) => { return http.post>(`/cronjobs/next`, { spec: spec }); }; +export const editCronjobGroup = (id: number, groupID: number) => { + return http.post(`/cronjobs/group/update`, { id: id, groupID: groupID }); +}; + export const importCronjob = (trans: Array) => { return http.post('cronjobs/import', { cronjobs: trans }, TimeoutEnum.T_60S); }; diff --git a/frontend/src/views/cronjob/cronjob/index.vue b/frontend/src/views/cronjob/cronjob/index.vue index a944aae0c..893735ade 100644 --- a/frontend/src/views/cronjob/cronjob/index.vue +++ b/frontend/src/views/cronjob/cronjob/index.vue @@ -5,7 +5,10 @@ {{ $t('commons.button.create') }}{{ $t('menu.cronjob') }} - + + {{ $t('commons.table.group') }} + + {{ $t('commons.button.enable') }} @@ -17,7 +20,7 @@ - + {{ $t('commons.button.import') }} @@ -27,6 +30,17 @@ + + +