yonge 3 years ago
parent
commit
f22b3454e0
27 changed files with 1514 additions and 17 deletions
  1. 0 12
      cooleshow-auth/auth-api/src/main/java/com/yonge/cooleshow/auth/api/entity/SysUserLoginLog.java
  2. 1 2
      cooleshow-auth/auth-server/src/main/resources/config/mybatis/SysUserLoginLogMapper.xml
  3. 60 0
      cooleshow-task/pom.xml
  4. 36 0
      cooleshow-task/src/main/java/com/yonge/cooleshow/task/TaskApplication.java
  5. 35 0
      cooleshow-task/src/main/java/com/yonge/cooleshow/task/config/ResourceServerConfig.java
  6. 36 0
      cooleshow-task/src/main/java/com/yonge/cooleshow/task/config/WebMvcConfig.java
  7. 106 0
      cooleshow-task/src/main/java/com/yonge/cooleshow/task/controller/TaskController.java
  8. 26 0
      cooleshow-task/src/main/java/com/yonge/cooleshow/task/core/BaseTask.java
  9. 54 0
      cooleshow-task/src/main/java/com/yonge/cooleshow/task/core/DelegatingJob.java
  10. 61 0
      cooleshow-task/src/main/java/com/yonge/cooleshow/task/core/LocalJobFactory.java
  11. 55 0
      cooleshow-task/src/main/java/com/yonge/cooleshow/task/core/LocalSchedulerFactoryBean.java
  12. 160 0
      cooleshow-task/src/main/java/com/yonge/cooleshow/task/core/QuartzHelper.java
  13. 27 0
      cooleshow-task/src/main/java/com/yonge/cooleshow/task/core/TaskException.java
  14. 52 0
      cooleshow-task/src/main/java/com/yonge/cooleshow/task/core/TaskSchedulerBootstrap.java
  15. 33 0
      cooleshow-task/src/main/java/com/yonge/cooleshow/task/core/TaskStatus.java
  16. 57 0
      cooleshow-task/src/main/java/com/yonge/cooleshow/task/dal/dao/TaskDao.java
  17. 105 0
      cooleshow-task/src/main/java/com/yonge/cooleshow/task/dal/model/Task.java
  18. 26 0
      cooleshow-task/src/main/java/com/yonge/cooleshow/task/queryinfo/TaskQueryInfo.java
  19. 84 0
      cooleshow-task/src/main/java/com/yonge/cooleshow/task/service/TaskService.java
  20. 96 0
      cooleshow-task/src/main/java/com/yonge/cooleshow/task/service/impl/TaskServiceImpl.java
  21. 16 0
      cooleshow-task/src/main/resources/bootstrap-dev.properties
  22. 21 0
      cooleshow-task/src/main/resources/config/mybatis/Global.mapper.xml
  23. 101 0
      cooleshow-task/src/main/resources/config/mybatis/TaskMapper.xml
  24. 29 0
      cooleshow-task/src/main/resources/config/properties/quartz.properties
  25. 179 0
      cooleshow-task/src/main/resources/config/properties/tables_mysql_innodb.sql
  26. 55 0
      cooleshow-task/src/main/resources/logback-spring.xml
  27. 3 3
      pom.xml

+ 0 - 12
cooleshow-auth/auth-api/src/main/java/com/yonge/cooleshow/auth/api/entity/SysUserLoginLog.java

