feat: 添加消息推送能力,添加新闻催化分析页的合规提示
This commit is contained in:
254
src/services/mockSocketService.js
Normal file
254
src/services/mockSocketService.js
Normal file
@@ -0,0 +1,254 @@
|
||||
// src/services/mockSocketService.js
|
||||
/**
|
||||
* Mock Socket 服务 - 用于开发环境模拟实时推送
|
||||
* 模拟交易提醒、系统通知等实时消息推送
|
||||
*/
|
||||
|
||||
import { logger } from '../utils/logger';
|
||||
|
||||
// 模拟交易提醒数据
|
||||
const mockTradeAlerts = [
|
||||
{
|
||||
type: 'trade_alert',
|
||||
severity: 'success',
|
||||
title: '买入成功',
|
||||
message: '您的订单已成功执行:买入 贵州茅台(600519) 100股,成交价 ¥1,850.00',
|
||||
timestamp: Date.now(),
|
||||
autoClose: 8000,
|
||||
},
|
||||
{
|
||||
type: 'trade_alert',
|
||||
severity: 'warning',
|
||||
title: '价格预警',
|
||||
message: '您关注的股票 比亚迪(002594) 当前价格 ¥245.50,已触达预设价格',
|
||||
timestamp: Date.now(),
|
||||
autoClose: 10000,
|
||||
},
|
||||
{
|
||||
type: 'trade_alert',
|
||||
severity: 'info',
|
||||
title: '持仓提醒',
|
||||
message: '您持有的 宁德时代(300750) 今日涨幅达 5.2%,当前盈利 +¥12,350',
|
||||
timestamp: Date.now(),
|
||||
autoClose: 8000,
|
||||
},
|
||||
{
|
||||
type: 'trade_alert',
|
||||
severity: 'error',
|
||||
title: '委托失败',
|
||||
message: '卖出订单失败:五粮液(000858) 当前处于停牌状态,无法交易',
|
||||
timestamp: Date.now(),
|
||||
autoClose: 12000,
|
||||
},
|
||||
{
|
||||
type: 'system_notification',
|
||||
severity: 'info',
|
||||
title: '系统公告',
|
||||
message: '市场将于15:00收盘,请注意及时调整持仓',
|
||||
timestamp: Date.now(),
|
||||
autoClose: 10000,
|
||||
},
|
||||
{
|
||||
type: 'trade_alert',
|
||||
severity: 'success',
|
||||
title: '分红到账',
|
||||
message: '您持有的 中国平安(601318) 分红已到账,金额 ¥560.00',
|
||||
timestamp: Date.now(),
|
||||
autoClose: 8000,
|
||||
},
|
||||
];
|
||||
|
||||
class MockSocketService {
|
||||
constructor() {
|
||||
this.connected = false;
|
||||
this.listeners = new Map();
|
||||
this.intervals = [];
|
||||
this.messageQueue = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* 连接到 mock socket
|
||||
*/
|
||||
connect() {
|
||||
if (this.connected) {
|
||||
logger.warn('mockSocketService', 'Already connected');
|
||||
return;
|
||||
}
|
||||
|
||||
logger.info('mockSocketService', 'Connecting to mock socket service...');
|
||||
|
||||
// 模拟连接延迟
|
||||
setTimeout(() => {
|
||||
this.connected = true;
|
||||
logger.info('mockSocketService', 'Mock socket connected successfully');
|
||||
|
||||
// 触发连接成功事件
|
||||
this.emit('connect', { timestamp: Date.now() });
|
||||
|
||||
// 在连接后3秒发送欢迎消息
|
||||
setTimeout(() => {
|
||||
this.emit('trade_notification', {
|
||||
type: 'system_notification',
|
||||
severity: 'info',
|
||||
title: '连接成功',
|
||||
message: '实时消息推送服务已启动 (Mock 模式)',
|
||||
timestamp: Date.now(),
|
||||
autoClose: 5000,
|
||||
});
|
||||
}, 3000);
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
/**
|
||||
* 断开连接
|
||||
*/
|
||||
disconnect() {
|
||||
if (!this.connected) {
|
||||
return;
|
||||
}
|
||||
|
||||
logger.info('mockSocketService', 'Disconnecting from mock socket service...');
|
||||
|
||||
// 清除所有定时器
|
||||
this.intervals.forEach(interval => clearInterval(interval));
|
||||
this.intervals = [];
|
||||
|
||||
this.connected = false;
|
||||
this.emit('disconnect', { timestamp: Date.now() });
|
||||
}
|
||||
|
||||
/**
|
||||
* 监听事件
|
||||
* @param {string} event - 事件名称
|
||||
* @param {Function} callback - 回调函数
|
||||
*/
|
||||
on(event, callback) {
|
||||
if (!this.listeners.has(event)) {
|
||||
this.listeners.set(event, []);
|
||||
}
|
||||
this.listeners.get(event).push(callback);
|
||||
|
||||
logger.info('mockSocketService', `Event listener added: ${event}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除事件监听
|
||||
* @param {string} event - 事件名称
|
||||
* @param {Function} callback - 回调函数
|
||||
*/
|
||||
off(event, callback) {
|
||||
if (!this.listeners.has(event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const callbacks = this.listeners.get(event);
|
||||
const index = callbacks.indexOf(callback);
|
||||
|
||||
if (index !== -1) {
|
||||
callbacks.splice(index, 1);
|
||||
logger.info('mockSocketService', `Event listener removed: ${event}`);
|
||||
}
|
||||
|
||||
// 如果没有监听器了,删除该事件
|
||||
if (callbacks.length === 0) {
|
||||
this.listeners.delete(event);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 触发事件
|
||||
* @param {string} event - 事件名称
|
||||
* @param {*} data - 事件数据
|
||||
*/
|
||||
emit(event, data) {
|
||||
if (!this.listeners.has(event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const callbacks = this.listeners.get(event);
|
||||
callbacks.forEach(callback => {
|
||||
try {
|
||||
callback(data);
|
||||
} catch (error) {
|
||||
logger.error('mockSocketService', 'emit', error, { event, data });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动模拟消息推送
|
||||
* @param {number} interval - 推送间隔(毫秒)
|
||||
* @param {number} burstCount - 每次推送的消息数量(1-3条)
|
||||
*/
|
||||
startMockPush(interval = 15000, burstCount = 1) {
|
||||
if (!this.connected) {
|
||||
logger.warn('mockSocketService', 'Cannot start mock push: not connected');
|
||||
return;
|
||||
}
|
||||
|
||||
logger.info('mockSocketService', `Starting mock push: interval=${interval}ms, burst=${burstCount}`);
|
||||
|
||||
const pushInterval = setInterval(() => {
|
||||
// 随机选择 1-burstCount 条消息
|
||||
const count = Math.floor(Math.random() * burstCount) + 1;
|
||||
|
||||
for (let i = 0; i < count; i++) {
|
||||
// 从模拟数据中随机选择一条
|
||||
const randomIndex = Math.floor(Math.random() * mockTradeAlerts.length);
|
||||
const alert = {
|
||||
...mockTradeAlerts[randomIndex],
|
||||
timestamp: Date.now(),
|
||||
id: `mock_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
|
||||
};
|
||||
|
||||
// 延迟发送(模拟层叠效果)
|
||||
setTimeout(() => {
|
||||
this.emit('trade_notification', alert);
|
||||
logger.info('mockSocketService', 'Mock notification sent', alert);
|
||||
}, i * 500); // 每条消息间隔500ms
|
||||
}
|
||||
}, interval);
|
||||
|
||||
this.intervals.push(pushInterval);
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止模拟推送
|
||||
*/
|
||||
stopMockPush() {
|
||||
this.intervals.forEach(interval => clearInterval(interval));
|
||||
this.intervals = [];
|
||||
logger.info('mockSocketService', 'Mock push stopped');
|
||||
}
|
||||
|
||||
/**
|
||||
* 手动触发一条测试消息
|
||||
* @param {object} customData - 自定义消息数据(可选)
|
||||
*/
|
||||
sendTestNotification(customData = null) {
|
||||
const notification = customData || {
|
||||
type: 'trade_alert',
|
||||
severity: 'info',
|
||||
title: '测试消息',
|
||||
message: '这是一条手动触发的测试消息',
|
||||
timestamp: Date.now(),
|
||||
autoClose: 5000,
|
||||
id: `test_${Date.now()}`,
|
||||
};
|
||||
|
||||
this.emit('trade_notification', notification);
|
||||
logger.info('mockSocketService', 'Test notification sent', notification);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取连接状态
|
||||
*/
|
||||
isConnected() {
|
||||
return this.connected;
|
||||
}
|
||||
}
|
||||
|
||||
// 导出单例
|
||||
export const mockSocketService = new MockSocketService();
|
||||
|
||||
export default mockSocketService;
|
||||
Reference in New Issue
Block a user