init version

This commit is contained in:
terry.wang
2025-12-08 17:13:30 +08:00
commit fd678e6ee7
4715 changed files with 295653 additions and 0 deletions

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4" />

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.jojubanking.boot</groupId>
<artifactId>joju-module-infra</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>joju-module-infra-api</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>
infra 模块 API暴露给其它模块调用
</description>
<dependencies>
<dependency>
<groupId>com.jojubanking.boot</groupId>
<artifactId>joju-common</artifactId>
</dependency>
<!-- 参数校验 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,41 @@
package com.jojubanking.boot.module.infra.api.file;
/**
* 文件 API 接口
*
* @author TW
*/
public interface FileApi {
/**
* 保存文件,并返回文件的访问路径
*
* @param content 文件内容
* @return 文件路径
*/
default String createFile(byte[] content) {
return createFile(null, null, content);
}
/**
* 保存文件,并返回文件的访问路径
*
* @param path 文件路径
* @param content 文件内容
* @return 文件路径
*/
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 com.jojubanking.boot.module.infra.api.logger;
import com.jojubanking.boot.module.infra.api.logger.dto.ApiAccessLogCreateReqDTO;
import javax.validation.Valid;
/**
* API 访问日志的 API 接口
*
* @author TW
*/
public interface ApiAccessLogApi {
/**
* 创建 API 访问日志
*
* @param createDTO 创建信息
*/
void createApiAccessLog(@Valid ApiAccessLogCreateReqDTO createDTO);
}

View File

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

View File

@@ -0,0 +1,85 @@
package com.jojubanking.boot.module.infra.api.logger.dto;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.util.Date;
/**
* API 访问日志
*
* @author TW
*/
@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 Date beginTime;
/**
* 结束请求时间
*/
@NotNull(message = "结束请求时间不能为空")
private Date endTime;
/**
* 执行时长,单位:毫秒
*/
@NotNull(message = "执行时长不能为空")
private Integer duration;
/**
* 结果码
*/
@NotNull(message = "错误码不能为空")
private Integer resultCode;
/**
* 结果提示
*/
private String resultMsg;
}

View File

@@ -0,0 +1,107 @@
package com.jojubanking.boot.module.infra.api.logger.dto;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.util.Date;
/**
* API 错误日志
*
* @author TW
*/
@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 Date 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

@@ -0,0 +1,4 @@
/**
* infra API 包,定义暴露给其它模块的 API
*/
package com.jojubanking.boot.module.infra.api;

View File

@@ -0,0 +1,20 @@
package com.jojubanking.boot.module.infra.enums;
/**
* Infra 字典类型的枚举类
*
* @author TW
*/
public interface DictTypeConstants {
String REDIS_TIMEOUT_TYPE = "infra_redis_timeout_type"; // Redis 超时类型
String JOB_STATUS = "infra_job_status"; // 定时任务状态的枚举
String JOB_LOG_STATUS = "infra_job_log_status"; // 定时任务日志状态的枚举
String API_ERROR_LOG_PROCESS_STATUS = "infra_api_error_log_process_status"; // API 错误日志的处理状态的枚举
String CONFIG_TYPE = "infra_config_type"; // 参数配置类型
String BOOLEAN_STRING = "infra_boolean_string"; // Boolean 是否类型
}

View File

@@ -0,0 +1,57 @@
package com.jojubanking.boot.module.infra.enums;
import com.jojubanking.boot.framework.common.exception.ErrorCode;
/**
* Infra 错误码枚举类
*
* infra 系统,使用 1-001-000-000 段
*/
public interface ErrorCodeConstants {
// ========== 参数配置 1001000000 ==========
ErrorCode CONFIG_NOT_EXISTS = new ErrorCode(1001000001, "参数配置不存在");
ErrorCode CONFIG_KEY_DUPLICATE = new ErrorCode(1001000002, "参数配置 key 重复");
ErrorCode CONFIG_CAN_NOT_DELETE_SYSTEM_TYPE = new ErrorCode(1001000003, "不能删除类型为系统内置的参数配置");
ErrorCode CONFIG_GET_VALUE_ERROR_IF_VISIBLE = new ErrorCode(1001000004, "获取参数配置失败,原因:不允许获取不可见配置");
// ========== 定时任务 1001001000 ==========
ErrorCode JOB_NOT_EXISTS = new ErrorCode(1001001000, "定时任务不存在");
ErrorCode JOB_HANDLER_EXISTS = new ErrorCode(1001001001, "定时任务的处理器已经存在");
ErrorCode JOB_CHANGE_STATUS_INVALID = new ErrorCode(1001001002, "只允许修改为开启或者关闭状态");
ErrorCode JOB_CHANGE_STATUS_EQUALS = new ErrorCode(1001001003, "定时任务已经处于该状态,无需修改");
ErrorCode JOB_UPDATE_ONLY_NORMAL_STATUS = new ErrorCode(1001001004, "只有开启状态的任务,才可以修改");
ErrorCode JOB_CRON_EXPRESSION_VALID = new ErrorCode(1001001005, "CRON 表达式不正确");
// ========== API 错误日志 1001002000 ==========
ErrorCode API_ERROR_LOG_NOT_FOUND = new ErrorCode(1001002000, "API 错误日志不存在");
ErrorCode API_ERROR_LOG_PROCESSED = new ErrorCode(1001002001, "API 错误日志已处理");
// ========= 文件相关 1001003000=================
ErrorCode FILE_PATH_EXISTS = new ErrorCode(1001003000, "文件路径已存在");
ErrorCode FILE_NOT_EXISTS = new ErrorCode(1001003001, "文件不存在");
ErrorCode FILE_IS_EMPTY = new ErrorCode(1001003002, "文件为空");
// ========== 代码生成器 1001004000 ==========
ErrorCode CODEGEN_TABLE_EXISTS = new ErrorCode(1003001000, "表定义已经存在");
ErrorCode CODEGEN_IMPORT_TABLE_NULL = new ErrorCode(1003001001, "导入的表不存在");
ErrorCode CODEGEN_IMPORT_COLUMNS_NULL = new ErrorCode(1003001002, "导入的字段不存在");
ErrorCode CODEGEN_TABLE_NOT_EXISTS = new ErrorCode(1003001004, "表定义不存在");
ErrorCode CODEGEN_COLUMN_NOT_EXISTS = new ErrorCode(1003001005, "字段义不存在");
ErrorCode CODEGEN_SYNC_COLUMNS_NULL = new ErrorCode(1003001006, "同步的字段不存在");
ErrorCode CODEGEN_SYNC_NONE_CHANGE = new ErrorCode(1003001007, "同步失败,不存在改变");
ErrorCode CODEGEN_TABLE_INFO_TABLE_COMMENT_IS_NULL = new ErrorCode(1003001008, "数据库的表注释未填写");
ErrorCode CODEGEN_TABLE_INFO_COLUMN_COMMENT_IS_NULL = new ErrorCode(1003001009, "数据库的表字段({})注释未填写");
// ========== 字典类型测试1001005000 ==========
ErrorCode TEST_DEMO_NOT_EXISTS = new ErrorCode(1001005000, "测试示例不存在");
// ========== 文件配置 1001006000 ==========
ErrorCode FILE_CONFIG_NOT_EXISTS = new ErrorCode(1001006000, "文件配置不存在");
ErrorCode FILE_CONFIG_DELETE_FAIL_MASTER = new ErrorCode(1001006001, "该文件配置不允许删除,原因:它是主配置,删除会导致无法上传文件");
// ========== 数据源配置 1001007000 ==========
ErrorCode DATA_SOURCE_CONFIG_NOT_EXISTS = new ErrorCode(1001007000, "数据源配置不存在");
ErrorCode DATA_SOURCE_CONFIG_NOT_OK = new ErrorCode(1001007001, "数据源配置不正确,无法进行连接");
}

View File

@@ -0,0 +1,5 @@
#Generated by Maven
#Wed Apr 02 13:07:24 CST 2025
version=2.0.0-beta
groupId=com.jojubanking.boot
artifactId=joju-module-infra-api

View File

@@ -0,0 +1,7 @@
com\jojubanking\boot\module\infra\api\logger\dto\ApiAccessLogCreateReqDTO.class
com\jojubanking\boot\module\infra\api\file\FileApi.class
com\jojubanking\boot\module\infra\enums\DictTypeConstants.class
com\jojubanking\boot\module\infra\api\logger\dto\ApiErrorLogCreateReqDTO.class
com\jojubanking\boot\module\infra\api\logger\ApiAccessLogApi.class
com\jojubanking\boot\module\infra\api\logger\ApiErrorLogApi.class
com\jojubanking\boot\module\infra\enums\ErrorCodeConstants.class

View File

@@ -0,0 +1,8 @@
D:\^新版项目\05.九聚项目\32.库尔勒妇幼二期\下园体检\examination\joju-module-infra\joju-module-infra-api\src\main\java\com\jojubanking\boot\module\infra\api\logger\ApiErrorLogApi.java
D:\^新版项目\05.九聚项目\32.库尔勒妇幼二期\下园体检\examination\joju-module-infra\joju-module-infra-api\src\main\java\com\jojubanking\boot\module\infra\api\logger\ApiAccessLogApi.java
D:\^新版项目\05.九聚项目\32.库尔勒妇幼二期\下园体检\examination\joju-module-infra\joju-module-infra-api\src\main\java\com\jojubanking\boot\module\infra\api\logger\dto\ApiAccessLogCreateReqDTO.java
D:\^新版项目\05.九聚项目\32.库尔勒妇幼二期\下园体检\examination\joju-module-infra\joju-module-infra-api\src\main\java\com\jojubanking\boot\module\infra\api\package-info.java
D:\^新版项目\05.九聚项目\32.库尔勒妇幼二期\下园体检\examination\joju-module-infra\joju-module-infra-api\src\main\java\com\jojubanking\boot\module\infra\api\file\FileApi.java
D:\^新版项目\05.九聚项目\32.库尔勒妇幼二期\下园体检\examination\joju-module-infra\joju-module-infra-api\src\main\java\com\jojubanking\boot\module\infra\api\logger\dto\ApiErrorLogCreateReqDTO.java
D:\^新版项目\05.九聚项目\32.库尔勒妇幼二期\下园体检\examination\joju-module-infra\joju-module-infra-api\src\main\java\com\jojubanking\boot\module\infra\enums\DictTypeConstants.java
D:\^新版项目\05.九聚项目\32.库尔勒妇幼二期\下园体检\examination\joju-module-infra\joju-module-infra-api\src\main\java\com\jojubanking\boot\module\infra\enums\ErrorCodeConstants.java

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4" />

View File

@@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.jojubanking.boot</groupId>
<artifactId>joju-module-infra</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>joju-module-infra-biz</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>
infra 模块,主要提供两块能力:
1. 我们放基础设施的运维与管理,支撑上层的通用与核心业务。 例如说:定时任务的管理、服务器的信息等等
2. 研发工具,提升研发效率与质量。 例如说:代码生成器、接口文档等等
</description>
<dependencies>
<dependency>
<groupId>com.jojubanking.boot</groupId>
<artifactId>joju-module-system-api</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.jojubanking.boot</groupId>
<artifactId>joju-module-infra-api</artifactId>
<version>${revision}</version>
</dependency>
<!-- 业务组件 -->
<dependency>
<groupId>com.jojubanking.boot</groupId>
<artifactId>joju-spring-boot-starter-biz-operatelog</artifactId>
</dependency>
<!-- Web 相关 -->
<dependency>
<groupId>com.jojubanking.boot</groupId>
<artifactId>joju-spring-boot-starter-security</artifactId>
</dependency>
<!-- DB 相关 -->
<dependency>
<groupId>com.jojubanking.boot</groupId>
<artifactId>joju-spring-boot-starter-mybatis</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId> <!-- 代码生成器,使用它解析表结构 -->
</dependency>
<dependency>
<groupId>com.jojubanking.boot</groupId>
<artifactId>joju-spring-boot-starter-redis</artifactId>
</dependency>
<!-- Config 配置中心相关 -->
<!-- <dependency>-->
<!-- <groupId>cn.joju.boot</groupId>-->
<!-- <artifactId>joju-spring-boot-starter-config</artifactId>-->
<!-- </dependency>-->
<!-- Job 定时任务相关 -->
<dependency>
<groupId>com.jojubanking.boot</groupId>
<artifactId>joju-spring-boot-starter-job</artifactId>
</dependency>
<!-- 消息队列相关 -->
<dependency>
<groupId>com.jojubanking.boot</groupId>
<artifactId>joju-spring-boot-starter-mq</artifactId>
</dependency>
<!-- Test 测试相关 -->
<dependency>
<groupId>com.jojubanking.boot</groupId>
<artifactId>joju-spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 工具类相关 -->
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId> <!-- 加解密 -->
</dependency>
<dependency>
<groupId>com.jojubanking.boot</groupId>
<artifactId>joju-spring-boot-starter-excel</artifactId>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId> <!-- 实现代码生成 -->
</dependency>
<dependency>
<groupId>cn.smallbun.screw</groupId>
<artifactId>screw-core</artifactId> <!-- 实现数据库文档 -->
</dependency>
<!-- 监控相关 -->
<!-- <dependency>-->
<!-- <groupId>cn.joju.boot</groupId>-->
<!-- <artifactId>joju-spring-boot-starter-monitor</artifactId>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>de.codecentric</groupId>-->
<!-- <artifactId>spring-boot-admin-starter-server</artifactId> &lt;!&ndash; 实现 Spring Boot Admin Server 服务端 &ndash;&gt;-->
<!-- </dependency>-->
<!-- 三方云服务相关 -->
<dependency>
<groupId>com.jojubanking.boot</groupId>
<artifactId>joju-spring-boot-starter-file</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,26 @@
package com.jojubanking.boot.module.infra.api.file;
import com.jojubanking.boot.module.infra.service.file.FileService;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
/**
* 文件 API 实现类
*
* @author TW
*/
@Service
@Validated
public class FileApiImpl implements FileApi {
@Resource
private FileService fileService;
@Override
public String createFile(String name, String path, byte[] content) {
return fileService.createFile(name, path, content);
}
}

View File