@@ -26,10 +26,6 @@ public class SysUserLoginLog {
 	@ApiModelProperty(value = "登录时间",required = false)
 	private java.util.Date loginTime;
 
-	/** 终端类型(0,pc端;1,人工;2,移动端;3,自动) */
-	@ApiModelProperty(value = "终端类型(0,pc端;1,人工;2,移动端;3,自动)",required = false)
-	private Integer source;
-
 	public Long getId() {
 		return id;
 	}
@@ -70,14 +66,6 @@ public class SysUserLoginLog {
 		return this.loginTime;
 	}
 
-	public void setSource(Integer source) {
-		this.source = source;
-	}
-
-	public Integer getSource() {
-		return this.source;
-	}
-
 	@Override
 	public String toString() {
 		return ToStringBuilder.reflectionToString(this);

+ 1 - 2
cooleshow-auth/auth-server/src/main/resources/config/mybatis/SysUserLoginLogMapper.xml

@@ -12,7 +12,6 @@
 		<result column="user_id_" property="userId" />
 		<result column="login_ip_" property="loginIp" />
 		<result column="login_time_" property="loginTime" />
-		<result column="source_" property="source" />
 	</resultMap>
 	
 	
@@ -28,7 +27,7 @@
 		SELECT SEQ_WSDEFINITION_ID.nextval AS ID FROM DUAL 
 		</selectKey>
 		-->
-		INSERT INTO sys_user_login_log (id_,client_id_,user_id_,login_ip_,login_time_,source_) VALUES(#{id},#{clientId},#{userId},#{loginIp},#{loginTime},#{source})
+		INSERT INTO sys_user_login_log (id_,client_id_,user_id_,login_ip_,login_time_) VALUES(#{id},#{clientId},#{userId},#{loginIp},#{loginTime})
 	</insert>
 	
 	

+ 60 - 0
cooleshow-task/pom.xml

@@ -0,0 +1,60 @@
+<?xml version="1.0"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>com.yonge.cooleshow</groupId>
+    <artifactId>cooleshow</artifactId>
+    <version>1.0</version>
+  </parent>
+  <groupId>com.yonge.cooleshow</groupId>
+  <artifactId>cooleshow-task</artifactId>
+  <version>1.0</version>
+  <name>cooleshow-task</name>
+  <url>http://maven.apache.org</url>
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+  </properties>
+  <dependencies>
+
+		<dependency>
+			<groupId>com.alibaba.cloud</groupId>
+			<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>com.alibaba.cloud</groupId>
+			<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
+		</dependency>
+		
+		<dependency>
+			<groupId>org.quartz-scheduler</groupId>
+			<artifactId>quartz</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>org.mybatis.spring.boot</groupId>
+			<artifactId>mybatis-spring-boot-starter</artifactId>
+		</dependency>
+		
+		<dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>druid-spring-boot-starter</artifactId>
+        </dependency>
+        
+		<dependency>
+			<groupId>com.spring4all</groupId>
+			<artifactId>swagger-spring-boot-starter</artifactId>
+		</dependency>
+		
+		<dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+        
+        <dependency>
+        	<groupId>com.yonge.cooleshow</groupId>
+        	<artifactId>auth-api</artifactId>
+        </dependency>
+  </dependencies>
+</project>

+ 36 - 0
cooleshow-task/src/main/java/com/yonge/cooleshow/task/TaskApplication.java

@@ -0,0 +1,36 @@
+package com.yonge.cooleshow.task;
+
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+import org.springframework.cloud.client.loadbalancer.LoadBalanced;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.web.client.RestTemplate;
+
+import com.spring4all.swagger.EnableSwagger2Doc;
+
+@SpringBootApplication
+@EnableDiscoveryClient
+@EnableFeignClients("com.ym.mec")
+@MapperScan("com.ym.mec.task.dal.dao")
+@ComponentScan(basePackages="com.yonge.cooleshow")
+@Configuration
+@EnableSwagger2Doc
+@EnableAsync
+public class TaskApplication {
+
+	public static void main(String[] args) {
+		SpringApplication.run(TaskApplication.class, args);
+	}
+	
+	@Bean
+	@LoadBalanced
+	public RestTemplate restTemplate(){
+		return new RestTemplate();
+	}
+}

+ 35 - 0
cooleshow-task/src/main/java/com/yonge/cooleshow/task/config/ResourceServerConfig.java

@@ -0,0 +1,35 @@
+package com.yonge.cooleshow.task.config;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
+import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
+import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
+
+import com.yonge.cooleshow.common.security.BaseAccessDeniedHandler;
+import com.yonge.cooleshow.common.security.BaseAuthenticationEntryPoint;
+
+@Configuration
+@EnableResourceServer
+@EnableGlobalMethodSecurity(prePostEnabled = true)
+public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
+
+	@Autowired
+	private BaseAccessDeniedHandler baseAccessDeniedHandler;
+
+	@Autowired
+	private BaseAuthenticationEntryPoint baseAuthenticationEntryPoint;
+
+	@Override
+	public void configure(HttpSecurity http) throws Exception {
+		http.authorizeRequests().antMatchers("/v2/api-docs").permitAll().anyRequest().authenticated().and().csrf().disable().exceptionHandling()
+				.accessDeniedHandler(baseAccessDeniedHandler).authenticationEntryPoint(baseAuthenticationEntryPoint).and();
+	}
+
+	@Override
+	public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
+		resources.authenticationEntryPoint(baseAuthenticationEntryPoint).accessDeniedHandler(baseAccessDeniedHandler);
+	}
+}

+ 36 - 0
cooleshow-task/src/main/java/com/yonge/cooleshow/task/config/WebMvcConfig.java

@@ -0,0 +1,36 @@
+package com.yonge.cooleshow.task.config;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.format.FormatterRegistry;
+import org.springframework.http.MediaType;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+import com.yonge.cooleshow.common.config.EnumConverterFactory;
+import com.yonge.cooleshow.common.config.LocalFastJsonHttpMessageConverter;
+
+@Configuration
+public class WebMvcConfig implements WebMvcConfigurer {
+
+	/**
+	 * 枚举类的转换器 addConverterFactory
+	 */
+	@Override
+	public void addFormatters(FormatterRegistry registry) {
+		registry.addConverterFactory(new EnumConverterFactory());
+	}
+	
+	@Bean
+    public HttpMessageConverters fastJsonHttpMessageConverters(){
+		LocalFastJsonHttpMessageConverter converter = new LocalFastJsonHttpMessageConverter();
+        List<MediaType> fastMediaTypes =  new ArrayList<MediaType>();
+        fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
+        converter.setSupportedMediaTypes(fastMediaTypes);
+        return new HttpMessageConverters(converter);
+    }
+
+}

+ 106 - 0
cooleshow-task/src/main/java/com/yonge/cooleshow/task/controller/TaskController.java

@@ -0,0 +1,106 @@
+package com.yonge.cooleshow.task.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiOperation;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.quartz.Scheduler;
+import org.quartz.SchedulerException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.page.PageInfo;
+import com.yonge.cooleshow.task.dal.model.Task;
+import com.yonge.cooleshow.task.queryinfo.TaskQueryInfo;
+import com.yonge.cooleshow.task.service.TaskService;
+import com.yonge.toolset.utils.collection.MapUtil;
+
+@RestController
+@RequestMapping(value = "task")
+@Api(tags = "任务调度")
+public class TaskController extends BaseController {
+
+	private final static Logger LOGGER = LoggerFactory.getLogger(TaskController.class);
+
+	@Autowired
+	private TaskService taskService;
+
+	@Autowired
+	private Scheduler scheduler;
+
+	@ApiOperation("任务列表分页查询")
+	@GetMapping("/list")
+	public HttpResponseResult<PageInfo<Task>> list(TaskQueryInfo queryInfo) {
+		PageInfo<Task> pageInfo = new PageInfo<Task>(queryInfo.getPage(), queryInfo.getRows());
+		Map<String, Object> params = new HashMap<String, Object>();
+		MapUtil.populateMap(params, queryInfo);
+
+		List<Task> dataList = null;
+		int count = taskService.queryCount(params);
+		if (count > 0) {
+			pageInfo.setTotal(count);
+			params.put("offset", pageInfo.getOffset());
+			dataList = taskService.queryPage(params);
+		}
+		if (count == 0) {
+			dataList = new ArrayList<Task>();
+		}
+		pageInfo.setRows(dataList);
+		return succeed(pageInfo);
+	}
+
+	@ApiOperation("执行当前任务")
+	@ApiImplicitParam(name = "taskId", value = "任务编号", required = true, dataType = "Integer", paramType = "path")
+	@PostMapping("/execute/{taskId}")
+	public HttpResponseResult<Object> execute(@PathVariable("taskId") int taskId) {
+		boolean result = false;
+		try {
+			result = taskService.execute(taskId, scheduler);
+		} catch (SchedulerException e) {
+			LOGGER.error("手工执行任务[{}]失败", taskId, e);
+			return failed(e.getMessage());
+		}
+		return result ? succeed() : failed();
+	}
+
+	@ApiOperation("暂停当前任务")
+	@ApiImplicitParam(name = "taskId", value = "任务编号", required = true, dataType = "Integer", paramType = "path")
+	@PostMapping("/pause/{taskId}")
+	public HttpResponseResult<Object> pause(@PathVariable("taskId") int taskId) {
+		boolean result = false;
+		try {
+			result = taskService.pause(taskId, scheduler);
+		} catch (SchedulerException e) {
+			LOGGER.error("手工暂停任务[{}]失败", taskId, e);
+			return failed(e.getMessage());
+		}
+		return result ? succeed() : failed();
+	}
+
+	@ApiOperation("暂停当前任务")
+	@ApiImplicitParam(name = "taskId", value = "任务编号", required = true, dataType = "Integer", paramType = "path")
+	@PostMapping("/resume/{taskId}")
+	public HttpResponseResult<Object> resume(@PathVariable("taskId") int taskId) {
+		boolean result = false;
+		try {
+			result = taskService.resume(taskId, scheduler);
+		} catch (SchedulerException e) {
+			LOGGER.error("手工恢复任务[{}]失败", taskId, e);
+			return failed(e.getMessage());
+		}
+		return result ? succeed() : failed();
+	}
+}

+ 26 - 0
cooleshow-task/src/main/java/com/yonge/cooleshow/task/core/BaseTask.java

@@ -0,0 +1,26 @@
+package com.yonge.cooleshow.task.core;
+
+import org.quartz.Job;
+import org.quartz.JobExecutionContext;
+import org.quartz.JobExecutionException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * 所有任务必须继承该抽象方法
+ */
+public abstract class BaseTask implements Job {
+
+	private Logger LOGGER = LoggerFactory.getLogger(BaseTask.class);
+
+	@Override
+	public void execute(JobExecutionContext context) throws JobExecutionException {
+		try {
+			execute();
+		} catch (TaskException e) {
+			LOGGER.error(e.getMessage(), e);
+		}
+	}
+
+	public abstract void execute() throws TaskException;
+}

+ 54 - 0
cooleshow-task/src/main/java/com/yonge/cooleshow/task/core/DelegatingJob.java

@@ -0,0 +1,54 @@
+package com.yonge.cooleshow.task.core;
+
+import org.quartz.Job;
+import org.quartz.JobExecutionContext;
+import org.quartz.JobExecutionException;
+import org.quartz.JobKey;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.yonge.cooleshow.task.core.TaskStatus;
+import com.yonge.cooleshow.task.dal.model.Task;
+import com.yonge.cooleshow.task.service.TaskService;
+
+public class DelegatingJob implements Job {
+
+	private final static Logger LOGGER = LoggerFactory.getLogger(DelegatingJob.class);
+
+	private Job job;
+
+	TaskService taskService;
+
+	public DelegatingJob(Job job, TaskService taskService) {
+		this.job = job;
+		this.taskService = taskService;
+	}
+
+	@Override
+	public void execute(JobExecutionContext context) throws JobExecutionException {
+		JobKey jobKey = context.getJobDetail().getKey();
+		String group = jobKey.getGroup();
+		String name = jobKey.getName();
+
+		Task task = taskService.queryTask(name, group);
+		if (task == null) {
+			return;
+		}
+		if (task.getStatus() == TaskStatus.EXECUTING.getCode()) {
+			LOGGER.warn("Failed to execute,because the Job[{}.{}] status is {}", group, name, TaskStatus.EXECUTING);
+			return;
+		} else if (task.getStatus() == TaskStatus.PAUSED.getCode()) {
+			LOGGER.warn("Failed to execute,because the Job[{}.{}] status is {}", group, name, TaskStatus.PAUSED);
+			return;
+		}
+		taskService.updateTaskStatus(task.getId(), TaskStatus.getTaskStatus(task.getStatus()), TaskStatus.EXECUTING);
+		try {
+			job.execute(context);
+		} catch (Exception e) {
+			throw new RuntimeException("执行任务出错", e);
+		} finally {
+			taskService.updateTaskStatus(task.getId(), TaskStatus.EXECUTING, TaskStatus.EXECUTED);
+		}
+	}
+
+}

+ 61 - 0
cooleshow-task/src/main/java/com/yonge/cooleshow/task/core/LocalJobFactory.java

@@ -0,0 +1,61 @@
+package com.yonge.cooleshow.task.core;
+
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.quartz.Job;
+import org.quartz.JobDetail;
+import org.quartz.Scheduler;
+import org.quartz.SchedulerException;
+import org.quartz.spi.JobFactory;
+import org.quartz.spi.TriggerFiredBundle;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+
+import com.yonge.cooleshow.task.core.TaskException;
+import com.yonge.cooleshow.task.service.TaskService;
+
+@Component
+public class LocalJobFactory implements JobFactory, ApplicationContextAware {
+
+	private ApplicationContext applicationContext;
+
+	@Autowired
+	private TaskService taskService;
+
+	@Override
+	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+		this.applicationContext = applicationContext;
+	}
+
+	@Override
+	public Job newJob(TriggerFiredBundle bundle, Scheduler scheduler) throws SchedulerException {
+		Job job = null;
+		JobDetail jobDetail = bundle.getJobDetail();
+		Class<? extends Job> jobClass = jobDetail.getJobClass();
+		Map<String, ? extends Job> jobMap = applicationContext.getBeansOfType(jobClass);
+		if (jobMap == null || jobMap.size() == 0) {
+			try {
+				job = jobClass.newInstance();
+			} catch (Exception e) {
+				throw new TaskException("Problem instantiating class '" + jobClass.getName() + "'", e);
+			}
+		} else if (jobMap.size() > 1) {
+			throw new TaskException("Get multiple instance from spring application context by type[{" + jobClass.getName() + "}]");
+		} else {
+			for (Entry<String, ? extends Job> entry : jobMap.entrySet()) {
+				job = entry.getValue();
+				break;
+			}
+		}
+		return new DelegatingJob(job, taskService);
+	}
+
+	public void setTaskService(TaskService taskService) {
+		this.taskService = taskService;
+	}
+
+}

+ 55 - 0
cooleshow-task/src/main/java/com/yonge/cooleshow/task/core/LocalSchedulerFactoryBean.java

@@ -0,0 +1,55 @@
+package com.yonge.cooleshow.task.core;
+
+import javax.sql.DataSource;
+
+import org.quartz.Trigger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.io.Resource;
+import org.springframework.scheduling.quartz.SchedulerFactoryBean;
+import org.springframework.stereotype.Component;
+
+@Component
+public class LocalSchedulerFactoryBean extends SchedulerFactoryBean {
+
+	@Autowired
+	private DataSource dataSource;
+
+	@Autowired
+	private LocalJobFactory jobFactory;
+
+	@Value("${task.configLocation}")
+	private Resource configLocation;
+
+	@Value("${task.autoStartup}")
+	private boolean autoStartup;
+
+	@Value("${task.startupDelay}")
+	private int startupDelay;
+
+	private boolean waitForJobsToCompleteOnShutdown = true;
+
+	@Override
+	public void afterPropertiesSet() throws Exception {
+		setDataSource(dataSource);
+		setJobFactory(jobFactory);
+		setOverwriteExistingJobs(true);
+		setConfigLocation(configLocation);
+		setWaitForJobsToCompleteOnShutdown(waitForJobsToCompleteOnShutdown);
+		setStartupDelay(startupDelay);
+		setAutoStartup(autoStartup);
+		
+		super.afterPropertiesSet();
+	}
+
+	@Override
+	public void setBeanName(String name) {
+		// 重写该方法的目的是为了scheduler的实例名称遵循quartz配置文件的配置,除非在spring的配置文件中指定了实例名称
+	}
+
+	@Override
+	public void setTriggers(Trigger... triggers) {
+		throw new UnsupportedOperationException("Not allowed to add the triggers instantiation");
+	}
+
+}

+ 160 - 0
cooleshow-task/src/main/java/com/yonge/cooleshow/task/core/QuartzHelper.java

@@ -0,0 +1,160 @@
+package com.yonge.cooleshow.task.core;
+
+import java.util.Date;
+
+import org.apache.commons.lang3.StringUtils;
+import org.quartz.CronScheduleBuilder;
+import org.quartz.JobBuilder;
+import org.quartz.JobDetail;
+import org.quartz.JobKey;
+import org.quartz.Scheduler;
+import org.quartz.SchedulerException;
+import org.quartz.Trigger;
+import org.quartz.TriggerBuilder;
+import org.quartz.TriggerKey;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.yonge.cooleshow.task.core.BaseTask;
+
+public class QuartzHelper {
+
+	private final static Logger LOGGER = LoggerFactory.getLogger(QuartzHelper.class);
+
+	/**
+	 * 添加一个定时任务,使用默认的任务组名,触发器名,触发器组名
+	 * @param scheduler 调度对象
+	 * @param jobName 任务名称
+	 * @param jobGroupName 任务组
+	 * @param triggerName 触发器名称
+	 * @param triggerGroupName 触发器组
+	 * @param jobClass 具体任务
+	 * @param cronExp 任务执行的时间表达式
+	 * @return
+	 * @throws SchedulerException
+	 */
+	public static boolean addJob(Scheduler scheduler, String jobName, String jobGroupName, String triggerName, String triggerGroupName,
+			Class<? extends BaseTask> jobClass, String cronExp) throws SchedulerException {
+		if (scheduler == null) {
+			throw new RuntimeException("Scheduler-instance must be not null");
+		}
+		if (StringUtils.isBlank(jobName)) {
+			throw new RuntimeException("jobName must be not blank");
+		}
+		if (StringUtils.isBlank(triggerName)) {
+			throw new RuntimeException("triggerName must be not blank");
+		}
+		if (StringUtils.isBlank(jobGroupName)) {
+			jobGroupName = Scheduler.DEFAULT_GROUP;
+		}
+		if (StringUtils.isBlank(triggerGroupName)) {
+			triggerGroupName = Scheduler.DEFAULT_GROUP;
+		}
+		JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
+		if (scheduler.checkExists(jobKey)) {
+			scheduler.deleteJob(jobKey);
+		}
+		JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName).build();
+
+		// 表达式调度构建器
+		CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExp);
+		Trigger trigger = TriggerBuilder.newTrigger().withIdentity(triggerName, triggerGroupName).withSchedule(scheduleBuilder).build();
+
+		scheduler.scheduleJob(jobDetail, trigger);
+		return true;
+	}
+
+	/**
+	 * 修改一个任务的触发时间
+	 * 
+	 * @param scheduler 调度对象
+	 * @param triggerName 触发器名称
+	 * @param triggerGroupName 触发器组
+	 * @param time 任务执行新的时间表达式
+	 * @return
+	 * @throws SchedulerException 
+	 */
+	public static boolean modifyJobTime(Scheduler scheduler, String triggerName, String triggerGroupName, String time) throws SchedulerException {
+
+		TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);
+		Trigger trigger = scheduler.getTrigger(triggerKey);
+		if (trigger == null) {
+			return false;
+		}
+		CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(time);
+		trigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
+
+		Date date = scheduler.rescheduleJob(triggerKey, trigger);
+		LOGGER.info("Successed to modify trigger time(JobTrigger[{},{}]), and next fired time {}", triggerGroupName, triggerName, date);
+		return true;
+	}
+
+	/**
+	 * 移除一个任务
+	 * 
+	 * @param scheduler 调度对象
+	 * @param jobName 任务名称
+	 * @param jobGroupName 任务组
+	 * @return
+	 * @throws SchedulerException 
+	 */
+	public static boolean deleteJob(Scheduler scheduler, String jobName, String jobGroupName) throws SchedulerException {
+		JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
+		if (jobKey == null) {
+			return false;
+		}
+		return scheduler.deleteJob(jobKey);
+	}
+
+	/**
+	 * 暂停任务
+	 * @param scheduler 调度对象
+	 * @param jobName 任务名称
+	 * @param jobGroupName 任务组
+	 * @return
+	 * @throws SchedulerException
+	 */
+	public static boolean pauseJob(Scheduler scheduler, String jobName, String jobGroupName) throws SchedulerException {
+		JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
+		if (jobKey == null) {
+			return false;
+		}
+		scheduler.pauseJob(jobKey);
+		return true;
+	}
+
+	/**
+	 * 恢复任务
+	 * @param scheduler 调度对象
+	 * @param jobName 任务名称
+	 * @param jobGroupName 任务组
+	 * @return
+	 * @throws SchedulerException
+	 */
+	public static boolean resumeJob(Scheduler scheduler, String jobName, String jobGroupName) throws SchedulerException {
+		JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
+		if (jobKey == null) {
+			return false;
+		}
+		scheduler.resumeJob(jobKey);
+		return true;
+	}
+
+	/**
+	 * 立即执行任务
+	 * @param scheduler 调度对象
+	 * @param jobName 任务名称
+	 * @param jobGroupName 任务组
+	 * @return
+	 * @throws SchedulerException
+	 */
+	public static boolean triggerJob(Scheduler scheduler, String jobName, String jobGroupName) throws SchedulerException {
+		JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
+		if (jobKey == null) {
+			return false;
+		}
+		scheduler.triggerJob(jobKey);
+		return true;
+	}
+
+}

