ai-engineering-init 1.7.0 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/.claude/hooks/skill-forced-eval.js +46 -62
  2. package/.claude/settings.json +10 -1
  3. package/.claude/skills/api-development/SKILL.md +179 -130
  4. package/.claude/skills/architecture-design/SKILL.md +102 -212
  5. package/.claude/skills/backend-annotations/SKILL.md +166 -220
  6. package/.claude/skills/bug-detective/SKILL.md +225 -186
  7. package/.claude/skills/code-patterns/SKILL.md +127 -244
  8. package/.claude/skills/collaborating-with-codex/SKILL.md +96 -113
  9. package/.claude/skills/crud-development/SKILL.md +226 -307
  10. package/.claude/skills/data-permission/SKILL.md +131 -202
  11. package/.claude/skills/database-ops/SKILL.md +158 -355
  12. package/.claude/skills/error-handler/SKILL.md +224 -285
  13. package/.claude/skills/file-oss-management/SKILL.md +174 -169
  14. package/.claude/skills/git-workflow/SKILL.md +123 -341
  15. package/.claude/skills/json-serialization/SKILL.md +121 -137
  16. package/.claude/skills/performance-doctor/SKILL.md +83 -89
  17. package/.claude/skills/redis-cache/SKILL.md +134 -185
  18. package/.claude/skills/scheduled-jobs/SKILL.md +187 -224
  19. package/.claude/skills/security-guard/SKILL.md +168 -276
  20. package/.claude/skills/sms-mail/SKILL.md +266 -228
  21. package/.claude/skills/social-login/SKILL.md +257 -195
  22. package/.claude/skills/tenant-management/SKILL.md +172 -188
  23. package/.claude/skills/utils-toolkit/SKILL.md +214 -222
  24. package/.claude/skills/websocket-sse/SKILL.md +251 -172
  25. package/.claude/skills/workflow-engine/SKILL.md +178 -250
  26. package/.codex/skills/api-development/SKILL.md +179 -130
  27. package/.codex/skills/architecture-design/SKILL.md +102 -212
  28. package/.codex/skills/backend-annotations/SKILL.md +166 -220
  29. package/.codex/skills/bug-detective/SKILL.md +225 -186
  30. package/.codex/skills/code-patterns/SKILL.md +127 -244
  31. package/.codex/skills/collaborating-with-codex/SKILL.md +96 -113
  32. package/.codex/skills/crud-development/SKILL.md +226 -307
  33. package/.codex/skills/data-permission/SKILL.md +131 -202
  34. package/.codex/skills/database-ops/SKILL.md +158 -355
  35. package/.codex/skills/error-handler/SKILL.md +224 -285
  36. package/.codex/skills/file-oss-management/SKILL.md +174 -169
  37. package/.codex/skills/git-workflow/SKILL.md +123 -341
  38. package/.codex/skills/json-serialization/SKILL.md +121 -137
  39. package/.codex/skills/performance-doctor/SKILL.md +83 -89
  40. package/.codex/skills/redis-cache/SKILL.md +134 -185
  41. package/.codex/skills/scheduled-jobs/SKILL.md +187 -224
  42. package/.codex/skills/security-guard/SKILL.md +168 -276
  43. package/.codex/skills/sms-mail/SKILL.md +266 -228
  44. package/.codex/skills/social-login/SKILL.md +257 -195
  45. package/.codex/skills/tenant-management/SKILL.md +172 -188
  46. package/.codex/skills/utils-toolkit/SKILL.md +214 -222
  47. package/.codex/skills/websocket-sse/SKILL.md +251 -172
  48. package/.codex/skills/workflow-engine/SKILL.md +178 -250
  49. package/.cursor/hooks/cursor-skill-eval.js +66 -6
  50. package/.cursor/skills/api-development/SKILL.md +179 -130
  51. package/.cursor/skills/architecture-design/SKILL.md +102 -212
  52. package/.cursor/skills/backend-annotations/SKILL.md +166 -220
  53. package/.cursor/skills/bug-detective/SKILL.md +225 -186
  54. package/.cursor/skills/code-patterns/SKILL.md +127 -244
  55. package/.cursor/skills/collaborating-with-codex/SKILL.md +96 -113
  56. package/.cursor/skills/crud-development/SKILL.md +226 -307
  57. package/.cursor/skills/data-permission/SKILL.md +131 -202
  58. package/.cursor/skills/database-ops/SKILL.md +158 -355
  59. package/.cursor/skills/error-handler/SKILL.md +224 -285
  60. package/.cursor/skills/file-oss-management/SKILL.md +174 -169
  61. package/.cursor/skills/git-workflow/SKILL.md +123 -341
  62. package/.cursor/skills/json-serialization/SKILL.md +121 -137
  63. package/.cursor/skills/performance-doctor/SKILL.md +83 -89
  64. package/.cursor/skills/redis-cache/SKILL.md +134 -185
  65. package/.cursor/skills/scheduled-jobs/SKILL.md +187 -224
  66. package/.cursor/skills/security-guard/SKILL.md +168 -276
  67. package/.cursor/skills/sms-mail/SKILL.md +266 -228
  68. package/.cursor/skills/social-login/SKILL.md +257 -195
  69. package/.cursor/skills/tenant-management/SKILL.md +172 -188
  70. package/.cursor/skills/utils-toolkit/SKILL.md +214 -222
  71. package/.cursor/skills/websocket-sse/SKILL.md +251 -172
  72. package/.cursor/skills/workflow-engine/SKILL.md +178 -250
  73. package/AGENTS.md +49 -540
  74. package/CLAUDE.md +73 -119
  75. package/README.md +37 -6
  76. package/bin/index.js +5 -1
  77. package/package.json +1 -1
  78. package/src/skills/api-development/SKILL.md +179 -130
  79. package/src/skills/architecture-design/SKILL.md +102 -212
  80. package/src/skills/backend-annotations/SKILL.md +166 -220
  81. package/src/skills/bug-detective/SKILL.md +225 -186
  82. package/src/skills/code-patterns/SKILL.md +127 -244
  83. package/src/skills/collaborating-with-codex/SKILL.md +96 -113
  84. package/src/skills/crud-development/SKILL.md +226 -307
  85. package/src/skills/data-permission/SKILL.md +131 -202
  86. package/src/skills/database-ops/SKILL.md +158 -355
  87. package/src/skills/error-handler/SKILL.md +224 -285
  88. package/src/skills/file-oss-management/SKILL.md +174 -169
  89. package/src/skills/git-workflow/SKILL.md +123 -341
  90. package/src/skills/json-serialization/SKILL.md +121 -137
  91. package/src/skills/performance-doctor/SKILL.md +83 -89
  92. package/src/skills/redis-cache/SKILL.md +134 -185
  93. package/src/skills/scheduled-jobs/SKILL.md +187 -224
  94. package/src/skills/security-guard/SKILL.md +168 -276
  95. package/src/skills/sms-mail/SKILL.md +266 -228
  96. package/src/skills/social-login/SKILL.md +257 -195
  97. package/src/skills/tenant-management/SKILL.md +172 -188
  98. package/src/skills/utils-toolkit/SKILL.md +214 -222
  99. package/src/skills/websocket-sse/SKILL.md +251 -172
  100. package/src/skills/workflow-engine/SKILL.md +178 -250
  101. package/.claude/skills/skill-creator/LICENSE.txt +0 -202
  102. package/.claude/skills/skill-creator/SKILL.md +0 -479
  103. package/.claude/skills/skill-creator/agents/analyzer.md +0 -274
  104. package/.claude/skills/skill-creator/agents/comparator.md +0 -202
  105. package/.claude/skills/skill-creator/agents/grader.md +0 -223
  106. package/.claude/skills/skill-creator/assets/eval_review.html +0 -146
  107. package/.claude/skills/skill-creator/eval-viewer/generate_review.py +0 -471
  108. package/.claude/skills/skill-creator/eval-viewer/viewer.html +0 -1325
  109. package/.claude/skills/skill-creator/references/schemas.md +0 -430
  110. package/.claude/skills/skill-creator/scripts/__init__.py +0 -0
  111. package/.claude/skills/skill-creator/scripts/aggregate_benchmark.py +0 -401
  112. package/.claude/skills/skill-creator/scripts/generate_report.py +0 -326
  113. package/.claude/skills/skill-creator/scripts/improve_description.py +0 -248
  114. package/.claude/skills/skill-creator/scripts/package_skill.py +0 -136
  115. package/.claude/skills/skill-creator/scripts/quick_validate.py +0 -103
  116. package/.claude/skills/skill-creator/scripts/run_eval.py +0 -310
  117. package/.claude/skills/skill-creator/scripts/run_loop.py +0 -332
  118. package/.claude/skills/skill-creator/scripts/utils.py +0 -47
