ai-engineering-init 1.3.4 → 1.4.1

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 (227) 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/cursor-skill-eval.js +53 -1
  153. package/.cursor/hooks.json +3 -3
  154. package/.cursor/skills/add-skill/SKILL.md +79 -32
  155. package/.cursor/skills/api-development/SKILL.md +83 -377
  156. package/.cursor/skills/architecture-design/SKILL.md +138 -632
  157. package/.cursor/skills/backend-annotations/SKILL.md +134 -506
  158. package/.cursor/skills/banana-image/SKILL.md +10 -3
  159. package/.cursor/skills/brainstorm/SKILL.md +103 -535
  160. package/.cursor/skills/bug-detective/SKILL.md +147 -1097
  161. package/.cursor/skills/bug-detective/references/error-patterns.md +242 -0
  162. package/.cursor/skills/code-patterns/SKILL.md +116 -426
  163. package/.cursor/skills/code-patterns/references/leniu-code-patterns.md +87 -0
  164. package/.cursor/skills/crud-development/SKILL.md +64 -304
  165. package/.cursor/skills/data-permission/SKILL.md +105 -412
  166. package/.cursor/skills/data-permission/references/custom-data-scope.md +90 -0
  167. package/.cursor/skills/file-oss-management/SKILL.md +106 -714
  168. package/.cursor/skills/file-oss-management/references/entities.md +105 -0
  169. package/.cursor/skills/file-oss-management/references/service-impl.md +104 -0
  170. package/.cursor/skills/git-workflow/SKILL.md +27 -5
  171. package/.cursor/skills/leniu-api-development/SKILL.md +142 -626
  172. package/.cursor/skills/leniu-api-development/references/real-examples.md +273 -0
  173. package/.cursor/skills/leniu-architecture-design/SKILL.md +176 -391
  174. package/.cursor/skills/leniu-backend-annotations/SKILL.md +132 -519
  175. package/.cursor/skills/leniu-brainstorm/SKILL.md +132 -541
  176. package/.cursor/skills/leniu-brainstorm/references/business-scenarios.md +162 -0
  177. package/.cursor/skills/leniu-crud-development/SKILL.md +232 -938
  178. package/.cursor/skills/leniu-crud-development/references/templates.md +597 -0
  179. package/.cursor/skills/leniu-customization-location/SKILL.md +410 -0
  180. package/.cursor/skills/leniu-data-permission/SKILL.md +70 -0
  181. package/.cursor/skills/leniu-java-code-style/SKILL.md +510 -0
  182. package/.cursor/skills/leniu-java-entity/SKILL.md +76 -590
  183. package/.cursor/skills/leniu-java-entity/references/templates.md +237 -0
  184. package/.cursor/skills/leniu-java-export/SKILL.md +94 -379
  185. package/.cursor/skills/leniu-java-logging/SKILL.md +106 -709
  186. package/.cursor/skills/leniu-java-logging/references/data-mask.md +46 -0
  187. package/.cursor/skills/leniu-java-logging/references/logging-scenarios.md +113 -0
  188. package/.cursor/skills/leniu-java-mybatis/SKILL.md +73 -446
  189. package/.cursor/skills/leniu-java-mybatis/references/report-mapper.md +88 -0
  190. package/.cursor/skills/leniu-report-customization/SKILL.md +111 -365
  191. package/.cursor/skills/leniu-report-customization/references/table-fields.md +93 -0
  192. package/.cursor/skills/leniu-report-standard-customization/SKILL.md +111 -334
  193. package/.cursor/skills/leniu-report-standard-customization/references/analysis-module.md +64 -0
  194. package/.cursor/skills/leniu-report-standard-customization/references/table-fields.md +113 -0
  195. package/.cursor/skills/leniu-security-guard/SKILL.md +133 -347
  196. package/.cursor/skills/mysql-debug/SKILL.md +364 -0
  197. package/.cursor/skills/openspec-apply-change/SKILL.md +10 -1
  198. package/.cursor/skills/openspec-archive-change/SKILL.md +9 -1
  199. package/.cursor/skills/openspec-bulk-archive-change/SKILL.md +9 -1
  200. package/.cursor/skills/openspec-continue-change/SKILL.md +9 -1
  201. package/.cursor/skills/openspec-explore/SKILL.md +10 -1
  202. package/.cursor/skills/openspec-ff-change/SKILL.md +9 -1
  203. package/.cursor/skills/openspec-new-change/SKILL.md +9 -1
  204. package/.cursor/skills/openspec-onboard/SKILL.md +15 -130
  205. package/.cursor/skills/openspec-sync-specs/SKILL.md +9 -1
  206. package/.cursor/skills/openspec-verify-change/SKILL.md +9 -1
  207. package/.cursor/skills/performance-doctor/SKILL.md +110 -434
  208. package/.cursor/skills/redis-cache/SKILL.md +89 -595
  209. package/.cursor/skills/redis-cache/references/listeners.md +23 -0
  210. package/.cursor/skills/scheduled-jobs/SKILL.md +88 -407
  211. package/.cursor/skills/security-guard/SKILL.md +137 -532
  212. package/.cursor/skills/security-guard/references/encrypt-config.md +103 -0
  213. package/.cursor/skills/security-guard/references/sensitive-strategies.md +42 -0
  214. package/.cursor/skills/sms-mail/SKILL.md +116 -574
  215. package/.cursor/skills/sms-mail/references/mail-config.md +88 -0
  216. package/.cursor/skills/sms-mail/references/sms-config.md +74 -0
  217. package/.cursor/skills/social-login/SKILL.md +112 -514
  218. package/.cursor/skills/social-login/references/provider-configs.md +118 -0
  219. package/.cursor/skills/tenant-management/SKILL.md +129 -444
  220. package/.cursor/skills/tenant-management/references/tenant-scenarios.md +91 -0
  221. package/.cursor/skills/test-development/SKILL.md +86 -540
  222. package/.cursor/skills/test-development/references/parameterized-examples.md +119 -0
  223. package/.cursor/skills/utils-toolkit/SKILL.md +52 -305
  224. package/.cursor/skills/utils-toolkit/references/redis-utils-api.md +56 -0
  225. package/.cursor/skills/websocket-sse/SKILL.md +105 -550
  226. package/.cursor/skills/workflow-engine/SKILL.md +147 -502
  227. package/package.json +1 -1