+ 27 - 0
cooleshow-task/src/main/java/com/yonge/cooleshow/task/core/TaskException.java

@@ -0,0 +1,27 @@
+package com.yonge.cooleshow.task.core;
+
+import org.quartz.SchedulerException;
+
+public class TaskException extends SchedulerException {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = -3520169301443502678L;
+
+	public TaskException() {
+		super();
+	}
+
+	public TaskException(String msg) {
+		super(msg);
+	}
+
+	public TaskException(Throwable cause) {
+		super(cause);
+	}
+
+	public TaskException(String msg, Throwable cause) {
+		super(msg, cause);
+	}
+}

+ 52 - 0
cooleshow-task/src/main/java/com/yonge/cooleshow/task/core/TaskSchedulerBootstrap.java

@@ -0,0 +1,52 @@
+package com.yonge.cooleshow.task.core;
+
+import java.util.List;
+
+import org.quartz.Scheduler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+
+import com.yonge.cooleshow.task.dal.model.Task;
+import com.yonge.cooleshow.task.service.TaskService;
+
+@Configuration
+public class TaskSchedulerBootstrap implements InitializingBean {
+
+	private static final Logger LOGGER = LoggerFactory.getLogger(TaskSchedulerBootstrap.class);
+
+	@Autowired
+	private TaskService taskService;
+
+	@Autowired
+	private LocalSchedulerFactoryBean localSchedulerFactoryBean;
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public void afterPropertiesSet() throws Exception {
+
+		Scheduler scheduler = localSchedulerFactoryBean.getScheduler();
+		if (scheduler == null) {
+			throw new IllegalArgumentException("[TaskSchedulerBootstrap]在实例化过程中,参数[scheduler]没有被设置,请检查配置");
+		}
+		if (taskService == null) {
+			throw new IllegalArgumentException("[TaskSchedulerBootstrap]在实例化过程中,参数[taskService]没有被设置,请检查配置");
+		}
+		List<Task> tasks = taskService.queryTasks();
+		Class<?> clazz = null;
+		for (Task task : tasks) {
+			clazz = Class.forName(task.getJobClass());
+			if (BaseTask.class.isAssignableFrom(clazz)) {
+				QuartzHelper.addJob(scheduler, task.getName(), task.getGroup(), task.getName(), task.getGroup(),
+						(Class<? extends BaseTask>) Class.forName(task.getJobClass()), task.getTimeExp());
+				LOGGER.info("Successed add job[{}.{}] to Schedule", task.getGroup(), task.getName());
+			} else {
+				LOGGER.warn("Failed add job[{}.{}],because class[{}] not implements com.yqh.p2p.task.BaseTask", task.getGroup(), task.getName(),
+						task.getJobClass());
+			}
+		}
+	}
+
+}

