使用SpringBoot集成Quartz定时任务
基于GitHub项目xkcoding/**spring-boot-demo**进行学习
项目地址:https://github.com/xkcoding/spring-boot-demo
spring-boot-starter-quartz
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<artifactId>spring-boot-demo-task-quartzartifactId>
<version>1.0.0-SNAPSHOTversion>
<packaging>jarpackaging>
<name>spring-boot-demo-task-quartzname>
<description>Demo project for Spring Bootdescription>
<parent>
<groupId>com.xkcodinggroupId>
<artifactId>spring-boot-demoartifactId>
<version>1.0.0-SNAPSHOTversion>
parent>
<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
<java.version>1.8java.version>
<mybatis.mapper.version>2.1.0mybatis.mapper.version>
<mybatis.pagehelper.version>1.2.10mybatis.pagehelper.version>
properties>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-quartzartifactId>
dependency>
<dependency>
<groupId>tk.mybatisgroupId>
<artifactId>mapper-spring-boot-starterartifactId>
<version>${mybatis.mapper.version}version>
dependency>
<dependency>
<groupId>com.github.pagehelpergroupId>
<artifactId>pagehelper-spring-boot-starterartifactId>
<version>${mybatis.pagehelper.version}version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>cn.hutoolgroupId>
<artifactId>hutool-allartifactId>
dependency>
<dependency>
<groupId>com.google.guavagroupId>
<artifactId>guavaartifactId>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<optional>trueoptional>
dependency>
dependencies>
<build>
<finalName>spring-boot-demo-task-quartzfinalName>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
build>
project>
参考博客: https://blog.csdn.net/noaman_wgs/article/details/80984873
Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,完全由Java开发,可以用来执行定时任务,类似于java.util.Timer。但是相较于Timer, Quartz增加了很多功能:
Quartz的基本组成部分:
package com.xkcoding.task.quartz.common;
import lombok.Data;
import org.springframework.http.HttpStatus;
import java.io.Serializable;
/**
*
* 通用Api封装
*
*
* @package: com.xkcoding.task.quartz.common
* @description: 通用Api封装
* @author: yangkai.shen
* @date: Created in 2018-11-26 13:59
* @copyright: Copyright (c) 2018
* @version: V1.0
* @modified: yangkai.shen
*/
@Data
public class ApiResponse implements Serializable {
/**
* 返回信息
*/
private String message;
/**
* 返回数据
*/
private Object data;
public ApiResponse() {
}
private ApiResponse(String message, Object data) {
this.message = message;
this.data = data;
}
/**
* 通用封装获取ApiResponse对象
*
* @param message 返回信息
* @param data 返回数据
* @return ApiResponse
*/
public static ApiResponse of(String message, Object data) {
return new ApiResponse(message, data);
}
/**
* 通用成功封装获取ApiResponse对象
*
* @param data 返回数据
* @return ApiResponse
*/
public static ApiResponse ok(Object data) {
return new ApiResponse(HttpStatus.OK.getReasonPhrase(), data);
}
/**
* 通用封装获取ApiResponse对象
*
* @param message 返回信息
* @return ApiResponse
*/
public static ApiResponse msg(String message) {
return of(message, null);
}
}
package com.xkcoding.task.quartz.entity.domain;
import lombok.Data;
import java.math.BigInteger;
/**
*
* 实体类
*
*
* @package: com.xkcoding.task.quartz.entity.domain
* @description: 实体类
* @author: yangkai.shen
* @date: Created in 2018-11-26 15:05
* @copyright: Copyright (c) 2018
* @version: V1.0
* @modified: yangkai.shen
*/
@Data
public class JobAndTrigger {
/**
* 定时任务名称
*/
private String jobName;
/**
* 定时任务组
*/
private String jobGroup;
/**
* 定时任务全类名
*/
private String jobClassName;
/**
* 触发器名称
*/
private String triggerName;
/**
* 触发器组
*/
private String triggerGroup;
/**
* 重复间隔
*/
private BigInteger repeatInterval;
/**
* 触发次数
*/
private BigInteger timesTriggered;
/**
* cron 表达式
*/
private String cronExpression;
/**
* 时区
*/
private String timeZoneId;
/**
* 定时任务状态
*/
private String triggerState;
}
package com.xkcoding.task.quartz.entity.form;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotBlank;
/**
*
* 定时任务详情
*
*
* @package: com.xkcoding.task.quartz.entity.form
* @description: 定时任务详情
* @author: yangkai.shen
* @date: Created in 2018-11-26 13:42
* @copyright: Copyright (c) 2018
* @version: V1.0
* @modified: yangkai.shen
*/
@Data
@Accessors(chain = true)
public class JobForm {
/**
* 定时任务全类名
*/
@NotBlank(message = "类名不能为空")
private String jobClassName;
/**
* 任务组名
*/
@NotBlank(message = "任务组名不能为空")
private String jobGroupName;
/**
* 定时任务cron表达式
*/
@NotBlank(message = "cron表达式不能为空")
private String cronExpression;
}
package com.xkcoding.task.quartz.job.base;
import org.quartz.*;
/**
*
* Job 基类,主要是在 {@link org.quartz.Job} 上再封装一层,只让我们自己项目里的Job去实现
*
*
* @package: com.xkcoding.task.quartz.job.base
* @description: Job 基类,主要是在 {@link org.quartz.Job} 上再封装一层,只让我们自己项目里的Job去实现
* @author: yangkai.shen
* @date: Created in 2018-11-26 13:27
* @copyright: Copyright (c) 2018
* @version: V1.0
* @modified: yangkai.shen
*/
public interface BaseJob extends Job {
/**
*
* Called by the {@link Scheduler}
when a {@link Trigger}
* fires that is associated with the Job
.
*
*
*
* The implementation may wish to set a
* {@link JobExecutionContext#setResult(Object) result} object on the
* {@link JobExecutionContext} before this method exits. The result itself
* is meaningless to Quartz, but may be informative to
* {@link JobListener}s
or
* {@link TriggerListener}s
that are watching the job's
* execution.
*
*
* @param context 上下文
* @throws JobExecutionException if there is an exception while executing the job.
*/
@Override
void execute(JobExecutionContext context) throws JobExecutionException;
}
package com.xkcoding.task.quartz.job;
import cn.hutool.core.date.DateUtil;
import com.xkcoding.task.quartz.job.base.BaseJob;
import lombok.extern.slf4j.Slf4j;
import org.quartz.JobExecutionContext;
/**
*
* Hello Job
*
*
* @package: com.xkcoding.task.quartz.job
* @description: Hello Job
* @author: yangkai.shen
* @date: Created in 2018-11-26 13:22
* @copyright: Copyright (c) 2018
* @version: V1.0
* @modified: yangkai.shen
*/
@Slf4j
public class HelloJob implements BaseJob {
@Override
public void execute(JobExecutionContext context) {
log.error("Hello Job 执行时间: {}", DateUtil.now());
}
}
package com.xkcoding.task.quartz.job;
import cn.hutool.core.date.DateUtil;
import com.xkcoding.task.quartz.job.base.BaseJob;
import lombok.extern.slf4j.Slf4j;
import org.quartz.JobExecutionContext;
/**
*
* Hello Job
*
*
* @package: com.xkcoding.task.quartz.job
* @description: Hello Job
* @author: yangkai.shen
* @date: Created in 2018-11-26 13:22
* @copyright: Copyright (c) 2018
* @version: V1.0
* @modified: yangkai.shen
*/
@Slf4j
public class HelloJob implements BaseJob {
@Override
public void execute(JobExecutionContext context) {
log.error("Hello Job 执行时间: {}", DateUtil.now());
}
}
package com.xkcoding.task.quartz.mapper;
import com.xkcoding.task.quartz.entity.domain.JobAndTrigger;
import org.springframework.stereotype.Component;
import java.util.List;
/**
*
* Job Mapper
*
*
* @package: com.xkcoding.task.quartz.mapper
* @description: Job Mapper
* @author: yangkai.shen
* @date: Created in 2018-11-26 15:12
* @copyright: Copyright (c) 2018
* @version: V1.0
* @modified: yangkai.shen
*/
@Component
public interface JobMapper {
/**
* 查询定时作业和触发器列表
*
* @return 定时作业和触发器列表
*/
List<JobAndTrigger> list();
}
<mapper namespace="com.xkcoding.task.quartz.mapper.JobMapper">
<select id="list" resultType="com.xkcoding.task.quartz.entity.domain.JobAndTrigger">
SELECT
job_details.`JOB_NAME`,
job_details.`JOB_GROUP`,
job_details.`JOB_CLASS_NAME`,
cron_triggers.`CRON_EXPRESSION`,
cron_triggers.`TIME_ZONE_ID`,
qrtz_triggers.`TRIGGER_NAME`,
qrtz_triggers.`TRIGGER_GROUP`,
qrtz_triggers.`TRIGGER_STATE`
FROM
`QRTZ_JOB_DETAILS` job_details
LEFT JOIN `QRTZ_CRON_TRIGGERS` cron_triggers ON job_details.`JOB_NAME` = cron_triggers.`TRIGGER_NAME`
AND job_details.`JOB_GROUP` = cron_triggers.`TRIGGER_GROUP`
LEFT JOIN `QRTZ_TRIGGERS` qrtz_triggers ON qrtz_triggers.`TRIGGER_NAME` = job_details.`JOB_NAME`
AND qrtz_triggers.`TRIGGER_GROUP` = job_details.`JOB_GROUP`
select>
mapper>
package com.xkcoding.task.quartz.service;
import com.github.pagehelper.PageInfo;
import com.xkcoding.task.quartz.entity.domain.JobAndTrigger;
import com.xkcoding.task.quartz.entity.form.JobForm;
import org.quartz.JobDetail;
import org.quartz.SchedulerException;
/**
*
* Job Service
*
*
* @package: com.xkcoding.task.quartz.service
* @description: Job Service
* @author: yangkai.shen
* @date: Created in 2018-11-26 13:24
* @copyright: Copyright (c) 2018
* @version: V1.0
* @modified: yangkai.shen
*/
public interface JobService {
/**
* 添加并启动定时任务
*
* @param form 表单参数 {@link JobForm}
* @throws Exception 异常
*/
void addJob(JobForm form) throws Exception;
/**
* 删除定时任务
*
* @param form 表单参数 {@link JobForm}
* @throws SchedulerException 异常
*/
void deleteJob(JobForm form) throws SchedulerException;
/**
* 暂停定时任务
*
* @param form 表单参数 {@link JobForm}
* @throws SchedulerException 异常
*/
void pauseJob(JobForm form) throws SchedulerException;
/**
* 恢复定时任务
*
* @param form 表单参数 {@link JobForm}
* @throws SchedulerException 异常
*/
void resumeJob(JobForm form) throws SchedulerException;
/**
* 重新配置定时任务
*
* @param form 表单参数 {@link JobForm}
* @throws Exception 异常
*/
void cronJob(JobForm form) throws Exception;
/**
* 查询定时任务列表
*
* @param currentPage 当前页
* @param pageSize 每页条数
* @return 定时任务列表
*/
PageInfo<JobAndTrigger> list(Integer currentPage, Integer pageSize);
}
package com.xkcoding.task.quartz.service.impl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.xkcoding.task.quartz.entity.domain.JobAndTrigger;
import com.xkcoding.task.quartz.entity.form.JobForm;
import com.xkcoding.task.quartz.mapper.JobMapper;
import com.xkcoding.task.quartz.service.JobService;
import com.xkcoding.task.quartz.util.JobUtil;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
*
* Job Service
*
*
* @package: com.xkcoding.task.quartz.service.impl
* @description: Job Service
* @author: yangkai.shen
* @date: Created in 2018-11-26 13:25
* @copyright: Copyright (c) 2018
* @version: V1.0
* @modified: yangkai.shen
*/
@Service
@Slf4j
public class JobServiceImpl implements JobService {
private final Scheduler scheduler; // 调度器
private final JobMapper jobMapper;
@Autowired
public JobServiceImpl(Scheduler scheduler, JobMapper jobMapper) {
this.scheduler = scheduler;
this.jobMapper = jobMapper;
}
/**
* 添加并启动定时任务
*
* @param form 表单参数 {@link JobForm}
* @return {@link JobDetail}
* @throws Exception 异常
*/
@Override
public void addJob(JobForm form) throws Exception {
// 启动调度器
scheduler.start();
// 构建Job信息
// 建造者模式
JobDetail jobDetail = JobBuilder.newJob(JobUtil.getClass(form.getJobClassName()).getClass()).withIdentity(form.getJobClassName(), form.getJobGroupName()).build();
// Cron表达式调度构建器(即任务执行的时间)
CronScheduleBuilder cron = CronScheduleBuilder.cronSchedule(form.getCronExpression());
//根据Cron表达式构建一个Trigger
CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(form.getJobClassName(), form.getJobGroupName()).withSchedule(cron).build();
try {
scheduler.scheduleJob(jobDetail, trigger);
} catch (SchedulerException e) {
log.error("【定时任务】创建失败!", e);
throw new Exception("【定时任务】创建失败!");
}
}
/**
* 删除定时任务
*
* @param form 表单参数 {@link JobForm}
* @throws SchedulerException 异常
*/
@Override
public void deleteJob(JobForm form) throws SchedulerException {
// 暂停触发器
scheduler.pauseTrigger(TriggerKey.triggerKey(form.getJobClassName(), form.getJobGroupName()));
// 使job失效
scheduler.unscheduleJob(TriggerKey.triggerKey(form.getJobClassName(), form.getJobGroupName()));
// 删除job
scheduler.deleteJob(JobKey.jobKey(form.getJobClassName(), form.getJobGroupName()));
}
/**
* 暂停定时任务
*
* @param form 表单参数 {@link JobForm}
* @throws SchedulerException 异常
*/
@Override
public void pauseJob(JobForm form) throws SchedulerException {
scheduler.pauseJob(JobKey.jobKey(form.getJobClassName(), form.getJobGroupName()));
}
/**
* 恢复定时任务
*
* @param form 表单参数 {@link JobForm}
* @throws SchedulerException 异常
*/
@Override
public void resumeJob(JobForm form) throws SchedulerException {
scheduler.resumeJob(JobKey.jobKey(form.getJobClassName(), form.getJobGroupName()));
}
/**
* 重新配置定时任务
*
* @param form 表单参数 {@link JobForm}
* @throws Exception 异常
*/
@Override
public void cronJob(JobForm form) throws Exception {
try {
TriggerKey triggerKey = TriggerKey.triggerKey(form.getJobClassName(), form.getJobGroupName());
// 表达式调度构建器
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(form.getCronExpression());
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
// 根据Cron表达式构建一个Trigger
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
// 按新的trigger重新设置job执行
scheduler.rescheduleJob(triggerKey, trigger);
} catch (SchedulerException e) {
log.error("【定时任务】更新失败!", e);
throw new Exception("【定时任务】创建失败!");
}
}
/**
* 查询定时任务列表
*
* @param currentPage 当前页
* @param pageSize 每页条数
* @return 定时任务列表
*/
@Override
public PageInfo<JobAndTrigger> list(Integer currentPage, Integer pageSize) {
PageHelper.startPage(currentPage, pageSize);
List<JobAndTrigger> list = jobMapper.list();
return new PageInfo<>(list);
}
}
package com.xkcoding.task.quartz.util;
import com.xkcoding.task.quartz.job.base.BaseJob;
/**
*
* 定时任务反射工具类
*
*
* @package: com.xkcoding.task.quartz.util
* @description: 定时任务反射工具类
* @author: yangkai.shen
* @date: Created in 2018-11-26 13:33
* @copyright: Copyright (c) 2018
* @version: V1.0
* @modified: yangkai.shen
*/
public class JobUtil {
/**
* 根据全类名获取Job实例
*
* @param classname Job全类名
* @return {@link BaseJob} 实例
* @throws Exception 泛型获取异常
*/
public static BaseJob getClass(String classname) throws Exception {
Class<?> clazz = Class.forName(classname);
return (BaseJob) clazz.newInstance();
}
}
<html>
<head>
<meta charset="UTF-8">
<title>spring-boot-demo-task-quartztitle>
<link href="https://cdnjs.cloudflare.com/ajax/libs/element-ui/2.4.9/theme-chalk/index.css" rel="stylesheet">
<script src="https://cdn.bootcss.com/vue/2.5.17/vue.min.js">script>
<script src="https://cdn.bootcss.com/vue-resource/1.5.1/vue-resource.min.js">script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/element-ui/2.4.9/index.js">script>
<style>
#top {
/*background: #20A0FF;*/
padding: 5px;
/*overflow: hidden*/
}
style>
head>
<body>
<div id="job">
<div id="top">
<el-button size="small" type="primary" plain @click="search" :loading="loading" icon="el-icon-search">查询
el-button>
<el-button size="small" type="primary" plain @click="handleadd" icon="el-icon-plus">添加el-button>
div>
<br/>
<div>
<el-table ref="jobTable" :data="tableData" style="width:100%" border center>
<el-table-column prop="jobName" label="任务名称" show-overflow-tooltip align="center">el-table-column>
<el-table-column prop="jobGroup" label="任务所在组" sortable align="center">el-table-column>
<el-table-column prop="jobClassName" label="任务类名" align="center">el-table-column>
<el-table-column prop="triggerName" label="触发器名称" align="center">el-table-column>
<el-table-column prop="triggerGroup" label="触发器所在组" sortable align="center">el-table-column>
<el-table-column prop="cronExpression" label="表达式" align="center">el-table-column>
<el-table-column prop="timeZoneId" label="时区" align="center">el-table-column>
<el-table-column prop="triggerState" label="状态" align="center" :formatter="formatState">el-table-column>
<el-table-column label="操作" width="300" align="center">
<template scope="scope">
<el-button size="small" type="warning" @click="handlePause(scope.$index, scope.row)">
暂停
el-button>
<el-button size="small" type="info" @click="handleResume(scope.$index, scope.row)">
恢复
el-button>
<el-button size="small" type="danger" @click="handleDelete(scope.$index, scope.row)">
删除
el-button>
<el-button size="small" type="success" @click="handleUpdate(scope.$index, scope.row)">
修改
el-button>
template>
el-table-column>
el-table>
<div align="center">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="currentPage"
:page-sizes="[10, 20, 30, 40]"
:page-size="pagesize"
layout="total, sizes, prev, pager, next, jumper"
:total="totalCount">
el-pagination>
div>
div>
<el-dialog title="添加任务" :visible.sync="dialogFormVisible">
<el-form :model="form">
<el-form-item label="任务名称" label-width="100px" style="width:90%">
<el-input v-model="form.jobName" auto-complete="off">el-input>
el-form-item>
<el-form-item label="任务分组" label-width="100px" style="width:90%">
<el-input v-model="form.jobGroup" auto-complete="off">el-input>
el-form-item>
<el-form-item label="表达式" label-width="100px" style="width:90%">
<el-input v-model="form.cronExpression" auto-complete="off">el-input>
el-form-item>
el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取 消el-button>
<el-button type="primary" @click="add">确 定el-button>
div>
el-dialog>
<el-dialog title="修改任务" :visible.sync="updateFormVisible">
<el-form :model="updateform">
<el-form-item label="表达式" label-width="100px" style="width:90%">
<el-input v-model="updateform.cronExpression" auto-complete="off">el-input>
el-form-item>
el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="updateFormVisible = false">取 消el-button>
<el-button type="primary" @click="update">确 定el-button>
div>
el-dialog>
div>
<footer align="center">
<p>© Quartz 定时任务管理p>
footer>
<script>
var vue = new Vue({
el: "#job",
data: {
//表格当前页数据
tableData: [],
//请求的URL
url: 'job',
//默认每页数据量
pagesize: 10,
//当前页码
currentPage: 1,
//查询的页码
start: 1,
//默认数据总数
totalCount: 1000,
//添加对话框默认可见性
dialogFormVisible: false,
//修改对话框默认可见性
updateFormVisible: false,
//提交的表单
form: {
jobName: '',
jobGroup: '',
cronExpression: ''
},
updateform: {
jobName: '',
jobGroup: '',
cronExpression: ''
},
loading: false
},
methods: {
// 格式化状态
formatState: function (row, column, cellValue, index) {
if (row.triggerState === 'WAITING' || row.triggerState === 'ACQUIRED') {
return "运行中";
} else if (row.triggerState === 'PAUSED') {
return "暂停";
} else {
return "未知状态";
}
},
// 从服务器读取数据
loadData: function (currentPage, pageSize) {
this.loading = true;
this.$http.get('job?' + 'currentPage=' + currentPage + '&pageSize=' + pageSize).then(function (res) {
console.log(res);
this.tableData = res.body.data.data;
this.totalCount = res.body.data.total;
this.loading = false;
}, function () {
console.log('failed');
});
},
// 删除任务
handleDelete: function (index, row) {
this.$http.delete('job', {
params: {
"jobClassName": row.jobName,
"jobGroupName": row.jobGroup
}
}, {emulateJSON: true}).then(function (res) {
this.loadData(this.currentPage, this.pagesize);
}, function () {
console.log('failed');
});
},
// 暂停任务
handlePause: function (index, row) {
this.$http.put('job?pause', {
"jobClassName": row.jobName,
"jobGroupName": row.jobGroup
}, {emulateJSON: true}).then(function (res) {
this.loadData(this.currentPage, this.pagesize);
}, function () {
console.log('failed');
});
},
// 恢复任务
handleResume: function (index, row) {
this.$http.put('job?resume', {
"jobClassName": row.jobName,
"jobGroupName": row.jobGroup
}, {emulateJSON: true}).then(function (res) {
this.loadData(this.currentPage, this.pagesize);
}, function () {
console.log('failed');
});
},
// 搜索
search: function () {
this.loadData(this.currentPage, this.pagesize);
},
// 弹出对话框
handleadd: function () {
this.dialogFormVisible = true;
},
// 添加
add: function () {
this.$http.post('job', {
"jobClassName": this.form.jobName,
"jobGroupName": this.form.jobGroup,
"cronExpression": this.form.cronExpression
}, {emulateJSON: true}).then(function (res) {
this.loadData(this.currentPage, this.pagesize);
this.dialogFormVisible = false;
}, function () {
console.log('failed');
});
},
// 更新
handleUpdate: function (index, row) {
console.log(row);
this.updateFormVisible = true;
this.updateform.jobName = row.jobName;
this.updateform.jobGroup = row.jobGroup;
},
// 更新任务
update: function () {
this.$http.put('job?cron',
{
"jobClassName": this.updateform.jobName,
"jobGroupName": this.updateform.jobGroup,
"cronExpression": this.updateform.cronExpression
}, {emulateJSON: true}
).then(function (res) {
this.loadData(this.currentPage, this.pagesize);
this.updateFormVisible = false;
}, function () {
console.log('failed');
});
},
// 每页显示数据量变更
handleSizeChange: function (val) {
this.pagesize = val;
this.loadData(this.currentPage, this.pagesize);
},
// 页码变更
handleCurrentChange: function (val) {
this.currentPage = val;
this.loadData(this.currentPage, this.pagesize);
}
}
});
//载入数据
vue.loadData(vue.currentPage, vue.pagesize);
script>
body>
html>
http://localhost:8080/demo/job.html
,可以看到前端页面