@@ -5,15 +5,12 @@ description: |
5
5
 
6
6
  触发场景:
7
7
  - 对象转换(BO/VO/Entity)
8
- - 字符串处理
9
- - 集合流操作
8
+ - 字符串处理、集合流操作
10
9
  - 树结构构建
11
- - 日期时间处理
12
10
  - Redis 缓存操作
13
11
  - Excel 导入导出
14
- - JSON 序列化
15
12
 
16
- 触发词:工具类、MapstructUtils、StringUtils、StreamUtils、TreeBuildUtils、DateUtils、RedisUtils、ExcelUtil、JsonUtils、LoginHelper、CollUtil、ObjectUtil、IdUtil、convert、对象转换、集合操作、树结构、缓存
13
+ 触发词:工具类、MapstructUtils、StringUtils、StreamUtils、TreeBuildUtils、DateUtils、RedisUtils、ExcelUtil、JsonUtils、LoginHelper、convert、对象转换、集合操作、树结构、缓存
17
14
 
18
15
  注意:
19
16
  - 对象转换必须使用 MapstructUtils.convert(),禁止使用 BeanUtils。
@@ -22,8 +19,6 @@ description: |
22
19
 
23
20
  # 后端工具类大全
24
21
 
25
- > 本项目是纯后端项目,本文档专注于 Java 后端工具类。
26
-
27
22
  ## 快速索引
28
23
 
29
24
  | 功能 | 工具类 | 包路径 | 常用方法 |
@@ -40,9 +35,6 @@ description: |
40
35
  | 登录用户 | `LoginHelper` | `o.d.common.satoken.utils` | `getUserId()`, `getUsername()` |
41
36
  | 业务异常 | `ServiceException` | `o.d.common.core.exception` | `throw new ServiceException()` |
42
37
  | Spring容器 | `SpringUtils` | `o.d.common.core.utils` | `getBean()` |
43
- | Hutool集合 | `CollUtil` | `cn.hutool.core.collection` | `isEmpty()`, `newArrayList()` |
44
- | Hutool对象 | `ObjectUtil` | `cn.hutool.core.util` | `isNull()`, `isEmpty()` |
45
- | ID生成 | `IdUtil` | `cn.hutool.core.util` | `getSnowflakeNextId()` |
46
38
 
47
39
  > **包路径说明**: `o.d` = `org.dromara`
48
40
 
@@ -50,42 +42,29 @@ description: |
50
42
 
51
43
  ## 1. 对象转换 - MapstructUtils(必须使用!)
52
44
 
53
- > ⚠️ **强制规范**: 禁止使用 `BeanUtils.copyProperties()`,必须使用 `MapstructUtils.convert()`
45
+ > **强制规范**: 禁止使用 `BeanUtils.copyProperties()`,必须使用 `MapstructUtils.convert()`
54
46
 
55
47
  ```java
56
48
  import org.dromara.common.core.utils.MapstructUtils;
57
49
 
58
- // 单个对象转换
50
+ // 单个对象转换
59
51
  XxxVo vo = MapstructUtils.convert(entity, XxxVo.class);
60
- Xxx entity = MapstructUtils.convert(bo, Xxx.class);
61
52
 
62
- // 集合转换
53
+ // 集合转换
63
54
  List<XxxVo> voList = MapstructUtils.convert(entityList, XxxVo.class);
64
55
 
65
- // 转换到已有对象(合并属性)
56
+ // 转换到已有对象(合并属性)
66
57
  XxxVo vo = MapstructUtils.convert(source, existingVo);
67
-
68
- // ✅ Map 转 Bean
69
- Xxx entity = MapstructUtils.convert(map, Xxx.class);
70
-
71
- // ❌ 禁止使用 BeanUtils
72
- // BeanUtils.copyProperties(source, target); // 禁止!
73
58
  ```
