调度中心API

This commit is contained in:
XinWei 2024-07-10 15:17:48 +08:00
parent e309502115
commit f6e2f92352
27 changed files with 988 additions and 318 deletions

View File

@ -43,6 +43,10 @@
<artifactId>spring-cloud-starter-openfeign</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-spring-boot-starter-excel</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -2,25 +2,24 @@ package com.xxl.job.admin.api.info;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import com.xxl.job.admin.api.info.dto.JobInfoDetailRespDTO;
import com.xxl.job.admin.api.info.dto.JobInfoRespDTO;
import com.xxl.job.admin.api.info.dto.JobInfoSaveReqDTO;
import com.xxl.job.admin.enums.ApiConstants;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
/**
* @Description TODO
* @Description 调度任务信息Api接口
*/
@FeignClient(name = ApiConstants.NAME)
@FeignClient(name = ApiConstants.NAME, path = "/xxl-job-admin")
@Tag(name = "RPC 服务 - 任务信息管理")
@RequestMapping("")
public interface JobInfoApi {
String PREFIX = ApiConstants.PREFIX + "/info";
@GetMapping(PREFIX + "/page")
@ -32,4 +31,31 @@ public interface JobInfoApi {
@Parameter(name = "handlerName", description = "处理器名字", required = false)
public CommonResult<PageResult<JobInfoRespDTO>> getPage(@RequestParam(value = "pageNo") Integer pageNo, @RequestParam(value = "pageSize") Integer pageSize, @RequestParam(required = false, value = "name") String name, @RequestParam(required = false, value = "status") Integer status, @RequestParam(required = false, value = "handlerName") String handlerName);
@GetMapping(PREFIX + "/get")
@Operation(summary = "获得任务详情")
@Parameter(name = "id", description = "任务主键", required = true)
CommonResult<JobInfoDetailRespDTO> get(@RequestParam("id") Integer id);
@PostMapping(PREFIX + "/create")
@Operation(summary = "创建任务")
CommonResult<Boolean> create(@RequestBody JobInfoSaveReqDTO jobInfoSaveReqDTO);
@PutMapping(PREFIX + "/update")
@Operation(summary = "修改任务")
CommonResult<Boolean> update(@RequestBody JobInfoSaveReqDTO jobInfoSaveReqDTO);
@DeleteMapping(PREFIX + "/delete")
@Operation(summary = "删除任务")
CommonResult<Boolean> delete(@RequestParam("id") Integer id);
@PutMapping(PREFIX + "/update-status")
@Operation(summary = "任务状态修改")
CommonResult<Boolean> updateStatus(@RequestParam("id") Integer id, @RequestParam("status") Integer status);
@PutMapping(PREFIX + "/trigger")
@Operation(summary = "任务立即执行一次")
CommonResult<Object> trigger(@RequestParam("id") Integer id);
@GetMapping(PREFIX + "/get_next_times")
@Operation(summary = "下n次执行时间")
CommonResult<List<String>> getNextTimes(@RequestParam("id") Integer id);
}

View File

@ -0,0 +1,26 @@
package com.xxl.job.admin.api.info.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* @Description 任务详情
*/
@Schema(description = "RPC 服务 - 任务信息 Response DTO")
@Data
public class JobInfoDetailRespDTO {
@Schema(description = "任务编号", requiredMode = Schema.RequiredMode.REQUIRED)
private Integer id;
@Schema(description = "任务名称")
private String name;
@Schema(description = "处理器的名字")
private String handlerName;
@Schema(description = "处理器的参数")
private String handlerParam;
@Schema(description = "CRON 表达式")
private String cronExpression;
@Schema(description = "重试次数")
private Integer retryCount;
@Schema(description = "监控超时时间")
private Integer monitorTimeout;
}

View File

@ -0,0 +1,24 @@
package com.xxl.job.admin.api.info.dto;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
@Schema(description = "RPC 服务 - 任务列表 Request DTO")
@Data
public class JobInfoPageReqDTO extends PageParam {
@Schema(description = "任务编号", requiredMode = Schema.RequiredMode.REQUIRED)
private Integer id;
@Schema(description = "任务名称")
private String name;
@Schema(description = "任务状态")
private Integer status;
@Schema(description = "处理器的名字")
private String handlerName;
@Schema(description = "处理器的参数")
private String handlerParam;
@Schema(description = "CRON 表达式")
private String cronExpression;
}

View File

@ -1,25 +1,34 @@
package com.xxl.job.admin.api.info.dto;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* @Description 任务信息
* @Description 任务列表单个信息
*/
@Schema(description = "RPC 服务 - 任务信息 Response DTO")
@Data
@ExcelIgnoreUnannotated
public class JobInfoRespDTO {
@Schema(description = "任务编号", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("任务编号")
private Integer id;
@Schema(description = "任务名称")
@ExcelProperty("任务名称")
private String name;
@Schema(description = "任务状态")
@ExcelProperty("任务状态")
private Integer status;
@Schema(description = "处理器的名字")
@ExcelProperty("处理器的名字")
private String handlerName;
@Schema(description = "处理器的参数")
@ExcelProperty("处理器的参数")
private String handlerParam;
@Schema(description = "CRON 表达式")
@ExcelProperty("CRON 表达式")
private String cronExpression;
}

View File

@ -0,0 +1,26 @@
package com.xxl.job.admin.api.info.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* @Description TODO
*/
@Schema(description = "RPC 服务 - 新增任务 Request DTO")
@Data
public class JobInfoSaveReqDTO {
@Schema(description = "任务编号")
private Integer id;
@Schema(description = "任务名称")
private String name;
@Schema(description = "处理器的名字")
private String handlerName;
@Schema(description = "处理器的参数")
private String handlerParam;
@Schema(description = "CRON 表达式")
private String cronExpression;
@Schema(description = "重试次数")
private Integer retryCount;
@Schema(description = "监控超时时间")
private Integer monitorTimeout;
}

View File

@ -0,0 +1,28 @@
package com.xxl.job.admin.api.log;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import com.xxl.job.admin.api.info.dto.JobInfoRespDTO;
import com.xxl.job.admin.api.log.dto.JobLogPageReqDTO;
import com.xxl.job.admin.api.log.dto.JobLogRespDTO;
import com.xxl.job.admin.enums.ApiConstants;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import javax.validation.Valid;
/**
* @Description 调度任务日志Api接口
*/
@FeignClient(name = ApiConstants.NAME, path = "/xxl-job-admin")
@Tag(name = "RPC 服务 - 任务日志管理")
public interface JobLogApi {
String PREFIX = ApiConstants.PREFIX + "/log";
@GetMapping(PREFIX + "/page")
@Operation(summary = "获得所有任务列表")
public CommonResult<PageResult<JobLogRespDTO>> getPage(@Valid JobLogPageReqDTO jobLogPageReqDTO);
}

View File

@ -0,0 +1,29 @@
package com.xxl.job.admin.api.log.dto;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.util.Date;
@Schema(description = "RPC 服务 - 任务日志 Request DTO")
@Data
public class JobLogPageReqDTO extends PageParam {
@NotNull(message = "任务编号不能为空")
@Schema(description = "任务编号")
private Integer jobId;
@Schema(description = "处理器的名字")
private String handlerName;
@Schema(description = "开始执行时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date beginTime;
@Schema(description = "结束执行时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date endTime;
@Schema(description = "任务状态")
private Integer status;
}

View File

@ -0,0 +1,42 @@
package com.xxl.job.admin.api.log.dto;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.Date;
@Schema(description = "RPC 服务 - 任务日志 Response DTO")
@Data
@ExcelIgnoreUnannotated
public class JobLogRespDTO {
@Schema(description = "日志编号")
@ExcelProperty("日志编号")
private Integer id;
@Schema(description = "任务编号")
@ExcelProperty("任务编号")
private Integer jobId;
@Schema(description = "处理器的名字")
@ExcelProperty("处理器的名字")
private String handlerName;
@Schema(description = "处理器的参数")
@ExcelProperty("处理器的参数")
private String handlerParam;
@Schema(description = "第几次执行")
@ExcelProperty("第几次执行")
private Integer executeIndex;
@Schema(description = "开始执行时间")
@ExcelProperty("开始执行时间")
private Date beginTime;
@Schema(description = "结束执行时间")
@ExcelProperty("结束执行时间")
private Date endTime;
@Schema(description = "执行时长")
@ExcelProperty("执行时长")
private Integer duration;
@Schema(description = "任务状态")
@ExcelProperty("任务状态")
private Integer status;
}

View File

@ -2,7 +2,9 @@ package com.xxl.job.admin.api.info;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import com.xxl.job.admin.api.info.dto.JobInfoDetailRespDTO;
import com.xxl.job.admin.api.info.dto.JobInfoRespDTO;
import com.xxl.job.admin.api.info.dto.JobInfoSaveReqDTO;
import com.xxl.job.admin.service.XxlJobService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RestController;
@ -14,7 +16,7 @@ import java.util.Map;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
/**
* @Description TODO
* @Description 调度任务信息Api实现类
*/
@RestController // 提供 RESTful API 接口 Feign 调用
@Validated
@ -26,4 +28,40 @@ public class JobInfoApiImpl implements JobInfoApi{
public CommonResult<PageResult<JobInfoRespDTO>> getPage(Integer pageNo, Integer pageSize, String name, Integer status, String handlerName) {
return success(xxlJobService.apiPage(pageNo, pageSize, name, status, handlerName));
}
@Override
public CommonResult<JobInfoDetailRespDTO> get(Integer id) {
return success(xxlJobService.apiGet(id));
}
@Override
public CommonResult<Boolean> create(JobInfoSaveReqDTO jobInfoSaveReqDTO) {
return xxlJobService.apiCreate(jobInfoSaveReqDTO);
}
@Override
public CommonResult<Boolean> update(JobInfoSaveReqDTO jobInfoSaveReqDTO) {
return xxlJobService.apiUpdate(jobInfoSaveReqDTO);
}
@Override
public CommonResult<Boolean> delete(Integer id) {
return success(xxlJobService.apiDelete(id));
}
@Override
public CommonResult<Boolean> updateStatus(Integer id, Integer status) {
return success(xxlJobService.apiUpdateStatus(id, status));
}
@Override
public CommonResult<Object> trigger(Integer id) {
return xxlJobService.apiTrigger(id);
}
@Override
public CommonResult<List<String>> getNextTimes(Integer id) {
return xxlJobService.apiGetNextTimes(id);
}
}

View File

@ -0,0 +1,56 @@
package com.xxl.job.admin.api.log;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import com.xxl.job.admin.api.info.dto.JobInfoRespDTO;
import com.xxl.job.admin.api.log.dto.JobLogPageReqDTO;
import com.xxl.job.admin.api.log.dto.JobLogRespDTO;
import com.xxl.job.admin.controller.JobInfoController;
import com.xxl.job.admin.controller.JobLogController;
import com.xxl.job.admin.core.model.XxlJobLog;
import com.xxl.job.admin.dao.XxlJobGroupDao;
import com.xxl.job.admin.dao.XxlJobInfoDao;
import com.xxl.job.admin.dao.XxlJobLogDao;
import com.xxl.job.core.util.DateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Description 调度任务日志Api实现类
*/
@RestController // 提供 RESTful API 接口 Feign 调用
@Validated
public class JobLogApiImpl implements JobLogApi {
private static Logger logger = LoggerFactory.getLogger(JobLogController.class);
@Resource
private XxlJobGroupDao xxlJobGroupDao;
@Resource
public XxlJobInfoDao xxlJobInfoDao;
@Resource
public XxlJobLogDao xxlJobLogDao;
@Override
public CommonResult<PageResult<JobLogRespDTO>> getPage(JobLogPageReqDTO jobLogPageReqDTO) {
// 设置默认组为3
int jobGroup = 3;
int status = jobLogPageReqDTO.getStatus() == null ? -1 : jobLogPageReqDTO.getStatus();
// page query
List<JobLogRespDTO> list = xxlJobLogDao.apiPageList(jobLogPageReqDTO.getPageNo(), jobLogPageReqDTO.getPageSize(), jobGroup, jobLogPageReqDTO.getJobId(), jobLogPageReqDTO.getBeginTime(), jobLogPageReqDTO.getEndTime(), status);
int list_count = xxlJobLogDao.pageListCount(jobLogPageReqDTO.getPageNo(), jobLogPageReqDTO.getPageSize(), jobGroup, jobLogPageReqDTO.getJobId(), jobLogPageReqDTO.getBeginTime(), jobLogPageReqDTO.getEndTime(), status);
// package result
PageResult<JobLogRespDTO> pageResult = new PageResult<>();
pageResult.setTotal((long) list_count);
pageResult.setList(list);
return CommonResult.success(pageResult);
}
}

View File

@ -1,7 +1,9 @@
package com.xxl.job.admin.dao;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import com.xxl.job.admin.api.info.dto.JobInfoDetailRespDTO;
import com.xxl.job.admin.api.info.dto.JobInfoRespDTO;
import com.xxl.job.admin.api.info.dto.JobInfoSaveReqDTO;
import com.xxl.job.admin.core.model.XxlJobInfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@ -51,4 +53,7 @@ public interface XxlJobInfoDao extends BaseMapperX<XxlJobInfo> {
List<JobInfoRespDTO> apiPage(@Param("pageNo") Integer pageNo, @Param("pageSize") Integer pageSize, @Param("name") String name, @Param("status") Integer status, @Param("handlerName") String handlerName);
Long apiPageCount(@Param("name") String name, @Param("status") Integer status, @Param("handlerName") String handlerName);
JobInfoDetailRespDTO apiGet(@Param("id") Integer id);
}

View File

@ -1,5 +1,6 @@
package com.xxl.job.admin.dao;
import com.xxl.job.admin.api.log.dto.JobLogRespDTO;
import com.xxl.job.admin.core.model.XxlJobLog;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@ -23,6 +24,13 @@ public interface XxlJobLogDao {
@Param("triggerTimeStart") Date triggerTimeStart,
@Param("triggerTimeEnd") Date triggerTimeEnd,
@Param("logStatus") int logStatus);
public List<JobLogRespDTO> apiPageList(@Param("offset") int offset,
@Param("pagesize") int pagesize,
@Param("jobGroup") int jobGroup,
@Param("jobId") int jobId,
@Param("triggerTimeStart") Date triggerTimeStart,
@Param("triggerTimeEnd") Date triggerTimeEnd,
@Param("logStatus") Integer logStatus);
public int pageListCount(@Param("offset") int offset,
@Param("pagesize") int pagesize,
@Param("jobGroup") int jobGroup,

View File

@ -1,7 +1,7 @@
package com.xxl.job.admin.framework.security.config;
import cn.iocoder.yudao.framework.security.config.AuthorizeRequestsCustomizer;
import cn.iocoder.yudao.module.system.enums.ApiConstants;
import com.xxl.job.admin.enums.ApiConstants;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
@ -29,6 +29,8 @@ public class SecurityConfiguration {
.antMatchers("/actuator/**").anonymous();
// RPC 服务的安全配置
registry.antMatchers(ApiConstants.PREFIX + "/**").permitAll();
// 放行所有后台原本请求和rpc接口
registry.antMatchers("/**").permitAll();
}
};

View File

@ -83,24 +83,33 @@ public class LoginService {
* @return
*/
public XxlJobUser ifLogin(HttpServletRequest request, HttpServletResponse response){
String cookieToken = CookieUtil.getValue(request, LOGIN_IDENTITY_KEY);
if (cookieToken != null) {
XxlJobUser cookieUser = null;
try {
cookieUser = parseToken(cookieToken);
} catch (Exception e) {
logout(request, response);
}
if (cookieUser != null) {
XxlJobUser dbUser = xxlJobUserDao.loadByUserName(cookieUser.getUsername());
if (dbUser != null) {
if (cookieUser.getPassword().equals(dbUser.getPassword())) {
return dbUser;
}
}
}
}
return null;
// String cookieToken = CookieUtil.getValue(request, LOGIN_IDENTITY_KEY);
// if (cookieToken != null) {
// XxlJobUser cookieUser = null;
// try {
// cookieUser = parseToken(cookieToken);
// } catch (Exception e) {
// logout(request, response);
// }
// if (cookieUser != null) {
// XxlJobUser dbUser = xxlJobUserDao.loadByUserName(cookieUser.getUsername());
// if (dbUser != null) {
// if (cookieUser.getPassword().equals(dbUser.getPassword())) {
// return dbUser;
// }
// }
// }
// }
// return null;
// TODO 暂时放行cookie
XxlJobUser test = new XxlJobUser();
test.setId(1);
test.setUsername("admin");
test.setPassword("e10adc3949ba59abbe56e057f20f883e");
test.setRole(1);
test.setPermission(null);
return test;
}
}

View File

@ -3,7 +3,9 @@ package com.xxl.job.admin.service;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import com.xxl.job.admin.api.info.dto.JobInfoDetailRespDTO;
import com.xxl.job.admin.api.info.dto.JobInfoRespDTO;
import com.xxl.job.admin.api.info.dto.JobInfoSaveReqDTO;
import com.xxl.job.admin.core.model.XxlJobInfo;
import com.xxl.job.admin.core.model.XxlJobUser;
import com.xxl.job.core.biz.model.ReturnT;
@ -109,4 +111,54 @@ public interface XxlJobService {
* @return
*/
PageResult<JobInfoRespDTO> apiPage(Integer pageNo, Integer pageSize, String name, Integer status, String handlerName);
/**
* api接口用于查看任务详情
* @param id
* @return com.xxl.job.admin.api.info.dto.JobInfoDetailRespDTO
*/
JobInfoDetailRespDTO apiGet(Integer id);
/**
* api接口用于创建任务
* @param jobInfoSaveReqDTO
* @return
*/
CommonResult<Boolean> apiCreate(JobInfoSaveReqDTO jobInfoSaveReqDTO);
/**
* api接口用于修改任务
* @param jobInfoSaveReqDTO
* @return
*/
CommonResult<Boolean> apiUpdate(JobInfoSaveReqDTO jobInfoSaveReqDTO);
/**
* api接口用于删除任务
* @param id
* @return
*/
Boolean apiDelete(Integer id);
/**
* api接口用于任务状态修改
* @param id
* @param status
* @return
*/
Boolean apiUpdateStatus(Integer id, Integer status);
/**
* api接口用于任务立即执行一次
* @param id
* @return
*/
CommonResult<Object> apiTrigger(Integer id);
/**
* api接口用于获取下N次执行时间
* @param id
* @return cn.iocoder.yudao.framework.common.pojo.CommonResult<java.util.List<java.lang.String>>
*/
CommonResult<List<String>> apiGetNextTimes(Integer id);
}

View File

@ -1,7 +1,10 @@
package com.xxl.job.admin.service.impl;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import com.xxl.job.admin.api.info.dto.JobInfoDetailRespDTO;
import com.xxl.job.admin.api.info.dto.JobInfoRespDTO;
import com.xxl.job.admin.api.info.dto.JobInfoSaveReqDTO;
import com.xxl.job.admin.core.cron.CronExpression;
import com.xxl.job.admin.core.model.XxlJobGroup;
import com.xxl.job.admin.core.model.XxlJobInfo;
@ -28,6 +31,9 @@ import javax.annotation.Resource;
import java.text.MessageFormat;
import java.util.*;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.error;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
/**
* core job action for xxl-job
* @author xuxueli 2016-5-28 15:30:33
@ -481,4 +487,126 @@ public class XxlJobServiceImpl implements XxlJobService {
return pageResult;
}
@Override
public JobInfoDetailRespDTO apiGet(Integer id) {
return xxlJobInfoDao.apiGet(id);
}
@Override
public CommonResult<Boolean> apiCreate(JobInfoSaveReqDTO jobInfoSaveReqDTO) {
XxlJobInfo xxlJobInfo = new XxlJobInfo();
xxlJobInfo.setJobDesc(jobInfoSaveReqDTO.getName());
xxlJobInfo.setExecutorHandler(jobInfoSaveReqDTO.getHandlerName());
xxlJobInfo.setExecutorParam(jobInfoSaveReqDTO.getHandlerParam());
xxlJobInfo.setScheduleConf(jobInfoSaveReqDTO.getCronExpression());
if (jobInfoSaveReqDTO.getRetryCount() != null){
xxlJobInfo.setExecutorFailRetryCount(jobInfoSaveReqDTO.getRetryCount());
}
if (jobInfoSaveReqDTO.getMonitorTimeout() != null){
xxlJobInfo.setExecutorTimeout(jobInfoSaveReqDTO.getMonitorTimeout());
}
// 设置默认参数 默认为第3组
xxlJobInfo.setJobGroup(3);
xxlJobInfo.setAuthor("ludu");
xxlJobInfo.setScheduleType("CRON");
xxlJobInfo.setGlueType("BEAN");
xxlJobInfo.setExecutorRouteStrategy("FIRST");
xxlJobInfo.setMisfireStrategy("DO_NOTHING");
xxlJobInfo.setExecutorBlockStrategy("SERIAL_EXECUTION");
xxlJobInfo.setGlueRemark("GLUE代码初始化");
ReturnT<String> add = add(xxlJobInfo);
if (add.getCode() == ReturnT.FAIL_CODE){
return error(add.getCode(), add.getMsg());
}
return success(true);
}
@Override
public CommonResult<Boolean> apiUpdate(JobInfoSaveReqDTO jobInfoSaveReqDTO) {
XxlJobInfo xxlJobInfo = new XxlJobInfo();
xxlJobInfo.setId(jobInfoSaveReqDTO.getId());
xxlJobInfo.setJobDesc(jobInfoSaveReqDTO.getName());
xxlJobInfo.setExecutorHandler(jobInfoSaveReqDTO.getHandlerName());
xxlJobInfo.setExecutorParam(jobInfoSaveReqDTO.getHandlerParam());
xxlJobInfo.setScheduleConf(jobInfoSaveReqDTO.getCronExpression());
if (jobInfoSaveReqDTO.getRetryCount() != null){
xxlJobInfo.setExecutorFailRetryCount(jobInfoSaveReqDTO.getRetryCount());
}
if (jobInfoSaveReqDTO.getMonitorTimeout() != null){
xxlJobInfo.setExecutorTimeout(jobInfoSaveReqDTO.getMonitorTimeout());
}
// 设置默认参数 默认为第3组
xxlJobInfo.setJobGroup(3);
xxlJobInfo.setAuthor("ludu");
xxlJobInfo.setScheduleType("CRON");
xxlJobInfo.setGlueType("BEAN");
xxlJobInfo.setExecutorRouteStrategy("FIRST");
xxlJobInfo.setMisfireStrategy("DO_NOTHING");
xxlJobInfo.setExecutorBlockStrategy("SERIAL_EXECUTION");
xxlJobInfo.setGlueRemark("GLUE代码初始化");
ReturnT<String> update = update(xxlJobInfo);
if (update.getCode() == ReturnT.FAIL_CODE){
return error(update.getCode(), update.getMsg());
}
return success(true);
}
@Override
public Boolean apiDelete(Integer id) {
remove(id);
return true;
}
@Override
public Boolean apiUpdateStatus(Integer id, Integer status) {
if (status == null || id == null){
return false;
}
if (status == 1){
start(id);
}else if (status == 2){
stop(id);
}else{
return false;
}
return true;
}
@Override
public CommonResult<Object> apiTrigger(Integer id) {
XxlJobInfo xxlJobInfo = xxlJobInfoDao.loadById(id);
if (xxlJobInfo == null) {
return error(ReturnT.FAIL.getCode(), I18nUtil.getString("jobinfo_glue_jobid_unvalid"));
}
JobTriggerPoolHelper.trigger(id, TriggerTypeEnum.MANUAL, -1, null, "", "");
return success(true);
}
@Override
public CommonResult<List<String>> apiGetNextTimes(Integer id) {
XxlJobInfo paramXxlJobInfo = new XxlJobInfo();
paramXxlJobInfo.setScheduleType("CRON");
paramXxlJobInfo.setScheduleConf(apiGet(id).getCronExpression());
List<String> result = new ArrayList<>();
try {
Date lastTime = new Date();
for (int i = 0; i < 5; i++) {
lastTime = JobScheduleHelper.generateNextValidTime(paramXxlJobInfo, lastTime);
if (lastTime != null) {
result.add(DateUtil.formatDateTime(lastTime));
} else {
break;
}
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
return error(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type")+I18nUtil.getString("system_unvalid")) + e.getMessage());
}
return success(result);
}
}

View File

@ -31,12 +31,11 @@ spring:
### actuator
management:
server:
servlet:
context-path: /actuator
health:
mail:
enabled: false
server:
base-path: /actuator

View File

@ -1,45 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xxl.job.admin.dao.XxlJobInfoDao">
<resultMap id="XxlJobInfo" type="com.xxl.job.admin.core.model.XxlJobInfo" >
<result column="id" property="id" />
<resultMap id="XxlJobInfo" type="com.xxl.job.admin.core.model.XxlJobInfo">
<result column="id" property="id"/>
<result column="job_group" property="jobGroup" />
<result column="job_desc" property="jobDesc" />
<result column="job_group" property="jobGroup"/>
<result column="job_desc" property="jobDesc"/>
<result column="add_time" property="addTime" />
<result column="update_time" property="updateTime" />
<result column="add_time" property="addTime"/>
<result column="update_time" property="updateTime"/>
<result column="author" property="author" />
<result column="alarm_email" property="alarmEmail" />
<result column="author" property="author"/>
<result column="alarm_email" property="alarmEmail"/>
<result column="schedule_type" property="scheduleType" />
<result column="schedule_conf" property="scheduleConf" />
<result column="misfire_strategy" property="misfireStrategy" />
<result column="schedule_type" property="scheduleType"/>
<result column="schedule_conf" property="scheduleConf"/>
<result column="misfire_strategy" property="misfireStrategy"/>
<result column="executor_route_strategy" property="executorRouteStrategy" />
<result column="executor_handler" property="executorHandler" />
<result column="executor_param" property="executorParam" />
<result column="executor_block_strategy" property="executorBlockStrategy" />
<result column="executor_timeout" property="executorTimeout" />
<result column="executor_fail_retry_count" property="executorFailRetryCount" />
<result column="executor_route_strategy" property="executorRouteStrategy"/>
<result column="executor_handler" property="executorHandler"/>
<result column="executor_param" property="executorParam"/>
<result column="executor_block_strategy" property="executorBlockStrategy"/>
<result column="executor_timeout" property="executorTimeout"/>
<result column="executor_fail_retry_count" property="executorFailRetryCount"/>
<result column="glue_type" property="glueType" />
<result column="glue_source" property="glueSource" />
<result column="glue_remark" property="glueRemark" />
<result column="glue_updatetime" property="glueUpdatetime" />
<result column="glue_type" property="glueType"/>
<result column="glue_source" property="glueSource"/>
<result column="glue_remark" property="glueRemark"/>
<result column="glue_updatetime" property="glueUpdatetime"/>
<result column="child_jobid" property="childJobId" />
<result column="child_jobid" property="childJobId"/>
<result column="trigger_status" property="triggerStatus" />
<result column="trigger_last_time" property="triggerLastTime" />
<result column="trigger_next_time" property="triggerNextTime" />
</resultMap>
<result column="trigger_status" property="triggerStatus"/>
<result column="trigger_last_time" property="triggerLastTime"/>
<result column="trigger_next_time" property="triggerNextTime"/>
</resultMap>
<sql id="Base_Column_List">
t.id,
<sql id="Base_Column_List">
t
.
id
,
t.job_group,
t.job_desc,
t.add_time,
@ -63,220 +66,254 @@
t.trigger_status,
t.trigger_last_time,
t.trigger_next_time
</sql>
</sql>
<select id="pageList" parameterType="java.util.HashMap" resultMap="XxlJobInfo">
SELECT <include refid="Base_Column_List" />
FROM xxl_job_info AS t
<trim prefix="WHERE" prefixOverrides="AND | OR" >
<if test="jobGroup gt 0">
AND t.job_group = #{jobGroup}
</if>
<select id="pageList" parameterType="java.util.HashMap" resultMap="XxlJobInfo">
SELECT
<include refid="Base_Column_List"/>
FROM xxl_job_info AS t
<trim prefix="WHERE" prefixOverrides="AND | OR">
<if test="jobGroup gt 0">
AND t.job_group = #{jobGroup}
</if>
<if test="triggerStatus gte 0">
AND t.trigger_status = #{triggerStatus}
</if>
<if test="jobDesc != null and jobDesc != ''">
AND t.job_desc like CONCAT(CONCAT('%', #{jobDesc}), '%')
</if>
<if test="executorHandler != null and executorHandler != ''">
AND t.executor_handler like CONCAT(CONCAT('%', #{executorHandler}), '%')
</if>
<if test="author != null and author != ''">
AND t.author like CONCAT(CONCAT('%', #{author}), '%')
</if>
</trim>
ORDER BY id DESC
LIMIT #{offset}, #{pagesize}
</select>
<if test="jobDesc != null and jobDesc != ''">
AND t.job_desc like CONCAT(CONCAT('%', #{jobDesc}), '%')
</if>
<if test="executorHandler != null and executorHandler != ''">
AND t.executor_handler like CONCAT(CONCAT('%', #{executorHandler}), '%')
</if>
<if test="author != null and author != ''">
AND t.author like CONCAT(CONCAT('%', #{author}), '%')
</if>
</trim>
ORDER BY id DESC
LIMIT #{offset}, #{pagesize}
</select>
<select id="pageListCount" parameterType="java.util.HashMap" resultType="int">
SELECT count(1)
FROM xxl_job_info AS t
<trim prefix="WHERE" prefixOverrides="AND | OR" >
<if test="jobGroup gt 0">
AND t.job_group = #{jobGroup}
</if>
<select id="pageListCount" parameterType="java.util.HashMap" resultType="int">
SELECT count(1)
FROM xxl_job_info AS t
<trim prefix="WHERE" prefixOverrides="AND | OR">
<if test="jobGroup gt 0">
AND t.job_group = #{jobGroup}
</if>
<if test="triggerStatus gte 0">
AND t.trigger_status = #{triggerStatus}
</if>
<if test="jobDesc != null and jobDesc != ''">
AND t.job_desc like CONCAT(CONCAT('%', #{jobDesc}), '%')
</if>
<if test="executorHandler != null and executorHandler != ''">
AND t.executor_handler like CONCAT(CONCAT('%', #{executorHandler}), '%')
</if>
<if test="author != null and author != ''">
AND t.author like CONCAT(CONCAT('%', #{author}), '%')
</if>
</trim>
</select>
<if test="jobDesc != null and jobDesc != ''">
AND t.job_desc like CONCAT(CONCAT('%', #{jobDesc}), '%')
</if>
<if test="executorHandler != null and executorHandler != ''">
AND t.executor_handler like CONCAT(CONCAT('%', #{executorHandler}), '%')
</if>
<if test="author != null and author != ''">
AND t.author like CONCAT(CONCAT('%', #{author}), '%')
</if>
</trim>
</select>
<insert id="save" parameterType="com.xxl.job.admin.core.model.XxlJobInfo" useGeneratedKeys="true" keyProperty="id" >
INSERT INTO xxl_job_info (
job_group,
job_desc,
add_time,
update_time,
author,
alarm_email,
schedule_type,
schedule_conf,
misfire_strategy,
executor_route_strategy,
executor_handler,
executor_param,
executor_block_strategy,
executor_timeout,
executor_fail_retry_count,
glue_type,
glue_source,
glue_remark,
glue_updatetime,
child_jobid,
trigger_status,
trigger_last_time,
trigger_next_time
) VALUES (
#{jobGroup},
#{jobDesc},
#{addTime},
#{updateTime},
#{author},
#{alarmEmail},
#{scheduleType},
#{scheduleConf},
#{misfireStrategy},
#{executorRouteStrategy},
#{executorHandler},
#{executorParam},
#{executorBlockStrategy},
#{executorTimeout},
#{executorFailRetryCount},
#{glueType},
#{glueSource},
#{glueRemark},
#{glueUpdatetime},
#{childJobId},
#{triggerStatus},
#{triggerLastTime},
#{triggerNextTime}
);
<!--<selectKey resultType="java.lang.Integer" order="AFTER" keyProperty="id">
SELECT LAST_INSERT_ID()
/*SELECT @@IDENTITY AS id*/
</selectKey>-->
</insert>
<insert id="save" parameterType="com.xxl.job.admin.core.model.XxlJobInfo" useGeneratedKeys="true" keyProperty="id">
INSERT INTO xxl_job_info (
job_group,
job_desc,
add_time,
update_time,
author,
alarm_email,
schedule_type,
schedule_conf,
misfire_strategy,
executor_route_strategy,
executor_handler,
executor_param,
executor_block_strategy,
executor_timeout,
executor_fail_retry_count,
glue_type,
glue_source,
glue_remark,
glue_updatetime,
child_jobid,
trigger_status,
trigger_last_time,
trigger_next_time
) VALUES (
#{jobGroup},
#{jobDesc},
#{addTime},
#{updateTime},
#{author},
#{alarmEmail},
#{scheduleType},
#{scheduleConf},
#{misfireStrategy},
#{executorRouteStrategy},
#{executorHandler},
#{executorParam},
#{executorBlockStrategy},
#{executorTimeout},
#{executorFailRetryCount},
#{glueType},
#{glueSource},
#{glueRemark},
#{glueUpdatetime},
#{childJobId},
#{triggerStatus},
#{triggerLastTime},
#{triggerNextTime}
);
<!--<selectKey resultType="java.lang.Integer" order="AFTER" keyProperty="id">
SELECT LAST_INSERT_ID()
/*SELECT @@IDENTITY AS id*/
</selectKey>-->
</insert>
<select id="loadById" parameterType="java.util.HashMap" resultMap="XxlJobInfo">
SELECT <include refid="Base_Column_List" />
FROM xxl_job_info AS t
WHERE t.id = #{id}
</select>
<select id="loadById" parameterType="java.util.HashMap" resultMap="XxlJobInfo">
SELECT
<include refid="Base_Column_List"/>
FROM xxl_job_info AS t
WHERE t.id = #{id}
</select>
<update id="update" parameterType="com.xxl.job.admin.core.model.XxlJobInfo" >
UPDATE xxl_job_info
SET
job_group = #{jobGroup},
job_desc = #{jobDesc},
update_time = #{updateTime},
author = #{author},
alarm_email = #{alarmEmail},
schedule_type = #{scheduleType},
schedule_conf = #{scheduleConf},
misfire_strategy = #{misfireStrategy},
executor_route_strategy = #{executorRouteStrategy},
executor_handler = #{executorHandler},
executor_param = #{executorParam},
executor_block_strategy = #{executorBlockStrategy},
executor_timeout = ${executorTimeout},
executor_fail_retry_count = ${executorFailRetryCount},
glue_type = #{glueType},
glue_source = #{glueSource},
glue_remark = #{glueRemark},
glue_updatetime = #{glueUpdatetime},
child_jobid = #{childJobId},
trigger_status = #{triggerStatus},
trigger_last_time = #{triggerLastTime},
trigger_next_time = #{triggerNextTime}
WHERE id = #{id}
</update>
<update id="update" parameterType="com.xxl.job.admin.core.model.XxlJobInfo">
UPDATE xxl_job_info
SET job_group = #{jobGroup},
job_desc = #{jobDesc},
update_time = #{updateTime},
author = #{author},
alarm_email = #{alarmEmail},
schedule_type = #{scheduleType},
schedule_conf = #{scheduleConf},
misfire_strategy = #{misfireStrategy},
executor_route_strategy = #{executorRouteStrategy},
executor_handler = #{executorHandler},
executor_param = #{executorParam},
executor_block_strategy = #{executorBlockStrategy},
executor_timeout = ${executorTimeout},
executor_fail_retry_count = ${executorFailRetryCount},
glue_type = #{glueType},
glue_source = #{glueSource},
glue_remark = #{glueRemark},
glue_updatetime = #{glueUpdatetime},
child_jobid = #{childJobId},
trigger_status = #{triggerStatus},
trigger_last_time = #{triggerLastTime},
trigger_next_time = #{triggerNextTime}
WHERE id = #{id}
</update>
<delete id="delete" parameterType="java.util.HashMap">
DELETE
FROM xxl_job_info
WHERE id = #{id}
</delete>
<delete id="delete" parameterType="java.util.HashMap">
DELETE
FROM xxl_job_info
WHERE id = #{id}
</delete>
<select id="getJobsByGroup" parameterType="java.util.HashMap" resultMap="XxlJobInfo">
SELECT <include refid="Base_Column_List" />
FROM xxl_job_info AS t
WHERE t.job_group = #{jobGroup}
</select>
<select id="getJobsByGroup" parameterType="java.util.HashMap" resultMap="XxlJobInfo">
SELECT
<include refid="Base_Column_List"/>
FROM xxl_job_info AS t
WHERE t.job_group = #{jobGroup}
</select>
<select id="findAllCount" resultType="int">
SELECT count(1)
FROM xxl_job_info
</select>
<select id="findAllCount" resultType="int">
SELECT count(1)
FROM xxl_job_info
</select>
<select id="scheduleJobQuery" parameterType="java.util.HashMap" resultMap="XxlJobInfo">
SELECT <include refid="Base_Column_List" />
FROM xxl_job_info AS t
WHERE t.trigger_status = 1
and t.trigger_next_time <![CDATA[ <= ]]> #{maxNextTime}
ORDER BY id ASC
LIMIT #{pagesize}
</select>
<select id="scheduleJobQuery" parameterType="java.util.HashMap" resultMap="XxlJobInfo">
SELECT
<include refid="Base_Column_List"/>
FROM xxl_job_info AS t
WHERE t.trigger_status = 1
and t.trigger_next_time <![CDATA[ <= ]]> #{maxNextTime}
ORDER BY id ASC
LIMIT #{pagesize}
</select>
<update id="scheduleUpdate" parameterType="com.xxl.job.admin.core.model.XxlJobInfo" >
UPDATE xxl_job_info
SET
trigger_last_time = #{triggerLastTime},
trigger_next_time = #{triggerNextTime},
trigger_status = #{triggerStatus}
WHERE id = #{id}
</update>
<resultMap id="JobInfoRespDTOResultMap" type="com.xxl.job.admin.api.info.dto.JobInfoRespDTO">
<id property="id" column="id" />
<result property="name" column="job_desc" />
<result property="status" column="trigger_status" />
<result property="handlerName" column="executor_handler" />
<result property="handlerParam" column="executor_param" />
<result property="cronExpression" column="schedule_conf" />
</resultMap>
<update id="scheduleUpdate" parameterType="com.xxl.job.admin.core.model.XxlJobInfo">
UPDATE xxl_job_info
SET trigger_last_time = #{triggerLastTime},
trigger_next_time = #{triggerNextTime},
trigger_status = #{triggerStatus}
WHERE id = #{id}
</update>
<select id="apiPage" resultMap="JobInfoRespDTOResultMap">
SELECT id, job_desc, CASE WHEN trigger_status = 0 THEN 2 ELSE trigger_status END AS trigger_status, executor_handler, executor_param, schedule_conf
FROM xxl_job_info
<where>
<if test="name != null and name != ''">
AND job_desc LIKE concat('%', #{name}, '%')
</if>
<if test="status == 0 or status == 1">
AND trigger_status = #{status}
</if>
<if test="handlerName != null and handlerName != ''">
AND executor_handler LIKE concat('%', #{handlerName}, '%')
</if>
</where>
LIMIT #{pageSize} OFFSET ${(pageNo - 1) * pageSize}
</select>
<select id="apiPageCount" resultType="java.lang.Long">
SELECT count(*)
FROM xxl_job_info
<where>
<if test="name != null and name != ''">
AND job_desc LIKE concat('%', #{name}, '%')
</if>
<if test="status == 0 or status == 1">
AND trigger_status = #{status}
</if>
<if test="handlerName != null and handlerName != ''">
AND executor_handler LIKE concat('%', #{handlerName}, '%')
</if>
</where>
</select>
<!-- 以下是自定义语句 -->
<sql id="job_group_default">
3
</sql>
<resultMap id="JobInfoRespDTOResultMap" type="com.xxl.job.admin.api.info.dto.JobInfoRespDTO">
<id property="id" column="id"/>
<result property="name" column="job_desc"/>
<result property="status" column="trigger_status"/>
<result property="handlerName" column="executor_handler"/>
<result property="handlerParam" column="executor_param"/>
<result property="cronExpression" column="schedule_conf"/>
</resultMap>
<select id="apiPage" resultMap="JobInfoRespDTOResultMap">
SELECT id, job_desc, CASE WHEN trigger_status = 0 THEN 2 ELSE trigger_status END AS trigger_status,
executor_handler, executor_param, schedule_conf
FROM xxl_job_info
<where>
AND job_group =
<include refid="job_group_default"/>
<if test="name != null and name != ''">
AND job_desc LIKE concat('%', #{name}, '%')
</if>
<if test="status == 0 or status == 1">
AND trigger_status = #{status}
</if>
<if test="handlerName != null and handlerName != ''">
AND executor_handler LIKE concat('%', #{handlerName}, '%')
</if>
</where>
<if test="pageSize > 0">
LIMIT #{pageSize} OFFSET ${(pageNo - 1) * pageSize}
</if>
</select>
<select id="apiPageCount" resultType="java.lang.Long">
SELECT count(*)
FROM xxl_job_info
<where>
AND job_group =
<include refid="job_group_default"/>
<if test="name != null and name != ''">
AND job_desc LIKE concat('%', #{name}, '%')
</if>
<if test="status == 0 or status == 1">
AND trigger_status = #{status}
</if>
<if test="handlerName != null and handlerName != ''">
AND executor_handler LIKE concat('%', #{handlerName}, '%')
</if>
</where>
</select>
<resultMap id="JobInfoDetailRespDTOResultMap" type="com.xxl.job.admin.api.info.dto.JobInfoDetailRespDTO">
<id property="id" column="id"/>
<result property="name" column="job_desc"/>
<result property="handlerName" column="executor_handler"/>
<result property="handlerParam" column="executor_param"/>
<result property="cronExpression" column="schedule_conf"/>
<result property="retryCount" column="executor_fail_retry_count"/>
<result property="monitorTimeout" column="executor_timeout"/>
</resultMap>
<select id="apiGet" resultMap="JobInfoDetailRespDTOResultMap">
SELECT id, job_desc, executor_handler, executor_param, schedule_conf, executor_fail_retry_count,
executor_timeout
FROM xxl_job_info
WHERE id = #{id}
AND job_group =
<include refid="job_group_default"/>
</select>
</mapper>

View File

@ -77,6 +77,51 @@
ORDER BY t.trigger_time DESC
LIMIT #{offset}, #{pagesize}
</select>
<resultMap id="ApiXxlJobLog" type="com.xxl.job.admin.api.log.dto.JobLogRespDTO">
<id column="id" property="id"/>
<result column="job_id" property="jobId"/>
<result column="executor_handler" property="handlerName"/>
<result column="executor_param" property="handlerParam"/>
<result column="index" property="executeIndex"/>
<result column="trigger_time" property="beginTime"/>
<result column="handle_time" property="endTime"/>
<result column="duration" property="duration"/>
<result column="alarm_status" property="status"/>
</resultMap>
<select id="apiPageList" resultMap="ApiXxlJobLog">
SELECT <include refid="Base_Column_List" />, ROW_NUMBER() OVER (ORDER BY t.trigger_time) AS 'index', (t.handle_time -t.trigger_time) AS 'duration'
FROM xxl_job_log AS t
<trim prefix="WHERE" prefixOverrides="AND | OR" >
<if test="jobId==0 and jobGroup gt 0">
AND t.job_group = #{jobGroup}
</if>
<if test="jobId gt 0">
AND t.job_id = #{jobId}
</if>
<if test="triggerTimeStart != null">
AND t.trigger_time <![CDATA[ >= ]]> #{triggerTimeStart}
</if>
<if test="triggerTimeEnd != null">
AND t.trigger_time <![CDATA[ <= ]]> #{triggerTimeEnd}
</if>
<if test="logStatus == 1" >
AND t.handle_code = 200
</if>
<if test="logStatus == 2" >
AND (
t.trigger_code NOT IN (0, 200) OR
t.handle_code NOT IN (0, 200)
)
</if>
<if test="logStatus == 3" >
AND t.trigger_code = 200
AND t.handle_code = 0
</if>
</trim>
ORDER BY t.trigger_time DESC
LIMIT #{offset}, #{pagesize}
</select>
<select id="pageListCount" resultType="int">
SELECT count(1)

View File

@ -108,7 +108,7 @@ yudao:
captcha:
enable: true # 验证码的开关,默认为 true
tenant: # 多租户相关配置项
enable: true
enable: false
ignore-urls:
ignore-tables:

View File

@ -1,7 +1,8 @@
package cn.iocoder.yudao.module.ticket.framework.security.config;
import cn.iocoder.yudao.framework.security.config.AuthorizeRequestsCustomizer;
import cn.iocoder.yudao.module.system.enums.ApiConstants;
import cn.iocoder.yudao.module.ticket.enums.ApiConstants;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;

View File

@ -124,33 +124,28 @@ public class YudaoWebSecurityConfigurerAdapter {
// 获得 @PermitAll 带来的 URL 列表免登录
Multimap<HttpMethod, String> permitAllUrls = getPermitAllUrlsFromAnnotations();
// 设置每个请求的权限
// httpSecurity
// // 全局共享规则
// .authorizeRequests()
// // 1.1 静态资源可匿名访问
// .antMatchers(HttpMethod.GET, "/*.html", "/**/*.html", "/**/*.css", "/**/*.js").permitAll()
// // 1.2 设置 @PermitAll 无需认证
// .antMatchers(HttpMethod.GET, permitAllUrls.get(HttpMethod.GET).toArray(new String[0])).permitAll()
// .antMatchers(HttpMethod.POST, permitAllUrls.get(HttpMethod.POST).toArray(new String[0])).permitAll()
// .antMatchers(HttpMethod.PUT, permitAllUrls.get(HttpMethod.PUT).toArray(new String[0])).permitAll()
// .antMatchers(HttpMethod.DELETE, permitAllUrls.get(HttpMethod.DELETE).toArray(new String[0])).permitAll()
// // 1.3 基于 yudao.security.permit-all-urls 无需认证
// .antMatchers(securityProperties.getPermitAllUrls().toArray(new String[0])).permitAll()
// // 1.4 设置 App API 无需认证
// .antMatchers(buildAppApi("/**")).permitAll()
// // 1.5 验证码captcha 允许匿名访问
// .antMatchers("/captcha/get", "/captcha/check").permitAll()
// // TODO 未解决对xxl-job的默认管理端放行
// .antMatchers("/**/xxl-job-admin/**").permitAll()
// // 每个项目的自定义规则
// .and().authorizeRequests(registry -> // 下面循环设置自定义规则
// authorizeRequestsCustomizers.forEach(customizer -> customizer.customize(registry)))
// // 兜底规则必须认证
// .authorizeRequests()
// .anyRequest().authenticated();
// TODO 暂时先放行用于调度中心后台查看
httpSecurity.authorizeRequests().anyRequest().permitAll();
httpSecurity
// 全局共享规则
.authorizeRequests()
// 1.1 静态资源可匿名访问
.antMatchers(HttpMethod.GET, "/*.html", "/**/*.html", "/**/*.css", "/**/*.js").permitAll()
// 1.2 设置 @PermitAll 无需认证
.antMatchers(HttpMethod.GET, permitAllUrls.get(HttpMethod.GET).toArray(new String[0])).permitAll()
.antMatchers(HttpMethod.POST, permitAllUrls.get(HttpMethod.POST).toArray(new String[0])).permitAll()
.antMatchers(HttpMethod.PUT, permitAllUrls.get(HttpMethod.PUT).toArray(new String[0])).permitAll()
.antMatchers(HttpMethod.DELETE, permitAllUrls.get(HttpMethod.DELETE).toArray(new String[0])).permitAll()
// 1.3 基于 yudao.security.permit-all-urls 无需认证
.antMatchers(securityProperties.getPermitAllUrls().toArray(new String[0])).permitAll()
// 1.4 设置 App API 无需认证
.antMatchers(buildAppApi("/**")).permitAll()
// 1.5 验证码captcha 允许匿名访问
.antMatchers("/captcha/get", "/captcha/check").permitAll()
// 每个项目的自定义规则
.and().authorizeRequests(registry -> // 下面循环设置自定义规则
authorizeRequestsCustomizers.forEach(customizer -> customizer.customize(registry)))
// 兜底规则必须认证
.authorizeRequests()
.anyRequest().authenticated();
// 添加 Token Filter
httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
return httpSecurity.build();

View File

@ -21,12 +21,12 @@
<dependencies>
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>ludu-job-admin-api</artifactId>
<artifactId>ludu-job-core</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>ludu-job-core</artifactId>
<artifactId>ludu-job-admin-api</artifactId>
<version>${revision}</version>
</dependency>
<!-- Spring Cloud 基础 -->

View File

@ -1,28 +1,35 @@
package cn.iocoder.yudao.module.infra.controller.admin.job;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.http.HttpRequestUtil;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import com.xxl.job.admin.api.info.JobInfoApi;
import com.xxl.job.admin.api.info.dto.JobInfoDetailRespDTO;
import com.xxl.job.admin.api.info.dto.JobInfoPageReqDTO;
import com.xxl.job.admin.api.info.dto.JobInfoRespDTO;
import com.xxl.job.admin.api.info.dto.JobInfoSaveReqDTO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.error;
@Tag(name = "管理后台 - 定时任务")
@ -30,36 +37,76 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.error;
@RequestMapping("/infra/job")
@Validated
public class JobController {
/*@Resource
private JobInfoApi jobInfoApi;*/
@Resource
private JobInfoApi jobInfoApi;
// private static final String XXL_JOB_URL = "http://127.0.0.1:9090/xxl-job-admin";
// private static final String USERNAME = "admin"; // TODO 可以直接读取配置中的账号和密码
// private static final String PASSWORD = "123456";
// TODO 整体思路也可以使用网关拦截器
// 用于获取登录成功后返回的Cookie值
/*static{
Map<String, Object> params = new HashMap<>();
params.put("userName", USERNAME);
params.put("password", PASSWORD);
HttpHeaders headers = HttpRequestUtil.post(XXL_JOB_URL + "/login", params).getHeaders();
// 获取 Set-Cookie
List<String> setCookies = headers.get("Set-Cookie");
if (setCookies != null && !setCookies.isEmpty()) {
String cookie = setCookies.get(0);
// TODO 存入到一个常量中
System.out.println("this is cookie" + cookie);
}else{
// TODO 如果登录失败则不会有Set-Cookie的值抛出异常使用全局异常处理类
}
}*/
// TODO 出现未知错误 JobInfoApi 无法创建 bean
/*@GetMapping("/page")
@Operation(summary = "获得定时任务分页")
@GetMapping("/page")
@Operation(summary = "获得任务列表")
@PreAuthorize("@ss.hasPermission('infra:job:query')")
public CommonResult<PageResult<JobInfoRespDTO>> getJobPage(@RequestParam(value = "pageNo") Integer pageNo, @RequestParam(value = "pageSize") Integer pageSize, @RequestParam(required = false, value = "name") String name, @RequestParam(required = false, value = "status") Integer status, @RequestParam(required = false, value = "handlerName") String handlerName) {
return jobInfoApi.getPage(pageNo, pageSize, name, status, handlerName);
}*/
}
@GetMapping("/get")
@Operation(summary = "获得任务详情")
@PreAuthorize("@ss.hasPermission('infra:job:query')")
public CommonResult<JobInfoDetailRespDTO> get(@RequestParam("id") Integer id){
return jobInfoApi.get(id);
}
@PostMapping("/create")
@Operation(summary = "新增任务")
@PreAuthorize("@ss.hasPermission('infra:job:create')")
public CommonResult<Boolean> create(@RequestBody JobInfoSaveReqDTO jobInfoSaveReqDTO){
return jobInfoApi.create(jobInfoSaveReqDTO);
}
@PutMapping("/update")
@Operation(summary = "修改任务")
@PreAuthorize("@ss.hasPermission('infra:job:update')")
public CommonResult<Boolean> update(@RequestBody JobInfoSaveReqDTO jobInfoSaveReqDTO){
return jobInfoApi.update(jobInfoSaveReqDTO);
}
@DeleteMapping("/delete")
@Operation(summary = "删除任务")
@PreAuthorize("@ss.hasPermission('infra:job:delete')")
public CommonResult<Boolean> delete(@RequestParam("id") Integer id){
return jobInfoApi.delete(id);
}
@GetMapping("/export-excel")
@Operation(summary = "导出任务 Excel")
@PreAuthorize("@ss.hasPermission('infra:job:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportJobInfoExcel(@Valid JobInfoPageReqDTO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<JobInfoRespDTO> list = jobInfoApi.getPage(pageReqVO.getPageNo(), pageReqVO.getPageSize(), pageReqVO.getName(), pageReqVO.getStatus(), pageReqVO.getHandlerName()).getData().getList();
// 导出 Excel
ExcelUtils.write(response, "任务调度.xls", "数据", JobInfoRespDTO.class,
list);
}
@PutMapping("/update-status")
@Operation(summary = "任务状态修改")
@PreAuthorize("@ss.hasPermission('infra:job:update')")
public CommonResult<Boolean> updateStatus(@RequestParam("id") Integer id, @RequestParam("status") Integer status){
return jobInfoApi.updateStatus(id, status);
}
@PutMapping("/trigger")
@Operation(summary = "任务立即执行一次")
@PreAuthorize("@ss.hasPermission('infra:job:update')")
public CommonResult<Object> trigger(@RequestParam("id") Integer id){
return jobInfoApi.trigger(id);
}
@GetMapping("/get_next_times")
@Operation(summary = "下n次执行时间")
@PreAuthorize("@ss.hasPermission('infra:job:query')")
public CommonResult<List<String>> getNextTimes(@RequestParam("id") Integer id){
return jobInfoApi.getNextTimes(id);
}
}

View File

@ -0,0 +1,33 @@
package cn.iocoder.yudao.module.infra.controller.admin.joblog;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import com.xxl.job.admin.api.info.dto.JobInfoRespDTO;
import com.xxl.job.admin.api.log.JobLogApi;
import com.xxl.job.admin.api.log.dto.JobLogPageReqDTO;
import com.xxl.job.admin.api.log.dto.JobLogRespDTO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.validation.Valid;
@Tag(name = "管理后台 - 定时任务日志")
@RestController
@RequestMapping("/infra/job-log")
@Validated
public class JobLogController {
@Resource
private JobLogApi jobLogApi;
@RequestMapping("/page")
@Operation(summary = "获得任务日志列表")
public CommonResult<PageResult<JobLogRespDTO>> getPage(@Valid JobLogPageReqDTO jobLogPageReqDTO){
return jobLogApi.getPage(jobLogPageReqDTO);
}
}

View File

@ -2,10 +2,11 @@ package cn.iocoder.yudao.module.infra.framework.rpc.config;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import com.xxl.job.admin.api.info.JobInfoApi;
import com.xxl.job.admin.api.log.JobLogApi;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
@EnableFeignClients(clients = {AdminUserApi.class, JobInfoApi.class})
@EnableFeignClients(clients = {AdminUserApi.class, JobInfoApi.class, JobLogApi.class})
public class RpcConfiguration {
}