Browse Source

【代码优化】SYSTEM:操作日志,增加异步记录

YunaiV 6 months ago
parent
commit
56ae4503a6

+ 13 - 1
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.autoconfigure.MybatisPlusAutoConfiguration;
 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.boot.autoconfigure.condition.ConditionalOnProperty;
 import org.springframework.context.annotation.Bean;
 import org.springframework.core.env.ConfigurableEnvironment;
 
+import java.util.concurrent.TimeUnit;
+
 /**
  * MyBaits 配置类
  *
@@ -26,6 +30,14 @@ import org.springframework.core.env.ConfigurableEnvironment;
         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 class YudaoMybatisAutoConfiguration {
     }
 
     @Bean
-    public MetaObjectHandler defaultMetaObjectHandler(){
+    public MetaObjectHandler defaultMetaObjectHandler() {
         return new DefaultDBFieldHandler(); // 自动填充参数类
     }
 

+ 3 - 4
yudao-framework/yudao-spring-boot-starter-protection/src/main/java/cn/iocoder/yudao/framework/signature/core/aop/ApiSignatureAspect.java

@@ -69,7 +69,7 @@ public class ApiSignatureAspect {
 
         // 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 @@ public class ApiSignatureAspect {
         }
 
         // 3. 检查 nonce 是否存在,有且仅能使用一次
-        return signatureRedisDAO.getNonce(nonce) == null;
+        return signatureRedisDAO.getNonce(appId, nonce) == null;
     }
 
     /**
@@ -165,5 +165,4 @@ public class ApiSignatureAspect {
         return sortedMap;
     }
 
-}
-
+}

+ 7 - 7
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);
     }
 
     // ========== 签名密钥 ==========

+ 2 - 2
yudao-framework/yudao-spring-boot-starter-protection/src/test/java/cn/iocoder/yudao/framework/signature/core/ApiSignatureTest.java

@@ -69,7 +69,7 @@ public class ApiSignatureTest {
         // 断言结果
         assertTrue(result);
         // 断言调用
-        verify(signatureRedisDAO).setNonce(eq(nonce), eq(120), eq(TimeUnit.SECONDS));
+        verify(signatureRedisDAO).setNonce(eq(appId), eq(nonce), eq(120), eq(TimeUnit.SECONDS));
     }
 
-}
+}

+ 16 - 10
yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/operatelog/core/service/LogRecordServiceImpl.java

@@ -11,6 +11,7 @@ import com.mzt.logapi.service.ILogRecordService;
 import jakarta.annotation.Resource;
 import jakarta.servlet.http.HttpServletRequest;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.scheduling.annotation.Async;
 
 import java.util.List;
 
@@ -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);
+        } catch (Throwable ex) {
+            // 由于 @Async 异步调用,这里打印下日志,更容易跟进
+            log.error("[record][url({}) log({}) 发生异常]", reqDTO.getRequestUrl(), reqDTO, ex);
+        }
     }
 
     private static void fillUserFields(OperateLogCreateReqDTO reqDTO) {

+ 1 - 1
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<Model> 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 class BpmModelServiceImpl implements BpmModelService {
             return PageResult.empty(count);
         }
         List<Model> models = modelQuery
-                .modelTenantId(FlowableUtils.getTenantId())
                 .orderByCreateTime().desc()
                 .listPage(PageUtils.getStart(pageVO), pageVO.getPageSize());
         return new PageResult<>(models, count);

+ 3 - 3
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java

@@ -97,7 +97,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
         }
         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();
         if (count == 0) {
@@ -119,7 +119,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
         }
         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 class BpmTaskServiceImpl implements BpmTaskService {
         }
         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();