feat: 2.4.0
1. 优化页面支持常驻任务 2. 触发类型输入框支持文本和数字类型 3.修复分片的参数解析问题
This commit is contained in:
parent
820cd7a3f4
commit
4d057510d3
@ -82,4 +82,8 @@ public interface SystemConstants {
|
||||
interface DATE_FORMAT {
|
||||
DateTimeFormatter YYYYMMDDHHMMSS = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
}
|
||||
|
||||
String JOB_SHARDING_VALUE_SEPARATOR = "#=@";
|
||||
|
||||
String JOB_SHARDING_ARGS_SEPARATOR = "#;@";
|
||||
}
|
||||
|
@ -3,13 +3,12 @@ package com.aizuda.easy.retry.server.job.task.support.generator.task;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.aizuda.easy.retry.common.core.enums.JobTaskStatusEnum;
|
||||
import com.aizuda.easy.retry.common.core.enums.TaskTypeEnum;
|
||||
import com.aizuda.easy.retry.server.common.cache.CacheRegisterTable;
|
||||
import com.aizuda.easy.retry.server.common.dto.RegisterNodeInfo;
|
||||
import com.aizuda.easy.retry.server.common.exception.EasyRetryServerException;
|
||||
import com.aizuda.easy.retry.server.common.util.ClientInfoUtils;
|
||||
import com.aizuda.easy.retry.server.job.task.support.JobTaskConverter;
|
||||
import com.aizuda.easy.retry.common.core.enums.TaskTypeEnum;
|
||||
import com.aizuda.easy.retry.template.datasource.persistence.mapper.JobMapper;
|
||||
import com.aizuda.easy.retry.template.datasource.persistence.mapper.JobTaskMapper;
|
||||
import com.aizuda.easy.retry.template.datasource.persistence.po.JobTask;
|
||||
import com.google.common.collect.Lists;
|
||||
@ -35,8 +34,6 @@ public class BroadcastTaskGenerator extends AbstractJobTaskGenerator {
|
||||
|
||||
@Autowired
|
||||
private JobTaskMapper jobTaskMapper;
|
||||
@Autowired
|
||||
private JobMapper jobMapper;
|
||||
|
||||
@Override
|
||||
public TaskTypeEnum getTaskInstanceType() {
|
||||
|
@ -2,6 +2,7 @@ package com.aizuda.easy.retry.server.job.task.support.generator.task;
|
||||
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.aizuda.easy.retry.common.core.constant.SystemConstants;
|
||||
import com.aizuda.easy.retry.common.core.enums.JobTaskStatusEnum;
|
||||
import com.aizuda.easy.retry.server.common.cache.CacheRegisterTable;
|
||||
import com.aizuda.easy.retry.server.common.dto.RegisterNodeInfo;
|
||||
@ -53,7 +54,7 @@ public class ShardingTaskGenerator extends AbstractJobTaskGenerator {
|
||||
}
|
||||
|
||||
String argsStr = context.getArgsStr();
|
||||
Map<String, String> split = Splitter.on(";").omitEmptyStrings().withKeyValueSeparator('=').split(argsStr);
|
||||
Map<String, String> split = Splitter.on(SystemConstants.JOB_SHARDING_ARGS_SEPARATOR).omitEmptyStrings().withKeyValueSeparator(SystemConstants.JOB_SHARDING_VALUE_SEPARATOR).split(argsStr);
|
||||
|
||||
List<RegisterNodeInfo> nodeInfoList = new ArrayList<>(serverNodes);
|
||||
List<JobTask> jobTasks = new ArrayList<>(split.size());
|
||||
|
Before Width: | Height: | Size: 8.7 KiB After Width: | Height: | Size: 8.7 KiB |
3
easy-retry-server/easy-retry-server-starter/src/main/resources/admin/axios.min.js
vendored
Normal file
3
easy-retry-server/easy-retry-server-starter/src/main/resources/admin/axios.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1 @@
|
||||
.ant-cron-result{display:none}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1 @@
|
||||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-7e5ff423"],{"3b7a":function(t,e,r){"use strict";r.d(e,"g",(function(){return u})),r.d(e,"j",(function(){return a})),r.d(e,"a",(function(){return s})),r.d(e,"l",(function(){return i})),r.d(e,"f",(function(){return b})),r.d(e,"h",(function(){return c})),r.d(e,"e",(function(){return d})),r.d(e,"d",(function(){return l})),r.d(e,"c",(function(){return f})),r.d(e,"b",(function(){return j})),r.d(e,"i",(function(){return h})),r.d(e,"k",(function(){return m}));var n=r("b775"),o={jobList:"/job/list",jobDetail:"/job/",saveJob:"/job/",updateJob:"/job/",updateJobStatus:"/job/status",delJob:"/job/",timeByCron:"/job/cron",jobNameList:"/job/job-name/list",jobBatchList:"/job/batch/list",jobBatchDetail:"/job/batch/",jobTaskList:"/job/task/list",jobLogList:"/job/log/list"};function u(t){return Object(n["b"])({url:o.jobNameList,method:"get",params:t})}function a(t){return Object(n["b"])({url:o.timeByCron,method:"get",params:t})}function s(t){return Object(n["b"])({url:o.delJob+t,method:"delete"})}function i(t){return Object(n["b"])({url:o.updateJobStatus,method:"put",data:t})}function b(t){return Object(n["b"])({url:o.jobLogList,method:"get",params:t})}function c(t){return Object(n["b"])({url:o.jobTaskList,method:"get",params:t})}function d(t){return Object(n["b"])({url:o.jobBatchList,method:"get",params:t})}function l(t){return Object(n["b"])({url:o.jobBatchDetail+t,method:"get"})}function f(t){return Object(n["b"])({url:o.jobList,method:"get",params:t})}function j(t){return Object(n["b"])({url:o.jobDetail+t,method:"get"})}function h(t){return Object(n["b"])({url:o.saveJob,method:"post",data:t})}function m(t){return Object(n["b"])({url:o.updateJob,method:"put",data:t})}},a03c:function(t,e,r){"use strict";r.r(e);var n=function(){var t=this,e=t._self._c;return e("div",[e("a-card",[e("s-table",{ref:"table",attrs:{size:"default",rowKey:"key",columns:t.columns,data:t.loadData},scopedSlots:t._u([{key:"serial",fn:function(r,n){return e("span",{},[t._v(" "+t._s(n.id)+" ")])}}])})],1)],1)},o=[],u=r("c1df"),a=r.n(u),s=r("2af9"),i=r("3b7a"),b={name:"JobLogList",components:{STable:s["j"]},data:function(){var t=this;return{columns:[{title:"#",scopedSlots:{customRender:"serial"},width:"5%"},{title:"信息",dataIndex:"message",width:"50%"},{title:"触发时间",dataIndex:"createDt",sorter:!0,customRender:function(t){return a()(t).format("YYYY-MM-DD HH:mm:ss")},width:"10%"}],queryParam:{},loadData:function(e){return Object(i["f"])(Object.assign(e,t.queryParam)).then((function(e){return t.total=e.total,e}))},total:0}},created:function(){var t=this.$route.query.taskBatchId,e=this.$route.query.jobId;t&&e?(this.queryParam={taskBatchId:t,jobId:e},this.$refs.table.refresh(!0)):this.$router.push({path:"/404"})},methods:{refreshTable:function(t){this.queryParam=t,this.$refs.table.refresh(!0)}}},c=b,d=r("2877"),l=Object(d["a"])(c,n,o,!1,null,"35165b21",null);e["default"]=l.exports}}]);
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -24,6 +24,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.ZonedDateTime;
|
||||
@ -111,7 +112,7 @@ public class JobServiceImpl implements JobService {
|
||||
if (Objects.nonNull(jobId)) {
|
||||
queryWrapper.eq(Job::getId, jobId);
|
||||
}
|
||||
|
||||
|
||||
PageDTO<Job> pageDTO = new PageDTO<>(1, 20);
|
||||
PageDTO<Job> selectPage = jobMapper.selectPage(pageDTO, queryWrapper);
|
||||
return JobResponseVOConverter.INSTANCE.toJobResponseVOs(selectPage.getRecords());
|
||||
@ -126,6 +127,25 @@ public class JobServiceImpl implements JobService {
|
||||
waitStrategyContext.setTriggerInterval(jobRequestVO.getTriggerInterval());
|
||||
waitStrategyContext.setNextTriggerAt(LocalDateTime.now());
|
||||
job.setNextTriggerAt(waitStrategy.computeRetryTime(waitStrategyContext));
|
||||
|
||||
// 判断常驻任务
|
||||
if (jobRequestVO.getTriggerType() == WaitStrategyEnum.FIXED.getTriggerType()) {
|
||||
if (Integer.parseInt(jobRequestVO.getTriggerInterval()) < 10) {
|
||||
job.setResident(StatusEnum.YES.getStatus());
|
||||
}
|
||||
} else if(jobRequestVO.getTriggerType() == WaitStrategyEnum.CRON.getTriggerType()) {
|
||||
List<String> timeByCron = getTimeByCron(jobRequestVO.getTriggerInterval());
|
||||
LocalDateTime first = LocalDateTime.parse(timeByCron.get(0), dateTimeFormatter);
|
||||
LocalDateTime second = LocalDateTime.parse(timeByCron.get(1), dateTimeFormatter);
|
||||
Duration duration = Duration.between(first, second);
|
||||
long milliseconds = duration.toMillis();
|
||||
if (milliseconds < 10 * 1000) {
|
||||
job.setResident(StatusEnum.YES.getStatus());
|
||||
}
|
||||
} else {
|
||||
throw new EasyRetryServerException("未知触发类型");
|
||||
}
|
||||
|
||||
return 1 == jobMapper.insert(job);
|
||||
}
|
||||
|
||||
|
@ -87,6 +87,7 @@
|
||||
<a-form-item label="触发类型">
|
||||
<a-select
|
||||
placeholder="请选择触发类型"
|
||||
@change="handleChange"
|
||||
v-decorator="[
|
||||
'triggerType',
|
||||
{
|
||||
@ -100,7 +101,19 @@
|
||||
</a-col>
|
||||
<a-col :lg="16" :md="12" :sm="12">
|
||||
<a-form-item label="间隔时长">
|
||||
<a-input-number
|
||||
v-if="triggerTypeValue === '2'"
|
||||
style="width: -webkit-fill-available"
|
||||
placeholder="请输入间隔时长(秒)"
|
||||
:min="1"
|
||||
v-decorator="[
|
||||
'triggerInterval',
|
||||
{initialValue: '60',
|
||||
rules: [ { required: true, message: '请输入间隔时长'}]}
|
||||
]" />
|
||||
|
||||
<a-input
|
||||
v-if="triggerTypeValue === '1'"
|
||||
@click="handlerCron"
|
||||
placeholder="请输入间隔时长"
|
||||
v-decorator="[
|
||||
@ -341,7 +354,8 @@ export default {
|
||||
routeKey: enums.routeKey,
|
||||
loading: false,
|
||||
visible: false,
|
||||
count: 0
|
||||
count: 0,
|
||||
triggerTypeValue: '2'
|
||||
}
|
||||
},
|
||||
beforeCreate () {
|
||||
@ -365,6 +379,13 @@ export default {
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
handleChange (value) {
|
||||
console.log(value)
|
||||
this.triggerTypeValue = value
|
||||
this.form.setFieldsValue({
|
||||
triggerInterval: null
|
||||
})
|
||||
},
|
||||
handlerCron () {
|
||||
const triggerType = this.form.getFieldValue('triggerType')
|
||||
if (triggerType === '1') {
|
||||
@ -413,11 +434,16 @@ export default {
|
||||
|
||||
const argsStr = this.form.getFieldValue('argsStr')
|
||||
|
||||
console.log(argsStr.includes('#=@'))
|
||||
if (!argsStr.includes('#=@')) {
|
||||
return
|
||||
}
|
||||
|
||||
// 将字符串分割成键值对数组
|
||||
const keyValuePairs = argsStr.split(';')
|
||||
const keyValuePairs = argsStr.split('#;@')
|
||||
console.log(keyValuePairs)
|
||||
const restoredArray = keyValuePairs.map(pair => {
|
||||
const [index, value] = pair.split('=')
|
||||
const [index, value] = pair.split('#=@')
|
||||
console.log(value)
|
||||
this.count++
|
||||
return Number.parseInt(index)
|
||||
@ -426,7 +452,7 @@ export default {
|
||||
this.dynamicForm.getFieldDecorator('keys', { initialValue: restoredArray, preserve: true })
|
||||
|
||||
keyValuePairs.map(pair => {
|
||||
const [index, value] = pair.split('=')
|
||||
const [index, value] = pair.split('#=@')
|
||||
this.dynamicForm.getFieldDecorator(`sharding[${index}]`, { initialValue: value, preserve: true })
|
||||
return value
|
||||
})
|
||||
@ -445,7 +471,7 @@ export default {
|
||||
if (!err) {
|
||||
console.log(values)
|
||||
const arr = values['sharding']
|
||||
const formattedString = arr.map((item, index) => `${index}=${item}`).join(';')
|
||||
const formattedString = arr.map((item, index) => `${index}#=@${item}`).join('#;@')
|
||||
form.setFieldsValue({
|
||||
argsStr: formattedString
|
||||
})
|
||||
@ -491,6 +517,7 @@ export default {
|
||||
formData.executorType = formData.executorType.toString()
|
||||
formData.blockStrategy = formData.blockStrategy.toString()
|
||||
formData.triggerType = formData.triggerType.toString()
|
||||
this.triggerTypeValue = formData.triggerType
|
||||
form.setFieldsValue(formData)
|
||||
})
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ const vueConfig = {
|
||||
lintOnSave: undefined,
|
||||
// babel-loader no-ignore node_modules/*
|
||||
transpileDependencies: [],
|
||||
outputDir: '../easy-retry-server/src/main/resources/admin',
|
||||
outputDir: '../easy-retry-server/easy-retry-server-starter/src/main/resources/admin'
|
||||
}
|
||||
|
||||
// preview.pro.loacg.com only do not use in your production;
|
||||
|
Loading…
Reference in New Issue
Block a user