xueli.xue il y a 9 ans
Parent
commit
2bfd1cb7a7

+ 2 - 0
README.md

@@ -4,6 +4,8 @@ github地址:https://github.com/xuxueli/xxl-job
 git.osc地址:http://git.oschina.net/xuxueli0323/xxl-job
 
 博客地址(内附使用教程):http://www.cnblogs.com/xuxueli/p/5021979.html
+
+技术交流群(仅作技术交流):367260654
 	
 # 特点:基于quartz封装实现的的集群任务调度管理平台
 	1、简单:支持通过Web页面对任务进行CRUD操作,操作简单,一分钟上手;

+ 29 - 11
doc/db/tables_xxl_log.sql

@@ -10,6 +10,7 @@
 # DROP TABLE IF EXISTS XXL_JOB_QRTZ_JOB_DETAILS;
 # DROP TABLE IF EXISTS XXL_JOB_QRTZ_CALENDARS;
 # DROP TABLE IF EXISTS `xxl_job_qrtz_trigger_log`;
+# DROP TABLE IF EXISTS `xxl_job_qrtz_trigger_info`;
 
 CREATE TABLE XXL_JOB_QRTZ_JOB_DETAILS
   (
@@ -158,18 +159,35 @@ CREATE TABLE XXL_JOB_QRTZ_LOCKS
 
 CREATE TABLE `xxl_job_qrtz_trigger_log` (
   `id` int(11) NOT NULL AUTO_INCREMENT,
-  `job_name` varchar(255) NOT NULL,
-  `job_cron` varchar(128) DEFAULT NULL,
-  `job_class` varchar(255) DEFAULT NULL,
-  `job_data` varchar(2048) DEFAULT NULL,
-  `trigger_time` datetime DEFAULT NULL,
-  `trigger_status` varchar(255) DEFAULT NULL,
-  `trigger_msg` varchar(2048) DEFAULT NULL,
-  `handle_time` datetime DEFAULT NULL,
-  `handle_status` varchar(255) DEFAULT NULL,
-  `handle_msg` varchar(2048) DEFAULT NULL,
+  `job_group` varchar(255) NOT NULL COMMENT '任务组',
+  `job_name` varchar(255) NOT NULL COMMENT '任务名',
+  `job_cron` varchar(128) NOT NULL COMMENT '任务执行CORN表达式',
+  `job_class` varchar(255) NOT NULL COMMENT '任务执行JobBean',
+  `job_data` varchar(2048) DEFAULT NULL COMMENT '任务执行数据',
+  `trigger_time` datetime DEFAULT NULL COMMENT '调度-时间',
+  `trigger_status` varchar(255) DEFAULT NULL COMMENT '调度-结果',
+  `trigger_msg` varchar(2048) DEFAULT NULL COMMENT '调度-日志',
+  `handle_time` datetime DEFAULT NULL COMMENT '执行-时间',
+  `handle_status` varchar(255) DEFAULT NULL COMMENT '执行-状态',
+  `handle_msg` varchar(2048) DEFAULT NULL COMMENT '执行-日志',
   PRIMARY KEY (`id`)
-) ENGINE=InnoDB AUTO_INCREMENT=127 DEFAULT CHARSET=utf8;
+);
+
+CREATE TABLE `xxl_job_qrtz_trigger_log` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `job_group` varchar(255) NOT NULL COMMENT '任务组',
+  `job_name` varchar(255) NOT NULL COMMENT '任务名',
+  `job_cron` varchar(128) NOT NULL COMMENT '任务执行CORN表达式',
+  `job_class` varchar(255) NOT NULL COMMENT '任务执行JobBean',
+  `job_data` varchar(2048) DEFAULT NULL COMMENT '任务执行数据',
+  `trigger_time` datetime DEFAULT NULL COMMENT '调度-时间',
+  `trigger_status` varchar(255) DEFAULT NULL COMMENT '调度-结果',
+  `trigger_msg` varchar(2048) DEFAULT NULL COMMENT '调度-日志',
+  `handle_time` datetime DEFAULT NULL COMMENT '执行-时间',
+  `handle_status` varchar(255) DEFAULT NULL COMMENT '执行-状态',
+  `handle_msg` varchar(2048) DEFAULT NULL COMMENT '执行-日志',
+  PRIMARY KEY (`id`)
+);
 
 commit;
 

+ 1 - 1
xxl-job-admin/pom.xml

@@ -127,7 +127,7 @@
 		<dependency>
 			<groupId>org.quartz-scheduler</groupId>
 			<artifactId>quartz</artifactId>
-			<version>2.2.1</version>
+			<version>2.2.2</version>
 		</dependency>
 		
 		<!-- httpclient -->

+ 1 - 1
xxl-job-admin/src/main/java/com/xxl/job/controller/IndexController.java

