ai-engineering-init 1.7.0 → 1.10.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 (139) hide show
  1. package/.claude/agents/bug-analyzer.md +103 -0
  2. package/.claude/agents/code-reviewer.md +115 -5
  3. package/.claude/agents/image-reader.md +154 -0
  4. package/.claude/agents/loki-runner.md +80 -0
  5. package/.claude/agents/mysql-runner.md +81 -0
  6. package/.claude/agents/requirements-analyzer.md +162 -0
  7. package/.claude/agents/task-fetcher.md +75 -0
  8. package/.claude/commands/dev.md +29 -0
  9. package/.claude/commands/next.md +31 -1
  10. package/.claude/commands/progress.md +23 -1
  11. package/.claude/hooks/skill-forced-eval.js +46 -62
  12. package/.claude/settings.json +10 -1
  13. package/.claude/skills/api-development/SKILL.md +179 -130
  14. package/.claude/skills/architecture-design/SKILL.md +102 -212
  15. package/.claude/skills/backend-annotations/SKILL.md +166 -220
  16. package/.claude/skills/bug-detective/SKILL.md +225 -186
  17. package/.claude/skills/code-patterns/SKILL.md +127 -244
  18. package/.claude/skills/collaborating-with-codex/SKILL.md +96 -113
  19. package/.claude/skills/crud-development/SKILL.md +226 -307
  20. package/.claude/skills/data-permission/SKILL.md +131 -202
  21. package/.claude/skills/database-ops/SKILL.md +158 -355
  22. package/.claude/skills/error-handler/SKILL.md +224 -285
  23. package/.claude/skills/file-oss-management/SKILL.md +174 -169
  24. package/.claude/skills/git-workflow/SKILL.md +123 -341
  25. package/.claude/skills/json-serialization/SKILL.md +121 -137
  26. package/.claude/skills/performance-doctor/SKILL.md +83 -89
  27. package/.claude/skills/redis-cache/SKILL.md +134 -185
  28. package/.claude/skills/scheduled-jobs/SKILL.md +187 -224
  29. package/.claude/skills/security-guard/SKILL.md +168 -276
  30. package/.claude/skills/sms-mail/SKILL.md +266 -228
  31. package/.claude/skills/social-login/SKILL.md +257 -195
  32. package/.claude/skills/tenant-management/SKILL.md +172 -188
  33. package/.claude/skills/utils-toolkit/SKILL.md +214 -222
  34. package/.claude/skills/websocket-sse/SKILL.md +251 -172
  35. package/.claude/skills/workflow-engine/SKILL.md +178 -250
  36. package/.codex/skills/api-development/SKILL.md +179 -130
  37. package/.codex/skills/architecture-design/SKILL.md +102 -212
  38. package/.codex/skills/backend-annotations/SKILL.md +166 -220
  39. package/.codex/skills/bug-detective/SKILL.md +225 -186
  40. package/.codex/skills/code-patterns/SKILL.md +127 -244
  41. package/.codex/skills/collaborating-with-codex/SKILL.md +96 -113
  42. package/.codex/skills/crud-development/SKILL.md +226 -307
  43. package/.codex/skills/data-permission/SKILL.md +131 -202
  44. package/.codex/skills/database-ops/SKILL.md +158 -355
  45. package/.codex/skills/dev/SKILL.md +476 -131
  46. package/.codex/skills/error-handler/SKILL.md +224 -285
  47. package/.codex/skills/file-oss-management/SKILL.md +174 -169
  48. package/.codex/skills/git-workflow/SKILL.md +123 -341
  49. package/.codex/skills/json-serialization/SKILL.md +121 -137
  50. package/.codex/skills/next/SKILL.md +186 -42
  51. package/.codex/skills/performance-doctor/SKILL.md +83 -89
  52. package/.codex/skills/progress/SKILL.md +147 -76
  53. package/.codex/skills/redis-cache/SKILL.md +134 -185
  54. package/.codex/skills/scheduled-jobs/SKILL.md +187 -224
  55. package/.codex/skills/security-guard/SKILL.md +168 -276
  56. package/.codex/skills/sms-mail/SKILL.md +266 -228
  57. package/.codex/skills/social-login/SKILL.md +257 -195
  58. package/.codex/skills/tenant-management/SKILL.md +172 -188
  59. package/.codex/skills/utils-toolkit/SKILL.md +214 -222
  60. package/.codex/skills/websocket-sse/SKILL.md +251 -172
  61. package/.codex/skills/workflow-engine/SKILL.md +178 -250
  62. package/.cursor/agents/bug-analyzer.md +102 -0
  63. package/.cursor/agents/code-reviewer.md +80 -97
  64. package/.cursor/agents/image-reader.md +154 -0
  65. package/.cursor/agents/loki-runner.md +80 -0
  66. package/.cursor/agents/mysql-runner.md +81 -0
  67. package/.cursor/agents/project-manager.md +1 -1
  68. package/.cursor/agents/requirements-analyzer.md +141 -0
  69. package/.cursor/agents/task-fetcher.md +75 -0
  70. package/.cursor/hooks/cursor-skill-eval.js +66 -6
  71. package/.cursor/skills/api-development/SKILL.md +179 -130
  72. package/.cursor/skills/architecture-design/SKILL.md +102 -212
  73. package/.cursor/skills/backend-annotations/SKILL.md +166 -220
  74. package/.cursor/skills/bug-detective/SKILL.md +225 -186
  75. package/.cursor/skills/code-patterns/SKILL.md +127 -244
  76. package/.cursor/skills/collaborating-with-codex/SKILL.md +96 -113
  77. package/.cursor/skills/crud-development/SKILL.md +226 -307
  78. package/.cursor/skills/data-permission/SKILL.md +131 -202
  79. package/.cursor/skills/database-ops/SKILL.md +158 -355
  80. package/.cursor/skills/error-handler/SKILL.md +224 -285
  81. package/.cursor/skills/file-oss-management/SKILL.md +174 -169
  82. package/.cursor/skills/git-workflow/SKILL.md +123 -341
  83. package/.cursor/skills/json-serialization/SKILL.md +121 -137
  84. package/.cursor/skills/performance-doctor/SKILL.md +83 -89
  85. package/.cursor/skills/redis-cache/SKILL.md +134 -185
  86. package/.cursor/skills/scheduled-jobs/SKILL.md +187 -224
  87. package/.cursor/skills/security-guard/SKILL.md +168 -276
  88. package/.cursor/skills/sms-mail/SKILL.md +266 -228
  89. package/.cursor/skills/social-login/SKILL.md +257 -195
  90. package/.cursor/skills/tenant-management/SKILL.md +172 -188
  91. package/.cursor/skills/utils-toolkit/SKILL.md +214 -222
  92. package/.cursor/skills/websocket-sse/SKILL.md +251 -172
  93. package/.cursor/skills/workflow-engine/SKILL.md +178 -250
  94. package/AGENTS.md +117 -540
  95. package/CLAUDE.md +105 -117
  96. package/README.md +37 -6
  97. package/bin/index.js +5 -1
  98. package/package.json +1 -1
  99. package/src/skills/api-development/SKILL.md +179 -130
  100. package/src/skills/architecture-design/SKILL.md +102 -212
  101. package/src/skills/backend-annotations/SKILL.md +166 -220
  102. package/src/skills/bug-detective/SKILL.md +225 -186
  103. package/src/skills/code-patterns/SKILL.md +127 -244
  104. package/src/skills/collaborating-with-codex/SKILL.md +96 -113
  105. package/src/skills/crud-development/SKILL.md +226 -307
  106. package/src/skills/data-permission/SKILL.md +131 -202
  107. package/src/skills/database-ops/SKILL.md +158 -355
  108. package/src/skills/error-handler/SKILL.md +224 -285
  109. package/src/skills/file-oss-management/SKILL.md +174 -169
  110. package/src/skills/git-workflow/SKILL.md +123 -341
  111. package/src/skills/json-serialization/SKILL.md +121 -137
  112. package/src/skills/performance-doctor/SKILL.md +83 -89
  113. package/src/skills/redis-cache/SKILL.md +134 -185
  114. package/src/skills/scheduled-jobs/SKILL.md +187 -224
  115. package/src/skills/security-guard/SKILL.md +168 -276
  116. package/src/skills/sms-mail/SKILL.md +266 -228
  117. package/src/skills/social-login/SKILL.md +257 -195
  118. package/src/skills/tenant-management/SKILL.md +172 -188
  119. package/src/skills/utils-toolkit/SKILL.md +214 -222
  120. package/src/skills/websocket-sse/SKILL.md +251 -172
  121. package/src/skills/workflow-engine/SKILL.md +178 -250
  122. package/.claude/skills/skill-creator/LICENSE.txt +0 -202
  123. package/.claude/skills/skill-creator/SKILL.md +0 -479
  124. package/.claude/skills/skill-creator/agents/analyzer.md +0 -274
  125. package/.claude/skills/skill-creator/agents/comparator.md +0 -202
  126. package/.claude/skills/skill-creator/agents/grader.md +0 -223
  127. package/.claude/skills/skill-creator/assets/eval_review.html +0 -146
  128. package/.claude/skills/skill-creator/eval-viewer/generate_review.py +0 -471
  129. package/.claude/skills/skill-creator/eval-viewer/viewer.html +0 -1325
  130. package/.claude/skills/skill-creator/references/schemas.md +0 -430
  131. package/.claude/skills/skill-creator/scripts/__init__.py +0 -0
  132. package/.claude/skills/skill-creator/scripts/aggregate_benchmark.py +0 -401
  133. package/.claude/skills/skill-creator/scripts/generate_report.py +0 -326
  134. package/.claude/skills/skill-creator/scripts/improve_description.py +0 -248
  135. package/.claude/skills/skill-creator/scripts/package_skill.py +0 -136
  136. package/.claude/skills/skill-creator/scripts/quick_validate.py +0 -103
  137. package/.claude/skills/skill-creator/scripts/run_eval.py +0 -310
  138. package/.claude/skills/skill-creator/scripts/run_loop.py +0 -332
  139. 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
  ```