refactor(schedule): 重构任务调度模块,使用 OpenFeign 替代 WebClient

This commit is contained in:
2025-03-28 23:07:52 +08:00
parent 3408e4d01c
commit c041496f65
16 changed files with 276 additions and 306 deletions

View File

@@ -25,15 +25,10 @@
<artifactId>snail-job-client-job-core</artifactId>
</dependency>
<!-- Spring WebFlux异步非阻塞 Web 框架 -->
<!-- OpenFeign一种基于 Spring Cloud 的声明式 REST 客户端,它简化了与 HTTP 服务交互的过程 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webflux</artifactId>
</dependency>
<dependency>
<groupId>io.projectreactor.netty</groupId>
<artifactId>reactor-netty-http</artifactId>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -17,12 +17,12 @@
package top.continew.admin.schedule.api;
import com.aizuda.snailjob.common.core.model.Result;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.service.annotation.*;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.cloud.openfeign.SpringQueryMap;
import org.springframework.web.bind.annotation.*;
import top.continew.admin.schedule.config.FeignRequestInterceptor;
import top.continew.admin.schedule.model.JobPageResult;
import top.continew.admin.schedule.model.query.JobQuery;
import top.continew.admin.schedule.model.req.JobReq;
import top.continew.admin.schedule.model.req.JobStatusReq;
import top.continew.admin.schedule.model.req.JobTriggerReq;
@@ -38,25 +38,17 @@ import java.util.Set;
* @author Charles7c
* @since 2024/6/25 18:20
*/
@HttpExchange(accept = MediaType.APPLICATION_JSON_VALUE)
@FeignClient(value = "job", url = "${snail-job.server.api.url}", path = "/job", configuration = FeignRequestInterceptor.class)
public interface JobApi {
/**
* 分页查询列表
*
* @param groupName 任务组
* @param jobName 任务名称
* @param jobStatus 任务状态
* @param page 页码
* @param size 每页条数
* @param query 查询条件
* @return 响应信息
*/
@GetExchange("/job/page/list")
ResponseEntity<JobPageResult<List<JobResp>>> page(@RequestParam(value = "groupName", required = false) String groupName,
@RequestParam(value = "jobName", required = false) String jobName,
@RequestParam(value = "jobStatus", required = false) Integer jobStatus,
@RequestParam("page") int page,
@RequestParam("size") int size);
@GetMapping("/page/list")
JobPageResult<List<JobResp>> page(@SpringQueryMap JobQuery query);
/**
* 新增
@@ -64,8 +56,8 @@ public interface JobApi {
* @param req 新增信息
* @return 响应信息
*/
@PostExchange("/job")
ResponseEntity<Result<Boolean>> create(@RequestBody JobReq req);
@PostMapping
Result<Boolean> create(@RequestBody JobReq req);
/**
* 修改
@@ -73,8 +65,8 @@ public interface JobApi {
* @param req 修改信息
* @return 响应信息
*/
@PutExchange("/job")
ResponseEntity<Result<Boolean>> update(@RequestBody JobReq req);
@PutMapping
Result<Boolean> update(@RequestBody JobReq req);
/**
* 修改状态
@@ -82,8 +74,8 @@ public interface JobApi {
* @param req 修改信息
* @return 响应信息
*/
@PutExchange("/job/status")
ResponseEntity<Result<Boolean>> updateStatus(@RequestBody JobStatusReq req);
@PutMapping("/status")
Result<Boolean> updateStatus(@RequestBody JobStatusReq req);
/**
* 删除
@@ -91,8 +83,8 @@ public interface JobApi {
* @param ids ID 列表
* @return 响应信息
*/
@DeleteExchange("/job/ids")
ResponseEntity<Result<Boolean>> delete(@RequestBody Set<Long> ids);
@DeleteMapping("/ids")
Result<Boolean> delete(@RequestBody Set<Long> ids);
/**
* 执行
@@ -100,14 +92,6 @@ public interface JobApi {
* @param req 参数
* @return 响应信息
*/
@PostExchange("/job/trigger")
ResponseEntity<Result<Boolean>> trigger(@RequestBody JobTriggerReq req);
/**
* 查询分组列表
*
* @return 响应信息
*/
@GetExchange("/group/all/group-name/list")
ResponseEntity<Result<List<String>>> listGroup();
@PostMapping("/trigger")
Result<Boolean> trigger(@RequestBody JobTriggerReq req);
}