@@ -13,7 +13,7 @@ public class IndexController {
 
 	@RequestMapping("/")
 	public String index(Model model) {
-		return "redirect:job";
+		return "redirect:jobinfo";
 	}
 	
 	@RequestMapping("/help")

+ 5 - 5
xxl-job-admin/src/main/java/com/xxl/job/controller/JobController.java

@@ -22,6 +22,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
 
 import com.xxl.job.client.handler.HandlerRepository;
 import com.xxl.job.client.util.JacksonUtil;
+import com.xxl.job.core.constant.Constants.JobGroupEnum;
 import com.xxl.job.core.model.ReturnT;
 import com.xxl.job.core.model.XxlJobInfo;
 import com.xxl.job.core.util.DynamicSchedulerUtil;
@@ -33,17 +34,16 @@ import com.xxl.job.service.job.HttpJobBean;
  * @author xuxueli 2015-12-19 16:13:16
  */
 @Controller
-@RequestMapping("/job")
-public class JobController {
+@RequestMapping("/jobinfo")
+public class JobInfoController {
 	
 	@Resource
 	private IXxlJobInfoDao xxlJobInfoDao;
 	
 	@RequestMapping
 	public String index(Model model) {
-		//List<Map<String, Object>> jobList = DynamicSchedulerUtil.getJobList();
-		//model.addAttribute("jobList", jobList);
-		return "job/index";
+		model.addAttribute("JobGroupList", JobGroupEnum.values());
+		return "jobinfo/index";
 	}
 	
 	@RequestMapping("/pageList")

+ 26 - 37
xxl-job-admin/src/main/java/com/xxl/job/controller/JobLogController.java

@@ -1,7 +1,6 @@
 package com.xxl.job.controller;
 
 import java.text.ParseException;
-import java.util.Calendar;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
@@ -17,6 +16,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.ResponseBody;
 
+import com.xxl.job.core.constant.Constants.JobGroupEnum;
 import com.xxl.job.core.model.ReturnT;
 import com.xxl.job.core.model.XxlJobLog;
 import com.xxl.job.dao.IXxlJobLogDao;
@@ -32,33 +32,9 @@ public class JobLogController {
 	@Resource
 	public IXxlJobLogDao xxlJobLogDao;
 	
-	@RequestMapping("/save")
-	@ResponseBody
-	public ReturnT<String> triggerLog(int triggerLogId, String status, String msg) {
-		XxlJobLog log = xxlJobLogDao.load(triggerLogId);
-		if (log!=null) {
-			log.setHandleTime(new Date());
-			log.setHandleStatus(status);
-			log.setHandleMsg(msg);
-			xxlJobLogDao.updateHandleInfo(log);
-			return ReturnT.SUCCESS;
-		}
-		return ReturnT.FAIL;
-	}
-	
 	@RequestMapping
-	public String index(Model model, String jobName, String filterTime) {
-		
-		// 默认filterTime
-		Calendar todayz = Calendar.getInstance();
-		todayz.set(Calendar.HOUR_OF_DAY, 0);
-		todayz.set(Calendar.MINUTE, 0);
-		todayz.set(Calendar.SECOND, 0);
-		model.addAttribute("triggerTimeStart", todayz.getTime());
-		model.addAttribute("triggerTimeEnd", Calendar.getInstance().getTime());
-				
-		model.addAttribute("jobName", jobName);
-		model.addAttribute("filterTime", filterTime);
+	public String index(Model model) {
+		model.addAttribute("JobGroupList", JobGroupEnum.values());
 		return "joblog/index";
 	}
 	
@@ -66,7 +42,8 @@ public class JobLogController {
 	@ResponseBody
 	public Map<String, Object> pageList(@RequestParam(required = false, defaultValue = "0") int start,  
 			@RequestParam(required = false, defaultValue = "10") int length,
-			String jobName, String filterTime) {
+			String jobGroup, String jobName, String filterTime) {
+		
 		// parse param
 		Date triggerTimeStart = null;
 		Date triggerTimeEnd = null;
@@ -74,24 +51,36 @@ public class JobLogController {
 			String[] temp = filterTime.split(" - ");
 			if (temp!=null && temp.length == 2) {
 				try {
-					triggerTimeEnd = DateUtils.parseDate(temp[0], new String[]{"yyyy-MM-dd HH:mm:ss"});
+					triggerTimeStart = DateUtils.parseDate(temp[0], new String[]{"yyyy-MM-dd HH:mm:ss"});
 					triggerTimeEnd = DateUtils.parseDate(temp[1], new String[]{"yyyy-MM-dd HH:mm:ss"});
-				} catch (ParseException e) {
-					e.printStackTrace();
-				}
+				} catch (ParseException e) {	}
 			}
 		}
 		
 		// page query
-		List<XxlJobLog> list = xxlJobLogDao.pageList(start, length, jobName, triggerTimeStart, triggerTimeEnd);
-		int list_count = xxlJobLogDao.pageListCount(start, length, jobName, triggerTimeStart, triggerTimeEnd);
+		List<XxlJobLog> list = xxlJobLogDao.pageList(start, length, jobGroup, jobName, triggerTimeStart, triggerTimeEnd);
+		int list_count = xxlJobLogDao.pageListCount(start, length, jobGroup, jobName, triggerTimeStart, triggerTimeEnd);
 		
 		// package result
 		Map<String, Object> maps = new HashMap<String, Object>();
-	    maps.put("recordsTotal", list_count);	// 总记录数
-	    maps.put("recordsFiltered", list_count);// 过滤后的总记录数
-	    maps.put("data", list);  				// 分页列表
+	    maps.put("recordsTotal", list_count);		// 总记录数
+	    maps.put("recordsFiltered", list_count);	// 过滤后的总记录数
+	    maps.put("data", list);  					// 分页列表
 		return maps;
 	}
 	
+	@RequestMapping("/save")
+	@ResponseBody
+	public ReturnT<String> triggerLog(int triggerLogId, String status, String msg) {
+		XxlJobLog log = xxlJobLogDao.load(triggerLogId);
+		if (log!=null) {
+			log.setHandleTime(new Date());
+			log.setHandleStatus(status);
+			log.setHandleMsg(msg);
+			xxlJobLogDao.updateHandleInfo(log);
+			return ReturnT.SUCCESS;
+		}
+		return ReturnT.FAIL;
+	}
+	
 }

+ 32 - 0
xxl-job-admin/src/main/java/com/xxl/job/core/constant/Constants.java

@@ -0,0 +1,32 @@
+package com.xxl.job.core.constant;
+
+/**
+ * job group
+ * @author xuxueli 2016-1-15 14:23:05
+ */
+public class Constants {
+	
+	public enum JobGroupEnum{
+		DEFAULT("默认"),
+		WAIMAI("外卖"),
+		MOVIE("电影");
+		private String desc;
+		private JobGroupEnum(String desc){
+			this.desc = desc;
+		}
+		public String getDesc() {
+			return desc;
+		}
+		public static JobGroupEnum match(String name){
+			if (name==null || name.trim().length()==0) {
+				return null;
+			}
+			for (JobGroupEnum group : JobGroupEnum.values()) {
+				if (group.name().equals(name)) {
+					return group;
+				}
+			}
+			return null;
+		}
+	}
+}

+ 72 - 16
xxl-job-admin/src/main/java/com/xxl/job/core/model/XxlJobInfo.java

@@ -9,69 +9,125 @@ import java.util.Date;
 public class XxlJobInfo {
 	
 	private int id;
-	// job info
-	private String jobName;
-	private String jobCron;		// base on quartz
-	private String jobClass;	// base on quartz
-	private String jobStatus;	// base on quartz
-	private String jobData;		// base on db, Map-JSON-String
+	
+	private String jobGroup;	// base on quartz	任务组
+	private String jobName;		// base on quartz	任务名
+	private String jobCron;		// base on quartz	任务执行CRON表达式
+	private String jobClass;	// base on quartz	任务执行JobBean
+	private String jobData;		// base on db, Map-JSON-String	任务执行数据
+	
 	private Date addTime;
 	private Date updateTime;
 	
+	private String author;		// 作者
+	private String alarmEmail;	// 报警邮件
+	private int alarmThreshold;	// 报警阀值
+	
+	// copy from quartz
+	private String jobStatus;	// 任务状态
+
 	public int getId() {
 		return id;
 	}
+
 	public void setId(int id) {
 		this.id = id;
 	}
+
+	public String getJobGroup() {
+		return jobGroup;
+	}
+
+	public void setJobGroup(String jobGroup) {
+		this.jobGroup = jobGroup;
+	}
+
 	public String getJobName() {
 		return jobName;
 	}
+
 	public void setJobName(String jobName) {
 		this.jobName = jobName;
 	}
+
 	public String getJobCron() {
 		return jobCron;
 	}
+
 	public void setJobCron(String jobCron) {
 		this.jobCron = jobCron;
 	}
+
 	public String getJobClass() {
 		return jobClass;
 	}
+
 	public void setJobClass(String jobClass) {
 		this.jobClass = jobClass;
 	}
-	public String getJobStatus() {
-		return jobStatus;
-	}
-	public void setJobStatus(String jobStatus) {
-		this.jobStatus = jobStatus;
-	}
+
 	public String getJobData() {
 		return jobData;
 	}
+
 	public void setJobData(String jobData) {
 		this.jobData = jobData;
 	}
+
 	public Date getAddTime() {
 		return addTime;
 	}
+
 	public void setAddTime(Date addTime) {
 		this.addTime = addTime;
 	}
+
 	public Date getUpdateTime() {
 		return updateTime;
 	}
+
 	public void setUpdateTime(Date updateTime) {
 		this.updateTime = updateTime;
 	}
-	
+
+	public String getAuthor() {
+		return author;
+	}
+
+	public void setAuthor(String author) {
+		this.author = author;
+	}
+
+	public String getAlarmEmail() {
+		return alarmEmail;
+	}
+
+	public void setAlarmEmail(String alarmEmail) {
+		this.alarmEmail = alarmEmail;
+	}
+
+	public int getAlarmThreshold() {
+		return alarmThreshold;
+	}
+
+	public void setAlarmThreshold(int alarmThreshold) {
+		this.alarmThreshold = alarmThreshold;
+	}
+
+	public String getJobStatus() {
+		return jobStatus;
+	}
+
+	public void setJobStatus(String jobStatus) {
+		this.jobStatus = jobStatus;
+	}
+
 	@Override
 	public String toString() {
-		return "XxlJobInfo [id=" + id + ", jobName=" + jobName + ", jobCron=" + jobCron + ", jobClass=" + jobClass
-				+ ", jobStatus=" + jobStatus + ", jobData=" + jobData + ", addTime=" + addTime + ", updateTime="
-				+ updateTime + "]";
+		return "XxlJobInfo [id=" + id + ", jobGroup=" + jobGroup + ", jobName=" + jobName + ", jobCron=" + jobCron
+				+ ", jobClass=" + jobClass + ", jobData=" + jobData + ", addTime=" + addTime + ", updateTime="
+				+ updateTime + ", author=" + author + ", alarmEmail=" + alarmEmail + ", alarmThreshold="
+				+ alarmThreshold + ", jobStatus=" + jobStatus + "]";
 	}
 	
 }

+ 12 - 4
xxl-job-admin/src/main/java/com/xxl/job/core/model/XxlJobLog.java

@@ -9,7 +9,9 @@ import java.util.Date;
 public class XxlJobLog {
 	
 	private int id;
+	
 	// job info
+	private String jobGroup;
 	private String jobName;
 	private String jobCron;
 	private String jobClass;
@@ -31,6 +33,12 @@ public class XxlJobLog {
 	public void setId(int id) {
 		this.id = id;
 	}
+	public String getJobGroup() {
+		return jobGroup;
+	}
+	public void setJobGroup(String jobGroup) {
+		this.jobGroup = jobGroup;
+	}
 	public String getJobName() {
 		return jobName;
 	}
@@ -94,10 +102,10 @@ public class XxlJobLog {
 	
 	@Override
 	public String toString() {
-		return "XxlJobLog [id=" + id + ", jobName=" + jobName + ", jobCron=" + jobCron + ", jobClass=" + jobClass
-				+ ", jobData=" + jobData + ", triggerTime=" + triggerTime + ", triggerStatus=" + triggerStatus
-				+ ", triggerMsg=" + triggerMsg + ", handleTime=" + handleTime + ", handleStatus=" + handleStatus
-				+ ", handleMsg=" + handleMsg + "]";
+		return "XxlJobLog [id=" + id + ", jobGroup=" + jobGroup + ", jobName=" + jobName + ", jobCron=" + jobCron
+				+ ", jobClass=" + jobClass + ", jobData=" + jobData + ", triggerTime=" + triggerTime
+				+ ", triggerStatus=" + triggerStatus + ", triggerMsg=" + triggerMsg + ", handleTime=" + handleTime
+				+ ", handleStatus=" + handleStatus + ", handleMsg=" + handleMsg + "]";
 	}
 	
 }

+ 41 - 0
xxl-job-admin/src/main/java/com/xxl/job/core/resolver/WebExceptionResolver.java

@@ -0,0 +1,41 @@
+package com.xxl.job.core.resolver;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.method.HandlerMethod;
+import org.springframework.web.servlet.HandlerExceptionResolver;
+import org.springframework.web.servlet.ModelAndView;
+
+import com.xxl.job.client.util.JacksonUtil;
+import com.xxl.job.core.model.ReturnT;
+
+/**
+ * common exception resolver
+ * @author xuxueli 2016-1-6 19:22:18
+ */
+public class WebExceptionResolver implements HandlerExceptionResolver {
+	private static transient Logger logger = LoggerFactory.getLogger(WebExceptionResolver.class);
+
+	@Override
+	public ModelAndView resolveException(HttpServletRequest request,
+			HttpServletResponse response, Object handler, Exception ex) {
+		logger.error("system catch exception:{}", ex);
+		
+		ModelAndView mv = new ModelAndView();
+		HandlerMethod method = (HandlerMethod)handler;
+		ResponseBody responseBody = method.getMethodAnnotation(ResponseBody.class);
+		if (responseBody != null) {
+			mv.addObject("result", JacksonUtil.writeValueAsString(new ReturnT<String>(500, ex.toString().replaceAll("\n", "<br/>"))));
+			mv.setViewName("/common/common.result");
+		} else {
+			mv.addObject("exceptionMsg", ex.toString().replaceAll("\n", "<br/>"));	
+			mv.setViewName("/common/common.exception");
+		}
+		return mv;
+	}
+	
+}

+ 4 - 7
xxl-job-admin/src/main/java/com/xxl/job/dao/IXxlJobLogDao.java

@@ -1,6 +1,5 @@
 package com.xxl.job.dao;
 
-
 import java.util.Date;
 import java.util.List;
 
@@ -12,16 +11,14 @@ import com.xxl.job.core.model.XxlJobLog;
  */
 public interface IXxlJobLogDao {
 	
-	public int save(XxlJobLog xxlJobLog);
+	public List<XxlJobLog> pageList(int offset, int pagesize, String jobGroup, String jobName, Date triggerTimeStart, Date triggerTimeEnd);
+	public int pageListCount(int offset, int pagesize, String jobGroup, String jobName, Date triggerTimeStart, Date triggerTimeEnd);
 	
 	public XxlJobLog load(int id);
+	public XxlJobLog loadByGroupAndName(String jobGroup, String jobName);
 	
+	public int save(XxlJobLog xxlJobLog);
 	public int updateTriggerInfo(XxlJobLog xxlJobLog);
-	
 	public int updateHandleInfo(XxlJobLog xxlJobLog);
 	
-	public List<XxlJobLog> pageList(int offset, int pagesize,String jobName, Date triggerTimeStart, Date triggerTimeEnd);
-	
-	public int pageListCount(int offset, int pagesize,String jobName, Date triggerTimeStart, Date triggerTimeEnd);
-	
 }

+ 39 - 27
xxl-job-admin/src/main/java/com/xxl/job/dao/impl/XxlJobLogDaoImpl.java

@@ -23,18 +23,52 @@ public class XxlJobLogDaoImpl implements IXxlJobLogDao {
 	public SqlSessionTemplate sqlSessionTemplate;
 
 	@Override
-	public int save(XxlJobLog xxlJobLog) {
-		if (xxlJobLog!=null && xxlJobLog.getJobData().length()>2000) {
-			xxlJobLog.setJobData(xxlJobLog.getJobData().substring(0, 2000));
-		}
-		return sqlSessionTemplate.insert("XxlJobLogMapper.save", xxlJobLog);
+	public List<XxlJobLog> pageList(int offset, int pagesize, String jobGroup, String jobName, Date triggerTimeStart, Date triggerTimeEnd) {
+		HashMap<String, Object> params = new HashMap<String, Object>();
+		params.put("offset", offset);
+		params.put("pagesize", pagesize);
+		params.put("jobGroup", jobGroup);
+		params.put("jobName", jobName);
+		params.put("triggerTimeStart", triggerTimeStart);
+		params.put("triggerTimeEnd", triggerTimeEnd);
+		
+		return sqlSessionTemplate.selectList("XxlJobLogMapper.pageList", params);
+	}
+
+	@Override
+	public int pageListCount(int offset, int pagesize, String jobGroup, String jobName, Date triggerTimeStart, Date triggerTimeEnd) {
+		HashMap<String, Object> params = new HashMap<String, Object>();
+		params.put("offset", offset);
+		params.put("pagesize", pagesize);
+		params.put("jobGroup", jobGroup);
+		params.put("jobName", jobName);
+		params.put("triggerTimeStart", triggerTimeStart);
+		params.put("triggerTimeEnd", triggerTimeEnd);
+		
+		return sqlSessionTemplate.selectOne("XxlJobLogMapper.pageListCount", params);
 	}
 
 	@Override
 	public XxlJobLog load(int id) {
 		return sqlSessionTemplate.selectOne("XxlJobLogMapper.load", id);
 	}
+	
+	@Override
+	public XxlJobLog loadByGroupAndName(String jobGroup, String jobName) {
+		HashMap<String, Object> params = new HashMap<String, Object>();
+		params.put("jobGroup", jobGroup);
+		params.put("jobName", jobName);
+		return sqlSessionTemplate.selectOne("XxlJobLogMapper.loadByGroupAndName", params);
+	}
 
+	@Override
+	public int save(XxlJobLog xxlJobLog) {
+		if (xxlJobLog!=null && xxlJobLog.getJobData().length()>2000) {
+			xxlJobLog.setJobData(xxlJobLog.getJobData().substring(0, 2000));
+		}
+		return sqlSessionTemplate.insert("XxlJobLogMapper.save", xxlJobLog);
+	}
+	
 	@Override
 	public int updateTriggerInfo(XxlJobLog xxlJobLog) {
 		if (xxlJobLog!=null && xxlJobLog.getTriggerMsg().length()>2000) {
@@ -50,27 +84,5 @@ public class XxlJobLogDaoImpl implements IXxlJobLogDao {
 		}
 		return sqlSessionTemplate.update("XxlJobLogMapper.updateHandleInfo", xxlJobLog);
 	}
-
-	@Override
-	public List<XxlJobLog> pageList(int offset, int pagesize,String jobName, Date triggerTimeStart, Date triggerTimeEnd) {
-		HashMap<String, Object> params = new HashMap<String, Object>();
-		params.put("offset", offset);
-		params.put("pagesize", pagesize);
-		params.put("jobName", jobName);
-		params.put("triggerTimeStart", triggerTimeStart);
-		params.put("triggerTimeEnd", triggerTimeEnd);
-		return sqlSessionTemplate.selectList("XxlJobLogMapper.pageList", params);
-	}
-
-	@Override
-	public int pageListCount(int offset, int pagesize,String jobName, Date triggerTimeStart, Date triggerTimeEnd) {
-		HashMap<String, Object> params = new HashMap<String, Object>();
-		params.put("offset", offset);
-		params.put("pagesize", pagesize);
-		params.put("jobName", jobName);
-		params.put("triggerTimeStart", triggerTimeStart);
-		params.put("triggerTimeEnd", triggerTimeEnd);
-		return sqlSessionTemplate.selectOne("XxlJobLogMapper.pageListCount", params);
-	}
 	
 }

+ 61 - 44
xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobLogMapper.xml

@@ -6,6 +6,7 @@
 	<resultMap id="XxlJobLog" type="com.xxl.job.core.model.XxlJobLog" >
 		<result column="id" property="id" />
 	
+	    <result column="job_group" property="jobGroup" />
 	    <result column="job_name" property="jobName" />
 	    <result column="job_cron" property="jobCron" />
 	    <result column="job_class" property="jobClass" />
@@ -22,6 +23,7 @@
 
 	<sql id="Base_Column_List">
 		t.id,
+		t.job_group,
 		t.job_name,
 		t.job_cron,
 		t.job_class,
@@ -34,16 +36,71 @@
 		t.handle_msg
 	</sql>
 	
+	<select id="pageList" parameterType="java.util.HashMap" resultMap="XxlJobLog">
+		SELECT <include refid="Base_Column_List" />
+		FROM xxl_job_qrtz_trigger_log AS t
+		<trim prefix="WHERE" prefixOverrides="AND | OR" >
+			<if test="jobGroup != null and jobGroup != ''">
+				AND t.job_group = #{jobGroup}
+			</if>
+			<if test="jobName != null and jobName != ''">
+				AND t.job_name = #{jobName}
+			</if>
+			<if test="triggerTimeStart != null">
+				AND t.trigger_time <![CDATA[ >= ]]> #{triggerTimeStart}
+			</if>
+			<if test="triggerTimeEnd != null">
+				AND t.trigger_time <![CDATA[ <= ]]> #{triggerTimeEnd}
+			</if>
+		</trim>
+		ORDER BY id DESC
+		LIMIT #{offset}, #{pagesize}
+	</select>
+	
+	<select id="pageListCount" parameterType="java.util.HashMap" resultType="int">
+		SELECT count(1)
+		FROM xxl_job_qrtz_trigger_log AS t
+		<trim prefix="WHERE" prefixOverrides="AND | OR" >
+			<if test="jobGroup != null and jobGroup != ''">
+				AND t.job_group = #{jobGroup}
+			</if>
+			<if test="jobName != null and jobName != ''">
+				AND t.job_name = #{jobName}
+			</if>
+			<if test="triggerTimeStart != null">
+				AND t.trigger_time <![CDATA[ >= ]]> #{triggerTimeStart}
+			</if>
+			<if test="triggerTimeEnd != null">
+				AND t.trigger_time <![CDATA[ <= ]]> #{triggerTimeEnd}
+			</if>
+		</trim>
+	</select>
+	
+	<select id="load" parameterType="java.lang.Integer" resultMap="XxlJobLog">
+		SELECT <include refid="Base_Column_List" />
+		FROM xxl_job_qrtz_trigger_log AS t
+		WHERE t.id = #{id}
+	</select>
+	
+	<select id="loadByGroupAndName" parameterType="java.util.HashMap" resultMap="XxlJobLog">
+		SELECT <include refid="Base_Column_List" />
+		FROM xxl_job_qrtz_trigger_log AS t
+		WHERE t.job_group = #{jobGroup}
+			AND t.job_name = #{jobName}
+	</select>
+	
 	<insert id="save" parameterType="com.xxl.job.core.model.XxlJobLog" useGeneratedKeys="true" keyProperty="id" >
 		INSERT INTO `xxl_job_qrtz_trigger_log` (
-			`job_name`, 
+			`job_group`,
+			`job_name`,
 			`job_cron`, 
 			`job_class`, 
 			`job_data`
 		) VALUES (
-			#{jobName}, 
-			#{jobCron}, 
-			#{jobClass}, 
+			#{jobGroup}, 
+			#{jobName},
+			#{jobCron},
+			#{jobClass},
 			#{jobData}
 		);
 		<selectKey resultType="java.lang.Integer" order="AFTER" keyProperty="id"> 
@@ -51,12 +108,6 @@
 		</selectKey> 
 	</insert>
 	
-	<select id="load" parameterType="java.lang.Integer" resultMap="XxlJobLog">
-		SELECT <include refid="Base_Column_List" />
-		FROM xxl_job_qrtz_trigger_log AS t
-		WHERE t.id = #{id}
-	</select>
-	
 	<update id="updateTriggerInfo">
 		UPDATE `xxl_job_qrtz_trigger_log` 
 		SET 
@@ -75,38 +126,4 @@
 		WHERE `id`= #{id}
 	</update>
 	
-	<select id="pageList" parameterType="java.util.HashMap" resultMap="XxlJobLog">
-		SELECT <include refid="Base_Column_List" />
-		FROM xxl_job_qrtz_trigger_log AS t
-		<trim prefix="WHERE" prefixOverrides="AND | OR" >
-			<if test="jobName != null and jobName!=''">
-				AND t.job_name = #{jobName}
-			</if>
-			<if test="triggerTimeStart != null">
-				AND t.trigger_time <![CDATA[ > ]]> #{triggerTimeStart}
-			</if>
-			<if test="triggerTimeEnd != null">
-				AND t.trigger_time <![CDATA[ < ]]> #{triggerTimeEnd}
-			</if>
-		</trim>
-		ORDER BY id DESC
-		LIMIT #{offset}, #{pagesize}
-	</select>
-	
-	<select id="pageListCount" parameterType="java.util.HashMap" resultType="int">
-		SELECT count(1)
-		FROM xxl_job_qrtz_trigger_log AS t
-		<trim prefix="WHERE" prefixOverrides="AND | OR" >
-			<if test="jobName != null and jobName!=''">
-				AND t.job_name = #{jobName}
-			</if>
-			<if test="triggerTimeStart != null">
-				AND t.trigger_time <![CDATA[ > ]]> #{triggerTimeStart}
-			</if>
-			<if test="triggerTimeEnd != null">
-				AND t.trigger_time <![CDATA[ < ]]> #{triggerTimeEnd}
-			</if>
-		</trim>
-	</select>
-	
 </mapper>

+ 2 - 0
xxl-job-admin/src/main/resources/springmvc-context.xml

@@ -38,6 +38,8 @@
 		<property name="order" value="0" />
 	</bean>
 	
+	<bean id="exceptionResolver" class="com.xxl.job.core.resolver.WebExceptionResolver" />
+	
 	<!--
 	// 自定义拦截器,支持SSO登陆拦截 
 	<mvc:interceptors>

+ 1 - 1
xxl-job-admin/src/main/webapp/WEB-INF/template/common/common.macro.ftl

@@ -64,7 +64,7 @@
 			<!-- sidebar menu: : style can be found in sidebar.less -->
 			<ul class="sidebar-menu">
 				<li class="header">常用模块</li>
-				<li class="nav-click" ><a href="${request.contextPath}/job/"><i class="fa fa-circle-o text-red"></i> <span>调度管理</span></a></li>
+				<li class="nav-click" ><a href="${request.contextPath}/jobinfo"><i class="fa fa-circle-o text-red"></i> <span>调度管理</span></a></li>
 				<li class="nav-click" ><a href="${request.contextPath}/joblog"><i class="fa fa-circle-o text-yellow"></i><span>调度日志</span></a></li>
 				<li class="nav-click" ><a href="${request.contextPath}/help"><i class="fa fa-circle-o text-yellow"></i><span>使用教程</span></a></li>
 			</ul>

+ 23 - 5
xxl-job-admin/src/main/webapp/WEB-INF/template/job/index.ftl

@@ -30,6 +30,16 @@
 	    <section class="content">
 	    
 	    	<div class="row">
+	    		<div class="col-xs-4">
+	              	<div class="input-group">
+	                	<span class="input-group-addon">任务组</span>
+                		<select class="form-control" id="jobGroup" >
+                			<#list JobGroupList as group>
+                				<option value="${group}" >${group.desc}</option>
+                			</#list>
+	                  	</select>
+	              	</div>
+	            </div>
 	            <div class="col-xs-4">
 	              	<div class="input-group">
 	                	<span class="input-group-addon">
@@ -128,16 +138,24 @@
 
 <!-- job新增.模态框 -->
 <div class="modal fade" id="addModal" tabindex="-1" role="dialog"  aria-hidden="true">
-	<div class="modal-dialog">
+	<div class="modal-dialog modal-lg">
 		<div class="modal-content">
 			<div class="modal-header">
-            	<h4 class="modal-title" >新增调度信息</h4>
+            	<h4 class="modal-title" >新增任务调度信息</h4>
          	</div>
          	<div class="modal-body">
 				<form class="form-horizontal form" role="form" >
 					<div class="form-group">
-						<label for="firstname" class="col-sm-3 control-label">任务Key</label>
-						<div class="col-sm-9"><input type="text" class="form-control" name="triggerKeyName" placeholder="请输入任务Key" minlength="4" maxlength="100" ></div>
+						<label for="firstname" class="col-sm-2 control-label">任务组</label>
+						<div class="col-sm-4">
+							<select class="form-control" name="jobGroup" >
+		            			<#list JobGroupList as group>
+		            				<option value="${group}" >${group.desc}</option>
+		            			</#list>
+		                  	</select>
+						</div>
+						<label for="firstname" class="col-sm-2 control-label">任务名</label>
+						<div class="col-sm-4"><input type="text" class="form-control" name="triggerKeyName" placeholder="请输入任务Key" minlength="4" maxlength="100" ></div>
 					</div>
 					<div class="form-group">
 						<label for="lastname" class="col-sm-3 control-label">任务Corn</label>
@@ -219,6 +237,6 @@
 <script src="${request.contextPath}/static/adminlte/plugins/daterangepicker/moment.min.js"></script>
 <script src="${request.contextPath}/static/adminlte/plugins/daterangepicker/daterangepicker.js"></script>
 <script>var base_url = '${request.contextPath}';</script>
-<script src="${request.contextPath}/static/js/job.index.1.js"></script>
+<script src="${request.contextPath}/static/js/jobinfo.index.1.js"></script>
 </body>
 </html>

+ 32 - 21
xxl-job-admin/src/main/webapp/WEB-INF/template/joblog/index.ftl

@@ -30,23 +30,33 @@
 		<!-- Main content -->
 	    <section class="content">
 	    	<div class="row">
-	            <div class="col-xs-5">
+	    		<div class="col-xs-3">
+ 					<div class="input-group">
+	                	<span class="input-group-addon">任务组</span>
+                		<select class="form-control" id="jobGroup" >
+                			<#list JobGroupList as group>
+                				<option value="${group}" <#if jobInfo?exists && group == jobInfo.jobGroup>selected</#if> >${group.desc}</option>
+                			</#list>
+	                  	</select>
+	              	</div>
+	            </div>
+	            <div class="col-xs-3">
+	              	<div class="input-group">
+	                	<span class="input-group-addon">任务名</span>
+	                	<input type="text" class="form-control" id="jobName" value="${jobName}" autocomplete="on" >
+	              	</div>
+	            </div>
+	            <div class="col-xs-4">
               		<div class="input-group">
                 		<span class="input-group-addon">
 	                  		调度时间
 	                	</span>
 	                	<input type="text" class="form-control" id="filterTime" readonly 
-	                		value="<#if triggerTimeStart?exists && triggerTimeEnd?exists >${triggerTimeStart?if_exists?string('yyyy-MM-dd HH:mm:ss')} - ${triggerTimeEnd?if_exists?string('yyyy-MM-dd HH:mm:ss')}</#if>"  >
-	              	</div>
-	            </div>
-	            <div class="col-xs-5">
-	              	<div class="input-group">
-	                	<span class="input-group-addon">
-	                  		jobName
-	                	</span>
-	                	<input type="text" class="form-control" id="jobName" value="${jobName}" autocomplete="on" >
+	                		value2="<#if triggerTimeStart?exists && triggerTimeEnd?exists >${triggerTimeStart?if_exists?string('yyyy-MM-dd HH:mm:ss')} - ${triggerTimeEnd?if_exists?string('yyyy-MM-dd HH:mm:ss')}</#if>"  >
 	              	</div>
 	            </div>
+	            
+				
 	            <div class="col-xs-2">
 	            	<button class="btn btn-block btn-info" id="searchBtn">搜索</button>
 	            </div>
@@ -60,17 +70,18 @@
 			              	<table id="joblog_list" class="table table-bordered table-striped display" width="100%" >
 				                <thead>
 					            	<tr>
-					                	<th>id</th>
-					                  	<th>jobName</th>
-					                  	<th>jobCron</th>
-					                  	<th>jobClass</th>
-					                  	<th>jobData</th>
-					                  	<th>triggerTime</th>
-					                  	<th>triggerStatus</th>
-					                  	<th>triggerMsg</th>
-					                  	<th>handleTime</th>
-					                  	<th>handleStatus</th>
-					                  	<th>handleMsg</th>
+					                	<th name="id" >id</th>
+					                	<th name="jobGroup" >任务组</th>
+					                  	<th name="jobName" >任务名</th>
+					                  	<th name="jobCron" >Cron</th>
+					                  	<th name="jobClass" >JobBean</th>
+					                  	<th name="jobData" >任务数据</th>
+					                  	<th name="triggerTime" >调度时间</th>
+					                  	<th name="triggerStatus" >调度结果</th>
+					                  	<th name="triggerMsg" >调度日志</th>
+					                  	<th name="handleTime" >执行时间</th>
+					                  	<th name="handleStatus" >执行结果</th>
+					                  	<th name="handleMsg" >执行日志</th>
 					                </tr>
 				                </thead>
 				                <tbody></tbody>

BIN
xxl-job-admin/src/main/webapp/favicon.ico


+ 1 - 1
xxl-job-admin/src/main/webapp/static/js/job.index.1.js

@@ -5,7 +5,7 @@ $(function() {
 		"processing" : true, 
 	    "serverSide": true,
 		"ajax": {
-			url: base_url + "/job/pageList",
+			url: base_url + "/jobinfo/pageList",
 	        data : function ( d ) {
                 d.jobName = $('#jobName').val()
             }

+ 37 - 16
xxl-job-admin/src/main/webapp/static/js/joblog.index.1.js

@@ -8,46 +8,66 @@ $(function() {
 		"ajax": {
 	        url: base_url + "/joblog/pageList" ,
 	        data : function ( d ) {
+                d.jobGroup = $('#jobGroup').val();
+                d.jobName = $('#jobName').val();
                 d.filterTime = $('#filterTime').val();
-                d.jobName = $('#jobName').val()
             }
 	    },
-	    //"scrollX": true,	// X轴滚动条,取消自适应
+	    "searching": false,
+	    "ordering": false,
+	    //"scrollX": false,
 	    "columns": [
 	                { "data": 'id', "bSortable": false, "visible" : false},
-	                { "data": 'jobName', "bSortable": false},
-	                { "data": 'jobCron', "bSortable": false, "visible" : false},
-	                { "data": 'jobClass', "bSortable": false, "visible" : false},
-	                { "data": 'jobData', "bSortable": false, "visible" : false},
 	                { 
-	                	"data": 'triggerTime', 
+	                	"data": 'jobGroup', 
 	                	"bSortable": false, 
+	                	"render": function ( data, type, row ) {
+	            			var groupMenu = $("#jobGroup").find("option");
+	            			for ( var index in $("#jobGroup").find("option")) {
+	            				if ($(groupMenu[index]).attr('value') == data) {
+									return $(groupMenu[index]).html();
+								}
+							}
+	            			return data;
+	            		}
+            		},
+	                { "data": 'jobName'},
+	                { "data": 'jobCron', "visible" : false},
+	                { "data": 'jobClass', "visible" : false},
+	                { 
+	                	"data": 'jobData',
+	                	"visible" : false,
+	                	"render": function ( data, type, row ) {
+	                		return data?'<a class="logTips" href="javascript:;" >查看<span style="display:none;">'+ data +'</span></a>':"无";
+	                	}
+	                },
+	                { 
+	                	"data": 'triggerTime', 
 	                	"render": function ( data, type, row ) {
 	                		return data?moment(new Date(data)).format("YYYY-MM-DD HH:mm:ss"):"";
 	                	}
 	                },
-	                { "data": 'triggerStatus', "bSortable": false},
-	                { "data": 'triggerMsg',"bSortable": false,
+	                { "data": 'triggerStatus'},
+	                { 
+	                	"data": 'triggerMsg',
 	                	"render": function ( data, type, row ) {
-	                		return data?'<a class="logTips" href="javascript:;" >调度日志<span style="display:none;">'+ data +'</span></a>':"无";
+	                		return data?'<a class="logTips" href="javascript:;" >查看<span style="display:none;">'+ data +'</span></a>':"无";
 	                	}
 	                },
 	                { 
 	                	"data": 'handleTime',
-	                	"bSortable": false,
 	                	"render": function ( data, type, row ) {
 	                		return data?moment(new Date(data)).format("YYYY-MM-DD HH:mm:ss"):"";
 	                	}
 	                },
 	                { "data": 'handleStatus',"bSortable": false},
-	                { "data": 'handleMsg' , "bSortable": false,
+	                { 
+	                	"data": 'handleMsg',
 	                	"render": function ( data, type, row ) {
-	                		return data?'<a class="logTips" href="javascript:;" >执行日志<span style="display:none;">'+ data +'</span></a>':"无";
+	                		return data?'<a class="logTips" href="javascript:;" >查看<span style="display:none;">'+ data +'</span></a>':"无";
 	                	}
 	                }
 	            ],
-	    "searching": false,
-	    "ordering": true,
 		"language" : {
 			"sProcessing" : "处理中...",
 			"sLengthMenu" : "每页 _MENU_ 条记录",
@@ -94,7 +114,7 @@ $(function() {
             '最近7日': [moment().subtract('days', 6), moment()],
             '最近30日': [moment().subtract('days', 29), moment()]
         },
-        opens : 'right', //日期选择框的弹出位置
+        opens : 'left', //日期选择框的弹出位置
         locale : {
         	customRangeLabel : '自定义',
             applyLabel : '确定',
@@ -106,6 +126,7 @@ $(function() {
             firstDay : 1
         }
 	});
+	$('#filterTime').val( moment(new Date()).format("YYYY-MM-DD 00:00:00") + ' - ' + moment(new Date()).format("YYYY-MM-DD HH:mm:ss") );
 	
 	// 搜索按钮
 	$('#searchBtn').on('click', function(){