infra:初始化 infra 服务的启动,还有一些报错,正在处理
parent
213ec8bd72
commit
6d5d72999b
|
@ -11,8 +11,8 @@
|
||||||
"appTenentId": "1"
|
"appTenentId": "1"
|
||||||
},
|
},
|
||||||
"gateway": {
|
"gateway": {
|
||||||
"baseUrl": "http://127.0.0.1:8888/admin-api",
|
"baseUrl": "http://127.0.0.1:48080/admin-api",
|
||||||
"systemBaseUrl": "http://127.0.0.1:8888/admin-api",
|
"systemBaseUrl": "http://127.0.0.1:48080/admin-api",
|
||||||
"token": "test1",
|
"token": "test1",
|
||||||
"adminTenentId": "1",
|
"adminTenentId": "1",
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,21 @@
|
||||||
<artifactId>yudao-module-system-api</artifactId> <!-- 需要使用它,进行 Token 的校验 -->
|
<artifactId>yudao-module-system-api</artifactId> <!-- 需要使用它,进行 Token 的校验 -->
|
||||||
<version>${revision}</version>
|
<version>${revision}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- RPC 远程调用相关 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-dubbo</artifactId>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -12,6 +12,7 @@ import cn.iocoder.yudao.module.system.api.oauth2.OAuth2TokenApi;
|
||||||
import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
|
import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
|
||||||
import org.springframework.beans.factory.config.MethodInvokingFactoryBean;
|
import org.springframework.beans.factory.config.MethodInvokingFactoryBean;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
|
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||||
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.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
@ -32,6 +33,7 @@ import javax.annotation.Resource;
|
||||||
*/
|
*/
|
||||||
@Configuration(proxyBeanMethods = false)
|
@Configuration(proxyBeanMethods = false)
|
||||||
@EnableConfigurationProperties(SecurityProperties.class)
|
@EnableConfigurationProperties(SecurityProperties.class)
|
||||||
|
@EnableFeignClients(clients = OAuth2TokenApi.class)
|
||||||
public class YudaoSecurityAutoConfiguration {
|
public class YudaoSecurityAutoConfiguration {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
server:
|
|
||||||
port: 8888
|
|
|
@ -4,3 +4,6 @@ spring:
|
||||||
|
|
||||||
profiles:
|
profiles:
|
||||||
active: local
|
active: local
|
||||||
|
|
||||||
|
server:
|
||||||
|
port: 48080
|
||||||
|
|
|
@ -19,6 +19,13 @@
|
||||||
</description>
|
</description>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<!-- Spring Cloud 基础 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-bootstrap</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- 依赖服务 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>cn.iocoder.cloud</groupId>
|
<groupId>cn.iocoder.cloud</groupId>
|
||||||
<artifactId>yudao-module-system-api</artifactId>
|
<artifactId>yudao-module-system-api</artifactId>
|
||||||
|
@ -57,14 +64,35 @@
|
||||||
<artifactId>yudao-spring-boot-starter-redis</artifactId>
|
<artifactId>yudao-spring-boot-starter-redis</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Config 配置中心相关 -->
|
<!-- RPC 远程调用相关 -->
|
||||||
|
|
||||||
<!-- Job 定时任务相关 -->
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>cn.iocoder.cloud</groupId>
|
<groupId>org.springframework.cloud</groupId>
|
||||||
<artifactId>yudao-spring-boot-starter-job</artifactId>
|
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-dubbo</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Registry 注册中心相关 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Config 配置中心相关 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Job 定时任务相关 TODO 芋艿:暂时去掉 -->
|
||||||
|
<!-- <dependency>-->
|
||||||
|
<!-- <groupId>cn.iocoder.cloud</groupId>-->
|
||||||
|
<!-- <artifactId>yudao-spring-boot-starter-job</artifactId>-->
|
||||||
|
<!-- </dependency>-->
|
||||||
|
|
||||||
<!-- 消息队列相关 -->
|
<!-- 消息队列相关 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>cn.iocoder.cloud</groupId>
|
<groupId>cn.iocoder.cloud</groupId>
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
package cn.iocoder.yudao.module.infra;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||||
|
|
||||||
|
// TODO 芋艿:修改启动文档的地址
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 项目的启动类
|
||||||
|
*
|
||||||
|
* 如果你碰到启动的问题,请认真阅读 https://doc.iocoder.cn/quick-start/ 文章
|
||||||
|
* 如果你碰到启动的问题,请认真阅读 https://doc.iocoder.cn/quick-start/ 文章
|
||||||
|
* 如果你碰到启动的问题,请认真阅读 https://doc.iocoder.cn/quick-start/ 文章
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@SpringBootApplication
|
||||||
|
public class InfraServerApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
// 如果你碰到启动的问题,请认真阅读 https://doc.iocoder.cn/quick-start/ 文章
|
||||||
|
// 如果你碰到启动的问题,请认真阅读 https://doc.iocoder.cn/quick-start/ 文章
|
||||||
|
// 如果你碰到启动的问题,请认真阅读 https://doc.iocoder.cn/quick-start/ 文章
|
||||||
|
|
||||||
|
SpringApplication.run(InfraServerApplication.class, args);
|
||||||
|
|
||||||
|
// 如果你碰到启动的问题,请认真阅读 https://doc.iocoder.cn/quick-start/ 文章
|
||||||
|
// 如果你碰到启动的问题,请认真阅读 https://doc.iocoder.cn/quick-start/ 文章
|
||||||
|
// 如果你碰到启动的问题,请认真阅读 https://doc.iocoder.cn/quick-start/ 文章
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,105 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.infra.controller.admin.config;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|
||||||
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
|
|
||||||
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.config.vo.*;
|
|
||||||
import cn.iocoder.yudao.module.infra.convert.config.ConfigConvert;
|
|
||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.config.ConfigDO;
|
|
||||||
import cn.iocoder.yudao.module.infra.service.config.ConfigService;
|
|
||||||
import cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants;
|
|
||||||
import io.swagger.annotations.Api;
|
|
||||||
import io.swagger.annotations.ApiImplicitParam;
|
|
||||||
import io.swagger.annotations.ApiOperation;
|
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
|
||||||
import org.springframework.validation.annotation.Validated;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import javax.validation.Valid;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
|
||||||
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
|
|
||||||
|
|
||||||
@Api(tags = "管理后台 - 参数配置")
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/infra/config")
|
|
||||||
@Validated
|
|
||||||
public class ConfigController {
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private ConfigService configService;
|
|
||||||
|
|
||||||
@PostMapping("/create")
|
|
||||||
@ApiOperation("创建参数配置")
|
|
||||||
@PreAuthorize("@ss.hasPermission('infra:config:create')")
|
|
||||||
public CommonResult<Long> createConfig(@Valid @RequestBody ConfigCreateReqVO reqVO) {
|
|
||||||
return success(configService.createConfig(reqVO));
|
|
||||||
}
|
|
||||||
|
|
||||||
@PutMapping("/update")
|
|
||||||
@ApiOperation("修改参数配置")
|
|
||||||
@PreAuthorize("@ss.hasPermission('infra:config:update')")
|
|
||||||
public CommonResult<Boolean> updateConfig(@Valid @RequestBody ConfigUpdateReqVO reqVO) {
|
|
||||||
configService.updateConfig(reqVO);
|
|
||||||
return success(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@DeleteMapping("/delete")
|
|
||||||
@ApiOperation("删除参数配置")
|
|
||||||
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
|
|
||||||
@PreAuthorize("@ss.hasPermission('infra:config:delete')")
|
|
||||||
public CommonResult<Boolean> deleteConfig(@RequestParam("id") Long id) {
|
|
||||||
configService.deleteConfig(id);
|
|
||||||
return success(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping(value = "/get")
|
|
||||||
@ApiOperation("获得参数配置")
|
|
||||||
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
|
|
||||||
@PreAuthorize("@ss.hasPermission('infra:config:query')")
|
|
||||||
public CommonResult<ConfigRespVO> getConfig(@RequestParam("id") Long id) {
|
|
||||||
return success(ConfigConvert.INSTANCE.convert(configService.getConfig(id)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping(value = "/get-value-by-key")
|
|
||||||
@ApiOperation(value = "根据参数键名查询参数值", notes = "不可见的配置,不允许返回给前端")
|
|
||||||
@ApiImplicitParam(name = "key", value = "参数键", required = true, example = "yunai.biz.username", dataTypeClass = String.class)
|
|
||||||
public CommonResult<String> getConfigKey(@RequestParam("key") String key) {
|
|
||||||
ConfigDO config = configService.getConfigByKey(key);
|
|
||||||
if (config == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (config.getVisible()) {
|
|
||||||
throw ServiceExceptionUtil.exception(ErrorCodeConstants.CONFIG_GET_VALUE_ERROR_IF_VISIBLE);
|
|
||||||
}
|
|
||||||
return success(config.getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/page")
|
|
||||||
@ApiOperation("获取参数配置分页")
|
|
||||||
@PreAuthorize("@ss.hasPermission('infra:config:query')")
|
|
||||||
public CommonResult<PageResult<ConfigRespVO>> getConfigPage(@Valid ConfigPageReqVO reqVO) {
|
|
||||||
PageResult<ConfigDO> page = configService.getConfigPage(reqVO);
|
|
||||||
return success(ConfigConvert.INSTANCE.convertPage(page));
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/export")
|
|
||||||
@ApiOperation("导出参数配置")
|
|
||||||
@PreAuthorize("@ss.hasPermission('infra:config:export')")
|
|
||||||
@OperateLog(type = EXPORT)
|
|
||||||
public void exportSysConfig(@Valid ConfigExportReqVO reqVO,
|
|
||||||
HttpServletResponse response) throws IOException {
|
|
||||||
List<ConfigDO> list = configService.getConfigList(reqVO);
|
|
||||||
// 拼接数据
|
|
||||||
List<ConfigExcelVO> datas = ConfigConvert.INSTANCE.convertList(list);
|
|
||||||
// 输出
|
|
||||||
ExcelUtils.write(response, "参数配置.xls", "数据", ConfigExcelVO.class, datas);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,40 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.infra.controller.admin.config.vo;
|
|
||||||
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import javax.validation.constraints.NotBlank;
|
|
||||||
import javax.validation.constraints.NotEmpty;
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
import javax.validation.constraints.Size;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 参数配置 Base VO,提供给添加、修改、详细的子 VO 使用
|
|
||||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
public class ConfigBaseVO {
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "参数分组", required = true, example = "biz")
|
|
||||||
@NotEmpty(message = "参数分组不能为空")
|
|
||||||
@Size(max = 50, message = "参数名称不能超过50个字符")
|
|
||||||
private String category;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "参数名称", required = true, example = "数据库名")
|
|
||||||
@NotBlank(message = "参数名称不能为空")
|
|
||||||
@Size(max = 100, message = "参数名称不能超过100个字符")
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "参数键值", required = true, example = "1024")
|
|
||||||
@NotBlank(message = "参数键值不能为空")
|
|
||||||
@Size(max = 500, message = "参数键值长度不能超过500个字符")
|
|
||||||
private String value;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "是否敏感", required = true, example = "true")
|
|
||||||
@NotNull(message = "是否敏感不能为空")
|
|
||||||
private Boolean visible;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "备注", example = "备注一下很帅气!")
|
|
||||||
private String remark;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.infra.controller.admin.config.vo;
|
|
||||||
|
|
||||||
import io.swagger.annotations.ApiModel;
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
|
|
||||||
import javax.validation.constraints.NotBlank;
|
|
||||||
import javax.validation.constraints.Size;
|
|
||||||
|
|
||||||
@ApiModel("管理后台 - 参数配置创建 Request VO")
|
|
||||||
@Data
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
public class ConfigCreateReqVO extends ConfigBaseVO {
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "参数键名", required = true, example = "yunai.db.username")
|
|
||||||
@NotBlank(message = "参数键名长度不能为空")
|
|
||||||
@Size(max = 100, message = "参数键名长度不能超过100个字符")
|
|
||||||
private String key;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,46 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.infra.controller.admin.config.vo;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
|
|
||||||
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
|
|
||||||
import cn.iocoder.yudao.module.infra.enums.DictTypeConstants;
|
|
||||||
import com.alibaba.excel.annotation.ExcelProperty;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 参数配置 Excel 导出响应 VO
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
public class ConfigExcelVO {
|
|
||||||
|
|
||||||
@ExcelProperty("参数配置序号")
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
@ExcelProperty("参数键名")
|
|
||||||
private String key;
|
|
||||||
|
|
||||||
@ExcelProperty("参数分组")
|
|
||||||
private String group;
|
|
||||||
|
|
||||||
@ExcelProperty("参数名称")
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
@ExcelProperty("参数键值")
|
|
||||||
private String value;
|
|
||||||
|
|
||||||
@ExcelProperty(value = "参数类型", converter = DictConvert.class)
|
|
||||||
@DictFormat(DictTypeConstants.CONFIG_TYPE)
|
|
||||||
private Integer type;
|
|
||||||
|
|
||||||
@ExcelProperty(value = "是否敏感", converter = DictConvert.class)
|
|
||||||
@DictFormat(DictTypeConstants.BOOLEAN_STRING)
|
|
||||||
private Boolean sensitive;
|
|
||||||
|
|
||||||
@ExcelProperty("备注")
|
|
||||||
private String remark;
|
|
||||||
|
|
||||||
@ExcelProperty("创建时间")
|
|
||||||
private Date createTime;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.infra.controller.admin.config.vo;
|
|
||||||
|
|
||||||
import io.swagger.annotations.ApiModel;
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import lombok.Data;
|
|
||||||
import org.springframework.format.annotation.DateTimeFormat;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
|
||||||
|
|
||||||
@ApiModel("管理后台 - 参数配置导出 Request VO")
|
|
||||||
@Data
|
|
||||||
public class ConfigExportReqVO {
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "参数名称", example = "模糊匹配")
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "参数键名", example = "yunai.db.username", notes = "模糊匹配")
|
|
||||||
private String key;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "参数类型", example = "1", notes = "参见 SysConfigTypeEnum 枚举")
|
|
||||||
private Integer type;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "开始时间", example = "2020-10-24 00:00:00")
|
|
||||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
|
||||||
private Date beginTime;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "结束时间", example = "2020-10-24 23:59:59")
|
|
||||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
|
||||||
private Date endTime;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,38 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.infra.controller.admin.config.vo;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
|
||||||
import io.swagger.annotations.ApiModel;
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
import lombok.ToString;
|
|
||||||
import org.springframework.format.annotation.DateTimeFormat;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
|
||||||
|
|
||||||
@ApiModel("管理后台 - 参数配置分页 Request VO")
|
|
||||||
@Data
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
@ToString(callSuper = true)
|
|
||||||
public class ConfigPageReqVO extends PageParam {
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "数据源名称", example = "模糊匹配")
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "参数键名", example = "yunai.db.username", notes = "模糊匹配")
|
|
||||||
private String key;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "参数类型", example = "1", notes = "参见 SysConfigTypeEnum 枚举")
|
|
||||||
private Integer type;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "开始时间", example = "2020-10-24 00:00:00")
|
|
||||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
|
||||||
private Date beginTime;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "结束时间", example = "2020-10-24 23:59:59")
|
|
||||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
|
||||||
private Date endTime;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.infra.controller.admin.config.vo;
|
|
||||||
|
|
||||||
import io.swagger.annotations.ApiModel;
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
|
|
||||||
import javax.validation.constraints.NotBlank;
|
|
||||||
import javax.validation.constraints.Size;
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
@ApiModel("管理后台 - 参数配置信息 Response VO")
|
|
||||||
@Data
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
public class ConfigRespVO extends ConfigBaseVO {
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "参数配置序号", required = true, example = "1024")
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "参数键名", required = true, example = "yunai.db.username")
|
|
||||||
@NotBlank(message = "参数键名长度不能为空")
|
|
||||||
@Size(max = 100, message = "参数键名长度不能超过100个字符")
|
|
||||||
private String key;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "参数类型", required = true, example = "1", notes = "参见 SysConfigTypeEnum 枚举")
|
|
||||||
private Integer type;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "创建时间", required = true, example = "时间戳格式")
|
|
||||||
private Date createTime;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.infra.controller.admin.config.vo;
|
|
||||||
|
|
||||||
import io.swagger.annotations.ApiModel;
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
import lombok.ToString;
|
|
||||||
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
|
|
||||||
@ApiModel("管理后台 - 参数配置创建 Request VO")
|
|
||||||
@Data
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
@ToString(callSuper = true)
|
|
||||||
public class ConfigUpdateReqVO extends ConfigBaseVO {
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "参数配置序号", required = true, example = "1024")
|
|
||||||
@NotNull(message = "参数配置编号不能为空")
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,145 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.infra.controller.admin.job;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|
||||||
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
|
|
||||||
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
|
|
||||||
import cn.iocoder.yudao.framework.quartz.core.util.CronUtils;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.job.vo.job.*;
|
|
||||||
import cn.iocoder.yudao.module.infra.convert.job.JobConvert;
|
|
||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.job.JobDO;
|
|
||||||
import cn.iocoder.yudao.module.infra.service.job.JobService;
|
|
||||||
import io.swagger.annotations.Api;
|
|
||||||
import io.swagger.annotations.ApiImplicitParam;
|
|
||||||
import io.swagger.annotations.ApiImplicitParams;
|
|
||||||
import io.swagger.annotations.ApiOperation;
|
|
||||||
import org.quartz.SchedulerException;
|
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
|
||||||
import org.springframework.validation.annotation.Validated;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import javax.validation.Valid;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
|
||||||
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
|
|
||||||
|
|
||||||
@Api(tags = "管理后台 - 定时任务")
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/infra/job")
|
|
||||||
@Validated
|
|
||||||
public class JobController {
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private JobService jobService;
|
|
||||||
|
|
||||||
@PostMapping("/create")
|
|
||||||
@ApiOperation("创建定时任务")
|
|
||||||
@PreAuthorize("@ss.hasPermission('infra:job:create')")
|
|
||||||
public CommonResult<Long> createJob(@Valid @RequestBody JobCreateReqVO createReqVO)
|
|
||||||
throws SchedulerException {
|
|
||||||
return success(jobService.createJob(createReqVO));
|
|
||||||
}
|
|
||||||
|
|
||||||
@PutMapping("/update")
|
|
||||||
@ApiOperation("更新定时任务")
|
|
||||||
@PreAuthorize("@ss.hasPermission('infra:job:update')")
|
|
||||||
public CommonResult<Boolean> updateJob(@Valid @RequestBody JobUpdateReqVO updateReqVO)
|
|
||||||
throws SchedulerException {
|
|
||||||
jobService.updateJob(updateReqVO);
|
|
||||||
return success(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@PutMapping("/update-status")
|
|
||||||
@ApiOperation("更新定时任务的状态")
|
|
||||||
@ApiImplicitParams({
|
|
||||||
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class),
|
|
||||||
@ApiImplicitParam(name = "status", value = "状态", required = true, example = "1", dataTypeClass = Integer.class),
|
|
||||||
})
|
|
||||||
@PreAuthorize("@ss.hasPermission('infra:job:update')")
|
|
||||||
public CommonResult<Boolean> updateJobStatus(@RequestParam(value = "id") Long id, @RequestParam("status") Integer status)
|
|
||||||
throws SchedulerException {
|
|
||||||
jobService.updateJobStatus(id, status);
|
|
||||||
return success(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@DeleteMapping("/delete")
|
|
||||||
@ApiOperation("删除定时任务")
|
|
||||||
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
|
|
||||||
@PreAuthorize("@ss.hasPermission('infra:job:delete')")
|
|
||||||
public CommonResult<Boolean> deleteJob(@RequestParam("id") Long id)
|
|
||||||
throws SchedulerException {
|
|
||||||
jobService.deleteJob(id);
|
|
||||||
return success(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@PutMapping("/trigger")
|
|
||||||
@ApiOperation("触发定时任务")
|
|
||||||
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
|
|
||||||
@PreAuthorize("@ss.hasPermission('infra:job:trigger')")
|
|
||||||
public CommonResult<Boolean> triggerJob(@RequestParam("id") Long id) throws SchedulerException {
|
|
||||||
jobService.triggerJob(id);
|
|
||||||
return success(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/get")
|
|
||||||
@ApiOperation("获得定时任务")
|
|
||||||
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
|
|
||||||
@PreAuthorize("@ss.hasPermission('infra:job:query')")
|
|
||||||
public CommonResult<JobRespVO> getJob(@RequestParam("id") Long id) {
|
|
||||||
JobDO job = jobService.getJob(id);
|
|
||||||
return success(JobConvert.INSTANCE.convert(job));
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/list")
|
|
||||||
@ApiOperation("获得定时任务列表")
|
|
||||||
@ApiImplicitParam(name = "ids", value = "编号列表", required = true, dataTypeClass = List.class)
|
|
||||||
@PreAuthorize("@ss.hasPermission('infra:job:query')")
|
|
||||||
public CommonResult<List<JobRespVO>> getJobList(@RequestParam("ids") Collection<Long> ids) {
|
|
||||||
List<JobDO> list = jobService.getJobList(ids);
|
|
||||||
return success(JobConvert.INSTANCE.convertList(list));
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/page")
|
|
||||||
@ApiOperation("获得定时任务分页")
|
|
||||||
@PreAuthorize("@ss.hasPermission('infra:job:query')")
|
|
||||||
public CommonResult<PageResult<JobRespVO>> getJobPage(@Valid JobPageReqVO pageVO) {
|
|
||||||
PageResult<JobDO> pageResult = jobService.getJobPage(pageVO);
|
|
||||||
return success(JobConvert.INSTANCE.convertPage(pageResult));
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/export-excel")
|
|
||||||
@ApiOperation("导出定时任务 Excel")
|
|
||||||
@PreAuthorize("@ss.hasPermission('infra:job:export')")
|
|
||||||
@OperateLog(type = EXPORT)
|
|
||||||
public void exportJobExcel(@Valid JobExportReqVO exportReqVO,
|
|
||||||
HttpServletResponse response) throws IOException {
|
|
||||||
List<JobDO> list = jobService.getJobList(exportReqVO);
|
|
||||||
// 导出 Excel
|
|
||||||
List<JobExcelVO> datas = JobConvert.INSTANCE.convertList02(list);
|
|
||||||
ExcelUtils.write(response, "定时任务.xls", "数据", JobExcelVO.class, datas);
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/get_next_times")
|
|
||||||
@ApiOperation("获得定时任务的下 n 次执行时间")
|
|
||||||
@ApiImplicitParams({
|
|
||||||
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class),
|
|
||||||
@ApiImplicitParam(name = "count", value = "数量", example = "5", dataTypeClass = Long.class)
|
|
||||||
})
|
|
||||||
@PreAuthorize("@ss.hasPermission('infra:job:query')")
|
|
||||||
public CommonResult<List<Date>> getJobNextTimes(@RequestParam("id") Long id,
|
|
||||||
@RequestParam(value = "count", required = false, defaultValue = "5") Integer count) {
|
|
||||||
JobDO job = jobService.getJob(id);
|
|
||||||
if (job == null) {
|
|
||||||
return success(Collections.emptyList());
|
|
||||||
}
|
|
||||||
return success(CronUtils.getNextTimes(job.getCronExpression(), count));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,81 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.infra.controller.admin.job;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|
||||||
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
|
|
||||||
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.job.vo.log.JobLogExcelVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.job.vo.log.JobLogExportReqVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.job.vo.log.JobLogPageReqVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.job.vo.log.JobLogRespVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.convert.job.JobLogConvert;
|
|
||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.job.JobLogDO;
|
|
||||||
import cn.iocoder.yudao.module.infra.service.job.JobLogService;
|
|
||||||
import io.swagger.annotations.Api;
|
|
||||||
import io.swagger.annotations.ApiImplicitParam;
|
|
||||||
import io.swagger.annotations.ApiOperation;
|
|
||||||
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 javax.annotation.Resource;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import javax.validation.Valid;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
|
||||||
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
|
|
||||||
|
|
||||||
@Api(tags = "管理后台 - 定时任务日志")
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/infra/job-log")
|
|
||||||
@Validated
|
|
||||||
public class JobLogController {
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private JobLogService jobLogService;
|
|
||||||
|
|
||||||
@GetMapping("/get")
|
|
||||||
@ApiOperation("获得定时任务日志")
|
|
||||||
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
|
|
||||||
@PreAuthorize("@ss.hasPermission('infra:job:query')")
|
|
||||||
public CommonResult<JobLogRespVO> getJobLog(@RequestParam("id") Long id) {
|
|
||||||
JobLogDO jobLog = jobLogService.getJobLog(id);
|
|
||||||
return success(JobLogConvert.INSTANCE.convert(jobLog));
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/list")
|
|
||||||
@ApiOperation("获得定时任务日志列表")
|
|
||||||
@ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)
|
|
||||||
@PreAuthorize("@ss.hasPermission('infra:job:query')")
|
|
||||||
public CommonResult<List<JobLogRespVO>> getJobLogList(@RequestParam("ids") Collection<Long> ids) {
|
|
||||||
List<JobLogDO> list = jobLogService.getJobLogList(ids);
|
|
||||||
return success(JobLogConvert.INSTANCE.convertList(list));
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/page")
|
|
||||||
@ApiOperation("获得定时任务日志分页")
|
|
||||||
@PreAuthorize("@ss.hasPermission('infra:job:query')")
|
|
||||||
public CommonResult<PageResult<JobLogRespVO>> getJobLogPage(@Valid JobLogPageReqVO pageVO) {
|
|
||||||
PageResult<JobLogDO> pageResult = jobLogService.getJobLogPage(pageVO);
|
|
||||||
return success(JobLogConvert.INSTANCE.convertPage(pageResult));
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/export-excel")
|
|
||||||
@ApiOperation("导出定时任务日志 Excel")
|
|
||||||
@PreAuthorize("@ss.hasPermission('infra:job:export')")
|
|
||||||
@OperateLog(type = EXPORT)
|
|
||||||
public void exportJobLogExcel(@Valid JobLogExportReqVO exportReqVO,
|
|
||||||
HttpServletResponse response) throws IOException {
|
|
||||||
List<JobLogDO> list = jobLogService.getJobLogList(exportReqVO);
|
|
||||||
// 导出 Excel
|
|
||||||
List<JobLogExcelVO> datas = JobLogConvert.INSTANCE.convertList02(list);
|
|
||||||
ExcelUtils.write(response, "任务日志.xls", "数据", JobLogExcelVO.class, datas);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.infra.controller.admin.job.vo.job;
|
|
||||||
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 定时任务 Base VO,提供给添加、修改、详细的子 VO 使用
|
|
||||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
public class JobBaseVO {
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "任务名称", required = true, example = "测试任务")
|
|
||||||
@NotNull(message = "任务名称不能为空")
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "处理器的参数", example = "yudao")
|
|
||||||
private String handlerParam;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "CRON 表达式", required = true, example = "0/10 * * * * ? *")
|
|
||||||
@NotNull(message = "CRON 表达式不能为空")
|
|
||||||
private String cronExpression;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "重试次数", required = true, example = "3")
|
|
||||||
@NotNull(message = "重试次数不能为空")
|
|
||||||
private Integer retryCount;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "重试间隔", required = true, example = "1000")
|
|
||||||
@NotNull(message = "重试间隔不能为空")
|
|
||||||
private Integer retryInterval;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "监控超时时间", example = "1000")
|
|
||||||
private Integer monitorTimeout;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.infra.controller.admin.job.vo.job;
|
|
||||||
|
|
||||||
import io.swagger.annotations.ApiModel;
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
import lombok.ToString;
|
|
||||||
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
|
|
||||||
@ApiModel("管理后台 - 定时任务创建 Request VO")
|
|
||||||
@Data
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
@ToString(callSuper = true)
|
|
||||||
public class JobCreateReqVO extends JobBaseVO {
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "处理器的名字", required = true, example = "sysUserSessionTimeoutJob")
|
|
||||||
@NotNull(message = "处理器的名字不能为空")
|
|
||||||
private String handlerName;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,56 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.infra.controller.admin.job.vo.job;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
|
|
||||||
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
|
|
||||||
import cn.iocoder.yudao.module.infra.enums.DictTypeConstants;
|
|
||||||
import com.alibaba.excel.annotation.ExcelProperty;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 定时任务 Excel VO
|
|
||||||
*
|
|
||||||
* @author 芋道源码
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
public class JobExcelVO {
|
|
||||||
|
|
||||||
@ExcelProperty("任务编号")
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
@ExcelProperty("任务名称")
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
@ExcelProperty(value = "任务状态", converter = DictConvert.class)
|
|
||||||
@DictFormat(DictTypeConstants.JOB_STATUS)
|
|
||||||
private Integer status;
|
|
||||||
|
|
||||||
@ExcelProperty("处理器的名字")
|
|
||||||
private String handlerName;
|
|
||||||
|
|
||||||
@ExcelProperty("处理器的参数")
|
|
||||||
private String handlerParam;
|
|
||||||
|
|
||||||
@ExcelProperty("CRON 表达式")
|
|
||||||
private String cronExpression;
|
|
||||||
|
|
||||||
@ExcelProperty("最后一次执行的开始时间")
|
|
||||||
private Date executeBeginTime;
|
|
||||||
|
|
||||||
@ExcelProperty("最后一次执行的结束时间")
|
|
||||||
private Date executeEndTime;
|
|
||||||
|
|
||||||
@ExcelProperty("上一次触发时间")
|
|
||||||
private Date firePrevTime;
|
|
||||||
|
|
||||||
@ExcelProperty("下一次触发时间")
|
|
||||||
private Date fireNextTime;
|
|
||||||
|
|
||||||
@ExcelProperty("监控超时时间")
|
|
||||||
private Integer monitorTimeout;
|
|
||||||
|
|
||||||
@ExcelProperty("创建时间")
|
|
||||||
private Date createTime;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.infra.controller.admin.job.vo.job;
|
|
||||||
|
|
||||||
import io.swagger.annotations.ApiModel;
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
@ApiModel(value = "管理后台 - 定时任务 Excel 导出 Request VO", description = "参数和 JobPageReqVO 是一致的")
|
|
||||||
@Data
|
|
||||||
public class JobExportReqVO {
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "任务名称", example = "测试任务", notes = "模糊匹配")
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "任务状态", example = "1", notes = "参见 JobStatusEnum 枚举")
|
|
||||||
private Integer status;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "处理器的名字", example = "UserSessionTimeoutJob", notes = "模糊匹配")
|
|
||||||
private String handlerName;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.infra.controller.admin.job.vo.job;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
|
||||||
import io.swagger.annotations.ApiModel;
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
import lombok.ToString;
|
|
||||||
|
|
||||||
@ApiModel("管理后台 - 定时任务分页 Request VO")
|
|
||||||
@Data
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
@ToString(callSuper = true)
|
|
||||||
public class JobPageReqVO extends PageParam {
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "任务名称", example = "测试任务", notes = "模糊匹配")
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "任务状态", example = "1", notes = "参见 JobStatusEnum 枚举")
|
|
||||||
private Integer status;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "处理器的名字", example = "sysUserSessionTimeoutJob", notes = "模糊匹配")
|
|
||||||
private String handlerName;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.infra.controller.admin.job.vo.job;
|
|
||||||
|
|
||||||
import io.swagger.annotations.ApiModel;
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
import lombok.ToString;
|
|
||||||
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
@ApiModel("管理后台 - 定时任务 Response VO")
|
|
||||||
@Data
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
@ToString(callSuper = true)
|
|
||||||
public class JobRespVO extends JobBaseVO {
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "任务编号", required = true, example = "1024")
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "任务状态", required = true, example = "1")
|
|
||||||
private Integer status;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "处理器的名字", required = true, example = "sysUserSessionTimeoutJob")
|
|
||||||
@NotNull(message = "处理器的名字不能为空")
|
|
||||||
private String handlerName;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "创建时间", required = true)
|
|
||||||
private Date createTime;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.infra.controller.admin.job.vo.job;
|
|
||||||
|
|
||||||
import io.swagger.annotations.ApiModel;
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
import lombok.ToString;
|
|
||||||
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
|
|
||||||
@ApiModel("管理后台 - 定时任务更新 Request VO")
|
|
||||||
@Data
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
@ToString(callSuper = true)
|
|
||||||
public class JobUpdateReqVO extends JobBaseVO {
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "任务编号", required = true, example = "1024")
|
|
||||||
@NotNull(message = "任务编号不能为空")
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,53 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.infra.controller.admin.job.vo.log;
|
|
||||||
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import lombok.Data;
|
|
||||||
import org.springframework.format.annotation.DateTimeFormat;
|
|
||||||
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 定时任务日志 Base VO,提供给添加、修改、详细的子 VO 使用
|
|
||||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
public class JobLogBaseVO {
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "任务编号", required = true, example = "1024")
|
|
||||||
@NotNull(message = "任务编号不能为空")
|
|
||||||
private Long jobId;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "处理器的名字", required = true, example = "sysUserSessionTimeoutJob")
|
|
||||||
@NotNull(message = "处理器的名字不能为空")
|
|
||||||
private String handlerName;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "处理器的参数", example = "yudao")
|
|
||||||
private String handlerParam;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "第几次执行", required = true, example = "1")
|
|
||||||
@NotNull(message = "第几次执行不能为空")
|
|
||||||
private Integer executeIndex;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "开始执行时间", required = true)
|
|
||||||
@NotNull(message = "开始执行时间不能为空")
|
|
||||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
|
||||||
private Date beginTime;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "结束执行时间")
|
|
||||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
|
||||||
private Date endTime;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "执行时长", example = "123")
|
|
||||||
private Integer duration;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "任务状态", required = true, example = "1", notes = "参见 JobLogStatusEnum 枚举")
|
|
||||||
@NotNull(message = "任务状态不能为空")
|
|
||||||
private Integer status;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "结果数据", example = "执行成功")
|
|
||||||
private String result;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,53 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.infra.controller.admin.job.vo.log;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
|
|
||||||
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
|
|
||||||
import cn.iocoder.yudao.module.infra.enums.DictTypeConstants;
|
|
||||||
import com.alibaba.excel.annotation.ExcelProperty;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 定时任务 Excel VO
|
|
||||||
*
|
|
||||||
* @author 芋艿
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
public class JobLogExcelVO {
|
|
||||||
|
|
||||||
@ExcelProperty("日志编号")
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
@ExcelProperty("任务编号")
|
|
||||||
private Long jobId;
|
|
||||||
|
|
||||||
@ExcelProperty("处理器的名字")
|
|
||||||
private String handlerName;
|
|
||||||
|
|
||||||
@ExcelProperty("处理器的参数")
|
|
||||||
private String handlerParam;
|
|
||||||
|
|
||||||
@ExcelProperty("第几次执行")
|
|
||||||
private Integer executeIndex;
|
|
||||||
|
|
||||||
@ExcelProperty("开始执行时间")
|
|
||||||
private Date beginTime;
|
|
||||||
|
|
||||||
@ExcelProperty("结束执行时间")
|
|
||||||
private Date endTime;
|
|
||||||
|
|
||||||
@ExcelProperty("执行时长")
|
|
||||||
private Integer duration;
|
|
||||||
|
|
||||||
@ExcelProperty(value = "任务状态", converter = DictConvert.class)
|
|
||||||
@DictFormat(DictTypeConstants.JOB_STATUS)
|
|
||||||
private Integer status;
|
|
||||||
|
|
||||||
@ExcelProperty("结果数据")
|
|
||||||
private String result;
|
|
||||||
|
|
||||||
@ExcelProperty("创建时间")
|
|
||||||
private Date createTime;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.infra.controller.admin.job.vo.log;
|
|
||||||
|
|
||||||
import io.swagger.annotations.ApiModel;
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import lombok.Data;
|
|
||||||
import org.springframework.format.annotation.DateTimeFormat;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
|
||||||
|
|
||||||
@ApiModel(value = "管理后台 - 定时任务 Excel 导出 Request VO", description = "参数和 JobLogPageReqVO 是一致的")
|
|
||||||
@Data
|
|
||||||
public class JobLogExportReqVO {
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "任务编号", example = "10")
|
|
||||||
private Long jobId;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "处理器的名字", notes = "模糊匹配")
|
|
||||||
private String handlerName;
|
|
||||||
|
|
||||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
|
||||||
@ApiModelProperty(value = "开始执行时间")
|
|
||||||
private Date beginTime;
|
|
||||||
|
|
||||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
|
||||||
@ApiModelProperty(value = "结束执行时间")
|
|
||||||
private Date endTime;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "任务状态", notes = "参见 JobLogStatusEnum 枚举")
|
|
||||||
private Integer status;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,38 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.infra.controller.admin.job.vo.log;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
|
||||||
import io.swagger.annotations.ApiModel;
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
import lombok.ToString;
|
|
||||||
import org.springframework.format.annotation.DateTimeFormat;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
|
||||||
|
|
||||||
@ApiModel("管理后台 - 定时任务日志分页 Request VO")
|
|
||||||
@Data
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
@ToString(callSuper = true)
|
|
||||||
public class JobLogPageReqVO extends PageParam {
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "任务编号", example = "10")
|
|
||||||
private Long jobId;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "处理器的名字", notes = "模糊匹配")
|
|
||||||
private String handlerName;
|
|
||||||
|
|
||||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
|
||||||
@ApiModelProperty(value = "开始执行时间")
|
|
||||||
private Date beginTime;
|
|
||||||
|
|
||||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
|
||||||
@ApiModelProperty(value = "结束执行时间")
|
|
||||||
private Date endTime;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "任务状态", notes = "参见 JobLogStatusEnum 枚举")
|
|
||||||
private Integer status;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.infra.controller.admin.job.vo.log;
|
|
||||||
|
|
||||||
import io.swagger.annotations.ApiModel;
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
import lombok.ToString;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
@ApiModel("管理后台 - 定时任务日志 Response VO")
|
|
||||||
@Data
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
@ToString(callSuper = true)
|
|
||||||
public class JobLogRespVO extends JobLogBaseVO {
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "日志编号", required = true, example = "1024")
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "创建时间", required = true)
|
|
||||||
private Date createTime;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.infra.convert.config;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.config.vo.ConfigCreateReqVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.config.vo.ConfigExcelVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.config.vo.ConfigRespVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.config.vo.ConfigUpdateReqVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.config.ConfigDO;
|
|
||||||
import org.mapstruct.Mapper;
|
|
||||||
import org.mapstruct.Mapping;
|
|
||||||
import org.mapstruct.factory.Mappers;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Mapper
|
|
||||||
public interface ConfigConvert {
|
|
||||||
|
|
||||||
ConfigConvert INSTANCE = Mappers.getMapper(ConfigConvert.class);
|
|
||||||
|
|
||||||
PageResult<ConfigRespVO> convertPage(PageResult<ConfigDO> page);
|
|
||||||
|
|
||||||
@Mapping(source = "configKey", target = "key")
|
|
||||||
ConfigRespVO convert(ConfigDO bean);
|
|
||||||
|
|
||||||
@Mapping(source = "key", target = "configKey")
|
|
||||||
ConfigDO convert(ConfigCreateReqVO bean);
|
|
||||||
|
|
||||||
ConfigDO convert(ConfigUpdateReqVO bean);
|
|
||||||
|
|
||||||
@Mapping(source = "configKey", target = "key")
|
|
||||||
List<ConfigExcelVO> convertList(List<ConfigDO> list);
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.infra.convert.job;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.job.vo.job.JobCreateReqVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.job.vo.job.JobExcelVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.job.vo.job.JobRespVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.job.vo.job.JobUpdateReqVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.job.JobDO;
|
|
||||||
import org.mapstruct.Mapper;
|
|
||||||
import org.mapstruct.factory.Mappers;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 定时任务 Convert
|
|
||||||
*
|
|
||||||
* @author 芋道源码
|
|
||||||
*/
|
|
||||||
@Mapper
|
|
||||||
public interface JobConvert {
|
|
||||||
|
|
||||||
JobConvert INSTANCE = Mappers.getMapper(JobConvert.class);
|
|
||||||
|
|
||||||
JobDO convert(JobCreateReqVO bean);
|
|
||||||
|
|
||||||
JobDO convert(JobUpdateReqVO bean);
|
|
||||||
|
|
||||||
JobRespVO convert(JobDO bean);
|
|
||||||
|
|
||||||
List<JobRespVO> convertList(List<JobDO> list);
|
|
||||||
|
|
||||||
PageResult<JobRespVO> convertPage(PageResult<JobDO> page);
|
|
||||||
|
|
||||||
List<JobExcelVO> convertList02(List<JobDO> list);
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.infra.convert.job;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.job.vo.log.JobLogExcelVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.job.vo.log.JobLogRespVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.job.JobLogDO;
|
|
||||||
import org.mapstruct.Mapper;
|
|
||||||
import org.mapstruct.factory.Mappers;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 定时任务日志 Convert
|
|
||||||
*
|
|
||||||
* @author 芋艿
|
|
||||||
*/
|
|
||||||
@Mapper
|
|
||||||
public interface JobLogConvert {
|
|
||||||
|
|
||||||
JobLogConvert INSTANCE = Mappers.getMapper(JobLogConvert.class);
|
|
||||||
|
|
||||||
JobLogRespVO convert(JobLogDO bean);
|
|
||||||
|
|
||||||
List<JobLogRespVO> convertList(List<JobLogDO> list);
|
|
||||||
|
|
||||||
PageResult<JobLogRespVO> convertPage(PageResult<JobLogDO> page);
|
|
||||||
|
|
||||||
List<JobLogExcelVO> convertList02(List<JobLogDO> list);
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,64 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.infra.dal.dataobject.config;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
|
||||||
import cn.iocoder.yudao.module.infra.enums.config.ConfigTypeEnum;
|
|
||||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
import lombok.ToString;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 参数配置表
|
|
||||||
*
|
|
||||||
* @author 芋道源码
|
|
||||||
*/
|
|
||||||
@TableName("infra_config")
|
|
||||||
@KeySequence("infra_config_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
|
||||||
@Data
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
@ToString(callSuper = true)
|
|
||||||
public class ConfigDO extends BaseDO {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 参数主键
|
|
||||||
*/
|
|
||||||
@TableId
|
|
||||||
private Long id;
|
|
||||||
/**
|
|
||||||
* 参数分类
|
|
||||||
*/
|
|
||||||
private String category;
|
|
||||||
/**
|
|
||||||
* 参数名称
|
|
||||||
*/
|
|
||||||
private String name;
|
|
||||||
/**
|
|
||||||
* 参数键名
|
|
||||||
*
|
|
||||||
* 支持多 DB 类型时,无法直接使用 key + @TableField("config_key") 来实现转换,原因是 "config_key" AS key 而存在报错
|
|
||||||
*/
|
|
||||||
private String configKey;
|
|
||||||
/**
|
|
||||||
* 参数键值
|
|
||||||
*/
|
|
||||||
private String value;
|
|
||||||
/**
|
|
||||||
* 参数类型
|
|
||||||
*
|
|
||||||
* 枚举 {@link ConfigTypeEnum}
|
|
||||||
*/
|
|
||||||
private Integer type;
|
|
||||||
/**
|
|
||||||
* 是否可见
|
|
||||||
*
|
|
||||||
* 不可见的参数,一般是敏感参数,前端不可获取
|
|
||||||
*/
|
|
||||||
private Boolean visible;
|
|
||||||
/**
|
|
||||||
* 备注
|
|
||||||
*/
|
|
||||||
private String remark;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,74 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.infra.dal.dataobject.job;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
|
||||||
import cn.iocoder.yudao.module.infra.enums.job.JobStatusEnum;
|
|
||||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
|
||||||
import lombok.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 定时任务 DO
|
|
||||||
*
|
|
||||||
* @author 芋道源码
|
|
||||||
*/
|
|
||||||
@TableName("infra_job")
|
|
||||||
@KeySequence("infra_job_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
|
||||||
@Data
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
@ToString(callSuper = true)
|
|
||||||
@Builder
|
|
||||||
@NoArgsConstructor
|
|
||||||
@AllArgsConstructor
|
|
||||||
public class JobDO extends BaseDO {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 任务编号
|
|
||||||
*/
|
|
||||||
@TableId
|
|
||||||
private Long id;
|
|
||||||
/**
|
|
||||||
* 任务名称
|
|
||||||
*/
|
|
||||||
private String name;
|
|
||||||
/**
|
|
||||||
* 任务状态
|
|
||||||
*
|
|
||||||
* 枚举 {@link JobStatusEnum}
|
|
||||||
*/
|
|
||||||
private Integer status;
|
|
||||||
/**
|
|
||||||
* 处理器的名字
|
|
||||||
*/
|
|
||||||
private String handlerName;
|
|
||||||
/**
|
|
||||||
* 处理器的参数
|
|
||||||
*/
|
|
||||||
private String handlerParam;
|
|
||||||
/**
|
|
||||||
* CRON 表达式
|
|
||||||
*/
|
|
||||||
private String cronExpression;
|
|
||||||
|
|
||||||
// ========== 重试相关字段 ==========
|
|
||||||
/**
|
|
||||||
* 重试次数
|
|
||||||
* 如果不重试,则设置为 0
|
|
||||||
*/
|
|
||||||
private Integer retryCount;
|
|
||||||
/**
|
|
||||||
* 重试间隔,单位:毫秒
|
|
||||||
* 如果没有间隔,则设置为 0
|
|
||||||
*/
|
|
||||||
private Integer retryInterval;
|
|
||||||
|
|
||||||
// ========== 监控相关字段 ==========
|
|
||||||
/**
|
|
||||||
* 监控超时时间,单位:毫秒
|
|
||||||
* 为空时,表示不监控
|
|
||||||
*
|
|
||||||
* 注意,这里的超时的目的,不是进行任务的取消,而是告警任务的执行时间过长
|
|
||||||
*/
|
|
||||||
private Integer monitorTimeout;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,82 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.infra.dal.dataobject.job;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
|
||||||
import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler;
|
|
||||||
import cn.iocoder.yudao.module.infra.enums.job.JobLogStatusEnum;
|
|
||||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
|
||||||
import lombok.*;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 定时任务的执行日志
|
|
||||||
*
|
|
||||||
* @author 芋道源码
|
|
||||||
*/
|
|
||||||
@TableName("infra_job_log")
|
|
||||||
@KeySequence("infra_job_log_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
|
||||||
@Data
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
@ToString(callSuper = true)
|
|
||||||
@Builder
|
|
||||||
@NoArgsConstructor
|
|
||||||
@AllArgsConstructor
|
|
||||||
public class JobLogDO extends BaseDO {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 日志编号
|
|
||||||
*/
|
|
||||||
private Long id;
|
|
||||||
/**
|
|
||||||
* 任务编号
|
|
||||||
*
|
|
||||||
* 关联 {@link JobDO#getId()}
|
|
||||||
*/
|
|
||||||
private Long jobId;
|
|
||||||
/**
|
|
||||||
* 处理器的名字
|
|
||||||
*
|
|
||||||
* 冗余字段 {@link JobDO#getHandlerName()}
|
|
||||||
*/
|
|
||||||
private String handlerName;
|
|
||||||
/**
|
|
||||||
* 处理器的参数
|
|
||||||
*
|
|
||||||
* 冗余字段 {@link JobDO#getHandlerParam()}
|
|
||||||
*/
|
|
||||||
private String handlerParam;
|
|
||||||
/**
|
|
||||||
* 第几次执行
|
|
||||||
*
|
|
||||||
* 用于区分是不是重试执行。如果是重试执行,则 index 大于 1
|
|
||||||
*/
|
|
||||||
private Integer executeIndex;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 开始执行时间
|
|
||||||
*/
|
|
||||||
private Date beginTime;
|
|
||||||
/**
|
|
||||||
* 结束执行时间
|
|
||||||
*/
|
|
||||||
private Date endTime;
|
|
||||||
/**
|
|
||||||
* 执行时长,单位:毫秒
|
|
||||||
*/
|
|
||||||
private Integer duration;
|
|
||||||
/**
|
|
||||||
* 状态
|
|
||||||
*
|
|
||||||
* 枚举 {@link JobLogStatusEnum}
|
|
||||||
*/
|
|
||||||
private Integer status;
|
|
||||||
/**
|
|
||||||
* 结果数据
|
|
||||||
*
|
|
||||||
* 成功时,使用 {@link JobHandler#execute(String)} 的结果
|
|
||||||
* 失败时,使用 {@link JobHandler#execute(String)} 的异常堆栈
|
|
||||||
*/
|
|
||||||
private String result;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.infra.dal.mysql.job;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.job.vo.log.JobLogExportReqVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.job.vo.log.JobLogPageReqVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.job.JobLogDO;
|
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 任务日志 Mapper
|
|
||||||
*
|
|
||||||
* @author 芋道源码
|
|
||||||
*/
|
|
||||||
@Mapper
|
|
||||||
public interface JobLogMapper extends BaseMapperX<JobLogDO> {
|
|
||||||
|
|
||||||
default PageResult<JobLogDO> selectPage(JobLogPageReqVO reqVO) {
|
|
||||||
return selectPage(reqVO, new QueryWrapperX<JobLogDO>()
|
|
||||||
.eqIfPresent("job_id", reqVO.getJobId())
|
|
||||||
.likeIfPresent("handler_name", reqVO.getHandlerName())
|
|
||||||
.geIfPresent("begin_time", reqVO.getBeginTime())
|
|
||||||
.leIfPresent("end_time", reqVO.getEndTime())
|
|
||||||
.eqIfPresent("status", reqVO.getStatus())
|
|
||||||
.orderByDesc("id") // ID 倒序
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
default List<JobLogDO> selectList(JobLogExportReqVO reqVO) {
|
|
||||||
return selectList(new QueryWrapperX<JobLogDO>()
|
|
||||||
.eqIfPresent("job_id", reqVO.getJobId())
|
|
||||||
.likeIfPresent("handler_name", reqVO.getHandlerName())
|
|
||||||
.geIfPresent("begin_time", reqVO.getBeginTime())
|
|
||||||
.leIfPresent("end_time", reqVO.getEndTime())
|
|
||||||
.eqIfPresent("status", reqVO.getStatus())
|
|
||||||
.orderByDesc("id") // ID 倒序
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,41 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.infra.dal.mysql.job;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.job.vo.job.JobExportReqVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.job.vo.job.JobPageReqVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.job.JobDO;
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 定时任务 Mapper
|
|
||||||
*
|
|
||||||
* @author 芋道源码
|
|
||||||
*/
|
|
||||||
@Mapper
|
|
||||||
public interface JobMapper extends BaseMapperX<JobDO> {
|
|
||||||
|
|
||||||
default JobDO selectByHandlerName(String handlerName) {
|
|
||||||
return selectOne(JobDO::getHandlerName, handlerName);
|
|
||||||
}
|
|
||||||
|
|
||||||
default PageResult<JobDO> selectPage(JobPageReqVO reqVO) {
|
|
||||||
return selectPage(reqVO, new LambdaQueryWrapperX<JobDO>()
|
|
||||||
.likeIfPresent(JobDO::getName, reqVO.getName())
|
|
||||||
.eqIfPresent(JobDO::getStatus, reqVO.getStatus())
|
|
||||||
.likeIfPresent(JobDO::getHandlerName, reqVO.getHandlerName())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
default List<JobDO> selectList(JobExportReqVO reqVO) {
|
|
||||||
return selectList(new LambdaQueryWrapperX<JobDO>()
|
|
||||||
.likeIfPresent(JobDO::getName, reqVO.getName())
|
|
||||||
.eqIfPresent(JobDO::getStatus, reqVO.getStatus())
|
|
||||||
.likeIfPresent(JobDO::getHandlerName, reqVO.getHandlerName())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.infra.enums.config;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@AllArgsConstructor
|
|
||||||
public enum ConfigTypeEnum {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 系统配置
|
|
||||||
*/
|
|
||||||
SYSTEM(1),
|
|
||||||
/**
|
|
||||||
* 自定义配置
|
|
||||||
*/
|
|
||||||
CUSTOM(2);
|
|
||||||
|
|
||||||
private final Integer type;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,24 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.infra.enums.job;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 任务日志的状态枚举
|
|
||||||
*
|
|
||||||
* @author 芋道源码
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@AllArgsConstructor
|
|
||||||
public enum JobLogStatusEnum {
|
|
||||||
|
|
||||||
RUNNING(0), // 运行中
|
|
||||||
SUCCESS(1), // 成功
|
|
||||||
FAILURE(2); // 失败
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 状态
|
|
||||||
*/
|
|
||||||
private final Integer status;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,42 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.infra.enums.job;
|
|
||||||
|
|
||||||
import com.google.common.collect.Sets;
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
|
||||||
import org.quartz.impl.jdbcjobstore.Constants;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 任务状态的枚举
|
|
||||||
*
|
|
||||||
* @author 芋道源码
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@AllArgsConstructor
|
|
||||||
public enum JobStatusEnum {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 初始化中
|
|
||||||
*/
|
|
||||||
INIT(0, Collections.emptySet()),
|
|
||||||
/**
|
|
||||||
* 开启
|
|
||||||
*/
|
|
||||||
NORMAL(1, Sets.newHashSet(Constants.STATE_WAITING, Constants.STATE_ACQUIRED, Constants.STATE_BLOCKED)),
|
|
||||||
/**
|
|
||||||
* 暂停
|
|
||||||
*/
|
|
||||||
STOP(2, Sets.newHashSet(Constants.STATE_PAUSED, Constants.STATE_PAUSED_BLOCKED));
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 状态
|
|
||||||
*/
|
|
||||||
private final Integer status;
|
|
||||||
/**
|
|
||||||
* 对应的 Quartz 触发器的状态集合
|
|
||||||
*/
|
|
||||||
private final Set<String> quartzStates;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,75 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.infra.service.config;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.config.vo.ConfigCreateReqVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.config.vo.ConfigExportReqVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.config.vo.ConfigPageReqVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.config.vo.ConfigUpdateReqVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.config.ConfigDO;
|
|
||||||
|
|
||||||
import javax.validation.Valid;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 参数配置 Service 接口
|
|
||||||
*
|
|
||||||
* @author 芋道源码
|
|
||||||
*/
|
|
||||||
public interface ConfigService {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建参数配置
|
|
||||||
*
|
|
||||||
* @param reqVO 创建信息
|
|
||||||
* @return 配置编号
|
|
||||||
*/
|
|
||||||
Long createConfig(@Valid ConfigCreateReqVO reqVO);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新参数配置
|
|
||||||
*
|
|
||||||
* @param reqVO 更新信息
|
|
||||||
*/
|
|
||||||
void updateConfig(@Valid ConfigUpdateReqVO reqVO);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除参数配置
|
|
||||||
*
|
|
||||||
* @param id 配置编号
|
|
||||||
*/
|
|
||||||
void deleteConfig(Long id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获得参数配置
|
|
||||||
*
|
|
||||||
* @param id 配置编号
|
|
||||||
* @return 参数配置
|
|
||||||
*/
|
|
||||||
ConfigDO getConfig(Long id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据参数键,获得参数配置
|
|
||||||
*
|
|
||||||
* @param key 配置键
|
|
||||||
* @return 参数配置
|
|
||||||
*/
|
|
||||||
ConfigDO getConfigByKey(String key);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获得参数配置分页列表
|
|
||||||
*
|
|
||||||
* @param reqVO 分页条件
|
|
||||||
* @return 分页列表
|
|
||||||
*/
|
|
||||||
PageResult<ConfigDO> getConfigPage(@Valid ConfigPageReqVO reqVO);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获得参数配置列表
|
|
||||||
*
|
|
||||||
* @param reqVO 列表
|
|
||||||
* @return 列表
|
|
||||||
*/
|
|
||||||
List<ConfigDO> getConfigList(@Valid ConfigExportReqVO reqVO);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,132 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.infra.service.config;
|
|
||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.config.vo.ConfigCreateReqVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.config.vo.ConfigExportReqVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.config.vo.ConfigPageReqVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.config.vo.ConfigUpdateReqVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.convert.config.ConfigConvert;
|
|
||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.config.ConfigDO;
|
|
||||||
import cn.iocoder.yudao.module.infra.dal.mysql.config.ConfigMapper;
|
|
||||||
import cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants;
|
|
||||||
import cn.iocoder.yudao.module.infra.enums.config.ConfigTypeEnum;
|
|
||||||
import cn.iocoder.yudao.module.infra.mq.producer.config.ConfigProducer;
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.validation.annotation.Validated;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 参数配置 Service 实现类
|
|
||||||
*/
|
|
||||||
@Service
|
|
||||||
@Slf4j
|
|
||||||
@Validated
|
|
||||||
public class ConfigServiceImpl implements ConfigService {
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private ConfigMapper configMapper;
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private ConfigProducer configProducer;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Long createConfig(ConfigCreateReqVO reqVO) {
|
|
||||||
// 校验正确性
|
|
||||||
checkCreateOrUpdate(null, reqVO.getKey());
|
|
||||||
// 插入参数配置
|
|
||||||
ConfigDO config = ConfigConvert.INSTANCE.convert(reqVO);
|
|
||||||
config.setType(ConfigTypeEnum.CUSTOM.getType());
|
|
||||||
configMapper.insert(config);
|
|
||||||
// 发送刷新消息
|
|
||||||
configProducer.sendConfigRefreshMessage();
|
|
||||||
return config.getId();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updateConfig(ConfigUpdateReqVO reqVO) {
|
|
||||||
// 校验正确性
|
|
||||||
checkCreateOrUpdate(reqVO.getId(), null); // 不允许更新 key
|
|
||||||
// 更新参数配置
|
|
||||||
ConfigDO updateObj = ConfigConvert.INSTANCE.convert(reqVO);
|
|
||||||
configMapper.updateById(updateObj);
|
|
||||||
// 发送刷新消息
|
|
||||||
configProducer.sendConfigRefreshMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void deleteConfig(Long id) {
|
|
||||||
// 校验配置存在
|
|
||||||
ConfigDO config = checkConfigExists(id);
|
|
||||||
// 内置配置,不允许删除
|
|
||||||
if (ConfigTypeEnum.SYSTEM.getType().equals(config.getType())) {
|
|
||||||
throw ServiceExceptionUtil.exception(ErrorCodeConstants.CONFIG_CAN_NOT_DELETE_SYSTEM_TYPE);
|
|
||||||
}
|
|
||||||
// 删除
|
|
||||||
configMapper.deleteById(id);
|
|
||||||
// 发送刷新消息
|
|
||||||
configProducer.sendConfigRefreshMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ConfigDO getConfig(Long id) {
|
|
||||||
return configMapper.selectById(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ConfigDO getConfigByKey(String key) {
|
|
||||||
return configMapper.selectByKey(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PageResult<ConfigDO> getConfigPage(ConfigPageReqVO reqVO) {
|
|
||||||
return configMapper.selectPage(reqVO);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<ConfigDO> getConfigList(ConfigExportReqVO reqVO) {
|
|
||||||
return configMapper.selectList(reqVO);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkCreateOrUpdate(Long id, String key) {
|
|
||||||
// 校验自己存在
|
|
||||||
checkConfigExists(id);
|
|
||||||
// 校验参数配置 key 的唯一性
|
|
||||||
if (StrUtil.isNotEmpty(key)) {
|
|
||||||
checkConfigKeyUnique(id, key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
public ConfigDO checkConfigExists(Long id) {
|
|
||||||
if (id == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
ConfigDO config = configMapper.selectById(id);
|
|
||||||
if (config == null) {
|
|
||||||
throw ServiceExceptionUtil.exception(ErrorCodeConstants.CONFIG_NOT_EXISTS);
|
|
||||||
}
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
public void checkConfigKeyUnique(Long id, String key) {
|
|
||||||
ConfigDO config = configMapper.selectByKey(key);
|
|
||||||
if (config == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 如果 id 为空,说明不用比较是否为相同 id 的参数配置
|
|
||||||
if (id == null) {
|
|
||||||
throw ServiceExceptionUtil.exception(ErrorCodeConstants.CONFIG_KEY_DUPLICATE);
|
|
||||||
}
|
|
||||||
if (!config.getId().equals(id)) {
|
|
||||||
throw ServiceExceptionUtil.exception(ErrorCodeConstants.CONFIG_KEY_DUPLICATE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,51 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.infra.service.job;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|
||||||
import cn.iocoder.yudao.framework.quartz.core.service.JobLogFrameworkService;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.job.vo.log.JobLogExportReqVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.job.vo.log.JobLogPageReqVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.job.JobLogDO;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Job 日志 Service 接口
|
|
||||||
*
|
|
||||||
* @author 芋道源码
|
|
||||||
*/
|
|
||||||
public interface JobLogService extends JobLogFrameworkService {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获得定时任务
|
|
||||||
*
|
|
||||||
* @param id 编号
|
|
||||||
* @return 定时任务
|
|
||||||
*/
|
|
||||||
JobLogDO getJobLog(Long id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获得定时任务列表
|
|
||||||
*
|
|
||||||
* @param ids 编号
|
|
||||||
* @return 定时任务列表
|
|
||||||
*/
|
|
||||||
List<JobLogDO> getJobLogList(Collection<Long> ids);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获得定时任务分页
|
|
||||||
*
|
|
||||||
* @param pageReqVO 分页查询
|
|
||||||
* @return 定时任务分页
|
|
||||||
*/
|
|
||||||
PageResult<JobLogDO> getJobLogPage(JobLogPageReqVO pageReqVO);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获得定时任务列表, 用于 Excel 导出
|
|
||||||
*
|
|
||||||
* @param exportReqVO 查询条件
|
|
||||||
* @return 定时任务分页
|
|
||||||
*/
|
|
||||||
List<JobLogDO> getJobLogList(JobLogExportReqVO exportReqVO);
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,73 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.infra.service.job;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.job.vo.log.JobLogExportReqVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.job.vo.log.JobLogPageReqVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.job.JobLogDO;
|
|
||||||
import cn.iocoder.yudao.module.infra.dal.mysql.job.JobLogMapper;
|
|
||||||
import cn.iocoder.yudao.module.infra.enums.job.JobLogStatusEnum;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.scheduling.annotation.Async;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.validation.annotation.Validated;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Job 日志 Service 实现类
|
|
||||||
*
|
|
||||||
* @author 芋道源码
|
|
||||||
*/
|
|
||||||
@Service
|
|
||||||
@Validated
|
|
||||||
@Slf4j
|
|
||||||
public class JobLogServiceImpl implements JobLogService {
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private JobLogMapper jobLogMapper;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Long createJobLog(Long jobId, Date beginTime, String jobHandlerName, String jobHandlerParam, Integer executeIndex) {
|
|
||||||
JobLogDO log = JobLogDO.builder().jobId(jobId).handlerName(jobHandlerName).handlerParam(jobHandlerParam).executeIndex(executeIndex)
|
|
||||||
.beginTime(beginTime).status(JobLogStatusEnum.RUNNING.getStatus()).build();
|
|
||||||
jobLogMapper.insert(log);
|
|
||||||
return log.getId();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Async
|
|
||||||
public void updateJobLogResultAsync(Long logId, Date endTime, Integer duration, boolean success, String result) {
|
|
||||||
try {
|
|
||||||
JobLogDO updateObj = JobLogDO.builder().id(logId).endTime(endTime).duration(duration)
|
|
||||||
.status(success ? JobLogStatusEnum.SUCCESS.getStatus() : JobLogStatusEnum.FAILURE.getStatus()).result(result).build();
|
|
||||||
jobLogMapper.updateById(updateObj);
|
|
||||||
} catch (Exception ex) {
|
|
||||||
log.error("[updateJobLogResultAsync][logId({}) endTime({}) duration({}) success({}) result({})]",
|
|
||||||
logId, endTime, duration, success, result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JobLogDO getJobLog(Long id) {
|
|
||||||
return jobLogMapper.selectById(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<JobLogDO> getJobLogList(Collection<Long> ids) {
|
|
||||||
return jobLogMapper.selectBatchIds(ids);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PageResult<JobLogDO> getJobLogPage(JobLogPageReqVO pageReqVO) {
|
|
||||||
return jobLogMapper.selectPage(pageReqVO);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<JobLogDO> getJobLogList(JobLogExportReqVO exportReqVO) {
|
|
||||||
return jobLogMapper.selectList(exportReqVO);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,91 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.infra.service.job;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.job.vo.job.JobCreateReqVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.job.vo.job.JobExportReqVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.job.vo.job.JobPageReqVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.job.vo.job.JobUpdateReqVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.job.JobDO;
|
|
||||||
import org.quartz.SchedulerException;
|
|
||||||
|
|
||||||
import javax.validation.Valid;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 定时任务 Service 接口
|
|
||||||
*
|
|
||||||
* @author 芋道源码
|
|
||||||
*/
|
|
||||||
public interface JobService {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建定时任务
|
|
||||||
*
|
|
||||||
* @param createReqVO 创建信息
|
|
||||||
* @return 编号
|
|
||||||
*/
|
|
||||||
Long createJob(@Valid JobCreateReqVO createReqVO) throws SchedulerException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新定时任务
|
|
||||||
*
|
|
||||||
* @param updateReqVO 更新信息
|
|
||||||
*/
|
|
||||||
void updateJob(@Valid JobUpdateReqVO updateReqVO) throws SchedulerException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新定时任务的状态
|
|
||||||
*
|
|
||||||
* @param id 任务编号
|
|
||||||
* @param status 状态
|
|
||||||
*/
|
|
||||||
void updateJobStatus(Long id, Integer status) throws SchedulerException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 触发定时任务
|
|
||||||
*
|
|
||||||
* @param id 任务编号
|
|
||||||
*/
|
|
||||||
void triggerJob(Long id) throws SchedulerException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除定时任务
|
|
||||||
*
|
|
||||||
* @param id 编号
|
|
||||||
*/
|
|
||||||
void deleteJob(Long id) throws SchedulerException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获得定时任务
|
|
||||||
*
|
|
||||||
* @param id 编号
|
|
||||||
* @return 定时任务
|
|
||||||
*/
|
|
||||||
JobDO getJob(Long id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获得定时任务列表
|
|
||||||
*
|
|
||||||
* @param ids 编号
|
|
||||||
* @return 定时任务列表
|
|
||||||
*/
|
|
||||||
List<JobDO> getJobList(Collection<Long> ids);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获得定时任务分页
|
|
||||||
*
|
|
||||||
* @param pageReqVO 分页查询
|
|
||||||
* @return 定时任务分页
|
|
||||||
*/
|
|
||||||
PageResult<JobDO> getJobPage(JobPageReqVO pageReqVO);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获得定时任务列表, 用于 Excel 导出
|
|
||||||
*
|
|
||||||
* @param exportReqVO 查询条件
|
|
||||||
* @return 定时任务分页
|
|
||||||
*/
|
|
||||||
List<JobDO> getJobList(JobExportReqVO exportReqVO);
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,173 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.infra.service.job;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|
||||||
import cn.iocoder.yudao.framework.quartz.core.scheduler.SchedulerManager;
|
|
||||||
import cn.iocoder.yudao.framework.quartz.core.util.CronUtils;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.job.vo.job.JobCreateReqVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.job.vo.job.JobExportReqVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.job.vo.job.JobPageReqVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.job.vo.job.JobUpdateReqVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.convert.job.JobConvert;
|
|
||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.job.JobDO;
|
|
||||||
import cn.iocoder.yudao.module.infra.dal.mysql.job.JobMapper;
|
|
||||||
import cn.iocoder.yudao.module.infra.enums.job.JobStatusEnum;
|
|
||||||
import org.quartz.SchedulerException;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
import org.springframework.validation.annotation.Validated;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
|
||||||
import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.*;
|
|
||||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.containsAny;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 定时任务 Service 实现类
|
|
||||||
*
|
|
||||||
* @author 芋道源码
|
|
||||||
*/
|
|
||||||
@Service
|
|
||||||
@Validated
|
|
||||||
public class JobServiceImpl implements JobService {
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private JobMapper jobMapper;
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private SchedulerManager schedulerManager;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
|
||||||
public Long createJob(JobCreateReqVO createReqVO) throws SchedulerException {
|
|
||||||
validateCronExpression(createReqVO.getCronExpression());
|
|
||||||
// 校验唯一性
|
|
||||||
if (jobMapper.selectByHandlerName(createReqVO.getHandlerName()) != null) {
|
|
||||||
throw exception(JOB_HANDLER_EXISTS);
|
|
||||||
}
|
|
||||||
// 插入
|
|
||||||
JobDO job = JobConvert.INSTANCE.convert(createReqVO);
|
|
||||||
job.setStatus(JobStatusEnum.INIT.getStatus());
|
|
||||||
fillJobMonitorTimeoutEmpty(job);
|
|
||||||
jobMapper.insert(job);
|
|
||||||
|
|
||||||
// 添加 Job 到 Quartz 中
|
|
||||||
schedulerManager.addJob(job.getId(), job.getHandlerName(), job.getHandlerParam(), job.getCronExpression(),
|
|
||||||
createReqVO.getRetryCount(), createReqVO.getRetryInterval());
|
|
||||||
// 更新
|
|
||||||
JobDO updateObj = JobDO.builder().id(job.getId()).status(JobStatusEnum.NORMAL.getStatus()).build();
|
|
||||||
jobMapper.updateById(updateObj);
|
|
||||||
|
|
||||||
// 返回
|
|
||||||
return job.getId();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
|
||||||
public void updateJob(JobUpdateReqVO updateReqVO) throws SchedulerException {
|
|
||||||
validateCronExpression(updateReqVO.getCronExpression());
|
|
||||||
// 校验存在
|
|
||||||
JobDO job = this.validateJobExists(updateReqVO.getId());
|
|
||||||
// 只有开启状态,才可以修改.原因是,如果出暂停状态,修改 Quartz Job 时,会导致任务又开始执行
|
|
||||||
if (!job.getStatus().equals(JobStatusEnum.NORMAL.getStatus())) {
|
|
||||||
throw exception(JOB_UPDATE_ONLY_NORMAL_STATUS);
|
|
||||||
}
|
|
||||||
// 更新
|
|
||||||
JobDO updateObj = JobConvert.INSTANCE.convert(updateReqVO);
|
|
||||||
fillJobMonitorTimeoutEmpty(updateObj);
|
|
||||||
jobMapper.updateById(updateObj);
|
|
||||||
|
|
||||||
// 更新 Job 到 Quartz 中
|
|
||||||
schedulerManager.updateJob(job.getHandlerName(), updateReqVO.getHandlerParam(), updateReqVO.getCronExpression(),
|
|
||||||
updateReqVO.getRetryCount(), updateReqVO.getRetryInterval());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
|
||||||
public void updateJobStatus(Long id, Integer status) throws SchedulerException {
|
|
||||||
// 校验 status
|
|
||||||
if (!containsAny(status, JobStatusEnum.NORMAL.getStatus(), JobStatusEnum.STOP.getStatus())) {
|
|
||||||
throw exception(JOB_CHANGE_STATUS_INVALID);
|
|
||||||
}
|
|
||||||
// 校验存在
|
|
||||||
JobDO job = this.validateJobExists(id);
|
|
||||||
// 校验是否已经为当前状态
|
|
||||||
if (job.getStatus().equals(status)) {
|
|
||||||
throw exception(JOB_CHANGE_STATUS_EQUALS);
|
|
||||||
}
|
|
||||||
// 更新 Job 状态
|
|
||||||
JobDO updateObj = JobDO.builder().id(id).status(status).build();
|
|
||||||
jobMapper.updateById(updateObj);
|
|
||||||
|
|
||||||
// 更新状态 Job 到 Quartz 中
|
|
||||||
if (JobStatusEnum.NORMAL.getStatus().equals(status)) { // 开启
|
|
||||||
schedulerManager.resumeJob(job.getHandlerName());
|
|
||||||
} else { // 暂停
|
|
||||||
schedulerManager.pauseJob(job.getHandlerName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void triggerJob(Long id) throws SchedulerException {
|
|
||||||
// 校验存在
|
|
||||||
JobDO job = this.validateJobExists(id);
|
|
||||||
|
|
||||||
// 触发 Quartz 中的 Job
|
|
||||||
schedulerManager.triggerJob(job.getId(), job.getHandlerName(), job.getHandlerParam());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
|
||||||
public void deleteJob(Long id) throws SchedulerException {
|
|
||||||
// 校验存在
|
|
||||||
JobDO job = this.validateJobExists(id);
|
|
||||||
// 更新
|
|
||||||
jobMapper.deleteById(id);
|
|
||||||
|
|
||||||
// 删除 Job 到 Quartz 中
|
|
||||||
schedulerManager.deleteJob(job.getHandlerName());
|
|
||||||
}
|
|
||||||
|
|
||||||
private JobDO validateJobExists(Long id) {
|
|
||||||
JobDO job = jobMapper.selectById(id);
|
|
||||||
if (job == null) {
|
|
||||||
throw exception(JOB_NOT_EXISTS);
|
|
||||||
}
|
|
||||||
return job;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void validateCronExpression(String cronExpression) {
|
|
||||||
if (!CronUtils.isValid(cronExpression)) {
|
|
||||||
throw exception(JOB_CRON_EXPRESSION_VALID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JobDO getJob(Long id) {
|
|
||||||
return jobMapper.selectById(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<JobDO> getJobList(Collection<Long> ids) {
|
|
||||||
return jobMapper.selectBatchIds(ids);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PageResult<JobDO> getJobPage(JobPageReqVO pageReqVO) {
|
|
||||||
return jobMapper.selectPage(pageReqVO);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<JobDO> getJobList(JobExportReqVO exportReqVO) {
|
|
||||||
return jobMapper.selectList(exportReqVO);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void fillJobMonitorTimeoutEmpty(JobDO job) {
|
|
||||||
if (job.getMonitorTimeout() == null) {
|
|
||||||
job.setMonitorTimeout(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,204 @@
|
||||||
|
server:
|
||||||
|
port: 48082
|
||||||
|
|
||||||
|
--- #################### 数据库相关配置 ####################
|
||||||
|
|
||||||
|
spring:
|
||||||
|
# 数据源配置项
|
||||||
|
autoconfigure:
|
||||||
|
exclude:
|
||||||
|
- com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure # 排除 Druid 的自动配置,使用 dynamic-datasource-spring-boot-starter 配置多数据源
|
||||||
|
datasource:
|
||||||
|
druid: # Druid 【监控】相关的全局配置
|
||||||
|
web-stat-filter:
|
||||||
|
enabled: true
|
||||||
|
stat-view-servlet:
|
||||||
|
enabled: true
|
||||||
|
allow: # 设置白名单,不填则允许所有访问
|
||||||
|
url-pattern: /druid/*
|
||||||
|
login-username: # 控制台管理用户名和密码
|
||||||
|
login-password:
|
||||||
|
filter:
|
||||||
|
stat:
|
||||||
|
enabled: true
|
||||||
|
log-slow-sql: true # 慢 SQL 记录
|
||||||
|
slow-sql-millis: 100
|
||||||
|
merge-sql: true
|
||||||
|
wall:
|
||||||
|
config:
|
||||||
|
multi-statement-allow: true
|
||||||
|
dynamic: # 多数据源配置
|
||||||
|
druid: # Druid 【连接池】相关的全局配置
|
||||||
|
initial-size: 5 # 初始连接数
|
||||||
|
min-idle: 10 # 最小连接池数量
|
||||||
|
max-active: 20 # 最大连接池数量
|
||||||
|
max-wait: 600000 # 配置获取连接等待超时的时间,单位:毫秒
|
||||||
|
time-between-eviction-runs-millis: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位:毫秒
|
||||||
|
min-evictable-idle-time-millis: 300000 # 配置一个连接在池中最小生存的时间,单位:毫秒
|
||||||
|
max-evictable-idle-time-millis: 900000 # 配置一个连接在池中最大生存的时间,单位:毫秒
|
||||||
|
validation-query: SELECT 1 # 配置检测连接是否有效
|
||||||
|
test-while-idle: true
|
||||||
|
test-on-borrow: false
|
||||||
|
test-on-return: false
|
||||||
|
primary: master
|
||||||
|
datasource:
|
||||||
|
master:
|
||||||
|
name: ruoyi-vue-pro
|
||||||
|
url: jdbc:mysql://400-infra.server.iocoder.cn:3306/${spring.datasource.dynamic.datasource.master.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT&nullCatalogMeansCurrent=true
|
||||||
|
driver-class-name: com.mysql.jdbc.Driver
|
||||||
|
username: root
|
||||||
|
password: 3WLiVUBEwTbvAfsh
|
||||||
|
slave: # 模拟从库,可根据自己需要修改 # 模拟从库,可根据自己需要修改
|
||||||
|
name: ruoyi-vue-pro
|
||||||
|
url: jdbc:mysql://400-infra.server.iocoder.cn:3306/${spring.datasource.dynamic.datasource.slave.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT&nullCatalogMeansCurrent=true
|
||||||
|
driver-class-name: com.mysql.jdbc.Driver
|
||||||
|
username: root
|
||||||
|
password: 3WLiVUBEwTbvAfsh
|
||||||
|
|
||||||
|
# Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
|
||||||
|
redis:
|
||||||
|
host: 400-infra.server.iocoder.cn # 地址
|
||||||
|
port: 6379 # 端口
|
||||||
|
database: 1 # 数据库索引
|
||||||
|
# password: 123456 # 密码,建议生产环境开启
|
||||||
|
|
||||||
|
jasypt:
|
||||||
|
encryptor:
|
||||||
|
password: yuanma # 加解密的秘钥
|
||||||
|
|
||||||
|
--- #################### 定时任务相关配置 ####################
|
||||||
|
|
||||||
|
# Quartz 配置项,对应 QuartzProperties 配置类
|
||||||
|
spring:
|
||||||
|
quartz:
|
||||||
|
auto-startup: true # 测试环境,需要开启 Job
|
||||||
|
scheduler-name: schedulerName # Scheduler 名字。默认为 schedulerName
|
||||||
|
job-store-type: jdbc # Job 存储器类型。默认为 memory 表示内存,可选 jdbc 使用数据库。
|
||||||
|
wait-for-jobs-to-complete-on-shutdown: true # 应用关闭时,是否等待定时任务执行完成。默认为 false ,建议设置为 true
|
||||||
|
properties: # 添加 Quartz Scheduler 附加属性,更多可以看 http://www.quartz-scheduler.org/documentation/2.4.0-SNAPSHOT/configuration.html 文档
|
||||||
|
org:
|
||||||
|
quartz:
|
||||||
|
# Scheduler 相关配置
|
||||||
|
scheduler:
|
||||||
|
instanceName: schedulerName
|
||||||
|
instanceId: AUTO # 自动生成 instance ID
|
||||||
|
# JobStore 相关配置
|
||||||
|
jobStore:
|
||||||
|
# JobStore 实现类。可见博客:https://blog.csdn.net/weixin_42458219/article/details/122247162
|
||||||
|
class: org.springframework.scheduling.quartz.LocalDataSourceJobStore
|
||||||
|
isClustered: true # 是集群模式
|
||||||
|
clusterCheckinInterval: 15000 # 集群检查频率,单位:毫秒。默认为 15000,即 15 秒
|
||||||
|
misfireThreshold: 60000 # misfire 阀值,单位:毫秒。
|
||||||
|
# 线程池相关配置
|
||||||
|
threadPool:
|
||||||
|
threadCount: 25 # 线程池大小。默认为 10 。
|
||||||
|
threadPriority: 5 # 线程优先级
|
||||||
|
class: org.quartz.simpl.SimpleThreadPool # 线程池类型
|
||||||
|
jdbc: # 使用 JDBC 的 JobStore 的时候,JDBC 的配置
|
||||||
|
initialize-schema: NEVER # 是否自动使用 SQL 初始化 Quartz 表结构。这里设置成 never ,我们手动创建表结构。
|
||||||
|
|
||||||
|
--- #################### 配置中心相关配置 ####################
|
||||||
|
|
||||||
|
# Apollo 配置中心
|
||||||
|
apollo:
|
||||||
|
bootstrap:
|
||||||
|
enabled: true # 设置 Apollo 在启动阶段生效
|
||||||
|
eagerLoad:
|
||||||
|
enabled: true # 设置 Apollo 在日志初始化前生效,可以实现日志的动态级别配置
|
||||||
|
jdbc: # 自定义的 JDBC 配置项,用于数据库的地址
|
||||||
|
dao: cn.iocoder.yudao.module.infra.dal.mysql.config.ConfigDAOImpl
|
||||||
|
url: ${spring.datasource.dynamic.datasource.master.url}
|
||||||
|
username: ${spring.datasource.dynamic.datasource.master.username}
|
||||||
|
password: ${spring.datasource.dynamic.datasource.master.password}
|
||||||
|
|
||||||
|
--- #################### 服务保障相关配置 ####################
|
||||||
|
|
||||||
|
# Lock4j 配置项
|
||||||
|
lock4j:
|
||||||
|
acquire-timeout: 3000 # 获取分布式锁超时时间,默认为 3000 毫秒
|
||||||
|
expire: 30000 # 分布式锁的超时时间,默认为 30 毫秒
|
||||||
|
|
||||||
|
# Resilience4j 配置项
|
||||||
|
resilience4j:
|
||||||
|
ratelimiter:
|
||||||
|
instances:
|
||||||
|
backendA:
|
||||||
|
limit-for-period: 1 # 每个周期内,允许的请求数。默认为 50
|
||||||
|
limit-refresh-period: 60s # 每个周期的时长,单位:微秒。默认为 500
|
||||||
|
timeout-duration: 1s # 被限流时,阻塞等待的时长,单位:微秒。默认为 5s
|
||||||
|
register-health-indicator: true # 是否注册到健康监测
|
||||||
|
|
||||||
|
--- #################### 监控相关配置 ####################
|
||||||
|
|
||||||
|
# Actuator 监控端点的配置项
|
||||||
|
management:
|
||||||
|
endpoints:
|
||||||
|
web:
|
||||||
|
base-path: /actuator # Actuator 提供的 API 接口的根目录。默认为 /actuator
|
||||||
|
exposure:
|
||||||
|
include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。
|
||||||
|
|
||||||
|
# Spring Boot Admin 配置项
|
||||||
|
spring:
|
||||||
|
boot:
|
||||||
|
admin:
|
||||||
|
# Spring Boot Admin Client 客户端的相关配置
|
||||||
|
client:
|
||||||
|
url: http://127.0.0.1:${server.port}/${spring.boot.admin.context-path} # 设置 Spring Boot Admin Server 地址
|
||||||
|
instance:
|
||||||
|
prefer-ip: true # 注册实例时,优先使用 IP
|
||||||
|
# Spring Boot Admin Server 服务端的相关配置
|
||||||
|
context-path: /admin # 配置 Spring
|
||||||
|
|
||||||
|
# 日志文件配置
|
||||||
|
logging:
|
||||||
|
file:
|
||||||
|
name: ${user.home}/logs/${spring.application.name}.log # 日志文件名,全路径
|
||||||
|
|
||||||
|
--- #################### 微信公众号相关配置 ####################
|
||||||
|
wx: # 参见 https://github.com/Wechat-Group/WxJava/blob/develop/spring-boot-starters/wx-java-mp-spring-boot-starter/README.md 文档
|
||||||
|
mp:
|
||||||
|
# 公众号配置(必填)
|
||||||
|
app-id: wx041349c6f39b268b
|
||||||
|
secret: 5abee519483bc9f8cb37ce280e814bd0
|
||||||
|
# 存储配置,解决 AccessToken 的跨节点的共享
|
||||||
|
config-storage:
|
||||||
|
type: RedisTemplate # 采用 RedisTemplate 操作 Redis,会自动从 Spring 中获取
|
||||||
|
key-prefix: wx # Redis Key 的前缀 TODO 芋艿:解决下 Redis key 管理的配置
|
||||||
|
http-client-type: HttpClient # 采用 HttpClient 请求微信公众号平台
|
||||||
|
|
||||||
|
--- #################### 芋道相关配置 ####################
|
||||||
|
|
||||||
|
# 芋道配置项,设置当前项目所有自定义的配置
|
||||||
|
yudao:
|
||||||
|
security:
|
||||||
|
token-header: Authorization
|
||||||
|
mock-enable: true
|
||||||
|
mock-secret: test
|
||||||
|
xss:
|
||||||
|
enable: false
|
||||||
|
exclude-urls: # 如下两个 url,仅仅是为了演示,去掉配置也没关系
|
||||||
|
- ${spring.boot.admin.context-path}/** # 不处理 Spring Boot Admin 的请求
|
||||||
|
- ${management.endpoints.web.base-path}/** # 不处理 Actuator 的请求
|
||||||
|
pay:
|
||||||
|
pay-notify-url: http://niubi.natapp1.cc/api/pay/order/notify
|
||||||
|
pay-return-url: http://niubi.natapp1.cc/api/pay/order/return
|
||||||
|
refund-notify-url: http://niubi.natapp1.cc/api/pay/refund/notify
|
||||||
|
demo: true # 开启演示模式
|
||||||
|
|
||||||
|
justauth:
|
||||||
|
enabled: true
|
||||||
|
type:
|
||||||
|
DINGTALK: # 钉钉
|
||||||
|
client-id: dingvrnreaje3yqvzhxg
|
||||||
|
client-secret: i8E6iZyDvZj51JIb0tYsYfVQYOks9Cq1lgryEjFRqC79P3iJcrxEwT6Qk2QvLrLI
|
||||||
|
ignore-check-redirect-uri: true
|
||||||
|
WECHAT_ENTERPRISE: # 企业微信
|
||||||
|
client-id: wwd411c69a39ad2e54
|
||||||
|
client-secret: 1wTb7hYxnpT2TUbIeHGXGo7T0odav1ic10mLdyyATOw
|
||||||
|
agent-id: 1000004
|
||||||
|
ignore-check-redirect-uri: true
|
||||||
|
cache:
|
||||||
|
type: REDIS
|
||||||
|
prefix: 'social_auth_state:' # 缓存前缀,目前只对 Redis 缓存生效,默认 JUSTAUTH::STATE::
|
||||||
|
timeout: 24h # 超时时长,目前只对 Redis 缓存生效,默认 3 分钟
|
|
@ -0,0 +1,220 @@
|
||||||
|
spring:
|
||||||
|
# 数据源配置项
|
||||||
|
autoconfigure:
|
||||||
|
exclude:
|
||||||
|
- com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure # 排除 Druid 的自动配置,使用 dynamic-datasource-spring-boot-starter 配置多数据源
|
||||||
|
datasource:
|
||||||
|
druid: # Druid 【监控】相关的全局配置
|
||||||
|
web-stat-filter:
|
||||||
|
enabled: true
|
||||||
|
stat-view-servlet:
|
||||||
|
enabled: true
|
||||||
|
allow: # 设置白名单,不填则允许所有访问
|
||||||
|
url-pattern: /druid/*
|
||||||
|
login-username: # 控制台管理用户名和密码
|
||||||
|
login-password:
|
||||||
|
filter:
|
||||||
|
stat:
|
||||||
|
enabled: true
|
||||||
|
log-slow-sql: true # 慢 SQL 记录
|
||||||
|
slow-sql-millis: 100
|
||||||
|
merge-sql: true
|
||||||
|
wall:
|
||||||
|
config:
|
||||||
|
multi-statement-allow: true
|
||||||
|
dynamic: # 多数据源配置
|
||||||
|
druid: # Druid 【连接池】相关的全局配置
|
||||||
|
initial-size: 5 # 初始连接数
|
||||||
|
min-idle: 10 # 最小连接池数量
|
||||||
|
max-active: 20 # 最大连接池数量
|
||||||
|
max-wait: 600000 # 配置获取连接等待超时的时间,单位:毫秒
|
||||||
|
time-between-eviction-runs-millis: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位:毫秒
|
||||||
|
min-evictable-idle-time-millis: 300000 # 配置一个连接在池中最小生存的时间,单位:毫秒
|
||||||
|
max-evictable-idle-time-millis: 900000 # 配置一个连接在池中最大生存的时间,单位:毫秒
|
||||||
|
validation-query: SELECT 1 FROM DUAL # 配置检测连接是否有效
|
||||||
|
test-while-idle: true
|
||||||
|
test-on-borrow: false
|
||||||
|
test-on-return: false
|
||||||
|
primary: master
|
||||||
|
datasource:
|
||||||
|
master:
|
||||||
|
name: ruoyi-vue-pro
|
||||||
|
url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.master.name}?allowMultiQueries=true&useUnicode=true&useSSL=false&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
|
||||||
|
# url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.master.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT # MySQL Connector/J 5.X 连接的示例
|
||||||
|
# url: jdbc:postgresql://127.0.0.1:5432/${spring.datasource.dynamic.datasource.slave.name} # PostgreSQL 连接的示例
|
||||||
|
# url: jdbc:oracle:thin:@127.0.0.1:1521:xe # Oracle 连接的示例
|
||||||
|
# url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=${spring.datasource.dynamic.datasource.master.name} # SQLServer 连接的示例
|
||||||
|
username: root
|
||||||
|
password: 123456
|
||||||
|
# username: sa
|
||||||
|
# password: JSm:g(*%lU4ZAkz06cd52KqT3)i1?H7W
|
||||||
|
slave: # 模拟从库,可根据自己需要修改
|
||||||
|
name: ruoyi-vue-pro
|
||||||
|
url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.slave.name}?allowMultiQueries=true&useUnicode=true&useSSL=false&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
|
||||||
|
# url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.slave.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT # MySQL Connector/J 5.X 连接的示例
|
||||||
|
# url: jdbc:postgresql://127.0.0.1:5432/${spring.datasource.dynamic.datasource.slave.name} # PostgreSQL 连接的示例
|
||||||
|
# url: jdbc:oracle:thin:@127.0.0.1:1521:xe # Oracle 连接的示例
|
||||||
|
# url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=${spring.datasource.dynamic.datasource.slave.name} # SQLServer 连接的示例
|
||||||
|
username: root
|
||||||
|
password: 123456
|
||||||
|
# username: sa
|
||||||
|
# password: JSm:g(*%lU4ZAkz06cd52KqT3)i1?H7W
|
||||||
|
|
||||||
|
# Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
|
||||||
|
redis:
|
||||||
|
host: 127.0.0.1 # 地址
|
||||||
|
port: 6379 # 端口
|
||||||
|
database: 0 # 数据库索引
|
||||||
|
# password: 123456 # 密码,建议生产环境开启
|
||||||
|
|
||||||
|
jasypt:
|
||||||
|
encryptor:
|
||||||
|
password: yuanma # 加解密的秘钥
|
||||||
|
|
||||||
|
--- #################### 定时任务相关配置 ####################
|
||||||
|
|
||||||
|
# Quartz 配置项,对应 QuartzProperties 配置类
|
||||||
|
spring:
|
||||||
|
quartz:
|
||||||
|
auto-startup: false # 本地开发环境,尽量不要开启 Job
|
||||||
|
scheduler-name: schedulerName # Scheduler 名字。默认为 schedulerName
|
||||||
|
job-store-type: jdbc # Job 存储器类型。默认为 memory 表示内存,可选 jdbc 使用数据库。
|
||||||
|
wait-for-jobs-to-complete-on-shutdown: true # 应用关闭时,是否等待定时任务执行完成。默认为 false ,建议设置为 true
|
||||||
|
properties: # 添加 Quartz Scheduler 附加属性,更多可以看 http://www.quartz-scheduler.org/documentation/2.4.0-SNAPSHOT/configuration.html 文档
|
||||||
|
org:
|
||||||
|
quartz:
|
||||||
|
# Scheduler 相关配置
|
||||||
|
scheduler:
|
||||||
|
instanceName: schedulerName
|
||||||
|
instanceId: AUTO # 自动生成 instance ID
|
||||||
|
# JobStore 相关配置
|
||||||
|
jobStore:
|
||||||
|
# JobStore 实现类。可见博客:https://blog.csdn.net/weixin_42458219/article/details/122247162
|
||||||
|
class: org.springframework.scheduling.quartz.LocalDataSourceJobStore
|
||||||
|
isClustered: true # 是集群模式
|
||||||
|
clusterCheckinInterval: 15000 # 集群检查频率,单位:毫秒。默认为 15000,即 15 秒
|
||||||
|
misfireThreshold: 60000 # misfire 阀值,单位:毫秒。
|
||||||
|
# 线程池相关配置
|
||||||
|
threadPool:
|
||||||
|
threadCount: 25 # 线程池大小。默认为 10 。
|
||||||
|
threadPriority: 5 # 线程优先级
|
||||||
|
class: org.quartz.simpl.SimpleThreadPool # 线程池类型
|
||||||
|
jdbc: # 使用 JDBC 的 JobStore 的时候,JDBC 的配置
|
||||||
|
initialize-schema: NEVER # 是否自动使用 SQL 初始化 Quartz 表结构。这里设置成 never ,我们手动创建表结构。
|
||||||
|
|
||||||
|
--- #################### 配置中心相关配置 ####################
|
||||||
|
|
||||||
|
# Apollo 配置中心
|
||||||
|
apollo:
|
||||||
|
bootstrap:
|
||||||
|
enabled: true # 设置 Apollo 在启动阶段生效
|
||||||
|
eagerLoad:
|
||||||
|
enabled: true # 设置 Apollo 在日志初始化前生效,可以实现日志的动态级别配置
|
||||||
|
jdbc: # 自定义的 JDBC 配置项,用于数据库的地址
|
||||||
|
dao: cn.iocoder.yudao.module.infra.dal.mysql.config.ConfigDAOImpl
|
||||||
|
url: ${spring.datasource.dynamic.datasource.master.url}
|
||||||
|
username: ${spring.datasource.dynamic.datasource.master.username}
|
||||||
|
password: ${spring.datasource.dynamic.datasource.master.password}
|
||||||
|
|
||||||
|
--- #################### 服务保障相关配置 ####################
|
||||||
|
|
||||||
|
# Lock4j 配置项
|
||||||
|
lock4j:
|
||||||
|
acquire-timeout: 3000 # 获取分布式锁超时时间,默认为 3000 毫秒
|
||||||
|
expire: 30000 # 分布式锁的超时时间,默认为 30 毫秒
|
||||||
|
|
||||||
|
# Resilience4j 配置项
|
||||||
|
resilience4j:
|
||||||
|
ratelimiter:
|
||||||
|
instances:
|
||||||
|
backendA:
|
||||||
|
limit-for-period: 1 # 每个周期内,允许的请求数。默认为 50
|
||||||
|
limit-refresh-period: 60s # 每个周期的时长,单位:微秒。默认为 500
|
||||||
|
timeout-duration: 1s # 被限流时,阻塞等待的时长,单位:微秒。默认为 5s
|
||||||
|
register-health-indicator: true # 是否注册到健康监测
|
||||||
|
|
||||||
|
--- #################### 监控相关配置 ####################
|
||||||
|
|
||||||
|
# Actuator 监控端点的配置项
|
||||||
|
management:
|
||||||
|
endpoints:
|
||||||
|
web:
|
||||||
|
base-path: /actuator # Actuator 提供的 API 接口的根目录。默认为 /actuator
|
||||||
|
exposure:
|
||||||
|
include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。
|
||||||
|
|
||||||
|
# Spring Boot Admin 配置项
|
||||||
|
spring:
|
||||||
|
boot:
|
||||||
|
admin:
|
||||||
|
# Spring Boot Admin Client 客户端的相关配置
|
||||||
|
client:
|
||||||
|
url: http://127.0.0.1:${server.port}/${spring.boot.admin.context-path} # 设置 Spring Boot Admin Server 地址
|
||||||
|
instance:
|
||||||
|
prefer-ip: true # 注册实例时,优先使用 IP
|
||||||
|
# Spring Boot Admin Server 服务端的相关配置
|
||||||
|
context-path: /admin # 配置 Spring
|
||||||
|
|
||||||
|
# 日志文件配置
|
||||||
|
logging:
|
||||||
|
file:
|
||||||
|
name: ${user.home}/logs/${spring.application.name}.log # 日志文件名,全路径
|
||||||
|
level:
|
||||||
|
# 配置自己写的 MyBatis Mapper 打印日志
|
||||||
|
cn.iocoder.yudao.module.bpm.dal.mysql: debug
|
||||||
|
cn.iocoder.yudao.module.infra.dal.mysql: debug
|
||||||
|
cn.iocoder.yudao.module.pay.dal.mysql: debug
|
||||||
|
cn.iocoder.yudao.module.system.dal.mysql: debug
|
||||||
|
cn.iocoder.yudao.module.tool.dal.mysql: debug
|
||||||
|
cn.iocoder.yudao.module.member.dal.mysql: debug
|
||||||
|
|
||||||
|
--- #################### 微信公众号相关配置 ####################
|
||||||
|
wx: # 参见 https://github.com/Wechat-Group/WxJava/blob/develop/spring-boot-starters/wx-java-mp-spring-boot-starter/README.md 文档
|
||||||
|
mp:
|
||||||
|
# 公众号配置(必填)
|
||||||
|
app-id: wx041349c6f39b268b
|
||||||
|
secret: 5abee519483bc9f8cb37ce280e814bd0
|
||||||
|
# 存储配置,解决 AccessToken 的跨节点的共享
|
||||||
|
config-storage:
|
||||||
|
type: RedisTemplate # 采用 RedisTemplate 操作 Redis,会自动从 Spring 中获取
|
||||||
|
key-prefix: wx # Redis Key 的前缀 TODO 芋艿:解决下 Redis key 管理的配置
|
||||||
|
http-client-type: HttpClient # 采用 HttpClient 请求微信公众号平台
|
||||||
|
|
||||||
|
--- #################### 芋道相关配置 ####################
|
||||||
|
|
||||||
|
# 芋道配置项,设置当前项目所有自定义的配置
|
||||||
|
yudao:
|
||||||
|
captcha:
|
||||||
|
enable: false # 本地环境,暂时关闭图片验证码,方便登录等接口的测试
|
||||||
|
security:
|
||||||
|
token-header: Authorization
|
||||||
|
mock-enable: true
|
||||||
|
mock-secret: test
|
||||||
|
xss:
|
||||||
|
enable: false
|
||||||
|
exclude-urls: # 如下两个 url,仅仅是为了演示,去掉配置也没关系
|
||||||
|
- ${spring.boot.admin.context-path}/** # 不处理 Spring Boot Admin 的请求
|
||||||
|
- ${management.endpoints.web.base-path}/** # 不处理 Actuator 的请求
|
||||||
|
pay:
|
||||||
|
pay-notify-url: http://niubi.natapp1.cc/api/pay/order/notify
|
||||||
|
pay-return-url: http://niubi.natapp1.cc/api/pay/order/return
|
||||||
|
refund-notify-url: http://niubi.natapp1.cc/api/pay/refund/notify
|
||||||
|
demo: false # 关闭演示模式
|
||||||
|
|
||||||
|
justauth:
|
||||||
|
enabled: true
|
||||||
|
type:
|
||||||
|
DINGTALK: # 钉钉
|
||||||
|
client-id: dingvrnreaje3yqvzhxg
|
||||||
|
client-secret: i8E6iZyDvZj51JIb0tYsYfVQYOks9Cq1lgryEjFRqC79P3iJcrxEwT6Qk2QvLrLI
|
||||||
|
ignore-check-redirect-uri: true
|
||||||
|
WECHAT_ENTERPRISE: # 企业微信
|
||||||
|
client-id: wwd411c69a39ad2e54
|
||||||
|
client-secret: 1wTb7hYxnpT2TUbIeHGXGo7T0odav1ic10mLdyyATOw
|
||||||
|
agent-id: 1000004
|
||||||
|
ignore-check-redirect-uri: true
|
||||||
|
cache:
|
||||||
|
type: REDIS
|
||||||
|
prefix: 'social_auth_state:' # 缓存前缀,目前只对 Redis 缓存生效,默认 JUSTAUTH::STATE::
|
||||||
|
timeout: 24h # 超时时长,目前只对 Redis 缓存生效,默认 3 分钟
|
||||||
|
|
|
@ -0,0 +1,146 @@
|
||||||
|
spring:
|
||||||
|
main:
|
||||||
|
allow-circular-references: true # 允许循环依赖,因为项目是三层架构,无法避免这个情况。
|
||||||
|
|
||||||
|
# Servlet 配置
|
||||||
|
servlet:
|
||||||
|
# 文件上传相关配置项
|
||||||
|
multipart:
|
||||||
|
max-file-size: 16MB # 单个文件大小
|
||||||
|
max-request-size: 32MB # 设置总上传的文件大小
|
||||||
|
mvc:
|
||||||
|
pathmatch:
|
||||||
|
matching-strategy: ANT_PATH_MATCHER # 解决 SpringFox 与 SpringBoot 2.6.x 不兼容的问题,参见 SpringFoxHandlerProviderBeanPostProcessor 类
|
||||||
|
|
||||||
|
# Jackson 配置项
|
||||||
|
jackson:
|
||||||
|
serialization:
|
||||||
|
write-dates-as-timestamps: true # 设置 Date 的格式,使用时间戳
|
||||||
|
write-date-timestamps-as-nanoseconds: false # 设置不使用 nanoseconds 的格式。例如说 1611460870.401,而是直接 1611460870401
|
||||||
|
write-durations-as-timestamps: true # 设置 Duration 的格式,使用时间戳
|
||||||
|
fail-on-empty-beans: false # 允许序列化无属性的 Bean
|
||||||
|
|
||||||
|
# Cache 配置项
|
||||||
|
cache:
|
||||||
|
type: REDIS
|
||||||
|
redis:
|
||||||
|
time-to-live: 1h # 设置过期时间为 1 小时
|
||||||
|
|
||||||
|
# 工作流 Activiti 配置
|
||||||
|
activiti:
|
||||||
|
# 1. false: 默认值,activiti启动时,对比数据库表中保存的版本,如果不匹配。将抛出异常
|
||||||
|
# 2. true: 启动时会对数据库中所有表进行更新操作,如果表存在,不做处理,反之,自动创建表
|
||||||
|
# 3. create_drop: 启动时自动创建表,关闭时自动删除表
|
||||||
|
# 4. drop_create: 启动时,删除旧表,再创建新表
|
||||||
|
database-schema-update: true # 设置为 false,可通过 sql/activiti.sql 初始化
|
||||||
|
db-history-used: true # activiti7 默认 false 不生成历史信息表,需手动设置开启
|
||||||
|
check-process-definitions: false # 设置为 false,禁用 /resources/processes 自动部署 BPMN XML 流程
|
||||||
|
history-level: full # full:保存历史数据的最高级别,可保存全部流程相关细节,包括流程流转各节点参数
|
||||||
|
|
||||||
|
# 工作流 Flowable 配置
|
||||||
|
flowable:
|
||||||
|
# 1. false: 默认值,Flowable 启动时,对比数据库表中保存的版本,如果不匹配。将抛出异常
|
||||||
|
# 2. true: 启动时会对数据库中所有表进行更新操作,如果表存在,不做处理,反之,自动创建表
|
||||||
|
# 3. create_drop: 启动时自动创建表,关闭时自动删除表
|
||||||
|
# 4. drop_create: 启动时,删除旧表,再创建新表
|
||||||
|
database-schema-update: true # 设置为 false,可通过 https://github.com/flowable/flowable-sql 初始化
|
||||||
|
db-history-used: true # flowable6 默认 true 生成信息表,无需手动设置
|
||||||
|
check-process-definitions: false # 设置为 false,禁用 /resources/processes 自动部署 BPMN XML 流程
|
||||||
|
history-level: full # full:保存历史数据的最高级别,可保存全部流程相关细节,包括流程流转各节点参数
|
||||||
|
|
||||||
|
# MyBatis Plus 的配置项
|
||||||
|
mybatis-plus:
|
||||||
|
configuration:
|
||||||
|
map-underscore-to-camel-case: true # 虽然默认为 true ,但是还是显示去指定下。
|
||||||
|
global-config:
|
||||||
|
db-config:
|
||||||
|
id-type: NONE # “智能”模式,基于 IdTypeEnvironmentPostProcessor + 数据源的类型,自动适配成 AUTO、INPUT 模式。
|
||||||
|
# id-type: AUTO # 自增 ID,适合 MySQL 等直接自增的数据库
|
||||||
|
# id-type: INPUT # 用户输入 ID,适合 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库
|
||||||
|
# id-type: ASSIGN_ID # 分配 ID,默认使用雪花算法。注意,Oracle、PostgreSQL、Kingbase、DB2、H2 数据库时,需要去除实体类上的 @KeySequence 注解
|
||||||
|
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
|
||||||
|
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
|
||||||
|
type-aliases-package: ${yudao.info.base-package}.dal.dataobject
|
||||||
|
|
||||||
|
--- #################### RPC 远程调用相关配置 ####################
|
||||||
|
dubbo:
|
||||||
|
scan:
|
||||||
|
base-packages: ${yudao.info.base-package}.api # 指定 Dubbo 服务实现类的扫描基准包
|
||||||
|
protocol:
|
||||||
|
name: dubbo # 协议名称
|
||||||
|
port: -1 # 协议端口,-1 表示自增端口,从 20880 开始
|
||||||
|
registry:
|
||||||
|
address: spring-cloud://localhost # 设置使用 Spring Cloud 注册中心
|
||||||
|
|
||||||
|
--- #################### 芋道相关配置 ####################
|
||||||
|
|
||||||
|
yudao:
|
||||||
|
info:
|
||||||
|
version: 1.0.0
|
||||||
|
base-package: cn.iocoder.yudao.module.infra
|
||||||
|
web:
|
||||||
|
admin-api:
|
||||||
|
prefix: /admin-api
|
||||||
|
controller: '**.controller.admin.**'
|
||||||
|
app-api:
|
||||||
|
prefix: /app-api
|
||||||
|
controller: '**.controller.app.**'
|
||||||
|
admin-ui:
|
||||||
|
url: http://dashboard.yudao.iocoder.cn # Admin 管理后台 UI 的地址
|
||||||
|
swagger:
|
||||||
|
title: 管理后台
|
||||||
|
description: 提供管理员管理的所有功能
|
||||||
|
version: ${yudao.info.version}
|
||||||
|
base-package: ${yudao.info.base-package}
|
||||||
|
captcha:
|
||||||
|
timeout: 5m
|
||||||
|
width: 160
|
||||||
|
height: 60
|
||||||
|
codegen:
|
||||||
|
base-package: ${yudao.info.base-package}
|
||||||
|
db-schemas: ${spring.datasource.dynamic.datasource.master.name}
|
||||||
|
error-code: # 错误码相关配置项
|
||||||
|
constants-class-list:
|
||||||
|
- cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants
|
||||||
|
- cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants
|
||||||
|
- cn.iocoder.yudao.module.member.enums.ErrorCodeConstants
|
||||||
|
- cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants
|
||||||
|
- cn.iocoder.yudao.module.system.enums.ErrorCodeConstants
|
||||||
|
tenant: # 多租户相关配置项
|
||||||
|
enable: true
|
||||||
|
ignore-urls:
|
||||||
|
- /admin-api/system/tenant/get-id-by-name # 基于名字获取租户,不许带租户编号
|
||||||
|
- /admin-api/system/captcha/get-image # 获取图片验证码,和租户无关
|
||||||
|
- /admin-api/infra/file/*/get/** # 获取图片,和租户无关
|
||||||
|
- /admin-api/system/sms/callback/* # 短信回调接口,无法带上租户编号
|
||||||
|
ignore-tables:
|
||||||
|
- system_tenant
|
||||||
|
- system_tenant_package
|
||||||
|
- system_dict_data
|
||||||
|
- system_dict_type
|
||||||
|
- system_error_code
|
||||||
|
- system_menu
|
||||||
|
- system_sms_channel
|
||||||
|
- system_sms_template
|
||||||
|
- system_sms_log
|
||||||
|
- system_sensitive_word
|
||||||
|
- system_oauth2_client
|
||||||
|
- infra_codegen_column
|
||||||
|
- infra_codegen_table
|
||||||
|
- infra_test_demo
|
||||||
|
- infra_config
|
||||||
|
- infra_file_config
|
||||||
|
- infra_file
|
||||||
|
- infra_file_content
|
||||||
|
- infra_job
|
||||||
|
- infra_job_log
|
||||||
|
- infra_job_log
|
||||||
|
- infra_data_source_config
|
||||||
|
sms-code: # 短信验证码相关的配置项
|
||||||
|
expire-times: 10m
|
||||||
|
send-frequency: 1m
|
||||||
|
send-maximum-quantity-per-day: 10
|
||||||
|
begin-code: 9999 # 这里配置 9999 的原因是,测试方便。
|
||||||
|
end-code: 9999 # 这里配置 9999 的原因是,测试方便。
|
||||||
|
|
||||||
|
debug: false
|
|
@ -0,0 +1,17 @@
|
||||||
|
芋道源码 http://www.iocoder.cn
|
||||||
|
Application Version: ${yudao.info.version}
|
||||||
|
Spring Boot Version: ${spring-boot.version}
|
||||||
|
|
||||||
|
.__ __. ______ .______ __ __ _______
|
||||||
|
| \ | | / __ \ | _ \ | | | | / _____|
|
||||||
|
| \| | | | | | | |_) | | | | | | | __
|
||||||
|
| . ` | | | | | | _ < | | | | | | |_ |
|
||||||
|
| |\ | | `--' | | |_) | | `--' | | |__| |
|
||||||
|
|__| \__| \______/ |______/ \______/ \______|
|
||||||
|
|
||||||
|
███╗ ██╗ ██████╗ ██████╗ ██╗ ██╗ ██████╗
|
||||||
|
████╗ ██║██╔═══██╗ ██╔══██╗██║ ██║██╔════╝
|
||||||
|
██╔██╗ ██║██║ ██║ ██████╔╝██║ ██║██║ ███╗
|
||||||
|
██║╚██╗██║██║ ██║ ██╔══██╗██║ ██║██║ ██║
|
||||||
|
██║ ╚████║╚██████╔╝ ██████╔╝╚██████╔╝╚██████╔╝
|
||||||
|
╚═╝ ╚═══╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚═════╝
|
|
@ -0,0 +1,23 @@
|
||||||
|
--- #################### 注册中心相关配置 ####################
|
||||||
|
|
||||||
|
spring:
|
||||||
|
cloud:
|
||||||
|
nacos:
|
||||||
|
server-addr: 127.0.0.1:8848
|
||||||
|
discovery:
|
||||||
|
namespace: dev # 命名空间。这里使用 dev 开发环境
|
||||||
|
metadata:
|
||||||
|
version: 1.0.0 # 服务实例的版本号,可用于灰度发布
|
||||||
|
|
||||||
|
--- #################### 配置中心相关配置 ####################
|
||||||
|
|
||||||
|
spring:
|
||||||
|
cloud:
|
||||||
|
nacos:
|
||||||
|
# Nacos Config 配置项,对应 NacosConfigProperties 配置属性类
|
||||||
|
config:
|
||||||
|
server-addr: 127.0.0.1:8848 # Nacos 服务器地址
|
||||||
|
namespace: dev # 命名空间。这里使用 dev 开发环境
|
||||||
|
group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP
|
||||||
|
name: # 使用的 Nacos 配置集的 dataId,默认为 spring.application.name
|
||||||
|
file-extension: yaml # 使用的 Nacos 配置集的 dataId 的文件拓展名,同时也是 Nacos 配置集的配置格式,默认为 properties
|
|
@ -0,0 +1,16 @@
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: infra-server
|
||||||
|
|
||||||
|
profiles:
|
||||||
|
active: local
|
||||||
|
|
||||||
|
server:
|
||||||
|
port: 48082
|
||||||
|
|
||||||
|
|
||||||
|
yudao:
|
||||||
|
security: # TODO 芋艿,发现一定要配置,需要找下原因
|
||||||
|
token-header: Authorization
|
||||||
|
mock-enable: true
|
||||||
|
mock-secret: test
|
|
@ -0,0 +1,76 @@
|
||||||
|
<configuration>
|
||||||
|
<!-- 引用 Spring Boot 的 logback 基础配置 -->
|
||||||
|
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
|
||||||
|
<!-- 变量 yudao.info.base-package,基础业务包 -->
|
||||||
|
<springProperty scope="context" name="yudao.info.base-package" source="yudao.info.base-package"/>
|
||||||
|
<!-- 格式化输出:%d 表示日期,%X{tid} SkWalking 链路追踪编号,%thread 表示线程名,%-5level:级别从左显示 5 个字符宽度,%msg:日志消息,%n是换行符 -->
|
||||||
|
<property name="PATTERN_DEFAULT" value="%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} ${LOG_LEVEL_PATTERN:-%5p} ${PID:- } --- [%thread] [%tid] %-40.40logger{39} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>
|
||||||
|
|
||||||
|
<!-- 控制台 Appender -->
|
||||||
|
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
|
||||||
|
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
|
||||||
|
<pattern>${PATTERN_DEFAULT}</pattern>
|
||||||
|
</layout>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<!-- 文件 Appender -->
|
||||||
|
<!-- 参考 Spring Boot 的 file-appender.xml 编写 -->
|
||||||
|
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||||
|
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
|
||||||
|
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
|
||||||
|
<pattern>${PATTERN_DEFAULT}</pattern>
|
||||||
|
</layout>
|
||||||
|
</encoder>
|
||||||
|
<!-- 日志文件名 -->
|
||||||
|
<file>${LOG_FILE}</file>
|
||||||
|
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||||
|
<!-- 滚动后的日志文件名 -->
|
||||||
|
<fileNamePattern>${LOGBACK_ROLLINGPOLICY_FILE_NAME_PATTERN:-${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz}</fileNamePattern>
|
||||||
|
<!-- 启动服务时,是否清理历史日志,一般不建议清理 -->
|
||||||
|
<cleanHistoryOnStart>${LOGBACK_ROLLINGPOLICY_CLEAN_HISTORY_ON_START:-false}</cleanHistoryOnStart>
|
||||||
|
<!-- 日志文件,到达多少容量,进行滚动 -->
|
||||||
|
<maxFileSize>${LOGBACK_ROLLINGPOLICY_MAX_FILE_SIZE:-10MB}</maxFileSize>
|
||||||
|
<!-- 日志文件的总大小,0 表示不限制 -->
|
||||||
|
<totalSizeCap>${LOGBACK_ROLLINGPOLICY_TOTAL_SIZE_CAP:-0}</totalSizeCap>
|
||||||
|
<!-- 日志文件的保留天数 -->
|
||||||
|
<maxHistory>${LOGBACK_ROLLINGPOLICY_MAX_HISTORY:-30}</maxHistory>
|
||||||
|
</rollingPolicy>
|
||||||
|
</appender>
|
||||||
|
<!-- 异步写入日志,提升性能 -->
|
||||||
|
<appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
|
||||||
|
<!-- 不丢失日志。默认的,如果队列的 80% 已满,则会丢弃 TRACT、DEBUG、INFO 级别的日志 -->
|
||||||
|
<discardingThreshold>0</discardingThreshold>
|
||||||
|
<!-- 更改默认的队列的深度,该值会影响性能。默认值为 256 -->
|
||||||
|
<queueSize>256</queueSize>
|
||||||
|
<appender-ref ref="FILE"/>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<!-- SkyWalking GRPC 日志收集,实现日志中心。注意:SkyWalking 8.4.0 版本开始支持 -->
|
||||||
|
<appender name="GRPC" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender">
|
||||||
|
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
|
||||||
|
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
|
||||||
|
<pattern>${PATTERN_DEFAULT}</pattern>
|
||||||
|
</layout>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<!-- 本地环境 -->
|
||||||
|
<springProfile name="local">
|
||||||
|
<root level="INFO">
|
||||||
|
<appender-ref ref="STDOUT"/>
|
||||||
|
<appender-ref ref="GRPC"/> <!-- 本地环境下,如果不想接入 SkyWalking 日志服务,可以注释掉本行 -->
|
||||||
|
<appender-ref ref="ASYNC"/> <!-- 本地环境下,如果不想打印日志,可以注释掉本行 -->
|
||||||
|
</root>
|
||||||
|
</springProfile>
|
||||||
|
<!-- 其它环境 -->
|
||||||
|
<springProfile name="dev,default">
|
||||||
|
<root level="INFO">
|
||||||
|
<appender-ref ref="STDOUT"/>
|
||||||
|
<appender-ref ref="ASYNC"/>
|
||||||
|
<appender-ref ref="GRPC"/>
|
||||||
|
</root>
|
||||||
|
</springProfile>
|
||||||
|
|
||||||
|
</configuration>
|
|
@ -1,252 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.infra.service.config;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|
||||||
import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils;
|
|
||||||
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
|
|
||||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
|
||||||
import cn.iocoder.yudao.framework.test.core.util.RandomUtils;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.config.vo.ConfigCreateReqVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.config.vo.ConfigExportReqVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.config.vo.ConfigPageReqVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.config.vo.ConfigUpdateReqVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.config.ConfigDO;
|
|
||||||
import cn.iocoder.yudao.module.infra.dal.mysql.config.ConfigMapper;
|
|
||||||
import cn.iocoder.yudao.module.infra.enums.config.ConfigTypeEnum;
|
|
||||||
import cn.iocoder.yudao.module.infra.mq.producer.config.ConfigProducer;
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
|
||||||
import org.springframework.context.annotation.Import;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
import static cn.hutool.core.util.RandomUtil.randomEle;
|
|
||||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.buildTime;
|
|
||||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
|
||||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
|
||||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
|
|
||||||
import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.*;
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
|
||||||
import static org.mockito.Mockito.times;
|
|
||||||
import static org.mockito.Mockito.verify;
|
|
||||||
|
|
||||||
@Import(ConfigServiceImpl.class)
|
|
||||||
public class ConfigServiceTest extends BaseDbUnitTest {
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private ConfigServiceImpl configService;
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private ConfigMapper configMapper;
|
|
||||||
@MockBean
|
|
||||||
private ConfigProducer configProducer;
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCreateConfig_success() {
|
|
||||||
// 准备参数
|
|
||||||
ConfigCreateReqVO reqVO = randomPojo(ConfigCreateReqVO.class);
|
|
||||||
|
|
||||||
// 调用
|
|
||||||
Long configId = configService.createConfig(reqVO);
|
|
||||||
// 断言
|
|
||||||
assertNotNull(configId);
|
|
||||||
// 校验记录的属性是否正确
|
|
||||||
ConfigDO config = configMapper.selectById(configId);
|
|
||||||
assertPojoEquals(reqVO, config);
|
|
||||||
Assertions.assertEquals(ConfigTypeEnum.CUSTOM.getType(), config.getType());
|
|
||||||
// 校验调用
|
|
||||||
verify(configProducer, times(1)).sendConfigRefreshMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUpdateConfig_success() {
|
|
||||||
// mock 数据
|
|
||||||
ConfigDO dbConfig = randomConfigDO();
|
|
||||||
configMapper.insert(dbConfig);// @Sql: 先插入出一条存在的数据
|
|
||||||
// 准备参数
|
|
||||||
ConfigUpdateReqVO reqVO = randomPojo(ConfigUpdateReqVO.class, o -> {
|
|
||||||
o.setId(dbConfig.getId()); // 设置更新的 ID
|
|
||||||
});
|
|
||||||
|
|
||||||
// 调用
|
|
||||||
configService.updateConfig(reqVO);
|
|
||||||
// 校验是否更新正确
|
|
||||||
ConfigDO config = configMapper.selectById(reqVO.getId()); // 获取最新的
|
|
||||||
assertPojoEquals(reqVO, config);
|
|
||||||
// 校验调用
|
|
||||||
verify(configProducer, times(1)).sendConfigRefreshMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDeleteConfig_success() {
|
|
||||||
// mock 数据
|
|
||||||
ConfigDO dbConfig = randomConfigDO(o -> {
|
|
||||||
o.setType(ConfigTypeEnum.CUSTOM.getType()); // 只能删除 CUSTOM 类型
|
|
||||||
});
|
|
||||||
configMapper.insert(dbConfig);// @Sql: 先插入出一条存在的数据
|
|
||||||
// 准备参数
|
|
||||||
Long id = dbConfig.getId();
|
|
||||||
|
|
||||||
// 调用
|
|
||||||
configService.deleteConfig(id);
|
|
||||||
// 校验数据不存在了
|
|
||||||
assertNull(configMapper.selectById(id));
|
|
||||||
// 校验调用
|
|
||||||
verify(configProducer, times(1)).sendConfigRefreshMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDeleteConfig_canNotDeleteSystemType() {
|
|
||||||
// mock 数据
|
|
||||||
ConfigDO dbConfig = randomConfigDO(o -> {
|
|
||||||
o.setType(ConfigTypeEnum.SYSTEM.getType()); // SYSTEM 不允许删除
|
|
||||||
});
|
|
||||||
configMapper.insert(dbConfig);// @Sql: 先插入出一条存在的数据
|
|
||||||
// 准备参数
|
|
||||||
Long id = dbConfig.getId();
|
|
||||||
|
|
||||||
// 调用, 并断言异常
|
|
||||||
assertServiceException(() -> configService.deleteConfig(id), CONFIG_CAN_NOT_DELETE_SYSTEM_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCheckConfigExists_success() {
|
|
||||||
// mock 数据
|
|
||||||
ConfigDO dbConfigDO = randomConfigDO();
|
|
||||||
configMapper.insert(dbConfigDO);// @Sql: 先插入出一条存在的数据
|
|
||||||
|
|
||||||
// 调用成功
|
|
||||||
configService.checkConfigExists(dbConfigDO.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCheckConfigExist_notExists() {
|
|
||||||
assertServiceException(() -> configService.checkConfigExists(randomLongId()), CONFIG_NOT_EXISTS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCheckConfigKeyUnique_success() {
|
|
||||||
// 调用,成功
|
|
||||||
configService.checkConfigKeyUnique(randomLongId(), randomString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCheckConfigKeyUnique_keyDuplicateForCreate() {
|
|
||||||
// 准备参数
|
|
||||||
String key = randomString();
|
|
||||||
// mock 数据
|
|
||||||
configMapper.insert(randomConfigDO(o -> o.setConfigKey(key)));
|
|
||||||
|
|
||||||
// 调用,校验异常
|
|
||||||
assertServiceException(() -> configService.checkConfigKeyUnique(null, key),
|
|
||||||
CONFIG_KEY_DUPLICATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCheckConfigKeyUnique_keyDuplicateForUpdate() {
|
|
||||||
// 准备参数
|
|
||||||
Long id = randomLongId();
|
|
||||||
String key = randomString();
|
|
||||||
// mock 数据
|
|
||||||
configMapper.insert(randomConfigDO(o -> o.setConfigKey(key)));
|
|
||||||
|
|
||||||
// 调用,校验异常
|
|
||||||
assertServiceException(() -> configService.checkConfigKeyUnique(id, key),
|
|
||||||
CONFIG_KEY_DUPLICATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetConfigPage() {
|
|
||||||
// mock 数据
|
|
||||||
ConfigDO dbConfig = randomConfigDO(o -> { // 等会查询到
|
|
||||||
o.setName("芋艿");
|
|
||||||
o.setConfigKey("yunai");
|
|
||||||
o.setType(ConfigTypeEnum.SYSTEM.getType());
|
|
||||||
o.setCreateTime(buildTime(2021, 2, 1));
|
|
||||||
});
|
|
||||||
configMapper.insert(dbConfig);
|
|
||||||
// 测试 name 不匹配
|
|
||||||
configMapper.insert(ObjectUtils.cloneIgnoreId(dbConfig, o -> o.setName("土豆")));
|
|
||||||
// 测试 key 不匹配
|
|
||||||
configMapper.insert(ObjectUtils.cloneIgnoreId(dbConfig, o -> o.setConfigKey("tudou")));
|
|
||||||
// 测试 type 不匹配
|
|
||||||
configMapper.insert(ObjectUtils.cloneIgnoreId(dbConfig, o -> o.setType(ConfigTypeEnum.CUSTOM.getType())));
|
|
||||||
// 测试 createTime 不匹配
|
|
||||||
configMapper.insert(ObjectUtils.cloneIgnoreId(dbConfig, o -> o.setCreateTime(buildTime(2021, 1, 1))));
|
|
||||||
// 准备参数
|
|
||||||
ConfigPageReqVO reqVO = new ConfigPageReqVO();
|
|
||||||
reqVO.setName("艿");
|
|
||||||
reqVO.setKey("nai");
|
|
||||||
reqVO.setType(ConfigTypeEnum.SYSTEM.getType());
|
|
||||||
reqVO.setBeginTime(buildTime(2021, 1, 15));
|
|
||||||
reqVO.setEndTime(buildTime(2021, 2, 15));
|
|
||||||
|
|
||||||
// 调用
|
|
||||||
PageResult<ConfigDO> pageResult = configService.getConfigPage(reqVO);
|
|
||||||
// 断言
|
|
||||||
assertEquals(1, pageResult.getTotal());
|
|
||||||
assertEquals(1, pageResult.getList().size());
|
|
||||||
assertPojoEquals(dbConfig, pageResult.getList().get(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetConfigList() {
|
|
||||||
// mock 数据
|
|
||||||
ConfigDO dbConfig = randomConfigDO(o -> { // 等会查询到
|
|
||||||
o.setName("芋艿");
|
|
||||||
o.setConfigKey("yunai");
|
|
||||||
o.setType(ConfigTypeEnum.SYSTEM.getType());
|
|
||||||
o.setCreateTime(buildTime(2021, 2, 1));
|
|
||||||
});
|
|
||||||
configMapper.insert(dbConfig);
|
|
||||||
// 测试 name 不匹配
|
|
||||||
configMapper.insert(ObjectUtils.cloneIgnoreId(dbConfig, o -> o.setName("土豆")));
|
|
||||||
// 测试 key 不匹配
|
|
||||||
configMapper.insert(ObjectUtils.cloneIgnoreId(dbConfig, o -> o.setConfigKey("tudou")));
|
|
||||||
// 测试 type 不匹配
|
|
||||||
configMapper.insert(ObjectUtils.cloneIgnoreId(dbConfig, o -> o.setType(ConfigTypeEnum.CUSTOM.getType())));
|
|
||||||
// 测试 createTime 不匹配
|
|
||||||
configMapper.insert(ObjectUtils.cloneIgnoreId(dbConfig, o -> o.setCreateTime(buildTime(2021, 1, 1))));
|
|
||||||
// 准备参数
|
|
||||||
ConfigExportReqVO reqVO = new ConfigExportReqVO();
|
|
||||||
reqVO.setName("艿");
|
|
||||||
reqVO.setKey("nai");
|
|
||||||
reqVO.setType(ConfigTypeEnum.SYSTEM.getType());
|
|
||||||
reqVO.setBeginTime(buildTime(2021, 1, 15));
|
|
||||||
reqVO.setEndTime(buildTime(2021, 2, 15));
|
|
||||||
|
|
||||||
// 调用
|
|
||||||
List<ConfigDO> list = configService.getConfigList(reqVO);
|
|
||||||
// 断言
|
|
||||||
assertEquals(1, list.size());
|
|
||||||
assertPojoEquals(dbConfig, list.get(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetConfigByKey() {
|
|
||||||
// mock 数据
|
|
||||||
ConfigDO dbConfig = randomConfigDO();
|
|
||||||
configMapper.insert(dbConfig);// @Sql: 先插入出一条存在的数据
|
|
||||||
// 准备参数
|
|
||||||
String key = dbConfig.getConfigKey();
|
|
||||||
|
|
||||||
// 调用
|
|
||||||
ConfigDO config = configService.getConfigByKey(key);
|
|
||||||
// 断言
|
|
||||||
assertNotNull(config);
|
|
||||||
assertPojoEquals(dbConfig, config);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ========== 随机对象 ==========
|
|
||||||
|
|
||||||
@SafeVarargs
|
|
||||||
private static ConfigDO randomConfigDO(Consumer<ConfigDO>... consumers) {
|
|
||||||
Consumer<ConfigDO> consumer = (o) -> {
|
|
||||||
o.setType(randomEle(ConfigTypeEnum.values()).getType()); // 保证 key 的范围
|
|
||||||
};
|
|
||||||
return RandomUtils.randomPojo(ConfigDO.class, ArrayUtils.append(consumer, consumers));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,163 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.infra.service.job;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|
||||||
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
|
|
||||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.job.vo.log.JobLogExportReqVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.job.vo.log.JobLogPageReqVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.job.JobLogDO;
|
|
||||||
import cn.iocoder.yudao.module.infra.dal.mysql.job.JobLogMapper;
|
|
||||||
import cn.iocoder.yudao.module.infra.enums.job.JobLogStatusEnum;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.springframework.context.annotation.Import;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static cn.hutool.core.util.RandomUtil.randomEle;
|
|
||||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.buildTime;
|
|
||||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
|
||||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
|
||||||
|
|
||||||
@Import(JobLogServiceImpl.class)
|
|
||||||
public class JobLogServiceTest extends BaseDbUnitTest {
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private JobLogServiceImpl jobLogService;
|
|
||||||
@Resource
|
|
||||||
private JobLogMapper jobLogMapper;
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCreateJobLog_success() {
|
|
||||||
// 准备参数
|
|
||||||
JobLogDO reqVO = randomPojo(JobLogDO.class, o -> {
|
|
||||||
o.setExecuteIndex(1);
|
|
||||||
});
|
|
||||||
// 调用
|
|
||||||
Long jobLogId = jobLogService.createJobLog(reqVO.getJobId(), reqVO.getBeginTime(), reqVO.getHandlerName(), reqVO.getHandlerParam(), reqVO.getExecuteIndex());
|
|
||||||
// 断言
|
|
||||||
assertNotNull(jobLogId);
|
|
||||||
// 校验记录的属性是否正确
|
|
||||||
JobLogDO job = jobLogMapper.selectById(jobLogId);
|
|
||||||
assertEquals(JobLogStatusEnum.RUNNING.getStatus(), job.getStatus());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUpdateJobLogResultAsync_success() {
|
|
||||||
// 准备参数
|
|
||||||
JobLogDO reqVO = randomPojo(JobLogDO.class, o -> {
|
|
||||||
o.setExecuteIndex(1);
|
|
||||||
});
|
|
||||||
JobLogDO log = JobLogDO.builder().jobId(reqVO.getJobId()).handlerName(reqVO.getHandlerName()).handlerParam(reqVO.getHandlerParam()).executeIndex(reqVO.getExecuteIndex())
|
|
||||||
.beginTime(reqVO.getBeginTime()).status(JobLogStatusEnum.RUNNING.getStatus()).build();
|
|
||||||
jobLogMapper.insert(log);
|
|
||||||
// 调用
|
|
||||||
jobLogService.updateJobLogResultAsync(log.getId(), reqVO.getBeginTime(), reqVO.getDuration(), true,reqVO.getResult());
|
|
||||||
// 校验记录的属性是否正确
|
|
||||||
JobLogDO job = jobLogMapper.selectById(log.getId());
|
|
||||||
assertEquals(JobLogStatusEnum.SUCCESS.getStatus(), job.getStatus());
|
|
||||||
|
|
||||||
// 调用
|
|
||||||
jobLogService.updateJobLogResultAsync(log.getId(), reqVO.getBeginTime(), reqVO.getDuration(), false,reqVO.getResult());
|
|
||||||
// 校验记录的属性是否正确
|
|
||||||
JobLogDO job2 = jobLogMapper.selectById(log.getId());
|
|
||||||
assertEquals(JobLogStatusEnum.FAILURE.getStatus(), job2.getStatus());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetJobLogListByIds_success() {
|
|
||||||
// mock 数据
|
|
||||||
JobLogDO dbJobLog = randomPojo(JobLogDO.class, o -> {
|
|
||||||
o.setExecuteIndex(1);
|
|
||||||
o.setStatus(randomEle(JobLogStatusEnum.values()).getStatus()); // 保证 status 的范围
|
|
||||||
});
|
|
||||||
JobLogDO cloneJobLog = ObjectUtils.cloneIgnoreId(dbJobLog, o -> o.setHandlerName(randomString()));
|
|
||||||
jobLogMapper.insert(dbJobLog);
|
|
||||||
// 测试 handlerName 不匹配
|
|
||||||
jobLogMapper.insert(cloneJobLog);
|
|
||||||
// 准备参数
|
|
||||||
ArrayList ids = new ArrayList<>();
|
|
||||||
ids.add(dbJobLog.getId());
|
|
||||||
ids.add(cloneJobLog.getId());
|
|
||||||
// 调用
|
|
||||||
List<JobLogDO> list = jobLogService.getJobLogList(ids);
|
|
||||||
// 断言
|
|
||||||
assertEquals(2, list.size());
|
|
||||||
assertPojoEquals(dbJobLog, list.get(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetJobPage_success() {
|
|
||||||
// mock 数据
|
|
||||||
JobLogDO dbJobLog = randomPojo(JobLogDO.class, o -> {
|
|
||||||
o.setExecuteIndex(1);
|
|
||||||
o.setHandlerName("handlerName 单元测试");
|
|
||||||
o.setStatus(JobLogStatusEnum.SUCCESS.getStatus());
|
|
||||||
o.setBeginTime(buildTime(2021, 1, 8));
|
|
||||||
o.setEndTime(buildTime(2021, 1, 8));
|
|
||||||
});
|
|
||||||
jobLogMapper.insert(dbJobLog);
|
|
||||||
// 测试 jobId 不匹配
|
|
||||||
jobLogMapper.insert(ObjectUtils.cloneIgnoreId(dbJobLog, o -> o.setJobId(randomLongId())));
|
|
||||||
// 测试 handlerName 不匹配
|
|
||||||
jobLogMapper.insert(ObjectUtils.cloneIgnoreId(dbJobLog, o -> o.setHandlerName(randomString())));
|
|
||||||
// 测试 beginTime 不匹配
|
|
||||||
jobLogMapper.insert(ObjectUtils.cloneIgnoreId(dbJobLog, o -> o.setBeginTime(buildTime(2021, 1, 7))));
|
|
||||||
// 测试 endTime 不匹配
|
|
||||||
jobLogMapper.insert(ObjectUtils.cloneIgnoreId(dbJobLog, o -> o.setEndTime(buildTime(2021, 1, 9))));
|
|
||||||
// 测试 status 不匹配
|
|
||||||
jobLogMapper.insert(ObjectUtils.cloneIgnoreId(dbJobLog, o -> o.setStatus(JobLogStatusEnum.FAILURE.getStatus())));
|
|
||||||
// 准备参数
|
|
||||||
JobLogPageReqVO reqVo = new JobLogPageReqVO();
|
|
||||||
reqVo.setJobId(dbJobLog.getJobId());
|
|
||||||
reqVo.setHandlerName("单元");
|
|
||||||
reqVo.setBeginTime(dbJobLog.getBeginTime());
|
|
||||||
reqVo.setEndTime(dbJobLog.getEndTime());
|
|
||||||
reqVo.setStatus(JobLogStatusEnum.SUCCESS.getStatus());
|
|
||||||
// 调用
|
|
||||||
PageResult<JobLogDO> pageResult = jobLogService.getJobLogPage(reqVo);
|
|
||||||
// 断言
|
|
||||||
assertEquals(1, pageResult.getTotal());
|
|
||||||
assertEquals(1, pageResult.getList().size());
|
|
||||||
assertPojoEquals(dbJobLog, pageResult.getList().get(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetJobListForExport_success() {
|
|
||||||
// mock 数据
|
|
||||||
JobLogDO dbJobLog = randomPojo(JobLogDO.class, o -> {
|
|
||||||
o.setExecuteIndex(1);
|
|
||||||
o.setHandlerName("handlerName 单元测试");
|
|
||||||
o.setStatus(JobLogStatusEnum.SUCCESS.getStatus());
|
|
||||||
o.setBeginTime(buildTime(2021, 1, 8));
|
|
||||||
o.setEndTime(buildTime(2021, 1, 8));
|
|
||||||
});
|
|
||||||
jobLogMapper.insert(dbJobLog);
|
|
||||||
// 测试 jobId 不匹配
|
|
||||||
jobLogMapper.insert(ObjectUtils.cloneIgnoreId(dbJobLog, o -> o.setJobId(randomLongId())));
|
|
||||||
// 测试 handlerName 不匹配
|
|
||||||
jobLogMapper.insert(ObjectUtils.cloneIgnoreId(dbJobLog, o -> o.setHandlerName(randomString())));
|
|
||||||
// 测试 beginTime 不匹配
|
|
||||||
jobLogMapper.insert(ObjectUtils.cloneIgnoreId(dbJobLog, o -> o.setBeginTime(buildTime(2021, 1, 7))));
|
|
||||||
// 测试 endTime 不匹配
|
|
||||||
jobLogMapper.insert(ObjectUtils.cloneIgnoreId(dbJobLog, o -> o.setEndTime(buildTime(2021, 1, 9))));
|
|
||||||
// 测试 status 不匹配
|
|
||||||
jobLogMapper.insert(ObjectUtils.cloneIgnoreId(dbJobLog, o -> o.setStatus(JobLogStatusEnum.FAILURE.getStatus())));
|
|
||||||
// 准备参数
|
|
||||||
JobLogExportReqVO reqVo = new JobLogExportReqVO();
|
|
||||||
reqVo.setJobId(dbJobLog.getJobId());
|
|
||||||
reqVo.setHandlerName("单元");
|
|
||||||
reqVo.setBeginTime(dbJobLog.getBeginTime());
|
|
||||||
reqVo.setEndTime(dbJobLog.getEndTime());
|
|
||||||
reqVo.setStatus(JobLogStatusEnum.SUCCESS.getStatus());
|
|
||||||
// 调用
|
|
||||||
List<JobLogDO> list = jobLogService.getJobLogList(reqVo);
|
|
||||||
// 断言
|
|
||||||
assertEquals(1, list.size());
|
|
||||||
assertPojoEquals(dbJobLog, list.get(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,294 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.infra.service.job;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|
||||||
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
|
|
||||||
import cn.iocoder.yudao.framework.quartz.core.scheduler.SchedulerManager;
|
|
||||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.job.vo.job.JobCreateReqVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.job.vo.job.JobExportReqVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.job.vo.job.JobPageReqVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.job.vo.job.JobUpdateReqVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.convert.job.JobConvert;
|
|
||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.job.JobDO;
|
|
||||||
import cn.iocoder.yudao.module.infra.dal.mysql.job.JobMapper;
|
|
||||||
import cn.iocoder.yudao.module.infra.enums.job.JobStatusEnum;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.quartz.SchedulerException;
|
|
||||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
|
||||||
import org.springframework.context.annotation.Import;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static cn.hutool.core.util.RandomUtil.randomEle;
|
|
||||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
|
||||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
|
||||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
|
|
||||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString;
|
|
||||||
import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.*;
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
|
||||||
import static org.mockito.Mockito.times;
|
|
||||||
import static org.mockito.Mockito.verify;
|
|
||||||
|
|
||||||
@Import(JobServiceImpl.class)
|
|
||||||
public class JobServiceTest extends BaseDbUnitTest {
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private JobServiceImpl jobService;
|
|
||||||
@Resource
|
|
||||||
private JobMapper jobMapper;
|
|
||||||
@MockBean
|
|
||||||
private SchedulerManager schedulerManager;
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCreateJob_cronExpressionValid() {
|
|
||||||
// 准备参数。Cron 表达式为 String 类型,默认随机字符串。
|
|
||||||
JobCreateReqVO reqVO = randomPojo(JobCreateReqVO.class);
|
|
||||||
// 调用,并断言异常
|
|
||||||
assertServiceException(() -> jobService.createJob(reqVO), JOB_CRON_EXPRESSION_VALID);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCreateJob_jobHandlerExists() throws SchedulerException {
|
|
||||||
// 准备参数 指定 Cron 表达式
|
|
||||||
JobCreateReqVO reqVO = randomPojo(JobCreateReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *"));
|
|
||||||
// 调用
|
|
||||||
jobService.createJob(reqVO);
|
|
||||||
// 调用,并断言异常
|
|
||||||
assertServiceException(() -> jobService.createJob(reqVO), JOB_HANDLER_EXISTS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCreateJob_success() throws SchedulerException {
|
|
||||||
// 准备参数 指定 Cron 表达式
|
|
||||||
JobCreateReqVO reqVO = randomPojo(JobCreateReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *"));
|
|
||||||
// 调用
|
|
||||||
Long jobId = jobService.createJob(reqVO);
|
|
||||||
// 断言
|
|
||||||
assertNotNull(jobId);
|
|
||||||
// 校验记录的属性是否正确
|
|
||||||
JobDO job = jobMapper.selectById(jobId);
|
|
||||||
assertPojoEquals(reqVO, job);
|
|
||||||
assertEquals(JobStatusEnum.NORMAL.getStatus(), job.getStatus());
|
|
||||||
// 校验调用
|
|
||||||
verify(schedulerManager, times(1)).addJob(eq(job.getId()), eq(job.getHandlerName()), eq(job.getHandlerParam()), eq(job.getCronExpression()),
|
|
||||||
eq(reqVO.getRetryCount()), eq(reqVO.getRetryInterval()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUpdateJob_jobNotExists(){
|
|
||||||
// 准备参数
|
|
||||||
JobUpdateReqVO reqVO = randomPojo(JobUpdateReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *"));
|
|
||||||
// 调用,并断言异常
|
|
||||||
assertServiceException(() -> jobService.updateJob(reqVO), JOB_NOT_EXISTS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUpdateJob_onlyNormalStatus(){
|
|
||||||
// mock 数据
|
|
||||||
JobCreateReqVO createReqVO = randomPojo(JobCreateReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *"));
|
|
||||||
JobDO job = JobConvert.INSTANCE.convert(createReqVO);
|
|
||||||
job.setStatus(JobStatusEnum.INIT.getStatus());
|
|
||||||
fillJobMonitorTimeoutEmpty(job);
|
|
||||||
jobMapper.insert(job);
|
|
||||||
// 准备参数
|
|
||||||
JobUpdateReqVO updateReqVO = randomPojo(JobUpdateReqVO.class, o -> {
|
|
||||||
o.setId(job.getId());
|
|
||||||
o.setName(createReqVO.getName());
|
|
||||||
o.setCronExpression(createReqVO.getCronExpression());
|
|
||||||
});
|
|
||||||
// 调用,并断言异常
|
|
||||||
assertServiceException(() -> jobService.updateJob(updateReqVO), JOB_UPDATE_ONLY_NORMAL_STATUS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUpdateJob_success() throws SchedulerException {
|
|
||||||
// mock 数据
|
|
||||||
JobCreateReqVO createReqVO = randomPojo(JobCreateReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *"));
|
|
||||||
JobDO job = JobConvert.INSTANCE.convert(createReqVO);
|
|
||||||
job.setStatus(JobStatusEnum.NORMAL.getStatus());
|
|
||||||
fillJobMonitorTimeoutEmpty(job);
|
|
||||||
jobMapper.insert(job);
|
|
||||||
// 准备参数
|
|
||||||
JobUpdateReqVO updateReqVO = randomPojo(JobUpdateReqVO.class, o -> {
|
|
||||||
o.setId(job.getId());
|
|
||||||
o.setName(createReqVO.getName());
|
|
||||||
o.setCronExpression(createReqVO.getCronExpression());
|
|
||||||
});
|
|
||||||
// 调用
|
|
||||||
jobService.updateJob(updateReqVO);
|
|
||||||
// 校验记录的属性是否正确
|
|
||||||
JobDO updateJob = jobMapper.selectById(updateReqVO.getId());
|
|
||||||
assertPojoEquals(updateReqVO, updateJob);
|
|
||||||
// 校验调用
|
|
||||||
verify(schedulerManager, times(1)).updateJob(eq(job.getHandlerName()), eq(updateReqVO.getHandlerParam()), eq(updateReqVO.getCronExpression()),
|
|
||||||
eq(updateReqVO.getRetryCount()), eq(updateReqVO.getRetryInterval()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUpdateJobStatus_changeStatusInvalid() {
|
|
||||||
// 调用,并断言异常
|
|
||||||
assertServiceException(() -> jobService.updateJobStatus(1L, JobStatusEnum.INIT.getStatus()), JOB_CHANGE_STATUS_INVALID);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUpdateJobStatus_changeStatusEquals() {
|
|
||||||
// mock 数据
|
|
||||||
JobCreateReqVO createReqVO = randomPojo(JobCreateReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *"));
|
|
||||||
JobDO job = JobConvert.INSTANCE.convert(createReqVO);
|
|
||||||
job.setStatus(JobStatusEnum.NORMAL.getStatus());
|
|
||||||
fillJobMonitorTimeoutEmpty(job);
|
|
||||||
jobMapper.insert(job);
|
|
||||||
// 调用,并断言异常
|
|
||||||
assertServiceException(() -> jobService.updateJobStatus(job.getId(), job.getStatus()), JOB_CHANGE_STATUS_EQUALS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUpdateJobStatus_NormalToStop_success() throws SchedulerException {
|
|
||||||
// mock 数据
|
|
||||||
JobCreateReqVO createReqVO = randomPojo(JobCreateReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *"));
|
|
||||||
JobDO job = JobConvert.INSTANCE.convert(createReqVO);
|
|
||||||
job.setStatus(JobStatusEnum.NORMAL.getStatus());
|
|
||||||
fillJobMonitorTimeoutEmpty(job);
|
|
||||||
jobMapper.insert(job);
|
|
||||||
// 调用
|
|
||||||
jobService.updateJobStatus(job.getId(), JobStatusEnum.STOP.getStatus());
|
|
||||||
// 校验记录的属性是否正确
|
|
||||||
JobDO updateJob = jobMapper.selectById(job.getId());
|
|
||||||
assertEquals(JobStatusEnum.STOP.getStatus(), updateJob.getStatus());
|
|
||||||
// 校验调用
|
|
||||||
verify(schedulerManager, times(1)).pauseJob(eq(job.getHandlerName()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUpdateJobStatus_StopToNormal_success() throws SchedulerException {
|
|
||||||
// mock 数据
|
|
||||||
JobCreateReqVO createReqVO = randomPojo(JobCreateReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *"));
|
|
||||||
JobDO job = JobConvert.INSTANCE.convert(createReqVO);
|
|
||||||
job.setStatus(JobStatusEnum.STOP.getStatus());
|
|
||||||
fillJobMonitorTimeoutEmpty(job);
|
|
||||||
jobMapper.insert(job);
|
|
||||||
// 调用
|
|
||||||
jobService.updateJobStatus(job.getId(), JobStatusEnum.NORMAL.getStatus());
|
|
||||||
// 校验记录的属性是否正确
|
|
||||||
JobDO updateJob = jobMapper.selectById(job.getId());
|
|
||||||
assertEquals(JobStatusEnum.NORMAL.getStatus(), updateJob.getStatus());
|
|
||||||
// 校验调用
|
|
||||||
verify(schedulerManager, times(1)).resumeJob(eq(job.getHandlerName()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testTriggerJob_success() throws SchedulerException {
|
|
||||||
// mock 数据
|
|
||||||
JobCreateReqVO createReqVO = randomPojo(JobCreateReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *"));
|
|
||||||
JobDO job = JobConvert.INSTANCE.convert(createReqVO);
|
|
||||||
job.setStatus(JobStatusEnum.NORMAL.getStatus());
|
|
||||||
fillJobMonitorTimeoutEmpty(job);
|
|
||||||
jobMapper.insert(job);
|
|
||||||
// 调用
|
|
||||||
jobService.triggerJob(job.getId());
|
|
||||||
// 校验调用
|
|
||||||
verify(schedulerManager, times(1)).triggerJob(eq(job.getId()), eq(job.getHandlerName()), eq(job.getHandlerParam()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDeleteJob_success() throws SchedulerException {
|
|
||||||
// mock 数据
|
|
||||||
JobCreateReqVO createReqVO = randomPojo(JobCreateReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *"));
|
|
||||||
JobDO job = JobConvert.INSTANCE.convert(createReqVO);
|
|
||||||
job.setStatus(JobStatusEnum.NORMAL.getStatus());
|
|
||||||
fillJobMonitorTimeoutEmpty(job);
|
|
||||||
jobMapper.insert(job);
|
|
||||||
// 调用 UPDATE inf_job SET deleted=1 WHERE id=? AND deleted=0
|
|
||||||
jobService.deleteJob(job.getId());
|
|
||||||
// 校验数据不存在了 WHERE id=? AND deleted=0 查询为空正常
|
|
||||||
assertNull(jobMapper.selectById(job.getId()));
|
|
||||||
// 校验调用
|
|
||||||
verify(schedulerManager, times(1)).deleteJob(eq(job.getHandlerName()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetJobListByIds_success() {
|
|
||||||
// mock 数据
|
|
||||||
JobDO dbJob = randomPojo(JobDO.class, o -> {
|
|
||||||
o.setStatus(randomEle(JobStatusEnum.values()).getStatus()); // 保证 status 的范围
|
|
||||||
});
|
|
||||||
JobDO cloneJob = ObjectUtils.cloneIgnoreId(dbJob, o -> o.setHandlerName(randomString()));
|
|
||||||
jobMapper.insert(dbJob);
|
|
||||||
// 测试 handlerName 不匹配
|
|
||||||
jobMapper.insert(cloneJob);
|
|
||||||
// 准备参数
|
|
||||||
ArrayList<Long> ids = new ArrayList<>();
|
|
||||||
ids.add(dbJob.getId());
|
|
||||||
ids.add(cloneJob.getId());
|
|
||||||
// 调用
|
|
||||||
List<JobDO> list = jobService.getJobList(ids);
|
|
||||||
// 断言
|
|
||||||
assertEquals(2, list.size());
|
|
||||||
assertPojoEquals(dbJob, list.get(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetJobPage_success() {
|
|
||||||
// mock 数据
|
|
||||||
JobDO dbJob = randomPojo(JobDO.class, o -> {
|
|
||||||
o.setName("定时任务测试");
|
|
||||||
o.setHandlerName("handlerName 单元测试");
|
|
||||||
o.setStatus(JobStatusEnum.INIT.getStatus());
|
|
||||||
});
|
|
||||||
jobMapper.insert(dbJob);
|
|
||||||
// 测试 name 不匹配
|
|
||||||
jobMapper.insert(ObjectUtils.cloneIgnoreId(dbJob, o -> o.setName("土豆")));
|
|
||||||
// 测试 status 不匹配
|
|
||||||
jobMapper.insert(ObjectUtils.cloneIgnoreId(dbJob, o -> o.setStatus(JobStatusEnum.NORMAL.getStatus())));
|
|
||||||
// 测试 handlerName 不匹配
|
|
||||||
jobMapper.insert(ObjectUtils.cloneIgnoreId(dbJob, o -> o.setHandlerName(randomString())));
|
|
||||||
// 准备参数
|
|
||||||
JobPageReqVO reqVo = new JobPageReqVO();
|
|
||||||
reqVo.setName("定时");
|
|
||||||
reqVo.setStatus(JobStatusEnum.INIT.getStatus());
|
|
||||||
reqVo.setHandlerName("单元");
|
|
||||||
// 调用
|
|
||||||
PageResult<JobDO> pageResult = jobService.getJobPage(reqVo);
|
|
||||||
// 断言
|
|
||||||
assertEquals(1, pageResult.getTotal());
|
|
||||||
assertEquals(1, pageResult.getList().size());
|
|
||||||
assertPojoEquals(dbJob, pageResult.getList().get(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetJobListForExport_success() {
|
|
||||||
// mock 数据
|
|
||||||
JobDO dbJob = randomPojo(JobDO.class, o -> {
|
|
||||||
o.setName("定时任务测试");
|
|
||||||
o.setHandlerName("handlerName 单元测试");
|
|
||||||
o.setStatus(JobStatusEnum.INIT.getStatus());
|
|
||||||
});
|
|
||||||
jobMapper.insert(dbJob);
|
|
||||||
// 测试 name 不匹配
|
|
||||||
jobMapper.insert(ObjectUtils.cloneIgnoreId(dbJob, o -> o.setName("土豆")));
|
|
||||||
// 测试 status 不匹配
|
|
||||||
jobMapper.insert(ObjectUtils.cloneIgnoreId(dbJob, o -> o.setStatus(JobStatusEnum.NORMAL.getStatus())));
|
|
||||||
// 测试 handlerName 不匹配
|
|
||||||
jobMapper.insert(ObjectUtils.cloneIgnoreId(dbJob, o -> o.setHandlerName(randomString())));
|
|
||||||
// 准备参数
|
|
||||||
JobExportReqVO reqVo = new JobExportReqVO();
|
|
||||||
reqVo.setName("定时");
|
|
||||||
reqVo.setStatus(JobStatusEnum.INIT.getStatus());
|
|
||||||
reqVo.setHandlerName("单元");
|
|
||||||
// 调用
|
|
||||||
List<JobDO> list = jobService.getJobList(reqVo);
|
|
||||||
// 断言
|
|
||||||
assertEquals(1, list.size());
|
|
||||||
assertPojoEquals(dbJob, list.get(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void fillJobMonitorTimeoutEmpty(JobDO job) {
|
|
||||||
if (job.getMonitorTimeout() == null) {
|
|
||||||
job.setMonitorTimeout(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,6 +1,3 @@
|
||||||
server:
|
|
||||||
port: 48081
|
|
||||||
|
|
||||||
--- #################### 数据库相关配置 ####################
|
--- #################### 数据库相关配置 ####################
|
||||||
spring:
|
spring:
|
||||||
|
|
||||||
|
|
|
@ -4,3 +4,6 @@ spring:
|
||||||
|
|
||||||
profiles:
|
profiles:
|
||||||
active: local
|
active: local
|
||||||
|
|
||||||
|
server:
|
||||||
|
port: 48081
|
||||||
|
|
Loading…
Reference in New Issue