View File

@@ -17,15 +17,17 @@
package top.continew.admin.schedule.api;
import com.aizuda.snailjob.common.core.model.Result;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.cloud.openfeign.SpringQueryMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.service.annotation.GetExchange;
import org.springframework.web.service.annotation.HttpExchange;
import org.springframework.web.service.annotation.PostExchange;
import org.springframework.web.bind.annotation.PostMapping;
import top.continew.admin.schedule.config.FeignRequestInterceptor;
import top.continew.admin.schedule.model.JobInstanceLogPageResult;
import top.continew.admin.schedule.model.JobPageResult;
import top.continew.admin.schedule.model.query.JobInstanceLogQuery;
import top.continew.admin.schedule.model.query.JobInstanceQuery;
import top.continew.admin.schedule.model.query.JobLogQuery;
import top.continew.admin.schedule.model.resp.JobInstanceResp;
import top.continew.admin.schedule.model.resp.JobLogResp;
@@ -38,29 +40,17 @@ import java.util.List;
* @author Charles7c
* @since 2024/6/27 23:03
*/
@HttpExchange(value = "/job", accept = MediaType.APPLICATION_JSON_VALUE)
@FeignClient(value = "job-batch", url = "${snail-job.server.api.url}", path = "/job", configuration = FeignRequestInterceptor.class)
public interface JobBatchApi {
/**
* 分页查询列表
*
* @param jobId 任务 ID
* @param jobName 任务名称
* @param groupName 组名称
* @param taskBatchStatus 任务批次状态
* @param datetimeRange 时间范围
* @param page 页码
* @param size 每页条数
* @param query 查询条件
* @return 响应信息
*/
@GetExchange("/batch/list")
ResponseEntity<JobPageResult<List<JobLogResp>>> page(@RequestParam(value = "jobId", required = false) Long jobId,
@RequestParam(value = "jobName", required = false) String jobName,
@RequestParam(value = "groupName", required = false) String groupName,
@RequestParam(value = "taskBatchStatus", required = false) Integer taskBatchStatus,
@RequestParam(value = "datetimeRange", required = false) String[] datetimeRange,
@RequestParam(value = "page") Integer page,
@RequestParam(value = "size") Integer size);
@GetMapping("/batch/list")
JobPageResult<List<JobLogResp>> page(@SpringQueryMap JobLogQuery query);
/**
* 停止
@@ -68,8 +58,8 @@ public interface JobBatchApi {
* @param id ID
* @return 响应信息
*/
@PostExchange("/batch/stop/{id}")
ResponseEntity<Result<Boolean>> stop(@PathVariable("id") Long id);
@PostMapping("/batch/stop/{id}")
Result<Boolean> stop(@PathVariable("id") Long id);
/**
* 重试
@@ -77,40 +67,24 @@ public interface JobBatchApi {
* @param id ID
* @return 响应信息
*/
@PostExchange("/batch/retry/{id}")
ResponseEntity<Result<Boolean>> retry(@PathVariable("id") Long id);
@PostMapping("/batch/retry/{id}")
Result<Boolean> retry(@PathVariable("id") Long id);
/**
* 分页查询任务实例列表
*
* @param jobId 任务 ID
* @param taskBatchId 任务批次 ID
* @param page 页码
* @param size 每页条数
* @param query 查询条件
* @return 响应信息
*/
@GetExchange("/task/list")
ResponseEntity<JobPageResult<List<JobInstanceResp>>> pageTask(@RequestParam(value = "jobId", required = false) Long jobId,
@RequestParam(value = "taskBatchId") Long taskBatchId,
@RequestParam(value = "page") Integer page,
@RequestParam(value = "size") Integer size);
@GetMapping("/task/list")
JobPageResult<List<JobInstanceResp>> pageTask(@SpringQueryMap JobInstanceQuery query);
/**
* 分页查询任务实例日志列表
*
* @param jobId 任务 ID
* @param taskBatchId 任务批次 ID
* @param taskId 任务实例ID
* @param startId 起始 ID
* @param fromIndex 起始索引
* @param size 每页条数
* @param query 查询条件
* @return 响应信息
*/
@GetExchange("/log/list")
ResponseEntity<Result<JobInstanceLogPageResult>> pageLog(@RequestParam(value = "jobId", required = false) Long jobId,
@RequestParam(value = "taskBatchId") Long taskBatchId,
@RequestParam(value = "taskId") Long taskId,
@RequestParam(value = "startId") Integer startId,
@RequestParam(value = "fromIndex") Integer fromIndex,
@RequestParam(value = "size") Integer size);
@GetMapping("/log/list")
Result<JobInstanceLogPageResult> pageLog(@SpringQueryMap JobInstanceLogQuery query);
}

