diff --git a/backend/app/service/cornjob.go b/backend/app/service/cornjob.go index 1451df3ea..6e0b912b6 100644 --- a/backend/app/service/cornjob.go +++ b/backend/app/service/cornjob.go @@ -262,7 +262,7 @@ func (u *CronjobService) AddCronJob(cronjob *model.Cronjob) (int, error) { } func mkdirAndWriteFile(cronjob *model.Cronjob, startTime time.Time, msg []byte) (string, error) { - dir := fmt.Sprintf("%s/%s/%s-%v", constant.TaskDir, cronjob.Type, cronjob.Name, cronjob.ID) + dir := fmt.Sprintf("%s/%s/%s", constant.TaskDir, cronjob.Type, cronjob.Name) if _, err := os.Stat(dir); err != nil && os.IsNotExist(err) { if err = os.MkdirAll(dir, os.ModePerm); err != nil { return "", err @@ -289,6 +289,8 @@ func loadSpec(cronjob model.Cronjob) string { 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": diff --git a/backend/app/service/cronjob_helper.go b/backend/app/service/cronjob_helper.go index 7dd588b7b..a0f78277f 100644 --- a/backend/app/service/cronjob_helper.go +++ b/backend/app/service/cronjob_helper.go @@ -32,6 +32,7 @@ func (u *CronjobService) HandleJob(cronjob *model.Cronjob) { if errExec != nil { err = errors.New(string(stdout)) } + message = stdout case "website": record.File, err = u.HandleBackup(cronjob, record.StartTime) case "database": @@ -61,9 +62,11 @@ func (u *CronjobService) HandleJob(cronjob *model.Cronjob) { cronjobRepo.EndRecords(record, constant.StatusFailed, err.Error(), string(message)) return } - record.Records, err = mkdirAndWriteFile(cronjob, record.StartTime, message) - if err != nil { - global.LOG.Errorf("save file %s failed, err: %v", record.Records, err) + if len(message) != 0 { + record.Records, err = mkdirAndWriteFile(cronjob, record.StartTime, message) + if err != nil { + global.LOG.Errorf("save file %s failed, err: %v", record.Records, err) + } } cronjobRepo.EndRecords(record, constant.StatusSuccess, "", record.Records) } @@ -143,8 +146,11 @@ func (u *CronjobService) HandleDelete(id uint) error { global.Cron.Remove(cron.EntryID(cronjob.EntryID)) _ = cronjobRepo.DeleteRecord(cronjobRepo.WithByJobID(int(id))) - if err := os.RemoveAll(fmt.Sprintf("%s/%s-%v", constant.TaskDir, commonDir, cronjob.ID)); err != nil { - global.LOG.Errorf("rm file %s/%s-%v failed, err: %v", constant.TaskDir, commonDir, cronjob.ID, err) + dir := fmt.Sprintf("%s/%s/%s", constant.TaskDir, cronjob.Type, cronjob.Name) + if _, err := os.Stat(dir); err == nil { + if err := os.RemoveAll(dir); err != nil { + global.LOG.Errorf("rm file %s/%s failed, err: %v", constant.TaskDir, commonDir, err) + } } return nil } diff --git a/frontend/src/api/modules/cronjob.ts b/frontend/src/api/modules/cronjob.ts index 87c3f4b63..0c9e9c99b 100644 --- a/frontend/src/api/modules/cronjob.ts +++ b/frontend/src/api/modules/cronjob.ts @@ -34,6 +34,6 @@ export const download = (params: Cronjob.Download) => { return http.download(`cronjobs/download`, params, { responseType: 'blob' }); }; -export const handleOnce = (params: number) => { - return http.post(`cronjobs/handle/${params}`); +export const handleOnce = (id: number) => { + return http.post(`cronjobs/handle`, { id: id }); }; diff --git a/frontend/src/lang/modules/en.ts b/frontend/src/lang/modules/en.ts index a1c257c1f..4f7b7f16b 100644 --- a/frontend/src/lang/modules/en.ts +++ b/frontend/src/lang/modules/en.ts @@ -143,6 +143,8 @@ export default { removing: 'removing', paused: 'paused', exited: 'exited', + enabled: 'Enabled', + disabled: 'Disabled', }, }, menu: { @@ -469,6 +471,9 @@ export default { }, cronjob: { cronTask: 'Task', + changeStatus: 'Change status', + disableMsg: 'The cronjob cannot continue to run after it is stopped. Do you want to stop it?', + enableMsg: 'The cronjob has been stopped. Enable now?', taskType: 'Task type', shell: 'shell', website: 'website', @@ -495,6 +500,7 @@ export default { perWeek: 'Per week', perHour: 'Per hour', perNDay: 'Every N days', + perDay: 'Every days', perNHour: 'Every N hours', perNMinute: 'Every N minutes', per: 'Every ', diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts index f45d5a774..bdfde33e5 100644 --- a/frontend/src/lang/modules/zh.ts +++ b/frontend/src/lang/modules/zh.ts @@ -146,6 +146,8 @@ export default { paused: '暂停', exited: '停止', installing: '安装中', + enabled: '已启用', + disabled: '已停止', }, }, menu: { @@ -481,6 +483,9 @@ export default { }, cronjob: { cronTask: '计划任务', + changeStatus: '状态修改', + disableMsg: '计划任务停止后将无法继续运行,是否停止?', + enableMsg: '该计划任务已停止,是否启用?', taskType: '任务类型', shell: 'Shell 脚本', website: '备份网站', @@ -507,6 +512,7 @@ export default { perWeek: '每周', perHour: '每小时', perNDay: '每隔 N 日', + perDay: '每天', perNHour: '每隔 N 时', perNMinute: '每隔 N 分钟', per: '每隔', diff --git a/frontend/src/views/cronjob/index.vue b/frontend/src/views/cronjob/index.vue index 73b51a8af..47061c622 100644 --- a/frontend/src/views/cronjob/index.vue +++ b/frontend/src/views/cronjob/index.vue @@ -19,15 +19,18 @@ @@ -90,10 +93,9 @@ import { loadBackupName } from '@/views/setting/helper'; import i18n from '@/lang'; import { Cronjob } from '@/api/interface/cronjob'; import { useDeleteData } from '@/hooks/use-delete-data'; -import { ElMessage } from 'element-plus'; +import { ElMessage, ElMessageBox } from 'element-plus'; const selects = ref([]); -const switchState = ref(false); const data = ref(); const paginationConfig = reactive({ @@ -164,17 +166,19 @@ const onBatchDelete = async (row: Cronjob.CronjobInfo | null) => { await useDeleteData(deleteCronjob, { ids: ids }, 'commons.msg.delete'); search(); }; -const beforeChangeStatus = () => { - switchState.value = true; - return switchState.value; -}; -const onChangeStatus = async (row: Cronjob.CronjobInfo) => { - if (switchState.value) { - await updateStatus({ id: row.id, status: row.status }); + +const onChangeStatus = async (id: number, status: string) => { + ElMessageBox.confirm(i18n.global.t('cronjob.' + status + 'Msg'), i18n.global.t('cronjob.changeStatus'), { + confirmButtonText: i18n.global.t('commons.button.confirm'), + cancelButtonText: i18n.global.t('commons.button.cancel'), + }).then(async () => { + let itemStatus = status === 'enable' ? 'Enable' : 'Disable'; + await updateStatus({ id: id, status: itemStatus }); ElMessage.success(i18n.global.t('commons.msg.operationSuccess')); search(); - } + }); }; + const onHandle = async (row: Cronjob.CronjobInfo) => { await handleOnce(row.id); ElMessage.success(i18n.global.t('commons.msg.operationSuccess')); diff --git a/frontend/src/views/cronjob/operate/index.vue b/frontend/src/views/cronjob/operate/index.vue index ddf963853..f5fb90b0a 100644 --- a/frontend/src/views/cronjob/operate/index.vue +++ b/frontend/src/views/cronjob/operate/index.vue @@ -226,6 +226,16 @@ const varifySpec = (rule: any, value: any, callback: any) => { callback(new Error(i18n.global.t('cronjob.cronSpecRule'))); } break; + case 'perDay': + if ( + !( + Number.isInteger(dialogData.value.rowData!.hour) && + Number.isInteger(dialogData.value.rowData!.minute) + ) + ) { + callback(new Error(i18n.global.t('cronjob.cronSpecRule'))); + } + break; case 'perNHour': if ( !( @@ -250,6 +260,7 @@ const specOptions = [ { label: i18n.global.t('cronjob.perMonth'), value: 'perMonth' }, { label: i18n.global.t('cronjob.perWeek'), value: 'perWeek' }, { label: i18n.global.t('cronjob.perNDay'), value: 'perNDay' }, + { label: i18n.global.t('cronjob.perDay'), value: 'perDay' }, { label: i18n.global.t('cronjob.perNHour'), value: 'perNHour' }, { label: i18n.global.t('cronjob.perHour'), value: 'perHour' }, { label: i18n.global.t('cronjob.perNMinute'), value: 'perNMinute' }, @@ -341,7 +352,7 @@ function changeName(isChangeType: boolean, type: string) { } } } - dialogData.value.rowData!.name = `${type}-test`; + dialogData.value.rowData!.name = `${type}_test`; } const onSubmit = async (formEl: FormInstance | undefined) => { diff --git a/frontend/src/views/cronjob/record/index.vue b/frontend/src/views/cronjob/record/index.vue index 4db96ebd5..ab3cbc830 100644 --- a/frontend/src/views/cronjob/record/index.vue +++ b/frontend/src/views/cronjob/record/index.vue @@ -191,35 +191,26 @@ - + - - {{ currentRecord?.message }} - -
- -
- - {{ currentRecordDetail }} - -
- -
-
+ +
+ + {{ currentRecordDetail }} + +
+ +