ai-engineering-init 1.3.3 → 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 (228) hide show
  1. package/.claude/hooks/skill-forced-eval.js +4 -1
  2. package/.claude/settings.json +3 -3
  3. package/.claude/skills/add-skill/SKILL.md +252 -116
  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 -325
  38. package/.claude/skills/leniu-report-customization/references/table-fields.md +93 -0
  39. package/.claude/skills/leniu-report-standard-customization/SKILL.md +328 -0
  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 +252 -116
  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 -325
  113. package/.codex/skills/leniu-report-customization/references/table-fields.md +93 -0
  114. package/.codex/skills/leniu-report-standard-customization/SKILL.md +328 -0
  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/rules/skill-activation.mdc +2 -0
  154. package/.cursor/skills/add-skill/SKILL.md +252 -116
  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 -325
  191. package/.cursor/skills/leniu-report-customization/references/table-fields.md +93 -0
  192. package/.cursor/skills/leniu-report-standard-customization/SKILL.md +328 -0
  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/AGENTS.md +1 -0
  228. package/package.json +1 -1
@@ -15,118 +15,65 @@ description: |
15
15
 
16
16
  # 短信与邮件开发指南
17
17
 
18
- > **适用模块**:`ruoyi-common-sms`(SMS4j)、`ruoyi-common-mail`(Hutool Mail
19
-
20
- ## 概述
21
-
22
- 本框架提供两种消息通知方案:
23
-
24
- | 方案 | 模块 | 技术栈 | 适用场景 |
25
- |------|------|--------|---------|
26
- | **短信** | `ruoyi-common-sms` | SMS4j | 验证码、营销短信、通知短信 |
27
- | **邮件** | `ruoyi-common-mail` | Hutool JakartaMail | 系统通知、报表发送、验证邮件 |
28
-
29
- **共同特性**:
30
- - ✅ 多供应商支持
31
- - ✅ 模板消息
32
- - ✅ 配置热更新
18
+ > 短信模块:`ruoyi-common/ruoyi-common-sms`(SMS4j
19
+ > 邮件模块:`ruoyi-common/ruoyi-common-mail`(Hutool JakartaMail)
33
20
 
34
21
  ---
35
22
 
36
- ## 一、短信开发指南(SMS4j)
37
-
38
- ### 1.1 支持的短信服务商
39
-
40
- SMS4j 支持多种短信服务商,开箱即用:
23
+ ## 一、短信开发(SMS4j)
41
24
 
42
- | 服务商 | 配置标识 | 说明 |
43
- |--------|---------|------|
44
- | 阿里云 | `alibaba` | 阿里云短信服务 |
45
- | 腾讯云 | `tencent` | 腾讯云短信 |
46
- | 华为云 | `huawei` | 华为云短信 |
47
- | 云片 | `yunpian` | 云片短信 |
48
- | 合一 | `unisms` | 合一短信 |
49
- | 京东云 | `jdcloud` | 京东云短信 |
50
- | 容联云 | `cloopen` | 容联云通讯 |
51
- | 亿美软通 | `emay` | 亿美短信 |
52
- | 天翼云 | `ctyun` | 天翼云短信 |
53
-
54
- ### 1.2 配置短信服务
25
+ ### 1.1 配置
55
26
 
56
27
  ```yaml
57
- # application.yml
58
28
  sms:
59
- # 配置源类型:yaml(默认)、接口、数据库
60
- config-type: yaml
61
-
62
- # 短信配置列表
29
+ config-type: yaml # yaml / 接口 / 数据库
63
30
  blends:
64
- # 配置标识(可自定义,用于 SmsFactory.getSmsBlend("config1"))
65
31
  config1:
66
- # 供应商类型
67
32
  supplier: alibaba
68
- # AccessKey ID
69
- access-key-id: your-access-key-id
70
- # AccessKey Secret
71
- access-key-secret: your-access-key-secret
72
- # 短信签名
33
+ access-key-id: ${ALIYUN_SMS_ACCESS_KEY_ID}
34
+ access-key-secret: ${ALIYUN_SMS_ACCESS_KEY_SECRET}
73
35
  signature: 若依框架
74
- # SDK AppId(腾讯云需要)
75
- sdk-app-id: ""
76
-
77
- # 可配置多个供应商
78
36
  config2:
79
37
  supplier: tencent
80
- access-key-id: your-tencent-secret-id
81
- access-key-secret: your-tencent-secret-key
38
+ access-key-id: ${TENCENT_SMS_SECRET_ID}
39
+ access-key-secret: ${TENCENT_SMS_SECRET_KEY}
82
40
  signature: 若依框架
83
- sdk-app-id: "1400000000"
41
+ sdk-app-id: "1400000000" # 腾讯云需要
84
42
  ```
85
43
 
86
- ### 1.3 核心 API:SmsBlend
44
+ > 支持的服务商:alibaba / tencent / huawei / yunpian / unisms / jdcloud / cloopen / emay / ctyun
45
+ > 限流配置详见 [references/sms-config.md](references/sms-config.md)
87
46
 
88
- **位置**:`org.dromara.sms4j.api.SmsBlend`(SMS4j 库)
47
+ ### 1.2 核心 API
89
48
 
90
49
  ```java
91
50
  import org.dromara.sms4j.api.SmsBlend;
92
51
  import org.dromara.sms4j.api.entity.SmsResponse;
93
52
  import org.dromara.sms4j.core.factory.SmsFactory;
94
53
 
95
- // ========== 获取短信实例 ==========
96
-
97
- // 1. 获取默认配置的短信实例
98
- SmsBlend smsBlend = SmsFactory.getSmsBlend();
99
-
100
- // 2. 获取指定配置的短信实例
101
- SmsBlend smsBlend = SmsFactory.getSmsBlend("config1"); // 阿里云
102
- SmsBlend smsBlend = SmsFactory.getSmsBlend("config2"); // 腾讯云
54
+ // 获取短信实例
55
+ SmsBlend smsBlend = SmsFactory.getSmsBlend(); // 默认配置
56
+ SmsBlend smsBlend = SmsFactory.getSmsBlend("config1"); // 指定配置
103
57
 
104
- // ========== 发送短信 ==========
105
-
106
- // 3. 发送模板短信(推荐)
107
- Map<String, String> templateParams = new LinkedHashMap<>();
108
- templateParams.put("code", "123456");
109
- templateParams.put("time", "5");
58
+ // 发送模板短信
59
+ Map<String, String> params = new LinkedHashMap<>();
60
+ params.put("code", "123456");
61
+ params.put("time", "5");
62
+ SmsResponse response = smsBlend.sendMessage("13800138000", "SMS_123456789", params);
110
63
 
111
- SmsResponse response = smsBlend.sendMessage(
112
- "13800138000", // 手机号
113
- "SMS_123456789", // 模板ID
114
- templateParams // 模板参数
115
- );
64
+ // 批量发送
65
+ List<String> phones = Arrays.asList("13800138001", "13800138002");
66
+ SmsResponse response = smsBlend.sendMessage(phones, "SMS_123456789", params);
116
67
 
117
- // 4. 检查发送结果
68
+ // 检查结果
118
69
  if (response.isSuccess()) {
119
- log.info("短信发送成功,msgId: {}", response.getBizId());
70
+ log.info("发送成功,msgId: {}", response.getBizId());
120
71
  } else {
121
- log.error("短信发送失败:{}", response.getMessage());
72
+ log.error("发送失败:{}", response.getMessage());
122
73
  }
123
-
124
- // 5. 批量发送短信
125
- List<String> phones = Arrays.asList("13800138001", "13800138002");
126
- SmsResponse response = smsBlend.sendMessage(phones, "SMS_123456789", templateParams);
127
74
  ```
128
75
 
129
- ### 1.4 发送验证码短信示例
76
+ ### 1.3 验证码短信示例
130
77
 
131
78
  ```java
132
79
  @RestController
@@ -134,279 +81,124 @@ SmsResponse response = smsBlend.sendMessage(phones, "SMS_123456789", templatePar
134
81
  @RequiredArgsConstructor
135
82
  public class CaptchaController {
136
83
 
137
- private final RedisUtils redisUtils;
138
-
139
- /**
140
- * 发送短信验证码
141
- */
142
84
  @GetMapping("/sms")
143
85
  public R<Void> sendSmsCode(@RequestParam String phonenumber) {
144
- // 1. 生成验证码
145
86
  String code = RandomUtil.randomNumbers(6);
146
87
 
147
- // 2. 存入 Redis(5分钟有效)
148
- String cacheKey = "sms:code:" + phonenumber;
149
- RedisUtils.setCacheObject(cacheKey, code, Duration.ofMinutes(5));
88
+ // 存入Redis(5分钟有效)
89
+ RedisUtils.setCacheObject("sms:code:" + phonenumber, code, Duration.ofMinutes(5));
150
90
 
151
- // 3. 构建模板参数
91
+ // 发送短信
152
92
  Map<String, String> map = new LinkedHashMap<>();
153
93
  map.put("code", code);
154
-
155
- // 4. 发送短信
156
- String templateId = "SMS_123456789"; // 短信模板ID
157
94
  SmsBlend smsBlend = SmsFactory.getSmsBlend("config1");
158
- SmsResponse smsResponse = smsBlend.sendMessage(phonenumber, templateId, map);
95
+ SmsResponse smsResponse = smsBlend.sendMessage(phonenumber, "SMS_123456789", map);
159
96
 
160
- // 5. 处理结果
161
97
  if (!smsResponse.isSuccess()) {
162
98
  log.error("短信发送失败:{}", smsResponse.getMessage());
163
99
  return R.fail("短信发送失败");
164
100
  }
165
-
166
101
  return R.ok("验证码已发送");
167
102
  }
168
103
 
169
- /**
170
- * 验证短信验证码
171
- */
172
104
  @PostMapping("/verify")
173
105
  public R<Boolean> verifySmsCode(@RequestParam String phonenumber,
174
106
  @RequestParam String code) {
175
107
  String cacheKey = "sms:code:" + phonenumber;
176
108
  String cachedCode = RedisUtils.getCacheObject(cacheKey);
177
109
 
178
- if (cachedCode == null) {
179
- return R.fail("验证码已过期");
180
- }
181
-
182
- if (!cachedCode.equals(code)) {
183
- return R.fail("验证码错误");
184
- }
110
+ if (cachedCode == null) return R.fail("验证码已过期");
111
+ if (!cachedCode.equals(code)) return R.fail("验证码错误");
185
112
 
186
- // 验证成功,删除缓存
187
113
  RedisUtils.deleteObject(cacheKey);
188
114
  return R.ok(true);
189
115
  }
190
116
  }
191
117
  ```
192
118
 
193
- ### 1.5 业务通知短信示例
194
-
195
- ```java
196
- @Service
197
- @RequiredArgsConstructor
198
- public class OrderNotifyService {
199
-
200
- /**
201
- * 订单发货通知
202
- */
203
- public void notifyShipment(Order order) {
204
- Map<String, String> params = new LinkedHashMap<>();
205
- params.put("orderNo", order.getOrderNo());
206
- params.put("expressNo", order.getExpressNo());
207
- params.put("expressCompany", order.getExpressCompany());
208
-
209
- SmsBlend smsBlend = SmsFactory.getSmsBlend("config1");
210
- SmsResponse response = smsBlend.sendMessage(
211
- order.getPhone(),
212
- "SMS_SHIPMENT_NOTIFY", // 发货通知模板
213
- params
214
- );
215
-
216
- if (!response.isSuccess()) {
217
- log.error("发货通知短信发送失败,订单号:{},错误:{}",
218
- order.getOrderNo(), response.getMessage());
219
- }
220
- }
221
-
222
- /**
223
- * 批量发送营销短信
224
- */
225
- public void sendMarketingSms(List<String> phones, String content) {
226
- Map<String, String> params = new LinkedHashMap<>();
227
- params.put("content", content);
228
-
229
- SmsBlend smsBlend = SmsFactory.getSmsBlend("config1");
230
- SmsResponse response = smsBlend.sendMessage(
231
- phones,
232
- "SMS_MARKETING",
233
- params
234
- );
235
-
236
- log.info("营销短信发送结果:成功={}, 消息={}",
237
- response.isSuccess(), response.getMessage());
238
- }
239
- }
240
- ```
241
-
242
119
  ---
243
120
 
244
- ## 二、邮件开发指南(Hutool Mail)
121
+ ## 二、邮件开发(Hutool Mail)
245
122
 
246
- ### 2.1 配置邮件服务
123
+ ### 2.1 配置
247
124
 
248
125
  ```yaml
249
- # application.yml
250
126
  mail:
251
127
  enabled: true
252
- # SMTP 服务器
253
128
  host: smtp.163.com
254
- # SMTP 端口
255
129
  port: 465
256
- # 是否需要认证
257
130
  auth: true
258
- # 发件人邮箱
259
- from: xxx@163.com
260
- # 用户名(通常与发件人相同)
261
- user: xxx@163.com
262
- # 密码(授权码,非登录密码)
263
- pass: your-smtp-password
264
- # 使用 SSL
131
+ from: system@example.com
132
+ user: system@example.com
133
+ pass: ${MAIL_PASSWORD} # 授权码,非登录密码
265
134
  sslEnable: true
266
- # 使用 STARTTLS
267
135
  starttlsEnable: false
268
- # 超时时间(毫秒)
269
136
  timeout: 10000
270
137
  connectionTimeout: 10000
271
138
  ```
272
139
 
273
- ### 2.2 常用 SMTP 服务器配置
140
+ > 常用 SMTP 服务器配置详见 [references/mail-config.md](references/mail-config.md)
274
141
 
275
- | 邮箱服务商 | SMTP 服务器 | SSL 端口 | 非 SSL 端口 |
276
- |-----------|-------------|---------|------------|
277
- | 163 邮箱 | smtp.163.com | 465 | 25 |
278
- | QQ 邮箱 | smtp.qq.com | 465 | 587 |
279
- | 阿里企业邮箱 | smtp.mxhichina.com | 465 | 25 |
280
- | 腾讯企业邮箱 | smtp.exmail.qq.com | 465 | 587 |
281
- | Gmail | smtp.gmail.com | 465 | 587 |
282
- | Outlook | smtp.office365.com | 587 | 587 |
283
-
284
- ### 2.3 核心工具类:MailUtils
285
-
286
- **位置**:`org.dromara.common.mail.utils.MailUtils`
142
+ ### 2.2 核心 API
287
143
 
288
144
  ```java
289
145
  import org.dromara.common.mail.utils.MailUtils;
290
146
 
291
- // ========== 发送文本邮件 ==========
292
-
293
- // 1. 发送简单文本邮件
294
- String messageId = MailUtils.sendText(
295
- "recipient@example.com", // 收件人
296
- "邮件标题", // 标题
297
- "这是邮件正文内容" // 正文
298
- );
299
-
300
- // 2. 发送文本邮件(带附件)
301
- File attachment = new File("/path/to/file.pdf");
302
- String messageId = MailUtils.sendText(
303
- "recipient@example.com",
304
- "带附件的邮件",
305
- "请查看附件",
306
- attachment
307
- );
308
-
309
- // ========== 发送 HTML 邮件 ==========
310
-
311
- // 3. 发送 HTML 邮件
312
- String htmlContent = """
313
- <h1>欢迎注册</h1>
314
- <p>您的验证码是:<strong>123456</strong></p>
315
- <p>有效期5分钟</p>
316
- """;
317
-
318
- String messageId = MailUtils.sendHtml(
319
- "recipient@example.com",
320
- "验证码邮件",
321
- htmlContent
322
- );
323
-
324
- // 4. 发送 HTML 邮件(带内嵌图片)
325
- Map<String, InputStream> imageMap = new HashMap<>();
326
- imageMap.put("logo", new FileInputStream("/path/to/logo.png"));
327
-
328
- String htmlWithImage = """
329
- <h1>欢迎使用若依系统</h1>
330
- <img src="cid:logo" alt="Logo"/>
331
- """;
332
-
333
- String messageId = MailUtils.sendHtml(
334
- "recipient@example.com",
335
- "带图片的邮件",
336
- htmlWithImage,
337
- imageMap
338
- );
339
-
340
- // ========== 发送给多人 ==========
341
-
342
- // 5. 发送给多个收件人
343
- List<String> recipients = Arrays.asList(
344
- "user1@example.com",
345
- "user2@example.com"
346
- );
347
-
348
- String messageId = MailUtils.sendHtml(
349
- recipients,
350
- "群发邮件",
351
- "<p>这是群发的邮件内容</p>"
352
- );
353
-
354
- // 6. 发送邮件(带抄送、密送)
355
- String messageId = MailUtils.send(
356
- "recipient@example.com", // 收件人
357
- "cc@example.com", // 抄送人
358
- "bcc@example.com", // 密送人
359
- "重要通知", // 标题
360
- "<p>这是重要通知内容</p>", // 正文
361
- true // 是否 HTML
362
- );
147
+ // 发送文本邮件
148
+ String msgId = MailUtils.sendText("to@example.com", "标题", "正文内容");
149
+
150
+ // 发送HTML邮件
151
+ String msgId = MailUtils.sendHtml("to@example.com", "标题", "<h1>内容</h1>");
152
+
153
+ // 带附件
154
+ String msgId = MailUtils.sendText("to@example.com", "标题", "正文", attachment);
155
+ String msgId = MailUtils.sendHtml("to@example.com", "标题", htmlContent, attachment);
156
+
157
+ // 带内嵌图片
158
+ Map<String, InputStream> imageMap = Map.of("logo", new FileInputStream("logo.png"));
159
+ String msgId = MailUtils.sendHtml("to@example.com", "标题",
160
+ "<img src='cid:logo'/>", imageMap);
161
+
162
+ // 群发
163
+ String msgId = MailUtils.sendHtml(List.of("a@x.com", "b@x.com"), "标题", htmlContent);
164
+
165
+ // 抄送/密送
166
+ String msgId = MailUtils.send("to@x.com", "cc@x.com", "bcc@x.com", "标题", "内容", true);
167
+
168
+ // 获取邮件账户配置
169
+ MailAccount account = MailUtils.getMailAccount();
363
170
  ```
364
171
 
365
- ### 2.4 邮件验证码示例
172
+ ### 2.3 邮件验证码示例
366
173
 
367
174
  ```java
368
175
  @Service
369
176
  @RequiredArgsConstructor
370
177
  public class EmailService {
371
178
 
372
- /**
373
- * 发送邮箱验证码
374
- */
375
179
  public void sendEmailCode(String email) {
376
- // 1. 生成验证码
377
180
  String code = RandomUtil.randomNumbers(6);
181
+ RedisUtils.setCacheObject("email:code:" + email, code, Duration.ofMinutes(10));
378
182
 
379
- // 2. 存入 Redis
380
- String cacheKey = "email:code:" + email;
381
- RedisUtils.setCacheObject(cacheKey, code, Duration.ofMinutes(10));
382
-
383
- // 3. 构建邮件内容
384
183
  String htmlContent = String.format("""
385
184
  <div style="padding: 20px; background: #f5f5f5;">
386
185
  <h2>验证码</h2>
387
186
  <p>您的验证码是:<strong style="color: #1890ff; font-size: 24px;">%s</strong></p>
388
- <p>有效期10分钟,请勿泄露给他人。</p>
389
- <p style="color: #999;">如非本人操作,请忽略此邮件。</p>
187
+ <p>有效期10分钟,请勿泄露。</p>
390
188
  </div>
391
189
  """, code);
392
190
 
393
- // 4. 发送邮件
394
191
  try {
395
192
  MailUtils.sendHtml(email, "【若依系统】验证码", htmlContent);
396
- log.info("验证码邮件发送成功:{}", email);
397
193
  } catch (Exception e) {
398
- log.error("验证码邮件发送失败:{}", e.getMessage());
194
+ log.error("邮件发送失败:{}", e.getMessage());
399
195
  throw new ServiceException("邮件发送失败");
400
196
  }
401
197
  }
402
198
 
403
- /**
404
- * 验证邮箱验证码
405
- */
406
199
  public boolean verifyEmailCode(String email, String code) {
407
200
  String cacheKey = "email:code:" + email;
408
201
  String cachedCode = RedisUtils.getCacheObject(cacheKey);
409
-
410
202
  if (cachedCode != null && cachedCode.equals(code)) {
411
203
  RedisUtils.deleteObject(cacheKey);
412
204
  return true;
@@ -416,179 +208,32 @@ public class EmailService {
416
208
  }
417
209
  ```
418
210
 
419
- ### 2.5 业务通知邮件示例
420
-
421
- ```java
422
- @Service
423
- @RequiredArgsConstructor
424
- public class NotificationService {
425
-
426
- /**
427
- * 发送订单确认邮件
428
- */
429
- public void sendOrderConfirmation(Order order, User user) {
430
- String htmlContent = String.format("""
431
- <div style="max-width: 600px; margin: 0 auto; font-family: Arial;">
432
- <h2>订单确认</h2>
433
- <p>尊敬的 %s,您好!</p>
434
- <p>您的订单已确认,订单信息如下:</p>
435
- <table style="width: 100%%; border-collapse: collapse;">
436
- <tr><td>订单号:</td><td>%s</td></tr>
437
- <tr><td>下单时间:</td><td>%s</td></tr>
438
- <tr><td>订单金额:</td><td>¥%s</td></tr>
439
- </table>
440
- <p>感谢您的购买!</p>
441
- </div>
442
- """,
443
- user.getNickName(),
444
- order.getOrderNo(),
445
- DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", order.getCreateTime()),
446
- order.getTotalAmount()
447
- );
448
-
449
- MailUtils.sendHtml(user.getEmail(), "【若依商城】订单确认", htmlContent);
450
- }
451
-
452
- /**
453
- * 发送密码重置邮件
454
- */
455
- public void sendPasswordResetEmail(String email, String resetToken) {
456
- String resetUrl = "https://example.com/reset-password?token=" + resetToken;
457
-
458
- String htmlContent = String.format("""
459
- <div style="padding: 20px;">
460
- <h2>密码重置</h2>
461
- <p>您正在重置密码,请点击下方链接完成操作:</p>
462
- <p><a href="%s" style="color: #1890ff;">点击重置密码</a></p>
463
- <p>链接有效期30分钟。</p>
464
- <p style="color: #999;">如非本人操作,请忽略此邮件。</p>
465
- </div>
466
- """, resetUrl);
467
-
468
- MailUtils.sendHtml(email, "【若依系统】密码重置", htmlContent);
469
- }
470
-
471
- /**
472
- * 发送报表邮件(带附件)
473
- */
474
- public void sendReportEmail(String email, String reportName, File reportFile) {
475
- String htmlContent = String.format("""
476
- <div style="padding: 20px;">
477
- <h2>%s</h2>
478
- <p>请查看附件中的报表文件。</p>
479
- <p>报表生成时间:%s</p>
480
- </div>
481
- """, reportName, DateUtils.getTime());
482
-
483
- MailUtils.sendHtml(email, reportName, htmlContent, reportFile);
484
- }
485
- }
486
- ```
487
-
488
211
  ---
489
212
 
490
- ## 三、多渠道消息通知
491
-
492
- ### 3.1 统一消息服务
213
+ ## 三、多渠道消息通知示例
493
214
 
494
215
  ```java
495
216
  @Service
496
217
  @RequiredArgsConstructor
497
218
  public class MessageService {
498
219
 
499
- /**
500
- * 消息类型枚举
501
- */
502
- public enum MessageType {
503
- SMS, // 短信
504
- EMAIL, // 邮件
505
- WECHAT, // 微信(需额外实现)
506
- SITE // 站内信(需额外实现)
507
- }
508
-
509
- /**
510
- * 发送多渠道消息
511
- */
512
- public void sendMessage(List<MessageType> types, String userId,
513
- String subject, String content) {
514
- // 获取用户信息
515
- SysUser user = userService.selectUserById(Long.valueOf(userId));
516
-
517
- for (MessageType type : types) {
220
+ public void sendMessage(List<String> messageType, String subject,
221
+ String message, List<UserDTO> userList) {
222
+ for (UserDTO user : userList) {
518
223
  try {
519
- switch (type) {
520
- case SMS -> sendSms(user.getPhonenumber(), content);
521
- case EMAIL -> sendEmail(user.getEmail(), subject, content);
522
- // case WECHAT -> sendWechat(user.getOpenId(), content);
523
- // case SITE -> sendSiteMessage(userId, subject, content);
224
+ if (messageType.contains("sms") && StringUtils.isNotBlank(user.getPhone())) {
225
+ Map<String, String> params = new LinkedHashMap<>();
226
+ params.put("content", message);
227
+ SmsFactory.getSmsBlend("config1")
228
+ .sendMessage(user.getPhone(), "SMS_NOTIFY", params);
229
+ }
230
+ if (messageType.contains("email") && StringUtils.isNotBlank(user.getEmail())) {
231
+ MailUtils.sendHtml(user.getEmail(), subject,
232
+ "<div style='padding:20px;'><h3>" + subject + "</h3><p>" + message + "</p></div>");
524
233
  }
525
234
  } catch (Exception e) {
526
235
  log.error("消息发送失败,类型:{},用户:{},错误:{}",
527
- type, userId, e.getMessage());
528
- }
529
- }
530
- }
531
-
532
- private void sendSms(String phone, String content) {
533
- if (StringUtils.isBlank(phone)) return;
534
-
535
- Map<String, String> params = new LinkedHashMap<>();
536
- params.put("content", content);
537
-
538
- SmsBlend smsBlend = SmsFactory.getSmsBlend("config1");
539
- smsBlend.sendMessage(phone, "SMS_NOTIFY", params);
540
- }
541
-
542
- private void sendEmail(String email, String subject, String content) {
543
- if (StringUtils.isBlank(email)) return;
544
-
545
- MailUtils.sendHtml(email, subject,
546
- "<div style='padding:20px;'>" + content + "</div>");
547
- }
548
- }
549
- ```
550
-
551
- ### 3.2 工作流消息通知示例
552
-
553
- ```java
554
- /**
555
- * 工作流消息服务(参考框架实现)
556
- */
557
- @Service
558
- @RequiredArgsConstructor
559
- public class FlwCommonServiceImpl implements IFlwCommonService {
560
-
561
- /**
562
- * 发送审批通知
563
- */
564
- @Override
565
- public void sendMessage(List<String> messageType, String message,
566
- String subject, List<UserDTO> userList) {
567
- if (CollUtil.isEmpty(messageType) || CollUtil.isEmpty(userList)) {
568
- return;
569
- }
570
-
571
- for (UserDTO user : userList) {
572
- // 短信通知
573
- if (messageType.contains("sms") && StringUtils.isNotBlank(user.getPhone())) {
574
- Map<String, String> params = new LinkedHashMap<>();
575
- params.put("content", message);
576
-
577
- SmsBlend smsBlend = SmsFactory.getSmsBlend("config1");
578
- smsBlend.sendMessage(user.getPhone(), "SMS_APPROVAL", params);
579
- }
580
-
581
- // 邮件通知
582
- if (messageType.contains("email") && StringUtils.isNotBlank(user.getEmail())) {
583
- String htmlContent = String.format("""
584
- <div style="padding: 20px;">
585
- <h3>%s</h3>
586
- <p>%s</p>
587
- <p>请登录系统处理。</p>
588
- </div>
589
- """, subject, message);
590
-
591
- MailUtils.sendHtml(user.getEmail(), subject, htmlContent);
236
+ messageType, user.getUserId(), e.getMessage());
592
237
  }
593
238
  }
594
239
  }
@@ -597,75 +242,25 @@ public class FlwCommonServiceImpl implements IFlwCommonService {
597
242
 
598
243
  ---
599
244
 
600
- ## 四、常见错误与最佳实践
601
-
602
- ### ❌ 错误1:未配置短信/邮件服务就使用
245
+ ## 四、常见错误
603
246
 
604
247
  ```java
605
- // ❌ 错误:未配置 sms.blends 就调用
606
- SmsBlend smsBlend = SmsFactory.getSmsBlend("config1"); // 返回 null
607
- smsBlend.sendMessage(...); // NullPointerException
608
- ```
609
-
610
- ```yaml
611
- # ✅ 正确:先配置
612
- sms:
613
- blends:
614
- config1:
615
- supplier: alibaba
616
- access-key-id: xxx
617
- access-key-secret: xxx
618
- signature: 若依框架
619
- ```
620
-
621
- ### ❌ 错误2:邮箱使用登录密码而非授权码
622
-
623
- ```yaml
624
- # ❌ 错误:使用登录密码
625
- mail:
626
- pass: my-login-password # 错误!
627
-
628
- # ✅ 正确:使用授权码(在邮箱设置中生成)
629
- mail:
630
- pass: ABCDEFGHIJKLMNOP # 授权码
631
- ```
632
-
633
- ### ❌ 错误3:短信模板参数与模板不匹配
248
+ // ❌ 未配置就使用,getSmsBlend 返回 null → NPE
249
+ SmsBlend smsBlend = SmsFactory.getSmsBlend("config1");
250
+ smsBlend.sendMessage(...);
634
251
 
635
- ```java
636
- // ❌ 错误:参数名与模板中定义的不一致
637
- Map<String, String> params = new LinkedHashMap<>();
252
+ // ❌ 模板参数名与模板定义不匹配
638
253
  params.put("verifyCode", "123456"); // 模板中是 ${code}
254
+ // ✅ params.put("code", "123456");
639
255
 
640
- // 正确:参数名要与模板一致
641
- Map<String, String> params = new LinkedHashMap<>();
642
- params.put("code", "123456"); // 匹配模板 ${code}
643
- ```
644
-
645
- ### ❌ 错误4:未处理发送失败的情况
646
-
647
- ```java
648
- // ❌ 错误:直接发送,不处理结果
649
- SmsBlend smsBlend = SmsFactory.getSmsBlend("config1");
256
+ // 不检查发送结果
650
257
  smsBlend.sendMessage(phone, templateId, params);
651
- // 如果失败,用户无感知
258
+ // ✅ SmsResponse response = smsBlend.sendMessage(...);
259
+ // if (!response.isSuccess()) throw new ServiceException("短信发送失败");
652
260
 
653
- // 正确:检查发送结果
654
- SmsResponse response = smsBlend.sendMessage(phone, templateId, params);
655
- if (!response.isSuccess()) {
656
- log.error("短信发送失败:{}", response.getMessage());
657
- throw new ServiceException("短信发送失败,请稍后重试");
658
- }
659
- ```
660
-
661
- ### ❌ 错误5:验证码明文存储或无过期时间
662
-
663
- ```java
664
- // ❌ 错误:无过期时间
665
- RedisUtils.setCacheObject("sms:code:" + phone, code); // 永不过期
666
-
667
- // ✅ 正确:设置合理的过期时间
668
- RedisUtils.setCacheObject("sms:code:" + phone, code, Duration.ofMinutes(5));
261
+ // 验证码无过期时间
262
+ RedisUtils.setCacheObject("sms:code:" + phone, code);
263
+ // ✅ RedisUtils.setCacheObject("sms:code:" + phone, code, Duration.ofMinutes(5));
669
264
  ```
670
265
 
671
266
  ---
@@ -677,90 +272,37 @@ RedisUtils.setCacheObject("sms:code:" + phone, code, Duration.ofMinutes(5));
677
272
  | 方法 | 说明 |
678
273
  |------|------|
679
274
  | `SmsFactory.getSmsBlend()` | 获取默认短信实例 |
680
- | `SmsFactory.getSmsBlend("config1")` | 获取指定配置的短信实例 |
275
+ | `SmsFactory.getSmsBlend("config1")` | 获取指定配置短信实例 |
681
276
  | `smsBlend.sendMessage(phone, templateId, params)` | 发送模板短信 |
682
- | `smsBlend.sendMessage(phones, templateId, params)` | 批量发送短信 |
683
- | `response.isSuccess()` | 检查是否发送成功 |
684
- | `response.getMessage()` | 获取错误信息 |
685
- | `response.getBizId()` | 获取消息ID |
277
+ | `smsBlend.sendMessage(phones, templateId, params)` | 批量发送 |
278
+ | `response.isSuccess()` | 是否成功 |
279
+ | `response.getMessage()` | 错误信息 |
280
+ | `response.getBizId()` | 消息ID |
686
281
 
687
282
  ### 邮件 API(MailUtils)
688
283
 
689
284
  | 方法 | 说明 |
690
285
  |------|------|
691
- | `MailUtils.sendText(to, subject, content)` | 发送文本邮件 |
692
- | `MailUtils.sendHtml(to, subject, content)` | 发送 HTML 邮件 |
693
- | `MailUtils.sendText(to, subject, content, files...)` | 发送带附件的文本邮件 |
694
- | `MailUtils.sendHtml(to, subject, content, files...)` | 发送带附件的 HTML 邮件 |
695
- | `MailUtils.sendHtml(to, subject, content, imageMap)` | 发送带内嵌图片的邮件 |
696
- | `MailUtils.send(to, cc, bcc, subject, content, isHtml)` | 发送带抄送/密送的邮件 |
697
- | `MailUtils.sendHtml(tos, subject, content)` | 群发 HTML 邮件 |
698
- | `MailUtils.getMailAccount()` | 获取邮件账户配置 |
699
-
700
- ---
701
-
702
- ## 六、配置参考
703
-
704
- ### 短信完整配置
705
-
706
- ```yaml
707
- sms:
708
- # 配置源类型:yaml、接口、数据库
709
- config-type: yaml
710
- # 短信拦截配置(可选)
711
- restricted:
712
- # 是否开启账号维度的每日发送上限
713
- account-max: 0
714
- # 是否开启手机号维度的每分钟发送上限
715
- minute-max: 1
716
- # 单账号每日发送上限
717
- account-max-count: 10
718
- # 单手机号每分钟发送上限
719
- minute-max-count: 1
720
-
721
- blends:
722
- config1:
723
- supplier: alibaba
724
- access-key-id: ${ALIYUN_SMS_ACCESS_KEY_ID}
725
- access-key-secret: ${ALIYUN_SMS_ACCESS_KEY_SECRET}
726
- signature: 若依框架
727
-
728
- config2:
729
- supplier: tencent
730
- access-key-id: ${TENCENT_SMS_SECRET_ID}
731
- access-key-secret: ${TENCENT_SMS_SECRET_KEY}
732
- signature: 若依框架
733
- sdk-app-id: "1400000000"
734
- ```
735
-
736
- ### 邮件完整配置
737
-
738
- ```yaml
739
- mail:
740
- enabled: true
741
- host: smtp.163.com
742
- port: 465
743
- auth: true
744
- from: system@example.com
745
- user: system@example.com
746
- pass: ${MAIL_PASSWORD}
747
- sslEnable: true
748
- starttlsEnable: false
749
- timeout: 10000
750
- connectionTimeout: 10000
751
- ```
286
+ | `MailUtils.sendText(to, subject, content)` | 文本邮件 |
287
+ | `MailUtils.sendHtml(to, subject, content)` | HTML邮件 |
288
+ | `MailUtils.sendText(to, subject, content, files...)` | 带附件文本邮件 |
289
+ | `MailUtils.sendHtml(to, subject, content, files...)` | 带附件HTML邮件 |
290
+ | `MailUtils.sendHtml(to, subject, content, imageMap)` | 带内嵌图片邮件 |
291
+ | `MailUtils.send(to, cc, bcc, subject, content, isHtml)` | 抄送/密送 |
292
+ | `MailUtils.sendHtml(tos, subject, content)` | 群发HTML邮件 |
293
+ | `MailUtils.getMailAccount()` | 获取邮件配置 |
752
294
 
753
295
  ---
754
296
 
755
- ## 七、参考代码位置
297
+ ## 六、核心文件位置
756
298
 
757
299
  | 类型 | 位置 |
758
300
  |------|------|
759
- | 短信配置 | `ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/config/SmsAutoConfiguration.java` |
760
- | 短信缓存 | `ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/core/dao/PlusSmsDao.java` |
761
- | 邮件工具类 | `ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/MailUtils.java` |
762
- | 邮件配置 | `ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/config/MailConfig.java` |
763
- | 邮件属性 | `ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/config/properties/MailProperties.java` |
764
- | 验证码示例 | `ruoyi-admin/src/main/java/org/dromara/web/controller/CaptchaController.java` |
765
- | 短信演示 | `ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/SmsController.java` |
766
- | 工作流消息 | `ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwCommonServiceImpl.java` |
301
+ | 短信配置 | `ruoyi-common/ruoyi-common-sms/.../config/SmsAutoConfiguration.java` |
302
+ | 短信缓存 | `ruoyi-common/ruoyi-common-sms/.../core/dao/PlusSmsDao.java` |
303
+ | 邮件工具类 | `ruoyi-common/ruoyi-common-mail/.../utils/MailUtils.java` |
304
+ | 邮件配置 | `ruoyi-common/ruoyi-common-mail/.../config/MailConfig.java` |
305
+ | 邮件属性 | `ruoyi-common/ruoyi-common-mail/.../config/properties/MailProperties.java` |
306
+ | 验证码示例 | `ruoyi-admin/.../web/controller/CaptchaController.java` |
307
+ | 短信演示 | `ruoyi-modules/ruoyi-demo/.../controller/SmsController.java` |
308
+ | 工作流消息 | `ruoyi-modules/ruoyi-workflow/.../service/impl/FlwCommonServiceImpl.java` |