Skip to content

Commit fe5ef28

Browse files
committed
feat: 重构通知模块REST API,简化接口设计
- 移除显式的type参数,通过模板代码自动确定通知类型 - 简化Controller返回类型,直接返回NotificationResponse - 更新相关DTO类和Service方法 - 同步更新API设计文档
1 parent 4d10ca1 commit fe5ef28

10 files changed

Lines changed: 445 additions & 11 deletions

File tree

NOTIFICATION_REST_API_DESIGN.md

Lines changed: 281 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,281 @@
1+
# 通知模块REST API设计文档 (Notification Module REST API Design Document)
2+
3+
## 1. 概述 (Overview)
4+
5+
本文档描述了通知模块的REST API设计,用于通过HTTP接口发送各种类型的通知,包括短信、邮件、微信等。API设计遵循RESTful原则,提供统一的通知发送入口。通知类型由模板代码自动确定,无需显式传递。
6+
7+
## 2. API 设计目标 (API Design Goals)
8+
9+
- **统一入口**: 提供单一端点支持多种通知类型
10+
- **灵活参数**: 支持位置参数和键值对参数两种模式
11+
- **扩展性**: 易于扩展新的通知类型和模板
12+
- **安全性**: 包含必要的认证和权限控制
13+
- **易用性**: 简单直观的API调用方式
14+
15+
## 3. API 接口定义 (API Endpoint Definition)
16+
17+
### 3.1 发送通知接口 (Send Notification API)
18+
19+
#### 基本信息
20+
- **请求路径**: `POST /notification/send`
21+
- **请求方式**: POST
22+
- **内容类型**: `application/json`
23+
- **认证方式**: JWT Token 或 API Key
24+
25+
#### 请求参数 (Request Parameters)
26+
27+
##### 请求体 (Request Body)
28+
```json
29+
{
30+
"target": "接收者地址(手机号、邮箱等)",
31+
"templateCode": "模板代码",
32+
"args": [],
33+
"mapArgs": {}
34+
}
35+
```
36+
37+
##### 字段说明 (Field Description)
38+
| 字段 | 类型 | 必填 | 说明 |
39+
|------|------|------|------|
40+
| target | String || 接收者地址,如手机号、邮箱地址 |
41+
| templateCode | String || 模板代码,对应NotificationTemplate枚举中的code,通知类型由此自动确定 |
42+
| args | Array || 位置参数数组,用于String.format格式化,与mapArgs二选一 |
43+
| mapArgs | Object || 键值对参数对象,用于模板参数替换,与args二选一 |
44+
45+
#### 响应格式 (Response Format)
46+
47+
API响应将直接返回响应对象,符合简化后的设计。
48+
49+
##### 成功响应 (Success Response)
50+
```json
51+
{
52+
"messageId": "消息唯一标识",
53+
"sentTime": "发送时间戳"
54+
}
55+
```
56+
57+
##### 错误响应 (Error Response)
58+
```json
59+
{
60+
"timestamp": "错误发生的时间戳",
61+
"status": "HTTP状态码",
62+
"error": "错误类型",
63+
"message": "错误信息",
64+
"path": "请求路径"
65+
}
66+
```
67+
68+
## 4. API 详细设计 (Detailed API Design)
69+
70+
### 4.1 Controller 层设计 (Controller Layer Design)
71+
72+
#### NotificationController 类
73+
```java
74+
@RestController
75+
@RequestMapping("/notification")
76+
@Slf4j
77+
public class NotificationController {
78+
79+
@Resource
80+
private NotificationServiceManager notificationServiceManager;
81+
82+
/**
83+
* 发送通知
84+
*
85+
* @param form 发送通知请求参数
86+
* @return 发送结果
87+
*/
88+
@PostMapping("/send")
89+
public NotificationResponse sendNotification(@Valid @RequestBody NotificationForm form) {
90+
// 实现逻辑
91+
}
92+
}
93+
```
94+
95+
### 4.2 Request/Response DTO 设计 (Request/Response DTO Design)
96+
97+
#### NotificationForm 类
98+
```java
99+
@Data
100+
@NoArgsConstructor
101+
@AllArgsConstructor
102+
public class NotificationForm {
103+
104+
@NotBlank(message = "目标地址不能为空")
105+
private String target; // 接收者地址
106+
107+
@NotBlank(message = "模板代码不能为空")
108+
private String templateCode; // NotificationTemplate枚举code
109+
110+
private Object[] args; // 位置参数,与mapArgs二选一
111+
112+
private Map<String, String> mapArgs; // 键值对参数,与args二选一
113+
}
114+
```
115+
116+
> **注意**: `args``mapArgs` 参数是互斥的,只能选择其中一种方式传递模板参数。
117+
> - 当使用位置参数时(如短信验证码模板),使用 `args` 数组
118+
> - 当使用键值对参数时(如邮件模板),使用 `mapArgs` 对象
119+
> - 两个参数同时存在时,系统会优先使用 `args` 参数
120+
121+
#### NotificationResponse 类
122+
```java
123+
@Data
124+
@NoArgsConstructor
125+
@AllArgsConstructor
126+
public class NotificationResponse {
127+
128+
private String messageId; // 消息唯一标识
129+
private Long sentTime; // 发送时间戳
130+
}
131+
```
132+
133+
### 4.3 Service 层集成 (Service Layer Integration)
134+
135+
#### 与现有服务集成
136+
- 利用现有的 [NotificationServiceManager](file:///Users/zhoutaoo/WorkSpaces/IdeaProjects/opensabre/base-sysadmin/src/main/java/io/github/opensabre/sysadmin/notification/service/NotificationServiceManager.java#L17-L58) 来分发通知请求
137+
- 通过 [NotificationTemplate](file:///Users/zhoutaoo/WorkSpaces/IdeaProjects/opensabre/base-sysadmin/src/main/java/io/github/opensabre/sysadmin/notification/enums/NotificationTemplate.java#L9-L56) 枚举中的类型信息自动确定通知渠道
138+
- 支持现有 [INotificationService](file:///Users/zhoutaoo/WorkSpaces/IdeaProjects/opensabre/base-sysadmin/src/main/java/io/github/opensabre/sysadmin/notification/service/INotificationService.java#L12-L39) 实现的扩展
139+
140+
## 5. API 使用示例 (API Usage Examples)
141+
142+
### 5.1 发送短信验证码 (Send SMS Verification Code)
143+
```bash
144+
curl -X POST http://localhost:8080/notification/send \
145+
-H "Content-Type: application/json" \
146+
-H "Authorization: Bearer {token}" \
147+
-d '{
148+
"target": "13800138000",
149+
"templateCode": "CAPTCHA",
150+
"args": ["123456", 5]
151+
}'
152+
```
153+
154+
### 5.2 发送邮件通知 (Send Email Notification)
155+
```bash
156+
curl -X POST http://localhost:8080/notification/send \
157+
-H "Content-Type: application/json" \
158+
-H "Authorization: Bearer {token}" \
159+
-d '{
160+
"target": "user@example.com",
161+
"templateCode": "WELCOME_EMAIL",
162+
"mapArgs": {
163+
"username": "张三",
164+
"company": "公司名称"
165+
}
166+
}'
167+
```
168+
169+
### 5.3 发送微信通知 (Send WeChat Notification)
170+
```bash
171+
curl -X POST http://localhost:8080/notification/send \
172+
-H "Content-Type: application/json" \
173+
-H "Authorization: Bearer {token}" \
174+
-d '{
175+
"target": "openid123456",
176+
"templateCode": "ORDER_STATUS",
177+
"args": ["订单号123", "已发货"]
178+
}'
179+
```
180+
181+
## 6. 安全考虑 (Security Considerations)
182+
183+
### 6.1 认证和授权 (Authentication and Authorization)
184+
- 使用JWT Token或API Key进行身份验证
185+
- 对敏感操作进行权限检查
186+
- 限制API调用频率以防止滥用
187+
188+
### 6.2 输入验证 (Input Validation)
189+
- 验证目标地址格式的有效性
190+
- 验证模板代码的存在性
191+
- 防止注入攻击和恶意内容
192+
193+
### 6.3 数据保护 (Data Protection)
194+
- 对敏感信息进行加密存储
195+
- 日志中不记录敏感数据
196+
- 符合隐私保护法规
197+
198+
## 7. 错误处理 (Error Handling)
199+
200+
### 7.1 HTTP状态码 (HTTP Status Codes)
201+
- `200 OK`: 请求成功处理
202+
- `400 Bad Request`: 请求参数错误
203+
- `401 Unauthorized`: 认证失败
204+
- `403 Forbidden`: 权限不足
205+
- `429 Too Many Requests`: 请求频率超限
206+
- `500 Internal Server Error`: 服务器内部错误
207+
208+
### 7.2 错误码定义 (Error Code Definitions)
209+
| 错误码 | 说明 |
210+
|--------|------|
211+
| N0002 | 目标地址格式错误 |
212+
| N0003 | 模板代码不存在 |
213+
| N0005 | 通知发送失败 |
214+
| N0006 | 调用频率超限 |
215+
216+
## 8. 性能优化 (Performance Optimization)
217+
218+
### 8.1 异步处理 (Asynchronous Processing)
219+
- 将通知发送操作异步化,提高API响应速度
220+
- 使用消息队列处理大量通知请求
221+
222+
### 8.2 缓存机制 (Caching Mechanism)
223+
- 缓存常用模板内容
224+
- 缓存频繁使用的配置信息
225+
226+
### 8.3 批量处理 (Batch Processing)
227+
- 支持批量发送通知,提高处理效率
228+
- 优化数据库操作
229+
230+
## 9. 监控和日志 (Monitoring and Logging)
231+
232+
### 9.1 日志记录 (Logging)
233+
- 记录所有通知发送请求
234+
- 记录发送结果和错误信息
235+
- 记录性能指标
236+
237+
### 9.2 监控指标 (Monitoring Metrics)
238+
- API调用次数和成功率
239+
- 各种通知类型的分布
240+
- 平均响应时间
241+
- 错误率统计
242+
243+
## 10. 扩展性设计 (Extensibility Design)
244+
245+
### 10.1 新增通知类型 (Adding New Notification Types)
246+
- 添加新的 [NotificationType](file:///Users/zhoutaoo/WorkSpaces/IdeaProjects/opensabre/base-sysadmin/src/main/java/io/github/opensabre/sysadmin/notification/enums/NotificationType.java#L9-L21) 枚举值
247+
- 实现对应的 [INotificationService](file:///Users/zhoutaoo/WorkSpaces/IdeaProjects/opensabre/base-sysadmin/src/main/java/io/github/opensabre/sysadmin/notification/service/INotificationService.java#L12-L39) 服务
248+
- 无需修改API接口
249+
250+
### 10.2 新增模板 (Adding New Templates)
251+
-[NotificationTemplate](file:///Users/zhoutaoo/WorkSpaces/IdeaProjects/opensabre/base-sysadmin/src/main/java/io/github/opensabre/sysadmin/notification/enums/NotificationTemplate.java#L9-L56) 枚举中添加新模板
252+
- 支持运行时动态加载模板
253+
254+
## 11. 配置选项 (Configuration Options)
255+
256+
### 11.1 应用配置 (Application Configuration)
257+
```yaml
258+
opensabre:
259+
notification:
260+
api:
261+
rate-limit: 100 # 每分钟最大请求数
262+
timeout: 30s # 请求超时时间
263+
default-template-path: classpath:templates/ # 默认模板路径
264+
```
265+
266+
## 12. 测试策略 (Testing Strategy)
267+
268+
### 12.1 单元测试 (Unit Tests)
269+
- 测试Controller层的参数验证
270+
- 测试Service层的业务逻辑
271+
- 测试异常处理逻辑
272+
273+
### 12.2 集成测试 (Integration Tests)
274+
- 测试完整的API调用链路
275+
- 测试各种通知类型的发送
276+
- 测试错误场景处理
277+
278+
---
279+
280+
*本文档版本: 1.0*
281+
*最后更新: 2026年1月*

src/main/java/io/github/opensabre/sysadmin/captcha/service/impl/EmailCaptchaService.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ protected void beforeGenerateCaptcha(String businessKey, BusinessScenario scenar
3838
protected CaptchaVo afterGenerateCaptcha(CaptchaInfo captchaInfo) {
3939
// Send Email
4040
String messageId = notificationServiceManager.sendNotification(
41-
NotificationType.EMAIL,
4241
captchaInfo.getBusinessKey(),
4342
NotificationTemplate.CAPTCHA,
4443
captchaInfo.getCode(),

src/main/java/io/github/opensabre/sysadmin/notification/enums/NotificationTemplate.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ public enum NotificationTemplate {
1111
/**
1212
* 短信验证码
1313
*/
14-
CAPTCHA("CAPTCHA", "验证码", NotificationType.SMS, "【通知】您的登录验证码为:%s,请在%d分钟内使用。如非本人操作,请忽略本信息。", "验证码类");
14+
CAPTCHA("CAPTCHA", "验证码", NotificationType.SMS, "【通知】您的登录验证码为:%s,请在%d分钟内使用。如非本人操作,请忽略本信息。", "验证码类"),
15+
ORDER("ORDER", "下单成功", NotificationType.SMS, "【通知】您订单已提交成功,谢谢。", "通知类"),
16+
ORDER_EMAIL("ORDER_EMAIL", "下单成功", NotificationType.EMAIL, "【通知】您订单已提交成功,谢谢。", "通知类");
1517

1618
/**
1719
* Unique code identifying the template
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package io.github.opensabre.sysadmin.notification.model.form;
2+
3+
import jakarta.validation.constraints.NotBlank;
4+
import lombok.AllArgsConstructor;
5+
import lombok.Data;
6+
import lombok.NoArgsConstructor;
7+
8+
import java.util.Map;
9+
10+
/**
11+
* 通知请求表单
12+
*/
13+
@Data
14+
@NoArgsConstructor
15+
@AllArgsConstructor
16+
public class NotificationForm {
17+
18+
@NotBlank(message = "目标地址不能为空")
19+
private String target; // 接收者地址
20+
21+
@NotBlank(message = "模板代码不能为空")
22+
private String templateCode; // NotificationTemplate枚举code
23+
24+
private Object[] args; // 位置参数,与mapArgs二选一
25+
26+
private Map<String, String> mapArgs; // 键值对参数,与args二选一
27+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package io.github.opensabre.sysadmin.notification.model.vo;
2+
3+
import lombok.AllArgsConstructor;
4+
import lombok.Builder;
5+
import lombok.Data;
6+
import lombok.NoArgsConstructor;
7+
8+
import java.time.LocalDateTime;
9+
10+
/**
11+
* 发送通知响应对象
12+
*/
13+
@Data
14+
@Builder
15+
@NoArgsConstructor
16+
@AllArgsConstructor
17+
public class NotificationResponse {
18+
private String messageId; // 消息唯一标识
19+
private LocalDateTime sentTime; // 发送时间戳
20+
}

0 commit comments

Comments
 (0)