feat:2.4.0
1. 完成任务的新增更新删除
This commit is contained in:
parent
cdbaf8ee75
commit
27fffc4d89
@ -221,13 +221,13 @@ CREATE TABLE `job` (
|
||||
`job_name` varchar(64) NOT NULL COMMENT '名称',
|
||||
`args_str` text NOT NULL COMMENT '执行方法参数',
|
||||
`args_type` tinyint(4) NOT NULL DEFAULT '' COMMENT '参数类型 ',
|
||||
`ext_attrs` text NOT NULL COMMENT '扩展字段',
|
||||
`ext_attrs` text COMMENT '扩展字段',
|
||||
`next_trigger_at` datetime NOT NULL COMMENT '下次触发时间',
|
||||
`job_status` tinyint(4) NOT NULL DEFAULT '1' COMMENT '重试状态 0、关闭、1、开启',
|
||||
`task_type` varchar(255) DEFAULT NULL COMMENT '任务类型 1、集群 2、广播 3、切片',
|
||||
`route_key` tinyint(4) NOT NULL DEFAULT '4' COMMENT '路由策略',
|
||||
`executor_type` tinyint(4) NOT NULL DEFAULT '1' COMMENT '执行器类型',
|
||||
`executor_name` varchar(255) DEFAULT NULL COMMENT '执行器名称',
|
||||
`executor_info` varchar(255) DEFAULT NULL COMMENT '执行器名称',
|
||||
`trigger_type` tinyint(4) NOT NULL COMMENT '触发类型 1.CRON 表达式 2. 固定时间',
|
||||
`trigger_interval` varchar(255) NOT NULL COMMENT '间隔时长',
|
||||
`block_strategy` varchar(50) DEFAULT NULL COMMENT '阻塞策略 1、丢弃 2、覆盖 3、并行',
|
||||
@ -250,7 +250,6 @@ CREATE TABLE `job_log_message` (
|
||||
`job_id` bigint(20) NOT NULL COMMENT '任务信息id',
|
||||
`task_batch_id` bigint(20) NOT NULL COMMENT '任务批次id',
|
||||
`task_id` bigint(20) NOT NULL COMMENT '调度任务id',
|
||||
`client_address` varchar(255) DEFAULT NULL COMMENT '客户端地址',
|
||||
`message` text NOT NULL COMMENT '调度信息',
|
||||
`create_dt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`ext_attrs` varchar(256) NULL default '' COMMENT '扩展字段',
|
||||
@ -263,9 +262,9 @@ CREATE TABLE `job_task` (
|
||||
`job_id` bigint(20) NOT NULL COMMENT '任务信息id',
|
||||
`task_batch_id` bigint(20) NOT NULL COMMENT '调度任务id',
|
||||
`parent_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '父执行器id',
|
||||
`execute_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '执行的状态 0、失败 1、成功',
|
||||
`task_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '执行的状态 0、失败 1、成功',
|
||||
`retry_count` int(11) NOT NULL DEFAULT '0' COMMENT '重试次数',
|
||||
`client_id` varchar(255) DEFAULT NULL COMMENT '客户端地址',
|
||||
`client_info` varchar(255) DEFAULT NULL COMMENT '客户端地址 clientId#ip:port',
|
||||
`result_message` text NOT NULL COMMENT '执行结果',
|
||||
`args_str` text NOT NULL COMMENT '执行方法参数',
|
||||
`args_type` varchar(16) NOT NULL DEFAULT '' COMMENT '参数类型 text/json',
|
||||
@ -279,7 +278,7 @@ CREATE TABLE `job_task_batch` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`group_name` varchar(64) NOT NULL COMMENT '组名称',
|
||||
`job_id` bigint(20) NOT NULL COMMENT '任务id',
|
||||
`task_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '任务状态 0、失败 1、成功',
|
||||
`task_batch_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '任务批次状态 0、失败 1、成功',
|
||||
`operation_reason` tinyint(4) NOT NULL DEFAULT '0' COMMENT '操作原因',
|
||||
`execution_at` datetime DEFAULT NULL COMMENT '任务执行时间',
|
||||
`create_dt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
|
@ -0,0 +1,12 @@
|
||||
package com.aizuda.easy.retry.template.datasource.persistence.dataobject;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author www.byteblogs.com
|
||||
* @date 2023-10-15 23:03:01
|
||||
* @since 2.4.0
|
||||
*/
|
||||
@Data
|
||||
public class JobBatchResponseDO {
|
||||
}
|
@ -1,10 +1,13 @@
|
||||
package com.aizuda.easy.retry.template.datasource.persistence.mapper;
|
||||
|
||||
import com.aizuda.easy.retry.template.datasource.persistence.dataobject.JobBatchResponseDO;
|
||||
import com.aizuda.easy.retry.template.datasource.persistence.po.JobTaskBatch;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 调度任务 Mapper 接口
|
||||
@ -16,4 +19,5 @@ import org.apache.ibatis.annotations.Param;
|
||||
@Mapper
|
||||
public interface JobTaskBatchMapper extends BaseMapper<JobTaskBatch> {
|
||||
|
||||
List<JobBatchResponseDO> selectJobBatchList();
|
||||
}
|
||||
|
@ -12,5 +12,8 @@
|
||||
<result column="update_dt" property="updateDt" />
|
||||
<result column="deleted" property="deleted" />
|
||||
</resultMap>
|
||||
|
||||
<select id="selectJobBatchList" resultType="com.aizuda.easy.retry.template.datasource.persistence.dataobject.JobBatchResponseDO">
|
||||
SELECT a.*, b.job_name, b.task_type, b.block_strategy, b.trigger_type
|
||||
FROM job_task_batch a join job b on a.job_id = b.id
|
||||
</select>
|
||||
</mapper>
|
||||
|
@ -34,8 +34,6 @@ import java.util.*;
|
||||
@Slf4j
|
||||
public class ShardingTaskGenerator extends AbstractJobTaskGenerator {
|
||||
|
||||
@Autowired
|
||||
private JobMapper jobMapper;
|
||||
@Autowired
|
||||
protected ClientNodeAllocateHandler clientNodeAllocateHandler;
|
||||
@Autowired
|
||||
|
@ -4,16 +4,12 @@ import com.aizuda.easy.retry.server.web.annotation.LoginRequired;
|
||||
import com.aizuda.easy.retry.server.web.model.base.PageResult;
|
||||
import com.aizuda.easy.retry.server.web.model.request.JobQueryVO;
|
||||
import com.aizuda.easy.retry.server.web.model.request.JobRequestVO;
|
||||
import com.aizuda.easy.retry.server.web.model.request.JobUpdateJobStatusRequestVO;
|
||||
import com.aizuda.easy.retry.server.web.model.response.JobResponseVO;
|
||||
import com.aizuda.easy.retry.server.web.service.JobService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -43,14 +39,26 @@ public class JobController {
|
||||
|
||||
@PostMapping
|
||||
@LoginRequired
|
||||
public Boolean saveJob(@RequestBody JobRequestVO jobRequestVO) {
|
||||
public Boolean saveJob(@RequestBody @Validated JobRequestVO jobRequestVO) {
|
||||
return jobService.saveJob(jobRequestVO);
|
||||
}
|
||||
|
||||
@PutMapping
|
||||
@LoginRequired
|
||||
public Boolean updateJob(@RequestBody JobRequestVO jobRequestVO) {
|
||||
public Boolean updateJob(@RequestBody @Validated JobRequestVO jobRequestVO) {
|
||||
return jobService.updateJob(jobRequestVO);
|
||||
}
|
||||
|
||||
@PutMapping("/status")
|
||||
@LoginRequired
|
||||
public Boolean updateJobStatus(@RequestBody @Validated JobUpdateJobStatusRequestVO jobRequestVO) {
|
||||
return jobService.updateJobStatus(jobRequestVO);
|
||||
}
|
||||
|
||||
@DeleteMapping("{id}")
|
||||
@LoginRequired
|
||||
public Boolean deleteJobById(@PathVariable("id") Long id) {
|
||||
return jobService.deleteJobById(id);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -29,6 +29,12 @@ public class JobRequestVO {
|
||||
@NotBlank(message = "jobName 不能为空")
|
||||
private String jobName;
|
||||
|
||||
/**
|
||||
* 重试状态 0、关闭、1、开启
|
||||
*/
|
||||
@NotNull(message = "jobStatus 不能为空")
|
||||
private Integer jobStatus;
|
||||
|
||||
/**
|
||||
* 执行方法参数
|
||||
*/
|
||||
@ -37,14 +43,14 @@ public class JobRequestVO {
|
||||
/**
|
||||
* 参数类型 text/json
|
||||
*/
|
||||
@NotNull(message = "argsType 不能为空")
|
||||
// @NotNull(message = "argsType 不能为空")
|
||||
private Integer argsType;
|
||||
|
||||
/**
|
||||
* 执行器路由策略
|
||||
*/
|
||||
@NotNull(message = "routeKey 不能为空")
|
||||
private String routeKey;
|
||||
private Integer routeKey;
|
||||
|
||||
/**
|
||||
* 执行器类型 1、Java
|
||||
|
@ -0,0 +1,21 @@
|
||||
package com.aizuda.easy.retry.server.web.model.request;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* @author www.byteblogs.com
|
||||
* @date 2023-10-15 16:06:20
|
||||
* @since 2.4.0
|
||||
*/
|
||||
@Data
|
||||
public class JobUpdateJobStatusRequestVO {
|
||||
|
||||
@NotNull(message = "id 不能为空")
|
||||
private Long id;
|
||||
|
||||
@NotNull(message = "jobStatus 不能为空")
|
||||
private Integer jobStatus;
|
||||
|
||||
}
|
@ -19,6 +19,11 @@ public class JobBatchResponseVO {
|
||||
*/
|
||||
private String groupName;
|
||||
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
private String jobName;
|
||||
|
||||
/**
|
||||
* 任务信息id
|
||||
*/
|
||||
@ -43,4 +48,14 @@ public class JobBatchResponseVO {
|
||||
* 操作原因
|
||||
*/
|
||||
private Integer operationReason;
|
||||
|
||||
/**
|
||||
* 执行器类型 1、Java
|
||||
*/
|
||||
private Integer executorType;
|
||||
|
||||
/**
|
||||
* 执行器名称
|
||||
*/
|
||||
private String executorName;
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package com.aizuda.easy.retry.server.web.service;
|
||||
import com.aizuda.easy.retry.server.web.model.base.PageResult;
|
||||
import com.aizuda.easy.retry.server.web.model.request.JobQueryVO;
|
||||
import com.aizuda.easy.retry.server.web.model.request.JobRequestVO;
|
||||
import com.aizuda.easy.retry.server.web.model.request.JobUpdateJobStatusRequestVO;
|
||||
import com.aizuda.easy.retry.server.web.model.response.JobResponseVO;
|
||||
|
||||
import java.util.List;
|
||||
@ -21,4 +22,7 @@ public interface JobService {
|
||||
|
||||
boolean updateJob(JobRequestVO jobRequestVO);
|
||||
|
||||
Boolean updateJobStatus(JobUpdateJobStatusRequestVO jobRequestVO);
|
||||
|
||||
Boolean deleteJobById(Long id);
|
||||
}
|
||||
|
@ -1,8 +1,11 @@
|
||||
package com.aizuda.easy.retry.server.web.service.convert;
|
||||
|
||||
import com.aizuda.easy.retry.server.web.model.response.JobBatchResponseVO;
|
||||
import com.aizuda.easy.retry.template.datasource.persistence.po.Job;
|
||||
import com.aizuda.easy.retry.template.datasource.persistence.po.JobTaskBatch;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.Mappings;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
@ -19,5 +22,10 @@ public interface JobBatchResponseVOConverter {
|
||||
|
||||
List<JobBatchResponseVO> toJobBatchResponseVOs(List<JobTaskBatch> jobBatches);
|
||||
|
||||
JobBatchResponseVO toJobBatchResponseVO(JobTaskBatch jobBatch);
|
||||
@Mappings({
|
||||
@Mapping(source = "jobBatch.groupName", target = "groupName"),
|
||||
@Mapping(source = "jobBatch.id", target = "id"),
|
||||
@Mapping(source = "jobBatch.createDt", target = "createDt")
|
||||
})
|
||||
JobBatchResponseVO toJobBatchResponseVO(JobTaskBatch jobBatch, Job job);
|
||||
}
|
||||
|
@ -1,11 +1,14 @@
|
||||
package com.aizuda.easy.retry.server.web.service.impl;
|
||||
|
||||
import com.aizuda.easy.retry.common.core.enums.StatusEnum;
|
||||
import com.aizuda.easy.retry.server.web.model.base.PageResult;
|
||||
import com.aizuda.easy.retry.server.web.model.request.JobBatchQueryVO;
|
||||
import com.aizuda.easy.retry.server.web.model.response.JobBatchResponseVO;
|
||||
import com.aizuda.easy.retry.server.web.service.JobBatchService;
|
||||
import com.aizuda.easy.retry.server.web.service.convert.JobBatchResponseVOConverter;
|
||||
import com.aizuda.easy.retry.template.datasource.persistence.mapper.JobMapper;
|
||||
import com.aizuda.easy.retry.template.datasource.persistence.mapper.JobTaskBatchMapper;
|
||||
import com.aizuda.easy.retry.template.datasource.persistence.po.Job;
|
||||
import com.aizuda.easy.retry.template.datasource.persistence.po.JobTaskBatch;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
|
||||
@ -25,6 +28,8 @@ public class JobBatchServiceImpl implements JobBatchService {
|
||||
|
||||
@Autowired
|
||||
private JobTaskBatchMapper jobTaskBatchMapper;
|
||||
@Autowired
|
||||
private JobMapper jobMapper;
|
||||
|
||||
@Override
|
||||
public PageResult<List<JobBatchResponseVO>> getJobBatchPage(final JobBatchQueryVO queryVO) {
|
||||
@ -32,6 +37,8 @@ public class JobBatchServiceImpl implements JobBatchService {
|
||||
PageDTO<JobTaskBatch> pageDTO = new PageDTO<>(queryVO.getPage(), queryVO.getSize());
|
||||
|
||||
LambdaQueryWrapper<JobTaskBatch> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(JobTaskBatch::getDeleted, StatusEnum.NO.getStatus());
|
||||
|
||||
if (Objects.nonNull(queryVO.getJobId())) {
|
||||
queryWrapper.eq(JobTaskBatch::getJobId, queryVO.getJobId());
|
||||
}
|
||||
@ -47,6 +54,11 @@ public class JobBatchServiceImpl implements JobBatchService {
|
||||
@Override
|
||||
public JobBatchResponseVO getJobBatchDetail(final Long id) {
|
||||
JobTaskBatch jobTaskBatch = jobTaskBatchMapper.selectById(id);
|
||||
return JobBatchResponseVOConverter.INSTANCE.toJobBatchResponseVO(jobTaskBatch);
|
||||
if (Objects.isNull(jobTaskBatch)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Job job = jobMapper.selectById(jobTaskBatch.getJobId());
|
||||
return JobBatchResponseVOConverter.INSTANCE.toJobBatchResponseVO(jobTaskBatch, job);
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author: www.byteblogs.com
|
||||
@ -31,6 +32,13 @@ public class JobLogServiceImpl implements JobLogService {
|
||||
PageDTO<JobLogMessage> pageDTO = new PageDTO<>(queryVO.getPage(), queryVO.getSize());
|
||||
|
||||
LambdaQueryWrapper<JobLogMessage> queryWrapper = new LambdaQueryWrapper<>();
|
||||
if (Objects.nonNull(queryVO.getJobId())) {
|
||||
queryWrapper.eq(JobLogMessage::getJobId, queryVO.getJobId());
|
||||
}
|
||||
|
||||
if (Objects.nonNull(queryVO.getTaskBatchId())) {
|
||||
queryWrapper.eq(JobLogMessage::getTaskBatchId, queryVO.getTaskBatchId());
|
||||
}
|
||||
|
||||
PageDTO<JobLogMessage> selectPage = jobLogMessageMapper.selectPage(pageDTO, queryWrapper);
|
||||
|
||||
|
@ -2,10 +2,13 @@ package com.aizuda.easy.retry.server.web.service.impl;
|
||||
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.aizuda.easy.retry.common.core.enums.StatusEnum;
|
||||
import com.aizuda.easy.retry.server.common.exception.EasyRetryServerException;
|
||||
import com.aizuda.easy.retry.server.retry.task.support.strategy.WaitStrategies;
|
||||
import com.aizuda.easy.retry.server.web.model.base.PageResult;
|
||||
import com.aizuda.easy.retry.server.web.model.request.JobQueryVO;
|
||||
import com.aizuda.easy.retry.server.web.model.request.JobRequestVO;
|
||||
import com.aizuda.easy.retry.server.web.model.request.JobUpdateJobStatusRequestVO;
|
||||
import com.aizuda.easy.retry.server.web.model.response.JobResponseVO;
|
||||
import com.aizuda.easy.retry.server.web.service.JobService;
|
||||
import com.aizuda.easy.retry.server.web.service.convert.JobConverter;
|
||||
@ -19,6 +22,7 @@ import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author www.byteblogs.com
|
||||
@ -37,6 +41,7 @@ public class JobServiceImpl implements JobService {
|
||||
PageDTO<Job> pageDTO = new PageDTO<>(queryVO.getPage(), queryVO.getSize());
|
||||
|
||||
LambdaQueryWrapper<Job> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(Job::getDeleted, StatusEnum.NO.getStatus());
|
||||
if (StrUtil.isNotBlank(queryVO.getGroupName())) {
|
||||
queryWrapper.eq(Job::getGroupName, queryVO.getGroupName());
|
||||
}
|
||||
@ -66,6 +71,7 @@ public class JobServiceImpl implements JobService {
|
||||
@Override
|
||||
public boolean saveJob(JobRequestVO jobRequestVO) {
|
||||
Job job = JobConverter.INSTANCE.toJob(jobRequestVO);
|
||||
job.setNextTriggerAt(WaitStrategies.randomWait(1, TimeUnit.SECONDS, 60, TimeUnit.SECONDS).computeRetryTime(null));
|
||||
return 1 == jobMapper.insert(job);
|
||||
}
|
||||
|
||||
@ -76,4 +82,23 @@ public class JobServiceImpl implements JobService {
|
||||
Job job = JobConverter.INSTANCE.toJob(jobRequestVO);
|
||||
return 1 == jobMapper.updateById(job);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean updateJobStatus(JobUpdateJobStatusRequestVO jobRequestVO) {
|
||||
Assert.notNull(jobRequestVO.getId(), () -> new EasyRetryServerException("id 不能为空"));
|
||||
Assert.isTrue(1 == jobMapper.selectCount(new LambdaQueryWrapper<Job>().eq(Job::getId, jobRequestVO.getId())));
|
||||
|
||||
Job job = new Job();
|
||||
job.setId(jobRequestVO.getId());
|
||||
job.setJobStatus(jobRequestVO.getJobStatus());
|
||||
return 1 == jobMapper.updateById(job);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean deleteJobById(Long id) {
|
||||
Job job = new Job();
|
||||
job.setId(id);
|
||||
job.setDeleted(StatusEnum.YES.getStatus());
|
||||
return 1 == jobMapper.updateById(job);
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,8 @@ const jobApi = {
|
||||
jobDetail: '/job/',
|
||||
saveJob: '/job/',
|
||||
updateJob: '/job/',
|
||||
updateJobStatus: '/job/status',
|
||||
delJob: '/job/',
|
||||
|
||||
// 任务批次
|
||||
jobBatchList: '/job/batch/list',
|
||||
@ -19,6 +21,21 @@ const jobApi = {
|
||||
|
||||
export default jobApi
|
||||
|
||||
export function delJob (id) {
|
||||
return request({
|
||||
url: jobApi.delJob + id,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
export function updateJobStatus (data) {
|
||||
return request({
|
||||
url: jobApi.updateJobStatus,
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function jobLogList (parameter) {
|
||||
return request({
|
||||
url: jobApi.jobLogList,
|
||||
|
@ -141,6 +141,13 @@ export const asyncRouterMap = [
|
||||
component: () => import('@/views/job/JobInfo'),
|
||||
meta: { title: '定时任务详情', icon: 'profile', permission: ['retryLog'] }
|
||||
},
|
||||
{
|
||||
path: '/job/config',
|
||||
name: 'JobFrom',
|
||||
hidden: true,
|
||||
component: () => import('@/views/job/from/JobFrom'),
|
||||
meta: { title: '任务配置', icon: 'profile', permission: ['retryLog'] }
|
||||
},
|
||||
{
|
||||
path: '/job/batch/list',
|
||||
name: 'JobBatchList',
|
||||
|
@ -4,24 +4,37 @@
|
||||
<div></div>
|
||||
</page-header-wrapper>
|
||||
<a-card :bordered="false" v-if="jobBatchInfo !==null ">
|
||||
<a-descriptions title="" :column="5" bordered>
|
||||
<a-descriptions title="" :column="3" bordered>
|
||||
<a-descriptions-item label="组名称">
|
||||
{{ jobBatchInfo.groupName }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="任务名称">
|
||||
{{ jobBatchInfo.jobName }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="重试状态">
|
||||
<a-descriptions-item label="状态">
|
||||
<a-tag :color="taskStatus[jobBatchInfo.taskStatus].color">
|
||||
{{ taskStatus[jobBatchInfo.taskStatus].name }}
|
||||
</a-tag>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="更新时间">
|
||||
{{ jobBatchInfo.updateDt }}
|
||||
<a-descriptions-item label="执行器类型">
|
||||
<a-tag :color="executorType[jobBatchInfo.executorType].color">
|
||||
{{ executorType[jobBatchInfo.executorType].name }}
|
||||
</a-tag>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="执行器名称" span="3">
|
||||
<a-descriptions-item label="操作原因">
|
||||
<a-tag :color="operationReason[jobBatchInfo.operationReason].color">
|
||||
{{ operationReason[jobBatchInfo.operationReason].name }}
|
||||
</a-tag>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="开始执行时间">
|
||||
{{ jobBatchInfo.executionAt }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="执行器名称" span="4">
|
||||
{{ jobBatchInfo.executorName }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="创建时间">
|
||||
{{ jobBatchInfo.createDt }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-card>
|
||||
<div style="margin: 20px 0; border-left: #f5222d 5px solid; font-size: medium; font-weight: bold">
|
||||
@ -47,7 +60,11 @@ export default {
|
||||
return {
|
||||
jobBatchInfo: null,
|
||||
taskStatus: enums.taskStatus,
|
||||
operationReason: enums.operationReason
|
||||
operationReason: enums.operationReason,
|
||||
taskType: enums.taskType,
|
||||
triggerType: enums.triggerType,
|
||||
blockStrategy: enums.blockStrategy,
|
||||
executorType: enums.executorType
|
||||
}
|
||||
},
|
||||
created () {
|
||||
|
@ -11,47 +11,29 @@
|
||||
<a-descriptions-item label="任务名称">
|
||||
{{ jobInfo.jobName }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="触发类型">
|
||||
<a-tag :color="triggerType[jobInfo.triggerType].color">
|
||||
{{ triggerType[jobInfo.triggerType].name }}
|
||||
<a-descriptions-item label="重试状态">
|
||||
<a-tag :color="jobStatusEnum[jobInfo.jobStatus].color">
|
||||
{{ jobStatusEnum[jobInfo.jobStatus].name }}
|
||||
</a-tag>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="间隔时长">
|
||||
{{ jobInfo.triggerInterval }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="最大重试次数">
|
||||
{{ jobInfo.maxRetryTimes }}次
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="重试间隔">
|
||||
{{ jobInfo.retryInterval }}(秒)
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="并行数">
|
||||
{{ jobInfo.parallelNum }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="执行器类型">
|
||||
<a-descriptions-item label="路由策略">
|
||||
<a-tag :color="routeKey[jobInfo.routeKey].color">
|
||||
{{ routeKey[jobInfo.routeKey].name }}
|
||||
</a-tag>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="执行器类型">
|
||||
<a-tag :color="executorType[jobInfo.executorType].color">
|
||||
{{ executorType[jobInfo.executorType].name }}
|
||||
</a-tag>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="任务类型">
|
||||
<a-tag :color="taskType[jobInfo.taskType].color">
|
||||
{{ taskType[jobInfo.taskType].name }}
|
||||
</a-tag>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="阻塞策略">
|
||||
<a-tag :color="blockStrategy[jobInfo.blockStrategy].color">
|
||||
{{ blockStrategy[jobInfo.blockStrategy].name }}
|
||||
</a-tag>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="重试状态">
|
||||
<a-tag :color="jobStatusEnum[jobInfo.jobStatus].color">
|
||||
{{ jobStatusEnum[jobInfo.jobStatus].name }}
|
||||
</a-tag>
|
||||
<a-descriptions-item label="并行数">
|
||||
{{ jobInfo.parallelNum }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="最大重试次数">
|
||||
{{ jobInfo.maxRetryTimes }}次
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="重试间隔">
|
||||
{{ jobInfo.retryInterval }}(秒)
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="超时时间">
|
||||
{{ jobInfo.executorTimeout }}(秒)
|
||||
@ -59,16 +41,34 @@
|
||||
<a-descriptions-item label="下次触发时间">
|
||||
{{ jobInfo.nextTriggerAt }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="更新时间">
|
||||
<a-descriptions-item label="更新时间" span="4">
|
||||
{{ jobInfo.updateDt }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="执行器名称" span="3">
|
||||
<a-descriptions-item label="触发类型" span="1">
|
||||
<a-tag :color="triggerType[jobInfo.triggerType].color">
|
||||
{{ triggerType[jobInfo.triggerType].name }}
|
||||
</a-tag>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="间隔时长" span="4">
|
||||
{{ jobInfo.triggerInterval }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="执行器类型">
|
||||
<a-tag :color="executorType[jobInfo.executorType].color">
|
||||
{{ executorType[jobInfo.executorType].name }}
|
||||
</a-tag>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="执行器名称" span="4">
|
||||
{{ jobInfo.executorName }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="参数" span="3">
|
||||
<a-descriptions-item label="任务类型">
|
||||
<a-tag :color="taskType[jobInfo.taskType].color">
|
||||
{{ taskType[jobInfo.taskType].name }}
|
||||
</a-tag>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="参数" span="4">
|
||||
{{ jobInfo.argsStr }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="扩展参数" span="3">
|
||||
<a-descriptions-item label="描述" span="4">
|
||||
{{ jobInfo.extAttrs }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
|
@ -14,40 +14,40 @@
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="8" :sm="24">
|
||||
<a-form-item label="场景名称">
|
||||
<a-select v-model="queryParam.sceneName" placeholder="请选择场景名称" allowClear>
|
||||
<a-select-option v-for="item in sceneList" :value="item.sceneName" :key="item.sceneName">
|
||||
{{ item.sceneName }}</a-select-option
|
||||
>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<!-- <a-col :md="8" :sm="24">-->
|
||||
<!-- <a-form-item label="场景名称">-->
|
||||
<!-- <a-select v-model="queryParam.sceneName" placeholder="请选择场景名称" allowClear>-->
|
||||
<!-- <a-select-option v-for="item in sceneList" :value="item.sceneName" :key="item.sceneName">-->
|
||||
<!-- {{ item.sceneName }}</a-select-option-->
|
||||
<!-- >-->
|
||||
<!-- </a-select>-->
|
||||
<!-- </a-form-item>-->
|
||||
<!-- </a-col>-->
|
||||
<a-col :md="8" :sm="24">
|
||||
<a-form-item label="状态">
|
||||
<a-select v-model="queryParam.jobStatus" placeholder="请选择状态" allowClear>
|
||||
<a-select-option v-for="(index, value) in jobStatus" :value="value" :key="value">
|
||||
<a-select-option v-for="(index, value) in jobStatusEnum" :value="value" :key="value">
|
||||
{{ index.name }}</a-select-option
|
||||
>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<template v-if="advanced">
|
||||
<a-col :md="8" :sm="24">
|
||||
<a-form-item label="业务编号">
|
||||
<a-input v-model="queryParam.bizNo" placeholder="请输入业务编号" allowClear />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="8" :sm="24">
|
||||
<a-form-item label="幂等id">
|
||||
<a-input v-model="queryParam.idempotentId" placeholder="请输入幂等id" allowClear />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="8" :sm="24">
|
||||
<a-form-item label="UniqueId">
|
||||
<a-input v-model="queryParam.uniqueId" placeholder="请输入唯一id" allowClear/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<!-- <a-col :md="8" :sm="24">-->
|
||||
<!-- <a-form-item label="业务编号">-->
|
||||
<!-- <a-input v-model="queryParam.bizNo" placeholder="请输入业务编号" allowClear />-->
|
||||
<!-- </a-form-item>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :md="8" :sm="24">-->
|
||||
<!-- <a-form-item label="幂等id">-->
|
||||
<!-- <a-input v-model="queryParam.idempotentId" placeholder="请输入幂等id" allowClear />-->
|
||||
<!-- </a-form-item>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :md="8" :sm="24">-->
|
||||
<!-- <a-form-item label="UniqueId">-->
|
||||
<!-- <a-input v-model="queryParam.uniqueId" placeholder="请输入唯一id" allowClear/>-->
|
||||
<!-- </a-form-item>-->
|
||||
<!-- </a-col>-->
|
||||
</template>
|
||||
<a-col :md="(!advanced && 8) || 24" :sm="24">
|
||||
<span
|
||||
@ -70,10 +70,9 @@
|
||||
<!-- <a-button type="primary" icon="plus" @click="handleBatchNew()">批量</a-button>-->
|
||||
<a-dropdown v-action:edit v-if="selectedRowKeys.length > 0">
|
||||
<a-menu slot="overlay" @click="onClick">
|
||||
<a-menu-item key="1"><a-icon type="delete" />删除</a-menu-item>
|
||||
<a-menu-item key="2"><a-icon type="edit" />更新</a-menu-item>
|
||||
<!-- <a-menu-item key="1"><a-icon type="delete" />删除</a-menu-item>-->
|
||||
</a-menu>
|
||||
<a-button style="margin-left: 8px"> 批量操作 <a-icon type="down" /> </a-button>
|
||||
<!-- <a-button style="margin-left: 8px"> 批量操作 <a-icon type="down" /> </a-button>-->
|
||||
</a-dropdown>
|
||||
</div>
|
||||
|
||||
@ -83,8 +82,6 @@
|
||||
:rowKey="(record) => record.id"
|
||||
:columns="columns"
|
||||
:data="loadData"
|
||||
:alert="options.alert"
|
||||
:rowSelection="options.rowSelection"
|
||||
>
|
||||
<span slot="serial" slot-scope="text, record">
|
||||
{{ record.id }}
|
||||
@ -119,40 +116,33 @@
|
||||
<template>
|
||||
<a @click="handleInfo(record)">详情</a>
|
||||
<a-divider type="vertical" />
|
||||
<a @click="handleEdit(record)">编辑</a>
|
||||
<a-divider type="vertical" />
|
||||
<a-popconfirm
|
||||
title="是否暂停?"
|
||||
ok-text="恢复"
|
||||
title="是否关闭?"
|
||||
ok-text="关闭"
|
||||
cancel-text="取消"
|
||||
@confirm="handleSuspend(record)"
|
||||
@confirm="handleClose(record)"
|
||||
>
|
||||
<a href="javascript:;" v-if="record.retryStatus === 0">暂停</a>
|
||||
<a href="javascript:;" v-if="record.jobStatus === 1">关闭</a>
|
||||
</a-popconfirm>
|
||||
<a-divider type="vertical" v-if="record.retryStatus === 0" />
|
||||
<a-divider type="vertical" v-if="record.jobStatus === 1" />
|
||||
<a-popconfirm
|
||||
title="是否恢复?"
|
||||
ok-text="恢复"
|
||||
title="是否开启?"
|
||||
ok-text="开启"
|
||||
cancel-text="取消"
|
||||
@confirm="handleRecovery(record)"
|
||||
@confirm="handleOpen(record)"
|
||||
>
|
||||
<a href="javascript:;" v-if="record.retryStatus === 3">恢复</a>
|
||||
<a href="javascript:;" v-if="record.jobStatus === 0">开启</a>
|
||||
</a-popconfirm>
|
||||
<a-divider type="vertical" v-if="record.retryStatus === 3" />
|
||||
<a-divider type="vertical" v-if="record.jobStatus === 0" />
|
||||
<a-popconfirm
|
||||
title="是否完成?"
|
||||
ok-text="完成"
|
||||
title="是否删除任务?"
|
||||
ok-text="删除"
|
||||
cancel-text="取消"
|
||||
@confirm="handleFinish(record)"
|
||||
@confirm="handleDel(record)"
|
||||
>
|
||||
<a href="javascript:;" v-if="record.retryStatus !== 1 && record.retryStatus !== 2">完成</a>
|
||||
</a-popconfirm>
|
||||
<a-divider type="vertical" v-if="record.retryStatus !== 1 && record.retryStatus !== 2" />
|
||||
<a-popconfirm
|
||||
title="是否执行任务?"
|
||||
ok-text="执行"
|
||||
cancel-text="取消"
|
||||
@confirm="handleTrigger(record)"
|
||||
>
|
||||
<a href="javascript:;" v-if="record.retryStatus !== 1 && record.retryStatus !== 2">执行</a>
|
||||
<a href="javascript:;" v-if="record.jobStatus === 0">删除</a>
|
||||
</a-popconfirm>
|
||||
|
||||
</template>
|
||||
@ -166,7 +156,7 @@
|
||||
import ATextarea from 'ant-design-vue/es/input/TextArea'
|
||||
import AInput from 'ant-design-vue/es/input/Input'
|
||||
import { STable } from '@/components'
|
||||
import { getJobList } from '@/api/jobApi'
|
||||
import { delJob, getJobList, updateJobStatus } from '@/api/jobApi'
|
||||
import { getAllGroupNameList } from '@/api/manage'
|
||||
import enums from '@/utils/enum'
|
||||
|
||||
@ -293,11 +283,11 @@ export default {
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
handleNew () {
|
||||
this.$refs.saveRetryTask.isShow(true, null)
|
||||
handleEdit (record) {
|
||||
this.$router.push({ path: '/job/config', query: { id: record.id } })
|
||||
},
|
||||
handleBatchNew () {
|
||||
this.$refs.batchSaveRetryTask.isShow(true, null)
|
||||
handleNew () {
|
||||
this.$router.push({ path: '/job/config' })
|
||||
},
|
||||
handleChange (value) {
|
||||
},
|
||||
@ -308,61 +298,38 @@ export default {
|
||||
this.$router.push({ path: '/job/info', query: { id: record.id, groupName: record.groupName } })
|
||||
},
|
||||
handleOk (record) {},
|
||||
handleSuspend (record) {
|
||||
// updateRetryTaskStatus({ id: record.id, groupName: record.groupName, retryStatus: 3 }).then((res) => {
|
||||
// const { status } = res
|
||||
// if (status === 0) {
|
||||
// this.$message.error('暂停失败')
|
||||
// } else {
|
||||
// this.$refs.table.refresh(true)
|
||||
// this.$message.success('暂停成功')
|
||||
// }
|
||||
// })
|
||||
handleClose (record) {
|
||||
updateJobStatus({ id: record.id, jobStatus: 0 }).then((res) => {
|
||||
const { status } = res
|
||||
if (status === 0) {
|
||||
this.$message.error('关闭失败')
|
||||
} else {
|
||||
this.$refs.table.refresh(true)
|
||||
this.$message.success('关闭成功')
|
||||
}
|
||||
})
|
||||
},
|
||||
handleRecovery (record) {
|
||||
// updateRetryTaskStatus({ id: record.id, groupName: record.groupName, retryStatus: 0 }).then((res) => {
|
||||
// const { status } = res
|
||||
// if (status === 0) {
|
||||
// this.$message.error('恢复失败')
|
||||
// } else {
|
||||
// this.$refs.table.refresh(true)
|
||||
// this.$message.success('恢复成功')
|
||||
// }
|
||||
// })
|
||||
handleOpen (record) {
|
||||
updateJobStatus({ id: record.id, jobStatus: 1 }).then((res) => {
|
||||
const { status } = res
|
||||
if (status === 0) {
|
||||
this.$message.error('开启失败')
|
||||
} else {
|
||||
this.$refs.table.refresh(true)
|
||||
this.$message.success('开启成功')
|
||||
}
|
||||
})
|
||||
},
|
||||
handleFinish (record) {
|
||||
// updateRetryTaskStatus({ id: record.id, groupName: record.groupName, retryStatus: 1 }).then((res) => {
|
||||
// const { status } = res
|
||||
// if (status === 0) {
|
||||
// this.$message.error('执行失败')
|
||||
// } else {
|
||||
// this.$refs.table.refresh(true)
|
||||
// this.$message.success('执行成功')
|
||||
// }
|
||||
// })
|
||||
},
|
||||
handleTrigger (record) {
|
||||
// if (record.taskType === 1) {
|
||||
// manualTriggerRetryTask({ groupName: record.groupName, uniqueIds: [ record.uniqueId ] }).then(res => {
|
||||
// const { status } = res
|
||||
// if (status === 0) {
|
||||
// this.$message.error('执行失败')
|
||||
// } else {
|
||||
// this.$refs.table.refresh(true)
|
||||
// this.$message.success('执行成功')
|
||||
// }
|
||||
// })
|
||||
// } else {
|
||||
// manualTriggerCallbackTask({ groupName: record.groupName, uniqueIds: [ record.uniqueId ] }).then(res => {
|
||||
// const { status } = res
|
||||
// if (status === 0) {
|
||||
// this.$message.error('执行失败')
|
||||
// } else {
|
||||
// this.$refs.table.refresh(true)
|
||||
// this.$message.success('执行完成')
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
handleDel (record) {
|
||||
delJob(record.id).then((res) => {
|
||||
const { status } = res
|
||||
if (status === 0) {
|
||||
this.$message.error('删除失败')
|
||||
} else {
|
||||
this.$refs.table.refresh(true)
|
||||
this.$message.success('删除成功')
|
||||
}
|
||||
})
|
||||
},
|
||||
refreshTable (v) {
|
||||
this.$refs.table.refresh(true)
|
||||
@ -371,23 +338,6 @@ export default {
|
||||
this.selectedRowKeys = selectedRowKeys
|
||||
this.selectedRows = selectedRows
|
||||
},
|
||||
handlerDel () {
|
||||
// var that = this
|
||||
// this.$confirm({
|
||||
// title: '您要删除这些数据吗?',
|
||||
// content: h => <div style="color:red;">删除后数据不可恢复,请确认!</div>,
|
||||
// onOk () {
|
||||
// batchDelete({ groupName: that.selectedRows[0].groupName, ids: that.selectedRowKeys }).then(res => {
|
||||
// that.$refs.table.refresh(true)
|
||||
// that.$message.success(`成功删除${res.data}条数据`)
|
||||
// that.selectedRowKeys = []
|
||||
// })
|
||||
// },
|
||||
// onCancel () {
|
||||
// },
|
||||
// class: 'test'
|
||||
// })
|
||||
},
|
||||
onClick ({ key }) {
|
||||
if (key === '2') {
|
||||
this.$refs.batchUpdateRetryTaskInfo.isShow(true, this.selectedRows, this.selectedRowKeys)
|
||||
|
@ -66,6 +66,19 @@ export default {
|
||||
total: 0
|
||||
}
|
||||
},
|
||||
created () {
|
||||
const taskBatchId = this.$route.query.taskBatchId
|
||||
const jobId = this.$route.query.jobId
|
||||
if (taskBatchId && jobId) {
|
||||
this.queryParam = {
|
||||
taskBatchId: taskBatchId,
|
||||
jobId: jobId
|
||||
}
|
||||
this.$refs.table.refresh(true)
|
||||
} else {
|
||||
this.$router.push({ path: '/404' })
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
refreshTable (v) {
|
||||
this.queryParam = v
|
||||
|
476
frontend/src/views/job/from/JobFrom.vue
Normal file
476
frontend/src/views/job/from/JobFrom.vue
Normal file
@ -0,0 +1,476 @@
|
||||
<template>
|
||||
<div>
|
||||
<page-header-wrapper content="定时任务配置" @back="() => $router.go(-1)" style="margin: -24px -1px 0">
|
||||
<div></div>
|
||||
</page-header-wrapper>
|
||||
<a-card :body-style="{padding: '24px 32px'}" :bordered="false" :loading="loading">
|
||||
<a-form @submit="handleSubmit" :form="form" class="form-row" layout="vertical" style="width: 35%;margin: auto;">
|
||||
<a-row class="form-row" :gutter="16">
|
||||
<a-col :lg="24" :md="24" :sm="24">
|
||||
<a-form-item>
|
||||
<a-input
|
||||
hidden
|
||||
v-decorator="['id']" />
|
||||
</a-form-item>
|
||||
<a-form-item label="任务名称" >
|
||||
<a-input
|
||||
placeholder="请输入任务名称"
|
||||
:maxLength="64"
|
||||
v-decorator="[
|
||||
'jobName',
|
||||
{rules: [{ required: true, message: '请输入任务名称', whitespace: true},{required: true, max: 64, message: '最多支持64个字符!'}]}
|
||||
]" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row class="form-row" :gutter="16">
|
||||
<a-col :lg="18" :md="18" :sm="24">
|
||||
<a-form-item label="组">
|
||||
<a-select
|
||||
placeholder="请选择组"
|
||||
v-decorator="['groupName', { rules: [{ required: true, message: '请选择组' }] }]"
|
||||
>
|
||||
<a-select-option v-for="item in groupNameList" :value="item" :key="item">{{ item }}</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item label="状态">
|
||||
<a-select
|
||||
placeholder="请选择状态"
|
||||
v-decorator="[
|
||||
'jobStatus',
|
||||
{
|
||||
initialValue: '1',
|
||||
rules: [{ required: true, message: '请选择状态'}]
|
||||
}
|
||||
]" >
|
||||
<a-select-option :value="index" v-for="(item, index) in jobStatusEnum" :key="index">{{ item.name }}</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row class="form-row" :gutter="16">
|
||||
<a-col :lg="12" :md="12" :sm="24">
|
||||
<a-form-item label="路由策略">
|
||||
<a-select
|
||||
placeholder="请选择路由策略"
|
||||
v-decorator="[
|
||||
'routeKey',
|
||||
{
|
||||
initialValue: '4',
|
||||
rules: [{ required: true, message: '请选择路由策略'}]
|
||||
}
|
||||
]" >
|
||||
<a-select-option :value="index" v-for="(item, index) in routeKey" :key="index">{{ item.name }}</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="12" :md="12" :sm="24">
|
||||
<a-form-item label="阻塞策略">
|
||||
<a-select
|
||||
placeholder="请选择阻塞策略"
|
||||
v-decorator="[
|
||||
'blockStrategy',
|
||||
{
|
||||
initialValue: '1',
|
||||
rules: [{ required: true, message: '请选择阻塞策略'}]
|
||||
}
|
||||
]" >
|
||||
<a-select-option :value="index" v-for="(item, index) in blockStrategy" :key="index">{{ item.name }}</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row class="form-row" :gutter="16">
|
||||
<a-col :lg="8" :md="12" :sm="12">
|
||||
<a-form-item label="触发类型">
|
||||
<a-select
|
||||
placeholder="请选择触发类型"
|
||||
v-decorator="[
|
||||
'triggerType',
|
||||
{
|
||||
initialValue: '2',
|
||||
rules: [{ required: true, message: '请选择触发类型'}]
|
||||
}
|
||||
]" >
|
||||
<a-select-option :value="index" v-for="(item, index) in triggerType" :key="index">{{ item.name }}</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="16" :md="12" :sm="12">
|
||||
<a-form-item label="间隔时长">
|
||||
<a-input
|
||||
placeholder="请输入间隔时长"
|
||||
v-decorator="[
|
||||
'triggerInterval',
|
||||
{rules: [{ required: true, message: '请输入间隔时长', whitespace: true}]}
|
||||
]" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row class="form-row" :gutter="16">
|
||||
<a-col :lg="8" :md="6" :sm="12">
|
||||
<a-form-item label="执行器类型">
|
||||
<a-select
|
||||
placeholder="请选择执行器类型"
|
||||
v-decorator="[
|
||||
'executorType',
|
||||
{
|
||||
initialValue: '1',
|
||||
rules: [{ required: true, message: '请选择执行器类型'}]
|
||||
}
|
||||
]" >
|
||||
<a-select-option :value="index" v-for="(item, index) in executorType" :key="index">{{ item.name }}</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="16" :md="24" :sm="24">
|
||||
<a-form-item label="执行器名称">
|
||||
<a-input
|
||||
placeholder="请输入执行器名称"
|
||||
type="textarea"
|
||||
:rows="1"
|
||||
v-decorator="[
|
||||
'executorName',
|
||||
{rules: [{ required: true, message: '请输入执行器名称', whitespace: true}]}
|
||||
]" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row class="form-row" :gutter="16">
|
||||
<a-col :lg="8" :md="12" :sm="24">
|
||||
<a-form-item label="任务类型">
|
||||
<a-select
|
||||
placeholder="请选择任务类型"
|
||||
v-decorator="[
|
||||
'taskType',
|
||||
{
|
||||
initialValue: '1',
|
||||
rules: [{ required: true, message: '请选择任务类型'}]
|
||||
}
|
||||
]" >
|
||||
<a-select-option :value="index" v-for="(item, index) in taskType" :key="index">{{ item.name }}</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="16" :md="24" :sm="24">
|
||||
<a-form-item label="方法参数">
|
||||
<a-input
|
||||
placeholder="请输入方法参数"
|
||||
type="textarea"
|
||||
:rows="1"
|
||||
@click="handleBlur"
|
||||
v-decorator="[
|
||||
'argsStr',
|
||||
{rules: [{ required: true, message: '请输入方法参数', whitespace: true}]}
|
||||
]" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row class="form-row" :gutter="16">
|
||||
<a-col :lg="6" :md="12" :sm="12">
|
||||
<a-form-item label="超时时间(秒)">
|
||||
<a-input-number
|
||||
id="inputNumber"
|
||||
:min="1"
|
||||
:max="36000"
|
||||
v-decorator="[
|
||||
'executorTimeout',
|
||||
{
|
||||
initialValue: '60',
|
||||
rules: [{ required: true, message: '请输入超时时间'}]
|
||||
}
|
||||
]" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="12" :sm="12">
|
||||
<a-form-item label="最大重试次数">
|
||||
<a-input-number
|
||||
:min="1"
|
||||
v-decorator="[
|
||||
'maxRetryTimes',
|
||||
{
|
||||
initialValue: '3',
|
||||
rules: [{ required: true, message: '请输入最大重试次数'}]
|
||||
}
|
||||
]" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="12" :sm="12">
|
||||
<a-form-item label="重试间隔(秒)">
|
||||
<a-input-number
|
||||
:min="1"
|
||||
v-decorator="[
|
||||
'retryInterval',
|
||||
{
|
||||
initialValue: '1',
|
||||
rules: [{ required: true, message: '请输入重试间隔'
|
||||
}]
|
||||
}
|
||||
]" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="6" :sm="12">
|
||||
<a-form-item label="并行数">
|
||||
<a-input-number
|
||||
:min="1"
|
||||
v-decorator="[
|
||||
'parallelNum',
|
||||
{
|
||||
initialValue: '1',
|
||||
rules: [{ required: true, message: '请输入并行数'}]
|
||||
}
|
||||
]" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row class="form-row" :gutter="16">
|
||||
</a-row>
|
||||
<a-row class="form-row" :gutter="16">
|
||||
<a-col :lg="24" :md="24" :sm="24">
|
||||
<a-form-item label="描述">
|
||||
<a-input
|
||||
placeholder="请输入描述"
|
||||
type="textarea"
|
||||
v-decorator="[
|
||||
'description',
|
||||
{rules: [{required: false, max: 256, message: '最多支持256个字符!'}]}
|
||||
]" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-form-item
|
||||
:wrapperCol="{ span: 24 }"
|
||||
style="text-align: center"
|
||||
>
|
||||
<a-button htmlType="submit" type="primary">提交</a-button>
|
||||
<a-button style="margin-left: 8px">重置</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-card>
|
||||
|
||||
<a-modal :visible="visible" title="添加配置" @ok="handleOk" @cancel="handlerCancel" width="500px">
|
||||
<a-form :form="dynamicForm" @submit="handleSubmit" :body-style="{padding: '0px 0px'}" v-bind="formItemLayout" >
|
||||
<a-form-item
|
||||
v-for="(k, index) in dynamicForm.getFieldValue('keys')"
|
||||
:key="k"
|
||||
v-bind="formItemLayoutWithOutLabel"
|
||||
:label="'分片' + index "
|
||||
:required="true"
|
||||
>
|
||||
<a-input
|
||||
v-decorator="[
|
||||
`sharding[${k}]`,
|
||||
{
|
||||
validateTrigger: ['change', 'blur'],
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
whitespace: true,
|
||||
message: '分片参数必填',
|
||||
},
|
||||
],
|
||||
},
|
||||
]"
|
||||
placeholder="请输入参数"
|
||||
style="width: 60%; margin-right: 8px"
|
||||
/>
|
||||
<a-icon
|
||||
v-if="dynamicForm.getFieldValue('keys').length > 1"
|
||||
class="dynamic-delete-button"
|
||||
type="minus-circle-o"
|
||||
:disabled="dynamicForm.getFieldValue('keys').length === 1"
|
||||
@click="() => remove(k)"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item v-bind="formItemLayoutWithOutLabel">
|
||||
<a-button type="dashed" style="width: 60%" @click="add">
|
||||
<a-icon type="plus" /> 添加分片
|
||||
</a-button>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
:wrapper-col="{
|
||||
xs: { span: 24, offset: 0 },
|
||||
sm: { span: 16, offset: 8 },
|
||||
lg: { span: 7 }
|
||||
}">
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getAllGroupNameList } from '@/api/manage'
|
||||
import { getJobDetail, saveJob, updateJob } from '@/api/jobApi'
|
||||
import pick from 'lodash.pick'
|
||||
const enums = require('@/utils/enum')
|
||||
let id = 0
|
||||
export default {
|
||||
name: 'JobFrom',
|
||||
props: {},
|
||||
data () {
|
||||
return {
|
||||
form: this.$form.createForm(this),
|
||||
formItemLayout: {
|
||||
labelCol: { lg: { span: 7 }, sm: { span: 7 } },
|
||||
wrapperCol: { lg: { span: 10 }, sm: { span: 17 } }
|
||||
},
|
||||
formItemLayoutWithOutLabel: {
|
||||
wrapperCol: {
|
||||
xs: { span: 24, offset: 0 },
|
||||
sm: { span: 20, offset: 4 }
|
||||
}
|
||||
},
|
||||
formType: 'create',
|
||||
groupNameList: [],
|
||||
jobStatusEnum: enums.jobStatusEnum,
|
||||
taskType: enums.taskType,
|
||||
triggerType: enums.triggerType,
|
||||
blockStrategy: enums.blockStrategy,
|
||||
executorType: enums.executorType,
|
||||
routeKey: enums.routeKey,
|
||||
loading: false,
|
||||
visible: false
|
||||
}
|
||||
},
|
||||
beforeCreate () {
|
||||
console.log('beforeCreate')
|
||||
this.dynamicForm = this.$form.createForm(this, { name: 'dynamic_form_item' })
|
||||
this.dynamicForm.getFieldDecorator('keys', { initialValue: [], preserve: true })
|
||||
},
|
||||
mounted () {
|
||||
getAllGroupNameList().then((res) => {
|
||||
this.groupNameList = res.data
|
||||
})
|
||||
|
||||
this.$nextTick(() => {
|
||||
const id = this.$route.query.id
|
||||
if (id) {
|
||||
this.loading = true
|
||||
getJobDetail(id).then(res => {
|
||||
this.loadEditInfo(res.data)
|
||||
this.loading = false
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
remove (k) {
|
||||
const { dynamicForm } = this
|
||||
// can use data-binding to get
|
||||
const keys = dynamicForm.getFieldValue('keys')
|
||||
// We need at least one passenger
|
||||
if (keys.length === 1) {
|
||||
return
|
||||
}
|
||||
|
||||
// can use data-binding to set
|
||||
dynamicForm.setFieldsValue({
|
||||
keys: keys.filter(key => key !== k)
|
||||
})
|
||||
},
|
||||
|
||||
add () {
|
||||
const { dynamicForm } = this
|
||||
// can use data-binding to get
|
||||
const keys = dynamicForm.getFieldValue('keys')
|
||||
console.log(keys)
|
||||
const nextKeys = keys.concat(id++)
|
||||
// can use data-binding to set
|
||||
// important! notify form to detect changes
|
||||
dynamicForm.setFieldsValue({
|
||||
keys: nextKeys
|
||||
})
|
||||
},
|
||||
handleBlur () {
|
||||
const taskType = this.form.getFieldValue('taskType')
|
||||
if (taskType === '3') {
|
||||
this.visible = !this.visible
|
||||
|
||||
if (this.formType === 'create') {
|
||||
return
|
||||
}
|
||||
|
||||
const argsStr = this.form.getFieldValue('argsStr')
|
||||
|
||||
// 将字符串分割成键值对数组
|
||||
const keyValuePairs = argsStr.split(';')
|
||||
console.log(keyValuePairs)
|
||||
const restoredArray = keyValuePairs.map(pair => {
|
||||
const [index, value] = pair.split('=')
|
||||
console.log(value)
|
||||
id++
|
||||
return Number.parseInt(index)
|
||||
})
|
||||
|
||||
this.dynamicForm.getFieldDecorator('keys', { initialValue: restoredArray, preserve: true })
|
||||
|
||||
keyValuePairs.map(pair => {
|
||||
const [index, value] = pair.split('=')
|
||||
this.dynamicForm.getFieldDecorator(`sharding[${index}]`, { initialValue: value, preserve: true })
|
||||
return value
|
||||
})
|
||||
}
|
||||
},
|
||||
handleOk (e) {
|
||||
const { form } = this
|
||||
e.preventDefault()
|
||||
this.dynamicForm.validateFields((err, values) => {
|
||||
console.log()
|
||||
if (!err) {
|
||||
console.log(values)
|
||||
const arr = values['sharding']
|
||||
const formattedString = arr.map((item, index) => `${index}=${item}`).join(';')
|
||||
form.setFieldsValue({
|
||||
argsStr: formattedString
|
||||
})
|
||||
this.visible = false
|
||||
}
|
||||
})
|
||||
},
|
||||
handlerCancel () {
|
||||
this.visible = false
|
||||
},
|
||||
handleSubmit (e) {
|
||||
e.preventDefault()
|
||||
this.form.validateFields((err, values) => {
|
||||
if (!err) {
|
||||
if (this.formType === 'create') {
|
||||
saveJob(values).then(res => {
|
||||
this.$message.success('任务新增完成')
|
||||
this.form.resetFields()
|
||||
this.$router.go(-1)
|
||||
})
|
||||
} else {
|
||||
updateJob(values).then(res => {
|
||||
this.$message.success('任务更新完成')
|
||||
this.form.resetFields()
|
||||
this.$router.go(-1)
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
loadEditInfo (data) {
|
||||
this.formType = 'edit'
|
||||
const { form } = this
|
||||
// ajax
|
||||
new Promise((resolve) => {
|
||||
setTimeout(resolve, 100)
|
||||
}).then(() => {
|
||||
const formData = pick(data, [
|
||||
'id', 'jobName', 'groupName', 'jobStatus', 'executorName', 'argsStr', 'executorTimeout', 'description',
|
||||
'maxRetryTimes', 'parallelNum', 'retryInterval', 'triggerType', 'blockStrategy', 'executorType', 'taskType', 'triggerInterval'])
|
||||
formData.jobStatus = formData.jobStatus.toString()
|
||||
formData.taskType = formData.taskType.toString()
|
||||
formData.executorType = formData.executorType.toString()
|
||||
formData.blockStrategy = formData.blockStrategy.toString()
|
||||
formData.triggerType = formData.triggerType.toString()
|
||||
form.setFieldsValue(formData)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
Loading…
Reference in New Issue
Block a user