+ 33 - 0
cooleshow-task/src/main/java/com/yonge/cooleshow/task/core/TaskStatus.java

@@ -0,0 +1,33 @@
+package com.yonge.cooleshow.task.core;
+
+public enum TaskStatus {
+
+	FAILED(-1, "执行失败"), PAUSED(0, "暂停"), READY(1, "准备就绪"), EXECUTING(2, "执行中"), EXECUTED(3, "执行完成");
+
+	private int code;
+
+	private String description;
+
+	private TaskStatus(int code, String description) {
+		this.code = code;
+		this.description = description;
+	}
+
+	public static TaskStatus getTaskStatus(int code) {
+		for (TaskStatus status : values()) {
+			if (status.getCode() == code) {
+				return status;
+			}
+		}
+		return null;
+	}
+
+	public int getCode() {
+		return code;
+	}
+
+	public String getDescription() {
+		return description;
+	}
+
+}

+ 57 - 0
cooleshow-task/src/main/java/com/yonge/cooleshow/task/dal/dao/TaskDao.java

@@ -0,0 +1,57 @@
+package com.yonge.cooleshow.task.dal.dao;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.ibatis.annotations.Param;
+
+import com.yonge.cooleshow.task.dal.model.Task;
+
+public interface TaskDao {
+
+	public Task get(int taskId);
+
+	/**
+	 * 查询可用的任务列表(除暂停、执行中的任务外)
+	 * @return
+	 */
+	public List<Task> queryAvailableTasks();
+
+	/**
+	 * 根据任务名称和任务组查询任务对象
+	 * @param name
+	 * @param group
+	 * @return
+	 */
+	public Task queryTaskByNameAndGroup(@Param("name") String name, @Param("group") String group);
+
+	/**
+	 * 更新状态
+	 * @param id
+	 * @param oldStatus
+	 * @param curStatus
+	 * @return
+	 */
+	public int updateStatusById(@Param("id") int id, @Param("oldStatus") int oldStatus, @Param("curStatus") int curStatus);
+
+	/**
+	 * 查询记录数
+	 * @param params
+	 * @return
+	 */
+	public int queryCount(Map<String, Object> params);
+
+	/**
+	 * 查询对象列表
+	 * @param params
+	 * @return
+	 */
+	public List<Task> queryPage(Map<String, Object> params);
+
+	/**
+	 * 锁定任务对象
+	 * @param id
+	 * @return
+	 */
+	public Task getLocked(int id);
+}