@@ -0,0 +1,27 @@
package com.jojubanking.boot.module.infra.api.logger;
import com.jojubanking.boot.module.infra.api.logger.dto.ApiAccessLogCreateReqDTO;
import com.jojubanking.boot.module.infra.service.logger.ApiAccessLogService;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
/**
* API 访问日志的 API 实现类
*
* @author TW
*/
@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 com.jojubanking.boot.module.infra.api.logger;
import com.jojubanking.boot.module.infra.api.logger.dto.ApiErrorLogCreateReqDTO;
import com.jojubanking.boot.module.infra.service.logger.ApiErrorLogService;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
/**
* API 访问日志的 API 接口
*
* @author TW
*/
@Service
@Validated
public class ApiErrorLogApiImpl implements ApiErrorLogApi {
@Resource
private ApiErrorLogService apiErrorLogService;
@Override
public void createApiErrorLog(ApiErrorLogCreateReqDTO createDTO) {
apiErrorLogService.createApiErrorLog(createDTO);
}
}

View File

@@ -0,0 +1 @@
package com.jojubanking.boot.module.infra.api;

View File

@@ -0,0 +1,141 @@
package com.jojubanking.boot.module.infra.controller.admin.codegen;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.ZipUtil;
import com.jojubanking.boot.framework.common.pojo.CommonResult;
import com.jojubanking.boot.framework.common.pojo.PageResult;
import com.jojubanking.boot.framework.common.util.servlet.ServletUtils;
import com.jojubanking.boot.module.infra.controller.admin.codegen.vo.CodegenCreateListReqVO;
import com.jojubanking.boot.module.infra.controller.admin.codegen.vo.CodegenDetailRespVO;
import com.jojubanking.boot.module.infra.controller.admin.codegen.vo.CodegenPreviewRespVO;
import com.jojubanking.boot.module.infra.controller.admin.codegen.vo.CodegenUpdateReqVO;
import com.jojubanking.boot.module.infra.controller.admin.codegen.vo.table.CodegenTablePageReqVO;
import com.jojubanking.boot.module.infra.controller.admin.codegen.vo.table.CodegenTableRespVO;
import com.jojubanking.boot.module.infra.controller.admin.codegen.vo.table.DatabaseTableRespVO;
import com.jojubanking.boot.module.infra.convert.codegen.CodegenConvert;
import com.jojubanking.boot.module.infra.dal.dataobject.codegen.CodegenColumnDO;
import com.jojubanking.boot.module.infra.dal.dataobject.codegen.CodegenTableDO;
import com.jojubanking.boot.module.infra.service.codegen.CodegenService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import static com.jojubanking.boot.framework.common.pojo.CommonResult.success;
import static com.jojubanking.boot.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
@Api(tags = "管理后台 - 代码生成器")
@RestController
@RequestMapping("/infra/codegen")
@Validated
public class CodegenController {
@Resource
private CodegenService codegenService;
@GetMapping("/db/table/list")
@ApiOperation(value = "获得数据库自带的表定义列表", notes = "会过滤掉已经导入 Codegen 的表")
@ApiImplicitParams({
@ApiImplicitParam(name = "dataSourceConfigId", value = "数据源配置的编号", required = true, example = "1", dataTypeClass = Long.class),
@ApiImplicitParam(name = "name", value = "表名,模糊匹配", example = "joju", dataTypeClass = String.class),
@ApiImplicitParam(name = "comment", value = "描述,模糊匹配", example = "芋道", dataTypeClass = String.class)
})
@PreAuthorize("@ss.hasPermission('infra:codegen:query')")
public CommonResult<List<DatabaseTableRespVO>> getDatabaseTableList(
@RequestParam(value = "dataSourceConfigId") Long dataSourceConfigId,
@RequestParam(value = "name", required = false) String name,
@RequestParam(value = "comment", required = false) String comment) {
return success(codegenService.getDatabaseTableList(dataSourceConfigId, name, comment));
}
@GetMapping("/table/page")
@ApiOperation("获得表定义分页")
@PreAuthorize("@ss.hasPermission('infra:codegen:query')")
public CommonResult<PageResult<CodegenTableRespVO>> getCodeGenTablePage(@Valid CodegenTablePageReqVO pageReqVO) {
PageResult<CodegenTableDO> pageResult = codegenService.getCodegenTablePage(pageReqVO);
return success(CodegenConvert.INSTANCE.convertPage(pageResult));
}
@GetMapping("/detail")
@ApiOperation("获得表和字段的明细")
@ApiImplicitParam(name = "tableId", value = "表编号", required = true, example = "1024", dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('infra:codegen:query')")
public CommonResult<CodegenDetailRespVO> getCodegenDetail(@RequestParam("tableId") Long tableId) {
CodegenTableDO table = codegenService.getCodegenTablePage(tableId);
List<CodegenColumnDO> columns = codegenService.getCodegenColumnListByTableId(tableId);
// 拼装返回
return success(CodegenConvert.INSTANCE.convert(table, columns));
}
@ApiOperation("基于数据库的表结构,创建代码生成器的表和字段定义")
@PostMapping("/create-list")
@PreAuthorize("@ss.hasPermission('infra:codegen:create')")
public CommonResult<List<Long>> createCodegenList(@Valid @RequestBody CodegenCreateListReqVO reqVO) {
return success(codegenService.createCodegenList(getLoginUserId(), reqVO));
}
@ApiOperation("更新数据库的表和字段定义")
@PutMapping("/update")
@PreAuthorize("@ss.hasPermission('infra:codegen:update')")
public CommonResult<Boolean> updateCodegen(@Valid @RequestBody CodegenUpdateReqVO updateReqVO) {
codegenService.updateCodegen(updateReqVO);
return success(true);
}
@ApiOperation("基于数据库的表结构,同步数据库的表和字段定义")
@PutMapping("/sync-from-db")
@ApiImplicitParam(name = "tableId", value = "表编号", required = true, example = "1024", dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('infra:codegen:update')")
public CommonResult<Boolean> syncCodegenFromDB(@RequestParam("tableId") Long tableId) {
codegenService.syncCodegenFromDB(tableId);
return success(true);
}
@ApiOperation("删除数据库的表和字段定义")
@DeleteMapping("/delete")
@ApiImplicitParam(name = "tableId", value = "表编号", required = true, example = "1024", dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('infra:codegen:delete')")
public CommonResult<Boolean> deleteCodegen(@RequestParam("tableId") Long tableId) {
codegenService.deleteCodegen(tableId);
return success(true);
}
@ApiOperation("预览生成代码")
@GetMapping("/preview")
@ApiImplicitParam(name = "tableId", value = "表编号", required = true, example = "1024", dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('infra:codegen:preview')")
public CommonResult<List<CodegenPreviewRespVO>> previewCodegen(@RequestParam("tableId") Long tableId) {
Map<String, String> codes = codegenService.generationCodes(tableId);
return success(CodegenConvert.INSTANCE.convert(codes));
}
@ApiOperation("下载生成代码")
@GetMapping("/download")
@ApiImplicitParam(name = "tableId", value = "表编号", required = true, example = "1024", dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('infra:codegen:download')")
public void downloadCodegen(@RequestParam("tableId") Long tableId,
HttpServletResponse response) throws IOException {
// 生成代码
Map<String, String> codes = codegenService.generationCodes(tableId);
// 构建 zip 包
String[] paths = codes.keySet().toArray(new String[0]);
ByteArrayInputStream[] ins = codes.values().stream().map(IoUtil::toUtf8Stream).toArray(ByteArrayInputStream[]::new);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ZipUtil.zip(outputStream, paths, ins);
// 输出
ServletUtils.writeAttachment(response, "codegen.zip", outputStream.toByteArray());
}
}

View File

@@ -0,0 +1,22 @@
package com.jojubanking.boot.module.infra.controller.admin.codegen.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.util.List;
@ApiModel("管理后台 - 基于数据库的表结构,创建代码生成器的表和字段定义 Request VO")
@Data
public class CodegenCreateListReqVO {
@ApiModelProperty(value = "数据源配置的编号", required = true, example = "1")
@NotNull(message = "数据源配置的编号不能为空")
private Long dataSourceConfigId;
@ApiModelProperty(value = "表名数组", required = true, example = "[1, 2, 3]")
@NotNull(message = "表名数组不能为空")
private List<String> tableNames;
}

View File

@@ -0,0 +1,21 @@
package com.jojubanking.boot.module.infra.controller.admin.codegen.vo;
import com.jojubanking.boot.module.infra.controller.admin.codegen.vo.column.CodegenColumnRespVO;
import com.jojubanking.boot.module.infra.controller.admin.codegen.vo.table.CodegenTableRespVO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
@ApiModel("管理后台 - 代码生成表和字段的明细 Response VO")
@Data
public class CodegenDetailRespVO {
@ApiModelProperty("表定义")
private CodegenTableRespVO table;
@ApiModelProperty("字段定义")
private List<CodegenColumnRespVO> columns;
}

View File

@@ -0,0 +1,17 @@
package com.jojubanking.boot.module.infra.controller.admin.codegen.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ApiModel(value = "管理后台 - 代码生成预览 Response VO", description ="注意,每个文件都是一个该对象")
@Data
public class CodegenPreviewRespVO {
@ApiModelProperty(value = "文件路径", required = true, example = "java/com.jojubanking.boot/adminserver/modules/system/controller/test/SysTestDemoController.java")
private String filePath;
@ApiModelProperty(value = "代码", required = true, example = "Hello World")
private String code;
}

View File

@@ -0,0 +1,60 @@
package com.jojubanking.boot.module.infra.controller.admin.codegen.vo;
import cn.hutool.core.util.ObjectUtil;
import com.jojubanking.boot.module.infra.controller.admin.codegen.vo.column.CodegenColumnBaseVO;
import com.jojubanking.boot.module.infra.controller.admin.codegen.vo.table.CodegenTableBaseVO;
import com.jojubanking.boot.module.infra.enums.codegen.CodegenSceneEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import javax.validation.Valid;
import javax.validation.constraints.AssertTrue;
import javax.validation.constraints.NotNull;
import java.util.List;
@ApiModel("管理后台 - 代码生成表和字段的修改 Request VO")
@Data
public class CodegenUpdateReqVO {
@Valid // 校验内嵌的字段
@NotNull(message = "表定义不能为空")
private Table table;
@Valid // 校验内嵌的字段
@NotNull(message = "字段定义不能为空")
private List<Column> columns;
@ApiModel("更新表定义")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Valid
public static class Table extends CodegenTableBaseVO {
@ApiModelProperty(value = "编号", required = true, example = "1")
private Long id;
@AssertTrue(message = "上级菜单不能为空")
public boolean isParentMenuIdValid() {
// 生成场景为管理后台时,必须设置上级菜单,不然生成的菜单 SQL 是无父级菜单的
return ObjectUtil.notEqual(getScene(), CodegenSceneEnum.ADMIN.getScene())
|| getParentMenuId() != null;
}
}
@ApiModel("更新表定义")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public static class Column extends CodegenColumnBaseVO {
@ApiModelProperty(value = "编号", required = true, example = "1")
private Long id;
}
}

View File

@@ -0,0 +1,85 @@
package com.jojubanking.boot.module.infra.controller.admin.codegen.vo.column;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
* 代码生成字段定义 Base VO提供给添加、修改、详细的子 VO 使用
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
*/
@Data
public class CodegenColumnBaseVO {
@ApiModelProperty(value = "表编号", required = true, example = "1")
@NotNull(message = "表编号不能为空")
private Long tableId;
@ApiModelProperty(value = "字段名", required = true, example = "user_age")
@NotNull(message = "字段名不能为空")
private String columnName;
@ApiModelProperty(value = "字段类型", required = true, example = "int(11)")
@NotNull(message = "字段类型不能为空")
private String dataType;
@ApiModelProperty(value = "字段描述", required = true, example = "年龄")
@NotNull(message = "字段描述不能为空")
private String columnComment;
@ApiModelProperty(value = "是否允许为空", required = true, example = "true")
@NotNull(message = "是否允许为空不能为空")
private Boolean nullable;
@ApiModelProperty(value = "是否主键", required = true, example = "false")
@NotNull(message = "是否主键不能为空")
private Boolean primaryKey;
@ApiModelProperty(value = "是否自增", required = true, example = "true")
@NotNull(message = "是否自增不能为空")
private String autoIncrement;
@ApiModelProperty(value = "排序", required = true, example = "10")
@NotNull(message = "排序不能为空")
private Integer ordinalPosition;
@ApiModelProperty(value = "Java 属性类型", required = true, example = "userAge")
@NotNull(message = "Java 属性类型不能为空")
private String javaType;
@ApiModelProperty(value = "Java 属性名", required = true, example = "Integer")
@NotNull(message = "Java 属性名不能为空")
private String javaField;
@ApiModelProperty(value = "字典类型", example = "sys_gender")
private String dictType;
@ApiModelProperty(value = "数据示例", example = "1024")
private String example;
@ApiModelProperty(value = "是否为 Create 创建操作的字段", required = true, example = "true")
@NotNull(message = "是否为 Create 创建操作的字段不能为空")
private Boolean createOperation;
@ApiModelProperty(value = "是否为 Update 更新操作的字段", required = true, example = "false")
@NotNull(message = "是否为 Update 更新操作的字段不能为空")
private Boolean updateOperation;
@ApiModelProperty(value = "是否为 List 查询操作的字段", required = true, example = "true")
@NotNull(message = "是否为 List 查询操作的字段不能为空")
private Boolean listOperation;
@ApiModelProperty(value = "List 查询操作的条件类型", required = true, example = "LIKE", notes = "参见 CodegenColumnListConditionEnum 枚举")
@NotNull(message = "List 查询操作的条件类型不能为空")
private String listOperationCondition;
@ApiModelProperty(value = "是否为 List 查询操作的返回字段", required = true, example = "true")
@NotNull(message = "是否为 List 查询操作的返回字段不能为空")
private Boolean listOperationResult;
@ApiModelProperty(value = "显示类型", required = true, example = "input")
@NotNull(message = "显示类型不能为空")
private String htmlType;
}

View File

@@ -0,0 +1,23 @@
package com.jojubanking.boot.module.infra.controller.admin.codegen.vo.column;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.util.Date;
@ApiModel("管理后台 - 代码生成字段定义 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class CodegenColumnRespVO extends CodegenColumnBaseVO {
@ApiModelProperty(value = "编号", required = true, example = "1")
private Long id;
@ApiModelProperty(value = "创建时间", required = true)
private Date createTime;
}

View File

@@ -0,0 +1,57 @@
package com.jojubanking.boot.module.infra.controller.admin.codegen.vo.table;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
* 代码生成 Base VO提供给添加、修改、详细的子 VO 使用
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
*/
@Data
public class CodegenTableBaseVO {
@ApiModelProperty(value = "生成场景", required = true, example = "1", notes = "参见 CodegenSceneEnum 枚举")
@NotNull(message = "导入类型不能为空")
private Integer scene;
@ApiModelProperty(value = "表名称", required = true, example = "joju")
@NotNull(message = "表名称不能为空")
private String tableName;
@ApiModelProperty(value = "表描述", required = true, example = "芋道")
@NotNull(message = "表描述不能为空")
private String tableComment;
@ApiModelProperty(value = "备注", example = "我是备注")
private String remark;
@ApiModelProperty(value = "模块名", required = true, example = "system")
@NotNull(message = "模块名不能为空")
private String moduleName;
@ApiModelProperty(value = "业务名", required = true, example = "codegen")
@NotNull(message = "业务名不能为空")
private String businessName;
@ApiModelProperty(value = "类名称", required = true, example = "CodegenTable")
@NotNull(message = "类名称不能为空")
private String className;
@ApiModelProperty(value = "类描述", required = true, example = "代码生成器的表定义")
@NotNull(message = "类描述不能为空")
private String classComment;
@ApiModelProperty(value = "作者", required = true, example = "TW")
@NotNull(message = "作者不能为空")
private String author;
@ApiModelProperty(value = "模板类型", required = true, example = "1", notes = "参见 CodegenTemplateTypeEnum 枚举")
@NotNull(message = "模板类型不能为空")
private Integer templateType;
@ApiModelProperty(value = "父菜单编号", example = "1024")
private Long parentMenuId;
}

View File

@@ -0,0 +1,31 @@
package com.jojubanking.boot.module.infra.controller.admin.codegen.vo.table;
import com.jojubanking.boot.framework.common.pojo.PageParam;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
import static com.jojubanking.boot.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@ApiModel("管理后台 - 表定义分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class CodegenTablePageReqVO extends PageParam {
@ApiModelProperty(value = "表名称", example = "joju", notes = "模糊匹配")
private String tableName;
@ApiModelProperty(value = "表描述", example = "芋道", notes = "模糊匹配")
private String tableComment;
@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[] createTime;
}

View File

@@ -0,0 +1,29 @@
package com.jojubanking.boot.module.infra.controller.admin.codegen.vo.table;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.util.Date;
@ApiModel("管理后台 - 代码生成表定义 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class CodegenTableRespVO extends CodegenTableBaseVO {
@ApiModelProperty(value = "编号", required = true, example = "1")
private Long id;
@ApiModelProperty(value = "主键编号", required = true, example = "1024")
private Integer dataSourceConfigId;
@ApiModelProperty(value = "创建时间", required = true)
private Date createTime;
@ApiModelProperty(value = "更新时间", required = true)
private Date updateTime;
}

View File

@@ -0,0 +1,17 @@
package com.jojubanking.boot.module.infra.controller.admin.codegen.vo.table;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ApiModel("管理后台 - 数据库的表定义 Response VO")
@Data
public class DatabaseTableRespVO {
@ApiModelProperty(value = "表名称", required = true, example = "yuanma")
private String name;
@ApiModelProperty(value = "表描述", required = true, example = "TW")
private String comment;
}

View File

@@ -0,0 +1,105 @@
package com.jojubanking.boot.module.infra.controller.admin.config;
import com.jojubanking.boot.framework.common.exception.util.ServiceExceptionUtil;
import com.jojubanking.boot.framework.common.pojo.CommonResult;
import com.jojubanking.boot.framework.common.pojo.PageResult;
import com.jojubanking.boot.framework.excel.core.util.ExcelUtils;
import com.jojubanking.boot.framework.operatelog.core.annotations.OperateLog;
import com.jojubanking.boot.module.infra.controller.admin.config.vo.*;
import com.jojubanking.boot.module.infra.convert.config.ConfigConvert;
import com.jojubanking.boot.module.infra.dal.dataobject.config.ConfigDO;
import com.jojubanking.boot.module.infra.service.config.ConfigService;
import com.jojubanking.boot.module.infra.enums.ErrorCodeConstants;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.List;
import static com.jojubanking.boot.framework.common.pojo.CommonResult.success;
import static com.jojubanking.boot.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
@Api(tags = "管理后台 - 参数配置")
@RestController
@RequestMapping("/infra/config")
@Validated
public class ConfigController {
@Resource
private ConfigService configService;
@PostMapping("/create")
@ApiOperation("创建参数配置")
@PreAuthorize("@ss.hasPermission('infra:config:create')")
public CommonResult<Long> createConfig(@Valid @RequestBody ConfigCreateReqVO reqVO) {
return success(configService.createConfig(reqVO));
}
@PutMapping("/update")
@ApiOperation("修改参数配置")
@PreAuthorize("@ss.hasPermission('infra:config:update')")
public CommonResult<Boolean> updateConfig(@Valid @RequestBody ConfigUpdateReqVO reqVO) {
configService.updateConfig(reqVO);
return success(true);
}
@DeleteMapping("/delete")
@ApiOperation("删除参数配置")
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('infra:config:delete')")
public CommonResult<Boolean> deleteConfig(@RequestParam("id") Long id) {
configService.deleteConfig(id);
return success(true);
}
@GetMapping(value = "/get")
@ApiOperation("获得参数配置")
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('infra:config:query')")
public CommonResult<ConfigRespVO> getConfig(@RequestParam("id") Long id) {
return success(ConfigConvert.INSTANCE.convert(configService.getConfig(id)));
}
@GetMapping(value = "/get-value-by-key")
@ApiOperation(value = "根据参数键名查询参数值", notes = "不可见的配置,不允许返回给前端")
@ApiImplicitParam(name = "key", value = "参数键", required = true, example = "yunai.biz.username", dataTypeClass = String.class)
public CommonResult<String> getConfigKey(@RequestParam("key") String key) {
ConfigDO config = configService.getConfigByKey(key);
if (config == null) {
return null;
}
if (config.getVisible()) {
throw ServiceExceptionUtil.exception(ErrorCodeConstants.CONFIG_GET_VALUE_ERROR_IF_VISIBLE);
}
return success(config.getValue());
}
@GetMapping("/page")
@ApiOperation("获取参数配置分页")
@PreAuthorize("@ss.hasPermission('infra:config:query')")
public CommonResult<PageResult<ConfigRespVO>> getConfigPage(@Valid ConfigPageReqVO reqVO) {
PageResult<ConfigDO> page = configService.getConfigPage(reqVO);
return success(ConfigConvert.INSTANCE.convertPage(page));
}
@GetMapping("/export")
@ApiOperation("导出参数配置")
@PreAuthorize("@ss.hasPermission('infra:config:export')")
@OperateLog(type = EXPORT)
public void exportSysConfig(@Valid ConfigExportReqVO reqVO,
HttpServletResponse response) throws IOException {
List<ConfigDO> list = configService.getConfigList(reqVO);
// 拼接数据
List<ConfigExcelVO> datas = ConfigConvert.INSTANCE.convertList(list);
// 输出
ExcelUtils.write(response, "参数配置.xls", "数据", ConfigExcelVO.class, datas);
}
}

View File

@@ -0,0 +1,40 @@
package com.jojubanking.boot.module.infra.controller.admin.config.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
/**
* 参数配置 Base VO提供给添加、修改、详细的子 VO 使用
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
*/
@Data
public class ConfigBaseVO {
@ApiModelProperty(value = "参数分组", required = true, example = "biz")
@NotEmpty(message = "参数分组不能为空")
@Size(max = 50, message = "参数名称不能超过50个字符")
private String category;
@ApiModelProperty(value = "参数名称", required = true, example = "数据库名")
@NotBlank(message = "参数名称不能为空")
@Size(max = 100, message = "参数名称不能超过100个字符")
private String name;
@ApiModelProperty(value = "参数键值", required = true, example = "1024")
@NotBlank(message = "参数键值不能为空")
@Size(max = 500, message = "参数键值长度不能超过500个字符")
private String value;
@ApiModelProperty(value = "是否敏感", required = true, example = "true")
@NotNull(message = "是否敏感不能为空")
private Boolean visible;
@ApiModelProperty(value = "备注", example = "备注一下很帅气!")
private String remark;
}

View File

@@ -0,0 +1,21 @@
package com.jojubanking.boot.module.infra.controller.admin.config.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
@ApiModel("管理后台 - 参数配置创建 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
public class ConfigCreateReqVO extends ConfigBaseVO {
@ApiModelProperty(value = "参数键名", required = true, example = "yunai.db.username")
@NotBlank(message = "参数键名长度不能为空")
@Size(max = 100, message = "参数键名长度不能超过100个字符")
private String key;
}

View File

@@ -0,0 +1,46 @@
package com.jojubanking.boot.module.infra.controller.admin.config.vo;
import com.jojubanking.boot.framework.excel.core.annotations.DictFormat;
import com.jojubanking.boot.framework.excel.core.convert.DictConvert;
import com.jojubanking.boot.module.infra.enums.DictTypeConstants;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
import java.util.Date;
/**
* 参数配置 Excel 导出响应 VO
*/
@Data
public class ConfigExcelVO {
@ExcelProperty("参数配置序号")
private Long id;
@ExcelProperty("参数键名")
private String key;
@ExcelProperty("参数分组")
private String group;
@ExcelProperty("参数名称")
private String name;
@ExcelProperty("参数键值")
private String value;
@ExcelProperty(value = "参数类型", converter = DictConvert.class)
@DictFormat(DictTypeConstants.CONFIG_TYPE)
private Integer type;
@ExcelProperty(value = "是否敏感", converter = DictConvert.class)
@DictFormat(DictTypeConstants.BOOLEAN_STRING)
private Boolean sensitive;
@ExcelProperty("备注")
private String remark;
@ExcelProperty("创建时间")
private Date createTime;
}

View File

@@ -0,0 +1,29 @@
package com.jojubanking.boot.module.infra.controller.admin.config.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
import static com.jojubanking.boot.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@ApiModel("管理后台 - 参数配置导出 Request VO")
@Data
public class ConfigExportReqVO {
@ApiModelProperty(value = "参数名称", example = "模糊匹配")
private String name;
@ApiModelProperty(value = "参数键名", example = "yunai.db.username", notes = "模糊匹配")
private String key;
@ApiModelProperty(value = "参数类型", example = "1", notes = "参见 SysConfigTypeEnum 枚举")
private Integer type;
@ApiModelProperty(value = "创建时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private Date[] createTime;
}

View File

@@ -0,0 +1,34 @@
package com.jojubanking.boot.module.infra.controller.admin.config.vo;
import com.jojubanking.boot.framework.common.pojo.PageParam;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
import static com.jojubanking.boot.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@ApiModel("管理后台 - 参数配置分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ConfigPageReqVO extends PageParam {
@ApiModelProperty(value = "数据源名称", example = "模糊匹配")
private String name;
@ApiModelProperty(value = "参数键名", example = "yunai.db.username", notes = "模糊匹配")
private String key;
@ApiModelProperty(value = "参数类型", example = "1", notes = "参见 SysConfigTypeEnum 枚举")
private Integer type;
@ApiModelProperty(value = "创建时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private Date[] createTime;
}

View File

@@ -0,0 +1,31 @@
package com.jojubanking.boot.module.infra.controller.admin.config.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import java.util.Date;
@ApiModel("管理后台 - 参数配置信息 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
public class ConfigRespVO extends ConfigBaseVO {
@ApiModelProperty(value = "参数配置序号", required = true, example = "1024")
private Long id;
@ApiModelProperty(value = "参数键名", required = true, example = "yunai.db.username")
@NotBlank(message = "参数键名长度不能为空")
@Size(max = 100, message = "参数键名长度不能超过100个字符")
private String key;
@ApiModelProperty(value = "参数类型", required = true, example = "1", notes = "参见 SysConfigTypeEnum 枚举")
private Integer type;
@ApiModelProperty(value = "创建时间", required = true, example = "时间戳格式")
private Date createTime;
}

View File

@@ -0,0 +1,21 @@
package com.jojubanking.boot.module.infra.controller.admin.config.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import javax.validation.constraints.NotNull;
@ApiModel("管理后台 - 参数配置创建 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ConfigUpdateReqVO extends ConfigBaseVO {
@ApiModelProperty(value = "参数配置序号", required = true, example = "1024")
@NotNull(message = "参数配置编号不能为空")
private Long id;
}

View File

@@ -0,0 +1,73 @@
package com.jojubanking.boot.module.infra.controller.admin.db;
import com.jojubanking.boot.framework.common.pojo.CommonResult;
import com.jojubanking.boot.module.infra.controller.admin.db.vo.DataSourceConfigCreateReqVO;
import com.jojubanking.boot.module.infra.controller.admin.db.vo.DataSourceConfigRespVO;
import com.jojubanking.boot.module.infra.controller.admin.db.vo.DataSourceConfigUpdateReqVO;
import com.jojubanking.boot.module.infra.convert.db.DataSourceConfigConvert;
import com.jojubanking.boot.module.infra.dal.dataobject.db.DataSourceConfigDO;
import com.jojubanking.boot.module.infra.service.db.DataSourceConfigService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;
import static com.jojubanking.boot.framework.common.pojo.CommonResult.success;
@Api(tags = "管理后台 - 数据源配置")
@RestController
@RequestMapping("/infra/data-source-config")
@Validated
public class DataSourceConfigController {
@Resource
private DataSourceConfigService dataSourceConfigService;
@PostMapping("/create")
@ApiOperation("创建数据源配置")
@PreAuthorize("@ss.hasPermission('infra:data-source-config:create')")
public CommonResult<Long> createDataSourceConfig(@Valid @RequestBody DataSourceConfigCreateReqVO createReqVO) {
return success(dataSourceConfigService.createDataSourceConfig(createReqVO));
}
@PutMapping("/update")
@ApiOperation("更新数据源配置")
@PreAuthorize("@ss.hasPermission('infra:data-source-config:update')")
public CommonResult<Boolean> updateDataSourceConfig(@Valid @RequestBody DataSourceConfigUpdateReqVO updateReqVO) {
dataSourceConfigService.updateDataSourceConfig(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@ApiOperation("删除数据源配置")
@ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('infra:data-source-config:delete')")
public CommonResult<Boolean> deleteDataSourceConfig(@RequestParam("id") Long id) {
dataSourceConfigService.deleteDataSourceConfig(id);
return success(true);
}
@GetMapping("/get")
@ApiOperation("获得数据源配置")
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('infra:data-source-config:query')")
public CommonResult<DataSourceConfigRespVO> getDataSourceConfig(@RequestParam("id") Long id) {
DataSourceConfigDO dataSourceConfig = dataSourceConfigService.getDataSourceConfig(id);
return success(DataSourceConfigConvert.INSTANCE.convert(dataSourceConfig));
}
@GetMapping("/list")
@ApiOperation("获得数据源配置列表")
@PreAuthorize("@ss.hasPermission('infra:data-source-config:query')")
public CommonResult<List<DataSourceConfigRespVO>> getDataSourceConfigList() {
List<DataSourceConfigDO> list = dataSourceConfigService.getDataSourceConfigList();
return success(DataSourceConfigConvert.INSTANCE.convertList(list));
}
}

View File

@@ -0,0 +1,157 @@
package com.jojubanking.boot.module.infra.controller.admin.db;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import com.jojubanking.boot.framework.common.util.servlet.ServletUtils;
import cn.smallbun.screw.core.Configuration;
import cn.smallbun.screw.core.engine.EngineConfig;
import cn.smallbun.screw.core.engine.EngineFileType;
import cn.smallbun.screw.core.engine.EngineTemplateType;
import cn.smallbun.screw.core.execute.DocumentationExecute;
import cn.smallbun.screw.core.process.ProcessConfig;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
@Api(tags = "管理后台 - 数据库文档")
@RestController
@RequestMapping("/infra/db-doc")
public class DatabaseDocController {
@Resource
private DynamicDataSourceProperties dynamicDataSourceProperties;
private static final String FILE_OUTPUT_DIR = System.getProperty("java.io.tmpdir") + File.separator
+ "db-doc";
private static final String DOC_FILE_NAME = "数据库文档";
private static final String DOC_VERSION = "1.0.0";
private static final String DOC_DESCRIPTION = "文档描述";
@GetMapping("/export-html")
@ApiOperation("导出 html 格式的数据文档")
@ApiImplicitParam(name = "deleteFile", value = "是否删除在服务器本地生成的数据库文档", example = "true",
dataTypeClass = Boolean.class)
public void exportHtml(@RequestParam(defaultValue = "true") Boolean deleteFile,
HttpServletResponse response) throws IOException {
doExportFile(EngineFileType.HTML, deleteFile, response);
}
@GetMapping("/export-word")
@ApiOperation("导出 word 格式的数据文档")
@ApiImplicitParam(name = "deleteFile", value = "是否删除在服务器本地生成的数据库文档", example = "true",
dataTypeClass = Boolean.class)
public void exportWord(@RequestParam(defaultValue = "true") Boolean deleteFile,
HttpServletResponse response) throws IOException {
doExportFile(EngineFileType.WORD, deleteFile, response);
}
@GetMapping("/export-markdown")
@ApiOperation("导出 markdown 格式的数据文档")
@ApiImplicitParam(name = "deleteFile", value = "是否删除在服务器本地生成的数据库文档", example = "true",
dataTypeClass = Boolean.class)
public void exportMarkdown(@RequestParam(defaultValue = "true") Boolean deleteFile,
HttpServletResponse response) throws IOException {
doExportFile(EngineFileType.MD, deleteFile, response);
}
private void doExportFile(EngineFileType fileOutputType, Boolean deleteFile,
HttpServletResponse response) throws IOException {
String docFileName = DOC_FILE_NAME + "_" + IdUtil.fastSimpleUUID();
String filePath = doExportFile(fileOutputType, docFileName);
String downloadFileName = DOC_FILE_NAME + fileOutputType.getFileSuffix(); //下载后的文件名
try {
// 读取,返回
ServletUtils.writeAttachment(response, downloadFileName, FileUtil.readBytes(filePath));
} finally {
handleDeleteFile(deleteFile, filePath);
}
}
/**
* 输出文件,返回文件路径
*
* @param fileOutputType 文件类型
* @param fileName 文件名, 无需 ".docx" 等文件后缀
* @return 生成的文件所在路径
*/
private String doExportFile(EngineFileType fileOutputType, String fileName) {
try (HikariDataSource dataSource = buildDataSource()) {
// 创建 screw 的配置
Configuration config = Configuration.builder()
.version(DOC_VERSION) // 版本
.description(DOC_DESCRIPTION) // 描述
.dataSource(dataSource) // 数据源
.engineConfig(buildEngineConfig(fileOutputType, fileName)) // 引擎配置
.produceConfig(buildProcessConfig()) // 处理配置
.build();
// 执行 screw生成数据库文档
new DocumentationExecute(config).execute();
return FILE_OUTPUT_DIR + File.separator + fileName + fileOutputType.getFileSuffix();
}
}
private void handleDeleteFile(Boolean deleteFile, String filePath) {
if (!deleteFile) {
return;
}
FileUtil.del(filePath);
}
/**
* 创建数据源
*/
// TODO TWscrew 暂时不支持 druid尴尬
private HikariDataSource buildDataSource() {
// 获得 DataSource 数据源,目前只支持首个
String primary = dynamicDataSourceProperties.getPrimary();
DataSourceProperty dataSourceProperty = dynamicDataSourceProperties.getDatasource().get(primary);
// 创建 HikariConfig 配置类
HikariConfig hikariConfig = new HikariConfig();
hikariConfig.setJdbcUrl(dataSourceProperty.getUrl());
hikariConfig.setUsername(dataSourceProperty.getUsername());
hikariConfig.setPassword(dataSourceProperty.getPassword());
hikariConfig.addDataSourceProperty("useInformationSchema", "true"); // 设置可以获取 tables remarks 信息
// 创建数据源
return new HikariDataSource(hikariConfig);
}
/**
* 创建 screw 的引擎配置
*/
private static EngineConfig buildEngineConfig(EngineFileType fileOutputType, String docFileName) {
return EngineConfig.builder()
.fileOutputDir(FILE_OUTPUT_DIR) // 生成文件路径
.openOutputDir(false) // 打开目录
.fileType(fileOutputType) // 文件类型
.produceType(EngineTemplateType.velocity) // 文件类型
.fileName(docFileName) // 自定义文件名称
.build();
}
/**
* 创建 screw 的处理配置,一般可忽略
* 指定生成逻辑、当存在指定表、指定表前缀、指定表后缀时,将生成指定表,其余表不生成、并跳过忽略表配置
*/
private static ProcessConfig buildProcessConfig() {
return ProcessConfig.builder()
.ignoreTablePrefix(Arrays.asList("QRTZ_", "ACT_")) // 忽略表前缀
.build();
}
}

View File

@@ -0,0 +1,27 @@
package com.jojubanking.boot.module.infra.controller.admin.db.vo;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
import javax.validation.constraints.*;
/**
* 数据源配置 Base VO提供给添加、修改、详细的子 VO 使用
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
*/
@Data
public class DataSourceConfigBaseVO {
@ApiModelProperty(value = "数据源名称", required = true, example = "test")
@NotNull(message = "数据源名称不能为空")
private String name;
@ApiModelProperty(value = "数据源连接", required = true, example = "jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro")
@NotNull(message = "数据源连接不能为空")
private String url;
@ApiModelProperty(value = "用户名", required = true, example = "root")
@NotNull(message = "用户名不能为空")
private String username;
}

View File

@@ -0,0 +1,18 @@
package com.jojubanking.boot.module.infra.controller.admin.db.vo;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
import javax.validation.constraints.*;
@ApiModel("管理后台 - 数据源配置创建 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class DataSourceConfigCreateReqVO extends DataSourceConfigBaseVO {
@ApiModelProperty(value = "密码", required = true, example = "123456")
@NotNull(message = "密码不能为空")
private String password;
}

View File

@@ -0,0 +1,19 @@
package com.jojubanking.boot.module.infra.controller.admin.db.vo;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
@ApiModel("管理后台 - 数据源配置 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class DataSourceConfigRespVO extends DataSourceConfigBaseVO {
@ApiModelProperty(value = "主键编号", required = true, example = "1024")
private Integer id;
@ApiModelProperty(value = "创建时间", required = true)
private Date createTime;
}

View File

@@ -0,0 +1,22 @@
package com.jojubanking.boot.module.infra.controller.admin.db.vo;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
import javax.validation.constraints.*;
@ApiModel("管理后台 - 数据源配置更新 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class DataSourceConfigUpdateReqVO extends DataSourceConfigBaseVO {
@ApiModelProperty(value = "主键编号", required = true, example = "1024")
@NotNull(message = "主键编号不能为空")
private Long id;
@ApiModelProperty(value = "密码", required = true, example = "123456")
@NotNull(message = "密码不能为空")
private String password;
}

View File

@@ -0,0 +1,45 @@
### 请求 /infra/file-config/create 接口 => 成功
POST {{baseUrl}}/infra/file-config/create
Content-Type: application/json
tenant-id: {{adminTenentId}}
Authorization: Bearer {{token}}
{
"name": "S3 - 七牛云",
"remark": "",
"storage": 20,
"config": {
"accessKey": "b7yvuhBSAGjmtPhMFcn9iMOxUOY_I06cA_p0ZUx8",
"accessSecret": "kXM1l5ia1RvSX3QaOEcwI3RLz3Y2rmNszWonKZtP",
"bucket": "ruoyi-vue-pro",
"endpoint": "s3-cn-south-1.qiniucs.com",
"domain": "http://test.joju.iocoder.cn",
"region": "oss-cn-beijing"
}
}
### 请求 /infra/file-config/update 接口 => 成功
PUT {{baseUrl}}/infra/file-config/update
Content-Type: application/json
tenant-id: {{adminTenentId}}
Authorization: Bearer {{token}}
{
"id": 2,
"name": "S3 - 七牛云",
"remark": "",
"config": {
"accessKey": "b7yvuhBSAGjmtPhMFcn9iMOxUOY_I06cA_p0ZUx8",
"accessSecret": "kXM1l5ia1RvSX3QaOEcwI3RLz3Y2rmNszWonKZtP",
"bucket": "ruoyi-vue-pro",
"endpoint": "s3-cn-south-1.qiniucs.com",
"domain": "http://test.joju.iocoder.cn",
"region": "oss-cn-beijing"
}
}
### 请求 /infra/file-config/test 接口 => 成功
GET {{baseUrl}}/infra/file-config/test?id=2
Content-Type: application/json
tenant-id: {{adminTenentId}}
Authorization: Bearer {{token}}

View File

@@ -0,0 +1,89 @@
package com.jojubanking.boot.module.infra.controller.admin.file;
import com.jojubanking.boot.framework.common.pojo.CommonResult;
import com.jojubanking.boot.framework.common.pojo.PageResult;
import com.jojubanking.boot.module.infra.controller.admin.file.vo.config.FileConfigCreateReqVO;
import com.jojubanking.boot.module.infra.controller.admin.file.vo.config.FileConfigPageReqVO;
import com.jojubanking.boot.module.infra.controller.admin.file.vo.config.FileConfigRespVO;
import com.jojubanking.boot.module.infra.controller.admin.file.vo.config.FileConfigUpdateReqVO;
import com.jojubanking.boot.module.infra.convert.file.FileConfigConvert;
import com.jojubanking.boot.module.infra.dal.dataobject.file.FileConfigDO;
import com.jojubanking.boot.module.infra.service.file.FileConfigService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import static com.jojubanking.boot.framework.common.pojo.CommonResult.success;
@Api(tags = "管理后台 - 文件配置")
@RestController
@RequestMapping("/infra/file-config")
@Validated
public class FileConfigController {
@Resource
private FileConfigService fileConfigService;
@PostMapping("/create")
@ApiOperation("创建文件配置")
@PreAuthorize("@ss.hasPermission('infra:file-config:create')")
public CommonResult<Long> createFileConfig(@Valid @RequestBody FileConfigCreateReqVO createReqVO) {
return success(fileConfigService.createFileConfig(createReqVO));
}
@PutMapping("/update")
@ApiOperation("更新文件配置")
@PreAuthorize("@ss.hasPermission('infra:file-config:update')")
public CommonResult<Boolean> updateFileConfig(@Valid @RequestBody FileConfigUpdateReqVO updateReqVO) {
fileConfigService.updateFileConfig(updateReqVO);
return success(true);
}
@PutMapping("/update-master")
@ApiOperation("更新文件配置为 Master")
@PreAuthorize("@ss.hasPermission('infra:file-config:update')")
public CommonResult<Boolean> updateFileConfigMaster(@RequestParam("id") Long id) {
fileConfigService.updateFileConfigMaster(id);
return success(true);
}
@DeleteMapping("/delete")
@ApiOperation("删除文件配置")
@ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('infra:file-config:delete')")
public CommonResult<Boolean> deleteFileConfig(@RequestParam("id") Long id) {
fileConfigService.deleteFileConfig(id);
return success(true);
}
@GetMapping("/get")
@ApiOperation("获得文件配置")
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('infra:file-config:query')")
public CommonResult<FileConfigRespVO> getFileConfig(@RequestParam("id") Long id) {
FileConfigDO fileConfig = fileConfigService.getFileConfig(id);
return success(FileConfigConvert.INSTANCE.convert(fileConfig));
}
@GetMapping("/page")
@ApiOperation("获得文件配置分页")
@PreAuthorize("@ss.hasPermission('infra:file-config:query')")
public CommonResult<PageResult<FileConfigRespVO>> getFileConfigPage(@Valid FileConfigPageReqVO pageVO) {
PageResult<FileConfigDO> pageResult = fileConfigService.getFileConfigPage(pageVO);
return success(FileConfigConvert.INSTANCE.convertPage(pageResult));
}
@GetMapping("/test")
@ApiOperation("测试文件配置是否正确")
@PreAuthorize("@ss.hasPermission('infra:file-config:query')")
public CommonResult<String> testFileConfig(@RequestParam("id") Long id) throws Exception {
String url = fileConfigService.testFileConfig(id);
return success(url);
}
}

View File

@@ -0,0 +1,89 @@
package com.jojubanking.boot.module.infra.controller.admin.file;
import cn.hutool.core.io.IoUtil;
import com.jojubanking.boot.framework.common.pojo.CommonResult;
import com.jojubanking.boot.framework.common.pojo.PageResult;
import com.jojubanking.boot.framework.common.util.servlet.ServletUtils;
import com.jojubanking.boot.framework.operatelog.core.annotations.OperateLog;
import com.jojubanking.boot.module.infra.controller.admin.file.vo.file.FilePageReqVO;
import com.jojubanking.boot.module.infra.controller.admin.file.vo.file.FileRespVO;
import com.jojubanking.boot.module.infra.convert.file.FileConvert;
import com.jojubanking.boot.module.infra.dal.dataobject.file.FileDO;
import com.jojubanking.boot.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;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
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.HttpServletResponse;
import javax.validation.Valid;
import static com.jojubanking.boot.framework.common.pojo.CommonResult.success;
@Api(tags = "管理后台 - 文件存储")
@RestController
@RequestMapping("/infra/file")
@Validated
@Slf4j
public class FileController {
@Resource
private FileService fileService;
@PostMapping("/upload")
@ApiOperation("上传文件")
@ApiImplicitParams({
@ApiImplicitParam(name = "file", value = "文件附件", required = true, dataTypeClass = MultipartFile.class),
@ApiImplicitParam(name = "path", value = "文件路径", example = "jojuyuanma.png", dataTypeClass = String.class)
})
@OperateLog(logArgs = false) // 上传文件,没有记录操作日志的必要
public CommonResult<String> uploadFile(@RequestParam("file") MultipartFile file,
@RequestParam(value = "path", required = false) String path) throws Exception {
return success(fileService.createFile(file.getOriginalFilename(), path, IoUtil.readBytes(file.getInputStream())));
}
@DeleteMapping("/delete")
@ApiOperation("删除文件")
@ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('infra:file:delete')")
public CommonResult<Boolean> deleteFile(@RequestParam("id") Long id) throws Exception {
fileService.deleteFile(id);
return success(true);
}
@GetMapping("/{configId}/get/{path}")
@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 {
byte[] content = fileService.getFileContent(configId, path);
if (content == null) {
log.warn("[getFileContent][configId({}) path({}) 文件不存在]", configId, path);
response.setStatus(HttpStatus.NOT_FOUND.value());
return;
}
ServletUtils.writeAttachment(response, path, content);
}
@GetMapping("/page")
@ApiOperation("获得文件分页")
@PreAuthorize("@ss.hasPermission('infra:file:query')")
public CommonResult<PageResult<FileRespVO>> getFilePage(@Valid FilePageReqVO pageVO) {
PageResult<FileDO> pageResult = fileService.getFilePage(pageVO);
return success(FileConvert.INSTANCE.convertPage(pageResult));
}
}

View File

@@ -0,0 +1,22 @@
package com.jojubanking.boot.module.infra.controller.admin.file.vo.config;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
* 文件配置 Base VO提供给添加、修改、详细的子 VO 使用
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
*/
@Data
public class FileConfigBaseVO {
@ApiModelProperty(value = "配置名", required = true, example = "S3 - 阿里云")
@NotNull(message = "配置名不能为空")
private String name;
@ApiModelProperty(value = "备注", example = "我是备注")
private String remark;
}

View File

@@ -0,0 +1,28 @@
package com.jojubanking.boot.module.infra.controller.admin.file.vo.config;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotNull;
import java.util.Map;
@ApiModel("管理后台 - 文件配置创建 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Accessors(chain = true)
public class FileConfigCreateReqVO extends FileConfigBaseVO {
@ApiModelProperty(value = "存储器", required = true, example = "1", notes = "参见 FileStorageEnum 枚举类")
@NotNull(message = "存储器不能为空")
private Integer storage;
@ApiModelProperty(value = "存储配置", required = true, notes = "配置是动态参数,所以使用 Map 接收")
@NotNull(message = "存储配置不能为空")
private Map<String, Object> config;
}

View File

@@ -0,0 +1,31 @@
package com.jojubanking.boot.module.infra.controller.admin.file.vo.config;
import com.jojubanking.boot.framework.common.pojo.PageParam;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
import static com.jojubanking.boot.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@ApiModel("管理后台 - 文件配置分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class FileConfigPageReqVO extends PageParam {
@ApiModelProperty(value = "配置名", example = "S3 - 阿里云")
private String name;
@ApiModelProperty(value = "存储器", example = "1")
private Integer storage;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "创建时间")
private Date[] createTime;
}

View File

@@ -0,0 +1,36 @@
package com.jojubanking.boot.module.infra.controller.admin.file.vo.config;
import com.jojubanking.boot.framework.file.core.client.FileClientConfig;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import javax.validation.constraints.NotNull;
import java.util.Date;
@ApiModel("管理后台 - 文件配置 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class FileConfigRespVO extends FileConfigBaseVO {
@ApiModelProperty(value = "编号", required = true, example = "1")
private Long id;
@ApiModelProperty(value = "存储器", required = true, example = "1", notes = "参见 FileStorageEnum 枚举类")
@NotNull(message = "存储器不能为空")
private Integer storage;
@ApiModelProperty(value = "是否为主配置", required = true, example = "true")
@NotNull(message = "是否为主配置不能为空")
private Boolean master;
@ApiModelProperty(value = "存储配置", required = true)
private FileClientConfig config;
@ApiModelProperty(value = "创建时间", required = true)
private Date createTime;
}

View File

@@ -0,0 +1,26 @@
package com.jojubanking.boot.module.infra.controller.admin.file.vo.config;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import javax.validation.constraints.NotNull;
import java.util.Map;
@ApiModel("管理后台 - 文件配置更新 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class FileConfigUpdateReqVO extends FileConfigBaseVO {
@ApiModelProperty(value = "编号", required = true, example = "1")
@NotNull(message = "编号不能为空")
private Long id;
@ApiModelProperty(value = "存储配置", required = true, notes = "配置是动态参数,所以使用 Map 接收")
@NotNull(message = "存储配置不能为空")
private Map<String, Object> config;
}

View File

@@ -0,0 +1,31 @@
package com.jojubanking.boot.module.infra.controller.admin.file.vo.file;
import com.jojubanking.boot.framework.common.pojo.PageParam;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
import static com.jojubanking.boot.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@ApiModel("管理后台 - 文件分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class FilePageReqVO extends PageParam {
@ApiModelProperty(value = "文件路径", example = "joju", notes = "模糊匹配")
private String path;
@ApiModelProperty(value = "文件类型", example = "application/octet-stream", notes = "模糊匹配")
private String type;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "创建时间")
private Date[] createTime;
}

View File

@@ -0,0 +1,37 @@
package com.jojubanking.boot.module.infra.controller.admin.file.vo.file;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
@ApiModel(value = "管理后台 - 文件 Response VO", description = "不返回 content 字段,太大")
@Data
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 = "joju.jpg")
private String path;
@ApiModelProperty(value = "原文件名", required = true, example = "joju.jpg")
private String name;
@ApiModelProperty(value = "文件 URL", required = true, example = "https://www.iocoder.cn/joju.jpg")
private String url;
@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;
}

View File

@@ -0,0 +1,16 @@
package com.jojubanking.boot.module.infra.controller.admin.file.vo.file;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel(value = "管理后台 - 上传文件 VO")
public class UploadRespVO {
@ApiModelProperty(value = "文件名", required = true, example = "joju.jpg")
private String fileName;
@ApiModelProperty(value = "文件 URL", required = true, example = "https://www.iocoder.cn/joju.jpg")
private String fileUrl;
}

View File

@@ -0,0 +1,145 @@
package com.jojubanking.boot.module.infra.controller.admin.job;
import com.jojubanking.boot.framework.common.pojo.CommonResult;
import com.jojubanking.boot.framework.common.pojo.PageResult;
import com.jojubanking.boot.framework.excel.core.util.ExcelUtils;
import com.jojubanking.boot.framework.operatelog.core.annotations.OperateLog;
import com.jojubanking.boot.framework.quartz.core.util.CronUtils;
import com.jojubanking.boot.module.infra.controller.admin.job.vo.job.*;
import com.jojubanking.boot.module.infra.convert.job.JobConvert;
import com.jojubanking.boot.module.infra.dal.dataobject.job.JobDO;
import com.jojubanking.boot.module.infra.service.job.JobService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.quartz.SchedulerException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import static com.jojubanking.boot.framework.common.pojo.CommonResult.success;
import static com.jojubanking.boot.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
@Api(tags = "管理后台 - 定时任务")
@RestController
@RequestMapping("/infra/job")
@Validated
public class JobController {
@Resource
private JobService jobService;
@PostMapping("/create")
@ApiOperation("创建定时任务")
@PreAuthorize("@ss.hasPermission('infra:job:create')")
public CommonResult<Long> createJob(@Valid @RequestBody JobCreateReqVO createReqVO)
throws SchedulerException {
return success(jobService.createJob(createReqVO));
}
@PutMapping("/update")
@ApiOperation("更新定时任务")
@PreAuthorize("@ss.hasPermission('infra:job:update')")
public CommonResult<Boolean> updateJob(@Valid @RequestBody JobUpdateReqVO updateReqVO)
throws SchedulerException {
jobService.updateJob(updateReqVO);
return success(true);
}
@PutMapping("/update-status")
@ApiOperation("更新定时任务的状态")
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class),
@ApiImplicitParam(name = "status", value = "状态", required = true, example = "1", dataTypeClass = Integer.class),
})
@PreAuthorize("@ss.hasPermission('infra:job:update')")
public CommonResult<Boolean> updateJobStatus(@RequestParam(value = "id") Long id, @RequestParam("status") Integer status)
throws SchedulerException {
jobService.updateJobStatus(id, status);
return success(true);
}
@DeleteMapping("/delete")
@ApiOperation("删除定时任务")
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('infra:job:delete')")
public CommonResult<Boolean> deleteJob(@RequestParam("id") Long id)
throws SchedulerException {
jobService.deleteJob(id);
return success(true);
}
@PutMapping("/trigger")
@ApiOperation("触发定时任务")
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('infra:job:trigger')")
public CommonResult<Boolean> triggerJob(@RequestParam("id") Long id) throws SchedulerException {
jobService.triggerJob(id);
return success(true);
}
@GetMapping("/get")
@ApiOperation("获得定时任务")
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('infra:job:query')")
public CommonResult<JobRespVO> getJob(@RequestParam("id") Long id) {
JobDO job = jobService.getJob(id);
return success(JobConvert.INSTANCE.convert(job));
}
@GetMapping("/list")
@ApiOperation("获得定时任务列表")
@ApiImplicitParam(name = "ids", value = "编号列表", required = true, dataTypeClass = List.class)
@PreAuthorize("@ss.hasPermission('infra:job:query')")
public CommonResult<List<JobRespVO>> getJobList(@RequestParam("ids") Collection<Long> ids) {
List<JobDO> list = jobService.getJobList(ids);
return success(JobConvert.INSTANCE.convertList(list));
}
@GetMapping("/page")
@ApiOperation("获得定时任务分页")
@PreAuthorize("@ss.hasPermission('infra:job:query')")
public CommonResult<PageResult<JobRespVO>> getJobPage(@Valid JobPageReqVO pageVO) {
PageResult<JobDO> pageResult = jobService.getJobPage(pageVO);
return success(JobConvert.INSTANCE.convertPage(pageResult));
}
@GetMapping("/export-excel")
@ApiOperation("导出定时任务 Excel")
@PreAuthorize("@ss.hasPermission('infra:job:export')")
@OperateLog(type = EXPORT)
public void exportJobExcel(@Valid JobExportReqVO exportReqVO,
HttpServletResponse response) throws IOException {
List<JobDO> list = jobService.getJobList(exportReqVO);
// 导出 Excel
List<JobExcelVO> datas = JobConvert.INSTANCE.convertList02(list);
ExcelUtils.write(response, "定时任务.xls", "数据", JobExcelVO.class, datas);
}
@GetMapping("/get_next_times")
@ApiOperation("获得定时任务的下 n 次执行时间")
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class),
@ApiImplicitParam(name = "count", value = "数量", example = "5", dataTypeClass = Long.class)
})
@PreAuthorize("@ss.hasPermission('infra:job:query')")
public CommonResult<List<Date>> getJobNextTimes(@RequestParam("id") Long id,
@RequestParam(value = "count", required = false, defaultValue = "5") Integer count) {
JobDO job = jobService.getJob(id);
if (job == null) {
return success(Collections.emptyList());
}
return success(CronUtils.getNextTimes(job.getCronExpression(), count));
}
}

View File

@@ -0,0 +1,81 @@
package com.jojubanking.boot.module.infra.controller.admin.job;
import com.jojubanking.boot.framework.common.pojo.CommonResult;
import com.jojubanking.boot.framework.common.pojo.PageResult;
import com.jojubanking.boot.framework.excel.core.util.ExcelUtils;
import com.jojubanking.boot.framework.operatelog.core.annotations.OperateLog;
import com.jojubanking.boot.module.infra.controller.admin.job.vo.log.JobLogExcelVO;
import com.jojubanking.boot.module.infra.controller.admin.job.vo.log.JobLogExportReqVO;
import com.jojubanking.boot.module.infra.controller.admin.job.vo.log.JobLogPageReqVO;
import com.jojubanking.boot.module.infra.controller.admin.job.vo.log.JobLogRespVO;
import com.jojubanking.boot.module.infra.convert.job.JobLogConvert;
import com.jojubanking.boot.module.infra.dal.dataobject.job.JobLogDO;
import com.jojubanking.boot.module.infra.service.job.JobLogService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import static com.jojubanking.boot.framework.common.pojo.CommonResult.success;
import static com.jojubanking.boot.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
@Api(tags = "管理后台 - 定时任务日志")
@RestController
@RequestMapping("/infra/job-log")
@Validated
public class JobLogController {
@Resource
private JobLogService jobLogService;
@GetMapping("/get")
@ApiOperation("获得定时任务日志")
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('infra:job:query')")
public CommonResult<JobLogRespVO> getJobLog(@RequestParam("id") Long id) {
JobLogDO jobLog = jobLogService.getJobLog(id);
return success(JobLogConvert.INSTANCE.convert(jobLog));
}
@GetMapping("/list")
@ApiOperation("获得定时任务日志列表")
@ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)
@PreAuthorize("@ss.hasPermission('infra:job:query')")
public CommonResult<List<JobLogRespVO>> getJobLogList(@RequestParam("ids") Collection<Long> ids) {
List<JobLogDO> list = jobLogService.getJobLogList(ids);
return success(JobLogConvert.INSTANCE.convertList(list));
}
@GetMapping("/page")
@ApiOperation("获得定时任务日志分页")
@PreAuthorize("@ss.hasPermission('infra:job:query')")
public CommonResult<PageResult<JobLogRespVO>> getJobLogPage(@Valid JobLogPageReqVO pageVO) {
PageResult<JobLogDO> pageResult = jobLogService.getJobLogPage(pageVO);
return success(JobLogConvert.INSTANCE.convertPage(pageResult));
}
@GetMapping("/export-excel")
@ApiOperation("导出定时任务日志 Excel")
@PreAuthorize("@ss.hasPermission('infra:job:export')")
@OperateLog(type = EXPORT)
public void exportJobLogExcel(@Valid JobLogExportReqVO exportReqVO,
HttpServletResponse response) throws IOException {
List<JobLogDO> list = jobLogService.getJobLogList(exportReqVO);
// 导出 Excel
List<JobLogExcelVO> datas = JobLogConvert.INSTANCE.convertList02(list);
ExcelUtils.write(response, "任务日志.xls", "数据", JobLogExcelVO.class, datas);
}
}

View File

@@ -0,0 +1,37 @@
package com.jojubanking.boot.module.infra.controller.admin.job.vo.job;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
* 定时任务 Base VO提供给添加、修改、详细的子 VO 使用
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
*/
@Data
public class JobBaseVO {
@ApiModelProperty(value = "任务名称", required = true, example = "测试任务")
@NotNull(message = "任务名称不能为空")
private String name;
@ApiModelProperty(value = "处理器的参数", example = "joju")
private String handlerParam;
@ApiModelProperty(value = "CRON 表达式", required = true, example = "0/10 * * * * ? *")
@NotNull(message = "CRON 表达式不能为空")
private String cronExpression;
@ApiModelProperty(value = "重试次数", required = true, example = "3")
@NotNull(message = "重试次数不能为空")
private Integer retryCount;
@ApiModelProperty(value = "重试间隔", required = true, example = "1000")
@NotNull(message = "重试间隔不能为空")
private Integer retryInterval;
@ApiModelProperty(value = "监控超时时间", example = "1000")
private Integer monitorTimeout;
}

View File

@@ -0,0 +1,21 @@
package com.jojubanking.boot.module.infra.controller.admin.job.vo.job;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import javax.validation.constraints.NotNull;
@ApiModel("管理后台 - 定时任务创建 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class JobCreateReqVO extends JobBaseVO {
@ApiModelProperty(value = "处理器的名字", required = true, example = "sysUserSessionTimeoutJob")
@NotNull(message = "处理器的名字不能为空")
private String handlerName;
}

View File

@@ -0,0 +1,56 @@
package com.jojubanking.boot.module.infra.controller.admin.job.vo.job;
import com.jojubanking.boot.framework.excel.core.annotations.DictFormat;
import com.jojubanking.boot.framework.excel.core.convert.DictConvert;
import com.jojubanking.boot.module.infra.enums.DictTypeConstants;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
import java.util.Date;
/**
* 定时任务 Excel VO
*
* @author TW
*/
@Data
public class JobExcelVO {
@ExcelProperty("任务编号")
private Long id;
@ExcelProperty("任务名称")
private String name;
@ExcelProperty(value = "任务状态", converter = DictConvert.class)
@DictFormat(DictTypeConstants.JOB_STATUS)
private Integer status;
@ExcelProperty("处理器的名字")
private String handlerName;
@ExcelProperty("处理器的参数")
private String handlerParam;
@ExcelProperty("CRON 表达式")
private String cronExpression;
@ExcelProperty("最后一次执行的开始时间")
private Date executeBeginTime;
@ExcelProperty("最后一次执行的结束时间")
private Date executeEndTime;
@ExcelProperty("上一次触发时间")
private Date firePrevTime;
@ExcelProperty("下一次触发时间")
private Date fireNextTime;
@ExcelProperty("监控超时时间")
private Integer monitorTimeout;
@ExcelProperty("创建时间")
private Date createTime;
}

View File

@@ -0,0 +1,20 @@
package com.jojubanking.boot.module.infra.controller.admin.job.vo.job;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ApiModel(value = "管理后台 - 定时任务 Excel 导出 Request VO", description = "参数和 JobPageReqVO 是一致的")
@Data
public class JobExportReqVO {
@ApiModelProperty(value = "任务名称", example = "测试任务", notes = "模糊匹配")
private String name;
@ApiModelProperty(value = "任务状态", example = "1", notes = "参见 JobStatusEnum 枚举")
private Integer status;
@ApiModelProperty(value = "处理器的名字", example = "UserSessionTimeoutJob", notes = "模糊匹配")
private String handlerName;
}

View File

@@ -0,0 +1,25 @@
package com.jojubanking.boot.module.infra.controller.admin.job.vo.job;
import com.jojubanking.boot.framework.common.pojo.PageParam;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
@ApiModel("管理后台 - 定时任务分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class JobPageReqVO extends PageParam {
@ApiModelProperty(value = "任务名称", example = "测试任务", notes = "模糊匹配")
private String name;
@ApiModelProperty(value = "任务状态", example = "1", notes = "参见 JobStatusEnum 枚举")
private Integer status;
@ApiModelProperty(value = "处理器的名字", example = "sysUserSessionTimeoutJob", notes = "模糊匹配")
private String handlerName;
}

View File

@@ -0,0 +1,31 @@
package com.jojubanking.boot.module.infra.controller.admin.job.vo.job;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import javax.validation.constraints.NotNull;
import java.util.Date;
@ApiModel("管理后台 - 定时任务 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class JobRespVO extends JobBaseVO {
@ApiModelProperty(value = "任务编号", required = true, example = "1024")
private Long id;
@ApiModelProperty(value = "任务状态", required = true, example = "1")
private Integer status;
@ApiModelProperty(value = "处理器的名字", required = true, example = "sysUserSessionTimeoutJob")
@NotNull(message = "处理器的名字不能为空")
private String handlerName;
@ApiModelProperty(value = "创建时间", required = true)
private Date createTime;
}

View File

@@ -0,0 +1,21 @@
package com.jojubanking.boot.module.infra.controller.admin.job.vo.job;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import javax.validation.constraints.NotNull;
@ApiModel("管理后台 - 定时任务更新 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class JobUpdateReqVO extends JobBaseVO {
@ApiModelProperty(value = "任务编号", required = true, example = "1024")
@NotNull(message = "任务编号不能为空")
private Long id;
}

View File

@@ -0,0 +1,53 @@
package com.jojubanking.boot.module.infra.controller.admin.job.vo.log;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.NotNull;
import java.util.Date;
import static com.jojubanking.boot.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
/**
* 定时任务日志 Base VO提供给添加、修改、详细的子 VO 使用
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
*/
@Data
public class JobLogBaseVO {
@ApiModelProperty(value = "任务编号", required = true, example = "1024")
@NotNull(message = "任务编号不能为空")
private Long jobId;
@ApiModelProperty(value = "处理器的名字", required = true, example = "sysUserSessionTimeoutJob")
@NotNull(message = "处理器的名字不能为空")
private String handlerName;
@ApiModelProperty(value = "处理器的参数", example = "joju")
private String handlerParam;
@ApiModelProperty(value = "第几次执行", required = true, example = "1")
@NotNull(message = "第几次执行不能为空")
private Integer executeIndex;
@ApiModelProperty(value = "开始执行时间", required = true)
@NotNull(message = "开始执行时间不能为空")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private Date beginTime;
@ApiModelProperty(value = "结束执行时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private Date endTime;
@ApiModelProperty(value = "执行时长", example = "123")
private Integer duration;
@ApiModelProperty(value = "任务状态", required = true, example = "1", notes = "参见 JobLogStatusEnum 枚举")
@NotNull(message = "任务状态不能为空")
private Integer status;
@ApiModelProperty(value = "结果数据", example = "执行成功")
private String result;
}

View File

@@ -0,0 +1,53 @@
package com.jojubanking.boot.module.infra.controller.admin.job.vo.log;
import com.jojubanking.boot.framework.excel.core.annotations.DictFormat;
import com.jojubanking.boot.framework.excel.core.convert.DictConvert;
import com.jojubanking.boot.module.infra.enums.DictTypeConstants;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
import java.util.Date;
/**
* 定时任务 Excel VO
*
* @author 芋艿
*/
@Data
public class JobLogExcelVO {
@ExcelProperty("日志编号")
private Long id;
@ExcelProperty("任务编号")
private Long jobId;
@ExcelProperty("处理器的名字")
private String handlerName;
@ExcelProperty("处理器的参数")
private String handlerParam;
@ExcelProperty("第几次执行")
private Integer executeIndex;
@ExcelProperty("开始执行时间")
private Date beginTime;
@ExcelProperty("结束执行时间")
private Date endTime;
@ExcelProperty("执行时长")
private Integer duration;
@ExcelProperty(value = "任务状态", converter = DictConvert.class)
@DictFormat(DictTypeConstants.JOB_STATUS)
private Integer status;
@ExcelProperty("结果数据")
private String result;
@ExcelProperty("创建时间")
private Date createTime;
}

View File

@@ -0,0 +1,33 @@
package com.jojubanking.boot.module.infra.controller.admin.job.vo.log;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
import static com.jojubanking.boot.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@ApiModel(value = "管理后台 - 定时任务 Excel 导出 Request VO", description = "参数和 JobLogPageReqVO 是一致的")
@Data
public class JobLogExportReqVO {
@ApiModelProperty(value = "任务编号", example = "10")
private Long jobId;
@ApiModelProperty(value = "处理器的名字", notes = "模糊匹配")
private String handlerName;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "开始执行时间")
private Date beginTime;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "结束执行时间")
private Date endTime;
@ApiModelProperty(value = "任务状态", notes = "参见 JobLogStatusEnum 枚举")
private Integer status;
}

View File

@@ -0,0 +1,38 @@
package com.jojubanking.boot.module.infra.controller.admin.job.vo.log;
import com.jojubanking.boot.framework.common.pojo.PageParam;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
import static com.jojubanking.boot.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@ApiModel("管理后台 - 定时任务日志分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class JobLogPageReqVO extends PageParam {
@ApiModelProperty(value = "任务编号", example = "10")
private Long jobId;
@ApiModelProperty(value = "处理器的名字", notes = "模糊匹配")
private String handlerName;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "开始执行时间")
private Date beginTime;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "结束执行时间")
private Date endTime;
@ApiModelProperty(value = "任务状态", notes = "参见 JobLogStatusEnum 枚举")
private Integer status;
}

View File

@@ -0,0 +1,23 @@
package com.jojubanking.boot.module.infra.controller.admin.job.vo.log;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.util.Date;
@ApiModel("管理后台 - 定时任务日志 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class JobLogRespVO extends JobLogBaseVO {
@ApiModelProperty(value = "日志编号", required = true, example = "1024")
private Long id;
@ApiModelProperty(value = "创建时间", required = true)
private Date createTime;
}

View File

@@ -0,0 +1,60 @@
package com.jojubanking.boot.module.infra.controller.admin.logger;
import com.jojubanking.boot.framework.common.pojo.CommonResult;
import com.jojubanking.boot.framework.common.pojo.PageResult;
import com.jojubanking.boot.framework.excel.core.util.ExcelUtils;
import com.jojubanking.boot.framework.operatelog.core.annotations.OperateLog;
import com.jojubanking.boot.module.infra.controller.admin.logger.vo.apiaccesslog.ApiAccessLogExcelVO;
import com.jojubanking.boot.module.infra.controller.admin.logger.vo.apiaccesslog.ApiAccessLogExportReqVO;
import com.jojubanking.boot.module.infra.controller.admin.logger.vo.apiaccesslog.ApiAccessLogPageReqVO;
import com.jojubanking.boot.module.infra.controller.admin.logger.vo.apiaccesslog.ApiAccessLogRespVO;
import com.jojubanking.boot.module.infra.convert.logger.ApiAccessLogConvert;
import com.jojubanking.boot.module.infra.dal.dataobject.logger.ApiAccessLogDO;
import com.jojubanking.boot.module.infra.service.logger.ApiAccessLogService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.List;
import static com.jojubanking.boot.framework.common.pojo.CommonResult.success;
import static com.jojubanking.boot.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
@Api(tags = "管理后台 - API 访问日志")
@RestController
@RequestMapping("/infra/api-access-log")
@Validated
public class ApiAccessLogController {
@Resource
private ApiAccessLogService apiAccessLogService;
@GetMapping("/page")
@ApiOperation("获得API 访问日志分页")
@PreAuthorize("@ss.hasPermission('infra:api-access-log:query')")
public CommonResult<PageResult<ApiAccessLogRespVO>> getApiAccessLogPage(@Valid ApiAccessLogPageReqVO pageVO) {
PageResult<ApiAccessLogDO> pageResult = apiAccessLogService.getApiAccessLogPage(pageVO);
return success(ApiAccessLogConvert.INSTANCE.convertPage(pageResult));
}
@GetMapping("/export-excel")
@ApiOperation("导出API 访问日志 Excel")
@PreAuthorize("@ss.hasPermission('infra:api-access-log:export')")
@OperateLog(type = EXPORT)
public void exportApiAccessLogExcel(@Valid ApiAccessLogExportReqVO exportReqVO,
HttpServletResponse response) throws IOException {
List<ApiAccessLogDO> list = apiAccessLogService.getApiAccessLogList(exportReqVO);
// 导出 Excel
List<ApiAccessLogExcelVO> datas = ApiAccessLogConvert.INSTANCE.convertList02(list);
ExcelUtils.write(response, "API 访问日志.xls", "数据", ApiAccessLogExcelVO.class, datas);
}
}

View File

@@ -0,0 +1,74 @@
package com.jojubanking.boot.module.infra.controller.admin.logger;
import com.jojubanking.boot.framework.common.pojo.CommonResult;
import com.jojubanking.boot.framework.common.pojo.PageResult;
import com.jojubanking.boot.framework.excel.core.util.ExcelUtils;
import com.jojubanking.boot.framework.operatelog.core.annotations.OperateLog;
import com.jojubanking.boot.module.infra.controller.admin.logger.vo.apierrorlog.ApiErrorLogExcelVO;
import com.jojubanking.boot.module.infra.controller.admin.logger.vo.apierrorlog.ApiErrorLogExportReqVO;
import com.jojubanking.boot.module.infra.controller.admin.logger.vo.apierrorlog.ApiErrorLogPageReqVO;
import com.jojubanking.boot.module.infra.controller.admin.logger.vo.apierrorlog.ApiErrorLogRespVO;
import com.jojubanking.boot.module.infra.convert.logger.ApiErrorLogConvert;
import com.jojubanking.boot.module.infra.dal.dataobject.logger.ApiErrorLogDO;
import com.jojubanking.boot.module.infra.service.logger.ApiErrorLogService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.List;
import static com.jojubanking.boot.framework.common.pojo.CommonResult.success;
import static com.jojubanking.boot.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
import static com.jojubanking.boot.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
@Api(tags = "管理后台 - API 错误日志")
@RestController
@RequestMapping("/infra/api-error-log")
@Validated
public class ApiErrorLogController {
@Resource
private ApiErrorLogService apiErrorLogService;
@PutMapping("/update-status")
@ApiOperation("更新 API 错误日志的状态")
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class),
@ApiImplicitParam(name = "processStatus", value = "处理状态", required = true, example = "1", dataTypeClass = Integer.class)
})
@PreAuthorize("@ss.hasPermission('infra:api-error-log:update-status')")
public CommonResult<Boolean> updateApiErrorLogProcess(@RequestParam("id") Long id,
@RequestParam("processStatus") Integer processStatus) {
apiErrorLogService.updateApiErrorLogProcess(id, processStatus, getLoginUserId());
return success(true);
}
@GetMapping("/page")
@ApiOperation("获得 API 错误日志分页")
@PreAuthorize("@ss.hasPermission('infra:api-error-log:query')")
public CommonResult<PageResult<ApiErrorLogRespVO>> getApiErrorLogPage(@Valid ApiErrorLogPageReqVO pageVO) {
PageResult<ApiErrorLogDO> pageResult = apiErrorLogService.getApiErrorLogPage(pageVO);
return success(ApiErrorLogConvert.INSTANCE.convertPage(pageResult));
}
@GetMapping("/export-excel")
@ApiOperation("导出 API 错误日志 Excel")
@PreAuthorize("@ss.hasPermission('infra:api-error-log:export')")
@OperateLog(type = EXPORT)
public void exportApiErrorLogExcel(@Valid ApiErrorLogExportReqVO exportReqVO,
HttpServletResponse response) throws IOException {
List<ApiErrorLogDO> list = apiErrorLogService.getApiErrorLogList(exportReqVO);
// 导出 Excel
List<ApiErrorLogExcelVO> datas = ApiErrorLogConvert.INSTANCE.convertList02(list);
ExcelUtils.write(response, "API 错误日志.xls", "数据", ApiErrorLogExcelVO.class, datas);
}
}

