ai-engineering-init 1.3.4 → 1.4.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 (226) hide show
  1. package/.claude/hooks/skill-forced-eval.js +2 -0
  2. package/.claude/settings.json +3 -3
  3. package/.claude/skills/add-skill/SKILL.md +79 -32
  4. package/.claude/skills/api-development/SKILL.md +83 -377
  5. package/.claude/skills/architecture-design/SKILL.md +138 -632
  6. package/.claude/skills/backend-annotations/SKILL.md +134 -506
  7. package/.claude/skills/banana-image/SKILL.md +10 -3
  8. package/.claude/skills/brainstorm/SKILL.md +103 -535
  9. package/.claude/skills/bug-detective/SKILL.md +147 -1097
  10. package/.claude/skills/bug-detective/references/error-patterns.md +242 -0
  11. package/.claude/skills/code-patterns/SKILL.md +116 -426
  12. package/.claude/skills/code-patterns/references/leniu-code-patterns.md +87 -0
  13. package/.claude/skills/crud-development/SKILL.md +64 -304
  14. package/.claude/skills/data-permission/SKILL.md +105 -412
  15. package/.claude/skills/data-permission/references/custom-data-scope.md +90 -0
  16. package/.claude/skills/file-oss-management/SKILL.md +106 -714
  17. package/.claude/skills/file-oss-management/references/entities.md +105 -0
  18. package/.claude/skills/file-oss-management/references/service-impl.md +104 -0
  19. package/.claude/skills/leniu-api-development/SKILL.md +142 -626
  20. package/.claude/skills/leniu-api-development/references/real-examples.md +273 -0
  21. package/.claude/skills/leniu-architecture-design/SKILL.md +176 -391
  22. package/.claude/skills/leniu-backend-annotations/SKILL.md +132 -519
  23. package/.claude/skills/leniu-brainstorm/SKILL.md +132 -541
  24. package/.claude/skills/leniu-brainstorm/references/business-scenarios.md +162 -0
  25. package/.claude/skills/leniu-crud-development/SKILL.md +232 -938
  26. package/.claude/skills/leniu-crud-development/references/templates.md +597 -0
  27. package/.claude/skills/leniu-customization-location/SKILL.md +410 -0
  28. package/.claude/skills/leniu-data-permission/SKILL.md +70 -0
  29. package/.claude/skills/leniu-java-entity/SKILL.md +76 -590
  30. package/.claude/skills/leniu-java-entity/references/templates.md +237 -0
  31. package/.claude/skills/leniu-java-export/SKILL.md +94 -379
  32. package/.claude/skills/leniu-java-logging/SKILL.md +106 -709
  33. package/.claude/skills/leniu-java-logging/references/data-mask.md +46 -0
  34. package/.claude/skills/leniu-java-logging/references/logging-scenarios.md +113 -0
  35. package/.claude/skills/leniu-java-mybatis/SKILL.md +73 -446
  36. package/.claude/skills/leniu-java-mybatis/references/report-mapper.md +88 -0
  37. package/.claude/skills/leniu-report-customization/SKILL.md +111 -365
  38. package/.claude/skills/leniu-report-customization/references/table-fields.md +93 -0
  39. package/.claude/skills/leniu-report-standard-customization/SKILL.md +111 -334
  40. package/.claude/skills/leniu-report-standard-customization/references/analysis-module.md +64 -0
  41. package/.claude/skills/leniu-report-standard-customization/references/table-fields.md +113 -0
  42. package/.claude/skills/leniu-security-guard/SKILL.md +133 -347
  43. package/.claude/skills/mysql-debug/SKILL.md +364 -0
  44. package/.claude/skills/openspec-apply-change/SKILL.md +10 -1
  45. package/.claude/skills/openspec-archive-change/SKILL.md +9 -1
  46. package/.claude/skills/openspec-bulk-archive-change/SKILL.md +9 -1
  47. package/.claude/skills/openspec-continue-change/SKILL.md +9 -1
  48. package/.claude/skills/openspec-explore/SKILL.md +10 -1
  49. package/.claude/skills/openspec-ff-change/SKILL.md +9 -1
  50. package/.claude/skills/openspec-new-change/SKILL.md +9 -1
  51. package/.claude/skills/openspec-onboard/SKILL.md +15 -130
  52. package/.claude/skills/openspec-sync-specs/SKILL.md +9 -1
  53. package/.claude/skills/openspec-verify-change/SKILL.md +9 -1
  54. package/.claude/skills/performance-doctor/SKILL.md +110 -434
  55. package/.claude/skills/redis-cache/SKILL.md +89 -595
  56. package/.claude/skills/redis-cache/references/listeners.md +23 -0
  57. package/.claude/skills/scheduled-jobs/SKILL.md +88 -407
  58. package/.claude/skills/security-guard/SKILL.md +137 -532
  59. package/.claude/skills/security-guard/references/encrypt-config.md +103 -0
  60. package/.claude/skills/security-guard/references/sensitive-strategies.md +42 -0
  61. package/.claude/skills/sms-mail/SKILL.md +116 -574
  62. package/.claude/skills/sms-mail/references/mail-config.md +88 -0
  63. package/.claude/skills/sms-mail/references/sms-config.md +74 -0
  64. package/.claude/skills/social-login/SKILL.md +112 -514
  65. package/.claude/skills/social-login/references/provider-configs.md +118 -0
  66. package/.claude/skills/tenant-management/SKILL.md +129 -444
  67. package/.claude/skills/tenant-management/references/tenant-scenarios.md +91 -0
  68. package/.claude/skills/test-development/SKILL.md +86 -540
  69. package/.claude/skills/test-development/references/parameterized-examples.md +119 -0
  70. package/.claude/skills/utils-toolkit/SKILL.md +52 -305
  71. package/.claude/skills/utils-toolkit/references/redis-utils-api.md +56 -0
  72. package/.claude/skills/websocket-sse/SKILL.md +105 -550
  73. package/.claude/skills/workflow-engine/SKILL.md +147 -502
  74. package/.codex/skills/add-skill/SKILL.md +79 -32
  75. package/.codex/skills/api-development/SKILL.md +172 -599
  76. package/.codex/skills/architecture-design/SKILL.md +138 -504
  77. package/.codex/skills/backend-annotations/SKILL.md +134 -496
  78. package/.codex/skills/banana-image/SKILL.md +10 -3
  79. package/.codex/skills/brainstorm/SKILL.md +103 -535
  80. package/.codex/skills/bug-detective/SKILL.md +147 -1097
  81. package/.codex/skills/bug-detective/references/error-patterns.md +242 -0
  82. package/.codex/skills/code-patterns/SKILL.md +120 -282
  83. package/.codex/skills/code-patterns/references/leniu-code-patterns.md +87 -0
  84. package/.codex/skills/crud-development/SKILL.md +64 -292
  85. package/.codex/skills/data-permission/SKILL.md +108 -407
  86. package/.codex/skills/data-permission/references/custom-data-scope.md +90 -0
  87. package/.codex/skills/database-ops/SKILL.md +8 -154
  88. package/.codex/skills/error-handler/SKILL.md +10 -0
  89. package/.codex/skills/file-oss-management/SKILL.md +106 -714
  90. package/.codex/skills/file-oss-management/references/entities.md +105 -0
  91. package/.codex/skills/file-oss-management/references/service-impl.md +104 -0
  92. package/.codex/skills/git-workflow/SKILL.md +27 -5
  93. package/.codex/skills/leniu-api-development/SKILL.md +142 -626
  94. package/.codex/skills/leniu-api-development/references/real-examples.md +273 -0
  95. package/.codex/skills/leniu-architecture-design/SKILL.md +176 -391
  96. package/.codex/skills/leniu-backend-annotations/SKILL.md +132 -519
  97. package/.codex/skills/leniu-brainstorm/SKILL.md +132 -541
  98. package/.codex/skills/leniu-brainstorm/references/business-scenarios.md +162 -0
  99. package/.codex/skills/leniu-crud-development/SKILL.md +232 -938
  100. package/.codex/skills/leniu-crud-development/references/templates.md +597 -0
  101. package/.codex/skills/leniu-customization-location/SKILL.md +410 -0
  102. package/.codex/skills/leniu-data-permission/SKILL.md +70 -0
  103. package/.codex/skills/leniu-java-code-style/SKILL.md +510 -0
  104. package/.codex/skills/leniu-java-entity/SKILL.md +76 -590
  105. package/.codex/skills/leniu-java-entity/references/templates.md +237 -0
  106. package/.codex/skills/leniu-java-export/SKILL.md +94 -379
  107. package/.codex/skills/leniu-java-logging/SKILL.md +106 -709
  108. package/.codex/skills/leniu-java-logging/references/data-mask.md +46 -0
  109. package/.codex/skills/leniu-java-logging/references/logging-scenarios.md +113 -0
  110. package/.codex/skills/leniu-java-mybatis/SKILL.md +73 -446
  111. package/.codex/skills/leniu-java-mybatis/references/report-mapper.md +88 -0
  112. package/.codex/skills/leniu-report-customization/SKILL.md +111 -365
  113. package/.codex/skills/leniu-report-customization/references/table-fields.md +93 -0
  114. package/.codex/skills/leniu-report-standard-customization/SKILL.md +111 -334
  115. package/.codex/skills/leniu-report-standard-customization/references/analysis-module.md +64 -0
  116. package/.codex/skills/leniu-report-standard-customization/references/table-fields.md +113 -0
  117. package/.codex/skills/leniu-security-guard/SKILL.md +133 -347
  118. package/.codex/skills/mysql-debug/SKILL.md +364 -0
  119. package/.codex/skills/openspec-apply-change/SKILL.md +10 -1
  120. package/.codex/skills/openspec-archive-change/SKILL.md +9 -1
  121. package/.codex/skills/openspec-bulk-archive-change/SKILL.md +9 -1
  122. package/.codex/skills/openspec-continue-change/SKILL.md +9 -1
  123. package/.codex/skills/openspec-explore/SKILL.md +10 -1
  124. package/.codex/skills/openspec-ff-change/SKILL.md +9 -1
  125. package/.codex/skills/openspec-new-change/SKILL.md +9 -1
  126. package/.codex/skills/openspec-onboard/SKILL.md +15 -130
  127. package/.codex/skills/openspec-sync-specs/SKILL.md +9 -1
  128. package/.codex/skills/openspec-verify-change/SKILL.md +9 -1
  129. package/.codex/skills/performance-doctor/SKILL.md +110 -434
  130. package/.codex/skills/project-navigator/SKILL.md +20 -1
  131. package/.codex/skills/redis-cache/SKILL.md +93 -589
  132. package/.codex/skills/redis-cache/references/listeners.md +23 -0
  133. package/.codex/skills/scheduled-jobs/SKILL.md +88 -407
  134. package/.codex/skills/security-guard/SKILL.md +141 -527
  135. package/.codex/skills/security-guard/references/encrypt-config.md +103 -0
  136. package/.codex/skills/security-guard/references/sensitive-strategies.md +42 -0
  137. package/.codex/skills/sms-mail/SKILL.md +116 -574
  138. package/.codex/skills/sms-mail/references/mail-config.md +88 -0
  139. package/.codex/skills/sms-mail/references/sms-config.md +74 -0
  140. package/.codex/skills/social-login/SKILL.md +112 -514
  141. package/.codex/skills/social-login/references/provider-configs.md +118 -0
  142. package/.codex/skills/store-pc/SKILL.md +258 -383
  143. package/.codex/skills/tenant-management/SKILL.md +129 -444
  144. package/.codex/skills/tenant-management/references/tenant-scenarios.md +91 -0
  145. package/.codex/skills/test-development/SKILL.md +86 -540
  146. package/.codex/skills/test-development/references/parameterized-examples.md +119 -0
  147. package/.codex/skills/ui-pc/SKILL.md +350 -387
  148. package/.codex/skills/utils-toolkit/SKILL.md +52 -283
  149. package/.codex/skills/utils-toolkit/references/redis-utils-api.md +56 -0
  150. package/.codex/skills/websocket-sse/SKILL.md +105 -550
  151. package/.codex/skills/workflow-engine/SKILL.md +147 -502
  152. package/.cursor/hooks.json +3 -3
  153. package/.cursor/skills/add-skill/SKILL.md +79 -32
  154. package/.cursor/skills/api-development/SKILL.md +83 -377
  155. package/.cursor/skills/architecture-design/SKILL.md +138 -632
  156. package/.cursor/skills/backend-annotations/SKILL.md +134 -506
  157. package/.cursor/skills/banana-image/SKILL.md +10 -3
  158. package/.cursor/skills/brainstorm/SKILL.md +103 -535
  159. package/.cursor/skills/bug-detective/SKILL.md +147 -1097
  160. package/.cursor/skills/bug-detective/references/error-patterns.md +242 -0
  161. package/.cursor/skills/code-patterns/SKILL.md +116 -426
  162. package/.cursor/skills/code-patterns/references/leniu-code-patterns.md +87 -0
  163. package/.cursor/skills/crud-development/SKILL.md +64 -304
  164. package/.cursor/skills/data-permission/SKILL.md +105 -412
  165. package/.cursor/skills/data-permission/references/custom-data-scope.md +90 -0
  166. package/.cursor/skills/file-oss-management/SKILL.md +106 -714
  167. package/.cursor/skills/file-oss-management/references/entities.md +105 -0
  168. package/.cursor/skills/file-oss-management/references/service-impl.md +104 -0
  169. package/.cursor/skills/git-workflow/SKILL.md +27 -5
  170. package/.cursor/skills/leniu-api-development/SKILL.md +142 -626
  171. package/.cursor/skills/leniu-api-development/references/real-examples.md +273 -0
  172. package/.cursor/skills/leniu-architecture-design/SKILL.md +176 -391
  173. package/.cursor/skills/leniu-backend-annotations/SKILL.md +132 -519
  174. package/.cursor/skills/leniu-brainstorm/SKILL.md +132 -541
  175. package/.cursor/skills/leniu-brainstorm/references/business-scenarios.md +162 -0
  176. package/.cursor/skills/leniu-crud-development/SKILL.md +232 -938
  177. package/.cursor/skills/leniu-crud-development/references/templates.md +597 -0
  178. package/.cursor/skills/leniu-customization-location/SKILL.md +410 -0
  179. package/.cursor/skills/leniu-data-permission/SKILL.md +70 -0
  180. package/.cursor/skills/leniu-java-code-style/SKILL.md +510 -0
  181. package/.cursor/skills/leniu-java-entity/SKILL.md +76 -590
  182. package/.cursor/skills/leniu-java-entity/references/templates.md +237 -0
  183. package/.cursor/skills/leniu-java-export/SKILL.md +94 -379
  184. package/.cursor/skills/leniu-java-logging/SKILL.md +106 -709
  185. package/.cursor/skills/leniu-java-logging/references/data-mask.md +46 -0
  186. package/.cursor/skills/leniu-java-logging/references/logging-scenarios.md +113 -0
  187. package/.cursor/skills/leniu-java-mybatis/SKILL.md +73 -446
  188. package/.cursor/skills/leniu-java-mybatis/references/report-mapper.md +88 -0
  189. package/.cursor/skills/leniu-report-customization/SKILL.md +111 -365
  190. package/.cursor/skills/leniu-report-customization/references/table-fields.md +93 -0
  191. package/.cursor/skills/leniu-report-standard-customization/SKILL.md +111 -334
  192. package/.cursor/skills/leniu-report-standard-customization/references/analysis-module.md +64 -0
  193. package/.cursor/skills/leniu-report-standard-customization/references/table-fields.md +113 -0
  194. package/.cursor/skills/leniu-security-guard/SKILL.md +133 -347
  195. package/.cursor/skills/mysql-debug/SKILL.md +364 -0
  196. package/.cursor/skills/openspec-apply-change/SKILL.md +10 -1
  197. package/.cursor/skills/openspec-archive-change/SKILL.md +9 -1
  198. package/.cursor/skills/openspec-bulk-archive-change/SKILL.md +9 -1
  199. package/.cursor/skills/openspec-continue-change/SKILL.md +9 -1
  200. package/.cursor/skills/openspec-explore/SKILL.md +10 -1
  201. package/.cursor/skills/openspec-ff-change/SKILL.md +9 -1
  202. package/.cursor/skills/openspec-new-change/SKILL.md +9 -1
  203. package/.cursor/skills/openspec-onboard/SKILL.md +15 -130
  204. package/.cursor/skills/openspec-sync-specs/SKILL.md +9 -1
  205. package/.cursor/skills/openspec-verify-change/SKILL.md +9 -1
  206. package/.cursor/skills/performance-doctor/SKILL.md +110 -434
  207. package/.cursor/skills/redis-cache/SKILL.md +89 -595
  208. package/.cursor/skills/redis-cache/references/listeners.md +23 -0
  209. package/.cursor/skills/scheduled-jobs/SKILL.md +88 -407
  210. package/.cursor/skills/security-guard/SKILL.md +137 -532
  211. package/.cursor/skills/security-guard/references/encrypt-config.md +103 -0
  212. package/.cursor/skills/security-guard/references/sensitive-strategies.md +42 -0
  213. package/.cursor/skills/sms-mail/SKILL.md +116 -574
  214. package/.cursor/skills/sms-mail/references/mail-config.md +88 -0
  215. package/.cursor/skills/sms-mail/references/sms-config.md +74 -0
  216. package/.cursor/skills/social-login/SKILL.md +112 -514
  217. package/.cursor/skills/social-login/references/provider-configs.md +118 -0
  218. package/.cursor/skills/tenant-management/SKILL.md +129 -444
  219. package/.cursor/skills/tenant-management/references/tenant-scenarios.md +91 -0
  220. package/.cursor/skills/test-development/SKILL.md +86 -540
  221. package/.cursor/skills/test-development/references/parameterized-examples.md +119 -0
  222. package/.cursor/skills/utils-toolkit/SKILL.md +52 -305
  223. package/.cursor/skills/utils-toolkit/references/redis-utils-api.md +56 -0
  224. package/.cursor/skills/websocket-sse/SKILL.md +105 -550
  225. package/.cursor/skills/workflow-engine/SKILL.md +147 -502
  226. package/package.json +1 -1