+ 105 - 0
cooleshow-task/src/main/java/com/yonge/cooleshow/task/dal/model/Task.java

@@ -0,0 +1,105 @@
+package com.yonge.cooleshow.task.dal.model;
+
+import java.util.Date;
+
+public class Task {
+
+	/** 任务id,主键 */
+	private Integer id;
+
+	/** 任务名称 */
+	private String name;
+
+	/** 任务所属分组*/
+	private String group;
+
+	/** 具体任务接口 */
+	private String jobClass;
+
+	/** 任务执行的时间表达式 */
+	private String timeExp;
+
+	/** 状态(-1,执行失败;0,暂停;1,准备就绪;2,执行中;3,执行成功) */
+	private Integer status;
+
+	/** 任务描述 */
+	private String description;
+
+	/** 创建时间 */
+	private Date createOn;
+
+	/** 修改时间 */
+	private Date modifyOn;
+
+	public Integer getId() {
+		return id;
+	}
+
+	public void setId(Integer id) {
+		this.id = id;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name == null ? null : name.trim();
+	}
+
+	public String getGroup() {
+		return group;
+	}
+
+	public void setGroup(String group) {
+		this.group = group == null ? null : group.trim();
+	}
+
+	public String getJobClass() {
+		return jobClass;
+	}
+
+	public void setJobClass(String jobClass) {
+		this.jobClass = jobClass == null ? null : jobClass.trim();
+	}
+
+	public String getTimeExp() {
+		return timeExp;
+	}
+
+	public void setTimeExp(String timeExp) {
+		this.timeExp = timeExp == null ? null : timeExp.trim();
+	}
+
+	public Integer getStatus() {
+		return status;
+	}
+
+	public void setStatus(Integer status) {
+		this.status = status;
+	}
+
+	public String getDescription() {
+		return description;
+	}
+
+	public void setDescription(String description) {
+		this.description = description == null ? null : description.trim();
+	}
+
+	public Date getCreateOn() {
+		return createOn;
+	}
+
+	public void setCreateOn(Date createOn) {
+		this.createOn = createOn;
+	}
+
+	public Date getModifyOn() {
+		return modifyOn;
+	}
+
+	public void setModifyOn(Date modifyOn) {
+		this.modifyOn = modifyOn;
+	}
+}

+ 26 - 0
cooleshow-task/src/main/java/com/yonge/cooleshow/task/queryinfo/TaskQueryInfo.java

@@ -0,0 +1,26 @@
+package com.yonge.cooleshow.task.queryinfo;
+
+import com.yonge.cooleshow.common.page.QueryInfo;
+
+public class TaskQueryInfo extends QueryInfo {
+
+	private String search;
+
+	private Integer status;
+
+	public String getSearch() {
+		return search;
+	}
+
+	public void setSearch(String search) {
+		this.search = search;
+	}
+
+	public Integer getStatus() {
+		return status;
+	}
+
+	public void setStatus(Integer status) {
+		this.status = status;
+	}
+}

+ 84 - 0
cooleshow-task/src/main/java/com/yonge/cooleshow/task/service/TaskService.java

@@ -0,0 +1,84 @@
+package com.yonge.cooleshow.task.service;
+
+import java.util.List;
+import java.util.Map;
+
+import org.quartz.Scheduler;
+import org.quartz.SchedulerException;
+
+import com.yonge.cooleshow.task.core.TaskStatus;
+import com.yonge.cooleshow.task.dal.model.Task;
+
+public interface TaskService {
+
+	/**
+	 * 查询所有任务列表
+	 * @return
+	 */
+	public List<Task> queryTasks();
+
+	/**
+	 * 分页查询
+	 * @param params
+	 * @return
+	 */
+	public List<Task> queryPage(Map<String, Object> params);
+
+	/**
+	 * 查询记录数
+	 * @param params
+	 * @return
+	 */
+	public int queryCount(Map<String, Object> params);
+
+	/**
+	 * 根据任务ID查询任务对象
+	 * @param taskId
+	 * @return
+	 */
+	public Task queryTask(int taskId);
+
+	/**
+	 * 根据任务名称和任务组获取任务对象
+	 * @param jobName
+	 * @param groupName
+	 * @return
+	 */
+	public Task queryTask(String jobName, String groupName);
+
+	/**
+	 * 更新指定任务id的状态
+	 * @param taskId
+	 * @param oldStatus
+	 * @param curStatus
+	 * @return
+	 */
+	public boolean updateTaskStatus(int taskId, TaskStatus oldStatus, TaskStatus curStatus);
+
+	/**
+	 * 执行指定任务编号的任务
+	 * @param taskId
+	 * @param scheduler
+	 * @return
+	 * @throws SchedulerException
+	 */
+	public boolean execute(int taskId, Scheduler scheduler) throws SchedulerException;
+
+	/**
+	 * 暂停任务
+	 * @param taskId
+	 * @param scheduler
+	 * @return
+	 * @throws SchedulerException
+	 */
+	public boolean pause(int taskId, Scheduler scheduler) throws SchedulerException;
+
+	/**
+	 * 恢复任务
+	 * @param taskId
+	 * @param scheduler
+	 * @return
+	 * @throws SchedulerException
+	 */
+	public boolean resume(int taskId, Scheduler scheduler) throws SchedulerException;
+}

+ 96 - 0
cooleshow-task/src/main/java/com/yonge/cooleshow/task/service/impl/TaskServiceImpl.java

