Commit 56ae4503a619dd52068c42ddcfae0dcf87a6cb91

Authored by YunaiV
1 parent 424922b4

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

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; @@ -7,6 +7,8 @@ import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration;
7 import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; 7 import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
8 import com.baomidou.mybatisplus.core.incrementer.IKeyGenerator; 8 import com.baomidou.mybatisplus.core.incrementer.IKeyGenerator;
9 import com.baomidou.mybatisplus.extension.incrementer.*; 9 import com.baomidou.mybatisplus.extension.incrementer.*;
  10 +import com.baomidou.mybatisplus.extension.parser.JsqlParserGlobal;
  11 +import com.baomidou.mybatisplus.extension.parser.cache.JdkSerialCaffeineJsqlParseCache;
10 import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; 12 import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
11 import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; 13 import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
12 import org.apache.ibatis.annotations.Mapper; 14 import org.apache.ibatis.annotations.Mapper;
@@ -16,6 +18,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -16,6 +18,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
16 import org.springframework.context.annotation.Bean; 18 import org.springframework.context.annotation.Bean;
17 import org.springframework.core.env.ConfigurableEnvironment; 19 import org.springframework.core.env.ConfigurableEnvironment;
18 20
  21 +import java.util.concurrent.TimeUnit;
  22 +
