From 74a66f2446cb7458fafa6693514bb4c1e2f50297 Mon Sep 17 00:00:00 2001 From: zwzw1219 Date: Sat, 30 Sep 2017 13:26:14 +0800 Subject: [PATCH] !2 job Merge pull request !2 from zwzw1219/job-crud --- doc/db/boot_backend.sql | 33 +++- .../com/zw/admin/server/config/JobConfig.java | 44 ++--- .../zw/admin/server/config/SwaggerConfig.java | 5 + .../server/controller/JobController.java | 163 ++++++++++++++++ .../java/com/zw/admin/server/dao/JobDao.java | 33 ++++ .../{DeleteLogJob.java => SpringBeanJob.java} | 9 +- .../com/zw/admin/server/model/JobModel.java | 26 +++ .../page/table/PageTableArgumentResolver.java | 39 +++- .../server/page/table/PageTableHandler.java | 3 +- .../server/page/table/PageTableResponse.java | 4 +- .../zw/admin/server/service/JobService.java | 15 ++ .../server/service/impl/JobServiceImpl.java | 151 +++++++++++++++ .../resources/mybatis-mappers/JobMapper.xml | 52 +++++ .../public/pages/article/articleList.html | 182 ++++++++++-------- .../resources/public/pages/file/fileList.html | 136 +++++++------ .../resources/public/pages/job/addJob.html | 101 ++++++++++ .../resources/public/pages/job/jobList.html | 172 +++++++++++++++++ .../resources/public/pages/job/updateJob.html | 120 ++++++++++++ .../resources/public/pages/log/logList.html | 182 +++++++++--------- .../resources/public/pages/mail/mailList.html | 158 ++++++++------- .../resources/public/pages/role/roleList.html | 123 ++++++------ .../resources/public/pages/user/userList.html | 181 +++++++++-------- src/main/resources/static/js/my/job.js | 72 +++++++ 23 files changed, 1529 insertions(+), 475 deletions(-) create mode 100644 src/main/java/com/zw/admin/server/controller/JobController.java create mode 100644 src/main/java/com/zw/admin/server/dao/JobDao.java rename src/main/java/com/zw/admin/server/job/{DeleteLogJob.java => SpringBeanJob.java} (70%) create mode 100644 src/main/java/com/zw/admin/server/model/JobModel.java create mode 100644 src/main/java/com/zw/admin/server/service/JobService.java create mode 100644 src/main/java/com/zw/admin/server/service/impl/JobServiceImpl.java create mode 100644 src/main/resources/mybatis-mappers/JobMapper.xml create mode 100644 src/main/resources/public/pages/job/addJob.html create mode 100644 src/main/resources/public/pages/job/jobList.html create mode 100644 src/main/resources/public/pages/job/updateJob.html create mode 100644 src/main/resources/static/js/my/job.js diff --git a/doc/db/boot_backend.sql b/doc/db/boot_backend.sql index 2411c55..52b5a31 100644 --- a/doc/db/boot_backend.sql +++ b/doc/db/boot_backend.sql @@ -327,10 +327,14 @@ INSERT INTO `sys_permission` VALUES ('22', '0', '公告管理', 'fa-book', 'page INSERT INTO `sys_permission` VALUES ('23', '22', '查询', '', '', '2', 'articles:query', '100'); INSERT INTO `sys_permission` VALUES ('24', '22', '添加', '', '', '2', 'articles:add', '100'); INSERT INTO `sys_permission` VALUES ('25', '22', '删除', '', '', '2', 'articles:del', '100'); -INSERT INTO `sys_permission` VALUES ('26', '0', '日志查询', 'fa-reorder', 'pages/log/logList.html', '1', 'sys:log:query', '100'); -INSERT INTO `sys_permission` VALUES ('27', '0', '邮件管理', 'fa-envelope', 'pages/mail/mailList.html', '1', '', '100'); +INSERT INTO `sys_permission` VALUES ('26', '0', '日志查询', 'fa-reorder', 'pages/log/logList.html', '1', 'sys:log:query', '13'); +INSERT INTO `sys_permission` VALUES ('27', '0', '邮件管理', 'fa-envelope', 'pages/mail/mailList.html', '1', '', '14'); INSERT INTO `sys_permission` VALUES ('28', '27', '发送邮件', '', '', '2', 'mail:send', '100'); INSERT INTO `sys_permission` VALUES ('29', '27', '查询', '', '', '2', 'mail:all:query', '100'); +INSERT INTO `sys_permission` VALUES ('30', '0', '定时任务管理', 'fa-tasks', 'pages/job/jobList.html', '1', '', '15'); +INSERT INTO `sys_permission` VALUES ('31', '30', '查询', '', '', '2', 'job:query', '100'); +INSERT INTO `sys_permission` VALUES ('32', '30', '新增', '', '', '2', 'job:add', '100'); +INSERT INTO `sys_permission` VALUES ('33', '30', '删除', '', '', '2', 'job:del', '100'); -- ---------------------------- -- Table structure for sys_role @@ -392,6 +396,10 @@ INSERT INTO `sys_role_permission` VALUES ('1', '26'); INSERT INTO `sys_role_permission` VALUES ('1', '27'); INSERT INTO `sys_role_permission` VALUES ('1', '28'); INSERT INTO `sys_role_permission` VALUES ('1', '29'); +INSERT INTO `sys_role_permission` VALUES ('1', '30'); +INSERT INTO `sys_role_permission` VALUES ('1', '31'); +INSERT INTO `sys_role_permission` VALUES ('1', '32'); +INSERT INTO `sys_role_permission` VALUES ('1', '33'); INSERT INTO `sys_role_permission` VALUES ('2', '1'); INSERT INTO `sys_role_permission` VALUES ('2', '2'); INSERT INTO `sys_role_permission` VALUES ('2', '3'); @@ -415,6 +423,8 @@ INSERT INTO `sys_role_permission` VALUES ('2', '22'); INSERT INTO `sys_role_permission` VALUES ('2', '23'); INSERT INTO `sys_role_permission` VALUES ('2', '24'); INSERT INTO `sys_role_permission` VALUES ('2', '25'); +INSERT INTO `sys_role_permission` VALUES ('2', '30'); +INSERT INTO `sys_role_permission` VALUES ('2', '31'); -- ---------------------------- -- Table structure for sys_role_user @@ -479,6 +489,25 @@ CREATE TABLE `t_mail` ( -- Records of t_mail -- ---------------------------- +-- ---------------------------- +-- Table structure for t_job +-- ---------------------------- +DROP TABLE IF EXISTS `t_job`; +CREATE TABLE `t_job` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `jobName` varchar(64) NOT NULL, + `description` varchar(255) DEFAULT NULL, + `cron` varchar(64) NOT NULL, + `springBeanName` varchar(64) NOT NULL COMMENT 'springBean名', + `methodName` varchar(64) NOT NULL COMMENT '方法名', + `isSysJob` tinyint(1) NOT NULL COMMENT '是否是系统job', + `status` tinyint(1) NOT NULL DEFAULT '1', + `createTime` datetime NOT NULL, + `updateTime` datetime NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `jobName` (`jobName`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4; + -- ---------------------------- -- Table structure for t_mail_to -- ---------------------------- diff --git a/src/main/java/com/zw/admin/server/config/JobConfig.java b/src/main/java/com/zw/admin/server/config/JobConfig.java index c0933b0..f934306 100644 --- a/src/main/java/com/zw/admin/server/config/JobConfig.java +++ b/src/main/java/com/zw/admin/server/config/JobConfig.java @@ -2,18 +2,18 @@ package com.zw.admin.server.config; import java.io.IOException; +import javax.annotation.PostConstruct; import javax.sql.DataSource; -import org.quartz.Trigger; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.support.PropertiesLoaderUtils; -import org.springframework.scheduling.quartz.CronTriggerFactoryBean; -import org.springframework.scheduling.quartz.JobDetailFactoryBean; import org.springframework.scheduling.quartz.SchedulerFactoryBean; -import com.zw.admin.server.job.DeleteLogJob; +import com.zw.admin.server.model.JobModel; +import com.zw.admin.server.service.JobService; @Configuration public class JobConfig { @@ -34,28 +34,26 @@ public class JobConfig { quartzScheduler.setOverwriteExistingJobs(true); quartzScheduler.setApplicationContextSchedulerContextKey(KEY); - Trigger[] triggers = { deleteLogTrigger().getObject() }; - quartzScheduler.setTriggers(triggers); - return quartzScheduler; } - @Bean - public JobDetailFactoryBean deleteLogJob() { - JobDetailFactoryBean jobDetailFactory = new JobDetailFactoryBean(); - jobDetailFactory.setJobClass(DeleteLogJob.class); - jobDetailFactory.setDurability(true); - jobDetailFactory.setDescription("定时删除三个月前日志"); - - return jobDetailFactory; - } - - @Bean - public CronTriggerFactoryBean deleteLogTrigger() { - CronTriggerFactoryBean cronTriggerFactoryBean = new CronTriggerFactoryBean(); - cronTriggerFactoryBean.setJobDetail(deleteLogJob().getObject()); - cronTriggerFactoryBean.setCronExpression("0 0 0 * * ?"); - return cronTriggerFactoryBean; + @Autowired + private JobService jobService; + + /** + * 初始化一个定时删除日志的任务 + */ + @PostConstruct + public void initDeleteLogsJob() { + JobModel jobModel = new JobModel(); + jobModel.setJobName("delete-logs-job"); + jobModel.setCron("0 0 0 * * ?"); + jobModel.setDescription("定时删除三个月前日志"); + jobModel.setSpringBeanName("sysLogServiceImpl"); + jobModel.setMethodName("deleteLogs"); + jobModel.setIsSysJob(true); + + jobService.saveJob(jobModel); } } diff --git a/src/main/java/com/zw/admin/server/config/SwaggerConfig.java b/src/main/java/com/zw/admin/server/config/SwaggerConfig.java index 295ab18..c8c5a06 100644 --- a/src/main/java/com/zw/admin/server/config/SwaggerConfig.java +++ b/src/main/java/com/zw/admin/server/config/SwaggerConfig.java @@ -60,6 +60,11 @@ public class SwaggerConfig { public Docket mailsDocket() { return docket("邮件", "/mails.*"); } + + @Bean("jobsDocket") + public Docket jobsDocket() { + return docket("定时任务", "/jobs.*"); + } private Docket docket(String title, String path) { Docket docket = new Docket(DocumentationType.SWAGGER_2) diff --git a/src/main/java/com/zw/admin/server/controller/JobController.java b/src/main/java/com/zw/admin/server/controller/JobController.java new file mode 100644 index 0000000..26b9d20 --- /dev/null +++ b/src/main/java/com/zw/admin/server/controller/JobController.java @@ -0,0 +1,163 @@ +package com.zw.admin.server.controller; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.quartz.CronExpression; +import org.quartz.SchedulerException; +import org.springframework.aop.support.AopUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.zw.admin.server.annotation.LogAnnotation; +import com.zw.admin.server.dao.JobDao; +import com.zw.admin.server.model.JobModel; +import com.zw.admin.server.page.table.PageTableHandler; +import com.zw.admin.server.page.table.PageTableHandler.CountHandler; +import com.zw.admin.server.page.table.PageTableHandler.ListHandler; +import com.zw.admin.server.page.table.PageTableRequest; +import com.zw.admin.server.page.table.PageTableResponse; +import com.zw.admin.server.service.JobService; + +import io.swagger.annotations.ApiOperation; + +@RestController +@RequestMapping("/jobs") +public class JobController { + + @Autowired + private JobService jobService; + @Autowired + private JobDao jobDao; + + @LogAnnotation + @ApiOperation("添加定时任务") + @PostMapping + @RequiresPermissions("job:add") + public void add(@RequestBody JobModel jobModel) { + JobModel model = jobDao.getByName(jobModel.getJobName()); + if (model != null) { + throw new IllegalArgumentException(jobModel.getJobName() + "已存在"); + } + + jobModel.setIsSysJob(false); + jobService.saveJob(jobModel); + } + + @LogAnnotation + @ApiOperation("修改定时任务") + @PutMapping + @RequiresPermissions("job:add") + public void update(@RequestBody JobModel jobModel) { + jobModel.setStatus(1); + jobService.saveJob(jobModel); + } + + @LogAnnotation + @ApiOperation("删除定时任务") + @DeleteMapping("/{id}") + @RequiresPermissions("job:del") + public void delete(@PathVariable Long id) throws SchedulerException { + jobService.deleteJob(id); + } + + @ApiOperation("根据id获取定时任务") + @GetMapping("/{id}") + @RequiresPermissions("job:query") + public JobModel getById(@PathVariable Long id) { + return jobDao.getById(id); + } + + @GetMapping + @ApiOperation(value = "定时任务列表") + @RequiresPermissions("job:query") + public PageTableResponse list(PageTableRequest request) { + return PageTableHandler. builder().countHandler(new CountHandler() { + + @Override + public int count(PageTableRequest request) { + return jobDao.count(request.getParams()); + } + }).listHandler(new ListHandler() { + + @Override + public List list(PageTableRequest request) { + List list = jobDao.list(request.getParams(), request.getOffset(), request.getLimit()); + return list; + } + }).build().handle(request); + } + + @ApiOperation(value = "校验cron表达式") + @GetMapping(params = "cron") + public boolean checkCron(String cron) { + return CronExpression.isValidExpression(cron); + } + + @Autowired + private ApplicationContext applicationContext; + + @ApiOperation(value = "springBean名字") + @GetMapping("/beans") + public List listAllBeanName() { + String[] strings = applicationContext.getBeanDefinitionNames(); + List list = new ArrayList<>(); + for (String str : strings) { + if (str.contains(".")) { + continue; + } + + Class clazz = getClass(str); + if (clazz.isAssignableFrom(Controller.class) || clazz.isAnnotationPresent(RestController.class)) { + continue; + } + + list.add(str); + } + list.sort((l1, l2) -> l1.compareTo(l2)); + + return list; + } + + @ApiOperation(value = "springBean的无参方法") + @GetMapping("/beans/{name}") + public Set listMethodName(@PathVariable String name) { + Class clazz = getClass(name); + Method[] methods = clazz.getDeclaredMethods(); + + Set names = new HashSet<>(); + Arrays.asList(methods).parallelStream().forEach(m -> { + Class[] classes = m.getParameterTypes(); + if (classes.length == 0) { + names.add(m.getName()); + } + }); + + return names; + } + + private Class getClass(String name) { + Object object = applicationContext.getBean(name); + Class clazz = object.getClass(); + if (AopUtils.isAopProxy(object)) { + clazz = clazz.getSuperclass(); + } + + return clazz; + } + +} diff --git a/src/main/java/com/zw/admin/server/dao/JobDao.java b/src/main/java/com/zw/admin/server/dao/JobDao.java new file mode 100644 index 0000000..a47deeb --- /dev/null +++ b/src/main/java/com/zw/admin/server/dao/JobDao.java @@ -0,0 +1,33 @@ +package com.zw.admin.server.dao; + +import java.util.List; +import java.util.Map; + +import org.apache.ibatis.annotations.Insert; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Options; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; + +import com.zw.admin.server.model.JobModel; + +@Mapper +public interface JobDao { + + @Options(useGeneratedKeys = true, keyProperty = "id") + @Insert("insert into t_job(jobName, description, cron, springBeanName, methodName, isSysJob, status, createTime, updateTime) values(#{jobName}, #{description}, #{cron}, #{springBeanName}, #{methodName}, #{isSysJob}, 1, now(), now())") + int save(JobModel jobModel); + + @Select("select * from t_job t where t.id = #{id}") + JobModel getById(Long id); + + @Select("select * from t_job t where t.jobName = #{jobName}") + JobModel getByName(String jobName); + + int update(JobModel jobModel); + + int count(@Param("params") Map params); + + List list(@Param("params") Map params, @Param("offset") Integer offset, + @Param("limit") Integer limit); +} diff --git a/src/main/java/com/zw/admin/server/job/DeleteLogJob.java b/src/main/java/com/zw/admin/server/job/SpringBeanJob.java similarity index 70% rename from src/main/java/com/zw/admin/server/job/DeleteLogJob.java rename to src/main/java/com/zw/admin/server/job/SpringBeanJob.java index e74be14..4e22780 100644 --- a/src/main/java/com/zw/admin/server/job/DeleteLogJob.java +++ b/src/main/java/com/zw/admin/server/job/SpringBeanJob.java @@ -7,21 +7,20 @@ import org.springframework.context.ApplicationContext; import org.springframework.scheduling.quartz.QuartzJobBean; import com.zw.admin.server.config.JobConfig; -import com.zw.admin.server.service.SysLogService; +import com.zw.admin.server.service.JobService; -public class DeleteLogJob extends QuartzJobBean { +public class SpringBeanJob extends QuartzJobBean { @Override protected void executeInternal(JobExecutionContext context) throws JobExecutionException { try { ApplicationContext applicationContext = (ApplicationContext) context.getScheduler().getContext() .get(JobConfig.KEY); - SysLogService service = applicationContext.getBean(SysLogService.class); - service.deleteLogs(); + JobService jobService = applicationContext.getBean(JobService.class); + jobService.doJob(context.getJobDetail().getJobDataMap()); } catch (SchedulerException e) { e.printStackTrace(); } - } } diff --git a/src/main/java/com/zw/admin/server/model/JobModel.java b/src/main/java/com/zw/admin/server/model/JobModel.java new file mode 100644 index 0000000..66acee4 --- /dev/null +++ b/src/main/java/com/zw/admin/server/model/JobModel.java @@ -0,0 +1,26 @@ +package com.zw.admin.server.model; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class JobModel extends BaseEntity { + + private static final long serialVersionUID = -2458935535811207209L; + + private String jobName; + + private String description; + + private String cron; + + private String springBeanName; + + private String methodName; + + private Boolean isSysJob; + + private int status; + +} diff --git a/src/main/java/com/zw/admin/server/page/table/PageTableArgumentResolver.java b/src/main/java/com/zw/admin/server/page/table/PageTableArgumentResolver.java index 269cf43..830f0a6 100644 --- a/src/main/java/com/zw/admin/server/page/table/PageTableArgumentResolver.java +++ b/src/main/java/com/zw/admin/server/page/table/PageTableArgumentResolver.java @@ -5,6 +5,7 @@ import java.util.Map; import javax.servlet.http.HttpServletRequest; +import org.apache.commons.lang3.StringUtils; import org.springframework.core.MethodParameter; import org.springframework.web.bind.support.WebDataBinderFactory; import org.springframework.web.context.request.NativeWebRequest; @@ -35,13 +36,12 @@ public class PageTableArgumentResolver implements HandlerMethodArgumentResolver PageTableRequest tableRequest = new PageTableRequest(); Map param = request.getParameterMap(); - - if (param.containsKey("limit")) { - tableRequest.setLimit(Integer.parseInt(request.getParameter("limit"))); + if (param.containsKey("start")) { + tableRequest.setOffset(Integer.parseInt(request.getParameter("start"))); } - if (param.containsKey("page")) { - int page = Integer.parseInt(request.getParameter("page")); - tableRequest.setOffset((page - 1) * tableRequest.getLimit()); + + if (param.containsKey("length")) { + tableRequest.setLimit(Integer.parseInt(request.getParameter("length"))); } Map map = Maps.newHashMap(); @@ -55,11 +55,32 @@ public class PageTableArgumentResolver implements HandlerMethodArgumentResolver } }); - if (map.containsKey("orderBy")) { - map.put("orderBy", " order by " + map.get("orderBy")); - } + setOrderBy(tableRequest, map); return tableRequest; } + private void setOrderBy(PageTableRequest tableRequest, Map map) { + StringBuilder orderBy = new StringBuilder(); + int size = map.size(); + for (int i = 0; i < size; i++) { + String index = (String) map.get("order[" + i + "][column]"); + if (StringUtils.isEmpty(index)) { + break; + } + String column = (String) map.get("columns[" + index + "][data]"); + if (StringUtils.isBlank(column)) { + continue; + } + String sort = (String) map.get("order[" + i + "][dir]"); + + orderBy.append(column).append(" ").append(sort).append(", "); + } + + if (orderBy.length() > 0) { + tableRequest.getParams().put("orderBy", + " order by " + StringUtils.substringBeforeLast(orderBy.toString(), ",")); + } + } + } diff --git a/src/main/java/com/zw/admin/server/page/table/PageTableHandler.java b/src/main/java/com/zw/admin/server/page/table/PageTableHandler.java index a462aa6..0d05e70 100644 --- a/src/main/java/com/zw/admin/server/page/table/PageTableHandler.java +++ b/src/main/java/com/zw/admin/server/page/table/PageTableHandler.java @@ -13,6 +13,7 @@ import lombok.Builder; */ @Builder public class PageTableHandler { + private CountHandler countHandler; private ListHandler listHandler; @@ -29,7 +30,7 @@ public class PageTableHandler { list = new ArrayList(); } - return PageTableResponse. builder().count(count).code(0).data(list).build(); + return PageTableResponse. builder().recordsTotal(count).recordsFiltered(count).data(list).build(); } public interface ListHandler { diff --git a/src/main/java/com/zw/admin/server/page/table/PageTableResponse.java b/src/main/java/com/zw/admin/server/page/table/PageTableResponse.java index 592241f..671892d 100644 --- a/src/main/java/com/zw/admin/server/page/table/PageTableResponse.java +++ b/src/main/java/com/zw/admin/server/page/table/PageTableResponse.java @@ -20,8 +20,8 @@ public class PageTableResponse implements Serializable { private static final long serialVersionUID = 620421858510718076L; - private Integer code; - private Integer count; + private Integer recordsTotal; + private Integer recordsFiltered; private List data; } \ No newline at end of file diff --git a/src/main/java/com/zw/admin/server/service/JobService.java b/src/main/java/com/zw/admin/server/service/JobService.java new file mode 100644 index 0000000..b3d55bb --- /dev/null +++ b/src/main/java/com/zw/admin/server/service/JobService.java @@ -0,0 +1,15 @@ +package com.zw.admin.server.service; + +import org.quartz.JobDataMap; +import org.quartz.SchedulerException; + +import com.zw.admin.server.model.JobModel; + +public interface JobService { + + void saveJob(JobModel jobModel); + + void doJob(JobDataMap jobDataMap); + + void deleteJob(Long id) throws SchedulerException; +} diff --git a/src/main/java/com/zw/admin/server/service/impl/JobServiceImpl.java b/src/main/java/com/zw/admin/server/service/impl/JobServiceImpl.java new file mode 100644 index 0000000..0c586be --- /dev/null +++ b/src/main/java/com/zw/admin/server/service/impl/JobServiceImpl.java @@ -0,0 +1,151 @@ +package com.zw.admin.server.service.impl; + +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +import org.quartz.CronScheduleBuilder; +import org.quartz.CronTrigger; +import org.quartz.JobBuilder; +import org.quartz.JobDataMap; +import org.quartz.JobDetail; +import org.quartz.JobKey; +import org.quartz.Scheduler; +import org.quartz.SchedulerException; +import org.quartz.TriggerBuilder; +import org.quartz.TriggerKey; +import org.springframework.aop.support.AopUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.stereotype.Service; + +import com.zw.admin.server.dao.JobDao; +import com.zw.admin.server.job.SpringBeanJob; +import com.zw.admin.server.model.JobModel; +import com.zw.admin.server.service.JobService; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j(topic = "adminLogger") +@Service +public class JobServiceImpl implements JobService { + + @Autowired + private Scheduler scheduler; + @Autowired + private ApplicationContext applicationContext; + private static final String JOB_DATA_KEY = "JOB_DATA_KEY"; + @Autowired + private JobDao jobDao; + + @Override + public void saveJob(JobModel jobModel) { + checkJobModel(jobModel); + String name = jobModel.getJobName(); + + JobKey jobKey = JobKey.jobKey(name); + JobDetail jobDetail = JobBuilder.newJob(SpringBeanJob.class).storeDurably() + .withDescription(jobModel.getDescription()).withIdentity(jobKey).build(); + + jobDetail.getJobDataMap().put(JOB_DATA_KEY, jobModel); + + CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(jobModel.getCron()); + CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(name).withSchedule(cronScheduleBuilder) + .forJob(jobKey).build(); + + try { + boolean exists = scheduler.checkExists(jobKey); + if (exists) { + scheduler.rescheduleJob(new TriggerKey(name), cronTrigger); + scheduler.addJob(jobDetail, true); + } else { + scheduler.scheduleJob(jobDetail, cronTrigger); + } + + JobModel model = jobDao.getByName(name); + if (model == null) { + jobDao.save(jobModel); + } else { + jobDao.update(jobModel); + } + } catch (SchedulerException e) { + log.error("新增或修改job异常", e); + } + } + + private void checkJobModel(JobModel jobModel) { + String springBeanName = jobModel.getSpringBeanName(); + boolean flag = applicationContext.containsBean(springBeanName); + if (!flag) { + throw new IllegalArgumentException("bean:" + springBeanName + "不存在,bean名如userServiceImpl,首字母小写"); + } + + Object object = applicationContext.getBean(springBeanName); + Class clazz = object.getClass(); + if (AopUtils.isAopProxy(object)) { + clazz = clazz.getSuperclass(); + } + + String methodName = jobModel.getMethodName(); + Method[] methods = clazz.getDeclaredMethods(); + + Set names = new HashSet<>(); + Arrays.asList(methods).parallelStream().forEach(m -> { + Class[] classes = m.getParameterTypes(); + if (classes.length == 0) { + names.add(m.getName()); + } + }); + + if (names.size() == 0) { + throw new IllegalArgumentException("该bean没有无参方法"); + } + + if (!names.contains(methodName)) { + throw new IllegalArgumentException("未找到无参方法" + methodName + ",该bean所有方法名为:" + names); + } + } + + @Override + public void doJob(JobDataMap jobDataMap) { + JobModel jobModel = (JobModel) jobDataMap.get(JOB_DATA_KEY); + + String beanName = jobModel.getSpringBeanName(); + String methodName = jobModel.getMethodName(); + Object object = applicationContext.getBean(beanName); + + try { + log.info("job:bean:{},方法名:{}", beanName, methodName); + Method method = object.getClass().getDeclaredMethod(methodName); + method.invoke(object); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 删除job + * + * @throws SchedulerException + */ + @Override + public void deleteJob(Long id) throws SchedulerException { + JobModel jobModel = jobDao.getById(id); + + if (jobModel.getIsSysJob() != null && jobModel.getIsSysJob()) { + throw new IllegalArgumentException("该job是系统任务,不能删除,因为此job是在代码里初始化的,删除该类job请先确保相关代码已经去除"); + } + + String jobName = jobModel.getJobName(); + JobKey jobKey = JobKey.jobKey(jobName); + + scheduler.pauseJob(jobKey); + scheduler.unscheduleJob(new TriggerKey(jobName)); + scheduler.deleteJob(jobKey); + + jobModel.setStatus(0); + jobDao.update(jobModel); + } + +} diff --git a/src/main/resources/mybatis-mappers/JobMapper.xml b/src/main/resources/mybatis-mappers/JobMapper.xml new file mode 100644 index 0000000..345f5b7 --- /dev/null +++ b/src/main/resources/mybatis-mappers/JobMapper.xml @@ -0,0 +1,52 @@ + + + + + + + + and t.description like concat('%', #{params.description}, '%') + + + and t.status = #{params.status} + + + + + + + + + + + update t_job t + + + description = #{description}, + + + cron = #{cron}, + + + springBeanName = #{springBeanName}, + + + methodName = #{methodName}, + + + status = #{status}, + + updateTime = now() + + where t.jobName = #{jobName} + + \ No newline at end of file diff --git a/src/main/resources/public/pages/article/articleList.html b/src/main/resources/public/pages/article/articleList.html index 5688ce2..b3ff3ef 100644 --- a/src/main/resources/public/pages/article/articleList.html +++ b/src/main/resources/public/pages/article/articleList.html @@ -3,6 +3,8 @@ Insert title here + + @@ -13,32 +15,23 @@
-
- - - - - - - - -
- - - - - - - - - -
- + +
+ title: + + 时间: + + + 状态: + + +
+
+ + +
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+ +
+
+
+ + +
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/public/pages/job/jobList.html b/src/main/resources/public/pages/job/jobList.html new file mode 100644 index 0000000..0388f64 --- /dev/null +++ b/src/main/resources/public/pages/job/jobList.html @@ -0,0 +1,172 @@ + + + + +Insert title here + + + + + +
+
+
+
+ + + + + +
+
+
+ 描述: + + + +
+
+
+ +
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
idjob名cron表达式bean名方法名描述状态修改时间操作
+
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/public/pages/job/updateJob.html b/src/main/resources/public/pages/job/updateJob.html new file mode 100644 index 0000000..e031244 --- /dev/null +++ b/src/main/resources/public/pages/job/updateJob.html @@ -0,0 +1,120 @@ + + + + + + +
+
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+ +
+
+
+ + +
+
+
+ +
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/public/pages/log/logList.html b/src/main/resources/public/pages/log/logList.html index 367273c..d64804d 100644 --- a/src/main/resources/public/pages/log/logList.html +++ b/src/main/resources/public/pages/log/logList.html @@ -3,6 +3,8 @@ Insert title here + + @@ -14,31 +16,21 @@ @@ -48,10 +40,24 @@
-
-
- - - - - - - - -
- - - - - - - - - -
- + +
+ 昵称: + + 时间: + + + 状态: + + +
- + + + + + + + + + + + + + + + +
id昵称模块状态备注时间
+ - @@ -61,59 +67,11 @@ + + - - \ No newline at end of file diff --git a/src/main/resources/public/pages/mail/mailList.html b/src/main/resources/public/pages/mail/mailList.html index e98b052..cae067a 100644 --- a/src/main/resources/public/pages/mail/mailList.html +++ b/src/main/resources/public/pages/mail/mailList.html @@ -3,6 +3,8 @@ Insert title here + + @@ -14,22 +16,14 @@
- - - - - - - -
- - - - - - - -
+
+ 标题: + + 时间: + + + +
@@ -44,8 +38,22 @@
-
-
+ + + + + + + + + + + + + + +
id标题内容时间操作
+
@@ -55,45 +63,13 @@ + + - \ No newline at end of file +init(); + \ No newline at end of file diff --git a/src/main/resources/public/pages/role/roleList.html b/src/main/resources/public/pages/role/roleList.html index d26e161..b894465 100644 --- a/src/main/resources/public/pages/role/roleList.html +++ b/src/main/resources/public/pages/role/roleList.html @@ -3,6 +3,8 @@ Insert title here + + @@ -16,10 +18,7 @@
角色: -
- -
- +
@@ -36,65 +35,78 @@
-
-
+ + + + + + + + + + + + + +
角色描述修改时间操作
+
- + + - \ No newline at end of file +init(); + \ No newline at end of file diff --git a/src/main/resources/public/pages/user/userList.html b/src/main/resources/public/pages/user/userList.html index 1fc3d78..5981ac1 100644 --- a/src/main/resources/public/pages/user/userList.html +++ b/src/main/resources/public/pages/user/userList.html @@ -3,6 +3,8 @@ Insert title here + + @@ -13,29 +15,21 @@
-
- - - - - - - -
- - - - - - - -
- + +
+ 用户名: + + 昵称: + + 状态: + + +
@@ -50,8 +44,23 @@
-
-
+ + + + + + + + + + + + + + + +
username昵称手机号邮箱状态操作
+
@@ -60,69 +69,75 @@ - + + - - \ No newline at end of file +init(); + \ No newline at end of file diff --git a/src/main/resources/static/js/my/job.js b/src/main/resources/static/js/my/job.js new file mode 100644 index 0000000..4f6e6d7 --- /dev/null +++ b/src/main/resources/static/js/my/job.js @@ -0,0 +1,72 @@ +function checkCron() { + var cron = $("#cron").val(); + if (cron != "") { + $.ajax({ + type : 'get', + url : '/jobs?cron=' + cron, + success : function(data) { + var msg = "正确"; + if (!data) { + msg = "cron表达式不对"; + } + layer.msg(msg, { + shift : -1, + time : 1000 + }, function() { + }); + } + }); + } else { + layer.msg("cron表达式不能为空", { + shift : -1, + time : 1000 + }, function() { + }); + } +} + +function initBeanNames() { + $.ajax({ + type : 'get', + url : '/jobs/beans', + async : false, + success : function(data) { + var select = $("#springBeanName"); + for (var i = 0; i < data.length; i++) { + var v = data[i]; + select.append("") + } + } + }); +} + +function showMethods() { + var val = $("#springBeanName").val(); + if (val == "") { + return; + } + + $.ajax({ + type : 'get', + url : '/jobs/beans/' + val, + async : false, + success : function(data) { + var select = $("#methodName"); + select.empty(); + if (data.length == 0) { + layer.msg(val + "没有无参方法", { + shift : -1, + time : 1000 + }, function() { + }); + + return; + } + + for (var i = 0; i < data.length; i++) { + var v = data[i]; + select.append("") + } + } + }); +} \ No newline at end of file -- Gitee