├── .gitignore ├── src ├── main │ ├── java │ │ └── com │ │ │ └── quartz │ │ │ └── cn │ │ │ └── springbootquartzdemo │ │ │ ├── service │ │ │ └── quartz │ │ │ │ ├── QuartzTaskErrorsService.java │ │ │ │ ├── QuartzTaskRecordsService.java │ │ │ │ ├── QuartzTaskInformationsService.java │ │ │ │ ├── impl │ │ │ │ ├── QuartzTaskErrorsServiceImpl.java │ │ │ │ ├── QuartzTaskRecordsServiceImpl.java │ │ │ │ ├── QuartzTaskInformationsServiceImpl.java │ │ │ │ └── QuartzServiceImpl.java │ │ │ │ └── QuartzService.java │ │ │ ├── dao │ │ │ ├── QuartzTaskRecordsMapper.java │ │ │ ├── QuartzTaskErrorsMapper.java │ │ │ └── QuartzTaskInformationsMapper.java │ │ │ ├── util │ │ │ ├── CommonUtil.java │ │ │ ├── ApplicationContextHolder.java │ │ │ ├── ResultUtil.java │ │ │ ├── ResultEnum.java │ │ │ ├── Result.java │ │ │ ├── Page.java │ │ │ └── HttpClientUtil.java │ │ │ ├── SpringbootQuartzDemoApplication.java │ │ │ ├── bean │ │ │ ├── QuartzTaskErrors.java │ │ │ ├── QuartzTaskRecords.java │ │ │ └── QuartzTaskInformations.java │ │ │ ├── controller │ │ │ ├── IndexController.java │ │ │ └── QuartzController.java │ │ │ ├── job │ │ │ ├── KafkaListener.java │ │ │ └── QuartzMainJobFactory.java │ │ │ └── vo │ │ │ └── QuartzTaskRecordsVo.java │ └── resources │ │ ├── static │ │ ├── css │ │ │ ├── reset.css │ │ │ ├── red.css │ │ │ ├── aero.css │ │ │ ├── supersized.css │ │ │ ├── loginstyle.css │ │ │ ├── simple-line-icons.css │ │ │ └── font-awesome.min.css │ │ └── js │ │ │ ├── supersized-init.js │ │ │ └── supersized.3.2.7.min.js │ │ ├── application.yml │ │ ├── db │ │ └── db.sql │ │ ├── templates │ │ ├── login.html │ │ ├── login666.html │ │ ├── taskerrors.html │ │ ├── taskrecords.html │ │ ├── addtask.html │ │ ├── index.html │ │ └── updatetask.html │ │ └── mapper │ │ ├── QuartzTaskErrorsMapper.xml │ │ ├── QuartzTaskRecordsMapper.xml │ │ └── QuartzTaskInformationsMapper.xml └── test │ └── java │ └── com │ └── quartz │ └── cn │ └── springbootquartzdemo │ └── SpringbootQuartzDemoApplicationTests.java ├── README.md └── pom.xml /.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | 4 | ### STS ### 5 | .apt_generated 6 | .classpath 7 | .factorypath 8 | .project 9 | .settings 10 | .springBeans 11 | .sts4-cache 12 | 13 | ### IntelliJ IDEA ### 14 | .idea 15 | *.iws 16 | *.iml 17 | *.ipr 18 | 19 | ### NetBeans ### 20 | /nbproject/private/ 21 | /build/ 22 | /nbbuild/ 23 | /dist/ 24 | /nbdist/ 25 | /.nb-gradle/ -------------------------------------------------------------------------------- /src/main/java/com/quartz/cn/springbootquartzdemo/service/quartz/QuartzTaskErrorsService.java: -------------------------------------------------------------------------------- 1 | package com.quartz.cn.springbootquartzdemo.service.quartz; 2 | 3 | import com.quartz.cn.springbootquartzdemo.bean.QuartzTaskErrors; 4 | 5 | public interface QuartzTaskErrorsService { 6 | Integer addTaskErrorRecord(QuartzTaskErrors quartzTaskErrors); 7 | 8 | QuartzTaskErrors detailTaskErrors(String recordId); 9 | } 10 | -------------------------------------------------------------------------------- /src/test/java/com/quartz/cn/springbootquartzdemo/SpringbootQuartzDemoApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.quartz.cn.springbootquartzdemo; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class SpringbootQuartzDemoApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | 18 | -------------------------------------------------------------------------------- /src/main/java/com/quartz/cn/springbootquartzdemo/service/quartz/QuartzTaskRecordsService.java: -------------------------------------------------------------------------------- 1 | package com.quartz.cn.springbootquartzdemo.service.quartz; 2 | 3 | import com.quartz.cn.springbootquartzdemo.bean.QuartzTaskRecords; 4 | 5 | import java.util.List; 6 | 7 | public interface QuartzTaskRecordsService { 8 | 9 | long addTaskRecords(QuartzTaskRecords quartzTaskRecords); 10 | 11 | Integer updateTaskRecords(QuartzTaskRecords quartzTaskRecords); 12 | 13 | List listTaskRecordsByTaskNo(String taskNo); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/quartz/cn/springbootquartzdemo/dao/QuartzTaskRecordsMapper.java: -------------------------------------------------------------------------------- 1 | package com.quartz.cn.springbootquartzdemo.dao; 2 | 3 | 4 | import com.quartz.cn.springbootquartzdemo.bean.QuartzTaskRecords; 5 | import org.apache.ibatis.annotations.Mapper; 6 | 7 | import java.util.List; 8 | 9 | @Mapper 10 | public interface QuartzTaskRecordsMapper { 11 | int deleteByPrimaryKey(Long id); 12 | 13 | long insert(QuartzTaskRecords record); 14 | 15 | int insertSelective(QuartzTaskRecords record); 16 | 17 | QuartzTaskRecords selectByPrimaryKey(Long id); 18 | 19 | int updateByPrimaryKeySelective(QuartzTaskRecords record); 20 | 21 | int updateByPrimaryKey(QuartzTaskRecords record); 22 | 23 | List getTaskRecordsByTaskNo(String taskNo); 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/quartz/cn/springbootquartzdemo/dao/QuartzTaskErrorsMapper.java: -------------------------------------------------------------------------------- 1 | package com.quartz.cn.springbootquartzdemo.dao; 2 | 3 | 4 | import com.quartz.cn.springbootquartzdemo.bean.QuartzTaskErrors; 5 | import org.apache.ibatis.annotations.Mapper; 6 | 7 | @Mapper 8 | public interface QuartzTaskErrorsMapper { 9 | int deleteByPrimaryKey(Long id); 10 | 11 | int insert(QuartzTaskErrors record); 12 | 13 | int insertSelective(QuartzTaskErrors record); 14 | 15 | QuartzTaskErrors selectByPrimaryKey(Long id); 16 | 17 | int updateByPrimaryKeySelective(QuartzTaskErrors record); 18 | 19 | int updateByPrimaryKeyWithBLOBs(QuartzTaskErrors record); 20 | 21 | int updateByPrimaryKey(QuartzTaskErrors record); 22 | 23 | QuartzTaskErrors detailTaskErrors(String recordId); 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/quartz/cn/springbootquartzdemo/util/CommonUtil.java: -------------------------------------------------------------------------------- 1 | package com.quartz.cn.springbootquartzdemo.util; 2 | 3 | import java.io.PrintWriter; 4 | import java.io.StringWriter; 5 | 6 | /** 7 | * @ClassName CommonUtil 8 | * @Description 通用工具类 9 | * @Author simonsfan 10 | * @Date 2019/1/8 11 | * Version 1.0 12 | */ 13 | public class CommonUtil { 14 | 15 | /** 16 | * 获取具体的异常信息 17 | * 18 | * @param ex 19 | * @return 20 | */ 21 | public static String getExceptionDetail(Exception ex) { 22 | StringWriter sw = new StringWriter(); 23 | PrintWriter pw = new PrintWriter(sw); 24 | try { 25 | ex.printStackTrace(pw); 26 | return sw.toString(); 27 | } finally { 28 | pw.close(); 29 | } 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/quartz/cn/springbootquartzdemo/util/ApplicationContextHolder.java: -------------------------------------------------------------------------------- 1 | package com.quartz.cn.springbootquartzdemo.util; 2 | 3 | import org.springframework.beans.BeansException; 4 | import org.springframework.context.ApplicationContext; 5 | import org.springframework.context.ApplicationContextAware; 6 | import org.springframework.stereotype.Component; 7 | 8 | /** 9 | * 类描述:获取Spring代理类(上下文) 10 | */ 11 | @Component 12 | public class ApplicationContextHolder implements ApplicationContextAware { 13 | 14 | private static ApplicationContext context; 15 | 16 | @Override 17 | public void setApplicationContext(ApplicationContext applicationcontext) 18 | throws BeansException { 19 | ApplicationContextHolder.context = applicationcontext; 20 | } 21 | 22 | public static Object getBean(String beanName) { 23 | return context.getBean(beanName); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/quartz/cn/springbootquartzdemo/SpringbootQuartzDemoApplication.java: -------------------------------------------------------------------------------- 1 | package com.quartz.cn.springbootquartzdemo; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.builder.SpringApplicationBuilder; 6 | import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; 7 | import org.springframework.transaction.annotation.EnableTransactionManagement; 8 | 9 | @SpringBootApplication 10 | public class SpringbootQuartzDemoApplication extends SpringBootServletInitializer { 11 | 12 | public static void main(String[] args) { 13 | SpringApplication.run(SpringbootQuartzDemoApplication.class, args); 14 | } 15 | 16 | @Override 17 | protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { 18 | return builder.sources(SpringbootQuartzDemoApplication.class); 19 | } 20 | } 21 | 22 | -------------------------------------------------------------------------------- /src/main/java/com/quartz/cn/springbootquartzdemo/service/quartz/QuartzTaskInformationsService.java: -------------------------------------------------------------------------------- 1 | package com.quartz.cn.springbootquartzdemo.service.quartz; 2 | 3 | 4 | import com.quartz.cn.springbootquartzdemo.bean.QuartzTaskInformations; 5 | 6 | import java.util.List; 7 | 8 | public interface QuartzTaskInformationsService { 9 | String insert(QuartzTaskInformations quartzTaskInformations); 10 | 11 | List selectList(String taskNo, String currentPage); 12 | 13 | QuartzTaskInformations getTaskById(String id); 14 | 15 | String updateTask(QuartzTaskInformations quartzTaskInformations); 16 | 17 | QuartzTaskInformations getTaskByTaskNo(String taskNo); 18 | 19 | Integer updateStatusById(QuartzTaskInformations quartzTaskInformations); 20 | 21 | List getUnnfrozenTasks(String status); 22 | 23 | Integer updateModifyTimeById(QuartzTaskInformations quartzTaskInformations); 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/quartz/cn/springbootquartzdemo/util/ResultUtil.java: -------------------------------------------------------------------------------- 1 | package com.quartz.cn.springbootquartzdemo.util; 2 | 3 | 4 | import com.google.gson.Gson; 5 | 6 | /** 7 | * @ClassName ResultUtil 8 | * @Description TODO 9 | * @Author simonsfan 10 | * @Date 2019/1/1 11 | * Version 1.0 12 | */ 13 | public class ResultUtil { 14 | 15 | public static String success() { 16 | Result result = new Result(ResultEnum.SUCCESS); 17 | return new Gson().toJson(result); 18 | } 19 | 20 | public static String success(Object obj) { 21 | Result result = new Result(ResultEnum.SUCCESS, obj); 22 | return new Gson().toJson(result); 23 | } 24 | 25 | public static String fail() { 26 | Result result = new Result(ResultEnum.FAIL); 27 | return new Gson().toJson(result); 28 | } 29 | 30 | public static String success(Integer code, String message) { 31 | Result result = new Result(code, message); 32 | return new Gson().toJson(result); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/quartz/cn/springbootquartzdemo/dao/QuartzTaskInformationsMapper.java: -------------------------------------------------------------------------------- 1 | package com.quartz.cn.springbootquartzdemo.dao; 2 | 3 | 4 | import com.quartz.cn.springbootquartzdemo.bean.QuartzTaskInformations; 5 | import org.apache.ibatis.annotations.Mapper; 6 | 7 | import java.util.List; 8 | import java.util.Map; 9 | 10 | @Mapper 11 | public interface QuartzTaskInformationsMapper { 12 | int deleteByPrimaryKey(Long id); 13 | 14 | int insert(QuartzTaskInformations record); 15 | 16 | int insertSelective(QuartzTaskInformations record); 17 | 18 | QuartzTaskInformations selectByPrimaryKey(Long id); 19 | 20 | int updateByPrimaryKeySelective(QuartzTaskInformations record); 21 | 22 | int updateByPrimaryKey(QuartzTaskInformations record); 23 | 24 | List selectList(Map map); 25 | 26 | Integer selectByTaskNo(String taskNo); 27 | 28 | QuartzTaskInformations getTaskByTaskNo(String taskNo); 29 | 30 | List getUnfrozenTasks(String status); 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/quartz/cn/springbootquartzdemo/util/ResultEnum.java: -------------------------------------------------------------------------------- 1 | package com.quartz.cn.springbootquartzdemo.util; 2 | 3 | /** 4 | * @ClassName ResultEnum 5 | * @Description 定义接口统一返回的code、message,方便维护 6 | * @Author simonsfan 7 | * @Date 2019/1/1 8 | * Version 1.0 9 | */ 10 | public enum ResultEnum { 11 | SUCCESS(200,"success"), 12 | FAIL(500,"system error"), 13 | INIT(600,"record init"), 14 | 15 | TASKNO_EXIST(1001,"该任务编号已经存在"), 16 | 17 | PARAM_EMPTY(6001,"parameter is empty"), 18 | 19 | 20 | FROZEN(10001,"FROZEN"), 21 | UNFROZEN(10002,"UNFROZEN"), 22 | 23 | RUN_NOW_FAIL(7001,"立即运行失败"), 24 | 25 | HTTP(10003,"http"), 26 | KAFKA(10004,"kafka"), 27 | 28 | UPDATE_FAIL(1002,"更新失败"), 29 | NO_DATA(1003,"无此定时任务编号"); 30 | 31 | 32 | 33 | private Integer code; 34 | private String message; 35 | 36 | public Integer getCode() { 37 | return code; 38 | } 39 | 40 | public String getMessage() { 41 | return message; 42 | } 43 | 44 | ResultEnum(Integer code, String message) { 45 | this.code = code; 46 | this.message = message; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/quartz/cn/springbootquartzdemo/service/quartz/impl/QuartzTaskErrorsServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.quartz.cn.springbootquartzdemo.service.quartz.impl; 2 | 3 | import com.quartz.cn.springbootquartzdemo.bean.QuartzTaskErrors; 4 | import com.quartz.cn.springbootquartzdemo.dao.QuartzTaskErrorsMapper; 5 | import com.quartz.cn.springbootquartzdemo.service.quartz.QuartzTaskErrorsService; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Service; 8 | 9 | /** 10 | * @ClassName QuartzTaskErrorsServiceImpl 11 | * @Description TODO 12 | * @Author simonsfan 13 | * @Date 2019/1/3 14 | * Version 1.0 15 | */ 16 | @Service 17 | public class QuartzTaskErrorsServiceImpl implements QuartzTaskErrorsService { 18 | 19 | @Autowired 20 | private QuartzTaskErrorsMapper quartzTaskErrorsMapper; 21 | 22 | @Override 23 | public Integer addTaskErrorRecord(QuartzTaskErrors quartzTaskErrors) { 24 | return quartzTaskErrorsMapper.insert(quartzTaskErrors); 25 | } 26 | 27 | @Override 28 | public QuartzTaskErrors detailTaskErrors(String recordId) { 29 | return quartzTaskErrorsMapper.detailTaskErrors(recordId); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/resources/static/css/reset.css: -------------------------------------------------------------------------------- 1 | 2 | /* ------- This is the CSS Reset ------- */ 3 | 4 | html, body, div, span, applet, object, iframe, 5 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, 6 | abbr, acronym, address, big, cite, code, del, 7 | dfn, em, img, ins, kbd, q, s, samp, small, 8 | strike, strong, sub, sup, tt, var, u, i, center, 9 | dl, dt, dd, ol, ul, li, fieldset, form, label, 10 | legend, table, caption, tbody, tfoot, thead, tr, 11 | th, td, article, aside, canvas, details, embed, 12 | figure, figcaption, footer, header, hgroup, menu, 13 | nav, output, ruby, section, summary, time, mark, audio, video { 14 | margin: 0; 15 | padding: 0; 16 | border: 0; 17 | font-size: 100%; 18 | font: inherit; 19 | vertical-align: baseline; 20 | } 21 | 22 | /* ------- HTML5 display-role reset for older browsers ------- */ 23 | 24 | article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { 25 | display: block; 26 | } 27 | body { 28 | line-height: 1; 29 | } 30 | ol, ul { 31 | list-style: none; 32 | } 33 | blockquote, q { 34 | quotes: none; 35 | } 36 | blockquote:before, blockquote:after, q:before, q:after { 37 | content: ''; 38 | content: none; 39 | } 40 | table { 41 | border-collapse: collapse; 42 | border-spacing: 0; 43 | } 44 | 45 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![](https://img.shields.io/badge/master分支-green.svg?logo=appveyor&style=for-the-badge) ![](https://img.shields.io/badge/quartz实现定制化定时任务-green.svg?logo=appveyor&style=for-the-badge) 2 | > ## master分支上是使用springboot+quartz+mysql+kafka实现定制化定时任务功能 3 | > * 系统启动初始化加载已有的定时任务 4 | > * 启动or暂停定时任务 5 | > * 立即运行定时任务 6 | > * 实时新增及修改定时任务 7 | > * 定时任务的详细监控 8 | > * 博客地址: [使用quartz实现定时任务定制化](https://blog.csdn.net/fanrenxiang/article/details/85539918) 9 | > * 注意此项目需要kafka服务,新手请参照kafka官网http://kafka.apache.org/quickstart安装启动 10 | 11 | 12 | > ## 定时任务界面效果图 13 | ![定时任务界面效果图](https://img-blog.csdnimg.cn/20190110162200891.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZhbnJlbnhpYW5n,size_16,color_FFFFFF,t_70) 14 | 15 | *** 16 | ![](https://img.shields.io/badge/feature_es分支-green.svg?logo=appveyor&style=for-the-badge) ![](https://img.shields.io/badge/ElasticSearch实现搜索引擎-green.svg?logo=appveyor&style=for-the-badge) 17 | > ## feature_es分支上是用springboot结合elastic search做的搜索引擎 18 | > * 博客地址: [elastic search java api及其实战demo](https://blog.csdn.net/fanrenxiang/article/details/86509688) 19 | > * 注意:这个项目里面也需要kafka,里面有很多东西需要完善,但是基本的搜索功能是有的,有兴趣的小伙伴可以自行研究完善 20 | > ## 搜索界面效果如下图: 21 | ![电影搜索引擎效果图](https://img-blog.csdnimg.cn/20190121134035650.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZhbnJlbnhpYW5n,size_16,color_FFFFFF,t_70) 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | # mybatis 2 | mybatis: 3 | type-aliases-package: com.quartz.cn.springbootquartzdemo.bean 4 | configuration: 5 | map-underscore-to-camel-case: true 6 | default-fetch-size: 100 7 | default-statement-timeout: 3000 8 | mapper-locations: classpath:mapper/*.xml 9 | 10 | spring: 11 | datasource: 12 | url: jdbc:mysql://10.200.20.194:3306/quartz?useUnicode=true&characterEncoding=utf-8 13 | username: root 14 | password: root 15 | driver-class-name: com.mysql.jdbc.Driver 16 | type: com.alibaba.druid.pool.DruidDataSource 17 | filters: stat 18 | maxActive: 1000 19 | initialSize: 100 20 | maxWait: 60000 21 | minIdle: 500 22 | timeBetweenEvictionRunsMillis: 60000 23 | minEvictableIdleTimeMillis: 300000 24 | validationQuery: select 'x' 25 | testWhileIdle: true 26 | testOnBorrow: false 27 | testOnReturn: false 28 | poolPreparedStatements: true 29 | maxOpenPreparedStatements: 20 30 | kafka: 31 | bootstrap-servers: 10.200.20.194:9092 32 | consumer: 33 | group-id: quartzdemo 34 | auto-offset-reset: earliest 35 | thymeleaf: 36 | prefix: classpath:/templates/ 37 | suffix: .html 38 | cache: false 39 | enabled: true 40 | encoding: UTF-8 41 | mode: HTML 42 | #logging: 43 | # level: 44 | # root: 45 | # info 46 | 47 | #logging: 48 | # level: 49 | # com.quartz.cn.springbootquartzdemo.dao: 50 | # debug 51 | 52 | 53 | -------------------------------------------------------------------------------- /src/main/java/com/quartz/cn/springbootquartzdemo/service/quartz/impl/QuartzTaskRecordsServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.quartz.cn.springbootquartzdemo.service.quartz.impl; 2 | 3 | 4 | import com.quartz.cn.springbootquartzdemo.bean.QuartzTaskRecords; 5 | import com.quartz.cn.springbootquartzdemo.dao.QuartzTaskRecordsMapper; 6 | import com.quartz.cn.springbootquartzdemo.service.quartz.QuartzTaskRecordsService; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.stereotype.Service; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | * @ClassName QuartzTaskRecordsServiceImpl 14 | * @Description TODO 15 | * @Author simonsfan 16 | * @Date 2019/1/3 17 | * Version 1.0 18 | */ 19 | @Service 20 | public class QuartzTaskRecordsServiceImpl implements QuartzTaskRecordsService { 21 | 22 | @Autowired 23 | private QuartzTaskRecordsMapper quartzTaskRecordsMapper; 24 | 25 | @Override 26 | public long addTaskRecords(QuartzTaskRecords quartzTaskRecords) { 27 | return quartzTaskRecordsMapper.insert(quartzTaskRecords); 28 | } 29 | 30 | @Override 31 | public Integer updateTaskRecords(QuartzTaskRecords quartzTaskRecords) { 32 | return quartzTaskRecordsMapper.updateByPrimaryKeySelective(quartzTaskRecords); 33 | } 34 | 35 | public List listTaskRecordsByTaskNo(String taskNo) { 36 | return quartzTaskRecordsMapper.getTaskRecordsByTaskNo(taskNo); 37 | } 38 | 39 | ; 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/quartz/cn/springbootquartzdemo/service/quartz/QuartzService.java: -------------------------------------------------------------------------------- 1 | package com.quartz.cn.springbootquartzdemo.service.quartz; 2 | 3 | 4 | import com.quartz.cn.springbootquartzdemo.bean.QuartzTaskErrors; 5 | import com.quartz.cn.springbootquartzdemo.bean.QuartzTaskInformations; 6 | import com.quartz.cn.springbootquartzdemo.bean.QuartzTaskRecords; 7 | import com.quartz.cn.springbootquartzdemo.vo.QuartzTaskRecordsVo; 8 | import org.quartz.SchedulerException; 9 | 10 | import java.util.List; 11 | 12 | public interface QuartzService { 13 | String addTask(QuartzTaskInformations quartzTaskInformations); 14 | 15 | List getTaskList(String taskNo, String currentPage); 16 | 17 | QuartzTaskInformations getTaskById(String id); 18 | 19 | String updateTask(QuartzTaskInformations quartzTaskInformations); 20 | 21 | String startJob(String taskNo) throws SchedulerException; 22 | 23 | void initLoadOnlineTasks(); 24 | 25 | void sendMessage(String message); 26 | 27 | QuartzTaskRecords addTaskRecords(String taskNo); 28 | 29 | Integer updateRecordById(Integer count, Long id); 30 | 31 | Integer updateModifyTimeById(QuartzTaskInformations quartzTaskInformations); 32 | 33 | Integer addTaskErrorRecord(String id, String errorKey, String errorValue); 34 | 35 | List taskRecords(String taskNo); 36 | 37 | String runTaskRightNow(String taskNo); 38 | 39 | QuartzTaskErrors detailTaskErrors(String recordId); 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/quartz/cn/springbootquartzdemo/util/Result.java: -------------------------------------------------------------------------------- 1 | package com.quartz.cn.springbootquartzdemo.util; 2 | 3 | /** 4 | * @ClassName Result 5 | * @Description 接口统一返回result 6 | * @Author simonsfan 7 | * @Date 2019/1/1 8 | * Version 1.0 9 | */ 10 | public class Result { 11 | private Integer code; 12 | private String message; 13 | private T data; 14 | 15 | public Result(ResultEnum resultEnum) { 16 | this.code = resultEnum.getCode(); 17 | this.message = resultEnum.getMessage(); 18 | } 19 | 20 | public Result(ResultEnum resultEnum, T data) { 21 | this.code = resultEnum.getCode(); 22 | this.message = resultEnum.getMessage(); 23 | this.data = data; 24 | } 25 | 26 | public Result(Integer code, String message) { 27 | this.code = code; 28 | this.message = message; 29 | } 30 | 31 | public Result(Integer code, String message, T data) { 32 | this.code = code; 33 | this.message = message; 34 | this.data = data; 35 | } 36 | 37 | public Integer getCode() { 38 | return code; 39 | } 40 | 41 | public void setCode(Integer code) { 42 | this.code = code; 43 | } 44 | 45 | public String getMessage() { 46 | return message; 47 | } 48 | 49 | public void setMessage(String message) { 50 | this.message = message; 51 | } 52 | 53 | public T getData() { 54 | return data; 55 | } 56 | 57 | public void setData(T data) { 58 | this.data = data; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/resources/static/css/red.css: -------------------------------------------------------------------------------- 1 | /* iCheck plugin Flat skin, red 2 | ----------------------------------- */ 3 | .icheckbox_flat-red, 4 | .iradio_flat-red { 5 | display: inline-block; 6 | *display: inline; 7 | vertical-align: middle; 8 | margin: 0; 9 | padding: 0; 10 | width: 20px; 11 | height: 20px; 12 | background: url(red.png) no-repeat; 13 | border: none; 14 | cursor: pointer; 15 | } 16 | 17 | .icheckbox_flat-red { 18 | background-position: 0 0; 19 | } 20 | .icheckbox_flat-red.checked { 21 | background-position: -22px 0; 22 | } 23 | .icheckbox_flat-red.disabled { 24 | background-position: -44px 0; 25 | cursor: default; 26 | } 27 | .icheckbox_flat-red.checked.disabled { 28 | background-position: -66px 0; 29 | } 30 | 31 | .iradio_flat-red { 32 | background-position: -88px 0; 33 | } 34 | .iradio_flat-red.checked { 35 | background-position: -110px 0; 36 | } 37 | .iradio_flat-red.disabled { 38 | background-position: -132px 0; 39 | cursor: default; 40 | } 41 | .iradio_flat-red.checked.disabled { 42 | background-position: -154px 0; 43 | } 44 | 45 | /* HiDPI support */ 46 | @media (-o-min-device-pixel-ratio: 5/4), (-webkit-min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { 47 | .icheckbox_flat-red, 48 | .iradio_flat-red { 49 | background-image: url(red@2x.png); 50 | -webkit-background-size: 176px 22px; 51 | background-size: 176px 22px; 52 | } 53 | } -------------------------------------------------------------------------------- /src/main/resources/static/css/aero.css: -------------------------------------------------------------------------------- 1 | /* iCheck plugin Flat skin, aero 2 | ----------------------------------- */ 3 | .icheckbox_flat-aero, 4 | .iradio_flat-aero { 5 | display: inline-block; 6 | *display: inline; 7 | vertical-align: middle; 8 | margin: 0; 9 | padding: 0; 10 | width: 20px; 11 | height: 20px; 12 | background: url(aero.png) no-repeat; 13 | border: none; 14 | cursor: pointer; 15 | } 16 | 17 | .icheckbox_flat-aero { 18 | background-position: 0 0; 19 | } 20 | .icheckbox_flat-aero.checked { 21 | background-position: -22px 0; 22 | } 23 | .icheckbox_flat-aero.disabled { 24 | background-position: -44px 0; 25 | cursor: default; 26 | } 27 | .icheckbox_flat-aero.checked.disabled { 28 | background-position: -66px 0; 29 | } 30 | 31 | .iradio_flat-aero { 32 | background-position: -88px 0; 33 | } 34 | .iradio_flat-aero.checked { 35 | background-position: -110px 0; 36 | } 37 | .iradio_flat-aero.disabled { 38 | background-position: -132px 0; 39 | cursor: default; 40 | } 41 | .iradio_flat-aero.checked.disabled { 42 | background-position: -154px 0; 43 | } 44 | 45 | /* HiDPI support */ 46 | @media (-o-min-device-pixel-ratio: 5/4), (-webkit-min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { 47 | .icheckbox_flat-aero, 48 | .iradio_flat-aero { 49 | background-image: url(aero@2x.png); 50 | -webkit-background-size: 176px 22px; 51 | background-size: 176px 22px; 52 | } 53 | } -------------------------------------------------------------------------------- /src/main/resources/static/js/supersized-init.js: -------------------------------------------------------------------------------- 1 | jQuery(function($){ 2 | 3 | $.supersized({ 4 | 5 | // Functionality 6 | slide_interval : 4000, // Length between transitions 7 | transition : 1, // 0-None, 1-Fade, 2-Slide Top, 3-Slide Right, 4-Slide Bottom, 5-Slide Left, 6-Carousel Right, 7-Carousel Left 8 | transition_speed : 1000, // Speed of transition 9 | performance : 1, // 0-Normal, 1-Hybrid speed/quality, 2-Optimizes image quality, 3-Optimizes transition speed // (Only works for Firefox/IE, not Webkit) 10 | 11 | // Size & Position 12 | min_width : 0, // Min width allowed (in pixels) 13 | min_height : 0, // Min height allowed (in pixels) 14 | vertical_center : 1, // Vertically center background 15 | horizontal_center : 1, // Horizontally center background 16 | fit_always : 0, // Image will never exceed browser width or height (Ignores min. dimensions) 17 | fit_portrait : 1, // Portrait images will not exceed browser height 18 | fit_landscape : 0, // Landscape images will not exceed browser width 19 | 20 | // Components 21 | slide_links : 'blank', // Individual links for each slide (Options: false, 'num', 'name', 'blank') 22 | slides : [ // Slideshow Images 23 | {image : '/img/backgrounds/1.jpg'}, 24 | {image : '/img/backgrounds/2.jpg'}, 25 | {image : '/img/backgrounds/3.jpg'} 26 | ] 27 | 28 | }); 29 | 30 | }); 31 | -------------------------------------------------------------------------------- /src/main/java/com/quartz/cn/springbootquartzdemo/bean/QuartzTaskErrors.java: -------------------------------------------------------------------------------- 1 | package com.quartz.cn.springbootquartzdemo.bean; 2 | 3 | public class QuartzTaskErrors { 4 | private Long id; 5 | 6 | private String taskexecuterecordid; 7 | 8 | private String errorkey; 9 | 10 | private Long createtime; 11 | 12 | private Long lastmodifytime; 13 | 14 | private String errorvalue; 15 | 16 | public Long getId() { 17 | return id; 18 | } 19 | 20 | public void setId(Long id) { 21 | this.id = id; 22 | } 23 | 24 | public String getTaskexecuterecordid() { 25 | return taskexecuterecordid; 26 | } 27 | 28 | public void setTaskexecuterecordid(String taskexecuterecordid) { 29 | this.taskexecuterecordid = taskexecuterecordid == null ? null : taskexecuterecordid.trim(); 30 | } 31 | 32 | public String getErrorkey() { 33 | return errorkey; 34 | } 35 | 36 | public void setErrorkey(String errorkey) { 37 | this.errorkey = errorkey == null ? null : errorkey.trim(); 38 | } 39 | 40 | public Long getCreatetime() { 41 | return createtime; 42 | } 43 | 44 | public void setCreatetime(Long createtime) { 45 | this.createtime = createtime; 46 | } 47 | 48 | public Long getLastmodifytime() { 49 | return lastmodifytime; 50 | } 51 | 52 | public void setLastmodifytime(Long lastmodifytime) { 53 | this.lastmodifytime = lastmodifytime; 54 | } 55 | 56 | public String getErrorvalue() { 57 | return errorvalue; 58 | } 59 | 60 | public void setErrorvalue(String errorvalue) { 61 | this.errorvalue = errorvalue == null ? null : errorvalue.trim(); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/resources/static/css/supersized.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Supersized - Fullscreen Slideshow jQuery Plugin 4 | Version : 3.2.7 5 | Site : www.buildinternet.com/project/supersized 6 | 7 | Author : Sam Dunn 8 | Company : One Mighty Roar (www.onemightyroar.com) 9 | License : MIT License / GPL License 10 | 11 | */ 12 | 13 | * { margin:0; padding:0; } 14 | body { background:#111; height:100%; } 15 | img { border:none; } 16 | 17 | #supersized-loader { position:absolute; top:50%; left:50%; z-index:0; width:60px; height:60px; margin:-30px 0 0 -30px; text-indent:-999em; background:url(/img/backgrounds/progress.gif) no-repeat center center;} 18 | 19 | #supersized { display:block; position:fixed; left:0; top:0; overflow:hidden; z-index:-999; height:100%; width:100%; } 20 | #supersized img { width:auto; height:auto; position:relative; display:none; outline:none; border:none; } 21 | #supersized.speed img { -ms-interpolation-mode:nearest-neighbor; image-rendering: -moz-crisp-edges; } /*Speed*/ 22 | #supersized.quality img { -ms-interpolation-mode:bicubic; image-rendering: optimizeQuality; } /*Quality*/ 23 | 24 | #supersized li { display:block; list-style:none; z-index:-30; position:fixed; overflow:hidden; top:0; left:0; width:100%; height:100%; background:#111; } 25 | #supersized a { width:100%; height:100%; display:block; } 26 | #supersized li.prevslide { z-index:-20; } 27 | #supersized li.activeslide { z-index:-10; } 28 | #supersized li.image-loading { background:#111 url(/img/backgrounds/progress.gif) no-repeat center center; width:100%; height:100%; } 29 | #supersized li.image-loading img{ visibility:hidden; } 30 | #supersized li.prevslide img, #supersized li.activeslide img{ display:inline; } 31 | 32 | 33 | #supersized img { max-width: none !important } 34 | 35 | -------------------------------------------------------------------------------- /src/main/java/com/quartz/cn/springbootquartzdemo/controller/IndexController.java: -------------------------------------------------------------------------------- 1 | package com.quartz.cn.springbootquartzdemo.controller; 2 | 3 | import com.quartz.cn.springbootquartzdemo.bean.QuartzTaskInformations; 4 | import com.quartz.cn.springbootquartzdemo.service.quartz.QuartzService; 5 | import com.quartz.cn.springbootquartzdemo.util.Page; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.stereotype.Controller; 10 | import org.springframework.ui.Model; 11 | import org.springframework.web.bind.annotation.RequestMapping; 12 | import org.springframework.web.bind.annotation.RequestMethod; 13 | import org.springframework.web.bind.annotation.RequestParam; 14 | 15 | import java.util.List; 16 | 17 | /** 18 | * @ClassName IndexController 19 | * @Description 首页跳转controller 20 | * @Author simonsfan 21 | * @Date 2019/1/4 22 | * Version 1.0 23 | */ 24 | @Controller 25 | public class IndexController { 26 | 27 | private static final Logger logger = LoggerFactory.getLogger(IndexController.class); 28 | @Autowired 29 | private QuartzService quartzService; 30 | 31 | @RequestMapping(value = "/", method = RequestMethod.GET) 32 | public String listTasks(Model model, @RequestParam(value = "currentPage", required = false, defaultValue = "1") String currentPage, 33 | @RequestParam(value = "taskNo", required = false) String taskNo) { 34 | try { 35 | List taskList = quartzService.getTaskList(taskNo, currentPage); 36 | int current = Integer.parseInt(currentPage); 37 | Page page = new Page(taskList, taskList.size(), current); 38 | model.addAttribute("taskList", taskList); 39 | model.addAttribute("size", taskList.size()); 40 | model.addAttribute("currentPage", page.getCurrentPage()); 41 | model.addAttribute("totalPage", page.getTotalPage()); 42 | model.addAttribute("taskNo", taskNo); 43 | } catch (Exception e) { 44 | logger.error("首页跳转发生异常exceptions-->" + e.toString()); 45 | } 46 | return "/index"; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/quartz/cn/springbootquartzdemo/job/KafkaListener.java: -------------------------------------------------------------------------------- 1 | package com.quartz.cn.springbootquartzdemo.job; 2 | 3 | import com.quartz.cn.springbootquartzdemo.bean.QuartzTaskInformations; 4 | import com.quartz.cn.springbootquartzdemo.service.quartz.QuartzService; 5 | import com.quartz.cn.springbootquartzdemo.service.quartz.impl.QuartzServiceImpl; 6 | import com.quartz.cn.springbootquartzdemo.util.CommonUtil; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.stereotype.Component; 11 | 12 | import java.util.concurrent.atomic.AtomicInteger; 13 | 14 | /** 15 | * @ClassName KafkaListener 16 | * @Description kafka消费者 17 | * @Author simonsfan 18 | * @Date 2019/1/10 19 | * Version 1.0 20 | */ 21 | @Component 22 | public class KafkaListener { 23 | 24 | @Autowired 25 | private QuartzService quartzService; 26 | 27 | private static final Logger logger = LoggerFactory.getLogger(KafkaListener.class); 28 | 29 | private AtomicInteger atomicInteger; 30 | 31 | @org.springframework.kafka.annotation.KafkaListener(topics = QuartzServiceImpl.QUARTZ_TOPIC) 32 | public void messageConsumerHandler(String content) { 33 | logger.info("监听到消息:{}", content); 34 | atomicInteger = new AtomicInteger(0); 35 | String id = ""; 36 | String taskNo = ""; 37 | try { 38 | // message格式 ---------> taskNo:id:executeParameter; 39 | String[] split = ":".split(content); 40 | id = split[1]; 41 | taskNo = split[0]; 42 | //TODO kafka逻辑 43 | 44 | } catch (Exception ex) { 45 | logger.error(""); 46 | atomicInteger.incrementAndGet(); 47 | quartzService.addTaskErrorRecord(id, taskNo + ":" + ex.getMessage(), CommonUtil.getExceptionDetail(ex)); 48 | } 49 | quartzService.updateRecordById(atomicInteger.get(), Long.parseLong(id)); 50 | QuartzTaskInformations quartzTaskInformation = new QuartzTaskInformations(); 51 | quartzTaskInformation.setId(Long.parseLong(id)); 52 | quartzTaskInformation.setLastmodifytime(System.currentTimeMillis()); 53 | quartzService.updateTask(quartzTaskInformation); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/main/resources/db/db.sql: -------------------------------------------------------------------------------- 1 | 2 | DROP TABLE IF EXISTS `quartz_task_informations`; 3 | CREATE TABLE `quartz_task_informations` ( 4 | `id` bigint(20) NOT NULL AUTO_INCREMENT, 5 | `version` int(11) NOT NULL COMMENT '版本号:需要乐观锁控制', 6 | `taskNo` varchar(64) NOT NULL COMMENT '任务编号', 7 | `taskName` varchar(64) NOT NULL COMMENT '任务名称', 8 | `schedulerRule` varchar(64) NOT NULL COMMENT '定时规则表达式', 9 | `frozenStatus` varchar(16) NOT NULL COMMENT '冻结状态', 10 | `executorNo` varchar(128) NOT NULL COMMENT '执行方', 11 | `frozenTime` bigint(13) DEFAULT NULL COMMENT '冻结时间', 12 | `unfrozenTime` bigint(13) DEFAULT NULL COMMENT '解冻时间', 13 | `createTime` bigint(13) NOT NULL COMMENT '创建时间', 14 | `lastModifyTime` bigint(13) DEFAULT NULL COMMENT '最近修改时间', 15 | `sendType` varchar(64) DEFAULT NULL COMMENT '发送方式', 16 | `url` varchar(64) DEFAULT NULL COMMENT '请求地址', 17 | `executeParamter` varchar(2000) DEFAULT NULL COMMENT '执行参数', 18 | `timeKey` varchar(32) NOT NULL, 19 | PRIMARY KEY (`id`) 20 | ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='定时任务信息表'; 21 | 22 | DROP TABLE IF EXISTS `quartz_task_records`; 23 | CREATE TABLE `quartz_task_records` ( 24 | `id` bigint(20) NOT NULL AUTO_INCREMENT, 25 | `taskNo` varchar(64) NOT NULL COMMENT '任务编号', 26 | `timeKeyValue` varchar(32) DEFAULT NULL COMMENT '执行时间格式值', 27 | `executeTime` bigint(13) NOT NULL COMMENT '执行时间', 28 | `taskStatus` varchar(16) NOT NULL COMMENT '任务状态', 29 | `failcount` int(10) DEFAULT NULL COMMENT '失败统计数', 30 | `failReason` varchar(64) DEFAULT NULL COMMENT '失败错误描述', 31 | `createTime` bigint(13) NOT NULL COMMENT '创建时间', 32 | `lastModifyTime` bigint(13) DEFAULT NULL COMMENT '最近修改时间', 33 | PRIMARY KEY (`id`), 34 | KEY `idx_task_records_taskno` (`taskNo`) 35 | ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='定时任务执行情况记录表'; 36 | 37 | DROP TABLE IF EXISTS `quartz_task_errors`; 38 | CREATE TABLE `quartz_task_errors` ( 39 | `id` bigint(20) NOT NULL AUTO_INCREMENT, 40 | `taskExecuteRecordId` varchar(64) NOT NULL COMMENT '任务执行记录Id', 41 | `errorKey` varchar(1024) NOT NULL COMMENT '信息关键字', 42 | `errorValue` text COMMENT '信息内容', 43 | `createTime` bigint(13) NOT NULL COMMENT '创建时间', 44 | `lastModifyTime` bigint(13) DEFAULT NULL COMMENT '最近修改时间', 45 | PRIMARY KEY (`id`) 46 | ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='定时任务出错现场信息表'; 47 | -------------------------------------------------------------------------------- /src/main/java/com/quartz/cn/springbootquartzdemo/bean/QuartzTaskRecords.java: -------------------------------------------------------------------------------- 1 | package com.quartz.cn.springbootquartzdemo.bean; 2 | 3 | public class QuartzTaskRecords { 4 | private Long id; 5 | 6 | private String taskno; 7 | 8 | private String timekeyvalue; 9 | 10 | private Long executetime; 11 | 12 | private String taskstatus; 13 | 14 | private Integer failcount; 15 | 16 | private String failreason; 17 | 18 | private Long createtime; 19 | 20 | private Long lastmodifytime; 21 | 22 | public Long getId() { 23 | return id; 24 | } 25 | 26 | public void setId(Long id) { 27 | this.id = id; 28 | } 29 | 30 | public String getTaskno() { 31 | return taskno; 32 | } 33 | 34 | public void setTaskno(String taskno) { 35 | this.taskno = taskno == null ? null : taskno.trim(); 36 | } 37 | 38 | public String getTimekeyvalue() { 39 | return timekeyvalue; 40 | } 41 | 42 | public void setTimekeyvalue(String timekeyvalue) { 43 | this.timekeyvalue = timekeyvalue == null ? null : timekeyvalue.trim(); 44 | } 45 | 46 | public Long getExecutetime() { 47 | return executetime; 48 | } 49 | 50 | public void setExecutetime(Long executetime) { 51 | this.executetime = executetime; 52 | } 53 | 54 | public String getTaskstatus() { 55 | return taskstatus; 56 | } 57 | 58 | public void setTaskstatus(String taskstatus) { 59 | this.taskstatus = taskstatus == null ? null : taskstatus.trim(); 60 | } 61 | 62 | public Integer getFailcount() { 63 | return failcount; 64 | } 65 | 66 | public void setFailcount(Integer failcount) { 67 | this.failcount = failcount; 68 | } 69 | 70 | public String getFailreason() { 71 | return failreason; 72 | } 73 | 74 | public void setFailreason(String failreason) { 75 | this.failreason = failreason == null ? null : failreason.trim(); 76 | } 77 | 78 | public Long getCreatetime() { 79 | return createtime; 80 | } 81 | 82 | public void setCreatetime(Long createtime) { 83 | this.createtime = createtime; 84 | } 85 | 86 | public Long getLastmodifytime() { 87 | return lastmodifytime; 88 | } 89 | 90 | public void setLastmodifytime(Long lastmodifytime) { 91 | this.lastmodifytime = lastmodifytime; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/main/java/com/quartz/cn/springbootquartzdemo/vo/QuartzTaskRecordsVo.java: -------------------------------------------------------------------------------- 1 | package com.quartz.cn.springbootquartzdemo.vo; 2 | 3 | /** 4 | * @ClassName QuartzTaskRecordsVo 5 | * @Description TODO 6 | * @Author simonsfan 7 | * @Date 2019/1/8 8 | * Version 1.0 9 | */ 10 | public class QuartzTaskRecordsVo 11 | { 12 | private Long id; 13 | 14 | private String taskno; 15 | 16 | private String timekeyvalue; 17 | 18 | private Long executetime; 19 | 20 | private String taskstatus; 21 | 22 | private Integer failcount; 23 | 24 | private String failreason; 25 | 26 | private Long createtime; 27 | 28 | private Long lastmodifytime; 29 | 30 | private Long time; 31 | 32 | public Long getId() { 33 | return id; 34 | } 35 | 36 | public void setId(Long id) { 37 | this.id = id; 38 | } 39 | 40 | public String getTaskno() { 41 | return taskno; 42 | } 43 | 44 | public void setTaskno(String taskno) { 45 | this.taskno = taskno; 46 | } 47 | 48 | public String getTimekeyvalue() { 49 | return timekeyvalue; 50 | } 51 | 52 | public void setTimekeyvalue(String timekeyvalue) { 53 | this.timekeyvalue = timekeyvalue; 54 | } 55 | 56 | public Long getExecutetime() { 57 | return executetime; 58 | } 59 | 60 | public void setExecutetime(Long executetime) { 61 | this.executetime = executetime; 62 | } 63 | 64 | public String getTaskstatus() { 65 | return taskstatus; 66 | } 67 | 68 | public void setTaskstatus(String taskstatus) { 69 | this.taskstatus = taskstatus; 70 | } 71 | 72 | public Integer getFailcount() { 73 | return failcount; 74 | } 75 | 76 | public void setFailcount(Integer failcount) { 77 | this.failcount = failcount; 78 | } 79 | 80 | public String getFailreason() { 81 | return failreason; 82 | } 83 | 84 | public void setFailreason(String failreason) { 85 | this.failreason = failreason; 86 | } 87 | 88 | public Long getCreatetime() { 89 | return createtime; 90 | } 91 | 92 | public void setCreatetime(Long createtime) { 93 | this.createtime = createtime; 94 | } 95 | 96 | public Long getLastmodifytime() { 97 | return lastmodifytime; 98 | } 99 | 100 | public void setLastmodifytime(Long lastmodifytime) { 101 | this.lastmodifytime = lastmodifytime; 102 | } 103 | 104 | public Long getTime() { 105 | return time; 106 | } 107 | 108 | public void setTime(Long time) { 109 | this.time = time; 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/main/resources/templates/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 电影资源后台管理 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 49 | 50 |
51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /src/main/resources/templates/login666.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 微信公众号: 91电影社 登录界面 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 21 | 22 | 23 | 24 |
25 |