@@ -1,302 +1,248 @@
1
1
  ---
2
2
  name: backend-annotations
3
3
  description: |
4
- 后端高级注解使用指南。包含 @RateLimiter、@RepeatSubmit、@Sensitive、@EncryptField、@ApiEncrypt、@DataPermission 等注解的用法。
5
-
4
+ 通用后端高级注解指南。包含限流、防重复提交、数据脱敏、字段加密、接口加密等横切关注点的 AOP 实现模式。
6
5
  触发场景:
7
- - 配置接口限流(@RateLimiter)
8
- - 配置防重复提交(@RepeatSubmit)
9
- - 配置数据脱敏(@Sensitive)
10
- - 配置字段加密(@EncryptField)
11
- - 配置接口加密(@ApiEncrypt)
12
- - 配置数据权限注解(@DataPermission)
13
-
14
- 触发词:注解、@RateLimiter、@RepeatSubmit、@Sensitive、@EncryptField、@ApiEncrypt、@DataPermission、@DataColumn、限流、防重复、脱敏、加密、数据权限注解
6
+ - 配置接口限流
7
+ - 配置防重复提交
8
+ - 配置数据脱敏
9
+ - 配置字段加密 / 接口加密
10
+ 触发词:注解、限流、防重复提交、脱敏、加密、RateLimiter、Idempotent、Sensitive、Encrypt、AOP
11
+ 注意:如果项目有专属技能(如 `leniu-backend-annotations`),优先使用专属版本。
15
12
  ---
