diff --git a/backend/app/dto/cronjob.go b/backend/app/dto/cronjob.go index 7bc33a29b..6ae136a2c 100644 --- a/backend/app/dto/cronjob.go +++ b/backend/app/dto/cronjob.go @@ -3,14 +3,9 @@ package dto import "time" type CronjobCreate struct { - Name string `json:"name" validate:"required"` - Type string `json:"type" validate:"required"` - SpecType string `json:"specType" validate:"required"` - Week int `json:"week" validate:"number,max=6,min=0"` - Day int `json:"day" validate:"number"` - Hour int `json:"hour" validate:"number"` - Minute int `json:"minute" validate:"number"` - Second int `json:"second" validate:"number"` + Name string `json:"name" validate:"required"` + Type string `json:"type" validate:"required"` + Spec string `json:"spec" validate:"required"` Script string `json:"script"` ContainerName string `json:"containerName"` @@ -27,14 +22,9 @@ type CronjobCreate struct { } type CronjobUpdate struct { - ID uint `json:"id" validate:"required"` - Name string `json:"name" validate:"required"` - SpecType string `json:"specType" validate:"required"` - Week int `json:"week" validate:"number,max=6,min=0"` - Day int `json:"day" validate:"number"` - Hour int `json:"hour" validate:"number"` - Minute int `json:"minute" validate:"number"` - Second int `json:"second" validate:"number"` + ID uint `json:"id" validate:"required"` + Name string `json:"name" validate:"required"` + Spec string `json:"spec" validate:"required"` Script string `json:"script"` ContainerName string `json:"containerName"` @@ -71,15 +61,10 @@ type CronjobBatchDelete struct { } type CronjobInfo struct { - ID uint `json:"id"` - Name string `json:"name"` - Type string `json:"type"` - SpecType string `json:"specType"` - Week int `json:"week"` - Day int `json:"day"` - Hour int `json:"hour"` - Minute int `json:"minute"` - Second int `json:"second"` + ID uint `json:"id"` + Name string `json:"name"` + Type string `json:"type"` + Spec string `json:"spec"` Script string `json:"script"` ContainerName string `json:"containerName"` diff --git a/backend/app/model/cronjob.go b/backend/app/model/cronjob.go index 5bd27aecf..fb1432666 100644 --- a/backend/app/model/cronjob.go +++ b/backend/app/model/cronjob.go @@ -5,15 +5,9 @@ import "time" type Cronjob struct { BaseModel - Name string `gorm:"type:varchar(64);not null;unique" json:"name"` - Type string `gorm:"type:varchar(64);not null" json:"type"` - SpecType string `gorm:"type:varchar(64);not null" json:"specType"` - Spec string `gorm:"type:varchar(64);not null" json:"spec"` - Week uint64 `gorm:"type:decimal" json:"week"` - Day uint64 `gorm:"type:decimal" json:"day"` - Hour uint64 `gorm:"type:decimal" json:"hour"` - Minute uint64 `gorm:"type:decimal" json:"minute"` - Second uint64 `gorm:"type:decimal" json:"second"` + Name string `gorm:"type:varchar(64);not null" json:"name"` + Type string `gorm:"type:varchar(64);not null" json:"type"` + Spec string `gorm:"type:varchar(64);not null" json:"spec"` ContainerName string `gorm:"type:varchar(64)" json:"containerName"` Script string `gorm:"longtext" json:"script"` @@ -29,9 +23,9 @@ type Cronjob struct { TargetDirID uint64 `gorm:"type:decimal" json:"targetDirID"` RetainCopies uint64 `gorm:"type:decimal" json:"retainCopies"` - Status string `gorm:"type:varchar(64)" json:"status"` - EntryID uint64 `gorm:"type:decimal" json:"entryID"` - Records []JobRecords `json:"records"` + Status string `gorm:"type:varchar(64)" json:"status"` + EntryIDs string `gorm:"type:varchar(64)" json:"entryIDs"` + Records []JobRecords `json:"records"` } type JobRecords struct { diff --git a/backend/app/service/cornjob.go b/backend/app/service/cornjob.go index 060908f32..12866cc36 100644 --- a/backend/app/service/cornjob.go +++ b/backend/app/service/cornjob.go @@ -5,6 +5,8 @@ import ( "fmt" "os" "path" + "strconv" + "strings" "time" "github.com/1Panel-dev/1Panel/backend/app/dto" @@ -28,7 +30,7 @@ type ICronjobService interface { UpdateStatus(id uint, status string) error Delete(req dto.CronjobBatchDelete) error Download(down dto.CronjobDownload) (string, error) - StartJob(cronjob *model.Cronjob) (int, error) + StartJob(cronjob *model.Cronjob) (string, error) CleanRecord(req dto.CronjobClean) error LoadRecordLog(req dto.OperateByID) (string, error) @@ -184,29 +186,40 @@ func (u *CronjobService) Create(cronjobDto dto.CronjobCreate) error { return errors.WithMessage(constant.ErrStructTransform, err.Error()) } cronjob.Status = constant.StatusEnable - cronjob.Spec = loadSpec(cronjob) global.LOG.Infof("create cronjob %s successful, spec: %s", cronjob.Name, cronjob.Spec) - entryID, err := u.StartJob(&cronjob) + spec := cronjob.Spec + entryIDs, err := u.StartJob(&cronjob) if err != nil { return err } - cronjob.EntryID = uint64(entryID) + cronjob.Spec = spec + cronjob.EntryIDs = entryIDs if err := cronjobRepo.Create(&cronjob); err != nil { return err } return nil } -func (u *CronjobService) StartJob(cronjob *model.Cronjob) (int, error) { - if cronjob.EntryID != 0 { - global.Cron.Remove(cron.EntryID(cronjob.EntryID)) +func (u *CronjobService) StartJob(cronjob *model.Cronjob) (string, error) { + if len(cronjob.EntryIDs) != 0 { + ids := strings.Split(cronjob.EntryIDs, ",") + for _, id := range ids { + idItem, _ := strconv.Atoi(id) + global.Cron.Remove(cron.EntryID(idItem)) + } } - entryID, err := u.AddCronJob(cronjob) - if err != nil { - return 0, err + specs := strings.Split(cronjob.Spec, ",") + var ids []string + for _, spec := range specs { + cronjob.Spec = spec + entryID, err := u.AddCronJob(cronjob) + if err != nil { + return "", err + } + ids = append(ids, fmt.Sprintf("%v", entryID)) } - return entryID, nil + return strings.Join(ids, ","), nil } func (u *CronjobService) Delete(req dto.CronjobBatchDelete) error { @@ -215,8 +228,12 @@ func (u *CronjobService) Delete(req dto.CronjobBatchDelete) error { if cronjob.ID == 0 { return errors.New("find cronjob in db failed") } - global.Cron.Remove(cron.EntryID(cronjob.EntryID)) - global.LOG.Infof("stop cronjob entryID: %d", cronjob.EntryID) + ids := strings.Split(cronjob.EntryIDs, ",") + for _, id := range ids { + idItem, _ := strconv.Atoi(id) + global.Cron.Remove(cron.EntryID(idItem)) + } + global.LOG.Infof("stop cronjob entryID: %s", cronjob.EntryIDs) if err := u.CleanRecord(dto.CronjobClean{CronjobID: id, CleanData: req.CleanData}); err != nil { return err } @@ -238,29 +255,27 @@ func (u *CronjobService) Update(id uint, req dto.CronjobUpdate) error { return constant.ErrRecordNotFound } upMap := make(map[string]interface{}) - cronjob.EntryID = cronModel.EntryID + cronjob.EntryIDs = cronModel.EntryIDs cronjob.Type = cronModel.Type - cronjob.Spec = loadSpec(cronjob) + spec := cronjob.Spec if cronModel.Status == constant.StatusEnable { - newEntryID, err := u.StartJob(&cronjob) + newEntryIDs, err := u.StartJob(&cronjob) if err != nil { return err } - upMap["entry_id"] = newEntryID + upMap["entry_ids"] = newEntryIDs } else { - global.Cron.Remove(cron.EntryID(cronjob.EntryID)) + ids := strings.Split(cronjob.EntryIDs, ",") + for _, id := range ids { + idItem, _ := strconv.Atoi(id) + global.Cron.Remove(cron.EntryID(idItem)) + } } upMap["name"] = req.Name - upMap["spec"] = cronjob.Spec + upMap["spec"] = spec upMap["script"] = req.Script upMap["container_name"] = req.ContainerName - upMap["spec_type"] = req.SpecType - upMap["week"] = req.Week - upMap["day"] = req.Day - upMap["hour"] = req.Hour - upMap["minute"] = req.Minute - upMap["second"] = req.Second upMap["app_id"] = req.AppID upMap["website"] = req.Website upMap["exclusion_rules"] = req.ExclusionRules @@ -280,19 +295,23 @@ func (u *CronjobService) UpdateStatus(id uint, status string) error { return errors.WithMessage(constant.ErrRecordNotFound, "record not found") } var ( - entryID int - err error + entryIDs string + err error ) if status == constant.StatusEnable { - entryID, err = u.StartJob(&cronjob) + entryIDs, err = u.StartJob(&cronjob) if err != nil { return err } } else { - global.Cron.Remove(cron.EntryID(cronjob.EntryID)) - global.LOG.Infof("stop cronjob entryID: %d", cronjob.EntryID) + ids := strings.Split(cronjob.EntryIDs, ",") + for _, id := range ids { + idItem, _ := strconv.Atoi(id) + global.Cron.Remove(cron.EntryID(idItem)) + } + global.LOG.Infof("stop cronjob entryID: %s", cronjob.EntryIDs) } - return cronjobRepo.Update(cronjob.ID, map[string]interface{}{"status": status, "entry_id": entryID}) + return cronjobRepo.Update(cronjob.ID, map[string]interface{}{"status": status, "entry_ids": entryIDs}) } func (u *CronjobService) AddCronJob(cronjob *model.Cronjob) (int, error) { @@ -328,26 +347,3 @@ func mkdirAndWriteFile(cronjob *model.Cronjob, startTime time.Time, msg []byte) write.Flush() return path, nil } - -func loadSpec(cronjob model.Cronjob) string { - switch cronjob.SpecType { - case "perMonth": - return fmt.Sprintf("%v %v %v * *", cronjob.Minute, cronjob.Hour, cronjob.Day) - case "perWeek": - return fmt.Sprintf("%v %v * * %v", cronjob.Minute, cronjob.Hour, cronjob.Week) - case "perNDay": - return fmt.Sprintf("%v %v */%v * *", cronjob.Minute, cronjob.Hour, cronjob.Day) - case "perDay": - return fmt.Sprintf("%v %v * * *", cronjob.Minute, cronjob.Hour) - case "perNHour": - return fmt.Sprintf("%v */%v * * *", cronjob.Minute, cronjob.Hour) - case "perHour": - return fmt.Sprintf("%v * * * *", cronjob.Minute) - case "perNMinute": - return fmt.Sprintf("@every %vm", cronjob.Minute) - case "perNSecond": - return fmt.Sprintf("@every %vs", cronjob.Second) - default: - return "" - } -} diff --git a/backend/cron/cron.go b/backend/cron/cron.go index 7d99e0c86..b1ef463a5 100644 --- a/backend/cron/cron.go +++ b/backend/cron/cron.go @@ -66,11 +66,11 @@ func Run() { global.LOG.Errorf("start my cronjob failed, err: %v", err) } for i := 0; i < len(cronJobs); i++ { - entryID, err := service.NewICronjobService().StartJob(&cronJobs[i]) + entryIDs, err := service.NewICronjobService().StartJob(&cronJobs[i]) if err != nil { global.LOG.Errorf("start %s job %s failed, err: %v", cronJobs[i].Type, cronJobs[i].Name, err) } - if err := repo.NewICronjobRepo().Update(cronJobs[i].ID, map[string]interface{}{"entry_id": entryID}); err != nil { + if err := repo.NewICronjobRepo().Update(cronJobs[i].ID, map[string]interface{}{"entry_ids": entryIDs}); err != nil { global.LOG.Errorf("update cronjob %s %s failed, err: %v", cronJobs[i].Type, cronJobs[i].Name, err) } } diff --git a/backend/init/migration/migrate.go b/backend/init/migration/migrate.go index 9d02eae7d..aba816dba 100644 --- a/backend/init/migration/migrate.go +++ b/backend/init/migration/migrate.go @@ -67,6 +67,7 @@ func Init() { migrations.AddPostgresqlSuperUser, migrations.UpdateCronjobWithWebsite, migrations.UpdateOneDriveToken, + migrations.UpdateCronjobSpec, }) if err := m.Migrate(); err != nil { global.LOG.Error(err) diff --git a/backend/init/migration/migrations/v_1_9.go b/backend/init/migration/migrations/v_1_9.go index c4784d36a..df0c1a51a 100644 --- a/backend/init/migration/migrations/v_1_9.go +++ b/backend/init/migration/migrations/v_1_9.go @@ -254,3 +254,20 @@ var UpdateOneDriveToken = &gormigrate.Migration{ return nil }, } + +var UpdateCronjobSpec = &gormigrate.Migration{ + ID: "20240122-update-cronjob-spec", + Migrate: func(tx *gorm.DB) error { + if err := tx.AutoMigrate(&model.Cronjob{}); err != nil { + return err + } + _ = tx.Exec("ALTER TABLE cronjobs DROP COLUMN spec_type;").Error + _ = tx.Exec("ALTER TABLE cronjobs DROP COLUMN week;").Error + _ = tx.Exec("ALTER TABLE cronjobs DROP COLUMN day;").Error + _ = tx.Exec("ALTER TABLE cronjobs DROP COLUMN hour;").Error + _ = tx.Exec("ALTER TABLE cronjobs DROP COLUMN minute;").Error + _ = tx.Exec("ALTER TABLE cronjobs DROP COLUMN second;").Error + + return nil + }, +} diff --git a/cmd/server/docs/docs.go b/cmd/server/docs/docs.go index e2dc009e0..54f3f803a 100644 --- a/cmd/server/docs/docs.go +++ b/cmd/server/docs/docs.go @@ -14918,7 +14918,7 @@ const docTemplate = `{ "type": "object", "required": [ "name", - "specType", + "spec", "type" ], "properties": { @@ -14928,9 +14928,6 @@ const docTemplate = `{ "containerName": { "type": "string" }, - "day": { - "type": "integer" - }, "dbName": { "type": "string" }, @@ -14940,15 +14937,9 @@ const docTemplate = `{ "exclusionRules": { "type": "string" }, - "hour": { - "type": "integer" - }, "keepLocal": { "type": "boolean" }, - "minute": { - "type": "integer" - }, "name": { "type": "string" }, @@ -14959,13 +14950,10 @@ const docTemplate = `{ "script": { "type": "string" }, - "second": { - "type": "integer" - }, "sourceDir": { "type": "string" }, - "specType": { + "spec": { "type": "string" }, "targetDirID": { @@ -14979,11 +14967,6 @@ const docTemplate = `{ }, "website": { "type": "string" - }, - "week": { - "type": "integer", - "maximum": 6, - "minimum": 0 } } }, @@ -15007,7 +14990,7 @@ const docTemplate = `{ "required": [ "id", "name", - "specType" + "spec" ], "properties": { "appID": { @@ -15016,9 +14999,6 @@ const docTemplate = `{ "containerName": { "type": "string" }, - "day": { - "type": "integer" - }, "dbName": { "type": "string" }, @@ -15028,18 +15008,12 @@ const docTemplate = `{ "exclusionRules": { "type": "string" }, - "hour": { - "type": "integer" - }, "id": { "type": "integer" }, "keepLocal": { "type": "boolean" }, - "minute": { - "type": "integer" - }, "name": { "type": "string" }, @@ -15050,13 +15024,10 @@ const docTemplate = `{ "script": { "type": "string" }, - "second": { - "type": "integer" - }, "sourceDir": { "type": "string" }, - "specType": { + "spec": { "type": "string" }, "targetDirID": { @@ -15067,11 +15038,6 @@ const docTemplate = `{ }, "website": { "type": "string" - }, - "week": { - "type": "integer", - "maximum": 6, - "minimum": 0 } } }, diff --git a/cmd/server/docs/swagger.json b/cmd/server/docs/swagger.json index badace5b1..8d5fce1ef 100644 --- a/cmd/server/docs/swagger.json +++ b/cmd/server/docs/swagger.json @@ -14911,7 +14911,7 @@ "type": "object", "required": [ "name", - "specType", + "spec", "type" ], "properties": { @@ -14921,9 +14921,6 @@ "containerName": { "type": "string" }, - "day": { - "type": "integer" - }, "dbName": { "type": "string" }, @@ -14933,15 +14930,9 @@ "exclusionRules": { "type": "string" }, - "hour": { - "type": "integer" - }, "keepLocal": { "type": "boolean" }, - "minute": { - "type": "integer" - }, "name": { "type": "string" }, @@ -14952,13 +14943,10 @@ "script": { "type": "string" }, - "second": { - "type": "integer" - }, "sourceDir": { "type": "string" }, - "specType": { + "spec": { "type": "string" }, "targetDirID": { @@ -14972,11 +14960,6 @@ }, "website": { "type": "string" - }, - "week": { - "type": "integer", - "maximum": 6, - "minimum": 0 } } }, @@ -15000,7 +14983,7 @@ "required": [ "id", "name", - "specType" + "spec" ], "properties": { "appID": { @@ -15009,9 +14992,6 @@ "containerName": { "type": "string" }, - "day": { - "type": "integer" - }, "dbName": { "type": "string" }, @@ -15021,18 +15001,12 @@ "exclusionRules": { "type": "string" }, - "hour": { - "type": "integer" - }, "id": { "type": "integer" }, "keepLocal": { "type": "boolean" }, - "minute": { - "type": "integer" - }, "name": { "type": "string" }, @@ -15043,13 +15017,10 @@ "script": { "type": "string" }, - "second": { - "type": "integer" - }, "sourceDir": { "type": "string" }, - "specType": { + "spec": { "type": "string" }, "targetDirID": { @@ -15060,11 +15031,6 @@ }, "website": { "type": "string" - }, - "week": { - "type": "integer", - "maximum": 6, - "minimum": 0 } } }, diff --git a/cmd/server/docs/swagger.yaml b/cmd/server/docs/swagger.yaml index c2729825b..293882023 100644 --- a/cmd/server/docs/swagger.yaml +++ b/cmd/server/docs/swagger.yaml @@ -582,20 +582,14 @@ definitions: type: string containerName: type: string - day: - type: integer dbName: type: string dbType: type: string exclusionRules: type: string - hour: - type: integer keepLocal: type: boolean - minute: - type: integer name: type: string retainCopies: @@ -603,11 +597,9 @@ definitions: type: integer script: type: string - second: - type: integer sourceDir: type: string - specType: + spec: type: string targetDirID: type: integer @@ -617,13 +609,9 @@ definitions: type: string website: type: string - week: - maximum: 6 - minimum: 0 - type: integer required: - name - - specType + - spec - type type: object dto.CronjobDownload: @@ -642,22 +630,16 @@ definitions: type: string containerName: type: string - day: - type: integer dbName: type: string dbType: type: string exclusionRules: type: string - hour: - type: integer id: type: integer keepLocal: type: boolean - minute: - type: integer name: type: string retainCopies: @@ -665,11 +647,9 @@ definitions: type: integer script: type: string - second: - type: integer sourceDir: type: string - specType: + spec: type: string targetDirID: type: integer @@ -677,14 +657,10 @@ definitions: type: string website: type: string - week: - maximum: 6 - minimum: 0 - type: integer required: - id - name - - specType + - spec type: object dto.CronjobUpdateStatus: properties: diff --git a/frontend/src/api/interface/cronjob.ts b/frontend/src/api/interface/cronjob.ts index 2278a0671..23460df25 100644 --- a/frontend/src/api/interface/cronjob.ts +++ b/frontend/src/api/interface/cronjob.ts @@ -5,12 +5,8 @@ export namespace Cronjob { id: number; name: string; type: string; - specType: string; - week: number; - day: number; - hour: number; - minute: number; - second: number; + spec: string; + specObjs: Array; script: string; inContainer: boolean; @@ -31,12 +27,8 @@ export namespace Cronjob { export interface CronjobCreate { name: string; type: string; - specType: string; - week: number; - day: number; - hour: number; - minute: number; - second: number; + spec: string; + specObjs: Array; script: string; website: string; @@ -49,14 +41,17 @@ export namespace Cronjob { targetDirID: number; retainCopies: number; } - export interface CronjobUpdate { - id: number; + export interface SpecObj { specType: string; week: number; day: number; hour: number; minute: number; second: number; + } + export interface CronjobUpdate { + id: number; + spec: string; script: string; website: string; diff --git a/frontend/src/views/cronjob/helper.ts b/frontend/src/views/cronjob/helper.ts new file mode 100644 index 000000000..888272740 --- /dev/null +++ b/frontend/src/views/cronjob/helper.ts @@ -0,0 +1,227 @@ +import { Cronjob } from '@/api/interface/cronjob'; +import i18n from '@/lang'; +import { loadZero } from '@/utils/util'; + +export const specOptions = [ + { label: i18n.global.t('cronjob.perMonth'), value: 'perMonth' }, + { label: i18n.global.t('cronjob.perWeek'), value: 'perWeek' }, + { label: i18n.global.t('cronjob.perDay'), value: 'perDay' }, + { label: i18n.global.t('cronjob.perHour'), value: 'perHour' }, + { label: i18n.global.t('cronjob.perNDay'), value: 'perNDay' }, + { label: i18n.global.t('cronjob.perNHour'), value: 'perNHour' }, + { label: i18n.global.t('cronjob.perNMinute'), value: 'perNMinute' }, + { label: i18n.global.t('cronjob.perNSecond'), value: 'perNSecond' }, +]; +export const weekOptions = [ + { label: i18n.global.t('cronjob.monday'), value: 1 }, + { label: i18n.global.t('cronjob.tuesday'), value: 2 }, + { label: i18n.global.t('cronjob.wednesday'), value: 3 }, + { label: i18n.global.t('cronjob.thursday'), value: 4 }, + { label: i18n.global.t('cronjob.friday'), value: 5 }, + { label: i18n.global.t('cronjob.saturday'), value: 6 }, + { label: i18n.global.t('cronjob.sunday'), value: 0 }, +]; +function loadWeek(i: number) { + for (const week of weekOptions) { + if (week.value === i) { + return week.label; + } + } + return ''; +} + +export function loadDefaultSpec(type: string) { + let item = {} as Cronjob.SpecObj; + switch (type) { + case 'shell': + item.specType = 'perWeek'; + item.week = 1; + item.hour = 1; + item.minute = 30; + break; + case 'app': + item.specType = 'perDay'; + item.hour = 2; + item.minute = 30; + break; + case 'database': + item.specType = 'perDay'; + item.hour = 2; + item.minute = 30; + break; + case 'clean': + case 'website': + item.specType = 'perWeek'; + item.week = 1; + item.hour = 1; + item.minute = 30; + break; + case 'log': + case 'snapshot': + item.specType = 'perWeek'; + item.week = 1; + item.hour = 1; + item.minute = 30; + break; + case 'directory': + item.specType = 'perDay'; + item.hour = 1; + item.minute = 30; + break; + case 'curl': + item.specType = 'perWeek'; + item.week = 1; + item.hour = 1; + item.minute = 30; + break; + } + return item; +} + +export function checkScript(specType: string, week, day, hour, minute, second) { + switch (specType) { + case 'perMonth': + return day > 0 && day < 32 && hour >= 0 && hour < 24 && minute >= 0 && minute < 60; + case 'perWeek': + return week >= 0 && week < 7 && hour >= 0 && hour < 24 && minute >= 0 && minute < 60; + case 'perDay': + return hour >= 0 && hour < 24 && minute >= 0 && minute < 60; + case 'perHour': + return minute >= 0 && minute < 60; + case 'perNDay': + return day > 0 && day < 366 && hour >= 0 && hour < 24 && minute >= 0 && minute < 60; + case 'perNHour': + return hour > 0 && hour < 8784 && minute >= 0 && minute < 60; + case 'perNMinute': + return minute > 0 && minute < 527040; + case 'perNSecond': + return second > 0 && second < 31622400; + } +} + +export function transObjToSpec(specType: string, week, day, hour, minute, second): string { + switch (specType) { + case 'perMonth': + return `${minute} ${hour} ${day} * *`; + case 'perWeek': + return `${minute} ${hour} * * ${week}`; + case 'perNDay': + return `${minute} ${hour} */${day} * *`; + case 'perDay': + return `${minute} ${hour} * * *`; + case 'perNHour': + return `${minute} */${hour} * * *`; + case 'perHour': + return `${minute} * * * *`; + case 'perNMinute': + return `@every ${minute}m`; + case 'perNSecond': + return `@every ${second}s`; + default: + return ''; + } +} + +export function transSpecToObj(spec: string) { + let specs = spec.split(' '); + let specItem = { + specType: 'perNMinute', + week: 0, + day: 0, + hour: 0, + minute: 0, + second: 0, + }; + if (specs.length === 2) { + if (specs[1].indexOf('m') !== -1) { + specItem.specType = 'perNMinute'; + specItem.minute = Number(specs[1].replaceAll('m', '')); + return specItem; + } else { + specItem.specType = 'perNSecond'; + specItem.second = Number(specs[1].replaceAll('s', '')); + return specItem; + } + } + if (specs.length !== 5 || specs[0] === '*') { + return null; + } + specItem.minute = Number(specs[0]); + if (specs[1] === '*') { + specItem.specType = 'perHour'; + return specItem; + } + if (specs[1].indexOf('*/') !== -1) { + specItem.specType = 'perNHour'; + specItem.hour = Number(specs[1].replaceAll('*/', '')); + return specItem; + } + specItem.hour = Number(specs[1]); + if (specs[2].indexOf('*/') !== -1) { + specItem.specType = 'perNDay'; + specItem.day = Number(specs[2].replaceAll('*/', '')); + return specItem; + } + if (specs[2] !== '*') { + specItem.specType = 'perMonth'; + specItem.day = Number(specs[2]); + return specItem; + } + if (specs[4] !== '*') { + specItem.specType = 'perWeek'; + specItem.week = Number(specs[4]); + return specItem; + } + specItem.specType = 'perDay'; + return specItem; +} + +export function transSpecToStr(spec: string): string { + const specObj = transSpecToObj(spec); + let str = ''; + if (specObj.specType.indexOf('N') === -1 || specObj.specType === 'perWeek') { + str += i18n.global.t('cronjob.' + specObj.specType) + ' '; + } else { + str += i18n.global.t('cronjob.per') + ' '; + } + switch (specObj.specType) { + case 'perMonth': + str += + specObj.day + + i18n.global.t('cronjob.day') + + ' ' + + loadZero(specObj.hour) + + ':' + + loadZero(specObj.minute); + break; + case 'perWeek': + str += loadWeek(specObj.week) + ' ' + loadZero(specObj.hour) + ':' + loadZero(specObj.minute); + break; + case 'perDay': + str += loadZero(specObj.hour) + ':' + loadZero(specObj.minute); + break; + case 'perNDay': + str += + specObj.day + + i18n.global.t('commons.units.day') + + ', ' + + loadZero(specObj.hour) + + ':' + + loadZero(specObj.minute); + break; + case 'perNHour': + str += specObj.hour + i18n.global.t('commons.units.hour') + ', ' + loadZero(specObj.minute); + break; + case 'perHour': + str += loadZero(specObj.minute); + break; + case 'perNMinute': + str += loadZero(specObj.minute) + i18n.global.t('commons.units.minute'); + break; + case 'perNSecond': + str += loadZero(specObj.second) + i18n.global.t('commons.units.second'); + break; + } + + return str + ' ' + i18n.global.t('cronjob.handle'); +} diff --git a/frontend/src/views/cronjob/index.vue b/frontend/src/views/cronjob/index.vue index f8d308783..048807ced 100644 --- a/frontend/src/views/cronjob/index.vue +++ b/frontend/src/views/cronjob/index.vue @@ -81,35 +81,23 @@ @@ -158,13 +146,13 @@ import TableSetting from '@/components/table-setting/index.vue'; import Tooltip from '@/components/tooltip/index.vue'; import OperateDialog from '@/views/cronjob/operate/index.vue'; import Records from '@/views/cronjob/record/index.vue'; -import { loadZero } from '@/utils/util'; import { onMounted, reactive, ref } from 'vue'; import { deleteCronjob, getCronjobPage, handleOnce, updateStatus } from '@/api/modules/cronjob'; import i18n from '@/lang'; import { Cronjob } from '@/api/interface/cronjob'; import { ElMessageBox } from 'element-plus'; import { MsgSuccess } from '@/utils/message'; +import { transSpecToStr } from './helper'; const loading = ref(); const selects = ref([]); @@ -186,16 +174,6 @@ const paginationConfig = reactive({ }); const searchName = ref(); -const weekOptions = [ - { label: i18n.global.t('cronjob.monday'), value: 1 }, - { label: i18n.global.t('cronjob.tuesday'), value: 2 }, - { label: i18n.global.t('cronjob.wednesday'), value: 3 }, - { label: i18n.global.t('cronjob.thursday'), value: 4 }, - { label: i18n.global.t('cronjob.friday'), value: 5 }, - { label: i18n.global.t('cronjob.saturday'), value: 6 }, - { label: i18n.global.t('cronjob.sunday'), value: 0 }, -]; - const search = async (column?: any) => { paginationConfig.orderBy = column?.order ? column.prop : paginationConfig.orderBy; paginationConfig.order = column?.order ? column.order : paginationConfig.order; @@ -229,13 +207,17 @@ const dialogRef = ref(); const onOpenDialog = async ( title: string, rowData: Partial = { - specType: 'perMonth', + specObjs: [ + { + specType: 'perMonth', + week: 1, + day: 3, + hour: 1, + minute: 30, + second: 30, + }, + ], type: 'shell', - week: 1, - day: 3, - hour: 1, - minute: 30, - second: 30, keepLocal: true, retainCopies: 7, }, @@ -370,14 +352,7 @@ const buttons = [ }, }, ]; -function loadWeek(i: number) { - for (const week of weekOptions) { - if (week.value === i) { - return week.label; - } - } - return ''; -} + onMounted(() => { search(); }); diff --git a/frontend/src/views/cronjob/operate/index.vue b/frontend/src/views/cronjob/operate/index.vue index a79e90ffd..c2b243280 100644 --- a/frontend/src/views/cronjob/operate/index.vue +++ b/frontend/src/views/cronjob/operate/index.vue @@ -64,46 +64,64 @@ - - - - - - - - - - - - - - - - - - +
+ + + + + + + + + + + + + + + + + + + + {{ $t('commons.button.delete') }} + + +
+ + {{ $t('commons.button.add') }} +
@@ -296,7 +314,7 @@