GLUE编辑器以及后端交互更新

This commit is contained in:
xueli.xue 2016-05-19 20:06:19 +08:00
parent 5c1bba3364
commit 74e4e58c0e
12 changed files with 393 additions and 69 deletions

View File

@ -1,7 +1,10 @@
package com.xxl.job.controller;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import javax.annotation.Resource;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@ -9,6 +12,9 @@ import org.springframework.web.bind.annotation.ResponseBody;
import com.xxl.job.core.model.ReturnT;
import com.xxl.job.core.model.XxlJobInfo;
import com.xxl.job.core.model.XxlJobLogGlue;
import com.xxl.job.dao.IXxlJobInfoDao;
import com.xxl.job.dao.IXxlJobLogGlueDao;
/**
* job code controller
@ -17,15 +23,55 @@ import com.xxl.job.core.model.XxlJobInfo;
@Controller
@RequestMapping("/jobcode")
public class JobCodeController {
@Resource
private IXxlJobInfoDao xxlJobInfoDao;
@Resource
private IXxlJobLogGlueDao xxlJobLogGlueDao;
@RequestMapping
public String index(Model model, HttpServletRequest request) {
public String index(Model model, String jobGroup, String jobName) {
XxlJobInfo jobInfo = xxlJobInfoDao.load(jobGroup, jobName);
List<XxlJobLogGlue> jobLogGlues = xxlJobLogGlueDao.selectList(jobGroup, jobName);
model.addAttribute("jobInfo", jobInfo);
model.addAttribute("jobLogGlues", jobLogGlues);
return "jobcode/index";
}
@RequestMapping("/save")
@ResponseBody
public ReturnT<String> save(Model model, XxlJobInfo jobInfo, HttpServletRequest request) {
public ReturnT<String> save(Model model, String jobGroup, String jobName, String glueSource, String glueRemark) {
// valid
if (glueRemark==null) {
return new ReturnT<String>(500, "请输入备注");
}
if (glueRemark.length()<6 || glueRemark.length()>100) {
return new ReturnT<String>(500, "备注长度应该在6至100之间");
}
XxlJobInfo jobInfoOld = xxlJobInfoDao.load(jobGroup, jobName);
if (jobInfoOld == null) {
return new ReturnT<String>(500, "任务不存在");
}
// log old code
XxlJobLogGlue xxlJobLogGlue = new XxlJobLogGlue();
xxlJobLogGlue.setJobGroup(jobInfoOld.getJobGroup());
xxlJobLogGlue.setJobName(jobInfoOld.getJobName());
xxlJobLogGlue.setGlueSource(jobInfoOld.getGlueSource());
xxlJobLogGlue.setGlueRemark(jobInfoOld.getGlueRemark());
// init new code
jobInfoOld.setGlueSource(glueSource);
jobInfoOld.setGlueRemark(glueRemark);
// update new code ,and log old code
xxlJobInfoDao.update(jobInfoOld);
if (StringUtils.isNotBlank(xxlJobLogGlue.getGlueSource()) && StringUtils.isNotBlank(xxlJobLogGlue.getGlueRemark())) {
xxlJobLogGlueDao.save(xxlJobLogGlue);
// remove code backup more than 30
xxlJobLogGlueDao.removeOld(xxlJobLogGlue.getJobGroup(), xxlJobLogGlue.getJobName(), 3);
}
return ReturnT.SUCCESS;
}

View File

@ -22,6 +22,8 @@ import com.xxl.job.core.model.ReturnT;
import com.xxl.job.core.model.XxlJobInfo;
import com.xxl.job.core.util.DynamicSchedulerUtil;
import com.xxl.job.dao.IXxlJobInfoDao;
import com.xxl.job.dao.IXxlJobLogDao;
import com.xxl.job.dao.IXxlJobLogGlueDao;
import com.xxl.job.service.job.RemoteHttpJobBean;
/**
@ -34,6 +36,10 @@ public class JobInfoController {
@Resource
private IXxlJobInfoDao xxlJobInfoDao;
@Resource
public IXxlJobLogDao xxlJobLogDao;
@Resource
private IXxlJobLogGlueDao xxlJobLogGlueDao;
@RequestMapping
public String index(Model model) {
@ -216,6 +222,8 @@ public class JobInfoController {
try {
DynamicSchedulerUtil.removeJob(jobName, jobGroup);
xxlJobInfoDao.delete(jobGroup, jobName);
xxlJobLogDao.delete(jobGroup, jobName);
xxlJobLogGlueDao.delete(jobGroup, jobName);
return ReturnT.SUCCESS;
} catch (SchedulerException e) {
e.printStackTrace();

View File

@ -0,0 +1,69 @@
package com.xxl.job.core.model;
/**
* xxl-job log for glue, used to track job code process
* @author xuxueli 2016-5-19 17:57:46
*/
public class XxlJobLogGlue {
private int id;
private String jobGroup;
private String jobName;
private String glueSource;
private String glueRemark;
private String addTime;
private String updateTime;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getJobGroup() {
return jobGroup;
}
public void setJobGroup(String jobGroup) {
this.jobGroup = jobGroup;
}
public String getJobName() {
return jobName;
}
public void setJobName(String jobName) {
this.jobName = jobName;
}
public String 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 String getAddTime() {
return addTime;
}
public void setAddTime(String addTime) {
this.addTime = addTime;
}
public String getUpdateTime() {
return updateTime;
}
public void setUpdateTime(String updateTime) {
this.updateTime = updateTime;
}
@Override
public String toString() {
return "XxlJobLogGlue [id=" + id + ", jobGroup=" + jobGroup + ", jobName=" + jobName + ", glueSource="
+ glueSource + ", glueRemark=" + glueRemark + ", addTime=" + addTime + ", updateTime=" + updateTime
+ "]";
}
}

