Commit fd9fb2a6 authored by dqjdda's avatar dqjdda
Browse files

Merge branch '2.3dev'

parents 7895e547 1839ef8d
package me.zhengjie.config.thread;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* 线程池配置属性类
* @author https://juejin.im/entry/5abb8f6951882555677e9da2
* @date 2019年10月31日14:58:18
*/
@Data
@Component
@ConfigurationProperties(prefix = "task.pool")
public class AsyncTaskProperties {
private int corePoolSize;
private int maxPoolSize;
private int keepAliveSeconds;
private int queueCapacity;
}
package me.zhengjie.config.thread;
import org.springframework.stereotype.Component;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 自定义线程名称
* @author Zheng Jie
* @date 2019年10月31日17:49:55
*/
@Component
public class TheadFactoryName implements ThreadFactory {
private static final AtomicInteger poolNumber = new AtomicInteger(1);
private final ThreadGroup group;
private final AtomicInteger threadNumber = new AtomicInteger(1);
private final String namePrefix;
public TheadFactoryName() {
this("el-pool");
}
private TheadFactoryName(String name){
SecurityManager s = System.getSecurityManager();
group = (s != null) ? s.getThreadGroup() :
Thread.currentThread().getThreadGroup();
//此时namePrefix就是 name + 第几个用这个工厂创建线程池的
this.namePrefix = name +
poolNumber.getAndIncrement();
}
@Override
public Thread newThread(Runnable r) {
//此时线程的名字 就是 namePrefix + -thread- + 这个线程池中第几个执行的线程
Thread t = new Thread(group, r,
namePrefix + "-thread-"+threadNumber.getAndIncrement(),
0);
if (t.isDaemon()) {
t.setDaemon(false);
}
if (t.getPriority() != Thread.NORM_PRIORITY) {
t.setPriority(Thread.NORM_PRIORITY);
}
return t;
}
}
package me.zhengjie.config.thread;
import me.zhengjie.utils.SpringContextHolder;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* 用于获取自定义线程池
* @author Zheng Jie
* @date 2019年10月31日18:16:47
*/
public class ThreadPoolExecutorUtil {
public static ThreadPoolExecutor getPoll(){
AsyncTaskProperties properties = SpringContextHolder.getBean(AsyncTaskProperties.class);
return new ThreadPoolExecutor(
properties.getCorePoolSize(),
properties.getMaxPoolSize(),
properties.getKeepAliveSeconds(),
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(properties.getQueueCapacity()),
new TheadFactoryName()
);
}
}
package me.zhengjie.modules.monitor.config; package me.zhengjie.modules.monitor.config;
import me.zhengjie.modules.monitor.service.VisitsService; import me.zhengjie.modules.monitor.service.VisitsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner; import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
...@@ -13,11 +12,14 @@ import org.springframework.stereotype.Component; ...@@ -13,11 +12,14 @@ import org.springframework.stereotype.Component;
@Component @Component
public class VisitsInitialization implements ApplicationRunner { public class VisitsInitialization implements ApplicationRunner {
@Autowired private final VisitsService visitsService;
private VisitsService visitsService;
public VisitsInitialization(VisitsService visitsService) {
this.visitsService = visitsService;
}
@Override @Override
public void run(ApplicationArguments args) throws Exception { public void run(ApplicationArguments args){
System.out.println("--------------- 初始化站点统计,如果存在今日统计则跳过 ---------------"); System.out.println("--------------- 初始化站点统计,如果存在今日统计则跳过 ---------------");
visitsService.save(); visitsService.save();
System.out.println("--------------- 初始化站点统计完成 ---------------"); System.out.println("--------------- 初始化站点统计完成 ---------------");
......
...@@ -4,6 +4,7 @@ import lombok.Data; ...@@ -4,6 +4,7 @@ import lombok.Data;
import org.hibernate.annotations.CreationTimestamp; import org.hibernate.annotations.CreationTimestamp;
import javax.persistence.*; import javax.persistence.*;
import java.io.Serializable;
import java.sql.Timestamp; import java.sql.Timestamp;
/** /**
...@@ -15,7 +16,7 @@ import java.sql.Timestamp; ...@@ -15,7 +16,7 @@ import java.sql.Timestamp;
@Entity @Entity
@Data @Data
@Table(name = "visits") @Table(name = "visits")
public class Visits { public class Visits implements Serializable {
@Id @Id
@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(strategy = GenerationType.IDENTITY)
......
...@@ -4,7 +4,6 @@ import me.zhengjie.modules.monitor.domain.Visits; ...@@ -4,7 +4,6 @@ import me.zhengjie.modules.monitor.domain.Visits;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import java.util.List; import java.util.List;
/** /**
...@@ -16,18 +15,17 @@ public interface VisitsRepository extends JpaRepository<Visits,Long> { ...@@ -16,18 +15,17 @@ public interface VisitsRepository extends JpaRepository<Visits,Long> {
/** /**
* findByDate * findByDate
* @param date * @param date 日期
* @return * @return Visits
*/ */
Visits findByDate(String date); Visits findByDate(String date);
/** /**
* 获得一个时间段的记录 * 获得一个时间段的记录
* @param date1 * @param date1 日期1
* @param date2 * @param date2 日期2
* @return * @return List
*/ */
@Query(value = "select * FROM visits where " + @Query(value = "select * FROM visits where create_time between ?1 and ?2",nativeQuery = true)
"create_time between ?1 and ?2",nativeQuery = true)
List<Visits> findAllVisits(String date1, String date2); List<Visits> findAllVisits(String date1, String date2);
} }
package me.zhengjie.modules.monitor.rest; package me.zhengjie.modules.monitor.rest;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import me.zhengjie.annotation.AnonymousAccess;
import me.zhengjie.annotation.Limit; import me.zhengjie.annotation.Limit;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
...@@ -12,15 +16,19 @@ import java.util.concurrent.atomic.AtomicInteger; ...@@ -12,15 +16,19 @@ import java.util.concurrent.atomic.AtomicInteger;
* 接口限流测试类 * 接口限流测试类
*/ */
@RestController @RestController
@RequestMapping("api") @RequestMapping("/api/limit")
@Api(tags = "系统:限流测试管理")
public class LimitController { public class LimitController {
private static final AtomicInteger ATOMIC_INTEGER = new AtomicInteger(); private static final AtomicInteger ATOMIC_INTEGER = new AtomicInteger();
/** /**
* 测试限流注解,下面配置说明该接口 60秒内最多只能访问 10次,保存到redis的键名为 limit_test, * 测试限流注解,下面配置说明该接口 60秒内最多只能访问 10次,保存到redis的键名为 limit_test,
*/ */
@GetMapping
@PreAuthorize("@el.check('anonymous')")
@ApiOperation("测试")
@Limit(key = "test", period = 60, count = 10, name = "testLimit", prefix = "limit") @Limit(key = "test", period = 60, count = 10, name = "testLimit", prefix = "limit")
@GetMapping("/limit")
public int testLimit() { public int testLimit() {
return ATOMIC_INTEGER.incrementAndGet(); return ATOMIC_INTEGER.incrementAndGet();
} }
......
package me.zhengjie.modules.monitor.rest; package me.zhengjie.modules.monitor.rest;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import me.zhengjie.aop.log.Log; import me.zhengjie.aop.log.Log;
import me.zhengjie.modules.monitor.domain.vo.RedisVo; import me.zhengjie.modules.monitor.domain.vo.RedisVo;
import me.zhengjie.modules.monitor.service.RedisService; import me.zhengjie.modules.monitor.service.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/** /**
* @author Zheng Jie * @author Zheng Jie
* @date 2018-12-10 * @date 2018-12-10
*/ */
@RestController @RestController
@RequestMapping("api") @RequestMapping("/api/redis")
@Api(tags = "系统:Redis缓存管理")
public class RedisController { public class RedisController {
@Autowired private final RedisService redisService;
private RedisService redisService;
public RedisController(RedisService redisService) {
this.redisService = redisService;
}
@Log("查询Redis缓存") @Log("查询Redis缓存")
@GetMapping(value = "/redis") @GetMapping
@PreAuthorize("hasAnyRole('ADMIN','REDIS_ALL','REDIS_SELECT')") @ApiOperation("查询Redis缓存")
@PreAuthorize("@el.check('redis:list')")
public ResponseEntity getRedis(String key, Pageable pageable){ public ResponseEntity getRedis(String key, Pageable pageable){
return new ResponseEntity(redisService.findByKey(key,pageable), HttpStatus.OK); return new ResponseEntity<>(redisService.findByKey(key,pageable), HttpStatus.OK);
}
@Log("导出数据")
@ApiOperation("导出数据")
@GetMapping(value = "/download")
@PreAuthorize("@el.check('redis:list')")
public void download(HttpServletResponse response, String key) throws IOException {
redisService.download(redisService.findByKey(key), response);
} }
@Log("删除Redis缓存") @Log("删除Redis缓存")
@DeleteMapping(value = "/redis") @DeleteMapping
@PreAuthorize("hasAnyRole('ADMIN','REDIS_ALL','REDIS_DELETE')") @ApiOperation("删除Redis缓存")
@PreAuthorize("@el.check('redis:del')")
public ResponseEntity delete(@RequestBody RedisVo resources){ public ResponseEntity delete(@RequestBody RedisVo resources){
redisService.delete(resources.getKey()); redisService.delete(resources.getKey());
return new ResponseEntity(HttpStatus.OK); return new ResponseEntity(HttpStatus.OK);
} }
@Log("清空Redis缓存") @Log("清空Redis缓存")
@DeleteMapping(value = "/redis/all") @DeleteMapping(value = "/all")
@PreAuthorize("hasAnyRole('ADMIN','REDIS_ALL','REDIS_DELETE')") @ApiOperation("清空Redis缓存")
@PreAuthorize("@el.check('redis:del')")
public ResponseEntity deleteAll(){ public ResponseEntity deleteAll(){
redisService.flushdb(); redisService.deleteAll();
return new ResponseEntity(HttpStatus.OK); return new ResponseEntity(HttpStatus.OK);
} }
} }
package me.zhengjie.modules.monitor.rest; package me.zhengjie.modules.monitor.rest;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import me.zhengjie.modules.monitor.service.VisitsService; import me.zhengjie.modules.monitor.service.VisitsService;
import me.zhengjie.utils.RequestHolder; import me.zhengjie.utils.RequestHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
...@@ -15,25 +16,32 @@ import org.springframework.web.bind.annotation.RestController; ...@@ -15,25 +16,32 @@ import org.springframework.web.bind.annotation.RestController;
* @date 2018-12-13 * @date 2018-12-13
*/ */
@RestController @RestController
@RequestMapping("api") @RequestMapping("/api/visits")
@Api(tags = "系统:访问记录管理")
public class VisitsController { public class VisitsController {
@Autowired private final VisitsService visitsService;
private VisitsService visitsService;
@PostMapping(value = "/visits") public VisitsController(VisitsService visitsService) {
this.visitsService = visitsService;
}
@PostMapping
@ApiOperation("创建访问记录")
public ResponseEntity create(){ public ResponseEntity create(){
visitsService.count(RequestHolder.getHttpServletRequest()); visitsService.count(RequestHolder.getHttpServletRequest());
return new ResponseEntity(HttpStatus.CREATED); return new ResponseEntity(HttpStatus.CREATED);
} }
@GetMapping(value = "/visits") @GetMapping
@ApiOperation("查询")
public ResponseEntity get(){ public ResponseEntity get(){
return new ResponseEntity(visitsService.get(),HttpStatus.OK); return new ResponseEntity<>(visitsService.get(),HttpStatus.OK);
} }
@GetMapping(value = "/visits/chartData") @GetMapping(value = "/chartData")
@ApiOperation("查询图表数据")
public ResponseEntity getChartData(){ public ResponseEntity getChartData(){
return new ResponseEntity(visitsService.getChartData(),HttpStatus.OK); return new ResponseEntity<>(visitsService.getChartData(),HttpStatus.OK);
} }
} }
...@@ -4,6 +4,10 @@ import me.zhengjie.modules.monitor.domain.vo.RedisVo; ...@@ -4,6 +4,10 @@ import me.zhengjie.modules.monitor.domain.vo.RedisVo;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
/** /**
* 可自行扩展 * 可自行扩展
* @author Zheng Jie * @author Zheng Jie
...@@ -13,33 +17,47 @@ public interface RedisService { ...@@ -13,33 +17,47 @@ public interface RedisService {
/** /**
* findById * findById
* @param key * @param key
* @return * @return /
*/ */
Page findByKey(String key, Pageable pageable); Page findByKey(String key, Pageable pageable);
/**
* findById
* @param key 键
* @return /
*/
List<RedisVo> findByKey(String key);
/** /**
* 查询验证码的值 * 查询验证码的值
* @param key * @param key
* @return * @return /
*/ */
String getCodeVal(String key); String getCodeVal(String key);
/** /**
* 保存验证码 * 保存验证码
* @param key * @param key
* @param val * @param val
*/ */
void saveCode(String key, Object val); void saveCode(String key, Object val);
/** /**
* delete * delete
* @param key * @param key
*/ */
void delete(String key); void delete(String key);
/** /**
* 清空所有缓存 * 清空缓存
*/
void deleteAll();
/**
*
* @param redisVos /
* @param response /
*/ */
void flushdb(); void download(List<RedisVo> redisVos, HttpServletResponse response) throws IOException;
} }
package me.zhengjie.modules.monitor.service; package me.zhengjie.modules.monitor.service;
import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.Async;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
/** /**
...@@ -17,20 +16,20 @@ public interface VisitsService { ...@@ -17,20 +16,20 @@ public interface VisitsService {
/** /**
* 新增记录 * 新增记录
* @param request * @param request /
*/ */
@Async @Async
void count(HttpServletRequest request); void count(HttpServletRequest request);
/** /**
* 获取数据 * 获取数据
* @return * @return /
*/ */
Object get(); Object get();
/** /**
* getChartData * getChartData
* @return * @return /
*/ */
Object getChartData(); Object getChartData();
} }
package me.zhengjie.modules.monitor.service.impl; package me.zhengjie.modules.monitor.service.impl;
import cn.hutool.core.util.ObjectUtil;
import me.zhengjie.modules.monitor.domain.vo.RedisVo; import me.zhengjie.modules.monitor.domain.vo.RedisVo;
import me.zhengjie.modules.monitor.service.RedisService; import me.zhengjie.modules.monitor.service.RedisService;
import me.zhengjie.utils.FileUtil;
import me.zhengjie.utils.PageUtil; import me.zhengjie.utils.PageUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List; import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/** /**
* @author Zheng Jie * @author Zheng Jie
* @date 2018-12-10 * @date 2018-12-10
*/ */
@Service @Service
@SuppressWarnings({"unchecked","all"})
public class RedisServiceImpl implements RedisService { public class RedisServiceImpl implements RedisService {
@Autowired private final RedisTemplate redisTemplate;
RedisTemplate redisTemplate;
@Value("${loginCode.expiration}") @Value("${loginCode.expiration}")
private Long expiration; private Long expiration;
@Value("${jwt.online}")
private String onlineKey;
@Value("${jwt.codeKey}")
private String codeKey;
public RedisServiceImpl(RedisTemplate redisTemplate) {
this.redisTemplate = redisTemplate;
}
@Override @Override
public Page<RedisVo> findByKey(String key, Pageable pageable){ public Page<RedisVo> findByKey(String key, Pageable pageable){
List<RedisVo> redisVos = findByKey(key);
return new PageImpl<RedisVo>(
PageUtil.toPage(pageable.getPageNumber(),pageable.getPageSize(),redisVos),
pageable,
redisVos.size());
}
@Override
public List<RedisVo> findByKey(String key) {
List<RedisVo> redisVos = new ArrayList<>(); List<RedisVo> redisVos = new ArrayList<>();
if(!"*".equals(key)){ if(!"*".equals(key)){
key = "*" + key + "*"; key = "*" + key + "*";
} }
for (Object s : redisTemplate.keys(key)) { Set<String> keys = redisTemplate.keys(key);
for (String s : keys) {
// 过滤掉权限的缓存 // 过滤掉权限的缓存
if (s.toString().indexOf("role::loadPermissionByUser") != -1 || s.toString().indexOf("user::loadUserByUsername") != -1) { if (s.contains("role::loadPermissionByUser") || s.contains("user::loadUserByUsername") || s.contains(onlineKey) || s.contains(codeKey)) {
continue; continue;
} }
RedisVo redisVo = new RedisVo(s.toString(),redisTemplate.opsForValue().get(s.toString()).toString()); RedisVo redisVo = new RedisVo(s, Objects.requireNonNull(redisTemplate.opsForValue().get(s)).toString());
redisVos.add(redisVo); redisVos.add(redisVo);
} }
Page<RedisVo> page = new PageImpl<RedisVo>( return redisVos;
PageUtil.toPage(pageable.getPageNumber(),pageable.getPageSize(),redisVos),
pageable,
redisVos.size());
return page;
} }
@Override @Override
...@@ -54,15 +74,15 @@ public class RedisServiceImpl implements RedisService { ...@@ -54,15 +74,15 @@ public class RedisServiceImpl implements RedisService {
} }
@Override @Override
public void flushdb() { public void deleteAll() {
redisTemplate.getConnectionFactory().getConnection().flushDb(); Set<String> keys = redisTemplate.keys( "*");
redisTemplate.delete(keys.stream().filter(s -> !s.contains(onlineKey)).filter(s -> !s.contains(codeKey)).collect(Collectors.toList()));
} }
@Override @Override
public String getCodeVal(String key) { public String getCodeVal(String key) {
try { try {
String value = redisTemplate.opsForValue().get(key).toString(); return Objects.requireNonNull(redisTemplate.opsForValue().get(key)).toString();
return value;
}catch (Exception e){ }catch (Exception e){
return ""; return "";
} }
...@@ -73,4 +93,16 @@ public class RedisServiceImpl implements RedisService { ...@@ -73,4 +93,16 @@ public class RedisServiceImpl implements RedisService {
redisTemplate.opsForValue().set(key,val); redisTemplate.opsForValue().set(key,val);
redisTemplate.expire(key,expiration, TimeUnit.MINUTES); redisTemplate.expire(key,expiration, TimeUnit.MINUTES);
} }
@Override
public void download(List<RedisVo> redisVos, HttpServletResponse response) throws IOException {
List<Map<String, Object>> list = new ArrayList<>();
for (RedisVo redisVo : redisVos) {
Map<String,Object> map = new LinkedHashMap<>();
map.put("key", redisVo.getKey());
map.put("value", redisVo.getValue());
list.add(map);
}
FileUtil.downloadExcel(list, response);
}
} }
...@@ -26,11 +26,14 @@ import java.util.stream.Collectors; ...@@ -26,11 +26,14 @@ import java.util.stream.Collectors;
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class) @Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class VisitsServiceImpl implements VisitsService { public class VisitsServiceImpl implements VisitsService {
@Autowired private final VisitsRepository visitsRepository;
private VisitsRepository visitsRepository;
@Autowired private final LogRepository logRepository;
private LogRepository logRepository;
public VisitsServiceImpl(VisitsRepository visitsRepository, LogRepository logRepository) {
this.visitsRepository = visitsRepository;
this.logRepository = logRepository;
}
@Override @Override
public void save() { public void save() {
...@@ -58,7 +61,7 @@ public class VisitsServiceImpl implements VisitsService { ...@@ -58,7 +61,7 @@ public class VisitsServiceImpl implements VisitsService {
@Override @Override
public Object get() { public Object get() {
Map map = new HashMap(); Map<String,Object> map = new HashMap<>();
LocalDate localDate = LocalDate.now(); LocalDate localDate = LocalDate.now();
Visits visits = visitsRepository.findByDate(localDate.toString()); Visits visits = visitsRepository.findByDate(localDate.toString());
List<Visits> list = visitsRepository.findAllVisits(localDate.minusDays(6).toString(),localDate.plusDays(1).toString()); List<Visits> list = visitsRepository.findAllVisits(localDate.minusDays(6).toString(),localDate.plusDays(1).toString());
...@@ -77,7 +80,7 @@ public class VisitsServiceImpl implements VisitsService { ...@@ -77,7 +80,7 @@ public class VisitsServiceImpl implements VisitsService {
@Override @Override
public Object getChartData() { public Object getChartData() {
Map map = new HashMap(); Map<String,Object> map = new HashMap<>();
LocalDate localDate = LocalDate.now(); LocalDate localDate = LocalDate.now();
List<Visits> list = visitsRepository.findAllVisits(localDate.minusDays(6).toString(),localDate.plusDays(1).toString()); List<Visits> list = visitsRepository.findAllVisits(localDate.minusDays(6).toString(),localDate.plusDays(1).toString());
map.put("weekDays",list.stream().map(Visits::getWeekDay).collect(Collectors.toList())); map.put("weekDays",list.stream().map(Visits::getWeekDay).collect(Collectors.toList()));
......
...@@ -3,7 +3,6 @@ package me.zhengjie.modules.quartz.config; ...@@ -3,7 +3,6 @@ package me.zhengjie.modules.quartz.config;
import me.zhengjie.modules.quartz.domain.QuartzJob; import me.zhengjie.modules.quartz.domain.QuartzJob;
import me.zhengjie.modules.quartz.repository.QuartzJobRepository; import me.zhengjie.modules.quartz.repository.QuartzJobRepository;
import me.zhengjie.modules.quartz.utils.QuartzManage; import me.zhengjie.modules.quartz.utils.QuartzManage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner; import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
...@@ -17,24 +16,24 @@ import java.util.List; ...@@ -17,24 +16,24 @@ import java.util.List;
@Component @Component
public class JobRunner implements ApplicationRunner { public class JobRunner implements ApplicationRunner {
@Autowired private final QuartzJobRepository quartzJobRepository;
private QuartzJobRepository quartzJobRepository;
@Autowired private final QuartzManage quartzManage;
private QuartzManage quartzManage;
public JobRunner(QuartzJobRepository quartzJobRepository, QuartzManage quartzManage) {
this.quartzJobRepository = quartzJobRepository;
this.quartzManage = quartzManage;
}
/** /**
* 项目启动时重新激活启用的定时任务 * 项目启动时重新激活启用的定时任务
* @param applicationArguments * @param applicationArguments /
* @throws Exception
*/ */
@Override @Override
public void run(ApplicationArguments applicationArguments){ public void run(ApplicationArguments applicationArguments){
System.out.println("--------------------注入定时任务---------------------"); System.out.println("--------------------注入定时任务---------------------");
List<QuartzJob> quartzJobs = quartzJobRepository.findByIsPauseIsFalse(); List<QuartzJob> quartzJobs = quartzJobRepository.findByIsPauseIsFalse();
quartzJobs.forEach(quartzJob -> { quartzJobs.forEach(quartzManage::addJob);
quartzManage.addJob(quartzJob);
});
System.out.println("--------------------定时任务注入完成---------------------"); System.out.println("--------------------定时任务注入完成---------------------");
} }
} }
...@@ -2,7 +2,6 @@ package me.zhengjie.modules.quartz.config; ...@@ -2,7 +2,6 @@ package me.zhengjie.modules.quartz.config;
import org.quartz.Scheduler; import org.quartz.Scheduler;
import org.quartz.spi.TriggerFiredBundle; import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory; import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
...@@ -12,7 +11,7 @@ import org.springframework.stereotype.Component; ...@@ -12,7 +11,7 @@ import org.springframework.stereotype.Component;
/** /**
* 定时任务配置 * 定时任务配置
* @author * @author /
* @date 2019-01-07 * @date 2019-01-07
*/ */
@Configuration @Configuration
...@@ -22,10 +21,13 @@ public class QuartzConfig { ...@@ -22,10 +21,13 @@ public class QuartzConfig {
* 解决Job中注入Spring Bean为null的问题 * 解决Job中注入Spring Bean为null的问题
*/ */
@Component("quartzJobFactory") @Component("quartzJobFactory")
public class QuartzJobFactory extends AdaptableJobFactory { public static class QuartzJobFactory extends AdaptableJobFactory {
@Autowired private final AutowireCapableBeanFactory capableBeanFactory;
private AutowireCapableBeanFactory capableBeanFactory;
public QuartzJobFactory(AutowireCapableBeanFactory capableBeanFactory) {
this.capableBeanFactory = capableBeanFactory;
}
@Override @Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception { protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
...@@ -39,9 +41,9 @@ public class QuartzConfig { ...@@ -39,9 +41,9 @@ public class QuartzConfig {
/** /**
* 注入scheduler到spring * 注入scheduler到spring
* @param quartzJobFactory * @param quartzJobFactory /
* @return * @return Scheduler
* @throws Exception * @throws Exception /
*/ */
@Bean(name = "scheduler") @Bean(name = "scheduler")
public Scheduler scheduler(QuartzJobFactory quartzJobFactory) throws Exception { public Scheduler scheduler(QuartzJobFactory quartzJobFactory) throws Exception {
......
package me.zhengjie.modules.quartz.domain; package me.zhengjie.modules.quartz.domain;
import lombok.Data; import lombok.Getter;
import org.hibernate.annotations.UpdateTimestamp; import lombok.Setter;
import org.hibernate.annotations.CreationTimestamp;
import javax.persistence.*; import javax.persistence.*;
import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
...@@ -13,10 +13,11 @@ import java.sql.Timestamp; ...@@ -13,10 +13,11 @@ import java.sql.Timestamp;
* @author Zheng Jie * @author Zheng Jie
* @date 2019-01-07 * @date 2019-01-07
*/ */
@Data @Getter
@Setter
@Entity @Entity
@Table(name = "quartz_job") @Table(name = "quartz_job")
public class QuartzJob implements Serializable { public class QuartzJob implements Serializable {
public static final String JOB_KEY = "JOB_KEY"; public static final String JOB_KEY = "JOB_KEY";
...@@ -25,58 +26,41 @@ public class QuartzJob implements Serializable { ...@@ -25,58 +26,41 @@ public class QuartzJob implements Serializable {
@NotNull(groups = {Update.class}) @NotNull(groups = {Update.class})
private Long id; private Long id;
/** // 定时器名称
* 定时器名称
*/
@Column(name = "job_name") @Column(name = "job_name")
private String jobName; private String jobName;
/** // Bean名称
* Bean名称
*/
@Column(name = "bean_name") @Column(name = "bean_name")
@NotBlank @NotBlank
private String beanName; private String beanName;
/** // 方法名称
* 方法名称
*/
@Column(name = "method_name") @Column(name = "method_name")
@NotBlank @NotBlank
private String methodName; private String methodName;
/** // 参数
* 参数
*/
@Column(name = "params") @Column(name = "params")
private String params; private String params;
/** // cron表达式
* cron表达式
*/
@Column(name = "cron_expression") @Column(name = "cron_expression")
@NotBlank @NotBlank
private String cronExpression; private String cronExpression;
/** // 状态
* 状态
*/
@Column(name = "is_pause") @Column(name = "is_pause")
private Boolean isPause = false; private Boolean isPause = false;
/** // 备注
* 备注
*/
@Column(name = "remark") @Column(name = "remark")
@NotBlank @NotBlank
private String remark; private String remark;
/** @Column(name = "create_time")
* 创建日期 @CreationTimestamp
*/ private Timestamp createTime;
@UpdateTimestamp
@Column(name = "update_time")
private Timestamp updateTime;
public interface Update{} public @interface Update {}
} }
\ No newline at end of file
...@@ -20,56 +20,38 @@ public class QuartzLog implements Serializable { ...@@ -20,56 +20,38 @@ public class QuartzLog implements Serializable {
@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id; private Long id;
/** // 任务名称
* 任务名称
*/
@Column(name = "job_name") @Column(name = "job_name")
private String jobName; private String jobName;
/** // Bean名称
* Bean名称
*/
@Column(name = "baen_name") @Column(name = "baen_name")
private String beanName; private String beanName;
/** // 方法名称
* 方法名称
*/
@Column(name = "method_name") @Column(name = "method_name")
private String methodName; private String methodName;
/** // 参数
* 参数
*/
@Column(name = "params") @Column(name = "params")
private String params; private String params;
/** // cron表达式
* cron表达式
*/
@Column(name = "cron_expression") @Column(name = "cron_expression")
private String cronExpression; private String cronExpression;
/** // 状态
* 状态
*/
@Column(name = "is_success") @Column(name = "is_success")
private Boolean isSuccess; private Boolean isSuccess;
/** // 异常详细
* 异常详细
*/
@Column(name = "exception_detail",columnDefinition = "text") @Column(name = "exception_detail",columnDefinition = "text")
private String exceptionDetail; private String exceptionDetail;
/** // 耗时(毫秒)
* 耗时(毫秒)
*/
private Long time; private Long time;
/** // 创建日期
* 创建日期
*/
@CreationTimestamp @CreationTimestamp
@Column(name = "create_time") @Column(name = "create_time")
private Timestamp createTime; private Timestamp createTime;
......
...@@ -9,11 +9,11 @@ import java.util.List; ...@@ -9,11 +9,11 @@ import java.util.List;
* @author Zheng Jie * @author Zheng Jie
* @date 2019-01-07 * @date 2019-01-07
*/ */
public interface QuartzJobRepository extends JpaRepository<QuartzJob,Long>, JpaSpecificationExecutor { public interface QuartzJobRepository extends JpaRepository<QuartzJob,Long>, JpaSpecificationExecutor<QuartzJob> {
/** /**
* 查询启用的任务 * 查询启用的任务
* @return * @return List
*/ */
List<QuartzJob> findByIsPauseIsFalse(); List<QuartzJob> findByIsPauseIsFalse();
} }
...@@ -8,6 +8,6 @@ import org.springframework.data.jpa.repository.JpaSpecificationExecutor; ...@@ -8,6 +8,6 @@ import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
* @author Zheng Jie * @author Zheng Jie
* @date 2019-01-07 * @date 2019-01-07
*/ */
public interface QuartzLogRepository extends JpaRepository<QuartzLog,Long>, JpaSpecificationExecutor { public interface QuartzLogRepository extends JpaRepository<QuartzLog,Long>, JpaSpecificationExecutor<QuartzLog> {
} }
package me.zhengjie.modules.quartz.rest; package me.zhengjie.modules.quartz.rest;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import me.zhengjie.aop.log.Log; import me.zhengjie.aop.log.Log;
import me.zhengjie.exception.BadRequestException; import me.zhengjie.exception.BadRequestException;
import me.zhengjie.modules.quartz.domain.QuartzJob; import me.zhengjie.modules.quartz.domain.QuartzJob;
import me.zhengjie.modules.quartz.service.QuartzJobService; import me.zhengjie.modules.quartz.service.QuartzJobService;
import me.zhengjie.modules.quartz.service.dto.JobQueryCriteria; import me.zhengjie.modules.quartz.service.dto.JobQueryCriteria;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
...@@ -14,70 +15,100 @@ import org.springframework.security.access.prepost.PreAuthorize; ...@@ -14,70 +15,100 @@ import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/** /**
* @author Zheng Jie * @author Zheng Jie
* @date 2019-01-07 * @date 2019-01-07
*/ */
@Slf4j @Slf4j
@RestController @RestController
@RequestMapping("/api") @Api(tags = "系统:定时任务管理")
@RequestMapping("/api/jobs")
public class QuartzJobController { public class QuartzJobController {
private static final String ENTITY_NAME = "quartzJob"; private static final String ENTITY_NAME = "quartzJob";
@Autowired private final QuartzJobService quartzJobService;
private QuartzJobService quartzJobService;
public QuartzJobController(QuartzJobService quartzJobService) {
this.quartzJobService = quartzJobService;
}
@Log("查询定时任务") @Log("查询定时任务")
@GetMapping(value = "/jobs") @ApiOperation("查询定时任务")
@PreAuthorize("hasAnyRole('ADMIN','JOB_ALL','JOB_SELECT')") @GetMapping
@PreAuthorize("@el.check('timing:list')")
public ResponseEntity getJobs(JobQueryCriteria criteria, Pageable pageable){ public ResponseEntity getJobs(JobQueryCriteria criteria, Pageable pageable){
return new ResponseEntity(quartzJobService.queryAll(criteria,pageable), HttpStatus.OK); return new ResponseEntity<>(quartzJobService.queryAll(criteria,pageable), HttpStatus.OK);
}
@Log("导出任务数据")
@ApiOperation("导出任务数据")
@GetMapping(value = "/download")
@PreAuthorize("@el.check('timing:list')")
public void download(HttpServletResponse response, JobQueryCriteria criteria) throws IOException {
quartzJobService.download(quartzJobService.queryAll(criteria), response);
}
@Log("导出日志数据")
@ApiOperation("导出日志数据")
@GetMapping(value = "/download/log")
@PreAuthorize("@el.check('timing:list')")
public void downloadLog(HttpServletResponse response, JobQueryCriteria criteria) throws IOException {
quartzJobService.downloadLog(quartzJobService.queryAllLog(criteria), response);
} }
@GetMapping(value = "/jobLogs") @ApiOperation("查询任务执行日志")
@PreAuthorize("hasAnyRole('ADMIN','JOB_ALL','JOB_SELECT')") @GetMapping(value = "/logs")
@PreAuthorize("@el.check('timing:list')")
public ResponseEntity getJobLogs(JobQueryCriteria criteria, Pageable pageable){ public ResponseEntity getJobLogs(JobQueryCriteria criteria, Pageable pageable){
return new ResponseEntity(quartzJobService.queryAllLog(criteria,pageable), HttpStatus.OK); return new ResponseEntity<>(quartzJobService.queryAllLog(criteria,pageable), HttpStatus.OK);
} }
@Log("新增定时任务") @Log("新增定时任务")
@PostMapping(value = "/jobs") @ApiOperation("新增定时任务")
@PreAuthorize("hasAnyRole('ADMIN','JOB_ALL','JOB_CREATE')") @PostMapping
@PreAuthorize("@el.check('timing:add')")
public ResponseEntity create(@Validated @RequestBody QuartzJob resources){ public ResponseEntity create(@Validated @RequestBody QuartzJob resources){
if (resources.getId() != null) { if (resources.getId() != null) {
throw new BadRequestException("A new "+ ENTITY_NAME +" cannot already have an ID"); throw new BadRequestException("A new "+ ENTITY_NAME +" cannot already have an ID");
} }
return new ResponseEntity(quartzJobService.create(resources),HttpStatus.CREATED); return new ResponseEntity<>(quartzJobService.create(resources),HttpStatus.CREATED);
} }
@Log("修改定时任务") @Log("修改定时任务")
@PutMapping(value = "/jobs") @ApiOperation("修改定时任务")
@PreAuthorize("hasAnyRole('ADMIN','JOB_ALL','JOB_EDIT')") @PutMapping
@PreAuthorize("@el.check('timing:edit')")
public ResponseEntity update(@Validated(QuartzJob.Update.class) @RequestBody QuartzJob resources){ public ResponseEntity update(@Validated(QuartzJob.Update.class) @RequestBody QuartzJob resources){
quartzJobService.update(resources); quartzJobService.update(resources);
return new ResponseEntity(HttpStatus.NO_CONTENT); return new ResponseEntity(HttpStatus.NO_CONTENT);
} }
@Log("更改定时任务状态") @Log("更改定时任务状态")
@PutMapping(value = "/jobs/{id}") @ApiOperation("更改定时任务状态")
@PreAuthorize("hasAnyRole('ADMIN','JOB_ALL','JOB_EDIT')") @PutMapping(value = "/{id}")
@PreAuthorize("@el.check('timing:edit')")
public ResponseEntity updateIsPause(@PathVariable Long id){ public ResponseEntity updateIsPause(@PathVariable Long id){
quartzJobService.updateIsPause(quartzJobService.findById(id)); quartzJobService.updateIsPause(quartzJobService.findById(id));
return new ResponseEntity(HttpStatus.NO_CONTENT); return new ResponseEntity(HttpStatus.NO_CONTENT);
} }
@Log("执行定时任务") @Log("执行定时任务")
@PutMapping(value = "/jobs/exec/{id}") @ApiOperation("执行定时任务")
@PreAuthorize("hasAnyRole('ADMIN','JOB_ALL','JOB_EDIT')") @PutMapping(value = "/exec/{id}")
@PreAuthorize("@el.check('timing:edit')")
public ResponseEntity execution(@PathVariable Long id){ public ResponseEntity execution(@PathVariable Long id){
quartzJobService.execution(quartzJobService.findById(id)); quartzJobService.execution(quartzJobService.findById(id));
return new ResponseEntity(HttpStatus.NO_CONTENT); return new ResponseEntity(HttpStatus.NO_CONTENT);
} }
@Log("删除定时任务") @Log("删除定时任务")
@DeleteMapping(value = "/jobs/{id}") @ApiOperation("删除定时任务")
@PreAuthorize("hasAnyRole('ADMIN','JOB_ALL','JOB_DELETE')") @DeleteMapping(value = "/{id}")
@PreAuthorize("@el.check('timing:del')")
public ResponseEntity delete(@PathVariable Long id){ public ResponseEntity delete(@PathVariable Long id){
quartzJobService.delete(quartzJobService.findById(id)); quartzJobService.delete(quartzJobService.findById(id));
return new ResponseEntity(HttpStatus.OK); return new ResponseEntity(HttpStatus.OK);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment