Commit 6fd7c943 by xuxueli

UI以及库中,新增字段 "失败重试次数"

parent 3d15669b
package com.xxl.job.admin.controller; package com.xxl.job.admin.controller;
import com.xxl.job.admin.core.model.XxlJobGroup; import com.xxl.job.admin.core.model.XxlJobGroup;
import com.xxl.job.admin.core.model.XxlJobInfo; import com.xxl.job.admin.core.model.XxlJobInfo;
import com.xxl.job.admin.core.route.ExecutorRouteStrategyEnum; import com.xxl.job.admin.core.route.ExecutorRouteStrategyEnum;
import com.xxl.job.admin.dao.XxlJobGroupDao; import com.xxl.job.admin.dao.XxlJobGroupDao;
import com.xxl.job.admin.service.XxlJobService; import com.xxl.job.admin.service.XxlJobService;
import com.xxl.job.core.biz.model.ReturnT; import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.enums.ExecutorBlockStrategyEnum; import com.xxl.job.core.enums.ExecutorBlockStrategyEnum;
import com.xxl.job.core.glue.GlueTypeEnum; import com.xxl.job.core.glue.GlueTypeEnum;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model; import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
* index controller * index controller
* @author xuxueli 2015-12-19 16:13:16 * @author xuxueli 2015-12-19 16:13:16
*/ */
@Controller @Controller
@RequestMapping("/jobinfo") @RequestMapping("/jobinfo")
public class JobInfoController { public class JobInfoController {
@Resource @Resource
private XxlJobGroupDao xxlJobGroupDao; private XxlJobGroupDao xxlJobGroupDao;
@Resource @Resource
private XxlJobService xxlJobService; private XxlJobService xxlJobService;
@RequestMapping @RequestMapping
public String index(Model model, @RequestParam(required = false, defaultValue = "-1") int jobGroup) { public String index(Model model, @RequestParam(required = false, defaultValue = "-1") int jobGroup) {
// 枚举-字典 // 枚举-字典
model.addAttribute("ExecutorRouteStrategyEnum", ExecutorRouteStrategyEnum.values()); // 路由策略-列表 model.addAttribute("ExecutorRouteStrategyEnum", ExecutorRouteStrategyEnum.values()); // 路由策略-列表
model.addAttribute("GlueTypeEnum", GlueTypeEnum.values()); // Glue类型-字典 model.addAttribute("GlueTypeEnum", GlueTypeEnum.values()); // Glue类型-字典
model.addAttribute("ExecutorBlockStrategyEnum", ExecutorBlockStrategyEnum.values()); // 阻塞处理策略-字典 model.addAttribute("ExecutorBlockStrategyEnum", ExecutorBlockStrategyEnum.values()); // 阻塞处理策略-字典
// 任务组 // 任务组
List<XxlJobGroup> jobGroupList = xxlJobGroupDao.findAll(); List<XxlJobGroup> jobGroupList = xxlJobGroupDao.findAll();
model.addAttribute("JobGroupList", jobGroupList); model.addAttribute("JobGroupList", jobGroupList);
model.addAttribute("jobGroup", jobGroup); model.addAttribute("jobGroup", jobGroup);
return "jobinfo/jobinfo.index"; return "jobinfo/jobinfo.index";
} }
@RequestMapping("/pageList") @RequestMapping("/pageList")
@ResponseBody @ResponseBody
public Map<String, Object> pageList(@RequestParam(required = false, defaultValue = "0") int start, public Map<String, Object> pageList(@RequestParam(required = false, defaultValue = "0") int start,
@RequestParam(required = false, defaultValue = "10") int length, @RequestParam(required = false, defaultValue = "10") int length,
int jobGroup, String jobDesc, String executorHandler, String filterTime) { int jobGroup, String jobDesc, String executorHandler, String filterTime) {
return xxlJobService.pageList(start, length, jobGroup, jobDesc, executorHandler, filterTime); return xxlJobService.pageList(start, length, jobGroup, jobDesc, executorHandler, filterTime);
} }
@RequestMapping("/add") @RequestMapping("/add")
@ResponseBody @ResponseBody
public ReturnT<String> add(XxlJobInfo jobInfo) { public ReturnT<String> add(XxlJobInfo jobInfo) {
return xxlJobService.add(jobInfo); return xxlJobService.add(jobInfo);
} }
@RequestMapping("/update") @RequestMapping("/update")
@ResponseBody @ResponseBody
public ReturnT<String> update(XxlJobInfo jobInfo) { public ReturnT<String> update(XxlJobInfo jobInfo) {
return xxlJobService.update(jobInfo); return xxlJobService.update(jobInfo);
} }
@RequestMapping("/remove") @RequestMapping("/remove")
@ResponseBody @ResponseBody
public ReturnT<String> remove(int id) { public ReturnT<String> remove(int id) {
return xxlJobService.remove(id); return xxlJobService.remove(id);
} }
@RequestMapping("/pause") @RequestMapping("/pause")
@ResponseBody @ResponseBody
public ReturnT<String> pause(int id) { public ReturnT<String> pause(int id) {
return xxlJobService.pause(id); return xxlJobService.pause(id);
} }
@RequestMapping("/resume") @RequestMapping("/resume")
@ResponseBody @ResponseBody
public ReturnT<String> resume(int id) { public ReturnT<String> resume(int id) {
return xxlJobService.resume(id); return xxlJobService.resume(id);
} }
@RequestMapping("/trigger") @RequestMapping("/trigger")
@ResponseBody @ResponseBody
public ReturnT<String> triggerJob(int id) { public ReturnT<String> triggerJob(int id) {
return xxlJobService.triggerJob(id); return xxlJobService.triggerJob(id);
} }
} }
package com.xxl.job.admin.core.model; package com.xxl.job.admin.core.model;
import java.util.Date; import java.util.Date;
/** /**
* xxl-job info * xxl-job info
* *
* @author xuxueli 2016-1-12 18:25:49 * @author xuxueli 2016-1-12 18:25:49
*/ */
public class XxlJobInfo { public class XxlJobInfo {
private int id; // 主键ID (JobKey.name) private int id; // 主键ID (JobKey.name)
private int jobGroup; // 执行器主键ID (JobKey.group) private int jobGroup; // 执行器主键ID (JobKey.group)
private String jobCron; // 任务执行CRON表达式 【base on quartz】 private String jobCron; // 任务执行CRON表达式 【base on quartz】
private String jobDesc; private String jobDesc;
private Date addTime; private Date addTime;
private Date updateTime; private Date updateTime;
private String author; // 负责人 private String author; // 负责人
private String alarmEmail; // 报警邮件 private String alarmEmail; // 报警邮件
private String executorRouteStrategy; // 执行器路由策略 private String executorRouteStrategy; // 执行器路由策略
private String executorHandler; // 执行器,任务Handler名称 private String executorHandler; // 执行器,任务Handler名称
private String executorParam; // 执行器,任务参数 private String executorParam; // 执行器,任务参数
private String executorBlockStrategy; // 阻塞处理策略 private String executorBlockStrategy; // 阻塞处理策略
private String executorFailStrategy; // 失败处理策略 private String executorFailStrategy; // 失败处理策略
private int executorTimeout; // 任务执行超时时间,单位秒 private int executorTimeout; // 任务执行超时时间,单位秒
private int executorFailRetryCount; // 失败重试次数 private int executorFailRetryCount; // 失败重试次数
private String glueType; // GLUE类型 #com.xxl.job.core.glue.GlueTypeEnum private String glueType; // GLUE类型 #com.xxl.job.core.glue.GlueTypeEnum
private String glueSource; // GLUE源代码 private String glueSource; // GLUE源代码
private String glueRemark; // GLUE备注 private String glueRemark; // GLUE备注
private Date glueUpdatetime; // GLUE更新时间 private Date glueUpdatetime; // GLUE更新时间
private String childJobId; // 子任务ID,多个逗号分隔 private String childJobId; // 子任务ID,多个逗号分隔
// copy from quartz // copy from quartz
private String jobStatus; // 任务状态 【base on quartz】 private String jobStatus; // 任务状态 【base on quartz】
public int getId() { public int getId() {
return id; return id;
} }
public void setId(int id) { public void setId(int id) {
this.id = id; this.id = id;
} }
public int getJobGroup() { public int getJobGroup() {
return jobGroup; return jobGroup;
} }
public void setJobGroup(int jobGroup) { public void setJobGroup(int jobGroup) {
this.jobGroup = jobGroup; this.jobGroup = jobGroup;
} }
public String getJobCron() { public String getJobCron() {
return jobCron; return jobCron;
} }
public void setJobCron(String jobCron) { public void setJobCron(String jobCron) {
this.jobCron = jobCron; this.jobCron = jobCron;
} }
public String getJobDesc() { public String getJobDesc() {
return jobDesc; return jobDesc;
} }
public void setJobDesc(String jobDesc) { public void setJobDesc(String jobDesc) {
this.jobDesc = jobDesc; this.jobDesc = jobDesc;
} }
public Date getAddTime() { public Date getAddTime() {
return addTime; return addTime;
} }
public void setAddTime(Date addTime) { public void setAddTime(Date addTime) {
this.addTime = addTime; this.addTime = addTime;
} }
public Date getUpdateTime() { public Date getUpdateTime() {
return updateTime; return updateTime;
} }
public void setUpdateTime(Date updateTime) { public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime; this.updateTime = updateTime;
} }
public String getAuthor() { public String getAuthor() {
return author; return author;
} }
public void setAuthor(String author) { public void setAuthor(String author) {
this.author = author; this.author = author;
} }
public String getAlarmEmail() { public String getAlarmEmail() {
return alarmEmail; return alarmEmail;
} }
public void setAlarmEmail(String alarmEmail) { public void setAlarmEmail(String alarmEmail) {
this.alarmEmail = alarmEmail; this.alarmEmail = alarmEmail;
} }
public String getExecutorRouteStrategy() { public String getExecutorRouteStrategy() {
return executorRouteStrategy; return executorRouteStrategy;
} }
public void setExecutorRouteStrategy(String executorRouteStrategy) { public void setExecutorRouteStrategy(String executorRouteStrategy) {
this.executorRouteStrategy = executorRouteStrategy; this.executorRouteStrategy = executorRouteStrategy;
} }
public String getExecutorHandler() { public String getExecutorHandler() {
return executorHandler; return executorHandler;
} }
public void setExecutorHandler(String executorHandler) { public void setExecutorHandler(String executorHandler) {
this.executorHandler = executorHandler; this.executorHandler = executorHandler;
} }
public String getExecutorParam() { public String getExecutorParam() {
return executorParam; return executorParam;
} }
public void setExecutorParam(String executorParam) { public void setExecutorParam(String executorParam) {
this.executorParam = executorParam; this.executorParam = executorParam;
} }
public String getExecutorBlockStrategy() { public String getExecutorBlockStrategy() {
return executorBlockStrategy; return executorBlockStrategy;
} }
public void setExecutorBlockStrategy(String executorBlockStrategy) { public void setExecutorBlockStrategy(String executorBlockStrategy) {
this.executorBlockStrategy = executorBlockStrategy; this.executorBlockStrategy = executorBlockStrategy;
} }
public String getExecutorFailStrategy() { public String getExecutorFailStrategy() {
return executorFailStrategy; return executorFailStrategy;
} }
public void setExecutorFailStrategy(String executorFailStrategy) { public void setExecutorFailStrategy(String executorFailStrategy) {
this.executorFailStrategy = executorFailStrategy; this.executorFailStrategy = executorFailStrategy;
} }
public int getExecutorTimeout() { public int getExecutorTimeout() {
return executorTimeout; return executorTimeout;
} }
public void setExecutorTimeout(int executorTimeout) { public void setExecutorTimeout(int executorTimeout) {
this.executorTimeout = executorTimeout; this.executorTimeout = executorTimeout;
} }
public int getExecutorFailRetryCount() { public int getExecutorFailRetryCount() {
return executorFailRetryCount; return executorFailRetryCount;
} }
public void setExecutorFailRetryCount(int executorFailRetryCount) { public void setExecutorFailRetryCount(int executorFailRetryCount) {
this.executorFailRetryCount = executorFailRetryCount; this.executorFailRetryCount = executorFailRetryCount;
} }
public String getGlueType() { public String getGlueType() {
return glueType; return glueType;
} }
public void setGlueType(String glueType) { public void setGlueType(String glueType) {
this.glueType = glueType; this.glueType = glueType;
} }
public String getGlueSource() { public String getGlueSource() {
return glueSource; return glueSource;
} }
public void setGlueSource(String glueSource) { public void setGlueSource(String glueSource) {
this.glueSource = glueSource; this.glueSource = glueSource;
} }
public String getGlueRemark() { public String getGlueRemark() {
return glueRemark; return glueRemark;
} }
public void setGlueRemark(String glueRemark) { public void setGlueRemark(String glueRemark) {
this.glueRemark = glueRemark; this.glueRemark = glueRemark;
} }
public Date getGlueUpdatetime() { public Date getGlueUpdatetime() {
return glueUpdatetime; return glueUpdatetime;
} }
public void setGlueUpdatetime(Date glueUpdatetime) { public void setGlueUpdatetime(Date glueUpdatetime) {
this.glueUpdatetime = glueUpdatetime; this.glueUpdatetime = glueUpdatetime;
} }
public String getChildJobId() { public String getChildJobId() {
return childJobId; return childJobId;
} }
public void setChildJobId(String childJobId) { public void setChildJobId(String childJobId) {
this.childJobId = childJobId; this.childJobId = childJobId;
} }
public String getJobStatus() { public String getJobStatus() {
return jobStatus; return jobStatus;
} }
public void setJobStatus(String jobStatus) { public void setJobStatus(String jobStatus) {
this.jobStatus = jobStatus; this.jobStatus = jobStatus;
} }
} }
package com.xxl.job.admin.service.impl; package com.xxl.job.admin.service.impl;
import com.xxl.job.admin.core.model.XxlJobGroup; import com.xxl.job.admin.core.model.XxlJobGroup;
import com.xxl.job.admin.core.model.XxlJobInfo; import com.xxl.job.admin.core.model.XxlJobInfo;
import com.xxl.job.admin.core.route.ExecutorRouteStrategyEnum; import com.xxl.job.admin.core.route.ExecutorRouteStrategyEnum;
import com.xxl.job.admin.core.schedule.XxlJobDynamicScheduler; import com.xxl.job.admin.core.schedule.XxlJobDynamicScheduler;
import com.xxl.job.admin.core.thread.JobTriggerPoolHelper; import com.xxl.job.admin.core.thread.JobTriggerPoolHelper;
import com.xxl.job.admin.core.util.I18nUtil; import com.xxl.job.admin.core.util.I18nUtil;
import com.xxl.job.admin.dao.XxlJobGroupDao; import com.xxl.job.admin.dao.XxlJobGroupDao;
import com.xxl.job.admin.dao.XxlJobInfoDao; import com.xxl.job.admin.dao.XxlJobInfoDao;
import com.xxl.job.admin.dao.XxlJobLogDao; import com.xxl.job.admin.dao.XxlJobLogDao;
import com.xxl.job.admin.dao.XxlJobLogGlueDao; import com.xxl.job.admin.dao.XxlJobLogGlueDao;
import com.xxl.job.admin.service.XxlJobService; import com.xxl.job.admin.service.XxlJobService;
import com.xxl.job.core.biz.model.ReturnT; import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.enums.ExecutorBlockStrategyEnum; import com.xxl.job.core.enums.ExecutorBlockStrategyEnum;
import com.xxl.job.core.glue.GlueTypeEnum; import com.xxl.job.core.glue.GlueTypeEnum;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils; import org.apache.commons.lang3.time.DateUtils;
import org.apache.commons.lang3.time.FastDateFormat; import org.apache.commons.lang3.time.FastDateFormat;
import org.quartz.CronExpression; import org.quartz.CronExpression;
import org.quartz.SchedulerException; import org.quartz.SchedulerException;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.*; import java.util.*;
/** /**
* core job action for xxl-job * core job action for xxl-job
* @author xuxueli 2016-5-28 15:30:33 * @author xuxueli 2016-5-28 15:30:33
*/ */
@Service @Service
public class XxlJobServiceImpl implements XxlJobService { public class XxlJobServiceImpl implements XxlJobService {
private static Logger logger = LoggerFactory.getLogger(XxlJobServiceImpl.class); private static Logger logger = LoggerFactory.getLogger(XxlJobServiceImpl.class);
@Resource @Resource
private XxlJobGroupDao xxlJobGroupDao; private XxlJobGroupDao xxlJobGroupDao;
@Resource @Resource
private XxlJobInfoDao xxlJobInfoDao; private XxlJobInfoDao xxlJobInfoDao;
@Resource @Resource
public XxlJobLogDao xxlJobLogDao; public XxlJobLogDao xxlJobLogDao;
@Resource @Resource
private XxlJobLogGlueDao xxlJobLogGlueDao; private XxlJobLogGlueDao xxlJobLogGlueDao;
@Override @Override
public Map<String, Object> pageList(int start, int length, int jobGroup, String jobDesc, String executorHandler, String filterTime) { public Map<String, Object> pageList(int start, int length, int jobGroup, String jobDesc, String executorHandler, String filterTime) {
// page list // page list
List<XxlJobInfo> list = xxlJobInfoDao.pageList(start, length, jobGroup, jobDesc, executorHandler); List<XxlJobInfo> list = xxlJobInfoDao.pageList(start, length, jobGroup, jobDesc, executorHandler);
int list_count = xxlJobInfoDao.pageListCount(start, length, jobGroup, jobDesc, executorHandler); int list_count = xxlJobInfoDao.pageListCount(start, length, jobGroup, jobDesc, executorHandler);
// fill job info // fill job info
if (list!=null && list.size()>0) { if (list!=null && list.size()>0) {
for (XxlJobInfo jobInfo : list) { for (XxlJobInfo jobInfo : list) {
XxlJobDynamicScheduler.fillJobInfo(jobInfo); XxlJobDynamicScheduler.fillJobInfo(jobInfo);
} }
} }
// package result // package result
Map<String, Object> maps = new HashMap<String, Object>(); Map<String, Object> maps = new HashMap<String, Object>();
maps.put("recordsTotal", list_count); // 总记录数 maps.put("recordsTotal", list_count); // 总记录数
maps.put("recordsFiltered", list_count); // 过滤后的总记录数 maps.put("recordsFiltered", list_count); // 过滤后的总记录数
maps.put("data", list); // 分页列表 maps.put("data", list); // 分页列表
return maps; return maps;
} }
@Override @Override
public ReturnT<String> add(XxlJobInfo jobInfo) { public ReturnT<String> add(XxlJobInfo jobInfo) {
// valid // valid
XxlJobGroup group = xxlJobGroupDao.load(jobInfo.getJobGroup()); XxlJobGroup group = xxlJobGroupDao.load(jobInfo.getJobGroup());
if (group == null) { if (group == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_choose")+I18nUtil.getString("jobinfo_field_jobgroup")) ); return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_choose")+I18nUtil.getString("jobinfo_field_jobgroup")) );
} }
if (!CronExpression.isValidExpression(jobInfo.getJobCron())) { if (!CronExpression.isValidExpression(jobInfo.getJobCron())) {
return new ReturnT<String>(ReturnT.FAIL_CODE, I18nUtil.getString("jobinfo_field_cron_unvalid") ); return new ReturnT<String>(ReturnT.FAIL_CODE, I18nUtil.getString("jobinfo_field_cron_unvalid") );
} }
if (StringUtils.isBlank(jobInfo.getJobDesc())) { if (StringUtils.isBlank(jobInfo.getJobDesc())) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input")+I18nUtil.getString("jobinfo_field_jobdesc")) ); return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input")+I18nUtil.getString("jobinfo_field_jobdesc")) );
} }
if (StringUtils.isBlank(jobInfo.getAuthor())) { if (StringUtils.isBlank(jobInfo.getAuthor())) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input")+I18nUtil.getString("jobinfo_field_author")) ); return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input")+I18nUtil.getString("jobinfo_field_author")) );
} }
if (ExecutorRouteStrategyEnum.match(jobInfo.getExecutorRouteStrategy(), null) == null) { if (ExecutorRouteStrategyEnum.match(jobInfo.getExecutorRouteStrategy(), null) == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_executorRouteStrategy")+I18nUtil.getString("system_unvalid")) ); return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_executorRouteStrategy")+I18nUtil.getString("system_unvalid")) );
} }
if (ExecutorBlockStrategyEnum.match(jobInfo.getExecutorBlockStrategy(), null) == null) { if (ExecutorBlockStrategyEnum.match(jobInfo.getExecutorBlockStrategy(), null) == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_executorBlockStrategy")+I18nUtil.getString("system_unvalid")) ); return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_executorBlockStrategy")+I18nUtil.getString("system_unvalid")) );
} }
if (GlueTypeEnum.match(jobInfo.getGlueType()) == null) { if (GlueTypeEnum.match(jobInfo.getGlueType()) == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_gluetype")+I18nUtil.getString("system_unvalid")) ); return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_gluetype")+I18nUtil.getString("system_unvalid")) );
} }
if (GlueTypeEnum.BEAN==GlueTypeEnum.match(jobInfo.getGlueType()) && StringUtils.isBlank(jobInfo.getExecutorHandler())) { if (GlueTypeEnum.BEAN==GlueTypeEnum.match(jobInfo.getGlueType()) && StringUtils.isBlank(jobInfo.getExecutorHandler())) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input")+"JobHandler") ); return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input")+"JobHandler") );
} }
// fix "\r" in shell // fix "\r" in shell
if (GlueTypeEnum.GLUE_SHELL==GlueTypeEnum.match(jobInfo.getGlueType()) && jobInfo.getGlueSource()!=null) { if (GlueTypeEnum.GLUE_SHELL==GlueTypeEnum.match(jobInfo.getGlueType()) && jobInfo.getGlueSource()!=null) {
jobInfo.setGlueSource(jobInfo.getGlueSource().replaceAll("\r", "")); jobInfo.setGlueSource(jobInfo.getGlueSource().replaceAll("\r", ""));
} }
// ChildJobId valid // ChildJobId valid
if (StringUtils.isNotBlank(jobInfo.getChildJobId())) { if (StringUtils.isNotBlank(jobInfo.getChildJobId())) {
String[] childJobIds = StringUtils.split(jobInfo.getChildJobId(), ","); String[] childJobIds = StringUtils.split(jobInfo.getChildJobId(), ",");
for (String childJobIdItem: childJobIds) { for (String childJobIdItem: childJobIds) {
if (StringUtils.isNotBlank(childJobIdItem) && StringUtils.isNumeric(childJobIdItem)) { if (StringUtils.isNotBlank(childJobIdItem) && StringUtils.isNumeric(childJobIdItem)) {
XxlJobInfo childJobInfo = xxlJobInfoDao.loadById(Integer.valueOf(childJobIdItem)); XxlJobInfo childJobInfo = xxlJobInfoDao.loadById(Integer.valueOf(childJobIdItem));
if (childJobInfo==null) { if (childJobInfo==null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, return new ReturnT<String>(ReturnT.FAIL_CODE,
MessageFormat.format((I18nUtil.getString("jobinfo_field_childJobId")+"({0})"+I18nUtil.getString("system_not_found")), childJobIdItem)); MessageFormat.format((I18nUtil.getString("jobinfo_field_childJobId")+"({0})"+I18nUtil.getString("system_not_found")), childJobIdItem));
} }
} else { } else {
return new ReturnT<String>(ReturnT.FAIL_CODE, return new ReturnT<String>(ReturnT.FAIL_CODE,
MessageFormat.format((I18nUtil.getString("jobinfo_field_childJobId")+"({0})"+I18nUtil.getString("system_unvalid")), childJobIdItem)); MessageFormat.format((I18nUtil.getString("jobinfo_field_childJobId")+"({0})"+I18nUtil.getString("system_unvalid")), childJobIdItem));
} }
} }
jobInfo.setChildJobId(StringUtils.join(childJobIds, ",")); jobInfo.setChildJobId(StringUtils.join(childJobIds, ","));
} }
// add in db // add in db
xxlJobInfoDao.save(jobInfo); xxlJobInfoDao.save(jobInfo);
if (jobInfo.getId() < 1) { if (jobInfo.getId() < 1) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_add")+I18nUtil.getString("system_fail")) ); return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_add")+I18nUtil.getString("system_fail")) );
} }
// add in quartz // add in quartz
String qz_group = String.valueOf(jobInfo.getJobGroup()); String qz_group = String.valueOf(jobInfo.getJobGroup());
String qz_name = String.valueOf(jobInfo.getId()); String qz_name = String.valueOf(jobInfo.getId());
try { try {
XxlJobDynamicScheduler.addJob(qz_name, qz_group, jobInfo.getJobCron()); XxlJobDynamicScheduler.addJob(qz_name, qz_group, jobInfo.getJobCron());
//XxlJobDynamicScheduler.pauseJob(qz_name, qz_group); //XxlJobDynamicScheduler.pauseJob(qz_name, qz_group);
return ReturnT.SUCCESS; return ReturnT.SUCCESS;
} catch (SchedulerException e) { } catch (SchedulerException e) {
logger.error(e.getMessage(), e); logger.error(e.getMessage(), e);
try { try {
xxlJobInfoDao.delete(jobInfo.getId()); xxlJobInfoDao.delete(jobInfo.getId());
XxlJobDynamicScheduler.removeJob(qz_name, qz_group); XxlJobDynamicScheduler.removeJob(qz_name, qz_group);
} catch (SchedulerException e1) { } catch (SchedulerException e1) {
logger.error(e.getMessage(), e1); logger.error(e.getMessage(), e1);
} }
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_add")+I18nUtil.getString("system_fail"))+":" + e.getMessage()); return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_add")+I18nUtil.getString("system_fail"))+":" + e.getMessage());
} }
} }
@Override @Override
public ReturnT<String> update(XxlJobInfo jobInfo) { public ReturnT<String> update(XxlJobInfo jobInfo) {
// valid // valid
if (!CronExpression.isValidExpression(jobInfo.getJobCron())) { if (!CronExpression.isValidExpression(jobInfo.getJobCron())) {
return new ReturnT<String>(ReturnT.FAIL_CODE, I18nUtil.getString("jobinfo_field_cron_unvalid") ); return new ReturnT<String>(ReturnT.FAIL_CODE, I18nUtil.getString("jobinfo_field_cron_unvalid") );
} }
if (StringUtils.isBlank(jobInfo.getJobDesc())) { if (StringUtils.isBlank(jobInfo.getJobDesc())) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input")+I18nUtil.getString("jobinfo_field_jobdesc")) ); return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input")+I18nUtil.getString("jobinfo_field_jobdesc")) );
} }
if (StringUtils.isBlank(jobInfo.getAuthor())) { if (StringUtils.isBlank(jobInfo.getAuthor())) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input")+I18nUtil.getString("jobinfo_field_author")) ); return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input")+I18nUtil.getString("jobinfo_field_author")) );
} }
if (ExecutorRouteStrategyEnum.match(jobInfo.getExecutorRouteStrategy(), null) == null) { if (ExecutorRouteStrategyEnum.match(jobInfo.getExecutorRouteStrategy(), null) == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_executorRouteStrategy")+I18nUtil.getString("system_unvalid")) ); return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_executorRouteStrategy")+I18nUtil.getString("system_unvalid")) );
} }
if (ExecutorBlockStrategyEnum.match(jobInfo.getExecutorBlockStrategy(), null) == null) { if (ExecutorBlockStrategyEnum.match(jobInfo.getExecutorBlockStrategy(), null) == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_executorBlockStrategy")+I18nUtil.getString("system_unvalid")) ); return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_executorBlockStrategy")+I18nUtil.getString("system_unvalid")) );
} }
// ChildJobId valid // ChildJobId valid
if (StringUtils.isNotBlank(jobInfo.getChildJobId())) { if (StringUtils.isNotBlank(jobInfo.getChildJobId())) {
String[] childJobIds = StringUtils.split(jobInfo.getChildJobId(), ","); String[] childJobIds = StringUtils.split(jobInfo.getChildJobId(), ",");
for (String childJobIdItem: childJobIds) { for (String childJobIdItem: childJobIds) {
if (StringUtils.isNotBlank(childJobIdItem) && StringUtils.isNumeric(childJobIdItem)) { if (StringUtils.isNotBlank(childJobIdItem) && StringUtils.isNumeric(childJobIdItem)) {
XxlJobInfo childJobInfo = xxlJobInfoDao.loadById(Integer.valueOf(childJobIdItem)); XxlJobInfo childJobInfo = xxlJobInfoDao.loadById(Integer.valueOf(childJobIdItem));
if (childJobInfo==null) { if (childJobInfo==null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, return new ReturnT<String>(ReturnT.FAIL_CODE,
MessageFormat.format((I18nUtil.getString("jobinfo_field_childJobId")+"({0})"+I18nUtil.getString("system_not_found")), childJobIdItem)); MessageFormat.format((I18nUtil.getString("jobinfo_field_childJobId")+"({0})"+I18nUtil.getString("system_not_found")), childJobIdItem));
} }
// avoid cycle relate // avoid cycle relate
if (childJobInfo.getId() == jobInfo.getId()) { if (childJobInfo.getId() == jobInfo.getId()) {
return new ReturnT<String>(ReturnT.FAIL_CODE, MessageFormat.format(I18nUtil.getString("jobinfo_field_childJobId_limit"), childJobIdItem)); return new ReturnT<String>(ReturnT.FAIL_CODE, MessageFormat.format(I18nUtil.getString("jobinfo_field_childJobId_limit"), childJobIdItem));
} }
} else { } else {
return new ReturnT<String>(ReturnT.FAIL_CODE, return new ReturnT<String>(ReturnT.FAIL_CODE,
MessageFormat.format((I18nUtil.getString("jobinfo_field_childJobId")+"({0})"+I18nUtil.getString("system_unvalid")), childJobIdItem)); MessageFormat.format((I18nUtil.getString("jobinfo_field_childJobId")+"({0})"+I18nUtil.getString("system_unvalid")), childJobIdItem));
} }
} }
jobInfo.setChildJobId(StringUtils.join(childJobIds, ",")); jobInfo.setChildJobId(StringUtils.join(childJobIds, ","));
} }
// stage job info // stage job info
XxlJobInfo exists_jobInfo = xxlJobInfoDao.loadById(jobInfo.getId()); XxlJobInfo exists_jobInfo = xxlJobInfoDao.loadById(jobInfo.getId());
if (exists_jobInfo == null) { if (exists_jobInfo == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_id")+I18nUtil.getString("system_not_found")) ); return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_id")+I18nUtil.getString("system_not_found")) );
} }
//String old_cron = exists_jobInfo.getJobCron(); //String old_cron = exists_jobInfo.getJobCron();
exists_jobInfo.setJobCron(jobInfo.getJobCron()); exists_jobInfo.setJobCron(jobInfo.getJobCron());
exists_jobInfo.setJobDesc(jobInfo.getJobDesc()); exists_jobInfo.setJobDesc(jobInfo.getJobDesc());
exists_jobInfo.setAuthor(jobInfo.getAuthor()); exists_jobInfo.setAuthor(jobInfo.getAuthor());
exists_jobInfo.setAlarmEmail(jobInfo.getAlarmEmail()); exists_jobInfo.setAlarmEmail(jobInfo.getAlarmEmail());
exists_jobInfo.setExecutorRouteStrategy(jobInfo.getExecutorRouteStrategy()); exists_jobInfo.setExecutorRouteStrategy(jobInfo.getExecutorRouteStrategy());
exists_jobInfo.setExecutorHandler(jobInfo.getExecutorHandler()); exists_jobInfo.setExecutorHandler(jobInfo.getExecutorHandler());
exists_jobInfo.setExecutorParam(jobInfo.getExecutorParam()); exists_jobInfo.setExecutorParam(jobInfo.getExecutorParam());
exists_jobInfo.setExecutorBlockStrategy(jobInfo.getExecutorBlockStrategy()); exists_jobInfo.setExecutorBlockStrategy(jobInfo.getExecutorBlockStrategy());
exists_jobInfo.setExecutorFailStrategy(jobInfo.getExecutorFailStrategy()); exists_jobInfo.setExecutorFailStrategy(jobInfo.getExecutorFailStrategy());
exists_jobInfo.setExecutorTimeout(jobInfo.getExecutorTimeout()); exists_jobInfo.setExecutorTimeout(jobInfo.getExecutorTimeout());
exists_jobInfo.setExecutorFailRetryCount(jobInfo.getExecutorFailRetryCount()); exists_jobInfo.setExecutorFailRetryCount(jobInfo.getExecutorFailRetryCount());
exists_jobInfo.setChildJobId(jobInfo.getChildJobId()); exists_jobInfo.setChildJobId(jobInfo.getChildJobId());
xxlJobInfoDao.update(exists_jobInfo); xxlJobInfoDao.update(exists_jobInfo);
// fresh quartz // fresh quartz
String qz_group = String.valueOf(exists_jobInfo.getJobGroup()); String qz_group = String.valueOf(exists_jobInfo.getJobGroup());
String qz_name = String.valueOf(exists_jobInfo.getId()); String qz_name = String.valueOf(exists_jobInfo.getId());
try { try {
boolean ret = XxlJobDynamicScheduler.rescheduleJob(qz_group, qz_name, exists_jobInfo.getJobCron()); boolean ret = XxlJobDynamicScheduler.rescheduleJob(qz_group, qz_name, exists_jobInfo.getJobCron());
return ret?ReturnT.SUCCESS:ReturnT.FAIL; return ret?ReturnT.SUCCESS:ReturnT.FAIL;
} catch (SchedulerException e) { } catch (SchedulerException e) {
logger.error(e.getMessage(), e); logger.error(e.getMessage(), e);
} }
return ReturnT.FAIL; return ReturnT.FAIL;
} }
@Override @Override
public ReturnT<String> remove(int id) { public ReturnT<String> remove(int id) {
XxlJobInfo xxlJobInfo = xxlJobInfoDao.loadById(id); XxlJobInfo xxlJobInfo = xxlJobInfoDao.loadById(id);
String group = String.valueOf(xxlJobInfo.getJobGroup()); String group = String.valueOf(xxlJobInfo.getJobGroup());
String name = String.valueOf(xxlJobInfo.getId()); String name = String.valueOf(xxlJobInfo.getId());
try { try {
XxlJobDynamicScheduler.removeJob(name, group); XxlJobDynamicScheduler.removeJob(name, group);
xxlJobInfoDao.delete(id); xxlJobInfoDao.delete(id);
xxlJobLogDao.delete(id); xxlJobLogDao.delete(id);
xxlJobLogGlueDao.deleteByJobId(id); xxlJobLogGlueDao.deleteByJobId(id);
return ReturnT.SUCCESS; return ReturnT.SUCCESS;
} catch (SchedulerException e) { } catch (SchedulerException e) {
logger.error(e.getMessage(), e); logger.error(e.getMessage(), e);
} }
return ReturnT.FAIL; return ReturnT.FAIL;
} }
@Override @Override
public ReturnT<String> pause(int id) { public ReturnT<String> pause(int id) {
XxlJobInfo xxlJobInfo = xxlJobInfoDao.loadById(id); XxlJobInfo xxlJobInfo = xxlJobInfoDao.loadById(id);
String group = String.valueOf(xxlJobInfo.getJobGroup()); String group = String.valueOf(xxlJobInfo.getJobGroup());
String name = String.valueOf(xxlJobInfo.getId()); String name = String.valueOf(xxlJobInfo.getId());
try { try {
boolean ret = XxlJobDynamicScheduler.pauseJob(name, group); // jobStatus do not store boolean ret = XxlJobDynamicScheduler.pauseJob(name, group); // jobStatus do not store
return ret?ReturnT.SUCCESS:ReturnT.FAIL; return ret?ReturnT.SUCCESS:ReturnT.FAIL;
} catch (SchedulerException e) { } catch (SchedulerException e) {
logger.error(e.getMessage(), e); logger.error(e.getMessage(), e);
return ReturnT.FAIL; return ReturnT.FAIL;
} }
} }
@Override @Override
public ReturnT<String> resume(int id) { public ReturnT<String> resume(int id) {
XxlJobInfo xxlJobInfo = xxlJobInfoDao.loadById(id); XxlJobInfo xxlJobInfo = xxlJobInfoDao.loadById(id);
String group = String.valueOf(xxlJobInfo.getJobGroup()); String group = String.valueOf(xxlJobInfo.getJobGroup());
String name = String.valueOf(xxlJobInfo.getId()); String name = String.valueOf(xxlJobInfo.getId());
try { try {
boolean ret = XxlJobDynamicScheduler.resumeJob(name, group); boolean ret = XxlJobDynamicScheduler.resumeJob(name, group);
return ret?ReturnT.SUCCESS:ReturnT.FAIL; return ret?ReturnT.SUCCESS:ReturnT.FAIL;
} catch (SchedulerException e) { } catch (SchedulerException e) {
logger.error(e.getMessage(), e); logger.error(e.getMessage(), e);
return ReturnT.FAIL; return ReturnT.FAIL;
} }
} }
@Override @Override
public ReturnT<String> triggerJob(int id) { public ReturnT<String> triggerJob(int id) {
JobTriggerPoolHelper.trigger(id); JobTriggerPoolHelper.trigger(id);
return ReturnT.SUCCESS; return ReturnT.SUCCESS;
/*XxlJobInfo xxlJobInfo = xxlJobInfoDao.loadById(id); /*XxlJobInfo xxlJobInfo = xxlJobInfoDao.loadById(id);
if (xxlJobInfo == null) { if (xxlJobInfo == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_id")+I18nUtil.getString("system_unvalid")) ); return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_id")+I18nUtil.getString("system_unvalid")) );
} }
String group = String.valueOf(xxlJobInfo.getJobGroup()); String group = String.valueOf(xxlJobInfo.getJobGroup());
String name = String.valueOf(xxlJobInfo.getId()); String name = String.valueOf(xxlJobInfo.getId());
try { try {
XxlJobDynamicScheduler.triggerJob(name, group); XxlJobDynamicScheduler.triggerJob(name, group);
return ReturnT.SUCCESS; return ReturnT.SUCCESS;
} catch (SchedulerException e) { } catch (SchedulerException e) {
logger.error(e.getMessage(), e); logger.error(e.getMessage(), e);
return new ReturnT<String>(ReturnT.FAIL_CODE, e.getMessage()); return new ReturnT<String>(ReturnT.FAIL_CODE, e.getMessage());
}*/ }*/
} }
@Override @Override
public Map<String, Object> dashboardInfo() { public Map<String, Object> dashboardInfo() {
int jobInfoCount = xxlJobInfoDao.findAllCount(); int jobInfoCount = xxlJobInfoDao.findAllCount();
int jobLogCount = xxlJobLogDao.triggerCountByHandleCode(-1); int jobLogCount = xxlJobLogDao.triggerCountByHandleCode(-1);
int jobLogSuccessCount = xxlJobLogDao.triggerCountByHandleCode(ReturnT.SUCCESS_CODE); int jobLogSuccessCount = xxlJobLogDao.triggerCountByHandleCode(ReturnT.SUCCESS_CODE);
// executor count // executor count
Set<String> executerAddressSet = new HashSet<String>(); Set<String> executerAddressSet = new HashSet<String>();
List<XxlJobGroup> groupList = xxlJobGroupDao.findAll(); List<XxlJobGroup> groupList = xxlJobGroupDao.findAll();
if (CollectionUtils.isNotEmpty(groupList)) { if (CollectionUtils.isNotEmpty(groupList)) {
for (XxlJobGroup group: groupList) { for (XxlJobGroup group: groupList) {
if (CollectionUtils.isNotEmpty(group.getRegistryList())) { if (CollectionUtils.isNotEmpty(group.getRegistryList())) {
executerAddressSet.addAll(group.getRegistryList()); executerAddressSet.addAll(group.getRegistryList());
} }
} }
} }
int executorCount = executerAddressSet.size(); int executorCount = executerAddressSet.size();
Map<String, Object> dashboardMap = new HashMap<String, Object>(); Map<String, Object> dashboardMap = new HashMap<String, Object>();
dashboardMap.put("jobInfoCount", jobInfoCount); dashboardMap.put("jobInfoCount", jobInfoCount);
dashboardMap.put("jobLogCount", jobLogCount); dashboardMap.put("jobLogCount", jobLogCount);
dashboardMap.put("jobLogSuccessCount", jobLogSuccessCount); dashboardMap.put("jobLogSuccessCount", jobLogSuccessCount);
dashboardMap.put("executorCount", executorCount); dashboardMap.put("executorCount", executorCount);
return dashboardMap; return dashboardMap;
} }
private static final String TRIGGER_CHART_DATA_CACHE = "trigger_chart_data_cache"; private static final String TRIGGER_CHART_DATA_CACHE = "trigger_chart_data_cache";
@Override @Override
public ReturnT<Map<String, Object>> chartInfo(Date startDate, Date endDate) { public ReturnT<Map<String, Object>> chartInfo(Date startDate, Date endDate) {
/*// get cache /*// get cache
String cacheKey = TRIGGER_CHART_DATA_CACHE + "_" + startDate.getTime() + "_" + endDate.getTime(); String cacheKey = TRIGGER_CHART_DATA_CACHE + "_" + startDate.getTime() + "_" + endDate.getTime();
Map<String, Object> chartInfo = (Map<String, Object>) LocalCacheUtil.get(cacheKey); Map<String, Object> chartInfo = (Map<String, Object>) LocalCacheUtil.get(cacheKey);
if (chartInfo != null) { if (chartInfo != null) {
return new ReturnT<Map<String, Object>>(chartInfo); return new ReturnT<Map<String, Object>>(chartInfo);
}*/ }*/
// process // process
List<String> triggerDayList = new ArrayList<String>(); List<String> triggerDayList = new ArrayList<String>();
List<Integer> triggerDayCountRunningList = new ArrayList<Integer>(); List<Integer> triggerDayCountRunningList = new ArrayList<Integer>();
List<Integer> triggerDayCountSucList = new ArrayList<Integer>(); List<Integer> triggerDayCountSucList = new ArrayList<Integer>();
List<Integer> triggerDayCountFailList = new ArrayList<Integer>(); List<Integer> triggerDayCountFailList = new ArrayList<Integer>();
int triggerCountRunningTotal = 0; int triggerCountRunningTotal = 0;
int triggerCountSucTotal = 0; int triggerCountSucTotal = 0;
int triggerCountFailTotal = 0; int triggerCountFailTotal = 0;
List<Map<String, Object>> triggerCountMapAll = xxlJobLogDao.triggerCountByDay(startDate, endDate); List<Map<String, Object>> triggerCountMapAll = xxlJobLogDao.triggerCountByDay(startDate, endDate);
if (CollectionUtils.isNotEmpty(triggerCountMapAll)) { if (CollectionUtils.isNotEmpty(triggerCountMapAll)) {
for (Map<String, Object> item: triggerCountMapAll) { for (Map<String, Object> item: triggerCountMapAll) {
String day = String.valueOf(item.get("triggerDay")); String day = String.valueOf(item.get("triggerDay"));
int triggerDayCount = Integer.valueOf(String.valueOf(item.get("triggerDayCount"))); int triggerDayCount = Integer.valueOf(String.valueOf(item.get("triggerDayCount")));
int triggerDayCountRunning = Integer.valueOf(String.valueOf(item.get("triggerDayCountRunning"))); int triggerDayCountRunning = Integer.valueOf(String.valueOf(item.get("triggerDayCountRunning")));
int triggerDayCountSuc = Integer.valueOf(String.valueOf(item.get("triggerDayCountSuc"))); int triggerDayCountSuc = Integer.valueOf(String.valueOf(item.get("triggerDayCountSuc")));
int triggerDayCountFail = triggerDayCount - triggerDayCountRunning - triggerDayCountSuc; int triggerDayCountFail = triggerDayCount - triggerDayCountRunning - triggerDayCountSuc;
triggerDayList.add(day); triggerDayList.add(day);
triggerDayCountRunningList.add(triggerDayCountRunning); triggerDayCountRunningList.add(triggerDayCountRunning);
triggerDayCountSucList.add(triggerDayCountSuc); triggerDayCountSucList.add(triggerDayCountSuc);
triggerDayCountFailList.add(triggerDayCountFail); triggerDayCountFailList.add(triggerDayCountFail);
triggerCountRunningTotal += triggerDayCountRunning; triggerCountRunningTotal += triggerDayCountRunning;
triggerCountSucTotal += triggerDayCountSuc; triggerCountSucTotal += triggerDayCountSuc;
triggerCountFailTotal += triggerDayCountFail; triggerCountFailTotal += triggerDayCountFail;
} }
} else { } else {
for (int i = 4; i > -1; i--) { for (int i = 4; i > -1; i--) {
triggerDayList.add(FastDateFormat.getInstance("yyyy-MM-dd").format(DateUtils.addDays(new Date(), -i))); triggerDayList.add(FastDateFormat.getInstance("yyyy-MM-dd").format(DateUtils.addDays(new Date(), -i)));
triggerDayCountSucList.add(0); triggerDayCountSucList.add(0);
triggerDayCountFailList.add(0); triggerDayCountFailList.add(0);
} }
} }
Map<String, Object> result = new HashMap<String, Object>(); Map<String, Object> result = new HashMap<String, Object>();
result.put("triggerDayList", triggerDayList); result.put("triggerDayList", triggerDayList);
result.put("triggerDayCountRunningList", triggerDayCountRunningList); result.put("triggerDayCountRunningList", triggerDayCountRunningList);
result.put("triggerDayCountSucList", triggerDayCountSucList); result.put("triggerDayCountSucList", triggerDayCountSucList);
result.put("triggerDayCountFailList", triggerDayCountFailList); result.put("triggerDayCountFailList", triggerDayCountFailList);
result.put("triggerCountRunningTotal", triggerCountRunningTotal); result.put("triggerCountRunningTotal", triggerCountRunningTotal);
result.put("triggerCountSucTotal", triggerCountSucTotal); result.put("triggerCountSucTotal", triggerCountSucTotal);
result.put("triggerCountFailTotal", triggerCountFailTotal); result.put("triggerCountFailTotal", triggerCountFailTotal);
/*// set cache /*// set cache
LocalCacheUtil.set(cacheKey, result, 60*1000); // cache 60s*/ LocalCacheUtil.set(cacheKey, result, 60*1000); // cache 60s*/
return new ReturnT<Map<String, Object>>(result); return new ReturnT<Map<String, Object>>(result);
} }
} }
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xxl.job.admin.dao.XxlJobInfoDao"> <mapper namespace="com.xxl.job.admin.dao.XxlJobInfoDao">
<resultMap id="XxlJobInfo" type="com.xxl.job.admin.core.model.XxlJobInfo" > <resultMap id="XxlJobInfo" type="com.xxl.job.admin.core.model.XxlJobInfo" >
<result column="id" property="id" /> <result column="id" property="id" />
<result column="job_group" property="jobGroup" /> <result column="job_group" property="jobGroup" />
<result column="job_cron" property="jobCron" /> <result column="job_cron" property="jobCron" />
<result column="job_desc" property="jobDesc" /> <result column="job_desc" property="jobDesc" />
<result column="add_time" property="addTime" /> <result column="add_time" property="addTime" />
<result column="update_time" property="updateTime" /> <result column="update_time" property="updateTime" />
<result column="author" property="author" /> <result column="author" property="author" />
<result column="alarm_email" property="alarmEmail" /> <result column="alarm_email" property="alarmEmail" />
<result column="executor_route_strategy" property="executorRouteStrategy" /> <result column="executor_route_strategy" property="executorRouteStrategy" />
<result column="executor_handler" property="executorHandler" /> <result column="executor_handler" property="executorHandler" />
<result column="executor_param" property="executorParam" /> <result column="executor_param" property="executorParam" />
<result column="executor_block_strategy" property="executorBlockStrategy" /> <result column="executor_block_strategy" property="executorBlockStrategy" />
<result column="executor_fail_strategy" property="executorFailStrategy" /> <result column="executor_fail_strategy" property="executorFailStrategy" />
<result column="executor_timeout" property="executorTimeout" /> <result column="executor_timeout" property="executorTimeout" />
<result column="executor_fail_retry_count" property="executorFailRetryCount" /> <result column="executor_fail_retry_count" property="executorFailRetryCount" />
<result column="glue_type" property="glueType" /> <result column="glue_type" property="glueType" />
<result column="glue_source" property="glueSource" /> <result column="glue_source" property="glueSource" />
<result column="glue_remark" property="glueRemark" /> <result column="glue_remark" property="glueRemark" />
<result column="glue_updatetime" property="glueUpdatetime" /> <result column="glue_updatetime" property="glueUpdatetime" />
<result column="child_jobid" property="childJobId" /> <result column="child_jobid" property="childJobId" />
</resultMap> </resultMap>
<sql id="Base_Column_List"> <sql id="Base_Column_List">
t.id, t.id,
t.job_group, t.job_group,
t.job_cron, t.job_cron,
t.job_desc, t.job_desc,
t.add_time, t.add_time,
t.update_time, t.update_time,
t.author, t.author,
t.alarm_email, t.alarm_email,
t.executor_route_strategy, t.executor_route_strategy,
t.executor_handler, t.executor_handler,
t.executor_param, t.executor_param,
t.executor_block_strategy, t.executor_block_strategy,
t.executor_fail_strategy, t.executor_fail_strategy,
t.executor_timeout, t.executor_timeout,
t.executor_fail_retry_count, t.executor_fail_retry_count,
t.glue_type, t.glue_type,
t.glue_source, t.glue_source,
t.glue_remark, t.glue_remark,
t.glue_updatetime, t.glue_updatetime,
t.child_jobid t.child_jobid
</sql> </sql>
<select id="pageList" parameterType="java.util.HashMap" resultMap="XxlJobInfo"> <select id="pageList" parameterType="java.util.HashMap" resultMap="XxlJobInfo">
SELECT <include refid="Base_Column_List" /> SELECT <include refid="Base_Column_List" />
FROM XXL_JOB_QRTZ_TRIGGER_INFO AS t FROM XXL_JOB_QRTZ_TRIGGER_INFO AS t
<trim prefix="WHERE" prefixOverrides="AND | OR" > <trim prefix="WHERE" prefixOverrides="AND | OR" >
<if test="jobGroup gt 0"> <if test="jobGroup gt 0">
AND t.job_group = #{jobGroup} AND t.job_group = #{jobGroup}
</if> </if>
<if test="jobDesc != null and jobDesc != ''"> <if test="jobDesc != null and jobDesc != ''">
AND t.job_desc like CONCAT(CONCAT('%', #{jobDesc}), '%') AND t.job_desc like CONCAT(CONCAT('%', #{jobDesc}), '%')
</if> </if>
<if test="executorHandler != null and executorHandler != ''"> <if test="executorHandler != null and executorHandler != ''">
AND t.executor_handler like CONCAT(CONCAT('%', #{executorHandler}), '%') AND t.executor_handler like CONCAT(CONCAT('%', #{executorHandler}), '%')
</if> </if>
</trim> </trim>
ORDER BY id DESC ORDER BY id DESC
LIMIT #{offset}, #{pagesize} LIMIT #{offset}, #{pagesize}
</select> </select>
<select id="pageListCount" parameterType="java.util.HashMap" resultType="int"> <select id="pageListCount" parameterType="java.util.HashMap" resultType="int">
SELECT count(1) SELECT count(1)
FROM XXL_JOB_QRTZ_TRIGGER_INFO AS t FROM XXL_JOB_QRTZ_TRIGGER_INFO AS t
<trim prefix="WHERE" prefixOverrides="AND | OR" > <trim prefix="WHERE" prefixOverrides="AND | OR" >
<if test="jobGroup gt 0"> <if test="jobGroup gt 0">
AND t.job_group = #{jobGroup} AND t.job_group = #{jobGroup}
</if> </if>
<if test="jobDesc != null and jobDesc != ''"> <if test="jobDesc != null and jobDesc != ''">
AND t.job_desc like CONCAT(CONCAT('%', #{jobDesc}), '%') AND t.job_desc like CONCAT(CONCAT('%', #{jobDesc}), '%')
</if> </if>
<if test="executorHandler != null and executorHandler != ''"> <if test="executorHandler != null and executorHandler != ''">
AND t.executor_handler like CONCAT(CONCAT('%', #{executorHandler}), '%') AND t.executor_handler like CONCAT(CONCAT('%', #{executorHandler}), '%')
</if> </if>
</trim> </trim>
</select> </select>
<insert id="save" parameterType="com.xxl.job.admin.core.model.XxlJobInfo" useGeneratedKeys="true" keyProperty="id" > <insert id="save" parameterType="com.xxl.job.admin.core.model.XxlJobInfo" useGeneratedKeys="true" keyProperty="id" >
INSERT INTO XXL_JOB_QRTZ_TRIGGER_INFO ( INSERT INTO XXL_JOB_QRTZ_TRIGGER_INFO (
job_group, job_group,
job_cron, job_cron,
job_desc, job_desc,
add_time, add_time,
update_time, update_time,
author, author,
alarm_email, alarm_email,
executor_route_strategy, executor_route_strategy,
executor_handler, executor_handler,
executor_param, executor_param,
executor_block_strategy, executor_block_strategy,
executor_fail_strategy, executor_fail_strategy,
executor_timeout, executor_timeout,
executor_fail_retry_count, executor_fail_retry_count,
glue_type, glue_type,
glue_source, glue_source,
glue_remark, glue_remark,
glue_updatetime, glue_updatetime,
child_jobid child_jobid
) VALUES ( ) VALUES (
#{jobGroup}, #{jobGroup},
#{jobCron}, #{jobCron},
#{jobDesc}, #{jobDesc},
NOW(), NOW(),
NOW(), NOW(),
#{author}, #{author},
#{alarmEmail}, #{alarmEmail},
#{executorRouteStrategy}, #{executorRouteStrategy},
#{executorHandler}, #{executorHandler},
#{executorParam}, #{executorParam},
#{executorBlockStrategy}, #{executorBlockStrategy},
#{executorFailStrategy}, #{executorFailStrategy},
#{executorTimeout}, #{executorTimeout},
#{executorFailRetryCount}, #{executorFailRetryCount},
#{glueType}, #{glueType},
#{glueSource}, #{glueSource},
#{glueRemark}, #{glueRemark},
NOW(), NOW(),
#{childJobId} #{childJobId}
); );
<!--<selectKey resultType="java.lang.Integer" order="AFTER" keyProperty="id"> <!--<selectKey resultType="java.lang.Integer" order="AFTER" keyProperty="id">
SELECT LAST_INSERT_ID() SELECT LAST_INSERT_ID()
/*SELECT @@IDENTITY AS id*/ /*SELECT @@IDENTITY AS id*/
</selectKey>--> </selectKey>-->
</insert> </insert>
<select id="loadById" parameterType="java.util.HashMap" resultMap="XxlJobInfo"> <select id="loadById" parameterType="java.util.HashMap" resultMap="XxlJobInfo">
SELECT <include refid="Base_Column_List" /> SELECT <include refid="Base_Column_List" />
FROM XXL_JOB_QRTZ_TRIGGER_INFO AS t FROM XXL_JOB_QRTZ_TRIGGER_INFO AS t
WHERE t.id = #{id} WHERE t.id = #{id}
</select> </select>
<update id="update" parameterType="com.xxl.job.admin.core.model.XxlJobInfo" > <update id="update" parameterType="com.xxl.job.admin.core.model.XxlJobInfo" >
UPDATE XXL_JOB_QRTZ_TRIGGER_INFO UPDATE XXL_JOB_QRTZ_TRIGGER_INFO
SET SET
job_cron = #{jobCron}, job_cron = #{jobCron},
job_desc = #{jobDesc}, job_desc = #{jobDesc},
update_time = NOW(), update_time = NOW(),
author = #{author}, author = #{author},
alarm_email = #{alarmEmail}, alarm_email = #{alarmEmail},
executor_route_strategy = #{executorRouteStrategy}, executor_route_strategy = #{executorRouteStrategy},
executor_handler = #{executorHandler}, executor_handler = #{executorHandler},
executor_param = #{executorParam}, executor_param = #{executorParam},
executor_block_strategy = #{executorBlockStrategy}, executor_block_strategy = #{executorBlockStrategy},
executor_fail_strategy = #{executorFailStrategy}, executor_fail_strategy = #{executorFailStrategy},
executor_timeout = ${executorTimeout}, executor_timeout = ${executorTimeout},
executor_fail_retry_count = ${executorFailRetryCount}, executor_fail_retry_count = ${executorFailRetryCount},
glue_type = #{glueType}, glue_type = #{glueType},
glue_source = #{glueSource}, glue_source = #{glueSource},
glue_remark = #{glueRemark}, glue_remark = #{glueRemark},
glue_updatetime = #{glueUpdatetime}, glue_updatetime = #{glueUpdatetime},
child_jobid = #{childJobId} child_jobid = #{childJobId}
WHERE id = #{id} WHERE id = #{id}
</update> </update>
<delete id="delete" parameterType="java.util.HashMap"> <delete id="delete" parameterType="java.util.HashMap">
DELETE DELETE
FROM XXL_JOB_QRTZ_TRIGGER_INFO FROM XXL_JOB_QRTZ_TRIGGER_INFO
WHERE id = #{id} WHERE id = #{id}
</delete> </delete>
<select id="getJobsByGroup" parameterType="java.util.HashMap" resultMap="XxlJobInfo"> <select id="getJobsByGroup" parameterType="java.util.HashMap" resultMap="XxlJobInfo">
SELECT <include refid="Base_Column_List" /> SELECT <include refid="Base_Column_List" />
FROM XXL_JOB_QRTZ_TRIGGER_INFO AS t FROM XXL_JOB_QRTZ_TRIGGER_INFO AS t
WHERE t.job_group = #{jobGroup} WHERE t.job_group = #{jobGroup}
</select> </select>
<select id="findAllCount" resultType="int"> <select id="findAllCount" resultType="int">
SELECT count(1) SELECT count(1)
FROM XXL_JOB_QRTZ_TRIGGER_INFO FROM XXL_JOB_QRTZ_TRIGGER_INFO
</select> </select>
</mapper> </mapper>
\ No newline at end of file
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<#import "/common/common.macro.ftl" as netCommon> <#import "/common/common.macro.ftl" as netCommon>
<@netCommon.commonStyle /> <@netCommon.commonStyle />
<!-- DataTables --> <!-- DataTables -->
<link rel="stylesheet" href="${request.contextPath}/static/adminlte/plugins/datatables/dataTables.bootstrap.css"> <link rel="stylesheet" href="${request.contextPath}/static/adminlte/plugins/datatables/dataTables.bootstrap.css">
<title>${I18n.admin_name}</title> <title>${I18n.admin_name}</title>
</head> </head>
<body class="hold-transition skin-blue sidebar-mini <#if cookieMap?exists && "off" == cookieMap["xxljob_adminlte_settings"].value >sidebar-collapse</#if>"> <body class="hold-transition skin-blue sidebar-mini <#if cookieMap?exists && "off" == cookieMap["xxljob_adminlte_settings"].value >sidebar-collapse</#if>">
<div class="wrapper"> <div class="wrapper">
<!-- header --> <!-- header -->
<@netCommon.commonHeader /> <@netCommon.commonHeader />
<!-- left --> <!-- left -->
<@netCommon.commonLeft "jobinfo" /> <@netCommon.commonLeft "jobinfo" />
<!-- Content Wrapper. Contains page content --> <!-- Content Wrapper. Contains page content -->
<div class="content-wrapper"> <div class="content-wrapper">
<!-- Content Header (Page header) --> <!-- Content Header (Page header) -->
<section class="content-header"> <section class="content-header">
<h1>${I18n.jobinfo_name}</h1> <h1>${I18n.jobinfo_name}</h1>
</section> </section>
<!-- Main content --> <!-- Main content -->
<section class="content"> <section class="content">
<div class="row"> <div class="row">
<div class="col-xs-3"> <div class="col-xs-3">
<div class="input-group"> <div class="input-group">
<span class="input-group-addon">${I18n.jobinfo_field_jobgroup}</span> <span class="input-group-addon">${I18n.jobinfo_field_jobgroup}</span>
<select class="form-control" id="jobGroup" > <select class="form-control" id="jobGroup" >
<#list JobGroupList as group> <#list JobGroupList as group>
<option value="${group.id}" <#if jobGroup==group.id>selected</#if> >${group.title}</option> <option value="${group.id}" <#if jobGroup==group.id>selected</#if> >${group.title}</option>
</#list> </#list>
</select> </select>
</div> </div>
</div> </div>
<div class="col-xs-3"> <div class="col-xs-3">
<div class="input-group"> <div class="input-group">
<span class="input-group-addon">${I18n.jobinfo_field_jobdesc}</span> <span class="input-group-addon">${I18n.jobinfo_field_jobdesc}</span>
<input type="text" class="form-control" id="jobDesc" autocomplete="on" > <input type="text" class="form-control" id="jobDesc" autocomplete="on" >
</div> </div>
</div> </div>
<div class="col-xs-3"> <div class="col-xs-3">
<div class="input-group"> <div class="input-group">
<span class="input-group-addon">JobHandler</span> <span class="input-group-addon">JobHandler</span>
<input type="text" class="form-control" id="executorHandler" autocomplete="on" > <input type="text" class="form-control" id="executorHandler" autocomplete="on" >
</div> </div>
</div> </div>
<div class="col-xs-1"> <div class="col-xs-1">
<button class="btn btn-block btn-info" id="searchBtn">${I18n.system_search}</button> <button class="btn btn-block btn-info" id="searchBtn">${I18n.system_search}</button>
</div> </div>
<div class="col-xs-2"> <div class="col-xs-2">
<button class="btn btn-block btn-success add" type="button">${I18n.jobinfo_field_add}</button> <button class="btn btn-block btn-success add" type="button">${I18n.jobinfo_field_add}</button>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-xs-12"> <div class="col-xs-12">
<div class="box"> <div class="box">
<#--<div class="box-header hide"> <#--<div class="box-header hide">
<h3 class="box-title">调度列表</h3> <h3 class="box-title">调度列表</h3>
</div>--> </div>-->
<div class="box-body" > <div class="box-body" >
<table id="job_list" class="table table-bordered table-striped" width="100%" > <table id="job_list" class="table table-bordered table-striped" width="100%" >
<thead> <thead>
<tr> <tr>
<th name="id" >${I18n.jobinfo_field_id}</th> <th name="id" >${I18n.jobinfo_field_id}</th>
<th name="jobGroup" >${I18n.jobinfo_field_jobgroup}</th> <th name="jobGroup" >${I18n.jobinfo_field_jobgroup}</th>
<th name="jobDesc" >${I18n.jobinfo_field_jobdesc}</th> <th name="jobDesc" >${I18n.jobinfo_field_jobdesc}</th>
<th name="glueType" >${I18n.jobinfo_field_gluetype}</th> <th name="glueType" >${I18n.jobinfo_field_gluetype}</th>
<th name="executorParam" >${I18n.jobinfo_field_executorparam}</th> <th name="executorParam" >${I18n.jobinfo_field_executorparam}</th>
<th name="jobCron" >Cron</th> <th name="jobCron" >Cron</th>
<th name="addTime" >addTime</th> <th name="addTime" >addTime</th>
<th name="updateTime" >updateTime</th> <th name="updateTime" >updateTime</th>
<th name="author" >${I18n.jobinfo_field_author}</th> <th name="author" >${I18n.jobinfo_field_author}</th>
<th name="alarmEmail" >${I18n.jobinfo_field_alarmemail}</th> <th name="alarmEmail" >${I18n.jobinfo_field_alarmemail}</th>
<th name="jobStatus" >${I18n.system_status}</th> <th name="jobStatus" >${I18n.system_status}</th>
<th>${I18n.system_opt}</th> <th>${I18n.system_opt}</th>
</tr> </tr>
</thead> </thead>
<tbody></tbody> <tbody></tbody>
<tfoot></tfoot> <tfoot></tfoot>
</table> </table>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</section> </section>
</div> </div>
<!-- footer --> <!-- footer -->
<@netCommon.commonFooter /> <@netCommon.commonFooter />
</div> </div>
<!-- job新增.模态框 --> <!-- job新增.模态框 -->
<div class="modal fade" id="addModal" tabindex="-1" role="dialog" aria-hidden="true"> <div class="modal fade" id="addModal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-lg"> <div class="modal-dialog modal-lg">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<h4 class="modal-title" >${I18n.jobinfo_field_add}</h4> <h4 class="modal-title" >${I18n.jobinfo_field_add}</h4>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<form class="form-horizontal form" role="form" > <form class="form-horizontal form" role="form" >
<div class="form-group"> <div class="form-group">
<label for="firstname" class="col-sm-2 control-label">${I18n.jobinfo_field_jobgroup}<font color="red">*</font></label> <label for="firstname" class="col-sm-2 control-label">${I18n.jobinfo_field_jobgroup}<font color="red">*</font></label>
<div class="col-sm-4"> <div class="col-sm-4">
<select class="form-control" name="jobGroup" > <select class="form-control" name="jobGroup" >
<#list JobGroupList as group> <#list JobGroupList as group>
<option value="${group.id}" <#if jobGroup==group.id>selected</#if> >${group.title}</option> <option value="${group.id}" <#if jobGroup==group.id>selected</#if> >${group.title}</option>
</#list> </#list>
</select> </select>
</div> </div>
<label for="lastname" class="col-sm-2 control-label">${I18n.jobinfo_field_jobdesc}<font color="red">*</font></label> <label for="lastname" class="col-sm-2 control-label">${I18n.jobinfo_field_jobdesc}<font color="red">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="jobDesc" placeholder="${I18n.system_please_input}${I18n.jobinfo_field_jobdesc}" maxlength="50" ></div> <div class="col-sm-4"><input type="text" class="form-control" name="jobDesc" placeholder="${I18n.system_please_input}${I18n.jobinfo_field_jobdesc}" maxlength="50" ></div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="firstname" class="col-sm-2 control-label">${I18n.jobinfo_field_executorRouteStrategy}<font color="red">*</font></label> <label for="firstname" class="col-sm-2 control-label">${I18n.jobinfo_field_executorRouteStrategy}<font color="red">*</font></label>
<div class="col-sm-4"> <div class="col-sm-4">
<select class="form-control" name="executorRouteStrategy" > <select class="form-control" name="executorRouteStrategy" >
<#list ExecutorRouteStrategyEnum as item> <#list ExecutorRouteStrategyEnum as item>
<option value="${item}" >${item.title}</option> <option value="${item}" >${item.title}</option>
</#list> </#list>
</select> </select>
</div> </div>
<label for="lastname" class="col-sm-2 control-label">Cron<font color="red">*</font></label> <label for="lastname" class="col-sm-2 control-label">Cron<font color="red">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="jobCron" placeholder="${I18n.system_please_input}Cron" maxlength="128" ></div> <div class="col-sm-4"><input type="text" class="form-control" name="jobCron" placeholder="${I18n.system_please_input}Cron" maxlength="128" ></div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="firstname" class="col-sm-2 control-label">${I18n.jobinfo_field_gluetype}<font color="red">*</font></label> <label for="firstname" class="col-sm-2 control-label">${I18n.jobinfo_field_gluetype}<font color="red">*</font></label>
<div class="col-sm-4"> <div class="col-sm-4">
<select class="form-control glueType" name="glueType" > <select class="form-control glueType" name="glueType" >
<#list GlueTypeEnum as item> <#list GlueTypeEnum as item>
<option value="${item}" >${item.desc}</option> <option value="${item}" >${item.desc}</option>
</#list> </#list>
</select> </select>
</div> </div>
<label for="firstname" class="col-sm-2 control-label">JobHandler<font color="red">*</font></label> <label for="firstname" class="col-sm-2 control-label">JobHandler<font color="red">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="executorHandler" placeholder="${I18n.system_please_input}JobHandler" maxlength="100" ></div> <div class="col-sm-4"><input type="text" class="form-control" name="executorHandler" placeholder="${I18n.system_please_input}JobHandler" maxlength="100" ></div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="firstname" class="col-sm-2 control-label">${I18n.jobinfo_field_executorparam}<font color="black">*</font></label> <label for="firstname" class="col-sm-2 control-label">${I18n.jobinfo_field_executorparam}<font color="black">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="executorParam" placeholder="${I18n.system_please_input}${I18n.jobinfo_field_executorparam}" maxlength="512" ></div> <div class="col-sm-4"><input type="text" class="form-control" name="executorParam" placeholder="${I18n.system_please_input}${I18n.jobinfo_field_executorparam}" maxlength="512" ></div>
<label for="lastname" class="col-sm-2 control-label">${I18n.jobinfo_field_childJobId}<font color="black">*</font></label> <label for="lastname" class="col-sm-2 control-label">${I18n.jobinfo_field_childJobId}<font color="black">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="childJobId" placeholder="${I18n.jobinfo_field_childJobId_placeholder}" maxlength="100" ></div> <div class="col-sm-4"><input type="text" class="form-control" name="childJobId" placeholder="${I18n.jobinfo_field_childJobId_placeholder}" maxlength="100" ></div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="lastname" class="col-sm-2 control-label">${I18n.jobinfo_field_timeout}<font color="black">*</font></label> <label for="lastname" class="col-sm-2 control-label">${I18n.jobinfo_field_timeout}<font color="black">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="executorTimeout" placeholder="${I18n.jobinfo_field_executorTimeout_placeholder}" maxlength="6" ></div> <div class="col-sm-4"><input type="text" class="form-control" name="executorTimeout" placeholder="${I18n.jobinfo_field_executorTimeout_placeholder}" maxlength="6" ></div>
<label for="firstname" class="col-sm-2 control-label">${I18n.jobinfo_field_executorBlockStrategy}<font color="red">*</font></label> <label for="firstname" class="col-sm-2 control-label">${I18n.jobinfo_field_executorBlockStrategy}<font color="red">*</font></label>
<div class="col-sm-4"> <div class="col-sm-4">
<select class="form-control" name="executorBlockStrategy" > <select class="form-control" name="executorBlockStrategy" >
<#list ExecutorBlockStrategyEnum as item> <#list ExecutorBlockStrategyEnum as item>
<option value="${item}" >${item.title}</option> <option value="${item}" >${item.title}</option>
</#list> </#list>
</select> </select>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="lastname" class="col-sm-2 control-label">${I18n.jobinfo_field_executorFailRetryCount}<font color="black">*</font></label> <label for="lastname" class="col-sm-2 control-label">${I18n.jobinfo_field_executorFailRetryCount}<font color="black">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="executorFailRetryCount" placeholder="${I18n.jobinfo_field_executorFailRetryCount_placeholder}" maxlength="4" ></div> <div class="col-sm-4"><input type="text" class="form-control" name="executorFailRetryCount" placeholder="${I18n.jobinfo_field_executorFailRetryCount_placeholder}" maxlength="4" ></div>
<label for="lastname" class="col-sm-2 control-label">${I18n.jobinfo_field_alarmemail}<font color="black">*</font></label> <label for="lastname" class="col-sm-2 control-label">${I18n.jobinfo_field_alarmemail}<font color="black">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="alarmEmail" placeholder="${I18n.jobinfo_field_alarmemail_placeholder}" maxlength="100" ></div> <div class="col-sm-4"><input type="text" class="form-control" name="alarmEmail" placeholder="${I18n.jobinfo_field_alarmemail_placeholder}" maxlength="100" ></div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="lastname" class="col-sm-2 control-label">${I18n.jobinfo_field_author}<font color="red">*</font></label> <label for="lastname" class="col-sm-2 control-label">${I18n.jobinfo_field_author}<font color="red">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="author" placeholder="${I18n.system_please_input}${I18n.jobinfo_field_author}" maxlength="50" ></div> <div class="col-sm-4"><input type="text" class="form-control" name="author" placeholder="${I18n.system_please_input}${I18n.jobinfo_field_author}" maxlength="50" ></div>
</div> </div>
<hr> <hr>
<div class="form-group"> <div class="form-group">
<div class="col-sm-offset-3 col-sm-6"> <div class="col-sm-offset-3 col-sm-6">
<button type="submit" class="btn btn-primary" >${I18n.system_save}</button> <button type="submit" class="btn btn-primary" >${I18n.system_save}</button>
<button type="button" class="btn btn-default" data-dismiss="modal">${I18n.system_cancel}</button> <button type="button" class="btn btn-default" data-dismiss="modal">${I18n.system_cancel}</button>
</div> </div>
</div> </div>
<input type="hidden" name="glueRemark" value="GLUE代码初始化" > <input type="hidden" name="glueRemark" value="GLUE代码初始化" >
<textarea name="glueSource" style="display:none;" ></textarea> <textarea name="glueSource" style="display:none;" ></textarea>
<textarea class="glueSource_java" style="display:none;" > <textarea class="glueSource_java" style="display:none;" >
package com.xxl.job.service.handler; package com.xxl.job.service.handler;
import com.xxl.job.core.log.XxlJobLogger; import com.xxl.job.core.log.XxlJobLogger;
import com.xxl.job.core.biz.model.ReturnT; import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.IJobHandler; import com.xxl.job.core.handler.IJobHandler;
public class DemoGlueJobHandler extends IJobHandler { public class DemoGlueJobHandler extends IJobHandler {
@Override @Override
public ReturnT<String> execute(String param) throws Exception { public ReturnT<String> execute(String param) throws Exception {
XxlJobLogger.log("XXL-JOB, Hello World."); XxlJobLogger.log("XXL-JOB, Hello World.");
return ReturnT.SUCCESS; return ReturnT.SUCCESS;
} }
} }
</textarea> </textarea>
<textarea class="glueSource_shell" style="display:none;" > <textarea class="glueSource_shell" style="display:none;" >
#!/bin/bash #!/bin/bash
echo "xxl-job: hello shell" echo "xxl-job: hello shell"
echo "${I18n.jobinfo_script_location}:$0" echo "${I18n.jobinfo_script_location}:$0"
echo "${I18n.jobinfo_field_executorparam}:$1" echo "${I18n.jobinfo_field_executorparam}:$1"
echo "${I18n.jobinfo_shard_index} = $2" echo "${I18n.jobinfo_shard_index} = $2"
echo "${I18n.jobinfo_shard_total} = $3" echo "${I18n.jobinfo_shard_total} = $3"
<#--echo "参数数量:$#" <#--echo "参数数量:$#"
for param in $* for param in $*
do do
echo "参数 : $param" echo "参数 : $param"
sleep 1s sleep 1s
done--> done-->
echo "Good bye!" echo "Good bye!"
exit 0 exit 0
</textarea> </textarea>
<textarea class="glueSource_python" style="display:none;" > <textarea class="glueSource_python" style="display:none;" >
#!/usr/bin/python #!/usr/bin/python
# -*- coding: UTF-8 -*- # -*- coding: UTF-8 -*-
import time import time
import sys import sys
print "xxl-job: hello python" print "xxl-job: hello python"
print "${I18n.jobinfo_script_location}:", sys.argv[0] print "${I18n.jobinfo_script_location}:", sys.argv[0]
print "${I18n.jobinfo_field_executorparam}:", sys.argv[1] print "${I18n.jobinfo_field_executorparam}:", sys.argv[1]
print "${I18n.jobinfo_shard_index}:", sys.argv[2] print "${I18n.jobinfo_shard_index}:", sys.argv[2]
print "${I18n.jobinfo_shard_total}:", sys.argv[3] print "${I18n.jobinfo_shard_total}:", sys.argv[3]
<#--for i in range(1, len(sys.argv)): <#--for i in range(1, len(sys.argv)):
time.sleep(1) time.sleep(1)
print "参数", i, sys.argv[i]--> print "参数", i, sys.argv[i]-->
print "Good bye!" print "Good bye!"
exit(0) exit(0)
<#-- <#--
import logging import logging
logging.basicConfig(level=logging.DEBUG) logging.basicConfig(level=logging.DEBUG)
logging.info("脚本文件:" + sys.argv[0]) logging.info("脚本文件:" + sys.argv[0])
--> -->
</textarea> </textarea>
<#--这里有问题,新建一个运行模式为 php 的任务后,GLUE 中没有下边的 php 代码--> <#--这里有问题,新建一个运行模式为 php 的任务后,GLUE 中没有下边的 php 代码-->
<textarea class="glueSource_php" style="display:none;" > <textarea class="glueSource_php" style="display:none;" >
<?php <?php
echo "xxl-job: hello php \n"; echo "xxl-job: hello php \n";
echo "${I18n.jobinfo_script_location}:$argv[0] \n"; echo "${I18n.jobinfo_script_location}:$argv[0] \n";
echo "${I18n.jobinfo_field_executorparam}:$argv[1] \n"; echo "${I18n.jobinfo_field_executorparam}:$argv[1] \n";
echo "${I18n.jobinfo_shard_index} = $argv[2] \n"; echo "${I18n.jobinfo_shard_index} = $argv[2] \n";
echo "${I18n.jobinfo_shard_total} = $argv[3] \n"; echo "${I18n.jobinfo_shard_total} = $argv[3] \n";
echo "Good bye! \n"; echo "Good bye! \n";
exit(0); exit(0);
?> ?>
</textarea> </textarea>
<textarea class="glueSource_nodejs" style="display:none;" > <textarea class="glueSource_nodejs" style="display:none;" >
#!/usr/bin/env node #!/usr/bin/env node
console.log("xxl-job: hello nodejs") console.log("xxl-job: hello nodejs")
var arguments = process.argv var arguments = process.argv
console.log("${I18n.jobinfo_script_location}: " + arguments[1]) console.log("${I18n.jobinfo_script_location}: " + arguments[1])
console.log("${I18n.jobinfo_field_executorparam}: " + arguments[2]) console.log("${I18n.jobinfo_field_executorparam}: " + arguments[2])
console.log("${I18n.jobinfo_shard_index}: " + arguments[3]) console.log("${I18n.jobinfo_shard_index}: " + arguments[3])
console.log("${I18n.jobinfo_shard_total}: " + arguments[4]) console.log("${I18n.jobinfo_shard_total}: " + arguments[4])
<#--for (var i = 2; i < arguments.length; i++){ <#--for (var i = 2; i < arguments.length; i++){
console.log("参数 %s = %s", (i-1), arguments[i]); console.log("参数 %s = %s", (i-1), arguments[i]);
}--> }-->
console.log("Good bye!") console.log("Good bye!")
process.exit(0) process.exit(0)
</textarea> </textarea>
</form> </form>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<!-- 更新.模态框 --> <!-- 更新.模态框 -->
<div class="modal fade" id="updateModal" tabindex="-1" role="dialog" aria-hidden="true"> <div class="modal fade" id="updateModal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-lg"> <div class="modal-dialog modal-lg">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<h4 class="modal-title" >${I18n.jobinfo_field_update}</h4> <h4 class="modal-title" >${I18n.jobinfo_field_update}</h4>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<form class="form-horizontal form" role="form" > <form class="form-horizontal form" role="form" >
<div class="form-group"> <div class="form-group">
<label for="firstname" class="col-sm-2 control-label">${I18n.jobinfo_field_jobgroup}<font color="red">*</font></label> <label for="firstname" class="col-sm-2 control-label">${I18n.jobinfo_field_jobgroup}<font color="red">*</font></label>
<div class="col-sm-4"> <div class="col-sm-4">
<select class="form-control" name="jobGroup" disabled > <select class="form-control" name="jobGroup" disabled >
<#list JobGroupList as group> <#list JobGroupList as group>
<option value="${group.id}" >${group.title}</option> <option value="${group.id}" >${group.title}</option>
</#list> </#list>
</select> </select>
</div> </div>
<label for="lastname" class="col-sm-2 control-label">${I18n.jobinfo_field_jobdesc}<font color="red">*</font></label> <label for="lastname" class="col-sm-2 control-label">${I18n.jobinfo_field_jobdesc}<font color="red">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="jobDesc" placeholder="${I18n.system_please_input}${I18n.jobinfo_field_jobdesc}" maxlength="50" ></div> <div class="col-sm-4"><input type="text" class="form-control" name="jobDesc" placeholder="${I18n.system_please_input}${I18n.jobinfo_field_jobdesc}" maxlength="50" ></div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="firstname" class="col-sm-2 control-label">${I18n.jobinfo_field_executorRouteStrategy}<font color="red">*</font></label> <label for="firstname" class="col-sm-2 control-label">${I18n.jobinfo_field_executorRouteStrategy}<font color="red">*</font></label>
<div class="col-sm-4"> <div class="col-sm-4">
<select class="form-control" name="executorRouteStrategy" > <select class="form-control" name="executorRouteStrategy" >
<#list ExecutorRouteStrategyEnum as item> <#list ExecutorRouteStrategyEnum as item>
<option value="${item}" >${item.title}</option> <option value="${item}" >${item.title}</option>
</#list> </#list>
</select> </select>
</div> </div>
<label for="lastname" class="col-sm-2 control-label">Cron<font color="red">*</font></label> <label for="lastname" class="col-sm-2 control-label">Cron<font color="red">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="jobCron" placeholder="${I18n.system_please_input}Cron" maxlength="128" ></div> <div class="col-sm-4"><input type="text" class="form-control" name="jobCron" placeholder="${I18n.system_please_input}Cron" maxlength="128" ></div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="firstname" class="col-sm-2 control-label">${I18n.jobinfo_field_gluetype}<font color="red">*</font></label> <label for="firstname" class="col-sm-2 control-label">${I18n.jobinfo_field_gluetype}<font color="red">*</font></label>
<div class="col-sm-4"> <div class="col-sm-4">
<select class="form-control glueType" name="glueType" disabled > <select class="form-control glueType" name="glueType" disabled >
<#list GlueTypeEnum as item> <#list GlueTypeEnum as item>
<option value="${item}" >${item.desc}</option> <option value="${item}" >${item.desc}</option>
</#list> </#list>
</select> </select>
</div> </div>
<label for="firstname" class="col-sm-2 control-label">JobHandler<font color="red">*</font></label> <label for="firstname" class="col-sm-2 control-label">JobHandler<font color="red">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="executorHandler" placeholder="${I18n.system_please_input}JobHandler" maxlength="100" ></div> <div class="col-sm-4"><input type="text" class="form-control" name="executorHandler" placeholder="${I18n.system_please_input}JobHandler" maxlength="100" ></div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="firstname" class="col-sm-2 control-label">${I18n.jobinfo_field_executorparam}<font color="black">*</font></label> <label for="firstname" class="col-sm-2 control-label">${I18n.jobinfo_field_executorparam}<font color="black">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="executorParam" placeholder="${I18n.system_please_input}${I18n.jobinfo_field_executorparam}" maxlength="512" ></div> <div class="col-sm-4"><input type="text" class="form-control" name="executorParam" placeholder="${I18n.system_please_input}${I18n.jobinfo_field_executorparam}" maxlength="512" ></div>
<label for="lastname" class="col-sm-2 control-label">${I18n.jobinfo_field_childJobId}<font color="black">*</font></label> <label for="lastname" class="col-sm-2 control-label">${I18n.jobinfo_field_childJobId}<font color="black">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="childJobId" placeholder="${I18n.jobinfo_field_childJobId_placeholder}" maxlength="100" ></div> <div class="col-sm-4"><input type="text" class="form-control" name="childJobId" placeholder="${I18n.jobinfo_field_childJobId_placeholder}" maxlength="100" ></div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="lastname" class="col-sm-2 control-label">${I18n.jobinfo_field_timeout}<font color="black">*</font></label> <label for="lastname" class="col-sm-2 control-label">${I18n.jobinfo_field_timeout}<font color="black">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="executorTimeout" placeholder="${I18n.jobinfo_field_executorTimeout_placeholder}" maxlength="6" ></div> <div class="col-sm-4"><input type="text" class="form-control" name="executorTimeout" placeholder="${I18n.jobinfo_field_executorTimeout_placeholder}" maxlength="6" ></div>
<label for="firstname" class="col-sm-2 control-label">${I18n.jobinfo_field_executorBlockStrategy}<font color="red">*</font></label> <label for="firstname" class="col-sm-2 control-label">${I18n.jobinfo_field_executorBlockStrategy}<font color="red">*</font></label>
<div class="col-sm-4"> <div class="col-sm-4">
<select class="form-control" name="executorBlockStrategy" > <select class="form-control" name="executorBlockStrategy" >
<#list ExecutorBlockStrategyEnum as item> <#list ExecutorBlockStrategyEnum as item>
<option value="${item}" >${item.title}</option> <option value="${item}" >${item.title}</option>
</#list> </#list>
</select> </select>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="lastname" class="col-sm-2 control-label">${I18n.jobinfo_field_executorFailRetryCount}<font color="black">*</font></label> <label for="lastname" class="col-sm-2 control-label">${I18n.jobinfo_field_executorFailRetryCount}<font color="black">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="executorFailRetryCount" placeholder="${I18n.jobinfo_field_executorFailRetryCount_placeholder}" maxlength="4" ></div> <div class="col-sm-4"><input type="text" class="form-control" name="executorFailRetryCount" placeholder="${I18n.jobinfo_field_executorFailRetryCount_placeholder}" maxlength="4" ></div>
<label for="lastname" class="col-sm-2 control-label">${I18n.jobinfo_field_alarmemail}<font color="black">*</font></label> <label for="lastname" class="col-sm-2 control-label">${I18n.jobinfo_field_alarmemail}<font color="black">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="alarmEmail" placeholder="${I18n.jobinfo_field_alarmemail_placeholder}" maxlength="100" ></div> <div class="col-sm-4"><input type="text" class="form-control" name="alarmEmail" placeholder="${I18n.jobinfo_field_alarmemail_placeholder}" maxlength="100" ></div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="lastname" class="col-sm-2 control-label">${I18n.jobinfo_field_author}<font color="red">*</font></label> <label for="lastname" class="col-sm-2 control-label">${I18n.jobinfo_field_author}<font color="red">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="author" placeholder="${I18n.system_please_input}${I18n.jobinfo_field_author}" maxlength="50" ></div> <div class="col-sm-4"><input type="text" class="form-control" name="author" placeholder="${I18n.system_please_input}${I18n.jobinfo_field_author}" maxlength="50" ></div>
</div> </div>
<hr> <hr>
<div class="form-group"> <div class="form-group">
<div class="col-sm-offset-3 col-sm-6"> <div class="col-sm-offset-3 col-sm-6">
<button type="submit" class="btn btn-primary" >${I18n.system_save}</button> <button type="submit" class="btn btn-primary" >${I18n.system_save}</button>
<button type="button" class="btn btn-default" data-dismiss="modal">${I18n.system_cancel}</button> <button type="button" class="btn btn-default" data-dismiss="modal">${I18n.system_cancel}</button>
<input type="hidden" name="id" > <input type="hidden" name="id" >
</div> </div>
</div> </div>
</form> </form>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<@netCommon.commonScript /> <@netCommon.commonScript />
<!-- DataTables --> <!-- DataTables -->
<script src="${request.contextPath}/static/adminlte/plugins/datatables/jquery.dataTables.min.js"></script> <script src="${request.contextPath}/static/adminlte/plugins/datatables/jquery.dataTables.min.js"></script>
<script src="${request.contextPath}/static/adminlte/plugins/datatables/dataTables.bootstrap.min.js"></script> <script src="${request.contextPath}/static/adminlte/plugins/datatables/dataTables.bootstrap.min.js"></script>
<script src="${request.contextPath}/static/plugins/jquery/jquery.validate.min.js"></script> <script src="${request.contextPath}/static/plugins/jquery/jquery.validate.min.js"></script>
<!-- moment --> <!-- moment -->
<script src="${request.contextPath}/static/adminlte/plugins/daterangepicker/moment.min.js"></script> <script src="${request.contextPath}/static/adminlte/plugins/daterangepicker/moment.min.js"></script>
<script src="${request.contextPath}/static/js/jobinfo.index.1.js"></script> <script src="${request.contextPath}/static/js/jobinfo.index.1.js"></script>
</body> </body>
</html> </html>
$(function() { $(function() {
// init date tables // init date tables
var jobTable = $("#job_list").dataTable({ var jobTable = $("#job_list").dataTable({
"deferRender": true, "deferRender": true,
"processing" : true, "processing" : true,
"serverSide": true, "serverSide": true,
"ajax": { "ajax": {
url: base_url + "/jobinfo/pageList", url: base_url + "/jobinfo/pageList",
type:"post", type:"post",
data : function ( d ) { data : function ( d ) {
var obj = {}; var obj = {};
obj.jobGroup = $('#jobGroup').val(); obj.jobGroup = $('#jobGroup').val();
obj.jobDesc = $('#jobDesc').val(); obj.jobDesc = $('#jobDesc').val();
obj.executorHandler = $('#executorHandler').val(); obj.executorHandler = $('#executorHandler').val();
obj.start = d.start; obj.start = d.start;
obj.length = d.length; obj.length = d.length;
return obj; return obj;
} }
}, },
"searching": false, "searching": false,
"ordering": false, "ordering": false,
//"scrollX": true, // scroll x,close self-adaption //"scrollX": true, // scroll x,close self-adaption
"columns": [ "columns": [
{ {
"data": 'id', "data": 'id',
"bSortable": false, "bSortable": false,
"visible" : true, "visible" : true,
"width":'10%' "width":'10%'
}, },
{ {
"data": 'jobGroup', "data": 'jobGroup',
"visible" : false, "visible" : false,
"width":'20%', "width":'20%',
"render": function ( data, type, row ) { "render": function ( data, type, row ) {
var groupMenu = $("#jobGroup").find("option"); var groupMenu = $("#jobGroup").find("option");
for ( var index in $("#jobGroup").find("option")) { for ( var index in $("#jobGroup").find("option")) {
if ($(groupMenu[index]).attr('value') == data) { if ($(groupMenu[index]).attr('value') == data) {
return $(groupMenu[index]).html(); return $(groupMenu[index]).html();
} }
} }
return data; return data;
} }
}, },
{ {
"data": 'jobDesc', "data": 'jobDesc',
"visible" : true, "visible" : true,
"width":'20%' "width":'20%'
}, },
{ {
"data": 'glueType', "data": 'glueType',
"width":'20%', "width":'20%',
"visible" : true, "visible" : true,
"render": function ( data, type, row ) { "render": function ( data, type, row ) {
var glueTypeTitle = findGlueTypeTitle(row.glueType); var glueTypeTitle = findGlueTypeTitle(row.glueType);
if (row.executorHandler) { if (row.executorHandler) {
return glueTypeTitle +":" + row.executorHandler; return glueTypeTitle +":" + row.executorHandler;
} else { } else {
return glueTypeTitle; return glueTypeTitle;
} }
} }
}, },
{ "data": 'executorParam', "visible" : false}, { "data": 'executorParam', "visible" : false},
{ {
"data": 'jobCron', "data": 'jobCron',
"visible" : true, "visible" : true,
"width":'10%' "width":'10%'
}, },
{ {
"data": 'addTime', "data": 'addTime',
"visible" : false, "visible" : false,
"render": function ( data, type, row ) { "render": function ( data, type, row ) {
return data?moment(new Date(data)).format("YYYY-MM-DD HH:mm:ss"):""; return data?moment(new Date(data)).format("YYYY-MM-DD HH:mm:ss"):"";
} }
}, },
{ {
"data": 'updateTime', "data": 'updateTime',
"visible" : false, "visible" : false,
"render": function ( data, type, row ) { "render": function ( data, type, row ) {
return data?moment(new Date(data)).format("YYYY-MM-DD HH:mm:ss"):""; return data?moment(new Date(data)).format("YYYY-MM-DD HH:mm:ss"):"";
} }
}, },
{ "data": 'author', "visible" : true, "width":'10%'}, { "data": 'author', "visible" : true, "width":'10%'},
{ "data": 'alarmEmail', "visible" : false}, { "data": 'alarmEmail', "visible" : false},
{ {
"data": 'jobStatus', "data": 'jobStatus',
"width":'10%', "width":'10%',
"visible" : true, "visible" : true,
"render": function ( data, type, row ) { "render": function ( data, type, row ) {
if ('NORMAL' == data) { if ('NORMAL' == data) {
return '<small class="label label-success" ><i class="fa fa-clock-o"></i>'+ data +'</small>'; return '<small class="label label-success" ><i class="fa fa-clock-o"></i>'+ data +'</small>';
} else if ('PAUSED' == data){ } else if ('PAUSED' == data){
return '<small class="label label-default" ><i class="fa fa-clock-o"></i>'+ data +'</small>'; return '<small class="label label-default" ><i class="fa fa-clock-o"></i>'+ data +'</small>';
} else if ('BLOCKED' == data){ } else if ('BLOCKED' == data){
return '<small class="label label-default" ><i class="fa fa-clock-o"></i>'+ data +'</small>'; return '<small class="label label-default" ><i class="fa fa-clock-o"></i>'+ data +'</small>';
} }
return data; return data;
} }
}, },
{ {
"data": I18n.system_opt , "data": I18n.system_opt ,
"width":'15%', "width":'15%',
"render": function ( data, type, row ) { "render": function ( data, type, row ) {
return function(){ return function(){
// status // status
var pause_resume = ""; var pause_resume = "";
if ('NORMAL' == row.jobStatus) { if ('NORMAL' == row.jobStatus) {
pause_resume = '<button class="btn btn-primary btn-xs job_operate" _type="job_pause" type="button">'+ I18n.jobinfo_opt_pause +'</button> '; pause_resume = '<button class="btn btn-primary btn-xs job_operate" _type="job_pause" type="button">'+ I18n.jobinfo_opt_pause +'</button> ';
} else if ('PAUSED' == row.jobStatus){ } else if ('PAUSED' == row.jobStatus){
pause_resume = '<button class="btn btn-primary btn-xs job_operate" _type="job_resume" type="button">'+ I18n.jobinfo_opt_resume +'</button> '; pause_resume = '<button class="btn btn-primary btn-xs job_operate" _type="job_resume" type="button">'+ I18n.jobinfo_opt_resume +'</button> ';
} }
// log url // log url
var logUrl = base_url +'/joblog?jobId='+ row.id; var logUrl = base_url +'/joblog?jobId='+ row.id;
// log url // log url
var codeBtn = ""; var codeBtn = "";
if ('BEAN' != row.glueType) { if ('BEAN' != row.glueType) {
var codeUrl = base_url +'/jobcode?jobId='+ row.id; var codeUrl = base_url +'/jobcode?jobId='+ row.id;
codeBtn = '<button class="btn btn-warning btn-xs" type="button" onclick="javascript:window.open(\'' + codeUrl + '\')" >GLUE</button> ' codeBtn = '<button class="btn btn-warning btn-xs" type="button" onclick="javascript:window.open(\'' + codeUrl + '\')" >GLUE</button> '
} }
// html // html
tableData['key'+row.id] = row; tableData['key'+row.id] = row;
var html = '<p id="'+ row.id +'" >'+ var html = '<p id="'+ row.id +'" >'+
'<button class="btn btn-primary btn-xs job_operate" _type="job_trigger" type="button">'+ I18n.jobinfo_opt_run +'</button> '+ '<button class="btn btn-primary btn-xs job_operate" _type="job_trigger" type="button">'+ I18n.jobinfo_opt_run +'</button> '+
pause_resume + pause_resume +
'<button class="btn btn-primary btn-xs" type="job_del" type="button" onclick="javascript:window.open(\'' + logUrl + '\')" >'+ I18n.jobinfo_opt_log +'</button><br> '+ '<button class="btn btn-primary btn-xs" type="job_del" type="button" onclick="javascript:window.open(\'' + logUrl + '\')" >'+ I18n.jobinfo_opt_log +'</button><br> '+
'<button class="btn btn-warning btn-xs update" type="button">'+ I18n.system_opt_edit +'</button> '+ '<button class="btn btn-warning btn-xs update" type="button">'+ I18n.system_opt_edit +'</button> '+
codeBtn + codeBtn +
'<button class="btn btn-danger btn-xs job_operate" _type="job_del" type="button">'+ I18n.system_opt_del +'</button> '+ '<button class="btn btn-danger btn-xs job_operate" _type="job_del" type="button">'+ I18n.system_opt_del +'</button> '+
'</p>'; '</p>';
return html; return html;
}; };
} }
} }
], ],
"language" : { "language" : {
"sProcessing" : I18n.dataTable_sProcessing , "sProcessing" : I18n.dataTable_sProcessing ,
"sLengthMenu" : I18n.dataTable_sLengthMenu , "sLengthMenu" : I18n.dataTable_sLengthMenu ,
"sZeroRecords" : I18n.dataTable_sZeroRecords , "sZeroRecords" : I18n.dataTable_sZeroRecords ,
"sInfo" : I18n.dataTable_sInfo , "sInfo" : I18n.dataTable_sInfo ,
"sInfoEmpty" : I18n.dataTable_sInfoEmpty , "sInfoEmpty" : I18n.dataTable_sInfoEmpty ,
"sInfoFiltered" : I18n.dataTable_sInfoFiltered , "sInfoFiltered" : I18n.dataTable_sInfoFiltered ,
"sInfoPostFix" : "", "sInfoPostFix" : "",
"sSearch" : I18n.dataTable_sSearch , "sSearch" : I18n.dataTable_sSearch ,
"sUrl" : "", "sUrl" : "",
"sEmptyTable" : I18n.dataTable_sEmptyTable , "sEmptyTable" : I18n.dataTable_sEmptyTable ,
"sLoadingRecords" : I18n.dataTable_sLoadingRecords , "sLoadingRecords" : I18n.dataTable_sLoadingRecords ,
"sInfoThousands" : ",", "sInfoThousands" : ",",
"oPaginate" : { "oPaginate" : {
"sFirst" : I18n.dataTable_sFirst , "sFirst" : I18n.dataTable_sFirst ,
"sPrevious" : I18n.dataTable_sPrevious , "sPrevious" : I18n.dataTable_sPrevious ,
"sNext" : I18n.dataTable_sNext , "sNext" : I18n.dataTable_sNext ,
"sLast" : I18n.dataTable_sLast "sLast" : I18n.dataTable_sLast
}, },
"oAria" : { "oAria" : {
"sSortAscending" : I18n.dataTable_sSortAscending , "sSortAscending" : I18n.dataTable_sSortAscending ,
"sSortDescending" : I18n.dataTable_sSortDescending "sSortDescending" : I18n.dataTable_sSortDescending
} }
} }
}); });
// table data // table data
var tableData = {}; var tableData = {};
// search btn // search btn
$('#searchBtn').on('click', function(){ $('#searchBtn').on('click', function(){
jobTable.fnDraw(); jobTable.fnDraw();
}); });
// jobGroup change // jobGroup change
$('#jobGroup').on('change', function(){ $('#jobGroup').on('change', function(){
//reload //reload
var jobGroup = $('#jobGroup').val(); var jobGroup = $('#jobGroup').val();
window.location.href = base_url + "/jobinfo?jobGroup=" + jobGroup; window.location.href = base_url + "/jobinfo?jobGroup=" + jobGroup;
}); });
// job operate // job operate
$("#job_list").on('click', '.job_operate',function() { $("#job_list").on('click', '.job_operate',function() {
var typeName; var typeName;
var url; var url;
var needFresh = false; var needFresh = false;
var type = $(this).attr("_type"); var type = $(this).attr("_type");
if ("job_pause" == type) { if ("job_pause" == type) {
typeName = I18n.jobinfo_opt_pause ; typeName = I18n.jobinfo_opt_pause ;
url = base_url + "/jobinfo/pause"; url = base_url + "/jobinfo/pause";
needFresh = true; needFresh = true;
} else if ("job_resume" == type) { } else if ("job_resume" == type) {
typeName = I18n.jobinfo_opt_resume ; typeName = I18n.jobinfo_opt_resume ;
url = base_url + "/jobinfo/resume"; url = base_url + "/jobinfo/resume";
needFresh = true; needFresh = true;
} else if ("job_del" == type) { } else if ("job_del" == type) {
typeName = I18n.system_opt_del ; typeName = I18n.system_opt_del ;
url = base_url + "/jobinfo/remove"; url = base_url + "/jobinfo/remove";
needFresh = true; needFresh = true;
} else if ("job_trigger" == type) { } else if ("job_trigger" == type) {
typeName = I18n.jobinfo_opt_run ; typeName = I18n.jobinfo_opt_run ;
url = base_url + "/jobinfo/trigger"; url = base_url + "/jobinfo/trigger";
} else { } else {
return; return;
} }
var id = $(this).parent('p').attr("id"); var id = $(this).parent('p').attr("id");
layer.confirm( I18n.system_ok + typeName + '?', { layer.confirm( I18n.system_ok + typeName + '?', {
icon: 3, icon: 3,
title: I18n.system_tips , title: I18n.system_tips ,
btn: [ I18n.system_ok, I18n.system_cancel ] btn: [ I18n.system_ok, I18n.system_cancel ]
}, function(index){ }, function(index){
layer.close(index); layer.close(index);
$.ajax({ $.ajax({
type : 'POST', type : 'POST',
url : url, url : url,
data : { data : {
"id" : id "id" : id
}, },
dataType : "json", dataType : "json",
success : function(data){ success : function(data){
if (data.code == 200) { if (data.code == 200) {
layer.open({ layer.open({
title: I18n.system_tips, title: I18n.system_tips,
btn: [ I18n.system_ok ], btn: [ I18n.system_ok ],
content: typeName + I18n.system_success , content: typeName + I18n.system_success ,
icon: '1', icon: '1',
end: function(layero, index){ end: function(layero, index){
if (needFresh) { if (needFresh) {
//window.location.reload(); //window.location.reload();
jobTable.fnDraw(false); jobTable.fnDraw(false);
} }
} }
}); });
} else { } else {
layer.open({ layer.open({
title: I18n.system_tips, title: I18n.system_tips,
btn: [ I18n.system_ok ], btn: [ I18n.system_ok ],
content: (data.msg || typeName + I18n.system_fail ), content: (data.msg || typeName + I18n.system_fail ),
icon: '2' icon: '2'
}); });
} }
}, },
}); });
}); });
}); });
// add // add
$(".add").click(function(){ $(".add").click(function(){
$('#addModal').modal({backdrop: false, keyboard: false}).modal('show'); $('#addModal').modal({backdrop: false, keyboard: false}).modal('show');
}); });
var addModalValidate = $("#addModal .form").validate({ var addModalValidate = $("#addModal .form").validate({
errorElement : 'span', errorElement : 'span',
errorClass : 'help-block', errorClass : 'help-block',
focusInvalid : true, focusInvalid : true,
rules : { rules : {
jobDesc : { jobDesc : {
required : true, required : true,
maxlength: 50 maxlength: 50
}, },
jobCron : { jobCron : {
required : true required : true
}, },
author : { author : {
required : true required : true
}, },
executorTimeout : { executorTimeout : {
digits:true digits:true
}, },
executorFailRetryCount : { executorFailRetryCount : {
digits:true digits:true
} }
}, },
messages : { messages : {
jobDesc : { jobDesc : {
required : I18n.system_please_input + I18n.jobinfo_field_jobdesc required : I18n.system_please_input + I18n.jobinfo_field_jobdesc
}, },
jobCron : { jobCron : {
required : I18n.system_please_input + "Cron" required : I18n.system_please_input + "Cron"
}, },
author : { author : {
required : I18n.system_please_input + I18n.jobinfo_field_author required : I18n.system_please_input + I18n.jobinfo_field_author
}, },
executorTimeout : { executorTimeout : {
digits: I18n.system_please_input + I18n.system_digits digits: I18n.system_please_input + I18n.system_digits
}, },
executorFailRetryCount : { executorFailRetryCount : {
digits: I18n.system_please_input + I18n.system_digits digits: I18n.system_please_input + I18n.system_digits
} }
}, },
highlight : function(element) { highlight : function(element) {
$(element).closest('.form-group').addClass('has-error'); $(element).closest('.form-group').addClass('has-error');
}, },
success : function(label) { success : function(label) {
label.closest('.form-group').removeClass('has-error'); label.closest('.form-group').removeClass('has-error');
label.remove(); label.remove();
}, },
errorPlacement : function(error, element) { errorPlacement : function(error, element) {
element.parent('div').append(error); element.parent('div').append(error);
}, },
submitHandler : function(form) { submitHandler : function(form) {
// process // process
var executorTimeout = $("#addModal .form input[name='executorTimeout']").val(); var executorTimeout = $("#addModal .form input[name='executorTimeout']").val();
if(!/^\d+$/.test(executorTimeout)) { if(!/^\d+$/.test(executorTimeout)) {
executorTimeout = 0; executorTimeout = 0;
} }
$("#addModal .form input[name='executorTimeout']").val(executorTimeout); $("#addModal .form input[name='executorTimeout']").val(executorTimeout);
$.post(base_url + "/jobinfo/add", $("#addModal .form").serialize(), function(data, status) { $.post(base_url + "/jobinfo/add", $("#addModal .form").serialize(), function(data, status) {
if (data.code == "200") { if (data.code == "200") {
$('#addModal').modal('hide'); $('#addModal').modal('hide');
layer.open({ layer.open({
title: I18n.system_tips , title: I18n.system_tips ,
btn: [ I18n.system_ok ], btn: [ I18n.system_ok ],
content: I18n.system_add_suc , content: I18n.system_add_suc ,
icon: '1', icon: '1',
end: function(layero, index){ end: function(layero, index){
jobTable.fnDraw(); jobTable.fnDraw();
//window.location.reload(); //window.location.reload();
} }
}); });
} else { } else {
layer.open({ layer.open({
title: I18n.system_tips , title: I18n.system_tips ,
btn: [ I18n.system_ok ], btn: [ I18n.system_ok ],
content: (data.msg || I18n.system_add_fail), content: (data.msg || I18n.system_add_fail),
icon: '2' icon: '2'
}); });
} }
}); });
} }
}); });
$("#addModal").on('hide.bs.modal', function () { $("#addModal").on('hide.bs.modal', function () {
$("#addModal .form")[0].reset(); $("#addModal .form")[0].reset();
addModalValidate.resetForm(); addModalValidate.resetForm();
$("#addModal .form .form-group").removeClass("has-error"); $("#addModal .form .form-group").removeClass("has-error");
$(".remote_panel").show(); // remote $(".remote_panel").show(); // remote
$("#addModal .form input[name='executorHandler']").removeAttr("readonly"); $("#addModal .form input[name='executorHandler']").removeAttr("readonly");
}); });
// glueType change // glueType change
$(".glueType").change(function(){ $(".glueType").change(function(){
// executorHandler // executorHandler
var $executorHandler = $(this).parents("form").find("input[name='executorHandler']"); var $executorHandler = $(this).parents("form").find("input[name='executorHandler']");
var glueType = $(this).val(); var glueType = $(this).val();
if ('BEAN' != glueType) { if ('BEAN' != glueType) {
$executorHandler.val(""); $executorHandler.val("");
$executorHandler.attr("readonly","readonly"); $executorHandler.attr("readonly","readonly");
} else { } else {
$executorHandler.removeAttr("readonly"); $executorHandler.removeAttr("readonly");
} }
}); });
$("#addModal .glueType").change(function(){ $("#addModal .glueType").change(function(){
// glueSource // glueSource
var glueType = $(this).val(); var glueType = $(this).val();
if ('GLUE_GROOVY'==glueType){ if ('GLUE_GROOVY'==glueType){
$("#addModal .form textarea[name='glueSource']").val( $("#addModal .form .glueSource_java").val() ); $("#addModal .form textarea[name='glueSource']").val( $("#addModal .form .glueSource_java").val() );
} else if ('GLUE_SHELL'==glueType){ } else if ('GLUE_SHELL'==glueType){
$("#addModal .form textarea[name='glueSource']").val( $("#addModal .form .glueSource_shell").val() ); $("#addModal .form textarea[name='glueSource']").val( $("#addModal .form .glueSource_shell").val() );
} else if ('GLUE_PYTHON'==glueType){ } else if ('GLUE_PYTHON'==glueType){
$("#addModal .form textarea[name='glueSource']").val( $("#addModal .form .glueSource_python").val() ); $("#addModal .form textarea[name='glueSource']").val( $("#addModal .form .glueSource_python").val() );
} else if ('GLUE_PHP'==glueType){ } else if ('GLUE_PHP'==glueType){
$("#addModal .form textarea[name='glueSource']").val( $("#addModal .form .glueSource_php").val() ); $("#addModal .form textarea[name='glueSource']").val( $("#addModal .form .glueSource_php").val() );
} else if ('GLUE_NODEJS'==glueType){ } else if ('GLUE_NODEJS'==glueType){
$("#addModal .form textarea[name='glueSource']").val( $("#addModal .form .glueSource_nodejs").val() ); $("#addModal .form textarea[name='glueSource']").val( $("#addModal .form .glueSource_nodejs").val() );
} }
}); });
// update // update
$("#job_list").on('click', '.update',function() { $("#job_list").on('click', '.update',function() {
var id = $(this).parent('p').attr("id"); var id = $(this).parent('p').attr("id");
var row = tableData['key'+id]; var row = tableData['key'+id];
// base data // base data
$("#updateModal .form input[name='id']").val( row.id ); $("#updateModal .form input[name='id']").val( row.id );
$('#updateModal .form select[name=jobGroup] option[value='+ row.jobGroup +']').prop('selected', true); $('#updateModal .form select[name=jobGroup] option[value='+ row.jobGroup +']').prop('selected', true);
$("#updateModal .form input[name='jobDesc']").val( row.jobDesc ); $("#updateModal .form input[name='jobDesc']").val( row.jobDesc );
$("#updateModal .form input[name='jobCron']").val( row.jobCron ); $("#updateModal .form input[name='jobCron']").val( row.jobCron );
$("#updateModal .form input[name='author']").val( row.author ); $("#updateModal .form input[name='author']").val( row.author );
$("#updateModal .form input[name='alarmEmail']").val( row.alarmEmail ); $("#updateModal .form input[name='alarmEmail']").val( row.alarmEmail );
$("#updateModal .form input[name='executorTimeout']").val( row.executorTimeout ); $("#updateModal .form input[name='executorTimeout']").val( row.executorTimeout );
$("#updateModal .form input[name='executorFailRetryCount']").val( row.executorFailRetryCount ); $("#updateModal .form input[name='executorFailRetryCount']").val( row.executorFailRetryCount );
$('#updateModal .form select[name=executorRouteStrategy] option[value='+ row.executorRouteStrategy +']').prop('selected', true); $('#updateModal .form select[name=executorRouteStrategy] option[value='+ row.executorRouteStrategy +']').prop('selected', true);
$("#updateModal .form input[name='executorHandler']").val( row.executorHandler ); $("#updateModal .form input[name='executorHandler']").val( row.executorHandler );
$("#updateModal .form input[name='executorParam']").val( row.executorParam ); $("#updateModal .form input[name='executorParam']").val( row.executorParam );
$("#updateModal .form input[name='childJobId']").val( row.childJobId ); $("#updateModal .form input[name='childJobId']").val( row.childJobId );
$('#updateModal .form select[name=executorBlockStrategy] option[value='+ row.executorBlockStrategy +']').prop('selected', true); $('#updateModal .form select[name=executorBlockStrategy] option[value='+ row.executorBlockStrategy +']').prop('selected', true);
$('#updateModal .form select[name=glueType] option[value='+ row.glueType +']').prop('selected', true); $('#updateModal .form select[name=glueType] option[value='+ row.glueType +']').prop('selected', true);
$("#updateModal .form select[name=glueType]").change(); $("#updateModal .form select[name=glueType]").change();
// show // show
$('#updateModal').modal({backdrop: false, keyboard: false}).modal('show'); $('#updateModal').modal({backdrop: false, keyboard: false}).modal('show');
}); });
var updateModalValidate = $("#updateModal .form").validate({ var updateModalValidate = $("#updateModal .form").validate({
errorElement : 'span', errorElement : 'span',
errorClass : 'help-block', errorClass : 'help-block',
focusInvalid : true, focusInvalid : true,
rules : { rules : {
jobDesc : { jobDesc : {
required : true, required : true,
maxlength: 50 maxlength: 50
}, },
jobCron : { jobCron : {
required : true required : true
}, },
author : { author : {
required : true required : true
}, },
executorTimeout : { executorTimeout : {
digits:true digits:true
}, },
executorFailRetryCount : { executorFailRetryCount : {
digits:true digits:true
} }
}, },
messages : { messages : {
jobDesc : { jobDesc : {
required : I18n.system_please_input + I18n.jobinfo_field_jobdesc required : I18n.system_please_input + I18n.jobinfo_field_jobdesc
}, },
jobCron : { jobCron : {
required : I18n.system_please_input + "Cron" required : I18n.system_please_input + "Cron"
}, },
author : { author : {
required : I18n.system_please_input + I18n.jobinfo_field_author required : I18n.system_please_input + I18n.jobinfo_field_author
}, },
executorTimeout : { executorTimeout : {
digits: I18n.system_please_input + I18n.system_digits digits: I18n.system_please_input + I18n.system_digits
}, },
executorFailRetryCount : { executorFailRetryCount : {
digits: I18n.system_please_input + I18n.system_digits digits: I18n.system_please_input + I18n.system_digits
} }
}, },
highlight : function(element) { highlight : function(element) {
$(element).closest('.form-group').addClass('has-error'); $(element).closest('.form-group').addClass('has-error');
}, },
success : function(label) { success : function(label) {
label.closest('.form-group').removeClass('has-error'); label.closest('.form-group').removeClass('has-error');
label.remove(); label.remove();
}, },
errorPlacement : function(error, element) { errorPlacement : function(error, element) {
element.parent('div').append(error); element.parent('div').append(error);
}, },
submitHandler : function(form) { submitHandler : function(form) {
// process // process
var executorTimeout = $("#updateModal .form input[name='executorTimeout']").val(); var executorTimeout = $("#updateModal .form input[name='executorTimeout']").val();
if(!/^\d+$/.test(executorTimeout)) { if(!/^\d+$/.test(executorTimeout)) {
executorTimeout = 0; executorTimeout = 0;
} }
$("#updateModal .form input[name='executorTimeout']").val(executorTimeout); $("#updateModal .form input[name='executorTimeout']").val(executorTimeout);
// post // post
$.post(base_url + "/jobinfo/update", $("#updateModal .form").serialize(), function(data, status) { $.post(base_url + "/jobinfo/update", $("#updateModal .form").serialize(), function(data, status) {
if (data.code == "200") { if (data.code == "200") {
$('#updateModal').modal('hide'); $('#updateModal').modal('hide');
layer.open({ layer.open({
title: I18n.system_tips , title: I18n.system_tips ,
btn: [ I18n.system_ok ], btn: [ I18n.system_ok ],
content: I18n.system_update_suc , content: I18n.system_update_suc ,
icon: '1', icon: '1',
end: function(layero, index){ end: function(layero, index){
//window.location.reload(); //window.location.reload();
jobTable.fnDraw(); jobTable.fnDraw();
} }
}); });
} else { } else {
layer.open({ layer.open({
title: I18n.system_tips , title: I18n.system_tips ,
btn: [ I18n.system_ok ], btn: [ I18n.system_ok ],
content: (data.msg || I18n.system_update_fail ), content: (data.msg || I18n.system_update_fail ),
icon: '2' icon: '2'
}); });
} }
}); });
} }
}); });
$("#updateModal").on('hide.bs.modal', function () { $("#updateModal").on('hide.bs.modal', function () {
$("#updateModal .form")[0].reset() $("#updateModal .form")[0].reset()
}); });
/** /**
* find title by name, GlueType * find title by name, GlueType
*/ */
function findGlueTypeTitle(glueType) { function findGlueTypeTitle(glueType) {
var glueTypeTitle; var glueTypeTitle;
$("#addModal .form select[name=glueType] option").each(function () { $("#addModal .form select[name=glueType] option").each(function () {
var name = $(this).val(); var name = $(this).val();
var title = $(this).text(); var title = $(this).text();
if (glueType == name) { if (glueType == name) {
glueTypeTitle = title; glueTypeTitle = title;
return false return false
} }
}); });
return glueTypeTitle; return glueTypeTitle;
} }
}); });
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment