Merge branch 'master' of https://gitee.com/zhijiantianya/ruoyi-vue-pro into feature/mail-1.6.1

# Conflicts:
#	yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java
#	yudao-module-system/yudao-module-system-biz/pom.xml
This commit is contained in:
YunaiV
2022-12-23 19:38:00 +08:00
3082 changed files with 174737 additions and 58537 deletions

View File

@@ -21,6 +21,13 @@
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-common</artifactId>
</dependency>
<!-- 参数校验 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>

View File

@@ -1,7 +1,5 @@
package cn.iocoder.yudao.module.infra.api.file;
import cn.hutool.core.util.IdUtil;
/**
* 文件 API 接口
*
@@ -15,9 +13,9 @@ public interface FileApi {
* @param content 文件内容
* @return 文件路径
*/
default String createFile(byte[] content) throws Exception {
return createFile(IdUtil.fastUUID(), content);
}
default String createFile(byte[] content) {
return createFile(null, null, content);
}
/**
* 保存文件,并返回文件的访问路径
@@ -26,6 +24,18 @@ public interface FileApi {
* @param content 文件内容
* @return 文件路径
*/
String createFile(String path, byte[] content) throws Exception;
default String createFile(String path, byte[] content) {
return createFile(null, path, content);
}
/**
* 保存文件,并返回文件的访问路径
*
* @param name 文件名称
* @param path 文件路径
* @param content 文件内容
* @return 文件路径
*/
String createFile(String name, String path, byte[] content);
}

View File

@@ -0,0 +1,21 @@
package cn.iocoder.yudao.module.infra.api.logger;
import cn.iocoder.yudao.module.infra.api.logger.dto.ApiAccessLogCreateReqDTO;
import javax.validation.Valid;
/**
* API 访问日志的 API 接口
*
* @author 芋道源码
*/
public interface ApiAccessLogApi {
/**
* 创建 API 访问日志
*
* @param createDTO 创建信息
*/
void createApiAccessLog(@Valid ApiAccessLogCreateReqDTO createDTO);
}

View File

@@ -0,0 +1,21 @@
package cn.iocoder.yudao.module.infra.api.logger;
import cn.iocoder.yudao.module.infra.api.logger.dto.ApiErrorLogCreateReqDTO;
import javax.validation.Valid;
/**
* API 错误日志的 API 接口
*
* @author 芋道源码
*/
public interface ApiErrorLogApi {
/**
* 创建 API 错误日志
*
* @param createDTO 创建信息
*/
void createApiErrorLog(@Valid ApiErrorLogCreateReqDTO createDTO);
}

View File

@@ -0,0 +1,85 @@
package cn.iocoder.yudao.module.infra.api.logger.dto;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
/**
* API 访问日志
*
* @author 芋道源码
*/
@Data
public class ApiAccessLogCreateReqDTO {
/**
* 链路追踪编号
*/
private String traceId;
/**
* 用户编号
*/
private Long userId;
/**
* 用户类型
*/
private Integer userType;
/**
* 应用名
*/
@NotNull(message = "应用名不能为空")
private String applicationName;
/**
* 请求方法名
*/
@NotNull(message = "http 请求方法不能为空")
private String requestMethod;
/**
* 访问地址
*/
@NotNull(message = "访问地址不能为空")
private String requestUrl;
/**
* 请求参数
*/
@NotNull(message = "请求参数不能为空")
private String requestParams;
/**
* 用户 IP
*/
@NotNull(message = "ip 不能为空")
private String userIp;
/**
* 浏览器 UA
*/
@NotNull(message = "User-Agent 不能为空")
private String userAgent;
/**
* 开始请求时间
*/
@NotNull(message = "开始请求时间不能为空")
private LocalDateTime beginTime;
/**
* 结束请求时间
*/
@NotNull(message = "结束请求时间不能为空")
private LocalDateTime endTime;
/**
* 执行时长,单位:毫秒
*/
@NotNull(message = "执行时长不能为空")
private Integer duration;
/**
* 结果码
*/
@NotNull(message = "错误码不能为空")
private Integer resultCode;
/**
* 结果提示
*/
private String resultMsg;
}

View File

@@ -0,0 +1,107 @@
package cn.iocoder.yudao.module.infra.api.logger.dto;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
/**
* API 错误日志
*
* @author 芋道源码
*/
@Data
public class ApiErrorLogCreateReqDTO {
/**
* 链路编号
*/
private String traceId;
/**
* 账号编号
*/
private Long userId;
/**
* 用户类型
*/
private Integer userType;
/**
* 应用名
*/
@NotNull(message = "应用名不能为空")
private String applicationName;
/**
* 请求方法名
*/
@NotNull(message = "http 请求方法不能为空")
private String requestMethod;
/**
* 访问地址
*/
@NotNull(message = "访问地址不能为空")
private String requestUrl;
/**
* 请求参数
*/
@NotNull(message = "请求参数不能为空")
private String requestParams;
/**
* 用户 IP
*/
@NotNull(message = "ip 不能为空")
private String userIp;
/**
* 浏览器 UA
*/
@NotNull(message = "User-Agent 不能为空")
private String userAgent;
/**
* 异常时间
*/
@NotNull(message = "异常时间不能为空")
private LocalDateTime exceptionTime;
/**
* 异常名
*/
@NotNull(message = "异常名不能为空")
private String exceptionName;
/**
* 异常发生的类全名
*/
@NotNull(message = "异常发生的类全名不能为空")
private String exceptionClassName;
/**
* 异常发生的类文件
*/
@NotNull(message = "异常发生的类文件不能为空")
private String exceptionFileName;
/**
* 异常发生的方法名
*/
@NotNull(message = "异常发生的方法名不能为空")
private String exceptionMethodName;
/**
* 异常发生的方法所在行
*/
@NotNull(message = "异常发生的方法所在行不能为空")
private Integer exceptionLineNumber;
/**
* 异常的栈轨迹异常的栈轨迹
*/
@NotNull(message = "异常的栈轨迹不能为空")
private String exceptionStackTrace;
/**
* 异常导致的根消息
*/
@NotNull(message = "异常导致的根消息不能为空")
private String exceptionRootCauseMessage;
/**
* 异常导致的消息
*/
@NotNull(message = "异常导致的消息不能为空")
private String exceptionMessage;
}

View File