16
13
 
17
- # 后端高级注解指南
14
+ # 后端高级注解开发指南
18
15
 
19
- > RuoYi-Vue-Plus 三层架构,包名 `org.dromara.*`
16
+ > 通用模板。如果项目有专属技能(如 `leniu-backend-annotations`),优先使用。
20
17
 
21
- ## 注解总览
18
+ ## 设计原则
22
19
 
23
- | 注解 | 机制 | 作用层 | 依赖 |
24
- |------|------|--------|------|
25
- | `@RateLimiter` | AOP | Controller 方法 | Redis |
26
- | `@RepeatSubmit` | AOP | Controller 方法 | Redis + Token |
27
- | `@Sensitive` | Jackson 序列化器 | VO 字段 | 无 |
28
- | `@EncryptField` | MyBatis 拦截器 | Entity 字段 | 无 |
29
- | `@ApiEncrypt` | 拦截器 | Controller 方法 | 无 |
30
- | `@DataPermission` | AOP | Mapper 接口 | MyBatis |
20
+ 1. **横切关注点用 AOP**:限流、防重复、脱敏、加密属于非功能性需求,应通过注解 + AOP/拦截器实现,不侵入业务代码。
21
+ 2. **分层职责清晰**:限流/防重复作用于 Controller 层;脱敏作用于 VO 序列化层;加密作用于持久化层。
22
+ 3. **声明式优于编程式**:用注解声明意图,框架自动执行,减少样板代码。
23
+ 4. **配置外置**:密钥、阈值等参数放在配置文件或配置中心,不硬编码。
31
24
 
32
25
  ---
33
26
 
34
- ## 1. @RateLimiter - 接口限流
27
+ ## 实现模式
35
28
 
36
- **导入**:`org.dromara.common.ratelimiter.annotation.RateLimiter`
29
+ ### 1. 接口限流
37
30
 
