456 lines
12 KiB
Markdown
456 lines
12 KiB
Markdown
# 实时消息推送系统使用指南
|
||
|
||
## 🆕 最新更新 (v1.1.0)
|
||
|
||
- ✅ **新消息置顶展示**:采用行业标准,新消息显示在最上方
|
||
- ✅ **智能队列管理**:最多同时显示 5 条消息,超出自动移除最旧的
|
||
- ✅ **视觉层次优化**:最新消息更强的阴影和边框高亮效果
|
||
- ✅ **测试工具增强**:实时显示队列状态,新增"测试最大限制"功能
|
||
|
||
## 📋 系统概述
|
||
|
||
本系统实现了完整的实时消息推送功能,支持 Mock 模式(开发)和真实 Socket.IO 模式(生产)。消息以右下角层叠弹窗的形式显示,**新消息在最上方**,符合主流桌面应用的交互习惯。
|
||
|
||
---
|
||
|
||
## 🎯 功能特性
|
||
|
||
### ✅ 已实现功能
|
||
|
||
1. **实时推送**
|
||
- WebSocket (Socket.IO) 连接
|
||
- Mock 模式自动定期推送(开发环境)
|
||
- 支持多种消息类型(成功、错误、警告、信息)
|
||
|
||
2. **UI 展示**
|
||
- 右下角固定定位
|
||
- **新消息在最上方**(符合行业标准)
|
||
- 层叠显示最多 5 条消息
|
||
- 智能队列管理:超出自动移除最旧消息
|
||
- 视觉层次:最新消息更突出(更强阴影、边框高亮)
|
||
- 自动关闭(可配置时长)
|
||
- 手动关闭按钮
|
||
- 流畅的进入/退出动画(从右侧滑入)
|
||
|
||
3. **音效提示**
|
||
- 新消息音效播放
|
||
- 可开关音效
|
||
|
||
4. **开发工具**
|
||
- 右上角测试工具面板(仅开发环境)
|
||
- 手动触发测试通知(4种类型)
|
||
- 层叠效果测试(4条消息)
|
||
- 最大限制测试(6条→5条)
|
||
- **实时队列状态显示**(当前消息数 / 5)
|
||
- 连接状态显示
|
||
- 音效开关
|
||
- 测试计数统计
|
||
|
||
---
|
||
|
||
## 📁 文件结构
|
||
|
||
```
|
||
src/
|
||
├── services/
|
||
│ ├── socket/
|
||
│ │ └── index.js # Socket 服务统一导出
|
||
│ ├── socketService.js # 真实 Socket.IO 服务
|
||
│ └── mockSocketService.js # Mock Socket 服务
|
||
├── contexts/
|
||
│ └── NotificationContext.js # 通知上下文管理
|
||
├── components/
|
||
│ ├── NotificationContainer/
|
||
│ │ └── index.js # 通知容器组件
|
||
│ └── NotificationTestTool/
|
||
│ └── index.js # 测试工具组件
|
||
└── assets/
|
||
└── sounds/
|
||
└── notification.wav # 通知音效
|
||
```
|
||
|
||
---
|
||
|
||
## 📐 展示逻辑说明
|
||
|
||
### 消息排列方式
|
||
|
||
本系统采用**新消息在最上方**的展示模式,这是桌面应用的行业标准(Windows、macOS、Slack、Discord等)。
|
||
|
||
```
|
||
用户视角(右下角):
|
||
|
||
第1条消息到达:
|
||
┌────────────────────┐
|
||
│ 🔔 买入成功 🆕 │ ← 从右侧滑入
|
||
└────────────────────┘
|
||
|
||
第2条消息到达:
|
||
┌────────────────────┐
|
||
│ 🔔 价格预警 🆕 │ ← 新消息(最上方)
|
||
├────────────────────┤
|
||
│ 🔔 买入成功 │ ← 旧消息向下平移
|
||
└────────────────────┘
|
||
|
||
第6条消息到达(超过5条限制):
|
||
┌────────────────────┐
|
||
│ 🔔 第6条 🆕 │ ← 最新
|
||
├────────────────────┤
|
||
│ 🔔 第5条 │
|
||
├────────────────────┤
|
||
│ 🔔 第4条 │
|
||
├────────────────────┤
|
||
│ 🔔 第3条 │
|
||
├────────────────────┤
|
||
│ 🔔 第2条 │ ← 最旧(仍显示)
|
||
└────────────────────┘
|
||
↓ 自动移除
|
||
│ 第1条(已移除) │
|
||
```
|
||
|
||
### 关键特性
|
||
|
||
- **最新消息固定位置**:始终在右下角的顶部,便于快速注意
|
||
- **自动队列管理**:最多保留 5 条,超出自动移除最旧的
|
||
- **视觉区分**:最新消息有更强的阴影(2xl vs lg)和边框高亮
|
||
- **z-index 层级**:最新消息层级最高(9999),依次递减
|
||
- **间距优化**:消息之间 12px 间距(spacing={3})
|
||
|
||
---
|
||
|
||
## 🚀 快速开始
|
||
|
||
### 1. 启用 Mock 模式
|
||
|
||
在 `.env` 文件中添加:
|
||
|
||
```bash
|
||
REACT_APP_ENABLE_MOCK=true
|
||
# 或
|
||
REACT_APP_USE_MOCK_SOCKET=true
|
||
```
|
||
|
||
### 2. 启动项目
|
||
|
||
```bash
|
||
npm start
|
||
```
|
||
|
||
### 3. 测试通知
|
||
|
||
打开浏览器,右上角会显示 **"通知测试工具"**,点击展开后可以:
|
||
|
||
- **单条测试**:测试不同类型的通知(成功、错误、警告、信息)
|
||
- **层叠测试**:一次发送 4 条消息,测试层叠效果
|
||
- **最大限制测试**:发送 6 条消息,验证只保留最新 5 条
|
||
- **队列状态**:实时显示当前队列中的消息数量(X / 5)
|
||
- **音效控制**:切换音效开关
|
||
- **清空功能**:一键清空所有通知
|
||
- **连接状态**:查看 Socket 连接状态和服务类型(MOCK/REAL)
|
||
|
||
### 4. 自动推送
|
||
|
||
在 Mock 模式下,系统会自动每 20 秒推送 1-2 条随机消息,用于测试层叠效果。
|
||
|
||
---
|
||
|
||
## 💻 代码使用
|
||
|
||
### 在组件中使用通知
|
||
|
||
```javascript
|
||
import { useNotification } from 'contexts/NotificationContext';
|
||
|
||
function MyComponent() {
|
||
const { addNotification, isConnected } = useNotification();
|
||
|
||
const handleTradeSuccess = () => {
|
||
addNotification({
|
||
type: 'trade_alert',
|
||
severity: 'success',
|
||
title: '买入成功',
|
||
message: '您的订单已成功执行:买入 贵州茅台(600519) 100股',
|
||
autoClose: 8000, // 8秒后自动关闭
|
||
});
|
||
};
|
||
|
||
return (
|
||
<div>
|
||
<p>连接状态: {isConnected ? '已连接' : '未连接'}</p>
|
||
<button onClick={handleTradeSuccess}>模拟交易成功</button>
|
||
</div>
|
||
);
|
||
}
|
||
```
|
||
|
||
### 消息格式
|
||
|
||
```javascript
|
||
{
|
||
type: 'trade_alert', // 消息类型
|
||
severity: 'info', // 'success' | 'error' | 'warning' | 'info'
|
||
title: '通知标题', // 主标题
|
||
message: '详细消息内容', // 详细内容
|
||
timestamp: Date.now(), // 时间戳(自动生成)
|
||
autoClose: 8000, // 自动关闭时长(毫秒),0 或 false 表示不自动关闭
|
||
id: 'unique_id' // 唯一ID(自动生成)
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 🔧 配置说明
|
||
|
||
### Mock 服务配置
|
||
|
||
在 `src/services/mockSocketService.js` 中可以配置:
|
||
|
||
```javascript
|
||
// 修改模拟数据
|
||
const mockTradeAlerts = [
|
||
{
|
||
severity: 'success',
|
||
title: '自定义标题',
|
||
message: '自定义消息',
|
||
autoClose: 8000,
|
||
},
|
||
// 添加更多...
|
||
];
|
||
|
||
// 调整推送频率
|
||
socket.startMockPush(20000, 2); // 每20秒推送1-2条
|
||
```
|
||
|
||
### NotificationContext 配置
|
||
|
||
在 `src/contexts/NotificationContext.js` 中:
|
||
|
||
```javascript
|
||
// 修改最大消息数量(默认 5 条)
|
||
const maxNotifications = 5; // 修改为其他数值
|
||
|
||
// 修改默认音效状态
|
||
const [soundEnabled, setSoundEnabled] = useState(true); // false 关闭音效
|
||
|
||
// 修改音效音量
|
||
audioRef.current.volume = 0.5; // 0.0 - 1.0
|
||
```
|
||
|
||
### NotificationContainer 配置
|
||
|
||
在 `src/components/NotificationContainer/index.js` 中:
|
||
|
||
```javascript
|
||
// 调整消息间距
|
||
<VStack spacing={3}> // 3 = 12px, 4 = 16px, 2 = 8px
|
||
|
||
// 调整位置
|
||
<Box
|
||
position="fixed"
|
||
bottom={6} // 修改为 top={6} 可以显示在右上角
|
||
right={6} // 修改为 left={6} 可以显示在左侧
|
||
>
|
||
```
|
||
|
||
---
|
||
|
||
## 🌐 后端集成(生产环境)
|
||
|
||
### 1. Flask 后端配置
|
||
|
||
当 `REACT_APP_ENABLE_MOCK=false` 时,系统会连接真实的 Socket.IO 服务器。
|
||
|
||
在 `app.py` 中初始化 Flask-SocketIO:
|
||
|
||
```python
|
||
from flask_socketio import SocketIO, emit
|
||
|
||
# 初始化 SocketIO
|
||
socketio = SocketIO(app, cors_allowed_origins=[
|
||
"http://localhost:3000",
|
||
"https://valuefrontier.cn"
|
||
])
|
||
|
||
# 连接事件
|
||
@socketio.on('connect')
|
||
def handle_connect():
|
||
print(f'Client connected: {request.sid}')
|
||
|
||
# 推送交易通知
|
||
def send_trade_notification(user_id, data):
|
||
"""
|
||
推送交易通知到指定用户
|
||
"""
|
||
emit('trade_notification', data, room=user_id)
|
||
|
||
# 启动服务器
|
||
if __name__ == '__main__':
|
||
socketio.run(app, host='0.0.0.0', port=5001)
|
||
```
|
||
|
||
### 2. 后端推送示例
|
||
|
||
```python
|
||
# 交易成功后推送通知
|
||
socketio.emit('trade_notification', {
|
||
'type': 'trade_alert',
|
||
'severity': 'success',
|
||
'title': '买入成功',
|
||
'message': f'买入 {stock_name}({stock_code}) {quantity}股',
|
||
'timestamp': int(time.time() * 1000),
|
||
'autoClose': 8000
|
||
}, room=user_id)
|
||
```
|
||
|
||
---
|
||
|
||
## 🎨 自定义样式
|
||
|
||
### 修改通知位置
|
||
|
||
在 `src/components/NotificationContainer/index.js`:
|
||
|
||
```javascript
|
||
<Box
|
||
position="fixed"
|
||
bottom={6} // 修改为 top={6} 可以显示在右上角
|
||
right={6} // 修改为 left={6} 可以显示在左侧
|
||
zIndex={9999}
|
||
>
|
||
```
|
||
|
||
### 修改通知颜色
|
||
|
||
在 `src/components/NotificationContainer/index.js` 中的 `NOTIFICATION_STYLES`:
|
||
|
||
```javascript
|
||
const NOTIFICATION_STYLES = {
|
||
success: {
|
||
icon: MdCheckCircle,
|
||
colorScheme: 'green', // 修改颜色主题
|
||
bg: 'green.50',
|
||
borderColor: 'green.400',
|
||
iconColor: 'green.500',
|
||
},
|
||
// ...
|
||
};
|
||
```
|
||
|
||
---
|
||
|
||
## 🐛 故障排除
|
||
|
||
### 问题 1: 通知不显示
|
||
|
||
**检查项:**
|
||
1. 确认 `NotificationProvider` 已包裹应用
|
||
2. 检查浏览器控制台是否有错误
|
||
3. 确认 socket 连接状态(查看测试工具)
|
||
|
||
### 问题 2: 音效不播放
|
||
|
||
**解决方案:**
|
||
1. 检查浏览器是否允许自动播放音频
|
||
2. 确认音效开关已打开
|
||
3. 检查音频文件路径是否正确
|
||
|
||
### 问题 3: Mock 推送不工作
|
||
|
||
**检查项:**
|
||
1. 确认 `.env` 中设置了 `REACT_APP_ENABLE_MOCK=true`
|
||
2. 查看控制台日志确认 Mock 服务已启动
|
||
3. 检查 `startMockPush` 是否被调用
|
||
|
||
### 问题 4: Socket 连接失败
|
||
|
||
**解决方案:**
|
||
1. 检查后端 Flask-SocketIO 是否正确运行
|
||
2. 确认 CORS 配置正确
|
||
3. 检查 `src/utils/apiConfig.js` 中的 API 地址
|
||
|
||
---
|
||
|
||
## 📊 性能优化建议
|
||
|
||
1. **智能队列管理** ✅ 已实现
|
||
- 系统自动限制最多 5 条通知
|
||
- 超出自动移除最旧的,避免内存泄漏
|
||
- 建议根据实际需求调整 `maxNotifications` 值
|
||
|
||
2. **合理设置自动关闭时长**
|
||
- 建议 5-10 秒(默认 8 秒)
|
||
- 重要消息可设置更长时间或 `autoClose: false`
|
||
|
||
3. **避免频繁推送**
|
||
- 生产环境建议间隔至少 3 秒
|
||
- 避免短时间内大量推送造成用户困扰
|
||
|
||
4. **视觉性能优化** ✅ 已实现
|
||
- 使用 Chakra UI 的优化动画(Slide、ScaleFade)
|
||
- z-index 合理分配,避免层叠问题
|
||
- 间距适中(12px),不会过于紧密
|
||
|
||
---
|
||
|
||
## 🔮 未来扩展
|
||
|
||
可以考虑添加的功能:
|
||
|
||
1. ✨ 通知历史记录
|
||
2. ✨ 通知分类过滤
|
||
3. ✨ 通知优先级
|
||
4. ✨ 通知持久化(存储到 localStorage)
|
||
5. ✨ 通知点击交互(跳转到相关页面)
|
||
6. ✨ 用户偏好设置(通知类型开关)
|
||
|
||
---
|
||
|
||
## 📝 更新日志
|
||
|
||
### v1.1.0 (2025-01-21) - 交互优化版
|
||
|
||
- ✅ **新消息置顶展示**(行业标准,参考 Windows/macOS/Slack)
|
||
- ✅ **智能队列管理**:最多保留 5 条,超出自动移除最旧的
|
||
- ✅ **视觉层次优化**:
|
||
- 最新消息:boxShadow='2xl' + 边框高亮
|
||
- 其他消息:boxShadow='lg'
|
||
- 消息间距:12px(spacing={3})
|
||
- ✅ **z-index 优化**:最新消息层级最高(9999),依次递减
|
||
- ✅ **测试工具增强**:
|
||
- 新增"测试最大限制"按钮(6条→5条)
|
||
- 实时显示队列状态(X / 5)
|
||
- 队列满时红色提示
|
||
- ✅ **文档完善**:添加展示逻辑说明、配置指南
|
||
|
||
### v1.0.0 (2025-01-20) - 初始版本
|
||
|
||
- ✅ 实现基础通知系统
|
||
- ✅ 支持 Mock 和真实 Socket.IO 模式
|
||
- ✅ 右下角层叠显示
|
||
- ✅ 音效提示
|
||
- ✅ 开发工具面板
|
||
- ✅ 4 种消息类型(成功、错误、警告、信息)
|
||
|
||
---
|
||
|
||
## 💡 技术栈
|
||
|
||
- **前端框架**: React 18.3.1
|
||
- **UI 库**: Chakra UI 2.8.2
|
||
- **实时通信**: Socket.IO Client 4.7.4
|
||
- **后端框架**: Flask-SocketIO 5.3.6
|
||
- **状态管理**: React Context API
|
||
|
||
---
|
||
|
||
## 📞 支持
|
||
|
||
如有问题,请查看:
|
||
- 项目文档: `CLAUDE.md`
|
||
- 测试工具: 开发环境右上角
|
||
- 控制台日志: 所有操作都有详细日志
|
||
|
||
---
|
||
|
||
**祝你使用愉快!** 🎉
|