@@ -16,649 +16,287 @@ description: |
16
16
 
17
17
  # 后端高级注解指南
18
18
 
19
- > **⚠️ 重要声明**: 本项目是 **RuoYi-Vue-Plus 纯后端项目**,采用三层架构!
20
- > 本文档规范基于框架内置的高级注解功能。所有注解均依赖 Redis 或数据库拦截机制。
19
+ > RuoYi-Vue-Plus 三层架构,包名 `org.dromara.*`
21
20
 
22
- ## 注解快速特征对比
21
+ ## 注解总览
23
22
 
24
- | 注解 | 实现机制 | 作用范围 | 依赖 | 常用场景 |
25
- |------|--------|--------|------|---------|
26
- | `@RateLimiter` | AOP 切面 | Controller 方法 | Redis | 接口防刷、流量保护 |
27
- | `@RepeatSubmit` | AOP 切面 | Controller 方法 | Redis + Token | 防重复提交、幂等性 |
28
- | `@Sensitive` | Jackson 序列化器 | VO 字段 | 无 | 数据脱敏、隐私保护 |
29
- | `@EncryptField` | MyBatis 拦截器 | Entity 字段 | 无 | 数据库加密、敏感字段 |
30
- | `@ApiEncrypt` | 拦截器 | Controller 方法 | 无 | 接口加密、传输安全 |
31
- | `@DataPermission` | AOP 拦截器 | Mapper 接口 | MyBatis | 数据隔离、行级权限 |
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 |
32
31
 
