任务分组管理,修改为执行器管理

v1.5
xueli.xue 8 years ago
parent 204d7848fe
commit 087cd1d435

@ -204,11 +204,12 @@ CREATE TABLE XXL_JOB_QRTZ_TRIGGER_REGISTRY (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE XXL_JOB_QRTZ_TRIGGER_GROUP (
`group_name` varchar(255) NOT NULL,
`group_desc` varchar(255) NOT NULL,
`order` int(11) NOT NULL,
PRIMARY KEY (`group_name`)
`app_name` varchar(64) NOT NULL,
`title` varchar(12) NOT NULL,
`order` tinyint(4) NOT NULL,
PRIMARY KEY (`app_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO XXL_JOB_QRTZ_TRIGGER_GROUP VALUES ('xxl-job-executor-example', '示例项目', '1');
commit;

@ -2,8 +2,11 @@ package com.xxl.job.admin.controller;
import com.xxl.job.admin.core.model.ReturnT;
import com.xxl.job.admin.core.model.XxlJobGroup;
import com.xxl.job.admin.core.thread.JobRegistryHelper;
import com.xxl.job.admin.dao.IXxlJobGroupDao;
import com.xxl.job.admin.dao.IXxlJobInfoDao;
import com.xxl.job.core.registry.RegistHelper;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
@ -30,6 +33,14 @@ public class JobGroupController {
@RequestMapping
public String index(Model model) {
List<XxlJobGroup> list = xxlJobGroupDao.findAll();
if (CollectionUtils.isNotEmpty(list)) {
for (XxlJobGroup group: list) {
List<String> registryList = JobRegistryHelper.discover(RegistHelper.RegistType.EXECUTOR.name(), group.getAppName());
group.setRegistryList(registryList);
}
}
model.addAttribute("list", list);
return "jobgroup/jobgroup.index";
}
@ -39,17 +50,20 @@ public class JobGroupController {
public ReturnT<String> save(XxlJobGroup xxlJobGroup){
// valid
if (xxlJobGroup.getGroupName()==null || StringUtils.isBlank(xxlJobGroup.getGroupName())) {
return new ReturnT<String>(500, "请输入分组");
if (xxlJobGroup.getAppName()==null || StringUtils.isBlank(xxlJobGroup.getAppName())) {
return new ReturnT<String>(500, "请输入AppName");
}
if (xxlJobGroup.getAppName().length()>64) {
return new ReturnT<String>(500, "AppName长度限制为4~64");
}
if (xxlJobGroup.getGroupDesc()==null || StringUtils.isBlank(xxlJobGroup.getGroupDesc())) {
return new ReturnT<String>(500, "请输入描述");
if (xxlJobGroup.getTitle()==null || StringUtils.isBlank(xxlJobGroup.getTitle())) {
return new ReturnT<String>(500, "请输入名称");
}
// check repeat
XxlJobGroup group = xxlJobGroupDao.load(xxlJobGroup.getGroupName());
XxlJobGroup group = xxlJobGroupDao.load(xxlJobGroup.getAppName());
if (group!=null) {
return new ReturnT<String>(500, "分组已存在, 请勿重复添加");
return new ReturnT<String>(500, "AppName对应的执行器已存在, 请勿重复添加");
}
int ret = xxlJobGroupDao.save(xxlJobGroup);
@ -59,21 +73,37 @@ public class JobGroupController {
@RequestMapping("/update")
@ResponseBody
public ReturnT<String> update(XxlJobGroup xxlJobGroup){
// valid
if (xxlJobGroup.getAppName()==null || StringUtils.isBlank(xxlJobGroup.getAppName())) {
return new ReturnT<String>(500, "请输入AppName");
}
if (xxlJobGroup.getAppName().length()>64) {
return new ReturnT<String>(500, "AppName长度限制为4~64");
}
if (xxlJobGroup.getTitle()==null || StringUtils.isBlank(xxlJobGroup.getTitle())) {
return new ReturnT<String>(500, "请输入名称");
}
int ret = xxlJobGroupDao.update(xxlJobGroup);
return (ret>0)?ReturnT.SUCCESS:ReturnT.FAIL;
}
@RequestMapping("/remove")
@ResponseBody
public ReturnT<String> remove(String groupName){
public ReturnT<String> remove(String appName){
// valid
int count = xxlJobInfoDao.pageListCount(0, 10, groupName, null);
int count = xxlJobInfoDao.pageListCount(0, 10, appName, null);
if (count > 0) {
return new ReturnT<String>(500, "该分组使用中, 不可删除");
}
int ret = xxlJobGroupDao.remove(groupName);
List<XxlJobGroup> allList = xxlJobGroupDao.findAll();
if (allList.size() == 1) {
return new ReturnT<String>(500, "删除失败, 系统需要至少预留一个默认分组");
}
int ret = xxlJobGroupDao.remove(appName);
return (ret>0)?ReturnT.SUCCESS:ReturnT.FAIL;
}

@ -1,28 +1,33 @@
package com.xxl.job.admin.core.model;
import java.util.List;
/**
* Created by xuxueli on 16/9/30.
*/
public class XxlJobGroup {
private String groupName;
private String groupDesc;
private String appName;
private String title;
private int order;
public String getGroupName() {
return groupName;
// registry list
private List<String> registryList;
public String getAppName() {
return appName;
}
public void setGroupName(String groupName) {
this.groupName = groupName;
public void setAppName(String appName) {
this.appName = appName;
}
public String getGroupDesc() {
return groupDesc;
public String getTitle() {
return title;
}
public void setGroupDesc(String groupDesc) {
this.groupDesc = groupDesc;
public void setTitle(String title) {
this.title = title;
}
public int getOrder() {
@ -32,4 +37,12 @@ public class XxlJobGroup {
public void setOrder(int order) {
this.order = order;
}
public List<String> getRegistryList() {
return registryList;
}
public void setRegistryList(List<String> registryList) {
this.registryList = registryList;
}
}

@ -42,12 +42,12 @@ public class JobRegistryHelper {
if (list != null) {
for (XxlJobRegistry item: list) {
String groupKey = makeGroupKey(item.getRegistryGroup(), item.getRegistryKey());
List<String> dataSet = temp.get(groupKey);
if (dataSet == null) {
dataSet = new ArrayList<String>();
List<String> registryList = temp.get(groupKey);
if (registryList == null) {
registryList = new ArrayList<String>();
}
dataSet.add(item.getRegistryValue());
temp.put(groupKey, dataSet);
registryList.add(item.getRegistryValue());
temp.put(groupKey, registryList);
}
}
registMap = temp;

@ -15,7 +15,7 @@ public interface IXxlJobGroupDao {
public int update(XxlJobGroup xxlJobGroup);
public int remove(String groupName);
public int remove(String appName);
public XxlJobGroup load(String groupName);
public XxlJobGroup load(String appName);
}

@ -33,13 +33,13 @@ public class XxlJobGroupDaoImpl implements IXxlJobGroupDao {
}
@Override
public int remove(String groupName) {
return sqlSessionTemplate.delete("XxlJobGroupMapper.remove", groupName);
public int remove(String appName) {
return sqlSessionTemplate.delete("XxlJobGroupMapper.remove", appName);
}
@Override
public XxlJobGroup load(String groupName) {
return sqlSessionTemplate.selectOne("XxlJobGroupMapper.load", groupName);
public XxlJobGroup load(String appName) {
return sqlSessionTemplate.selectOne("XxlJobGroupMapper.load", appName);
}

@ -4,14 +4,14 @@
<mapper namespace="XxlJobGroupMapper">
<resultMap id="XxlJobGroup" type="com.xxl.job.admin.core.model.XxlJobGroup" >
<result column="group_name" property="groupName" />
<result column="group_desc" property="groupDesc" />
<result column="app_name" property="appName" />
<result column="title" property="title" />
<result column="order" property="order" />
</resultMap>
<sql id="Base_Column_List">
t.group_name,
t.group_desc,
t.app_name,
t.title,
t.order
</sql>
@ -22,26 +22,26 @@
</select>
<insert id="save" parameterType="java.util.Map" >
INSERT INTO XXL_JOB_QRTZ_TRIGGER_GROUP ( `group_name`, `group_desc`, `order`)
values ( #{groupName}, #{groupDesc}, #{order});
INSERT INTO XXL_JOB_QRTZ_TRIGGER_GROUP ( `app_name`, `title`, `order`)
values ( #{appName}, #{title}, #{order});
</insert>
<update id="update" parameterType="java.util.Map" >
UPDATE XXL_JOB_QRTZ_TRIGGER_GROUP
SET `group_desc` = #{groupDesc},
SET `title` = #{title},
`order` = #{order}
WHERE group_name = #{groupName}
WHERE app_name = #{appName}
</update>
<delete id="remove" parameterType="java.lang.String" >
DELETE FROM XXL_JOB_QRTZ_TRIGGER_GROUP
WHERE group_name = #{groupName}
WHERE app_name = #{appName}
</delete>
<select id="load" parameterType="java.lang.String" resultMap="XxlJobGroup">
SELECT <include refid="Base_Column_List" />
FROM XXL_JOB_QRTZ_TRIGGER_GROUP AS t
WHERE t.group_name = #{groupName}
WHERE t.app_name = #{appName}
</select>
</mapper>

@ -85,8 +85,8 @@
<li class="header">常用模块</li>
<li class="nav-click" ><a href="${request.contextPath}/jobinfo"><i class="fa fa-circle-o text-red"></i> <span>调度管理</span></a></li>
<li class="nav-click" ><a href="${request.contextPath}/joblog"><i class="fa fa-circle-o text-yellow"></i><span>调度日志</span></a></li>
<li class="nav-click" ><a href="${request.contextPath}/jobgroup"><i class="fa fa-circle-o text-red"></i> <span>分组管理</span></a></li>
<li class="nav-click" ><a href="${request.contextPath}/help"><i class="fa fa-circle-o text-yellow"></i><span>使用教程</span></a></li>
<li class="nav-click" ><a href="${request.contextPath}/jobgroup"><i class="fa fa-circle-o text-aqua"></i> <span>执行器管理</span></a></li>
<li class="nav-click" ><a href="${request.contextPath}/help"><i class="fa fa-circle-o text-red"></i><span>使用教程</span></a></li>
</ul>
</section>
<!-- /.sidebar -->

@ -16,7 +16,7 @@
<div class="content-wrapper">
<!-- Content Header (Page header) -->
<section class="content-header">
<h1>任务调度中心<small>使用教程</small></h1>
<h1>使用教程<small>任务调度中心</small></h1>
<!--
<ol class="breadcrumb">
<li><a><i class="fa fa-dashboard"></i>调度中心</a></li>

@ -20,7 +20,7 @@
<div class="content-wrapper">
<!-- Content Header (Page header) -->
<section class="content-header">
<h1>分组管理<small>任务调度中心</small></h1>
<h1>执行器管理<small>任务调度中心</small></h1>
</section>
<!-- Main content -->
@ -30,16 +30,17 @@
<div class="col-xs-12">
<div class="box">
<div class="box-header">
<h3 class="box-title">分组管理</h3>
<button class="btn btn-success btn-xs pull-left2 add" >+新增分组</button>
<h3 class="box-title">执行器列表</h3>&nbsp;&nbsp;
<button class="btn btn-info btn-xs pull-left2 add" >+新增执行器</button>
</div>
<div class="box-body">
<table id="joblog_list" class="table table-bordered table-striped display" width="100%" >
<thead>
<tr>
<th name="groupDesc" >名称</th>
<th name="groupName" >AppName</th>
<th name="appName" >AppName</th>
<th name="title" >名称</th>
<th name="order" >排序</th>
<th name="registryList" >OnLine</th>
<th name="operate" >操作</th>
</tr>
</thead>
@ -47,12 +48,13 @@
<#if list?exists && list?size gt 0>
<#list list as group>
<tr>
<td>${group.groupDesc}</td>
<td>${group.groupName}</td>
<td>${group.appName}</td>
<td>${group.title}</td>
<td>${group.order}</td>
<td><#if group.registryList?exists><#list group.registryList as item><span class="badge bg-green">${item}</span><br></#list></#if></td>
<td>
<button class="btn btn-warning btn-xs update" groupName="${group.groupName}" groupDesc="${group.groupDesc}" order="${group.order}" >编辑</button>
<button class="btn btn-danger btn-xs remove" groupName="${group.groupName}" >删除</button>
<button class="btn btn-warning btn-xs update" appName="${group.appName}" title="${group.title}" order="${group.order}" >编辑</button>
<button class="btn btn-danger btn-xs remove" appName="${group.appName}" >删除</button>
</td>
</tr>
</#list>
@ -71,17 +73,17 @@
<div class="modal-dialog ">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" >新增分组</h4>
<h4 class="modal-title" >新增执行器</h4>
</div>
<div class="modal-body">
<form class="form-horizontal form" role="form" >
<div class="form-group">
<label for="lastname" class="col-sm-2 control-label">分组<font color="red">*</font></label>
<div class="col-sm-10"><input type="text" class="form-control" name="groupName" placeholder="请输入“分组”" maxlength="200" ></div>
<label for="lastname" class="col-sm-2 control-label">AppName<font color="red">*</font></label>
<div class="col-sm-10"><input type="text" class="form-control" name="appName" placeholder="请输入“AppName”" maxlength="64" ></div>
</div>
<div class="form-group">
<label for="lastname" class="col-sm-2 control-label">描述<font color="red">*</font></label>
<div class="col-sm-10"><input type="text" class="form-control" name="groupDesc" placeholder="请输入“描述”" maxlength="200" ></div>
<label for="lastname" class="col-sm-2 control-label">名称<font color="red">*</font></label>
<div class="col-sm-10"><input type="text" class="form-control" name="title" placeholder="请输入“名称”" maxlength="12" ></div>
</div>
<div class="form-group">
<label for="lastname" class="col-sm-2 control-label">排序<font color="red">*</font></label>
@ -105,17 +107,17 @@
<div class="modal-dialog ">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" >编辑分组</h4>
<h4 class="modal-title" >编辑执行器</h4>
</div>
<div class="modal-body">
<form class="form-horizontal form" role="form" >
<div class="form-group">
<label for="lastname" class="col-sm-2 control-label">分组<font color="red">*</font></label>
<div class="col-sm-10"><input type="text" class="form-control" name="groupName" placeholder="请输入“分组”" maxlength="200" readonly ></div>
<label for="lastname" class="col-sm-2 control-label">AppName<font color="red">*</font></label>
<div class="col-sm-10"><input type="text" class="form-control" name="appName" placeholder="请输入“AppName”" maxlength="64" readonly ></div>
</div>
<div class="form-group">
<label for="lastname" class="col-sm-2 control-label">描述<font color="red">*</font></label>
<div class="col-sm-10"><input type="text" class="form-control" name="groupDesc" placeholder="请输入“描述”" maxlength="200" ></div>
<label for="lastname" class="col-sm-2 control-label">名称<font color="red">*</font></label>
<div class="col-sm-10"><input type="text" class="form-control" name="title" placeholder="请输入“名称”" maxlength="12" ></div>
</div>
<div class="form-group">
<label for="lastname" class="col-sm-2 control-label">排序<font color="red">*</font></label>

@ -25,7 +25,7 @@
<div class="content-wrapper">
<!-- Content Header (Page header) -->
<section class="content-header">
<h1>调度管理任务调度中心<small></small></h1>
<h1>调度管理<small>任务调度中心</small></h1>
<!--
<ol class="breadcrumb">
<li><a><i class="fa fa-dashboard"></i>调度管理</a></li>

@ -2,21 +2,25 @@ $(function() {
// remove
$('.remove').on('click', function(){
var groupName = $(this).attr('groupName');
var appName = $(this).attr('appName');
ComConfirm.show("确认删除分组?", function(){
$.ajax({
type : 'POST',
url : base_url + '/jobgroup/remove',
data : {"groupName":groupName},
data : {"appName":appName},
dataType : "json",
success : function(data){
if (data.code == 200) {
ComAlert.show(1, '删除成功');
window.location.reload();
} else {
if (data.msg) {
ComAlert.show(2, data.msg);
} else {
ComAlert.show(2, '删除失败');
}
}
},
});
});
@ -37,12 +41,12 @@ $(function() {
errorClass : 'help-block',
focusInvalid : true,
rules : {
groupName : {
appName : {
required : true,
rangelength:[4,200],
rangelength:[4,64],
myValid01 : true
},
groupDesc : {
title : {
required : true,
rangelength:[4, 12]
},
@ -53,13 +57,13 @@ $(function() {
}
},
messages : {
groupName : {
required :"请输入“分组”",
rangelength:"长度限制为4~200",
appName : {
required :"请输入“AppName”",
rangelength:"AppName长度限制为4~64",
myValid01: "限制以小写字母开头,由小写字母、数字和中划线组成"
},
groupDesc : {
required :"请输入“描述”",
title : {
required :"请输入“执行器名称”",
rangelength:"长度限制为4~12"
},
order : {
@ -104,8 +108,8 @@ $(function() {
});
$('.update').on('click', function(){
$("#updateModal .form input[name='groupName']").val($(this).attr("groupName"));
$("#updateModal .form input[name='groupDesc']").val($(this).attr("groupDesc"));
$("#updateModal .form input[name='appName']").val($(this).attr("appName"));
$("#updateModal .form input[name='title']").val($(this).attr("title"));
$("#updateModal .form input[name='order']").val($(this).attr("order"));
$('#updateModal').modal({backdrop: false, keyboard: false}).modal('show');
@ -115,12 +119,12 @@ $(function() {
errorClass : 'help-block',
focusInvalid : true,
rules : {
groupName : {
appName : {
required : true,
rangelength:[4,200],
rangelength:[4,64],
myValid01 : true
},
groupDesc : {
title : {
required : true,
rangelength:[4, 12]
},
@ -131,13 +135,13 @@ $(function() {
}
},
messages : {
groupName : {
required :"请输入“分组”",
rangelength:"长度限制为4~200",
appName : {
required :"请输入“AppName”",
rangelength:"AppName长度限制为4~64",
myValid01: "限制以小写字母开头,由小写字母、数字和中划线组成"
},
groupDesc : {
required :"请输入“描述”",
title : {
required :"请输入“执行器名称”",
rangelength:"长度限制为4~12"
},
order : {

Loading…
Cancel
Save