View File

@@ -0,0 +1,75 @@
package com.jojubanking.boot.module.infra.controller.admin.logger.vo.apiaccesslog;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.NotNull;
import java.util.Date;
import static com.jojubanking.boot.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
/**
* API 访问日志 Base VO提供给添加、修改、详细的子 VO 使用
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
*/
@Data
public class ApiAccessLogBaseVO {
@ApiModelProperty(value = "链路追踪编号", required = true, example = "66600cb6-7852-11eb-9439-0242ac130002")
@NotNull(message = "链路追踪编号不能为空")
private String traceId;
@ApiModelProperty(value = "用户编号", required = true, example = "666")
@NotNull(message = "用户编号不能为空")
private Long userId;
@ApiModelProperty(value = "用户类型", required = true, example = "2", notes = "参见 UserTypeEnum 枚举")
@NotNull(message = "用户类型不能为空")
private Integer userType;
@ApiModelProperty(value = "应用名", required = true, example = "dashboard")
@NotNull(message = "应用名不能为空")
private String applicationName;
@ApiModelProperty(value = "请求方法名", required = true, example = "GET")
@NotNull(message = "请求方法名不能为空")
private String requestMethod;
@ApiModelProperty(value = "请求地址", required = true, example = "/xxx/yyy")
@NotNull(message = "请求地址不能为空")
private String requestUrl;
@ApiModelProperty(value = "请求参数")
private String requestParams;
@ApiModelProperty(value = "用户 IP", required = true, example = "127.0.0.1")
@NotNull(message = "用户 IP不能为空")
private String userIp;
@ApiModelProperty(value = "浏览器 UA", required = true, example = "Mozilla/5.0")
@NotNull(message = "浏览器 UA不能为空")
private String userAgent;
@ApiModelProperty(value = "开始请求时间", required = true)
@NotNull(message = "开始请求时间不能为空")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private Date beginTime;
@ApiModelProperty(value = "结束请求时间", required = true)
@NotNull(message = "结束请求时间不能为空")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private Date endTime;
@ApiModelProperty(value = "执行时长", required = true, example = "100")
@NotNull(message = "执行时长不能为空")
private Integer duration;
@ApiModelProperty(value = "结果码", required = true, example = "0")
@NotNull(message = "结果码不能为空")
private Integer resultCode;
@ApiModelProperty(value = "结果提示", example = "TW牛逼")
private String resultMsg;
}

