mirror of
https://github.com/dqjdda/Aurora.git
synced 2018-11-06 05:33:29 +00:00
新增任务调度,调度日志,Aurora v1.1发布
This commit is contained in:
@@ -12,6 +12,6 @@ ADD *.war app.war
|
||||
RUN bash -c 'touch /app.jar'
|
||||
|
||||
#指定映射端口
|
||||
EXPOSE 8080
|
||||
EXPOSE 80
|
||||
|
||||
CMD ["java","-jar","app.war"]
|
||||
2
LICENSE
2
LICENSE
@@ -176,7 +176,7 @@ recommend that a file or class name and description of purpose be included on
|
||||
the same "printed page" as the copyright notice for easier identification within
|
||||
third-party archives.
|
||||
|
||||
Copyright 2018 郑杰
|
||||
Copyright 2018 ZhengJie
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
10
README.MD
10
README.MD
@@ -1,4 +1,4 @@
|
||||
### Aurora 1.0
|
||||
### Aurora
|
||||

|
||||

|
||||

|
||||
@@ -40,10 +40,8 @@ Aurora是一个简单高效的后台管理系统。项目基础框架采用全
|
||||
│ │-支付宝支付
|
||||
│ │-七牛云储存
|
||||
│ │-SM.MS图床
|
||||
│ │-百度富文本编辑器
|
||||
│ │-微信支付(开发中)
|
||||
│ └─阿里大鱼(开发中)
|
||||
└─任务调度(开发中)
|
||||
│ └─百度富文本编辑器
|
||||
└─任务调度
|
||||
├─定时任务
|
||||
└─调度日志
|
||||
```
|
||||
@@ -72,6 +70,8 @@ Aurora是一个简单高效的后台管理系统。项目基础框架采用全
|
||||
|
||||
- 工具包:hutool-all
|
||||
|
||||
- 任务调度:quartz
|
||||
|
||||
- 其他:fastjson,aop,MapStruct等。
|
||||
|
||||
#### 前端
|
||||
|
||||
2
mvnw
vendored
2
mvnw
vendored
@@ -7,9 +7,7 @@
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
|
||||
1
mvnw.cmd
vendored
1
mvnw.cmd
vendored
@@ -56,7 +56,6 @@ set ERROR_CODE=0
|
||||
|
||||
@REM ==== START VALIDATION ====
|
||||
if not "%JAVA_HOME%" == "" goto OkJHome
|
||||
|
||||
echo.
|
||||
echo Error: JAVA_HOME not found in your environment. >&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||
|
||||
6
pom.xml
6
pom.xml
@@ -159,6 +159,12 @@
|
||||
<version>4.1.8</version>
|
||||
</dependency>
|
||||
|
||||
<!-- quartz -->
|
||||
<dependency>
|
||||
<groupId>org.quartz-scheduler</groupId>
|
||||
<artifactId>quartz</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!--七牛云存储-->
|
||||
<dependency>
|
||||
<groupId>com.qiniu</groupId>
|
||||
|
||||
141
src/main/java/me/aurora/app/rest/job/JobController.java
Normal file
141
src/main/java/me/aurora/app/rest/job/JobController.java
Normal file
@@ -0,0 +1,141 @@
|
||||
package me.aurora.app.rest.job;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.HttpStatus;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.aurora.annotation.Log;
|
||||
import me.aurora.domain.ResponseEntity;
|
||||
import me.aurora.domain.job.Job;
|
||||
import me.aurora.repository.spec.JobSpce;
|
||||
import me.aurora.service.JobService;
|
||||
import me.aurora.util.HttpContextUtils;
|
||||
import org.apache.shiro.authz.annotation.Logical;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author 郑杰
|
||||
* @date 2018/10/05 19:12:24
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("job")
|
||||
public class JobController {
|
||||
|
||||
@Autowired
|
||||
private JobService jobService;
|
||||
|
||||
/**
|
||||
* 跳转到列表页面
|
||||
* @return
|
||||
*/
|
||||
@GetMapping(value = "/index")
|
||||
public ModelAndView index(){
|
||||
return new ModelAndView("/job/index");
|
||||
}
|
||||
|
||||
@Log("查询所有任务")
|
||||
@RequiresPermissions(value={"admin", "job:all","job:select"}, logical= Logical.OR)
|
||||
@GetMapping(value = "/getJobsInfo")
|
||||
public Map getJobsInfo(@RequestParam(value = "beanName",required = false) String beanName,
|
||||
@RequestParam(value = "methodName",required = false) String methodName,
|
||||
@RequestParam(value = "remark",required = false) String remark,
|
||||
@RequestParam(value = "status",required = false) String status,
|
||||
@RequestParam(value = "page",defaultValue = "1")Integer page,
|
||||
@RequestParam(value = "limit",defaultValue = "10")Integer limit){
|
||||
Sort sort = new Sort(Sort.Direction.ASC,"id");
|
||||
Pageable pageable = PageRequest.of(page-1,limit,sort);
|
||||
return jobService.getJobsInfo(new JobSpce(beanName,methodName,remark,status),pageable);
|
||||
}
|
||||
|
||||
/**
|
||||
* 去新增页面
|
||||
* @return
|
||||
*/
|
||||
@RequiresPermissions (value={"admin", "job:all","job:add"}, logical= Logical.OR)
|
||||
@GetMapping(value = "/toAddPage")
|
||||
public ModelAndView toAddPage(){
|
||||
return new ModelAndView("/job/add");
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增
|
||||
* @param job
|
||||
* @return
|
||||
*/
|
||||
@Log("新增任务")
|
||||
@RequiresPermissions (value={"admin", "job:all","job:add"}, logical= Logical.OR)
|
||||
@PostMapping(value = "/insert")
|
||||
public ResponseEntity insert(@Validated(Job.New.class) @RequestBody Job job){
|
||||
log.warn("REST request to insert Job : {}"+job);
|
||||
jobService.insert(job);
|
||||
return ResponseEntity.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新状态
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@Log("更新任务状态")
|
||||
@RequiresPermissions (value={"admin", "job:all","job:status"}, logical= Logical.OR)
|
||||
@PutMapping(value = "/updateStatus")
|
||||
public ResponseEntity updateStatus(@RequestParam Long id){
|
||||
log.warn("REST request to updateStatus Job : {}" +id);
|
||||
jobService.updateStatus(jobService.findById(id));
|
||||
return ResponseEntity.ok();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 去编辑页面
|
||||
* @return
|
||||
*/
|
||||
@RequiresPermissions (value={"admin", "job:all","job:update"}, logical= Logical.OR)
|
||||
@GetMapping(value = "/toUpdatePage")
|
||||
public ModelAndView toUpdatePage(@RequestParam Long id){
|
||||
Job job = jobService.findById(id);
|
||||
// 获取request
|
||||
HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
|
||||
request.setAttribute("job", job);
|
||||
return new ModelAndView("/job/update");
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新任务
|
||||
* @param job
|
||||
* @return
|
||||
*/
|
||||
@Log("更新任务")
|
||||
@RequiresPermissions (value={"admin", "job:all","job:update"}, logical= Logical.OR)
|
||||
@PutMapping(value = "/update")
|
||||
public ResponseEntity update(@Validated(Job.Update.class) @RequestBody Job job) {
|
||||
log.warn("REST request to update Job : {}" +job);
|
||||
jobService.update(jobService.findById(job.getId()),job);
|
||||
return ResponseEntity.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除任务
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@Log("删除任务")
|
||||
@RequiresPermissions (value={"admin", "job:all","job:delete"}, logical= Logical.OR)
|
||||
@DeleteMapping(value = "/delete")
|
||||
public ResponseEntity delete(@RequestParam Long id) {
|
||||
log.warn("REST request to delete Job : {}" +id);
|
||||
jobService.delete(jobService.findById(id));
|
||||
return ResponseEntity.ok();
|
||||
}
|
||||
|
||||
}
|
||||
51
src/main/java/me/aurora/app/rest/job/JobLogController.java
Normal file
51
src/main/java/me/aurora/app/rest/job/JobLogController.java
Normal file
@@ -0,0 +1,51 @@
|
||||
package me.aurora.app.rest.job;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.aurora.annotation.Log;
|
||||
import me.aurora.repository.spec.JobLogSpce;
|
||||
import me.aurora.service.JobLogService;
|
||||
import org.apache.shiro.authz.annotation.Logical;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author 郑杰
|
||||
* @date 2018/10/06 11:40:21
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("jobLog")
|
||||
public class JobLogController {
|
||||
|
||||
@Autowired
|
||||
private JobLogService jobLogService;
|
||||
|
||||
/**
|
||||
* 跳转到列表页面
|
||||
* @return
|
||||
*/
|
||||
@GetMapping(value = "/index")
|
||||
public ModelAndView index(){
|
||||
return new ModelAndView("/job/log");
|
||||
}
|
||||
|
||||
@Log("查询所有任务日志")
|
||||
@RequiresPermissions(value={"admin", "job:all","job:log"}, logical= Logical.OR)
|
||||
@GetMapping(value = "/getJobLogsInfo")
|
||||
public Map getJobLogsInfo(@RequestParam(value = "beanName",required = false) String beanName,
|
||||
@RequestParam(value = "methodName",required = false) String methodName,
|
||||
@RequestParam(value = "remark",required = false) String remark,
|
||||
@RequestParam(value = "status",required = false) String status,
|
||||
@RequestParam(value = "page",defaultValue = "1")Integer page,
|
||||
@RequestParam(value = "limit",defaultValue = "10")Integer limit){
|
||||
Sort sort = new Sort(Sort.Direction.DESC,"id");
|
||||
Pageable pageable = PageRequest.of(page-1,limit,sort);
|
||||
return jobLogService.getJobLogsInfo(new JobLogSpce(beanName,methodName,remark,status),pageable);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package me.aurora.config;
|
||||
|
||||
import lombok.Data;
|
||||
import me.aurora.config.scheduled.db.DBProperties;
|
||||
import me.aurora.config.shiro.ShiroProperties;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -18,8 +17,6 @@ public class AuroraProperties {
|
||||
|
||||
private ShiroProperties shiro = new ShiroProperties();
|
||||
|
||||
private DBProperties db = new DBProperties();
|
||||
|
||||
private Boolean openAopLog;
|
||||
|
||||
private String userAvatar;
|
||||
|
||||
41
src/main/java/me/aurora/config/job/MyJobRunner.java
Normal file
41
src/main/java/me/aurora/config/job/MyJobRunner.java
Normal file
@@ -0,0 +1,41 @@
|
||||
package me.aurora.config.job;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.aurora.domain.job.Job;
|
||||
import me.aurora.repository.JobRepo;
|
||||
import me.aurora.util.job.ScheduleUtils;
|
||||
import org.quartz.Scheduler;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.ApplicationArguments;
|
||||
import org.springframework.boot.ApplicationRunner;
|
||||
import org.springframework.stereotype.Component;
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author 郑杰
|
||||
* @date 2018/10/06 11:09:35
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class MyJobRunner implements ApplicationRunner {
|
||||
|
||||
@Autowired
|
||||
private JobRepo jobRepo;
|
||||
|
||||
@Resource(name = "scheduler")
|
||||
private Scheduler scheduler;
|
||||
|
||||
/**
|
||||
* 项目启动时重新激活启用的定时任务
|
||||
* @param applicationArguments
|
||||
* @throws Exception
|
||||
*/
|
||||
@Override
|
||||
public void run(ApplicationArguments applicationArguments){
|
||||
List<Job> jobs = jobRepo.findAll();
|
||||
jobs.forEach(scheduleJob -> {
|
||||
ScheduleUtils.createScheduleJob(scheduler, scheduleJob);
|
||||
});
|
||||
}
|
||||
}
|
||||
58
src/main/java/me/aurora/config/job/ScheduleConfig.java
Normal file
58
src/main/java/me/aurora/config/job/ScheduleConfig.java
Normal file
@@ -0,0 +1,58 @@
|
||||
package me.aurora.config.job;
|
||||
|
||||
import org.quartz.Scheduler;
|
||||
import org.quartz.spi.TriggerFiredBundle;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.quartz.AdaptableJobFactory;
|
||||
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 定时任务配置
|
||||
* @author 郑杰
|
||||
*/
|
||||
@Configuration
|
||||
public class ScheduleConfig {
|
||||
|
||||
/**
|
||||
* 解决Job中注入Spring Bean为null的问题
|
||||
*/
|
||||
@Component("quartzJobFactory")
|
||||
public class QuartzJobFactory extends AdaptableJobFactory {
|
||||
|
||||
/**
|
||||
* 这个对象Spring会帮我们自动注入进来,也属于Spring技术范畴.
|
||||
*/
|
||||
@Autowired
|
||||
private AutowireCapableBeanFactory capableBeanFactory;
|
||||
|
||||
@Override
|
||||
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
|
||||
//调用父类的方法
|
||||
Object jobInstance = super.createJobInstance(bundle);
|
||||
//进行注入,这属于Spring的技术,不清楚的可以查看Spring的API.
|
||||
capableBeanFactory.autowireBean(jobInstance);
|
||||
return jobInstance;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 注入scheduler到spring,在下面quartzManege会用到
|
||||
* @param quartzJobFactory
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
@Bean(name = "scheduler")
|
||||
public Scheduler scheduler(QuartzJobFactory quartzJobFactory) throws Exception {
|
||||
|
||||
SchedulerFactoryBean factoryBean=new SchedulerFactoryBean();
|
||||
factoryBean.setJobFactory(quartzJobFactory);
|
||||
factoryBean.afterPropertiesSet();
|
||||
Scheduler scheduler=factoryBean.getScheduler();
|
||||
scheduler.start();
|
||||
return scheduler;
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
package me.aurora.config.scheduled.db;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author 郑杰
|
||||
* @date 2018/09/16 13:59:01
|
||||
*/
|
||||
@Data
|
||||
public class DBProperties {
|
||||
|
||||
private String username;
|
||||
|
||||
private String password;
|
||||
|
||||
private String dbName;
|
||||
|
||||
private String path;
|
||||
|
||||
private String linuxDbPath;
|
||||
|
||||
private String pathName;
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
package me.aurora.config.scheduled.db;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.aurora.config.AuroraProperties;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
|
||||
/**
|
||||
* @author 郑杰
|
||||
* @date 2018/09/18 11:28:39
|
||||
* 还原数据库
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class DBRecover {
|
||||
|
||||
@Autowired
|
||||
private AuroraProperties auroraProperties;
|
||||
|
||||
/**
|
||||
* 还原数据库
|
||||
* @Scheduled(cron = "0 0 1 * * ?")
|
||||
* @Scheduled(cron = "0/5 * * * * ?")
|
||||
*/
|
||||
public void recover(){
|
||||
log.warn("=====>>>>>定时恢复数据库");
|
||||
String path = "";
|
||||
String userName = auroraProperties.getDb().getUsername();
|
||||
String password = auroraProperties.getDb().getPassword();
|
||||
String database = auroraProperties.getDb().getDbName();
|
||||
try {
|
||||
InputStream file = new ClassPathResource(auroraProperties.getDb().getPath()).getInputStream();
|
||||
path = auroraProperties.getDb().getLinuxDbPath()+auroraProperties.getDb().getPathName();
|
||||
Path dBPaht = Paths.get(path);
|
||||
/**
|
||||
* 将本地的sql复制到linux
|
||||
*/
|
||||
Files.copy(file, dBPaht, StandardCopyOption.REPLACE_EXISTING);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
String[] cmd=new String[]{"/bin/sh ","-c ","/usr/bin/mysqldump -u"+userName+" -p"+password+" "+database+ " < " + path};
|
||||
try {
|
||||
Process p = Runtime.getRuntime().exec(cmd);
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
|
||||
// 0 表示线程正常终止。
|
||||
if (p.waitFor() == 0) {
|
||||
System.out.println("数据库恢复成功!");
|
||||
} else {
|
||||
System.out.println("数据库恢复失败!");
|
||||
}
|
||||
} catch (Exception e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package me.aurora.config.scheduled.task;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author 郑杰
|
||||
* @date 2018/10/06 10:03:43
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class MyTaskTest {
|
||||
|
||||
public void test(String params) {
|
||||
log.info("我是带参数的test方法,正在被执行,参数为:{}" , params);
|
||||
}
|
||||
|
||||
public void test1() {
|
||||
log.info("我是不带参数的test1方法,正在被执行");
|
||||
}
|
||||
}
|
||||
@@ -22,20 +22,20 @@ public class Dict implements Serializable {
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@NotBlank(groups = {Menu.New.class, Menu.Update.class})
|
||||
@NotBlank(groups = {New.class, Update.class})
|
||||
@Column(name = "table_name",nullable = false)
|
||||
private String tableName;
|
||||
|
||||
@NotBlank(groups = {Menu.New.class, Menu.Update.class})
|
||||
@NotBlank(groups = {New.class, Update.class})
|
||||
@Column(name = "fteld_name",nullable = false)
|
||||
private String fieldName;
|
||||
|
||||
@NotBlank(groups = {Menu.New.class, Menu.Update.class})
|
||||
@NotBlank(groups = {New.class, Update.class})
|
||||
@Column(name = "field_value",nullable = false)
|
||||
private String fieldValue;
|
||||
|
||||
@Column(name = "field_detail",nullable = false)
|
||||
@NotBlank(groups = {Menu.New.class, Menu.Update.class})
|
||||
@NotBlank(groups = {New.class, Update.class})
|
||||
private String fieldDetail;
|
||||
|
||||
@CreationTimestamp
|
||||
|
||||
115
src/main/java/me/aurora/domain/job/Job.java
Normal file
115
src/main/java/me/aurora/domain/job/Job.java
Normal file
@@ -0,0 +1,115 @@
|
||||
package me.aurora.domain.job;
|
||||
|
||||
import com.google.common.base.MoreObjects;
|
||||
import lombok.Data;
|
||||
import org.hibernate.annotations.CreationTimestamp;
|
||||
import org.hibernate.annotations.UpdateTimestamp;
|
||||
|
||||
import javax.persistence.*;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import java.io.Serializable;
|
||||
import java.sql.Timestamp;
|
||||
|
||||
/**
|
||||
* @author 郑杰
|
||||
* @date 2018/10/05 19:06:42
|
||||
*/
|
||||
@Data
|
||||
@Entity
|
||||
@Table(name = "zj_job")
|
||||
public class Job implements Serializable {
|
||||
|
||||
/**
|
||||
* 任务调度参数key
|
||||
*/
|
||||
public static final String JOB_PARAM_KEY = "JOB_PARAM_KEY";
|
||||
|
||||
public enum ScheduleStatus {
|
||||
/**
|
||||
* 正常
|
||||
*/
|
||||
NORMAL("0"),
|
||||
/**
|
||||
* 暂停
|
||||
*/
|
||||
PAUSE("1");
|
||||
|
||||
private String value;
|
||||
|
||||
private ScheduleStatus(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* Bean名称
|
||||
*/
|
||||
@Column(name = "baen_name")
|
||||
@NotBlank(groups = {New.class,Update.class})
|
||||
private String beanName;
|
||||
|
||||
/**
|
||||
* 方法名称
|
||||
*/
|
||||
@Column(name = "method_name")
|
||||
@NotBlank(groups = {New.class,Update.class})
|
||||
private String methodName;
|
||||
|
||||
/**
|
||||
* 参数
|
||||
*/
|
||||
@Column(name = "params")
|
||||
private String params;
|
||||
|
||||
/**
|
||||
* cron表达式
|
||||
*/
|
||||
@Column(name = "cron_expression")
|
||||
@NotBlank(groups = {New.class,Update.class})
|
||||
private String cronExpression;
|
||||
|
||||
/**
|
||||
* 状态 0=正常,1=暂停
|
||||
*/
|
||||
@Column(name = "status")
|
||||
@NotBlank(groups = {New.class,Update.class})
|
||||
private String status = "0";
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
@Column(name = "remark")
|
||||
@NotBlank(groups = {New.class,Update.class})
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 创建日期
|
||||
*/
|
||||
@UpdateTimestamp
|
||||
private Timestamp updateTime;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return MoreObjects.toStringHelper(this)
|
||||
.add("id", id)
|
||||
.add("beanName", beanName)
|
||||
.add("methodName", methodName)
|
||||
.add("params", params)
|
||||
.add("cronExpression", cronExpression)
|
||||
.add("status", status)
|
||||
.add("remark", remark)
|
||||
.add("updateTime", updateTime)
|
||||
.toString();
|
||||
}
|
||||
|
||||
public interface New{};
|
||||
public interface Update{};
|
||||
}
|
||||
90
src/main/java/me/aurora/domain/job/JobLog.java
Normal file
90
src/main/java/me/aurora/domain/job/JobLog.java
Normal file
@@ -0,0 +1,90 @@
|
||||
package me.aurora.domain.job;
|
||||
|
||||
import lombok.Data;
|
||||
import org.hibernate.annotations.CreationTimestamp;
|
||||
import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.sql.Timestamp;
|
||||
|
||||
/**
|
||||
* @author 郑杰
|
||||
* @date 2018/10/05 19:47:38
|
||||
*/
|
||||
@Entity
|
||||
@Data
|
||||
@Table(name = "zj_job_log")
|
||||
public class JobLog implements Serializable {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 任务id
|
||||
*/
|
||||
@Column(name = "job_id")
|
||||
private Long jobId;
|
||||
|
||||
/**
|
||||
* Bean名称
|
||||
*/
|
||||
@Column(name = "baen_name")
|
||||
private String beanName;
|
||||
|
||||
/**
|
||||
* 方法名称
|
||||
*/
|
||||
@Column(name = "method_name")
|
||||
private String methodName;
|
||||
|
||||
/**
|
||||
* 参数
|
||||
*/
|
||||
@Column(name = "params")
|
||||
private String params;
|
||||
|
||||
/**
|
||||
* cron表达式
|
||||
*/
|
||||
@Column(name = "cron_expression")
|
||||
private String cronExpression;
|
||||
|
||||
/**
|
||||
* 0=成功,1=失败
|
||||
*/
|
||||
@Column(name = "status")
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 错误信息
|
||||
*/
|
||||
@Column(name = "error_msg")
|
||||
private String error;
|
||||
|
||||
/**
|
||||
* 耗时(毫秒)
|
||||
*/
|
||||
private Long times;
|
||||
|
||||
/**
|
||||
* 创建日期
|
||||
*/
|
||||
@CreationTimestamp
|
||||
private Timestamp createTime;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "JobLog{" +
|
||||
"id=" + id +
|
||||
", jobId=" + jobId +
|
||||
", beanName='" + beanName + '\'' +
|
||||
", methodName='" + methodName + '\'' +
|
||||
", params='" + params + '\'' +
|
||||
", cronExpression='" + cronExpression + '\'' +
|
||||
", status='" + status + '\'' +
|
||||
", error='" + error + '\'' +
|
||||
", times=" + times +
|
||||
", createTime=" + createTime +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
13
src/main/java/me/aurora/repository/JobLogRepo.java
Normal file
13
src/main/java/me/aurora/repository/JobLogRepo.java
Normal file
@@ -0,0 +1,13 @@
|
||||
package me.aurora.repository;
|
||||
|
||||
import me.aurora.domain.job.JobLog;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
|
||||
/**
|
||||
* @author 郑杰
|
||||
* @date 2018/10/05 19:52:11
|
||||
*/
|
||||
public interface JobLogRepo extends JpaRepository<JobLog,Long>, JpaSpecificationExecutor {
|
||||
|
||||
}
|
||||
20
src/main/java/me/aurora/repository/JobRepo.java
Normal file
20
src/main/java/me/aurora/repository/JobRepo.java
Normal file
@@ -0,0 +1,20 @@
|
||||
package me.aurora.repository;
|
||||
|
||||
import me.aurora.domain.job.Job;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author 郑杰
|
||||
* @date 2018/10/05 19:18:54
|
||||
*/
|
||||
public interface JobRepo extends JpaRepository<Job,Long>, JpaSpecificationExecutor {
|
||||
|
||||
/**
|
||||
* 查找启用的任务
|
||||
* @return
|
||||
*/
|
||||
List<Job> findByStatusIsTrue();
|
||||
}
|
||||
65
src/main/java/me/aurora/repository/spec/JobLogSpce.java
Normal file
65
src/main/java/me/aurora/repository/spec/JobLogSpce.java
Normal file
@@ -0,0 +1,65 @@
|
||||
package me.aurora.repository.spec;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import me.aurora.domain.job.JobLog;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Predicate;
|
||||
import javax.persistence.criteria.Root;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* @author 郑杰
|
||||
* @date 2018/10/06 11:43:38
|
||||
*/
|
||||
public class JobLogSpce implements Specification<JobLog> {
|
||||
|
||||
private String beanName;
|
||||
private String remark;
|
||||
private String methodName;
|
||||
private String status;
|
||||
|
||||
public JobLogSpce(String beanName, String methodName, String remark, String status) {
|
||||
this.beanName = beanName;
|
||||
this.remark = remark;
|
||||
this.methodName = methodName;
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Predicate toPredicate(Root<JobLog> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
|
||||
List<Predicate> list = new ArrayList<Predicate>();
|
||||
|
||||
if (!StrUtil.isEmpty(status)) {
|
||||
list.add(cb.equal(root.get("status").as(String.class), status));
|
||||
}
|
||||
|
||||
if (!StrUtil.isEmpty(beanName)) {
|
||||
list.add(cb.equal(root.get("beanName").as(String.class), "%"+beanName+"%"));
|
||||
}
|
||||
|
||||
if (!StrUtil.isEmpty(remark)) {
|
||||
list.add(cb.like(root.get("remark").as(String.class), "%"+remark+"%"));
|
||||
}
|
||||
|
||||
if (!StrUtil.isEmpty(methodName)) {
|
||||
list.add(cb.equal(root.get("methodName").as(String.class), "%"+methodName+"%"));
|
||||
}
|
||||
|
||||
Predicate[] p = new Predicate[list.size()];
|
||||
return cb.and(list.toArray(p));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "JobSpce{" +
|
||||
"beanName='" + beanName + '\'' +
|
||||
", remark='" + remark + '\'' +
|
||||
", methodName='" + methodName + '\'' +
|
||||
", status='" + status + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
68
src/main/java/me/aurora/repository/spec/JobSpce.java
Normal file
68
src/main/java/me/aurora/repository/spec/JobSpce.java
Normal file
@@ -0,0 +1,68 @@
|
||||
package me.aurora.repository.spec;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import me.aurora.domain.Dict;
|
||||
import me.aurora.domain.job.Job;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Predicate;
|
||||
import javax.persistence.criteria.Root;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* @author 郑杰
|
||||
* @date 2018/10/05 19:20:51
|
||||
*/
|
||||
public class JobSpce implements Specification<Job> {
|
||||
|
||||
private String beanName;
|
||||
private String remark;
|
||||
private String methodName;
|
||||
private String status;
|
||||
|
||||
public JobSpce(String beanName, String methodName, String remark, String status) {
|
||||
this.beanName = beanName;
|
||||
this.remark = remark;
|
||||
this.methodName = methodName;
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Predicate toPredicate(Root<Job> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
|
||||
List<Predicate> list = new ArrayList<Predicate>();
|
||||
|
||||
|
||||
if (!StrUtil.isEmpty(status)) {
|
||||
list.add(cb.equal(root.get("status").as(String.class), status));
|
||||
}
|
||||
|
||||
if (!StrUtil.isEmpty(beanName)) {
|
||||
list.add(cb.equal(root.get("beanName").as(String.class), "%"+beanName+"%"));
|
||||
}
|
||||
|
||||
if (!StrUtil.isEmpty(methodName)) {
|
||||
list.add(cb.equal(root.get("methodName").as(String.class), "%"+methodName+"%"));
|
||||
}
|
||||
|
||||
if (!StrUtil.isEmpty(remark)) {
|
||||
list.add(cb.like(root.get("remark").as(String.class), "%"+remark+"%"));
|
||||
}
|
||||
|
||||
Predicate[] p = new Predicate[list.size()];
|
||||
return cb.and(list.toArray(p));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "JobSpce{" +
|
||||
"beanName='" + beanName + '\'' +
|
||||
", remark='" + remark + '\'' +
|
||||
", methodName='" + methodName + '\'' +
|
||||
", status='" + status + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
28
src/main/java/me/aurora/service/JobLogService.java
Normal file
28
src/main/java/me/aurora/service/JobLogService.java
Normal file
@@ -0,0 +1,28 @@
|
||||
package me.aurora.service;
|
||||
|
||||
import me.aurora.domain.job.JobLog;
|
||||
import me.aurora.repository.spec.JobLogSpce;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author 郑杰
|
||||
* @date 2018/10/05 19:50:21
|
||||
*/
|
||||
public interface JobLogService {
|
||||
|
||||
/**
|
||||
* 保存日志
|
||||
* @param log
|
||||
*/
|
||||
void insert(JobLog log);
|
||||
|
||||
/**
|
||||
* 查询全部日志
|
||||
* @param jobLogSpce
|
||||
* @param pageable
|
||||
* @return
|
||||
*/
|
||||
Map getJobLogsInfo(JobLogSpce jobLogSpce, Pageable pageable);
|
||||
}
|
||||
63
src/main/java/me/aurora/service/JobService.java
Normal file
63
src/main/java/me/aurora/service/JobService.java
Normal file
@@ -0,0 +1,63 @@
|
||||
package me.aurora.service;
|
||||
|
||||
import me.aurora.domain.job.Job;
|
||||
import me.aurora.repository.spec.JobSpce;
|
||||
import org.springframework.cache.annotation.CacheConfig;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author 郑杰
|
||||
* @date 2018/10/05 19:17:38
|
||||
*/
|
||||
@CacheConfig(cacheNames = "job")
|
||||
public interface JobService {
|
||||
|
||||
/**
|
||||
* 查询全部任务
|
||||
* @param jobSpce
|
||||
* @param pageable
|
||||
* @return
|
||||
*/
|
||||
@Cacheable(keyGenerator = "keyGenerator")
|
||||
Map getJobsInfo(JobSpce jobSpce, Pageable pageable);
|
||||
|
||||
/**
|
||||
* 新增任务
|
||||
* @param job
|
||||
*/
|
||||
@CacheEvict(allEntries = true)
|
||||
void insert(Job job);
|
||||
|
||||
/**
|
||||
* 根据ID查询
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@Cacheable(key = "#p0")
|
||||
Job findById(Long id);
|
||||
|
||||
/**
|
||||
* 更新任务状态
|
||||
* @param byId
|
||||
*/
|
||||
@CacheEvict(allEntries = true)
|
||||
void updateStatus(Job byId);
|
||||
|
||||
/**
|
||||
* 更新任务
|
||||
* @param old
|
||||
* @param job
|
||||
*/
|
||||
@CacheEvict(allEntries = true)
|
||||
void update(Job old, Job job);
|
||||
|
||||
/**
|
||||
* 删除任务
|
||||
* @param byId
|
||||
*/
|
||||
@CacheEvict(allEntries = true)
|
||||
void delete(Job byId);
|
||||
}
|
||||
35
src/main/java/me/aurora/service/impl/JobLogServiceImpl.java
Normal file
35
src/main/java/me/aurora/service/impl/JobLogServiceImpl.java
Normal file
@@ -0,0 +1,35 @@
|
||||
package me.aurora.service.impl;
|
||||
|
||||
import me.aurora.domain.job.JobLog;
|
||||
import me.aurora.repository.JobLogRepo;
|
||||
import me.aurora.repository.spec.JobLogSpce;
|
||||
import me.aurora.service.JobLogService;
|
||||
import me.aurora.util.PageUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author 郑杰
|
||||
* @date 2018/10/05 19:51:22
|
||||
*/
|
||||
@Service(value = "jobLogService")
|
||||
public class JobLogServiceImpl implements JobLogService {
|
||||
|
||||
@Autowired
|
||||
private JobLogRepo jobLogRepo;
|
||||
|
||||
@Override
|
||||
public void insert(JobLog log) {
|
||||
jobLogRepo.save(log);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map getJobLogsInfo(JobLogSpce jobLogSpce, Pageable pageable) {
|
||||
Page<JobLog> jobLogs = jobLogRepo.findAll(jobLogSpce,pageable);
|
||||
return PageUtil.buildPage(jobLogs.getContent(),jobLogs.getTotalElements());
|
||||
}
|
||||
}
|
||||
84
src/main/java/me/aurora/service/impl/JobServiceImpl.java
Normal file
84
src/main/java/me/aurora/service/impl/JobServiceImpl.java
Normal file
@@ -0,0 +1,84 @@
|
||||
package me.aurora.service.impl;
|
||||
|
||||
import cn.hutool.http.HttpStatus;
|
||||
import me.aurora.config.exception.AuroraException;
|
||||
import me.aurora.domain.job.Job;
|
||||
import me.aurora.repository.JobRepo;
|
||||
import me.aurora.repository.spec.JobSpce;
|
||||
import me.aurora.service.JobService;
|
||||
import me.aurora.util.PageUtil;
|
||||
import me.aurora.util.ValidationUtil;
|
||||
import me.aurora.util.job.ScheduleUtils;
|
||||
import org.quartz.CronExpression;
|
||||
import org.quartz.Scheduler;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* @author 郑杰
|
||||
* @date 2018/10/05 19:18:05
|
||||
*/
|
||||
@Service(value = "jobService")
|
||||
public class JobServiceImpl implements JobService {
|
||||
|
||||
@Autowired
|
||||
private JobRepo jobRepo;
|
||||
|
||||
@Resource(name = "scheduler")
|
||||
private Scheduler scheduler;
|
||||
|
||||
@Override
|
||||
public Map getJobsInfo(JobSpce jobSpce, Pageable pageable) {
|
||||
Page<Job> jobs = jobRepo.findAll(jobSpce,pageable);
|
||||
return PageUtil.buildPage(jobs.getContent(),jobs.getTotalElements());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insert(Job job) {
|
||||
if (!CronExpression.isValidExpression(job.getCronExpression())){
|
||||
throw new AuroraException(HttpStatus.HTTP_BAD_REQUEST,"cron表达式格式错误");
|
||||
}
|
||||
jobRepo.save(job);
|
||||
ScheduleUtils.createScheduleJob(scheduler, job);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Job findById(Long id) {
|
||||
Optional<Job> job = jobRepo.findById(id);
|
||||
ValidationUtil.isNull(job,"id :" +id +" is not find");
|
||||
return job.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateStatus(Job job) {
|
||||
if (job.getStatus().equals(Job.ScheduleStatus.PAUSE.getValue())) {
|
||||
ScheduleUtils.resumeJob(scheduler, job.getId());
|
||||
job.setStatus("0");
|
||||
} else {
|
||||
ScheduleUtils.pauseJob(scheduler,job.getId());
|
||||
job.setStatus("1");
|
||||
}
|
||||
jobRepo.save(job);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Job old, Job job) {
|
||||
if (!CronExpression.isValidExpression(job.getCronExpression())){
|
||||
throw new AuroraException(HttpStatus.HTTP_BAD_REQUEST,"cron表达式格式错误");
|
||||
}
|
||||
job.setStatus(old.getStatus());
|
||||
jobRepo.save(job);
|
||||
ScheduleUtils.updateScheduleJob(scheduler,job);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(Job job) {
|
||||
ScheduleUtils.deleteScheduleJob(scheduler,job.getId());
|
||||
jobRepo.delete(job);
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,7 @@ import me.aurora.service.mapper.PerMissionMapper;
|
||||
import me.aurora.util.PageUtil;
|
||||
import me.aurora.config.exception.AuroraException;
|
||||
import me.aurora.util.ValidationUtil;
|
||||
import me.aurora.util.job.ScheduleUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
@@ -88,21 +89,22 @@ public class PermissionServiceImpl implements PermissionService {
|
||||
@Override
|
||||
public List<Map<String, Object>> buildPermissionTree(List<Permission> permissions) {
|
||||
List<Map<String,Object>> maps = new LinkedList<>();
|
||||
for (Permission permission:permissions) {
|
||||
if (permission!=null){
|
||||
List<Permission> permissionList = permissionRepo.findByPid(Integer.parseInt(permission.getId()+""));
|
||||
Map<String,Object> map = new HashMap<>(16);
|
||||
map.put("id",permission.getId());
|
||||
String name = !StrUtil.isEmpty(permission.getRemark())?permission.getRemark():permission.getPerms();
|
||||
map.put("name",name);
|
||||
if(permissionList!=null && permissionList.size()!=0){
|
||||
map.put("open",true);
|
||||
map.put("isParent",true);
|
||||
map.put("children",buildPermissionTree(permissionList));
|
||||
permissions.forEach(permission -> {
|
||||
if (permission!=null){
|
||||
List<Permission> permissionList = permissionRepo.findByPid(Integer.parseInt(permission.getId()+""));
|
||||
Map<String,Object> map = new HashMap<>(16);
|
||||
map.put("id",permission.getId());
|
||||
String name = !StrUtil.isEmpty(permission.getRemark())?permission.getRemark():permission.getPerms();
|
||||
map.put("name",name);
|
||||
if(permissionList!=null && permissionList.size()!=0){
|
||||
map.put("open",true);
|
||||
map.put("isParent",true);
|
||||
map.put("children",buildPermissionTree(permissionList));
|
||||
}
|
||||
maps.add(map);
|
||||
}
|
||||
maps.add(map);
|
||||
}
|
||||
}
|
||||
);
|
||||
return maps;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,14 +36,14 @@ public class RoleServiceImpl implements RoleService {
|
||||
@Override
|
||||
public List<Map<String, Object>> buildRoleTree(List<Role> roles) {
|
||||
List<Map<String,Object>> maps = new LinkedList<>();
|
||||
for (Role role:roles) {
|
||||
roles.forEach(role -> {
|
||||
if (role!=null){
|
||||
Map<String,Object> map = new HashMap<>(16);
|
||||
map.put("id",role.getId());
|
||||
map.put("name",role.getName());
|
||||
maps.add(map);
|
||||
}
|
||||
}
|
||||
});
|
||||
return maps;
|
||||
}
|
||||
|
||||
|
||||
@@ -70,10 +70,10 @@ public class UserServiceImpl implements UserService {
|
||||
public Map getUsersInfo(UserSpec userSpec, Pageable pageable) {
|
||||
Page<User> users = userRepo.findAll(userSpec,pageable);
|
||||
List<UserDTO> userDTOS = new ArrayList<>();
|
||||
for(User user:users.getContent()){
|
||||
users.getContent().forEach(user -> {
|
||||
UserDTO userDTO = userMapper.toDto(user,roleService.getRoles(user.getRoles()));
|
||||
userDTOS.add(userDTO);
|
||||
}
|
||||
});
|
||||
return PageUtil.buildPage(userDTOS,users.getTotalElements());
|
||||
}
|
||||
|
||||
|
||||
73
src/main/java/me/aurora/util/job/ScheduleJob.java
Normal file
73
src/main/java/me/aurora/util/job/ScheduleJob.java
Normal file
@@ -0,0 +1,73 @@
|
||||
package me.aurora.util.job;
|
||||
|
||||
import me.aurora.domain.job.Job;
|
||||
import me.aurora.domain.job.JobLog;
|
||||
import me.aurora.service.JobLogService;
|
||||
import me.aurora.service.JobService;
|
||||
import me.aurora.util.SpringContextUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.quartz.JobExecutionContext;
|
||||
import org.quartz.Scheduler;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.scheduling.quartz.QuartzJobBean;
|
||||
import javax.annotation.Resource;
|
||||
import java.util.concurrent.*;
|
||||
|
||||
/**
|
||||
* 用于记录日志
|
||||
* 定时任务
|
||||
* @author 郑杰
|
||||
*/
|
||||
public class ScheduleJob extends QuartzJobBean {
|
||||
|
||||
@Resource(name = "scheduler")
|
||||
private Scheduler scheduler;
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
private ExecutorService service = Executors.newSingleThreadExecutor();
|
||||
|
||||
@Override
|
||||
protected void executeInternal(JobExecutionContext context) {
|
||||
Job scheduleJob = (Job) context.getMergedJobDataMap().get(Job.JOB_PARAM_KEY);
|
||||
|
||||
// 获取spring bean
|
||||
JobLogService logService = (JobLogService) SpringContextUtils.getBean("jobLogService");
|
||||
JobService jobService = (JobService) SpringContextUtils.getBean("jobService");
|
||||
|
||||
JobLog log = new JobLog();
|
||||
log.setJobId(scheduleJob.getId());
|
||||
log.setBeanName(scheduleJob.getBeanName());
|
||||
log.setMethodName(scheduleJob.getMethodName());
|
||||
log.setParams(scheduleJob.getParams());
|
||||
long startTime = System.currentTimeMillis();
|
||||
log.setCronExpression(scheduleJob.getCronExpression());
|
||||
try {
|
||||
// 执行任务
|
||||
logger.info("任务准备执行,任务ID:{}", scheduleJob.getId());
|
||||
ScheduleRunnable task = new ScheduleRunnable(scheduleJob.getBeanName(), scheduleJob.getMethodName(),
|
||||
scheduleJob.getParams());
|
||||
Future<?> future = service.submit(task);
|
||||
future.get();
|
||||
long times = System.currentTimeMillis() - startTime;
|
||||
log.setTimes(times);
|
||||
// 任务状态 0:成功 1:失败
|
||||
log.setStatus("0");
|
||||
logger.info("任务执行完毕,任务ID:{} 总共耗时:{} 毫秒", scheduleJob.getId(), times);
|
||||
} catch (Exception e) {
|
||||
logger.error("任务执行失败,任务ID:" + scheduleJob.getId(), e);
|
||||
long times = System.currentTimeMillis() - startTime;
|
||||
log.setTimes(times);
|
||||
// 任务状态 0:成功 1:失败
|
||||
log.setStatus("1");
|
||||
log.setError(StringUtils.substring(e.toString(), 0, 2000));
|
||||
//出错就暂停任务
|
||||
ScheduleUtils.pauseJob(scheduler,scheduleJob.getId());
|
||||
//更新状态
|
||||
jobService.updateStatus(scheduleJob);
|
||||
} finally {
|
||||
logService.insert(log);
|
||||
}
|
||||
}
|
||||
}
|
||||
49
src/main/java/me/aurora/util/job/ScheduleRunnable.java
Normal file
49
src/main/java/me/aurora/util/job/ScheduleRunnable.java
Normal file
@@ -0,0 +1,49 @@
|
||||
package me.aurora.util.job;
|
||||
|
||||
import me.aurora.util.SpringContextUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* 执行定时任务
|
||||
* @author 郑杰
|
||||
*
|
||||
*/
|
||||
public class ScheduleRunnable implements Runnable {
|
||||
|
||||
private Logger log = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
private Object target;
|
||||
private Method method;
|
||||
private String params;
|
||||
|
||||
ScheduleRunnable(String beanName, String methodName, String params)
|
||||
throws NoSuchMethodException, SecurityException {
|
||||
this.target = SpringContextUtils.getBean(beanName);
|
||||
this.params = params;
|
||||
|
||||
if (StringUtils.isNotBlank(params)) {
|
||||
this.method = target.getClass().getDeclaredMethod(methodName, String.class);
|
||||
} else {
|
||||
this.method = target.getClass().getDeclaredMethod(methodName);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
ReflectionUtils.makeAccessible(method);
|
||||
if (StringUtils.isNotBlank(params)) {
|
||||
method.invoke(target, params);
|
||||
} else {
|
||||
method.invoke(target);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("执行定时任务失败",e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
175
src/main/java/me/aurora/util/job/ScheduleUtils.java
Normal file
175
src/main/java/me/aurora/util/job/ScheduleUtils.java
Normal file
@@ -0,0 +1,175 @@
|
||||
package me.aurora.util.job;
|
||||
|
||||
import cn.hutool.http.HttpStatus;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.aurora.config.exception.AuroraException;
|
||||
import me.aurora.domain.job.Job;
|
||||
import org.quartz.*;
|
||||
import org.quartz.impl.triggers.CronTriggerImpl;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 定时任务工具类
|
||||
* @author 郑杰
|
||||
*/
|
||||
@Slf4j
|
||||
public class ScheduleUtils {
|
||||
|
||||
protected ScheduleUtils() {
|
||||
}
|
||||
|
||||
private static final String JOB_NAME = "TASK_";
|
||||
|
||||
/**
|
||||
* 获取触发器key
|
||||
*/
|
||||
private static TriggerKey getTriggerKey(Long id) {
|
||||
return TriggerKey.triggerKey(JOB_NAME + id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取jobKey
|
||||
*/
|
||||
private static JobKey getJobKey(Long id) {
|
||||
return JobKey.jobKey(JOB_NAME + id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取表达式触发器
|
||||
*/
|
||||
public static CronTrigger getCronTrigger(Scheduler scheduler, Long jobId) {
|
||||
try {
|
||||
return (CronTrigger) scheduler.getTrigger(getTriggerKey(jobId));
|
||||
} catch (SchedulerException e) {
|
||||
log.error("获取Cron表达式失败", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建定时任务
|
||||
*/
|
||||
public static void createScheduleJob(Scheduler scheduler, Job scheduleJob) {
|
||||
try {
|
||||
// 构建job信息
|
||||
JobDetail jobDetail = JobBuilder.newJob(ScheduleJob.class).withIdentity(getJobKey(scheduleJob.getId()))
|
||||
.build();
|
||||
|
||||
// 表达式调度构建器
|
||||
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression())
|
||||
.withMisfireHandlingInstructionDoNothing();
|
||||
|
||||
// 按新的cronExpression表达式构建一个新的trigger
|
||||
CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(getTriggerKey(scheduleJob.getId()))
|
||||
.withSchedule(scheduleBuilder).build();
|
||||
|
||||
// 放入参数,运行时的方法可以获取
|
||||
jobDetail.getJobDataMap().put(Job.JOB_PARAM_KEY, scheduleJob);
|
||||
|
||||
//重置启动时间
|
||||
((CronTriggerImpl)trigger).setStartTime(new Date());
|
||||
|
||||
//执行定时任务
|
||||
scheduler.scheduleJob(jobDetail, trigger);
|
||||
|
||||
// 暂停任务
|
||||
if (scheduleJob.getStatus().equals(Job.ScheduleStatus.PAUSE.getValue())) {
|
||||
pauseJob(scheduler, scheduleJob.getId());
|
||||
}
|
||||
} catch (SchedulerException e) {
|
||||
log.error("创建定时任务失败", e);
|
||||
throw new AuroraException(HttpStatus.HTTP_INTERNAL_ERROR,"创建定时任务失败");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新定时任务
|
||||
*/
|
||||
public static void updateScheduleJob(Scheduler scheduler, Job scheduleJob) {
|
||||
try {
|
||||
TriggerKey triggerKey = getTriggerKey(scheduleJob.getId());
|
||||
|
||||
// 表达式调度构建器
|
||||
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression())
|
||||
.withMisfireHandlingInstructionDoNothing();
|
||||
|
||||
CronTrigger trigger = getCronTrigger(scheduler, scheduleJob.getId());
|
||||
|
||||
if (trigger == null) {
|
||||
throw new SchedulerException("获取Cron表达式失败");
|
||||
} else {
|
||||
// 按新的cronExpression表达式重新构建trigger
|
||||
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
|
||||
// 参数
|
||||
trigger.getJobDataMap().put(Job.JOB_PARAM_KEY, scheduleJob);
|
||||
}
|
||||
|
||||
//重置启动时间
|
||||
((CronTriggerImpl)trigger).setStartTime(new Date());
|
||||
|
||||
//重置表达式
|
||||
scheduler.rescheduleJob(triggerKey, trigger);
|
||||
|
||||
// 暂停任务
|
||||
if (scheduleJob.getStatus().equals(Job.ScheduleStatus.PAUSE.getValue())) {
|
||||
pauseJob(scheduler, scheduleJob.getId());
|
||||
}
|
||||
|
||||
} catch (SchedulerException e) {
|
||||
log.error("更新定时任务失败", e);
|
||||
throw new AuroraException(HttpStatus.HTTP_INTERNAL_ERROR,"更新定时任务失败");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 立即执行任务
|
||||
*/
|
||||
public static void run(Scheduler scheduler, Job scheduleJob) {
|
||||
try {
|
||||
// 参数
|
||||
JobDataMap dataMap = new JobDataMap();
|
||||
dataMap.put(Job.JOB_PARAM_KEY, scheduleJob);
|
||||
|
||||
scheduler.triggerJob(getJobKey(scheduleJob.getId()), dataMap);
|
||||
} catch (SchedulerException e) {
|
||||
log.error("执行定时任务失败", e);
|
||||
throw new AuroraException(HttpStatus.HTTP_INTERNAL_ERROR,"执行定时任务失败");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 暂停任务
|
||||
*/
|
||||
public static void pauseJob(Scheduler scheduler, Long jobId) {
|
||||
try {
|
||||
scheduler.pauseJob(getJobKey(jobId));
|
||||
} catch (SchedulerException e) {
|
||||
log.error("暂停定时任务失败", e);
|
||||
throw new AuroraException(HttpStatus.HTTP_INTERNAL_ERROR,"暂停定时任务失败");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 恢复任务
|
||||
*/
|
||||
public static void resumeJob(Scheduler scheduler, Long jobId) {
|
||||
try {
|
||||
scheduler.resumeJob(getJobKey(jobId));
|
||||
} catch (SchedulerException e) {
|
||||
log.error("恢复定时任务失败", e);
|
||||
throw new AuroraException(HttpStatus.HTTP_INTERNAL_ERROR,"恢复定时任务失败");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除定时任务
|
||||
*/
|
||||
public static void deleteScheduleJob(Scheduler scheduler, Long jobId) {
|
||||
try {
|
||||
scheduler.deleteJob(getJobKey(jobId));
|
||||
} catch (SchedulerException e) {
|
||||
log.error("删除定时任务失败", e);
|
||||
throw new AuroraException(HttpStatus.HTTP_INTERNAL_ERROR,"删除定时任务失败");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -134,13 +134,4 @@ aurora:
|
||||
unauthorizedUrl: /exception/403
|
||||
# 是否开启 AOP 日志,默认开启
|
||||
openAopLog: true
|
||||
userAvatar: https://i.loli.net/2018/08/16/5b75166b3157a.jpg
|
||||
|
||||
db:
|
||||
username: root
|
||||
password: dqjdda@1996.
|
||||
dbName: aurora
|
||||
# 将resources下的sql文件,复制到Windows或者linux系统下,用于还原操作
|
||||
path: sql/aurora.sql
|
||||
pathName: aurora.sql
|
||||
linuxDbPath: /data/db
|
||||
userAvatar: https://i.loli.net/2018/08/16/5b75166b3157a.jpg
|
||||
@@ -11,7 +11,7 @@
|
||||
Target Server Version : 50559
|
||||
File Encoding : 65001
|
||||
|
||||
Date: 05/10/2018 15:02:12
|
||||
Date: 06/10/2018 14:05:55
|
||||
*/
|
||||
|
||||
SET NAMES utf8mb4;
|
||||
@@ -54,7 +54,7 @@ CREATE TABLE `zj_dict` (
|
||||
`table_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
|
||||
`updateTime` datetime NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 11 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 15 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of zj_dict
|
||||
@@ -68,6 +68,10 @@ INSERT INTO `zj_dict` VALUES (6, '2018-10-05 14:15:18', '内链菜单', 'iframe'
|
||||
INSERT INTO `zj_dict` VALUES (7, '2018-10-05 14:15:39', '外链菜单', 'iframe', '1', 'zj_menu', '2018-10-05 14:15:39');
|
||||
INSERT INTO `zj_dict` VALUES (8, '2018-10-05 14:16:36', '系统菜单', 'sys', '1', 'zj_menu', '2018-10-05 14:16:36');
|
||||
INSERT INTO `zj_dict` VALUES (9, '2018-10-05 14:16:55', '普通菜单', 'sys', '0', 'zj_menu', '2018-10-05 14:16:55');
|
||||
INSERT INTO `zj_dict` VALUES (11, '2018-10-06 12:31:03', '启动', 'status', '0', 'zj_job', '2018-10-06 12:31:03');
|
||||
INSERT INTO `zj_dict` VALUES (12, '2018-10-06 12:31:19', '暂停', 'status', '1', 'zj_job', '2018-10-06 12:31:19');
|
||||
INSERT INTO `zj_dict` VALUES (13, '2018-10-06 12:31:36', '成功', 'status', '0', 'zj_job_log', '2018-10-06 12:31:36');
|
||||
INSERT INTO `zj_dict` VALUES (14, '2018-10-06 12:31:49', '失败', 'status', '1', 'zj_job_log', '2018-10-06 12:31:49');
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for zj_email_config
|
||||
@@ -89,6 +93,46 @@ CREATE TABLE `zj_email_config` (
|
||||
-- ----------------------------
|
||||
INSERT INTO `zj_email_config` VALUES (1, 'auaur@sina.com', 'smtp.sina.com', '21BC734311FFD2BA881D34A08DAB61AE', '465', 'auaur', b'1');
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for zj_job
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `zj_job`;
|
||||
CREATE TABLE `zj_job` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT,
|
||||
`baen_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
|
||||
`cron_expression` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
|
||||
`method_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
|
||||
`params` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
|
||||
`remark` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
|
||||
`status` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
|
||||
`updateTime` datetime NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of zj_job
|
||||
-- ----------------------------
|
||||
INSERT INTO `zj_job` VALUES (1, 'myTaskTest', '0/5 * * * * ?', 'test', '测试', '带参数测试', '1', '2018-10-06 12:45:19');
|
||||
INSERT INTO `zj_job` VALUES (2, 'myTaskTest', '0/6 * * * * ?', 'test1', '', '不带参数测试', '1', '2018-10-06 12:46:13');
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for zj_job_log
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `zj_job_log`;
|
||||
CREATE TABLE `zj_job_log` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT,
|
||||
`baen_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
|
||||
`createTime` datetime NULL DEFAULT NULL,
|
||||
`cron_expression` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
|
||||
`error_msg` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
|
||||
`job_id` bigint(20) NULL DEFAULT NULL,
|
||||
`method_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
|
||||
`params` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
|
||||
`status` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
|
||||
`times` bigint(20) NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for zj_menu
|
||||
-- ----------------------------
|
||||
@@ -108,7 +152,7 @@ CREATE TABLE `zj_menu` (
|
||||
`sys` bit(1) NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `UK_cbhg0bi3f1emxkhqqtvca9btx`(`soft`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 28 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 31 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of zj_menu
|
||||
@@ -131,6 +175,9 @@ INSERT INTO `zj_menu` VALUES (22, 'layui-icon-edit', 18, 2, '邮件工具', 41,
|
||||
INSERT INTO `zj_menu` VALUES (24, 'layui-icon-dollar', 18, 2, '支付宝工具', 42, '/aliPay/index', '2018-09-30 15:16:43', '2018-10-02 16:27:09', 0, b'0', b'1');
|
||||
INSERT INTO `zj_menu` VALUES (25, 'layui-icon-upload', 18, 2, '七牛云存储', 43, '/qiNiu/index', '2018-10-02 11:03:27', '2018-10-02 16:26:42', 0, b'0', b'1');
|
||||
INSERT INTO `zj_menu` VALUES (27, 'layui-icon-read', 7, 2, '字典管理', 6, '/dict/index', '2018-10-05 14:03:40', '2018-10-05 14:03:40', 0, b'0', b'0');
|
||||
INSERT INTO `zj_menu` VALUES (28, 'layui-icon-log', 0, 1, '任务调度', 20, '', '2018-10-06 10:37:11', '2018-10-06 11:55:59', 2, b'0', b'0');
|
||||
INSERT INTO `zj_menu` VALUES (29, 'layui-icon-radio', 28, 2, '定时任务', 21, '/job/index', '2018-10-06 10:38:06', '2018-10-06 10:38:06', 0, b'0', b'0');
|
||||
INSERT INTO `zj_menu` VALUES (30, 'layui-icon-survey', 28, 2, '调度日志', 22, '/jobLog/index', '2018-10-06 11:55:59', '2018-10-06 11:55:59', 0, b'0', b'0');
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for zj_menus_roles
|
||||
@@ -166,6 +213,9 @@ INSERT INTO `zj_menus_roles` VALUES (22, 1);
|
||||
INSERT INTO `zj_menus_roles` VALUES (24, 1);
|
||||
INSERT INTO `zj_menus_roles` VALUES (25, 1);
|
||||
INSERT INTO `zj_menus_roles` VALUES (27, 1);
|
||||
INSERT INTO `zj_menus_roles` VALUES (28, 1);
|
||||
INSERT INTO `zj_menus_roles` VALUES (29, 1);
|
||||
INSERT INTO `zj_menus_roles` VALUES (30, 1);
|
||||
INSERT INTO `zj_menus_roles` VALUES (5, 3);
|
||||
INSERT INTO `zj_menus_roles` VALUES (6, 3);
|
||||
INSERT INTO `zj_menus_roles` VALUES (7, 3);
|
||||
@@ -194,7 +244,7 @@ CREATE TABLE `zj_permission` (
|
||||
`pid` int(11) NOT NULL,
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `UK_djtxn2vldlgrkfk21d155b48i`(`perms`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 37 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 44 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of zj_permission
|
||||
@@ -232,6 +282,13 @@ INSERT INTO `zj_permission` VALUES (33, 'dict:select', '字典查询', '2018-10-
|
||||
INSERT INTO `zj_permission` VALUES (34, 'dict:add', '新增字典', '2018-10-05 14:01:19', '2018-10-05 14:01:19', 32);
|
||||
INSERT INTO `zj_permission` VALUES (35, 'dict:update', '更新字典', '2018-10-05 14:01:33', '2018-10-05 14:01:33', 32);
|
||||
INSERT INTO `zj_permission` VALUES (36, 'dict:delete', '删除字典', '2018-10-05 14:01:46', '2018-10-05 14:01:46', 32);
|
||||
INSERT INTO `zj_permission` VALUES (37, 'job:all', '任务调度', '2018-10-06 12:28:06', '2018-10-06 12:28:06', 0);
|
||||
INSERT INTO `zj_permission` VALUES (38, 'job:select', '任务查询', '2018-10-06 12:28:39', '2018-10-06 12:28:39', 37);
|
||||
INSERT INTO `zj_permission` VALUES (39, 'job:log', '任务日志查询', '2018-10-06 12:28:59', '2018-10-06 12:29:06', 37);
|
||||
INSERT INTO `zj_permission` VALUES (40, 'job:add', '新增任务', '2018-10-06 12:29:28', '2018-10-06 12:29:28', 37);
|
||||
INSERT INTO `zj_permission` VALUES (41, 'job:status', '任务状态修改', '2018-10-06 12:29:45', '2018-10-06 12:29:45', 37);
|
||||
INSERT INTO `zj_permission` VALUES (42, 'job:update', '更新任务', '2018-10-06 12:30:00', '2018-10-06 12:30:00', 37);
|
||||
INSERT INTO `zj_permission` VALUES (43, 'job:delete', '删除任务', '2018-10-06 12:30:16', '2018-10-06 12:30:16', 37);
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for zj_permissions_roles
|
||||
@@ -275,7 +332,7 @@ CREATE TABLE `zj_picture` (
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
INDEX `FK5qtt7wql9517j0e2read2pdus`(`user_id`) USING BTREE,
|
||||
CONSTRAINT `FK5qtt7wql9517j0e2read2pdus` FOREIGN KEY (`user_id`) REFERENCES `zj_user` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of zj_picture
|
||||
@@ -315,12 +372,7 @@ CREATE TABLE `zj_qiniu_content` (
|
||||
`url` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
|
||||
`updateTime` datetime NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of zj_qiniu_content
|
||||
-- ----------------------------
|
||||
INSERT INTO `zj_qiniu_content` VALUES (1, 'aurora', '8.49KB ', '5ba46d305018d20181003145806.jpg', '公开', 'http://pfywktugt.bkt.clouddn.com/5ba46d305018d20181003145806.jpg', '2018-10-05 11:50:30');
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for zj_role
|
||||
@@ -356,7 +408,7 @@ CREATE TABLE `zj_syslog` (
|
||||
`time` int(11) NULL DEFAULT NULL,
|
||||
`username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 369 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for zj_user
|
||||
@@ -373,12 +425,12 @@ CREATE TABLE `zj_user` (
|
||||
`username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `UK_kpubos9gc2cvtkb0thktkbkes`(`email`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of zj_user
|
||||
-- ----------------------------
|
||||
INSERT INTO `zj_user` VALUES (1, 'https://www.zhengjie.me/images/avatar.jpg', '2018-08-23 09:11:56', 'zhengjie@tom.com', 1, '2018-10-05 14:58:50', '65a674ce6632479005ea7a9071234cfb', 'aurora');
|
||||
INSERT INTO `zj_user` VALUES (1, 'https://www.zhengjie.me/images/avatar.jpg', '2018-08-23 09:11:56', 'zhengjie@tom.com', 1, '2018-10-06 14:01:49', '65a674ce6632479005ea7a9071234cfb', 'aurora');
|
||||
INSERT INTO `zj_user` VALUES (2, 'https://i.loli.net/2018/08/16/5b75166b3157a.jpg', '2018-10-03 09:16:20', 'everyone@aurora.xyz', 1, '2018-10-05 11:29:44', '36318d4cc46eb68050b8b81ebc620f05', 'everyone');
|
||||
|
||||
-- ----------------------------
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>版本号</td>
|
||||
<td>v1.0</td>
|
||||
<td>v1.1</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>前端框架</td>
|
||||
@@ -135,7 +135,7 @@
|
||||
</div>
|
||||
<div class="layui-col-md12">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">关于Aurora 1.0</div>
|
||||
<div class="layui-card-header">关于Aurora</div>
|
||||
<div class="layui-card-body">
|
||||
<ul class="layui-timeline">
|
||||
|
||||
@@ -190,7 +190,7 @@
|
||||
<li class="layui-timeline-item">
|
||||
<i class="layui-icon layui-timeline-axis"></i>
|
||||
<div class="layui-timeline-content layui-text">
|
||||
<h3 class="layui-timeline-title">2018年9月28日 - 至今 (v1.0.1)</h3>
|
||||
<h3 class="layui-timeline-title">2018年9月28日 (v1.0.1)</h3>
|
||||
<p>
|
||||
<b>#集成了第三方工具</b>
|
||||
<ul>
|
||||
@@ -198,8 +198,19 @@
|
||||
<li>邮件发送工具</li>
|
||||
<li>支付宝支付</li>
|
||||
<li>七牛云储存</li>
|
||||
<li>微信支付(开发中)</li>
|
||||
<li>阿里大鱼(开发中)</li>
|
||||
</ul>
|
||||
</p>
|
||||
</div>
|
||||
</li>
|
||||
<li class="layui-timeline-item">
|
||||
<i class="layui-icon layui-timeline-axis"></i>
|
||||
<div class="layui-timeline-content layui-text">
|
||||
<h3 class="layui-timeline-title">2018年10月6日 (v1.1)</h3>
|
||||
<p>
|
||||
<b>#v1.1发布,集成任务调度</b>
|
||||
<ul>
|
||||
<li>任务调度</li>
|
||||
<li>调度日志</li>
|
||||
</ul>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||
<title>Aurora 1.0 后台管理</title>
|
||||
<title>Aurora 后台管理</title>
|
||||
<!-- build:css -->
|
||||
<link rel="stylesheet" th:href="@{'/plugins/css/layui.css'}">
|
||||
<link rel="stylesheet" th:href="@{'/plugins/css/theme/default.css'}" th:id="theme">
|
||||
@@ -19,7 +19,7 @@
|
||||
<i class="layui-icon"></i>
|
||||
</div>
|
||||
<div class="layui-logo-brand">
|
||||
<a href="#/">Aurora 1.0</a>
|
||||
<a href="#/">Aurora 1.1</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-layout-left">
|
||||
|
||||
48
src/main/resources/templates/job/add.html
Normal file
48
src/main/resources/templates/job/add.html
Normal file
@@ -0,0 +1,48 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||
<title>Aurora- 新增任务</title>
|
||||
<!-- build:css -->
|
||||
<link rel="stylesheet" th:href="@{'/plugins/css/layui.css'}">
|
||||
<!-- endbuild -->
|
||||
</head>
|
||||
<body>
|
||||
<div style="padding: 10px; line-height: 15px; font-weight: 300;">
|
||||
<form class="layui-form layui-form-pane" action="">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">Bean名称</label>
|
||||
<div class=layui-input-lump>
|
||||
<input type="text" name="beanName" placeholder="请输入Bean名称.." autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">方法名称</label>
|
||||
<div class=layui-input-lump>
|
||||
<input type="text" name="methodName" placeholder="请输入方法名称.." autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">cron表达式</label>
|
||||
<div class=layui-input-lump>
|
||||
<input type="text" name="cronExpression" placeholder="请输入cron表达式.." autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">参数</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="params" lay-verify="required" placeholder="请输入参数.." autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item layui-form-text">
|
||||
<label class="layui-form-label">备注</label>
|
||||
<div class="layui-input-block">
|
||||
<textarea name="remark" placeholder="请输入备注.." class="layui-textarea"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
300
src/main/resources/templates/job/index.html
Normal file
300
src/main/resources/templates/job/index.html
Normal file
@@ -0,0 +1,300 @@
|
||||
<div class="layui-fluid">
|
||||
<div class="layui-row">
|
||||
<div class="layui-col-xs12">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">定时任务管理</div>
|
||||
<div class="layui-card-body">
|
||||
<div class="layui-card-header">
|
||||
<a id="add" shiro:hasAnyPermissions="admin,job:all,job:add" class="layui-btn layui-btn-xs">
|
||||
<i class="layui-icon"></i>
|
||||
<span>新增</span>
|
||||
</a>
|
||||
<a href="javascript:;" class="layui-btn layui-btn-xs layui-btn-primary" id="search_hash">
|
||||
<i class="layui-icon"></i>
|
||||
</a>
|
||||
</div>
|
||||
<table class="layui-table" id="myTable" lay-filter="tools"></table>
|
||||
<script type="text/html" id="checkLock">
|
||||
<input shiro:hasAnyPermissions="admin,job:all,job:status" value="{{d.id}}" type="checkbox" name="status" lay-skin="switch" lay-text="启动|暂停" lay-event="lock" lay-filter="lockDemo" {{ d.status == 0 ? 'checked' : '' }}>
|
||||
</script>
|
||||
<script type="text/html" id="operation">
|
||||
<button shiro:hasAnyPermissions="admin,job:all,job:update" class="layui-btn layui-btn-xs" lay-event="edit">编辑</button>
|
||||
<button shiro:hasAnyPermissions="admin,job:all,job:delete" class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</button>
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/html" id="search_tpl_hash">
|
||||
<form class="layui-form" action="">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">Bean名称</label>
|
||||
<div class=layui-input-lump>
|
||||
<input type="text" name="beanName" placeholder="请输入Bean名称.." autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">方法名称</label>
|
||||
<div class=layui-input-lump>
|
||||
<input type="text" name="methodName" placeholder="请输入方法名称.." autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">任务备注</label>
|
||||
<div class=layui-input-lump>
|
||||
<input type="text" name="remark" placeholder="请输入备注.." autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">任务状态</label>
|
||||
<div class=layui-input-lump>
|
||||
<select name="status" lay-verify="">
|
||||
<option value="">请选择...</option>
|
||||
<option value="0">运行中</option>
|
||||
<option value="1">已暂停</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-lump">
|
||||
<button class="layui-btn" lay-submit lay-filter="formDemo_hash">搜索</button>
|
||||
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</script>
|
||||
<script>
|
||||
layui.use(['jquery', 'table', 'sidebar', 'form'], function () {
|
||||
var $ = layui.jquery,
|
||||
layer = layui.layer,
|
||||
table = layui.table,
|
||||
sidebar = layui.sidebar,
|
||||
form = layui.form;
|
||||
|
||||
//监听新增事件
|
||||
$('#add').on('click', function(){
|
||||
var index = layer.open({
|
||||
type: 2
|
||||
,content: '/job/toAddPage'
|
||||
,area: ['500px', '500px']
|
||||
,btnAlign: 'c'
|
||||
,shade: 0.8
|
||||
,maxmin: true
|
||||
,title: '新增任务'
|
||||
,btn: ['确认', '取消']
|
||||
,yes: function(){
|
||||
var body = layer.getChildFrame('body', index);
|
||||
add(layer,body);
|
||||
}
|
||||
});
|
||||
parent.layer.iframeAuto(index);
|
||||
});
|
||||
|
||||
//表格渲染
|
||||
table.render({
|
||||
elem: '#myTable'
|
||||
,url:'/job/getJobsInfo'
|
||||
,page: true
|
||||
,id:"ID"
|
||||
,cellMinWidth: 80 //全局定义常规单元格的最小宽度,layui 2.2.1 新增
|
||||
,cols: [
|
||||
[
|
||||
{field:'id',align:'center', width:100, title: '任务ID'}
|
||||
,{field:'beanName', title: 'Bean名称'}
|
||||
,{field:'methodName', title: '方法名'}
|
||||
,{field:'params', title: '参数'}
|
||||
,{field:'cronExpression', title: 'cron表达式'}
|
||||
,{field:'remark', title: '备注'}
|
||||
,{field:'updateTime', title: '更新日期',width:180}
|
||||
,{field:'lock', align: 'center', width: 120, toolbar: '#checkLock', title: '任务状态'}
|
||||
,{field:'operation',align:'center', width:150, toolbar: '#operation', title: '操作',fixed: 'right'}
|
||||
]
|
||||
]
|
||||
});
|
||||
|
||||
//监听搜索事件
|
||||
$('#search_hash').on('click', function () {
|
||||
var that = this;
|
||||
sidebar.render({
|
||||
elem: that,
|
||||
content: $('#search_tpl_hash').html(),
|
||||
title: '搜索',
|
||||
shade: true,
|
||||
width: '450px', //可以设置百分比和px
|
||||
done: function () {
|
||||
form.render();
|
||||
//监听提交
|
||||
form.on('submit(formDemo_hash)', function (data) {
|
||||
table.reload('ID', {
|
||||
where: {
|
||||
beanName: $('input[name="beanName"]').val(),
|
||||
methodName: $('input[name="methodName"]').val(),
|
||||
remark: $('input[name="remark"]').val(),
|
||||
status: $('select[name="status"]').val()
|
||||
}
|
||||
,page: {
|
||||
curr: 1 //重新从第 1 页开始
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// 监听状态事件
|
||||
form.on('switch(lockDemo)', function (data) {
|
||||
// 开关方法
|
||||
$.ajax({
|
||||
url: "/job/updateStatus?id="+this.value,
|
||||
type: "PUT",
|
||||
success: function(data){
|
||||
if (data.code == 200) {
|
||||
layer.msg(data.msg, {icon: 6, time: 1500});
|
||||
} else {
|
||||
layer.msg(data.msg, {icon: 5, time: 1500});
|
||||
setTimeout(function () {
|
||||
location.reload(true)
|
||||
},1500);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
//监听修改按钮
|
||||
table.on('tool(tools)', function(obj){
|
||||
var data = obj.data;
|
||||
if(obj.event === 'edit'){
|
||||
// 编辑
|
||||
var index = layer.open({
|
||||
type: 2
|
||||
,content: '/job/toUpdatePage?id='+data.id
|
||||
,area: ['500px', '500px']
|
||||
,btnAlign: 'c'
|
||||
,shade: 0.8
|
||||
,title: '编辑用户'
|
||||
,maxmin: true
|
||||
,btn: ['确认', '取消']
|
||||
,yes: function(){
|
||||
var body = layer.getChildFrame('body', index);
|
||||
update(layer,body);
|
||||
}
|
||||
});
|
||||
parent.layer.iframeAuto(index);
|
||||
//监听删除事件
|
||||
} else if(obj.event === 'del'){
|
||||
layer.confirm("你确定删除任务吗?", {icon: 3 ,btnAlign: 'c', title:'提示'},
|
||||
function(index){//确定回调
|
||||
// 写删除方法
|
||||
$.ajax({
|
||||
url: "/job/delete?id="+data.id,
|
||||
type: "DELETE",
|
||||
success: function(data){
|
||||
if (data.code == 200) {
|
||||
layer.close(index);
|
||||
layui.layer.msg("删除成功", {icon: 6});
|
||||
setTimeout(function () {
|
||||
table.reload('ID', {
|
||||
where: {}
|
||||
,page: {
|
||||
curr: 1
|
||||
}
|
||||
});
|
||||
},1000);
|
||||
} else {
|
||||
layer.close(index);
|
||||
layer.msg(data.msg, {icon: 5});
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* 新增
|
||||
* @param layer
|
||||
* @param body
|
||||
*/
|
||||
function add(layer,body) {
|
||||
$.ajax({
|
||||
url: "/job/insert",
|
||||
contentType: "application/json",
|
||||
type: "POST",
|
||||
data:JSON.stringify({
|
||||
beanName:body.contents().find("input[name=\"beanName\"]").val(),
|
||||
methodName:body.contents().find("input[name=\"methodName\"]").val(),
|
||||
remark:body.contents().find("textarea[name=\"remark\"]").val(),
|
||||
cronExpression:body.contents().find("input[name=\"cronExpression\"]").val(),
|
||||
params:body.contents().find("input[name=\"params\"]").val()
|
||||
}),
|
||||
dataType: "json",
|
||||
success: function(data){
|
||||
if(data.code==200){
|
||||
//同步更新表格和缓存对应的值
|
||||
layui.use(['jquery', 'layer'], function (){
|
||||
layer.closeAll();
|
||||
layui.layer.msg("添加成功", {icon: 6});
|
||||
setTimeout(function () {
|
||||
layui.table.reload('ID', {
|
||||
where: {}
|
||||
,page: {
|
||||
curr: 1 //重新从第 1 页开始
|
||||
}
|
||||
});
|
||||
},1000)
|
||||
});
|
||||
}else {
|
||||
layui.use(['jquery', 'layer'], function (){
|
||||
layui.layer.msg(data.msg, {icon: 5});
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新
|
||||
* @param layer
|
||||
* @param body
|
||||
*/
|
||||
function update(layer,body) {
|
||||
$.ajax({
|
||||
url: "/job/update",
|
||||
contentType: "application/json",
|
||||
type: "PUT",
|
||||
data:JSON.stringify({
|
||||
id:body.contents().find("input[name=\"id\"]").val(),
|
||||
beanName:body.contents().find("input[name=\"beanName\"]").val(),
|
||||
methodName:body.contents().find("input[name=\"methodName\"]").val(),
|
||||
remark:body.contents().find("textarea[name=\"remark\"]").val(),
|
||||
cronExpression:body.contents().find("input[name=\"cronExpression\"]").val(),
|
||||
params:body.contents().find("input[name=\"params\"]").val()
|
||||
}),
|
||||
dataType: "json",
|
||||
success: function(data){
|
||||
if(data.code==200){
|
||||
//同步更新表格和缓存对应的值
|
||||
layui.use(['jquery', 'layer'], function (){
|
||||
layer.closeAll();
|
||||
layui.layer.msg("修改成功", {icon: 6});
|
||||
setTimeout(function () {
|
||||
layui.table.reload('ID', {
|
||||
where: {}
|
||||
,page: {
|
||||
curr: 1 //重新从第 1 页开始
|
||||
}
|
||||
});
|
||||
},1000)
|
||||
});
|
||||
}else {
|
||||
layui.use(['jquery', 'layer'], function (){
|
||||
layui.layer.msg(data.msg, {icon: 5});
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
137
src/main/resources/templates/job/log.html
Normal file
137
src/main/resources/templates/job/log.html
Normal file
@@ -0,0 +1,137 @@
|
||||
<div class="layui-fluid">
|
||||
<div class="layui-row">
|
||||
<div class="layui-col-xs12">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">调度日志</div>
|
||||
<div class="layui-card-body">
|
||||
<div class="layui-card-header">
|
||||
<a href="javascript:;" class="layui-btn layui-btn-xs layui-btn-primary" id="search_hash">
|
||||
<i class="layui-icon"></i>
|
||||
</a>
|
||||
</div>
|
||||
<table class="layui-table" id="myTable" lay-filter="tools"></table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/html" id="search_tpl_hash">
|
||||
<form class="layui-form" action="">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">Bean名称</label>
|
||||
<div class=layui-input-lump>
|
||||
<input type="text" name="beanName" placeholder="请输入Bean名称.." autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">方法名称</label>
|
||||
<div class=layui-input-lump>
|
||||
<input type="text" name="methodName" placeholder="请输入方法名称.." autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">任务备注</label>
|
||||
<div class=layui-input-lump>
|
||||
<input type="text" name="remark" placeholder="请输入备注.." autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">任务状态</label>
|
||||
<div class=layui-input-lump>
|
||||
<select name="status" lay-verify="">
|
||||
<option value="">请选择...</option>
|
||||
<option value="0">成功</option>
|
||||
<option value="1">失败</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-lump">
|
||||
<button class="layui-btn" lay-submit lay-filter="formDemo_hash">搜索</button>
|
||||
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</script>
|
||||
<script>
|
||||
layui.use(['jquery', 'table', 'sidebar', 'form'], function () {
|
||||
var $ = layui.jquery,
|
||||
layer = layui.layer,
|
||||
table = layui.table,
|
||||
sidebar = layui.sidebar,
|
||||
form = layui.form;
|
||||
|
||||
//表格渲染
|
||||
table.render({
|
||||
elem: '#myTable'
|
||||
,url:'/jobLog/getJobLogsInfo'
|
||||
,page: true
|
||||
,id:"ID"
|
||||
,cellMinWidth: 80 //全局定义常规单元格的最小宽度,layui 2.2.1 新增
|
||||
,cols: [
|
||||
[
|
||||
{field:'id',align:'center', width:80, title: '编号'}
|
||||
,{field:'jobId',align:'center', width:87, title: '任务ID'}
|
||||
,{field:'beanName', title: 'Bean名称'}
|
||||
,{field:'methodName', title: '方法名'}
|
||||
,{field:'params', title: '参数'}
|
||||
,{field:'cronExpression', title: 'cron表达式'}
|
||||
,{field:'status', title: '状态'}
|
||||
,{field:'error', title: '错误信息'}
|
||||
,{field:'times', align:'center', title: '耗时(毫秒)', width:100}
|
||||
,{field:'createTime', title: '创建日期',width:185}
|
||||
]
|
||||
]
|
||||
,done:function(res, curr, count) { //res 接口返回的信息
|
||||
|
||||
$("td[data-field$='status']").children().each(function () {
|
||||
|
||||
if ($(this).text() == '1') {
|
||||
|
||||
$(this).text("失败");
|
||||
|
||||
} else if ($(this).text() == '0') {
|
||||
|
||||
$(this).text("成功");
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
$("td[data-field$='times']").children().each(function () {
|
||||
$(this).html("<span class=\"layui-badge\">"+$(this).text()+"</span>");
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
//监听搜索事件
|
||||
$('#search_hash').on('click', function () {
|
||||
var that = this;
|
||||
sidebar.render({
|
||||
elem: that,
|
||||
content: $('#search_tpl_hash').html(),
|
||||
title: '搜索',
|
||||
shade: true,
|
||||
width: '450px', //可以设置百分比和px
|
||||
done: function () {
|
||||
form.render();
|
||||
//监听提交
|
||||
form.on('submit(formDemo_hash)', function (data) {
|
||||
table.reload('ID', {
|
||||
where: {
|
||||
beanName: $('input[name="beanName"]').val(),
|
||||
methodName: $('input[name="methodName"]').val(),
|
||||
remark: $('input[name="remark"]').val(),
|
||||
status: $('select[name="status"]').val()
|
||||
}
|
||||
,page: {
|
||||
curr: 1 //重新从第 1 页开始
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
49
src/main/resources/templates/job/update.html
Normal file
49
src/main/resources/templates/job/update.html
Normal file
@@ -0,0 +1,49 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||
<title>Aurora- 新增任务</title>
|
||||
<!-- build:css -->
|
||||
<link rel="stylesheet" th:href="@{'/plugins/css/layui.css'}">
|
||||
<!-- endbuild -->
|
||||
</head>
|
||||
<body>
|
||||
<div style="padding: 10px; line-height: 15px; font-weight: 300;">
|
||||
<form class="layui-form layui-form-pane" action="">
|
||||
<input type="text" th:value="${job.id}" name="id" hidden="hidden">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">Bean名称</label>
|
||||
<div class=layui-input-lump>
|
||||
<input type="text" th:value="${job.beanName}" name="beanName" placeholder="请输入Bean名称.." autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">方法名称</label>
|
||||
<div class=layui-input-lump>
|
||||
<input type="text" th:value="${job.methodName}" name="methodName" placeholder="请输入方法名称.." autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">cron表达式</label>
|
||||
<div class=layui-input-lump>
|
||||
<input type="text" th:value="${job.cronExpression}" name="cronExpression" placeholder="请输入cron表达式.." autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">参数</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" th:value="${job.params}" name="params" lay-verify="required" placeholder="请输入参数.." autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item layui-form-text">
|
||||
<label class="layui-form-label">备注</label>
|
||||
<div class="layui-input-block">
|
||||
<textarea name="remark" placeholder="请输入备注.." class="layui-textarea">[[${job.remark}]]</textarea>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -7,9 +7,6 @@
|
||||
<script type="text/javascript" charset="utf-8" th:src="@{'/plugins/richText/all.min.js'}"> </script>
|
||||
<link rel="stylesheet" th:href="@{'/plugins/css/layui.css'}">
|
||||
<script type="text/javascript" charset="utf-8" th:src="@{'/plugins/richText/lang/zh-cn/zh-cn.js'}"></script>
|
||||
<style>
|
||||
.layui-form-label{float:left;display:block;padding:9px 15px;width:100px;font-weight:400;line-height:20px;text-align:right}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="layui-tab layui-tab-brief" lay-filter="docDemoTabBrief">
|
||||
@@ -44,7 +41,7 @@
|
||||
<div class="layui-form-mid layui-word-aux">注意,某些邮箱需要为SMTP服务单独设置密码</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label"><span class="layui-badge-dot"></span> SMTP地址</label>
|
||||
<label class="layui-form-label"><span class="layui-badge-dot"></span> SMTP</label>
|
||||
<div class="layui-input-inline" style="width: 40%">
|
||||
<input name="host" th:value="${email.host}" lay-verify="required" placeholder="请输入SMTP地址" autocomplete="off" class="layui-input" type="text">
|
||||
</div>
|
||||
@@ -52,9 +49,9 @@
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label"><span class="layui-badge-dot"></span> SMTP端口</label>
|
||||
<label class="layui-form-label"><span class="layui-badge-dot"></span> 端口</label>
|
||||
<div class="layui-input-inline" style="width: 40%">
|
||||
<input name="port" th:value="${email.port}" lay-verify="required" placeholder="请输入SMTP端口" autocomplete="off" class="layui-input" type="password">
|
||||
<input name="port" th:value="${email.port}" lay-verify="required" placeholder="请输入SMTP端口" autocomplete="off" class="layui-input" type="text">
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">邮件服务器SMTP端口</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user