feat:2.4.0
1.前端页面未完成
This commit is contained in:
parent
18b952234c
commit
f1a64c2fb8
@ -80,20 +80,6 @@ public class JobExecutorResultActor extends AbstractActor {
|
||||
}
|
||||
});
|
||||
|
||||
// TODO 60秒内的任务直接丢入时间轮中
|
||||
if (Integer.parseInt("30") <= 60) {
|
||||
if (jobTaskBatchMapper.selectCount(new LambdaQueryWrapper<JobTaskBatch>()
|
||||
.eq(JobTaskBatch::getId, result.getTaskBatchId())
|
||||
.in(JobTaskBatch::getTaskStatus, JobTaskBatchStatusEnum.NOT_COMPLETE)) <= 0) {
|
||||
ActorRef scanActorRef = CacheGroupScanActor.get("DEFAULT_JOB_KEY", TaskTypeEnum.JOB);
|
||||
ScanTask scanTask = new ScanTask();
|
||||
scanTask.setBuckets(Sets.newHashSet(0));
|
||||
scanTask.setSize(1);
|
||||
scanTask.setStartId(result.getJobId());
|
||||
scanActorRef.tell(scanTask, scanActorRef);
|
||||
}
|
||||
}
|
||||
|
||||
JobLogDTO jobLogDTO = JobTaskConverter.INSTANCE.toJobLogDTO(result);
|
||||
jobLogDTO.setMessage(result.getMessage());
|
||||
jobLogDTO.setClientId(result.getClientId());
|
||||
|
@ -52,8 +52,6 @@ public class ScanJobTaskActor extends AbstractActor {
|
||||
@Autowired
|
||||
private JobMapper jobMapper;
|
||||
|
||||
private static final AtomicLong lastId = new AtomicLong(0L);
|
||||
|
||||
@Override
|
||||
public Receive createReceive() {
|
||||
return receiveBuilder().match(ScanTask.class, config -> {
|
||||
@ -104,9 +102,9 @@ public class ScanJobTaskActor extends AbstractActor {
|
||||
new LambdaQueryWrapper<Job>()
|
||||
.eq(Job::getJobStatus, StatusEnum.YES.getStatus())
|
||||
.in(Job::getBucketIndex, scanTask.getBuckets())
|
||||
.le(Job::getNextTriggerAt, LocalDateTime.now().plusSeconds(60))
|
||||
.le(Job::getNextTriggerAt, LocalDateTime.now().plusSeconds(10))
|
||||
.eq(Job::getDeleted, StatusEnum.NO.getStatus())
|
||||
.gt(Job::getId, startId)
|
||||
.ge(Job::getId, startId)
|
||||
).getRecords();
|
||||
|
||||
return JobTaskConverter.INSTANCE.toJobPartitionTasks(jobs);
|
||||
|
@ -35,7 +35,7 @@ public class DispatchService implements Lifecycle {
|
||||
/**
|
||||
* 调度时长
|
||||
*/
|
||||
public static final Long PERIOD = 60L;
|
||||
public static final Long PERIOD = 10L;
|
||||
|
||||
/**
|
||||
* 延迟10s为了尽可能保障集群节点都启动完成在进行rebalance
|
||||
|
@ -0,0 +1,51 @@
|
||||
package com.aizuda.easy.retry.server.web.controller;
|
||||
|
||||
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.response.JobResponseVO;
|
||||
import com.aizuda.easy.retry.server.web.model.response.SceneConfigResponseVO;
|
||||
import com.aizuda.easy.retry.server.web.service.JobService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author www.byteblogs.com
|
||||
* @date 2023-10-11 22:18:29
|
||||
* @since 2.4.0
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/job")
|
||||
public class JobController {
|
||||
|
||||
@Autowired
|
||||
private JobService jobService;
|
||||
|
||||
@GetMapping("/list")
|
||||
@LoginRequired
|
||||
public PageResult<List<JobResponseVO>> getJobPage(JobQueryVO jobQueryVO) {
|
||||
return jobService.getJobPage(jobQueryVO);
|
||||
}
|
||||
|
||||
@GetMapping("{id}")
|
||||
@LoginRequired
|
||||
public PageResult<List<JobResponseVO>> getJobDetail(@PathVariable("id") Long id) {
|
||||
return jobService.getJobDetail(id);
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@LoginRequired
|
||||
public PageResult<List<JobResponseVO>> saveJob(@RequestBody JobRequestVO jobRequestVO) {
|
||||
return jobService.saveJob(jobRequestVO);
|
||||
}
|
||||
|
||||
@PutMapping
|
||||
@LoginRequired
|
||||
public PageResult<List<JobResponseVO>> updateJob(@RequestBody JobRequestVO jobRequestVO) {
|
||||
return jobService.updateJob(jobRequestVO);
|
||||
}
|
||||
|
||||
}
|
@ -15,7 +15,7 @@ import java.util.List;
|
||||
* @since 2.0
|
||||
*/
|
||||
@Configuration
|
||||
public class XRetryWebMvcConfigurerAdapter implements WebMvcConfigurer {
|
||||
public class EasyRetryRetryWebMvcConfigurerAdapter implements WebMvcConfigurer {
|
||||
|
||||
@Autowired
|
||||
private LoginUserMethodArgumentResolver loginUserMethodArgumentResolver;
|
@ -0,0 +1,11 @@
|
||||
package com.aizuda.easy.retry.server.web.model.request;
|
||||
|
||||
import com.aizuda.easy.retry.server.web.model.base.BaseQueryVO;
|
||||
|
||||
/**
|
||||
* @author www.byteblogs.com
|
||||
* @date 2023-10-11 22:28:07
|
||||
* @since 2.4.0
|
||||
*/
|
||||
public class JobQueryVO extends BaseQueryVO {
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package com.aizuda.easy.retry.server.web.model.request;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author www.byteblogs.com
|
||||
* @date 2023-10-11 22:37:55
|
||||
* @since 2.4.0
|
||||
*/
|
||||
@Data
|
||||
public class JobRequestVO {
|
||||
}
|
@ -0,0 +1,132 @@
|
||||
package com.aizuda.easy.retry.server.web.model.response;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* @author www.byteblogs.com
|
||||
* @date 2023-10-11 22:30:00
|
||||
* @since 2.4.0
|
||||
*/
|
||||
@Data
|
||||
public class JobResponseVO {
|
||||
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 组名称
|
||||
*/
|
||||
private String groupName;
|
||||
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
private String jobName;
|
||||
|
||||
/**
|
||||
* 执行方法参数
|
||||
*/
|
||||
private String argsStr;
|
||||
|
||||
/**
|
||||
* 参数类型 text/json
|
||||
*/
|
||||
private String argsType;
|
||||
|
||||
/**
|
||||
* 扩展字段
|
||||
*/
|
||||
private String extAttrs;
|
||||
|
||||
/**
|
||||
* 下次触发时间
|
||||
*/
|
||||
private LocalDateTime nextTriggerAt;
|
||||
|
||||
/**
|
||||
* 重试状态 0、关闭、1、开启
|
||||
*/
|
||||
private Integer jobStatus;
|
||||
|
||||
/**
|
||||
* 执行器路由策略
|
||||
*/
|
||||
private String routeKey;
|
||||
|
||||
/**
|
||||
* 执行器类型 1、Java
|
||||
*/
|
||||
private Integer executorType;
|
||||
|
||||
/**
|
||||
* 执行器名称
|
||||
*/
|
||||
private String executorName;
|
||||
|
||||
/**
|
||||
* 触发类型 1.CRON 表达式 2. 固定时间
|
||||
*/
|
||||
private Integer triggerType;
|
||||
|
||||
/**
|
||||
* 间隔时长
|
||||
*/
|
||||
private String triggerInterval;
|
||||
|
||||
/**
|
||||
* 阻塞策略 1、丢弃 2、覆盖 3、并行
|
||||
*/
|
||||
private Integer blockStrategy;
|
||||
|
||||
/**
|
||||
* 任务执行超时时间,单位秒
|
||||
*/
|
||||
private Integer executorTimeout;
|
||||
|
||||
/**
|
||||
* 最大重试次数
|
||||
*/
|
||||
private Integer maxRetryTimes;
|
||||
|
||||
/**
|
||||
* 重试间隔(s)
|
||||
*/
|
||||
private Integer retryInterval;
|
||||
|
||||
/**
|
||||
* 任务类型
|
||||
*/
|
||||
private Integer taskType;
|
||||
|
||||
/**
|
||||
* 并行数
|
||||
*/
|
||||
private Integer parallelNum;
|
||||
|
||||
/**
|
||||
* bucket
|
||||
*/
|
||||
private Integer bucketIndex;
|
||||
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private LocalDateTime createDt;
|
||||
|
||||
/**
|
||||
* 修改时间
|
||||
*/
|
||||
private LocalDateTime updateDt;
|
||||
|
||||
/**
|
||||
* 逻辑删除 1、删除
|
||||
*/
|
||||
private Integer deleted;
|
||||
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
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.response.JobResponseVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author www.byteblogs.com
|
||||
* @date 2023-10-11 22:20:23
|
||||
* @since 2.4.0
|
||||
*/
|
||||
public interface JobService {
|
||||
PageResult<List<JobResponseVO>> getJobPage(JobQueryVO jobQueryVO);
|
||||
|
||||
PageResult<List<JobResponseVO>> getJobDetail(Long id);
|
||||
|
||||
PageResult<List<JobResponseVO>> saveJob(JobRequestVO jobRequestVO);
|
||||
|
||||
PageResult<List<JobResponseVO>> updateJob(JobRequestVO jobRequestVO);
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package com.aizuda.easy.retry.server.web.service.convert;
|
||||
|
||||
import com.aizuda.easy.retry.server.web.model.response.JobResponseVO;
|
||||
import com.aizuda.easy.retry.template.datasource.persistence.po.Job;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author www.byteblogs.com
|
||||
* @date 2023-10-11 22:50:40
|
||||
* @since 2.4.0
|
||||
*/
|
||||
@Mapper
|
||||
public interface JobResponseVOConverter {
|
||||
|
||||
JobResponseVOConverter INSTANCE = Mappers.getMapper(JobResponseVOConverter.class);
|
||||
|
||||
List<JobResponseVO> toJobResponseVOs(List<Job> jobs);
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
package com.aizuda.easy.retry.server.web.service.impl;
|
||||
|
||||
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.response.JobResponseVO;
|
||||
import com.aizuda.easy.retry.server.web.service.JobService;
|
||||
import com.aizuda.easy.retry.server.web.service.convert.JobResponseVOConverter;
|
||||
import com.aizuda.easy.retry.template.datasource.persistence.mapper.JobMapper;
|
||||
import com.aizuda.easy.retry.template.datasource.persistence.po.Job;
|
||||
import com.aizuda.easy.retry.template.datasource.persistence.po.RetryTask;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author www.byteblogs.com
|
||||
* @date 2023-10-11 22:20:42
|
||||
* @since 2.4.0
|
||||
*/
|
||||
@Service
|
||||
public class JobServiceImpl implements JobService {
|
||||
|
||||
@Autowired
|
||||
private JobMapper jobMapper;
|
||||
|
||||
@Override
|
||||
public PageResult<List<JobResponseVO>> getJobPage(JobQueryVO queryVO) {
|
||||
|
||||
PageDTO<Job> pageDTO = new PageDTO<>(queryVO.getPage(), queryVO.getSize());
|
||||
|
||||
LambdaQueryWrapper<Job> queryWrapper = new LambdaQueryWrapper<>();
|
||||
PageDTO<Job> selectPage = jobMapper.selectPage(pageDTO, queryWrapper);
|
||||
|
||||
List<JobResponseVO> jobResponseList = JobResponseVOConverter.INSTANCE.toJobResponseVOs(selectPage.getRecords());
|
||||
|
||||
return new PageResult<>(pageDTO, jobResponseList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<List<JobResponseVO>> getJobDetail(Long id) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<List<JobResponseVO>> saveJob(JobRequestVO jobRequestVO) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<List<JobResponseVO>> updateJob(JobRequestVO jobRequestVO) {
|
||||
return null;
|
||||
}
|
||||
}
|
@ -97,9 +97,6 @@ public class RetryTaskServiceImpl implements RetryTaskService {
|
||||
@Autowired
|
||||
private List<TaskGenerator> taskGenerators;
|
||||
@Autowired
|
||||
@Qualifier("bitSetIdempotentStrategyHandler")
|
||||
protected IdempotentStrategy<String, Integer> idempotentStrategy;
|
||||
@Autowired
|
||||
private List<TaskActuator> taskActuators;
|
||||
|
||||
@Override
|
||||
@ -323,7 +320,6 @@ public class RetryTaskServiceImpl implements RetryTaskService {
|
||||
public boolean manualTriggerRetryTask(ManualTriggerTaskRequestVO requestVO) {
|
||||
|
||||
List<String> uniqueIds = requestVO.getUniqueIds();
|
||||
String groupName = requestVO.getGroupName();
|
||||
|
||||
List<RetryTask> list = accessTemplate.getRetryTaskAccess().list(requestVO.getGroupName(),
|
||||
new LambdaQueryWrapper<RetryTask>()
|
||||
@ -346,7 +342,6 @@ public class RetryTaskServiceImpl implements RetryTaskService {
|
||||
@Override
|
||||
public boolean manualTriggerCallbackTask(ManualTriggerTaskRequestVO requestVO) {
|
||||
List<String> uniqueIds = requestVO.getUniqueIds();
|
||||
String groupName = requestVO.getGroupName();
|
||||
|
||||
List<RetryTask> list = accessTemplate.getRetryTaskAccess().list(requestVO.getGroupName(),
|
||||
new LambdaQueryWrapper<RetryTask>()
|
||||
@ -366,29 +361,4 @@ public class RetryTaskServiceImpl implements RetryTaskService {
|
||||
return true;
|
||||
}
|
||||
|
||||
private WaitStrategy getRetryTaskWaitWaitStrategy(String groupName, String sceneName) {
|
||||
|
||||
SceneConfig sceneConfig = accessTemplate.getSceneConfigAccess().getSceneConfigByGroupNameAndSceneName(groupName, sceneName);
|
||||
Integer backOff = sceneConfig.getBackOff();
|
||||
|
||||
return WaitStrategies.WaitStrategyEnum.getWaitStrategy(backOff);
|
||||
}
|
||||
|
||||
private WaitStrategy getCallbackWaitWaitStrategy() {
|
||||
// 回调失败每15min重试一次
|
||||
return WaitStrategies.WaitStrategyEnum.getWaitStrategy(WaitStrategies.WaitStrategyEnum.FIXED.getBackOff());
|
||||
}
|
||||
|
||||
private void retryCountIncrement(RetryTask retryTask) {
|
||||
Integer retryCount = retryTask.getRetryCount();
|
||||
retryTask.setRetryCount(++retryCount);
|
||||
}
|
||||
|
||||
private void productExecUnitActor(RetryExecutor retryExecutor, ActorRef actorRef) {
|
||||
String groupIdHash = retryExecutor.getRetryContext().getRetryTask().getGroupName();
|
||||
Long retryId = retryExecutor.getRetryContext().getRetryTask().getId();
|
||||
idempotentStrategy.set(groupIdHash, retryId.intValue());
|
||||
|
||||
actorRef.tell(retryExecutor, actorRef);
|
||||
}
|
||||
}
|
||||
|
15
frontend/src/api/jobApi.js
Normal file
15
frontend/src/api/jobApi.js
Normal file
@ -0,0 +1,15 @@
|
||||
import request from '@/utils/request'
|
||||
const jobApi = {
|
||||
|
||||
jobList: '/job/list'
|
||||
}
|
||||
|
||||
export default jobApi
|
||||
|
||||
export function getJobList (parameter) {
|
||||
return request({
|
||||
url: jobApi.jobList,
|
||||
method: 'get',
|
||||
params: parameter
|
||||
})
|
||||
}
|
@ -1,7 +1,9 @@
|
||||
<template>
|
||||
<div :class="wrpCls">
|
||||
<avatar-dropdown :menu="showMenu" :current-user="currentUser" :class="prefixCls" />
|
||||
<!-- <select-lang :class="prefixCls" />-->
|
||||
<a href="https://www.easyretry.com" target="_blank" :class="prefixCls"><a-icon type="question-circle" :style="{ fontSize: '18px', color: '#08c' }"/></a>
|
||||
<avatar-dropdown :menu="showMenu" :current-user="currentUser" :class="prefixCls"/>
|
||||
<!-- <select-lang :class="prefixCls" />-->
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -15,16 +15,16 @@
|
||||
export default {
|
||||
navTheme: 'dark', // theme for nav menu
|
||||
primaryColor: '#1890ff', // '#F5222D', // primary color of ant design
|
||||
layout: 'topmenu', // nav menu position: `sidemenu` or `topmenu`
|
||||
contentWidth: 'Fixed', // layout of content: `Fluid` or `Fixed`, only works when layout is topmenu
|
||||
fixedHeader: false, // sticky header
|
||||
fixSiderbar: false, // sticky siderbar
|
||||
layout: 'sidemenu', // nav menu position: `sidemenu` or `topmenu`
|
||||
contentWidth: 'Fluid', // layout of content: `Fluid` or `Fixed`, only works when layout is topmenu
|
||||
fixedHeader: true, // sticky header
|
||||
fixSiderbar: true, // sticky siderbar
|
||||
colorWeak: false,
|
||||
menu: {
|
||||
locale: true
|
||||
},
|
||||
title: 'Easy Retry',
|
||||
pwa: false,
|
||||
iconfontUrl: '',
|
||||
iconfontUrl: 'https://www.easyretry.com/',
|
||||
production: process.env.NODE_ENV === 'production' && process.env.VUE_APP_PREVIEW !== 'true'
|
||||
}
|
||||
|
@ -131,9 +131,25 @@ export const asyncRouterMap = [
|
||||
meta: { title: '新增或更新用户', icon: 'profile', permission: ['userForm'] }
|
||||
},
|
||||
{
|
||||
path: 'https://www.easyretry.com',
|
||||
name: 'HelpDocs',
|
||||
meta: { title: '帮助文档', icon: 'question-circle', target: '_blank' }
|
||||
path: '/job',
|
||||
name: 'Job',
|
||||
component: RouteView,
|
||||
redirect: '/list',
|
||||
meta: { title: '任务调度管理', icon: 'profile', permission: ['retryLog'] },
|
||||
children: [
|
||||
{
|
||||
path: '/list',
|
||||
name: 'JobList',
|
||||
component: () => import('@/views/job/JobList'),
|
||||
meta: { title: '调度任务', icon: 'profile', permission: ['retryLog'] }
|
||||
},
|
||||
{
|
||||
path: '/retry-log/info',
|
||||
name: 'RetryLogInfo',
|
||||
component: () => import('@/views/task/RetryLogInfo'),
|
||||
meta: { title: '任务批次', icon: 'profile', permission: ['retryLog'] }
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
398
frontend/src/views/job/JobList.vue
Normal file
398
frontend/src/views/job/JobList.vue
Normal file
@ -0,0 +1,398 @@
|
||||
<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.retryStatus" placeholder="请选择状态" allowClear>
|
||||
<a-select-option v-for="(index, value) in retryStatus" :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"
|
||||
:scroll="{ x: 2000 }"
|
||||
>
|
||||
<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="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'
|
||||
|
||||
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'
|
||||
}
|
||||
},
|
||||
// 表头
|
||||
columns: [
|
||||
{
|
||||
title: 'ID',
|
||||
scopedSlots: { customRender: 'serial' },
|
||||
fixed: 'left'
|
||||
},
|
||||
{
|
||||
title: '组名称',
|
||||
dataIndex: 'groupName',
|
||||
width: '10%'
|
||||
},
|
||||
{
|
||||
title: '任务名称',
|
||||
dataIndex: 'jobName',
|
||||
ellipsis: true,
|
||||
width: '10%'
|
||||
},
|
||||
{
|
||||
title: '业务编号',
|
||||
dataIndex: 'bizNo',
|
||||
width: '10%'
|
||||
},
|
||||
{
|
||||
title: '下次触发时间',
|
||||
dataIndex: 'nextTriggerAt',
|
||||
needTotal: false,
|
||||
width: '10%'
|
||||
},
|
||||
{
|
||||
title: '次数',
|
||||
dataIndex: 'retryCount',
|
||||
sorter: true,
|
||||
width: '6%'
|
||||
},
|
||||
{
|
||||
title: '任务状态',
|
||||
dataIndex: 'jobStatus',
|
||||
scopedSlots: { customRender: 'jobStatus' },
|
||||
width: '5%'
|
||||
},
|
||||
{
|
||||
title: '任务类型',
|
||||
dataIndex: 'taskType',
|
||||
scopedSlots: { customRender: 'taskType' },
|
||||
width: '5%'
|
||||
},
|
||||
{
|
||||
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 () {
|
||||
},
|
||||
methods: {
|
||||
handleNew () {
|
||||
this.$refs.saveRetryTask.isShow(true, null)
|
||||
},
|
||||
handleBatchNew () {
|
||||
this.$refs.batchSaveRetryTask.isShow(true, null)
|
||||
},
|
||||
handleChange (value) {
|
||||
// getSceneList({ groupName: value }).then((res) => {
|
||||
// this.sceneList = res.data
|
||||
// })
|
||||
},
|
||||
toggleAdvanced () {
|
||||
this.advanced = !this.advanced
|
||||
},
|
||||
handleInfo (record) {
|
||||
this.$router.push({ path: '/retry-task/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>
|
Loading…
Reference in New Issue
Block a user