@@ -0,0 +1,96 @@
+package com.yonge.cooleshow.task.service.impl;
+
+import java.util.List;
+import java.util.Map;
+
+import org.quartz.Scheduler;
+import org.quartz.SchedulerException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.yonge.cooleshow.task.core.QuartzHelper;
+import com.yonge.cooleshow.task.core.TaskException;
+import com.yonge.cooleshow.task.core.TaskStatus;
+import com.yonge.cooleshow.task.dal.dao.TaskDao;
+import com.yonge.cooleshow.task.dal.model.Task;
+import com.yonge.cooleshow.task.service.TaskService;
+
+@Service
+public class TaskServiceImpl implements TaskService {
+
+	@Autowired
+	private TaskDao taskDao;
+
+	@Override
+	public List<Task> queryTasks() {
+		return taskDao.queryAvailableTasks();
+	}
+
+	@Override
+	public List<Task> queryPage(Map<String, Object> params) {
+		return taskDao.queryPage(params);
+	}
+
+	@Override
+	public int queryCount(Map<String, Object> params) {
+		return taskDao.queryCount(params);
+	}
+
+	@Override
+	public Task queryTask(int taskId) {
+		return taskDao.get(taskId);
+	}
+
+	@Override
+	public Task queryTask(String jobName, String groupName) {
+		return taskDao.queryTaskByNameAndGroup(jobName, groupName);
+	}
+
+	@Override
+	public boolean updateTaskStatus(int taskId, TaskStatus oldStatus, TaskStatus curStatus) {
+		return taskDao.updateStatusById(taskId, oldStatus.getCode(), curStatus.getCode()) > 0;
+	}
+
+	@Override
+	public boolean execute(int taskId, Scheduler scheduler) throws SchedulerException {
+		Task task = taskDao.getLocked(taskId);
+		if (task == null) {
+			throw new TaskException("任务编号[{" + taskId + "}]不存在");
+		}
+		if (task.getStatus() == TaskStatus.EXECUTING.getCode() || task.getStatus() == TaskStatus.PAUSED.getCode()) {
+			throw new TaskException("“执行中”或“暂停”状态的任务不能被执行");
+		}
+		return QuartzHelper.triggerJob(scheduler, task.getName(), task.getGroup());
+	}
+
+	@Override
+	public boolean pause(int taskId, Scheduler scheduler) throws SchedulerException {
+		Task task = taskDao.getLocked(taskId);
+		if (task == null) {
+			throw new TaskException("任务编号[{" + taskId + "}]不存在");
+		}
+		if (task.getStatus() == TaskStatus.EXECUTING.getCode() || task.getStatus() == TaskStatus.PAUSED.getCode()) {
+			throw new TaskException("“执行中”或“暂停”状态的任务不能被暂停执行");
+		}
+		if (QuartzHelper.pauseJob(scheduler, task.getName(), task.getGroup())) {
+			return taskDao.updateStatusById(taskId, task.getStatus(), TaskStatus.PAUSED.getCode()) > 0;
+		}
+		return false;
+	}
+
+	@Override
+	public boolean resume(int taskId, Scheduler scheduler) throws SchedulerException {
+		Task task = taskDao.getLocked(taskId);
+		if (task == null) {
+			throw new TaskException("任务编号[{" + taskId + "}]不存在");
+		}
+		if (task.getStatus() != TaskStatus.PAUSED.getCode()) {
+			throw new TaskException("只有“暂停”状态的任务才能被恢复执行");
+		}
+		if (QuartzHelper.resumeJob(scheduler, task.getName(), task.getGroup())) {
+			return taskDao.updateStatusById(taskId, task.getStatus(), TaskStatus.READY.getCode()) > 0;
+		}
+		return false;
+	}
+
+}

+ 16 - 0
cooleshow-task/src/main/resources/bootstrap-dev.properties

@@ -0,0 +1,16 @@
+#\u6307\u5b9a\u5f00\u53d1\u73af\u5883
+#spring.profiles.active=dev
+#\u670d\u52a1\u5668\u5730\u5740
+spring.cloud.nacos.config.server-addr=47.114.1.200:8848
+#\u9ed8\u8ba4\u4e3aPublic\u547d\u540d\u7a7a\u95f4,\u53ef\u4ee5\u7701\u7565\u4e0d\u5199
+spring.cloud.nacos.config.namespace=6f8374a9-598f-4889-bb17-476070ffb8de
+#\u6307\u5b9a\u914d\u7f6e\u7fa4\u7ec4 --\u5982\u679c\u662fPublic\u547d\u540d\u7a7a\u95f4 \u5219\u53ef\u4ee5\u7701\u7565\u7fa4\u7ec4\u914d\u7f6e
+spring.cloud.nacos.config.group=DEFAULT_GROUP
+#\u6587\u4ef6\u540d -- \u5982\u679c\u6ca1\u6709\u914d\u7f6e\u5219\u9ed8\u8ba4\u4e3a ${spring.appliction.name}
+spring.cloud.nacos.config.prefix=task
+#\u6307\u5b9a\u6587\u4ef6\u540e\u7f00
+spring.cloud.nacos.config.file-extension=yaml
+#\u662f\u5426\u52a8\u6001\u5237\u65b0
+spring.cloud.nacos.config.refresh.enabled=true
+#\u662f\u5426\u542f\u7528nacos\u914d\u7f6e\u4e2d\u5fc3
+spring.cloud.nacos.config.enabled=true

+ 21 - 0
cooleshow-task/src/main/resources/config/mybatis/Global.mapper.xml

@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="global">
+
+	<sql id="limit">
+		<if test="offset != null">
+			 limit #{offset},#{rows}
+		</if>
+	</sql>
+
+	<sql id="orderby">
+		<if test="sort != null and sort != ''">
+			 ORDER BY ${sort}
+			 <if test="order != null and order != ''">
+			 	${order}
+			 </if>
+		</if>
+	</sql>	
+ </mapper>

+ 101 - 0
cooleshow-task/src/main/resources/config/mybatis/TaskMapper.xml