@@ -58,10 +58,6 @@
</dependency>
<!-- Config 配置中心相关 -->
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-config</artifactId>
</dependency>
<!-- Job 定时任务相关 -->
<dependency>
@@ -83,10 +79,6 @@
</dependency>
<!-- 工具类相关 -->
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId> <!-- 加解密 -->
</dependency>
<dependency>
<groupId>cn.iocoder.boot</groupId>
@@ -119,7 +111,6 @@
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-file</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -19,8 +19,8 @@ public class FileApiImpl implements FileApi {
private FileService fileService;
@Override
public String createFile(String path, byte[] content) throws Exception {
return fileService.createFile(path, content);
public String createFile(String name, String path, byte[] content) {
return fileService.createFile(name, path, content);
}
}

View File

@@ -0,0 +1,27 @@
package cn.iocoder.yudao.module.infra.api.logger;
import cn.iocoder.yudao.module.infra.api.logger.dto.ApiAccessLogCreateReqDTO;
import cn.iocoder.yudao.module.infra.service.logger.ApiAccessLogService;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
/**
* API 访问日志的 API 实现类
*
* @author 芋道源码
*/
@Service
@Validated
public class ApiAccessLogApiImpl implements ApiAccessLogApi {
@Resource
private ApiAccessLogService apiAccessLogService;
@Override
public void createApiAccessLog(ApiAccessLogCreateReqDTO createDTO) {
apiAccessLogService.createApiAccessLog(createDTO);
}
}

View File

@@ -0,0 +1,27 @@
package cn.iocoder.yudao.module.infra.api.logger;
import cn.iocoder.yudao.module.infra.api.logger.dto.ApiErrorLogCreateReqDTO;
import cn.iocoder.yudao.module.infra.service.logger.ApiErrorLogService;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
/**
* API 访问日志的 API 接口
*
* @author 芋道源码
*/
@Service
@Validated
public class ApiErrorLogApiImpl implements ApiErrorLogApi {
@Resource
private ApiErrorLogService apiErrorLogService;
@Override
public void createApiErrorLog(ApiErrorLogCreateReqDTO createDTO) {
apiErrorLogService.createApiErrorLog(createDTO);
}
}

View File

@@ -6,7 +6,7 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.util.Date;
import java.time.LocalDateTime;
@ApiModel("管理后台 - 代码生成字段定义 Response VO")
@Data
@@ -18,6 +18,6 @@ public class CodegenColumnRespVO extends CodegenColumnBaseVO {
private Long id;
@ApiModelProperty(value = "创建时间", required = true)
private Date createTime;
private LocalDateTime createTime;
}

View File

@@ -8,7 +8,7 @@ import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@@ -24,12 +24,8 @@ public class CodegenTablePageReqVO extends PageParam {
@ApiModelProperty(value = "表描述", example = "芋道", notes = "模糊匹配")
private String tableComment;
@ApiModelProperty(value = "开始创建时间", example = "2020-10-24 00:00:00")
@ApiModelProperty(value = "创建时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private Date beginCreateTime;
@ApiModelProperty(value = "结束创建时间", example = "2020-10-24 23:59:59")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private Date endCreateTime;
private LocalDateTime[] createTime;
}

View File

@@ -6,7 +6,7 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.util.Date;
import java.time.LocalDateTime;
@ApiModel("管理后台 - 代码生成表定义 Response VO")
@Data
@@ -21,9 +21,9 @@ public class CodegenTableRespVO extends CodegenTableBaseVO {
private Integer dataSourceConfigId;
@ApiModelProperty(value = "创建时间", required = true)
private Date createTime;
private LocalDateTime createTime;
@ApiModelProperty(value = "更新时间", required = true)
private Date updateTime;
private LocalDateTime updateTime;
}

View File

@@ -6,7 +6,7 @@ import cn.iocoder.yudao.module.infra.enums.DictTypeConstants;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
import java.util.Date;
import java.time.LocalDateTime;
/**
* 参数配置 Excel 导出响应 VO
@@ -41,6 +41,6 @@ public class ConfigExcelVO {
private String remark;
@ExcelProperty("创建时间")
private Date createTime;
private LocalDateTime createTime;
}

View File

@@ -5,7 +5,7 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@@ -22,12 +22,8 @@ public class ConfigExportReqVO {
@ApiModelProperty(value = "参数类型", example = "1", notes = "参见 SysConfigTypeEnum 枚举")
private Integer type;
@ApiModelProperty(value = "开始时间", example = "2020-10-24 00:00:00")
@ApiModelProperty(value = "创建时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]")
@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;
private LocalDateTime[] createTime;
}

View File

@@ -8,7 +8,7 @@ import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@@ -27,12 +27,8 @@ public class ConfigPageReqVO extends PageParam {
@ApiModelProperty(value = "参数类型", example = "1", notes = "参见 SysConfigTypeEnum 枚举")
private Integer type;
@ApiModelProperty(value = "开始时间", example = "2020-10-24 00:00:00")
@ApiModelProperty(value = "创建时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]")
@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;
private LocalDateTime[] createTime;
}

View File

@@ -7,7 +7,7 @@ import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import java.util.Date;
import java.time.LocalDateTime;
@ApiModel("管理后台 - 参数配置信息 Response VO")
@Data
@@ -26,6 +26,6 @@ public class ConfigRespVO extends ConfigBaseVO {
private Integer type;
@ApiModelProperty(value = "创建时间", required = true, example = "时间戳格式")
private Date createTime;
private LocalDateTime createTime;
}

View File

@@ -1,7 +1,8 @@
package cn.iocoder.yudao.module.infra.controller.admin.db.vo;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import io.swagger.annotations.*;
@ApiModel("管理后台 - 数据源配置 Response VO")
@@ -14,6 +15,6 @@ public class DataSourceConfigRespVO extends DataSourceConfigBaseVO {
private Integer id;
@ApiModelProperty(value = "创建时间", required = true)
private Date createTime;
private LocalDateTime createTime;
}

View File

@@ -1,17 +1,19 @@
package cn.iocoder.yudao.module.infra.controller.admin.file;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FilePageReqVO;
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FileRespVO;
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FileUploadReqVO;
import cn.iocoder.yudao.module.infra.convert.file.FileConvert;
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO;
import cn.iocoder.yudao.module.infra.service.file.FileService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
@@ -21,6 +23,8 @@ import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.annotation.security.PermitAll;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
@@ -38,13 +42,11 @@ public class FileController {
@PostMapping("/upload")
@ApiOperation("上传文件")
@ApiImplicitParams({
@ApiImplicitParam(name = "file", value = "文件附件", required = true, dataTypeClass = MultipartFile.class),
@ApiImplicitParam(name = "path", value = "文件路径", example = "yudaoyuanma.png", dataTypeClass = String.class)
})
public CommonResult<String> uploadFile(@RequestParam("file") MultipartFile file,
@RequestParam("path") String path) throws Exception {
return success(fileService.createFile(path, IoUtil.readBytes(file.getInputStream())));
@OperateLog(logArgs = false) // 上传文件,没有记录操作日志的必要
public CommonResult<String> uploadFile(FileUploadReqVO uploadReqVO) throws Exception {
MultipartFile file = uploadReqVO.getFile();
String path = uploadReqVO.getPath();
return success(fileService.createFile(file.getOriginalFilename(), path, IoUtil.readBytes(file.getInputStream())));
}
@DeleteMapping("/delete")
@@ -56,15 +58,20 @@ public class FileController {
return success(true);
}
@GetMapping("/{configId}/get/{path}")
@GetMapping("/{configId}/get/**")
@PermitAll
@ApiOperation("下载文件")
@ApiImplicitParams({
@ApiImplicitParam(name = "configId", value = "配置编号", required = true, dataTypeClass = Long.class),
@ApiImplicitParam(name = "path", value = "文件路径", required = true, dataTypeClass = String.class)
})
public void getFileContent(HttpServletResponse response,
@PathVariable("configId") Long configId,
@PathVariable("path") String path) throws Exception {
@ApiImplicitParam(name = "configId", value = "配置编号", required = true, dataTypeClass = Long.class)
public void getFileContent(HttpServletRequest request,
HttpServletResponse response,
@PathVariable("configId") Long configId) throws Exception {
// 获取请求的路径
String path = StrUtil.subAfter(request.getRequestURI(), "/get/", false);
if (StrUtil.isEmpty(path)) {
throw new IllegalArgumentException("结尾的 path 路径必须传递");
}
// 读取内容
byte[] content = fileService.getFileContent(configId, path);
if (content == null) {
log.warn("[getFileContent][configId({}) path({}) 文件不存在]", configId, path);

View File

@@ -8,7 +8,7 @@ import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@@ -25,11 +25,7 @@ public class FileConfigPageReqVO extends PageParam {
private Integer storage;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "开始创建时间")
private Date beginCreateTime;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "结束创建时间")
private Date endCreateTime;
@ApiModelProperty(value = "创建时间")
private LocalDateTime[] createTime;
}

View File

@@ -8,7 +8,7 @@ import lombok.EqualsAndHashCode;
import lombok.ToString;
import javax.validation.constraints.NotNull;
import java.util.Date;
import java.time.LocalDateTime;
@ApiModel("管理后台 - 文件配置 Response VO")
@Data
@@ -31,6 +31,6 @@ public class FileConfigRespVO extends FileConfigBaseVO {
private FileClientConfig config;
@ApiModelProperty(value = "创建时间", required = true)
private Date createTime;
private LocalDateTime createTime;
}

View File

@@ -8,7 +8,7 @@ import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@@ -21,15 +21,11 @@ public class FilePageReqVO extends PageParam {
@ApiModelProperty(value = "文件路径", example = "yudao", notes = "模糊匹配")
private String path;
@ApiModelProperty(value = "文件类型", example = "jpg", notes = "模糊匹配")
@ApiModelProperty(value = "文件类型", example = "application/octet-stream", notes = "模糊匹配")
private String type;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "开始创建时间")
private Date beginCreateTime;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "结束创建时间")
private Date endCreateTime;
@ApiModelProperty(value = "创建时间")
private LocalDateTime[] createTime;
}

View File

@@ -4,7 +4,7 @@ import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
import java.time.LocalDateTime;
@ApiModel(value = "管理后台 - 文件 Response VO", description = "不返回 content 字段,太大")
@Data
@@ -13,19 +13,25 @@ public class FileRespVO {
@ApiModelProperty(value = "文件编号", required = true, example = "1024")
private Long id;
@ApiModelProperty(value = "配置编号", required = true, example = "11")
private Long configId;
@ApiModelProperty(value = "文件路径", required = true, example = "yudao.jpg")
private String path;
@ApiModelProperty(value = "原文件名", required = true, example = "yudao.jpg")
private String name;
@ApiModelProperty(value = "文件 URL", required = true, example = "https://www.iocoder.cn/yudao.jpg")
private String url;
@ApiModelProperty(value = "文件类型", example = "jpg")
@ApiModelProperty(value = "文件MIME类型", example = "application/octet-stream")
private String type;
@ApiModelProperty(value = "文件大小", example = "2048", required = true)
private Integer size;
@ApiModelProperty(value = "创建时间", required = true)
private Date createTime;
private LocalDateTime createTime;
}

View File

@@ -0,0 +1,21 @@
package cn.iocoder.yudao.module.infra.controller.admin.file.vo.file;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.web.multipart.MultipartFile;
import javax.validation.constraints.NotNull;
@ApiModel(value = "管理后台 - 上传文件 Request VO")
@Data
public class FileUploadReqVO {
@ApiModelProperty(value = "文件附件", required = true)
@NotNull(message = "文件附件不能为空")
private MultipartFile file;
@ApiModelProperty(value = "文件附件", example = "yudaoyuanma.png")
private String path;
}

View File

@@ -22,9 +22,9 @@ import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.time.LocalDateTime;
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;
@@ -133,8 +133,8 @@ public class JobController {
@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) {
public CommonResult<List<LocalDateTime>> 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());

View File

@@ -6,7 +6,7 @@ import cn.iocoder.yudao.module.infra.enums.DictTypeConstants;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
import java.util.Date;
import java.time.LocalDateTime;
/**
* 定时任务 Excel VO
@@ -36,21 +36,21 @@ public class JobExcelVO {
private String cronExpression;
@ExcelProperty("最后一次执行的开始时间")
private Date executeBeginTime;
private LocalDateTime executeBeginTime;
@ExcelProperty("最后一次执行的结束时间")
private Date executeEndTime;
private LocalDateTime executeEndTime;
@ExcelProperty("上一次触发时间")
private Date firePrevTime;
private LocalDateTime firePrevTime;
@ExcelProperty("下一次触发时间")
private Date fireNextTime;
private LocalDateTime fireNextTime;
@ExcelProperty("监控超时时间")
private Integer monitorTimeout;
@ExcelProperty("创建时间")
private Date createTime;
private LocalDateTime createTime;
}

View File

@@ -7,7 +7,7 @@ import lombok.EqualsAndHashCode;
import lombok.ToString;
import javax.validation.constraints.NotNull;
import java.util.Date;
import java.time.LocalDateTime;
@ApiModel("管理后台 - 定时任务 Response VO")
@Data
@@ -26,6 +26,6 @@ public class JobRespVO extends JobBaseVO {
private String handlerName;
@ApiModelProperty(value = "创建时间", required = true)
private Date createTime;
private LocalDateTime createTime;
}

View File

@@ -5,7 +5,7 @@ import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.NotNull;
import java.util.Date;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@@ -34,11 +34,11 @@ public class JobLogBaseVO {
@ApiModelProperty(value = "开始执行时间", required = true)
@NotNull(message = "开始执行时间不能为空")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private Date beginTime;
private LocalDateTime beginTime;
@ApiModelProperty(value = "结束执行时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private Date endTime;
private LocalDateTime endTime;
@ApiModelProperty(value = "执行时长", example = "123")
private Integer duration;

View File

@@ -6,7 +6,7 @@ import cn.iocoder.yudao.module.infra.enums.DictTypeConstants;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
import java.util.Date;
import java.time.LocalDateTime;
/**
* 定时任务 Excel VO
@@ -32,10 +32,10 @@ public class JobLogExcelVO {
private Integer executeIndex;
@ExcelProperty("开始执行时间")
private Date beginTime;
private LocalDateTime beginTime;
@ExcelProperty("结束执行时间")
private Date endTime;
private LocalDateTime endTime;
@ExcelProperty("执行时长")
private Integer duration;
@@ -48,6 +48,6 @@ public class JobLogExcelVO {
private String result;
@ExcelProperty("创建时间")
private Date createTime;
private LocalDateTime createTime;
}

View File

@@ -5,7 +5,7 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@@ -21,11 +21,11 @@ public class JobLogExportReqVO {
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "开始执行时间")
private Date beginTime;
private LocalDateTime beginTime;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "结束执行时间")
private Date endTime;
private LocalDateTime endTime;
@ApiModelProperty(value = "任务状态", notes = "参见 JobLogStatusEnum 枚举")
private Integer status;

View File

@@ -8,7 +8,7 @@ import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@@ -26,11 +26,11 @@ public class JobLogPageReqVO extends PageParam {
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "开始执行时间")
private Date beginTime;
private LocalDateTime beginTime;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "结束执行时间")
private Date endTime;
private LocalDateTime endTime;
@ApiModelProperty(value = "任务状态", notes = "参见 JobLogStatusEnum 枚举")
private Integer status;

View File

@@ -6,7 +6,7 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.util.Date;
import java.time.LocalDateTime;
@ApiModel("管理后台 - 定时任务日志 Response VO")
@Data
@@ -18,6 +18,6 @@ public class JobLogRespVO extends JobLogBaseVO {
private Long id;
@ApiModelProperty(value = "创建时间", required = true)
private Date createTime;
private LocalDateTime createTime;
}

View File

@@ -5,7 +5,7 @@ import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.NotNull;
import java.util.Date;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@@ -54,12 +54,12 @@ public class ApiAccessLogBaseVO {
@ApiModelProperty(value = "开始请求时间", required = true)
@NotNull(message = "开始请求时间不能为空")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private Date beginTime;
private LocalDateTime beginTime;
@ApiModelProperty(value = "结束请求时间", required = true)
@NotNull(message = "结束请求时间不能为空")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private Date endTime;
private LocalDateTime endTime;
@ApiModelProperty(value = "执行时长", required = true, example = "100")
@NotNull(message = "执行时长不能为空")

View File

@@ -6,7 +6,7 @@ import cn.iocoder.yudao.module.system.enums.DictTypeConstants;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
import java.util.Date;
import java.time.LocalDateTime;
/**
* API 访问日志 Excel VO
@@ -48,10 +48,10 @@ public class ApiAccessLogExcelVO {
private String userAgent;
@ExcelProperty("开始请求时间")
private Date beginTime;
private LocalDateTime beginTime;
@ExcelProperty("结束请求时间")
private Date endTime;
private LocalDateTime endTime;
@ExcelProperty("执行时长")
private Integer duration;

View File

@@ -5,7 +5,7 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@@ -26,12 +26,8 @@ public class ApiAccessLogExportReqVO {
private String requestUrl;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "开始开始请求时间")
private Date beginBeginTime;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "结束开始请求时间")
private Date endBeginTime;
@ApiModelProperty(value = "开始请求时间")
private LocalDateTime[] beginTime;
@ApiModelProperty(value = "执行时长", example = "100", notes = "大于等于,单位:毫秒")
private Integer duration;

View File

@@ -8,7 +8,7 @@ import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@@ -31,12 +31,8 @@ public class ApiAccessLogPageReqVO extends PageParam {
private String requestUrl;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "开始开始请求时间")
private Date beginBeginTime;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "结束开始请求时间")
private Date endBeginTime;
@ApiModelProperty(value = "开始请求时间")
private LocalDateTime[] beginTime;
@ApiModelProperty(value = "执行时长", example = "100", notes = "大于等于,单位:毫秒")
private Integer duration;

View File

@@ -6,7 +6,7 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.util.Date;
import java.time.LocalDateTime;
@ApiModel("管理后台 - API 访问日志 Response VO")
@Data
@@ -18,6 +18,6 @@ public class ApiAccessLogRespVO extends ApiAccessLogBaseVO {
private Long id;
@ApiModelProperty(value = "创建时间", required = true)
private Date createTime;
private LocalDateTime createTime;
}

View File

@@ -5,7 +5,7 @@ import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.NotNull;
import java.util.Date;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@@ -55,7 +55,7 @@ public class ApiErrorLogBaseVO {
@ApiModelProperty(value = "异常发生时间", required = true)
@NotNull(message = "异常发生时间不能为空")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private Date exceptionTime;
private LocalDateTime exceptionTime;
@ApiModelProperty(value = "异常名", required = true)
@NotNull(message = "异常名不能为空")

View File

@@ -6,7 +6,7 @@ import cn.iocoder.yudao.module.infra.enums.DictTypeConstants;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
import java.util.Date;
import java.time.LocalDateTime;
/**
* API 错误日志 Excel VO
@@ -48,7 +48,7 @@ public class ApiErrorLogExcelVO {
private String userAgent;
@ExcelProperty("异常发生时间")
private Date exceptionTime;
private LocalDateTime exceptionTime;
@ExcelProperty("异常名")
private String exceptionName;
@@ -75,14 +75,14 @@ public class ApiErrorLogExcelVO {
private Integer exceptionLineNumber;
@ExcelProperty("创建时间")
private Date createTime;
private LocalDateTime createTime;
@ExcelProperty(value = "处理状态", converter = DictConvert.class)
@DictFormat(DictTypeConstants.API_ERROR_LOG_PROCESS_STATUS)
private Integer processStatus;
@ExcelProperty("处理时间")
private Date processTime;
private LocalDateTime processTime;
@ExcelProperty("处理用户编号")
private Integer processUserId;

View File

@@ -5,7 +5,7 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@@ -26,12 +26,8 @@ public class ApiErrorLogExportReqVO {
private String requestUrl;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "开始异常发生时间")
private Date beginExceptionTime;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "结束异常发生时间")
private Date endExceptionTime;
@ApiModelProperty(value = "异常发生时间")
private LocalDateTime[] exceptionTime;
@ApiModelProperty(value = "处理状态", example = "0")
private Integer processStatus;

View File

@@ -8,7 +8,7 @@ import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@@ -31,12 +31,8 @@ public class ApiErrorLogPageReqVO extends PageParam {
private String requestUrl;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "开始异常发生时间")
private Date beginExceptionTime;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "结束异常发生时间")
private Date endExceptionTime;
@ApiModelProperty(value = "异常发生时间")
private LocalDateTime[] exceptionTime;
@ApiModelProperty(value = "处理状态", example = "0")
private Integer processStatus;

View File

@@ -6,7 +6,7 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.util.Date;
import java.time.LocalDateTime;
@ApiModel("管理后台 - API 错误日志 Response VO")
@Data
@@ -18,10 +18,10 @@ public class ApiErrorLogRespVO extends ApiErrorLogBaseVO {
private Integer id;
@ApiModelProperty(value = "创建时间", required = true)
private Date createTime;
private LocalDateTime createTime;
@ApiModelProperty(value = "处理时间", required = true)
private Date processTime;
private LocalDateTime processTime;
@ApiModelProperty(value = "处理用户编号", example = "233")
private Integer processUserId;

View File

@@ -1,24 +1,27 @@
package cn.iocoder.yudao.module.infra.controller.admin.redis;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.redis.core.RedisKeyDefine;
import cn.iocoder.yudao.framework.redis.core.RedisKeyRegistry;
import cn.iocoder.yudao.module.infra.controller.admin.redis.vo.RedisKeyRespVO;
import cn.iocoder.yudao.module.infra.controller.admin.redis.vo.RedisKeyDefineRespVO;
import cn.iocoder.yudao.module.infra.controller.admin.redis.vo.RedisKeyValueRespVO;
import cn.iocoder.yudao.module.infra.controller.admin.redis.vo.RedisMonitorRespVO;
import cn.iocoder.yudao.module.infra.convert.redis.RedisConvert;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.data.redis.connection.RedisServerCommands;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
import java.util.Properties;
import java.util.*;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@@ -44,12 +47,66 @@ public class RedisController {
return success(RedisConvert.INSTANCE.build(info, dbSize, commandStats));
}
@GetMapping("/get-key-list")
@ApiOperation("获得 Redis Key 列表")
@GetMapping("/get-key-define-list")
@ApiOperation("获得 Redis Key 模板列表")
@PreAuthorize("@ss.hasPermission('infra:redis:get-key-list')")
public CommonResult<List<RedisKeyRespVO>> getKeyList() {
public CommonResult<List<RedisKeyDefineRespVO>> getKeyDefineList() {
List<RedisKeyDefine> keyDefines = RedisKeyRegistry.list();
return success(RedisConvert.INSTANCE.convertList(keyDefines));
}
@GetMapping("/get-key-list")
@ApiOperation("获得 Redis keys 键名列表")
@ApiImplicitParam(name = "keyTemplate", value = "Redis Key 定义", example = "true", dataTypeClass = String.class)
@PreAuthorize("@ss.hasPermission('infra:redis:get-key-list')")
public CommonResult<Set<String>> getKeyDefineList(@RequestParam("keyTemplate") String keyTemplate) {
return success(getKeyDefineList0(keyTemplate));
}
private Set<String> getKeyDefineList0(String keyTemplate) {
// key 格式化
String key = StrUtil.replace(keyTemplate, "%[s|c|b|d|x|o|f|a|e|g]", parameter -> "*");
// scan 扫描 key
Set<String> keys = new LinkedHashSet<>();
stringRedisTemplate.execute((RedisCallback<Set<String>>) connection -> {
try (Cursor<byte[]> cursor = connection.scan(ScanOptions.scanOptions().match(key).count(100).build())) {
cursor.forEachRemaining(value -> keys.add(StrUtil.utf8Str(value)));
} catch (Exception e) {
throw new RuntimeException(e);
}
return keys;
});
return keys;
}
@GetMapping("/get-key-value")
@ApiOperation("获得 Redis key 内容")
@ApiImplicitParam(name = "key", value = "Redis Key", example = "oauth2_access_token:233", dataTypeClass = String.class)
@PreAuthorize("@ss.hasPermission('infra:redis:get-key-list')")
public CommonResult<RedisKeyValueRespVO> getKeyValue(@RequestParam("key") String key) {
String value = stringRedisTemplate.opsForValue().get(key);
return success(new RedisKeyValueRespVO(key, value));
}
@DeleteMapping("/delete-key")
@ApiOperation("删除 Redis Key")
@ApiImplicitParam(name = "key", value = "Redis Key", example = "oauth2_access_token:233", dataTypeClass = String.class)
@PreAuthorize("@ss.hasPermission('infra:redis:get-key-list')")
public CommonResult<Boolean> deleteKey(@RequestParam("key") String key) {
stringRedisTemplate.delete(key);
return success(Boolean.TRUE);
}
@DeleteMapping("/delete-keys")
@ApiOperation("删除 Redis Key 根据模板")
@ApiImplicitParam(name = "keyTemplate", value = "Redis Key 定义", example = "true", dataTypeClass = String.class)
@PreAuthorize("@ss.hasPermission('infra:redis:get-key-list')")
public CommonResult<Boolean> deleteKeys(@RequestParam("keyTemplate") String keyTemplate) {
Set<String> keys = getKeyDefineList0(keyTemplate);
if (CollUtil.isNotEmpty(keys)) {
stringRedisTemplate.delete(keys);
}
return success(Boolean.TRUE);
}
}

View File

@@ -13,9 +13,9 @@ import java.time.Duration;
@Data
@Builder
@AllArgsConstructor
public class RedisKeyRespVO {
public class RedisKeyDefineRespVO {
@ApiModelProperty(value = "login_user:%s", required = true, example = "String")
@ApiModelProperty(value = "Key 模板", required = true, example = "login_user:%s")
private String keyTemplate;
@ApiModelProperty(value = "Key 类型的枚举", required = true, example = "String")

View File

@@ -0,0 +1,19 @@
package cn.iocoder.yudao.module.infra.controller.admin.redis.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
@ApiModel("管理后台 - 单个 Redis Key Value Response VO")
@Data
@AllArgsConstructor
public class RedisKeyValueRespVO {
@ApiModelProperty(value = "c5f6990767804a928f4bb96ca249febf", required = true, example = "String")
private String key;
@ApiModelProperty(required = true, example = "String")
private String value;
}

View File

@@ -34,7 +34,7 @@ public class RedisMonitorRespVO {
private String command;
@ApiModelProperty(value = "调用次数", required = true, example = "1024")
private Integer calls;
private Long calls;
@ApiModelProperty(value = "消耗 CPU 秒数", required = true, example = "666")
private Long usec;

View File

@@ -1,8 +1,8 @@
package cn.iocoder.yudao.module.infra.controller.admin.test.vo;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
import java.time.LocalDateTime;
import com.alibaba.excel.annotation.ExcelProperty;
@@ -33,6 +33,6 @@ public class TestDemoExcelVO {
private String remark;
@ExcelProperty("创建时间")
private Date createTime;
private LocalDateTime createTime;
}

View File

@@ -1,9 +1,9 @@
package cn.iocoder.yudao.module.infra.controller.admin.test.vo;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import io.swagger.annotations.*;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@@ -28,11 +28,7 @@ public class TestDemoExportReqVO {
private String remark;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "开始创建时间")
private Date beginCreateTime;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "结束创建时间")
private Date endCreateTime;
@ApiModelProperty(value = "创建时间")
private LocalDateTime[] createTime;
}

View File

@@ -1,7 +1,8 @@
package cn.iocoder.yudao.module.infra.controller.admin.test.vo;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import io.swagger.annotations.*;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
@@ -30,11 +31,7 @@ public class TestDemoPageReqVO extends PageParam {
private String remark;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "开始创建时间")
private Date beginCreateTime;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "结束创建时间")
private Date endCreateTime;
@ApiModelProperty(value = "创建时间")
private LocalDateTime[] createTime;
}

View File

@@ -1,7 +1,8 @@
package cn.iocoder.yudao.module.infra.controller.admin.test.vo;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import io.swagger.annotations.*;
@ApiModel("管理后台 - 字典类型 Response VO")
@@ -14,6 +15,6 @@ public class TestDemoRespVO extends TestDemoBaseVO {
private Long id;
@ApiModelProperty(value = "创建时间", required = true)
private Date createTime;
private LocalDateTime createTime;
}

View File

@@ -1,7 +1,7 @@
package cn.iocoder.yudao.module.infra.convert.logger;
import cn.iocoder.yudao.framework.apilog.core.service.dto.ApiAccessLogCreateReqDTO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.infra.api.logger.dto.ApiAccessLogCreateReqDTO;
import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apiaccesslog.ApiAccessLogExcelVO;
import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apiaccesslog.ApiAccessLogRespVO;
import cn.iocoder.yudao.module.infra.dal.dataobject.logger.ApiAccessLogDO;

View File

@@ -1,7 +1,7 @@
package cn.iocoder.yudao.module.infra.convert.logger;
import cn.iocoder.yudao.framework.apilog.core.service.dto.ApiErrorLogCreateReqDTO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.infra.api.logger.dto.ApiErrorLogCreateReqDTO;
import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apierrorlog.ApiErrorLogExcelVO;
import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apierrorlog.ApiErrorLogRespVO;
import cn.iocoder.yudao.module.infra.dal.dataobject.logger.ApiErrorLogDO;

View File

@@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.infra.convert.redis;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.redis.core.RedisKeyDefine;
import cn.iocoder.yudao.module.infra.controller.admin.redis.vo.RedisKeyRespVO;
import cn.iocoder.yudao.module.infra.controller.admin.redis.vo.RedisKeyDefineRespVO;
import cn.iocoder.yudao.module.infra.controller.admin.redis.vo.RedisMonitorRespVO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
@@ -22,13 +22,13 @@ public interface RedisConvert {
commandStats.forEach((key, value) -> {
respVO.getCommandStats().add(RedisMonitorRespVO.CommandStat.builder()
.command(StrUtil.subAfter((String) key, "cmdstat_", false))
.calls(Integer.valueOf(StrUtil.subBetween((String) value, "calls=", ",")))
.calls(Long.valueOf(StrUtil.subBetween((String) value, "calls=", ",")))
.usec(Long.valueOf(StrUtil.subBetween((String) value, "usec=", ",")))
.build());
});
return respVO;
}
List<RedisKeyRespVO> convertList(List<RedisKeyDefine> list);
List<RedisKeyDefineRespVO> convertList(List<RedisKeyDefine> list);
}

View File

@@ -1,7 +1,9 @@
package cn.iocoder.yudao.module.infra.dal.dataobject.db;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.framework.mybatis.core.type.EncryptTypeHandler;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@@ -10,7 +12,7 @@ import lombok.Data;
*
* @author 芋道源码
*/
@TableName("infra_data_source_config")
@TableName(value = "infra_data_source_config", autoResultMap = true)
@KeySequence("infra_data_source_config_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
public class DataSourceConfigDO extends BaseDO {
@@ -40,6 +42,7 @@ public class DataSourceConfigDO extends BaseDO {
/**
* 密码
*/
@TableField(typeHandler = EncryptTypeHandler.class)
private String password;
}

View File

@@ -5,8 +5,6 @@ import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
import java.io.InputStream;
/**
* 文件表
* 每次文件上传,都会记录一条记录到该表中
@@ -33,6 +31,10 @@ public class FileDO extends BaseDO {
* 关联 {@link FileConfigDO#getId()}
*/
private Long configId;
/**
* 原文件名
*/
private String name;
/**
* 路径,即文件名
*/
@@ -42,9 +44,7 @@ public class FileDO extends BaseDO {
*/
private String url;
/**
* 文件类型
*
* 通过 {@link cn.hutool.core.io.FileTypeUtil#getType(InputStream)} 获取
* 文件的 MIME 类型,例如 "application/octet-stream"
*/
private String type;
/**

View File

@@ -7,7 +7,7 @@ import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
import java.util.Date;
import java.time.LocalDateTime;
/**
* 定时任务的执行日志
@@ -56,11 +56,11 @@ public class JobLogDO extends BaseDO {
/**
* 开始执行时间
*/
private Date beginTime;
private LocalDateTime beginTime;
/**
* 结束执行时间
*/
private Date endTime;
private LocalDateTime endTime;
/**
* 执行时长,单位:毫秒
*/

View File

@@ -8,7 +8,7 @@ import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
import java.util.Date;
import java.time.LocalDateTime;
/**
* API 访问日志
@@ -84,11 +84,11 @@ public class ApiAccessLogDO extends BaseDO {
/**
* 开始请求时间
*/
private Date beginTime;
private LocalDateTime beginTime;
/**
* 结束请求时间
*/
private Date endTime;
private LocalDateTime endTime;
/**
* 执行时长,单位:毫秒
*/

View File

@@ -8,7 +8,7 @@ import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
import java.util.Date;
import java.time.LocalDateTime;
/**
* API 异常数据
@@ -84,7 +84,7 @@ public class ApiErrorLogDO extends BaseDO {
/**
* 异常发生时间
*/
private Date exceptionTime;
private LocalDateTime exceptionTime;
/**
* 异常名
*
@@ -145,7 +145,7 @@ public class ApiErrorLogDO extends BaseDO {
/**
* 处理时间
*/
private Date processTime;
private LocalDateTime processTime;
/**
* 处理用户编号
*

View File

@@ -21,7 +21,7 @@ public interface CodegenTableMapper extends BaseMapperX<CodegenTableDO> {
return selectPage(pageReqVO, new LambdaQueryWrapperX<CodegenTableDO>()
.likeIfPresent(CodegenTableDO::getTableName, pageReqVO.getTableName())
.likeIfPresent(CodegenTableDO::getTableComment, pageReqVO.getTableComment())
.betweenIfPresent(CodegenTableDO::getCreateTime, pageReqVO.getBeginCreateTime(), pageReqVO.getEndCreateTime()));
.betweenIfPresent(CodegenTableDO::getCreateTime, pageReqVO.getCreateTime()));
}
default List<CodegenTableDO> selectListByDataSourceConfigId(Long dataSourceConfigId) {

View File

@@ -1,41 +0,0 @@
package cn.iocoder.yudao.module.infra.dal.mysql.config;
import cn.iocoder.yudao.framework.apollo.internals.ConfigFrameworkDAO;
import cn.iocoder.yudao.framework.apollo.internals.dto.ConfigRespDTO;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import javax.sql.DataSource;
import java.util.Date;
import java.util.List;
/**
* ConfigDAOImpl 实现类
*
* @author 芋道源码
*/
public class ConfigDAOImpl implements ConfigFrameworkDAO {
private final JdbcTemplate jdbcTemplate;
public ConfigDAOImpl(String jdbcUrl, String username, String password) {
DataSource dataSource = new DriverManagerDataSource(jdbcUrl, username, password);
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
@Override
public int selectCountByUpdateTimeGt(Date maxUpdateTime) {
return jdbcTemplate.queryForObject("SELECT COUNT(*) FROM infra_config WHERE update_time > ?",
Integer.class, maxUpdateTime);
}
@Override
public List<ConfigRespDTO> selectList() {
return jdbcTemplate.query("SELECT config_key, value, update_time, deleted FROM infra_config",
(rs, rowNum) -> new ConfigRespDTO().setKey(rs.getString("config_key"))
.setValue(rs.getString("value"))
.setUpdateTime(rs.getDate("update_time"))
.setDeleted(rs.getBoolean("deleted")));
}
}

View File

@@ -22,7 +22,7 @@ public interface ConfigMapper extends BaseMapperX<ConfigDO> {
.likeIfPresent(ConfigDO::getName, reqVO.getName())
.likeIfPresent(ConfigDO::getConfigKey, reqVO.getKey())
.eqIfPresent(ConfigDO::getType, reqVO.getType())
.betweenIfPresent(ConfigDO::getCreateTime, reqVO.getBeginTime(), reqVO.getEndTime()));
.betweenIfPresent(ConfigDO::getCreateTime, reqVO.getCreateTime()));
}
default List<ConfigDO> selectList(ConfigExportReqVO reqVO) {
@@ -30,7 +30,7 @@ public interface ConfigMapper extends BaseMapperX<ConfigDO> {
.likeIfPresent(ConfigDO::getName, reqVO.getName())
.likeIfPresent(ConfigDO::getConfigKey, reqVO.getKey())
.eqIfPresent(ConfigDO::getType, reqVO.getType())
.betweenIfPresent(ConfigDO::getCreateTime, reqVO.getBeginTime(), reqVO.getEndTime()));
.betweenIfPresent(ConfigDO::getCreateTime, reqVO.getCreateTime()));
}
}

View File

@@ -8,7 +8,7 @@ import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileConfigDO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.Date;
import java.time.LocalDateTime;
/**
* 文件配置 Mapper
@@ -22,11 +22,11 @@ public interface FileConfigMapper extends BaseMapperX<FileConfigDO> {
return selectPage(reqVO, new LambdaQueryWrapperX<FileConfigDO>()
.likeIfPresent(FileConfigDO::getName, reqVO.getName())
.eqIfPresent(FileConfigDO::getStorage, reqVO.getStorage())
.betweenIfPresent(FileConfigDO::getCreateTime, reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
.betweenIfPresent(FileConfigDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(FileConfigDO::getId));
}
@Select("SELECT COUNT(*) FROM infra_file_config WHERE update_time > #{maxUpdateTime}")
Long selectCountByUpdateTimeGt(Date maxUpdateTime);
Long selectCountByUpdateTimeGt(LocalDateTime maxUpdateTime);
}

View File

@@ -19,7 +19,7 @@ public interface FileMapper extends BaseMapperX<FileDO> {
return selectPage(reqVO, new LambdaQueryWrapperX<FileDO>()
.likeIfPresent(FileDO::getPath, reqVO.getPath())
.likeIfPresent(FileDO::getType, reqVO.getType())
.betweenIfPresent(FileDO::getCreateTime, reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
.betweenIfPresent(FileDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(FileDO::getId));
}

View File

@@ -1,10 +1,10 @@
package cn.iocoder.yudao.module.infra.dal.mysql.logger;
import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apiaccesslog.ApiAccessLogExportReqVO;
import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apiaccesslog.ApiAccessLogPageReqVO;
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.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apiaccesslog.ApiAccessLogExportReqVO;
import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apiaccesslog.ApiAccessLogPageReqVO;
import cn.iocoder.yudao.module.infra.dal.dataobject.logger.ApiAccessLogDO;
import org.apache.ibatis.annotations.Mapper;
@@ -19,28 +19,28 @@ import java.util.List;
public interface ApiAccessLogMapper extends BaseMapperX<ApiAccessLogDO> {
default PageResult<ApiAccessLogDO> selectPage(ApiAccessLogPageReqVO reqVO) {
return selectPage(reqVO, new QueryWrapperX<ApiAccessLogDO>()
.eqIfPresent("user_id", reqVO.getUserId())
.eqIfPresent("user_type", reqVO.getUserType())
.eqIfPresent("application_name", reqVO.getApplicationName())
.likeIfPresent("request_url", reqVO.getRequestUrl())
.betweenIfPresent("begin_time", reqVO.getBeginBeginTime(), reqVO.getEndBeginTime())
.geIfPresent("duration", reqVO.getDuration())
.eqIfPresent("result_code", reqVO.getResultCode())
.orderByDesc("id")
return selectPage(reqVO, new LambdaQueryWrapperX<ApiAccessLogDO>()
.eqIfPresent(ApiAccessLogDO::getUserId, reqVO.getUserId())
.eqIfPresent(ApiAccessLogDO::getUserType, reqVO.getUserType())
.eqIfPresent(ApiAccessLogDO::getApplicationName, reqVO.getApplicationName())
.likeIfPresent(ApiAccessLogDO::getRequestUrl, reqVO.getRequestUrl())
.betweenIfPresent(ApiAccessLogDO::getBeginTime, reqVO.getBeginTime())
.geIfPresent(ApiAccessLogDO::getDuration, reqVO.getDuration())
.eqIfPresent(ApiAccessLogDO::getResultCode, reqVO.getResultCode())
.orderByDesc(ApiAccessLogDO::getId)
);
}
default List<ApiAccessLogDO> selectList(ApiAccessLogExportReqVO reqVO) {
return selectList(new QueryWrapperX<ApiAccessLogDO>()
.eqIfPresent("user_id", reqVO.getUserId())
.eqIfPresent("user_type", reqVO.getUserType())
.eqIfPresent("application_name", reqVO.getApplicationName())
.likeIfPresent("request_url", reqVO.getRequestUrl())
.betweenIfPresent("begin_time", reqVO.getBeginBeginTime(), reqVO.getEndBeginTime())
.geIfPresent("duration", reqVO.getDuration())
.eqIfPresent("result_code", reqVO.getResultCode())
.orderByDesc("id")
return selectList(new LambdaQueryWrapperX<ApiAccessLogDO>()
.eqIfPresent(ApiAccessLogDO::getUserId, reqVO.getUserId())
.eqIfPresent(ApiAccessLogDO::getUserType, reqVO.getUserType())
.eqIfPresent(ApiAccessLogDO::getApplicationName, reqVO.getApplicationName())
.likeIfPresent(ApiAccessLogDO::getRequestUrl, reqVO.getRequestUrl())
.betweenIfPresent(ApiAccessLogDO::getBeginTime, reqVO.getBeginTime())
.geIfPresent(ApiAccessLogDO::getDuration, reqVO.getDuration())
.eqIfPresent(ApiAccessLogDO::getResultCode, reqVO.getResultCode())
.orderByDesc(ApiAccessLogDO::getId)
);
}

View File

@@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.infra.dal.mysql.logger;
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.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apierrorlog.ApiErrorLogExportReqVO;
import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apierrorlog.ApiErrorLogPageReqVO;
import cn.iocoder.yudao.module.infra.dal.dataobject.logger.ApiErrorLogDO;
@@ -19,26 +19,26 @@ import java.util.List;
public interface ApiErrorLogMapper extends BaseMapperX<ApiErrorLogDO> {
default PageResult<ApiErrorLogDO> selectPage(ApiErrorLogPageReqVO reqVO) {
return selectPage(reqVO, new QueryWrapperX<ApiErrorLogDO>()
.eqIfPresent("user_id", reqVO.getUserId())
.eqIfPresent("user_type", reqVO.getUserType())
.eqIfPresent("application_name", reqVO.getApplicationName())
.likeIfPresent("request_url", reqVO.getRequestUrl())
.betweenIfPresent("exception_time", reqVO.getBeginExceptionTime(), reqVO.getEndExceptionTime())
.eqIfPresent("process_status", reqVO.getProcessStatus())
.orderByDesc("id")
return selectPage(reqVO, new LambdaQueryWrapperX<ApiErrorLogDO>()
.eqIfPresent(ApiErrorLogDO::getUserId, reqVO.getUserId())
.eqIfPresent(ApiErrorLogDO::getUserType, reqVO.getUserType())
.eqIfPresent(ApiErrorLogDO::getApplicationName, reqVO.getApplicationName())
.likeIfPresent(ApiErrorLogDO::getRequestUrl, reqVO.getRequestUrl())
.betweenIfPresent(ApiErrorLogDO::getExceptionTime, reqVO.getExceptionTime())
.eqIfPresent(ApiErrorLogDO::getProcessStatus, reqVO.getProcessStatus())
.orderByDesc(ApiErrorLogDO::getId)
);
}
default List<ApiErrorLogDO> selectList(ApiErrorLogExportReqVO reqVO) {
return selectList(new QueryWrapperX<ApiErrorLogDO>()
.eqIfPresent("user_id", reqVO.getUserId())
.eqIfPresent("user_type", reqVO.getUserType())
.eqIfPresent("application_name", reqVO.getApplicationName())
.likeIfPresent("request_url", reqVO.getRequestUrl())
.betweenIfPresent("exception_time", reqVO.getBeginExceptionTime(), reqVO.getEndExceptionTime())
.eqIfPresent("process_status", reqVO.getProcessStatus())
.orderByDesc("id")
return selectList(new LambdaQueryWrapperX<ApiErrorLogDO>()
.eqIfPresent(ApiErrorLogDO::getUserId, reqVO.getUserId())
.eqIfPresent(ApiErrorLogDO::getUserType, reqVO.getUserType())
.eqIfPresent(ApiErrorLogDO::getApplicationName, reqVO.getApplicationName())
.likeIfPresent(ApiErrorLogDO::getRequestUrl, reqVO.getRequestUrl())
.betweenIfPresent(ApiErrorLogDO::getExceptionTime, reqVO.getExceptionTime())
.eqIfPresent(ApiErrorLogDO::getProcessStatus, reqVO.getProcessStatus())
.orderByDesc(ApiErrorLogDO::getId)
);
}

View File

@@ -25,7 +25,7 @@ public interface TestDemoMapper extends BaseMapperX<TestDemoDO> {
.eqIfPresent(TestDemoDO::getType, reqVO.getType())
.eqIfPresent(TestDemoDO::getCategory, reqVO.getCategory())
.eqIfPresent(TestDemoDO::getRemark, reqVO.getRemark())
.betweenIfPresent(TestDemoDO::getCreateTime, reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
.betweenIfPresent(TestDemoDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(TestDemoDO::getId));
}
@@ -36,7 +36,7 @@ public interface TestDemoMapper extends BaseMapperX<TestDemoDO> {
.eqIfPresent(TestDemoDO::getType, reqVO.getType())
.eqIfPresent(TestDemoDO::getCategory, reqVO.getCategory())
.eqIfPresent(TestDemoDO::getRemark, reqVO.getRemark())
.betweenIfPresent(TestDemoDO::getCreateTime, reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
.betweenIfPresent(TestDemoDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(TestDemoDO::getId));
}

View File

@@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.infra.framework.codegen.config;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(CodegenProperties.class)
public class CodegenConfiguration {
}

View File

@@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.infra.framework.monitor.config;
import de.codecentric.boot.admin.server.config.EnableAdminServer;
import org.springframework.context.annotation.Configuration;
@Configuration
@Configuration(proxyBeanMethods = false)
@EnableAdminServer
public class AdminServerConfiguration {
}

View File

@@ -10,7 +10,7 @@ import org.springframework.security.config.annotation.web.configurers.Expression
/**
* Infra 模块的 Security 配置
*/
@Configuration("infraSecurityConfiguration")
@Configuration(proxyBeanMethods = false, value = "infraSecurityConfiguration")
public class SecurityConfiguration {
@Value("${spring.boot.admin.context-path:''}")
@@ -27,6 +27,8 @@ public class SecurityConfiguration {
.antMatchers("/swagger-resources/**").anonymous()
.antMatchers("/webjars/**").anonymous()
.antMatchers("/*/api-docs").anonymous();
// 积木报表
registry.antMatchers("/jmreport/**").permitAll();
// Spring Boot Actuator 的安全配置
registry.antMatchers("/actuator").anonymous()
.antMatchers("/actuator/**").anonymous();
@@ -35,8 +37,8 @@ public class SecurityConfiguration {
// Spring Boot Admin Server 的安全配置
registry.antMatchers(adminSeverContextPath).anonymous()
.antMatchers(adminSeverContextPath + "/**").anonymous();
// 文件的获取接口,可匿名访问
registry.antMatchers(buildAdminApi("/infra/file/*/get/**"), buildAppApi("/infra/file/get/**")).permitAll();
// 文件读取
registry.antMatchers(buildAdminApi("/infra/file/*/get/**")).permitAll();
}
};

View File

@@ -1,24 +0,0 @@
package cn.iocoder.yudao.module.infra.mq.consumer.config;
import cn.iocoder.yudao.framework.apollo.internals.DBConfigRepository;
import cn.iocoder.yudao.framework.mq.core.pubsub.AbstractChannelMessageListener;
import cn.iocoder.yudao.module.infra.mq.message.config.ConfigRefreshMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
* 针对 {@link ConfigRefreshMessage} 的消费者
*
* @author 芋道源码
*/
@Component
@Slf4j
public class ConfigRefreshConsumer extends AbstractChannelMessageListener<ConfigRefreshMessage> {
@Override
public void onMessage(ConfigRefreshMessage message) {
log.info("[onMessage][收到 Config 刷新消息]");
DBConfigRepository.noticeSync();
}
}

View File

@@ -0,0 +1,4 @@
/**
* 占位符,避免缩进
*/
package cn.iocoder.yudao.module.infra.mq.consumer;

View File

@@ -1,17 +0,0 @@
package cn.iocoder.yudao.module.infra.mq.message.config;
import cn.iocoder.yudao.framework.mq.core.pubsub.AbstractChannelMessage;
import lombok.Data;
/**
* 配置数据刷新 Message
*/
@Data
public class ConfigRefreshMessage extends AbstractChannelMessage {
@Override
public String getChannel() {
return "infra.config.refresh";
}
}

View File

@@ -0,0 +1,4 @@
/**
* 占位符,避免缩进
*/
package cn.iocoder.yudao.module.infra.mq.message;

View File

@@ -1,26 +0,0 @@
package cn.iocoder.yudao.module.infra.mq.producer.config;
import cn.iocoder.yudao.module.infra.mq.message.config.ConfigRefreshMessage;
import cn.iocoder.yudao.framework.mq.core.RedisMQTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* Config 配置相关消息的 Producer
*/
@Component
public class ConfigProducer {
@Resource
private RedisMQTemplate redisMQTemplate;
/**
* 发送 {@link ConfigRefreshMessage} 消息
*/
public void sendConfigRefreshMessage() {
ConfigRefreshMessage message = new ConfigRefreshMessage();
redisMQTemplate.send(message);
}
}

View File

@@ -0,0 +1,4 @@
/**
* 占位符,避免缩进
*/
package cn.iocoder.yudao.module.infra.mq.producer;

View File

@@ -28,6 +28,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.BiPredicate;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -154,12 +155,27 @@ public class CodegenServiceImpl implements CodegenService {
// 构建 CodegenColumnDO 数组,只同步新增的字段
List<CodegenColumnDO> codegenColumns = codegenColumnMapper.selectListByTableId(tableId);
Set<String> codegenColumnNames = CollectionUtils.convertSet(codegenColumns, CodegenColumnDO::getColumnName);
// 移除已经存在的字段
tableFields.removeIf(column -> codegenColumnNames.contains(column.getColumnName()));
//计算需要修改的字段,插入时重新插入,删除时将原来的删除
BiPredicate<TableField, CodegenColumnDO> pr =
(tableField, codegenColumn) -> tableField.getType().equals(codegenColumn.getDataType())
&& tableField.getMetaInfo().isNullable() == codegenColumn.getNullable()
&& tableField.isKeyFlag() == codegenColumn.getPrimaryKey()
&& tableField.getComment().equals(codegenColumn.getColumnComment());
Map<String, CodegenColumnDO> codegenColumnDOMap = CollectionUtils.convertMap(codegenColumns, CodegenColumnDO::getColumnName);
//需要修改的字段
Set<String> modifyFieldNames = tableFields.stream()
.filter(tableField -> codegenColumnDOMap.get(tableField.getColumnName()) != null
&& !pr.test(tableField, codegenColumnDOMap.get(tableField.getColumnName())))
.map(TableField::getColumnName)
.collect(Collectors.toSet());
// 计算需要删除的字段
Set<String> tableFieldNames = CollectionUtils.convertSet(tableFields, TableField::getName);
Set<Long> deleteColumnIds = codegenColumns.stream().filter(column -> !tableFieldNames.contains(column.getColumnName()))
Set<Long> deleteColumnIds = codegenColumns.stream()
.filter(column -> (!tableFieldNames.contains(column.getColumnName())) || modifyFieldNames.contains(column.getColumnName()))
.map(CodegenColumnDO::getId).collect(Collectors.toSet());
// 移除已经存在的字段
tableFields.removeIf(column -> codegenColumnNames.contains(column.getColumnName()) && (!modifyFieldNames.contains(column.getColumnName())));
if (CollUtil.isEmpty(tableFields) && CollUtil.isEmpty(deleteColumnIds)) {
throw exception(CODEGEN_SYNC_NONE_CHANGE);
}
@@ -206,7 +222,7 @@ public class CodegenServiceImpl implements CodegenService {
public Map<String, String> generationCodes(Long tableId) {
// 校验是否已经存在
CodegenTableDO table = codegenTableMapper.selectById(tableId);
if (codegenTableMapper.selectById(tableId) == null) {
if (table == null) {
throw exception(CODEGEN_TABLE_NOT_EXISTS);
}
List<CodegenColumnDO> columns = codegenColumnMapper.selectListByTableId(tableId);

View File

@@ -31,7 +31,7 @@ public class CodegenBuilder {
* 字段名与 {@link CodegenColumnListConditionEnum} 的默认映射
* 注意,字段的匹配以后缀的方式
*/
private static final Map<String, CodegenColumnListConditionEnum> columnListOperationConditionMappings =
private static final Map<String, CodegenColumnListConditionEnum> COLUMN_LIST_OPERATION_CONDITION_MAPPINGS =
MapUtil.<String, CodegenColumnListConditionEnum>builder()
.put("name", CodegenColumnListConditionEnum.LIKE)
.put("time", CodegenColumnListConditionEnum.BETWEEN)
@@ -42,7 +42,7 @@ public class CodegenBuilder {
* 字段名与 {@link CodegenColumnHtmlTypeEnum} 的默认映射
* 注意,字段的匹配以后缀的方式
*/
private static final Map<String, CodegenColumnHtmlTypeEnum> columnHtmlTypeMappings =
private static final Map<String, CodegenColumnHtmlTypeEnum> COLUMN_HTML_TYPE_MAPPINGS =
MapUtil.<String, CodegenColumnHtmlTypeEnum>builder()
.put("status", CodegenColumnHtmlTypeEnum.RADIO)
.put("sex", CodegenColumnHtmlTypeEnum.RADIO)
@@ -143,7 +143,7 @@ public class CodegenBuilder {
column.setListOperation(!LIST_OPERATION_EXCLUDE_COLUMN.contains(column.getJavaField())
&& !column.getPrimaryKey()); // 对于主键,列表过滤不需要传递
// 处理 listOperationCondition 字段
columnListOperationConditionMappings.entrySet().stream()
COLUMN_LIST_OPERATION_CONDITION_MAPPINGS.entrySet().stream()
.filter(entry -> StrUtil.endWithIgnoreCase(column.getJavaField(), entry.getKey()))
.findFirst().ifPresent(entry -> column.setListOperationCondition(entry.getValue().getCondition()));
if (column.getListOperationCondition() == null) {
@@ -155,7 +155,7 @@ public class CodegenBuilder {
private void processColumnUI(CodegenColumnDO column) {
// 基于后缀进行匹配
columnHtmlTypeMappings.entrySet().stream()
COLUMN_HTML_TYPE_MAPPINGS.entrySet().stream()
.filter(entry -> StrUtil.endWithIgnoreCase(column.getJavaField(), entry.getKey()))
.findFirst().ifPresent(entry -> column.setHtmlType(entry.getValue().getType()));
// 如果是 Boolean 类型时,设置为 radio 类型.

View File

@@ -79,11 +79,18 @@ public class CodegenEngine {
javaModuleImplTestFilePath("service/${table.businessName}/${table.className}ServiceImplTest"))
// Java module-api Main
.put(javaTemplatePath("enums/errorcode"), javaModuleApiMainFilePath("enums/ErrorCodeConstants_手动操作"))
// Vue
// Vue2
.put(vueTemplatePath("views/index.vue"),
vueFilePath("views/${table.moduleName}/${classNameVar}/index.vue"))
.put(vueTemplatePath("api/api.js"),
vueFilePath("api/${table.moduleName}/${classNameVar}.js"))
// Vue3
.put(vue3TemplatePath("views/index.vue"),
vue3FilePath("views/${table.moduleName}/${classNameVar}/index.vue"))
.put(vue3TemplatePath("views/data.ts"),
vue3FilePath("views/${table.moduleName}/${classNameVar}/${classNameVar}.data.ts"))
.put(vue3TemplatePath("api/api.ts"),
vue3FilePath("api/${table.moduleName}/${classNameVar}/index.ts"))
// SQL
.put("codegen/sql/sql.vm", "sql/sql.sql")
.put("codegen/sql/h2.vm", "sql/h2.sql")
@@ -228,5 +235,12 @@ public class CodegenEngine {
return "yudao-ui-${sceneEnum.basePackage}/" + // 顶级目录
"src/" + path;
}
private static String vue3TemplatePath(String path) {
return "codegen/vue3/" + path + ".vm";
}
private static String vue3FilePath(String path) {
return "yudao-ui-${sceneEnum.basePackage}-vue3/" + // 顶级目录
"src/" + path;
}
}

View File

@@ -1,7 +1,6 @@
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;
@@ -12,7 +11,6 @@ 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;
@@ -21,6 +19,8 @@ import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.util.List;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
/**
* 参数配置 Service 实现类
*/
@@ -32,9 +32,6 @@ public class ConfigServiceImpl implements ConfigService {
@Resource
private ConfigMapper configMapper;
@Resource
private ConfigProducer configProducer;
@Override
public Long createConfig(ConfigCreateReqVO reqVO) {
// 校验正确性
@@ -43,8 +40,6 @@ public class ConfigServiceImpl implements ConfigService {
ConfigDO config = ConfigConvert.INSTANCE.convert(reqVO);
config.setType(ConfigTypeEnum.CUSTOM.getType());
configMapper.insert(config);
// 发送刷新消息
configProducer.sendConfigRefreshMessage();
return config.getId();
}
@@ -54,9 +49,7 @@ public class ConfigServiceImpl implements ConfigService {
checkCreateOrUpdate(reqVO.getId(), null); // 不允许更新 key
// 更新参数配置
ConfigDO updateObj = ConfigConvert.INSTANCE.convert(reqVO);
configMapper.updateById(updateObj);
// 发送刷新消息
configProducer.sendConfigRefreshMessage();
configMapper.updateById(updateObj);;
}
@Override
@@ -65,12 +58,10 @@ public class ConfigServiceImpl implements ConfigService {
ConfigDO config = checkConfigExists(id);
// 内置配置,不允许删除
if (ConfigTypeEnum.SYSTEM.getType().equals(config.getType())) {
throw ServiceExceptionUtil.exception(ErrorCodeConstants.CONFIG_CAN_NOT_DELETE_SYSTEM_TYPE);
throw exception(ErrorCodeConstants.CONFIG_CAN_NOT_DELETE_SYSTEM_TYPE);
}
// 删除
configMapper.deleteById(id);
// 发送刷新消息
configProducer.sendConfigRefreshMessage();
}
@Override
@@ -109,7 +100,7 @@ public class ConfigServiceImpl implements ConfigService {
}
ConfigDO config = configMapper.selectById(id);
if (config == null) {
throw ServiceExceptionUtil.exception(ErrorCodeConstants.CONFIG_NOT_EXISTS);
throw exception(ErrorCodeConstants.CONFIG_NOT_EXISTS);
}
return config;
}
@@ -122,10 +113,10 @@ public class ConfigServiceImpl implements ConfigService {
}
// 如果 id 为空,说明不用比较是否为相同 id 的参数配置
if (id == null) {
throw ServiceExceptionUtil.exception(ErrorCodeConstants.CONFIG_KEY_DUPLICATE);
throw exception(ErrorCodeConstants.CONFIG_KEY_DUPLICATE);
}
if (!config.getId().equals(id)) {
throw ServiceExceptionUtil.exception(ErrorCodeConstants.CONFIG_KEY_DUPLICATE);
throw exception(ErrorCodeConstants.CONFIG_KEY_DUPLICATE);
}
}

View File

@@ -8,7 +8,6 @@ import cn.iocoder.yudao.module.infra.dal.dataobject.db.DataSourceConfigDO;
import cn.iocoder.yudao.module.infra.dal.mysql.db.DataSourceConfigMapper;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties;
import org.jasypt.encryption.StringEncryptor;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
@@ -32,9 +31,6 @@ public class DataSourceConfigServiceImpl implements DataSourceConfigService {
@Resource
private DataSourceConfigMapper dataSourceConfigMapper;
@Resource
private StringEncryptor stringEncryptor;
@Resource
private DynamicDataSourceProperties dynamicDataSourceProperties;
@@ -44,7 +40,6 @@ public class DataSourceConfigServiceImpl implements DataSourceConfigService {
checkConnectionOK(dataSourceConfig);
// 插入
dataSourceConfig.setPassword(stringEncryptor.encrypt(createReqVO.getPassword()));
dataSourceConfigMapper.insert(dataSourceConfig);
// 返回
return dataSourceConfig.getId();
@@ -58,7 +53,6 @@ public class DataSourceConfigServiceImpl implements DataSourceConfigService {
checkConnectionOK(updateObj);
// 更新
updateObj.setPassword(stringEncryptor.encrypt(updateObj.getPassword()));
dataSourceConfigMapper.updateById(updateObj);
}
@@ -83,12 +77,7 @@ public class DataSourceConfigServiceImpl implements DataSourceConfigService {
return buildMasterDataSourceConfig();
}
// 从 DB 中读取
DataSourceConfigDO dataSourceConfig = dataSourceConfigMapper.selectById(id);
try {
dataSourceConfig.setPassword(stringEncryptor.decrypt(dataSourceConfig.getPassword()));
} catch (Exception ignore) { // 解码失败,则不解码
}
return dataSourceConfig;
return dataSourceConfigMapper.selectById(id);
}
@Override

View File

@@ -53,7 +53,7 @@ public class DatabaseTableServiceImpl implements DatabaseTableService {
if (StrUtil.isNotEmpty(name)) {
strategyConfig.addInclude(name);
}
GlobalConfig globalConfig = new GlobalConfig.Builder().dateType(DateType.ONLY_DATE).build(); // 只使用 Date 类型,不使用 LocalDate
GlobalConfig globalConfig = new GlobalConfig.Builder().dateType(DateType.TIME_PACK).build(); // 只使用 Date 类型,不使用 LocalDate
ConfigBuilder builder = new ConfigBuilder(null, dataSourceConfig, strategyConfig.build(),
null, globalConfig, null);
// 按照名字排序

View File

@@ -31,8 +31,8 @@ import org.springframework.validation.annotation.Validated;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.validation.Validator;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
@@ -60,7 +60,7 @@ public class FileConfigServiceImpl implements FileConfigService {
* 缓存菜单的最大更新时间,用于后续的增量轮询,判断是否有更新
*/
@Getter
private volatile Date maxUpdateTime;
private volatile LocalDateTime maxUpdateTime;
@Resource
private FileClientFactory fileClientFactory;
@@ -118,7 +118,7 @@ public class FileConfigServiceImpl implements FileConfigService {
* @param maxUpdateTime 当前文件配置的最大更新时间
* @return 文件配置列表
*/
private List<FileConfigDO> loadFileConfigIfUpdate(Date maxUpdateTime) {
private List<FileConfigDO> loadFileConfigIfUpdate(LocalDateTime maxUpdateTime) {
// 第一步,判断是否要更新。
if (maxUpdateTime == null) { // 如果更新时间为空,说明 DB 一定有新数据
log.info("[loadFileConfigIfUpdate][首次加载全量文件配置]");
@@ -230,7 +230,7 @@ public class FileConfigServiceImpl implements FileConfigService {
this.validateFileConfigExists(id);
// 上传文件
byte[] content = ResourceUtil.readBytes("file/erweima.jpg");
return fileClientFactory.getFileClient(id).upload(content, IdUtil.fastSimpleUUID() + ".jpg");
return fileClientFactory.getFileClient(id).upload(content, IdUtil.fastSimpleUUID() + ".jpg", "image/jpeg");
}
@Override

View File

@@ -22,11 +22,12 @@ public interface FileService {
/**
* 保存文件,并返回文件的访问路径
*
* @param name 文件名称
* @param path 文件路径
* @param content 文件内容
* @return 文件路径
*/
String createFile(String path, byte[] content) throws Exception;
String createFile(String name, String path, byte[] content);
/**
* 删除文件

View File

@@ -1,16 +1,18 @@
package cn.iocoder.yudao.module.infra.service.file;
import cn.hutool.core.io.FileTypeUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.io.FileUtils;
import cn.iocoder.yudao.framework.file.core.client.FileClient;
import cn.iocoder.yudao.framework.file.core.utils.FileTypeUtils;
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FilePageReqVO;
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO;
import cn.iocoder.yudao.module.infra.dal.mysql.file.FileMapper;
import lombok.SneakyThrows;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.FILE_NOT_EXISTS;
@@ -35,18 +37,30 @@ public class FileServiceImpl implements FileService {
}
@Override
public String createFile(String path, byte[] content) throws Exception {
@SneakyThrows
public String createFile(String name, String path, byte[] content) {
// 计算默认的 path 名
String type = FileTypeUtils.getMineType(content, name);
if (StrUtil.isEmpty(path)) {
path = FileUtils.generatePath(content, name);
}
// 如果 name 为空,则使用 path 填充
if (StrUtil.isEmpty(name)) {
name = path;
}
// 上传到文件存储器
FileClient client = fileConfigService.getMasterFileClient();
Assert.notNull(client, "客户端(master) 不能为空");
String url = client.upload(content, path);
String url = client.upload(content, path, type);
// 保存到数据库
FileDO file = new FileDO();
file.setConfigId(client.getId());
file.setName(name);
file.setPath(path);
file.setUrl(url);
file.setType(FileTypeUtil.getType(new ByteArrayInputStream(content)));
file.setType(type);
file.setSize(content.length);
fileMapper.insert(file);
return url;

View File

@@ -12,8 +12,8 @@ import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.Date;
import java.util.List;
/**
@@ -30,7 +30,7 @@ public class JobLogServiceImpl implements JobLogService {
private JobLogMapper jobLogMapper;
@Override
public Long createJobLog(Long jobId, Date beginTime, String jobHandlerName, String jobHandlerParam, Integer executeIndex) {
public Long createJobLog(Long jobId, LocalDateTime 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);
@@ -39,7 +39,7 @@ public class JobLogServiceImpl implements JobLogService {
@Override
@Async
public void updateJobLogResultAsync(Long logId, Date endTime, Integer duration, boolean success, String result) {
public void updateJobLogResultAsync(Long logId, LocalDateTime 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();

View File

@@ -1,9 +1,9 @@
package cn.iocoder.yudao.module.infra.service.logger;
import cn.iocoder.yudao.framework.apilog.core.service.ApiAccessLogFrameworkService;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.infra.api.logger.dto.ApiAccessLogCreateReqDTO;
import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apiaccesslog.ApiAccessLogExportReqVO;
import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apiaccesslog.ApiAccessLogPageReqVO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.infra.dal.dataobject.logger.ApiAccessLogDO;
import java.util.List;
@@ -13,7 +13,14 @@ import java.util.List;
*
* @author 芋道源码
*/
public interface ApiAccessLogService extends ApiAccessLogFrameworkService {
public interface ApiAccessLogService {
/**
* 创建 API 访问日志
*
* @param createReqDTO API 访问日志
*/
void createApiAccessLog(ApiAccessLogCreateReqDTO createReqDTO);
/**
* 获得 API 访问日志分页

View File

@@ -1,13 +1,12 @@
package cn.iocoder.yudao.module.infra.service.logger;
import cn.iocoder.yudao.framework.apilog.core.service.dto.ApiAccessLogCreateReqDTO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.infra.api.logger.dto.ApiAccessLogCreateReqDTO;
import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apiaccesslog.ApiAccessLogExportReqVO;
import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apiaccesslog.ApiAccessLogPageReqVO;
import cn.iocoder.yudao.module.infra.convert.logger.ApiAccessLogConvert;
import cn.iocoder.yudao.module.infra.dal.dataobject.logger.ApiAccessLogDO;
import cn.iocoder.yudao.module.infra.dal.mysql.logger.ApiAccessLogMapper;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
@@ -26,6 +25,12 @@ public class ApiAccessLogServiceImpl implements ApiAccessLogService {
@Resource
private ApiAccessLogMapper apiAccessLogMapper;
@Override
public void createApiAccessLog(ApiAccessLogCreateReqDTO createDTO) {
ApiAccessLogDO apiAccessLog = ApiAccessLogConvert.INSTANCE.convert(createDTO);
apiAccessLogMapper.insert(apiAccessLog);
}
@Override
public PageResult<ApiAccessLogDO> getApiAccessLogPage(ApiAccessLogPageReqVO pageReqVO) {
return apiAccessLogMapper.selectPage(pageReqVO);
@@ -36,11 +41,4 @@ public class ApiAccessLogServiceImpl implements ApiAccessLogService {
return apiAccessLogMapper.selectList(exportReqVO);
}
@Override
@Async
public void createApiAccessLogAsync(ApiAccessLogCreateReqDTO createDTO) {
ApiAccessLogDO apiAccessLog = ApiAccessLogConvert.INSTANCE.convert(createDTO);
apiAccessLogMapper.insert(apiAccessLog);
}
}

View File

@@ -1,7 +1,7 @@
package cn.iocoder.yudao.module.infra.service.logger;
import cn.iocoder.yudao.framework.apilog.core.service.ApiErrorLogFrameworkService;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.infra.api.logger.dto.ApiErrorLogCreateReqDTO;
import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apierrorlog.ApiErrorLogExportReqVO;
import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apierrorlog.ApiErrorLogPageReqVO;
import cn.iocoder.yudao.module.infra.dal.dataobject.logger.ApiErrorLogDO;
@@ -13,7 +13,14 @@ import java.util.List;
*
* @author 芋道源码
*/
public interface ApiErrorLogService extends ApiErrorLogFrameworkService {
public interface ApiErrorLogService {
/**
* 创建 API 错误日志
*
* @param createReqDTO API 错误日志
*/
void createApiErrorLog(ApiErrorLogCreateReqDTO createReqDTO);
/**
* 获得 API 错误日志分页

View File

@@ -1,21 +1,20 @@
package cn.iocoder.yudao.module.infra.service.logger;
import cn.iocoder.yudao.framework.apilog.core.service.dto.ApiErrorLogCreateReqDTO;
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.infra.api.logger.dto.ApiErrorLogCreateReqDTO;
import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apierrorlog.ApiErrorLogExportReqVO;
import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apierrorlog.ApiErrorLogPageReqVO;
import cn.iocoder.yudao.module.infra.convert.logger.ApiErrorLogConvert;
import cn.iocoder.yudao.module.infra.dal.dataobject.logger.ApiErrorLogDO;
import cn.iocoder.yudao.module.infra.dal.mysql.logger.ApiErrorLogMapper;
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants;
import cn.iocoder.yudao.module.infra.enums.logger.ApiErrorLogProcessStatusEnum;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.util.Date;
import java.time.LocalDateTime;
import java.util.List;
/**
@@ -30,6 +29,13 @@ public class ApiErrorLogServiceImpl implements ApiErrorLogService {
@Resource
private ApiErrorLogMapper apiErrorLogMapper;
@Override
public void createApiErrorLog(ApiErrorLogCreateReqDTO createDTO) {
ApiErrorLogDO apiErrorLog = ApiErrorLogConvert.INSTANCE.convert(createDTO);
apiErrorLog.setProcessStatus(ApiErrorLogProcessStatusEnum.INIT.getStatus());
apiErrorLogMapper.insert(apiErrorLog);
}
@Override
public PageResult<ApiErrorLogDO> getApiErrorLogPage(ApiErrorLogPageReqVO pageReqVO) {
return apiErrorLogMapper.selectPage(pageReqVO);
@@ -51,15 +57,7 @@ public class ApiErrorLogServiceImpl implements ApiErrorLogService {
}
// 标记处理
apiErrorLogMapper.updateById(ApiErrorLogDO.builder().id(id).processStatus(processStatus)
.processUserId(processUserId).processTime(new Date()).build());
}
@Override
@Async
public void createApiErrorLogAsync(ApiErrorLogCreateReqDTO createDTO) {
ApiErrorLogDO apiErrorLog = ApiErrorLogConvert.INSTANCE.convert(createDTO);
apiErrorLog.setProcessStatus(ApiErrorLogProcessStatusEnum.INIT.getStatus());
apiErrorLogMapper.insert(apiErrorLog);
.processUserId(processUserId).processTime(LocalDateTime.now()).build());
}
}

View File

@@ -7,7 +7,7 @@
@NotNull(message = "${column.columnComment}不能为空")
#end
#end
#if (${column.javaType} == "Date")## 时间类型
#if (${column.javaType} == "LocalDateTime")## 时间类型
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
#end
private ${column.javaType} ${column.javaField};

View File

@@ -2,12 +2,20 @@ package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePac
import lombok.*;
import java.util.*;
#foreach ($column in $columns)
#if (${column.javaType} == "BigDecimal")
import java.math.BigDecimal;
#end
#if (${column.javaType} == "LocalDateTime")
import java.time.LocalDateTime;
#end
#end
import io.swagger.annotations.*;
import javax.validation.constraints.*;
## 处理 Date 字段的引入
#foreach ($column in $columns)
#if (${column.createOperation} && ${column.updateOperation} && ${column.listOperationResult}
&& ${column.javaType} == "Date")## 时间类型
&& ${column.javaType} == "LocalDateTime")## 时间类型
import org.springframework.format.annotation.DateTimeFormat;
import static ${DateUtilsClassName}.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;

View File

@@ -7,9 +7,9 @@ import javax.validation.constraints.*;
## 处理 Date 字段的引入
#foreach ($column in $columns)
#if (${column.createOperation} && (!${column.updateOperation} || !${column.listOperationResult})
&& ${column.javaType} == "Date")## 时间类型
&& ${column.javaType} == "LocalDateTime")## 时间类型
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static ${DateUtilsClassName}.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
#break
#end

View File

@@ -2,6 +2,14 @@ package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePac
import lombok.*;
import java.util.*;
#foreach ($column in $columns)
#if (${column.javaType} == "BigDecimal")
import java.math.BigDecimal;
#end
#if (${column.javaType} == "LocalDateTime")
import java.time.LocalDateTime;
#end
#end
import io.swagger.annotations.*;
import com.alibaba.excel.annotation.ExcelProperty;

View File

@@ -6,7 +6,8 @@ import io.swagger.annotations.*;
import ${PageParamClassName};
## 处理 Date 字段的引入
#foreach ($column in $columns)
#if (${column.listOperation} && ${column.javaType} == "Date")## 时间类型
#if (${column.listOperation} && ${column.javaType} == "LocalDateTime")## 时间类型
import java.time.LocalDateTime;
import org.springframework.format.annotation.DateTimeFormat;
import static ${DateUtilsClassName}.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@@ -15,9 +16,6 @@ import static ${DateUtilsClassName}.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
#end
## 字段模板
#macro(columnTpl $prefix $prefixStr)
#if (${column.javaType} == "Date")## 时间类型
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
#end
@ApiModelProperty(value = "${prefixStr}${column.columnComment}"#if ("$!column.example" != ""), example = "${column.example}"#end)
private ${column.javaType}#if ("$!prefix" != "") ${prefix}${JavaField}#else ${column.javaField}#end;
#end
@@ -27,12 +25,11 @@ import static ${DateUtilsClassName}.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
public class ${sceneEnum.prefixClass}${table.className}ExportReqVO {
#foreach ($column in $columns)
#set ($JavaField = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})##首字母大写
#if (${column.listOperation})##查询操作
#if (${column.listOperationCondition} == "BETWEEN")## 情况一Between 的时候
#columnTpl('begin', '开始')
#columnTpl('end', '结束')
@ApiModelProperty(value = "${column.columnComment}"#if ("$!column.example" != ""), example = "${column.example}"#end)
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private ${column.javaType}[] ${column.javaField};
#else##情况二,非 Between 的时间
#columnTpl('', '')
#end

View File

@@ -6,8 +6,9 @@ import io.swagger.annotations.*;
import ${PageParamClassName};
## 处理 Date 字段的引入
#foreach ($column in $columns)
#if (${column.listOperation} && ${column.javaType} == "Date")## 时间类型
#if (${column.listOperation} && ${column.javaType} == "LocalDateTime")## 时间类型
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static ${DateUtilsClassName}.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
#break
@@ -15,9 +16,6 @@ import static ${DateUtilsClassName}.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
#end
## 字段模板
#macro(columnTpl $prefix $prefixStr)
#if (${column.javaType} == "Date")## 时间类型
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
#end
@ApiModelProperty(value = "${prefixStr}${column.columnComment}"#if ("$!column.example" != ""), example = "${column.example}"#end)
private ${column.javaType}#if ("$!prefix" != "") ${prefix}${JavaField}#else ${column.javaField}#end;
#end
@@ -29,12 +27,11 @@ import static ${DateUtilsClassName}.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
public class ${sceneEnum.prefixClass}${table.className}PageReqVO extends PageParam {
#foreach ($column in $columns)
#set ($JavaField = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})##首字母大写
#if (${column.listOperation})##查询操作
#if (${column.listOperationCondition} == "BETWEEN")## 情况一Between 的时候
#columnTpl('begin', '开始')
#columnTpl('end', '结束')
@ApiModelProperty(value = "${column.columnComment}"#if ("$!column.example" != ""), example = "${column.example}"#end)
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private ${column.javaType}[] ${column.javaField};
#else##情况二,非 Between 的时间
#columnTpl('', '')
#end

View File

@@ -1,7 +1,12 @@
package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo;
import lombok.*;
import java.util.*;
#foreach ($column in $columns)
#if (${column.javaType} == "LocalDateTime")
import java.time.LocalDateTime;
#break
#end
#end
import io.swagger.annotations.*;
@ApiModel("${sceneEnum.name} - ${table.classComment} Response VO")

View File

@@ -7,9 +7,9 @@ import javax.validation.constraints.*;
## 处理 Date 字段的引入
#foreach ($column in $columns)
#if (${column.updateOperation} && (!${column.createOperation} || !${column.listOperationResult})
&& ${column.javaType} == "Date"))## 时间类型
&& ${column.javaType} == "LocalDateTime")## 时间类型
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static ${DateUtilsClassName}.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
#break
#end

View File

@@ -2,6 +2,14 @@ package ${basePackage}.module.${table.moduleName}.dal.dataobject.${table.busines
import lombok.*;
import java.util.*;
#foreach ($column in $columns)
#if (${column.javaType} == "BigDecimal")
import java.math.BigDecimal;
#end
#if (${column.javaType} == "LocalDateTime")
import java.time.LocalDateTime;
#end
#end
import com.baomidou.mybatisplus.annotation.*;
import ${BaseDOClassName};
@@ -30,7 +38,7 @@ public class ${table.className}DO extends BaseDO {
#end
*/
#if (${column.primaryKey})##处理主键
@TableId#if (${column.javaType} == 'String')type = IdType.INPUT)#end
@TableId#if (${column.javaType} == 'String')(type = IdType.INPUT)#end
#end
private ${column.javaType} ${column.javaField};
#end

View File

@@ -36,7 +36,7 @@ import ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePack
.likeIfPresent(${table.className}DO::get${JavaField}, reqVO.get${JavaField}())
#end
#if (${column.listOperationCondition} == "BETWEEN")##情况八Between 的时候
.betweenIfPresent(${table.className}DO::get${JavaField}, reqVO.getBegin${JavaField}(), reqVO.getEnd${JavaField}())
.betweenIfPresent(${table.className}DO::get${JavaField}, reqVO.get${JavaField}())
#end
#end
#end

View File

@@ -16,6 +16,7 @@ import ${PageResultClassName};
import javax.annotation.Resource;
import org.springframework.context.annotation.Import;
import java.util.*;
import java.time.LocalDateTime;
import static cn.hutool.core.util.RandomUtil.*;
import static ${basePackage}.module.${table.moduleName}.enums.ErrorCodeConstants.*;
@@ -51,8 +52,7 @@ import static org.mockito.Mockito.*;
#if (${column.listOperation})
#set ($JavaField = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})##首字母大写
#if (${column.listOperationCondition} == "BETWEEN")## BETWEEN 的情况
reqVO.setBegin${JavaField}(null);
reqVO.setEnd${JavaField}(null);
reqVO.set${JavaField}((new LocalDateTime[]{}));
#else
reqVO.set$JavaField(null);
#end

Some files were not shown because too many files have changed in this diff Show More