Merge pull request '调度中心API' (#3) from xinwei into master

Reviewed-on: http://120.46.37.243:3000/lundu/ludu-cloud/pulls/3
This commit is contained in:
root 2024-07-10 07:22:51 +00:00
commit bab03cb461
29 changed files with 1139 additions and 371 deletions

View File

@ -43,6 +43,10 @@
<artifactId>spring-cloud-starter-openfeign</artifactId> <artifactId>spring-cloud-starter-openfeign</artifactId>
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-spring-boot-starter-excel</artifactId>
</dependency>
</dependencies> </dependencies>
</project> </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.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult; 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.JobInfoRespDTO;
import com.xxl.job.admin.api.info.dto.JobInfoSaveReqDTO;
import com.xxl.job.admin.enums.ApiConstants; import com.xxl.job.admin.enums.ApiConstants;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.cloud.openfeign.FeignClient; import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
* @Description TODO * @Description 调度任务信息Api接口
*/ */
@FeignClient(name = ApiConstants.NAME) @FeignClient(name = ApiConstants.NAME, path = "/xxl-job-admin")
@Tag(name = "RPC 服务 - 任务信息管理") @Tag(name = "RPC 服务 - 任务信息管理")
@RequestMapping("")
public interface JobInfoApi { public interface JobInfoApi {
String PREFIX = ApiConstants.PREFIX + "/info"; String PREFIX = ApiConstants.PREFIX + "/info";
@GetMapping(PREFIX + "/page") @GetMapping(PREFIX + "/page")
@ -32,4 +31,31 @@ public interface JobInfoApi {
@Parameter(name = "handlerName", description = "处理器名字", required = false) @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); 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; 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 io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
/** /**
* @Description 任务信息 * @Description 任务列表单个信息
*/ */
@Schema(description = "RPC 服务 - 任务信息 Response DTO") @Schema(description = "RPC 服务 - 任务信息 Response DTO")
@Data @Data
@ExcelIgnoreUnannotated
public class JobInfoRespDTO { public class JobInfoRespDTO {
@Schema(description = "任务编号", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "任务编号", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("任务编号")
private Integer id; private Integer id;
@Schema(description = "任务名称") @Schema(description = "任务名称")
@ExcelProperty("任务名称")
private String name; private String name;
@Schema(description = "任务状态") @Schema(description = "任务状态")
@ExcelProperty("任务状态")
private Integer status; private Integer status;
@Schema(description = "处理器的名字") @Schema(description = "处理器的名字")
@ExcelProperty("处理器的名字")
private String handlerName; private String handlerName;
@Schema(description = "处理器的参数") @Schema(description = "处理器的参数")
@ExcelProperty("处理器的参数")
private String handlerParam; private String handlerParam;
@Schema(description = "CRON 表达式") @Schema(description = "CRON 表达式")
@ExcelProperty("CRON 表达式")
private String cronExpression; 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.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult; 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.JobInfoRespDTO;
import com.xxl.job.admin.api.info.dto.JobInfoSaveReqDTO;
import com.xxl.job.admin.service.XxlJobService; import com.xxl.job.admin.service.XxlJobService;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RestController; 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; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
/** /**
* @Description TODO * @Description 调度任务信息Api实现类
*/ */
@RestController // 提供 RESTful API 接口 Feign 调用 @RestController // 提供 RESTful API 接口 Feign 调用
@Validated @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) { public CommonResult<PageResult<JobInfoRespDTO>> getPage(Integer pageNo, Integer pageSize, String name, Integer status, String handlerName) {
return success(xxlJobService.apiPage(pageNo, pageSize, name, status, 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; package com.xxl.job.admin.dao;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 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.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.XxlJobInfo;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param; 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); 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); 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; package com.xxl.job.admin.dao;
import com.xxl.job.admin.api.log.dto.JobLogRespDTO;
import com.xxl.job.admin.core.model.XxlJobLog; import com.xxl.job.admin.core.model.XxlJobLog;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
@ -23,6 +24,13 @@ public interface XxlJobLogDao {
@Param("triggerTimeStart") Date triggerTimeStart, @Param("triggerTimeStart") Date triggerTimeStart,
@Param("triggerTimeEnd") Date triggerTimeEnd, @Param("triggerTimeEnd") Date triggerTimeEnd,
@Param("logStatus") int logStatus); @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, public int pageListCount(@Param("offset") int offset,
@Param("pagesize") int pagesize, @Param("pagesize") int pagesize,
@Param("jobGroup") int jobGroup, @Param("jobGroup") int jobGroup,

View File

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

View File

@ -83,24 +83,33 @@ public class LoginService {
* @return * @return
*/ */
public XxlJobUser ifLogin(HttpServletRequest request, HttpServletResponse response){ public XxlJobUser ifLogin(HttpServletRequest request, HttpServletResponse response){
String cookieToken = CookieUtil.getValue(request, LOGIN_IDENTITY_KEY);
if (cookieToken != null) { // String cookieToken = CookieUtil.getValue(request, LOGIN_IDENTITY_KEY);
XxlJobUser cookieUser = null; // if (cookieToken != null) {
try { // XxlJobUser cookieUser = null;
cookieUser = parseToken(cookieToken); // try {
} catch (Exception e) { // cookieUser = parseToken(cookieToken);
logout(request, response); // } catch (Exception e) {
} // logout(request, response);
if (cookieUser != null) { // }
XxlJobUser dbUser = xxlJobUserDao.loadByUserName(cookieUser.getUsername()); // if (cookieUser != null) {
if (dbUser != null) { // XxlJobUser dbUser = xxlJobUserDao.loadByUserName(cookieUser.getUsername());
if (cookieUser.getPassword().equals(dbUser.getPassword())) { // if (dbUser != null) {
return dbUser; // if (cookieUser.getPassword().equals(dbUser.getPassword())) {
} // return dbUser;
} // }
} // }
} // }
return null; // }
// 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.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult; 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.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.XxlJobInfo;
import com.xxl.job.admin.core.model.XxlJobUser; import com.xxl.job.admin.core.model.XxlJobUser;
import com.xxl.job.core.biz.model.ReturnT; import com.xxl.job.core.biz.model.ReturnT;
@ -109,4 +111,54 @@ public interface XxlJobService {
* @return * @return
*/ */
PageResult<JobInfoRespDTO> apiPage(Integer pageNo, Integer pageSize, String name, Integer status, String handlerName); 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; package com.xxl.job.admin.service.impl;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult; 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.JobInfoRespDTO;
import com.xxl.job.admin.api.info.dto.JobInfoSaveReqDTO;
import com.xxl.job.admin.core.cron.CronExpression; import com.xxl.job.admin.core.cron.CronExpression;
import com.xxl.job.admin.core.model.XxlJobGroup; import com.xxl.job.admin.core.model.XxlJobGroup;
import com.xxl.job.admin.core.model.XxlJobInfo; import com.xxl.job.admin.core.model.XxlJobInfo;
@ -28,6 +31,9 @@ import javax.annotation.Resource;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.*; 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 * core job action for xxl-job
* @author xuxueli 2016-5-28 15:30:33 * @author xuxueli 2016-5-28 15:30:33
@ -481,4 +487,126 @@ public class XxlJobServiceImpl implements XxlJobService {
return pageResult; 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 ### actuator
management: management:
server:
servlet:
context-path: /actuator
health: health:
mail: mail:
enabled: false enabled: false
server:
base-path: /actuator

View File

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

View File

@ -78,6 +78,51 @@
LIMIT #{offset}, #{pagesize} LIMIT #{offset}, #{pagesize}
</select> </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 id="pageListCount" resultType="int">
SELECT count(1) SELECT count(1)
FROM xxl_job_log AS t FROM xxl_job_log AS t

View File

@ -63,37 +63,35 @@ public class TicketingSamplingJob {
List<Map<String, Object>> mapList = ticketingSamplingRespVO.getDataMapList(); List<Map<String, Object>> mapList = ticketingSamplingRespVO.getDataMapList();
// 总条数小于等于每页条数 则直接按照总条数进行插入即可 // 总条数小于等于每页条数 则直接按照总条数进行插入即可
if (totalRows <= PAGE_SIZE) { if (totalRows <= PAGE_SIZE) {
for (int i = 0; i < ticketingSamplingRespVO.getTotalRows(); i++) { failedCount += insertSaleData(mapList, totalRows, pageNumber);
Map<String, Object> currentMap = mapList.get(i); } else {
// 装配数据 // 总条数大于每页条数 执行完第一次插入后根据返回的页数继续进行请求和插入
SaleDataSaveReqDTO saleData = new SaleDataSaveReqDTO(); // 插入第一页的数据
saleData.setDataId((String) currentMap.get("dataId")); failedCount += insertSaleData(mapList, PAGE_SIZE, pageNumber);
saleData.setSdno((String) currentMap.get("sdno")); pageNumber++;
saleData.setTransactiontypeno((String) currentMap.get("transactiontypeno")); // 获得总页数
saleData.setSddate((String) currentMap.get("sddate")); int totalPages = ticketingSamplingRespVO.getTotalPages();
saleData.setSdtime((String) currentMap.get("sdtime")); // 处理剩余页的数据
saleData.setAmount(new BigDecimal(currentMap.get("amount").toString())); for (; pageNumber <= totalPages; pageNumber++) {
saleData.setQuantity((Integer) currentMap.get("quantity")); ticketingSamplingReqVO.setPageNumber(pageNumber);
saleData.setCertificatetype((String) currentMap.get("certificatetype")); str = HttpUtil.post("http://shinanlundu.pro.jiutianda.com/joytime-erp-eportal/console/openapi/handler", JSONUtil.toJsonStr(ticketingSamplingReqVO));
saleData.setCertificateno((String) currentMap.get("certificateno")); ticketingSamplingRespVO = new ObjectMapper().readValue(str, TicketingSamplingRespVO.class);
saleData.setProductbatchno((String) currentMap.get("productbatchno"));
saleData.setItem((String) currentMap.get("item")); if (!ticketingSamplingRespVO.isPassflag()) {
saleData.setItemtypename((String) currentMap.get("itemtypename")); XxlJobHelper.log("抽数服务:销售数据抽数失败,返回消息:" + ticketingSamplingRespVO.getRtnMsg());
saleData.setItemtype((String) currentMap.get("itemtype")); XxlJobHelper.handleFail("销售数据抽数失败,请重试");
saleData.setItemname((String) currentMap.get("itemname")); return;
saleData.setSalepropetyvaluename((String) currentMap.get("salepropetyvaluename")); }
saleData.setTenant_id(1L);
if (ticketSaleDataApi.createSaleData(saleData).getCode() != 0) { mapList = ticketingSamplingRespVO.getDataMapList();
failedCount++; // 对最后一页进行处理得到最后一页的实际条数
XxlJobHelper.log("第{}条数据插入失败,数据值为:{}", ((pageNumber - 1) * PAGE_SIZE + i + 1), currentMap); if (pageNumber != totalPages) {
failedCount += insertSaleData(mapList, PAGE_SIZE, pageNumber);
} else {
failedCount += insertSaleData(mapList, totalRows % PAGE_SIZE, pageNumber);
} }
} }
}
// TODO 由于小于大于都要执行第一次插入数据只是长度不同同时小于执行完直接return就行
// 总条数大于每页条数 执行完第一次插入后根据返回的页数继续进行请求和插入
for (int i = pageNumber; i <= totalRows; i++) {
// 请求
// 插入
} }
XxlJobHelper.log("抽数服务:销售数据抽数正常结束!总共:{}条数据,{}条数据插入失败!", totalRows, failedCount); XxlJobHelper.log("抽数服务:销售数据抽数正常结束!总共:{}条数据,{}条数据插入失败!", totalRows, failedCount);
@ -101,32 +99,130 @@ public class TicketingSamplingJob {
@XxlJob("getCheckTicket") @XxlJob("getCheckTicket")
public void getCheckTicketHandler() throws Exception { public void getCheckTicketHandler() throws Exception {
XxlJobHelper.log("抽数服务:检票数据开始抽数"); int failedCount = 0;
Map<String, Object> map = new HashMap<>(); int pageNumber = 1;
map.put("service", "apiCheckService"); XxlJobHelper.log("抽数服务:检票数据开始抽数...");
map.put("method", "CheckDetail"); // 准备请求参数
map.put("queryDate", "20240707"); TicketingSamplingReqVO ticketingSamplingReqVO = new TicketingSamplingReqVO();
map.put("pageNumber", 1); ticketingSamplingReqVO.setService("apiCheckService");
map.put("pageSize", 2000); ticketingSamplingReqVO.setMethod("CheckDetail");
String str = HttpUtil.post("http://shinanlundu.pro.jiutianda.com/joytime-erp-eportal/console/openapi/handler", JSONUtil.toJsonStr(map)); ticketingSamplingReqVO.setQueryDate(TickingDateUtils.getNowDayFormat());
TicketingSamplingRespVO ticketingSamplingRespVO = new ObjectMapper().readValue(str, TicketingSamplingRespVO.class); ticketingSamplingReqVO.setPageNumber(pageNumber);
int successNum = 0; ticketingSamplingReqVO.setPageSize(PAGE_SIZE);
for (Map<String, Object> stringObjectMap : ticketingSamplingRespVO.getDataMapList()) { // 先发起第一次请求
String str = HttpUtil.post("http://shinanlundu.pro.jiutianda.com/joytime-erp-eportal/console/openapi/handler", JSONUtil.toJsonStr(ticketingSamplingReqVO));
// 解析读取响应数据
TicketingSamplingRespVO ticketingSamplingRespVO = new ObjectMapper().readValue(str, TicketingSamplingRespVO.class);
// 如果访问失败则让调度中心重新调用
if (!ticketingSamplingRespVO.isPassflag()) {
// 让调度中心重新调用
XxlJobHelper.log("抽数服务:检票数据抽数失败,返回消息:" + ticketingSamplingRespVO.getRtnMsg());
XxlJobHelper.handleFail("销售数据抽数失败,请重试");
return;
}
int totalRows = ticketingSamplingRespVO.getTotalRows();
List<Map<String, Object>> mapList = ticketingSamplingRespVO.getDataMapList();
// 总条数小于等于每页条数 则直接按照总条数进行插入即可
if (totalRows <= PAGE_SIZE) {
failedCount += insertCheckTicket(mapList, totalRows, pageNumber);
} else {
// 总条数大于每页条数 执行完第一次插入后根据返回的页数继续进行请求和插入
// 插入第一页的数据
failedCount += insertCheckTicket(mapList, PAGE_SIZE, pageNumber);
pageNumber++;
// 获得总页数
int totalPages = ticketingSamplingRespVO.getTotalPages();
// 处理剩余页的数据
for (; pageNumber <= totalPages; pageNumber++) {
ticketingSamplingReqVO.setPageNumber(pageNumber);
str = HttpUtil.post("http://shinanlundu.pro.jiutianda.com/joytime-erp-eportal/console/openapi/handler", JSONUtil.toJsonStr(ticketingSamplingReqVO));
ticketingSamplingRespVO = new ObjectMapper().readValue(str, TicketingSamplingRespVO.class);
if (!ticketingSamplingRespVO.isPassflag()) {
XxlJobHelper.log("抽数服务:销售数据抽数失败,返回消息:" + ticketingSamplingRespVO.getRtnMsg());
XxlJobHelper.handleFail("销售数据抽数失败,请重试");
return;
}
mapList = ticketingSamplingRespVO.getDataMapList();
// 对最后一页进行处理得到最后一页的实际条数
if (pageNumber != totalPages) {
failedCount += insertCheckTicket(mapList, PAGE_SIZE, pageNumber);
} else {
failedCount += insertCheckTicket(mapList, totalRows % PAGE_SIZE, pageNumber);
}
}
CheckTicketSaveReqDTO checkTicket = new CheckTicketSaveReqDTO();
checkTicket.setDataId((String) stringObjectMap.get("dataId"));
checkTicket.setTicket((String) stringObjectMap.get("ticket"));
checkTicket.setCheckticketdate((String) stringObjectMap.get("checkticketdate"));
checkTicket.setChecktickettime((String) stringObjectMap.get("checktickettime"));
checkTicket.setPersoncount((Integer) stringObjectMap.get("personcount"));
checkTicket.setCheckstation((String) stringObjectMap.get("checkstation"));
checkTicket.setCheckstationname((String) stringObjectMap.get("checkstationname"));
checkTicket.setSdshipping((String) stringObjectMap.get("sdshipping"));
checkTicket.setSalepropetyvaluename((String) stringObjectMap.get("salepropetyvaluename"));
checkTicket.setTenant_id(1L);
ticketCheckTicketApi.createCheckTicket(checkTicket);
successNum++;
} }
XxlJobHelper.log("抽数服务:检票数据抽数正常结束!总共:{}条数据,{}条数据插入失败!", totalRows, failedCount);
}
/**
* 插入销售数据的方法
* @param mapList 数据集合数组
* @param listSize 实际个数
* @param pageNumber 每页显示条数
* @return int 失败条数
*/
private int insertSaleData(List<Map<String, Object>> mapList, int listSize, int pageNumber) {
int failedCount = 0;
for (int i = 0; i < listSize; i++) {
Map<String, Object> currentMap = mapList.get(i);
SaleDataSaveReqDTO saleData = new SaleDataSaveReqDTO();
saleData.setDataId((String) currentMap.get("dataId"));
saleData.setSdno((String) currentMap.get("sdno"));
saleData.setTransactiontypeno((String) currentMap.get("transactiontypeno"));
saleData.setSddate((String) currentMap.get("sddate"));
saleData.setSdtime((String) currentMap.get("sdtime"));
saleData.setAmount(new BigDecimal(currentMap.get("amount").toString()));
saleData.setQuantity((Integer) currentMap.get("quantity"));
saleData.setCertificatetype((String) currentMap.get("certificatetype"));
saleData.setCertificateno((String) currentMap.get("certificateno"));
saleData.setProductbatchno((String) currentMap.get("productbatchno"));
saleData.setItem((String) currentMap.get("item"));
saleData.setItemtypename((String) currentMap.get("itemtypename"));
saleData.setItemtype((String) currentMap.get("itemtype"));
saleData.setItemname((String) currentMap.get("itemname"));
saleData.setSalepropetyvaluename((String) currentMap.get("salepropetyvaluename"));
saleData.setTenant_id(1L);
if (ticketSaleDataApi.createSaleData(saleData).getCode() != 0) {
failedCount++;
XxlJobHelper.log("第{}条数据插入失败,数据值为:{}", ((pageNumber - 1) * PAGE_SIZE + i + 1), currentMap);
}
}
return failedCount;
}
/**
* 插入检票数据的方法
* @param mapList 数据集合数组
* @param listSize 实际个数
* @param pageNumber 每页显示条数
* @return int 失败条数
*/
private int insertCheckTicket(List<Map<String, Object>> mapList, int listSize, int pageNumber) {
int failedCount = 0;
for (int i = 0; i < listSize; i++) {
Map<String, Object> currentMap = mapList.get(i);
CheckTicketSaveReqDTO checkTicket = new CheckTicketSaveReqDTO();
checkTicket.setDataId((String) currentMap.get("dataId"));
checkTicket.setTicket((String) currentMap.get("ticket"));
checkTicket.setCheckticketdate((String) currentMap.get("checkticketdate"));
checkTicket.setChecktickettime((String) currentMap.get("checktickettime"));
checkTicket.setPersoncount((Integer) currentMap.get("personcount"));
checkTicket.setCheckstation((String) currentMap.get("checkstation"));
checkTicket.setCheckstationname((String) currentMap.get("checkstationname"));
checkTicket.setSdshipping((String) currentMap.get("sdshipping"));
checkTicket.setSalepropetyvaluename((String) currentMap.get("salepropetyvaluename"));
checkTicket.setTenant_id(1L);
ticketCheckTicketApi.createCheckTicket(checkTicket);
if (ticketCheckTicketApi.createCheckTicket(checkTicket).getCode() != 0) {
failedCount++;
XxlJobHelper.log("第{}条数据插入失败,数据值为:{}", ((pageNumber - 1) * PAGE_SIZE + i + 1), currentMap);
}
}
return failedCount;
} }
} }

View File

@ -22,6 +22,8 @@ public class TicketingSamplingRespVO {
private Integer pageNumber; private Integer pageNumber;
@Schema(description = "分页每页多少条每页最多2000条") @Schema(description = "分页每页多少条每页最多2000条")
private Integer pageSize; private Integer pageSize;
@Schema(description = "总页数")
private Integer totalPages;
@Schema(description = "总条数") @Schema(description = "总条数")
private Integer totalRows; private Integer totalRows;
@Schema(description = "数据数组") @Schema(description = "数据数组")

View File

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

View File

@ -1,7 +1,8 @@
package cn.iocoder.yudao.module.ticket.framework.security.config; package cn.iocoder.yudao.module.ticket.framework.security.config;
import cn.iocoder.yudao.framework.security.config.AuthorizeRequestsCustomizer; 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.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity;

View File

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

View File

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

View File

@ -1,28 +1,35 @@
package cn.iocoder.yudao.module.infra.controller.admin.job; 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.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.http.HttpRequestUtil; 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.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.JobInfoRespDTO;
import com.xxl.job.admin.api.info.dto.JobInfoSaveReqDTO;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.http.HttpHeaders; import org.apache.poi.ss.formula.functions.T;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.*;
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.client.RestTemplate; import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; 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; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.error;
@Tag(name = "管理后台 - 定时任务") @Tag(name = "管理后台 - 定时任务")
@ -30,36 +37,76 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.error;
@RequestMapping("/infra/job") @RequestMapping("/infra/job")
@Validated @Validated
public class JobController { public class JobController {
/*@Resource @Resource
private JobInfoApi jobInfoApi;*/ private JobInfoApi jobInfoApi;
// private static final String XXL_JOB_URL = "http://127.0.0.1:9090/xxl-job-admin"; @GetMapping("/page")
// private static final String USERNAME = "admin"; // TODO 可以直接读取配置中的账号和密码 @Operation(summary = "获得任务列表")
// 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 = "获得定时任务分页")
@PreAuthorize("@ss.hasPermission('infra:job:query')") @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) { 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); 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 cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import com.xxl.job.admin.api.info.JobInfoApi; 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.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false) @Configuration(proxyBeanMethods = false)
@EnableFeignClients(clients = {AdminUserApi.class, JobInfoApi.class}) @EnableFeignClients(clients = {AdminUserApi.class, JobInfoApi.class, JobLogApi.class})
public class RpcConfiguration { public class RpcConfiguration {
} }