feat:2.4.0
1. 完成的控制台的日志 任务 批次列表页和详情页部分内容
This commit is contained in:
parent
8a6d16b44b
commit
b3c4cd92c1
@ -35,8 +35,6 @@ public enum JobTaskStatusEnum {
|
||||
* 任务停止
|
||||
*/
|
||||
STOP(5),
|
||||
|
||||
|
||||
;
|
||||
|
||||
private final int status;
|
||||
|
@ -8,7 +8,8 @@
|
||||
<result column="group_name" property="groupName" />
|
||||
<result column="job_id" property="jobId" />
|
||||
<result column="task_id" property="taskId" />
|
||||
<result column="task_instance_id" property="taskInstanceId" />
|
||||
<result column="client_address" property="clientAddress"/>
|
||||
<result column="task_batch_id" property="taskBatchId" />
|
||||
<result column="create_dt" property="createDt" />
|
||||
<result column="message" property="message" />
|
||||
</resultMap>
|
||||
|
@ -18,7 +18,6 @@ import java.util.Objects;
|
||||
public class RequestBuilder<T, R> {
|
||||
|
||||
private Class<T> clintInterface;
|
||||
private String groupName;
|
||||
private RegisterNodeInfo nodeInfo;
|
||||
private boolean failRetry;
|
||||
private int retryTimes = 3;
|
||||
@ -43,10 +42,10 @@ public class RequestBuilder<T, R> {
|
||||
return this;
|
||||
}
|
||||
|
||||
public RequestBuilder<T, R> groupName(String groupName) {
|
||||
this.groupName = groupName;
|
||||
return this;
|
||||
}
|
||||
// public RequestBuilder<T, R> groupName(String groupName) {
|
||||
// this.groupName = groupName;
|
||||
// return this;
|
||||
// }
|
||||
|
||||
public RequestBuilder<T, R> failRetry(boolean failRetry) {
|
||||
this.failRetry = failRetry;
|
||||
@ -68,7 +67,7 @@ public class RequestBuilder<T, R> {
|
||||
return this;
|
||||
}
|
||||
|
||||
public RequestBuilder<T, R> allocKey(boolean failover) {
|
||||
public RequestBuilder<T, R> failover(boolean failover) {
|
||||
this.failover = failover;
|
||||
return this;
|
||||
}
|
||||
@ -89,7 +88,6 @@ public class RequestBuilder<T, R> {
|
||||
throw new EasyRetryServerException("clintInterface cannot be null");
|
||||
}
|
||||
|
||||
Assert.notBlank(groupName, () -> new EasyRetryServerException("groupName cannot be null"));
|
||||
Assert.notNull(nodeInfo, () -> new EasyRetryServerException("nodeInfo cannot be null"));
|
||||
|
||||
if (failover) {
|
||||
@ -103,7 +101,7 @@ public class RequestBuilder<T, R> {
|
||||
}
|
||||
|
||||
RpcClientInvokeHandler clientInvokeHandler = new RpcClientInvokeHandler(
|
||||
groupName, nodeInfo, failRetry, retryTimes, retryInterval, retryListener, routeKey, allocKey, failover);
|
||||
nodeInfo.getGroupName(), nodeInfo, failRetry, retryTimes, retryInterval, retryListener, routeKey, allocKey, failover);
|
||||
|
||||
return (T) Proxy.newProxyInstance(clintInterface.getClassLoader(),
|
||||
new Class[]{clintInterface}, clientInvokeHandler);
|
||||
|
@ -65,13 +65,18 @@ public interface JobTaskConverter {
|
||||
DispatchJobRequest toDispatchJobRequest(RealJobExecutorDTO realJobExecutorDTO);
|
||||
|
||||
@Mappings({
|
||||
@Mapping(source = "job.groupName", target = "groupName"),
|
||||
@Mapping(source = "jobTask.groupName", target = "groupName"),
|
||||
@Mapping(source = "jobTask.jobId", target = "jobId"),
|
||||
@Mapping(source = "jobTask.taskBatchId", target = "taskBatchId"),
|
||||
@Mapping(source = "jobTask.clientId", target = "clientId"),
|
||||
@Mapping(source = "jobTask.id", target = "taskId"),
|
||||
@Mapping(source = "jobTask.argsStr", target = "argsStr"),
|
||||
@Mapping(source = "jobTask.argsType", target = "argsType"),
|
||||
@Mapping(source = "jobTask.extAttrs", target = "extAttrs")
|
||||
})
|
||||
RealJobExecutorDTO toRealJobExecutorDTO(Job job, JobTask jobTask);
|
||||
RealJobExecutorDTO toRealJobExecutorDTO(JobExecutorContext context, JobTask jobTask);
|
||||
|
||||
JobExecutorContext toJobExecutorContext(Job job);
|
||||
|
||||
JobExecutorResultDTO toJobExecutorResultDTO(ClientCallbackContext context);
|
||||
|
||||
|
@ -5,6 +5,7 @@ import com.aizuda.easy.retry.common.core.log.LogUtils;
|
||||
import com.aizuda.easy.retry.server.common.akka.ActorGenerator;
|
||||
import com.aizuda.easy.retry.server.job.task.dto.TaskExecuteDTO;
|
||||
import com.aizuda.easy.retry.server.job.task.support.JobExecutor;
|
||||
import com.aizuda.easy.retry.server.job.task.support.JobTaskConverter;
|
||||
import com.aizuda.easy.retry.server.job.task.support.executor.JobExecutorContext;
|
||||
import com.aizuda.easy.retry.server.job.task.support.executor.JobExecutorFactory;
|
||||
import com.aizuda.easy.retry.template.datasource.persistence.mapper.JobMapper;
|
||||
@ -44,12 +45,10 @@ public class JobExecutorActor extends AbstractActor {
|
||||
Job job = jobMapper.selectById(taskExecute.getJobId());
|
||||
JobExecutor jobExecutor = JobExecutorFactory.getJobExecutor(job.getTaskType());
|
||||
|
||||
JobExecutorContext context = new JobExecutorContext();
|
||||
JobExecutorContext context = JobTaskConverter.INSTANCE.toJobExecutorContext(job);
|
||||
context.setTaskBatchId(taskExecute.getTaskBatchId());
|
||||
context.setGroupName(taskExecute.getGroupName());
|
||||
context.setJobId(job.getId());
|
||||
context.setTaskType(job.getTaskType());
|
||||
context.setJob(job);
|
||||
jobExecutor.execute(context);
|
||||
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ public class JobLogActor extends AbstractActor {
|
||||
JobLogMessage jobLogMessage = JobTaskConverter.INSTANCE.toJobLogMessage(jobLogDTO);
|
||||
if (Objects.nonNull(jobLogDTO.getClientId())) {
|
||||
Optional.ofNullable(CacheRegisterTable.getServerNode(jobLogDTO.getGroupName(), jobLogDTO.getClientId())).ifPresent(registerNodeInfo -> {
|
||||
jobLogMessage.setClientAddress(registerNodeInfo.fullUrl());
|
||||
jobLogMessage.setClientAddress(registerNodeInfo.address());
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -29,11 +29,10 @@ public class BroadcastTaskJobExecutor extends AbstractJobExecutor {
|
||||
@Override
|
||||
protected void doExecute(JobExecutorContext context) {
|
||||
|
||||
Job job = context.getJob();
|
||||
List<JobTask> taskList = context.getTaskList();
|
||||
|
||||
for (JobTask jobTask : taskList) {
|
||||
RealJobExecutorDTO realJobExecutor = JobTaskConverter.INSTANCE.toRealJobExecutorDTO(job, jobTask);
|
||||
RealJobExecutorDTO realJobExecutor = JobTaskConverter.INSTANCE.toRealJobExecutorDTO(context, jobTask);
|
||||
ActorRef actorRef = ActorGenerator.jobRealTaskExecutorActor();
|
||||
actorRef.tell(realJobExecutor, actorRef);
|
||||
}
|
||||
|
@ -31,9 +31,8 @@ public class ClusterJobExecutor extends AbstractJobExecutor {
|
||||
protected void doExecute(JobExecutorContext context) {
|
||||
|
||||
// 调度客户端
|
||||
Job job = context.getJob();
|
||||
List<JobTask> taskList = context.getTaskList();
|
||||
RealJobExecutorDTO realJobExecutor = JobTaskConverter.INSTANCE.toRealJobExecutorDTO(job, taskList.get(0));
|
||||
RealJobExecutorDTO realJobExecutor = JobTaskConverter.INSTANCE.toRealJobExecutorDTO(context, taskList.get(0));
|
||||
ActorRef actorRef = ActorGenerator.jobRealTaskExecutorActor();
|
||||
actorRef.tell(realJobExecutor, actorRef);
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
package com.aizuda.easy.retry.server.job.task.support.executor;
|
||||
|
||||
import com.aizuda.easy.retry.template.datasource.persistence.po.Job;
|
||||
import com.aizuda.easy.retry.template.datasource.persistence.po.JobTask;
|
||||
import lombok.Data;
|
||||
|
||||
@ -48,4 +47,37 @@ public class JobExecutorContext {
|
||||
|
||||
private Integer routeKey;
|
||||
|
||||
/**
|
||||
* 扩展字段
|
||||
*/
|
||||
private String extAttrs;
|
||||
|
||||
|
||||
|
||||
private Long taskId;
|
||||
|
||||
|
||||
private Integer parallelNum;
|
||||
|
||||
private Integer executorType;
|
||||
|
||||
private String executorName;
|
||||
|
||||
private String clientId;
|
||||
|
||||
/**
|
||||
* 最大重试次数
|
||||
*/
|
||||
private Integer maxRetryTimes;
|
||||
|
||||
/**
|
||||
* 重试间隔(s)
|
||||
*/
|
||||
private Integer retryInterval;
|
||||
|
||||
private Integer shardingTotal;
|
||||
|
||||
private Integer shardingIndex;
|
||||
|
||||
private Integer executorTimeout;
|
||||
}
|
||||
|
@ -115,7 +115,6 @@ public class RealJobExecutorActor extends AbstractActor {
|
||||
|
||||
private JobRpcClient buildRpcClient(RegisterNodeInfo registerNodeInfo, RealJobExecutorDTO realJobExecutorDTO) {
|
||||
return RequestBuilder.<JobRpcClient, Result>newBuilder()
|
||||
.groupName(registerNodeInfo.getGroupName())
|
||||
.nodeInfo(registerNodeInfo)
|
||||
.failRetry(Boolean.TRUE)
|
||||
.retryTimes(realJobExecutorDTO.getMaxRetryTimes())
|
||||
|
@ -30,10 +30,9 @@ public class ShardingJobExecutor extends AbstractJobExecutor {
|
||||
|
||||
@Override
|
||||
protected void doExecute(JobExecutorContext context) {
|
||||
Job job = context.getJob();
|
||||
List<JobTask> taskList = context.getTaskList();
|
||||
for (int i = 0; i < taskList.size(); i++) {
|
||||
RealJobExecutorDTO realJobExecutor = JobTaskConverter.INSTANCE.toRealJobExecutorDTO(job, taskList.get(i));
|
||||
RealJobExecutorDTO realJobExecutor = JobTaskConverter.INSTANCE.toRealJobExecutorDTO(context, taskList.get(i));
|
||||
realJobExecutor.setShardingIndex(i);
|
||||
realJobExecutor.setShardingTotal(taskList.size());
|
||||
ActorRef actorRef = ActorGenerator.jobRealTaskExecutorActor();
|
||||
|
@ -49,11 +49,7 @@ public class RealStopTaskActor extends AbstractActor {
|
||||
|
||||
private Result<Boolean> requestClient(RealStopTaskInstanceDTO realStopTaskInstanceDTO, RegisterNodeInfo registerNodeInfo) {
|
||||
JobRpcClient rpcClient = RequestBuilder.<JobRpcClient, Result>newBuilder()
|
||||
.hostPort(registerNodeInfo.getHostPort())
|
||||
.groupName(realStopTaskInstanceDTO.getGroupName())
|
||||
.hostId(registerNodeInfo.getHostId())
|
||||
.hostIp(registerNodeInfo.getHostIp())
|
||||
.contextPath(registerNodeInfo.getContextPath())
|
||||
.nodeInfo(registerNodeInfo)
|
||||
.failRetry(Boolean.TRUE)
|
||||
.retryTimes(3)
|
||||
.retryInterval(1)
|
||||
|
@ -22,10 +22,10 @@ import com.aizuda.easy.retry.server.common.client.annotation.Mapping;
|
||||
*/
|
||||
public interface RetryRpcClient {
|
||||
|
||||
@Mapping(path = "/retry/dispatch/v1", method = RequestMethod.POST, failover = true)
|
||||
@Mapping(path = "/retry/dispatch/v1", method = RequestMethod.POST)
|
||||
Result<DispatchRetryResultDTO> dispatch(@Body DispatchRetryDTO dispatchRetryDTO, @Header EasyRetryHeaders headers);
|
||||
|
||||
@Mapping(path = "/retry/callback/v1", method = RequestMethod.POST, failover = true)
|
||||
@Mapping(path = "/retry/callback/v1", method = RequestMethod.POST)
|
||||
Result callback(@Body RetryCallbackDTO retryCallbackDTO);
|
||||
|
||||
@Mapping(path = "/retry/generate/idempotent-id/v1", method = RequestMethod.POST)
|
||||
|
@ -2,6 +2,7 @@ package com.aizuda.easy.retry.server.retry.task.support;
|
||||
|
||||
import com.aizuda.easy.retry.server.common.dto.RegisterNodeInfo;
|
||||
import com.aizuda.easy.retry.template.datasource.persistence.po.RetryTask;
|
||||
import com.aizuda.easy.retry.template.datasource.persistence.po.SceneConfig;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
@ -74,4 +75,10 @@ public interface RetryContext<V> {
|
||||
*/
|
||||
Set<String> getSceneBlacklist();
|
||||
|
||||
/**
|
||||
* 路由策略
|
||||
*
|
||||
* @return 路由策略
|
||||
*/
|
||||
SceneConfig sceneConfig();
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import com.aizuda.easy.retry.server.common.dto.RegisterNodeInfo;
|
||||
import com.aizuda.easy.retry.server.retry.task.support.RetryContext;
|
||||
import com.aizuda.easy.retry.server.retry.task.support.WaitStrategy;
|
||||
import com.aizuda.easy.retry.template.datasource.persistence.po.RetryTask;
|
||||
import com.aizuda.easy.retry.template.datasource.persistence.po.SceneConfig;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Objects;
|
||||
@ -47,9 +48,19 @@ public class CallbackRetryContext<V> implements RetryContext<V> {
|
||||
*/
|
||||
private RegisterNodeInfo serverNode;
|
||||
|
||||
/**
|
||||
* 场景配置
|
||||
*/
|
||||
private SceneConfig sceneConfig;
|
||||
|
||||
@Override
|
||||
public boolean hasException() {
|
||||
return Objects.nonNull(exception);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SceneConfig sceneConfig() {
|
||||
return sceneConfig;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import com.aizuda.easy.retry.server.common.dto.RegisterNodeInfo;
|
||||
import com.aizuda.easy.retry.server.retry.task.support.RetryContext;
|
||||
import com.aizuda.easy.retry.server.retry.task.support.WaitStrategy;
|
||||
import com.aizuda.easy.retry.template.datasource.persistence.po.RetryTask;
|
||||
import com.aizuda.easy.retry.template.datasource.persistence.po.SceneConfig;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
|
||||
@ -50,6 +51,11 @@ public class MaxAttemptsPersistenceRetryContext<V> implements RetryContext<V> {
|
||||
*/
|
||||
private RegisterNodeInfo serverNode;
|
||||
|
||||
/**
|
||||
* 场景配置
|
||||
*/
|
||||
private SceneConfig sceneConfig;
|
||||
|
||||
@Override
|
||||
public void setCallResult(V v) {
|
||||
this.callResult = v;
|
||||
@ -64,4 +70,10 @@ public class MaxAttemptsPersistenceRetryContext<V> implements RetryContext<V> {
|
||||
public boolean hasException() {
|
||||
return Objects.nonNull(exception);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SceneConfig sceneConfig() {
|
||||
return sceneConfig;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ import com.aizuda.easy.retry.server.retry.task.support.retry.RetryExecutor;
|
||||
import com.aizuda.easy.retry.template.datasource.access.AccessTemplate;
|
||||
import com.aizuda.easy.retry.template.datasource.access.TaskAccess;
|
||||
import com.aizuda.easy.retry.template.datasource.persistence.po.RetryTask;
|
||||
import com.aizuda.easy.retry.template.datasource.persistence.po.SceneConfig;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@ -44,7 +45,7 @@ import java.util.concurrent.Callable;
|
||||
@Component(ActorGenerator.EXEC_CALLBACK_UNIT_ACTOR)
|
||||
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||
@Slf4j
|
||||
public class ExecCallbackUnitActor extends AbstractActor {
|
||||
public class ExecCallbackUnitActor extends AbstractActor {
|
||||
|
||||
@Autowired
|
||||
@Qualifier("bitSetIdempotentStrategyHandler")
|
||||
@ -61,6 +62,7 @@ public class ExecCallbackUnitActor extends AbstractActor {
|
||||
CallbackRetryContext context = (CallbackRetryContext) retryExecutor.getRetryContext();
|
||||
RetryTask retryTask = context.getRetryTask();
|
||||
RegisterNodeInfo serverNode = context.getServerNode();
|
||||
SceneConfig sceneConfig = context.getSceneConfig();
|
||||
|
||||
RetryTaskLogDTO retryTaskLog = new RetryTaskLogDTO();
|
||||
retryTaskLog.setGroupName(retryTask.getGroupName());
|
||||
@ -70,7 +72,7 @@ public class ExecCallbackUnitActor extends AbstractActor {
|
||||
|
||||
if (Objects.nonNull(serverNode)) {
|
||||
retryExecutor.call((Callable<Result<Void>>) () -> {
|
||||
Result<Void> result = callClient(retryTask, serverNode);
|
||||
Result<Void> result = callClient(retryTask, serverNode, sceneConfig);
|
||||
|
||||
String message = "回调客户端成功";
|
||||
if (StatusEnum.YES.getStatus() != result.getStatus()) {
|
||||
@ -90,7 +92,7 @@ public class ExecCallbackUnitActor extends AbstractActor {
|
||||
retryTaskLog.setMessage("There are currently no available client PODs.");
|
||||
}
|
||||
|
||||
}catch (Exception e) {
|
||||
} catch (Exception e) {
|
||||
LogUtils.error(log, "callback client error. retryTask:[{}]", JsonUtil.toJsonString(retryTask), e);
|
||||
retryTaskLog.setMessage(StringUtils.isBlank(e.getMessage()) ? StrUtil.EMPTY : e.getMessage());
|
||||
} finally {
|
||||
@ -114,15 +116,15 @@ public class ExecCallbackUnitActor extends AbstractActor {
|
||||
* @param callbackTask {@link RetryTask} 回调任务
|
||||
* @return 重试结果返回值
|
||||
*/
|
||||
private Result callClient(RetryTask callbackTask, RegisterNodeInfo serverNode) {
|
||||
private Result callClient(RetryTask callbackTask, RegisterNodeInfo serverNode, SceneConfig sceneConfig) {
|
||||
|
||||
String retryTaskUniqueId = callbackRetryTaskHandler.getRetryTaskUniqueId(callbackTask.getUniqueId());
|
||||
|
||||
TaskAccess<RetryTask> retryTaskAccess = accessTemplate.getRetryTaskAccess();
|
||||
RetryTask retryTask = retryTaskAccess.one(callbackTask.getGroupName(),
|
||||
new LambdaQueryWrapper<RetryTask>().eq(RetryTask::getUniqueId, retryTaskUniqueId));
|
||||
new LambdaQueryWrapper<RetryTask>().eq(RetryTask::getUniqueId, retryTaskUniqueId));
|
||||
Assert.notNull(retryTask, () -> new EasyRetryServerException("未查询回调任务对应的重试任务. callbackUniqueId:[{}] uniqueId:[{}]",
|
||||
callbackTask.getUniqueId(), retryTaskUniqueId));
|
||||
callbackTask.getUniqueId(), retryTaskUniqueId));
|
||||
|
||||
// 回调参数
|
||||
RetryCallbackDTO retryCallbackDTO = new RetryCallbackDTO();
|
||||
@ -136,17 +138,13 @@ public class ExecCallbackUnitActor extends AbstractActor {
|
||||
retryCallbackDTO.setUniqueId(callbackTask.getUniqueId());
|
||||
|
||||
RetryRpcClient rpcClient = RequestBuilder.<RetryRpcClient, Result>newBuilder()
|
||||
.hostPort(serverNode.getHostPort())
|
||||
.groupName(serverNode.getGroupName())
|
||||
.hostId(serverNode.getHostId())
|
||||
.hostIp(serverNode.getHostIp())
|
||||
.contextPath(serverNode.getContextPath())
|
||||
.client(RetryRpcClient.class)
|
||||
.build();
|
||||
|
||||
.nodeInfo(serverNode)
|
||||
.failover(Boolean.TRUE)
|
||||
.routeKey(sceneConfig.getRouteKey())
|
||||
.allocKey(sceneConfig.getSceneName())
|
||||
.client(RetryRpcClient.class)
|
||||
.build();
|
||||
return rpcClient.callback(retryCallbackDTO);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ import com.aizuda.easy.retry.server.retry.task.support.context.MaxAttemptsPersis
|
||||
import com.aizuda.easy.retry.server.retry.task.support.dispatch.actor.log.RetryTaskLogDTO;
|
||||
import com.aizuda.easy.retry.server.retry.task.support.retry.RetryExecutor;
|
||||
import com.aizuda.easy.retry.template.datasource.persistence.po.RetryTask;
|
||||
import com.aizuda.easy.retry.template.datasource.persistence.po.SceneConfig;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
@ -42,7 +43,7 @@ import java.util.concurrent.Callable;
|
||||
@Component(ActorGenerator.EXEC_UNIT_ACTOR)
|
||||
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||
@Slf4j
|
||||
public class ExecUnitActor extends AbstractActor {
|
||||
public class ExecUnitActor extends AbstractActor {
|
||||
|
||||
@Autowired
|
||||
@Qualifier("bitSetIdempotentStrategyHandler")
|
||||
@ -55,6 +56,7 @@ public class ExecUnitActor extends AbstractActor {
|
||||
MaxAttemptsPersistenceRetryContext context = (MaxAttemptsPersistenceRetryContext) retryExecutor.getRetryContext();
|
||||
RetryTask retryTask = context.getRetryTask();
|
||||
RegisterNodeInfo serverNode = context.getServerNode();
|
||||
SceneConfig sceneConfig = context.getSceneConfig();
|
||||
|
||||
RetryTaskLogDTO retryTaskLog = new RetryTaskLogDTO();
|
||||
retryTaskLog.setGroupName(retryTask.getGroupName());
|
||||
@ -67,7 +69,7 @@ public class ExecUnitActor extends AbstractActor {
|
||||
|
||||
retryExecutor.call((Callable<Result<DispatchRetryResultDTO>>) () -> {
|
||||
|
||||
Result<DispatchRetryResultDTO> result = callClient(retryTask, serverNode);
|
||||
Result<DispatchRetryResultDTO> result = callClient(retryTask, serverNode, sceneConfig);
|
||||
|
||||
// 回调接口请求成功,处理返回值
|
||||
if (StatusEnum.YES.getStatus() != result.getStatus()) {
|
||||
@ -106,7 +108,7 @@ public class ExecUnitActor extends AbstractActor {
|
||||
retryTaskLog.setMessage("There are currently no available client PODs.");
|
||||
}
|
||||
|
||||
}catch (Exception e) {
|
||||
} catch (Exception e) {
|
||||
LogUtils.error(log, "callback client error. retryTask:[{}]", JsonUtil.toJsonString(retryTask), e);
|
||||
retryTaskLog.setMessage(e.getMessage());
|
||||
} finally {
|
||||
@ -128,7 +130,7 @@ public class ExecUnitActor extends AbstractActor {
|
||||
* @param retryTask {@link RetryTask} 需要重试的数据
|
||||
* @return 重试结果返回值
|
||||
*/
|
||||
private Result<DispatchRetryResultDTO> callClient(RetryTask retryTask, RegisterNodeInfo serverNode) {
|
||||
private Result<DispatchRetryResultDTO> callClient(RetryTask retryTask, RegisterNodeInfo serverNode, SceneConfig sceneConfig) {
|
||||
|
||||
DispatchRetryDTO dispatchRetryDTO = new DispatchRetryDTO();
|
||||
dispatchRetryDTO.setIdempotentId(retryTask.getIdempotentId());
|
||||
@ -139,20 +141,17 @@ public class ExecUnitActor extends AbstractActor {
|
||||
dispatchRetryDTO.setRetryCount(retryTask.getRetryCount());
|
||||
|
||||
// 设置header
|
||||
HttpHeaders requestHeaders = new HttpHeaders();
|
||||
EasyRetryHeaders easyRetryHeaders = new EasyRetryHeaders();
|
||||
easyRetryHeaders.setEasyRetry(Boolean.TRUE);
|
||||
easyRetryHeaders.setEasyRetryId(retryTask.getUniqueId());
|
||||
requestHeaders.add(SystemConstants.EASY_RETRY_HEAD_KEY, JsonUtil.toJsonString(easyRetryHeaders));
|
||||
|
||||
RetryRpcClient rpcClient = RequestBuilder.<RetryRpcClient, Result>newBuilder()
|
||||
.hostPort(serverNode.getHostPort())
|
||||
.groupName(serverNode.getGroupName())
|
||||
.hostId(serverNode.getHostId())
|
||||
.hostIp(serverNode.getHostIp())
|
||||
.contextPath(serverNode.getContextPath())
|
||||
.client(RetryRpcClient.class)
|
||||
.build();
|
||||
.nodeInfo(serverNode)
|
||||
.failover(Boolean.TRUE)
|
||||
.allocKey(retryTask.getSceneName())
|
||||
.routeKey(sceneConfig.getRouteKey())
|
||||
.client(RetryRpcClient.class)
|
||||
.build();
|
||||
|
||||
return rpcClient.dispatch(dispatchRetryDTO, easyRetryHeaders);
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ public class CallbackTaskExecutor extends AbstractTaskExecutor {
|
||||
retryContext.setServerNode(
|
||||
clientNodeAllocateHandler.getServerNode(retryTask.getSceneName(), retryTask.getGroupName(),
|
||||
sceneConfig.getRouteKey()));
|
||||
retryContext.setSceneConfig(sceneConfig);
|
||||
return retryContext;
|
||||
}
|
||||
|
||||
|
@ -38,6 +38,7 @@ public class ManualCallbackTaskExecutor extends AbstractTaskExecutor {
|
||||
retryContext.setServerNode(
|
||||
clientNodeAllocateHandler.getServerNode(retryTask.getSceneName(), retryTask.getGroupName(),
|
||||
sceneConfig.getRouteKey()));
|
||||
retryContext.setSceneConfig(sceneConfig);
|
||||
return retryContext;
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,9 @@ public class ManualRetryTaskExecutor extends AbstractTaskExecutor {
|
||||
retryContext.setSceneBlacklist(accessTemplate.getSceneConfigAccess().getBlacklist(groupName));
|
||||
retryContext.setServerNode(
|
||||
clientNodeAllocateHandler.getServerNode(retryTask.getSceneName(), retryTask.getGroupName(),
|
||||
sceneConfig.getRouteKey())); return retryContext;
|
||||
sceneConfig.getRouteKey()));
|
||||
retryContext.setSceneConfig(sceneConfig);
|
||||
return retryContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -36,6 +36,7 @@ public class RetryTaskExecutor extends AbstractTaskExecutor {
|
||||
retryContext.setServerNode(
|
||||
clientNodeAllocateHandler.getServerNode(retryTask.getSceneName(), retryTask.getGroupName(),
|
||||
sceneConfig.getRouteKey()));
|
||||
retryContext.setSceneConfig(sceneConfig);
|
||||
return retryContext;
|
||||
}
|
||||
|
||||
@ -43,7 +44,6 @@ public class RetryTaskExecutor extends AbstractTaskExecutor {
|
||||
protected RetryExecutor<Result<DispatchRetryResultDTO>> builderResultRetryExecutor(RetryContext retryContext,
|
||||
final SceneConfig sceneConfig) {
|
||||
|
||||
RetryTask retryTask = retryContext.getRetryTask();
|
||||
return RetryBuilder.<Result<DispatchRetryResultDTO>>newBuilder()
|
||||
.withStopStrategy(StopStrategies.stopException())
|
||||
.withStopStrategy(StopStrategies.stopResultStatusCode())
|
||||
|
@ -226,11 +226,7 @@ public class RetryTaskServiceImpl implements RetryTaskService {
|
||||
generateRetryIdempotentIdDTO.setExecutorName(generateRetryIdempotentIdVO.getExecutorName());
|
||||
|
||||
RetryRpcClient rpcClient = RequestBuilder.<RetryRpcClient, Result>newBuilder()
|
||||
.hostPort(serverNode.getHostPort())
|
||||
.groupName(serverNode.getGroupName())
|
||||
.hostId(serverNode.getHostId())
|
||||
.hostIp(serverNode.getHostIp())
|
||||
.contextPath(serverNode.getContextPath())
|
||||
.nodeInfo(serverNode)
|
||||
.client(RetryRpcClient.class)
|
||||
.build();
|
||||
|
||||
|
@ -8,12 +8,33 @@ const jobApi = {
|
||||
|
||||
// 任务批次
|
||||
jobBatchList: '/job/batch/list',
|
||||
jobBatchDetail: '/job/batch/'
|
||||
jobBatchDetail: '/job/batch/',
|
||||
|
||||
// 任务
|
||||
jobTaskList: '/job/task/list',
|
||||
|
||||
// 日志
|
||||
jobLogList: '/job/log/list'
|
||||
}
|
||||
|
||||
export default jobApi
|
||||
|
||||
export function jobLogList (parameter) {
|
||||
return request({
|
||||
url: jobApi.jobLogList,
|
||||
method: 'get',
|
||||
params: parameter
|
||||
})
|
||||
}
|
||||
|
||||
export function jobTaskList (parameter) {
|
||||
return request({
|
||||
url: jobApi.jobTaskList,
|
||||
method: 'get',
|
||||
params: parameter
|
||||
})
|
||||
}
|
||||
|
||||
export function jobBatchList (parameter) {
|
||||
return request({
|
||||
url: jobApi.jobBatchList,
|
||||
|
@ -143,15 +143,30 @@ export const asyncRouterMap = [
|
||||
},
|
||||
{
|
||||
path: '/job/batch/list',
|
||||
name: 'JobBatch',
|
||||
component: () => import('@/views/job/JobBatch'),
|
||||
name: 'JobBatchList',
|
||||
component: () => import('@/views/job/JobBatchList'),
|
||||
meta: { title: '任务批次', icon: 'profile', permission: ['retryLog'] }
|
||||
},
|
||||
{
|
||||
path: '/job/batch/info',
|
||||
name: 'JobBatchInfo',
|
||||
hidden: true,
|
||||
component: () => import('@/views/job/JobBatchInfo'),
|
||||
meta: { title: '任务批次详情', icon: 'profile', permission: ['retryLog'] }
|
||||
},
|
||||
{
|
||||
path: '/job/task/list',
|
||||
name: 'JobTask',
|
||||
component: () => import('@/views/job/JobTask'),
|
||||
name: 'JobTaskList',
|
||||
hidden: true,
|
||||
component: () => import('@/views/job/JobTaskList'),
|
||||
meta: { title: '任务项', icon: 'profile', permission: ['retryLog'] }
|
||||
},
|
||||
{
|
||||
path: '/job/log/list',
|
||||
name: 'JobLogMessageList',
|
||||
hidden: true,
|
||||
component: () => import('@/views/job/JobLogMessageList'),
|
||||
meta: { title: '任务调度日志', icon: 'profile', permission: ['retryLog'] }
|
||||
}
|
||||
]
|
||||
},
|
||||
|
149
frontend/src/utils/enum.js
Normal file
149
frontend/src/utils/enum.js
Normal file
@ -0,0 +1,149 @@
|
||||
const enums = {
|
||||
jobStatusEnum: {
|
||||
'0': {
|
||||
'name': '关闭',
|
||||
'color': '#9c1f1f'
|
||||
},
|
||||
'1': {
|
||||
'name': '开启',
|
||||
'color': '#f5a22d'
|
||||
}
|
||||
},
|
||||
taskType: {
|
||||
'1': {
|
||||
'name': '集群模式',
|
||||
'color': '#d06892'
|
||||
},
|
||||
'2': {
|
||||
'name': '广播模式',
|
||||
'color': '#f5a22d'
|
||||
},
|
||||
'3': {
|
||||
'name': '分片模式',
|
||||
'color': '#e1f52d'
|
||||
}
|
||||
},
|
||||
triggerType: {
|
||||
'1': {
|
||||
'name': 'CRON表达式',
|
||||
'color': '#d06892'
|
||||
},
|
||||
'2': {
|
||||
'name': '固定时间',
|
||||
'color': '#f5a22d'
|
||||
}
|
||||
},
|
||||
blockStrategy: {
|
||||
'1': {
|
||||
'name': '丢弃策略',
|
||||
'color': '#d06892'
|
||||
},
|
||||
'2': {
|
||||
'name': '覆盖',
|
||||
'color': '#f5a22d'
|
||||
},
|
||||
'3': {
|
||||
'name': '并行',
|
||||
'color': '#e1f52d'
|
||||
}
|
||||
},
|
||||
executorType: {
|
||||
'1': {
|
||||
'name': 'Java',
|
||||
'color': '#d06892'
|
||||
}
|
||||
},
|
||||
routeKey: {
|
||||
'4': {
|
||||
'name': '轮询',
|
||||
'color': '#8f68d2'
|
||||
},
|
||||
'1': {
|
||||
'name': '一致性Hash',
|
||||
'color': '#d06892'
|
||||
},
|
||||
'2': {
|
||||
'name': '随机',
|
||||
'color': '#f5a22d'
|
||||
},
|
||||
'3': {
|
||||
'name': 'LRU',
|
||||
'color': '#e1f52d'
|
||||
}
|
||||
},
|
||||
taskStatus: {
|
||||
'1': {
|
||||
'name': '待处理',
|
||||
'color': '#64a6ea'
|
||||
},
|
||||
'2': {
|
||||
'name': '运行中',
|
||||
'color': '#1b7ee5'
|
||||
},
|
||||
'3': {
|
||||
'name': '成功',
|
||||
'color': '#087da1'
|
||||
},
|
||||
'4': {
|
||||
'name': '失败',
|
||||
'color': '#f52d80'
|
||||
},
|
||||
'5': {
|
||||
'name': '停止',
|
||||
'color': '#ac2df5'
|
||||
},
|
||||
'6': {
|
||||
'name': '取消',
|
||||
'color': '#f5732d'
|
||||
}
|
||||
},
|
||||
operationReason: {
|
||||
'0': {
|
||||
'name': ''
|
||||
},
|
||||
'1': {
|
||||
'name': '执行超时',
|
||||
'color': '#64a6ea'
|
||||
},
|
||||
'2': {
|
||||
'name': '无客户端节点',
|
||||
'color': '#1b7ee5'
|
||||
},
|
||||
'3': {
|
||||
'name': '任务已关闭',
|
||||
'color': '#087da1'
|
||||
}
|
||||
// '4': {
|
||||
// 'name': '失败',
|
||||
// 'color': '#f52d80'
|
||||
// },
|
||||
// '5': {
|
||||
// 'name': '停止',
|
||||
// 'color': '#ac2df5'
|
||||
// },
|
||||
// '6': {
|
||||
// 'name': '取消',
|
||||
// 'color': '#f5732d'
|
||||
// }
|
||||
},
|
||||
executeStatus: {
|
||||
'2': {
|
||||
'name': '运行中',
|
||||
'color': '#1b7ee5'
|
||||
},
|
||||
'3': {
|
||||
'name': '成功',
|
||||
'color': '#087da1'
|
||||
},
|
||||
'4': {
|
||||
'name': '失败',
|
||||
'color': '#f52d80'
|
||||
},
|
||||
'5': {
|
||||
'name': '停止',
|
||||
'color': '#ac2df5'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = enums
|
80
frontend/src/views/job/JobBatchInfo.vue
Normal file
80
frontend/src/views/job/JobBatchInfo.vue
Normal file
@ -0,0 +1,80 @@
|
||||
<template>
|
||||
<div>
|
||||
<page-header-wrapper @back="() => $router.go(-1)" style="margin: -24px -1px 0">
|
||||
<div></div>
|
||||
</page-header-wrapper>
|
||||
<a-card :bordered="false" v-if="jobBatchInfo !==null ">
|
||||
<a-descriptions title="" :column="5" bordered>
|
||||
<a-descriptions-item label="组名称">
|
||||
{{ jobBatchInfo.groupName }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="任务名称">
|
||||
{{ jobBatchInfo.jobName }}
|
||||
</a-descriptions-item>
|
||||
<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>
|
||||
<a-descriptions-item label="执行器名称" span="3">
|
||||
{{ jobBatchInfo.executorName }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-card>
|
||||
<div style="margin: 20px 0; border-left: #f5222d 5px solid; font-size: medium; font-weight: bold">
|
||||
任务项列表
|
||||
</div>
|
||||
<JobTaskList ref="JobTaskListRef" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { jobBatchDetail, jobTaskList } from '@/api/jobApi'
|
||||
import moment from 'moment'
|
||||
import enums from '@/utils/enum'
|
||||
import JobTaskList from './JobTaskList'
|
||||
|
||||
export default {
|
||||
name: 'JobInfo',
|
||||
components: {
|
||||
JobTaskList
|
||||
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
jobBatchInfo: null,
|
||||
taskStatus: enums.taskStatus,
|
||||
operationReason: enums.operationReason
|
||||
}
|
||||
},
|
||||
created () {
|
||||
const id = this.$route.query.id
|
||||
const groupName = this.$route.query.groupName
|
||||
if (id && groupName) {
|
||||
jobBatchDetail(id).then(res => {
|
||||
this.jobBatchInfo = res.data
|
||||
this.queryParam = {
|
||||
groupName: this.jobBatchInfo.groupName,
|
||||
taskBatchId: id
|
||||
}
|
||||
this.$refs.JobTaskListRef.refreshTable(this.queryParam)
|
||||
})
|
||||
} else {
|
||||
this.$router.push({ path: '/404' })
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
jobTaskList,
|
||||
parseDate (date) {
|
||||
return moment(date).format('YYYY-MM-DD HH:mm:ss')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
@ -66,8 +66,6 @@
|
||||
</a-form>
|
||||
</div>
|
||||
<div class="table-operator">
|
||||
<a-button type="primary" icon="plus" @click="handleNew()">新增</a-button>
|
||||
<!-- <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>
|
||||
@ -89,31 +87,13 @@
|
||||
<span slot="serial" slot-scope="text, record">
|
||||
{{ record.id }}
|
||||
</span>
|
||||
<span slot="taskType" slot-scope="text">
|
||||
<a-tag :color="taskType[text].color">
|
||||
{{ taskType[text].name }}
|
||||
</a-tag>
|
||||
</span>
|
||||
<span slot="taskStatus" slot-scope="text">
|
||||
<a-tag :color="taskStatus[text].color">
|
||||
{{ taskStatus[text].name }}
|
||||
</a-tag>
|
||||
</span>
|
||||
<span slot="triggerType" slot-scope="text">
|
||||
<a-tag :color="triggerType[text].color">
|
||||
{{ triggerType[text].name }}
|
||||
</a-tag>
|
||||
</span>
|
||||
<span slot="blockStrategy" slot-scope="text">
|
||||
<a-tag :color="blockStrategy[text].color">
|
||||
{{ blockStrategy[text].name }}
|
||||
</a-tag>
|
||||
</span>
|
||||
<span slot="triggerInterval" slot-scope="text">
|
||||
<span>{{ text }}(秒)</span>
|
||||
</span>
|
||||
<span slot="executorTimeout" slot-scope="text">
|
||||
<span>{{ text }}(秒)</span>
|
||||
<span slot="operationReason" slot-scope="text">
|
||||
{{ operationReason[text].name }}
|
||||
</span>
|
||||
<span slot="action" slot-scope="text, record">
|
||||
<template>
|
||||
@ -168,9 +148,10 @@ import AInput from 'ant-design-vue/es/input/Input'
|
||||
import { STable } from '@/components'
|
||||
import { jobBatchList } from '@/api/jobApi'
|
||||
import { getAllGroupNameList } from '@/api/manage'
|
||||
const enums = require('@/utils/enum')
|
||||
|
||||
export default {
|
||||
name: 'JobList',
|
||||
name: 'JobBatchList',
|
||||
components: {
|
||||
AInput,
|
||||
ATextarea,
|
||||
@ -186,54 +167,8 @@ export default {
|
||||
advanced: false,
|
||||
// 查询参数
|
||||
queryParam: {},
|
||||
jobStatus: {
|
||||
'0': {
|
||||
'name': '关闭',
|
||||
'color': '#9c1f1f'
|
||||
},
|
||||
'1': {
|
||||
'name': '开启',
|
||||
'color': '#f5a22d'
|
||||
}
|
||||
},
|
||||
taskType: {
|
||||
'1': {
|
||||
'name': '集群模式',
|
||||
'color': '#d06892'
|
||||
},
|
||||
'2': {
|
||||
'name': '广播模式',
|
||||
'color': '#f5a22d'
|
||||
},
|
||||
'3': {
|
||||
'name': '分片模式',
|
||||
'color': '#e1f52d'
|
||||
}
|
||||
},
|
||||
triggerType: {
|
||||
'1': {
|
||||
'name': 'CRON表达式',
|
||||
'color': '#d06892'
|
||||
},
|
||||
'2': {
|
||||
'name': '固定时间',
|
||||
'color': '#f5a22d'
|
||||
}
|
||||
},
|
||||
blockStrategy: {
|
||||
'1': {
|
||||
'name': '丢弃策略',
|
||||
'color': '#d06892'
|
||||
},
|
||||
'2': {
|
||||
'name': '覆盖',
|
||||
'color': '#f5a22d'
|
||||
},
|
||||
'3': {
|
||||
'name': '并行',
|
||||
'color': '#e1f52d'
|
||||
}
|
||||
},
|
||||
taskStatus: enums.taskStatus,
|
||||
operationReason: enums.operationReason,
|
||||
// 表头
|
||||
columns: [
|
||||
{
|
||||
@ -242,42 +177,27 @@ export default {
|
||||
},
|
||||
{
|
||||
title: '组名称',
|
||||
dataIndex: 'groupName'
|
||||
},
|
||||
{
|
||||
title: '任务名称',
|
||||
dataIndex: 'jobName',
|
||||
dataIndex: 'groupName',
|
||||
ellipsis: true
|
||||
},
|
||||
// {
|
||||
// title: '任务名称',
|
||||
// dataIndex: 'jobName',
|
||||
// ellipsis: true
|
||||
// },
|
||||
{
|
||||
title: '状态',
|
||||
dataIndex: 'taskStatus',
|
||||
scopedSlots: { customRender: 'taskStatus' }
|
||||
},
|
||||
{
|
||||
title: '任务类型',
|
||||
dataIndex: 'taskType',
|
||||
scopedSlots: { customRender: 'taskType' }
|
||||
title: '开始执行时间',
|
||||
dataIndex: 'executionAt'
|
||||
},
|
||||
{
|
||||
title: '触发类型',
|
||||
dataIndex: 'triggerType',
|
||||
scopedSlots: { customRender: 'triggerType' }
|
||||
},
|
||||
{
|
||||
title: '间隔时长',
|
||||
dataIndex: 'triggerInterval',
|
||||
scopedSlots: { customRender: 'triggerInterval' }
|
||||
},
|
||||
{
|
||||
title: '阻塞策略',
|
||||
dataIndex: 'blockStrategy',
|
||||
scopedSlots: { customRender: 'blockStrategy' }
|
||||
},
|
||||
{
|
||||
title: '超时时间',
|
||||
dataIndex: 'executorTimeout',
|
||||
scopedSlots: { customRender: 'executorTimeout' }
|
||||
title: '操作原因',
|
||||
dataIndex: 'operationReason',
|
||||
scopedSlots: { customRender: 'operationReason' }
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
@ -343,7 +263,7 @@ export default {
|
||||
this.advanced = !this.advanced
|
||||
},
|
||||
handleInfo (record) {
|
||||
this.$router.push({ path: '/job/info', query: { id: record.id, groupName: record.groupName } })
|
||||
this.$router.push({ path: '/job/batch/info', query: { id: record.id, groupName: record.groupName } })
|
||||
},
|
||||
handleOk (record) {},
|
||||
handleSuspend (record) {
|
@ -4,25 +4,58 @@
|
||||
<div></div>
|
||||
</page-header-wrapper>
|
||||
<a-card :bordered="false" v-if="jobInfo !==null ">
|
||||
<a-descriptions title="" bordered>
|
||||
<a-descriptions title="" :column="4" bordered>
|
||||
<a-descriptions-item label="组名称">
|
||||
{{ jobInfo.groupName }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="任务名称">
|
||||
{{ jobInfo.jobName }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="重试次数">
|
||||
{{ jobInfo.retryCount }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="重试状态 | 数据类型">
|
||||
<a-tag color="red">
|
||||
{{ retryStatus[jobInfo.retryStatus] }}
|
||||
<a-descriptions-item label="触发类型">
|
||||
<a-tag :color="triggerType[jobInfo.triggerType].color">
|
||||
{{ triggerType[jobInfo.triggerType].name }}
|
||||
</a-tag>
|
||||
<a-divider type="vertical" />
|
||||
</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-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>
|
||||
<a-descriptions-item label="超时时间">
|
||||
{{ jobInfo.executorTimeout }}(秒)
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="下次触发时间">
|
||||
{{ jobInfo.nextTriggerAt }}
|
||||
</a-descriptions-item>
|
||||
@ -46,6 +79,7 @@
|
||||
<script>
|
||||
import { getJobDetail } from '@/api/jobApi'
|
||||
import moment from 'moment'
|
||||
import enums from '@/utils/enum'
|
||||
|
||||
export default {
|
||||
name: 'JobInfo',
|
||||
@ -55,22 +89,12 @@ export default {
|
||||
data () {
|
||||
return {
|
||||
jobInfo: null,
|
||||
retryStatus: {
|
||||
'0': '处理中',
|
||||
'1': '处理成功',
|
||||
'2': '最大次数',
|
||||
'3': '暂停'
|
||||
},
|
||||
taskType: {
|
||||
'1': {
|
||||
'name': '重试数据',
|
||||
'color': '#d06892'
|
||||
},
|
||||
'2': {
|
||||
'name': '回调数据',
|
||||
'color': '#f5a22d'
|
||||
}
|
||||
}
|
||||
jobStatusEnum: enums.jobStatusEnum,
|
||||
taskType: enums.taskType,
|
||||
triggerType: enums.triggerType,
|
||||
blockStrategy: enums.blockStrategy,
|
||||
executorType: enums.executorType,
|
||||
routeKey: enums.routeKey
|
||||
}
|
||||
},
|
||||
created () {
|
||||
|
@ -95,8 +95,8 @@
|
||||
</a-tag>
|
||||
</span>
|
||||
<span slot="jobStatus" slot-scope="text">
|
||||
<a-tag :color="jobStatus[text].color">
|
||||
{{ jobStatus[text].name }}
|
||||
<a-tag :color="jobStatusEnum[text].color">
|
||||
{{ jobStatusEnum[text].name }}
|
||||
</a-tag>
|
||||
</span>
|
||||
<span slot="triggerType" slot-scope="text">
|
||||
@ -168,6 +168,7 @@ import AInput from 'ant-design-vue/es/input/Input'
|
||||
import { STable } from '@/components'
|
||||
import { getJobList } from '@/api/jobApi'
|
||||
import { getAllGroupNameList } from '@/api/manage'
|
||||
import enums from '@/utils/enum'
|
||||
|
||||
export default {
|
||||
name: 'JobList',
|
||||
@ -186,54 +187,11 @@ export default {
|
||||
advanced: false,
|
||||
// 查询参数
|
||||
queryParam: {},
|
||||
jobStatus: {
|
||||
'0': {
|
||||
'name': '关闭',
|
||||
'color': '#9c1f1f'
|
||||
},
|
||||
'1': {
|
||||
'name': '开启',
|
||||
'color': '#f5a22d'
|
||||
}
|
||||
},
|
||||
taskType: {
|
||||
'1': {
|
||||
'name': '集群模式',
|
||||
'color': '#d06892'
|
||||
},
|
||||
'2': {
|
||||
'name': '广播模式',
|
||||
'color': '#f5a22d'
|
||||
},
|
||||
'3': {
|
||||
'name': '分片模式',
|
||||
'color': '#e1f52d'
|
||||
}
|
||||
},
|
||||
triggerType: {
|
||||
'1': {
|
||||
'name': 'CRON表达式',
|
||||
'color': '#d06892'
|
||||
},
|
||||
'2': {
|
||||
'name': '固定时间',
|
||||
'color': '#f5a22d'
|
||||
}
|
||||
},
|
||||
blockStrategy: {
|
||||
'1': {
|
||||
'name': '丢弃策略',
|
||||
'color': '#d06892'
|
||||
},
|
||||
'2': {
|
||||
'name': '覆盖',
|
||||
'color': '#f5a22d'
|
||||
},
|
||||
'3': {
|
||||
'name': '并行',
|
||||
'color': '#e1f52d'
|
||||
}
|
||||
},
|
||||
jobStatusEnum: enums.jobStatusEnum,
|
||||
taskType: enums.taskType,
|
||||
triggerType: enums.triggerType,
|
||||
blockStrategy: enums.blockStrategy,
|
||||
executorType: enums.executorType,
|
||||
// 表头
|
||||
columns: [
|
||||
{
|
||||
|
81
frontend/src/views/job/JobLogMessageList.vue
Normal file
81
frontend/src/views/job/JobLogMessageList.vue
Normal file
@ -0,0 +1,81 @@
|
||||
<template>
|
||||
<div>
|
||||
<a-card>
|
||||
<s-table
|
||||
ref="table"
|
||||
size="default"
|
||||
rowKey="key"
|
||||
:columns="columns"
|
||||
:data="loadData"
|
||||
>
|
||||
<span slot="serial" slot-scope="text, record">
|
||||
{{ record.id }}
|
||||
</span>
|
||||
</s-table>
|
||||
</a-card>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import moment from 'moment'
|
||||
import { STable } from '@/components'
|
||||
import { jobLogList } from '@/api/jobApi'
|
||||
|
||||
export default {
|
||||
name: 'JobLogList',
|
||||
components: {
|
||||
STable
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
// 表头
|
||||
columns: [
|
||||
{
|
||||
title: '#',
|
||||
scopedSlots: { customRender: 'serial' },
|
||||
width: '5%'
|
||||
},
|
||||
{
|
||||
title: '客户端地址',
|
||||
dataIndex: 'clientAddress',
|
||||
width: '10%'
|
||||
},
|
||||
{
|
||||
title: '信息',
|
||||
dataIndex: 'message',
|
||||
width: '50%'
|
||||
},
|
||||
{
|
||||
title: '触发时间',
|
||||
dataIndex: 'createDt',
|
||||
sorter: true,
|
||||
customRender: (text) => moment(text).format('YYYY-MM-DD HH:mm:ss'),
|
||||
width: '10%'
|
||||
}
|
||||
],
|
||||
queryParam: {},
|
||||
// 加载数据方法 必须为 Promise 对象
|
||||
loadData: parameter => {
|
||||
return jobLogList(Object.assign(parameter, this.queryParam))
|
||||
.then(res => {
|
||||
this.total = res.total
|
||||
return res
|
||||
})
|
||||
},
|
||||
total: 0
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
refreshTable (v) {
|
||||
this.queryParam = v
|
||||
this.$refs.table.refresh(true)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
@ -1,445 +0,0 @@
|
||||
<template>
|
||||
<a-card :bordered="false">
|
||||
<div class="table-page-search-wrapper">
|
||||
<a-form layout="inline">
|
||||
<a-row :gutter="48">
|
||||
<a-col :md="8" :sm="24">
|
||||
<a-form-item label="组名称">
|
||||
<a-select
|
||||
v-model="queryParam.groupName"
|
||||
placeholder="请输入组名称"
|
||||
@change="(value) => handleChange(value)"
|
||||
>
|
||||
<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 :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">
|
||||
{{ 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>
|
||||
</template>
|
||||
<a-col :md="(!advanced && 8) || 24" :sm="24">
|
||||
<span
|
||||
class="table-page-search-submitButtons"
|
||||
:style="(advanced && { float: 'right', overflow: 'hidden' }) || {}"
|
||||
>
|
||||
<a-button type="primary" @click="$refs.table.refresh(true)">查询</a-button>
|
||||
<a-button style="margin-left: 8px" @click="() => (queryParam = {})">重置</a-button>
|
||||
<a @click="toggleAdvanced" style="margin-left: 8px">
|
||||
{{ advanced ? '收起' : '展开' }}
|
||||
<a-icon :type="advanced ? 'up' : 'down'" />
|
||||
</a>
|
||||
</span>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</div>
|
||||
<div class="table-operator">
|
||||
<a-button type="primary" icon="plus" @click="handleNew()">新增</a-button>
|
||||
<!-- <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>
|
||||
<a-button style="margin-left: 8px"> 批量操作 <a-icon type="down" /> </a-button>
|
||||
</a-dropdown>
|
||||
</div>
|
||||
|
||||
<s-table
|
||||
ref="table"
|
||||
size="default"
|
||||
:rowKey="(record) => record.id"
|
||||
:columns="columns"
|
||||
:data="loadData"
|
||||
:alert="options.alert"
|
||||
:rowSelection="options.rowSelection"
|
||||
>
|
||||
<span slot="serial" slot-scope="text, record">
|
||||
{{ record.id }}
|
||||
</span>
|
||||
<span slot="taskType" slot-scope="text">
|
||||
<a-tag :color="taskType[text].color">
|
||||
{{ taskType[text].name }}
|
||||
</a-tag>
|
||||
</span>
|
||||
<span slot="jobStatus" slot-scope="text">
|
||||
<a-tag :color="jobStatus[text].color">
|
||||
{{ jobStatus[text].name }}
|
||||
</a-tag>
|
||||
</span>
|
||||
<span slot="triggerType" slot-scope="text">
|
||||
<a-tag :color="triggerType[text].color">
|
||||
{{ triggerType[text].name }}
|
||||
</a-tag>
|
||||
</span>
|
||||
<span slot="blockStrategy" slot-scope="text">
|
||||
<a-tag :color="blockStrategy[text].color">
|
||||
{{ blockStrategy[text].name }}
|
||||
</a-tag>
|
||||
</span>
|
||||
<span slot="triggerInterval" slot-scope="text">
|
||||
<span>{{ text }}(秒)</span>
|
||||
</span>
|
||||
<span slot="executorTimeout" slot-scope="text">
|
||||
<span>{{ text }}(秒)</span>
|
||||
</span>
|
||||
<span slot="action" slot-scope="text, record">
|
||||
<template>
|
||||
<a @click="handleInfo(record)">详情</a>
|
||||
<a-divider type="vertical" />
|
||||
<a-popconfirm
|
||||
title="是否暂停?"
|
||||
ok-text="恢复"
|
||||
cancel-text="取消"
|
||||
@confirm="handleSuspend(record)"
|
||||
>
|
||||
<a href="javascript:;" v-if="record.retryStatus === 0">暂停</a>
|
||||
</a-popconfirm>
|
||||
<a-divider type="vertical" v-if="record.retryStatus === 0" />
|
||||
<a-popconfirm
|
||||
title="是否恢复?"
|
||||
ok-text="恢复"
|
||||
cancel-text="取消"
|
||||
@confirm="handleRecovery(record)"
|
||||
>
|
||||
<a href="javascript:;" v-if="record.retryStatus === 3">恢复</a>
|
||||
</a-popconfirm>
|
||||
<a-divider type="vertical" v-if="record.retryStatus === 3" />
|
||||
<a-popconfirm
|
||||
title="是否完成?"
|
||||
ok-text="完成"
|
||||
cancel-text="取消"
|
||||
@confirm="handleFinish(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-popconfirm>
|
||||
|
||||
</template>
|
||||
</span>
|
||||
</s-table>
|
||||
|
||||
</a-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
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 { getAllGroupNameList } from '@/api/manage'
|
||||
|
||||
export default {
|
||||
name: 'JobList',
|
||||
components: {
|
||||
AInput,
|
||||
ATextarea,
|
||||
STable
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
currentComponet: 'List',
|
||||
record: '',
|
||||
mdl: {},
|
||||
visible: false,
|
||||
// 高级搜索 展开/关闭
|
||||
advanced: false,
|
||||
// 查询参数
|
||||
queryParam: {},
|
||||
jobStatus: {
|
||||
'0': {
|
||||
'name': '关闭',
|
||||
'color': '#9c1f1f'
|
||||
},
|
||||
'1': {
|
||||
'name': '开启',
|
||||
'color': '#f5a22d'
|
||||
}
|
||||
},
|
||||
taskType: {
|
||||
'1': {
|
||||
'name': '集群模式',
|
||||
'color': '#d06892'
|
||||
},
|
||||
'2': {
|
||||
'name': '广播模式',
|
||||
'color': '#f5a22d'
|
||||
},
|
||||
'3': {
|
||||
'name': '分片模式',
|
||||
'color': '#e1f52d'
|
||||
}
|
||||
},
|
||||
triggerType: {
|
||||
'1': {
|
||||
'name': 'CRON表达式',
|
||||
'color': '#d06892'
|
||||
},
|
||||
'2': {
|
||||
'name': '固定时间',
|
||||
'color': '#f5a22d'
|
||||
}
|
||||
},
|
||||
blockStrategy: {
|
||||
'1': {
|
||||
'name': '丢弃策略',
|
||||
'color': '#d06892'
|
||||
},
|
||||
'2': {
|
||||
'name': '覆盖',
|
||||
'color': '#f5a22d'
|
||||
},
|
||||
'3': {
|
||||
'name': '并行',
|
||||
'color': '#e1f52d'
|
||||
}
|
||||
},
|
||||
// 表头
|
||||
columns: [
|
||||
{
|
||||
title: 'ID',
|
||||
scopedSlots: { customRender: 'serial' }
|
||||
},
|
||||
{
|
||||
title: '组名称',
|
||||
dataIndex: 'groupName'
|
||||
},
|
||||
{
|
||||
title: '任务名称',
|
||||
dataIndex: 'jobName',
|
||||
ellipsis: true
|
||||
},
|
||||
{
|
||||
title: '触发时间',
|
||||
dataIndex: 'nextTriggerAt'
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
dataIndex: 'jobStatus',
|
||||
scopedSlots: { customRender: 'jobStatus' }
|
||||
},
|
||||
{
|
||||
title: '任务类型',
|
||||
dataIndex: 'taskType',
|
||||
scopedSlots: { customRender: 'taskType' }
|
||||
},
|
||||
{
|
||||
title: '触发类型',
|
||||
dataIndex: 'triggerType',
|
||||
scopedSlots: { customRender: 'triggerType' }
|
||||
},
|
||||
{
|
||||
title: '间隔时长',
|
||||
dataIndex: 'triggerInterval',
|
||||
scopedSlots: { customRender: 'triggerInterval' }
|
||||
},
|
||||
{
|
||||
title: '阻塞策略',
|
||||
dataIndex: 'blockStrategy',
|
||||
scopedSlots: { customRender: 'blockStrategy' }
|
||||
},
|
||||
{
|
||||
title: '超时时间',
|
||||
dataIndex: 'executorTimeout',
|
||||
scopedSlots: { customRender: 'executorTimeout' }
|
||||
},
|
||||
{
|
||||
title: '更新时间',
|
||||
dataIndex: 'updateDt',
|
||||
sorter: true,
|
||||
width: '10%'
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
fixed: 'right',
|
||||
dataIndex: 'action',
|
||||
width: '180px',
|
||||
scopedSlots: { customRender: 'action' }
|
||||
}
|
||||
],
|
||||
// 加载数据方法 必须为 Promise 对象
|
||||
loadData: (parameter) => {
|
||||
return getJobList(Object.assign(parameter, this.queryParam)).then((res) => {
|
||||
return res
|
||||
})
|
||||
},
|
||||
selectedRowKeys: [],
|
||||
selectedRows: [],
|
||||
|
||||
// custom table alert & rowSelection
|
||||
options: {
|
||||
alert: {
|
||||
show: true,
|
||||
clear: () => {
|
||||
this.selectedRowKeys = []
|
||||
}
|
||||
},
|
||||
rowSelection: {
|
||||
selectedRowKeys: this.selectedRowKeys,
|
||||
onChange: this.onSelectChange
|
||||
}
|
||||
},
|
||||
optionAlertShow: false,
|
||||
groupNameList: [],
|
||||
sceneList: []
|
||||
}
|
||||
},
|
||||
created () {
|
||||
getAllGroupNameList().then((res) => {
|
||||
this.groupNameList = res.data
|
||||
if (this.groupNameList !== null && this.groupNameList.length > 0) {
|
||||
this.queryParam['groupName'] = this.groupNameList[0]
|
||||
this.$refs.table.refresh(true)
|
||||
this.handleChange(this.groupNameList[0])
|
||||
}
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
handleNew () {
|
||||
this.$refs.saveRetryTask.isShow(true, null)
|
||||
},
|
||||
handleBatchNew () {
|
||||
this.$refs.batchSaveRetryTask.isShow(true, null)
|
||||
},
|
||||
handleChange (value) {
|
||||
},
|
||||
toggleAdvanced () {
|
||||
this.advanced = !this.advanced
|
||||
},
|
||||
handleInfo (record) {
|
||||
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('暂停成功')
|
||||
// }
|
||||
// })
|
||||
},
|
||||
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('恢复成功')
|
||||
// }
|
||||
// })
|
||||
},
|
||||
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('执行完成')
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
},
|
||||
refreshTable (v) {
|
||||
this.$refs.table.refresh(true)
|
||||
},
|
||||
onSelectChange (selectedRowKeys, selectedRows) {
|
||||
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)
|
||||
return
|
||||
}
|
||||
|
||||
if (key === '1') {
|
||||
this.handlerDel()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
325
frontend/src/views/job/JobTaskList.vue
Normal file
325
frontend/src/views/job/JobTaskList.vue
Normal file
@ -0,0 +1,325 @@
|
||||
<template>
|
||||
<a-card :bordered="false">
|
||||
<div class="table-page-search-wrapper">
|
||||
<a-form layout="inline">
|
||||
<a-row :gutter="48">
|
||||
<!-- <a-col :md="8" :sm="24">-->
|
||||
<!-- <a-form-item label="组名称">-->
|
||||
<!-- <a-select-->
|
||||
<!-- v-model="queryParam.groupName"-->
|
||||
<!-- placeholder="请输入组名称"-->
|
||||
<!-- @change="(value) => handleChange(value)"-->
|
||||
<!-- >-->
|
||||
<!-- <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 :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">-->
|
||||
<!-- {{ 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>-->
|
||||
<!-- </template>-->
|
||||
<!-- <a-col :md="(!advanced && 8) || 24" :sm="24">-->
|
||||
<!-- <span-->
|
||||
<!-- class="table-page-search-submitButtons"-->
|
||||
<!-- :style="(advanced && { float: 'right', overflow: 'hidden' }) || {}"-->
|
||||
<!-- >-->
|
||||
<!-- <a-button type="primary" @click="$refs.table.refresh(true)">查询</a-button>-->
|
||||
<!-- <a-button style="margin-left: 8px" @click="() => (queryParam = {})">重置</a-button>-->
|
||||
<!-- <a @click="toggleAdvanced" style="margin-left: 8px">-->
|
||||
<!-- {{ advanced ? '收起' : '展开' }}-->
|
||||
<!-- <a-icon :type="advanced ? 'up' : 'down'" />-->
|
||||
<!-- </a>-->
|
||||
<!-- </span>-->
|
||||
<!-- </a-col>-->
|
||||
</a-row>
|
||||
</a-form>
|
||||
</div>
|
||||
<div class="table-operator">
|
||||
<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>
|
||||
<a-button style="margin-left: 8px"> 批量操作 <a-icon type="down" /> </a-button>
|
||||
</a-dropdown>
|
||||
</div>
|
||||
|
||||
<s-table
|
||||
ref="table"
|
||||
size="default"
|
||||
:rowKey="(record) => record.id"
|
||||
:columns="columns"
|
||||
:data="loadData"
|
||||
:alert="options.alert"
|
||||
:rowSelection="options.rowSelection"
|
||||
>
|
||||
<span slot="serial" slot-scope="text, record">
|
||||
{{ record.id }}
|
||||
</span>
|
||||
<span slot="executeStatus" slot-scope="text">
|
||||
<a-tag :color="executeStatus[text].color">
|
||||
{{ executeStatus[text].name }}
|
||||
</a-tag>
|
||||
</span>
|
||||
<p slot="expandedRowRender" style="margin: 0" slot-scope="record">
|
||||
执行结果: {{ record.resultMessage }}<br/>
|
||||
参数: {{ record.argsStr }}
|
||||
</p>
|
||||
<span slot="action" slot-scope="text, record">
|
||||
<template>
|
||||
<a @click="handleLog(record)">日志</a>
|
||||
</template>
|
||||
</span>
|
||||
</s-table>
|
||||
|
||||
</a-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ATextarea from 'ant-design-vue/es/input/TextArea'
|
||||
import AInput from 'ant-design-vue/es/input/Input'
|
||||
import { STable } from '@/components'
|
||||
import { jobTaskList } from '@/api/jobApi'
|
||||
import { getAllGroupNameList } from '@/api/manage'
|
||||
import enums from '@/utils/enum'
|
||||
import JobLogMessageList from './JobLogMessageList'
|
||||
export default {
|
||||
name: 'JobTaskList',
|
||||
components: {
|
||||
AInput,
|
||||
ATextarea,
|
||||
STable,
|
||||
JobLogMessageList
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
currentComponet: 'List',
|
||||
record: '',
|
||||
mdl: {},
|
||||
visible: false,
|
||||
// 高级搜索 展开/关闭
|
||||
advanced: false,
|
||||
// 查询参数
|
||||
queryParam: {},
|
||||
executeStatus: enums.executeStatus,
|
||||
// 表头
|
||||
columns: [
|
||||
{
|
||||
title: 'ID',
|
||||
scopedSlots: { customRender: 'serial' }
|
||||
},
|
||||
{
|
||||
title: '组名称',
|
||||
dataIndex: 'groupName'
|
||||
},
|
||||
{
|
||||
title: '参数',
|
||||
dataIndex: 'argsStr',
|
||||
ellipsis: true
|
||||
},
|
||||
{
|
||||
title: '结果',
|
||||
dataIndex: 'resultMessage',
|
||||
ellipsis: true
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
dataIndex: 'executeStatus',
|
||||
scopedSlots: { customRender: 'executeStatus' }
|
||||
},
|
||||
{
|
||||
title: '重试次数',
|
||||
dataIndex: 'retryCount'
|
||||
},
|
||||
{
|
||||
title: '开始执行时间',
|
||||
dataIndex: 'createDt',
|
||||
sorter: true,
|
||||
width: '10%'
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
fixed: 'right',
|
||||
dataIndex: 'action',
|
||||
width: '180px',
|
||||
scopedSlots: { customRender: 'action' }
|
||||
}
|
||||
],
|
||||
// 加载数据方法 必须为 Promise 对象
|
||||
loadData: (parameter) => {
|
||||
return jobTaskList(Object.assign(parameter, this.queryParam)).then((res) => {
|
||||
return res
|
||||
})
|
||||
},
|
||||
selectedRowKeys: [],
|
||||
selectedRows: [],
|
||||
|
||||
// custom table alert & rowSelection
|
||||
options: {
|
||||
alert: {
|
||||
show: true,
|
||||
clear: () => {
|
||||
this.selectedRowKeys = []
|
||||
}
|
||||
},
|
||||
rowSelection: {
|
||||
selectedRowKeys: this.selectedRowKeys,
|
||||
onChange: this.onSelectChange
|
||||
}
|
||||
},
|
||||
optionAlertShow: false,
|
||||
groupNameList: [],
|
||||
sceneList: []
|
||||
}
|
||||
},
|
||||
created () {
|
||||
getAllGroupNameList().then((res) => {
|
||||
this.groupNameList = res.data
|
||||
if (this.groupNameList !== null && this.groupNameList.length > 0) {
|
||||
this.queryParam['groupName'] = this.groupNameList[0]
|
||||
this.$refs.table.refresh(true)
|
||||
this.handleChange(this.groupNameList[0])
|
||||
}
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
handleNew () {
|
||||
this.$refs.saveRetryTask.isShow(true, null)
|
||||
},
|
||||
handleBatchNew () {
|
||||
this.$refs.batchSaveRetryTask.isShow(true, null)
|
||||
},
|
||||
handleChange (value) {
|
||||
},
|
||||
toggleAdvanced () {
|
||||
this.advanced = !this.advanced
|
||||
},
|
||||
handleLog (record) {
|
||||
this.$router.push({ path: '/job/log/list', query: { taskBatchId: record.id, jobId: record.jobId } })
|
||||
},
|
||||
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('暂停成功')
|
||||
// }
|
||||
// })
|
||||
},
|
||||
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('恢复成功')
|
||||
// }
|
||||
// })
|
||||
},
|
||||
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('执行完成')
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
},
|
||||
refreshTable (v) {
|
||||
this.queryParam = v
|
||||
this.$refs.table.refresh(true)
|
||||
},
|
||||
onSelectChange (selectedRowKeys, selectedRows) {
|
||||
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)
|
||||
return
|
||||
}
|
||||
|
||||
if (key === '1') {
|
||||
this.handlerDel()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
Loading…
Reference in New Issue
Block a user