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