# 消息通知系统使用说明 ## 概述 本项目集成了一套完整的消息通知系统,支持WebSocket实时推送和数据库存储,提供便捷的消息管理功能。 ## 功能特性 - ✅ **实时推送**: 基于WebSocket + STOMP协议 - ✅ **消息持久化**: MySQL数据库存储 - ✅ **多种消息类型**: 系统通知、任务通知、报告通知、警告通知、提醒通知 - ✅ **消息管理**: 已读/未读状态管理、删除、统计 - ✅ **批量操作**: 批量发送、批量标记已读、批量删除 - ✅ **优先级支持**: 低、普通、高、紧急四个级别 - ✅ **自动清理**: 定时清理过期消息 - ✅ **业务关联**: 支持业务ID和业务类型关联 - ✅ **工具类支持**: 提供静态方法便捷调用 ## 系统架构 ``` 前端页面 ↓ (WebSocket) 消息推送服务 (WebSocketService) ↓ 消息服务 (NotificationService) ↓ 数据库存储 (MySQL) ↓ 定时清理 (NotificationCleanupTask) ``` ## 快速开始 ### 1. 数据库初始化 执行SQL脚本创建相关表: ```sql -- 运行 /sql/notification.sql 文件 ``` ### 2. 启动应用 确保Spring Boot应用正常启动,WebSocket会自动配置。 ### 3. 前端集成 参考 `frontend/websocket-example.html` 文件进行前端集成。 ## API接口 ### 消息管理接口 #### 获取消息列表 ```http GET /api/notification/list?current=1&size=20&messageType=SYSTEM&status=UNREAD ``` #### 获取未读消息数量 ```http GET /api/notification/unread-count ``` #### 标记消息为已读 ```http POST /api/notification/read/{messageId} ``` #### 批量标记已读 ```http POST /api/notification/read/batch Content-Type: application/json [1, 2, 3, 4, 5] ``` #### 标记全部已读 ```http POST /api/notification/read/all ``` #### 删除消息 ```http DELETE /api/notification/{messageId} ``` #### 获取消息统计 ```http GET /api/notification/statistics ``` ### 消息发送接口 #### 发送系统通知 ```http POST /api/message/system Content-Type: application/json { "receiverId": 1001, "title": "系统维护通知", "content": "系统将于今晚22:00进行维护", "businessId": "SYS_MAINTENANCE_001", "businessType": "SYSTEM_MAINTENANCE" } ``` #### 发送任务通知 ```http POST /api/message/task Content-Type: application/json { "receiverId": 1001, "title": "新任务分配", "content": "您有一个新的影像诊断任务", "businessId": "TASK_12345" } ``` #### 发送报告通知 ```http POST /api/message/report Content-Type: application/json { "receiverId": 1001, "title": "诊断报告已完成", "content": "患者张三的影像诊断报告已完成", "businessId": "REPORT_54321" } ``` #### 批量发送系统通知 ```http POST /api/message/system/batch Content-Type: application/json { "receiverIds": [1001, 1002, 1003], "title": "系统升级通知", "content": "系统已升级到新版本,请查看更新内容" } ``` ## 代码集成 ### 1. 使用Service方式 ```java @Autowired private NotificationService notificationService; // 发送系统通知 Long messageId = notificationService.sendSystemNotification( userId, "标题", "内容" ); // 发送任务通知 Long messageId = notificationService.sendTaskNotification( userId, "任务标题", "任务内容", businessId ); // 批量发送 int count = notificationService.batchSendNotification( userIdList, "标题", "内容", "SYSTEM" ); ``` ### 2. 使用工具类(推荐) ```java import static com.zskk.pacsonline.modules.notification.util.NotificationUtil.*; // 发送系统通知 sendSystemNotification(userId, "标题", "内容"); // 发送带业务ID的系统通知 sendSystemNotification(userId, "标题", "内容", businessId, "REPORT"); // 发送任务通知 sendTaskNotification(userId, "任务标题", "任务内容", businessId); // 发送报告通知 sendReportNotification(userId, "报告标题", "报告内容", businessId); // 发送警告通知 sendWarningNotification(userId, "警告标题", "警告内容"); // 批量发送 List userIds = Arrays.asList(1001L, 1002L, 1003L); sendToMultipleUsers(userIds, "标题", "内容", "SYSTEM"); ``` ### 3. 在Controller中使用 ```java @RestController public class ReportController { @Autowired private NotificationService notificationService; @PostMapping("/report/complete") public RestResult completeReport(@RequestBody CompleteReportRequest request) { // 业务逻辑处理 reportService.completeReport(request); // 发送通知给申请人 notificationService.sendReportNotification( request.getApplicantId(), "诊断报告已完成", String.format("患者%s的影像诊断报告已完成,请及时查看", request.getPatientName()), request.getReportId() ); return RestResult.success("报告完成通知已发送"); } } ``` ## WebSocket连接 ### 连接信息 - **WebSocket URL**: `ws://localhost:8080/ws-notification` - **HTTP URL**: `http://localhost:8080/ws-notification` - **协议**: STOMP over WebSocket ### 连接示例(JavaScript) ```javascript // 连接WebSocket const socket = new SockJS('http://localhost:8080/ws-notification'); const stompClient = Stomp.over(socket); // 设置认证头 const headers = { 'Authorization': 'Bearer ' + token }; stompClient.connect(headers, function(frame) { console.log('连接成功: ' + frame); // 订阅个人消息 stompClient.subscribe('/user/queue/notifications', function(message) { const data = JSON.parse(message.body); console.log('收到消息: ', data); // 处理消息显示 }); // 订阅系统消息 stompClient.subscribe('/user/queue/system', function(message) { const data = JSON.parse(message.body); console.log('收到系统消息: ', data); }); // 订阅广播消息 stompClient.subscribe('/topic/broadcast', function(message) { const data = JSON.parse(message.body); console.log('收到广播消息: ', data); }); }); ``` ### 消息格式 #### 通知消息格式 ```json { "type": "NOTIFICATION", "data": { "id": 1234567890, "receiverId": 1001, "receiverName": "张医生", "messageType": "REPORT", "title": "诊断报告已完成", "content": "患者李四的影像诊断报告已完成", "priority": "HIGH", "status": "UNREAD", "businessId": "REPORT_54321", "businessType": "REPORT", "sendTime": "2023-12-01 10:30:00" }, "timestamp": 1701426600000 } ``` #### 系统消息格式 ```json { "type": "SYSTEM_MESSAGE", "title": "系统维护通知", "content": "系统将于今晚22:00进行维护", "timestamp": 1701426600000 } ``` ## 消息类型说明 | 类型 | 说明 | 优先级 | 过期时间 | |------|------|--------|----------| | SYSTEM | 系统通知 | 普通 | 7天 | | TASK | 任务通知 | 普通 | 30天 | | REPORT | 报告通知 | 高 | 30天 | | MESSAGE | 普通消息 | 普通 | 30天 | | REMINDER | 提醒通知 | 普通 | 30天 | | WARNING | 警告通知 | 高 | 3天 | ## 优先级说明 | 级别 | 说明 | 显示效果 | |------|------|----------| | LOW | 低 | 普通显示 | | NORMAL | 普通 | 普通显示 | | HIGH | 高 | 红色标记 | | URGENT | 紧急 | 红色标记 + 弹窗提醒 | ## 状态说明 | 状态 | 说明 | |------|------| | UNREAD | 未读 | | READ | 已读 | | ARCHIVED | 已归档 | ## 配置说明 ### application.yaml配置 ```yaml # 消息通知配置 notification: # 默认过期时间(小时) default-expire-hours: 720 # 30天 # 系统消息过期时间(小时) system-expire-hours: 168 # 7天 # 警告消息过期时间(小时) warning-expire-hours: 72 # 3天 # 批量发送限制 batch-limit: 1000 # WebSocket连接心跳间隔(秒) heartbeat-interval: 30 ``` ## 性能优化建议 1. **数据库索引**: 确保相关字段有索引 2. **消息分页**: 避免一次性加载过多消息 3. **定期清理**: 自动清理过期消息 4. **缓存策略**: 可结合Redis缓存未读数量 5. **批量操作**: 使用批量API提高效率 ## 监控和日志 ### 关键日志 - 消息发送成功/失败 - WebSocket连接状态 - 数据库操作异常 - 定时任务执行情况 ### 监控指标 - 消息发送量 - WebSocket连接数 - 未读消息统计 - 系统性能指标 ## 故障排除 ### 常见问题 1. **WebSocket连接失败** - 检查Token是否正确 - 检查网络连接 - 查看浏览器控制台错误 2. **消息未收到** - 检查用户是否在线 - 检查消息是否已过期 - 查看后端日志 3. **数据库查询慢** - 检查索引是否正确 - 优化SQL查询 - 考虑分页查询 ## 扩展开发 ### 自定义消息类型 1. 在`NotificationConstants`中添加新的消息类型 2. 在Service中添加对应的发送方法 3. 更新数据库表类型约束 ### 自定义推送渠道 1. 实现`MessagePushService`接口 2. 在`NotificationService`中调用自定义推送服务 3. 配置相关参数 ## 示例代码 完整的使用示例请参考: - `frontend/websocket-example.html` - 前端集成示例 - 各个Controller中的实际使用案例 ## 技术支持 如有问题,请联系开发团队或查看项目文档。