38
- | 参数 | 类型 | 默认值 | 说明 |
39
- |------|------|--------|------|
40
- | `key` | String | "" | 限流key,支持SpEL |
41
- | `time` | int | 60 | 时间窗口(秒) |
42
- | `count` | int | 100 | 最大请求次数 |
43
- | `limitType` | LimitType | DEFAULT | DEFAULT/IP/CLUSTER |
44
- | `message` | String | 国际化key | 错误提示 |
31
+ **概念**:通过 AOP 拦截请求,基于 Redis/内存计数器控制单位时间内的请求次数。
45
32
 
46
33
  ```java
47
- // 全局限流:60秒100次
48
- @RateLimiter(time = 60, count = 100)
49
- @GetMapping("/list")
50
- public R<List<XxxVo>> list() { }
51
-
52
- // IP限流:每个IP每分钟10次(登录、验证码)
53
- @RateLimiter(time = 60, count = 10, limitType = LimitType.IP)
54
- @PostMapping("/login")
55
- public R<String> login() { }
56
-
57
- // 动态key:基于用户ID限流
58
- @RateLimiter(key = "#userId", time = 60, count = 5)
59
- @PostMapping("/submit")
60
- public R<Void> submit(Long userId) { }
34
+ // 自定义注解
35
+ @Target(ElementType.METHOD)
36
+ @Retention(RetentionPolicy.RUNTIME)
37
+ public @interface RateLimiter {
38
+ String key() default ""; // 限流key,支持 SpEL
39
+ int time() default 60; // 时间窗口(秒)
40
+ int count() default 100; // 最大请求次数
41
+ LimitType limitType() default LimitType.DEFAULT; // DEFAULT / IP / CLUSTER
42
+ String message() default "请求过于频繁";
43
+ }
44
+
45
+ // AOP 切面
46
+ @Aspect
47
+ @Component
48
+ public class RateLimiterAspect {
49
+
50
+ @Autowired
51
+ private StringRedisTemplate redisTemplate;
52
+
53
+ @Around("@annotation([你的包名].annotation.RateLimiter)")
54
+ public Object around(ProceedingJoinPoint point) throws Throwable {
55
+ RateLimiter limiter = /* 获取注解 */;
56
+ String key = buildKey(limiter, point);
57
+ // 使用 Redis Lua 脚本做原子计数
58
+ Long count = redisTemplate.execute(rateLimiterScript, List.of(key),
59
+ String.valueOf(limiter.count()), String.valueOf(limiter.time()));
60
+ if (count != null && count > limiter.count()) {
61
+ throw new [你的异常类](limiter.message());
62
+ }
63
+ return point.proceed();
64
+ }
65
+ }
61
66
  ```
62
67
 
63
- ---
68
+ **推荐阈值参考**:
64
69
 
65
- ## 2. @RepeatSubmit - 防重复提交
70
+ | 场景 | 时间窗口 | 次数 | 限流类型 |
71
+ |------|---------|------|---------|
72
+ | 登录接口 | 60s | 5-10 | IP |
73
+ | 验证码 | 60s | 3 | IP |
74
+ | 查询接口 | 60s | 100-1000 | DEFAULT |
75
+ | 写入接口 | 60s | 10-50 | DEFAULT |
76
+ | 敏感操作 | 60s | 1-5 | IP |
77
+
78
+ ---
66
79
 
67
- **导入**:`org.dromara.common.idempotent.annotation.RepeatSubmit`
80
+ ### 2. 防重复提交
68
81
 
69
- | 参数 | 类型 | 默认值 | 说明 |
70
- |------|------|--------|------|
71
- | `interval` | int | 5000 | 间隔时间(毫秒) |
72
- | `timeUnit` | TimeUnit | MILLISECONDS | 时间单位 |
73
- | `message` | String | 国际化key | 错误提示 |
82
+ **概念**:在指定时间窗口内,相同用户的相同请求(基于 Token + 参数哈希)只允许提交一次。
74
83
 