33
32
  ---
34
33
 
35
34
  ## 1. @RateLimiter - 接口限流
36
35
 
37
- ### 作用
38
- 基于 Redis 和令牌桶算法实现分布式限流,防止接口被恶意刷新或频繁访问。
39
-
40
- ### 限流类型
41
-
42
- | 类型 | 说明 | 适用场景 |
43
- |------|------|---------|
44
- | `LimitType.DEFAULT` | 全局限流,所有请求共享配额 | 查询接口、通用接口 |
45
- | `LimitType.IP` | IP限流,每个IP独立计算 | 登录、验证码、敏感操作 |
46
- | `LimitType.CLUSTER` | 集群限流,每个节点独立 | 集群部署、分布式场景 |
47
-
48
- ### 使用示例
49
-
50
- ```java
51
- import org.dromara.common.ratelimiter.annotation.RateLimiter;
52
- import org.dromara.common.ratelimiter.enums.LimitType;
53
-
54
- @RestController
55
- @RequestMapping("/demo")
56
- public class DemoController {
57
-
58
- // ✅ 基本用法:60秒内最多100次
59
- @RateLimiter(time = 60, count = 100)
60
- @GetMapping("/list")
61
- public R<List<XxxVo>> list() { }
62
-
63
- // ✅ IP限流:每个IP每分钟最多10次
64
- @RateLimiter(time = 60, count = 10, limitType = LimitType.IP)
65
- @PostMapping("/login")
66
- public R<String> login() { }
67
-
68
- // ✅ 集群限流:每个节点独立限流
69
- @RateLimiter(time = 60, count = 20, limitType = LimitType.CLUSTER)
70
- @GetMapping("/data")
71
- public R<DataVo> getData() { }
72
-
73
- // ✅ 动态key:基于用户ID限流
74
- @RateLimiter(key = "#userId", time = 60, count = 5)
75
- @PostMapping("/submit")
76
- public R<Void> submit(Long userId) { }
77
-
78
- // ✅ 自定义错误消息
79
- @RateLimiter(time = 60, count = 10, message = "访问过于频繁,请稍后再试")
80
- @GetMapping("/sensitive")
81
- public R<DataVo> getSensitiveData() { }
82
- }
83
- ```
84
-
85
- ### 注解参数
36
+ **导入**:`org.dromara.common.ratelimiter.annotation.RateLimiter`
86
37
 
87
38
  | 参数 | 类型 | 默认值 | 说明 |
88
39
  |------|------|--------|------|
89
- | `key` | String | "" | 限流key,支持SpEL表达式 |
40
+ | `key` | String | "" | 限流key,支持SpEL |
90
41
  | `time` | int | 60 | 时间窗口(秒) |
91
42
  | `count` | int | 100 | 最大请求次数 |
92
- | `limitType` | LimitType | DEFAULT | 限流类型 |
93
- | `message` | String | 国际化key | 错误提示消息 |
94
- | `timeout` | int | 86400 | Redis超时(秒) |
95
-
96
- ### 推荐配置
43
+ | `limitType` | LimitType | DEFAULT | DEFAULT/IP/CLUSTER |
44
+ | `message` | String | 国际化key | 错误提示 |
97
45
 
98
- | 场景 | time | count | limitType | 说明 |
99
- |------|------|-------|-----------|------|
100
- | 登录接口 | 60 | 5-10 | IP | 防止暴力破解 |
101
- | 验证码 | 60 | 3 | IP | 防止验证码滥用 |
102
- | 查询接口 | 60 | 100-1000 | DEFAULT | 一般查询 |
103
- | 写入接口 | 60 | 10-50 | DEFAULT | 新增/修改/删除 |
104
- | 敏感操作 | 60 | 1-5 | IP | 支付、提现等 |
46
+ ```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) { }
61
+ ```
105
62
 
106
63
  ---
107
64
 
108
65
  ## 2. @RepeatSubmit - 防重复提交
109
66
 
110
- ### 作用
111
- 基于 Redis 分布式锁防止短时间内重复提交表单或请求,保证接口幂等性。
112
-
113
- ### 使用示例
114
-
115
- ```java
116
- import org.dromara.common.idempotent.annotation.RepeatSubmit;
117
- import java.util.concurrent.TimeUnit;
118
-
119
- @RestController
120
- @RequestMapping("/order")
121
- public class OrderController {
122
-
123
- // ✅ 默认:5秒内不能重复提交
124
- @RepeatSubmit()
125
- @PostMapping()
126
- public R<Long> addOrder(@RequestBody OrderBo bo) {
127
- return R.ok(orderService.add(bo));
128
- }
129
-
130
- // ✅ 自定义间隔:10秒
131
- @RepeatSubmit(interval = 10000)
132
- @PostMapping("/pay")
133
- public R<Void> pay(@RequestBody PayBo bo) { }
134
-
135
- // ✅ 使用秒作为单位
136
- @RepeatSubmit(interval = 10, timeUnit = TimeUnit.SECONDS)
137
- @PostMapping("/submit")
138
- public R<Void> submit(@RequestBody SubmitBo bo) { }
139
-
140
- // ✅ 自定义提示消息
141
- @RepeatSubmit(interval = 5000, message = "请勿重复提交订单")
142
- @PostMapping("/create")
143
- public R<Long> createOrder(@RequestBody OrderBo bo) { }
144
- }
145
- ```
146
-
147
- ### 注解参数
67
+ **导入**:`org.dromara.common.idempotent.annotation.RepeatSubmit`
148
68
 
149
69
  | 参数 | 类型 | 默认值 | 说明 |
150
70
  |------|------|--------|------|
151
71
  | `interval` | int | 5000 | 间隔时间(毫秒) |
152
72
  | `timeUnit` | TimeUnit | MILLISECONDS | 时间单位 |
