feat: 增加计划任务记录清空按钮 (#528)

This commit is contained in:
ssongliu 2023-04-07 12:02:10 +08:00 committed by GitHub
parent e45ef455ef
commit 8902111c23
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 697 additions and 459 deletions

View File

@ -92,6 +92,30 @@ func (b *BaseApi) SearchJobRecords(c *gin.Context) {
}) })
} }
// @Tags Cronjob
// @Summary Clean job records
// @Description 清空计划任务记录
// @Accept json
// @Param request body dto.OperateByID true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /cronjobs/records/clean [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"cronjobs","output_colume":"name","output_value":"name"}],"formatZH":"清空计划任务记录 [name]","formatEN":"clean cronjob [name] records"}
func (b *BaseApi) CleanRecord(c *gin.Context) {
var req dto.OperateByID
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := cronjobService.CleanRecord(req.ID); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, nil)
}
// @Tags Cronjob // @Tags Cronjob
// @Summary Delete cronjob // @Summary Delete cronjob
// @Description 删除计划任务 // @Description 删除计划任务

View File

@ -20,6 +20,7 @@ type ICronjobRepo interface {
Page(limit, offset int, opts ...DBOption) (int64, []model.Cronjob, error) Page(limit, offset int, opts ...DBOption) (int64, []model.Cronjob, error)
Create(cronjob *model.Cronjob) error Create(cronjob *model.Cronjob) error
WithByJobID(id int) DBOption WithByJobID(id int) DBOption
WithByRecordDropID(id int) DBOption
Save(id uint, cronjob model.Cronjob) error Save(id uint, cronjob model.Cronjob) error
Update(id uint, vars map[string]interface{}) error Update(id uint, vars map[string]interface{}) error
Delete(opts ...DBOption) error Delete(opts ...DBOption) error
@ -113,6 +114,12 @@ func (c *CronjobRepo) WithByJobID(id int) DBOption {
} }
} }
func (c *CronjobRepo) WithByRecordDropID(id int) DBOption {
return func(g *gorm.DB) *gorm.DB {
return g.Where("id < ?", id)
}
}
func (u *CronjobRepo) StartRecords(cronjobID uint, fromLocal bool, targetPath string) model.JobRecords { func (u *CronjobRepo) StartRecords(cronjobID uint, fromLocal bool, targetPath string) model.JobRecords {
var record model.JobRecords var record model.JobRecords
record.StartTime = time.Now() record.StartTime = time.Now()

View File

@ -27,6 +27,7 @@ type ICronjobService interface {
Delete(ids []uint) error Delete(ids []uint) error
Download(down dto.CronjobDownload) (string, error) Download(down dto.CronjobDownload) (string, error)
StartJob(cronjob *model.Cronjob) (int, error) StartJob(cronjob *model.Cronjob) (int, error)
CleanRecord(id uint) error
} }
func NewICronjobService() ICronjobService { func NewICronjobService() ICronjobService {
@ -78,6 +79,27 @@ func (u *CronjobService) SearchRecords(search dto.SearchRecord) (int64, interfac
return total, dtoCronjobs, err return total, dtoCronjobs, err
} }
func (u *CronjobService) CleanRecord(id uint) error {
_, records, err := cronjobRepo.PageRecords(1, 7, cronjobRepo.WithByJobID(int(id)), commonRepo.WithOrderBy("created_at desc"))
if err != nil {
return err
}
if len(records) < 7 {
return nil
}
delRecords, err := cronjobRepo.ListRecord(cronjobRepo.WithByJobID(int(id)), cronjobRepo.WithByRecordDropID(int(records[6].ID)))
if err != nil {
return err
}
for _, del := range delRecords {
_ = os.RemoveAll(del.Records)
}
if err := cronjobRepo.DeleteRecord(cronjobRepo.WithByJobID(int(id)), cronjobRepo.WithByRecordDropID(int(records[6].ID))); err != nil {
return err
}
return nil
}
func (u *CronjobService) Download(down dto.CronjobDownload) (string, error) { func (u *CronjobService) Download(down dto.CronjobDownload) (string, error) {
record, _ := cronjobRepo.GetRecord(commonRepo.WithByID(down.RecordID)) record, _ := cronjobRepo.GetRecord(commonRepo.WithByID(down.RecordID))
if record.ID == 0 { if record.ID == 0 {

View File

@ -24,5 +24,6 @@ func (s *CronjobRouter) InitCronjobRouter(Router *gin.RouterGroup) {
cmdRouter.POST("/download", baseApi.TargetDownload) cmdRouter.POST("/download", baseApi.TargetDownload)
cmdRouter.POST("/search", baseApi.SearchCronjob) cmdRouter.POST("/search", baseApi.SearchCronjob)
cmdRouter.POST("/search/records", baseApi.SearchJobRecords) cmdRouter.POST("/search/records", baseApi.SearchJobRecords)
cmdRouter.POST("/records/clean", baseApi.CleanRecord)
} }
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -22,6 +22,10 @@ export const searchRecords = (params: Cronjob.SearchRecord) => {
return http.post<ResPage<Cronjob.Record>>(`cronjobs/search/records`, params); return http.post<ResPage<Cronjob.Record>>(`cronjobs/search/records`, params);
}; };
export const cleanRecords = (id: number) => {
return http.post(`cronjobs/records/clean`, { id: id });
};
export const getRecordDetail = (params: string) => { export const getRecordDetail = (params: string) => {
return http.post<string>(`cronjobs/search/detail`, { path: params }); return http.post<string>(`cronjobs/search/detail`, { path: params });
}; };

View File

@ -584,6 +584,8 @@ const message = {
taskName: 'Task name', taskName: 'Task name',
cronSpec: 'Lifecycle', cronSpec: 'Lifecycle',
cronSpecHelper: 'Enter the correct execution period', cronSpecHelper: 'Enter the correct execution period',
cleanHelper:
'This operation will retain the latest seven task execution records and log files. Do you want to continue?',
directory: 'Backup directory', directory: 'Backup directory',
sourceDir: 'Backup directory', sourceDir: 'Backup directory',
allOptionHelper: allOptionHelper:

View File

@ -588,6 +588,7 @@ const message = {
taskName: '任务名称', taskName: '任务名称',
cronSpec: '执行周期', cronSpec: '执行周期',
cronSpecHelper: '请输入正确的执行周期', cronSpecHelper: '请输入正确的执行周期',
cleanHelper: '该操作将保留最新的 7 份任务执行记录和日志文件是否继续',
directory: '备份目录', directory: '备份目录',
sourceDir: '备份目录', sourceDir: '备份目录',
allOptionHelper: '当前计划任务为备份所有 {0}暂不支持直接下载可在 {0} 备份列表中查看', allOptionHelper: '当前计划任务为备份所有 {0}暂不支持直接下载可在 {0} 备份列表中查看',

View File

@ -65,6 +65,7 @@
> >
{{ $t('commons.button.disable') }} {{ $t('commons.button.disable') }}
</el-button> </el-button>
<el-divider direction="vertical" />
<el-button <el-button
type="primary" type="primary"
v-if="dialogData.rowData.status === 'Disable'" v-if="dialogData.rowData.status === 'Disable'"
@ -73,6 +74,9 @@
> >
{{ $t('commons.button.enable') }} {{ $t('commons.button.enable') }}
</el-button> </el-button>
<el-button type="primary" :disabled="records.length <= 7" @click="cleanRecord()" link>
{{ $t('commons.button.clean') }}
</el-button>
</span> </span>
</div> </div>
</el-card> </el-card>
@ -289,7 +293,7 @@
import { reactive, ref } from 'vue'; import { reactive, ref } from 'vue';
import { Cronjob } from '@/api/interface/cronjob'; import { Cronjob } from '@/api/interface/cronjob';
import { loadZero } from '@/utils/util'; import { loadZero } from '@/utils/util';
import { searchRecords, download, handleOnce, updateStatus } from '@/api/modules/cronjob'; import { searchRecords, download, handleOnce, updateStatus, cleanRecords } from '@/api/modules/cronjob';
import { dateFormat } from '@/utils/util'; import { dateFormat } from '@/utils/util';
import i18n from '@/lang'; import i18n from '@/lang';
import { ElMessageBox } from 'element-plus'; import { ElMessageBox } from 'element-plus';
@ -519,6 +523,18 @@ const loadRecord = async (row: Cronjob.Record) => {
currentRecordDetail.value = res.data; currentRecordDetail.value = res.data;
} }
}; };
const cleanRecord = async () => {
ElMessageBox.confirm(i18n.global.t('cronjob.cleanHelper'), i18n.global.t('commons.button.clean'), {
confirmButtonText: i18n.global.t('commons.button.confirm'),
cancelButtonText: i18n.global.t('commons.button.cancel'),
type: 'info',
}).then(async () => {
await cleanRecords(dialogData.value.rowData.id);
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
search(true);
});
};
function isBackup() { function isBackup() {
return ( return (
dialogData.value.rowData!.type === 'website' || dialogData.value.rowData!.type === 'website' ||