diff --git a/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/config/YudaoMybatisAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/config/YudaoMybatisAutoConfiguration.java index d685fd81a4..ab2992184f 100644 --- a/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/config/YudaoMybatisAutoConfiguration.java +++ b/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/config/YudaoMybatisAutoConfiguration.java @@ -7,6 +7,8 @@ import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; import com.baomidou.mybatisplus.core.incrementer.IKeyGenerator; import com.baomidou.mybatisplus.extension.incrementer.*; +import com.baomidou.mybatisplus.extension.parser.JsqlParserGlobal; +import com.baomidou.mybatisplus.extension.parser.cache.JdkSerialCaffeineJsqlParseCache; import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; import org.apache.ibatis.annotations.Mapper; @@ -16,6 +18,8 @@ import org.springframework.context.annotation.Bean; import org.springframework.core.env.ConfigurableEnvironment; +import java.util.concurrent.TimeUnit; + /** * MyBaits 配置类 * @@ -26,6 +30,14 @@ lazyInitialization = "${mybatis.lazy-initialization:false}") // Mapper 懒加载,目前仅用于单元测试 public class YudaoMybatisAutoConfiguration { + static { + // 动态 SQL 智能优化支持本地缓存加速解析,更完善的租户复杂 XML 动态 SQL 支持,静态注入缓存 + JsqlParserGlobal.setJsqlParseCache(new JdkSerialCaffeineJsqlParseCache( + (cache) -> cache.maximumSize(1024) + .expireAfterWrite(5, TimeUnit.SECONDS)) + ); + } + @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor(); @@ -34,7 +46,7 @@ public MybatisPlusInterceptor mybatisPlusInterceptor() { } @Bean - public MetaObjectHandler defaultMetaObjectHandler(){ + public MetaObjectHandler defaultMetaObjectHandler() { return new DefaultDBFieldHandler(); // 自动填充参数类 } diff --git a/yudao-framework/yudao-spring-boot-starter-protection/src/main/java/cn/iocoder/yudao/framework/signature/core/aop/ApiSignatureAspect.java b/yudao-framework/yudao-spring-boot-starter-protection/src/main/java/cn/iocoder/yudao/framework/signature/core/aop/ApiSignatureAspect.java index fec3c74f49..af276e35a9 100644 --- a/yudao-framework/yudao-spring-boot-starter-protection/src/main/java/cn/iocoder/yudao/framework/signature/core/aop/ApiSignatureAspect.java +++ b/yudao-framework/yudao-spring-boot-starter-protection/src/main/java/cn/iocoder/yudao/framework/signature/core/aop/ApiSignatureAspect.java @@ -69,7 +69,7 @@ public boolean verifySignature(ApiSignature signature, HttpServletRequest reques // 3. 将 nonce 记入缓存,防止重复使用(重点二:此处需要将 ttl 设定为允许 timestamp 时间差的值 x 2 ) String nonce = request.getHeader(signature.nonce()); - signatureRedisDAO.setNonce(nonce, signature.timeout() * 2, signature.timeUnit()); + signatureRedisDAO.setNonce(appId, nonce, signature.timeout() * 2, signature.timeUnit()); return true; } @@ -113,7 +113,7 @@ private boolean verifyHeaders(ApiSignature signature, HttpServletRequest request } // 3. 检查 nonce 是否存在,有且仅能使用一次 - return signatureRedisDAO.getNonce(nonce) == null; + return signatureRedisDAO.getNonce(appId, nonce) == null; } /** @@ -165,5 +165,4 @@ private static SortedMap getRequestParameterMap(HttpServletReque return sortedMap; } -} - +} \ No newline at end of file diff --git a/yudao-framework/yudao-spring-boot-starter-protection/src/main/java/cn/iocoder/yudao/framework/signature/core/redis/ApiSignatureRedisDAO.java b/yudao-framework/yudao-spring-boot-starter-protection/src/main/java/cn/iocoder/yudao/framework/signature/core/redis/ApiSignatureRedisDAO.java index f4aa84910d..11fe384dac 100644 --- a/yudao-framework/yudao-spring-boot-starter-protection/src/main/java/cn/iocoder/yudao/framework/signature/core/redis/ApiSignatureRedisDAO.java +++ b/yudao-framework/yudao-spring-boot-starter-protection/src/main/java/cn/iocoder/yudao/framework/signature/core/redis/ApiSignatureRedisDAO.java @@ -22,7 +22,7 @@ public class ApiSignatureRedisDAO { * VALUE 格式:String * 过期时间:不固定 */ - private static final String SIGNATURE_NONCE = "api_signature_nonce:%s"; + private static final String SIGNATURE_NONCE = "api_signature_nonce:%s:%s"; /** * 签名密钥 @@ -36,16 +36,16 @@ public class ApiSignatureRedisDAO { // ========== 验签随机数 ========== - public String getNonce(String nonce) { - return stringRedisTemplate.opsForValue().get(formatNonceKey(nonce)); + public String getNonce(String appId, String nonce) { + return stringRedisTemplate.opsForValue().get(formatNonceKey(appId, nonce)); } - public void setNonce(String nonce, int time, TimeUnit timeUnit) { - stringRedisTemplate.opsForValue().set(formatNonceKey(nonce), "", time, timeUnit); + public void setNonce(String appId, String nonce, int time, TimeUnit timeUnit) { + stringRedisTemplate.opsForValue().set(formatNonceKey(appId, nonce), "", time, timeUnit); } - private static String formatNonceKey(String key) { - return String.format(SIGNATURE_NONCE, key); + private static String formatNonceKey(String appId, String nonce) { + return String.format(SIGNATURE_NONCE, appId, nonce); } // ========== 签名密钥 ========== diff --git a/yudao-framework/yudao-spring-boot-starter-protection/src/test/java/cn/iocoder/yudao/framework/signature/core/ApiSignatureTest.java b/yudao-framework/yudao-spring-boot-starter-protection/src/test/java/cn/iocoder/yudao/framework/signature/core/ApiSignatureTest.java index 4a80e7bf5c..9eeaf8b440 100644 --- a/yudao-framework/yudao-spring-boot-starter-protection/src/test/java/cn/iocoder/yudao/framework/signature/core/ApiSignatureTest.java +++ b/yudao-framework/yudao-spring-boot-starter-protection/src/test/java/cn/iocoder/yudao/framework/signature/core/ApiSignatureTest.java @@ -69,7 +69,7 @@ public void testSignatureGet() throws IOException { // 断言结果 assertTrue(result); // 断言调用 - verify(signatureRedisDAO).setNonce(eq(nonce), eq(120), eq(TimeUnit.SECONDS)); + verify(signatureRedisDAO).setNonce(eq(appId), eq(nonce), eq(120), eq(TimeUnit.SECONDS)); } } diff --git a/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/operatelog/core/service/LogRecordServiceImpl.java b/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/operatelog/core/service/LogRecordServiceImpl.java index 765857eed0..aaccec169e 100644 --- a/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/operatelog/core/service/LogRecordServiceImpl.java +++ b/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/operatelog/core/service/LogRecordServiceImpl.java @@ -9,6 +9,7 @@ import com.mzt.logapi.beans.LogRecord; import com.mzt.logapi.service.ILogRecordService; import lombok.extern.slf4j.Slf4j; +import org.springframework.scheduling.annotation.Async; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; @@ -28,19 +29,24 @@ public class LogRecordServiceImpl implements ILogRecordService { private OperateLogApi operateLogApi; @Override + @Async public void record(LogRecord logRecord) { - // 1. 补全通用字段 OperateLogCreateReqDTO reqDTO = new OperateLogCreateReqDTO(); - reqDTO.setTraceId(TracerUtils.getTraceId()); - // 补充用户信息 - fillUserFields(reqDTO); - // 补全模块信息 - fillModuleFields(reqDTO, logRecord); - // 补全请求信息 - fillRequestFields(reqDTO); + try { + reqDTO.setTraceId(TracerUtils.getTraceId()); + // 补充用户信息 + fillUserFields(reqDTO); + // 补全模块信息 + fillModuleFields(reqDTO, logRecord); + // 补全请求信息 + fillRequestFields(reqDTO); - // 2. 异步记录日志 - operateLogApi.createOperateLog(reqDTO); + // 2. 异步记录日志 + operateLogApi.createOperateLog(reqDTO).getCheckedData(); + } catch (Throwable ex) { + // 由于 @Async 异步调用,这里打印下日志,更容易跟进 + log.error("[record][url({}) log({}) 发生异常]", reqDTO.getRequestUrl(), reqDTO, ex); + } } private static void fillUserFields(OperateLogCreateReqDTO reqDTO) { diff --git a/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/config/YudaoSecurityAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/config/YudaoSecurityAutoConfiguration.java index 432b2acea8..f23aeed542 100644 --- a/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/config/YudaoSecurityAutoConfiguration.java +++ b/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/config/YudaoSecurityAutoConfiguration.java @@ -10,6 +10,7 @@ import cn.iocoder.yudao.framework.web.core.handler.GlobalExceptionHandler; import cn.iocoder.yudao.module.system.api.oauth2.OAuth2TokenApi; import cn.iocoder.yudao.module.system.api.permission.PermissionApi; +import jakarta.annotation.Resource; import org.springframework.beans.factory.config.MethodInvokingFactoryBean; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigureOrder; @@ -21,8 +22,6 @@ import org.springframework.security.web.AuthenticationEntryPoint; import org.springframework.security.web.access.AccessDeniedHandler; -import javax.annotation.Resource; - /** * Spring Security 自动配置类,主要用于相关组件的配置 * diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java index 245fca2867..c9ccf19248 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java @@ -63,6 +63,7 @@ public class BpmModelServiceImpl implements BpmModelService { @Override public PageResult getModelPage(BpmModelPageReqVO pageVO) { ModelQuery modelQuery = repositoryService.createModelQuery(); + modelQuery.modelTenantId(FlowableUtils.getTenantId()); if (StrUtil.isNotBlank(pageVO.getKey())) { modelQuery.modelKey(pageVO.getKey()); } @@ -78,7 +79,6 @@ public PageResult getModelPage(BpmModelPageReqVO pageVO) { return PageResult.empty(count); } List models = modelQuery - .modelTenantId(FlowableUtils.getTenantId()) .orderByCreateTime().desc() .listPage(PageUtils.getStart(pageVO), pageVO.getPageSize()); return new PageResult<>(models, count); diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java index b91bae3115..2794a4e507 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java @@ -119,7 +119,7 @@ public PageResult getTaskDonePage(Long userId, BpmTaskPage } if (ArrayUtil.isNotEmpty(pageVO.getCreateTime())) { taskQuery.taskCreatedAfter(DateUtils.of(pageVO.getCreateTime()[0])); - taskQuery.taskCreatedAfter(DateUtils.of(pageVO.getCreateTime()[1])); + taskQuery.taskCreatedBefore(DateUtils.of(pageVO.getCreateTime()[1])); } // 执行查询 long count = taskQuery.count(); @@ -141,7 +141,7 @@ public PageResult getTaskPage(Long userId, BpmTaskPageReqV } if (ArrayUtil.isNotEmpty(pageVO.getCreateTime())) { taskQuery.taskCreatedAfter(DateUtils.of(pageVO.getCreateTime()[0])); - taskQuery.taskCreatedAfter(DateUtils.of(pageVO.getCreateTime()[1])); + taskQuery.taskCreatedBefore(DateUtils.of(pageVO.getCreateTime()[1])); } // 执行查询 long count = taskQuery.count(); diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/DictTypeConstants.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/DictTypeConstants.java index e91aea886f..d7592c34c9 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/DictTypeConstants.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/DictTypeConstants.java @@ -18,8 +18,6 @@ public interface DictTypeConstants { String LOGIN_TYPE = "system_login_type"; // 登录日志的类型 String LOGIN_RESULT = "system_login_result"; // 登录结果 - String ERROR_CODE_TYPE = "system_error_code_type"; // 错误码的类型枚举 - String SMS_CHANNEL_CODE = "system_sms_channel_code"; // 短信渠道编码 String SMS_TEMPLATE_TYPE = "system_sms_template_type"; // 短信模板类型 String SMS_SEND_STATUS = "system_sms_send_status"; // 短信发送状态 diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImpl.java index 389f28b4f6..6203cd7d34 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImpl.java @@ -2,6 +2,7 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.extra.spring.SpringUtil; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; @@ -61,7 +62,7 @@ public Long createRole(RoleSaveReqVO createReqVO, Integer type) { // 2. 插入到数据库 RoleDO role = BeanUtils.toBean(createReqVO, RoleDO.class) .setType(ObjectUtil.defaultIfNull(type, RoleTypeEnum.CUSTOM.getType())) - .setStatus(CommonStatusEnum.ENABLE.getStatus()) + .setStatus(ObjUtil.defaultIfNull(createReqVO.getStatus(), CommonStatusEnum.ENABLE.getStatus())) .setDataScope(DataScopeEnum.ALL.getScope()); // 默认可查看所有数据。原因是,可能一些项目不需要项目权限 roleMapper.insert(role); diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImplTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImplTest.java index 51c1de6cab..922a16482e 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImplTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImplTest.java @@ -51,7 +51,8 @@ public class RoleServiceImplTest extends BaseDbUnitTest { public void testCreateRole() { // 准备参数 RoleSaveReqVO reqVO = randomPojo(RoleSaveReqVO.class) - .setId(null); // 防止 id 被赋值 + .setId(null) // 防止 id 被赋值 + .setStatus(randomCommonStatus()); // 调用 Long roleId = roleService.createRole(reqVO, null); @@ -59,7 +60,6 @@ public void testCreateRole() { RoleDO roleDO = roleMapper.selectById(roleId); assertPojoEquals(reqVO, roleDO, "id"); assertEquals(RoleTypeEnum.CUSTOM.getType(), roleDO.getType()); - assertEquals(CommonStatusEnum.ENABLE.getStatus(), roleDO.getStatus()); assertEquals(DataScopeEnum.ALL.getScope(), roleDO.getDataScope()); } @@ -70,7 +70,8 @@ public void testUpdateRole() { roleMapper.insert(roleDO); // 准备参数 Long id = roleDO.getId(); - RoleSaveReqVO reqVO = randomPojo(RoleSaveReqVO.class, o -> o.setId(id)); + RoleSaveReqVO reqVO = randomPojo(RoleSaveReqVO.class, o -> o.setId(id) + .setStatus(randomCommonStatus())); // 调用 roleService.updateRole(reqVO);