Files
vf_react/docs/ENHANCED_FEATURES_GUIDE.md
zdl 09db05c448 docs: 将所有文档迁移到 docs/ 目录
- 移动42个文档文件到 docs/ 目录
  - 更新 .gitignore 允许 docs/ 下的 .md 文件
  - 删除根目录下的重复文档文件

  📁 文档分类:
  - StockDetailPanel 重构文档(3个)
  - PostHog 集成文档(6个)
  - 系统架构和API文档(33个)

  🤖 Generated with [Claude Code](https://claude.com/claude-code)

  Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-30 14:51:22 +08:00

15 KiB
Raw Blame History

通知系统增强功能 - 使用指南

📋 概述

本指南介绍通知系统的三大增强功能:

  1. 智能桌面通知 - 自动请求权限,系统级通知
  2. 性能监控 - 追踪推送效果,数据驱动优化
  3. 历史记录 - 持久化存储,随时查询

🎯 功能 1智能桌面通知

功能说明

首次收到重要/紧急通知时,自动请求浏览器通知权限,确保用户不错过关键信息。

工作原理

// 在 NotificationContext 中的逻辑
if (priority === URGENT || priority === IMPORTANT) {
  if (browserPermission === 'default' && !hasRequestedPermission) {
    // 首次遇到重要通知,自动请求权限
    await requestBrowserPermission();
    setHasRequestedPermission(true); // 避免重复请求
  }
}

权限状态

  • granted: 已授权,可以发送桌面通知
  • denied: 已拒绝,无法发送桌面通知
  • default: 未请求,首次重要通知时会自动请求

使用示例

自动触发(推荐)

// 无需任何代码,系统自动处理
// 首次收到重要/紧急通知时会自动弹出权限请求

手动请求

import { useNotification } from 'contexts/NotificationContext';

function SettingsPage() {
  const { requestBrowserPermission, browserPermission } = useNotification();

  return (
    <div>
      <p>当前状态: {browserPermission}</p>
      <button onClick={requestBrowserPermission}>
        开启桌面通知
      </button>
    </div>
  );
}

通知分发策略

优先级 页面在前台 页面在后台
紧急 桌面通知 + 网页通知 桌面通知 + 网页通知
重要 网页通知 桌面通知
普通 网页通知 网页通知

测试步骤

  1. 清除已保存的权限状态

    localStorage.removeItem('browser_notification_requested');
    
  2. 刷新页面

  3. 触发一个重要/紧急通知

    • Mock 模式:等待自动推送
    • Real 模式:创建测试事件
  4. 观察权限请求弹窗

    • 浏览器会弹出通知权限请求
    • 点击"允许"授权
  5. 验证桌面通知

    • 切换到其他标签页
    • 收到重要通知时应该看到桌面通知

📊 功能 2性能监控

功能说明

追踪通知推送的各项指标,包括:

  • 到达率: 发送 vs 接收
  • 点击率: 点击 vs 接收
  • 响应时间: 收到通知到点击的平均时间
  • 类型分布: 各类型通知的数量和效果
  • 时段分布: 每小时推送量

API 参考

获取汇总统计

import { notificationMetricsService } from 'services/notificationMetricsService';

const summary = notificationMetricsService.getSummary();
console.log(summary);
/* 输出:
{
  totalSent: 100,
  totalReceived: 98,
  totalClicked: 45,
  totalDismissed: 53,
  avgResponseTime: 5200, // 毫秒
  clickRate: '45.92',    // 百分比
  deliveryRate: '98.00'  // 百分比
}
*/

获取按类型统计

const byType = notificationMetricsService.getByType();
console.log(byType);
/* 输出:
{
  announcement: { sent: 20, received: 20, clicked: 15, dismissed: 5, clickRate: '75.00' },
  stock_alert: { sent: 30, received: 30, clicked: 20, dismissed: 10, clickRate: '66.67' },
  event_alert: { sent: 40, received: 38, clicked: 10, dismissed: 28, clickRate: '26.32' },
  analysis_report: { sent: 10, received: 10, clicked: 0, dismissed: 10, clickRate: '0.00' }
}
*/

获取按优先级统计

const byPriority = notificationMetricsService.getByPriority();
console.log(byPriority);
/* 输出:
{
  urgent: { sent: 10, received: 10, clicked: 9, dismissed: 1, clickRate: '90.00' },
  important: { sent: 40, received: 39, clicked: 25, dismissed: 14, clickRate: '64.10' },
  normal: { sent: 50, received: 49, clicked: 11, dismissed: 38, clickRate: '22.45' }
}
*/

获取每日数据

const dailyData = notificationMetricsService.getDailyData(7); // 最近 7 天
console.log(dailyData);
/* 输出:
[
  { date: '2025-01-15', sent: 15, received: 14, clicked: 6, dismissed: 8, clickRate: '42.86' },
  { date: '2025-01-16', sent: 20, received: 20, clicked: 10, dismissed: 10, clickRate: '50.00' },
  ...
]
*/

获取完整指标

const allMetrics = notificationMetricsService.getAllMetrics();
console.log(allMetrics);

导出数据

// 导出为 JSON
const json = notificationMetricsService.exportToJSON();
console.log(json);

// 导出为 CSV
const csv = notificationMetricsService.exportToCSV();
console.log(csv);

重置指标

notificationMetricsService.reset();

在控制台查看实时指标

打开浏览器控制台,执行:

// 引入服务
import { notificationMetricsService } from './services/notificationMetricsService.js';

// 查看汇总
console.table(notificationMetricsService.getSummary());

// 查看按类型分布
console.table(notificationMetricsService.getByType());

// 查看最近 7 天数据
console.table(notificationMetricsService.getDailyData(7));

监控埋点(自动)

监控服务已自动集成到 NotificationContext,无需手动调用:

  • trackReceived: 收到通知时自动调用
  • trackClicked: 点击通知时自动调用
  • trackDismissed: 关闭通知时自动调用

可视化展示(可选)

你可以基于监控数据创建仪表板:

import { notificationMetricsService } from 'services/notificationMetricsService';
import { PieChart, LineChart } from 'recharts';

function MetricsDashboard() {
  const summary = notificationMetricsService.getSummary();
  const dailyData = notificationMetricsService.getDailyData(7);
  const byType = notificationMetricsService.getByType();

  return (
    <div>
      {/* 汇总卡片 */}
      <StatsCard title="总推送数" value={summary.totalSent} />
      <StatsCard title="点击率" value={`${summary.clickRate}%`} />
      <StatsCard title="平均响应时间" value={`${summary.avgResponseTime}ms`} />

      {/* 类型分布饼图 */}
      <PieChart data={Object.entries(byType).map(([type, data]) => ({
        name: type,
        value: data.received
      }))} />

      {/* 每日趋势折线图 */}
      <LineChart data={dailyData} />
    </div>
  );
}

📜 功能 3历史记录

功能说明

持久化存储所有接收到的通知,支持:

  • 查询和筛选
  • 搜索关键词
  • 标记已读/已点击
  • 批量删除
  • 导出JSON/CSV

API 参考

获取历史记录(支持筛选和分页)

import { notificationHistoryService } from 'services/notificationHistoryService';

const result = notificationHistoryService.getHistory({
  type: 'event_alert',      // 可选:筛选类型
  priority: 'urgent',       // 可选:筛选优先级
  readStatus: 'unread',     // 可选:'read' | 'unread' | 'all'
  startDate: Date.now() - 7 * 24 * 60 * 60 * 1000, // 可选:开始日期
  endDate: Date.now(),      // 可选:结束日期
  page: 1,                  // 页码
  pageSize: 20,             // 每页数量
});

console.log(result);
/* 输出:
{
  records: [...],   // 当前页的记录
  total: 150,       // 总记录数
  page: 1,          // 当前页
  pageSize: 20,     // 每页数量
  totalPages: 8     // 总页数
}
*/

搜索历史记录

const results = notificationHistoryService.searchHistory('降准');
console.log(results); // 返回标题/内容中包含"降准"的所有记录

标记已读/已点击

// 标记已读
notificationHistoryService.markAsRead('notification_id');

// 标记已点击
notificationHistoryService.markAsClicked('notification_id');

删除记录

// 删除单条
notificationHistoryService.deleteRecord('notification_id');

// 批量删除
notificationHistoryService.deleteRecords(['id1', 'id2', 'id3']);

// 清空所有
notificationHistoryService.clearHistory();

获取统计数据

const stats = notificationHistoryService.getStats();
console.log(stats);
/* 输出:
{
  total: 500,           // 总记录数
  read: 320,            // 已读数
  unread: 180,          // 未读数
  clicked: 150,         // 已点击数
  clickRate: '30.00',   // 点击率
  byType: {             // 按类型统计
    announcement: 100,
    stock_alert: 150,
    event_alert: 200,
    analysis_report: 50
  },
  byPriority: {         // 按优先级统计
    urgent: 50,
    important: 200,
    normal: 250
  }
}
*/

导出历史记录

// 导出为 JSON 字符串
const json = notificationHistoryService.exportToJSON({
  type: 'event_alert'  // 可选:只导出特定类型
});

// 导出为 CSV 字符串
const csv = notificationHistoryService.exportToCSV();

// 直接下载 JSON 文件
notificationHistoryService.downloadJSON();

// 直接下载 CSV 文件
notificationHistoryService.downloadCSV();

在控制台使用

打开浏览器控制台,执行:

// 引入服务
import { notificationHistoryService } from './services/notificationHistoryService.js';

// 查看所有历史
console.table(notificationHistoryService.getHistory().records);

// 搜索
const results = notificationHistoryService.searchHistory('央行');
console.table(results);

// 查看统计
console.table(notificationHistoryService.getStats());

// 导出并下载
notificationHistoryService.downloadJSON();

数据结构

每条历史记录包含:

{
  id: 'notif_123',           // 通知 ID
  notification: {            // 完整通知对象
    type: 'event_alert',
    priority: 'urgent',
    title: '...',
    content: '...',
    ...
  },
  receivedAt: 1737459600000, // 接收时间戳
  readAt: 1737459650000,     // 已读时间戳null 表示未读)
  clickedAt: null,           // 已点击时间戳null 表示未点击)
}

存储限制

  • 最大数量: 500 条(超过后自动删除最旧的)
  • 存储位置: localStorage
  • 容量估算: 约 2-5MB取决于通知内容长度

🔧 技术细节

文件结构

src/
├── services/
│   ├── browserNotificationService.js   [已存在] 浏览器通知服务
│   ├── notificationMetricsService.js   [新建] 性能监控服务
│   └── notificationHistoryService.js   [新建] 历史记录服务
├── contexts/
│   └── NotificationContext.js           [修改] 集成所有功能
└── components/
    └── NotificationContainer/
        └── index.js                      [修改] 添加点击追踪

修改清单

文件 修改内容 状态
NotificationContext.js 添加智能权限请求、监控埋点、历史保存 已完成
NotificationContainer/index.js 添加点击追踪 已完成
notificationMetricsService.js 性能监控服务 已创建
notificationHistoryService.js 历史记录服务 已创建

数据流

用户收到通知
    ↓
NotificationContext.addWebNotification()
    ├─ notificationMetricsService.trackReceived()      [监控埋点]
    ├─ notificationHistoryService.saveNotification()   [历史保存]
    ├─ 首次重要通知 → requestBrowserPermission()       [智能权限]
    └─ 显示网页通知或桌面通知

用户点击通知
    ↓
NotificationContainer.handleClick()
    ├─ notificationMetricsService.trackClicked()       [监控埋点]
    ├─ notificationHistoryService.markAsClicked()      [历史标记]
    └─ 跳转到目标页面

用户关闭通知
    ↓
NotificationContext.removeNotification()
    └─ notificationMetricsService.trackDismissed()     [监控埋点]

🧪 测试步骤

1. 测试智能桌面通知

# 1. 清除已保存的权限状态
localStorage.removeItem('browser_notification_requested');

# 2. 刷新页面

# 3. 等待或触发一个重要/紧急通知

# 4. 观察浏览器弹出权限请求

# 5. 授权后验证桌面通知功能

2. 测试性能监控

// 在控制台执行
import { notificationMetricsService } from './services/notificationMetricsService.js';

// 查看实时统计
console.table(notificationMetricsService.getSummary());

// 模拟推送几条通知,再次查看
console.table(notificationMetricsService.getAllMetrics());

// 导出数据
console.log(notificationMetricsService.exportToJSON());

3. 测试历史记录

// 在控制台执行
import { notificationHistoryService } from './services/notificationHistoryService.js';

// 查看历史
console.table(notificationHistoryService.getHistory().records);

// 搜索
console.table(notificationHistoryService.searchHistory('降准'));

// 查看统计
console.table(notificationHistoryService.getStats());

// 导出
notificationHistoryService.downloadJSON();

📈 数据导出示例

导出性能监控数据

import { notificationMetricsService } from 'services/notificationMetricsService';

// 导出 JSON
const json = notificationMetricsService.exportToJSON();
// 复制到剪贴板或保存

// 导出 CSV
const csv = notificationMetricsService.exportToCSV();
// 可以在 Excel 中打开

导出历史记录

import { notificationHistoryService } from 'services/notificationHistoryService';

// 导出最近 7 天的事件动向通知
const json = notificationHistoryService.exportToJSON({
  type: 'event_alert',
  startDate: Date.now() - 7 * 24 * 60 * 60 * 1000
});

// 直接下载为文件
notificationHistoryService.downloadJSON({
  type: 'event_alert'
});

⚠️ 注意事项

1. localStorage 容量限制

  • 大多数浏览器限制为 5-10MB
  • 建议定期清理历史记录和监控数据
  • 使用导出功能备份数据

2. 浏览器兼容性

  • 桌面通知: 需要 HTTPS 或 localhost
  • localStorage: 所有现代浏览器支持
  • 权限请求: 需要用户交互(不能自动授权)

3. 隐私和数据安全

  • 所有数据存储在本地localStorage
  • 不会上传到服务器
  • 用户可以随时清空数据

4. 性能影响

  • 监控埋点非常轻量,几乎无性能影响
  • 历史记录保存异步进行,不阻塞 UI
  • 数据查询在客户端完成,不增加服务器负担

🎉 总结

已实现的功能

智能桌面通知

  • 首次重要通知时自动请求权限
  • 智能分发策略(前台/后台)
  • localStorage 持久化权限状态

性能监控

  • 到达率、点击率、响应时间追踪
  • 按类型、优先级、时段统计
  • 数据导出JSON/CSV

历史记录

  • 持久化存储(最多 500 条)
  • 筛选、搜索、分页
  • 已读/已点击标记
  • 数据导出JSON/CSV

未实现的功能(备份,待上线)

⏸️ 历史记录页面 UI代码已备份随时可上线 ⏸️ 监控仪表板 UI可选暂未实现

下一步建议

  1. 用户设置页面: 允许用户自定义通知偏好
  2. 声音提示: 为紧急通知添加音效
  3. 数据同步: 将历史和监控数据同步到服务器
  4. 高级筛选: 添加更多筛选维度(如关键词、股票代码等)

文档版本: v1.0 最后更新: 2025-01-21 维护者: Claude Code