153
- | `message` | String | 国际化key | 错误提示消息 |
154
-
155
- ### 工作原理
156
-
157
- 1. **提交前** - 生成请求唯一键:`MD5(token + ":" + 序列化参数)`
158
- 2. **Redis检查** - 尝试在 Redis 中设置该键,有效期为 `interval`
159
- 3. **重复检测** - 如果已存在该键,说明重复提交,直接返回错误
160
- 4. **成功处理** - 如果返回 `R.SUCCESS`,保持 Redis 数据不删除(防止短时间重复)
161
- 5. **异常处理** - 如果异常,删除 Redis 数据允许重新提交
73
+ | `message` | String | 国际化key | 错误提示 |
162
74
 
163
- ### 常见场景
75
+ ```java
76
+ // 默认5秒
77
+ @RepeatSubmit()
78
+ @PostMapping()
79
+ public R<Long> add(@RequestBody OrderBo bo) { }
80
+
81
+ // 10秒间隔 + 自定义提示
82
+ @RepeatSubmit(interval = 10, timeUnit = TimeUnit.SECONDS, message = "请勿重复提交")
83
+ @PostMapping("/pay")
84
+ public R<Void> pay(@RequestBody PayBo bo) { }
85
+ ```
164
86
 
165
- | 场景 | 推荐间隔 |
166
- |------|---------|
167
- | 普通表单 | 3-5秒 |
168
- | 订单创建 | 10秒 |
169
- | 支付操作 | 30秒 |
170
- | 文件上传 | 10秒 |
87
+ **原理**:`MD5(token + ":" + 序列化参数)` -> Redis 设置/检查 -> 成功保留key防重复 -> 异常删除key允许重试。
171
88
 
172
89
  ---
173
90
 
174
91
  ## 3. @Sensitive - 数据脱敏
175
92
 
176
- ### 作用
177
- 在 JSON 序列化时自动对敏感字段进行脱敏处理,支持基于角色/权限的访问控制。
93
+ **导入**:`org.dromara.common.sensitive.annotation.Sensitive`
178
94
 
179
95
  ### 脱敏策略
180
96
 
181
- | 策略 | 说明 | 效果示例 |
182
- |------|------|---------|
183
- | `ID_CARD` | 身份证 | 110397198608215431 110***5431 |
184
- | `PHONE` | 手机号 | 17640125371 176****5371 |
185
- | `EMAIL` | 邮箱 | test@example.com t**@example.com |
186
- | `BANK_CARD` | 银行卡 | 6222456952351452853 6222***2853 |
187
- | `CHINESE_NAME` | 中文名 | 张三 张* |
188
- | `ADDRESS` | 地址 | 北京市朝阳区某街道 → 北京市朝阳区**** |
189
- | `FIXED_PHONE` | 固定电话 | 010-12345678 → 010****5678 |
190
- | `PASSWORD` | 密码 | ****** |
191
- | `IPV4` | IPv4地址 | 192.168.1.1 → 192.*.*.* |
192
- | `IPV6` | IPv6地址 | 2001:0db8:... → 2001:*:*:*:*:*:*:* |
193
- | `USER_ID` | 用户ID | 0 |
194
- | `CAR_LICENSE` | 车牌号 | 京A12345 → 京A1***5 |
195
- | `FIRST_MASK` | 只显示第一个字符 | abcdef → a***** |
196
- | `STRING_MASK` | 通用字符串脱敏 | abcdefghij → abcd****ghij |
197
- | `MASK_HIGH_SECURITY` | 高安全级别脱敏 | token → to******en |
198
- | `CLEAR` | 清空为空字符串 | abc → "" |
199
- | `CLEAR_TO_NULL` | 清空为null | abc → null |
200
-
201
- ### 使用示例
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` | "" |
202
104
 
203
105
  ```java
204
- import org.dromara.common.sensitive.annotation.Sensitive;
205
- import org.dromara.common.sensitive.core.SensitiveStrategy;
206
-
207
106
  public class UserVo {
208
-
209
- private Long id;
210
- private String name;
211
-
212
- // ✅ 手机号脱敏(所有人看脱敏数据)
107
+ // 所有人看脱敏数据
213
108
  @Sensitive(strategy = SensitiveStrategy.PHONE)
214
109
  private String phone;
215
110
 
216
- // 身份证脱敏,admin角色可查看原数据
111
+ // admin 角色可查看原数据
217
112
  @Sensitive(strategy = SensitiveStrategy.ID_CARD, roleKey = {"admin"})
218
113
  private String idCard;
219
114
 
220
- // ✅ 邮箱脱敏,需要用户详情权限才能看原数据
115
+ // 需要权限才能看原数据
221
116
  @Sensitive(strategy = SensitiveStrategy.EMAIL, perms = {"system:user:detail"})
222
117
  private String email;
223
-
224
- // ✅ 银行卡脱敏,admin角色或有权限都可查看
225
- @Sensitive(strategy = SensitiveStrategy.BANK_CARD,
226
- roleKey = {"admin"},
227
- perms = {"finance:account:query"})
228
- private String bankCard;
229
118
  }
230
119
  ```
231
120
 
232
- ### 注解参数
233
-
234
- | 参数 | 类型 | 默认值 | 说明 |
235
- |------|------|--------|------|
236
- | `strategy` | SensitiveStrategy | 必填 | 脱敏策略 |
237
- | `roleKey` | String[] | {} | 可查看原数据的角色 |
238
- | `perms` | String[] | {} | 可查看原数据的权限 |
239
-
240
- **权限控制逻辑**:
241
- - `roleKey` 和 `perms` 都为空:所有人都看脱敏数据
242
- - 满足任一 `roleKey` **或** 任一 `perms`:可查看原数据
243
- - 两者是 **OR** 关系,不是 AND
121
+ **权限逻辑**:roleKey 和 perms 都为空 = 全部脱敏;满足任一 roleKey **或** 任一 perms = 可查看原数据(OR 关系)。
244
122
 
245
123
  ---
246
124
 
247
125
  ## 4. @EncryptField - 字段加密
248
126
 
249
- ### 作用
250
- 在数据库级别对敏感字段进行加密存储,读取时自动解密。支持多种加密算法。
251
-
252
- ### 支持的算法
127
+ **导入**:`org.dromara.common.encrypt.annotation.EncryptField`
253
128
 
254
- | 算法 | 说明 | 性能 | 安全性 | 适用场景 |
255
- |------|------|------|--------|---------|
256
- | `BASE64` | BASE64编码 | | | 简单数据保护 |
257
- | `AES` | AES对称加密 | | | 生产环境推荐 |
258
- | `RSA` | RSA非对称加密 | | | 高安全需求 |
259
- | `SM2` | SM2非对称加密 | 低 | 高 | 国密要求 |
260
- | `SM4` | SM4对称加密 | 中 | 高 | 国密要求 |
261
-
262
- ### 使用示例
129
+ | 算法 | 说明 | 算法 | 说明 |
130
+ |------|------|------|------|
131
+ | `BASE64` | 编码(低安全) | `AES` | 对称加密(推荐) |
132
+ | `RSA` | 非对称(高安全) | `SM2` | 国密非对称 |
133
+ | `SM4` | 国密对称 | | |
263
134
 
264
135
  ```java