75
84
  ```java
76
- // 默认5秒
77
- @RepeatSubmit()
78
- @PostMapping()
79
- public R<Long> add(@RequestBody OrderBo bo) { }
85
+ @Target(ElementType.METHOD)
86
+ @Retention(RetentionPolicy.RUNTIME)
87
+ public @interface RepeatSubmit {
88
+ int interval() default 5000; // 间隔时间(毫秒)
89
+ TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
90
+ String message() default "请勿重复提交";
91
+ }
80
92
 
81
- // 10秒间隔 + 自定义提示
82
- @RepeatSubmit(interval = 10, timeUnit = TimeUnit.SECONDS, message = "请勿重复提交")
83
- @PostMapping("/pay")
84
- public R<Void> pay(@RequestBody PayBo bo) { }
93
+ // AOP 切面核心逻辑
94
+ // 1. 从请求中提取 Token + 请求参数
95
+ // 2. 计算 MD5(token + ":" + serialize(params))
96
+ // 3. Redis SETNX,设置过期时间 = interval
97
+ // 4. 设置成功 -> 允许请求;设置失败 -> 拒绝
98
+ // 5. 请求异常时删除 key,允许重试
85
99
  ```
86
100
 
87
- **原理**:`MD5(token + ":" + 序列化参数)` -> Redis 设置/检查 -> 成功保留key防重复 -> 异常删除key允许重试。
101
+ | 场景 | 推荐间隔 |
102
+ |------|---------|
103
+ | 普通表单 | 3-5 秒 |
104
+ | 订单创建 | 10 秒 |
105
+ | 支付操作 | 30 秒 |
106
+ | 文件上传 | 10 秒 |
88
107
 
89
108
  ---
90
109
 
91
- ## 3. @Sensitive - 数据脱敏
110
+ ### 3. 数据脱敏
92
111
 
93
- **导入**:`org.dromara.common.sensitive.annotation.Sensitive`
112
+ **概念**:在 JSON 序列化阶段,对 VO 中的敏感字段进行掩码处理。通过自定义 Jackson 序列化器实现。
94
113
 
95
- ### 脱敏策略
114
+ ```java
115
+ @Target(ElementType.FIELD)
116
+ @Retention(RetentionPolicy.RUNTIME)
117
+ @JacksonAnnotationsInside
118
+ @JsonSerialize(using = SensitiveSerializer.class)
119
+ public @interface Sensitive {
120
+ SensitiveStrategy strategy();
121
+ String[] roleKey() default {}; // 拥有这些角色可查看原文
122
+ String[] perms() default {}; // 拥有这些权限可查看原文
123
+ }
96
124
 
97
- | 策略 | 效果 | 策略 | 效果 |
98
- |------|------|------|------|
99
- | `ID_CARD` | 110\*\*\*5431 | `PHONE` | 176\*\*\*\*5371 |
100
- | `EMAIL` | t\*\*@example.com | `BANK_CARD` | 6222\*\*\*2853 |
101
- | `CHINESE_NAME` | 张\* | `ADDRESS` | 北京市朝阳区\*\*\*\* |
102
- | `PASSWORD` | \*\*\*\*\*\* | `IPV4` | 192.\*.\*.\* |
103
- | `FIRST_MASK` | a\*\*\*\*\* | `CLEAR` | "" |
125
+ public enum SensitiveStrategy {
126
+ ID_CARD(s -> s.substring(0, 3) + "***" + s.substring(s.length() - 4)),
127
+ PHONE(s -> s.substring(0, 3) + "****" + s.substring(s.length() - 4)),
128
+ EMAIL(s -> s.charAt(0) + "**@" + s.substring(s.indexOf('@') + 1)),
129
+ CHINESE_NAME(s -> s.charAt(0) + "*".repeat(s.length() - 1)),
130
+ BANK_CARD(s -> s.substring(0, 4) + "****" + s.substring(s.length() - 4)),
131
+ PASSWORD(s -> "******");
104
132
 
105
- ```java
133
+ private final Function<String, String> desensitizer;
134
+ // constructor, getter...
135
+ }
136
+
137
+ // 使用
106
138
  public class UserVo {
107
- // 所有人看脱敏数据
108
139
  @Sensitive(strategy = SensitiveStrategy.PHONE)
109
140
  private String phone;
110
141
 
111
- // admin 角色可查看原数据
112
142
  @Sensitive(strategy = SensitiveStrategy.ID_CARD, roleKey = {"admin"})
113
143
  private String idCard;
114
-
115
- // 需要权限才能看原数据
116
- @Sensitive(strategy = SensitiveStrategy.EMAIL, perms = {"system:user:detail"})
117
- private String email;
118
144
  }