View File

@ -21,4 +21,6 @@ public interface IXxlJobLogDao {
public int updateTriggerInfo(XxlJobLog xxlJobLog);
public int updateHandleInfo(XxlJobLog xxlJobLog);
public int delete(String jobGroup, String jobName);
}

View File

@ -0,0 +1,21 @@
package com.xxl.job.dao;
import java.util.List;
import com.xxl.job.core.model.XxlJobLogGlue;
/**
* job log for glue
* @author xuxueli 2016-5-19 18:04:56
*/
public interface IXxlJobLogGlueDao {
public int save(XxlJobLogGlue xxlJobLogGlue);
public List<XxlJobLogGlue> selectList(String jobGroup, String jobName);
public int removeOld(String jobGroup, String jobName, int limit);
public int delete(String jobGroup, String jobName);
}

View File

@ -84,5 +84,13 @@ public class XxlJobLogDaoImpl implements IXxlJobLogDao {
}
return sqlSessionTemplate.update("XxlJobLogMapper.updateHandleInfo", xxlJobLog);
}
@Override
public int delete(String jobGroup, String jobName) {
HashMap<String, Object> params = new HashMap<String, Object>();
params.put("jobGroup", jobGroup);
params.put("jobName", jobName);
return sqlSessionTemplate.delete("XxlJobLogMapper.delete", params);
}
}

View File

@ -0,0 +1,54 @@
package com.xxl.job.dao.impl;
import java.util.HashMap;
import java.util.List;
import javax.annotation.Resource;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.stereotype.Repository;
import com.xxl.job.core.model.XxlJobLogGlue;
import com.xxl.job.dao.IXxlJobLogGlueDao;
/**
* job log for glue
* @author xuxueli 2016-5-19 18:17:52
*/
@Repository
public class XxlJobLogGlueDaoImpl implements IXxlJobLogGlueDao {
@Resource
public SqlSessionTemplate sqlSessionTemplate;
@Override
public int save(XxlJobLogGlue xxlJobLogGlue) {
return sqlSessionTemplate.insert("XxlJobLogGlueMapper.save", xxlJobLogGlue);
}
@Override
public List<XxlJobLogGlue> selectList(String jobGroup, String jobName) {
HashMap<String, Object> params = new HashMap<String, Object>();
params.put("jobGroup", jobGroup);
params.put("jobName", jobName);
return sqlSessionTemplate.selectList("XxlJobLogGlueMapper.selectList", params);
}
@Override
public int removeOld(String jobGroup, String jobName, int limit) {
HashMap<String, Object> params = new HashMap<String, Object>();
params.put("jobGroup", jobGroup);
params.put("jobName", jobName);
params.put("limit", limit);
return sqlSessionTemplate.delete("XxlJobLogGlueMapper.removeOld", params);
}
@Override
public int delete(String jobGroup, String jobName) {
HashMap<String, Object> params = new HashMap<String, Object>();
params.put("jobGroup", jobGroup);
params.put("jobName", jobName);
return sqlSessionTemplate.delete("XxlJobLogGlueMapper.delete", params);
}
}

View File