19 /** 23 /**
20 * MyBaits 配置类 24 * MyBaits 配置类
21 * 25 *
@@ -26,6 +30,14 @@ import org.springframework.core.env.ConfigurableEnvironment; @@ -26,6 +30,14 @@ import org.springframework.core.env.ConfigurableEnvironment;
26 lazyInitialization = "${mybatis.lazy-initialization:false}") // Mapper 懒加载,目前仅用于单元测试 30 lazyInitialization = "${mybatis.lazy-initialization:false}") // Mapper 懒加载,目前仅用于单元测试
27 public class YudaoMybatisAutoConfiguration { 31 public class YudaoMybatisAutoConfiguration {
28 32
  33 + static {
  34 + // 动态 SQL 智能优化支持本地缓存加速解析,更完善的租户复杂 XML 动态 SQL 支持,静态注入缓存
  35 + JsqlParserGlobal.setJsqlParseCache(new JdkSerialCaffeineJsqlParseCache(
  36 + (cache) -> cache.maximumSize(1024)
  37 + .expireAfterWrite(5, TimeUnit.SECONDS))
  38 + );
  39 + }
  40 +
29 @Bean 41 @Bean
30 public MybatisPlusInterceptor mybatisPlusInterceptor() { 42 public MybatisPlusInterceptor mybatisPlusInterceptor() {
31 MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor(); 43 MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
@@ -34,7 +46,7 @@ public class YudaoMybatisAutoConfiguration { @@ -34,7 +46,7 @@ public class YudaoMybatisAutoConfiguration {
34 } 46 }
35 47
36 @Bean 48 @Bean
37 - public MetaObjectHandler defaultMetaObjectHandler(){ 49 + public MetaObjectHandler defaultMetaObjectHandler() {
38 return new DefaultDBFieldHandler(); // 自动填充参数类 50 return new DefaultDBFieldHandler(); // 自动填充参数类
39 } 51 }
40 52
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 { @@ -69,7 +69,7 @@ public class ApiSignatureAspect {
69 69
70 // 3. 将 nonce 记入缓存,防止重复使用(重点二:此处需要将 ttl 设定为允许 timestamp 时间差的值 x 2 ) 70 // 3. 将 nonce 记入缓存,防止重复使用(重点二:此处需要将 ttl 设定为允许 timestamp 时间差的值 x 2 )
71 String nonce = request.getHeader(signature.nonce()); 71 String nonce = request.getHeader(signature.nonce());
72 - signatureRedisDAO.setNonce(nonce, signature.timeout() * 2, signature.timeUnit()); 72 + signatureRedisDAO.setNonce(appId, nonce, signature.timeout() * 2, signature.timeUnit());
73 return true; 73 return true;
74 } 74 }
75 75
@@ -113,7 +113,7 @@ public class ApiSignatureAspect { @@ -113,7 +113,7 @@ public class ApiSignatureAspect {
113 } 113 }
114 114
115 // 3. 检查 nonce 是否存在,有且仅能使用一次 115 // 3. 检查 nonce 是否存在,有且仅能使用一次
116 - return signatureRedisDAO.getNonce(nonce) == null; 116 + return signatureRedisDAO.getNonce(appId, nonce) == null;
117 } 117 }
118 118
119 /** 119 /**
@@ -165,5 +165,4 @@ public class ApiSignatureAspect { @@ -165,5 +165,4 @@ public class ApiSignatureAspect {
165 return sortedMap; 165 return sortedMap;
166 } 166 }
167 167
168 -}  
169 - 168 +}
170 \ No newline at end of file 169 \ No newline at end of file
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 { @@ -22,7 +22,7 @@ public class ApiSignatureRedisDAO {
22 * VALUE 格式:String 22 * VALUE 格式:String
23 * 过期时间:不固定 23 * 过期时间:不固定
24 */ 24 */
25 - private static final String SIGNATURE_NONCE = "api_signature_nonce:%s"; 25 + private static final String SIGNATURE_NONCE = "api_signature_nonce:%s:%s";
26 26
27 /** 27 /**
28 * 签名密钥 28 * 签名密钥
@@ -36,16 +36,16 @@ public class ApiSignatureRedisDAO { @@ -36,16 +36,16 @@ public class ApiSignatureRedisDAO {
36 36
37 // ========== 验签随机数 ========== 37 // ========== 验签随机数 ==========
38 38
39 - public String getNonce(String nonce) {  
40 - return stringRedisTemplate.opsForValue().get(formatNonceKey(nonce)); 39 + public String getNonce(String appId, String nonce) {
  40 + return stringRedisTemplate.opsForValue().get(formatNonceKey(appId, nonce));
41 } 41 }
42 42
43 - public void setNonce(String nonce, int time, TimeUnit timeUnit) {  
44 - stringRedisTemplate.opsForValue().set(formatNonceKey(nonce), "", time, timeUnit); 43 + public void setNonce(String appId, String nonce, int time, TimeUnit timeUnit) {
  44 + stringRedisTemplate.opsForValue().set(formatNonceKey(appId, nonce), "", time, timeUnit);
45 } 45 }
46 46
47 - private static String formatNonceKey(String key) {  
48 - return String.format(SIGNATURE_NONCE, key); 47 + private static String formatNonceKey(String appId, String nonce) {
  48 + return String.format(SIGNATURE_NONCE, appId, nonce);
49 } 49 }
50 50
51 // ========== 签名密钥 ========== 51 // ========== 签名密钥 ==========
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 { @@ -69,7 +69,7 @@ public class ApiSignatureTest {
69 // 断言结果 69 // 断言结果
70 assertTrue(result); 70 assertTrue(result);
71 // 断言调用 71 // 断言调用
72 - verify(signatureRedisDAO).setNonce(eq(nonce), eq(120), eq(TimeUnit.SECONDS)); 72 + verify(signatureRedisDAO).setNonce(eq(appId), eq(nonce), eq(120), eq(TimeUnit.SECONDS));
73 } 73 }
74 74
75 -} 75 -}
  76 +}
76 \ No newline at end of file 77 \ No newline at end of file
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; @@ -11,6 +11,7 @@ import com.mzt.logapi.service.ILogRecordService;
11 import jakarta.annotation.Resource; 11 import jakarta.annotation.Resource;
12 import jakarta.servlet.http.HttpServletRequest; 12 import jakarta.servlet.http.HttpServletRequest;
13 import lombok.extern.slf4j.Slf4j; 13 import lombok.extern.slf4j.Slf4j;
  14 +import org.springframework.scheduling.annotation.Async;
14 15
15 import java.util.List; 16 import java.util.List;
16 17
@@ -28,19 +29,24 @@ public class LogRecordServiceImpl implements ILogRecordService { @@ -28,19 +29,24 @@ public class LogRecordServiceImpl implements ILogRecordService {
28 private OperateLogApi operateLogApi; 29 private OperateLogApi operateLogApi;
29 30
30 @Override 31 @Override
  32 + @Async
31 public void record(LogRecord logRecord) { 33 public void record(LogRecord logRecord) {
32 - // 1. 补全通用字段  
33 OperateLogCreateReqDTO reqDTO = new OperateLogCreateReqDTO(); 34 OperateLogCreateReqDTO reqDTO = new OperateLogCreateReqDTO();
34 - reqDTO.setTraceId(TracerUtils.getTraceId());  
35 - // 补充用户信息  
36 - fillUserFields(reqDTO);  
37 - // 补全模块信息  
38 - fillModuleFields(reqDTO, logRecord);  
39 - // 补全请求信息  
40 - fillRequestFields(reqDTO); 35 + try {
  36 + reqDTO.setTraceId(TracerUtils.getTraceId());
  37 + // 补充用户信息
  38 + fillUserFields(reqDTO);
  39 + // 补全模块信息
  40 + fillModuleFields(reqDTO, logRecord);
  41 + // 补全请求信息
  42 + fillRequestFields(reqDTO);
41 43
42 - // 2. 异步记录日志  
43 - operateLogApi.createOperateLog(reqDTO); 44 + // 2. 异步记录日志
  45 + operateLogApi.createOperateLog(reqDTO);
  46 + } catch (Throwable ex) {
  47 + // 由于 @Async 异步调用,这里打印下日志,更容易跟进
  48 + log.error("[record][url({}) log({}) 发生异常]", reqDTO.getRequestUrl(), reqDTO, ex);
  49 + }
44 } 50 }
45 51
46 private static void fillUserFields(OperateLogCreateReqDTO reqDTO) { 52 private static void fillUserFields(OperateLogCreateReqDTO reqDTO) {
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 { @@ -63,6 +63,7 @@ public class BpmModelServiceImpl implements BpmModelService {
63 @Override 63 @Override
64 public PageResult<Model> getModelPage(BpmModelPageReqVO pageVO) { 64 public PageResult<Model> getModelPage(BpmModelPageReqVO pageVO) {
65 ModelQuery modelQuery = repositoryService.createModelQuery(); 65 ModelQuery modelQuery = repositoryService.createModelQuery();
  66 + modelQuery.modelTenantId(FlowableUtils.getTenantId());
66 if (StrUtil.isNotBlank(pageVO.getKey())) { 67 if (StrUtil.isNotBlank(pageVO.getKey())) {
67 modelQuery.modelKey(pageVO.getKey()); 68 modelQuery.modelKey(pageVO.getKey());
68 } 69 }
@@ -78,7 +79,6 @@ public class BpmModelServiceImpl implements BpmModelService { @@ -78,7 +79,6 @@ public class BpmModelServiceImpl implements BpmModelService {
78 return PageResult.empty(count); 79 return PageResult.empty(count);
79 } 80 }
80 List<Model> models = modelQuery 81 List<Model> models = modelQuery
81 - .modelTenantId(FlowableUtils.getTenantId())  
82 .orderByCreateTime().desc() 82 .orderByCreateTime().desc()
83 .listPage(PageUtils.getStart(pageVO), pageVO.getPageSize()); 83 .listPage(PageUtils.getStart(pageVO), pageVO.getPageSize());
84 return new PageResult<>(models, count); 84 return new PageResult<>(models, count);
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 { @@ -97,7 +97,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
97 } 97 }
98 if (ArrayUtil.isNotEmpty(pageVO.getCreateTime())) { 98 if (ArrayUtil.isNotEmpty(pageVO.getCreateTime())) {
99 taskQuery.taskCreatedAfter(DateUtils.of(pageVO.getCreateTime()[0])); 99 taskQuery.taskCreatedAfter(DateUtils.of(pageVO.getCreateTime()[0]));
100 - taskQuery.taskCreatedAfter(DateUtils.of(pageVO.getCreateTime()[1])); 100 + taskQuery.taskCreatedBefore(DateUtils.of(pageVO.getCreateTime()[1]));
101 } 101 }
102 long count = taskQuery.count(); 102 long count = taskQuery.count();
103 if (count == 0) { 103 if (count == 0) {
@@ -119,7 +119,7 @@ public class BpmTaskServiceImpl implements BpmTaskService { @@ -119,7 +119,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
119 } 119 }
120 if (ArrayUtil.isNotEmpty(pageVO.getCreateTime())) { 120 if (ArrayUtil.isNotEmpty(pageVO.getCreateTime())) {
121 taskQuery.taskCreatedAfter(DateUtils.of(pageVO.getCreateTime()[0])); 121 taskQuery.taskCreatedAfter(DateUtils.of(pageVO.getCreateTime()[0]));
122 - taskQuery.taskCreatedAfter(DateUtils.of(pageVO.getCreateTime()[1])); 122 + taskQuery.taskCreatedBefore(DateUtils.of(pageVO.getCreateTime()[1]));
123 } 123 }
124 // 执行查询 124 // 执行查询
125 long count = taskQuery.count(); 125 long count = taskQuery.count();
@@ -141,7 +141,7 @@ public class BpmTaskServiceImpl implements BpmTaskService { @@ -141,7 +141,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
141 } 141 }
142 if (ArrayUtil.isNotEmpty(pageVO.getCreateTime())) { 142 if (ArrayUtil.isNotEmpty(pageVO.getCreateTime())) {
143 taskQuery.taskCreatedAfter(DateUtils.of(pageVO.getCreateTime()[0])); 143 taskQuery.taskCreatedAfter(DateUtils.of(pageVO.getCreateTime()[0]));
144 - taskQuery.taskCreatedAfter(DateUtils.of(pageVO.getCreateTime()[1])); 144 + taskQuery.taskCreatedBefore(DateUtils.of(pageVO.getCreateTime()[1]));
145 } 145 }
146 // 执行查询 146 // 执行查询
147 long count = taskQuery.count(); 147 long count = taskQuery.count();