refactor: 升级框架
This commit is contained in:
@@ -64,6 +64,13 @@
|
||||
<scope>provided</scope> <!-- 设置为 provided,主要是 PageParam 使用到 -->
|
||||
</dependency>
|
||||
|
||||
<!-- RPC 远程调用相关 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-openfeign-core</artifactId>
|
||||
<scope>provided</scope> <!-- 设置为 provided,主要是 api 包使用到 -->
|
||||
</dependency>
|
||||
|
||||
<!-- 监控相关 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.skywalking</groupId>
|
||||
|
||||
@@ -1,22 +1,21 @@
|
||||
package org.agt.module.infra.api.logger;
|
||||
package org.agt.framework.common.biz.infra.logger;
|
||||
|
||||
import org.agt.framework.common.biz.infra.logger.dto.ApiAccessLogCreateReqDTO;
|
||||
import org.agt.framework.common.enums.RpcConstants;
|
||||
import org.agt.framework.common.pojo.CommonResult;
|
||||
import org.agt.module.infra.api.logger.dto.ApiAccessLogCreateReqDTO;
|
||||
import org.agt.module.infra.enums.ApiConstants;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
import jakarta.validation.Valid;
|
||||
|
||||
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿:fallbackFactory =
|
||||
@FeignClient(name = RpcConstants.INFRA_NAME) // TODO 芋艿:fallbackFactory =
|
||||
@Tag(name = "RPC 服务 - API 访问日志")
|
||||
public interface ApiAccessLogApi {
|
||||
public interface ApiAccessLogCommonApi {
|
||||
|
||||
String PREFIX = ApiConstants.PREFIX + "/api-access-log";
|
||||
String PREFIX = RpcConstants.INFRA_PREFIX + "/api-access-log";
|
||||
|
||||
@PostMapping(PREFIX + "/create")
|
||||
@Operation(summary = "创建 API 访问日志")
|
||||
@@ -1,22 +1,21 @@
|
||||
package org.agt.module.infra.api.logger;
|
||||
package org.agt.framework.common.biz.infra.logger;
|
||||
|
||||
import org.agt.framework.common.biz.infra.logger.dto.ApiErrorLogCreateReqDTO;
|
||||
import org.agt.framework.common.enums.RpcConstants;
|
||||
import org.agt.framework.common.pojo.CommonResult;
|
||||
import org.agt.module.infra.api.logger.dto.ApiErrorLogCreateReqDTO;
|
||||
import org.agt.module.infra.enums.ApiConstants;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
import jakarta.validation.Valid;
|
||||
|
||||
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿:fallbackFactory =
|
||||
@FeignClient(name = RpcConstants.INFRA_NAME) // TODO 芋艿:fallbackFactory =
|
||||
@Tag(name = "RPC 服务 - API 异常日志")
|
||||
public interface ApiErrorLogApi {
|
||||
public interface ApiErrorLogCommonApi {
|
||||
|
||||
String PREFIX = ApiConstants.PREFIX + "/api-error-log";
|
||||
String PREFIX = RpcConstants.INFRA_PREFIX + "/api-error-log";
|
||||
|
||||
@PostMapping(PREFIX + "/create")
|
||||
@Operation(summary = "创建 API 异常日志")
|
||||
@@ -0,0 +1,103 @@
|
||||
package org.agt.framework.common.biz.infra.logger.dto;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* API 访问日志
|
||||
*
|
||||
* @author 千通源码
|
||||
*/
|
||||
@Data
|
||||
public class ApiAccessLogCreateReqDTO {
|
||||
|
||||
/**
|
||||
* 链路追踪编号
|
||||
*/
|
||||
private String traceId;
|
||||
/**
|
||||
* 用户编号
|
||||
*/
|
||||
private Long userId;
|
||||
/**
|
||||
* 用户类型
|
||||
*/
|
||||
private Integer userType;
|
||||
/**
|
||||
* 应用名
|
||||
*/
|
||||
@NotNull(message = "应用名不能为空")
|
||||
private String applicationName;
|
||||
|
||||
/**
|
||||
* 请求方法名
|
||||
*/
|
||||
@NotNull(message = "http 请求方法不能为空")
|
||||
private String requestMethod;
|
||||
/**
|
||||
* 访问地址
|
||||
*/
|
||||
@NotNull(message = "访问地址不能为空")
|
||||
private String requestUrl;
|
||||
/**
|
||||
* 请求参数
|
||||
*/
|
||||
private String requestParams;
|
||||
/**
|
||||
* 响应结果
|
||||
*/
|
||||
private String responseBody;
|
||||
/**
|
||||
* 用户 IP
|
||||
*/
|
||||
@NotNull(message = "ip 不能为空")
|
||||
private String userIp;
|
||||
/**
|
||||
* 浏览器 UA
|
||||
*/
|
||||
@NotNull(message = "User-Agent 不能为空")
|
||||
private String userAgent;
|
||||
|
||||
/**
|
||||
* 操作模块
|
||||
*/
|
||||
private String operateModule;
|
||||
/**
|
||||
* 操作名
|
||||
*/
|
||||
private String operateName;
|
||||
/**
|
||||
* 操作分类
|
||||
*
|
||||
* 枚举,参见 OperateTypeEnum 类
|
||||
*/
|
||||
private Integer operateType;
|
||||
|
||||
/**
|
||||
* 开始请求时间
|
||||
*/
|
||||
@NotNull(message = "开始请求时间不能为空")
|
||||
private LocalDateTime beginTime;
|
||||
/**
|
||||
* 结束请求时间
|
||||
*/
|
||||
@NotNull(message = "结束请求时间不能为空")
|
||||
private LocalDateTime endTime;
|
||||
/**
|
||||
* 执行时长,单位:毫秒
|
||||
*/
|
||||
@NotNull(message = "执行时长不能为空")
|
||||
private Integer duration;
|
||||
/**
|
||||
* 结果码
|
||||
*/
|
||||
@NotNull(message = "错误码不能为空")
|
||||
private Integer resultCode;
|
||||
/**
|
||||
* 结果提示
|
||||
*/
|
||||
private String resultMsg;
|
||||
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
package org.agt.module.infra.api.logger.dto;
|
||||
package org.agt.framework.common.biz.infra.logger.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "RPC 服务 - API 错误日志创建 Request DTO")
|
||||
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* 针对 infra 模块的 api 包
|
||||
*/
|
||||
package org.agt.framework.common.biz.infra;
|
||||
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* 特殊:用于 framework 下,starter 需要调用 biz 业务模块的接口定义!
|
||||
*/
|
||||
package org.agt.framework.common.biz;
|
||||
@@ -0,0 +1,26 @@
|
||||
package org.agt.framework.common.biz.system.dict;
|
||||
|
||||
import org.agt.framework.common.biz.system.dict.dto.DictDataRespDTO;
|
||||
import org.agt.framework.common.enums.RpcConstants;
|
||||
import org.agt.framework.common.pojo.CommonResult;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@FeignClient(name = RpcConstants.SYSTEM_NAME, primary = false) // TODO 芋艿:fallbackFactory =
|
||||
@Tag(name = "RPC 服务 - 字典数据")
|
||||
public interface DictDataCommonApi {
|
||||
|
||||
String PREFIX = RpcConstants.SYSTEM_PREFIX + "/dict-data";
|
||||
|
||||
@GetMapping(PREFIX + "/list")
|
||||
@Operation(summary = "获得指定字典类型的字典数据列表")
|
||||
@Parameter(name = "dictType", description = "字典类型", example = "SEX", required = true)
|
||||
CommonResult<List<DictDataRespDTO>> getDictDataList(@RequestParam("dictType") String dictType);
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.agt.module.system.api.dict.dto;
|
||||
package org.agt.framework.common.biz.system.dict.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
@@ -0,0 +1,34 @@
|
||||
package org.agt.framework.common.biz.system.logger;
|
||||
|
||||
import org.agt.framework.common.biz.system.logger.dto.OperateLogCreateReqDTO;
|
||||
import org.agt.framework.common.enums.RpcConstants;
|
||||
import org.agt.framework.common.pojo.CommonResult;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
@FeignClient(name = RpcConstants.SYSTEM_NAME, primary = false) // TODO 芋艿:fallbackFactory =
|
||||
@Tag(name = "RPC 服务 - 操作日志")
|
||||
public interface OperateLogCommonApi {
|
||||
|
||||
String PREFIX = RpcConstants.SYSTEM_PREFIX + "/operate-log";
|
||||
|
||||
@PostMapping(PREFIX + "/create")
|
||||
@Operation(summary = "创建操作日志")
|
||||
CommonResult<Boolean> createOperateLog(@Valid @RequestBody OperateLogCreateReqDTO createReqDTO);
|
||||
|
||||
/**
|
||||
* 【异步】创建操作日志
|
||||
*
|
||||
* @param createReqDTO 请求
|
||||
*/
|
||||
@Async
|
||||
default void createOperateLogAsync(OperateLogCreateReqDTO createReqDTO) {
|
||||
createOperateLog(createReqDTO).checkError();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.agt.module.system.api.logger.dto;
|
||||
package org.agt.framework.common.biz.system.logger.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
@@ -1,10 +1,10 @@
|
||||
package org.agt.module.system.api.oauth2;
|
||||
package org.agt.framework.common.biz.system.oauth2;
|
||||
|
||||
import org.agt.framework.common.enums.RpcConstants;
|
||||
import org.agt.framework.common.pojo.CommonResult;
|
||||
import org.agt.module.system.api.oauth2.dto.OAuth2AccessTokenCheckRespDTO;
|
||||
import org.agt.module.system.api.oauth2.dto.OAuth2AccessTokenCreateReqDTO;
|
||||
import org.agt.module.system.api.oauth2.dto.OAuth2AccessTokenRespDTO;
|
||||
import org.agt.module.system.enums.ApiConstants;
|
||||
import org.agt.framework.common.biz.system.oauth2.dto.OAuth2AccessTokenCheckRespDTO;
|
||||
import org.agt.framework.common.biz.system.oauth2.dto.OAuth2AccessTokenCreateReqDTO;
|
||||
import org.agt.framework.common.biz.system.oauth2.dto.OAuth2AccessTokenRespDTO;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Parameters;
|
||||
@@ -14,17 +14,17 @@ import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import jakarta.validation.Valid;
|
||||
|
||||
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿:fallbackFactory =
|
||||
@FeignClient(name = RpcConstants.SYSTEM_NAME) // TODO 芋艿:fallbackFactory =
|
||||
@Tag(name = "RPC 服务 - OAuth2.0 令牌")
|
||||
public interface OAuth2TokenApi {
|
||||
public interface OAuth2TokenCommonApi {
|
||||
|
||||
String PREFIX = ApiConstants.PREFIX + "/oauth2/token";
|
||||
String PREFIX = RpcConstants.SYSTEM_PREFIX + "/oauth2/token";
|
||||
|
||||
/**
|
||||
* 校验 Token 的 URL 地址,主要是提供给 Gateway 使用
|
||||
*/
|
||||
@SuppressWarnings("HttpUrlsUsage")
|
||||
String URL_CHECK = "http://" + ApiConstants.NAME + PREFIX + "/check";
|
||||
String URL_CHECK = "http://" + RpcConstants.SYSTEM_NAME + PREFIX + "/check";
|
||||
|
||||
@PostMapping(PREFIX + "/create")
|
||||
@Operation(summary = "创建访问令牌")
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.agt.module.system.api.oauth2.dto;
|
||||
package org.agt.framework.common.biz.system.oauth2.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.agt.module.system.api.oauth2.dto;
|
||||
package org.agt.framework.common.biz.system.oauth2.dto;
|
||||
|
||||
import org.agt.framework.common.enums.UserTypeEnum;
|
||||
import org.agt.framework.common.validation.InEnum;
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.agt.module.system.api.oauth2.dto;
|
||||
package org.agt.framework.common.biz.system.oauth2.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* 针对 system 模块的 api 包
|
||||
*/
|
||||
package org.agt.framework.common.biz.system;
|
||||
@@ -0,0 +1,43 @@
|
||||
package org.agt.framework.common.biz.system.permission;
|
||||
|
||||
import org.agt.framework.common.biz.system.permission.dto.DeptDataPermissionRespDTO;
|
||||
import org.agt.framework.common.enums.RpcConstants;
|
||||
import org.agt.framework.common.pojo.CommonResult;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Parameters;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
@FeignClient(name = RpcConstants.SYSTEM_NAME, primary = false) // TODO 芋艿:fallbackFactory =
|
||||
@Tag(name = "RPC 服务 - 权限")
|
||||
public interface PermissionCommonApi {
|
||||
|
||||
String PREFIX = RpcConstants.SYSTEM_PREFIX + "/permission";
|
||||
|
||||
@GetMapping(PREFIX + "/has-any-permissions")
|
||||
@Operation(summary = "判断是否有权限,任一一个即可")
|
||||
@Parameters({
|
||||
@Parameter(name = "userId", description = "用户编号", example = "1", required = true),
|
||||
@Parameter(name = "permissions", description = "权限", example = "read,write", required = true)
|
||||
})
|
||||
CommonResult<Boolean> hasAnyPermissions(@RequestParam("userId") Long userId,
|
||||
@RequestParam("permissions") String... permissions);
|
||||
|
||||
@GetMapping(PREFIX + "/has-any-roles")
|
||||
@Operation(summary = "判断是否有角色,任一一个即可")
|
||||
@Parameters({
|
||||
@Parameter(name = "userId", description = "用户编号", example = "1", required = true),
|
||||
@Parameter(name = "roles", description = "角色数组", example = "2", required = true)
|
||||
})
|
||||
CommonResult<Boolean> hasAnyRoles(@RequestParam("userId") Long userId,
|
||||
@RequestParam("roles") String... roles);
|
||||
|
||||
@GetMapping(PREFIX + "/get-dept-data-permission")
|
||||
@Operation(summary = "获得登陆用户的部门数据权限")
|
||||
@Parameter(name = "userId", description = "用户编号", example = "2", required = true)
|
||||
CommonResult<DeptDataPermissionRespDTO> getDeptDataPermission(@RequestParam("userId") Long userId);
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.agt.module.system.api.permission.dto;
|
||||
package org.agt.framework.common.biz.system.permission.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
@@ -1,7 +1,7 @@
|
||||
package org.agt.module.system.api.tenant;
|
||||
package org.agt.framework.common.biz.system.tenant;
|
||||
|
||||
import org.agt.framework.common.enums.RpcConstants;
|
||||
import org.agt.framework.common.pojo.CommonResult;
|
||||
import org.agt.module.system.enums.ApiConstants;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
@@ -11,11 +11,11 @@ import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿:fallbackFactory =
|
||||
@FeignClient(name = RpcConstants.SYSTEM_NAME) // TODO 芋艿:fallbackFactory =
|
||||
@Tag(name = "RPC 服务 - 多租户")
|
||||
public interface TenantApi {
|
||||
public interface TenantCommonApi {
|
||||
|
||||
String PREFIX = ApiConstants.PREFIX + "/tenant";
|
||||
String PREFIX = RpcConstants.SYSTEM_PREFIX + "/tenant";
|
||||
|
||||
@GetMapping(PREFIX + "/id-list")
|
||||
@Operation(summary = "获得所有租户编号")
|
||||
@@ -7,11 +7,34 @@ package org.agt.framework.common.enums;
|
||||
*
|
||||
* @author 千通源码
|
||||
*/
|
||||
public class RpcConstants {
|
||||
public interface RpcConstants {
|
||||
|
||||
/**
|
||||
* RPC API 的前缀
|
||||
*/
|
||||
public static final String RPC_API_PREFIX = "/rpc-api";
|
||||
String RPC_API_PREFIX = "/rpc-api";
|
||||
|
||||
/**
|
||||
* system 服务名
|
||||
*
|
||||
* 注意,需要保证和 spring.application.name 保持一致
|
||||
*/
|
||||
String SYSTEM_NAME = "system-server";
|
||||
|
||||
/**
|
||||
* system 服务的前缀
|
||||
*/
|
||||
String SYSTEM_PREFIX = RPC_API_PREFIX + "/system";
|
||||
|
||||
/**
|
||||
* infra 服务名
|
||||
*
|
||||
* 注意,需要保证和 spring.application.name 保持一致
|
||||
*/
|
||||
String INFRA_NAME = "infra-server";
|
||||
/**
|
||||
* infra 服务的前缀
|
||||
*/
|
||||
String INFRA_PREFIX = RPC_API_PREFIX + "/infra";
|
||||
|
||||
}
|
||||
|
||||
@@ -41,13 +41,6 @@
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- 业务组件 -->
|
||||
<dependency>
|
||||
<groupId>org.agt</groupId>
|
||||
<artifactId>agt-module-system-api</artifactId> <!-- 需要使用它,进行数据权限的获取 -->
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Test 测试相关 -->
|
||||
<dependency>
|
||||
<groupId>org.agt</groupId>
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
package org.agt.framework.datapermission.config;
|
||||
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import org.agt.framework.common.biz.system.permission.PermissionCommonApi;
|
||||
import org.agt.framework.datapermission.core.rule.dept.DeptDataPermissionRule;
|
||||
import org.agt.framework.datapermission.core.rule.dept.DeptDataPermissionRuleCustomizer;
|
||||
import org.agt.framework.security.core.LoginUser;
|
||||
import org.agt.module.system.api.permission.PermissionApi;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
@@ -19,16 +20,16 @@ import java.util.List;
|
||||
*/
|
||||
@AutoConfiguration
|
||||
@ConditionalOnClass(LoginUser.class)
|
||||
@ConditionalOnBean(value = DeptDataPermissionRuleCustomizer.class)
|
||||
@ConditionalOnBean(value = {PermissionCommonApi.class, DeptDataPermissionRuleCustomizer.class})
|
||||
public class AgtDeptDataPermissionAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
public DeptDataPermissionRule deptDataPermissionRule(PermissionApi permissionApi,
|
||||
public DeptDataPermissionRule deptDataPermissionRule(PermissionCommonApi permissionApi,
|
||||
List<DeptDataPermissionRuleCustomizer> customizers) {
|
||||
// Cloud 专属逻辑:优先使用本地的 PermissionApi 实现类,而不是 Feign 调用
|
||||
// 原因:在创建租户时,租户还没创建好,导致 Feign 调用获取数据权限时,报“租户不存在”的错误
|
||||
try {
|
||||
PermissionApi permissionApiImpl = SpringUtil.getBean("permissionApiImpl", PermissionApi.class);
|
||||
PermissionCommonApi permissionApiImpl = SpringUtil.getBean("permissionApiImpl", PermissionCommonApi.class);
|
||||
if (permissionApiImpl != null) {
|
||||
permissionApi = permissionApiImpl;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.agt.framework.datapermission.core.rule.dept;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import org.agt.framework.common.biz.system.permission.PermissionCommonApi;
|
||||
import org.agt.framework.common.enums.UserTypeEnum;
|
||||
import org.agt.framework.common.util.collection.CollectionUtils;
|
||||
import org.agt.framework.common.util.json.JsonUtils;
|
||||
@@ -11,8 +12,7 @@ import org.agt.framework.mybatis.core.dataobject.BaseDO;
|
||||
import org.agt.framework.mybatis.core.util.MyBatisUtils;
|
||||
import org.agt.framework.security.core.LoginUser;
|
||||
import org.agt.framework.security.core.util.SecurityFrameworkUtils;
|
||||
import org.agt.module.system.api.permission.PermissionApi;
|
||||
import org.agt.module.system.api.permission.dto.DeptDataPermissionRespDTO;
|
||||
import org.agt.framework.common.biz.system.permission.dto.DeptDataPermissionRespDTO;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -59,7 +59,7 @@ public class DeptDataPermissionRule implements DataPermissionRule {
|
||||
|
||||
static final Expression EXPRESSION_NULL = new NullValue();
|
||||
|
||||
private final PermissionApi permissionApi;
|
||||
private final PermissionCommonApi permissionApi;
|
||||
|
||||
/**
|
||||
* 基于部门的表字段配置
|
||||
|
||||
@@ -2,13 +2,13 @@ package org.agt.framework.datapermission.core.rule.dept;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.ReflectUtil;
|
||||
import org.agt.framework.common.biz.system.permission.PermissionCommonApi;
|
||||
import org.agt.framework.common.enums.UserTypeEnum;
|
||||
import org.agt.framework.common.util.collection.SetUtils;
|
||||
import org.agt.framework.security.core.LoginUser;
|
||||
import org.agt.framework.security.core.util.SecurityFrameworkUtils;
|
||||
import org.agt.framework.test.core.ut.BaseMockitoUnitTest;
|
||||
import org.agt.module.system.api.permission.PermissionApi;
|
||||
import org.agt.module.system.api.permission.dto.DeptDataPermissionRespDTO;
|
||||
import org.agt.framework.common.biz.system.permission.dto.DeptDataPermissionRespDTO;
|
||||
import net.sf.jsqlparser.expression.Alias;
|
||||
import net.sf.jsqlparser.expression.Expression;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
@@ -40,7 +40,7 @@ class DeptDataPermissionRuleTest extends BaseMockitoUnitTest {
|
||||
private DeptDataPermissionRule rule;
|
||||
|
||||
@Mock
|
||||
private PermissionApi permissionApi;
|
||||
private PermissionCommonApi permissionApi;
|
||||
|
||||
@BeforeEach
|
||||
@SuppressWarnings("unchecked")
|
||||
|
||||
@@ -20,7 +20,7 @@ import org.agt.framework.tenant.core.web.TenantContextWebFilter;
|
||||
import org.agt.framework.tenant.core.web.TenantVisitContextInterceptor;
|
||||
import org.agt.framework.web.config.WebProperties;
|
||||
import org.agt.framework.web.core.handler.GlobalExceptionHandler;
|
||||
import org.agt.module.system.api.tenant.TenantApi;
|
||||
import org.agt.framework.common.biz.system.tenant.TenantCommonApi;
|
||||
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
|
||||
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
|
||||
import jakarta.annotation.Resource;
|
||||
@@ -60,10 +60,10 @@ public class AgtTenantAutoConfiguration {
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Bean
|
||||
public TenantFrameworkService tenantFrameworkService(TenantApi tenantApi) {
|
||||
public TenantFrameworkService tenantFrameworkService(TenantCommonApi tenantApi) {
|
||||
// 参见 https://gitee.com/zhijiantianya/agt-cloud/issues/IC6YZF
|
||||
try {
|
||||
TenantApi tenantApiImpl = SpringUtil.getBean("tenantApiImpl", TenantApi.class);
|
||||
TenantCommonApi tenantApiImpl = SpringUtil.getBean("tenantApiImpl", TenantCommonApi.class);
|
||||
if (tenantApiImpl != null) {
|
||||
tenantApi = tenantApiImpl;
|
||||
}
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
package org.agt.framework.tenant.config;
|
||||
|
||||
import org.agt.framework.tenant.core.rpc.TenantRequestInterceptor;
|
||||
import org.agt.module.system.api.tenant.TenantApi;
|
||||
import org.agt.framework.common.biz.system.tenant.TenantCommonApi;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@AutoConfiguration
|
||||
@ConditionalOnProperty(prefix = "agt.tenant", value = "enable", matchIfMissing = true) // 允许使用 agt.tenant.enable=false 禁用多租户
|
||||
@EnableFeignClients(clients = TenantApi.class) // 主要是引入相关的 API 服务
|
||||
@EnableFeignClients(clients = TenantCommonApi.class) // 主要是引入相关的 API 服务
|
||||
public class AgtTenantRpcAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package org.agt.framework.tenant.core.service;
|
||||
|
||||
import org.agt.framework.common.pojo.CommonResult;
|
||||
import org.agt.framework.common.util.cache.CacheUtils;
|
||||
import org.agt.module.system.api.tenant.TenantApi;
|
||||
import org.agt.framework.common.biz.system.tenant.TenantCommonApi;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@@ -21,7 +20,7 @@ import static org.agt.framework.common.util.cache.CacheUtils.buildAsyncReloading
|
||||
@RequiredArgsConstructor
|
||||
public class TenantFrameworkServiceImpl implements TenantFrameworkService {
|
||||
|
||||
private final TenantApi tenantApi;
|
||||
private final TenantCommonApi tenantApi;
|
||||
|
||||
/**
|
||||
* 针对 {@link #getTenantIds()} 的缓存
|
||||
|
||||
@@ -34,13 +34,6 @@
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- 业务组件 -->
|
||||
<dependency>
|
||||
<groupId>org.agt</groupId>
|
||||
<artifactId>agt-module-system-api</artifactId> <!-- 需要使用它,进行 Dict 的查询 -->
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Web 相关 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package org.agt.framework.dict.config;
|
||||
|
||||
import org.agt.framework.common.biz.system.dict.DictDataCommonApi;
|
||||
import org.agt.framework.dict.core.DictFrameworkUtils;
|
||||
import org.agt.module.system.api.dict.DictDataApi;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
@@ -10,7 +10,7 @@ public class AgtDictAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@SuppressWarnings("InstantiationOfUtilityClass")
|
||||
public DictFrameworkUtils dictUtils(DictDataApi dictDataApi) {
|
||||
public DictFrameworkUtils dictUtils(DictDataCommonApi dictDataApi) {
|
||||
DictFrameworkUtils.init(dictDataApi);
|
||||
return new DictFrameworkUtils();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package org.agt.framework.dict.config;
|
||||
|
||||
import org.agt.module.system.api.dict.DictDataApi;
|
||||
import org.agt.framework.common.biz.system.dict.DictDataCommonApi;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
|
||||
@@ -10,6 +10,6 @@ import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
* @author 千通源码
|
||||
*/
|
||||
@AutoConfiguration
|
||||
@EnableFeignClients(clients = DictDataApi.class) // 主要是引入相关的 API 服务
|
||||
@EnableFeignClients(clients = DictDataCommonApi.class) // 主要是引入相关的 API 服务
|
||||
public class AgtDictRpcAutoConfiguration {
|
||||
}
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
package org.agt.framework.dict.core;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import org.agt.framework.common.core.KeyValue;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import org.agt.framework.common.biz.system.dict.DictDataCommonApi;
|
||||
import org.agt.framework.common.util.cache.CacheUtils;
|
||||
import org.agt.module.system.api.dict.DictDataApi;
|
||||
import org.agt.module.system.api.dict.dto.DictDataRespDTO;
|
||||
import org.agt.framework.common.biz.system.dict.dto.DictDataRespDTO;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import lombok.SneakyThrows;
|
||||
@@ -12,6 +11,9 @@ import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.agt.framework.common.util.collection.CollectionUtils.convertList;
|
||||
|
||||
/**
|
||||
* 字典工具类
|
||||
@@ -21,76 +23,57 @@ import java.util.List;
|
||||
@Slf4j
|
||||
public class DictFrameworkUtils {
|
||||
|
||||
private static DictDataApi dictDataApi;
|
||||
private static DictDataCommonApi dictDataApi;
|
||||
|
||||
private static final DictDataRespDTO DICT_DATA_NULL = new DictDataRespDTO();
|
||||
|
||||
// TODO @puhui999:GET_DICT_DATA_CACHE、GET_DICT_DATA_LIST_CACHE、PARSE_DICT_DATA_CACHE 这 3 个缓存是有点重叠,可以思考下,有没可能减少 1 个。微信讨论好私聊,再具体改哈
|
||||
/**
|
||||
* 针对 {@link #getDictDataLabel(String, String)} 的缓存
|
||||
* 针对 dictType 的字段数据缓存
|
||||
*/
|
||||
private static final LoadingCache<KeyValue<String, String>, DictDataRespDTO> GET_DICT_DATA_CACHE = CacheUtils.buildAsyncReloadingCache(
|
||||
private static final LoadingCache<String, List<DictDataRespDTO>> GET_DICT_DATA_CACHE = CacheUtils.buildAsyncReloadingCache(
|
||||
Duration.ofMinutes(1L), // 过期时间 1 分钟
|
||||
new CacheLoader<KeyValue<String, String>, DictDataRespDTO>() {
|
||||
new CacheLoader<String, List<DictDataRespDTO>>() {
|
||||
|
||||
@Override
|
||||
public DictDataRespDTO load(KeyValue<String, String> key) {
|
||||
return ObjectUtil.defaultIfNull(dictDataApi.getDictData(key.getKey(), key.getValue()).getCheckedData(), DICT_DATA_NULL);
|
||||
public List<DictDataRespDTO> load(String dictType) {
|
||||
return dictDataApi.getDictDataList(dictType).getCheckedData();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* 针对 {@link #getDictDataLabelList(String)} 的缓存
|
||||
*/
|
||||
private static final LoadingCache<String, List<String>> GET_DICT_DATA_LIST_CACHE = CacheUtils.buildAsyncReloadingCache(
|
||||
Duration.ofMinutes(1L), // 过期时间 1 分钟
|
||||
new CacheLoader<String, List<String>>() {
|
||||
|
||||
@Override
|
||||
public List<String> load(String dictType) {
|
||||
return dictDataApi.getDictDataLabelList(dictType);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* 针对 {@link #parseDictDataValue(String, String)} 的缓存
|
||||
*/
|
||||
private static final LoadingCache<KeyValue<String, String>, DictDataRespDTO> PARSE_DICT_DATA_CACHE = CacheUtils.buildAsyncReloadingCache(
|
||||
Duration.ofMinutes(1L), // 过期时间 1 分钟
|
||||
new CacheLoader<KeyValue<String, String>, DictDataRespDTO>() {
|
||||
|
||||
@Override
|
||||
public DictDataRespDTO load(KeyValue<String, String> key) {
|
||||
return ObjectUtil.defaultIfNull(dictDataApi.parseDictData(key.getKey(), key.getValue()).getCheckedData(), DICT_DATA_NULL);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
public static void init(DictDataApi dictDataApi) {
|
||||
public static void init(DictDataCommonApi dictDataApi) {
|
||||
DictFrameworkUtils.dictDataApi = dictDataApi;
|
||||
log.info("[init][初始化 DictFrameworkUtils 成功]");
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static String getDictDataLabel(String dictType, Integer value) {
|
||||
return GET_DICT_DATA_CACHE.get(new KeyValue<>(dictType, String.valueOf(value))).getLabel();
|
||||
public static void clearCache() {
|
||||
GET_DICT_DATA_CACHE.invalidateAll();
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static String getDictDataLabel(String dictType, String value) {
|
||||
return GET_DICT_DATA_CACHE.get(new KeyValue<>(dictType, value)).getLabel();
|
||||
public static String parseDictDataLabel(String dictType, Integer value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return parseDictDataLabel(dictType, String.valueOf(value));
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static String parseDictDataLabel(String dictType, String value) {
|
||||
List<DictDataRespDTO> dictDatas = GET_DICT_DATA_CACHE.get(dictType);
|
||||
DictDataRespDTO dictData = CollUtil.findOne(dictDatas, data -> Objects.equals(data.getValue(), value));
|
||||
return dictData != null ? dictData.getLabel(): null;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static List<String> getDictDataLabelList(String dictType) {
|
||||
return GET_DICT_DATA_LIST_CACHE.get(dictType);
|
||||
List<DictDataRespDTO> dictDatas = GET_DICT_DATA_CACHE.get(dictType);
|
||||
return convertList(dictDatas, DictDataRespDTO::getLabel);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static String parseDictDataValue(String dictType, String label) {
|
||||
return PARSE_DICT_DATA_CACHE.get(new KeyValue<>(dictType, label)).getValue();
|
||||
List<DictDataRespDTO> dictDatas = GET_DICT_DATA_CACHE.get(dictType);
|
||||
DictDataRespDTO dictData = CollUtil.findOne(dictDatas, data -> Objects.equals(data.getLabel(), label));
|
||||
return dictData!= null ? dictData.getValue(): null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ public class DictConvert implements Converter<Object> {
|
||||
// 使用字典格式化
|
||||
String type = getType(contentProperty);
|
||||
String value = String.valueOf(object);
|
||||
String label = DictFrameworkUtils.getDictDataLabel(type, value);
|
||||
String label = DictFrameworkUtils.parseDictDataLabel(type, value);
|
||||
if (label == null) {
|
||||
log.error("[convertToExcelData][type({}) 转换不了 label({})]", type, value);
|
||||
return new WriteCellData<>("");
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
package org.agt.framework.dict.core.util;
|
||||
|
||||
import org.agt.framework.common.enums.CommonStatusEnum;
|
||||
import org.agt.framework.common.biz.system.dict.DictDataCommonApi;
|
||||
import org.agt.framework.dict.core.DictFrameworkUtils;
|
||||
import org.agt.framework.test.core.ut.BaseMockitoUnitTest;
|
||||
import org.agt.module.system.api.dict.DictDataApi;
|
||||
import org.agt.module.system.api.dict.dto.DictDataRespDTO;
|
||||
import org.agt.framework.common.biz.system.dict.dto.DictDataRespDTO;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mock;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.agt.framework.common.pojo.CommonResult.success;
|
||||
import static org.agt.framework.test.core.util.RandomUtils.randomPojo;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
@@ -20,32 +22,40 @@ import static org.mockito.Mockito.when;
|
||||
public class DictFrameworkUtilsTest extends BaseMockitoUnitTest {
|
||||
|
||||
@Mock
|
||||
private DictDataApi dictDataApi;
|
||||
private DictDataCommonApi dictDataApi;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
DictFrameworkUtils.init(dictDataApi);
|
||||
DictFrameworkUtils.clearCache();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDictDataLabel() {
|
||||
public void testParseDictDataLabel() {
|
||||
// mock 数据
|
||||
DictDataRespDTO dataRespDTO = randomPojo(DictDataRespDTO.class, o -> o.setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
List<DictDataRespDTO> dictDatas = List.of(
|
||||
randomPojo(DictDataRespDTO.class, o -> o.setDictType("animal").setValue("cat").setLabel("猫")),
|
||||
randomPojo(DictDataRespDTO.class, o -> o.setDictType("animal").setValue("dog").setLabel("狗"))
|
||||
);
|
||||
// mock 方法
|
||||
when(dictDataApi.getDictData(dataRespDTO.getDictType(), dataRespDTO.getValue())).thenReturn(success(dataRespDTO));
|
||||
when(dictDataApi.getDictDataList(eq("animal"))).thenReturn(success(dictDatas));
|
||||
|
||||
// 断言返回值
|
||||
assertEquals(dataRespDTO.getLabel(), DictFrameworkUtils.getDictDataLabel(dataRespDTO.getDictType(), dataRespDTO.getValue()));
|
||||
assertEquals("狗", DictFrameworkUtils.parseDictDataLabel("animal", "dog"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseDictDataValue() {
|
||||
// mock 数据
|
||||
DictDataRespDTO resp = randomPojo(DictDataRespDTO.class, o -> o.setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
List<DictDataRespDTO> dictDatas = List.of(
|
||||
randomPojo(DictDataRespDTO.class, o -> o.setDictType("animal").setValue("cat").setLabel("猫")),
|
||||
randomPojo(DictDataRespDTO.class, o -> o.setDictType("animal").setValue("dog").setLabel("狗"))
|
||||
);
|
||||
// mock 方法
|
||||
when(dictDataApi.parseDictData(resp.getDictType(), resp.getLabel())).thenReturn(success(resp));
|
||||
when(dictDataApi.getDictDataList(eq("animal"))).thenReturn(success(dictDatas));
|
||||
|
||||
// 断言返回值
|
||||
assertEquals(resp.getValue(), DictFrameworkUtils.parseDictDataValue(resp.getDictType(), resp.getLabel()));
|
||||
assertEquals("dog", DictFrameworkUtils.parseDictDataValue("animal", "狗"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -54,13 +54,6 @@
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- 业务组件 -->
|
||||
<dependency>
|
||||
<groupId>org.agt</groupId>
|
||||
<artifactId>agt-module-system-api</artifactId> <!-- 需要使用它,进行 Token 的校验 -->
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 工具类相关 -->
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package org.agt.framework.operatelog.config;
|
||||
|
||||
import org.agt.module.system.api.logger.OperateLogApi;
|
||||
import org.agt.framework.common.biz.system.logger.OperateLogCommonApi;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
|
||||
@@ -10,6 +10,6 @@ import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
* @author 千通源码
|
||||
*/
|
||||
@AutoConfiguration
|
||||
@EnableFeignClients(clients = {OperateLogApi.class}) // 主要是引入相关的 API 服务
|
||||
@EnableFeignClients(clients = {OperateLogCommonApi.class}) // 主要是引入相关的 API 服务
|
||||
public class AgtOperateLogRpcAutoConfiguration {
|
||||
}
|
||||
|
||||
@@ -1,23 +1,24 @@
|
||||
package org.agt.framework.operatelog.core.service;
|
||||
|
||||
import org.agt.framework.common.biz.system.logger.OperateLogCommonApi;
|
||||
import org.agt.framework.common.util.monitor.TracerUtils;
|
||||
import org.agt.framework.common.util.servlet.ServletUtils;
|
||||
import org.agt.framework.security.core.LoginUser;
|
||||
import org.agt.framework.security.core.util.SecurityFrameworkUtils;
|
||||
import org.agt.module.system.api.logger.OperateLogApi;
|
||||
import org.agt.module.system.api.logger.dto.OperateLogCreateReqDTO;
|
||||
import org.agt.framework.common.biz.system.logger.dto.OperateLogCreateReqDTO;
|
||||
import com.mzt.logapi.beans.LogRecord;
|
||||
import com.mzt.logapi.service.ILogRecordService;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 操作日志 ILogRecordService 实现类
|
||||
*
|
||||
* 基于 {@link OperateLogApi} 实现,记录操作日志
|
||||
* 基于 {@link OperateLogCommonApi} 实现,记录操作日志
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@@ -25,7 +26,7 @@ import java.util.List;
|
||||
public class LogRecordServiceImpl implements ILogRecordService {
|
||||
|
||||
@Resource
|
||||
private OperateLogApi operateLogApi;
|
||||
private OperateLogCommonApi operateLogApi;
|
||||
|
||||
@Override
|
||||
public void record(LogRecord logRecord) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.agt.framework.security.config;
|
||||
|
||||
import org.agt.framework.common.biz.system.permission.PermissionCommonApi;
|
||||
import org.agt.framework.security.core.context.TransmittableThreadLocalSecurityContextHolderStrategy;
|
||||
import org.agt.framework.security.core.filter.TokenAuthenticationFilter;
|
||||
import org.agt.framework.security.core.handler.AccessDeniedHandlerImpl;
|
||||
@@ -7,8 +8,7 @@ import org.agt.framework.security.core.handler.AuthenticationEntryPointImpl;
|
||||
import org.agt.framework.security.core.service.SecurityFrameworkService;
|
||||
import org.agt.framework.security.core.service.SecurityFrameworkServiceImpl;
|
||||
import org.agt.framework.web.core.handler.GlobalExceptionHandler;
|
||||
import org.agt.module.system.api.oauth2.OAuth2TokenApi;
|
||||
import org.agt.module.system.api.permission.PermissionApi;
|
||||
import org.agt.framework.common.biz.system.oauth2.OAuth2TokenCommonApi;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.beans.factory.config.MethodInvokingFactoryBean;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
@@ -69,12 +69,12 @@ public class AgtSecurityAutoConfiguration {
|
||||
*/
|
||||
@Bean
|
||||
public TokenAuthenticationFilter authenticationTokenFilter(GlobalExceptionHandler globalExceptionHandler,
|
||||
OAuth2TokenApi oauth2TokenApi) {
|
||||
OAuth2TokenCommonApi oauth2TokenApi) {
|
||||
return new TokenAuthenticationFilter(securityProperties, globalExceptionHandler, oauth2TokenApi);
|
||||
}
|
||||
|
||||
@Bean("ss") // 使用 Spring Security 的缩写,方便使用
|
||||
public SecurityFrameworkService securityFrameworkService(PermissionApi permissionApi) {
|
||||
public SecurityFrameworkService securityFrameworkService(PermissionCommonApi permissionApi) {
|
||||
return new SecurityFrameworkServiceImpl(permissionApi);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package org.agt.framework.security.config;
|
||||
|
||||
import org.agt.framework.common.biz.system.permission.PermissionCommonApi;
|
||||
import org.agt.framework.security.core.rpc.LoginUserRequestInterceptor;
|
||||
import org.agt.module.system.api.oauth2.OAuth2TokenApi;
|
||||
import org.agt.module.system.api.permission.PermissionApi;
|
||||
import org.agt.framework.common.biz.system.oauth2.OAuth2TokenCommonApi;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@@ -13,8 +13,8 @@ import org.springframework.context.annotation.Bean;
|
||||
* @author 千通源码
|
||||
*/
|
||||
@AutoConfiguration
|
||||
@EnableFeignClients(clients = {OAuth2TokenApi.class, // 主要是引入相关的 API 服务
|
||||
PermissionApi.class})
|
||||
@EnableFeignClients(clients = {OAuth2TokenCommonApi.class, // 主要是引入相关的 API 服务
|
||||
PermissionCommonApi.class})
|
||||
public class AgtSecurityRpcAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -11,8 +11,8 @@ import org.agt.framework.security.core.LoginUser;
|
||||
import org.agt.framework.security.core.util.SecurityFrameworkUtils;
|
||||
import org.agt.framework.web.core.handler.GlobalExceptionHandler;
|
||||
import org.agt.framework.web.core.util.WebFrameworkUtils;
|
||||
import org.agt.module.system.api.oauth2.OAuth2TokenApi;
|
||||
import org.agt.module.system.api.oauth2.dto.OAuth2AccessTokenCheckRespDTO;
|
||||
import org.agt.framework.common.biz.system.oauth2.OAuth2TokenCommonApi;
|
||||
import org.agt.framework.common.biz.system.oauth2.dto.OAuth2AccessTokenCheckRespDTO;
|
||||
import jakarta.servlet.FilterChain;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
@@ -40,7 +40,7 @@ public class TokenAuthenticationFilter extends OncePerRequestFilter {
|
||||
|
||||
private final GlobalExceptionHandler globalExceptionHandler;
|
||||
|
||||
private final OAuth2TokenApi oauth2TokenApi;
|
||||
private final OAuth2TokenCommonApi oauth2TokenApi;
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("NullableProblems")
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package org.agt.framework.security.core.service;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import org.agt.framework.common.biz.system.permission.PermissionCommonApi;
|
||||
import org.agt.framework.common.core.KeyValue;
|
||||
import org.agt.framework.security.core.LoginUser;
|
||||
import org.agt.framework.security.core.util.SecurityFrameworkUtils;
|
||||
import org.agt.module.system.api.permission.PermissionApi;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import lombok.AllArgsConstructor;
|
||||
@@ -26,7 +26,7 @@ import static org.agt.framework.security.core.util.SecurityFrameworkUtils.skipPe
|
||||
@AllArgsConstructor
|
||||
public class SecurityFrameworkServiceImpl implements SecurityFrameworkService {
|
||||
|
||||
private final PermissionApi permissionApi;
|
||||
private final PermissionCommonApi permissionApi;
|
||||
|
||||
/**
|
||||
* 针对 {@link #hasAnyRoles(String...)} 的缓存
|
||||
|
||||
@@ -61,18 +61,6 @@
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- 业务组件 -->
|
||||
<dependency>
|
||||
<groupId>org.agt</groupId>
|
||||
<artifactId>agt-module-infra-api</artifactId> <!-- 需要使用它,进行操作日志的记录 -->
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.agt</groupId>
|
||||
<artifactId>agt-module-system-api</artifactId> <!-- 需要使用它,进行错误码的记录 -->
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- xss -->
|
||||
<dependency>
|
||||
<groupId>org.jsoup</groupId>
|
||||
|
||||
@@ -2,10 +2,10 @@ package org.agt.framework.apilog.config;
|
||||
|
||||
import org.agt.framework.apilog.core.filter.ApiAccessLogFilter;
|
||||
import org.agt.framework.apilog.core.interceptor.ApiAccessLogInterceptor;
|
||||
import org.agt.framework.common.biz.infra.logger.ApiAccessLogCommonApi;
|
||||
import org.agt.framework.common.enums.WebFilterOrderEnum;
|
||||
import org.agt.framework.web.config.WebProperties;
|
||||
import org.agt.framework.web.config.AgtWebAutoConfiguration;
|
||||
import org.agt.module.infra.api.logger.ApiAccessLogApi;
|
||||
import jakarta.servlet.Filter;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
@@ -23,10 +23,9 @@ public class AgtApiLogAutoConfiguration implements WebMvcConfigurer {
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnProperty(prefix = "agt.access-log", value = "enable", matchIfMissing = true) // 允许使用 agt.access-log.enable=false 禁用访问日志
|
||||
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
|
||||
public FilterRegistrationBean<ApiAccessLogFilter> apiAccessLogFilter(WebProperties webProperties,
|
||||
@Value("${spring.application.name}") String applicationName,
|
||||
ApiAccessLogApi apiAccessLogApi) {
|
||||
ApiAccessLogCommonApi apiAccessLogApi) {
|
||||
ApiAccessLogFilter filter = new ApiAccessLogFilter(webProperties, applicationName, apiAccessLogApi);
|
||||
return createFilterBean(filter, WebFilterOrderEnum.API_ACCESS_LOG_FILTER);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package org.agt.framework.apilog.config;
|
||||
|
||||
import org.agt.module.infra.api.logger.ApiAccessLogApi;
|
||||
import org.agt.module.infra.api.logger.ApiErrorLogApi;
|
||||
import org.agt.framework.common.biz.infra.logger.ApiAccessLogCommonApi;
|
||||
import org.agt.framework.common.biz.infra.logger.ApiErrorLogCommonApi;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
|
||||
@@ -11,6 +11,6 @@ import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
* @author 千通源码
|
||||
*/
|
||||
@AutoConfiguration
|
||||
@EnableFeignClients(clients = {ApiAccessLogApi.class, ApiErrorLogApi.class}) // 主要是引入相关的 API 服务
|
||||
@EnableFeignClients(clients = {ApiAccessLogCommonApi.class, ApiErrorLogCommonApi.class}) // 主要是引入相关的 API 服务
|
||||
public class AgtApiLogRpcAutoConfiguration {
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@ import cn.hutool.core.util.BooleanUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import org.agt.framework.apilog.core.annotation.ApiAccessLog;
|
||||
import org.agt.framework.apilog.core.enums.OperateTypeEnum;
|
||||
import org.agt.framework.common.biz.infra.logger.ApiAccessLogCommonApi;
|
||||
import org.agt.framework.common.biz.infra.logger.dto.ApiAccessLogCreateReqDTO;
|
||||
import org.agt.framework.common.exception.enums.GlobalErrorCodeConstants;
|
||||
import org.agt.framework.common.pojo.CommonResult;
|
||||
import org.agt.framework.common.util.json.JsonUtils;
|
||||
@@ -17,8 +19,6 @@ import org.agt.framework.common.util.servlet.ServletUtils;
|
||||
import org.agt.framework.web.config.WebProperties;
|
||||
import org.agt.framework.web.core.filter.ApiRequestFilter;
|
||||
import org.agt.framework.web.core.util.WebFrameworkUtils;
|
||||
import org.agt.module.infra.api.logger.ApiAccessLogApi;
|
||||
import org.agt.module.infra.api.logger.dto.ApiAccessLogCreateReqDTO;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
@@ -53,9 +53,9 @@ public class ApiAccessLogFilter extends ApiRequestFilter {
|
||||
|
||||
private final String applicationName;
|
||||
|
||||
private final ApiAccessLogApi apiAccessLogApi;
|
||||
private final ApiAccessLogCommonApi apiAccessLogApi;
|
||||
|
||||
public ApiAccessLogFilter(WebProperties webProperties, String applicationName, ApiAccessLogApi apiAccessLogApi) {
|
||||
public ApiAccessLogFilter(WebProperties webProperties, String applicationName, ApiAccessLogCommonApi apiAccessLogApi) {
|
||||
super(webProperties);
|
||||
this.applicationName = applicationName;
|
||||
this.apiAccessLogApi = apiAccessLogApi;
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package org.agt.framework.web.config;
|
||||
|
||||
import org.agt.framework.common.biz.infra.logger.ApiErrorLogCommonApi;
|
||||
import org.agt.framework.common.enums.WebFilterOrderEnum;
|
||||
import org.agt.framework.web.core.filter.CacheRequestBodyFilter;
|
||||
import org.agt.framework.web.core.filter.DemoFilter;
|
||||
import org.agt.framework.web.core.handler.GlobalExceptionHandler;
|
||||
import org.agt.framework.web.core.handler.GlobalResponseBodyHandler;
|
||||
import org.agt.framework.web.core.util.WebFrameworkUtils;
|
||||
import org.agt.module.infra.api.logger.ApiErrorLogApi;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
@@ -59,8 +59,7 @@ public class AgtWebAutoConfiguration implements WebMvcConfigurer {
|
||||
}
|
||||
|
||||
@Bean
|
||||
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
|
||||
public GlobalExceptionHandler globalExceptionHandler(ApiErrorLogApi apiErrorLogApi) {
|
||||
public GlobalExceptionHandler globalExceptionHandler(ApiErrorLogCommonApi apiErrorLogApi) {
|
||||
return new GlobalExceptionHandler(applicationName, apiErrorLogApi);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@ import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.extra.servlet.JakartaServletUtil;
|
||||
import org.agt.framework.common.biz.infra.logger.ApiErrorLogCommonApi;
|
||||
import org.agt.framework.common.biz.infra.logger.dto.ApiErrorLogCreateReqDTO;
|
||||
import org.agt.framework.common.exception.ServiceException;
|
||||
import org.agt.framework.common.exception.util.ServiceExceptionUtil;
|
||||
import org.agt.framework.common.pojo.CommonResult;
|
||||
@@ -14,8 +16,6 @@ import org.agt.framework.common.util.json.JsonUtils;
|
||||
import org.agt.framework.common.util.monitor.TracerUtils;
|
||||
import org.agt.framework.common.util.servlet.ServletUtils;
|
||||
import org.agt.framework.web.core.util.WebFrameworkUtils;
|
||||
import org.agt.module.infra.api.logger.ApiErrorLogApi;
|
||||
import org.agt.module.infra.api.logger.dto.ApiErrorLogCreateReqDTO;
|
||||
import com.fasterxml.jackson.databind.exc.InvalidFormatException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.validation.ConstraintViolation;
|
||||
@@ -63,7 +63,7 @@ public class GlobalExceptionHandler {
|
||||
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
|
||||
private final String applicationName;
|
||||
|
||||
private final ApiErrorLogApi apiErrorLogApi;
|
||||
private final ApiErrorLogCommonApi apiErrorLogApi;
|
||||
|
||||
/**
|
||||
* 处理所有异常,主要是提供给 Filter 使用
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
<name>${project.artifactId}</name>
|
||||
<description>API 服务网关,基于 Spring Cloud Gateway 实现</description>
|
||||
<url>https://github.com/YunaiV/agt-cloud</url>
|
||||
<url>https://github.com/agt/agt-cloud</url>
|
||||
|
||||
<dependencies>
|
||||
<!-- 业务组件 -->
|
||||
|
||||
@@ -47,7 +47,7 @@ public class GrayReactiveLoadBalancerClientFilter implements GlobalFilter, Order
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
// https://github.com/YunaiV/agt-cloud/pull/213
|
||||
// https://github.com/agt/agt-cloud/pull/213
|
||||
return ReactiveLoadBalancerClientFilter.LOAD_BALANCER_CLIENT_FILTER_ORDER - 50;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,8 +7,8 @@ import org.agt.framework.common.util.date.LocalDateTimeUtils;
|
||||
import org.agt.framework.common.util.json.JsonUtils;
|
||||
import org.agt.gateway.util.SecurityFrameworkUtils;
|
||||
import org.agt.gateway.util.WebFrameworkUtils;
|
||||
import org.agt.module.system.api.oauth2.OAuth2TokenApi;
|
||||
import org.agt.module.system.api.oauth2.dto.OAuth2AccessTokenCheckRespDTO;
|
||||
import org.agt.framework.common.biz.system.oauth2.OAuth2TokenCommonApi;
|
||||
import org.agt.framework.common.biz.system.oauth2.dto.OAuth2AccessTokenCheckRespDTO;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
@@ -133,7 +133,7 @@ public class TokenAuthenticationFilter implements GlobalFilter, Ordered {
|
||||
|
||||
private Mono<String> checkAccessToken(Long tenantId, String token) {
|
||||
return webClient.get()
|
||||
.uri(OAuth2TokenApi.URL_CHECK, uriBuilder -> uriBuilder.queryParam("accessToken", token).build())
|
||||
.uri(OAuth2TokenCommonApi.URL_CHECK, uriBuilder -> uriBuilder.queryParam("accessToken", token).build())
|
||||
.headers(httpHeaders -> WebFrameworkUtils.setTenantIdHeader(tenantId, httpHeaders)) // 设置租户的 Header
|
||||
.retrieve().bodyToMono(String.class);
|
||||
}
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
package org.agt.module.infra.api.logger.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "RPC 服务 - API 访问日志创建 Request DTO")
|
||||
@Data
|
||||
public class ApiAccessLogCreateReqDTO {
|
||||
|
||||
@Schema(description = "链路追踪编号", example = "89aca178-a370-411c-ae02-3f0d672be4ab")
|
||||
private String traceId;
|
||||
|
||||
@Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long userId;
|
||||
@Schema(description = "用户类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer userType;
|
||||
@Schema(description = "应用名", requiredMode = Schema.RequiredMode.REQUIRED, example = "system-server")
|
||||
@NotNull(message = "应用名不能为空")
|
||||
private String applicationName;
|
||||
|
||||
@Schema(description = "请求方法名", requiredMode = Schema.RequiredMode.REQUIRED, example = "GET")
|
||||
@NotNull(message = "http 请求方法不能为空")
|
||||
private String requestMethod;
|
||||
@Schema(description = "请求地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "/xxx/yyy")
|
||||
@NotNull(message = "访问地址不能为空")
|
||||
private String requestUrl;
|
||||
@Schema(description = "请求参数")
|
||||
private String requestParams;
|
||||
@Schema(description = "响应结果")
|
||||
private String responseBody;
|
||||
@Schema(description = "用户 IP", requiredMode = Schema.RequiredMode.REQUIRED, example = "127.0.0.1")
|
||||
@NotNull(message = "ip 不能为空")
|
||||
private String userIp;
|
||||
@Schema(description = "浏览器 UserAgent", requiredMode = Schema.RequiredMode.REQUIRED, example = "Mozilla/5.0")
|
||||
@NotNull(message = "User-Agent 不能为空")
|
||||
private String userAgent;
|
||||
|
||||
@Schema(description = "操作模块", requiredMode = Schema.RequiredMode.REQUIRED, example = "商品模块")
|
||||
private String operateModule;
|
||||
@Schema(description = "操作名", requiredMode = Schema.RequiredMode.REQUIRED, example = "商品新增")
|
||||
private String operateName;
|
||||
@Schema(description = "操作分类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer operateType; // 参见 OperateTypeEnum 枚举
|
||||
|
||||
@Schema(description = "开始时间",requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "开始请求时间不能为空")
|
||||
private LocalDateTime beginTime;
|
||||
@Schema(description = "结束时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "结束请求时间不能为空")
|
||||
private LocalDateTime endTime;
|
||||
@Schema(description = "执行时长,单位:毫秒", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "执行时长不能为空")
|
||||
private Integer duration;
|
||||
@Schema(description = "结果码", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "错误码不能为空")
|
||||
private Integer resultCode;
|
||||
@Schema(description = "结果提示")
|
||||
private String resultMsg;
|
||||
|
||||
}
|
||||
@@ -7,6 +7,8 @@ package org.agt.module.infra.enums;
|
||||
*/
|
||||
public interface DictTypeConstants {
|
||||
|
||||
String USER_TYPE = "user_type"; // 用户类型
|
||||
|
||||
String JOB_STATUS = "infra_job_status"; // 定时任务状态的枚举
|
||||
String JOB_LOG_STATUS = "infra_job_log_status"; // 定时任务日志状态的枚举
|
||||
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
package org.agt.module.infra.dal.dataobject.demo;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalDateTime;
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import org.agt.framework.mybatis.core.dataobject.BaseDO;
|
||||
|
||||
/**
|
||||
* 学生 DO
|
||||
*
|
||||
* @author sys
|
||||
*/
|
||||
@TableName("infra_student")
|
||||
@KeySequence("infra_student_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class InfraStudentDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 编号
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* 名字
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 简介
|
||||
*/
|
||||
private String description;
|
||||
/**
|
||||
* 出生日期
|
||||
*/
|
||||
private LocalDateTime birthday;
|
||||
/**
|
||||
* 性别
|
||||
*
|
||||
* 枚举 {@link TODO system_user_sex 对应的类}
|
||||
*/
|
||||
private Integer sex;
|
||||
/**
|
||||
* 是否有效
|
||||
*
|
||||
* 枚举 {@link TODO infra_boolean_string 对应的类}
|
||||
*/
|
||||
private Boolean enabled;
|
||||
/**
|
||||
* 头像
|
||||
*/
|
||||
private String avatar;
|
||||
/**
|
||||
* 附件
|
||||
*/
|
||||
private String video;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String memo;
|
||||
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package org.agt.module.infra.dal.mysql.demo;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import org.agt.framework.common.pojo.PageResult;
|
||||
import org.agt.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import org.agt.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import org.agt.module.infra.dal.dataobject.demo.InfraStudentDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.agt.module.infra.controller.admin.demo.vo.*;
|
||||
|
||||
/**
|
||||
* 学生 Mapper
|
||||
*
|
||||
* @author sys
|
||||
*/
|
||||
@Mapper
|
||||
public interface InfraStudentMapper extends BaseMapperX<InfraStudentDO> {
|
||||
|
||||
default PageResult<InfraStudentDO> selectPage(InfraStudentPageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<InfraStudentDO>()
|
||||
.likeIfPresent(InfraStudentDO::getName, reqVO.getName())
|
||||
.eqIfPresent(InfraStudentDO::getBirthday, reqVO.getBirthday())
|
||||
.eqIfPresent(InfraStudentDO::getSex, reqVO.getSex())
|
||||
.eqIfPresent(InfraStudentDO::getEnabled, reqVO.getEnabled())
|
||||
.betweenIfPresent(InfraStudentDO::getCreateTime, reqVO.getCreateTime())
|
||||
.orderByDesc(InfraStudentDO::getId));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,146 +0,0 @@
|
||||
package org.agt.module.infra.service.demo;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.agt.framework.test.core.ut.BaseDbUnitTest;
|
||||
|
||||
import org.agt.module.infra.controller.admin.demo.vo.*;
|
||||
import org.agt.module.infra.dal.dataobject.demo.InfraStudentDO;
|
||||
import org.agt.module.infra.dal.mysql.demo.InfraStudentMapper;
|
||||
import org.agt.framework.common.pojo.PageResult;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import java.util.*;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.hutool.core.util.RandomUtil.*;
|
||||
import static org.agt.module.infra.enums.ErrorCodeConstants.*;
|
||||
import static org.agt.framework.test.core.util.AssertUtils.*;
|
||||
import static org.agt.framework.test.core.util.RandomUtils.*;
|
||||
import static org.agt.framework.common.util.date.LocalDateTimeUtils.*;
|
||||
import static org.agt.framework.common.util.object.ObjectUtils.*;
|
||||
import static org.agt.framework.common.util.date.DateUtils.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
/**
|
||||
* {@link InfraStudentServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author sys
|
||||
*/
|
||||
@Import(InfraStudentServiceImpl.class)
|
||||
public class InfraStudentServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private InfraStudentServiceImpl studentService;
|
||||
|
||||
@Resource
|
||||
private InfraStudentMapper studentMapper;
|
||||
|
||||
@Test
|
||||
public void testCreateStudent_success() {
|
||||
// 准备参数
|
||||
InfraStudentSaveReqVO createReqVO = randomPojo(InfraStudentSaveReqVO.class).setId(null);
|
||||
|
||||
// 调用
|
||||
Long studentId = studentService.createStudent(createReqVO);
|
||||
// 断言
|
||||
assertNotNull(studentId);
|
||||
// 校验记录的属性是否正确
|
||||
InfraStudentDO student = studentMapper.selectById(studentId);
|
||||
assertPojoEquals(createReqVO, student, "id");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateStudent_success() {
|
||||
// mock 数据
|
||||
InfraStudentDO dbStudent = randomPojo(InfraStudentDO.class);
|
||||
studentMapper.insert(dbStudent);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
InfraStudentSaveReqVO updateReqVO = randomPojo(InfraStudentSaveReqVO.class, o -> {
|
||||
o.setId(dbStudent.getId()); // 设置更新的 ID
|
||||
});
|
||||
|
||||
// 调用
|
||||
studentService.updateStudent(updateReqVO);
|
||||
// 校验是否更新正确
|
||||
InfraStudentDO student = studentMapper.selectById(updateReqVO.getId()); // 获取最新的
|
||||
assertPojoEquals(updateReqVO, student);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateStudent_notExists() {
|
||||
// 准备参数
|
||||
InfraStudentSaveReqVO updateReqVO = randomPojo(InfraStudentSaveReqVO.class);
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> studentService.updateStudent(updateReqVO), STUDENT_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteStudent_success() {
|
||||
// mock 数据
|
||||
InfraStudentDO dbStudent = randomPojo(InfraStudentDO.class);
|
||||
studentMapper.insert(dbStudent);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbStudent.getId();
|
||||
|
||||
// 调用
|
||||
studentService.deleteStudent(id);
|
||||
// 校验数据不存在了
|
||||
assertNull(studentMapper.selectById(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteStudent_notExists() {
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> studentService.deleteStudent(id), STUDENT_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
|
||||
public void testGetStudentPage() {
|
||||
// mock 数据
|
||||
InfraStudentDO dbStudent = randomPojo(InfraStudentDO.class, o -> { // 等会查询到
|
||||
o.setName(null);
|
||||
o.setBirthday(null);
|
||||
o.setSex(null);
|
||||
o.setEnabled(null);
|
||||
o.setCreateTime(null);
|
||||
});
|
||||
studentMapper.insert(dbStudent);
|
||||
// 测试 name 不匹配
|
||||
studentMapper.insert(cloneIgnoreId(dbStudent, o -> o.setName(null)));
|
||||
// 测试 birthday 不匹配
|
||||
studentMapper.insert(cloneIgnoreId(dbStudent, o -> o.setBirthday(null)));
|
||||
// 测试 sex 不匹配
|
||||
studentMapper.insert(cloneIgnoreId(dbStudent, o -> o.setSex(null)));
|
||||
// 测试 enabled 不匹配
|
||||
studentMapper.insert(cloneIgnoreId(dbStudent, o -> o.setEnabled(null)));
|
||||
// 测试 createTime 不匹配
|
||||
studentMapper.insert(cloneIgnoreId(dbStudent, o -> o.setCreateTime(null)));
|
||||
// 准备参数
|
||||
InfraStudentPageReqVO reqVO = new InfraStudentPageReqVO();
|
||||
reqVO.setName(null);
|
||||
reqVO.setBirthday(null);
|
||||
reqVO.setSex(null);
|
||||
reqVO.setEnabled(null);
|
||||
reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
|
||||
|
||||
// 调用
|
||||
PageResult<InfraStudentDO> pageResult = studentService.getStudentPage(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(dbStudent, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
package org.agt.module.infra.dal.dataobject.demo;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalDateTime;
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import org.agt.framework.mybatis.core.dataobject.BaseDO;
|
||||
|
||||
/**
|
||||
* 学生联系人 DO
|
||||
*
|
||||
* @author sys
|
||||
*/
|
||||
@TableName("infra_student_contact")
|
||||
@KeySequence("infra_student_contact_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class InfraStudentContactDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 编号
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* 学生编号
|
||||
*/
|
||||
private Long studentId;
|
||||
/**
|
||||
* 名字
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 简介
|
||||
*/
|
||||
private String description;
|
||||
/**
|
||||
* 出生日期
|
||||
*/
|
||||
private LocalDateTime birthday;
|
||||
/**
|
||||
* 性别
|
||||
*
|
||||
* 枚举 {@link TODO system_user_sex 对应的类}
|
||||
*/
|
||||
private Integer sex;
|
||||
/**
|
||||
* 是否有效
|
||||
*
|
||||
* 枚举 {@link TODO infra_boolean_string 对应的类}
|
||||
*/
|
||||
private Boolean enabled;
|
||||
/**
|
||||
* 头像
|
||||
*/
|
||||
private String avatar;
|
||||
/**
|
||||
* 附件
|
||||
*/
|
||||
private String video;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String memo;
|
||||
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
package org.agt.module.infra.dal.dataobject.demo;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalDateTime;
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import org.agt.framework.mybatis.core.dataobject.BaseDO;
|
||||
|
||||
/**
|
||||
* 学生 DO
|
||||
*
|
||||
* @author sys
|
||||
*/
|
||||
@TableName("infra_student")
|
||||
@KeySequence("infra_student_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class InfraStudentDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 编号
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* 名字
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 简介
|
||||
*/
|
||||
private String description;
|
||||
/**
|
||||
* 出生日期
|
||||
*/
|
||||
private LocalDateTime birthday;
|
||||
/**
|
||||
* 性别
|
||||
*
|
||||
* 枚举 {@link TODO system_user_sex 对应的类}
|
||||
*/
|
||||
private Integer sex;
|
||||
/**
|
||||
* 是否有效
|
||||
*
|
||||
* 枚举 {@link TODO infra_boolean_string 对应的类}
|
||||
*/
|
||||
private Boolean enabled;
|
||||
/**
|
||||
* 头像
|
||||
*/
|
||||
private String avatar;
|
||||
/**
|
||||
* 附件
|
||||
*/
|
||||
private String video;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String memo;
|
||||
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package org.agt.module.infra.dal.mysql.demo;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import org.agt.framework.common.pojo.PageResult;
|
||||
import org.agt.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import org.agt.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import org.agt.module.infra.dal.dataobject.demo.InfraStudentDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.agt.module.infra.controller.admin.demo.vo.*;
|
||||
|
||||
/**
|
||||
* 学生 Mapper
|
||||
*
|
||||
* @author sys
|
||||
*/
|
||||
@Mapper
|
||||
public interface InfraStudentMapper extends BaseMapperX<InfraStudentDO> {
|
||||
|
||||
default PageResult<InfraStudentDO> selectPage(InfraStudentPageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<InfraStudentDO>()
|
||||
.likeIfPresent(InfraStudentDO::getName, reqVO.getName())
|
||||
.eqIfPresent(InfraStudentDO::getBirthday, reqVO.getBirthday())
|
||||
.eqIfPresent(InfraStudentDO::getSex, reqVO.getSex())
|
||||
.eqIfPresent(InfraStudentDO::getEnabled, reqVO.getEnabled())
|
||||
.betweenIfPresent(InfraStudentDO::getCreateTime, reqVO.getCreateTime())
|
||||
.orderByDesc(InfraStudentDO::getId));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,146 +0,0 @@
|
||||
package org.agt.module.infra.service.demo;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.agt.framework.test.core.ut.BaseDbUnitTest;
|
||||
|
||||
import org.agt.module.infra.controller.admin.demo.vo.*;
|
||||
import org.agt.module.infra.dal.dataobject.demo.InfraStudentDO;
|
||||
import org.agt.module.infra.dal.mysql.demo.InfraStudentMapper;
|
||||
import org.agt.framework.common.pojo.PageResult;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import java.util.*;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.hutool.core.util.RandomUtil.*;
|
||||
import static org.agt.module.infra.enums.ErrorCodeConstants.*;
|
||||
import static org.agt.framework.test.core.util.AssertUtils.*;
|
||||
import static org.agt.framework.test.core.util.RandomUtils.*;
|
||||
import static org.agt.framework.common.util.date.LocalDateTimeUtils.*;
|
||||
import static org.agt.framework.common.util.object.ObjectUtils.*;
|
||||
import static org.agt.framework.common.util.date.DateUtils.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
/**
|
||||
* {@link InfraStudentServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author sys
|
||||
*/
|
||||
@Import(InfraStudentServiceImpl.class)
|
||||
public class InfraStudentServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private InfraStudentServiceImpl studentService;
|
||||
|
||||
@Resource
|
||||
private InfraStudentMapper studentMapper;
|
||||
|
||||
@Test
|
||||
public void testCreateStudent_success() {
|
||||
// 准备参数
|
||||
InfraStudentSaveReqVO createReqVO = randomPojo(InfraStudentSaveReqVO.class).setId(null);
|
||||
|
||||
// 调用
|
||||
Long studentId = studentService.createStudent(createReqVO);
|
||||
// 断言
|
||||
assertNotNull(studentId);
|
||||
// 校验记录的属性是否正确
|
||||
InfraStudentDO student = studentMapper.selectById(studentId);
|
||||
assertPojoEquals(createReqVO, student, "id");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateStudent_success() {
|
||||
// mock 数据
|
||||
InfraStudentDO dbStudent = randomPojo(InfraStudentDO.class);
|
||||
studentMapper.insert(dbStudent);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
InfraStudentSaveReqVO updateReqVO = randomPojo(InfraStudentSaveReqVO.class, o -> {
|
||||
o.setId(dbStudent.getId()); // 设置更新的 ID
|
||||
});
|
||||
|
||||
// 调用
|
||||
studentService.updateStudent(updateReqVO);
|
||||
// 校验是否更新正确
|
||||
InfraStudentDO student = studentMapper.selectById(updateReqVO.getId()); // 获取最新的
|
||||
assertPojoEquals(updateReqVO, student);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateStudent_notExists() {
|
||||
// 准备参数
|
||||
InfraStudentSaveReqVO updateReqVO = randomPojo(InfraStudentSaveReqVO.class);
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> studentService.updateStudent(updateReqVO), STUDENT_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteStudent_success() {
|
||||
// mock 数据
|
||||
InfraStudentDO dbStudent = randomPojo(InfraStudentDO.class);
|
||||
studentMapper.insert(dbStudent);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbStudent.getId();
|
||||
|
||||
// 调用
|
||||
studentService.deleteStudent(id);
|
||||
// 校验数据不存在了
|
||||
assertNull(studentMapper.selectById(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteStudent_notExists() {
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> studentService.deleteStudent(id), STUDENT_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
|
||||
public void testGetStudentPage() {
|
||||
// mock 数据
|
||||
InfraStudentDO dbStudent = randomPojo(InfraStudentDO.class, o -> { // 等会查询到
|
||||
o.setName(null);
|
||||
o.setBirthday(null);
|
||||
o.setSex(null);
|
||||
o.setEnabled(null);
|
||||
o.setCreateTime(null);
|
||||
});
|
||||
studentMapper.insert(dbStudent);
|
||||
// 测试 name 不匹配
|
||||
studentMapper.insert(cloneIgnoreId(dbStudent, o -> o.setName(null)));
|
||||
// 测试 birthday 不匹配
|
||||
studentMapper.insert(cloneIgnoreId(dbStudent, o -> o.setBirthday(null)));
|
||||
// 测试 sex 不匹配
|
||||
studentMapper.insert(cloneIgnoreId(dbStudent, o -> o.setSex(null)));
|
||||
// 测试 enabled 不匹配
|
||||
studentMapper.insert(cloneIgnoreId(dbStudent, o -> o.setEnabled(null)));
|
||||
// 测试 createTime 不匹配
|
||||
studentMapper.insert(cloneIgnoreId(dbStudent, o -> o.setCreateTime(null)));
|
||||
// 准备参数
|
||||
InfraStudentPageReqVO reqVO = new InfraStudentPageReqVO();
|
||||
reqVO.setName(null);
|
||||
reqVO.setBirthday(null);
|
||||
reqVO.setSex(null);
|
||||
reqVO.setEnabled(null);
|
||||
reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
|
||||
|
||||
// 调用
|
||||
PageResult<InfraStudentDO> pageResult = studentService.getStudentPage(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(dbStudent, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
package org.agt.module.infra.dal.dataobject.demo;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalDateTime;
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import org.agt.framework.mybatis.core.dataobject.BaseDO;
|
||||
|
||||
/**
|
||||
* 学生班主任 DO
|
||||
*
|
||||
* @author sys
|
||||
*/
|
||||
@TableName("infra_student_teacher")
|
||||
@KeySequence("infra_student_teacher_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class InfraStudentTeacherDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 编号
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* 学生编号
|
||||
*/
|
||||
private Long studentId;
|
||||
/**
|
||||
* 名字
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 简介
|
||||
*/
|
||||
private String description;
|
||||
/**
|
||||
* 出生日期
|
||||
*/
|
||||
private LocalDateTime birthday;
|
||||
/**
|
||||
* 性别
|
||||
*
|
||||
* 枚举 {@link TODO system_user_sex 对应的类}
|
||||
*/
|
||||
private Integer sex;
|
||||
/**
|
||||
* 是否有效
|
||||
*
|
||||
* 枚举 {@link TODO infra_boolean_string 对应的类}
|
||||
*/
|
||||
private Boolean enabled;
|
||||
/**
|
||||
* 头像
|
||||
*/
|
||||
private String avatar;
|
||||
/**
|
||||
* 附件
|
||||
*/
|
||||
private String video;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String memo;
|
||||
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
package org.agt.module.infra.dal.dataobject.demo;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalDateTime;
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import org.agt.framework.mybatis.core.dataobject.BaseDO;
|
||||
|
||||
/**
|
||||
* 学生联系人 DO
|
||||
*
|
||||
* @author sys
|
||||
*/
|
||||
@TableName("infra_student_contact")
|
||||
@KeySequence("infra_student_contact_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class InfraStudentContactDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 编号
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* 学生编号
|
||||
*/
|
||||
private Long studentId;
|
||||
/**
|
||||
* 名字
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 简介
|
||||
*/
|
||||
private String description;
|
||||
/**
|
||||
* 出生日期
|
||||
*/
|
||||
private LocalDateTime birthday;
|
||||
/**
|
||||
* 性别
|
||||
*
|
||||
* 枚举 {@link TODO system_user_sex 对应的类}
|
||||
*/
|
||||
private Integer sex;
|
||||
/**
|
||||
* 是否有效
|
||||
*
|
||||
* 枚举 {@link TODO infra_boolean_string 对应的类}
|
||||
*/
|
||||
private Boolean enabled;
|
||||
/**
|
||||
* 头像
|
||||
*/
|
||||
private String avatar;
|
||||
/**
|
||||
* 附件
|
||||
*/
|
||||
private String video;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String memo;
|
||||
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
package org.agt.module.infra.dal.dataobject.demo;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalDateTime;
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import org.agt.framework.mybatis.core.dataobject.BaseDO;
|
||||
|
||||
/**
|
||||
* 学生 DO
|
||||
*
|
||||
* @author sys
|
||||
*/
|
||||
@TableName("infra_student")
|
||||
@KeySequence("infra_student_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class InfraStudentDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 编号
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* 名字
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 简介
|
||||
*/
|
||||
private String description;
|
||||
/**
|
||||
* 出生日期
|
||||
*/
|
||||
private LocalDateTime birthday;
|
||||
/**
|
||||
* 性别
|
||||
*
|
||||
* 枚举 {@link TODO system_user_sex 对应的类}
|
||||
*/
|
||||
private Integer sex;
|
||||
/**
|
||||
* 是否有效
|
||||
*
|
||||
* 枚举 {@link TODO infra_boolean_string 对应的类}
|
||||
*/
|
||||
private Boolean enabled;
|
||||
/**
|
||||
* 头像
|
||||
*/
|
||||
private String avatar;
|
||||
/**
|
||||
* 附件
|
||||
*/
|
||||
private String video;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String memo;
|
||||
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package org.agt.module.infra.dal.mysql.demo;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import org.agt.framework.common.pojo.PageResult;
|
||||
import org.agt.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import org.agt.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import org.agt.module.infra.dal.dataobject.demo.InfraStudentDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.agt.module.infra.controller.admin.demo.vo.*;
|
||||
|
||||
/**
|
||||
* 学生 Mapper
|
||||
*
|
||||
* @author sys
|
||||
*/
|
||||
@Mapper
|
||||
public interface InfraStudentMapper extends BaseMapperX<InfraStudentDO> {
|
||||
|
||||
default PageResult<InfraStudentDO> selectPage(InfraStudentPageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<InfraStudentDO>()
|
||||
.likeIfPresent(InfraStudentDO::getName, reqVO.getName())
|
||||
.eqIfPresent(InfraStudentDO::getBirthday, reqVO.getBirthday())
|
||||
.eqIfPresent(InfraStudentDO::getSex, reqVO.getSex())
|
||||
.eqIfPresent(InfraStudentDO::getEnabled, reqVO.getEnabled())
|
||||
.betweenIfPresent(InfraStudentDO::getCreateTime, reqVO.getCreateTime())
|
||||
.orderByDesc(InfraStudentDO::getId));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,146 +0,0 @@
|
||||
package org.agt.module.infra.service.demo;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.agt.framework.test.core.ut.BaseDbUnitTest;
|
||||
|
||||
import org.agt.module.infra.controller.admin.demo.vo.*;
|
||||
import org.agt.module.infra.dal.dataobject.demo.InfraStudentDO;
|
||||
import org.agt.module.infra.dal.mysql.demo.InfraStudentMapper;
|
||||
import org.agt.framework.common.pojo.PageResult;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import java.util.*;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.hutool.core.util.RandomUtil.*;
|
||||
import static org.agt.module.infra.enums.ErrorCodeConstants.*;
|
||||
import static org.agt.framework.test.core.util.AssertUtils.*;
|
||||
import static org.agt.framework.test.core.util.RandomUtils.*;
|
||||
import static org.agt.framework.common.util.date.LocalDateTimeUtils.*;
|
||||
import static org.agt.framework.common.util.object.ObjectUtils.*;
|
||||
import static org.agt.framework.common.util.date.DateUtils.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
/**
|
||||
* {@link InfraStudentServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author sys
|
||||
*/
|
||||
@Import(InfraStudentServiceImpl.class)
|
||||
public class InfraStudentServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private InfraStudentServiceImpl studentService;
|
||||
|
||||
@Resource
|
||||
private InfraStudentMapper studentMapper;
|
||||
|
||||
@Test
|
||||
public void testCreateStudent_success() {
|
||||
// 准备参数
|
||||
InfraStudentSaveReqVO createReqVO = randomPojo(InfraStudentSaveReqVO.class).setId(null);
|
||||
|
||||
// 调用
|
||||
Long studentId = studentService.createStudent(createReqVO);
|
||||
// 断言
|
||||
assertNotNull(studentId);
|
||||
// 校验记录的属性是否正确
|
||||
InfraStudentDO student = studentMapper.selectById(studentId);
|
||||
assertPojoEquals(createReqVO, student, "id");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateStudent_success() {
|
||||
// mock 数据
|
||||
InfraStudentDO dbStudent = randomPojo(InfraStudentDO.class);
|
||||
studentMapper.insert(dbStudent);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
InfraStudentSaveReqVO updateReqVO = randomPojo(InfraStudentSaveReqVO.class, o -> {
|
||||
o.setId(dbStudent.getId()); // 设置更新的 ID
|
||||
});
|
||||
|
||||
// 调用
|
||||
studentService.updateStudent(updateReqVO);
|
||||
// 校验是否更新正确
|
||||
InfraStudentDO student = studentMapper.selectById(updateReqVO.getId()); // 获取最新的
|
||||
assertPojoEquals(updateReqVO, student);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateStudent_notExists() {
|
||||
// 准备参数
|
||||
InfraStudentSaveReqVO updateReqVO = randomPojo(InfraStudentSaveReqVO.class);
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> studentService.updateStudent(updateReqVO), STUDENT_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteStudent_success() {
|
||||
// mock 数据
|
||||
InfraStudentDO dbStudent = randomPojo(InfraStudentDO.class);
|
||||
studentMapper.insert(dbStudent);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbStudent.getId();
|
||||
|
||||
// 调用
|
||||
studentService.deleteStudent(id);
|
||||
// 校验数据不存在了
|
||||
assertNull(studentMapper.selectById(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteStudent_notExists() {
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> studentService.deleteStudent(id), STUDENT_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
|
||||
public void testGetStudentPage() {
|
||||
// mock 数据
|
||||
InfraStudentDO dbStudent = randomPojo(InfraStudentDO.class, o -> { // 等会查询到
|
||||
o.setName(null);
|
||||
o.setBirthday(null);
|
||||
o.setSex(null);
|
||||
o.setEnabled(null);
|
||||
o.setCreateTime(null);
|
||||
});
|
||||
studentMapper.insert(dbStudent);
|
||||
// 测试 name 不匹配
|
||||
studentMapper.insert(cloneIgnoreId(dbStudent, o -> o.setName(null)));
|
||||
// 测试 birthday 不匹配
|
||||
studentMapper.insert(cloneIgnoreId(dbStudent, o -> o.setBirthday(null)));
|
||||
// 测试 sex 不匹配
|
||||
studentMapper.insert(cloneIgnoreId(dbStudent, o -> o.setSex(null)));
|
||||
// 测试 enabled 不匹配
|
||||
studentMapper.insert(cloneIgnoreId(dbStudent, o -> o.setEnabled(null)));
|
||||
// 测试 createTime 不匹配
|
||||
studentMapper.insert(cloneIgnoreId(dbStudent, o -> o.setCreateTime(null)));
|
||||
// 准备参数
|
||||
InfraStudentPageReqVO reqVO = new InfraStudentPageReqVO();
|
||||
reqVO.setName(null);
|
||||
reqVO.setBirthday(null);
|
||||
reqVO.setSex(null);
|
||||
reqVO.setEnabled(null);
|
||||
reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
|
||||
|
||||
// 调用
|
||||
PageResult<InfraStudentDO> pageResult = studentService.getStudentPage(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(dbStudent, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
package org.agt.module.infra.dal.dataobject.demo;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalDateTime;
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import org.agt.framework.mybatis.core.dataobject.BaseDO;
|
||||
|
||||
/**
|
||||
* 学生班主任 DO
|
||||
*
|
||||
* @author sys
|
||||
*/
|
||||
@TableName("infra_student_teacher")
|
||||
@KeySequence("infra_student_teacher_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class InfraStudentTeacherDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 编号
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* 学生编号
|
||||
*/
|
||||
private Long studentId;
|
||||
/**
|
||||
* 名字
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 简介
|
||||
*/
|
||||
private String description;
|
||||
/**
|
||||
* 出生日期
|
||||
*/
|
||||
private LocalDateTime birthday;
|
||||
/**
|
||||
* 性别
|
||||
*
|
||||
* 枚举 {@link TODO system_user_sex 对应的类}
|
||||
*/
|
||||
private Integer sex;
|
||||
/**
|
||||
* 是否有效
|
||||
*
|
||||
* 枚举 {@link TODO infra_boolean_string 对应的类}
|
||||
*/
|
||||
private Boolean enabled;
|
||||
/**
|
||||
* 头像
|
||||
*/
|
||||
private String avatar;
|
||||
/**
|
||||
* 附件
|
||||
*/
|
||||
private String video;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String memo;
|
||||
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
package org.agt.module.infra.dal.dataobject.demo;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalDateTime;
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import org.agt.framework.mybatis.core.dataobject.BaseDO;
|
||||
|
||||
/**
|
||||
* 学生 DO
|
||||
*
|
||||
* @author sys
|
||||
*/
|
||||
@TableName("infra_student")
|
||||
@KeySequence("infra_student_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class InfraStudentDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 编号
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* 名字
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 简介
|
||||
*/
|
||||
private String description;
|
||||
/**
|
||||
* 出生日期
|
||||
*/
|
||||
private LocalDateTime birthday;
|
||||
/**
|
||||
* 性别
|
||||
*
|
||||
* 枚举 {@link TODO system_user_sex 对应的类}
|
||||
*/
|
||||
private Integer sex;
|
||||
/**
|
||||
* 是否有效
|
||||
*
|
||||
* 枚举 {@link TODO infra_boolean_string 对应的类}
|
||||
*/
|
||||
private Boolean enabled;
|
||||
/**
|
||||
* 头像
|
||||
*/
|
||||
private String avatar;
|
||||
/**
|
||||
* 附件
|
||||
*/
|
||||
private String video;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String memo;
|
||||
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package org.agt.module.infra.dal.mysql.demo;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import org.agt.framework.common.pojo.PageResult;
|
||||
import org.agt.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import org.agt.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import org.agt.module.infra.dal.dataobject.demo.InfraStudentDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.agt.module.infra.controller.admin.demo.vo.*;
|
||||
|
||||
/**
|
||||
* 学生 Mapper
|
||||
*
|
||||
* @author sys
|
||||
*/
|
||||
@Mapper
|
||||
public interface InfraStudentMapper extends BaseMapperX<InfraStudentDO> {
|
||||
|
||||
default PageResult<InfraStudentDO> selectPage(InfraStudentPageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<InfraStudentDO>()
|
||||
.likeIfPresent(InfraStudentDO::getName, reqVO.getName())
|
||||
.eqIfPresent(InfraStudentDO::getBirthday, reqVO.getBirthday())
|
||||
.eqIfPresent(InfraStudentDO::getSex, reqVO.getSex())
|
||||
.eqIfPresent(InfraStudentDO::getEnabled, reqVO.getEnabled())
|
||||
.betweenIfPresent(InfraStudentDO::getCreateTime, reqVO.getCreateTime())
|
||||
.orderByDesc(InfraStudentDO::getId));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,146 +0,0 @@
|
||||
package org.agt.module.infra.service.demo;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.agt.framework.test.core.ut.BaseDbUnitTest;
|
||||
|
||||
import org.agt.module.infra.controller.admin.demo.vo.*;
|
||||
import org.agt.module.infra.dal.dataobject.demo.InfraStudentDO;
|
||||
import org.agt.module.infra.dal.mysql.demo.InfraStudentMapper;
|
||||
import org.agt.framework.common.pojo.PageResult;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import java.util.*;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.hutool.core.util.RandomUtil.*;
|
||||
import static org.agt.module.infra.enums.ErrorCodeConstants.*;
|
||||
import static org.agt.framework.test.core.util.AssertUtils.*;
|
||||
import static org.agt.framework.test.core.util.RandomUtils.*;
|
||||
import static org.agt.framework.common.util.date.LocalDateTimeUtils.*;
|
||||
import static org.agt.framework.common.util.object.ObjectUtils.*;
|
||||
import static org.agt.framework.common.util.date.DateUtils.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
/**
|
||||
* {@link InfraStudentServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author sys
|
||||
*/
|
||||
@Import(InfraStudentServiceImpl.class)
|
||||
public class InfraStudentServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private InfraStudentServiceImpl studentService;
|
||||
|
||||
@Resource
|
||||
private InfraStudentMapper studentMapper;
|
||||
|
||||
@Test
|
||||
public void testCreateStudent_success() {
|
||||
// 准备参数
|
||||
InfraStudentSaveReqVO createReqVO = randomPojo(InfraStudentSaveReqVO.class).setId(null);
|
||||
|
||||
// 调用
|
||||
Long studentId = studentService.createStudent(createReqVO);
|
||||
// 断言
|
||||
assertNotNull(studentId);
|
||||
// 校验记录的属性是否正确
|
||||
InfraStudentDO student = studentMapper.selectById(studentId);
|
||||
assertPojoEquals(createReqVO, student, "id");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateStudent_success() {
|
||||
// mock 数据
|
||||
InfraStudentDO dbStudent = randomPojo(InfraStudentDO.class);
|
||||
studentMapper.insert(dbStudent);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
InfraStudentSaveReqVO updateReqVO = randomPojo(InfraStudentSaveReqVO.class, o -> {
|
||||
o.setId(dbStudent.getId()); // 设置更新的 ID
|
||||
});
|
||||
|
||||
// 调用
|
||||
studentService.updateStudent(updateReqVO);
|
||||
// 校验是否更新正确
|
||||
InfraStudentDO student = studentMapper.selectById(updateReqVO.getId()); // 获取最新的
|
||||
assertPojoEquals(updateReqVO, student);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateStudent_notExists() {
|
||||
// 准备参数
|
||||
InfraStudentSaveReqVO updateReqVO = randomPojo(InfraStudentSaveReqVO.class);
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> studentService.updateStudent(updateReqVO), STUDENT_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteStudent_success() {
|
||||
// mock 数据
|
||||
InfraStudentDO dbStudent = randomPojo(InfraStudentDO.class);
|
||||
studentMapper.insert(dbStudent);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbStudent.getId();
|
||||
|
||||
// 调用
|
||||
studentService.deleteStudent(id);
|
||||
// 校验数据不存在了
|
||||
assertNull(studentMapper.selectById(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteStudent_notExists() {
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> studentService.deleteStudent(id), STUDENT_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
|
||||
public void testGetStudentPage() {
|
||||
// mock 数据
|
||||
InfraStudentDO dbStudent = randomPojo(InfraStudentDO.class, o -> { // 等会查询到
|
||||
o.setName(null);
|
||||
o.setBirthday(null);
|
||||
o.setSex(null);
|
||||
o.setEnabled(null);
|
||||
o.setCreateTime(null);
|
||||
});
|
||||
studentMapper.insert(dbStudent);
|
||||
// 测试 name 不匹配
|
||||
studentMapper.insert(cloneIgnoreId(dbStudent, o -> o.setName(null)));
|
||||
// 测试 birthday 不匹配
|
||||
studentMapper.insert(cloneIgnoreId(dbStudent, o -> o.setBirthday(null)));
|
||||
// 测试 sex 不匹配
|
||||
studentMapper.insert(cloneIgnoreId(dbStudent, o -> o.setSex(null)));
|
||||
// 测试 enabled 不匹配
|
||||
studentMapper.insert(cloneIgnoreId(dbStudent, o -> o.setEnabled(null)));
|
||||
// 测试 createTime 不匹配
|
||||
studentMapper.insert(cloneIgnoreId(dbStudent, o -> o.setCreateTime(null)));
|
||||
// 准备参数
|
||||
InfraStudentPageReqVO reqVO = new InfraStudentPageReqVO();
|
||||
reqVO.setName(null);
|
||||
reqVO.setBirthday(null);
|
||||
reqVO.setSex(null);
|
||||
reqVO.setEnabled(null);
|
||||
reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
|
||||
|
||||
// 调用
|
||||
PageResult<InfraStudentDO> pageResult = studentService.getStudentPage(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(dbStudent, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,7 +8,7 @@
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>agt-module-infra-biz</artifactId>
|
||||
<artifactId>agt-module-infra-server</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>${project.artifactId}</name>
|
||||
@@ -1,7 +1,8 @@
|
||||
package org.agt.module.infra.api.logger;
|
||||
|
||||
import org.agt.framework.common.biz.infra.logger.ApiAccessLogCommonApi;
|
||||
import org.agt.framework.common.biz.infra.logger.dto.ApiAccessLogCreateReqDTO;
|
||||
import org.agt.framework.common.pojo.CommonResult;
|
||||
import org.agt.module.infra.api.logger.dto.ApiAccessLogCreateReqDTO;
|
||||
import org.agt.module.infra.service.logger.ApiAccessLogService;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
@@ -12,7 +13,7 @@ import static org.agt.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@RestController // 提供 RESTful API 接口,给 Feign 调用
|
||||
@Validated
|
||||
public class ApiAccessLogApiImpl implements ApiAccessLogApi {
|
||||
public class ApiAccessLogApiImpl implements ApiAccessLogCommonApi {
|
||||
|
||||
@Resource
|
||||
private ApiAccessLogService apiAccessLogService;
|
||||
@@ -1,7 +1,8 @@
|
||||
package org.agt.module.infra.api.logger;
|
||||
|
||||
import org.agt.framework.common.biz.infra.logger.ApiErrorLogCommonApi;
|
||||
import org.agt.framework.common.biz.infra.logger.dto.ApiErrorLogCreateReqDTO;
|
||||
import org.agt.framework.common.pojo.CommonResult;
|
||||
import org.agt.module.infra.api.logger.dto.ApiErrorLogCreateReqDTO;
|
||||
import org.agt.module.infra.service.logger.ApiErrorLogService;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
@@ -12,7 +13,7 @@ import static org.agt.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@RestController // 提供 RESTful API 接口,给 Feign 调用
|
||||
@Validated
|
||||
public class ApiErrorLogApiImpl implements ApiErrorLogApi {
|
||||
public class ApiErrorLogApiImpl implements ApiErrorLogCommonApi {
|
||||
|
||||
@Resource
|
||||
private ApiErrorLogService apiErrorLogService;
|
||||
@@ -35,6 +35,7 @@ import java.util.Map;
|
||||
|
||||
import static org.agt.framework.common.pojo.CommonResult.success;
|
||||
import static org.agt.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
import static org.agt.framework.security.core.util.SecurityFrameworkUtils.getLoginUserNickname;
|
||||
import static org.agt.module.infra.framework.file.core.utils.FileTypeUtils.writeAttachment;
|
||||
|
||||
@Tag(name = "管理后台 - 代码生成器")
|
||||
@@ -93,7 +94,7 @@ public class CodegenController {
|
||||
@PostMapping("/create-list")
|
||||
@PreAuthorize("@ss.hasPermission('infra:codegen:create')")
|
||||
public CommonResult<List<Long>> createCodegenList(@Valid @RequestBody CodegenCreateListReqVO reqVO) {
|
||||
return success(codegenService.createCodegenList(getLoginUserId(), reqVO));
|
||||
return success(codegenService.createCodegenList(getLoginUserNickname(), reqVO));
|
||||
}
|
||||
|
||||
@Operation(summary = "更新数据库的表和字段定义")
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user