265
- import org.dromara.common.encrypt.annotation.EncryptField;
266
- import org.dromara.common.encrypt.enums.AlgorithmType;
267
-
268
136
  @Data
269
137
  @TableName("test_demo")
270
138
  public class TestDemo extends BaseEntity {
271
-
272
- private Long id;
273
-
274
- // ✅ AES加密(使用yml配置的秘钥)
139
+ // AES 加密(使用 yml 全局秘钥)
275
140
  @EncryptField(algorithm = AlgorithmType.AES)
276
- private String aesField;
141
+ private String phone;
277
142
 
278
- // RSA加密(指定公私钥)
143
+ // RSA 加密(指定公私钥)
279
144
  @EncryptField(algorithm = AlgorithmType.RSA,
280
- privateKey = "MIICdQIBADANB...",
281
- publicKey = "MFkwEwYHKoZI...")
282
- private String rsaField;
145
+ privateKey = "MIICdQ...", publicKey = "MFkwEw...")
146
+ private String idCard;
283
147
 
284
- // 使用默认配置
148
+ // 使用 yml 默认配置
285
149
  @EncryptField
286
- private String defaultField;
287
-
288
- // ❌ 不加密字段 - 无需添加注解
289
- private String normalField;
150
+ private String secretField;
290
151
  }
291
152
  ```
292
153
 
293
- ### 配置文件(application.yml)
154
+ **配置**:
294
155
 
295
156
  ```yaml
296
157
  mybatis-encryptor:
297
- # 是否开启加密
298
158
  enable: false
299
- # 默认加密算法:BASE64 | AES | RSA | SM2 | SM4
300
- algorithm: BASE64
301
- # 编码方式:BASE64 | HEX
302
- encode: BASE64
303
- # AES/SM4 对称算法秘钥(16字符)
304
- password: your-secret-key-16-chars
305
- # RSA/SM2 公私钥
306
- publicKey: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJnNwrj4hi/...
307
- privateKey: MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6...
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 私钥
308
164
  ```
309
165
 
310
- ### 注解参数
311
-
312
- | 参数 | 类型 | 默认值 | 说明 |
313
- |------|------|--------|------|
314
- | `algorithm` | AlgorithmType | DEFAULT | 加密算法 |
315
- | `password` | String | "" | 对称算法秘钥 |
316
- | `publicKey` | String | "" | 非对称算法公钥 |
317
- | `privateKey` | String | "" | 非对称算法私钥 |
318
- | `encode` | EncodeType | DEFAULT | 编码方式 |
319
-
320
166
  ---
321
167
 
322
168
  ## 5. @ApiEncrypt - 接口加密
323
169
 
324
- ### 作用
325
- 对接口的请求和响应进行加密处理,确保数据在网络传输中的安全性。
326
-
327
- ### 使用示例
170
+ **导入**:`org.dromara.common.encrypt.annotation.ApiEncrypt`
328
171
 
329
172
  ```java
330
- import org.dromara.common.encrypt.annotation.ApiEncrypt;
331
-
332
- @RestController
333
- @RequestMapping("/api/user")
334
- public class UserController {
335
-
336
- // ✅ 加密响应数据
337
- @ApiEncrypt(response = true)
338
- @GetMapping("/{id}")
339
- public R<UserVo> getUser(@PathVariable Long id) {
340
- // 返回的数据会被自动加密
341
- return R.ok(userService.getById(id));
342
- }
343
-
344
- // ✅ 不加密响应(默认)
345
- @GetMapping("/public")
346
- public R<List<PublicVo>> getPublicData() { }
347
- }
173
+ // 加密响应数据
174
+ @ApiEncrypt(response = true)
175
+ @GetMapping("/{id}")
176
+ public R<UserVo> getUser(@PathVariable Long id) { }
348
177
  ```
349
178
 
350
- ### 配置文件(application.yml)
179
+ | 参数 | 类型 | 默认值 | 说明 |
180
+ |------|------|--------|------|
181
+ | `response` | boolean | false | 是否加密响应 |
182
+
183
+ **配置**:
351
184
 
352
185
  ```yaml
353
186
  api-decrypt:
354
- # 是否开启接口加密
355
187
  enabled: true
356
- # 加密头标识
357
188
  headerFlag: encrypt-key
358
- # 响应加密公钥(客户端使用私钥解密)
359
- publicKey: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJnNwrj4hi/y3CCJu868ghCG5dUj8...
360
- # 请求解密私钥(服务端使用私钥解密客户端加密的数据)
361
- privateKey: MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqhHyZfSsYouqNxaY7...
189
+ publicKey: MFwwDQ... # 响应加密公钥
190
+ privateKey: MIIBVAIBADANBg... # 请求解密私钥
362
191
  ```
363
192
 
364
- ### 注解参数
365
-
366
- | 参数 | 类型 | 默认值 | 说明 |
367
- |------|------|--------|------|
368
- | `response` | boolean | false | 是否加密响应 |
369
-
370
193
  ---
371
194
 
372
195
  ## 6. @DataPermission - 数据权限
373
196
 
374
- ### 作用
375
- 在 SQL 查询时自动拼接数据权限过滤条件,实现部门级或用户级数据隔离(行级权限)。
376
-
377
- ### 使用示例
197
+ **导入**:`org.dromara.common.mybatis.annotation.DataPermission`、`@DataColumn`
378
198
 
379
199
  ```java