@ -0,0 +1,78 @@
<?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="XxlJobLogGlueMapper">
<resultMap id="XxlJobLogGlue" type="com.xxl.job.core.model.XxlJobLogGlue" >
<result column="id" property="id" />
<result column="job_group" property="jobGroup" />
<result column="job_name" property="jobName" />
<result column="glue_source" property="glueSource" />
<result column="glue_remark" property="glueRemark" />
<result column="add_time" property="addTime" />
<result column="update_time" property="updateTime" />
</resultMap>
<sql id="Base_Column_List">
t.id,
t.job_group,
t.job_name,
t.glue_source,
t.glue_remark,
t.add_time,
t.update_time
</sql>
<insert id="save" parameterType="com.xxl.job.core.model.XxlJobLogGlue" useGeneratedKeys="true" keyProperty="id" >
INSERT INTO `xxl_job_qrtz_trigger_logglue` (
`job_group`,
`job_name`,
`glue_source`,
`glue_remark`,
`add_time`,
`update_time`
) VALUES (
#{jobGroup},
#{jobName},
#{glueSource},
#{glueRemark},
now(),
now()
);
<selectKey resultType="java.lang.Integer" order="AFTER" keyProperty="id">
SELECT LAST_INSERT_ID()
</selectKey>
</insert>
<select id="selectList" parameterType="java.util.HashMap" resultMap="XxlJobLogGlue">
SELECT <include refid="Base_Column_List" />
FROM xxl_job_qrtz_trigger_logglue AS t
<trim prefix="WHERE" prefixOverrides="AND | OR" >
<if test="jobGroup != null and jobGroup != ''">
AND t.job_group = #{jobGroup}
</if>
<if test="jobName != null and jobName != ''">
AND t.job_name = #{jobName}
</if>
</trim>
ORDER BY id DESC
</select>
<delete id="removeOld" parameterType="java.util.HashMap" >
DELETE FROM xxl_job_qrtz_trigger_logglue
WHERE id NOT in(
SELECT id FROM(
SELECT id FROM xxl_job_qrtz_trigger_logglue
WHERE `job_group` = #{jobGroup} and `job_name` = #{jobName}
ORDER BY update_time desc
LIMIT 0, #{limit}
) t1
)
</delete>
<delete id="delete" parameterType="java.util.HashMap" >
DELETE FROM xxl_job_qrtz_trigger_logglue
WHERE job_group = #{jobGroup} and job_name = #{jobName}
</delete>
</mapper>

View File

@ -130,4 +130,10 @@
WHERE `id`= #{id}
</update>
<delete id="delete">
delete from `xxl_job_qrtz_trigger_log`
WHERE job_group = #{jobGroup}
AND job_name = #{jobName}
</delete>
</mapper>

View File