View File

@@ -0,0 +1,65 @@
package com.jojubanking.boot.module.infra.controller.admin.logger.vo.apiaccesslog;
import com.jojubanking.boot.framework.excel.core.annotations.DictFormat;
import com.jojubanking.boot.framework.excel.core.convert.DictConvert;
import com.jojubanking.boot.module.system.enums.DictTypeConstants;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
import java.util.Date;
/**
* API 访问日志 Excel VO
*
* @author TW
*/
@Data
public class ApiAccessLogExcelVO {
@ExcelProperty("日志主键")
private Long id;
@ExcelProperty("链路追踪编号")
private String traceId;
@ExcelProperty("用户编号")
private Long userId;
@ExcelProperty(value = "用户类型", converter = DictConvert.class)
@DictFormat(DictTypeConstants.USER_TYPE)
private Integer userType;
@ExcelProperty("应用名")
private String applicationName;
@ExcelProperty("请求方法名")
private String requestMethod;
@ExcelProperty("请求地址")
private String requestUrl;
@ExcelProperty("请求参数")
private String requestParams;
@ExcelProperty("用户 IP")
private String userIp;
@ExcelProperty("浏览器 UA")
private String userAgent;
@ExcelProperty("开始请求时间")
private Date beginTime;
@ExcelProperty("结束请求时间")
private Date endTime;
@ExcelProperty("执行时长")
private Integer duration;
@ExcelProperty("结果码")
private Integer resultCode;
@ExcelProperty("结果提示")
private String resultMsg;
}