91电影社 后台管理

26 |
27 | 28 | 29 | 30 | 31 |
+
32 |
33 |
34 |

微信扫一扫:


35 |

36 | 37 |

38 |
39 |
40 | 41 | 42 | 43 | 44 | 45 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /src/main/java/com/quartz/cn/springbootquartzdemo/util/Page.java: -------------------------------------------------------------------------------- 1 | package com.quartz.cn.springbootquartzdemo.util; 2 | 3 | import java.io.Serializable; 4 | import java.util.List; 5 | 6 | /** 7 | * @ClassName Page 8 | * @Description 分页实体类 9 | * @Author simonsfan 10 | * @Date 2019/1/8 11 | * Version 1.0 12 | */ 13 | public class Page implements Serializable { 14 | private static final long serialVersionUID = 130050641959720183L; 15 | private List list; //数据集合 16 | private int totalRecord; //总记录数 17 | private int currentPage; //当前页 18 | private int pageSize; //每页大小 19 | private int startIndex; 20 | private int totalPage; //总页数 21 | private int previousPage; //前一页 22 | private int nextPage; //下一页 23 | 24 | public List getList() { 25 | return list; 26 | } 27 | 28 | public void setList(List list) { 29 | this.list = list; 30 | } 31 | 32 | public int getTotalRecord() { 33 | return totalRecord; 34 | } 35 | 36 | public void setTotalRecord(int totalRecord) { 37 | this.totalRecord = list.size(); 38 | } 39 | 40 | public int getCurrentPage() { 41 | return currentPage; 42 | } 43 | 44 | public void setCurrentPage(int currentPage) { 45 | this.currentPage = currentPage; 46 | } 47 | 48 | public int getPageSize() { 49 | return pageSize; 50 | } 51 | 52 | public void setPageSize(int pageSize) { 53 | this.pageSize = 10; 54 | } 55 | 56 | public int getStartIndex() { 57 | return startIndex; 58 | } 59 | 60 | public void setStartIndex(int startIndex) { 61 | this.startIndex = pageSize * (currentPage-1); 62 | } 63 | 64 | public void setTotalPage(int totalPage) { 65 | if(this.totalRecord % this.pageSize == 0) { 66 | this.totalPage = this.totalRecord / this.pageSize; 67 | }else { 68 | this.totalPage = this.totalRecord / this.pageSize + 1; 69 | } 70 | } 71 | 72 | public void setPreviousPage(int previousPage) { 73 | if(this.totalRecord % this.pageSize == 0) { 74 | this.totalPage = this.totalRecord / this.pageSize; 75 | }else { 76 | this.totalPage = this.totalRecord / this.pageSize + 1; 77 | } 78 | } 79 | 80 | public void setNextPage(int nextPage) { 81 | if(this.currentPage + 1 > this.totalPage) { 82 | this.nextPage = this.totalPage; 83 | }else { 84 | this.nextPage = this.currentPage + 1; 85 | } 86 | } 87 | 88 | public int getTotalPage() { 89 | return totalPage; 90 | } 91 | 92 | public int getPreviousPage() { 93 | return previousPage; 94 | } 95 | 96 | public int getNextPage() { 97 | return nextPage; 98 | } 99 | 100 | @Override 101 | public String toString() { 102 | return "Page{" + 103 | "list=" + list + 104 | ", totalRecord=" + totalRecord + 105 | ", currentPage=" + currentPage + 106 | ", pageSize=" + pageSize + 107 | ", startIndex=" + startIndex + 108 | ", totalPage=" + totalPage + 109 | ", previousPage=" + previousPage + 110 | ", nextPage=" + nextPage + 111 | '}'; 112 | } 113 | 114 | public Page(List list, int totalRecord, int currentPage) { 115 | this.list = list; 116 | this.totalRecord = totalRecord; 117 | this.currentPage = currentPage; 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /src/main/resources/templates/taskerrors.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 定时任务错误详情页面 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 |
19 |
20 |
21 |
22 |

定时任务错误详情

23 |
24 |
25 |
26 | 27 | 28 | 29 | 31 | 32 | 33 | 35 |
errorKey 30 |
errorValue 34 |
36 |
37 |
38 |
39 |
40 |
41 | 42 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /src/main/resources/templates/taskrecords.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 定时任务执行详情页面 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 |
19 |
20 |
21 |

定时任务执行情况

22 |
23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 47 | 53 | 54 | 55 |
任务编号timeKeyValue执行时间执行时长(毫秒)执行状态失败数操作
39 | 40 | 41 | 42 | 43 | 成功 44 | 初始化 45 | 失败 46 | 48 | 49 | 50 | 51 | 52 |
56 |
57 |
58 | showing items 59 |
60 |
61 |
62 |
63 |
64 | 65 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /src/main/java/com/quartz/cn/springbootquartzdemo/bean/QuartzTaskInformations.java: -------------------------------------------------------------------------------- 1 | package com.quartz.cn.springbootquartzdemo.bean; 2 | 3 | public class QuartzTaskInformations { 4 | private Long id; 5 | 6 | private Integer version; 7 | 8 | private String taskno; 9 | 10 | private String taskname; 11 | 12 | private String schedulerrule; 13 | 14 | private String frozenstatus; 15 | 16 | private String executorno; 17 | 18 | private Long frozentime; 19 | 20 | private Long unfrozentime; 21 | 22 | private Long createtime; 23 | 24 | private Long lastmodifytime; 25 | 26 | private String sendtype; 27 | 28 | private String url; 29 | 30 | private String executeparamter; 31 | 32 | private String timekey; 33 | 34 | public Long getId() { 35 | return id; 36 | } 37 | 38 | public void setId(Long id) { 39 | this.id = id; 40 | } 41 | 42 | public Integer getVersion() { 43 | return version; 44 | } 45 | 46 | public void setVersion(Integer version) { 47 | this.version = version; 48 | } 49 | 50 | public String getTaskno() { 51 | return taskno; 52 | } 53 | 54 | public void setTaskno(String taskno) { 55 | this.taskno = taskno == null ? null : taskno.trim(); 56 | } 57 | 58 | public String getTaskname() { 59 | return taskname; 60 | } 61 | 62 | public void setTaskname(String taskname) { 63 | this.taskname = taskname == null ? null : taskname.trim(); 64 | } 65 | 66 | public String getSchedulerrule() { 67 | return schedulerrule; 68 | } 69 | 70 | public void setSchedulerrule(String schedulerrule) { 71 | this.schedulerrule = schedulerrule == null ? null : schedulerrule.trim(); 72 | } 73 | 74 | public String getFrozenstatus() { 75 | return frozenstatus; 76 | } 77 | 78 | public void setFrozenstatus(String frozenstatus) { 79 | this.frozenstatus = frozenstatus == null ? null : frozenstatus.trim(); 80 | } 81 | 82 | public String getExecutorno() { 83 | return executorno; 84 | } 85 | 86 | public void setExecutorno(String executorno) { 87 | this.executorno = executorno == null ? null : executorno.trim(); 88 | } 89 | 90 | public Long getFrozentime() { 91 | return frozentime; 92 | } 93 | 94 | public void setFrozentime(Long frozentime) { 95 | this.frozentime = frozentime; 96 | } 97 | 98 | public Long getUnfrozentime() { 99 | return unfrozentime; 100 | } 101 | 102 | public void setUnfrozentime(Long unfrozentime) { 103 | this.unfrozentime = unfrozentime; 104 | } 105 | 106 | public Long getCreatetime() { 107 | return createtime; 108 | } 109 | 110 | public void setCreatetime(Long createtime) { 111 | this.createtime = createtime; 112 | } 113 | 114 | public Long getLastmodifytime() { 115 | return lastmodifytime; 116 | } 117 | 118 | public void setLastmodifytime(Long lastmodifytime) { 119 | this.lastmodifytime = lastmodifytime; 120 | } 121 | 122 | public String getSendtype() { 123 | return sendtype; 124 | } 125 | 126 | public void setSendtype(String sendtype) { 127 | this.sendtype = sendtype == null ? null : sendtype.trim(); 128 | } 129 | 130 | public String getUrl() { 131 | return url; 132 | } 133 | 134 | public void setUrl(String url) { 135 | this.url = url == null ? null : url.trim(); 136 | } 137 | 138 | public String getExecuteparamter() { 139 | return executeparamter; 140 | } 141 | 142 | public void setExecuteparamter(String executeparamter) { 143 | this.executeparamter = executeparamter == null ? null : executeparamter.trim(); 144 | } 145 | 146 | public String getTimekey() { 147 | return timekey; 148 | } 149 | 150 | public void setTimekey(String timekey) { 151 | this.timekey = timekey == null ? null : timekey.trim(); 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /src/main/java/com/quartz/cn/springbootquartzdemo/util/HttpClientUtil.java: -------------------------------------------------------------------------------- 1 | package com.quartz.cn.springbootquartzdemo.util; 2 | 3 | import org.apache.commons.httpclient.*; 4 | import org.apache.commons.httpclient.cookie.CookiePolicy; 5 | import org.apache.commons.httpclient.methods.ByteArrayRequestEntity; 6 | import org.apache.commons.httpclient.methods.GetMethod; 7 | import org.apache.commons.httpclient.methods.PostMethod; 8 | import org.apache.commons.httpclient.params.HttpConnectionManagerParams; 9 | import org.apache.commons.httpclient.params.HttpMethodParams; 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | 13 | /** 14 | * @ClassName HttpClientUtil 15 | * @Description httpclient get/post方式调用接口 16 | * @Author simonsfan 17 | * @Date 2019/1/7 18 | * Version 1.0 19 | */ 20 | public class HttpClientUtil { 21 | private static Logger log = LoggerFactory.getLogger(HttpClientUtil.class); 22 | 23 | private static final String ENCODING = "UTF-8"; 24 | 25 | private static final int CONNECTION_TIME_OUT = 3000; 26 | 27 | private static final int SO_TIME_OUT = 5000; 28 | 29 | private static final boolean STALE_CHECK_ENABLED = true; 30 | 31 | private static final boolean TCP_NO_DELAY = true; 32 | 33 | private static final int DEFAULT_MAX_CONNECTIONS_PER_HOST = 100; 34 | 35 | private static final int MAX_TOTAL_CONNECTIONS = 1000; 36 | 37 | private static final HttpConnectionManager connectionManager; 38 | 39 | public static final HttpClient client; 40 | 41 | static { 42 | HttpConnectionManagerParams params = loadHttpConfFromFile(); 43 | 44 | connectionManager = new MultiThreadedHttpConnectionManager(); 45 | 46 | connectionManager.setParams(params); 47 | 48 | client = new HttpClient(connectionManager); 49 | } 50 | 51 | private static HttpConnectionManagerParams loadHttpConfFromFile() { 52 | HttpConnectionManagerParams params = new HttpConnectionManagerParams(); 53 | params.setConnectionTimeout(CONNECTION_TIME_OUT); 54 | params.setStaleCheckingEnabled(STALE_CHECK_ENABLED); 55 | params.setTcpNoDelay(TCP_NO_DELAY); 56 | params.setSoTimeout(SO_TIME_OUT); 57 | params.setDefaultMaxConnectionsPerHost(DEFAULT_MAX_CONNECTIONS_PER_HOST); 58 | params.setMaxTotalConnections(MAX_TOTAL_CONNECTIONS); 59 | params.setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(0, false)); 60 | return params; 61 | } 62 | 63 | /** 64 | * get请求 65 | * 66 | * @param url 67 | * @return 68 | */ 69 | public static String doGet(String url) { 70 | String result = null; 71 | try { 72 | GetMethod getMethod = new GetMethod(url); 73 | client.executeMethod(getMethod); 74 | result = getMethod.getResponseBodyAsString(); 75 | } catch (Exception e) { 76 | log.error("httpclient get request url=" + url + ",exception=" + e); 77 | } 78 | return result; 79 | } 80 | 81 | public static String doPost(String url, String contentType, String content) throws Exception { 82 | PostMethod method = new PostMethod(url); 83 | method.addRequestHeader("Connection", "Keep-Alive"); 84 | method.getParams().setCookiePolicy(CookiePolicy.IGNORE_COOKIES); 85 | method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(0, false)); 86 | try { 87 | method.setRequestEntity(new ByteArrayRequestEntity(content.getBytes(ENCODING))); 88 | method.addRequestHeader("Content-Type", contentType); 89 | 90 | int statusCode = client.executeMethod(method); 91 | if (statusCode != HttpStatus.SC_OK) { 92 | return null; 93 | } 94 | byte[] ret = method.getResponseBody(); 95 | if (ret == null) 96 | return null; 97 | return new String(ret, ENCODING); 98 | } finally { 99 | method.releaseConnection(); 100 | } 101 | } 102 | 103 | } 104 | 105 | -------------------------------------------------------------------------------- /src/main/java/com/quartz/cn/springbootquartzdemo/job/QuartzMainJobFactory.java: -------------------------------------------------------------------------------- 1 | package com.quartz.cn.springbootquartzdemo.job; 2 | 3 | import com.quartz.cn.springbootquartzdemo.bean.QuartzTaskInformations; 4 | import com.quartz.cn.springbootquartzdemo.bean.QuartzTaskRecords; 5 | import com.quartz.cn.springbootquartzdemo.service.quartz.QuartzService; 6 | import com.quartz.cn.springbootquartzdemo.service.quartz.impl.QuartzServiceImpl; 7 | import com.quartz.cn.springbootquartzdemo.util.ApplicationContextHolder; 8 | import com.quartz.cn.springbootquartzdemo.util.CommonUtil; 9 | import com.quartz.cn.springbootquartzdemo.util.HttpClientUtil; 10 | import com.quartz.cn.springbootquartzdemo.util.ResultEnum; 11 | import org.apache.commons.lang.StringUtils; 12 | import org.quartz.*; 13 | import org.slf4j.Logger; 14 | import org.slf4j.LoggerFactory; 15 | 16 | import java.util.concurrent.atomic.AtomicInteger; 17 | 18 | /** 19 | * @ClassName QuartzMainJobFactory 20 | * @Description 定时任务的主要执行逻辑,实现Job接口 21 | * @Author simonsfan 22 | * @Date 2019/1/7 23 | * Version 1.0 24 | */ 25 | @DisallowConcurrentExecution 26 | public class QuartzMainJobFactory implements Job { 27 | 28 | private static Logger logger = LoggerFactory.getLogger(QuartzMainJobFactory.class); 29 | 30 | private AtomicInteger atomicInteger; 31 | 32 | @Override 33 | public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { 34 | atomicInteger = new AtomicInteger(0); 35 | 36 | JobDataMap jobDataMap = jobExecutionContext.getMergedJobDataMap(); 37 | String id = jobDataMap.getString("id"); 38 | String taskNo = jobDataMap.getString("taskNo"); 39 | String executorNo = jobDataMap.getString("executorNo"); 40 | String sendType = jobDataMap.getString("sendType"); 41 | String url = jobDataMap.getString("url"); 42 | String executeParameter = jobDataMap.getString("executeParameter"); 43 | logger.info("定时任务被执行:taskNo={},executorNo={},sendType={},url={},executeParameter={}", taskNo, executorNo, sendType, url, executeParameter); 44 | QuartzService quartzService = (QuartzServiceImpl) ApplicationContextHolder.getBean("quartzServiceImpl"); 45 | QuartzTaskRecords records = null; 46 | try { 47 | //保存定时任务的执行记录 48 | records = quartzService.addTaskRecords(taskNo); 49 | if (null == records || !ResultEnum.INIT.name().equals(records.getTaskstatus())) { 50 | logger.info("taskNo={}保存执行记录失败", taskNo); 51 | return; 52 | } 53 | 54 | if (ResultEnum.HTTP.getMessage().equals(sendType)) { 55 | try { 56 | String result = HttpClientUtil.doPost(url, "text/json", executeParameter); 57 | logger.info("taskNo={},sendtype={}执行结果result{}", taskNo, sendType, result); 58 | if (StringUtils.isEmpty(result)) { 59 | throw new RuntimeException("taskNo=" + taskNo + "http方式返回null"); 60 | } 61 | } catch (Exception ex) { 62 | logger.error(""); 63 | throw ex; 64 | } 65 | } else if (ResultEnum.KAFKA.getMessage().equals(sendType)) { 66 | try { 67 | String message = new StringBuffer(taskNo).append(":").append(id).append(":").append(executeParameter).toString(); 68 | quartzService.sendMessage(message); 69 | logger.info("taskNo={},sendtype={}推送至kafka成功", taskNo, sendType); 70 | } catch (Exception ex) { 71 | logger.error(""); 72 | throw ex; 73 | } 74 | } 75 | } catch (Exception ex) { 76 | logger.error(""); 77 | atomicInteger.incrementAndGet(); 78 | quartzService.addTaskErrorRecord(records.getId().toString(), taskNo + ":" + ex.getMessage(), CommonUtil.getExceptionDetail(ex)); 79 | } 80 | 81 | quartzService.updateRecordById(atomicInteger.get(), records.getId()); 82 | QuartzTaskInformations quartzTaskInformation = new QuartzTaskInformations(); 83 | quartzTaskInformation.setId(Long.parseLong(id)); 84 | quartzTaskInformation.setLastmodifytime(System.currentTimeMillis()); 85 | quartzService.updateTask(quartzTaskInformation); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/main/java/com/quartz/cn/springbootquartzdemo/service/quartz/impl/QuartzTaskInformationsServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.quartz.cn.springbootquartzdemo.service.quartz.impl; 2 | 3 | 4 | import com.quartz.cn.springbootquartzdemo.bean.QuartzTaskInformations; 5 | import com.quartz.cn.springbootquartzdemo.dao.QuartzTaskInformationsMapper; 6 | import com.quartz.cn.springbootquartzdemo.service.quartz.QuartzTaskInformationsService; 7 | import com.quartz.cn.springbootquartzdemo.util.ResultEnum; 8 | import com.quartz.cn.springbootquartzdemo.util.ResultUtil; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.stereotype.Service; 11 | 12 | import java.util.HashMap; 13 | import java.util.List; 14 | import java.util.Map; 15 | 16 | /** 17 | * @ClassName QuartzTaskInformationsServiceImpl 18 | * @Description TODO 19 | * @Author simonsfan 20 | * @Date 2019/1/3 21 | * Version 1.0 22 | */ 23 | @Service 24 | public class QuartzTaskInformationsServiceImpl implements QuartzTaskInformationsService { 25 | 26 | @Autowired 27 | private QuartzTaskInformationsMapper quartzTaskInformationsMapper; 28 | 29 | @Override 30 | public String insert(QuartzTaskInformations quartzTaskInformations) { 31 | String taskNo = quartzTaskInformations.getTaskno(); 32 | quartzTaskInformations.setVersion(0); 33 | quartzTaskInformations.setCreatetime(System.currentTimeMillis()); 34 | quartzTaskInformations.setLastmodifytime(System.currentTimeMillis()); 35 | Integer count = quartzTaskInformationsMapper.selectByTaskNo(taskNo); 36 | //判断是否重复任务编号 37 | if (count > 0) { 38 | return ResultUtil.success(ResultEnum.TASKNO_EXIST.getCode(), ResultEnum.TASKNO_EXIST.getMessage()); 39 | } 40 | int insert = quartzTaskInformationsMapper.insert(quartzTaskInformations); 41 | if (insert < 1) { 42 | return ResultUtil.success(ResultEnum.FAIL.getCode(), ResultEnum.FAIL.getMessage()); 43 | } 44 | return ResultUtil.success(ResultEnum.SUCCESS.getCode(), ResultEnum.SUCCESS.getMessage()); 45 | } 46 | 47 | @Override 48 | public List selectList(String taskNo, String currentPage) { 49 | Map map = new HashMap<>(); 50 | Integer start = Integer.parseInt(currentPage); 51 | map.put("taskNo", taskNo); 52 | map.put("startIndex", 10 * (start - 1)); 53 | return quartzTaskInformationsMapper.selectList(map); 54 | } 55 | 56 | @Override 57 | public QuartzTaskInformations getTaskById(String id) { 58 | return quartzTaskInformationsMapper.selectByPrimaryKey(Long.parseLong(id)); 59 | } 60 | 61 | @Override 62 | public String updateTask(QuartzTaskInformations quartzTaskInformations) { 63 | Integer count = quartzTaskInformationsMapper.selectByTaskNo(quartzTaskInformations.getTaskno()); 64 | //判断是否重复任务编号 65 | if (count >= 2) { 66 | return ResultUtil.success(ResultEnum.TASKNO_EXIST.getCode(), ResultEnum.TASKNO_EXIST.getMessage()); 67 | } 68 | //设置解冻时间或冻结时间及最后修改时间 69 | if (ResultEnum.FROZEN.name().equals(quartzTaskInformations.getFrozenstatus())) { 70 | quartzTaskInformations.setFrozentime(System.currentTimeMillis()); 71 | } else if (ResultEnum.UNFROZEN.name().equals(quartzTaskInformations.getFrozenstatus())) { 72 | quartzTaskInformations.setUnfrozentime(System.currentTimeMillis()); 73 | } 74 | quartzTaskInformations.setLastmodifytime(System.currentTimeMillis()); 75 | int updateCount = quartzTaskInformationsMapper.updateByPrimaryKeySelective(quartzTaskInformations); 76 | //乐观锁控制并发修改 77 | if (updateCount < 1) { 78 | return ResultUtil.success(ResultEnum.UPDATE_FAIL.getCode(), ResultEnum.UPDATE_FAIL.getMessage()); 79 | } 80 | return ResultUtil.success(ResultEnum.SUCCESS.getCode(), ResultEnum.SUCCESS.getMessage()); 81 | } 82 | 83 | @Override 84 | public QuartzTaskInformations getTaskByTaskNo(String taskNo) { 85 | return quartzTaskInformationsMapper.getTaskByTaskNo(taskNo); 86 | } 87 | 88 | @Override 89 | public Integer updateStatusById(QuartzTaskInformations quartzTaskInformations) { 90 | return quartzTaskInformationsMapper.updateByPrimaryKeySelective(quartzTaskInformations); 91 | } 92 | 93 | @Override 94 | public List getUnnfrozenTasks(String status) { 95 | return quartzTaskInformationsMapper.getUnfrozenTasks(status); 96 | } 97 | 98 | @Override 99 | public Integer updateModifyTimeById(QuartzTaskInformations quartzTaskInformations) { 100 | return quartzTaskInformationsMapper.updateByPrimaryKeySelective(quartzTaskInformations); 101 | } 102 | 103 | } 104 | -------------------------------------------------------------------------------- /src/main/resources/static/css/loginstyle.css: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Template Name: Fullscreen Login 4 | * Description: Login Template with Fullscreen Background Slideshow 5 | * Author: Anli Zaimi 6 | * Author URI: http://azmind.com 7 | * 8 | */ 9 | 10 | 11 | body { 12 | background: #f8f8f8; 13 | font-family: 'PT Sans', Helvetica, Arial, sans-serif; 14 | text-align: center; 15 | color: #fff; 16 | } 17 | 18 | .page-container { 19 | margin: 120px auto 0 auto; 20 | } 21 | 22 | h1 { 23 | font-size: 30px; 24 | font-weight: 700; 25 | text-shadow: 0 1px 4px rgba(0,0,0,.2); 26 | } 27 | 28 | form { 29 | position: relative; 30 | width: 305px; 31 | margin: 15px auto 0 auto; 32 | text-align: center; 33 | } 34 | 35 | input { 36 | width: 270px; 37 | height: 42px; 38 | margin-top: 25px; 39 | padding: 0 15px; 40 | background: #2d2d2d; /* browsers that don't support rgba */ 41 | background: rgba(45,45,45,.15); 42 | -moz-border-radius: 6px; 43 | -webkit-border-radius: 6px; 44 | border-radius: 6px; 45 | border: 1px solid #3d3d3d; /* browsers that don't support rgba */ 46 | border: 1px solid rgba(255,255,255,.15); 47 | -moz-box-shadow: 0 2px 3px 0 rgba(0,0,0,.1) inset; 48 | -webkit-box-shadow: 0 2px 3px 0 rgba(0,0,0,.1) inset; 49 | box-shadow: 0 2px 3px 0 rgba(0,0,0,.1) inset; 50 | font-family: 'PT Sans', Helvetica, Arial, sans-serif; 51 | font-size: 14px; 52 | color: #fff; 53 | text-shadow: 0 1px 2px rgba(0,0,0,.1); 54 | -o-transition: all .2s; 55 | -moz-transition: all .2s; 56 | -webkit-transition: all .2s; 57 | -ms-transition: all .2s; 58 | } 59 | 60 | input:-moz-placeholder { color: #fff; } 61 | input:-ms-input-placeholder { color: #fff; } 62 | input::-webkit-input-placeholder { color: #fff; } 63 | 64 | input:focus { 65 | outline: none; 66 | -moz-box-shadow: 67 | 0 2px 3px 0 rgba(0,0,0,.1) inset, 68 | 0 2px 7px 0 rgba(0,0,0,.2); 69 | -webkit-box-shadow: 70 | 0 2px 3px 0 rgba(0,0,0,.1) inset, 71 | 0 2px 7px 0 rgba(0,0,0,.2); 72 | box-shadow: 73 | 0 2px 3px 0 rgba(0,0,0,.1) inset, 74 | 0 2px 7px 0 rgba(0,0,0,.2); 75 | } 76 | 77 | button { 78 | cursor: pointer; 79 | width: 300px; 80 | height: 44px; 81 | margin-top: 25px; 82 | padding: 0; 83 | background: #ef4300; 84 | -moz-border-radius: 6px; 85 | -webkit-border-radius: 6px; 86 | border-radius: 6px; 87 | border: 1px solid #ff730e; 88 | -moz-box-shadow: 89 | 0 15px 30px 0 rgba(255,255,255,.25) inset, 90 | 0 2px 7px 0 rgba(0,0,0,.2); 91 | -webkit-box-shadow: 92 | 0 15px 30px 0 rgba(255,255,255,.25) inset, 93 | 0 2px 7px 0 rgba(0,0,0,.2); 94 | box-shadow: 95 | 0 15px 30px 0 rgba(255,255,255,.25) inset, 96 | 0 2px 7px 0 rgba(0,0,0,.2); 97 | font-family: 'PT Sans', Helvetica, Arial, sans-serif; 98 | font-size: 14px; 99 | font-weight: 700; 100 | color: #fff; 101 | text-shadow: 0 1px 2px rgba(0,0,0,.1); 102 | -o-transition: all .2s; 103 | -moz-transition: all .2s; 104 | -webkit-transition: all .2s; 105 | -ms-transition: all .2s; 106 | } 107 | 108 | button:hover { 109 | -moz-box-shadow: 110 | 0 15px 30px 0 rgba(255,255,255,.15) inset, 111 | 0 2px 7px 0 rgba(0,0,0,.2); 112 | -webkit-box-shadow: 113 | 0 15px 30px 0 rgba(255,255,255,.15) inset, 114 | 0 2px 7px 0 rgba(0,0,0,.2); 115 | box-shadow: 116 | 0 15px 30px 0 rgba(255,255,255,.15) inset, 117 | 0 2px 7px 0 rgba(0,0,0,.2); 118 | } 119 | 120 | button:active { 121 | -moz-box-shadow: 122 | 0 15px 30px 0 rgba(255,255,255,.15) inset, 123 | 0 2px 7px 0 rgba(0,0,0,.2); 124 | -webkit-box-shadow: 125 | 0 15px 30px 0 rgba(255,255,255,.15) inset, 126 | 0 2px 7px 0 rgba(0,0,0,.2); 127 | box-shadow: 128 | 0 5px 8px 0 rgba(0,0,0,.1) inset, 129 | 0 1px 4px 0 rgba(0,0,0,.1); 130 | 131 | border: 0px solid #ef4300; 132 | } 133 | 134 | .error { 135 | display: none; 136 | position: absolute; 137 | top: 27px; 138 | right: -55px; 139 | width: 40px; 140 | height: 40px; 141 | background: #2d2d2d; /* browsers that don't support rgba */ 142 | background: rgba(45,45,45,.25); 143 | -moz-border-radius: 8px; 144 | -webkit-border-radius: 8px; 145 | border-radius: 8px; 146 | } 147 | 148 | .error span { 149 | display: inline-block; 150 | margin-left: 2px; 151 | font-size: 40px; 152 | font-weight: 700; 153 | line-height: 40px; 154 | text-shadow: 0 1px 2px rgba(0,0,0,.1); 155 | -o-transform: rotate(45deg); 156 | -moz-transform: rotate(45deg); 157 | -webkit-transform: rotate(45deg); 158 | -ms-transform: rotate(45deg); 159 | 160 | } 161 | 162 | .connect { 163 | width: 305px; 164 | margin: 35px auto 0 auto; 165 | font-size: 18px; 166 | font-weight: 700; 167 | text-shadow: 0 1px 3px rgba(0,0,0,.2); 168 | } 169 | 170 | .connect a { 171 | display: inline-block; 172 | width: 32px; 173 | height: 35px; 174 | margin-top: 15px; 175 | -o-transition: all .2s; 176 | -moz-transition: all .2s; 177 | -webkit-transition: all .2s; 178 | -ms-transition: all .2s; 179 | } 180 | 181 | .connect a.facebook { background: url(../img/facebook.png) center center no-repeat; } 182 | .connect a.twitter { background: url(../img/twitter.png) center center no-repeat; } 183 | 184 | .connect a:hover { background-position: center bottom; } 185 | 186 | 187 | 188 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | org.springframework.boot 6 | spring-boot-starter-parent 7 | 2.0.3.RELEASE 8 | 9 | 10 | 4.0.0 11 | com.quartz.cn 12 | springboot-quartz-demo 13 | 0.0.1-SNAPSHOT 14 | war 15 | Quartz定时任务及ES相关 16 | Demo project for Spring Boot 17 | 18 | 19 | UTF-8 20 | UTF-8 21 | 1.8 22 | 23 | 24 | 25 | 26 | org.springframework.boot 27 | spring-boot-starter-web 28 | 29 | 30 | 31 | org.springframework.boot 32 | spring-boot-starter-test 33 | test 34 | 35 | 36 | 37 | 38 | org.mybatis.spring.boot 39 | mybatis-spring-boot-starter 40 | 1.3.1 41 | 42 | 43 | 44 | 45 | com.alibaba 46 | druid 47 | 1.0.5 48 | 49 | 50 | 51 | mysql 52 | mysql-connector-java 53 | 54 | 55 | 56 | org.springframework.boot 57 | spring-boot-starter-thymeleaf 58 | 59 | 60 | 61 | org.springframework.boot 62 | spring-boot-starter-tomcat 63 | provided 64 | 65 | 66 | 67 | org.apache.commons 68 | commons-lang3 69 | 3.6 70 | 71 | 72 | 73 | net.sf.json-lib 74 | json-lib 75 | 2.4 76 | jdk15 77 | 78 | 79 | 80 | org.apache.poi 81 | poi 82 | 3.15-beta2 83 | 84 | 85 | 86 | org.springframework.boot 87 | spring-boot-starter-aop 88 | 89 | 90 | 91 | org.slf4j 92 | slf4j-log4j12 93 | 1.7.7 94 | 95 | 96 | 97 | commons-codec 98 | commons-codec 99 | 1.9 100 | 101 | 102 | 103 | org.apache.commons 104 | commons-lang3 105 | 3.6 106 | 107 | 108 | 109 | junit 110 | junit 111 | 4.12 112 | test 113 | 114 | 115 | com.google.code.gson 116 | gson 117 | 2.7 118 | 119 | 120 | 121 | 122 | org.springframework.boot 123 | spring-boot-starter-quartz 124 | 125 | 126 | 127 | 128 | org.springframework.kafka 129 | spring-kafka 130 | 131 | 132 | 133 | 134 | commons-httpclient 135 | commons-httpclient 136 | 3.1 137 | 138 | 139 | 140 | 141 | 142 | 143 | ${project.artifactId} 144 | 145 | 146 | org.springframework.boot 147 | spring-boot-maven-plugin 148 | 149 | 150 | org.apache.maven.plugins 151 | maven-war-plugin 152 | 153 | false 154 | 155 | 156 | 157 | 158 | 159 | 160 | -------------------------------------------------------------------------------- /src/main/java/com/quartz/cn/springbootquartzdemo/controller/QuartzController.java: -------------------------------------------------------------------------------- 1 | package com.quartz.cn.springbootquartzdemo.controller; 2 | 3 | 4 | import com.quartz.cn.springbootquartzdemo.bean.QuartzTaskErrors; 5 | import com.quartz.cn.springbootquartzdemo.bean.QuartzTaskInformations; 6 | import com.quartz.cn.springbootquartzdemo.service.quartz.QuartzService; 7 | import com.quartz.cn.springbootquartzdemo.util.ResultEnum; 8 | import com.quartz.cn.springbootquartzdemo.util.ResultUtil; 9 | import com.quartz.cn.springbootquartzdemo.vo.QuartzTaskRecordsVo; 10 | import org.apache.commons.lang.StringUtils; 11 | import org.slf4j.Logger; 12 | import org.slf4j.LoggerFactory; 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | import org.springframework.stereotype.Controller; 15 | import org.springframework.ui.Model; 16 | import org.springframework.web.bind.annotation.RequestMapping; 17 | import org.springframework.web.bind.annotation.RequestMethod; 18 | import org.springframework.web.bind.annotation.RequestParam; 19 | import org.springframework.web.bind.annotation.ResponseBody; 20 | 21 | import java.util.List; 22 | 23 | /** 24 | * @ClassName QuartzController 25 | * @Description quartz controller主要逻辑 26 | * @Author simonsfan 27 | * @Date 2019/1/3 28 | * Version 1.0 29 | */ 30 | @Controller 31 | @RequestMapping("/quartz") 32 | public class QuartzController { 33 | 34 | private static final Logger logger = LoggerFactory.getLogger(QuartzController.class); 35 | 36 | @Autowired 37 | private QuartzService quartzService; 38 | 39 | @RequestMapping(value = "/add/taskpage", method = RequestMethod.GET) 40 | public String addTaskpage() { 41 | return "addtask"; 42 | } 43 | 44 | @ResponseBody 45 | @RequestMapping(value = "/add/task", method = RequestMethod.POST) 46 | public String addTask(QuartzTaskInformations taskInformations) { 47 | try { 48 | String result = quartzService.addTask(taskInformations); 49 | return result; 50 | } catch (Exception e) { 51 | logger.error("/add/task exception={}", e); 52 | return ResultUtil.fail(); 53 | } 54 | } 55 | 56 | @RequestMapping(value = "/edit/taskpage", method = RequestMethod.GET) 57 | public String editTaskpage(Model model, String id) { 58 | QuartzTaskInformations taskInformation = quartzService.getTaskById(id); 59 | model.addAttribute("taskInformation", taskInformation); 60 | return "updatetask"; 61 | } 62 | 63 | @ResponseBody 64 | @RequestMapping(value = "/edit/task", method = RequestMethod.POST) 65 | public String editTask(QuartzTaskInformations taskInformations) { 66 | try { 67 | String result = quartzService.updateTask(taskInformations); 68 | return result; 69 | } catch (Exception e) { 70 | logger.error("/edit/task exception={}", e); 71 | return ResultUtil.fail(); 72 | } 73 | } 74 | 75 | /** 76 | * 启动 或者 暂定定时任务 77 | * 78 | * @param taskNo 79 | * @return 80 | */ 81 | @ResponseBody 82 | @RequestMapping(value = "/list/optionjob", method = RequestMethod.GET) 83 | public String optionJob(String taskNo) { 84 | logger.info(""); 85 | if (StringUtils.isEmpty(taskNo)) { 86 | return ResultUtil.success(ResultEnum.PARAM_EMPTY.getCode(), ResultEnum.PARAM_EMPTY.getMessage()); 87 | } 88 | try { 89 | return quartzService.startJob(taskNo); 90 | } catch (Exception e) { 91 | logger.error("/list/optionjob exception={}", e); 92 | return ResultUtil.fail(); 93 | } 94 | } 95 | 96 | /** 97 | * 定时任务执行情况 98 | * 99 | * @param taskNo 100 | * @param model 101 | * @return 102 | */ 103 | @RequestMapping(value = "/taskrecords", method = RequestMethod.GET) 104 | public String taskRecordsPage(@RequestParam(value = "taskno", required = false) String taskNo, Model model) { 105 | logger.info(""); 106 | try { 107 | if (StringUtils.isEmpty(taskNo)) { 108 | return "redirect:/"; 109 | } 110 | List quartzTaskRecords = quartzService.taskRecords(taskNo); 111 | model.addAttribute("quartzTaskRecords", quartzTaskRecords); 112 | } catch (Exception e) { 113 | logger.error(""); 114 | return "redirect:/"; 115 | } 116 | return "/taskrecords"; 117 | } 118 | 119 | /** 120 | * 立即运行一次定时任务 121 | * 122 | * @param taskNo 123 | * @param model 124 | * @return 125 | */ 126 | @ResponseBody 127 | @RequestMapping(value = "/runtask/rightnow", method = RequestMethod.GET) 128 | public String runTaskRightNow(@RequestParam(value = "taskno", required = false) String taskNo, Model model) { 129 | logger.info(""); 130 | try { 131 | if (StringUtils.isEmpty(taskNo)) { 132 | return ResultUtil.success(ResultEnum.PARAM_EMPTY.getCode(), ResultEnum.PARAM_EMPTY.getMessage()); 133 | } 134 | return quartzService.runTaskRightNow(taskNo); 135 | } catch (Exception e) { 136 | logger.error(""); 137 | return ResultUtil.success(ResultEnum.FAIL.getCode(), ResultEnum.FAIL.getMessage()); 138 | } 139 | } 140 | 141 | /** 142 | * 定时任务失败详情 143 | * 144 | * @param recordId 145 | * @param model 146 | * @return 147 | */ 148 | @RequestMapping(value = "/task/errors", method = RequestMethod.GET) 149 | public String detailTaskErrors(@RequestParam(value = "recordid", required = false) String recordId, Model model) { 150 | logger.info(""); 151 | try { 152 | if (StringUtils.isEmpty(recordId)) { 153 | return ResultUtil.success(ResultEnum.PARAM_EMPTY.getCode(), ResultEnum.PARAM_EMPTY.getMessage()); 154 | } 155 | QuartzTaskErrors taskErrors = quartzService.detailTaskErrors(recordId); 156 | model.addAttribute("taskErrors", taskErrors); 157 | return "taskerrors"; 158 | } catch (Exception e) { 159 | logger.error(""); 160 | return "redirect:/"; 161 | } 162 | } 163 | 164 | 165 | } 166 | -------------------------------------------------------------------------------- /src/main/resources/mapper/QuartzTaskErrorsMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 13 | 14 | 15 | 16 | id, taskExecuteRecordId, errorKey, createTime, lastModifyTime 17 | 18 | 19 | id, taskExecuteRecordId, errorKey, errorValue ,createTime, lastModifyTime 20 | 21 | 22 | errorValue 23 | 24 | 32 | 33 | delete from quartz_task_errors 34 | where id = #{id,jdbcType=BIGINT} 35 | 36 | 37 | insert into quartz_task_errors (id, taskExecuteRecordId, errorKey, 38 | createTime, lastModifyTime, errorValue 39 | ) 40 | values (#{id,jdbcType=BIGINT}, #{taskexecuterecordid,jdbcType=VARCHAR}, #{errorkey,jdbcType=VARCHAR}, 41 | #{createtime,jdbcType=BIGINT}, #{lastmodifytime,jdbcType=BIGINT}, #{errorvalue,jdbcType=LONGVARCHAR} 42 | ) 43 | 44 | 45 | insert into quartz_task_errors 46 | 47 | 48 | id, 49 | 50 | 51 | taskExecuteRecordId, 52 | 53 | 54 | errorKey, 55 | 56 | 57 | createTime, 58 | 59 | 60 | lastModifyTime, 61 | 62 | 63 | errorValue, 64 | 65 | 66 | 67 | 68 | #{id,jdbcType=BIGINT}, 69 | 70 | 71 | #{taskexecuterecordid,jdbcType=VARCHAR}, 72 | 73 | 74 | #{errorkey,jdbcType=VARCHAR}, 75 | 76 | 77 | #{createtime,jdbcType=BIGINT}, 78 | 79 | 80 | #{lastmodifytime,jdbcType=BIGINT}, 81 | 82 | 83 | #{errorvalue,jdbcType=LONGVARCHAR}, 84 | 85 | 86 | 87 | 88 | update quartz_task_errors 89 | 90 | 91 | taskExecuteRecordId = #{taskexecuterecordid,jdbcType=VARCHAR}, 92 | 93 | 94 | errorKey = #{errorkey,jdbcType=VARCHAR}, 95 | 96 | 97 | createTime = #{createtime,jdbcType=BIGINT}, 98 | 99 | 100 | lastModifyTime = #{lastmodifytime,jdbcType=BIGINT}, 101 | 102 | 103 | errorValue = #{errorvalue,jdbcType=LONGVARCHAR}, 104 | 105 | 106 | where id = #{id,jdbcType=BIGINT} 107 | 108 | 109 | update quartz_task_errors 110 | set taskExecuteRecordId = #{taskexecuterecordid,jdbcType=VARCHAR}, 111 | errorKey = #{errorkey,jdbcType=VARCHAR}, 112 | createTime = #{createtime,jdbcType=BIGINT}, 113 | lastModifyTime = #{lastmodifytime,jdbcType=BIGINT}, 114 | errorValue = #{errorvalue,jdbcType=LONGVARCHAR} 115 | where id = #{id,jdbcType=BIGINT} 116 | 117 | 118 | update quartz_task_errors 119 | set taskExecuteRecordId = #{taskexecuterecordid,jdbcType=VARCHAR}, 120 | errorKey = #{errorkey,jdbcType=VARCHAR}, 121 | createTime = #{createtime,jdbcType=BIGINT}, 122 | lastModifyTime = #{lastmodifytime,jdbcType=BIGINT} 123 | where id = #{id,jdbcType=BIGINT} 124 | 125 | 126 | 132 | 133 | -------------------------------------------------------------------------------- /src/main/resources/mapper/QuartzTaskRecordsMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | id, taskNo, timeKeyValue, executeTime, taskStatus, failcount, failReason, createTime, 17 | lastModifyTime 18 | 19 | 25 | 26 | delete from quartz_task_records 27 | where id = #{id,jdbcType=BIGINT} 28 | 29 | 31 | insert into quartz_task_records (taskNo, timeKeyValue, 32 | executeTime, taskStatus, failcount, 33 | failReason, createTime, lastModifyTime 34 | ) 35 | values (#{taskno,jdbcType=VARCHAR}, #{timekeyvalue,jdbcType=VARCHAR}, 36 | #{executetime,jdbcType=BIGINT}, #{taskstatus,jdbcType=VARCHAR}, #{failcount,jdbcType=INTEGER}, 37 | #{failreason,jdbcType=VARCHAR}, #{createtime,jdbcType=BIGINT}, #{lastmodifytime,jdbcType=BIGINT} 38 | ) 39 | 40 | 41 | insert into quartz_task_records 42 | 43 | 44 | id, 45 | 46 | 47 | taskNo, 48 | 49 | 50 | timeKeyValue, 51 | 52 | 53 | executeTime, 54 | 55 | 56 | taskStatus, 57 | 58 | 59 | failcount, 60 | 61 | 62 | failReason, 63 | 64 | 65 | createTime, 66 | 67 | 68 | lastModifyTime, 69 | 70 | 71 | 72 | 73 | #{id,jdbcType=BIGINT}, 74 | 75 | 76 | #{taskno,jdbcType=VARCHAR}, 77 | 78 | 79 | #{timekeyvalue,jdbcType=VARCHAR}, 80 | 81 | 82 | #{executetime,jdbcType=BIGINT}, 83 | 84 | 85 | #{taskstatus,jdbcType=VARCHAR}, 86 | 87 | 88 | #{failcount,jdbcType=INTEGER}, 89 | 90 | 91 | #{failreason,jdbcType=VARCHAR}, 92 | 93 | 94 | #{createtime,jdbcType=BIGINT}, 95 | 96 | 97 | #{lastmodifytime,jdbcType=BIGINT}, 98 | 99 | 100 | 101 | 102 | update quartz_task_records 103 | 104 | 105 | taskNo = #{taskno,jdbcType=VARCHAR}, 106 | 107 | 108 | timeKeyValue = #{timekeyvalue,jdbcType=VARCHAR}, 109 | 110 | 111 | executeTime = #{executetime,jdbcType=BIGINT}, 112 | 113 | 114 | taskStatus = #{taskstatus,jdbcType=VARCHAR}, 115 | 116 | 117 | failcount = #{failcount,jdbcType=INTEGER}, 118 | 119 | 120 | failReason = #{failreason,jdbcType=VARCHAR}, 121 | 122 | 123 | createTime = #{createtime,jdbcType=BIGINT}, 124 | 125 | 126 | lastModifyTime = #{lastmodifytime,jdbcType=BIGINT}, 127 | 128 | 129 | where id = #{id,jdbcType=BIGINT} 130 | 131 | 132 | update quartz_task_records 133 | set taskNo = #{taskno,jdbcType=VARCHAR}, 134 | timeKeyValue = #{timekeyvalue,jdbcType=VARCHAR}, 135 | executeTime = #{executetime,jdbcType=BIGINT}, 136 | taskStatus = #{taskstatus,jdbcType=VARCHAR}, 137 | failcount = #{failcount,jdbcType=INTEGER}, 138 | failReason = #{failreason,jdbcType=VARCHAR}, 139 | createTime = #{createtime,jdbcType=BIGINT}, 140 | lastModifyTime = #{lastmodifytime,jdbcType=BIGINT} 141 | where id = #{id,jdbcType=BIGINT} 142 | 143 | 144 | 149 | 150 | -------------------------------------------------------------------------------- /src/main/resources/templates/addtask.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 定时任务新增页面 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 |
19 |
20 |
21 |
22 |

新增定时任务项

23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |


31 |
32 |
34 |
35 |

36 |
37 |
39 |
40 |
41 |

42 |
43 |
44 | 47 |
48 |
49 | 50 |

51 |
52 |
54 |
55 |

56 |
57 |
58 | 62 |
63 |
64 |

65 |
66 |
67 |
68 |

69 |
70 |
72 |
73 |

74 |
75 |
77 |
78 |


79 |        81 | 82 |
83 |
84 |
85 |
86 |
87 |
88 | 89 | 131 | 132 | 133 | -------------------------------------------------------------------------------- /src/main/resources/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 定时任务后台管理页面 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 |
19 |
20 |
21 |
22 |

定时任务列表

23 |
24 |
25 |
26 | 28 |
29 |
30 |
31 |
32 |
33 |
34 | 35 |
36 |     37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 63 | 69 | 74 | 90 | 91 | 92 |
任务编号任务名称定时配置cron冻结状态执行方执行方式创建时间最后修改时间操作
61 | 62 | 64 | 65 | 66 | 未冻结 67 | 已冻结 68 | 70 | 71 | kafka 72 | http 73 | 75 | 76 | 77 |   81 |   85 | 87 | 89 |
93 |
94 |
95 | 总共条记录 96 |
97 | 98 |
99 | 126 |
127 |
128 |
129 |
130 |
131 | 132 | 180 | 181 | 182 | -------------------------------------------------------------------------------- /src/main/resources/templates/updatetask.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 定时任务修改 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 |
19 |
20 |
21 |
22 |

修改定时任务项

23 |
24 |
25 |
26 | 27 | 28 | 30 | 32 | 34 | 36 |
37 |
39 |
40 |
41 |


42 |
43 |
46 |
47 |

48 |
49 |
53 |
54 |
55 |

56 |
57 |
58 | 66 |
67 |
68 | 69 |

70 |
71 |
74 |
75 |

76 |
77 |
78 | 85 |
86 |
87 |

88 |
89 |
91 |
92 |

93 |
94 |
98 |
99 |

100 |
101 |
104 |
105 |


106 |        108 | 109 |
110 | 111 |
112 |
113 |
114 |
115 |
116 | 117 | 172 | 173 | 174 | -------------------------------------------------------------------------------- /src/main/resources/mapper/QuartzTaskInformationsMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | id, version, taskNo, taskName, schedulerRule, frozenStatus, executorNo, frozenTime, 23 | unfrozenTime, createTime, lastModifyTime, sendType, url, executeParamter, timeKey 24 | 25 | 31 | 32 | delete from quartz_task_informations 33 | where id = #{id,jdbcType=BIGINT} 34 | 35 | 36 | insert into quartz_task_informations (id, version, taskNo, 37 | taskName, schedulerRule, frozenStatus, 38 | executorNo, frozenTime, unfrozenTime, 39 | createTime, lastModifyTime, sendType, 40 | url, executeParamter, timeKey 41 | ) 42 | values (#{id,jdbcType=BIGINT}, #{version,jdbcType=INTEGER}, #{taskno,jdbcType=VARCHAR}, 43 | #{taskname,jdbcType=VARCHAR}, #{schedulerrule,jdbcType=VARCHAR}, #{frozenstatus,jdbcType=VARCHAR}, 44 | #{executorno,jdbcType=VARCHAR}, #{frozentime,jdbcType=BIGINT}, #{unfrozentime,jdbcType=BIGINT}, 45 | #{createtime,jdbcType=BIGINT}, #{lastmodifytime,jdbcType=BIGINT}, #{sendtype,jdbcType=VARCHAR}, 46 | #{url,jdbcType=VARCHAR}, #{executeparamter,jdbcType=VARCHAR}, #{timekey,jdbcType=VARCHAR} 47 | ) 48 | 49 | 50 | insert into quartz_task_informations 51 | 52 | 53 | id, 54 | 55 | 56 | version, 57 | 58 | 59 | taskNo, 60 | 61 | 62 | taskName, 63 | 64 | 65 | schedulerRule, 66 | 67 | 68 | frozenStatus, 69 | 70 | 71 | executorNo, 72 | 73 | 74 | frozenTime, 75 | 76 | 77 | unfrozenTime, 78 | 79 | 80 | createTime, 81 | 82 | 83 | lastModifyTime, 84 | 85 | 86 | sendType, 87 | 88 | 89 | url, 90 | 91 | 92 | executeParamter, 93 | 94 | 95 | timeKey, 96 | 97 | 98 | 99 | 100 | #{id,jdbcType=BIGINT}, 101 | 102 | 103 | #{version,jdbcType=INTEGER}, 104 | 105 | 106 | #{taskno,jdbcType=VARCHAR}, 107 | 108 | 109 | #{taskname,jdbcType=VARCHAR}, 110 | 111 | 112 | #{schedulerrule,jdbcType=VARCHAR}, 113 | 114 | 115 | #{frozenstatus,jdbcType=VARCHAR}, 116 | 117 | 118 | #{executorno,jdbcType=VARCHAR}, 119 | 120 | 121 | #{frozentime,jdbcType=BIGINT}, 122 | 123 | 124 | #{unfrozentime,jdbcType=BIGINT}, 125 | 126 | 127 | #{createtime,jdbcType=BIGINT}, 128 | 129 | 130 | #{lastmodifytime,jdbcType=BIGINT}, 131 | 132 | 133 | #{sendtype,jdbcType=VARCHAR}, 134 | 135 | 136 | #{url,jdbcType=VARCHAR}, 137 | 138 | 139 | #{executeparamter,jdbcType=VARCHAR}, 140 | 141 | 142 | #{timekey,jdbcType=VARCHAR}, 143 | 144 | 145 | 146 | 148 | update quartz_task_informations 149 | 150 | 151 | version = version+1, 152 | 153 | 154 | taskNo = #{taskno,jdbcType=VARCHAR}, 155 | 156 | 157 | taskName = #{taskname,jdbcType=VARCHAR}, 158 | 159 | 160 | schedulerRule = #{schedulerrule,jdbcType=VARCHAR}, 161 | 162 | 163 | frozenStatus = #{frozenstatus,jdbcType=VARCHAR}, 164 | 165 | 166 | executorNo = #{executorno,jdbcType=VARCHAR}, 167 | 168 | 169 | frozenTime = #{frozentime,jdbcType=BIGINT}, 170 | 171 | 172 | unfrozenTime = #{unfrozentime,jdbcType=BIGINT}, 173 | 174 | 175 | createTime = #{createtime,jdbcType=BIGINT}, 176 | 177 | 178 | lastModifyTime = #{lastmodifytime,jdbcType=BIGINT}, 179 | 180 | 181 | sendType = #{sendtype,jdbcType=VARCHAR}, 182 | 183 | 184 | url = #{url,jdbcType=VARCHAR}, 185 | 186 | 187 | executeParamter = #{executeparamter,jdbcType=VARCHAR}, 188 | 189 | 190 | timeKey = #{timekey,jdbcType=VARCHAR}, 191 | 192 | 193 | where id = #{id,jdbcType=BIGINT} and version = #{version} 194 | 195 | 196 | update quartz_task_informations 197 | set version = #{version,jdbcType=INTEGER}, 198 | taskNo = #{taskno,jdbcType=VARCHAR}, 199 | taskName = #{taskname,jdbcType=VARCHAR}, 200 | schedulerRule = #{schedulerrule,jdbcType=VARCHAR}, 201 | frozenStatus = #{frozenstatus,jdbcType=VARCHAR}, 202 | executorNo = #{executorno,jdbcType=VARCHAR}, 203 | frozenTime = #{frozentime,jdbcType=BIGINT}, 204 | unfrozenTime = #{unfrozentime,jdbcType=BIGINT}, 205 | createTime = #{createtime,jdbcType=BIGINT}, 206 | lastModifyTime = #{lastmodifytime,jdbcType=BIGINT}, 207 | sendType = #{sendtype,jdbcType=VARCHAR}, 208 | url = #{url,jdbcType=VARCHAR}, 209 | executeParamter = #{executeparamter,jdbcType=VARCHAR}, 210 | timeKey = #{timekey,jdbcType=VARCHAR} 211 | where id = #{id,jdbcType=BIGINT} 212 | 213 | 214 | 225 | 226 | 229 | 230 | 236 | 237 | 242 | 243 | 244 | -------------------------------------------------------------------------------- /src/main/java/com/quartz/cn/springbootquartzdemo/service/quartz/impl/QuartzServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.quartz.cn.springbootquartzdemo.service.quartz.impl; 2 | 3 | 4 | import com.quartz.cn.springbootquartzdemo.bean.QuartzTaskErrors; 5 | import com.quartz.cn.springbootquartzdemo.bean.QuartzTaskInformations; 6 | import com.quartz.cn.springbootquartzdemo.bean.QuartzTaskRecords; 7 | import com.quartz.cn.springbootquartzdemo.job.QuartzMainJobFactory; 8 | import com.quartz.cn.springbootquartzdemo.service.quartz.QuartzService; 9 | import com.quartz.cn.springbootquartzdemo.service.quartz.QuartzTaskErrorsService; 10 | import com.quartz.cn.springbootquartzdemo.service.quartz.QuartzTaskInformationsService; 11 | import com.quartz.cn.springbootquartzdemo.service.quartz.QuartzTaskRecordsService; 12 | import com.quartz.cn.springbootquartzdemo.util.CommonUtil; 13 | import com.quartz.cn.springbootquartzdemo.util.HttpClientUtil; 14 | import com.quartz.cn.springbootquartzdemo.util.ResultEnum; 15 | import com.quartz.cn.springbootquartzdemo.util.ResultUtil; 16 | import com.quartz.cn.springbootquartzdemo.vo.QuartzTaskRecordsVo; 17 | import org.apache.commons.collections.CollectionUtils; 18 | import org.quartz.*; 19 | import org.slf4j.Logger; 20 | import org.slf4j.LoggerFactory; 21 | import org.springframework.beans.BeanUtils; 22 | import org.springframework.beans.factory.InitializingBean; 23 | import org.springframework.beans.factory.annotation.Autowired; 24 | import org.springframework.kafka.core.KafkaTemplate; 25 | import org.springframework.scheduling.quartz.SchedulerFactoryBean; 26 | import org.springframework.stereotype.Service; 27 | import org.springframework.transaction.annotation.Transactional; 28 | 29 | import java.util.ArrayList; 30 | import java.util.List; 31 | import java.util.concurrent.atomic.AtomicInteger; 32 | 33 | /** 34 | * @ClassName QuartzServiceImpl 35 | * @Description quartz service逻辑相关 36 | * @Author simonsfan 37 | * @Date 2019/1/3 38 | * Version 1.0 39 | */ 40 | @Service 41 | public class QuartzServiceImpl implements QuartzService, InitializingBean { 42 | 43 | private static final Logger logger = LoggerFactory.getLogger(QuartzServiceImpl.class); 44 | public static final String QUARTZ_TOPIC = "quartztopic"; 45 | 46 | private AtomicInteger atomicInteger; 47 | 48 | @Autowired 49 | private KafkaTemplate kafkaTemplate; 50 | 51 | @Autowired 52 | private QuartzTaskInformationsService quartzTaskInformationsService; 53 | 54 | @Autowired 55 | private QuartzTaskErrorsService quartzTaskErrorsService; 56 | 57 | @Autowired 58 | private QuartzTaskRecordsService quartzTaskRecordsService; 59 | 60 | @Autowired 61 | private SchedulerFactoryBean schedulerBean; 62 | 63 | /** 64 | * 列表查询所有定时任务 65 | * 66 | * @return 67 | */ 68 | @Override 69 | public List getTaskList(String taskNo, String currentPage) { 70 | List quartzTaskInformations = quartzTaskInformationsService.selectList(taskNo, currentPage); 71 | return quartzTaskInformations; 72 | } 73 | 74 | /** 75 | * 新增定时任务 76 | * 77 | * @param quartzTaskInformations 78 | * @return 79 | */ 80 | @Override 81 | public String addTask(QuartzTaskInformations quartzTaskInformations) { 82 | String result = quartzTaskInformationsService.insert(quartzTaskInformations); 83 | return result; 84 | } 85 | 86 | @Override 87 | public QuartzTaskInformations getTaskById(String id) { 88 | return quartzTaskInformationsService.getTaskById(id); 89 | } 90 | 91 | @Override 92 | public String updateTask(QuartzTaskInformations quartzTaskInformations) { 93 | return quartzTaskInformationsService.updateTask(quartzTaskInformations); 94 | } 95 | 96 | /** 97 | * 启动 or 暂停定时任务 98 | * 99 | * @param taskNo 100 | * @return 101 | * @throws SchedulerException 102 | */ 103 | @Override 104 | @Transactional 105 | public String startJob(String taskNo) throws SchedulerException { 106 | QuartzTaskInformations quartzTaskInformation = quartzTaskInformationsService.getTaskByTaskNo(taskNo); 107 | if (quartzTaskInformation == null) { 108 | return ResultUtil.success(ResultEnum.NO_DATA.getCode(), ResultEnum.NO_DATA.getMessage()); 109 | } 110 | String status = quartzTaskInformation.getFrozenstatus(); 111 | Scheduler scheduler = schedulerBean.getScheduler(); 112 | long currentTimeMillis = System.currentTimeMillis(); 113 | QuartzTaskInformations task = new QuartzTaskInformations(); 114 | task.setId(quartzTaskInformation.getId()); 115 | task.setVersion(quartzTaskInformation.getVersion()); 116 | //说明要暂停 117 | if (ResultEnum.UNFROZEN.name().equals(status)) { 118 | scheduler.deleteJob(new JobKey(taskNo)); 119 | task.setFrozentime(currentTimeMillis); 120 | task.setFrozenstatus(ResultEnum.FROZEN.name()); 121 | //说明要启动 122 | } else if (ResultEnum.FROZEN.name().equals(status)) { 123 | scheduler.deleteJob(new JobKey(taskNo)); 124 | this.schedule(quartzTaskInformation, scheduler); 125 | task.setUnfrozentime(currentTimeMillis); 126 | task.setFrozenstatus(ResultEnum.UNFROZEN.name()); 127 | } 128 | task.setLastmodifytime(currentTimeMillis); 129 | quartzTaskInformationsService.updateStatusById(task); 130 | logger.info("taskNo={},taskName={},scheduleRule={},任务{}成功", quartzTaskInformation.getTaskno(), quartzTaskInformation.getTaskname(), quartzTaskInformation.getSchedulerrule(), ResultEnum.FROZEN.name().equals(status) ? "启动" : "暂停"); 131 | return ResultUtil.success(ResultEnum.SUCCESS.getCode(), ResultEnum.SUCCESS.getMessage()); 132 | } 133 | 134 | /** 135 | * 初始化加载定时任务 136 | * 137 | * @throws Exception 138 | */ 139 | @Override 140 | public void initLoadOnlineTasks() { 141 | List unnfrozenTasks = quartzTaskInformationsService.getUnnfrozenTasks(ResultEnum.UNFROZEN.name()); 142 | if (CollectionUtils.isEmpty(unnfrozenTasks)) { 143 | logger.info("没有需要初始化加载的定时任务"); 144 | return; 145 | } 146 | Scheduler scheduler = schedulerBean.getScheduler(); 147 | for (QuartzTaskInformations unnfrozenTask : unnfrozenTasks) { 148 | try { 149 | this.schedule(unnfrozenTask, scheduler); 150 | } catch (Exception e) { 151 | logger.error("系统初始化加载定时任务:taskno={},taskname={}失败原因exception={}", unnfrozenTask.getTaskno(), unnfrozenTask.getTaskname(), e); 152 | } 153 | } 154 | } 155 | 156 | /** 157 | * 初始化加载定时任务 158 | * 159 | * @throws Exception 160 | */ 161 | @Override 162 | public void afterPropertiesSet() throws Exception { 163 | this.initLoadOnlineTasks(); 164 | } 165 | 166 | @Override 167 | public QuartzTaskRecords addTaskRecords(String taskNo) { 168 | QuartzTaskRecords quartzTaskRecords = null; 169 | try { 170 | QuartzTaskInformations quartzTaskInformation = quartzTaskInformationsService.getTaskByTaskNo(taskNo); 171 | if (null == quartzTaskInformation || ResultEnum.FROZEN.name().equals(quartzTaskInformation.getFrozenstatus())) { 172 | logger.info("taskNo={} not exist or status is frozen!"); 173 | return null; 174 | } 175 | long currentTimeMillis = System.currentTimeMillis(); 176 | QuartzTaskInformations task = new QuartzTaskInformations(); 177 | task.setId(quartzTaskInformation.getId()); 178 | task.setLastmodifytime(currentTimeMillis); 179 | quartzTaskInformationsService.updateTask(task); 180 | logger.info("taskNo={},taskName={}更新最后修改时间成功", quartzTaskInformation.getTaskno(), quartzTaskInformation.getTaskname()); 181 | 182 | quartzTaskRecords = new QuartzTaskRecords(); 183 | quartzTaskRecords.setTaskno(taskNo); 184 | quartzTaskRecords.setTimekeyvalue(quartzTaskInformation.getTimekey()); 185 | quartzTaskRecords.setExecutetime(currentTimeMillis); 186 | quartzTaskRecords.setTaskstatus(ResultEnum.INIT.name()); 187 | quartzTaskRecords.setFailcount(0); 188 | quartzTaskRecords.setFailreason(""); 189 | quartzTaskRecords.setCreatetime(currentTimeMillis); 190 | quartzTaskRecords.setLastmodifytime(currentTimeMillis); 191 | quartzTaskRecordsService.addTaskRecords(quartzTaskRecords); 192 | logger.info("taskNo={},taskName={}添加执行记录表成功", quartzTaskInformation.getTaskno(), quartzTaskInformation.getTaskname()); 193 | } catch (Exception ex) { 194 | logger.error("添加执行记录表异常exceptio={}", ex); 195 | return null; 196 | } 197 | return quartzTaskRecords; 198 | } 199 | 200 | @Override 201 | public Integer updateRecordById(Integer count, Long id) { 202 | QuartzTaskRecords records = new QuartzTaskRecords(); 203 | records.setId(id); 204 | records.setFailcount(count); 205 | records.setLastmodifytime(System.currentTimeMillis()); 206 | if (count > 0) { 207 | records.setTaskstatus(ResultEnum.FAIL.name()); 208 | } else { 209 | records.setTaskstatus(ResultEnum.SUCCESS.name()); 210 | } 211 | return quartzTaskRecordsService.updateTaskRecords(records); 212 | } 213 | 214 | @Override 215 | public Integer updateModifyTimeById(QuartzTaskInformations quartzTaskInformations) { 216 | return quartzTaskInformationsService.updateModifyTimeById(quartzTaskInformations); 217 | } 218 | 219 | @Override 220 | public Integer addTaskErrorRecord(String id, String errorKey, String errorValue) { 221 | QuartzTaskErrors taskErrors = new QuartzTaskErrors(); 222 | taskErrors.setTaskexecuterecordid(String.valueOf(id)); 223 | taskErrors.setErrorkey(errorKey); 224 | taskErrors.setCreatetime(System.currentTimeMillis()); 225 | taskErrors.setLastmodifytime(System.currentTimeMillis()); 226 | taskErrors.setErrorvalue(errorValue); 227 | return quartzTaskErrorsService.addTaskErrorRecord(taskErrors); 228 | } 229 | 230 | public void schedule(QuartzTaskInformations quartzTaskInfo, Scheduler scheduler) throws SchedulerException { 231 | TriggerKey triggerKey = TriggerKey.triggerKey(quartzTaskInfo.getTaskno(), Scheduler.DEFAULT_GROUP); 232 | JobDetail jobDetail = JobBuilder.newJob(QuartzMainJobFactory.class).withDescription(quartzTaskInfo.getTaskname()).withIdentity(quartzTaskInfo.getTaskno(), Scheduler.DEFAULT_GROUP).build(); 233 | JobDataMap jobDataMap = jobDetail.getJobDataMap(); 234 | jobDataMap.put("id", quartzTaskInfo.getId().toString()); 235 | jobDataMap.put("taskNo", quartzTaskInfo.getTaskno()); 236 | jobDataMap.put("executorNo", quartzTaskInfo.getExecutorno()); 237 | jobDataMap.put("sendType", quartzTaskInfo.getSendtype()); 238 | jobDataMap.put("url", quartzTaskInfo.getUrl()); 239 | jobDataMap.put("executeParameter", quartzTaskInfo.getExecuteparamter()); 240 | CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(quartzTaskInfo.getSchedulerrule()); 241 | CronTrigger cronTrigger = TriggerBuilder.newTrigger().withDescription(quartzTaskInfo.getTaskname()).withIdentity(triggerKey).withSchedule(cronScheduleBuilder).build(); 242 | scheduler.scheduleJob(jobDetail, cronTrigger); 243 | logger.info("taskNo={},taskName={},scheduleRule={} load to quartz success!", quartzTaskInfo.getTaskno(), quartzTaskInfo.getTaskname(), quartzTaskInfo.getSchedulerrule()); 244 | } 245 | 246 | /** 247 | * kafka推送消息 248 | * 249 | * @param message 250 | */ 251 | @Override 252 | public void sendMessage(String message) { 253 | kafkaTemplate.send(QUARTZ_TOPIC, message); 254 | logger.info("给kafka推送消息message={}成功", message); 255 | } 256 | 257 | @Override 258 | public List taskRecords(String taskNo) { 259 | List quartzTaskRecords = quartzTaskRecordsService.listTaskRecordsByTaskNo(taskNo); 260 | QuartzTaskRecordsVo recordsVo = null; 261 | List voList = new ArrayList<>(); 262 | for (QuartzTaskRecords quartzTaskRecord : quartzTaskRecords) { 263 | recordsVo = new QuartzTaskRecordsVo(); 264 | BeanUtils.copyProperties(quartzTaskRecord, recordsVo); 265 | recordsVo.setTime(quartzTaskRecord.getLastmodifytime() - quartzTaskRecord.getCreatetime()); 266 | voList.add(recordsVo); 267 | } 268 | return voList; 269 | } 270 | 271 | /** 272 | * 立即运行一次定时任务 273 | * 274 | * @param taskNo 275 | * @return 276 | */ 277 | @Override 278 | public String runTaskRightNow(String taskNo) { 279 | atomicInteger = new AtomicInteger(0); 280 | QuartzTaskInformations quartzTaskInformations = quartzTaskInformationsService.getTaskByTaskNo(taskNo); 281 | if (quartzTaskInformations == null) { 282 | return ResultUtil.success(ResultEnum.NO_DATA.getCode(), ResultEnum.NO_DATA.getMessage()); 283 | } 284 | Long id = quartzTaskInformations.getId(); 285 | String sendType = quartzTaskInformations.getSendtype(); 286 | String executorNo = quartzTaskInformations.getExecutorno(); 287 | String url = quartzTaskInformations.getUrl(); 288 | String executeParameter = quartzTaskInformations.getExecuteparamter(); 289 | logger.info("定时任务被执行:taskNo={},executorNo={},sendType={},url={},executeParameter={}", taskNo, executorNo, sendType, url, executeParameter); 290 | QuartzTaskRecords records = null; 291 | try { 292 | //保存定时任务的执行记录 293 | records = this.addTaskRecords(taskNo); 294 | if (null == records || !ResultEnum.INIT.name().equals(records.getTaskstatus())) { 295 | logger.info("taskNo={}立即运行失--->>保存执行记录失败", taskNo); 296 | return ResultUtil.success(ResultEnum.RUN_NOW_FAIL.getCode(), ResultEnum.RUN_NOW_FAIL.getMessage()); 297 | } 298 | 299 | if (ResultEnum.HTTP.getMessage().equals(sendType)) { 300 | try { 301 | HttpClientUtil.doPost(url, "text/json", executeParameter); 302 | logger.info(""); 303 | } catch (Exception ex) { 304 | logger.error(""); 305 | atomicInteger.incrementAndGet(); 306 | throw ex; 307 | } 308 | } else if (ResultEnum.KAFKA.getMessage().equals(sendType)) { 309 | try { 310 | String message = new StringBuffer(taskNo).append(":").append(executeParameter).toString(); 311 | this.sendMessage(message); 312 | } catch (Exception ex) { 313 | logger.error(""); 314 | atomicInteger.incrementAndGet(); 315 | throw ex; 316 | } 317 | } 318 | } catch (Exception ex) { 319 | logger.error(""); 320 | atomicInteger.incrementAndGet(); 321 | this.addTaskErrorRecord(records.getId().toString(), taskNo + ":" + ex.getMessage(), CommonUtil.getExceptionDetail(ex)); 322 | } 323 | //更改record表的执行状态、最后修改时间、失败个数 324 | this.updateRecordById(atomicInteger.get(), records.getId()); 325 | 326 | //更新taskinfo表的最后修改时间 327 | QuartzTaskInformations quartzTaskInformation = new QuartzTaskInformations(); 328 | quartzTaskInformation.setId(id); 329 | quartzTaskInformation.setLastmodifytime(System.currentTimeMillis()); 330 | this.updateTask(quartzTaskInformation); 331 | return ResultUtil.success(ResultEnum.SUCCESS.getCode(), ResultEnum.SUCCESS.getMessage()); 332 | } 333 | 334 | @Override 335 | public QuartzTaskErrors detailTaskErrors(String recordId) { 336 | return quartzTaskErrorsService.detailTaskErrors(recordId); 337 | } 338 | 339 | 340 | } 341 | -------------------------------------------------------------------------------- /src/main/resources/static/css/simple-line-icons.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'simple-line-icons'; 3 | src: url('../../fonts/Simple-Line-Icons.eot?v=2.2.2'); 4 | src: url('../../fonts/Simple-Line-Icons.eot?#iefix&v=2.2.2') format('embedded-opentype'), 5 | url('../../fonts/Simple-Line-Icons.ttf?v=2.2.2') format('truetype'), 6 | url('../../fonts/Simple-Line-Icons.woff2?v=2.2.2') format('woff2'), 7 | url('../../fonts/Simple-Line-Icons.woff?v=2.2.2') format('woff'), 8 | url('../../fonts/Simple-Line-Icons.svg?v=2.2.2#simple-line-icons') format('svg'); 9 | font-weight: normal; 10 | font-style: normal; 11 | } 12 | /* 13 | Use the following CSS code if you want to have a class per icon. 14 | Instead of a list of all class selectors, you can use the generic [class*="icon-"] selector, but it's slower: 15 | */ 16 | .icon-user, 17 | .icon-people, 18 | .icon-user-female, 19 | .icon-user-follow, 20 | .icon-user-following, 21 | .icon-user-unfollow, 22 | .icon-login, 23 | .icon-logout, 24 | .icon-emotsmile, 25 | .icon-phone, 26 | .icon-call-end, 27 | .icon-call-in, 28 | .icon-call-out, 29 | .icon-map, 30 | .icon-location-pin, 31 | .icon-direction, 32 | .icon-directions, 33 | .icon-compass, 34 | .icon-layers, 35 | .icon-menu, 36 | .icon-list, 37 | .icon-options-vertical, 38 | .icon-options, 39 | .icon-arrow-down, 40 | .icon-arrow-left, 41 | .icon-arrow-right, 42 | .icon-arrow-up, 43 | .icon-arrow-up-circle, 44 | .icon-arrow-left-circle, 45 | .icon-arrow-right-circle, 46 | .icon-arrow-down-circle, 47 | .icon-check, 48 | .icon-clock, 49 | .icon-plus, 50 | .icon-close, 51 | .icon-trophy, 52 | .icon-screen-smartphone, 53 | .icon-screen-desktop, 54 | .icon-plane, 55 | .icon-notebook, 56 | .icon-mustache, 57 | .icon-mouse, 58 | .icon-magnet, 59 | .icon-energy, 60 | .icon-disc, 61 | .icon-cursor, 62 | .icon-cursor-move, 63 | .icon-crop, 64 | .icon-chemistry, 65 | .icon-speedometer, 66 | .icon-shield, 67 | .icon-screen-tablet, 68 | .icon-magic-wand, 69 | .icon-hourglass, 70 | .icon-graduation, 71 | .icon-ghost, 72 | .icon-game-controller, 73 | .icon-fire, 74 | .icon-eyeglass, 75 | .icon-envelope-open, 76 | .icon-envelope-letter, 77 | .icon-bell, 78 | .icon-badge, 79 | .icon-anchor, 80 | .icon-wallet, 81 | .icon-vector, 82 | .icon-speech, 83 | .icon-puzzle, 84 | .icon-printer, 85 | .icon-present, 86 | .icon-playlist, 87 | .icon-pin, 88 | .icon-picture, 89 | .icon-handbag, 90 | .icon-globe-alt, 91 | .icon-globe, 92 | .icon-folder-alt, 93 | .icon-folder, 94 | .icon-film, 95 | .icon-feed, 96 | .icon-drop, 97 | .icon-drawar, 98 | .icon-docs, 99 | .icon-doc, 100 | .icon-diamond, 101 | .icon-cup, 102 | .icon-calculator, 103 | .icon-bubbles, 104 | .icon-briefcase, 105 | .icon-book-open, 106 | .icon-basket-loaded, 107 | .icon-basket, 108 | .icon-bag, 109 | .icon-action-undo, 110 | .icon-action-redo, 111 | .icon-wrench, 112 | .icon-umbrella, 113 | .icon-trash, 114 | .icon-tag, 115 | .icon-support, 116 | .icon-frame, 117 | .icon-size-fullscreen, 118 | .icon-size-actual, 119 | .icon-shuffle, 120 | .icon-share-alt, 121 | .icon-share, 122 | .icon-rocket, 123 | .icon-question, 124 | .icon-pie-chart, 125 | .icon-pencil, 126 | .icon-note, 127 | .icon-loop, 128 | .icon-home, 129 | .icon-grid, 130 | .icon-graph, 131 | .icon-microphone, 132 | .icon-music-tone-alt, 133 | .icon-music-tone, 134 | .icon-earphones-alt, 135 | .icon-earphones, 136 | .icon-equalizer, 137 | .icon-like, 138 | .icon-dislike, 139 | .icon-control-start, 140 | .icon-control-rewind, 141 | .icon-control-play, 142 | .icon-control-pause, 143 | .icon-control-forward, 144 | .icon-control-end, 145 | .icon-volume-1, 146 | .icon-volume-2, 147 | .icon-volume-off, 148 | .icon-calendar, 149 | .icon-bulb, 150 | .icon-chart, 151 | .icon-ban, 152 | .icon-bubble, 153 | .icon-camrecorder, 154 | .icon-camera, 155 | .icon-cloud-download, 156 | .icon-cloud-upload, 157 | .icon-envelope, 158 | .icon-eye, 159 | .icon-flag, 160 | .icon-heart, 161 | .icon-info, 162 | .icon-key, 163 | .icon-link, 164 | .icon-lock, 165 | .icon-lock-open, 166 | .icon-magnifier, 167 | .icon-magnifier-add, 168 | .icon-magnifier-remove, 169 | .icon-paper-clip, 170 | .icon-paper-plane, 171 | .icon-power, 172 | .icon-refresh, 173 | .icon-reload, 174 | .icon-settings, 175 | .icon-star, 176 | .icon-symble-female, 177 | .icon-symbol-male, 178 | .icon-target, 179 | .icon-credit-card, 180 | .icon-paypal, 181 | .icon-social-tumblr, 182 | .icon-social-twitter, 183 | .icon-social-facebook, 184 | .icon-social-instagram, 185 | .icon-social-linkedin, 186 | .icon-social-pinterest, 187 | .icon-social-github, 188 | .icon-social-gplus, 189 | .icon-social-reddit, 190 | .icon-social-skype, 191 | .icon-social-dribbble, 192 | .icon-social-behance, 193 | .icon-social-foursqare, 194 | .icon-social-soundcloud, 195 | .icon-social-spotify, 196 | .icon-social-stumbleupon, 197 | .icon-social-youtube, 198 | .icon-social-dropbox { 199 | font-family: 'simple-line-icons'; 200 | speak: none; 201 | font-style: normal; 202 | font-weight: normal; 203 | font-variant: normal; 204 | text-transform: none; 205 | line-height: 1; 206 | /* Better Font Rendering =========== */ 207 | -webkit-font-smoothing: antialiased; 208 | -moz-osx-font-smoothing: grayscale; 209 | } 210 | .icon-user:before { 211 | content: "\e005"; 212 | } 213 | .icon-people:before { 214 | content: "\e001"; 215 | } 216 | .icon-user-female:before { 217 | content: "\e000"; 218 | } 219 | .icon-user-follow:before { 220 | content: "\e002"; 221 | } 222 | .icon-user-following:before { 223 | content: "\e003"; 224 | } 225 | .icon-user-unfollow:before { 226 | content: "\e004"; 227 | } 228 | .icon-login:before { 229 | content: "\e066"; 230 | } 231 | .icon-logout:before { 232 | content: "\e065"; 233 | } 234 | .icon-emotsmile:before { 235 | content: "\e021"; 236 | } 237 | .icon-phone:before { 238 | content: "\e600"; 239 | } 240 | .icon-call-end:before { 241 | content: "\e048"; 242 | } 243 | .icon-call-in:before { 244 | content: "\e047"; 245 | } 246 | .icon-call-out:before { 247 | content: "\e046"; 248 | } 249 | .icon-map:before { 250 | content: "\e033"; 251 | } 252 | .icon-location-pin:before { 253 | content: "\e096"; 254 | } 255 | .icon-direction:before { 256 | content: "\e042"; 257 | } 258 | .icon-directions:before { 259 | content: "\e041"; 260 | } 261 | .icon-compass:before { 262 | content: "\e045"; 263 | } 264 | .icon-layers:before { 265 | content: "\e034"; 266 | } 267 | .icon-menu:before { 268 | content: "\e601"; 269 | } 270 | .icon-list:before { 271 | content: "\e067"; 272 | } 273 | .icon-options-vertical:before { 274 | content: "\e602"; 275 | } 276 | .icon-options:before { 277 | content: "\e603"; 278 | } 279 | .icon-arrow-down:before { 280 | content: "\e604"; 281 | } 282 | .icon-arrow-left:before { 283 | content: "\e605"; 284 | } 285 | .icon-arrow-right:before { 286 | content: "\e606"; 287 | } 288 | .icon-arrow-up:before { 289 | content: "\e607"; 290 | } 291 | .icon-arrow-up-circle:before { 292 | content: "\e078"; 293 | } 294 | .icon-arrow-left-circle:before { 295 | content: "\e07a"; 296 | } 297 | .icon-arrow-right-circle:before { 298 | content: "\e079"; 299 | } 300 | .icon-arrow-down-circle:before { 301 | content: "\e07b"; 302 | } 303 | .icon-check:before { 304 | content: "\e080"; 305 | } 306 | .icon-clock:before { 307 | content: "\e081"; 308 | } 309 | .icon-plus:before { 310 | content: "\e095"; 311 | } 312 | .icon-close:before { 313 | content: "\e082"; 314 | } 315 | .icon-trophy:before { 316 | content: "\e006"; 317 | } 318 | .icon-screen-smartphone:before { 319 | content: "\e010"; 320 | } 321 | .icon-screen-desktop:before { 322 | content: "\e011"; 323 | } 324 | .icon-plane:before { 325 | content: "\e012"; 326 | } 327 | .icon-notebook:before { 328 | content: "\e013"; 329 | } 330 | .icon-mustache:before { 331 | content: "\e014"; 332 | } 333 | .icon-mouse:before { 334 | content: "\e015"; 335 | } 336 | .icon-magnet:before { 337 | content: "\e016"; 338 | } 339 | .icon-energy:before { 340 | content: "\e020"; 341 | } 342 | .icon-disc:before { 343 | content: "\e022"; 344 | } 345 | .icon-cursor:before { 346 | content: "\e06e"; 347 | } 348 | .icon-cursor-move:before { 349 | content: "\e023"; 350 | } 351 | .icon-crop:before { 352 | content: "\e024"; 353 | } 354 | .icon-chemistry:before { 355 | content: "\e026"; 356 | } 357 | .icon-speedometer:before { 358 | content: "\e007"; 359 | } 360 | .icon-shield:before { 361 | content: "\e00e"; 362 | } 363 | .icon-screen-tablet:before { 364 | content: "\e00f"; 365 | } 366 | .icon-magic-wand:before { 367 | content: "\e017"; 368 | } 369 | .icon-hourglass:before { 370 | content: "\e018"; 371 | } 372 | .icon-graduation:before { 373 | content: "\e019"; 374 | } 375 | .icon-ghost:before { 376 | content: "\e01a"; 377 | } 378 | .icon-game-controller:before { 379 | content: "\e01b"; 380 | } 381 | .icon-fire:before { 382 | content: "\e01c"; 383 | } 384 | .icon-eyeglass:before { 385 | content: "\e01d"; 386 | } 387 | .icon-envelope-open:before { 388 | content: "\e01e"; 389 | } 390 | .icon-envelope-letter:before { 391 | content: "\e01f"; 392 | } 393 | .icon-bell:before { 394 | content: "\e027"; 395 | } 396 | .icon-badge:before { 397 | content: "\e028"; 398 | } 399 | .icon-anchor:before { 400 | content: "\e029"; 401 | } 402 | .icon-wallet:before { 403 | content: "\e02a"; 404 | } 405 | .icon-vector:before { 406 | content: "\e02b"; 407 | } 408 | .icon-speech:before { 409 | content: "\e02c"; 410 | } 411 | .icon-puzzle:before { 412 | content: "\e02d"; 413 | } 414 | .icon-printer:before { 415 | content: "\e02e"; 416 | } 417 | .icon-present:before { 418 | content: "\e02f"; 419 | } 420 | .icon-playlist:before { 421 | content: "\e030"; 422 | } 423 | .icon-pin:before { 424 | content: "\e031"; 425 | } 426 | .icon-picture:before { 427 | content: "\e032"; 428 | } 429 | .icon-handbag:before { 430 | content: "\e035"; 431 | } 432 | .icon-globe-alt:before { 433 | content: "\e036"; 434 | } 435 | .icon-globe:before { 436 | content: "\e037"; 437 | } 438 | .icon-folder-alt:before { 439 | content: "\e039"; 440 | } 441 | .icon-folder:before { 442 | content: "\e089"; 443 | } 444 | .icon-film:before { 445 | content: "\e03a"; 446 | } 447 | .icon-feed:before { 448 | content: "\e03b"; 449 | } 450 | .icon-drop:before { 451 | content: "\e03e"; 452 | } 453 | .icon-drawar:before { 454 | content: "\e03f"; 455 | } 456 | .icon-docs:before { 457 | content: "\e040"; 458 | } 459 | .icon-doc:before { 460 | content: "\e085"; 461 | } 462 | .icon-diamond:before { 463 | content: "\e043"; 464 | } 465 | .icon-cup:before { 466 | content: "\e044"; 467 | } 468 | .icon-calculator:before { 469 | content: "\e049"; 470 | } 471 | .icon-bubbles:before { 472 | content: "\e04a"; 473 | } 474 | .icon-briefcase:before { 475 | content: "\e04b"; 476 | } 477 | .icon-book-open:before { 478 | content: "\e04c"; 479 | } 480 | .icon-basket-loaded:before { 481 | content: "\e04d"; 482 | } 483 | .icon-basket:before { 484 | content: "\e04e"; 485 | } 486 | .icon-bag:before { 487 | content: "\e04f"; 488 | } 489 | .icon-action-undo:before { 490 | content: "\e050"; 491 | } 492 | .icon-action-redo:before { 493 | content: "\e051"; 494 | } 495 | .icon-wrench:before { 496 | content: "\e052"; 497 | } 498 | .icon-umbrella:before { 499 | content: "\e053"; 500 | } 501 | .icon-trash:before { 502 | content: "\e054"; 503 | } 504 | .icon-tag:before { 505 | content: "\e055"; 506 | } 507 | .icon-support:before { 508 | content: "\e056"; 509 | } 510 | .icon-frame:before { 511 | content: "\e038"; 512 | } 513 | .icon-size-fullscreen:before { 514 | content: "\e057"; 515 | } 516 | .icon-size-actual:before { 517 | content: "\e058"; 518 | } 519 | .icon-shuffle:before { 520 | content: "\e059"; 521 | } 522 | .icon-share-alt:before { 523 | content: "\e05a"; 524 | } 525 | .icon-share:before { 526 | content: "\e05b"; 527 | } 528 | .icon-rocket:before { 529 | content: "\e05c"; 530 | } 531 | .icon-question:before { 532 | content: "\e05d"; 533 | } 534 | .icon-pie-chart:before { 535 | content: "\e05e"; 536 | } 537 | .icon-pencil:before { 538 | content: "\e05f"; 539 | } 540 | .icon-note:before { 541 | content: "\e060"; 542 | } 543 | .icon-loop:before { 544 | content: "\e064"; 545 | } 546 | .icon-home:before { 547 | content: "\e069"; 548 | } 549 | .icon-grid:before { 550 | content: "\e06a"; 551 | } 552 | .icon-graph:before { 553 | content: "\e06b"; 554 | } 555 | .icon-microphone:before { 556 | content: "\e063"; 557 | } 558 | .icon-music-tone-alt:before { 559 | content: "\e061"; 560 | } 561 | .icon-music-tone:before { 562 | content: "\e062"; 563 | } 564 | .icon-earphones-alt:before { 565 | content: "\e03c"; 566 | } 567 | .icon-earphones:before { 568 | content: "\e03d"; 569 | } 570 | .icon-equalizer:before { 571 | content: "\e06c"; 572 | } 573 | .icon-like:before { 574 | content: "\e068"; 575 | } 576 | .icon-dislike:before { 577 | content: "\e06d"; 578 | } 579 | .icon-control-start:before { 580 | content: "\e06f"; 581 | } 582 | .icon-control-rewind:before { 583 | content: "\e070"; 584 | } 585 | .icon-control-play:before { 586 | content: "\e071"; 587 | } 588 | .icon-control-pause:before { 589 | content: "\e072"; 590 | } 591 | .icon-control-forward:before { 592 | content: "\e073"; 593 | } 594 | .icon-control-end:before { 595 | content: "\e074"; 596 | } 597 | .icon-volume-1:before { 598 | content: "\e09f"; 599 | } 600 | .icon-volume-2:before { 601 | content: "\e0a0"; 602 | } 603 | .icon-volume-off:before { 604 | content: "\e0a1"; 605 | } 606 | .icon-calendar:before { 607 | content: "\e075"; 608 | } 609 | .icon-bulb:before { 610 | content: "\e076"; 611 | } 612 | .icon-chart:before { 613 | content: "\e077"; 614 | } 615 | .icon-ban:before { 616 | content: "\e07c"; 617 | } 618 | .icon-bubble:before { 619 | content: "\e07d"; 620 | } 621 | .icon-camrecorder:before { 622 | content: "\e07e"; 623 | } 624 | .icon-camera:before { 625 | content: "\e07f"; 626 | } 627 | .icon-cloud-download:before { 628 | content: "\e083"; 629 | } 630 | .icon-cloud-upload:before { 631 | content: "\e084"; 632 | } 633 | .icon-envelope:before { 634 | content: "\e086"; 635 | } 636 | .icon-eye:before { 637 | content: "\e087"; 638 | } 639 | .icon-flag:before { 640 | content: "\e088"; 641 | } 642 | .icon-heart:before { 643 | content: "\e08a"; 644 | } 645 | .icon-info:before { 646 | content: "\e08b"; 647 | } 648 | .icon-key:before { 649 | content: "\e08c"; 650 | } 651 | .icon-link:before { 652 | content: "\e08d"; 653 | } 654 | .icon-lock:before { 655 | content: "\e08e"; 656 | } 657 | .icon-lock-open:before { 658 | content: "\e08f"; 659 | } 660 | .icon-magnifier:before { 661 | content: "\e090"; 662 | } 663 | .icon-magnifier-add:before { 664 | content: "\e091"; 665 | } 666 | .icon-magnifier-remove:before { 667 | content: "\e092"; 668 | } 669 | .icon-paper-clip:before { 670 | content: "\e093"; 671 | } 672 | .icon-paper-plane:before { 673 | content: "\e094"; 674 | } 675 | .icon-power:before { 676 | content: "\e097"; 677 | } 678 | .icon-refresh:before { 679 | content: "\e098"; 680 | } 681 | .icon-reload:before { 682 | content: "\e099"; 683 | } 684 | .icon-settings:before { 685 | content: "\e09a"; 686 | } 687 | .icon-star:before { 688 | content: "\e09b"; 689 | } 690 | .icon-symble-female:before { 691 | content: "\e09c"; 692 | } 693 | .icon-symbol-male:before { 694 | content: "\e09d"; 695 | } 696 | .icon-target:before { 697 | content: "\e09e"; 698 | } 699 | .icon-credit-card:before { 700 | content: "\e025"; 701 | } 702 | .icon-paypal:before { 703 | content: "\e608"; 704 | } 705 | .icon-social-tumblr:before { 706 | content: "\e00a"; 707 | } 708 | .icon-social-twitter:before { 709 | content: "\e009"; 710 | } 711 | .icon-social-facebook:before { 712 | content: "\e00b"; 713 | } 714 | .icon-social-instagram:before { 715 | content: "\e609"; 716 | } 717 | .icon-social-linkedin:before { 718 | content: "\e60a"; 719 | } 720 | .icon-social-pinterest:before { 721 | content: "\e60b"; 722 | } 723 | .icon-social-github:before { 724 | content: "\e60c"; 725 | } 726 | .icon-social-gplus:before { 727 | content: "\e60d"; 728 | } 729 | .icon-social-reddit:before { 730 | content: "\e60e"; 731 | } 732 | .icon-social-skype:before { 733 | content: "\e60f"; 734 | } 735 | .icon-social-dribbble:before { 736 | content: "\e00d"; 737 | } 738 | .icon-social-behance:before { 739 | content: "\e610"; 740 | } 741 | .icon-social-foursqare:before { 742 | content: "\e611"; 743 | } 744 | .icon-social-soundcloud:before { 745 | content: "\e612"; 746 | } 747 | .icon-social-spotify:before { 748 | content: "\e613"; 749 | } 750 | .icon-social-stumbleupon:before { 751 | content: "\e614"; 752 | } 753 | .icon-social-youtube:before { 754 | content: "\e008"; 755 | } 756 | .icon-social-dropbox:before { 757 | content: "\e00c"; 758 | } 759 | -------------------------------------------------------------------------------- /src/main/resources/static/js/supersized.3.2.7.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Supersized - Fullscreen Slideshow jQuery Plugin 4 | Version : 3.2.7 5 | Site : www.buildinternet.com/project/supersized 6 | 7 | Author : Sam Dunn 8 | Company : One Mighty Roar (www.onemightyroar.com) 9 | License : MIT License / GPL License 10 | 11 | */ 12 | 13 | (function(a){a(document).ready(function(){a("body").append('
    ')});a.supersized=function(b){var c="#supersized",d=this;d.$el=a(c);d.el=c;vars=a.supersized.vars;d.$el.data("supersized",d);api=d.$el.data("supersized");d.init=function(){a.supersized.vars=a.extend(a.supersized.vars,a.supersized.themeVars);a.supersized.vars.options=a.extend({},a.supersized.defaultOptions,a.supersized.themeOptions,b);d.options=a.supersized.vars.options;d._build()};d._build=function(){var g=0,e="",j="",h,f="",i;while(g<=d.options.slides.length-1){switch(d.options.slide_links){case"num":h=g;break;case"name":h=d.options.slides[g].title;break;case"blank":h="";break}e=e+'
  • ';if(g==d.options.start_slide-1){if(d.options.slide_links){j=j+'"}if(d.options.thumb_links){d.options.slides[g].thumb?i=d.options.slides[g].thumb:i=d.options.slides[g].image;f=f+'
  • '}}else{if(d.options.slide_links){j=j+'"}if(d.options.thumb_links){d.options.slides[g].thumb?i=d.options.slides[g].thumb:i=d.options.slides[g].image;f=f+'
  • '}}g++}if(d.options.slide_links){a(vars.slide_list).html(j)}if(d.options.thumb_links&&vars.thumb_tray.length){a(vars.thumb_tray).append('
      '+f+"
    ")}a(d.el).append(e);if(d.options.thumbnail_navigation){vars.current_slide-1<0?prevThumb=d.options.slides.length-1:prevThumb=vars.current_slide-1;a(vars.prev_thumb).show().html(a("").attr("src",d.options.slides[prevThumb].image));vars.current_slide==d.options.slides.length-1?nextThumb=0:nextThumb=vars.current_slide+1;a(vars.next_thumb).show().html(a("").attr("src",d.options.slides[nextThumb].image))}d._start()};d._start=function(){if(d.options.start_slide){vars.current_slide=d.options.start_slide-1}else{vars.current_slide=Math.floor(Math.random()*d.options.slides.length)}var o=d.options.new_window?' target="_blank"':"";if(d.options.performance==3){d.$el.addClass("speed")}else{if((d.options.performance==1)||(d.options.performance==2)){d.$el.addClass("quality")}}if(d.options.random){arr=d.options.slides;for(var h,m,k=arr.length;k;h=parseInt(Math.random()*k),m=arr[--k],arr[k]=arr[h],arr[h]=m){}d.options.slides=arr}if(d.options.slides.length>1){if(d.options.slides.length>2){vars.current_slide-1<0?loadPrev=d.options.slides.length-1:loadPrev=vars.current_slide-1;var g=(d.options.slides[loadPrev].url)?"href='"+d.options.slides[loadPrev].url+"'":"";var q=a('');var n=d.el+" li:eq("+loadPrev+")";q.appendTo(n).wrap("").parent().parent().addClass("image-loading prevslide");q.load(function(){a(this).data("origWidth",a(this).width()).data("origHeight",a(this).height());d.resizeNow()})}}else{d.options.slideshow=0}g=(api.getField("url"))?"href='"+api.getField("url")+"'":"";var l=a('');var f=d.el+" li:eq("+vars.current_slide+")";l.appendTo(f).wrap("").parent().parent().addClass("image-loading activeslide");l.load(function(){d._origDim(a(this));d.resizeNow();d.launch();if(typeof theme!="undefined"&&typeof theme._init=="function"){theme._init()}});if(d.options.slides.length>1){vars.current_slide==d.options.slides.length-1?loadNext=0:loadNext=vars.current_slide+1;g=(d.options.slides[loadNext].url)?"href='"+d.options.slides[loadNext].url+"'":"";var e=a('');var p=d.el+" li:eq("+loadNext+")";e.appendTo(p).wrap("").parent().parent().addClass("image-loading");e.load(function(){a(this).data("origWidth",a(this).width()).data("origHeight",a(this).height());d.resizeNow()})}d.$el.css("visibility","hidden");a(".load-item").hide()};d.launch=function(){d.$el.css("visibility","visible");a("#supersized-loader").remove();if(typeof theme!="undefined"&&typeof theme.beforeAnimation=="function"){theme.beforeAnimation("next")}a(".load-item").show();if(d.options.keyboard_nav){a(document.documentElement).keyup(function(e){if(vars.in_animation){return false}if((e.keyCode==37)||(e.keyCode==40)){clearInterval(vars.slideshow_interval);d.prevSlide()}else{if((e.keyCode==39)||(e.keyCode==38)){clearInterval(vars.slideshow_interval);d.nextSlide()}else{if(e.keyCode==32&&!vars.hover_pause){clearInterval(vars.slideshow_interval);d.playToggle()}}}})}if(d.options.slideshow&&d.options.pause_hover){a(d.el).hover(function(){if(vars.in_animation){return false}vars.hover_pause=true;if(!vars.is_paused){vars.hover_pause="resume";d.playToggle()}},function(){if(vars.hover_pause=="resume"){d.playToggle();vars.hover_pause=false}})}if(d.options.slide_links){a(vars.slide_list+"> li").click(function(){index=a(vars.slide_list+"> li").index(this);targetSlide=index+1;d.goTo(targetSlide);return false})}if(d.options.thumb_links){a(vars.thumb_list+"> li").click(function(){index=a(vars.thumb_list+"> li").index(this);targetSlide=index+1;api.goTo(targetSlide);return false})}if(d.options.slideshow&&d.options.slides.length>1){if(d.options.autoplay&&d.options.slides.length>1){vars.slideshow_interval=setInterval(d.nextSlide,d.options.slide_interval)}else{vars.is_paused=true}a(".load-item img").bind("contextmenu mousedown",function(){return false})}a(window).resize(function(){d.resizeNow()})};d.resizeNow=function(){return d.$el.each(function(){a("img",d.el).each(function(){thisSlide=a(this);var f=(thisSlide.data("origHeight")/thisSlide.data("origWidth")).toFixed(2);var e=d.$el.width(),h=d.$el.height(),i;if(d.options.fit_always){if((h/e)>f){g()}else{j()}}else{if((h<=d.options.min_height)&&(e<=d.options.min_width)){if((h/e)>f){d.options.fit_landscape&&f<1?g(true):j(true)}else{d.options.fit_portrait&&f>=1?j(true):g(true)}}else{if(e<=d.options.min_width){if((h/e)>f){d.options.fit_landscape&&f<1?g(true):j()}else{d.options.fit_portrait&&f>=1?j():g(true)}}else{if(h<=d.options.min_height){if((h/e)>f){d.options.fit_landscape&&f<1?g():j(true)}else{d.options.fit_portrait&&f>=1?j(true):g()}}else{if((h/e)>f){d.options.fit_landscape&&f<1?g():j()}else{d.options.fit_portrait&&f>=1?j():g()}}}}}function g(k){if(k){if(thisSlide.width()=d.options.min_height){thisSlide.width(d.options.min_width);thisSlide.height(thisSlide.width()*f)}else{j()}}}else{if(d.options.min_height>=h&&!d.options.fit_landscape){if(e*f>=d.options.min_height||(e*f>=d.options.min_height&&f<=1)){thisSlide.width(e);thisSlide.height(e*f)}else{if(f>1){thisSlide.height(d.options.min_height);thisSlide.width(thisSlide.height()/f)}else{if(thisSlide.width()=d.options.min_width){thisSlide.height(d.options.min_height);thisSlide.width(thisSlide.height()/f)}else{g(true)}}}else{if(d.options.min_width>=e){if(h/f>=d.options.min_width||f>1){thisSlide.height(h);thisSlide.width(h/f)}else{if(f<=1){thisSlide.width(d.options.min_width);thisSlide.height(thisSlide.width()*f)}}}else{thisSlide.height(h);thisSlide.width(h/f)}}}if(thisSlide.parents("li").hasClass("image-loading")){a(".image-loading").removeClass("image-loading")}if(d.options.horizontal_center){a(this).css("left",(e-a(this).width())/2)}if(d.options.vertical_center){a(this).css("top",(h-a(this).height())/2)}});if(d.options.image_protect){a("img",d.el).bind("contextmenu mousedown",function(){return false})}return false})};d.nextSlide=function(){if(vars.in_animation||!api.options.slideshow){return false}else{vars.in_animation=true}clearInterval(vars.slideshow_interval);var h=d.options.slides,e=d.$el.find(".activeslide");a(".prevslide").removeClass("prevslide");e.removeClass("activeslide").addClass("prevslide");vars.current_slide+1==d.options.slides.length?vars.current_slide=0:vars.current_slide++;var g=a(d.el+" li:eq("+vars.current_slide+")"),i=d.$el.find(".prevslide");if(d.options.performance==1){d.$el.removeClass("quality").addClass("speed")}loadSlide=false;vars.current_slide==d.options.slides.length-1?loadSlide=0:loadSlide=vars.current_slide+1;var k=d.el+" li:eq("+loadSlide+")";if(!a(k).html()){var j=d.options.new_window?' target="_blank"':"";imageLink=(d.options.slides[loadSlide].url)?"href='"+d.options.slides[loadSlide].url+"'":"";var f=a('');f.appendTo(k).wrap("").parent().parent().addClass("image-loading").css("visibility","hidden");f.load(function(){d._origDim(a(this));d.resizeNow()})}if(d.options.thumbnail_navigation==1){vars.current_slide-1<0?prevThumb=d.options.slides.length-1:prevThumb=vars.current_slide-1;a(vars.prev_thumb).html(a("").attr("src",d.options.slides[prevThumb].image));nextThumb=loadSlide;a(vars.next_thumb).html(a("").attr("src",d.options.slides[nextThumb].image))}if(typeof theme!="undefined"&&typeof theme.beforeAnimation=="function"){theme.beforeAnimation("next")}if(d.options.slide_links){a(".current-slide").removeClass("current-slide");a(vars.slide_list+"> li").eq(vars.current_slide).addClass("current-slide")}g.css("visibility","hidden").addClass("activeslide");switch(d.options.transition){case 0:case"none":g.css("visibility","visible");vars.in_animation=false;d.afterAnimation();break;case 1:case"fade":g.animate({opacity:0},0).css("visibility","visible").animate({opacity:1,avoidTransforms:false},d.options.transition_speed,function(){d.afterAnimation()});break;case 2:case"slideTop":g.animate({top:-d.$el.height()},0).css("visibility","visible").animate({top:0,avoidTransforms:false},d.options.transition_speed,function(){d.afterAnimation()});break;case 3:case"slideRight":g.animate({left:d.$el.width()},0).css("visibility","visible").animate({left:0,avoidTransforms:false},d.options.transition_speed,function(){d.afterAnimation()});break;case 4:case"slideBottom":g.animate({top:d.$el.height()},0).css("visibility","visible").animate({top:0,avoidTransforms:false},d.options.transition_speed,function(){d.afterAnimation()});break;case 5:case"slideLeft":g.animate({left:-d.$el.width()},0).css("visibility","visible").animate({left:0,avoidTransforms:false},d.options.transition_speed,function(){d.afterAnimation()});break;case 6:case"carouselRight":g.animate({left:d.$el.width()},0).css("visibility","visible").animate({left:0,avoidTransforms:false},d.options.transition_speed,function(){d.afterAnimation()});e.animate({left:-d.$el.width(),avoidTransforms:false},d.options.transition_speed);break;case 7:case"carouselLeft":g.animate({left:-d.$el.width()},0).css("visibility","visible").animate({left:0,avoidTransforms:false},d.options.transition_speed,function(){d.afterAnimation()});e.animate({left:d.$el.width(),avoidTransforms:false},d.options.transition_speed);break}return false};d.prevSlide=function(){if(vars.in_animation||!api.options.slideshow){return false}else{vars.in_animation=true}clearInterval(vars.slideshow_interval);var h=d.options.slides,e=d.$el.find(".activeslide");a(".prevslide").removeClass("prevslide");e.removeClass("activeslide").addClass("prevslide");vars.current_slide==0?vars.current_slide=d.options.slides.length-1:vars.current_slide--;var g=a(d.el+" li:eq("+vars.current_slide+")"),i=d.$el.find(".prevslide");if(d.options.performance==1){d.$el.removeClass("quality").addClass("speed")}loadSlide=vars.current_slide;var k=d.el+" li:eq("+loadSlide+")";if(!a(k).html()){var j=d.options.new_window?' target="_blank"':"";imageLink=(d.options.slides[loadSlide].url)?"href='"+d.options.slides[loadSlide].url+"'":"";var f=a('');f.appendTo(k).wrap("").parent().parent().addClass("image-loading").css("visibility","hidden");f.load(function(){d._origDim(a(this));d.resizeNow()})}if(d.options.thumbnail_navigation==1){loadSlide==0?prevThumb=d.options.slides.length-1:prevThumb=loadSlide-1;a(vars.prev_thumb).html(a("").attr("src",d.options.slides[prevThumb].image));vars.current_slide==d.options.slides.length-1?nextThumb=0:nextThumb=vars.current_slide+1;a(vars.next_thumb).html(a("").attr("src",d.options.slides[nextThumb].image))}if(typeof theme!="undefined"&&typeof theme.beforeAnimation=="function"){theme.beforeAnimation("prev")}if(d.options.slide_links){a(".current-slide").removeClass("current-slide");a(vars.slide_list+"> li").eq(vars.current_slide).addClass("current-slide")}g.css("visibility","hidden").addClass("activeslide");switch(d.options.transition){case 0:case"none":g.css("visibility","visible");vars.in_animation=false;d.afterAnimation();break;case 1:case"fade":g.animate({opacity:0},0).css("visibility","visible").animate({opacity:1,avoidTransforms:false},d.options.transition_speed,function(){d.afterAnimation()});break;case 2:case"slideTop":g.animate({top:d.$el.height()},0).css("visibility","visible").animate({top:0,avoidTransforms:false},d.options.transition_speed,function(){d.afterAnimation()});break;case 3:case"slideRight":g.animate({left:-d.$el.width()},0).css("visibility","visible").animate({left:0,avoidTransforms:false},d.options.transition_speed,function(){d.afterAnimation()});break;case 4:case"slideBottom":g.animate({top:-d.$el.height()},0).css("visibility","visible").animate({top:0,avoidTransforms:false},d.options.transition_speed,function(){d.afterAnimation()});break;case 5:case"slideLeft":g.animate({left:d.$el.width()},0).css("visibility","visible").animate({left:0,avoidTransforms:false},d.options.transition_speed,function(){d.afterAnimation()});break;case 6:case"carouselRight":g.animate({left:-d.$el.width()},0).css("visibility","visible").animate({left:0,avoidTransforms:false},d.options.transition_speed,function(){d.afterAnimation()});e.animate({left:0},0).animate({left:d.$el.width(),avoidTransforms:false},d.options.transition_speed);break;case 7:case"carouselLeft":g.animate({left:d.$el.width()},0).css("visibility","visible").animate({left:0,avoidTransforms:false},d.options.transition_speed,function(){d.afterAnimation()});e.animate({left:0},0).animate({left:-d.$el.width(),avoidTransforms:false},d.options.transition_speed);break}return false};d.playToggle=function(){if(vars.in_animation||!api.options.slideshow){return false}if(vars.is_paused){vars.is_paused=false;if(typeof theme!="undefined"&&typeof theme.playToggle=="function"){theme.playToggle("play")}vars.slideshow_interval=setInterval(d.nextSlide,d.options.slide_interval)}else{vars.is_paused=true;if(typeof theme!="undefined"&&typeof theme.playToggle=="function"){theme.playToggle("pause")}clearInterval(vars.slideshow_interval)}return false};d.goTo=function(f){if(vars.in_animation||!api.options.slideshow){return false}var e=d.options.slides.length;if(f<0){f=e}else{if(f>e){f=1}}f=e-f+1;clearInterval(vars.slideshow_interval);if(typeof theme!="undefined"&&typeof theme.goTo=="function"){theme.goTo()}if(vars.current_slide==e-f){if(!(vars.is_paused)){vars.slideshow_interval=setInterval(d.nextSlide,d.options.slide_interval)}return false}if(e-f>vars.current_slide){vars.current_slide=e-f-1;vars.update_images="next";d._placeSlide(vars.update_images)}else{if(e-f .current-slide").removeClass("current-slide");a(vars.slide_list+"> li").eq((e-f)).addClass("current-slide")}if(d.options.thumb_links){a(vars.thumb_list+"> .current-thumb").removeClass("current-thumb");a(vars.thumb_list+"> li").eq((e-f)).addClass("current-thumb")}};d._placeSlide=function(e){var h=d.options.new_window?' target="_blank"':"";loadSlide=false;if(e=="next"){vars.current_slide==d.options.slides.length-1?loadSlide=0:loadSlide=vars.current_slide+1;var g=d.el+" li:eq("+loadSlide+")";if(!a(g).html()){var h=d.options.new_window?' target="_blank"':"";imageLink=(d.options.slides[loadSlide].url)?"href='"+d.options.slides[loadSlide].url+"'":"";var f=a('');f.appendTo(g).wrap("").parent().parent().addClass("image-loading").css("visibility","hidden");f.load(function(){d._origDim(a(this));d.resizeNow()})}d.nextSlide()}else{if(e=="prev"){vars.current_slide-1<0?loadSlide=d.options.slides.length-1:loadSlide=vars.current_slide-1;var g=d.el+" li:eq("+loadSlide+")";if(!a(g).html()){var h=d.options.new_window?' target="_blank"':"";imageLink=(d.options.slides[loadSlide].url)?"href='"+d.options.slides[loadSlide].url+"'":"";var f=a('');f.appendTo(g).wrap("").parent().parent().addClass("image-loading").css("visibility","hidden");f.load(function(){d._origDim(a(this));d.resizeNow()})}d.prevSlide()}}};d._origDim=function(e){e.data("origWidth",e.width()).data("origHeight",e.height())};d.afterAnimation=function(){if(d.options.performance==1){d.$el.removeClass("speed").addClass("quality")}if(vars.update_images){vars.current_slide-1<0?setPrev=d.options.slides.length-1:setPrev=vars.current_slide-1;vars.update_images=false;a(".prevslide").removeClass("prevslide");a(d.el+" li:eq("+setPrev+")").addClass("prevslide")}vars.in_animation=false;if(!vars.is_paused&&d.options.slideshow){vars.slideshow_interval=setInterval(d.nextSlide,d.options.slide_interval);if(d.options.stop_loop&&vars.current_slide==d.options.slides.length-1){d.playToggle()}}if(typeof theme!="undefined"&&typeof theme.afterAnimation=="function"){theme.afterAnimation()}return false};d.getField=function(e){return d.options.slides[vars.current_slide][e]};d.init()};a.supersized.vars={thumb_tray:"#thumb-tray",thumb_list:"#thumb-list",slide_list:"#slide-list",current_slide:0,in_animation:false,is_paused:false,hover_pause:false,slideshow_interval:false,update_images:false,options:{}};a.supersized.defaultOptions={slideshow:1,autoplay:1,start_slide:1,stop_loop:0,random:0,slide_interval:5000,transition:1,transition_speed:750,new_window:1,pause_hover:0,keyboard_nav:1,performance:1,image_protect:1,fit_always:0,fit_landscape:0,fit_portrait:1,min_width:0,min_height:0,horizontal_center:1,vertical_center:1,slide_links:1,thumb_links:1,thumbnail_navigation:0};a.fn.supersized=function(b){return this.each(function(){(new a.supersized(b))})}})(jQuery); -------------------------------------------------------------------------------- /src/main/resources/static/css/font-awesome.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 4.4.0 by @davegandy - http://fontawesome.io - @fontawesome 3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) 4 | */@font-face{font-family:'FontAwesome';src:url('../../fonts/fontawesome-webfont.eot?v=4.4.0');src:url('../../fonts/fontawesome-webfont.eot?#iefix&v=4.4.0') format('embedded-opentype'),url('../../fonts/fontawesome-webfont.woff2?v=4.4.0') format('woff2'),url('../../fonts/fontawesome-webfont.woff?v=4.4.0') format('woff'),url('../../fonts/fontawesome-webfont.ttf?v=4.4.0') format('truetype'),url('../../fonts/fontawesome-webfont.svg?v=4.4.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"} 5 | --------------------------------------------------------------------------------