74
59
 
75
60
  **配合 @AutoMapper 注解**:
76
61
 
77
62
  ```java
78
- // 在 BO 类上声明映射关系
79
63
  @AutoMapper(target = Xxx.class, reverseConvertGenerate = false)
80
- public class XxxBo extends BaseEntity {
81
- // ...
82
- }
64
+ public class XxxBo extends BaseEntity { }
83
65
 
84
- // 在 VO 类上声明映射关系
85
66
  @AutoMapper(target = Xxx.class)
86
- public class XxxVo implements Serializable {
87
- // ...
88
- }
67
+ public class XxxVo implements Serializable { }
89
68
  ```
90
69
 
91
70
  ---
@@ -95,40 +74,24 @@ public class XxxVo implements Serializable {
95
74
  ```java
96
75
  import org.dromara.common.core.utils.StringUtils;
97
76
 
98
- // 判空(推荐)
99
- StringUtils.isBlank(str); // null / "" / 空白 都返回 true
100
- StringUtils.isNotBlank(str);
101
- StringUtils.isEmpty(str); // null / "" 返回 true
102
- StringUtils.isNotEmpty(str);
103
-
104
- // 格式化(占位符 {})
77
+ // 格式化(占位符 {})—— 项目特有
105
78
  StringUtils.format("用户 {} 不存在", userId);
106
- // 输出: "用户 123 不存在"
107
-
108
- // 字符串分割
109
- List<String> list = StringUtils.splitList("1,2,3"); // ["1", "2", "3"]
110
- List<String> list = StringUtils.splitList("1|2|3", "|"); // 自定义分隔符
111
- List<Long> ids = StringUtils.splitTo("1,2,3", Convert::toLong); // 转换类型
112
79
 
113
- // 字符串拼接
114
- String str = StringUtils.joinComma(list); // "1,2,3"
115
- String str = StringUtils.joinComma(array); // 数组版本
80
+ // 字符串分割/拼接 —— 项目特有
81
+ List<String> list = StringUtils.splitList("1,2,3");
82
+ List<Long> ids = StringUtils.splitTo("1,2,3", Convert::toLong);
83
+ String str = StringUtils.joinComma(list);
116
84
 
117
85
  // 驼峰转换
118
86
  StringUtils.toCamelCase("user_name"); // "userName"
119
87
  StringUtils.toUnderScoreCase("userName"); // "user_name"
120
- StringUtils.convertToCamelCase("user_name"); // "UserName" (首字母大写)
121
88
 
122
- // 截取
123
- StringUtils.substring(str, 0, 10);
124
-
125
- // 路径匹配(Ant 风格)
126
- StringUtils.isMatch("/api/**", "/api/user/list"); // true
89
+ // Ant 风格路径匹配
90
+ StringUtils.isMatch("/api/**", "/api/user/list");
127
91
  StringUtils.matches("/api/user", Arrays.asList("/api/**", "/admin/**"));
128
92
 
129
93
  // 左补零
130
- StringUtils.padl(5, 3); // "005"
131
- StringUtils.padl("ab", 5, '0'); // "000ab"
94
+ StringUtils.padl(5, 3); // "005"
132
95
  ```
133
96
 
134
97
  ---
@@ -139,40 +102,28 @@ StringUtils.padl("ab", 5, '0'); // "000ab"
139
102
  import org.dromara.common.core.utils.StreamUtils;
140
103
 
141
104
  // 过滤
142
- List<User> activeUsers = StreamUtils.filter(users, u -> "1".equals(u.getStatus()));
105
+ List<User> active = StreamUtils.filter(users, u -> "1".equals(u.getStatus()));
143
106
 
144
- // 查找第一个
145
- Optional<User> user = StreamUtils.findFirst(users, u -> u.getId().equals(id));
146
- User user = StreamUtils.findFirstValue(users, u -> u.getId().equals(id)); // 返回 null 而非 Optional
107
+ // 查找
108
+ User user = StreamUtils.findFirstValue(users, u -> u.getId().equals(id));
147
109
 
148
- // 提取属性为 List
110
+ // 提取属性
149
111
  List<Long> ids = StreamUtils.toList(users, User::getId);
150
-
151
- // 提取属性为 Set
152
112
  Set<Long> deptIds = StreamUtils.toSet(users, User::getDeptId);
153
113
 
154
- // 转为 Map(value 是元素本身)
114
+ // Map
155
115
  Map<Long, User> userMap = StreamUtils.toIdentityMap(users, User::getId);
156
-
157
- // 转为 Map(自定义 key 和 value)
158
116
  Map<Long, String> nameMap = StreamUtils.toMap(users, User::getId, User::getName);
159
117
 
160
118
  // 分组
161
- Map<Long, List<User>> deptUserMap = StreamUtils.groupByKey(users, User::getDeptId);
162
-
163
- // 双层分组
164
- Map<Long, Map<String, List<User>>> map = StreamUtils.groupBy2Key(
165
- users, User::getDeptId, User::getStatus
166
- );
119
+ Map<Long, List<User>> grouped = StreamUtils.groupByKey(users, User::getDeptId);
167
120
 
168
121
  // 拼接字符串
169
- String names = StreamUtils.join(users, User::getName); // "张三,李四,王五"
170
- String names = StreamUtils.join(users, User::getName, "|"); // "张三|李四|王五"
122
+ String names = StreamUtils.join(users, User::getName); // "张三,李四,王五"
123
+ String names = StreamUtils.join(users, User::getName, "|"); // 自定义分隔符
171
124
 
172
- // 排序
125
+ // 排序 / 合并 Map
173
126
  List<User> sorted = StreamUtils.sorted(users, Comparator.comparing(User::getCreateTime));
174
-
175
- // 合并两个 Map
176
127
  Map<Long, String> merged = StreamUtils.merge(map1, map2, (v1, v2) -> v1 + v2);
177
128
  ```
178
129
 
@@ -184,36 +135,16 @@ Map<Long, String> merged = StreamUtils.merge(map1, map2, (v1, v2) -> v1 + v2);
184
135
  import org.dromara.common.core.utils.TreeBuildUtils;
185
136
  import cn.hutool.core.lang.tree.Tree;
186
137
 
187
- // 构建树(自动检测根节点)
188
138
  List<Tree<Long>> tree = TreeBuildUtils.build(list, (node, item) -> {
189
139
  node.setId(item.getId());
190
140
  node.setParentId(item.getParentId());
191
141
  node.setName(item.getName());
192
- node.setWeight(item.getOrderNum()); // 排序
193
- // 扩展属性
142
+ node.setWeight(item.getOrderNum());
194
143
  node.putExtra("icon", item.getIcon());
195
- node.putExtra("path", item.getPath());
196
144
  });
197
145
 
198
146
  // 指定根节点 ID
199
- List<Tree<Long>> tree = TreeBuildUtils.build(list, 0L, (node, item) -> {
200
- // ...
201
- });
202
-
203
- // 多根节点树
204
- List<Tree<Long>> tree = TreeBuildUtils.buildMultiRoot(
205
- list,
206
- Item::getId,
207
- Item::getParentId,
208
- (node, item) -> {
209
- node.setId(item.getId());
210
- node.setParentId(item.getParentId());
211
- node.setName(item.getName());
212
- }
213
- );
214
-
215
- // 获取叶子节点
216
- List<Tree<Long>> leaves = TreeBuildUtils.getLeafNodes(tree);
147
+ List<Tree<Long>> tree = TreeBuildUtils.build(list, 0L, (node, item) -> { ... });
217
148
  ```
218
149
 
219
150
  ---
@@ -225,51 +156,29 @@ import org.dromara.common.core.utils.DateUtils;
225
156
  import org.dromara.common.core.enums.FormatsType;
226
157
 
227
158
  // 获取当前时间
228
- Date now = DateUtils.getNowDate();
229
- String date = DateUtils.getDate(); // "2026-01-24"
230
- String time = DateUtils.getTime(); // "2026-01-24 15:30:00"
159
+ String date = DateUtils.getDate(); // "2026-01-24"
160
+ String time = DateUtils.getTime(); // "2026-01-24 15:30:00"
231
161
 
232
- // 格式化
233
- DateUtils.formatDate(date); // "2026-01-24"
234
- DateUtils.formatDateTime(date); // "2026-01-24 15:30:00"
162
+ // 格式化 / 解析
163
+ DateUtils.formatDateTime(date);
235
164
  DateUtils.parseDateToStr(FormatsType.YYYY_MM_DD_HH_MM, date);
236
-
237
- // 解析
238
- Date date = DateUtils.parseDate("2026-01-24");
239
165
  Date date = DateUtils.parseDateTime(FormatsType.YYYY_MM_DD_HH_MM_SS, "2026-01-24 15:30:00");
240
166
 
241
167
  // 时间差
242
168
  long days = DateUtils.difference(start, end, TimeUnit.DAYS);
243
169
  String diff = DateUtils.getDatePoor(endDate, startDate); // "3天 2小时 30分钟"
244
- String diff = DateUtils.getTimeDifference(endDate, startDate); // 智能省略0值
245
170
 
246
171
  // 日期范围校验
247
- DateUtils.validateDateRange(startDate, endDate, 30, TimeUnit.DAYS); // 最大30天
172
+ DateUtils.validateDateRange(startDate, endDate, 30, TimeUnit.DAYS);
248
173
 
249
174
  // 友好时间(仿微信)
250
- DateUtils.formatFriendlyTime(date); // "刚刚" / "5分钟前" / "昨天 14:30" / "周三 10:00"
251
-
252
- // 时间段
253
- DateUtils.getTodayHour(date); // "凌晨" / "上午" / "中午" / "下午" / "晚上"
175
+ DateUtils.formatFriendlyTime(date); // "刚刚" / "5分钟前" / "昨天 14:30"
254
176
 
255
177
  // 类型转换
256
178
  Date date = DateUtils.toDate(localDateTime);
257
- Date date = DateUtils.toDate(localDate);
258
-
259
- // 路径格式
260
- DateUtils.datePath(); // "2026/01/24"
261
179
  ```
262
180
 
263
- **FormatsType 枚举**:
264
-
265
- | 枚举值 | 格式 |
266
- |-------|------|
267
- | `YYYY_MM_DD` | yyyy-MM-dd |
268
- | `YYYY_MM_DD_HH_MM_SS` | yyyy-MM-dd HH:mm:ss |
269
- | `YYYY_MM_DD_HH_MM` | yyyy-MM-dd HH:mm |
270
- | `YYYYMMDD` | yyyyMMdd |
271
- | `YYYYMMDDHHMMSS` | yyyyMMddHHmmss |
272
- | `HH_MM_SS` | HH:mm:ss |
181
+ **FormatsType 枚举**: `YYYY_MM_DD` | `YYYY_MM_DD_HH_MM_SS` | `YYYY_MM_DD_HH_MM` | `YYYYMMDD` | `YYYYMMDDHHMMSS` | `HH_MM_SS`
273
182
 
274
183
  ---
275
184
 
@@ -280,43 +189,27 @@ import org.dromara.common.core.utils.ValidatorUtils;
280
189
  import org.dromara.common.core.validate.AddGroup;
281
190
  import org.dromara.common.core.validate.EditGroup;
282
191
 
283
- // 手动校验(在 Service 层使用)
192
+ // Service 层手动校验
284
193
  ValidatorUtils.validate(bo, AddGroup.class);
285
- ValidatorUtils.validate(bo, EditGroup.class);
286
194
 
287
- // Controller 层使用 @Validated(推荐)
195
+ // Controller 层(推荐)
288
196
  @PostMapping
289
- public R<Void> add(@Validated(AddGroup.class) @RequestBody XxxBo bo) {
290
- // ...
291
- }
197
+ public R<Void> add(@Validated(AddGroup.class) @RequestBody XxxBo bo) { }
292
198
 
293
199
  @PutMapping
294
- public R<Void> edit(@Validated(EditGroup.class) @RequestBody XxxBo bo) {
295
- // ...
296
- }
200
+ public R<Void> edit(@Validated(EditGroup.class) @RequestBody XxxBo bo) { }
297
201
  ```
298
202
 
299
203
  **BO 类校验注解**:
300
204
 
301
205
  ```java
302
206
  public class XxxBo extends BaseEntity {
303
-
304
207
  @NotNull(message = "ID不能为空", groups = { EditGroup.class })
305
208
  private Long id;
306
209
 
307
210
  @NotBlank(message = "名称不能为空", groups = { AddGroup.class, EditGroup.class })
308
211
  @Size(max = 100, message = "名称长度不能超过100个字符")
309
212
  private String name;
310
-
311
- @Email(message = "邮箱格式不正确")
312
- private String email;
313
-
314
- @Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确")
315
- private String phone;
316
-
317
- @Min(value = 0, message = "数量不能小于0")
318
- @Max(value = 9999, message = "数量不能大于9999")
319
- private Integer count;
320
213
  }
321
214
  ```
322
215
 
@@ -324,59 +217,35 @@ public class XxxBo extends BaseEntity {
324
217
 
325
218
  ## 7. Redis 缓存 - RedisUtils
326
219
 
220
+ > 详细 API 见 `references/redis-utils-api.md`
221
+
327
222
  ```java
328
223
  import org.dromara.common.redis.utils.RedisUtils;
329
- import java.time.Duration;
330
224
 
331
225
  // 基本操作
332
- RedisUtils.setCacheObject("key", value); // 永久
333
- RedisUtils.setCacheObject("key", value, Duration.ofMinutes(30)); // 30分钟过期
226
+ RedisUtils.setCacheObject("key", value);
227
+ RedisUtils.setCacheObject("key", value, Duration.ofMinutes(30));
334
228
  RedisUtils.getCacheObject("key");
335
229
  RedisUtils.deleteObject("key");
336
230
  RedisUtils.hasKey("key");
337
- RedisUtils.expire("key", 3600); // 设置过期时间(秒)
338
231
 
339
232
  // 条件设置
340
- RedisUtils.setObjectIfAbsent("key", value, Duration.ofMinutes(5)); // 不存在才设置
341
- RedisUtils.setObjectIfExists("key", value, Duration.ofMinutes(5)); // 存在才设置
233
+ RedisUtils.setObjectIfAbsent("key", value, Duration.ofMinutes(5));
342
234
 
343
- // List 操作
235
+ // List / Set / Map 操作
344
236
  RedisUtils.setCacheList("listKey", dataList);
345
- RedisUtils.addCacheList("listKey", item);
346
- List<T> list = RedisUtils.getCacheList("listKey");
347
- List<T> range = RedisUtils.getCacheListRange("listKey", 0, 10);
348
-
349
- // Set 操作
350
- RedisUtils.setCacheSet("setKey", dataSet);
351
- RedisUtils.addCacheSet("setKey", item);
352
- Set<T> set = RedisUtils.getCacheSet("setKey");
353
-
354
- // Map/Hash 操作
355
237
  RedisUtils.setCacheMap("mapKey", dataMap);
356
238
  RedisUtils.setCacheMapValue("mapKey", "field", value);
357
- T value = RedisUtils.getCacheMapValue("mapKey", "field");
358
- Map<String, T> map = RedisUtils.getCacheMap("mapKey");
359
- RedisUtils.delCacheMapValue("mapKey", "field");
360
239
 
361
240
  // 原子操作
362
- RedisUtils.setAtomicValue("counter", 0);
363
- long val = RedisUtils.incrAtomicValue("counter"); // +1
364
- long val = RedisUtils.decrAtomicValue("counter"); // -1
365
- long val = RedisUtils.getAtomicValue("counter");
366
-
367
- // 批量操作
368
- Collection<String> keys = RedisUtils.keys("user:*");
369
- RedisUtils.deleteKeys("temp:*");
241
+ long val = RedisUtils.incrAtomicValue("counter");
370
242
 
371
243
  // 发布订阅
372
244
  RedisUtils.publish("channel", message);
373
- RedisUtils.subscribe("channel", Message.class, msg -> {
374
- // 处理消息
375
- });
245
+ RedisUtils.subscribe("channel", Message.class, msg -> { });
376
246
 
377
247
  // 限流
378
248
  long remaining = RedisUtils.rateLimiter("api:user:list", RateType.OVERALL, 100, 60);
379
- // 每60秒最多100次,返回剩余次数,-1表示被限流
380
249
  ```
381
250
 
382
251
  ---
@@ -386,23 +255,14 @@ long remaining = RedisUtils.rateLimiter("api:user:list", RateType.OVERALL, 100,
386
255
  ```java
387
256
  import org.dromara.common.satoken.utils.LoginHelper;
388
257
 
389
- // 获取当前登录用户信息
390
258
  Long userId = LoginHelper.getUserId();
391
259
  String username = LoginHelper.getUsername();
392
260
  Long deptId = LoginHelper.getDeptId();
393
261
  String tenantId = LoginHelper.getTenantId();
394
262
  LoginUser loginUser = LoginHelper.getLoginUser();
395
-
396
- // 判断登录状态
397
263
  boolean isLogin = LoginHelper.isLogin();
398
-
399
- // 判断是否超级管理员
400
264
  boolean isSuperAdmin = LoginHelper.isSuperAdmin();
401
- boolean isSuperAdmin = LoginHelper.isSuperAdmin(userId);
402
-
403
- // 判断是否租户管理员
404
265
  boolean isTenantAdmin = LoginHelper.isTenantAdmin();
405
- boolean isTenantAdmin = LoginHelper.isTenantAdmin(rolePermission);
406
266
  ```
407
267
 
408
268
  ---
@@ -412,17 +272,9 @@ boolean isTenantAdmin = LoginHelper.isTenantAdmin(rolePermission);
412
272
  ```java
413
273
  import org.dromara.common.core.exception.ServiceException;
414
274
 
415
- // 抛出业务异常
416
275
  throw new ServiceException("用户不存在");
417
276
  throw new ServiceException("用户 {} 不存在", userId);
418
-
419
- // 条件判断
420
- if (user == null) {
421
- throw new ServiceException("用户不存在");
422
- }
423
-
424
- // 带错误码
425
- throw new ServiceException("用户不存在", 500);
277
+ throw new ServiceException("用户不存在", 500); // 带错误码
426
278
  ```
427
279
 
428
280
  ---
@@ -432,7 +284,7 @@ throw new ServiceException("用户不存在", 500);
432
284
  ```java
433
285
  import org.dromara.common.excel.utils.ExcelUtil;
434
286
 
435
- // Controller 中导出
287
+ // 导出
436
288
  @PostMapping("/export")
437
289
  public void export(XxxBo bo, HttpServletResponse response) {
438
290
  List<XxxVo> list = xxxService.queryList(bo);
@@ -443,7 +295,6 @@ public void export(XxxBo bo, HttpServletResponse response) {
443
295
  @PostMapping("/import")
444
296
  public R<Void> importData(@RequestPart("file") MultipartFile file) throws Exception {
445
297
  List<XxxVo> list = ExcelUtil.importExcel(file.getInputStream(), XxxVo.class);
446
- // 处理导入数据
447
298
  return R.ok();
448
299
  }
449
300
  ```
@@ -452,19 +303,12 @@ public R<Void> importData(@RequestPart("file") MultipartFile file) throws Except
452
303
 
453
304
  ```java
454
305
  public class XxxVo implements Serializable {
455
-
456
306
  @ExcelProperty(value = "ID")
457
307
  private Long id;
458
308
 
459
- @ExcelProperty(value = "名称")
460
- private String name;
461
-
462
309
  @ExcelProperty(value = "状态", converter = ExcelDictConvert.class)
463
310
  @ExcelDictFormat(dictType = "sys_normal_disable")
464
311
  private String status;
465
-
466
- @ExcelProperty(value = "创建时间")
467
- private Date createTime;
468
312
  }
469
313
  ```
470
314
 
@@ -475,92 +319,24 @@ public class XxxVo implements Serializable {
475
319
  ```java
476
320
  import org.dromara.common.json.utils.JsonUtils;
477
321
 
478
- // 对象转 JSON
479
322
  String json = JsonUtils.toJsonString(obj);
480
-
481
- // JSON 转对象
482
323
  User user = JsonUtils.parseObject(json, User.class);
483
-
484
- // JSON 转 List
485
324
  List<User> list = JsonUtils.parseArray(json, User.class);
486
-
487
- // JSON 转 Map
488
325
  Map<String, Object> map = JsonUtils.parseMap(json);
489
326
  ```
490
327
 
491
328
  ---
492
329
 
493
- ## 12. Hutool 常用工具
494
-
495
- ```java
496
- import cn.hutool.core.collection.CollUtil;
497
- import cn.hutool.core.util.ObjectUtil;
498
- import cn.hutool.core.util.StrUtil;
499
- import cn.hutool.core.util.IdUtil;
500
- import cn.hutool.crypto.SecureUtil;
501
-
502
- // 集合判空
503
- CollUtil.isEmpty(list);
504
- CollUtil.isNotEmpty(list);
505
- CollUtil.newArrayList(1, 2, 3);
506
- CollUtil.newHashSet("a", "b");
507
-
508
- // 对象判空
509
- ObjectUtil.isNull(obj);
510
- ObjectUtil.isNotNull(obj);
511
- ObjectUtil.isEmpty(obj); // null / 空字符串 / 空集合
512
- ObjectUtil.defaultIfNull(obj, defaultValue);
513
-
514
- // ID 生成
515
- long snowflakeId = IdUtil.getSnowflakeNextId(); // 雪花ID(推荐)
516
- String uuid = IdUtil.simpleUUID(); // 无横线 UUID
517
- String uuid = IdUtil.randomUUID(); // 标准 UUID
518
- String nanoId = IdUtil.nanoId(); // NanoID
519
-
520
- // 加密
521
- String md5 = SecureUtil.md5("password");
522
- String sha256 = SecureUtil.sha256("password");
523
-
524
- // Base64
525
- import cn.hutool.core.codec.Base64;
526
- String encoded = Base64.encode("data");
527
- String decoded = Base64.decodeStr(encoded);
528
- ```
529
-
530
- ---
531
-
532
- ## 常用正则表达式
533
-
534
- ```java
535
- // 手机号
536
- String phoneReg = "^1[3-9]\\d{9}$";
537
-
538
- // 邮箱
539
- String emailReg = "^[\\w-]+(\\.[\\w-]+)*@[\\w-]+(\\.[\\w-]+)+$";
540
-
541
- // 身份证
542
- String idCardReg = "^[1-9]\\d{5}(19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])\\d{3}[\\dXx]$";
543
-
544
- // URL
545
- String urlReg = "^https?://.+";
546
-
547
- // 中文
548
- String chineseReg = "^[\\u4e00-\\u9fa5]+$";
549
- ```
550
-
551
- ---
552
-
553
330
  ## 工具类选择速查
554
331
 
555
332
  | 需求 | 推荐工具 | 说明 |
556
333
  |------|---------|------|
557
- | BOEntityVO 转换 | `MapstructUtils.convert()` | **必须使用** |
558
- | 字符串判空 | `StringUtils.isBlank()` | 推荐项目工具类 |
334
+ | BO/Entity/VO 转换 | `MapstructUtils.convert()` | **必须使用** |
335
+ | 字符串判空 | `StringUtils.isBlank()` | 项目工具类 |
559
336
  | 集合判空 | `CollUtil.isEmpty()` | Hutool |
560
337
  | 对象判空 | `ObjectUtil.isNull()` | Hutool |
561
338
  | 提取集合属性 | `StreamUtils.toList()` | 项目工具类 |
562
339
  | 集合转 Map | `StreamUtils.toIdentityMap()` | 项目工具类 |
563
- | 分组 | `StreamUtils.groupByKey()` | 项目工具类 |
564
340
  | 构建树 | `TreeBuildUtils.build()` | 项目工具类 |
565
341
  | 日期格式化 | `DateUtils.formatDateTime()` | 项目工具类 |
566
342
  | 抛业务异常 | `throw new ServiceException()` | 项目异常类 |
@@ -568,7 +344,6 @@ String chineseReg = "^[\\u4e00-\\u9fa5]+$";
568
344
  | Redis 缓存 | `RedisUtils.setCacheObject()` | 项目工具类 |
569
345
  | Excel 导出 | `ExcelUtil.exportExcel()` | 项目工具类 |
570
346
  | 生成 ID | `IdUtil.getSnowflakeNextId()` | Hutool |
571
- | MD5/SHA | `SecureUtil.md5()` | Hutool |
572
347
 
573
348
  ---
574
349
 
@@ -576,18 +351,12 @@ String chineseReg = "^[\\u4e00-\\u9fa5]+$";
576
351
 
577
352
  ```java
578
353
  // ❌ 禁止使用 BeanUtils
579
- BeanUtils.copyProperties(source, target); // 禁止!
354
+ BeanUtils.copyProperties(source, target);
580
355
 
581
356
  // ❌ 禁止使用 Map 传递业务数据
582
- public Map<String, Object> getXxx() { ... } // 禁止!
357
+ public Map<String, Object> getXxx() { ... }
583
358
 
584
359
  // ❌ 禁止手写 stream 转换(应使用 StreamUtils)
585
360
  list.stream().map(User::getId).collect(Collectors.toList()); // 不推荐
586
361
  StreamUtils.toList(list, User::getId); // ✅ 推荐
587
-
588
- // ❌ 禁止使用完整类型引用
589
- public org.dromara.common.core.domain.R<XxxVo> getXxx() // 禁止!
590
- // ✅ 正确:先 import,再使用短类名
591
- import org.dromara.common.core.domain.R;
592
- public R<XxxVo> getXxx()
593
362
  ```
@@ -0,0 +1,56 @@
1
+ # RedisUtils 完整 API
2
+
3
+ ```java
4
+ import org.dromara.common.redis.utils.RedisUtils;
5
+ import java.time.Duration;
6
+
7
+ // ========== 基本操作 ==========
8
+ RedisUtils.setCacheObject("key", value); // 永久
9
+ RedisUtils.setCacheObject("key", value, Duration.ofMinutes(30)); // 30分钟过期
10
+ RedisUtils.getCacheObject("key");
11
+ RedisUtils.deleteObject("key");
12
+ RedisUtils.hasKey("key");
13
+ RedisUtils.expire("key", 3600); // 设置过期时间(秒)
14
+
15
+ // ========== 条件设置 ==========
16
+ RedisUtils.setObjectIfAbsent("key", value, Duration.ofMinutes(5)); // 不存在才设置
17
+ RedisUtils.setObjectIfExists("key", value, Duration.ofMinutes(5)); // 存在才设置
18
+
19
+ // ========== List 操作 ==========
20
+ RedisUtils.setCacheList("listKey", dataList);
21
+ RedisUtils.addCacheList("listKey", item);
22
+ List<T> list = RedisUtils.getCacheList("listKey");
23
+ List<T> range = RedisUtils.getCacheListRange("listKey", 0, 10);
24
+
25
+ // ========== Set 操作 ==========
26
+ RedisUtils.setCacheSet("setKey", dataSet);
27
+ RedisUtils.addCacheSet("setKey", item);
28
+ Set<T> set = RedisUtils.getCacheSet("setKey");
29
+
30
+ // ========== Map/Hash 操作 ==========
31
+ RedisUtils.setCacheMap("mapKey", dataMap);
32
+ RedisUtils.setCacheMapValue("mapKey", "field", value);
33
+ T value = RedisUtils.getCacheMapValue("mapKey", "field");
34
+ Map<String, T> map = RedisUtils.getCacheMap("mapKey");
35
+ RedisUtils.delCacheMapValue("mapKey", "field");
36
+
37
+ // ========== 原子操作 ==========
38
+ RedisUtils.setAtomicValue("counter", 0);
39
+ long val = RedisUtils.incrAtomicValue("counter"); // +1
40
+ long val = RedisUtils.decrAtomicValue("counter"); // -1
41
+ long val = RedisUtils.getAtomicValue("counter");
42
+
43
+ // ========== 批量操作 ==========
44
+ Collection<String> keys = RedisUtils.keys("user:*");
45
+ RedisUtils.deleteKeys("temp:*");
46
+
47
+ // ========== 发布订阅 ==========
48
+ RedisUtils.publish("channel", message);
49
+ RedisUtils.subscribe("channel", Message.class, msg -> {
50
+ // 处理消息
51
+ });
52
+
53
+ // ========== 限流 ==========
54
+ long remaining = RedisUtils.rateLimiter("api:user:list", RateType.OVERALL, 100, 60);
55
+ // 每60秒最多100次,返回剩余次数,-1表示被限流
56
+ ```