View File

@@ -0,0 +1,38 @@
package com.jojubanking.boot.module.infra.controller.admin.logger.vo.apiaccesslog;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
import static com.jojubanking.boot.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@ApiModel(value = "管理后台 - API 访问日志 Excel 导出 Request VO", description = "参数和 ApiAccessLogPageReqVO 是一致的")
@Data
public class ApiAccessLogExportReqVO {
@ApiModelProperty(value = "用户编号", example = "666")
private Long userId;
@ApiModelProperty(value = "用户类型", example = "2")
private Integer userType;
@ApiModelProperty(value = "应用名", example = "dashboard")
private String applicationName;
@ApiModelProperty(value = "请求地址", example = "/xxx/yyy", notes = "模糊匹配")
private String requestUrl;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "开始请求时间")
private Date[] beginTime;
@ApiModelProperty(value = "执行时长", example = "100", notes = "大于等于,单位:毫秒")
private Integer duration;
@ApiModelProperty(value = "结果码", example = "0")
private Integer resultCode;
}

View File

@@ -0,0 +1,43 @@
package com.jojubanking.boot.module.infra.controller.admin.logger.vo.apiaccesslog;
import com.jojubanking.boot.framework.common.pojo.PageParam;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
import static com.jojubanking.boot.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@ApiModel("管理后台 - API 访问日志分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ApiAccessLogPageReqVO extends PageParam {
@ApiModelProperty(value = "用户编号", example = "666")
private Long userId;
@ApiModelProperty(value = "用户类型", example = "2")
private Integer userType;
@ApiModelProperty(value = "应用名", example = "dashboard")
private String applicationName;
@ApiModelProperty(value = "请求地址", example = "/xxx/yyy", notes = "模糊匹配")
private String requestUrl;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "开始请求时间")
private Date[] beginTime;
@ApiModelProperty(value = "执行时长", example = "100", notes = "大于等于,单位:毫秒")
private Integer duration;
@ApiModelProperty(value = "结果码", example = "0")
private Integer resultCode;
}

View File

@@ -0,0 +1,23 @@
package com.jojubanking.boot.module.infra.controller.admin.logger.vo.apiaccesslog;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.util.Date;
@ApiModel("管理后台 - API 访问日志 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ApiAccessLogRespVO extends ApiAccessLogBaseVO {
@ApiModelProperty(value = "日志主键", required = true, example = "1024")
private Long id;
@ApiModelProperty(value = "创建时间", required = true)
private Date createTime;
}

View File

@@ -0,0 +1,96 @@
package com.jojubanking.boot.module.infra.controller.admin.logger.vo.apierrorlog;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.NotNull;
import java.util.Date;
import static com.jojubanking.boot.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
/**
* API 错误日志 Base VO提供给添加、修改、详细的子 VO 使用
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
*/
@Data
public class ApiErrorLogBaseVO {
@ApiModelProperty(value = "链路追踪编号", required = true, example = "66600cb6-7852-11eb-9439-0242ac130002")
@NotNull(message = "链路追踪编号不能为空")
private String traceId;
@ApiModelProperty(value = "用户编号", required = true, example = "666")
@NotNull(message = "用户编号不能为空")
private Integer userId;
@ApiModelProperty(value = "用户类型", required = true, example = "1")
@NotNull(message = "用户类型不能为空")
private Integer userType;
@ApiModelProperty(value = "应用名", required = true, example = "dashboard")
@NotNull(message = "应用名不能为空")
private String applicationName;
@ApiModelProperty(value = "请求方法名", required = true, example = "GET")
@NotNull(message = "请求方法名不能为空")
private String requestMethod;
@ApiModelProperty(value = "请求地址", required = true, example = "/xx/yy")
@NotNull(message = "请求地址不能为空")
private String requestUrl;
@ApiModelProperty(value = "请求参数", required = true)
@NotNull(message = "请求参数不能为空")
private String requestParams;
@ApiModelProperty(value = "用户 IP", required = true, example = "127.0.0.1")
@NotNull(message = "用户 IP不能为空")
private String userIp;
@ApiModelProperty(value = "浏览器 UA", required = true, example = "Mozilla/5.0")
@NotNull(message = "浏览器 UA不能为空")
private String userAgent;
@ApiModelProperty(value = "异常发生时间", required = true)
@NotNull(message = "异常发生时间不能为空")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private Date exceptionTime;
@ApiModelProperty(value = "异常名", required = true)
@NotNull(message = "异常名不能为空")
private String exceptionName;
@ApiModelProperty(value = "异常导致的消息", required = true)
@NotNull(message = "异常导致的消息不能为空")
private String exceptionMessage;
@ApiModelProperty(value = "异常导致的根消息", required = true)
@NotNull(message = "异常导致的根消息不能为空")
private String exceptionRootCauseMessage;
@ApiModelProperty(value = "异常的栈轨迹", required = true)
@NotNull(message = "异常的栈轨迹不能为空")
private String exceptionStackTrace;
@ApiModelProperty(value = "异常发生的类全名", required = true)
@NotNull(message = "异常发生的类全名不能为空")
private String exceptionClassName;
@ApiModelProperty(value = "异常发生的类文件", required = true)
@NotNull(message = "异常发生的类文件不能为空")
private String exceptionFileName;
@ApiModelProperty(value = "异常发生的方法名", required = true)
@NotNull(message = "异常发生的方法名不能为空")
private String exceptionMethodName;
@ApiModelProperty(value = "异常发生的方法所在行", required = true)
@NotNull(message = "异常发生的方法所在行不能为空")
private Integer exceptionLineNumber;
@ApiModelProperty(value = "处理状态", required = true, example = "0")
@NotNull(message = "处理状态不能为空")
private Integer processStatus;
}

View File

@@ -0,0 +1,90 @@
package com.jojubanking.boot.module.infra.controller.admin.logger.vo.apierrorlog;
import com.jojubanking.boot.framework.excel.core.annotations.DictFormat;
import com.jojubanking.boot.framework.excel.core.convert.DictConvert;
import com.jojubanking.boot.module.infra.enums.DictTypeConstants;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
import java.util.Date;
/**
* API 错误日志 Excel VO
*
* @author TW
*/
@Data
public class ApiErrorLogExcelVO {
@ExcelProperty("编号")
private Integer id;
@ExcelProperty("链路追踪编号")
private String traceId;
@ExcelProperty("用户编号")
private Integer userId;
@ExcelProperty(value = "用户类型", converter = DictConvert.class)
@DictFormat(com.jojubanking.boot.module.system.enums.DictTypeConstants.USER_TYPE)
private Integer userType;
@ExcelProperty("应用名")
private String applicationName;
@ExcelProperty("请求方法名")
private String requestMethod;
@ExcelProperty("请求地址")
private String requestUrl;
@ExcelProperty("请求参数")
private String requestParams;
@ExcelProperty("用户 IP")
private String userIp;
@ExcelProperty("浏览器 UA")
private String userAgent;
@ExcelProperty("异常发生时间")
private Date exceptionTime;
@ExcelProperty("异常名")
private String exceptionName;
@ExcelProperty("异常导致的消息")
private String exceptionMessage;
@ExcelProperty("异常导致的根消息")
private String exceptionRootCauseMessage;
@ExcelProperty("异常的栈轨迹")
private String exceptionStackTrace;
@ExcelProperty("异常发生的类全名")
private String exceptionClassName;
@ExcelProperty("异常发生的类文件")
private String exceptionFileName;
@ExcelProperty("异常发生的方法名")
private String exceptionMethodName;
@ExcelProperty("异常发生的方法所在行")
private Integer exceptionLineNumber;
@ExcelProperty("创建时间")
private Date createTime;
@ExcelProperty(value = "处理状态", converter = DictConvert.class)
@DictFormat(DictTypeConstants.API_ERROR_LOG_PROCESS_STATUS)
private Integer processStatus;
@ExcelProperty("处理时间")
private Date processTime;
@ExcelProperty("处理用户编号")
private Integer processUserId;
}