119
145
  ```
120
146
 
121
- **权限逻辑**:roleKey 和 perms 都为空 = 全部脱敏;满足任一 roleKey **或** 任一 perms = 可查看原数据(OR 关系)。
147
+ **权限逻辑**:roleKey 和 perms 都为空 = 全部脱敏;满足任一条件 = 可查看原文(OR 关系)。
122
148
 
123
149
  ---
124
150
 
125
- ## 4. @EncryptField - 字段加密
126
-
127
- **导入**:`org.dromara.common.encrypt.annotation.EncryptField`
151
+ ### 4. 字段加密(持久层)
128
152
 
129
- | 算法 | 说明 | 算法 | 说明 |
130
- |------|------|------|------|
131
- | `BASE64` | 编码(低安全) | `AES` | 对称加密(推荐) |
132
- | `RSA` | 非对称(高安全) | `SM2` | 国密非对称 |
133
- | `SM4` | 国密对称 | | |
153
+ **概念**:通过 MyBatis 拦截器/TypeHandler,在数据写入数据库时自动加密,读取时自动解密。对业务代码透明。
134
154
 
135
155
  ```java
136
- @Data
137
- @TableName("test_demo")
138
- public class TestDemo extends BaseEntity {
139
- // AES 加密(使用 yml 全局秘钥)
140
- @EncryptField(algorithm = AlgorithmType.AES)
141
- private String phone;
142
-
143
- // RSA 加密(指定公私钥)
144
- @EncryptField(algorithm = AlgorithmType.RSA,
145
- privateKey = "MIICdQ...", publicKey = "MFkwEw...")
146
- private String idCard;
147
-
148
- // 使用 yml 默认配置
149
- @EncryptField
150
- private String secretField;
156
+ @Target(ElementType.FIELD)
157
+ @Retention(RetentionPolicy.RUNTIME)
158
+ public @interface EncryptField {
159
+ AlgorithmType algorithm() default AlgorithmType.DEFAULT; // 使用全局配置
160
+ String password() default ""; // AES/SM4 密钥
161
+ String publicKey() default ""; // RSA/SM2 公钥
162
+ String privateKey() default ""; // RSA/SM2 私钥
151
163
  }
152
- ```
153
-
154
- **配置**:
155
-
156
- ```yaml
157
- mybatis-encryptor:
158
- enable: false
159
- algorithm: BASE64 # 默认算法
160
- encode: BASE64 # 编码方式:BASE64 | HEX
161
- password: your-secret-16 # AES/SM4 秘钥(16字符)
162
- publicKey: MFwwDQ... # RSA/SM2 公钥
163
- privateKey: MIIBVAIBADANBg... # RSA/SM2 私钥
164
- ```
165
-
166
- ---
167
-
168
- ## 5. @ApiEncrypt - 接口加密
169
164
 
170
- **导入**:`org.dromara.common.encrypt.annotation.ApiEncrypt`
171
-
172
- ```java
173
- // 加密响应数据
174
- @ApiEncrypt(response = true)
175
- @GetMapping("/{id}")
176
- public R<UserVo> getUser(@PathVariable Long id) { }
165
+ public enum AlgorithmType {
166
+ DEFAULT, BASE64, AES, RSA, SM2, SM4
167
+ }
177
168
  ```
178
169
 
179
- | 参数 | 类型 | 默认值 | 说明 |
180
- |------|------|--------|------|
181
- | `response` | boolean | false | 是否加密响应 |
182
-
183
- **配置**:
170
+ **配置示例**:
184
171
 
185
172
  ```yaml
186
- api-decrypt:
187
- enabled: true
188
- headerFlag: encrypt-key
189
- publicKey: MFwwDQ... # 响应加密公钥
190
- privateKey: MIIBVAIBADANBg... # 请求解密私钥
173
+ # [你的加密配置前缀]:
174
+ encrypt:
175
+ enable: true
176
+ algorithm: AES
177
+ password: your-secret-key-16ch # AES/SM4 密钥(16字符)
178
+ public-key: MFkwEw... # RSA/SM2 公钥
179
+ private-key: MIIBVAIBADANBg... # RSA/SM2 私钥
191
180
  ```
192
181
 
193
182
  ---
194
183
 
195
- ## 6. @DataPermission - 数据权限
184
+ ### 5. 接口加密(传输层)
196
185
 
197
- **导入**:`org.dromara.common.mybatis.annotation.DataPermission`、`@DataColumn`
186
+ **概念**:通过 Filter/Interceptor,对 HTTP 请求体自动解密、响应体自动加密。适用于前后端通信加密。
198
187
 
199
188
  ```java
200
- public interface OrderMapper extends BaseMapperPlus<Order, OrderVo> {
201
-
202
- // 按部门+创建人隔离
203
- @DataPermission({
204
- @DataColumn(key = "deptName", value = "dept_id"),
205
- @DataColumn(key = "userName", value = "create_by")
206
- })
207
- default Page<OrderVo> selectPageOrderList(Page<Order> page, Wrapper<Order> wrapper) {
208
- return this.selectVoPage(page, wrapper);
209
- }
210
-
211
- // 使用表别名
212
- @DataPermission({
213
- @DataColumn(key = "deptName", value = "d.dept_id"),
214
- @DataColumn(key = "userName", value = "u.create_by")
215
- })
216
- List<OrderVo> selectWithJoin(@Param(Constants.WRAPPER) Wrapper<Order> wrapper);
189
+ @Target(ElementType.METHOD)
190
+ @Retention(RetentionPolicy.RUNTIME)
191
+ public @interface ApiEncrypt {
192
+ boolean response() default false; // 是否加密响应
217
193
  }
218
- ```
219
-
220
- **@DataColumn 参数**:
221
194
 
222
- | 参数 | 默认值 | 说明 |
223
- |------|--------|------|
224
- | `key` | "deptName" | 占位符关键字 |
225
- | `value` | "dept_id" | 替换的字段名 |
226
- | `permission` | "" | 拥有此权限则不过滤 |
227
-
228
- **权限范围**:全部数据 / 本部门 / 本部门及以下 / 仅本人 / 自定义。
195
+ // RequestBodyAdvice / ResponseBodyAdvice 中拦截处理
196
+ // 或通过 Filter + HttpServletRequestWrapper 实现
197
+ ```
229
198
 
230
199
  ---
231
200
 
232
- ## 七、组合使用
201
+ ## 选型建议
233
202
 
234
- ```java
235
- // 接口防护:限流 + 防重复 + 日志
236
- @RateLimiter(time = 60, count = 10, limitType = LimitType.IP)
237
- @RepeatSubmit(interval = 10, timeUnit = TimeUnit.SECONDS)
238
- @Log(title = "订单", businessType = BusinessType.INSERT)
239
- @PostMapping()
240
- public R<Long> addOrder(@Validated @RequestBody OrderBo bo) { }
241
- ```
203
+ | 关注点 | 实现方式 | 作用层 | 依赖 |
204
+ |--------|---------|--------|------|
205
+ | 限流 | AOP + Redis Lua 脚本 | Controller | Redis |
206
+ | 防重复 | AOP + Redis SETNX | Controller | Redis + Token |
207
+ | 脱敏 | Jackson 自定义序列化器 | VO 字段 | 无 |
208
+ | 字段加密 | MyBatis 拦截器 / TypeHandler | Entity 字段 | 加密库 |
209
+ | 接口加密 | Filter / RequestBodyAdvice | Controller 方法 | 加密库 |
242
210
 
243
- ```java
244
- // 数据保护分层:Entity 加密存储 + VO 脱敏展示
245
- @TableName("sys_user")
246
- public class SysUser extends TenantEntity {
247
- @EncryptField(algorithm = AlgorithmType.AES)
248
- private String phone; // 存储时加密
249
- }
250
-
251
- public class UserVo {
252
- @Sensitive(strategy = SensitiveStrategy.PHONE)
253
- private String phone; // 序列化时脱敏
254
- }
255
- ```
211
+ | 加密算法 | 类型 | 密钥要求 | 适用场景 |
212
+ |---------|------|---------|---------|
213
+ | BASE64 | 编码(非加密) | 无 | 简单混淆 |
214
+ | AES | 对称加密 | 16/24/32 字节 | 通用加密(推荐) |
215
+ | RSA | 非对称加密 | 公钥/私钥对 | 高安全场景 |
216
+ | SM4 | 国密对称 | 16 字节 | 国密合规 |
217
+ | SM2 | 国密非对称 | 公钥/私钥对 | 国密合规 |
256
218
 
257
219
  ---
258
220
 
259
- ## 八、常见错误
221
+ ## 常见错误
260
222
 
261
223
  ```java
262
- // @RateLimiter 用在 Service 方法上(无效,只能 Controller)
224
+ // 1. 限流/防重复注解放在 Service 方法上(无效,应在 Controller)
263
225
  @Service
264
226
  public class XxxService {
265
- @RateLimiter(...) // 无效!
227
+ @RateLimiter(...) // 无效!AOP 通常只拦截 Controller
266
228
  public void doSomething() { }
267
229
  }
268
230
 
269
- // @DataPermission 未配置 @DataColumn
270
- @DataPermission // 空注解无效!
271
- public interface UserMapper { }
272
-
273
- // ❌ @Sensitive 用在 Entity 上(应在 VO 上)
274
- // ❌ @EncryptField 用在 VO 上(应在 Entity 上)
275
-
276
- // ✅ @DataPermission 支持类级别 + 方法级别(方法覆盖类)
277
- @DataPermission({ @DataColumn(key = "deptName", value = "dept_id") })
278
- public interface UserMapper {
279
- @DataPermission({ /* 方法级覆盖 */ })
280
- List<UserVo> selectList();
281
- }
282
- ```
283
-
284
- ---
231
+ // 2. @Sensitive 用在 Entity 上(应在 VO 上,序列化时生效)
232
+ // 3. @EncryptField 用在 VO 上(应在 Entity 上,持久化时生效)
285
233
 
286
- ## 九、参考实现
234
+ // 4. 加密密钥硬编码在注解中
235
+ @EncryptField(password = "my-secret-key") // 不安全
236
+ // 应使用全局配置或环境变量
287
237
 
288
- | 类型 | 位置 |
289
- |------|------|
290
- | 限流示例 | `org.dromara.demo.controller.RedisRateLimiterController` |
291
- | 脱敏示例 | `org.dromara.demo.controller.TestSensitiveController` |
292
- | 加密示例 | `org.dromara.demo.domain.TestDemo` |
293
- | 数据权限 | `org.dromara.system.mapper.SysUserMapper` |
238
+ // 5. 限流 key 设计不合理
239
+ @RateLimiter(key = "") // 所有用户共享限流
240
+ // 应根据场景选择:用户维度 key="#userId",IP 维度 limitType=IP
294
241
 
295
- **配置位置**:
296
-
297
- ```
298
- application.yml:
299
- mybatis-encryptor.* → @EncryptField 全局配置
300
- api-decrypt.* → @ApiEncrypt 全局配置
301
- spring.data.redis.* → @RateLimiter/@RepeatSubmit 依赖
242
+ // 6. 组合注解顺序不当
243
+ // 推荐顺序:限流 -> 防重复 -> 权限 -> 日志
244
+ @RateLimiter(time = 60, count = 10)
245
+ @RepeatSubmit(interval = 5000)
246
+ @PostMapping()
247
+ public Result<?> add(@RequestBody XxxDTO dto) { }
302
248
  ```