@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="com.yonge.cooleshow.task.dal.dao.TaskDao" >
+  <resultMap id="TaskResultMap" type="com.yonge.cooleshow.task.dal.model.Task" >
+    <id column="id_" property="id" jdbcType="INTEGER" />
+    <result column="name_" property="name" jdbcType="VARCHAR" />
+    <result column="group_" property="group" jdbcType="VARCHAR" />
+    <result column="job_class_" property="jobClass" jdbcType="VARCHAR" />
+    <result column="time_exp_" property="timeExp" jdbcType="VARCHAR" />
+    <result column="status_" property="status" jdbcType="TINYINT" />
+    <result column="description_" property="description" jdbcType="VARCHAR" />
+    <result column="create_on_" property="createOn" jdbcType="TIMESTAMP" />
+    <result column="modify_on_" property="modifyOn" jdbcType="TIMESTAMP" />
+  </resultMap>
+  
+  <sql id="Base_Column_List" >
+    id_, name_, group_, job_class_, time_exp_, status_, description_, create_on_, modify_on_
+  </sql>
+  
+  <sql id="queryCondition">
+  	<where>
+	  	<if test="search != null">
+	  		and (name_ like '%' #{search} '%' or description_ like '%' #{search} '%')
+	  	</if>
+	  	<if test="status != null">
+	  		and status_ = #{status}
+	  	</if>
+  	</where>
+  </sql>
+  
+  <select id="get" resultMap="TaskResultMap" parameterType="java.lang.Integer" >
+    select 
+    <include refid="Base_Column_List" />
+    from sys_task
+    where id_ = #{id,jdbcType=INTEGER}
+  </select>
+  
+  <delete id="delete" parameterType="java.lang.Integer" >
+    delete from sys_task
+    where id_ = #{id,jdbcType=INTEGER}
+  </delete>
+  
+  <insert id="insert" parameterType="com.yonge.cooleshow.task.dal.model.Task" >
+    insert into sys_task (id_, name_, group_, 
+      job_class_, time_exp_, status_, 
+      description_, create_on_, modify_on_
+      )
+    values (#{id,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR}, #{group,jdbcType=VARCHAR}, 
+      #{jobClass,jdbcType=VARCHAR}, #{timeExp,jdbcType=VARCHAR}, #{status,jdbcType=TINYINT}, 
+      #{description,jdbcType=VARCHAR}, #{createOn,jdbcType=TIMESTAMP}, #{modifyOn,jdbcType=TIMESTAMP}
+      )
+  </insert>
+  
+  <update id="update" parameterType="com.yonge.cooleshow.task.dal.model.Task" >
+    update sys_task
+    set name_ = #{name,jdbcType=VARCHAR},
+      group_ = #{group,jdbcType=VARCHAR},
+      job_class_ = #{jobClass,jdbcType=VARCHAR},
+      time_exp_ = #{timeExp,jdbcType=VARCHAR},
+      status_ = #{status,jdbcType=TINYINT},
+      description_ = #{description,jdbcType=VARCHAR},
+      create_on_ = #{createOn,jdbcType=TIMESTAMP},
+      modify_on_ = #{modifyOn,jdbcType=TIMESTAMP}
+    where id_ = #{id,jdbcType=INTEGER}
+  </update>
+  
+  <select id="queryAvailableTasks" resultMap="TaskResultMap">
+    select  * from sys_task
+    where status_ != 0 and status_ != 2
+  </select>
+  
+  <select id="queryTaskByNameAndGroup" resultMap="TaskResultMap" parameterType="java.util.Map" >
+    select 
+    <include refid="Base_Column_List" />
+    from sys_task
+    where name_ = #{name} and group_ = #{group}
+  </select>
+  
+  <update id="updateStatusById" parameterType="java.util.Map">
+  	update sys_task set status_ = #{curStatus},modify_on_ = now() where id_ = #{id} and status_ = #{oldStatus} 
+  </update>
+  
+  <select id="queryCount" parameterType="map" resultType="int">
+  	select count(*) from  sys_task
+   <include refid="queryCondition"/>
+  </select>
+
+  <select id="queryPage" parameterType="map" resultMap="TaskResultMap">
+ 	 select * from sys_task
+   <include refid="queryCondition"/>
+   order by create_on_ desc
+   <include refid="global.limit"/>
+  </select>
+
+	<select id="getLocked" resultMap="TaskResultMap" parameterType="java.lang.Integer">
+		select
+		<include refid="Base_Column_List" />
+		from sys_task
+		where id_ = #{id,jdbcType=INTEGER} for update
+	</select>
+</mapper>

+ 29 - 0
cooleshow-task/src/main/resources/config/properties/quartz.properties

@@ -0,0 +1,29 @@
+#============================================================================
+# Configure Main Scheduler Properties  
+#============================================================================
+
+org.quartz.scheduler.instanceName = p2p
+org.quartz.scheduler.instanceId = AUTO
+
+#============================================================================
+# Configure ThreadPool  
+#============================================================================
+
+org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
+org.quartz.threadPool.threadCount = 25
+org.quartz.threadPool.threadPriority = 5
+
+#============================================================================
+# Configure JobStore  
+#============================================================================
+
+org.quartz.jobStore.misfireThreshold = 60000
+
+org.quartz.jobStore.class = org.springframework.scheduling.quartz.LocalDataSourceJobStore
+org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
+#org.quartz.jobStore.useProperties = false
+#org.quartz.jobStore.dataSource = myDS
+org.quartz.jobStore.tablePrefix = QRTZ_
+
+org.quartz.jobStore.isClustered = true
+org.quartz.jobStore.clusterCheckinInterval = 20000

+ 179 - 0
cooleshow-task/src/main/resources/config/properties/tables_mysql_innodb.sql

@@ -0,0 +1,179 @@
+#
+# In your Quartz properties file, you'll need to set 
+# org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
+#
+#
+# By: Ron Cordell - roncordell
+#  I didn't see this anywhere, so I thought I'd post it here. This is the script from Quartz to create the tables in a MySQL database, modified to use INNODB instead of MYISAM.
+
+DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
+DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;
+DROP TABLE IF EXISTS QRTZ_LOCKS;
+DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;
+DROP TABLE IF EXISTS QRTZ_CALENDARS;
+
+CREATE TABLE QRTZ_JOB_DETAILS(
+SCHED_NAME VARCHAR(120) NOT NULL,
+JOB_NAME VARCHAR(200) NOT NULL,
+JOB_GROUP VARCHAR(200) NOT NULL,
+DESCRIPTION VARCHAR(250) NULL,
+JOB_CLASS_NAME VARCHAR(250) NOT NULL,
+IS_DURABLE VARCHAR(1) NOT NULL,
+IS_NONCONCURRENT VARCHAR(1) NOT NULL,
+IS_UPDATE_DATA VARCHAR(1) NOT NULL,
+REQUESTS_RECOVERY VARCHAR(1) NOT NULL,
+JOB_DATA BLOB NULL,
+PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP))
+ENGINE=InnoDB;
+
+CREATE TABLE QRTZ_TRIGGERS (
+SCHED_NAME VARCHAR(120) NOT NULL,
+TRIGGER_NAME VARCHAR(200) NOT NULL,
+TRIGGER_GROUP VARCHAR(200) NOT NULL,
+JOB_NAME VARCHAR(200) NOT NULL,
+JOB_GROUP VARCHAR(200) NOT NULL,
+DESCRIPTION VARCHAR(250) NULL,
+NEXT_FIRE_TIME BIGINT(13) NULL,
+PREV_FIRE_TIME BIGINT(13) NULL,
+PRIORITY INTEGER NULL,
+TRIGGER_STATE VARCHAR(16) NOT NULL,
+TRIGGER_TYPE VARCHAR(8) NOT NULL,
+START_TIME BIGINT(13) NOT NULL,
+END_TIME BIGINT(13) NULL,
+CALENDAR_NAME VARCHAR(200) NULL,
+MISFIRE_INSTR SMALLINT(2) NULL,
+JOB_DATA BLOB NULL,
+PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
+REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP))
+ENGINE=InnoDB;
+
+CREATE TABLE QRTZ_SIMPLE_TRIGGERS (
+SCHED_NAME VARCHAR(120) NOT NULL,
+TRIGGER_NAME VARCHAR(200) NOT NULL,
+TRIGGER_GROUP VARCHAR(200) NOT NULL,
+REPEAT_COUNT BIGINT(7) NOT NULL,
+REPEAT_INTERVAL BIGINT(12) NOT NULL,
+TIMES_TRIGGERED BIGINT(10) NOT NULL,
+PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
+ENGINE=InnoDB;
+
+CREATE TABLE QRTZ_CRON_TRIGGERS (
+SCHED_NAME VARCHAR(120) NOT NULL,
+TRIGGER_NAME VARCHAR(200) NOT NULL,
+TRIGGER_GROUP VARCHAR(200) NOT NULL,
+CRON_EXPRESSION VARCHAR(120) NOT NULL,
+TIME_ZONE_ID VARCHAR(80),
+PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
+ENGINE=InnoDB;
+
+CREATE TABLE QRTZ_SIMPROP_TRIGGERS
+  (          
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    TRIGGER_NAME VARCHAR(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR(200) NOT NULL,
+    STR_PROP_1 VARCHAR(512) NULL,
+    STR_PROP_2 VARCHAR(512) NULL,
+    STR_PROP_3 VARCHAR(512) NULL,
+    INT_PROP_1 INT NULL,
+    INT_PROP_2 INT NULL,
+    LONG_PROP_1 BIGINT NULL,
+    LONG_PROP_2 BIGINT NULL,
+    DEC_PROP_1 NUMERIC(13,4) NULL,
+    DEC_PROP_2 NUMERIC(13,4) NULL,
+    BOOL_PROP_1 VARCHAR(1) NULL,
+    BOOL_PROP_2 VARCHAR(1) NULL,
+    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
+    REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
+ENGINE=InnoDB;
+
+CREATE TABLE QRTZ_BLOB_TRIGGERS (
+SCHED_NAME VARCHAR(120) NOT NULL,
+TRIGGER_NAME VARCHAR(200) NOT NULL,
+TRIGGER_GROUP VARCHAR(200) NOT NULL,
+BLOB_DATA BLOB NULL,
+PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+INDEX (SCHED_NAME,TRIGGER_NAME, TRIGGER_GROUP),
+FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
+ENGINE=InnoDB;
+
+CREATE TABLE QRTZ_CALENDARS (
+SCHED_NAME VARCHAR(120) NOT NULL,
+CALENDAR_NAME VARCHAR(200) NOT NULL,
+CALENDAR BLOB NOT NULL,
+PRIMARY KEY (SCHED_NAME,CALENDAR_NAME))
+ENGINE=InnoDB;
+
+CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS (
+SCHED_NAME VARCHAR(120) NOT NULL,
+TRIGGER_GROUP VARCHAR(200) NOT NULL,
+PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP))
+ENGINE=InnoDB;
+
+CREATE TABLE QRTZ_FIRED_TRIGGERS (
+SCHED_NAME VARCHAR(120) NOT NULL,
+ENTRY_ID VARCHAR(95) NOT NULL,
+TRIGGER_NAME VARCHAR(200) NOT NULL,
+TRIGGER_GROUP VARCHAR(200) NOT NULL,
+INSTANCE_NAME VARCHAR(200) NOT NULL,
+FIRED_TIME BIGINT(13) NOT NULL,
+SCHED_TIME BIGINT(13) NOT NULL,
+PRIORITY INTEGER NOT NULL,
+STATE VARCHAR(16) NOT NULL,
+JOB_NAME VARCHAR(200) NULL,
+JOB_GROUP VARCHAR(200) NULL,
+IS_NONCONCURRENT VARCHAR(1) NULL,
+REQUESTS_RECOVERY VARCHAR(1) NULL,
+PRIMARY KEY (SCHED_NAME,ENTRY_ID))
+ENGINE=InnoDB;
+
+CREATE TABLE QRTZ_SCHEDULER_STATE (
+SCHED_NAME VARCHAR(120) NOT NULL,
+INSTANCE_NAME VARCHAR(200) NOT NULL,
+LAST_CHECKIN_TIME BIGINT(13) NOT NULL,
+CHECKIN_INTERVAL BIGINT(13) NOT NULL,
+PRIMARY KEY (SCHED_NAME,INSTANCE_NAME))
+ENGINE=InnoDB;
+
+CREATE TABLE QRTZ_LOCKS (
+SCHED_NAME VARCHAR(120) NOT NULL,
+LOCK_NAME VARCHAR(40) NOT NULL,
+PRIMARY KEY (SCHED_NAME,LOCK_NAME))
+ENGINE=InnoDB;
+
+CREATE INDEX IDX_QRTZ_J_REQ_RECOVERY ON QRTZ_JOB_DETAILS(SCHED_NAME,REQUESTS_RECOVERY);
+CREATE INDEX IDX_QRTZ_J_GRP ON QRTZ_JOB_DETAILS(SCHED_NAME,JOB_GROUP);
+
+CREATE INDEX IDX_QRTZ_T_J ON QRTZ_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);
+CREATE INDEX IDX_QRTZ_T_JG ON QRTZ_TRIGGERS(SCHED_NAME,JOB_GROUP);
+CREATE INDEX IDX_QRTZ_T_C ON QRTZ_TRIGGERS(SCHED_NAME,CALENDAR_NAME);
+CREATE INDEX IDX_QRTZ_T_G ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);
+CREATE INDEX IDX_QRTZ_T_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE);
+CREATE INDEX IDX_QRTZ_T_N_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE);
+CREATE INDEX IDX_QRTZ_T_N_G_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE);
+CREATE INDEX IDX_QRTZ_T_NEXT_FIRE_TIME ON QRTZ_TRIGGERS(SCHED_NAME,NEXT_FIRE_TIME);
+CREATE INDEX IDX_QRTZ_T_NFT_ST ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME);
+CREATE INDEX IDX_QRTZ_T_NFT_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME);
+CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE);
+CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE_GRP ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE);
+
+CREATE INDEX IDX_QRTZ_FT_TRIG_INST_NAME ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME);
+CREATE INDEX IDX_QRTZ_FT_INST_JOB_REQ_RCVRY ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY);
+CREATE INDEX IDX_QRTZ_FT_J_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);
+CREATE INDEX IDX_QRTZ_FT_JG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_GROUP);
+CREATE INDEX IDX_QRTZ_FT_T_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP);
+CREATE INDEX IDX_QRTZ_FT_TG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);
+
+commit; 