View File

@@ -0,0 +1,35 @@
package com.jojubanking.boot.module.infra.controller.admin.logger.vo.apierrorlog;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
import static com.jojubanking.boot.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@ApiModel(value = "管理后台 - API 错误日志 Excel 导出 Request VO", description = "参数和 ApiErrorLogPageReqVO 是一致的")
@Data
public class ApiErrorLogExportReqVO {
@ApiModelProperty(value = "用户编号", example = "666")
private Long userId;
@ApiModelProperty(value = "用户类型", example = "1")
private Integer userType;
@ApiModelProperty(value = "应用名", example = "dashboard")
private String applicationName;
@ApiModelProperty(value = "请求地址", example = "/xx/yy")
private String requestUrl;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "异常发生时间")
private Date[] exceptionTime;
@ApiModelProperty(value = "处理状态", example = "0")
private Integer processStatus;
}

View File

@@ -0,0 +1,40 @@
package com.jojubanking.boot.module.infra.controller.admin.logger.vo.apierrorlog;
import com.jojubanking.boot.framework.common.pojo.PageParam;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
import static com.jojubanking.boot.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@ApiModel("管理后台 - API 错误日志分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ApiErrorLogPageReqVO extends PageParam {
@ApiModelProperty(value = "用户编号", example = "666")
private Long userId;
@ApiModelProperty(value = "用户类型", example = "1")
private Integer userType;
@ApiModelProperty(value = "应用名", example = "dashboard")
private String applicationName;
@ApiModelProperty(value = "请求地址", example = "/xx/yy")
private String requestUrl;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "异常发生时间")
private Date[] exceptionTime;
@ApiModelProperty(value = "处理状态", example = "0")
private Integer processStatus;
}

View File

@@ -0,0 +1,29 @@
package com.jojubanking.boot.module.infra.controller.admin.logger.vo.apierrorlog;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.util.Date;
@ApiModel("管理后台 - API 错误日志 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ApiErrorLogRespVO extends ApiErrorLogBaseVO {
@ApiModelProperty(value = "编号", required = true, example = "1024")
private Integer id;
@ApiModelProperty(value = "创建时间", required = true)
private Date createTime;
@ApiModelProperty(value = "处理时间", required = true)
private Date processTime;
@ApiModelProperty(value = "处理用户编号", example = "233")
private Integer processUserId;
}

View File

@@ -0,0 +1,9 @@
### 请求 /infra/redis/get-monitor-info 接口 => 成功
GET {{baseUrl}}/infra/redis/get-monitor-info
Authorization: Bearer {{token}}
tenant-id: {{adminTenentId}}
### 请求 /infra/redis/get-key-list 接口 => 成功
GET {{baseUrl}}/infra/redis/get-key-list
Authorization: Bearer {{token}}
tenant-id: {{adminTenentId}}

View File

@@ -0,0 +1,112 @@
package com.jojubanking.boot.module.infra.controller.admin.redis;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.jojubanking.boot.framework.common.pojo.CommonResult;
import com.jojubanking.boot.framework.redis.core.RedisKeyDefine;
import com.jojubanking.boot.framework.redis.core.RedisKeyRegistry;
import com.jojubanking.boot.module.infra.controller.admin.redis.vo.RedisKeyDefineRespVO;
import com.jojubanking.boot.module.infra.controller.admin.redis.vo.RedisKeyValueRespVO;
import com.jojubanking.boot.module.infra.controller.admin.redis.vo.RedisMonitorRespVO;
import com.jojubanking.boot.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.*;
import javax.annotation.Resource;
import java.util.*;
import static com.jojubanking.boot.framework.common.pojo.CommonResult.success;
@Api(tags = "管理后台 - Redis 监控")
@RestController
@RequestMapping("/infra/redis")
public class RedisController {
@Resource
private StringRedisTemplate stringRedisTemplate;
@GetMapping("/get-monitor-info")
@ApiOperation("获得 Redis 监控信息")
@PreAuthorize("@ss.hasPermission('infra:redis:get-monitor-info')")
public CommonResult<RedisMonitorRespVO> getRedisMonitorInfo() {
// 获得 Redis 统计信息
Properties info = stringRedisTemplate.execute((RedisCallback<Properties>) RedisServerCommands::info);
Long dbSize = stringRedisTemplate.execute(RedisServerCommands::dbSize);
Properties commandStats = stringRedisTemplate.execute((
RedisCallback<Properties>) connection -> connection.info("commandstats"));
assert commandStats != null; // 断言,避免警告
// 拼接结果返回
return success(RedisConvert.INSTANCE.build(info, dbSize, commandStats));
}
@GetMapping("/get-key-define-list")
@ApiOperation("获得 Redis Key 模板列表")
@PreAuthorize("@ss.hasPermission('infra:redis:get-key-list')")
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

@@ -0,0 +1,36 @@
package com.jojubanking.boot.module.infra.controller.admin.redis.vo;
import com.jojubanking.boot.framework.redis.core.RedisKeyDefine;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import java.time.Duration;
@ApiModel("管理后台 - Redis Key 信息 Response VO")
@Data
@Builder
@AllArgsConstructor
public class RedisKeyDefineRespVO {
@ApiModelProperty(value = "Key 模板", required = true, example = "login_user:%s")
private String keyTemplate;
@ApiModelProperty(value = "Key 类型的枚举", required = true, example = "String")
private RedisKeyDefine.KeyTypeEnum keyType;
@ApiModelProperty(value = "Value 类型", required = true, example = "java.lang.String")
private Class<?> valueType;
@ApiModelProperty(value = "超时类型", required = true, example = "1")
private RedisKeyDefine.TimeoutTypeEnum timeoutType;
@ApiModelProperty(value = "过期时间,单位:毫秒", required = true, example = "1024")
private Duration timeout;
@ApiModelProperty(value = "备注", required = true, example = "啦啦啦啦~")
private String memo;
}

View File

@@ -0,0 +1,19 @@
package com.jojubanking.boot.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

@@ -0,0 +1,44 @@
package com.jojubanking.boot.module.infra.controller.admin.redis.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import java.util.List;
import java.util.Properties;
@ApiModel("管理后台 - Redis 监控信息 Response VO")
@Data
@Builder
@AllArgsConstructor
public class RedisMonitorRespVO {
@ApiModelProperty(value = "Redis info 指令结果", required = true, notes = "具体字段,查看 Redis 文档")
private Properties info;
@ApiModelProperty(value = "Redis key 数量", required = true, example = "1024")
private Long dbSize;
@ApiModelProperty(value = "CommandStat 数组", required = true)
private List<CommandStat> commandStats;
@ApiModel("Redis 命令统计结果")
@Data
@Builder
@AllArgsConstructor
public static class CommandStat {
@ApiModelProperty(value = "Redis 命令", required = true, example = "get")
private String command;
@ApiModelProperty(value = "调用次数", required = true, example = "1024")
private Long calls;
@ApiModelProperty(value = "消耗 CPU 秒数", required = true, example = "666")
private Long usec;
}
}

View File

@@ -0,0 +1,19 @@
### 请求 /infra/test-demo/get 接口 => 成功
GET {{baseUrl}}/infra/test-demo/get?id=106
Authorization: Bearer {{token}}
tenant-id: {{adminTenentId}}
### 请求 /infra/test-demo/update 接口 => 成功
PUT {{baseUrl}}/infra/test-demo/update
Authorization: Bearer {{token}}
tenant-id: {{adminTenentId}}
Content-Type: application/json
{
"id": 106,
"name": "测试",
"status": "0",
"type": 1,
"category": 1
}

View File

@@ -0,0 +1,97 @@
package com.jojubanking.boot.module.infra.controller.admin.test;
import com.jojubanking.boot.framework.common.pojo.CommonResult;
import com.jojubanking.boot.framework.common.pojo.PageResult;
import com.jojubanking.boot.framework.excel.core.util.ExcelUtils;
import com.jojubanking.boot.framework.operatelog.core.annotations.OperateLog;
import com.jojubanking.boot.module.infra.controller.admin.test.vo.*;
import com.jojubanking.boot.module.infra.convert.test.TestDemoConvert;
import com.jojubanking.boot.module.infra.dal.dataobject.test.TestDemoDO;
import com.jojubanking.boot.module.infra.service.test.TestDemoService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import static com.jojubanking.boot.framework.common.pojo.CommonResult.success;
import static com.jojubanking.boot.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
@Api(tags = "管理后台 - 字典类型")
@RestController
@RequestMapping("/infra/test-demo")
@Validated
public class TestDemoController {
@Resource
private TestDemoService testDemoService;
@PostMapping("/create")
@ApiOperation("创建字典类型")
@PreAuthorize("@ss.hasPermission('infra:test-demo:create')")
public CommonResult<Long> createTestDemo(@Valid @RequestBody TestDemoCreateReqVO createReqVO) {
return success(testDemoService.createTestDemo(createReqVO));
}
@PutMapping("/update")
@ApiOperation("更新字典类型")
@PreAuthorize("@ss.hasPermission('infra:test-demo:update')")
public CommonResult<Boolean> updateTestDemo(@Valid @RequestBody TestDemoUpdateReqVO updateReqVO) {
testDemoService.updateTestDemo(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@ApiOperation("删除字典类型")
@ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('infra:test-demo:delete')")
public CommonResult<Boolean> deleteTestDemo(@RequestParam("id") Long id) {
testDemoService.deleteTestDemo(id);
return success(true);
}
@GetMapping("/get")
@ApiOperation("获得字典类型")
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('infra:test-demo:query')")
public CommonResult<TestDemoRespVO> getTestDemo(@RequestParam("id") Long id) {
TestDemoDO testDemo = testDemoService.getTestDemo(id);
return success(TestDemoConvert.INSTANCE.convert(testDemo));
}
@GetMapping("/list")
@ApiOperation("获得字典类型列表")
@ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)
@PreAuthorize("@ss.hasPermission('infra:test-demo:query')")
public CommonResult<List<TestDemoRespVO>> getTestDemoList(@RequestParam("ids") Collection<Long> ids) {
List<TestDemoDO> list = testDemoService.getTestDemoList(ids);
return success(TestDemoConvert.INSTANCE.convertList(list));
}
@GetMapping("/page")
@ApiOperation("获得字典类型分页")
@PreAuthorize("@ss.hasPermission('infra:test-demo:query')") public CommonResult<PageResult<TestDemoRespVO>> getTestDemoPage(@Valid TestDemoPageReqVO pageVO) {
PageResult<TestDemoDO> pageResult = testDemoService.getTestDemoPage(pageVO);
return success(TestDemoConvert.INSTANCE.convertPage(pageResult));
}
@GetMapping("/export-excel")
@ApiOperation("导出字典类型 Excel")
@PreAuthorize("@ss.hasPermission('infra:test-demo:export')") @OperateLog(type = EXPORT)
public void exportTestDemoExcel(@Valid TestDemoExportReqVO exportReqVO,
HttpServletResponse response) throws IOException {
List<TestDemoDO> list = testDemoService.getTestDemoList(exportReqVO);
// 导出 Excel
List<TestDemoExcelVO> datas = TestDemoConvert.INSTANCE.convertList02(list);
ExcelUtils.write(response, "字典类型.xls", "数据", TestDemoExcelVO.class, datas);
}
}

View File

@@ -0,0 +1,34 @@
package com.jojubanking.boot.module.infra.controller.admin.test.vo;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
import javax.validation.constraints.*;
/**
* 字典类型 Base VO提供给添加、修改、详细的子 VO 使用
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
*/
@Data
public class TestDemoBaseVO {
@ApiModelProperty(value = "名字", required = true)
@NotNull(message = "名字不能为空")
private String name;
@ApiModelProperty(value = "状态", required = true)
@NotNull(message = "状态不能为空")
private Integer status;
@ApiModelProperty(value = "类型", required = true)
@NotNull(message = "类型不能为空")
private Integer type;
@ApiModelProperty(value = "分类", required = true)
@NotNull(message = "分类不能为空")
private Integer category;
@ApiModelProperty(value = "备注")
private String remark;
}

View File

@@ -0,0 +1,12 @@
package com.jojubanking.boot.module.infra.controller.admin.test.vo;
import lombok.*;
import io.swagger.annotations.*;
@ApiModel("管理后台 - 字典类型创建 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class TestDemoCreateReqVO extends TestDemoBaseVO {
}

View File

@@ -0,0 +1,38 @@
package com.jojubanking.boot.module.infra.controller.admin.test.vo;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
import com.alibaba.excel.annotation.ExcelProperty;
/**
* 字典类型 Excel VO
*
* @author TW
*/
@Data
public class TestDemoExcelVO {
@ExcelProperty("编号")
private Long id;
@ExcelProperty("名字")
private String name;
@ExcelProperty("状态")
private Integer status;
@ExcelProperty("类型")
private Integer type;
@ExcelProperty("分类")
private Integer category;
@ExcelProperty("备注")
private String remark;
@ExcelProperty("创建时间")
private Date createTime;
}

View File

@@ -0,0 +1,34 @@
package com.jojubanking.boot.module.infra.controller.admin.test.vo;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
import com.jojubanking.boot.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
import static com.jojubanking.boot.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@ApiModel(value = "管理后台 - 字典类型 Excel 导出 Request VO", description = "参数和 TestDemoPageReqVO 是一致的")
@Data
public class TestDemoExportReqVO {
@ApiModelProperty(value = "名字")
private String name;
@ApiModelProperty(value = "状态")
private Integer status;
@ApiModelProperty(value = "类型")
private Integer type;
@ApiModelProperty(value = "分类")
private Integer category;
@ApiModelProperty(value = "备注")
private String remark;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "创建时间")
private Date[] createTime;
}

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