380
- import org.dromara.common.mybatis.annotation.DataPermission;
381
- import org.dromara.common.mybatis.annotation.DataColumn;
382
-
383
200
  public interface OrderMapper extends BaseMapperPlus<Order, OrderVo> {
384
201
 
385
- // ✅ 类级别配置:按部门和创建人隔离数据
202
+ // 按部门+创建人隔离
386
203
  @DataPermission({
387
204
  @DataColumn(key = "deptName", value = "dept_id"),
388
205
  @DataColumn(key = "userName", value = "create_by")
389
206
  })
390
- default Page<OrderVo> selectPageOrderList(Page<Order> page, Wrapper<Order> queryWrapper) {
391
- return this.selectVoPage(page, queryWrapper);
207
+ default Page<OrderVo> selectPageOrderList(Page<Order> page, Wrapper<Order> wrapper) {
208
+ return this.selectVoPage(page, wrapper);
392
209
  }
393
210
 
394
- // ✅ 方法级别配置:覆盖类级别设置
395
- @DataPermission({
396
- @DataColumn(key = "deptName", value = "create_dept")
397
- })
398
- List<OrderVo> selectByDept(Long deptId);
399
-
400
- // ✅ 指定权限标识:拥有此权限的角色不拼接过滤条件
401
- @DataPermission({
402
- @DataColumn(key = "deptName", value = "dept_id", permission = "order:all")
403
- })
404
- List<OrderVo> selectAllOrders();
405
-
406
- // ✅ 使用表别名
211
+ // 使用表别名
407
212
  @DataPermission({
408
213
  @DataColumn(key = "deptName", value = "d.dept_id"),
409
214
  @DataColumn(key = "userName", value = "u.create_by")
410
215
  })
411
- List<OrderVo> selectWithJoin(@Param(Constants.WRAPPER) Wrapper<Order> queryWrapper);
216
+ List<OrderVo> selectWithJoin(@Param(Constants.WRAPPER) Wrapper<Order> wrapper);
412
217
  }
413
218
  ```
414
219
 
415
- ### 注解参数
416
-
417
- **@DataPermission**
220
+ **@DataColumn 参数**:
418
221
 
419
- | 参数 | 类型 | 说明 |
420
- |------|------|------|
421
- | `value` | DataColumn[] | **必填**,数据权限配置数组 |
422
- | `joinStr` | String | SQL连接符(OR/AND),默认为空 |
222
+ | 参数 | 默认值 | 说明 |
223
+ |------|--------|------|
224
+ | `key` | "deptName" | 占位符关键字 |
225
+ | `value` | "dept_id" | 替换的字段名 |
226
+ | `permission` | "" | 拥有此权限则不过滤 |
423
227
 
424
- **@DataColumn**
425
-
426
- | 参数 | 类型 | 默认值 | 说明 |
427
- |------|------|--------|------|
428
- | `key` | String[] | "deptName" | 占位符关键字 |
429
- | `value` | String[] | "dept_id" | 替换的字段名 |
430
- | `permission` | String | "" | 权限标识(拥有此权限不过滤) |
431
-
432
- ### 数据权限范围
433
-
434
- 系统支持的权限范围:
435
- 1. **全部数据** - 无过滤条件
436
- 2. **本部门数据** - 仅查看本部门数据
437
- 3. **本部门及以下** - 本部门 + 所有子部门数据
438
- 4. **仅本人数据** - 只看自己创建的数据
439
- 5. **自定义权限** - 根据指定权限控制
228
+ **权限范围**:全部数据 / 本部门 / 本部门及以下 / 仅本人 / 自定义。
440
229
 
441
230
  ---
442
231
 
443
- ## 最佳实践
444
-
445
- ### 1. 限流 + 防重复提交组合
232
+ ## 七、组合使用
446
233
 
447
234
  ```java
448
- @RestController
449
- @RequestMapping("/order")
450
- public class OrderController {
451
-
452
- // ✅ 同时使用限流 + 防重复提交 + 日志
453
- @RateLimiter(time = 60, count = 10, limitType = LimitType.IP)
454
- @RepeatSubmit(interval = 10, timeUnit = TimeUnit.SECONDS)
455
- @Log(title = "订单", businessType = BusinessType.INSERT)
456
- @PostMapping()
457
- public R<Long> addOrder(@Validated @RequestBody OrderBo bo) {
458
- return R.ok(orderService.add(bo));
459
- }
460
- }
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) { }
461
241
  ```
462
242
 
463
- ### 2. VO层脱敏示例
464
-
465
- ```java
466
- public class UserDetailVo {
467
-
468
- private Long id;
469
-
470
- // 脱敏:手机号
471
- @Sensitive(strategy = SensitiveStrategy.PHONE)
472
- private String phone;
473
-
474
- // 脱敏:身份证(admin角色可查看)
475
- @Sensitive(strategy = SensitiveStrategy.ID_CARD, roleKey = {"admin"})
476
- private String idCard;
477
-
478
- // 脱敏:邮箱(需要权限才能查看原数据)
479
- @Sensitive(strategy = SensitiveStrategy.EMAIL, perms = {"system:user:detail"})
480
- private String email;
481
-
482
- // 脱敏:银行卡
483
- @Sensitive(strategy = SensitiveStrategy.BANK_CARD)
484
- private String bankCard;
485
- }
486
- ```
487
-
488
- ### 3. Entity层字段加密
489
-
490
243
  ```java
491
- @Data
244
+ // 数据保护分层:Entity 加密存储 + VO 脱敏展示
492
245
  @TableName("sys_user")
493
246
  public class SysUser extends TenantEntity {
494
-
495
- private Long id;
496
- private String username;
497
-
498
- // ✅ 加密存储手机号
499
247
  @EncryptField(algorithm = AlgorithmType.AES)
500
- private String phone;
248
+ private String phone; // 存储时加密
249
+ }
501
250
 
502
- // 加密存储身份证
503
- @EncryptField(algorithm = AlgorithmType.AES)
504
- private String idCard;
251
+ public class UserVo {
252
+ @Sensitive(strategy = SensitiveStrategy.PHONE)
253
+ private String phone; // 序列化时脱敏
505
254
  }
506
255
  ```
507
256
 
508
257
  ---
509
258
 
510
- ## 常见错误
511
-
512
- ### ❌ 不要做
259
+ ## 八、常见错误
513
260
 
514
261
  ```java
515
- // 错误1:RateLimiter 用在 Service 方法上(无效)
262
+ // ❌ @RateLimiter 用在 Service 方法上(无效,只能 Controller)
516
263
  @Service
517
264
  public class XxxService {
518
- @RateLimiter(...) // ❌ 无效!只能用在 Controller
265
+ @RateLimiter(...) // 无效!
519
266
  public void doSomething() { }
520
267
  }
521
268
 
522
- // 错误2:@DataPermission 未配置 @DataColumn
523
- @DataPermission // ❌ 空注解无效!必须至少有一个 @DataColumn
269
+ // ❌ @DataPermission 未配置 @DataColumn
270
+ @DataPermission // 空注解无效!
524
271
  public interface UserMapper { }