+ 55 - 0
cooleshow-task/src/main/resources/logback-spring.xml

@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration scan="true" scanPeriod="10 seconds">
+
+	<property name="LOG_HOME" value="/mdata/logs/task-%d{yyyy-MM-dd_HH}-%i.log" />
+	<property name="CONSOLE_LOG_PATTERN"
+			  value="[%X{username} %X{ip} %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36}] : %msg%n" />
+
+	<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
+		<encoder charset="UTF-8">
+			<pattern>${CONSOLE_LOG_PATTERN}</pattern>
+		</encoder>
+	</appender>
+
+	<appender name="file"
+			  class="ch.qos.logback.core.rolling.RollingFileAppender">
+		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+			<FileNamePattern>${LOG_HOME}</FileNamePattern>
+			<MaxHistory>90</MaxHistory>
+			<TimeBasedFileNamingAndTriggeringPolicy
+					class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+				<MaxFileSize>20MB</MaxFileSize>
+			</TimeBasedFileNamingAndTriggeringPolicy>
+		</rollingPolicy>
+
+		<encoder>
+			<pattern>${CONSOLE_LOG_PATTERN}</pattern>
+		</encoder>
+	</appender>
+
+	<logger name="com.ym.mec" level="debug" />
+
+	<!--开发环境:打印控制台 -->
+	<springProfile name="dev">
+		<root level="info">
+			<appender-ref ref="stdout" />
+			<appender-ref ref="file" />
+		</root>
+	</springProfile>
+
+	<springProfile name="test">
+		<root level="INFO">
+			<appender-ref ref="stdout" />
+			<appender-ref ref="file" />
+		</root>
+	</springProfile>
+
+	<!--生产环境:输出到文件 -->
+	<springProfile name="prod">
+		<root level="WARN">
+			<appender-ref ref="stdout" />
+			<appender-ref ref="file" />
+		</root>
+	</springProfile>
+
+</configuration>

+ 3 - 3
pom.xml

@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 	<modelVersion>4.0.0</modelVersion>
 
 	<groupId>com.yonge.cooleshow</groupId>
@@ -355,5 +354,6 @@
 		<module>cooleshow-user</module>
 		<module>toolset</module>
 		<module>cooleshow-im</module>
-	</modules>
+	  <module>cooleshow-task</module>
+  </modules>
 </project>