新增调试工具目录 src/devtools/,提供完整的生产环境调试能力: - apiDebugger: 拦截所有 API 请求/响应,记录日志 - notificationDebugger: 测试浏览器通知,检查权限 - socketDebugger: 监听所有 Socket 事件,诊断连接状态 - 全局 API: window.__DEBUG__ 提供便捷的控制台调试命令 功能特性: - 环境变量控制:REACT_APP_ENABLE_DEBUG=true 开启 - 动态导入:不影响生产环境性能 - 完整诊断:diagnose()、performance()、exportAll() - 易于移除:所有代码集中在 src/devtools/ 目录 Webpack 配置: - 添加 'debug' alias 强制解析到 node_modules/debug - 添加 @devtools alias 简化导入路径 - 避免与 npm debug 包的命名冲突 🔧 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
167 lines
4.2 KiB
JavaScript
167 lines
4.2 KiB
JavaScript
// src/debug/notificationDebugger.js
|
||
/**
|
||
* 通知系统调试工具
|
||
* 扩展现有的 window.__NOTIFY_DEBUG__,添加更多生产环境调试能力
|
||
*/
|
||
|
||
import { browserNotificationService } from '@services/browserNotificationService';
|
||
|
||
class NotificationDebugger {
|
||
constructor() {
|
||
this.eventLog = [];
|
||
this.maxLogSize = 100;
|
||
}
|
||
|
||
/**
|
||
* 初始化调试工具
|
||
*/
|
||
init() {
|
||
console.log('%c[Notification Debugger] Initialized', 'color: #FF9800; font-weight: bold;');
|
||
}
|
||
|
||
/**
|
||
* 记录通知事件
|
||
*/
|
||
logEvent(eventType, data) {
|
||
const logEntry = {
|
||
type: eventType,
|
||
timestamp: new Date().toISOString(),
|
||
data,
|
||
};
|
||
|
||
this.eventLog.unshift(logEntry);
|
||
if (this.eventLog.length > this.maxLogSize) {
|
||
this.eventLog = this.eventLog.slice(0, this.maxLogSize);
|
||
}
|
||
|
||
console.log(
|
||
`%c[Notification Event] ${eventType}`,
|
||
'color: #9C27B0; font-weight: bold;',
|
||
data
|
||
);
|
||
}
|
||
|
||
/**
|
||
* 获取所有事件日志
|
||
*/
|
||
getLogs() {
|
||
return this.eventLog;
|
||
}
|
||
|
||
/**
|
||
* 清空日志
|
||
*/
|
||
clearLogs() {
|
||
this.eventLog = [];
|
||
console.log('[Notification Debugger] Logs cleared');
|
||
}
|
||
|
||
/**
|
||
* 导出日志
|
||
*/
|
||
exportLogs() {
|
||
const blob = new Blob([JSON.stringify(this.eventLog, null, 2)], {
|
||
type: 'application/json',
|
||
});
|
||
const url = URL.createObjectURL(blob);
|
||
const a = document.createElement('a');
|
||
a.href = url;
|
||
a.download = `notification-logs-${Date.now()}.json`;
|
||
a.click();
|
||
URL.revokeObjectURL(url);
|
||
console.log('[Notification Debugger] Logs exported');
|
||
}
|
||
|
||
/**
|
||
* 强制发送浏览器通知(测试用)
|
||
*/
|
||
forceNotification(options = {}) {
|
||
const defaultOptions = {
|
||
title: '🧪 测试通知',
|
||
body: `测试时间: ${new Date().toLocaleString()}`,
|
||
tag: `test_${Date.now()}`,
|
||
requireInteraction: false,
|
||
autoClose: 5000,
|
||
};
|
||
|
||
const finalOptions = { ...defaultOptions, ...options };
|
||
|
||
console.log('[Notification Debugger] Sending test notification:', finalOptions);
|
||
|
||
const notification = browserNotificationService.sendNotification(finalOptions);
|
||
|
||
if (notification) {
|
||
console.log('[Notification Debugger] ✅ Notification sent successfully');
|
||
} else {
|
||
console.error('[Notification Debugger] ❌ Failed to send notification');
|
||
}
|
||
|
||
return notification;
|
||
}
|
||
|
||
/**
|
||
* 检查通知权限状态
|
||
*/
|
||
checkPermission() {
|
||
const permission = browserNotificationService.getPermissionStatus();
|
||
const isSupported = browserNotificationService.isSupported();
|
||
|
||
const status = {
|
||
supported: isSupported,
|
||
permission,
|
||
canSend: isSupported && permission === 'granted',
|
||
};
|
||
|
||
console.table(status);
|
||
return status;
|
||
}
|
||
|
||
/**
|
||
* 请求通知权限
|
||
*/
|
||
async requestPermission() {
|
||
console.log('[Notification Debugger] Requesting notification permission...');
|
||
const result = await browserNotificationService.requestPermission();
|
||
console.log(`[Notification Debugger] Permission result: ${result}`);
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* 打印事件统计
|
||
*/
|
||
printStats() {
|
||
const stats = {
|
||
total: this.eventLog.length,
|
||
byType: {},
|
||
};
|
||
|
||
this.eventLog.forEach((log) => {
|
||
stats.byType[log.type] = (stats.byType[log.type] || 0) + 1;
|
||
});
|
||
|
||
console.log('=== Notification Stats ===');
|
||
console.table(stats.byType);
|
||
console.log(`Total events: ${stats.total}`);
|
||
|
||
return stats;
|
||
}
|
||
|
||
/**
|
||
* 按类型过滤日志
|
||
*/
|
||
getLogsByType(eventType) {
|
||
return this.eventLog.filter((log) => log.type === eventType);
|
||
}
|
||
|
||
/**
|
||
* 获取最近的事件
|
||
*/
|
||
getRecentEvents(count = 10) {
|
||
return this.eventLog.slice(0, count);
|
||
}
|
||
}
|
||
|
||
// 导出单例
|
||
export const notificationDebugger = new NotificationDebugger();
|
||
export default notificationDebugger;
|