View File

@@ -31,7 +31,6 @@ import cn.hutool.jwt.RegisteredPayload;
import com.aizuda.snailjob.common.core.model.Result;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import top.continew.admin.schedule.constant.JobConstants;
import top.continew.admin.schedule.model.JobPageResult;
import top.continew.starter.cache.redisson.util.RedisUtils;
@@ -74,10 +73,8 @@ public class JobClient {
* @param <T> 响应类型
* @return 响应信息
*/
public <T> T request(Supplier<ResponseEntity<Result<T>>> apiSupplier) {
ResponseEntity<Result<T>> responseEntity = apiSupplier.get();
this.checkResponse(responseEntity);
Result<T> result = responseEntity.getBody();
public <T> T request(Supplier<Result<T>> apiSupplier) {
Result<T> result = apiSupplier.get();
if (!STATUS_SUCCESS.equals(result.getStatus())) {
throw new IllegalStateException(result.getMessage());
}
@@ -91,10 +88,8 @@ public class JobClient {
* @param <T> 响应类型
* @return 分页列表信息
*/
public <T> PageResp<T> requestPage(Supplier<ResponseEntity<JobPageResult<List<T>>>> apiSupplier) {
ResponseEntity<JobPageResult<List<T>>> responseEntity = apiSupplier.get();
this.checkResponse(responseEntity);
JobPageResult<List<T>> result = responseEntity.getBody();
public <T> PageResp<T> requestPage(Supplier<JobPageResult<List<T>>> apiSupplier) {
JobPageResult<List<T>> result = apiSupplier.get();
if (!STATUS_SUCCESS.equals(result.getStatus())) {
throw new IllegalStateException(result.getMessage());
}
@@ -143,15 +138,4 @@ public class JobClient {
}
return JSONUtil.parseObj(result.getData()).getStr("token");
}
/**
* 检查响应
*
* @param responseEntity 响应信息
*/
private void checkResponse(ResponseEntity<?> responseEntity) {
if (!responseEntity.getStatusCode().is2xxSuccessful() || responseEntity.getBody() == null) {
throw new IllegalStateException("连接任务调度中心异常");
}
}
}

View File

@@ -0,0 +1,42 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.continew.admin.schedule.api;
import com.aizuda.snailjob.common.core.model.Result;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import top.continew.admin.schedule.config.FeignRequestInterceptor;
import java.util.List;
/**
* 任务组 REST API
*
* @author Charles7c
* @since 2025/3/28 22:25
*/
@FeignClient(value = "job-group", url = "${snail-job.server.api.url}", path = "/group", configuration = FeignRequestInterceptor.class)
public interface JobGroupApi {
/**
* 查询分组列表
*
* @return 响应信息
*/
@GetMapping("/all/group-name/list")
Result<List<String>> listGroup();
}

View File

@@ -0,0 +1,63 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.continew.admin.schedule.config;
import feign.Logger;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import top.continew.admin.schedule.api.JobClient;
import top.continew.starter.core.autoconfigure.project.ProjectProperties;
/**
* Feign 配置
*
* @author Charles7c
* @since 2025/3/28 21:17
*/
@Configuration
@RequiredArgsConstructor
public class FeignConfiguration {
private final ProjectProperties projectProperties;
@Value("${snail-job.server.api.url}")
private String baseUrl;
@Value("${snail-job.server.api.username}")
private String username;
@Value("${snail-job.server.api.password}")
private String password;
/**
* 调度客户端
*/
@Bean
public JobClient jobClient() {
return new JobClient(baseUrl, username, password);
}
/**
* Feign 日志级别
*/
@Bean
public Logger.Level feignLoggerLevel() {
return projectProperties.isProduction() ? Logger.Level.BASIC : Logger.Level.FULL;
}
}

View File

@@ -0,0 +1,47 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.continew.admin.schedule.config;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import top.continew.admin.schedule.api.JobClient;
import top.continew.admin.schedule.constant.JobConstants;
/**
* Feign 请求拦截器
*
* @author Charles7c
* @since 2025/3/28 21:17
*/
@Component
@RequiredArgsConstructor
public class FeignRequestInterceptor implements RequestInterceptor {
private final JobClient jobClient;
@Value("${snail-job.namespace}")
private String namespace;
@Override
public void apply(RequestTemplate requestTemplate) {
requestTemplate.header(JobConstants.NAMESPACE_ID_HEADER, namespace);
requestTemplate.header(JobConstants.AUTH_TOKEN_HEADER, jobClient.getToken());
}
}

View File

@@ -1,134 +0,0 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.continew.admin.schedule.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.netty.channel.ChannelOption;
import io.netty.handler.timeout.ReadTimeoutHandler;
import io.netty.handler.timeout.WriteTimeoutHandler;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.http.codec.json.Jackson2JsonDecoder;
import org.springframework.http.codec.json.Jackson2JsonEncoder;
import org.springframework.web.reactive.function.client.ClientRequest;
import org.springframework.web.reactive.function.client.ClientResponse;
import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.client.support.WebClientAdapter;
import org.springframework.web.service.invoker.HttpServiceProxyFactory;
import reactor.core.publisher.Mono;
import reactor.netty.http.client.HttpClient;
import top.continew.admin.schedule.api.JobApi;
import top.continew.admin.schedule.api.JobBatchApi;
import top.continew.admin.schedule.api.JobClient;
import top.continew.admin.schedule.constant.JobConstants;
/**
* HTTP Exchange 配置
*
* @author KAI
* @author Charles7c
* @since 2024/6/25 18:03
*/
@Slf4j
@Configuration
@RequiredArgsConstructor
public class HttpExchangeConfiguration {
private final ObjectMapper objectMapper;
@Value("${snail-job.namespace}")
private String namespace;
@Value("${snail-job.server.api.url}")
private String baseUrl;
@Value("${snail-job.server.api.username}")
private String username;
@Value("${snail-job.server.api.password}")
private String password;
@Bean
public JobApi jobApi() {
return httpServiceProxyFactory().createClient(JobApi.class);
}
@Bean
public JobBatchApi jobBatchApi() {
return httpServiceProxyFactory().createClient(JobBatchApi.class);
}
@Bean
public HttpServiceProxyFactory httpServiceProxyFactory() {
HttpClient httpClient = HttpClient.create()
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 30000)
.doOnConnected(conn -> {
conn.addHandlerLast(new ReadTimeoutHandler(10));
conn.addHandlerLast(new WriteTimeoutHandler(10));
})
.wiretap(true);
WebClient webClient = WebClient.builder()
.codecs(config -> config.defaultCodecs().jackson2JsonEncoder(new Jackson2JsonEncoder(objectMapper)))
.codecs(config -> config.defaultCodecs().jackson2JsonDecoder(new Jackson2JsonDecoder(objectMapper)))
.clientConnector(new ReactorClientHttpConnector(httpClient))
.filter(logRequest())
.filter(logResponse())
.filter((request, next) -> {
// 设置请求头
ClientRequest filtered = ClientRequest.from(request)
.header(JobConstants.NAMESPACE_ID_HEADER, namespace)
.header(JobConstants.AUTH_TOKEN_HEADER, jobClient().getToken())
.build();
return next.exchange(filtered);
})
.baseUrl(baseUrl)
.build();
return HttpServiceProxyFactory.builderFor(WebClientAdapter.create(webClient)).build();
}
@Bean
public JobClient jobClient() {
return new JobClient(baseUrl, username, password);
}
/**
* 打印请求日志
*/
private ExchangeFilterFunction logRequest() {
return ExchangeFilterFunction.ofRequestProcessor(request -> {
log.info("---> {} {}", request.method(), request.url());
return Mono.just(request);
});
}
/**
* 打印响应日志
*/
private ExchangeFilterFunction logResponse() {
return ExchangeFilterFunction.ofResponseProcessor(response -> response.bodyToMono(String.class)
.flatMap(body -> {
log.info("<--- {}", response.statusCode());
log.info(body);
return Mono.just(ClientResponse.from(response).body(body).build());
}));
}
}

View File

@@ -17,14 +17,12 @@
package top.continew.admin.schedule.model.query;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.Size;
import lombok.Data;
import org.hibernate.validator.constraints.Range;
import top.continew.admin.schedule.enums.JobExecuteStatusEnum;
import top.continew.starter.core.validation.constraints.EnumValue;
import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
@@ -35,7 +33,7 @@ import java.time.LocalDateTime;
*/
@Data
@Schema(description = "任务日志查询条件")
public class JobLogQuery implements Serializable {
public class JobLogQuery extends JobPageQuery {
@Serial
private static final long serialVersionUID = 1L;
@@ -62,7 +60,8 @@ public class JobLogQuery implements Serializable {
* 任务批次状态
*/
@Schema(description = "任务批次状态", example = "1")
private JobExecuteStatusEnum taskBatchStatus;
@EnumValue(value = JobExecuteStatusEnum.class, message = "任务批次状态无效")
private Integer taskBatchStatus;
/**
* 创建时间
@@ -70,18 +69,4 @@ public class JobLogQuery implements Serializable {
@Schema(description = "创建时间", example = "2023-08-08 00:00:00,2023-08-08 23:59:59")
@Size(max = 2, message = "创建时间必须是一个范围")
private LocalDateTime[] datetimeRange;
/**
* 页码
*/
@Schema(description = "页码", example = "1")
@Min(value = 1, message = "页码最小值为 {value}")
private Integer page = 1;
/**
* 每页条数
*/
@Schema(description = "每页条数", example = "10")
@Range(min = 1, max = 1000, message = "每页条数(取值范围 {min}-{max}")
private Integer size = 10;
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.continew.admin.schedule.model.query;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Min;
import lombok.Data;
import org.hibernate.validator.constraints.Range;
import java.io.Serial;
import java.io.Serializable;
/**
* 任务分页查询条件
*
* @author Charles7c
* @since 2025/3/28 21:55
*/
@Data
public class JobPageQuery implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 页码
*/
@Schema(description = "页码", example = "1")
@Min(value = 1, message = "页码最小值为 {value}")
private Integer page = 1;
/**
* 每页条数
*/
@Schema(description = "每页条数", example = "10")
@Range(min = 1, max = 1000, message = "每页条数(取值范围 {min}-{max}")
private Integer size = 10;
}

View File

@@ -17,13 +17,11 @@
package top.continew.admin.schedule.model.query;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Min;
import lombok.Data;
import org.hibernate.validator.constraints.Range;
import top.continew.admin.schedule.enums.JobStatusEnum;
import top.continew.starter.core.validation.constraints.EnumValue;
import java.io.Serial;
import java.io.Serializable;
/**
* 任务查询条件
@@ -33,7 +31,7 @@ import java.io.Serializable;
*/
@Data
@Schema(description = "任务查询条件")
public class JobQuery implements Serializable {
public class JobQuery extends JobPageQuery {
@Serial
private static final long serialVersionUID = 1L;
@@ -54,19 +52,6 @@ public class JobQuery implements Serializable {
* 任务状态
*/
@Schema(description = "任务状态", example = "1")
private JobStatusEnum jobStatus;
/**
* 页码
*/
@Schema(description = "页码", example = "1")
@Min(value = 1, message = "页码最小值为 {value}")
private Integer page = 1;
/**
* 每页条数
*/
@Schema(description = "每页条数", example = "10")
@Range(min = 1, max = 1000, message = "每页条数(取值范围 {min}-{max}")
private Integer size = 10;
@EnumValue(value = JobStatusEnum.class, message = "任务状态无效")
private Integer jobStatus;
}

View File

@@ -80,18 +80,18 @@ public class JobResp implements Serializable {
@Schema(description = " 执行器类型", example = "1")
private Integer executorType;
/**
* 任务类型
*/
@Schema(description = "任务类型", example = "1")
private JobTaskTypeEnum taskType;
/**
* 执行器名称
*/
@Schema(description = "执行器名称", example = "test")
private String executorInfo;
/**
* 任务类型
*/
@Schema(description = "任务类型", example = "1")
private JobTaskTypeEnum taskType;
/**
* 任务参数
*/

View File

@@ -16,8 +16,6 @@
package top.continew.admin.schedule.service.impl;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import top.continew.admin.schedule.api.JobBatchApi;
@@ -31,9 +29,7 @@ import top.continew.admin.schedule.model.resp.JobLogResp;
import top.continew.admin.schedule.service.JobLogService;
import top.continew.starter.extension.crud.model.resp.PageResp;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
/**
* 任务日志业务实现
@@ -51,12 +47,7 @@ public class JobLogServiceImpl implements JobLogService {
@Override
public PageResp<JobLogResp> page(JobLogQuery query) {
LocalDateTime[] datetimeRange = query.getDatetimeRange();
return jobClient.requestPage(() -> jobBatchApi.page(query.getJobId(), query.getJobName(), query
.getGroupName(), query.getTaskBatchStatus() != null
? query.getTaskBatchStatus().getValue()
: null, new String[] {DateUtil.format(datetimeRange[0], DatePattern.UTC_SIMPLE_PATTERN), DateUtil
.format(datetimeRange[1], DatePattern.UTC_SIMPLE_PATTERN)}, query.getPage(), query.getSize()));
return jobClient.requestPage(() -> jobBatchApi.page(query));
}
@Override
@@ -71,13 +62,11 @@ public class JobLogServiceImpl implements JobLogService {
@Override
public List<JobInstanceResp> listInstance(JobInstanceQuery query) {
return jobClient.requestPage(() -> jobBatchApi.pageTask(query.getJobId(), query.getTaskBatchId(), 1, 100))
.getList();
return jobClient.requestPage(() -> jobBatchApi.pageTask(query)).getList();
}
@Override
public JobInstanceLogPageResult pageInstanceLog(JobInstanceLogQuery query) {
return Objects.requireNonNull(jobBatchApi.pageLog(query.getJobId(), query.getTaskBatchId(), query
.getTaskId(), query.getStartId(), query.getFromIndex(), query.getSize()).getBody()).getData();
return jobClient.request(() -> jobBatchApi.pageLog(query));
}
}

View File

@@ -20,6 +20,7 @@ import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import top.continew.admin.schedule.api.JobApi;
import top.continew.admin.schedule.api.JobClient;
import top.continew.admin.schedule.api.JobGroupApi;
import top.continew.admin.schedule.model.query.JobQuery;
import top.continew.admin.schedule.model.req.JobReq;
import top.continew.admin.schedule.model.req.JobStatusReq;
@@ -44,11 +45,11 @@ public class JobServiceImpl implements JobService {
private final JobClient jobClient;
private final JobApi jobApi;
private final JobGroupApi jobGroupApi;
@Override
public PageResp<JobResp> page(JobQuery query) {
return jobClient.requestPage(() -> jobApi.page(query.getGroupName(), query.getJobName(), query
.getJobStatus() != null ? query.getJobStatus().getValue() : null, query.getPage(), query.getSize()));
return jobClient.requestPage(() -> jobApi.page(query));
}
@Override
@@ -80,6 +81,6 @@ public class JobServiceImpl implements JobService {
@Override
public List<String> listGroup() {
return jobClient.request(jobApi::listGroup);
return jobClient.request(jobGroupApi::listGroup);
}
}