@ -16,59 +16,80 @@
</head>
<body class=" layout-top-nav">
<div class="wrapper">
<div class="content-wrapper">
<!-- Content Header (Page header) -->
<section class="content-header">
<h1>任务调度中心<small>任务CODE管理</small></h1>
</section>
<#if !jobInfo?exists>
<div class="wrapper">
<div class="content-wrapper">
<section class="content-header">
<h1>抱歉,任务不存在.</small></h1>
</section>
</div>
</div>
<#else>
<div class="wrapper">
<!-- Main content -->
<section class="content">
<div class="row">
<div class="col-xs-4">
<div class="input-group margin">
<div class="input-group-btn">
<button type="button" class="btn btn-info">版本回溯</button>
</div>
<select class="form-control" id="jobGroup" >
<option value="999" >逻辑调整版本C</option>
<option value="999" >逻辑调整版本B</option>
<option value="999" >逻辑调整版本A</option>
<option value="999" >代码初始化</option>
</select>
</div>
</div>
<div class="col-xs-4">
<div class="input-group margin">
<div class="input-group-btn">
<button type="button" class="btn btn-info">备注</button>
</div>
<input type="text" class="form-control" id="codeRemark" value="${jobName}" autocomplete="on" >
</div>
</div>
<div class="col-xs-2">
<div class="input-group margin">
<div class="input-group-btn">
<button type="button" class="btn btn-primary" id="save" >保存</button>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="box callout callout-info">
<textarea id="codeSource" ></textarea>
<div class="content-wrapper">
<!-- Content Header (Page header) -->
<section class="content-header">
<h1>任务调度中心<small>任务GLUE管理</small></h1>
</section>
<!-- Main content -->
<section class="content">
<div class="row">
<div class="col-xs-4">
<div class="input-group margin">
<div class="input-group-btn">
<button type="button" class="btn btn-info">版本回溯</button>
</div>
<select class="form-control" id="glue_version" >
<option value="glue_now" >${jobInfo.glueRemark}【线上】</option>
<#if jobLogGlues?exists && jobLogGlues?size gt 0 >
<#list jobLogGlues as glue>
<option value="glue_log_${glue.id}" >${glue.glueRemark}</option>
</#list>
</#if>
</select>
<textarea id="glue_now" style="display:none;" >${jobInfo.glueSource}</textarea>
<#if jobLogGlues?exists && jobLogGlues?size gt 0 >
<#list jobLogGlues as glue>
<textarea id="glue_log_${glue.id}" style="display:none;" >${glue.glueSource}</textarea>
</#list>
</#if>
</div>
</div>
<div class="col-xs-4">
<div class="input-group margin">
<div class="input-group-btn">
<button type="button" class="btn btn-info">备注</button>
</div>
<input type="text" class="form-control" id="glueRemark" value="${jobName}" autocomplete="on" >
</div>
</div>
<div class="col-xs-2">
<div class="input-group margin">
<div class="input-group-btn">
<button type="button" class="btn btn-primary" id="save" >保存</button>
</div>
<div class="input-group-btn">
<button type="button" class="btn btn-default" id="demoCode_btn" >DEMO</button>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="box callout callout-info">
<textarea id="glueSource" ></textarea>
</div>
</div>
</div>
</div>
</section>
</section>
</div>
<!-- footer -->
<@netCommon.commonFooter />
</div>
<!-- footer -->
<@netCommon.commonFooter />
</div>
<textarea id="demoCode" style="display:none;" >
package com.xxl.job.service.handler;
@ -83,11 +104,7 @@ public class DemoJobHandler extends IJobHandler {
@Override
public JobHandleStatus handle(String... params) throws Exception {
logger.info(" ... params:" + params);
for (int i = 0; i < 5; i++) {
TimeUnit.SECONDS.sleep(1);
logger.info("handler run:{}", i);
}
logger.info("demo run success...");
return JobHandleStatus.SUCCESS;
}
}
@ -100,8 +117,11 @@ public class DemoJobHandler extends IJobHandler {
<script src="${request.contextPath}/static/plugins/codemirror/addon/hint/show-hint.js"></script>
<script src="${request.contextPath}/static/plugins/codemirror/addon/hint/anyword-hint.js"></script>
<script>
var id = ${id!-1};
var jobGroup = '${jobInfo.jobGroup}';
var jobName = '${jobInfo.jobName}';
</script>
<script src="${request.contextPath}/static/js/jobcode.index.1.js"></script>
</#if>
</body>
</html>

View File

@ -1,12 +1,23 @@
$(function() {
// init code editor
var codeEditor = CodeMirror.fromTextArea(document.getElementById("codeSource"), {
var codeEditor = CodeMirror.fromTextArea(document.getElementById("glueSource"), {
mode : "text/x-java",
lineNumbers : true,
matchBrackets : true
});
codeEditor.setValue( $("#demoCode").val() );
codeEditor.setValue( $("#glue_now").val() );
// code change
$("#glue_version").change(function(){
var temp = $( "#" + $(this).val() ).val();
codeEditor.setValue( temp );
});
// democode
$("#demoCode_btn").click(function() {
codeEditor.setValue( $("#demoCode").val() );
});
// editor height
var height = Math.max(document.documentElement.clientHeight, document.body.offsetHeight);
@ -14,14 +25,14 @@ $(function() {
// code source save
$("#save").click(function() {
var codeSource = codeEditor.getValue();
var codeRemark = $("#codeRemark").val();
var glueSource = codeEditor.getValue();
var glueRemark = $("#glueRemark").val();
if (!codeRemark) {
if (!glueRemark) {
ComAlert.show(2, "请输入备注");
return;
}
if (codeRemark.length < 6|| codeRemark.length > 100) {
if (glueRemark.length < 6|| glueRemark.length > 100) {
ComAlert.show(2, "备注长度应该在6至100之间");
return;
}
@ -31,9 +42,10 @@ $(function() {
type : 'POST',
url : base_url + '/jobcode/save',
data : {
'jobInfo.id' : id,
'jobInfo.codeSource' : codeSource,
'jobInfo.codeRemark' : codeRemark
'jobGroup' : jobGroup,
'jobName' : jobName,
'glueSource' : glueSource,
'glueRemark' : glueRemark
},
dataType : "json",
success : function(data){
@ -43,7 +55,7 @@ $(function() {
window.location.reload();
});
} else {
ComAlert.alert(data.msg);
ComAlert.show(2, data.msg);
}
}
});

View File

@ -92,7 +92,7 @@ $(function() {
// log url
var codeHtml = "";
if(row.glueSwitch != 0){
var codeUrl = base_url +'/jobcode?id='+ row.id;
var codeUrl = base_url +'/jobcode?jobGroup='+ row.jobGroup +'&jobName='+ row.jobName;
codeHtml = '<button class="btn btn-warning btn-xs" type="button" onclick="javascript:window.open(\'' + codeUrl + '\')" >GLUE</button> '
}