525
272
 
526
- // 错误3:@Sensitive @EncryptField 混淆
527
- // @Sensitive 是序列化脱敏(VO层)
528
- // @EncryptField 是数据库加密(Entity层)
529
- // 不应该在 Entity 中使用 @Sensitive
530
- ```
531
-
532
- ### ✅ 正确做法
273
+ // ❌ @Sensitive 用在 Entity 上(应在 VO 上)
274
+ // @EncryptField 用在 VO 上(应在 Entity 上)
533
275
 
534
- ```java
535
- // 正确1:限流只能用在 Controller
536
- @RestController
537
- public class XxxController {
538
- @RateLimiter(...) // ✅
539
- @GetMapping("/test")
540
- public R<Void> test() { }
541
- }
542
-
543
- // 正确2:@DataPermission 用在 Mapper 接口或方法上(支持类/方法两级)
544
- @DataPermission({ // ✅ 类级别:所有方法默认使用此配置
545
- @DataColumn(key = "deptName", value = "dept_id")
546
- })
276
+ // ✅ @DataPermission 支持类级别 + 方法级别(方法覆盖类)
277
+ @DataPermission({ @DataColumn(key = "deptName", value = "dept_id") })
547
278
  public interface UserMapper {
548
- @DataPermission({ // 方法级别:覆盖类级别配置
549
- @DataColumn(key = "deptName", value = "dept_id"),
550
- @DataColumn(key = "userName", value = "create_by")
551
- })
279
+ @DataPermission({ /* 方法级覆盖 */ })
552
280
  List<UserVo> selectList();
553
281
  }
554
-
555
- // 正确3:分层使用注解
556
- @Entity
557
- public class SysUser {
558
- @EncryptField(algorithm = AlgorithmType.AES) // 存储时加密
559
- private String phone;
560
- }
561
-
562
- @VO
563
- public class UserVo {
564
- @Sensitive(strategy = SensitiveStrategy.PHONE) // 序列化时脱敏
565
- private String phone;
566
- }
567
282
  ```
568
283
 
569
284
  ---
570
285
 
571
- ## 使用检查清单
572
-
573
- 使用后端注解前必须检查:
286
+ ## 九、参考实现
574
287
 
575
- - [ ] **使用 @RateLimiter 吗**?是否选择了正确的 `limitType`?
576
- - [ ] **使用 @RepeatSubmit 吗**?新增/修改/支付 必须添加!
577
- - [ ] **使用 @Sensitive 吗**?VO 中的敏感字段应该脱敏
578
- - [ ] **使用 @EncryptField 吗**?Entity 中的敏感字段应该加密
579
- - [ ] **使用 @DataPermission 吗**?Mapper 需要数据隔离时必须添加!
580
- - [ ] **所有配置都在 yml 中**?Redis 密钥、加密算法等
581
- - [ ] **是否正确处理了异常**?脱敏/加密异常不应该导致请求失败
582
- - [ ] **是否测试了权限控制**?不同角色应该看到不同数据
583
- - [ ] **依赖是否齐全**?Redis、MyBatis-Plus 等必需库
584
- - [ ] **导入路径是否正确**?使用 `org.dromara.*` 包名
585
-
586
- ---
587
-
588
- ## 快速参考
589
-
590
- ### 注解速查表
591
-
592
- ```
593
- @RateLimiter → 接口限流(Controller 方法)
594
- @RepeatSubmit → 防重复提交(POST/PUT 方法)
595
- @Sensitive → 数据脱敏(VO 字段)
596
- @EncryptField → 字段加密(Entity 字段)
597
- @ApiEncrypt → 接口加密(Controller 方法)
598
- @DataPermission → 数据权限(Mapper 接口)
599
- ```
600
-
601
- ### 组合使用速查
602
-
603
- ```
604
- 接口防护: @RateLimiter + @RepeatSubmit
605
- 数据保护: @EncryptField + @Sensitive + @ApiEncrypt
606
- 数据隔离: @DataPermission(Mapper)
607
- ```
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` |
608
294
 
609
- ### 配置位置速查
295
+ **配置位置**:
610
296
 
611
297
  ```
612
298
  application.yml:
613
- - mybatis-encryptor.* → @EncryptField 全局配置
614
- - api-decrypt.* → @ApiEncrypt 全局配置
615
- - spring.data.redis.* → @RateLimiter/@RepeatSubmit 依赖(Redisson 客户端)
616
- ```
617
-
618
- ---
619
-
620
- ## 参考实现
621
-
622
- 查看框架中的完整实现:
623
-
624
- - **限流示例**: `org.dromara.demo.controller.RedisRateLimiterController`(@RateLimiter 详细用法)
625
- - **脱敏示例**: `org.dromara.demo.controller.TestSensitiveController`(@Sensitive 各策略)
626
- - **防重示例**: 任何 POST/PUT 方法都有 @RepeatSubmit
627
- - **加密示例**: `org.dromara.demo.domain.TestDemo`(@EncryptField 使用)
628
- - **数据权限**: `org.dromara.system.mapper.SysUserMapper`(@DataPermission 使用)
629
- - **对象映射**: 系统 BO/VO 类中的 `@AutoMapper` 注解(见 crud-development 技能)
630
-
631
- **特别注意**:上述参考代码是本项目的标准实现,严格遵循三层架构和后端规范。
632
-
633
- ---
634
-
635
- ## 关键配置
636
-
637
- ```yaml
638
- # Redis 配置(必须,限流和防重复依赖)
639
- # ⚠️ Spring Boot 3 使用 spring.data.redis(非 spring.redis)
640
- # 本项目使用 Redisson 客户端(非 Jedis/Lettuce),连接池由 Redisson 管理
641
- spring:
642
- data:
643
- redis:
644
- host: localhost
645
- port: 6379
646
- password:
647
- timeout: 10s
648
-
649
- # 字段加密配置
650
- mybatis-encryptor:
651
- enable: false
652
- algorithm: BASE64
653
- encode: BASE64
654
- password: your-secret-key
655
- publicKey: your-public-key
656
- privateKey: your-private-key
657
-
658
- # 接口加密配置
659
- api-decrypt:
660
- enabled: true
661
- headerFlag: encrypt-key
662
- publicKey: your-public-key
663
- privateKey: your-private-key
299
+ mybatis-encryptor.* → @EncryptField 全局配置
300
+ api-decrypt.* → @ApiEncrypt 全局配置
301
+ spring.data.redis.* → @RateLimiter/@RepeatSubmit 依赖
664
302
  ```